Jump to content

Multi-Leader Shrinkwrap


Shoey

Recommended Posts

Hi all

 

We have drawings containing Multi-Leaders that have their bounding boxes way too big! Too bigger than what the text is contained in the bounding box.

 

We do have a lisp that can re-size the bounding box for MTEXT entities, but this does not work for Multi-Leaders text.

 

Does anyone already have a lisp that does this and are willing to share?

 

It will be very much appreciated if anyone can assist.

 

Regards

Shoey

Link to comment
Share on other sites

Try this simple code ...

 

(defun c:Test (/ e i n)
 (if (setq e (ssget "_:L" '((0 . "MULTILEADER"))))
   (repeat (setq i (sslength e))
     (setq n (ssname e (setq i (1- i))))
     (entmod (subst '(43 . 0.) (assoc 43 (entget n)) (entget n)))
   )
 )
 (princ)
)

Link to comment
Share on other sites

Thanks very much Tharwat.

 

I appreciate your code. However, i forgot to mention that we have multiple lines of text contained within our multi-leaders.

We need to retain these lines of text and keep the width and height of the bounding box the same.

We do not wish to convert them into a single line of text.

 

Regards

Shoey

Link to comment
Share on other sites

Try the following Shoey:

 

[color=GREEN];; Fit MLeader MText Frame  -  Lee Mac[/color]

([color=BLUE]defun[/color] c:mlf ( [color=BLUE]/[/color] e f i l s )

   ([color=BLUE]defun[/color] f ( e [color=BLUE]/[/color] i l s x )
       ([color=BLUE]setq[/color] s ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 304 e))
             x ([color=BLUE]list[/color]
                   ([color=BLUE]cons[/color] 40 ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 41 e)))
                   ([color=BLUE]cons[/color] 07 ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 02 ([color=BLUE]entget[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 340 e))))))
               )
       )
       ([color=BLUE]while[/color] ([color=BLUE]setq[/color] i ([color=BLUE]vl-string-search[/color] [color=MAROON]"\\P"[/color] s))
           ([color=BLUE]setq[/color] l ([color=BLUE]cons[/color] ([color=BLUE]substr[/color] s 1 i) l)
                 s ([color=BLUE]substr[/color] s ([color=BLUE]+[/color] i 3))
           )
       )
       ([color=BLUE]setq[/color] l
           ([color=BLUE]vl-remove-if[/color] '[color=BLUE]null[/color]
               ([color=BLUE]mapcar[/color]
                   ([color=BLUE]function[/color]
                       ([color=BLUE]lambda[/color] ( s [color=BLUE]/[/color] b )
                           ([color=BLUE]if[/color] ([color=BLUE]setq[/color] b ([color=BLUE]textbox[/color] ([color=BLUE]cons[/color] ([color=BLUE]cons[/color] 1 s) x)))
                               ([color=BLUE]mapcar[/color] '[color=BLUE]-[/color] ([color=BLUE]cadr[/color] b) ([color=BLUE]car[/color] b))
                           )
                       )
                   )
                   ([color=BLUE]cons[/color] s l)
               )
           )
       )
       ([color=BLUE]list[/color]
           ([color=BLUE]*[/color] [highlight]1.01[/highlight] ([color=BLUE]apply[/color] '[color=BLUE]max[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]car[/color] l)))
           ([color=BLUE]+[/color] ([color=BLUE]apply[/color] '[color=BLUE]+[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]cadr[/color] l)) ([color=BLUE]*[/color] 0.68 ([color=BLUE]1-[/color] ([color=BLUE]length[/color] l))))
       )
   )
   
   ([color=BLUE]if[/color] ([color=BLUE]setq[/color] s ([color=BLUE]ssget[/color] [color=MAROON]"_:L"[/color] '((0 . [color=MAROON]"MULTILEADER"[/color]))))
       ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
           ([color=BLUE]setq[/color] e ([color=BLUE]entget[/color] ([color=BLUE]ssname[/color] s ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i))))
                 l (f e)
           )
           ([color=BLUE]entmod[/color]
               ([color=BLUE]subst[/color] ([color=BLUE]cons[/color] 43 ([color=BLUE]car[/color] l)) ([color=BLUE]assoc[/color] 43 e)
                   ([color=BLUE]subst[/color] ([color=BLUE]cons[/color] 44 ([color=BLUE]cadr[/color] l)) ([color=BLUE]assoc[/color] 44 e) e)
               )
           )
       )
   )
   ([color=BLUE]princ[/color])
)

 

Increase the [highlight]highlighted[/highlight] tolerance value if you find some text is still moved onto the next line.

Edited by Lee Mac
Link to comment
Share on other sites

Lee

 

Many thanks for your code too.

Its nearly there but the bounding box for the height is not quite there.

Hopefully, the attached image will make more sense to what we require.

The left image is what we are finding in our drawings.

Users have been returning upon the end of the line instead of using fixed widths.

We have also found that either multiple returns have been added at the end, hence the space at the bottom, or the users ahve been clicking and stretching the grips.

The image on the right is what we would like to see after the lisp is run.

Your code fixes the width grip location, but not the height grip location.

 

 

Hope you can assist.

 

Regards

Shoey

Mleader.jpg

Link to comment
Share on other sites

  • 2 years later...
Try the following Shoey:

 

[color=GREEN];; Fit MLeader MText Frame  -  Lee Mac[/color]

([color=BLUE]defun[/color] c:mlf ( [color=BLUE]/[/color] e f i l s )

   ([color=BLUE]defun[/color] f ( e [color=BLUE]/[/color] i l s x )
       ([color=BLUE]setq[/color] s ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 304 e))
             x ([color=BLUE]list[/color]
                   ([color=BLUE]cons[/color] 40 ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 41 e)))
                   ([color=BLUE]cons[/color] 07 ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 02 ([color=BLUE]entget[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 340 e))))))
               )
       )
       ([color=BLUE]while[/color] ([color=BLUE]setq[/color] i ([color=BLUE]vl-string-search[/color] [color=MAROON]"\\P"[/color] s))
           ([color=BLUE]setq[/color] l ([color=BLUE]cons[/color] ([color=BLUE]substr[/color] s 1 i) l)
                 s ([color=BLUE]substr[/color] s ([color=BLUE]+[/color] i 3))
           )
       )
       ([color=BLUE]setq[/color] l
           ([color=BLUE]vl-remove-if[/color] '[color=BLUE]null[/color]
               ([color=BLUE]mapcar[/color]
                   ([color=BLUE]function[/color]
                       ([color=BLUE]lambda[/color] ( s [color=BLUE]/[/color] b )
                           ([color=BLUE]if[/color] ([color=BLUE]setq[/color] b ([color=BLUE]textbox[/color] ([color=BLUE]cons[/color] ([color=BLUE]cons[/color] 1 s) x)))
                               ([color=BLUE]mapcar[/color] '[color=BLUE]-[/color] ([color=BLUE]cadr[/color] b) ([color=BLUE]car[/color] b))
                           )
                       )
                   )
                   ([color=BLUE]cons[/color] s l)
               )
           )
       )
       ([color=BLUE]list[/color]
           ([color=BLUE]*[/color] [highlight]1.01[/highlight] ([color=BLUE]apply[/color] '[color=BLUE]max[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]car[/color] l)))
           ([color=BLUE]+[/color] ([color=BLUE]apply[/color] '[color=BLUE]+[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]cadr[/color] l)) ([color=BLUE]*[/color] 0.68 ([color=BLUE]1-[/color] ([color=BLUE]length[/color] l))))
       )
   )
   
   ([color=BLUE]if[/color] ([color=BLUE]setq[/color] s ([color=BLUE]ssget[/color] [color=MAROON]"_:L"[/color] '((0 . [color=MAROON]"MULTILEADER"[/color]))))
       ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
           ([color=BLUE]setq[/color] e ([color=BLUE]entget[/color] ([color=BLUE]ssname[/color] s ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i))))
                 l (f e)
           )
           ([color=BLUE]entmod[/color]
               ([color=BLUE]subst[/color] ([color=BLUE]cons[/color] 43 ([color=BLUE]car[/color] l)) ([color=BLUE]assoc[/color] 43 e)
                   ([color=BLUE]subst[/color] ([color=BLUE]cons[/color] 44 ([color=BLUE]cadr[/color] l)) ([color=BLUE]assoc[/color] 44 e) e)
               )
           )
       )
   )
   ([color=BLUE]princ[/color])
)

 

Increase the [highlight]highlighted[/highlight] tolerance value if you find some text is still moved onto the next line.

 

Dear LeeMac

Can get the textbox or 4 vertex coordinates of Mleader ?

It's possible ?

Link to comment
Share on other sites

Here's a draft of a function to determine the textbox of an MLeader with text content:

[color=GREEN];; MLeader Textbox  -  Lee Mac[/color]
[color=GREEN];; Returns four OCS points describing the textbox of the content for a given MLeader[/color]
[color=GREEN];; ent - [ent] MLeader entity[/color]

([color=BLUE]defun[/color] LM:mleadertextbox ( ent [color=BLUE]/[/color] bpt enx hgt jus lst mat org prp rot wid )
   ([color=BLUE]if[/color] ([color=BLUE]=[/color] [color=BLUE]acmtextcontent[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 172 ([color=BLUE]reverse[/color] ([color=BLUE]setq[/color] enx ([color=BLUE]entget[/color] ent))))))
       ([color=BLUE]progn[/color]
           ([color=BLUE]setq[/color] prp ([color=BLUE]list[/color] ([color=BLUE]cons[/color] 40 ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 41 enx)))
                           ([color=BLUE]cons[/color] 07 ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 02 ([color=BLUE]entget[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 340 enx))))))
                     )
                 lst ([color=BLUE]vl-remove-if[/color] '[color=BLUE]null[/color]
                         ([color=BLUE]mapcar[/color]
                            '([color=BLUE]lambda[/color] ( str [color=BLUE]/[/color] box )
                                 ([color=BLUE]if[/color] ([color=BLUE]setq[/color] box ([color=BLUE]textbox[/color] ([color=BLUE]cons[/color] ([color=BLUE]cons[/color] 1 str) prp)))
                                     ([color=BLUE]mapcar[/color] '[color=BLUE]-[/color] ([color=BLUE]cadr[/color] box) ([color=BLUE]car[/color] box))
                                 )
                             )
                             (LM:str->lst ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 304 enx)) [color=MAROON]"\\P"[/color])
                         )
                     )
                 bpt ([color=BLUE]trans[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 12 enx)) 0 ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 11 enx)))
                 rot ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 042 enx))
                 jus ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 171 enx))
                 wid ([color=BLUE]apply[/color] '[color=BLUE]max[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]car[/color] lst))
                 hgt ([color=BLUE]+[/color] ([color=BLUE]apply[/color] '[color=BLUE]+[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]cadr[/color] lst)) ([color=BLUE]*[/color] 0.68 ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 45 enx)) ([color=BLUE]1-[/color] ([color=BLUE]length[/color] lst))))
                 org ([color=BLUE]list[/color] ([color=BLUE]cond[/color] (([color=BLUE]member[/color] jus '(2 5 ) ([color=BLUE]/[/color] wid -2.0)) (([color=BLUE]member[/color] jus '(3 6 9)) ([color=BLUE]-[/color] wid))      (0.0))
                           ([color=BLUE]cond[/color] (([color=BLUE]member[/color] jus '(1 2 3)) ([color=BLUE]-[/color] hgt))      (([color=BLUE]member[/color] jus '(4 5 6)) ([color=BLUE]/[/color] hgt -2.0)) (0.0))
                     )
                 mat ([color=BLUE]list[/color]
                         ([color=BLUE]list[/color] ([color=BLUE]cos[/color] rot) ([color=BLUE]sin[/color] ([color=BLUE]-[/color] rot)) 0.0)
                         ([color=BLUE]list[/color] ([color=BLUE]sin[/color] rot) ([color=BLUE]cos[/color] rot)     0.0)
                        '(0.0 0.0 1.0)
                     )
           )
           ([color=BLUE]mapcar[/color] '([color=BLUE]lambda[/color] ( p ) ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] (mxv mat p) bpt))
               ([color=BLUE]list[/color] org
                   ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] org ([color=BLUE]list[/color] wid   0))
                   ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] org ([color=BLUE]list[/color] wid hgt))
                   ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] org ([color=BLUE]list[/color] 0   hgt))
               )
           )
       )
   )
)

