chiimayred Posted July 23, 2013 Posted July 23, 2013 Hey, I am looking to write a lisp routine that, among other things, creates a block and scales it in the x and y but not z (this is a requirement for a coordinate conversion from a client)... I haven't been able to figure it out yet. My thoughts were to add a sort of break in the command where the user can click on the block and change the scales manually, but I don't know how to add such a break. Here's my attempt: (DEFUN C:CC () (COMMAND "_.SCALE" "_ALL" "" '(0 0) 3.28084 "_BLOCK" "1" '(0 0) "_ALL" "" (prompt "change x and y scale of block to 1.025") break "_.explode" ) ) Any help would be appreciated. Thanks, CR Quote
CheSyn Posted July 23, 2013 Posted July 23, 2013 How about something like this? (defun c:cc ( / newscl) (setq blk (car (entsel "\nSelect the block to change the X and Y to 1.025 : "))) (setq newscl 1.025) (entmod (subst (cons 41 newscl) (assoc 41 (entget blk)) (entget blk) ) ) (entmod (subst (cons 42 newscl) (assoc 42 (entget blk)) (entget blk) ) ) (entupd blk) (princ) ) Do you want everything scaled from metric to imperial first, or just the blocks? Either way, I would run this separately. At the break, are you looking to allow the user to manually override the 1.025 default? Quote
chiimayred Posted July 23, 2013 Author Posted July 23, 2013 How about something like this? (defun c:cc ( / newscl) (setq blk (car (entsel "\nSelect the block to change the X and Y to 1.025 : "))) (setq newscl 1.025) (entmod (subst (cons 41 newscl) (assoc 41 (entget blk)) (entget blk) ) ) (entmod (subst (cons 42 newscl) (assoc 42 (entget blk)) (entget blk) ) ) (entupd blk) (princ) ) Do you want everything scaled from metric to imperial first, or just the blocks? Either way, I would run this separately. At the break, are you looking to allow the user to manually override the 1.025 default? I would like everything scaled first. I am looking for the user somehow select the block entity created and scaling the x and y axis without scaling the z. the only way i know how to do this currently is to make the contours into a block, scaling the x and y via the properties and exploding the block. Also, if you could go line by as to what each command means and why you're deciding to go this route... extreme beginner here. Thanks! CR Quote
Tharwat Posted July 23, 2013 Posted July 23, 2013 CheSyn , you can shorten your code to the following besides that , it is a good practice to include if function to check none nil return value from the first variable . (defun c:Test (/ blk newscl) (if (setq blk (car (entsel "\nSelect the block to change the X and Y to 1.025 : "))) (entmod (append (entget blk) (list (cons 41 1.025) (cons 42 1.025)) ))) (princ) ) Quote
CheSyn Posted July 23, 2013 Posted July 23, 2013 Thanks for the heads-up Tharwat! I added a prompt for the if function as well. I didn't realize append and list could be used in conjunction with entmod; it looks much cleaner. Is there a time/place where "subst" would be preferred, and if so, why/where? Chiimayred, I included some comments below. I still feel scaling from metric to imperial would best be done in a separate command. The block will now explode upon completion of the command. (defun c:cc ( / blk newscl) (if (setq blk (car (entsel "\nSelect the block to change : "))) (progn (setq newscl (getreal ; set newscl as a real number (strcat "\nSpecify the scale factor < 1.025 > : "); string prompt ) ) (if ; if newscl does not have a value associated with it, set the value as 1.025 (= nil newscl ) (setq newscl 1.025) ) (entmod ; modifies the properties of the entity (append ; combines the list (entget blk); indicates what entity to edit (list ; create a list of properties to change (cons 41 newscl) (cons 42 newscl) ) ) ) (entupd blk); updates the block (command "_.explode" blk "") ) (prompt "\nNo selection made!") ) (princ) ) Quote
chiimayred Posted July 23, 2013 Author Posted July 23, 2013 I think I may have been a bit misunderstood. After I scale the drawing, I am making the whole drawing into a block. As a result I don't need to select the block as the whole drawing is a block. I am looking for a way to just scale the X and Y axis of that block, as the Z can't be scaled at this point in the conversion. I don't quite understand how cons 41 and cons 42 play into this, but that seems to work. I just need to figure out how to select the one block, scale about cons 41 and cons 42 and then explode it and purge the block. Thanks, CR Quote
Tharwat Posted July 23, 2013 Posted July 23, 2013 Thanks for the heads-up Tharwat! I added a prompt for the if function as well. You're very welcome . I didn't realize append and list could be used in conjunction with entmod; it looks much cleaner. Is there a time/place where "subst" would be preferred, and if so, why? Each function has its own performance and I have used the append function since that I have more than one substitute dxf code to replace otherwise I would go for subst function immediately . Quote
CheSyn Posted July 23, 2013 Posted July 23, 2013 Tharwat, being somewhat new to LISP, I was apprehensive of using lists. Seeing how useful they are, I will look more into them. Chiimayred, cons 41 & 42 are referring to the DXF codes 41 & 42. DXF 41 refers to X-scale, DXF 42 refers to Y-scale, and DXF 43 refers to Z-scale. I did not include DXF 43 because you did not want it altered. What specifically is missing from the posted LISP that you would like added/altered? Quote
chiimayred Posted July 23, 2013 Author Posted July 23, 2013 Tharwat, being somewhat new to LISP, I was apprehensive of using lists. Seeing how useful they are, I will look more into them. Chiimayred, cons 41 & 42 are referring to the DXF codes 41 & 42. DXF 41 refers to X-scale, DXF 42 refers to Y-scale, and DXF 43 refers to Z-scale. I did not include DXF 43 because you did not want it altered. What specifically is missing from the posted LISP that you would like added/altered? Thanks Chesyn, I will have to look into DXF codes. Instead of getting input from the user, just straight up selecting the block created and scaling it. Thanks, both of you for your help so far CR Quote
CheSyn Posted July 23, 2013 Posted July 23, 2013 (edited) Let me know if this is what you are looking for. (defun c:cc ( / sset blk newscl) (if (setq sset (ssget "_x" (list '(0 . "INSERT") (cons 410 (getvar "ctab"))))) (progn (setq blk (ssname sset 0)) (entmod ; modifies the properties of the entity (append ; combines the list (entget blk); indicates what entity to edit (list ; create a list of properties to change (cons 41 1.025) (cons 42 1.025) ) ) ) (entupd blk); updates the block (command "_.explode" blk "") ) (prompt "\nNo blocks in drawing!") ) (princ) ) Edited July 23, 2013 by CheSyn update to use selection set 1 Quote
chiimayred Posted July 23, 2013 Author Posted July 23, 2013 Let me know if this is what you are looking for. (defun c:cc ( / blk newscl) (if (setq blk (car (entsel "\nSelect the block to change : "))) (progn (entmod ; modifies the properties of the entity (append ; combines the list (entget blk); indicates what entity to edit (list ; create a list of properties to change (cons 41 1.025) (cons 42 1.025) ) ) ) (entupd blk); updates the block (command "_.explode" blk "") ) (prompt "\nNo selection made!") ) (princ) ) I'm looking to get rid of the "entsel" portion of it and just have the lisp select the only entity in the drawing without any input from the user. Quote
Tharwat Posted July 23, 2013 Posted July 23, 2013 Let me know if this is what you are looking for. I think the OP does not want to select any block so you need to go with ssget function with the mode "_X" and iterate into the selection set entity names one by one . Quote
CheSyn Posted July 23, 2013 Posted July 23, 2013 Chiimayred, I have updated the code I posted on the previous page. I am assuming, based on your description that there will only be one block in the drawing when you use this command. Tharwat, please check my update and let me know if I'm on the right track (time permitting, of course) Quote
Tharwat Posted July 23, 2013 Posted July 23, 2013 Tharwat, please check my update and let me know if I'm on the right track (time permitting, of course) Almost well , but please find the new changes on your codes into the following routine . Let's hope that the user have all layers UNLOCKED to avoid the rainy error messages . (defun c:test (/ sset blk newscl n) (if (setq sset (ssget "_x" (list '(0 . "INSERT") (cons 410 (getvar "ctab"))))) (repeat (setq n (sslength sset)) (setq blk (ssname sset (setq n (1- n)))) (entmod (append (entget blk) (list (cons 41 1.025) (cons 42 1.025)))) (command "_.explode" blk "") ) (prompt "\nNo blocks in drawing!") ) (princ) ) Quote
CheSyn Posted July 23, 2013 Posted July 23, 2013 Almost well , but please find the new changes on your codes into the following routine . Let's hope that the user have all layers UNLOCKED to avoid the rainy error messages . I see! Just in case more than one block is present, correct? Quote
Tharwat Posted July 23, 2013 Posted July 23, 2013 I see! Just in case more than one block is present, correct? Correct if you are talking about the changes in the codes , but if you are talking about the second paragraph , so I can tell if any of the selected blocks in on locked layer , the code can not change the scale and nor to explode it . Quote
CheSyn Posted July 23, 2013 Posted July 23, 2013 Correct if you are talking about the changes in the codes , but if you are talking about the second paragraph , so I can tell if any of the selected blocks in on locked layer , the code can not change the scale and nor to explode it . Yes, I was responding to the first paragraph. But I will keep both points in mind Quote
chiimayred Posted July 23, 2013 Author Posted July 23, 2013 (defun c:utm2bp (/ blk) (command "_.scale" "_all" "" '(0 0) 3.28084 "_block" "1" '(0 0) "_all" "" ) (if (setq sset (ssget "_x" (list '(0 . "INSERT") (cons 410 (getvar "ctab"))))) (repeat (setq n (sslength sset)) (setq blk (ssname sset (setq n (1- n)))) (entmod (append (entget blk) (list (cons 41 1.025) (cons 42 1.025)))) (command "_.explode" blk "") ) (prompt "\nNo blocks in drawing!") ) (princ) ) here's what it looks like... i keep on getting a "No Blocks in Drawing" prompt when I run this lisp... Quote
Lee Mac Posted July 23, 2013 Posted July 23, 2013 I would suggest the following: (defun c:utm2bp ( / blk sel ) (if (= 1 (getvar 'cvport)) (princ "\nCommand only available in Modelspace.") (if (setq sel (ssget "_X" '((410 . "Model")))) (progn (setq blk 0) (while (tblsearch "block" (itoa (setq blk (1+ blk))))) (setq blk (itoa blk)) (command "_.scale" sel "" "_non" '(0 0) 3.28084 "_.-block" blk "_non" '(0 0) sel "" "_.-insert" blk "_non" '(0 0) 1.025 1.025 0.0 "_.explode" (entlast) "_.-purge" "_b" blk "_N" ) ) (princ "\nNo objects found in Modelspace.") ) ) (princ) ) Quote
chiimayred Posted July 23, 2013 Author Posted July 23, 2013 I would suggest the following: (defun c:utm2bp ( / blk sel ) (if (= 1 (getvar 'cvport)) (princ "\nCommand only available in Modelspace.") (if (setq sel (ssget "_X" '((410 . "Model")))) (progn (setq blk 0) (while (tblsearch "block" (itoa (setq blk (1+ blk))))) (setq blk (itoa blk)) (command "_.scale" sel "" "_non" '(0 0) 3.28084 "_.-block" blk "_non" '(0 0) sel "" "_.-insert" blk "_non" '(0 0) 1.025 1.025 0.0 "_.explode" (entlast) "_.-purge" "_b" blk "_N" ) ) (princ "\nNo objects found in Modelspace.") ) ) (princ) ) Hey, I am currently trying it out... could you explain the use of the while command, tblsearch, progn and this little bit of code (setq blk 0) (while (tblsearch "block" (itoa (setq blk (1+ blk))))) (setq blk (itoa blk)) Thanks for your time, help and patience. 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.