September 09, 2007

OSNAP Toggle Macro

There was a request for a macro to toggle the running object snap (OSNAP) settings between "off" and a specific combination of OSNAPs, in a thread in the AutoCAD Architecture 2008 Discussion Group. I posted some AutoLISP code in reply, and thought I would archive the code here and explain how it works.

The OSMODE system variable keeps track of which OSNAP settings are active, and whether running object snap is turned on or off. The value stored in the OSMODE system variable is "bit coded". A bit coded system variable allows multiple, related items that can be either "on" or "off" to be tracked "separately" in one number. If you expressed that number in Base 2, each digit (or "bit") will either be zero (not set, or off) or a one (set, or on). Each OSNAP setting is assigned to a particular digit, and if that bit is "set" (1), that OSNAP is on. If all of the bits are set to zero, then the NONe OSNAP is "set". The decimal value held in the OSMODE system variable is the sum of the associated decimal values of each of the set bits. As noted in the Help, the following indicates the bit with which each OSNAP is associated.
OSNAP
  
Decimal Value
ENDpoint 1
MIDpoint 2
CENter 4
NODe 8
QUAdrant 16
INTersection 32
INSertion 64
PERpendicular 128
TANgent 256
NEArest 512
Clears all object snaps 1024
APParent Intersection 2048
EXTension 4096
PARallel 8192

There is also an additional bit setting for the 16384 bit. If this bit is set, then running object snaps are turned off, but the individual snap settings are retained and can be reactivated by clearing the 16384 bit. So there are two ways in which runnning object snaps can be off: either none are set (OSMODE = 0) or the 16384 bit is set (OSMODE > 16383). These are the tests that my macro code uses to test whether running object snaps are inactive. If inactive, OSMODE is set to the desired combination of OSNAPs - in this example, endpoint (1), intersection (32), perpendicular (128) and nearest (512); otherwise, 16384 is added to the current value to set the 16384 bit and turn off running object snaps. Rather than adding the bit codes and entering that specific number, I used the AutoLISP "+" function to do the adding for me. This may slow down execution a bit, but it makes seeing what OSNAPs are being set by the code much clearer and makes adding or removing a particular OSNAP easier, too.

The macro code could be assigned to a function key or a keyboard accelerator, as the person making the request in the Discussion Group wanted, or it could be assigned to a toolbar button or to a command tool on a Tool palette. Similar code could be put into an AutoLISP function which, when loaded, could be run by any of the above methods or at the Command: prompt by typing in the function name.

MACRO CODE:
(if 
(or
(= (getvar "OSMODE") 0)
(> (getvar "OSMODE") 16383)
)
(setvar "OSMODE" (+ 1 32 128 512))
(setvar "OSMODE" (+ (getvar "OSMODE") 16384))
)


MACRO CODE in an AutoLISP Function:
(defun C:OSM ( / aosmo)
(setq aosmo (getvar "OSMODE"))
(if
(or
(= aosmo 0)
(> aosmo 16383)
)
(setvar "OSMODE" (+ 1 32 128 512))
(setvar "OSMODE" (+ aosmo 16384))
)
(prin1)
)

No comments: