Skip to content

Commit 54d25bc

Browse files
authored
Merge pull request FreeCAD#24904 from tetektoza/fix/23459_fix_locked_ovp_allowing_change_geom
Sketcher: Remember cursor angle for OVPs after OVP is set
2 parents f0e70e6 + ced9c0d commit 54d25bc

File tree

3 files changed

+83
-21
lines changed

3 files changed

+83
-21
lines changed

src/Mod/Sketcher/Gui/DrawSketchHandlerLine.h

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ class DrawSketchHandlerLine: public DrawSketchHandlerLineBase
8686
explicit DrawSketchHandlerLine(
8787
ConstructionMethod constrMethod = ConstructionMethod::OnePointLengthAngle)
8888
: DrawSketchHandlerLineBase(constrMethod)
89-
, length(0.0) {};
89+
, length(0.0)
90+
, lengthSign(0)
91+
, widthSign(0)
92+
, capturedDirection(0.0, 0.0) {};
9093
~DrawSketchHandlerLine() override = default;
9194

9295
private:
@@ -237,10 +240,23 @@ class DrawSketchHandlerLine: public DrawSketchHandlerLineBase
237240
}
238241
}
239242

243+
void onReset() override
244+
{
245+
lengthSign = 0;
246+
widthSign = 0;
247+
capturedDirection = Base::Vector2d(0.0, 0.0);
248+
toolWidgetManager.resetControls();
249+
}
250+
240251
private:
241252
Base::Vector2d startPoint, endPoint;
242253
double length;
243254

255+
// These store the direction sign when OVP is first set to prevent sign flipping
256+
int lengthSign, widthSign;
257+
// Direction tracking to check once OVP is locked
258+
Base::Vector2d capturedDirection;
259+
244260
void createShape(bool onlyeditoutline) override
245261
{
246262
Q_UNUSED(onlyeditoutline);
@@ -427,12 +443,17 @@ void DSHLineControllerBase::doEnforceControlParameters(Base::Vector2d& onSketchP
427443
if (fabs(width) < Precision::Confusion()
428444
&& fourthParam->hasFinishedEditing) {
429445
unsetOnViewParameter(thirdParam.get());
446+
handler->lengthSign = 0;
430447
return;
431448
}
432449
}
433450
}
434-
int sign = (onSketchPos.x - handler->startPoint.x) >= 0 ? 1 : -1;
435-
onSketchPos.x = handler->startPoint.x + sign * length;
451+
// get sign on the first time we set the OVP label, so it won't get flipped
452+
// with mouse next time
453+
if (handler->lengthSign == 0) {
454+
handler->lengthSign = (onSketchPos.x - handler->startPoint.x) >= 0 ? 1 : -1;
455+
}
456+
onSketchPos.x = handler->startPoint.x + handler->lengthSign * length;
436457
}
437458

