Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Running osnap problem - Osmode, Autosnap, and Autolisp

709 views
Skip to first unread message

Howard Partridge

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
Anyone know of a way to keep running osnaps on from inside a R14
Autolisp program while leaving autosnap on? I don't believe the 16384
Osmode bit is the answer here.

My running object snaps keep getting turned off after drawing one line
segment in an Autolisp program.

This only occurs when setting the osmode from inside the program, not as
a command override while the program runs. I've determined that
AutoSnap is at the root of the problem. I find that when I turn it off
(set it to 0), my running Osnaps stay on as long as I like (but I get
the old style osnap selection). But when AutoSnap is on, running osnaps
mysteriously turn off after the end of the first line segment.

Try these simplified code snippets to see what I mean:

(defun c:snapoff
(prompt "\nRunning snaps turn off after first line segment, uses new
style osnap")
(setvar "autosnap" 7)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))
(command "._pline" pt1 pause)
(setq pt1 nil)
(princ)
)

(defun c:snapon
(prompt "\nRunning snaps stay on after first line segment, uses old
style osnap")
(setvar "autosnap" 0)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))
(command "._pline" pt1 pause)
(setq pt1 nil)
(princ)
)

I have purposely left out the restoration of the previous settings for
autosnap and osmode. Doing so adds a level of complexity that isn't
necessary for this example.

Make sure you have some linework on the screen with intersections to
snap to before testing this out.

Any thoughts?

-Howard Partridge
webm...@cupola.com
http://www.cupola.com


Paul Turvill

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
Your simplified code snippets are incorrectly written. They're trying to
declare "prompt" as a variable; they shouldn't run at all. Try this:

(defun c:snapoff (/ pt1)


(prompt "\nRunning snaps turn off after first line segment, uses new
style osnap")
(setvar "autosnap" 7)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))

(command "._pline" pt1)
(princ)
)

(defun c:snapon (/ pt1)


(prompt "\nRunning snaps stay on after first line segment, uses old
style osnap")
(setvar "autosnap" 0)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))

(command "._pline" pt1)
(princ)
)

___

Howard Partridge <Loo...@cupola.com> wrote in message
news:37175F1A...@cupola.com...

Howard Partridge

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
Hi Paul,

You're right. I inadvertently dropped the () after my defun statements in
my posting. The original snippets should have read like this (which is what
I tested).

(defun c:snapoff ()


(prompt "\nRunning snaps turn off after first line segment, uses new
style osnap")
(setvar "autosnap" 7)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))
(command "._pline" pt1 pause)
(setq pt1 nil)
(princ)
)

(defun c:snapon ()


(prompt "\nRunning snaps stay on after first line segment, uses old
style osnap")
(setvar "autosnap" 0)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))
(command "._pline" pt1 pause)
(setq pt1 nil)
(princ)
)

These do cause the behavior that I described. But your answer seems to
resolve the problem anyway. I wasn't aware that the functions would work
without the pauses in the command line. When dropped, they appear to work
correctly, whether or not Autosnap is on. Not quite sure why pause does
this, but you've provided a much better workaround. Thanks!

Paul Turvill

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
I'm not sure it's the pauses (although, as you surmise, they *are*
redundant, the way the code is written); rather it may be the (setq pt1
nil) which makes the routine try to re-enter AutoLISP *after* the
(command ...) function. If you declare pt1 as a local variable (as in my
examples) it gets nulled automatically, and there's no need for (setq pt1
nil) in the routine.

__
Howard Partridge <Loo...@cupola.com> wrote in message
news:37177CC6...@cupola.com...

Howard Partridge

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
Hi Paul,

Thanks for writing. You've raise some good points. And I agree, the
extra setq statement could be handled more elegantly.

While re-examining the code today, I found that I could no longer make
the osmode fail, with or without the pause and setq pt1 nil statement.
I had been testing it out in a new AutoCAD session this morning when it
failed, but something subtle must have changed in the drawing
environment. Either that or the gremlins that live inside my machine
have been working their mischief today. They like to make sure you know
you're still human.

