Create diagram with Lisp

Create diagram with Lisp

karfung
Explorer Explorer
1,178 Views
29 Replies
Message 1 of 30

Create diagram with Lisp

karfung
Explorer
Explorer

Hi Sir,
I wish to create the diagram (grey colour only) when the red line and red dot in horizontal or vertical are provided as per picture 1. Kindly advise on the Lisp. 

Condition as below, 

1). The red line or red dot in picture 1 may be at various distances in vertical and horizontal. Lisp shall allow the user to create the grey circle located based on centre of red dot. Allow the user to select the red dot. 

2). Ask the user for the diameter of the grey circle. 

3). Fixed the grey colour line and circle as picture 1 with layer "SNA-DIM".

4). Finish 

 

Thanks. 

0 Likes
Accepted solutions (4)
1,179 Views
29 Replies
Replies (29)
Message 2 of 30

jreidKVSUZ
Collaborator
Collaborator

Good day.

 

This site might help more. They are LISPers!!

 

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/bd-p/visual-lisp-autolisp-customizat...

 

Hope this helps!!

 

Thanks, JRR!

0 Likes
Message 3 of 30

karfung
Explorer
Explorer

could you produce the lisp code. thanks

0 Likes
Message 4 of 30

Kent1Cooper
Consultant
Consultant

I agree that the Customization Forum is the better place for this.  But when you post the question there, add more detail, and better yet, include a small sample drawing.
What are the red dots?  Donuts with zero inside radius [i.e. closed two-arc-segment Polylines with width]?  Blocks?  Solid Hatch patterns?  If Hatch patterns, is the presumed Circle that was Hatched still there?

It looks to me as though the red lines are irrelevant, but since they are mentioned in the description, I wonder whether that's true.  If they are relevant, what is their part in the process?

Kent Cooper, AIA
0 Likes
Message 5 of 30

karfung
Explorer
Explorer

Hi Sir,
I wish to create a diagram in the line and circle format (as per picture 1 and drawing 1) to denote the rebar diameter in the engineering detail. In picture 1 and drawing 1, the vertical red line denotes vertical rebar installed parallel with the concrete surface, However, the red dot denotes horizontal rebar installed perpendicular with the concrete surface. The diagram shall create with grey colour line with x (inverse) on the 4 nos red dot only. Kindly advise on the Lisp. 

 

Condition as below, 

1). The red line or red dot in picture 1 may be at various distances in vertical and horizontal. Lisp shall allow the user to create the grey circle located based on the centre of the red dot. Allow the user to select the red dot. Display as per drawing 1. 

2). Ask the user for the diameter of the grey circle. 

3). Fixed the grey colour line and circle as in picture 1 with layer "SNA-DIM".

4). Finish 

 

Thanks. 

0 Likes
Message 6 of 30

komondormrex
Mentor
Mentor
Accepted solution

check the following. since since the 'points' for a diagram are parts of arrays, you need to pick center points manually in either order.

;*****************************************************************************************************************************************************

