]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Initial iteration for storage the back references and making concealment only on...
authormpv <mikhail.ponikarov@opencascade.com>
Mon, 27 Oct 2014 08:09:36 +0000 (11:09 +0300)
committermpv <mikhail.ponikarov@opencascade.com>
Mon, 27 Oct 2014 08:09:36 +0000 (11:09 +0300)
18 files changed:
src/Model/Model_AttributeReference.cpp
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Model/Model_AttributeSelectionList.cpp
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_ResultBody.cpp
src/Model/Model_ResultConstruction.cpp
src/Model/Model_ResultPart.cpp
src/Model/Model_Session.cpp
src/Model/Model_Update.cpp
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_Object.h
src/ModelAPI/ModelAPI_Result.h
src/ModelAPI/ModelAPI_ResultBody.h
src/XGUI/XGUI_Workshop.cpp

index 134516972b2a2eecfacab366f3bb46f9204d5a8c..3781fb2a2c4157a37b8a9b605b596e85ec4a3179 100644 (file)
@@ -20,9 +20,7 @@ void Model_AttributeReference::setValue(ObjectPtr theObject)
 
     boost::shared_ptr<Model_Document> aDoc =
       boost::dynamic_pointer_cast<Model_Document>(owner()->document());
-    if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Get()));
     myRef->Set(aData->label().Father());  // references to the feature label
-    boost::shared_dynamic_cast<Model_Document>(owner()->document())->objectIsReferenced(theObject);
 
     owner()->data()->sendAttributeUpdated(this);
   }
@@ -51,7 +49,6 @@ Model_AttributeReference::Model_AttributeReference(TDF_Label& theLabel)
     if (owner()) {
       boost::shared_ptr<Model_Document> aDoc =
         boost::dynamic_pointer_cast<Model_Document>(owner()->document());
-      if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Get()));
     }
   }
 }
@@ -62,7 +59,6 @@ void Model_AttributeReference::setObject(const boost::shared_ptr<ModelAPI_Object
     ModelAPI_AttributeReference::setObject(theObject);
     boost::shared_ptr<Model_Document> aDoc =
       boost::dynamic_pointer_cast<Model_Document>(owner()->document());
-    if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Get()));
   }
 }
 
@@ -71,5 +67,4 @@ Model_AttributeReference::~Model_AttributeReference()
   boost::shared_ptr<Model_Document> aDoc =
     boost::dynamic_pointer_cast<Model_Document>(owner()->document());
   TDF_Label aLab = myRef->Get();
-  if (aDoc && !aLab.IsNull()) aDoc->objectIsNotReferenced(aDoc->object(myRef->Get()));
 }
index 9c71730a021a647bef420f490b566f0c6cdb8c29..5c1793d848d012b01f080ca052f279115ac80c57 100644 (file)
@@ -56,7 +56,7 @@ boost::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
   boost::shared_ptr<GeomAPI_Shape> aResult;
   if (myIsInitialized) {
     Handle(TNaming_NamedShape) aSelection;
-    if (myRef.myRef->Label().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
+    if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
       TopoDS_Shape aSelShape = aSelection->Get();
       aResult = boost::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
       aResult->setImpl(new TopoDS_Shape(aSelShape));
@@ -88,7 +88,7 @@ bool Model_AttributeSelection::update()
   if (!aContext) return false;
   if (aContext->groupName() == ModelAPI_ResultBody::group()) {
     // body: just a named shape, use selection mechanism from OCCT
-    TNaming_Selector aSelector(myRef.myRef->Label());
+    TNaming_Selector aSelector(selectionLabel());
     TDF_LabelMap aScope; // empty means the whole document
     return aSelector.Solve(aScope) == Standard_True;
    
@@ -182,7 +182,7 @@ void Model_AttributeSelection::selectBody(
     const ResultPtr& theContext, const boost::shared_ptr<GeomAPI_Shape>& theSubShape)
 {
   // perform the selection
-  TNaming_Selector aSel(myRef.myRef->Label());
+  TNaming_Selector aSel(selectionLabel());
   TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl<TopoDS_Shape>() : TopoDS_Shape();
   TopoDS_Shape aContext;
 
@@ -196,9 +196,6 @@ void Model_AttributeSelection::selectBody(
     else
       throw std::invalid_argument("a result with shape is expected");
   }
-  Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aNewShape, myRef.myRef->Label());
-  TDF_Label aLab = aNS->Label();
-
   aSel.Select(aNewShape, aContext);
 }
 
@@ -249,6 +246,11 @@ void Model_AttributeSelection::selectConstruction(
     }
   }
   // store the selected as primitive
-  TNaming_Builder aBuilder(myRef.myRef->Label());
+  TNaming_Builder aBuilder(selectionLabel());
   aBuilder.Generated(aSubShape);
 }
