diff --git a/src/RWGltf/RWGltf_CafWriter.cxx b/src/RWGltf/RWGltf_CafWriter.cxx index 71f88bb499..b54198fba7 100644 --- a/src/RWGltf/RWGltf_CafWriter.cxx +++ b/src/RWGltf/RWGltf_CafWriter.cxx @@ -434,13 +434,14 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, TopLoc_Location(), true, aDocNode.Style); if (myToMergeFaces) { - if (myBinDataMap.Contains (aFaceIter.ExploredShape())) + RWGltf_StyledShape aStyledShape (aFaceIter.ExploredShape(), aDocNode.Style); + if (myBinDataMap.Contains (aStyledShape)) { continue; } Handle(RWGltf_GltfFaceList) aGltfFaceList = new RWGltf_GltfFaceList(); - myBinDataMap.Add (aFaceIter.ExploredShape(), aGltfFaceList); + myBinDataMap.Add (aStyledShape, aGltfFaceList); for (; aFaceIter.More() && aPSentryBin.More(); aFaceIter.Next()) { if (toSkipFaceMesh (aFaceIter)) @@ -489,8 +490,9 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument { for (; aFaceIter.More() && aPSentryBin.More(); aFaceIter.Next()) { + RWGltf_StyledShape aStyledShape (aFaceIter.Face(), aFaceIter.FaceStyle()); if (toSkipFaceMesh (aFaceIter) - || myBinDataMap.Contains (aFaceIter.Face())) + || myBinDataMap.Contains (aStyledShape)) { continue; } @@ -500,13 +502,14 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument aGltfFace->Shape = aFaceIter.Face(); aGltfFace->Style = aFaceIter.FaceStyle(); aGltfFaceList->Append (aGltfFace); - myBinDataMap.Add (aFaceIter.Face(), aGltfFaceList); + myBinDataMap.Add (aStyledShape, aGltfFaceList); } } } Standard_Integer aNbAccessors = 0; NCollection_Map aWrittenFaces; + NCollection_DataMap aWrittenPrimData; for (Standard_Integer aTypeIter = 0; aTypeIter < 4; ++aTypeIter) { const RWGltf_GltfArrayType anArrType = (RWGltf_GltfArrayType )anArrTypes[aTypeIter]; @@ -521,6 +524,7 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument } aBuffView->ByteOffset = aBinFile->tellp(); aWrittenFaces.Clear (false); + aWrittenPrimData.Clear (false); for (ShapeToGltfFaceMap::Iterator aBinDataIter (myBinDataMap); aBinDataIter.More() && aPSentryBin.More(); aBinDataIter.Next()) { const Handle(RWGltf_GltfFaceList)& aGltfFaceList = aBinDataIter.Value(); @@ -532,6 +536,41 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument for (RWGltf_GltfFaceList::Iterator aGltfFaceIter (*aGltfFaceList); aGltfFaceIter.More() && aPSentryBin.More(); aGltfFaceIter.Next()) { const Handle(RWGltf_GltfFace)& aGltfFace = aGltfFaceIter.Value(); + + Handle(RWGltf_GltfFace) anOldGltfFace; + if (aWrittenPrimData.Find (aGltfFace->Shape, anOldGltfFace)) + { + switch (anArrType) + { + case RWGltf_GltfArrayType_Position: + { + aGltfFace->NodePos = anOldGltfFace->NodePos; + break; + } + case RWGltf_GltfArrayType_Normal: + { + aGltfFace->NodeNorm = anOldGltfFace->NodeNorm; + break; + } + case RWGltf_GltfArrayType_TCoord0: + { + aGltfFace->NodeUV = anOldGltfFace->NodeUV; + break; + } + case RWGltf_GltfArrayType_Indices: + { + aGltfFace->Indices = anOldGltfFace->Indices; + break; + } + default: + { + break; + } + } + continue; + } + aWrittenPrimData.Bind (aGltfFace->Shape, aGltfFace); + for (RWMesh_FaceIterator aFaceIter (aGltfFace->Shape, aGltfFace->Style); aFaceIter.More() && aPSentryBin.More(); aFaceIter.Next()) { switch (anArrType) @@ -864,6 +903,8 @@ void RWGltf_CafWriter::writeAccessors (const RWGltf_GltfSceneNodeMap& ) RWGltf_GltfArrayType_Indices }; NCollection_Map aWrittenFaces; + NCollection_Map aWrittenIds; + int aNbAccessors = 0; for (Standard_Integer aTypeIter = 0; aTypeIter < 4; ++aTypeIter) { const RWGltf_GltfArrayType anArrType = (RWGltf_GltfArrayType )anArrTypes[aTypeIter]; @@ -883,21 +924,71 @@ void RWGltf_CafWriter::writeAccessors (const RWGltf_GltfSceneNodeMap& ) { case RWGltf_GltfArrayType_Position: { + const int anAccessorId = aGltfFace->NodePos.Id; + if (anAccessorId == RWGltf_GltfAccessor::INVALID_ID + || !aWrittenIds.Add (anAccessorId)) + { + break; + } + + if (anAccessorId != aNbAccessors) + { + throw Standard_ProgramError ("Internal error: RWGltf_CafWriter::writeAccessors()"); + } + ++aNbAccessors; writePositions (*aGltfFace); break; } case RWGltf_GltfArrayType_Normal: { + const int anAccessorId = aGltfFace->NodeNorm.Id; + if (anAccessorId == RWGltf_GltfAccessor::INVALID_ID + || !aWrittenIds.Add (anAccessorId)) + { + break; + } + + if (anAccessorId != aNbAccessors) + { + throw Standard_ProgramError ("Internal error: RWGltf_CafWriter::writeAccessors()"); + } + ++aNbAccessors; writeNormals (*aGltfFace); break; } case RWGltf_GltfArrayType_TCoord0: { + const int anAccessorId = aGltfFace->NodeUV.Id; + if (anAccessorId == RWGltf_GltfAccessor::INVALID_ID + || !aWrittenIds.Add (anAccessorId) + ) + { + break; + } + + if (anAccessorId != aNbAccessors) + { + throw Standard_ProgramError ("Internal error: RWGltf_CafWriter::writeAccessors()"); + } + ++aNbAccessors; writeTextCoords (*aGltfFace); break; } case RWGltf_GltfArrayType_Indices: { + const int anAccessorId = aGltfFace->Indices.Id; + if (anAccessorId == RWGltf_GltfAccessor::INVALID_ID + || !aWrittenIds.Add (anAccessorId) + ) + { + break; + } + + if (anAccessorId != aNbAccessors) + { + throw Standard_ProgramError ("Internal error: RWGltf_CafWriter::writeAccessors()"); + } + ++aNbAccessors; writeIndices (*aGltfFace); break; } @@ -1420,7 +1511,8 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM Handle(RWGltf_GltfFaceList) aGltfFaceList; aShape.Location (TopLoc_Location()); - myBinDataMap.FindFromKey (aShape, aGltfFaceList); + RWGltf_StyledShape aStyledShape (aShape, aDocNode.Style); + myBinDataMap.FindFromKey (aStyledShape, aGltfFaceList); if (!aWrittenFaces.Add (aGltfFaceList)) { continue; @@ -1441,7 +1533,8 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM continue; } - const Handle(RWGltf_GltfFaceList)& aGltfFaceList = myBinDataMap.FindFromKey (aFaceIter.Face()); + RWGltf_StyledShape aStyledShape (aFaceIter.Face(), aFaceIter.FaceStyle()); + const Handle(RWGltf_GltfFaceList)& aGltfFaceList = myBinDataMap.FindFromKey (aStyledShape); if (!aWrittenFaces.Add (aGltfFaceList)) { continue; diff --git a/src/RWGltf/RWGltf_CafWriter.hxx b/src/RWGltf/RWGltf_CafWriter.hxx index bfc5119177..328c1b7a94 100644 --- a/src/RWGltf/RWGltf_CafWriter.hxx +++ b/src/RWGltf/RWGltf_CafWriter.hxx @@ -318,7 +318,31 @@ protected: protected: - typedef NCollection_IndexedDataMap ShapeToGltfFaceMap; + //! Shape + Style pair. + struct RWGltf_StyledShape + { + TopoDS_Shape Shape; + XCAFPrs_Style Style; + + RWGltf_StyledShape() {} + explicit RWGltf_StyledShape (const TopoDS_Shape& theShape) : Shape (theShape) {} + explicit RWGltf_StyledShape (const TopoDS_Shape& theShape, + const XCAFPrs_Style& theStyle) : Shape (theShape), Style (theStyle) {} + public: + //! Computes a hash code. + static Standard_Integer HashCode (const RWGltf_StyledShape& theShape, Standard_Integer theUpperBound) + { + return theShape.Shape.HashCode (theUpperBound); + } + //! Equality comparison. + static Standard_Boolean IsEqual (const RWGltf_StyledShape& theS1, const RWGltf_StyledShape& theS2) + { + return theS1.Shape.IsSame (theS2.Shape) + && theS1.Style.IsEqual(theS2.Style); + } + }; + + typedef NCollection_IndexedDataMap ShapeToGltfFaceMap; protected: diff --git a/src/RWGltf/RWGltf_GltfJsonParser.cxx b/src/RWGltf/RWGltf_GltfJsonParser.cxx index 9974cfa8d2..e29b4b4e47 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.cxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.cxx @@ -1340,51 +1340,27 @@ bool RWGltf_GltfJsonParser::gltfParseMesh (TopoDS_Shape& theMeshShape, return true; } + const TCollection_AsciiString aUserName ((aName != NULL && aName->IsString()) ? aName->GetString() : ""); + BRep_Builder aBuilder; TopoDS_Compound aMeshShape; int aNbFaces = 0; for (rapidjson::Value::ConstValueIterator aPrimArrIter = aPrims->Begin(); aPrimArrIter != aPrims->End(); ++aPrimArrIter) { - TCollection_AsciiString aUserName; - if (aName != NULL - && aName->IsString()) - { - aUserName = aName->GetString(); - } - - Handle(RWGltf_GltfLatePrimitiveArray) aMeshData = new RWGltf_GltfLatePrimitiveArray (theMeshId, aUserName); - if (!gltfParsePrimArray (aMeshData, theMeshId, *aPrimArrIter)) + TopoDS_Shape aFace; + if (!gltfParsePrimArray (aFace, theMeshId, aUserName, *aPrimArrIter)) { return false; } - if (!aMeshData->Data().IsEmpty()) + if (!aFace.IsNull()) { if (aMeshShape.IsNull()) { aBuilder.MakeCompound (aMeshShape); } - - TopoDS_Face aFace; - aBuilder.MakeFace (aFace, aMeshData); aBuilder.Add (aMeshShape, aFace); - if (myAttribMap != NULL - && aMeshData->HasStyle()) - { - RWMesh_NodeAttributes aShapeAttribs; - aShapeAttribs.RawName = aUserName; - - // assign material and not color - //aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor()); - - Handle(XCAFDoc_VisMaterial) aMat; - myMaterials.Find (!aMeshData->MaterialPbr().IsNull() ? aMeshData->MaterialPbr()->Id : aMeshData->MaterialCommon()->Id, aMat); - aShapeAttribs.Style.SetMaterial (aMat); - - myAttribMap->Bind (aFace, aShapeAttribs); - } - myFaceList.Append (aFace); ++aNbFaces; } } @@ -1405,8 +1381,9 @@ bool RWGltf_GltfJsonParser::gltfParseMesh (TopoDS_Shape& theMeshShape, // function : gltfParsePrimArray // purpose : // ======================================================================= -bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData, +bool RWGltf_GltfJsonParser::gltfParsePrimArray (TopoDS_Shape& thePrimArrayShape, const TCollection_AsciiString& theMeshId, + const TCollection_AsciiString& theMeshName, const RWGltf_JsonValue& thePrimArray) { const RWGltf_JsonValue* anAttribs = findObjectMember (thePrimArray, "attributes"); @@ -1447,22 +1424,69 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrim Message::SendWarning (TCollection_AsciiString() + "Primitive array within Mesh '" + theMeshId + "' skipped due to unsupported mode"); return true; } - theMeshData->SetPrimitiveMode (aMode); - // assign material + const TCollection_AsciiString aMatId = aMaterial != NULL ? getKeyString (*aMaterial) : TCollection_AsciiString(); + const TCollection_AsciiString anIndicesId = anIndices != NULL ? getKeyString (*anIndices) : TCollection_AsciiString(); + Handle(RWGltf_MaterialMetallicRoughness) aMatPbr; + Handle(RWGltf_MaterialCommon) aMatCommon; + Handle(XCAFDoc_VisMaterial) aMat; if (aMaterial != NULL) { - Handle(RWGltf_MaterialMetallicRoughness) aMatPbr; - if (myMaterialsPbr.Find (getKeyString (*aMaterial), aMatPbr)) + if (myMaterialsPbr.Find (aMatId, aMatPbr)) { - theMeshData->SetMaterialPbr (aMatPbr); + myMaterials.Find (aMatPbr->Id, aMat); } + if (myMaterialsCommon.Find (aMatId, aMatCommon)) + { + if (aMat.IsNull()) + { + myMaterials.Find (aMatCommon->Id, aMat); + } + } + } - Handle(RWGltf_MaterialCommon) aMatCommon; - if (myMaterialsCommon.Find (getKeyString (*aMaterial), aMatCommon)) + // try reusing already loaded primitive array - generate a unique id + TCollection_AsciiString aPrimArrayId, aPrimArrayIdWithMat; + aPrimArrayId += TCollection_AsciiString (aMode); + aPrimArrayId += TCollection_AsciiString (":") + anIndicesId; + for (rapidjson::Value::ConstMemberIterator anAttribIter = anAttribs->MemberBegin(); + anAttribIter != anAttribs->MemberEnd(); ++anAttribIter) + { + const TCollection_AsciiString anAttribId = getKeyString (anAttribIter->value); + aPrimArrayId += TCollection_AsciiString (":") + anAttribId; + } + aPrimArrayIdWithMat = aPrimArrayId + TCollection_AsciiString ("::") + aMatId; + if (myShapeMap[ShapeMapGroup_PrimArray].Find (aPrimArrayIdWithMat, thePrimArrayShape)) + { + return true; + } + else if (myShapeMap[ShapeMapGroup_PrimArray].Find (aPrimArrayId, thePrimArrayShape)) + { + if (myAttribMap != NULL) { - theMeshData->SetMaterialCommon (aMatCommon); + // sharing just triangulation is not much useful + //Handle(RWGltf_GltfLatePrimitiveArray) aLateData = Handle(RWGltf_GltfLatePrimitiveArray)::DownCast (BRep_Tool::Triangulation (TopoDS::Face (thePrimArrayShape), aDummy)); + //TopoDS_Face aFaceCopy; BRep_Builder().MakeFace (aFaceCopy, aLateData); + + // make a located Face copy + TopoDS_Shape aFaceCopy = thePrimArrayShape; + aFaceCopy.Location (TopLoc_Location (gp_Trsf())); + RWMesh_NodeAttributes aShapeAttribs; + aShapeAttribs.RawName = theMeshName; + aShapeAttribs.Style.SetMaterial (aMat); + myAttribMap->Bind (aFaceCopy, aShapeAttribs); + myShapeMap[ShapeMapGroup_PrimArray].Bind (aPrimArrayIdWithMat, aFaceCopy); + thePrimArrayShape = aFaceCopy; } + return true; + } + + Handle(RWGltf_GltfLatePrimitiveArray) aMeshData = new RWGltf_GltfLatePrimitiveArray (theMeshId, theMeshName); + aMeshData->SetPrimitiveMode (aMode); + if (aMaterial != NULL) + { + aMeshData->SetMaterialPbr (aMatPbr); + aMeshData->SetMaterialCommon (aMatCommon); } bool hasPositions = false; @@ -1490,7 +1514,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrim reportGltfError ("Primitive array attribute accessor key '" + anAttribId + "' points to non-existing object."); return false; } - else if (!gltfParseAccessor (theMeshData, anAttribId, *anAccessor, aType, aDracoBuf)) + else if (!gltfParseAccessor (aMeshData, anAttribId, *anAccessor, aType, aDracoBuf)) { return false; } @@ -1507,7 +1531,6 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrim if (anIndices != NULL) { - const TCollection_AsciiString anIndicesId = getKeyString (*anIndices); const RWGltf_JsonValue* anAccessor = myGltfRoots[RWGltf_GltfRootElement_Accessors].FindChild (*anIndices); if (anAccessor == NULL || !anAccessor->IsObject()) @@ -1515,16 +1538,38 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrim reportGltfError ("Primitive array indices accessor key '" + anIndicesId + "' points to non-existing object."); return false; } - else if (!gltfParseAccessor (theMeshData, anIndicesId, *anAccessor, RWGltf_GltfArrayType_Indices, aDracoBuf)) + else if (!gltfParseAccessor (aMeshData, anIndicesId, *anAccessor, RWGltf_GltfArrayType_Indices, aDracoBuf)) { return false; } } else { - theMeshData->SetNbDeferredTriangles (theMeshData->NbDeferredNodes() / 3); + aMeshData->SetNbDeferredTriangles (aMeshData->NbDeferredNodes() / 3); } + if (!aMeshData->Data().IsEmpty()) + { + TopoDS_Face aFace; + BRep_Builder aBuilder; + aBuilder.MakeFace (aFace, aMeshData); + if (myAttribMap != NULL + && aMeshData->HasStyle()) + { + RWMesh_NodeAttributes aShapeAttribs; + aShapeAttribs.RawName = theMeshName; + + // assign material and not color + //aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor()); + aShapeAttribs.Style.SetMaterial (aMat); + + myAttribMap->Bind (aFace, aShapeAttribs); + } + myFaceList.Append (aFace); + myShapeMap[ShapeMapGroup_PrimArray].Bind (aPrimArrayId, aFace); + myShapeMap[ShapeMapGroup_PrimArray].Bind (aPrimArrayIdWithMat, aFace); + thePrimArrayShape = aFace; + } return true; } @@ -1873,6 +1918,7 @@ void RWGltf_GltfJsonParser::bindNamedShape (TopoDS_Shape& theShape, return; } + TopoDS_Shape aShape = theShape; if (!theLoc.IsIdentity()) { if (!theShape.Location().IsIdentity()) @@ -1896,31 +1942,32 @@ void RWGltf_GltfJsonParser::bindNamedShape (TopoDS_Shape& theShape, aUserName = theId; } - myShapeMap[theGroup].Bind (theId, theShape); if (myAttribMap != NULL) { RWMesh_NodeAttributes aShapeAttribs; - aShapeAttribs.Name = aUserName; - aShapeAttribs.RawName = theId; + aShapeAttribs.Name = aUserName; + if (myIsGltf1) + { + aShapeAttribs.RawName = theId; + } if (theShape.ShapeType() == TopAbs_FACE) { - TopLoc_Location aDummy; - if (Handle(RWGltf_GltfLatePrimitiveArray) aLateData = Handle(RWGltf_GltfLatePrimitiveArray)::DownCast (BRep_Tool::Triangulation (TopoDS::Face (theShape), aDummy))) + RWMesh_NodeAttributes aFaceAttribs; + if (myAttribMap->Find (aShape, aFaceAttribs)) { - if (aLateData->HasStyle()) - { - // assign material and not color - //aShapeAttribs.Style.SetColorSurf (aLateData->BaseColor()); - - Handle(XCAFDoc_VisMaterial) aMat; - myMaterials.Find (!aLateData->MaterialPbr().IsNull() ? aLateData->MaterialPbr()->Id : aLateData->MaterialCommon()->Id, aMat); - aShapeAttribs.Style.SetMaterial (aMat); - } + aShapeAttribs.Style.SetMaterial (aFaceAttribs.Style.Material()); if (aShapeAttribs.Name.IsEmpty() && myUseMeshNameAsFallback) { // fallback using Mesh name - aShapeAttribs.Name = aLateData->Name(); + aShapeAttribs.Name = aFaceAttribs.RawName; + } + else if (!aFaceAttribs.Name.IsEmpty() + && theLoc.IsIdentity() + && theGroup == ShapeMapGroup_Nodes) + { + // keep Product name (from Mesh) separated from Instance name (from Node) + theShape.Location (TopLoc_Location (gp_Trsf()) * theShape.Location(), Standard_False); } } } @@ -1955,8 +2002,20 @@ void RWGltf_GltfJsonParser::bindNamedShape (TopoDS_Shape& theShape, aShapeAttribs.Name = aMeshName; } } + else if (!aShapeAttribs.Name.IsEmpty() + && theGroup == ShapeMapGroup_Nodes) + { + RWMesh_NodeAttributes anOldAttribs; + if (myAttribMap->Find (aShape, anOldAttribs) + && !anOldAttribs.Name.IsEmpty()) + { + // keep Product name (from Mesh) separated from Instance name (from Node) + theShape.Location (TopLoc_Location (gp_Trsf()) * theShape.Location(), Standard_False); + } + } myAttribMap->Bind (theShape, aShapeAttribs); } + myShapeMap[theGroup].Bind (theId, theShape); } #endif diff --git a/src/RWGltf/RWGltf_GltfJsonParser.hxx b/src/RWGltf/RWGltf_GltfJsonParser.hxx index b285932e02..922b9790fc 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.hxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.hxx @@ -188,7 +188,8 @@ protected: const RWGltf_JsonValue& theMesh); //! Parse primitive array. - Standard_EXPORT bool gltfParsePrimArray (const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData, + Standard_EXPORT bool gltfParsePrimArray (TopoDS_Shape& thePrimArrayShape, + const TCollection_AsciiString& theMeshId, const TCollection_AsciiString& theMeshName, const RWGltf_JsonValue& thePrimArray); @@ -284,8 +285,9 @@ protected: //! Groups for re-using shapes. enum ShapeMapGroup { - ShapeMapGroup_Nodes, //!< nodes - ShapeMapGroup_Meshes, //!< meshes + ShapeMapGroup_Nodes, //!< nodes + ShapeMapGroup_Meshes, //!< meshes + ShapeMapGroup_PrimArray, //!< primitive array }; //! Bind name attribute. @@ -416,7 +418,7 @@ protected: NCollection_DataMap myMaterialsPbr; NCollection_DataMap myMaterialsCommon; NCollection_DataMap myMaterials; - NCollection_DataMap myShapeMap[2]; + NCollection_DataMap myShapeMap[3]; NCollection_DataMap myProbedFiles; NCollection_DataMap myDecodedBuffers; diff --git a/src/RWMesh/RWMesh_CafReader.cxx b/src/RWMesh/RWMesh_CafReader.cxx index f998d3b8b9..64c9b6e9d0 100644 --- a/src/RWMesh/RWMesh_CafReader.cxx +++ b/src/RWMesh/RWMesh_CafReader.cxx @@ -402,6 +402,12 @@ Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (CafDocumentTools& theTools, hasProductName = true; setShapeName (aNewRefLabel, aShapeType, aShapeAttribs.Name, theLabel, theParentName); } + else if (aShapeAttribs.Name.IsEmpty() + && !aRefShapeAttribs.Name.IsEmpty()) + { + // copy name from Product + setShapeName (aNewLabel, aShapeType, aRefShapeAttribs.Name, theLabel, theParentName); + } } else { diff --git a/src/RWMesh/RWMesh_FaceIterator.cxx b/src/RWMesh/RWMesh_FaceIterator.cxx index a19ee16920..a7f6d58ae5 100644 --- a/src/RWMesh/RWMesh_FaceIterator.cxx +++ b/src/RWMesh/RWMesh_FaceIterator.cxx @@ -42,12 +42,13 @@ RWMesh_FaceIterator::RWMesh_FaceIterator (const TDF_Label& theLabel, return; } - aShape.Location (theLocation); + aShape.Location (theLocation, false); myFaceIter.Init (aShape, TopAbs_FACE); if (theToMapColors) { dispatchStyles (theLabel, theLocation, theStyle); + myStyles.Bind (aShape, theStyle); } Next(); diff --git a/tests/de_mesh/gltf_write/as1 b/tests/de_mesh/gltf_write/as1 index 3efb8b1ea4..eda810ba4a 100644 --- a/tests/de_mesh/gltf_write/as1 +++ b/tests/de_mesh/gltf_write/as1 @@ -17,8 +17,8 @@ WriteGltf D0 "$aTmpGltf2" -mergeFaces ReadGltf D1 "$aTmpGltf1" XGetOneShape s1 D1 -checknbshapes s1 -face 160 -compound 28 +checknbshapes s1 -face 53 -compound 28 ReadGltf D "$aTmpGltf2" XGetOneShape s2 D -checknbshapes s2 -face 18 -compound 10 +checknbshapes s2 -face 5 -compound 10 diff --git a/tests/de_mesh/gltf_write/spheres b/tests/de_mesh/gltf_write/spheres new file mode 100644 index 0000000000..ec01a88d56 --- /dev/null +++ b/tests/de_mesh/gltf_write/spheres @@ -0,0 +1,56 @@ +puts "========" +puts "0032107: Data Exchange, RWGltf_CafReader - reading glTF document back loses sharing" +puts "========" + +vclear +vclose ALL +Close * +source $env(CSF_OCCTSamplesPath)/tcl/vis_pbr_spheres.tcl +vdump "${imagedir}/${casename}_0.png" + +set aTmpGltf1 "${imagedir}/${casename}_tmp1.glb" +set aTmpGltf1m "${imagedir}/${casename}_tmp1m.glb" +set aTmpGltf2 "${imagedir}/${casename}_tmp2.glb" +set aTmpGltf2m "${imagedir}/${casename}_tmp2m.glb" +lappend occ_tmp_files $aTmpGltf1 +lappend occ_tmp_files $aTmpGltf1m +lappend occ_tmp_files $aTmpGltf2 +lappend occ_tmp_files $aTmpGltf2m + +WriteGltf D "$aTmpGltf1" +puts [file size "$aTmpGltf1"] +WriteGltf D "$aTmpGltf1m" -mergeFaces +puts [file size "$aTmpGltf1m"] + +ReadGltf D1 "$aTmpGltf1" +XGetOneShape s1 D1 +checknbshapes s1 -face 26 -compound 22 +vclear +XDisplay D1 -dispMode 1 +vdump "${imagedir}/${casename}_1.png" + +ReadGltf D1m "$aTmpGltf1m" +XGetOneShape s1m D1m +checknbshapes s1m -face 5 -compound 18 +vclear +XDisplay D1m -dispMode 1 +vdump "${imagedir}/${casename}_1m.png" + +WriteGltf D1 "$aTmpGltf2" +puts [file size "$aTmpGltf2"] +WriteGltf D1m "$aTmpGltf2m" -mergeFaces +puts [file size "$aTmpGltf2m"] + +ReadGltf D2 "$aTmpGltf2" +XGetOneShape s2 D2 +checknbshapes s2 -face 26 -compound 22 +vclear +XDisplay D2 -dispMode 1 +vdump "${imagedir}/${casename}_2.png" + +ReadGltf D2m "$aTmpGltf2m" +XGetOneShape s2m D2m +checknbshapes s2m -face 5 -compound 18 +vclear +XDisplay D2m -dispMode 1 +vdump "${imagedir}/${casename}_2m.png"