Convert multiple texts that are in proximity to each other into Mtext

Convert multiple texts that are in proximity to each other into Mtext

gilberto.liraV9VSW
Explorer Explorer
793 Views
6 Replies
Message 1 of 7

Convert multiple texts that are in proximity to each other into Mtext

gilberto.liraV9VSW
Explorer
Explorer

I have a project with over 300 labels. I need to convert each group of 4 text into a single mtext. I'm currenlty using txt2mtxt individually to convert into 1 mtext. This question came up already but it was to convert 2 text into mtxt. It worked but it converted my group of 4 text into 2 seperate Mtext. 

 

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/convert-texts-that-are-close-to-each...

 

 

0 Likes
Accepted solutions (1)
794 Views
6 Replies
Replies (6)
Message 2 of 7

gilberto.liraV9VSW
Explorer
Explorer

This is the code that worked for 2 text but i need help chaning it to 4 text. 

 

(defun C:2T2M ; = 2 nearby Text objects {to} two-line Mtext
  (/ ss1 T1 minpt maxpt LL UR ss2 T2 data1 data2 txt1 txt2)
  (if (setq ss1 (ssget "_:L" '((0 . "TEXT"))))
    (while (> (sslength ss1) 1); still at least 2 Text objects remaining
      (setq T1 (ssname ss1 0))
      (vla-getboundingbox (vlax-ename->vla-object T1) 'minpt 'maxpt)
      (setq
        LL (vlax-safearray->list minpt)
        UR (vlax-safearray->list maxpt)
      ); setq
      (if
        (and ; finds 2 Text objects [including T1] in vicinity
          (setq ss2
            (ssget
              "_C"
                (polar LL (angle UR LL) (distance LL UR))
                (polar UR (angle LL UR) (distance LL UR))
              '((0 . "TEXT"))
            ); ssget
          ); setq
          (= (sslength ss2) 2)
        ); and
        (progn ; then
          (setq T2 (ssname (ssdel T1 ss2) 0))
          (vla-getboundingbox (vlax-ename->vla-object T2) 'minpt 'maxpt)
          (setq ; collective bounding box of both
            LL (mapcar 'min (vlax-safearray->list minpt) LL)
            UR (mapcar 'max (vlax-safearray->list maxpt) UR)
            data1 (entget T1)
            data2 (entget T2)
            txt1 (cdr (assoc 1 data1))
            txt2 (cdr (assoc 1 data2))
          ); setq
          (command "_.ucs" "_object" T1)
          (if (minusp (cadr (trans (cdr (assoc 10 data2)) 0 1))); T2 "under" T1
            (setq txtA txt1 txtB txt2); then
            (setq txtA txt2 txtB txt1); else
          ); if
          (command
            "_.ucs" "_previous"
            "_.mtext"
              "_non" LL
              "_height" (cdr (assoc 40 data1))
              "_rotation" (cdr (assoc 50 data1))
              "_style" (cdr (assoc 7 data1))
              "_justify" "_mc" "_non" UR
              (strcat txtA "\\P" txtB) ""
            "_.matchprop" T1 (entlast) "" ; Layer, color etc. override(s)
            "_.erase" T1 T2 ""
          ); command
          (ssdel T1 ss1) (ssdel T2 ss1)
        ); progn
        (ssdel T1 ss1); else [no other nearby]
      ); if
    ); while
  ); if
  (princ)
); defun
0 Likes
Message 3 of 7

komondormrex
Mentor
Mentor
Accepted solution

check the following. almost all of 4 and 3 lines text will be joined to mtexts. upon completing all mtexts are hidden. few remaining lines of text may be converted to mtext using txt2mtxt et command. to unhide hidden mtext use unisolateobjects command. alignment to all mtexts is top left.

 

(defun c:text_autojoin (/ bottom_text_sset text_lines_sset text_box text_lines_list mtext_line mtext)
  (if (setq bottom_text_sset (ssget "_x" '((0 . "text") (1 . "*(*),02-T*"))))
    (foreach text (vl-remove-if 'listp (mapcar 'cadr (ssnamex bottom_text_sset)))
      (setq text_lines_sset (ssget "_f" 
                    (list (cdr (assoc 10 (entget text)))
                        (mapcar '+ (cdr (assoc 10 (entget text))) 
                             (list (abs (car (mapcar '- (car (setq text_box (textbox (entget text)))) (cadr text_box)))) 
                                 30
                             )
                        )
                        (mapcar '+ (cdr (assoc 10 (entget text))) 
                             (list (abs (car (mapcar '- (car text_box) (cadr text_box)))) 
                                 0
                             )
                        )
                        (mapcar '+ (cdr (assoc 10 (entget text))) 
                             (list 0
                                 30
                             )
                        )
                    )
                    (list '(0 . "text")
                         '(-4 . "<and")
                             '(-4 . "<not")
                                 '(1 . "*(*),02-T*")
                             '(-4 . "not>")
                         '(-4 . "and>")
                         (assoc 62 (entget text))
                    )
                  )
          text_lines_list (append (vl-sort (vl-remove-if 'listp (mapcar 'cadr (ssnamex text_lines_sset)))
				   	  '(lambda (text_1 text_2) (> (caddr (assoc 10 (entget text_1))) (caddr (assoc 10 (entget text_2)))))
			  	  )
				  (list text)
			  )
          mtext_line ""
      )
      (foreach line text_lines_list
        (setq mtext_line (strcat mtext_line (cdr (assoc 1 (entget line))) "\\P")) 
      )
        (setq mtext (vla-addmtext (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
		            	  (vlax-3d-point (cdr (assoc 10 (entget (car text_lines_list)))))
		            	  0
		            	  mtext_line
		    )
	)
      	(vla-put-height mtext (cdr (assoc 40 (entget text))))
      	(vla-put-color mtext (cdr (assoc 62 (entget text))))
      	(vla-put-layer mtext (cdr (assoc 8 (entget text))))
      	(mapcar 'entdel text_lines_list) 
    )
  )
  (command "_hideobjects" (ssget "_x" '((0 . "mtext"))) "")
  (princ)
)

 

Message 4 of 7

daniel_cadext
Advisor
Advisor

I played with is in Python, using an RTree to locate interesting bounding boxes

didn't quite work selecting the whole thing because of the selection set order.

it should be possible to sort the texts,

 

https://www.theswamp.org/index.php?topic=58909.0

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 5 of 7

Sea-Haven
Mentor
Mentor

Double posted Solved: Convert texts that are close to each other into Mtext - Page 2 - Autodesk Community - AutoCA...

 

Like you I looked at intersecting bounding box.

 

Was thinking sort text based on X & Y then look at Y distance between text is same then add to mtext string, else new string. For sample its 8.7637. This is 2 blocks of text the distance between. The 1st value would be say 0.

8.764
8.764
7.702
95.444
8.764
8.763
7.702

Now to try to put into practice. Noticed the 7.7 the last text is closer so use a max value.

 

 

0 Likes
Message 6 of 7

daniel_cadext
Advisor
Advisor

the lisp routine doesn't work as the request, unless I'm missing something

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 7 of 7

gilberto.liraV9VSW
Explorer
Explorer

This worked perfectly. Thank you. 

0 Likes