Osmode variable Vs osnap command and its position in lisp routine

Osmode variable Vs osnap command and its position in lisp routine

Anonymous
Not applicable
3,520 Views
7 Replies
Message 1 of 8

Osmode variable Vs osnap command and its position in lisp routine

Anonymous
Not applicable

Hello kind people of the forum,

Have had a number of you here write me some truly amazing routines & in a bid to try & streamline them even further, I am looking to have only specific snap points/modes available at certain parts in the routines.

Firstly, I am unsure if it is as simple as setting the osmode variable to required integer (quadrants snap for example) & then resetting the variable to mystandard osmode number to reinstate all usual snaps at end of routine. Or...

Do I use the osnap command to specify the desired snap points by name somewhere in the routine? 

 

Aside from not being sure in the differences of outcome in these two methods, I have had extremely little success using either method. At the end of a failed lisp routine the snaps have indeed changed but the lisp ceases to run as it did before i tried adding these little cherries on top.

Hopefully this has all made sense without me supplying all the lisps I'm trying to tweak & someone would be kind enough to explain where I would use the osmode variable over the osnap command & where these snippets of code should be placed..?

 

I'm currently working on a lisp that inserts a circular named block in the middle of two other circular blocks so would like to restrict my snapping to quadrants as am dealing with sides/tops of circles. Could someone maybe give me a hint on how to include the above mentioned? Please use your own example if preferred... just something uncomplicated so I can work out the key to it all.

 

Thank you everyone. Hope everyone is doing okay.

Brad

0 Likes
Accepted solutions (1)
3,521 Views
7 Replies
Replies (7)
Message 2 of 8

dbroad
Mentor
Mentor

See the help page on osmode. (2016 version)

(setvar "osmode" #)  where # is the sum of whatever modes you want on (bitflag based #).

To toggle osnap on and off just negate the #.

(setvar "osmode" (- (getvar "osmode"))) ;;just toggles the mode.

 

These are relatively easy concepts and you should be able to look them up using the vlide help features.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 3 of 8

john.uhden
Mentor
Mentor

@dbroad is one of the most helpful and brilliant guys here.

Unless it's in the help, what Doug didn't explain well enough is that each bit is a Boolean value.

For example, let's say you have your osnaps set to endpoint (1), that's all.

To add center (16), you would use (logior 1 16) to get 17.

Spelling it out... (setvar "osmode" (logior 16 (getvar "osmode")))

To remove endpoint (1), you would use (boole 2 17 1) to get 16.

Spelling it out... (setvar "osmode" (boole 2 (getvar "osmode") 1))

Of course you should save the value of osmode to a variable at the beginning of any program that will change it so that you can restore it just before the program finishes, or exits due to a cancel or error.

These may save you some time and characters:

(defun add_osmode (n)
  (setvar "osmode" (logior (getvar "osmode") n))
)
(defun del_osmode (n)
  (setvar "osmode" (boole 2 (getvar "osmode") n))
)
(defun is_osmode_set (n)
  (= n (logand (getvar "osmode") n))
)

 Plus, you can combine bits to add or delete more than one at one time.

For example (logior 3 9) returns 11  (+ 1 2 8), and (boole 2 11 3) returns 8.

Go ahead and play with it.

John F. Uhden

0 Likes
Message 4 of 8

cadffm
Consultant
Consultant

Additional to Johns post:

 


@dbroad  schrieb:

(setvar "osmode" (- (getvar "osmode"))) ;;just toggles the mode.


That would be new for me and my AutoCAD, the toggle for ON/OFF is bit value 16384 as documented

(defun c:osmodetoggle nil
  (setvar "OSMODE" (boole 6 16384 (getvar "OSMODE")))
)

 

 

Sebastian

Message 5 of 8

john.uhden
Mentor
Mentor
Both Doug and you have brightened my day. I had forgotten about (boole 6
...)

John F. Uhden

0 Likes
Message 6 of 8

Sea-Haven
Mentor
Mentor
Accepted solution

Why go down the to hard path just Osnap set it to what you want then type osmode, then get things called a pencil and paper and write the number down, in most cases its only 2 or 3 numbers used, 1, 4, 512, my reset is 47.

0 Likes
Message 7 of 8

Anonymous
Not applicable

Hello again everyone,

 

I accepted the solution and the points went to sea.haven but only because the rest of the solutions (although probably more robust) were a little above my paygrade.  Thank you so much to everyone that replied though, I took a little from each and it all helps with my study.

 

The stage I'm at though, I have had to limit editing my lisp files by simply adding ("osmode" x) as the first line of the code and then adding ("osmode" 5823) as the end line to return to my standard snap settings.  Not sure I really understood a lot of the other replies but that's entirely a reflection of my limited knowledge.  Really appreciate everyones input.

 

Using my over-simplified method of changing the snaps, I'm not sure what would happen if I cancelled mid command or there was some other error... no doubt my method will leave me with incorrect snap settings but there was only maybe half a dozen lisp routines that I wanted to specify the snaps on so I'll live with that until I've learned how to factor in errors and such.

 

Thanks again, so very much everyone.

 

Brad 

0 Likes
Message 8 of 8

ВeekeeCZ
Consultant
Consultant

Here you have very often used way to handle osmode on simple (hopefully) example.

 

Save old osmode, set new, reset to old. You ALWAYS need to establish the *error* function if you change ANY of system variables to make sure that it resets even in case of ESCaping/error.

 

 

(defun OMultiple (cur / *error* osm ent pnt dst)
  
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
      (princ (strcat "\nError: " errmsg)))
    (if osm (setvar 'OSMODE osm))
    (if ent (redraw ent 4))
    (princ)
    )
  
  (if (and (setq ent (ssget "_+.:E:S"))
           (setq ent (ssname ent 0))
           (setq osm (getvar 'OSMODE)) 
           (setvar 'OSMODE 0)	
           (not (redraw ent 3))
           )
    (while (setq dst (getdist "\nSpecify offset distance: "))
      (or pnt
          (setq pnt (polar (trans (cdr (assoc 10 (entget ent))) 0 1) (* 1.5 pi) 1)
                dst (abs dst)))
      (command "_.OFFSET" "_E" "_N" "_L" (if cur "_C" "_S") dst ent pnt "")
      (redraw ent 4)
      (redraw (setq ent (entlast)) 3)))

  (if osm (setvar 'OSMODE osm))
  (if ent (redraw ent 4))
  (princ)
  )

(defun c:OM ()  (OMultiple nil) (princ))
(defun c:OWM () (OMultiple T) 	(princ))

 

 

0 Likes