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!
Solved! Go to Solution.
Solved by pbejse. Go to Solution.
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.
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. 🙂
@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,
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. 🙂
@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.
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! 🙂
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) )
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 ?
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"?
@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.
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.
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) )
@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.
@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?
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.
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.