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

BREAK LINES HORIZONTALLY OR VERTICALLY

26 REPLIES 26
SOLVED
Reply
Message 1 of 27
kameron1967
4244 Views, 26 Replies

BREAK LINES HORIZONTALLY OR VERTICALLY

Just wondering if anyone can help me with a routine that has the option to break vertical or break horizontal, depending on the option, the lines that cross either the horizontal or vertical (again, depending on the option) a specified distance (say .05) on either side of the line you wanted to keep.  So if I choose BREAKH, the vertical lines that I choose would break any horizontal lines that cross them.  Same applies to BREAKV.  Hopefully I communicated clearly enough.  Thanks in advance!

26 REPLIES 26
Message 2 of 27
scot-65
in reply to: kameron1967

I like the sounds of this.

But I have an issue with your user input method.

Maybe someone else can help out with the "crossing" method...

 

(if (not USER_BREAK) (setq USER_BREAK 1.0) )

(if (not (setq d (getreal (strcat "Enter total gap distance <" (rtos USER_BREAK 2 2) ">: "))))

 (setq d USER_BREAK) );if

(if (and

   (setq p1 (getpoint "Select object to break: "))

   (setq p2 (getpoint "Specify line intersection: ")) );and

 (command ".break" p1 "F"

  (polar p2 (angle p2 p1) (/ d 2.0))

  (polar p2 (angle p1 p2) (/ (setq USER_BREAK d) 2.0)) )

);if

(setq d nil p1 nil p2 nil) ;USER_BREAK is the gremlin

 

* untested and simplified [osnap might need suppressing here] *

 

I do not like WIPEOUT, however this is yet another option.

 

???

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 3 of 27
kameron1967
in reply to: scot-65

Thanks for helping with a portion of the code, Scot-65.  I think we're good, unless anyone else want to give it a try. 🙂

Message 4 of 27
Kent1Cooper
in reply to: kameron1967


@kameron1967 wrote:

Just wondering if anyone can help me with a routine that has the option to break vertical or break horizontal, depending on the option, the lines that cross either the horizontal or vertical (again, depending on the option) a specified distance (say .05) on either side of the line you wanted to keep.  So if I choose BREAKH, the vertical lines that I choose would break any horizontal lines that cross them.  Same applies to BREAKV.  Hopefully I communicated clearly enough.  Thanks in advance!


Would you always be working with only horizontal and vertical Line entities?  That would make it comparatively easy -- I can imagine a way to do it by just selecting the Line you want others broken around, it could find all Lines that intersect it perpendicularly without User selection, and it could be done with one command that would cover either situation, without requiring specifying a horizontal or vertical option nor separate commands.  If you might sometimes be working with, say, Polylines or any curvy things, and/or non-orthogonal angles, things would get more complicated, but I think it could still be done.

Kent Cooper, AIA
Message 5 of 27
kameron1967
in reply to: kameron1967

Kent,

 

For my purpose, only horizontal/vertical lines and/or polylines will do.  However, if you wanted to tackle the other type of entities that you mentioned, I would love to see it.  Thank you very much for your suggestion, Kent. 🙂

 

 

Message 6 of 27
Kent1Cooper
in reply to: kameron1967


@kameron1967 wrote:
....

For my purpose, only horizontal/vertical lines and/or polylines will do. ....


Might the Polylines always be equivalent to Lines, i.e. of single line segments only?  Again, that's a lot easier than if they might bend, possibly intersecting more than once with something you want to Break, or to Break them around, etc.  I'm hoping (inters) will do, rather than conversions to VLA objects so you can use the IntersectWith approach.

Kent Cooper, AIA
Message 7 of 27
kameron1967
in reply to: Kent1Cooper

