- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
The below LISP aligns (rotates) entities (blocks, text, MText) to various curves. Currently it successfully selects and aligns entities to standard curves like lines, polylines, arcs, circles, ellipses, and splines.
However, I need it to also properly handle curves that are nested within blocks. Since it does allow block selection, but the result is not always correct (especially if the nested object is not a straight line, or if the block is rotated at angle other than 0 degrees).
Specifically, I want the script to:
1- Detect when a user selects a curve that is part of a block.
2- Temporarily copy the nested object below the cursor.
3- Use the copied object if it’s a supported curve (line, polyline, arc, circle, ellipse, spline) to calculate the rotation.
4- Align subsequent text, MText, or block selections based on this rotation.
;; Auto Align Multiple Entities (Blocks, Text, MText) to various curves
(defun C:RTC (/ picksize bss bname ins bdata pt param enx idx entityType pl o c a valid initial-angle adjusted-angle last-angle)
(vl-load-com)
(setq picksize (* (getvar 'viewsize) (/ (getvar 'pickbox) (car (getvar 'screensize)))))
(setq valid nil)
;; Loop until a valid curve is picked
(while (not valid)
(setq pl (nentselp "\nPick a point on any curve (line, polyline, arc, circle, ellipse, spline): "))
(if (and pl (wcmatch (cdr (assoc 0 (entget (car pl)))) "*LINE,*POLYLINE,*ARC,*CIRCLE,*ELLIPSE,*SPLINE"))
(setq valid t) ; Set valid flag to true as a valid curve is selected
(princ "\nInvalid curve. Try again.")
)
)
;; If a valid curve is selected, then proceed to select the blocks, text, and MText
(if valid
(if (setq bss (ssget "_:L" '((0 . "INSERT,MTEXT,TEXT"))))
(progn
(setq o (car pl)
c (vlax-curve-getclosestpointto o (cadr pl)) ; Closest point on curve
param (vlax-curve-getparamatpoint o c) ; Parametric point on curve
)
;; Loop through each selected entity
(setq idx 0 last-angle 0)
(repeat (sslength bss)
(setq enx (ssname bss idx)
bdata (entget enx) ; Get entity data
ins (cdr (assoc 10 bdata)) ; Get insertion point of the entity
bname (cdr (assoc 2 bdata)) ; Get entity name
entityType (cdr (assoc 0 bdata)) ; Get entity type
)
;; Modify the entity to align rotation if it is a block or text
(if (or (= entityType "INSERT") (= entityType "TEXT") (= entityType "MTEXT"))
(progn
(setq initial-angle (angle '(0 0 0) (vlax-curve-getFirstDeriv o param)))
;; Check if the angle is between 90 and 270 degrees
(setq adjusted-angle
(if (and (> initial-angle (/ pi 2)) (< initial-angle (* 3 (/ pi 2))))
(+ initial-angle pi)
initial-angle
)
)
(setq last-angle (* (/ 180 pi) adjusted-angle)) ; Store last angle for reporting
(entmod
(subst
(cons 50 adjusted-angle)
(assoc 50 bdata)
bdata
)
)
)
)
(setq idx (+ idx 1))
) ; repeat
(princ (strcat "\nEntities aligned to curve @ " (rtos last-angle 2 2) "°."))
) ; progn if bss
) ; if entities selected
) ; if valid curve
(princ)
)
Edit: Added Drawing + Screenshot
Solved! Go to Solution.