Salome HOME
Implementation of the issue #1307. Also make connected parameters from different...
authormpv <mpv@opencascade.com>
Tue, 5 Apr 2016 12:52:56 +0000 (15:52 +0300)
committermpv <mpv@opencascade.com>
Tue, 5 Apr 2016 12:52:56 +0000 (15:52 +0300)
src/Model/Model_AttributeRefList.cpp
src/Model/Model_AttributeRefList.h
src/Model/Model_Data.cpp
src/Model/Model_Document.cpp
src/Model/Model_Update.cpp
src/ParametersPlugin/ParametersPlugin_Parameter.cpp
src/SketchPlugin/Test/TestConstraintConcidence.py

index cf45b99a957792820aa8c461941539d8bb3db3f6..36d11541c50724c82befa3355af40875bee1e31a 100644 (file)
 #include "Model_Objects.h"
 #include <ModelAPI_Feature.h>
 #include <TDF_ListIteratorOfLabelList.hxx>
+#include <TDF_Tool.hxx>
+#include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
 
 using namespace std;
 
 void Model_AttributeRefList::append(ObjectPtr theObject)
 {
-  std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
-  myRef->Append(aData->label().Father());  // store label of the object
+  if (owner()->document() == theObject->document()) {
+    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
+    myRef->Append(aData->label().Father());  // store label of the object
+  } else if (theObject.get() && theObject->data()->isValid()) { // reference to the other document
+    myRef->Append(myRef->Label());
+    // if these attributes exist, the link is external: keep reference to access the label
+    std::ostringstream anIdString; // string with document Id
+    anIdString<<theObject->document()->id();
+    myExtDocRef->Append(anIdString.str().c_str());
+    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
+    TCollection_AsciiString anEntry;
+    TDF_Tool::Entry(aData->label().Father(), anEntry);
+    myExtDocRef->Append(anEntry);
+  } else return; // something is wrong
+
   // do it before the transaction finish to make just created/removed objects know dependencies
   // and reference from composite feature is removed automatically
   ADD_BACK_REF(theObject);
-
   owner()->data()->sendAttributeUpdated(this);
 }
 
 void Model_AttributeRefList::remove(ObjectPtr theObject)
 {
-  std::shared_ptr<Model_Data> aData;
   if (theObject.get() != NULL) {
-    aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
-    myRef->Remove(aData->label().Father());
-    REMOVE_BACK_REF(theObject);
+    if (owner()->document() == theObject->document()) {
+      std::shared_ptr<Model_Data> aData;
+      aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
+      myRef->Remove(aData->label().Father());
+      REMOVE_BACK_REF(theObject);
+      owner()->data()->sendAttributeUpdated(this);
+    } else {
+      // create new lists because for the current moment remove one of the duplicated elements
+      // from the list is buggy
+      TDF_LabelList anOldList = myRef->List();
+      myRef->Clear();
+      TDataStd_ListOfExtendedString anOldExts = myExtDocRef->List();
+      myExtDocRef->Clear();
+
+      std::ostringstream anIdString; // string with document Id
+      anIdString<<theObject->document()->id();
+      std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
+      TCollection_AsciiString anEntry;
+      TDF_Tool::Entry(aData->label().Father(), anEntry);
+      bool aFound = false;
+      TDataStd_ListIteratorOfListOfExtendedString anExtIter(anOldExts);
+      for (TDF_ListIteratorOfLabelList aLIter(anOldList); aLIter.More(); aLIter.Next()) {
+        if (aLIter.Value() == myRef->Label()) {
+          if (anExtIter.Value() == anIdString.str().c_str()) {
+            TDataStd_ListIteratorOfListOfExtendedString anExtIter2 = anExtIter;
+            anExtIter2.Next();
+            if (anExtIter2.Value() == anEntry) { // fully maches, so, remove(don't copy)
+              aFound = true;
+              continue;
+            }
+          }
+          myExtDocRef->Append(anExtIter.Value());
+          anExtIter.Next();
+          myExtDocRef->Append(anExtIter.Value());
+          anExtIter.Next();
+        }
+        myRef->Append(aLIter.Value());
+      }
+      if (aFound) {
+        REMOVE_BACK_REF(theObject);
+        owner()->data()->sendAttributeUpdated(this);
+      }
+    }
   }
   else { // in case of empty object remove, the first empty object is removed from the list
     std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
@@ -42,12 +95,12 @@ void Model_AttributeRefList::remove(ObjectPtr theObject)
         if (anObj.get() == NULL) {
           myRef->Remove(aLIter.Value());
           REMOVE_BACK_REF(theObject);
+          owner()->data()->sendAttributeUpdated(this);
           break;
         }
       }
     }
   }
