Salome HOME
Fix for the problem that selection of sub-elements of compsolids for concealment...
authormpv <mpv@opencascade.com>
Thu, 27 Aug 2015 09:10:26 +0000 (12:10 +0300)
committermpv <mpv@opencascade.com>
Thu, 27 Aug 2015 09:10:26 +0000 (12:10 +0300)
src/Model/Model_Update.cpp
src/Model/Model_Update.h

index d0b06ce0bdc369429939c68e4d80b93e0fc777a3..6c0dfc950520f7ca2d7bc0531f196e27a75ddb84 100644 (file)
@@ -168,6 +168,47 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
   }
 }
 
+bool Model_Update::iterateUpdate(std::shared_ptr<ModelAPI_CompositeFeature> theFeature)
+{
+  myProcessIterator.push_back(IterationItem());
+  IterationItem& aCurrent = *myProcessIterator.rbegin();
+  if (theFeature.get()) {
+    aCurrent.myMain = theFeature;
+    // two cycles: parameters must be processed first
+    for(int a = 0; a < theFeature->numberOfSubs(); a++) {
+      FeaturePtr aSub = theFeature->subFeature(a);
+      aCurrent.mySub = aSub;
+      if (aSub->getKind() == "Parameter")
+        updateFeature(aSub);
+    }
+    // number of subs can be changed in execution: like fillet
+    for(int a = 0; a < theFeature->numberOfSubs(); a++) {
+      FeaturePtr aSub = theFeature->subFeature(a);
+      aCurrent.mySub = aSub;
+      if (aSub->getKind() != "Parameter")
+       updateFeature(aSub);
+    }
+  } else {
+    DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+    Model_Objects* anObjs = std::dynamic_pointer_cast<Model_Document>(aRootDoc)->objects();
+    if (!anObjs)
+      return false;
+    aCurrent.mySub = anObjs->firstFeature();
+    for (; aCurrent.mySub.get(); aCurrent.mySub = anObjs->nextFeature(aCurrent.mySub)) {
+      if (aCurrent.mySub->getKind() == "Parameter")
+        updateFeature(aCurrent.mySub);
+    }
+    aCurrent.mySub = anObjs->firstFeature();
+    for (; aCurrent.mySub.get(); aCurrent.mySub = anObjs->nextFeature(aCurrent.mySub)) {
+      if (aCurrent.mySub->getKind() != "Parameter")
+        updateFeature(aCurrent.mySub);
+    }
+  }
+  // processing is finished, so, remove the iterated
+  myProcessIterator.pop_back();
+  return true; // iteration is finished correctly
+}
+
 void Model_Update::processOperation(const bool theTotalUpdate, const bool theFinish)
 {
   if (theFinish) {
@@ -202,23 +243,9 @@ void Model_Update::processOperation(const bool theTotalUpdate, const bool theFin
       isAutomaticChanged = true;
       myIsAutomatic = true;
     }
-
-    // iterate all features in the root document to update each
-    DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
-    Model_Objects* anObjs = std::dynamic_pointer_cast<Model_Document>(aRootDoc)->objects();
-    if (!anObjs) return;
-    // two cycles: parameters are first to process
-    FeaturePtr aFeatureIter = anObjs->firstFeature();
+    // init iteration from the root document
     myProcessed.clear(); // to avoid processing twice
-    for (; aFeatureIter.get(); aFeatureIter = anObjs->nextFeature(aFeatureIter)) {
-      if (aFeatureIter->getKind() == "Parameter")
-        updateFeature(aFeatureIter);
-    }
-    aFeatureIter = anObjs->firstFeature();
-    for (; aFeatureIter.get(); aFeatureIter = anObjs->nextFeature(aFeatureIter)) {
-      if (aFeatureIter->getKind() != "Parameter")
-        updateFeature(aFeatureIter);
-    }
+    iterateUpdate(CompositeFeaturePtr());
 
     if (isAutomaticChanged) myIsAutomatic = false;
     myProcessed.clear(); // to avoid keeping features in memory
@@ -264,18 +291,8 @@ void Model_Update::updateFeature(FeaturePtr theFeature)
 
   // composite feature must be executed after sub-features execution
   if (aCompos) {
-    // two cycles: parameters must be processed first
-    for(int a = 0; a < aCompos->numberOfSubs(); a++) {
-      FeaturePtr aSub = aCompos->subFeature(a);
-      if (aSub->getKind() == "Parameter")
-        updateFeature(aSub);
-    }
-    // number of subs can be changed in execution: like fillet
-    for(int a = 0; a < aCompos->numberOfSubs(); a++) {
-      FeaturePtr aSub = aCompos->subFeature(a);
-      if (aSub->getKind() != "Parameter")
-       updateFeature(aSub);
-    }
+    if (!iterateUpdate(aCompos))
+      return; // iteration was interrupted, so, interrupt the update of this feature (it will be done later)
     // reupdate arguments of composite feature: it may be changed during subs execution
     if (theFeature->data()->execState() != ModelAPI_StateMustBeUpdated)
       updateArguments(theFeature);
index aed04adae6191dc2b79b3b31085348e53baad9e8..845118c88c92235a939be9e5d01055d627d3e8cb 100644 (file)
@@ -16,6 +16,7 @@
 
 class ModelAPI_Object;
 class ModelAPI_Feature;
+class ModelAPI_CompositeFeature;
 
 /**\class Model_Update
  * \ingroup DataModel
@@ -38,6 +39,18 @@ class Model_Update : public Events_Listener
   /// Set of already processed features in the "processOperation" method
   std::set<std::shared_ptr<ModelAPI_Feature> > myProcessed;
 
+  /// internal structure that contains the updating iteration information:
+  /// which object and subobject is iterated, t ocontinue iteration
+  struct IterationItem {
+    /// the main object, subs of it are iterated
+    std::shared_ptr<ModelAPI_CompositeFeature> myMain;
+    /// the currently iterated sub-object
+    std::shared_ptr<ModelAPI_Feature> mySub;
+  };
+  /// List of iterated features: composite feature to the currently iterated sub.
+  /// The first element in the list has no "main": the root document is not feature.
+  std::list<IterationItem> myProcessIterator;
+
  public:
   /// Is called only once, on startup of the application
   Model_Update();
@@ -65,6 +78,12 @@ protected:
   /// Performs the feature execution
   /// \returns the status of execution
   void executeFeature(std::shared_ptr<ModelAPI_Feature> theFeature);
+
+  /// Iterates and updates features from theFeature by managing myProcessIterator.
+  /// Returns only after the iteration is finished.
+  /// \param theFeature is null for iteration of root document (which is not composite)
+  /// \returns false if this feature should not be updated: iteration was moved much upper
+  bool iterateUpdate(std::shared_ptr<ModelAPI_CompositeFeature> theFeature);
 };
 
 #endif