Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

(420 . TrueColor)

11 REPLIES 11
Reply
Message 1 of 12
morgeny
2879 Views, 11 Replies

(420 . TrueColor)

Hello,

 

I was trying to figure out how to do color override for layer in a particular viewport. Right now I think I am completely lost and need help.

 

First, I called (acad_truecolordlg). For color RGB (59 196 95), the function returned (420 . 3916895). Then I opened layer manager and changed a layer in a viewport to this color. I tried to find out what was stored in the Xrecord of that particular layer by

 

(setq LayerPick (vla-item AllLayers layername1))
(setq Dictionary1 (vla-getExtensionDictionary LayerPick))
(setq Record1 (vla-item Dictionary1 0))
(vla-getXRecordData Record1 'Type1 'Value1)

 

The name of Record1 is ADSK_XREC_LAYER_COLOR_OVR.

 

The first question is, Type1 contains 4 group codes, and the third one is 420, while the corresponding item in Value1

is -1036270974. So I got (420 -103627974). I thought the color code in Xrecord was RGB (59 196 95), but it is negative.

 

Another question is, the 2nd item in Type1 is 335, which I thought was the name of viewport, but I checked the corresponding value in Value1, it is (-5943920 -29400974).

 

I wonder what 420 and 335 in the layer's Xrecord (named ADSK_XREC_LAYER_COLOR_OVR) are?

 

 

Thanks,

Xiangyu

11 REPLIES 11
Message 2 of 12
Lee_Mac
in reply to: morgeny

The DXF Group 420 value is the viewport override colour, however, when used with viewport overrides, mleaderstyles, and mleader background masks (and perhaps other items), the value is not an AutoCAD True Colour value, but a different format.

 

DXF Group 335 should be the entity name of a Viewport entity, however, the value of this group may be altered when retrieved using ActiveX rather than Vanilla AutoLISP.

 

Consider retrieving the dictionary data in the following way:

 

(defun getvpoverride ( lay / ent )
    (if
        (and
            (setq ent (tblobjname "layer" lay))
            (setq ent (cdr (assoc 360 (entget ent))))
        )
        (dictsearch ent "adsk_xrec_layer_color_ovr")
    )
)

 

You can convert the negative colour using the following function:

 

;; Negative Colour -> Colour  -  Lee Mac
;; c - [int] Negative colour value

