From a9a7883a28655bd30a20a9233b0a572f697e9510 Mon Sep 17 00:00:00 2001 From: mpv Date: Tue, 18 Aug 2015 19:14:28 +0300 Subject: [PATCH] Fox for the issue #855: make able to create a sketch arc using keyboard, not only selection in the viewer. --- src/SketchPlugin/SketchPlugin_Arc.cpp | 46 +++++++++++++++++++++++++-- src/SketchPlugin/SketchPlugin_Arc.h | 2 ++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 5a922cbd1..e9f1ab084 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -28,6 +28,9 @@ SketchPlugin_Arc::SketchPlugin_Arc() { myStartUpdate = false; myEndUpdate = false; + // default values + myXEndBefore = 0; + myYEndBefore = 0; } void SketchPlugin_Arc::initAttributes() @@ -36,9 +39,16 @@ void SketchPlugin_Arc::initAttributes() data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId()); data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId()); - data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId()); + std::shared_ptr anEndAttr = std::dynamic_pointer_cast< + GeomDataAPI_Point2D>(data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId())); data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID()); + + // get the initial values + if (anEndAttr->isInitialized()) { + myXEndBefore = anEndAttr->x(); + myYEndBefore = anEndAttr->y(); + } } void SketchPlugin_Arc::execute() @@ -243,12 +253,42 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) std::shared_ptr aCircleForArc( new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt())); std::shared_ptr aProjection = aCircleForArc->project(anEndAttr->pnt()); - if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance) + if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance) { + // issue #855: trying to update only not-updated coordinate if it is possible + if (abs(myXEndBefore - anEndAttr->x()) < 1.e-10) { // keep Y unchanged + double aVy = aCenterAttr->y() - anEndAttr->y(); + double aVy2 = aVy * aVy; + double aR2 = aCircleForArc->radius() * aCircleForArc->radius(); + if (aVy2 <= aR2) { + double aDX = sqrt(aR2 - aVy * aVy); + if (anEndAttr->x() > aCenterAttr->x()) + aProjection->setX(aCenterAttr->x() + aDX); + else + aProjection->setX(aCenterAttr->x() - aDX); + aProjection->setY(anEndAttr->y()); + } + } else if (abs(myYEndBefore - anEndAttr->y()) < 1.e-10) { // keep X unchanged + double aVx = aCenterAttr->x() - anEndAttr->x(); + double aVx2 = aVx * aVx; + double aR2 = aCircleForArc->radius() * aCircleForArc->radius(); + if (aVx2 <= aR2) { + double aDY = sqrt(aR2 - aVx * aVx); + if (anEndAttr->y() > aCenterAttr->y()) + aProjection->setY(aCenterAttr->y() + aDY); + else + aProjection->setY(aCenterAttr->y() - aDY); + aProjection->setX(anEndAttr->x()); + } + } + anEndAttr->setValue(aProjection); + } + myXEndBefore = anEndAttr->x(); + myYEndBefore = anEndAttr->y(); myEndUpdate = false; } else if (theID == START_ID() && !myStartUpdate) { myStartUpdate = true; - // compute and change the arc end point + // compute and change the arc start point std::shared_ptr aCircleForArc( new GeomAPI_Circ2d(aCenterAttr->pnt(), anEndAttr->pnt())); std::shared_ptr aProjection = aCircleForArc->project(aStartAttr->pnt()); diff --git a/src/SketchPlugin/SketchPlugin_Arc.h b/src/SketchPlugin/SketchPlugin_Arc.h index 47a9f9dd4..efb66cf4f 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.h +++ b/src/SketchPlugin/SketchPlugin_Arc.h @@ -24,6 +24,8 @@ class SketchPlugin_Arc : public SketchPlugin_SketchEntity, public GeomAPI_IPrese /// to avoid cyclic dependencies in automatic updates: they mean that /// update is performed right now and automatic updates are not needed bool myStartUpdate, myEndUpdate; + /// to avoid (if possible) additional modification of changed coordinate (issue #855) + double myXEndBefore, myYEndBefore; public: /// Arc feature kind -- 2.39.2