+
+TDF_Label Model_AttributeSelection::selectionLabel()
+{
+  return myRef.myRef->Label().FindChild(1);
+}
index 79ce151daf2fd6cd10c683f167cc15914e76a846..1508476794ba5bd7f6ebd46d9d4c4a8e45a47b06 100644 (file)
@@ -47,6 +47,10 @@ protected:
   virtual void selectConstruction(
     const ResultPtr& theContext, const boost::shared_ptr<GeomAPI_Shape>& theSubShape);
 
+  /// Returns the label where TNaming_Selection results are stored
+  /// Note: there must be no attributes stored at the same label because Selector clears this lab
+  TDF_Label selectionLabel();
+
   friend class Model_Data;
   friend class Model_AttributeSelectionList;
 };
index 31a2e6473fac8d178f86dc21c3fcad510c595558..a95510118475b39a4e03d102df82725f09fa8de9 100644 (file)
@@ -43,6 +43,7 @@ boost::shared_ptr<ModelAPI_AttributeSelection>
 void Model_AttributeSelectionList::clear()
 {
   if (!mySubs.empty()) {
+    mySize->Set(0);
     mySubs.clear();
     TDF_ChildIterator aSubIter(mySize->Label());
     for(; aSubIter.More(); aSubIter.Next()) {
index b293bd3f9af914a6cf302e57f57d0325da9a53ff..c33f682a13ff740eb5f8859ca6bba5d651b3ae79 100644 (file)
@@ -392,3 +392,48 @@ int Model_Data::featureId() const
 {
   return myLab.Father().Tag(); // tag of the feature label
 }
+
+void Model_Data::addBackReference(FeaturePtr theFeature, std::string theAttrID)
+{
+  // TODO: the concealment state update
+  myRefsToMe.insert(theFeature->data()->attribute(theAttrID));
+}
+
+void Model_Data::referencesToObjects(
+  std::list<std::pair<std::string, std::list<ObjectPtr> > >& theRefs)
+{
+  std::map<std::string, boost::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = myAttrs.begin();
+  std::list<ObjectPtr> aReferenced; // not inside of cycle to avoid excess memory menagement
+  for(; anAttr != myAttrs.end(); anAttr++) {
+    std::string aType = anAttr->second->attributeType();
+    if (aType == ModelAPI_AttributeReference::type()) { // reference to object
+      boost::shared_ptr<ModelAPI_AttributeReference> aRef = boost::dynamic_pointer_cast<
+          ModelAPI_AttributeReference>(anAttr->second);
+      aReferenced.push_back(aRef->value());
+      theRefs.push_back(std::pair<std::string, std::list<ObjectPtr> >(anAttr->first, aReferenced));
+    } else if (aType == ModelAPI_AttributeRefAttr::type()) { // reference to attribute or object
+      boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef = boost::dynamic_pointer_cast<
+          ModelAPI_AttributeRefAttr>(anAttr->second);
+      aReferenced.push_back(aRef->isObject() ? aRef->object() : aRef->attr()->owner());
+    } else if (aType == ModelAPI_AttributeRefList::type()) { // list of references
+      aReferenced = boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(anAttr->second)->list();
+    } else if (aType == ModelAPI_AttributeSelection::type()) { // selection attribute
+      boost::shared_ptr<ModelAPI_AttributeSelection> aRef = boost::dynamic_pointer_cast<
+          ModelAPI_AttributeSelection>(anAttr->second);
+      aReferenced.push_back(aRef->context());
+      theRefs.push_back(std::pair<std::string, std::list<ObjectPtr> >(anAttr->first, aReferenced));
+    } else if (aType == ModelAPI_AttributeSelectionList::type()) { // list of selection attributes
+      boost::shared_ptr<ModelAPI_AttributeSelectionList> aRef = boost::dynamic_pointer_cast<
+          ModelAPI_AttributeSelectionList>(anAttr->second);
+      for(int a = aRef->size() - 1; a >= 0; a--) {
+        aReferenced.push_back(aRef->value(a)->context());
+      }
+    } else
+      continue; // nothing to do, not reference
+
+    if (!aReferenced.empty()) {
+      theRefs.push_back(std::pair<std::string, std::list<ObjectPtr> >(anAttr->first, aReferenced));
+      aReferenced.clear();
+    }
+  }
+}
index d61ddd6c2ca45302e1ef062982c815abf8302f63..f2de09385b7c1c25ff4799bdb800e0e06634162b 100644 (file)
@@ -26,6 +26,7 @@
 #include <map>
 #include <list>
 #include <string>
+#include <set>
 
 class ModelAPI_Attribute;
 
@@ -44,6 +45,9 @@ class Model_Data : public ModelAPI_Data
   /// needed here to emit signal that object changed on change of the attribute
   ObjectPtr myObject;
 
+  /// List of attributes referenced to owner (updated only during the transaction change)
+  std::set<AttributePtr> myRefsToMe;
+
   Model_Data();
 
   /// Returns label of this feature
@@ -53,6 +57,7 @@ class Model_Data : public ModelAPI_Data
   }
 
   friend class Model_Document;
+  friend class Model_Update;
   friend class Model_AttributeReference;
   friend class Model_AttributeRefAttr;
   friend class Model_AttributeRefList;
@@ -150,6 +155,14 @@ class Model_Data : public ModelAPI_Data
   /// Returns the identifier of feature-owner, unique in this document
   MODEL_EXPORT virtual int featureId() const;
 
+private:
+  // removes all information about back references
+  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 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);
 };
 
 #endif
index 59ebd2fb0f1663417cfa9e1b17c945d973215a64..509d94e6a31e08cf253b5080fb25bdf3ab670a83 100644 (file)
@@ -10,6 +10,7 @@
 #include <Model_ResultPart.h>
 #include <Model_ResultConstruction.h>
 #include <Model_ResultBody.h>
+#include <ModelAPI_Validator.h>
 #include <Events_Loop.h>
 #include <Events_Error.h>
 
@@ -146,7 +147,7 @@ bool Model_Document::load(const char* theFileName)
     myDoc->SetUndoLimit(UNDO_LIMIT);
     // to avoid the problem that feature is created in the current, not this, document
     Model_Session::get()->setActiveDocument(anApp->getDocument(myID));
-    synchronizeFeatures();
+    synchronizeFeatures(false, true);
   }
   return !isError;
 }
@@ -304,7 +305,7 @@ void Model_Document::abortOperation()
       myNestedNum = -1;
     myDoc->AbortCommand();
   }
-  synchronizeFeatures(true);
+  synchronizeFeatures(true, false); // references were not changed since transaction start
   // abort for all subs
   std::set<std::string>::iterator aSubIter = mySubs.begin();
   for (; aSubIter != mySubs.end(); aSubIter++)
@@ -343,7 +344,7 @@ void Model_Document::undo()
     myNestedNum--;
   if (!myIsEmptyTr[myTransactionsAfterSave])
     myDoc->Undo();
-  synchronizeFeatures(true);
+  synchronizeFeatures(true, true);
   // undo for all subs
   std::set<std::string>::iterator aSubIter = mySubs.begin();
   for (; aSubIter != mySubs.end(); aSubIter++)
@@ -369,7 +370,7 @@ void Model_Document::redo()
   if (!myIsEmptyTr[myTransactionsAfterSave])
     myDoc->Redo();
   myTransactionsAfterSave++;
-  synchronizeFeatures(true);
+  synchronizeFeatures(true, true);
   // redo for all subs
   std::set<std::string>::iterator aSubIter = mySubs.begin();
   for (; aSubIter != mySubs.end(); aSubIter++)