438459
if (fourthParam->isSet) {
@@ -444,12 +465,15 @@ void DSHLineControllerBase::doEnforceControlParameters(Base::Vector2d& onSketchP
444465
if (fabs(length) < Precision::Confusion()
445466
&& thirdParam->hasFinishedEditing) {
446467
unsetOnViewParameter(fourthParam.get());
468+
handler->widthSign = 0;
447469
return;
448470
}
449471
}
450472
}
451-
int sign = (onSketchPos.y - handler->startPoint.y) >= 0 ? 1 : -1;
452-
onSketchPos.y = handler->startPoint.y + sign * width;
473+
if (handler->widthSign == 0) {
474+
handler->widthSign = (onSketchPos.y - handler->startPoint.y) >= 0 ? 1 : -1;
475+
}
476+
onSketchPos.y = handler->startPoint.y + handler->widthSign * width;
453477
}
454478
}
455479
else if (handler->constructionMethod() == ConstructionMethod::OnePointLengthAngle) {
@@ -460,20 +484,29 @@ void DSHLineControllerBase::doEnforceControlParameters(Base::Vector2d& onSketchP
460484
}
461485
double length = dir.Length();
462486

487+
if (fourthParam->isSet) {
488+
const double angle = Base::toRadians(fourthParam->getValue());
489+
const Base::Vector2d ovpDir(cos(angle), sin(angle));
490+
handler->capturedDirection = ovpDir;
491+
}
492+
else {
493+
handler->capturedDirection = dir.Normalize();
494+
}
495+
463496
if (thirdParam->isSet) {
464497
length = thirdParam->getValue();
465498
if (length < Precision::Confusion() && thirdParam->hasFinishedEditing) {
466499
unsetOnViewParameter(thirdParam.get());
500+
handler->capturedDirection = Base::Vector2d(0.0, 0.0);
467501
return;
468502
}
469503

470-
onSketchPos = handler->startPoint + length * dir.Normalize();
504+
onSketchPos = handler->startPoint + length * handler->capturedDirection;
471505
}
472-
473-
if (fourthParam->isSet) {
474-
double angle = Base::toRadians(fourthParam->getValue());
475-
Base::Vector2d ovpDir(cos(angle), sin(angle));
476-
onSketchPos.ProjectToLine(onSketchPos - handler->startPoint, ovpDir);
506+
else if (fourthParam->isSet) {
507+
// only angle is set, project current position onto that angle
508+
onSketchPos.ProjectToLine(onSketchPos - handler->startPoint,
509+
handler->capturedDirection);
477510
onSketchPos += handler->startPoint;
478511
}
479512
}
@@ -490,6 +523,8 @@ void DSHLineControllerBase::doEnforceControlParameters(Base::Vector2d& onSketchP
490523
&& (onSketchPos - handler->startPoint).Length() < Precision::Confusion()) {
491524
unsetOnViewParameter(thirdParam.get());
492525
unsetOnViewParameter(fourthParam.get());
526+
handler->lengthSign = 0;
527+
handler->widthSign = 0;
493528
}
494529
} break;
495530
default:

src/Mod/Sketcher/Gui/DrawSketchHandlerRectangle.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ class DrawSketchHandlerRectangle: public DrawSketchHandlerRectangleBase
104104
, constructionPointThreeId(Sketcher::GeoEnum::GeoUndef)
105105
, centerPointId(Sketcher::GeoEnum::GeoUndef)
106106
, side(0)
107+
, lengthSign(0)
108+
, widthSign(0)
107109
{}
108110

109111
~DrawSketchHandlerRectangle() override = default;
@@ -815,6 +817,8 @@ class DrawSketchHandlerRectangle: public DrawSketchHandlerRectangleBase
815817
void onReset() override
816818
{
817819
thickness = 0.;
820+
lengthSign = 0;
821+
widthSign = 0;
818822
toolWidgetManager.resetControls();
819823
}
820824

@@ -827,6 +831,10 @@ class DrawSketchHandlerRectangle: public DrawSketchHandlerRectangleBase
827831
int firstCurve, constructionPointOneId, constructionPointTwoId, constructionPointThreeId,
828832
centerPointId, side;
829833

