Salome HOME
Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003)
authorazv <azv@opencascade.com>
Thu, 26 Sep 2019 06:44:46 +0000 (09:44 +0300)
committerazv <azv@opencascade.com>
Thu, 26 Sep 2019 06:45:09 +0000 (09:45 +0300)
Python API for elliptic arc

22 files changed:
src/ModelHighAPI/ModelHighAPI_Macro.h
src/SketchAPI/CMakeLists.txt
src/SketchAPI/SketchAPI.i
src/SketchAPI/SketchAPI_Ellipse.cpp
src/SketchAPI/SketchAPI_Ellipse.h
src/SketchAPI/SketchAPI_EllipticArc.cpp [new file with mode: 0644]
src/SketchAPI/SketchAPI_EllipticArc.h [new file with mode: 0644]
src/SketchAPI/SketchAPI_MacroEllipse.cpp
src/SketchAPI/SketchAPI_MacroEllipticArc.cpp [new file with mode: 0644]
src/SketchAPI/SketchAPI_MacroEllipticArc.h [new file with mode: 0644]
src/SketchAPI/SketchAPI_Sketch.cpp
src/SketchAPI/SketchAPI_Sketch.h
src/SketchAPI/SketchAPI_SketchEntity.cpp
src/SketchAPI/SketchAPI_swig.h
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_EllipticArc.cpp
src/SketchPlugin/SketchPlugin_EllipticArc.h
src/SketchPlugin/SketchPlugin_MacroEllipticArc.cpp
src/SketchPlugin/SketchPlugin_MacroEllipticArc.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp
src/SketchSolver/SketchSolver_ConstraintMirror.cpp

index 7b7364103291f818e5ebaa2809305190178fcc36..7fd21232ced3b794e80740b2a59e30d85c3f8ba3 100644 (file)
     END_INIT() \
   public:
 
+//--------------------------------------------------------------------------------------
+#define INTERFACE_13(KIND, \
+                     N_0, AN_0, T_0, C_0, \
+                     N_1, AN_1, T_1, C_1, \
+                     N_2, AN_2, T_2, C_2, \
+                     N_3, AN_3, T_3, C_3, \
+                     N_4, AN_4, T_4, C_4, \
+                     N_5, AN_5, T_5, C_5, \
+                     N_6, AN_6, T_6, C_6, \
+                     N_7, AN_7, T_7, C_7, \
+                     N_8, AN_8, T_8, C_8, \
+                     N_9, AN_9, T_9, C_9, \
+                     N_10, AN_10, T_10, C_10, \
+                     N_11, AN_11, T_11, C_11, \
+                     N_12, AN_12, T_12, C_12) \
+  public: \
+    INTERFACE_COMMON(KIND) \
+    DEFINE_ATTRIBUTE(N_0, T_0, C_0) \
+    DEFINE_ATTRIBUTE(N_1, T_1, C_1) \
+    DEFINE_ATTRIBUTE(N_2, T_2, C_2) \
+    DEFINE_ATTRIBUTE(N_3, T_3, C_3) \
+    DEFINE_ATTRIBUTE(N_4, T_4, C_4) \
+    DEFINE_ATTRIBUTE(N_5, T_5, C_5) \
+    DEFINE_ATTRIBUTE(N_6, T_6, C_6) \
+    DEFINE_ATTRIBUTE(N_7, T_7, C_7) \
+    DEFINE_ATTRIBUTE(N_8, T_8, C_8) \
+    DEFINE_ATTRIBUTE(N_9, T_9, C_9) \
+    DEFINE_ATTRIBUTE(N_10, T_10, C_10) \
+    DEFINE_ATTRIBUTE(N_11, T_11, C_11) \
+    DEFINE_ATTRIBUTE(N_12, T_12, C_12) \
+  protected: \
+    START_INIT() \
+      SET_ATTRIBUTE(N_0, T_0, AN_0) \
+      SET_ATTRIBUTE(N_1, T_1, AN_1) \
+      SET_ATTRIBUTE(N_2, T_2, AN_2) \
+      SET_ATTRIBUTE(N_3, T_3, AN_3) \
+      SET_ATTRIBUTE(N_4, T_4, AN_4) \
+      SET_ATTRIBUTE(N_5, T_5, AN_5) \
+      SET_ATTRIBUTE(N_6, T_6, AN_6) \
+      SET_ATTRIBUTE(N_7, T_7, AN_7) \
+      SET_ATTRIBUTE(N_8, T_8, AN_8) \
+      SET_ATTRIBUTE(N_9, T_9, AN_9) \
+      SET_ATTRIBUTE(N_10, T_10, AN_10) \
+      SET_ATTRIBUTE(N_11, T_11, AN_11) \
+      SET_ATTRIBUTE(N_12, T_12, AN_12) \
+    END_INIT() \
+  public:
+
 //--------------------------------------------------------------------------------------
 #define INTERFACE_14(KIND, \
                      N_0, AN_0, T_0, C_0, \
index ff40200abe4509d4e08d898cdb8d34af5ebfcd11..9d2b423d8a244dc27cab1286d334d11b2ec35c43 100644 (file)
@@ -26,11 +26,13 @@ SET(PROJECT_HEADERS
   SketchAPI_Constraint.h
   SketchAPI_ConstraintAngle.h
   SketchAPI_Ellipse.h
+  SketchAPI_EllipticArc.h
   SketchAPI_IntersectionPoint.h
   SketchAPI_Line.h
   SketchAPI_MacroArc.h
   SketchAPI_MacroCircle.h
   SketchAPI_MacroEllipse.h
+  SketchAPI_MacroEllipticArc.h
   SketchAPI_Mirror.h
   SketchAPI_Point.h
   SketchAPI_Projection.h
@@ -47,11 +49,13 @@ SET(PROJECT_SOURCES
   SketchAPI_Constraint.cpp
   SketchAPI_ConstraintAngle.cpp
   SketchAPI_Ellipse.cpp
+  SketchAPI_EllipticArc.cpp
   SketchAPI_IntersectionPoint.cpp
   SketchAPI_Line.cpp
   SketchAPI_MacroArc.cpp
   SketchAPI_MacroCircle.cpp
   SketchAPI_MacroEllipse.cpp
+  SketchAPI_MacroEllipticArc.cpp
   SketchAPI_Mirror.cpp
   SketchAPI_Point.cpp
   SketchAPI_Projection.cpp
index 8cbda8d3b7d723547cfd048ca9b4f6943ca4c605..08f87c104fe754f46b9de4453fa37d5094c9f3a3 100644 (file)
@@ -46,6 +46,7 @@
 
 // function with named parameters
 %feature("kwargs") SketchAPI_Ellipse::construction;
+%feature("kwargs") SketchAPI_EllipticArc::construction;
 
 // shared pointers
 %shared_ptr(SketchAPI_Arc)
@@ -54,6 +55,8 @@
 %shared_ptr(SketchAPI_MacroCircle)
 %shared_ptr(SketchAPI_Ellipse)
 %shared_ptr(SketchAPI_MacroEllipse)
+%shared_ptr(SketchAPI_EllipticArc)
+%shared_ptr(SketchAPI_MacroEllipticArc)
 %shared_ptr(SketchAPI_Constraint)
 %shared_ptr(SketchAPI_ConstraintAngle)
 %shared_ptr(SketchAPI_IntersectionPoint)
 %include "SketchAPI_MacroArc.h"
 %include "SketchAPI_Ellipse.h"
 %include "SketchAPI_MacroEllipse.h"
+%include "SketchAPI_EllipticArc.h"
+%include "SketchAPI_MacroEllipticArc.h"
 %include "SketchAPI_Projection.h"
 %include "SketchAPI_Mirror.h"
 %include "SketchAPI_Translation.h"
index 6bcd6c0dc019d36d40f6dd94de01cb3165ff3bd6..19de091d4f9c55c158462332dcb330f6cdeea734 100644 (file)
@@ -147,14 +147,26 @@ void SketchAPI_Ellipse::setMinorRadius(double theMinorRadius)
   execute();
 }
 
-ModelHighAPI_Selection SketchAPI_Ellipse::majorAxis() const
+static const std::list<PairOfStrings>& ellipseAttrAndDumpNames()
 {
-  return ModelHighAPI_Selection();
-}
-
-ModelHighAPI_Selection SketchAPI_Ellipse::minorAxis() const
-{
-  return ModelHighAPI_Selection();
+  static std::list<PairOfStrings> anAttributes;
+  if (anAttributes.empty()) {
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_Ellipse::CENTER_ID(), "center"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_Ellipse::FIRST_FOCUS_ID(), "firstFocus"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_Ellipse::SECOND_FOCUS_ID(), "secondFocus"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(), "majorAxisStart"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID(), "majorAxisEnd"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_Ellipse::MINOR_AXIS_START_ID(), "minorAxisStart"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_Ellipse::MINOR_AXIS_END_ID(), "minorAxisEnd"));
+  }
+  return anAttributes;
 }
 
 static CompositeFeaturePtr sketchForFeature(FeaturePtr theFeature)
@@ -176,11 +188,15 @@ static void createInternalConstraint(const CompositeFeaturePtr& theSketch,
   aConstraint->execute();
 }
 