I believe a simple line or polyline intersection (whether it's perpendicular or not) scenario would probably suffice, Kent.  Give it a whirl and I'll bet you that it's more than enough.  Thanks! 🙂

Message 8 of 27
alanjt_
in reply to: kameron1967

Here's two submissions. The first will only break one curve (line, arc, circle, lwpolyline, ellipse, spline), giving a choice, if the picked point is over more than one curve. The other will break all selected curves at picked point.

 

Single curve version:

 

(defun c:BPG (/ *error* AT:DrawX AT:CycleThroughSS cmd poc ent dap p1 p2)
  ;; Break curve at Point with Gap
  ;; Alan J. Thompson, 2013.05.15

  (defun *error* (msg)
    (and cmd (setvar 'CMDECHO cmd))
    (and *AcadDoc* (vla-endundomark *AcadDoc*))
    (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,")))
      (princ (strcat "\nError: " msg))
    )
  )

  (defun AT:DrawX (P C)
    ;; Draw and "X" vector at specified point
    ;; P - Placement point for "X"
    ;; C - Color of "X" (must be integer b/w 1 & 255)
    ;; Alan J. Thompson, 10.31.09
    (if (vl-consp P)
      ((lambda (d)
         (grvecs (cons C
                       (mapcar (function (lambda (n) (polar P (* n pi) d)))
                               '(0.25 1.25 0.75 1.75)
                       )
                 )
         )
         P
       )
        (* (getvar 'viewsize) 0.02)
      )
    )
  )

  (defun AT:CycleThroughSS (ss / l i e)
    ;; Cycle through a selection set to choose one
    ;; ss - selection set
    ;; Alan J. Thompson, 03.30.11
    (if (eq (type ss) 'PICKSET)
      (if (eq (setq l (sslength ss)) 1)
        (ssname ss 0)
        (progn (princ "\n<Tab> to cycle through entities: ")
               (redraw (setq e (ssname ss (setq i 0))) 3)
               (while (eq (cadr (grread nil 10)) 9)
                 (mapcar 'redraw (list e (setq e (ssname ss (setq i (rem (1+ i) l))))) '(4 3))
               )
               (redraw e 4)
               e
        )
      )
    )
  )

  (vla-startundomark
    (cond (*AcadDoc*)
          ((setq *AcadDoc* (vla-get-activedocument (vlax-get-acad-object))))
    )
  )

  (setq cmd (getvar 'CMDECHO))
  (setvar 'CMDECHO 0)

  (redraw)

  (initget 6)
  (setq *BPG:Gap* (cond ((getdist (strcat "\nSpecify gap at break point <"
                                          (rtos (cond (*BPG:Gap*)
                                                      ((setq *BPG:Gap* 1.))
                                                )
                                          )
                                          ">: "
                                  )
                         )
                        )
                        (*BPG:Gap*)
                  )
  )


  (cond
    ((not (AT:DrawX (setq poc (getpoint "\nSpecify first point on curve: ")) 3)))
    ((not (setq ent (AT:CycleThroughSS
                      (ssget "_C"
                             (list (car poc) (cadr poc))
                             (list (car poc) (cadr poc))
                             '((0 . "ARC,CIRCLE,ELLIPSE,LINE,LWPOLYLINE,SPLINE"))
                      )
                    )
          )
     )
     (alert "Point must be on curve!")
    )
    ((eq (logand 4 (cdr (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8 (entget ent)))))))) 4)
     (alert "Curve on locked layer!")
    )
    ((not (and (setq dap (vlax-curve-GetDistAtPoint ent (trans poc 1 ent)))
               (setq p1 (vlax-curve-getPointAtDist ent (+ dap (/ *BPG:Gap* 2.))))
               (setq p2 (vlax-curve-getPointAtDist ent (- dap (/ *BPG:Gap* 2.))))
          )
     )
     (alert "Cannot break curve with specified gap at picked point.")
    )
    (T
     (vl-cmdf "_.break" (list ent poc) "_non" (trans p1 ent 1))
     (vl-cmdf "_.break" (list ent poc) "_non" (trans p2 ent 1))
    )
  )

  (*error* nil)
  (princ)
)

 

 

Multiple curve version:

(defun c:BPG (/ *error* AT:DrawX AT:CycleThroughSS cmd poc ss i ent dap p1 p2)
  ;; Break curve(s) at Point with Gap
  ;; Alan J. Thompson, 2013.05.15

  (defun *error* (msg)
    (and cmd (setvar 'CMDECHO cmd))
    (and *AcadDoc* (vla-endundomark *AcadDoc*))
    (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,")))
      (princ (strcat "\nError: " msg))
    )
  )

  (defun AT:DrawX (P C)
    ;; Draw and "X" vector at specified point
    ;; P - Placement point for "X"
    ;; C - Color of "X" (must be integer b/w 1 & 255)
    ;; Alan J. Thompson, 10.31.09
    (if (vl-consp P)
      ((lambda (d)
         (grvecs (cons C
                       (mapcar (function (lambda (n) (polar P (* n pi) d)))
                               '(0.25 1.25 0.75 1.75)
                       )
                 )
         )
         P
       )
        (* (getvar 'viewsize) 0.02)
      )
    )
  )

  (defun AT:CycleThroughSS (ss / l i e)
    ;; Cycle through a selection set to choose one
    ;; ss - selection set
    ;; Alan J. Thompson, 03.30.11
    (if (eq (type ss) 'PICKSET)
      (if (eq (setq l (sslength ss)) 1)
        (ssname ss 0)
        (progn (princ "\n<Tab> to cycle through entities: ")
               (redraw (setq e (ssname ss (setq i 0))) 3)
               (while (eq (cadr (grread nil 10)) 9)
                 (mapcar 'redraw (list e (setq e (ssname ss (setq i (rem (1+ i) l))))) '(4 3))
               )
               (redraw e 4)
               e
        )
      )
    )
  )

  (vla-startundomark
    (cond (*AcadDoc*)
          ((setq *AcadDoc* (vla-get-activedocument (vlax-get-acad-object))))
    )
  )

  (setq cmd (getvar 'CMDECHO))
  (setvar 'CMDECHO 0)

  (redraw)

  (initget 6)
  (setq *BPG:Gap* (cond ((getdist (strcat "\nSpecify gap at break point <"
                                          (rtos (cond (*BPG:Gap*)
                                                      ((setq *BPG:Gap* 1.))
                                                )
                                          )
                                          ">: "
                                  )
                         )
                        )
                        (*BPG:Gap*)
                  )
  )


  (cond
    ((not (AT:DrawX (setq poc (getpoint "\nSpecify first point on curve: ")) 3)))
    ((not (setq ss (ssget "_C"
                          (list (car poc) (cadr poc))
                          (list (car poc) (cadr poc))
                          '((0 . "ARC,CIRCLE,ELLIPSE,LINE,LWPOLYLINE,SPLINE"))
                   )
          )
     )
     (alert "Point must be on curve!")
    )
    (T
     (repeat (setq i (sslength ss))
       (setq ent (ssname ss (setq i (1- i)))
             dap (vlax-curve-GetDistAtPoint ent (trans poc 1 ent))
       )
       (if
         (and
           (/= (logand 4 (cdr (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8 (entget ent))))))))
               4
           )
           (setq p1 (vlax-curve-getPointAtDist ent (+ dap (/ *BPG:Gap* 2.))))
           (setq p2 (vlax-curve-getPointAtDist ent (- dap (/ *BPG:Gap* 2.))))
         )
          (progn (vl-cmdf "_.break" (list ent poc) "_non" (trans p1 ent 1))
                 (vl-cmdf "_.break" (list ent poc) "_non" (trans p2 ent 1))
          )
       )
     )
    )
  )

  (*error* nil)
  (princ)
)

 

Message 9 of 27
_Tharwat
in reply to: alanjt_

Alan , is not it better to turn off the osmode and set only the 512 to ensure the pick point on the correct location on the objects ?

 

 

Message 10 of 27
alanjt_
in reply to: _Tharwat

Short answer: no.
Isn't osmode 512 just nearest?
Never assume you know what the user wants, give them an option..within the constraints of the program, of course. Also, nearest would just be an arbitrary point on your curve. If you are breaking just at a point, then it's specific and not arbitrary. The user should be allowed to run all their active osnaps, plus access to osnap overrides. Why limit a precision based program to "close enough"?

Message 11 of 27
Kent1Cooper
in reply to: kameron1967


@kameron1967 wrote:

I believe a simple line or polyline intersection (whether it's perpendicular or not) scenario would probably suffice, Kent.  Give it a whirl and I'll bet you that it's more than enough.  Thanks! 🙂


A LINES-ONLY version is attached, comparatively basic and lightly tested [BALIS.lsp = Break All Lines Intersecting Selected one(s)].  I realized that restricing it to orthogonal directions wasn't going to make it as much simpler as I thought at first, so this works with Lines at any angle(s) [though it doesn't account for the 3rd dimension, if you need that].  As long as you keep picking Lines, it keeps Breaking every Line [on an unlocked Layer] that intersects the one you just picked.  You could do an Undo wrapper around it all, and/or turn off command echoing and/or blips, and if you do, add error handling to end the Undo and/or reset anything.

 

It would be comparatively easy to add the possibility of single-line-segment Polylines, and it could still use plain old (inters) to find where to break things.  Once you expand to multi-segment Polylines and/or Arcs/Circles/Ellipses/Splines/etc., finding that location [or the possibility of multiple locations] becomes more complicated, as you can see in others' routines.

Kent Cooper, AIA
Message 12 of 27
kameron1967
in reply to: alanjt_

Alanjt_ - I tried both routines, thank you.  They appear to only break one instance of the line/polyline crossing.   The 1st option allows me to choose which of the 2 intersecting lines I need to trim, while the 2nd option trims both.  This is great for doing it to each intersection at a time, but I need to apply it to multiple intersections.  I don't mind if one trims only vertical lines that intersect that one horizontal line or arc that I choose.  If there is another routine that only trims the horizontal lines intersecting the vertical line or arc, that would be what I'm looking for.  Would you be able to modify your routine to do that?  I like the option to choose which line to trim, but when we have multiple, it's simpler to just trim whicher routine we use (either breakV or breakH for vertical, horizontal, respectively).  Thanks in advance.

Message 13 of 27

My 2 cents, isn't perfect, but it work's well with lines and polylignes, with other objects ... you can ameliorate it!

 

(vl-load-com)
(defun l-coor2l-pt (lst flag / )
  (if lst
    (cons
      (list
        (car lst)
        (cadr lst)
        (if flag
          (+ (if (vlax-property-available-p vlaobj 'Elevation) (vlax-get vlaobj 'Elevation) 0.0) (caddr lst))
          (if (vlax-property-available-p vlaobj 'Elevation) (vlax-get vlaobj 'Elevation) 0.0)
        )
      )
      (l-coor2l-pt (if flag (cdddr lst) (cddr lst)) flag)
    )
  )
)
(defun c:white_cut ( / val_offset js js_up vla_obj js_cut obj_brk vlaobj pt l_pt)
(setq l_pt nil)
  (initget 6)
  (setq val_offset (getdist (strcat "\nComplete breadth to be hollowed out <" (rtos (getvar "USERR1")) ">:")))
  (if (not val_offset) (setq val_offset (getvar "USERR1")) (setvar "USERR1" val_offset))
  (setq js (ssadd))
  (princ "\nChoice of the covering object: ")
  (while
    (not
      (setq js_up
        (ssget "_+.:E:S" 
          (list
            (cons -4 "<OR")
              (cons -4 "<AND")
                (cons 0 "*POLYLINE,LINE,ARC,CIRCLE,ELLIPSE")
                (cons -4 "<NOT")
                  (cons -4 "&") (cons 70 112)
                (cons -4 "NOT>")
              (cons -4 "AND>")
              (cons 0 "SPLINE")
            (cons -4 "OR>")
          )
        )
      )
    )
  )
  (setq vla_obj (vlax-ename->vla-object (ssname js_up 0)))
  (princ "\nChoice of objects to be hollowed out: ")
  (setq js_cut
    (ssget
      (list
        (cons -4 "<OR")
          (cons -4 "<AND")
            (cons 0 "*POLYLINE,LINE,ARC,CIRCLE,ELLIPSE")
            (cons -4 "<NOT")
              (cons -4 "&") (cons 70 112)
            (cons -4 "NOT>")
          (cons -4 "AND>")
          (cons 0 "SPLINE")
        (cons -4 "OR>")
      )
    )
  )
  (cond
    (js_cut
      (vla-Offset vla_obj (* val_offset 0.5))
      (setq js (ssadd (entlast) js))
      (vla-Offset vla_obj (- (* val_offset 0.5)))
      (setq js (ssadd (entlast) js))
      (while (not (zerop (sslength js_cut)))
        (setq
          obj_brk (ssname js_cut 0)
          vlaobj (vlax-ename->vla-object obj_brk)
        )
        (if (setq pt (vlax-invoke (vlax-ename->vla-object (ssname js 0)) 'IntersectWith vlaobj acExtendNone))
          (setq l_pt (append (l-coor2l-pt pt T) l_pt))
        )
        (if (setq pt (vlax-invoke (vlax-ename->vla-object (ssname js 1)) 'IntersectWith vlaobj acExtendNone))
          (setq l_pt (mapcar 'list (l-coor2l-pt pt T) l_pt))
        )
        (if l_pt
          (progn
            (setvar "CMDECHO" 0)
            (foreach n l_pt
              (cond
                ((eq (length n) 2)
                  (vl-cmdf "_.break" obj_brk "_none" (trans (car n) 0 1) "_none" (trans (cadr n) 0 1))
                  (setq obj_brk (entlast))
                )
                ((eq (length n) 1)
                  (vl-cmdf "_.break" obj_brk "_none" (trans (car n) 0 1) "_none" (polar (trans (car n) 0 1) (angle (trans (car n) 0 1) (osnap (trans (car n) 0 1) "_end")) val_offset))
                )
              )
            )
            (setvar "CMDECHO" 1)
          )
        )
        (ssdel (ssname js_cut 0) js_cut)
        (setq l_pt nil)
      )
    )
  )
  (entdel (ssname js 0))
  (entdel (ssname js 1))
  (prin1)
)

 

Message 14 of 27
kameron1967
in reply to: Kent1Cooper

Kent - I tried it and it asks me to select objects. However, the cursor is a square box which means that it's asking me to choose a single object. Once I did that, it exits without breaking any line/sweat. 🙂 I think you were trying to give me the option to choose a single line, then choose the lines to break through fence option, maybe..? Thanks.
Message 15 of 27

CADaStroumph - tested it. Worked well, like you said. Thanks! I appreciate both Alanjt and Kent's help. I'm good with CADaStroumph's routine, but if you want to finish up your routines, I'd like to test them also. It's kind of like wine, you never know which flavor you'll end up drinking. But it's great that everyone's chipping in! 🙂
Message 16 of 27
Kent1Cooper
in reply to: kameron1967


@kameron1967 wrote:
Kent - I tried it and it asks me to select objects. However, the cursor is a square box which means that it's asking me to choose a single object. Once I did that, it exits without breaking any line/sweat. 🙂 I think you were trying to give me the option to choose a single line, then choose the lines to break through fence option, maybe..? Thanks.

It's built so that you select a [yes, single] Line, and it finds all Lines that intersect it [you don't need to choose them, or maybe I should say you don't get to choose them], and Breaks them around it.  That was my interpretation of this from the original question [emphasis mine]:  "So if I choose BREAKH, the vertical lines that I choose would break any horizontal lines that cross them."  Then you can select another Line and it does the same, as long as you keep selecting Lines that you want others Broken around.

 

It can certainly be adjusted easily enough to limit either the Line-you-want-to-Break-things-around selection or the other Lines that it Breaks, or both, to horizontal or vertical ones.  I didn't limit it that way, because of your "(whether it's perpendicular or not)" in Message 7.  It would also be pretty easy to adjust it to let you choose the ones to be Broken rather than finding any that intersect with the selected one.

Kent Cooper, AIA
Message 17 of 27
kameron1967
in reply to: Kent1Cooper

Kent - No, you interpretted it right. Although having the option to break only the lines selected is nice also. But since the routine did not break any line(s), I didn't know what it was supposed to do. If you could check into that, that would be great. Thanks!
Message 18 of 27
Kent1Cooper
in reply to: kameron1967


@kameron1967 wrote:
Kent - No, you interpretted it right. .... But since the routine did not break any line(s), I didn't know what it was supposed to do. If you could check into that, that would be great. Thanks!

I tried it again in a different drawing, and it still worked for me.  Might there be Z-coordinate differences?  Locked Layers?  Is your gap size too small to be visible unless you Zoom in closer?

Kent Cooper, AIA
Message 19 of 27
kameron1967
in reply to: Kent1Cooper

No Z coordinate on these ones.  I am uploading a sample file.  Let me know if you can still successfully break them, Kent.

 

Update:  Actually, these are polylines.  So when I created lines, they do break them.  If you can include the polyline and allow to pick the lines that you want to be broken, that would be great, Kent.

Message 20 of 27
alanjt_
in reply to: kameron1967

Ok, I didn't realize you were looking to break at multiple intersections at once. I'd highly suggest checking out CAB's Break All or Some routine. Here's the link: http://www.theswamp.org/index.php?topic=10370.0

 

I'm pretty sure you have to be a memeber.

 

EDIT: Oh yeah, I'm not sure if it's in the latest version, but he added a version that creates gaps. Just scroll through a few pages, it's there.

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

Post to forums  

Autodesk Design & Make Report

”Boost