PDA

View Full Version : osnap will not turn off



bowtle
2013-09-10, 04:52 AM
i am trying to write a simple routine that sets the current layer to wipeout, turns off all osnaps draws a wipeout and then resets the layer and osnaps.

I can not get it to turn off the osnaps!!!!!!!!!!!

I am using Autocad 2014.

any help would be greatly appreciated



(defun c:wp(/ o_lyr o_osm o_snm o_orm)


(setq o_lyr (getvar "CLAYER") ; save current layer
o_osm (getvar "OSMODE") ; save osnaps
o_snm (getvar "SNAPMODE")
o_orm (getvar "ORTHOMODE")
)

(setvar "osmode" 0) ; turn off osnaps
(setvar "snapmode" 0)
(setvar "orthomode" 0)


(command "_.layer" "M" "wipeout" "") ; make a layer for the wipeout
(command "_.wipeout")
;(vl-cmdf "_.wipeout" ) ;"_p" (car (entsel "Select closed polyline: ")) "_y")

(setvar "CLAYER" o_lyr) ; restore old values
(setvar "OSMODE" o_osm)
(setvar "SNAPMODE" o_snm)
(setvar "ORTHOMODE" o_orm)
)

(princ "\n")
(princ "command: wp ... create wipeout in layer wipeout")
(princ)




Thanks
GregB

bhull1985403354
2013-09-10, 12:09 PM
(setq old_snap (getvar "snapmode"))
(setq old_osnap (getvar "osmode"))
(setvar "snapmode" 0)
(setvar "osmode" 0)

...[rest of code here]....

(setvar "snapmode" old_snap)
(setvar "osmode" old_osnap)


Should work just fine, I tested the first 2 setvars, snapmode to 0 then osmode to 0, and it toggled my snaps off in 2012 just fine.

BlackBox
2013-09-10, 12:25 PM
i am trying to write a simple routine that sets the current layer to wipeout, turns off all osnaps draws a wipeout and then resets the layer and osnaps.

I can not get it to turn off the osnaps!!!!!!!!!!!

I am using Autocad 2014.

any help would be greatly appreciated


Hi Greg, give this a try...



(vl-load-com)

