]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Finalization of concealment management with stable and not stable feature
authormpv <mpv@opencascade.com>
Fri, 9 Oct 2015 14:36:38 +0000 (17:36 +0300)
committermpv <mpv@opencascade.com>
Fri, 9 Oct 2015 14:36:38 +0000 (17:36 +0300)
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/Model/Model_Objects.cpp
src/Model/Model_Objects.h
src/Model/Model_Update.cpp
src/ModelAPI/ModelAPI_Result.cpp

index e43e34e2509d53704740588712c8aa0482af053a..75b38aeb01e0f85057c88e9bc7dfeef34acb9202 100644 (file)
@@ -368,13 +368,20 @@ void Model_Data::eraseBackReferences()
 void Model_Data::removeBackReference(FeaturePtr theFeature, std::string theAttrID)
 {
   AttributePtr anAttribute = theFeature->data()->attribute(theAttrID);
-  if (myRefsToMe.find(anAttribute) == myRefsToMe.end())
+  removeBackReference(anAttribute);
+}
+
+void Model_Data::removeBackReference(AttributePtr theAttr)
+{
+  if (myRefsToMe.find(theAttr) == myRefsToMe.end())
     return;
 
-  myRefsToMe.erase(anAttribute);
+  myRefsToMe.erase(theAttr);
 
   // remove concealment immideately: on deselection it must be posible to reselect in GUI the same
-  if (ModelAPI_Session::get()->validators()->isConcealed(theFeature->getKind(), theAttrID)) {
+  FeaturePtr aFeatureOwner = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttr->owner());
+  if (aFeatureOwner.get() &&
+    ModelAPI_Session::get()->validators()->isConcealed(aFeatureOwner->getKind(), theAttr->id())) {
     updateConcealmentFlag();
   }
 }
@@ -406,10 +413,15 @@ void Model_Data::updateConcealmentFlag()
   for(; aRefsIter != myRefsToMe.end(); aRefsIter++) {
     if (aRefsIter->get()) {
       FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRefsIter)->owner());
-      if (aFeature.get() && !aFeature->isDisabled()) {
+      if (aFeature.get() && !aFeature->isDisabled() && aFeature->isStable()) {
         if (ModelAPI_Session::get()->validators()->isConcealed(
               aFeature->getKind(), (*aRefsIter)->id())) {
-          return; // it is still concealed, nothing to do
+          std::shared_ptr<ModelAPI_Result> aRes = 
+            std::dynamic_pointer_cast<ModelAPI_Result>(myObject);
+          if (aRes.get()) {
+            aRes->setIsConcealed(true); // set concealed
+          }
+          return;
         }
       }
     }
@@ -417,11 +429,8 @@ void Model_Data::updateConcealmentFlag()
   // thus, no concealment references anymore => make not-concealed
   std::shared_ptr<ModelAPI_Result> aRes = 
     std::dynamic_pointer_cast<ModelAPI_Result>(myObject);
-  if (aRes.get() && aRes->isConcealed()) {
+  if (aRes.get()) {
     aRes->setIsConcealed(false);
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
-    ModelAPI_EventCreator::get()->sendUpdated(aRes, anEvent);
-    Events_Loop::loop()->flush(anEvent);
   }
 }
 
index 1e6c0d65082a4df12d4f9b7c7e61c9b78feed426..da40e7d4a8de9e5247bd08e92167765da748209c 100644 (file)
@@ -223,11 +223,13 @@ protected:
 private:
   /// Removes all information about back references
   void eraseBackReferences();
-  /// Adds a back reference (with identifier which attribute references to this object
-  /// It does not change the consealment flag of the data object result
+  /// Removes a back reference (with identifier which attribute references to this object)
   /// \param theFeature feature referenced to this
   /// \param theAttrID identifier of the attribute that is references from theFeature to this
   void removeBackReference(FeaturePtr theFeature, std::string theAttrID);
+  /// Removes a back reference (by the attribute)
+  /// \param theAttr the referenced attribute
+  void removeBackReference(AttributePtr theAttr);
   /// Adds a back reference (with identifier which attribute references to this object
   /// \param theFeature feature referenced to this
   /// \param theAttrID identifier of the attribute that is references from theFeature to this
index 9e209eb72b491e9e9c65c33a698981a7d6074f6e..53c9d554f3f56bb5307f22fd8455053308abcba9 100644 (file)
@@ -696,91 +696,82 @@ void Model_Objects::synchronizeFeatures(
   anOwner->executeFeatures() = true;
 }
 
