From b15a11dac283c9e5ed1072b26ea5b158f96b11da Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Mon, 26 Oct 2020 13:15:28 +0200 Subject: [PATCH] Improve editing a spline path through control points for locked angles. When a user locks one segment of a spline path, the neighboring segment must not be able to override it. --- ChangeLog.txt | 1 + .../drawTools/toolcurve/vtoolsplinepath.cpp | 87 +++++++++++++++++-- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index a8243fcf6..87e885430 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,7 @@ # Version 0.7.37 (unreleased) - Fix Tape crash on Mac OS X. - Fix issue in VAbstractCurve::CurveIntersectAxis. +- Improve editing a spline path through control points for locked angles. # Version 0.7.36 October 24, 2020 - [#892] Show tooltip for piece node point. diff --git a/src/libs/vtools/tools/drawTools/toolcurve/vtoolsplinepath.cpp b/src/libs/vtools/tools/drawTools/toolcurve/vtoolsplinepath.cpp index 93c398c09..ebdab5e21 100644 --- a/src/libs/vtools/tools/drawTools/toolcurve/vtoolsplinepath.cpp +++ b/src/libs/vtools/tools/drawTools/toolcurve/vtoolsplinepath.cpp @@ -111,14 +111,38 @@ VToolSplinePath::VToolSplinePath(const VToolSplinePathInitData &initData, QGraph { const VSpline spl = splPath->GetSpline(i); - const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula()); + bool freeAngle1 = true; + + if (i > 1) + { + const VSpline prevSpl = splPath->GetSpline(i-1); + freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula()) && + qmu::QmuTokenParser::IsSingle(prevSpl.GetEndAngleFormula()); + } + else + { + freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula()); + } + const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl.GetC1LengthFormula()); auto *controlPoint = new VControlPointSpline(i, SplinePointPosition::FirstPoint, static_cast(spl.GetP2()), freeAngle1, freeLength1, this); InitControlPoint(controlPoint); - const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula()); + bool freeAngle2 = true; + + if (i < splPath->CountSubSpl()) + { + const VSpline nextSpl = splPath->GetSpline(i+1); + freeAngle2 = qmu::QmuTokenParser::IsSingle(nextSpl.GetStartAngleFormula()) && + qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula()); + } + else + { + freeAngle2 = qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula()); + } + const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl.GetC2LengthFormula()); controlPoint = new VControlPointSpline(i, SplinePointPosition::LastPoint, static_cast(spl.GetP3()), @@ -325,12 +349,39 @@ void VToolSplinePath::UpdateControlPoints(const VSpline &spl, QSharedPointerGetSplinePoint(indexSpline, SplinePointPosition::FirstPoint); - p.SetAngle2(spl.GetStartAngle(), spl.GetStartAngleFormula()); + + if (indexSpline >1) + { + VSpline prevSpline = splPath->GetSpline(indexSpline-1); + if (qmu::QmuTokenParser::IsSingle(prevSpline.GetEndAngleFormula())) + { + p.SetAngle1(spl.GetEndAngle(), spl.GetEndAngleFormula()); + } + } + else + { + p.SetAngle2(spl.GetStartAngle(), spl.GetStartAngleFormula()); + } + + p.SetLength2(spl.GetC1Length(), spl.GetC1LengthFormula()); splPath->UpdatePoint(indexSpline, SplinePointPosition::FirstPoint, p); p = splPath->GetSplinePoint(indexSpline, SplinePointPosition::LastPoint); - p.SetAngle1(spl.GetEndAngle(), spl.GetEndAngleFormula()); + + if (indexSpline < splPath->CountSubSpl()) + { + VSpline nextSpline = splPath->GetSpline(indexSpline+1); + if (qmu::QmuTokenParser::IsSingle(nextSpline.GetStartAngleFormula())) + { + p.SetAngle1(spl.GetEndAngle(), spl.GetEndAngleFormula()); + } + } + else + { + p.SetAngle1(spl.GetEndAngle(), spl.GetEndAngleFormula()); + } + p.SetLength1(spl.GetC2Length(), spl.GetC2LengthFormula()); splPath->UpdatePoint(indexSpline, SplinePointPosition::LastPoint, p); } @@ -732,7 +783,19 @@ void VToolSplinePath::RefreshCtrlPoints() const auto spl = splPath->GetSpline(i); { - const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula()); + bool freeAngle1 = true; + + if (i > 1) + { + const VSpline prevSpl = splPath->GetSpline(i-1); + freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula()) && + qmu::QmuTokenParser::IsSingle(prevSpl.GetEndAngleFormula()); + } + else + { + freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula()); + } + const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl.GetC1LengthFormula()); const auto splinePoint = spl.GetP1(); @@ -741,7 +804,19 @@ void VToolSplinePath::RefreshCtrlPoints() } { - const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula()); + bool freeAngle2 = true; + + if (i < splPath->CountSubSpl()) + { + const VSpline nextSpl = splPath->GetSpline(i+1); + freeAngle2 = qmu::QmuTokenParser::IsSingle(nextSpl.GetStartAngleFormula()) && + qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula()); + } + else + { + freeAngle2 = qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula()); + } + const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl.GetC2LengthFormula()); const auto splinePoint = spl.GetP4();