(defun vectors_angle (vector_1 vector_2 / x1 y1 z1 x2 y2 z2 ccw cos_a sin_a alpha)
  	(mapcar 'set '(x1 y1 z1) (mapcar '- (cadr vector_1) (car vector_1)))
  	(mapcar 'set '(x2 y2 z2) (mapcar '- (cadr vector_2) (car vector_2)))
	(setq cos_a (/ (+ (* x1 x2) (* y1 y2) (* z1 z2))
				   (* (sqrt (apply '+ (mapcar '(lambda (number) (expt number 2)) (list x1 y1 z1))))
					  (sqrt (apply '+ (mapcar '(lambda (number) (expt number 2)) (list x2 y2 z2))))
				   )
				)
		  sin_a (sqrt (- 1 (expt cos_a 2)))
	)
	(cond
		((zerop cos_a) (* 0.5 pi))
		((zerop (setq alpha (atan (/ sin_a cos_a)))) pi)
		((minusp alpha) (+ pi alpha))
		(t alpha)
	)
)

;*****************************************************************************************************************************************************

(defun c:cross_diag (/ diag_layer point_1 point_2 point_3 point_4 diameter compared_indices point_list )
	(setq diag_layer "SNA-DIM")
  	(if (null diameter_saved) (setq diameter_saved 50))
	(if (vl-catch-all-error-p (vl-catch-all-apply 'vla-item (list (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) diag_layer)))
		(vla-add (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) diag_layer)
	)
	(setq ;center_list (mapcar 'cdr (mapcar '(lambda (circle) (assoc 10 (entget circle)))
;											(vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget '((0 . "circle"))))))
;								   )
;					  )
;		  v_1_2 (list (car center_list) (cadr center_list))
;		  v_1_3 (list (car center_list) (caddr center_list))
;		  v_1_4 (list (car center_list) (cadddr center_list))
		  point_1 (trans (getpoint "\nPick 1st point: ") 1 0)
    	  point_2 (trans (getpoint "\nPick 2nd point: ") 1 0)
  		  point_3 (trans (getpoint "\nPick 3rd point: ") 1 0)
  		  point_4 (trans (getpoint "\nPick 4th point: ") 1 0)
		  v_1_2 (list point_1 point_2)
		  v_1_3 (list point_1 point_3)
		  v_1_4 (list point_1 point_4)
		  diameter (getreal (strcat "\nEnter circle diameter <" (rtos diameter_saved 2 1) ">: "))
  	)
  	(if (null diameter) (setq diameter diameter_saved) (setq diameter_saved diameter))
;	(cond
;		((= 0 (setq compared_indices (car (vl-sort-i (list (vectors_angle v_1_2 v_1_3) (vectors_angle v_1_2 v_1_4) (vectors_angle v_1_3 v_1_4)) '>))))
;			(setq point_list (list (car center_list) (cadddr center_list) (cadr center_list) (caddr center_list)))
;		)
;		((= 1 compared_indices) (setq point_list (list (car center_list) (caddr center_list) (cadr center_list) (cadddr center_list))))
;		(t (setq point_list (list (car center_list) (cadr center_list) (caddr center_list) (cadddr center_list))))
;	)
	(cond
		((= 0 (setq compared_indices (car (vl-sort-i (list (vectors_angle v_1_2 v_1_3) (vectors_angle v_1_2 v_1_4) (vectors_angle v_1_3 v_1_4)) '>))))
			(setq point_list (list point_1 point_4 point_2 point_3))
		)
		((= 1 compared_indices) (setq point_list (list point_1 point_3 point_2 point_4)))
		(t (setq point_list (list point_1 point_2 point_3 point_4)))
	)
	(if (and (and (member (angle (caddr point_list) (cadr point_list)) (list (* pi 0.5) (* pi 1.5)))
				  (member (angle (car point_list) (cadddr point_list)) (list (* pi 0.5) (* pi 1.5)))
			 )
			 (and (member (angle (car point_list) (caddr point_list)) (list 0 pi))
				  (member (angle (cadddr point_list) (cadr point_list)) (list 0 pi))
			 )
		)
		(mapcar '(lambda (2_point_list) (vla-put-layer (vla-addline (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
													 				(vlax-3d-point (polar (car 2_point_list)
													 									   (angle (car 2_point_list) (cadr 2_point_list))
													 									   (* 0.5 diameter)
													 								)
													 				)
													 				(vlax-3d-point (polar (cadr 2_point_list)
													 									   (angle (cadr 2_point_list) (car 2_point_list))
													 									   (* 0.5 diameter)
													 								)
													 				)
													   )
													   diag_layer
										)
										(vla-put-layer (vla-addcircle (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
													   				  (vlax-3d-point (car 2_point_list))
													   				  (* 0.5 diameter)
													   )
													   diag_layer
										)
										(vla-put-layer (vla-addcircle (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
													   				  (vlax-3d-point (cadr 2_point_list))
													   				  (* 0.5 diameter)
													   )
													   diag_layer
										)

				 )
				 (list (list (car point_list) (cadr point_list)) (list (caddr point_list) (cadddr point_list)))
		)
		(princ "\nSelected points are not orthogonally placed...")
	)
	(princ)
)

updated 

0 Likes
Message 7 of 30

karfung
Explorer
Explorer

Hi komondormrex, 

I have copy paste in the autocad, it not working. Could you review it?

 

Thanks 

0 Likes
Message 8 of 30

Kent1Cooper
Consultant
Consultant

@karfung wrote:

I have copy paste in the autocad, it not working. Could you review it?


[Add the missing closing right parenthesis at line 95.]

Kent Cooper, AIA
0 Likes
Message 9 of 30

Kent1Cooper
Consultant
Consultant

Are they always aligned horizontally, never offset like this?

Kent1Cooper_0-1765383791142.png

And always the same vertical spacing on both sides?

If so, it should be possible to pick just two dots.

Kent Cooper, AIA
0 Likes
Message 10 of 30

komondormrex
Mentor
Mentor

@karfung 

check the code in message 7, and yep as Kent already wrote i missed closing parenthesis at line 95 (97 now).

0 Likes
Message 11 of 30

Kent1Cooper
Consultant
Consultant

If the rods are horizontally aligned, here's my take on it:

(defun C:RodX(/ *error* doc svn svv ctr1 ctr2 ctr3 ctr4 rad)
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (prompt (strcat "\nError: " errmsg))
    ); if
    (mapcar 'setvar svn svv); reset System Variables
    (vla-endundomark doc)
    (prin1)
  ); defun - *error*
  (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
  (setq
    svn '(osmode cmdecho blipmode clayer); System Variable Names
    svv (mapcar 'getvar svn); and current Values
  ); setq
  (setvar 'osmode 4); CENter
  (setq
    ctr1 (getpoint "\nRod center at first corner of X: ")
    ctr3 (getpoint "\nRod center at opposite corner of X: ")
    ctr2 (list (car ctr1) (cadr ctr3))
    ctr4 (list (car ctr3) (cadr ctr1))
  ); setq
  (initget (if *RodXdia* 6 7)); no zero, no negative, no Enter on first use
  (setq *RodXdia*
    (cond
      ( (getdist
          (strcat
            "\nDiameter of Circles"
            (if *RodXdia* (strcat " <" (rtos *RodXdia*) ">") "")
            ": "
          ); strcat
        ); getdist
      ); User-input condition
      (*RodXdia*); prior value if present on Enter when allowed
    ); cond
    rad (/ *RodXdia* 2)   
  ); setq
  (mapcar 'setvar svn '(0 0 0)); turn off Osnap, command echo, blips
  (command
    "_.layer" "_make" "SNA-DIM" "_color" 9 "" ""
    "_.circle" ctr1 rad
    "_.copy" "_last" "" "_multiple" ctr1 ctr2 ctr3 ctr4 ""
    "_.line" (polar ctr1 (angle ctr1 ctr3) rad) (polar ctr3 (angle ctr3 ctr1) rad) ""
    "_.line" (polar ctr2 (angle ctr2 ctr4) rad) (polar ctr4 (angle ctr4 ctr2) rad) ""
    "_.line" (inters ctr1 ctr3 ctr2 ctr4) (polar (getvar 'lastpoint) 0 (* (abs (- (car ctr1) (car ctr3))) 1.5)) ""
    "_.layer" "_make" "SNA-TXT-2" "_color" 4 "" ""
  ); command
  (command-s "_.text" "_style" "ROMANS0.8" "_ml" (polar (getvar 'lastpoint) 0 rad) 80 0)
  (mapcar 'setvar svn svv); reset
  (vla-endundomark doc)
  (prin1)
)

You can pick the CENters [Object Snap built in for that] of two rod dots at any two opposite corners of the desired X location, in either order.

It includes the horizontal Line rightward from the X intersection, and the Text, which it leaves you to provide content for [you don't get to see it on-screen as you type, but just type it, answering the prompt in the Command line].  It currently uses the Text Style & height in your sample drawing, but could be made to ask for either or both of those and remember what you give it.  It needs the Style to exist in the drawing, without fixed height as in your sample, but could be made to create it, as it does with the Layers.

It remembers your Circle Diameter [once you have given it one], and offers it as default on subsequent use, so you don't need to enter it repeatedly.

Kent Cooper, AIA
Message 12 of 30

Sea-Haven
Mentor
Mentor
Accepted solution

Another select 3 points as in a "L". Works if even sloped.

; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/create-diagram-with-lisp/td-p/13938747

; X on reo by AlanH

(defun c:XREO ( / dia mp oldlay oldsnap pt1 pt1a pt2 pt2a pt3 pt3a pt4 pt4a rad)

(defun rtd (a)
 (/ (* a 180.0) pi)
)

(setq oldlay (getvar 'clayer))
(setvar 'clayer "SNA-DIM")
(setq oldsnap (getvar 'osmode))
(setvar 'osmode 4)

(if (= (tblsearch "Layer" "SNA-TXT-2") nil)
  (command "-layer" "M" "SNA-TXT-2" "")
)

(setq pt1 (getpoint "\nPick 1st point "))
(setq pt2 (getpoint pt1 "\nPick 1st point "))
(setq pt3 (getpoint pt2 "\nPick 1st point "))
(setq pt4 (polar  pt3 (angle pt2 pt1) (distance pt1 pt2)))
(setq dia (getreal "\nEnter diameter of circle "))

(if (= dia nil)(setq dia 50))

(setq rad (/ dia 2.0))

(setvar 'osmode 0)

(command "circle" pt1 rad)
(command "circle" pt2 rad)
(command "circle" pt3 rad)
(command "circle" pt4 rad)
(setq pt1a (polar pt1 (angle pt1 pt3) rad))
(setq pt3a (polar pt3 (angle pt3 pt1) rad))
(command "Line" pt1a pt3a "")

(setq pt2a (polar pt2 (angle pt2 pt4) rad))
(setq pt4a (polar pt4 (angle pt4 pt2) rad))
(command "Line" pt2a pt4a "")
(setq mp (mapcar '* (mapcar '+ pt1 pt3) '(0.5 0.5)))
(setq pt2 (polar mp (angle pt2 pt3) 180.0))
(command "line" mp pt2 "")
(setvar 'clayer "SNA-TXT-2")
; (command "text" "J" "ML" pt2 80.0 0.0 (getstring T "\nEnter bar description "))
(command "mtext" pt2 pt2 "T10-200" "")

(setvar 'osmode oldsnap)
(setvar 'clayer oldlay)

(princ)
)
(c:xreo)

Not sure what angle for text I used zero.

SeaHaven_0-1765509227481.png

 

 

0 Likes
Message 13 of 30

karfung
Explorer
Explorer

This is not working; the result shows the circle spacing similar to the circle diameter. 

For your info, solution of Sea Haven is work. 

 

0 Likes
Message 14 of 30

karfung
Explorer
Explorer

Yes, this is working. Could you do me a favour to revise as follows, 

1). Show the text "T12-200" with line from the center of cross as per picture 1. 

2). The text "T12-200" shall be layer SNA-TXT-2 and in multitext format.  

 

Thanks. 

0 Likes
Message 15 of 30

karfung
Explorer
Explorer

Yes, this is working. Could you do me a favour to revise as follows, 

1). Show the text "T12-200" automatically instead of requesting input "Enter bar description".  

2). The text "T12-200" shall be layer SNA-TXT-2 and in multitext format.  

 

Thanks 

0 Likes
Message 16 of 30

Kent1Cooper
Consultant
Consultant

@karfung wrote:

This is not working; the result shows the circle spacing similar to the circle diameter. 


I don't know what to tell you.  It works for me [still in re-testing, as it did when I posted it]:

Kent1Cooper_0-1765820391959.png

Can you show what you are getting?

[Maybe you're selecting in some way other than Osnapping to centers of diagonally opposite rods, or in a non-orthogonal arrangement.]

Kent Cooper, AIA
0 Likes
Message 17 of 30

komondormrex
Mentor
Mentor

surely,

;*****************************************************************************************************************************************************

(defun vectors_angle (vector_1 vector_2 / x1 y1 z1 x2 y2 z2 ccw cos_a sin_a alpha)
  	(mapcar 'set '(x1 y1 z1) (mapcar '- (cadr vector_1) (car vector_1)))
  	(mapcar 'set '(x2 y2 z2) (mapcar '- (cadr vector_2) (car vector_2)))
	(setq cos_a (/ (+ (* x1 x2) (* y1 y2) (* z1 z2))
				   (* (sqrt (apply '+ (mapcar '(lambda (number) (expt number 2)) (list x1 y1 z1))))
					  (sqrt (apply '+ (mapcar '(lambda (number) (expt number 2)) (list x2 y2 z2))))
				   )
				)
		  sin_a (sqrt (- 1 (expt cos_a 2)))
	)
	(cond
		((zerop cos_a) (* 0.5 pi))
		((zerop (setq alpha (atan (/ sin_a cos_a)))) pi)
		((minusp alpha) (+ pi alpha))
		(t alpha)
	)
)

;*****************************************************************************************************************************************************

(defun c:cross_diag (/ diag_layer bar_desc_layer point_1 point_2 point_3 point_4 diameter crossing_point end_mark_line_point bar_marking_mtext compared_indices point_list )
	(setq diag_layer "SNA-DIM")
  	(setq bar_desc_layer "SNA-TXT-2")
  	(if (null diameter_saved) (setq diameter_saved 50))
  	(if (null bar_desc_saved) (setq bar_desc_saved "BAR DESCRIPTION"))
	(if (vl-catch-all-error-p (vl-catch-all-apply 'vla-item (list (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) diag_layer)))
		(vla-add (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) diag_layer)
	)
  	(if (vl-catch-all-error-p (vl-catch-all-apply 'vla-item (list (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) bar_desc_layer)))
		(vla-add (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) bar_desc_layer)
	)
	(setq ;center_list (mapcar 'cdr (mapcar '(lambda (circle) (assoc 10 (entget circle)))
;											(vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget '((0 . "circle"))))))
;								   )
;					  )
;		  v_1_2 (list (car center_list) (cadr center_list))
;		  v_1_3 (list (car center_list) (caddr center_list))
;		  v_1_4 (list (car center_list) (cadddr center_list))
		  point_1 (trans (getpoint "\nPick 1st point: ") 1 0)
    	  	  point_2 (trans (getpoint "\nPick 2nd point: ") 1 0)
  		  point_3 (trans (getpoint "\nPick 3rd point: ") 1 0)
  		  point_4 (trans (getpoint "\nPick 4th point: ") 1 0)
		  v_1_2 (list point_1 point_2)
		  v_1_3 (list point_1 point_3)
		  v_1_4 (list point_1 point_4)
		  diameter (getreal (strcat "\nEnter circle diameter <" (rtos diameter_saved 2 1) ">: "))
		  bar_desc (getstring t (strcat "\nEnter bar description <" bar_desc_saved "> :")) 
  	)
  	(if (null diameter) (setq diameter diameter_saved) (setq diameter_saved diameter))
  	(if (= "" bar_desc) (setq bar_desc bar_desc_saved) (setq bar_desc_saved bar_desc))
;	(cond
;		((= 0 (setq compared_indices (car (vl-sort-i (list (vectors_angle v_1_2 v_1_3) (vectors_angle v_1_2 v_1_4) (vectors_angle v_1_3 v_1_4)) '>))))
;			(setq point_list (list (car center_list) (cadddr center_list) (cadr center_list) (caddr center_list)))
;		)
;		((= 1 compared_indices) (setq point_list (list (car center_list) (caddr center_list) (cadr center_list) (cadddr center_list))))
;		(t (setq point_list (list (car center_list) (cadr center_list) (caddr center_list) (cadddr center_list))))
;	)
	(cond
		((= 0 (setq compared_indices (car (vl-sort-i (list (vectors_angle v_1_2 v_1_3) (vectors_angle v_1_2 v_1_4) (vectors_angle v_1_3 v_1_4)) '>))))
			(setq point_list (list point_1 point_4 point_2 point_3))
		)
		((= 1 compared_indices) (setq point_list (list point_1 point_3 point_2 point_4)))
		(t (setq point_list (list point_1 point_2 point_3 point_4)))
	)
	(if (and (and (member (angle (caddr point_list) (cadr point_list)) (list (* pi 0.5) (* pi 1.5)))
				  (member (angle (car point_list) (cadddr point_list)) (list (* pi 0.5) (* pi 1.5)))
			 )
			 (and (member (angle (car point_list) (caddr point_list)) (list 0 pi))
				  (member (angle (cadddr point_list) (cadr point_list)) (list 0 pi))
			 )
		)
		(mapcar '(lambda (2_point_list) (vla-put-layer (vla-addline (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
					 				    (vlax-3d-point (polar (car 2_point_list)
			 									  (angle (car 2_point_list) (cadr 2_point_list))
			 									  (* 0.5 diameter)
			 								   )
					 				    )
					 				    (vlax-3d-point (polar (cadr 2_point_list)
			 									  (angle (cadr 2_point_list) (car 2_point_list))
			 									  (* 0.5 diameter)
			 								   )
					 				    )
					   			)
							   	diag_layer
						)
						(vla-put-layer (vla-addcircle (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
					   				      (vlax-3d-point (car 2_point_list))
					   				      (* 0.5 diameter)
					   		       )
					     		       diag_layer
						)
						(vla-put-layer (vla-addcircle (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
					   				      (vlax-3d-point (cadr 2_point_list))
					   				      (* 0.5 diameter)
					   		       )
					   		       diag_layer
						)
			   			(vla-put-layer (vla-addline (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
								 	    (vlax-3d-point (setq crossing_point (mapcar '* '(0.5 0.5) (mapcar '+ (car 2_point_list) (cadr 2_point_list)))))
								 	    (setq end_mark_line_point (vlax-3d-point (polar crossing_point 0 (* 2.4 diameter))))
					 				    
					   		       )
							       diag_layer
						)
			   			(vla-put-layer (setq bar_marking_mtext (vla-addmtext (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
								 	     			     end_mark_line_point 0 bar_desc
										       )
							       )
						               bar_desc_layer
						)
			   			(vla-put-height bar_marking_mtext (* 1.6 diameter))
			   			(vla-put-attachmentpoint bar_marking_mtext acAttachmentPointMiddleLeft)
			   			(vla-put-insertionpoint bar_marking_mtext end_mark_line_point)
			 )
			 (list (list (car point_list) (cadr point_list)) (list (caddr point_list) (cadddr point_list)))
		)
		(princ "\nSelected points are not orthogonally placed...")
	)
	(princ)
)
0 Likes
Message 18 of 30

Sea-Haven
Mentor
Mentor
Accepted solution

@karfung code updated above.

0 Likes
Message 19 of 30

karfung
Explorer
Explorer

Yes, this is working. Could you do me a favour to revise as follows,

1). The text "T12-200" shall be layer SNA-TXT-2 and in "multitext" or "mtext" format.  

2). To request the mtext to be what text size (height). Subsequently, the mtext shall indicate the text height as per key in .This request should be request after the diameter circle is entered.   

 

Thanks 

0 Likes
Message 20 of 30

karfung
Explorer
Explorer

The mtext should be aligned to the left center. 

0 Likes