Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

BLOCK MLEADER ROTATE AN EXISTING MLEADER

16 REPLIES 16
SOLVED
Reply
Message 1 of 17
Anonymous
5152 Views, 16 Replies

BLOCK MLEADER ROTATE AN EXISTING MLEADER

Hi,

 

I've done a lot of searching on this but haven't been able to locate an answer as of yet.

 

I have a substantial number of existing block multileaders that require a change to their rotation.

 

When I set them up I set the UCS to the required angle prior to adding each one and they all worked great.

 

And then the layout's changed. Now I need to change the rotation of the block and the landing on a couple of hundred multileaders.

 

I am 99% sure this is going to require a lisp to modify the existing mleaders.

 

The existing multileaders....

  • Are contained in an xref and are referenced into multiple layouts => different rotations for different sheets depending on where they are.
  • Are on different layers within the xref.
  • The blocks contain attributes that have already been populated.
  • Some mleaders contain multiple arrowheads.

 

Does anyone have a way of selecting a group of multileaders and setting a new angle which would then be applied to those.

 

Thanks in advance.

 

Dave

Tags (3)
16 REPLIES 16
Message 2 of 17
imadHabash
in reply to: Anonymous

Hi and welcome to AutoDesk community,

 

some how by QSELECT command you can do it.

 

mleader.png




Message 3 of 17
john.vellek
in reply to: Anonymous

Hi dmosull1,

 

Welcome to the Autodesk Community!

 

This sounds like a laborious task so let's see if we can find a way to make it easier.  Is it possible to attach some sample files that show these file relationships and ucs issues? I would like to experiment with them in order to give you some suggestions.


John Vellek


Join the Autodesk Customer Council - Interact with developers, provide feedback on current and future software releases, and beta test the latest software!

Autodesk Knowledge Network | Autodesk Account | Product Feedback
Message 4 of 17
Anonymous
in reply to: john.vellek

Hi Guys,

 

Thanks for the responses.

 

Imad,

That assists in selecting the mleaders but doesn't allow me to rotate the block and landing as far as I can tell.

 

John,

Please find attached a simplified sample file as requested that illustrates the problem.

 

I would like to keep the arrowheads exactly where they are but rotate the multileader block portion plus the landing.

There will be mutiple orientations of these in the final xref file. The orientation will depend on which sheet they end up appearing in. (30+ sheets)

 

Multileaders have been sensational for me except for this current stumbling block of rotating to a different angle after they have been previously orientated.

 

 

Thanks for looking guys.

 

Regards

 

Dave

Message 5 of 17
john.vellek
in reply to: Anonymous

HI @Anonymous,

 

In playing with your sample, I tried making the blocks annotative so that they would rotate to the view but apparently this does not work with MultiLeaders.

 

I also tried exploding the Mleader and then redfining the block so that it is annotative and rotates to match the view and this seemed to work the best but does not address the leader part of the Mleader.

 

Capture.PNG

 

I suggest that to go further with this I can move this thread to the Customization forum.  I am thinking a lisp routine that can put it a new mleader (maybe on its own layer) to match the existing but with proper orientation might work. Please let me know if you would like me to move the thread for you.

 

Please select the Accept as Solution button if my post solves your issue or answers your question.


John Vellek


Join the Autodesk Customer Council - Interact with developers, provide feedback on current and future software releases, and beta test the latest software!

Autodesk Knowledge Network | Autodesk Account | Product Feedback
Message 6 of 17
Anonymous
in reply to: john.vellek

Hi John,

 

Yes please move it to that forum. 

 

I believe a lisp with some kind of entmod action is the way to go. I had a look but the complexity of the multi leader with block data structure is outside my skill set. 

 

Im sure the rotation is buried within each individual multileaders entity data somewhere. It just seems to be so well hidden. 

 

Thanks very much for looking into this. 

 

Regards

 

Dave

Message 7 of 17
Anonymous
in reply to: Anonymous

Ok ,

 

I've had a smidgen of success but there is more to go. Any tips greatly appreciated.

 

I found a dxf code for the block rotation. "46". With this little bit of code I could change the block rotation.

 

(Defun C:MLA (/)
 (Setq MLA_NEW_ANG 0)
 (Setq ed (entget (car (entsel))))
 (setq MLA_EXISTING_ANG (cdr (assoc 46 ed)))
 (Prompt "\nExisting Block Angle = ")
 (Prin1 MLA_EXISTING_ANG)
 (Prompt "\n")
 (setq ed (subst (cons 46 0.0) (assoc 46 ed) ed ))
 (entmod ed)
);end defun

But the leader landings are still in disarray. Especially if the leaders are off the right hand side of the block.

 

Before....

 

before.PNG

 

After....

 

After.PNG

 

I'm still looking but I cant seem to find what controls the "landing" for the leader lines.

 

Can anyone point me to what dxf codes control the glitch seen above.

 

Thanks

 

Dave 

Message 8 of 17
Anonymous
in reply to: Anonymous

I think i know what dxf codes require modifying. 

 

http://help.autodesk.com/view/ACD/2016/ENU/?guid=GUID-72D20B8C-0F5E-4993-BEB7-0FCF94F32BE0

 

 

46 - Block Content Rotation

111 - MLeader Plane X-Axis Direction

112 - MLeader Plane Y-Axis Direction

10 -  Last Leader Line Point ?

11 - Dogleg Vector ?

 

And this one is doing my head in.

 

47 - Block Transformation Matrix

 

There appear to be 16 of these pieces of data and I cant figure out what to do with them or how to change them.

 

 

Message 9 of 17
trevor.bird.au
in reply to: Anonymous

Hi Dave,

 

I hope the following program achieves the result you require.

It currently realigns the MText content and Block content of the MLeader to the current UCS.

The UCS (if set) needs to be in the same plane as the selected MLeaders.

Undesired results may occur on MLeaders that aren't in the same UCS plane.

 

I've only been able to test it on the examples you provide.

The realigned block content is upside down on some of the example MLeaders but I think it is unavoidable due to the setout geometry of the leader and the block content.

I would like to investigate this further and hopefully provide an update in the future to ensure MLeader content is realigned in a readable orientation.

 

I would also like to thank Lee Mac for providing the vector manipulation functions.

 

FYI: the 16 entries for DXF code 47 form a 4x4 matrix.

 

Regards,

Trevor 

 

;;  MLeadersAlign.lsp by Trevor Bird
;;
;;  2016-08-12

