Salome HOME
Merge branch 'task_5_2_4' into CEA_2019
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_Tools.cpp
index a4e461ada6afe7a04c830f84d2eedcdf19a214eb..e90def0d2bce33d7fda69f0ee79ce14671aa1386 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include <PlaneGCSSolver_Tools.h>
@@ -107,7 +106,8 @@ static ConstraintWrapperPtr
                         std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theIntermed);
 static ConstraintWrapperPtr
   createConstraintMiddlePoint(std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
-                              std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
+                              std::shared_ptr<PlaneGCSSolver_EdgeWrapper>  theEntity,
+                              std::shared_ptr<PlaneGCSSolver_PointWrapper> theAuxParameters);
 
 static GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar);
 static GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint);
@@ -192,7 +192,7 @@ ConstraintWrapperPtr PlaneGCSSolver_Tools::createConstraint(
     aResult = createConstraintPointOnEntity(theType, aPoint1, GCS_EDGE_WRAPPER(theEntity1));
     break;
   case CONSTRAINT_MIDDLE_POINT:
-    aResult = createConstraintMiddlePoint(aPoint1, GCS_EDGE_WRAPPER(theEntity1));
+    aResult = createConstraintMiddlePoint(aPoint1, GCS_EDGE_WRAPPER(theEntity1), aPoint2);
     break;
   case CONSTRAINT_PT_PT_DISTANCE:
     aResult = createConstraintDistancePointPoint(GCS_SCALAR_WRAPPER(theValue), aPoint1, aPoint2);
@@ -355,19 +355,38 @@ ConstraintWrapperPtr createConstraintPointOnEntity(
 
 ConstraintWrapperPtr createConstraintMiddlePoint(
     std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
-    std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity)
+    std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity,
+    std::shared_ptr<PlaneGCSSolver_PointWrapper> theAuxParameters)
 {
+  std::list<GCSConstraintPtr> aConstrList;
+
   GCSPointPtr aPoint = thePoint->point();
   std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(theEntity->entity());
-  if (!aLine)
-    return ConstraintWrapperPtr();
-
-  std::list<GCSConstraintPtr> aConstrList;
-  aConstrList.push_back(
-      GCSConstraintPtr(new GCS::ConstraintPointOnPerpBisector(*aPoint, aLine->p1, aLine->p2)));
-  aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintPointOnLine(*aPoint, *aLine)));
+  if (aLine) {
+    aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintPointOnLine(*aPoint, *aLine)));
+    aConstrList.push_back(
+        GCSConstraintPtr(new GCS::ConstraintPointOnPerpBisector(*aPoint, aLine->p1, aLine->p2)));
+  }
+  else {
+    std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(theEntity->entity());
+    if (anArc) {
+      double* u = theAuxParameters->point()->x;
+      double* diff = theAuxParameters->point()->y;
+      *u = (*anArc->startAngle + *anArc->endAngle) * 0.5;
+      *diff = (*anArc->endAngle - *anArc->startAngle) * 0.5;
+
+      aConstrList.push_back(GCSConstraintPtr(
+          new GCS::ConstraintCurveValue(*aPoint, aPoint->x, *anArc, u)));
+      aConstrList.push_back(GCSConstraintPtr(
+          new GCS::ConstraintCurveValue(*aPoint, aPoint->y, *anArc, u)));
+      aConstrList.push_back(GCSConstraintPtr(
+          new GCS::ConstraintDifference(anArc->startAngle, u, diff)));
+      aConstrList.push_back(GCSConstraintPtr(
+          new GCS::ConstraintDifference(u, anArc->endAngle, diff)));
+    }
+  }
 
-  return ConstraintWrapperPtr(
+  return aConstrList.empty() ? ConstraintWrapperPtr() : ConstraintWrapperPtr(
       new PlaneGCSSolver_ConstraintWrapper(aConstrList, CONSTRAINT_MIDDLE_POINT));
 }
 
@@ -497,7 +516,23 @@ ConstraintWrapperPtr createConstraintPerpendicular(
 {
   std::shared_ptr<GCS::Line> aLine1 = std::dynamic_pointer_cast<GCS::Line>(theEntity1->entity());
   std::shared_ptr<GCS::Line> aLine2 = std::dynamic_pointer_cast<GCS::Line>(theEntity2->entity());
-  GCSConstraintPtr aNewConstr(new GCS::ConstraintPerpendicular(*(aLine1), *(aLine2)));
+
+  std::shared_ptr<GCS::Circle> aCirc1 =
+      std::dynamic_pointer_cast<GCS::Circle>(theEntity1->entity());
+  std::shared_ptr<GCS::Circle> aCirc2 =
+      std::dynamic_pointer_cast<GCS::Circle>(theEntity2->entity());
+
+  GCSConstraintPtr aNewConstr;
+  if (aLine1 && aLine2)
+    aNewConstr.reset(new GCS::ConstraintPerpendicular(*(aLine1), *(aLine2)));
+  else {
+    if (aLine1 && aCirc2)
+      aCirc1 = aCirc2;
+    else if (aLine2 && aCirc1)
+      aLine1 = aLine2;
+
+    aNewConstr.reset(new GCS::ConstraintPointOnLine(aCirc1->center, *aLine1));
+  }
 
   return ConstraintWrapperPtr(
       new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_PERPENDICULAR));