mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-21 10:55:33 +03:00
0030623: Draw Harness - support hex color codes within ViewerTest::ParseColor()
ViewerTest::ParseColor() function is improved to be able to parse the following set of input arguments: - "Red Green Blue [Alpha]", where Red, Green, Blue, Alpha must be integers within the range [0, 255] or reals within the range [0.0, 1.0]. Note that "0 0 1" triple is parsed as "0.0 0.0 1.0" and will be interpreted as a blue color. - "ColorName [Alpha]", where ColorName is one of WHITE, BLACK, RED, GREEN, BLUE, etc. (look at Quantity_NameOfColor enumeration for all possible variants). Alpha may be integer or real, as described at the previous list item. - #HHH, [#]HHH[H], [#]HHHHHH[HH], where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F). There are a short hexadecimal RGB, RGBA formats, and a usual RGB[A], respectively.
This commit is contained in:
parent
a5278fc126
commit
f9b30c0db3
@ -96,11 +96,24 @@ public:
|
||||
//! variables, to real value.
|
||||
Standard_EXPORT static Standard_Real Atof (const Standard_CString Name);
|
||||
|
||||
//! Converts the numeric expression, that can involve DRAW variables, to a real value
|
||||
//! @param theExpressionString the strings that containes the expression involving DRAW variables to be parsed
|
||||
//! @param theParsedRealValue a real value that is a result of parsing
|
||||
//! @return true if parsing was successfull, or false otherwise
|
||||
Standard_EXPORT static bool ParseReal (const Standard_CString theExpressionString, Standard_Real& theParsedRealValue);
|
||||
|
||||
//! Converts numeric expression, that can involve DRAW
|
||||
//! variables, to integer value.
|
||||
//! Implemented as cast of Atof() to integer.
|
||||
Standard_EXPORT static Standard_Integer Atoi (const Standard_CString Name);
|
||||
|
||||
//! Converts the numeric expression, that can involve DRAW variables, to an integer value
|
||||
//! @param theExpressionString the strings that containes the expression involving DRAW variables to be parsed
|
||||
//! @param theParsedIntegerValue an integer value that is a result of parsing
|
||||
//! @return true if parsing was successfull, or false otherwise
|
||||
Standard_EXPORT static bool ParseInteger (const Standard_CString theExpressionString,
|
||||
Standard_Integer& theParsedIntegerValue);
|
||||
|
||||
//! Returns last graphic selection description.
|
||||
Standard_EXPORT static void LastPick (Standard_Integer& view, Standard_Integer& X, Standard_Integer& Y, Standard_Integer& button);
|
||||
|
||||
|
@ -1122,6 +1122,7 @@ static Standard_Real Parse(char*& name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Atof
|
||||
// purpose :
|
||||
@ -1132,6 +1133,7 @@ Standard_Real Draw::Atof(const Standard_CString name)
|
||||
char* n = new char[1+strlen(name)];
|
||||
char* b = n;
|
||||
strcpy(n,name);
|
||||
Draw_ParseFailed = Standard_False;
|
||||
Standard_Real x = Parse(n);
|
||||
while ((*n == ' ') || (*n == '\t')) n++;
|
||||
if (*n) Draw_ParseFailed = Standard_True;
|
||||
@ -1139,10 +1141,51 @@ Standard_Real Draw::Atof(const Standard_CString name)
|
||||
return x;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : ParseReal
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
bool Draw::ParseReal (const Standard_CString theExpressionString, Standard_Real& theParsedRealValue)
|
||||
{
|
||||
const Standard_Real aParsedRealValue = Atof (theExpressionString);
|
||||
if (Draw_ParseFailed)
|
||||
{
|
||||
Draw_ParseFailed = Standard_False;
|
||||
return false;
|
||||
}
|
||||
theParsedRealValue = aParsedRealValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Atoi
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer Draw::Atoi(const Standard_CString name)
|
||||
{
|
||||
return (Standard_Integer) Draw::Atof(name);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : ParseInteger
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
bool Draw::ParseInteger (const Standard_CString theExpressionString, Standard_Integer& theParsedIntegerValue)
|
||||
{
|
||||
Standard_Real aParsedRealValue = 0.0;
|
||||
if (!ParseReal (theExpressionString, aParsedRealValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const Standard_Integer aParsedIntegerValue = static_cast<Standard_Integer> (aParsedRealValue);
|
||||
if (static_cast<Standard_Real> (aParsedIntegerValue) != aParsedRealValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theParsedIntegerValue = aParsedIntegerValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Set
|
||||
//purpose : set a TCL var
|
||||
|
@ -49,6 +49,17 @@ public:
|
||||
InitIdentity();
|
||||
}
|
||||
|
||||
//! Conversion constructor (explicitly converts some 4 x 4 matrix with other element type
|
||||
//! to a new 4 x 4 matrix with the element type Element_t,
|
||||
//! whose elements are static_cast'ed corresponding elements of theOtherMat4 matrix)
|
||||
//! @tparam OtherElement_t the element type of the other 4 x 4 matrix theOtherVec4
|
||||
//! @param theOtherMat4 the 4 x 4 matrix that needs to be converted
|
||||
template <typename OtherElement_t>
|
||||
explicit NCollection_Mat4 (const NCollection_Mat4<OtherElement_t>& theOtherMat4)
|
||||
{
|
||||
ConvertFrom (theOtherMat4);
|
||||
}
|
||||
|
||||
//! Get element at the specified row and column.
|
||||
//! @param theRow [in] the row.to address.
|
||||
//! @param theCol [in] the column to address.
|
||||
|
@ -57,6 +57,18 @@ public:
|
||||
v[1] = theY;
|
||||
}
|
||||
|
||||
//! Conversion constructor (explicitly converts some 2-component vector with other element type
|
||||
//! to a new 2-component vector with the element type Element_t,
|
||||
//! whose elements are static_cast'ed corresponding elements of theOtherVec2 vector)
|
||||
//! @tparam OtherElement_t the element type of the other 2-component vector theOtherVec2
|
||||
//! @param theOtherVec2 the 2-component vector that needs to be converted
|
||||
template <typename OtherElement_t>
|
||||
explicit NCollection_Vec2 (const NCollection_Vec2<OtherElement_t>& theOtherVec2)
|
||||
{
|
||||
v[0] = static_cast<Element_t> (theOtherVec2[0]);
|
||||
v[1] = static_cast<Element_t> (theOtherVec2[1]);
|
||||
}
|
||||
|
||||
//! Assign new values to the vector.
|
||||
void SetValues (const Element_t theX,
|
||||
const Element_t theY)
|
||||
|
@ -73,6 +73,19 @@ public:
|
||||
v[2] = theZ;
|
||||
}
|
||||
|
||||
//! Conversion constructor (explicitly converts some 3-component vector with other element type
|
||||
//! to a new 3-component vector with the element type Element_t,
|
||||
//! whose elements are static_cast'ed corresponding elements of theOtherVec3 vector)
|
||||
//! @tparam OtherElement_t the element type of the other 3-component vector theOtherVec3
|
||||
//! @param theOtherVec3 the 3-component vector that needs to be converted
|
||||
template <typename OtherElement_t>
|
||||
explicit NCollection_Vec3 (const NCollection_Vec3<OtherElement_t>& theOtherVec3)
|
||||
{
|
||||
v[0] = static_cast<Element_t> (theOtherVec3[0]);
|
||||
v[1] = static_cast<Element_t> (theOtherVec3[1]);
|
||||
v[2] = static_cast<Element_t> (theOtherVec3[2]);
|
||||
}
|
||||
|
||||
//! Assign new values to the vector.
|
||||
void SetValues (const Element_t theX,
|
||||
const Element_t theY,
|
||||
|
@ -73,6 +73,20 @@ public:
|
||||
v[3] = theW;
|
||||
}
|
||||
|
||||
//! Conversion constructor (explicitly converts some 4-component vector with other element type
|
||||
//! to a new 4-component vector with the element type Element_t,
|
||||
//! whose elements are static_cast'ed corresponding elements of theOtherVec4 vector)
|
||||
//! @tparam OtherElement_t the element type of the other 4-component vector theOtherVec4
|
||||
//! @param theOtherVec4 the 4-component vector that needs to be converted
|
||||
template <typename OtherElement_t>
|
||||
explicit NCollection_Vec4 (const NCollection_Vec4<OtherElement_t>& theOtherVec4)
|
||||
{
|
||||
v[0] = static_cast<Element_t> (theOtherVec4[0]);
|
||||
v[1] = static_cast<Element_t> (theOtherVec4[1]);
|
||||
v[2] = static_cast<Element_t> (theOtherVec4[2]);
|
||||
v[3] = static_cast<Element_t> (theOtherVec4[3]);
|
||||
}
|
||||
|
||||
//! Assign new values to the vector.
|
||||
void SetValues (const Element_t theX,
|
||||
const Element_t theY,
|
||||
|
@ -14,6 +14,7 @@ Quantity_CoefficientOfExpansion.hxx
|
||||
Quantity_Color.cxx
|
||||
Quantity_Color.hxx
|
||||
Quantity_ColorHasher.hxx
|
||||
Quantity_ColorRGBA.cxx
|
||||
Quantity_ColorRGBA.hxx
|
||||
Quantity_ColorRGBAHasher.hxx
|
||||
Quantity_ColorDefinitionError.hxx
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <Quantity_Color.hxx>
|
||||
|
||||
#include <Quantity_ColorDefinitionError.hxx>
|
||||
#include <Quantity_ColorRGBA.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
@ -66,6 +67,21 @@ Standard_Boolean Quantity_Color::ColorFromName (const Standard_CString theName,
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : ColorFromHex
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
bool Quantity_Color::ColorFromHex (const Standard_CString theHexColorString, Quantity_Color& theColor)
|
||||
{
|
||||
Quantity_ColorRGBA aColorRGBA;
|
||||
if (!Quantity_ColorRGBA::ColorFromHex (theHexColorString, aColorRGBA, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theColor = aColorRGBA.GetRGB();
|
||||
return true;
|
||||
}
|
||||
|
||||
Quantity_Color::Quantity_Color () {
|
||||
|
||||
Quantity_Color::ValuesOf
|
||||
|
@ -223,6 +223,30 @@ Standard_Boolean operator == (const Quantity_Color& Other) const
|
||||
//! Returns false if name is unknown.
|
||||
Standard_EXPORT static Standard_Boolean ColorFromName (const Standard_CString theName, Quantity_NameOfColor& theColor);
|
||||
|
||||
//! Finds color from predefined names.
|
||||
//! For example, the name of the color which
|
||||
//! corresponds to "BLACK" is Quantity_NOC_BLACK.
|
||||
//! Returns false if name is unknown.
|
||||
//! @param theColorNameString the color name
|
||||
//! @param theColor a found color
|
||||
//! @return false if the color name is unknown, or true if the search by color name was successful
|
||||
static Standard_Boolean ColorFromName (const Standard_CString theColorNameString, Quantity_Color& theColor)
|
||||
{
|
||||
Quantity_NameOfColor aColorName = Quantity_NOC_BLACK;
|
||||
if (!ColorFromName (theColorNameString, aColorName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theColor = aColorName;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Parses the string as a hex color (like "#FF0" for short RGB color, or "#FFFF00" for RGB color)
|
||||
//! @param theHexColorString the string to be parsed
|
||||
//! @param theColor a color that is a result of parsing
|
||||
//! @return true if parsing was successful, or false otherwise
|
||||
Standard_EXPORT static bool ColorFromHex (const Standard_CString theHexColorString, Quantity_Color& theColor);
|
||||
|
||||
//! Converts HLS components into RGB ones.
|
||||
Standard_EXPORT static void HlsRgb (const Standard_Real H, const Standard_Real L, const Standard_Real S, Standard_Real& R, Standard_Real& G, Standard_Real& B);
|
||||
|
||||
|
200
src/Quantity/Quantity_ColorRGBA.cxx
Normal file
200
src/Quantity/Quantity_ColorRGBA.cxx
Normal file
@ -0,0 +1,200 @@
|
||||
// Created on: 2019-03-22
|
||||
// Created by: Timur Izmaylov
|
||||
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <Quantity_ColorRGBA.hxx>
|
||||
|
||||
#include <Graphic3d_Vec4.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
//! The integer type used to represent some color or color component
|
||||
typedef unsigned int ColorInteger;
|
||||
|
||||
//! Defines all possible lengths of strings representing color in hex format
|
||||
enum HexColorLength
|
||||
{
|
||||
HexColorLength_ShortRGB = 3, //!< short RGB hex color format
|
||||
HexColorLength_ShortRGBA = 4, //!< short RGBA hex color format
|
||||
HexColorLength_RGB = 6, //!< RGB hex color format
|
||||
HexColorLength_RGBA = 8 //!< RGBA hex color format
|
||||
};
|
||||
|
||||
//! Takes next color component from the integer representing a color (it is a step in a process of a conversion
|
||||
//! implemented by the function ConvertIntegerToColorRGBA)
|
||||
//! @param theColorInteger the integer representing a color
|
||||
//! @param theColorComponentBase the base of the numeral system used to represent a color
|
||||
//! @return a color component taken from the integer
|
||||
static Standard_ShortReal takeColorComponentFromInteger (ColorInteger& theColorInteger,
|
||||
const ColorInteger theColorComponentBase)
|
||||
{
|
||||
Standard_ASSERT_RETURN (theColorComponentBase >= 2,
|
||||
__FUNCTION__ ": 'theColorComponentBase' must be greater than 1.",
|
||||
0.0f);
|
||||
const ColorInteger aColorComponentMaxValue = theColorComponentBase - 1;
|
||||
const ColorInteger aColorComponentAsInteger = theColorInteger % theColorComponentBase;
|
||||
const Standard_ShortReal aColorComponent = aColorComponentAsInteger * 1.0f / aColorComponentMaxValue;
|
||||
theColorInteger /= theColorComponentBase;
|
||||
return aColorComponent;
|
||||
}
|
||||
|
||||
//! Converts the integer representing a color to a RGBA color object
|
||||
//! @param theColorInteger the integer representing a color (using the numerical system based
|
||||
//! on theColorComponentBase value, where color components represent digits:
|
||||
//! an alpha component is a low number and a red component is a high number)
|
||||
//! @param theColorComponentBase the base of the numeral system used to represent a color
|
||||
//! @param hasAlphaComponent true if the integer to be converted contains an alpha component value
|
||||
//! @param theColor a color that is a result of a conversion
|
||||
//! @return true if a conversion was successful, or false otherwise
|
||||
static bool convertIntegerToColorRGBA (ColorInteger theColorInteger,
|
||||
const ColorInteger theColorComponentBase,
|
||||
const bool hasAlphaComponent,
|
||||
Quantity_ColorRGBA& theColor)
|
||||
{
|
||||
Standard_ASSERT_RETURN (theColorComponentBase >= 2,
|
||||
__FUNCTION__ ": 'theColorComponentBase' must be greater than 1.",
|
||||
0.0f);
|
||||
Graphic3d_Vec4 aColor (1.0f);
|
||||
if (hasAlphaComponent)
|
||||
{
|
||||
const Standard_ShortReal anAlphaComponent = takeColorComponentFromInteger (theColorInteger,
|
||||
theColorComponentBase);
|
||||
aColor.a() = anAlphaComponent;
|
||||
}
|
||||
for (Standard_Integer aColorComponentIndex = 2; aColorComponentIndex >= 0; --aColorComponentIndex)
|
||||
{
|
||||
const Standard_ShortReal aColorComponent = takeColorComponentFromInteger (theColorInteger, theColorComponentBase);
|
||||
aColor[aColorComponentIndex] = aColorComponent;
|
||||
}
|
||||
if (theColorInteger != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theColor = Quantity_ColorRGBA (aColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Converts the string to an integer number using the number base
|
||||
//! @tparam TheNumber the type of a resulting number
|
||||
//! @param theString the string to be converted
|
||||
//! @param theNumber a number that is the result of the conversion
|
||||
//! @param theBase the base of a numeral system used to represent a number in a string form
|
||||
//! @return true if a conversion was successful, or false otherwise
|
||||
template <typename TheNumber>
|
||||
static bool convertStringToInteger (const char* const theString, TheNumber& theNumber, const TheNumber theBase = 10)
|
||||
{
|
||||
std::stringstream aConversionStringStream;
|
||||
aConversionStringStream << std::setbase (theBase) << theString;
|
||||
if (aConversionStringStream.fail())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
aConversionStringStream >> theNumber;
|
||||
if (aConversionStringStream.fail())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Checks if the character is a hexadecimal digit (0 .. 9, a .. f, A .. F)
|
||||
//! @param theCharacter the character to be checked
|
||||
//! @return true if the checking character is a hexadecimal digit, or false otherwise
|
||||
static bool isHexDigit (const char theCharacter)
|
||||
{
|
||||
return std::isxdigit (static_cast<unsigned char> (theCharacter)) != 0;
|
||||
}
|
||||
|
||||
//! Checks if the string consists only of hexadecimal digits (0 .. 9, a .. f, A .. F)
|
||||
//! @param theString the string to be checked
|
||||
//! @param theLength the length of the checked string
|
||||
//! @return true if the checking string consists only of hexadecimal digits, or false otherwise
|
||||
//! an empty string is not interpreted as a hex string
|
||||
static bool isHexString (const char* const theString, const std::size_t theLength)
|
||||
{
|
||||
if (theLength == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// std::all_of is not used due to VS2008 compilability limitation
|
||||
return std::count_if (theString, theString + theLength, isHexDigit) == static_cast<std::ptrdiff_t> (theLength);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//=======================================================================
|
||||
// function : ColorFromHex
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
bool Quantity_ColorRGBA::ColorFromHex (const char* const theHexColorString,
|
||||
Quantity_ColorRGBA& theColor,
|
||||
const bool theAlphaComponentIsOff)
|
||||
{
|
||||
std::size_t aHexColorStringLength = std::strlen (theHexColorString);
|
||||
if (aHexColorStringLength == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool hasPrefix = (theHexColorString[0] == '#');
|
||||
const std::size_t aPrefixLength = hasPrefix ? 1 : 0;
|
||||
const char* const aHexColorString = theHexColorString + aPrefixLength;
|
||||
aHexColorStringLength -= aPrefixLength;
|
||||
if (!isHexString (aHexColorString, aHexColorStringLength))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ColorInteger aHexColorInteger;
|
||||
if (!convertStringToInteger (aHexColorString, aHexColorInteger, 16u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasAlphaComponent = false;
|
||||
bool isShort = false;
|
||||
switch (static_cast<HexColorLength> (aHexColorStringLength))
|
||||
{
|
||||
case HexColorLength_ShortRGBA:
|
||||
hasAlphaComponent = true;
|
||||
Standard_FALLTHROUGH
|
||||
case HexColorLength_ShortRGB:
|
||||
isShort = true;
|
||||
break;
|
||||
case HexColorLength_RGBA:
|
||||
hasAlphaComponent = true;
|
||||
break;
|
||||
case HexColorLength_RGB:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (theAlphaComponentIsOff && hasAlphaComponent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// to distinguish with a usual integer color component value
|
||||
if (isShort && !hasAlphaComponent && !hasPrefix)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const ColorInteger THE_HEX_COLOR_COMPONENT_BASE = 1 << 8;
|
||||
const ColorInteger THE_HEX_COLOR_COMPONENT_SHORT_BASE = 1 << 4;
|
||||
const ColorInteger aColorComponentBase = isShort ? THE_HEX_COLOR_COMPONENT_SHORT_BASE : THE_HEX_COLOR_COMPONENT_BASE;
|
||||
return convertIntegerToColorRGBA (aHexColorInteger, aColorComponentBase, hasAlphaComponent, theColor);
|
||||
}
|
@ -91,6 +91,36 @@ public:
|
||||
//! Two colors are considered to be equal if their distance is no greater than Epsilon().
|
||||
bool operator== (const Quantity_ColorRGBA& theOther) const { return IsEqual (theOther); }
|
||||
|
||||
//! Finds color from predefined names.
|
||||
//! For example, the name of the color which
|
||||
//! corresponds to "BLACK" is Quantity_NOC_BLACK.
|
||||
//! Returns false if name is unknown.
|
||||
//! An alpha component is set to 1.0.
|
||||
//! @param theColorNameString the color name
|
||||
//! @param theColor a found color
|
||||
//! @return false if the color name is unknown, or true if the search by color name was successful
|
||||
static Standard_Boolean ColorFromName (const Standard_CString theColorNameString, Quantity_ColorRGBA& theColor)
|
||||
{
|
||||
Quantity_ColorRGBA aColor;
|
||||
if (!Quantity_Color::ColorFromName (theColorNameString, aColor.ChangeRGB()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theColor = aColor;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Parses the string as a hex color (like "#FF0" for short RGB color, "#FF0F" for short RGBA color,
|
||||
//! "#FFFF00" for RGB color, or "#FFFF00FF" for RGBA color)
|
||||
//! @param theHexColorString the string to be parsed
|
||||
//! @param theColor a color that is a result of parsing
|
||||
//! @param theAlphaComponentIsOff the flag that indicates if a color alpha component is presented
|
||||
//! in the input string (false) or not (true)
|
||||
//! @return true if parsing was successful, or false otherwise
|
||||
Standard_EXPORT static bool ColorFromHex (const char* const theHexColorString,
|
||||
Quantity_ColorRGBA& theColor,
|
||||
const bool theAlphaComponentIsOff = false);
|
||||
|
||||
private:
|
||||
|
||||
static void myTestSize3() { Standard_STATIC_ASSERT (sizeof(float) * 3 == sizeof(Quantity_Color)); }
|
||||
|
@ -82,6 +82,166 @@ extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
|
||||
#define DEFAULT_FREEBOUNDARY_COLOR Quantity_NOC_GREEN
|
||||
#define DEFAULT_MATERIAL Graphic3d_NOM_BRASS
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const Standard_Integer THE_MAX_INTEGER_COLOR_COMPONENT = 255;
|
||||
|
||||
const Standard_ShortReal THE_MAX_REAL_COLOR_COMPONENT = 1.0f;
|
||||
|
||||
//! Parses string and get an integer color component (only values within range 0 .. 255 are allowed)
|
||||
//! @param theColorComponentString the string representing the color component
|
||||
//! @param theIntegerColorComponent an integer color component that is a result of parsing
|
||||
//! @return true if parsing was successful, or false otherwise
|
||||
static bool parseNumericalColorComponent (const Standard_CString theColorComponentString,
|
||||
Standard_Integer& theIntegerColorComponent)
|
||||
{
|
||||
Standard_Integer anIntegerColorComponent;
|
||||
if (!Draw::ParseInteger (theColorComponentString, anIntegerColorComponent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((anIntegerColorComponent < 0) || (anIntegerColorComponent > THE_MAX_INTEGER_COLOR_COMPONENT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theIntegerColorComponent = anIntegerColorComponent;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Parses the string and gets a real color component from it (only values within range 0.0 .. 1.0 are allowed)
|
||||
//! @param theColorComponentString the string representing the color component
|
||||
//! @param theRealColorComponent a real color component that is a result of parsing
|
||||
//! @return true if parsing was successful, or false otherwise
|
||||
static bool parseNumericalColorComponent (const Standard_CString theColorComponentString,
|
||||
Standard_ShortReal& theRealColorComponent)
|
||||
{
|
||||
Standard_Real aRealColorComponent;
|
||||
if (!Draw::ParseReal (theColorComponentString, aRealColorComponent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const Standard_ShortReal aShortRealColorComponent = static_cast<Standard_ShortReal> (aRealColorComponent);
|
||||
if ((aShortRealColorComponent < 0.0f) || (aShortRealColorComponent > THE_MAX_REAL_COLOR_COMPONENT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theRealColorComponent = aShortRealColorComponent;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Parses the string and gets a real color component from it (integer values 2 .. 255 are scaled to the 0.0 .. 1.0
|
||||
//! range, values 0 and 1 are leaved as they are)
|
||||
//! @param theColorComponentString the string representing the color component
|
||||
//! @param theColorComponent a color component that is a result of parsing
|
||||
//! @return true if parsing was successful, or false otherwise
|
||||
static bool parseColorComponent (const Standard_CString theColorComponentString,
|
||||
Standard_ShortReal& theColorComponent)
|
||||
{
|
||||
Standard_Integer anIntegerColorComponent;
|
||||
if (parseNumericalColorComponent (theColorComponentString, anIntegerColorComponent))
|
||||
{
|
||||
if (anIntegerColorComponent == 1)
|
||||
{
|
||||
theColorComponent = THE_MAX_REAL_COLOR_COMPONENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
theColorComponent = anIntegerColorComponent * 1.0f / THE_MAX_INTEGER_COLOR_COMPONENT;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return parseNumericalColorComponent (theColorComponentString, theColorComponent);
|
||||
}
|
||||
|
||||
//! Parses the array of strings and gets an integer color (only values within range 0 .. 255 are allowed and at least
|
||||
//! one of components must be greater than 1)
|
||||
//! @tparam TheNumber the type of resulting color vector elements
|
||||
//! @param theNumberOfColorComponents the number of color components
|
||||
//! @param theColorComponentStrings the array of strings representing color components
|
||||
//! @param theNumericalColor a 4-component vector that is a result of parsing
|
||||
//! @return true if parsing was successful, or false otherwise
|
||||
template <typename TheNumber>
|
||||
static bool parseNumericalColor (Standard_Integer& theNumberOfColorComponents,
|
||||
const char* const* const theColorComponentStrings,
|
||||
NCollection_Vec4<TheNumber>& theNumericalColor)
|
||||
{
|
||||
for (Standard_Integer aColorComponentIndex = 0; aColorComponentIndex < theNumberOfColorComponents;
|
||||
++aColorComponentIndex)
|
||||
{
|
||||
const char* const aColorComponentString = theColorComponentStrings[aColorComponentIndex];
|
||||
TheNumber aNumericalColorComponent;
|
||||
if (parseNumericalColorComponent (aColorComponentString, aNumericalColorComponent))
|
||||
{
|
||||
theNumericalColor[aColorComponentIndex] = aNumericalColorComponent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aColorComponentIndex == 3)
|
||||
{
|
||||
theNumberOfColorComponents = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Parses an array of strings and get an integer color (only values within range 0 .. 255 are allowed and at least
|
||||
//! one of components must be greater than 1)
|
||||
//! @param theNumberOfColorComponents the number of color components
|
||||
//! @param theColorComponentStrings the array of strings representing color components
|
||||
//! @param theColor a color that is a result of parsing
|
||||
//! @return true if parsing was successful, or false otherwise
|
||||
static bool parseIntegerColor (Standard_Integer& theNumberOfColorComponents,
|
||||
const char* const* const theColorComponentStrings,
|
||||
Quantity_ColorRGBA& theColor)
|
||||
{
|
||||
const Standard_Integer THE_COLOR_COMPONENT_NOT_PARSED = -1;
|
||||
Graphic3d_Vec4i anIntegerColor (THE_COLOR_COMPONENT_NOT_PARSED);
|
||||
if (!parseNumericalColor (theNumberOfColorComponents, theColorComponentStrings, anIntegerColor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool hasColorComponentGreaterThanOne = (anIntegerColor.maxComp() > 1);
|
||||
if (anIntegerColor.a() == THE_COLOR_COMPONENT_NOT_PARSED)
|
||||
{
|
||||
anIntegerColor.a() = THE_MAX_INTEGER_COLOR_COMPONENT;
|
||||
}
|
||||
|
||||
Graphic3d_Vec4 aRealColor (anIntegerColor);
|
||||
if (hasColorComponentGreaterThanOne)
|
||||
{
|
||||
aRealColor /= static_cast<Standard_ShortReal> (THE_MAX_INTEGER_COLOR_COMPONENT);
|
||||
}
|
||||
theColor = Quantity_ColorRGBA (aRealColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Parses an array of strings and get a real color (only values within range 0.0 .. 1.0 are allowed)
|
||||
//! @param theNumberOfColorComponents the number of color components
|
||||
//! @param theColorComponentStrings the array of strings representing color components
|
||||
//! @param theColor a color that is a result of parsing
|
||||
//! @return true if parsing was successful, or false otherwise
|
||||
static bool parseRealColor (Standard_Integer& theNumberOfColorComponents,
|
||||
const char* const* const theColorComponentStrings,
|
||||
Quantity_ColorRGBA& theColor)
|
||||
{
|
||||
Graphic3d_Vec4 aRealColor (THE_MAX_REAL_COLOR_COMPONENT);
|
||||
if (!parseNumericalColor (theNumberOfColorComponents, theColorComponentStrings, aRealColor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theColor = Quantity_ColorRGBA (aRealColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//=======================================================================
|
||||
// function : GetColorFromName
|
||||
// purpose : get the Quantity_NameOfColor from a string
|
||||
@ -94,67 +254,47 @@ Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theNam
|
||||
return aColor;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
// function : parseColor
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer ViewerTest::parseColor (Standard_Integer theArgNb,
|
||||
const char** theArgVec,
|
||||
Standard_Integer ViewerTest::parseColor (const Standard_Integer theArgNb,
|
||||
const char* const* const theArgVec,
|
||||
Quantity_ColorRGBA& theColor,
|
||||
bool theToParseAlpha)
|
||||
const bool theToParseAlpha)
|
||||
{
|
||||
Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
|
||||
if (theArgNb >= 1
|
||||
&& Quantity_Color::ColorFromName (theArgVec[0], aColor))
|
||||
if ((theArgNb >= 1) && Quantity_ColorRGBA::ColorFromHex (theArgVec[0], theColor, !theToParseAlpha))
|
||||
{
|
||||
theColor = Quantity_ColorRGBA (aColor);
|
||||
if (theArgNb >= 2
|
||||
&& theToParseAlpha)
|
||||
{
|
||||
const TCollection_AsciiString anAlphaStr (theArgVec[1]);
|
||||
if (anAlphaStr.IsRealValue())
|
||||
{
|
||||
float anAlpha = (float )anAlphaStr.RealValue();
|
||||
if (anAlpha < 0.0f || anAlpha > 1.0f)
|
||||
{
|
||||
std::cout << "Syntax error: alpha should be within range 0..1!\n";
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (theArgNb >= 1 && Quantity_ColorRGBA::ColorFromName (theArgVec[0], theColor))
|
||||
{
|
||||
if (theArgNb >= 2 && theToParseAlpha)
|
||||
{
|
||||
const Standard_CString anAlphaStr = theArgVec[1];
|
||||
Standard_ShortReal anAlphaComponent;
|
||||
if (parseColorComponent (anAlphaStr, anAlphaComponent))
|
||||
{
|
||||
theColor.SetAlpha (anAlphaComponent);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if (theArgNb >= 3)
|
||||
if (theArgNb >= 3)
|
||||
{
|
||||
Graphic3d_Vec4 anRgba (0.0f, 0.0f, 0.0f, 1.0f);
|
||||
Standard_Integer aNbComps = Min (theArgNb, theToParseAlpha ? 4 : 3);
|
||||
for (int aCompIter = 0; aCompIter < aNbComps; ++aCompIter)
|
||||
const Standard_Integer aNumberOfColorComponentsToParse = Min (theArgNb, theToParseAlpha ? 4 : 3);
|
||||
Standard_Integer aNumberOfColorComponentsParsed = aNumberOfColorComponentsToParse;
|
||||
if (parseIntegerColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
|
||||
{
|
||||
const TCollection_AsciiString anRgbaStr (theArgVec[aCompIter]);
|
||||
if (!anRgbaStr.IsRealValue())
|
||||
return aNumberOfColorComponentsParsed;
|
||||
}
|
||||
if (parseRealColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
|
||||
{
|
||||
if (aCompIter == 3)
|
||||
{
|
||||
anRgba.a() = 1.0f;
|
||||
aNbComps = 3;
|
||||
break;
|
||||
return aNumberOfColorComponentsParsed;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
anRgba[aCompIter] = (float )anRgbaStr.RealValue();
|
||||
if (anRgba[aCompIter] < 0.0 || anRgba[aCompIter] > 1.0)
|
||||
{
|
||||
std::cout << "Error: RGBA color values should be within range 0..1!\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
theColor = Quantity_ColorRGBA (anRgba);
|
||||
return aNbComps;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -153,9 +153,9 @@ public:
|
||||
//! Handles either color specified by name (single argument)
|
||||
//! or by RGB(A) components (3-4 arguments) in range 0..1.
|
||||
//! The result is stored in theColor on success.
|
||||
//! Returns number of handled arguments (1, 3 or 4) or 0 on syntax error.
|
||||
static Standard_Integer ParseColor (Standard_Integer theArgNb,
|
||||
const char** theArgVec,
|
||||
//! Returns number of handled arguments (1, 2, 3 or 4) or 0 on syntax error.
|
||||
static Standard_Integer ParseColor (const Standard_Integer theArgNb,
|
||||
const char* const* const theArgVec,
|
||||
Quantity_ColorRGBA& theColor)
|
||||
{
|
||||
return parseColor (theArgNb, theArgVec, theColor, true);
|
||||
@ -163,12 +163,12 @@ public:
|
||||
|
||||
//! Parses RGB color argument(s).
|
||||
//! Returns number of handled arguments (1 or 3) or 0 on syntax error.
|
||||
static Standard_Integer ParseColor (Standard_Integer theArgNb,
|
||||
const char** theArgVec,
|
||||
static Standard_Integer ParseColor (const Standard_Integer theArgNb,
|
||||
const char* const* const theArgVec,
|
||||
Quantity_Color& theColor)
|
||||
{
|
||||
Quantity_ColorRGBA anRgba;
|
||||
Standard_Integer aNbParsed = parseColor (theArgNb, theArgVec, anRgba, false);
|
||||
const Standard_Integer aNbParsed = parseColor (theArgNb, theArgVec, anRgba, false);
|
||||
if (aNbParsed != 0)
|
||||
{
|
||||
theColor = anRgba.GetRGB();
|
||||
@ -236,9 +236,9 @@ private:
|
||||
//! Handles either color specified by name (single argument)
|
||||
//! or by RGB(A) components (3-4 arguments) in range 0..1.
|
||||
//! The result is stored in theColor on success.
|
||||
//! Returns number of handled arguments (1, 3 or 4) or 0 on syntax error.
|
||||
//! Returns number of handled arguments (1, 2, 3 or 4) or 0 on syntax error.
|
||||
Standard_EXPORT static Standard_Integer parseColor (Standard_Integer theArgNb,
|
||||
const char** theArgVec,
|
||||
const char* const* theArgVec,
|
||||
Quantity_ColorRGBA& theColor,
|
||||
bool theToParseAlpha);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user