Author Topic: "Rotating" MLeader block content to horizontal  (Read 8020 times)

0 Members and 1 Guest are viewing this topic.

cadpoobah

  • Newt
  • Posts: 48
"Rotating" MLeader block content to horizontal
« on: January 03, 2018, 04:21:03 PM »
We have some drawings that have been rotated, along with all their MLeaders (some containing text, some containing blocks). These all need re-oriented to be horizontal again.

Fixing those with text is not a huge deal. It can be done manually via the Properties palette (there's a "Rotation" option). I was also able to write a function that will select all the MLeaders and change the rotation to 0 via the vla-put-TextRotation function.

The MLeaders with blocks is another issue, though. There is no similar vla- function that I've found. There is a DXF group code (46) that returns the block's rotation. Changing it "appears" to work, but if the grip-edit the leader afterward, it still acts as if the MLeader is rotated (the new landing goes haywire).

Ideally, I'd like to create a TOrient-style program that would work for MLeaders, rotating them to be horizontal. For that matter, I'd even be satisfied if the function deleted the existing MLeader and simply recreated it using the same points.

Any thoughts or suggestions would be appreciated!
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: "Rotating" MLeader block content to horizontal
« Reply #1 on: January 03, 2018, 04:50:02 PM »
How about using the ROTATE command / vla-rotate method to rotate the MLeader about its arrowhead point by the angle of the text rotation?

cadpoobah

  • Newt
  • Posts: 48
Re: "Rotating" MLeader block content to horizontal
« Reply #2 on: January 03, 2018, 05:33:26 PM »
That's a possibility, but the MLeader itself could potentially end up being rotated back over top of other geometry that it didn't overlap previously.

I'd rather the leader's basic geometry stay how it is and only the content (the block) be reoriented, similar to how changing the Rotation property in the palette only changes the text's orientation, leaving the leader geometry alone (except for the landing).
« Last Edit: January 04, 2018, 01:25:30 PM by cadpoobah »
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

ChrisCarlson

  • Guest
Re: "Rotating" MLeader block content to horizontal
« Reply #3 on: January 04, 2018, 12:51:48 PM »
Simple fix would be to simply have a vertical and horizontal version of the block tied to a mleader style. Then simply change the desired mleader style.

cadpoobah

  • Newt
  • Posts: 48
Re: "Rotating" MLeader block content to horizontal
« Reply #4 on: January 04, 2018, 01:24:11 PM »
Simple fix would be to simply have a vertical and horizontal version of the block tied to a mleader style. Then simply change the desired mleader style.

Yes, if things were only rotated in 90 deg increments. *sigh*
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

ChrisCarlson

  • Guest
Re: "Rotating" MLeader block content to horizontal
« Reply #5 on: January 05, 2018, 09:13:00 AM »
If your desire is to have 360° of rotation of full function within the mleader, I don't see that being possible.

cadpoobah

  • Newt
  • Posts: 48
Re: "Rotating" MLeader block content to horizontal
« Reply #6 on: January 05, 2018, 12:17:01 PM »
Not exactly, @Master_Shake. I'm not expecting "grip-edit" style functionality, where you can simply click on the MLeader's block and rotate it to any angle (although, that could be pretty handy!).

Rather, if geometry (including MLeaders) gets rotated, I would like a way to re-orient the MLeader content (whether text or block) to its proper, readable orientation (again, think TOrient). As mentioned, this is possible for MLeaders with text, but for for MLeaders with blocks, the only option is to delete and recreate it.
 

I just want functionality that is already possible with MLeaders containing text; via the TextRotation function. I guess expecting consistent behavior across all AutoCAD objects is a little too much to ask.  :tickedoff:

« Last Edit: January 05, 2018, 12:32:52 PM by cadpoobah »
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

ronjonp

  • Needs a day job
  • Posts: 7529
Re: "Rotating" MLeader block content to horizontal
« Reply #7 on: January 05, 2018, 12:22:56 PM »
Why is the drawing getting rotated? It seems that the "correct" way to do this is DVIEW TWIST ?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cadpoobah

  • Newt
  • Posts: 48
Re: "Rotating" MLeader block content to horizontal
« Reply #8 on: January 05, 2018, 12:31:48 PM »
Why is the drawing getting rotated? It seems that the "correct" way to do this is DVIEW TWIST ?

Agreed. More precisely, the geometry has been rotated, not the drawing.
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

ronjonp

  • Needs a day job
  • Posts: 7529
Re: "Rotating" MLeader block content to horizontal
« Reply #9 on: January 05, 2018, 12:50:10 PM »
Maybe post a drawing with before and after results.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cadpoobah

  • Newt
  • Posts: 48
Re: "Rotating" MLeader block content to horizontal
« Reply #10 on: January 05, 2018, 02:08:22 PM »
Maybe post a drawing with before and after results.

Posted. Shown (left) is an office layout in it's typical orientation. But it's not uncommon to need that layout oriented completely differently (right), requiring manual MLeader cleanup afterward.

Now, expand that cleanup effort to other areas of the drawing (potentially the entire drawing) and you get an idea of why a TOrient-style program would be extremely helpful.
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

ChrisCarlson

  • Guest

ronjonp

  • Needs a day job
  • Posts: 7529
Re: "Rotating" MLeader block content to horizontal
« Reply #12 on: January 05, 2018, 02:30:22 PM »
If this is always an issue, is there a possibility to change your leaders to have mtext content? Then this would be VERY easy :).

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cadpoobah

  • Newt
  • Posts: 48