Some basic lisp commands are OK to use after a (command...) function
without ill effect (like triggering the lisp reentry problems that you
mentioned). The (Princ) command found at the end of many lisp routines
is a perfect example. But calling another lisp PROGRAM afterward is
another kettle of fish.

Putting a (setvar "osmode" 0) command after the (command...) fucntion
does work, for example, but probably not as one might expect. This code
DOES cause the weird behavior that I described earlier (unless those
gremlins have been at it again!)


(defun c:snapoff1 ()


(prompt "\nRunning snaps turn off after first line segment, uses new
style osnap")
(setvar "autosnap" 7)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))
(command "._pline" pt1 pause)
(setq pt1 nil)

(setvar "osmode" 0)
(princ)
)

;or alternatively, in your prettier form:

(defun c:snapoff2 (/ pt1)


(prompt "\nRunning snaps turn off after first line segment, uses new
style osnap")
(setvar "autosnap" 7)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))

(command "._pline" pt1)
(setvar "osmode" 0)
(princ)
)

Both functions clear running osnaps at some point after the command has
begun the polyline, continuing it with running osnaps disabled.

The one with the pause command uses the intersection running osnap for
two points, while the second method works for the first point only. It
seems that once an open ended command like this is issued, the program
continues in a special suspended kind of mode. It still processes basic
lisp commands, but it won't allow you to call other lisp programs.

The pause command in this case actually isn't redundant. It allows the
user a second input, before evaluating the remaining lisp as it
continues the pline command.

Paul Turvill

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
No, there's really no problem in calling other lisp routines after just
about *any* (command ...) sequence -- PROVIDED the (command ...) function
is properly completed before returning to the rest of the lisp program.
Any time you launch an AutoCAD command from within AutoLISP, and that
command requires user interaction, you must include code to keep AutoLISP
"at bay" until the command is completed. This is usually done with a
(while...) loop, similar to the following:

<<code before>>
(command "_.line")
(while (= (logand (getvar "cmdactive") 1) 1)
(command pause))
<<code after>>

The (while ...) loop checks to see if there's a "native" command active,
and if there is, it pauses for user input; when the native command is
finished, CMDACTIVE's low bit (1) goes to 0, (while...) sees the change,
and allows the routine to continue. This prevents the lisp stuff in
<<code after>> from trying to execute while the command is still
attempting to get user input.

Your (modified) and my suggested code for your original problem works
only because the (command ...) function is effectively the last function
in the routine.

The correct code for your latest example (using "my" format) is:

(defun c:snapoff2 (/ pt1)

(prompt "\nRunning snaps REMAIN ON during Pline, off when done")


(setvar "autosnap" 7)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))
(command "._pline" pt1)

(while (= (logand (getvar "cmdactive") 1) 1)
(command pause))


(setvar "osmode" 0)
(princ)
)

__
Howard Partridge <Loo...@cupola.com> wrote in message

news:37182464...@cupola.com...


>
> Some basic lisp commands are OK to use after a (command...) function
> without ill effect (like triggering the lisp reentry problems that you
> mentioned). The (Princ) command found at the end of many lisp routines
> is a perfect example. But calling another lisp PROGRAM afterward is
> another kettle of fish.
>
> Putting a (setvar "osmode" 0) command after the (command...) fucntion
> does work, for example, but probably not as one might expect. This
code
> DOES cause the weird behavior that I described earlier (unless those
> gremlins have been at it again!)

<snip>

Howard Partridge

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
Great input, Paul!

I knew about the while loop stuff, having done this a little differently
in some of my previous programs. I just hadn't used one before with the
pause command.

Your logand method below is new for me.



>(while (= (logand (getvar "cmdactive") 1) 1)
> (command pause))

What's your reason behind the logand? The command seems to work without
it. Am I missing something? How about this minor modification to your
modifications? It also has the nitpicky advantage of not dropping out
of the command because a transparent command was issued during user
input (the bitflag for cmdactive could be greater than 1 and still be
active).

