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

Trimming intersecting polylines

22 REPLIES 22
SOLVED
Reply
Message 1 of 23
ScottMason
5756 Views, 22 Replies

Trimming intersecting polylines

I am looking to develop a lisp routine to help out trimming out our panel joints, it is a task that we perform everyday and the "trim" command takes a lot of time. In the attached image the cyan box on the left is how they start with two sets of intersecting polylines, the box on the right is how we would like them after the routine. Currently we have to trim selecting all edges and then zoom in and only select the area inbetween the lines, i would like to bea able to make a selection window roughly the size of the cyan box over the entire joint/intersection. There wont always be 4 intersecting lines but at least:  one line with two parallel lines terminating into the continuous line. In the current trim command when i select all edges and try to window around the joint, it will give the opposite result of what i am wanting, leaving only a small "box" made up of only the portions of the lines in between. 

22 REPLIES 22
Message 2 of 23
Gary_J_Orr
in reply to: ScottMason


@Anonymous wrote:

I am looking to develop a lisp routine to help out trimming out our panel joints, it is a task that we perform everyday and the "trim" command takes a lot of time. In the attached image the cyan box on the left is how they start with two sets of intersecting polylines, the box on the right is how we would like them after the routine. Currently we have to trim selecting all edges and then zoom in and only select the area inbetween the lines, i would like to bea able to make a selection window roughly the size of the cyan box over the entire joint/intersection. There wont always be 4 intersecting lines but at least:  one line with two parallel lines terminating into the continuous line. In the current trim command when i select all edges and try to window around the joint, it will give the opposite result of what i am wanting, leaving only a small "box" made up of only the portions of the lines in between. 


What you are looking to do is actually pretty complex to build (at least if you are looking at a nearly "hands off" approach after selecting the work area).

It has been done... I know, I've used a similar function... I thought it was in the Express Tools as something like L-trim and X-trim and T-trim but I can't find any such now. There is an embedded app within MLines that allows for similar such intersection cleanups but no (easy) way to pull that out and rebuild a similar function set for regular linework... So, as it stands now it would be a "start from scratch" build in which you would need to grab a selectionSet of objects to work with, convert them to ActiveX objects, get their intersecting points, run through a few calculations based on entity types and intersection type to determine "pick points" to pass to the trim command, then run the command...

 

However, if you are familiar with the use of the "mid between two points" (m2p) snap override, then a fairly simple command method can be created to automate using that snap override to keep one from having to keep calling it up... unfortunately it means that you need to pick twice as many points during the trim command... instead of zooming in so you can pick on the segment that exists between the cutting objects you would pick the intersections themselves and the m2p override would pick the point between the intersections for you.

 

Such a function, if acceptable, would look something like this:

 

Spoiler
(defun C:Trim_m2p ( / OldOSM NextPoint)
  (setq OldOSM (getvar "osmode"))
  (setvar "osmode" 33)
  (command "._trim" "_Crossing")
  (command (getpoint "Select Crossing Window Start Corner"))
  (command (getcorner (getvar "lastpoint") "Select Opposite Corner"))
  (command "")
  (while (> (getvar "cmdactive") 0)
    (if (setq NextPoint (getpoint "Select an intersection or endpoint on linewrok for m2p Snap: "))
      (command "_m2p" NextPoint (getpoint))
      (command "")
      )
    )
  (setvar "osmode" OldOSM)
  )

 

-Gary

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 3 of 23
p_mcknight
in reply to: ScottMason

I don't think it would be too difficult to do.  One question firs, are the lines always horizontal and vertical to the WCS?

Message 4 of 23
Gary_J_Orr
in reply to: p_mcknight

p_Mcknight,

You just pointed out one of the many complications...
and what if there is an angle involved with one or more of the crossing lines/linesets?
What if one of the plines is an arc segment?
what if it's a "corner" cleanup vs an "Intersection" cleanup vs a "T" cleanup?
What if it's some combination of the above?

To build something reliable it would need to take all of those issues into consideration.

Not sayin that it can't be done, just that it isn't as simple as it seems.

-G
Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 5 of 23
p_mcknight
in reply to: Gary_J_Orr

Gary,

I completely agree with you that to make a foolproof routine that would work for anybody in any situation would take quite a bit of programming and have to include ways to handle many scenarios.  However, I am a firm believer that the beauty of AutoCAD and LISP is that it allows us to make programs that work for specific companies in specific situations in an econimically sound and time efficient manner. 

 

