mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-06-05 11:24:17 +03:00
Data Exchange, GLTF - fix saving edges when Merge Faces is enabled #554
Removed check for LineStrip mode to force use of Lines for merged faces Updated primitive mode checks by removing LineStrip references Added getShapeType to correctly determine the underlying shape type from compounds and updated index calculation logic
This commit is contained in:
parent
7ed396b0eb
commit
4f2d4c1f4b
@ -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
|
Standard_Boolean RWGltf_CafWriter::toSkipShape(const RWMesh_ShapeIterator& theShapeIter) const
|
||||||
{
|
{
|
||||||
return theShapeIter.IsEmpty();
|
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
|
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:
|
case TopAbs_FACE:
|
||||||
return true;
|
return true;
|
||||||
case TopAbs_WIRE:
|
|
||||||
case TopAbs_EDGE:
|
case TopAbs_EDGE:
|
||||||
case TopAbs_VERTEX:
|
case TopAbs_VERTEX:
|
||||||
default:
|
|
||||||
return false;
|
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,
|
void RWGltf_CafWriter::saveEdgeIndices(RWGltf_GltfFace& theGltfFace,
|
||||||
std::ostream& theBinFile,
|
std::ostream& theBinFile,
|
||||||
const RWMesh_EdgeIterator& theFaceIter)
|
const RWMesh_EdgeIterator& theEdgeIter)
|
||||||
{
|
{
|
||||||
const Standard_Integer aNodeFirst = theGltfFace.NbIndexedNodes - theFaceIter.ElemLower();
|
const Standard_Integer aNodeFirst = theGltfFace.NbIndexedNodes;
|
||||||
theGltfFace.NbIndexedNodes += theFaceIter.NbNodes();
|
theGltfFace.NbIndexedNodes += theEdgeIter.NbNodes();
|
||||||
theGltfFace.Indices.Count += theFaceIter.NbNodes();
|
|
||||||
for (Standard_Integer anElemIter = theFaceIter.ElemLower(); anElemIter <= theFaceIter.ElemUpper();
|
const Standard_Integer numSegments = Max(0, theEdgeIter.NbNodes() - 1);
|
||||||
++anElemIter)
|
// 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)
|
if (theGltfFace.Indices.ComponentType == RWGltf_GltfAccessorCompType_UInt16)
|
||||||
{
|
{
|
||||||
writeVertex(theBinFile, (uint16_t)(anElemIter + aNodeFirst));
|
writeVertex(theBinFile, (uint16_t)i0);
|
||||||
|
writeVertex(theBinFile, (uint16_t)i1);
|
||||||
}
|
}
|
||||||
else
|
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,
|
void RWGltf_CafWriter::saveVertexIndices(RWGltf_GltfFace& theGltfFace,
|
||||||
std::ostream& theBinFile,
|
std::ostream& theBinFile,
|
||||||
const RWMesh_VertexIterator& theFaceIter)
|
const RWMesh_VertexIterator& theVertexIter)
|
||||||
{
|
{
|
||||||
const Standard_Integer aNodeFirst = theGltfFace.NbIndexedNodes - theFaceIter.ElemLower();
|
const Standard_Integer aNodeFirst = theGltfFace.NbIndexedNodes - theVertexIter.ElemLower();
|
||||||
theGltfFace.NbIndexedNodes += theFaceIter.NbNodes();
|
theGltfFace.NbIndexedNodes += theVertexIter.NbNodes();
|
||||||
theGltfFace.Indices.Count += theFaceIter.NbNodes();
|
theGltfFace.Indices.Count += theVertexIter.NbNodes();
|
||||||
for (Standard_Integer anElemIter = theFaceIter.ElemLower(); anElemIter <= theFaceIter.ElemUpper();
|
for (Standard_Integer anElemIter = theVertexIter.ElemLower();
|
||||||
|
anElemIter <= theVertexIter.ElemUpper();
|
||||||
++anElemIter)
|
++anElemIter)
|
||||||
{
|
{
|
||||||
if (theGltfFace.Indices.ComponentType == RWGltf_GltfAccessorCompType_UInt16)
|
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,
|
void RWGltf_CafWriter::saveIndices(RWGltf_GltfFace& theGltfFace,
|
||||||
std::ostream& theBinFile,
|
std::ostream& theBinFile,
|
||||||
const RWMesh_ShapeIterator& theFaceIter,
|
const RWMesh_ShapeIterator& theShapeIter,
|
||||||
Standard_Integer& theAccessorNb,
|
Standard_Integer& theAccessorNb,
|
||||||
const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh)
|
const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh)
|
||||||
{
|
{
|
||||||
@ -574,17 +598,18 @@ void RWGltf_CafWriter::saveIndices(RWGltf_GltfFace&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const RWMesh_FaceIterator* aFaceIter = dynamic_cast<const RWMesh_FaceIterator*>(&theFaceIter))
|
if (const RWMesh_FaceIterator* aFaceIter =
|
||||||
|
dynamic_cast<const RWMesh_FaceIterator*>(&theShapeIter))
|
||||||
{
|
{
|
||||||
saveTriangleIndices(theGltfFace, theBinFile, *aFaceIter, theMesh);
|
saveTriangleIndices(theGltfFace, theBinFile, *aFaceIter, theMesh);
|
||||||
}
|
}
|
||||||
else if (const RWMesh_EdgeIterator* anEdgeIter =
|
else if (const RWMesh_EdgeIterator* anEdgeIter =
|
||||||
dynamic_cast<const RWMesh_EdgeIterator*>(&theFaceIter))
|
dynamic_cast<const RWMesh_EdgeIterator*>(&theShapeIter))
|
||||||
{
|
{
|
||||||
saveEdgeIndices(theGltfFace, theBinFile, *anEdgeIter);
|
saveEdgeIndices(theGltfFace, theBinFile, *anEdgeIter);
|
||||||
}
|
}
|
||||||
else if (const RWMesh_VertexIterator* aVertexIter =
|
else if (const RWMesh_VertexIterator* aVertexIter =
|
||||||
dynamic_cast<const RWMesh_VertexIterator*>(&theFaceIter))
|
dynamic_cast<const RWMesh_VertexIterator*>(&theShapeIter))
|
||||||
{
|
{
|
||||||
saveVertexIndices(theGltfFace, theBinFile, *aVertexIter);
|
saveVertexIndices(theGltfFace, theBinFile, *aVertexIter);
|
||||||
}
|
}
|
||||||
@ -963,7 +988,9 @@ bool RWGltf_CafWriter::writeBinData(const Handle(TDocStd_Document)& theDocument,
|
|||||||
aWrittenPrimData.Bind(aGltfFace->Shape, aGltfFace);
|
aWrittenPrimData.Bind(aGltfFace->Shape, aGltfFace);
|
||||||
|
|
||||||
Standard_Boolean wasWrittenNonFace = Standard_False;
|
Standard_Boolean wasWrittenNonFace = Standard_False;
|
||||||
switch (aGltfFace->Shape.ShapeType())
|
TopAbs_ShapeEnum shapeType = getShapeType(aGltfFace->Shape);
|
||||||
|
|
||||||
|
switch (shapeType)
|
||||||
{
|
{
|
||||||
case TopAbs_EDGE: {
|
case TopAbs_EDGE: {
|
||||||
RWMesh_EdgeIterator anIter(aGltfFace->Shape, aGltfFace->Style);
|
RWMesh_EdgeIterator anIter(aGltfFace->Shape, aGltfFace->Style);
|
||||||
@ -2027,10 +2054,13 @@ void RWGltf_CafWriter::writePrimArray(const RWGltf_GltfFace& theGltfFace
|
|||||||
}
|
}
|
||||||
|
|
||||||
myWriter->Key("mode");
|
myWriter->Key("mode");
|
||||||
switch (theGltfFace.Shape.ShapeType())
|
|
||||||
|
TopAbs_ShapeEnum shapeType = getShapeType(theGltfFace.Shape);
|
||||||
|
|
||||||
|
switch (shapeType)
|
||||||
{
|
{
|
||||||
case TopAbs_EDGE:
|
case TopAbs_EDGE:
|
||||||
myWriter->Int(RWGltf_GltfPrimitiveMode_LineStrip);
|
myWriter->Int(RWGltf_GltfPrimitiveMode_Lines);
|
||||||
break;
|
break;
|
||||||
case TopAbs_VERTEX:
|
case TopAbs_VERTEX:
|
||||||
myWriter->Int(RWGltf_GltfPrimitiveMode_Points);
|
myWriter->Int(RWGltf_GltfPrimitiveMode_Points);
|
||||||
|
@ -209,6 +209,9 @@ protected:
|
|||||||
const Message_ProgressRange& theProgress);
|
const Message_ProgressRange& theProgress);
|
||||||
|
|
||||||
protected:
|
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).
|
//! Return TRUE if face shape should be skipped (e.g. because it is invalid or empty).
|
||||||
Standard_EXPORT virtual Standard_Boolean toSkipShape(
|
Standard_EXPORT virtual Standard_Boolean toSkipShape(
|
||||||
const RWMesh_ShapeIterator& theShapeIter) const;
|
const RWMesh_ShapeIterator& theShapeIter) const;
|
||||||
|
@ -1808,7 +1808,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aMode != RWGltf_GltfPrimitiveMode_Triangles && aMode != RWGltf_GltfPrimitiveMode_Lines
|
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
|
Message::SendWarning(TCollection_AsciiString() + "Primitive array within Mesh '" + theMeshId
|
||||||
+ "' skipped due to unsupported mode");
|
+ "' skipped due to unsupported mode");
|
||||||
@ -1976,8 +1976,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th
|
|||||||
aShape = aVertices;
|
aShape = aVertices;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RWGltf_GltfPrimitiveMode_Lines:
|
case RWGltf_GltfPrimitiveMode_Lines: {
|
||||||
case RWGltf_GltfPrimitiveMode_LineStrip: {
|
|
||||||
TColgp_Array1OfPnt aNodes(1, aMeshData->NbEdges());
|
TColgp_Array1OfPnt aNodes(1, aMeshData->NbEdges());
|
||||||
for (Standard_Integer anEdgeIdx = 1; anEdgeIdx <= aMeshData->NbEdges(); ++anEdgeIdx)
|
for (Standard_Integer anEdgeIdx = 1; anEdgeIdx <= aMeshData->NbEdges(); ++anEdgeIdx)
|
||||||
{
|
{
|
||||||
@ -2012,7 +2011,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th
|
|||||||
aShapeAttribs.RawName = theMeshName;
|
aShapeAttribs.RawName = theMeshName;
|
||||||
|
|
||||||
// assign material and not color
|
// 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());
|
aShapeAttribs.Style.SetColorCurv(aMeshData->BaseColor().GetRGB());
|
||||||
}
|
}
|
||||||
|
@ -579,7 +579,6 @@ bool RWGltf_TriangulationReader::ReadStream(
|
|||||||
const TCollection_AsciiString& aName = theSourceMesh->Id();
|
const TCollection_AsciiString& aName = theSourceMesh->Id();
|
||||||
const RWGltf_GltfPrimitiveMode aPrimMode = theSourceMesh->PrimitiveMode();
|
const RWGltf_GltfPrimitiveMode aPrimMode = theSourceMesh->PrimitiveMode();
|
||||||
if (aPrimMode != RWGltf_GltfPrimitiveMode_Triangles && aPrimMode != RWGltf_GltfPrimitiveMode_Lines
|
if (aPrimMode != RWGltf_GltfPrimitiveMode_Triangles && aPrimMode != RWGltf_GltfPrimitiveMode_Lines
|
||||||
&& aPrimMode != RWGltf_GltfPrimitiveMode_LineStrip
|
|
||||||
&& aPrimMode != RWGltf_GltfPrimitiveMode_Points)
|
&& aPrimMode != RWGltf_GltfPrimitiveMode_Points)
|
||||||
{
|
{
|
||||||
Message::SendWarning(TCollection_AsciiString("Buffer '") + aName
|
Message::SendWarning(TCollection_AsciiString("Buffer '") + aName
|
||||||
|
Loading…
x
Reference in New Issue
Block a user