0030930: Draw Harness, ViewerTest - add commands vlistcolors and vlistmaterials listi...
authorkgv <kgv@opencascade.com>
Fri, 30 Aug 2019 14:54:09 +0000 (17:54 +0300)
committerapn <apn@opencascade.com>
Mon, 2 Sep 2019 16:17:23 +0000 (19:17 +0300)
Introduced two new commands vlistcolors listing named colors and vlistmaterials listing standard materials.
These commands also can generate HTML table listing colors/materials with their properties.
vlistmaterials can generate OBJ model for comparing OCCT materials in different viewers.
New test cases use these commands for generating HTML tables.

Graphic3d_MaterialAspect::MaterialType() - added missing getter.
Corrected name of unlit shading model within vaspects and vrenderparams commands.

src/Graphic3d/Graphic3d_MaterialAspect.hxx
src/Graphic3d/Graphic3d_TypeOfMaterial.hxx
src/Quantity/Quantity_Color.hxx
src/Quantity/Quantity_NameOfColor.hxx
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest_OpenGlCommands.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/materials/colors [new file with mode: 0644]
tests/v3d/materials/materials [new file with mode: 0644]

index 9d4ee83..78b9b10 100644 (file)
@@ -208,6 +208,9 @@ public:
   //! Deactivates the reflective properties of the surface with specified reflection type.
   void SetReflectionModeOff (const Graphic3d_TypeOfReflection theType) { SetReflectionMode (theType, Standard_False); }
 
+  //! Returns material type.
+  Graphic3d_TypeOfMaterial MaterialType() const { return myMaterialType; }
+
   //! Returns TRUE if type of this material is equal to specified type.
   Standard_Boolean MaterialType (const Graphic3d_TypeOfMaterial theType) const { return myMaterialType == theType; }
 
index d8ee5e9..4f15904 100644 (file)
@@ -20,8 +20,8 @@
 //! Types of materials specifies if a material can change color.
 enum Graphic3d_TypeOfMaterial
 {
-Graphic3d_MATERIAL_ASPECT,
-Graphic3d_MATERIAL_PHYSIC
+  Graphic3d_MATERIAL_ASPECT, //!< aspect   material definition with configurable color (like plastic)
+  Graphic3d_MATERIAL_PHYSIC  //!< physical material definition with fixed color (like gold)
 };
 
 #endif // _Graphic3d_TypeOfMaterial_HeaderFile
index 07ce584..77fbf22 100644 (file)
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
-
 #include <Standard_ShortReal.hxx>
+
 #include <Quantity_NameOfColor.hxx>
 #include <Quantity_TypeOfColor.hxx>
-#include <Standard_Real.hxx>
-#include <Standard_Boolean.hxx>
-#include <Standard_CString.hxx>
-#include <Standard_Integer.hxx>
+#include <TCollection_AsciiString.hxx>
 #include <NCollection_Vec4.hxx>
 class Quantity_ColorDefinitionError;
 
@@ -51,11 +48,10 @@ public:
   DEFINE_STANDARD_ALLOC
 
   
-  //! Creates a colour with the default value of
-  //! Colour name : YELLOW
+  //! Creates Quantity_NOC_YELLOW color.
   Standard_EXPORT Quantity_Color();
   
-  //! Creates the colour <AName>.
+  //! Creates the color from enumeration value.
   Standard_EXPORT Quantity_Color(const Quantity_NameOfColor AName);
   
   //! Creates a color according to the definition system theType.
@@ -98,12 +94,12 @@ public:
   Standard_EXPORT void SetValues (const Quantity_NameOfColor AName);
   
   //! Updates a color according to the mode specified by theType.
-  //! TOC_RGB:
+  //! Quantity_TOC_RGB:
   //!  - theR1 the value of Red   within range [0.0; 1.0]
   //!  - theR2 the value of Green within range [0.0; 1.0]
   //!  - theR3 the value of Blue  within range [0.0; 1.0]
   //!
-  //! TOC_HLS:
+  //! Quantity_TOC_HLS:
   //!  - theR1 is the Hue (H) angle in degrees within range [0.0; 360.0], 0.0 being Red.
   //!    -1.0 is a special value reserved for grayscale color (S should be 0.0).
   //!  - theR2 is the Lightness  (L) within range [0.0; 1.0]
