Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Reverse direction of any directional entity

19 REPLIES 19
Reply
Message 1 of 20
Kent1Cooper
4171 Views, 19 Replies

Reverse direction of any directional entity

A recent thread about text direction in complex linetypes got me thinking about this, and looking around.  I found several routines to reverse directions of things, but they all had limitations -- all work with only a limited set of entity types;  some lose all width information in Polylines, or can maintain global width but lose or do strange things with variable width, or change arc segments to line segments;  some don't account for UCS differences;  some make the reversed object under all current settings of Layer, linetype, color, etc. without regard to those qualities of the selected object;  etc., etc.

 

So I've been working on a more universal routine, and I think it's "ready," so it's attached:  ReverseDirection.lsp, with its RD command.  It works on Lines, Arcs, Circles, Polylines [any variety, including curve-fitted 2D and splined 2D or 3D], Ellipses, Splines & Multilines.  It preserves all properties of the selected objects, including varying width of Polylines.  See the top of the file for some notes on how it works with certain kinds of objects, particularly those for which it has to change entity type or make an approximation.  In the latter case, the User specifies the level of precision of the approximation.  Because of that, the routine asks you to pick things one at a time, and lets you Undo individual reversals as you go along, so that you can redo the reversal of one of those with higher precision if you want, without getting out of the command to undo, and without undoing other things you've already reversed.

 

I hope there are people out there who will find it useful.

Kent Cooper, AIA
19 REPLIES 19
Message 2 of 20
Kent1Cooper
in reply to: Kent1Cooper

So of course, I somehow discovered a very limited-possibility circumstance in which it didn't work right for one variety of one kind of drawing entity....

 

Use this version instead.

Kent Cooper, AIA
Message 3 of 20
Kent1Cooper
in reply to: Kent1Cooper

... and wouldn't you know it -- today I found another very limited circumstance in which something didn't work quite as expected.  Use this one instead.

Kent Cooper, AIA
Message 4 of 20
sean.keohane
in reply to: Kent1Cooper

Kent,

I found your lisp, looking for something else. Very nice, thanks for sharing.

Regards

Sean

Message 5 of 20
Kent1Cooper
in reply to: sean.keohane


@sean.keohane wrote:

Kent,

I found your lisp, looking for something else. Very nice, thanks for sharing.

Regards

Sean


Great!  That's one of the benefits of a forum like this.

 

In case anyone has any trouble downloading it from here, it's now also available from this site.

Kent Cooper, AIA
Message 6 of 20
skintsubby
in reply to: Kent1Cooper

Kent.

 

Brilliant wee routine. Thanks for this... very handy. Man Happy

 

Your efforts are very much appreciated.

 

 

Mark

Message 7 of 20
Kent1Cooper
in reply to: skintsubby


@skintsubby wrote:

.... 

Brilliant wee routine. Thanks for this... very handy. ....

....


I'm glad to know people are finding it useful.  [But I wouldn't have thought anyone would use the word "wee" to describe a file of 567 lines!]

Kent Cooper, AIA
Message 8 of 20
braudpat
in reply to: Kent1Cooper

 

 

Hello Kent

 

FIRST, THKS for all routines you have written for OPs ...

 

I have a few probem with your routine RD - Tested on MAP 2013 French ...

I don't think my problems are related to the French language of MAP !?

 

4 Test Objetcs : Line, Arc, Pline, Mline

On each object I add/attach Xdata and I add OD (Object Data of MAP) 

 

I reverse the 4 objects with your RD routine, the results are :

OK for Line & Pline : Xdata & OD are kept and correct !

Arc --> Pline Arc (Reverse is OK) !!! - Xdata and OD are lost !!

Mline (Reverse is OK) - - Xdata and OD are lost !!

 

It's STRANGE for me !?

 

Waiting for your opinion ?

 

Bye, Pat

 

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Message 9 of 20
Kent1Cooper
in reply to: braudpat


@braudpat wrote:

