From c86c669d2f44fd4af123a57ee35ad58e949c3e90 Mon Sep 17 00:00:00 2001 From: mzernova Date: Sun, 5 Jan 2025 22:47:18 +0000 Subject: [PATCH] GLTF Import - Edge and Vertex support #242 Added functionality to import Points and Lines from GLTF format --- src/RWGltf/RWGltf_GltfJsonParser.cxx | 123 ++++++++++++++----- src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx | 3 +- src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx | 2 +- src/RWGltf/RWGltf_TriangulationReader.cxx | 71 ++++++----- src/RWGltf/RWGltf_TriangulationReader.hxx | 2 +- src/RWMesh/RWMesh_TriangulationReader.cxx | 34 +++++ src/RWMesh/RWMesh_TriangulationReader.hxx | 19 +++ src/RWMesh/RWMesh_TriangulationSource.cxx | 17 ++- src/RWMesh/RWMesh_TriangulationSource.hxx | 42 ++++++- tests/de_mesh/gltf_write/empty | 38 +++++- tests/de_mesh/gltf_write/primitives | 39 ++++++ tests/metadata/gltf/A2 | 2 +- tests/metadata/gltf/A3 | 2 +- tests/metadata/gltf/A4 | 2 +- tests/metadata/gltf/A7 | 2 +- tests/metadata/gltf/end | 3 +- 16 files changed, 329 insertions(+), 72 deletions(-) create mode 100644 tests/de_mesh/gltf_write/primitives diff --git a/src/RWGltf/RWGltf_GltfJsonParser.cxx b/src/RWGltf/RWGltf_GltfJsonParser.cxx index 36f6a41f13..cf56f32bb3 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.cxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.cxx @@ -15,7 +15,7 @@ #include "RWGltf_GltfJsonParser.hxx" #include -#include +#include #include #include #include @@ -24,11 +24,13 @@ #include #include #include -#include +#include #include #include #include +#include #include +#include #include @@ -1581,7 +1583,10 @@ 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 +1843,9 @@ 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 +1894,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; + aShapeAttribs.Style.SetMaterial (aMat); + myAttribMap->Bind (aShapeCopy, aShapeAttribs); + myShapeMap[ShapeMapGroup_PrimArray].Bind (aPrimArrayIdWithMat, aShapeCopy); + thePrimArrayShape = aShapeCopy; } return true; } @@ -1978,31 +1979,87 @@ 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 (myAttribMap != NULL && aMeshData->HasStyle()) + 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; aShapeAttribs.RawName = theMeshName; // assign material and not color - // aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor()); + //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 +2204,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 = diff --git a/src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx b/src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx index c4f4f0c14b..9826a18fde 100644 --- a/src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx +++ b/src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx @@ -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)(); diff --git a/src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx b/src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx index 62d7804dbe..f5e33dbe18 100644 --- a/src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx +++ b/src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx @@ -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. diff --git a/src/RWGltf/RWGltf_TriangulationReader.cxx b/src/RWGltf/RWGltf_TriangulationReader.cxx index 36fe83e413..7d42a8010f 100644 --- a/src/RWGltf/RWGltf_TriangulationReader.cxx +++ b/src/RWGltf/RWGltf_TriangulationReader.cxx @@ -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,50 @@ 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) + const size_t aStride = theAccessor.ByteStride != 0 + ? theAccessor.ByteStride + : sizeof(uint16_t); + Standard_ReadBuffer aBuffer (theAccessor.Count * aStride, aStride); + Standard_Integer aLastIndex = 0; + for (Standard_Integer aTriIter = 0; aTriIter < aCounter; ++aTriIter) { - if (const uint16_t* anIndex0 = aBuffer.ReadChunk(theStream)) - { - aVec3.ChangeValue(1) = THE_LOWER_NODE_INDEX + *anIndex0; - } - if (const uint16_t* anIndex1 = aBuffer.ReadChunk(theStream)) - { - aVec3.ChangeValue(2) = THE_LOWER_NODE_INDEX + *anIndex1; - } - if (const uint16_t* anIndex2 = aBuffer.ReadChunk(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(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(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 +661,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 +681,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; } diff --git a/src/RWGltf/RWGltf_TriangulationReader.hxx b/src/RWGltf/RWGltf_TriangulationReader.hxx index 317b548d8e..d3331388dc 100644 --- a/src/RWGltf/RWGltf_TriangulationReader.hxx +++ b/src/RWGltf/RWGltf_TriangulationReader.hxx @@ -112,7 +112,7 @@ protected: const Handle(OSD_FileSystem)& theFileSystem) const; protected: - Handle(Poly_Triangulation) myTriangulation; + Handle(RWMesh_TriangulationSource) myTriangulation; }; #endif // _RWGltf_TriangulationReader_HeaderFile diff --git a/src/RWMesh/RWMesh_TriangulationReader.cxx b/src/RWMesh/RWMesh_TriangulationReader.cxx index b81f197b8e..575c83e13a 100644 --- a/src/RWMesh/RWMesh_TriangulationReader.cxx +++ b/src/RWMesh/RWMesh_TriangulationReader.cxx @@ -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; +} diff --git a/src/RWMesh/RWMesh_TriangulationReader.hxx b/src/RWMesh/RWMesh_TriangulationReader.hxx index 1d3eec5f99..3974ab949b 100644 --- a/src/RWMesh/RWMesh_TriangulationReader.hxx +++ b/src/RWMesh/RWMesh_TriangulationReader.hxx @@ -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 diff --git a/src/RWMesh/RWMesh_TriangulationSource.cxx b/src/RWMesh/RWMesh_TriangulationSource.cxx index 01f73e9e8d..191c72d6e0 100644 --- a/src/RWMesh/RWMesh_TriangulationSource.cxx +++ b/src/RWMesh/RWMesh_TriangulationSource.cxx @@ -50,9 +50,24 @@ 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); +} diff --git a/src/RWMesh/RWMesh_TriangulationSource.hxx b/src/RWMesh/RWMesh_TriangulationSource.hxx index 97ff465885..debeacea92 100644 --- a/src/RWMesh/RWMesh_TriangulationSource.hxx +++ b/src/RWMesh/RWMesh_TriangulationSource.hxx @@ -15,6 +15,7 @@ #define _RWMesh_TriangulationSource_HeaderFile #include +#include 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,16 @@ 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& 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 +106,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 myEdges; + Standard_Integer myNbDefNodes; + Standard_Integer myNbDefTriangles; + mutable Standard_Integer myStatisticOfDegeneratedTriNb; }; #endif // _RWMesh_TriangulationSource_HeaderFile diff --git a/tests/de_mesh/gltf_write/empty b/tests/de_mesh/gltf_write/empty index 50daa2f2e6..cf8297e1ce 100644 --- a/tests/de_mesh/gltf_write/empty +++ b/tests/de_mesh/gltf_write/empty @@ -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 index 0000000000..1aacab6d1e --- /dev/null +++ b/tests/de_mesh/gltf_write/primitives @@ -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 diff --git a/tests/metadata/gltf/A2 b/tests/metadata/gltf/A2 index 732c1f0771..f93d3de148 100644 --- a/tests/metadata/gltf/A2 +++ b/tests/metadata/gltf/A2 @@ -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 diff --git a/tests/metadata/gltf/A3 b/tests/metadata/gltf/A3 index 8db299a681..6297ee0c68 100644 --- a/tests/metadata/gltf/A3 +++ b/tests/metadata/gltf/A3 @@ -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 diff --git a/tests/metadata/gltf/A4 b/tests/metadata/gltf/A4 index 3a89e74c07..8c55e366ab 100644 --- a/tests/metadata/gltf/A4 +++ b/tests/metadata/gltf/A4 @@ -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 diff --git a/tests/metadata/gltf/A7 b/tests/metadata/gltf/A7 index 163cf41daa..7208d25cf5 100644 --- a/tests/metadata/gltf/A7 +++ b/tests/metadata/gltf/A7 @@ -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 : - > diff --git a/tests/metadata/gltf/end b/tests/metadata/gltf/end index ff03351666..aa47f549e2 100644 --- a/tests/metadata/gltf/end +++ b/tests/metadata/gltf/end @@ -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" }