diff --git a/src/RWGltf/FILES b/src/RWGltf/FILES index fc24654adf..141fda37d1 100644 --- a/src/RWGltf/FILES +++ b/src/RWGltf/FILES @@ -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 @@ -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 diff --git a/src/RWGltf/RWGltf_CafReader.cxx b/src/RWGltf/RWGltf_CafReader.cxx index 6db997df3d..43fca6b504 100644 --- a/src/RWGltf/RWGltf_CafReader.cxx +++ b/src/RWGltf/RWGltf_CafReader.cxx @@ -26,6 +26,7 @@ #include #include #include +#include IMPLEMENT_STANDARD_RTTIEXT(RWGltf_CafReader, RWMesh_CafReader) @@ -35,11 +36,11 @@ class RWGltf_CafReader::CafReader_GltfBaseLoadingFunctor public: //! Main constructor. - CafReader_GltfBaseLoadingFunctor (NCollection_Vector& theFaceList, + CafReader_GltfBaseLoadingFunctor (NCollection_Vector& 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) { // @@ -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()) { @@ -77,10 +100,10 @@ class RWGltf_CafReader::CafReader_GltfBaseLoadingFunctor protected: - NCollection_Vector* myFaceList; - mutable Standard_Mutex myMutex; - mutable Message_ProgressScope myProgress; - const OSD_ThreadPool::Launcher& myThreadPool; + NCollection_Vector* 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 @@ -94,7 +117,7 @@ class RWGltf_CafReader::CafReader_GltfFullDataLoadingFunctor : public RWGltf_Caf //! Main constructor. CafReader_GltfFullDataLoadingFunctor (RWGltf_CafReader* myCafReader, - NCollection_Vector& theFaceList, + NCollection_Vector& theFaceList, const Message_ProgressRange& theProgress, const OSD_ThreadPool::Launcher& theThreadPool) : CafReader_GltfBaseLoadingFunctor (theFaceList, theProgress, theThreadPool), @@ -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); @@ -141,7 +170,7 @@ class RWGltf_CafReader::CafReader_GltfStreamDataLoadingFunctor : public RWGltf_C public: //! Main constructor. - CafReader_GltfStreamDataLoadingFunctor (NCollection_Vector& theFaceList, + CafReader_GltfStreamDataLoadingFunctor (NCollection_Vector& theFaceList, const Message_ProgressRange& theProgress, const OSD_ThreadPool::Launcher& theThreadPool) : CafReader_GltfBaseLoadingFunctor (theFaceList, theProgress, theThreadPool) @@ -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; } @@ -357,7 +386,7 @@ Handle(RWMesh_TriangulationReader) RWGltf_CafReader::createMeshReaderContext() c // Function : readLateData // Purpose : //================================================================ -Standard_Boolean RWGltf_CafReader::readLateData (NCollection_Vector& theFaces, +Standard_Boolean RWGltf_CafReader::readLateData (NCollection_Vector& theFaces, const TCollection_AsciiString& theFile, const Message_ProgressRange& theProgress) { @@ -396,13 +425,17 @@ Standard_Boolean RWGltf_CafReader::readLateData (NCollection_Vector // Function : updateLateDataReader // Purpose : //================================================================ -void RWGltf_CafReader::updateLateDataReader (NCollection_Vector& theFaces, +void RWGltf_CafReader::updateLateDataReader (NCollection_Vector& theFaces, const Handle(RWMesh_TriangulationReader)& theReader) const { TopLoc_Location aDummyLoc; - for (NCollection_Vector::Iterator aFaceIter(theFaces); aFaceIter.More(); aFaceIter.Next()) + for (NCollection_Vector::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()); diff --git a/src/RWGltf/RWGltf_CafReader.hxx b/src/RWGltf/RWGltf_CafReader.hxx index 905e59958a..57bf0c37bd 100644 --- a/src/RWGltf/RWGltf_CafReader.hxx +++ b/src/RWGltf/RWGltf_CafReader.hxx @@ -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& theFaces, + Standard_EXPORT virtual Standard_Boolean readLateData (NCollection_Vector& theFaces, const TCollection_AsciiString& theFile, const Message_ProgressRange& theProgress); //! Set reader for each late data. - Standard_EXPORT void updateLateDataReader (NCollection_Vector& theFaces, + Standard_EXPORT void updateLateDataReader (NCollection_Vector& theFaces, const Handle(RWMesh_TriangulationReader)& theReader) const; protected: diff --git a/src/RWGltf/RWGltf_GltfJsonParser.cxx b/src/RWGltf/RWGltf_GltfJsonParser.cxx index c3fc588c5f..8d057be0f4 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.cxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.cxx @@ -29,6 +29,10 @@ #include #include #include +#include +#include +#include +#include #include @@ -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; } @@ -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; @@ -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; } @@ -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; } @@ -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); diff --git a/src/RWGltf/RWGltf_GltfJsonParser.hxx b/src/RWGltf/RWGltf_GltfJsonParser.hxx index ccb5757a19..157d604f8f 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.hxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.hxx @@ -120,8 +120,8 @@ public: //! Parse glTF document. Standard_EXPORT bool Parse (const Message_ProgressRange& theProgress); - //! Return face list for loading triangulation. - NCollection_Vector& FaceList() { return myFaceList; } + //! Return shape list for loading geometry. + NCollection_Vector& ShapeList() { return myShapeList; } protected: #ifdef HAVE_RAPIDJSON @@ -454,7 +454,7 @@ protected: NCollection_DataMap myProbedFiles; NCollection_DataMap myDecodedBuffers; - NCollection_Vector myFaceList; //!< face list for loading triangulation + NCollection_Vector myShapeList; //!< shape list for loading geometry TCollection_AsciiString myFilePath; //!< file path TCollection_AsciiString myFolder; //!< folder diff --git a/src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx b/src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx index ebca9dc366..808699add3 100644 --- a/src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx +++ b/src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx @@ -103,7 +103,7 @@ 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 10e2d299b7..fd88b637f9 100644 --- a/src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx +++ b/src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx @@ -82,7 +82,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 c528ae6134..41983898ee 100644 --- a/src/RWGltf/RWGltf_TriangulationReader.cxx +++ b/src/RWGltf/RWGltf_TriangulationReader.cxx @@ -107,7 +107,7 @@ void RWGltf_TriangulationReader::reportError (const TCollection_AsciiString& the // purpose : // ======================================================================= bool RWGltf_TriangulationReader::LoadStreamData (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh) const + const Handle(RWMesh_TriangulationSource)& theDestMesh) const { Standard_ASSERT_RETURN (!theDestMesh.IsNull(), "The destination mesh should be initialized before loading data to it", false); theDestMesh->Clear(); @@ -132,7 +132,7 @@ bool RWGltf_TriangulationReader::LoadStreamData (const Handle(RWMesh_Triangulati // ======================================================================= bool RWGltf_TriangulationReader::readStreamData (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh, const RWGltf_GltfPrimArrayData& theGltfData, - const Handle(Poly_Triangulation)& theDestMesh) const + const Handle(RWMesh_TriangulationSource)& theDestMesh) const { Standard_ArrayStreamBuffer aStreamBuffer ((const char* )theGltfData.StreamData->Data(), theGltfData.StreamData->Size()); std::istream aStream (&aStreamBuffer); @@ -150,7 +150,7 @@ bool RWGltf_TriangulationReader::readStreamData (const Handle(RWGltf_GltfLatePri // ======================================================================= bool RWGltf_TriangulationReader::readFileData (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh, const RWGltf_GltfPrimArrayData& theGltfData, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const { const Handle(OSD_FileSystem)& aFileSystem = !theFileSystem.IsNull() ? theFileSystem : OSD_FileSystem::DefaultFileSystem(); @@ -174,7 +174,7 @@ bool RWGltf_TriangulationReader::readFileData (const Handle(RWGltf_GltfLatePrimi // purpose : // ======================================================================= bool RWGltf_TriangulationReader::loadStreamData (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, bool theToResetStream) const { const Handle(RWGltf_GltfLatePrimitiveArray) aSourceGltfMesh = Handle(RWGltf_GltfLatePrimitiveArray)::DownCast(theSourceMesh); @@ -210,7 +210,7 @@ bool RWGltf_TriangulationReader::loadStreamData (const Handle(RWMesh_Triangulati // ======================================================================= bool RWGltf_TriangulationReader::readDracoBuffer (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh, const RWGltf_GltfPrimArrayData& theGltfData, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const { const TCollection_AsciiString& aName = theSourceGltfMesh->Id(); @@ -422,7 +422,7 @@ bool RWGltf_TriangulationReader::readDracoBuffer (const Handle(RWGltf_GltfLatePr // purpose : // ======================================================================= bool RWGltf_TriangulationReader::load (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const { const Handle(RWGltf_GltfLatePrimitiveArray) aSourceGltfMesh = Handle(RWGltf_GltfLatePrimitiveArray)::DownCast(theSourceMesh); @@ -477,7 +477,7 @@ bool RWGltf_TriangulationReader::load (const Handle(RWMesh_TriangulationSource)& // purpose : // ======================================================================= bool RWGltf_TriangulationReader::finalizeLoading (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh) const + const Handle(RWMesh_TriangulationSource)& theDestMesh) const { if (theDestMesh->NbNodes() < 1) { @@ -514,18 +514,18 @@ bool RWGltf_TriangulationReader::finalizeLoading (const Handle(RWMesh_Triangulat // purpose : // ======================================================================= bool RWGltf_TriangulationReader::readBuffer (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, std::istream& theStream, const RWGltf_GltfAccessor& theAccessor, RWGltf_GltfArrayType theType) const { const TCollection_AsciiString& aName = theSourceMesh->Id(); - if (theSourceMesh->PrimitiveMode() != RWGltf_GltfPrimitiveMode_Triangles) - { - Message::SendWarning (TCollection_AsciiString("Buffer '") + aName + "' skipped unsupported primitive array"); - return true; - } + //if (theSourceMesh->PrimitiveMode() != RWGltf_GltfPrimitiveMode_Triangles) + //{ + // Message::SendWarning (TCollection_AsciiString("Buffer '") + aName + "' skipped unsupported primitive array"); + // return true; + //} switch (theType) { @@ -545,18 +545,48 @@ bool RWGltf_TriangulationReader::readBuffer (const Handle(RWGltf_GltfLatePrimiti return false; } - const Standard_Integer aNbTris = (Standard_Integer )(theAccessor.Count / 3); - if (!setNbTriangles (theDestMesh, aNbTris)) + const Standard_Boolean isTriangles = theSourceMesh->PrimitiveMode() == 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) + for (Standard_Integer aTriIter = 0; aTriIter < aCounter; ++aTriIter) { + if (!isTriangles) + { + if (const uint16_t* anIndex = aBuffer.ReadChunk(theStream)) + { + const Standard_Integer wasSet = setEdge (theDestMesh, + THE_LOWER_TRI_INDEX + aLastTriIndex, + THE_LOWER_NODE_INDEX + *anIndex); + if (!wasSet) + { + reportError(TCollection_AsciiString("Buffer '") + aName + "' refers to invalid indices."); + } + if (wasSet > 0) + { + aLastTriIndex++; + } + } + else + { + reportError (TCollection_AsciiString("Buffer '") + aName + "' reading error."); + return false; + } + continue; + } + if (const uint16_t* anIndex0 = aBuffer.ReadChunk (theStream)) { aVec3.ChangeValue (1) = THE_LOWER_NODE_INDEX + *anIndex0; @@ -585,10 +615,10 @@ bool RWGltf_TriangulationReader::readBuffer (const Handle(RWGltf_GltfLatePrimiti aLastTriIndex++; } } - const Standard_Integer aNbDegenerate = aNbTris - aLastTriIndex; + const Standard_Integer aNbDegenerate = aCounter - aLastTriIndex; if (aNbDegenerate > 0) { - if (aNbDegenerate == aNbTris) + if (aNbDegenerate == aCounter) { Message::SendWarning (TCollection_AsciiString("Buffer '") + aName + "' has been skipped (all elements are degenerative in)"); return false; diff --git a/src/RWGltf/RWGltf_TriangulationReader.hxx b/src/RWGltf/RWGltf_TriangulationReader.hxx index 649b8f3456..c627fe0eca 100644 --- a/src/RWGltf/RWGltf_TriangulationReader.hxx +++ b/src/RWGltf/RWGltf_TriangulationReader.hxx @@ -34,7 +34,7 @@ public: //! Loads only primitive arrays saved as stream buffer //! (it is primarily glTF data encoded in base64 saved to temporary buffer during glTF file reading). Standard_EXPORT bool LoadStreamData (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh) const; + const Handle(RWMesh_TriangulationSource)& theDestMesh) const; protected: @@ -47,14 +47,14 @@ protected: //! @param theFileSystem shared file system to read from //! Note: this method skips "stream data" that should be loaded by LoadStreamData() call. Standard_EXPORT virtual bool load (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const Standard_OVERRIDE; //! Performs additional actions to finalize data loading. //! @param theSourceMesh source triangulation //! @param theDestMesh triangulation to be modified Standard_EXPORT virtual bool finalizeLoading (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh) const Standard_OVERRIDE; + const Handle(RWMesh_TriangulationSource)& theDestMesh) const Standard_OVERRIDE; //! Loads only primitive arrays saved as stream buffer //! (it is primarily glTF data encoded in base64 saved to temporary buffer during glTF file reading). @@ -62,7 +62,7 @@ protected: //! @param theDestMesh triangulation to be modified //! @param theToResetStream if TRUE reset input stream data buffer after its loading. Standard_EXPORT bool loadStreamData (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, bool theToResetStream = true) const; //! Reads primitive array from stream data. @@ -71,7 +71,7 @@ protected: //! @param theDestMesh triangulation to be modified Standard_EXPORT bool readStreamData (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh, const RWGltf_GltfPrimArrayData& theGltfData, - const Handle(Poly_Triangulation)& theDestMesh) const; + const Handle(RWMesh_TriangulationSource)& theDestMesh) const; //! Reads primitive array from file data. //! @param theSourceGltfMesh source glTF triangulation @@ -80,7 +80,7 @@ protected: //! @param theFileSystem shared file system to read from Standard_EXPORT bool readFileData (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh, const RWGltf_GltfPrimArrayData& theGltfData, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const; //! Fills triangulation data and ignore non-triangulation primitives. @@ -91,7 +91,7 @@ protected: //! @param theType array type //! @return FALSE on error Standard_EXPORT virtual bool readBuffer (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, std::istream& theStream, const RWGltf_GltfAccessor& theAccessor, RWGltf_GltfArrayType theType) const; @@ -103,12 +103,12 @@ protected: //! @param theFileSystem shared file system to read from Standard_EXPORT virtual bool readDracoBuffer (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh, const RWGltf_GltfPrimArrayData& theGltfData, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const; protected: - Handle(Poly_Triangulation) myTriangulation; + Handle(RWMesh_TriangulationSource) myTriangulation; }; diff --git a/src/RWMesh/RWMesh_TriangulationReader.cxx b/src/RWMesh/RWMesh_TriangulationReader.cxx index bc001ffe73..163a57b608 100644 --- a/src/RWMesh/RWMesh_TriangulationReader.cxx +++ b/src/RWMesh/RWMesh_TriangulationReader.cxx @@ -97,7 +97,7 @@ RWMesh_TriangulationReader::~RWMesh_TriangulationReader() // purpose : // ======================================================================= bool RWMesh_TriangulationReader::Load (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const { Standard_ASSERT_RETURN (!theDestMesh.IsNull(), "The destination mesh should be initialized before loading data to it", false); @@ -122,7 +122,7 @@ bool RWMesh_TriangulationReader::Load (const Handle(RWMesh_TriangulationSource)& // purpose : // ======================================================================= bool RWMesh_TriangulationReader::finalizeLoading (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh) const + const Handle(RWMesh_TriangulationSource)& theDestMesh) const { if (!theSourceMesh->CachedMinMax().IsVoid()) { @@ -147,3 +147,157 @@ bool RWMesh_TriangulationReader::finalizeLoading (const Handle(RWMesh_Triangulat } return true; } + +// ======================================================================= +// function : setNbPositionNodes +// purpose : +// ======================================================================= +bool RWMesh_TriangulationReader::setNbPositionNodes (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbNodes, + Standard_Boolean theToCopyData) const +{ + if (theNbNodes <= 0) + { + return false; + } + theMesh->ResizeNodes(theNbNodes, theToCopyData); + return true; +} + +// ======================================================================= +// function : setNodePosition +// purpose : +// ======================================================================= +void RWMesh_TriangulationReader::setNodePosition (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const gp_Pnt& thePnt) const +{ + theMesh->SetNode(theIndex, thePnt); +} + +// ======================================================================= +// function : setNbUVNodes +// purpose : +// ======================================================================= +bool RWMesh_TriangulationReader::setNbUVNodes (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbNodes) const +{ + if (theNbNodes <= 0 + || theMesh->NbNodes() != theNbNodes) + { + return false; + } + theMesh->AddUVNodes(); + return true; +} + +// ======================================================================= +// function : setNodeUV +// purpose : +// ======================================================================= +void RWMesh_TriangulationReader::setNodeUV (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const gp_Pnt2d& theUV) const +{ + theMesh->SetUVNode (theIndex, theUV); +} + +// ======================================================================= +// function : setNbNormalNodes +// purpose : +// ======================================================================= +bool RWMesh_TriangulationReader::setNbNormalNodes (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbNodes) const +{ + if (theNbNodes <= 0 + || theMesh->NbNodes() != theNbNodes) + { + return false; + } + theMesh->AddNormals(); + return true; +} + +// ======================================================================= +// function : setNodeNormal +// purpose : +// ======================================================================= +void RWMesh_TriangulationReader::setNodeNormal (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const gp_Vec3f& theNormal) const +{ + theMesh->SetNormal(theIndex, theNormal); +} + +// ======================================================================= +// function : setNbTriangles +// purpose : +// ======================================================================= +bool RWMesh_TriangulationReader::setNbTriangles (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbTris, + Standard_Boolean theToCopyData) const +{ + if (theNbTris >= 1) + { + theMesh->ResizeTriangles (theNbTris, theToCopyData); + return true; + } + return false; +} + +// ======================================================================= +// function : setTriangle +// purpose : +// ======================================================================= +Standard_Integer RWMesh_TriangulationReader::setTriangle (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const Poly_Triangle& theTriangle) const +{ + if (theTriangle.Value(1) < 1 || theTriangle.Value(1) > theMesh->NbNodes() + || theTriangle.Value(2) < 1 || theTriangle.Value(2) > theMesh->NbNodes() + || theTriangle.Value(3) < 1 || theTriangle.Value(3) > theMesh->NbNodes()) + { + return 0; + } + if (myToSkipDegenerateTris + && (theTriangle.Value(1) == theTriangle.Value(2) + || theTriangle.Value(1) == theTriangle.Value(3) + || theTriangle.Value(2) == theTriangle.Value(3))) + { + return -1; + } + theMesh->SetTriangle (theIndex, theTriangle); + return 1; +} + +// ======================================================================= +// function : setNbEdges +// purpose : +// ======================================================================= +bool RWMesh_TriangulationReader::setNbEdges (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbTris, + Standard_Boolean theToCopyData) const +{ + if (theNbTris >= 1) + { + theMesh->ResizeEdges (theNbTris, theToCopyData); + return true; + } + return false; +} + +// ======================================================================= +// function : setEdge +// purpose : +// ======================================================================= +Standard_Integer RWMesh_TriangulationReader::setEdge (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const Standard_Integer theEdge) const +{ + if (theEdge < 1 || theEdge > theMesh->NbNodes()) + { + return 0; + } + theMesh->SetEdge(theIndex, theEdge); + return 1; +} diff --git a/src/RWMesh/RWMesh_TriangulationReader.hxx b/src/RWMesh/RWMesh_TriangulationReader.hxx index 7860cf55f0..af4f12336c 100644 --- a/src/RWMesh/RWMesh_TriangulationReader.hxx +++ b/src/RWMesh/RWMesh_TriangulationReader.hxx @@ -126,19 +126,19 @@ public: //! Loads primitive array. Standard_EXPORT bool Load (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const; protected: //! Loads primitive array. Standard_EXPORT virtual bool load (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh, + const Handle(RWMesh_TriangulationSource)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const = 0; //! Performs additional actions to finalize data loading. Standard_EXPORT virtual bool finalizeLoading (const Handle(RWMesh_TriangulationSource)& theSourceMesh, - const Handle(Poly_Triangulation)& theDestMesh) const; + const Handle(RWMesh_TriangulationSource)& theDestMesh) const; protected: //! @name interface for filling triangulation data @@ -147,99 +147,56 @@ protected: //! @name interface for filling triangulation data //! @param[in] theNbNodes nodes number //! @param[in] theToCopyData copy old nodes into new array //! @return TRUE in case of success operation - virtual bool setNbPositionNodes (const Handle(Poly_Triangulation)& theMesh, - Standard_Integer theNbNodes, - Standard_Boolean theToCopyData = false) const - { - if (theNbNodes <= 0) - { - return false; - } - theMesh->ResizeNodes (theNbNodes, theToCopyData); - return true; - } + Standard_EXPORT virtual bool setNbPositionNodes (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbNodes, + Standard_Boolean theToCopyData = false) const; //! Sets node position. //! @param[in] theMesh triangulation to be modified //! @param[in] theIndex node index starting from 1 //! @param[in] thePnt node position - virtual void setNodePosition (const Handle(Poly_Triangulation)& theMesh, - Standard_Integer theIndex, - const gp_Pnt& thePnt) const - { - theMesh->SetNode (theIndex, thePnt); - } + Standard_EXPORT virtual void setNodePosition (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const gp_Pnt& thePnt) const; //! Resizes array of UV nodes to specified size. //! @param[in] theMesh triangulation to be modified //! @param[in] theNbNodes nodes number //! @return TRUE in case of success operation - virtual bool setNbUVNodes (const Handle(Poly_Triangulation)& theMesh, - Standard_Integer theNbNodes) const - { - if (theNbNodes <= 0 - || theMesh->NbNodes() != theNbNodes) - { - return false; - } - theMesh->AddUVNodes(); - return true; - } + Standard_EXPORT virtual bool setNbUVNodes (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbNodes) const; //! Sets node UV texture coordinates. //! @param[in] theMesh triangulation to be modified //! @param[in] theIndex node index starting from 1 //! @param[in] theUV node UV coordinates - virtual void setNodeUV (const Handle(Poly_Triangulation)& theMesh, - Standard_Integer theIndex, - const gp_Pnt2d& theUV) const - { - theMesh->SetUVNode (theIndex, theUV); - } + Standard_EXPORT virtual void setNodeUV (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const gp_Pnt2d& theUV) const; //! Resizes array of nodes normals to specified size. //! @param[in] theMesh triangulation to be modified //! @param[in] theNbNodes nodes number //! @return TRUE in case of success operation - virtual bool setNbNormalNodes (const Handle(Poly_Triangulation)& theMesh, - Standard_Integer theNbNodes) const - { - if (theNbNodes <= 0 - || theMesh->NbNodes() != theNbNodes) - { - return false; - } - theMesh->AddNormals(); - return true; - } + Standard_EXPORT virtual bool setNbNormalNodes (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbNodes) const; //! Sets node normal. //! @param[in] theMesh triangulation to be modified //! @param theIndex node index starting from 1 //! @param theNormal node normal vector - virtual void setNodeNormal (const Handle(Poly_Triangulation)& theMesh, - Standard_Integer theIndex, - const gp_Vec3f& theNormal) const - { - theMesh->SetNormal (theIndex, theNormal); - } + Standard_EXPORT virtual void setNodeNormal (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const gp_Vec3f& theNormal) const; //! Resizes array of triangles to specified size. //! @param[in] theMesh triangulation to be modified //! @param[in] theNbTris elements number //! @param[in] theToCopyData copy old triangles into new array //! @return TRUE in case of success operation - virtual bool setNbTriangles (const Handle(Poly_Triangulation)& theMesh, - Standard_Integer theNbTris, - Standard_Boolean theToCopyData = false) const - { - if (theNbTris >= 1) - { - theMesh->ResizeTriangles (theNbTris, theToCopyData); - return true; - } - return false; - } + Standard_EXPORT virtual bool setNbTriangles (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbTris, + Standard_Boolean theToCopyData = false) const; //! Adds triangle element. //! @param[in] theMesh triangulation to be modified @@ -248,26 +205,29 @@ protected: //! @name interface for filling triangulation data //! @return 0 if node indexes are out of range, //! -1 if triangle is degenerated and should be skipped, //! 1 in case of success operation. - virtual Standard_Integer setTriangle (const Handle(Poly_Triangulation)& theMesh, - Standard_Integer theIndex, - const Poly_Triangle& theTriangle) const - { - if (theTriangle.Value (1) < 1 || theTriangle.Value (1) > theMesh->NbNodes() - || theTriangle.Value (2) < 1 || theTriangle.Value (2) > theMesh->NbNodes() - || theTriangle.Value (3) < 1 || theTriangle.Value (3) > theMesh->NbNodes()) - { - return 0; - } - if (myToSkipDegenerateTris - && (theTriangle.Value (1) == theTriangle.Value (2) - || theTriangle.Value (1) == theTriangle.Value (3) - || theTriangle.Value (2) == theTriangle.Value (3))) - { - return -1; - } - theMesh->SetTriangle (theIndex, theTriangle); - return 1; - } + Standard_EXPORT virtual Standard_Integer setTriangle (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const Poly_Triangle& theTriangle) const; + + //! Resizes array of triangles to specified size. + //! @param[in] theMesh triangulation to be modified + //! @param[in] theNbTris elements number + //! @param[in] theToCopyData copy old triangles into new array + //! @return TRUE in case of success operation + Standard_EXPORT virtual bool setNbEdges (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theNbTris, + Standard_Boolean theToCopyData = false) const; + + //! Adds triangle element. + //! @param[in] theMesh triangulation to be modified + //! @param theIndex triangle index starting from 1 + //! @param theTriangle triangle nodes starting from 1 + //! @return 0 if node indexes are out of range, + //! -1 if triangle is degenerated and should be skipped, + //! 1 in case of success operation. + Standard_EXPORT virtual Standard_Integer setEdge (const Handle(RWMesh_TriangulationSource)& theMesh, + Standard_Integer theIndex, + const Standard_Integer theEdge) const; protected: diff --git a/src/RWMesh/RWMesh_TriangulationSource.cxx b/src/RWMesh/RWMesh_TriangulationSource.cxx index 39beb673d1..ac8eb691dc 100644 --- a/src/RWMesh/RWMesh_TriangulationSource.cxx +++ b/src/RWMesh/RWMesh_TriangulationSource.cxx @@ -49,9 +49,24 @@ Standard_Boolean RWMesh_TriangulationSource::loadDeferredData (const Handle(OSD_ { 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 cab9293d7e..ff2a405c1b 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,13 +45,35 @@ 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 actually loaded values //! (due to broken header or extra mesh processing). //! Always check triangulation size of actually loaded data in code to avoid out-of-range issues. - virtual Standard_Integer NbDeferredNodes() const Standard_OVERRIDE { return myNbDefNodes; } + virtual Standard_Integer NbDeferredNodes() const { return myNbDefNodes; } //! Sets number of nodes for deferred loading. void SetNbDeferredNodes (const Standard_Integer theNbNodes) { myNbDefNodes = theNbNodes; } @@ -59,11 +82,21 @@ public: //! @name late-load deferred data interface //! Note: this is estimated values defined in object header, which might be different from actually loaded values //! (due to broken header or extra mesh processing). //! Always check triangulation size of actually loaded data in code to avoid out-of-range issues. - virtual Standard_Integer NbDeferredTriangles() const Standard_OVERRIDE { return myNbDefTriangles; } + virtual Standard_Integer NbDeferredTriangles() const { return myNbDefTriangles; } //! 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. @@ -72,10 +105,11 @@ protected: 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; };