]> OCCT Git - occt.git/commitdiff
0032061: Data Exchange, RWGltf_CafWriter - exporting XBF file produces an invalid...
authorkgv <kgv@opencascade.com>
Mon, 18 Jan 2021 11:58:22 +0000 (14:58 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 20 Jan 2021 18:24:17 +0000 (21:24 +0300)
Empty Nodes are now skipped while filling in Scene node map.

src/RWGltf/RWGltf_CafWriter.cxx
src/RWGltf/RWGltf_GltfJsonParser.cxx
tests/de_mesh/gltf_write/empty [new file with mode: 0644]

index 99b2e271f0af811a33e800b4b3d7846a1a87e5c9..aebe94348d1e33dac7372b99b3fef5b41a410bbb 100644 (file)
@@ -639,7 +639,29 @@ bool RWGltf_CafWriter::writeJson (const Handle(TDocStd_Document)&  theDocument,
     {
       continue;
     }
-    aSceneNodeMap.Add (aDocNode);
+
+    bool hasMeshData = false;
+    if (!aDocNode.IsAssembly)
+    {
+      for (RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style); aFaceIter.More(); aFaceIter.Next())
+      {
+        if (!toSkipFaceMesh (aFaceIter))
+        {
+          hasMeshData = true;
+          break;
+        }
+      }
+    }
+    if (hasMeshData)
+    {
+      aSceneNodeMap.Add (aDocNode);
+    }
+    else
+    {
+      // glTF disallows empty meshes / primitive arrays
+      const TCollection_AsciiString aNodeName = readNameAttribute (aDocNode.RefLabel);
+      Message::SendWarning (TCollection_AsciiString("RWGltf_CafWriter skipped node '") + aNodeName + "' without triangulation data");
+    }
   }
 
   rapidjson::OStreamWrapper aFileStream (aGltfContentFile);
@@ -1273,20 +1295,8 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM
   {
     const XCAFPrs_DocumentNode& aDocNode = aSceneNodeIter.Value();
     const TCollection_AsciiString aNodeName = readNameAttribute (aDocNode.RefLabel);
-    {
-      RWMesh_FaceIterator aFaceIter(aDocNode.RefLabel, TopLoc_Location(), false);
-      if (!aFaceIter.More())
-      {
-        Message::SendWarning (TCollection_AsciiString("RWGltf_CafWriter skipped node '") + aNodeName + "' without triangulation data");
-        continue;
-      }
-    }
-    myWriter->StartObject();
-    myWriter->Key ("name");
-    myWriter->String (aNodeName.ToCString());
-    myWriter->Key ("primitives");
-    myWriter->StartArray();
 
+    bool toStartPrims = true;
     Standard_Integer aNbFacesInNode = 0;
     for (RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style); aFaceIter.More(); aFaceIter.Next(), ++aNbFacesInNode)
     {
@@ -1295,6 +1305,16 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM
         continue;
       }
 
+      if (toStartPrims)
+      {
+        toStartPrims = false;
+        myWriter->StartObject();
+        myWriter->Key ("name");
+        myWriter->String (aNodeName.ToCString());
+        myWriter->Key ("primitives");
+        myWriter->StartArray();
+      }
+
       const RWGltf_GltfFace& aGltfFace = myBinDataMap.Find (aFaceIter.Face());
       const TCollection_AsciiString aMatId = myMaterialMap->FindMaterial (aFaceIter.FaceStyle());
       myWriter->StartObject();
@@ -1329,8 +1349,12 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM
       }
       myWriter->EndObject();
     }
-    myWriter->EndArray();
-    myWriter->EndObject();
+
+    if (!toStartPrims)
+    {
+      myWriter->EndArray();
+      myWriter->EndObject();
+    }
   }
   myWriter->EndArray();
 #else
@@ -1357,19 +1381,16 @@ void RWGltf_CafWriter::writeNodes (const Handle(TDocStd_Document)&  theDocument,
        aDocExplorer.More(); aDocExplorer.Next())
   {
     const XCAFPrs_DocumentNode& aDocNode = aDocExplorer.Current();
-    {
-      RWMesh_FaceIterator aFaceIter(aDocNode.RefLabel, TopLoc_Location(), false);
-      if (!aFaceIter.More())
-      {
-        continue;
-      }
-    }
     if (theLabelFilter != NULL
     && !theLabelFilter->Contains (aDocNode.Id))
     {
       continue;
     }
 
+    // keep empty nodes
+    //RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, TopLoc_Location(), false);
+    //if (!aFaceIter.More()) { continue; }
+
     Standard_Integer aNodeIndex = aSceneNodeMapWithChildren.Add (aDocNode);
     if (aDocExplorer.CurrentDepth() == 0)
     {
@@ -1490,11 +1511,11 @@ void RWGltf_CafWriter::writeNodes (const Handle(TDocStd_Document)&  theDocument,
     }
     if (!aDocNode.IsAssembly)
     {
-      myWriter->Key ("mesh");
       // Mesh order of current node is equal to order of this node in scene nodes map
       Standard_Integer aMeshIdx = theSceneNodeMap.FindIndex (aDocNode.Id);
       if (aMeshIdx > 0)
       {
+        myWriter->Key ("mesh");
         myWriter->Int (aMeshIdx - 1);
       }
     }
index 9d2add6d2172983a3f4316a19d537e1ed56ab771..c2ea361ffbd3832fcb78b7756f237314564717e8 100644 (file)
@@ -1317,7 +1317,8 @@ bool RWGltf_GltfJsonParser::gltfParseMesh (TopoDS_Shape& theMeshShape,
 {
   const RWGltf_JsonValue* aName  = findObjectMember (theMesh, "name");
   const RWGltf_JsonValue* aPrims = findObjectMember (theMesh, "primitives");
-  if (!aPrims->IsArray())
+  if (aPrims == NULL
+  || !aPrims->IsArray())
   {
     reportGltfError ("Primitive array attributes within Mesh '" + theMeshId + "' is not an array.");
     return false;
diff --git a/tests/de_mesh/gltf_write/empty b/tests/de_mesh/gltf_write/empty
new file mode 100644 (file)
index 0000000..e109545
--- /dev/null
@@ -0,0 +1,21 @@
+puts "========"
+puts "0032061: Data Exchange, RWGltf_CafWriter - exporting XBF file produces an invalid glTF document"
+puts "========"
+
+set aTmpGltf "${imagedir}/${casename}_tmp.glb"
+pload MODELING OCAF XDE VISUALIZATION
+
+# create a document with one shape without triangulation
+box b1 0 0 0 1 2 3
+box b2 3 3 3 1 2 3
+compound ce
+compound b1 b2 ce cc
+incmesh b2 1
+XNewDoc   DD
+XAddShape DD cc 1
+WriteGltf DD "$aTmpGltf"
+Close     DD
+
+ReadGltf  D "$aTmpGltf"
+XGetOneShape s D
+checknbshapes s -face 6 -compound 1