(defun c:WP (/ *error* clayer orthomode osmode snapmode layerName)

(defun *error* (msg)
(and clayer (setvar 'clayer clayer))
(and orthomode (setvar 'orthomode orthomode))
(and osmode (setvar 'osmode osmode))
(and snapmode (setvar 'snapmode snapmode))
(cond ((not msg)) ; Normal exit
((member msg '("Function cancelled" "quit / exit abort"))) ; <esc> or (quit)
((princ (strcat "\n** Error: " msg " ** "))) ; Fatal error, display it
)
(princ)
)

(if (and (setq clayer (getvar 'clayer))
(setq orthomode (getvar 'orthomode))
(setq osmode (getvar 'osmode))
(setq snapmode (getvar 'snapmode))
(vla-add (vla-get-layers
(vla-get-activedocument (vlax-get-acad-object))
)
(setq layerName "wipeout")
)
(setvar 'clayer layerName)
(setvar 'orthomode 0)
(setvar 'osmode 0)
(setvar 'snapmode 0)
)
(progn

(command "._wipeout")
(while (= 1 (getvar 'cmdactive))
(command pause)
)
)
)
(*error* nil)
)

bowtle
2013-09-11, 01:31 AM
Thank you both

bhull
... i tried your code and it works as it should, i then retried my code with a getstring to pause the prog before the command to make the layer, the osmode, orthomode, and snapmode were turned off, but when the wipeout command was active they were back on!!!

blackbox
... thanks this code does what i originally wanted ... I need to study it closely


any ideas why my code does not work?

Thanks again for your help

GregB

BlackBox
2013-09-11, 12:24 PM
blackbox
... thanks this code does what i originally wanted ... I need to study it closely


any ideas why my code does not work?


Your, and bhull's code are effectively the same, in that they first store the original system variables, set the desired values, perform some action(s), and the restore the original values, which is a good practice.

Where my code builds on this is in two key areas, first I employ a localized (read temporary) error handler, and then I force the Command call to pause for user input.

The latter is where you're noticing the biggest difference, as a Command call on it's own runs after the completion of the rest of your code (asynchronous), however by implementing the WHILE loop as I have forces the code to execute immediately (synchronous).

The former, is especially essential given that we're pausing for using input before the rest of the code being executed, as now one can simply hit escape at any pause for using input, and the rest of the code would not execute (i.e., leaving system variables not restored to their original setting). By adding a localized error handler, we've temporarily implemented a custom error handler, which I've coded to do our system variable restore, etc. both in the event of successful code completion, in the event of an actual error, or if the user hits escape.

Hope this make (more?) sense now.

Cheers

bhull1985403354
2013-09-11, 09:28 PM
Ah yes, the sysvars do need to be reset inside the local error handler as well, for the reasons mentioned above. Good looking out, BB.
This will force the variables the way you need them and then back to the way that they were before being modified, in any scenario. By successful completion and the hardcoded return to original values or via the error handler including the reset in case of any error causing the program to not reach it's end. Just paraphrasing, for the second time this thread, as my example for the osnaps was just a condensed version of his showing that the lines of code behave as expected. Thanks for the reminder though as that's really important to do, include the resets in the error handler. :)

BlackBox
2013-09-11, 09:33 PM
Good looking out, BB.


You're welcome, Brandon; I'm happy to help. ;)

bowtle
2013-09-12, 11:13 PM
Thanks BB

I did not realise that the command statement ran AFTER all the lisp statements had been executed ... now it makes sense.

I had assumed the code would execute in the order of the statements.

Thanks again ... :)

garcigj
2013-09-13, 10:08 AM
a good practice is to disable only the button object snap, not all options OSMODE



(vl-load-com)
(defun c:WP (/ *error* clayer btnOsnap orthomode osmode snapmode layerName)
;;---------- Main ERROR -------------------------------
(defun *error* (msg)
(and clayer (setvar 'clayer clayer))
(and orthomode (setvar 'orthomode orthomode))
(and osmode (setvar 'osmode osmode))
(and snapmode (setvar 'snapmode snapmode))
(cond ((not msg)) ; Normal exit
((member msg '("Function cancelled" "quit / exit abort"))) ; <esc> or (quit)
((princ (strcat "\n** WP Error: " msg " ** "))) ; Fatal error, display it
)
(princ)
)

(if (and (setq clayer (getvar 'clayer))
(setq orthomode (getvar 'orthomode))
(setq osmode (getvar 'osmode))
(setq snapmode (getvar 'snapmode))
(vla-add (vla-get-layers
(vla-get-activedocument (vlax-get-acad-object))
)
(setq layerName "wipeout")
)
(setvar 'clayer layerName)
(setvar 'orthomode 0)
(setvar 'snapmode 0)
;;disable only the button object snap:
(setvar 'osmode (boole 7 (getvar 'osmode) 16384))
)
(progn

(command "._wipeout")
(while (= 1 (getvar 'cmdactive))
(command pause)
)
)
)
(*error* nil)
)


this would be a feature for use with any features sharing ERROR routine


;;;--------------------- SetBtnRefent -----------------------------------
;;;(setvar "OSMODE" (boole 7 (getvar "OSMODE") 16384))
;;;Turns running object snap off
;;;(setvar "OSMODE" (boole 2 (getvar "OSMODE") 16384))
;;;Turns running object snap on
;;;
;;usage: (BtnRefent T) => Activate Button Osnap
;;usage: (BtnRefent nil) => Disable Button Osnap
(defun SetBtnRefent (Activate)
(setvar 'osmode
(boole (if Activate 2 7)
(getvar 'osmode)
16384)
)
)

rkmcswain
2013-09-13, 12:10 PM
a good practice is to disable only the button object snap, not all options OSMODE


;;;--------------------- SetBtnRefent -----------------------------------
;;;(setvar "OSMODE" (boole 7 (getvar "OSMODE") 16384))
;;;Turns running object snap off
;;;(setvar "OSMODE" (boole 2 (getvar "OSMODE") 16384))
;;;Turns running object snap on
;;;
;;usage: (BtnRefent T) => Activate Button Osnap
;;usage: (BtnRefent nil) => Disable Button Osnap
(defun SetBtnRefent (Activate)
(setvar 'osmode
(boole (if Activate 2 7)
(getvar 'osmode)
16384)
)
)


As I was reading this thread, I was thinking the exact same thing. Thanks for posting that.

BlackBox
2013-09-13, 03:54 PM
I had assumed the code would execute in the order of the statements.


For the most part it does (LISP), with few exceptions, LISP is considered to be a 'linear' language.

This very sort of issue is the first thing that tripped me up when jumping up to the .NET API... The difference between Synchronous, and Asynchronous calls... So I can relate.

Cheers

bowtle
2013-09-16, 05:25 AM
Could you explain what you mean by disabling only the button object snap, not all OSMODE options, I do not understand.

Thanks



a good practice is to disable only the button object snap, not all options OSMODE



(vl-load-com)
(defun c:WP (/ *error* clayer btnOsnap orthomode osmode snapmode layerName)
;;---------- Main ERROR -------------------------------
(defun *error* (msg)
(and clayer (setvar 'clayer clayer))
(and orthomode (setvar 'orthomode orthomode))
(and osmode (setvar 'osmode osmode))
(and snapmode (setvar 'snapmode snapmode))
(cond ((not msg)) ; Normal exit
((member msg '("Function cancelled" "quit / exit abort"))) ; <esc> or (quit)
((princ (strcat "\n** WP Error: " msg " ** "))) ; Fatal error, display it
)
(princ)
)

(if (and (setq clayer (getvar 'clayer))
(setq orthomode (getvar 'orthomode))
(setq osmode (getvar 'osmode))
(setq snapmode (getvar 'snapmode))
(vla-add (vla-get-layers
(vla-get-activedocument (vlax-get-acad-object))
)
(setq layerName "wipeout")
)
(setvar 'clayer layerName)
(setvar 'orthomode 0)
(setvar 'snapmode 0)
;;disable only the button object snap:
(setvar 'osmode (boole 7 (getvar 'osmode) 16384))
)
(progn

(command "._wipeout")
(while (= 1 (getvar 'cmdactive))
(command pause)
)
)
)
(*error* nil)
)


this would be a feature for use with any features sharing ERROR routine


;;;--------------------- SetBtnRefent -----------------------------------
;;;(setvar "OSMODE" (boole 7 (getvar "OSMODE") 16384))
;;;Turns running object snap off
;;;(setvar "OSMODE" (boole 2 (getvar "OSMODE") 16384))
;;;Turns running object snap on
;;;
;;usage: (BtnRefent T) => Activate Button Osnap
;;usage: (BtnRefent nil) => Disable Button Osnap
(defun SetBtnRefent (Activate)
(setvar 'osmode
(boole (if Activate 2 7)
(getvar 'osmode)
16384)
)
)

Tom Beauford
2013-09-16, 11:17 AM
Could you explain what you mean by disabling only the button object snap, not all OSMODE options, I do not understand.

Thanks

In simplest terms it sets "OSMODE" to the same value as if you had used the button on the Status bar at the bottom of the AutoCAD screen to toggle it off. If the routine was exited somehow without resetting "OSMODE" by simply toggling Osnaps back the settings would be exactly the same as before the routine was run.

bowtle
2013-09-16, 09:43 PM
In simplest terms it sets "OSMODE" to the same value as if you had used the button on the Status bar at the bottom of the AutoCAD screen to toggle it off. If the routine was exited somehow without resetting "OSMODE" by simply toggling Osnaps back the settings would be exactly the same as before the routine was run.

Ahh ... I understand now,

instead of clearing all the osnaps it would leave all the running osnaps set, but just make them inactive, so you could activate them by pressing the button.

Thanks.