Slide text along a line/polyline

Slide text along a line/polyline

kzD1219
Collaborator Collaborator
7,722 Views
10 Replies
Message 1 of 11

Slide text along a line/polyline

kzD1219
Collaborator
Collaborator

I am looking for a quick lisp routine to slide a piece of text parallel with the line/polyline without having to type in move-select text-pick nearest to line-pick nearest to line to place my text where I want it.  I just want to be able to slide it along without having to do those 2 osnaps.

 

I know there are lisp routines out there.  I found one called dtcurve which allows you to pick text and then a line, but it doesn't work in my situation.  It just rotates the text and then allows me to move it along the polyline.  Even when ucs is in world, it will do the same thing so I am looking for something that works.  I have attached a jpeg of what ends up happening to my text with the lisp routine I do have.  Am I doing something wrong or do you happen to know of a lisp that works?

 

 

0 Likes
Accepted solutions (1)
7,723 Views
10 Replies
Replies (10)
Message 2 of 11

JustOpie
Advocate
Advocate

Have you seen Lee Mac's Slinky Text routine?

0 Likes
Message 3 of 11

kzD1219
Collaborator
Collaborator

Yes I have and that doesn't help what I am trying to do.  In the image attached, I would like to move the 50.38' text from one spot to another Keeping the same offset from the line.  So instead of typing move-nea-nea I would just like to be able to do a pick text, pick line and then be able to slide it parallel to the line.

0 Likes
Message 4 of 11

ВeekeeCZ
Consultant
Consultant

Mayby this would be enough... it's not that nice visual... but..

 