;;------------------------------------------------------------------------------
(defun c:mleadersalign
  (
    /

    BlockContentPosition_15
    BlockContentRotation_46
    BlockMatrix1
    BlockMatrix2
    BlockPlaneX:uv
    BlockPlaneY:uv
    BlockPlaneZ:uv

    ContentBasePosition_10
    ContextData_10
    ContextData_110
    ContextData_111
    ContextData_112
    ContextData_12
    ContextData_13
    ContextData_14
    ContextData_15
    ContextData_16
    ContextData_171
    ContextData_175
    ContextData_297
    ContextData_42
    ContextData_46
    ContextData_DXF
    ContextData_DXF_new

    DogLeg:uv

    Leader_10
    Leader_11
    Leader_40
    Leader_DXF_new
    list_47_new

    MULTILEADER_172
    MULTILEADER_DXF
    MULTILEADER_DXF_new
    MULTILEADER_ename

    ScalarDistance
    ScalarSign
    ssC
    ss_MULTILEADER
    sv_ucsxdir_wcs
    sv_ucsydir_wcs

    TextDirection_13
    TextLocation_12

    ucsxdir_angle
    ucsydir_angle
    ucszdir_wcs

    VectorsAngle
    VectorsVDP
    VectorX
    VectorY
    Vector:v
  )
  (setq ss_MULTILEADER (ssget (list '(0 . "MULTILEADER") (cons 410 (getvar 'CTAB)))))


  (cond
    ( (not ss_MULTILEADER)
      (princ "\nNo MLeaders selected.")
    );(not ss_MULTILEADER)


    (ss_MULTILEADER
      (setq sv_ucsxdir_wcs (getvar 'UCSXDIR)
            sv_ucsydir_wcs (getvar 'UCSYDIR)
            ucsxdir_angle  (atan (cadr sv_ucsxdir_wcs) (car sv_ucsxdir_wcs))
            ucsydir_angle  (atan (cadr sv_ucsydir_wcs) (car sv_ucsydir_wcs))
      );setq

      (setq ssC -1)

      (repeat (sslength ss_MULTILEADER)
        (setq MULTILEADER_ename   (ssname ss_MULTILEADER (setq ssC (1+ ssC)))
              MULTILEADER_DXF     (entget MULTILEADER_ename)
              MULTILEADER_DXF_new (reverse (cdr (member '(300 . "CONTEXT_DATA{") (reverse MULTILEADER_DXF))))
              MULTILEADER_DXF_new (append MULTILEADER_DXF_new (cdr (member '(301 . "}") MULTILEADER_DXF)))
              MULTILEADER_172     (cdr (assoc 172 MULTILEADER_DXF_new)) ; Content Type

              ContextData_DXF     (cdr (member '(300 . "CONTEXT_DATA{") MULTILEADER_DXF))
              ContextData_DXF     (reverse (cdr (member '(301 . "}") (reverse ContextData_DXF))))
              ContextData_10      (cdr (assoc 10  ContextData_DXF)) ; Content Base Position
              ContextData_110     (cdr (assoc 110 ContextData_DXF)) ; MLeader Plane Origin Point
              ContextData_111     (cdr (assoc 111 ContextData_DXF)) ; MLeader Plane X-Axis Direction
              ContextData_112     (cdr (assoc 112 ContextData_DXF)) ; MLeader Plane Y-Axis Direction
              ContextData_297     (cdr (assoc 297 ContextData_DXF)) ; MLeader Plane Normal Reversed
        );setq


        ;;  <!--  Leader
        (setq Leader_DXF_new      (cdr (member '(302 . "LEADER{") ContextData_DXF))
              Leader_DXF_new      (reverse (cdr (member '(303 . "}") (reverse Leader_DXF_new))))

              ContextData_DXF_new (reverse (cdr (member '(302 . "LEADER{") (reverse ContextData_DXF))))
              ContextData_DXF_new (append ContextData_DXF_new (cdr (member '(303 . "}") ContextData_DXF)))

              Leader_10           (cdr (assoc 10 Leader_DXF_new)) ; Last Leader Line Point
              Leader_11           (cdr (assoc 11 Leader_DXF_new)) ; Dogleg Vector
              Leader_40           (cdr (assoc 40 Leader_DXF_new)) ; Dogleg Length
              DogLeg:uv           Leader_11
        );setq
        ;;  Leader -->


        ;;  <!--  Content Type
        (cond
          ( (= MULTILEADER_172 acMTextContent)
            (setq ContextData_12  (cdr (assoc 12  ContextData_DXF)) ; Text Location
                  ContextData_13  (cdr (assoc 13  ContextData_DXF)) ; Text Direction
                  ContextData_42  (cdr (assoc 42  ContextData_DXF)) ; Text Rotation
                  ContextData_171 (cdr (assoc 171 ContextData_DXF)) ; Text Attachment
                  ContextData_175 (cdr (assoc 175 ContextData_DXF)) ; Text Alignment Type
            );setq

            ;;  Determine new Dog Leg direction:
            (if (minusp (leemac:vxv Leader_11 sv_ucsxdir_wcs))
              (setq ScalarSign -1.0)
              (setq ScalarSign 1.0)
            );if

            (setq DogLeg:uv      (leemac:vxs sv_ucsxdir_wcs ScalarSign)
                  Leader_DXF_new (subst (cons 11 DogLeg:uv) (assoc 11 Leader_DXF_new) Leader_DXF_new)
            );setq


            ;;  Reset Text Location:
            (setq Vector:v            (mapcar '- ContextData_12 Leader_10)
                  VectorsVDP          (leemac:vxv (leemac:unit Vector:v) Leader_11)
                  VectorsAngle        (* ScalarSign (leemac:acos VectorsVDP))
                  ScalarDistance      (distance Leader_10 ContextData_12)
                  VectorX             (- (* (car DogLeg:uv) (cos VectorsAngle)) (* (cadr DogLeg:uv) (sin VectorsAngle)))
                  VectorY             (+ (* (cadr DogLeg:uv) (cos VectorsAngle)) (* (car DogLeg:uv) (sin VectorsAngle)))
                  TextLocation_12     (mapcar '+ Leader_10 (leemac:vxs (list VectorX VectorY 0.0) ScalarDistance))
                  TextDirection_13    sv_ucsxdir_wcs
                  ContextData_DXF_new (subst (cons 12 TextLocation_12) (assoc 12 ContextData_DXF_new) ContextData_DXF_new)
                  ContextData_DXF_new (subst (cons 13 TextDirection_13) (assoc 13 ContextData_DXF_new) ContextData_DXF_new)
            );setq

            ;;  Reset Content Base Postion:
            (setq Vector:v               (mapcar '- ContextData_10 Leader_10)
                  VectorsVDP             (leemac:vxv (leemac:unit Vector:v) Leader_11)
                  VectorsAngle           (* ScalarSign (leemac:acos VectorsVDP))
                  ScalarDistance         (distance Leader_10 ContextData_10)
                  VectorX                (- (* (car DogLeg:uv) (cos VectorsAngle)) (* (cadr DogLeg:uv) (sin VectorsAngle)))
                  VectorY                (+ (* (cadr DogLeg:uv) (cos VectorsAngle)) (* (car DogLeg:uv) (sin VectorsAngle)))
                  ContentBasePosition_10 (mapcar '+ Leader_10 (leemac:vxs (list VectorX VectorY 0.0) ScalarDistance))
                  ContextData_DXF_new    (subst (cons 10 ContentBasePosition_10) (assoc 10 ContextData_DXF_new) ContextData_DXF_new)
            );setq
          );(= MULTILEADER_172 acMTextContent)




          ( (= MULTILEADER_172 acBlockContent)
            (setq ContextData_14 (cdr (assoc 14 ContextData_DXF)) ; Block Content Normal Direction
                  ContextData_15 (cdr (assoc 15 ContextData_DXF)) ; Block Content Position
                  ContextData_16 (cdr (assoc 16 ContextData_DXF)) ; Block Content Scale
                  ContextData_46 (cdr (assoc 46 ContextData_DXF)) ; Block Content Rotation
            );setq

            ;;  Block Content Axes in UCS:
            (setq ucszdir_wcs    (leemac:v^v sv_ucsxdir_wcs sv_ucsydir_wcs)
                  BlockPlaneX:uv (mapcar '* ContextData_16 sv_ucsxdir_wcs)
                  BlockPlaneY:uv (mapcar '* ContextData_16 sv_ucsydir_wcs)
                  BlockPlaneZ:uv (mapcar '* ContextData_16 ucszdir_wcs)
            );setq

            ;;  Determine new Dog Leg direction:
            (setq Vector:v (mapcar '- ContextData_15 Leader_10))

            (if (minusp (leemac:vxv (leemac:unit Vector:v) sv_ucsxdir_wcs))
              (setq ScalarSign -1.0)
              (setq ScalarSign 1.0)
            );if

            (setq DogLeg:uv      (leemac:vxs sv_ucsxdir_wcs ScalarSign)
                  Leader_DXF_new (subst (cons 11 DogLeg:uv) (assoc 11 Leader_DXF_new) Leader_DXF_new)
            );setq


            ;;  Determine new Block Content Rotation:
            (cond
              ( (and  (> ContextData_46 ucsydir_angle)
                      (< ContextData_46 (+ ucsydir_angle pi))
                );and
                (setq BlockContentRotation_46 ucsxdir_angle
                      ScalarDistance          Leader_40
                );setq
              )

              (ContextData_46
                (setq BlockContentRotation_46 ucsxdir_angle
                      ScalarDistance          (distance Leader_10 ContextData_15)
                );setq
              );ContextData_46
            );cond

            (setq ContextData_DXF_new (subst (cons 46 BlockContentRotation_46) (assoc 46 ContextData_DXF_new) ContextData_DXF_new))


            ;;  Determine new Block Content Position:
            (setq BlockContentPosition_15 (mapcar '+ Leader_10 (leemac:vxs DogLeg:uv ScalarDistance))
                  ContextData_DXF_new     (subst (cons 15 BlockContentPosition_15) (assoc 15 ContextData_DXF_new) ContextData_DXF_new)
            );setq


            ;;  Reconstruct Block Content Matrix:
            (setq BlockMatrix1
              (list
                (append BlockPlaneX:uv '(0.0))
                (append BlockPlaneY:uv '(0.0))
                (append BlockPlaneZ:uv '(0.0))
                (append BlockContentPosition_15 '(1.0))
              );list

                  BlockMatrix2        (apply 'mapcar (cons 'list BlockMatrix1))
                  list_47_new         (apply 'append BlockMatrix2)
                  list_47_new         (mapcar '(lambda (x) (cons 47 x)) list_47_new)
                  ContextData_DXF_new (vl-remove-if '(lambda (_dp) (= (car _dp) 47)) ContextData_DXF_new)
                  ContextData_DXF_new (append ContextData_DXF_new list_47_new)
            );setq
          );(= MULTILEADER_172 acBlockContent)
        );cond
        ;;  Content Type  -->




        ;;  Reconstruct MULTILEADER_DXF_new:
        (setq Leader_DXF_new      (cons '(302 . "LEADER{") Leader_DXF_new)
              Leader_DXF_new      (reverse (cons '(303 . "}") (reverse Leader_DXF_new)))

              ContextData_DXF_new (append ContextData_DXF_new Leader_DXF_new)
              ContextData_DXF_new (cons '(300 . "CONTEXT_DATA{") ContextData_DXF_new)
              ContextData_DXF_new (reverse (cons '(301 . "}") (reverse ContextData_DXF_new)))
        );setq


        (setq MULTILEADER_DXF_new
          (append MULTILEADER_DXF_new
            ContextData_DXF_new
          );append
        );setq

        (entmod MULTILEADER_DXF_new)
        (entupd MULTILEADER_ename)
      );repeat (sslength ss_MULTILEADER)
    );ss_MULTILEADER
  );cond


  (princ)
);c:mleadersalign




;;------------------------------------------------------------------------------
;; Vector Norm - Lee Mac
;; Args: v - vector in R^n

(defun leemac:norm ( v )
  (sqrt (apply '+ (mapcar '* v v)))
)


;; Vector x Scalar - Lee Mac
;; Args: v - vector in R^n, s - real scalar

(defun leemac:vxs ( v s )
  (mapcar '(lambda ( n ) (* n s)) v)
)


;; Unit Vector - Lee Mac
;; Args: v - vector in R^n

(defun leemac:unit ( v )
  ( (lambda ( n ) (if (equal 0.0 n 1e-14) nil (leemac:vxs v (/ 1.0 n)))) (leemac:norm v))
)


;; Vector Cross Product - Lee Mac
;; Args: u,v - vectors in R^3

(defun leemac:v^v ( u v )
  (list
    (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
    (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
    (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
  )
)


;; Vector Dot Product  -  Lee Mac
;; Args: u,v - vectors in R^n

(defun leemac:vxv ( u v )
    (apply '+ (mapcar '* u v))
)


;; ArcCosine  -  Lee Mac
;; Args: -1 <= x <= 1

(defun leemac:acos ( x )
    (if (<= -1.0 x 1.0)
        (atan (sqrt (- 1.0 (* x x))) x)
    )
)




;;------------------------------------------------------------------------------
(princ "\nMLeadersAlign loaded. Start command with MLEADERSALIGN.")
(princ)

 

Tags (2)
Message 10 of 17
Anonymous
in reply to: trevor.bird.au

Hi Trevor,

That is awesome thanks very much. I had a quick play on my laptop but will try at work on Monday on the actual xref. I'll let you know how that goes.

It works on most of the multileaders I tested it on, and like you said there are one or two that end up upside down. But this is a great time saver for me. I'm also going to try get my head around that code. See if I can learn something 😉

THANKS !

Dave
Message 11 of 17
trevor.bird.au
in reply to: Anonymous

Hi Dave,

 

After some more testing I've updated this program.

 

The issue with upside down MLeader content was not related to the geometry of the MLeader and is resolved now by correctly redefining the MLeader plane X and Y axes that are saved with the MLeader object.

 

There is an issue with MLeaders that have been mirrored and I am still investigating.

 

I also found an issue with scaled MLeaders in that the scale factor is not applied and saved to the DXF codes that seem to be used for storing scale information.

For MLeaders with block content I've assumed (rightly or wrongly) that the Content Scale (Context Data Group code 40) should equal the Block Content Scale factor (Context Data Group code 16) which is actually a list of scale factors (X, Y and Z).

MText content does not seem to save any scaling information about itself and seems to be controlled by Context Data Group code 40 which does not update if the MLeader is scaled.

Again, still investigating Smiley Happy

 

 

Regards,

Trevor

 

;;  MLeaderContentAlign.lsp by Trevor Bird
;;
;;  2016-08-12

;;------------------------------------------------------------------------------
(defun c:mleadercontentalign
  (
    /

    BlockContentPosition_15
    BlockContentRotation_46
    BlockPlaneX:v_new
    BlockPlaneY:v_new
    BlockPlaneZ:v_new
    BlockRotation:uv

    ContentBasePosition_10
    ContextData_10
    ContextData_110
    ContextData_111
    ContextData_112
    ContextData_12
    ContextData_13
    ContextData_14
    ContextData_15
    ContextData_16
    ContextData_16_new
    ContextData_171
    ContextData_175
    ContextData_297
    ContextData_40
    ContextData_40_new
    ContextData_42
    ContextData_46
    ContextData_DXF
    ContextData_DXF_copy
    ContextData_DXF_new

    DogLeg:uv
    dp

    flag_ContextData
    flag_while

    LeaderControl_10
    LeaderControl_11
    LeaderControl_40
    LeaderControl_DXF
    Leaders_DXF
    Leaders_DXF_copy
    Leaders_DXF_new
    Leader_10
    Leader_10_new
    Leader_11
    Leader_11_new
    Leader_DXF
    Leader_DXF_new
    list_47
    list_47_copy
    list_47_new
    list_Leaders
    list_Leaders_copy
    list_Leaders_new
    list_vector

    member_list
    MULTILEADER_172
    MULTILEADER_DXF
    MULTILEADER_DXF_new
    MULTILEADER_ename

    m:Block2_list
    m:BlockNew1_list
    m:BlockNew2_list

    ScalarDistance
    ScalarSign
    ssC
    ss_MULTILEADER
    sv_ucsxdir_wcs
    sv_ucsydir_wcs

    TextDirection_13
    TextLocation_12

    ucsxdir_angle
    ucsydir_angle
    ucszdir_wcs

    Vector:uv
    Vector:v
    VectorsAngle
    VectorsVDP
    VectorX
    VectorY
  )
  (setq ss_MULTILEADER (ssget ":L" (list '(0 . "MULTILEADER") (cons 410 (getvar 'CTAB)))))


  (cond
    ( (not ss_MULTILEADER)
      (princ "\nNo MLeaders selected.")
    );(not ss_MULTILEADER)


    (ss_MULTILEADER
      (setq sv_ucsxdir_wcs  (getvar 'UCSXDIR)
            sv_ucsydir_wcs  (getvar 'UCSYDIR)
            ucsxdir_angle   (atan (cadr sv_ucsxdir_wcs) (car sv_ucsxdir_wcs))
            ucsydir_angle   (atan (cadr sv_ucsydir_wcs) (car sv_ucsydir_wcs))
      );setq


      (setq ssC -1)

      (repeat (sslength ss_MULTILEADER)
        (setq MULTILEADER_ename   (ssname ss_MULTILEADER (setq ssC  (1+ ssC)))
              MULTILEADER_DXF     (entget MULTILEADER_ename)
              MULTILEADER_DXF_new (reverse (cdr (member '(300 . "CONTEXT_DATA{") (reverse MULTILEADER_DXF))))
              MULTILEADER_DXF_new (append MULTILEADER_DXF_new (cdr (member '(301 . "}") MULTILEADER_DXF)))
              MULTILEADER_172     (cdr (assoc 172 MULTILEADER_DXF_new)) ; Content Type

              ContextData_DXF     (cdr (member '(300 . "CONTEXT_DATA{") MULTILEADER_DXF))
              ContextData_DXF     (reverse (cdr (member '(301 . "}") (reverse ContextData_DXF))))
              ContextData_10      (cdr (assoc 10 ContextData_DXF))    ; Content Base Position
              ContextData_40      (cdr (assoc 40 ContextData_DXF))    ; Content Scale
              ContextData_110     (cdr (assoc 110 ContextData_DXF))   ; MLeader Plane Origin Point
              ContextData_111     (cdr (assoc 111 ContextData_DXF))   ; MLeader Plane X-Axis Direction
              ContextData_112     (cdr (assoc 112 ContextData_DXF))   ; MLeader Plane Y-Axis Direction
              ContextData_297     (cdr (assoc 297 ContextData_DXF))   ; MLeader Plane Normal Reversed
        );setq


        ;;  <!--  ContextData
        ;;  Reconstruct ContextData_DXF without LEADER data:
        (setq ContextData_DXF_copy  ContextData_DXF
              ContextData_DXF_new   nil
              Leaders_DXF           nil
              flag_while            T
              flag_ContextData      T
        );setq

        (while flag_while
          (setq dp                    (car ContextData_DXF_copy)
                ContextData_DXF_copy  (cdr ContextData_DXF_copy)
          );setq

          (cond
            ( (equal dp '(302 . "LEADER{"))
              (setq Leaders_DXF       (append Leaders_DXF (list dp))
                    flag_ContextData  nil
              );setq
            );(equal dp '(302 . "LEADER{"))

            ( (equal dp '(303 . "}"))
              (setq Leaders_DXF       (append Leaders_DXF (list dp))
                    flag_ContextData  T
              );setq
            );(equal dp '(303 . "}"))


            ( (not flag_ContextData)
              (setq Leaders_DXF (append Leaders_DXF (list dp)))
            );(not flag_ContextData)

            (flag_ContextData
              (setq ContextData_DXF_new (append ContextData_DXF_new (list dp)))
            );flag_ContextData
          );cond


          (if (not ContextData_DXF_copy)
            (setq flag_while  nil)
          );if
        );while flag_while
        ;;  ContextData -->




        ;;  <!--  Leaders
        (setq Leaders_DXF_copy  Leaders_DXF
              list_Leaders      nil
              LeaderControl_DXF nil
              flag_while        T
        );setq

        (while flag_while
          (setq member_list (member '(302 . "LEADER{") Leaders_DXF_copy))

          (cond
            ( (not member_list)
              (setq flag_while  nil)
            );(not member_list)

            (member_list
              (setq Leaders_DXF_copy  (cdr (member '(303 . "}") member_list))
                    Leader_DXF        nil
              );setq

              (while member_list
                (setq dp          (car member_list)
                      member_list (cdr member_list)
                      Leader_DXF  (append Leader_DXF (list dp))
                );setq

                (if (equal dp '(303 . "}"))
                  (setq member_list nil)
                );if
              );while member_list

              (cond
                ( (not LeaderControl_DXF)
                  ;;  Assume "Last Leader Line Point" of first leader in multileader is control point:
                  (setq LeaderControl_DXF Leader_DXF)
                );(not LeaderControl_DXF)

                (LeaderControl_DXF
                  (setq list_Leaders  (append list_Leaders (list Leader_DXF)))
                );LeaderControl_DXF
              );cond
            );member_list
          );cond
        );while flag_while



        (setq LeaderControl_10    (cdr (assoc 10  LeaderControl_DXF)) ; Last Leader Line Point
              LeaderControl_11    (cdr (assoc 11  LeaderControl_DXF)) ; Dogleg Vector
              LeaderControl_40    (cdr (assoc 40  LeaderControl_DXF)) ; Dogleg Length
              DogLeg:uv           LeaderControl_11
        );setq
        ;;  Leaders -->




        ;;  <!--  Content Type
        (cond
          ( (= MULTILEADER_172 acMTextContent)
            (setq ContextData_12  (cdr (assoc 12  ContextData_DXF))   ; Text Location
                  ContextData_13  (cdr (assoc 13  ContextData_DXF))   ; Text Direction
                  ContextData_42  (cdr (assoc 42  ContextData_DXF))   ; Text Rotation
                  ContextData_171 (cdr (assoc 171  ContextData_DXF))  ; Text Attachment
                  ContextData_175 (cdr (assoc 175  ContextData_DXF))  ; Text Alignment Type
            );setq

            (if (minusp (leemac:vxv LeaderControl_11 sv_ucsxdir_wcs))
              (setq ScalarSign  -1.0)
              (setq ScalarSign  1.0)
            );if

            (setq DogLeg:uv         (leemac:vxs sv_ucsxdir_wcs ScalarSign)
                  LeaderControl_DXF (subst (cons 11 DogLeg:uv) (assoc 11 LeaderControl_DXF) LeaderControl_DXF)

                  ;;  Reset Text Location:
                  Vector:v        (mapcar '- ContextData_12 LeaderControl_10)
                  Vector:uv       (leemac:unit Vector:v)
                  VectorsVDP      (leemac:vxv Vector:uv LeaderControl_11)
                  VectorsAngle    (leemac:acos VectorsVDP)
                  VectorsAngle    (* ScalarSign VectorsAngle)
                  ScalarDistance  (distance LeaderControl_10 ContextData_12)

                  ;;  2D Vector Rotation:
                  VectorX             (- (* (car DogLeg:uv) (cos VectorsAngle)) (* (cadr DogLeg:uv) (sin VectorsAngle)))
                  VectorY             (+ (* (cadr DogLeg:uv) (cos VectorsAngle)) (* (car DogLeg:uv) (sin VectorsAngle)))

                  TextLocation_12     (mapcar '+ LeaderControl_10 (leemac:vxs (list VectorX VectorY 0.0) ScalarDistance))
                  TextDirection_13    sv_ucsxdir_wcs
                  ContextData_DXF_new (subst (cons 12 TextLocation_12) (assoc 12 ContextData_DXF_new) ContextData_DXF_new)
                  ContextData_DXF_new (subst (cons 13 TextDirection_13) (assoc 13 ContextData_DXF_new) ContextData_DXF_new)
            );setq


            ;;  <!--  Reset Content Base Postion:
            (setq Vector:v        (mapcar '- ContextData_10 LeaderControl_10)
                  Vector:uv       (leemac:unit Vector:v)
                  VectorsVDP      (leemac:vxv Vector:uv LeaderControl_11)
                  VectorsAngle    (leemac:acos VectorsVDP)
                  VectorsAngle    (* ScalarSign VectorsAngle)
                  ScalarDistance  (distance LeaderControl_10 ContextData_10)

                  ;;  2D Vector Rotation:
                  VectorX                 (- (* (car DogLeg:uv) (cos VectorsAngle)) (* (cadr DogLeg:uv) (sin VectorsAngle)))
                  VectorY                 (+ (* (cadr DogLeg:uv) (cos VectorsAngle)) (* (car DogLeg:uv) (sin VectorsAngle)))

                  ContentBasePosition_10  (mapcar '+ LeaderControl_10 (leemac:vxs (list VectorX VectorY 0.0) ScalarDistance))
                  ContextData_DXF_new     (subst (cons 10 ContentBasePosition_10) (assoc 10 ContextData_DXF_new) ContextData_DXF_new)
            );setq
						;;  Reset Content Base Postion	-->
          );(= MULTILEADER_172 acMTextContent)








          ( (= MULTILEADER_172 acBlockContent)
            (setq ContextData_14  (cdr (assoc 14  ContextData_DXF))   ; Block Content Normal Direction
                  ContextData_15  (cdr (assoc 15  ContextData_DXF))   ; Block Content Position
                  ContextData_16  (cdr (assoc 16  ContextData_DXF))   ; Block Content Scale
                  ContextData_46  (cdr (assoc 46  ContextData_DXF))   ; Block Content Rotation

                  ContextData_16_new  (mapcar 'abs ContextData_16)

                  ;;  Reset Content Scale
                  ContextData_40_new  (car ContextData_16_new)
                  ContextData_DXF_new (subst (cons 40 ContextData_40_new) (assoc 40 ContextData_DXF_new) ContextData_DXF_new)
            );setq


            ;;  Block Content Axes in UCS:
            (setq ucszdir_wcs       (leemac:v^v sv_ucsxdir_wcs sv_ucsydir_wcs)
                  BlockPlaneX:v_new (mapcar '* ContextData_16_new sv_ucsxdir_wcs)
                  BlockPlaneY:v_new (mapcar '* ContextData_16_new sv_ucsydir_wcs)
                  BlockPlaneZ:v_new (mapcar '* ContextData_16_new ucszdir_wcs)
            );setq

            ;;  Determine new Dog Leg direction:
            (setq Vector:v  (mapcar '- ContextData_15 LeaderControl_10)
                  Vector:uv (leemac:unit Vector:v)
            );setq

            (if (minusp (leemac:vxv Vector:uv sv_ucsxdir_wcs))
              (setq ScalarSign  -1.0)
              (setq ScalarSign  1.0)
            );if

            (setq DogLeg:uv         (leemac:vxs sv_ucsxdir_wcs ScalarSign)
                  LeaderControl_DXF (subst (cons 11 DogLeg:uv) (assoc 11 LeaderControl_DXF) LeaderControl_DXF)
            );setq


            ;;  Determine new Block Content Rotation:
            (cond
              ( (and  (> ContextData_46 ucsydir_angle)
                      (< ContextData_46 (+ ucsydir_angle pi))
                );and
                (setq BlockContentRotation_46 ucsxdir_angle
                      ScalarDistance          LeaderControl_40
                );setq
              )

              (ContextData_46
                (setq BlockContentRotation_46 ucsxdir_angle
                      ScalarDistance          (distance LeaderControl_10 ContextData_15)
                );setq
              );ContextData_46
            );cond

            (setq ContextData_DXF_new (subst (cons 46 BlockContentRotation_46) (assoc 46 ContextData_DXF_new) ContextData_DXF_new))

            ;;  Define block rotation as a vector:
            (setq BlockRotation:uv  (list (cos BlockContentRotation_46) (sin BlockContentRotation_46) 0.0))

            ;;  <!--  Determine new Block Content Position:
            (setq BlockContentPosition_15 (mapcar '+ LeaderControl_10 (leemac:vxs DogLeg:uv ScalarDistance))
                  ContextData_DXF_new     (subst (cons 15 BlockContentPosition_15) (assoc 15 ContextData_DXF_new) ContextData_DXF_new)
            );setq
            ;;  Determine new Block Content Position: -->




            ;;  <!--  Block Transformation Matrix
            (setq list_47 (vl-remove-if-not '(lambda (_dp) (= (car _dp) 47)) ContextData_DXF_new)
                  list_47 (mapcar 'cdr list_47)
            );setq


            (setq m:Block2_list nil
                  list_47_copy  list_47
            );setq

            (while list_47_copy
              (setq list_vector nil)

              (repeat 4
                (setq list_vector   (append list_vector (list (car list_47_copy)))
                      list_47_copy  (cdr list_47_copy)
                );setq
              );repeat 4

              (setq m:Block2_list (append m:Block2_list (list list_vector)))
            );while list_47_copy
            ;;  Block Transformation Matrix -->




            ;;  <!--  Reconstruct Block Content Matrix (includes scaling):
            (setq m:BlockNew1_list
              (list
                (append BlockPlaneX:v_new '(0.0))
                (append BlockPlaneY:v_new '(0.0))
                (append BlockPlaneZ:v_new '(0.0))
                (append BlockContentPosition_15 '(1.0))
              );list

                  m:BlockNew2_list  (apply 'mapcar (cons 'list m:BlockNew1_list))
            );setq
            ;;  Reconstruct Block Content Matrix  -->


            (setq list_47_new         (apply 'append m:BlockNew2_list)
                  list_47_new         (mapcar '(lambda (_x) (cons 47 _x)) list_47_new)

                  ContextData_DXF_new (vl-remove-if '(lambda (_dp) (= (car _dp) 47)) ContextData_DXF_new)
                  ContextData_DXF_new (append ContextData_DXF_new list_47_new)
            );setq
            ;;  Reconstruct Block Content Matrix (includes scaling) -->




            ;;  <!--  Reset Content Base Postion:
            ;;  Compare block rotation with block plane axis X.
            (if (minusp (leemac:vxv (leemac:unit BlockPlaneX:v_new) DogLeg:uv))
              (setq ScalarSign      -1.0
                    ScalarDistance  (distance LeaderControl_10 ContextData_10)
              );setq
              (setq ScalarSign      1.0
                    ScalarDistance  LeaderControl_40
              );setq
            );if

            (setq ContentBasePosition_10  (mapcar '+ LeaderControl_10 (leemac:vxs DogLeg:uv (* ScalarDistance 1.0)))
                  ContextData_DXF_new     (subst (cons 10 ContentBasePosition_10) (assoc 10 ContextData_DXF_new) ContextData_DXF_new)
            );setq
            ;;  Reset Content Base Postion  -->
          );(= MULTILEADER_172 acBlockContent)
        );cond
        ;;  Content Type  -->








        ;;  <!--  Reset MLeader Plane X-Axis and Y-Axis Directions:
        (setq Vector:v        (mapcar '- ContextData_110 LeaderControl_10)
              Vector:uv       (leemac:unit Vector:v)
              VectorsVDP      (leemac:vxv Vector:uv LeaderControl_11)
              VectorsAngle    (leemac:acos VectorsVDP)
              ScalarDistance  (distance LeaderControl_10 ContextData_110)

              ;;  2D Vector Rotation:
              VectorX             (- (* (car DogLeg:uv) (cos VectorsAngle)) (* (cadr DogLeg:uv) (sin VectorsAngle)))
              VectorY             (+ (* (cadr DogLeg:uv) (cos VectorsAngle)) (* (car DogLeg:uv) (sin VectorsAngle)))

              ContextData_DXF_new (subst (cons 111 sv_ucsxdir_wcs) (assoc 111 ContextData_DXF_new) ContextData_DXF_new)
              ContextData_DXF_new (subst (cons 112 sv_ucsydir_wcs) (assoc 112 ContextData_DXF_new) ContextData_DXF_new)
        );setq
        ;;  Reset MLeader Plane X-Axis and Y-Axis Directions  -->




        ;;  <!--  Reconstruct MLeader
        (setq list_Leaders_new  nil
              list_Leaders_copy list_Leaders
        );setq

        ;;  Recalculate Leader_10 from LeaderControl_10 and DogLeg:uv for other leaders:
        (while list_Leaders_copy
          (setq Leader_DXF  (car list_Leaders_copy)
                Leader_10   (cdr (assoc 10 Leader_DXF)) ; Last Leader Line Point
                Leader_11   (cdr (assoc 11 Leader_DXF)) ; Dogleg Vector
          );setq


          (if (minusp (leemac:vxv Leader_11 LeaderControl_11))
            (setq ScalarSign  -1.0)
            (setq ScalarSign  1.0)
          );if

          (setq Leader_11_new     (leemac:vxs  DogLeg:uv   ScalarSign)

                ScalarDistance    (distance Leader_10 LeaderControl_10)
                Leader_10_new     (mapcar '+ LeaderControl_10 (leemac:vxs DogLeg:uv ScalarDistance))
                Leader_DXF_new    Leader_DXF
                Leader_DXF_new    (subst (cons 11 Leader_11_new) (assoc 11 Leader_DXF_new) Leader_DXF_new)
                Leader_DXF_new    (subst (cons 10 Leader_10_new) (assoc 10 Leader_DXF_new) Leader_DXF_new)
                list_Leaders_new  (append list_Leaders_new (list Leader_DXF_new))
                list_Leaders_copy (cdr list_Leaders_copy)
          );setq
        );while list_Leaders_copy


        (setq list_Leaders        (cons LeaderControl_DXF list_Leaders_new)
              Leaders_DXF_new     (apply 'append list_Leaders)

              ContextData_DXF_new (append ContextData_DXF_new Leaders_DXF_new)
              ContextData_DXF_new (cons '(300 . "CONTEXT_DATA{") ContextData_DXF_new)
              ContextData_DXF_new (reverse (cons '(301 . "}") (reverse ContextData_DXF_new)))
        );setq


        (setq MULTILEADER_DXF_new
          (append MULTILEADER_DXF_new
            ContextData_DXF_new
          );append
        );setq
        (entmod MULTILEADER_DXF_new)
        (entupd MULTILEADER_ename)
				;;	Reconstruct MLeader	-->
      );repeat (sslength ss_MULTILEADER)
    );ss_MULTILEADER
  );cond


  (princ)
);c:mleadercontentalign




;;------------------------------------------------------------------------------
;; Vector Norm - Lee Mac
;; Args: v - vector in R^n

(defun leemac:norm ( v )
  (sqrt (apply '+ (mapcar '* v v)))
)


;; Vector x Scalar - Lee Mac
;; Args: v - vector in R^n, s - real scalar

(defun leemac:vxs ( v s )
  (mapcar '(lambda ( n ) (* n s)) v)
)


;; Unit Vector - Lee Mac
;; Args: v - vector in R^n

(defun leemac:unit ( v )
  ( (lambda ( n ) (if (equal 0.0 n 1e-14) nil (leemac:vxs v (/ 1.0 n)))) (leemac:norm v))
)


;; Vector Cross Product - Lee Mac
;; Args: u,v - vectors in R^3

(defun leemac:v^v ( u v )
  (list
    (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
    (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
    (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
  )
)


;; Vector Dot Product  -  Lee Mac
;; Args: u,v - vectors in R^n

(defun leemac:vxv ( u v )
    (apply '+ (mapcar '* u v))
)


;; ArcCosine  -  Lee Mac
;; Args: -1 <= x <= 1

(defun leemac:acos ( x )
    (if (<= -1.0 x 1.0)
        (atan (sqrt (- 1.0 (* x x))) x)
    )
)




;;------------------------------------------------------------------------------
(princ "\nMLeaderContentAlign loaded. Start command with MLEADERCONTENTALIGN.")
(princ)

 

Tags (1)
Message 12 of 17

EDIT to posted code.

 

Replace:

(setq ss_MULTILEADER (ssget ":L" (list '(0 . "MULTILEADER") (cons 410 (getvar 'CTAB)))))

 

 

With:

  (setq ss_Filter '((0 . "MULTILEADER")))

  (if (= (getvar 'CVPORT) 1)
    (setq ss_Filter (append ss_Filter (list (cons 410 (getvar 'CTAB)))))
    (setq ss_Filter (append ss_Filter '((410 . "Model"))))
  );if

  (setq ss_MULTILEADER  (ssget ":L" ss_Filter))

 

 

Original code will not allow selection of MLeaders inside a paperspace viewport.

Message 13 of 17
clindner
in reply to: trevor.bird.au

@trevor.bird.au,

 

This is a handy routine! Nice work. Thanks for sharing!

 

We have an issue that I'd like to have you take a look at. In the example below, the original leaders are at the bottom, the "fixed" ones (via MLEADERCONTENTALIGN) are at the top. It only seems to happen on MLeaders in which the leader is I've attached a drawing file for you to experiment with if you are so inclined.
Screenshot_2017.12.07_16h13m45s_002_.jpg

 

In reviewing the DXF info of each original MLeader, the only thing I see different (other than the obvious coordinates, etc.) is the first Group 90 code.

The MLeader that flipped correctly (A0202), was (90 . 0). The other (C1801) was (90 . 1). 

 

Would love to have a fix for this.

 

Thanks, again. 


Please use the Accept as Solution or Kudo buttons when appropriate

Chris Lindner
CAD Technology Consultant @ onebuttoncad.com
AUGI Board of Directors

Message 14 of 17
clindner
in reply to: clindner

@trevor.bird.au,

 

I'm still trying to get my MLeaders to "straighten up"! Smiley Frustrated

 

I've noticed something interesting on leaders that have been re-aligned (via MLEADERSALIGN): when you attempt to add a leader, it adds it as if the block content was still rotated. And then, if you move or copy the modified leader, the "connection points" re-attach as if the block was still rotated. 

 

Screenshot_2018.01.04_10h59m42s_002_.jpg

 

Gotta love MLeaders!


Please use the Accept as Solution or Kudo buttons when appropriate

Chris Lindner
CAD Technology Consultant @ onebuttoncad.com
AUGI Board of Directors

Message 15 of 17
trevor.bird.au
in reply to: clindner

Hi Chris,

 

My apologies for not replying to you sooner.

 

I did revisit this program when you provided your example drawing and hoped to reply with a solution but unfortunately the revisit has been a work in progress and then...Christmas Smiley Happy

 

I appreciate the example drawings you've been providing; it's good to have more scenarios to test.

I'll also take into account the leader attachment point issue when leaders added.

 

Hopefully it will all fall into place soon...and yes, I agree, gotta love MLEADERS!

 

 

Regards,

Trevor

 

 

Message 16 of 17
trevor.bird.au
in reply to: clindner

Hi Chris,

 

I quickly "polished up" my work in progress which I believe handles the leader attachment point correctly.

It still doesn't handle some of the scenarios in your first example drawing you first posted "temp.dwg"

 

In this version I mainly focused on Block Content MLEADERS and have not thoroughly tested the changes on MTEXT Content leaders which I hope still works correctly!

 

I look forward to your feedback.

 

Also many thanks to Lee Mac and his vast library of matrix and vector functions which are very much appreciated.

 

 

Regards,

Trevor

 

;;  MLeaderContentAlign.lsp by Trevor Bird
;;
;;  2018-01-05

;;------------------------------------------------------------------------------
(defun c:mleadercontentalign
  (
    /

    BlockContentPosition_15
    BlockContentRotation_46
    BlockPlaneX:uv
    BlockPlaneX:v_new
    BlockPlaneY:uv
    BlockPlaneY:v_new
    BlockPlaneZ:uv
    BlockPlaneZ:v_new
    BlockRotation:uv

    ContentBasePosition_10
    ContextData_10
    ContextData_110
    ContextData_111
    ContextData_112
    ContextData_12
    ContextData_13
    ContextData_14
    ContextData_15
    ContextData_16
    ContextData_16_new
    ContextData_171
    ContextData_175
    ContextData_297
    ContextData_40
    ContextData_40_new
    ContextData_42
    ContextData_46
    ContextData_DXF
    ContextData_DXF_copy
    ContextData_DXF_new

    DogLeg:uv
    dp

    flag_ContextData
    flag_while

    LeaderControl_10
    LeaderControl_11
    LeaderControl_40
    LeaderControl_DXF
    LeaderLine_10
    LeaderLine_91
    LeaderLine_DXF
    Leaders_DXF
    Leaders_DXF_copy
    Leaders_DXF_new
    Leader_10
    Leader_10_new
    Leader_11
    Leader_11_new
    Leader_90
    Leader_DXF
    Leader_DXF_new
    list_47
    list_47_cdr
    list_47_copy
    list_47_new
    list_90
    list_LeaderLines
    list_Leaders
    list_Leaders_copy
    list_Leaders_new
    list_vector

    member_list
    MULTILEADER_172
    MULTILEADER_DXF
    MULTILEADER_DXF_new
    MULTILEADER_ename

    m:Block1_list
    m:Block2_list
    m:BlockNew1_list
    m:BlockNew2_list

    ScalarDistance
    ScalarSign
    ssC
    ss_Filter
    ss_MULTILEADER
    sv_cvport
    sv_ucsorg_wcs
    sv_ucsxdir_wcs
    sv_ucsydir_wcs

    TextDirection_13
    TextLocation_12

    ucsxdir_angle
    ucsydir_angle
    ucszdir_wcs

    Vector:uv
    Vector:v
    VectorsAngle
    VectorsVDP
    VectorX
    VectorY
  )
  (setq sv_cvport (getvar 'CVPORT)
        ss_Filter '((0 . "MULTILEADER"))
  );setq

  (if (= sv_cvport 1)
    (setq ss_Filter (append ss_Filter (list (cons 410 (getvar 'CTAB)))))
    (setq ss_Filter (append ss_Filter '((410 . "Model"))))
  );if (= sv_cvport 1)




  (setq ss_MULTILEADER  (ssget ":L" ss_Filter))


  (cond
    ( (not ss_MULTILEADER)
      (princ "\nNo MLeaders selected.")
    );(not ss_MULTILEADER)


    (ss_MULTILEADER
      (setq sv_ucsorg_wcs   (getvar 'UCSORG)
            sv_ucsxdir_wcs  (getvar 'UCSXDIR)
            sv_ucsydir_wcs  (getvar 'UCSYDIR)
            ucsxdir_angle   (atan (cadr sv_ucsxdir_wcs) (car sv_ucsxdir_wcs))
            ucsydir_angle   (atan (cadr sv_ucsydir_wcs) (car sv_ucsydir_wcs))
            ucszdir_wcs     (leemac:v^v sv_ucsxdir_wcs sv_ucsydir_wcs)
      );setq


      (setq ssC -1)

      (repeat (sslength ss_MULTILEADER)
        (setq MULTILEADER_ename   (ssname ss_MULTILEADER (setq ssC  (1+ ssC)))
              MULTILEADER_DXF     (entget MULTILEADER_ename)
              MULTILEADER_DXF_new (reverse (cdr (member '(300 . "CONTEXT_DATA{") (reverse MULTILEADER_DXF))))
              MULTILEADER_DXF_new (append MULTILEADER_DXF_new (cdr (member '(301 . "}") MULTILEADER_DXF)))
              MULTILEADER_172     (cdr (assoc 172 MULTILEADER_DXF_new)) ;  Content Type

              ContextData_DXF     (cdr (member '(300 . "CONTEXT_DATA{") MULTILEADER_DXF))
              ContextData_DXF     (reverse (cdr (member '(301 . "}") (reverse ContextData_DXF))))
              ContextData_10      (cdr (assoc 10 ContextData_DXF))      ;  Content Base Position
              ContextData_40      (cdr (assoc 40 ContextData_DXF))      ;  Content Scale
              ContextData_110     (cdr (assoc 110 ContextData_DXF))     ;  MLeader Plane Origin Point
              ContextData_111     (cdr (assoc 111 ContextData_DXF))     ;  MLeader Plane X-Axis Direction
              ContextData_112     (cdr (assoc 112 ContextData_DXF))     ;  MLeader Plane Y-Axis Direction
              ContextData_297     (cdr (assoc 297 ContextData_DXF))     ;  MLeader Plane Normal Reversed
        );setq


        ;;  <!--  ContextData
        ;;  Construct ContextData_DXF_new without LEADER data.
        ;;  Create list of LEADER data.
        (setq ContextData_DXF_copy  ContextData_DXF
              ContextData_DXF_new   nil
              Leaders_DXF           nil
              flag_while            T
              flag_ContextData      T
        );setq

        (while flag_while
          (setq dp                    (car ContextData_DXF_copy)
                ContextData_DXF_copy  (cdr ContextData_DXF_copy)
          );setq

          (cond
            ( (not ContextData_DXF_copy)
              (setq flag_while  nil)
            );(not ContextData_DXF_copy)

            ( (equal dp '(302 . "LEADER{"))
              (setq Leaders_DXF       (append Leaders_DXF (list dp))
                    flag_ContextData  nil
              );setq
            );(equal dp '(302 . "LEADER{"))

            ( (equal dp '(303 . "}"))
              (setq Leaders_DXF       (append Leaders_DXF (list dp))
                    flag_ContextData  T
              );setq
            );(equal dp '(303 . "}"))


            ( (not flag_ContextData)
              (setq Leaders_DXF (append Leaders_DXF (list dp)))
            );(not flag_ContextData)

            (flag_ContextData
              (setq ContextData_DXF_new (append ContextData_DXF_new (list dp)))
            );flag_ContextData
          );cond
        );while flag_while
        ;;  ContextData  -->




        ;;  <!--  Leader Nodes
        (setq Leaders_DXF_copy  Leaders_DXF
              list_Leaders      nil
              LeaderControl_DXF nil
              list_90           nil
              flag_while        T
        );setq

        (while flag_while
          (setq member_list (member '(302 . "LEADER{") Leaders_DXF_copy))

          (cond
            ( (not member_list)
              (setq flag_while  nil)
            );(not member_list)

            (member_list
              (setq Leaders_DXF_copy  (cdr (member '(303 . "}") member_list))
                    Leader_DXF        nil
              );setq

              ;;  Construct Leader_DXF for each LEADER
              (while member_list
                (setq dp          (car member_list)
                      member_list (cdr member_list)
                      Leader_DXF  (append Leader_DXF (list dp))
                );setq

                (if (equal dp '(303 . "}"))
                  (progn
                    (setq Leader_90     (cdr (assoc 90  Leader_DXF))  ;  Leader Branch Index
                          list_90       (append list_90 (list Leader_90))
                          member_list   nil
                    );setq
                  );progn
                );if (equal dp '(303 . "}"))
              );while member_list


              (cond
                ( (not LeaderControl_DXF)
                  ;;  Assume FIRST leader in multileader is control leader for content:
                  (setq LeaderControl_DXF Leader_DXF)
                );(not LeaderControl_DXF)

                (LeaderControl_DXF
                  (setq list_Leaders  (append list_Leaders (list Leader_DXF)))
                );LeaderControl_DXF
              );cond
            );member_list
          );cond
        );while flag_while



        (setq LeaderControl_10  (cdr (assoc 10  LeaderControl_DXF)) ;  Last Leader Line Point
              LeaderControl_11  (cdr (assoc 11  LeaderControl_DXF)) ;  Dogleg Vector
              LeaderControl_40  (cdr (assoc 40  LeaderControl_DXF)) ;  Dogleg Length
              DogLeg:uv         LeaderControl_11

              list_LeaderLines  nil
              Leaders_DXF_copy  Leaders_DXF
              LeaderLine_10     nil
              flag_while        T
        );setq

        (while flag_while
          (setq member_list  (member '(304 . "LEADER_LINE{") Leaders_DXF_copy))

          (cond
            ( (not member_list)
              (setq flag_while  nil)
            );(not member_list)

            (member_list
              (setq Leaders_DXF_copy  (cdr (member '(305 . "}") member_list))
                    LeaderLine_DXF  nil
              );setq

              (while member_list
                (setq dp              (car member_list)
                      member_list     (cdr member_list)
                      LeaderLine_DXF  (append LeaderLine_DXF (list dp))
                );setq

                (if (equal dp '(305 . "}"))
                  (progn
                    (setq list_LeaderLines  (append list_LeaderLines (list LeaderLine_DXF))
                          LeaderLine_91     (cdr (assoc 91 LeaderLine_DXF))
                          member_list       nil
                    );setq

                    ;;  New MLeader Plane Origin Point (first point of first leader)
                    (if (not LeaderLine_10)
                      (setq LeaderLine_10 (cdr (assoc 10 LeaderLine_DXF)))
                    );if (not LeaderLine_10)
                  );progn
                );if
              );while member_list
            );member_list
          );cond
        );while flag_while
        ;;  Leader Nodes  -->




        ;;  <!--  Content Type
        (cond
          ( (= MULTILEADER_172 acMTextContent)
            (setq ContextData_12  (cdr (assoc 12  ContextData_DXF)) ;  Text Location
                  ContextData_13  (cdr (assoc 13  ContextData_DXF)) ;  Text Direction
                  ContextData_42  (cdr (assoc 42  ContextData_DXF)) ;  Text Rotation
                  ContextData_171 (cdr (assoc 171 ContextData_DXF)) ;  Text Attachment
                  ContextData_175 (cdr (assoc 175 ContextData_DXF)) ;  Text Alignment Type
            );setq

            (if (minusp (leemac:vxv LeaderControl_11 sv_ucsxdir_wcs))
              (setq ScalarSign  -1.0)
              (setq ScalarSign  1.0)
            );if

            (setq DogLeg:uv           (leemac:vxs sv_ucsxdir_wcs ScalarSign)
                  LeaderControl_DXF   (subst (cons 11 DogLeg:uv) (assoc 11 LeaderControl_DXF) LeaderControl_DXF)

                  ;;  Reset Text Location:
                  Vector:v            (mapcar '- ContextData_12 LeaderControl_10)
                  Vector:uv           (leemac:unit Vector:v)
                  VectorsVDP          (leemac:vxv Vector:uv LeaderControl_11)
                  VectorsAngle        (leemac:acos VectorsVDP)
                  VectorsAngle        (* ScalarSign VectorsAngle)
                  ScalarDistance      (distance LeaderControl_10 ContextData_12)

                  ;;  2D Vector Rotation:
                  VectorX             (- (* (car DogLeg:uv) (cos VectorsAngle)) (* (cadr DogLeg:uv) (sin VectorsAngle)))
                  VectorY             (+ (* (cadr DogLeg:uv) (cos VectorsAngle)) (* (car DogLeg:uv) (sin VectorsAngle)))

                  TextLocation_12     (mapcar '+ LeaderControl_10 (leemac:vxs (list VectorX VectorY 0.0) ScalarDistance))
                  TextDirection_13    sv_ucsxdir_wcs
                  ContextData_DXF_new (subst (cons 12 TextLocation_12) (assoc 12 ContextData_DXF_new) ContextData_DXF_new)
                  ContextData_DXF_new (subst (cons 13 TextDirection_13) (assoc 13 ContextData_DXF_new) ContextData_DXF_new)
            );setq


            ;;  <!--  Reset Content Base Postion:
            (setq Vector:v                (mapcar '- ContextData_10 LeaderControl_10)
                  Vector:uv               (leemac:unit Vector:v)
                  VectorsVDP              (leemac:vxv Vector:uv LeaderControl_11)
                  VectorsAngle            (leemac:acos VectorsVDP)
                  VectorsAngle            (* ScalarSign VectorsAngle)
                  ScalarDistance          (distance LeaderControl_10 ContextData_10)

                  ;;  2D Vector Rotation:
                  VectorX                 (- (* (car DogLeg:uv) (cos VectorsAngle)) (* (cadr DogLeg:uv) (sin VectorsAngle)))
                  VectorY                 (+ (* (cadr DogLeg:uv) (cos VectorsAngle)) (* (car DogLeg:uv) (sin VectorsAngle)))

                  ContentBasePosition_10  (mapcar '+ LeaderControl_10 (leemac:vxs (list VectorX VectorY 0.0) ScalarDistance))
                  ContextData_DXF_new     (subst (cons 10 ContentBasePosition_10) (assoc 10 ContextData_DXF_new) ContextData_DXF_new)
            );setq
            ;;  Reset Content Base Postion  -->
          );(= MULTILEADER_172 acMTextContent)








          ( (= MULTILEADER_172 acBlockContent)
            (setq ContextData_14  (cdr (assoc 14  ContextData_DXF))   ;  Block Content Normal Direction
                  ContextData_15  (cdr (assoc 15  ContextData_DXF))   ;  Block Content Position
                  ContextData_16  (cdr (assoc 16  ContextData_DXF))   ;  Block Content Scale
                  ContextData_46  (cdr (assoc 46  ContextData_DXF))   ;  Block Content Rotation
            );setq


            ;;  <!--  Block Transformation Matrix
            (setq list_47     (vl-remove-if-not '(lambda (_dp) (= (car _dp) 47)) ContextData_DXF)
                  list_47_cdr (mapcar 'cdr list_47)
            );setq
            ;;  Block Transformation Matrix  -->

            (setq ContextData_16_new  (mapcar 'abs ContextData_16)

                  ;;  Reset Content Scale
                  ContextData_40_new  (car ContextData_16_new)
                  ContextData_DXF_new (subst (cons 40 ContextData_40_new) (assoc 40 ContextData_DXF_new) ContextData_DXF_new)
            );setq


            ;;  Define block rotation as a vector:
            (setq BlockRotation:uv  (list (cos ContextData_46) (sin ContextData_46) 0.0))


            ;;  Block Content Axes in UCS:
            (setq BlockPlaneX:v_new (mapcar '* ContextData_16_new sv_ucsxdir_wcs)
                  BlockPlaneY:v_new (mapcar '* ContextData_16_new sv_ucsydir_wcs)
                  BlockPlaneZ:v_new (mapcar '* ContextData_16_new ucszdir_wcs)
            );setq


            ;;  Determine new Dog Leg direction:
            (setq Vector:v  (mapcar '- ContextData_15 LeaderControl_10)
                  Vector:uv (leemac:unit Vector:v)
            );setq

            (if (minusp (leemac:vxv Vector:uv sv_ucsxdir_wcs))
              (setq ScalarSign  -1.0)
              (setq ScalarSign  1.0)
            );if

            (setq DogLeg:uv         (leemac:vxs sv_ucsxdir_wcs ScalarSign)
                  LeaderControl_DXF (subst (cons 11 DogLeg:uv) (assoc 11 LeaderControl_DXF) LeaderControl_DXF)
            );setq




            ;;  Determine new Block Content Rotation:
            (cond
              ( (and  (> ContextData_46 ucsydir_angle)
                      (< ContextData_46 (+ ucsydir_angle pi))
                );and
                (setq BlockContentRotation_46 ucsxdir_angle
                      ScalarDistance          LeaderControl_40
                );setq
              )

              (ContextData_46
                (setq BlockContentRotation_46 ucsxdir_angle
                      ScalarDistance          (distance LeaderControl_10 ContextData_15)
                );setq
              );ContextData_46
            );cond


            (setq ContextData_DXF_new     (subst (cons 46 BlockContentRotation_46) (assoc 46 ContextData_DXF_new) ContextData_DXF_new)
                  BlockContentPosition_15 (mapcar '+ LeaderControl_10 (leemac:vxs DogLeg:uv ScalarDistance))
                  ContextData_DXF_new     (subst (cons 15 BlockContentPosition_15) (assoc 15 ContextData_DXF_new) ContextData_DXF_new)
            );setq
            ;;  Determine new Block Content Position: -->




            ;;  <!--  Block Transformation Matrix
            (setq list_47         (vl-remove-if-not '(lambda (_dp) (= (car _dp) 47)) ContextData_DXF_new)
                  list_47_cdr     (mapcar 'cdr list_47)
                  list_47_copy    list_47_cdr
                  m:Block2_list   nil
                  BlockPlaneX:uv  nil
                  BlockPlaneY:uv  nil
                  BlockPlaneZ:uv  nil
            );setq

            (while list_47_copy
              (setq list_vector nil)

              (repeat 4
                (setq list_vector   (append list_vector (list (car list_47_copy)))
                      list_47_copy  (cdr list_47_copy)
                );setq
              );repeat 4

              (cond
                ( (not BlockPlaneX:uv)
                  (setq BlockPlaneX:uv  (leemac:unit (reverse (cdr (reverse list_vector)))))
                );(not BlockPlaneX:uv)

                ( (not BlockPlaneY:uv)
                  (setq BlockPlaneY:uv  (leemac:unit (reverse (cdr (reverse list_vector)))))
                );(not BlockPlaneY:uv)

                ( (not BlockPlaneZ:uv)
                  (setq BlockPlaneZ:uv  (leemac:unit (reverse (cdr (reverse list_vector)))))
                );(not BlockPlaneZ:uv)
              );cond

              (setq m:Block2_list (append m:Block2_list (list list_vector)))
            );while list_47_copy

            (setq m:Block1_list (apply 'mapcar (cons 'list m:Block2_list)))
            ;;  Block Transformation Matrix  -->




            ;;  <!--  Reconstruct Block Content Matrix (includes scaling):
            (setq m:BlockNew1_list
              (list
                (append BlockPlaneX:v_new '(0.0))
                (append BlockPlaneY:v_new '(0.0))
                (append BlockPlaneZ:v_new '(0.0))
                (append BlockContentPosition_15 '(1.0))
              );list

                  m:BlockNew2_list  (apply 'mapcar (cons 'list m:BlockNew1_list))
            );setq
            ;;  Reconstruct Block Content Matrix  -->


            (setq list_47_new         (apply 'append m:BlockNew2_list)
                  list_47_new         (mapcar '(lambda (_x) (cons 47 _x)) list_47_new)
                  ContextData_DXF_new (vl-remove-if '(lambda (_dp) (= (car _dp) 47)) ContextData_DXF_new)
                  ContextData_DXF_new (append ContextData_DXF_new list_47_new)
            );setq
            ;;  Reconstruct Block Content Matrix (includes scaling)  -->




            ;;  <!--  Reset Content Base Postion:
            ;;  Compare block rotation with block plane axis X.
            (if (minusp (leemac:vxv (leemac:unit BlockPlaneX:v_new) DogLeg:uv))
              (setq ScalarSign      -1.0
                    ScalarDistance  (distance LeaderControl_10 ContextData_10)
              );setq
              (setq ScalarSign      1.0
                    ScalarDistance  LeaderControl_40
              );setq
            );if


            (setq ContentBasePosition_10  (mapcar '+ LeaderControl_10 (leemac:vxs DogLeg:uv (* ScalarDistance 1.0)))
                  ContextData_DXF_new     (subst (cons 10 ContentBasePosition_10) (assoc 10 ContextData_DXF_new) ContextData_DXF_new)
            );setq
            ;;  Reset Content Base Postion  -->
          );(= MULTILEADER_172 acBlockContent)
        );cond
        ;;  Content Type  -->








        ;;  <!--  Reset MLeader Plane X-Axis and Y-Axis Directions:
        (setq Vector:v               (mapcar '- ContextData_110 LeaderControl_10)
              Vector:uv              (leemac:unit Vector:v)
              VectorsVDP             (leemac:vxv Vector:uv LeaderControl_11)
              VectorsAngle           (leemac:acos VectorsVDP)
              ScalarDistance         (distance LeaderControl_10 ContextData_110)

              ;;  2D Vector Rotation:
              VectorX                (- (* (car DogLeg:uv) (cos VectorsAngle)) (* (cadr DogLeg:uv) (sin VectorsAngle)))
              VectorY                (+ (* (cadr DogLeg:uv) (cos VectorsAngle)) (* (car DogLeg:uv) (sin VectorsAngle)))

              ContextData_DXF_new    (subst (cons 110 LeaderLine_10)  (assoc 110 ContextData_DXF_new) ContextData_DXF_new)
              ContextData_DXF_new    (subst (cons 111 sv_ucsxdir_wcs) (assoc 111 ContextData_DXF_new) ContextData_DXF_new)
              ContextData_DXF_new    (subst (cons 112 sv_ucsydir_wcs) (assoc 112 ContextData_DXF_new) ContextData_DXF_new)
        );setq
        ;;  Reset MLeader Plane X-Axis and Y-Axis Directions  -->




        ;;  <!--  Reconstruct MLeader
        (setq list_Leaders_new  nil
              list_Leaders_copy list_Leaders
        );setq

        ;;  Recalculate Leader_10 from LeaderControl_10 and DogLeg:uv for other leaders:
        (while list_Leaders_copy
          (setq Leader_DXF  (car list_Leaders_copy)
                Leader_10   (cdr (assoc 10 Leader_DXF)) ;  Last Leader Line Point
                Leader_11   (cdr (assoc 11 Leader_DXF)) ;  Dogleg Vector
          );setq


          (if (minusp (leemac:vxv Leader_11 LeaderControl_11))
            (setq ScalarSign  -1.0)
            (setq ScalarSign  1.0)
          );if

          (setq Leader_11_new     (leemac:vxs DogLeg:uv ScalarSign)
                ScalarDistance    (distance Leader_10 LeaderControl_10)
                Leader_10_new     (mapcar '+ LeaderControl_10 (leemac:vxs DogLeg:uv ScalarDistance))
                Leader_DXF_new    Leader_DXF
                Leader_DXF_new    (subst (cons 11 Leader_11_new) (assoc 11 Leader_DXF_new) Leader_DXF_new)
                Leader_DXF_new    (subst (cons 10 Leader_10_new) (assoc 10 Leader_DXF_new) Leader_DXF_new)
                list_Leaders_new  (append list_Leaders_new (list Leader_DXF_new))
                list_Leaders_copy (cdr list_Leaders_copy)
          );setq
        );while list_Leaders_copy


        (setq list_Leaders        (cons LeaderControl_DXF list_Leaders_new)
              Leaders_DXF_new     (apply 'append list_Leaders)

              ContextData_DXF_new (append ContextData_DXF_new Leaders_DXF_new)
              ContextData_DXF_new (cons '(300 . "CONTEXT_DATA{") ContextData_DXF_new)
              ContextData_DXF_new (reverse (cons '(301 . "}") (reverse ContextData_DXF_new)))
        );setq


        (setq MULTILEADER_DXF_new
          (append MULTILEADER_DXF_new
            ContextData_DXF_new
          );append
        );setq
        (entmod MULTILEADER_DXF_new)
        (entupd MULTILEADER_ename)
        ;;  Reconstruct MLeader -->
      );repeat (sslength ss_MULTILEADER)
    );ss_MULTILEADER
  );cond


  (princ)
);c:mleadercontentalign









;;------------------------------------------------------------------------------
;; Matrix x Vector  -  Vladimir Nesterovsky
;; Args: m - nxn matrix, v - vector in R^n

(defun leemac:mxv ( m v )
    (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
)


;; Vector Norm - Lee Mac
;; Args: v - vector in R^n

(defun leemac:norm ( v )
  (sqrt (apply '+ (mapcar '* v v)))
)


;; Vector x Scalar - Lee Mac
;; Args: v - vector in R^n, s - real scalar

(defun leemac:vxs ( v s )
  (mapcar '(lambda ( n ) (* n s)) v)
)


;; Unit Vector - Lee Mac
;; Args: v - vector in R^n

(defun leemac:unit ( v )
  ( (lambda ( n ) (if (equal 0.0 n 1e-14) nil (leemac:vxs v (/ 1.0 n)))) (leemac:norm v))
)


;; Vector Cross Product - Lee Mac
;; Args: u,v - vectors in R^3

(defun leemac:v^v ( u v )
  (list
    (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
    (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
    (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
  )
)


;; Vector Dot Product  -  Lee Mac
;; Args: u,v - vectors in R^n

(defun leemac:vxv ( u v )
    (apply '+ (mapcar '* u v))
)


;; ArcCosine  -  Lee Mac
;; Args: -1 <= x <= 1

(defun leemac:acos ( x )
    (if (<= -1.0 x 1.0)
        (atan (sqrt (- 1.0 (* x x))) x)
    )
)




;;------------------------------------------------------------------------------
(princ "\nMLeaderContentAlign loaded. Start command with MLEADERCONTENTALIGN.")
(princ)
Tags (2)
Message 17 of 17
dbroad
in reply to: Anonymous

Quite an impressive programming effort.  I can confirm that it works but can leave the block content misplaced relative to the doglegs.  In my experience, the insertion point ends up on the end of the left dogleg with a gap between the block content and the right dogleg.  The effect is that the left dogleg overlaps the rotated block content.  The misaligned block content can be changed by toggling the mleaderstyle's BlockConnectionType between extents and insertion point and back. That automatically shifts the mleaders. If I get time, I'll try to study your code more.

Architect, Registered NC, VA, SC, & GA.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost