Jump to content

Rotate Dynamic Blocks on Insert with Option for Additional Rotate.


dortega4269

Recommended Posts

Experts,

Since I'm a n00b to LiSP, I have been doing research to try and piece together some LiSP to help me with this seemingly tedious task/ritual that I endure daily. Lee Mac posted a reply on another Thread (Rotate multiple blocks around their individual origin point) and it works to an extent, rotates the individual block but it's not everything I need.

 

and please offer any advice on how best to achieve this using using LiSP. I have attached my Dynamic Block should you need it for testing.

 

Brief explanation:

I have several dynamic blocks that I created in 3D and was forced to lay them down on the Y-axis in order to get the stretch function to work on the Z-axis. My sequence on inserting the dynamic blocks is to insert my block, select the block, click on the top left corner of my viewcube, using the isometric view I am now able to utilize the 3Drotate command and rotate the block about the insertion point on the X-axis 90 degrees -- doing so now brings my block to the correct orientation to use in my 3D modeling of metal stud framing members, however, now I must rotate the blocks using world ucs (X,Y) about the Z-axis to align with the Architectural floorplan.

door.dwg

Edited by dortega4269
Link to comment
Share on other sites

  • Replies 26
  • Created
  • Last Reply

Top Posters In This Topic

  • dortega4269

    13

  • Lee Mac

    7

  • Tharwat

    3

  • satishrajdev

    2

I have had some luck with these little macros I wrote, however, it tends to be hit and miss. These macros allow me to rotate a single item I by clicking on it and repeats the command until I hit ESC, but if I don't click directly on the block the block will not be rotated about the insertion point rather a bit off. Another issue with this macro is that I cannot have an item/block selected when I click on the newly created Icons, I must click on the icon first to start the macro and proceed with selecting the item/block.

 

Can any one offer help with either this macro or offer help with creating LiSP for the aforementioned issue? Anything helps.

*^C^C_rotate;\\_insert;@;180;
*^C^C_rotate;\\_insert;@;90;
*^C^C_rotate;\\_insert;@;-90;

Link to comment
Share on other sites

Almost forgot, I threw together this tidbit and it hits and misses on occasion. Sometimes I have issues keeping it loaded and other times I have trouble getting it to work, but when it works it works well for half of what I'm trying to do.

(defun c:rb ( / ss )
 (if (setq ss (ssget "_:L"))
   (command "rotate" ss "" "_ins" "@" "90")
 )
 (princ)
)

Edited by dortega4269
Link to comment
Share on other sites

I hope this'll work

 

(defun c:rb ( / ss )
  (setq ss (ssget "_:L"))
   [color="red"](setq pnt (getpoint "\n Specify Base Point :"))[/color]
   (command "rotate" ss "" [color="red"]pnt[/color] "_ins" "90")
 (princ)
)

Link to comment
Share on other sites

Thanks Satishrajdev! I'll be sure to check this out first thing when I get back to the office in a couple hours. :)

Link to comment
Share on other sites

:glare:So... now i get this prompt:

Command: rb

Select objects: 1 found

Select objects:

No Endpoint found for specified point.

Invalid point.

Link to comment
Share on other sites

Are you after a routine that should allow a user to select blocks and enter angle degree and after that the code should rotate the selected blocks each one alone

at its insertion point ?

Link to comment
Share on other sites

Is this what you're trying to accomplish?

 