-static FeaturePtr createPoint(const CompositeFeaturePtr& theSketch,
-                              const FeaturePtr& theEllipse,
-                              const std::string& theCoincident,
-                              const std::string& theAuxOrName)
+static void createPoint(const CompositeFeaturePtr& theSketch,
+                        const FeaturePtr& theEllipse,
+                        const std::string& theCoincident,
+                        const std::string& theAuxOrName,
+                        std::list<FeaturePtr>& theEntities)
 {
+  if (theAuxOrName.empty())
+    return;
+
   AttributePoint2DPtr anElPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       theEllipse->attribute(theCoincident));
 
@@ -204,15 +220,19 @@ static FeaturePtr createPoint(const CompositeFeaturePtr& theSketch,
 
   createInternalConstraint(theSketch, anElPoint, aCoord);
 
-  return aPointFeature;
+  theEntities.push_back(aPointFeature);
 }
 
-static FeaturePtr createAxis(const CompositeFeaturePtr& theSketch,
-                             const FeaturePtr& theEllipse,
-                             const std::string& theCoincidentStart,
-                             const std::string& theCoincidentEnd,
-                             const std::string& theAuxOrName)
+static void createAxis(const CompositeFeaturePtr& theSketch,
+                       const FeaturePtr& theEllipse,
+                       const std::string& theCoincidentStart,
+                       const std::string& theCoincidentEnd,
+                       const std::string& theAuxOrName,
+                       std::list<FeaturePtr>& theEntities)
 {
+  if (theAuxOrName.empty())
+    return;
+
   AttributePoint2DPtr aStartPoint =
       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theEllipse->attribute(theCoincidentStart));
   AttributePoint2DPtr aEndPoint =
