Hi all,
I created a simple AutoLISP command to speed up creating line breaks and jumps for use in a wiring diagram. The command breaks the selected line and draws an arc to show that the lines do not cross / connect.
Solved! Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Solved by ronjonp. Go to Solution.
Solved by ronjonp. Go to Solution.
Good for you for making a start, though it could use some improvements. It assumes only orthogonal Lines. If you choose the vertical one to break, it does break that one, but draws the Arc as though you chose the horizontal one to break. [It also draws the Arc the same way if you pick non-orthogonal Lines.] And it requires you to pick the one to break inside the 1/8-drawing-unit distance from the intersection -- if you pick on it farther away, the wrong part gets broken off.
To see how others have approached this in more comprehensive ways, there are some other threads just on this Forum, such as >this one< and >this other one<, and no doubt others on different websites, available for the Searching.
Yes, there still are some things that can be tweaked. I am fairly new to customizing AutoCAD using LISP, this is actually my first custom command using it. I personally know how this function works, so I will use it accordingly, but if you have any suggestions to help fix those issues, I am completely open to hear them.
Thanks for the reply!
Here is another quick to mull over one for polylines. The nice thing here is the segment will stay as one piece :).
(defun c:hop (/ a d e i o p p1 p2 p3) ;; RJP » 2019-01-14 ;; Adds a 'hop' to a lwpolyline ( very little error checking ) (setq a 0.125) (while (and (setq e (entsel "\nPick a polyline to add a hop: ")) (= "LWPOLYLINE" (cdr (assoc 0 (entget (car e))))) (setq p (vlax-curve-getclosestpointto (car e) (cadr e))) (setq i (1+ (fix (vlax-curve-getparamatpoint (setq e (car e)) p)))) (setq d (vlax-curve-getdistatpoint e p)) (setq p1 (vlax-curve-getpointatdist e (+ d a))) (setq p2 (vlax-curve-getpointatdist e (- d a))) ) (setq o (vlax-ename->vla-object e)) (vlax-invoke o 'addvertex i (mapcar '+ p1 '(0 0))) (vlax-invoke o 'addvertex i (mapcar '+ p2 '(0 0))) (vla-setbulge o i (cond ((< (angle '(0 0) p1) (angle '(0 0) p2)) -1.) (1.) ) ) ) (princ) ) (vl-load-com)
@andrew_k hi,
here is how i would do it
add comments at each line for you to understand.
if user fail to supply the right inputs? the (and) function will return nil thus command will exit (just as any AutoCAD standard command).
enjoy
moshe
(defun C:LJ2 (/ pick ename c0 c1 c2 c3 ;| local variables |;) (setvar "cmdecho" 0) ; disable command echo (command "._undo" "_begin") ; start undo group (if (and (setq pick (entsel "\nSelect line to break: ")) ; select entity (setq ename (car pick)) ; get ename (eq (cdr (assoc '0 (entget ename))) "LINE") ; make sure it's a line? (not (redraw ename 3)) ; highlight entity (setq c0 (getpoint "\nSpecify intersection: ")) ; get intersection ) (progn (setq p0 (osnap (cadr pick) "_nearest")) ; make sure the pick is on object (setq c1 (polar c0 (angle p0 c0) 0.125)) (setq c2 (polar c0 (angle c0 p0) 0.125)) (command "._break" pick "_f" "_none" c1 "_none" c2) ; break (command "._arc" "_none" c1 "_C" "_none" c0 "_none" c2) ; draw arc (jump) ); progn ); if (command "._undo" "_end") ; clsoe undo group (setvar "cmdecho" 1) ; enable command echo (princ) ; quiet exit ); C:LJ2
When you get tired of picking points, here is a quick mod to allow for multiple selection 🙂 Enjoy!
(defun c:hops (/ a b d e i p p1 p2 pts s x) ;; RJP » 2019-01-21 ;; Creates hops on a selection of intersecting polylines (setq a 0.125) (cond ((and (setq s (ssget ":L" '((0 . "lwpolyline")))) (> (sslength s) 1) (setq s (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))) (setq b s) ) (foreach e s (if (setq pts (apply 'append (mapcar '(lambda (x) (vlax-invoke e 'intersectwith x acextendnone)) (setq b (cdr b)) ) ) ) (while (caddr pts) (cond ((and (setq p (list (car pts) (cadr pts))) (setq i (vlax-curve-getparamatpoint e p)) (= 0.0 (vla-getbulge e (fix i))) (setq d (vlax-curve-getdistatpoint e p)) (setq p1 (vlax-curve-getpointatdist e (+ d a))) (setq p2 (vlax-curve-getpointatdist e (- d a))) ) (vlax-invoke e 'addvertex (setq i (1+ (fix i))) (mapcar '+ p1 '(0 0))) (vlax-invoke e 'addvertex i (mapcar '+ p2 '(0 0))) (vla-setbulge e i (cond ((< (angle '(0 0) p1) (angle '(0 0) p2)) -1.) (1.) ) ) ) ) (setq pts (cdddr pts)) ) ) ) ) ) (princ) ) (vl-load-com)
@adhammagdy At above function from @ronjonp change value 0.125 to some greater value.
At this link you can find my solution to similar problem (change radius value if needed (set at 2).
Miljenko Hatlak
I am back on this project after some time away. I tried messing with your code to make it more suited for me, but have been unable to do so.
I am looking to allow lines to be converted as well, and not just polylines. I also wanted control over the arc length and the exact intersection where the arc is being placed (taken from Moshe's code) which is working for me. The program works exactly how I want it to, but only while working exclusively with polylines, which is not always the case on my drawings.
Can you help me get this figured out?
(defun c:LineJump (/ a d e i o p p1 p2 p3)
;; Adds a 'hop' to a lwpolyline ( very little error checking )
;(setq a 0.125) ; replaced this with arc length user input
(while (and (setq e (entsel "\nPick a polyline to add a hop: "))
;(= "LWPOLYLINE" (cdr (assoc 0 (entget (car e))))) ; i want to remove check to allow lines as well as polylines
; add step to convert standard lines into polylines to let the program run
;(setq p (vlax-curve-getclosestpointto (car e) (cadr e))) ; replaced by next line
(setq p (getpoint "\nSpecify intersection: "))
(setq i (1+ (fix (vlax-curve-getparamatpoint (setq e (car e)) p))))
(setq d (vlax-curve-getdistatpoint e p))
(setq a (getdist "\nSpecify arc length: "))
(setq p1 (vlax-curve-getpointatdist e (+ d a)))
(setq p2 (vlax-curve-getpointatdist e (- d a)))
)
(setq o (vlax-ename->vla-object e))
(vlax-invoke o 'addvertex i (mapcar '+ p1 '(0 0)))
(vlax-invoke o 'addvertex i (mapcar '+ p2 '(0 0)))
(vla-setbulge
o
i
(cond ((< (angle '(0 0) p1) (angle '(0 0) p2)) -1.)
(1.)
)
)
)
(princ)
)
(vl-load-com)
@andrew_k Maybe convert them ... assuming they are all 2D.
(defun c:c-l (/ line->polyline s)
;; RJP » 2022-03-08
(defun line->polyline (e / el)
(if (and (= (type e) 'ename) (= "LINE" (cdr (assoc 0 (setq el (entget e '("*")))))))
(progn (entdel e)
(entmakex (mapcar '(lambda (x)
(cond ((= (car x) 0) '(0 . "LWPOLYLINE"))
((= (cdr x) "AcDbLine") '(100 . "AcDbPolyline"))
((= (car x) 11) (cons 10 (cdr x)))
(x)
)
)
(append (reverse (member '(100 . "AcDbLine") (reverse el)))
'((90 . 2) (43 . 0.0) (38 . 0.0) (70 . 0))
(cdr (member '(100 . "AcDbLine") el))
)
)
)
)
)
)
(if (setq s (ssget ":L" '((0 . "LINE"))))
(foreach line (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))) (line->polyline line))
)
)
Thanks for the quick reply! I will test this out in a little while. One question though - is there any chance you could add comments to let me know what each line does? I've been trying to research things, but getting nowhere. This language makes my brain hurt!
@andrew_k wrote:
....
I am looking to allow lines to be converted as well, and not just polylines. I also wanted control over the arc length and the exact intersection where the arc is being placed ....
Something like this? [Untested -- I left much of your code alone]
(defun c:LineJump (/ a d e etype i o p p1 p2) ;; Adds a 'hop' to a LWPolyline or Line
(setq a (getdist "\nSpecify arc length: "))
(setvar 'peditaccept 1); [for PEDIT - could save current value and reset later if desired]
(while
(and
(setq e (entsel "\nPick a line or polyline to add a hop: "))
(wcmatch (setq etype (cdr (assoc 0 (entget (car e))))) "LINE,LWPOLYLINE")
); and
(if (= etype "LINE") (command "_.pedit" (car e) "")); convert Line to Polyline
(setq p (getpoint "\nSpecify intersection: "))
(setq i (1+ (fix (vlax-curve-getparamatpoint (setq e (car e)) p))))
(setq d (vlax-curve-getdistatpoint e p))
(setq p1 (vlax-curve-getpointatdist e (+ d a)))
(setq p2 (vlax-curve-getpointatdist e (- d a)))
(setq o (vlax-ename->vla-object e)); make into VLA object for next functions:
(vlax-invoke o 'addvertex i (mapcar '+ p1 '(0 0)))
(vlax-invoke o 'addvertex i (mapcar '+ p2 '(0 0)))
(vla-setbulge ; make into half-circle arc segment
o
i
(cond
((< (angle '(0 0) p1) (angle '(0 0) p2)) -1.)
(1.)
); cond
); vla-setbulge
); while
(princ)
)
(vl-load-com)
Enter at the pick-one prompt will end it.
A couple of explanations too long for inside the code window:
The (mapcar '+ {point variable} '(0 0)) parts make a 3-coordinate XYZ point list into a 2-coordinate XY-only list, which it will want for adding a vertex to a LWPolyline. [Read about (mapcar) in Help to understand why.]
The bulge factor of an arc segment is 1 for a half-circle arc, positive for CCW direction and negative for CW direction.
This works great for polylines. It has trouble with standard lines though. It converts the line but then exits and spits out an "error: bad argument value: AcDbCurve 57" response. When I run the command on the line it previously converted, it works fine.
I tested it out and it works, but I am having to select the line twice - once for the hop and once for the convert.
Can't find what you're looking for? Ask the community or share your knowledge.