]> OCCT Git - occt.git/commitdiff
GLTF Import - Edge and Vertex support #242
authormzernova <mzernova@opencascade.com>
Sun, 5 Jan 2025 22:47:18 +0000 (22:47 +0000)
committermzernova <mzernova@opencascade.com>
Sun, 2 Feb 2025 21:30:21 +0000 (21:30 +0000)
Added functionality to import Points and Lines from GLTF format

16 files changed:
src/RWGltf/RWGltf_GltfJsonParser.cxx
src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx
src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx
src/RWGltf/RWGltf_TriangulationReader.cxx
src/RWGltf/RWGltf_TriangulationReader.hxx
src/RWMesh/RWMesh_TriangulationReader.cxx
src/RWMesh/RWMesh_TriangulationReader.hxx
src/RWMesh/RWMesh_TriangulationSource.cxx
src/RWMesh/RWMesh_TriangulationSource.hxx
tests/de_mesh/gltf_write/empty
tests/de_mesh/gltf_write/primitives [new file with mode: 0644]
tests/metadata/gltf/A2
tests/metadata/gltf/A3
tests/metadata/gltf/A4
tests/metadata/gltf/A7
tests/metadata/gltf/end

index 36f6a41f136bdd33706dd8bb85bb6405bb6ec909..05ffdccba0ab679ca9f32c1e8b76024146b70747 100644 (file)
@@ -15,7 +15,7 @@
 #include "RWGltf_GltfJsonParser.hxx"
 
 #include <BRep_Builder.hxx>
-#include <gp_Quaternion.hxx>
+#include <FSD_Base64.hxx>
 #include <Message.hxx>
 #include <Message_Messenger.hxx>
 #include <Message_ProgressScope.hxx>
 #include <OSD_Path.hxx>
 #include <OSD_ThreadPool.hxx>
 #include <Precision.hxx>
-#include <FSD_Base64.hxx>
+#include <RWGltf_TriangulationReader.hxx>
 #include <TDataStd_NamedData.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
 #include <TopoDS_Iterator.hxx>
+#include <gp_Quaternion.hxx>
 
 #include <fstream>
 
@@ -1581,7 +1583,9 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNodes(TopTools_SequenceOfShape&    the
     {
       continue;
     }
-    else if (myToSkipEmptyNodes && !TopExp_Explorer(aNodeShape, TopAbs_FACE).More())
+    else if (myToSkipEmptyNodes && !TopExp_Explorer(aNodeShape, TopAbs_FACE).More()
+             && !TopExp_Explorer(aNodeShape, TopAbs_EDGE).More()
+             && !TopExp_Explorer(aNodeShape, TopAbs_VERTEX).More())
     {
       continue;
     }
@@ -1838,7 +1842,8 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape&                  th
       return false;
     }
   }
-  if (aMode != RWGltf_GltfPrimitiveMode_Triangles)
+  if (aMode != RWGltf_GltfPrimitiveMode_Triangles && aMode != RWGltf_GltfPrimitiveMode_Lines
+      && aMode != RWGltf_GltfPrimitiveMode_Points)
   {
     Message::SendWarning(TCollection_AsciiString() + "Primitive array within Mesh '" + theMeshId
                          + "' skipped due to unsupported mode");
@@ -1887,21 +1892,15 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape&                  th
   {
     if (myAttribMap != NULL)
     {
-      // sharing just triangulation is not much useful
-      // Handle(RWGltf_GltfLatePrimitiveArray) aLateData =
-      // Handle(RWGltf_GltfLatePrimitiveArray)::DownCast (BRep_Tool::Triangulation (TopoDS::Face
-      // (thePrimArrayShape), aDummy)); TopoDS_Face aFaceCopy; BRep_Builder().MakeFace (aFaceCopy,
-      // aLateData);
-
-      // make a located Face copy
-      TopoDS_Shape aFaceCopy = thePrimArrayShape;
-      aFaceCopy.Location(TopLoc_Location(gp_Trsf()));
+      // make a located Shape copy
+      TopoDS_Shape aShapeCopy = thePrimArrayShape;
+      aShapeCopy.Location(TopLoc_Location(gp_Trsf()));
       RWMesh_NodeAttributes aShapeAttribs;
       aShapeAttribs.RawName = theMeshName;
       aShapeAttribs.Style.SetMaterial(aMat);
-      myAttribMap->Bind(aFaceCopy, aShapeAttribs);
-      myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayIdWithMat, aFaceCopy);
-      thePrimArrayShape = aFaceCopy;
+      myAttribMap->Bind(aShapeCopy, aShapeAttribs);
+      myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayIdWithMat, aShapeCopy);
+      thePrimArrayShape = aShapeCopy;
     }
     return true;
   }
