mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +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:
@@ -82,9 +82,169 @@ 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
|
||||
// function : GetColorFromName
|
||||
// purpose : get the Quantity_NameOfColor from a string
|
||||
//=======================================================================
|
||||
|
||||
Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theName)
|
||||
@@ -94,67 +254,47 @@ Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theNam
|
||||
return aColor;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : parseColor
|
||||
//purpose :
|
||||
// function : parseColor
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer ViewerTest::parseColor (Standard_Integer theArgNb,
|
||||
const char** theArgVec,
|
||||
Quantity_ColorRGBA& theColor,
|
||||
bool theToParseAlpha)
|
||||
Standard_Integer ViewerTest::parseColor (const Standard_Integer theArgNb,
|
||||
const char* const* const theArgVec,
|
||||
Quantity_ColorRGBA& theColor,
|
||||
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)
|
||||
return 1;
|
||||
}
|
||||
if (theArgNb >= 1 && Quantity_ColorRGBA::ColorFromName (theArgVec[0], theColor))
|
||||
{
|
||||
if (theArgNb >= 2 && theToParseAlpha)
|
||||
{
|
||||
const TCollection_AsciiString anAlphaStr (theArgVec[1]);
|
||||
if (anAlphaStr.IsRealValue())
|
||||
const Standard_CString anAlphaStr = theArgVec[1];
|
||||
Standard_ShortReal anAlphaComponent;
|
||||
if (parseColorComponent (anAlphaStr, anAlphaComponent))
|
||||
{
|
||||
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;
|
||||
}
|
||||
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())
|
||||
{
|
||||
if (aCompIter == 3)
|
||||
{
|
||||
anRgba.a() = 1.0f;
|
||||
aNbComps = 3;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return aNumberOfColorComponentsParsed;
|
||||
}
|
||||
theColor = Quantity_ColorRGBA (anRgba);
|
||||
return aNbComps;
|
||||
if (parseRealColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
|
||||
{
|
||||
return aNumberOfColorComponentsParsed;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -153,22 +153,22 @@ 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,
|
||||
Quantity_ColorRGBA& theColor)
|
||||
//! 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);
|
||||
}
|
||||
|
||||
//! 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,
|
||||
Quantity_Color& theColor)
|
||||
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,11 +236,11 @@ 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.
|
||||
Standard_EXPORT 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.
|
||||
Standard_EXPORT static Standard_Integer parseColor (Standard_Integer theArgNb,
|
||||
const char* const* theArgVec,
|
||||
Quantity_ColorRGBA& theColor,
|
||||
bool theToParseAlpha);
|
||||
bool theToParseAlpha);
|
||||
|
||||
//! Parses ZLayer name.
|
||||
//! @param theArg [in] layer name, enumeration alias or index (of existing Layer)
|
||||
|
Reference in New Issue
Block a user