dortega4269 Posted May 10, 2013 Posted May 10, 2013 (edited) 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 May 15, 2013 by dortega4269 Quote
dortega4269 Posted May 15, 2013 Author Posted May 15, 2013 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; Quote
dortega4269 Posted May 15, 2013 Author Posted May 15, 2013 (edited) 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 May 16, 2013 by dortega4269 Quote
satishrajdev Posted May 16, 2013 Posted May 16, 2013 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) ) Quote
dortega4269 Posted May 16, 2013 Author Posted May 16, 2013 Thanks Satishrajdev! I'll be sure to check this out first thing when I get back to the office in a couple hours. Quote
dortega4269 Posted May 16, 2013 Author Posted May 16, 2013 :glare:So... now i get this prompt: Command: rbSelect objects: 1 found Select objects: No Endpoint found for specified point. Invalid point. Quote
Tharwat Posted May 16, 2013 Posted May 16, 2013 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 ? Quote
alanjt Posted May 16, 2013 Posted May 16, 2013 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) ) Quote
dortega4269 Posted May 16, 2013 Author Posted May 16, 2013 (edited) 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 May 16, 2013 by dortega4269 Added link and additional information Quote
Tharwat Posted May 16, 2013 Posted May 16, 2013 Your video is private and it is not public to be able to watch the suspense Quote
dortega4269 Posted May 16, 2013 Author Posted May 16, 2013 Your video is private and it is not public to be able to watch the suspense Tharwat, hahaha I guess that would limit the amount of viewers... it's now set to Public. Quote
Tharwat Posted May 16, 2013 Posted May 16, 2013 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) ) Quote
Lee Mac Posted May 16, 2013 Posted May 16, 2013 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]) Quote
dortega4269 Posted May 16, 2013 Author Posted May 16, 2013 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. Quote
alanjt Posted May 16, 2013 Posted May 16, 2013 I leave for lunch and every thing gets sorted. Nicely done, Lee. Quote
Lee Mac Posted May 16, 2013 Posted May 16, 2013 I leave for lunch and every thing gets sorted. Nicely done, Lee. Cheers dude Quote
dortega4269 Posted May 16, 2013 Author Posted May 16, 2013 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. Quote
Lee Mac Posted May 16, 2013 Posted May 16, 2013 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. Quote
dortega4269 Posted May 17, 2013 Author Posted May 17, 2013 Thanks Lee Mac, you definitely are very talented and I appreciate what you have done. 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. Quote
Recommended Posts
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.