From 884210338f7a0d6ea5442328609c841028503334 Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 5 May 2017 17:22:49 +0300 Subject: [PATCH] Task 2.4. Ability to modify the radius of circles and arcs of circle with the mouse Complete new movement functionality --- src/SketchPlugin/Test/TestConstraintFixed.py | 135 +++++++++++++++ .../PlaneGCSSolver/PlaneGCSSolver_Defs.h | 1 + .../PlaneGCSSolver/PlaneGCSSolver_Solver.cpp | 40 ++++- .../PlaneGCSSolver/PlaneGCSSolver_Solver.h | 7 + .../PlaneGCSSolver/PlaneGCSSolver_Storage.cpp | 3 - .../SketchSolver_ConstraintFixed.cpp | 16 +- .../SketchSolver_ConstraintFixed.h | 7 +- .../SketchSolver_ConstraintMovement.cpp | 154 +++++++++++++++--- .../SketchSolver_ConstraintMovement.h | 16 +- src/SketchSolver/SketchSolver_Group.cpp | 6 +- 10 files changed, 338 insertions(+), 47 deletions(-) diff --git a/src/SketchPlugin/Test/TestConstraintFixed.py b/src/SketchPlugin/Test/TestConstraintFixed.py index d3b631530..c0fb8b3fe 100644 --- a/src/SketchPlugin/Test/TestConstraintFixed.py +++ b/src/SketchPlugin/Test/TestConstraintFixed.py @@ -149,6 +149,141 @@ assert ((aLineAStartPoint.x(), aLineAStartPoint.y()) == (aLineCEndPoint.x(), aLi assert ((aLineBStartPoint.x(), aLineBStartPoint.y()) == (aLineAEndPoint.x(), aLineAEndPoint.y())) assert ((aLineCStartPoint.x(), aLineCStartPoint.y()) == (aLineBEndPoint.x(), aLineBEndPoint.y())) assert (model.dof(aSketchFeature) == 6) + +#========================================================================= +# Create circle, fix it and check the circle is not moved +#========================================================================= +aCenter = [10., 10.] +aRadius = 5. +aSession.startOperation() +aCircle = aSketchFeature.addFeature("SketchCircle") +aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center")) +aCircleRadius = aCircle.real("circle_radius") +aCircleCenter.setValue(aCenter[0], aCenter[1]) +aCircleRadius.setValue(aRadius) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 9) +# fixed constraints +aSession.startOperation() +aRigidConstraint = aSketchFeature.addFeature("SketchConstraintRigid") +aRigidConstraint.refattr("ConstraintEntityA").setObject(aCircle.lastResult()) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 6) +# move center of circle +aSession.startOperation() +aCircleCenter.setValue(aCenter[0] + 1., aCenter[1] - 1.) +aSession.finishOperation() +assert (aCircleCenter.x() == aCenter[0] and aCircleCenter.y() == aCenter[1]) +assert (aCircleRadius.value() == aRadius) +assert (model.dof(aSketchFeature) == 6) +# change radius of circle +aSession.startOperation() +aCircleRadius.setValue(aRadius + 3.) +aSession.finishOperation() +assert (aCircleCenter.x() == aCenter[0] and aCircleCenter.y() == aCenter[1]) +assert (aCircleRadius.value() == aRadius) +assert (model.dof(aSketchFeature) == 6) + +#========================================================================= +# Remove Fixed constraint and check the circle can be moved +#========================================================================= +aSession.startOperation() +aDocument.removeFeature(aRigidConstraint) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 9) +# move center of circle +aCenter = [aCenter[0] + 1., aCenter[1] - 1.] +aSession.startOperation() +aCircleCenter.setValue(aCenter[0], aCenter[1]) +aSession.finishOperation() +assert (aCircleCenter.x() == aCenter[0] and aCircleCenter.y() == aCenter[1]) +assert (aCircleRadius.value() == aRadius) +assert (model.dof(aSketchFeature) == 9) +# change radius of circle +aRadius = aRadius + 3. +aSession.startOperation() +aCircleRadius.setValue(aRadius) +aSession.finishOperation() +assert (aCircleCenter.x() == aCenter[0] and aCircleCenter.y() == aCenter[1]) +assert (aCircleRadius.value() == aRadius) +assert (model.dof(aSketchFeature) == 9) + +#========================================================================= +# Create arc, fix it and check it is not moved +#========================================================================= +aCenter = [10., 10.] +aStart = [5., 10.] +aEnd = [10., 15.] +aSession.startOperation() +anArc = aSketchFeature.addFeature("SketchArc") +anArcCenter = geomDataAPI_Point2D(anArc.attribute("center_point")) +anArcStart = geomDataAPI_Point2D(anArc.attribute("start_point")) +anArcEnd = geomDataAPI_Point2D(anArc.attribute("end_point")) +anArcCenter.setValue(aCenter[0], aCenter[1]) +anArcStart.setValue(aStart[0], aStart[1]) +anArcEnd.setValue(aEnd[0], aEnd[1]) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 14) +# fixed constraints +aSession.startOperation() +aRigidConstraint = aSketchFeature.addFeature("SketchConstraintRigid") +aRigidConstraint.refattr("ConstraintEntityA").setObject(anArc.lastResult()) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 9) +# move center of arc +aSession.startOperation() +anArcCenter.setValue(aCenter[0] + 1., aCenter[1] - 1.) +aSession.finishOperation() +assert (anArcCenter.x() == aCenter[0] and anArcCenter.y() == aCenter[1]) +assert (anArcStart.x() == aStart[0] and anArcStart.y() == aStart[1]) +assert (anArcEnd.x() == aEnd[0] and anArcEnd.y() == aEnd[1]) +assert (model.dof(aSketchFeature) == 9) +# move start point of arc +aSession.startOperation() +anArcStart.setValue(aStart[0] + 1., aStart[1] - 1.) +aSession.finishOperation() +assert (anArcCenter.x() == aCenter[0] and anArcCenter.y() == aCenter[1]) +assert (anArcStart.x() == aStart[0] and anArcStart.y() == aStart[1]) +assert (anArcEnd.x() == aEnd[0] and anArcEnd.y() == aEnd[1]) +assert (model.dof(aSketchFeature) == 9) +# move end point of arc +aSession.startOperation() +anArcEnd.setValue(aEnd[0] + 1., aEnd[1] - 1.) +aSession.finishOperation() +assert (anArcCenter.x() == aCenter[0] and anArcCenter.y() == aCenter[1]) +assert (anArcStart.x() == aStart[0] and anArcStart.y() == aStart[1]) +assert (anArcEnd.x() == aEnd[0] and anArcEnd.y() == aEnd[1]) +assert (model.dof(aSketchFeature) == 9) + +#========================================================================= +# Remove Fixed constraint and check the arc can be moved +#========================================================================= +aSession.startOperation() +aDocument.removeFeature(aRigidConstraint) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 14) +# move center of arc +aCenter = [anArcCenter.x(), anArcCenter.y()] +aSession.startOperation() +anArcCenter.setValue(aCenter[0] + 1., aCenter[1] - 1.) +aSession.finishOperation() +assert (anArcCenter.x() != aCenter[0] or anArcCenter.y() != aCenter[1]) +assert (model.dof(aSketchFeature) == 14) +# move start point of arc +aStart = [anArcStart.x(), anArcStart.y()] +aSession.startOperation() +anArcStart.setValue(aStart[0] + 1., aStart[1] - 1.) +aSession.finishOperation() +assert (anArcStart.x() != aStart[0] or anArcStart.y() != aStart[1]) +assert (model.dof(aSketchFeature) == 14) +# move end point of arc +aEnd = [anArcEnd.x(), anArcEnd.y()] +aSession.startOperation() +anArcEnd.setValue(aEnd[0] + 1., aEnd[1] - 1.) +aSession.finishOperation() +assert (anArcEnd.x() != aEnd[0] or anArcEnd.y() != aEnd[1]) +assert (model.dof(aSketchFeature) == 14) + #========================================================================= # End of test #========================================================================= diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h index 9274c2878..3fa64daa8 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h @@ -26,6 +26,7 @@ typedef int ConstraintID; // Predefined values for identifiers const ConstraintID CID_UNKNOWN = 0; const ConstraintID CID_MOVEMENT = -1; +const ConstraintID CID_FICTIVE = 1024; /// Types of entities enum SketchSolver_EntityType { diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp index eb8868409..0c1584873 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp @@ -13,7 +13,8 @@ PlaneGCSSolver_Solver::PlaneGCSSolver_Solver() myDiagnoseBeforeSolve(false), myInitilized(false), myConfCollected(false), - myDOF(0) + myDOF(0), + myFictiveConstraint(0) { } @@ -29,6 +30,8 @@ void PlaneGCSSolver_Solver::clear() myConstraints.clear(); myConflictingIDs.clear(); myDOF = 0; + + removeFictiveConstraint(); } void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint) @@ -73,6 +76,7 @@ void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams) void PlaneGCSSolver_Solver::initialize() { Events_LongOp::start(this); + addFictiveConstraintIfNecessary(); if (myDiagnoseBeforeSolve) diagnose(); myEquationSystem->declareUnknowns(myParameters); @@ -98,6 +102,8 @@ PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve() if (myInitilized) { aResult = (GCS::SolveStatus)myEquationSystem->solve(); } else { + addFictiveConstraintIfNecessary(); + if (myDiagnoseBeforeSolve) diagnose(); aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters); @@ -121,6 +127,7 @@ PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve() aStatus = STATUS_OK; } + removeFictiveConstraint(); myInitilized = false; return aStatus; } @@ -162,3 +169,34 @@ void PlaneGCSSolver_Solver::diagnose() myDOF = myEquationSystem->diagnose(); myDiagnoseBeforeSolve = false; } + +void PlaneGCSSolver_Solver::addFictiveConstraintIfNecessary() +{ + if (!myConstraints.empty() && + myConstraints.find(CID_MOVEMENT) == myConstraints.end()) + return; + + if (myFictiveConstraint) + return; // no need several fictive constraints + + double* aParam = createParameter(); + double* aFictiveParameter = new double(0.0); + + myFictiveConstraint = new GCS::ConstraintEqual(aFictiveParameter, aParam); + myFictiveConstraint->setTag(CID_FICTIVE); + myEquationSystem->addConstraint(myFictiveConstraint); +} + +void PlaneGCSSolver_Solver::removeFictiveConstraint() +{ + if (myFictiveConstraint) { + myEquationSystem->removeConstraint(myFictiveConstraint); + myParameters.pop_back(); + + GCS::VEC_pD aParams = myFictiveConstraint->params(); + for (GCS::VEC_pD::iterator anIt = aParams.begin(); anIt != aParams.end(); ++ anIt) + delete *anIt; + delete myFictiveConstraint; + myFictiveConstraint = 0; + } +} diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h index cb195ada3..8d8322714 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h @@ -65,6 +65,11 @@ public: private: void collectConflicting(); + /// \brief Add fictive constraint if the sketch contains temporary constraints only + void addFictiveConstraintIfNecessary(); + /// \brief Remove previously added fictive constraint + void removeFictiveConstraint(); + private: typedef std::map > ConstraintMap; @@ -80,6 +85,8 @@ private: bool myConfCollected; int myDOF; ///< degrees of freedom + + GCS::Constraint* myFictiveConstraint; }; typedef std::shared_ptr SolverPtr; diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 88020df90..c7e6f276f 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -54,9 +54,6 @@ void PlaneGCSSolver_Storage::addConstraint( void PlaneGCSSolver_Storage::addMovementConstraint( const ConstraintWrapperPtr& theSolverConstraint) { - if (myConstraintMap.empty()) - return; // no need to process temporary constraints if there is no active constraint - // before adding movement constraint to solver, re-check its DOF if (mySketchSolver->dof() == 0) mySketchSolver->diagnose(); diff --git a/src/SketchSolver/SketchSolver_ConstraintFixed.cpp b/src/SketchSolver/SketchSolver_ConstraintFixed.cpp index ab58762a4..3d316d0ff 100644 --- a/src/SketchSolver/SketchSolver_ConstraintFixed.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintFixed.cpp @@ -12,10 +12,8 @@ #include #include -#include - -// Verify the entities are equal -static bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2); +/// \brief Get list of parameters of current entity +static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity); SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint) @@ -79,7 +77,11 @@ EntityWrapperPtr SketchSolver_ConstraintFixed::entityToFix() return EntityWrapperPtr(); } -GCS::VEC_pD SketchSolver_ConstraintFixed::toParameters(const EntityWrapperPtr& theEntity) + + + +// ================== Auxiliary functions ================== +GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity) { GCS::VEC_pD aParameters; if (!theEntity) @@ -110,12 +112,16 @@ GCS::VEC_pD SketchSolver_ConstraintFixed::toParameters(const EntityWrapperPtr& t std::dynamic_pointer_cast(anEntity->entity()); aParameters.push_back(aCircle->center.x); aParameters.push_back(aCircle->center.y); + aParameters.push_back(aCircle->rad); break; } case ENTITY_ARC: { std::shared_ptr anArc = std::dynamic_pointer_cast(anEntity->entity()); aParameters.push_back(anArc->center.x); aParameters.push_back(anArc->center.y); + aParameters.push_back(anArc->rad); + aParameters.push_back(anArc->startAngle); + aParameters.push_back(anArc->endAngle); break; } default: diff --git a/src/SketchSolver/SketchSolver_ConstraintFixed.h b/src/SketchSolver/SketchSolver_ConstraintFixed.h index 7d20a4320..41805b4a0 100644 --- a/src/SketchSolver/SketchSolver_ConstraintFixed.h +++ b/src/SketchSolver/SketchSolver_ConstraintFixed.h @@ -33,15 +33,12 @@ protected: {} /// \brief Obtain entity to be fixed - virtual EntityWrapperPtr entityToFix(); + EntityWrapperPtr entityToFix(); /// \brief Create Fixed constraint for the feature basing on its type /// \param theFeature [in] feature, converted to solver specific format /// \return Fixed constraint - virtual ConstraintWrapperPtr fixFeature(EntityWrapperPtr theFeature); - - /// \brief Get list of parameters of current entity - static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity); + ConstraintWrapperPtr fixFeature(EntityWrapperPtr theFeature); protected: std::vector myFixedValues; diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.cpp b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp index 44efdafe9..bec111b87 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMovement.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp @@ -4,6 +4,9 @@ #include #include +#include +#include + #include #include #include @@ -16,13 +19,15 @@ SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theFeature) : SketchSolver_ConstraintFixed(ConstraintPtr()), - myMovedFeature(theFeature) + myMovedFeature(theFeature), + mySimpleMove(true) { } SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(AttributePtr thePoint) : SketchSolver_ConstraintFixed(ConstraintPtr()), - myDraggedPoint(thePoint) + myDraggedPoint(thePoint), + mySimpleMove(true) { myMovedFeature = ModelAPI_Feature::feature(thePoint->owner()); } @@ -41,57 +46,156 @@ void SketchSolver_ConstraintMovement::process() return; } - EntityWrapperPtr aMovedEntity = entityToFix(); - if (!myErrorMsg.empty() || !aMovedEntity) { + mySolverConstraint = initMovement(); + if (!myErrorMsg.empty() || !mySolverConstraint) { // Nothing to move, clear the feature to avoid changing its group // after removing the Movement constraint. myMovedFeature = FeaturePtr(); return; } - - mySolverConstraint = fixFeature(aMovedEntity); myStorage->addMovementConstraint(mySolverConstraint); } -EntityWrapperPtr SketchSolver_ConstraintMovement::entityToFix() +static bool isSimpleMove(FeaturePtr theMovedFeature, AttributePtr theDraggedPoint) +{ + bool isSimple = true; + if (theMovedFeature->getKind() == SketchPlugin_Circle::ID()) + isSimple = (theDraggedPoint.get() != 0); + else if (theMovedFeature->getKind() == SketchPlugin_Arc::ID()) { + isSimple = (theDraggedPoint.get() != 0 && + theDraggedPoint->id() == SketchPlugin_Arc::CENTER_ID()); + } + return isSimple; +} + +ConstraintWrapperPtr SketchSolver_ConstraintMovement::initMovement() { + ConstraintWrapperPtr aConstraint; + // if the feature is copy, do not move it std::shared_ptr aSketchFeature = std::dynamic_pointer_cast(myMovedFeature); if (!aSketchFeature || aSketchFeature->isCopy()) { myStorage->setNeedToResolve(true); - return EntityWrapperPtr(); + return aConstraint; } EntityWrapperPtr anEntity = myDraggedPoint ? myStorage->entity(myDraggedPoint) : myStorage->entity(myMovedFeature); if (!anEntity) { myStorage->update(myMovedFeature, true); - anEntity = myStorage->entity(myMovedFeature); + anEntity = + myDraggedPoint ? myStorage->entity(myDraggedPoint) : myStorage->entity(myMovedFeature); + if (!anEntity) + return aConstraint; + } + + mySimpleMove = isSimpleMove(myMovedFeature, myDraggedPoint); + + if (mySimpleMove) + aConstraint = fixFeature(anEntity); + else { + if (myDraggedPoint) // start or end point of arc has been moved + aConstraint = fixArcExtremity(anEntity); + else // arc or circle has been moved + aConstraint = fixPointOnCircle(anEntity); + } + + return aConstraint; +} + +ConstraintWrapperPtr SketchSolver_ConstraintMovement::fixArcExtremity( + const EntityWrapperPtr& theArcExtremity) +{ + static const int nbParams = 4; + myFixedValues.reserve(nbParams); // moved point and center of arc + + EdgeWrapperPtr aCircularEntity = std::dynamic_pointer_cast( + myStorage->entity(myMovedFeature)); + std::shared_ptr anArc = + std::dynamic_pointer_cast(aCircularEntity->entity()); + + PointWrapperPtr aPoint = + std::dynamic_pointer_cast(theArcExtremity); + + double* aParams[nbParams] = { aPoint->point()->x, aPoint->point()->y, + anArc->center.x, anArc->center.y }; + + std::list aConstraints; + for (int i = 0; i < nbParams; ++i) { + myFixedValues.push_back(*aParams[i]); + GCSConstraintPtr aNewConstraint(new GCS::ConstraintEqual(&myFixedValues[i], aParams[i])); + aNewConstraint->rescale(0.01); + aConstraints.push_back(aNewConstraint); + } + + return ConstraintWrapperPtr( + new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType())); +} + +ConstraintWrapperPtr SketchSolver_ConstraintMovement::fixPointOnCircle( + const EntityWrapperPtr& theCircular) +{ + static const double scale = 0.01; + static const int nbParams = 4; + myFixedValues.reserve(nbParams); // moved point and center of arc/circle + + EdgeWrapperPtr aCircularEntity = + std::dynamic_pointer_cast(theCircular); + std::shared_ptr aCircular = + std::dynamic_pointer_cast(aCircularEntity->entity()); + + // initialize fixed values + myFixedValues.push_back(*aCircular->center.x + *aCircular->rad); + myFixedValues.push_back(*aCircular->center.y); + myFixedValues.push_back(*aCircular->center.x); + myFixedValues.push_back(*aCircular->center.y); + + // create a moved point + GCS::Point aPointOnCircle; + aPointOnCircle.x = &myFixedValues[0]; + aPointOnCircle.y = &myFixedValues[1]; + + std::list aConstraints; + // point-on-circle + GCSConstraintPtr aNewConstraint( + new GCS::ConstraintP2PDistance(aPointOnCircle, aCircular->center, aCircular->rad)); + aNewConstraint->rescale(scale); + aConstraints.push_back(aNewConstraint); + // fixed center (x) + aNewConstraint = GCSConstraintPtr( + new GCS::ConstraintEqual(&myFixedValues[2], aCircular->center.x)); + aNewConstraint->rescale(scale); + aConstraints.push_back(aNewConstraint); + // fixed center (y) + aNewConstraint = GCSConstraintPtr( + new GCS::ConstraintEqual(&myFixedValues[3], aCircular->center.y)); + aNewConstraint->rescale(scale); + aConstraints.push_back(aNewConstraint); + + return ConstraintWrapperPtr( + new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType())); +} + + +void SketchSolver_ConstraintMovement::startPoint( + const std::shared_ptr& theStartPoint) +{ + myStartPoint = theStartPoint; + if (!mySimpleMove) { + myFixedValues[0] = myStartPoint->x(); + myFixedValues[1] = myStartPoint->y(); } - return anEntity; } void SketchSolver_ConstraintMovement::moveTo( const std::shared_ptr& theDestinationPoint) { - EntityWrapperPtr aMovedEntity = - myDraggedPoint ? myStorage->entity(myDraggedPoint) : myStorage->entity(myMovedFeature); - if (!aMovedEntity) - return; - double aDelta[2] = { theDestinationPoint->x() - myStartPoint->x(), theDestinationPoint->y() - myStartPoint->y() }; - GCS::VEC_pD aFixedParams = toParameters(aMovedEntity); - for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i) - myFixedValues[i] = *(aFixedParams[i]) + aDelta[i % 2]; - - // no persistent constraints in the storage, thus store values directly to the feature - if (myStorage->isEmpty()) { - for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i) - *(aFixedParams[i]) = myFixedValues[i]; - myStorage->setNeedToResolve(true); - } + int aMaxSize = mySimpleMove ? (int)myFixedValues.size() : 2; + for (int i = 0; i < aMaxSize; ++i) + myFixedValues[i] += aDelta[i % 2]; } diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.h b/src/SketchSolver/SketchSolver_ConstraintMovement.h index 59fa2a198..f25bbb0af 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMovement.h +++ b/src/SketchSolver/SketchSolver_ConstraintMovement.h @@ -25,8 +25,7 @@ public: SketchSolver_ConstraintMovement(AttributePtr thePoint); /// \brief Set coordinates of the start point of the movement - void startPoint(const std::shared_ptr& theStartPoint) - { myStartPoint = theStartPoint; } + void startPoint(const std::shared_ptr& theStartPoint); /// \brief Set coordinates of fixed feature to the values where it has been dragged. /// Useful when the feature is being moved. @@ -43,13 +42,22 @@ protected: /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints virtual void process(); - /// \brief Obtain entity to be fixed - virtual EntityWrapperPtr entityToFix(); + /// \brief Create Fixed constraint for the feature basing on its type and moved point + /// \return Fixed constraint + ConstraintWrapperPtr initMovement(); + + /// \brief Create constraint to fix moved arc extremity + ConstraintWrapperPtr fixArcExtremity(const EntityWrapperPtr& theArcExtremity); + + /// \brief Creat constraint to fix moved point on circle/arc + ConstraintWrapperPtr fixPointOnCircle(const EntityWrapperPtr& theCircular); private: FeaturePtr myMovedFeature; ///< fixed feature (if set, myBaseConstraint should be NULL) AttributePtr myDraggedPoint; ///< one of the feature points which has been moved std::shared_ptr myStartPoint; ///< start point of the movement + + bool mySimpleMove; ///< simple move, thus all parameters should be increased by movement delta }; #endif diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index 840c7b736..222482386 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -137,12 +137,10 @@ static SolverConstraintPtr move(StoragePtr theStorage, if (aConstraint) { SolverConstraintPtr(aConstraint)->process(theStorage, theEventsBlocked); if (aConstraint->error().empty()) { - if (!theStorage->isEmpty()) - theStorage->setNeedToResolve(true); - - theSketchSolver->initialize(); aConstraint->startPoint(theFrom); + theSketchSolver->initialize(); aConstraint->moveTo(theTo); + theStorage->setNeedToResolve(true); } else theStorage->notify(aConstraint->movedFeature()); } -- 2.39.2