Jump to content
tmduk

Rotating multiple objects / text in 3d around their insertion point

Recommended Posts

tmduk

Hi there all

 

First post and it's a request for help (although been a long time lurker)

 

I've got a 3d drawing that has a load of levels in 3d positions with text displaying the height value. These are all orientated and readable in plan view.

 

I want to create some sections using the 3d information, and what I would like to work out is the best way to manipulate the level cross (block) and associated text so that it is rotated to a side on section view. (in model space not just in a paper space viewport)

 

I've tried using the rotate3d command on mass and can't quite get the results I'm after, basically it rotates the text so that it is now readable in the section but when selecting multiple items it rotates the whole lot around one datum rather than rotating each item around it's own insertion / justification point.

 

acadrottxt.jpg

 

in the above image, to the left is what I'm starting with levels (red) in 3d

 

- next is the result I get from using the command rotate3d (levels in white) when they are selected in one go. the text is rotated so that it's legible but has moved away from the 3d polyline

 

- the 2 to the right show what i'm aiming for, having manually moved them to their representative points and then rotated, however there's gonna be quite a few to rotate and shift along different sections, so it would be good to have this a bit more automated

 

acadrottxt1.jpg

 

acadrottxt2.jpg

 

acadrottxt4.jpg

 

any suggestions? am I not using rotate3d to it's full potential or is this something that would need to be solved with a lisp routine? picking a temp ucs along the section line and then selecting the relative objects to rotate

 

thanks in advance

Share this post


Link to post
Share on other sites
marko_ribar

You can try to firstly set UCS to desired plane - your elevation view, then you can select text entities and iterate through selection set entmodifying each 210 DXF association code to match normal unit vector of your UCS previously set at correct 3d orientation...

Share this post


Link to post
Share on other sites
Jef!

Hi tmduk.

 

First of all, welcome to the forum.

 

If I understood correctly, you want to do a 3D rotation of the selected entities, but you want the texts (or datum blocs?) to keep facing the same direction after the 3d rotation. That is not the result you would get with the native rotate3D. I succeeded in doing it by making a routine. It is always a good way to save time by getting cad to do exactly what you need, especially if your needs are very specific.

 

Here my suggestions: The easiest way I came up with... i retrieved the rotation axis using (getpoint), then made a selection set with ssget.

After that i used an if statement. if it is not a block/text/mtext, i use (vla-Rotate3D. If it is a block/text/mtext, to avoid the hassle of dealing with their OCS, I created a temporary point on the insertion pointof the block/text/mtext, (vla-Rotate3D the temporary point, then retrieved its coordinate property and used it to change the insertion point of the block/text/mtext (instead of rotating it). I then deleted the temporary points. If it is a block, i also attsync'ed it to replace the attributes back to their correct position.

Works like a charm!

delete.png

 

It is a good thing to use trans to take coordinates in WCS even if you are currently on a ucs, because you need to feed wcs coordinates to (vla-Rotate3D. It is of course necessary to trans back p1coord to feed it to the second (getpoint), as it requires a coord in the current ucs.

 

Here, that is the code I made

(defun c:test ( / p1coord p2coord point1 point2 delta obj vlss tmppoint)
;made by Jef! 2015-12-10.
  (princ "\nSelect things to rotate")
  (if (ssget)
       (progn
           (setq point1 (vlax-3d-point (setq p1coord (trans (getpoint "\nPick 1rst rotation axis point") 1 0)))
                 point2 (vlax-3d-point (setq p2coord (trans (getpoint (trans p1coord 0 1) "\nPick 2nd rotation axis point")1 0)))
                 delta  (mapcar '- p2coord p1coord)
           )
           (vlax-for obj (setq vlss (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))
              (if (or (eq (vla-get-objectname obj) "AcDbMText")
                      (eq (vla-get-objectname obj) "AcDbText")
                      (eq (vla-get-objectname obj) "AcDbBlockReference")
                  )
                  (progn
                     (setq tmppoint(vlax-ename->vla-object(entmakex (list (cons 0 "POINT") (cons 10 (vlax-get obj 'InsertionPoint))))))
                     (vla-Rotate3D tmppoint point1 point2 (/ pi 2))
                     (vlax-put obj 'InsertionPoint (vlax-get tmppoint 'coordinates))
                     (vla-erase tmppoint)
                     (if (eq (vla-get-objectname obj) "AcDbBlockReference")
                         (vl-cmdf "_.AttSync" "Name" (vla-get-name obj))
                     )
                  )
                  (vla-Rotate3D obj point1 point2 (/ pi 2))
               )
            )
        )
    )
)

I made the code to do a rotation of 90degres, it could be asked by a prompt and applied instead of the (/ pi 2)... There is no error handler, i'll leave some of the fun for you.

 

I hope it helps. Cheers

Jef!

Share this post


Link to post
Share on other sites
tmduk

Hi there, thanks for the quick responses folks,

 

tried your routine Jef and it works well but doesn't quite give the results I'm after...

 

to try and explain a bit more, I would like the 3d polyline / profile to remain in the same place in 3d and the text / blocks to rotate to a new orientation but remain with the same insertion point.

Using the Acad command rotate3d, rotates the selected items around one baseline, I'm after rotating the elements around individual baselines but along the same plane on a UCS set up per section line. hopefully the image below will illustrate this a bit better

 

acadrottxt6.jpg

 

once again thanks for your help so far...

Share this post


Link to post
Share on other sites
Jef!

Based on my first routine, i just removed the the rotations of the non block/text/mtext objects. I then added the rotation in the if for the texts/mtexts/blocks. instead of picking points, I took their original insertion points. As they are rotated around an axis I created from their own 'InsertionPoint coordinate I removed the 2 points hand picking. Now you only have to select all items from a view. All the texts/mtexts and blocks will get 3d rotation around an axis aligned on the x axis, passing by their individual insertion points. With a few quick modification the result was achieved.

 

I also removed the delta variable which i finally never used, the vlss variable as well. I added an error handler, and I actually validate that a block has attributes before doing attsync. No fun left for you. Enjoy!

 

 (defun c:3rtx ( / *error* obj tmppoint)
;3D rotate texts mtexts and blocks aound an axis aligned
;on the x axis, passing by their individual insertion points. 
;made by Jef! 2015-12-11.
  (defun *error* ( msg )
       (if (not (member msg '("Function cancelled" "quit / exit abort")))
           (princ (strcat "\nError: " msg))
       )
       (princ)
  )
  (princ "\nSelect objects to rotate")
  (if (ssget)
       (progn
           (vlax-for obj (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)))
              (if (or (eq (vla-get-objectname obj) "AcDbMText")
                      (eq (vla-get-objectname obj) "AcDbText")
                      (eq (vla-get-objectname obj) "AcDbBlockReference")
                  )
                  (progn
                     (vla-Rotate3D obj (vlax-3d-point (setq tmppoint (vlax-get obj 'InsertionPoint))) (vlax-3d-point (mapcar '+ tmppoint '(1 0 0))) (/ pi 2))
                     (if (and (eq (vla-get-objectname obj) "AcDbBlockReference")
                              (= (vlax-get-property obj 'HasAttributes) :vlax-true)
                         )
                         (vl-cmdf "_.AttSync" "Name" (vla-get-name obj))
                     )
                  )
               )
            )
        )
     (princ "nothing selected")
    )
  (princ)
)

 

ps.: I hope your goal is learning... lisp is fun and powerfull.

Cheers!

Jef!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×