diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx index 292cadbd48..989c418751 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1932,10 +1933,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray(TopoDS_Shape& th { Message::SendWarning("Deferred loading is available only for triangulations. Other elements " "will be loaded immediately."); - Handle(RWGltf_TriangulationReader) aReader = new RWGltf_TriangulationReader(); - aReader->SetCoordinateSystemConverter(myCSTrsf); - aMeshData->SetReader(aReader); - aMeshData->LoadDeferredData(); + fillMeshData(aMeshData); } TopoDS_Shape aShape; @@ -2457,6 +2455,49 @@ void RWGltf_GltfJsonParser::bindNamedShape(TopoDS_Shape& the } myShapeMap[theGroup].Bind(theId, theShape); } + +//================================================================================================= + +bool RWGltf_GltfJsonParser::fillMeshData( + const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData) const +{ + const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem(); + for (NCollection_Sequence::Iterator aDataIter(theMeshData->Data()); + aDataIter.More(); + aDataIter.Next()) + { + const RWGltf_GltfPrimArrayData& aData = aDataIter.Value(); + + Handle(RWGltf_TriangulationReader) aReader = new RWGltf_TriangulationReader(); + aReader->SetCoordinateSystemConverter(myCSTrsf); + std::shared_ptr aNewStream; + if (myStream != nullptr) + { + aNewStream = myStream; + aNewStream->seekg(aData.StreamOffset); + } + else + { + aNewStream = aFileSystem->OpenIStream(aData.StreamUri, + std::ios::in | std::ios::binary, + aData.StreamOffset); + } + + if (aNewStream == nullptr) + { + reportGltfError("Buffer '" + aData.StreamUri + "' isn't defined."); + return false; + } + + if (!aReader + ->ReadStream(theMeshData, theMeshData, *aNewStream.get(), aData.Accessor, aData.Type)) + { + return false; + } + } + + return true; +} #endif //================================================================================================= diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.hxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.hxx index ea0843eb2b..7982d2e41d 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.hxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.hxx @@ -126,6 +126,9 @@ public: //! Return face list for loading triangulation. NCollection_Vector& FaceList() { return myFaceList; } + //! Set inpit stream. + void SetStream(std::shared_ptr& theStream) { myStream = theStream; } + protected: #ifdef HAVE_RAPIDJSON //! Search mandatory root elements in the document. @@ -421,6 +424,11 @@ private: const RWGltf_JsonValue* theScaleVal, const RWGltf_JsonValue* theTranslationVal, TopLoc_Location& theResult) const; + + //! Fill lines and points data not deferred. + //! @param theMeshData source glTF triangulation + Standard_EXPORT bool fillMeshData(const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData) const; + #endif protected: //! Print message about invalid glTF syntax. @@ -437,6 +445,8 @@ protected: // clang-format on TColStd_IndexedDataMapOfStringString* myMetadata; //!< file metadata + mutable std::shared_ptr myStream; //!< input stream + NCollection_DataMap myMaterialsPbr; NCollection_DataMap myMaterialsCommon; diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx index 445e315b66..77dfdf4a3a 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx @@ -562,6 +562,19 @@ bool RWGltf_TriangulationReader::readBuffer( const RWGltf_GltfAccessor& theAccessor, RWGltf_GltfArrayType theType) const +{ + return ReadStream(theSourceMesh, theDestMesh, theStream, theAccessor, theType); +} + +//================================================================================================= + +bool RWGltf_TriangulationReader::ReadStream( + const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceMesh, + const Handle(Poly_Triangulation)& theDestMesh, + std::istream& theStream, + const RWGltf_GltfAccessor& theAccessor, + RWGltf_GltfArrayType theType) const + { const TCollection_AsciiString& aName = theSourceMesh->Id(); const RWGltf_GltfPrimitiveMode aPrimMode = theSourceMesh->PrimitiveMode(); diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.hxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.hxx index d3331388dc..d61c336e0c 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.hxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.hxx @@ -36,6 +36,19 @@ public: Standard_EXPORT bool LoadStreamData(const Handle(RWMesh_TriangulationSource)& theSourceMesh, const Handle(Poly_Triangulation)& theDestMesh) const; + //! Fills triangulation, lines and points data. + //! @param theSourceGltfMesh source glTF triangulation + //! @param theDestMesh triangulation to be modified + //! @param theStream input stream to read from + //! @param theAccessor buffer accessor + //! @param theType array type + //! @return FALSE on error + Standard_EXPORT bool ReadStream(const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceMesh, + const Handle(Poly_Triangulation)& theDestMesh, + std::istream& theStream, + const RWGltf_GltfAccessor& theAccessor, + RWGltf_GltfArrayType theType) const; + protected: //! Reports error. Standard_EXPORT virtual void reportError(const TCollection_AsciiString& theText) const;