mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
0032061: Data Exchange, RWGltf_CafWriter - exporting XBF file produces an invalid glTF document
Empty Nodes are now skipped while filling in Scene node map.
This commit is contained in:
parent
78c4e836b1
commit
4925946065
@ -639,7 +639,29 @@ bool RWGltf_CafWriter::writeJson (const Handle(TDocStd_Document)& theDocument,
|
|||||||
{
|
{
|
||||||
continue;
|
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);
|
rapidjson::OStreamWrapper aFileStream (aGltfContentFile);
|
||||||
@ -1273,20 +1295,8 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM
|
|||||||
{
|
{
|
||||||
const XCAFPrs_DocumentNode& aDocNode = aSceneNodeIter.Value();
|
const XCAFPrs_DocumentNode& aDocNode = aSceneNodeIter.Value();
|
||||||
const TCollection_AsciiString aNodeName = readNameAttribute (aDocNode.RefLabel);
|
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;
|
Standard_Integer aNbFacesInNode = 0;
|
||||||
for (RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style); aFaceIter.More(); aFaceIter.Next(), ++aNbFacesInNode)
|
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;
|
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 RWGltf_GltfFace& aGltfFace = myBinDataMap.Find (aFaceIter.Face());
|
||||||
const TCollection_AsciiString aMatId = myMaterialMap->FindMaterial (aFaceIter.FaceStyle());
|
const TCollection_AsciiString aMatId = myMaterialMap->FindMaterial (aFaceIter.FaceStyle());
|
||||||
myWriter->StartObject();
|
myWriter->StartObject();
|
||||||
@ -1329,8 +1349,12 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM
|
|||||||
}
|
}
|
||||||
myWriter->EndObject();
|
myWriter->EndObject();
|
||||||
}
|
}
|
||||||
myWriter->EndArray();
|
|
||||||
myWriter->EndObject();
|
if (!toStartPrims)
|
||||||
|
{
|
||||||
|
myWriter->EndArray();
|
||||||
|
myWriter->EndObject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
myWriter->EndArray();
|
myWriter->EndArray();
|
||||||
#else
|
#else
|
||||||
@ -1357,19 +1381,16 @@ void RWGltf_CafWriter::writeNodes (const Handle(TDocStd_Document)& theDocument,
|
|||||||
aDocExplorer.More(); aDocExplorer.Next())
|
aDocExplorer.More(); aDocExplorer.Next())
|
||||||
{
|
{
|
||||||
const XCAFPrs_DocumentNode& aDocNode = aDocExplorer.Current();
|
const XCAFPrs_DocumentNode& aDocNode = aDocExplorer.Current();
|
||||||
{
|
|
||||||
RWMesh_FaceIterator aFaceIter(aDocNode.RefLabel, TopLoc_Location(), false);
|
|
||||||
if (!aFaceIter.More())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (theLabelFilter != NULL
|
if (theLabelFilter != NULL
|
||||||
&& !theLabelFilter->Contains (aDocNode.Id))
|
&& !theLabelFilter->Contains (aDocNode.Id))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep empty nodes
|
||||||
|
//RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, TopLoc_Location(), false);
|
||||||
|
//if (!aFaceIter.More()) { continue; }
|
||||||
|
|
||||||
Standard_Integer aNodeIndex = aSceneNodeMapWithChildren.Add (aDocNode);
|
Standard_Integer aNodeIndex = aSceneNodeMapWithChildren.Add (aDocNode);
|
||||||
if (aDocExplorer.CurrentDepth() == 0)
|
if (aDocExplorer.CurrentDepth() == 0)
|
||||||
{
|
{
|
||||||
@ -1490,11 +1511,11 @@ void RWGltf_CafWriter::writeNodes (const Handle(TDocStd_Document)& theDocument,
|
|||||||
}
|
}
|
||||||
if (!aDocNode.IsAssembly)
|
if (!aDocNode.IsAssembly)
|
||||||
{
|
{
|
||||||
myWriter->Key ("mesh");
|
|
||||||
// Mesh order of current node is equal to order of this node in scene nodes map
|
// Mesh order of current node is equal to order of this node in scene nodes map
|
||||||
Standard_Integer aMeshIdx = theSceneNodeMap.FindIndex (aDocNode.Id);
|
Standard_Integer aMeshIdx = theSceneNodeMap.FindIndex (aDocNode.Id);
|
||||||
if (aMeshIdx > 0)
|
if (aMeshIdx > 0)
|
||||||
{
|
{
|
||||||
|
myWriter->Key ("mesh");
|
||||||
myWriter->Int (aMeshIdx - 1);
|
myWriter->Int (aMeshIdx - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1317,7 +1317,8 @@ bool RWGltf_GltfJsonParser::gltfParseMesh (TopoDS_Shape& theMeshShape,
|
|||||||
{
|
{
|
||||||
const RWGltf_JsonValue* aName = findObjectMember (theMesh, "name");
|
const RWGltf_JsonValue* aName = findObjectMember (theMesh, "name");
|
||||||
const RWGltf_JsonValue* aPrims = findObjectMember (theMesh, "primitives");
|
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.");
|
reportGltfError ("Primitive array attributes within Mesh '" + theMeshId + "' is not an array.");
|
||||||
return false;
|
return false;
|
||||||
|
21
tests/de_mesh/gltf_write/empty
Normal file
21
tests/de_mesh/gltf_write/empty
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user