Spoiler
(defun c:MAL ( / ss pt pl pt1 pt2) ;Move Along Line
  (if (and (setq ss (ssget "_+.:E:S" '((0 . "TEXT"))))
	   (setq pt (cdr (assoc 10 (entget (ssname ss 0)))))
	   (setq pl (car (entsel "\nSelect geometry: ")))
	   (wcmatch (cdr (assoc 0 (entget pl))) "*LINE,ARC")
	   (setq pt1 (vlax-curve-getClosestPointTo pl pt))
	   )
    (command "_.MOVE" ss "" "_none" pt1 PAUSE
	     "_.MOVE" ss "" "_none" (setq pt2 (getvar 'LASTPOINT)) "_none" (vlax-curve-getClosestPointTo pl pt2)))
  (princ)
)
0 Likes
Message 5 of 11

kzD1219
Collaborator
Collaborator

I can see where you are going with this, but after loading the command, it doesn't allow me to select objects like it asks.

0 Likes
Message 6 of 11

ВeekeeCZ
Consultant
Consultant

And what are you selecting?

 

Try...

Spoiler
(vl-load-com)

(defun c:MAL ( / ss pt pl pt1 pt2) ;Move Along Line
  (if (and (setq ss (ssget "_+.:E:S" '((0 . "*TEXT"))))
	   (setq pt (cdr (assoc 10 (entget (ssname ss 0)))))
	   (setq pl (car (nentsel "\nSelect geometry (*line,arc): ")))
	   (wcmatch (cdr (assoc 0 (entget pl))) "*LINE,ARC")
	   (setq pt1 (vlax-curve-getClosestPointTo pl pt))
	   )
    (command "_.MOVE" ss "" "_none" pt1 PAUSE
	     "_.MOVE" ss "" "_none" (setq pt2 (getvar 'LASTPOINT)) "_none" (vlax-curve-getClosestPointTo pl pt2)))
  (princ)
)
0 Likes
Message 7 of 11

kzD1219
Collaborator
Collaborator

I am selecting mtext and a line. I have tried the lisp again and even just selecting text and a line with ucs world it will slide along the x and y of world, not the bearing of the line the text is on. If I adjust my ucs to what I used in the plan, selecting the text and line then just makes the text disappear off the screen. I use a lot of mtext, text and lines and polylines.

 

 

In Civil 3D 2015 once labels are inserted, they can slide along a line (as long as they aren't exploded).  I am looking for a lisp like that.

0 Likes
Message 8 of 11

ВeekeeCZ
Consultant
Consultant
Accepted solution

Ok then...

 

(vl-load-com)

(defun c:MAL ( / ss pt pl pt1 pt2) ;Move Along Line
  (if (and (setq ss (ssget '((0 . "*TEXT"))))
	   (setq pt (cdr (assoc 10 (entget (ssname ss 0)))))
	   (setq pl (car (nentsel "\nSelect geometry (*line,arc): ")))
	   (wcmatch (cdr (assoc 0 (entget pl))) "*LINE,ARC")
	   (setq pt1 (trans (vlax-curve-getClosestPointTo pl pt) 0 1))
	   )
    (command "_.MOVE" ss "" "_none" pt1 PAUSE
	     "_.MOVE" ss "" "_none" (setq pt2 (getvar 'LASTPOINT)) "_none" (trans (vlax-curve-getClosestPointTo pl (trans pt2 1 0)) 0 1)))
  (princ)
)
0 Likes
Message 9 of 11

kzD1219
Collaborator
Collaborator
That is a little freaky that you can move the text like that, but that is certainly what I am looking for.

Thank you! That will save so much time since we are constantly moving things to make room.
0 Likes
Message 10 of 11

Kent1Cooper
Consultant
Consultant

@kkD7719 wrote:

....  I would like to move the 50.38' text from one spot to another Keeping the same offset from the line.  So instead of typing move-nea-nea I would just like to be able to do a pick text, pick line and then be able to slide it parallel to the line.


If the Text [or Mtext] always starts out aligned with the direction of the Line [or Polyline line segment] as in your image, then think about it -- you don't need to pick the Line/Polyline [or any other path element] at all -- you don't even need to have a path associated with the situation.  You can just MOVE the [M]Text in the direction of its own Rotation angle.  Here's a way to do that, in which the total number of picks is only 2 [one to select the Text/Mtext, the other where you want to take it to].  Lightly tested, and without the usual bells and whistles yet, but see what you think:

(defun C:STRA (/ sna orth tsel tdata txt); = Slide Text along its Rotation Angle
  (setq
    sna (getvar 'snapang)
    orth (getvar 'orthomode)
  ); setq
  (if
    (and
      (setq tsel (entsel "\nSelect [M]Text to slide along its rotation angle: "))
      (wcmatch (cdr (assoc 0 (setq tdata (entget (setq txt (car tsel)))))) "*TEXT")
    ); and
    (progn ; then
      (setvar 'snapang (cdr (assoc 50 tdata)))
      (setvar 'orthomode 1); ORTHO on
      (command "_.move" txt "" (cadr tsel) pause)
      (setvar 'snapang sna)
      (setvar 'orthomode orth)
    ); progn
  ); if
); defun

That assumes it's always in relation to Lines or Polyline line segments [or Xlines, or Rays, or Mlines, or Traces, or edges of 3DFaces or 2D Solids, or nothing at all, or....].  BeekeeCZ's routine would, I expect, also only work as intended in straight-path situations, despite its letting you pick an Arc for a path [why not also a Circle?], which would presumably require a ROTATE command rather than MOVE, if you want its alignment relative to the curve to remain.  [It would also let you pick a SPLine as a path, which I assume isn't appropriate, but would not let you pick other viable straight paths such as a Ray.]

 

Kent Cooper, AIA
0 Likes
Message 11 of 11

ВeekeeCZ
Consultant
Consultant

@ВeekeeCZ wrote:

Maybe this would be enough...

Spoiler
 

Well... Kent says it's not... 🙂 ... I got understanding that kkD7719 knows how it works, that it has some limitations, so he knows what to do. But for other potention users... a for the OP as well...

 

Added rotation, you can move (almost) anything, not just text..., multiply.

 

 

Spoiler
(vl-load-com)

(defun c:MAL ( / ss pl pt p1 p2) ;Move Along Line
  (if (and (setq ss (ssget))
	   (setq pl (car (nentsel "\nSelect linear geometry: ")))
	   (wcmatch (cdr (assoc 0 (entget pl))) "*LINE,ARC,CIRCLE,RAY")
	   (wcmatch (cdr (assoc 0 (entget pl))) "~MLINE")
	   (setq p1 (trans (vlax-curve-getClosestPointTo pl (cdr (assoc 10 (entget (ssname ss 0))))) 0 1)) ; p1 ucs
	   )
    
    (command "_.MOVE" ss ""
	     "_none" p1 ; ucs
	     PAUSE

	     "_.MOVE" ss "" 
	     "_none" (setq pt (getvar 'LASTPOINT)) ; pt ucs
	     "_none" (setq p2 (trans (vlax-curve-getClosestPointTo pl (trans pt 1 0)) 0 1)) ; p2 ucs

	     "_.ROTATE" ss ""
	     "_none" p2
	     "_Reference"
	     '(0 0 0) ; wcs
	     (vlax-curve-getFirstDeriv pl (vlax-curve-getParamAtPoint pl (trans p1 1 0))) ; wcs
	     "_Points"
	     '(0 0 0) ; wcs
	     (vlax-curve-getFirstDeriv pl (vlax-curve-getParamAtPoint pl (trans p2 1 0))) ; wcs
	     )
    (princ "\nWrong selection. You can select '*LINE,ARC,CIRCLE,RAY' but 'MLINE'.")

    )
  (princ)
)

 

 If anyone finds the visual confusion (I think it's better than nothing), so I made the second version without the visual.

 

Spoiler
(vl-load-com)

(defun c:MAL2 ( / ss pl pt p1 p2) ;Move Along Line
  (if (and (setq ss (ssget))
	   (setq pl (car (nentsel "\nSelect linear geometry: ")))
	   (wcmatch (cdr (assoc 0 (entget pl))) "*LINE,ARC,CIRCLE,RAY")
	   (wcmatch (cdr (assoc 0 (entget pl))) "~MLINE")
	   (setq p1 (trans (vlax-curve-getClosestPointTo pl (cdr (assoc 10 (entget (ssname ss 0))))) 0 1)) ; p1 ucs
	   (setq pt  (getpoint p1 "\nSelect second point: "))
	   )
    
    (command 
	     "_.MOVE" ss "" 
	     "_none" p1 ; pt ucs
	     "_none" (setq p2 (trans (vlax-curve-getClosestPointTo pl (trans pt 1 0)) 0 1)) ; p2 ucs

	     "_.ROTATE" ss ""
	     "_none" p2
	     "_Reference"
	     '(0 0 0) ; wcs
	     (vlax-curve-getFirstDeriv pl (vlax-curve-getParamAtPoint pl (trans p1 1 0))) ; wcs
	     "_Points"
	     '(0 0 0) ; wcs
	     (vlax-curve-getFirstDeriv pl (vlax-curve-getParamAtPoint pl (trans p2 1 0))) ; wcs
	     )
    (princ "\nWrong selection. You can select '*LINE,ARC,CIRCLE,RAY' but 'MLINE'.")

    )
  (princ)
)