@@ -1978,16 +1977,72 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape&                  th
       return false;
     }
   }
-  else
+  else if (aMode == RWGltf_GltfPrimitiveMode_Triangles)
   {
     aMeshData->SetNbDeferredTriangles(aMeshData->NbDeferredNodes() / 3);
   }
+  else
+  {
+    aMeshData->SetNbDeferredTriangles(0);
+  }
 
   if (!aMeshData->Data().IsEmpty())
   {
-    TopoDS_Face  aFace;
-    BRep_Builder aBuilder;
-    aBuilder.MakeFace(aFace, aMeshData);
+    if (aMode != RWGltf_GltfPrimitiveMode_Triangles)
+    {
+      Message::SendWarning("Deferred loading is available only for triangulations. Other elements "
+                           "will be loaded immediately.");
+      Handle(RWGltf_TriangulationReader) aReader = new RWGltf_TriangulationReader();
+      aReader->SetCoordinateSystemConverter(myCSTrsf);
+      aMeshData->SetReader(aReader);
+      aMeshData->LoadDeferredData();
+    }
+
+    TopoDS_Shape aShape;
+    switch (aMode)
+    {
+      case RWGltf_GltfPrimitiveMode_Points: {
+        BRep_Builder    aBuilder;
+        TopoDS_Compound aVertices;
+        aBuilder.MakeCompound(aVertices);
+        for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aMeshData->NbNodes(); ++aNodeIdx)
+        {
+          TopoDS_Vertex aVertex;
+          aBuilder.MakeVertex(aVertex, aMeshData->Node(aNodeIdx), Precision::Confusion());
+          aBuilder.Add(aVertices, aVertex);
+        }
+        aShape = aVertices;
+        break;
+      }
+      case RWGltf_GltfPrimitiveMode_Lines: {
+        TColgp_Array1OfPnt aNodes(1, aMeshData->NbEdges());
+        for (Standard_Integer anEdgeIdx = 1; anEdgeIdx <= aMeshData->NbEdges(); ++anEdgeIdx)
+        {
+          Standard_Integer aNodeIdx = aMeshData->Edge(anEdgeIdx);
+          aNodes.SetValue(anEdgeIdx, aMeshData->Node(aNodeIdx));
+        }
+        TopoDS_Edge            anEdge;
+        BRep_Builder           aBuilder;
+        Handle(Poly_Polygon3D) aPoly = new Poly_Polygon3D(aNodes);
+        aBuilder.MakeEdge(anEdge, aPoly);
+
+        aShape = anEdge;
+        break;
+      }
+      case RWGltf_GltfPrimitiveMode_Triangles: {
+        TopoDS_Face  aFace;
+        BRep_Builder aBuilder;
+        aBuilder.MakeFace(aFace, aMeshData);
+        aShape = aFace;
+        myFaceList.Append(aFace);
+        break;
+      }
+      default: {
+        Message::SendFail("Unsupported primitive mode.");
+        return false;
+        break;
+      }
+    }
     if (myAttribMap != NULL && aMeshData->HasStyle())
     {
       RWMesh_NodeAttributes aShapeAttribs;
@@ -1997,12 +2052,11 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape&                  th
       // aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor());
       aShapeAttribs.Style.SetMaterial(aMat);
 
-      myAttribMap->Bind(aFace, aShapeAttribs);
+      myAttribMap->Bind(aShape, aShapeAttribs);
     }
