Skip to content

Commit

Permalink
#draft
Browse files Browse the repository at this point in the history
Added functionality to import Points and Lines from GLTF format
  • Loading branch information
mzernova committed Jan 5, 2025
1 parent 1b6e878 commit 8141e34
Show file tree
Hide file tree
Showing 13 changed files with 484 additions and 173 deletions.
3 changes: 3 additions & 0 deletions src/RWGltf/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ RWGltf_GltfAlphaMode.hxx
RWGltf_GltfArrayType.hxx
RWGltf_GltfBufferView.hxx
RWGltf_GltfBufferViewTarget.hxx
RWGltf_GltfEdge.hxx
RWGltf_GltfFace.hxx
RWGltf_GltfJsonParser.cxx
RWGltf_GltfJsonParser.hxx
Expand All @@ -24,6 +25,8 @@ RWGltf_GltfPrimArrayData.hxx
RWGltf_GltfPrimitiveMode.hxx
RWGltf_GltfRootElement.hxx
RWGltf_GltfSceneNodeMap.hxx
RWGltf_GltfShape.hxx
RWGltf_GltfVertex.hxx
RWGltf_MaterialCommon.hxx
RWGltf_MaterialMetallicRoughness.hxx
RWGltf_Provider.cxx
Expand Down
75 changes: 54 additions & 21 deletions src/RWGltf/RWGltf_CafReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <OSD_FileSystem.hxx>
#include <OSD_ThreadPool.hxx>
#include <RWGltf_GltfLatePrimitiveArray.hxx>
#include <TopoDS.hxx>

IMPLEMENT_STANDARD_RTTIEXT(RWGltf_CafReader, RWMesh_CafReader)

Expand All @@ -35,11 +36,11 @@ class RWGltf_CafReader::CafReader_GltfBaseLoadingFunctor
public:

//! Main constructor.
CafReader_GltfBaseLoadingFunctor (NCollection_Vector<TopoDS_Face>& theFaceList,
CafReader_GltfBaseLoadingFunctor (NCollection_Vector<TopoDS_Shape>& theShapeList,
const Message_ProgressRange& theProgress,
const OSD_ThreadPool::Launcher& theThreadPool)
: myFaceList (&theFaceList),
myProgress (theProgress, "Loading glTF triangulation", Max (1, theFaceList.Size())),
: myShapeList (&theShapeList),
myProgress (theProgress, "Loading glTF triangulation", Max (1, theShapeList.Size())),
myThreadPool(theThreadPool)
{
//
Expand All @@ -49,14 +50,36 @@ class RWGltf_CafReader::CafReader_GltfBaseLoadingFunctor
void operator() (int theThreadIndex,
int theFaceIndex) const
{
TopLoc_Location aDummyLoc;
TopoDS_Face& aFace = myFaceList->ChangeValue (theFaceIndex);
Handle(RWGltf_GltfLatePrimitiveArray) aLateData = Handle(RWGltf_GltfLatePrimitiveArray)::DownCast (BRep_Tool::Triangulation (aFace, aDummyLoc));
Handle(Poly_Triangulation) aPolyData = loadData (aLateData, theThreadIndex);
if (!aPolyData.IsNull())
TopoDS_Shape& aShape = myShapeList->ChangeValue (theFaceIndex);
switch (aShape.ShapeType())
{
BRep_Builder aBuilder;
aBuilder.UpdateFace (aFace, aPolyData); // replace all "proxy"-triangulations of face by loaded active one.
case TopAbs_FACE:
{
TopLoc_Location aDummyLoc;
TopoDS_Face& aFace = TopoDS::Face (aShape);
Handle(RWGltf_GltfLatePrimitiveArray) aLateData = Handle(RWGltf_GltfLatePrimitiveArray)::DownCast (BRep_Tool::Triangulation (aFace, aDummyLoc));
Handle(Poly_Triangulation) aPolyData = loadData (aLateData, theThreadIndex);
if (!aPolyData.IsNull())
{
BRep_Builder aBuilder;
aBuilder.UpdateFace (aFace, aPolyData); // replace all "proxy"-triangulations of face by loaded active one.
}
break;
}
case TopAbs_EDGE:
{
TopoDS_Edge& aFace = TopoDS::Edge (aShape);
break;
}
case TopAbs_VERTEX:
{
TopoDS_Vertex& aFace = TopoDS::Vertex (aShape);
break;
}
default:
{
break;
}
}
if (myThreadPool.HasThreads())
{
Expand All @@ -77,10 +100,10 @@ class RWGltf_CafReader::CafReader_GltfBaseLoadingFunctor

protected:

NCollection_Vector<TopoDS_Face>* myFaceList;
mutable Standard_Mutex myMutex;
mutable Message_ProgressScope myProgress;
const OSD_ThreadPool::Launcher& myThreadPool;
NCollection_Vector<TopoDS_Shape>* myShapeList;
mutable Standard_Mutex myMutex;
mutable Message_ProgressScope myProgress;
const OSD_ThreadPool::Launcher& myThreadPool;
};
//! Functor for parallel execution of all glTF data loading.
class RWGltf_CafReader::CafReader_GltfFullDataLoadingFunctor : public RWGltf_CafReader::CafReader_GltfBaseLoadingFunctor
Expand All @@ -94,7 +117,7 @@ class RWGltf_CafReader::CafReader_GltfFullDataLoadingFunctor : public RWGltf_Caf

//! Main constructor.
CafReader_GltfFullDataLoadingFunctor (RWGltf_CafReader* myCafReader,
NCollection_Vector<TopoDS_Face>& theFaceList,
NCollection_Vector<TopoDS_Shape>& theFaceList,
const Message_ProgressRange& theProgress,
const OSD_ThreadPool::Launcher& theThreadPool)
: CafReader_GltfBaseLoadingFunctor (theFaceList, theProgress, theThreadPool),
Expand Down Expand Up @@ -124,6 +147,12 @@ class RWGltf_CafReader::CafReader_GltfFullDataLoadingFunctor : public RWGltf_Caf
if (myCafReader->ToKeepLateData())
{
theLateData->LoadDeferredData (aTlsData.FileSystem);
Message::SendInfo() << "Load Late Data, Name : " << theLateData->Name();
for (Standard_Integer i = 1; i <= theLateData->NbNodes(); ++i)
{
gp_Pnt point = theLateData->Node (i);
Message::SendInfo() << "Node " << i << ": (" << point.X() << ", " << point.Y() << ", " << point.Z() << ")";
}
return Handle(Poly_Triangulation)();
}
return theLateData->DetachedLoadDeferredData (aTlsData.FileSystem);
Expand All @@ -141,7 +170,7 @@ class RWGltf_CafReader::CafReader_GltfStreamDataLoadingFunctor : public RWGltf_C
public:

//! Main constructor.
CafReader_GltfStreamDataLoadingFunctor (NCollection_Vector<TopoDS_Face>& theFaceList,
CafReader_GltfStreamDataLoadingFunctor (NCollection_Vector<TopoDS_Shape>& theFaceList,
const Message_ProgressRange& theProgress,
const OSD_ThreadPool::Launcher& theThreadPool)
: CafReader_GltfBaseLoadingFunctor (theFaceList, theProgress, theThreadPool)
Expand Down Expand Up @@ -331,7 +360,7 @@ Standard_Boolean RWGltf_CafReader::performMesh (std::istream& theStream,
}

if (!theToProbe
&& !readLateData (aDoc.FaceList(), theFile, aPSentry.Next()))
&& !readLateData (aDoc.ShapeList(), theFile, aPSentry.Next()))
{
return false;
}
Expand All @@ -357,7 +386,7 @@ Handle(RWMesh_TriangulationReader) RWGltf_CafReader::createMeshReaderContext() c
// Function : readLateData
// Purpose :
//================================================================
Standard_Boolean RWGltf_CafReader::readLateData (NCollection_Vector<TopoDS_Face>& theFaces,
Standard_Boolean RWGltf_CafReader::readLateData (NCollection_Vector<TopoDS_Shape>& theFaces,
const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress)
{
Expand Down Expand Up @@ -396,13 +425,17 @@ Standard_Boolean RWGltf_CafReader::readLateData (NCollection_Vector<TopoDS_Face>
// Function : updateLateDataReader
// Purpose :
//================================================================
void RWGltf_CafReader::updateLateDataReader (NCollection_Vector<TopoDS_Face>& theFaces,
void RWGltf_CafReader::updateLateDataReader (NCollection_Vector<TopoDS_Shape>& theFaces,
const Handle(RWMesh_TriangulationReader)& theReader) const
{
TopLoc_Location aDummyLoc;
for (NCollection_Vector<TopoDS_Face>::Iterator aFaceIter(theFaces); aFaceIter.More(); aFaceIter.Next())
for (NCollection_Vector<TopoDS_Shape>::Iterator aFaceIter(theFaces); aFaceIter.More(); aFaceIter.Next())
{
const TopoDS_Face& aFace = aFaceIter.Value();
if (aFaceIter.Value().ShapeType() != TopAbs_FACE)
{
continue;
}
const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value());
for (Poly_ListOfTriangulation::Iterator anIter(BRep_Tool::Triangulations (aFace, aDummyLoc)); anIter.More(); anIter.Next())
{
Handle(RWGltf_GltfLatePrimitiveArray) aData = Handle(RWGltf_GltfLatePrimitiveArray)::DownCast(anIter.Value());
Expand Down
4 changes: 2 additions & 2 deletions src/RWGltf/RWGltf_CafReader.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ protected:
Standard_EXPORT virtual Handle(RWMesh_TriangulationReader) createMeshReaderContext() const;

//! Read late data from RWGltf_GltfLatePrimitiveArray stored as Poly_Triangulation within faces.
Standard_EXPORT virtual Standard_Boolean readLateData (NCollection_Vector<TopoDS_Face>& theFaces,
Standard_EXPORT virtual Standard_Boolean readLateData (NCollection_Vector<TopoDS_Shape>& theFaces,
const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress);

//! Set reader for each late data.
Standard_EXPORT void updateLateDataReader (NCollection_Vector<TopoDS_Face>& theFaces,
Standard_EXPORT void updateLateDataReader (NCollection_Vector<TopoDS_Shape>& theFaces,
const Handle(RWMesh_TriangulationReader)& theReader) const;

protected:
Expand Down
130 changes: 106 additions & 24 deletions src/RWGltf/RWGltf_GltfJsonParser.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Edge.hxx>
#include <RWGltf_TriangulationReader.hxx>
#include <OSD_FileSystem.hxx>
#include <OSD_CachedFileSystem.hxx>

#include <fstream>

Expand Down Expand Up @@ -1528,7 +1532,9 @@ bool RWGltf_GltfJsonParser::gltfParseSceneNodes (TopTools_SequenceOfShape& theSh
continue;
}
else if (myToSkipEmptyNodes
&& !TopExp_Explorer (aNodeShape, TopAbs_FACE).More())
&& !TopExp_Explorer (aNodeShape, TopAbs_FACE).More()
&& !TopExp_Explorer (aNodeShape, TopAbs_EDGE).More()
&& !TopExp_Explorer (aNodeShape, TopAbs_VERTEX).More())
{
continue;
}
Expand Down Expand Up @@ -1780,7 +1786,9 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (TopoDS_Shape& thePrimArrayShape,
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");
return true;
Expand Down Expand Up @@ -1825,19 +1833,15 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (TopoDS_Shape& thePrimArrayShape,
{
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;
}
Expand Down Expand Up @@ -1904,32 +1908,102 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (TopoDS_Shape& thePrimArrayShape,
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);
///////////
RWMesh_CoordinateSystemConverter aCoordSysConverter;
aCoordSysConverter.SetInputLengthUnit (1.0); // glTF defines model in meters
aCoordSysConverter.SetOutputLengthUnit (0.001);

aCoordSysConverter.SetInputCoordinateSystem (RWMesh_CoordinateSystem_glTF);
aCoordSysConverter.SetOutputCoordinateSystem (RWMesh_CoordinateSystem_Zup);

Handle(RWGltf_TriangulationReader) aReader = new RWGltf_TriangulationReader();
aReader->SetCoordinateSystemConverter(aCoordSysConverter);
////////////

TopoDS_Shape aShape;
switch (aMode)
{
case RWGltf_GltfPrimitiveMode_Points:
{
aMeshData->SetReader (aReader);
aMeshData->LoadDeferredData (new OSD_CachedFileSystem());

BRep_Builder aBuilder;
TopoDS_Compound aVertices;
aBuilder.MakeCompound (aVertices);
for (Standard_Integer i = 1; i <= aMeshData->NbNodes(); ++i) {
gp_Pnt point = aMeshData->Node(i);
Message::SendInfo() << "Node Points " << i << ": (" << point.X() << ", " << point.Y() << ", " << point.Z() << ")";

TopoDS_Vertex aVertex;
aBuilder.MakeVertex (aVertex, aMeshData->Node (i), Precision::Confusion());
aBuilder.Add (aVertices, aVertex);
}

aShape = aVertices;
break;
}
case RWGltf_GltfPrimitiveMode_Lines:
{
aMeshData->SetReader (aReader);
aMeshData->LoadDeferredData (new OSD_CachedFileSystem());
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));

gp_Pnt point = aMeshData->Node (aNodeIdx);
Message::SendInfo() << "Node Lines " << aNodeIdx << ": (" << point.X() << ", " << point.Y() << ", " << point.Z() << ")";
}

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;
break;
}
default:
{
break;
}
}
if (myAttribMap != NULL
&& aMeshData->HasStyle())
&& aMeshData->HasStyle())
{
RWMesh_NodeAttributes aShapeAttribs;
aShapeAttribs.RawName = theMeshName;

// assign material and not color
//aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor());
aShapeAttribs.Style.SetMaterial (aMat);
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;
myShapeList.Append (aShape);
myShapeMap[ShapeMapGroup_PrimArray].Bind (aPrimArrayId, aShape);
myShapeMap[ShapeMapGroup_PrimArray].Bind (aPrimArrayIdWithMat, aShape);
thePrimArrayShape = aShape;
}
return true;
}
Expand Down Expand Up @@ -2081,7 +2155,15 @@ bool RWGltf_GltfJsonParser::gltfParseAccessor (const Handle(RWGltf_GltfLatePrimi
}
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 = myGltfRoots[RWGltf_GltfRootElement_BufferViews].FindChild (*aBufferViewName);
Expand Down
6 changes: 3 additions & 3 deletions src/RWGltf/RWGltf_GltfJsonParser.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ public:
//! Parse glTF document.
Standard_EXPORT bool Parse (const Message_ProgressRange& theProgress);

//! Return face list for loading triangulation.
NCollection_Vector<TopoDS_Face>& FaceList() { return myFaceList; }
//! Return shape list for loading geometry.
NCollection_Vector<TopoDS_Shape>& ShapeList() { return myShapeList; }

protected:
#ifdef HAVE_RAPIDJSON
Expand Down Expand Up @@ -454,7 +454,7 @@ protected:

NCollection_DataMap<TCollection_AsciiString, bool> myProbedFiles;
NCollection_DataMap<TCollection_AsciiString, Handle(NCollection_Buffer)> myDecodedBuffers;
NCollection_Vector<TopoDS_Face> myFaceList; //!< face list for loading triangulation
NCollection_Vector<TopoDS_Shape> myShapeList; //!< shape list for loading geometry

TCollection_AsciiString myFilePath; //!< file path
TCollection_AsciiString myFolder; //!< folder
Expand Down
Loading

0 comments on commit 8141e34

Please sign in to comment.