Sketcher: Fix Angle Constraint jumping to opposite side on movement (#24150)

* Sketcher: Fix Angle Constraint jumping to opposite side on movement

* implement way to dynamically disable snapping where not needed

---------

Co-authored-by: Matthias Danner <28687794+matthiasdanner@users.noreply.github.com>
This commit is contained in:
matthiasdanner
2025-10-13 18:07:09 +02:00
committed by GitHub
parent 45401513b4
commit 62c222c211
20 changed files with 197 additions and 120 deletions

View File

@@ -1153,12 +1153,7 @@ void SketchObject::reverseAngleConstraintToSupplementary(Constraint* constr, int
{
std::swap(constr->First, constr->Second);
std::swap(constr->FirstPos, constr->SecondPos);
if (constr->FirstPos == constr->SecondPos) {
constr->FirstPos = (constr->FirstPos == Sketcher::PointPos::start) ? Sketcher::PointPos::end : Sketcher::PointPos::start;
}
else {
constr->SecondPos = (constr->SecondPos == Sketcher::PointPos::start) ? Sketcher::PointPos::end : Sketcher::PointPos::start;
}
constr->FirstPos = (constr->FirstPos == Sketcher::PointPos::start) ? Sketcher::PointPos::end : Sketcher::PointPos::start;
// Edit the expression if any, else modify constraint value directly
if (constraintHasExpression(constNum)) {

View File

@@ -52,6 +52,7 @@
#include "ViewProviderSketch.h"
#include "ui_InsertDatum.h"
#include <Inventor/events/SoKeyboardEvent.h>
#include "SnapManager.h"
// Remove this after pre-commit hook is activated
// clang-format off
@@ -1033,7 +1034,7 @@ public:
Gui::Selection().rmvSelectionGate();
}
void mouseMove(Base::Vector2d /*onSketchPos*/) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{}
bool pressButton(Base::Vector2d /*onSketchPos*/) override
@@ -1835,13 +1836,16 @@ public:
}
}
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
if (hasBeenAborted()) {
resetTool();
return;
}
//All snap Positions except of edges, because it results in jumps on angle constraints
SnapType mask = static_cast<SnapType>(static_cast<int>(SnapType::All) & ~static_cast<int>(SnapType::Edge));
Base::Vector2d onSketchPos = snapHandle.compute(mask);
previousOnSketchPos = onSketchPos;
//Change distance constraint based on position of mouse.

View File

@@ -39,6 +39,7 @@
#include "DrawSketchHandler.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
using namespace std;
@@ -765,9 +766,10 @@ public:
~DrawSketchHandlerBSplineInsertKnot() override
{}
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
auto bsp = static_cast<const Part::GeomBSplineCurve*>(Obj->getGeometry(GeoId));
Base::Vector2d onSketchPos = snapHandle.compute();
// get closest parameter using OCC
// TODO: This is called every time we move the cursor. Can get overwhelming.

View File

@@ -64,6 +64,7 @@
#include "DrawSketchHandlerRotate.h"
#include "DrawSketchHandlerScale.h"
#include "DrawSketchHandlerSymmetry.h"
#include "SnapManager.h"
// Hint: this is to prevent to re-format big parts of the file. Remove it later again.
// clang-format off
@@ -1211,9 +1212,10 @@ public:
Snap5Degree
};
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
using std::numbers::pi;
Base::Vector2d onSketchPos = snapHandle.compute();
if (Mode == STATUS_SEEK_First) {
@@ -1789,9 +1791,10 @@ public:
Snap5Degree
};
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
using std::numbers::pi;
Base::Vector2d onSketchPos = snapHandle.compute();
if (Mode == STATUS_SEEK_First) {

View File

@@ -27,6 +27,7 @@
#include <type_traits>
#include "DrawSketchDefaultHandler.h"
#include "SnapManager.h"
namespace SketcherGui
{
@@ -79,8 +80,9 @@ public:
/** @name functions NOT intended for specialisation or further overriding */
//@{
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
Base::Vector2d onSketchPos = snapHandle.compute();
toolWidgetManager.mouseMoved(onSketchPos);
toolWidgetManager.enforceControlParameters(onSketchPos);

View File

@@ -333,7 +333,8 @@ public:
handler->reset(); // reset of handler to restart.
}
handler->mouseMove(prevCursorPosition);
auto snapHandle = std::make_unique<SnapManager::SnapHandle>(nullptr, prevCursorPosition);
handler->mouseMove(*snapHandle);
}
//@}
@@ -534,7 +535,9 @@ public:
virtual void afterHandlerModeChanged()
{
if (handler && (!handler->isState(SelectModeT::End) || handler->continuousMode)) {
handler->mouseMove(prevCursorPosition);
auto snapHandle =
std::make_unique<SnapManager::SnapHandle>(nullptr, prevCursorPosition);
handler->mouseMove(*snapHandle);
}
}
@@ -624,7 +627,8 @@ protected:
/// change
void finishControlsChanged()
{
handler->mouseMove(prevCursorPosition);
auto snapHandle = std::make_unique<SnapManager::SnapHandle>(nullptr, prevCursorPosition);
handler->mouseMove(*snapHandle);
auto currentstate = handler->state();
// ensure that object at point is preselected, so that autoconstraints are generated
@@ -645,7 +649,9 @@ protected:
// reset)
if (shouldProcessLastPosWithNextState) {
// mode has changed, so reprocess the previous position to the new widget state
handler->mouseMove(prevCursorPosition);
auto snapHandle =
std::make_unique<SnapManager::SnapHandle>(nullptr, prevCursorPosition);
handler->mouseMove(*snapHandle);
}
}

View File

@@ -39,6 +39,7 @@
#include "AutoConstraint.h"
#include "DrawSketchHandler.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
#include "Utils.h"
@@ -425,9 +426,9 @@ public:
* overridden/specialised instead.
*/
//@{
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
updateDataAndDrawToPosition(onSketchPos);
updateDataAndDrawToPosition(snapHandle.compute());
}
bool pressButton(Base::Vector2d onSketchPos) override

View File

@@ -39,6 +39,7 @@
#include "AutoConstraint.h"
#include "Utils.h"
#include "SnapManager.h"
class QWidget;
@@ -154,7 +155,7 @@ public:
void setSketchGui(ViewProviderSketch* vp);
void deactivate() override;
virtual void mouseMove(Base::Vector2d pos) = 0;
virtual void mouseMove(SnapManager::SnapHandle snapHandle) = 0;
virtual bool pressButton(Base::Vector2d pos) = 0;
virtual bool releaseButton(Base::Vector2d pos) = 0;

View File

@@ -34,6 +34,7 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
namespace SketcherGui
@@ -67,9 +68,10 @@ public:
STATUS_Close
};
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
using std::numbers::pi;
Base::Vector2d onSketchPos = snapHandle.compute();
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);

View File

@@ -36,6 +36,7 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
namespace SketcherGui
@@ -64,8 +65,9 @@ public:
STATUS_Close
};
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
Base::Vector2d onSketchPos = snapHandle.compute();
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
seekAndRenderAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f));

View File

@@ -37,6 +37,7 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
namespace SketcherGui
{
@@ -67,8 +68,9 @@ public:
STATUS_Close
};
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
Base::Vector2d onSketchPos = snapHandle.compute();
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
seekAndRenderAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f));

View File

@@ -39,6 +39,7 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
namespace SketcherGui
@@ -127,9 +128,9 @@ public:
Gui::Selection().rmvSelectionGate();
}
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
Q_UNUSED(onSketchPos);
Q_UNUSED(snapHandle);
if (Gui::Selection().getPreselection().pObjectName) {
applyCursor();
}

View File

@@ -34,6 +34,7 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
namespace SketcherGui
@@ -107,9 +108,9 @@ public:
STATUS_SEEK_Second,
};
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
Q_UNUSED(onSketchPos);
Base::Vector2d onSketchPos = snapHandle.compute();
using std::numbers::pi;