[color=GREEN];; String to List  -  Lee Mac[/color]
[color=GREEN];; Separates a string using a given delimiter[/color]
[color=GREEN];; str - [str] String to process[/color]
[color=GREEN];; del - [str] Delimiter by which to separate the string[/color]
[color=GREEN];; Returns: [lst] List of strings[/color]

([color=BLUE]defun[/color] LM:str->lst ( str del [color=BLUE]/[/color] pos )
   ([color=BLUE]if[/color] ([color=BLUE]setq[/color] pos ([color=BLUE]vl-string-search[/color] del str))
       ([color=BLUE]cons[/color] ([color=BLUE]substr[/color] str 1 pos) (LM:str->lst ([color=BLUE]substr[/color] str ([color=BLUE]+[/color] pos 1 ([color=BLUE]strlen[/color] del))) del))
       ([color=BLUE]list[/color] str)
   )
)

[color=GREEN];; Matrix x Vector  -  Vladimir Nesterovsky[/color]
[color=GREEN];; Args: m - nxn matrix, v - vector in R^n[/color]

([color=BLUE]defun[/color] mxv ( m v )
   ([color=BLUE]mapcar[/color] '([color=BLUE]lambda[/color] ( r ) ([color=BLUE]apply[/color] '[color=BLUE]+[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]*[/color] r v))) m)
)

 

