Salome HOME
Fix problems in sketch unit tests
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_Builder.cpp
index 23933b232d6ee48c19872ca21ea23b4be62bc350..a7c348db78a0c00b73b3ee9be87ea8a550d2c90d 100644 (file)
@@ -29,6 +29,7 @@
 #include <SketchPlugin_Circle.h>
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_Point.h>
+#include <SketchPlugin_IntersectionPoint.h>
 #include <SketchPlugin_ConstraintAngle.h>
 
 #include <math.h>
@@ -141,8 +142,6 @@ static ConstraintWrapperPtr
 
 
 
-/// \brief Set flags for angle constraint
-static void adjustAngle(ConstraintWrapperPtr theConstraint);
 /// \brief Update mirror points
 static void adjustMirror(ConstraintWrapperPtr theConstraint);
 /// \brief Update a sign of the point-line distance constraint
@@ -341,10 +340,10 @@ std::list<ConstraintWrapperPtr> PlaneGCSSolver_Builder::createMirror(
         std::dynamic_pointer_cast<GCS::Line>(aMirrorLine->entity());
 
     std::list<GCSConstraintPtr> aConstrList;
-    aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintPerpendicular(
-        *(aPoint1->point()), *(aPoint2->point()), aLine->p1, aLine->p2)));
     aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintMidpointOnLine(
         *(aPoint1->point()), *(aPoint2->point()), aLine->p1, aLine->p2)));
+    aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintPerpendicular(
+        *(aPoint1->point()), *(aPoint2->point()), aLine->p1, aLine->p2)));
 
     ConstraintWrapperPtr aSubResult(new PlaneGCSSolver_ConstraintWrapper(
         theConstraint, aConstrList, CONSTRAINT_SYMMETRIC));
