]> OCCT Git - occt.git/commitdiff
Data Exchange, Step - Vis Material support #447
authorPasukhin Dmitry <dpasukhi@opencascade.com>
Wed, 9 Apr 2025 11:46:48 +0000 (12:46 +0100)
committerGitHub <noreply@github.com>
Wed, 9 Apr 2025 11:46:48 +0000 (12:46 +0100)
- Introduced STEPConstruct_RenderingProperties class to handle rendering properties in STEP format.
- Implemented constructors for initializing rendering properties from various sources including STEP entities, RGBA colors, and XCAF materials.
- Added methods to set and retrieve ambient, diffuse, and specular reflectance values, along with transparency and rendering method.
- Integrated functionality to create corresponding STEP and XCAF material entities.

29 files changed:
.github/actions/retest-failures/action.yml
src/DataExchange/TKDESTEP/DESTEP/DESTEP_ConfigurationNode.cxx
src/DataExchange/TKDESTEP/DESTEP/DESTEP_Parameters.hxx
src/DataExchange/TKDESTEP/DESTEP/DESTEP_Provider.cxx
src/DataExchange/TKDESTEP/GTests/FILES.cmake
src/DataExchange/TKDESTEP/GTests/STEPConstruct_RenderingProperties_Test.cxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/RWStepAP214/RWStepAP214_GeneralModule.cxx
src/DataExchange/TKDESTEP/RWStepAP214/RWStepAP214_ReadWriteModule.cxx
src/DataExchange/TKDESTEP/RWStepVisual/FILES.cmake
src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.cxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.pxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.cxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.pxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/STEPCAFControl/STEPCAFControl_Reader.cxx
src/DataExchange/TKDESTEP/STEPCAFControl/STEPCAFControl_Writer.cxx
src/DataExchange/TKDESTEP/STEPCAFControl/STEPCAFControl_Writer.hxx
src/DataExchange/TKDESTEP/STEPConstruct/FILES.cmake
src/DataExchange/TKDESTEP/STEPConstruct/STEPConstruct_RenderingProperties.cxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/STEPConstruct/STEPConstruct_RenderingProperties.hxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/STEPConstruct/STEPConstruct_Styles.cxx
src/DataExchange/TKDESTEP/STEPConstruct/STEPConstruct_Styles.hxx
src/DataExchange/TKDESTEP/StepAP214/StepAP214_Protocol.cxx
src/DataExchange/TKDESTEP/StepVisual/FILES.cmake
src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuse.cxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.cxx [new file with mode: 0644]
src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx [new file with mode: 0644]
tests/de_wrapper/configuration/A3
tests/de_wrapper/configuration/A4

index 8a710f8785a7e33939975867e559fc3069754cb7..06d0540b1e0677a9d88e7053d6dca1adb13afabc 100644 (file)
@@ -260,11 +260,21 @@ runs:
           echo "No retest results to copy - directory is empty"
         fi
 
-    - name: Upload updated test results
+    - name: Upload updated test results (Windows)
+      if: ${{ inputs.platform == 'windows' && steps.check_failures.outputs.failed_count > 0 }}
+      uses: actions/upload-artifact@v4.4.3
+      with:
+        name: ${{ inputs.results-artifact-name }}
+        path: install/results/${{ inputs.test-directory-name }}*
+        retention-days: 15
+        overwrite: true
+
+    - name: Upload updated test results (macOS/Linux)
+      if : ${{ inputs.platform != 'windows' && steps.check_failures.outputs.failed_count > 0 }}
       uses: actions/upload-artifact@v4.4.3
       with:
         name: ${{ inputs.results-artifact-name }}
-        path: install/${{ inputs.platform == 'windows' && 'results' || 'bin/results' }}/${{ inputs.test-directory-name }}*
+        path: install/bin/results/${{ inputs.test-directory-name }}*
         retention-days: 15
         overwrite: true
 
