BrianTFC Posted February 6, 2012 Posted February 6, 2012 Hi All, I have the wonderful Lisp routine that mfuccaro wrote back in 2003 called Offset Polylines "POF" for short. like I've said before in my other threads I'm just learning how to write and modify Lisp routines, I've manage to modify this routine to offset to the current layer but i can't figure out how to get it to remember the last offset distance. Can anyone help me please. thanks, Brian ;| OFFSET POLYLINES mfuccaro@hotmail.com September 2003 |; (defun c:pof( / plines ; selection set of polylines ext ; extrnal point dist ; distance to offset poly ; a polyline from plines plist ; the list of poly del ; polyline to delete int ; internal point i) (command "undo" "begin") (princ "select polylines") (setq plines (ssget) i 0 ext (getvar "limmax") dist (getdist "distance ")) (repeat (sslength plines) (setq poly (ssname plines i)) (setq plist (entget poly)) (command "offset" dist poly ext "") (setq del (entlast) int (polar (cdr (assoc 10 (entget del))) (angle (cdr (assoc 10 (entget del))) (cdr (assoc 10 plist))) (* 2 (distance (cdr (assoc 10 plist)) (cdr (assoc 10 (entget del))))))) (command "offset" dist poly int "") (command "_.change" (entlast) "" "_p" "_la" (getvar 'clayer) "") (entdel del) (setq i (1+ i))) (command "undo" "end") (princ) ) Quote
irneb Posted February 7, 2012 Posted February 7, 2012 Basically this is the same as for any other "default" input. You need to save the distance into a global variable, or some other place which doesn't get cleared after the routine completes. Then to show the distance you change the message in the getdist to something like: (strcat "distance : ") The the less-than & greater-than is a convention and doesn't actually mean much other than showing the user that this is the default. Next you need to check if the distance input was a new distance, or if the user just pressed Enter/Space. On the getdist function a nill is returned if no distance is input. So: (if (not *saved-dist*) (setq *saved-dist* 0.0)) ;Initialize the default distance to 0 if it doesn't exist (if (setq dist (getdist (strcat "distance <" (rtos *saved-dist*) ">: "))) (setq *saved-dist* dist) ;A new distance was given, so save it into the global var (setq dist *saved-dist*) ;Enter/space pressed, so retrieve the global var ) Continue as normal, since the dist variable now holds whatever the user wanted (either the new distance or the value of the default). Note I use the lisp convention of prefixing & suffixing asterisks (*) onto the global variable's name. That's just a convention & not needed, but it is considered good practise to differentiate such variables. Also note this would only make a default per DWG per session. To have a default over multiple DWG's per session or to have a default even over multiple sessions you'd need to save the global value to something else (like a file, the black-board, user sysvar, or registry). Quote
MSasu Posted February 7, 2012 Posted February 7, 2012 (edited) One solution is to not use a global variable to store the offset distance - will be preserved between runs. Just take care to don't reuse that name in other routine. ;| OFFSET POLYLINES [email="mfuccaro@hotmail.com"]mfuccaro@hotmail.com[/email] September 2003 |; (defun c:pof( / plines ; selection set of polylines ext ; extrnal point dist ; distance to offset poly ; a polyline from plines plist ; the list of poly del ; polyline to delete int ; internal point i) (command "undo" "begin") (princ "select polylines") (setq plines (ssget) i 0 ext (getvar "limmax") dist (getdist [color=blue](strcat "distance <" (if olddist (rtos olddist) ;use old value as default "") ">")[/color])) [color=blue] (if (not dist) (setq dist olddist)) ;reuse old distance if user press <Enter> [/color] (repeat (sslength plines) (setq poly (ssname plines i)) (setq plist (entget poly)) (command "offset" dist poly ext "") (setq del (entlast) int (polar (cdr (assoc 10 (entget del))) (angle (cdr (assoc 10 (entget del))) (cdr (assoc 10 plist))) (* 2 (distance (cdr (assoc 10 plist)) (cdr (assoc 10 (entget del))))))) (command "offset" dist poly int "") (command "_.change" (entlast) "" "_p" "_la" (getvar 'clayer) "") (entdel del) (setq i (1+ i))) (command "undo" "end") [color=blue] (setq olddist dist) ;preserve current distance for next run [/color] (princ) ) Regards, Mircea Edited February 7, 2012 by MSasu fixed statement Quote
pBe Posted February 7, 2012 Posted February 7, 2012 or (setq plines (ssget) i 0 ext (getvar "limmax") dist [color=blue][b](cond ((getdist (strcat "\nEnter Distance [Enter to accept: <" (rtos (setq dist (getvar 'Offsetdist)) 2 2) ">: " ) ) ) (dist) )[/b][/color]) As posted on AUGI Quote
MSasu Posted February 7, 2012 Posted February 7, 2012 @pBe: I really like this solution; I will use this from now on my code. Thank you for sharing it! Regards, Mircea Quote
pBe Posted February 7, 2012 Posted February 7, 2012 @pBe: I really like this solution; I will use this from now on my code. Thank you for sharing it! Regards, Mircea Make it so Mircea, After all, thats what this forum is all about [sharing] Quote
Lee Mac Posted February 7, 2012 Posted February 7, 2012 Mircea, You may be interested in this brief article Lee Quote
MSasu Posted February 7, 2012 Posted February 7, 2012 I will read it, for sure. Thank you! Regards, Mircea Quote
Lee Mac Posted February 7, 2012 Posted February 7, 2012 I will read it, for sure. Thank you! You're welcome! Though I'm sure it contains nothing that you don't already know Quote
BrianTFC Posted February 7, 2012 Author Posted February 7, 2012 thanks, for all your help that worked perfectly.... Quote
irneb Posted February 7, 2012 Posted February 7, 2012 One solution is to not use a global variable to store the offset distance - will be preserved between runs. Just take care to don't reuse that name in other routine.Mircea, your code in post #3 is actually using a global variable. The olddist is global, it's just not indicated as such by the asterisk convention. As I've stated, the asterisk is simply a convention, it's not needed. But, IMO pBe's solution is the most effective for this scenario as it uses the offset command's built-in default. Not to mention it's the most succinct It's just that the getvar idea would only work in some instances, i.e. where acad has a built-in default which is saved as a sysvar. Otherwise you're stuck with using a global or some other variable (e.g. as ldata in the drawing to be persistend for that DWG even over separate sessions; or using vl-bb-set & vl-bb-get to have a default across all open DWG's in the current session; or a file/registry to have a persistent default across all DWG's and all sessions. It all depends on what you want to achieve. Probably pBe's code is perfect for this case, but obviously it might need something else in another case. Though the global var default could easily be implemented in a similar cond statement to pBe's code. And actually I'd like to revise my original one thus as well: (setq dist ((lambda (def / d) (cond ((setq d (getdist (strcat "Enter distance <" (rtos def) ">: "))) (setq *saved-dist* d) ) (def) ) ) (if *saved-dist* *saved-dist* (setq *saved-dist* 0.)) ) ) Not that is needed for this, just to show it is possible to use the same method even on a global var. Quote
pBe Posted February 7, 2012 Posted February 7, 2012 @Mircea sometimes i use. USERS1-5 USERR1-5 USERI1-5 (setq dist (cond ((getdist (strcat "\nEnter Distance [Enter to accept: <" (rtos (setq dist [color=blue][b](getvar 'userr1))[/b][/color] 2 2) ">: " ) ) ) (dist) )) [color=blue][b](setvar 'userr1 dist)[/b][/color] It all depends on the usage really. if i am to use "GLOBAL" [literally] ----- > vl-propagate (vl-propagate 'dist) Hope this helps Quote
MSasu Posted February 7, 2012 Posted February 7, 2012 @irneb: Thank you for your correction. You are right, that "not" should not be there. Sorry for inconvenience. One solution is to not use a global variable to store the offset distance - will be preserved between runs. Just take care to don't reuse that name in other routine. Regards, Mircea 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.