Salome HOME
Improvement #996: topological reference syntax
[modules/shaper.git] / src / Model / Model_AttributeRefAttr.cpp
index b6f9e3e67ee5fa6dffa1427c44f52232e1b5ddf3..0c24fe3e1b762cfa047e634473aca9408b288c2c 100644 (file)
@@ -7,6 +7,7 @@
 #include "Model_AttributeRefAttr.h"
 #include "Model_Application.h"
 #include "Model_Data.h"
+#include "Model_Objects.h"
 #include <ModelAPI_Feature.h>
 
 using namespace std;
@@ -23,8 +24,10 @@ void Model_AttributeRefAttr::setAttr(std::shared_ptr<ModelAPI_Attribute> theAttr
   string anID = aData->id(theAttr);
   if (myIsInitialized && object() == theAttr->owner() && myID->Get().IsEqual(anID.c_str()))
     return;  // nothing is changed
+  REMOVE_BACK_REF(theAttr->owner());
   myRef->Set(aData->label().Father());
   myID->Set(aData->id(theAttr).c_str());
+  ADD_BACK_REF(theAttr->owner());
   owner()->data()->sendAttributeUpdated(this);
 }
 
@@ -41,13 +44,26 @@ std::shared_ptr<ModelAPI_Attribute> Model_AttributeRefAttr::attr()
 
 void Model_AttributeRefAttr::setObject(ObjectPtr theObject)
 {
-  if (theObject && (!myIsInitialized || myID->Get().Length() != 0 || object() != theObject)) {
+  // the back reference from the previous object to the attribute should be removed
+  ObjectPtr anObject = object();
+  if (theObject.get() && (!myIsInitialized || myID->Get().Length() != 0 || object() != theObject)) {
+    REMOVE_BACK_REF(anObject);
+
     std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(
         theObject->data());
     myRef->Set(aData->label().Father());
     myID->Set("");  // feature is identified by the empty ID
+
+    // do it before the transaction finish to make just created/removed objects know dependencies
+    // and reference from composite feature is removed automatically
+    FeaturePtr anOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+    if (anOwnerFeature.get()) {
+      aData->addBackReference(anOwnerFeature, id(), false);
+    }
+    ADD_BACK_REF(theObject);
     owner()->data()->sendAttributeUpdated(this);
   } else if (theObject.get() == NULL) {
+    REMOVE_BACK_REF(anObject);
     myRef->Set(myRef->Label()); // reference to itself means that object is null
     myID->Set("");  // feature is identified by the empty ID
     owner()->data()->sendAttributeUpdated(this);
@@ -61,13 +77,21 @@ ObjectPtr Model_AttributeRefAttr::object()
         owner()->document());
     if (aDoc) {
       TDF_Label aRefLab = myRef->Get();
-      return aDoc->object(aRefLab);
+      return aDoc->objects()->object(aRefLab);
     }
   }
   // not initialized
   return ObjectPtr();
 }
 
+bool Model_AttributeRefAttr::isInitialized()
+{
+  if (myRef->Get() == myRef->Label()) { // empty is not initialized: sketch parallelity
+    return false;
+  }
+  return ModelAPI_AttributeRefAttr::isInitialized();
+}
+
 Model_AttributeRefAttr::Model_AttributeRefAttr(TDF_Label& theLabel)
 {
   myIsInitialized = theLabel.FindAttribute(TDataStd_Comment::GetID(), myID) == Standard_True;