diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafReader.cxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafReader.cxx index cd5a5deaa52..5fca8b2d40e 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafReader.cxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafReader.cxx @@ -449,20 +449,18 @@ void RWGltf_CafReader::fillDocument() Message::SendWarning("Warning: Length unit of document not equal to the system length unit"); } - const bool wasAutoNaming = XCAFDoc_ShapeTool::AutoNaming(); - XCAFDoc_ShapeTool::SetAutoNaming(false); const TCollection_AsciiString aRootName; // = generateRootName (theFile); CafDocumentTools aTools; aTools.ShapeTool = XCAFDoc_DocumentTool::ShapeTool(myXdeDoc->Main()); aTools.ColorTool = XCAFDoc_DocumentTool::ColorTool(myXdeDoc->Main()); aTools.VisMaterialTool = XCAFDoc_DocumentTool::VisMaterialTool(myXdeDoc->Main()); + XCAFDoc_ShapeTool::OwnAutoNamingScope anAutoNamingScope(aTools.ShapeTool, false); for (NCollection_Sequence::Iterator aRootIter(myRootShapes); aRootIter.More(); aRootIter.Next()) { addShapeIntoDoc(aTools, aRootIter.Value(), TDF_Label(), aRootName); } XCAFDoc_DocumentTool::ShapeTool(myXdeDoc->Main())->UpdateAssemblies(); - XCAFDoc_ShapeTool::SetAutoNaming(wasAutoNaming); } //================================================================================================= diff --git a/src/DataExchange/TKRWMesh/RWMesh/RWMesh_CafReader.cxx b/src/DataExchange/TKRWMesh/RWMesh/RWMesh_CafReader.cxx index e2fe99b4721..06f4d3f9a69 100644 --- a/src/DataExchange/TKRWMesh/RWMesh/RWMesh_CafReader.cxx +++ b/src/DataExchange/TKRWMesh/RWMesh/RWMesh_CafReader.cxx @@ -178,20 +178,18 @@ void RWMesh_CafReader::fillDocument() Message::SendWarning("Warning: Length unit of document not equal to the system length unit"); } - const bool wasAutoNaming = XCAFDoc_ShapeTool::AutoNaming(); - XCAFDoc_ShapeTool::SetAutoNaming(false); const TCollection_AsciiString aRootName; // = generateRootName (theFile); CafDocumentTools aTools; aTools.ShapeTool = XCAFDoc_DocumentTool::ShapeTool(myXdeDoc->Main()); aTools.ColorTool = XCAFDoc_DocumentTool::ColorTool(myXdeDoc->Main()); aTools.VisMaterialTool = XCAFDoc_DocumentTool::VisMaterialTool(myXdeDoc->Main()); + XCAFDoc_ShapeTool::OwnAutoNamingScope anAutoNamingScope(aTools.ShapeTool, false); for (NCollection_Sequence::Iterator aRootIter(myRootShapes); aRootIter.More(); aRootIter.Next()) { addShapeIntoDoc(aTools, aRootIter.Value(), TDF_Label(), aRootName); } XCAFDoc_DocumentTool::ShapeTool(myXdeDoc->Main())->UpdateAssemblies(); - XCAFDoc_ShapeTool::SetAutoNaming(wasAutoNaming); } //================================================================================================= diff --git a/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_Editor.cxx b/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_Editor.cxx index 0b06e0b2437..9acce946a1b 100644 --- a/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_Editor.cxx +++ b/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_Editor.cxx @@ -66,9 +66,8 @@ bool XCAFDoc_Editor::Expand(const TDF_Label& theDoc, { return false; } - occ::handle aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc); - bool isAutoNaming = aShapeTool->AutoNaming(); - aShapeTool->SetAutoNaming(false); + occ::handle aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc); + XCAFDoc_ShapeTool::OwnAutoNamingScope anAutoNamingScope(aShapeTool, false); TDF_Label aCompoundPartL = theShape; if (aShapeTool->IsReference(theShape)) @@ -139,10 +138,8 @@ bool XCAFDoc_Editor::Expand(const TDF_Label& theDoc, } } } - aShapeTool->SetAutoNaming(isAutoNaming); return true; } - aShapeTool->SetAutoNaming(isAutoNaming); return false; } diff --git a/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_ShapeTool.cxx b/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_ShapeTool.cxx index 65d8b94c1f2..c613ed29bd3 100644 --- a/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_ShapeTool.cxx +++ b/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_ShapeTool.cxx @@ -15,6 +15,8 @@ #include +#include + #include #include #include @@ -50,7 +52,7 @@ IMPLEMENT_DERIVED_ATTRIBUTE_WITH_TYPE(XCAFDoc_ShapeTool, TDataStd_GenericEmpty, "xcaf", "ShapeTool") -static bool theAutoNaming = true; +static std::atomic theAutoNaming{true}; // attribute methods ////////////////////////////////////////////////// @@ -81,6 +83,7 @@ occ::handle XCAFDoc_ShapeTool::Set(const TDF_Label& L) XCAFDoc_ShapeTool::XCAFDoc_ShapeTool() { hasSimpleShapes = false; + myOwnAutonaming = -1; } //================================================================================================= @@ -453,7 +456,7 @@ void XCAFDoc_ShapeTool::MakeReference(const TDF_Label& L, refNode->Remove(); // abv: fix against bug in TreeNode::Append() mainNode->Append(refNode); - if (theAutoNaming) + if (OwnAutoNaming()) { SetLabelNameByLink(L); } @@ -529,7 +532,7 @@ TDF_Label XCAFDoc_ShapeTool::addShape(const TopoDS_Shape& S, const bool makeAsse // } A->SetShape(S); - if (theAutoNaming) + if (OwnAutoNaming()) { SetLabelNameByShape(ShapeLabel); } @@ -540,7 +543,7 @@ TDF_Label XCAFDoc_ShapeTool::addShape(const TopoDS_Shape& S, const bool makeAsse // mark assembly by assigning UAttribute occ::handle Uattr; Uattr = TDataStd_UAttribute::Set(ShapeLabel, XCAFDoc::AssemblyGUID()); - if (theAutoNaming) + if (OwnAutoNaming()) { TDataStd_Name::Set(ShapeLabel, TCollection_ExtendedString("ASSEMBLY")); } @@ -702,6 +705,31 @@ bool XCAFDoc_ShapeTool::AutoNaming() //================================================================================================= +// Saves/restores the instance's own override, not a shared flag -- no locking +// needed, and nested scopes on the same instance compose correctly since each +// one restores exactly the state it observed on entry. +XCAFDoc_ShapeTool::OwnAutoNamingScope::OwnAutoNamingScope( + const occ::handle& theTool, + const bool theTemporaryValue) + : myTool(theTool), + myWasOwnAutoNaming(theTool.IsNull() ? -1 : theTool->myOwnAutonaming) +{ + if (!myTool.IsNull()) + { + myTool->myOwnAutonaming = theTemporaryValue ? 1 : 0; + } +} + +XCAFDoc_ShapeTool::OwnAutoNamingScope::~OwnAutoNamingScope() +{ + if (!myTool.IsNull()) + { + myTool->myOwnAutonaming = myWasOwnAutoNaming; + } +} + +//================================================================================================= + void XCAFDoc_ShapeTool::ComputeShapes(const TDF_Label& L) { TDF_ChildIterator it(L); @@ -1542,7 +1570,7 @@ bool XCAFDoc_ShapeTool::SetSHUO(const NCollection_Sequence& labels, TDF_TagSource aTag; TDF_Label UpperSubL = TDF_TagSource::NewChild(labels(1)); - if (theAutoNaming) + if (OwnAutoNaming()) { TCollection_ExtendedString Entry("SHUO"); TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString(Entry)); @@ -1555,7 +1583,7 @@ bool XCAFDoc_ShapeTool::SetSHUO(const NCollection_Sequence& labels, for (i = 2; i <= labels.Length(); i++) { TDF_Label NextSubL = TDF_TagSource::NewChild(labels(i)); - if (theAutoNaming) + if (OwnAutoNaming()) { TCollection_ExtendedString EntrySub("SHUO-"); EntrySub += i; diff --git a/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_ShapeTool.hxx b/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_ShapeTool.hxx index 84c43dd8428..b88573bb9e3 100644 --- a/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_ShapeTool.hxx +++ b/src/DataExchange/TKXCAF/XCAFDoc/XCAFDoc_ShapeTool.hxx @@ -255,6 +255,39 @@ public: //! description. Standard_EXPORT static bool AutoNaming(); + //! Returns the auto-naming mode for this instance: its own local override if + //! set, otherwise the process-wide default. See SetOwnAutoNaming(). + bool OwnAutoNaming() const + { + return myOwnAutonaming == -1 ? XCAFDoc_ShapeTool::AutoNaming() : myOwnAutonaming == 1; + } + + //! Locally overrides auto-naming for this instance only, leaving the + //! process-wide default and other documents untouched. Prefer + //! OwnAutoNamingScope so a local override can't leak past an exception. + void SetOwnAutoNaming(const bool theOwnFlag) { myOwnAutonaming = theOwnFlag ? 1 : 0; } + + //! Resets this instance to inherit the process-wide default again. + void UnsetOwnAutoNaming() { myOwnAutonaming = -1; } + + //! RAII scope: locally overrides auto-naming on one ShapeTool instance, + //! restoring its previous own-override state on destruction. Needs no + //! locking, and nests correctly on the same instance. + class OwnAutoNamingScope + { + public: + Standard_EXPORT OwnAutoNamingScope(const occ::handle& theTool, + const bool theTemporaryValue); + Standard_EXPORT ~OwnAutoNamingScope(); + + OwnAutoNamingScope(const OwnAutoNamingScope&) = delete; + OwnAutoNamingScope& operator=(const OwnAutoNamingScope&) = delete; + + private: + occ::handle myTool; + int myWasOwnAutoNaming; + }; + //! recursive Standard_EXPORT void ComputeShapes(const TDF_Label& L); @@ -500,9 +533,9 @@ private: //! Makes a shape on label L to be a reference to shape refL //! with location loc - Standard_EXPORT static void MakeReference(const TDF_Label& L, - const TDF_Label& refL, - const TopLoc_Location& loc); + Standard_EXPORT void MakeReference(const TDF_Label& L, + const TDF_Label& refL, + const TopLoc_Location& loc); //! Auxiliary method for Expand //! Add declared under expanded theMainShapeL subshapes to new part label thePart @@ -517,6 +550,8 @@ private: NCollection_DataMap mySubShapes; NCollection_DataMap mySimpleShapes; bool hasSimpleShapes; + //! -1: inherit the process-wide default; 0/1: local override. + int myOwnAutonaming; }; #endif // _XCAFDoc_ShapeTool_HeaderFile