Hello,
'cause I just translate the OLEColor.htm and the Color.htm:
If you use the (acad_truecolordlg)-function of AutoCAD to change the color of an object or a layer you have to work quite differently to OpenDCL to get the right OLEColorIndex. Here is a sample:
this r g b color is given:
(setq lstRGB (list 123 234 56))
When preset the right color in (acad_truecolordlg ...) I have to make
(setq lstRGBForAcad (reverse lstRGB))
(setq intRGBForAcad (+ (+ (lsh (caddr lstRGBForAcad ) 16) (lsh (cadr lstRGBForAcad ) 8 )) (car lstRGBForAcad )))
When set the backcolor of an picturebox to show the changed color I have to make
(setq lstRGBForODCL lstRGB)
(setq intRGBForODCL (+ (+ (lsh (caddr lstRGBForODCL ) 16) (lsh (cadr lstRGBForODCL ) 8 )) (car lstRGBForODCL )))
Just for whom who needs. I will document this difference in the function GetOLEColorValue.
Fred
I'm having exactly this problem, but I'm not seeing where you are getting your RGB values from.
When the user picks a Truecolor from the Acad Truecolor dialog -- let's say 255,235,51, I get a return value of 16771891.
Yet picking the same color in the OpenDCL Editor, I get 3402751.
How do I convert from acad_truecolordlg return value to what OpenDCL wants?
--J
The difference is :
RGB 255,235,51 is hex FF EB 33 which is decimal 16771891
however ActiveX colors are based on the colors as BGR.
If you feed 33ebff into this
http://www.easycalculation.com/hex-converter.php (http://www.easycalculation.com/hex-converter.php)
you'll get 3402751 which is the OLEColor number needed by OpenDCL
whereas ffeb33 will return 16771891
The ole number is based on
R
+ G*255
+ B*65536
== 3402751
Hope that helps
Quote from: honkinberry on July 21, 2010, 08:57:58 AM
< .. >
How do I convert from acad_truecolordlg return value to what OpenDCL wants?
--J
Forgot to add :
(dcl_GetOLEColorValue (list 255 235 51)) ;=>> 3402751
That helps a bit, but I still have no idea how to decode 16771891 to hex or RGB.
So given an Acad truecolor decimal value...
I decode it into Hex, then reverse the list, then encode back into decimal?
Or, once I've decoded it into Hex, encode just each RGB into decimal, which can be passed to GetOLEColor.
Seems like GetOLEColor either needs an additional parameter or an additional helper function, as this is a pretty standard operation in my opinion.
--J
OK, If you know the Acad truecolor decimal
try this
using this converter
(defun TrueColor-split (c /)
(list
(lsh (fix c) -16)
(lsh (lsh (fix c) 16) -24)
(lsh (lsh (fix c) 24) -24)
)
)
and if the Truecolor is known as 16771891
(dcl_GetOLEColorValue (TrueColor-split 16771891 ))
;;==>> 3402751
and just for completeness
(defun TrueColor-make (r g b /)
(+ (lsh (fix r) 16)
(lsh (fix g) 8)
(fix b)
)
)
(TrueColor-make 255 235 51)
;; returns the TrueColor from RGB
;;==>> 16771891
(defun OCEColor-make (r g b /)
(+ (fix r)
(lsh (fix g) 8)
(lsh (fix b) 16)
)
)
(OCEColor-make 255 235 51)
;; returns the OCEColor from RGB
;;==>> 3402751
You're a genuis!
Thank you.
--J
Well, it's a good thing you're humble, because your work is not done. :)
For some colors, I'm getting Invalid Argument Type.
Here are some of the values that threw the error:
(dcl_getolecolorvalue (18 208 237))
(dcl_getolecolorvalue (19 34 236))
(dcl_getolecolorvalue (222 226 29))
Thanks again for your god-like assistance!
--J
You have to trick AutoCAD into not treating your list as a DXF list. One way to do that is to pass at least one element as a real number (your examples don't quote the list, which I assume is an oversight):
(dcl_getolecolorvalue '(18.0 208 237))
Worked perfectly, thanks!
So of course Truecolor-split becomes:
(defun TrueColor-split (c /)
(list
(+ (lsh (fix c) -16) 0.0)
(lsh (lsh (fix c) 16) -24)
(lsh (lsh (fix c) 24) -24)
)
)
--J
Personally :
I wouldn't change TrueColor-split because the return is correct.
The Problem is with the parameters for dcl_GetOLEColorValue
NOT with the return from TrueColor-split in it's pure form as a stand alone function.
(dcl_GetOLEColorValue (TrueColor-split 16771891 )) works for me .. does it work for you ?
I'd either pre-process the input to dcl_GetOLEColorValue ..
something like
(dcl_GetOLEColorValue (mapcar '+ '(0. 0 0) (TrueColor-split 16771891 ) )) if necessary
or use something like
(defun OCEColor-make_From-TrueColor (c /)
(+ (fix (lsh (fix c) -16))
(lsh (fix (lsh (lsh (fix c) 16) -24)) 8)
(lsh (fix (lsh (lsh (fix c) 24) -24)) 16)
)
)
(OCEColor-make_From-TrueColor 16771891 )
;;=> 3402751
Good point.
Or even wrap GetOLEColorValue with a function that can handle color as an AutoCAD color, even hex value, RGB, whatever, and then converts and preps as necessary.
--J
I know this is an old post but I'm going to add to it anyway.
When using Freds line of code in the original post which converts RGB color to OLE color.
(setq intOLE (+ (+ (lsh (caddr lstRGB) 16) (lsh (cadr lstRGB) 8 )) (car lstRGB)))
It works great until Green and Blue are set to zero and you only have a RED value. When setting a background color of an OpenDCL object, for example a rectangle, it defaults to the Autocad Pallett not versions of RED. So an RGB value of 255,0,0 should be very RED but instead its Autocad pallett of 255 which is White.
I figured out a fix, add 16777216 to Freds results and it works.
For example:
(setq intOLE (+ (+ (+ (lsh (caddr lstRGB) 16) (lsh (cadr lstRGB) 8 )) (car lstRGB)) 16777216))
Hi Eric, sounds interesting, I hadn't that problem yet.
Regards, Fred