That said, for the OP, below is a program that in a down and dirty manner should do what you want.  That is, if I understood your standard procedures correctly.  I did minimal testing and included no error handling, so if you want a more robust routine you can add that stuff later.  Let me know if this works for you or if I need to modify it a bit for what you need/do.

 

(defun c:xtr ( / p1 p2 objs tempobjs TempSelectionSet Marker vlobj objtyp i sp ep xList yList pointsList n )
  
  (setq p1 (getpoint "\nSpecify first corner of crossing window: ")
	p2 (getcorner p1 "\nSpecify second corner of crossing window: ")
	)
  (setq objs (ssget "_C" p1 p2))
  ;explode to lines
  (setq TempSelectionSet (ssadd))
  (setq Marker (entlast))
  (command ".copy" objs "" '(0 0 0) '(0 0 0))
  (while (setq Marker (entnext Marker))
    (setq vlobj (vlax-ename->vla-object Marker))
    (setq objtyp (vla-get-ObjectName vlobj))
    (if (or (= objtyp "AcDbBlockReference") (= objtyp "AcDbPolyline"))
      (progn
	(command ".explode" Marker)
	)
      (ssadd Marker TempSelectionSet)
      )
    )
  ;get center of intersection sections
  (setq tempobjs (ssget "_C" p1 p2))
  (repeat (setq i (sslength tempobjs))
    (setq obj (ssname tempobjs (setq i (1- i))))
    (if (not (ssmemb obj objs))
      (progn
	(setq vlobj (vlax-ename->vla-object obj))
	(if (= "AcDbLine" (vla-get-objectname vlobj))
	  (progn
	    (setq sp (vlax-safearray->list (vlax-variant-value (vla-get-startpoint vlobj)))
		  ep (vlax-safearray->list (vlax-variant-value (vla-get-endpoint vlobj)))
		  )
	    (if (equal (car sp) (car ep) 0.00001)
	      (setq xList (cons (car sp) xList))
	      (setq yList (cons (cadr sp) yList))
	      )
	    )
	  )
	)
      )
    )
  (cond
    ((= 1 (length xList))
     (cond
       ((= 2 (length yList))
	(setq pointsList (cons (list (car xList) (/ (+ (car yList) (cadr yList)) 2) 0) pointsList))
	)
       (t
	(alert "Error processing number of lines.")
	)
       )
     )
    ((= 2 (length xList))
     (cond
       ((= 1 (length yList))
	(setq pointsList (cons (list (/ (+ (car xList) (cadr xList)) 2) (car yList)  0) pointsList))
	)
       ((= 2 (length yList))
	(setq pointsList (cons (list (/ (+ (car xList) (cadr xList)) 2) (car yList)  0) pointsList))
	(setq pointsList (cons (list (/ (+ (car xList) (cadr xList)) 2) (cadr yList)  0) pointsList))
	(setq pointsList (cons (list (car xList) (/ (+ (car yList) (cadr yList)) 2) 0) pointsList))
	(setq pointsList (cons (list (cadr xList) (/ (+ (car yList) (cadr yList)) 2) 0) pointsList))
	)
       (t
	(alert "Error processing number of lines.")
	)
       )
     )
    (t
     (alert "Error processing number of lines.")
     )
    )
  (command ".erase" TempSelectionSet "")
  (if pointsList
    (foreach n pointsList
      (command ".trim" "crossing" p1 p2 "" n "")
      )
    )
  (princ)
  )

 

Message 6 of 23
Kent1Cooper
in reply to: ScottMason


@Anonymous wrote:

I am looking to develop a lisp routine to help out trimming .... Currently we have to trim selecting all edges and then zoom in and only select the area inbetween the lines, i would like to bea able to make a selection window roughly the size of the cyan box over the entire joint/intersection. There wont always be 4 intersecting lines but at least:  one line with two parallel lines terminating into the continuous line. .... 


I'm picturing a different approach than it seems anyone else has suggested so far.  It wouldn't care whether the objects in question are Lines or Polylines or Arcs or Circles or Splines or Ellipses or Xlines or Rays, or with Lines and Polyline line segments whether they are orthogonal.

 

Ask the User to select objects for one intersection area, limiting it in the selection to those entity types that can be Broken [and that are on un-locked Layers].  Use (vla-Intersectwith) methods to determine which of them intersect and where, and when it finds an intersection, put that point into a list for each object involved.  Then for every object whose list contains two intersections with other objects, use Break on it to take out what's in between those intersections.

 

It could have something built in to honor only intersections found within the selection area, in case some pair [e.g. a Line and a Circle] might also intersect somewhere else.

 

Does that sound worth pursuing?

 

