diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafWriter.cxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafWriter.cxx index d2cff43a66..630eca3d5a 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafWriter.cxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafWriter.cxx @@ -278,6 +278,23 @@ TCollection_AsciiString RWGltf_CafWriter::formatName(RWMesh_NameFormat theFormat //================================================================================================= +TopAbs_ShapeEnum RWGltf_CafWriter::getShapeType(const TopoDS_Shape& theShape) const +{ + TopAbs_ShapeEnum aShapeType = theShape.ShapeType(); + if (aShapeType == TopAbs_COMPOUND) + { + // Compounds are created in the case of merged faces. + // Assuming that all shapes in the compound are of the same type + TopoDS_Iterator it(theShape); + Standard_ProgramError_Raise_if(!it.More(), "Empty compound"); + aShapeType = it.Value().ShapeType(); + } + + return aShapeType; +} + +//================================================================================================= + Standard_Boolean RWGltf_CafWriter::toSkipShape(const RWMesh_ShapeIterator& theShapeIter) const { return theShapeIter.IsEmpty(); @@ -287,19 +304,17 @@ Standard_Boolean RWGltf_CafWriter::toSkipShape(const RWMesh_ShapeIterator& theSh Standard_Boolean RWGltf_CafWriter::hasTriangulation(const RWGltf_GltfFace& theGltfFace) const { - switch (theGltfFace.Shape.ShapeType()) + TopAbs_ShapeEnum shapeType = getShapeType(theGltfFace.Shape); + + switch (shapeType) { - case TopAbs_COMPOUND: - case TopAbs_COMPSOLID: - case TopAbs_SOLID: - case TopAbs_SHELL: case TopAbs_FACE: return true; - case TopAbs_WIRE: case TopAbs_EDGE: case TopAbs_VERTEX: - default: return false; + default: + throw Standard_ProgramError("Unsupported shape type"); } } @@ -499,21 +514,29 @@ void RWGltf_CafWriter::saveTriangleIndices(RWGltf_GltfFace& theGltfFac void RWGltf_CafWriter::saveEdgeIndices(RWGltf_GltfFace& theGltfFace, std::ostream& theBinFile, - const RWMesh_EdgeIterator& theFaceIter) + const RWMesh_EdgeIterator& theEdgeIter) { - const Standard_Integer aNodeFirst = theGltfFace.NbIndexedNodes - theFaceIter.ElemLower(); - theGltfFace.NbIndexedNodes += theFaceIter.NbNodes(); - theGltfFace.Indices.Count += theFaceIter.NbNodes(); - for (Standard_Integer anElemIter = theFaceIter.ElemLower(); anElemIter <= theFaceIter.ElemUpper(); - ++anElemIter) + const Standard_Integer aNodeFirst = theGltfFace.NbIndexedNodes; + theGltfFace.NbIndexedNodes += theEdgeIter.NbNodes(); + + const Standard_Integer numSegments = Max(0, theEdgeIter.NbNodes() - 1); + // each segment writes two indices + theGltfFace.Indices.Count += numSegments * 2; + + for (Standard_Integer i = 0; i < numSegments; ++i) { + Standard_Integer i0 = aNodeFirst + i; + Standard_Integer i1 = aNodeFirst + i + 1; + if (theGltfFace.Indices.ComponentType == RWGltf_GltfAccessorCompType_UInt16) { - writeVertex(theBinFile, (uint16_t)(anElemIter + aNodeFirst)); + writeVertex(theBinFile, (uint16_t)i0); + writeVertex(theBinFile, (uint16_t)i1); } else { - writeVertex(theBinFile, anElemIter + aNodeFirst); + writeVertex(theBinFile, i0); + writeVertex(theBinFile, i1); } } } @@ -522,12 +545,13 @@ void RWGltf_CafWriter::saveEdgeIndices(RWGltf_GltfFace& theGltfFace, void RWGltf_CafWriter::saveVertexIndices(RWGltf_GltfFace& theGltfFace, std::ostream& theBinFile, - const RWMesh_VertexIterator& theFaceIter) + const RWMesh_VertexIterator& theVertexIter) { - const Standard_Integer aNodeFirst = theGltfFace.NbIndexedNodes - theFaceIter.ElemLower(); - theGltfFace.NbIndexedNodes += theFaceIter.NbNodes(); - theGltfFace.Indices.Count += theFaceIter.NbNodes(); - for (Standard_Integer anElemIter = theFaceIter.ElemLower(); anElemIter <= theFaceIter.ElemUpper(); + const Standard_Integer aNodeFirst = theGltfFace.NbIndexedNodes - theVertexIter.ElemLower(); + theGltfFace.NbIndexedNodes += theVertexIter.NbNodes(); + theGltfFace.Indices.Count += theVertexIter.NbNodes(); + for (Standard_Integer anElemIter = theVertexIter.ElemLower(); + anElemIter <= theVertexIter.ElemUpper(); ++anElemIter) { if (theGltfFace.Indices.ComponentType == RWGltf_GltfAccessorCompType_UInt16) @@ -545,7 +569,7 @@ void RWGltf_CafWriter::saveVertexIndices(RWGltf_GltfFace& theGltfFac void RWGltf_CafWriter::saveIndices(RWGltf_GltfFace& theGltfFace, std::ostream& theBinFile, - const RWMesh_ShapeIterator& theFaceIter, + const RWMesh_ShapeIterator& theShapeIter, Standard_Integer& theAccessorNb, const std::shared_ptr& theMesh) { @@ -574,17 +598,18 @@ void RWGltf_CafWriter::saveIndices(RWGltf_GltfFace& } } - if (const RWMesh_FaceIterator* aFaceIter = dynamic_cast(&theFaceIter)) + if (const RWMesh_FaceIterator* aFaceIter = + dynamic_cast(&theShapeIter)) { saveTriangleIndices(theGltfFace, theBinFile, *aFaceIter, theMesh); } else if (const RWMesh_EdgeIterator* anEdgeIter = - dynamic_cast(&theFaceIter)) + dynamic_cast(&theShapeIter)) { saveEdgeIndices(theGltfFace, theBinFile, *anEdgeIter); } else if (const RWMesh_VertexIterator* aVertexIter = - dynamic_cast(&theFaceIter)) + dynamic_cast(&theShapeIter)) { saveVertexIndices(theGltfFace, theBinFile, *aVertexIter); } @@ -963,7 +988,9 @@ bool RWGltf_CafWriter::writeBinData(const Handle(TDocStd_Document)& theDocument, aWrittenPrimData.Bind(aGltfFace->Shape, aGltfFace); Standard_Boolean wasWrittenNonFace = Standard_False; - switch (aGltfFace->Shape.ShapeType()) + TopAbs_ShapeEnum shapeType = getShapeType(aGltfFace->Shape); + + switch (shapeType) { case TopAbs_EDGE: { RWMesh_EdgeIterator anIter(aGltfFace->Shape, aGltfFace->Style); @@ -2027,10 +2054,13 @@ void RWGltf_CafWriter::writePrimArray(const RWGltf_GltfFace& theGltfFace } myWriter->Key("mode"); - switch (theGltfFace.Shape.ShapeType()) + + TopAbs_ShapeEnum shapeType = getShapeType(theGltfFace.Shape); + + switch (shapeType) { case TopAbs_EDGE: - myWriter->Int(RWGltf_GltfPrimitiveMode_LineStrip); + myWriter->Int(RWGltf_GltfPrimitiveMode_Lines); break; case TopAbs_VERTEX: myWriter->Int(RWGltf_GltfPrimitiveMode_Points); diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafWriter.hxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafWriter.hxx index b06838fb45..5c4f8e0be6 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafWriter.hxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafWriter.hxx @@ -209,6 +209,9 @@ protected: const Message_ProgressRange& theProgress); protected: + //! Returns the underlying shape in case of a compound. + Standard_EXPORT virtual TopAbs_ShapeEnum getShapeType(const TopoDS_Shape& theShape) const; + //! Return TRUE if face shape should be skipped (e.g. because it is invalid or empty). Standard_EXPORT virtual Standard_Boolean toSkipShape( const RWMesh_ShapeIterator& theShapeIter) const; diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx index 922ac6d27f..e517be7bf5 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx @@ -1808,7 +1808,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th } } if (aMode != RWGltf_GltfPrimitiveMode_Triangles && aMode != RWGltf_GltfPrimitiveMode_Lines - && aMode != RWGltf_GltfPrimitiveMode_LineStrip && aMode != RWGltf_GltfPrimitiveMode_Points) + && aMode != RWGltf_GltfPrimitiveMode_Points) { Message::SendWarning(TCollection_AsciiString() + "Primitive array within Mesh '" + theMeshId + "' skipped due to unsupported mode"); @@ -1976,8 +1976,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th aShape = aVertices; break; } - case RWGltf_GltfPrimitiveMode_Lines: - case RWGltf_GltfPrimitiveMode_LineStrip: { + case RWGltf_GltfPrimitiveMode_Lines: { TColgp_Array1OfPnt aNodes(1, aMeshData->NbEdges()); for (Standard_Integer anEdgeIdx = 1; anEdgeIdx <= aMeshData->NbEdges(); ++anEdgeIdx) { @@ -2012,7 +2011,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th aShapeAttribs.RawName = theMeshName; // assign material and not color - if (aMode == RWGltf_GltfPrimitiveMode_Lines || aMode == RWGltf_GltfPrimitiveMode_LineStrip) + if (aMode == RWGltf_GltfPrimitiveMode_Lines) { aShapeAttribs.Style.SetColorCurv(aMeshData->BaseColor().GetRGB()); } diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx index 3542a26375..77dfdf4a3a 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx @@ -579,7 +579,6 @@ bool RWGltf_TriangulationReader::ReadStream( const TCollection_AsciiString& aName = theSourceMesh->Id(); const RWGltf_GltfPrimitiveMode aPrimMode = theSourceMesh->PrimitiveMode(); if (aPrimMode != RWGltf_GltfPrimitiveMode_Triangles && aPrimMode != RWGltf_GltfPrimitiveMode_Lines - && aPrimMode != RWGltf_GltfPrimitiveMode_LineStrip && aPrimMode != RWGltf_GltfPrimitiveMode_Points) { Message::SendWarning(TCollection_AsciiString("Buffer '") + aName