-    myFaceList.Append(aFace);
-    myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayId, aFace);
-    myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayIdWithMat, aFace);
-    thePrimArrayShape = aFace;
+    myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayId, aShape);
+    myShapeMap[ShapeMapGroup_PrimArray].Bind(aPrimArrayIdWithMat, aShape);
+    thePrimArrayShape = aShape;
   }
   return true;
 }
@@ -2147,7 +2201,15 @@ bool RWGltf_GltfJsonParser::gltfParseAccessor(
   }
   else if (theType == RWGltf_GltfArrayType_Indices)
   {
-    theMeshData->SetNbDeferredTriangles((Standard_Integer)(aStruct.Count / 3));
+    if (theMeshData->PrimitiveMode() == RWGltf_GltfPrimitiveMode_Triangles)
+    {
+      theMeshData->SetNbDeferredTriangles((Standard_Integer)(aStruct.Count / 3));
+    }
+    else
+    {
+      theMeshData->SetNbDeferredNodes((Standard_Integer)(aStruct.Count));
+      theMeshData->SetNbDeferredTriangles(0);
+    }
   }
 
   const RWGltf_JsonValue* aBufferView =
index c4f4f0c14b18211658ecac529de716a80b54a6a8..9826a18fde0ddadc9e15ec1cb134ffd88d7d93b6 100644 (file)
@@ -104,7 +104,8 @@ Handle(Poly_Triangulation) RWGltf_GltfLatePrimitiveArray::LoadStreamData() const
   {
     return Handle(Poly_Triangulation)();
   }
