]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix for hang up (and crash after) on remove of all features in the complicated model...
authormpv <mpv@opencascade.com>
Thu, 17 Sep 2015 13:09:05 +0000 (16:09 +0300)
committermpv <mpv@opencascade.com>
Thu, 17 Sep 2015 13:09:05 +0000 (16:09 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/ModelAPI/ModelAPI_Document.h
src/XGUI/XGUI_Tools.cpp
src/XGUI/XGUI_Tools.h
src/XGUI/XGUI_Workshop.cpp

index a657f75ef8680bbfdd118eaa418ae15fb3e71cad..e2a0026405bcd5e1b90c710117e1a24d43c8575a 100644 (file)
@@ -746,7 +746,7 @@ std::shared_ptr<ModelAPI_Feature> Model_Document::currentFeature(const bool theV
 }
 
 void Model_Document::setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent,
-  const bool theVisible)
+  const bool theVisible, const bool theFlushUpdates)
 {
   // blocks the flush signals to avoid each objects visualization in the viewer
   // they should not be shown once after all modifications are performed
@@ -841,9 +841,11 @@ void Model_Document::setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurr
   // unblock  the flush signals and up them after this
   aLoop->activateFlushes(isActive);
 
-  aLoop->flush(aCreateEvent);
-  aLoop->flush(aRedispEvent);
-  aLoop->flush(aDeleteEvent);
+  if (theFlushUpdates) {
+    aLoop->flush(aCreateEvent);
+    aLoop->flush(aRedispEvent);
+    aLoop->flush(aDeleteEvent);
+  }
 }
 
 void Model_Document::setCurrentFeatureUp()
@@ -853,7 +855,8 @@ void Model_Document::setCurrentFeatureUp()
   FeaturePtr aCurrent = currentFeature(false);
   if (aCurrent.get()) { // if not, do nothing because null is the upper
     FeaturePtr aPrev = myObjs->nextFeature(aCurrent, true);
-    setCurrentFeature(aPrev, false);
+    // do not flush: it is called only on remove, it will be flushed in the end of transaction
+    setCurrentFeature(aPrev, false, false);
   }
 }
 
index ad28e74d493d842dc7601f8e49f7fd625acdaa6e..a3f28a20f0262a1de52b9f82549c5fcaf260b65a 100644 (file)
@@ -135,7 +135,7 @@ class Model_Document : public ModelAPI_Document
   //! \param theCurrent the selected feature as current: blow it everythin become disabled
   //! \param theVisible use visible features only: flag is true for Object Browser functionality
   MODEL_EXPORT virtual void setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent,
-    const bool theVisible);
+    const bool theVisible, const bool theFlushUpdates = true);
 
   //! Makes the current feature one feature upper
   MODEL_EXPORT virtual void setCurrentFeatureUp();
index 03a740af211265caa0a25720a16073009b5018a0..0f4ccc3302bdf510196bdb23b93bf1be412fe442 100644 (file)
@@ -103,8 +103,9 @@ public:
   //! will be appended after this one.
   //! \param theCurrent the selected feature as current: blow it everythin become disabled
   //! \param theVisible use visible features only: flag is true for Object Browser functionality
+  //! \param theFlushUpdates if it is true (default) it flashes creation/redisplay/delete messages
   virtual void setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent,
-    const bool theVisible) = 0;
+    const bool theVisible, const bool theFlushUpdates = true) = 0;
   //! Makes the current feature one feature upper
   virtual void setCurrentFeatureUp() = 0;
 
index 45398077f6f74fd50603f75f5d93ebc09db61055..fb0a8f2567dfa992722205900b0204dd9629a6a4 100644 (file)
@@ -174,11 +174,16 @@ bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
 
 //**************************************************************
 void refsToFeatureInAllDocuments(const ObjectPtr& theSourceObject, const ObjectPtr& theObject,
-                                 std::set<FeaturePtr>& theDirectRefFeatures, std::set<FeaturePtr>& theIndirectRefFeatures)
+                                 std::set<FeaturePtr>& theDirectRefFeatures, 
+                                 std::set<FeaturePtr>& theIndirectRefFeatures,
+                                 std::set<FeaturePtr>& theAlreadyProcessed)
 {
   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
   if (!aFeature.get())
     return;
+  if (theAlreadyProcessed.find(aFeature) != theAlreadyProcessed.end())
+    return;
+  theAlreadyProcessed.insert(aFeature);
 
   // 1. find references in the current document
   std::set<FeaturePtr> aRefFeatures;
@@ -249,12 +254,13 @@ void refsToFeatureInAllDocuments(const ObjectPtr& theSourceObject, const ObjectP
 
   // Run recursion. It is possible recursive dependency, like the following: plane, extrusion uses plane,
   // axis is built on extrusion. Delete of a plane should check the dependency from the axis also.
-  std::set<FeaturePtr> aRecursiveRefFeatures;
   std::set<FeaturePtr>::const_iterator aFeatureIt = theDirectRefFeatures.begin();
   for (; aFeatureIt != theDirectRefFeatures.end(); ++aFeatureIt) {
-    refsToFeatureInAllDocuments(theSourceObject, *aFeatureIt, aRecursiveRefFeatures, aRecursiveRefFeatures);
-  } 
-  theIndirectRefFeatures.insert(aRecursiveRefFeatures.begin(), aRecursiveRefFeatures.end());
+    std::set<FeaturePtr> aRecursiveRefFeatures;
+    refsToFeatureInAllDocuments(theSourceObject, *aFeatureIt, 
+      aRecursiveRefFeatures, aRecursiveRefFeatures, theAlreadyProcessed);
+    theIndirectRefFeatures.insert(aRecursiveRefFeatures.begin(), aRecursiveRefFeatures.end());
+  }
 }
 
 }
index b158a62c1250e2d5af992e8d96e6eb5b24ecb52e..178b8b2a4c9bc4034a319a9cb818c1219b67180a 100644 (file)
@@ -115,12 +115,14 @@ bool XGUI_EXPORT isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr&
  which has the object as a sub object.
  \param theSourceObject an object, which references are searched
  \param theObject an intermediate recursive object, should be set in the source object
+ \param theAlreadyProcessed set of processed elements, used for optimization (do not reanalyse processed)
  \return a boolean value
  */
 void XGUI_EXPORT refsToFeatureInAllDocuments(const ObjectPtr& theSourceObject,
                                              const ObjectPtr& theObject,
                                              std::set<FeaturePtr>& theDirectRefFeatures,
-                                             std::set<FeaturePtr>& theIndirectRefFeatures);
+                                             std::set<FeaturePtr>& theIndirectRefFeatures,
+                                             std::set<FeaturePtr>& theAlreadyProcessed);
 };
 
 #endif
index f6ee0f99d426357651b524e8db15bd3d91fcb542..9715028144d51cf576a6f99b4893d87a5a1abd8b 100644 (file)
@@ -1211,7 +1211,9 @@ bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList,
   // 1. find all referenced features
   std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
   foreach (ObjectPtr aDeletedObj, theList) {
-    XGUI_Tools::refsToFeatureInAllDocuments(aDeletedObj, aDeletedObj, aDirectRefFeatures, aIndirectRefFeatures);
+    std::set<FeaturePtr> alreadyProcessed;
+    XGUI_Tools::refsToFeatureInAllDocuments(
+      aDeletedObj, aDeletedObj, aDirectRefFeatures, aIndirectRefFeatures, alreadyProcessed);
     std::set<FeaturePtr> aDifference;
     std::set_difference(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end(), 
                         aDirectRefFeatures.begin(), aDirectRefFeatures.end(),