(defun c:BR90 (/ pi/2 ss i d a)
 (if (setq pi/2 (/ pi 2.)
           ss   (ssget "_:L" '((0 . "INSERT")))
     )
   (repeat (setq i (sslength ss))
     (entmod
       (subst
         (cons 50 (+ (cdr (setq a (assoc 50 (setq d (entget (ssname ss (setq i (1- i)))))))) pi/2))
         a
         d
       )
     )
   )
 )
 (princ)
)

Link to comment
Share on other sites

Are you after a routine that should allow a user to select blocks and enter angle degree and after that the code should rotate the selected blocks each one alone

at its insertion point ?

 

Tharwat,

That would work. My only issue is that my block and my drawing have different UCS's, the block must rotate based on the block's insertion point which has been rotated 90 degrees on the x-axis (see my youtube video).

 

Is this what you're trying to accomplish?

 

(defun c:BR90 (/ pi/2 ss i d a)
 (if (setq pi/2 (/ pi 2.)
           ss   (ssget "_:L" '((0 . "INSERT")))
     )
   (repeat (setq i (sslength ss))
     (entmod
       (subst
         (cons 50 (+ (cdr (setq a (assoc 50 (setq d (entget (ssname ss (setq i (1- i)))))))) pi/2))
         a
         d
       )
     )
   )
 )
 (princ)
)

 

alanjt,

This rotates my block 90 degrees based on the block's z-axis and not my drawings z-axis. Can you have it rotate about the block's x-axis? My YouTube video and block attached to the original thread may offer more understanding.

 

Edited by dortega4269
Added link and additional information
Link to comment
Share on other sites

Your video is private and it is not public to be able to watch the suspense :D

 

Tharwat, hahaha I guess that would limit the amount of viewers... it's now set to Public.

Link to comment
Share on other sites

Although that I am not a 3D user , I guess this piece of code should work , try it and let me know .

 

Note: I couldn't open your drawing with that dynamic block and it was opened in a polyface mesh .

 

(vl-load-com)
(defun c:test (/ ss ang i e sn pt) 
 (if (and (setq ss (ssget "_:L" '((0 . "INSERT"))))
          (setq ang (getangle "\n Specify Angle: "))
     )
   (repeat (setq i (sslength ss))
     (setq e (entget (setq sn (ssname ss (setq i (1- i))))))
     (setq pt (cdr (assoc 10 e)))
     (vla-Rotate3D
       (vlax-ename->vla-object sn)
       (vlax-3D-point (trans pt 1 0))
       (vlax-3D-point (mapcar '+ (trans pt 1 0) '(1. 0. 0.)))
       ang
     )
   )
 )
 (princ)
)

Link to comment
Share on other sites

I would recommend:

([color=BLUE]defun[/color] c:bx90r ( [color=BLUE]/[/color] a e i p q r s x )
   ([color=BLUE]setq[/color] a ([color=BLUE]/[/color] [color=BLUE]pi[/color] 2.0))
   ([color=BLUE]if[/color] ([color=BLUE]setq[/color] s ([color=BLUE]ssget[/color] [color=MAROON]"_:L"[/color] '((0 . [color=MAROON]"INSERT"[/color]))))
       ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
           ([color=BLUE]setq[/color] e ([color=BLUE]ssname[/color] s ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)))
                 x ([color=BLUE]entget[/color] e)
                 p ([color=BLUE]trans[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 10 x)) e 0)
                 r ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 50 x))
                 q ([color=BLUE]trans[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 10 x)) ([color=BLUE]list[/color] ([color=BLUE]cos[/color] r) ([color=BLUE]sin[/color] r) 0.0)) e 0)
           )
           ([color=BLUE]vlax-invoke[/color] ([color=BLUE]vlax-ename->vla-object[/color] e) 'rotate3d p q a)
       )
   )
   ([color=BLUE]princ[/color])
)
([color=BLUE]vl-load-com[/color]) ([color=BLUE]princ[/color])

Link to comment
Share on other sites

Although that I am not a 3D user , I guess this piece of code should work , try it and let me know .

 

It works well to rotate a block based on the drawings axis which is perfect for the first part of my issue. Using the same bit of code, I edited your code to rotate on the drawings Z-axis, however, when I copy the originally inserted block it's not using the copied blocks insert point, but the insertion point in which the original block was inserted.

 

Explanation:

If I insert a block at 0,0,0

Copy that block based on the insert point

Place it with coordinates of 1,0,0

Rotate the block 90 degrees using your lisp (test)

The block will now be rotated 90 degrees, but with the coordinates of 0,1,0

 

I need it to remain at 0,0,0 at rotate 90 degrees, is this achievable?

 

(vl-load-com)
(defun c:test (/ ss ang i e sn pt) 
 (if (and (setq ss (ssget "_:L" '((0 . "INSERT"))))
          (setq ang (getangle "\n Specify Angle: "))
     )
   (repeat (setq i (sslength ss))
     (setq e (entget (setq sn (ssname ss (setq i (1- i))))))
     (setq pt (cdr (assoc 10 e)))
     (vla-Rotate3D
       (vlax-ename->vla-object sn)
       (vlax-3D-point (trans pt 1 0))
[color="red"]        (vlax-3D-point (mapcar '+ (trans pt 1 0) '(0. 0. 1.)))[/color]
       ang
     )
   )
 )
 (princ)
)

 

Note: I couldn't open your drawing with that dynamic block and it was opened in a polyface mesh .

 

I use Polyface Mesh to allow stretching and to minimize the files size.

Link to comment
Share on other sites

I would recommend:

([color=BLUE]defun[/color] c:bx90r ( [color=BLUE]/[/color] a e i p q r s x )
   ([color=BLUE]setq[/color] a ([color=BLUE]/[/color] [color=BLUE]pi[/color] 2.0))
   ([color=BLUE]if[/color] ([color=BLUE]setq[/color] s ([color=BLUE]ssget[/color] [color=MAROON]"_:L"[/color] '((0 . [color=MAROON]"INSERT"[/color]))))
       ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
           ([color=BLUE]setq[/color] e ([color=BLUE]ssname[/color] s ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)))
                 x ([color=BLUE]entget[/color] e)
                 p ([color=BLUE]trans[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 10 x)) e 0)
                 r ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 50 x))
                 q ([color=BLUE]trans[/color] ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 10 x)) ([color=BLUE]list[/color] ([color=BLUE]cos[/color] r) ([color=BLUE]sin[/color] r) 0.0)) e 0)
           )
           ([color=BLUE]vlax-invoke[/color] ([color=BLUE]vlax-ename->vla-object[/color] e) 'rotate3d p q a)
       )
   )
   ([color=BLUE]princ[/color])
)
([color=BLUE]vl-load-com[/color]) ([color=BLUE]princ[/color])

 

