SLW210 Posted Thursday at 03:31 PM Posted Thursday at 03:31 PM Anyone have any hints on how to get Spline Leader lengths? Ultimately, I am looking to make several already drawn spline leaders the same length. Quote
BIGAL Posted Friday at 01:10 AM Posted Friday at 01:10 AM As a spline gives two answers the points answer and another with nodes. So any way if you explode the Mleader then you can get at the spline using this. Just need to check that the spline is last entity, tested in Bricscad. A disclaimer not sure if length is correct. I think it is short by length of arrow. Will try to find arrow length. Yep found it. (defun c:wow ( / plent pt len lenar) (setq plent (entsel "\nPick mleader ")) (setq lenar (cdr (assoc 140 (entget (car plent))))) (command "undo" "M") (command "explode" (car plent)) (setq ent (ssname (ssget "L") 0)) (setq len (getpropertyvalue ent "length")) (command "undo" "B") (alert (strcat "Total length is " (rtos (+ lenar len) 2 3))) (princ) ) (c:wow) I think you could do a "I want a length of 100 by drawing something close then move say arrow point till you get approx 100. Via lisp. It would be a two step process explode and move then undo and reset arrow head point. 1 Quote
SLW210 Posted Friday at 10:08 AM Author Posted Friday at 10:08 AM 17 hours ago, 1958 said: ml.LSP 1.41 kB · 5 downloads It would be nice if you could put the prompts and comments in English. I saw the Dogleglength when I did a dump on a Mleader. I'll see what I come up with. 8 hours ago, BIGAL said: As a spline gives two answers the points answer and another with nodes. So any way if you explode the Mleader then you can get at the spline using this. Just need to check that the spline is last entity, tested in Bricscad. A disclaimer not sure if length is correct. I think it is short by length of arrow. Will try to find arrow length. Yep found it. (defun c:wow ( / plent pt len lenar) (setq plent (entsel "\nPick mleader ")) (setq lenar (cdr (assoc 140 (entget (car plent))))) (command "undo" "M") (command "explode" (car plent)) (setq ent (ssname (ssget "L") 0)) (setq len (getpropertyvalue ent "length")) (command "undo" "B") (alert (strcat "Total length is " (rtos (+ lenar len) 2 3))) (princ) ) (c:wow) I think you could do a "I want a length of 100 by drawing something close then move say arrow point till you get approx 100. Via lisp. It would be a two step process explode and move then undo and reset arrow head point. I know how to get a Spline length, I don't want to explode the Mleaders, defeats the purpose. Quote
BIGAL Posted Saturday at 05:22 AM Posted Saturday at 05:22 AM (edited) The Undo un-explodes them though. On my phone. Will have a look at the lsp tomorrow. Edited Saturday at 05:23 AM by BIGAL 1 Quote
SLW210 Posted Monday at 02:18 PM Author Posted Monday at 02:18 PM But wouldn't undo change it back to original length? Quote Ultimately, I am looking to make several already drawn spline leaders the same length. On 8/28/2025 at 12:45 PM, 1958 said: ml.LSP 1.41 kB · 7 downloads Still looking to decipher this one, probably tomorrow when I get back to work. Quote
BIGAL Posted yesterday at 12:08 AM Posted yesterday at 12:08 AM As I suggested can move the vertices and return the new length or say draw something and move say the first point keep repeating till it is the length you want. Will have a play. 1 Quote
Tsuky Posted yesterday at 02:01 AM Posted yesterday at 02:01 AM @SLW210 Quote I saw the Dogleglength when I did a dump on a Mleader. I'll see what I come up with. You are rigth this is the good direction for your ask. Try this (defun c:length2lead ( / AcDoc Space ss dog_l n sel obj) (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)) Space (if (= 1 (getvar "CVPORT")) (vla-get-PaperSpace AcDoc) (vla-get-ModelSpace AcDoc) ) ) (vla-startundomark AcDoc) (princ "\nSelect mleader") (while (not (setq ss (ssget (list '(0 . "MULTILEADER") (cons 67 (if (eq (getvar "CVPORT") 1) 1 0)) (cons 410 (if (eq (getvar "CVPORT") 1) (getvar "CTAB") "Model")) ) ) ) ) ) (initget 7) (setq dog_l (getdist (getvar "VIEWCTR") "nNew length for multileader?: ")) (repeat (setq n (sslength ss)) (setq sel (ssname ss (setq n (1- n))) obj (vlax-ename->vla-object sel) ) (vla-put-DoglegLength obj dog_l) (vla-regen AcDoc acactiveviewport) ) (vla-endundomark AcDoc) (prin1) ) 1 Quote
BIGAL Posted yesterday at 06:17 AM Posted yesterday at 06:17 AM (edited) I don't think dogleglength is what you want. This example is original mleader was 33 tried dogleglength at 35 can see is way to long. Like twice the length required. it was like 70+ The only way I have found is to move either the 1st or last point and can get the desired spline length, but a big but must explode and recalc the spline point and then undo and reset the mleader then its length is correct. Or within say 1e-03 etc. I have not found a way to get a length of a mleader spline. Some one else may know. The default dogleg length is in the Mleaderstyle, I have started to play with it set to 0.0 asked me it makes it easier to work out lengths. Starting to look at making a spline so can easy recalc without any explodes. This shows in red what I consider the spline length. Note have to add arrow size. Please confirm. Can you also post a dwg with sample mleaders. Edited yesterday at 06:19 AM by BIGAL 1 Quote
SLW210 Posted yesterday at 10:36 AM Author Posted yesterday at 10:36 AM I thought I posted this yesterday. Yes, DOGLEGLENGTH is the landing, they should all be 0, but to make sure, it needs accounted for. May need to dig into something deeper. It's not a super important deal at the moment, I was just curious as to why it's so obscure for methods to manipulate Multileaders/Leaders without exploding. I have no Mtext, just have some routes, and would like them to match lengths, I need the arrow to relocate, not the landing. I have posted a test drawing. For future work, drawing them to a specific length would be nice, that seems to be what 1958's LISP does, still trying to decipher it though. P.S. After some testing, ml.lsp asks to select a line and then draws an Mleader and places text for the length, best I can decipher. MLeader Test.dwg Quote
Isaac26a Posted 23 hours ago Posted 23 hours ago I think the translation to 1958's lisp is this, although not quite sure is the best ;;; Multi-length ;;; https://www.cadtutor.net/forum/profile/26931-1958/ ;;; 28 august 2025 (defun c:ml (/ ent pline txt p1 p2) (vl-load-com) (while (setq pline (vlax-ename->vla-object (car (setq ent (entsel "\n indicate the line \n"))))) (setq txt (strcat "L = " (rtos (vlax-curve-getDistAtParam pline (vlax-curve-getEndParam pline)) 2 2) " m" ) ) (setq p1 (vlax-curve-getClosestPointTo pline (cadr ent)) p2 (getpoint p1 "\n insertion point >> \n") ) (vl-cmdf "_mleader" p1 p2 txt) (setq ent (vlax-ename->vla-object (entlast))) (vla-put-TextHeight ent 2.00) ; font size (height) (vla-put-TextJustify ent 1) ; text alignment (1-left) (vla-put-TextLeftAttachmentType ent 4) ; append text to left (vla-put-TextRightAttachmentType ent 4) ; append text to the right ;;; 0 - top of line 1 ;;; 1 - middle of line 1 ;;; 2 - bottom of line 1 ;;; 3 - underline of line 1 ;;; 4 - middle of text ;;; 5 - middle of last line ;;; 6 - bottom of last line ;;; 7 - underline of last line ;;; 8 - underline of all text (vla-put-DoglegLength ent 0.5) ; shelf size (length) ;;; (vla-put-TextStyleName ent "ext til") ; change text style ) (princ) ) ;|?Visual LISP Format Options? (100 1 2 2 nil " " 80 60 0 0 0 nil nil nil T) ;*** Please add text under the comments! ***|; 1 Quote
BIGAL Posted 13 hours ago Posted 13 hours ago I have some test code and it adjusts a spline can move start or end as a choice. In the ML it uses 2 points so there is no drama in making a Mleader with a correct length as its just a case of moving arrow along the angle of the leader line. So just reset p2 to be correct length. This will draw a 2pt leader. (defun c:wow1 ( / ) (setq p1 (getpoint "\nPick 1st point ") p2 (getpoint p1 "\n insertion point >> ") ) (setq ang (angle p1 p2)) (setq d1 (rtos (distance p1 p2) 2 3)) (setq str (strcat "\n existing is " d1 " Enter new length ")) (setq d2 (getreal str)) (setq p2 (polar p1 ang d2)) (command "Mleader" p1 p2 (getstring "\nEnter text ")) (setq ent (vlax-ename->vla-object (entlast))) (vla-put-DoglegLength ent 0.0) (princ) ) (c:wow1) Note the mleader style must be set to 2 points. For the spline type answer I used 4 points max in the mleader style, I thought that was what you wanted. A 3 -4 curved leader of a known length. 1 Quote
SLW210 Posted 3 hours ago Author Posted 3 hours ago I have more than 2 points most of the time. I'm wanting to fix already drawn leaders by matching the size and draw leaders to a specific length. Yes, I did some looking yesterday and from what I could find AutoCAD doesn't have the information exposed to API to get an exact length with more than 2 points. Quote
SLW210 Posted 3 hours ago Author Posted 3 hours ago So I have this working so far, not super accurate on multipoint Spline Multileaders, but close enough, seems accurate on some tested 2 point Multileaders. Changing the multipoint Multileaders to Straight Multileaders then running the LISP, then converting back to Spline Multileaders seems more accurate. Only quickly tested, so I'll know more later today if any problems arise. If interested it can be tested on the drawing I posted earlier. ;;; Match selected Multileader lengths using first selection. ;;; ;;; https://www.cadtutor.net/forum/topic/98672-get-length-of-mleaderqleader-spline/#findComment-676006 ;;; ;;; By SLW210 (a.k.a. Steve Wilson) ;;; (defun c:MLMtchLgnth (/ sel firstLeader vlaFirst firstLength i ent vlaCurrent pts allPts curLanding curLength scaleFactor newPts sa prevPt pt ) (vl-load-com) ;; Select MLeaders (setq sel (ssget '((0 . "MULTILEADER")))) (if sel (progn ;; First selected leader (setq firstLeader (ssname sel 0)) (setq vlaFirst (vlax-ename->vla-object firstLeader)) ;; Get points from First leader (setq pts (vlax-safearray->list (vlax-variant-value (vla-GetLeaderLineVertices vlaFirst 0) ) ) ) (setq allPts (vl-list->3dpoints pts)) ;; Measure first leader length (setq firstLength 0.0) (setq prevPt (car allPts)) (foreach pt (cdr allPts) (setq firstLength (+ firstLength (distance prevPt pt))) (setq prevPt pt) ) (princ (strcat "\nFirst leader length: " (rtos firstLength 2 2) ) ) ;; Process leaders (setq i 1) (while (< i (sslength sel)) (setq ent (ssname sel i)) (setq i (1+ i)) (setq vlaCurrent (vlax-ename->vla-object ent)) ;; Get vertices (setq pts (vlax-safearray->list (vlax-variant-value (vla-GetLeaderLineVertices vlaCurrent 0) ) ) ) (setq allPts (vl-list->3dpoints pts)) ;; Skip if less than 2 points (if (> (length allPts) 1) (progn (setq curLanding (last allPts)) ;; Measure current length (setq curLength 0.0) (setq prevPt curLanding) (foreach pt (reverse allPts) (setq curLength (+ curLength (distance prevPt pt))) (setq prevPt pt) ) ;; Compute scale factor (setq scaleFactor (/ firstLength curLength)) ;; Build new points (setq newPts '()) (foreach pt allPts (setq newPts (append newPts (list (scale-point pt curLanding)) ) ) ) ;; Flatten to doubles (setq pts (apply 'append newPts)) ;; Create and fill SafeArray (setq sa (vlax-make-safearray vlax-vbDouble (cons 0 (- (length pts) 1)) ) ) (vlax-safearray-fill sa pts) ;; Apply modified points (vla-SetLeaderLineVertices vlaCurrent 0 (vlax-make-variant sa) ) (princ (strcat "\nAdjusted leader to length " (rtos firstLength 2 2) ) ) ) (princ "\nSkipping leader with insufficient vertices.") ) ) ) (princ "\nNo MLeaders selected.") ) (princ) ) ;; Flat list to 3D points (defun vl-list->3dpoints (lst / out) (setq out nil) (while (>= (length lst) 3) (setq out (cons (list (car lst) (cadr lst) (caddr lst)) out)) (setq lst (cdddr lst)) ) (reverse out) ) ;; Scale vector from landing (defun scale-delta (landing pt) (list (* scaleFactor (- (nth 0 pt) (nth 0 landing))) (* scaleFactor (- (nth 1 pt) (nth 1 landing))) (* scaleFactor (- (nth 2 pt) (nth 2 landing))) ) ) ;; Scale point (defun scale-point (pt landing) (if (and (listp pt) (= (length pt) 3)) (mapcar '+ landing (scale-delta landing pt)) pt ) ) I wasted too much time on this, so drawing Multileaders to exact lengths will have to wait. Quote
SLW210 Posted 3 hours ago Author Posted 3 hours ago 20 hours ago, Isaac26a said: I think the translation to 1958's lisp is this, although not quite sure is the best I had most of it deciphered, but thanks that's much better than I ended up with. I may yet have use for it. 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.