+
+bool SketchSolver_ConstraintDistance::remove()
+{
+ removeConstraintsKeepingSign();
+ return SketchSolver_Constraint::remove();
+}
+
+void SketchSolver_ConstraintDistance::addConstraintsToKeepSign()
+{
+ std::shared_ptr<PlaneGCSSolver_Storage> aStorage =
+ std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage);
+
+ ConstraintWrapperPtr aConstraint = aStorage->constraint(myBaseConstraint);
+ std::list<GCSConstraintPtr> aGCSConstraints = aConstraint->constraints();
+
+ // calculate projection of the point on the line and find a sign of a distance
+ EntityWrapperPtr aDistPoint, aDistLine;
+ getPointAndLine(myBaseConstraint, myStorage, aDistPoint, aDistLine);
+
+ std::shared_ptr<GeomAPI_Lin2d> aLine = PlaneGCSSolver_Tools::line(aDistLine);
+ std::shared_ptr<GeomAPI_Pnt2d> aPoint = PlaneGCSSolver_Tools::point(aDistPoint);
+
+ std::shared_ptr<GeomAPI_XY> aLineVec = aLine->direction()->xy();
+ std::shared_ptr<GeomAPI_XY> aPtLineVec = aPoint->xy()->decreased(aLine->location()->xy());
+ if (aLineVec->cross(aPtLineVec) >= 0.)
+ mySignValue = PI/2.0;
+ else
+ mySignValue = - PI/2.0;
+
+ // create auxiliary point on the line and set auxiliary constraints
+ myOddPoint = GCSPointPtr(new GCS::Point);
+ myOddPoint->x = aStorage->createParameter();
+ myOddPoint->y = aStorage->createParameter();
+ adjustOddPoint(aDistPoint, aDistLine, myOddPoint);
+
+ PointWrapperPtr aPointWr = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(aDistPoint);
+ EdgeWrapperPtr anEdgeWr = std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(aDistLine);
+ std::shared_ptr<GCS::Line> aGCSLine = std::dynamic_pointer_cast<GCS::Line>(anEdgeWr->entity());
+ // point-on-line
+ GCSConstraintPtr aNewConstraint(new GCS::ConstraintPointOnLine(*myOddPoint, *aGCSLine));
+ aGCSConstraints.push_back(aNewConstraint);
+ // angle which keep orientation
+ aNewConstraint = GCSConstraintPtr(new GCS::ConstraintL2LAngle(
+ aGCSLine->p1, aGCSLine->p2, *myOddPoint, *(aPointWr->point()), &mySignValue));
+ aGCSConstraints.push_back(aNewConstraint);
+
+ aConstraint->setConstraints(aGCSConstraints);
+
+ aStorage->removeConstraint(myBaseConstraint);
+ aStorage->addConstraint(myBaseConstraint, aConstraint);
+}
+
+void SketchSolver_ConstraintDistance::removeConstraintsKeepingSign()
+{
+ if (!myOddPoint)
+ return; // no sign kept => nothing to remove
+
+ std::shared_ptr<PlaneGCSSolver_Storage> aStorage =
+ std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage);
+
+ ConstraintWrapperPtr aConstraint = aStorage->constraint(myBaseConstraint);
+ std::list<GCSConstraintPtr> aGCSConstraints = aConstraint->constraints();
+
+ aStorage->removeConstraint(myBaseConstraint);
+
+ // remove parameters related to auxiliary point
+ GCS::SET_pD aParams;
+ aParams.insert(myOddPoint->x);
+ aParams.insert(myOddPoint->y);
+ aStorage->removeParameters(aParams);
+
+ // remove constraints keeping sign of point-line distance,
+ // not more than 2 additional constraints is possible
+ if (!aGCSConstraints.empty())
+ aGCSConstraints.pop_back();
+ if (!aGCSConstraints.empty())
+ aGCSConstraints.pop_back();
+ aConstraint->setConstraints(aGCSConstraints);
+ aStorage->addConstraint(myBaseConstraint, aConstraint);
+
+ myIsSigned = false;
+}