-  Handle(Poly_Triangulation) aResult = createNewEntity();
+
+  Handle(RWMesh_TriangulationSource) aResult = new RWMesh_TriangulationSource();
   if (!aGltfReader->LoadStreamData(this, aResult))
   {
     return Handle(Poly_Triangulation)();
index 62d7804dbe6e9ccfaa710c7115d6aa5cf8f7f8d3..f5e33dbe182931b59030c1f41e694d1e6376a469 100644 (file)
@@ -84,7 +84,7 @@ public:
   //! that can be loaded using LoadDeferredData().
   virtual Standard_Boolean HasDeferredData() const Standard_OVERRIDE
   {
-    return !myData.IsEmpty() && RWMesh_TriangulationSource::HasDeferredData();
+    return !myData.IsEmpty() && (NbDeferredTriangles() > 0 || NbDeferredNodes() > 0);
   }
 
   //! Load primitive array saved as stream buffer to new triangulation object.
index 36fe83e413bf921765c92ad774da9cc170ae33f2..0bc0a5c08261d1c3594d8caa85bc56aa41a1c0a4 100644 (file)
@@ -583,8 +583,10 @@ bool RWGltf_TriangulationReader::readBuffer(
   RWGltf_GltfArrayType                         theType) const
 
 {
-  const TCollection_AsciiString& aName = theSourceMesh->Id();
-  if (theSourceMesh->PrimitiveMode() != RWGltf_GltfPrimitiveMode_Triangles)
+  const TCollection_AsciiString& aName     = theSourceMesh->Id();
+  const RWGltf_GltfPrimitiveMode aPrimMode = theSourceMesh->PrimitiveMode();
+  if (aPrimMode != RWGltf_GltfPrimitiveMode_Triangles && aPrimMode != RWGltf_GltfPrimitiveMode_Lines
+      && aPrimMode != RWGltf_GltfPrimitiveMode_Points)
   {
     Message::SendWarning(TCollection_AsciiString("Buffer '") + aName
                          + "' skipped unsupported primitive array");
@@ -608,37 +610,48 @@ bool RWGltf_TriangulationReader::readBuffer(
           return false;
         }
 
-        const Standard_Integer aNbTris = (Standard_Integer)(theAccessor.Count / 3);
-        if (!setNbTriangles(theDestMesh, aNbTris))
+        const Standard_Boolean isTriangles = aPrimMode == RWGltf_GltfPrimitiveMode_Triangles;
+        const Standard_Integer aCounter    = isTriangles ? (Standard_Integer)(theAccessor.Count / 3)
+                                                         : (Standard_Integer)(theAccessor.Count);
+        if ((isTriangles && !setNbTriangles(theDestMesh, aCounter))
+            || !setNbEdges(theDestMesh, aCounter))
         {
           return false;
         }
         const size_t aStride =
           theAccessor.ByteStride != 0 ? theAccessor.ByteStride : sizeof(uint16_t);
         Standard_ReadBuffer aBuffer(theAccessor.Count * aStride, aStride);
-        Standard_Integer    aLastTriIndex = 0;
-        for (Standard_Integer aTriIter = 0; aTriIter < aNbTris; ++aTriIter)
+        Standard_Integer    aLastIndex = 0;
+        for (Standard_Integer aTriIter = 0; aTriIter < aCounter; ++aTriIter)
         {
-          if (const uint16_t* anIndex0 = aBuffer.ReadChunk<uint16_t>(theStream))
-          {
-            aVec3.ChangeValue(1) = THE_LOWER_NODE_INDEX + *anIndex0;
-          }
-          if (const uint16_t* anIndex1 = aBuffer.ReadChunk<uint16_t>(theStream))
-          {
-            aVec3.ChangeValue(2) = THE_LOWER_NODE_INDEX + *anIndex1;
-          }
-          if (const uint16_t* anIndex2 = aBuffer.ReadChunk<uint16_t>(theStream))
-          {
-            aVec3.ChangeValue(3) = THE_LOWER_NODE_INDEX + *anIndex2;
+          Standard_Integer wasSet = false;
+          if (isTriangles)
+          {
+            for (Standard_Integer anIter = 1; anIter <= 3; ++anIter)
+            {
+              const uint16_t* anIndex = aBuffer.ReadChunk<uint16_t>(theStream);
+              if (anIndex == nullptr)
+              {
+                reportError(TCollection_AsciiString("Buffer '") + aName + "' reading error.");
+                return false;
+              }
+              aVec3.ChangeValue(anIter) = THE_LOWER_NODE_INDEX + *anIndex;
+            }
+            wasSet = setTriangle(theDestMesh, THE_LOWER_TRI_INDEX + aLastIndex, aVec3);
           }
           else
           {
-            reportError(TCollection_AsciiString("Buffer '") + aName + "' reading error.");
-            return false;
+            const uint16_t* anIndex = aBuffer.ReadChunk<uint16_t>(theStream);
+            if (anIndex == nullptr)
+            {
+              reportError(TCollection_AsciiString("Buffer '") + aName + "' reading error.");
+              return false;
+            }
+            wasSet = setEdge(theDestMesh,
+                             THE_LOWER_TRI_INDEX + aLastIndex,
+                             THE_LOWER_NODE_INDEX + *anIndex);
           }
 
-          const Standard_Integer wasSet =
-            setTriangle(theDestMesh, THE_LOWER_TRI_INDEX + aLastTriIndex, aVec3);
           if (!wasSet)
           {
             reportError(TCollection_AsciiString("Buffer '") + aName
@@ -646,13 +659,13 @@ bool RWGltf_TriangulationReader::readBuffer(
           }
           if (wasSet > 0)
           {
-            aLastTriIndex++;
+            aLastIndex++;
           }
         }
-        const Standard_Integer aNbDegenerate = aNbTris - aLastTriIndex;
+        const Standard_Integer aNbDegenerate = aCounter - aLastIndex;
         if (aNbDegenerate > 0)
         {
-          if (aNbDegenerate == aNbTris)
+          if (aNbDegenerate == aCounter)
           {
             Message::SendWarning(TCollection_AsciiString("Buffer '") + aName
                                  + "' has been skipped (all elements are degenerative in)");
@@ -666,7 +679,7 @@ bool RWGltf_TriangulationReader::readBuffer(
               + " degenerate triangles have been skipped while reading glTF triangulation '" + aName
               + "'");
           }
-          if (!setNbTriangles(theDestMesh, aLastTriIndex, true))
+          if (!setNbTriangles(theDestMesh, aLastIndex, true))
           {
             return false;
           }
index 317b548d8ee79aff2a64caea41c76d4850828ff9..d3331388dc02d91777eaf53b63381fd869e031da 100644 (file)
@@ -112,7 +112,7 @@ protected:
     const Handle(OSD_FileSystem)&                theFileSystem) const;
 
 protected:
-  Handle(Poly_Triangulation) myTriangulation;
+  Handle(RWMesh_TriangulationSource) myTriangulation;
 };
 
 #endif // _RWGltf_TriangulationReader_HeaderFile
index b81f197b8e1f7b3c0eee84919330d789da57a6c1..575c83e13a8b033da47d2baf84bd1e381489f8b0 100644 (file)
@@ -162,3 +162,37 @@ bool RWMesh_TriangulationReader::finalizeLoading(
   }
   return true;
 }
+
+// =======================================================================
+// function : setNbEdges
+// purpose  :
+// =======================================================================
+bool RWMesh_TriangulationReader::setNbEdges(const Handle(Poly_Triangulation)& theMesh,
+                                            const Standard_Integer            theNbTris,
+                                            const Standard_Boolean            theToCopyData) const
+{
+  Handle(RWMesh_TriangulationSource) aMesh = Handle(RWMesh_TriangulationSource)::DownCast(theMesh);
+  if (theNbTris >= 1)
+  {
+    aMesh->ResizeEdges(theNbTris, theToCopyData);
+    return true;
+  }
+  return false;
+}
+
+// =======================================================================
+// function : setEdge
+// purpose  :
+// =======================================================================
+Standard_Integer RWMesh_TriangulationReader::setEdge(const Handle(Poly_Triangulation)& theMesh,
+                                                     const Standard_Integer            theIndex,
+                                                     const Standard_Integer theEdge) const
+{
+  Handle(RWMesh_TriangulationSource) aMesh = Handle(RWMesh_TriangulationSource)::DownCast(theMesh);
+  if (theEdge < 1 || theEdge > theMesh->NbNodes())
+  {
+    return 0;
+  }
+  aMesh->SetEdge(theIndex, theEdge);
+  return 1;
+}
index 1d3eec5f9997642108e78ed42672a92dbf192508..39da96095163465ba4fb6f380f2b3119cb64384e 100644 (file)
@@ -283,6 +283,25 @@ protected: //! @name interface for filling triangulation data
     return 1;
   }
 
+  //! Resizes array of edges to specified size.
+  //! @param[in] theMesh  triangulation source to be modified
+  //! @param[in] theNbEdges  elements number
+  //! @param[in] theToCopyData  copy old edges into new array
+  //! @return TRUE in case of success operation
+  Standard_EXPORT virtual bool setNbEdges(const Handle(Poly_Triangulation)& theMesh,
+                                          const Standard_Integer            theNbEdges,
+                                          const Standard_Boolean theToCopyData = false) const;
+
+  //! Adds edge element.
+  //! @param[in] theMesh  triangulation source to be modified
+  //! @param theIndex     edge index starting from 1
+  //! @param theEdge      edge nodes starting from 1
+  //! @return 0 if node indexes are out of range,
+  //!         1 in case of success operation.
+  Standard_EXPORT virtual Standard_Integer setEdge(const Handle(Poly_Triangulation)& theMesh,
+                                                   const Standard_Integer            theIndex,
+                                                   const Standard_Integer            theEdge) const;
+
 protected:
   RWMesh_CoordinateSystemConverter myCoordSysConverter; //!< coordinate system converter
   // clang-format off
index 01f73e9e8d2380284664fdfbcd6b1f71fb5d1755..7d04ebaad888f656f0064ad7d54de201dff1f35e 100644 (file)
@@ -50,9 +50,25 @@ Standard_Boolean RWMesh_TriangulationSource::loadDeferredData(
   {
     return false;
   }
-  if (myReader->Load(this, theDestTriangulation, theFileSystem))
+  Handle(RWMesh_TriangulationSource) aDestTriangulation =
+    Handle(RWMesh_TriangulationSource)::DownCast(theDestTriangulation);
+  if (aDestTriangulation.IsNull())
+  {
+    return false;
+  }
+  if (myReader->Load(this, aDestTriangulation, theFileSystem))
   {
     return true;
   }
   return false;
 }
+
+// =======================================================================
+// function : ResizeEdges
+// purpose  :
+// =======================================================================
+void RWMesh_TriangulationSource::ResizeEdges(Standard_Integer theNbEdges,
+                                             Standard_Boolean theToCopyOld)
+{
+  myEdges.Resize(1, theNbEdges, theToCopyOld);
+}
index 97ff4658859dae23caf2474c7b62684562ea570d..a38c2e0497da076c827f23df82edc2be00768c0a 100644 (file)
@@ -15,6 +15,7 @@
 #define _RWMesh_TriangulationSource_HeaderFile
 
 #include <Poly_Triangulation.hxx>
+#include <NCollection_Array1.hxx>
 
 class RWMesh_TriangulationReader;
 
@@ -44,6 +45,28 @@ public:
   //! Gets access to number of degenerated triangles to collect them during data reading.
   Standard_Integer& ChangeDegeneratedTriNb() { return myStatisticOfDegeneratedTriNb; }
 
+  //! Returns TRUE if triangulation has some geometry.
+  virtual Standard_Boolean HasGeometry() const Standard_OVERRIDE
+  {
+    return !myNodes.IsEmpty() && (!myTriangles.IsEmpty() || !myEdges.IsEmpty());
+  }
+
+  //! Returns the number of edges for this triangulation.
+  Standard_Integer NbEdges() const { return myEdges.Length(); }
+
+  //! Returns edge at the given index.
+  //! @param[in] theIndex edge index within [1, NbEdges()] range
+  //! @return edge node indices, with each node defined within [1, NbNodes()] range
+  Standard_Integer Edge(Standard_Integer theIndex) const { return myEdges.Value(theIndex); }
+
+  //! Sets an edge.
+  //! @param[in] theIndex edge index within [1, NbEdges()] range
+  //! @param[in] theEdge edge node indices, with each node defined within [1, NbNodes()] range
+  void SetEdge(Standard_Integer theIndex, Standard_Integer theEdge)
+  {
+    myEdges.SetValue(theIndex, theEdge);
+  }
+
 public: //! @name late-load deferred data interface
   //! Returns number of nodes for deferred loading.
   //! Note: this is estimated values defined in object header, which might be different from
@@ -66,6 +89,15 @@ public: //! @name late-load deferred data interface
   //! Sets number of triangles for deferred loading.
   void SetNbDeferredTriangles(const Standard_Integer theNbTris) { myNbDefTriangles = theNbTris; }
 
+  //! Returns an internal array of edges.
+  //! Edge()/SetEdge() should be used instead in portable code.
+  NCollection_Array1<Standard_Integer>& InternalEdges() { return myEdges; }
+
+  //! Method resizing an internal array of triangles.
+  //! @param[in] theNbTriangles  new number of triangles
+  //! @param[in] theToCopyOld    copy old triangles into the new array
+  Standard_EXPORT void ResizeEdges(Standard_Integer theNbEdges, Standard_Boolean theToCopyOld);
+
 protected:
   //! Loads triangulation data from deferred storage using specified shared input file system.
   Standard_EXPORT virtual Standard_Boolean loadDeferredData(
@@ -73,10 +105,11 @@ protected:
     const Handle(Poly_Triangulation)& theDestTriangulation) const Standard_OVERRIDE;
 
 protected:
-  Handle(RWMesh_TriangulationReader) myReader;
-  Standard_Integer                   myNbDefNodes;
-  Standard_Integer                   myNbDefTriangles;
-  mutable Standard_Integer           myStatisticOfDegeneratedTriNb;
+  Handle(RWMesh_TriangulationReader)   myReader;
+  NCollection_Array1<Standard_Integer> myEdges;
+  Standard_Integer                     myNbDefNodes;
+  Standard_Integer                     myNbDefTriangles;
+  mutable Standard_Integer             myStatisticOfDegeneratedTriNb;
 };
 
 #endif // _RWMesh_TriangulationSource_HeaderFile
index 50daa2f2e6186d489211324852ed106d969e2248..cf8297e1cec5c7fd4e8e5aa90d5bd60aa29881ed 100644 (file)
@@ -19,12 +19,46 @@ Close     DD
 
 ReadGltf  D "$aTmpGltf"
 XGetOneShape s D
-checknbshapes s -face 6 -compound 2
+checknbshapes s -face 6 -vertex 8 -compound 11
 
 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"
-PART COMPOUND 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"
 
 Free Shapes: 1
 ASSEMBLY COMPOUND  0:1:1:1 "empty_tmp.glb"
diff --git a/tests/de_mesh/gltf_write/primitives b/tests/de_mesh/gltf_write/primitives
new file mode 100644 (file)
index 0000000..1aacab6
--- /dev/null
@@ -0,0 +1,39 @@
+puts "========"
+puts "Data Exchange, RWGltf_CafReader - Edge and Vertex support"
+puts "========"
+
+vclear
+vclose ALL
+Close *
+
+set aTmpGltf "${imagedir}/${casename}_tmp.glb"
+
+vertex v1 2 0 0
+vertex v2 2 1 0
+vertex v3 3 1 0
+vertex v4 3 0 0
+
+polygon3d p1 2 0 0 0 1 1 0
+mkedge e1 p1
+polygon3d p2 2 0 1 0 1 0 0
+mkedge e2 p2
+
+XNewDoc D
+XAddShape D e1
+XAddShape D e2
+XAddShape D v1
+XAddShape D v2
+XAddShape D v3
+XAddShape D v4
+SetName D [XFindShape D e1] "edge_1"
+SetName D [XFindShape D e2] "edge_2"
+SetName D [XFindShape D v1] "vertex_1"
+SetName D [XFindShape D v2] "vertex_2"
+SetName D [XFindShape D v3] "vertex_3"
+SetName D [XFindShape D v4] "vertex_4"
+
+WriteGltf D "$aTmpGltf"
+
+ReadGltf D1 "$aTmpGltf"
+XGetOneShape s D1
+checknbshapes s -vertex 4 -edge 2
index 732c1f077120786d0a4b5b6317ee1e69d77f54f5..f93d3de1481420af94bd5cd4506703b9cf246e3d 100644 (file)
@@ -1,6 +1,6 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename bug28389_CONFIDENTIAL_SHEET_METAL_F3D.stp
-set ref_size 86338
+set ref_size 103329
 set check_metadata 1
 set ref_metadata {Property for [0:1:1:1]:
 yCenterOfGravity : 0.1148447698
index 8db299a681e86a2cb2b341db7d68e26cfaa794c5..6297ee0c6829463f2f31bf7a66c9b1365e6009dd 100644 (file)
@@ -1,6 +1,6 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename bug28444_nist_ftc_06_asme1_ct5240_rd.stp
-set ref_size 85605
+set ref_size 118300
 set check_metadata 1
 set ref_metadata {Property for [0:1:1:1]:
 yCenterOfGravity : 0.0289950044
index 3a89e74c07f27cc90ee675019f7cb10e4dc6f0c5..8c55e366abdd7f87fccc4efd0d3d78064904d00d 100644 (file)
@@ -1,4 +1,4 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename bug29525_rev_part_neu_01.prt_converted_from_datakit.stp
-set ref_size 81056
+set ref_size 90657
 set check_metadata 0
index 163cf41daa9557f6968ce43a876849b477af139d..7208d25cf5cd54da92ea512a636fcde1eef508c0 100644 (file)
@@ -1,6 +1,6 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename sp7_04-do-242.stp
-set ref_size 224869
+set ref_size 246373
 set check_metadata 1
 set ref_metadata {Property for [0:1:1:1]:
 PRO_MP_ALT_COGX : - >
index ff03351666a6fa3ae7d13f0d2abff0af0bfe8572..aa47f549e265abbb824a61440cdb88900cd5bff5 100644 (file)
@@ -39,7 +39,8 @@ if { $dump_file == 1 } {
     close $fd_stream
     puts "Error : Running in regeneration mode, comparison was not performed!"
 } else {
-    if {$aSize != $ref_size} {
+    set tolerance [expr {min(max(0.001 * $ref_size, 1), 100)}]
+    if {abs($aSize - $ref_size) > $tolerance} {
         puts "Error: Wrong file size $aSize instead of $ref_size"
     }