Skip to content

Commit

Permalink
GLTF Export - Edge and Vertex support Open-Cascade-SAS#243
Browse files Browse the repository at this point in the history
Added functionality to export TopoDS_Vertex and TopoDS_Edge to GLTF format
  • Loading branch information
mzernova committed Jan 17, 2025
1 parent f91655b commit 82bad1a
Show file tree
Hide file tree
Showing 11 changed files with 1,350 additions and 483 deletions.
718 changes: 480 additions & 238 deletions src/RWGltf/RWGltf_CafWriter.cxx

Large diffs are not rendered by default.

95 changes: 87 additions & 8 deletions src/RWGltf/RWGltf_CafWriter.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,30 @@
#ifndef _RWGltf_CafWriter_HeaderFiler
#define _RWGltf_CafWriter_HeaderFiler

#include <Message_ProgressScope.hxx>
#include <NCollection_DataMap.hxx>
#include <TColStd_IndexedDataMapOfStringString.hxx>
#include <TColStd_MapOfAsciiString.hxx>
#include <TDF_LabelSequence.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <RWGltf_DracoParameters.hxx>
#include <RWGltf_GltfArrayType.hxx>
#include <RWGltf_GltfBufferView.hxx>
#include <RWGltf_GltfFace.hxx>
#include <RWGltf_WriterTrsfFormat.hxx>
#include <RWMesh_CoordinateSystemConverter.hxx>
#include <RWMesh_NameFormat.hxx>
#include <XCAFPrs_DocumentNode.hxx>
#include <XCAFPrs_Style.hxx>
#include <Poly_Triangle.hxx>

#include <memory>

class Message_ProgressRange;
class RWMesh_ShapeIterator;
class RWMesh_FaceIterator;
class RWMesh_EdgeIterator;
class RWMesh_VertexIterator;
class RWGltf_GltfOStreamWriter;
class RWGltf_GltfMaterialMap;
class RWGltf_GltfSceneNodeMap;
Expand Down Expand Up @@ -194,8 +201,11 @@ protected:

protected:

//! Return TRUE if face mesh should be skipped (e.g. because it is invalid or empty).
Standard_EXPORT virtual Standard_Boolean toSkipFaceMesh (const RWMesh_FaceIterator& theFaceIter);
//! 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;

//! Return TRUE if shape has triangulation (not vertex or edge).
Standard_EXPORT virtual Standard_Boolean hasTriangulation (const RWGltf_GltfFace& theShape) const;

//! Generate name for specified labels.
//! @param[in] theFormat name format to apply
Expand All @@ -208,12 +218,12 @@ protected:
//! Write mesh nodes into binary file.
//! @param[out] theGltfFace glTF face definition
//! @param[out] theBinFile output file to write into
//! @param[in] theFaceIter current face to write
//! @param[in] theShapeIter current shape to write
//! @param[in][out] theAccessorNb last accessor index
//! @param[in][out] theMesh mesh
Standard_EXPORT virtual void saveNodes (RWGltf_GltfFace& theGltfFace,
std::ostream& theBinFile,
const RWMesh_FaceIterator& theFaceIter,
const RWMesh_ShapeIterator& theShapeIter,
Standard_Integer& theAccessorNb,
const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh) const;

Expand All @@ -225,7 +235,7 @@ protected:
//! @param[in][out] theMesh mesh
Standard_EXPORT virtual void saveNormals (RWGltf_GltfFace& theGltfFace,
std::ostream& theBinFile,
RWMesh_FaceIterator& theFaceIter,
const RWMesh_FaceIterator& theFaceIter,
Standard_Integer& theAccessorNb,
const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh) const;

Expand All @@ -244,15 +254,41 @@ protected:
//! Write mesh indexes into binary file.
//! @param[out] theGltfFace glTF face definition
//! @param[out] theBinFile output file to write into
//! @param[in] theFaceIter current face to write
//! @param[in] theShapeIter current shape to write
//! @param[in][out] theAccessorNb last accessor index
//! @param[in][out] theMesh mesh
Standard_EXPORT virtual void saveIndices (RWGltf_GltfFace& theGltfFace,
std::ostream& theBinFile,
const RWMesh_FaceIterator& theFaceIter,
const RWMesh_ShapeIterator& theShapeIter,
Standard_Integer& theAccessorNb,
const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh);

//! Write triangle indexes into binary file.
//! @param[out] theGltfFace glTF face definition
//! @param[out] theBinFile output file to write into
//! @param[in] theFaceIter current face to write
//! @param[in][out] theMesh mesh
Standard_EXPORT virtual void saveTriangleIndices (RWGltf_GltfFace& theGltfFace,
std::ostream& theBinFile,
const RWMesh_FaceIterator& theFaceIter,
const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh);