@@ -467,10 +468,12 @@ 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()) {
@@ -590,9 +593,9 @@ ObjectPtr Model_Document::object(const std::string& theGroupID, const int theInd
       std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
       for (; aRIter != aResults.cend(); aRIter++) {
         if ((*aRIter)->groupName() != theGroupID) continue;
-        bool isIn = theHidden;
+        bool isIn = theHidden && (*aRIter)->isInHistory();
         if (!isIn && (*aRIter)->isInHistory()) { // check that there is nobody references this result
-          isIn = myConcealedResults.find(*aRIter) == myConcealedResults.end();
+          isIn = !(*aRIter)->isConcealed();
         }
         if (isIn) {
           if (anIndex == theIndex)
@@ -629,7 +632,7 @@ int Model_Document::size(const std::string& theGroupID, const bool theHidden)
         if ((*aRIter)->groupName() != theGroupID) continue;
         bool isIn = theHidden;
         if (!isIn && (*aRIter)->isInHistory()) { // check that there is nobody references this result
-          isIn = myConcealedResults.find(*aRIter) == myConcealedResults.end();
+          isIn = !(*aRIter)->isConcealed();
         }
         if (isIn)
           aResult++;
@@ -664,12 +667,12 @@ void Model_Document::setUniqueName(FeaturePtr theFeature)
   // check this is unique, if not, increase index by 1
   for (aFIter.Initialize(myObjs); aFIter.More();) {
     FeaturePtr aFeature = aFIter.Value();
-    bool isSameName = aFeature->isInHistory() && aFeature->data()->name() == aName;
+    bool isSameName = aFeature->data()->name() == aName;
     if (!isSameName) {  // check also results to avoid same results names (actual for Parts)
       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++) {
-        isSameName = (*aRIter)->isInHistory() && (*aRIter)->data()->name() == aName;
+        isSameName = (*aRIter)->data()->name() == aName;
       }
     }
     if (isSameName) {
@@ -701,7 +704,7 @@ void Model_Document::initData(ObjectPtr theObj, TDF_Label theLab, const int theT
   }
 }
 
-void Model_Document::synchronizeFeatures(const bool theMarkUpdated)
+void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences)
 {
   boost::shared_ptr<ModelAPI_Document> aThis = 
     Model_Application::getApplication()->getDocument(myID);
@@ -785,6 +788,49 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated)
       aFIter.Next();
   }
 
+  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
+          }
+        }
+      }
+    }
+  }
+
   myExecuteFeatures = false;
   aLoop->activateFlushes(true);
 
@@ -928,48 +974,6 @@ void Model_Document::updateResults(FeaturePtr theFeature)
   }
 }
 
