From 77ae13ae182551859b34f04f72bb4299def18432 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sat, 23 Feb 2019 18:43:06 +0200 Subject: [PATCH] New pedantic check. Check if allowance path is valid. This check validate seam allowance path and layout allowance path. --HG-- branch : develop --- src/libs/vlayout/vabstractpiece.cpp | 46 ++++++++++++++++++++ src/libs/vlayout/vabstractpiece.h | 1 + src/libs/vlayout/vbank.cpp | 8 ++-- src/libs/vlayout/vlayoutpiece.cpp | 20 ++++----- src/libs/vpatterndb/vpiece.cpp | 6 +++ src/libs/vpatterndb/vpiece.h | 2 + src/libs/vtools/tools/vtoolseamallowance.cpp | 8 ++++ 7 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/libs/vlayout/vabstractpiece.cpp b/src/libs/vlayout/vabstractpiece.cpp index 365038595..eeeae73ff 100644 --- a/src/libs/vlayout/vabstractpiece.cpp +++ b/src/libs/vlayout/vabstractpiece.cpp @@ -1419,6 +1419,52 @@ QLineF VAbstractPiece::ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qrea return paralel; } +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractPiece::IsAllowanceValid(const QVector &base, const QVector &allowance) +{ + if (base.size() < 3 || allowance.size() < 3) + { + return false; // Not enough data + } + + const qreal baseDirection = VPiece::SumTrapezoids(base); + const qreal allowanceDirection = VPiece::SumTrapezoids(allowance); + + if (baseDirection >= 0 || allowanceDirection >= 0) + { + return false; // Wrong direction + } + + for (auto i = 0; i < base.count()-1; ++i) + { + QLineF baseSegment(base.at(i), base.at(i+1)); + if (baseSegment.isNull()) + { + continue; + } + + for (auto j = 0; j < allowance.count()-1; ++j) + { + QLineF allowanceSegment(allowance.at(j), allowance.at(j+1)); + if (allowanceSegment.isNull()) + { + continue; + } + + QPointF crosPoint; + const auto type = baseSegment.intersect(allowanceSegment, &crosPoint); + if (type == QLineF::BoundedIntersection && not VFuzzyComparePoints(baseSegment.p1(), crosPoint) + && not VFuzzyComparePoints(baseSegment.p2(), crosPoint)) + { + + return false; + } + } + } + + return true; +} + //--------------------------------------------------------------------------------------------------------------------- bool VAbstractPiece::IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint) { diff --git a/src/libs/vlayout/vabstractpiece.h b/src/libs/vlayout/vabstractpiece.h index c5626fc4f..b5f72af92 100644 --- a/src/libs/vlayout/vabstractpiece.h +++ b/src/libs/vlayout/vabstractpiece.h @@ -196,6 +196,7 @@ public: const VSAPoint &p1Line2, VSAPoint p2Line2, qreal width, bool *needRollback = nullptr); static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width); + static bool IsAllowanceValid(const QVector &base, const QVector &allowance); template static QVector CorrectPathDistortion(QVector path); diff --git a/src/libs/vlayout/vbank.cpp b/src/libs/vlayout/vbank.cpp index 08447e8ac..2789697d3 100644 --- a/src/libs/vlayout/vbank.cpp +++ b/src/libs/vlayout/vbank.cpp @@ -32,6 +32,7 @@ #include "../vmisc/diagnostic.h" #include "../vmisc/logging.h" +#include "../vmisc/vabstractapplication.h" #include "vlayoutpiece.h" QT_WARNING_PUSH @@ -190,10 +191,11 @@ bool VBank::Prepare() { details[i].SetLayoutWidth(layoutWidth); details[i].SetLayoutAllowancePoints(); - if (not details[i].IsLayoutAllowanceValid()) + if (not details.at(i).IsLayoutAllowanceValid()) { - qWarning()<< QObject::tr("Piece '%1' may broke a layout. Please, check seam allowance to check how seam " - "allowance behave.").arg(details[i].GetName()); + const QString errorMsg = QObject::tr("Piece '%1' has invalid layout allowance. Please, check seam allowance" + " to check how seam allowance behave.").arg(details.at(i).GetName()); + qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg; } const qreal d = details.at(i).Diagonal(); diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index e971df3ff..76a366012 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -254,6 +254,7 @@ VLayoutPiece::~VLayoutPiece() VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern) { QFuture > futureSeamAllowance = QtConcurrent::run(piece, &VPiece::SeamAllowancePoints, pattern); + QFuture futureSeamAllowanceValid = QtConcurrent::run(piece, &VPiece::IsSeamAllowanceValid, pattern); QFuture > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern); QFuture > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern); QFuture > futurePassmarksLines = QtConcurrent::run(piece, &VPiece::PassmarksLines, pattern); @@ -270,6 +271,13 @@ VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern det.SetForbidFlipping(piece.IsForbidFlipping()); det.SetForceFlipping(piece.IsForceFlipping()); + if (not futureSeamAllowanceValid.result()) + { + const QString errorMsg = QObject::tr("Piece '%1'. Seam allowance is not valid.") + .arg(piece.GetName()); + qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg; + } + det.SetCountourPoints(futureMainPath.result(), piece.IsHideMainPath()); det.SetSeamAllowancePoints(futureSeamAllowance.result(), piece.IsSeamAllowance(), piece.IsSeamAllowanceBuiltIn()); det.SetInternalPaths(futureInternalPaths.result()); @@ -933,16 +941,8 @@ QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const //--------------------------------------------------------------------------------------------------------------------- bool VLayoutPiece::IsLayoutAllowanceValid() const { - QVector piecePath; - if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) - { - piecePath = d->seamAllowance; - } - else - { - piecePath = d->contour; - } - return qFloor(qAbs(SumTrapezoids(d->layoutAllowance)/2.0)) >= qFloor(qAbs(SumTrapezoids(piecePath)/2.0)); + QVector base = (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? d->seamAllowance : d->contour; + return VAbstractPiece::IsAllowanceValid(base, d->layoutAllowance); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vpatterndb/vpiece.cpp b/src/libs/vpatterndb/vpiece.cpp index fa8be8a85..5264efdc5 100644 --- a/src/libs/vpatterndb/vpiece.cpp +++ b/src/libs/vpatterndb/vpiece.cpp @@ -610,6 +610,12 @@ QPainterPath VPiece::PlaceLabelPath(const VContainer *data) const return path; } +//--------------------------------------------------------------------------------------------------------------------- +bool VPiece::IsSeamAllowanceValid(const VContainer *data) const +{ + return VAbstractPiece::IsAllowanceValid(UniteMainPathPoints(data), SeamAllowancePoints(data)); +} + //--------------------------------------------------------------------------------------------------------------------- bool VPiece::IsInLayout() const { diff --git a/src/libs/vpatterndb/vpiece.h b/src/libs/vpatterndb/vpiece.h index a6ba94e7c..f482de936 100644 --- a/src/libs/vpatterndb/vpiece.h +++ b/src/libs/vpatterndb/vpiece.h @@ -112,6 +112,8 @@ public: QPainterPath PassmarksPath(const VContainer *data) const; QPainterPath PlaceLabelPath(const VContainer *data) const; + bool IsSeamAllowanceValid(const VContainer *data) const; + bool IsInLayout() const; void SetInLayout(bool inLayout); diff --git a/src/libs/vtools/tools/vtoolseamallowance.cpp b/src/libs/vtools/tools/vtoolseamallowance.cpp index 884707f53..00280049e 100644 --- a/src/libs/vtools/tools/vtoolseamallowance.cpp +++ b/src/libs/vtools/tools/vtoolseamallowance.cpp @@ -1295,10 +1295,12 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren) QFuture futurePassmarks = QtConcurrent::run(detail, &VPiece::PassmarksPath, this->getData()); QFuture > futureSeamAllowance; + QFuture futureSeamAllowanceValid; if (detail.IsSeamAllowance()) { futureSeamAllowance = QtConcurrent::run(detail, &VPiece::SeamAllowancePoints, this->getData()); + futureSeamAllowanceValid = QtConcurrent::run(detail, &VPiece::IsSeamAllowanceValid, this->getData()); } this->setPos(detail.GetMx(), detail.GetMy()); @@ -1327,6 +1329,12 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren) if (detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn()) { + if (not futureSeamAllowanceValid.result()) + { + const QString errorMsg = QObject::tr("Piece '%1'. Seam allowance is not valid.") + .arg(detail.GetName()); + qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg; + } path.addPath(detail.SeamAllowancePath(futureSeamAllowance.result())); path.setFillRule(Qt::OddEvenFill); m_seamAllowance->setPath(path);