Salome HOME
Debug of selection and delete of feature
authormpv <mikhail.ponikarov@opencascade.com>
Mon, 27 Oct 2014 11:55:00 +0000 (14:55 +0300)
committermpv <mikhail.ponikarov@opencascade.com>
Mon, 27 Oct 2014 11:55:00 +0000 (14:55 +0300)
src/Model/Model_AttributeSelection.cpp
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/ModelAPI/ModelAPI_Data.h
src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp

index 5c1793d848d012b01f080ca052f279115ac80c57..3d351d4132510f01df693dce50be930c92649ee6 100644 (file)
@@ -129,7 +129,7 @@ bool Model_AttributeSelection::update()
             for(; aRes != aResults.cend(); aRes++) {
               ResultConstructionPtr aConstr = 
                 boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
-              if (aConstr->shape()) {
+              if (aConstr->shape() && aConstr->shape()->isEdge()) {
                 const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
                 TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
                 if (!anEdge.IsNull()) {
@@ -230,7 +230,7 @@ void Model_AttributeSelection::selectConstruction(
     for(; aRes != aResults.cend(); aRes++) {
       ResultConstructionPtr aConstr = 
         boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
-      if (aConstr->shape()) {
+      if (aConstr->shape() && aConstr->shape()->isEdge()) {
         const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
         TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
         if (!anEdge.IsNull()) {
index c33f682a13ff740eb5f8859ca6bba5d651b3ae79..cc3ed5ef3b003ba4390bb21cddbd6d4a1b3574e2 100644 (file)
@@ -351,43 +351,6 @@ bool Model_Data::mustBeUpdated()
   return myLab.IsAttribute(kMustBeUpdatedGUID) == Standard_True;
 }
 
-bool Model_Data::referencesTo(const boost::shared_ptr<ModelAPI_Feature>& theFeature)
-{
-  // collect results of this feature first to check references quickly in the cycle
-  std::set<ObjectPtr> aFeatureObjs;
-  aFeatureObjs.insert(theFeature);
-  std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter =
-    theFeature->results().cbegin();
-  for(; aRIter != theFeature->results().cend(); aRIter++) {
-    if (*aRIter)
-      aFeatureObjs.insert(*aRIter);
-  }
-
-  std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter = 
-    myAttrs.begin();
-  for (; anAttrsIter != myAttrs.end(); anAttrsIter++) {
-    if (anAttrsIter->second->attributeType() == ModelAPI_AttributeRefAttr::type()) {
-      boost::shared_ptr<ModelAPI_AttributeRefAttr> aRefAttr = 
-        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttrsIter->second);
-      if (aRefAttr && aRefAttr->isObject()) { // check referenced object
-        if (aFeatureObjs.find(aRefAttr->object()) != aFeatureObjs.end())
-          return true;
-      } else { // check object of referenced attribute
-        boost::shared_ptr<ModelAPI_Attribute> anAttr = aRefAttr->attr();
-        if (anAttr && aFeatureObjs.find(anAttr->owner()) != aFeatureObjs.end())
-          return true;
-      }
-    } else if (anAttrsIter->second->attributeType() == ModelAPI_AttributeReference::type()) {
-      boost::shared_ptr<ModelAPI_AttributeReference> aRef = 
-        boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttrsIter->second);
-      if (aFeatureObjs.find(aRef->value()) != aFeatureObjs.end()) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
 int Model_Data::featureId() const
 {
   return myLab.Father().Tag(); // tag of the feature label
index f2de09385b7c1c25ff4799bdb800e0e06634162b..46d50acc0080a7dc069f0a9db8198e6abd22ecc2 100644 (file)
@@ -149,9 +149,6 @@ class Model_Data : public ModelAPI_Data
   /// Returns true if feature must be updated (re-executed) on rebuild
   MODEL_EXPORT virtual bool mustBeUpdated();
 
-  /// Returns true if this data attributes are referenced to the given feature or its results
-  MODEL_EXPORT virtual bool referencesTo(const boost::shared_ptr<ModelAPI_Feature>& theFeature);
-
   /// Returns the identifier of feature-owner, unique in this document
   MODEL_EXPORT virtual int featureId() const;
 
@@ -160,6 +157,8 @@ private:
   inline void eraseBackReferences() {myRefsToMe.clear();}
   // adds a back reference (with identifier which attribute references to this object
   void addBackReference(FeaturePtr theFeature, std::string theAttrID);
+  // returns all objects referenced to this
+  const std::set<AttributePtr>& refsToMe() {return myRefsToMe;}
   // returns all references by attributes of this data
   // \param the returned list of pairs: id of referenced attribute and list of referenced objects
   void referencesToObjects(std::list<std::pair<std::string, std::list<ObjectPtr> > >& theRefs);
index 509d94e6a31e08cf253b5080fb25bdf3ab670a83..05452239ceba196e3b7763f29263c154c8bf29db 100644 (file)
@@ -265,10 +265,12 @@ void Model_Document::finishOperation()
   if (!myDoc->HasOpenCommand() && myNestedNum != -1)
     boost::static_pointer_cast<Model_Session>(Model_Session::get())
         ->setCheckTransactions(false);  // for nested transaction commit
+  synchronizeBackRefs();
   Events_Loop* aLoop = Events_Loop::loop();
   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TOHIDE));
   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
   if (!myDoc->HasOpenCommand() && myNestedNum != -1)
     boost::static_pointer_cast<Model_Session>(Model_Session::get())
@@ -468,18 +470,11 @@ void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck)
     // check the feature: it must have no depended objects on it
     std::list<ResultPtr>::const_iterator aResIter = theFeature->results().cbegin();
     for(; aResIter != theFeature->results().cend(); aResIter++) {
-      /*
-      if (myConcealedResults.find(*aResIter) != myConcealedResults.end()) {
-        Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted");
-        return;
-      }
-      */
-    }
-    NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator anObjIter(myObjs);
-    for(; anObjIter.More(); anObjIter.Next()) {
-      DataPtr aData = anObjIter.Value()->data();
-      if (aData->referencesTo(theFeature)) {
-        Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted");
+      boost::shared_ptr<Model_Data> aData = 
+        boost::dynamic_pointer_cast<Model_Data>((*aResIter)->data());
+      if (aData && !aData->refsToMe().empty()) {
+        Events_Error::send(
+          "Feature '" + theFeature->data()->name() + "' is used and can not be deleted");
         return;
       }
     }
@@ -496,22 +491,11 @@ void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck)
   // erase all attributes under the label of feature
   aFeatureLabel.ForgetAllAttributes();
   // remove it from the references array
-  RemoveFromRefArray(featuresLabel(), aFeatureLabel);
-
+  if (theFeature->isInHistory()) {
+    RemoveFromRefArray(featuresLabel(), aFeatureLabel);
+  }
   // event: feature is deleted
   ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group());
-  /* this is in "erase"
-  // results of this feature must be redisplayed
-  static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
-  const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
-  std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
-  for (; aRIter != aResults.cend(); aRIter++) {
-    boost::shared_ptr<ModelAPI_Result> aRes = *aRIter;
-    aRes->setData(boost::shared_ptr<ModelAPI_Data>());  // deleted flag
-    ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP);
-    ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), aRes->groupName());
-  }
-  */
 }
 
 FeaturePtr Model_Document::feature(TDF_Label& theLabel)
@@ -789,46 +773,7 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t
   }
 
   if (theUpdateReferences) {
-    // first cycle: erase all data about back-references
-    NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFeatures(myObjs);
-    for(; aFeatures.More(); aFeatures.Next()) {
-      FeaturePtr aFeature = aFeatures.Value();
-      boost::shared_ptr<Model_Data> aFData = 
-        boost::dynamic_pointer_cast<Model_Data>(aFeature->data());
-      if (aFData) {
-        aFData->eraseBackReferences();
-      }
-      const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
-      std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
-      for (; aRIter != aResults.cend(); aRIter++) {
-        boost::shared_ptr<Model_Data> aResData = 
-          boost::dynamic_pointer_cast<Model_Data>((*aRIter)->data());
-        if (aResData) {
-          aResData->eraseBackReferences();
-        }
-      }
-    }
-
-    // second cycle: set new back-references: only features may have reference, iterate only them
-    ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
-    for(aFeatures.Initialize(myObjs); aFeatures.More(); aFeatures.Next()) {
-      FeaturePtr aFeature = aFeatures.Value();
-      boost::shared_ptr<Model_Data> aFData = 
-        boost::dynamic_pointer_cast<Model_Data>(aFeature->data());
-      if (aFData) {
-        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 aReferenced = aRefsIter->second.begin();
-          for(; aReferenced != aRefsIter->second.end(); aReferenced++) {
-            boost::shared_ptr<Model_Data> aRefData = 
-              boost::dynamic_pointer_cast<Model_Data>((*aReferenced)->data());
-            aRefData->addBackReference(aFeature, aRefsIter->first); // here the Concealed flag is updated
-          }
-        }
-      }
-    }
+    synchronizeBackRefs();
   }
 
   myExecuteFeatures = false;
@@ -840,11 +785,58 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t
     aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
   }
   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TOHIDE));
   boost::static_pointer_cast<Model_Session>(Model_Session::get())
     ->setCheckTransactions(true);
   myExecuteFeatures = true;
 }
 