-void Model_Document::objectIsReferenced(const ObjectPtr& theObject)
-{
-  // only bodies are concealed now
-  ResultBodyPtr aResult = boost::dynamic_pointer_cast<ModelAPI_ResultBody>(theObject);
-  if (aResult) {
-    if (myConcealedResults.find(aResult) != myConcealedResults.end()) {
-      Events_Error::send(std::string("The object '") + aResult->data()->name() +
-        "' is already referenced");
-    } else {
-      myConcealedResults.insert(aResult);
-      boost::shared_ptr<ModelAPI_Document> aThis = 
-        Model_Application::getApplication()->getDocument(myID);
-      ModelAPI_EventCreator::get()->sendDeleted(aThis, ModelAPI_ResultBody::group());
-
-      static Events_Loop* aLoop = Events_Loop::loop();
-      static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
-      static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
-      aECreator->sendUpdated(aResult, EVENT_DISP);
-    }
-  }
-}
-
-void Model_Document::objectIsNotReferenced(const ObjectPtr& theObject)
-{
-  // only bodies are concealed now
-  ResultBodyPtr aResult = boost::dynamic_pointer_cast<ModelAPI_ResultBody>(theObject);
-  if (aResult) {
-    std::set<ResultPtr>::iterator aFind = myConcealedResults.find(aResult);
-    if (aFind != myConcealedResults.end()) {
-      ResultPtr aFeature = *aFind;
-      myConcealedResults.erase(aFind);
-      boost::shared_ptr<ModelAPI_Document> aThis = 
-        Model_Application::getApplication()->getDocument(myID);
-      static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
-      ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent, false);
-    } else {
-      Events_Error::send(std::string("The object '") + aResult->data()->name() +
-        "' was not referenced '");
-    }
-  }
-}
-
 Standard_Integer HashCode(const TDF_Label& theLab, const Standard_Integer theUpper)
 {
   return TDF_LabelMapHasher::HashCode(theLab, theUpper);
index 6f813bd231da45a6b72917c1b7cb508605c3259f..2446cbf7c2b01b3f27cbd39454d11eac4e2267cb 100644 (file)
@@ -130,12 +130,6 @@ class Model_Document : public ModelAPI_Document
   ///! On abort, undo or redo it is not necessary: results in document are updated automatically
   bool executeFeatures() {return myExecuteFeatures;}
 
-  ///! Reutrns true is result was conecaled because of usage it by other object
-  virtual bool isConcealed(const boost::shared_ptr<ModelAPI_Object>& theResult) {
-    return myConcealedResults.find(boost::dynamic_pointer_cast<ModelAPI_Result>(theResult))
-      != myConcealedResults.end();
-  }
-
  protected:
 
   //! Returns (creates if needed) the features label
@@ -146,7 +140,9 @@ class Model_Document : public ModelAPI_Document
   void setUniqueName(FeaturePtr theFeature);
 
   //! Synchronizes myFeatures list with the updated document
-  void synchronizeFeatures(const bool theMarkUpdated = false);
+  //! \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);
 
   //! Creates new document with binary file format
   Model_Document(const std::string theID, const std::string theKind);
@@ -174,11 +170,6 @@ class Model_Document : public ModelAPI_Document
   //! Updates the results list of the feature basing on the current data tree
   void updateResults(FeaturePtr theFeature);
 
-  //! Stores information that there is a reference to this object
-  void objectIsReferenced(const ObjectPtr& theObject);
-  //! Removes information that there is a reference to this object
-  void objectIsNotReferenced(const ObjectPtr& theObject);
-
   //! Returns all sub documents
   const std::set<std::string>& subDocuments() const {return mySubs;}
 
@@ -198,8 +189,6 @@ class Model_Document : public ModelAPI_Document
   /// All features managed by this document (not only in history of OB)
   /// For optimization mapped by labels
   NCollection_DataMap<TDF_Label, FeaturePtr> myObjs;
-  /// Results that are referenced and must be concealed for object browser
-  std::set<ResultPtr> myConcealedResults;
 
   ///< set of identifiers of sub-documents of this document
   std::set<std::string> mySubs;
index f5c8cb223d1d0438fc78fc0210628e840328add0..1fad264d8122ff265b11deea8178ad15d0ce9bce 100644 (file)
@@ -12,6 +12,7 @@
 
 Model_ResultBody::Model_ResultBody()
 {
+  setIsConcealed(false);
 }
 
 void Model_ResultBody::store(const boost::shared_ptr<GeomAPI_Shape>& theShape)
index 0b6d56612c64ffd89b2e735e8f45f67788a29f97..8af38252d8805c917b64bb5b34ace6b63ed55860 100644 (file)
@@ -17,6 +17,7 @@ boost::shared_ptr<GeomAPI_Shape>& Model_ResultConstruction::shape()
 Model_ResultConstruction::Model_ResultConstruction()
 {
   myIsInHistory = true;
+  setIsConcealed(false);
 }
 
 void Model_ResultConstruction::setIsInHistory(const bool isInHistory)
index 98319c4749f33fc524bba9e5ee00662d21a87043..a1fb09b010ff87b8cbbc935e96201ebcbb7d1dfe 100644 (file)
@@ -19,6 +19,7 @@ boost::shared_ptr<ModelAPI_Feature> Model_ResultPart::owner()
 
 Model_ResultPart::Model_ResultPart()
 {
+  setIsConcealed(false);
 }
 
 void Model_ResultPart::setData(boost::shared_ptr<ModelAPI_Data> theData)
index 6a3cf53cc0718af4ba104f2e7d19a3bfededcb95..37b020eeeec6be69126e17a0eefcf386887059f8 100644 (file)
@@ -191,7 +191,7 @@ boost::shared_ptr<ModelAPI_Document> Model_Session::copy(
   aRT->SetRelocation(aSourceRoot, aTargetRoot);
   TDF_CopyTool::Copy(aDS, aRT);
 
-  aNew->synchronizeFeatures();
+  aNew->synchronizeFeatures(false, true);
   return aNew;
 }
 
index 5ef4a8f098d65d9383f74425ca700e106a6c14df..ccdd45e77d1588a490b8edec85e784be4178a34c 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <Model_Update.h>
 #include <Model_Document.h>
+#include <Model_Data.h>
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Document.h>
@@ -137,67 +138,16 @@ bool Model_Update::updateFeature(FeaturePtr theFeature)
           aMustbeUpdated = true;
       }
     }
