Salome HOME
updated copyright message
[modules/shaper.git] / src / SketchAPI / SketchAPI_Sketch.cpp
index 6ce7550f005e1bad1fda95aec479f5972fcd4e47..823897f5a6e2213e98c2a0e07d3fa8fd79e7f0ec 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  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
 #include <SketchPlugin_ConstraintPerpendicular.h>
 #include <SketchPlugin_ConstraintRadius.h>
 #include <SketchPlugin_ConstraintRigid.h>
+#include <SketchPlugin_CurveFitting.h>
 #include <SketchPlugin_Trim.h>
 #include <SketchPlugin_Split.h>
 #include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_ConstraintVertical.h>
 #include <SketchPlugin_MacroBSpline.h>
 #include <SketchPlugin_SketchCopy.h>
+#include <SketchPlugin_Offset.h>
 #include <SketcherPrs_Tools.h>
 //--------------------------------------------------------------------------------------
 #include <ModelAPI_Events.h>
@@ -66,6 +68,7 @@
 #include "SketchAPI_MacroEllipse.h"
 #include "SketchAPI_MacroEllipticArc.h"
 #include "SketchAPI_Mirror.h"
+#include "SketchAPI_Offset.h"
 #include "SketchAPI_Point.h"
 #include "SketchAPI_Projection.h"
 #include "SketchAPI_Rectangle.h"
@@ -220,7 +223,7 @@ SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
 }
 
 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
-                    const std::string & theExternalName)
+                    const std::wstring & theExternalName)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
   return SketchPtr(
@@ -346,7 +349,7 @@ std::shared_ptr<SketchAPI_Point>
     compositeFeature()->addFeature(SketchPlugin_Point::ID());
   return PointPtr(new SketchAPI_Point(aFeature, theExternal));
 }
-std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(const std::string & theExternalName)
+std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(const std::wstring & theExternalName)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
     compositeFeature()->addFeature(SketchPlugin_Point::ID());
@@ -365,7 +368,7 @@ std::shared_ptr<SketchAPI_IntersectionPoint> SketchAPI_Sketch::addIntersectionPo
   return anIntersection;
 }
 std::shared_ptr<SketchAPI_IntersectionPoint> SketchAPI_Sketch::addIntersectionPoint(
-    const std::string & theExternalName,
+    const std::wstring & theExternalName,
     bool theKeepResult)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
@@ -398,7 +401,7 @@ std::shared_ptr<SketchAPI_Line>
     compositeFeature()->addFeature(SketchPlugin_Line::ID());
   return LinePtr(new SketchAPI_Line(aFeature, theExternal));
 }
-std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(const std::string & theExternalName)
+std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(const std::wstring & theExternalName)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
     compositeFeature()->addFeature(SketchPlugin_Line::ID());
@@ -422,6 +425,49 @@ std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(
   return RectanglePtr(new SketchAPI_Rectangle(aFeature, theStartPoint, theEndPoint));
 }
 
+static std::shared_ptr<GeomAPI_Pnt2d> pointCoordinates(
+    const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & thePoint)
+{
+  if (thePoint.first)
+    return thePoint.first;
+
+  AttributePtr anAttr = thePoint.second.attr();
+  if (thePoint.second.object()) {
+    FeaturePtr aFeature = ModelAPI_Feature::feature(thePoint.second.object());
+    if (aFeature)
+      anAttr = aFeature->attribute(SketchPlugin_Point::COORD_ID());
+  }
+
+  std::shared_ptr<GeomDataAPI_Point2D> aPntAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr);
+  if (aPntAttr)
+    return aPntAttr->pnt();
+  return std::shared_ptr<GeomAPI_Pnt2d>();
+}
+
+std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangleCentered(
+    const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & theCenter,
+    const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & theCorner)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+    compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
+  RectanglePtr aRect(new SketchAPI_Rectangle(aFeature));
+  fillAttribute("RectangleTypeCentered", aRect->type());
+  if (!theCenter.second.isEmpty())
+    fillAttribute(theCenter.second, aRect->centerPointRef());
+  fillAttribute(pointCoordinates(theCenter), aRect->centerPoint());
+  fillAttribute(pointCoordinates(theCorner), aRect->cornerPoint());
+  aRect->execute();
+
+  if (!theCorner.second.isEmpty() && aRect->linesList()->size() > 1) {
+    // get start point of the last line in rectangle and apply coindidence constraint
+    FeaturePtr aLine = ModelAPI_Feature::feature(aRect->linesList()->object(3));
+    AttributePtr aEndPnt = aLine->attribute(SketchPlugin_Line::START_ID());
+    setCoincident(ModelHighAPI_RefAttr(aEndPnt), theCorner.second);
+  }
+  return aRect;
+}
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(double theCenterX,
                                                               double theCenterY,
@@ -490,7 +536,7 @@ std::shared_ptr<SketchAPI_Circle>
   return CirclePtr(new SketchAPI_Circle(aFeature, theExternal));
 }
 