+void Model_Document::synchronizeBackRefs()
+{
+  // first cycle: erase all data about back-references
+  NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFeatures(myObjs);
+  for(; aFeatures.More(); aFeatures.Next()) {
+    FeaturePtr aFeature = aFeatures.Value();
+    boost::shared_ptr<Model_Data> aFData = 
+      boost::dynamic_pointer_cast<Model_Data>(aFeature->data());
+    if (aFData) {
+      aFData->eraseBackReferences();
+    }
+    const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
+    std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
+    for (; aRIter != aResults.cend(); aRIter++) {
+      boost::shared_ptr<Model_Data> aResData = 
+        boost::dynamic_pointer_cast<Model_Data>((*aRIter)->data());
+      if (aResData) {
+        aResData->eraseBackReferences();
+      }
+    }
+  }
+
+  // second cycle: set new back-references: only features may have reference, iterate only them
+  ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+  for(aFeatures.Initialize(myObjs); aFeatures.More(); aFeatures.Next()) {
+    FeaturePtr aFeature = aFeatures.Value();
+    boost::shared_ptr<Model_Data> aFData = 
+      boost::dynamic_pointer_cast<Model_Data>(aFeature->data());
+    if (aFData) {
+      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++) {
+          if (*aRefTo) {
+            boost::shared_ptr<Model_Data> aRefData = 
+              boost::dynamic_pointer_cast<Model_Data>((*aRefTo)->data());
+            aRefData->addBackReference(aFeature, aRefsIter->first); // here the Concealed flag is updated
+          }
+        }
+      }
+    }
+  }
+}
+
 TDF_Label Model_Document::resultLabel(
   const boost::shared_ptr<ModelAPI_Data>& theFeatureData, const int theResultIndex) 
 {
index 2446cbf7c2b01b3f27cbd39454d11eac4e2267cb..cbea4a19e58826dd8c9148f0e33679ccea3b60d8 100644 (file)
@@ -143,6 +143,8 @@ class Model_Document : public ModelAPI_Document
   //! \param theMarkUpdated causes the "update" event for all features
   //! \param theUpdateReferences causes the update of back-references
   void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences);