@@ -458,10 +457,10 @@ void PlaneGCSSolver_Builder::adjustConstraint(ConstraintWrapperPtr theConstraint
 {
   SketchSolver_ConstraintType aType = theConstraint->type();
   // Update flags and parameters in constraints
-  if (aType == CONSTRAINT_ANGLE)
-    adjustAngle(theConstraint);
-  else if (aType == CONSTRAINT_PT_LINE_DISTANCE)
+  if (aType == CONSTRAINT_PT_LINE_DISTANCE)
     adjustPtLineDistance(theConstraint);
+  else if (aType == CONSTRAINT_SYMMETRIC)
+    adjustMirror(theConstraint);
 }
 
 EntityWrapperPtr PlaneGCSSolver_Builder::createFeature(
@@ -497,7 +496,8 @@ EntityWrapperPtr PlaneGCSSolver_Builder::createFeature(
   else if (aFeatureKind == SketchPlugin_Arc::ID())
     return createArc(theFeature, theAttributes, theGroupID);
   // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
-  else if (aFeatureKind == SketchPlugin_Point::ID()) {
+  else if (aFeatureKind == SketchPlugin_Point::ID() ||
+           aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
     EntityWrapperPtr aSub;
     if (theAttributes.size() == 1)
       aSub = theAttributes.front();
@@ -856,7 +856,7 @@ ConstraintWrapperPtr createConstraintMiddlePoint(
   aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintPointOnLine(*aPoint, *aLine)));
   double aDist = lineLength(*aLine);
   std::shared_ptr<PlaneGCSSolver_ParameterWrapper> aDistance =
-      std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(createParameter(theGroupID, aDist));
+      std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(createParameter(theGroupID, aDist * 0.5));
   aConstrList.push_back(GCSConstraintPtr(
       new GCS::ConstraintP2PDistance(*aPoint, aLine->p1, aDistance->parameter())));
   aConstrList.push_back(GCSConstraintPtr(
@@ -951,9 +951,19 @@ ConstraintWrapperPtr createConstraintAngle(
     std::shared_ptr<PlaneGCSSolver_EntityWrapper> theEntity2)
 {
   std::shared_ptr<GCS::Line> aLine1 = std::dynamic_pointer_cast<GCS::Line>(theEntity1->entity());
+  bool isLine1Rev = theConstraint->boolean(
+      SketchPlugin_ConstraintAngle::ANGLE_REVERSED_FIRST_LINE_ID())->value();
+  GCS::Point aLine1Pt1 = isLine1Rev ? aLine1->p2 : aLine1->p1;
+  GCS::Point aLine1Pt2 = isLine1Rev ? aLine1->p1 : aLine1->p2;
+
   std::shared_ptr<GCS::Line> aLine2 = std::dynamic_pointer_cast<GCS::Line>(theEntity2->entity());
+  bool isLine2Rev = theConstraint->boolean(
+      SketchPlugin_ConstraintAngle::ANGLE_REVERSED_SECOND_LINE_ID())->value();
+  GCS::Point aLine2Pt1 = isLine2Rev ? aLine2->p2 : aLine2->p1;
+  GCS::Point aLine2Pt2 = isLine2Rev ? aLine2->p1 : aLine2->p2;
+
   GCSConstraintPtr aNewConstr(new GCS::ConstraintL2LAngle(
-      *(aLine1), *(aLine2), theValue->parameter()));
+      aLine1Pt1, aLine1Pt2, aLine2Pt1, aLine2Pt2, theValue->parameter()));
 
   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aResult(
       new PlaneGCSSolver_ConstraintWrapper(theConstraint, aNewConstr, CONSTRAINT_ANGLE));
@@ -1067,6 +1077,11 @@ ConstraintWrapperPtr createConstraintEqual(
         new GCS::ConstraintP2PDistance(aLine1->p1, aLine1->p2, theIntermed->parameter())));
     aConstrList.push_back(GCSConstraintPtr(
         new GCS::ConstraintP2PDistance(aLine2->p1, aLine2->p2, theIntermed->parameter())));
+    // update value of intermediate parameter
+    double x = *aLine1->p1.x - *aLine1->p2.x;
+    double y = *aLine1->p1.y - *aLine1->p2.y;
+    double aLen = sqrt(x*x + y*y);
+    theIntermed->setValue(aLen);
   } else {
     std::shared_ptr<GCS::Circle> aCirc1 =
         std::dynamic_pointer_cast<GCS::Circle>(theEntity1->entity());
@@ -1124,72 +1139,6 @@ ConstraintWrapperPtr createConstraintTangent(
 
 
 
-void adjustAngle(ConstraintWrapperPtr theConstraint)
-{
-  BuilderPtr aBuilder = PlaneGCSSolver_Builder::getInstance();
-
-  std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aConstraint =
-    std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(theConstraint);
-
-  std::shared_ptr<GeomAPI_Pnt2d> aPoints[2][2]; // start and end points of lines
-  const std::list<EntityWrapperPtr>& aConstrLines = aConstraint->entities();
-  std::list<EntityWrapperPtr>::const_iterator aCLIt = aConstrLines.begin();
-  for (int i = 0; aCLIt != aConstrLines.end(); ++i, ++aCLIt) {
-    const std::list<EntityWrapperPtr>& aLinePoints = (*aCLIt)->subEntities();
-    std::list<EntityWrapperPtr>::const_iterator aLPIt = aLinePoints.begin();
-    for (int j = 0; aLPIt != aLinePoints.end(); ++j, ++aLPIt)
-      aPoints[i][j] = aBuilder->point(*aLPIt);
-  }
-
-  std::shared_ptr<GeomAPI_Lin2d> aLine[2] = {
-    std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aPoints[0][0], aPoints[0][1])),
-    std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aPoints[1][0], aPoints[1][1]))
-  };
-  std::shared_ptr<GeomAPI_Pnt2d> anIntersection = aLine[0]->intersect(aLine[1]);
-  if (!anIntersection)
-    return;
-  double aDist[2][2];
-  for (int i = 0; i < 2; i++) {
-    for (int j = 0; j < 2; j++) {
-      aDist[i][j] = anIntersection->distance(aPoints[i][j]);
-      if (fabs(aDist[i][j]) <= tolerance)
-        aDist[i][j] = 0.0;
-    }
-    if (aDist[i][0] > tolerance && aDist[i][1] > tolerance &&
-        aDist[i][0] + aDist[i][1] < aPoints[i][0]->distance(aPoints[i][1]) + 2.0 * tolerance) {
-      // the intersection point is an inner point of the line,
-      // we change the sign of distance till start point to calculate correct coordinates
-      // after rotation
-      aDist[i][0] *= -1.0;
-    }
-  }
-  std::shared_ptr<GeomAPI_Dir2d> aDir[2];
-  for (int i = 0; i < 2; i++) {
-    if (aDist[i][1] > fabs(aDist[i][0]))
-      aDir[i] = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(
-          aPoints[i][1]->xy()->decreased(anIntersection->xy())));
-    else {
-      aDir[i] = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(
-          aPoints[i][0]->xy()->decreased(anIntersection->xy())));
-      // main direction is opposite => change signs
-      if (aDist[i][0] < 0.0) {
-        aDist[i][0] *= -1.0;
-        aDist[i][1] *= -1.0;
-      }
-    }
-  }
-
-  double anAngle = aLine[0]->direction()->angle(aLine[1]->direction()) / PI * 180;
-  if (anAngle * aConstraint->value() < 0.0)
-    aConstraint->setValue(-aConstraint->value());
-  if ((90.0 - fabs(anAngle)) * (fabs(aConstraint->value()) - 90.0) > 0.0) {
-    if (aConstraint->value() < 0.0)
-      aConstraint->setValue(-180.0 - aConstraint->value());
-    else
-      aConstraint->setValue(180.0 - aConstraint->value());
-  }
-}
-
 void makeMirrorPoints(EntityWrapperPtr theOriginal,
                       EntityWrapperPtr theMirrored,
                       EntityWrapperPtr theMirrorLine)
@@ -1239,3 +1188,28 @@ void adjustPtLineDistance(ConstraintWrapperPtr theConstraint)
     theConstraint->setValue(theConstraint->value() * (-1.0));
 }
 
+void adjustMirror(ConstraintWrapperPtr theConstraint)
+{
+  std::vector<EntityWrapperPtr> aPoints;
+  EntityWrapperPtr aMirrorLine;
+
+  const std::list<EntityWrapperPtr>& aSubs = theConstraint->entities();
+  std::list<EntityWrapperPtr>::const_iterator anIt = aSubs.begin();
+  for (; anIt != aSubs.end(); ++anIt) {
+    if ((*anIt)->type() == ENTITY_POINT)
+      aPoints.push_back(*anIt);
+    else if ((*anIt)->type() == ENTITY_LINE)
+      aMirrorLine = *anIt;
+  }
+
+  if (aPoints.size() == 2)
+    makeMirrorPoints(aPoints[0], aPoints[1], aMirrorLine);
+
+  // update scales of constraints
+  std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aGCSConstraint = 
+      std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(theConstraint);
+  std::list<GCSConstraintPtr>::const_iterator aCIt = aGCSConstraint->constraints().begin();
+  for (; aCIt != aGCSConstraint->constraints().end(); ++aCIt)
+    (*aCIt)->rescale();
+}
+