-  owner()->data()->sendAttributeUpdated(this);
 }
 
 void Model_AttributeRefList::clear()
@@ -58,6 +111,7 @@ void Model_AttributeRefList::clear()
   for(; anOldIter != anOldList.end(); anOldIter++) {
     REMOVE_BACK_REF((*anOldIter));
   }
+  myExtDocRef->Clear();
   owner()->data()->sendAttributeUpdated(this);
 }
 
@@ -81,6 +135,33 @@ bool Model_AttributeRefList::isInitialized()
   return ModelAPI_AttributeRefList::isInitialized();
 }
 
+ObjectPtr Model_AttributeRefList::iteratedObject(TDF_ListIteratorOfLabelList& theLIter,
+    TDataStd_ListIteratorOfListOfExtendedString& theExtIter, 
+    std::shared_ptr<Model_Document> theDoc) const
+{
+  ObjectPtr anObj;
+  if (!theLIter.Value().IsNull() && !theLIter.Value().IsRoot()) {
+    if (theLIter.Value() == myRef->Label()) { // external document object
+      int anID = atoi(TCollection_AsciiString(theExtIter.Value()).ToCString());
+      theExtIter.Next();
+      DocumentPtr aRefDoc = Model_Application::getApplication()->document(anID);
+      if (aRefDoc.get()) {
+        std::shared_ptr<Model_Document> aDR = std::dynamic_pointer_cast<Model_Document>(aRefDoc);
+        TDF_Label aRefLab;
+        TDF_Tool::Label(aDR->objects()->featuresLabel().Data(),
+          TCollection_AsciiString(theExtIter.Value()).ToCString(), aRefLab);
+        if (!aRefLab.IsNull()) {
+          anObj = aDR->objects()->object(aRefLab);
+        }
+      }
+      theExtIter.Next();
+    } else { // internal document object
+      anObj = theDoc->objects()->object(theLIter.Value());
+    }
+  }
+  return anObj;
+}
+
 list<ObjectPtr> Model_AttributeRefList::list()
 {
   std::list<ObjectPtr> aResult;
@@ -88,11 +169,9 @@ list<ObjectPtr> Model_AttributeRefList::list()
       owner()->document());
   if (aDoc) {
     const TDF_LabelList& aList = myRef->List();
+    TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List());
     for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
-      ObjectPtr anObj;
-      if (!aLIter.Value().IsNull() && !aLIter.Value().IsRoot())
-        anObj = aDoc->objects()->object(aLIter.Value());
-      aResult.push_back(anObj);
+      aResult.push_back(iteratedObject(aLIter, anExtIter, aDoc));
     }
   }
   return aResult;
@@ -103,18 +182,39 @@ bool Model_AttributeRefList::isInList(const ObjectPtr& theObj)
   if(!theObj.get()) {
     return false;
   }
-  std::list<ObjectPtr> aResult;
-  std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
-      owner()->document());
-  if (aDoc) {
+  if (theObj->document() == owner()->document()) { // this document object
+    std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
+        owner()->document());
+    if (aDoc) {
+      std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObj->data());
+      if (aData.get() && aData->isValid()) {
+        TDF_Label anObjLab = aData->label().Father();
+        const TDF_LabelList& aList = myRef->List();
+        for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
+          if (aLIter.Value().IsEqual(anObjLab)) {
+            return true;
+          }
+        }
+      }
+    }
+  } else { // external document object
+    // create new lists because for the current moment remove one of the duplicated elements
+    // from the list is buggy
+    std::ostringstream anIdString; // string with document Id
+    anIdString<<theObj->document()->id();
     std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObj->data());
-    if (aData.get() && aData->isValid()) {
-      TDF_Label anObjLab = aData->label().Father();
-      const TDF_LabelList& aList = myRef->List();
-      for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
-        if (aLIter.Value().IsEqual(anObjLab)) {
+    TCollection_AsciiString anEntry;
+    TDF_Tool::Entry(aData->label().Father(), anEntry);
+    bool aFound = false;
+    TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List());
+    for (; anExtIter.More(); anExtIter.Next()) {
+      if (anExtIter.Value() == anIdString.str().c_str()) {
+        anExtIter.Next();
+        if (anExtIter.Value() == anEntry) { // fully maches
           return true;
         }
+      } else {
+        anExtIter.Next();
       }
     }
   }