-std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(const std::string & theExternalName)
+std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(const std::wstring & theExternalName)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
@@ -584,7 +630,7 @@ std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const ModelHighAPI_Selec
   return ArcPtr(new SketchAPI_Arc(aFeature, theExternal));
 }
 
-std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const std::string & theExternalName)
+std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const std::wstring & theExternalName)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
@@ -659,7 +705,7 @@ std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
 }
 
 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
-    const std::string & theExternalName)
+    const std::wstring & theExternalName)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
@@ -710,7 +756,7 @@ std::shared_ptr<SketchAPI_EllipticArc> SketchAPI_Sketch::addEllipticArc(
 }
 
 std::shared_ptr<SketchAPI_EllipticArc> SketchAPI_Sketch::addEllipticArc(
-    const std::string & theExternalName)
+    const std::wstring & theExternalName)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID());
@@ -794,25 +840,79 @@ std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addSpline(
 }
 
 //--------------------------------------------------------------------------------------
-std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
-    const ModelHighAPI_Selection & theExternalFeature,
-    bool theKeepResult)
+static std::shared_ptr<SketchAPI_BSpline> buildInterpolation(
+    const CompositeFeaturePtr& theSketch,
+    const FeaturePtr& theCurveFittingFeature,
+    const std::list<ModelHighAPI_RefAttr>& points,
+    const bool periodic,
+    const bool closed)
+{
+  AttributeBooleanPtr aPeriodicAttr =
+      theCurveFittingFeature->boolean(SketchPlugin_CurveFitting::PERIODIC_ID());
+  fillAttribute(periodic, aPeriodicAttr);
+  AttributeBooleanPtr aClosedAttr =
+      theCurveFittingFeature->boolean(SketchPlugin_CurveFitting::CLOSED_ID());
+  fillAttribute(closed, aClosedAttr);
+  AttributeRefAttrListPtr aPointsAttr =
+      theCurveFittingFeature->refattrlist(SketchPlugin_CurveFitting::POINTS_ID());
+  fillAttribute(points, aPointsAttr);
+  apply(); // to execute and kill the macro-feature
+
+  // find created B-spline feature
+  BSplinePtr aBSpline;
+  const std::string& aKindToFind =
+      periodic ? SketchPlugin_BSplinePeriodic::ID() : SketchPlugin_BSpline::ID();
+  int aNbSubs = theSketch->numberOfSubs();
+  for (int anIndex = aNbSubs - 1; anIndex >= 0; --anIndex) {
+    FeaturePtr aFeature = theSketch->subFeature(anIndex);
+    if (aFeature->getKind() == aKindToFind) {
+      aBSpline.reset(periodic ? new SketchAPI_BSplinePeriodic(aFeature)
+        : new SketchAPI_BSpline(aFeature));
+      aBSpline->execute();
+      break;
+    }
+  }
+  return aBSpline;
+}
+
+std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addInterpolation(
+    const std::list<ModelHighAPI_RefAttr>& points,
+    const bool periodic,
+    const bool closed)
 {
-  std::shared_ptr<ModelAPI_Feature> aFeature =
-    compositeFeature()->addFeature(SketchPlugin_Projection::ID());
-  ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalFeature));
-  aProjection->setIncludeToResult(theKeepResult);
-  return aProjection;
+  CompositeFeaturePtr aSketch = compositeFeature();
+  FeaturePtr anInterpFeature = aSketch->addFeature(SketchPlugin_CurveFitting::ID());
+  anInterpFeature->string(SketchPlugin_CurveFitting::TYPE_ID())
+      ->setValue(SketchPlugin_CurveFitting::TYPE_INTERPOLATION_ID());
+  return buildInterpolation(aSketch, anInterpFeature, points, periodic, closed);
 }
 