@@ -247,6 +243,16 @@ Standard_Boolean operator == (const Quantity_Color& Other) const
   //! @return true if parsing was successful, or false otherwise
   Standard_EXPORT static bool ColorFromHex (const Standard_CString theHexColorString, Quantity_Color& theColor);
 
+  //! Returns hex sRGB string in format "#FFAAFF".
+  static TCollection_AsciiString ColorToHex (const Quantity_Color& theColor)
+  {
+    NCollection_Vec3<Standard_ShortReal> anSRgb = (NCollection_Vec3<Standard_ShortReal> )theColor;
+    NCollection_Vec3<Standard_Integer> anSRgbInt (anSRgb * 255.0f);
+    char aBuff[10];
+    Sprintf (aBuff, "#%02X%02X%02X", anSRgbInt.r(), anSRgbInt.g(), anSRgbInt.b());
+    return aBuff;
+  }
+
   //! 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);
   
index 34f885a..1ef519b 100644 (file)
@@ -17,7 +17,8 @@
 #ifndef _Quantity_NameOfColor_HeaderFile
 #define _Quantity_NameOfColor_HeaderFile
 
-//! Definition of names of known colours.
+//! Definition of names of known colors.
+//! The names come (mostly) from the X11 specification.
 enum Quantity_NameOfColor
 {
 Quantity_NOC_BLACK,
index 100d63e..d008ef9 100644 (file)
@@ -6608,7 +6608,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
       "\n\t\t:          [-isoontriangulation 0|1]"
       "\n\t\t:          [-setMaxParamValue {value}]"
       "\n\t\t:          [-setSensitivity {selection_mode} {value}]"
-      "\n\t\t:          [-setShadingModel {color|flat|gouraud|phong}]"
+      "\n\t\t:          [-setShadingModel {unlit|flat|gouraud|phong}]"
       "\n\t\t:          [-unsetShadingModel]"
       "\n\t\t:          [-setInterior {solid|hatch|hidenline|point}]"
       "\n\t\t:          [-unsetInterior] [-setHatch HatchStyle]"
@@ -6623,7 +6623,9 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
       "\n\t\t: When -defaults is specified than presentation properties will be"
       "\n\t\t: assigned to all objects that have not their own specified properties"
       "\n\t\t: and to all objects to be displayed in the future."
-      "\n\t\t: If -defaults is used there should not be any objects' names and -subshapes specifier.",
+      "\n\t\t: If -defaults is used there should not be any objects' names and -subshapes specifier."
+      "\n\t\t: See also vlistcolors and vlistmaterials to list named colors and materials"
+      "\n\t\t: accepted by arguments -setMaterial and -setColor",
                  __FILE__,VAspects,group);
 
   theCommands.Add("vsetcolor",
index dc5feb2..b6d41ec 100644 (file)
@@ -22,6 +22,7 @@
 #include <Graphic3d_Group.hxx>
 #include <Graphic3d_ShaderObject.hxx>
 #include <Graphic3d_ShaderProgram.hxx>
+#include <Image_AlienPixMap.hxx>
 #include <OpenGl_Aspects.hxx>
 #include <OpenGl_Context.hxx>
 #include <OpenGl_Element.hxx>
@@ -45,6 +46,7 @@
 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
 #include <OpenGl_Group.hxx>
+#include <OSD_OpenFile.hxx>
 
 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
                                            const Handle(AIS_InteractiveObject)& theAISObj,
@@ -873,6 +875,474 @@ static Standard_Integer VShaderProg (Draw_Interpretor& theDI,
   return 0;
 }
 
+//! Print triplet of values.
+template<class S, class T> static S& operator<< (S& theStream, const NCollection_Vec3<T>& theVec)
+{
+  theStream << theVec[0] << " " << theVec[1] << " " << theVec[2];
+  return theStream;
+}
+
+//! Print 4 values.
+template<class S, class T> static S& operator<< (S& theStream, const NCollection_Vec4<T>& theVec)
+{
+  theStream << theVec[0] << " " << theVec[1] << " " << theVec[2] << " " << theVec[3];
+  return theStream;
+}
+
+//! Print fresnel model.
+static const char* fresnelModelString (const Graphic3d_FresnelModel theModel)
+{
+  switch (theModel)
+  {
+    case Graphic3d_FM_SCHLICK:    return "SCHLICK";
+    case Graphic3d_FM_CONSTANT:   return "CONSTANT";
+    case Graphic3d_FM_CONDUCTOR:  return "CONDUCTOR";
+    case Graphic3d_FM_DIELECTRIC: return "DIELECTRIC";
+  }
+  return "N/A";
+}
+
+//! Create a colored rectangle SVG element.
+static TCollection_AsciiString formatSvgColoredRect (const Quantity_Color& theColor)
+{
+  return TCollection_AsciiString()
+       + "<svg width='20px' height='20px'><rect width='20px' height='20px' fill='" + Quantity_Color::ColorToHex (theColor) + "' /></svg>";
+}
+
+//==============================================================================
+//function : VListMaterials
+//purpose  :
+//==============================================================================
+static Standard_Integer VListMaterials (Draw_Interpretor& theDI,
+                                        Standard_Integer  theArgNb,
+                                        const char**      theArgVec)
+{
+  TCollection_AsciiString aDumpFile;
+  NCollection_Sequence<Graphic3d_NameOfMaterial> aMatList;
+  for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
+  {
+    TCollection_AsciiString anArg (theArgVec[anArgIter]);
+    anArg.LowerCase();
+    Graphic3d_NameOfMaterial aMat = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter]);
+    if (aMat != Graphic3d_NOM_DEFAULT)
+    {
+      aMatList.Append (aMat);
+    }
+    else if (anArg == "*")
+    {
+      for (Standard_Integer aMatIter = 0; aMatIter < (Standard_Integer )Graphic3d_NOM_DEFAULT; ++aMatIter)
+      {
+        aMatList.Append ((Graphic3d_NameOfMaterial )aMatIter);
+      }
+    }
+    else if (aDumpFile.IsEmpty()
+          && (anArg.EndsWith (".obj")
+           || anArg.EndsWith (".mtl")
+           || anArg.EndsWith (".htm")
+           || anArg.EndsWith (".html")))
+    {
+      aDumpFile = theArgVec[anArgIter];
+    }
+    else
+    {
+      std::cout << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'\n";
+      return 1;
+    }
+  }
+  if (aMatList.IsEmpty())
+  {
+    if (aDumpFile.IsEmpty())
+    {
+      for (Standard_Integer aMatIter = 1; aMatIter <= Graphic3d_MaterialAspect::NumberOfMaterials(); ++aMatIter)
+      {
+        theDI << Graphic3d_MaterialAspect::MaterialName (aMatIter) << " ";
+      }
+      return 0;
+    }
+
+    for (Standard_Integer aMatIter = 0; aMatIter < (Standard_Integer )Graphic3d_NOM_DEFAULT; ++aMatIter)
+    {
+      aMatList.Append ((Graphic3d_NameOfMaterial )aMatIter);
+    }
+  }
+
+  // geometry for dumping
+  const Graphic3d_Vec3 aBoxVerts[8] =
+  {
+    Graphic3d_Vec3( 1, -1, -1),
+    Graphic3d_Vec3( 1, -1,  1),
+    Graphic3d_Vec3(-1, -1,  1),
+    Graphic3d_Vec3(-1, -1, -1),
+    Graphic3d_Vec3( 1,  1, -1),
+    Graphic3d_Vec3( 1,  1,  1),
+    Graphic3d_Vec3(-1,  1,  1),
+    Graphic3d_Vec3(-1,  1, -1)
+  };
+
+  const Graphic3d_Vec4i aBoxQuads[6] =
+  {
+    Graphic3d_Vec4i (1, 2, 3, 4),
+    Graphic3d_Vec4i (5, 8, 7, 6),
+    Graphic3d_Vec4i (1, 5, 6, 2),
+    Graphic3d_Vec4i (2, 6, 7, 3),
+    Graphic3d_Vec4i (3, 7, 8, 4),
+    Graphic3d_Vec4i (5, 1, 4, 8)
+  };
+
+  std::ofstream aMatFile, anObjFile, anHtmlFile;
+  if (aDumpFile.EndsWith (".obj")
+   || aDumpFile.EndsWith (".mtl"))
+  {
+    const TCollection_AsciiString aMatFilePath  = aDumpFile.SubString (1, aDumpFile.Length() - 3) + "mtl";
+    const TCollection_AsciiString anObjFilePath = aDumpFile.SubString (1, aDumpFile.Length() - 3) + "obj";
+
+    OSD_OpenStream (aMatFile,  aMatFilePath.ToCString(),  std::ios::out | std::ios::binary);
+    if (!aMatFile.is_open())
+    {
+      std::cout << "Error: unable creating material file\n";
+      return 0;
+    }
+    if (!aDumpFile.EndsWith (".mtl"))
+    {
+      OSD_OpenStream (anObjFile, anObjFilePath.ToCString(), std::ios::out | std::ios::binary);
+      if (!anObjFile.is_open())
+      {
+        std::cout << "Error: unable creating OBJ file\n";
+        return 0;
+      }
+
+      TCollection_AsciiString anMtlName, aFolder;
+      OSD_Path::FolderAndFileFromPath (aMatFilePath, aFolder, anMtlName);
+      anObjFile << "mtllib " << anMtlName << "\n";
+    }
+  }
+  else if (aDumpFile.EndsWith (".htm")
+        || aDumpFile.EndsWith (".html"))
+  {
+    OSD_OpenStream (anHtmlFile, aDumpFile.ToCString(), std::ios::out | std::ios::binary);
+    if (!anHtmlFile.is_open())
+    {
+      std::cout << "Error: unable creating HTML file\n";
+      return 0;
+    }
+    anHtmlFile << "<html>\n"
+                  "<head><title>OCCT Material table</title></head>\n"
+                  "<body>\n"
+                  "<table border='1'><tbody>\n"
+                  "<tr>\n"
+                  "<th rowspan='2'><div title='Material name.\n"
+                                              "See also Graphic3d_NameOfMaterial enumeration'>"
+                                   "Name</div></th>\n"
+                  "<th rowspan='2'><div title='Material type: PHYSIC or ASPECT.\n"
+                                              "ASPECT material does not define final colors, it is taken from Internal Color instead.\n"
+                                              "See also Graphic3d_TypeOfMaterial enumeration'>"
+                                   "Type</div></th>\n"
+                  "<th colspan='5'><div title='Common material definition for Phong shading model'>"
+                                   "Common</div></th>\n"
+                  "<th rowspan='2'>Transparency</th>\n"
+                  "<th rowspan='2'>Refraction Index</th>\n"
+                  "<th colspan='9'><div title='BSDF (Bidirectional Scattering Distribution Function).\n"
+                                              "Used for physically-based rendering (in path tracing engine).\n"
+                                              "BSDF is represented as weighted mixture of basic BRDFs/BTDFs (Bidirectional Reflectance (Transmittance) Distribution Functions).\n"
+                                              "See also Graphic3d_BSDF structure.'>"
+                                   "BSDF</div></th>\n"
+                  "</tr>\n"
+                  "<tr>\n"
+                  "<th>Ambient</th>\n"
+                  "<th>Diffuse</th>\n"
+                  "<th>Specular</th>\n"
+                  "<th>Emissive</th>\n"
+                  "<th>Shiness</th>\n"
+                  "<th><div title='Weight of coat specular/glossy BRDF'>"
+                       "Kc</div></th>\n"
+                  "<th><div title='Weight of base diffuse BRDF'>"
+                       "Kd</div></th>\n"
+                  "<th><div title='Weight of base specular/glossy BRDF'>"
+                       "Ks</div></th>\n"
+                  "<th><div title='Weight of base specular/glossy BTDF'>"
+                       "Kt</div></th>\n"
+                  "<th><div title='Radiance emitted by the surface'>"
+                       "Le</div></th>\n"
+                  "<th><div title='Volume scattering color/density'>"
+                       "Absorption</div></th>\n"
+                  "<th><div title='Parameters of Fresnel reflectance of coat layer'>"
+                       "FresnelCoat</div></th>\n"
+                  "<th><div title='Parameters of Fresnel reflectance of base layer'>"
+                       "FresnelBase</div></th>\n"
+                  "</tr>\n";
+  }
+  else if (!aDumpFile.IsEmpty())
+  {
+    std::cout << "Syntax error: unknown output file format\n";
+    return 1;
+  }
+
+  Standard_Integer aMatIndex = 0, anX = 0, anY = 0;
+  for (NCollection_Sequence<Graphic3d_NameOfMaterial>::Iterator aMatIter (aMatList); aMatIter.More(); aMatIter.Next(), ++aMatIndex)
+  {
+    Graphic3d_MaterialAspect aMat (aMatIter.Value());
+    const TCollection_AsciiString aMatName = aMat.StringName();
+    const Graphic3d_Vec3 anAmbient = aMat.ReflectionMode (Graphic3d_TOR_AMBIENT)
+                                   ? (Graphic3d_Vec3 )aMat.AmbientColor()  * aMat.Ambient()
+                                   : Graphic3d_Vec3 (0.0f);
+    const Graphic3d_Vec3 aDiffuse  = aMat.ReflectionMode (Graphic3d_TOR_DIFFUSE)
+                                   ? (Graphic3d_Vec3 )aMat.DiffuseColor()  * aMat.Diffuse()
+                                   : Graphic3d_Vec3 (0.0f);
+    const Graphic3d_Vec3 aSpecular = aMat.ReflectionMode (Graphic3d_TOR_SPECULAR)
+                                   ? (Graphic3d_Vec3 )aMat.SpecularColor() * aMat.Specular()
+                                   : Graphic3d_Vec3 (0.0f);
+    const Graphic3d_Vec3 anEmission = aMat.ReflectionMode (Graphic3d_TOR_EMISSION)
+                                   ? (Graphic3d_Vec3 )aMat.EmissiveColor() * aMat.Emissive()
+                                   : Graphic3d_Vec3 (0.0f);
+    const Standard_Real  aShiness  = aMat.Shininess() * 1000.0;
+    if (aMatFile.is_open())
+    {
+      aMatFile << "newmtl " << aMatName << "\n";
+      aMatFile << "Ka " << anAmbient << "\n";
+      aMatFile << "Kd " << aDiffuse  << "\n";
+      aMatFile << "Ks " << aSpecular << "\n";
+      aMatFile << "Ns " << aShiness  << "\n";
+      if (aMat.Transparency() >= 0.0001)
+      {
+        aMatFile << "Tr " << aMat.Transparency() << "\n";
+      }
+      aMatFile << "\n";
+    }
+    else if (anHtmlFile.is_open())
+    {
+      anHtmlFile << "<tr>\n";
+      anHtmlFile << "<td>" << aMat.StringName() << "</td>\n";
+      anHtmlFile << "<td>" << (aMat.MaterialType() == Graphic3d_MATERIAL_PHYSIC ? "PHYSIC" : "ASPECT")  << "</td>\n";
+      anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (anAmbient))  << anAmbient  << "</td>\n";
+      anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (aDiffuse))   << aDiffuse   << "</td>\n";
+      anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (aSpecular))  << aSpecular  << "</td>\n";
+      anHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (anEmission)) << anEmission << "</td>\n";
+      anHtmlFile << "<td>" << aMat.Shininess() << "</td>\n";
+      anHtmlFile << "<td>" << aMat.Transparency() << "</td>\n";
+      anHtmlFile << "<td>" << aMat.RefractionIndex() << "</td>\n";
+      anHtmlFile << "<td>" << aMat.BSDF().Kc << "</td>\n";
+      anHtmlFile << "<td>" << aMat.BSDF().Kd << "</td>\n";
+      anHtmlFile << "<td>" << aMat.BSDF().Ks << "</td>\n";
+      anHtmlFile << "<td>" << aMat.BSDF().Kt << "</td>\n";
+      anHtmlFile << "<td>" << aMat.BSDF().Le << "</td>\n";
+      anHtmlFile << "<td>" << aMat.BSDF().Absorption << "</td>\n";
+      anHtmlFile << "<td>" << fresnelModelString (aMat.BSDF().FresnelCoat.FresnelType()) << "</td>\n";
+      anHtmlFile << "<td>" << fresnelModelString (aMat.BSDF().FresnelBase.FresnelType()) << "</td>\n";
+      anHtmlFile << "</tr>\n";
+    }
+    else
+    {
+      theDI << aMat.StringName() << "\n";
+      theDI << "  Common.Ambient:         " << anAmbient << "\n";
+      theDI << "  Common.Diffuse:         " << aDiffuse  << "\n";
+      theDI << "  Common.Specular:        " << aSpecular << "\n";
+      theDI << "  Common.Emissive:        " << anEmission << "\n";
+      theDI << "  Common.Shiness:         " << aMat.Shininess() << "\n";
+      theDI << "  Common.Transparency:    " << aMat.Transparency() << "\n";
+      theDI << "  RefractionIndex:        " << aMat.RefractionIndex() << "\n";
+      theDI << "  BSDF.Kc:                " << aMat.BSDF().Kc << "\n";
+      theDI << "  BSDF.Kd:                " << aMat.BSDF().Kd << "\n";
+      theDI << "  BSDF.Ks:                " << aMat.BSDF().Ks << "\n";
+      theDI << "  BSDF.Kt:                " << aMat.BSDF().Kt << "\n";
+      theDI << "  BSDF.Le:                " << aMat.BSDF().Le << "\n";
+      theDI << "  BSDF.Absorption:        " << aMat.BSDF().Absorption << "\n";
+      theDI << "  BSDF.FresnelCoat:       " << fresnelModelString (aMat.BSDF().FresnelCoat.FresnelType()) << "\n";
+      theDI << "  BSDF.FresnelBase:       " << fresnelModelString (aMat.BSDF().FresnelBase.FresnelType()) << "\n";
+    }
+
+    if (anObjFile.is_open())
+    {
+      anObjFile << "g " << aMatName << "\n";
+      anObjFile << "usemtl " << aMatName << "\n";
+      for (Standard_Integer aVertIter = 0; aVertIter < 8; ++aVertIter)
+      {
+        anObjFile << "v " << (aBoxVerts[aVertIter] + Graphic3d_Vec3 (3.0f * anX, -3.0f * anY, 0.0f)) << "\n";
+      }
+      anObjFile << "s off\n";
+      for (Standard_Integer aFaceIter = 0; aFaceIter < 6; ++aFaceIter)
+      {
+        anObjFile << "f " << (aBoxQuads[aFaceIter] + Graphic3d_Vec4i (8 * aMatIndex)) << "\n";
+      }
+      anObjFile << "\n";
+      if (++anX > 5)
+      {
+        anX = 0;
+        ++anY;
+      }
+    }
+  }
+
+  if (anHtmlFile.is_open())
+  {
+    anHtmlFile << "</tbody></table>\n</body>\n</html>\n";
+  }
+  return 0;
+}
+
+//==============================================================================
+//function : VListColors
+//purpose  :
+//==============================================================================
+static Standard_Integer VListColors (Draw_Interpretor& theDI,
+                                     Standard_Integer  theArgNb,
+                                     const char**      theArgVec)
+{
+  TCollection_AsciiString aDumpFile;
+  NCollection_Sequence<Quantity_NameOfColor> aColList;
+  for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
+  {
+    TCollection_AsciiString anArg (theArgVec[anArgIter]);
+    anArg.LowerCase();
+    Quantity_NameOfColor aName;
+    if (Quantity_Color::ColorFromName (theArgVec[anArgIter], aName))
+    {
+      aColList.Append (aName);
+    }
+    else if (anArg == "*")
+    {
+      for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
+      {
+        aColList.Append ((Quantity_NameOfColor )aColIter);
+      }
+    }
+    else if (aDumpFile.IsEmpty()
+          && (anArg.EndsWith (".htm")
+           || anArg.EndsWith (".html")))
+    {
+      aDumpFile = theArgVec[anArgIter];
+    }
+    else
+    {
+      std::cout << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'\n";
+      return 1;
+    }
+  }
+  if (aColList.IsEmpty())
+  {
+    if (aDumpFile.IsEmpty())
+    {
+      for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
+      {
+        theDI << Quantity_Color::StringName (Quantity_NameOfColor (aColIter)) << " ";
+      }
+      return 0;
+    }
+
+    for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
+    {
+      aColList.Append ((Quantity_NameOfColor )aColIter);
+    }
+  }
+
+  std::ofstream anHtmlFile;
+  TCollection_AsciiString aFileNameBase, aFolder;
+  if (aDumpFile.EndsWith (".htm")
+   || aDumpFile.EndsWith (".html"))
+  {
+    OSD_Path::FolderAndFileFromPath (aDumpFile, aFolder, aFileNameBase);
+    aFileNameBase = aFileNameBase.SubString (1, aFileNameBase.Length() -  (aDumpFile.EndsWith (".htm") ? 4 : 5));
+  }
+  else if (!aDumpFile.IsEmpty())
+  {
+    std::cout << "Syntax error: unknown output file format\n";
+    return 1;
+  }
+
+  Standard_Integer aMaxNameLen = 1;
+  for (NCollection_Sequence<Quantity_NameOfColor>::Iterator aColIter (aColList); aColIter.More(); aColIter.Next())
+  {
+    aMaxNameLen = Max (aMaxNameLen, TCollection_AsciiString (Quantity_Color::StringName (aColIter.Value())).Length());
+  }
+
+  V3d_ImageDumpOptions anImgParams;
+  anImgParams.Width  = 60;
+  anImgParams.Height = 30;
+  anImgParams.BufferType = Graphic3d_BT_RGB;
+  anImgParams.StereoOptions  = V3d_SDO_MONO;
+  anImgParams.ToAdjustAspect = Standard_True;
+  Handle(V3d_View) aView;
+  if (!aDumpFile.IsEmpty())
+  {
+    ViewerTest::ViewerInit (0, 0, anImgParams.Width, anImgParams.Height, "TmpDriver/TmpViewer/TmpView");
+    aView = ViewerTest::CurrentView();
+    aView->SetImmediateUpdate (false);
+    aView->SetBgGradientStyle (Aspect_GFM_NONE, false);
+  }
+
+  if (!aDumpFile.IsEmpty())
+  {
+    OSD_OpenStream (anHtmlFile, aDumpFile.ToCString(), std::ios::out | std::ios::binary);
+    if (!anHtmlFile.is_open())
+    {
+      std::cout << "Error: unable creating HTML file\n";
+      return 0;
+    }
+    anHtmlFile << "<html>\n"
+               << "<head><title>OCCT Color table</title></head>\n"
+               << "<body>\n"
+               << "<table border='1'><tbody>\n"
+               << "<tr>\n"
+               << "<th>HTML</th>\n"
+               << "<th>OCCT</th>\n"
+               << "<th>Color name</th>\n"
+               << "<th>sRGB hex</th>\n"
+               << "<th>sRGB dec</th>\n"
+               << "<th>RGB linear</th>\n"
+               << "</tr>\n";
+  }
+
+  Image_AlienPixMap anImg;
+  Standard_Integer aColIndex = 0;
+  for (NCollection_Sequence<Quantity_NameOfColor>::Iterator aColIter (aColList); aColIter.More(); aColIter.Next(), ++aColIndex)
+  {
+    Quantity_Color aCol (aColIter.Value());
+    const TCollection_AsciiString aColName  = Quantity_Color::StringName (aColIter.Value());
+    const TCollection_AsciiString anSRgbHex = Quantity_Color::ColorToHex (aCol);
+    const Graphic3d_Vec3i anSRgbInt ((Graphic3d_Vec3 )aCol * 255.0f);
+    if (anHtmlFile.is_open())
+    {
+      const TCollection_AsciiString anImgPath = aFileNameBase + "_" + aColName + ".png";
+      if (!aView.IsNull())
+      {
+        aView->SetImmediateUpdate (false);
+        aView->SetBackgroundColor (aCol);
+        if (!aView->ToPixMap (anImg, anImgParams)
+         || !anImg.Save (aFolder + anImgPath))
+        {
+          theDI << "Error: image dump failed\n";
+          return 0;
+        }
+      }
+
+      anHtmlFile << "<tr>\n";
+      anHtmlFile << "<td style='background-color:" << anSRgbHex << "'><pre>       </pre></td>\n";
+      anHtmlFile << "<td><img src='" << (!aView.IsNull() ? anImgPath : "") << "'></img></td>\n";
+      anHtmlFile << "<td style='text-align:left'>" << aColName << "</td>\n";
+      anHtmlFile << "<td style='text-align:left'><pre>" << anSRgbHex << "</pre></td>\n";
+      anHtmlFile << "<td style='text-align:left'>(" << anSRgbInt.r() << " " << anSRgbInt.g() << " " << anSRgbInt.b() << ")</td>\n";
+      anHtmlFile << "<td style='text-align:left'>(" << aCol.Red() << " " << aCol.Green() << " " << aCol.Blue() << ")</td>\n";
+      anHtmlFile << "</tr>\n";
+    }
+    else
+    {
+      TCollection_AsciiString aColNameLong (aColName);
+      aColNameLong.RightJustify (aMaxNameLen, ' ');
+      theDI << aColNameLong << " [" << anSRgbHex << "]: " << aCol.Red() << " " << aCol.Green() << " " << aCol.Blue() << "\n";
+    }
+  }
+
+  if (!aView.IsNull())
+  {
+    ViewerTest::RemoveView (aView);
+  }
+
+  if (anHtmlFile.is_open())
+  {
+    anHtmlFile << "</tbody></table>\n</body>\n</html>\n";
+  }
+  return 0;
+}
+
 //=======================================================================
 //function : OpenGlCommands
 //purpose  :