@@ -244,7 +264,7 @@ static FeaturePtr createAxis(const CompositeFeaturePtr& theSketch,
   createInternalConstraint(theSketch, aStartPoint, aLineStart);
   createInternalConstraint(theSketch, aEndPoint, aLineEnd);
 
-  return aLineFeature;
+  theEntities.push_back(aLineFeature);
 }
 
 std::list<std::shared_ptr<SketchAPI_SketchEntity> > SketchAPI_Ellipse::construction(
@@ -259,53 +279,54 @@ std::list<std::shared_ptr<SketchAPI_SketchEntity> > SketchAPI_Ellipse::construct
     const std::string& minorAxis) const
 {
   FeaturePtr anEllipse = feature();
-  CompositeFeaturePtr aSketch = sketchForFeature(anEllipse);
+
+  std::list<PairOfStrings> anAttributes = ellipseAttrAndDumpNames();
+  // append start and end attributes for axes
+  anAttributes.push_back(PairOfStrings(SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(),
+                                       SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()));
+  anAttributes.push_back(PairOfStrings(SketchPlugin_Ellipse::MINOR_AXIS_START_ID(),
+                                       SketchPlugin_Ellipse::MINOR_AXIS_END_ID()));
+
+  return buildConstructionEntities(anEllipse, anAttributes, center, firstFocus, secondFocus,
+            majorAxisStart, majorAxisEnd, minorAxisStart, minorAxisEnd, majorAxis, minorAxis);
+}
+
+std::list<std::shared_ptr<SketchAPI_SketchEntity> > SketchAPI_Ellipse::buildConstructionEntities(
+      const FeaturePtr& theEllipse,
+      const std::list<PairOfStrings>& theAttributes,
+      const std::string& theCenter,
+      const std::string& theFirstFocus,
+      const std::string& theSecondFocus,
+      const std::string& theMajorAxisStart,
+      const std::string& theMajorAxisEnd,
+      const std::string& theMinorAxisStart,
+      const std::string& theMinorAxisEnd,
+      const std::string& theMajorAxis,
+      const std::string& theMinorAxis)
+{
+  CompositeFeaturePtr aSketch = sketchForFeature(theEllipse);
 
   std::list<FeaturePtr> anEntities;
-  if (!center.empty()) {
-    anEntities.push_back(
-        createPoint(aSketch, anEllipse, SketchPlugin_Ellipse::CENTER_ID(), center));
-  }
-  if (!firstFocus.empty()) {
-    anEntities.push_back(
-        createPoint(aSketch, anEllipse, SketchPlugin_Ellipse::FIRST_FOCUS_ID(), firstFocus));
-  }
-  if (!secondFocus.empty()) {
-    anEntities.push_back(
-        createPoint(aSketch, anEllipse, SketchPlugin_Ellipse::SECOND_FOCUS_ID(), secondFocus));
-  }
-  if (!majorAxisStart.empty()) {
-    anEntities.push_back(createPoint(aSketch, anEllipse,
-        SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(), majorAxisStart));
-  }
-  if (!majorAxisEnd.empty()) {
-    anEntities.push_back(createPoint(aSketch, anEllipse,
-        SketchPlugin_Ellipse::MAJOR_AXIS_END_ID(), majorAxisEnd));
-  }
-  if (!minorAxisStart.empty()) {
-    anEntities.push_back(createPoint(aSketch, anEllipse,
-        SketchPlugin_Ellipse::MINOR_AXIS_START_ID(), minorAxisStart));
-  }
-  if (!minorAxisEnd.empty()) {
-    anEntities.push_back(createPoint(aSketch, anEllipse,
-        SketchPlugin_Ellipse::MINOR_AXIS_END_ID(), minorAxisEnd));
-  }
-  if (!majorAxis.empty()) {
-    anEntities.push_back(
-        createAxis(aSketch, anEllipse, SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(),
-                   SketchPlugin_Ellipse::MAJOR_AXIS_END_ID(), majorAxis));
-  }
-  if (!minorAxis.empty()) {
-    anEntities.push_back(
-        createAxis(aSketch, anEllipse, SketchPlugin_Ellipse::MINOR_AXIS_START_ID(),
-                   SketchPlugin_Ellipse::MINOR_AXIS_END_ID(), minorAxis));
-  }
+  std::list<PairOfStrings>::const_iterator anAttrIt = theAttributes.begin();
+  createPoint(aSketch, theEllipse, (anAttrIt++)->first, theCenter, anEntities);
+  createPoint(aSketch, theEllipse, (anAttrIt++)->first, theFirstFocus, anEntities);
+  createPoint(aSketch, theEllipse, (anAttrIt++)->first, theSecondFocus, anEntities);
+  createPoint(aSketch, theEllipse, (anAttrIt++)->first, theMajorAxisStart, anEntities);
+  createPoint(aSketch, theEllipse, (anAttrIt++)->first, theMajorAxisEnd, anEntities);
+  createPoint(aSketch, theEllipse, (anAttrIt++)->first, theMinorAxisStart, anEntities);
+  createPoint(aSketch, theEllipse, (anAttrIt++)->first, theMinorAxisEnd, anEntities);
+
+  createAxis(aSketch, theEllipse, anAttrIt->first, anAttrIt->second, theMajorAxis, anEntities);
+  ++anAttrIt;
+  createAxis(aSketch, theEllipse, anAttrIt->first, anAttrIt->second, theMinorAxis, anEntities);
 
   return SketchAPI_SketchEntity::wrap(anEntities);
 }
 
 static void ellipseAttributeAndAuxiliaryFeature(
     const FeaturePtr& theInternalConstraint,
+    const std::pair<std::string, std::string>& theMajorAxisStartEnd,
+    const std::pair<std::string, std::string>& theMinorAxisStartEnd,
     std::map<std::string, FeaturePtr>& theAttrToFeature)
 {
   AttributeRefAttrPtr aRefAttrA =
@@ -325,15 +346,30 @@ static void ellipseAttributeAndAuxiliaryFeature(
     theAttrToFeature[aRefAttrA->attr()->id()] = anAuxFeature;
   else {
     const std::string& anAttrID = aRefAttrA->attr()->id();
-    if (anAttrID == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
-        anAttrID == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID())
+    if (anAttrID == theMajorAxisStartEnd.first || anAttrID == theMajorAxisStartEnd.second)
       theAttrToFeature[MAJOR_AXIS_ID] = anAuxFeature;
-    else if (anAttrID == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
-             anAttrID == SketchPlugin_Ellipse::MINOR_AXIS_END_ID())
+    else if (anAttrID == theMinorAxisStartEnd.first || anAttrID == theMinorAxisStartEnd.second)
       theAttrToFeature[MINOR_AXIS_ID] = anAuxFeature;
   }
 }
 
+void SketchAPI_Ellipse::collectAuxiliaryFeatures(
+    FeaturePtr theEllipse,
+    const std::pair<std::string, std::string>& theMajorAxis,
+    const std::pair<std::string, std::string>& theMinorAxis,
+    std::map<std::string, FeaturePtr>& theAttrToFeature)
+{
+  const std::set<AttributePtr>& aRefs = theEllipse->data()->refsToMe();
+  for (std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
+       aRefIt != aRefs.end(); ++aRefIt) {
+    FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
+    if (anOwner->getKind() == SketchPlugin_ConstraintCoincidenceInternal::ID()) {
+      // process internal constraints only
+      ellipseAttributeAndAuxiliaryFeature(anOwner, theMajorAxis, theMinorAxis, theAttrToFeature);
+    }
+  }
+}
+
 void SketchAPI_Ellipse::dump(ModelHighAPI_Dumper& theDumper) const
 {
   if (isCopy())
@@ -356,58 +392,61 @@ void SketchAPI_Ellipse::dump(ModelHighAPI_Dumper& theDumper) const
 
   // dump auxiliary features produced by ellipse
   std::map<std::string, FeaturePtr> anAuxFeatures;
-  const std::set<AttributePtr>& aRefs = aBase->data()->refsToMe();
-  for (std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
-       aRefIt != aRefs.end(); ++aRefIt) {
-    FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
-    if (anOwner->getKind() != SketchPlugin_ConstraintCoincidenceInternal::ID())
-      continue; // process internal constraints only
-    ellipseAttributeAndAuxiliaryFeature(anOwner, anAuxFeatures);
-  }
+  static const std::pair<std::string, std::string> aMajorAxis(
+      SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(),
+      SketchPlugin_Ellipse::MAJOR_AXIS_END_ID());
+  static const std::pair<std::string, std::string> aMinorAxis(
+      SketchPlugin_Ellipse::MINOR_AXIS_START_ID(),
+      SketchPlugin_Ellipse::MINOR_AXIS_END_ID());
+  collectAuxiliaryFeatures(aBase, aMajorAxis, aMinorAxis, anAuxFeatures);
+
   if (!anAuxFeatures.empty()) {
-    typedef std::pair<std::string, std::string> PairOfStrings;
-    static PairOfStrings anAttributes[] = {
-        PairOfStrings(SketchPlugin_Ellipse::CENTER_ID(), "center"),
-        PairOfStrings(SketchPlugin_Ellipse::FIRST_FOCUS_ID(), "firstFocus"),
-        PairOfStrings(SketchPlugin_Ellipse::SECOND_FOCUS_ID(), "secondFocus"),
-        PairOfStrings(SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(), "majorAxisStart"),
-        PairOfStrings(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID(), "majorAxisEnd"),
-        PairOfStrings(SketchPlugin_Ellipse::MINOR_AXIS_START_ID(), "minorAxisStart"),
-        PairOfStrings(SketchPlugin_Ellipse::MINOR_AXIS_END_ID(), "minorAxisEnd"),
-        PairOfStrings(MAJOR_AXIS_ID, MAJOR_AXIS_ID),
-        PairOfStrings(MINOR_AXIS_ID, MINOR_AXIS_ID)
-    };
-
-    theDumper << "[";
-    bool isFirst = true;
-    for (PairOfStrings* anIt = std::begin(anAttributes);
-         anIt != std::end(anAttributes); ++anIt) {
-      std::map<std::string, FeaturePtr>::iterator aFound = anAuxFeatures.find(anIt->first);
-      if (aFound == anAuxFeatures.end())
-        continue;
-      if (!isFirst)
-        theDumper << ", ";
-      theDumper << theDumper.name(aFound->second, false);
-      theDumper.doNotDumpFeature(aFound->second);
-      isFirst = false;
-    }
-    theDumper << "] = " << theDumper.name(aBase) << ".construction(";
-    isFirst = true;
-    for (PairOfStrings* anIt = std::begin(anAttributes);
-         anIt != std::end(anAttributes); ++anIt) {
-      std::map<std::string, FeaturePtr>::iterator aFound = anAuxFeatures.find(anIt->first);
-      if (aFound == anAuxFeatures.end())
-        continue;
-      if (!isFirst)
-        theDumper << ", ";
-      isFirst = false;
-      theDumper << anIt->second << " = \"";
-      if (aFound->second->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value())
-        theDumper << AUXILIARY_VALUE;
-      else
-        theDumper << aFound->second->name();
-      theDumper << "\"";
-    }
-    theDumper << ")" << std::endl;
+    // a list of attributes to write features in special order
+    const std::list<PairOfStrings>& anAttributes = ellipseAttrAndDumpNames();
+    dumpConstructionEntities(theDumper, aBase, anAttributes, anAuxFeatures);
+  }
+}
+
+void SketchAPI_Ellipse::dumpConstructionEntities(
+    ModelHighAPI_Dumper& theDumper,
+    const FeaturePtr& theEllipse,
+    const std::list<PairOfStrings>& theAttributes,
+    const std::map<std::string, FeaturePtr>& theAuxFeatures)
+{
+  std::list<PairOfStrings> anAttributes = theAttributes;
+  // append axes
+  anAttributes.push_back(PairOfStrings(MAJOR_AXIS_ID, MAJOR_AXIS_ID));
+  anAttributes.push_back(PairOfStrings(MINOR_AXIS_ID, MINOR_AXIS_ID));
+
+  theDumper << "[";
+  bool isFirst = true;
+  for (std::list<PairOfStrings>::iterator anIt = anAttributes.begin();
+        anIt != anAttributes.end(); ++anIt) {
+    std::map<std::string, FeaturePtr>::const_iterator aFound = theAuxFeatures.find(anIt->first);
+    if (aFound == theAuxFeatures.end())
+      continue;
+    if (!isFirst)
+      theDumper << ", ";
+    theDumper << theDumper.name(aFound->second, false);
+    theDumper.doNotDumpFeature(aFound->second);
+    isFirst = false;
+  }
+  theDumper << "] = " << theDumper.name(theEllipse) << ".construction(";
+  isFirst = true;
+  for (std::list<PairOfStrings>::iterator anIt = anAttributes.begin();
+        anIt != anAttributes.end(); ++anIt) {
+    std::map<std::string, FeaturePtr>::const_iterator aFound = theAuxFeatures.find(anIt->first);
+    if (aFound == theAuxFeatures.end())
+      continue;
+    if (!isFirst)
+      theDumper << ", ";
+    isFirst = false;
+    theDumper << anIt->second << " = \"";
+    if (aFound->second->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value())
+      theDumper << AUXILIARY_VALUE;
+    else
+      theDumper << aFound->second->name();
+    theDumper << "\"";
   }
+  theDumper << ")" << std::endl;
 }
index ee79357c866912ef1fce34db7b0023167a452935..598d41356f086267419e656675dca3e6e99c8688 100644 (file)
@@ -27,6 +27,8 @@
 
 class ModelHighAPI_Selection;
 
+typedef std::pair<std::string, std::string> PairOfStrings;
+
 /// \class SketchAPI_Ellipse
 /// \ingroup CPPHighAPI
 /// \brief Interface for Ellipse feature.
@@ -113,7 +115,7 @@ public:
 
   /// Set center.
   SKETCHAPI_EXPORT
-  void setCenter(const std::shared_ptr<GeomAPI_Pnt2d> & theCenter);
+  void setCenter(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter);
 
   /// Set focus.
   SKETCHAPI_EXPORT
@@ -121,20 +123,12 @@ public:
 
   /// Set focus.
   SKETCHAPI_EXPORT
-  void setFocus(const std::shared_ptr<GeomAPI_Pnt2d> & theCenter);
+  void setFocus(const std::shared_ptr<GeomAPI_Pnt2d>& theFocus);
 
   /// Set radius.
   SKETCHAPI_EXPORT
   void setMinorRadius(double theRadius);
 
-  /// Return major axis of the ellipse
-  SKETCHAPI_EXPORT
-  ModelHighAPI_Selection majorAxis() const;
-
-  /// Return minor axis of the ellipse
-  SKETCHAPI_EXPORT
-  ModelHighAPI_Selection minorAxis() const;
-
   /// Create construction elements (focuses, axes etc.).
   /// Empty value for each parameter shows that the corresponding feature has been removed.
   /// Value "aux" marks this feature as auxiliary.
@@ -154,6 +148,44 @@ public:
   /// Dump wrapped feature
   SKETCHAPI_EXPORT
   virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+private:
+  /// Find all features connected with theEllipse by the internal coincidence.
+  /// \param[in]  theEllipse        ellipse or elliptic arc
+  /// \param[in]  theMajorAxis      names of attributes composing a major axis of ellipse
+  /// \param[in]  theMinorAxis      names of attributes composing a minor axis of ellipse
+  /// \param[out] theAttrToFeature  map attribute of ellipse and coincident auxiliary feature
+  static void collectAuxiliaryFeatures(FeaturePtr theEllipse,
+                                       const PairOfStrings& theMajorAxis,
+                                       const PairOfStrings& theMinorAxis,
+                                       std::map<std::string, FeaturePtr>& theAttrToFeature);
+
+  /// \brief Dump the construction features (points, axes) for the ellipse.
+  /// \param[in] theDumper      dumper instance
+  /// \param[in] theAttributes  list of attributes the construction points are
+  ///                           connected with, and their dump names
+  /// \param[in] theAuxFeatures list of construction features
+  static void dumpConstructionEntities(ModelHighAPI_Dumper& theDumper,
+                                       const FeaturePtr& theEllipse,
+                                       const std::list<PairOfStrings>& theAttributes,
+                                       const std::map<std::string, FeaturePtr>& theAuxFeatures);
+
+  /// \brief Create construction features for the ellipse connected
+  ///        with corresponding attribute of ellipse.
+  static std::list<std::shared_ptr<SketchAPI_SketchEntity> > buildConstructionEntities(
+      const FeaturePtr& theEllipse,
+      const std::list<PairOfStrings>& theAttributes,
+      const std::string& theCenter,
+      const std::string& theFirstFocus,
+      const std::string& theSecondFocus,
+      const std::string& theMajorAxisStart,
+      const std::string& theMajorAxisEnd,
+      const std::string& theMinorAxisStart,
+      const std::string& theMinorAxisEnd,
+      const std::string& theMajorAxis,
+      const std::string& theMinorAxis);
+
+  friend class SketchAPI_EllipticArc;
 };
 
 /// Pointer on Ellipse object.
diff --git a/src/SketchAPI/SketchAPI_EllipticArc.cpp b/src/SketchAPI/SketchAPI_EllipticArc.cpp
new file mode 100644 (file)
index 0000000..dd7d905
--- /dev/null
@@ -0,0 +1,242 @@
+// 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SketchAPI_EllipticArc.h"
+#include "SketchAPI_Ellipse.h"
+
+#include <GeomAPI_Pnt2d.h>
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Selection.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <SketchPlugin_ConstraintCoincidenceInternal.h>
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Point.h>
+
+
+SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature> & theFeature)
+  : SketchAPI_SketchEntity(theFeature)
+{
+  initialize();
+}
+
+SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                             double theCenterX, double theCenterY,
+                                             double theFocusX, double theFocusY,
+                                             double theStartX, double theStartY,
+                                             double theEndX, double theEndY,
+                                             bool theInversed)
+  : SketchAPI_SketchEntity(theFeature)
+{
+  if(initialize()) {
+    setByCenterFocusAndPoints(theCenterX, theCenterY, theFocusX, theFocusY,
+                              theStartX, theStartY, theEndX, theEndY, theInversed);
+  }
+}
+
+SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                             const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                                             const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
+                                             const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+                                             const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                                             bool theInversed)
+  : SketchAPI_SketchEntity(theFeature)
+{
+  if(initialize()) {
+    setByCenterFocusAndPoints(theCenter, theFocus, theStart, theEnd, theInversed);
+  }
+}
+
+SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const ModelHighAPI_Selection& theExternal)
+  : SketchAPI_SketchEntity(theFeature)
+{
+  if (initialize()) {
+    setByExternal(theExternal);
+  }
+}
+
+SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                     const std::string& theExternalName)
+  : SketchAPI_SketchEntity(theFeature)
+{
+  if (initialize()) {
+    setByExternalName(theExternalName);
+  }
+}
+
+SketchAPI_EllipticArc::~SketchAPI_EllipticArc()
+{
+}
+
+void SketchAPI_EllipticArc::setByCenterFocusAndPoints(double theCenterX, double theCenterY,
+                                                      double theFocusX, double theFocusY,
+                                                      double theStartX, double theStartY,
+                                                      double theEndX, double theEndY,
+                                                      bool theInversed)
+{
+  fillAttribute(center(), theCenterX, theCenterY);
+  fillAttribute(firstFocus(), theFocusX, theFocusY);
+  fillAttribute(startPoint(), theStartX, theStartY);
+  fillAttribute(endPoint(), theEndX, theEndY);
+  fillAttribute(theInversed, reversed());
+
+  execute();
+}
+
+void SketchAPI_EllipticArc::setByCenterFocusAndPoints(
+    const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+    bool theInversed)
+{
+  fillAttribute(theCenter, center());
+  fillAttribute(theFocus, firstFocus());
+  fillAttribute(theStart, startPoint());
+  fillAttribute(theEnd, endPoint());
+  fillAttribute(theInversed, reversed());
+
+  execute();
+}
+
+void SketchAPI_EllipticArc::setByExternal(const ModelHighAPI_Selection & theExternal)
+{
+  fillAttribute(theExternal, external());
+  execute();
+}
+
+void SketchAPI_EllipticArc::setByExternalName(const std::string & theExternalName)
+{
+  fillAttribute(ModelHighAPI_Selection("EDGE", theExternalName), external());
+  execute();
+}
+
+void SketchAPI_EllipticArc::setCenter(double theX, double theY)
+{
+  fillAttribute(center(), theX, theY);
+  execute();
+}
+
+void SketchAPI_EllipticArc::setCenter(const std::shared_ptr<GeomAPI_Pnt2d> & theCenter)
+{
+  fillAttribute(theCenter, mycenter);
+  execute();
+}
+
+void SketchAPI_EllipticArc::setFocus(double theX, double theY)
+{
+  fillAttribute(firstFocus(), theX, theY);
+  execute();
+}
+
+void SketchAPI_EllipticArc::setFocus(const std::shared_ptr<GeomAPI_Pnt2d> & theFocus)
+{
+  fillAttribute(theFocus, myfirstFocus);
+  execute();
+}
+
+static const std::list<PairOfStrings>& ellipticArcAttrAndDumpNames()
+{
+  static std::list<PairOfStrings> anAttributes;
+  if (anAttributes.empty()) {
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_EllipticArc::CENTER_ID(), "center"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_EllipticArc::FIRST_FOCUS_ID(), "firstFocus"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_EllipticArc::SECOND_FOCUS_ID(), "secondFocus"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID(), "majorAxisStart"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID(), "majorAxisEnd"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_EllipticArc::MINOR_AXIS_START_ID(), "minorAxisStart"));
+    anAttributes.push_back(
+        PairOfStrings(SketchPlugin_EllipticArc::MINOR_AXIS_END_ID(), "minorAxisEnd"));
+  }
+  return anAttributes;
+}
+
+std::list<std::shared_ptr<SketchAPI_SketchEntity> > SketchAPI_EllipticArc::construction(
+    const std::string& center,
+    const std::string& firstFocus,
+    const std::string& secondFocus,
+    const std::string& majorAxisStart,
+    const std::string& majorAxisEnd,
+    const std::string& minorAxisStart,
+    const std::string& minorAxisEnd,
+    const std::string& majorAxis,
+    const std::string& minorAxis) const
+{
+  FeaturePtr anEllipse = feature();
+
+  std::list<PairOfStrings> anAttributes = ellipticArcAttrAndDumpNames();
+  // append start and end attributes for axes
+  anAttributes.push_back(PairOfStrings(SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID(),
+                                       SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID()));
+  anAttributes.push_back(PairOfStrings(SketchPlugin_EllipticArc::MINOR_AXIS_START_ID(),
+                                       SketchPlugin_EllipticArc::MINOR_AXIS_END_ID()));
+
+  return SketchAPI_Ellipse::buildConstructionEntities(anEllipse, anAttributes,
+                                                      center, firstFocus, secondFocus,
+                                                      majorAxisStart, majorAxisEnd,
+                                                      minorAxisStart, minorAxisEnd,
+                                                      majorAxis, minorAxis);
+}
+
+void SketchAPI_EllipticArc::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  if (isCopy())
+    return; // no need to dump copied feature
+
+  FeaturePtr aBase = feature();
+  const std::string& aSketchName = theDumper.parentName(aBase);
+
+  AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+  if (anExternal->context()) {
+    // circle is external
+    theDumper << aBase << " = " << aSketchName << ".addEllipticArc(" << anExternal << ")" << std::endl;
+  } else {
+    // ellipse given by center, focus and radius
+    theDumper << aBase << " = " << aSketchName << ".addEllipticArc("
+              << center() << ", " << firstFocus() << ", "
+              << startPoint() << ", " << endPoint() << ", "
+              << reversed() << ")" << std::endl;
+  }
+  // dump "auxiliary" flag if necessary
+  SketchAPI_SketchEntity::dump(theDumper);
+
+  // dump auxiliary features produced by elliptic arc
+  std::map<std::string, FeaturePtr> anAuxFeatures;
+  static const std::pair<std::string, std::string> aMajorAxis(
+      SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID(),
+      SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID());
+  static const std::pair<std::string, std::string> aMinorAxis(
+      SketchPlugin_EllipticArc::MINOR_AXIS_START_ID(),
+      SketchPlugin_EllipticArc::MINOR_AXIS_END_ID());
+  SketchAPI_Ellipse::collectAuxiliaryFeatures(aBase, aMajorAxis, aMinorAxis, anAuxFeatures);
+
+  if (!anAuxFeatures.empty()) {
+    // a list of attributes to write features in special order
+    static std::list<PairOfStrings> anAttributes = ellipticArcAttrAndDumpNames();
+    SketchAPI_Ellipse::dumpConstructionEntities(theDumper, aBase, anAttributes, anAuxFeatures);
+  }
+}
diff --git a/src/SketchAPI/SketchAPI_EllipticArc.h b/src/SketchAPI/SketchAPI_EllipticArc.h
new file mode 100644 (file)
index 0000000..dea0544
--- /dev/null
@@ -0,0 +1,164 @@
+// 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef SketchAPI_EllipticArc_H_
+#define SketchAPI_EllipticArc_H_
+
+#include "SketchAPI.h"
+#include "SketchAPI_SketchEntity.h"
+
+#include <SketchPlugin_EllipticArc.h>
+
+class ModelHighAPI_Selection;
+
+/// \class SketchAPI_EllipticArc
+/// \ingroup CPPHighAPI
+/// \brief Interface for Elliptic Arc feature.
+class SketchAPI_EllipticArc : public SketchAPI_SketchEntity
+{
+public:
+  /// Constructor without values.
+  SKETCHAPI_EXPORT
+  explicit SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  SKETCHAPI_EXPORT
+  SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                        double theCenterX, double theCenterY,
+                        double theFocusX, double theFocusY,
+                        double theStartX, double theStartY,
+                        double theEndX, double theEndY,
+                        bool theInversed);
+
+  /// Constructor with values.
+  SKETCHAPI_EXPORT
+  SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                        const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                        const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
+                        const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+                        const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                        bool theInversed);
+
+  /// Constructor with external.
+  SKETCHAPI_EXPORT
+  SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                        const ModelHighAPI_Selection& theExternal);
+
+  /// Constructor with external.
+  SKETCHAPI_EXPORT
+  SketchAPI_EllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                        const std::string& theExternalName);
+
+  /// Destructor.
+  SKETCHAPI_EXPORT
+  virtual ~SketchAPI_EllipticArc();
+
+  INTERFACE_13(SketchPlugin_EllipticArc::ID(),
+               center, SketchPlugin_EllipticArc::CENTER_ID(),
+               GeomDataAPI_Point2D, /** Center point */,
+               startPoint, SketchPlugin_EllipticArc::START_POINT_ID(),
+               GeomDataAPI_Point2D, /** Start point of elliptic arc */,
+               endPoint, SketchPlugin_EllipticArc::END_POINT_ID(),
+               GeomDataAPI_Point2D, /** End point of elliptic arc */,
+               reversed, SketchPlugin_EllipticArc::REVERSED_ID(),
+               ModelAPI_AttributeBoolean, /** Inversed flag */,
+               firstFocus, SketchPlugin_EllipticArc::FIRST_FOCUS_ID(),
+               GeomDataAPI_Point2D, /** Focus in positive direction of a major axis */,
+               secondFocus, SketchPlugin_EllipticArc::SECOND_FOCUS_ID(),
+               GeomDataAPI_Point2D, /** Focus in negative direction of a major axis */,
+               majorAxisNegative, SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID(),
+               GeomDataAPI_Point2D, /** Start point of major axis */,
+               majorAxisPositive, SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID(),
+               GeomDataAPI_Point2D, /** End point of major axis */,
+               minorAxisNegative, SketchPlugin_EllipticArc::MINOR_AXIS_START_ID(),
+               GeomDataAPI_Point2D, /** Start point of minor axis */,
+               minorAxisPositive, SketchPlugin_EllipticArc::MINOR_AXIS_END_ID(),
+               GeomDataAPI_Point2D, /** End point of minor axis */,
+               majorRadius, SketchPlugin_EllipticArc::MAJOR_RADIUS_ID(),
+               ModelAPI_AttributeDouble, /** Major radius */,
+               minorRadius, SketchPlugin_EllipticArc::MINOR_RADIUS_ID(),
+               ModelAPI_AttributeDouble, /** Minor radius */,
+               external, SketchPlugin_EllipticArc::EXTERNAL_ID(),
+               ModelAPI_AttributeSelection, /** External */)
+
+  /// Set by center, focus and radius.
+  SKETCHAPI_EXPORT
+  void setByCenterFocusAndPoints(double theCenterX, double theCenterY,
+                                 double theFocusX, double theFocusY,
+                                 double theStartX, double theStartY,
+                                 double theEndX, double theEndY,
+                                 bool theInversed);
+
+  /// Set by center, focus and radius.
+  SKETCHAPI_EXPORT
+  void setByCenterFocusAndPoints(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                                 const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
+                                 const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+                                 const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                                 bool theInversed);
+
+  /// Set by external.
+  SKETCHAPI_EXPORT
+  void setByExternal(const ModelHighAPI_Selection& theExternal);
+
+  /// Set by external name.
+  SKETCHAPI_EXPORT
+  void setByExternalName(const std::string& theExternalName);
+
+  /// Set center.
+  SKETCHAPI_EXPORT
+  void setCenter(double theX, double theY);
+
+  /// Set center.
+  SKETCHAPI_EXPORT
+  void setCenter(const std::shared_ptr<GeomAPI_Pnt2d> & theCenter);
+
+  /// Set focus.
+  SKETCHAPI_EXPORT
+  void setFocus(double theX, double theY);
+
+  /// Set focus.
+  SKETCHAPI_EXPORT
+  void setFocus(const std::shared_ptr<GeomAPI_Pnt2d> & theFocus);
+
+  /// Create construction elements (focuses, axes etc.).
+  /// Empty value for each parameter shows that the corresponding feature has been removed.
+  /// Value "aux" marks this feature as auxiliary.
+  /// And the name of the feature shows that it is a regular feature.
+  SKETCHAPI_EXPORT
+  std::list<std::shared_ptr<SketchAPI_SketchEntity> > construction(
+      const std::string& center = std::string(),
+      const std::string& firstFocus = std::string(),
+      const std::string& secondFocus = std::string(),
+      const std::string& majorAxisStart = std::string(),
+      const std::string& majorAxisEnd = std::string(),
+      const std::string& minorAxisStart = std::string(),
+      const std::string& minorAxisEnd = std::string(),
+      const std::string& majorAxis = std::string(),
+      const std::string& minorAxis = std::string()) const;
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on Ellipse object.
+typedef std::shared_ptr<SketchAPI_EllipticArc> EllipticArcPtr;
+
+#endif // SketchAPI_EllipticArc_H_
index c3ed48080d6f9d365379ccf597a359d7fc3aae32..3a4ef16d3631b4191c670a57d20d7d3bc4988ccb 100644 (file)
@@ -59,7 +59,8 @@ static CompositeFeaturePtr sketch(FeaturePtr theFeature)
 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature)
 : SketchAPI_SketchEntity(theFeature)
 {
-  initialize();
+  if (initialize())
+    mySketch = sketch(theFeature);
 }
 
 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
diff --git a/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp b/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp
new file mode 100644 (file)
index 0000000..4702bc8
--- /dev/null
@@ -0,0 +1,95 @@
+// 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SketchAPI_MacroEllipticArc.h"
+
+#include <GeomAPI_Pnt2d.h>
+
+#include <ModelHighAPI_RefAttr.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <SketchPlugin_MacroEllipticArc.h>
+
+#define CENTER_POINT (std::dynamic_pointer_cast<GeomDataAPI_Point2D>( \
+                      feature()->attribute(SketchPlugin_MacroEllipticArc::CENTER_ID())))
+#define MAJOR_AXIS_POSITIVE (std::dynamic_pointer_cast<GeomDataAPI_Point2D>( \
+                      feature()->attribute(SketchPlugin_MacroEllipticArc::MAJOR_AXIS_POINT_ID())))
+#define START_POINT (std::dynamic_pointer_cast<GeomDataAPI_Point2D>( \
+                     feature()->attribute(SketchPlugin_MacroEllipticArc::START_POINT_ID())))
+#define END_POINT (std::dynamic_pointer_cast<GeomDataAPI_Point2D>( \
+                   feature()->attribute(SketchPlugin_MacroEllipticArc::END_POINT_ID())))
+
+#define CENTER_POINT_REF (feature()->refattr(SketchPlugin_MacroEllipticArc::CENTER_REF_ID()))
+#define MAJOR_AXIS_POSITIVE_REF (feature()->refattr( \
+                                 SketchPlugin_MacroEllipticArc::MAJOR_AXIS_POINT_REF_ID()))
+#define START_POINT_REF (feature()->refattr(SketchPlugin_MacroEllipticArc::START_POINT_REF_ID()))
+#define END_POINT_REF (feature()->refattr(SketchPlugin_MacroEllipticArc::END_POINT_REF_ID()))
+
+
+static void fillAttribute(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint,
+                          const ModelHighAPI_RefAttr& thePointRef,
+                          std::shared_ptr<GeomDataAPI_Point2D> thePointAttr,
+                          AttributeRefAttrPtr thePointRefAttr)
+{
+  GeomPnt2dPtr aPoint = thePoint;
+  if (!thePointRef.isEmpty()) {
+    fillAttribute(thePointRef, thePointRefAttr);
+    std::shared_ptr<GeomDataAPI_Point2D> anAttrPnt =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(thePointRefAttr->attr());
+    if (anAttrPnt)
+      aPoint = anAttrPnt->pnt();
+  }
+  fillAttribute(aPoint, thePointAttr);
+}
+
+SketchAPI_MacroEllipticArc::SketchAPI_MacroEllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+  : SketchAPI_MacroEllipse(theFeature)
+{
+}
+
+SketchAPI_MacroEllipticArc::SketchAPI_MacroEllipticArc(
+    const std::shared_ptr<ModelAPI_Feature>& theFeature,
+    const std::shared_ptr<GeomAPI_Pnt2d>&    theCenter,
+    const ModelHighAPI_RefAttr&              theCenterRef,
+    const std::shared_ptr<GeomAPI_Pnt2d>&    theMajorAxisPoint,
+    const ModelHighAPI_RefAttr&              theMajorAxisPointRef,
+    const std::shared_ptr<GeomAPI_Pnt2d>&    theArcStart,
+    const ModelHighAPI_RefAttr&              theArcStartRef,
+    const std::shared_ptr<GeomAPI_Pnt2d>&    theArcEnd,
+    const ModelHighAPI_RefAttr&              theArcEndRef,
+    const bool                               theReversed)
+  : SketchAPI_MacroEllipse(theFeature)
+{
+  if (initialize()) {
+    fillAttribute(theCenter, theCenterRef,
+                  CENTER_POINT, CENTER_POINT_REF);
+    fillAttribute(theMajorAxisPoint, theMajorAxisPointRef,
+                  MAJOR_AXIS_POSITIVE, MAJOR_AXIS_POSITIVE_REF);
+    fillAttribute(theArcStart, theArcStartRef, START_POINT, START_POINT_REF);
+    fillAttribute(theArcEnd, theArcEndRef, END_POINT, END_POINT_REF);
+
+    fillAttribute(theReversed, reversed());
+
+    execute();
+  }
+}
+
+SketchAPI_MacroEllipticArc::~SketchAPI_MacroEllipticArc()
+{
+}
diff --git a/src/SketchAPI/SketchAPI_MacroEllipticArc.h b/src/SketchAPI/SketchAPI_MacroEllipticArc.h
new file mode 100644 (file)
index 0000000..51eb3a3
--- /dev/null
@@ -0,0 +1,67 @@
+// 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef SketchAPI_MacroEllipticArc_H_
+#define SketchAPI_MacroEllipticArc_H_
+
+#include "SketchAPI.h"
+#include "SketchAPI_MacroEllipse.h"
+
+#include <SketchPlugin_MacroEllipticArc.h>
+
+/// \class SketchAPI_MacroEllipticArc
+/// \ingroup CPPHighAPI
+/// \brief Interface for Elliptic Arc feature.
+class SketchAPI_MacroEllipticArc: public SketchAPI_MacroEllipse
+{
+public:
+  /// Constructor without values.
+  SKETCHAPI_EXPORT
+  explicit SketchAPI_MacroEllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values and/or references.
+  SKETCHAPI_EXPORT
+  SketchAPI_MacroEllipticArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                             const std::shared_ptr<GeomAPI_Pnt2d>&    theCenter,
+                             const ModelHighAPI_RefAttr&              theCenterRef,
+                             const std::shared_ptr<GeomAPI_Pnt2d>&    theMajorAxisPoint,
+                             const ModelHighAPI_RefAttr&              theMajorAxisPointRef,
+                             const std::shared_ptr<GeomAPI_Pnt2d>&    theArcStart,
+                             const ModelHighAPI_RefAttr&              theArcStartRef,
+                             const std::shared_ptr<GeomAPI_Pnt2d>&    theArcEnd,
+                             const ModelHighAPI_RefAttr&              theArcEndRef,
+                             const bool                               theReversed);
+
+  /// Destructor.
+  SKETCHAPI_EXPORT
+  virtual ~SketchAPI_MacroEllipticArc();
+
+  INTERFACE_3(SketchPlugin_MacroEllipticArc::ID(),
+              startPoint, SketchPlugin_MacroEllipticArc::START_POINT_ID(),
+              GeomDataAPI_Point2D, /** Start point of elliptic arc */,
+              endPoint, SketchPlugin_MacroEllipticArc::END_POINT_ID(),
+              GeomDataAPI_Point2D, /** End point of elliptic arc */,
+              reversed, SketchPlugin_MacroEllipticArc::REVERSED_ID(),
+              ModelAPI_AttributeBoolean, /** Reversed flag for elliptic arc*/)
+};
+
+/// Pointer on Elliptic Arc object.
+typedef std::shared_ptr<SketchAPI_MacroEllipticArc> MacroEllipticArcPtr;
+
+#endif // SketchAPI_MacroEllipticArc_H_
index 5a329558fd3e2217782f7aec38c9a864297895c3..cfcf93b7b7c3554a4e557ecb2b35d1b28244349c 100644 (file)
 #include "SketchAPI_Arc.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"
@@ -642,6 +644,70 @@ 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_EllipticArc> SketchAPI_Sketch::addEllipticArc(
+    const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+    bool theInversed)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+      compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID());
+  return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature,
+      theCenter, theFocus, theStart, theEnd, 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_Projection> SketchAPI_Sketch::addProjection(
     const ModelHighAPI_Selection & theExternalFeature,
index 726250f6dc08c36b93a7b9f9bc7084258fef46ca..2f722b5e5ae053ade63b6d2ea2daf45c21682433 100644 (file)
@@ -44,6 +44,8 @@ class SketchAPI_Circle;
 class SketchAPI_MacroCircle;
 class SketchAPI_Ellipse;
 class SketchAPI_MacroEllipse;
+class SketchAPI_EllipticArc;
+class SketchAPI_MacroEllipticArc;
 class SketchAPI_IntersectionPoint;
 class SketchAPI_Line;
 class SketchAPI_Mirror;
@@ -299,6 +301,37 @@ public:
   SKETCHAPI_EXPORT
   std::shared_ptr<SketchAPI_Ellipse> addEllipse(const std::string & theExternalName);
 
+  /// Add elliptic arc
+  SKETCHAPI_EXPORT
+  std::shared_ptr<SketchAPI_EllipticArc> addEllipticArc(
+      double theCenterX, double theCenterY,
+      double theFocusX, double theFocusY,
+      double theStartX, double theStartY,
+      double theEndX, double theEndY,
+      bool theInversed = false);
+  /// Add elliptic arc
+  SKETCHAPI_EXPORT
+  std::shared_ptr<SketchAPI_EllipticArc> addEllipticArc(
+      const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+      const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
+      const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+      const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+      bool theInversed = false);
+  /// Add elliptic arc
+  SKETCHAPI_EXPORT
+  std::shared_ptr<SketchAPI_MacroEllipticArc> 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 = false);
+  /// Add elliptic arc
+  SKETCHAPI_EXPORT
+  std::shared_ptr<SketchAPI_EllipticArc> addEllipticArc(const ModelHighAPI_Selection & theExternal);
+  /// Add elliptic arc
+  SKETCHAPI_EXPORT
+  std::shared_ptr<SketchAPI_EllipticArc> addEllipticArc(const std::string & theExternalName);
+
   /// Add projection
   SKETCHAPI_EXPORT
   std::shared_ptr<SketchAPI_Projection> addProjection(
index 5c7202268073dcc4c6ccf77d3c07d332229863ea..467e04349007f9719eb375542bf144417d93f5ea 100644 (file)
@@ -21,6 +21,7 @@
 #include <SketchAPI_Arc.h>
 #include <SketchAPI_Circle.h>
 #include <SketchAPI_Ellipse.h>
+#include <SketchAPI_EllipticArc.h>
 #include <SketchAPI_IntersectionPoint.h>
 #include <SketchAPI_Line.h>
 #include <SketchAPI_Point.h>
@@ -100,6 +101,8 @@ SketchAPI_SketchEntity::wrap(const std::list<std::shared_ptr<ModelAPI_Feature> >
       aResult.push_back(std::shared_ptr<SketchAPI_SketchEntity>(new SketchAPI_Circle(*anIt)));
     else if ((*anIt)->getKind() == SketchPlugin_Ellipse::ID())
       aResult.push_back(std::shared_ptr<SketchAPI_SketchEntity>(new SketchAPI_Ellipse(*anIt)));
+    else if ((*anIt)->getKind() == SketchPlugin_EllipticArc::ID())
+      aResult.push_back(std::shared_ptr<SketchAPI_SketchEntity>(new SketchAPI_EllipticArc(*anIt)));
     else if ((*anIt)->getKind() == SketchPlugin_Point::ID())
       aResult.push_back(std::shared_ptr<SketchAPI_SketchEntity>(new SketchAPI_Point(*anIt)));
     else if ((*anIt)->getKind() == SketchPlugin_IntersectionPoint::ID())
index fa19b36c252e37cd72f9a9d25e77d37a66c4d5b3..93788350bae92690c04502d068eb60227b3b250c 100644 (file)
@@ -29,6 +29,8 @@
   #include "SketchAPI_MacroCircle.h"
   #include "SketchAPI_Ellipse.h"
   #include "SketchAPI_MacroEllipse.h"
+  #include "SketchAPI_EllipticArc.h"
+  #include "SketchAPI_MacroEllipticArc.h"
   #include "SketchAPI_Constraint.h"
   #include "SketchAPI_ConstraintAngle.h"
   #include "SketchAPI_IntersectionPoint.h"
index 85fb674259d9c577b6dd5a84865f82d85a0e1e38..1cd476011e1bdfd80b334123333b6d1c1ec4f9bc 100644 (file)
@@ -52,9 +52,9 @@
 // for sqrt on Linux
 #include <cmath>
 
-const double tolerance = 1e-7;
-const double paramTolerance = 1.e-4;
-const double PI = 3.141592653589793238463;
+static const double tolerance = 1e-7;
+static const double paramTolerance = 1.e-4;
+static const double PI = 3.141592653589793238463;
 
 
 SketchPlugin_Arc::SketchPlugin_Arc()
index 3bc24f1ccee81a5aeaf4f8c2db99d444f84c0ee8..a5c2b29fb413945892f1afeb32959e474ce94bb3 100644 (file)
@@ -25,7 +25,9 @@
 #include <GeomAPI_Dir2d.h>
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Ellipse.h>
+#include <GeomAPI_Ellipse2d.h>
 #include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_XY.h>
 
 #include <GeomDataAPI_Point2D.h>
 
 #include <cmath>
 
 static const double tolerance = 1e-7;
+static const double paramTolerance = 1.e-4;
+static const double PI = 3.141592653589793238463;
 
 
 SketchPlugin_EllipticArc::SketchPlugin_EllipticArc()
-: SketchPlugin_SketchEntity()
+  : SketchPlugin_SketchEntity(),
+    myParamDelta(0.0)
 {
 }
 
@@ -102,77 +107,125 @@ void SketchPlugin_EllipticArc::attributeChanged(const std::string& theID) {
     }
     // update arguments due to the selection value
     if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
-      std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
+      std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aSelection));
       std::shared_ptr<GeomAPI_Ellipse> anEllipse = anEdge->ellipse();
 
       std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
       aCenterAttr->setValue(sketch()->to2D(anEllipse->center()));
 
       std::shared_ptr<GeomDataAPI_Point2D> aFocusAttr =
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(FIRST_FOCUS_ID()));
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(FIRST_FOCUS_ID()));
       aFocusAttr->setValue(sketch()->to2D(anEllipse->firstFocus()));
 
       std::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
       aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint()));
 
       std::shared_ptr<GeomDataAPI_Point2D> aEndAttr =
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_ID()));
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_ID()));
       aEndAttr->setValue(sketch()->to2D(anEdge->lastPoint()));
 
       real(MAJOR_RADIUS_ID())->setValue(anEllipse->majorRadius());
       real(MINOR_RADIUS_ID())->setValue(anEllipse->minorRadius());
     }
   }
+  else if (theID == CENTER_ID() || theID == FIRST_FOCUS_ID() ||
+           theID == START_POINT_ID() || theID == END_POINT_ID())
+    fillCharacteristicPoints();
+}
+
+static void calculateRadii(const GeomPnt2dPtr& theCenter,
+                           const GeomPnt2dPtr& theFocus,
+                           const GeomPnt2dPtr& thePassed,
+                           double& theMajorRadius,
+                           double& theMinorRadius)
+{
+  GeomPnt2dPtr aSecondFocus(new GeomAPI_Pnt2d(
+      theCenter->xy()->multiplied(2.0)->decreased(theFocus->xy())));
+  theMajorRadius = 0.5 * (thePassed->distance(theFocus) + thePassed->distance(aSecondFocus));
+
+  GeomDir2dPtr aXAxis(new GeomAPI_Dir2d(theFocus->x() - theCenter->x(),
+                                        theFocus->y() - theCenter->y()));
+  std::shared_ptr<GeomAPI_XY> aPassedVec = thePassed->xy()->decreased(theCenter->xy());
+
+  double x = aPassedVec->dot(aXAxis->xy()) / theMajorRadius;
+  double y = abs(aPassedVec->cross(aXAxis->xy()));
+  theMinorRadius = y / sqrt(1.0 - x * x);
 }
 
 bool SketchPlugin_EllipticArc::fillCharacteristicPoints()
 {
   std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
-      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
+    std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
   std::shared_ptr<GeomDataAPI_Point2D> aFocusAttr =
-      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(FIRST_FOCUS_ID()));
-
-  AttributeDoublePtr aMinorRadiusAttr = real(MINOR_RADIUS_ID());
+    std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(FIRST_FOCUS_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aStartPointAttr =
+    std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START_POINT_ID()));
 
   if (!aCenterAttr->isInitialized() ||
-      !aFocusAttr->isInitialized() ||
-      !aMinorRadiusAttr->isInitialized()) {
-    return false;
-  }
-
-  double aMinorRadius = aMinorRadiusAttr->value();
-  if (aMinorRadius < tolerance) {
+    !aFocusAttr->isInitialized() ||
+    !aStartPointAttr->isInitialized()) {
     return false;
   }
 
   data()->blockSendAttributeUpdated(true);
   GeomPnt2dPtr aCenter2d = aCenterAttr->pnt();
   GeomPnt2dPtr aFocus2d = aFocusAttr->pnt();
+  GeomPnt2dPtr aStart2d = aStartPointAttr->pnt();
+
+  double aMajorRadius = 0.0, aMinorRadius = 0.0;
+  calculateRadii(aCenter2d, aFocus2d, aStart2d, aMajorRadius, aMinorRadius);
+  if (aMinorRadius < tolerance)
+    return false;
+  real(MAJOR_RADIUS_ID())->setValue(aMajorRadius);
+  real(MINOR_RADIUS_ID())->setValue(aMinorRadius);
+
   GeomDir2dPtr aMajorDir2d(new GeomAPI_Dir2d(aFocus2d->x() - aCenter2d->x(),
-                                             aFocus2d->y() - aCenter2d->y()));
+    aFocus2d->y() - aCenter2d->y()));
   GeomDir2dPtr aMinorDir2d(new GeomAPI_Dir2d(-aMajorDir2d->y(), aMajorDir2d->x()));
 
-  AttributeDoublePtr aMajorRadiusAttr = real(MAJOR_RADIUS_ID());
-  double aFocalDist = aCenter2d->distance(aFocus2d);
-  double aMajorRadius = sqrt(aFocalDist * aFocalDist + aMinorRadius * aMinorRadius);
-  aMajorRadiusAttr->setValue(aMajorRadius);
-
   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(SECOND_FOCUS_ID()))
     ->setValue(2.0 * aCenter2d->x() - aFocus2d->x(), 2.0 * aCenter2d->y() - aFocus2d->y());
   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(MAJOR_AXIS_START_ID()))
-      ->setValue(aCenter2d->x() - aMajorDir2d->x() * aMajorRadius,
-                 aCenter2d->y() - aMajorDir2d->y() * aMajorRadius);
+    ->setValue(aCenter2d->x() - aMajorDir2d->x() * aMajorRadius,
+      aCenter2d->y() - aMajorDir2d->y() * aMajorRadius);
   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(MAJOR_AXIS_END_ID()))
-      ->setValue(aCenter2d->x() + aMajorDir2d->x() * aMajorRadius,
-                 aCenter2d->y() + aMajorDir2d->y() * aMajorRadius);
+    ->setValue(aCenter2d->x() + aMajorDir2d->x() * aMajorRadius,
+      aCenter2d->y() + aMajorDir2d->y() * aMajorRadius);
   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(MINOR_AXIS_START_ID()))
-      ->setValue(aCenter2d->x() - aMinorDir2d->x() * aMinorRadius,
-                 aCenter2d->y() - aMinorDir2d->y() * aMinorRadius);
+    ->setValue(aCenter2d->x() - aMinorDir2d->x() * aMinorRadius,
+      aCenter2d->y() - aMinorDir2d->y() * aMinorRadius);
   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(MINOR_AXIS_END_ID()))
-      ->setValue(aCenter2d->x() + aMinorDir2d->x() * aMinorRadius,
-                 aCenter2d->y() + aMinorDir2d->y() * aMinorRadius);
+    ->setValue(aCenter2d->x() + aMinorDir2d->x() * aMinorRadius,
+      aCenter2d->y() + aMinorDir2d->y() * aMinorRadius);
+
+  std::shared_ptr<GeomDataAPI_Point2D> aEndPointAttr =
+    std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(END_POINT_ID()));
+  if (aEndPointAttr->isInitialized()) {
+    // recalculate REVERSED flag
+    std::shared_ptr<GeomAPI_Ellipse2d> anEllipseForArc(
+        new GeomAPI_Ellipse2d(aCenter2d, aMajorDir2d, aMajorRadius, aMinorRadius));
+    GeomPnt2dPtr anEnd = aEndPointAttr->pnt();
+    std::shared_ptr<GeomAPI_Pnt2d> aProjection = anEllipseForArc->project(anEnd);
+    double aParamStart = 0.0, aParamEnd = 0.0;
+    if (aProjection && anEnd->distance(aProjection) <= tolerance &&
+        anEllipseForArc->parameter(anEnd, paramTolerance, aParamEnd)) {
+      // do not recalculate REVERSED flag if the arc is not consistent
+      anEllipseForArc->parameter(aStart2d, paramTolerance, aParamStart);
+      aParamEnd -= aParamStart;
+
+      if (myParamDelta >= 0.0 && myParamDelta <= PI * 0.5 &&
+          aParamEnd < 0 && aParamEnd >= -PI * 0.5) {
+        boolean(REVERSED_ID())->setValue(true);
+      }
+      else if (myParamDelta <= 0.0 && myParamDelta >= -PI * 0.5 &&
+               aParamEnd > 0.0 && aParamEnd <= PI * 0.5) {
+        boolean(REVERSED_ID())->setValue(false);
+      }
+    }
+    myParamDelta = aParamEnd;
+  }
   data()->blockSendAttributeUpdated(false);
 
   return true;
@@ -207,6 +260,8 @@ void SketchPlugin_EllipticArc::createEllipticArc(SketchPlugin_Sketch* theSketch)
 
     GeomPointPtr aStartPnt(theSketch->to3D(aStartAttr->x(), aStartAttr->y()));
     GeomPointPtr aEndPnt(theSketch->to3D(aEndAttr->x(), aEndAttr->y()));
+    if (boolean(REVERSED_ID())->value())
+      std::swap(aStartPnt, aEndPnt);
 
     anEllipseShape = GeomAlgoAPI_EdgeBuilder::ellipticArc(aCenter, aNormal, aMajorAxis,
         aMajorRadius, aMinorRadius, aStartPnt, aEndPnt);
index b6c6e1c71e5eee6ae5f620da010f08acee761741..f3730d1662ed9f5c921807557d8abecb07c2d121 100644 (file)
@@ -144,6 +144,9 @@ private:
   bool fillCharacteristicPoints();
 
   void createEllipticArc(SketchPlugin_Sketch* theSketch);
+
+private:
+  double myParamDelta;
 };
 
 #endif
index 768e827134092cc66944132f81bcc90a660240d2..ab87ca57f7bb40ba1ecb49961d470f8e388824fa 100644 (file)
 
 #include <SketchPlugin_MacroEllipticArc.h>
 
-////#include <SketchPlugin_ConstraintCoincidenceInternal.h>
 #include <SketchPlugin_EllipticArc.h>
-////#include <SketchPlugin_Line.h>
 #include <SketchPlugin_MacroArcReentrantMessage.h>
-////#include <SketchPlugin_Point.h>
 #include <SketchPlugin_Tools.h>
 #include <SketchPlugin_Sketch.h>
 
@@ -228,50 +225,6 @@ std::string SketchPlugin_MacroEllipticArc::processEvent(
 }
 // LCOV_EXCL_STOP
 
-////void SketchPlugin_MacroEllipticArc::constraintsForEllipseByCenterAxisAndPassed(
-////    FeaturePtr theEllipseFeature)
-////{
-////  // tangency on-the-fly is not applicable for ellipses
-////  static const bool isTangencyApplicable = false;
-////  // Create constraints.
-////  SketchPlugin_Tools::createCoincidenceOrTangency(
-////      this, FIRST_POINT_REF_ID(),
-////      theEllipseFeature->attribute(SketchPlugin_Ellipse::CENTER_ID()),
-////      ObjectPtr(), isTangencyApplicable);
-////  SketchPlugin_Tools::createCoincidenceOrTangency(
-////      this, SECOND_POINT_REF_ID(),
-////      theEllipseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()),
-////      ObjectPtr(), isTangencyApplicable);
-////  // make coincidence only if PASSED_POINT_REF_ID() refers a point but not an object
-////  if (!refattr(PASSED_POINT_REF_ID())->isObject()) {
-////    SketchPlugin_Tools::createCoincidenceOrTangency(
-////        this, PASSED_POINT_REF_ID(), AttributePtr(),
-////        theEllipseFeature->lastResult(), isTangencyApplicable);
-////  }
-////}
-////
-////void SketchPlugin_MacroEllipticArc::constraintsForEllipseByMajoxAxisAndPassed(
-////    FeaturePtr theEllipseFeature)
-////{
-////  // tangency on-the-fly is not applicable for ellipses
-////  static const bool isTangencyApplicable = false;
-////  // Create constraints.
-////  SketchPlugin_Tools::createCoincidenceOrTangency(
-////      this, FIRST_POINT_REF_ID(),
-////      theEllipseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_START_ID()),
-////      ObjectPtr(), isTangencyApplicable);
-////  SketchPlugin_Tools::createCoincidenceOrTangency(
-////      this, SECOND_POINT_REF_ID(),
-////      theEllipseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()),
-////      ObjectPtr(), isTangencyApplicable);
-////  // make coincidence only if PASSED_POINT_REF_ID() refers a point but not an object
-////  if (!refattr(PASSED_POINT_REF_ID())->isObject()) {
-////    SketchPlugin_Tools::createCoincidenceOrTangency(
-////        this, PASSED_POINT_REF_ID(), AttributePtr(),
-////        theEllipseFeature->lastResult(), isTangencyApplicable);
-////  }
-////}
-
 FeaturePtr SketchPlugin_MacroEllipticArc::createEllipticArcFeature()
 {
   GeomShapePtr anArc = getArcShape();
@@ -281,6 +234,8 @@ FeaturePtr SketchPlugin_MacroEllipticArc::createEllipticArcFeature()
     GeomEdgePtr anArcEdge = anArc->edge();
     aStartPoint = anArcEdge->firstPoint();
     aEndPoint = anArcEdge->lastPoint();
+    if (boolean(REVERSED_ID())->value())
+      std::swap(aStartPoint, aEndPoint);
 
     if (anArcEdge->isEllipse())
       anEllipse = anArcEdge->ellipse();
index d0c8982c46ab0d6731d6d3f850bffb183774937e..5c43f6784733660df8feb06c729484c61e116025 100644 (file)
@@ -158,9 +158,6 @@ class SketchPlugin_MacroEllipticArc: public SketchPlugin_SketchEntity,
 private:
   std::shared_ptr<GeomAPI_Shape> getArcShape();
 
-////  void constraintsForEllipseByCenterAxisAndPassed(FeaturePtr theEllipseFeature);
-////  void constraintsForEllipseByMajoxAxisAndPassed(FeaturePtr theEllipseFeature);
-
   FeaturePtr createEllipticArcFeature();
 
 private:
index 4a9ae8a5af537c4208e7d1b1afc7f0bc731ea401..4b89a59dccfde47d154cff9b13e1d84279503a7e 100644 (file)
@@ -470,10 +470,10 @@ void PlaneGCSSolver_Storage::adjustParametrizationOfArcs()
     if (anArc)
       adjustArcParametrization(*anArc, anEdge->isReversed());
     else {
-////      std::shared_ptr<GCS::ArcOfEllipse> aEllArc =
-////          std::dynamic_pointer_cast<GCS::ArcOfEllipse>(anEdge->entity());
-////      if (aEllArc)
-////        adjustArcParametrization(*aEllArc, anEdge->isReversed());
+      std::shared_ptr<GCS::ArcOfEllipse> aEllArc =
+          std::dynamic_pointer_cast<GCS::ArcOfEllipse>(anEdge->entity());
+      if (aEllArc)
+        adjustArcParametrization(*aEllArc, anEdge->isReversed());
     }
   }
 
index 39b78af57729a6933fb2eeb26289073e9d670456..5aeb10987fe3c5fd56e99bd5eb9ff499a20617e4 100644 (file)
@@ -331,45 +331,37 @@ void PlaneGCSSolver_Tools::recalculateArcParameters(EntityWrapperPtr theArc)
   if (!anEdge)
     return;
 
-  GCS::Point aCenter, aStartPnt, aEndPnt;
-  double *aStartAngle, *aEndAngle;
-  GeomDir2dPtr OX;
-
   if (anEdge->type() == ENTITY_ARC) {
     std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEdge->entity());
 
-    aCenter = anArc->center;
-    aStartPnt = anArc->start;
-    aEndPnt = anArc->end;
+    GCS::Point aCenter = anArc->center;
+    GCS::Point aStartPnt = anArc->start;
+    GCS::Point aEndPnt = anArc->end;
 
     *anArc->rad = distance(aCenter, aStartPnt);
 
-    aStartAngle = anArc->startAngle;
-    aEndAngle = anArc->endAngle;
+    static GeomDir2dPtr OX(new GeomAPI_Dir2d(1.0, 0.0));
+
+    GeomDir2dPtr aDir(new GeomAPI_Dir2d(*aStartPnt.x - *aCenter.x, *aStartPnt.y - *aCenter.y));
+    *anArc->startAngle = OX->angle(aDir);
 
-    OX.reset(new GeomAPI_Dir2d(1.0, 0.0));
+    aDir.reset(new GeomAPI_Dir2d(*aEndPnt.x - *aCenter.x, *aEndPnt.y - *aCenter.y));
+    *anArc->endAngle = OX->angle(aDir);
   }
   else if (anEdge->type() == ENTITY_ELLIPTIC_ARC) {
     std::shared_ptr<GCS::ArcOfEllipse> aEllArc =
         std::dynamic_pointer_cast<GCS::ArcOfEllipse>(anEdge->entity());
 
-    aCenter = aEllArc->center;
-    aStartPnt = aEllArc->start;
-    aEndPnt = aEllArc->end;
-
-    aStartAngle = aEllArc->startAngle;
-    aEndAngle = aEllArc->endAngle;
+    GeomPnt2dPtr aCenter(new GeomAPI_Pnt2d(*aEllArc->center.x, *aEllArc->center.y));
+    GeomPnt2dPtr aStartPnt(new GeomAPI_Pnt2d(*aEllArc->start.x, *aEllArc->start.y));
+    GeomPnt2dPtr aEndPnt(new GeomAPI_Pnt2d(*aEllArc->end.x, *aEllArc->end.y));
 
-    OX.reset(new GeomAPI_Dir2d(*aEllArc->focus1.x - *aCenter.x, *aEllArc->focus1.y - *aCenter.y));
+    GeomDir2dPtr anAxis(new GeomAPI_Dir2d(*aEllArc->focus1.x - aCenter->x(),
+                                          *aEllArc->focus1.y - aCenter->y()));
+    GeomAPI_Ellipse2d anEllipse(aCenter, anAxis, aEllArc->getRadMaj(), *aEllArc->radmin);
+    anEllipse.parameter(aStartPnt, 1.e-4, *aEllArc->startAngle);
+    anEllipse.parameter(aEndPnt, 1.e-4, *aEllArc->endAngle);
   }
-  else // skip other type of entities
-    return;
-
-  GeomDir2dPtr aDir(new GeomAPI_Dir2d(*aStartPnt.x - *aCenter.x, *aStartPnt.y - *aCenter.y));
-  *aStartAngle = OX->angle(aDir);
-
-  aDir.reset(new GeomAPI_Dir2d(*aEndPnt.x - *aCenter.x, *aEndPnt.y - *aCenter.y));
-  *aEndAngle = OX->angle(aDir);
 }
 
 
index 6be506b2591e4eff1b09c806061fb3096f7a223e..7f22fa947f3ca7b7203a6864ce2403f3038c7345 100644 (file)
@@ -30,6 +30,7 @@
 #include <ModelAPI_AttributeRefList.h>
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_Circle.h>
+#include <SketchPlugin_EllipticArc.h>
 
 
 static void mirrorPoints(const std::shared_ptr<GeomAPI_Lin2d>& theMirrorLine,
@@ -194,6 +195,11 @@ void mirrorEntities(const std::shared_ptr<GeomAPI_Lin2d>& theMirrorLine,
     theMirrored->real(SketchPlugin_Circle::RADIUS_ID())->setValue(
         theOriginal->real(SketchPlugin_Circle::RADIUS_ID())->value());
   }
+  else if (theOriginal->getKind() == SketchPlugin_EllipticArc::ID()) {
+    // orientation of arc
+    theMirrored->boolean(SketchPlugin_EllipticArc::REVERSED_ID())->setValue(
+        !theOriginal->boolean(SketchPlugin_EllipticArc::REVERSED_ID())->value());
+  }
 
   // mirror all initialized points of features
   std::list<AttributePtr>::iterator anIt0, anIt1;