Salome HOME
Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003)
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_FeatureBuilder.cpp
index 376bab37f6f266909a94645cd3e89b84d65c03e2..400319aed4bd9804a46ec5c2c118da1d8473c9d7 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_FeatureBuilder.h>
 #include <PlaneGCSSolver_EdgeWrapper.h>
 #include <PlaneGCSSolver_PointWrapper.h>
 #include <PlaneGCSSolver_ScalarWrapper.h>
+#include <PlaneGCSSolver_BooleanWrapper.h>
+#include <PlaneGCSSolver_Tools.h>
 
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_Circle.h>
+#include <SketchPlugin_Ellipse.h>
+#include <SketchPlugin_EllipticArc.h>
 #include <SketchPlugin_IntersectionPoint.h>
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_Point.h>
@@ -40,6 +43,9 @@ static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
 static EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
                                   PlaneGCSSolver_Storage*      theStorage);
+static EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes);
+static EntityWrapperPtr createEllipticArc(const AttributeEntityMap& theAttributes,
+                                          PlaneGCSSolver_Storage*   theStorage);
 
 
 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
@@ -90,6 +96,12 @@ EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeat
   // Arc
   else if (aFeatureKind == SketchPlugin_Arc::ID())
     aResult = createArc(myAttributes, myStorage);
+  // Ellipse
+  else if (aFeatureKind == SketchPlugin_Ellipse::ID())
+    aResult = createEllipse(myAttributes);
+  // Arc of ellipse
+  else if (aFeatureKind == SketchPlugin_EllipticArc::ID())
+    aResult = createEllipticArc(myAttributes, myStorage);
   // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
   else if (aFeatureKind == SketchPlugin_Point::ID() ||
            aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
@@ -163,45 +175,117 @@ EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
                            PlaneGCSSolver_Storage*      theStorage)
 {
   std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
+  BooleanWrapperPtr isReversed;
 
   // Base attributes of arc (center, start and end points)
   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
   for (; anIt != theAttributes.end(); ++anIt) {
     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
-    if (!aPoint)
-      continue;
-
-    if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
-      aNewArc->center = *(aPoint->point());
-    else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
-      aNewArc->start = *(aPoint->point());
-    else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
-      aNewArc->end = *(aPoint->point());
+    if (aPoint) {
+      if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
+        aNewArc->center = *(aPoint->point());
+      else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
+        aNewArc->start = *(aPoint->point());
+      else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
+        aNewArc->end = *(aPoint->point());
+    }
+    else {
+      // reversed flag
+      isReversed = std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(anIt->second);
+    }
   }
 
-  // Additional atrtributes of arc necessary for PlaneGCS solver
+  // Additional attributes of arc necessary for PlaneGCS solver
   // (start and end angles, radius)
   aNewArc->startAngle = createParameter(theStorage);
   aNewArc->endAngle   = createParameter(theStorage);
   aNewArc->rad        = createParameter(theStorage);
 
-  static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
-  std::shared_ptr<GeomAPI_Pnt2d> aCenter(
-      new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
-  std::shared_ptr<GeomAPI_Pnt2d> aStart(
-      new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
+  EdgeWrapperPtr anArcWrapper(new PlaneGCSSolver_EdgeWrapper(aNewArc));
+  anArcWrapper->setReversed(isReversed);
+  PlaneGCSSolver_Tools::recalculateArcParameters(anArcWrapper);
 
-  *aNewArc->rad = aStart->distance(aCenter);
+  return anArcWrapper;
+}
 
-  std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
-  *aNewArc->startAngle = OX->angle(aDir);
+EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes)
+{
+  std::shared_ptr<GCS::Ellipse> aNewEllipse(new GCS::Ellipse);
 
-  aDir = std::shared_ptr<GeomAPI_Dir2d>(
-      new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
-  *aNewArc->endAngle = OX->angle(aDir);
+  std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
 
-  return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewArc));
+  AttributeEntityMap::const_iterator anIt = theAttributes.begin();
+  for (; anIt != theAttributes.end(); ++anIt) {
+    std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
+        std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
+    if (aPoint) {
+      if (anIt->first->id() == SketchPlugin_Ellipse::CENTER_ID())
+        aNewEllipse->center = *(aPoint->point());
+      else if (anIt->first->id() == SketchPlugin_Ellipse::FIRST_FOCUS_ID())
+        aNewEllipse->focus1 = *(aPoint->point());
+      else
+        anAdditionalAttributes[anIt->first->id()] = anIt->second;
+    }
+    else if (anIt->first->id() == SketchPlugin_Ellipse::MINOR_RADIUS_ID()) {
+      ScalarWrapperPtr aScalar =
+          std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
+      aNewEllipse->radmin = aScalar->scalar();
+    }
+    else
+      anAdditionalAttributes[anIt->first->id()] = anIt->second;
+  }
+
+  EntityWrapperPtr anEllipseWrapper(new PlaneGCSSolver_EdgeWrapper(aNewEllipse));
+  anEllipseWrapper->setAdditionalAttributes(anAdditionalAttributes);
+  return anEllipseWrapper;
+}
+
+EntityWrapperPtr createEllipticArc(const AttributeEntityMap& theAttributes,
+                                   PlaneGCSSolver_Storage*   theStorage)
+{
+  std::shared_ptr<GCS::ArcOfEllipse> aNewArc(new GCS::ArcOfEllipse);
+
+  BooleanWrapperPtr isReversed;
+  std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
+
+  AttributeEntityMap::const_iterator anIt = theAttributes.begin();
+  for (; anIt != theAttributes.end(); ++anIt) {
+    std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
+        std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
+    if (aPoint) {
+      if (anIt->first->id() == SketchPlugin_EllipticArc::CENTER_ID())
+        aNewArc->center = *(aPoint->point());
+      else if (anIt->first->id() == SketchPlugin_EllipticArc::FIRST_FOCUS_ID())
+        aNewArc->focus1 = *(aPoint->point());
+      else if (anIt->first->id() == SketchPlugin_EllipticArc::START_POINT_ID())
+        aNewArc->start = *(aPoint->point());
+      else if (anIt->first->id() == SketchPlugin_EllipticArc::END_POINT_ID())
+        aNewArc->end = *(aPoint->point());
+      else
+        anAdditionalAttributes[anIt->first->id()] = anIt->second;
+    }
+    else if (anIt->first->id() == SketchPlugin_EllipticArc::MINOR_RADIUS_ID()) {
+      ScalarWrapperPtr aScalar =
+          std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
+      aNewArc->radmin = aScalar->scalar();
+    }
+    else if (anIt->first->id() == SketchPlugin_EllipticArc::REVERSED_ID())
+      isReversed = std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(anIt->second);
+    else
+      anAdditionalAttributes[anIt->first->id()] = anIt->second;
+  }
+
+  // Additional attributes of elliptic arc necessary for PlaneGCS solver (start and end angles)
+  aNewArc->startAngle = createParameter(theStorage);
+  aNewArc->endAngle = createParameter(theStorage);
+
+  EdgeWrapperPtr anEllipseWrapper(new PlaneGCSSolver_EdgeWrapper(aNewArc));
+  anEllipseWrapper->setReversed(isReversed);
+  anEllipseWrapper->setAdditionalAttributes(anAdditionalAttributes);
+  PlaneGCSSolver_Tools::recalculateArcParameters(anEllipseWrapper);
+
+  return anEllipseWrapper;
 }
 
 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
@@ -209,7 +293,8 @@ bool isAttributeApplicable(const std::string& theAttrName, const std::string& th
   if (theOwnerName == SketchPlugin_Arc::ID()) {
     return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
            theAttrName == SketchPlugin_Arc::START_ID() ||
-           theAttrName == SketchPlugin_Arc::END_ID();
+           theAttrName == SketchPlugin_Arc::END_ID() ||
+           theAttrName == SketchPlugin_Arc::REVERSED_ID();
   }
   else if (theOwnerName == SketchPlugin_Circle::ID()) {
     return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
@@ -219,6 +304,31 @@ bool isAttributeApplicable(const std::string& theAttrName, const std::string& th
     return theAttrName == SketchPlugin_Line::START_ID() ||
            theAttrName == SketchPlugin_Line::END_ID();
   }
+  else if (theOwnerName == SketchPlugin_Ellipse::ID()) {
+    return theAttrName == SketchPlugin_Ellipse::CENTER_ID() ||
+           theAttrName == SketchPlugin_Ellipse::FIRST_FOCUS_ID() ||
+           theAttrName == SketchPlugin_Ellipse::SECOND_FOCUS_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_END_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MAJOR_RADIUS_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MINOR_RADIUS_ID();
+  }
+  else if (theOwnerName == SketchPlugin_EllipticArc::ID()) {
+    return theAttrName == SketchPlugin_EllipticArc::CENTER_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::FIRST_FOCUS_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::SECOND_FOCUS_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_START_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_END_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MAJOR_RADIUS_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MINOR_RADIUS_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::START_POINT_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::END_POINT_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::REVERSED_ID();
+  }
 
   // suppose that all remaining features are points
   return theAttrName == SketchPlugin_Point::COORD_ID();