Salome HOME
Mirror constraint behavior stabilization
authorazv <azv@opencascade.com>
Thu, 9 Apr 2015 08:02:58 +0000 (11:02 +0300)
committerazv <azv@opencascade.com>
Thu, 9 Apr 2015 08:02:58 +0000 (11:02 +0300)
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_ConstraintMirror.cpp

index b86ce1a28073d4caa0cecf85827bc7e4b4b517b8..1d2abb3547d3e51a4cec0234fcf0eb2c242176be 100644 (file)
@@ -618,18 +618,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 +644,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;
index f3ded1d30f1046113d0ef92ac879f94f63c959df..fde4b811ecd73e1b72683d306a5c836f8f2222bf 100644 (file)
@@ -159,6 +159,20 @@ void SketchSolver_ConstraintMirror::process()
             0.0, aBothMiddlePoints[i], SLVS_E_UNKNOWN, aBothArcs[i].h, SLVS_E_UNKNOWN);
         aPonCircConstr.h = myStorage->addConstraint(aPonCircConstr);
         mySlvsConstraints.push_back(aPonCircConstr.h);
+        if (i == 0) {
+          // additional constraint for the point to be in the middle of a base arc
+          Slvs_Entity aLine1 = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(),
+              myGroup->getWorkplaneId(), aBothArcs[i].point[1], aBothMiddlePoints[i]);
+          aLine1.h = myStorage->addEntity(aLine1);
+          Slvs_Entity aLine2 = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(),
+              myGroup->getWorkplaneId(), aBothArcs[i].point[2], aBothMiddlePoints[i]);
+          aLine2.h = myStorage->addEntity(aLine2);
+          Slvs_Constraint aMiddleConstr = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
+              SLVS_C_EQUAL_LENGTH_LINES, myGroup->getWorkplaneId(),
+              0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aLine1.h, aLine2.h);
+          aMiddleConstr.h = myStorage->addConstraint(aMiddleConstr);
+          mySlvsConstraints.push_back(aMiddleConstr.h);
+        }
       }
 
       aBaseArcPoints[2] = aBothMiddlePoints[0];
@@ -319,6 +333,7 @@ void SketchSolver_ConstraintMirror::adjustConstraint()
     if (aPonCircA.h == SLVS_E_UNKNOWN || aPonCircB.h == SLVS_E_UNKNOWN)
       continue;
 
+    bool aNeedToResolve = myStorage->isNeedToResolve();
     // Calculate middle point for base arc and mirrored point on mirror arc
     Slvs_Entity aBaseArc = myStorage->getEntity(aPonCircA.entityA);
     Slvs_Entity aBasePoint = myStorage->getEntity(aPonCircA.ptA);
@@ -327,7 +342,14 @@ void SketchSolver_ConstraintMirror::adjustConstraint()
     calculateMiddlePoint(aBaseArc, 0.5, aParamX.val, aParamY.val);
     myStorage->updateParameter(aParamX);
     myStorage->updateParameter(aParamY);
+    Slvs_Entity aMirrorArc = myStorage->getEntity(aPonCircB.entityA);
     Slvs_Entity aMirrorPoint = myStorage->getEntity(aPonCircB.ptA);
-    makeMirrorEntity(aBasePoint, aMirrorPoint, aStartEnd);
+    aParamX = myStorage->getParameter(aMirrorPoint.param[0]);
+    aParamY = myStorage->getParameter(aMirrorPoint.param[1]);
+    calculateMiddlePoint(aMirrorArc, 0.5, aParamX.val, aParamY.val);
+    myStorage->updateParameter(aParamX);
+    myStorage->updateParameter(aParamY);
+    // To avoid looped recalculations of sketch
+    myStorage->setNeedToResolve(aNeedToResolve);
   }
 }