From af4c3a36f92e8ba3b43c4c9919ea430e80ae11fc Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 7 Jul 2015 16:01:46 +0300 Subject: [PATCH] Issue #693 - Crash when undo delete rotated segments 1. updateResults should be done after back references synchronization. Sketch multi-rotation uses sketch in the execute(). If the presentation is visualized before the back references are calculated, it leads to crash. 2. synchronize back references should be done after updateResults. List of back references should be set for the updated results. Case: bug scenario, delete, crash. --- src/Model/Model_Objects.cpp | 38 +++++++++++++++++++++---------------- src/XGUI/XGUI_Workshop.cpp | 12 +++++++++++- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index c815aa12d..1acc94806 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -560,22 +560,6 @@ void Model_Objects::synchronizeFeatures( } } } - // update results of the features (after features created because they may be connected, like sketch and sub elements) - std::list aComposites; // composites must be updated after their subs (issue 360) - TDF_ChildIDIterator aLabIter2(featuresLabel(), TDataStd_Comment::GetID()); - for (; aLabIter2.More(); aLabIter2.Next()) { - TDF_Label aFeatureLabel = aLabIter2.Value()->Label(); - if (myFeatures.IsBound(aFeatureLabel)) { // a new feature is inserted - FeaturePtr aFeature = myFeatures.Find(aFeatureLabel); - if (std::dynamic_pointer_cast(aFeature).get()) - aComposites.push_back(aFeature); - updateResults(aFeature); - } - } - std::list::iterator aComposite = aComposites.begin(); - for(; aComposite != aComposites.end(); aComposite++) { - updateResults(*aComposite); - } // check all features are checked: if not => it was removed NCollection_DataMap::Iterator aFIter(myFeatures); @@ -600,6 +584,28 @@ void Model_Objects::synchronizeFeatures( aFIter.Next(); } + if (theUpdateReferences) { + synchronizeBackRefs(); + } + // update results of the features (after features created because they may be connected, like sketch and sub elements) + // After synchronisation of back references because sketch must be set in sub-elements before "execute" by updateResults + std::list aComposites; // composites must be updated after their subs (issue 360) + TDF_ChildIDIterator aLabIter2(featuresLabel(), TDataStd_Comment::GetID()); + for (; aLabIter2.More(); aLabIter2.Next()) { + TDF_Label aFeatureLabel = aLabIter2.Value()->Label(); + if (myFeatures.IsBound(aFeatureLabel)) { // a new feature is inserted + FeaturePtr aFeature = myFeatures.Find(aFeatureLabel); + if (std::dynamic_pointer_cast(aFeature).get()) + aComposites.push_back(aFeature); + updateResults(aFeature); + } + } + std::list::iterator aComposite = aComposites.begin(); + for(; aComposite != aComposites.end(); aComposite++) { + updateResults(*aComposite); + } + + // the synchronize should be done after updateResults in order to correct back references of updated results if (theUpdateReferences) { synchronizeBackRefs(); } diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index a824f4298..533443827 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1143,6 +1143,16 @@ bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList, QWidget* theParent, const bool theAskAboutDeleteReferences) { +#ifdef DEBUG_DELETE + QStringList aDInfo; + QObjectPtrList::const_iterator aDIt = theList.begin(), aDLast = theList.end(); + for (; aDIt != aDLast; ++aDIt) { + aDInfo.append(ModuleBase_Tools::objectInfo((*aDIt))); + } + QString anInfoStr = aDInfo.join(", "); + qDebug(QString("deleteFeatures: %1, %2").arg(theList.size()).arg(anInfoStr).toStdString().c_str()); +#endif + // 1. find all referenced features std::set aRefFeatures; foreach (ObjectPtr aDeletedObj, theList) { @@ -1208,12 +1218,12 @@ These features will be deleted also. Would you like to continue?")).arg(aNames), DocumentPtr aDoc = aObj->document(); if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) { - aDoc->removeFeature(aFeature); #ifdef DEBUG_DELETE QString anInfoStr = ModuleBase_Tools::objectInfo(aFeature); anInfo.append(anInfoStr); qDebug(QString("remove feature :%1").arg(anInfoStr).toStdString().c_str()); #endif + aDoc->removeFeature(aFeature); } } } -- 2.39.2