And a small test program:

([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] e v )
   ([color=BLUE]if[/color] ([color=BLUE]setq[/color] e ([color=BLUE]ssget[/color] [color=MAROON]"_+.:E:S"[/color] '((0 . [color=MAROON]"MULTILEADER"[/color]))))
       ([color=BLUE]progn[/color]
           ([color=BLUE]setq[/color] e ([color=BLUE]ssname[/color] e 0)
                 v ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 11 ([color=BLUE]entget[/color] e)))
           )
           ([color=BLUE]foreach[/color] x (LM:mleadertextbox e)
               ([color=BLUE]entmake[/color] ([color=BLUE]list[/color] '(0 . [color=MAROON]"POINT"[/color]) ([color=BLUE]cons[/color] 10 ([color=BLUE]trans[/color] x v 0))))
           )
       )
   )
   ([color=BLUE]princ[/color])
)

Link to comment
Share on other sites

Here's a draft of a function to determine the textbox of an MLeader with text content:

 

Dear LeeMac

8) Thanks a million. I do appreciate your timely help!

Link to comment
Share on other sites

  • 9 months later...

In order to eliminate a step, is there a way to determine the boundaries of multileader text while place the multileader in the drawing?

Link to comment
Share on other sites

  • 6 years later...

I know this is an old thread but on current versions of ACAD I get the following error when I run Lee Mac's Fit MLeader MText Frame code. Can anyone help me? Thanks.

 

