New pedantic check. Check if allowance path is valid.

This check validate seam allowance path and layout allowance path.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2019-02-23 18:43:06 +02:00
parent 73885ea890
commit 77ae13ae18
7 changed files with 78 additions and 13 deletions

View file

@ -1419,6 +1419,52 @@ QLineF VAbstractPiece::ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qrea
return paralel;
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractPiece::IsAllowanceValid(const QVector<QPointF> &base, const QVector<QPointF> &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)
{

View file

@ -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<QPointF> &base, const QVector<QPointF> &allowance);
template <class T>
static QVector<T> CorrectPathDistortion(QVector<T> path);

View file

@ -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();

View file

@ -254,6 +254,7 @@ VLayoutPiece::~VLayoutPiece()
VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern)
{
QFuture<QVector<QPointF> > futureSeamAllowance = QtConcurrent::run(piece, &VPiece::SeamAllowancePoints, pattern);
QFuture<bool> futureSeamAllowanceValid = QtConcurrent::run(piece, &VPiece::IsSeamAllowanceValid, pattern);
QFuture<QVector<QPointF> > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern);
QFuture<QVector<VLayoutPiecePath> > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern);
QFuture<QVector<QLineF> > 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<QPointF> 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<QPointF> base = (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? d->seamAllowance : d->contour;
return VAbstractPiece::IsAllowanceValid(base, d->layoutAllowance);
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -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
{

View file

@ -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);

View file

@ -1295,10 +1295,12 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
QFuture<QPainterPath > futurePassmarks = QtConcurrent::run(detail, &VPiece::PassmarksPath, this->getData());
QFuture<QVector<QPointF> > futureSeamAllowance;
QFuture<bool> 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);