-
-    // references
-    list<boost::shared_ptr<ModelAPI_Attribute> > aRefs = theFeature->data()->attributes(
-        ModelAPI_AttributeReference::type());
-    list<boost::shared_ptr<ModelAPI_Attribute> >::iterator aRefsIter = aRefs.begin();
-    for (; aRefsIter != aRefs.end(); aRefsIter++) {
-      boost::shared_ptr<ModelAPI_Object> aSub = boost::dynamic_pointer_cast<
-          ModelAPI_AttributeReference>(*aRefsIter)->value();
-      if (updateObject(aSub)) {
-        aMustbeUpdated = true;
-      }
-    }
-    // reference to attribute or object
-    list<boost::shared_ptr<ModelAPI_Attribute> > aRefAttrs = theFeature->data()->attributes(
-        ModelAPI_AttributeRefAttr::type());
-    for (aRefsIter = aRefAttrs.begin(); aRefsIter != aRefAttrs.end(); aRefsIter++) {
-      boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
-        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefsIter);
-      if (!aRef) continue;
-      if (aRef->isObject()) {
-        boost::shared_ptr<ModelAPI_Object> aSub = aRef->object();
-        if (updateObject(aSub)) {
-          aMustbeUpdated = true;
-        }
-      } else if (aRef->attr()) { // reference to the attribute
-        boost::shared_ptr<ModelAPI_Object> aSub = aRef->attr()->owner();
-        if (updateObject(aSub)) {
-          aMustbeUpdated = true;
-        }
-      }
-    }
-    // lists of references
-    aRefs = theFeature->data()->attributes(ModelAPI_AttributeRefList::type());
-    for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
-      list<ObjectPtr> aListRef = boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*aRefsIter)
-          ->list();
-      list<ObjectPtr>::iterator aListIter = aListRef.begin();
-      for (; aListIter != aListRef.end(); aListIter++) {
-        boost::shared_ptr<ModelAPI_Object> aSub = *aListIter;
-        if (updateObject(aSub)) {
-          aMustbeUpdated = true;
-        }
-      }
-    }
-    // selection attributes: must be called "update" methods if needed
-    aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelection::type());
-    for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
-      boost::shared_ptr<ModelAPI_AttributeSelection> aSel =
-        boost::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*aRefsIter);
-      if (updateObject(aSel->context())) {
-        aMustbeUpdated = true;
-        // aSel->update(); // this must be done on execution since it may be long operation
-      }
-    }
-    // lists of selection attributes: must be called "update" methods if needed
-    aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelectionList::type());
-    for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
-      boost::shared_ptr<ModelAPI_AttributeSelectionList> aSel =
-        boost::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aRefsIter);
-      for(int a = aSel->size() - 1; a >= 0; a--) {
-        if (updateObject(aSel->value(a)->context())) {
+    // check all references: if referenced objects are updated, this object also must be updated
+    std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
+    boost::shared_ptr<Model_Data> aData = 
+      boost::dynamic_pointer_cast<Model_Data>(theFeature->data());
+    aData->referencesToObjects(aRefs);
+    std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRef = aRefs.begin();
+    for(; aRef != aRefs.end(); aRef++) {
+      std::list<ObjectPtr>::iterator aRefObj = aRef->second.begin();
+      for(; aRefObj != aRef->second.end(); aRefObj++) {
+        if (updateObject(*aRefObj)) {
           aMustbeUpdated = true;
         }
       }
@@ -214,8 +164,10 @@ bool Model_Update::updateFeature(FeaturePtr theFeature)
             !theFeature->isPersistentResult() /* execute quick, not persistent results */) 
           {
             // before execution update the selection attributes if any
-            aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelection::type());
-            for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
+            list<AttributePtr> aRefs = 
+              theFeature->data()->attributes(ModelAPI_AttributeSelection::type());
+            list<AttributePtr>::iterator aRefsIter = aRefs.begin();
+            for (; aRefsIter != aRefs.end(); aRefsIter++) {
               boost::shared_ptr<ModelAPI_AttributeSelection> aSel =
                 boost::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*aRefsIter);
               aSel->update(); // this must be done on execution since it may be long operation
index 773ec389cf5a49b52cd8259c8374a5b28e8f6119..cdfa1d75ed89bb6661e2d7e30a239cfc3eab1a88 100644 (file)
@@ -81,9 +81,6 @@ public:
   virtual boost::shared_ptr<ModelAPI_Feature> feature(
       const boost::shared_ptr<ModelAPI_Result>& theResult) = 0;
 
-  ///! Reutrns true is result was conecaled because of usage it by other object
-  virtual bool isConcealed(const boost::shared_ptr<ModelAPI_Object>& theResult) = 0;
-
 protected:
   /// Only for SWIG wrapping it is here
   MODELAPI_EXPORT ModelAPI_Document()
index 7c539d7d52e84608445a9033a9d5e8afaa4ca491..f6e3c6c3228d6b34867361e7ab06a8060b3c06d5 100644 (file)
@@ -56,6 +56,7 @@ class ModelAPI_Object
 
   /// To use virtuality for destructors
   virtual ~ModelAPI_Object() {}
+
  protected:
   /// Sets the data manager of an object (document does)
   virtual void setData(boost::shared_ptr<ModelAPI_Data> theData)
index af9e7ce87edba6ae1b672dc98f7c7cffe056d77b..eb664ec221c92ccb1a0befd1b1a9a5ab3d035c76 100644 (file)
@@ -17,12 +17,19 @@ class ModelAPI_Feature;
  */
 class ModelAPI_Result : public ModelAPI_Object
 {
+  bool myIsConcealed; ///< the result is concealed from the data tree (referenced by other objects)
  public:
-  /// Returns the source feature of this result
-  //virtual boost::shared_ptr<ModelAPI_Feature> owner() = 0;
+   /// Returns true if the result is concealed from the data tree (referenced by other objects)
+  inline bool isConcealed() {return myIsConcealed;}
+
+  /// Returns true if the result is concealed from the data tree (referenced by other objects)
+  inline void setIsConcealed(const bool theValue) {myIsConcealed = theValue;}
+
+  /// To virtually destroy the fields of successors
+  virtual ~ModelAPI_Result()
+  {
+  }
 
-  /// Returns the group identifier of this result
-  //virtual std::string groupName() = 0;
 };
 
 //! Pointer on feature object
index bcd45b354aa721d90e17cd7b32121c47f21fb2b9..db329c1fc621be76c2fab6d7afd0015c197ab20a 100644 (file)
@@ -39,11 +39,6 @@ public:
   /// Returns the shape-result produced by this feature
   virtual boost::shared_ptr<GeomAPI_Shape> shape() = 0;
 
-  /// To virtually destroy the fields of successors
-  virtual ~ModelAPI_ResultBody()
-  {
-  }
-
   /// Records the subshape newShape which was generated during a topological construction.
   /// As an example, consider the case of a face generated in construction of a box.
   virtual void generated(
@@ -66,11 +61,6 @@ public:
     const boost::shared_ptr<GeomAPI_Shape>& theOldShape, const int theTag = 1) = 0;
 
 protected:
-  /// Use plugin manager for features creation: this method is 
-  /// defined here only for SWIG-wrapping
-  ModelAPI_ResultBody()
-  {
-  }
 };
 
 //! Pointer on feature object
index 8ca4729a3f373e5765c1b5a69a41dba3a796862b..7746a3c5637197f88c180da9396c1dd48b612101 100644 (file)
@@ -419,7 +419,12 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const boost::shared_ptr<ModelAPI_Objec
   QIntList aModes;
   for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
     ObjectPtr aObj = (*aIt);
-    if (!aObj->data() || !aObj->data()->isValid() || aObj->document()->isConcealed(aObj))
+    bool aHide = !aObj->data() || !aObj->data()->isValid();
+    if (!aHide) { // check that this is not hidden result
+      ResultPtr aRes = boost::dynamic_pointer_cast<ModelAPI_Result>(aObj);
+      aHide = aRes && aRes->isConcealed();
+    }
+    if (aHide)
       myDisplayer->erase(aObj, false);
     else {
       if (myDisplayer->isVisible(aObj))  {
@@ -463,8 +468,7 @@ void XGUI_Workshop::onFeatureCreatedMsg(const boost::shared_ptr<ModelAPI_ObjectU
       // it doesn't stored in the operation mgr and doesn't displayed
     } else if (myOperationMgr->hasOperation()) {
       ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
-      if (!(*aIt)->document()->isConcealed(*aIt) &&
-          aOperation->hasObject(*aIt)) {  // Display only current operation results
+      if (aOperation->hasObject(*aIt)) {  // Display only current operation results
         myDisplayer->display(*aIt, false);
         isDisplayed = true;
       }