bad argument type: numberp: nil :error#0

Edited by mcweb
Link to comment
Share on other sites

  • 5 months later...
On 3/22/2023 at 10:22 AM, mcweb said:

I know this is an old thread but on current versions of ACAD I get the following error when I run Lee Mac's Fit MLeader MText Frame code. Can anyone help me? Thanks.

 

bad argument type: numberp: nil :error#0

Still would like to try out Lee Mac's code. I get this error in ACAD 2022.

 

 ; error: bad argument type: numberp: nil

Link to comment
Share on other sites

If you clean up the extra formatting it should work.

 

;; Fit MLeader MText Frame  -  Lee Mac

(defun c:mlf ( / e f i l s )

   (defun f ( e / i l s x )
       (setq s (cdr (assoc 304 e))
             x (list
                   (cons 40 (cdr (assoc 41 e)))
                   (cons 07 (cdr (assoc 02 (entget (cdr (assoc 340 e))))))
               )
       )
       (while (setq i (vl-string-search "\\P" s))
           (setq l (cons (substr s 1 i) l)
                 s (substr s (+ i 3))
           )
       )
       (setq l
           (vl-remove-if 'null
               (mapcar
                   (function
                       (lambda ( s / b )
                           (if (setq b (textbox (cons (cons 1 s) x)))
                               (mapcar '- (cadr b) (car b))
                           )
                       )
                   )
                   (cons s l)
               )
           )
       )
       (list
           (* 1.01 (apply 'max (mapcar 'car l)))
           (+ (apply '+ (mapcar 'cadr l)) (* 0.68 (1- (length l))))
       )
   )
   
   (if (setq s (ssget "_:L" '((0 . "MULTILEADER"))))
       (repeat (setq i (sslength s))
           (setq e (entget (ssname s (setq i (1- i))))
                 l (f e)
           )
           (entmod
               (subst (cons 43 (car l)) (assoc 43 e)
                   (subst (cons 44 (cadr l)) (assoc 44 e) e)
               )
           )
       )
   )
   (princ)
)

 

 

Link to comment
Share on other sites

This tip may or may not be relevant. You can minimize the boundaries of multitext by double-clicking on the margin jig. See picture with before and after.

 

multitexttip.png.68937857f5e58a4329ad63ccc6910349.png

Link to comment
Share on other sites

5 hours ago, SLW210 said:

If you clean up the extra formatting it should work.

 

;; Fit MLeader MText Frame  -  Lee Mac

(defun c:mlf ( / e f i l s )

   (defun f ( e / i l s x )
       (setq s (cdr (assoc 304 e))
             x (list
                   (cons 40 (cdr (assoc 41 e)))
                   (cons 07 (cdr (assoc 02 (entget (cdr (assoc 340 e))))))
               )
       )
       (while (setq i (vl-string-search "\\P" s))
           (setq l (cons (substr s 1 i) l)
                 s (substr s (+ i 3))
           )
       )
       (setq l
           (vl-remove-if 'null
               (mapcar
                   (function
                       (lambda ( s / b )
                           (if (setq b (textbox (cons (cons 1 s) x)))
                               (mapcar '- (cadr b) (car b))
                           )
                       )
                   )
                   (cons s l)
               )
           )
       )
       (list
           (* 1.01 (apply 'max (mapcar 'car l)))
           (+ (apply '+ (mapcar 'cadr l)) (* 0.68 (1- (length l))))
       )
   )
   
   (if (setq s (ssget "_:L" '((0 . "MULTILEADER"))))
       (repeat (setq i (sslength s))
           (setq e (entget (ssname s (setq i (1- i))))
                 l (f e)
           )
           (entmod
               (subst (cons 43 (car l)) (assoc 43 e)
                   (subst (cons 44 (cadr l)) (assoc 44 e) e)
               )
           )
       )
   )
   (princ)
)

 

 

Thank you SLW210, I thought I cleaned it up, but I must have missed a bit of it. That works!

Edited by mcweb
Link to comment
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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  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...