//! Write edge indexes into binary file.
//! @param[out] theGltfFace glTF face definition
//! @param[out] theBinFile output file to write into
//! @param[in] theEdgeIter current edge to write
Standard_EXPORT virtual void saveEdgeIndices (RWGltf_GltfFace& theGltfFace,
std::ostream& theBinFile,
const RWMesh_EdgeIterator& theEdgeIter);

//! Write vertex indexes into binary file.
//! @param[out] theGltfFace glTF face definition
//! @param[out] theBinFile output file to write into
//! @param[in] theVertexIter current vertex to write
Standard_EXPORT virtual void saveVertexIndices (RWGltf_GltfFace& theGltfFace,
std::ostream& theBinFile,
const RWMesh_VertexIterator& theVertexIter);

protected:

//! Write bufferView for vertex positions within RWGltf_GltfRootElement_Accessors section
Expand Down Expand Up @@ -352,7 +388,50 @@ protected:

//! Write nodes.extras section with key-value attributes.
//! @param[in] theNamedData attributes map to process.
Standard_EXPORT virtual void writeExtrasAttributes(const Handle(TDataStd_NamedData)& theNamedData);
Standard_EXPORT virtual void writeExtrasAttributes (const Handle(TDataStd_NamedData)& theNamedData);

//! Dispatch shapes
//! @param[in] theDocNode Document node containing shape data
//! @param[in] thePSentryBin Progress scope for the operation
//! @param[in,out] theMergedFaces Data map to store merged faces
//! @param[in,out] theShapeIter Shape iterator to traverse shapes
Standard_EXPORT virtual void dispatchShapes (const XCAFPrs_DocumentNode& theDocNode,
const Message_ProgressScope& thePSentryBin,
NCollection_DataMap<XCAFPrs_Style, Handle(RWGltf_GltfFace)>& theMergedFaces,
RWMesh_ShapeIterator& theShapeIter);

//! Write shape into binary file
//! @param[out] theGltfFace glTF face definition
//! @param[out] theBinFile Output file to write into
//! @param[in] theShapeIter Current shape iterator
//! @param[in,out] theAccessorNb Last accessor index
//! @param[in,out] theMesh Mesh data
//! @param[in] theArrType Array type for glTF
//! @param[in] thePSentryBin Progress scope for the operation
//! @return True if shapes were successfully written to the binary file, false otherwise
Standard_EXPORT bool writeShapesToBin (RWGltf_GltfFace& theGltfFace,
std::ostream& theBinFile,
RWMesh_ShapeIterator& theShapeIter,
Standard_Integer& theAccessorNb,
const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh,
const RWGltf_GltfArrayType theArrType,
const Message_ProgressScope& thePSentryBin);

//! 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
//! @param[in,out] theWrittenShapes Map to store written shapes
//! @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,
NCollection_Map<Handle(RWGltf_GltfFaceList)>& theWrittenShapes,
NCollection_IndexedDataMap<int, int>& theDracoBufIndMap);

protected:

Expand Down
6 changes: 6 additions & 0 deletions src/RWMesh/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ RWMesh_CafReader.hxx
RWMesh_CoordinateSystem.hxx
RWMesh_CoordinateSystemConverter.cxx
RWMesh_CoordinateSystemConverter.hxx
RWMesh_EdgeIterator.cxx
RWMesh_EdgeIterator.hxx
RWMesh_FaceIterator.cxx
RWMesh_FaceIterator.hxx
RWMesh_MaterialMap.cxx
RWMesh_MaterialMap.hxx
RWMesh_NameFormat.hxx
RWMesh_NodeAttributes.hxx
RWMesh_ShapeIterator.cxx
RWMesh_ShapeIterator.hxx
RWMesh_TriangulationReader.cxx
RWMesh_TriangulationReader.hxx
RWMesh_TriangulationSource.cxx
RWMesh_TriangulationSource.hxx
RWMesh_VertexIterator.cxx
RWMesh_VertexIterator.hxx
78 changes: 78 additions & 0 deletions src/RWMesh/RWMesh_EdgeIterator.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2025 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

#include <RWMesh_EdgeIterator.hxx>

#include <BRep_Tool.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include <XCAFPrs.hxx>

// =======================================================================
// function : RWMesh_EdgeIterator
// purpose :
// =======================================================================
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)
{
Next();
}

// =======================================================================
// function : RWMesh_EdgeIterator
// purpose :
// =======================================================================
RWMesh_EdgeIterator::RWMesh_EdgeIterator(const TopoDS_Shape& theShape,
const XCAFPrs_Style& theStyle)
: RWMesh_ShapeIterator(theShape, TopAbs_EDGE, theStyle)
{
Next();
}

// =======================================================================
// function : Next
// purpose :
// =======================================================================
void RWMesh_EdgeIterator::Next()
{
for (; myIter.More(); myIter.Next())
{
myEdge = TopoDS::Edge(myIter.Current());
myPolygon3D = BRep_Tool::Polygon3D(myEdge, myLocation);
myTrsf = myLocation.Transformation();
if (myPolygon3D.IsNull() || myPolygon3D->NbNodes() == 0)
{
resetEdge();
continue;
}

initEdge();
myIter.Next();
return;
}

resetEdge();
}

// =======================================================================
// function : initEdge
// purpose :
// =======================================================================
void RWMesh_EdgeIterator::initEdge()
{
initShape();
}
118 changes: 118 additions & 0 deletions src/RWMesh/RWMesh_EdgeIterator.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright (c) 2025 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

#ifndef _RWMesh_EdgeIterator_HeaderFile
#define _RWMesh_EdgeIterator_HeaderFile

#include <NCollection_DataMap.hxx>
#include <Poly_Polygon3D.hxx>
#include <RWMesh_ShapeIterator.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopoDS_Edge.hxx>
#include <XCAFPrs_Style.hxx>
#include <gp_Trsf.hxx>

#include <algorithm>

class TDF_Label;

//! Auxiliary class to iterate through edges.
//! Provides functionality to iterate through the edges of a shape.
//! It inherits from `RWMesh_ShapeIterator` and implements
//! methods to access and manipulate edge data.
class RWMesh_EdgeIterator : public RWMesh_ShapeIterator
{
public:
//! Main constructor.
//! @param[in] theLabel The label of the shape.
//! @param[in] theLocation The location of the shape.
//! @param[in] theToMapColors Flag to indicate if colors should be mapped.
//! @param[in] theStyle The style of the shape.
Standard_EXPORT RWMesh_EdgeIterator(const TDF_Label& theLabel,
const TopLoc_Location& theLocation,
const Standard_Boolean theToMapColors = false,
const XCAFPrs_Style& theStyle = XCAFPrs_Style());

//! Auxiliary constructor.
//! @param[in] theShape The shape to iterate.
//! @param[in] theStyle The style of the shape.
Standard_EXPORT RWMesh_EdgeIterator(const TopoDS_Shape& theShape,
const XCAFPrs_Style& theStyle = XCAFPrs_Style());

//! Return true if iterator points to the valid triangulation.
bool More() const Standard_OVERRIDE { return !myPolygon3D.IsNull(); }

//! Find next value.
Standard_EXPORT void Next() Standard_OVERRIDE;

//! Return current edge.
const TopoDS_Edge& Edge() const { return myEdge; }

//! Return current edge.
const TopoDS_Shape& Shape() const Standard_OVERRIDE { return myEdge; }

//! Return current edge data.
const Handle(Poly_Polygon3D)& Polygon3D() const { return myPolygon3D; }

//! Return true if geometry data is defined.
bool IsEmpty() const Standard_OVERRIDE
{
return myPolygon3D.IsNull() || myPolygon3D->NbNodes() < 1;
}

public:
//! Lower element index in current triangulation.
Standard_Integer ElemLower() const Standard_OVERRIDE { return 1; }

//! Upper element index in current triangulation.
Standard_Integer ElemUpper() const Standard_OVERRIDE { return myPolygon3D->NbNodes(); }

public:
//! Return number of nodes for the current edge.
Standard_Integer NbNodes() const Standard_OVERRIDE
{
return !myPolygon3D.IsNull() ? myPolygon3D->NbNodes() : 0;
}

//! Lower node index in current triangulation.
Standard_Integer NodeLower() const Standard_OVERRIDE { return 1; }

//! Upper node index in current triangulation.
Standard_Integer NodeUpper() const Standard_OVERRIDE { return myPolygon3D->NbNodes(); }

public:
//! Return the node with specified index with applied transformation.
gp_Pnt node(const Standard_Integer theNode) const Standard_OVERRIDE
{
return myPolygon3D->Nodes().Value(theNode);
}

private:
//! Reset information for current edge.
void resetEdge()
{
myPolygon3D.Nullify();
myEdge.Nullify();
resetShape();
}

//! Initialize edge properties.
void initEdge();

private:
TopoDS_Edge myEdge; //!< current edge
Handle(Poly_Polygon3D) myPolygon3D; //!< geometry of current edge
};

#endif // _RWMesh_EdgeIterator_HeaderFile
Loading

0 comments on commit 82bad1a

Please sign in to comment.