From f5086eebab1d538a0e8b2b655ed6729fcba0da86 Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 26 Sep 2019 15:45:19 +0300 Subject: [PATCH] Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003) Constraint Equal for ellipses and elliptic arcs. This is a workaround for PlaneGCS. It avoids using GCS::ConstraintEqualMajorAxesConic which changes parameters of the curves (updates pointers in curves to own array). --- src/SketchPlugin/SketchPlugin_Validators.cpp | 7 ++-- .../PlaneGCSSolver/PlaneGCSSolver_Defs.h | 1 + .../PlaneGCSSolver/PlaneGCSSolver_Tools.cpp | 34 +++++++++++-------- .../SketchSolver_ConstraintEqual.cpp | 7 +++- .../SketchSolver_ConstraintEqual.h | 3 ++ 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index a889f1068..b8c9de51f 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -26,6 +26,7 @@ #include "SketchPlugin_ConstraintRigid.h" #include "SketchPlugin_ConstraintTangent.h" #include "SketchPlugin_Ellipse.h" +#include "SketchPlugin_EllipticArc.h" #include "SketchPlugin_Fillet.h" #include "SketchPlugin_Line.h" #include "SketchPlugin_MacroArc.h" @@ -307,7 +308,8 @@ bool SketchPlugin_EqualAttrValidator::isValid(const AttributePtr& theAttribute, if (aFeature->getKind() != SketchPlugin_Line::ID() && aFeature->getKind() != SketchPlugin_Circle::ID() && aFeature->getKind() != SketchPlugin_Arc::ID() && - aFeature->getKind() != SketchPlugin_Ellipse::ID()) { + aFeature->getKind() != SketchPlugin_Ellipse::ID() && + aFeature->getKind() != SketchPlugin_EllipticArc::ID()) { theError = "The %1 feature is not supported by the Equal constraint."; theError.arg(aFeature->getKind()); // wrong type of attribute @@ -323,7 +325,8 @@ bool SketchPlugin_EqualAttrValidator::isValid(const AttributePtr& theAttribute, } if (!isOk) { // ellipse and elliptic arc may be equal - // TODO + isOk = (aType[0] == SketchPlugin_EllipticArc::ID() && aType[1] == SketchPlugin_Ellipse::ID()) + || (aType[0] == SketchPlugin_Ellipse::ID() && aType[1] == SketchPlugin_EllipticArc::ID()); } if (!isOk) { theError = "Features with kinds %1 and %2 can not be equal."; diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h index b4e0056e2..fc543f5b0 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h @@ -79,6 +79,7 @@ enum SketchSolver_ConstraintType { CONSTRAINT_EQUAL_LINES, CONSTRAINT_EQUAL_LINE_ARC, CONSTRAINT_EQUAL_RADIUS, + CONSTRAINT_EQUAL_ELLIPSES, CONSTRAINT_TANGENT, // base tangency if we don't know the measured objects yet CONSTRAINT_TANGENT_CIRCLE_LINE, CONSTRAINT_TANGENT_CURVE_CURVE, diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp index 5aeb10987..35cbb4d72 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp @@ -241,6 +241,7 @@ ConstraintWrapperPtr PlaneGCSSolver_Tools::createConstraint( GCS_EDGE_WRAPPER(theEntity2)); break; case CONSTRAINT_EQUAL_LINES: + case CONSTRAINT_EQUAL_ELLIPSES: anIntermediate = GCS_SCALAR_WRAPPER(theValue); // parameter is used to store length of lines case CONSTRAINT_EQUAL_LINE_ARC: case CONSTRAINT_EQUAL_RADIUS: @@ -654,25 +655,28 @@ ConstraintWrapperPtr createConstraintEqual( new GCS::ConstraintP2PDistance(aLine2->p1, aLine2->p2, theIntermed->scalar()))); // update value of intermediate parameter theIntermed->setValue(distance(aLine1->p1, aLine1->p2)); - } else { + } + else if (theType == CONSTRAINT_EQUAL_ELLIPSES) { + std::shared_ptr anEllipse1 = + std::dynamic_pointer_cast(theEntity1->entity()); + std::shared_ptr anEllipse2 = + std::dynamic_pointer_cast(theEntity2->entity()); + + aConstrList.push_back(GCSConstraintPtr( + new GCS::ConstraintEqual(anEllipse1->radmin, anEllipse2->radmin))); + aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance( + anEllipse1->center, anEllipse1->focus1, theIntermed->scalar()))); + aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance( + anEllipse2->center, anEllipse2->focus1, theIntermed->scalar()))); + // update value of intermediate parameter + theIntermed->setValue(distance(anEllipse1->center, anEllipse1->focus1)); + } + else { std::shared_ptr aCirc1 = std::dynamic_pointer_cast(theEntity1->entity()); std::shared_ptr aCirc2 = std::dynamic_pointer_cast(theEntity2->entity()); - - if (aCirc1 && aCirc2) - aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(aCirc1->rad, aCirc2->rad))); - else { - std::shared_ptr anEllipse1 = - std::dynamic_pointer_cast(theEntity1->entity()); - std::shared_ptr anEllipse2 = - std::dynamic_pointer_cast(theEntity2->entity()); - - aConstrList.push_back(GCSConstraintPtr( - new GCS::ConstraintEqual(anEllipse1->radmin, anEllipse2->radmin))); - aConstrList.push_back(GCSConstraintPtr( - new GCS::ConstraintEqualMajorAxesConic(anEllipse1.get(), anEllipse2.get()))); - } + aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(aCirc1->rad, aCirc2->rad))); } std::shared_ptr aResult( diff --git a/src/SketchSolver/SketchSolver_ConstraintEqual.cpp b/src/SketchSolver/SketchSolver_ConstraintEqual.cpp index 8d3bab21b..1218c072e 100644 --- a/src/SketchSolver/SketchSolver_ConstraintEqual.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintEqual.cpp @@ -63,7 +63,12 @@ void SketchSolver_ConstraintEqual::getAttributes( switch (aNbLines) { case 0: - myType = CONSTRAINT_EQUAL_RADIUS; + if (aNbEllipses == 2) { + myType = CONSTRAINT_EQUAL_ELLIPSES; + theValue = ScalarWrapperPtr(new PlaneGCSSolver_ScalarWrapper(&myAuxValue)); + } + else + myType = CONSTRAINT_EQUAL_RADIUS; break; case 1: myType = CONSTRAINT_EQUAL_LINE_ARC; diff --git a/src/SketchSolver/SketchSolver_ConstraintEqual.h b/src/SketchSolver/SketchSolver_ConstraintEqual.h index b7495d2d8..a7505be5f 100644 --- a/src/SketchSolver/SketchSolver_ConstraintEqual.h +++ b/src/SketchSolver/SketchSolver_ConstraintEqual.h @@ -40,6 +40,9 @@ protected: /// \param[out] theAttributes list of attributes to be filled virtual void getAttributes(EntityWrapperPtr& theValue, std::vector& theAttributes); + +private: + double myAuxValue; ///< scalar value to store ellipses focus distance }; #endif -- 2.39.2