Salome HOME
Issue #463: Fillet constraint - closed line is destroyed
[modules/shaper.git] / src / SketchSolver / SketchSolver_Constraint.cpp
index b86ce1a28073d4caa0cecf85827bc7e4b4b517b8..4db4c4636bfcfa54936257b11bda9c9c28841d63 100644 (file)
@@ -33,10 +33,16 @@ SketchSolver_Constraint::~SketchSolver_Constraint()
     myStorage->removeEntity(anIt2->second);
   myAttributeMap.clear();
 
-  std::map<FeaturePtr, Slvs_hEntity>::const_iterator anIt3 =  myFeatureMap.begin();
-  for (; anIt3 != myFeatureMap.end(); anIt3++)
-    myStorage->removeEntity(anIt3->second);
-  myFeatureMap.clear();
+  std::map<FeaturePtr, Slvs_hEntity>::iterator anIt3 =  myFeatureMap.begin();
+  while (!myFeatureMap.empty()) {
+    std::shared_ptr<SketchPlugin_Feature> aFeature =
+        std::dynamic_pointer_cast<SketchPlugin_Feature>(anIt3->first);
+    Slvs_hEntity anEnt = anIt3->second;
+    std::map<FeaturePtr, Slvs_hEntity>::iterator aRemIt = anIt3++;
+    myFeatureMap.erase(aRemIt);
+    if (!myGroup->isInteract(aFeature))
+      myStorage->removeEntity(anEnt);
+  }
 
   std::vector<Slvs_hConstraint>::const_iterator anIt4 = mySlvsConstraints.begin();
   for (; anIt4 != mySlvsConstraints.end(); anIt4++)
@@ -56,6 +62,12 @@ void SketchSolver_Constraint::setGroup(SketchSolver_Group* theGroup)
   process();
 }
 
+void SketchSolver_Constraint::addFeature(FeaturePtr theFeature)
+{
+  int aType;
+  changeEntity(theFeature, aType);
+}
+
 
 void SketchSolver_Constraint::process()
 {
@@ -104,12 +116,53 @@ void SketchSolver_Constraint::process()
 void SketchSolver_Constraint::update(ConstraintPtr theConstraint)
 {
   cleanErrorMsg();
-  if (theConstraint && theConstraint != myBaseConstraint) {
-    if (theConstraint->getKind() != myBaseConstraint->getKind())
+  bool needToRebuild = (theConstraint && theConstraint != myBaseConstraint);
+  if (!needToRebuild) {
+    // Check the attrbutes of constraint are changed
+    ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint;
+    std::list<AttributePtr> anAttrList = aConstraint->data()->attributes(std::string());
+    std::list<AttributePtr>::iterator anAttrIter = anAttrList.begin();
+    for (; anAttrIter != anAttrList.end(); anAttrIter++) {
+      AttributeRefAttrPtr aRefAttr =
+          std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIter);
+      if (aRefAttr) {
+        if (aRefAttr->isObject()) {
+          FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
+          if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end()) {
+            needToRebuild = true;
+            break;
+          }
+        } else if (aRefAttr->attr() &&
+                    myAttributeMap.find(aRefAttr->attr()) == myAttributeMap.end()) {
+          needToRebuild = true;
+          break;
+        }
+      }
+      AttributeRefListPtr aRefList =
+          std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anAttrIter);
+      if (aRefList) {
+        std::list<ObjectPtr> anItems = aRefList->list();
+        std::list<ObjectPtr>::iterator anIt = anItems.begin();
+        for (; anIt != anItems.end(); anIt++) {
+          FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
+          if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end()) {
+            needToRebuild = true;
+            break;
+          }
+        }
+        if (needToRebuild)
+          break;
+      }
+    }
+  }
+  if (needToRebuild) {
+    if (theConstraint && theConstraint->getKind() != myBaseConstraint->getKind())
       return;
     remove(myBaseConstraint);
-    myBaseConstraint = theConstraint;
+    if (theConstraint)
+      myBaseConstraint = theConstraint;
     process();
+    return;
   }
 
   // Update all attributes
