From a38e73135e95b1f1845f1b390b823bf8b386d026 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 25 Feb 2024 00:19:28 +0100 Subject: [PATCH] Sketcher: fixes #12343: Undo/Redo for sketcher constraints doesn't work correctly --- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 53 ++++++++++++++++----- src/Mod/Sketcher/Gui/ViewProviderSketch.h | 6 ++- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 8b5f8015f3..d432ef0ef4 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -1135,15 +1135,27 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe return true; case STATUS_SKETCH_DragConstraint: if (!drag.DragConstraintSet.empty()) { - getDocument()->openCommand(QT_TRANSLATE_NOOP("Command", "Drag Constraint")); auto idset = drag.DragConstraintSet; + // restore the old positions before opening the transaction and setting the new positions for (int id : idset) { - moveConstraint(id, Base::Vector2d(x, y)); - // updateColor(); + moveConstraint(id, Base::Vector2d(drag.xInit, drag.yInit)); } + + getDocument()->openCommand(QT_TRANSLATE_NOOP("Command", "Drag Constraint")); + std::vector constraints = getConstraints(); + for (int id : idset) { + Sketcher::Constraint* constr = constraints[id]->clone(); + moveConstraint(constr, id, Base::Vector2d(x, y)); + constraints[id] = constr; + } + + Sketcher::SketchObject* obj = getSketchObject(); + obj->Constraints.setValues(std::move(constraints)); + preselection.PreselectConstraintSet = drag.DragConstraintSet; drag.DragConstraintSet.clear(); getDocument()->commitCommand(); + tryAutoRecomputeIfNotSolve(getSketchObject()); } Mode = STATUS_NONE; return true; @@ -1593,6 +1605,8 @@ bool ViewProviderSketch::mouseMove(const SbVec2s& cursorPos, Gui::View3DInventor case STATUS_SELECT_Constraint: Mode = STATUS_SKETCH_DragConstraint; drag.DragConstraintSet = preselection.PreselectConstraintSet; + drag.xInit = x; + drag.yInit = y; resetPreselectPoint(); return true; case STATUS_SKETCH_DragPoint: @@ -1656,8 +1670,9 @@ bool ViewProviderSketch::mouseMove(const SbVec2s& cursorPos, Gui::View3DInventor case STATUS_SKETCH_DragConstraint: if (!drag.DragConstraintSet.empty()) { auto idset = drag.DragConstraintSet; - for (int id : idset) + for (int id : idset) { moveConstraint(id, Base::Vector2d(x, y)); + } } return true; case STATUS_SKETCH_UseHandler: @@ -1693,16 +1708,20 @@ bool ViewProviderSketch::mouseMove(const SbVec2s& cursorPos, Gui::View3DInventor } void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d& toPos) +{ + if (auto constr = getConstraint(constNum)) { + moveConstraint(constr, constNum, toPos); + } +} + +void ViewProviderSketch::moveConstraint(Sketcher::Constraint* Constr, int constNum, const Base::Vector2d& toPos) { // are we in edit? if (!isInEditMode()) return; - Sketcher::SketchObject* obj = getSketchObject(); - const std::vector& constrlist = obj->Constraints.getValues(); - Constraint* Constr = constrlist[constNum]; - #ifdef FC_DEBUG + Sketcher::SketchObject* obj = getSketchObject(); int intGeoCount = obj->getHighestCurveIndex() + 1; int extGeoCount = obj->getExternalGeometryCount(); #endif @@ -1869,7 +1888,7 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d& toPo } } else if (Constr->Type == Angle) { - moveAngleConstraint(constNum, toPos); + moveAngleConstraint(Constr, constNum, toPos); } // delete the cloned objects @@ -1882,12 +1901,9 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d& toPo draw(true, false); } -void ViewProviderSketch::moveAngleConstraint(int constNum, const Base::Vector2d& toPos) +void ViewProviderSketch::moveAngleConstraint(Sketcher::Constraint* constr, int constNum, const Base::Vector2d& toPos) { Sketcher::SketchObject* obj = getSketchObject(); - const std::vector& constrlist = obj->Constraints.getValues(); - Constraint* constr = constrlist[constNum]; - Base::Vector3d p0(0., 0., 0.); double factor = 0.5; if (constr->Second != GeoEnum::GeoUndef) {// line to line angle @@ -3735,6 +3751,17 @@ const std::vector ViewProviderSketch::getConstraints() co return getSketchObject()->Constraints.getValues(); } +Sketcher::Constraint* ViewProviderSketch::getConstraint(int constid) const +{ + Sketcher::SketchObject* obj = getSketchObject(); + const std::vector& constrlist = obj->Constraints.getValues(); + if (constid >= 0 || constid < int(constrlist.size())) { + return constrlist[constid]; + } + + return nullptr; +} + const GeoList ViewProviderSketch::getGeoList() const { const std::vector tempGeo = diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index 5c1e7dd42f..dfaee9ee8e 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -804,7 +804,8 @@ private: //@{ /// moves a selected constraint void moveConstraint(int constNum, const Base::Vector2d& toPos); - void moveAngleConstraint(int constNum, const Base::Vector2d& toPos); + void moveConstraint(Sketcher::Constraint*, int constNum, const Base::Vector2d& toPos); + void moveAngleConstraint(Sketcher::Constraint*, int constNum, const Base::Vector2d& toPos); /// returns whether the sketch is in edit mode. bool isInEditMode() const; @@ -830,6 +831,9 @@ private: bool constraintHasExpression(int constrid) const; const std::vector getConstraints() const; + /// gets the corresponding constraint to the given \a constid + /// or null if it doesn't exist. + Sketcher::Constraint* getConstraint(int constid) const; // gets the list of geometry of the sketchobject or of the solver instance const GeoList getGeoList() const;