]> SALOME platform Git repositories - modules/shaper.git/blobdiff - src/SketchSolver/SketchSolver_Group.cpp
Salome HOME
Add tools
[modules/shaper.git] / src / SketchSolver / SketchSolver_Group.cpp
index 0e4093ffa71f3e8501b1463f6ee6383ea819c6aa..cc60f0c2555e6479934dcbb1b65086b31313bbbf 100644 (file)
@@ -9,6 +9,7 @@
 #include <SketchSolver_Builder.h>
 #include <SketchSolver_Constraint.h>
 #include <SketchSolver_ConstraintCoincidence.h>
+#include <SketchSolver_ConstraintMulti.h>
 #include <SketchSolver_Error.h>
 
 #include <Events_Error.h>
@@ -147,11 +148,12 @@ Slvs_hEntity SketchSolver_Group::getFeatureId(FeaturePtr theFeature) const
   Slvs_hEntity aResult = SLVS_E_UNKNOWN;
   if (!myFeatureStorage)
     return aResult;
+  // Obtain regular constraints interacting with the feature and find its ID
   std::set<ConstraintPtr> aConstraints = myFeatureStorage->getConstraints(theFeature);
   if (aConstraints.empty())
     return aResult;
   std::set<ConstraintPtr>::iterator aConstrIter = aConstraints.begin();
-  for (; aConstrIter != aConstraints.end(); aConstrIter++) {
+  for (; aConstrIter != aConstraints.end(); ++aConstrIter) {
     ConstraintConstraintMap::const_iterator aCIter = myConstraints.find(*aConstrIter);
     if (aCIter == myConstraints.end())
       continue;
@@ -159,7 +161,11 @@ Slvs_hEntity SketchSolver_Group::getFeatureId(FeaturePtr theFeature) const
     if (aResult != SLVS_E_UNKNOWN)
       return aResult;
   }
-  return SLVS_E_UNKNOWN;
+  // The feature is not found, check it in the temporary constraints
+  std::set<SolverConstraintPtr>::iterator aTmpCIter = myTempConstraints.begin();
+  for (; aTmpCIter != myTempConstraints.end() && aResult == SLVS_E_UNKNOWN; ++aTmpCIter)
+    aResult = (*aTmpCIter)->getId(theFeature);
+  return aResult;
 }
 
 // ============================================================================
@@ -172,9 +178,8 @@ Slvs_hEntity SketchSolver_Group::getAttributeId(AttributePtr theAttribute) const
   Slvs_hEntity aResult = SLVS_E_UNKNOWN;
   if (!myFeatureStorage)
     return aResult;
+  // Obtain regular constraints interacting with the attribute and find its ID
   std::set<ConstraintPtr> aConstraints = myFeatureStorage->getConstraints(theAttribute);
-  if (aConstraints.empty())
-    return aResult;
   std::set<ConstraintPtr>::iterator aConstrIter = aConstraints.begin();
   for (; aConstrIter != aConstraints.end(); aConstrIter++) {
     ConstraintConstraintMap::const_iterator aCIter = myConstraints.find(*aConstrIter);
@@ -184,7 +189,16 @@ Slvs_hEntity SketchSolver_Group::getAttributeId(AttributePtr theAttribute) const
     if (aResult != SLVS_E_UNKNOWN)
       return aResult;
   }
-  return SLVS_E_UNKNOWN;
+  // The attribute is not found, check it in the temporary constraints
+  std::set<SolverConstraintPtr>::const_iterator aTmpCIter = myTempConstraints.begin();
+  for (; aTmpCIter != myTempConstraints.end() && aResult == SLVS_E_UNKNOWN; ++aTmpCIter)
+    aResult = (*aTmpCIter)->getId(theAttribute);
+  // Last chance to find attribute in parametric constraints
+  std::map<AttributePtr, SolverConstraintPtr>::const_iterator aParIter =
+      myParametricConstraints.find(theAttribute);
+  if (aParIter != myParametricConstraints.end())
+    aResult = aParIter->second->getId(theAttribute);
+  return aResult;
 }
 
 // ============================================================================
