From 366b40efa19ba925734c3c97ca50ae909ab816ed Mon Sep 17 00:00:00 2001
From: mzernova <mzernova@opencascade.com>
Date: Fri, 7 Feb 2025 09:49:59 +0000
Subject: [PATCH] Data Exchange - Fix GLTF Export for vertices and edges

Only free vertices and edges are exported now
---
 src/RWGltf/RWGltf_CafWriter.cxx      | 51 ++++++----------------------
 src/RWGltf/RWGltf_CafWriter.hxx      |  6 +---
 src/RWMesh/RWMesh_EdgeIterator.cxx   |  4 +--
 src/RWMesh/RWMesh_FaceIterator.cxx   |  9 +++--
 src/RWMesh/RWMesh_ShapeIterator.cxx  | 19 +++++++----
 src/RWMesh/RWMesh_ShapeIterator.hxx  |  6 ++--
 src/RWMesh/RWMesh_VertexIterator.cxx |  9 +++--
 tests/de_mesh/gltf_write/empty       | 38 ++-------------------
 8 files changed, 46 insertions(+), 96 deletions(-)

diff --git a/src/RWGltf/RWGltf_CafWriter.cxx b/src/RWGltf/RWGltf_CafWriter.cxx
index e2c36f71c5..d64e459dd6 100644
--- a/src/RWGltf/RWGltf_CafWriter.cxx
+++ b/src/RWGltf/RWGltf_CafWriter.cxx
@@ -852,18 +852,14 @@ bool RWGltf_CafWriter::writeBinData(const Handle(TDocStd_Document)& theDocument,
 
     // transformation will be stored at scene nodes
     aMergedFaces.Clear(false);
-
-    Standard_Integer aBinDataSize = myBinDataMap.Size();
     {
       RWMesh_FaceIterator aFaceIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
       dispatchShapes(aDocNode, aPSentryBin, aMergedFaces, aFaceIter);
     }
-    if (aBinDataSize == myBinDataMap.Size())
     {
       RWMesh_EdgeIterator anEdgeIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
       dispatchShapes(aDocNode, aPSentryBin, aMergedFaces, anEdgeIter);
     }
-    if (aBinDataSize == myBinDataMap.Size())
     {
       RWMesh_VertexIterator aVertexIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
       dispatchShapes(aDocNode, aPSentryBin, aMergedFaces, aVertexIter);
@@ -1936,13 +1932,11 @@ void RWGltf_CafWriter::writeImages(const RWGltf_GltfSceneNodeMap& theSceneNodeMa
 //=================================================================================================
 
 void RWGltf_CafWriter::writeMaterial(RWMesh_ShapeIterator& theShapeIter,
-                                     Standard_Boolean&     theIsStarted,
-                                     Standard_Integer&     theAddedMaterialsNb)
+                                     Standard_Boolean&     theIsStarted)
 {
   for (; theShapeIter.More(); theShapeIter.Next())
   {
     myMaterialMap->AddMaterial(myWriter.get(), theShapeIter.Style(), theIsStarted);
-    theAddedMaterialsNb++;
   }
 }
 
@@ -1959,21 +1953,18 @@ void RWGltf_CafWriter::writeMaterials(const RWGltf_GltfSceneNodeMap& theSceneNod
   for (RWGltf_GltfSceneNodeMap::Iterator aSceneNodeIter(theSceneNodeMap); aSceneNodeIter.More();
        aSceneNodeIter.Next())
   {
-    const XCAFPrs_DocumentNode& aDocNode           = aSceneNodeIter.Value();
-    Standard_Integer            anAddedMaterialsNb = 0;
+    const XCAFPrs_DocumentNode& aDocNode = aSceneNodeIter.Value();
     {
       RWMesh_FaceIterator aFaceIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
-      writeMaterial(aFaceIter, anIsStarted, anAddedMaterialsNb);
+      writeMaterial(aFaceIter, anIsStarted);
     }
-    if (anAddedMaterialsNb == 0)
     {
       RWMesh_EdgeIterator anEdgeIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
-      writeMaterial(anEdgeIter, anIsStarted, anAddedMaterialsNb);
+      writeMaterial(anEdgeIter, anIsStarted);
     }
-    if (anAddedMaterialsNb == 0)
     {
       RWMesh_VertexIterator VertexIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
-      writeMaterial(VertexIter, anIsStarted, anAddedMaterialsNb);
+      writeMaterial(VertexIter, anIsStarted);
     }
   }
   if (anIsStarted)
@@ -2096,14 +2087,13 @@ void RWGltf_CafWriter::writePrimArray(const RWGltf_GltfFace&         theGltfFace
 //=================================================================================================
 
 void RWGltf_CafWriter::writeShapes(RWMesh_ShapeIterator&                         theShapeIter,
-                                   Standard_Integer&                             theNbFacesInNode,
                                    Standard_Integer&                             theDracoBufInd,
                                    Standard_Boolean&                             theToStartPrims,
                                    const TCollection_AsciiString&                theNodeName,
                                    NCollection_Map<Handle(RWGltf_GltfFaceList)>& theWrittenShapes,
                                    NCollection_IndexedDataMap<int, int>&         theDracoBufIndMap)
 {
-  for (; theShapeIter.More(); theShapeIter.Next(), ++theNbFacesInNode)
+  for (; theShapeIter.More(); theShapeIter.Next())
   {
     if (toSkipShape(theShapeIter))
     {
@@ -2157,8 +2147,7 @@ void RWGltf_CafWriter::writeMeshes(const RWGltf_GltfSceneNodeMap& theSceneNodeMa
     const TCollection_AsciiString aNodeName =
       formatName(myMeshNameFormat, aDocNode.Label, aDocNode.RefLabel);
 
-    bool             toStartPrims = true;
-    Standard_Integer aNbShapes    = 0;
+    bool toStartPrims = true;
     aWrittenShapes.Clear(false);
     if (myToMergeFaces)
     {
@@ -2201,35 +2190,15 @@ void RWGltf_CafWriter::writeMeshes(const RWGltf_GltfSceneNodeMap& theSceneNodeMa
     {
       {
         RWMesh_FaceIterator anIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
-        writeShapes(anIter,
-                    aNbShapes,
-                    aDracoBufInd,
-                    toStartPrims,
-                    aNodeName,
-                    aWrittenShapes,
-                    aDracoBufMap);
+        writeShapes(anIter, aDracoBufInd, toStartPrims, aNodeName, aWrittenShapes, aDracoBufMap);
       }
-      if (aNbShapes == 0)
       {
         RWMesh_EdgeIterator anIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
-        writeShapes(anIter,
-                    aNbShapes,
-                    aDracoBufInd,
-                    toStartPrims,
-                    aNodeName,
-                    aWrittenShapes,
-                    aDracoBufMap);
+        writeShapes(anIter, aDracoBufInd, toStartPrims, aNodeName, aWrittenShapes, aDracoBufMap);
       }
-      if (aNbShapes == 0)
       {
         RWMesh_VertexIterator anIter(aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style);
-        writeShapes(anIter,
-                    aNbShapes,
-                    aDracoBufInd,
-                    toStartPrims,
-                    aNodeName,
-                    aWrittenShapes,
-                    aDracoBufMap);
+        writeShapes(anIter, aDracoBufInd, toStartPrims, aNodeName, aWrittenShapes, aDracoBufMap);
       }
     }
 
diff --git a/src/RWGltf/RWGltf_CafWriter.hxx b/src/RWGltf/RWGltf_CafWriter.hxx
index fed2d845c7..b06838fb45 100644
--- a/src/RWGltf/RWGltf_CafWriter.hxx
+++ b/src/RWGltf/RWGltf_CafWriter.hxx
@@ -356,10 +356,8 @@ protected:
   //! Write RWGltf_GltfRootElement_Materials section.
   //! @param[in]  theShapeIter         Shape iterator to traverse shapes
   //! @param[out] theIsStarted         Flag indicating that writing material has been started
-  //! @param[out] theAddedMaterialsNb  Number of added materials
   Standard_EXPORT virtual void writeMaterial(RWMesh_ShapeIterator& theShapeIter,
-                                             Standard_Boolean&     theIsStarted,
-                                             Standard_Integer&     theAddedMaterialsNb);
+                                             Standard_Boolean&     theIsStarted);
 
   //! Write RWGltf_GltfRootElement_Meshes section.
   //! @param[in] theSceneNodeMap  ordered map of scene nodes
@@ -445,7 +443,6 @@ protected:
 
   //! Write shapes to RWGltf_GltfRootElement_Meshes section
   //! @param[in] theShapeIter          Shape iterator to traverse shapes
-  //! @param[in,out] theNbFacesInNode  Number of faces in the current node
   //! @param[in,out] theDracoBufInd    Draco buffer index
   //! @param[in,out] theToStartPrims   Flag to indicate if primitives should be started
   //! @param[in] theNodeName           Name of the current node
@@ -453,7 +450,6 @@ protected:
   //! @param[in,out] theDracoBufIndMap Map to store Draco buffer indices
   Standard_EXPORT virtual void writeShapes(
     RWMesh_ShapeIterator&                         theShapeIter,
-    Standard_Integer&                             theNbFacesInNode,
     Standard_Integer&                             theDracoBufInd,
     Standard_Boolean&                             theToStartPrims,
     const TCollection_AsciiString&                theNodeName,
diff --git a/src/RWMesh/RWMesh_EdgeIterator.cxx b/src/RWMesh/RWMesh_EdgeIterator.cxx
index 68b76cc7b7..7efe829f08 100644
--- a/src/RWMesh/RWMesh_EdgeIterator.cxx
+++ b/src/RWMesh/RWMesh_EdgeIterator.cxx
@@ -25,7 +25,7 @@ RWMesh_EdgeIterator::RWMesh_EdgeIterator(const TDF_Label&       theLabel,
                                          const TopLoc_Location& theLocation,
                                          const Standard_Boolean theToMapColors,
                                          const XCAFPrs_Style&   theStyle)
-    : RWMesh_ShapeIterator(theLabel, theLocation, TopAbs_EDGE, theToMapColors, theStyle)
+    : RWMesh_ShapeIterator(theLabel, theLocation, TopAbs_EDGE, TopAbs_FACE, theToMapColors, theStyle)
 {
   Next();
 }
@@ -34,7 +34,7 @@ RWMesh_EdgeIterator::RWMesh_EdgeIterator(const TDF_Label&       theLabel,
 
 RWMesh_EdgeIterator::RWMesh_EdgeIterator(const TopoDS_Shape&  theShape,
                                          const XCAFPrs_Style& theStyle)
-    : RWMesh_ShapeIterator(theShape, TopAbs_EDGE, theStyle)
+    : RWMesh_ShapeIterator(theShape, TopAbs_EDGE, TopAbs_FACE, theStyle)
 {
   Next();
 }
diff --git a/src/RWMesh/RWMesh_FaceIterator.cxx b/src/RWMesh/RWMesh_FaceIterator.cxx
index 59e62666c0..9cc4846ec5 100644
--- a/src/RWMesh/RWMesh_FaceIterator.cxx
+++ b/src/RWMesh/RWMesh_FaceIterator.cxx
@@ -26,7 +26,12 @@ RWMesh_FaceIterator::RWMesh_FaceIterator(const TDF_Label&       theLabel,
                                          const TopLoc_Location& theLocation,
                                          const Standard_Boolean theToMapColors,
                                          const XCAFPrs_Style&   theStyle)
-    : RWMesh_ShapeIterator(theLabel, theLocation, TopAbs_FACE, theToMapColors, theStyle),
+    : RWMesh_ShapeIterator(theLabel,
+                           theLocation,
+                           TopAbs_FACE,
+                           TopAbs_SHAPE,
+                           theToMapColors,
+                           theStyle),
       mySLTool(1, 1e-12),
       myHasNormals(false),
       myIsMirrored(false)
@@ -38,7 +43,7 @@ RWMesh_FaceIterator::RWMesh_FaceIterator(const TDF_Label&       theLabel,
 
 RWMesh_FaceIterator::RWMesh_FaceIterator(const TopoDS_Shape&  theShape,
                                          const XCAFPrs_Style& theStyle)
-    : RWMesh_ShapeIterator(theShape, TopAbs_FACE, theStyle),
+    : RWMesh_ShapeIterator(theShape, TopAbs_FACE, TopAbs_SHAPE, theStyle),
       mySLTool(1, 1e-12),
       myHasNormals(false),
       myIsMirrored(false)
diff --git a/src/RWMesh/RWMesh_ShapeIterator.cxx b/src/RWMesh/RWMesh_ShapeIterator.cxx
index a26b6c5766..1095cb91f8 100644
--- a/src/RWMesh/RWMesh_ShapeIterator.cxx
+++ b/src/RWMesh/RWMesh_ShapeIterator.cxx
@@ -22,12 +22,13 @@
 
 RWMesh_ShapeIterator::RWMesh_ShapeIterator(const TDF_Label&       theLabel,
                                            const TopLoc_Location& theLocation,
-                                           const TopAbs_ShapeEnum theShapeType,
+                                           const TopAbs_ShapeEnum theShapeTypeFind,
+                                           const TopAbs_ShapeEnum theShapeTypeAvoid,
                                            const Standard_Boolean theToMapColors,
                                            const XCAFPrs_Style&   theStyle)
     : myDefStyle(theStyle),
       myToMapColors(theToMapColors),
-      myShapeType(theShapeType),
+      myShapeType(theShapeTypeFind),
       myHasColor(false)
 {
   TopoDS_Shape aShape;
@@ -37,7 +38,7 @@ RWMesh_ShapeIterator::RWMesh_ShapeIterator(const TDF_Label&       theLabel,
   }
 
   aShape.Location(theLocation, false);
-  myIter.Init(aShape, myShapeType);
+  myIter.Init(aShape, myShapeType, theShapeTypeAvoid);
 
   if (theToMapColors)
   {
@@ -49,18 +50,19 @@ RWMesh_ShapeIterator::RWMesh_ShapeIterator(const TDF_Label&       theLabel,
 //=================================================================================================
 
 RWMesh_ShapeIterator::RWMesh_ShapeIterator(const TopoDS_Shape&    theShape,
-                                           const TopAbs_ShapeEnum theShapeType,
+                                           const TopAbs_ShapeEnum theShapeTypeFind,
+                                           const TopAbs_ShapeEnum theShapeTypeAvoid,
                                            const XCAFPrs_Style&   theStyle)
     : myDefStyle(theStyle),
       myToMapColors(true),
-      myShapeType(theShapeType),
+      myShapeType(theShapeTypeFind),
       myHasColor(false)
 {
   if (theShape.IsNull())
   {
     return;
   }
-  myIter.Init(theShape, myShapeType);
+  myIter.Init(theShape, myShapeType, theShapeTypeAvoid);
 }
 
 //=================================================================================================
@@ -152,4 +154,9 @@ void RWMesh_ShapeIterator::initShape()
     myHasColor = true;
     myColor    = myStyle.GetColorSurfRGBA();
   }
+  else if (myStyle.IsSetColorCurv())
+  {
+    myHasColor = true;
+    myColor    = Quantity_ColorRGBA(myStyle.GetColorCurv());
+  }
 }
\ No newline at end of file
diff --git a/src/RWMesh/RWMesh_ShapeIterator.hxx b/src/RWMesh/RWMesh_ShapeIterator.hxx
index 6efdfa915c..3f1735a7d1 100644
--- a/src/RWMesh/RWMesh_ShapeIterator.hxx
+++ b/src/RWMesh/RWMesh_ShapeIterator.hxx
@@ -88,13 +88,15 @@ protected:
   //! Main constructor.
   RWMesh_ShapeIterator(const TDF_Label&       theLabel,
                        const TopLoc_Location& theLocation,
-                       const TopAbs_ShapeEnum theShapeType,
+                       const TopAbs_ShapeEnum theShapeTypeFind,
+                       const TopAbs_ShapeEnum theShapeTypeAvoid,
                        const Standard_Boolean theToMapColors = false,
                        const XCAFPrs_Style&   theStyle       = XCAFPrs_Style());
 
   //! Auxiliary constructor.
   RWMesh_ShapeIterator(const TopoDS_Shape&    theShape,
-                       const TopAbs_ShapeEnum theShapeType,
+                       const TopAbs_ShapeEnum theShapeTypeFind,
+                       const TopAbs_ShapeEnum theShapeTypeAvoid,
                        const XCAFPrs_Style&   theStyle = XCAFPrs_Style());
 
   //! Dispatch shape styles.
diff --git a/src/RWMesh/RWMesh_VertexIterator.cxx b/src/RWMesh/RWMesh_VertexIterator.cxx
index 555b170a03..7cb77aaba3 100644
--- a/src/RWMesh/RWMesh_VertexIterator.cxx
+++ b/src/RWMesh/RWMesh_VertexIterator.cxx
@@ -25,7 +25,12 @@ RWMesh_VertexIterator::RWMesh_VertexIterator(const TDF_Label&       theLabel,
                                              const TopLoc_Location& theLocation,
                                              const Standard_Boolean theToMapColors,
                                              const XCAFPrs_Style&   theStyle)
-    : RWMesh_ShapeIterator(theLabel, theLocation, TopAbs_VERTEX, theToMapColors, theStyle)
+    : RWMesh_ShapeIterator(theLabel,
+                           theLocation,
+                           TopAbs_VERTEX,
+                           TopAbs_EDGE,
+                           theToMapColors,
+                           theStyle)
 {
   Next();
 }
@@ -34,7 +39,7 @@ RWMesh_VertexIterator::RWMesh_VertexIterator(const TDF_Label&       theLabel,
 
 RWMesh_VertexIterator::RWMesh_VertexIterator(const TopoDS_Shape&  theShape,
                                              const XCAFPrs_Style& theStyle)
-    : RWMesh_ShapeIterator(theShape, TopAbs_VERTEX, theStyle)
+    : RWMesh_ShapeIterator(theShape, TopAbs_VERTEX, TopAbs_EDGE, theStyle)
 {
   Next();
 }
diff --git a/tests/de_mesh/gltf_write/empty b/tests/de_mesh/gltf_write/empty
index cf8297e1ce..50daa2f2e6 100644
--- a/tests/de_mesh/gltf_write/empty
+++ b/tests/de_mesh/gltf_write/empty
@@ -19,46 +19,12 @@ Close     DD
 
 ReadGltf  D "$aTmpGltf"
 XGetOneShape s D
-checknbshapes s -face 6 -vertex 8 -compound 11
+checknbshapes s -face 6 -compound 2
 
 set THE_REF_DUMP {
 ASSEMBLY COMPOUND 0:1:1:1 "empty_tmp.glb"
 	INSTANCE COMPOUND 0:1:1:1:1 (refers to 0:1:1:2) "Compound"
-	INSTANCE COMPOUND 0:1:1:1:2 (refers to 0:1:1:19) "Compound"
-ASSEMBLY COMPOUND 0:1:1:2 "Compound"
-	INSTANCE COMPOUND 0:1:1:2:1 (refers to 0:1:1:3) "Compound"
-	INSTANCE COMPOUND 0:1:1:2:2 (refers to 0:1:1:5) "Compound"
-	INSTANCE COMPOUND 0:1:1:2:3 (refers to 0:1:1:7) "Compound"
-	INSTANCE COMPOUND 0:1:1:2:4 (refers to 0:1:1:9) "Compound"
-	INSTANCE COMPOUND 0:1:1:2:5 (refers to 0:1:1:11) "Compound"
-	INSTANCE COMPOUND 0:1:1:2:6 (refers to 0:1:1:13) "Compound"
-	INSTANCE COMPOUND 0:1:1:2:7 (refers to 0:1:1:15) "Compound"
-	INSTANCE COMPOUND 0:1:1:2:8 (refers to 0:1:1:17) "Compound"
-ASSEMBLY COMPOUND 0:1:1:3 "Compound"
-	INSTANCE VERTEX 0:1:1:3:1 (refers to 0:1:1:4) "Vertex"
-PART VERTEX 0:1:1:4 "Vertex"
-ASSEMBLY COMPOUND 0:1:1:5 "Compound"
-	INSTANCE VERTEX 0:1:1:5:1 (refers to 0:1:1:6) "Vertex"
-PART VERTEX 0:1:1:6 "Vertex"
-ASSEMBLY COMPOUND 0:1:1:7 "Compound"
-	INSTANCE VERTEX 0:1:1:7:1 (refers to 0:1:1:8) "Vertex"
-PART VERTEX 0:1:1:8 "Vertex"
-ASSEMBLY COMPOUND 0:1:1:9 "Compound"
-	INSTANCE VERTEX 0:1:1:9:1 (refers to 0:1:1:10) "Vertex"
-PART VERTEX 0:1:1:10 "Vertex"
-ASSEMBLY COMPOUND 0:1:1:11 "Compound"
-	INSTANCE VERTEX 0:1:1:11:1 (refers to 0:1:1:12) "Vertex"
-PART VERTEX 0:1:1:12 "Vertex"
-ASSEMBLY COMPOUND 0:1:1:13 "Compound"
-	INSTANCE VERTEX 0:1:1:13:1 (refers to 0:1:1:14) "Vertex"
-PART VERTEX 0:1:1:14 "Vertex"
-ASSEMBLY COMPOUND 0:1:1:15 "Compound"
-	INSTANCE VERTEX 0:1:1:15:1 (refers to 0:1:1:16) "Vertex"
-PART VERTEX 0:1:1:16 "Vertex"
-ASSEMBLY COMPOUND 0:1:1:17 "Compound"
-	INSTANCE VERTEX 0:1:1:17:1 (refers to 0:1:1:18) "Vertex"
-PART VERTEX 0:1:1:18 "Vertex"
-PART COMPOUND 0:1:1:19 "Compound"
+PART COMPOUND 0:1:1:2 "Compound"
 
 Free Shapes: 1
 ASSEMBLY COMPOUND  0:1:1:1 "empty_tmp.glb"