From 8a17a8bb45c4c633dc25ab6019ba7f94c019c9f2 Mon Sep 17 00:00:00 2001 From: kgv Date: Thu, 9 Sep 2021 21:59:18 +0300 Subject: [PATCH] 0032540: RWGltf_CafReader - optional "scene" parameter encoded as mandatory First scene is now loaded when default one is undefined. --- src/RWGltf/RWGltf_CafReader.cxx | 2 ++ src/RWGltf/RWGltf_CafReader.hxx | 7 ++++ src/RWGltf/RWGltf_GltfJsonParser.cxx | 47 +++++++++++++++++++++++++-- src/RWGltf/RWGltf_GltfJsonParser.hxx | 4 +++ src/RWGltf/RWGltf_GltfRootElement.hxx | 2 +- src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx | 12 +++++++ 6 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/RWGltf/RWGltf_CafReader.cxx b/src/RWGltf/RWGltf_CafReader.cxx index 499ffdb0e8..c53b59b11a 100644 --- a/src/RWGltf/RWGltf_CafReader.cxx +++ b/src/RWGltf/RWGltf_CafReader.cxx @@ -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) { diff --git a/src/RWGltf/RWGltf_CafReader.hxx b/src/RWGltf/RWGltf_CafReader.hxx index 6d36cb7504..d084408d43 100644 --- a/src/RWGltf/RWGltf_CafReader.hxx +++ b/src/RWGltf/RWGltf_CafReader.hxx @@ -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 diff --git a/src/RWGltf/RWGltf_GltfJsonParser.cxx b/src/RWGltf/RWGltf_GltfJsonParser.cxx index e29b4b4e47..a77903cc6c 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.cxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.cxx @@ -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."); diff --git a/src/RWGltf/RWGltf_GltfJsonParser.hxx b/src/RWGltf/RWGltf_GltfJsonParser.hxx index 922b9790fc..7fcb5bce51 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.hxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.hxx @@ -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 diff --git a/src/RWGltf/RWGltf_GltfRootElement.hxx b/src/RWGltf/RWGltf_GltfRootElement.hxx index 7d8d0e6566..f0b5a6917c 100644 --- a/src/RWGltf/RWGltf_GltfRootElement.hxx +++ b/src/RWGltf/RWGltf_GltfRootElement.hxx @@ -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 diff --git a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx index a1ab08d303..2f96e14eb6 100644 --- a/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx +++ b/src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx @@ -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", -- 2.20.1