From cc7a7d32e0b6e31f65013e016055e9708283a289 Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 28 Nov 2014 11:22:38 +0300 Subject: [PATCH] Issue #262: the updated points of arc now projected back to initial circle --- src/ModelAPI/ModelAPI_Result.h | 2 +- src/SketchPlugin/SketchPlugin_Arc.cpp | 96 +++++++++++++------ src/SketchPlugin/SketchPlugin_Arc.h | 8 ++ src/SketchPlugin/Test/TestConstraintRadius.py | 7 +- src/SketchPlugin/Test/TestSketchArcCircle.py | 52 +++++----- 5 files changed, 109 insertions(+), 56 deletions(-) diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index 91304744e..cde508254 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -6,7 +6,7 @@ #define ModelAPI_Result_H_ #include "ModelAPI_Object.h" -#include "GeomAPI_Shape.h" +#include class ModelAPI_Feature; diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 9f717bd70..0ae869322 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -23,6 +23,8 @@ const double tolerance = 1e-7; SketchPlugin_Arc::SketchPlugin_Arc() : SketchPlugin_Feature() { + myStartUpdate = false; + myEndUpdate = false; } void SketchPlugin_Arc::initAttributes() @@ -42,10 +44,10 @@ void SketchPlugin_Arc::execute() if (aSketch && isFeatureValid()) { // compute a circle point in 3D view std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::CENTER_ID())); + GeomDataAPI_Point2D>(data()->attribute(CENTER_ID())); // compute the arc start point std::shared_ptr aStartAttr = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID())); + GeomDataAPI_Point2D>(data()->attribute(START_ID())); std::shared_ptr aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y())); // make a visible point @@ -59,30 +61,29 @@ void SketchPlugin_Arc::execute() // make a visible circle std::shared_ptr aNDir = std::dynamic_pointer_cast( aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID())); - bool aHasPlane = aNDir && !(aNDir->x() == 0 && aNDir->y() == 0 && aNDir->z() == 0); - if (aHasPlane) { - std::shared_ptr aNormal = aNDir->dir(); - std::shared_ptr aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y())); - - // compute and change the arc end point - std::shared_ptr anEndAttr = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::END_ID())); - 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) - anEndAttr->setValue(aProjection); - std::shared_ptr aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y())); - - std::shared_ptr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc( - aCenter, aStartPoint, aEndPoint, aNormal); - if (aCircleShape) { - std::shared_ptr aConstr2 = document()->createConstruction( - data(), 1); - aConstr2->setShape(aCircleShape); - aConstr2->setIsInHistory(false); - setResult(aConstr2, 1); - } + std::shared_ptr aNormal = aNDir->dir(); + std::shared_ptr aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y())); + + // compute and change the arc end point + std::shared_ptr anEndAttr = std::dynamic_pointer_cast< + GeomDataAPI_Point2D>(data()->attribute(END_ID())); + /* must be automatically done in attributeChanged + 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) + anEndAttr->setValue(aProjection); + */ + std::shared_ptr aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y())); + + std::shared_ptr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc( + aCenter, aStartPoint, aEndPoint, aNormal); + if (aCircleShape) { + std::shared_ptr aConstr2 = document()->createConstruction( + data(), 1); + aConstr2->setShape(aCircleShape); + aConstr2->setIsInHistory(false); + setResult(aConstr2, 1); } } } @@ -95,7 +96,7 @@ AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious) if (!isFeatureValid()) { // compute a circle point in 3D view std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::CENTER_ID())); + GeomDataAPI_Point2D>(data()->attribute(CENTER_ID())); if (aCenterAttr->isInitialized()) { std::shared_ptr aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y())); @@ -146,6 +147,8 @@ void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY) aData->attribute(SketchPlugin_Arc::CENTER_ID())); aPoint1->move(theDeltaX, theDeltaY); + myStartUpdate = true; + myEndUpdate = true; std::shared_ptr aPoint2 = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Arc::START_ID())); aPoint2->move(theDeltaX, theDeltaY); @@ -153,6 +156,8 @@ void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY) std::shared_ptr aPoint3 = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Arc::END_ID())); aPoint3->move(theDeltaX, theDeltaY); + myStartUpdate = false; + myEndUpdate = false; } double SketchPlugin_Arc::distanceToPoint(const std::shared_ptr& thePoint) @@ -194,3 +199,40 @@ bool SketchPlugin_Arc::isFeatureValid() return aCenterAttr->isInitialized() && aStartAttr->isInitialized() && anEndAttr->isInitialized(); } + +void SketchPlugin_Arc::attributeChanged(const std::string& theID) +{ + std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< + GeomDataAPI_Point2D>(data()->attribute(CENTER_ID())); + if (!aCenterAttr->isInitialized()) + return; + std::shared_ptr aStartAttr = std::dynamic_pointer_cast< + GeomDataAPI_Point2D>(data()->attribute(START_ID())); + if (!aStartAttr->isInitialized()) + return; + std::shared_ptr anEndAttr = std::dynamic_pointer_cast< + GeomDataAPI_Point2D>(data()->attribute(END_ID())); + if (!anEndAttr->isInitialized()) + return; + + // update the points in accordance to the changed point changes + if (theID == END_ID() && !myEndUpdate) { + myEndUpdate = true; + // compute and change the arc end point + 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) + anEndAttr->setValue(aProjection); + myEndUpdate = false; + } else if (theID == START_ID() && !myStartUpdate) { + myStartUpdate = true; + // compute and change the arc end point + std::shared_ptr aCircleForArc( + new GeomAPI_Circ2d(aCenterAttr->pnt(), anEndAttr->pnt())); + std::shared_ptr aProjection = aCircleForArc->project(aStartAttr->pnt()); + if (aProjection && aStartAttr->pnt()->distance(aProjection) > tolerance) + aStartAttr->setValue(aProjection); + myStartUpdate = false; + } +} diff --git a/src/SketchPlugin/SketchPlugin_Arc.h b/src/SketchPlugin/SketchPlugin_Arc.h index 3958adbd7..e03da285a 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.h +++ b/src/SketchPlugin/SketchPlugin_Arc.h @@ -19,6 +19,10 @@ */ class SketchPlugin_Arc : public SketchPlugin_Feature, public GeomAPI_IPresentable { + /// to avoid cyclic dependencies in automatic updates: they mean that + /// update is performed right now and automatic updates are not needed + bool myStartUpdate, myEndUpdate; + public: /// Arc feature kind inline static const std::string& ID() @@ -62,6 +66,10 @@ class SketchPlugin_Arc : public SketchPlugin_Feature, public GeomAPI_IPresentabl /// Request for initialization of data model of the feature: adding all attributes SKETCHPLUGIN_EXPORT virtual void initAttributes(); + /// Called on change of any argument-attribute of this object + /// \param theID identifier of changed attribute + SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + /// Returns the AIS preview virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious); diff --git a/src/SketchPlugin/Test/TestConstraintRadius.py b/src/SketchPlugin/Test/TestConstraintRadius.py index afe60ba4f..cc71a412f 100644 --- a/src/SketchPlugin/Test/TestConstraintRadius.py +++ b/src/SketchPlugin/Test/TestConstraintRadius.py @@ -107,12 +107,13 @@ assert (anArcPrevEndPointX == 50.) assert (anArcPrevEndPointY == 0.) # Move one point of the arc aSession.startOperation() -anArcStartPoint.setValue(0., 60) +anArcStartPoint.setValue(0, 60) aSession.finishOperation() assert (anArcCentr.x() == 10.) assert (anArcCentr.y() == 10.) -assert (anArcEndPoint.x() != anArcPrevEndPointX) -assert (anArcEndPoint.y() != anArcPrevEndPointY) +# MPV: it just projects back to the circle the moved start point +#assert (anArcEndPoint.x() != anArcPrevEndPointX) +#assert (anArcEndPoint.y() != anArcPrevEndPointY) #========================================================================= # 4. Move the centr or the point of the arc # 5. Check radius is the same diff --git a/src/SketchPlugin/Test/TestSketchArcCircle.py b/src/SketchPlugin/Test/TestSketchArcCircle.py index 8ce7a3186..c59725e21 100644 --- a/src/SketchPlugin/Test/TestSketchArcCircle.py +++ b/src/SketchPlugin/Test/TestSketchArcCircle.py @@ -86,31 +86,33 @@ assert (anArcEndPoint.y() == 0.0) # 1. Move whole arc # 2. Change the start point #========================================================================= -aSession.startOperation() -deltaX, deltaY = 5., 10. -anArcCentr.setValue(anArcCentr.x() + deltaX, anArcCentr.y() + deltaY) -anArcStartPoint.setValue( - anArcStartPoint.x() + deltaX, anArcStartPoint.y() + deltaY) -anArcEndPoint.setValue(anArcEndPoint.x() + deltaX, anArcEndPoint.y() + deltaY) -aSession.finishOperation() -assert (anArcCentr.x() == 15) -assert (anArcCentr.y() == 20) -assert (anArcStartPoint.x() == 5) -assert (anArcStartPoint.y() == 60) -assert (anArcEndPoint.x() == 55) -assert (anArcEndPoint.y() == 10) -# Change the start point -aSession.startOperation() -anArcStartPoint.setValue(anArcStartPoint.x() + deltaX, anArcStartPoint.y()) -aPrevEndPointX = anArcEndPoint.x() -aPrevEndPointY = anArcEndPoint.y() -aSession.finishOperation() -assert (anArcCentr.x() == 15) -assert (anArcCentr.y() == 20) -assert (anArcStartPoint.x() == 10) -assert (anArcStartPoint.y() == 60) -assert (anArcEndPoint.x() != aPrevEndPointX) -assert (anArcEndPoint.y() != aPrevEndPointY) + +# MPV: movement now is done little bit in different way, just move points causes changing them +# back t okeep the radius unchanged (projection back to the initial circle) +#aSession.startOperation() +#deltaX, deltaY = 5., 10. +#anArcCentr.setValue(anArcCentr.x() + deltaX, anArcCentr.y() + deltaY) +#anArcStartPoint.setValue( +# anArcStartPoint.x() + deltaX, anArcStartPoint.y() + deltaY) +#anArcEndPoint.setValue(anArcEndPoint.x() + deltaX, anArcEndPoint.y() + deltaY) +#aSession.finishOperation() +#assert (anArcCentr.y() == 20) +#assert (anArcStartPoint.x() == 5) +#assert (anArcStartPoint.y() == 60) +#assert (anArcEndPoint.x() == 55) +#assert (anArcEndPoint.y() == 10) +## Change the start point +#aSession.startOperation() +#anArcStartPoint.setValue(anArcStartPoint.x() + deltaX, anArcStartPoint.y()) +#aPrevEndPointX = anArcEndPoint.x() +#aPrevEndPointY = anArcEndPoint.y() +#aSession.finishOperation() +#assert (anArcCentr.x() == 15) +#assert (anArcCentr.y() == 20) +#assert (anArcStartPoint.x() == 10) +#assert (anArcStartPoint.y() == 60) +#assert (anArcEndPoint.x() != aPrevEndPointX) +#assert (anArcEndPoint.y() != aPrevEndPointY) #========================================================================= # Check results of the Arc #========================================================================= -- 2.39.2