Re: "Rotating" MLeader block content to horizontal
« Reply #13 on: January 05, 2018, 03:00:58 PM »
Some searching yield something that kind of works

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/block-mleader-rotate-an-existing-mleader/m-p/7665762/highlight/true#M363381

Yea, I'm tracking that thread as well. SonicSSV's solution is getting closer. Will definitely share a link if there are any breakthroughs.
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

cadpoobah

  • Newt
  • Posts: 48
Re: "Rotating" MLeader block content to horizontal
« Reply #14 on: January 05, 2018, 03:02:22 PM »
If this is always an issue, is there a possibility to change your leaders to have mtext content? Then this would be VERY easy :).

Agreed. Client wants their cute little ovals.  :hahanot:
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

ronjonp

  • Needs a day job
  • Posts: 7529
Re: "Rotating" MLeader block content to horizontal
« Reply #15 on: January 05, 2018, 03:06:18 PM »
Well it was worth a try :) . Seems like recreating the mleader would be the easiest for this then, but you'd still have some manual cleanup.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ChrisCarlson

  • Guest
Re: "Rotating" MLeader block content to horizontal
« Reply #16 on: January 05, 2018, 04:21:55 PM »
Could you make your static blocks into dynamic block with a text rotation and "fudge" the mleaders?

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: "Rotating" MLeader block content to horizontal
« Reply #17 on: January 05, 2018, 06:38:22 PM »
Well it was worth a try :) . Seems like recreating the mleader would be the easiest for this then, but you'd still have some manual cleanup.

I thought the same and decided to try that out. :)
And saw the few problems that occur (aside from the obvious manual cleanup):
  • Mleader that has no leaders - so basically reinserting a new block is required, but how to (re)match the scale?
  • Mleader with more than one leader - couldn't replicate the multiple leaders in the newly created one (see below the code what I tried, but removed in the end)
  • Other mleader that errors on the GetLeaderLineVertices method - no idea whats wrong
