]> OCCT Git - occt.git/commitdiff
Data Exchange, GLTF Reader - Add stream to json parser to read lines and points #489
authorsshutina <svetlana.shutina@opencascade.com>
Sat, 12 Apr 2025 12:40:29 +0000 (13:40 +0100)
committerGitHub <noreply@github.com>
Sat, 12 Apr 2025 12:40:29 +0000 (13:40 +0100)
Reorganize GLTF mesh reader to work with streams.
The updated scenario is impact on Edge and Vertex reading, which were
  rely on postponed loading operation, which re-create stream by file name.

src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.cxx
src/DataExchange/TKDEGLTF/RWGltf/RWGltf_GltfJsonParser.hxx
src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.cxx
src/DataExchange/TKDEGLTF/RWGltf/RWGltf_TriangulationReader.hxx

index 292cadbd48cda825cbbe9314a7ff70ba246b15c4..989c4187512080153b6c4aee13d1aad98cf9dbb1 100644 (file)
@@ -20,6 +20,7 @@
 #include <Message_Messenger.hxx>
 #include <Message_ProgressScope.hxx>
 #include <OSD_File.hxx>
+#include <OSD_FileSystem.hxx>
 #include <OSD_OpenFile.hxx>
 #include <OSD_Path.hxx>
 #include <OSD_ThreadPool.hxx>
@@ -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<RWGltf_GltfPrimArrayData>::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<std::istream> 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
 
 //=================================================================================================
index ea0843eb2b6558b20c7172ef4efc488ed22121f4..7982d2e41d84cef5e3a77e424eb0dc42812a1257 100644 (file)
@@ -126,6 +126,9 @@ public:
   //! Return face list for loading triangulation.
   NCollection_Vector<TopoDS_Face>& FaceList() { return myFaceList; }
 
+  //! Set inpit stream.
+  void SetStream(std::shared_ptr<std::istream>& 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<std::istream> myStream; //!< input stream
+
   NCollection_DataMap<TCollection_AsciiString, Handle(RWGltf_MaterialMetallicRoughness)>
                                                                               myMaterialsPbr;
   NCollection_DataMap<TCollection_AsciiString, Handle(RWGltf_MaterialCommon)> myMaterialsCommon;
index 445e315b66f7330c2f71594f338eeb3f15bfb387..77dfdf4a3a95a130b84ae508e0dcbcc8c88da1c1 100644 (file)
@@ -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();
index d3331388dc02d91777eaf53b63381fd869e031da..d61c336e0c497371a7b7e7fbb81356b6c3a936dd 100644 (file)
@@ -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;