Salome HOME
Adaptation to a new ModelAPI architecture
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintManager.cpp
index 1933745bec3c1c3224d778d53401ea36c3de3aee..a3136681381719388cc90fbc4aacaabab7945fd6 100644 (file)
@@ -8,7 +8,7 @@
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_Data.h>
-#include <Model_Events.h>
+#include <ModelAPI_Events.h>
 
 #include <SketchPlugin_Constraint.h>
 
@@ -41,10 +41,10 @@ SketchSolver_ConstraintManager::SketchSolver_ConstraintManager()
   myGroups.clear();
 
   // Register in event loop
-  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED));
-  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
-  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED));
-  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_MOVED));
+  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+  Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_MOVED));
 }
 
 SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager()
@@ -59,40 +59,44 @@ SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager()
 // ============================================================================
 void SketchSolver_ConstraintManager::processEvent(const Events_Message* theMessage)
 {
-  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED) ||
-      theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED) || 
-      theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_MOVED))
+  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))
   {
-    const Model_FeatureUpdatedMessage* anUpdateMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
-    std::set< boost::shared_ptr<ModelAPI_Feature> > aFeatures = anUpdateMsg->features();
+    const ModelAPI_ObjectUpdatedMessage* anUpdateMsg = 
+      dynamic_cast<const ModelAPI_ObjectUpdatedMessage*>(theMessage);
+    std::set< ObjectPtr > aFeatures = anUpdateMsg->objects();
 
-    bool isModifiedEvt = theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_MOVED);
+    bool isModifiedEvt = 
+      theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED);
     if (!isModifiedEvt)
     {
-      std::set< boost::shared_ptr<ModelAPI_Feature> >::iterator aFeatIter;
+      std::set< ObjectPtr >::iterator aFeatIter;
       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 = (*aFeatIter)->getKind();
-        if (aFeatureKind.compare("Sketch") == 0)
+        const std::string& aFeatureKind = aFeature->getKind();
+        if (aFeatureKind.compare(SKETCH_KIND) == 0)
         {
           boost::shared_ptr<SketchPlugin_Feature> aSketch =
-            boost::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
+            boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
           if (aSketch)
             changeWorkplane(aSketch);
           continue;
         }
         boost::shared_ptr<SketchPlugin_Constraint> aConstraint =
-          boost::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFeatIter);
+          boost::dynamic_pointer_cast<SketchPlugin_Constraint>(aFeature);
         if (aConstraint)
           changeConstraint(aConstraint);
         else
         {
           // Sketch plugin features can be only updated
-          boost::shared_ptr<SketchPlugin_Feature> aFeature =
-            boost::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
-          if (aFeature)
-            updateEntity(aFeature);
+          boost::shared_ptr<SketchPlugin_Feature> aSFeature =
+            boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+          if (aSFeature)
+            updateEntity(aSFeature);
         }
       }
     }
@@ -100,31 +104,40 @@ void SketchSolver_ConstraintManager::processEvent(const Events_Message* theMessa
     // Solve the set of constraints
     resolveConstraints();
   }
-  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED))
+  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED))
   {
-    const Model_FeatureDeletedMessage* aDeleteMsg = dynamic_cast<const Model_FeatureDeletedMessage*>(theMessage);
+    const ModelAPI_ObjectDeletedMessage* aDeleteMsg = 
+      dynamic_cast<const ModelAPI_ObjectDeletedMessage*>(theMessage);
     const std::set<std::string>& aFeatureGroups = aDeleteMsg->groups();
 
-    // Find "Sketch" in groups. The constraint groups should be updated when an object removed from Sketch
+    // Find SKETCH_KIND in groups. The constraint groups should be updated when an object removed from Sketch
     std::set<std::string>::const_iterator aFGrIter;
     for (aFGrIter = aFeatureGroups.begin(); aFGrIter != aFeatureGroups.end(); aFGrIter++)
-      if (aFGrIter->compare("Sketch") == 0)
+      if (aFGrIter->compare(SKETCH_KIND) == 0)
         break;
     
     if (aFGrIter != aFeatureGroups.end())
     {
       std::vector<SketchSolver_ConstraintGroup*>::iterator aGroupIter = myGroups.begin();
+      std::vector<SketchSolver_ConstraintGroup*> aSeparatedGroups;
       while (aGroupIter != myGroups.end())
       {
-        if ((*aGroupIter)->updateGroup())
+        if (!(*aGroupIter)->isWorkplaneValid())
         { // the group should be removed
           delete *aGroupIter;
           int aShift = aGroupIter - myGroups.begin();
           myGroups.erase(aGroupIter);
           aGroupIter = myGroups.begin() + aShift;
+          continue;
+        }
+        if ((*aGroupIter)->updateGroup())
+        { // some constraints were removed, try to split the group
+          (*aGroupIter)->splitGroup(aSeparatedGroups);
         }
-        else aGroupIter++;
+        aGroupIter++;
       }
+      if (aSeparatedGroups.size() > 0)
+        myGroups.insert(myGroups.end(), aSeparatedGroups.begin(), aSeparatedGroups.end());
     }
   }
 }
