Jump to content

Help with lisp to move text to specific locations w/ a better narrative.


poffenberger

Recommended Posts

I need help with a lisp to move multiple, (3)lines of text, to a point or an insertion point. I was helped the other day by a awesome individual who instructed me on using the Point Manager and then a lisp to move text to point, and it worked great. I'd like to somehow incorporate similar logic to move (3) lines of text (multiple (3)lines of text) to a common point relative to each set of (3)line text strings. Please see attachment for a visual narrative. Any help will be greatly appreciated. I'll also share the txt2pt code in the hopes that it maybe tweaked to work in this scenario.

 

I'd like to thank you all advance,

 

Paul

Move Green Text.dwg

Move Green Text.pdf

txt2pt.LSP

PtManagerV2-4.lsp

Link to comment
Share on other sites

  • Replies 21
  • Created
  • Last Reply

Top Posters In This Topic

  • poffenberger

    11

  • ronjonp

    10

  • Roy_043

    1

I need help with a lisp to move multiple, (3)lines of text, to a point or an insertion point. I was helped the other day by a awesome individual who instructed me on using the Point Manager and then a lisp to move text to point, and it worked great. I'd like to somehow incorporate similar logic to move (3) lines of text (multiple (3)lines of text) to a common point relative to each set of (3)line text strings. Please see attachment for a visual narrative. Any help will be greatly appreciated. I'll also share the txt2pt code in the hopes that it maybe tweaked to work in this scenario.

 

I'd like to thank you all advance,

 

Paul

 

Based on your example drawing .. try this:

(defun c:foo (/ p t1 t2 t3 x y)
 ;; RJP - 07.07.2017
 ;; Load visual lisp
 (vl-load-com)
 ;; This is a the y offset for text based on example drawing
 ;; (setq y 0.145833)
 (cond
   ;; If no text on layer "OLI_IDTEXT" are in the drawing exit and prompt
   ((null (setq t1 (ssget "_x" '((0 . "text") (8 . "OLI_IDTEXT")))))
    (print "'OLI_IDTEXT' text not found!")
   )
   ;; If no text on layer "OLI_ANTEXT" are in the drawing exit and prompt
   ((null (setq t2 (ssget "_x" '((0 . "text") (8 . "OLI_ANTEXT")))))
    (print "'OLI_ANTEXT' text not found!")
   )
   ;; Rock and roll  .. compile a list of all the green text to be moved as a list of ((<alignment_point> . ename)...)
   ((setq
      t2 (mapcar '(lambda (x) (cons (cdr (assoc 11 (entget x))) x)) (mapcar 'cadr (ssnamex t2)))
    )
    ;; Changed to be a 2X factor of the text height in drawing
    (setq y (* 2. (cdr (assoc 40 (entget (cdr (car t2)))))))
    ;; Foreach base text
    (foreach base (mapcar 'cadr (ssnamex t1))
      ;; Grab the alignment point to move to
      (setq p (cdr (assoc 11 (entget base))))
      (if
 ;; Sort the 'green text' list by distance
 (and (setq t3 (vl-sort t2 '(lambda (a b) (< (distance p (car a)) (distance p (car b))))))
      ;; and check that we have at least 3 items in the sorted list
      (>= (length t3) 3)
 );; For the first 3 items in sorted green text list ( closest to base text )
  (foreach x (list (car t3) (cadr t3) (caddr t3))
    ;; Move the text using the base text x value and incrementing the y value by 2X the text height
    (vlax-invoke
      (vlax-ename->vla-object (cdr x))
      'move
      (car x)
      (setq p (list (car p) (+ y (cadr p)) 0.0))
    )
    ;; Remove the item from the 'green text' list so it won't get processed twice
    (setq t2 (vl-remove x t2))
  )
      )
    )
   )
 )
 ;; Shhhh
 (princ)
)

Edited by ronjonp
added comments and fixed typo
Link to comment
Share on other sites

ronjonp,

Thanks for the reply.

I pasted your code in the visual lisp editor and saved to a .lsp file. Loaded application without any errors. In my drawing at the command line I typed foo then nothing... no prompts, errors nothing. Please let me know if my process is wrong. From just researching the forums I believe the foo after the c: is the command name?

 

Thanks

Paul

Link to comment
Share on other sites

You are awesome!!

 

I"m new to this coding thing so I'd like to ask you 2 things?

On a scale of 1-10 (10 being the hardest) how difficult was this?

 

Any recommendation on a starting point? Macro's - Lisp - Scripts. Do they sort of line up in a logical order to learn.

 

Thanks again for everything.

 

Paul

Link to comment
Share on other sites

@ronjonp:

There seems to be a typo here:

(foreach x t3 (setq t2 (vl-remove t3 t2)))

And you probably want to only remove the first 3 t3 items from t2.

Link to comment
Share on other sites

Roy_043,

 

This routine seems to work great, is there something I'm missing?

 

Roy is correct there was a typo ( actually a couple :?) ( fixed above ) .. the reason it worked fine is because nothing was being removed from the 't2' list because I was calling the whole list 't3' rather than the individual elements of 't3'. Scale of difficulty for me, I'd give it a 2 :).

As far as learning goes, just keep trying to understand what routines are given to you .. I'll comment the code above so you can learn from it .

Edited by ronjonp
Link to comment
Share on other sites

ronjonp,

 

I made an error in the move green text dwg file. For some reason I scaled the dwg by a factor of 1.5, so your routine works but the distance between the 4 lines of text is too great. Please find attached dwg at the proper scale and could I bother to repeat your magic on the move red text drawing.

 

Thanks again

Move Red Text.dwg

Link to comment
Share on other sites

Change: (setq y 0.218751) to (setq y 0.145833) .. I also commented the code above so take a look. 8)

 

Actually .. I modified the code above so it will use the 2X the text height as the Y spacing so it should not matter now. I can't believe you used to do this manually!

Link to comment
Share on other sites

Yes it's very time consuming

 

Sorta new to this "production" type drafting. I'm definitely going to start looking at other tasks that can be simplified.

 

So if I'm understanding you correctly; I just need to make a new lsp file from the code above? (the one that you originally made, but is now modified)

 

Thanks so much, hopefully I can pay it forward some day.

Link to comment
Share on other sites

Yes it's very time consuming

 

Sorta new to this "production" type drafting. I'm definitely going to start looking at other tasks that can be simplified.

 

So if I'm understanding you correctly; I just need to make a new lsp file from the code above? (the one that you originally made, but is now modified)

 

Thanks so much, hopefully I can pay it forward some day.

 

I did modify the original code for you. Hopefully you can learn from the comments. :)

Link to comment
Share on other sites

ronjonp,

 

Your code is working fine and is much appreciated. On the bigger drawings some of the text gets confused and lands up misplaced so to speak. Would there be a way to pause for user input and allow me to select the text I want, then have that selection move automatically; then repeat as necessary. Perhaps something similar to below?

 

(getpoint [ptlst] [prompt]) Waits for a user-input point and returns the coordinates of the point as a list. If the optional point list argument is supplied, a drag line appears from the point argument to the crosshairs. The optional prompt must be a string and appears on the command line when the program pauses while the user is selecting the point(s).

 

Thanks,

Paul

Link to comment
Share on other sites

ronjonp,

 

Your code is working fine and is much appreciated. On the bigger drawings some of the text gets confused and lands up misplaced so to speak. Would there be a way to pause for user input and allow me to select the text I want, then have that selection move automatically; then repeat as necessary. Perhaps something similar to below?

 

(getpoint [ptlst] [prompt]) Waits for a user-input point and returns the coordinates of the point as a list. If the optional point list argument is supplied, a drag line appears from the point argument to the crosshairs. The optional prompt must be a string and appears on the command line when the program pauses while the user is selecting the point(s).

 

Thanks,

Paul

Maybe post your drawing where results aren't as desired .. perhaps there are other rules to look for.

Link to comment
Share on other sites

Question: Is the text that is going to be moved always a consistent color? Your example drawing has them all as red.

 

If so, add the red part to the filter (null (setq t2 (ssget "_x" '((0 . "text") (8 . "OLI_ANTEXT")(62 . 1)))))

Link to comment
Share on other sites

At this point the answer would be no(they're all the same color). I've been changing the colors for clarity purposes. My first thought was to change the 'confused' text to another layer, which means I'd be hand selecting each one. This would be fine if it's the best solution. I was just wondering if there was perhaps something else we could do. I do appreciate all your help.

 

Thanks again,

Paul

Link to comment
Share on other sites

Try this version. It only grabs text within a specified max distance (setq maxd (* y 8.)) .. From my testing this approach works well on your drawing. I also left a couple of double check items in the code to circle base texts not processed and a line to show where the text was and where it moved to. Give it a go!

(defun c:foo (/ maxd p t1 t2 t3 x y)
 ;; RJP - 07.11.2017
 ;; Load visual lisp
 (vl-load-com)
 ;; This is a the y offset for text based on example drawing
 ;; (setq y 0.145833)
 (cond
   ;; If no text on layer "OLI_IDTEXT" are in the drawing exit and prompt
   ((null (setq t1 (ssget "_X" '((0 . "text") (8 . "OLI_IDTEXT")))))
    (print "'OLI_IDTEXT' text not found!")
   )
   ;; If no text on layer "OLI_ANTEXT" are in the drawing exit and prompt
   ((null (setq t2 (ssget "_X" '((0 . "text") (8 . "OLI_ANTEXT")))))
    (print "'OLI_ANTEXT' text not found!")
   )
   ;; Rock and roll  .. compile a list of all the green text to be moved as a list of ((<alignment_point> . ename)...)
   ((setq t2 (mapcar '(lambda (x) (cons (cdr (assoc 11 (entget x))) x))
	      (vl-remove-if 'listp (mapcar 'cadr (ssnamex t2)))
      )
    )
    ;; Changed to be a 2X factor of the text height in drawing
    (setq y (* 2. (cdr (assoc 40 (entget (cdr (car t2)))))))
    ;; Max distance allowed for closest results ( text height * 15 )
    (setq maxd (* y 8.))
    ;; Foreach base text
    (foreach base (mapcar 'cadr (ssnamex t1))
      ;; Grab the alignment point to move to
      (setq p (cdr (assoc 11 (entget base))))
      (if
 ;; Sort the 'green text' list by distance
 (and (setq t3 (vl-sort t2 '(lambda (a b) (< (distance p (car a)) (distance p (car b))))))
      ;; and check that we have at least 3 items in the sorted list
      (>= (length t3) 3)
 );; If the closest items are with the max distance set
  (if (<= (distance p (car (caddr t3))) maxd)
    ;; For the first 3 items in sorted green text list ( closest to base text )
    (foreach x (list (car t3) (cadr t3) (caddr t3))
      ;; Move the text using the base text x value and incrementing the y value by 2X the text height
      (vlax-invoke
	(vlax-ename->vla-object (cdr x))
	'move
	(car x)
	(setq p (list (car p) (+ y (cadr p)) 0.0))
      )
      ;; Line to check where text is moving
      (entmakex
	(list '(0 . "line") '(8 . "_RJPCheck") (cons 10 (car x)) (cons 11 p) '(62 . 30))
      )
      ;; Remove the item from the 'green text' list so it won't get processed twice
      (setq t2 (vl-remove x t2))
    )
    ;; Draw a circle to show that some 'base' text were not processed
    (entmakex
      (list '(0 . "circle") '(8 . "_RJPCheck") (cons 10 p) (cons 40 (* 0.5 maxd)) '(62 . 30))
    )
  )
      )
    )
   )
 )
 ;; Shhhh
 (princ)
)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...