Heres the sloppy code as a starting point (try it on cadpoobah's dwg to see/understand the listed problems) :
Code - Auto/Visual Lisp: [Select]
  1. (defun C:test ( / MleaderBlockAtts doc spc SS i o n L )
  2.  
  3.   ; _$ (MleaderBlockAtts (vlax-ename->vla-object (car (entsel)))) -> (("EQNOMISC" 1060 "") ("EQNO" 1059 "N0802"))
  4.   (defun MleaderBlockAtts ( mld / id L )
  5.     (and
  6.       (eq 'VLA-OBJECT (type mld)) (member (vla-get-ObjectName mld) '("AcDbMLeader" "AcDbLeader"))
  7.       (eq (vla-get-ContentType mld) acBlockContent)
  8.       (vlax-for x (vla-Item (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object))) (vla-get-ContentBlockName mld))
  9.         (and
  10.           (eq (vla-get-ObjectName x) "AcDbAttributeDefinition") (setq id (vla-get-ObjectID x))
  11.           (setq L (cons (list (vla-get-TagString x) id (vla-GetBlockAttributeValue mld id)) L))
  12.         )
  13.       ); vlax-for
  14.     ); and
  15.     L
  16.   ); defun MleaderBlockAtts
  17.  
  18.   (and
  19.     (princ "\nSelect multileaders: ")
  20.     (setq SS (ssget "_:L-I" '((0 . "MULTILEADER"))))
  21.     (repeat (setq i (sslength SS))
  22.       (and
  23.         (setq o (vlax-ename->vla-object (ssname SS (setq i (1- i)))))
  24.         (setq n (vla-get-LeaderCount o))
  25.         (setq L (MleaderBlockAtts o))
  26.         (cond
  27.           ( (zerop n) ; Mleader that doesn't contains any leaders - lets create a block reference
  28.             (
  29.               (lambda ( / _dist _cen b atts att ll1 ll2 ur1 ur2 )
  30.                 (setq _dist (lambda (p1 p2) (apply 'distance (mapcar 'vlax-safearray->list (list p1 p2)))))
  31.                 (setq _cen (lambda ( pts ) (vlax-3D-point (apply 'mapcar (cons '(lambda (a b) (/ (+ a b) 2.)) (mapcar 'vlax-safearray->list pts))))))
  32.                 (vla-GetBoundingBox o 'll1 'ur1)
  33.                 (setq b (vlax-invoke spc 'InsertBlock '(0. 0. 0.) (vla-get-ContentBlockName o) 1 1 1 0.))
  34.                 (vla-GetBoundingBox b 'll2 'ur2)
  35.                 (vlax-invoke b 'ScaleEntity '(0. 0. 0.) (/ (_dist ll1 ur1) (_dist ll2 ur2))) ; <- THIS IS NOT CORRECT, I KNOW (but its close to the result)
  36.                 (vla-GetBoundingBox b 'll2 'ur2)
  37.                 (vla-Move b (_cen (list ll2 ur2)) (_cen (list ll1 ur1)))
  38.                 (setq atts (mapcar (function (lambda (x) (cons (vla-get-TagString x) x))) (vlax-invoke b 'GetAttributes)))
  39.                 (foreach x L
  40.                   (and
  41.                     (setq att (cdr (assoc (car x) atts)))
  42.                     (vla-put-TextString att (last x))
  43.                   )
  44.                 ); foreach
  45.                 (vla-put-Layer b (vla-get-Layer o))
  46.                 (vla-Delete o)
  47.               ); lambda
  48.             )
  49.           )
  50.           ( (>= n 1) ; Standard Mleader that contains 1+ leaders
  51.             (
  52.               (lambda ( / tmp new )
  53.                 (and
  54.                   (not (vl-catch-all-error-p (setq tmp (vl-catch-all-apply 'vla-GetLeaderLineVertices (list o 0)))))
  55.                   (setq new (vla-AddMLeader spc tmp 0))
  56.                   (progn
  57.                     (foreach x '(ArrowheadSize ArrowheadType ContentBlockName ContentType StyleName Layer LeaderType BlockConnectionType BlockScale)
  58.                       (vlax-put new x (vlax-get o x))
  59.                     ); foreach
  60.                     (foreach x L (apply 'vla-SetBlockAttributeValue (cons new (cdr x))) )
  61.                     (vla-Delete o)
  62.                   ); progn
  63.                 ); and
  64.               ); lambda
  65.             )
  66.           )
  67.         ); cond
  68.       ); and
  69.     ); repeat
  70.   ); and
  71.   (princ)
  72. ); defun

So this is what I tried to solve problem #2 - but it creates only one 'leader' for the multileader object:
Code - Auto/Visual Lisp: [Select]
  1.   (setq n (vla-get-LeaderCount o))
  2.   (not (vl-catch-all-error-p (setq tmp (vl-catch-all-apply 'vla-GetLeaderLineVertices (list o 0))))) ; 'tmp' - the initial safearray
  3.   (setq new (vla-AddMLeader spc tmp 0)) ; use 'tmp' to create the mleader (since its required)
  4.   (progn
  5.     (vla-RemoveLeader new 0) ; remove the only leader we added to the mleader, so we won't mess up the indexes
  6.     (repeat n
  7.       (setq n (1- n))
  8.       (setq tmp (vla-AddLeader new))
  9.       (vla-AddLeaderLine new tmp (vla-GetLeaderLineVertices o n))
  10.     ); repeat
  11.   ); progn
  12. ); and
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg