From 585213412c6660fbcd982417a300a200506e762f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 25 Apr 2017 20:48:32 +0300 Subject: [PATCH] Fix case with custom piece path as part of main path. ref #668. --HG-- branch : release --- src/libs/vlayout/vabstractpiece.cpp | 45 -------- src/libs/vlayout/vabstractpiece.h | 1 - src/libs/vpatterndb/vpiece.cpp | 170 ++++++++-------------------- src/libs/vpatterndb/vpiece.h | 13 +-- src/libs/vpatterndb/vpiecepath.cpp | 54 ++++++--- src/libs/vpatterndb/vpiecepath.h | 4 +- 6 files changed, 97 insertions(+), 190 deletions(-) diff --git a/src/libs/vlayout/vabstractpiece.cpp b/src/libs/vlayout/vabstractpiece.cpp index 06584008d..74021f732 100644 --- a/src/libs/vlayout/vabstractpiece.cpp +++ b/src/libs/vlayout/vabstractpiece.cpp @@ -755,51 +755,6 @@ QLineF VAbstractPiece::ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qrea return paralel; } -//--------------------------------------------------------------------------------------------------------------------- -QVector VAbstractPiece::ParallelCurve(const QVector &points, qreal width) -{ - QVector curvePoints; - - bool removeFirstAndLast = false; - const QVector p = CorrectEquidistantPoints(points, removeFirstAndLast); - - if (p.size() < 2) - { - return QVector(); - } - else if (p.size() < 3) - { - const QLineF line = ParallelLine(p.at(0), p.at(1), width); - curvePoints << line.p1(); - curvePoints << line.p2(); - } - else - { - for (qint32 i = 0; i < p.size(); ++i) - { - if ( i == 0) - {//first point - curvePoints << ParallelLine(p.at(i), p.at(i+1), width).p1(); - continue; - } - - if (i == p.size()-1) - {//last point - if (not curvePoints.isEmpty()) - { - curvePoints << ParallelLine(p.at(i-1), p.at(i), width).p2(); - } - continue; - } - //points in the middle of polyline - curvePoints << EkvPoint(p.at(i-1), p.at(i), p.at(i+1), p.at(i), width); - } - } - - curvePoints = CheckLoops(CorrectEquidistantPoints(curvePoints, removeFirstAndLast));//Result path can contain loops - return curvePoints; -} - //--------------------------------------------------------------------------------------------------------------------- QLineF VAbstractPiece::ParallelLine(const QPointF &p1, const QPointF &p2, qreal width) { diff --git a/src/libs/vlayout/vabstractpiece.h b/src/libs/vlayout/vabstractpiece.h index b34ea01b1..e45a8a385 100644 --- a/src/libs/vlayout/vabstractpiece.h +++ b/src/libs/vlayout/vabstractpiece.h @@ -173,7 +173,6 @@ public: static QVector EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1, const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width); static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width); - static QVector ParallelCurve(const QVector &points, qreal width); template static QVector CorrectEquidistantPoints(const QVector &points, bool removeFirstAndLast = true); diff --git a/src/libs/vpatterndb/vpiece.cpp b/src/libs/vpatterndb/vpiece.cpp index d81f0427b..0387b2988 100644 --- a/src/libs/vpatterndb/vpiece.cpp +++ b/src/libs/vpatterndb/vpiece.cpp @@ -428,29 +428,10 @@ QVector VPiece::PassmarksLines(const VContainer *data) const continue;// skip node } - int passmarkIndex = i; + const int previousIndex = VPiecePath::FindInLoopNotExcludedUp(i, unitedPath); + const int nextIndex = VPiecePath::FindInLoopNotExcludedDown(i, unitedPath); - int previousIndex = 0; - if (passmarkIndex == 0) - { - previousIndex = VPiecePath::FindInLoopNotExcludedUp(unitedPath.size()-1, unitedPath); - } - else - { - previousIndex = VPiecePath::FindInLoopNotExcludedUp(passmarkIndex-1, unitedPath); - } - - int nextIndex = 0; - if (passmarkIndex == unitedPath.size()-1) - { - nextIndex = VPiecePath::FindInLoopNotExcludedDown(0, unitedPath); - } - else - { - nextIndex = VPiecePath::FindInLoopNotExcludedDown(passmarkIndex+1, unitedPath); - } - - passmarks += CreatePassmark(unitedPath, previousIndex, passmarkIndex, nextIndex, data); + passmarks += CreatePassmark(unitedPath, previousIndex, i, nextIndex, data); } return passmarks; @@ -936,27 +917,26 @@ bool VPiece::GetPassmarkSAPoint(const QVector &path, int index, cons } //--------------------------------------------------------------------------------------------------------------------- -int VPiece::GetPassmarkPreviousSAPoints(const QVector &path, int index, const VSAPoint &passmarkSAPoint, - const VContainer *data, QVector &points) const +bool VPiece::GetPassmarkPreviousSAPoints(const QVector &path, int index, const VSAPoint &passmarkSAPoint, + const VContainer *data, VSAPoint &point) const { SCASSERT(data != nullptr) - const QVector saPoints = GetNodeSAPoints(path, index, data); + const QVector points = GetNodeSAPoints(path, index, data); - if (saPoints.isEmpty()) + if (points.isEmpty()) { - return -1; // Something wrong + return false; // Something wrong } - int saIndex = -1; bool found = false; - int nodeIndex = saPoints.size()-1; + int nodeIndex = points.size()-1; do { - const VSAPoint previous = saPoints.at(nodeIndex); + const VSAPoint previous = points.at(nodeIndex); if (passmarkSAPoint.toPoint() != previous.toPoint()) { - saIndex = nodeIndex; + point = previous; found = true; } --nodeIndex; @@ -964,44 +944,43 @@ int VPiece::GetPassmarkPreviousSAPoints(const QVector &path, int ind if (not found) { - return -1; // Something wrong + return false; // Something wrong } - points = saPoints; - return saIndex; + return true; } //--------------------------------------------------------------------------------------------------------------------- int VPiece::GetPassmarkNextSAPoints(const QVector &path, int index, const VSAPoint &passmarkSAPoint, - const VContainer *data, QVector &points) const + const VContainer *data, VSAPoint &point) const { - const QVector saPoints = GetNodeSAPoints(path, index, data); + SCASSERT(data != nullptr) - if (saPoints.isEmpty()) + const QVector points = GetNodeSAPoints(path, index, data); + + if (points.isEmpty()) { - return -1; // Something wrong + return false; // Something wrong } - int saIndex = -1; bool found = false; int nodeIndex = 0; do { - const VSAPoint next = saPoints.at(nodeIndex); + const VSAPoint next = points.at(nodeIndex); if (passmarkSAPoint.toPoint() != next.toPoint()) { - saIndex = nodeIndex; + point = next; found = true; } ++nodeIndex; - } while (nodeIndex < saPoints.size() && not found); + } while (nodeIndex < points.size() && not found); if (not found) { - return -1; // Something wrong + return false; // Something wrong } - points = saPoints; - return saIndex; + return true; } //--------------------------------------------------------------------------------------------------------------------- @@ -1099,17 +1078,15 @@ QVector VPiece::CreatePassmark(const QVector &path, int prev return QVector(); // Something wrong } - QVector previousSAPoints; - const int previousSAPointIndex = GetPassmarkPreviousSAPoints(path, previousIndex, passmarkSAPoint, data, - previousSAPoints); - if (previousSAPointIndex == -1) + VSAPoint previousSAPoint; + if (not GetPassmarkPreviousSAPoints(path, previousIndex, passmarkSAPoint, data, + previousSAPoint)) { return QVector(); // Something wrong } - QVector nextSAPoints; - const int nextSAPointIndex = GetPassmarkNextSAPoints(path, nextIndex, passmarkSAPoint, data, nextSAPoints); - if (nextSAPointIndex == -1) + VSAPoint nextSAPoint; + if (not GetPassmarkNextSAPoints(path, nextIndex, passmarkSAPoint, data, nextSAPoint)) { return QVector(); // Something wrong } @@ -1117,33 +1094,26 @@ QVector VPiece::CreatePassmark(const QVector &path, int prev if (not IsSeamAllowanceBuiltIn()) { QVector lines; - lines += SAPassmark(path, previousSAPoints, previousSAPointIndex, passmarkSAPoint, nextSAPoints, - nextSAPointIndex, data, passmarkIndex); + lines += SAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex); if (qApp->Settings()->IsDoublePassmark() && path.at(passmarkIndex).IsMainPathNode() && path.at(passmarkIndex).GetPassmarkAngleType() != PassmarkAngleType::Intersection) { - lines += BuiltInSAPassmark(path, previousSAPoints.at(previousSAPointIndex), passmarkSAPoint, - nextSAPoints.at(nextSAPointIndex), data, passmarkIndex); + lines += BuiltInSAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex); } return lines; } else { - return BuiltInSAPassmark(path, previousSAPoints.at(previousSAPointIndex), passmarkSAPoint, - nextSAPoints.at(nextSAPointIndex), data, passmarkIndex); + return BuiltInSAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex); } } //--------------------------------------------------------------------------------------------------------------------- -QVector VPiece::SAPassmark(const QVector &path, const QVector &previousSAPoints, - const int previousSAPointIndex, const VSAPoint &passmarkSAPoint, - const QVector &nextSAPoints, const int nextSAPointIndex, - const VContainer *data, int passmarkIndex) const +QVector VPiece::SAPassmark(const QVector &path, VSAPoint &previousSAPoint, + const VSAPoint &passmarkSAPoint, VSAPoint &nextSAPoint, const VContainer *data, + int passmarkIndex) const { - const VSAPoint &previousSAPoint = previousSAPoints.at(previousSAPointIndex); - const VSAPoint &nextSAPoint = nextSAPoints.at(nextSAPointIndex); - QPointF seamPassmarkSAPoint; if (not GetSeamPassmarkSAPoint(previousSAPoint, passmarkSAPoint, nextSAPoint, data, seamPassmarkSAPoint)) { @@ -1151,8 +1121,6 @@ QVector VPiece::SAPassmark(const QVector &path, const QVecto } const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit()); - const QLineF bigLine1 = ParallelLine(previousSAPoint, passmarkSAPoint, width ); - const QLineF bigLine2 = ParallelLine(passmarkSAPoint, nextSAPoint, width ); QVector passmarksLines; @@ -1167,6 +1135,9 @@ QVector VPiece::SAPassmark(const QVector &path, const QVecto } else if (node.GetPassmarkAngleType() == PassmarkAngleType::Bisector) { + const QLineF bigLine1 = ParallelLine(previousSAPoint, passmarkSAPoint, width ); + const QLineF bigLine2 = ParallelLine(passmarkSAPoint, nextSAPoint, width ); + QLineF edge1 = QLineF(seamPassmarkSAPoint, bigLine1.p1()); QLineF edge2 = QLineF(seamPassmarkSAPoint, bigLine2.p2()); @@ -1179,38 +1150,16 @@ QVector VPiece::SAPassmark(const QVector &path, const QVecto { { // first passmark - QPointF p; QLineF line(previousSAPoint, passmarkSAPoint); + line.setLength(line.length()*100); // Hope 100 is enough - if (nextSAPoints.size() < 2) + const QVector intersections = VAbstractCurve::CurveIntersectLine(SeamAllowancePoints(data), line); + if (intersections.isEmpty()) { - const QLineF::IntersectType type = line.intersect(bigLine2, &p); - if (type == QLineF::NoIntersection) - { - p = passmarkSAPoint; - } - } - else - { - line.setLength(line.length() + passmarkSAPoint.GetSAAfter(width)*2); - - QVector vector; - vector << previousSAPoints; - vector.append(passmarkSAPoint); - vector << nextSAPoints; - - const QVector curvePoints = ParallelCurve(vector, width); - const QVector intersections = VAbstractCurve::CurveIntersectLine(curvePoints, line); - - if (intersections.isEmpty()) - { - return QVector(); // Something wrong - } - - p = intersections.first(); + return QVector(); // Something wrong } - line = QLineF(p, passmarkSAPoint); + line = QLineF(intersections.first(), passmarkSAPoint); line.setLength(qMin(passmarkSAPoint.GetSAAfter(width) * passmarkFactor, maxPassmarkLength)); passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line); @@ -1218,38 +1167,17 @@ QVector VPiece::SAPassmark(const QVector &path, const QVecto { // second passmark - QPointF p; QLineF line(nextSAPoint, passmarkSAPoint); + line.setLength(line.length()*100); // Hope 100 is enough - if (previousSAPoints.size() < 2) + const QVector intersections = VAbstractCurve::CurveIntersectLine(SeamAllowancePoints(data), line); + + if (intersections.isEmpty()) { - const QLineF::IntersectType type = line.intersect(bigLine1, &p); - if (type == QLineF::NoIntersection) - { - p = passmarkSAPoint; - } - } - else - { - line.setLength(line.length() + passmarkSAPoint.GetSABefore(width)*2); - - QVector vector; - vector << previousSAPoints; - vector.append(passmarkSAPoint); - vector << nextSAPoints; - - const QVector curvePoints = ParallelCurve(vector, width); - const QVector intersections = VAbstractCurve::CurveIntersectLine(curvePoints, line); - - if (intersections.isEmpty()) - { - return QVector(); // Something wrong - } - - p = intersections.last(); + return QVector(); // Something wrong } - line = QLineF(p, passmarkSAPoint); + line = QLineF(intersections.last(), passmarkSAPoint); line.setLength(qMin(passmarkSAPoint.GetSABefore(width) * passmarkFactor, maxPassmarkLength)); passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line); diff --git a/src/libs/vpatterndb/vpiece.h b/src/libs/vpatterndb/vpiece.h index f6a5b9092..bec6a9489 100644 --- a/src/libs/vpatterndb/vpiece.h +++ b/src/libs/vpatterndb/vpiece.h @@ -129,10 +129,10 @@ private: QVector GetNodeSAPoints(const QVector &path, int index, const VContainer *data) const; bool GetPassmarkSAPoint(const QVector &path, int index, const VContainer *data, VSAPoint &point) const; - int GetPassmarkPreviousSAPoints(const QVector &path, int index, const VSAPoint &passmarkSAPoint, - const VContainer *data, QVector &points) const; + bool GetPassmarkPreviousSAPoints(const QVector &path, int index, const VSAPoint &passmarkSAPoint, + const VContainer *data, VSAPoint &point) const; int GetPassmarkNextSAPoints(const QVector &path, int index, const VSAPoint &passmarkSAPoint, - const VContainer *data, QVector &points) const; + const VContainer *data, VSAPoint &point) const; bool GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, const VSAPoint &passmarkSAPoint, const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const; @@ -140,10 +140,9 @@ private: QVector CreatePassmark(const QVector &path, int previousIndex, int passmarkIndex, int nextIndex, const VContainer *data) const; - QVector SAPassmark(const QVector &path, const QVector &previousSAPoints, - const int previousSAPointIndex, const VSAPoint &passmarkSAPoint, - const QVector &nextSAPoints, const int nextSAPointIndex, - const VContainer *data, int passmarkIndex) const; + QVector SAPassmark(const QVector &path, VSAPoint &previousSAPoint, + const VSAPoint &passmarkSAPoint, VSAPoint &nextSAPoint, const VContainer *data, + int passmarkIndex) const; QVector BuiltInSAPassmark(const QVector &path, const VSAPoint &previousSAPoint, const VSAPoint &passmarkSAPoint, const VSAPoint &nextSAPoint, const VContainer *data, int passmarkIndex) const; diff --git a/src/libs/vpatterndb/vpiecepath.cpp b/src/libs/vpatterndb/vpiecepath.cpp index 714bb87ee..b9a2b6c8e 100644 --- a/src/libs/vpatterndb/vpiecepath.cpp +++ b/src/libs/vpatterndb/vpiecepath.cpp @@ -386,8 +386,7 @@ VSAPoint VPiecePath::StartSegment(const VContainer *data, const QVector 1) { - int index = 0; - i == 0 ? index = FindInLoopNotExcludedUp(nodes.size()-1, nodes) : index = FindInLoopNotExcludedUp(i-1, nodes); + const int index = FindInLoopNotExcludedUp(i, nodes); if (index != i && index != -1) { @@ -418,8 +417,7 @@ VSAPoint VPiecePath::EndSegment(const VContainer *data, const QVector 2) { - int index = 0; - i == nodes.size()-1 ? index=FindInLoopNotExcludedDown(0, nodes) : index=FindInLoopNotExcludedDown(i+1, nodes); + const int index = FindInLoopNotExcludedDown(i, nodes); if (index != i && index != -1) { @@ -775,19 +773,33 @@ int VPiecePath::indexOfNode(const QVector &nodes, quint32 id) } //--------------------------------------------------------------------------------------------------------------------- -int VPiecePath::FindInLoopNotExcludedUp(int candidate, const QVector &nodes) +int VPiecePath::FindInLoopNotExcludedUp(int start, const QVector &nodes) { - if (candidate < 0 || candidate >= nodes.size()) + if (start < 0 || start >= nodes.size()) + { + return -1; + } + + int i = (start == 0) ? nodes.size()-1 : start-1; + + if (i < 0 || i >= nodes.size()) { return -1; } int checked = 0; - int i = candidate; + bool found = false; do { - if (not nodes.at(i).IsExcluded()) + if (not nodes.at(i).IsExcluded() + && (not nodes.at(start).IsMainPathNode() + || (nodes.at(start).IsMainPathNode() + && nodes.at(start).GetPassmarkAngleType() != PassmarkAngleType::Intersection) + || (nodes.at(start).IsMainPathNode() + && nodes.at(start).GetPassmarkAngleType() == PassmarkAngleType::Intersection + && nodes.at(i).IsMainPathNode()))) { + found = true; break; } @@ -799,23 +811,37 @@ int VPiecePath::FindInLoopNotExcludedUp(int candidate, const QVector } } while (checked < nodes.size()); - return i; + return (not found) ? -1 : i; } //--------------------------------------------------------------------------------------------------------------------- -int VPiecePath::FindInLoopNotExcludedDown(int candidate, const QVector &nodes) +int VPiecePath::FindInLoopNotExcludedDown(int start, const QVector &nodes) { - if (candidate < 0 || candidate >= nodes.size()) + if (start < 0 || start >= nodes.size()) + { + return -1; + } + + int i = (start == nodes.size()-1) ? 0 : start+1; + + if (i < 0 || i >= nodes.size()) { return -1; } int checked = 0; - int i = candidate; + bool found = false; do { - if (not nodes.at(i).IsExcluded()) + if (not nodes.at(i).IsExcluded() + && (not nodes.at(start).IsMainPathNode() + || (nodes.at(start).IsMainPathNode() + && nodes.at(start).GetPassmarkAngleType() != PassmarkAngleType::Intersection) + || (nodes.at(start).IsMainPathNode() + && nodes.at(start).GetPassmarkAngleType() == PassmarkAngleType::Intersection + && nodes.at(i).IsMainPathNode()))) { + found = true; break; } @@ -827,7 +853,7 @@ int VPiecePath::FindInLoopNotExcludedDown(int candidate, const QVector &nodes, quint32 id); - static int FindInLoopNotExcludedUp(int candidate, const QVector &nodes); - static int FindInLoopNotExcludedDown(int candidate, const QVector &nodes); + static int FindInLoopNotExcludedUp(int start, const QVector &nodes); + static int FindInLoopNotExcludedDown(int start, const QVector &nodes); static VSAPoint StartSegment(const VContainer *data, const QVector &nodes, int i, bool reverse); static VSAPoint EndSegment(const VContainer *data, const QVector &nodes, int i, bool reverse);