(defun negcolor->color ( c )
    (if (< 0 (logand 16777216 c))
        (last (LM:True->RGB c))
        (if (equal '(0 0 0) (setq c (LM:True->RGB c))) 256 c)
    )
)

;; True -> RGB  -  Lee Mac
;; Args: c - True Colour

(defun LM:True->RGB ( c )
    (list
        (lsh (lsh (fix c) 08) -24)
        (lsh (lsh (fix c) 16) -24)
        (lsh (lsh (fix c) 24) -24)
    )
)

For example:

_$ (negcolor->color -1036919263)
(49 222 33)

_$ (negcolor->color -1023410125)
51

 

However, I'm not sure that the negative colour value shown in your post corresponds to the colour you have stated.

Message 3 of 12
phanaem
in reply to: morgeny

Normaly, standard color is stored in 62 DXF code and true color is stored in 420 code.

In this case, vp color is stored in 420 code, nomater if it is standard or a true color.

To make a difference between them (because, for example, standard color 64 is NOT equal to (0 0 64) true color),

the significant byte in 420 code (normaly 0) is set to 195 for standard color and 194 for true color. By doing this, the bit 31 is set to 1 so the result is a negative number.

 

As an alternative to Lee's negative colour, you can try this:

(defun vp-col->RGB (n / l)
  (setq l (mapcar '(lambda (c) (logand 255 (lsh n (- c)))) '(24 16 8 0)))
  (if (= 195 (car l))
    (last l)
    (cdr l)
  )
)

(defun RGB->vp-col (l)
  (apply '+
    (mapcar 'lsh
      (if (numberp l) (list 195 0 0 l) (cons 194 l))
      '(24 16 8 0)
    )
  )
)

(VP-COL->RGB  -103627974)  -->  (210 195 58)
(VP-COL->RGB -1036467105)  -->  (56 196 95)
(VP-COL->RGB -1023410153)  -->  23

(RGB->VP-COL '(56 196 95)) --> -1036467105
(RGB->VP-COL 23)           --> -1023410153
(RGB->VP-COL 64)           --> -1023410112
(RGB->VP-COL '(0 0 64))    --> -1040187328

 

 

Message 4 of 12
Lee_Mac
in reply to: phanaem

Very good phanaem Smiley Happy

Message 5 of 12
Lee_Mac
in reply to: phanaem

Though, since we are working with bitwise values I think I'd be inclined to use logior over + when combining the four bytes, e.g.:

 

(defun rgb->neg ( l )
    (apply 'logior
        (mapcar 'lsh
            (if (numberp l)
                (list 195 0 0 l)
                (cons 194 l)
            )
           '(24 16 8 0)
        )
    )
)

 

I used 'negative' since this form of colour value is also used for MLeader Styles & MLeader Background Masks in addition to Viewport Colour Overrides, and so I didn't know what to call it Smiley Wink

Message 6 of 12
phanaem
in reply to: Lee_Mac

Hi Lee

 

It makes perfect sense to use  logior. Thanks.

 

"Negative color" is just fine. I did not mean to criticize your choice. I just quoted your words.

 

Cheers!

Message 7 of 12
Lee_Mac
in reply to: phanaem

No problem at all phanaem -

 

Thank you once again for contributing your solution to the thread, I really like the way that you obtained the byte values using logand as opposed to my multiple calls to lsh.

 

Cheers my friend! Smiley Happy

Message 8 of 12
morgeny
in reply to: Lee_Mac

Thank you very much for the reply. I was able to retrieve the dictionary by using

 

(set ent (cdr (assoc 360 (entget ent))))

 

I checked the help, it explains group 360 as Hard-owner ID/handle to owner dictionary (optional), and there is another group 330, which is Soft-pointer ID/handle to owner dictionary (optional). I don't understand those explanation.

So I am still wondering how the dictionary and layer are connected by group 360? And what is the difference between group 330 and 360. I compared the values for 330 and 360 in the dictionary ent, they are obviously different: group 330 is the entity name of the layer, while there are two values for 360, and I have no idea what they are.

 

 

Thanks a lot!

Xiangyu

 

 

Message 9 of 12
mailmaverick
in reply to: morgeny

Dear Lee,

 

Thanks for your valuable replies. But I don't know the difference between following functions :-

 

(Do they perform exactly same operation ? Also which is better to use ?)

 

1.) SET OF FUNCTIONS 1 :

(defun RGB->vp-col (l)
(apply '+
(mapcar 'lsh
(if (numberp l)
(list 195 0 0 l)
(cons 194 l))
'(24 16 8 0))))

 

and


(defun rgb->neg (l)
(apply 'logior
(mapcar 'lsh
(if (numberp l)
(list 195 0 0 l)
(cons 194 l))
'(24 16 8 0))))

 

Both above functions give same result.

 

2.) SET OF FUNCTIONS 2 :

(defun vp-col->RGB (n / l)
(setq l (mapcar '(lambda (c) (logand 255 (lsh n (- c)))) '(24 16 8 0)))
(if (= 195 (car l))
(last l)
(cdr l)))

 

and

 

(defun negcolor->color (c)
(if (< 0 (logand 16777216 c))
(last (LM:True->RGB c))
(if (equal '(0 0 0) (setq c (LM:True->RGB c)))
256
c)))

 

(defun LM:True->RGB (c)
(list (lsh (lsh (fix c) 08) -24) (lsh (lsh (fix c) 16) -24) (lsh (lsh (fix c) 24) -24)))

 

All the three above functions give same result.

 

 

Message 10 of 12
Lee_Mac
in reply to: mailmaverick

Yes, they perform the same operation -there are usually many different ways to tackle the same problem in LISP

Message 11 of 12
mailmaverick
in reply to: Lee_Mac

Dear Lee,

 

Thanks for you reply. 

 

But if there are different ways, then there must be the best way.

 

Which one is it ?

 

Message 12 of 12
Lee_Mac
in reply to: mailmaverick

Well that depends on your definition of what is 'best' where coding is concerned -

Most efficient? Most elegant? Most readable?

 

Though of course, such attributes would also be subjective.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost