Salome HOME
Merge branch 'master' into occ/bsplines
[modules/shaper.git] / src / SketchAPI / SketchAPI_Sketch.cpp
index 5a329558fd3e2217782f7aec38c9a864297895c3..a93c26e05a1f586beb5f48ff95fd9ec369ea28c7 100644 (file)
 #include <ModelHighAPI_Tools.h>
 //--------------------------------------------------------------------------------------
 #include "SketchAPI_Arc.h"
+#include "SketchAPI_BSpline.h"
 #include "SketchAPI_Circle.h"
 #include "SketchAPI_Ellipse.h"
+#include "SketchAPI_EllipticArc.h"
 #include "SketchAPI_IntersectionPoint.h"
 #include "SketchAPI_Line.h"
 #include "SketchAPI_MacroArc.h"
 #include "SketchAPI_MacroCircle.h"
 #include "SketchAPI_MacroEllipse.h"
+#include "SketchAPI_MacroEllipticArc.h"
 #include "SketchAPI_Mirror.h"
 #include "SketchAPI_Point.h"
 #include "SketchAPI_Projection.h"
@@ -73,6 +76,8 @@
 #include <GeomAPI_ShapeExplorer.h>
 #include <GeomAPI_XY.h>
 #include <GeomAlgoAPI_SketchBuilder.h>
+
+#include <algorithm>
 #include <cmath>
 //--------------------------------------------------------------------------------------
 SketchAPI_Sketch::SketchAPI_Sketch(
@@ -642,6 +647,83 @@ std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
   return EllipsePtr(new SketchAPI_Ellipse(aFeature, theExternalName));
 }
 
+//--------------------------------------------------------------------------------------
+std::shared_ptr<SketchAPI_EllipticArc> SketchAPI_Sketch::addEllipticArc(
+    double theCenterX, double theCenterY,
+    double theFocusX, double theFocusY,
+    double theStartX, double theStartY,
+    double theEndX, double theEndY,
+    bool theInversed)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+      compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID());
+  return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature,
+      theCenterX, theCenterY,
+      theFocusX, theFocusY,
+      theStartX, theStartY,
+      theEndX, theEndY,
+      theInversed));
+}
+
+std::shared_ptr<SketchAPI_MacroEllipticArc> SketchAPI_Sketch::addEllipticArc(
+    const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr>& theCenter,
+    const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr>& theMajorAxisPoint,
+    const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr>& theStartPoint,
+    const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr>& theEndPoint,
+    bool theInversed)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+      compositeFeature()->addFeature(SketchPlugin_MacroEllipticArc::ID());
+  return MacroEllipticArcPtr(new SketchAPI_MacroEllipticArc(aFeature,
+      theCenter.first, theCenter.second,
+      theMajorAxisPoint.first, theMajorAxisPoint.second,
+      theStartPoint.first, theStartPoint.second,
+      theEndPoint.first, theEndPoint.second,
+      theInversed));
+}
+
+std::shared_ptr<SketchAPI_EllipticArc> SketchAPI_Sketch::addEllipticArc(
+    const ModelHighAPI_Selection & theExternal)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+      compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID());
+  return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, theExternal));
+}
+
+std::shared_ptr<SketchAPI_EllipticArc> SketchAPI_Sketch::addEllipticArc(
+    const std::string & theExternalName)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+      compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID());
+  return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, theExternalName));
+}
+
+//--------------------------------------------------------------------------------------
+
+std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addSpline(
+    const ModelHighAPI_Selection & external,
+    const int degree,
+    const std::list<std::shared_ptr<GeomAPI_Pnt2d> >& poles,
+    const std::list<ModelHighAPI_Double>& weights,
+    const std::list<ModelHighAPI_Double>& knots,
+    const std::list<ModelHighAPI_Integer>& multiplicities,
+    const bool periodic)
+{
+  FeaturePtr aFeature = compositeFeature()->addFeature(
+    periodic ? SketchPlugin_BSplinePeriodic::ID() : SketchPlugin_BSpline::ID());
+
+  BSplinePtr aBSpline(periodic ? new SketchAPI_BSplinePeriodic(aFeature)
+                               : new SketchAPI_BSpline(aFeature));
+  if (external.variantType() != ModelHighAPI_Selection::VT_Empty)
+    aBSpline->setByExternal(external);
+  else if (knots.empty() || multiplicities.empty())
+    aBSpline->setByDegreePolesAndWeights(degree, poles, weights);
+  else
+    aBSpline->setByParameters(degree, poles, weights, knots, multiplicities);
+
+  return aBSpline;
+}
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
     const ModelHighAPI_Selection & theExternalFeature,
@@ -745,16 +827,38 @@ std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addTrim(
 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngle(
     const ModelHighAPI_RefAttr & theLine1,
     const ModelHighAPI_RefAttr & theLine2,
-    const ModelHighAPI_Double & theValue)
+    const ModelHighAPI_Double & theValue,
+    const std::string& theType)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
-  fillAttribute(SketcherPrs_Tools::ANGLE_DIRECT,
-      aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
-  // fill the value before llines to avoid calculation of angle value by the Angle feature
+
+  const int aVersion = theType.empty() ? SketchPlugin_ConstraintAngle::THE_VERSION_0
+                                       : SketchPlugin_ConstraintAngle::THE_VERSION_1;
+  fillAttribute(aVersion, aFeature->integer(SketchPlugin_ConstraintAngle::VERSION_ID()));
+
+  int aType = (int)SketcherPrs_Tools::ANGLE_DIRECT;
+  fillAttribute(aType, aFeature->integer(SketchPlugin_ConstraintAngle::PREV_TYPE_ID()));
+  fillAttribute(aType, aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
+
+  if (aVersion == SketchPlugin_ConstraintAngle::THE_VERSION_0)
+    fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
+
   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
-  fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
+
+  if (aVersion == SketchPlugin_ConstraintAngle::THE_VERSION_1) {
+    std::string aTypeLC = theType;
+    std::transform(aTypeLC.begin(), aTypeLC.end(), aTypeLC.begin(), ::tolower);
+    if (aTypeLC == "supplementary")
+      aType = (int)SketcherPrs_Tools::ANGLE_COMPLEMENTARY;
+    else if (aTypeLC == "backward")
+      aType = (int)SketcherPrs_Tools::ANGLE_BACKWARD;
+
+    fillAttribute(aType, aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
+    fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
+  }
+
   aFeature->execute();
   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
 }
@@ -766,11 +870,13 @@ std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleComplementary(
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
+  fillAttribute(SketchPlugin_ConstraintAngle::THE_VERSION_0,
+      aFeature->integer(SketchPlugin_ConstraintAngle::VERSION_ID()));
   fillAttribute(SketcherPrs_Tools::ANGLE_COMPLEMENTARY,
       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
+  fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
-  fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
   aFeature->execute();
   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
 }
@@ -782,11 +888,13 @@ std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleBackward(
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
+  fillAttribute(SketchPlugin_ConstraintAngle::THE_VERSION_0,
+      aFeature->integer(SketchPlugin_ConstraintAngle::VERSION_ID()));
   fillAttribute(SketcherPrs_Tools::ANGLE_BACKWARD,
       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
+  fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
-  fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
   aFeature->execute();
   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
 }
@@ -1093,14 +1201,29 @@ static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnArc(const FeaturePtr& theFeat
   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(x, y));
 }
 
-static std::shared_ptr<GeomAPI_Pnt2d> pointOnEllipse(const FeaturePtr& theFeature)
+static std::shared_ptr<GeomAPI_Pnt2d> pointOnEllipse(const FeaturePtr& theFeature,
+                                                     bool isEllipse = true)
 {
+  const std::string& anAttrName = isEllipse ? SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() :
+                                  SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID();
   AttributePoint2DPtr aMajorAxisEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      theFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()));
+      theFeature->attribute(anAttrName));
   return aMajorAxisEnd ? aMajorAxisEnd->pnt() : std::shared_ptr<GeomAPI_Pnt2d>();
 }
 
-static std::shared_ptr<GeomAPI_Pnt2d> middlePoint(const ObjectPtr& theObject)
+static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnBSpline(const FeaturePtr& theFeature,
+                                                           const CompositeFeaturePtr& theSketch)
+{
+  GeomAPI_Edge anEdge(theFeature->lastResult()->shape());
+  GeomPointPtr aMiddle = anEdge.middlePoint();
+
+  std::shared_ptr<SketchPlugin_Sketch> aSketch =
+      std::dynamic_pointer_cast<SketchPlugin_Sketch>(theSketch);
+  return aSketch->to2D(aMiddle);
+}
+
+static std::shared_ptr<GeomAPI_Pnt2d> middlePoint(const ObjectPtr& theObject,
+                                                  const CompositeFeaturePtr& theSketch)
 {
   std::shared_ptr<GeomAPI_Pnt2d> aMiddlePoint;
   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
@@ -1117,6 +1240,11 @@ static std::shared_ptr<GeomAPI_Pnt2d> middlePoint(const ObjectPtr& theObject)
       aMiddlePoint = middlePointOnArc(aFeature);
     else if (aFeatureKind == SketchPlugin_Ellipse::ID())
       aMiddlePoint = pointOnEllipse(aFeature);
+    else if (aFeatureKind == SketchPlugin_EllipticArc::ID())
+      aMiddlePoint = pointOnEllipse(aFeature, false);
+    else if (aFeatureKind == SketchPlugin_BSpline::ID() ||
+             aFeatureKind == SketchPlugin_BSplinePeriodic::ID())
+      aMiddlePoint = middlePointOnBSpline(aFeature, theSketch);
   }
   return aMiddlePoint;
 }
@@ -1131,7 +1259,7 @@ void SketchAPI_Sketch::move(const ModelHighAPI_RefAttr& theMovedEntity,
   if (aMessage->movedAttribute())
     anOriginalPosition = pointCoordinates(aMessage->movedAttribute());
   else
-    anOriginalPosition = middlePoint(aMessage->movedObject());
+    anOriginalPosition = middlePoint(aMessage->movedObject(), compositeFeature());
 
   if (!anOriginalPosition)
     return; // something has gone wrong, do not process movement
@@ -1337,5 +1465,7 @@ void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const
       theDumper << *aFIt;
     }
     theDumper << "\n" << aSpaceShift << " ])" << std::endl;
+    // call model.do() for correct update of the document's labels related to the changed faces
+    theDumper << "model.do()" << std::endl;
   }
 }