Salome HOME
A fix for the next case:
[modules/shaper.git] / src / SketchSolver / SketchSolver_Constraint.cpp
index c382cdeb30e86ec4d051643104d75e95ec23aeec..2a4c36f8f7dada5503b0c0c55875144e3c55344c 100644 (file)
@@ -7,11 +7,13 @@
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_Point.h>
 
+#include <GeomAPI_Dir2d.h>
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_ResultConstruction.h>
 
+#include <math.h>
 
 SketchSolver_Constraint::SketchSolver_Constraint(
     ConstraintPtr  theConstraint)
@@ -32,10 +34,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++)
@@ -55,6 +63,12 @@ void SketchSolver_Constraint::setGroup(SketchSolver_Group* theGroup)
   process();
 }
 
+void SketchSolver_Constraint::addFeature(FeaturePtr theFeature)
+{
+  int aType;
+  changeEntity(theFeature, aType);
+}
+
 
 void SketchSolver_Constraint::process()
 {
@@ -72,6 +86,8 @@ void SketchSolver_Constraint::process()
   getAttributes(aValue, anAttributes);
   if (!myErrorMsg.empty())
     return;
+  if (aConstrType == SLVS_C_UNKNOWN)
+    aConstrType = getType();
 
   Slvs_hGroup aGroupID = myGroup->getId();
   Slvs_hEntity aWorkplaneID = myGroup->getWorkplaneId();
@@ -100,15 +116,53 @@ void SketchSolver_Constraint::process()
   adjustConstraint();
 }
 
+bool SketchSolver_Constraint::checkAttributesChanged(ConstraintPtr theConstraint)
+{
+  // 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())
+          return true;
+      } else if (aRefAttr->attr() &&
+                 myAttributeMap.find(aRefAttr->attr()) == myAttributeMap.end())
+        return true;
+    }
+    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())
+          return true;
+      }
+    }
+  }
+  return false;
+}
+
 void SketchSolver_Constraint::update(ConstraintPtr theConstraint)
 {
   cleanErrorMsg();
-  if (theConstraint && theConstraint != myBaseConstraint) {
-    if (theConstraint->getKind() != myBaseConstraint->getKind())
+  bool needToRebuild = (theConstraint && theConstraint != myBaseConstraint);
+  if (!needToRebuild)
+    needToRebuild = checkAttributesChanged(theConstraint);
+  if (needToRebuild) {
+    if (theConstraint && theConstraint->getKind() != myBaseConstraint->getKind())
       return;
     remove(myBaseConstraint);
-    myBaseConstraint = theConstraint;
+    if (theConstraint)
+      myBaseConstraint = theConstraint;
     process();
+    return;
   }
 
   // Update all attributes
@@ -130,15 +184,18 @@ void SketchSolver_Constraint::update(ConstraintPtr theConstraint)
   }
 
   // Value if exists
+  DataPtr aData = myBaseConstraint->data();
+  if (!aData) return;
   AttributeDoublePtr aValueAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
-    myBaseConstraint->data()->attribute(SketchPlugin_Constraint::VALUE()));
+    myBaseConstraint->attribute(SketchPlugin_Constraint::VALUE()));
   double aValue = aValueAttr ? aValueAttr->value() : 0.0;
 
   // Update constraint
   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,
@@ -169,6 +226,7 @@ bool SketchSolver_Constraint::remove(ConstraintPtr theConstraint)
     myValueMap.clear();
   } else
     cleanRemovedEntities();
+  mySlvsConstraints.clear();
   return true;
 }
 
@@ -278,8 +336,10 @@ Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributeRefAttrPtr theAttrib
 Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributePtr theEntity, int& theType)
 {
   Slvs_hEntity aResult = SLVS_E_UNKNOWN;
-  if (!theEntity->isInitialized())
+  if (!theEntity || !isInitialized(theEntity)) {
+    myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
     return SLVS_E_UNKNOWN;
+  }
 
   // If the entity is already in the group, try to find it
   std::map<std::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator anEntIter =
@@ -293,6 +353,7 @@ Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributePtr theEntity, int&
     if (aResult != SLVS_E_UNKNOWN) {
       Slvs_Entity anEnt = myStorage->getEntity(aResult);
       theType = anEnt.type;
+      myAttributeMap[theEntity] = aResult;
       return aResult;
     }
   }
@@ -373,7 +434,7 @@ Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributePtr theEntity, int&
 Slvs_hEntity SketchSolver_Constraint::changeEntity(FeaturePtr theEntity, int& theType)
 {
   Slvs_hEntity aResult = SLVS_E_UNKNOWN;
-  if (!theEntity->data()->isValid())
+  if (!theEntity || !theEntity->data() || !theEntity->data()->isValid())
     return SLVS_E_UNKNOWN;
   // If the entity is already in the group, try to find it
   std::map<FeaturePtr, Slvs_hEntity>::const_iterator anEntIter = myFeatureMap.find(theEntity);
@@ -386,91 +447,89 @@ Slvs_hEntity SketchSolver_Constraint::changeEntity(FeaturePtr theEntity, int& th
     if (aResult != SLVS_E_UNKNOWN) {
       Slvs_Entity anEnt = myStorage->getEntity(aResult);
       theType = anEnt.type;
+      myFeatureMap[theEntity] = aResult;
       return aResult;
     }
   }
 
   Slvs_hGroup aGroupID = myGroup->getId();
   Slvs_hEntity aWorkplaneID = myGroup->getWorkplaneId();
+  DataPtr aData = theEntity->data();
+
   // SketchPlugin features
-  std::shared_ptr<SketchPlugin_Feature> aFeature = std::dynamic_pointer_cast<
-      SketchPlugin_Feature>(theEntity);
-  if (aFeature) {  // Verify the feature by its kind
-    const std::string& aFeatureKind = aFeature->getKind();
-    AttributePtr anAttribute;
-    int anAttrType;
-
-    // Line
-    if (aFeatureKind == SketchPlugin_Line::ID()) {
-      anAttribute = aFeature->data()->attribute(SketchPlugin_Line::START_ID());
-      if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
-      Slvs_hEntity aStart = changeEntity(anAttribute, anAttrType);
-
-      anAttribute = aFeature->data()->attribute(SketchPlugin_Line::END_ID());
-      if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
-      Slvs_hEntity aEnd = changeEntity(anAttribute, anAttrType);
+  const std::string& aFeatureKind = theEntity->getKind();
+  AttributePtr anAttribute;
+  int anAttrType;
+  // Line
+  if (aFeatureKind == SketchPlugin_Line::ID()) {
+    anAttribute = aData->attribute(SketchPlugin_Line::START_ID());
+    if (!isInitialized(anAttribute)) return SLVS_E_UNKNOWN;
+    Slvs_hEntity aStart = changeEntity(anAttribute, anAttrType);
+
+    anAttribute = aData->attribute(SketchPlugin_Line::END_ID());
+    if (!isInitialized(anAttribute)) return SLVS_E_UNKNOWN;
+    Slvs_hEntity aEnd = changeEntity(anAttribute, anAttrType);
 
-      if (aCurrentEntity.h == SLVS_E_UNKNOWN) // New entity
-        aCurrentEntity = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID, aStart, aEnd);
-      else {
-        aCurrentEntity.point[0] = aStart;
-        aCurrentEntity.point[1] = aEnd;
-      }
-      aResult = myStorage->addEntity(aCurrentEntity);
-    }
-    // Circle
-    else if (aFeatureKind == SketchPlugin_Circle::ID()) {
-      anAttribute = aFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID());
-      if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
-      Slvs_hEntity aCenter = changeEntity(anAttribute, anAttrType);
-
-      anAttribute = aFeature->data()->attribute(SketchPlugin_Circle::RADIUS_ID());
-      if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
-      Slvs_hEntity aRadius = changeEntity(anAttribute, anAttrType);
-
-      if (aCurrentEntity.h == SLVS_E_UNKNOWN) { // New entity
-        Slvs_Entity aWorkplane = myStorage->getEntity(aWorkplaneID);
-        aCurrentEntity = Slvs_MakeCircle(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID,
-                                         aCenter, aWorkplane.normal, aRadius);
-      } else {
-        aCurrentEntity.point[0] = aCenter;
-        aCurrentEntity.distance = aRadius;
-      }
-      aResult = myStorage->addEntity(aCurrentEntity);
+    if (aCurrentEntity.h == SLVS_E_UNKNOWN) // New entity
+      aCurrentEntity = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID, aStart, aEnd);
+    else {
+      aCurrentEntity.point[0] = aStart;
+      aCurrentEntity.point[1] = aEnd;
     }
-    // Arc
-    else if (aFeatureKind == SketchPlugin_Arc::ID()) {
-      anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID());
-      if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
-      Slvs_hEntity aCenter = changeEntity(anAttribute, anAttrType);
-
-      anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::START_ID());
-      if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
-      Slvs_hEntity aStart = changeEntity(anAttribute, anAttrType);
-
-      anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::END_ID());
-      if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
-      Slvs_hEntity aEnd = changeEntity(anAttribute, anAttrType);
-
-      if (aCurrentEntity.h == SLVS_E_UNKNOWN) { // New entity
-        Slvs_Entity aWorkplane = myStorage->getEntity(aWorkplaneID);
-        aCurrentEntity = Slvs_MakeArcOfCircle(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID,
-                                              aWorkplane.normal, aCenter, aStart, aEnd);
-      } else {
-        aCurrentEntity.point[0] = aCenter;
-        aCurrentEntity.point[1] = aStart;
-        aCurrentEntity.point[2] = aEnd;
-      }
-      aResult = myStorage->addEntity(aCurrentEntity);
+    aResult = myStorage->addEntity(aCurrentEntity);
+  }
+  // Circle
+  else if (aFeatureKind == SketchPlugin_Circle::ID()) {
+    anAttribute = aData->attribute(SketchPlugin_Circle::CENTER_ID());
+    if (!isInitialized(anAttribute)) return SLVS_E_UNKNOWN;
+    Slvs_hEntity aCenter = changeEntity(anAttribute, anAttrType);
+
+    anAttribute = aData->attribute(SketchPlugin_Circle::RADIUS_ID());
+    if (!isInitialized(anAttribute)) return SLVS_E_UNKNOWN;
+    Slvs_hEntity aRadius = changeEntity(anAttribute, anAttrType);
+
+    if (aCurrentEntity.h == SLVS_E_UNKNOWN) { // New entity
+      Slvs_Entity aWorkplane = myStorage->getEntity(aWorkplaneID);
+      aCurrentEntity = Slvs_MakeCircle(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID,
+                                        aCenter, aWorkplane.normal, aRadius);
+    } else {
+      aCurrentEntity.point[0] = aCenter;
+      aCurrentEntity.distance = aRadius;
     }
-    // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
-    else if (aFeatureKind == SketchPlugin_Point::ID()) {
-      anAttribute = aFeature->data()->attribute(SketchPlugin_Point::COORD_ID());
-      if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
-      // Both the sketch point and its attribute (coordinates) link to the same SolveSpace point identifier
-      aResult = changeEntity(anAttribute, anAttrType);
-      aCurrentEntity.type = SLVS_E_POINT_IN_3D;
+    aResult = myStorage->addEntity(aCurrentEntity);
+  }
+  // Arc
+  else if (aFeatureKind == SketchPlugin_Arc::ID()) {
+    anAttribute = aData->attribute(SketchPlugin_Arc::CENTER_ID());
+    if (!isInitialized(anAttribute)) return SLVS_E_UNKNOWN;
+    Slvs_hEntity aCenter = changeEntity(anAttribute, anAttrType);
+
+    anAttribute = aData->attribute(SketchPlugin_Arc::START_ID());
+    if (!isInitialized(anAttribute)) return SLVS_E_UNKNOWN;
+    Slvs_hEntity aStart = changeEntity(anAttribute, anAttrType);
+
+    anAttribute = aData->attribute(SketchPlugin_Arc::END_ID());
+    if (!isInitialized(anAttribute)) return SLVS_E_UNKNOWN;
+    Slvs_hEntity aEnd = changeEntity(anAttribute, anAttrType);
+
+    if (aCurrentEntity.h == SLVS_E_UNKNOWN) { // New entity
+      Slvs_Entity aWorkplane = myStorage->getEntity(aWorkplaneID);
+      aCurrentEntity = Slvs_MakeArcOfCircle(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID,
+                                            aWorkplane.normal, aCenter, aStart, aEnd);
+    } else {
+      aCurrentEntity.point[0] = aCenter;
+      aCurrentEntity.point[1] = aStart;
+      aCurrentEntity.point[2] = aEnd;
     }
+    aResult = myStorage->addEntity(aCurrentEntity);
+  }
+  // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
+  else if (aFeatureKind == SketchPlugin_Point::ID()) {
+    anAttribute = aData->attribute(SketchPlugin_Point::COORD_ID());
+    if (!isInitialized(anAttribute)) return SLVS_E_UNKNOWN;
+    // Both the sketch point and its attribute (coordinates) link to the same SolveSpace point identifier
+    aResult = changeEntity(anAttribute, anAttrType);
+    aCurrentEntity.type = SLVS_E_POINT_IN_3D;
   }
 
   if (aResult != SLVS_E_UNKNOWN) {
@@ -501,19 +560,24 @@ void SketchSolver_Constraint::refresh()
         Slvs_Param aPar = myStorage->getParameter(anEntity.param[i]);
         aXYZ[i] = aPar.val;
       }
-      aPoint->setValue(aXYZ[0], aXYZ[1], aXYZ[2]);
+      if (fabs(aPoint->x() - aXYZ[0]) > tolerance ||
+          fabs(aPoint->y() - aXYZ[1]) > tolerance ||
+          fabs(aPoint->z() - aXYZ[2]) > tolerance)
+        aPoint->setValue(aXYZ[0], aXYZ[1], aXYZ[2]);
     } else {
       // Point in 2D
       std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
           std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrIter->first);
       if (aPoint2D) {
         Slvs_Entity anEntity = myStorage->getEntity(anAttrIter->second);
-        double aXYZ[2];
+        double aXY[2];
         for (int i = 0; i < 2; i++) {
           Slvs_Param aPar = myStorage->getParameter(anEntity.param[i]);
-          aXYZ[i] = aPar.val;
+          aXY[i] = aPar.val;
         }
-        aPoint2D->setValue(aXYZ[0], aXYZ[1]);
+        if (fabs(aPoint2D->x() - aXY[0]) > tolerance ||
+            fabs(aPoint2D->y() - aXY[1]) > tolerance)
+          aPoint2D->setValue(aXY[0], aXY[1]);
       } else {
         // Scalar value (used for the distance entities)
         AttributeDoublePtr aScalar =
@@ -521,7 +585,8 @@ void SketchSolver_Constraint::refresh()
         if (aScalar) {
           Slvs_Entity anEntity = myStorage->getEntity(anAttrIter->second);
           Slvs_Param aPar = myStorage->getParameter(anEntity.param[0]);
-          aScalar->setValue(aPar.val);
+          if (fabs(aScalar->value() - aPar.val) > tolerance)
+            aScalar->setValue(aPar.val);
         }
       }
     }
@@ -543,7 +608,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
@@ -554,3 +627,76 @@ Slvs_hEntity SketchSolver_Constraint::getId(AttributePtr theAttribute) const
   return anAttrIter->second;
 }
 
+bool SketchSolver_Constraint::isInitialized(AttributePtr theAttribute)
+{
+  if (theAttribute->isInitialized())
+    return true;
+  myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
+  return false;
+}
+
+
+void SketchSolver_Constraint::calculateMiddlePoint(
+    const Slvs_Entity& theEntity, double theCoeff, double& theX, double& theY) const
+{
+  if (theEntity.type == SLVS_E_LINE_SEGMENT) {
+    double aStartEndXY[2][2];
+    Slvs_Entity aPoint;
+    for (int i = 0; i < 2; i++) {
+      aPoint = myStorage->getEntity(theEntity.point[i]);
+      for (int j = 0; j < 2; j++)
+        aStartEndXY[i][j] = myStorage->getParameter(aPoint.param[j]).val;
+    }
+    theX = (1.0 - theCoeff) * aStartEndXY[0][0] + theCoeff * aStartEndXY[1][0];
+    theY = (1.0 - theCoeff) * aStartEndXY[0][1] + theCoeff * aStartEndXY[1][1];
+  } else if (theEntity.type == SLVS_E_ARC_OF_CIRCLE) {
+    double anArcPoint[3][2];
+    Slvs_Entity aPoint;
+    for (int i = 0; i < 3; i++) {
+      aPoint = myStorage->getEntity(theEntity.point[i]);
+      for (int j = 0; j < 2; j++)
+        anArcPoint[i][j] = myStorage->getParameter(aPoint.param[j]).val;
+    }
+    // project last point of arc on the arc
+    double x = anArcPoint[1][0] - anArcPoint[0][0];
+    double y = anArcPoint[1][1] - anArcPoint[0][1];
+    double aRad = sqrt(x*x + y*y);
+    x = anArcPoint[2][0] - anArcPoint[0][0];
+    y = anArcPoint[2][1] - anArcPoint[0][1];
+    double aNorm = sqrt(x*x + y*y);
+    if (aNorm >= tolerance) {
+      anArcPoint[2][0] = x * aRad / aNorm;
+      anArcPoint[2][1] = y * aRad / aNorm;
+    }
+    anArcPoint[1][0] -= anArcPoint[0][0];
+    anArcPoint[1][1] -= anArcPoint[0][1];
+    if (theCoeff < tolerance) {
+      theX = anArcPoint[0][0] + anArcPoint[1][0];
+      theY = anArcPoint[0][1] + anArcPoint[1][1];
+      return;
+    } else if (1 - theCoeff < tolerance) {
+      theX = anArcPoint[0][0] + anArcPoint[2][0];
+      theY = anArcPoint[0][1] + anArcPoint[2][1];
+      return;
+    }
+
+    std::shared_ptr<GeomAPI_Dir2d> aStartDir(new GeomAPI_Dir2d(anArcPoint[1][0], anArcPoint[1][1]));
+    std::shared_ptr<GeomAPI_Dir2d> aEndDir(new GeomAPI_Dir2d(anArcPoint[2][0], anArcPoint[2][1]));
+    double anAngle = aStartDir->angle(aEndDir);
+    if (anAngle < 0)
+      anAngle += 2.0 * PI;
+    anAngle *= theCoeff;
+    double aCos = cos(anAngle);
+    double aSin = sin(anAngle);
+    theX = anArcPoint[0][0] + anArcPoint[1][0] * aCos - anArcPoint[1][1] * aSin;
+    theY = anArcPoint[0][1] + anArcPoint[1][0] * aSin + anArcPoint[1][1] * aCos;
+  }
+}
+
+void SketchSolver_Constraint::makeTemporary() const
+{
+  std::vector<Slvs_hConstraint>::const_iterator anIt = mySlvsConstraints.begin();
+  for (; anIt != mySlvsConstraints.end(); anIt++)
+    myStorage->addTemporaryConstraint(*anIt);
+}
+