Author Topic: MLEADER arrow coordinates  (Read 1114 times)

0 Members and 2 Guests are viewing this topic.

CHulse

  • Bull Frog
  • Posts: 453
MLEADER arrow coordinates
« on: March 21, 2019, 03:28:40 PM »
Could anyone share an example of how to access the arrowhead point location (coordinates) for mleaders?

Ultimately, I want to extract the leader coordinates and the text contents, but I don't see how to get to the arrowhead location.

Appreciate any help with this.
Thanks
Cary Hulse
Sr. Urban Forester
Wetland Studies and Solutions

Civil 3D 2018

ronjonp

  • Needs a day job
  • Posts: 7060
Re: MLEADER arrow coordinates
« Reply #1 on: March 21, 2019, 04:18:13 PM »
Try something like this for some hints :)
Code: [Select]
(SETQ O (vlax-ename->vla-object (CAR (ENTSEL))))
(vlax-dump-Object O T)
(VLAX-INVOKE O 'GetLeaderLineVertices 0)

Windows 10 x64 - AutoCAD /C3D 2020

Custom Build PC

Lee Mac

  • Seagull
  • Posts: 12295
  • London, England
Re: MLEADER arrow coordinates
« Reply #2 on: March 21, 2019, 05:23:30 PM »
Here's another route -
Code - Auto/Visual Lisp: [Select]
  1. (if (setq s (ssget "_+.:E:S" '((0 . "MULTILEADER"))))
  2.     (cdr (assoc 10 (member '(304 . "LEADER_LINE{") (entget (ssname s 0)))))
  3. )

CHulse

  • Bull Frog
  • Posts: 453
Re: MLEADER arrow coordinates
« Reply #3 on: March 22, 2019, 07:15:21 AM »
Thanks guys. I really appreciate the help.
Cary Hulse
Sr. Urban Forester
Wetland Studies and Solutions

Civil 3D 2018

CHulse

  • Bull Frog
  • Posts: 453
Re: MLEADER arrow coordinates
« Reply #4 on: April 11, 2019, 02:09:13 PM »
OK, so I'm a little confused with how this works.

Given 2 different drawings with mleaders-

this worked on one:
Code: [Select]
(vla-getleaderlinevertices obj 0)
but didn't work on the other.
This did:
Code: [Select]
(vla-getleaderlinevertices obj 1)

Help?
Cary Hulse
Sr. Urban Forester
Wetland Studies and Solutions

Civil 3D 2018

Dlanor

  • Newt
  • Posts: 183
Re: MLEADER arrow coordinates
« Reply #5 on: April 11, 2019, 04:45:52 PM »
Typing MLeader on the command lines gives you this :

Specify leader arrowhead location or [leader Landing first/Content first/Options] <Options>:

Default is to construct from arrowhead location to landing then content but you can also opt for Landing first then arrowhead then content

or

Content then construct the leader to the arrowhead (landing location is calculated from content location)

With the default option (vla-getleaderlinevertices obj 0) gets you the arrowhead. With the other options you have to use the (GetVertexCount) method to find out how many vertices there are, and the last one will be the arrowhead

Code - Auto/Visual Lisp: [Select]
  1. (vla-getvertexcount (vlax-ename->vla-object (car (entsel))) 0)

The 0 at the end is the index of the leader, as you can have multiple leaders to a single content. So on a 3 vertex leader the last vertex will be index 2 (indices are zero based)


 


Lee Mac

  • Seagull
  • Posts: 12295
  • London, England
Re: MLEADER arrow coordinates
« Reply #6 on: April 11, 2019, 04:51:22 PM »
Since a multileader can have multiple leader lines (by using the AIMLEADEREDITADD command), the leaderlineindex argument (the final integer argument) of the getleaderlinevertices method is a zero-based integer index corresponding to the leader line for which you wish to obtain the vertices.

Since leader lines are not re-indexed when a leader line is removed, if you have constructed a multileader with multiple leader lines, and then removed the first leader line constructed (using the AIMLEADEREDITREMOVE command), the remaining leader line will remain at index 1, and invoking the getleaderlinevertices method with a leaderlineindex argument of 0 will result in an error.

I should add that you can obtain a list of valid leader line indexes using the getleaderlineindexes method, and hence, a more robust method of obtaining the leader line vertices (for all leader lines associated with an multileader) could be the following:
Code - Auto/Visual Lisp: [Select]
  1. (defun mleaderlinevertices ( mlr )
  2.     (mapcar '(lambda ( x ) (vlax-invoke mlr 'getleaderlinevertices x)) (vlax-invoke mlr 'getleaderlineindexes 0))
  3. )
« Last Edit: April 11, 2019, 05:08:46 PM by Lee Mac »

CHulse

  • Bull Frog
  • Posts: 453
Re: MLEADER arrow coordinates
« Reply #7 on: April 12, 2019, 01:16:05 PM »
Thanks Lee
using your hint, I've been playing around with this to get the first leader's coordinates:

Code - Auto/Visual Lisp: [Select]
  1. (setq idxa (car(vlax-safearray->list (vlax-variant-value (vla-GetLeaderLineIndexes obj 0))))
  2.          verts (vlax-safearray->list (vlax-variant-value (vla-getleaderlinevertices obj idxa))))
  3.  

This seems to work fine for most, but I still get an error with some leaders, saying "invalid index".


I'm not sure what to check. It seems to happen as you said, if a leader has been removed, and also in a file where the user apparently copy/pasted over and over from another dwg.
 
Is there a way to check for a valid leader that I'm missing?

« Last Edit: April 12, 2019, 01:21:29 PM by CHulse »
Cary Hulse
Sr. Urban Forester
Wetland Studies and Solutions

Civil 3D 2018

Lee Mac

  • Seagull
  • Posts: 12295
  • London, England
Re: MLEADER arrow coordinates
« Reply #8 on: April 12, 2019, 01:48:02 PM »
Why not use the function I provided?

CHulse

  • Bull Frog
  • Posts: 453
Re: MLEADER arrow coordinates
« Reply #9 on: April 12, 2019, 03:18:24 PM »
I did try that and had the same results, unless I wasn't applying it correctly.  I broke it down so I could follow it better. I still struggle with mapcar and lambda.


Here's my testing code:
Code - Auto/Visual Lisp: [Select]
  1. (while (setq en (ssname ss 0))
  2.                 (setq   obj      (vlax-ename->vla-object en) ;convert ename to vla object
  3.                            verts   (mapcar '(lambda ( x ) (vlax-invoke obj 'getleaderlinevertices x)) (vlax-invoke obj 'getleaderlineindexes 0))
  4.                 );_end setq
  5.  
  6.         (princ " verts: " )    
  7.         (princ verts)
  8.         (terpri )
  9.        
  10.         (ssdel en ss)  
  11. );_end while
  12.  
« Last Edit: April 12, 2019, 03:28:26 PM by CHulse »
Cary Hulse
Sr. Urban Forester
Wetland Studies and Solutions

Civil 3D 2018

CHulse

  • Bull Frog
  • Posts: 453
Re: MLEADER arrow coordinates
« Reply #10 on: April 12, 2019, 03:24:12 PM »
Here's an example of the mleaders I have. Some work fine and others give the error.
Cary Hulse
Sr. Urban Forester
Wetland Studies and Solutions

Civil 3D 2018

Lee Mac

  • Seagull
  • Posts: 12295
  • London, England
Re: MLEADER arrow coordinates
« Reply #11 on: April 13, 2019, 02:41:08 PM »
Unless I've overlooked something, there would seem to be insufficient information exposed by the ActiveX properties & methods derived from a Multileader Object to tackle this purely through Visual LISP, for example: the methods getleaderlinevertices, getleaderlineindexes, & getleaderindex all require a leaderlineindex, but there does not appear to be a property or method which yields the available valid leader line indexes which may be supplied to these methods.

As such, I think this task may be easier to tackle through Vanilla AutoLISP since more information is exposed through the DXF data associated with a MULTILEADER entity.

To this end, consider the following function to return the vertices for all leaders associated with a given Multileader entity:
Code - Auto/Visual Lisp: [Select]
  1. (defun LM:mleadervertices ( ent )
  2.     (mapcar '(lambda ( x ) (massoc 10 x))
  3.         (massoc "LEADER_LINE{"
  4.             (cdr
  5.                 (assoc "LEADER{"
  6.                     (cdr
  7.                         (assoc "CONTEXT_DATA{"
  8.                             (parsedxfdata (entget ent))
  9.                         )
  10.                     )
  11.                 )
  12.             )
  13.         )
  14.     )
  15. )
  16. (defun massoc ( k l )
  17.     (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= k (car x))) l))
  18. )
  19. (defun parsedxfdata ( l / foo )
  20.     (defun foo ( / x )
  21.         (setq x (car l)
  22.               l (cdr l)
  23.         )
  24.         (cond
  25.             (   (or (null x) (= "}" (cdr x)))
  26.                 nil
  27.             )
  28.             (   (and (= 'str (type (cdr x))) (wcmatch (cdr x) "*{*"))
  29.                 (cons (cons (cdr x) (foo)) (foo))
  30.             )
  31.             (   (cons x (foo)))
  32.         )
  33.     )
  34.     (foo)
  35. )

Here is a basic program to test the above:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / c e )
  2.     (if
  3.         (and
  4.             (setq e (car (entsel "\nSelect mleader: ")))
  5.             (= "MULTILEADER" (cdr (assoc 0 (entget e))))
  6.             (setq c 1)
  7.         )
  8.         (foreach l (LM:mleadervertices e)
  9.             (foreach v l
  10.                 (entmake (list '(0 . "POINT") (cons 10 v) (cons 62 c)))
  11.             )
  12.             (setq c (1+ (rem c 255)))
  13.         )
  14.     )
  15. )

CHulse

  • Bull Frog
  • Posts: 453
Re: MLEADER arrow coordinates
« Reply #12 on: April 13, 2019, 03:51:13 PM »
Thanks Lee
I'll give this a go on Monday. Much appreciated.
Cary Hulse
Sr. Urban Forester
Wetland Studies and Solutions

Civil 3D 2018