Sort and Seperate txt and Mtxt

Sort and Seperate txt and Mtxt

eoconnor95662
Enthusiast Enthusiast
1,570 Views
9 Replies
Message 1 of 10

Sort and Seperate txt and Mtxt

eoconnor95662
Enthusiast
Enthusiast

Attached is a dummy DWG file where I have various alignments and both Mtext and Text all scrunched up together.

 

I am looking for a command where I can fence ALL the texts and have the LISP routine spit TEXT/MTEXT in order according to their X position, If they have the EXACT same X position then it spits it out in a different row either below or above (does not matter).

 

I know TXTALIGN followed by TXT2MTEXT followed by EXPLODE does something similar to what I want

but it only grabs the TXT files, not the MText also.

 

I have been talking with Kent, and I have some code edited/expanded by Kent Cooper that works for both Mtext and Text, however it requires individual selection for ordering.

 

Some additional difficulty might arise when sorting the position of MTEXTs/TEXTS that are vertically near each other and alternating, such as the example:

MTEXT, TEXT, MTEXT MTEXT, TEXT

resulting in: MTEXT, MTEXT, MTEXT, TEXT, TEXT or some less than ideal circumstance.

rather than the desired: MTEXT, TEXT, MTEXT MTEXT, TEXT  vertically spaced format.

 

 

I will be interested in hearing your suggestions, opinions or code on the matter.

 

Sincerely,

Bobston

 

0 Likes
1,571 Views
9 Replies
Replies (9)
Message 2 of 10

ronjonp
Advisor
Advisor

Maybe THIS will give you a start ... but probably not since that drawing is horrid. ;\ How was that created and why?

 

0 Likes
Message 3 of 10

ronjonp
Advisor
Advisor

A visual thing you could do so you can at least see what you're working with is set the height on those items to 1 rather than 10.

image.png

0 Likes
Message 4 of 10

eoconnor95662
Enthusiast
Enthusiast

Using explode (for mtexts), txtalign and a move command I can get the data to look a little nicer. Still don't know how to deal with same X position coordinates otherwise id just follow it up with txt2mtext and explode and call it a day.

Unfortunately this results in some rows containing multiple different text strings in the same mtext file.

0 Likes
Message 5 of 10

ronjonp
Advisor
Advisor

What are you doing with this? It's still looks like chaos to me even after a sort.

0 Likes
Message 6 of 10

eoconnor95662
Enthusiast
Enthusiast

This is a slightly exaggerated example of text and mtext but I need to separate out texts from each other (overlap) with different orientations en mass. That is the primary desire.

The secondary goal is to quickly and effectively maintain consistent positioning.

 

If this "Pandora's Box" problem can be solved I have a variety of applications for this. Such as but not limited to; selecting a group of potentially less stacked text and having it group and align for later design,  auto space text boxes, clean up messy drawings by spacing them out.

 

 

 

 

0 Likes
Message 7 of 10

ronjonp
Advisor
Advisor

Maybe this will get you started:

(defun c:foo (/ d h p s)
  ;; RJP » 2019-04-05
  (cond	((setq s (ssget ":L" '((0 . "*text"))))
	 ;; Convert the pickset to a list of vla-objects
	 (setq s (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))))
	 ;; Get largest text height x 2
	 (setq h (* 2. (apply 'max (mapcar '(lambda (x) (vla-get-height x)) s))))
	 ;; Sort top to bottom
	 (setq
	   s (vl-sort s
		      '(lambda (a b)
			 (> (cadr (vlax-get a 'insertionpoint)) (cadr (vlax-get b 'insertionpoint)))
		       )
	     )
	 )
	 ;; Top point
	 (setq p (vlax-get (car s) 'insertionpoint))
	 ;; Somewhat align text
	 (foreach o s
	   (vlax-put o 'insertionpoint p)
	   (and	(vlax-property-available-p o 'alignment)
		(/= 0 (vla-get-alignment o))
		(vlax-put o 'textalignmentpoint p)
	   )
	   (setq p (list (car p) (- (cadr p) h) (caddr p)))
	 )
	)
  )
  (princ)
)(vl-load-com)

image.png

0 Likes
Message 8 of 10

Kent1Cooper
Consultant
Consultant

Here's my take [modified from something else I had that did something similar horizontally]:

(vl-load-com)
(defun C:UnMess (/ corners tss ins tent tlist tsort n tdata tLL tUL ref)
  (defun corners ()
    (vla-getboundingbox (vlax-ename->vla-object tent) 'minpt 'maxpt)
    (setq
      tLL (vlax-safearray->list minpt)
      tUL (list (car tLL) (cadr (vlax-safearray->list maxpt)))
    ); setq
  ); defun -- corners
  (if
    (and
      (setq tss (ssget '((0 . "*TEXT"))))
      (setq ins (getpoint "\nNew top left corner of first object: "))
    ); and
    (progn ; then
      (repeat (setq n (sslength tss)); list of lists of insertion points & entity names
        (setq
          tent (ssname tss (setq n (1- n)))
          tdata (entget tent)
          tlist
            (cons
              (list ; pair insertion point with entity name
                (cdr (assoc 10 (entget tent))); insertion point
                tent ; entity name
              ); list
              tlist
            ); cons & tlist
        ); setq
      ); repeat
      (setq; list of entity names sorted in X direction
        tsort (mapcar 'cadr (vl-sort tlist '(lambda (a b) (< (caar a) (caar b))))); smaller X first
        n -1
        ref (polar ins (/ pi 2) (/ (cdr (assoc 40 (entget (car tsort)))) 2))
      ); setq
      (repeat (length tsort)
        (setq
          tent (nth (setq n (1+ n)) tsort); entity name
          tdata (entget tent)
        ); setq
        (entmod (subst '(50 . 0.0) (assoc 50 tdata) tdata)); rotation to 0
        (corners)
        (command "_.move" tent ""
          "_none" tUL
          "_none" (polar ref (* pi 1.5) (setq gap (/ (cdr (assoc 40 tdata)) 2)))
        ); command
        (corners); again in new location
        (setq ref (polar tLL (* pi 1.5) gap))
      ); while
    ); progn
  ); if
  (princ)
); defun -- C:UnMess

which does this:

UnMess.PNG

They line up on the left edge.  The spacing between is related to the height of each object, so they can vary in height, and it's based on their bounding boxes, so Mtext can have multiple lines.

 

Kent Cooper, AIA
0 Likes
Message 9 of 10

CodeDing
Advisor
Advisor

@eoconnor95662 ,

 

I wish I could spend more time looking into this since it looks like a fun challenge, but for what it's worth here is a function to return the width of the text objects:

(defun c:TEST ( / e)
(setq e (car (entsel "\nSelect MText or Text object: ")))
(if (member (cdr (assoc 0 (entget e))) '("TEXT" "MTEXT"))
  (prompt (strcat "\nText width is: " (rtos (GetTextWidth e) 2)))
  (prompt "\n...a Text or MText object was not selected.")
);if
(princ)
);defun

(defun GetTextWidth (e / w box tmp)
;e - ename, MText or Text
;returns width of text as real, or nil
(setq e (entget e) w nil)
(cond
  ((eq "MTEXT" (cdr (assoc 0 e)))
    (setq w (cdr (assoc 42 e)))
  );cond 1
  ((eq "TEXT" (cdr (assoc 0 e)))
    (setq box (textbox e))
    (setq tmp (list (car box) (list (car (cadr box)) (cadr (car box)))))
    (setq w (distance (car tmp) (cadr tmp)))
  );cond 2
  (t (prompt "\n...an incorrect object was passed to get text width."))
);cond
w
);defun

...this should help when trying to align them horizontally.

Best,

~DD

0 Likes
Message 10 of 10

CodeDing
Advisor
Advisor
...(caar...) ...can't believe I'm just now learning about these..
0 Likes