0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / Quantity / Quantity_Color.hxx
CommitLineData
42cf5bc1 1// Created by: NW,JPB,CAL
2// Copyright (c) 1991-1999 Matra Datavision
3// Copyright (c) 1999-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#ifndef _Quantity_Color_HeaderFile
17#define _Quantity_Color_HeaderFile
18
19#include <Standard.hxx>
20#include <Standard_DefineAlloc.hxx>
21#include <Standard_Handle.hxx>
42cf5bc1 22#include <Standard_ShortReal.hxx>
59ee34ef 23
42cf5bc1 24#include <Quantity_NameOfColor.hxx>
42cf5bc1 25#include <Quantity_TypeOfColor.hxx>
59ee34ef 26#include <TCollection_AsciiString.hxx>
b6472664 27#include <NCollection_Vec4.hxx>
aaf8d6a9 28
29//! This class allows the definition of an RGB color as triplet of 3 normalized floating point values (red, green, blue).
ba00aab7 30//!
31//! Although Quantity_Color can be technically used for pass-through storage of RGB triplet in any color space,
32//! other OCCT interfaces taking/returning Quantity_Color would expect them in linear space.
33//! Therefore, take a look into methods converting to and from non-linear sRGB color space, if needed;
34//! for instance, application usually providing color picking within 0..255 range in sRGB color space.
aaf8d6a9 35class Quantity_Color
42cf5bc1 36{
37public:
38
39 DEFINE_STANDARD_ALLOC
40
aaf8d6a9 41 //! Creates Quantity_NOC_YELLOW color (for historical reasons).
42 Quantity_Color() : myRgb (valuesOf (Quantity_NOC_YELLOW, Quantity_TOC_RGB)) {}
43
59ee34ef 44 //! Creates the color from enumeration value.
aaf8d6a9 45 Quantity_Color (const Quantity_NameOfColor theName) : myRgb (valuesOf (theName, Quantity_TOC_RGB)) {}
46
82cf4904 47 //! Creates a color according to the definition system theType.
aaf8d6a9 48 //! Throws exception if values are out of range.
14b741b0 49 Standard_EXPORT Quantity_Color (const Standard_Real theC1,
50 const Standard_Real theC2,
51 const Standard_Real theC3,
82cf4904 52 const Quantity_TypeOfColor theType);
b6472664 53
14b741b0 54 //! Define color from linear RGB values.
b6472664 55 Standard_EXPORT explicit Quantity_Color (const NCollection_Vec3<float>& theRgb);
56
aaf8d6a9 57 //! Returns the name of the nearest color from the Quantity_NameOfColor enumeration.
58 Standard_EXPORT Quantity_NameOfColor Name() const;
59
60 //! Updates the color from specified named color.
61 void SetValues (const Quantity_NameOfColor theName) { myRgb = valuesOf (theName, Quantity_TOC_RGB); }
62
14b741b0 63 //! Return the color as vector of 3 float elements.
64 const NCollection_Vec3<float>& Rgb () const { return myRgb; }
65
aaf8d6a9 66 //! Return the color as vector of 3 float elements.
67 operator const NCollection_Vec3<float>&() const { return myRgb; }
68
14b741b0 69 //! Returns in theC1, theC2 and theC3 the components of this color
70 //! according to the color system definition theType.
71 Standard_EXPORT void Values (Standard_Real& theC1,
72 Standard_Real& theC2,
73 Standard_Real& theC3,
aaf8d6a9 74 const Quantity_TypeOfColor theType) const;
75
82cf4904 76 //! Updates a color according to the mode specified by theType.
aaf8d6a9 77 //! Throws exception if values are out of range.
14b741b0 78 Standard_EXPORT void SetValues (const Standard_Real theC1,
79 const Standard_Real theC2,
80 const Standard_Real theC3,
82cf4904 81 const Quantity_TypeOfColor theType);
aaf8d6a9 82
83 //! Returns the Red component (quantity of red) of the color within range [0.0; 1.0].
84 Standard_Real Red() const { return myRgb.r(); }
85
82cf4904 86 //! Returns the Green component (quantity of green) of the color within range [0.0; 1.0].
aaf8d6a9 87 Standard_Real Green() const { return myRgb.g(); }
88
89 //! Returns the Blue component (quantity of blue) of the color within range [0.0; 1.0].
90 Standard_Real Blue() const { return myRgb.b(); }
91
82cf4904 92 //! Returns the Hue component (hue angle) of the color
93 //! in degrees within range [0.0; 360.0], 0.0 being Red.
94 //! -1.0 is a special value reserved for grayscale color (S should be 0.0)
ba00aab7 95 Standard_Real Hue() const { return Convert_LinearRGB_To_HLS (myRgb)[0]; }
aaf8d6a9 96
82cf4904 97 //! Returns the Light component (value of the lightness) of the color within range [0.0; 1.0].
ba00aab7 98 Standard_Real Light() const { return Convert_LinearRGB_To_HLS (myRgb)[1]; }
aaf8d6a9 99
100 //! Increases or decreases the intensity (variation of the lightness).
101 //! The delta is a percentage. Any value greater than zero will increase the intensity.
102 //! The variation is expressed as a percentage of the current value.
103 Standard_EXPORT void ChangeIntensity (const Standard_Real theDelta);
104
82cf4904 105 //! Returns the Saturation component (value of the saturation) of the color within range [0.0; 1.0].
ba00aab7 106 Standard_Real Saturation() const { return Convert_LinearRGB_To_HLS (myRgb)[2]; }
b6472664 107
aaf8d6a9 108 //! Increases or decreases the contrast (variation of the saturation).
109 //! The delta is a percentage. Any value greater than zero will increase the contrast.
110 //! The variation is expressed as a percentage of the current value.
111 Standard_EXPORT void ChangeContrast (const Standard_Real theDelta);
b6472664 112
aaf8d6a9 113 //! Returns TRUE if the distance between two colors is greater than Epsilon().
ba00aab7 114 Standard_Boolean IsDifferent (const Quantity_Color& theOther) const { return (SquareDistance (theOther) > Epsilon() * Epsilon()); }
aaf8d6a9 115
116 //! Alias to IsDifferent().
117 Standard_Boolean operator!= (const Quantity_Color& theOther) const { return IsDifferent (theOther); }
118
119 //! Returns TRUE if the distance between two colors is no greater than Epsilon().
ba00aab7 120 Standard_Boolean IsEqual (const Quantity_Color& theOther) const { return (SquareDistance (theOther) <= Epsilon() * Epsilon()); }
aaf8d6a9 121
122 //! Alias to IsEqual().
123 Standard_Boolean operator== (const Quantity_Color& theOther) const { return IsEqual (theOther); }
42cf5bc1 124
aaf8d6a9 125 //! Returns the distance between two colors. It's a value between 0 and the square root of 3 (the black/white distance).
126 Standard_Real Distance (const Quantity_Color& theColor) const
127 {
128 return (NCollection_Vec3<Standard_Real> (myRgb) - NCollection_Vec3<Standard_Real> (theColor.myRgb)).Modulus();
129 }
130
131 //! Returns the square of distance between two colors.
132 Standard_Real SquareDistance (const Quantity_Color& theColor) const
133 {
134 return (NCollection_Vec3<Standard_Real> (myRgb) - NCollection_Vec3<Standard_Real> (theColor.myRgb)).SquareModulus();
135 }
136
137 //! Returns the percentage change of contrast and intensity between this and another color.
138 //! <DC> and <DI> are percentages, either positive or negative.
139 //! The calculation is with respect to this color.
140 //! If <DC> is positive then <me> is more contrasty.
141 //! If <DI> is positive then <me> is more intense.
142 Standard_EXPORT void Delta (const Quantity_Color& theColor,
143 Standard_Real& DC, Standard_Real& DI) const;
144
14b741b0 145 //! Returns the value of the perceptual difference between this color
146 //! and @p theOther, computed using the CIEDE2000 formula.
147 //! The difference is in range [0, 100.], with 1 approximately corresponding
148 //! to the minimal percievable difference (usually difference 5 or greater is
149 //! needed for the difference to be recognizable in practice).
150 Standard_EXPORT Standard_Real DeltaE2000 (const Quantity_Color& theOther) const;
151
aaf8d6a9 152public:
153
154 //! Returns the color from Quantity_NameOfColor enumeration nearest to specified RGB values.
155 static Quantity_NameOfColor Name (const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
156 {
157 const Quantity_Color aColor (theR, theG, theB, Quantity_TOC_RGB);
158 return aColor.Name();
159 }
160
161 //! Returns the name of the color identified by the given Quantity_NameOfColor enumeration value.
162 Standard_EXPORT static Standard_CString StringName (const Quantity_NameOfColor theColor);
163
42cf5bc1 164 //! Finds color from predefined names.
aaf8d6a9 165 //! For example, the name of the color which corresponds to "BLACK" is Quantity_NOC_BLACK.
166 //! Returns FALSE if name is unknown.
42cf5bc1 167 Standard_EXPORT static Standard_Boolean ColorFromName (const Standard_CString theName, Quantity_NameOfColor& theColor);
f9b30c0d 168
169 //! Finds color from predefined names.
f9b30c0d 170 //! @param theColorNameString the color name
171 //! @param theColor a found color
172 //! @return false if the color name is unknown, or true if the search by color name was successful
173 static Standard_Boolean ColorFromName (const Standard_CString theColorNameString, Quantity_Color& theColor)
174 {
175 Quantity_NameOfColor aColorName = Quantity_NOC_BLACK;
176 if (!ColorFromName (theColorNameString, aColorName))
177 {
178 return false;
179 }
180 theColor = aColorName;
181 return true;
182 }
183
14b741b0 184public:
185 //!@name Routines converting colors between different encodings and color spaces
186
aaf8d6a9 187 //! Parses the string as a hex color (like "#FF0" for short sRGB color, or "#FFFF00" for sRGB color)
f9b30c0d 188 //! @param theHexColorString the string to be parsed
189 //! @param theColor a color that is a result of parsing
190 //! @return true if parsing was successful, or false otherwise
191 Standard_EXPORT static bool ColorFromHex (const Standard_CString theHexColorString, Quantity_Color& theColor);
192
59ee34ef 193 //! Returns hex sRGB string in format "#FFAAFF".
9196ea9d 194 static TCollection_AsciiString ColorToHex (const Quantity_Color& theColor,
195 const bool theToPrefixHash = true)
59ee34ef 196 {
ba00aab7 197 NCollection_Vec3<Standard_ShortReal> anSRgb = Convert_LinearRGB_To_sRGB ((NCollection_Vec3<Standard_ShortReal> )theColor);
9196ea9d 198 NCollection_Vec3<Standard_Integer> anSRgbInt (anSRgb * 255.0f + NCollection_Vec3<Standard_ShortReal> (0.5f));
59ee34ef 199 char aBuff[10];
9196ea9d 200 Sprintf (aBuff, theToPrefixHash ? "#%02X%02X%02X" : "%02X%02X%02X",
201 anSRgbInt.r(), anSRgbInt.g(), anSRgbInt.b());
59ee34ef 202 return aBuff;
203 }
204
aaf8d6a9 205 //! Converts sRGB components into HLS ones.
206 Standard_EXPORT static NCollection_Vec3<float> Convert_sRGB_To_HLS (const NCollection_Vec3<float>& theRgb);
207
42cf5bc1 208 //! Converts HLS components into RGB ones.
aaf8d6a9 209 Standard_EXPORT static NCollection_Vec3<float> Convert_HLS_To_sRGB (const NCollection_Vec3<float>& theHls);
210
211 //! Converts Linear RGB components into HLS ones.
212 static NCollection_Vec3<float> Convert_LinearRGB_To_HLS (const NCollection_Vec3<float>& theRgb)
213 {
214 return Convert_sRGB_To_HLS (Convert_LinearRGB_To_sRGB (theRgb));
215 }
216
217 //! Converts HLS components into linear RGB ones.
218 static NCollection_Vec3<float> Convert_HLS_To_LinearRGB (const NCollection_Vec3<float>& theHls)
219 {
220 return Convert_sRGB_To_LinearRGB (Convert_HLS_To_sRGB (theHls));
221 }
222
14b741b0 223 //! Converts linear RGB components into CIE Lab ones.
224 Standard_EXPORT static NCollection_Vec3<float> Convert_LinearRGB_To_Lab (const NCollection_Vec3<float>& theRgb);
225
226 //! Converts CIE Lab components into CIE Lch ones.
227 Standard_EXPORT static NCollection_Vec3<float> Convert_Lab_To_Lch (const NCollection_Vec3<float>& theLab);
228
229 //! Converts CIE Lab components into linear RGB ones.
230 //! Note that the resulting values may be out of the valid range for RGB.
231 Standard_EXPORT static NCollection_Vec3<float> Convert_Lab_To_LinearRGB (const NCollection_Vec3<float>& theLab);
232
233 //! Converts CIE Lch components into CIE Lab ones.
234 Standard_EXPORT static NCollection_Vec3<float> Convert_Lch_To_Lab (const NCollection_Vec3<float>& theLch);
235
aaf8d6a9 236 //! Convert the color value to ARGB integer value, with alpha equals to 0.
237 //! So the output is formatted as 0x00RRGGBB.
ba00aab7 238 //! Note that this unpacking does NOT involve non-linear sRGB -> linear RGB conversion,
239 //! as would be usually expected for RGB color packed into 4 bytes.
aaf8d6a9 240 //! @param theColor [in] color to convert
241 //! @param theARGB [out] result color encoded as integer
242 static void Color2argb (const Quantity_Color& theColor,
243 Standard_Integer& theARGB)
244 {
245 const NCollection_Vec3<Standard_Integer> aColor (static_cast<Standard_Integer> (255.0f * theColor.myRgb.r() + 0.5f),
246 static_cast<Standard_Integer> (255.0f * theColor.myRgb.g() + 0.5f),
247 static_cast<Standard_Integer> (255.0f * theColor.myRgb.b() + 0.5f));
248 theARGB = (((aColor.r() & 0xff) << 16)
249 | ((aColor.g() & 0xff) << 8)
250 | (aColor.b() & 0xff));
251 }
252
ba00aab7 253 //! Convert integer ARGB value to Color. Alpha bits are ignored.
254 //! Note that this packing does NOT involve linear -> non-linear sRGB conversion,
255 //! as would be usually expected to preserve higher (for human eye) color precision in 4 bytes.
aaf8d6a9 256 static void Argb2color (const Standard_Integer theARGB,
257 Quantity_Color& theColor)
258 {
259 const NCollection_Vec3<Standard_Real> aColor (static_cast <Standard_Real> ((theARGB & 0xff0000) >> 16),
260 static_cast <Standard_Real> ((theARGB & 0x00ff00) >> 8),
261 static_cast <Standard_Real> ((theARGB & 0x0000ff)));
ba00aab7 262 theColor.SetValues (aColor.r() / 255.0, aColor.g() / 255.0, aColor.b() / 255.0, Quantity_TOC_sRGB);
aaf8d6a9 263 }
264
aaf8d6a9 265 //! Convert linear RGB component into sRGB using OpenGL specs formula (double precision), also known as gamma correction.
266 static Standard_Real Convert_LinearRGB_To_sRGB (Standard_Real theLinearValue)
267 {
268 return theLinearValue <= 0.0031308
269 ? theLinearValue * 12.92
270 : Pow (theLinearValue, 1.0/2.4) * 1.055 - 0.055;
271 }
272
273 //! Convert linear RGB component into sRGB using OpenGL specs formula (single precision), also known as gamma correction.
274 static float Convert_LinearRGB_To_sRGB (float theLinearValue)
275 {
276 return theLinearValue <= 0.0031308f
277 ? theLinearValue * 12.92f
278 : powf (theLinearValue, 1.0f/2.4f) * 1.055f - 0.055f;
279 }
280
281 //! Convert sRGB component into linear RGB using OpenGL specs formula (double precision), also known as gamma correction.
282 static Standard_Real Convert_sRGB_To_LinearRGB (Standard_Real thesRGBValue)
283 {
284 return thesRGBValue <= 0.04045
285 ? thesRGBValue / 12.92
286 : Pow ((thesRGBValue + 0.055) / 1.055, 2.4);
287 }
288
289 //! Convert sRGB component into linear RGB using OpenGL specs formula (single precision), also known as gamma correction.
290 static float Convert_sRGB_To_LinearRGB (float thesRGBValue)
291 {
292 return thesRGBValue <= 0.04045f
293 ? thesRGBValue / 12.92f
294 : powf ((thesRGBValue + 0.055f) / 1.055f, 2.4f);
295 }
296
297 //! Convert linear RGB components into sRGB using OpenGL specs formula.
298 template<typename T>
299 static NCollection_Vec3<T> Convert_LinearRGB_To_sRGB (const NCollection_Vec3<T>& theRGB)
300 {
301 return NCollection_Vec3<T> (Convert_LinearRGB_To_sRGB (theRGB.r()),
302 Convert_LinearRGB_To_sRGB (theRGB.g()),
303 Convert_LinearRGB_To_sRGB (theRGB.b()));
304 }
305
306 //! Convert sRGB components into linear RGB using OpenGL specs formula.
307 template<typename T>
308 static NCollection_Vec3<T> Convert_sRGB_To_LinearRGB (const NCollection_Vec3<T>& theRGB)
309 {
310 return NCollection_Vec3<T> (Convert_sRGB_To_LinearRGB (theRGB.r()),
311 Convert_sRGB_To_LinearRGB (theRGB.g()),
312 Convert_sRGB_To_LinearRGB (theRGB.b()));
313 }
314
aaf8d6a9 315 //! Convert linear RGB component into sRGB using approximated uniform gamma coefficient 2.2.
316 static float Convert_LinearRGB_To_sRGB_approx22 (float theLinearValue) { return powf (theLinearValue, 2.2f); }
317
318 //! Convert sRGB component into linear RGB using approximated uniform gamma coefficient 2.2
319 static float Convert_sRGB_To_LinearRGB_approx22 (float thesRGBValue) { return powf (thesRGBValue, 1.0f/2.2f); }
320
321 //! Convert linear RGB components into sRGB using approximated uniform gamma coefficient 2.2
322 static NCollection_Vec3<float> Convert_LinearRGB_To_sRGB_approx22 (const NCollection_Vec3<float>& theRGB)
323 {
324 return NCollection_Vec3<float> (Convert_LinearRGB_To_sRGB_approx22 (theRGB.r()),
325 Convert_LinearRGB_To_sRGB_approx22 (theRGB.g()),
326 Convert_LinearRGB_To_sRGB_approx22 (theRGB.b()));
327 }
328
329 //! Convert sRGB components into linear RGB using approximated uniform gamma coefficient 2.2
330 static NCollection_Vec3<float> Convert_sRGB_To_LinearRGB_approx22 (const NCollection_Vec3<float>& theRGB)
331 {
332 return NCollection_Vec3<float> (Convert_sRGB_To_LinearRGB_approx22 (theRGB.r()),
333 Convert_sRGB_To_LinearRGB_approx22 (theRGB.g()),
334 Convert_sRGB_To_LinearRGB_approx22 (theRGB.b()));
335 }
336
ba00aab7 337 //! Converts HLS components into sRGB ones.
aaf8d6a9 338 static void HlsRgb (const Standard_Real theH, const Standard_Real theL, const Standard_Real theS,
339 Standard_Real& theR, Standard_Real& theG, Standard_Real& theB)
340 {
341 const NCollection_Vec3<float> anRgb = Convert_HLS_To_sRGB (NCollection_Vec3<float> ((float )theH, (float )theL, (float )theS));
342 theR = anRgb[0];
343 theG = anRgb[1];
344 theB = anRgb[2];
345 }
346
ba00aab7 347 //! Converts sRGB components into HLS ones.
aaf8d6a9 348 static void RgbHls (const Standard_Real theR, const Standard_Real theG, const Standard_Real theB,
349 Standard_Real& theH, Standard_Real& theL, Standard_Real& theS)
350 {
351 const NCollection_Vec3<float> aHls = Convert_sRGB_To_HLS (NCollection_Vec3<float> ((float )theR, (float )theG, (float )theB));
352 theH = aHls[0];
353 theL = aHls[1];
354 theS = aHls[2];
355 }
356
14b741b0 357public:
358
359 //! Returns the value used to compare two colors for equality; 0.0001 by default.
360 Standard_EXPORT static Standard_Real Epsilon();
361
362 //! Set the value used to compare two colors for equality.
363 Standard_EXPORT static void SetEpsilon (const Standard_Real theEpsilon);
42cf5bc1 364
0904aa63 365 //! Dumps the content of me into the stream
bc73b006 366 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0904aa63 367
42cf5bc1 368private:
369
aaf8d6a9 370 //! Returns the values of a predefined color according to the mode.
371 Standard_EXPORT static NCollection_Vec3<float> valuesOf (const Quantity_NameOfColor theName,
372 const Quantity_TypeOfColor theType);
373
374private:
375
376 NCollection_Vec3<float> myRgb;
42cf5bc1 377
42cf5bc1 378};
379
42cf5bc1 380#endif // _Quantity_Color_HeaderFile