Salome HOME
The parametric update of loaded documents: sketch solver problems fix
authormpv <mikhail.ponikarov@opencascade.com>
Fri, 7 Nov 2014 06:38:16 +0000 (09:38 +0300)
committermpv <mikhail.ponikarov@opencascade.com>
Fri, 7 Nov 2014 06:38:16 +0000 (09:38 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Update.cpp
src/SketchPlugin/SketchPlugin_Circle.cpp
src/SketchPlugin/SketchPlugin_Line.cpp
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchSolver/SketchSolver_ConstraintManager.cpp

index 8bb7c7809bce575ab456c856da75880378202186..15983188d822ba65cc920976f75a969a671d04f4 100644 (file)
@@ -737,9 +737,6 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t
       // event: model is updated
       static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
       ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
-
-      // update results of the appeared feature
-      updateResults(aFeature);
     } else {  // nothing is changed, both iterators are incremented
       aFeature = myObjs.Find(aFeatureLabel);
       aKeptFeatures.insert(aFeature);
@@ -747,9 +744,18 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t
         static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
         ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
       }
+    }
+  }
+  // update results of thefeatures (after features created because they may be connected, like sketch and sub elements)
+  TDF_ChildIDIterator aLabIter2(featuresLabel(), TDataStd_Comment::GetID());
+  for (; aLabIter2.More(); aLabIter2.Next()) {
+    TDF_Label aFeatureLabel = aLabIter2.Value()->Label();
+    if (myObjs.IsBound(aFeatureLabel)) {  // a new feature is inserted
+      FeaturePtr aFeature = myObjs.Find(aFeatureLabel);
       updateResults(aFeature);
     }
   }