Thanks Lee Mac! This code works perfect for rotating blocks about their insert point based on the blocks x-axis. Can you make it rotate based on the blocks z-axis? How about prompt for the axis "\n Specify Axis: "?

Tharwat was on to something with his code for rotating blocks based on the drawings UCS -- maybe a mix of the two.

(vl-load-com)
(defun c:test (/ ss ang i e sn pt) 
 (if (and (setq ss (ssget "_:L" '((0 . "INSERT"))))
          (setq ang (getangle "\n Specify Angle: "))
     )
   (repeat (setq i (sslength ss))
     (setq e (entget (setq sn (ssname ss (setq i (1- i))))))
     (setq pt (cdr (assoc 10 e)))
     (vla-Rotate3D
       (vlax-ename->vla-object sn)
       (vlax-3D-point (trans pt 1 0))
       (vlax-3D-point (mapcar '+ (trans pt 1 0) '(1. 0. 0.)))
       ang
     )
   )
 )
 (princ)
)

 

I don't know this code or else I would attempt to edit it and try to make it work.

Link to comment
Share on other sites

Thanks Lee Mac! This code works perfect for rotating blocks about their insert point based on the blocks x-axis. Can you make it rotate based on the blocks z-axis? How about prompt for the axis "\n Specify Axis: "?

 

Try the following program:

([color=BLUE]defun[/color] c:b90r ( [color=BLUE]/[/color] a f i k s )
   ([color=BLUE]setq[/color] a ([color=BLUE]/[/color] [color=BLUE]pi[/color] 2.0))
   ([color=BLUE]if[/color] ([color=BLUE]setq[/color] s ([color=BLUE]ssget[/color] [color=MAROON]"_:L"[/color] '((0 . [color=MAROON]"INSERT"[/color]))))
       ([color=BLUE]progn[/color]
           ([color=BLUE]initget[/color] [color=MAROON]"X Y Z"[/color])
           ([color=BLUE]if[/color] ([color=BLUE]=[/color] [color=MAROON]"Z"[/color] ([color=BLUE]setq[/color] k ([color=BLUE]getkword[/color] [color=MAROON]"\nChoose Block Rotation Axis [X/Y/Z] <X>: "[/color])))
               ([color=BLUE]setq[/color] f
                   ([color=BLUE]lambda[/color] ( l [color=BLUE]/[/color] r )
                       ([color=BLUE]setq[/color] r ([color=BLUE]assoc[/color] 50 l))
                       ([color=BLUE]entmod[/color] ([color=BLUE]subst[/color] ([color=BLUE]cons[/color] 50 ([color=BLUE]+[/color] a ([color=BLUE]cdr[/color] r))) r l))
                   )
               )
               ([color=BLUE]setq[/color] f
                   ([color=BLUE]lambda[/color] ( l [color=BLUE]/[/color] e r )
                       ([color=BLUE]setq[/color] e ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] -1 l))
                             r ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 50 l))
                       )
                       ([color=BLUE]vlax-invoke[/color] ([color=BLUE]vlax-ename->vla-object[/color] e) 'rotate3d
                           ([color=BLUE]trans[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 10 l)) e 0)
                           ([color=BLUE]trans[/color]
                               ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 10 l))
                                   ([color=BLUE]if[/color] ([color=BLUE]=[/color] [color=MAROON]"Y"[/color] k)
                                       ([color=BLUE]list[/color] ([color=BLUE]-[/color] ([color=BLUE]sin[/color] r)) ([color=BLUE]cos[/color] r) 0.0)
                                       ([color=BLUE]list[/color] ([color=BLUE]cos[/color] r) ([color=BLUE]sin[/color] r) 0.0)
                                   )
                               )
                               e 0
                           )
                           a
                       )
                   )
               )
           )
           ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
               (f ([color=BLUE]entget[/color] ([color=BLUE]ssname[/color] s ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)))))
           )
       )
   )
   ([color=BLUE]princ[/color])
)
([color=BLUE]vl-load-com[/color]) ([color=BLUE]princ[/color])

 

Tharwat was on to something with his code for rotating blocks based on the drawings UCS

 

BTW, Tharwat's code is not performing a rotation based on the active UCS; I should imagine his code will produce some obscure results since the block insertion point is expressed relative to the block OCS, however in the code is being transformed with respect to the active UCS to the WCS. This will result in the program performing a rotation relative to the WCS X-Axis only if the active UCS is parallel to the OCS plane.

Link to comment
Share on other sites

Thanks Lee Mac, you definitely are very talented and I appreciate what you have done. :D My next task is to sit down this weekend and try to decipher this code and understand how it works -- it may take a bit, but I would like to understand 'how and why' and attempt writing code on my own rather than asking someone to write something for me. I have been using AutoCAD for 15 years and have dabbled very lightly with respect to writing code; macros, simple LiSP routines and minor customization, but seeing this excites me to learn more. It started with me having an idea, I wrote something simple and you my friend took it to a whole new level. Thank you very much for your time.:notworthy:

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