index d34865e39688ad6a13fe1589a8ccc2c658e4c399..3d1395350b13545439cda3b90069ccdfdeaf7ac2 100644 (file)
@@ -190,6 +190,10 @@ bool DESTEP_ConfigurationNode::Load(const Handle(DE_ConfigurationContext)& theRe
     theResource->BooleanVal("write.layer", InternalParameters.WriteLayer, aScope);
   InternalParameters.WriteProps =
     theResource->BooleanVal("write.props", InternalParameters.WriteProps, aScope);
+  InternalParameters.WriteMaterial =
+    theResource->BooleanVal("write.material", InternalParameters.WriteMaterial, aScope);
+  InternalParameters.WriteVisMaterial =
+    theResource->BooleanVal("write.vismaterial", InternalParameters.WriteVisMaterial, aScope);
   InternalParameters.WriteModelType =
     (STEPControl_StepModelType)theResource->IntegerVal("write.model.type",
                                                        InternalParameters.WriteModelType,
@@ -556,6 +560,20 @@ TCollection_AsciiString DESTEP_ConfigurationNode::Save() const
   aResult += aScope + "write.props :\t " + InternalParameters.WriteProps + "\n";
   aResult += "!\n";
 
+  aResult += "!\n";
+  aResult += "!Setting up the write.material parameter which is used to indicate write "
+             "Material properties or not\n";
+  aResult += "!Default value: +. Available values: \"-\", \"+\"\n";
+  aResult += aScope + "write.material :\t " + InternalParameters.WriteMaterial + "\n";
+  aResult += "!\n";
+
+  aResult += "!\n";
+  aResult += "!Setting up the write.vismaterial parameter which is used to indicate write "
+             "Visual Material properties or not\n";
+  aResult += "!Default value: +. Available values: \"-\", \"+\"\n";
+  aResult += aScope + "write.vismaterial :\t " + InternalParameters.WriteVisMaterial + "\n";
+  aResult += "!\n";
+
   aResult += "!\n";
   aResult += "!Setting up the Model Type which gives you the choice of translation mode for an "
              "Open CASCADE shape that ";
index d70a81f5ac332b510cf3523c5dfb3b54b5b3cb7b..c4557fec4514ace619afa8f4d8f68294a9d4259a 100644 (file)
@@ -199,6 +199,8 @@ public:
   bool WriteName = true; //<! NameMode is used to indicate write Name or not
   bool WriteLayer = true; //<! LayerMode is used to indicate write Layers or not
   bool WriteProps = true; //<! PropsMode is used to indicate write Validation properties or not
+  bool WriteMaterial = true;  //<! MaterialMode is used to indicate write Material or not
+  bool WriteVisMaterial = false;  //<! VisMaterialMode is used to indicate write Visual Material or not
   STEPControl_StepModelType WriteModelType = STEPControl_AsIs; //<! Gives you the choice of translation mode for an Open CASCADE shape that is being translated to STEP
   bool CleanDuplicates = false; //<! Indicates whether to remove duplicate entities from the STEP file
   // clang-format on
index b53501656b0bf0503aafee5080071e686186f70f..f3d04175549f0e3ba390a9307c63c0e672320d56 100644 (file)
@@ -116,6 +116,8 @@ bool DESTEP_Provider::Write(const TCollection_AsciiString&  thePath,
   aWriter.SetLayerMode(aNode->InternalParameters.WriteLayer);
   aWriter.SetPropsMode(aNode->InternalParameters.WriteProps);
   aWriter.SetShapeFixParameters(aNode->ShapeFixParameters);
+  aWriter.SetMaterialMode(aNode->InternalParameters.WriteMaterial);
+  aWriter.SetVisualMaterialMode(aNode->InternalParameters.WriteVisMaterial);
   aWriter.SetCleanDuplicates(aNode->InternalParameters.CleanDuplicates);
   DESTEP_Parameters aParams        = aNode->InternalParameters;
   Standard_Real     aScaleFactorMM = 1.;
index 235d256623a00d968dcae37fbeba2b59aa5b35f2..478b5cfcb5d778e8182c8d6120ac61c25f5eea1d 100644 (file)
@@ -2,6 +2,7 @@
 set(OCCT_TKDESTEP_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
 
 set(OCCT_TKDESTEP_GTests_FILES
+    STEPConstruct_RenderingProperties_Test.cxx
     StepTidy_BaseTestFixture.pxx
     StepTidy_Axis2Placement3dReducer_Test.cxx
     StepTidy_CartesianPointReducer_Test.cxx
diff --git a/src/DataExchange/TKDESTEP/GTests/STEPConstruct_RenderingProperties_Test.cxx b/src/DataExchange/TKDESTEP/GTests/STEPConstruct_RenderingProperties_Test.cxx
new file mode 100644 (file)
index 0000000..eb7053d
--- /dev/null
@@ -0,0 +1,508 @@
+// Copyright (c) 2025 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 <STEPConstruct_RenderingProperties.hxx>
+
+#include <STEPConstruct_Styles.hxx>
+#include <StepVisual_SurfaceStyleRenderingWithProperties.hxx>
+#include <StepVisual_HArray1OfRenderingPropertiesSelect.hxx>
+#include <StepVisual_SurfaceStyleTransparent.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx>
+#include <StepVisual_ColourRgb.hxx>
+#include <Quantity_Color.hxx>
+#include <Quantity_ColorRGBA.hxx>
+#include <TCollection_HAsciiString.hxx>
+
+#include <gtest/gtest.h>
+
+// Test fixture for STEPConstruct_RenderingProperties tests
+class STEPConstruct_RenderingPropertiesTest : public ::testing::Test
+{
+protected:
+  //! Set up function called before each test
+  void SetUp() override
+  {
+    // Create some common colors and values for testing
+    mySurfaceColor     = Quantity_Color(0.8, 0.5, 0.2, Quantity_TOC_RGB);
+    myTransparency     = 0.25;
+    myAmbientFactor    = 0.3;
+    myDiffuseFactor    = 1.0;
+    mySpecularFactor   = 0.8;
+    mySpecularExponent = 45.0;
+    mySpecularColor    = Quantity_Color(0.9, 0.9, 0.9, Quantity_TOC_RGB);
+  }
+
+  //! Helper function to create a STEP rendering properties object for testing
+  Handle(StepVisual_SurfaceStyleRenderingWithProperties) CreateStepRenderingProperties()
+  {
+    // Create the surface color
+    Handle(TCollection_HAsciiString) aColorName = new TCollection_HAsciiString("");
+    Handle(StepVisual_Colour) aSurfaceColor     = STEPConstruct_Styles::EncodeColor(mySurfaceColor);
+
+    // Create transparency property
+    Handle(StepVisual_SurfaceStyleTransparent) aTransp = new StepVisual_SurfaceStyleTransparent();
+    aTransp->Init(myTransparency);
+
+    // Create specular color
+    Handle(StepVisual_Colour) aSpecColor = STEPConstruct_Styles::EncodeColor(mySpecularColor);
+
+    // Create reflectance model
+    Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular) aReflectance =
+      new StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular();
+    aReflectance->Init(myAmbientFactor,
+                       myDiffuseFactor,
+                       mySpecularFactor,
+                       mySpecularExponent,
+                       aSpecColor);
+
+    // Create the properties array with two entries: transparency and reflectance
+    Handle(StepVisual_HArray1OfRenderingPropertiesSelect) aProps =
+      new StepVisual_HArray1OfRenderingPropertiesSelect(1, 2);
+
+    StepVisual_RenderingPropertiesSelect aRps1, aRps2;
+    aRps1.SetValue(aTransp);
+    aRps2.SetValue(aReflectance);
+
+    aProps->SetValue(1, aRps1);
+    aProps->SetValue(2, aRps2);
+
+    // Create and return the final object
+    Handle(StepVisual_SurfaceStyleRenderingWithProperties) aResult =
+      new StepVisual_SurfaceStyleRenderingWithProperties();
+    aResult->Init(StepVisual_ssmNormalShading, aSurfaceColor, aProps);
+
+    return aResult;
+  }
+
+  //! Helper function to create a common material for testing
+  XCAFDoc_VisMaterialCommon CreateMaterial()
+  {
+    XCAFDoc_VisMaterialCommon aMaterial;
+
+    // Set basic properties
+    aMaterial.DiffuseColor = mySurfaceColor;
+    aMaterial.Transparency = myTransparency;
+
+    // Calculate ambient color based on ambient factor
+    aMaterial.AmbientColor = Quantity_Color(mySurfaceColor.Red() * myAmbientFactor,
+                                            mySurfaceColor.Green() * myAmbientFactor,
+                                            mySurfaceColor.Blue() * myAmbientFactor,
+                                            Quantity_TOC_RGB);
+
+    // Set specular properties
+    aMaterial.SpecularColor = mySpecularColor;
+    aMaterial.Shininess     = (Standard_ShortReal)(mySpecularExponent / 128.0);
+
+    // Mark as defined
+    aMaterial.IsDefined = Standard_True;
+
+    return aMaterial;
+  }
+
+  //! Compare two colors with tolerance
+  Standard_Boolean AreColorsEqual(const Quantity_Color& theC1,
+                                  const Quantity_Color& theC2,
+                                  const Standard_Real   theTol = 0.01)
+  {
+    return (Abs(theC1.Red() - theC2.Red()) <= theTol)
+           && (Abs(theC1.Green() - theC2.Green()) <= theTol)
+           && (Abs(theC1.Blue() - theC2.Blue()) <= theTol);
+  }
+
+  // Test member variables
+  Quantity_Color mySurfaceColor;     //!< Surface color for testing
+  Quantity_Color mySpecularColor;    //!< Specular color for testing
+  Standard_Real  myTransparency;     //!< Transparency value for testing
+  Standard_Real  myAmbientFactor;    //!< Ambient reflectance factor for testing
+  Standard_Real  myDiffuseFactor;    //!< Diffuse reflectance factor for testing
+  Standard_Real  mySpecularFactor;   //!< Specular reflectance factor for testing
+  Standard_Real  mySpecularExponent; //!< Specular exponent value for testing
+};
+
+// Test default constructor
+TEST_F(STEPConstruct_RenderingPropertiesTest, DefaultConstructor)
+{
+  STEPConstruct_RenderingProperties aProps;
+
+  EXPECT_FALSE(aProps.IsDefined());
+  EXPECT_FALSE(aProps.IsAmbientReflectanceDefined());
+  EXPECT_FALSE(aProps.IsDiffuseReflectanceDefined());
+  EXPECT_FALSE(aProps.IsSpecularReflectanceDefined());
+  EXPECT_FALSE(aProps.IsSpecularExponentDefined());
+  EXPECT_FALSE(aProps.IsSpecularColourDefined());
+
+  EXPECT_EQ(aProps.Transparency(), 0.0);
+  EXPECT_EQ(aProps.RenderingMethod(), StepVisual_ssmNormalShading);
+}
+
+// Test RGBA color constructor
+TEST_F(STEPConstruct_RenderingPropertiesTest, RGBAConstructor)
+{
+  // Create an RGBA color with alpha = 0.75 (transparency = 0.25)
+  Quantity_ColorRGBA aRgba(mySurfaceColor, 0.75);
+
+  // Create rendering properties from RGBA
+  STEPConstruct_RenderingProperties aProps(aRgba);
+
+  EXPECT_TRUE(aProps.IsDefined());
+  EXPECT_FALSE(aProps.IsAmbientReflectanceDefined());
+  EXPECT_FALSE(aProps.IsDiffuseReflectanceDefined());
+  EXPECT_FALSE(aProps.IsSpecularReflectanceDefined());
+
+  EXPECT_TRUE(AreColorsEqual(aProps.SurfaceColor(), mySurfaceColor));
+  EXPECT_NEAR(aProps.Transparency(), 0.25, 0.001);
+  EXPECT_EQ(aProps.RenderingMethod(), StepVisual_ssmNormalShading);
+}
+
+// Test StepVisual_SurfaceStyleRenderingWithProperties constructor
+TEST_F(STEPConstruct_RenderingPropertiesTest, StepRenderingPropertiesConstructor)
+{
+  Handle(StepVisual_SurfaceStyleRenderingWithProperties) aStepProps =
+    CreateStepRenderingProperties();
+
+  STEPConstruct_RenderingProperties aProps(aStepProps);
+
+  EXPECT_TRUE(aProps.IsDefined());
+  EXPECT_TRUE(aProps.IsAmbientReflectanceDefined());
+  EXPECT_TRUE(aProps.IsDiffuseReflectanceDefined());
+  EXPECT_TRUE(aProps.IsSpecularReflectanceDefined());
+  EXPECT_TRUE(aProps.IsSpecularExponentDefined());
+  EXPECT_TRUE(aProps.IsSpecularColourDefined());
+
+  EXPECT_TRUE(AreColorsEqual(aProps.SurfaceColor(), mySurfaceColor));
+  EXPECT_NEAR(aProps.Transparency(), myTransparency, 0.001);
+  EXPECT_NEAR(aProps.AmbientReflectance(), myAmbientFactor, 0.001);
+  EXPECT_NEAR(aProps.DiffuseReflectance(), myDiffuseFactor, 0.001);
+  EXPECT_NEAR(aProps.SpecularReflectance(), mySpecularFactor, 0.001);
+  EXPECT_NEAR(aProps.SpecularExponent(), mySpecularExponent, 0.001);
+  EXPECT_TRUE(AreColorsEqual(aProps.SpecularColour(), mySpecularColor));
+  EXPECT_EQ(aProps.RenderingMethod(), StepVisual_ssmNormalShading);
+}
+
+// Test XCAFDoc_VisMaterialCommon constructor
+TEST_F(STEPConstruct_RenderingPropertiesTest, MaterialConstructor)
+{
+  XCAFDoc_VisMaterialCommon aMaterial = CreateMaterial();
+
+  STEPConstruct_RenderingProperties aProps(aMaterial);
+
+  EXPECT_TRUE(aProps.IsDefined());
+  EXPECT_TRUE(aProps.IsAmbientReflectanceDefined());
+  EXPECT_TRUE(aProps.IsDiffuseReflectanceDefined());
+  EXPECT_TRUE(aProps.IsSpecularReflectanceDefined());
+  EXPECT_TRUE(aProps.IsSpecularExponentDefined());
+  EXPECT_TRUE(aProps.IsSpecularColourDefined());
+
+  EXPECT_TRUE(AreColorsEqual(aProps.SurfaceColor(), mySurfaceColor));
+  EXPECT_NEAR(aProps.Transparency(), myTransparency, 0.001);
+  EXPECT_NEAR(aProps.AmbientReflectance(), myAmbientFactor, 0.02); // Slightly larger tolerance
+  EXPECT_NEAR(aProps.DiffuseReflectance(), 1.0, 0.001);
+}
+
+// Test setting reflectance properties
+TEST_F(STEPConstruct_RenderingPropertiesTest, SetReflectanceProperties)
+{
+  STEPConstruct_RenderingProperties aProps;
+
+  // Initialize with basic color and transparency
+  aProps.Init(mySurfaceColor, myTransparency);
+  EXPECT_TRUE(aProps.IsDefined());
+
+  // Set ambient reflectance
+  aProps.SetAmbientReflectance(myAmbientFactor);
+  EXPECT_TRUE(aProps.IsAmbientReflectanceDefined());
+  EXPECT_NEAR(aProps.AmbientReflectance(), myAmbientFactor, 0.001);
+  EXPECT_FALSE(aProps.IsDiffuseReflectanceDefined());
+
+  // Set ambient and diffuse reflectance
+  aProps.SetAmbientAndDiffuseReflectance(myAmbientFactor, myDiffuseFactor);
+  EXPECT_TRUE(aProps.IsAmbientReflectanceDefined());
+  EXPECT_TRUE(aProps.IsDiffuseReflectanceDefined());
+  EXPECT_NEAR(aProps.AmbientReflectance(), myAmbientFactor, 0.001);
+  EXPECT_NEAR(aProps.DiffuseReflectance(), myDiffuseFactor, 0.001);
+  EXPECT_FALSE(aProps.IsSpecularReflectanceDefined());
+
+  // Set all reflectance properties
+  aProps.SetAmbientDiffuseAndSpecularReflectance(myAmbientFactor,
+                                                 myDiffuseFactor,
+                                                 mySpecularFactor,
+                                                 mySpecularExponent,
+                                                 mySpecularColor);
+
+  EXPECT_TRUE(aProps.IsAmbientReflectanceDefined());
+  EXPECT_TRUE(aProps.IsDiffuseReflectanceDefined());
+  EXPECT_TRUE(aProps.IsSpecularReflectanceDefined());
+  EXPECT_TRUE(aProps.IsSpecularExponentDefined());
+  EXPECT_TRUE(aProps.IsSpecularColourDefined());
+
+  EXPECT_NEAR(aProps.AmbientReflectance(), myAmbientFactor, 0.001);
+  EXPECT_NEAR(aProps.DiffuseReflectance(), myDiffuseFactor, 0.001);
+  EXPECT_NEAR(aProps.SpecularReflectance(), mySpecularFactor, 0.001);
+  EXPECT_NEAR(aProps.SpecularExponent(), mySpecularExponent, 0.001);
+  EXPECT_TRUE(AreColorsEqual(aProps.SpecularColour(), mySpecularColor));
+}
+
+// Test creating STEP rendering properties
+TEST_F(STEPConstruct_RenderingPropertiesTest, CreateRenderingProperties)
+{
+  STEPConstruct_RenderingProperties aProps;
+  aProps.Init(mySurfaceColor, myTransparency);
+  aProps.SetAmbientDiffuseAndSpecularReflectance(myAmbientFactor,
+                                                 myDiffuseFactor,
+                                                 mySpecularFactor,
+                                                 mySpecularExponent,
+                                                 mySpecularColor);
+
+  Handle(StepVisual_SurfaceStyleRenderingWithProperties) aStepProps =
+    aProps.CreateRenderingProperties();
+
+  ASSERT_FALSE(aStepProps.IsNull());
+  EXPECT_EQ(aStepProps->RenderingMethod(), StepVisual_ssmNormalShading);
+
+  // Verify properties through re-parsing
+  STEPConstruct_RenderingProperties aParsedProps(aStepProps);
+
+  EXPECT_TRUE(aParsedProps.IsDefined());
+  EXPECT_TRUE(AreColorsEqual(aParsedProps.SurfaceColor(), mySurfaceColor));
+  EXPECT_NEAR(aParsedProps.Transparency(), myTransparency, 0.001);
+  EXPECT_NEAR(aParsedProps.AmbientReflectance(), myAmbientFactor, 0.001);
+  EXPECT_NEAR(aParsedProps.DiffuseReflectance(), myDiffuseFactor, 0.001);
+  EXPECT_NEAR(aParsedProps.SpecularReflectance(), mySpecularFactor, 0.001);
+  EXPECT_NEAR(aParsedProps.SpecularExponent(), mySpecularExponent, 0.001);
+  EXPECT_TRUE(AreColorsEqual(aParsedProps.SpecularColour(), mySpecularColor));
+}
+
+// Test creating XCAFDoc_VisMaterialCommon
+TEST_F(STEPConstruct_RenderingPropertiesTest, CreateXCAFMaterial)
+{
+  STEPConstruct_RenderingProperties aProps;
+  aProps.Init(mySurfaceColor, myTransparency);
+  aProps.SetAmbientDiffuseAndSpecularReflectance(myAmbientFactor,
+                                                 myDiffuseFactor,
+                                                 mySpecularFactor,
+                                                 mySpecularExponent,
+                                                 mySpecularColor);
+
+  XCAFDoc_VisMaterialCommon aMaterial = aProps.CreateXCAFMaterial();
+  EXPECT_TRUE(aMaterial.IsDefined);
+
+  // Check basic properties
+  EXPECT_TRUE(AreColorsEqual(aMaterial.DiffuseColor, mySurfaceColor));
+  EXPECT_NEAR(aMaterial.Transparency, myTransparency, 0.001);
+
+  // Check calculated ambient color
+  Quantity_Color anExpectedAmbient(mySurfaceColor.Red() * myAmbientFactor,
+                                   mySurfaceColor.Green() * myAmbientFactor,
+                                   mySurfaceColor.Blue() * myAmbientFactor,
+                                   Quantity_TOC_RGB);
+  EXPECT_TRUE(AreColorsEqual(aMaterial.AmbientColor, anExpectedAmbient));
+
+  // Check specular properties
+  EXPECT_TRUE(AreColorsEqual(aMaterial.SpecularColor, mySpecularColor));
+  EXPECT_NEAR(aMaterial.Shininess, mySpecularExponent / 128.0, 0.01);
+}
+
+// Test bidirectional conversion
+TEST_F(STEPConstruct_RenderingPropertiesTest, BidirectionalConversion)
+{
+  // Start with an XCAFDoc_VisMaterialCommon
+  XCAFDoc_VisMaterialCommon aOriginalMaterial = CreateMaterial();
+
+  // Convert to rendering properties
+  STEPConstruct_RenderingProperties aProps(aOriginalMaterial);
+
+  // Convert back to material
+  XCAFDoc_VisMaterialCommon aConvertedMaterial = aProps.CreateXCAFMaterial();
+
+  // Verify that the converted material matches the original
+  EXPECT_TRUE(aConvertedMaterial.IsDefined);
+
+  EXPECT_TRUE(AreColorsEqual(aConvertedMaterial.DiffuseColor, aOriginalMaterial.DiffuseColor));
+  EXPECT_NEAR(aConvertedMaterial.Transparency, aOriginalMaterial.Transparency, 0.001);
+  EXPECT_TRUE(
+    AreColorsEqual(aConvertedMaterial.AmbientColor, aOriginalMaterial.AmbientColor, 0.05));
+  EXPECT_TRUE(
+    AreColorsEqual(aConvertedMaterial.SpecularColor, aOriginalMaterial.SpecularColor, 0.05));
+  EXPECT_NEAR(aConvertedMaterial.Shininess, aOriginalMaterial.Shininess, 0.05);
+}
+
+// Test Init method with RGBA color
+TEST_F(STEPConstruct_RenderingPropertiesTest, InitWithRGBAColor)
+{
+  STEPConstruct_RenderingProperties aProps;
+
+  // Create an RGBA color with alpha = 0.6 (transparency = 0.4)
+  Quantity_ColorRGBA aRgba(Quantity_Color(0.3, 0.6, 0.9, Quantity_TOC_RGB), 0.6);
+
+  aProps.Init(aRgba);
+
+  EXPECT_TRUE(aProps.IsDefined());
+  EXPECT_FALSE(aProps.IsAmbientReflectanceDefined());
+  EXPECT_FALSE(aProps.IsDiffuseReflectanceDefined());
+  EXPECT_FALSE(aProps.IsSpecularReflectanceDefined());
+
+  Quantity_Color expectedColor(0.3, 0.6, 0.9, Quantity_TOC_RGB);
+  EXPECT_TRUE(AreColorsEqual(aProps.SurfaceColor(), expectedColor));
+  EXPECT_NEAR(aProps.Transparency(), 0.4, 0.001);
+}
+
+// Test Init method with custom rendering method
+TEST_F(STEPConstruct_RenderingPropertiesTest, InitWithCustomRenderingMethod)
+{
+  STEPConstruct_RenderingProperties aProps;
+
+  // Initialize with phong shading
+  aProps.Init(mySurfaceColor, myTransparency);
+  aProps.SetRenderingMethod(StepVisual_ssmDotShading);
+
+  EXPECT_TRUE(aProps.IsDefined());
+  EXPECT_TRUE(AreColorsEqual(aProps.SurfaceColor(), mySurfaceColor));
+  EXPECT_NEAR(aProps.Transparency(), myTransparency, 0.001);
+  EXPECT_EQ(aProps.RenderingMethod(), StepVisual_ssmDotShading);
+}
+
+// Test the IsMaterialConvertible method
+TEST_F(STEPConstruct_RenderingPropertiesTest, MaterialConvertible)
+{
+  STEPConstruct_RenderingProperties aProps;
+
+  // Initially shouldn't be convertible
+  EXPECT_FALSE(aProps.IsMaterialConvertible());
+
+  // After setting basic properties, still shouldn't be convertible
+  aProps.Init(mySurfaceColor, myTransparency);
+  EXPECT_FALSE(aProps.IsMaterialConvertible());
+
+  // After setting all required properties, should be convertible
+  aProps.SetAmbientDiffuseAndSpecularReflectance(myAmbientFactor,
+                                                 myDiffuseFactor,
+                                                 mySpecularFactor,
+                                                 mySpecularExponent,
+                                                 mySpecularColor);
+
+  EXPECT_TRUE(aProps.IsMaterialConvertible());
+}
+
+// Test with null inputs
+TEST_F(STEPConstruct_RenderingPropertiesTest, NullInputs)
+{
+  STEPConstruct_RenderingProperties aProps;
+
+  // Creating from null STEP rendering properties
+  Handle(StepVisual_SurfaceStyleRenderingWithProperties) nullProps;
+  aProps.Init(nullProps);
+
+  EXPECT_FALSE(aProps.IsDefined());
+
+  // Creating from null XCAF material
+  XCAFDoc_VisMaterialCommon nullMaterial;
+  nullMaterial.IsDefined = Standard_False;
+
+  STEPConstruct_RenderingProperties propsFromNull(nullMaterial);
+  EXPECT_FALSE(propsFromNull.IsDefined());
+}
+
+// Test creating STEP rendering properties with ambient only
+TEST_F(STEPConstruct_RenderingPropertiesTest, CreateAmbientOnlyProperties)
+{
+  STEPConstruct_RenderingProperties aProps;
+  aProps.Init(mySurfaceColor, myTransparency);
+  aProps.SetAmbientReflectance(myAmbientFactor);
+
+  Handle(StepVisual_SurfaceStyleRenderingWithProperties) aStepProps =
+    aProps.CreateRenderingProperties();
+
+  ASSERT_FALSE(aStepProps.IsNull());
+
+  // Verify properties through re-parsing
+  STEPConstruct_RenderingProperties aParsedProps(aStepProps);
+
+  EXPECT_TRUE(aParsedProps.IsDefined());
+  EXPECT_TRUE(aParsedProps.IsAmbientReflectanceDefined());
+  EXPECT_FALSE(aParsedProps.IsDiffuseReflectanceDefined());
+  EXPECT_FALSE(aParsedProps.IsSpecularReflectanceDefined());
+
+  EXPECT_TRUE(AreColorsEqual(aParsedProps.SurfaceColor(), mySurfaceColor));
+  EXPECT_NEAR(aParsedProps.Transparency(), myTransparency, 0.001);
+  EXPECT_NEAR(aParsedProps.AmbientReflectance(), myAmbientFactor, 0.001);
+}
+
+// Test creating STEP rendering properties with ambient and diffuse
+TEST_F(STEPConstruct_RenderingPropertiesTest, CreateAmbientAndDiffuseProperties)
+{
+  STEPConstruct_RenderingProperties aProps;
+  aProps.Init(mySurfaceColor, myTransparency);
+  aProps.SetAmbientAndDiffuseReflectance(myAmbientFactor, myDiffuseFactor);
+
+  Handle(StepVisual_SurfaceStyleRenderingWithProperties) aStepProps =
+    aProps.CreateRenderingProperties();
+
+  ASSERT_FALSE(aStepProps.IsNull());
+
+  // Verify properties through re-parsing
+  STEPConstruct_RenderingProperties aParsedProps(aStepProps);
+
+  EXPECT_TRUE(aParsedProps.IsDefined());
+  EXPECT_TRUE(aParsedProps.IsAmbientReflectanceDefined());
+  EXPECT_TRUE(aParsedProps.IsDiffuseReflectanceDefined());
+  EXPECT_FALSE(aParsedProps.IsSpecularReflectanceDefined());
+
+  EXPECT_TRUE(AreColorsEqual(aParsedProps.SurfaceColor(), mySurfaceColor));
+  EXPECT_NEAR(aParsedProps.Transparency(), myTransparency, 0.001);
+  EXPECT_NEAR(aParsedProps.AmbientReflectance(), myAmbientFactor, 0.001);
+  EXPECT_NEAR(aParsedProps.DiffuseReflectance(), myDiffuseFactor, 0.001);
+}
+
+// Test handling of non-standard specular color
+TEST_F(STEPConstruct_RenderingPropertiesTest, NonStandardSpecularColor)
+{
+  // Create a material with custom specular color not matching diffuse
+  XCAFDoc_VisMaterialCommon aMaterial = CreateMaterial();
+  Quantity_Color aCustomSpecular(0.1, 0.8, 0.2, Quantity_TOC_RGB); // Very different from diffuse
+  aMaterial.SpecularColor = aCustomSpecular;
+
+  // Convert to rendering properties
+  STEPConstruct_RenderingProperties aProps(aMaterial);
+
+  // Verify specular color is preserved as actual color, not just a factor
+  EXPECT_TRUE(aProps.IsSpecularColourDefined());
+  EXPECT_TRUE(AreColorsEqual(aProps.SpecularColour(), aCustomSpecular));
+
+  // Verify converting back preserves the special color
+  XCAFDoc_VisMaterialCommon aReconvertedMaterial = aProps.CreateXCAFMaterial();
+  EXPECT_TRUE(AreColorsEqual(aReconvertedMaterial.SpecularColor, aCustomSpecular, 0.05));
+}
+
+// Test extreme values for properties
+TEST_F(STEPConstruct_RenderingPropertiesTest, ExtremeValues)
+{
+  STEPConstruct_RenderingProperties aProps;
+
+  // Test with full transparency
+  aProps.Init(mySurfaceColor, 1.0);
+  EXPECT_NEAR(aProps.Transparency(), 1.0, 0.001);
+
+  // Test with extreme reflectance values
+  aProps.SetAmbientDiffuseAndSpecularReflectance(0.0, 2.0, 1.0, 256.0, mySpecularColor);
+
+  // Values should be clamped when creating material
+  XCAFDoc_VisMaterialCommon aMaterial = aProps.CreateXCAFMaterial();
+
+  // Ambient should be 0
+  EXPECT_NEAR(aMaterial.AmbientColor.Red(), 0.0, 0.001);
+  EXPECT_NEAR(aMaterial.AmbientColor.Green(), 0.0, 0.001);
+  EXPECT_NEAR(aMaterial.AmbientColor.Blue(), 0.0, 0.001);
+
+  // Shininess should be reasonable value (256/128 = 2, clamped to 1.0)
+  EXPECT_NEAR(aMaterial.Shininess, 1.0, 0.1);
+}
index 9b168b2996358fb49bdc0d790944e5b2f72fb895..9a93732365607e24978a2f2e026cbb785b98824a 100644 (file)
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleFillArea.pxx"
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleParameterLine.pxx"
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbient.pxx"
+#include "../RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.pxx"
+#include "../RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.pxx"
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleRendering.pxx"
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleRenderingWithProperties.pxx"
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleSegmentationCurve.pxx"
 #include <StepVisual_SurfaceStyleFillArea.hxx>
 #include <StepVisual_SurfaceStyleParameterLine.hxx>
 #include <StepVisual_SurfaceStyleReflectanceAmbient.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx>
 #include <StepVisual_SurfaceStyleRenderingWithProperties.hxx>
 #include <StepVisual_SurfaceStyleSegmentationCurve.hxx>
 #include <StepVisual_SurfaceStyleSilhouette.hxx>
@@ -5284,6 +5288,18 @@ void RWStepAP214_GeneralModule::FillSharedCase(const Standard_Integer
       aTool.Share(anEnt, iter);
     }
     break;
+    case 825: {
+      DeclareAndCast(StepVisual_SurfaceStyleReflectanceAmbientDiffuse, anEnt, ent);
+      RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse aTool;
+      aTool.Share(anEnt, iter);
+    }
+    break;
+    case 826: {
+      DeclareAndCast(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular, anEnt, ent);
+      RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular aTool;
+      aTool.Share(anEnt, iter);
+    }
+    break;
     default:
       break;
   }
@@ -7588,7 +7604,12 @@ Standard_Boolean RWStepAP214_GeneralModule::NewVoid(const Standard_Integer
     case 824:
       ent = new StepRepr_MechanicalDesignAndDraughtingRelationship;
       break;
-
+    case 825:
+      ent = new StepVisual_SurfaceStyleReflectanceAmbientDiffuse;
+      break;
+    case 826:
+      ent = new StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular;
+      break;
     default:
       return Standard_False;
   }
index b49cde5c528a124d97e0415125a86cc4ea417d8e..0ab8e359c6936220ac87f1eae5fa0db2e819163d 100644 (file)
@@ -436,6 +436,8 @@ IMPLEMENT_STANDARD_RTTIEXT(RWStepAP214_ReadWriteModule, StepData_ReadWriteModule
 
 #include <StepVisual_SurfaceStyleTransparent.hxx>
 #include <StepVisual_SurfaceStyleReflectanceAmbient.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx>
 #include <StepVisual_SurfaceStyleRendering.hxx>
 #include <StepVisual_SurfaceStyleRenderingWithProperties.hxx>
 
@@ -1454,6 +1456,8 @@ IMPLEMENT_STANDARD_RTTIEXT(RWStepAP214_ReadWriteModule, StepData_ReadWriteModule
 
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleTransparent.pxx"
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbient.pxx"
+#include "../RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.pxx"
+#include "../RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.pxx"
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleRendering.pxx"
 #include "../RWStepVisual/RWStepVisual_RWSurfaceStyleRenderingWithProperties.pxx"
 
@@ -10816,6 +10820,18 @@ void RWStepAP214_ReadWriteModule::ReadStep(const Standard_Integer
       aTool.ReadStep(data, num, ach, anent);
     }
     break;
+    case 825: {
+      DeclareAndCast(StepVisual_SurfaceStyleReflectanceAmbientDiffuse, anent, ent);
+      RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse aTool;
+      aTool.ReadStep(data, num, ach, anent);
+    }
+    break;
+    case 826: {
+      DeclareAndCast(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular, anent, ent);
+      RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular aTool;
+      aTool.ReadStep(data, num, ach, anent);
+    }
+    break;
     default:
       ach->AddFail("Type Mismatch when reading - Entity");
   }
index 9b19354f12120fe9df2b1c938e3e97a5ca5c1a80..5edb1a9aafbbaccb290b213909d6daaa1350d462 100644 (file)
@@ -128,6 +128,10 @@ set(OCCT_RWStepVisual_FILES
   RWStepVisual_RWSurfaceStyleParameterLine.pxx
   RWStepVisual_RWSurfaceStyleReflectanceAmbient.cxx
   RWStepVisual_RWSurfaceStyleReflectanceAmbient.pxx
+  RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.cxx
+  RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.pxx
+  RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.cxx
+  RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.pxx
   RWStepVisual_RWSurfaceStyleRendering.cxx
   RWStepVisual_RWSurfaceStyleRendering.pxx
   RWStepVisual_RWSurfaceStyleRenderingWithProperties.cxx
diff --git a/src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.cxx b/src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.cxx
new file mode 100644 (file)
index 0000000..fff069f
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (c) Open CASCADE 2025
+//
+// 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 "RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.pxx"
+#include <Interface_EntityIterator.hxx>
+#include <StepData_StepReaderData.hxx>
+#include <StepData_StepWriter.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx>
+#include <Standard_Real.hxx>
+
+//=================================================================================================
+
+RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse::
+  RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse()
+{
+}
+
+//=================================================================================================
+
+void RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse::ReadStep(
+  const Handle(StepData_StepReaderData)&                          theData,
+  const Standard_Integer                                          theNum,
+  Handle(Interface_Check)&                                        theAch,
+  const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse)& theEnt) const
+{
+  // Check number of parameters
+  if (!theData->CheckNbParams(theNum, 2, theAch, "surface_style_reflectance_ambient_diffuse"))
+    return;
+
+  // Inherited fields of SurfaceStyleReflectanceAmbient
+  Standard_Real aAmbientReflectance;
+  theData->ReadReal(theNum, 1, "ambient_reflectance", theAch, aAmbientReflectance);
+
+  // Own fields of SurfaceStyleReflectanceAmbientDiffuse
+  Standard_Real aDiffuseReflectance;
+  theData->ReadReal(theNum, 2, "diffuse_reflectance", theAch, aDiffuseReflectance);
+
+  // Initialize entity
+  theEnt->Init(aAmbientReflectance, aDiffuseReflectance);
+}
+
+//=================================================================================================
+
+void RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse::WriteStep(
+  StepData_StepWriter&                                            theSW,
+  const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse)& theEnt) const
+{
+  // Inherited fields of SurfaceStyleReflectanceAmbient
+  theSW.Send(theEnt->AmbientReflectance());
+
+  // Own fields of SurfaceStyleReflectanceAmbientDiffuse
+  theSW.Send(theEnt->DiffuseReflectance());
+}
+
+//=================================================================================================
+
+void RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse::Share(
+  const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse)&,
+  Interface_EntityIterator&) const
+{
+  // Own fields of SurfaceStyleReflectanceAmbientDiffuse
+}
diff --git a/src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.pxx b/src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse.pxx
new file mode 100644 (file)
index 0000000..8c25c7c
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (c) Open CASCADE 2025
+//
+// 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.
+
+#ifndef _RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse_HeaderFile_
+#define _RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse_HeaderFile_
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+
+class StepData_StepReaderData;
+class Interface_Check;
+class StepData_StepWriter;
+class Interface_EntityIterator;
+class StepVisual_SurfaceStyleReflectanceAmbientDiffuse;
+
+//! Read & Write tool for SurfaceStyleReflectanceAmbientDiffuse
+class RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse
+{
+public:
+  DEFINE_STANDARD_ALLOC
+
+  Standard_HIDDEN RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse();
+
+  Standard_HIDDEN void ReadStep(
+    const Handle(StepData_StepReaderData)&                          theData,
+    const Standard_Integer                                          theNum,
+    Handle(Interface_Check)&                                        theAch,
+    const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse)& theEnt) const;
+
+  Standard_HIDDEN void WriteStep(
+    StepData_StepWriter&                                            theSW,
+    const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse)& theEnt) const;
+
+  Standard_HIDDEN void Share(const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse)& theEnt,
+                             Interface_EntityIterator& theIter) const;
+};
+#endif // _RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuse_HeaderFile_
diff --git a/src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.cxx b/src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.cxx
new file mode 100644 (file)
index 0000000..d08b5a6
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (c) Open CASCADE 2025
+//
+// 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 "RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.pxx"
+#include <Interface_EntityIterator.hxx>
+#include <StepData_StepReaderData.hxx>
+#include <StepData_StepWriter.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx>
+#include <StepVisual_Colour.hxx>
+#include <Standard_Real.hxx>
+
+//=================================================================================================
+
+RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular::
+  RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular()
+{
+}
+
+//=================================================================================================
+
+void RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular::ReadStep(
+  const Handle(StepData_StepReaderData)&                                  theData,
+  const Standard_Integer                                                  theNum,
+  Handle(Interface_Check)&                                                theAch,
+  const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular)& theEnt) const
+{
+  // Check number of parameters
+  if (!theData->CheckNbParams(theNum,
+                              5,
+                              theAch,
+                              "surface_style_reflectance_ambient_diffuse_specular"))
+    return;
+
+  // Inherited fields of SurfaceStyleReflectanceAmbient
+  Standard_Real aAmbientReflectance;
+  theData->ReadReal(theNum, 1, "ambient_reflectance", theAch, aAmbientReflectance);
+
+  // Inherited fields of SurfaceStyleReflectanceAmbientDiffuse
+  Standard_Real aDiffuseReflectance;
+  theData->ReadReal(theNum, 2, "diffuse_reflectance", theAch, aDiffuseReflectance);
+
+  // Own fields of SurfaceStyleReflectanceAmbientDiffuseSpecular
+  Standard_Real aSpecularReflectance;
+  theData->ReadReal(theNum, 3, "specular_reflectance", theAch, aSpecularReflectance);
+
+  Standard_Real aSpecularExponent;
+  theData->ReadReal(theNum, 4, "specular_exponent", theAch, aSpecularExponent);
+
+  Handle(StepVisual_Colour) aSpecularColour;
+  theData->ReadEntity(theNum,
+                      5,
+                      "specular_colour",
+                      theAch,
+                      STANDARD_TYPE(StepVisual_Colour),
+                      aSpecularColour);
+
+  // Initialize entity
+  theEnt->Init(aAmbientReflectance,
+               aDiffuseReflectance,
+               aSpecularReflectance,
+               aSpecularExponent,
+               aSpecularColour);
+}
+
+//=================================================================================================
+
+void RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular::WriteStep(
+  StepData_StepWriter&                                                    theSW,
+  const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular)& theEnt) const
+{
+  // Inherited fields of SurfaceStyleReflectanceAmbient
+  theSW.Send(theEnt->AmbientReflectance());
+
+  // Inherited fields of SurfaceStyleReflectanceAmbientDiffuse
+  theSW.Send(theEnt->DiffuseReflectance());
+
+  // Own fields of SurfaceStyleReflectanceAmbientDiffuseSpecular
+  theSW.Send(theEnt->SpecularReflectance());
+  theSW.Send(theEnt->SpecularExponent());
+  theSW.Send(theEnt->SpecularColour());
+}
+
+//=================================================================================================
+
+void RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular::Share(
+  const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular)& theEnt,
+  Interface_EntityIterator&                                               theIter) const
+{
+  // Own fields of SurfaceStyleReflectanceAmbientDiffuseSpecular
+  theIter.AddItem(theEnt->SpecularColour());
+}
diff --git a/src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.pxx b/src/DataExchange/TKDESTEP/RWStepVisual/RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular.pxx
new file mode 100644 (file)
index 0000000..f422a63
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (c) Open CASCADE 2025
+//
+// 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.
+
+#ifndef _RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular_HeaderFile_
+#define _RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular_HeaderFile_
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+
+class StepData_StepReaderData;
+class Interface_Check;
+class StepData_StepWriter;
+class Interface_EntityIterator;
+class StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular;
+
+//! Read & Write tool for SurfaceStyleReflectanceAmbientDiffuseSpecular
+class RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular
+{
+public:
+  DEFINE_STANDARD_ALLOC
+
+  Standard_HIDDEN RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular();
+
+  Standard_HIDDEN void ReadStep(
+    const Handle(StepData_StepReaderData)&                                  theData,
+    const Standard_Integer                                                  theNum,
+    Handle(Interface_Check)&                                                theAch,
+    const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular)& theEnt) const;
+
+  Standard_HIDDEN void WriteStep(
+    StepData_StepWriter&                                                    theSW,
+    const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular)& theEnt) const;
+
+  Standard_HIDDEN void Share(
+    const Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular)& theEnt,
+    Interface_EntityIterator&                                               theIter) const;
+};
+#endif // _RWStepVisual_RWSurfaceStyleReflectanceAmbientDiffuseSpecular_HeaderFile_
index bbd0811cdc9a75000885c1fd1c81844ad3d3f59c..636916e3b16e63841ea59315dbc120eecd092550 100644 (file)
@@ -1024,17 +1024,11 @@ static void SetAssemblyComponentStyle(
   if (theStyle.IsNull())
     return;
 
-  Handle(StepVisual_Colour) aSurfCol, aBoundCol, aCurveCol, aRenderCol;
-  Standard_Real             aRenderTransp;
+  Handle(StepVisual_Colour)         aSurfCol, aBoundCol, aCurveCol;
+  STEPConstruct_RenderingProperties aRenderProps;
   // check if it is component style
   Standard_Boolean anIsComponent = Standard_False;
-  if (!theStyles.GetColors(theStyle,
-                           aSurfCol,
-                           aBoundCol,
-                           aCurveCol,
-                           aRenderCol,
-                           aRenderTransp,
-                           anIsComponent))
+  if (!theStyles.GetColors(theStyle, aSurfCol, aBoundCol, aCurveCol, aRenderProps, anIsComponent))
     return;
 
   const Interface_Graph& aGraph = theTP->Graph();
@@ -1103,7 +1097,7 @@ static void SetAssemblyComponentStyle(
 
   aShape.Location(aLoc, Standard_False);
 
-  if (!aSurfCol.IsNull() || !aBoundCol.IsNull() || !aCurveCol.IsNull() || !aRenderCol.IsNull())
+  if (!aSurfCol.IsNull() || !aBoundCol.IsNull() || !aCurveCol.IsNull() || aRenderProps.IsDefined())
   {
     Quantity_Color     aSCol, aBCol, aCCol, aRCol;
     Quantity_ColorRGBA aFullSCol;
@@ -1116,13 +1110,12 @@ static void SetAssemblyComponentStyle(
       theStyles.DecodeColor(aBoundCol, aBCol);
     if (!aCurveCol.IsNull())
       theStyles.DecodeColor(aCurveCol, aCCol);
-    if (!aRenderCol.IsNull())
+    if (aRenderProps.IsDefined())
     {
-      theStyles.DecodeColor(aRenderCol, aRCol);
-      aFullSCol = Quantity_ColorRGBA(aRCol, static_cast<float>(1.0f - aRenderTransp));
+      aFullSCol = aRenderProps.GetRGBAColor();
     }
 
-    if (!aSurfCol.IsNull() || !aRenderCol.IsNull())
+    if (!aSurfCol.IsNull() || aRenderProps.IsDefined())
       theCTool->SetInstanceColor(aShape, XCAFDoc_ColorSurf, aFullSCol);
     if (!aBoundCol.IsNull())
       theCTool->SetInstanceColor(aShape, XCAFDoc_ColorCurv, aBCol);
@@ -1182,17 +1175,12 @@ static void SetStyle(const Handle(XSControl_WorkSession)&        theWS,
     anIsVisible = Standard_False;
     break;
   }
-  Handle(StepVisual_Colour) aSurfCol, aBoundCol, aCurveCol, aRenderCol;
-  Standard_Real             aRenderTransp;
+
+  Handle(StepVisual_Colour) aSurfCol, aBoundCol, aCurveCol;
   // check if it is component style
-  Standard_Boolean anIsComponent = Standard_False;
-  if (!theStyles.GetColors(theStyle,
-                           aSurfCol,
-                           aBoundCol,
-                           aCurveCol,
-                           aRenderCol,
-                           aRenderTransp,
-                           anIsComponent)
+  Standard_Boolean                  anIsComponent = Standard_False;
+  STEPConstruct_RenderingProperties aRenderProps;
+  if (!theStyles.GetColors(theStyle, aSurfCol, aBoundCol, aCurveCol, aRenderProps, anIsComponent)
       && anIsVisible)
     return;
 
@@ -1272,12 +1260,13 @@ static void SetStyle(const Handle(XSControl_WorkSession)&        theWS,
     if (aS.IsNull())
       continue;
 
-    if (!aSurfCol.IsNull() || !aBoundCol.IsNull() || !aCurveCol.IsNull() || !aRenderCol.IsNull()
+    if (!aSurfCol.IsNull() || !aBoundCol.IsNull() || !aCurveCol.IsNull() || aRenderProps.IsDefined()
         || !anIsVisible)
     {
       TDF_Label        aL;
       Standard_Boolean isFound = theSTool->SearchUsingMap(aS, aL, Standard_False, Standard_True);
-      if (!aSurfCol.IsNull() || !aBoundCol.IsNull() || !aCurveCol.IsNull() || !aRenderCol.IsNull())
+      if (!aSurfCol.IsNull() || !aBoundCol.IsNull() || !aCurveCol.IsNull()
+          || aRenderProps.IsDefined())
       {
         Quantity_Color     aSCol, aBCol, aCCol, aRCol;
         Quantity_ColorRGBA aFullSCol;
@@ -1290,14 +1279,13 @@ static void SetStyle(const Handle(XSControl_WorkSession)&        theWS,
           theStyles.DecodeColor(aBoundCol, aBCol);
         if (!aCurveCol.IsNull())
           theStyles.DecodeColor(aCurveCol, aCCol);
-        if (!aRenderCol.IsNull())
+        if (aRenderProps.IsDefined())
         {
-          theStyles.DecodeColor(aRenderCol, aRCol);
-          aFullSCol = Quantity_ColorRGBA(aRCol, static_cast<float>(1.0f - aRenderTransp));
+          aFullSCol = aRenderProps.GetRGBAColor();
         }
         if (isFound)
         {
-          if (!aSurfCol.IsNull() || !aRenderCol.IsNull())
+          if (!aSurfCol.IsNull() || aRenderProps.IsDefined())
             theCTool->SetColor(aL, aFullSCol, XCAFDoc_ColorSurf);
           if (!aBoundCol.IsNull())
             theCTool->SetColor(aL, aBCol, XCAFDoc_ColorCurv);
@@ -1311,7 +1299,7 @@ static void SetStyle(const Handle(XSControl_WorkSession)&        theWS,
             TDF_Label aL1;
             if (theSTool->SearchUsingMap(it.Value(), aL1, Standard_False, Standard_True))
             {
-              if (!aSurfCol.IsNull() || !aRenderCol.IsNull())
+              if (!aSurfCol.IsNull() || aRenderProps.IsDefined())
                 theCTool->SetColor(aL1, aFullSCol, XCAFDoc_ColorSurf);
               if (!aBoundCol.IsNull())
                 theCTool->SetColor(aL1, aBCol, XCAFDoc_ColorCurv);
@@ -2012,11 +2000,11 @@ Standard_Boolean STEPCAFControl_Reader::ReadSHUOs(
       break;
     }
 
-    Handle(StepVisual_Colour) SurfCol, BoundCol, CurveCol, RenderCol;
-    Standard_Real             RenderTransp;
+    Handle(StepVisual_Colour) SurfCol, BoundCol, CurveCol;
     // check if it is component style
-    Standard_Boolean IsComponent = Standard_False;
-    if (!Styles.GetColors(style, SurfCol, BoundCol, CurveCol, RenderCol, RenderTransp, IsComponent)
+    Standard_Boolean                  IsComponent = Standard_False;
+    STEPConstruct_RenderingProperties aRenderProps;
+    if (!Styles.GetColors(style, SurfCol, BoundCol, CurveCol, aRenderProps, IsComponent)
         && IsVisible)
       continue;
     if (!IsComponent)
@@ -2056,7 +2044,7 @@ Standard_Boolean STEPCAFControl_Reader::ReadSHUOs(
         continue;
       }
       // now set the style to the SHUO main label.
-      if (!SurfCol.IsNull() || !RenderCol.IsNull())
+      if (!SurfCol.IsNull() || aRenderProps.IsDefined())
       {
         Quantity_Color     col;
         Quantity_ColorRGBA colRGBA;
@@ -2065,10 +2053,9 @@ Standard_Boolean STEPCAFControl_Reader::ReadSHUOs(
           Styles.DecodeColor(SurfCol, col);
           colRGBA = Quantity_ColorRGBA(col);
         }
-        if (!RenderCol.IsNull())
+        if (aRenderProps.IsDefined())
         {
-          Styles.DecodeColor(RenderCol, col);
-          colRGBA = Quantity_ColorRGBA(col, static_cast<float>(1.0 - RenderTransp));
+          colRGBA = aRenderProps.GetRGBAColor();
         }
         CTool->SetColor(aLabelForStyle, colRGBA, XCAFDoc_ColorSurf);
       }
index 731641409616bb60daaab8c05fe5c23cc188135a..f8b9a0455c7edbcfe2a16e925a62641df5e006bc 100644 (file)
@@ -250,6 +250,7 @@ STEPCAFControl_Writer::STEPCAFControl_Writer()
       mySHUOMode(Standard_True),
       myGDTMode(Standard_True),
       myMatMode(Standard_True),
+      myVisMatMode(Standard_False),
       myIsCleanDuplicates(Standard_False)
 {
   STEPCAFControl_Controller::Init();
@@ -268,6 +269,7 @@ STEPCAFControl_Writer::STEPCAFControl_Writer(const Handle(XSControl_WorkSession)
       mySHUOMode(Standard_True),
       myGDTMode(Standard_True),
       myMatMode(Standard_True),
+      myVisMatMode(Standard_False),
       myIsCleanDuplicates(Standard_False)
 {
   STEPCAFControl_Controller::Init();
@@ -1192,8 +1194,9 @@ static void MakeSTEPStyles(STEPConstruct_Styles&                        theStyle
                            STEPConstruct_DataMapOfAsciiStringTransient& theDPDCs,
                            STEPConstruct_DataMapOfPointTransient&       theColRGBs,
                            const Handle(XCAFDoc_ShapeTool)&             theShTool,
-                           const XCAFPrs_Style*                         theInherit = 0,
-                           const Standard_Boolean theIsComponent                   = Standard_False)
+                           const XCAFPrs_Style*                         theInherit,
+                           const Standard_Boolean                       theIsComponent,
+                           const Standard_Boolean                       theVisMaterialMode)
 {
   // skip already processed shapes
   if (!theMap.Add(theShape))
@@ -1212,6 +1215,8 @@ static void MakeSTEPStyles(STEPConstruct_Styles&                        theStyle
       aStyle.SetColorCurv(anOwnStyle.GetColorCurv());
     if (anOwnStyle.IsSetColorSurf())
       aStyle.SetColorSurf(anOwnStyle.GetColorSurfRGBA());
+    if (!anOwnStyle.Material().IsNull())
+      aStyle.SetMaterial(anOwnStyle.Material());
   }
 
   // translate colors to STEP
@@ -1251,22 +1256,31 @@ static void MakeSTEPStyles(STEPConstruct_Styles&                        theStyle
         const Handle(StepRepr_RepresentationItem)& anItem =
           Handle(StepRepr_RepresentationItem)::DownCast(anEntIter.Value());
         Handle(StepVisual_PresentationStyleAssignment) aPSA;
-        if (aStyle.IsVisible() || !aSurfColor.IsNull() || !aCurvColor.IsNull())
+        if (aStyle.IsVisible() || !aSurfColor.IsNull() || !aCurvColor.IsNull()
+            || (theVisMaterialMode && !aStyle.Material().IsNull() && !aStyle.Material()->IsEmpty()))
         {
-          aPSA = theStyles.MakeColorPSA(anItem,
-                                        aSurfColor,
-                                        aCurvColor,
-                                        aSurfColor,
-                                        aRenderTransp,
-                                        theIsComponent);
+          STEPConstruct_RenderingProperties aRenderProps;
+          if (theVisMaterialMode && !aStyle.Material().IsNull() && !aStyle.Material()->IsEmpty())
+          {
+            aRenderProps.Init(aStyle.Material());
+          }
+          else if (aRenderTransp > 0.0)
+          {
+            aRenderProps.Init(aStyle.GetColorSurfRGBA());
+          }
+          aPSA =
+            theStyles.MakeColorPSA(anItem, aSurfColor, aCurvColor, aRenderProps, theIsComponent);
         }
         else
         {
           // default white color
           aSurfColor =
             theStyles.EncodeColor(Quantity_Color(Quantity_NOC_WHITE), theDPDCs, theColRGBs);
-          aPSA =
-            theStyles.MakeColorPSA(anItem, aSurfColor, aCurvColor, aSurfColor, 0.0, theIsComponent);
+          aPSA = theStyles.MakeColorPSA(anItem,
+                                        aSurfColor,
+                                        aCurvColor,
+                                        STEPConstruct_RenderingProperties(),
+                                        theIsComponent);
           if (theIsComponent)
             setDefaultInstanceColor(theOverride, aPSA);
 
@@ -1296,7 +1310,9 @@ static void MakeSTEPStyles(STEPConstruct_Styles&                        theStyle
                    theDPDCs,
                    theColRGBs,
                    theShTool,
-                   (aHasOwn ? &aStyle : 0));
+                   (aHasOwn ? &aStyle : 0),
+                   Standard_False,
+                   theVisMaterialMode);
   }
 }
 
@@ -1417,7 +1433,8 @@ Standard_Boolean STEPCAFControl_Writer::writeColors(const Handle(XSControl_WorkS
                    ColRGBs,
                    aSTool,
                    0,
-                   anIsComponent);
+                   anIsComponent,
+                   GetVisualMaterialMode());
 
     const Handle(XSControl_TransferWriter)& aTW = theWS->TransferWriter();
     const Handle(Transfer_FinderProcess)&   aFP = aTW->FinderProcess();
@@ -2019,8 +2036,13 @@ static Standard_Boolean createSHUOStyledItem(const XCAFPrs_Style& theStyle,
     aSurfColor        = aStyles.EncodeColor(Quantity_Color(Quantity_NOC_WHITE));
     isSetDefaultColor = Standard_True;
   }
+  STEPConstruct_RenderingProperties aRenderProps;
+  if (aRenderTransp > 0.0)
+  {
+    aRenderProps.Init(theStyle.GetColorSurfRGBA());
+  }
   Handle(StepVisual_PresentationStyleAssignment) aPSA =
-    aStyles.MakeColorPSA(anItem, aSurfColor, aCurvColor, aSurfColor, aRenderTransp, isComponent);
+    aStyles.MakeColorPSA(anItem, aSurfColor, aCurvColor, aRenderProps, isComponent);
   Handle(StepVisual_StyledItem) anOverride; // null styled item
 
   // find the repr item of the shape
@@ -4268,7 +4290,7 @@ Standard_Boolean STEPCAFControl_Writer::writeDGTsAP242(const Handle(XSControl_Wo
   Handle(StepRepr_RepresentationItem) anItem     = NULL;
   myGDTPrsCurveStyle->SetValue(
     1,
-    aStyles.MakeColorPSA(anItem, aCurvColor, aCurvColor, aCurvColor, 0.0));
+    aStyles.MakeColorPSA(anItem, aCurvColor, aCurvColor, STEPConstruct_RenderingProperties()));
   for (Interface_EntityIterator aModelIter = aModel->Entities();
        aModelIter.More() && myGDTCommonPDS.IsNull();
        aModelIter.Next())
index bd1f716a04f4b274d3e9d223a3f81cced04363ff..a32839b8ba2a14c558be59b806a5366dce0de74f 100644 (file)
@@ -221,11 +221,19 @@ public:
 
   Standard_Boolean GetDimTolMode() const { return myGDTMode; }
 
-  //! Set dimtolmode for indicate write D&GTs or not.
+  //! Set flag for indicate write material or not.
   void SetMaterialMode(const Standard_Boolean theMaterialMode) { myMatMode = theMaterialMode; }
 
   Standard_Boolean GetMaterialMode() const { return myMatMode; }
 
+  //! Set flag for indicate write visual material or not.
+  void SetVisualMaterialMode(const Standard_Boolean theVisualMaterialMode)
+  {
+    myVisMatMode = theVisualMaterialMode;
+  }
+
+  Standard_Boolean GetVisualMaterialMode() const { return myVisMatMode; }
+
   //! Set clean duplicates flag.
   //! If set to True, duplicates will be removed from the model.
   //! @param theCleanDuplicates the flag to set.
@@ -394,6 +402,7 @@ private:
   MoniTool_DataMapOfShapeTransient                                                myMapCompMDGPR;
   Standard_Boolean                                                                myGDTMode;
   Standard_Boolean                                                                myMatMode;
+  Standard_Boolean                                                                myVisMatMode;
   Standard_Boolean                                        myIsCleanDuplicates;
   NCollection_Vector<Handle(StepRepr_RepresentationItem)> myGDTAnnotations;
   Handle(StepVisual_DraughtingModel)                      myGDTPresentationDM;
index 81d45737e0d6ca87436c1a3fa73cb4e0417d719c..1dc6cf0e1227220f5b856b6ea43c8a6f87a54918 100644 (file)
@@ -18,6 +18,8 @@ set(OCCT_STEPConstruct_FILES
   STEPConstruct_ExternRefs.hxx
   STEPConstruct_Part.cxx
   STEPConstruct_Part.hxx
+  STEPConstruct_RenderingProperties.cxx
+  STEPConstruct_RenderingProperties.hxx
   STEPConstruct_Styles.cxx
   STEPConstruct_Styles.hxx
   STEPConstruct_Tool.cxx
diff --git a/src/DataExchange/TKDESTEP/STEPConstruct/STEPConstruct_RenderingProperties.cxx b/src/DataExchange/TKDESTEP/STEPConstruct/STEPConstruct_RenderingProperties.cxx
new file mode 100644 (file)
index 0000000..e56de2a
--- /dev/null
@@ -0,0 +1,736 @@
+// Copyright (c) 2025 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 <STEPConstruct_RenderingProperties.hxx>
+
+#include <STEPConstruct_Styles.hxx>
+#include <StepVisual_SurfaceStyleRenderingWithProperties.hxx>
+#include <StepVisual_SurfaceStyleElementSelect.hxx>
+#include <StepVisual_SurfaceStyleTransparent.hxx>
+#include <StepVisual_RenderingPropertiesSelect.hxx>
+#include <StepVisual_HArray1OfRenderingPropertiesSelect.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx>
+#include <StepVisual_ColourRgb.hxx>
+#include <StepVisual_DraughtingPreDefinedColour.hxx>
+#include <StepVisual_PreDefinedItem.hxx>
+#include <TCollection_HAsciiString.hxx>
+#include <XCAFDoc_VisMaterialCommon.hxx>
+#include <XCAFDoc_VisMaterial.hxx>
+
+//=================================================================================================
+
+STEPConstruct_RenderingProperties::STEPConstruct_RenderingProperties()
+    : mySurfaceColor(Quantity_NOC_WHITE),
+      myTransparency(0.0),
+      myRenderingMethod(StepVisual_ssmNormalShading),
+      myIsDefined(Standard_False),
+      myAmbientReflectance(0.0, Standard_False),
+      myDiffuseReflectance(0.0, Standard_False),
+      mySpecularReflectance(0.0, Standard_False),
+      mySpecularExponent(0.0, Standard_False),
+      mySpecularColour(Quantity_NOC_WHITE, Standard_False)
+{
+}
+
+//=================================================================================================
+
+STEPConstruct_RenderingProperties::STEPConstruct_RenderingProperties(
+  const Handle(StepVisual_SurfaceStyleRenderingWithProperties)& theRenderingProperties)
+    : mySurfaceColor(Quantity_NOC_WHITE),
+      myTransparency(0.0),
+      myRenderingMethod(StepVisual_ssmNormalShading),
+      myIsDefined(Standard_False),
+      myAmbientReflectance(0.0, Standard_False),
+      myDiffuseReflectance(0.0, Standard_False),
+      mySpecularReflectance(0.0, Standard_False),
+      mySpecularExponent(0.0, Standard_False),
+      mySpecularColour(Quantity_NOC_WHITE, Standard_False)
+{
+  Init(theRenderingProperties);
+}
+
+//=================================================================================================
+
+STEPConstruct_RenderingProperties::STEPConstruct_RenderingProperties(
+  const Quantity_ColorRGBA& theRGBAColor)
+    : mySurfaceColor(Quantity_NOC_WHITE),
+      myTransparency(0.0),
+      myRenderingMethod(StepVisual_ssmNormalShading),
+      myIsDefined(Standard_False),
+      myAmbientReflectance(0.0, Standard_False),
+      myDiffuseReflectance(0.0, Standard_False),
+      mySpecularReflectance(0.0, Standard_False),
+      mySpecularExponent(0.0, Standard_False),
+      mySpecularColour(Quantity_NOC_WHITE, Standard_False)
+{
+  Init(theRGBAColor);
+}
+
+//=================================================================================================
+
+STEPConstruct_RenderingProperties::STEPConstruct_RenderingProperties(
+  const Handle(StepVisual_Colour)& theColor,
+  const Standard_Real              theTransparency)
+    : mySurfaceColor(Quantity_NOC_WHITE),
+      myTransparency(0.0),
+      myRenderingMethod(StepVisual_ssmNormalShading),
+      myIsDefined(Standard_False),
+      myAmbientReflectance(0.0, Standard_False),
+      myDiffuseReflectance(0.0, Standard_False),
+      mySpecularReflectance(0.0, Standard_False),
+      mySpecularExponent(0.0, Standard_False),
+      mySpecularColour(Quantity_NOC_WHITE, Standard_False)
+{
+  Init(theColor, theTransparency);
+}
+
+//=================================================================================================
+
+STEPConstruct_RenderingProperties::STEPConstruct_RenderingProperties(
+  const XCAFDoc_VisMaterialCommon& theMaterial)
+    : mySurfaceColor(Quantity_NOC_WHITE),
+      myTransparency(0.0),
+      myRenderingMethod(StepVisual_ssmNormalShading),
+      myIsDefined(Standard_False),
+      myAmbientReflectance(0.0, Standard_False),
+      myDiffuseReflectance(0.0, Standard_False),
+      mySpecularReflectance(0.0, Standard_False),
+      mySpecularExponent(0.0, Standard_False),
+      mySpecularColour(Quantity_NOC_WHITE, Standard_False)
+{
+  Init(theMaterial);
+}
+
+//=================================================================================================
+
+STEPConstruct_RenderingProperties::STEPConstruct_RenderingProperties(
+  const Handle(XCAFDoc_VisMaterial)& theMaterial)
+    : mySurfaceColor(Quantity_NOC_WHITE),
+      myTransparency(0.0),
+      myRenderingMethod(StepVisual_ssmNormalShading),
+      myIsDefined(Standard_False),
+      myAmbientReflectance(0.0, Standard_False),
+      myDiffuseReflectance(0.0, Standard_False),
+      mySpecularReflectance(0.0, Standard_False),
+      mySpecularExponent(0.0, Standard_False),
+      mySpecularColour(Quantity_NOC_WHITE, Standard_False)
+{
+  Init(theMaterial);
+}
+
+//=================================================================================================
+
+STEPConstruct_RenderingProperties::STEPConstruct_RenderingProperties(
+  const Quantity_Color& theSurfaceColor,
+  const Standard_Real   theTransparency)
+    : mySurfaceColor(Quantity_NOC_WHITE),
+      myTransparency(0.0),
+      myRenderingMethod(StepVisual_ssmNormalShading),
+      myIsDefined(Standard_False),
+      myAmbientReflectance(0.0, Standard_False),
+      myDiffuseReflectance(0.0, Standard_False),
+      mySpecularReflectance(0.0, Standard_False),
+      mySpecularExponent(0.0, Standard_False),
+      mySpecularColour(Quantity_NOC_WHITE, Standard_False)
+{
+  Init(theSurfaceColor, theTransparency);
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::SetAmbientReflectance(
+  const Standard_Real theAmbientReflectance)
+{
+  myAmbientReflectance.first  = theAmbientReflectance;
+  myAmbientReflectance.second = Standard_True;
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::SetAmbientAndDiffuseReflectance(
+  const Standard_Real theAmbientReflectance,
+  const Standard_Real theDiffuseReflectance)
+{
+  myAmbientReflectance.first  = theAmbientReflectance;
+  myAmbientReflectance.second = Standard_True;
+  myDiffuseReflectance.first  = theDiffuseReflectance;
+  myDiffuseReflectance.second = Standard_True;
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::SetAmbientDiffuseAndSpecularReflectance(
+  const Standard_Real   theAmbientReflectance,
+  const Standard_Real   theDiffuseReflectance,
+  const Standard_Real   theSpecularReflectance,
+  const Standard_Real   theSpecularExponent,
+  const Quantity_Color& theSpecularColour)
+{
+  myAmbientReflectance.first   = theAmbientReflectance;
+  myAmbientReflectance.second  = Standard_True;
+  myDiffuseReflectance.first   = theDiffuseReflectance;
+  myDiffuseReflectance.second  = Standard_True;
+  mySpecularReflectance.first  = theSpecularReflectance;
+  mySpecularReflectance.second = Standard_True;
+  mySpecularExponent.first     = theSpecularExponent;
+  mySpecularExponent.second    = Standard_True;
+  mySpecularColour.first       = theSpecularColour;
+  mySpecularColour.second      = Standard_True;
+}
+
+//=================================================================================================
+
+Handle(StepVisual_SurfaceStyleRenderingWithProperties) STEPConstruct_RenderingProperties::
+  CreateRenderingProperties() const
+{
+  return CreateRenderingProperties(STEPConstruct_Styles::EncodeColor(mySurfaceColor));
+}
+
+//=================================================================================================
+
+Handle(StepVisual_SurfaceStyleRenderingWithProperties) STEPConstruct_RenderingProperties::
+  CreateRenderingProperties(const Handle(StepVisual_Colour)& theRenderColour) const
+{
+  if (!myIsDefined)
+  {
+    return nullptr;
+  }
+
+  // Create STEP RGB color or use predefined color using STEPConstruct_Styles utility
+  Handle(StepVisual_Colour) aStepColor =
+    !theRenderColour.IsNull() ? theRenderColour : STEPConstruct_Styles::EncodeColor(mySurfaceColor);
+
+  // Count and determine which properties to create.
+  // Transparency is always included.
+  Standard_Integer aNbProps = 1;
+
+  // Determine which reflectance properties to include
+  const Standard_Boolean hasFullReflectance =
+    (mySpecularColour.second && mySpecularExponent.second && mySpecularReflectance.second
+     && myDiffuseReflectance.second && myAmbientReflectance.second);
+  const Standard_Boolean hasDiffuseAndAmbient =
+    (myDiffuseReflectance.second && myAmbientReflectance.second && !mySpecularReflectance.second);
+  const Standard_Boolean hasAmbientOnly =
+    (myAmbientReflectance.second && !myDiffuseReflectance.second && !mySpecularReflectance.second);
+
+  // Add reflectance property if we have any defined
+  if (hasFullReflectance || hasDiffuseAndAmbient || hasAmbientOnly)
+  {
+    aNbProps++;
+  }
+
+  // Create properties array
+  Handle(StepVisual_HArray1OfRenderingPropertiesSelect) aProps =
+    new StepVisual_HArray1OfRenderingPropertiesSelect(1, aNbProps);
+  Standard_Integer aPropIndex = 1;
+
+  // Add transparency
+  Handle(StepVisual_SurfaceStyleTransparent) aTransparent = new StepVisual_SurfaceStyleTransparent;
+  aTransparent->Init(myTransparency);
+
+  StepVisual_RenderingPropertiesSelect aRPS;
+  aRPS.SetValue(aTransparent);
+  aProps->SetValue(aPropIndex++, aRPS);
+
+  // Add the appropriate reflectance model based on what we have
+  if (hasAmbientOnly)
+  {
+    // Add ambient reflectance only
+    Handle(StepVisual_SurfaceStyleReflectanceAmbient) aAmbient =
+      new StepVisual_SurfaceStyleReflectanceAmbient;
+    aAmbient->Init(myAmbientReflectance.first);
+
+    StepVisual_RenderingPropertiesSelect aRPS;
+    aRPS.SetValue(aAmbient);
+    aProps->SetValue(aPropIndex++, aRPS);
+  }
+  else if (hasDiffuseAndAmbient)
+  {
+    // Add ambient and diffuse reflectance
+    Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse) aAmbientDiffuse =
+      new StepVisual_SurfaceStyleReflectanceAmbientDiffuse;
+    aAmbientDiffuse->Init(myAmbientReflectance.first, myDiffuseReflectance.first);
+
+    StepVisual_RenderingPropertiesSelect aRPS;
+    aRPS.SetValue(aAmbientDiffuse);
+    aProps->SetValue(aPropIndex++, aRPS);
+  }
+  else if (hasFullReflectance)
+  {
+    // Add full PBR reflectance model (ambient, diffuse, specular)
+    Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular) aFullRefl =
+      new StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular;
+
+    aFullRefl->Init(myAmbientReflectance.first,
+                    myDiffuseReflectance.first,
+                    mySpecularReflectance.first,
+                    mySpecularExponent.first,
+                    STEPConstruct_Styles::EncodeColor(mySpecularColour.first));
+
+    StepVisual_RenderingPropertiesSelect aRPS;
+    aRPS.SetValue(aFullRefl);
+    aProps->SetValue(aPropIndex++, aRPS);
+  }
+
+  // Create STEP surface style rendering with properties
+  Handle(StepVisual_SurfaceStyleRenderingWithProperties) aSSRWP =
+    new StepVisual_SurfaceStyleRenderingWithProperties;
+  aSSRWP->Init(myRenderingMethod, aStepColor, aProps);
+  return aSSRWP;
+}
+
+//=================================================================================================
+
+XCAFDoc_VisMaterialCommon STEPConstruct_RenderingProperties::CreateXCAFMaterial() const
+{
+  if (!myIsDefined)
+  {
+    XCAFDoc_VisMaterialCommon aMaterial;
+    aMaterial.IsDefined = Standard_False;
+    return aMaterial;
+  }
+
+  XCAFDoc_VisMaterialCommon aMaterial;
+
+  // Use surface color as the base diffuse color
+  aMaterial.DiffuseColor = mySurfaceColor;
+  aMaterial.Transparency = myTransparency;
+  aMaterial.IsDefined    = Standard_True;
+
+  // Set default values for other properties
+  aMaterial.AmbientColor  = Quantity_Color(0.1, 0.1, 0.1, Quantity_TOC_RGB);
+  aMaterial.SpecularColor = Quantity_Color(0.2, 0.2, 0.2, Quantity_TOC_RGB);
+  aMaterial.EmissiveColor = Quantity_Color(0.0, 0.0, 0.0, Quantity_TOC_RGB);
+  aMaterial.Shininess     = 1.0f;
+
+  // Handle ambient reflectance - apply factor to diffuse color
+  if (myAmbientReflectance.second)
+  {
+    // Get the reflectance factor, clamped to valid range
+    const Standard_Real aAmbientFactor = Max(0.0, Min(1.0, myAmbientReflectance.first));
+
+    // Apply factor to surface color (RGB components individually)
+    const Standard_Real aRed   = mySurfaceColor.Red() * aAmbientFactor;
+    const Standard_Real aGreen = mySurfaceColor.Green() * aAmbientFactor;
+    const Standard_Real aBlue  = mySurfaceColor.Blue() * aAmbientFactor;
+
+    Quantity_Color aAmbientColor(aRed, aGreen, aBlue, Quantity_TOC_RGB);
+    aMaterial.AmbientColor = aAmbientColor;
+  }
+
+  // Handle specular properties - apply factor to diffuse color or use explicit color
+  if (mySpecularColour.second)
+  {
+    // Use explicitly defined specular color
+    aMaterial.SpecularColor = mySpecularColour.first;
+  }
+  else if (mySpecularReflectance.second)
+  {
+    // Apply specular reflectance factor to surface color
+    const Standard_Real aSpecularFactor = Max(0.0, Min(1.0, mySpecularReflectance.first));
+
+    const Standard_Real aRed   = mySurfaceColor.Red() * aSpecularFactor;
+    const Standard_Real aGreen = mySurfaceColor.Green() * aSpecularFactor;
+    const Standard_Real aBlue  = mySurfaceColor.Blue() * aSpecularFactor;
+
+    Quantity_Color aSpecularColor(aRed, aGreen, aBlue, Quantity_TOC_RGB);
+    aMaterial.SpecularColor = aSpecularColor;
+  }
+
+  // Handle shininess (specular exponent)
+  if (mySpecularExponent.second)
+  {
+    // Convert STEP specular exponent to XCAF shininess using fixed scale factor
+    const Standard_Real kScaleFactor = 128.0;
+    const Standard_Real aShininess   = mySpecularExponent.first / kScaleFactor;
+    aMaterial.Shininess              = (Standard_ShortReal)Min(1.0, aShininess);
+  }
+
+  return aMaterial;
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::Init(
+  const Handle(StepVisual_SurfaceStyleRenderingWithProperties)& theRenderingProperties)
+{
+  mySurfaceColor        = Quantity_NOC_WHITE;
+  myTransparency        = 0.0;
+  myRenderingMethod     = StepVisual_ssmNormalShading;
+  myIsDefined           = Standard_False;
+  myAmbientReflectance  = std::make_pair(0.0, Standard_False);
+  myDiffuseReflectance  = std::make_pair(0.0, Standard_False);
+  mySpecularReflectance = std::make_pair(0.0, Standard_False);
+  mySpecularExponent    = std::make_pair(0.0, Standard_False);
+  mySpecularColour      = std::make_pair(Quantity_NOC_WHITE, Standard_False);
+
+  if (theRenderingProperties.IsNull())
+  {
+    return;
+  }
+
+  myRenderingMethod                = theRenderingProperties->RenderingMethod();
+  Handle(StepVisual_Colour) aColor = theRenderingProperties->SurfaceColour();
+
+  // Decode surface color using STEPConstruct_Styles utility
+  if (!aColor.IsNull())
+  {
+    Quantity_Color aDecodedColor;
+    if (STEPConstruct_Styles::DecodeColor(aColor, aDecodedColor))
+    {
+      mySurfaceColor = aDecodedColor;
+      myIsDefined    = Standard_True;
+    }
+  }
+
+  // Process rendering properties
+  Handle(StepVisual_HArray1OfRenderingPropertiesSelect) aProperties =
+    theRenderingProperties->Properties();
+  if (!aProperties.IsNull())
+  {
+    for (Standard_Integer i = 1; i <= aProperties->Length(); i++)
+    {
+      StepVisual_RenderingPropertiesSelect aPropSelect = aProperties->Value(i);
+
+      // Check for transparency
+      Handle(StepVisual_SurfaceStyleTransparent) aTransparent =
+        aPropSelect.SurfaceStyleTransparent();
+      if (!aTransparent.IsNull())
+      {
+        myTransparency = aTransparent->Transparency();
+        myIsDefined    = Standard_True;
+      }
+
+      // Check for ambient reflectance
+      Handle(StepVisual_SurfaceStyleReflectanceAmbient) aAmbient =
+        aPropSelect.SurfaceStyleReflectanceAmbient();
+      Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse) aAmbientDiffuse =
+        Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuse)::DownCast(aAmbient);
+      Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular) aFullRefl =
+        Handle(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular)::DownCast(aAmbient);
+      if (!aFullRefl.IsNull())
+      {
+        myIsDefined                  = Standard_True;
+        myAmbientReflectance.first   = aFullRefl->AmbientReflectance();
+        myDiffuseReflectance.first   = aFullRefl->DiffuseReflectance();
+        mySpecularReflectance.first  = aFullRefl->SpecularReflectance();
+        mySpecularExponent.first     = aFullRefl->SpecularExponent();
+        myAmbientReflectance.second  = Standard_True;
+        myDiffuseReflectance.second  = Standard_True;
+        mySpecularReflectance.second = Standard_True;
+        mySpecularExponent.second    = Standard_True;
+        mySpecularColour.second =
+          STEPConstruct_Styles::DecodeColor(aFullRefl->SpecularColour(), mySpecularColour.first);
+      }
+      else if (!aAmbientDiffuse.IsNull())
+      {
+        myAmbientReflectance.first  = aAmbientDiffuse->AmbientReflectance();
+        myAmbientReflectance.second = Standard_True;
+        myDiffuseReflectance.first  = aAmbientDiffuse->DiffuseReflectance();
+        myDiffuseReflectance.second = Standard_True;
+        myIsDefined                 = Standard_True;
+      }
+      else if (!aAmbient.IsNull())
+      {
+        myAmbientReflectance.first  = aAmbient->AmbientReflectance();
+        myAmbientReflectance.second = Standard_True;
+        myIsDefined                 = Standard_True;
+      }
+    }
+  }
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::Init(const Quantity_ColorRGBA& theRGBAColor)
+{
+  mySurfaceColor        = theRGBAColor.GetRGB();
+  myTransparency        = 1.0 - theRGBAColor.Alpha();
+  myRenderingMethod     = StepVisual_ssmNormalShading;
+  myIsDefined           = Standard_True;
+  myAmbientReflectance  = std::make_pair(0.0, Standard_False);
+  myDiffuseReflectance  = std::make_pair(0.0, Standard_False);
+  mySpecularReflectance = std::make_pair(0.0, Standard_False);
+  mySpecularExponent    = std::make_pair(0.0, Standard_False);
+  mySpecularColour      = std::make_pair(Quantity_NOC_WHITE, Standard_False);
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::Init(const Handle(StepVisual_Colour)& theColor,
+                                             const Standard_Real              theTransparency)
+{
+  mySurfaceColor        = Quantity_NOC_WHITE;
+  myTransparency        = theTransparency;
+  myRenderingMethod     = StepVisual_ssmNormalShading;
+  myIsDefined           = Standard_False;
+  myAmbientReflectance  = std::make_pair(0.0, Standard_False);
+  myDiffuseReflectance  = std::make_pair(0.0, Standard_False);
+  mySpecularReflectance = std::make_pair(0.0, Standard_False);
+  mySpecularExponent    = std::make_pair(0.0, Standard_False);
+  mySpecularColour      = std::make_pair(Quantity_NOC_WHITE, Standard_False);
+
+  if (theColor.IsNull())
+  {
+    return;
+  }
+
+  // Decode color using STEPConstruct_Styles utility
+  Quantity_Color aDecodedColor;
+  if (STEPConstruct_Styles::DecodeColor(theColor, aDecodedColor))
+  {
+    mySurfaceColor = aDecodedColor;
+    myIsDefined    = Standard_True;
+  }
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::Init(const XCAFDoc_VisMaterialCommon& theMaterial)
+{
+  if (!theMaterial.IsDefined)
+  {
+    mySurfaceColor = Quantity_NOC_WHITE;
+    myTransparency = 0.0;
+    myIsDefined    = Standard_False;
+    return;
+  }
+
+  // Basic properties - use diffuse color as the base surface color
+  mySurfaceColor    = theMaterial.DiffuseColor;
+  myTransparency    = theMaterial.Transparency;
+  myRenderingMethod = StepVisual_ssmNormalShading;
+  myIsDefined       = Standard_True;
+
+  // Reset reflectance properties
+  myAmbientReflectance  = std::make_pair(0.0, Standard_False);
+  myDiffuseReflectance  = std::make_pair(0.0, Standard_False);
+  mySpecularReflectance = std::make_pair(0.0, Standard_False);
+  mySpecularExponent    = std::make_pair(0.0, Standard_False);
+  mySpecularColour      = std::make_pair(Quantity_NOC_WHITE, Standard_False);
+
+  // Extract RGB components from diffuse color
+  const Standard_Real aDiffRed   = theMaterial.DiffuseColor.Red();
+  const Standard_Real aDiffGreen = theMaterial.DiffuseColor.Green();
+  const Standard_Real aDiffBlue  = theMaterial.DiffuseColor.Blue();
+
+  // Find maximum diffuse component to avoid division by zero for dark colors
+  const Standard_Real aDiffMax = Max(aDiffRed, Max(aDiffGreen, aDiffBlue));
+
+  // Check if ambient color is non-default and diffuse color has non-zero components
+  if (aDiffMax > Precision::Confusion())
+  {
+    // Extract RGB components from ambient color
+    Standard_Real aAmbRed   = theMaterial.AmbientColor.Red();
+    Standard_Real aAmbGreen = theMaterial.AmbientColor.Green();
+    Standard_Real aAmbBlue  = theMaterial.AmbientColor.Blue();
+
+    // Calculate per-channel ratios
+    const Standard_Real aRed = (aDiffRed > Precision::Confusion()) ? aAmbRed / aDiffRed : 0.0;
+    const Standard_Real aGreen =
+      (aDiffGreen > Precision::Confusion()) ? aAmbGreen / aDiffGreen : 0.0;
+    const Standard_Real aBlue = (aDiffBlue > Precision::Confusion()) ? aAmbBlue / aDiffBlue : 0.0;
+
+    // Calculate min and max of RGB ratios
+    const Standard_Real aMin = Min(aRed, Min(aGreen, aBlue));
+    const Standard_Real aMax = Max(aRed, Max(aGreen, aBlue));
+
+    // If ratios are reasonably close, use average as ambient reflectance factor
+    // otherwise the ambient color isn't a simple multiplier of diffuse
+    const Standard_Real kMaxRatioDeviation = 0.2; // Max allowed deviation between RGB ratios
+    if ((aMax - aMin) < kMaxRatioDeviation)
+    {
+      // Use average of RGB ratios as the reflectance factor
+      Standard_Real aAmbientFactor = (aRed + aGreen + aBlue) / 3.0;
+
+      // Check if factor is significantly different from default (0.1)
+      if (Abs(aAmbientFactor - 0.1) > 0.01)
+      {
+        // Clamp to valid range
+        aAmbientFactor = Max(0.0, Min(1.0, aAmbientFactor));
+
+        myAmbientReflectance.first  = aAmbientFactor;
+        myAmbientReflectance.second = Standard_True;
+      }
+    }
+  }
+
+  // Diffuse reflectance is always 1.0 for the main color
+  myDiffuseReflectance.first  = 1.0;
+  myDiffuseReflectance.second = Standard_True;
+
+  // Calculate specular reflectance factor relative to diffuse color
+  // Compare specular color to diffuse color directly to get reflectance factor
+  if (aDiffMax > Precision::Confusion())
+  {
+    // Extract RGB components from specular color
+    const Standard_Real aSpecRed   = theMaterial.SpecularColor.Red();
+    const Standard_Real aSpecGreen = theMaterial.SpecularColor.Green();
+    const Standard_Real aSpecBlue  = theMaterial.SpecularColor.Blue();
+
+    // Calculate per-channel ratios
+    const Standard_Real aRed = (aDiffRed > Precision::Confusion()) ? aSpecRed / aDiffRed : 0.0;
+    const Standard_Real aGreen =
+      (aDiffGreen > Precision::Confusion()) ? aSpecGreen / aDiffGreen : 0.0;
+    const Standard_Real aBlue = (aDiffBlue > Precision::Confusion()) ? aSpecBlue / aDiffBlue : 0.0;
+
+    // Calculate min and max of RGB ratios
+    const Standard_Real aMin = Min(aRed, Min(aGreen, aBlue));
+    const Standard_Real aMax = Max(aRed, Max(aGreen, aBlue));
+
+    // If ratios are reasonably close, use average as specular reflectance factor
+    const Standard_Real kMaxRatioDeviation = 0.2; // Max allowed deviation between RGB ratios
+    if ((aMax - aMin) < kMaxRatioDeviation)
+    {
+      // Use average of RGB ratios as the reflectance factor
+      Standard_Real aSpecularFactor = (aRed + aGreen + aBlue) / 3.0;
+
+      // Check if factor is significantly different from default (0.2)
+      if (Abs(aSpecularFactor - 0.2) > 0.01)
+      {
+        // Clamp to valid range
+        aSpecularFactor = Max(0.0, Min(1.0, aSpecularFactor));
+
+        mySpecularReflectance.first  = aSpecularFactor;
+        mySpecularReflectance.second = Standard_True;
+      }
+    }
+    else
+    {
+      // Ratios differ significantly, specular color isn't a simple multiplier of diffuse
+      // Store actual specular color
+      mySpecularColour.first  = theMaterial.SpecularColor;
+      mySpecularColour.second = Standard_True;
+
+      // Still compute an average reflectance factor for formats that don't support color
+      Standard_Real aSpecularFactor = (aSpecRed + aSpecGreen + aSpecBlue) / 3.0;
+      mySpecularReflectance.first   = aSpecularFactor;
+      mySpecularReflectance.second  = Standard_True;
+    }
+  }
+
+  // Convert shininess to specular exponent using fixed scale factor
+  if (theMaterial.Shininess >= 0.0f && Abs(theMaterial.Shininess - 1.0f) > 0.01f)
+  {
+    const Standard_Real kScaleFactor = 128.0;
+    mySpecularExponent.first         = theMaterial.Shininess * kScaleFactor;
+    mySpecularExponent.second        = Standard_True;
+  }
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::Init(const Handle(XCAFDoc_VisMaterial)& theMaterial)
+{
+  if (theMaterial.IsNull())
+  {
+    return;
+  }
+
+  // Use the material to initialize rendering properties
+  Init(theMaterial->ConvertToCommonMaterial());
+}
+
+//=================================================================================================
+
+void STEPConstruct_RenderingProperties::Init(const Quantity_Color& theSurfaceColor,
+                                             const Standard_Real   theTransparency)
+{
+  mySurfaceColor        = theSurfaceColor;
+  myTransparency        = theTransparency;
+  myRenderingMethod     = StepVisual_ssmNormalShading;
+  myIsDefined           = Standard_True;
+  myAmbientReflectance  = std::make_pair(0.0, Standard_False);
+  myDiffuseReflectance  = std::make_pair(0.0, Standard_False);
+  mySpecularReflectance = std::make_pair(0.0, Standard_False);
+  mySpecularExponent    = std::make_pair(0.0, Standard_False);
+  mySpecularColour      = std::make_pair(Quantity_NOC_WHITE, Standard_False);
+}
+
+//=================================================================================================
+
+Standard_Boolean STEPConstruct_RenderingProperties::IsMaterialConvertible() const
+{
+  return myIsDefined && myAmbientReflectance.second && myDiffuseReflectance.second
+         && mySpecularReflectance.second && mySpecularExponent.second && mySpecularColour.second;
+}
+
+//=================================================================================================
+
+Standard_Real STEPConstruct_RenderingProperties::AmbientReflectance() const
+{
+  return myAmbientReflectance.first;
+}
+
+//=================================================================================================
+
+Standard_Boolean STEPConstruct_RenderingProperties::IsAmbientReflectanceDefined() const
+{
+  return myAmbientReflectance.second;
+}
+
+//=================================================================================================
+
+Standard_Real STEPConstruct_RenderingProperties::DiffuseReflectance() const
+{
+  return myDiffuseReflectance.first;
+}
+
+//=================================================================================================
+
+Standard_Boolean STEPConstruct_RenderingProperties::IsDiffuseReflectanceDefined() const
+{
+  return myDiffuseReflectance.second;
+}
+
+//=================================================================================================
+
+Standard_Real STEPConstruct_RenderingProperties::SpecularReflectance() const
+{
+  return mySpecularReflectance.first;
+}
+
+//=================================================================================================
+
+Standard_Boolean STEPConstruct_RenderingProperties::IsSpecularReflectanceDefined() const
+{
+  return mySpecularReflectance.second;
+}
+
+//=================================================================================================
+
+Standard_Real STEPConstruct_RenderingProperties::SpecularExponent() const
+{
+  return mySpecularExponent.first;
+}
+
+//=================================================================================================
+
+Standard_Boolean STEPConstruct_RenderingProperties::IsSpecularExponentDefined() const
+{
+  return mySpecularExponent.second;
+}
+
+//=================================================================================================
+
+Quantity_Color STEPConstruct_RenderingProperties::SpecularColour() const
+{
+  return mySpecularColour.first;
+}
+
+//=================================================================================================
+
+Standard_Boolean STEPConstruct_RenderingProperties::IsSpecularColourDefined() const
+{
+  return mySpecularColour.second;
+}
diff --git a/src/DataExchange/TKDESTEP/STEPConstruct/STEPConstruct_RenderingProperties.hxx b/src/DataExchange/TKDESTEP/STEPConstruct/STEPConstruct_RenderingProperties.hxx
new file mode 100644 (file)
index 0000000..79e9ad6
--- /dev/null
@@ -0,0 +1,235 @@
+// Copyright (c) 2025 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.
+
+#ifndef STEPConstruct_RenderingProperties_HeaderFile
+#define STEPConstruct_RenderingProperties_HeaderFile
+
+#include <Quantity_Color.hxx>
+#include <Quantity_ColorRGBA.hxx>
+#include <StepVisual_ShadingSurfaceMethod.hxx>
+#include <StepVisual_SurfaceStyleRenderingWithProperties.hxx>
+#include <XCAFDoc_VisMaterialCommon.hxx>
+
+#include <utility>
+
+class StepVisual_SurfaceStyleRenderingWithProperties;
+class StepVisual_Colour;
+class XCAFDoc_VisMaterial;
+
+//! Class for working with STEP rendering properties.
+//! Provides functionality to create and manipulate rendering properties
+//! used for specifying visual appearance in STEP format.
+//! This class handles both parsing of STEP entities and creation of new ones.
+class STEPConstruct_RenderingProperties
+{
+public:
+  DEFINE_STANDARD_ALLOC
+public:
+  //! Default constructor creating an empty rendering properties object
+  Standard_EXPORT STEPConstruct_RenderingProperties();
+
+  //! Constructor from STEP rendering properties entity.
+  //! Extracts color, transparency, and other properties from the STEP entity.
+  //! @param[in] theRenderingProperties rendering properties entity
+  Standard_EXPORT STEPConstruct_RenderingProperties(
+    const Handle(StepVisual_SurfaceStyleRenderingWithProperties)& theRenderingProperties);
+
+  //! Constructor from RGBA color.
+  //! Creates rendering properties with the given color and transparency.
+  //! @param[in] theRGBAColor color with transparency
+  Standard_EXPORT STEPConstruct_RenderingProperties(const Quantity_ColorRGBA& theRGBAColor);
+
+  //! Constructor from STEP color and transparency value.
+  //! Creates rendering properties with the given color and transparency.
+  //! @param[in] theColor color
+  //! @param[in] theTransparency transparency value
+  Standard_EXPORT STEPConstruct_RenderingProperties(const Handle(StepVisual_Colour)& theColor,
+                                                    const Standard_Real theTransparency);
+
+  //! Constructor from XCAFDoc_VisMaterialCommon.
+  //! Creates rendering properties using material properties from the OCCT material.
+  //! @param[in] theMaterial common visualization material properties
+  Standard_EXPORT STEPConstruct_RenderingProperties(const XCAFDoc_VisMaterialCommon& theMaterial);
+
+  //! Constructor from XCAFDoc_VisMaterial.
+  //! Creates rendering properties using material properties from the OCCT material.
+  //! @param[in] theMaterial visualization material properties
+  Standard_EXPORT STEPConstruct_RenderingProperties(const Handle(XCAFDoc_VisMaterial)& theMaterial);
+
+  //! Constructor from surface color, transparency, and rendering method.
+  //! @param[in] theSurfaceColor surface color
+  //! @param[in] theTransparency transparency value
+  Standard_EXPORT STEPConstruct_RenderingProperties(const Quantity_Color& theSurfaceColor,
+                                                    const Standard_Real   theTransparency = 0.0);
+
+  //! Initializes from STEP rendering properties entity.
+  //! Extracts color, transparency, and other properties from the STEP entity.
+  //! @param[in] theRenderingProperties rendering properties entity
+  Standard_EXPORT void Init(
+    const Handle(StepVisual_SurfaceStyleRenderingWithProperties)& theRenderingProperties);
+
+  //! Initializes from RGBA color.
+  //! @param[in] theRGBAColor color with transparency
+  Standard_EXPORT void Init(const Quantity_ColorRGBA& theRGBAColor);
+
+  //! Initializes from STEP color and transparency value.
+  //! @param[in] theColor STEP color entity
+  //! @param[in] theTransparency transparency value
+  Standard_EXPORT void Init(const Handle(StepVisual_Colour)& theColor,
+                            const Standard_Real              theTransparency);
+
+  //! Initializes from XCAFDoc_VisMaterialCommon.
+  //! @param[in] theMaterial common visualization material properties
+  Standard_EXPORT void Init(const XCAFDoc_VisMaterialCommon& theMaterial);
+
+  //! Initializes from XCAFDoc_VisMaterial.
+  //! @param[in] theMaterial visualization material properties
+  Standard_EXPORT void Init(const Handle(XCAFDoc_VisMaterial)& theMaterial);
+
+  //! Initializes from surface color, transparency and rendering method.
+  //! @param[in] theSurfaceColor surface color
+  //! @param[in] theTransparency transparency value
+  Standard_EXPORT void Init(const Quantity_Color& theSurfaceColor,
+                            const Standard_Real   theTransparency = 0.0);
+
+  //! Sets ambient reflectance value
+  //! @param[in] theAmbientReflectance ambient reflectance value
+  Standard_EXPORT void SetAmbientReflectance(const Standard_Real theAmbientReflectance);
+
+  //! Sets ambient and diffuse reflectance values
+  //! @param[in] theAmbientReflectance ambient reflectance value
+  //! @param[in] theDiffuseReflectance diffuse reflectance value
+  Standard_EXPORT void SetAmbientAndDiffuseReflectance(const Standard_Real theAmbientReflectance,
+                                                       const Standard_Real theDiffuseReflectance);
+
+  //! Sets ambient, diffuse and specular reflectance values
+  //! @param[in] theAmbientReflectance ambient reflectance value
+  //! @param[in] theDiffuseReflectance diffuse reflectance value
+  //! @param[in] theSpecularReflectance specular reflectance value
+  //! @param[in] theSpecularExponent specular exponent value
+  //! @param[in] theSpecularColour specular color
+  Standard_EXPORT void SetAmbientDiffuseAndSpecularReflectance(
+    const Standard_Real   theAmbientReflectance,
+    const Standard_Real   theDiffuseReflectance,
+    const Standard_Real   theSpecularReflectance,
+    const Standard_Real   theSpecularExponent,
+    const Quantity_Color& theSpecularColour);
+
+  //! Creates and returns rendering properties entity
+  //! @return created rendering properties entity
+  Standard_EXPORT Handle(StepVisual_SurfaceStyleRenderingWithProperties) CreateRenderingProperties()
+    const;
+
+  // Creates and returns rendering properties entity with the specified color
+  //! @param[in] theRenderColour color to be used for rendering
+  //! @return created rendering properties entity
+  Standard_EXPORT Handle(StepVisual_SurfaceStyleRenderingWithProperties) CreateRenderingProperties(
+    const Handle(StepVisual_Colour)& theRenderColour) const;
+
+  //! Creates and returns XCAF material entity
+  //! @return created XCAF material entity
+  Standard_EXPORT XCAFDoc_VisMaterialCommon CreateXCAFMaterial() const;
+
+  //! Creates the ColorRGBA object from the current color and transparency
+  //! @return ColorRGBA object
+  Quantity_ColorRGBA GetRGBAColor() const
+  {
+    return Quantity_ColorRGBA(mySurfaceColor, 1.0 - myTransparency);
+  }
+
+  //! Returns surface color
+  //! @return surface color
+  Quantity_Color SurfaceColor() const { return mySurfaceColor; }
+
+  //! Returns transparency value
+  //! @return transparency value
+  Standard_Real Transparency() const { return myTransparency; }
+
+  //! Returns rendering method
+  //! @return rendering method
+  StepVisual_ShadingSurfaceMethod RenderingMethod() const { return myRenderingMethod; }
+
+  //! Sets rendering method
+  //! @param[in] theRenderingMethod rendering method
+  void SetRenderingMethod(const StepVisual_ShadingSurfaceMethod theRenderingMethod)
+  {
+    myRenderingMethod = theRenderingMethod;
+  }
+
+  //! Returns whether the rendering properties are defined
+  //! @return true if defined, false otherwise
+  Standard_Boolean IsDefined() const { return myIsDefined; }
+
+  //! Returns whether material is convertible to STEP
+  //! @return true if fully defined for conversion, false otherwise
+  Standard_EXPORT Standard_Boolean IsMaterialConvertible() const;
+
+  //! Returns ambient reflectance value
+  //! @return ambient reflectance value
+  Standard_EXPORT Standard_Real AmbientReflectance() const;
+
+  //! Returns whether ambient reflectance is defined
+  //! @return true if defined, false otherwise
+  Standard_EXPORT Standard_Boolean IsAmbientReflectanceDefined() const;
+
+  //! Returns diffuse reflectance value
+  //! @return diffuse reflectance value
+  Standard_EXPORT Standard_Real DiffuseReflectance() const;
+
+  //! Returns whether diffuse reflectance is defined
+  //! @return true if defined, false otherwise
+  Standard_EXPORT Standard_Boolean IsDiffuseReflectanceDefined() const;
+
+  //! Returns specular reflectance value
+  //! @return specular reflectance value
+  Standard_EXPORT Standard_Real SpecularReflectance() const;
+
+  //! Returns whether specular reflectance is defined
+  //! @return true if defined, false otherwise
+  Standard_EXPORT Standard_Boolean IsSpecularReflectanceDefined() const;
+
+  //! Returns specular exponent value
+  //! @return specular exponent value
+  Standard_EXPORT Standard_Real SpecularExponent() const;
+
+  //! Returns whether specular exponent is defined
+  //! @return true if defined, false otherwise
+  Standard_EXPORT Standard_Boolean IsSpecularExponentDefined() const;
+
+  //! Returns specular color
+  //! @return specular color
+  Standard_EXPORT Quantity_Color SpecularColour() const;
+
+  //! Returns whether specular color is defined
+  //! @return true if defined, false otherwise
+  Standard_EXPORT Standard_Boolean IsSpecularColourDefined() const;
+
+private:
+  Quantity_Color mySurfaceColor; //!< Surface colour used for rendering
+  Standard_Real  myTransparency; //!< Transparency value (0.0 - opaque, 1.0 - fully transparent)
+  StepVisual_ShadingSurfaceMethod myRenderingMethod; //!< Rendering method used for shading
+  Standard_Boolean myIsDefined; //!< Flag indicating if rendering properties are defined
+
+  //! Ambient reflectance value, applyed on the surface color
+  std::pair<Standard_Real, Standard_Boolean> myAmbientReflectance;
+  //! Diffuse reflectance value, applyed on the surface color
+  std::pair<Standard_Real, Standard_Boolean> myDiffuseReflectance;
+  //! Specular reflectance value, applyed on the surface color
+  std::pair<Standard_Real, Standard_Boolean> mySpecularReflectance;
+  //! Specular exponent value, applyed on the surface color
+  std::pair<Standard_Real, Standard_Boolean> mySpecularExponent;
+  //! Specular color, applyed on the surface color
+  std::pair<Quantity_Color, Standard_Boolean> mySpecularColour;
+};
+
+#endif // STEPConstruct_RenderingProperties_HeaderFile
\ No newline at end of file
index 55a7f1d35eb102c9de7b886cdec1f2eb181de2b4..21b36bfe9a258b411dfadf270cb5b4783f0d4f46 100644 (file)
@@ -79,39 +79,23 @@ namespace
 //           (even if color and transparency data couldn't be extracted
 //           for some reason), otherwise returns false.
 //=======================================================================
-Standard_Boolean ProcessAsSurfaceStyleRendering(const StepVisual_SurfaceStyleElementSelect& theSSES,
-                                                Handle(StepVisual_Colour)& theRenderColour,
-                                                Standard_Real&             theRenderTransparency)
+Standard_Boolean ProcessAsSurfaceStyleRendering(
+  const StepVisual_SurfaceStyleElementSelect& theSSES,
+  STEPConstruct_RenderingProperties&          theRenderingProps)
 {
   const Handle(StepVisual_SurfaceStyleRendering) aSSR = theSSES.SurfaceStyleRendering();
   if (aSSR.IsNull())
   {
     return Standard_False;
   }
-  theRenderColour       = aSSR->SurfaceColour();
-  theRenderTransparency = 0.0;
   const Handle(StepVisual_SurfaceStyleRenderingWithProperties) aSSRWP =
     Handle(StepVisual_SurfaceStyleRenderingWithProperties)::DownCast(aSSR);
   if (aSSRWP.IsNull())
   {
     return Standard_True;
   }
-  const Handle(StepVisual_HArray1OfRenderingPropertiesSelect) aHARP = aSSRWP->Properties();
-  if (aHARP.IsNull())
-  {
-    return Standard_True;
-  }
-
-  for (Standard_Integer aPropIndex = 1; aPropIndex <= aHARP->Length(); ++aPropIndex)
-  {
-    const Handle(StepVisual_SurfaceStyleTransparent) aSST =
-      aHARP->Value(aPropIndex).SurfaceStyleTransparent();
-    if (!aSST.IsNull())
-    {
-      theRenderTransparency = aSST->Transparency();
-    }
-  }
-  return Standard_True;
+  theRenderingProps.Init(aSSRWP);
+  return theRenderingProps.IsDefined();
 }
 
 //=======================================================================
@@ -189,10 +173,9 @@ Standard_Boolean ProcessAsSurfaceStyleFillArea(const StepVisual_SurfaceStyleElem
 //           otherwise returns false.
 //=======================================================================
 Standard_Boolean ProcessAsSurfaceStyleUsage(const StepVisual_PresentationStyleSelect& thePSS,
-                                            Handle(StepVisual_Colour)& theSurfaceColour,
-                                            Handle(StepVisual_Colour)& theBoundaryColour,
-                                            Handle(StepVisual_Colour)& theRenderColour,
-                                            Standard_Real&             theRenderTransparency)
+                                            Handle(StepVisual_Colour)&         theSurfaceColour,
+                                            Handle(StepVisual_Colour)&         theBoundaryColour,
+                                            STEPConstruct_RenderingProperties& theRenderingProps)
 {
   const Handle(StepVisual_SurfaceStyleUsage) aSSU = thePSS.SurfaceStyleUsage();
   if (aSSU.IsNull())
@@ -209,7 +192,7 @@ Standard_Boolean ProcessAsSurfaceStyleUsage(const StepVisual_PresentationStyleSe
     // So we're using && operator to stop as soon as this type is processed.
     ProcessAsSurfaceStyleFillArea(aSSES, aSSU->Side(), theSurfaceColour)
       || ProcessAsSurfaceStyleBoundary(aSSES, theBoundaryColour)
-      || ProcessAsSurfaceStyleRendering(aSSES, theRenderColour, theRenderTransparency);
+      || ProcessAsSurfaceStyleRendering(aSSES, theRenderingProps);
   }
   return Standard_True;
 }
@@ -584,11 +567,10 @@ Standard_Boolean STEPConstruct_Styles::LoadInvisStyles(
 
 Handle(StepVisual_PresentationStyleAssignment) STEPConstruct_Styles::MakeColorPSA(
   const Handle(StepRepr_RepresentationItem)& /*item*/,
-  const Handle(StepVisual_Colour)& SurfCol,
-  const Handle(StepVisual_Colour)& CurveCol,
-  const Handle(StepVisual_Colour)& RenderCol,
-  const Standard_Real              RenderTransp,
-  const Standard_Boolean           isForNAUO) const
+  const Handle(StepVisual_Colour)&         SurfCol,
+  const Handle(StepVisual_Colour)&         CurveCol,
+  const STEPConstruct_RenderingProperties& theRenderingProps,
+  const Standard_Boolean                   isForNAUO) const
 {
   Handle(StepVisual_PresentationStyleAssignment) PSA;
   TColStd_SequenceOfTransient                    items;
@@ -617,30 +599,20 @@ Handle(StepVisual_PresentationStyleAssignment) STEPConstruct_Styles::MakeColorPS
     StepVisual_SurfaceStyleElementSelect SES;
     SES.SetValue(SSFA);
 
+    Handle(StepVisual_SurfaceStyleRenderingWithProperties) aSSRWP =
+      theRenderingProps.CreateRenderingProperties(SurfCol);
+
     Handle(StepVisual_HArray1OfSurfaceStyleElementSelect) SSESs;
-    if (RenderTransp == 0.0)
+    if (aSSRWP.IsNull())
     {
       SSESs = new StepVisual_HArray1OfSurfaceStyleElementSelect(1, 1);
     }
     else
     {
-      Handle(StepVisual_SurfaceStyleTransparent) SST = new StepVisual_SurfaceStyleTransparent;
-      SST->Init(RenderTransp);
-      StepVisual_RenderingPropertiesSelect RPS;
-      RPS.SetValue(SST);
-      Handle(StepVisual_HArray1OfRenderingPropertiesSelect) HARP =
-        new StepVisual_HArray1OfRenderingPropertiesSelect(1, 1);
-      HARP->SetValue(1, RPS);
-      Handle(StepVisual_SurfaceStyleRenderingWithProperties) SSRWP =
-        new StepVisual_SurfaceStyleRenderingWithProperties;
-
-      SSRWP->Init(StepVisual_ssmNormalShading, RenderCol, HARP);
-
-      StepVisual_SurfaceStyleElementSelect SESR;
-      SESR.SetValue(SSRWP);
-
+      StepVisual_SurfaceStyleElementSelect aSESR;
+      aSESR.SetValue(aSSRWP);
       SSESs = new StepVisual_HArray1OfSurfaceStyleElementSelect(1, 2);
-      SSESs->SetValue(2, SESR);
+      SSESs->SetValue(2, aSESR);
     }
     SSESs->SetValue(1, SES);
 
@@ -719,7 +691,7 @@ Handle(StepVisual_PresentationStyleAssignment) STEPConstruct_Styles::GetColorPSA
   }
   else
   {
-    PSA = MakeColorPSA(item, Col, Col, Col, 0.0);
+    PSA = MakeColorPSA(item, Col, Col, STEPConstruct_RenderingProperties());
     myMapOfStyles.Add(Col, PSA);
   }
   return PSA;
@@ -727,18 +699,18 @@ Handle(StepVisual_PresentationStyleAssignment) STEPConstruct_Styles::GetColorPSA
 
 //=================================================================================================
 
-Standard_Boolean STEPConstruct_Styles::GetColors(const Handle(StepVisual_StyledItem)& theStyle,
-                                                 Handle(StepVisual_Colour)& theSurfaceColour,
-                                                 Handle(StepVisual_Colour)& theBoundaryColour,
-                                                 Handle(StepVisual_Colour)& theCurveColour,
-                                                 Handle(StepVisual_Colour)& theRenderColour,
-                                                 Standard_Real&             theRenderTransparency,
-                                                 Standard_Boolean&          theIsComponent) const
+Standard_Boolean STEPConstruct_Styles::GetColors(
+  const Handle(StepVisual_StyledItem)& theStyle,
+  Handle(StepVisual_Colour)&           theSurfaceColour,
+  Handle(StepVisual_Colour)&           theBoundaryColour,
+  Handle(StepVisual_Colour)&           theCurveColour,
+  STEPConstruct_RenderingProperties&   theRenderingProps,
+  Standard_Boolean&                    theIsComponent) const
 {
   theSurfaceColour.Nullify();
   theBoundaryColour.Nullify();
   theCurveColour.Nullify();
-  theRenderColour.Nullify();
+  theRenderingProps = STEPConstruct_RenderingProperties();
 
   // parse on styles
   for (Standard_Integer aPSAIndex = 1; aPSAIndex <= theStyle->NbStyles(); ++aPSAIndex)
@@ -756,16 +728,12 @@ Standard_Boolean STEPConstruct_Styles::GetColors(const Handle(StepVisual_StyledI
       // PresentationStyleSelect can be of only one of the following types:
       // SurfaceStyleUsage, CurveStyle.
       // So we're using && operator to stop as soon as this type is processed.
-      ProcessAsSurfaceStyleUsage(aPSS,
-                                 theSurfaceColour,
-                                 theBoundaryColour,
-                                 theRenderColour,
-                                 theRenderTransparency)
+      ProcessAsSurfaceStyleUsage(aPSS, theSurfaceColour, theBoundaryColour, theRenderingProps)
         || ProcessAsCurveStyle(aPSS, theCurveColour);
     }
   }
   return !theSurfaceColour.IsNull() || !theBoundaryColour.IsNull() || !theCurveColour.IsNull()
-         || !theRenderColour.IsNull();
+         || theRenderingProps.IsDefined();
 }
 
 //=================================================================================================
index f6d207860a325194ab1ecfd9815b351f72f6a52c..ed1379210fbdac11cc544b0449119c0ecf3328ae 100644 (file)
@@ -25,6 +25,7 @@
 #include <STEPConstruct_Tool.hxx>
 #include <Standard_Integer.hxx>
 #include <TColStd_HSequenceOfTransient.hxx>
+#include <STEPConstruct_RenderingProperties.hxx>
 #include <STEPConstruct_DataMapOfAsciiStringTransient.hxx>
 #include <STEPConstruct_DataMapOfPointTransient.hxx>
 
@@ -35,6 +36,7 @@ class StepVisual_PresentationStyleAssignment;
 class TopoDS_Shape;
 class StepRepr_RepresentationContext;
 class StepVisual_MechanicalDesignGeometricPresentationRepresentation;
+class StepData_StepModel;
 class StepShape_ContextDependentShapeRepresentation;
 class StepRepr_ProductDefinitionShape;
 class StepVisual_Colour;
@@ -136,8 +138,7 @@ public:
     const Handle(StepRepr_RepresentationItem)& item,
     const Handle(StepVisual_Colour)&           SurfCol,
     const Handle(StepVisual_Colour)&           CurveCol,
-    const Handle(StepVisual_Colour)&           RenderCol,
-    const Standard_Real                        RenderTransp,
+    const STEPConstruct_RenderingProperties&   theRenderingProps,
     const Standard_Boolean                     isForNAUO = Standard_False) const;
 
   //! Returns a PresentationStyleAssignment entity which defines
@@ -156,8 +157,7 @@ public:
                                              Handle(StepVisual_Colour)&           theSurfaceColour,
                                              Handle(StepVisual_Colour)&           theBoundaryColour,
                                              Handle(StepVisual_Colour)&           theCurveColour,
-                                             Handle(StepVisual_Colour)&           theRenderColour,
-                                             Standard_Real&    theRenderTransparency,
+                                             STEPConstruct_RenderingProperties&   theRenderingProps,
                                              Standard_Boolean& theIsComponent) const;
 
   //! Create STEP color entity by given Quantity_Color
index 7ebf6d1befac960f334b1de1b0f184b37ec899e4..e23a7903bfb917ce1d21eabebe310b11f8729a35 100644 (file)
@@ -734,6 +734,8 @@ static Standard_CString schemaAP242DIS =
 
 #include <StepVisual_SurfaceStyleTransparent.hxx>
 #include <StepVisual_SurfaceStyleReflectanceAmbient.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx>
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx>
 #include <StepVisual_SurfaceStyleRenderingWithProperties.hxx>
 
 #include <StepVisual_TessellatedConnectingEdge.hxx>
@@ -1567,6 +1569,8 @@ StepAP214_Protocol::StepAP214_Protocol()
   types.Bind(STANDARD_TYPE(StepRepr_BooleanRepresentationItem), 822);
   types.Bind(STANDARD_TYPE(StepRepr_RealRepresentationItem), 823);
   types.Bind(STANDARD_TYPE(StepRepr_MechanicalDesignAndDraughtingRelationship), 824);
+  types.Bind(STANDARD_TYPE(StepVisual_SurfaceStyleReflectanceAmbientDiffuse), 825);
+  types.Bind(STANDARD_TYPE(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular), 826);
 }
 
 //=================================================================================================
index cb66655cca6eead330547b188712c22ea73b3158..d2689638c9e3d1dcf511f900a77a75309d05bc61 100644 (file)
@@ -227,6 +227,10 @@ set(OCCT_StepVisual_FILES
   StepVisual_SurfaceStyleParameterLine.hxx
   StepVisual_SurfaceStyleReflectanceAmbient.cxx
   StepVisual_SurfaceStyleReflectanceAmbient.hxx
+  StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.cxx
+  StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx
+  StepVisual_SurfaceStyleReflectanceAmbientDiffuse.cxx
+  StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx
   StepVisual_SurfaceStyleRendering.cxx
   StepVisual_SurfaceStyleRendering.hxx
   StepVisual_SurfaceStyleRenderingWithProperties.cxx
diff --git a/src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuse.cxx b/src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuse.cxx
new file mode 100644 (file)
index 0000000..4c173f8
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (c) Open CASCADE 2025
+//
+// 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 <StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(StepVisual_SurfaceStyleReflectanceAmbientDiffuse,
+                           StepVisual_SurfaceStyleReflectanceAmbient)
+
+//=================================================================================================
+
+StepVisual_SurfaceStyleReflectanceAmbientDiffuse::StepVisual_SurfaceStyleReflectanceAmbientDiffuse()
+{
+}
+
+//=================================================================================================
+
+void StepVisual_SurfaceStyleReflectanceAmbientDiffuse::Init(
+  const Standard_Real theAmbientReflectance,
+  const Standard_Real theDiffuseReflectance)
+{
+  StepVisual_SurfaceStyleReflectanceAmbient::Init(theAmbientReflectance);
+  myDiffuseReflectance = theDiffuseReflectance;
+}
+
+//=================================================================================================
+
+Standard_Real StepVisual_SurfaceStyleReflectanceAmbientDiffuse::DiffuseReflectance() const
+{
+  return myDiffuseReflectance;
+}
+
+//=================================================================================================
+
+void StepVisual_SurfaceStyleReflectanceAmbientDiffuse::SetDiffuseReflectance(
+  const Standard_Real theDiffuseReflectance)
+{
+  myDiffuseReflectance = theDiffuseReflectance;
+}
diff --git a/src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx b/src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx
new file mode 100644 (file)
index 0000000..757fb71
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (c) Open CASCADE 2025
+//
+// 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.
+
+#ifndef _StepVisual_SurfaceStyleReflectanceAmbientDiffuse_HeaderFile_
+#define _StepVisual_SurfaceStyleReflectanceAmbientDiffuse_HeaderFile_
+
+#include <StepVisual_SurfaceStyleReflectanceAmbient.hxx>
+
+//! Representation of STEP entity SurfaceStyleReflectanceAmbientDiffuse
+class StepVisual_SurfaceStyleReflectanceAmbientDiffuse
+    : public StepVisual_SurfaceStyleReflectanceAmbient
+{
+public:
+  //! default constructor
+  Standard_EXPORT StepVisual_SurfaceStyleReflectanceAmbientDiffuse();
+
+  //! Initialize all fields (own and inherited)
+  Standard_EXPORT void Init(const Standard_Real theAmbientReflectance,
+                            const Standard_Real theDiffuseReflectance);
+
+  //! Returns field DiffuseReflectance
+  Standard_EXPORT Standard_Real DiffuseReflectance() const;
+
+  //! Sets field DiffuseReflectance
+  Standard_EXPORT void SetDiffuseReflectance(const Standard_Real theDiffuseReflectance);
+
+  DEFINE_STANDARD_RTTIEXT(StepVisual_SurfaceStyleReflectanceAmbientDiffuse,
+                          StepVisual_SurfaceStyleReflectanceAmbient)
+
+private:
+  Standard_Real myDiffuseReflectance;
+};
+#endif // _StepVisual_SurfaceStyleReflectanceAmbientDiffuse_HeaderFile_
diff --git a/src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.cxx b/src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.cxx
new file mode 100644 (file)
index 0000000..bb0787d
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (c) Open CASCADE 2025
+//
+// 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 <StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular,
+                           StepVisual_SurfaceStyleReflectanceAmbientDiffuse)
+
+//=================================================================================================
+
+StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular::
+  StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular()
+{
+}
+
+//=================================================================================================
+
+void StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular::Init(
+  const Standard_Real              theAmbientReflectance,
+  const Standard_Real              theDiffuseReflectance,
+  const Standard_Real              theSpecularReflectance,
+  const Standard_Real              theSpecularExponent,
+  const Handle(StepVisual_Colour)& theSpecularColour)
+{
+  StepVisual_SurfaceStyleReflectanceAmbientDiffuse::Init(theAmbientReflectance,
+                                                         theDiffuseReflectance);
+  mySpecularReflectance = theSpecularReflectance;
+  mySpecularExponent    = theSpecularExponent;
+  mySpecularColour      = theSpecularColour;
+}
+
+//=================================================================================================
+
+Standard_Real StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular::SpecularReflectance() const
+{
+  return mySpecularReflectance;
+}
+
+//=================================================================================================
+
+void StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular::SetSpecularReflectance(
+  const Standard_Real theSpecularReflectance)
+{
+  mySpecularReflectance = theSpecularReflectance;
+}
+
+//=================================================================================================
+
+Standard_Real StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular::SpecularExponent() const
+{
+  return mySpecularExponent;
+}
+
+//=================================================================================================
+
+void StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular::SetSpecularExponent(
+  const Standard_Real theSpecularExponent)
+{
+  mySpecularExponent = theSpecularExponent;
+}
+
+//=================================================================================================
+
+Handle(StepVisual_Colour) StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular::SpecularColour()
+  const
+{
+  return mySpecularColour;
+}
+
+//=================================================================================================
+
+void StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular::SetSpecularColour(
+  const Handle(StepVisual_Colour)& theSpecularColour)
+{
+  mySpecularColour = theSpecularColour;
+}
\ No newline at end of file
diff --git a/src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx b/src/DataExchange/TKDESTEP/StepVisual/StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular.hxx
new file mode 100644 (file)
index 0000000..72fad79
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (c) Open CASCADE 2025
+//
+// 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.
+
+#ifndef _StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular_HeaderFile_
+#define _StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular_HeaderFile_
+
+#include <StepVisual_SurfaceStyleReflectanceAmbientDiffuse.hxx>
+#include <StepVisual_Colour.hxx>
+
+//! Representation of STEP entity SurfaceStyleReflectanceAmbientDiffuseSpecular
+class StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular
+    : public StepVisual_SurfaceStyleReflectanceAmbientDiffuse
+{
+public:
+  //! default constructor
+  Standard_EXPORT StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular();
+
+  //! Initialize all fields (own and inherited)
+  Standard_EXPORT void Init(const Standard_Real              theAmbientReflectance,
+                            const Standard_Real              theDiffuseReflectance,
+                            const Standard_Real              theSpecularReflectance,
+                            const Standard_Real              theSpecularExponent,
+                            const Handle(StepVisual_Colour)& theSpecularColour);
+
+  //! Returns field SpecularReflectance
+  Standard_EXPORT Standard_Real SpecularReflectance() const;
+
+  //! Sets field SpecularReflectance
+  Standard_EXPORT void SetSpecularReflectance(const Standard_Real theSpecularReflectance);
+
+  //! Returns field SpecularExponent
+  Standard_EXPORT Standard_Real SpecularExponent() const;
+
+  //! Sets field SpecularExponent
+  Standard_EXPORT void SetSpecularExponent(const Standard_Real theSpecularExponent);
+
+  //! Returns field SpecularColour
+  Standard_EXPORT Handle(StepVisual_Colour) SpecularColour() const;
+
+  //! Sets field SpecularColour
+  Standard_EXPORT void SetSpecularColour(const Handle(StepVisual_Colour)& theSpecularColour);
+
+  DEFINE_STANDARD_RTTIEXT(StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular,
+                          StepVisual_SurfaceStyleReflectanceAmbientDiffuse)
+
+private:
+  Standard_Real             mySpecularReflectance;
+  Standard_Real             mySpecularExponent;
+  Handle(StepVisual_Colour) mySpecularColour;
+};
+#endif // _StepVisual_SurfaceStyleReflectanceAmbientDiffuseSpecular_HeaderFile_
index 1c00144f83461dec1b22f6cb1e84686b4727a24e..52c224f82a8d37b0e65e93cd87d434cfe9be7c74 100644 (file)
@@ -193,6 +193,8 @@ provider.STEP.OCC.write.color :      1
 provider.STEP.OCC.write.nonmanifold :   0
 provider.STEP.OCC.write.name :  1
 provider.STEP.OCC.write.layer :         1
+provider.STEP.OCC.write.material :      1
+provider.STEP.OCC.write.vismaterial :   0
 provider.STEP.OCC.write.props :         1
 provider.STEP.OCC.write.model.type :    0
 provider.STEP.OCC.write.cleanduplicates : 0
index 616f2eba1535f6a06670b35e19f58daf8dc998db..9099d77f66385fd65d2598112dcdc75252678963 100644 (file)
@@ -139,6 +139,8 @@ provider.STEP.OCC.write.nonmanifold :        0
 provider.STEP.OCC.write.name :  1
 provider.STEP.OCC.write.layer :         1
 provider.STEP.OCC.write.props :         1
+provider.STEP.OCC.write.material :      1
+provider.STEP.OCC.write.vismaterial :   0
 provider.STEP.OCC.write.model.type :    0
 provider.STEP.OCC.write.cleanduplicates : 0
 provider.STEP.OCC.healing.tolerance3d :         1e-06