An alternative:  Can you draw them with MLINES and use MLEDIT?  That has an "Open Cross" option that will do what you're after with one pick anywhere on each Mline.  It wouldn't catch the edges where the Mline for a panel joint meets a plain Line perimeter, but there Trim isn't bad -- only one piece to be Trimmed.

Kent Cooper, AIA
Message 7 of 23
Gary_J_Orr
in reply to: p_mcknight

Part of my problem I reckon... I tend to "over think" things a bit 😉

No way that I could have whipped anything like that out in that kinda time cause I'd be over thinking every step...

Happy Lisping,
Gary
Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 8 of 23
Gary_J_Orr
in reply to: Kent1Cooper

Kent,
That's more like what I got to thinking (using break) after I posted that comment about "passing the points to the Trim command"...
Although even that might have to option to a trim command for a "T" type intersection where there might be overruns of the endpoints to the perpendicular/ending segment...
Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 9 of 23
ScottMason
in reply to: Gary_J_Orr

The problem i have found with using mlines is that i will have to explode them later as i will treat the adjacent panels that have been created when trimmed as separate objects. Also the elevations are generally drawn by an outsource. I have attached a drawing that may explain a little more as it has more context info. I am not opposed to using break instead of trim but only mentioned trim as it it what i am currently using. The elevations in the file are "cleaned up" from extraneous info not pertinent to our discussion. They are generally drawn using polylines and sometimes arcs but most of the time follow the patterns shown. The resultant trimmed out polylines are then joined to create closed polygons and used in another process. We spend a lot of time going from the elevation on the left to the one on the right and i was trying to find a way to speed things up. I am open minded to the process to get there but would like it to be simple enough for me to pass on to other users. 

Message 10 of 23
ScottMason
in reply to: p_mcknight

This command seems to work pretty well, i have tried it a few time in the drawing i just posted and it seems to do what i was asking but it does "error out" if the lines are not orthagonal "perpendicular". I would like the command to continue running as i would have many such intersections to trim out. But thank you this is moing closer to what i was wanting.

 

Message 11 of 23
p_mcknight
in reply to: ScottMason

You can always assign the xtr routine to a button as a repeating macro.  Or if you would like you can change the routine itself.  Best of luck.

Message 12 of 23
ScottMason
in reply to: p_mcknight

Im still having problems with  the posted script. it errors at points where the lines are not perpendicular or not two sets of parallel lines. I need it to work at situations where sometimes there are 2 parallel lines terminating into one edge line, or where the parallel lines terminate or intersect one or two parallel lines not perpendicular to themselves. the script works perfectly at the condition of perpendicular parallel lines but it ends after running once, i would need the command to continue running intil cancelled just as the trim command does because there are many joints i will need to trim out.

Message 13 of 23
p_mcknight
in reply to: ScottMason

Unfortunately I have quite a bit going on with my own job right now.  If I have time this weekend I will see what I can do.

Message 14 of 23
Gary_J_Orr
in reply to: ScottMason

Here Scott (decided to play around with the idea a bit this afternoon),

 

