takeanosan Posted November 28, 2014 Posted November 28, 2014 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. Quote
Tharwat Posted November 28, 2014 Posted November 28, 2014 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) ..... Quote
takeanosan Posted December 1, 2014 Author Posted December 1, 2014 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. Quote
Tharwat Posted December 1, 2014 Posted December 1, 2014 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 Quote
takeanosan Posted December 9, 2014 Author Posted December 9, 2014 (edited) 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 December 10, 2014 by takeanosan Quote
takeanosan Posted December 13, 2014 Author Posted December 13, 2014 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))) There is still more polishing work to be done. Such as undo and forcing the selection of leaders/text. This code also assumes that the leader is drawn header first. Improvements to be made to handle this. Calling the command in AutoCAD to draw the Mleader is slower than visual lisp or entmake, which I will be looking into. 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? Quote
BIGAL Posted December 14, 2014 Posted December 14, 2014 (edited) 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 December 15, 2014 by SLW210 Fixed Code Tags!! Quote
SergioPerez Posted June 16, 2019 Posted June 16, 2019 Take a look to this article: https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/get-last-vertex-of-a-leader/td-p/877846 Quote
SergioPerez Posted June 16, 2019 Posted June 16, 2019 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) ) Quote
Recommended Posts
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.