From feb83de70e93d26ac5fc47f8b6ae82ebe965309a Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 16 Apr 2015 07:25:24 +0300 Subject: [PATCH] Precise calculation of the flyout point for the Radius constraint --- .../SketchPlugin_ConstraintRadius.cpp | 57 ++++++++++++++----- .../SketchPlugin_ConstraintRadius.h | 3 + .../SketcherPrs_LengthDimension.cpp | 2 +- src/SketcherPrs/SketcherPrs_Tools.cpp | 35 +++++++++++- src/SketcherPrs/SketcherPrs_Tools.h | 5 +- 5 files changed, 85 insertions(+), 17 deletions(-) diff --git a/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp b/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp index af53efa5d..9530bc2ad 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp @@ -19,12 +19,15 @@ #include #include #include +#include #include #include #include #include +const double tolerance = 1.e-7; + SketchPlugin_ConstraintRadius::SketchPlugin_ConstraintRadius() { } @@ -158,19 +161,9 @@ void SketchPlugin_ConstraintRadius::move(double theDeltaX, double theDeltaY) if (!aData->isValid()) return; - std::shared_ptr aRef = std::dynamic_pointer_cast< - ModelAPI_AttributeRefAttr>(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); - FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object()); - if (!aFeature) - return; - std::string aCenterAttrName; - if (aFeature->getKind() == SketchPlugin_Circle::ID()) - aCenterAttrName = SketchPlugin_Circle::CENTER_ID(); - else if (aFeature->getKind() == SketchPlugin_Arc::ID()) - aCenterAttrName = SketchPlugin_Arc::CENTER_ID(); - std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(aFeature->data()->attribute(aCenterAttrName)); - std::shared_ptr aCenter = aCenterAttr->pnt(); + // The flyout point is calculated in local coordinates of the shape, + // so the center should be coincident with origin + std::shared_ptr aCenter(new GeomAPI_Pnt2d(0.0, 0.0)); // The specified delta applied on the circle curve, // so it will be scaled due to distance between flyout and center points @@ -187,7 +180,9 @@ void SketchPlugin_ConstraintRadius::move(double theDeltaX, double theDeltaY) aFlyout->setY(aFlyout->y() + aScale * theDeltaY); aFlyout = aCircle->project(aFlyout); + myFlyoutUpdate = true; aFlyoutAttr->setValue(aFlyout->x(), aFlyout->y()); + myFlyoutUpdate = false; } void SketchPlugin_ConstraintRadius::attributeChanged(const std::string& theID) { @@ -201,5 +196,41 @@ void SketchPlugin_ConstraintRadius::attributeChanged(const std::string& theID) { aValueAttr->setValue(aRadius); } } + } else if (theID == SketchPlugin_Constraint::FLYOUT_VALUE_PNT() && !myFlyoutUpdate) { + // Recalculate flyout point in local coordinates of the circle (or arc): + // coordinates are calculated according to center of the shape + std::shared_ptr aFlyoutAttr = + std::dynamic_pointer_cast( + attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT())); + + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + attribute(SketchPlugin_Constraint::ENTITY_A())); + if (!aRefAttr || !aRefAttr->isObject()) + return; + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); + if (!aFeature || (aFeature->getKind() != SketchPlugin_Arc::ID() && + aFeature->getKind() != SketchPlugin_Circle::ID())) + return; + + std::string aCenterAttrName; + if (aFeature->getKind() == SketchPlugin_Circle::ID()) + aCenterAttrName = SketchPlugin_Circle::CENTER_ID(); + else if (aFeature->getKind() == SketchPlugin_Arc::ID()) + aCenterAttrName = SketchPlugin_Arc::CENTER_ID(); + std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< + GeomDataAPI_Point2D>(aFeature->data()->attribute(aCenterAttrName)); + std::shared_ptr aCenter = aCenterAttr->pnt(); + std::shared_ptr aRadius = std::dynamic_pointer_cast< + ModelAPI_AttributeDouble>(attribute(SketchPlugin_Constraint::VALUE())); + + std::shared_ptr aFlyoutPnt = aFlyoutAttr->pnt(); + double aDist = aFlyoutPnt->distance(aCenter); + if (aDist < tolerance) + return; + + myFlyoutUpdate = true; + std::shared_ptr aFlyoutDir = aFlyoutPnt->xy()->decreased(aCenter->xy()); + aFlyoutAttr->setValue(aFlyoutDir->x(), aFlyoutDir->y()); + myFlyoutUpdate = false; } } diff --git a/src/SketchPlugin/SketchPlugin_ConstraintRadius.h b/src/SketchPlugin/SketchPlugin_ConstraintRadius.h index 5400bc443..cc2c96eb2 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintRadius.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintRadius.h @@ -65,6 +65,9 @@ private: /// Checks and gets the radius of referenced circle (or arc) otherwise returns -1. /// \param theCircData the found referenced circle returned by this method double circleRadius(std::shared_ptr& theCirc); + +private: + bool myFlyoutUpdate; ///< to avoid cyclic dependencies on automatic updates of flyout point }; #endif diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp index d2b062bfd..99cd15c37 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp @@ -85,7 +85,7 @@ void SketcherPrs_LengthDimension::Compute(const Handle(PrsMgr_PresentationManage //aFlyout = aDist; //SetFlyout(aFlyout); - SetFlyout(SketcherPrs_Tools::getFlyoutDistance(myConstraint, myPlane)); + SetFlyout(SketcherPrs_Tools::getFlyoutDistance(myConstraint)); SetMeasuredGeometry(aPnt1, aPnt2, myPlane->impl()); AIS_LengthDimension::Compute(thePresentationManager, thePresentation, theMode); } diff --git a/src/SketcherPrs/SketcherPrs_Tools.cpp b/src/SketcherPrs/SketcherPrs_Tools.cpp index 8497ec08e..980b28f23 100644 --- a/src/SketcherPrs/SketcherPrs_Tools.cpp +++ b/src/SketcherPrs/SketcherPrs_Tools.cpp @@ -10,9 +10,11 @@ #include #include #include +#include #include #include +#include #include #include @@ -142,8 +144,7 @@ void setArrowSize(double theSize) MyArrowSize = theSize; } -double getFlyoutDistance(const ModelAPI_Feature* theConstraint, - const std::shared_ptr& thePlane) +double getFlyoutDistance(const ModelAPI_Feature* theConstraint) { std::shared_ptr aFlyoutPoint = std::dynamic_pointer_cast( @@ -152,5 +153,35 @@ double getFlyoutDistance(const ModelAPI_Feature* theConstraint, return aFlyoutPoint->y(); } +std::shared_ptr getAnchorPoint(const ModelAPI_Feature* theConstraint, + const std::shared_ptr& thePlane) +{ + ModelAPI_Feature* aConstraint = const_cast(theConstraint); + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); + if (!aRefAttr || !aRefAttr->isObject() || !aRefAttr->object()) + return std::shared_ptr(); + + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); + std::shared_ptr aCenter; + if (aFeature->getKind() == SketchPlugin_Arc::ID()) { + aCenter = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt(); + } else if (aFeature->getKind() == SketchPlugin_Circle::ID()) { + aCenter = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_Circle::CENTER_ID()))->pnt(); + } else + return std::shared_ptr(); + + std::shared_ptr anOrigin(new GeomAPI_Pnt2d(0.0, 0.0)); + std::shared_ptr aFlyoutPnt = std::dynamic_pointer_cast( + aConstraint->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()))->pnt(); + double aRadius = std::dynamic_pointer_cast( + aConstraint->attribute(SketchPlugin_Constraint::VALUE()))->value(); + double aLen = aFlyoutPnt->distance(anOrigin); + aFlyoutPnt->setX(aCenter->x() + aFlyoutPnt->x() * aRadius / aLen); + aFlyoutPnt->setY(aCenter->y() + aFlyoutPnt->y() * aRadius / aLen); + return thePlane->to3D(aFlyoutPnt->x(), aFlyoutPnt->y()); +} }; diff --git a/src/SketcherPrs/SketcherPrs_Tools.h b/src/SketcherPrs/SketcherPrs_Tools.h index bda6b2a73..b2ed89c5b 100644 --- a/src/SketcherPrs/SketcherPrs_Tools.h +++ b/src/SketcherPrs/SketcherPrs_Tools.h @@ -62,7 +62,10 @@ enum SelectionModes { SKETCHERPRS_EXPORT void setArrowSize(double theSize); - SKETCHERPRS_EXPORT double getFlyoutDistance(const ModelAPI_Feature* theConstraint, + SKETCHERPRS_EXPORT double getFlyoutDistance(const ModelAPI_Feature* theConstraint); + + SKETCHERPRS_EXPORT std::shared_ptr getAnchorPoint( + const ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane); }; -- 2.39.2