+std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addApproximation(
+    const std::list<ModelHighAPI_RefAttr>& points,
+    const ModelHighAPI_Double& precision,
+    const bool periodic,
+    const bool closed)
+{
+  CompositeFeaturePtr aSketch = compositeFeature();
+  FeaturePtr anInterpFeature = aSketch->addFeature(SketchPlugin_CurveFitting::ID());
+  anInterpFeature->string(SketchPlugin_CurveFitting::TYPE_ID())
+      ->setValue(SketchPlugin_CurveFitting::TYPE_APPROXIMATION_ID());
+  fillAttribute(precision, anInterpFeature->real(SketchPlugin_CurveFitting::PRECISION_ID()));
+  return buildInterpolation(aSketch, anInterpFeature, points, periodic, closed);
+}
+
+//--------------------------------------------------------------------------------------
 std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
-    const std::string & theExternalName,
-    bool theKeepResult)
+    const ModelHighAPI_Selection & theExternalFeature,
+    bool keepResult,
+    bool keepRefToOriginal)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
     compositeFeature()->addFeature(SketchPlugin_Projection::ID());
-  ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalName));
-  aProjection->setIncludeToResult(theKeepResult);
+  ProjectionPtr aProjection(new SketchAPI_Projection(aFeature));
+  aProjection->setIncludeToResult(keepResult);
+  aProjection->setKeepReferenceToOriginal(keepRefToOriginal);
+  aProjection->setExternalFeature(theExternalFeature);
   return aProjection;
 }
 
@@ -826,6 +926,18 @@ std::shared_ptr<SketchAPI_Mirror> SketchAPI_Sketch::addMirror(
   return MirrorPtr(new SketchAPI_Mirror(aFeature, theMirrorLine, theObjects));
 }
 
+//--------------------------------------------------------------------------------------
+std::shared_ptr<SketchAPI_Offset> SketchAPI_Sketch::addOffset(
+    const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
+    const ModelHighAPI_Double & theValue,
+    const bool theReversed,
+    const std::string & theJointType)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+    compositeFeature()->addFeature(SketchPlugin_Offset::ID());
+  return OffsetPtr(new SketchAPI_Offset(aFeature, theObjects, theValue, theReversed, theJointType));
+}
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<SketchAPI_Translation> SketchAPI_Sketch::addTranslation(
     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
@@ -918,7 +1030,8 @@ std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngle(
 
   if (aVersion == SketchPlugin_ConstraintAngle::THE_VERSION_1) {
     std::string aTypeLC = theType;
-    std::transform(aTypeLC.begin(), aTypeLC.end(), aTypeLC.begin(), ::tolower);
+    std::transform(aTypeLC.begin(), aTypeLC.end(), aTypeLC.begin(),
+                   [](char c) { return static_cast<char>(::tolower(c)); });
     if (aTypeLC == "supplementary")
       aType = (int)SketcherPrs_Tools::ANGLE_COMPLEMENTARY;
     else if (aTypeLC == "backward")
@@ -1472,7 +1585,7 @@ void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const
         aBase->attribute(SketchPlugin_Sketch::DIRX_ID()))->dir();
 
     // Check the plane is coordinate plane
-    std::string aPlaneName = defaultPlane(anOrigin, aNormal, aDirX);
+    std::wstring aPlaneName = defaultPlane(anOrigin, aNormal, aDirX);
     if(anExternal->context()) { // checking for selected planes
       if (!aPlaneName.empty()
           && anExternal->context()->data()