-void Model_Objects::synchronizeBackRefs()
+/// synchronises back references for the given object basing on the collected data
+void Model_Objects::synchronizeBackRefsForObject(const std::set<AttributePtr>& theNewRefs,
+  ObjectPtr theObject) 
 {
-  // keeps the concealed flags of result to catch the change and create created/deleted events
-  std::list<std::pair<ResultPtr, bool> > aConcealed;
-  // first cycle: erase all data about back-references
-  NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFeatures(myFeatures);
-  for(; aFeatures.More(); aFeatures.Next()) {
-    FeaturePtr aFeature = aFeatures.Value();
-    std::shared_ptr<Model_Data> aFData = 
-      std::dynamic_pointer_cast<Model_Data>(aFeature->data());
-    if (aFData.get()) {
-      aFData->eraseBackReferences();
+  if (!theObject.get() || !theObject->data()->isValid())
+    return; // invalid
+  std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
+  // iterate new list to compare with curent
+  std::set<AttributePtr>::iterator aNewIter = theNewRefs.begin();
+  for(; aNewIter != theNewRefs.end(); aNewIter++) {
+    if (aData->refsToMe().find(*aNewIter) == aData->refsToMe().end()) {
+      FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aNewIter)->owner());
+      aData->addBackReference(aRefFeat, (*aNewIter)->id());
     }
-    const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
-    std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
-    for (; aRIter != aResults.cend(); aRIter++) {
-      std::shared_ptr<Model_Data> aResData = 
-        std::dynamic_pointer_cast<Model_Data>((*aRIter)->data());
-      if (aResData.get()) {
-        aConcealed.push_back(std::pair<ResultPtr, bool>(*aRIter, (*aRIter)->isConcealed()));
-        aResData->eraseBackReferences();
-      }
-      // iterate sub-bodies of compsolid
-      ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(*aRIter);
-      if (aComp.get()) {
-        int aNumSub = aComp->numberOfSubs();
-        for(int a = 0; a < aNumSub; a++) {
-          ResultPtr aSub = aComp->subResult(a);
-          std::shared_ptr<Model_Data> aResData = 
-            std::dynamic_pointer_cast<Model_Data>(aSub->data());
-          if (aResData.get()) {
-            aConcealed.push_back(std::pair<ResultPtr, bool>(aSub, aSub->isConcealed()));
-            aResData->eraseBackReferences();
-          }
-        }
-      }
+  }
+  if (theNewRefs.size() != aData->refsToMe().size()) { // some back ref must be removed
+    std::set<AttributePtr>::iterator aCurrentIter = aData->refsToMe().begin();
+    while(aCurrentIter != aData->refsToMe().end()) {
+      if (theNewRefs.find(*aCurrentIter) == theNewRefs.end()) {
+        aData->removeBackReference(*aCurrentIter);
+        aCurrentIter = aData->refsToMe().begin(); // reinitialize iteration after delete
+      } else aCurrentIter++;
     }
   }
+  aData->updateConcealmentFlag();
+}
 
-  // second cycle: set new back-references: only features may have reference, iterate only them
-  ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
-  for(aFeatures.Initialize(myFeatures); aFeatures.More(); aFeatures.Next()) {
+void Model_Objects::synchronizeBackRefs()
+{
+  // collect all back references in the separated container: to update everything at once,
+  // without additional Concealment switchin on and off: only the final modification
+
+  // referenced (slave) objects to referencing attirbutes
+  std::map<ObjectPtr, std::set<AttributePtr> > allRefs;
+  NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFeatures(myFeatures);
+  for(; aFeatures.More(); aFeatures.Next()) {
     FeaturePtr aFeature = aFeatures.Value();
-    std::shared_ptr<Model_Data> aFData = 
-      std::dynamic_pointer_cast<Model_Data>(aFeature->data());
+    std::shared_ptr<Model_Data> aFData = std::dynamic_pointer_cast<Model_Data>(aFeature->data());
     if (aFData.get()) {
       std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
       aFData->referencesToObjects(aRefs);
-      std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator 
-        aRefsIter = aRefs.begin();
-      for(; aRefsIter != aRefs.end(); aRefsIter++) {
-        std::list<ObjectPtr>::iterator aRefTo = aRefsIter->second.begin();
-        for(; aRefTo != aRefsIter->second.end(); aRefTo++) {
+      std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefsIt = aRefs.begin();
+      for(; aRefsIt != aRefs.end(); aRefsIt++) {
+        std::list<ObjectPtr>::iterator aRefTo = aRefsIt->second.begin();
+        for(; aRefTo != aRefsIt->second.end(); aRefTo++) {
           if (*aRefTo) {
-            std::shared_ptr<Model_Data> aRefData = 
-              std::dynamic_pointer_cast<Model_Data>((*aRefTo)->data());
-            aRefData->addBackReference(aFeature, aRefsIter->first); // here the Concealed flag is updated
-            // update enable/disable status: the nested status must be equal to the composite
-            /* MPV: not sub-elements of sketch may be enabled during editition of sketch
-            CompositeFeaturePtr aComp = 
-              std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
-            if (aComp.get()) {
-              FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>(*aRefTo);
-              if (aReferenced.get()) {
-                aReferenced->setDisabled(aComp->isDisabled());
-              }
+            std::map<ObjectPtr, std::set<AttributePtr> >::iterator aFound = allRefs.find(*aRefTo);
+            if (aFound == allRefs.end()) {
+              allRefs[*aRefTo] = std::set<AttributePtr>();
+              aFound = allRefs.find(*aRefTo);
             }
-            */
+            aFound->second.insert(aFeature->data()->attribute(aRefsIt->first));
           }
         }
       }
     }
   }
-  std::list<std::pair<ResultPtr, bool> >::iterator aCIter = aConcealed.begin();
-  for(; aCIter != aConcealed.end(); aCIter++) {
-    if (aCIter->first->isConcealed() != aCIter->second) { // something is changed => produce event
-      if (aCIter->second) { // was concealed become not => creation event
-        static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
-        ModelAPI_EventCreator::get()->sendUpdated(aCIter->first, anEvent);
-      } else { // was not concealed become concealed => delete event
-        ModelAPI_EventCreator::get()->sendDeleted(myDoc, aCIter->first->groupName());
-        // redisplay for the viewer (it must be disappeared also)
-        static Events_ID EVENT_DISP = 
-          Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
-        ModelAPI_EventCreator::get()->sendUpdated(aCIter->first, EVENT_DISP);
+  // second iteration: just compare back-references with existing in features and results
+  for(aFeatures.Initialize(myFeatures); aFeatures.More(); aFeatures.Next()) {
+    FeaturePtr aFeature = aFeatures.Value();
+    static std::set<AttributePtr> anEmpty;
+    std::map<ObjectPtr, std::set<AttributePtr> >::iterator aFound = allRefs.find(aFeature);
+    if (aFound == allRefs.end()) { // not found => erase all back references
+      synchronizeBackRefsForObject(anEmpty, aFeature);
+    } else {
+      synchronizeBackRefsForObject(aFound->second, aFeature);
+    }
+    // also for results
+    const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
+    std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
+    for(; aRes != aResults.cend(); aRes++) {
+      aFound = allRefs.find(*aRes);
+      if (aFound == allRefs.end()) { // not found => erase all back references
+        synchronizeBackRefsForObject(anEmpty, *aRes);
+      } else {
+        synchronizeBackRefsForObject(aFound->second, *aRes);
       }
     }
   }
index dc1fe7855a74cd19abd0879fcaa072365af8ca1d..9f947c776f62d0f392f076e63198c4d11736242b 100644 (file)
@@ -190,10 +190,13 @@ class Model_Objects
   /// be created before)
   std::string featureResultGroup(FeaturePtr theFeature);
 
-  ///! Returns all features of the document including the hidden features which are not in
-  ///! history. Not very fast method, for calling once, not in big cycles.
+  //! Returns all features of the document including the hidden features which are not in
+  //! history. Not very fast method, for calling once, not in big cycles.
   std::list<std::shared_ptr<ModelAPI_Feature> > allFeatures();
 
+  //! synchronises back references for the given object basing on the collected data
+  void synchronizeBackRefsForObject(
+    const std::set<std::shared_ptr<ModelAPI_Attribute>>& theNewRefs, ObjectPtr theObject);
 
  private:
   TDF_Label myMain; ///< main label of the data storage
index 0f8c3abdc25693e4d361358eb8ca9b32075da5a2..595feacf1fcc979c0317fcc425dff91b33b8b55e 100644 (file)
@@ -677,6 +677,7 @@ void Model_Update::executeFeature(FeaturePtr theFeature)
 void Model_Update::updateStability(void* theSender)
 {
   if (theSender) {
+    bool added = false; // object may be was crated
     ModelAPI_Object* aSender = static_cast<ModelAPI_Object*>(theSender);
     if (aSender && aSender->document()) {
       FeaturePtr aFeatureSender = 
@@ -701,6 +702,7 @@ void Model_Update::updateStability(void* theSender)
                   aData->addBackReference(aFeatureSender, aRefIt->first);
                 } else {
                   aData->removeBackReference(aFeatureSender, aRefIt->first);
+                  added = true; // remove of concealment may be caused creation of some result
                 }
               }
             }
@@ -708,6 +710,11 @@ void Model_Update::updateStability(void* theSender)
         }
       }
     }
+    if (added) {
+      static Events_Loop* aLoop = Events_Loop::loop();
+      static Events_ID kEventCreated = aLoop->eventByName(EVENT_OBJECT_CREATED);
+      aLoop->flush(kEventCreated);
+    }
   }
 }
 
index 624566416846743e143ed66c62a2589e6356172a..cefbd7af8310d7d2119ced6737c347304fc2e5e3 100644 (file)
@@ -54,8 +54,17 @@ void ModelAPI_Result::setIsConcealed(const bool theValue)
 {
   if (myIsConcealed != theValue) {
     myIsConcealed = theValue;
-    if (document().get()) // can be on creation of result
+    if (document().get()) // can be on creation of result
       document()->updateHistory(groupName()); // to update the history cash data in the document
+      if (myIsConcealed) {
+        ModelAPI_EventCreator::get()->sendDeleted(document(), groupName());
+        static Events_ID kDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+        ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), kDispEvent);
+      } else {
+        static Events_ID kEventCreated = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
+        ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), kEventCreated);
+      }
+    }
   }
 }