From f05cd909a281966095c732a5e2b8735e2718d1ab Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 30 Mar 2017 12:26:06 +0300 Subject: [PATCH] Unite nodes to be able to show passmarks from custom seam allowance included as main path. --HG-- branch : feature --- src/libs/vpatterndb/vpiece.cpp | 145 +++++++++++++++++++---------- src/libs/vpatterndb/vpiece.h | 21 +++-- src/libs/vpatterndb/vpiecepath.cpp | 26 ++++-- src/libs/vpatterndb/vpiecepath.h | 2 + 4 files changed, 125 insertions(+), 69 deletions(-) diff --git a/src/libs/vpatterndb/vpiece.cpp b/src/libs/vpatterndb/vpiece.cpp index d6a875471..b049a5543 100644 --- a/src/libs/vpatterndb/vpiece.cpp +++ b/src/libs/vpatterndb/vpiece.cpp @@ -226,11 +226,12 @@ QVector VPiece::SeamAllowancePoints(const VContainer *data) const int recordIndex = -1; bool insertingCSA = false; const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit()); + const QVector unitedPath = GetUnitedPath(data); QVector pointsEkv; - for (int i = 0; i< d->m_path.CountNodes(); ++i) + for (int i = 0; i< unitedPath.size(); ++i) { - const VPieceNode &node = d->m_path.at(i); + const VPieceNode &node = unitedPath.at(i); if (node.IsExcluded()) { continue;// skip excluded node @@ -245,21 +246,18 @@ QVector VPiece::SeamAllowancePoints(const VContainer *data) const pointsEkv.append(VPiecePath::PreparePointEkv(node, data)); recordIndex = IsCSAStart(records, node.GetId()); - if (recordIndex != -1) + if (recordIndex != -1 && records.at(recordIndex).includeType == PiecePathIncludeType::AsCustomSA) { insertingCSA = true; const VPiecePath path = data->GetPiecePath(records.at(recordIndex).path); QVector r = path.SeamAllowancePoints(data, width, records.at(recordIndex).reverse); - if (records.at(recordIndex).includeType == PiecePathIncludeType::AsCustomSA) + for (int j = 0; j < r.size(); ++j) { - for (int j = 0; j < r.size(); ++j) - { - r[j].SetAngleType(PieceNodeAngle::ByLength); - r[j].SetSABefore(0); - r[j].SetSAAfter(0); - } + r[j].SetAngleType(PieceNodeAngle::ByLength); + r[j].SetSABefore(0); + r[j].SetSAAfter(0); } pointsEkv += r; @@ -286,8 +284,8 @@ QVector VPiece::SeamAllowancePoints(const VContainer *data) const { const QSharedPointer curve = data->GeometricObject(node.GetId()); - pointsEkv += VPiecePath::CurveSeamAllowanceSegment(data, d->m_path.GetNodes(), curve, i, - node.GetReverse(), width); + pointsEkv += VPiecePath::CurveSeamAllowanceSegment(data, unitedPath, curve, i, node.GetReverse(), + width); } } break; @@ -303,16 +301,17 @@ QVector VPiece::SeamAllowancePoints(const VContainer *data) const //--------------------------------------------------------------------------------------------------------------------- QVector VPiece::PassmarksLines(const VContainer *data) const { - if (not IsSeamAllowance() || not IsPassmarksPossible()) + const QVector unitedPath = GetUnitedPath(data); + if (not IsSeamAllowance() || not IsPassmarksPossible(unitedPath)) { return QVector(); } QVector passmarks; - for (int i = 0; i< d->m_path.CountNodes(); ++i) + for (int i = 0; i< unitedPath.size(); ++i) { - const VPieceNode &node = d->m_path.at(i); + const VPieceNode &node = unitedPath.at(i); if (node.IsExcluded() || not node.IsPassmark()) { continue;// skip node @@ -323,24 +322,24 @@ QVector VPiece::PassmarksLines(const VContainer *data) const int previousIndex = 0; if (passmarkIndex == 0) { - previousIndex = VPiecePath::FindInLoopNotExcludedUp(d->m_path.CountNodes()-1, d->m_path.GetNodes()); + previousIndex = VPiecePath::FindInLoopNotExcludedUp(unitedPath.size()-1, unitedPath); } else { - previousIndex = VPiecePath::FindInLoopNotExcludedUp(passmarkIndex-1, d->m_path.GetNodes()); + previousIndex = VPiecePath::FindInLoopNotExcludedUp(passmarkIndex-1, unitedPath); } int nextIndex = 0; - if (passmarkIndex == d->m_path.CountNodes()-1) + if (passmarkIndex == unitedPath.size()-1) { - nextIndex = VPiecePath::FindInLoopNotExcludedDown(0, d->m_path.GetNodes()); + nextIndex = VPiecePath::FindInLoopNotExcludedDown(0, unitedPath); } else { - nextIndex = VPiecePath::FindInLoopNotExcludedDown(passmarkIndex+1, d->m_path.GetNodes()); + nextIndex = VPiecePath::FindInLoopNotExcludedDown(passmarkIndex+1, unitedPath); } - passmarks += CreatePassmark(previousIndex, passmarkIndex, nextIndex, data); + passmarks += CreatePassmark(unitedPath, previousIndex, passmarkIndex, nextIndex, data); } return passmarks; @@ -644,6 +643,47 @@ const VGrainlineData &VPiece::GetGrainlineGeometry() const return d->m_glGrainline; } +//--------------------------------------------------------------------------------------------------------------------- +QVector VPiece::GetUnitedPath(const VContainer *data) const +{ + SCASSERT(data != nullptr) + + QVector united = d->m_path.GetNodes(); + const QVector records = FilterRecords(GetValidRecords()); + + for (int i = 0; i < records.size(); ++i) + { + if (records.at(i).includeType == PiecePathIncludeType::AsMainPath) + { + const int indexStartPoint = VPiecePath::indexOfNode(united, records.at(i).startPoint); + const int indexEndPoint = VPiecePath::indexOfNode(united, records.at(i).endPoint); + + if (indexStartPoint == -1 || indexEndPoint == -1) + { + continue; + } + + const QVector midBefore = united.mid(0, indexStartPoint+1); + const QVector midAfter = united.mid(indexEndPoint); + + QVector customNodes = data->GetPiecePath(records.at(i).path).GetNodes(); + if (records.at(i).reverse) + { + customNodes = VGObject::GetReversePoints(customNodes); + + // Additionally reverse all curves + for (int j = 0; j < customNodes.size(); ++j) + { // don't make a check because node point will ignore the change + customNodes[j].SetReverse(not customNodes.at(j).GetReverse()); + } + } + + united = midBefore + customNodes + midAfter; + } + } + return united; +} + //--------------------------------------------------------------------------------------------------------------------- QVector VPiece::GetValidRecords() const { @@ -719,16 +759,16 @@ QVector VPiece::FilterRecords(QVector records) c } //--------------------------------------------------------------------------------------------------------------------- -QVector VPiece::GetNodeSAPoints(int index, const VContainer *data) const +QVector VPiece::GetNodeSAPoints(const QVector &path, int index, const VContainer *data) const { SCASSERT(data != nullptr) - if (index < 0 || index >= d->m_path.CountNodes()) + if (index < 0 || index >= path.size()) { return QVector(); } - const VPieceNode &node = d->m_path.at(index); + const VPieceNode &node = path.at(index); QVector points; if (node.GetTypeTool() == Tool::NodePoint) @@ -740,18 +780,18 @@ QVector VPiece::GetNodeSAPoints(int index, const VContainer *data) con const QSharedPointer curve = data->GeometricObject(node.GetId()); const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit()); - points += VPiecePath::CurveSeamAllowanceSegment(data, d->m_path.GetNodes(), curve, index, node.GetReverse(), - width); + points += VPiecePath::CurveSeamAllowanceSegment(data, path, curve, index, node.GetReverse(), width); } return points; } //--------------------------------------------------------------------------------------------------------------------- -bool VPiece::GetPassmarkSAPoint(int index, const VContainer *data, VSAPoint &point) const +bool VPiece::GetPassmarkSAPoint(const QVector &path, int index, const VContainer *data, + VSAPoint &point) const { SCASSERT(data != nullptr) - const QVector points = GetNodeSAPoints(index, data); + const QVector points = GetNodeSAPoints(path, index, data); if (points.isEmpty() || points.size() > 1) { @@ -763,12 +803,12 @@ bool VPiece::GetPassmarkSAPoint(int index, const VContainer *data, VSAPoint &poi } //--------------------------------------------------------------------------------------------------------------------- -bool VPiece::GetPassmarkPreviousSAPoint(int index, const VSAPoint &passmarkSAPoint, const VContainer *data, - VSAPoint &point) const +bool VPiece::GetPassmarkPreviousSAPoint(const QVector &path, int index, const VSAPoint &passmarkSAPoint, + const VContainer *data, VSAPoint &point) const { SCASSERT(data != nullptr) - const QVector points = GetNodeSAPoints(index, data); + const QVector points = GetNodeSAPoints(path, index, data); if (points.isEmpty()) { @@ -796,10 +836,10 @@ bool VPiece::GetPassmarkPreviousSAPoint(int index, const VSAPoint &passmarkSAPoi } //--------------------------------------------------------------------------------------------------------------------- -bool VPiece::GetPassmarkNextSAPoint(int index, const VSAPoint &passmarkSAPoint, const VContainer *data, - VSAPoint &point) const +bool VPiece::GetPassmarkNextSAPoint(const QVector &path, int index, const VSAPoint &passmarkSAPoint, + const VContainer *data, VSAPoint &point) const { - const QVector points = GetNodeSAPoints(index, data); + const QVector points = GetNodeSAPoints(path, index, data); if (points.isEmpty()) { @@ -855,14 +895,14 @@ bool VPiece::GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, const VSAPo } //--------------------------------------------------------------------------------------------------------------------- -bool VPiece::IsPassmarksPossible() const +bool VPiece::IsPassmarksPossible(const QVector &path) const { int countPointNodes = 0; int countOthers = 0; - for (int i = 0; i< d->m_path.CountNodes(); ++i) + for (int i = 0; i< path.size(); ++i) { - const VPieceNode &node = d->m_path.at(i); + const VPieceNode &node = path.at(i); if (node.IsExcluded()) { continue;// skip node @@ -875,14 +915,14 @@ bool VPiece::IsPassmarksPossible() const } //--------------------------------------------------------------------------------------------------------------------- -bool VPiece::IsPassmarkVisible(int passmarkIndex) const +bool VPiece::IsPassmarkVisible(const QVector &path, int passmarkIndex) const { - if (passmarkIndex < 0 || passmarkIndex >= d->m_path.CountNodes()) + if (passmarkIndex < 0 || passmarkIndex >= path.size()) { return false; } - const VPieceNode &node = d->m_path.at(passmarkIndex); + const VPieceNode &node = path.at(passmarkIndex); if (node.GetTypeTool() != Tool::NodePoint || not node.IsPassmark() || node.IsExcluded()) { return false; @@ -896,41 +936,44 @@ bool VPiece::IsPassmarkVisible(int passmarkIndex) const for (int i = 0; i < records.size(); ++i) { - const int indexStartPoint = d->m_path.indexOfNode(records.at(i).startPoint); - const int indexEndPoint = d->m_path.indexOfNode(records.at(i).endPoint); - if (passmarkIndex > indexStartPoint && passmarkIndex < indexEndPoint) + if (records.at(i).includeType == PiecePathIncludeType::AsCustomSA) { - return false; + const int indexStartPoint = VPiecePath::indexOfNode(path, records.at(i).startPoint); + const int indexEndPoint = VPiecePath::indexOfNode(path, records.at(i).endPoint); + if (passmarkIndex > indexStartPoint && passmarkIndex < indexEndPoint) + { + return false; + } } } return true; } //--------------------------------------------------------------------------------------------------------------------- -QVector VPiece::CreatePassmark(int previousIndex, int passmarkIndex, int nextIndex, - const VContainer *data) const +QVector VPiece::CreatePassmark(const QVector &path, int previousIndex, int passmarkIndex, + int nextIndex, const VContainer *data) const { SCASSERT(data != nullptr); - if (not IsPassmarkVisible(passmarkIndex)) + if (not IsPassmarkVisible(path, passmarkIndex)) { return QVector(); } VSAPoint passmarkSAPoint; - if (not GetPassmarkSAPoint(passmarkIndex, data, passmarkSAPoint)) + if (not GetPassmarkSAPoint(path, passmarkIndex, data, passmarkSAPoint)) { return QVector(); // Something wrong } VSAPoint previousSAPoint; - if (not GetPassmarkPreviousSAPoint(previousIndex, passmarkSAPoint, data, previousSAPoint)) + if (not GetPassmarkPreviousSAPoint(path, previousIndex, passmarkSAPoint, data, previousSAPoint)) { return QVector(); // Something wrong } VSAPoint nextSAPoint; - if (not GetPassmarkNextSAPoint(nextIndex, passmarkSAPoint, data, nextSAPoint)) + if (not GetPassmarkNextSAPoint(path, nextIndex, passmarkSAPoint, data, nextSAPoint)) { return QVector(); // Something wrong } @@ -948,7 +991,7 @@ QVector VPiece::CreatePassmark(int previousIndex, int passmarkIndex, int QVector passmarksLines; const qreal passmarkLength = VAbstractPiece::MaxLocalSA(passmarkSAPoint, width) * 0.25; - const VPieceNode &node = d->m_path.at(passmarkIndex); + const VPieceNode &node = path.at(passmarkIndex); if (node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward) { QLineF line = QLineF(seamPassmarkSAPoint, passmarkSAPoint); diff --git a/src/libs/vpatterndb/vpiece.h b/src/libs/vpatterndb/vpiece.h index 7f5c40ec6..a2ec5971f 100644 --- a/src/libs/vpatterndb/vpiece.h +++ b/src/libs/vpatterndb/vpiece.h @@ -113,23 +113,26 @@ public: private: QSharedDataPointer d; + QVector GetUnitedPath(const VContainer *data) const; + QVector GetValidRecords() const; QVector FilterRecords(QVector records) const; - QVector GetNodeSAPoints(int index, const VContainer *data) const; + QVector GetNodeSAPoints(const QVector &path, int index, const VContainer *data) const; - bool GetPassmarkSAPoint(int index, const VContainer *data, VSAPoint &point) const; - bool GetPassmarkPreviousSAPoint(int index, const VSAPoint &passmarkSAPoint, const VContainer *data, - VSAPoint &point) const; - bool GetPassmarkNextSAPoint(int index, const VSAPoint &passmarkSAPoint, const VContainer *data, - VSAPoint &point) const; + bool GetPassmarkSAPoint(const QVector &path, int index, const VContainer *data, VSAPoint &point) const; + bool GetPassmarkPreviousSAPoint(const QVector &path, int index, const VSAPoint &passmarkSAPoint, + const VContainer *data, VSAPoint &point) const; + bool GetPassmarkNextSAPoint(const QVector &path, int index, const VSAPoint &passmarkSAPoint, + const VContainer *data, VSAPoint &point) const; bool GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, const VSAPoint &passmarkSAPoint, const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const; - bool IsPassmarksPossible() const; - bool IsPassmarkVisible(int passmarkIndex) const; + bool IsPassmarksPossible(const QVector &path) const; + bool IsPassmarkVisible(const QVector &path, int passmarkIndex) const; - QVector CreatePassmark(int previousIndex, int passmarkIndex, int nextIndex, const VContainer *data) const; + QVector CreatePassmark(const QVector &path, int previousIndex, int passmarkIndex, int nextIndex, + const VContainer *data) const; static int IsCSAStart(const QVector &records, quint32 id); }; diff --git a/src/libs/vpatterndb/vpiecepath.cpp b/src/libs/vpatterndb/vpiecepath.cpp index 3e23330e4..3e569a8b7 100644 --- a/src/libs/vpatterndb/vpiecepath.cpp +++ b/src/libs/vpatterndb/vpiecepath.cpp @@ -466,15 +466,7 @@ QVector VPiecePath::MissingNodes(const VPiecePath &path) const //--------------------------------------------------------------------------------------------------------------------- int VPiecePath::indexOfNode(quint32 id) const { - for (int i = 0; i < d->m_nodes.size(); ++i) - { - if (d->m_nodes.at(i).GetId() == id) - { - return i; - } - } - qDebug()<<"Can't find node."; - return -1; + return indexOfNode(d->m_nodes, id); } //--------------------------------------------------------------------------------------------------------------------- @@ -768,6 +760,20 @@ QPointF VPiecePath::NodeNextPoint(const VContainer *data, int i) const return point; } +//--------------------------------------------------------------------------------------------------------------------- +int VPiecePath::indexOfNode(const QVector &nodes, quint32 id) +{ + for (int i = 0; i < nodes.size(); ++i) + { + if (nodes.at(i).GetId() == id) + { + return i; + } + } + qDebug()<<"Can't find node."; + return -1; +} + //--------------------------------------------------------------------------------------------------------------------- int VPiecePath::FindInLoopNotExcludedUp(int candidate, const QVector &nodes) { @@ -827,6 +833,8 @@ int VPiecePath::FindInLoopNotExcludedDown(int candidate, const QVector point = data->GeometricObject(node.GetId()); VSAPoint p(point->toQPointF()); diff --git a/src/libs/vpatterndb/vpiecepath.h b/src/libs/vpatterndb/vpiecepath.h index 8bda5957b..bd41edb64 100644 --- a/src/libs/vpatterndb/vpiecepath.h +++ b/src/libs/vpatterndb/vpiecepath.h @@ -94,6 +94,8 @@ public: QPointF NodePreviousPoint(const VContainer *data, int i) const; QPointF NodeNextPoint(const VContainer *data, int i) const; + static int indexOfNode(const QVector &nodes, quint32 id); + static int FindInLoopNotExcludedUp(int candidate, const QVector &nodes); static int FindInLoopNotExcludedDown(int candidate, const QVector &nodes);