Lisp for Align text

Lisp for Align text

Automohan
Advocate Advocate
8,573 Views
17 Replies
Message 1 of 18

Lisp for Align text

Automohan
Advocate
Advocate
Hello anyone; I need a lisp routine that will Align texts with respect to nearest polyline Parallel at onces attached example of cad file look forward to hear from you soon as possible thanks a lot Mohan
"Save Energy"
Did you find this reply helpful? If so please use the Accept as Solution
0 Likes
8,574 Views
17 Replies
Replies (17)
Message 2 of 18

Kent1Cooper
Consultant
Consultant

[...nothing attached...]

Kent Cooper, AIA
0 Likes
Message 3 of 18

Automohan
Advocate
Advocate

Sorry

again attached dwg

"Save Energy"
Did you find this reply helpful? If so please use the Accept as Solution
0 Likes
Message 4 of 18

Kent1Cooper
Consultant
Consultant

That would be quite a challenge....

 

Some things are not clear [to me] about the intent.  The Text rotations are not all at the closer-to-horizontal direction from among the "choices" possible in their surrounding Polylines, so at first I thought they were all supposed to be aligned with the long direction of their surrounding Polylines, but the red ones below are in the direction perpendicular to that.  Some of the Mtext objects align [at least approximately, since the plots are not all rectangular] with the direction of the first Polyline segment, but others are roughly perpendicular to that, usually in the general direction of the second segment.  And it looks like the intent is to put them in the middle of the plots, but the green one is not even close [maybe that's just a mistake].

 

Then there's the question of the multiple plots within one surrounding Polyline [the yellow one].  About the only way I can imagine doing this is to have a routine search outward from the middle of the Mtext object at successively larger sizes, using something like (ssget) with a Crossing-window selection, until it finds a Polyline.  Then presumably it should place the Mtext in the middle of that, and rotate it appropriately [by whatever criteria you prefer].  But in an operation like that, the three Mtext objects inside the multiple-plot boundary would either all go on top of each other at the middle of that one, or if the search for any of them [likely the middle one, but possible one or both of the others] finds one of the interior subdividing Polylines first, the Mtext would be centered on top of that subdivision line.  I can't imagine a way for a routine to calculate the locations of at least the outer ones there.

 

Also, some of the plot boundaries are single Polylines [easy enough to find the middle of], but some are made up of more than one.  If a routine searches until it finds one, I guess it could potentially check whether it's closed, and if not, keep looking for more, but when it would know that it found all of the plot perimeter is hard to imagine.  Maybe it could be asked to Join the first one it finds, if that's not closed, to anything it can join to, until the result is closed, but that risks getting pieces that don't belong.  And some of the "boundaries" shown are not anything like closed, so it would never get there, and if it keeps looking until it finds more, what it would find next would be un-related to the Mtext object it's searching around.  But looking deeper, I now notice that the ones that look closed are not actually "closed" in AutoCAD terms, so a check for closed-ness wouldn't help.

 

Whatever happens, it would be far easier if the justification of the Mtext objects was Middle-Center, rather than Upper-Left, but a routine could change them to be that way, if necessary.

 

A little more refinement of the objective, and perhaps of the starting conditions, would be helpful.

 

TextAlign.png

Kent Cooper, AIA
0 Likes
Message 5 of 18

Anonymous
Not applicable

 This is what i use to align text 

Spoiler

;;----------------------=={ Align Text to Curve }==---------------------;;
;; ;;
;; ----------------------------------- ;;
;; Program Overview ;;
;; ----------------------------------- ;;
;; This program enables the user to dynamically align a new or ;;
;; existing Text or MText object to a selected curve, with intuitive ;;
;; placement controls available. ;;
;; ;;
;; ----------------------------------- ;;
;; User Input ;;
;; ----------------------------------- ;;
;; Upon issuing the command syntax 'atc' at the AutoCAD command-line, ;;
;; the user is prompted to select a Text or MText object to align. ;;
;; At this prompt, the user also has the option to create a new Text ;;
;; or MText object, or configure the program settings. ;;
;; ;;
;; If the 'New' option is chosen, the user is prompted to enter the ;;
;; content for the new text object, or may press 'Enter' to return to ;;
;; the previous prompt. ;;
;; ;;
;; If the 'Settings' option is chosen, the user is presented with a ;;
;; dialog interface through which several program parameters may be ;;
;; configured - these settings are detailed in the section below. ;;
;; ;;
;; The user is then prompted to select a curve to which the text will ;;
;; be dynamically aligned. The program is compatible for use with ;;
;; Lines, LWPolylines, 2D (Heavy) Polylines, 3D Polylines, Arcs, ;;
;; Circles, Ellipses, Elliptical Arcs & Splines; furthermore, these ;;
;; objects may be primary or nested (to any depth) within a block or ;;
;; xref. ;;
;; ;;
;; ----------------------------------- ;;
;; Dynamic Text Alignment ;;
;; ----------------------------------- ;;
;; Following valid selection of a curve, the new or existing Text or ;;
;; MText object is dynamically aligned to the curve based on the ;;
;; position of the AutoCAD cursor. ;;
;; ;;
;; During text alignment, several controls are available at the ;;
;; command-line to refine the text position & other properties; these ;;
;; controls are individually detailed below: ;;
;; ;;
;; [ Enter ] - (or Esc/Space/Right-Click) Exit program (Cancel) ;;
;; [ Click ] - Place text ;;
;; [ +/- ] - Incrementally increase/decrease text offset ;;
;; [ O ] - Specify exact text offset ;;
;; [ </> ] - Rotate text by 45 degrees ;;
;; [ R ] - Specify exact text rotation (relative to curve) ;;
;; [ Y ] - Toggle text readability ;;
;; [ B ] - Toggle MText Background Mask ;;
;; ;;
;; ----------------------------------- ;;
;; Program Settings ;;
;; ----------------------------------- ;;
;; Upon selecting the 'Settings' option when prompted, the user is ;;
;; presented with a dialog interface offering the following options: ;;
;; ;;
;; Object type for new text: this setting determines whether the ;;
;; program will create a single-line Text object or MText object when ;;
;; the user opts to create a new text. ;;
;; ;;
;; Justification for new text: this setting controls the justification ;;
;; of any new text object created by the program. ;;
;; ;;
;; Text Offset Factor: this is the default offset factor of the text ;;
;; from the selected curve, as a multiple of the text height. This ;;
;; factor may also be zero if the text is to be positioned directly ;;
;; over the selected curve. ;;
;; ;;
;; Text Rotation: this setting controls the default rotation of the ;;
;; text relative to the selected curve. ;;
;; ;;
;; Text Readability: this toggle determines whether the text should ;;
;; be rotated to preserve readability, i.e. the text will never appear ;;
;; upside-down. ;;
;; ;;
;; Background Mask: this toggle controls whether a background mask is ;;
;; used when aligning MText objects. ;;
;; ;;
;; Multiple Text Mode: if this setting is enabled, the program will ;;
;; continuously generate text objects to align with the selected curve ;;
;; until the user exits the program. ;;
;; ;;
;; ----------------------------------- ;;
;; Notes ;;
;; ----------------------------------- ;;
;; The program is compatible with all full versions of AutoCAD ;;
;; supporting Visual LISP with ActiveX (COM) functionality (that is, ;;
;; AutoCAD 2000 onwards on a Windows OS). ;;
;; ;;
;; The program will perform successfully under all UCS & View ;;
;; settings and with Annotative Text Styles. ;;
;; ;;
;;----------------------------------------------------------------------;;
;; Author: Lee Mac, Copyright © 2013 - www.lee-mac.com ;;
;;----------------------------------------------------------------------;;
;; Version 1.2 - 12-10-2013 ;;
;; ;;
;; First release - previously 'CurveAlignedTextV1-1.lsp'. ;;
;;----------------------------------------------------------------------;;

(setq atc:version "1.2")

;;----------------------------------------------------------------------;;

(defun c:atc

(
/
*error*
ang
bak
cfg
dcl def dis
ent enx
gr1 gr2
hgt
jus
mat msg mtp
nrm
off
pi2 prn prp pt1 pt2
red rot
sav sel str sym
tmp txt typ
uxa
)

(defun *error* ( msg )
(if
(and
(= 'list (type def))
(= 'str (type cfg))
(findfile cfg)
)
(atc:writeconfig cfg (mapcar 'eval (mapcar 'car def)))
)
(if
(and
(= 'vla-object (type txt))
(not (vlax-erased-p txt))
(vlax-write-enabled-p txt)
)
(if (= 'list (type prp))
(foreach x prp
(if (vlax-property-available-p txt (car x) t)
(vl-catch-all-apply 'vlax-put-property (cons txt x))
)
)
(vl-catch-all-apply 'vla-delete (list txt))
)
)
(if
(and
(= 'list (type mat))
(= 'ename (type ent))
(entget ent)
)
(entdel ent)
)
(atc:endundo (atc:acdoc))
(if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
(princ (strcat "\nError: " msg))
)
(princ)
)

(atc:startundo (atc:acdoc))
(cond
( (or (atc:layerlocked (getvar 'clayer))
(atc:layerlocked "0")
)
(princ "\nCurrent layer or layer \"0\" locked.")
)
( (null (vl-file-directory-p (setq sav (atc:savepath))))
(princ "\nSave path invalid.")
)
( (progn
(setq def
'(
(typ . "txt")
(jus . "Middle-Center")
(off . 1.0)
(rot . 0.0)
(red . t)
(bak . nil)
(mtp . nil)
)
)
(setq cfg (strcat sav "\\LMAC_ATC_V" (vl-string-translate "." "-" atc:version) ".cfg")
dcl (strcat sav "\\LMAC_ATC_V" (vl-string-translate "." "-" atc:version) ".dcl")
)
(if (not (findfile cfg))
(atc:writeconfig cfg (mapcar 'cdr def))
)
(atc:readconfig cfg (setq sym (mapcar 'car def)))

(while
(progn
(setvar 'errno 0)
(initget "New Settings Exit")
(setq sel (entsel "\nSelect text to align [New/Settings] <Exit>: "))
(cond
( (= 7 (getvar 'errno))
(princ "\nMissed, try again.")
)
( (= 'list (type sel))
(setq ent (car sel)
enx (entget ent)
)
(cond
( (not (wcmatch (cdr (assoc 0 enx)) "TEXT,MTEXT"))
(princ "\nObject must be either Text or MText.")
)
( (atc:layerlocked (cdr (assoc 8 enx)))
(princ "\nObject is on a locked layer.")
)
( t
(setq txt (vlax-ename->vla-object ent)
prp (atc:getproperties txt)
)
nil
)
)
)
( (= "Exit" sel)
nil
)
( (= "Settings" sel)
(mapcar 'set sym (atc:settings dcl (mapcar 'eval sym)))
)
( (= "New" sel)
(= "" (vl-string-trim " \t\n" (setq str (getstring t "\nSpecify text <Select>: "))))
)
)
)
)
(not
(or (= 'vla-object (type txt))
(and (= 'str (type str)) (/= "" (vl-string-trim " \t\n" str)))
)
)
)
(atc:writeconfig cfg (mapcar 'eval sym))
)
( (progn
(while
(progn
(setvar 'errno 0)
(setq sel (nentselp "\nSelect curve to align text <Exit>: "))
(cond
( (= 7 (getvar 'errno))
(princ "\nMissed, try again.")
)
( (= 'ename (type (car sel)))
(if
(not
(or (= "VERTEX" (cdr (assoc 0 (entget (car sel)))))
(not (vl-catch-all-error-p (vl-catch-all-apply 'vlax-curve-getendparam (list (car sel)))))
)
)
(princ "\nInvalid object selected.")
)
)
)
)
)
(null sel)
)
)
( (not
(or
(and
(setq mat (caddr sel))
(setq ent (atc:copynested (car sel) mat))
)
(and
(= "VERTEX" (cdr (assoc 0 (entget (car sel)))))
(setq ent (cdr (assoc 330 (entget (car sel)))))
)
(setq ent (car sel))
)
)
(princ "\nUnable to recreate nested entity.")
)
( t
(if (null txt)
(if (= "txt" typ)
(progn
(setq txt
(vla-addtext
(vlax-get-property (atc:acdoc)
(if (= 1 (getvar 'cvport))
'paperspace
'modelspace
)
)
str
(vlax-3D-point (trans (cadr sel) 1 0))
(atc:styleheight (getvar 'textstyle))
)
)
(vla-put-alignment txt
(eval
(cadr
(assoc jus
'(
("Left" acalignmentleft)
("Center" acalignmentcenter)
("Right" acalignmentright)
("Middle" acalignmentmiddle)
("Top-Left" acalignmenttopleft)
("Top-Center" acalignmenttopcenter)
("Top-Right" acalignmenttopright)
("Middle-Left" acalignmentmiddleleft)
("Middle-Center" acalignmentmiddlecenter)
("Middle-Right" acalignmentmiddleright)
("Bottom-Left" acalignmentbottomleft)
("Bottom-Center" acalignmentbottomcenter)
("Bottom-Right" acalignmentbottomright)
)
)
)
)
)
)
(progn
(setq txt
(vla-addmtext
(vlax-get-property (atc:acdoc)
(if (= 1 (getvar 'cvport))
'paperspace
'modelspace
)
)
(vlax-3D-point (trans (cadr sel) 1 0))
( (lambda ( box ) (- (caadr box) (caar box)))
(textbox
(list
(cons 01 (strcat str "."))
(cons 40 (atc:styleheight (getvar 'textstyle)))
(cons 07 (getvar 'textstyle))
)
)
)
str
)
)
(vla-put-attachmentpoint txt
(eval
(cadr
(assoc jus
'(
("Top-Left" acattachmentpointtopleft)
("Top-Center" acattachmentpointtopcenter)
("Top-Right" acattachmentpointtopright)
("Middle-Left" acattachmentpointmiddleleft)
("Middle-Center" acattachmentpointmiddlecenter)
("Middle-Right" acattachmentpointmiddleright)
("Bottom-Left" acattachmentpointbottomleft)
("Bottom-Center" acattachmentpointbottomcenter)
("Bottom-Right" acattachmentpointbottomright)
)
)
)
)
)
(vla-put-height txt (atc:styleheight (getvar 'textstyle)))
(if bak (vla-put-backgroundfill txt :vlax-true))
)
)
)
(if
(and
(= "AcDbText" (vla-get-objectname txt))
(/= acalignmentleft (vla-get-alignment txt))
)
(setq prn 'textalignmentpoint)
(setq prn 'insertionpoint)
)
(setq hgt (vla-get-height txt)
pi2 (/ pi -2.0)
nrm (trans '(0.0 0.0 1.0) 1 0 t)
uxa (if (= "AcDbText" (vla-get-objectname txt)) (angle '(0.0 0.0 0.0) (trans (getvar 'ucsxdir) 0 nrm t)) 0.0)
msg (strcat "\n[+/-] for [O]ffset | [</>] for [R]otation | Readabilit[y] |"
(if (= "AcDbMText" (vla-get-objectname txt))
" [B]ackground Mask | <[E]xit>: "
" <[E]xit>: "
)
)
)
(princ msg)
(while
(progn
(setq gr1 (grread t 15 0)
gr2 (cadr gr1)
gr1 (car gr1)
)
(cond
( (or (= 5 gr1) (= 3 gr1))
(setq pt2 (trans gr2 1 0)
pt1 (vlax-curve-getclosestpointto ent pt2)
)
(if (not (equal pt1 pt2 1e-8))
(progn
(setq dis (/ (* hgt off) (distance pt1 pt2))
ang (+ (angle (trans pt1 0 1) gr2) uxa rot pi2)
)
(vlax-put-property txt prn (vlax-3D-point (mapcar '(lambda ( a b ) (+ a (* (- b a) dis))) pt1 pt2)))
(vla-put-rotation txt (if red (atc:readable ang) ang))
)
)
(cond
( (= 5 gr1))
( mtp
(setq txt (vla-copy txt)
prp nil
)
t
)
)
)
( (= 2 gr1)
(cond
( (member gr2 '(043 061))
(setq off (+ off 0.1))
)
( (member gr2 '(045 095))
(setq off (- off 0.1))
)
( (member gr2 '(044 060))
(setq rot (+ rot (/ pi 4.0)))
)
( (member gr2 '(046 062))
(setq rot (- rot (/ pi 4.0)))
)
( (member gr2 '(013 032 069 101))
(*error* nil)
nil
)
( (member gr2 '(089 121))
(if (setq red (not red))
(princ "\n<Text Readability Enabled>")
(princ "\n<Text Readability Disabled>")
)
(princ msg)
)
( (member gr2 '(066 098))
(if (= "AcDbMText" (vla-get-objectname txt))
(progn
(vlax-put txt 'backgroundfill (~ (vlax-get txt 'backgroundfill)))
(if (setq bak (= -1 (vlax-get txt 'backgroundfill)))
(princ "\n<Background Mask On>")
(princ "\n<Background Mask Off>")
)
)
(princ "\nBackground mask only available with MText.")
)
(princ msg)
)
( (member gr2 '(082 114))
(if (setq tmp (getangle (strcat "\nSpecify Rotation <" (angtos rot) ">: ")))
(setq rot tmp)
)
(princ msg)
)
( (member gr2 '(079 111))
(if (setq tmp (getdist (strcat "\nSpecify Offset <" (rtos (* hgt off)) ">: ")))
(setq off (/ tmp hgt))
)
(princ msg)
)
( t )
)
)
( (member gr1 '(11 25))
(*error* nil)
nil
)
( t )
)
)
)
(if mat (entdel ent))
(atc:writeconfig cfg (mapcar 'eval sym))
)
)
(atc:endundo (atc:acdoc))
(princ)
)

;;----------------------------------------------------------------------;;

(defun atc:readable ( a )
( (lambda ( a )
(if (and (< (* pi 0.5) a) (<= a (* pi 1.5)))
(atc:readable (+ a pi))
a
)
)
(rem (+ a pi pi) (+ pi pi))
)
)

;;----------------------------------------------------------------------;;

(defun atc:styleheight ( sty / tmp )
(if (zerop (setq tmp (cdr (assoc 40 (tblsearch "style" sty)))))
(setq tmp (getvar 'textsize))
)
(if (atc:annotative-p sty)
(/ tmp (cond ((getvar 'cannoscalevalue)) (1.0)))
tmp
)
)

;;----------------------------------------------------------------------;;

(defun atc:annotative-p ( sty )
(and
(setq sty (tblobjname "style" sty))
(setq sty (cadr (assoc -3 (entget sty '("AcadAnnotative")))))
(= 1 (cdr (assoc 1070 (reverse sty))))
)
)

;;----------------------------------------------------------------------;;

(defun atc:copynested ( ent mat / enx tmp )
(if (= 1 (cdr (assoc 66 (setq enx (entget ent)))))
(progn
(atc:entmakex enx)
(setq ent (entnext ent)
enx (entget ent)
)
(while (/= "SEQEND" (cdr (assoc 0 enx)))
(atc:entmakex enx)
(setq ent (entnext ent)
enx (entget ent)
)
)
(setq tmp (cdr (assoc 330 (entget (atc:entmakex enx)))))
)
(setq tmp (atc:entmakex enx))
)
(if tmp (vla-transformby (vlax-ename->vla-object tmp) (vlax-tmatrix mat)))
tmp
)

;;----------------------------------------------------------------------;;

(defun atc:entmakex ( enx )
(entmakex
(append
(vl-remove-if
(function
(lambda ( x )
(or (member (car x) '(005 006 008 039 048 062 102 370))
(= 'ename (type (cdr x)))
)
)
)
enx
)
'(
(006 . "CONTINUOUS")
(008 . "0")
(039 . 0.0)
(048 . 1.0)
(062 . 7)
(370 . 0)
)
)
)
)

;;----------------------------------------------------------------------;;

(defun atc:getproperties ( obj )
(vl-remove nil
(mapcar
(function
(lambda ( prp )
(if (vlax-property-available-p obj prp t)
(list prp (vlax-get-property obj prp))
)
)
)
'(
insertionpoint
textalignmentpoint
backgroundfill
rotation
)
)
)
)

;;----------------------------------------------------------------------;;

(defun atc:settings ( dcl lst / *error* alg bak dch jus mtp off off:str red rot rot:str typ typ:fun )

(defun *error* ( msg )
(if (< 0 dch)
(unload_dialog dch)
)
(if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
(princ (strcat "\nError: " msg))
)
(princ)
)

(cond
( (not (atc:writedcl dcl))
(princ "\nDCL file could not be written.")
)
( (<= (setq dch (load_dialog dcl)) 0)
(princ "\nDCL file could not be loaded.")
)
( (not (new_dialog "atc" dch))
(princ "\nProgram dialog could not be loaded.")
)
( t
(mapcar 'set '(typ jus off rot red bak mtp) lst)

(set_tile typ "1")
(
(setq typ:fun
(lambda ( typ )
(setq alg (atc:justlist typ))
(set_tile "jus"
(itoa
(cond
( (vl-position jus alg))
( (setq jus (car alg)) 0)
)
)
)
(if (= "mtx" typ)
(mode_tile "bak" 0)
(mode_tile "bak" 1)
)
)
)
typ
)
(action_tile "jus" "(setq jus (nth (atoi $value) alg))")
(action_tile "txt" "(typ:fun (setq typ $key))")
(action_tile "mtx" "(typ:fun (setq typ $key))")

(set_tile "off" (setq off:str (rtos off)))
(action_tile "off" "(setq off:str $value)")

(set_tile "rot" (setq rot:str (angtos rot)))
(action_tile "rot" "(setq rot:str $value)")

(foreach key '("red" "bak" "mtp")
(set_tile key (if (eval (read key)) "1" "0"))
(action_tile key (strcat "(setq " key " (= \"1\" $value))"))
)
(action_tile "accept"
(vl-prin1-to-string
'(cond
( (not (distof off:str))
(alert "\nOffset Factor must be numerical.")
(mode_tile "off" 2)
)
( (not (angtof rot:str))
(alert "\nText Rotation must be numerical.")
(mode_tile "rot" 2)
)
( (setq off (distof off:str)
rot (angtof rot:str)
)
(done_dialog 1)
)
)
)
)

(if (= 1 (start_dialog))
(setq lst (list typ jus off rot red bak mtp))
)
)
)
(if (< 0 dch)
(unload_dialog dch)
)
lst
)

;;----------------------------------------------------------------------;;

(defun atc:justlist ( typ / lst )
(start_list "jus")
(foreach itm
(setq lst
(append
(if (= "txt" typ)
'(
"Left"
"Center"
"Right"
"Middle"
)
)
'(
"Top-Left"
"Top-Center"
"Top-Right"
"Middle-Left"
"Middle-Center"
"Middle-Right"
"Bottom-Left"
"Bottom-Center"
"Bottom-Right"
)
)
)
(add_list itm)
)
(end_list)
lst
)

;;----------------------------------------------------------------------;;

(defun atc:layerlocked ( lay / def )
(and
(setq def (tblsearch "layer" lay))
(= 4 (logand 4 (cdr (assoc 70 def))))
)
)

;;----------------------------------------------------------------------;;

(defun atc:writedcl ( dcl / des )
(cond
( (findfile dcl))
( (setq des (open dcl "w"))
(foreach x
'(
"edt : edit_box"
"{"
" edit_width = 8;"
" edit_limit = 10;"
" alignment = left;"
"}"
"atc : dialog"
"{"
" label = \"Settings\";"
" spacer;"
" : text"
" {"
" label = \"Object type for new text:\";"
" }"
" : radio_row"
" {"
" alignment = centered;"
" fixed_width = true;"
" : radio_button"
" {"
" key = \"txt\";"
" label = \"Text\";"
" }"
" : radio_button"
" {"
" key = \"mtx\";"
" label = \"MText\";"
" }"
" }"
" spacer;"
" : text"
" {"
" label = \"Justification for new text:\";"
" }"
" : popup_list"
" {"
" key = \"jus\";"
" }"
" spacer;"
" : edt"
" {"
" key = \"off\";"
" label = \"Offset Factor:\";"
" }"
" : edt"
" {"
" key = \"rot\";"
" label = \"Text Rotation:\";"
" }"
" spacer;"
" : toggle"
" {"
" key = \"red\";"
" label = \"Retain Text Readability\";"
" }"
" : toggle"
" {"
" key = \"bak\";"
" label = \"MText Background Mask\";"
" }"
" : toggle"
" {"
" key = \"mtp\";"
" label = \"Multiple Text Mode\";"
" }"
" spacer;"
" ok_cancel;"
"}"
)
(write-line x des)
)
(setq des (close des))
(while (not (findfile dcl)))
dcl
)
)
)

;;----------------------------------------------------------------------;;

(defun atc:writeconfig ( cfg lst / _tostring des )

(defun _tostring ( x / dim )
(cond
( (= 'int (type x))
(itoa x)
)
( (= 'real (type x))
(setq dim (getvar 'dimzin))
(setvar 'dimzin 0)
(setq x (rtos x 2 8))
(setvar 'dimzin dim)
x
)
( (vl-prin1-to-string x))
)
)

(if (setq des (open cfg "w"))
(progn
(foreach x lst (write-line (_tostring x) des))
(setq des (close des))
t
)
)
)

;;----------------------------------------------------------------------;;

(defun atc:readconfig ( cfg lst / des itm )
(if
(and
(setq cfg (findfile cfg))
(setq des (open cfg "r"))
)
(progn
(foreach sym lst
(if (setq itm (read-line des))
(set sym (read itm))
)
)
(setq des (close des))
t
)
)
)

;;----------------------------------------------------------------------;;

(defun atc:savepath ( / tmp )
(if (setq tmp (getvar 'roamablerootprefix))
(strcat (atc:fixdir tmp) "\\Support")
(atc:fixdir (getvar 'tempprefix))
)
)

;;----------------------------------------------------------------------;;

(defun atc:fixdir ( dir )
(vl-string-right-trim "\\" (vl-string-translate "/" "\\" dir))
)

;;----------------------------------------------------------------------;;

(defun atc:startundo ( doc )
(atc:endundo doc)
(vla-startundomark doc)
)

;;----------------------------------------------------------------------;;

(defun atc:endundo ( doc )
(while (= 8 (logand 8 (getvar 'undoctl)))
(vla-endundomark doc)
)
)

;;----------------------------------------------------------------------;;

(defun atc:acdoc nil
(eval (list 'defun 'atc:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object))))
(atc:acdoc)
)

;;----------------------------------------------------------------------;;

(vl-load-com)
(princ
(strcat
"\n:: AlignTextToCurve.lsp | Version "
atc:version
" | \\U+00A9 Lee Mac "
(menucmd "m=$(edtime,0,yyyy)")
" www.lee-mac.com ::"
"\n:: Type \"atc\" to Invoke ::"
)
)
(princ)

;;----------------------------------------------------------------------;;
;; End of File ;;
;;----------------------------------------------------------------------;;

 

Message 6 of 18

Hannan1
Advocate
Advocate
Can you add a option multiple text selection
Message 7 of 18

john.uhden
Mentor
Mentor
It's not very difficult to align text to a polyline segment. I have an ATEXT.lsp that will do it, but in your drawing it 's not immediately clear as to which segment to align the text. My first reaction is to use the segment that is closest to the text, but that may not be appropriate. Then again nearest to what... the beginning of the text, the end of the text, the middle center, top center, bottom center?

To automate whatever the desired conditions may be, the harder part is to find the polyline that surrounds each piece of text. I think I already have the code for that unless I left it on the work PC at my last job.

Were you going to write the code yourself with our help, or were you looking for a gift, as in freeware?

John F. Uhden

Message 8 of 18

HullDrafter
Advocate
Advocate

I just use "BA".

It will line up my text and I just arrange it for where it needs to be.

HD

0 Likes
Message 9 of 18

Hannan1
Advocate
Advocate
Hi,

Thanks for the info!
Were i get this "ATEXT.LSP" can you send me link please.
0 Likes
Message 10 of 18

john.uhden
Mentor
Mentor
I haven't made it available as freeware. These days I just like to hang around here to help and learn.

John F. Uhden

Message 11 of 18

Hannan1
Advocate
Advocate
Okey , Fine Thanks
0 Likes
Message 12 of 18

jackel74
Participant
Participant

Can I ask if your lisp routine would be able to automatically rotate multiple text aligning to a polyline for a topographical survey - basically to align level text with features > - 

 

Cheers in advance

 

K 🙂

 

Karl 

0 Likes
Message 13 of 18

john.uhden
Mentor
Mentor

@jackel74 

Around here there are some who can do most anything.  I love to learn from them.

Anyway, I have a LabelContour (LC) command that orients the elevation text tangent to the contour and adjusts the rotation according to the current viewtwist for legibility.  Yes, we have Civil3D for building surface models but with so many of our sites being on the waterfront, it's easier for me to just draw the one, two, or three contours within the site, and label them as fast as pick pick pick.

Might that be related to your need?  What exactly are you trying to do?

John F. Uhden

0 Likes
Message 14 of 18

jackel74
Participant
Participant

Thanks for the quick reply - 

 

Actually no thats not really what I am after (I think lol) 

 

I have added a couple of screendump's - 

 

One shows the raw data and the other shows what im trying to do 🙂 

 

I think it will be obvious once you see - my bad for not adding soz 🙂

 

cheers again for spending your time looking for me 🙂 

 

 

K 🙂

0 Likes
Message 15 of 18

john.uhden
Mentor
Mentor

@jackel74 

Okay, so all the elevation shots are random?  How is the 3Dpoly getting created?

It seems as though you might wish just to label each vertex of the 3Dpolys, is that correct?

What about all those other random shots that do not fall on a 3Dpoly?

I am confused because one would think that the shots would come first (and labeled) and the poly would be drawn after.  Are the labels like a "SPOT" block with a point or an X for it's location and an attribute for the elevation?

John F. Uhden

0 Likes
Message 16 of 18

jackel74
Participant
Participant

Basically the polylines are created from survey data - this is processed and it produces spot levels as well as feature lines with associated level text and autocad points - 

 

It seems someone else had a solution for this :

 

;-----
(vl-load-com)

(defun c:RotateToLine ( / ss pl i en ed pc pt pp an et)

(if (and (setq ss (ssget "_:L" '((0 . "*TEXT,INSERT"))))
(setq pl (car (entsel "\nSelect line to enclose to: ")))
(wcmatch (cdr (assoc 0 (entget pl))) "*LINE,ARC,CIRCLE,RAY")
(wcmatch (cdr (assoc 0 (entget pl))) "~MLINE")
)
(repeat (setq i (sslength ss))
(if (setq en (ssname ss (setq i (1- i)))
ed (entget en)
et (cdr (assoc 0 ed))
pc (if (and (= "TEXT" et)
(/= 0 (cdr (assoc 72 ed)) (cdr (assoc 73 ed))))
11
10)
pt (cdr (assoc pc ed))
pp (vlax-curve-getClosestPointTo pl pt)
an (angle '(0 0 0) (vlax-curve-getFirstDeriv pl (vlax-curve-getParamAtPoint pl pp))))
(entmod (append ed
(list ;(cons pc (polar pp (angle pp pt) 0))
(cons 50 (setq an (if (= et "MTEXT")
(- an (angle '(0 0 0) (getvar 'UCSXDIR)))
an)
an (if (< an 0)
(+ an (* 2 pi))
an)
an (if (and (<= (if (= et "MTEXT")
an
(angle (trans '(0 0 0) 0 1) (trans (polar '(0 0 0) an 1) 0 1))) ; readable text mtext ucs
(* 1.5 pi))
(> (if (= et "MTEXT")
an
(angle (trans '(0 0 0) 0 1) (trans (polar '(0 0 0) an 1) 0 1)))
(* 0.5 pi)))
(+ an pi)
an)))))))))
(princ)
)

 

For future reference 🙂

 

I basically am trying to make a topographical survey drawing look better and have the levels follow features - but the stand alone spot levels would not change 🙂 

 

 

Cheers for your assistance on this - I do love this site and all the people in it 🙂

 

 

Thanks again for the support 

 

 

k 🙂

0 Likes
Message 17 of 18

john.uhden
Mentor
Mentor

@jackel74 

Good.  You already have a tool.  Of course it adheres to the UCS whereas around these parts (NJ) I sorta established the technique of using VIEWTWIST.

Anyway, let's see if my sluggish brain can get this...

The textual labels are already in the drawing, but all horizontal, whereas you want them aligned tangent to each polyline segment.  What object type is the text (text, mtext, mleader, attribute)?

Since each vertex has a segment on each side, how would you like the text aligned, to the previous segment or to the subsequent segment (which is confusing because the polyline could have been created either CW or CCW)?

Actually, we don't need the existing text at all since each vertex has an elevation, right?

BTW, I don't mean to hurt your feelings, but I think the horizontal text looks better than the aligned text.

John F. Uhden

0 Likes
Message 18 of 18

cregdieziger
Enthusiast
Enthusiast

This little lisp routine works for me;

 

(defun c:AT( / txt txtobj osm pt0 tang) ;align text but don't move
(setq osm (getvar "osmode"))
(while
(setq txt(car(entsel "\nselect text or mtext: ")))
(redraw txt 3)
(setq txtobj(entget txt))
(setvar "osmode" 512) ;near
(setq pt0 (getpoint "\nPick a point (Osnap NEAR is on):"))
(setq tang (getangle pt0 "\nPick a direction (near): "))
(setvar "osmode" osm) ;reset osnap
(setq txtobj(subst (cons 50 tang) (assoc 50 txtobj) txtobj))
(entmod txtobj)
) ;while
(princ))

 

@Automohan 

0 Likes