Jump to content
takeanosan

Second vertex of a leader

Recommended Posts

takeanosan

I have found the following at the swamp, however I would like to modify it to better suite my needs. All credits to Lyle Hardin for writing the awesome code.

 

;;; CADALYST 08/08  www.cadalyst.com/code 
;;; Tip 2305: LeaderToMleader.lsp	Leader to Multileader	(c) 2008 Lyle Hardin 
;;; Pick an old style leader and text to create a new mleader entity and erase the old leader and text.
;;; March/2008

(defun c:leadertomleader ()
 (setq	leader	(entsel "\nPick Leader")	; pick leader
leader2	(entget (car leader))
pt1	(dxf 10 leader2)		; get first point of leader
layer 	(dxf 8 leader2)			; get layer of leader

mtext	(entsel "\nPick Text")	; pick text
mtext2	(entget (car mtext))
pt2	(dxf 10 mtext2)		; get point of text
text	(dxf 1 mtext2)		; get 
 )					; setq
 
 (command "-layer" "s" layer "")	; set layer of leader picked to current
 (command "mleader" pt1 pt2 text)	; start mleader command
 (COMMAND "ERASE" mtext "")		; erase text picked
 (command "erase" leader "")		; erase leader picked

)					; defun

(defun dxf(code elist)		; define dxf function
 (cdr (assoc code elist))     ;Finds the association pair, strips 1st element
);defun

 

So what I would like to do is instead of selecting the insertion point of the mtext as the second point, I would like to change it to the second point of the leader.

 

I've done a little bit of digging around, but all I have found is that the dxf codes for the vertices are 10, resulting in a list:

(10 -94274.8 121436.0 0.0)

(10 -94274.8 121109.0 0.0)

(10 -95313.2 121109.0 0.0)

...(and so on)

 

Hence my question, how do I get the second vertex of the leader?

 

Thanks in advance.

Share this post


Link to post
Share on other sites
Tharwat

Modify that routine to suit the new changes .

 

.....
 leader2 (entget (car leader))
       pt1     (cdr (car (setq lst (vl-remove-if-not
                                     '(lambda (p) (eq (car p) 10))
                                     leader2
                                   )
                         )
                    )
               )
       pt2     (cdr (cadr lst))
       layer   (dxf 8 leader2)
.....

Share this post


Link to post
Share on other sites
takeanosan

Tharwat, we meet again!

 

The code is working! You just saved me countless hours in the future =D For that you have my sincere gratitude.

 

I'm trying to read the codes, do you mind annotating it so that it makes sense in plain language? I have yet to read up upon vl-remove-if-not and a quick glance at the Autodesk Help page does not help.

 

Besides that, I also came across two problem.

1. Any possible method to detect the number of vertices and hence saving each vertex into separate variables?

2. The multileader style definition "maximum leader points" defined to more than 2 (or set to 0 for the matter) will cause an error when drawing the multileader. When drafting it is a simple matter of hitting space/enter but in code is it possible to prevent/circumvent this? (I'm thinking detecting amount of vertices as above, then adding 1 variable as enter)(not sure if it works)

 

Then again, this is not exactly crucial to my work just more of a learning process for me. Hope it is not too much of a bother.

 

Best regards. :)

Share this post


Link to post
Share on other sites
Tharwat
Tharwat, we meet again!

 

:)

 

Besides that, I also came across two problem.

1. Any possible method to detect the number of vertices and hence saving each vertex into separate variables?

 

To get the number of a list , you can use length function .

 

Suppose that the ( lst ) variable has a list of coordinates as following .

((10 2141.66 1392.33) (10 2704.09 1392.33) (10 2704.09 1029.03) (10 3088.02 1029.03) (10 3088.02 776.739))

(length lst)

Should return 5 and to save each vertex with into separate variable , have a look at this .

 


(setq v "v"
     i 0
)
(while lst
 (set (read (strcat v (itoa (setq i (1+ i))))) (car lst))
 (setq lst (cdr lst))
)

Hope this helps :)

Share this post


Link to post
Share on other sites
takeanosan

It's been a week!

Finally had some time to code....and this is what I have came up with:

 

;;; CADALYST 08/08  www.cadalyst.com/code 
;;; Tip 2305: LeaderToMleader.lsp	Leader to Multileader	(c) 2008 Lyle Hardin 
;;; Pick an old style leader and text to create a new mleader entity and erase the old leader and text.
;;; March/2008

(defun c:leadertomleader ()
 (setq	leader	(entsel "\nPick Leader")		; pick leader in ACAD
	leaderpro (entget (car leader))		; all leader properties
	lst (vl-remove-if-not			; all properties that matches dxf 10
		  '(lambda (p) (eq (car p) 10))	; lambda defines an unknown function
		  leaderpro
		)
	lstr lst
		layer   	(dxf 8 leaderpro)
	mtext		(entsel "\nPick Text")	; pick text in ACAD
	mtextpro	(entget (car mtext)) 	; all text properties
	text		(dxf 1 mtextpro)	; text contents 
	llen 		(length lst)		; length of the list "lst"
	)					; end of setq
 
 (setq v "v"
	i 0
 )
 (while lstr								; while list is true
(set (read (strcat v (itoa (setq i (1+ i))))) (car lstr))	; expression
(setq lstr (cdr lstr))						; remove first value
 )

 (setq 	i2 0)

 
 
;START DRAWING LEADER
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;
 (command "-layer" "s" layer "")			; set layer of leader picked to current
; (command "mleader" pt1 pt2 text)			; start mleader command
 (command "mleader" (repeat llen (strcat "v"(itoa (setq i2 (1+ i2))))) e text)				; start mleader command
 (COMMAND "ERASE" mtext "")				; erase text picked
 (command "erase" leader "")				; erase leader picked

)							; defun