@@ -910,4 +1380,18 @@ void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
                   "\n\t\t:  -reload restores dump of specified GLSL program",
     __FILE__, VShaderProg, aGroup);
   theCommands.Add("vshaderprog", "Alias for vshader", __FILE__, VShaderProg, aGroup);
+  theCommands.Add("vlistmaterials",
+                  "vlistmaterials [*] [MaterialName1 [MaterialName2 [...]]] [dump.obj|dump.html]"
+                  "\n\t\t: Without arguments, command prints the list of standard materials."
+                  "\n\t\t: Otherwise, properties of specified materials will be printed"
+                  "\n\t\t: or dumped into specified file."
+                  "\n\t\t: * can be used to refer to complete list of standard materials.",
+                  __FILE__, VListMaterials, aGroup);
+  theCommands.Add("vlistcolors",
+                  "vlistcolors [*] [ColorName1 [ColorName2 [...]]] [dump.html]"
+                  "\n\t\t: Without arguments, command prints the list of standard colors."
+                  "\n\t\t: Otherwise, properties of specified colors will be printed"
+                  "\n\t\t: or dumped into specified file."
+                  "\n\t\t: * can be used to refer to complete list of standard colors.",
+                  __FILE__, VListColors, aGroup);
 }
index b7a2b56..833ac10 100644 (file)
@@ -14247,7 +14247,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n      '-nbtiles      64..1024'    Specifies number of screen tiles per Redraw in ISS mode (256 by default)"
     "\n      '-rebuildGlsl  on|off'      Rebuild Ray-Tracing GLSL programs (for debugging)"
     "\n      '-shadingModel model'       Controls shading model from enumeration"