@@ -248,22 +261,22 @@ void SketchSolver_ConstraintManager::updateEntity(boost::shared_ptr<SketchPlugin
   std::vector<std::string> anAttrList;
   const std::string& aFeatureKind = theFeature->getKind();
   // Point
-  if (aFeatureKind.compare("SketchPoint") == 0)
+  if (aFeatureKind.compare(SKETCH_POINT_KIND) == 0)
     anAttrList.push_back(POINT_ATTR_COORD);
   // Line
-  else if (aFeatureKind.compare("SketchLine") == 0)
+  else if (aFeatureKind.compare(SKETCH_LINE_KIND) == 0)
   {
     anAttrList.push_back(LINE_ATTR_START);
     anAttrList.push_back(LINE_ATTR_END);
   }
   // Circle
-  else if (aFeatureKind.compare("SketchCircle") == 0)
+  else if (aFeatureKind.compare(SKETCH_CIRCLE_KIND) == 0)
   {
     anAttrList.push_back(CIRCLE_ATTR_CENTER);
     anAttrList.push_back(CIRCLE_ATTR_RADIUS);
   }
   // Arc
-  else if (aFeatureKind.compare("SketchArc") == 0)
+  else if (aFeatureKind.compare(SKETCH_ARC_KIND) == 0)
   {
     anAttrList.push_back(ARC_ATTR_CENTER);
     anAttrList.push_back(ARC_ATTR_START);
@@ -278,11 +291,18 @@ void SketchSolver_ConstraintManager::updateEntity(boost::shared_ptr<SketchPlugin
     std::vector<SketchSolver_ConstraintGroup*>::iterator aGroupIter;
     for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
     {
+      if ((*aGroupIter)->isEmpty()) 
+        continue;
       boost::shared_ptr<ModelAPI_Attribute> anAttribute =
         boost::dynamic_pointer_cast<ModelAPI_Attribute>(theFeature->data()->attribute(*anAttrIter));
       (*aGroupIter)->updateEntityIfPossible(anAttribute);
     }
   }
+
+  std::vector<SketchSolver_ConstraintGroup*>::iterator aGroupIter;
+  for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
+    if (!(*aGroupIter)->isEmpty())
+      (*aGroupIter)->updateRelatedConstraints(theFeature);
 }
 
 
@@ -333,8 +353,8 @@ boost::shared_ptr<SketchPlugin_Feature> SketchSolver_ConstraintManager::findWork
 
     boost::shared_ptr<ModelAPI_AttributeRefList> aWPFeatures =
       boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aWP->data()->attribute(SKETCH_ATTR_FEATURES));
-    std::list< boost::shared_ptr<ModelAPI_Feature> > aFeaturesList = aWPFeatures->list();
-    std::list< boost::shared_ptr<ModelAPI_Feature> >::const_iterator anIter;
+    std::list< ObjectPtr >& aFeaturesList = aWPFeatures->list();
+    std::list< ObjectPtr >::const_iterator anIter;
     for (anIter = aFeaturesList.begin(); anIter != aFeaturesList.end(); anIter++)
       if (*anIter == theConstraint)
         return aWP; // workplane is found
@@ -356,6 +376,6 @@ void SketchSolver_ConstraintManager::resolveConstraints()
     (*aGroupIter)->resolveConstraints();
 
   // Features may be updated => send events
-  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
+  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
 }