0032540: RWGltf_CafReader - optional "scene" parameter encoded as mandatory
authorkgv <kgv@opencascade.com>
Thu, 9 Sep 2021 18:59:18 +0000 (21:59 +0300)
committersmoskvin <smoskvin@opencascade.com>
Fri, 10 Sep 2021 17:24:52 +0000 (20:24 +0300)
First scene is now loaded when default one is undefined.

src/RWGltf/RWGltf_CafReader.cxx
src/RWGltf/RWGltf_CafReader.hxx
src/RWGltf/RWGltf_GltfJsonParser.cxx
src/RWGltf/RWGltf_GltfJsonParser.hxx
src/RWGltf/RWGltf_GltfRootElement.hxx
src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx

index 499ffdb..c53b59b 100644 (file)
@@ -168,6 +168,7 @@ protected:
 RWGltf_CafReader::RWGltf_CafReader()
 : myToParallel (false),
   myToSkipEmptyNodes (true),
+  myToLoadAllScenes (false),
   myUseMeshNameAsFallback (true),
   myIsDoublePrecision (false),
   myToSkipLateDataLoading (false),
@@ -290,6 +291,7 @@ Standard_Boolean RWGltf_CafReader::performMesh (const TCollection_AsciiString& t
   aDoc.SetErrorPrefix (anErrPrefix);
   aDoc.SetCoordinateSystemConverter (myCoordSysConverter);
   aDoc.SetSkipEmptyNodes (myToSkipEmptyNodes);
+  aDoc.SetLoadAllScenes (myToLoadAllScenes);
   aDoc.SetMeshNameAsFallback (myUseMeshNameAsFallback);
   if (!theToProbe)
   {
index 6d36cb7..d084408 100644 (file)
@@ -43,6 +43,12 @@ public:
   //! Set flag to ignore nodes without Geometry.
   void SetSkipEmptyNodes (bool theToSkip) { myToSkipEmptyNodes = theToSkip; }
 
+  //! Return TRUE if all scenes in the document should be loaded, FALSE by default which means only main (default) scene will be loaded.
+  bool ToLoadAllScenes() const { return myToLoadAllScenes; }
+
+  //! Set flag to flag to load all scenes in the document, FALSE by default which means only main (default) scene will be loaded.
+  void SetLoadAllScenes (bool theToLoadAll) { myToLoadAllScenes = theToLoadAll; }
+
   //! Set flag to use Mesh name in case if Node name is empty, TRUE by default.
   bool ToUseMeshNameAsFallback() { return myUseMeshNameAsFallback; }
 
@@ -106,6 +112,7 @@ protected:
 
   Standard_Boolean myToParallel;            //!< flag to use multithreading; FALSE by default
   Standard_Boolean myToSkipEmptyNodes;      //!< ignore nodes without Geometry; TRUE by default
+  Standard_Boolean myToLoadAllScenes;       //!< flag to load all scenes in the document, FALSE by default
   Standard_Boolean myUseMeshNameAsFallback; //!< flag to use Mesh name in case if Node name is empty, TRUE by default
   Standard_Boolean myIsDoublePrecision;     //!< flag to fill in triangulation using single or double precision
   Standard_Boolean myToSkipLateDataLoading; //!< flag to skip triangulation loading
index e29b4b4..a77903c 100644 (file)
@@ -186,6 +186,7 @@ RWGltf_GltfJsonParser::RWGltf_GltfJsonParser (TopTools_SequenceOfShape& theRootS
   myIsBinary (false),
   myIsGltf1 (false),
   myToSkipEmptyNodes (true),
+  myToLoadAllScenes (false),
   myUseMeshNameAsFallback (true),
   myToProbeHeader (false)
 {
@@ -236,7 +237,8 @@ bool RWGltf_GltfJsonParser::gltfParseRoots()
 
   for (int aRootNameIter = 0; aRootNameIter < RWGltf_GltfRootElement_NB_MANDATORY; ++aRootNameIter)
   {
-    if (myGltfRoots[aRootNameIter].IsNull())
+    if (myGltfRoots[aRootNameIter].IsNull()
+     && aRootNameIter != RWGltf_GltfRootElement_Scene)
     {
       reportGltfError ("Member '" + RWGltf_GltfRootElementName ((RWGltf_GltfRootElement )aRootNameIter) + "' is not found.");
       return false;
@@ -984,8 +986,49 @@ bool RWGltf_GltfJsonParser::gltfParseTextureInBufferView (Handle(Image_Texture)&
 // =======================================================================
 bool RWGltf_GltfJsonParser::gltfParseScene (const Message_ProgressRange& theProgress)
 {
+  const RWGltf_JsonValue* aScenes = myGltfRoots[RWGltf_GltfRootElement_Scenes].Root();
+  if (myToLoadAllScenes
+  && !myIsGltf1
+  &&  aScenes->IsArray()
+  &&  aScenes->Size() > 1)
+  {
+    Message_ProgressScope aPS (theProgress, "Parsing scenes", aScenes->Size());
+    for (rapidjson::Value::ConstValueIterator aSceneIter = aScenes->Begin(); aSceneIter != aScenes->End(); ++aSceneIter)
+    {
+      if (!aPS.More())
+      {
+        return false;
+      }
+      Message_ProgressRange aRange = aPS.Next();
+      const RWGltf_JsonValue* aSceneNodes = findObjectMember (*aSceneIter, "nodes");
+      if (aSceneNodes == NULL
+      || !aSceneNodes->IsArray())
+      {
+        reportGltfWarning ("Empty scene '" + getKeyString (*aSceneIter) + "'.");
+      }
+      if (!gltfParseSceneNodes (*myRootShapes, *aSceneNodes, aRange))
+      {
+        return false;
+      }
+    }
+    return true;
+  }
+
   // search default scene
-  const RWGltf_JsonValue* aDefScene = myGltfRoots[RWGltf_GltfRootElement_Scenes].FindChild (*myGltfRoots[RWGltf_GltfRootElement_Scene].Root());
+  const RWGltf_JsonValue* aDefScene = NULL;
+  if (!myGltfRoots[RWGltf_GltfRootElement_Scene].IsNull())
+  {
+    aDefScene = myGltfRoots[RWGltf_GltfRootElement_Scenes].FindChild (*myGltfRoots[RWGltf_GltfRootElement_Scene].Root());
+  }
+  else if (!myIsGltf1)
+  {
+    rapidjson::Value::ConstValueIterator aSceneIter = aScenes->Begin();
+    if (aSceneIter != aScenes->End())
+    {
+      aDefScene = aSceneIter;
+      reportGltfWarning ("Default scene is undefined, the first one will be loaded.");
+    }
+  }
   if (aDefScene == NULL)
   {
     reportGltfError ("Default scene is not found.");
index 922b979..7fcb5bc 100644 (file)
@@ -111,6 +111,9 @@ public:
   //! Set flag to ignore nodes without Geometry, TRUE by default.
   void SetSkipEmptyNodes (bool theToSkip) { myToSkipEmptyNodes = theToSkip; }
 
+  //! Set flag to flag to load all scenes in the document, FALSE by default which means only main (default) scene will be loaded.
+  void SetLoadAllScenes (bool theToLoadAll) { myToLoadAllScenes = theToLoadAll; }
+
   //! Set flag to use Mesh name in case if Node name is empty, TRUE by default.
   void SetMeshNameAsFallback (bool theToFallback) { myUseMeshNameAsFallback = theToFallback; }
 
@@ -432,6 +435,7 @@ protected:
   bool                      myIsBinary;       //!< binary document
   bool                      myIsGltf1;        //!< obsolete glTF 1.0 version format
   bool                      myToSkipEmptyNodes; //!< ignore nodes without Geometry
+  bool                      myToLoadAllScenes;  //!< flag to load all scenes in the document, FALSE by default
   bool                      myUseMeshNameAsFallback; //!< flag to use Mesh name in case if Node name is empty, TRUE by default
   bool                      myToProbeHeader;  //!< flag to probe header without full reading, FALSE by default
 
index 7d8d0e6..f0b5a69 100644 (file)
@@ -20,7 +20,7 @@ enum RWGltf_GltfRootElement
 {
   RWGltf_GltfRootElement_Asset,        //!< "asset"       element, mandatory
   RWGltf_GltfRootElement_Scenes,       //!< "scenes"      element, mandatory
-  RWGltf_GltfRootElement_Scene,        //!< "scene"       element, mandatory
+  RWGltf_GltfRootElement_Scene,        //!< "scene"       element, optional
   RWGltf_GltfRootElement_Nodes,        //!< "nodes"       element, mandatory
   RWGltf_GltfRootElement_Meshes,       //!< "meshes"      element, mandatory
   RWGltf_GltfRootElement_Accessors,    //!< "accessors"   element, mandatory
index a1ab08d..2f96e14 100644 (file)
@@ -187,6 +187,7 @@ static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
   Standard_Boolean toSkipLateDataLoading = Standard_False;
   Standard_Boolean toKeepLateData = Standard_True;
   Standard_Boolean toPrintDebugInfo = Standard_False;
+  Standard_Boolean toLoadAllScenes = Standard_False;
   Standard_Boolean isNoDoc = (TCollection_AsciiString(theArgVec[0]) == "readgltf");
   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
   {
@@ -246,6 +247,15 @@ static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
         ++anArgIter;
       }
     }
+    else if (anArgCase == "-allscenes")
+    {
+      toLoadAllScenes = Standard_True;
+      if (anArgIter + 1 < theNbArgs
+       && Draw::ParseOnOff (theArgVec[anArgIter + 1], toLoadAllScenes))
+      {
+        ++anArgIter;
+      }
+    }
     else if (anArgCase == "-toprintinfo"
           || anArgCase == "-toprintdebuginfo")
     {
@@ -322,6 +332,7 @@ static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
   aReader.SetToSkipLateDataLoading (toSkipLateDataLoading);
   aReader.SetToKeepLateData (toKeepLateData);
   aReader.SetToPrintDebugMessages (toPrintDebugInfo);
+  aReader.SetLoadAllScenes (toLoadAllScenes);
   if (toListExternalFiles)
   {
     aReader.ProbeHeader (aFilePath);
@@ -2032,6 +2043,7 @@ void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
                    "\n\t\t:                    (false by default)"
                    "\n\t\t:   -keepLate data is loaded into itself with preservation of information"
                    "\n\t\t:             about deferred storage to load/unload this data later.",
+                   "\n\t\t:   -allScenes load all scenes defined in the document instead of default one (false by default)"
                    "\n\t\t:   -toPrintDebugInfo print additional debug information during data reading"
                    __FILE__, ReadGltf, g);
   theCommands.Add ("readgltf",