@@ -123,19 +223,20 @@ bool Model_AttributeRefList::isInList(const ObjectPtr& theObj)
 
 ObjectPtr Model_AttributeRefList::object(const int theIndex, const bool theWithEmpty) const
 {
-  std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
-      owner()->document());
+  std::shared_ptr<Model_Document> aDoc = 
+    std::dynamic_pointer_cast<Model_Document>(owner()->document());
   if (aDoc) {
-    const TDF_LabelList& aList = myRef->List();
     int anIndex = -1;
-    for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
+    TDataStd_ListIteratorOfListOfExtendedString anExtIter(myExtDocRef->List());
+    for (TDF_ListIteratorOfLabelList aLIter(myRef->List()); aLIter.More(); aLIter.Next()) {
       if (theWithEmpty || (!aLIter.Value().IsNull() && !aLIter.Value().IsRoot()))
         anIndex++;
       if (anIndex == theIndex) {
-        if (aLIter.Value().IsNull() || aLIter.Value().IsRoot()) { // null label => null sub
-          return ObjectPtr();
-        }
-        return aDoc->objects()->object(aLIter.Value());
+        return iteratedObject(aLIter, anExtIter, aDoc);
+      }
+      if (aLIter.Value() == myRef->Label()) {
+        anExtIter.Next();
+        anExtIter.Next();
       }
     }
   }
@@ -246,4 +347,7 @@ Model_AttributeRefList::Model_AttributeRefList(TDF_Label& theLabel)
   if (!myIsInitialized) {
     myRef = TDataStd_ReferenceList::Set(theLabel);
   }
+  if (!theLabel.FindAttribute(TDataStd_ExtStringList::GetID(), myExtDocRef)) {
+    myExtDocRef = TDataStd_ExtStringList::Set(theLabel);
+  }
 }
index eaa1d92067a7fd8d384f1e09781290e694fdc67e..9f3df94af22df3f9d744041a7f69ae4b1701b082 100644 (file)
 #include "ModelAPI_Feature.h"
 
 #include <TDataStd_ReferenceList.hxx>
+#include <TDataStd_ExtStringList.hxx>
 
 /**\class Model_AttributeRefList
  * \ingroup DataModel
- * \brief Attribute that contains list of references to features (located in the same document).
- * For the current moment it does not support references to objects in other documents.
+ * \brief Attribute that contains list of references to features, may be located in different documents.
  */
 
 class Model_AttributeRefList : public ModelAPI_AttributeRefList
 {
   Handle_TDataStd_ReferenceList myRef;  ///< references to the features labels
+  /// pairs of doc ID and entries if reference is to external object, appends some in this list if
+  /// something in myRef is empty
+  Handle_TDataStd_ExtStringList myExtDocRef;
  public:
   /// Appends the feature to the end of a list
   MODEL_EXPORT virtual void append(ObjectPtr theObject);
@@ -48,15 +51,19 @@ class Model_AttributeRefList : public ModelAPI_AttributeRefList
   MODEL_EXPORT virtual ObjectPtr object(const int theIndex, const bool theWithEmpty = true) const;
 
   /// Substitutes the feature by another one. Does nothing if such object is not found.
+  /// Does not support the external documents objects yet.
   MODEL_EXPORT virtual void substitute(const ObjectPtr& theCurrent, const ObjectPtr& theNew);
 
   /// Substitutes the object by another one and back. So, features will become exchanged in the list
+  /// Does not support the external documents objects yet.
   MODEL_EXPORT virtual void exchange(const ObjectPtr& theObject1, const ObjectPtr& theObject2);
 
   /// Removes the last element in the list.
+  /// Does not support the external documents objects yet.
   MODEL_EXPORT virtual void removeLast();
 
   /// Removes the elements from the list.
+  /// Does not support the external documents objects yet.
   /// \param theIndices a list of indices of elements to be removed
   MODEL_EXPORT virtual void remove(const std::set<int>& theIndices);
 
@@ -65,6 +72,10 @@ class Model_AttributeRefList : public ModelAPI_AttributeRefList
  protected:
   /// Objects are created for features automatically
   MODEL_EXPORT Model_AttributeRefList(TDF_Label& theLabel);
+  /// Returns the object by iterators (theExtIter is iterated if necessary)
+  ObjectPtr iteratedObject(TDF_ListIteratorOfLabelList& theLIter,
+    TDataStd_ListIteratorOfListOfExtendedString& theExtIter,
+    std::shared_ptr<Model_Document> theDoc) const;
 
   friend class Model_Data;
 };
