From 4efa9bb9d29c7dcdd986abcf773058a663e3bfc2 Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 26 Sep 2019 09:44:46 +0300 Subject: [PATCH] Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003) Python API for elliptic arc --- src/ModelHighAPI/ModelHighAPI_Macro.h | 48 ++++ src/SketchAPI/CMakeLists.txt | 4 + src/SketchAPI/SketchAPI.i | 5 + src/SketchAPI/SketchAPI_Ellipse.cpp | 265 ++++++++++-------- src/SketchAPI/SketchAPI_Ellipse.h | 52 +++- src/SketchAPI/SketchAPI_EllipticArc.cpp | 242 ++++++++++++++++ src/SketchAPI/SketchAPI_EllipticArc.h | 164 +++++++++++ src/SketchAPI/SketchAPI_MacroEllipse.cpp | 3 +- src/SketchAPI/SketchAPI_MacroEllipticArc.cpp | 95 +++++++ src/SketchAPI/SketchAPI_MacroEllipticArc.h | 67 +++++ src/SketchAPI/SketchAPI_Sketch.cpp | 66 +++++ src/SketchAPI/SketchAPI_Sketch.h | 33 +++ src/SketchAPI/SketchAPI_SketchEntity.cpp | 3 + src/SketchAPI/SketchAPI_swig.h | 2 + src/SketchPlugin/SketchPlugin_Arc.cpp | 6 +- src/SketchPlugin/SketchPlugin_EllipticArc.cpp | 117 ++++++-- src/SketchPlugin/SketchPlugin_EllipticArc.h | 3 + .../SketchPlugin_MacroEllipticArc.cpp | 49 +--- .../SketchPlugin_MacroEllipticArc.h | 3 - .../PlaneGCSSolver/PlaneGCSSolver_Storage.cpp | 8 +- .../PlaneGCSSolver/PlaneGCSSolver_Tools.cpp | 42 ++- .../SketchSolver_ConstraintMirror.cpp | 6 + 22 files changed, 1046 insertions(+), 237 deletions(-) create mode 100644 src/SketchAPI/SketchAPI_EllipticArc.cpp create mode 100644 src/SketchAPI/SketchAPI_EllipticArc.h create mode 100644 src/SketchAPI/SketchAPI_MacroEllipticArc.cpp create mode 100644 src/SketchAPI/SketchAPI_MacroEllipticArc.h diff --git a/src/ModelHighAPI/ModelHighAPI_Macro.h b/src/ModelHighAPI/ModelHighAPI_Macro.h index 7b7364103..7fd21232c 100644 --- a/src/ModelHighAPI/ModelHighAPI_Macro.h +++ b/src/ModelHighAPI/ModelHighAPI_Macro.h @@ -437,6 +437,54 @@ 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, \ diff --git a/src/SketchAPI/CMakeLists.txt b/src/SketchAPI/CMakeLists.txt index ff40200ab..9d2b423d8 100644 --- a/src/SketchAPI/CMakeLists.txt +++ b/src/SketchAPI/CMakeLists.txt @@ -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 diff --git a/src/SketchAPI/SketchAPI.i b/src/SketchAPI/SketchAPI.i index 8cbda8d3b..08f87c104 100644 --- a/src/SketchAPI/SketchAPI.i +++ b/src/SketchAPI/SketchAPI.i @@ -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) @@ -343,6 +346,8 @@ %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" diff --git a/src/SketchAPI/SketchAPI_Ellipse.cpp b/src/SketchAPI/SketchAPI_Ellipse.cpp index 6bcd6c0dc..19de091d4 100644 --- a/src/SketchAPI/SketchAPI_Ellipse.cpp +++ b/src/SketchAPI/SketchAPI_Ellipse.cpp @@ -147,14 +147,26 @@ void SketchAPI_Ellipse::setMinorRadius(double theMinorRadius) execute(); } -ModelHighAPI_Selection SketchAPI_Ellipse::majorAxis() const +static const std::list& ellipseAttrAndDumpNames() { - return ModelHighAPI_Selection(); -} - -ModelHighAPI_Selection SketchAPI_Ellipse::minorAxis() const -{ - return ModelHighAPI_Selection(); + static std::list 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& theEntities) { + if (theAuxOrName.empty()) + return; + AttributePoint2DPtr anElPoint = std::dynamic_pointer_cast( 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& theEntities) { + if (theAuxOrName.empty()) + return; + AttributePoint2DPtr aStartPoint = std::dynamic_pointer_cast(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 > SketchAPI_Ellipse::construction( @@ -259,53 +279,54 @@ std::list > SketchAPI_Ellipse::construct const std::string& minorAxis) const { FeaturePtr anEllipse = feature(); - CompositeFeaturePtr aSketch = sketchForFeature(anEllipse); + + std::list 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 > SketchAPI_Ellipse::buildConstructionEntities( + const FeaturePtr& theEllipse, + const std::list& 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 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::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& theMajorAxisStartEnd, + const std::pair& theMinorAxisStartEnd, std::map& 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& theMajorAxis, + const std::pair& theMinorAxis, + std::map& theAttrToFeature) +{ + const std::set& aRefs = theEllipse->data()->refsToMe(); + for (std::set::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 anAuxFeatures; - const std::set& aRefs = aBase->data()->refsToMe(); - for (std::set::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 aMajorAxis( + SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(), + SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()); + static const std::pair aMinorAxis( + SketchPlugin_Ellipse::MINOR_AXIS_START_ID(), + SketchPlugin_Ellipse::MINOR_AXIS_END_ID()); + collectAuxiliaryFeatures(aBase, aMajorAxis, aMinorAxis, anAuxFeatures); + if (!anAuxFeatures.empty()) { - typedef std::pair 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::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::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& anAttributes = ellipseAttrAndDumpNames(); + dumpConstructionEntities(theDumper, aBase, anAttributes, anAuxFeatures); + } +} + +void SketchAPI_Ellipse::dumpConstructionEntities( + ModelHighAPI_Dumper& theDumper, + const FeaturePtr& theEllipse, + const std::list& theAttributes, + const std::map& theAuxFeatures) +{ + std::list 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::iterator anIt = anAttributes.begin(); + anIt != anAttributes.end(); ++anIt) { + std::map::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::iterator anIt = anAttributes.begin(); + anIt != anAttributes.end(); ++anIt) { + std::map::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; } diff --git a/src/SketchAPI/SketchAPI_Ellipse.h b/src/SketchAPI/SketchAPI_Ellipse.h index ee79357c8..598d41356 100644 --- a/src/SketchAPI/SketchAPI_Ellipse.h +++ b/src/SketchAPI/SketchAPI_Ellipse.h @@ -27,6 +27,8 @@ class ModelHighAPI_Selection; +typedef std::pair 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 & theCenter); + void setCenter(const std::shared_ptr& theCenter); /// Set focus. SKETCHAPI_EXPORT @@ -121,20 +123,12 @@ public: /// Set focus. SKETCHAPI_EXPORT - void setFocus(const std::shared_ptr & theCenter); + void setFocus(const std::shared_ptr& 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& 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& theAttributes, + const std::map& theAuxFeatures); + + /// \brief Create construction features for the ellipse connected + /// with corresponding attribute of ellipse. + static std::list > buildConstructionEntities( + const FeaturePtr& theEllipse, + const std::list& 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 index 000000000..dd7d905c8 --- /dev/null +++ b/src/SketchAPI/SketchAPI_EllipticArc.cpp @@ -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 + +#include +#include +#include + +#include +#include +#include + + +SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr & theFeature) + : SketchAPI_SketchEntity(theFeature) +{ + initialize(); +} + +SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr& 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& theFeature, + const std::shared_ptr& theCenter, + const std::shared_ptr& theFocus, + const std::shared_ptr& theStart, + const std::shared_ptr& theEnd, + bool theInversed) + : SketchAPI_SketchEntity(theFeature) +{ + if(initialize()) { + setByCenterFocusAndPoints(theCenter, theFocus, theStart, theEnd, theInversed); + } +} + +SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theExternal) + : SketchAPI_SketchEntity(theFeature) +{ + if (initialize()) { + setByExternal(theExternal); + } +} + +SketchAPI_EllipticArc::SketchAPI_EllipticArc(const std::shared_ptr& 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& theCenter, + const std::shared_ptr& theFocus, + const std::shared_ptr& theStart, + const std::shared_ptr& 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 & 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 & theFocus) +{ + fillAttribute(theFocus, myfirstFocus); + execute(); +} + +static const std::list& ellipticArcAttrAndDumpNames() +{ + static std::list 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 > 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 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 anAuxFeatures; + static const std::pair aMajorAxis( + SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID(), + SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID()); + static const std::pair 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 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 index 000000000..dea054449 --- /dev/null +++ b/src/SketchAPI/SketchAPI_EllipticArc.h @@ -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 + +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& theFeature); + + /// Constructor with values. + SKETCHAPI_EXPORT + SketchAPI_EllipticArc(const std::shared_ptr& 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& theFeature, + const std::shared_ptr& theCenter, + const std::shared_ptr& theFocus, + const std::shared_ptr& theStart, + const std::shared_ptr& theEnd, + bool theInversed); + + /// Constructor with external. + SKETCHAPI_EXPORT + SketchAPI_EllipticArc(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theExternal); + + /// Constructor with external. + SKETCHAPI_EXPORT + SketchAPI_EllipticArc(const std::shared_ptr& 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& theCenter, + const std::shared_ptr& theFocus, + const std::shared_ptr& theStart, + const std::shared_ptr& 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 & theCenter); + + /// Set focus. + SKETCHAPI_EXPORT + void setFocus(double theX, double theY); + + /// Set focus. + SKETCHAPI_EXPORT + void setFocus(const std::shared_ptr & 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 > 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 EllipticArcPtr; + +#endif // SketchAPI_EllipticArc_H_ diff --git a/src/SketchAPI/SketchAPI_MacroEllipse.cpp b/src/SketchAPI/SketchAPI_MacroEllipse.cpp index c3ed48080..3a4ef16d3 100644 --- a/src/SketchAPI/SketchAPI_MacroEllipse.cpp +++ b/src/SketchAPI/SketchAPI_MacroEllipse.cpp @@ -59,7 +59,8 @@ static CompositeFeaturePtr sketch(FeaturePtr theFeature) SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr& theFeature) : SketchAPI_SketchEntity(theFeature) { - initialize(); + if (initialize()) + mySketch = sketch(theFeature); } SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr& theFeature, diff --git a/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp b/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp new file mode 100644 index 000000000..4702bc84b --- /dev/null +++ b/src/SketchAPI/SketchAPI_MacroEllipticArc.cpp @@ -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 + +#include +#include + +#include + +#define CENTER_POINT (std::dynamic_pointer_cast( \ + feature()->attribute(SketchPlugin_MacroEllipticArc::CENTER_ID()))) +#define MAJOR_AXIS_POSITIVE (std::dynamic_pointer_cast( \ + feature()->attribute(SketchPlugin_MacroEllipticArc::MAJOR_AXIS_POINT_ID()))) +#define START_POINT (std::dynamic_pointer_cast( \ + feature()->attribute(SketchPlugin_MacroEllipticArc::START_POINT_ID()))) +#define END_POINT (std::dynamic_pointer_cast( \ + 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& thePoint, + const ModelHighAPI_RefAttr& thePointRef, + std::shared_ptr thePointAttr, + AttributeRefAttrPtr thePointRefAttr) +{ + GeomPnt2dPtr aPoint = thePoint; + if (!thePointRef.isEmpty()) { + fillAttribute(thePointRef, thePointRefAttr); + std::shared_ptr anAttrPnt = + std::dynamic_pointer_cast(thePointRefAttr->attr()); + if (anAttrPnt) + aPoint = anAttrPnt->pnt(); + } + fillAttribute(aPoint, thePointAttr); +} + +SketchAPI_MacroEllipticArc::SketchAPI_MacroEllipticArc(const std::shared_ptr& theFeature) + : SketchAPI_MacroEllipse(theFeature) +{ +} + +SketchAPI_MacroEllipticArc::SketchAPI_MacroEllipticArc( + const std::shared_ptr& theFeature, + const std::shared_ptr& theCenter, + const ModelHighAPI_RefAttr& theCenterRef, + const std::shared_ptr& theMajorAxisPoint, + const ModelHighAPI_RefAttr& theMajorAxisPointRef, + const std::shared_ptr& theArcStart, + const ModelHighAPI_RefAttr& theArcStartRef, + const std::shared_ptr& 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 index 000000000..51eb3a337 --- /dev/null +++ b/src/SketchAPI/SketchAPI_MacroEllipticArc.h @@ -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 + +/// \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& theFeature); + + /// Constructor with values and/or references. + SKETCHAPI_EXPORT + SketchAPI_MacroEllipticArc(const std::shared_ptr& theFeature, + const std::shared_ptr& theCenter, + const ModelHighAPI_RefAttr& theCenterRef, + const std::shared_ptr& theMajorAxisPoint, + const ModelHighAPI_RefAttr& theMajorAxisPointRef, + const std::shared_ptr& theArcStart, + const ModelHighAPI_RefAttr& theArcStartRef, + const std::shared_ptr& 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 MacroEllipticArcPtr; + +#endif // SketchAPI_MacroEllipticArc_H_ diff --git a/src/SketchAPI/SketchAPI_Sketch.cpp b/src/SketchAPI/SketchAPI_Sketch.cpp index 5a329558f..cfcf93b7b 100644 --- a/src/SketchAPI/SketchAPI_Sketch.cpp +++ b/src/SketchAPI/SketchAPI_Sketch.cpp @@ -55,11 +55,13 @@ #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_Sketch::addEllipse( return EllipsePtr(new SketchAPI_Ellipse(aFeature, theExternalName)); } +//-------------------------------------------------------------------------------------- +std::shared_ptr SketchAPI_Sketch::addEllipticArc( + double theCenterX, double theCenterY, + double theFocusX, double theFocusY, + double theStartX, double theStartY, + double theEndX, double theEndY, + bool theInversed) +{ + std::shared_ptr 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_Sketch::addEllipticArc( + const std::shared_ptr& theCenter, + const std::shared_ptr& theFocus, + const std::shared_ptr& theStart, + const std::shared_ptr& theEnd, + bool theInversed) +{ + std::shared_ptr aFeature = + compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID()); + return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, + theCenter, theFocus, theStart, theEnd, theInversed)); +} + +std::shared_ptr SketchAPI_Sketch::addEllipticArc( + const std::pair, ModelHighAPI_RefAttr>& theCenter, + const std::pair, ModelHighAPI_RefAttr>& theMajorAxisPoint, + const std::pair, ModelHighAPI_RefAttr>& theStartPoint, + const std::pair, ModelHighAPI_RefAttr>& theEndPoint, + bool theInversed) +{ + std::shared_ptr 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_Sketch::addEllipticArc( + const ModelHighAPI_Selection & theExternal) +{ + std::shared_ptr aFeature = + compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID()); + return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, theExternal)); +} + +std::shared_ptr SketchAPI_Sketch::addEllipticArc( + const std::string & theExternalName) +{ + std::shared_ptr aFeature = + compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID()); + return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, theExternalName)); +} + //-------------------------------------------------------------------------------------- std::shared_ptr SketchAPI_Sketch::addProjection( const ModelHighAPI_Selection & theExternalFeature, diff --git a/src/SketchAPI/SketchAPI_Sketch.h b/src/SketchAPI/SketchAPI_Sketch.h index 726250f6d..2f722b5e5 100644 --- a/src/SketchAPI/SketchAPI_Sketch.h +++ b/src/SketchAPI/SketchAPI_Sketch.h @@ -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 addEllipse(const std::string & theExternalName); + /// Add elliptic arc + SKETCHAPI_EXPORT + std::shared_ptr 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 addEllipticArc( + const std::shared_ptr& theCenter, + const std::shared_ptr& theFocus, + const std::shared_ptr& theStart, + const std::shared_ptr& theEnd, + bool theInversed = false); + /// Add elliptic arc + SKETCHAPI_EXPORT + std::shared_ptr addEllipticArc( + const std::pair, ModelHighAPI_RefAttr>& theCenter, + const std::pair, ModelHighAPI_RefAttr>& theMajorAxisPoint, + const std::pair, ModelHighAPI_RefAttr>& theStartPoint, + const std::pair, ModelHighAPI_RefAttr>& theEndPoint, + bool theInversed = false); + /// Add elliptic arc + SKETCHAPI_EXPORT + std::shared_ptr addEllipticArc(const ModelHighAPI_Selection & theExternal); + /// Add elliptic arc + SKETCHAPI_EXPORT + std::shared_ptr addEllipticArc(const std::string & theExternalName); + /// Add projection SKETCHAPI_EXPORT std::shared_ptr addProjection( diff --git a/src/SketchAPI/SketchAPI_SketchEntity.cpp b/src/SketchAPI/SketchAPI_SketchEntity.cpp index 5c7202268..467e04349 100644 --- a/src/SketchAPI/SketchAPI_SketchEntity.cpp +++ b/src/SketchAPI/SketchAPI_SketchEntity.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -100,6 +101,8 @@ SketchAPI_SketchEntity::wrap(const std::list > aResult.push_back(std::shared_ptr(new SketchAPI_Circle(*anIt))); else if ((*anIt)->getKind() == SketchPlugin_Ellipse::ID()) aResult.push_back(std::shared_ptr(new SketchAPI_Ellipse(*anIt))); + else if ((*anIt)->getKind() == SketchPlugin_EllipticArc::ID()) + aResult.push_back(std::shared_ptr(new SketchAPI_EllipticArc(*anIt))); else if ((*anIt)->getKind() == SketchPlugin_Point::ID()) aResult.push_back(std::shared_ptr(new SketchAPI_Point(*anIt))); else if ((*anIt)->getKind() == SketchPlugin_IntersectionPoint::ID()) diff --git a/src/SketchAPI/SketchAPI_swig.h b/src/SketchAPI/SketchAPI_swig.h index fa19b36c2..93788350b 100644 --- a/src/SketchAPI/SketchAPI_swig.h +++ b/src/SketchAPI/SketchAPI_swig.h @@ -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" diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 85fb67425..1cd476011 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -52,9 +52,9 @@ // for sqrt on Linux #include -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() diff --git a/src/SketchPlugin/SketchPlugin_EllipticArc.cpp b/src/SketchPlugin/SketchPlugin_EllipticArc.cpp index 3bc24f1cc..a5c2b29fb 100644 --- a/src/SketchPlugin/SketchPlugin_EllipticArc.cpp +++ b/src/SketchPlugin/SketchPlugin_EllipticArc.cpp @@ -25,7 +25,9 @@ #include #include #include +#include #include +#include #include @@ -37,10 +39,13 @@ #include 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 anEdge( new GeomAPI_Edge(aSelection)); + std::shared_ptr anEdge(new GeomAPI_Edge(aSelection)); std::shared_ptr anEllipse = anEdge->ellipse(); std::shared_ptr aCenterAttr = - std::dynamic_pointer_cast(attribute(CENTER_ID())); + std::dynamic_pointer_cast(attribute(CENTER_ID())); aCenterAttr->setValue(sketch()->to2D(anEllipse->center())); std::shared_ptr aFocusAttr = - std::dynamic_pointer_cast(attribute(FIRST_FOCUS_ID())); + std::dynamic_pointer_cast(attribute(FIRST_FOCUS_ID())); aFocusAttr->setValue(sketch()->to2D(anEllipse->firstFocus())); std::shared_ptr aStartAttr = - std::dynamic_pointer_cast(attribute(START_POINT_ID())); + std::dynamic_pointer_cast(attribute(START_POINT_ID())); aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint())); std::shared_ptr aEndAttr = - std::dynamic_pointer_cast(attribute(END_POINT_ID())); + std::dynamic_pointer_cast(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 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 aCenterAttr = - std::dynamic_pointer_cast(data()->attribute(CENTER_ID())); + std::dynamic_pointer_cast(data()->attribute(CENTER_ID())); std::shared_ptr aFocusAttr = - std::dynamic_pointer_cast(data()->attribute(FIRST_FOCUS_ID())); - - AttributeDoublePtr aMinorRadiusAttr = real(MINOR_RADIUS_ID()); + std::dynamic_pointer_cast(data()->attribute(FIRST_FOCUS_ID())); + std::shared_ptr aStartPointAttr = + std::dynamic_pointer_cast(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(attribute(SECOND_FOCUS_ID())) ->setValue(2.0 * aCenter2d->x() - aFocus2d->x(), 2.0 * aCenter2d->y() - aFocus2d->y()); std::dynamic_pointer_cast(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(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(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(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 aEndPointAttr = + std::dynamic_pointer_cast(data()->attribute(END_POINT_ID())); + if (aEndPointAttr->isInitialized()) { + // recalculate REVERSED flag + std::shared_ptr anEllipseForArc( + new GeomAPI_Ellipse2d(aCenter2d, aMajorDir2d, aMajorRadius, aMinorRadius)); + GeomPnt2dPtr anEnd = aEndPointAttr->pnt(); + std::shared_ptr 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); diff --git a/src/SketchPlugin/SketchPlugin_EllipticArc.h b/src/SketchPlugin/SketchPlugin_EllipticArc.h index b6c6e1c71..f3730d166 100644 --- a/src/SketchPlugin/SketchPlugin_EllipticArc.h +++ b/src/SketchPlugin/SketchPlugin_EllipticArc.h @@ -144,6 +144,9 @@ private: bool fillCharacteristicPoints(); void createEllipticArc(SketchPlugin_Sketch* theSketch); + +private: + double myParamDelta; }; #endif diff --git a/src/SketchPlugin/SketchPlugin_MacroEllipticArc.cpp b/src/SketchPlugin/SketchPlugin_MacroEllipticArc.cpp index 768e82713..ab87ca57f 100644 --- a/src/SketchPlugin/SketchPlugin_MacroEllipticArc.cpp +++ b/src/SketchPlugin/SketchPlugin_MacroEllipticArc.cpp @@ -19,11 +19,8 @@ #include -////#include #include -////#include #include -////#include #include #include @@ -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(); diff --git a/src/SketchPlugin/SketchPlugin_MacroEllipticArc.h b/src/SketchPlugin/SketchPlugin_MacroEllipticArc.h index d0c8982c4..5c43f6784 100644 --- a/src/SketchPlugin/SketchPlugin_MacroEllipticArc.h +++ b/src/SketchPlugin/SketchPlugin_MacroEllipticArc.h @@ -158,9 +158,6 @@ class SketchPlugin_MacroEllipticArc: public SketchPlugin_SketchEntity, private: std::shared_ptr getArcShape(); -//// void constraintsForEllipseByCenterAxisAndPassed(FeaturePtr theEllipseFeature); -//// void constraintsForEllipseByMajoxAxisAndPassed(FeaturePtr theEllipseFeature); - FeaturePtr createEllipticArcFeature(); private: diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 4a9ae8a5a..4b89a59dc 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -470,10 +470,10 @@ void PlaneGCSSolver_Storage::adjustParametrizationOfArcs() if (anArc) adjustArcParametrization(*anArc, anEdge->isReversed()); else { -//// std::shared_ptr aEllArc = -//// std::dynamic_pointer_cast(anEdge->entity()); -//// if (aEllArc) -//// adjustArcParametrization(*aEllArc, anEdge->isReversed()); + std::shared_ptr aEllArc = + std::dynamic_pointer_cast(anEdge->entity()); + if (aEllArc) + adjustArcParametrization(*aEllArc, anEdge->isReversed()); } } diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp index 39b78af57..5aeb10987 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp @@ -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 anArc = std::dynamic_pointer_cast(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 aEllArc = std::dynamic_pointer_cast(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); } diff --git a/src/SketchSolver/SketchSolver_ConstraintMirror.cpp b/src/SketchSolver/SketchSolver_ConstraintMirror.cpp index 6be506b25..7f22fa947 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMirror.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMirror.cpp @@ -30,6 +30,7 @@ #include #include #include +#include static void mirrorPoints(const std::shared_ptr& theMirrorLine, @@ -194,6 +195,11 @@ void mirrorEntities(const std::shared_ptr& 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::iterator anIt0, anIt1; -- 2.39.2