TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Coder on June 09, 2013, 03:36:45 AM

Title: To check one of osmode is set to on
Post by: Coder on June 09, 2013, 03:36:45 AM
Hello everyone .  :-)

I need to know if any of the object snap is set to on ( active ) , I think this could be possible if we use the boole function but I couldn't understand how it works from the help document .

Anybody can help me with this please by explaining the function as simple as it could be .

Many thanks .
Title: Re: To check one of osmode is set to on
Post by: irneb on June 09, 2013, 04:37:20 AM
You can use boole (http://docs.autodesk.com/ACD/2013/DEU/index.html?url=files/GUID-C8412B41-BED9-4182-94E6-9EDB3C176D13.htm,topicNumber=d30e603676) yes. You need its AND operation, in which case you give it a 1 as the operator code. This is the same as using the logand (http://docs.autodesk.com/ACD/2013/ENU/index.html?url=files/GUID-4E042C63-8BD7-4FED-B9E1-B5CE12D18273.htm,topicNumber=d30e622469) function.


Both these perform a bitwise and (http://en.wikipedia.org/wiki/Bitwise_operation#AND) operation. It's a programming trick using the way integers are stored in RAM. Seeing as all integers (and for that matter all other stuff too) are stored as a binary number (i.e. 1's and 0's) normal boolean logic can be applied to them. So:
Code: [Select]
1 and 1 = 1
1 and 0 = 0
0 and 0 = 0
The way larger numbers are store depends on the position of the 1:
Code: [Select]
2 = binary(10)
3 = binary(11)
4 = binary(100)
5 = binary(101)
6 = binary(110)
7 = binary(111)
8 = binary(1000)
And so on. So you see a new position is opened for each power of 2. Same as a new position is opened in decimal numbers for each power of 10.


Now from the OSMode (http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%202010%20User%20Documentation/index.html?url=WS1a9193826455f5ffa23ce210c4a30acaf-4f1d.htm,topicNumber=d0e352473) variable all those settings you'll note are powers of 2. So.
Code - Auto/Visual Lisp: [Select]
  1. (> (logand (getvar "OSMode") 32) 0) ;Check of Intersection is turned on
  2. (> (logand (getvar "OSMode") (+ 32 64)) 0) ;Check if either Intersection or Insertion (or both) are turned on
Title: Re: To check one of osmode is set to on
Post by: ribarm on June 09, 2013, 07:10:56 AM
You can use boole (http://docs.autodesk.com/ACD/2013/DEU/index.html?url=files/GUID-C8412B41-BED9-4182-94E6-9EDB3C176D13.htm,topicNumber=d30e603676) yes.

Actually, you don't have to use boole at all...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:oschk ( / os 3dos )
  2.   (setq os (getvar 'osmode))
  3.   (setq 3dos (getvar '3dosmode))
  4.   (if (< 0 os 16384)
  5.     (princ "\nOsnap is turned on")
  6.     (princ "\nOsnap is turned off")
  7.   )
  8.   (if 3dos
  9.     (if (not (or (= 3dos 1) (= 3dos 0)))
  10.       (princ "\n3DOsnap is turned on")
  11.       (princ "\n3DOsnap is turned off")
  12.     )
  13.   )
  14.   (princ)
  15. )
  16.  
Title: Re: To check one of osmode is set to on
Post by: CAB on June 09, 2013, 08:21:48 AM
More osmode routines:

Code - Auto/Visual Lisp: [Select]
  1. ;;  CAB  02.04.08
  2.   (defun Set_osmode (flg) ; nil=OFF  t=ON
  3.     (if (or (and flg (>= (getvar "osmode") 16383)) ; ON & osmode is off
  4.             (and (null flg) (<= (getvar "osmode") 16383)) ; OFF & osmode is ON
  5.         )
  6.       (setvar "osmode" (boole 6 (getvar "osmode") 16384)) ; Toggle osmode
  7.     )
  8.   )
  9.  
  10. ;;  Lee ? http://www.theswamp.org/index.php?topic=32806.msg382796#msg382796
  11. (defun os (flag) (setvar "OSMODE" (boole (if flag 2 7) (getvar "OSMODE") 16384)) )
  12.  
  13.  
  14.  
  15. ;;  CAB  10/5/2006
  16. ;;
  17. ;;  Function to return the current osmode setting in the form of a string
  18. ;;  If (getvar "osmode") = 175
  19. ;;  (get_osmode)  returns   "_end,_mid,_cen,_nod,_int,_per"
  20. ;;  Usage
  21. ;;  (osnap (getpoint) (get_osmode))
  22. ;;
  23. (defun get_osmode (/ cur_mode mode$)
  24.   (setq mode$ "")
  25.   (if (< 0 (setq cur_mode (getvar "osmode")) 16383)
  26.     (mapcar
  27.       '(lambda (x)
  28.          (if (not (zerop (logand cur_mode (car x))))
  29.            (setq mode$ (strcat mode$ (cadr x)))
  30.          )
  31.        )
  32.       '((0 "_non,")  (1 "_end,")   (2 "_mid,")   (4 "_cen,")   (8 "_nod,")
  33.         (16 "_qua,") (32 "_int,")  (64 "_ins,")  (128 "_per,") (256 "_tan,")
  34.         (512 "_nea,")(1024 "_qui,")(2048 "_app,")(4096 "_ext,")(8192 "_par")
  35.        )
  36.     )
  37.   )
  38.   mode$
  39. )
Title: Re: To check one of osmode is set to on
Post by: Lee Mac on June 09, 2013, 12:49:25 PM
I need to know if any of the object snap is set to on ( active )

The following will return T if any Object Snap modes are active, irregardless of whether Object Snap is enabled:
Code - Auto/Visual Lisp: [Select]
  1. (< 0 (logand (getvar 'osmode) 16383))

The following will return T if any Object Snap modes are active and Object Snap is enabled:
Code - Auto/Visual Lisp: [Select]
  1. (< (logand (getvar 'osmode) 32767) 16384)
Title: Re: To check one of osmode is set to on
Post by: Coder on June 09, 2013, 01:00:35 PM
Thank you guys for your nice work .  :-)

Maybe I did not describe my work clearly  :-(

When I retrieve the osmode settings like this .

Code: [Select]
(setq osm (getvar "osmode"))
I get this value 4119 , how can I know if the nearest or insertion modes are set on with that return value ? and how to add it to the
new settings of the current osmode value and after the routine finishes , I need to reset them back as they were before
these changes .

Many thanks  :-)
Title: Re: To check one of osmode is set to on
Post by: Lee Mac on June 09, 2013, 01:04:43 PM
How can I know if the nearest or insertion modes are set on with that return value ? and how to add it to the new settings of the current osmode value and after the routine finishes , I need to reset them back as they were before these changes .

I would recommend:
Code - Auto/Visual Lisp: [Select]
  1. (setq os (getvar 'osmode)) ;; Current OSMODE setting
  2. (setvar 'osmode (logior os 576)) ;; (= 64+512)
  3.  
  4. ;; ... Do something ...
  5.  
  6. (setvar 'osmode os) ;; Reset OSMODE
Title: Re: To check one of osmode is set to on
Post by: Coder on June 09, 2013, 01:17:36 PM
How can I know if the nearest or insertion modes are set on with that return value ? and how to add it to the new settings of the current osmode value and after the routine finishes , I need to reset them back as they were before these changes .

I would recommend:
Code - Auto/Visual Lisp: [Select]
  1. (setq os (getvar 'osmode)) ;; Current OSMODE setting
  2. (setvar 'osmode (logior os 576)) ;; (= 64+512)
  3.  
  4. ;; ... Do something ...
  5.  
  6. (setvar 'osmode os) ;; Reset OSMODE

Thank you Lee for the fast reply and perfect one .  :-D

I had a problem today in the way to understand the boole function but with the logior function , things went too far from my hand to
understand how they behave  :-o

Many thanks .
Title: Re: To check one of osmode is set to on
Post by: Lee Mac on June 09, 2013, 01:23:06 PM
To explain the logior bitwise logic operation, consider the following example illustrating the binary representation of each case:

For this example, consider an 8-bit (unsigned) integer storing a particular bit-coded setting (values ranging from 0 to 255), and imagine that this setting is initially set to 155:

Code: [Select]
=======================================
bit:      7   6   5   4   3   2   1   0
---------------------------------------
dec:    128  64  32  16   8   4   2   1
=======================================
155:      1   0   0   1   1   0   1   1

Now say that we wish to ensure that bits 3 (8) & 6 (64) are enabled; for this we can use a logior operation.

logior performs the inclusive OR of the bitwise representations of two or more integers, hence, for each bit representing the integer value of each supplied argument, the logior operation will return 1 if either of the bits is 1, or if both are 1.

Hence, in our example:

Code: [Select]
=======================================
bit:      7   6   5   4   3   2   1   0
---------------------------------------
dec:    128  64  32  16   8   4   2   1
=======================================
155:      1   0   0   1   1   0   1   1  =  155
---------------------------------------
 72:      0   1   0   0   1   0   0   0  =   72
=======================================
LOGIOR:   1   1   0   1   1   0   1   1  =  219

Looking at the column representing each bit, note that logior will return 1 if the column contains at least one 1. The result is then converted back to decimal and returned by the functon.
Title: Re: To check one of osmode is set to on
Post by: Lee Mac on June 09, 2013, 01:28:41 PM
See this thread also:

http://www.theswamp.org/index.php?topic=12786 (http://www.theswamp.org/index.php?topic=12786)

In the same vein, this digression may also be of interest:

http://www.cadtutor.net/forum/showthread.php?61237-I-want-just-Blocks-and-not-Xrefs&p=416106&viewfull=1#post416106 (http://www.cadtutor.net/forum/showthread.php?61237-I-want-just-Blocks-and-not-Xrefs&p=416106&viewfull=1#post416106)
Title: Re: To check one of osmode is set to on
Post by: kruuger on June 09, 2013, 04:47:22 PM
Code: [Select]
; =========================================================================================== ;
; Lista bitow liczby calkowitej / List of bits integer                                        ;
;  Number [INT] - liczba calkowita / integer number                                           ;
; ------------------------------------------------------------------------------------------- ;
; (cd:CAL_BitList 127)                                                                        ;
; =========================================================================================== ;
(defun cd:CAL_BitList (Number / n res)
  (setq n 1)
  (while (>= Number n)
    (and
      (= (logand Number n) n)
      (setq res (cons n res))
    )
    (setq n (lsh n 1))
  )
  (if res
    (reverse res)
    (list Number)
  )
)
Code: [Select]
(cd:CAL_BitList 4119) -> (1 2 4 16 4096)?
kruuger
Title: Re: To check one of osmode is set to on
Post by: Lee Mac on June 09, 2013, 04:51:36 PM
Code: [Select]
(defun bits ( n / b )
    (if (< 0 n)
        (cons (setq b (expt 2 (fix (/ (log n) (log 2))))) (bits (- n b)))
    )
)
Code: [Select]
_$ (bits 4119)
(4096 16 4 2 1)

 :-)
Title: Re: To check one of osmode is set to on
Post by: Lee Mac on June 09, 2013, 05:26:19 PM
Another:
Code: [Select]
(defun bits ( n / b l )
    (repeat (1+ (setq b (fix (/ (log n) (log 2)))))
        (if (= 1 (rem (lsh n (- b)) 2))
            (setq l (cons (lsh 1 b) l))
        )
        (setq b (1- b))
    )
    l
)
Code: [Select]
_$ (bits 4119)
(1 2 4 16 4096)

Or, using the same logic:
Code: [Select]
(defun dec->bin ( n / b l )
    (repeat (1+ (setq b (fix (/ (log n) (log 2)))))
        (setq l (cons (rem (lsh n (- b)) 2) l)
              b (1- b)
        )
    )
    (reverse l)
)
Code: [Select]
_$ (dec->bin 4119)
(1 0 0 0 0 0 0 0 1 0 1 1 1)

I'm having fun  :-)
Title: Re: To check one of osmode is set to on
Post by: kruuger on June 09, 2013, 05:35:11 PM
Lee thanks for codes.
i will review, learn and update my routine :)

k.
Title: Re: To check one of osmode is set to on
Post by: Marc'Antonio Alessi on June 10, 2013, 03:13:14 AM
Another version:
Code: [Select]
; Function: ALE_UtlBits_AreOn
;
; Version 1.00 - 16/11/2006
;
; Arguments:
;   BtsVal = Integer [INT]
;   IntNum = Integer [INT]
;
; Return Values:
;   T if all bits <BtsVal> in number <IntNum> are set
;
; Example:
;   (if (ALE_UtlBits_AreOn 2 18) (progn (princ "\nBit 2 is set in 18") (princ)))
;
(defun ALE_UtlBits_AreOn (BtsVal IntNum)
  (and
    (eq (type BtsVal) 'INT)
    (eq (type IntNum) 'INT)
    (eq BtsVal (logand IntNum BtsVal))
  )
)
;
; Function: ALE_UtlBits_GetBitWise
;
; Version 1.00 - 16/11/2006
;
; Arguments:
;   BtsVal = Integer [INT]
;
; Return Values:
;  [LIST] a list of all logical bitwise AND's of an integer
;         or nil if BtsVal > 32767 or < 1
;
; Examples:
;  (ALE_UtlBits_GetBitWise 32767)
;  ==> (1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384)
;  (ALE_UtlBits_GetBitWise 32768)
;  ==> nil
;  (ALE_UtlBits_GetBitWise   nil)
;  ==> nil
;  (ALE_UtlBits_GetBitWise     0)
;  ==> nil
;
(defun ALE_UtlBits_GetBitWise (BtsVal / CurBit OutVal)
  (cond
    ( (> 1 BtsVal 32767) nil ) ; 32767 = bits sum max value
    ( (setq CurBit 1)
      (while (<= CurBit BtsVal)
        (if (= (logand BtsVal CurBit) CurBit)
          (setq OutVal (cons CurBit OutVal))
        )
        (setq CurBit (* CurBit 2))
      )
      (reverse OutVal)
    )
  )
)
Title: Re: To check one of osmode is set to on
Post by: irneb on June 10, 2013, 05:19:35 AM
Anyhow, here's a full to-and-from conversion based on the challenge in that other thread:
Code - Auto/Visual Lisp: [Select]
  1. (defun OSMode->SnapList  (osmode / n)
  2.   (setq n -1)
  3.   (if (< 0 osmode 16383)
  4.     (vl-remove-if (function (lambda (snap) (zerop (logand osmode (expt 2 (setq n (1+ n)))))))
  5.                   '("END" "MID" "CEN" "NOD" "QUA" "INT" "INS" "PER" "TAN" "NEA" "APP" "EXT" "PAR"))))
  6.  
  7. (defun get-SnapList () (OSMode->SnapList (getvar 'OSMode)))
  8.  
  9. (defun set-SnapList  (Snaps / AllSnaps)
  10.   (setq AllSnaps '("END" "MID" "CEN" "NOD" "QUA" "INT" "INS" "PER" "TAN" "NEA" "APP" "EXT" "PAR"))
  11.   (setvar 'OSMode (apply 'logior
  12.                          (mapcar (function (lambda (Snap) (expt 2 (vl-position (strcase (substr Snap 1 3)) AllSnaps))))
  13.                                  Snaps))))

And my version to list which bits are turned on:
Code - Auto/Visual Lisp: [Select]
  1. (defun list-bits (num / pow val res)
  2.   (setq pow 31)
  3.   (while (>= (setq pow (1- pow)) 0)
  4.     (if (> (logand num (setq val (expt 2 pow))) 0)
  5.       (setq res (cons (cons pow val) res))))
  6.   res)
Gives a list stating the 0 based indexes of each bit set followed by its actual value. E.g.
Code: [Select]
_$ (list-bits 123456)
((6 . 64) (9 . 512) (13 . 8192) (14 . 16384) (15 . 32768) (16 . 65536))
Title: Re: To check one of osmode is set to on
Post by: Coder on June 10, 2013, 06:30:16 AM
See this thread also:

http://www.theswamp.org/index.php?topic=12786 (http://www.theswamp.org/index.php?topic=12786)

In the same vein, this digression may also be of interest:

http://www.cadtutor.net/forum/showthread.php?61237-I-want-just-Blocks-and-not-Xrefs&p=416106&viewfull=1#post416106 (http://www.cadtutor.net/forum/showthread.php?61237-I-want-just-Blocks-and-not-Xrefs&p=416106&viewfull=1#post416106)

Thank you for time and for these nice links  :-)

And thank you all guys for your relies , now I have lots of examples to learn from .

Many thanks guys