index 3d16c14bb0dfe7bc74b7ae13ac2f67bb67fa50e7..e9d808ade039cee5c7f934664bdfa7817b73b81e 100644 (file)
@@ -116,7 +116,7 @@ void Model_Data::setName(const std::string& theName)
 AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
 {
   AttributePtr aResult;
-  TDF_Label anAttrLab = myLab.FindChild(myAttrs.size() + 1);
+  TDF_Label anAttrLab = myLab.FindChild(int(myAttrs.size()) + 1);
   ModelAPI_Attribute* anAttr = 0;
   if (theAttrType == ModelAPI_AttributeDocRef::typeId()) {
     anAttr = new Model_AttributeDocRef(anAttrLab);
index 21823b4e05b73ba391dff15922d5fd5f5c77caab..7dd2b7366b197e1f327125bf8f360ad8ad4d1b82 100755 (executable)
@@ -975,6 +975,7 @@ void Model_Document::setCurrentFeature(
   bool aPassed = false; // flag that the current object is already passed in cycle
   FeaturePtr anIter = myObjs->lastFeature();
   bool aWasChanged = false;
+  bool isCurrentParameter = theCurrent.get() && theCurrent->getKind() == "Parameter";
   for(; anIter.get(); anIter = myObjs->nextFeature(anIter, true)) {
     // check this before passed become enabled: the current feature is enabled!
     if (anIter == theCurrent) aPassed = true;
@@ -988,9 +989,12 @@ void Model_Document::setCurrentFeature(
     }
 
     if (anIter->getKind() == "Parameter") {// parameters are always out of the history of features, but not parameters
-      if (theCurrent.get() && theCurrent->getKind() != "Parameter")
+      if (!isCurrentParameter)
         aDisabledFlag = false;
+    } else if (isCurrentParameter) { // if paramater is active, all other features become enabled (issue 1307)
+      aDisabledFlag = false;
     }
+
     if (anIter->setDisabled(aDisabledFlag)) {
       // state of feature is changed => so feature become updated
       static Events_ID anUpdateEvent = aLoop->eventByName(EVENT_OBJECT_UPDATED);
index dfd0a45145f49c416ab2688ae8513f0b9424a4f7..38549c395974cd4a9f1b3fabd76a1ebc3565d2c5 100644 (file)
@@ -33,7 +33,7 @@
 using namespace std;
 
 Model_Update MY_UPDATER_INSTANCE;  /// the only one instance initialized on load of the library
-#define DEB_UPDATE
+//#define DEB_UPDATE
 
 Model_Update::Model_Update()
 {
@@ -66,7 +66,9 @@ void Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
   }
   if (myModified.find(theFeature) != myModified.end()) {
     if (theReason.get()) {
+#ifdef DEB_UPDATE
       std::cout<<"*** Add already modified "<<theFeature->name()<<std::endl;
+#endif
       myModified[theFeature].insert(theReason);
     }
     return; // already is marked as modified, so, nothing to do, it will be processed
@@ -684,4 +686,3 @@ void Model_Update::updateStability(void* theSender)
     }
   }
 }
-
index 803ea9e43983c4b7403c967b18120636cb6bb364..953bb6c4053e60f01609d4ca1f2dd25e2383f3f5 100644 (file)
@@ -150,5 +150,5 @@ double ParametersPlugin_Parameter::evaluate(const std::string& theExpression, st
 
 bool ParametersPlugin_Parameter::isPreviewNeeded() const
 {
-  return false;
+  return true;
 }
index 4e19fd45576798996fb825f46ce746aab3d102d6..bf8a2b71d592723af75a079207ee72a39f8eec55 100644 (file)
@@ -200,7 +200,7 @@ reflistA.setAttr(aCircleCenter)
 reflistB.setObject(aSketchArc.lastResult())
 aConstraint.execute()
 aSession.finishOperation()
-#checkPointOnArc(aCircleCenter, aSketchArc)
+checkPointOnArc(aCircleCenter, aSketchArc)
 #=========================================================================
 # Check center of circle is still in origin
 #=========================================================================