View File

@@ -41,6 +41,7 @@
#include "Utils.h"
#include "ViewProviderSketch.h"
#include <Mod/Part/App/Datums.h>
#include "SnapManager.h"
namespace SketcherGui
@@ -133,9 +134,9 @@ public:
Gui::Selection().rmvSelectionGate();
}
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
Q_UNUSED(onSketchPos);
Q_UNUSED(snapHandle);
if (Gui::Selection().getPreselection().pObjectName) {
applyCursor();
}

View File

@@ -39,6 +39,7 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
namespace SketcherGui
@@ -181,16 +182,18 @@ public:
else {
EditCurve.resize(32);
}
mouseMove(onSketchPos); // trigger an update of EditCurve
auto snapHandle = std::make_unique<SnapManager::SnapHandle>(nullptr, onSketchPos);
mouseMove(*snapHandle); // trigger an update of EditCurve
}
else {
DrawSketchHandler::registerPressedKey(pressed, key);
}
}
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
using std::numbers::pi;
Base::Vector2d onSketchPos = snapHandle.compute();
suppressTransition = false;
if (Mode == STATUS_SEEK_First) {
@@ -711,7 +714,8 @@ public:
SegmentMode = SEGMENT_MODE_Line;
SnapMode = SNAP_MODE_Free;
EditCurve[1] = EditCurve[0];
mouseMove(onSketchPos); // trigger an update of EditCurve
auto snapHandle = std::make_unique<SnapManager::SnapHandle>(nullptr, onSketchPos);
mouseMove(*snapHandle); // trigger an update of EditCurve
}
}

View File

@@ -34,6 +34,7 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
namespace SketcherGui
@@ -100,9 +101,9 @@ public:
Gui::Selection().rmvSelectionGate();
}
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
Q_UNUSED(onSketchPos);
Q_UNUSED(snapHandle);
}
bool pressButton(Base::Vector2d onSketchPos) override

View File

@@ -37,6 +37,7 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SnapManager.h"
namespace SketcherGui
@@ -88,9 +89,9 @@ public:
Gui::Selection().rmvSelectionGate();
}
void mouseMove(Base::Vector2d onSketchPos) override
void mouseMove(SnapManager::SnapHandle snapHandle) override
{
Q_UNUSED(onSketchPos);
Base::Vector2d onSketchPos = snapHandle.compute();
if (mousePressed) {
executeCommands(onSketchPos);
return;

View File

@@ -184,55 +184,62 @@ SnapManager::SnapManager(ViewProviderSketch& vp)
SnapManager::~SnapManager()
{}
bool SnapManager::snap(double& x, double& y)
Base::Vector2d SnapManager::snap(Base::Vector2d inputPos, SnapType mask)
{
if (!snapRequested) {
return false;
return inputPos;
}
// In order of priority :
Base::Vector2d snapPos;
// In order of priority:
// 1 - Snap at an angle
if (angleSnapRequested && QApplication::keyboardModifiers() == Qt::ControlModifier) {
return snapAtAngle(x, y);
if ((static_cast<int>(mask) & static_cast<int>(SnapType::Angle)) && angleSnapRequested
&& QApplication::keyboardModifiers() == Qt::ControlModifier
&& snapAtAngle(inputPos, snapPos)) {
return snapPos;
}
else {
lastMouseAngle = 0.0;
}
// 2 - Snap to objects
if (snapToObjectsRequested && snapToObject(x, y)) {
return true;
if ((static_cast<int>(mask)
& (static_cast<int>(SnapType::Point) | static_cast<int>(SnapType::Edge)))
&& snapToObjectsRequested && snapToObject(inputPos, snapPos, mask)) {
return snapPos;
}
// 3 - Snap to grid
if (snapToGridRequested /*&& viewProvider.ShowGrid.getValue() */) { // Snap to grid is enabled
// even if the grid is not
// visible.
return snapToGrid(x, y);
if ((static_cast<int>(mask) & static_cast<int>(SnapType::Grid)) && snapToGridRequested
&& snapToGrid(inputPos, snapPos)
/*&& viewProvider.ShowGrid.getValue() */) { // Snap to grid is
// enabled
// even if the grid is not
// visible.
return snapPos;
}
return false;
return inputPos;
}
bool SnapManager::snapAtAngle(double& x, double& y)
bool SnapManager::snapAtAngle(Base::Vector2d inputPos, Base::Vector2d& snapPos)
{
Base::Vector2d pointToOverride(x, y);
double length = (pointToOverride - referencePoint).Length();
double length = (inputPos - referencePoint).Length();
double angle1 = (pointToOverride - referencePoint).Angle();
double angle1 = (inputPos - referencePoint).Angle();
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * std::numbers::pi;
lastMouseAngle = abs(angle1 - lastMouseAngle) < abs(angle2 - lastMouseAngle) ? angle1 : angle2;
double angle = round(lastMouseAngle / snapAngle) * snapAngle;
pointToOverride = referencePoint + length * Base::Vector2d(cos(angle), sin(angle));
x = pointToOverride.x;
y = pointToOverride.y;
snapPos = referencePoint + length * Base::Vector2d(cos(angle), sin(angle));
return true;
}
bool SnapManager::snapToObject(double& x, double& y)
bool SnapManager::snapToObject(Base::Vector2d inputPos, Base::Vector2d& snapPos, SnapType mask)
{
Sketcher::SketchObject* Obj = viewProvider.getSketchObject();
int geoId = GeoEnum::GeoUndef;
@@ -242,7 +249,7 @@ bool SnapManager::snapToObject(double& x, double& y)
int CrsId = ViewProviderSketchSnapAttorney::getPreselectCross(viewProvider);
int CrvId = ViewProviderSketchSnapAttorney::getPreselectCurve(viewProvider);
if (CrsId == 0 || VtId >= 0) {
if ((static_cast<int>(mask) & static_cast<int>(SnapType::Point)) && (CrsId == 0 || VtId >= 0)) {
if (CrsId == 0) {
geoId = Sketcher::GeoEnum::RtPnt;
posId = Sketcher::PointPos::start;
@@ -251,78 +258,81 @@ bool SnapManager::snapToObject(double& x, double& y)
Obj->getGeoVertexIndex(VtId, geoId, posId);
}
x = Obj->getPoint(geoId, posId).x;
y = Obj->getPoint(geoId, posId).y;
snapPos.x = Obj->getPoint(geoId, posId).x;
snapPos.y = Obj->getPoint(geoId, posId).y;
return true;
}
else if (CrsId == 1) { // H_Axis
y = 0;
return true;
}
else if (CrsId == 2) { // V_Axis
x = 0;
return true;
}
else if (CrvId >= 0 || CrvId <= Sketcher::GeoEnum::RefExt) { // Curves
const Part::Geometry* geo = Obj->getGeometry(CrvId);
Base::Vector3d pointToOverride(x, y, 0.);
double pointParam = 0.0;
auto curve = dynamic_cast<const Part::GeomCurve*>(geo);
if (curve) {
try {
curve->closestParameter(pointToOverride, pointParam);
pointToOverride = curve->pointAtParameter(pointParam);
}
catch (Base::CADKernelError& e) {
e.reportException();
return false;
}
// If it is a line, then we check if we need to snap to the middle.
if (geo->is<Part::GeomLineSegment>()) {
const Part::GeomLineSegment* line = static_cast<const Part::GeomLineSegment*>(geo);
snapToLineMiddle(pointToOverride, line);
}
// If it is an arc, then we check if we need to snap to the middle (not the center).
if (geo->is<Part::GeomArcOfCircle>()) {
const Part::GeomArcOfCircle* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
snapToArcMiddle(pointToOverride, arc);
}
x = pointToOverride.x;
y = pointToOverride.y;
else if (static_cast<int>(mask) & static_cast<int>(SnapType::Edge)) {
if (CrsId == 1) { // H_Axis
snapPos.y = 0;
return true;
}
}
else if (CrsId == 2) { // V_Axis
snapPos.x = 0;
return true;
}
else if (CrvId >= 0 || CrvId <= Sketcher::GeoEnum::RefExt) { // Curves
const Part::Geometry* geo = Obj->getGeometry(CrvId);
Base::Vector3d pointToOverride(inputPos.x, inputPos.y, 0.);
double pointParam = 0.0;
auto curve = dynamic_cast<const Part::GeomCurve*>(geo);
if (curve) {
try {
curve->closestParameter(pointToOverride, pointParam);
pointToOverride = curve->pointAtParameter(pointParam);
}
catch (Base::CADKernelError& e) {
e.reportException();
return false;
}
// If it is a line, then we check if we need to snap to the middle.
if (geo->is<Part::GeomLineSegment>()) {
const Part::GeomLineSegment* line =
static_cast<const Part::GeomLineSegment*>(geo);
snapToLineMiddle(pointToOverride, line);
}
// If it is an arc, then we check if we need to snap to the middle (not the center).
if (geo->is<Part::GeomArcOfCircle>()) {
const Part::GeomArcOfCircle* arc =
static_cast<const Part::GeomArcOfCircle*>(geo);
snapToArcMiddle(pointToOverride, arc);
}
snapPos.x = pointToOverride.x;
snapPos.y = pointToOverride.y;
return true;
}
}
}
return false;
}
bool SnapManager::snapToGrid(double& x, double& y)
bool SnapManager::snapToGrid(Base::Vector2d inputPos, Base::Vector2d& snapPos)
{
// Snap Tolerance in pixels
const double snapTol = viewProvider.getGridSize() / 5;
double tmpX = x, tmpY = y;
double tmpX = inputPos.x, tmpY = inputPos.y;
viewProvider.getClosestGridPoint(tmpX, tmpY);
bool snapped = false;
// Check if x within snap tolerance
if (x < tmpX + snapTol && x > tmpX - snapTol) {
x = tmpX; // Snap X Mouse Position
if (inputPos.x < tmpX + snapTol && inputPos.x > tmpX - snapTol) {
snapPos.x = tmpX; // Snap X Mouse Position
snapped = true;
}
// Check if y within snap tolerance
if (y < tmpY + snapTol && y > tmpY - snapTol) {
y = tmpY; // Snap Y Mouse Position
if (inputPos.y < tmpY + snapTol && inputPos.y > tmpY - snapTol) {
snapPos.y = tmpY; // Snap Y Mouse Position
snapped = true;
}
@@ -389,3 +399,11 @@ void SnapManager::setAngleSnapping(bool enable, Base::Vector2d referencepoint)
angleSnapRequested = enable;
referencePoint = referencepoint;
}
Base::Vector2d SketcherGui::SnapManager::SnapHandle::compute(SnapType mask)
{
if (!mgr) {
return cursorPos;
}
return mgr->snap(cursorPos, mask);
}

View File

@@ -51,6 +51,17 @@ private:
friend class SnapManager;
};
enum class SnapType
{
None = 0x0,
Angle = 0x1,
Point = 0x2,
Edge = 0x4,
Grid = 0x8,
All = Angle | Point | Edge | Grid
};
/* This class is used to manage the overriding of mouse pointer coordinates in Sketcher
* (in Edit-Mode) depending on the situation. Those situations are in priority order :
* 1 - Snap at angle: For tools like Slot, Arc, Line, Ellipse, this enables to constrain the angle
@@ -99,16 +110,29 @@ public:
explicit SnapManager(ViewProviderSketch& vp);
~SnapManager();
bool snap(double& x, double& y);
bool snapAtAngle(double& x, double& y);
bool snapToObject(double& x, double& y);
bool snapToGrid(double& x, double& y);
Base::Vector2d snap(Base::Vector2d inputPos, SnapType mask);
bool snapAtAngle(Base::Vector2d inputPos, Base::Vector2d& snapPos);
bool snapToObject(Base::Vector2d inputPos, Base::Vector2d& snapPos, SnapType mask);
bool snapToGrid(Base::Vector2d inputPos, Base::Vector2d& snapPos);
bool snapToLineMiddle(Base::Vector3d& pointToOverride, const Part::GeomLineSegment* line);
bool snapToArcMiddle(Base::Vector3d& pointToOverride, const Part::GeomArcOfCircle* arc);
void setAngleSnapping(bool enable, Base::Vector2d referencepoint);
struct SnapHandle
{
SnapManager* mgr = nullptr;
Base::Vector2d cursorPos;
SnapHandle(SnapManager* m, const Base::Vector2d& cursorPos)
: mgr(m)
, cursorPos(cursorPos)
{}
Base::Vector2d compute(SnapType mask = SnapType::All);
};
private:
/// Reference to ViewProviderSketch in order to access the public and the Attorney Interface
ViewProviderSketch& viewProvider;

View File

@@ -963,9 +963,10 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe
}
}
std::unique_ptr<SnapManager::SnapHandle> snapHandle;
try {
getCoordsOnSketchPlane(pos, normal, x, y);
snapManager->snap(x, y);
snapHandle = std::make_unique<SnapManager::SnapHandle>(snapManager.get(), Base::Vector2d(x, y));
}
catch (const Base::ZeroDivisionError&) {
return false;
@@ -1436,10 +1437,11 @@ bool ViewProviderSketch::mouseMove(const SbVec2s& cursorPos, Gui::View3DInventor
SbLine line;
getProjectingLine(cursorPos, viewer, line);
double x, y;
std::unique_ptr<SnapManager::SnapHandle> snapHandle;
try {
double x, y;
getCoordsOnSketchPlane(line.getPosition(), line.getDirection(), x, y);
snapManager->snap(x, y);
snapHandle = std::make_unique<SnapManager::SnapHandle>(snapManager.get(), Base::Vector2d(x, y));
}
catch (const Base::ZeroDivisionError&) {
return false;
@@ -1488,27 +1490,31 @@ bool ViewProviderSketch::mouseMove(const SbVec2s& cursorPos, Gui::View3DInventor
}
resetPreselectPoint();
return true;
case STATUS_SELECT_Constraint:
case STATUS_SELECT_Constraint: {
setSketchMode(STATUS_SKETCH_DragConstraint);
drag.DragConstraintSet = preselection.PreselectConstraintSet;
drag.xInit = x;
drag.yInit = y;
Base::Vector2d selectionPos = snapHandle->compute();
drag.xInit = selectionPos.x;
drag.yInit = selectionPos.y;
resetPreselectPoint();
return true;
}
case STATUS_SKETCH_Drag: {
doDragStep(x, y);
Base::Vector2d dragPos = snapHandle->compute();
doDragStep(dragPos.x, dragPos.y);
return true;
}
case STATUS_SKETCH_DragConstraint:
if (!drag.DragConstraintSet.empty()) {
Base::Vector2d dragPos = snapHandle->compute();
auto idset = drag.DragConstraintSet;
for (int id : idset) {
moveConstraint(id, Base::Vector2d(x, y));
moveConstraint(id, Base::Vector2d(dragPos.x, dragPos.y));
}
}
return true;
case STATUS_SKETCH_UseHandler:
sketchHandler->mouseMove(Base::Vector2d(x, y));
sketchHandler->mouseMove(*snapHandle);
if (preselectChanged) {
editCoinManager->drawConstraintIcons();
sketchHandler->applyCursor();
@@ -1617,7 +1623,7 @@ void ViewProviderSketch::initDragging(int geoId, Sketcher::PointPos pos, Gui::Vi
getProjectingLine(DoubleClick::prvCursorPos, viewer, line2);
getCoordsOnSketchPlane(
line2.getPosition(), line2.getDirection(), drag.xInit, drag.yInit);
snapManager->snap(drag.xInit, drag.yInit);
snapManager->snap(Base::Vector2d(drag.xInit, drag.yInit), SnapType::All);
};
if (drag.Dragged.size() == 1 && pos == Sketcher::PointPos::none) {