Salome HOME
#878 Segmentation fault when setting distance on the two same points
[modules/shaper.git] / src / SketchSolver / SketchSolver_Group.cpp
index 08f594fe7dc90af4776ea05c7e68de734c64815c..9371607d2d6511b13336b394ea32ed078e7a237c 100644 (file)
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
 
 #include <SketchPlugin_Constraint.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintEqual.h>
 #include <SketchPlugin_ConstraintFillet.h>
 #include <SketchPlugin_ConstraintLength.h>
-#include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintMirror.h>
 #include <SketchPlugin_ConstraintRigid.h>
 #include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_Feature.h>
 #include <SketchPlugin_MultiRotation.h>
 #include <SketchPlugin_MultiTranslation.h>
+#include <SketchPlugin_Sketch.h>
 
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_Circle.h>
@@ -67,6 +71,14 @@ private:
 Slvs_hGroup GroupIndexer::myGroupIndex = 0;
 
 
+static void sendMessage(const char* theMessageName)
+{
+  std::shared_ptr<Events_Message> aMessage = std::shared_ptr<Events_Message>(
+      new Events_Message(Events_Loop::eventByName(theMessageName)));
+  Events_Loop::loop()->send(aMessage);
+}
+
+
 
 // ========================================================
 // =========  SketchSolver_Group  ===============
@@ -74,7 +86,8 @@ Slvs_hGroup GroupIndexer::myGroupIndex = 0;
 
 SketchSolver_Group::SketchSolver_Group(
     std::shared_ptr<ModelAPI_CompositeFeature> theWorkplane)
-    : myID(GroupIndexer::NEW_GROUP())
+    : myID(GroupIndexer::NEW_GROUP()),
+      myPrevSolved(true)
 {
   // Initialize workplane
   myWorkplaneID = SLVS_E_UNKNOWN;
@@ -182,6 +195,9 @@ bool SketchSolver_Group::changeConstraint(
   if (!theConstraint)
     return false;
 
+  if (!checkFeatureValidity(theConstraint))
+    return false;
+
   bool isNewConstraint = myConstraints.find(theConstraint) == myConstraints.end();
   if (isNewConstraint) {
     // Add constraint to the current group
@@ -269,14 +285,39 @@ bool SketchSolver_Group::changeConstraint(
 }
 
 
+void SketchSolver_Group::updateConstraints()
+{
+  std::set<SolverConstraintPtr> aPostponed; // postponed constraints Multi-Rotation and Multi-Translation
+
+  ConstraintConstraintMap::iterator anIt = myConstraints.begin();
+  for (; anIt != myConstraints.end(); ++anIt) {
+    if (myChangedConstraints.find(anIt->first) == myChangedConstraints.end())
+      continue;
+    if (anIt->first->getKind() == SketchPlugin_MultiRotation::ID() ||
+        anIt->first->getKind() == SketchPlugin_MultiTranslation::ID())
+      aPostponed.insert(anIt->second);
+    else
+      anIt->second->update();
+  }
+
+  // Update postponed constraints
+  std::set<SolverConstraintPtr>::iterator aSCIter = aPostponed.begin();
+  for (; aSCIter != aPostponed.end(); ++aSCIter)
+    (*aSCIter)->update();
+
+  myChangedConstraints.clear();
+}
+
 bool SketchSolver_Group::updateFeature(std::shared_ptr<SketchPlugin_Feature> theFeature)
 {
+  if (!checkFeatureValidity(theFeature))
+    return false;
+
   std::set<ConstraintPtr> aConstraints =
       myFeatureStorage->getConstraints(std::dynamic_pointer_cast<ModelAPI_Feature>(theFeature));
   if (aConstraints.empty())
     return false;
   std::set<ConstraintPtr>::iterator aCIter = aConstraints.begin();
-  std::set<SolverConstraintPtr> aPostponed; // postponed constraints Multi-Rotation and Multi-Translation
   for (; aCIter != aConstraints.end(); aCIter++) {
     ConstraintConstraintMap::iterator aSolConIter = myConstraints.find(*aCIter);
     if (aSolConIter == myConstraints.end() || !aSolConIter->first->data() ||
@@ -284,20 +325,8 @@ bool SketchSolver_Group::updateFeature(std::shared_ptr<SketchPlugin_Feature> the
       continue;
     myFeatureStorage->changeFeature(theFeature, aSolConIter->first);
 
-    if (aSolConIter->first->getKind() == SketchPlugin_MultiRotation::ID() ||
-        aSolConIter->first->getKind() == SketchPlugin_MultiTranslation::ID()) {
-      aPostponed.insert(aSolConIter->second);
-      continue;
-    }
     aSolConIter->second->addFeature(theFeature);
-    aSolConIter->second->update();
-  }
-
-  // Update postponed constraints
-  std::set<SolverConstraintPtr>::iterator aSCIter = aPostponed.begin();
-  for (; aSCIter != aPostponed.end(); ++aSCIter) {
-    (*aSCIter)->addFeature(theFeature);
-    (*aSCIter)->update();
+    myChangedConstraints.insert(aSolConIter->first);
   }
   return true;
 }
@@ -435,6 +464,9 @@ bool SketchSolver_Group::updateWorkplane()
 // ============================================================================
 bool SketchSolver_Group::resolveConstraints()
 {
+  if (!myChangedConstraints.empty())
+    updateConstraints();
+
   bool aResolved = false;
   if (myStorage->isNeedToResolve() && !isEmpty()) {
     myConstrSolver.setGroupID(myID);
@@ -465,7 +497,12 @@ bool SketchSolver_Group::resolveConstraints()
         }
       }
     } catch (...) {
-      Events_Error::send(SketchSolver_Error::SOLVESPACE_CRASH(), this);
+//      Events_Error::send(SketchSolver_Error::SOLVESPACE_CRASH(), this);
+      if (myPrevSolved) {
+        sendMessage(EVENT_SOLVER_FAILED);
+        myPrevSolved = false;
+      }
+      getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::SOLVESPACE_CRASH());
       return false;
     }
     if (aResult == SLVS_RESULT_OKAY) {  // solution succeeded, store results into correspondent attributes
@@ -474,8 +511,19 @@ bool SketchSolver_Group::resolveConstraints()
       for (; aConstrIter != myConstraints.end(); aConstrIter++)
         aConstrIter->second->refresh();
       myFeatureStorage->blockEvents(false);
-    } else if (!myConstraints.empty())
-      Events_Error::send(SketchSolver_Error::CONSTRAINTS(), this);
+      if (!myPrevSolved) {
+        sendMessage(EVENT_SOLVER_REPAIRED);
+        myPrevSolved = true;
+      }
+      getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue("");
+    } else if (!myConstraints.empty()) {
+//      Events_Error::send(SketchSolver_Error::CONSTRAINTS(), this);
+      if (myPrevSolved) {
+        sendMessage(EVENT_SOLVER_FAILED);
+        myPrevSolved = false;
+      }
+      getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS());
+    }
 
     aResolved = true;
   }
@@ -676,3 +724,19 @@ void SketchSolver_Group::setTemporary(SolverConstraintPtr theConstraint)
   myTempConstraints.insert(theConstraint);
 }
 
+
+// ============================================================================
+//  Function: checkFeatureValidity
+//  Class:    SketchSolver_Group
+//  Purpose:  verifies is the feature valid
+// ============================================================================
+bool SketchSolver_Group::checkFeatureValidity(FeaturePtr theFeature)
+{
+  if (!theFeature || !theFeature->data()->isValid())
+    return true;
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+  return aFactory->validate(theFeature);
+}
+