+
   // check all features are checked: if not => it was removed
   NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFIter(myObjs);
   while (aFIter.More()) {
@@ -957,11 +963,11 @@ boost::shared_ptr<ModelAPI_Feature> Model_Document::feature(
 void Model_Document::updateResults(FeaturePtr theFeature)
 {
   // for not persistent is will be done by parametric updater automatically
-  if (!theFeature->isPersistentResult()) return;
+  //if (!theFeature->isPersistentResult()) return;
   // check the existing results and remove them if there is nothing on the label
   std::list<ResultPtr>::const_iterator aResIter = theFeature->results().cbegin();
   while(aResIter != theFeature->results().cend()) {
-    ResultBodyPtr aBody = boost::dynamic_pointer_cast<ModelAPI_ResultBody>(*aResIter);
+    ResultPtr aBody = boost::dynamic_pointer_cast<ModelAPI_Result>(*aResIter);
     if (aBody) {
       if (!aBody->data()->isValid()) { 
         // found a disappeared result => remove it
@@ -988,8 +994,12 @@ void Model_Document::updateResults(FeaturePtr theFeature)
           aNewBody = createBody(theFeature->data(), aResIndex);
         } else if (aGroup->Get() == ModelAPI_ResultPart::group().c_str()) {
           aNewBody = createPart(theFeature->data(), aResIndex);
-        } else if (aGroup->Get() != ModelAPI_ResultConstruction::group().c_str() &&
-          aGroup->Get() != ModelAPI_ResultGroup::group().c_str()) {
+        } else if (aGroup->Get() == ModelAPI_ResultConstruction::group().c_str()) {
+          theFeature->execute(); // construction shapes are needed for sketch solver
+          break;
+        } else if (aGroup->Get() == ModelAPI_ResultGroup::group().c_str()) {
+          aNewBody = createGroup(theFeature->data(), aResIndex);
+        } else {
           Events_Error::send(std::string("Unknown type of result is found in the document:") +
             TCollection_AsciiString(aGroup->Get()).ToCString());
         }
index b6a4a9553860f80e52cb95204d788390132c45a0..676e3ba2c0ba4dcbb66424c13bf8a171154a9437 100644 (file)
@@ -38,6 +38,8 @@ Model_Update::Model_Update()
   aLoop->registerListener(this, kCreatedEvent);
   static const Events_ID kUpdatedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
   aLoop->registerListener(this, kUpdatedEvent);
+  static const Events_ID kMovedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED);
+  aLoop->registerListener(this, kMovedEvent);
   static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation");
   aLoop->registerListener(this, kOpFinishEvent);
   static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation");
@@ -57,6 +59,7 @@ void Model_Update::processEvent(const boost::shared_ptr<Events_Message>& theMess
   static const Events_ID kRebuildEvent = aLoop->eventByName("Rebuild");
   static const Events_ID kCreatedEvent = aLoop->eventByName(EVENT_OBJECT_CREATED);
   static const Events_ID kUpdatedEvent = aLoop->eventByName(EVENT_OBJECT_UPDATED);
+  static const Events_ID kMovedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED);
   static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation");
   static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation");
   static const Events_ID kOpStartEvent = aLoop->eventByName("StartOperation");
@@ -69,7 +72,8 @@ void Model_Update::processEvent(const boost::shared_ptr<Events_Message>& theMess
       isAutomaticChanged = true;
       isAutomatic = true;
     }
-  } else if (theMessage->eventID() == kCreatedEvent || theMessage->eventID() == kUpdatedEvent) {
+  } else if (theMessage->eventID() == kCreatedEvent || theMessage->eventID() == kUpdatedEvent ||
+    theMessage->eventID() == kMovedEvent) {
     boost::shared_ptr<ModelAPI_ObjectUpdatedMessage> aMsg =
         boost::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
     const std::set<ObjectPtr>& anObjs = aMsg->objects();
@@ -77,6 +81,8 @@ void Model_Update::processEvent(const boost::shared_ptr<Events_Message>& theMess
     for(; anObjIter != anObjs.cend(); anObjIter++) {
       myJustCreatedOrUpdated.insert(*anObjIter);
     }
+    if (theMessage->eventID() == kMovedEvent)
+      return; // this event is for solver update, not here
   } else if (theMessage->eventID() == kOpStartEvent) {
     myJustCreatedOrUpdated.clear();
     return; // we don't need the update only on operation start (caused problems in PartSet_Listener::processEvent)
index 06ab76d14be74af9e3e6e017afddb8f246776782..3669232cba85ab5d0829c37752865116a8e1e57d 100644 (file)
@@ -102,7 +102,8 @@ bool SketchPlugin_Circle::isFixed() {
 void SketchPlugin_Circle::attributeChanged() {
   static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change
   boost::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
-  if (aSelection && !myIsUpdated) { // update arguments due to the selection value
+  // update arguments due to the selection value
+  if (aSelection && !aSelection->isNull() && aSelection->isEdge() && !myIsUpdated) {
     myIsUpdated = true;
     boost::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
     boost::shared_ptr<GeomAPI_Circ> aCirc = anEdge->circle();
index 95b6de896acd8644ace08a86a29f8a48e17f047b..22a4668158244b4d72ae5c7f2138883b02ea4353 100644 (file)
@@ -101,7 +101,7 @@ void SketchPlugin_Line::attributeChanged() {
   static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change
   boost::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
    // update arguments due to the selection value
-  if (aSelection && !aSelection->isNull() && !myIsUpdated) {
+  if (aSelection && !aSelection->isNull() && aSelection->isEdge() && !myIsUpdated) {
     myIsUpdated = true;
     boost::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
     boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr = 
index 2b45cb65a45458a6bbb61f182e10b2fee5c92a31..813ce28fb3bc5a0a8bce780917d4895cb97eab26 100644 (file)
@@ -78,6 +78,8 @@ void SketchPlugin_Sketch::execute()
   for (; anIt != aLast; anIt++) {
     aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
     if (aFeature) {
+      if (!aFeature->sketch()) // on load document the back references are missed
+        aFeature->setSketch(this);
       // do not include the external edges into the result
       if (aFeature->data()->attribute(SketchPlugin_Feature::EXTERNAL_ID())) {
         if (aFeature->data()->selection(SketchPlugin_Feature::EXTERNAL_ID())->value())
index 1dec2867f7ee2b098386b0f51ffcf5a82c12353f..d308e99d0b7bc3e56da28fe832498b0884541e75 100644 (file)
@@ -63,8 +63,8 @@ SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager()
 void SketchSolver_ConstraintManager::processEvent(
   const boost::shared_ptr<Events_Message>& theMessage)
 {
-  if (myIsComputed)
-    return;
+  //if (myIsComputed)
+  //  return;
   if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)
       || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)
       || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) {
@@ -84,24 +84,25 @@ void SketchSolver_ConstraintManager::processEvent(
       }
     } else {
       std::set<ObjectPtr>::iterator aFeatIter;
+      // iterate sketchers fisrt to create all sketches before (on load may exist several sketches)
       for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
         FeaturePtr aFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(*aFeatIter);
         if (!aFeature)
           continue;
-        // Only sketches and constraints can be added by Create event
         const std::string& aFeatureKind = aFeature->getKind();
         if (aFeatureKind.compare(SketchPlugin_Sketch::ID()) == 0) {
           boost::shared_ptr<ModelAPI_CompositeFeature> aSketch = boost::dynamic_pointer_cast<
               ModelAPI_CompositeFeature>(aFeature);
-          if (aSketch)
-            changeWorkplane(aSketch);
-          continue;
+          changeWorkplane(aSketch);
         }
-        // Sketch plugin features can be only updated
-        boost::shared_ptr<SketchPlugin_Feature> aSFeature = boost::dynamic_pointer_cast<
-            SketchPlugin_Feature>(aFeature);
-        if (aSFeature)
-          changeConstraintOrEntity(aSFeature);
+      }
+      // then get anything but not the sketch
+      for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
+        boost::shared_ptr<SketchPlugin_Feature> aFeature = 
+          boost::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
+        if (!aFeature)
+          continue;
+          changeConstraintOrEntity(aFeature);
       }
     }