834+
// Sign tracking for OVP lock fix (issue #23459)
835+
// These store the direction sign when OVP is first set to prevent sign flipping
836+
int lengthSign, widthSign;
837+
830838
void createShape(bool onlyeditoutline) override
831839
{
832840
ShapeGeometry.clear();
@@ -1987,12 +1995,16 @@ void DSHRectangleControllerBase::doEnforceControlParameters(Base::Vector2d& onSk
19871995
if (fabs(length) < Precision::Confusion()
19881996
&& onViewParameters[OnViewParameter::Third]->hasFinishedEditing) {
19891997
unsetOnViewParameter(onViewParameters[OnViewParameter::Third].get());
1998+
handler->lengthSign = 0;
19901999
return;
19912000
}
19922001

19932002
if (handler->constructionMethod() == ConstructionMethod::Diagonal) {
1994-
int sign = (onSketchPos.x - handler->corner1.x) >= 0 ? 1 : -1;
1995-
onSketchPos.x = handler->corner1.x + sign * length;
2003+
if (handler->lengthSign == 0) {
2004+
handler->lengthSign =
2005+
(onSketchPos.x - handler->corner1.x) >= 0 ? 1 : -1;
2006+
}
2007+
onSketchPos.x = handler->corner1.x + handler->lengthSign * length;
19962008
}
19972009
else {
19982010
onSketchPos.x = handler->center.x + length / 2;
@@ -2003,12 +2015,15 @@ void DSHRectangleControllerBase::doEnforceControlParameters(Base::Vector2d& onSk
20032015
if (fabs(width) < Precision::Confusion()
20042016
&& onViewParameters[OnViewParameter::Fourth]->hasFinishedEditing) {
20052017
unsetOnViewParameter(onViewParameters[OnViewParameter::Fourth].get());
2018+
handler->widthSign = 0;
20062019
return;
20072020
}
20082021

20092022
if (handler->constructionMethod() == ConstructionMethod::Diagonal) {
2010-
int sign = (onSketchPos.y - handler->corner1.y) >= 0 ? 1 : -1;
2011-
onSketchPos.y = handler->corner1.y + sign * width;
2023+
if (handler->widthSign == 0) {
2024+
handler->widthSign = (onSketchPos.y - handler->corner1.y) >= 0 ? 1 : -1;
2025+
}
2026+
onSketchPos.y = handler->corner1.y + handler->widthSign * width;
20122027
}
20132028
else {
20142029
onSketchPos.y = handler->center.y + width / 2;

src/Mod/Sketcher/Gui/DrawSketchHandlerSlot.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class DrawSketchHandlerSlot: public DrawSketchHandlerSlotBase
7474
, length(0.0)
7575
, angle(0.0)
7676
, firstCurve(0)
77+
, capturedDirection(0.0, 0.0)
7778
{}
7879

7980
~DrawSketchHandlerSlot() override = default;
@@ -339,6 +340,9 @@ class DrawSketchHandlerSlot: public DrawSketchHandlerSlotBase
339340
Base::Vector2d startPoint, secondPoint;
340341
double radius, length, angle;
341342
int firstCurve;
343+
344+
// Direction tracking to prevent OVP from flipping (issue #23459)
345+
Base::Vector2d capturedDirection;
342346
};
343347

344348
template<>
@@ -403,20 +407,28 @@ void DSHSlotControllerBase::doEnforceControlParameters(Base::Vector2d& onSketchP
403407
}
404408
double length = dir.Length();
405409

410+
if (fourthParam->isSet) {
411+
const double angle = Base::toRadians(fourthParam->getValue());
412+
const Base::Vector2d ovpDir(cos(angle), sin(angle));
413+
handler->capturedDirection = ovpDir;
414+
}
415+
else {
416+
handler->capturedDirection = dir.Normalize();
417+
}
418+
406419
if (thirdParam->isSet) {
407420
length = thirdParam->getValue();
408421
if (length < Precision::Confusion() && thirdParam->hasFinishedEditing) {
409422
unsetOnViewParameter(thirdParam.get());
423+
handler->capturedDirection = Base::Vector2d(0.0, 0.0);
410424
return;
411425
}
412426

413-
onSketchPos = handler->startPoint + length * dir.Normalize();
427+
onSketchPos = handler->startPoint + length * handler->capturedDirection;
414428
}
415-
416-
if (fourthParam->isSet) {
417-
double angle = Base::toRadians(fourthParam->getValue());
418-
Base::Vector2d ovpDir(cos(angle), sin(angle));
419-
onSketchPos.ProjectToLine(onSketchPos - handler->startPoint, ovpDir);
429+
else if (fourthParam->isSet) {
430+
onSketchPos.ProjectToLine(onSketchPos - handler->startPoint,
431+
handler->capturedDirection);
420432
onSketchPos += handler->startPoint;
421433
}
422434
} break;

0 commit comments

Comments
 (0)