It's still pretty "bare bones" but it's a good starting point at least. It will handle most of the simplier intersections but still needs to have handlers for "overrun" (linework that projects beyond the crossing object) and "underrun" (linework that doesn't quite make it to the crossing objects) conditions and it still needs the simple "single intersection" (two lines that cross each other but only have the one intersection like at a corner)...

But, again, it's a decent start.

 

(defun C:GJO_XTrim ( / OldOSM OldEcho OldCopy CWP1 SelSet Index SSEnt 
		    Entlist IntList OBJ1 Enty2 Values tempPoint intPoints NewAssoc)
  (command "._undo" "_begin")
  (setq OldOSM (getvar "osmode"))
  (setq OldEcho (getvar "cmdecho"))
  (setq OldCopy (getvar "copymode"))
  (setvar "cmdecho" 0)
  (setvar "osmode" 0)
  (setvar "copymode" 1)

  (while (setq CWP1 (getpoint "\nSelect Crossing Window Start Corner"))
    (setq SelSet (ssget "_C" CWP1 (getcorner CWP1 "\nSelect Opposite Corner") '((0 . "*LINE,ARC"))))
    (cond
      ((> (sslength SelSet) 4) (Princ "\nToo many entities in selection set: 4 entities maximum"))
      ((>= (sslength SelSet) 2)
       (progn
	 ;Extract the entities
	 (setq Index 0)
	 (while (< Index (sslength SelSet))
	   (setq SSEnt (ssname SelSet Index))
	   (setq Entlist (cons SSEnt Entlist))
	   (setq Index (1+ Index))
	   );while
	 ;get the entities intersections
	 (foreach SSEnt Entlist
	   (setq OBJ1 (vlax-ename->vla-object SSEnt))
	   (setq Index 0)
	   (repeat (length Entlist)
	     (if (/= Enty (setq Enty2 (nth index Entlist)))
	       (progn
		 (setq intPoints (vla-IntersectWith OBJ1 (vlax-ename->vla-object Enty2) acExtendNone))
		 (setq Values (vlax-variant-value intPoints))
		 (if (> (vlax-safearray-get-u-bound Values 1) 0)
		   (progn
		     (setq tempPoint (vlax-safearray->list Values))
		     (if (not (assoc SSEnt IntList))
		       ;add the group
		       (setq IntList (cons (cons SSEnt (list tempPoint)) IntList));setq
		       ;add the point to existing group
		       (progn
			 (setq NewAssoc (cons SSEnt (cons tempPoint (cdr (assoc SSEnt IntList)))))
			 (setq IntList (subst NewAssoc (assoc SSEnt IntList) IntList));setq
			 );progn if in list
		       );if not in list
		     );progn
		   (setq tempPoint nil)
		   );if intpoint
		 );progn
	       );if not same enty
	     (setq Index (1+ Index))
	     );repeat
	   );foreach
	 ;get to work
	 (princ "\nWorking List: ")
	 (princ IntList)
	 (foreach SSEnt IntList
	   (if (= 2 (length (cdr SSEnt)))
	     (progn
	       (command "._Break" (ssadd (car SSEnt)) (cadr SSEnt) (caddr SSEnt))
	       );progn
	     );if
	   );foreach
	 );progn for workable cond
       );workable cond
      (T (Princ "\nInsufficient number of entities in selection set: 2 entities Minimum"))
      );cond stmt
    (setq Entlist nil)
    (setq IntList nil)
    );while

  (setvar "copymode" OldCopy)
  (setvar "osmode" OldOSM)
  (setvar "cmdecho" OldEcho)
  (command "._undo" "_end")
  );C:GJO_XTrim

(vl-load-com)

 

-Gary

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 15 of 23
Gary_J_Orr
in reply to: Gary_J_Orr

Well, here it is... Saturday... unfortunately storms rolling through have kept me from riding and/or yard work... but it works out well for you as I decided to dig into this a bit further (I decided that it could come in handy when detailing as I used to have similar gripes)...

 

Take a look at the attached... it does everything but extend entities that don't quite reach the intersecting lines...

I tested it with a few additional conditions as well (arcs, lines that butt end-to end but appear to be single lines, multi-segmented plines etc).

 

It is intended to do one intersection at a time (if you try to do multiple intersections at the same time there is a problem with the entities in the original selection set since trimming the first intersection can invalidate the entities for the second), but it does run continuous (allowing you to window intersection after intersection) until you hit "enter" (Right-click, etc depending on your settings)

 

-Gary

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 16 of 23
greg_battin
in reply to: ScottMason

Attached is one that I have used in the past.

 

Also, here is an example of it in action: http://autocadtips.wordpress.com/2012/02/17/autolisp-x-shape-wall-intersection-clean-up/

~Greg

Message 17 of 23
ScottMason
in reply to: Gary_J_Orr

Thank you Gary, that is essentially what I was looking for, that will help out a lot and save us time cleaning up our drawings. I am teaching myself LISP but this was far above my head. 

Message 18 of 23
Gary_J_Orr
in reply to: ScottMason

I was beginning to think that you didn't like it...

But now that you've taken a look at it I'll post the next version 😉

 

I realized that there are a few places in which one might not like the results and decide that they want to clean that intersection up manually, but my last version is "all or nothing"... ie: if you undo it because of a bad result part way through then you need to start over so I modified it a bit and worked out a couple of other bugs along the way (and renamed it since it actually uses the "break" command instead of the "trim" command)

 

So give this one a go... if you have your undo turned on and set to Auto (the defaults for most Acad flavors) you will have the option to undo each intersection cleanup during the loop.

 

-G

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 19 of 23
ScottMason
in reply to: Gary_J_Orr

Gary, thank you again. I have tried it out and it works great. It will save us valuable time in our drawing cleanup. 

Message 20 of 23
Gary_J_Orr
in reply to: ScottMason

You again?
*ReallyBigGrin*

Glad it works for you...
For my own reasons I'm actually working on expanding and strengthening it (circles have some issues) and I would like to eventually select multiple intersections at once...

Maybe I'll get there, maybe not, time will tell.
Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)

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

Post to forums  

Autodesk Design & Make Report

”Boost