From 4009aa9938655a349d1151319972149f2d75b3bd Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 3 Oct 2019 10:56:22 +0300 Subject: [PATCH] Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003) Improve constraint Middle point on elliptic arc. --- src/GeomAPI/GeomAPI.i | 11 +++++ src/SketchPlugin/SketchPlugin_Validators.cpp | 3 +- src/SketchPlugin/plugin-Sketch.xml | 4 +- .../PlaneGCSSolver/PlaneGCSSolver_Tools.cpp | 42 ++++++++++++------- .../SketchSolver_ConstraintMiddle.cpp | 32 ++++++++++---- 5 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/GeomAPI/GeomAPI.i b/src/GeomAPI/GeomAPI.i index 56ab015a7..4c4110155 100644 --- a/src/GeomAPI/GeomAPI.i +++ b/src/GeomAPI/GeomAPI.i @@ -103,6 +103,17 @@ } } +%typemap(in) double & (double temp) { + if (PyLong_Check($input)) { + temp = PyLong_AsLong($input); + $1 = &temp; + } +} + +%typemap(argout) double & { + $result = PyFloat_FromDouble(*$1); +} + // all supported interfaces %include "GeomAPI_Interface.h" diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 46a358114..1a255e57e 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -771,7 +771,8 @@ bool SketchPlugin_MiddlePointAttrValidator::isValid(const AttributePtr& theAttri if (aFeature->getKind() == SketchPlugin_Point::ID()) ++aNbPoints; else if (aFeature->getKind() == SketchPlugin_Line::ID() || - aFeature->getKind() == SketchPlugin_Arc::ID()) + aFeature->getKind() == SketchPlugin_Arc::ID() || + aFeature->getKind() == SketchPlugin_EllipticArc::ID()) ++aNbLines; } } diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 69d6a1c71..3db87cbf2 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -1128,7 +1128,7 @@ - + - + diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp index 7f416c66b..ccc07b05b 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp @@ -464,6 +464,27 @@ ConstraintWrapperPtr createConstraintPointsCollinear( new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_PT_ON_CURVE)); } +template +void createConstraintMiddlePointOnArc(ARCTYPE theArc, + GCSPointPtr thePoint, + std::shared_ptr theAuxParameters, + std::list& theConstraints) +{ + double* u = theAuxParameters->point()->x; + double* diff = theAuxParameters->point()->y; + *u = (*theArc->startAngle + *theArc->endAngle) * 0.5; + *diff = (*theArc->endAngle - *theArc->startAngle) * 0.5; + + theConstraints.push_back(GCSConstraintPtr( + new GCS::ConstraintCurveValue(*thePoint, thePoint->x, *theArc, u))); + theConstraints.push_back(GCSConstraintPtr( + new GCS::ConstraintCurveValue(*thePoint, thePoint->y, *theArc, u))); + theConstraints.push_back(GCSConstraintPtr( + new GCS::ConstraintDifference(theArc->startAngle, u, diff))); + theConstraints.push_back(GCSConstraintPtr( + new GCS::ConstraintDifference(u, theArc->endAngle, diff))); +} + ConstraintWrapperPtr createConstraintMiddlePoint( std::shared_ptr thePoint, std::shared_ptr theEntity, @@ -480,20 +501,13 @@ ConstraintWrapperPtr createConstraintMiddlePoint( } else { std::shared_ptr anArc = std::dynamic_pointer_cast(theEntity->entity()); - if (anArc) { - double* u = theAuxParameters->point()->x; - double* diff = theAuxParameters->point()->y; - *u = (*anArc->startAngle + *anArc->endAngle) * 0.5; - *diff = (*anArc->endAngle - *anArc->startAngle) * 0.5; - - aConstrList.push_back(GCSConstraintPtr( - new GCS::ConstraintCurveValue(*aPoint, aPoint->x, *anArc, u))); - aConstrList.push_back(GCSConstraintPtr( - new GCS::ConstraintCurveValue(*aPoint, aPoint->y, *anArc, u))); - aConstrList.push_back(GCSConstraintPtr( - new GCS::ConstraintDifference(anArc->startAngle, u, diff))); - aConstrList.push_back(GCSConstraintPtr( - new GCS::ConstraintDifference(u, anArc->endAngle, diff))); + if (anArc) + createConstraintMiddlePointOnArc(anArc, aPoint, theAuxParameters, aConstrList); + else { + std::shared_ptr aEllArc = + std::dynamic_pointer_cast(theEntity->entity()); + if (aEllArc) + createConstraintMiddlePointOnArc(aEllArc, aPoint, theAuxParameters, aConstrList); } } diff --git a/src/SketchSolver/SketchSolver_ConstraintMiddle.cpp b/src/SketchSolver/SketchSolver_ConstraintMiddle.cpp index 15b8dc285..893747131 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMiddle.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMiddle.cpp @@ -25,6 +25,11 @@ #include #include +static bool isArc(EntityWrapperPtr theEntity) +{ + return theEntity->type() == ENTITY_ARC || theEntity->type() == ENTITY_ELLIPTIC_ARC; +} + void SketchSolver_ConstraintMiddle::getAttributes( EntityWrapperPtr& theValue, std::vector& theAttributes) @@ -32,7 +37,7 @@ void SketchSolver_ConstraintMiddle::getAttributes( SketchSolver_Constraint::getAttributes(theValue, theAttributes); // create auxiliary point if middle point on arc is specified - if (theAttributes[2]->type() == ENTITY_ARC) { + if (isArc(theAttributes[2])) { std::shared_ptr aStorage = std::dynamic_pointer_cast(myStorage); @@ -65,16 +70,25 @@ void SketchSolver_ConstraintMiddle::notify(const FeaturePtr& theFeature, // update the middle point parameter if the constraint is "point-on-arc". if (myOddPoint) { EntityWrapperPtr anArcEntity = - myAttributes.front()->type() == ENTITY_ARC ? myAttributes.front() : myAttributes.back(); + isArc(myAttributes.front()) ? myAttributes.front() : myAttributes.back(); EdgeWrapperPtr anArcEdge = std::dynamic_pointer_cast(anArcEntity); - std::shared_ptr anArc; - if (anArcEdge) - anArc = std::dynamic_pointer_cast(anArcEdge->entity()); - if (anArc) { - // recalculate parameters of middle point according to arc - *myOddPoint->x = (*anArc->startAngle + *anArc->endAngle) * 0.5; - *myOddPoint->y = (*anArc->endAngle - *anArc->startAngle) * 0.5; + if (anArcEdge) { + std::shared_ptr anArc = std::dynamic_pointer_cast(anArcEdge->entity()); + if (anArc) { + // recalculate parameters of middle point according to arc + *myOddPoint->x = (*anArc->startAngle + *anArc->endAngle) * 0.5; + *myOddPoint->y = (*anArc->endAngle - *anArc->startAngle) * 0.5; + } + else { + std::shared_ptr aEllArc = + std::dynamic_pointer_cast(anArcEdge->entity()); + if (aEllArc) { + // recalculate parameters of middle point according to arc + *myOddPoint->x = (*aEllArc->startAngle + *aEllArc->endAngle) * 0.5; + *myOddPoint->y = (*aEllArc->endAngle - *aEllArc->startAngle) * 0.5; + } + } } } return; -- 2.30.2