Break lines at block insertion points at once

Break lines at block insertion points at once

tanvirme2k9
Contributor Contributor
4,144 Views
12 Replies
Message 1 of 13

Break lines at block insertion points at once

tanvirme2k9
Contributor
Contributor

Hi all,

I am interested in a lisp that will break a line or polyline at multiple block insertion points. The attached drawing will clearly demonstrate the requirements. Thanks in advance.

0 Likes
Accepted solutions (2)
4,145 Views
12 Replies
Replies (12)
Message 2 of 13

ВeekeeCZ
Consultant
Consultant
Accepted solution

Hey, try this... I've modified my previous routine (pipedia)...

 

Spoiler
(defun c:PipeBreak ( / *error* oOSMODE oCLAYER oCECOLOR doc ss ssp en pre pt0 ptl pts pt)

 ;------
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg)))
    (setvar 'OSMODE oOSMODE)
    (setvar 'CLAYER oCLAYER)
    (setvar 'CECOLOR oCECOLOR)
    (vla-endundomark doc)
    (princ))

 ;------
 (defun _SortPtListByDist  (ptList en)
  ;; Argument: Point list
  ;; Returns: Point list, sorted by distance from curve
  ;; By BlackBox
  ;; http://www.cadtutor.net/forum/showthread.php?61433-Help-Sort-a-list-point-by-distance
  (mapcar
    '(lambda (x / ptList2)
       (setq ptList2 (append (cdr x) ptList2)))
    (vl-sort
      (mapcar
        '(lambda (x / pt ptlist2)
           (setq ptlist2
                  (append
                    (cons
                      (vlax-curve-getDistAtPoint
			en
			(vlax-curve-getClosestPointTo en x T))                        
                      x)
                    ptlist2)))
        ptList)
      '(lambda (x y)
         (< (car x) (car y))))))
  
  
  (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
  (setq oOSMODE	 (getvar 'OSMODE))
  (setq oCLAYER	 (getvar 'CLAYER))
  (setq oCECOLOR (getvar 'CECOLOR))
  
  (setvar 'OSMODE 0)
  
  (if (and (princ "\nNeed BLOCKs, ")
	   (setq ss (ssget '((0 . "INSERT"))))
	   (< 2 (setq i (sslength ss)))
	   (setq ensel (entsel "\nSelect a (poly)line closer to beginning: "))
	   (wcmatch (cdr (assoc 0 (entget (setq en (car ensel))))) "LWPOLYLINE,LINE")
	   (if (> (vlax-curve-getDistAtPoint en (vlax-curve-getClosestPointTo en (cadr ensel) T))
		  (/ (vlax-curve-getDistAtParam en (vlax-curve-getEndParam en)) 2))
	     (progn								
	       (command "_.REVERSE" en "")
	       (princ "\nPolyline was reversed."))						
	     T)
	   
	   (while (not (minusp (setq i (1- i))))
	     (setq pts (cons (vlax-curve-getClosestPointTo en (cdr (assoc 10 (entget (ssname ss i)))) T) pts)))
	   (setq pts (_SortPtListByDist pts en))
	   (setq pre 1.
		 pt0 (vlax-curve-getPointAtParam en (vlax-curve-getStartParam en))
		 ptl (vlax-curve-getPointAtParam en (vlax-curve-getEndParam en)))
	   (setvar 'CLAYER (cdr (assoc 8 (entget en))))
	   (if (assoc 62 (entget en))
	     (setvar 'CECOLOR (itoa (cdr (assoc 62 (entget en)))))
	     T)
       )
    (progn
      (foreach e pts
	(if (or (< (distance pt0 e) pre)
		(< (distance ptl e) pre))
	  (setq pts2 (cons pt pts2))))
      (setq pts2 (cons ptl pts2)
	    pts2 (reverse pts2)
	    pts2 (cons pt0 pts2))
      (command "_.LINE")
      (foreach e pts
	(command e))
      (command "")
      (entdel en)))
  
  (setvar 'OSMODE oOSMODE)
  (setvar 'CLAYER oCLAYER)
  (setvar 'CECOLOR oCECOLOR)
  (vla-endundomark doc)
  (princ)
)

 

Message 3 of 13

Kent1Cooper
Consultant
Consultant
Accepted solution

@tanvirme2k9 wrote:

...

I am interested in a lisp that will break a line or polyline at multiple block insertion points. .....


Here's an approach that works with many more breakable object types [even different ones through different Block insertion points], and doesn't require sorting the Block locations by position along the object, assuming there are not multiple breakable objects going through the Block insertion points, and assuming the insertion points are accurately on the breakable object.  Very lightly tested, and without the usual enhancements yet:

 

(defun C:BOAB (); = Break Objects At Blocks [Line, Polyline, Arc, Xline, Ray, open Ellipse or Spline]
  (prompt "\nTo Break the object passing through each Block's insertion point,")
  (if (setq blkss (ssget '((0 . "INSERT"))))
    (repeat (setq n (sslength blkss))
      (setq ins (cdr (assoc 10 (entget (ssname blkss (setq n (1- n)))))))
      (if
        (and
          (setq entss (ssget "_C" ins ins '((0 . "*LINE,*POLYLINE,ARC,ELLIPSE,RAY"))))
          (setq
            ent (ssname entss 0)
            etype (cdr (assoc 0 (entget ent)))
          ); setq
          (/= etype "MLINE"); [can't be broken]
          (if (wcmatch etype "SPLINE,ELLIPSE") (not (vlax-curve-isClosed ent)) T); no single-point Break
        ); and
        (command "_.break" ent ins ins)
      ); if
    ); repeat
  ); if
); defun

 

It could be made to also work with Circles and closed Ellipses or Splines, but it would need to be more complicated, because you can't Break those at a single point.

Kent Cooper, AIA
Message 4 of 13

ВeekeeCZ
Consultant
Consultant

@Kent1Cooper wrote:
....
Here's an approach that works with many more breakable object types [even different ones through different Block insertion points], and doesn't require sorting the Block locations by position along the object....

As usual ... you gave me a lesson in efficiency and simplicity. Nice.
Unfortunately, I realized that my approach is not only more complicated but also less functional (assuming that the curve is a straight, or with vertices below the blocks. Vertices between the blocks are not considered.) 

Message 5 of 13

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:
....

          (setq entss (ssget "_C" ins ins '((0 . "*LINE,*POLYLINE,ARC,ELLIPSE,RAY"))))

   ....


Duh -- that could be just:

 

          (setq entss (ssget "_C" ins ins '((0 . "*LINE,ARC,ELLIPSE,RAY"))))

 

because the *LINE part will also see Polylines in addition to Lines, Splines and Xlines [and Mlines, but they're disallowed later].

Kent Cooper, AIA
0 Likes
Message 6 of 13

tanvirme2k9
Contributor
Contributor

Genius! Thanks a lot. I was working with the previous 'pipedia', I found that I need a little modification like the image. Can you please modify a bit?

PipeDia.JPG

0 Likes
Message 7 of 13

ВeekeeCZ
Consultant
Consultant
First of all - don't mix subjects... Post this into the old thread about pipedia.

Then, thanks for kudo.. but you should not overlook Kent's suggestion (see my comment) and at least try it and then possibly appreciate his effort.
0 Likes
Message 8 of 13

tanvirme2k9
Contributor
Contributor
Excellent! worked for all kinds. Thanks man.
0 Likes
Message 9 of 13

Kent1Cooper
Consultant
Consultant

@tanvirme2k9 wrote:
Excellent! worked for all kinds. Thanks man.

You're welcome.  I thought of another tweak to suggest:

....

    (command "_.break" ent "_none" ins "_none" ins)

....

 

in case you have running Object Snap modes on that don't include INSert or anything else that might occur in the Block at its insertion point, and that therefore could take the breaking point elsewhere.  The "usual enhancements" mentioned, that are not in the routine yet, would typically include controlling for that, but it's easy enough to add that element as above rather than by changing the Osnap setting.

Kent Cooper, AIA
Message 10 of 13

Anonymous
Not applicable

Hey I know this is an old post and maybe dead but I hope not. I am trying to utilize your lisp routine but it gets funky with my polylines for some reason. I was able to get it to break one polyline one time then I undid it to check that it worked then could not repeat. It works wonders with lines but I need to use polylines for my application.

 

EDIT: Was able to repeat it once but do not know how.

0 Likes
Message 11 of 13

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... I am trying to utilize your lisp routine but it gets funky with my polylines for some reason. ....

 

EDIT: Was able to repeat it once but do not know how.


An intermittent problem is the hardest to trouble-shoot.  First, there are more than one thing passing through some Block insertion points -- see the first paragraph in Post 3.  The code is written assuming only one, though I guess it could be altered to allow more than one if every such things needs to be Broken.

 

Apart from that, I suspect there would be a problem because the Polylines have width.  Unfortunately, you can't select a Polyline with width at its center-line "path" where the Block insertion points are, because there's "nothing there" [unless you happen to be at a vertex].  To select one manually, you have to pick along the edge.

 

It should work if you can temporarily remove the width from the Polylines.  It may also work if you Zoom out pretty far, but I don't guarantee that.

 

If those don't work, or it's too much to remove the width and then re-assign it afterwards, the remaining possibility is to increase the size of the Crossing window by which it looks for things at Block insertion points, and make it look around the points instead.  If that Crossing selection window were to be made the size of the Block itself, would it be safe to assume there would be nothing passing through it other than the Block and whatever is to be Broken?

Kent Cooper, AIA
0 Likes
Message 12 of 13

Anonymous
Not applicable

Sorry for the delay and thank you for the quick response on an old post. Yes after looking at it a bit it seems you are right that it is the width. Not a big deal to xplode to lines then PEDIT back to polyline. Anyway thanks for the help and the routine!

0 Likes
Message 13 of 13

Anonymous
Not applicable
Great works. Thanks a lot
0 Likes