Stermaj Posted April 24, 2009 Posted April 24, 2009 I have a model in autocad where i want to have autolisp select a group of blocks defined either by location relative to the WCS or a customized UCS, and then rotate them 90 degrees relative to the current UCS. I am trying to use SSGET to select the blocks, but I cant seem to get the syntax right. For example, I want to be able to have autocad select all objects where their base points are located at Z > 0. I was able to define the selection set in both filters and in qselect but I dont see any way to have autocad run those functions through the command prompt making those efforts futile. Any help would greatly be appreciated. Quote
Lee Mac Posted April 24, 2009 Posted April 24, 2009 Perhaps: (defun c:selObj (/ ss ent) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB")(cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not (> (cadddr (assoc 10 (entget ent))) 0)) (ssdel ent ss))) (if (not (zerop (sslength ss))) (command "_rotate" ss "" pause pause))) (princ "\n<!> No Blocks Found <!>")) (princ)) Quote
Stermaj Posted April 24, 2009 Author Posted April 24, 2009 Wow that did exactly what i needed it to do. Thank you so much for your help! Quote
Lee Mac Posted April 24, 2009 Posted April 24, 2009 No Probs, If you have any questions on the code - just shout Lee Quote
Stermaj Posted April 24, 2009 Author Posted April 24, 2009 I modified your code for each axis by changing the CADDDR to CADDR and CADR so I can use it for each axis as necessary. I noticed though that if a block is moved by one function to say, below the z axis, running the code again still selects that block even though its z position is negative now. Am i missing something that would clear the list and have it rescan to determine which blocks meet the criteria to be selected? Quote
Lee Mac Posted April 24, 2009 Posted April 24, 2009 Not sure I quite follow you - the selection set is localised, so is set to nil upon completion of the function. Quote
Stermaj Posted April 26, 2009 Author Posted April 26, 2009 I am animating a rubiks cube, and I am writing commands to rotate sides. Basically, I loaded both lisp files and then i manually run each command. running the oranger function rotates all the blocks located at higher than 10 in the z axis (the orange side of the cube), then i run redr and it rotates the blocks found lower than -10 in the y axis (the red side of the cube). if i run oranger again, it selects the same block set it did the first time oranger ran even though redr switched blocks around. What this means for the cube is, some blocks that are no longer on the orange face are still being selected for some reason, while others on the orange side are not. The blocks that do get selected end up being slid though blocks that are stationary. The following is the code i have for the selection and rotation. the c:COLORucs commands call another function that simply establishes a ucs so the rotation occurs in the correct plane. Thanks again for all your help! -Jon (defun c:yellowr () (setq oldosn (getvar "osmode")) (setvar "osmode" 0) (c:yellowucs) (setq pt1 (LIST 0 0 0)) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB")(cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not ( (ssdel ent ss))) (if (not (zerop (sslength ss))) (repeat 9 (command "_rotate" ss "" pt1 -10) ) ) ) (princ "\n No Blocks Found ")) (setvar "osmode" oldosn) ) (defun c:oranger () (setq oldosn (getvar "osmode")) (setvar "osmode" 0) (c:orangeucs) (setq pt1 (LIST 0 0 0)) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB")(cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not (> (cadddr (assoc 10 (entget ent))) 10)) (ssdel ent ss))) (if (not (zerop (sslength ss))) (repeat 9 (command "_rotate" ss "" pt1 -10) ) ) ) (princ "\n No Blocks Found ")) (setvar "osmode" oldosn) ) (defun c:redr () (setq oldosn (getvar "osmode")) (setvar "osmode" 0) (c:reducs) (setq pt1 (LIST 0 0 0)) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB")(cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not ( (ssdel ent ss))) (if (not (zerop (sslength ss))) (repeat 9 (command "_rotate" ss "" pt1 -10) ) ) ) (princ "\n No Blocks Found ")) (setvar "osmode" oldosn) ) (defun c:purpler () (setq oldosn (getvar "osmode")) (setvar "osmode" 0) (c:purpleucs) (setq pt1 (LIST 0 0 0)) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB")(cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not (> (caddr (assoc 10 (entget ent))) 10)) (ssdel ent ss))) (if (not (zerop (sslength ss))) (repeat 9 (command "_rotate" ss "" pt1 -10) ) ) ) (princ "\n No Blocks Found ")) (setvar "osmode" oldosn) ) Quote
Lee Mac Posted April 26, 2009 Posted April 26, 2009 OK, try this - I have commented the code as to the possible errors: (defun c:yellowr (/ oldosn ss) ;; Make sure you localise the variables! (setq oldosn (getvar "osmode")) (setvar "osmode" 0) (yellowucs) ; Shouldn't need (c:xxx), just (xxx) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB") (cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not (< (cadddr (assoc 10 (entget ent))) -10)) ;; Z value less than -10 (ssdel ent ss))) (if (not (zerop (sslength ss))) (repeat 9 (command "_rotate" ss "" '(0 0 0) -10)))) ; Don't feel the need for variable "pt1" (princ "\n<!> No Blocks Found <!>")) (setvar "osmode" oldosn) (princ)) ; Make sure you exit cleanly (defun c:oranger (/ oldosn ss) (setq oldosn (getvar "osmode")) (setvar "osmode" 0) (orangeucs) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB") (cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not (> (cadddr (assoc 10 (entget ent))) 10)) ;; Z value greater than 10 (ssdel ent ss))) (if (not (zerop (sslength ss))) (repeat 9 (command "_rotate" ss "" '(0 0 0) -10)))) (princ "\n<!> No Blocks Found <!>")) (setvar "osmode" oldosn) (princ)) (defun c:redr (/ oldosn ss) (setq oldosn (getvar "osmode")) (setvar "osmode" 0) (reducs) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB") (cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not (< (caddr (assoc 10 (entget ent))) -10)) ;; Y value less than -10 (ssdel ent ss))) (if (not (zerop (sslength ss))) (repeat 9 (command "_rotate" ss "" '(0 0 0) -10)))) (princ "\n<!> No Blocks Found <!>")) (setvar "osmode" oldosn) (princ)) (defun c:purpler (/ oldosn ss) (setq oldosn (getvar "osmode")) (setvar "osmode" 0) (purpleucs) (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB") (cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) (progn (foreach ent (mapcar 'cadr (ssnamex ss)) (if (not (> (caddr (assoc 10 (entget ent))) 10)) ;; Y value greater than 10 (ssdel ent ss))) (if (not (zerop (sslength ss))) (repeat 9 (command "_rotate" ss "" '(0 0 0) -10)))) (princ "\n<!> No Blocks Found <!>")) (setvar "osmode" oldosn) (princ)) Make sure that you localise your variables so that they are set to nil when the program completes. You have used "ss" in every code, so this could be causing the problem. Also, remember to add "princ" to exit cleanly. Let me know how you get on. Lee Quote
Stermaj Posted April 26, 2009 Author Posted April 26, 2009 I tried that, its still shifting the wrong blocks. It doesnt seem to do it consistently though. For every function, if its the 1st one i try, then it works, but things break down once i start doing several after eachother. Is there a way i can send u the autocad file itself? its too large for the forum limits. UCS.lsp rotation.lsp Quote
Lee Mac Posted April 26, 2009 Posted April 26, 2009 I would use this: You don't need a new ucs function for every colour if they are all doing the same thing - just one function requiring an argument. Also, the variable ss was not localised in the first function. One more thing, why the repeats? why not just rotate by 90 degrees? rotation.lsp Quote
Stermaj Posted April 27, 2009 Author Posted April 27, 2009 Well for the UCS's i plan on having other commands refer to them so i thought i might as well make it a separate function but i guess i can switch those back. as far as the repeats goes, i wanted to give it a frame rate so you can watch the sides as they turn instead of it instantly shifting. I did correct the initializing ss in the 1st function though, thanks for the catch. In your original code, i am wondering, what does the part of the code in that first if statement do: (if (setq ss (ssget "X" (list (cons 0 "INSERT") (if (getvar "CTAB")(cons 410 (getvar "CTAB")) (cons 67 (- 1 (getvar "TILEMODE"))))))) I know ssget "x" selects everything, but i dont follow what the rest does. Thanks again for all your help, i really appreciate it. Is there a way i can send u the dwg file? Quote
Lee Mac Posted April 27, 2009 Posted April 27, 2009 You can zip the file, or send it to my email address which I shall PM to you As for the other bit of code: [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] ss [b][color=RED]([/color][/b][b][color=BLUE]ssget[/color][/b] [b][color=#ff00ff]"X"[/color][/b] [i][color=#990099]; Scan the whole Database[/color][/i] [b][color=RED]([/color][/b][b][color=BLUE]list[/color][/b] [i][color=#990099]; Make a Filter List[/color][/i] [b][color=RED]([/color][/b][b][color=BLUE]cons[/color][/b] [b][color=#009900]0[/color][/b] [b][color=#ff00ff]"INSERT"[/color][/b][b][color=RED])[/color][/b] [i][color=#990099]; Get Blocks (and Xrefs)[/color][/i] [b][color=RED]([/color][/b][b][color=BLUE]if[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]getvar[/color][/b] [b][color=#ff00ff]"CTAB"[/color][/b][b][color=RED])[/color][/b] [i][color=#990099]; If there is a variable CTAB[/color][/i] [b][color=RED]([/color][/b][b][color=BLUE]cons[/color][/b] [b][color=#009900]410[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]getvar[/color][/b] [b][color=#ff00ff]"CTAB"[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [i][color=#990099]; Use it[/color][/i] [b][color=RED]([/color][/b][b][color=BLUE]cons[/color][/b] [b][color=#009900]67[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]-[/color][/b] [b][color=#009900]1[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]getvar[/color][/b] [b][color=#ff00ff]"TILEMODE"[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [i][color=#990099]; Otherwise use TILEMODE[/color][/i] AutoCAD R14 didn't have CTAB, so to set the space you have to use TILEMODE, hence I have accounted for all versions. Quote
Lee Mac Posted April 27, 2009 Posted April 27, 2009 I can't seem to PM you - I think you may have restricted it on your accout - try zipping the dwg file. Quote
Stermaj Posted April 27, 2009 Author Posted April 27, 2009 I posted the file to a website i run: nyu.edu/clubs/shalhevet/Cube_8.dwg Quote
Lee Mac Posted April 27, 2009 Posted April 27, 2009 I think I may have cracked it-- didn't need the file after all really. I think there may be one thing we're overlooking, when you retrieve the selectionset, the points that are referenced and tested in the IF statement are in WCS not UCS (just thought you might not be aware).... Not sure if that affects things.. Quote
Stermaj Posted April 27, 2009 Author Posted April 27, 2009 I planned for that, i actually reset the UCS to the WCS before running ssget just in case there would be a conflict, and then later only when it does the rotation does it restore the specific ucs for that case, and that really is only to establish the plane of rotation. Quote
Lee Mac Posted April 27, 2009 Posted April 27, 2009 Well I'm stumped as to why its not performing as you want it to. There is nothing else I can think of that would be causing it to fail. - when you run each function, it is the same as if you had run only the one, so I can't see how one function would be affecting the other. Quote
Stermaj Posted April 27, 2009 Author Posted April 27, 2009 Could it be that the coordinates of each block aren't being updated in the database? If so, is there possibly another set of criteria for the selection process? Quote
Lee Mac Posted April 27, 2009 Posted April 27, 2009 Could it be that the coordinates of each block aren't being updated in the database? If so, is there possibly another set of criteria for the selection process? No I don't think that would be the case. I'm puzzled, as each function is a stand-alone function, then you could have manually rotated those blocks, and then run the function and it would be the same circumstances. Perhaps try this - rotate the blocks manually as if you were running one of the functions, then try running a different function. Other than that, i'm out of ideas Lee Quote
Stermaj Posted April 27, 2009 Author Posted April 27, 2009 Yeah, rotating the blocks manually, and then running one of the functions still causes problems. could the lookup criteria be the issue? 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.