.... 

4 Test Objetcs : Line, Arc, Pline, Mline

On each object I add/attach Xdata and I add OD (Object Data of MAP) 

 

I reverse the 4 objects with your RD routine, the results are :

OK for Line & Pline : Xdata & OD are kept and correct !

Arc --> Pline Arc (Reverse is OK) !!! - Xdata and OD are lost !!

Mline (Reverse is OK) - - Xdata and OD are lost !!

....


I think that is probably because it reverses an Arc by converting it into a Polyline using PEDIT, and it reverses an Mline by drawing a new one in reverse order and with reverse justification, and giving it the old one's Layer and other properties.  For Lines and Polylines, all it does is substitute new endpoint and vertex/width/bulge entries into the same entity data list, which I imagine is why Xdata and OD are preserved.

 

I can imagine a way to retain Xdata and OD for an Mline, by instead giving the old one the new vertices and justification.  But I don't know about an Arc, since it's changing the entity type.  [There's no other way to reverse an Arc, unless it's acceptable to reverse its extrusion direction, but if the purpose is to get embedded Text elements in complex linetypes to read in the other direction, that won't do it in the right way -- it will be upside-down instead.]

 

I would be interested to know whether Xdata and OD are preserved for a Polyline that consists of only one zero-width arc segment, running clockwise, because the routine reverses that by Exploding it into an Arc.  So if it's the change in entity type that causes it to lose Xdata and OD, I assume it would also happen in that case.  If so, there are instructions in the code for having it reverse it still as a Polyline, instead of Exploding it into an Arc.

Kent Cooper, AIA
Message 10 of 20
klugb
in reply to: Kent1Cooper

Hi Kent,

I was searching for a similar routine and found this thread. What I'm looking for is a routine that will take 3D lines and set the direction to always be down slope or from the upper Z to the lower Z. This way I can select all of the lines in a drawing and globally change them all without having to know if they need to be reversed as some will and some won't.

Then I will assign our "Flow" linetype and our ditch lines will always be pointing the correct flow direction Smiley Happy

 

The attachment shows where the survey crew went down one ditch and back on the other and the directions are different even though they both flow the same direction.

 

Thanks

Bruce Klug, P.E.
AutoCAD Expert Elite Alumni
AutoCAD Civil 3D Certified Professional
Civil 3D 2023.2.1

Win 10 Enterprise, 64-bit
Message 11 of 20
Kent1Cooper
in reply to: klugb


@Anonymous wrote:

.... What I'm looking for is a routine that will take 3D lines and set the direction to always be down slope or from the upper Z to the lower Z. This way I can select all of the lines in a drawing and globally change them all without having to know if they need to be reversed as some will and some won't.

....


When you say "lines," do mean actual AutoCAD Line entities, or just paths/routes/courses that might be represented by Lines and/or Polylines and/or maybe some other things?  It shouldn't be hard to check for what you're looking for, in any case, using the returned values of (vlax-curve-getStartPoint) and (vlax-curve-getEndPoint) on them [which will work for any appropriate entity type], and comparing their Z coordinates -- if the starting Z is lower than the ending Z, reverse it.  I ask the question because if they're really always Lines, that would make for a much shorter routine than if they can be of any of those directional entity types.

Kent Cooper, AIA
Message 12 of 20
klugb
in reply to: Kent1Cooper

Thanks for the quick response!

 

They come to us as 3D Polylines but these can have multiple "low points" so we normally explode them and assign our "flow" linetype, but to get the arrows pointing correctly we have to check every one :(.

So, for us, they would all be AutoCAD lines with 2 different Z values.

 

Thanks

Bruce Klug, P.E.
AutoCAD Expert Elite Alumni
AutoCAD Civil 3D Certified Professional
Civil 3D 2023.2.1

Win 10 Enterprise, 64-bit
Message 13 of 20
Kent1Cooper
in reply to: klugb


@Anonymous wrote:

.... 

They come to us as 3D Polylines but these can have multiple "low points" so we normally explode them and assign our "flow" linetype, ...  So, for us, they would all be AutoCAD lines with 2 different Z values.

....


That's really so much simpler....  The attached LinesDown.lsp with its LD command does that in limited testing.  If any are level, they will be left alone.  You could turn it into one to make all selected Lines slope upward instead, just by changing the > to < and correcting the wording of certain things [including the file and command names].

Kent Cooper, AIA
Message 14 of 20
klugb
in reply to: Kent1Cooper

Awesome, works great.

Everything I checked looked good. The attached picture had 32 individual lines in it and the project had 478 total. You made our civil tech's day!!

 

Thanks Again for the quick work.

 

 

Bruce Klug, P.E.
AutoCAD Expert Elite Alumni
AutoCAD Civil 3D Certified Professional
Civil 3D 2023.2.1

Win 10 Enterprise, 64-bit
Message 15 of 20
damian.wrobel
in reply to: klugb

In your attached .png file, there are arrows. Do ypu draw them all as only helping objects which you delete after pecified time?

Or do you use this lisp?

https://autocadtips.wordpress.com/2014/06/24/autolisp-polyline-direction-preview/

 

I copy it on case the site will not work or something else (just in case):

 

;; Original Code by Luis Esquival http://www.theswamp.org/index.php?topic=9441.msg169894#msg169894
;; Displays the direction of polylines with temporary arrows
;;
;; Modified by RonJonP
;; http://www.theswamp.org/index.php?topic=35706.msg409414#msg409414
(vl-load-com)
(defun getarcsegment (cen r fromvertex p2 / a1 a2 d)
  (if (and fromvertex p2)
    (progn (setq a1 (angle cen fromvertex)
		 a2 (angle cen p2)
	   )
	   (if (or (< a1 a2) (equal a1 a2 0.001))
	     (setq d (* r (- a2 a1)))
	     (setq d (* r (- (+ 6.2831853 a2) a1)))
	   )
    )
    ;; is a circle
    (setq d (* r 6.2831853))
  )
)

(defun getbulgedata (bulge fromvertex p2 / dir theta beta radio dat)
  (setq	dir   (cond ((minusp bulge) -1.0)
		    (t 1.0)
	      )
	theta (* 4.0 (atan (abs bulge)))
  )
  (if (> theta pi)
    (setq theta	(- (* 2.0 pi) theta)
	  dir	(* -1.0 dir)
    )
  )
  (setq	theta (/ theta 2.0)
	radio (abs (/ (distance fromvertex p2) (* 2.0 (abs (sin theta)))))
	beta  (+ (angle fromvertex p2) (* (- (/ pi 2.0) theta) dir))
	pc    (polar fromvertex beta radio)
  )
  (getarcsegment pc radio p2 fromvertex)
)

(defun getlwpolydata
       (vla_poly / name endparam param closed fromvertex p2 midp bulge vlist)
  (setq closed (vla-get-closed vla_poly))
  (setq endparam (vlax-curve-getendparam vla_poly))
  (setq param endparam)
  (setq i 0)
  (while (> param 0)
    (setq param (1- param))
    (setq fromvertex (vlax-curve-getpointatparam vla_poly i))
    (if	(vlax-property-available-p vla_poly 'bulge)
      (setq bulge (vla-getbulge vla_poly (fix i)))
    )
    (setq nextvertex (vlax-curve-getpointatparam vla_poly (+ i 1)))
    (setq dis (distance fromvertex nextvertex))
    (setq midpt (vlax-curve-getpointatparam vla_poly (+ i 0.5)))
    (if	(and bulge (not (zerop bulge)))
      (progn (setq bulge (getbulgedata bulge fromvertex nextvertex))
	     (setq etype "ARC")
      )
      (progn bulge (setq etype "LINE"))
    )
;;;;;;    (if	(not :rcmPrefixArcText)
;;;;;;      (setq :rcmPrefixArcText "L="))
    (setq vlist	(cons (list ;; vertex number
			    (+ i 1)
			    ;; object type
			    etype
			    ;; midpoint
			    midpt
			    ;; start vertex
			    fromvertex
			    ;; ending vertex
			    nextvertex
			    ;; curved or straight length
;;;;;;	       (if (= eType "ARC")
;;;;;;		 (strcat
;;;;;;		   :rcmPrefixArcText
;;;;;;		   (rtos bulge (rcmd-getUnits-mode) :rcmPrec))
;;;;;;		 ;; is straight
;;;;;;		 (rtos dis (rcmd-getUnits-mode) :rcmPrec))
		      )
		      vlist
		)
    )
    (setq i (1+ i))
  )
  (reverse vlist)
)

(defun dib_flechdir (lst_dat / unidad angf dirf pfm pf1 pf2 pf3 pf4 pftemp)
  ;; set arrow length according to screen height
  ;; to draw the same arrows at any level of zoom
  (setq unidad (/ (getvar "VIEWSIZE") 15))
  (foreach dat lst_dat
    (setq angf (cadr dat)
	  dirf (caddr dat)
	  pfm  (polar (car dat) (+ angf (/ pi 2)) (* unidad 0.3))
	  pf1  (polar pfm (- angf pi) (/ unidad 2.0))
	  pf2  (polar pfm angf (/ unidad 2.0))
    )
    (if	(= dirf 1)
      (setq pf3	(polar pf2 (- angf (/ (* pi 5.0) 6.0)) (/ unidad 4.0))
	    pf4	(polar pf2 (+ angf (/ (* pi 5.0) 6.0)) (/ unidad 4.0))
      )
      (setq pftemp pf1
	    pf1	   pf2
	    pf2	   pftemp
	    pf3	   (polar pf2 (+ angf (/ pi 6.0)) (/ unidad 4.0))
	    pf4	   (polar pf2 (- angf (/ pi 6.0)) (/ unidad 4.0))
      )
    )
    (if	flag_dir
      (progn ;; draw green arrow
	     ;; when you are changing direction
	     (grdraw pf1 pf2 3)
	     (grdraw pf2 pf3 3)
	     (grdraw pf2 pf4 3)
      )
      (progn ;; draw arrow
	     (grdraw pf1 pf2 4)
	     (grdraw pf2 pf3 4)
	     (grdraw pf2 pf4 4)
      )
    )
  )
  (setq flag_dir nil)
)

;;; Command for test...
(defun c:PLD (/ pol obj pol_data)
  (setq	pol	 (car (entsel "\nSelect polyline: "))
	obj	 (vlax-ename->vla-object pol)
	pol_data (getlwpolydata obj)
  )
  (dib_flechdir
    (setq lst_dat
	   (vl-remove
	     nil
	     (mapcar (function (lambda (i)
				 (if (nth 2 i)
				   (list (nth 2 i) (angle (nth 3 i) (nth 4 i)) 1)
				 )
			       )
		     )
		     pol_data
	     )
	   )
    )
  )
  (princ)
)

 

 

I have something to write about this lisp.

 

1.
 Works for Polyline, Spline, Polygon, Rectangle, 3D Polyline
 Does not work for: Arc,Circle, Ellipse, Line, MultiLine
2.
 It is bad, that the arrows are only temporary.
 If you zoom out to look at other Polylines, the arrows will be gone.
3.
 For 3D Polylines, the arrows are not precisely aligned.

There should be lisp for "Show Direction", which:
1.
It will be working for all the types of Objects which I write above.
2.
And it will create the arrows which will be not temporary objects.
 They will be created on the new Layer called "Direction Arrows".

So if you want to erase these arrows, simply isolate objects on this layer (LAYISO) end delete them.

Or QSELECT -> and select all objects which Layer = Direction Arrows
3.
 They will be tangent to Splines, Circles, Arcs, Ellipses and aligned with Polylines etc.

Message 16 of 20
klugb
in reply to: damian.wrobel

We want them to stay with the arrows so we are using a basic linetype that shows the flow direction:

 

*Flow,---->---->---->---->
A,0,-0.005,0.025,-0.1,0.025,-0.1,[">",standard,S=.05,R=0.0,X=-0.05,Y=-.05],-.15

 

Now thanks to Kent it got a lot easier.

 

Bruce Klug, P.E.
AutoCAD Expert Elite Alumni
AutoCAD Civil 3D Certified Professional
Civil 3D 2023.2.1

Win 10 Enterprise, 64-bit
Message 17 of 20
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:
....  The attached LinesDown.lsp with its LD command does that in limited testing.  ....  You could turn it into one to make all selected Lines slope upward instead, just by changing the > to < ....

Here's a revised file, LinesSlopeSameDir.lsp, that has two commands: LD [to make them all slope Downward as before] and LU [to make them all slope Upward].  The latter may be appropriate for others in a similar situation if the linetype they use is defined with its pointers aiming the other way.  People may have other reasons to need two commands to go either way.

Kent Cooper, AIA
Message 18 of 20
damian.wrobel
in reply to: klugb

You had very good idea to create such a linetype.

I improved it and now the ">" are collinear with the "-":

 

*DW-Flow,---->---->---->---->
A,0.5,-5.0,[">",standard,S=2.5,R=0,X=-2.54,Y=-1.27],-2.0

 

it is - > - > - > - > etc.

 

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

 

Edit:

Now it is better:

 

*DW-Flow,---->---->---->---->
A,2.5,-2.5,[">",standard,S=2.5,R=0,X=-2.54,Y=-1.27],-0.15

 

Message 19 of 20
Kent1Cooper
in reply to: damian.wrobel


@damian.wrobel wrote:

You had very good idea to create such a linetype.

I improved it and now the ">" are collinear with the "-":

.... 


That will be affected by what font you have assigned to the "Standard" Text Style.  Your correction makes it work better when that Style has the default TXT.shx font, but many people give the Standard Style a different font.  Klugb has obviously done that, because the angle of their arrowheads is not the same as that in the > character in TXT, and their images show a linetype that is at least closer to having the arrowheads collinear with the line parts than the way it comes out with TXT assigned to the Standard Style.  This is something you always need to be careful about when taking linetype definitions containing Text elements from on-line sources, if whoever put them there doesn't reveal what font they have set in the Style that the linetype definition calls for.

Kent Cooper, AIA
Message 20 of 20
Kent1Cooper
in reply to: damian.wrobel


@damian.wrobel wrote:

....

Does not work for: Arc,Circle, Ellipse, Line, MultiLine

....

There should be lisp for "Show Direction", which:
1.
It will be working for all the types of Objects which I write above.
2.
And it will create the arrows which will be not temporary objects.
 They will be created on the new Layer called "Direction Arrows".

....

3.
 They will be tangent to Splines, Circles, Arcs, Ellipses and aligned with Polylines etc.


For the great majority of objects, you can just use an arrowhead Block [make one for the purpose if you don't have one, pointing to the right at 0 rotation], set your Direction Arrows Layer current, and use Measure or Divide with the Block option, and accepting the default to Align the Blocks with the object.  It should be quite simple to make a command to take care of all that for you [it could even make the arrow Block if it doesn't exist already].  If you use DIV+ or MEA+ from here, you can also specify the Scale of the Blocks, if a Scale of 1 in regular Measure/Divide isn't appropriate, and you don't even need a Block -- you can draw any kind of pointy thing and use it without making it a Block, with the user-Selection option.

 

Or, temporarily assign a Flow-direction-type linetype to any object you like.

 

I think the only thing that would require much special coding would be to get such an indication on Multilines, for which neither of the above approaches works, and 3D Polylines, for which the Measure/Divide approach works but the non-continuous-linetype approach does not.

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost