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