(defun c:snapoff3 (/ pt1)


(prompt "\nRunning snaps REMAIN ON during Pline, off when done")
(setvar "autosnap" 7)
(setvar "osmode" 32)
(setq pt1 (getpoint "\nPline from point <osnap=int> "))
(command "._pline" pt1)

(while (getvar "cmdactive")


(command pause))
(setvar "osmode" 0)
(princ)
)

I've read what I could on the logand function, but none of my books are
very clear on the subject. The truth tables and their bits make sense
to me, but the logic behind Autodesk's examples still eludes me. I
mean, why does (logand 7 15 3) return 3, and (logand 8 3 4) return 0?

Howard Partridge
webm...@cupola.com
http://www.cupola.com

Howard Partridge

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
Whoops! My mistake. Gremlins again.

Your suggested modifications work just fine. Please disregard my
previous suggestion, which does not close the command properly. That
must be what the logand function is helping to do. Strange that I got
kicked out in a transparent command one time though. That had led me to
believe that the cmdactive evaluation wasn't working for all of its
possible nonzero values, but I now see that I must have been mistaken in
that belief. Still not clear on how logand actually works, maybe a
little clarification would help.

Paul Turvill

unread,
Apr 18, 1999, 3:00:00 AM4/18/99
to
The (logand ...) function permits you to examine a single bit (or more)
of a "bitmapped" value. Bitmapping simply attaches a special meaning to
each bit of a binary number. In this case, all you're interested in is
whether there's an AutoCAD command running or not; a running AutoCAD
command causes the low bit (value = 1) of CMDACTIVE to be set, and
(logand (getvar "cmdactive") 1) simply checks to see if that bit is set
or not. It ignores all bits other than the "1" bit. You can find
information on all of the bit values in the Help system under CMDACTIVE.

(logand) compares two numbers "bit by bit" and reports which bits are
common. Every bit's place value is a power of 2 -- 1, 2, 4, 8....
(logand 7 15 3) returns 3 because the two lowest bits (1 and 2) are
common to all three; and (logand 8 3 4) returns 0 because 8, 3, and 4
have no bits in common. Every conceivable integer can, by definition, be
composed of a sum of bit values.
__
Howard Partridge <webm...@cupola.com> wrote in message
news:3718D1C8...@cupola.com...

Howard Partridge

unread,
Apr 18, 1999, 3:00:00 AM4/18/99
to
Hi Paul,

Thanks so much for taking the time to shed light on the (logand...)
function for me. I now see how both it and the related (logior...)
function work.

For anyone else reading this still having trouble, I recommend studying
Paul's explanation with a binary table like this in hand:

Base 10 Base 2 (Binary)
Number Eights Fours Twos Ones
1 0 0 0 1
2 0 0 1 0
3 0 0 1 1
4 0 1 0 0
5 0 1 0 1
6 0 1 1 0
7 0 1 1 1
8 1 0 0 0
9 1 0 0 1
10 1 0 1 0
11 1 0 1 1
12 1 1 0 0
13 1 1 0 1
14 1 1 1 0
15 1 1 1 1

Back to the original problem then, now that I see what you're done with
logand. Quite nice, I might add. Here's some additional refinement,
now that the basics are working right.

It appears that the setting for AutoSnap has no serious effect on the
program's functionality. I also noticed that we could dispense with the
pt1 variable entirely, since the pause command line makes it
unnecessary. Of course, if CMDECHO is turned off, as is often the case,
the prompting could be quite hideous. Here's my latest program
revisions:

(defun c:plsp ()
(command "._undo" "begin")
(setvar "osmode" 32)
(prompt "\nPline from point <osnap=int> ")
(command "._pline")
(setvar "cmdecho" 1)
(while (= (logand (getvar "cmdactive") 1) 1)
(command pause))
(setvar "cmdecho" 0)
(setvar "osmode" 0)
(command "._undo" "end")
(princ)
)

One fault of the program is that it IS possible to get cmdecho turned
back by canceling part way thru the command and then undoing one step.
The undo end doesn't get processed, so you don't go back all the way.
But I guess that an error handler might fix that problem. The window of
opportunity for the condition to occur looks fairly small, though.

I'm aware that the program does not store the original variable settings
for later restoration. I didn't think it necessary for now.

Comments?

0 new messages