@@ -141,7 +194,8 @@ void SketchSolver_Constraint::update(ConstraintPtr theConstraint)
   std::vector<Slvs_hConstraint>::iterator aCIter = mySlvsConstraints.begin();
   for (; aCIter != mySlvsConstraints.end(); aCIter++) {
     Slvs_Constraint aConstraint = myStorage->getConstraint(*aCIter);
-    aConstraint.valA = aValue;
+    if (aValueAttr)
+      aConstraint.valA = aValue;
     Slvs_hEntity* aCoeffs[6] = {
         &aConstraint.ptA, &aConstraint.ptB,
         &aConstraint.entityA, &aConstraint.entityB,
@@ -521,7 +575,7 @@ void SketchSolver_Constraint::refresh()
         }
         if (fabs(aPoint2D->x() - aXY[0]) > tolerance ||
             fabs(aPoint2D->y() - aXY[1]) > tolerance)
-        aPoint2D->setValue(aXY[0], aXY[1]);
+          aPoint2D->setValue(aXY[0], aXY[1]);
       } else {
         // Scalar value (used for the distance entities)
         AttributeDoublePtr aScalar =
@@ -552,7 +606,15 @@ Slvs_hEntity SketchSolver_Constraint::getId(FeaturePtr theFeature) const
   std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFIter = myFeatureMap.find(theFeature);
   if (aFIter == myFeatureMap.end())
     return SLVS_E_UNKNOWN;
-  return aFIter->second;
+  // check the Feature is really in the storage
+  Slvs_Entity anEntity = myStorage->getEntity(aFIter->second);
+  if (anEntity.h == SLVS_E_UNKNOWN) {
+    // rebuild feature
+    int aType;
+    anEntity.h = const_cast<SketchSolver_Constraint*>(this)->changeEntity(aFIter->first, aType);
+    const_cast<SketchSolver_Constraint*>(this)->myFeatureMap[theFeature] = anEntity.h;
+  }
+  return anEntity.h;
 }
 
 Slvs_hEntity SketchSolver_Constraint::getId(AttributePtr theAttribute) const
@@ -618,18 +680,24 @@ void SketchSolver_Constraint::calculateMiddlePoint(
 
     double xStart = anArcPoint[1][0] / aRad, xEnd = anArcPoint[2][0] / aRad;
     double yStart = anArcPoint[1][1] / aRad, yEnd = anArcPoint[2][1] / aRad;
+    double aTanStart = abs(xStart) < tolerance ? yStart : yStart / xStart;
+    double aTanEnd   = abs(xEnd) < tolerance   ? yEnd   : yEnd / xEnd;
+    double aCotStart = abs(yStart) < tolerance ? xStart : xStart / yStart;
+    double aCotEnd   = abs(yEnd) < tolerance   ? xEnd   : xEnd / yEnd;
     if (anArcPoint[1][0] * anArcPoint[2][0] < 0.0) {
       if (anArcPoint[1][0] > 0.0)
         yEnd = 2.0 - yEnd;
       else
         yStart = -2.0 - yStart;
     } else {
-      if (yStart > yEnd) {
-        yStart = 2.0 - yStart;
-        yEnd = -2.0 - yEnd;
-      } else {
-        yStart = -2.0 - yStart;
-        yEnd = 2.0 - yEnd;
+      if (aTanStart > aTanEnd) {
+        if (yStart > yEnd) {
+          yStart = 2.0 - yStart;
+          yEnd = -2.0 - yEnd;
+        } else {
+          yStart = -2.0 - yStart;
+          yEnd = 2.0 - yEnd;
+        }
       }
     }
     if (anArcPoint[1][1] * anArcPoint[2][1] < 0.0) {
@@ -638,12 +706,14 @@ void SketchSolver_Constraint::calculateMiddlePoint(
       else
         xStart = -2.0 - xStart;
     } else {
-      if (xStart > xEnd) {
-        xStart = 2.0 - xStart;
-        xEnd = -2.0 - xEnd;
-      } else {
-        xStart = -2.0 - xStart;
-        xEnd = 2.0 - xEnd;
+      if (aCotStart < aCotEnd) {
+        if (xStart > xEnd) {
+          xStart = 2.0 - xStart;
+          xEnd = -2.0 - xEnd;
+        } else {
+          xStart = -2.0 - xStart;
+          xEnd = 2.0 - xEnd;
+        }
       }
     }
     x = (1.0 - theCoeff) * xStart + theCoeff * xEnd;
@@ -666,3 +736,10 @@ void SketchSolver_Constraint::calculateMiddlePoint(
   }
 }
 
+void SketchSolver_Constraint::makeTemporary() const
+{
+  std::vector<Slvs_hConstraint>::const_iterator anIt = mySlvsConstraints.begin();
+  for (; anIt != mySlvsConstraints.end(); anIt++)
+    myStorage->addTemporaryConstraint(*anIt);
+}
+