RubberDinero Posted September 12, 2016 Share Posted September 12, 2016 I'm still learning Lisps and am in the need of a function. I'm not going to say what i need it for, i want to try and write the lisp from the input of this forum. I need to know how to store the polyline width of a user selected polyline. for example, if i select a polyline and i run my lisp, or vice versa, the lisp will store the global width of the selected polyline into memory. (setq PW (ssget "polyline width") After i get this info, i will post my lisp and what it does. After you guys can share how you would have done it instead. and it will probably be better then my way. thanks ahead of time. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 12, 2016 Share Posted September 12, 2016 Assuming you are referring to the global (constant) width of an LWPolyline, the width value is associated with DXF group 43: (defun c:test ( / ent enx ) (if (setq ent (car (entsel))) (if (= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent))))) (princ (strcat "\nThe polyline width is " (rtos (cdr (assoc 43 enx))))) (princ "\nThe selected object is not a polyline.") ) (princ "\nNo object selected.") ) (princ) ) Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 12, 2016 Author Share Posted September 12, 2016 (defun c:test ( / ent enx ) (if (setq ent (car (entsel))) (if (= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent))))) (princ (strcat "\nThe polyline width is " (rtos (cdr (assoc 43 enx))))) (princ "\nThe selected object is not a polyline.") ) (princ "\nNo object selected.") ) (princ) ) this is kind of what i'm looking for, and maybe i can take it from here. instead of String output, i want to put the value into memory to use within another command. let me take a shot at it, and if i can't figure it out, i'll reach out for more help. Thanks! Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 12, 2016 Author Share Posted September 12, 2016 Assuming you are referring to the global (constant) width of an LWPolyline, the width value is associated with DXF group 43:[/code] Thanks to YOU! I did it!!! probably not as good as you would have done it, but i did it! (defun c:px nil (if (setq ent (car (entsel))) (if (= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent))))) (setq pw (rtos (cdr (assoc 43 enx))))) ) (command "explode" ent) (command "pedit" "m" "p" "" "w" pw"") (princ) ) This lisp xplodes the polyline while keeping the width. Technically, it gets the width, stores it in memory, explodes the LWPOLYLINE, converts the lines to LWPOLYLINE then adds the width of "pw" it just clicked that i may need to add a "peditaccept" just incase most people have it set to 0. I am curious as to how the better approach would be. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted September 13, 2016 Share Posted September 13, 2016 Rather than calling it save in memory which is correct, you are saving a "Global" variable for further use in the same dwg session. The only problem may be if you write another program that uses pw. You can save variables within the dwg such as USERI1-5 5 integers, USERR1-5 5 reals But again they can be overridden. If saving global variables maybe use a prefix GLBpw and keep a list somewhere of what you have used with a description. (setvar "userr1" 0.25) ; sets userr1 value (getvar "userr1") ; retrieves the value (defun c:px ( / ent) ; implies ent is a local variable and will not be saved at end of defun just me added a space after pw (command "pedit" "m" "p" "" "w" [color=red]pw ""[color=red])[/color] [/color] Almost forgot if your wanting to save a lot of variables and use them across drawings then save to a simple txt file and just read as required. Make it a library defun in acaddoc.lsp then can use when ever. Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 13, 2016 Author Share Posted September 13, 2016 Rather than calling it save in memory which is correct, you are saving a "Global" variable for further use in the same dwg session. Thanks. I'm still learning Lisp and kind of understand the memory within the lisp. i used nil, because i wasn't 100% confident. i do understand the importance of it, so i'll add it just in case other lisps end up using "pw" as a variable. Thanks everyone. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 13, 2016 Share Posted September 13, 2016 Thanks to YOU! I did it!!! probably not as good as you would have done it, but i did it! Well done! I am curious as to how the better approach would be. There are numerous ways in which the code could be developed further in order to account for and mitigate against every possibility of an error - an initial improvement would be to account for a null or invalid selection, e.g.: (defun c:px ( / cmd ent enx ped ) (if (setq ent (car (entsel))) (if (= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent))))) (progn (setq cmd (getvar 'cmdecho) ped (getvar 'peditaccept) ) (setvar 'cmdecho 0) (setvar 'peditaccept 1) (command "_.explode" ent "_.pedit" "_m" "_p" "" "_w" (cdr (assoc 43 enx)) "" ) (setvar 'peditaccept ped) (setvar 'cmdecho cmd) ) (princ "\nThe selected object is not an LWPolyline.") ) (princ "\nNo object selected.") ) (princ) ) But one could go further to account for locked layers, with checks to ensure that valid objects were generated following the call to the EXPLODE command prior to invoking the PEDIT command. Quote Link to comment Share on other sites More sharing options...
Grrr Posted September 13, 2016 Share Posted September 13, 2016 But one could go further to account for locked layers, with checks to ensure that valid objects were generated following the call to the EXPLODE command prior to invoking the PEDIT command. Hi Lee, I was curious would it be possible to account for locked layer with the entsel/nentsel approach, without using the: (ssget "_+.:E:S:L") I thought that the only way would be acessing entity's layer definition and retrieve from there if its status is locked. So the above line shows how much this issue is simplified. Another way I could think of is something like: (setq s (ssadd)) (ssadd (car (entsel "\nSelect entity: ")) s) (sssetfirst nil s) (/= 0 (sslength (ssget "_.+:I:L"))); here we can check if the selected entity is on locked layer (sssetfirst nil nil) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 13, 2016 Share Posted September 13, 2016 Here is an example: (defun c:px ( / cmd ent enx ped ) (setvar 'errno 0) (while (/= 52 (getvar 'errno)) (setvar 'errno 0) (setq ent (car (entsel "\nSelect polyline <exit>: "))) (cond ( (= 7 (getvar 'errno)) (prompt "\nMissed, try again.") ) ( (null ent) (prompt "\nExit.") ) ( (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent))))) (prompt "\nSelected object is not an LWPolyline.") ) ( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx))))))) (prompt "\nSelected polyline is on a locked layer.") ) ( (setq cmd (getvar 'cmdecho) ped (getvar 'peditaccept) ) (setvar 'cmdecho 0) (setvar 'peditaccept 1) (command "_.explode" ent "_.pedit" "_m" "_p" "" "_w" (cdr (assoc 43 enx)) "" ) (setvar 'peditaccept ped) (setvar 'cmdecho cmd) ) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
Grrr Posted September 13, 2016 Share Posted September 13, 2016 Thank you, Lee I've just wrote something similar: (defun C:test ( / e enx ) (while (not (and (setq e (car (entsel "\nSelect LWpolyline on non-locked layer: "))) (eq (cdr (assoc 0 (setq enx (entget e)))) "LWPOLYLINE") (/= (cdr (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8 enx)))))) 4) ) ) e ) (print enx); if successful (princ) ) I might need to study deeper this logand function as its not the first time I see its in use. I think I'm done writing codes for today. Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 13, 2016 Author Share Posted September 13, 2016 Here is an example:(defun c:px ( / cmd ent enx ped ) (setvar 'errno 0) (while (/= 52 (getvar 'errno)) (setvar 'errno 0) (setq ent (car (entsel "\nSelect polyline <exit>: "))) (cond ( (= 7 (getvar 'errno)) (prompt "\nMissed, try again.") ) ( (null ent) (prompt "\nExit.") ) ( (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent))))) (prompt "\nSelected object is not an LWPolyline.") ) ( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx))))))) (prompt "\nSelected polyline is on a locked layer.") ) ( (setq cmd (getvar 'cmdecho) ped (getvar 'peditaccept) ) (setvar 'cmdecho 0) (setvar 'peditaccept 1) (command "_.explode" ent "_.pedit" "_m" "_p" "" "_w" (cdr (assoc 43 enx)) "" ) (setvar 'peditaccept ped) (setvar 'cmdecho cmd) ) ) ) (princ) ) WOW!!! Now that is the right way to do it!!! on a side note, i keep re-writing and re-writing my code cuz i kept getting an error. turns out the global was not set and i kept getting an error. after i ran yours and it also didn't work, i knew something was wrong. never did i think to check if the global width was set. maybe there could be a variable to select either starting width or ending width if global is not set. Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 13, 2016 Author Share Posted September 13, 2016 (command "_.explode" ent "_.pedit" "_m" "_p" "" "_w" (cdr (assoc 43 enx)) "" ) I learn more from your code then from the book I'm reading. I see now that I don't need to setq pw for assoc 43, i can simply invoke assoc 43 when i need that number. I'm still a caveman in coding, but i'm trying to make that fire burn. that should be my CADTutor motto. lol. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 13, 2016 Share Posted September 13, 2016 (/= (cdr (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8 enx)))))) 4) I might need to study deeper this logand function as its not the first time I see its in use. Indeed - DXF group 70 is typically bit-coded and therefore may not be equal to 4 if locked with other properties set (for example, test your code with an object residing on a locked layer which is frozen in new viewports). I learn more from your code then from the book I'm reading. That's great to hear! Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 13, 2016 Author Share Posted September 13, 2016 (command "_.explode" ent "_.pedit" "_m" "_p" "" "_w" (cdr (assoc 43 enx)) "" ) Where the following code is (cdr (assoc 43 enx)) would it be possible to make that a variable and add an (if parameter stating that if the Constant width is null and (cdr (assoc 40)) is equal to (cdr (assoc 41) then width would be set to starting width. If different, ask user input to choose either start or end i.e. (initget "Start End" where start is (cdr (assoc 40)) and end is (cdr (assoc 41)) i think that would wrap up this lisp of all errors. Quote Link to comment Share on other sites More sharing options...
Grrr Posted September 14, 2016 Share Posted September 14, 2016 Indeed - DXF group 70 is typically bit-coded and therefore may not be equal to 4 if locked with other properties set (for example, test your code with an object residing on a locked layer which is frozen in new viewports). That was exactly my thought, I wasn't sure how to structure your answer as a question in my previous post, but you answered already. (english is not my first langugage). Thank you for elaborating! Quote Link to comment Share on other sites More sharing options...
broncos15 Posted September 14, 2016 Share Posted September 14, 2016 Where the following code is (cdr (assoc 43 enx)) would it be possible to make that a variable and add an (if parameter stating that if the Constant width is null and (cdr (assoc 40)) is equal to (cdr (assoc 41) then width would be set to starting width. If different, ask user input to choose either start or end i.e. (initget "Start End" where start is (cdr (assoc 40)) and end is (cdr (assoc 41)) i think that would wrap up this lisp of all errors. Hint, look at dxf group codes 40 and 41 to find the starting and ending widths. Just need to put in a conditional statement where if dxf group code 43 is null, then move onto the 40 or 41 depending on your preference. Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 14, 2016 Author Share Posted September 14, 2016 (defun c:px2 ( / cmd ent enx ped pw1 ) (setvar 'errno 0) (while (/= 52 (getvar 'errno)) (setvar 'errno 0) (setq ent (car (entsel "\nSelect polyline <exit>: "))) (cond ( (= 7 (getvar 'errno)) (prompt "\nMissed, try again.") ) ( (null ent) (prompt "\nExit.") ) ( (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent))))) (prompt "\nSelected object is not an LWPolyline.") ) ( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx))))))) (prompt "\nSelected polyline is on a locked layer.") ) ( (setq cmd (getvar 'cmdecho) ped (getvar 'peditaccept) ) (setvar 'cmdecho 0) (setvar 'peditaccept 1) [size="2"] [b][color="red"] (if (= (cdr (assoc 43 enx)) nil) (if (= (cdr (assoc 41 enx)) (cdr (assoc 40 enx))) (setq pw1 (cdr (assoc 40 enx))) (initget "Start End (cdr (assoc 40 enx)) (cdr (assoc 41 enx))) (setq pw1 (getkword "\nEnter an Option (Start/End): ")) ) (setq pw1 (cdr (assoc 43 enx))) ) (command "_.explode" ent "_.pedit" "_m" "_p" "" "_w" pw1 "" )[/color][/b][/size] (setvar 'peditaccept ped) (setvar 'cmdecho cmd) ) ) ) (princ) ) I tried my caveman coding, but is it not possible to have an "IF" statement within an "IF" statement? or did I write the "(=" statement wrong? Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 14, 2016 Author Share Posted September 14, 2016 (defun c:px2 ( / cmd ent enx ped pw1 ) (setvar 'errno 0) (while (/= 52 (getvar 'errno)) (setvar 'errno 0) (setq ent (car (entsel "\nSelect polyline <exit>: "))) (cond ( (= 7 (getvar 'errno)) (prompt "\nMissed, try again.") ) ( (null ent) (prompt "\nExit.") ) ( (/= "LWPOLYLINE" (cdr (assoc 0 (setq enx (entget ent))))) (prompt "\nSelected object is not an LWPolyline.") ) ( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx))))))) (prompt "\nSelected polyline is on a locked layer.") ) ( (setq cmd (getvar 'cmdecho) ped (getvar 'peditaccept) ) (setvar 'cmdecho 0) (setvar 'peditaccept 1) (if (= (cdr (assoc 43 enx)) nil) (if (= (cdr (assoc 41 enx)) (cdr (assoc 40 enx))) (setq pw1 (cdr (assoc 40 enx))) ((initget "Start End (cdr (assoc 40 enx)) (cdr (assoc 41 enx))") (setq pw1 (getkword "\nEnter an Option (Start/End): "))) ) (setq pw1 (cdr (assoc 43 enx))) ) (command "_.explode" ent "_.pedit" "_m" "_p" "" "_w" pw1 "" ) (setvar 'peditaccept ped) (setvar 'cmdecho cmd) ) ) ) (princ) ) HAD FORGOT TO PUT A END QUOTE!!! LOL! But now when i do getkword it doesn't accept Start or End, it says invalid. Quote Link to comment Share on other sites More sharing options...
RubberDinero Posted September 14, 2016 Author Share Posted September 14, 2016 But now when i do getkword it doesn't accept Start or End, it says invalid. i know see that initget are the acceptable keywords. now i need to set up the if statements. Quote Link to comment Share on other sites More sharing options...
Grrr Posted September 14, 2016 Share Posted September 14, 2016 RubberDinero, check this: http://www.lee-mac.com/promptwithdefault.html then check this (especially the last example code - for your case): http://www.afralisp.net/autolisp/tutorials/conditionals.php Quote Link to comment Share on other sites More sharing options...
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.