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

Simple line break and jump AutoLISP

32 REPLIES 32
SOLVED
Reply
Message 1 of 33
andrew_k
8569 Views, 32 Replies

Simple line break and jump AutoLISP

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.

32 REPLIES 32
Message 2 of 33
Kent1Cooper
in reply to: andrew_k

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.

Kent Cooper, AIA
Message 3 of 33
andrew_k
in reply to: Kent1Cooper

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!

Message 4 of 33
ronjonp
in reply to: andrew_k

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)

2019-01-14_11-03-41.gif

 

 

Message 5 of 33
Moshe-A
in reply to: andrew_k

@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

Message 6 of 33
andrew_k
in reply to: ronjonp

Hey, thanks! This solution seems to be working very well. I really appreciate your help!

Message 7 of 33
ronjonp
in reply to: andrew_k

 


@andrew_k wrote:

Hey, thanks! This solution seems to be working very well. I really appreciate your help!


Glad to help 🙂

Message 8 of 33
ronjonp
in reply to: andrew_k

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)

2019-01-21_10-31-58.gif

Message 9 of 33
hpnavale
in reply to: ronjonp

please send lisp file

Message 10 of 33
hpnavale
in reply to: ronjonp

WHAT IS COMMAND 

Message 11 of 33
ronjonp
in reply to: hpnavale


@hpnavale wrote:

WHAT IS COMMAND 


HOPS

Message 12 of 33
adhammagdy
in reply to: ronjonp

This is great but how to make the hop bigger?

Message 13 of 33
hak_vz
in reply to: adhammagdy

@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

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 14 of 33
ronjonp
in reply to: adhammagdy

@adhammagdy 

A few more suggestions HERE.

Message 15 of 33
andrew_k
in reply to: ronjonp

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)

 

Message 16 of 33
ronjonp
in reply to: andrew_k

@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))
  )
)
Message 17 of 33
andrew_k
in reply to: ronjonp

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!

Message 18 of 33
Kent1Cooper
in reply to: andrew_k


@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.

Kent Cooper, AIA
Message 19 of 33
andrew_k
in reply to: Kent1Cooper

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.

Message 20 of 33
andrew_k
in reply to: andrew_k

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.

Post to forums  

Autodesk Design & Make Report

”Boost