File indexing completed on 2026-07-29 09:16:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef _Quantity_Color_HeaderFile
0017 #define _Quantity_Color_HeaderFile
0018
0019 #include <Standard.hxx>
0020 #include <Standard_DefineAlloc.hxx>
0021 #include <Standard_Handle.hxx>
0022 #include <Standard_HashUtils.hxx>
0023 #include <Standard_ShortReal.hxx>
0024
0025 #include <Quantity_NameOfColor.hxx>
0026 #include <Quantity_TypeOfColor.hxx>
0027 #include <NCollection_Vec4.hxx>
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 class Quantity_Color
0038 {
0039 public:
0040 DEFINE_STANDARD_ALLOC
0041
0042
0043 Quantity_Color()
0044 : myRgb(valuesOf(Quantity_NOC_YELLOW, Quantity_TOC_RGB))
0045 {
0046 }
0047
0048
0049 Quantity_Color(const Quantity_NameOfColor theName)
0050 : myRgb(valuesOf(theName, Quantity_TOC_RGB))
0051 {
0052 }
0053
0054
0055
0056 Standard_EXPORT Quantity_Color(const Standard_Real theC1,
0057 const Standard_Real theC2,
0058 const Standard_Real theC3,
0059 const Quantity_TypeOfColor theType);
0060
0061
0062 Standard_EXPORT explicit Quantity_Color(const NCollection_Vec3<float>& theRgb);
0063
0064
0065 Standard_EXPORT Quantity_NameOfColor Name() const;
0066
0067
0068 void SetValues(const Quantity_NameOfColor theName)
0069 {
0070 myRgb = valuesOf(theName, Quantity_TOC_RGB);
0071 }
0072
0073
0074 const NCollection_Vec3<float>& Rgb() const { return myRgb; }
0075
0076
0077 operator const NCollection_Vec3<float>&() const { return myRgb; }
0078
0079
0080
0081 Standard_EXPORT void Values(Standard_Real& theC1,
0082 Standard_Real& theC2,
0083 Standard_Real& theC3,
0084 const Quantity_TypeOfColor theType) const;
0085
0086
0087
0088 Standard_EXPORT void SetValues(const Standard_Real theC1,
0089 const Standard_Real theC2,
0090 const Standard_Real theC3,
0091 const Quantity_TypeOfColor theType);
0092
0093
0094 Standard_Real Red() const { return myRgb.r(); }
0095
0096
0097 Standard_Real Green() const { return myRgb.g(); }
0098
0099
0100 Standard_Real Blue() const { return myRgb.b(); }
0101
0102
0103
0104
0105 Standard_Real Hue() const { return Convert_LinearRGB_To_HLS(myRgb)[0]; }
0106
0107
0108 Standard_Real Light() const { return Convert_LinearRGB_To_HLS(myRgb)[1]; }
0109
0110
0111
0112
0113 Standard_EXPORT void ChangeIntensity(const Standard_Real theDelta);
0114
0115
0116
0117 Standard_Real Saturation() const { return Convert_LinearRGB_To_HLS(myRgb)[2]; }
0118
0119
0120
0121
0122 Standard_EXPORT void ChangeContrast(const Standard_Real theDelta);
0123
0124
0125 Standard_Boolean IsDifferent(const Quantity_Color& theOther) const
0126 {
0127 return (SquareDistance(theOther) > Epsilon() * Epsilon());
0128 }
0129
0130
0131 Standard_Boolean operator!=(const Quantity_Color& theOther) const
0132 {
0133 return IsDifferent(theOther);
0134 }
0135
0136
0137 Standard_Boolean IsEqual(const Quantity_Color& theOther) const
0138 {
0139 return (SquareDistance(theOther) <= Epsilon() * Epsilon());
0140 }
0141
0142
0143 Standard_Boolean operator==(const Quantity_Color& theOther) const { return IsEqual(theOther); }
0144
0145
0146
0147 Standard_Real Distance(const Quantity_Color& theColor) const
0148 {
0149 return (NCollection_Vec3<Standard_Real>(myRgb)
0150 - NCollection_Vec3<Standard_Real>(theColor.myRgb))
0151 .Modulus();
0152 }
0153
0154
0155 Standard_Real SquareDistance(const Quantity_Color& theColor) const
0156 {
0157 return (NCollection_Vec3<Standard_Real>(myRgb)
0158 - NCollection_Vec3<Standard_Real>(theColor.myRgb))
0159 .SquareModulus();
0160 }
0161
0162
0163
0164
0165
0166
0167 Standard_EXPORT void Delta(const Quantity_Color& theColor,
0168 Standard_Real& DC,
0169 Standard_Real& DI) const;
0170
0171
0172
0173
0174
0175
0176 Standard_EXPORT Standard_Real DeltaE2000(const Quantity_Color& theOther) const;
0177
0178 public:
0179
0180 static Quantity_NameOfColor Name(const Standard_Real theR,
0181 const Standard_Real theG,
0182 const Standard_Real theB)
0183 {
0184 const Quantity_Color aColor(theR, theG, theB, Quantity_TOC_RGB);
0185 return aColor.Name();
0186 }
0187
0188
0189 Standard_EXPORT static Standard_CString StringName(const Quantity_NameOfColor theColor);
0190
0191
0192
0193
0194 Standard_EXPORT static Standard_Boolean ColorFromName(const Standard_CString theName,
0195 Quantity_NameOfColor& theColor);
0196
0197
0198
0199
0200
0201 static Standard_Boolean ColorFromName(const Standard_CString theColorNameString,
0202 Quantity_Color& theColor)
0203 {
0204 Quantity_NameOfColor aColorName = Quantity_NOC_BLACK;
0205 if (!ColorFromName(theColorNameString, aColorName))
0206 {
0207 return false;
0208 }
0209 theColor = aColorName;
0210 return true;
0211 }
0212
0213 public:
0214
0215
0216
0217
0218
0219
0220
0221 Standard_EXPORT static bool ColorFromHex(const Standard_CString theHexColorString,
0222 Quantity_Color& theColor);
0223
0224
0225 static TCollection_AsciiString ColorToHex(const Quantity_Color& theColor,
0226 const bool theToPrefixHash = true)
0227 {
0228 NCollection_Vec3<Standard_ShortReal> anSRgb =
0229 Convert_LinearRGB_To_sRGB((NCollection_Vec3<Standard_ShortReal>)theColor);
0230 NCollection_Vec3<Standard_Integer> anSRgbInt(anSRgb * 255.0f
0231 + NCollection_Vec3<Standard_ShortReal>(0.5f));
0232 char aBuff[10];
0233 Sprintf(aBuff,
0234 theToPrefixHash ? "#%02X%02X%02X" : "%02X%02X%02X",
0235 anSRgbInt.r(),
0236 anSRgbInt.g(),
0237 anSRgbInt.b());
0238 return aBuff;
0239 }
0240
0241
0242 Standard_EXPORT static NCollection_Vec3<float> Convert_sRGB_To_HLS(
0243 const NCollection_Vec3<float>& theRgb);
0244
0245
0246 Standard_EXPORT static NCollection_Vec3<float> Convert_HLS_To_sRGB(
0247 const NCollection_Vec3<float>& theHls);
0248
0249
0250 static NCollection_Vec3<float> Convert_LinearRGB_To_HLS(const NCollection_Vec3<float>& theRgb)
0251 {
0252 return Convert_sRGB_To_HLS(Convert_LinearRGB_To_sRGB(theRgb));
0253 }
0254
0255
0256 static NCollection_Vec3<float> Convert_HLS_To_LinearRGB(const NCollection_Vec3<float>& theHls)
0257 {
0258 return Convert_sRGB_To_LinearRGB(Convert_HLS_To_sRGB(theHls));
0259 }
0260
0261
0262 Standard_EXPORT static NCollection_Vec3<float> Convert_LinearRGB_To_Lab(
0263 const NCollection_Vec3<float>& theRgb);
0264
0265
0266 Standard_EXPORT static NCollection_Vec3<float> Convert_Lab_To_Lch(
0267 const NCollection_Vec3<float>& theLab);
0268
0269
0270
0271 Standard_EXPORT static NCollection_Vec3<float> Convert_Lab_To_LinearRGB(
0272 const NCollection_Vec3<float>& theLab);
0273
0274
0275 Standard_EXPORT static NCollection_Vec3<float> Convert_Lch_To_Lab(
0276 const NCollection_Vec3<float>& theLch);
0277
0278
0279
0280
0281
0282
0283
0284 static void Color2argb(const Quantity_Color& theColor, Standard_Integer& theARGB)
0285 {
0286 const NCollection_Vec3<Standard_Integer> aColor(
0287 static_cast<Standard_Integer>(255.0f * theColor.myRgb.r() + 0.5f),
0288 static_cast<Standard_Integer>(255.0f * theColor.myRgb.g() + 0.5f),
0289 static_cast<Standard_Integer>(255.0f * theColor.myRgb.b() + 0.5f));
0290 theARGB = (((aColor.r() & 0xff) << 16) | ((aColor.g() & 0xff) << 8) | (aColor.b() & 0xff));
0291 }
0292
0293
0294
0295
0296 static void Argb2color(const Standard_Integer theARGB, Quantity_Color& theColor)
0297 {
0298 const NCollection_Vec3<Standard_Real> aColor(
0299 static_cast<Standard_Real>((theARGB & 0xff0000) >> 16),
0300 static_cast<Standard_Real>((theARGB & 0x00ff00) >> 8),
0301 static_cast<Standard_Real>((theARGB & 0x0000ff)));
0302 theColor.SetValues(aColor.r() / 255.0,
0303 aColor.g() / 255.0,
0304 aColor.b() / 255.0,
0305 Quantity_TOC_sRGB);
0306 }
0307
0308
0309
0310 static Standard_Real Convert_LinearRGB_To_sRGB(Standard_Real theLinearValue)
0311 {
0312 return theLinearValue <= 0.0031308 ? theLinearValue * 12.92
0313 : Pow(theLinearValue, 1.0 / 2.4) * 1.055 - 0.055;
0314 }
0315
0316
0317
0318 static float Convert_LinearRGB_To_sRGB(float theLinearValue)
0319 {
0320 return theLinearValue <= 0.0031308f ? theLinearValue * 12.92f
0321 : powf(theLinearValue, 1.0f / 2.4f) * 1.055f - 0.055f;
0322 }
0323
0324
0325
0326 static Standard_Real Convert_sRGB_To_LinearRGB(Standard_Real thesRGBValue)
0327 {
0328 return thesRGBValue <= 0.04045 ? thesRGBValue / 12.92
0329 : Pow((thesRGBValue + 0.055) / 1.055, 2.4);
0330 }
0331
0332
0333
0334 static float Convert_sRGB_To_LinearRGB(float thesRGBValue)
0335 {
0336 return thesRGBValue <= 0.04045f ? thesRGBValue / 12.92f
0337 : powf((thesRGBValue + 0.055f) / 1.055f, 2.4f);
0338 }
0339
0340
0341 template <typename T>
0342 static NCollection_Vec3<T> Convert_LinearRGB_To_sRGB(const NCollection_Vec3<T>& theRGB)
0343 {
0344 return NCollection_Vec3<T>(Convert_LinearRGB_To_sRGB(theRGB.r()),
0345 Convert_LinearRGB_To_sRGB(theRGB.g()),
0346 Convert_LinearRGB_To_sRGB(theRGB.b()));
0347 }
0348
0349
0350 template <typename T>
0351 static NCollection_Vec3<T> Convert_sRGB_To_LinearRGB(const NCollection_Vec3<T>& theRGB)
0352 {
0353 return NCollection_Vec3<T>(Convert_sRGB_To_LinearRGB(theRGB.r()),
0354 Convert_sRGB_To_LinearRGB(theRGB.g()),
0355 Convert_sRGB_To_LinearRGB(theRGB.b()));
0356 }
0357
0358
0359 static float Convert_LinearRGB_To_sRGB_approx22(float theLinearValue)
0360 {
0361 return powf(theLinearValue, 2.2f);
0362 }
0363
0364
0365 static float Convert_sRGB_To_LinearRGB_approx22(float thesRGBValue)
0366 {
0367 return powf(thesRGBValue, 1.0f / 2.2f);
0368 }
0369
0370
0371 static NCollection_Vec3<float> Convert_LinearRGB_To_sRGB_approx22(
0372 const NCollection_Vec3<float>& theRGB)
0373 {
0374 return NCollection_Vec3<float>(Convert_LinearRGB_To_sRGB_approx22(theRGB.r()),
0375 Convert_LinearRGB_To_sRGB_approx22(theRGB.g()),
0376 Convert_LinearRGB_To_sRGB_approx22(theRGB.b()));
0377 }
0378
0379
0380 static NCollection_Vec3<float> Convert_sRGB_To_LinearRGB_approx22(
0381 const NCollection_Vec3<float>& theRGB)
0382 {
0383 return NCollection_Vec3<float>(Convert_sRGB_To_LinearRGB_approx22(theRGB.r()),
0384 Convert_sRGB_To_LinearRGB_approx22(theRGB.g()),
0385 Convert_sRGB_To_LinearRGB_approx22(theRGB.b()));
0386 }
0387
0388
0389 static void HlsRgb(const Standard_Real theH,
0390 const Standard_Real theL,
0391 const Standard_Real theS,
0392 Standard_Real& theR,
0393 Standard_Real& theG,
0394 Standard_Real& theB)
0395 {
0396 const NCollection_Vec3<float> anRgb =
0397 Convert_HLS_To_sRGB(NCollection_Vec3<float>((float)theH, (float)theL, (float)theS));
0398 theR = anRgb[0];
0399 theG = anRgb[1];
0400 theB = anRgb[2];
0401 }
0402
0403
0404 static void RgbHls(const Standard_Real theR,
0405 const Standard_Real theG,
0406 const Standard_Real theB,
0407 Standard_Real& theH,
0408 Standard_Real& theL,
0409 Standard_Real& theS)
0410 {
0411 const NCollection_Vec3<float> aHls =
0412 Convert_sRGB_To_HLS(NCollection_Vec3<float>((float)theR, (float)theG, (float)theB));
0413 theH = aHls[0];
0414 theL = aHls[1];
0415 theS = aHls[2];
0416 }
0417
0418 public:
0419
0420 Standard_EXPORT static Standard_Real Epsilon();
0421
0422
0423 Standard_EXPORT static void SetEpsilon(const Standard_Real theEpsilon);
0424
0425
0426 Standard_EXPORT void DumpJson(Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0427
0428
0429 Standard_EXPORT Standard_Boolean InitFromJson(const Standard_SStream& theSStream,
0430 Standard_Integer& theStreamPos);
0431
0432 private:
0433
0434 Standard_EXPORT static NCollection_Vec3<float> valuesOf(const Quantity_NameOfColor theName,
0435 const Quantity_TypeOfColor theType);
0436
0437 private:
0438 NCollection_Vec3<float> myRgb;
0439 };
0440
0441 namespace std
0442 {
0443 template <>
0444 struct hash<Quantity_Color>
0445 {
0446 std::size_t operator()(const Quantity_Color& theColor) const noexcept
0447 {
0448 unsigned char aByteArr[3] = {static_cast<unsigned char>(255 * theColor.Red()),
0449 static_cast<unsigned char>(255 * theColor.Green()),
0450 static_cast<unsigned char>(255 * theColor.Blue())};
0451 return opencascade::hashBytes(aByteArr, sizeof(aByteArr));
0452 }
0453 };
0454 }
0455
0456 #endif