+  //! Synchronizes the BackReferences list in Data of Features and Results
+  void synchronizeBackRefs();
 
   //! Creates new document with binary file format
   Model_Document(const std::string theID, const std::string theKind);
index 85c65cbd5fbab26156409800dcb267504ddff955..2acf4fc6bf2cc264c2123d1c2094aa2f11119c6a 100644 (file)
@@ -106,9 +106,6 @@ class MODELAPI_EXPORT ModelAPI_Data
   /// Returns true if feature must be updated (re-executed) on rebuild
   virtual bool mustBeUpdated() = 0;
 
-  /// Returns true if this data attributes are referenced to the given feature or its results
-  virtual bool referencesTo(const boost::shared_ptr<ModelAPI_Feature>& theFeature) = 0;
-
   /// Returns the identifier of feature-owner, unique in this document
   virtual int featureId() const = 0;
 
index 47045007066d2890123230111f8352465ea8efc1..1de73631a75a822059f694ee04595d6f7d59c3e3 100644 (file)
@@ -227,7 +227,6 @@ void ModuleBase_WidgetShapeSelector::setObject(ObjectPtr theObj, boost::shared_p
     if (!myUseSubShapes) {
       static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TOHIDE);
       ModelAPI_EventCreator::get()->sendUpdated(mySelectedObject, anEvent);
-      Events_Loop::loop()->flush(anEvent);
     }
   } 
   updateSelectionName();