@@ -199,7 +213,7 @@ bool SketchSolver_Group::changeConstraint(
   if (myWorkplaneID == SLVS_E_UNKNOWN)
     return false;
 
-  if (!theConstraint)
+  if (!theConstraint || !theConstraint->data())
     return false;
 
   if (!checkFeatureValidity(theConstraint))
@@ -222,8 +236,9 @@ bool SketchSolver_Group::changeConstraint(
 
     // Additional verification of coincidence of several points
     if (theConstraint->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+      bool hasMultiCoincidence = false;
       ConstraintConstraintMap::iterator aCIter = myConstraints.begin();
-      for (; aCIter != myConstraints.end(); aCIter++) {
+      for (; aCIter != myConstraints.end(); ++aCIter) {
         std::shared_ptr<SketchSolver_ConstraintCoincidence> aCoincidence =
           std::dynamic_pointer_cast<SketchSolver_ConstraintCoincidence>(aCIter->second);
         if (!aCoincidence)
@@ -238,8 +253,12 @@ bool SketchSolver_Group::changeConstraint(
             if (anIt->second == aCIter->second)
               anIt->second = aCoinc2;
           aCIter->second = aCoinc2;
+          hasMultiCoincidence = true;
         }
       }
+
+      if (hasMultiCoincidence)
+        notifyMultiConstraints();
     }
     myConstraints[theConstraint] = aConstraint;
   }
@@ -288,6 +307,34 @@ bool SketchSolver_Group::changeConstraint(
     myFeatureStorage = FeatureStoragePtr(new SketchSolver_FeatureStorage);
   myFeatureStorage->changeConstraint(theConstraint);
 
+  // Check the attributes of constraint are given by parametric expression
+  std::list<AttributePtr> anAttributes =
+      theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+  std::list<AttributePtr>::iterator anAttrIt = anAttributes.begin();
+  for (; anAttrIt != anAttributes.end(); ++anAttrIt) {
+    AttributeRefAttrPtr aRefAttr =
+        std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIt);
+    if (!aRefAttr || aRefAttr->isObject())
+      continue;
+    std::shared_ptr<GeomDataAPI_Point2D> aPoint =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
+    if (!aPoint || (aPoint->textX().empty() && aPoint->textY().empty()))
+      continue;
+
+    std::map<AttributePtr, SolverConstraintPtr>::iterator aFound =
+        myParametricConstraints.find(aRefAttr->attr());
+    if (aFound == myParametricConstraints.end()) {
+      SolverConstraintPtr aConstraint =
+          SketchSolver_Builder::getInstance()->createParametricConstraint(aRefAttr->attr());
+      if (!aConstraint)
+        continue;
+      aConstraint->setGroup(this);
+      aConstraint->setStorage(myStorage);
+      myParametricConstraints[aRefAttr->attr()] = aConstraint;
+    } else
+      aFound->second->update();
+  }
+
   return true;
 }
 
@@ -335,6 +382,31 @@ bool SketchSolver_Group::updateFeature(std::shared_ptr<SketchPlugin_Feature> the
     aSolConIter->second->addFeature(theFeature);
     myChangedConstraints.insert(aSolConIter->first);
   }
+
+  // Search attributes of the feature in the set of parametric constraints and update them
+  std::list<AttributePtr> anAttrList =
+      theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+  std::list<AttributePtr>::iterator anAttrIt = anAttrList.begin();
+  for (; anAttrIt != anAttrList.end(); ++anAttrIt) {
+    std::map<AttributePtr, SolverConstraintPtr>::iterator aFound =
+        myParametricConstraints.find(*anAttrIt);
+    if (aFound != myParametricConstraints.end())
+      aFound->second->update();
+    else {
+      std::shared_ptr<GeomDataAPI_Point2D> aPoint =
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anAttrIt);
+      if (aPoint && (!aPoint->textX().empty() || !aPoint->textY().empty())) {
+        // Create new parametric constraint
+        SolverConstraintPtr aConstraint =
+            SketchSolver_Builder::getInstance()->createParametricConstraint(*anAttrIt);
+        if (!aConstraint)
+          continue;
+        aConstraint->setGroup(this);
+        aConstraint->setStorage(myStorage);
+        myParametricConstraints[*anAttrIt] = aConstraint;
+      }
+    }
+  }
   return true;
 }
 
@@ -477,6 +549,7 @@ bool SketchSolver_Group::resolveConstraints()
   bool aResolved = false;
   if (myStorage->isNeedToResolve() && !isEmpty()) {
     myConstrSolver.setGroupID(myID);
+    myConstrSolver.calculateFailedConstraints(false);
     myStorage->initializeSolver(myConstrSolver);
 
     int aResult = SLVS_RESULT_OKAY;
@@ -500,6 +573,7 @@ bool SketchSolver_Group::resolveConstraints()
             isLastChance = true;
           } else
             aNbTemp = myStorage->deleteTemporaryConstraint();
+          myConstrSolver.calculateFailedConstraints(true); // something failed => need to find it
           myStorage->initializeSolver(myConstrSolver);
         }
       }
@@ -515,8 +589,13 @@ bool SketchSolver_Group::resolveConstraints()
     }
     if (aResult == SLVS_RESULT_OKAY) {  // solution succeeded, store results into correspondent attributes
       myFeatureStorage->blockEvents(true);
+      // First refresh parametric constraints to satisfy parameters
+      std::map<AttributePtr, SolverConstraintPtr>::iterator aParIter = myParametricConstraints.begin();
+      for (; aParIter != myParametricConstraints.end(); ++aParIter)
+        aParIter->second->refresh();
+      // Update all other constraints
       ConstraintConstraintMap::iterator aConstrIter = myConstraints.begin();
-      for (; aConstrIter != myConstraints.end(); aConstrIter++)
+      for (; aConstrIter != myConstraints.end(); ++aConstrIter)
         aConstrIter->second->refresh();
       myFeatureStorage->blockEvents(false);
       if (!myPrevSolved) {
@@ -657,7 +736,11 @@ bool SketchSolver_Group::isConsistent()
 // ============================================================================
 void SketchSolver_Group::removeTemporaryConstraints()
 {
+  std::set<SolverConstraintPtr>::iterator aTmpIt = myTempConstraints.begin();
+  for (; aTmpIt != myTempConstraints.end(); ++aTmpIt)
+    (*aTmpIt)->remove();
   myTempConstraints.clear();
+
   while (myStorage->numberTemporary())
     myStorage->deleteTemporaryConstraint();
   // Clean lists of removed entities in the storage
@@ -709,6 +792,8 @@ void SketchSolver_Group::removeConstraint(ConstraintPtr theConstraint)
     std::list<ConstraintPtr>::iterator anIt = aMultiCoinc.begin();
     for (; anIt != aMultiCoinc.end(); ++anIt)
       changeConstraint(*anIt);
+
+    notifyMultiConstraints();
   }
 }
 
@@ -751,6 +836,23 @@ bool SketchSolver_Group::checkFeatureValidity(FeaturePtr theFeature)
   return aFactory->validate(theFeature);
 }
 
+// ============================================================================
+//  Function: notifyMultiConstraints
+//  Class:    SketchSolver_Group
+//  Purpose:  Update Multi-Translation/-Rotation constraints due to multi coincidence appears/disappears
+// ============================================================================
+void SketchSolver_Group::notifyMultiConstraints()
+{
+  ConstraintConstraintMap::iterator aCIter = myConstraints.begin();
+  for (; aCIter != myConstraints.end(); ++aCIter) {
+    if (aCIter->first->getKind() == SketchPlugin_MultiRotation::ID() ||
+        aCIter->first->getKind() == SketchPlugin_MultiTranslation::ID()) {
+      std::shared_ptr<SketchSolver_ConstraintMulti> aMulti = 
+          std::dynamic_pointer_cast<SketchSolver_ConstraintMulti>(aCIter->second);
+      aMulti->checkCoincidence();
+    }
+  }
+}