diff --git a/src/QABugs/QABugs_20.cxx b/src/QABugs/QABugs_20.cxx index 7a5e33bee5..80f90678cb 100644 --- a/src/QABugs/QABugs_20.cxx +++ b/src/QABugs/QABugs_20.cxx @@ -2802,6 +2802,38 @@ static Standard_Integer OCC29430(Draw_Interpretor& theDI, return 0; } +#include + +//======================================================================= +//function : OCC29531 +//purpose : +//======================================================================= +static Standard_Integer OCC29531(Draw_Interpretor&, Standard_Integer, const char** theArgV) +{ + Handle(TDocStd_Application) anApp = DDocStd::GetApplication(); + Handle(TDocStd_Document) aDoc; + anApp->NewDocument("BinOcaf", aDoc); + aDoc->SetUndoLimit(1); + + STEPCAFControl_Reader Reader; + Reader.ReadFile(theArgV[1]); + Reader.Transfer(aDoc); + TDF_Label aShL, aDL; + TDF_Tool::Label(aDoc->GetData(), "0:1:1:2:672", aShL); + TDF_Tool::Label(aDoc->GetData(), "0:1:4:10", aDL); + + aDoc->OpenCommand(); + + Handle(XCAFDoc_DimTolTool) aDimTolTool = XCAFDoc_DocumentTool::DimTolTool(aDoc->Main()); + aDimTolTool->SetDimension(aShL, aDL); + + aDoc->CommitCommand(); + + aDoc->Undo(); + aDoc->Redo(); + return 0; +} + void QABugs::Commands_20(Draw_Interpretor& theCommands) { const char *group = "QABugs"; @@ -2835,6 +2867,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) { theCommands.Add("OCC29430", "OCC29430 " " ", __FILE__, OCC29430, group); + theCommands.Add("OCC29531", "OCC29531 ", __FILE__, OCC29531, group); return; } diff --git a/src/TDF/TDF_Data.cxx b/src/TDF/TDF_Data.cxx index 96cdd85811..a6d8df8ac1 100644 --- a/src/TDF/TDF_Data.cxx +++ b/src/TDF/TDF_Data.cxx @@ -375,42 +375,25 @@ Standard_Boolean TDF_Data::IsApplicable //======================================================================= void TDF_Data::FixOrder(const Handle(TDF_Delta)& theDelta) { + // make all OnRemoval (which will cause addition of the attribute) are in the end + // to do not put two attributes with the same GUID at one label during undo/redo + TDF_AttributeDeltaList anOrderedList; + const TDF_AttributeDeltaList& attList = theDelta->AttributeDeltas(); - Handle(TDF_AttributeDelta) attDelta; - Handle(TDF_Attribute) att; - Standard_Integer i, indx1(0), indx2(0); - Standard_GUID aGuid; - TDF_ListIteratorOfAttributeDeltaList itr(attList) ; - for (i=1; itr.More(); itr.Next(), i++) { - attDelta = itr.Value(); - if(indx1) { - att = attDelta->Attribute(); - if((att->ID() == aGuid) && (attDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition)))) { - indx2 = i; - break; - } - } else - if (attDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) { - att = attDelta->Attribute(); - aGuid = att->ID(); - indx1 = i; - } + TDF_ListIteratorOfAttributeDeltaList anIt(attList); + for (; anIt.More(); anIt.Next()) { // append not-removal + Handle(TDF_AttributeDelta) attDelta = anIt.Value(); + if (!attDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) { + anOrderedList.Append(attDelta); + } } - if(indx1 && indx2) { - TDF_Array1OfAttributeIDelta anArray(1, attList.Extent()); - itr.Initialize(attList); - for (i=1; itr.More(); itr.Next(), i++) - anArray.SetValue(i, itr.Value()); - Handle(TDF_AttributeDelta) attDelta1, attDelta2; - attDelta1 = anArray.Value(indx1); - attDelta2 = anArray.Value(indx2); - anArray.SetValue(indx1, attDelta2); - anArray.SetValue(indx2, attDelta1); - TDF_AttributeDeltaList attList2; - for(i=1; i<= anArray.Upper(); i++) - attList2.Append(anArray.Value(i)); - theDelta->ReplaceDeltaList(attList2); + for (anIt.Initialize(attList); anIt.More(); anIt.Next()) { // append removal + Handle(TDF_AttributeDelta) attDelta = anIt.Value(); + if (attDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) { + anOrderedList.Append(attDelta); + } } + theDelta->ReplaceDeltaList(anOrderedList); } //======================================================================= //function : Undo diff --git a/src/TDF/TDF_Data.hxx b/src/TDF/TDF_Data.hxx index 5856a32f38..c9c3c2813f 100644 --- a/src/TDF/TDF_Data.hxx +++ b/src/TDF/TDF_Data.hxx @@ -147,7 +147,8 @@ protected: private: - //! Fixes order of Attributes' Deltas + //! Fixes order of Attributes' Deltas to perform undo/redo without exceptions: + //! puts OnRemoval deltas to the end of the list. void FixOrder(const Handle(TDF_Delta)& theDelta); //! Increments the transaction number and returns it. diff --git a/tests/bugs/caf/bug29531 b/tests/bugs/caf/bug29531 new file mode 100644 index 0000000000..688f39c64c --- /dev/null +++ b/tests/bugs/caf/bug29531 @@ -0,0 +1,7 @@ +puts "===========" +puts "OCC29531" +puts "===========" + +pload QAcommands + +OCC29531 [locate_data_file bug29531_nist_ctc_02_asme1_ap242-2.stp]