-    "\n                                  color, flat, gouraud, phong"
+    "\n                                  unlit, flat, gouraud, phong"
     "\n      '-resolution   value'       Sets a new pixels density (PPI), defines scaling factor for parameters like text size"
     "\n      '-aperture     >= 0.0'      Aperture size  of perspective camera for depth-of-field effect (0 disables DOF)"
     "\n      '-focal        >= 0.0'      Focal distance of perspective camera for depth-of-field effect"
diff --git a/tests/v3d/materials/colors b/tests/v3d/materials/colors
new file mode 100644 (file)
index 0000000..75d65cc
--- /dev/null
@@ -0,0 +1,32 @@
+puts "========"
+puts "0030930: Draw Harness, ViewerTest - add commands vlistcolors and vlistmaterials listing standard Colors and Materials"
+puts "Generate a table of predefined Colors (Quantity_NameOfColor enumeration)"
+puts "========"
+
+pload MODELING VISUALIZATION
+box b 10 10 10
+explode b F
+
+vclear
+vclose ALL
+vinit View1
+vtop
+
+puts "<a href=${::casename}_table.html>Color Comparison Table</a>"
+
+set aColors [vlistcolors]
+set anY 0
+set anX 0
+foreach aColor $aColors {
+  puts "$aColor"
+  tcopy b_6 ${aColor}
+  vdisplay  -noUpdate -dispMode 1 ${aColor}
+  vaspects  -noUpdate ${aColor} -setShadingModel unlit -setColor ${aColor}
+  vlocation -noUpdate ${aColor} -setLocation [expr 12*$anX] [expr 12*$anY] 0
+  set anX [expr $anX+1]
+  if { $anX > 25 } { set anX 0; set anY [expr $anY+1] }
+}
+vfit
+
+vdump $::imagedir/${::casename}.png
+vlistcolors $::imagedir/${::casename}_table.html
diff --git a/tests/v3d/materials/materials b/tests/v3d/materials/materials
new file mode 100644 (file)
index 0000000..dd2df2c
--- /dev/null
@@ -0,0 +1,21 @@
+puts "========"
+puts "0030930: Draw Harness, ViewerTest - add commands vlistcolors and vlistmaterials listing standard Colors and Materials"
+puts "Generate a table of predefined Materials (Graphic3d_NameOfMaterial enumeration)"
+puts "========"
+
+pload XDE OCAF MODELING VISUALIZATION
+
+catch { Close D }
+vclear
+vinit View1
+vaxo
+
+puts "<a href=${::casename}_table.html>Material Comparison Table</a>"
+vlistmaterials $::imagedir/${::casename}.obj
+ReadObj D $::imagedir/${::casename}.obj
+
+XDisplay -dispMode 1 D -explore
+vfit
+vdump ${imagedir}/${casename}.png
+
+vlistmaterials $::imagedir/${::casename}_table.html