;DEFINE DXF TO STRIP 1ST ELEMENT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun dxf(code elist)					; define dxf function
 (cdr (assoc code elist))    				; Finds the association pair, strips 1st element
);end defun dxf

 

I have been trying numerous way to debug the code...however it gives me invalid input, bad argument type-consp, and I have run out of ideas.

 

Edit: Currently looking into mapcar and lambda, might just solve it!

 

best regards,

Takeano

Edited by takeanosan

Share this post


Link to post
Share on other sites
takeanosan

And the current working codes are:

 

;;; CADALYST 08/08  www.cadalyst.com/code 
;;; Tip 2305: LeaderToMleader.lsp	Leader to Multileader	(c) 2008 Lyle Hardin 
;;; Pick an old style leader and text to create a new mleader entity and erase the old leader and text.
;;; March/2008

(defun c:leadertomleader ()
 (setq	leader		(entsel "\nPick Leader")	; pick leader in ACAD
	leaderpro 	(entget (car leader))		; all leader properties
	lst 		(vl-remove-if-not				; all properties that matches dxf 10
				'(lambda (p) (eq (car p) 10))	; lambda defines an unknown function
				leaderpro
				)
	lsto		lst						; saving the original list
	llen		(length lst)			; length of the list "lst"
	
       layer   	(dxf 8 leaderpro)		; layer of leader
	layero 		(getvar "clayer")		; layer original
	
	mtext		(entsel "\nPick Text")	; pick text in ACAD
	mtextpro	(entget (car mtext)) 	; all text properties
	text		(dxf 1 mtextpro)		; text contents 

	
	v			"v"						; variable to add number to 
	i			0						; number for variable
	mlpt		()						; multileader point list, empty
)										; end of setq
 
 
 
;BUILDING THE LIST OF MLEADER POINTS
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;
 (while lst								; while list is less than lst length
(set (read (strcat v (itoa (setq i (1+ i))))) (car lst))
(setq mlpt (append mlpt (list (cdr (eval(read (strcat v (itoa i))))))))
(setq lst (cdr lst))					; set lst to second item
 )
 (setq mlpt (append mlpt (list "" text)))
 
;START DRAWING LEADER
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;
 (setvar 	"clayer" layer)					; set layer of leader picked to selected layer
 (command 	"mleader")						; start mleader command
 (foreach n mlpt (command n))
 (command 	"ERASE" mtext "")				; erase text picked
 (command 	"erase" leader "")				; erase leader picked
 (setvar 	"clayer" layero)				; set layer back to original
)											; end main function



;DEFINE DXF TO STRIP 1ST ELEMENT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun dxf(code elist)						; define dxf function
 (cdr (assoc code elist))    				; Finds the association pair, strips 1st element
);end defun dxf

;tests in autocad
;(setq lst (vl-remove-if-not '(lambda (p) (eq (car p) 10)) (entget (car (entsel)))))
;(while lst (set (read (strcat v (itoa (setq i (1+ i))))) (car lst)) (setq lst (cdr lst)))




 

 

  1. There is still more polishing work to be done. Such as undo and forcing the selection of leaders/text.
  2. This code also assumes that the leader is drawn header first. Improvements to be made to handle this.
  3. Calling the command in AutoCAD to draw the Mleader is slower than visual lisp or entmake, which I will be looking into.
  4. Besides that I believe that there should be other methods to extract and create the multileader point list.

 

Any alternatives/help/suggestions and criticism is welcomed.

 

regards.

Takeano

 

P.S. I've noted that the code looks tidy during edits in Notepad++. However while posting in these forums the comments tend to go wild =) Is there anything I can do?

Share this post


Link to post
Share on other sites
BIGAL

An alternative to the LST method as you know the length you can get each sub list item by using nth then car cadr caddr you can also double loop and use nth inside the sub string.

 

(setq lst((10 2141.66 1392.33) (10 2704.09 1392.33) (10 2704.09 1029.03) (10 3088.02 1029.03) (10 3088.02 776.739)))

(setq len (length lst))
(setq x 0)
(repeat len
(setq ans (nth x lst))
(princ (strcat "\ndxf code is" (car ans) "X is " (cadr ans) "Y is " (caddr ans)))
;(princ (strcat "\ndxf code is" (nth 0 ans) "X is " (nth 1 ans) "Y is " (nth 2 ans)))
(setq x (+ x 1))
)

Edited by SLW210
Fixed Code Tags!!

Share this post


Link to post
Share on other sites
SergioPerez

This is my version of the program.

 

(defun c:ch2mlea ()
  (setq ent ( car (entsel "\nPick Leader:"))        ; selecciona elemento
        entdata (entget ent)                                     ; obtiene los datos
        p1 (cdr (assoc 10 entdata))                       ; obtiene punto inicial
        ent2 (cdr (assoc 340 entdata))
        entdata2 (entget ent2)
        p2 (cdr (assoc 10 (reverse entdata) ))
        tex (cdr (assoc 1 entdata2)))
  (command "mleader" p1 p2 tex)
  (entdel ent2)
  (entdel ent)
  (princ)     
 )
 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...