Fixed issue #924. Valentina produces wrong passmark for rollback case.

--HG--
branch : release
This commit is contained in:
Roman Telezhynskyi 2019-01-09 17:46:02 +02:00
parent 38d8342b57
commit 9a803bf4f3
11 changed files with 1016 additions and 320 deletions

View File

@ -7,6 +7,7 @@
- [#914] Filtering custom seam allowance paths prevent including more than one. - [#914] Filtering custom seam allowance paths prevent including more than one.
- [#915] Valentina produces wrong seam allowance for acute angle. - [#915] Valentina produces wrong seam allowance for acute angle.
- [#923] Valentina produces wrong seam allowance for rollback case. - [#923] Valentina produces wrong seam allowance for rollback case.
- [#924] Valentina produces wrong passmark for rollback case.
# Version 0.6.1 October 23, 2018 # Version 0.6.1 October 23, 2018
- [#885] Regression. Broken support for multi size measurements. - [#885] Regression. Broken support for multi size measurements.

View File

@ -39,6 +39,9 @@
const qreal maxL = 2.5; const qreal maxL = 2.5;
const qreal VSAPoint::passmarkFactor = 0.5;
const qreal VSAPoint::maxPassmarkLength = (10/*mm*/ / 25.4) * PrintDPI;
namespace namespace
{ {
// Do we create a point outside of a path? // Do we create a point outside of a path?
@ -178,55 +181,13 @@ Q_DECL_CONSTEXPR qreal PointPosition(const QPointF &p, const QLineF &line)
(line.p2().y() - line.p1().y()) * (p.x() - line.p1().x()); (line.p2().y() - line.p1().y()) * (p.x() - line.p1().x());
} }
//---------------------------------------------------------------------------------------------------------------------
// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
QVector<QPointF> RollbackSeamAllowance(QVector<QPointF> points, const QLineF &cuttingEdge, bool *success)
{
*success = false;
QVector<QPointF> clipped;
clipped.reserve(points.count()+1);
for (int i = points.count()-1; i > 0; --i)
{
QLineF segment(points.at(i), points.at(i-1));
QPointF crosPoint;
const QLineF::IntersectType type = cuttingEdge.intersect(segment, &crosPoint);
if (type != QLineF::NoIntersection
&& VGObject::IsPointOnLineSegment(crosPoint, segment.p1(), segment.p2())
&& IsOutsidePoint(cuttingEdge.p2(), cuttingEdge.p1(), crosPoint))
{
clipped.append(crosPoint);
for (int j=i-1; j>=0; --j)
{
clipped.append(points.at(j));
}
points = VGObject::GetReversePoints(clipped);
*success = true;
break;
}
}
if (not *success && points.size() > 1)
{
QPointF crosPoint;
QLineF secondLast(points.at(points.size()-2), points.at(points.size()-1));
QLineF::IntersectType type = secondLast.intersect(cuttingEdge, &crosPoint);
if (type != QLineF::NoIntersection && IsOutsidePoint(secondLast.p1(), secondLast.p2(), crosPoint))
{
points.append(crosPoint);
*success = true;
}
}
return points;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> AngleByLength(QVector<QPointF> points, QPointF p2, const QLineF &bigLine1, QPointF sp2, QVector<QPointF> AngleByLength(QVector<QPointF> points, QPointF p2, const QLineF &bigLine1, QPointF sp2,
const QLineF &bigLine2, const VSAPoint &p, qreal width, int *needRollback = nullptr) const QLineF &bigLine2, const VSAPoint &p, qreal width, bool *needRollback = nullptr)
{ {
if (needRollback != nullptr) if (needRollback != nullptr)
{ {
*needRollback = -1; *needRollback = false;
} }
const QPointF sp1 = bigLine1.p1(); const QPointF sp1 = bigLine1.p1();
@ -273,10 +234,10 @@ QVector<QPointF> AngleByLength(QVector<QPointF> points, QPointF p2, const QLineF
if (p.GetAngleType() != PieceNodeAngle::ByLengthCurve) if (p.GetAngleType() != PieceNodeAngle::ByLengthCurve)
{ {
bool success = false; bool success = false;
points = RollbackSeamAllowance(points, bigLine2, &success); points = VAbstractPiece::RollbackSeamAllowance(points, bigLine2, &success);
if (needRollback != nullptr) if (needRollback != nullptr)
{ {
*needRollback = 0; *needRollback = true;
} }
} }
else else
@ -311,11 +272,11 @@ QVector<QPointF> AngleByLength(QVector<QPointF> points, QPointF p2, const QLineF
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> AngleByIntersection(const QVector<QPointF> &points, QPointF p1, QPointF p2, QPointF p3, QVector<QPointF> AngleByIntersection(const QVector<QPointF> &points, QPointF p1, QPointF p2, QPointF p3,
const QLineF &bigLine1, QPointF sp2, const QLineF &bigLine2, const QLineF &bigLine1, QPointF sp2, const QLineF &bigLine2,
const VSAPoint &p, qreal width, int *needRollback = nullptr) const VSAPoint &p, qreal width, bool *needRollback = nullptr)
{ {
if (needRollback != nullptr) if (needRollback != nullptr)
{ {
*needRollback = -1; *needRollback = false;
} }
const qreal localWidth = p.MaxLocalSA(width); const qreal localWidth = p.MaxLocalSA(width);
@ -331,7 +292,6 @@ QVector<QPointF> AngleByIntersection(const QVector<QPointF> &points, QPointF p1,
return AngleByLength(points, p2, bigLine1, sp2, bigLine2, p, width); return AngleByLength(points, p2, bigLine1, sp2, bigLine2, p, width);
} }
bool rollbackFlag = false;
if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px)) if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px))
{ {
if (QLineF(p2, px).length() > localWidth*maxL) if (QLineF(p2, px).length() > localWidth*maxL)
@ -343,8 +303,12 @@ QVector<QPointF> AngleByIntersection(const QVector<QPointF> &points, QPointF p1,
else else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points {// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false; bool success = false;
pointsIntr = RollbackSeamAllowance(pointsIntr, edge2, &success); pointsIntr = VAbstractPiece::RollbackSeamAllowance(pointsIntr, edge2, &success);
rollbackFlag = true;
if (needRollback != nullptr)
{
*needRollback = true;
}
} }
// Second point // Second point
@ -359,11 +323,6 @@ QVector<QPointF> AngleByIntersection(const QVector<QPointF> &points, QPointF p1,
if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px)) if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px))
{ {
pointsIntr.append(px); pointsIntr.append(px);
if (needRollback != nullptr && rollbackFlag)
{
*needRollback = 1;
}
} }
else else
{ {
@ -372,11 +331,6 @@ QVector<QPointF> AngleByIntersection(const QVector<QPointF> &points, QPointF p1,
allowance.setLength(allowance.length() + localWidth * 3.); allowance.setLength(allowance.length() + localWidth * 3.);
pointsIntr.append(allowance.p2()); pointsIntr.append(allowance.p2());
pointsIntr.append(bigLine2.p2()); pointsIntr.append(bigLine2.p2());
if (needRollback != nullptr && rollbackFlag)
{
*needRollback = 3;
}
} }
return pointsIntr; return pointsIntr;
@ -385,11 +339,11 @@ QVector<QPointF> AngleByIntersection(const QVector<QPointF> &points, QPointF p1,
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> AngleByFirstSymmetry(const QVector<QPointF> &points, QPointF p1, QPointF p2, QVector<QPointF> AngleByFirstSymmetry(const QVector<QPointF> &points, QPointF p1, QPointF p2,
const QLineF &bigLine1, QPointF sp2, const QLineF &bigLine2, const QLineF &bigLine1, QPointF sp2, const QLineF &bigLine2,
const VSAPoint &p, qreal width, int *needRollback = nullptr) const VSAPoint &p, qreal width, bool *needRollback = nullptr)
{ {
if (needRollback != nullptr) if (needRollback != nullptr)
{ {
*needRollback = -1; *needRollback = false;
} }
const qreal localWidth = p.MaxLocalSA(width); const qreal localWidth = p.MaxLocalSA(width);
@ -404,7 +358,6 @@ QVector<QPointF> AngleByFirstSymmetry(const QVector<QPointF> &points, QPointF p1
return AngleByLength(points, p2, bigLine1, sp2, bigLine2, p, width); return AngleByLength(points, p2, bigLine1, sp2, bigLine2, p, width);
} }
bool rollbackFlag = false;
if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px)) if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px))
{ {
if (QLineF(p2, px).length() > localWidth*maxL) if (QLineF(p2, px).length() > localWidth*maxL)
@ -416,8 +369,12 @@ QVector<QPointF> AngleByFirstSymmetry(const QVector<QPointF> &points, QPointF p1
else else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points {// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false; bool success = false;
pointsIntr = RollbackSeamAllowance(pointsIntr, bigLine2, &success); pointsIntr = VAbstractPiece::RollbackSeamAllowance(pointsIntr, bigLine2, &success);
rollbackFlag = true;
if (needRollback != nullptr)
{
*needRollback = true;
}
} }
type = sEdge.intersect(bigLine2, &px); type = sEdge.intersect(bigLine2, &px);
@ -433,11 +390,6 @@ QVector<QPointF> AngleByFirstSymmetry(const QVector<QPointF> &points, QPointF p1
return AngleByLength(points, p2, bigLine1, sp2, bigLine2, p, width); return AngleByLength(points, p2, bigLine1, sp2, bigLine2, p, width);
} }
pointsIntr.append(px); pointsIntr.append(px);
if (needRollback != nullptr && rollbackFlag)
{
*needRollback = 1;
}
} }
else else
{ {
@ -445,11 +397,6 @@ QVector<QPointF> AngleByFirstSymmetry(const QVector<QPointF> &points, QPointF p1
allowance.setAngle(allowance.angle() + 90); allowance.setAngle(allowance.angle() + 90);
pointsIntr.append(allowance.p2()); pointsIntr.append(allowance.p2());
pointsIntr.append(bigLine2.p1()); pointsIntr.append(bigLine2.p1());
if (needRollback != nullptr && rollbackFlag)
{
*needRollback = 2;
}
} }
return pointsIntr; return pointsIntr;
@ -458,11 +405,11 @@ QVector<QPointF> AngleByFirstSymmetry(const QVector<QPointF> &points, QPointF p1
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> AngleBySecondSymmetry(const QVector<QPointF> &points, QPointF p2, QPointF p3, QVector<QPointF> AngleBySecondSymmetry(const QVector<QPointF> &points, QPointF p2, QPointF p3,
const QLineF &bigLine1, QPointF sp2, const QLineF &bigLine2, const QLineF &bigLine1, QPointF sp2, const QLineF &bigLine2,
const VSAPoint &p, qreal width, int *needRollback = nullptr) const VSAPoint &p, qreal width, bool *needRollback = nullptr)
{ {
if (needRollback != nullptr) if (needRollback != nullptr)
{ {
*needRollback = -1; *needRollback = false;
} }
const qreal localWidth = p.MaxLocalSA(width); const qreal localWidth = p.MaxLocalSA(width);
@ -489,8 +436,13 @@ QVector<QPointF> AngleBySecondSymmetry(const QVector<QPointF> &points, QPointF p
else else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points {// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false; bool success = false;
pointsIntr = RollbackSeamAllowance(pointsIntr, bigLine2, &success); pointsIntr = VAbstractPiece::RollbackSeamAllowance(pointsIntr, bigLine2, &success);
rollbackFlag = true; rollbackFlag = true;
if (needRollback != nullptr)
{
*needRollback = true;
}
} }
type = sEdge.intersect(bigLine2, &px); type = sEdge.intersect(bigLine2, &px);
@ -510,11 +462,6 @@ QVector<QPointF> AngleBySecondSymmetry(const QVector<QPointF> &points, QPointF p
{ {
pointsIntr.append(px); pointsIntr.append(px);
} }
if (needRollback != nullptr && rollbackFlag)
{
*needRollback = 0;
}
} }
else else
{ {
@ -524,11 +471,6 @@ QVector<QPointF> AngleBySecondSymmetry(const QVector<QPointF> &points, QPointF p
allowance.setLength(allowance.length() + localWidth * 3.); allowance.setLength(allowance.length() + localWidth * 3.);
pointsIntr.append(allowance.p2()); pointsIntr.append(allowance.p2());
pointsIntr.append(bigLine2.p2()); pointsIntr.append(bigLine2.p2());
if (needRollback != nullptr && rollbackFlag)
{
*needRollback = 3;
}
} }
return pointsIntr; return pointsIntr;
@ -583,11 +525,11 @@ QVector<QPointF> AngleByFirstRightAngle(const QVector<QPointF> &points, QPointF
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> AngleBySecondRightAngle(QVector<QPointF> points, QPointF p2, QPointF p3, QVector<QPointF> AngleBySecondRightAngle(QVector<QPointF> points, QPointF p2, QPointF p3,
const QLineF &bigLine1, QPointF sp2, const QLineF &bigLine2, const QLineF &bigLine1, QPointF sp2, const QLineF &bigLine2,
const VSAPoint &p, qreal width, int *needRollback = nullptr) const VSAPoint &p, qreal width, bool *needRollback = nullptr)
{ {
if (needRollback != nullptr) if (needRollback != nullptr)
{ {
*needRollback = -1; *needRollback = false;
} }
const qreal localWidth = p.MaxLocalSA(width); const qreal localWidth = p.MaxLocalSA(width);
@ -618,7 +560,7 @@ QVector<QPointF> AngleBySecondRightAngle(QVector<QPointF> points, QPointF p2, QP
// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points // Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false; bool success = false;
const int countBefore = points.size(); const int countBefore = points.size();
points = RollbackSeamAllowance(points, edge, &success); points = VAbstractPiece::RollbackSeamAllowance(points, edge, &success);
if (success) if (success)
{ {
@ -636,7 +578,7 @@ QVector<QPointF> AngleBySecondRightAngle(QVector<QPointF> points, QPointF p2, QP
{ {
if (needRollback != nullptr) if (needRollback != nullptr)
{ {
*needRollback = 0; *needRollback = true;
} }
} }
} }
@ -972,7 +914,7 @@ QVector<QPointF> VAbstractPiece::Equidistant(QVector<VSAPoint> points, qreal wid
points.append(points.at(0));// Should be always closed points.append(points.at(0));// Should be always closed
} }
int needRollback = -1; // no need for rollback bool needRollback = false; // no need for rollback
QVector<QPointF> ekvPoints; QVector<QPointF> ekvPoints;
for (qint32 i = 0; i < points.size(); ++i ) for (qint32 i = 0; i < points.size(); ++i )
{ {
@ -995,25 +937,23 @@ QVector<QPointF> VAbstractPiece::Equidistant(QVector<VSAPoint> points, qreal wid
ekvPoints = EkvPoint(ekvPoints, points.at(i-1), points.at(i), points.at(i+1), points.at(i), width); ekvPoints = EkvPoint(ekvPoints, points.at(i-1), points.at(i), points.at(i+1), points.at(i), width);
} }
if (needRollback != -1) if (needRollback)
{ {
auto Rollback = [&ekvPoints, needRollback](const QLineF &edge) auto Rollback = [&ekvPoints](const QLineF &edge)
{ {
if (not ekvPoints.isEmpty()) if (not ekvPoints.isEmpty())
{ {
ekvPoints.removeLast(); ekvPoints.removeLast();
QVector<QPointF> head = ekvPoints.mid(0, needRollback);
ekvPoints.remove(0, needRollback);
bool success = false; bool success = false;
ekvPoints = RollbackSeamAllowance(ekvPoints, edge, &success); ekvPoints = RollbackSeamAllowance(ekvPoints, edge, &success);
ekvPoints = head + ekvPoints;
if (not ekvPoints.isEmpty()) if (not ekvPoints.isEmpty())
{ {
ekvPoints.append(ekvPoints.first()); if (ekvPoints.last().toPoint() != ekvPoints.first().toPoint())
{
ekvPoints.append(ekvPoints.first());// Should be always closed
}
} }
} }
}; };
@ -1262,7 +1202,7 @@ QVector<QPointF> VAbstractPiece::CheckLoops(const QVector<QPointF> &points)
* @return seam aloowance points. * @return seam aloowance points.
*/ */
QVector<QPointF> VAbstractPiece::EkvPoint(QVector<QPointF> points, const VSAPoint &p1Line1, VSAPoint p2Line1, QVector<QPointF> VAbstractPiece::EkvPoint(QVector<QPointF> points, const VSAPoint &p1Line1, VSAPoint p2Line1,
const VSAPoint &p1Line2, VSAPoint p2Line2, qreal width, int *needRollback) const VSAPoint &p1Line2, VSAPoint p2Line2, qreal width, bool *needRollback)
{ {
if (width < 0) if (width < 0)
{ // width can't be < 0 { // width can't be < 0
@ -1543,3 +1483,54 @@ qreal VSAPoint::MaxLocalSA(qreal width) const
return qMax(w1, w2); return qMax(w1, w2);
} }
//---------------------------------------------------------------------------------------------------------------------
qreal VSAPoint::PassmarkLength(qreal width) const
{
qreal passmarkLength = MaxLocalSA(width) * passmarkFactor;
passmarkLength = qMin(passmarkLength, maxPassmarkLength);
return passmarkLength;
}
//---------------------------------------------------------------------------------------------------------------------
// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
QVector<QPointF> VAbstractPiece::RollbackSeamAllowance(QVector<QPointF> points, const QLineF &cuttingEdge,
bool *success)
{
*success = false;
QVector<QPointF> clipped;
clipped.reserve(points.count()+1);
for (int i = points.count()-1; i > 0; --i)
{
QLineF segment(points.at(i), points.at(i-1));
QPointF crosPoint;
const QLineF::IntersectType type = cuttingEdge.intersect(segment, &crosPoint);
if (type != QLineF::NoIntersection
&& VGObject::IsPointOnLineSegment(crosPoint, segment.p1(), segment.p2())
&& IsOutsidePoint(cuttingEdge.p2(), cuttingEdge.p1(), crosPoint))
{
clipped.append(crosPoint);
for (int j=i-1; j>=0; --j)
{
clipped.append(points.at(j));
}
points = VGObject::GetReversePoints(clipped);
*success = true;
break;
}
}
if (not *success && points.size() > 1)
{
QPointF crosPoint;
QLineF secondLast(points.at(points.size()-2), points.at(points.size()-1));
QLineF::IntersectType type = secondLast.intersect(cuttingEdge, &crosPoint);
if (type != QLineF::NoIntersection && IsOutsidePoint(secondLast.p1(), secondLast.p2(), crosPoint))
{
points.append(crosPoint);
*success = true;
}
}
return points;
}

View File

@ -69,6 +69,10 @@ public:
void SetAngleType(PieceNodeAngle value); void SetAngleType(PieceNodeAngle value);
qreal MaxLocalSA(qreal width) const; qreal MaxLocalSA(qreal width) const;
qreal PassmarkLength(qreal width) const;
static const qreal passmarkFactor;
static const qreal maxPassmarkLength;
private: private:
qreal m_before; qreal m_before;
@ -188,7 +192,7 @@ public:
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points); static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
static QVector<QPointF> EkvPoint(QVector<QPointF> points, const VSAPoint &p1Line1, VSAPoint p2Line1, static QVector<QPointF> EkvPoint(QVector<QPointF> points, const VSAPoint &p1Line1, VSAPoint p2Line1,
const VSAPoint &p1Line2, VSAPoint p2Line2, qreal width, const VSAPoint &p1Line2, VSAPoint p2Line2, qreal width,
int *needRollback = nullptr); bool *needRollback = nullptr);
static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width); static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width);
template <class T> template <class T>
@ -197,6 +201,8 @@ public:
template <class T> template <class T>
static QVector<T> CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast = true); static QVector<T> CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast = true);
static QVector<QPointF> RollbackSeamAllowance(QVector<QPointF> points, const QLineF &cuttingEdge, bool *success);
protected: protected:
template <class T> template <class T>
static QVector<T> RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true); static QVector<T> RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true);
@ -204,7 +210,6 @@ protected:
static bool IsEkvPointOnLine(const VSAPoint &iPoint, const VSAPoint &prevPoint, const VSAPoint &nextPoint); static bool IsEkvPointOnLine(const VSAPoint &iPoint, const VSAPoint &prevPoint, const VSAPoint &nextPoint);
static QPainterPath PlaceLabelImgPath(const PlaceLabelImg &img); static QPainterPath PlaceLabelImgPath(const PlaceLabelImg &img);
private: private:
QSharedDataPointer<VAbstractPieceData> d; QSharedDataPointer<VAbstractPieceData> d;
}; };

View File

@ -398,8 +398,7 @@ VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern
QFuture<QVector<QPointF> > futureSeamAllowance = QtConcurrent::run(piece, &VPiece::SeamAllowancePoints, pattern); QFuture<QVector<QPointF> > futureSeamAllowance = QtConcurrent::run(piece, &VPiece::SeamAllowancePoints, pattern);
QFuture<QVector<QPointF> > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern); QFuture<QVector<QPointF> > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern);
QFuture<QVector<VLayoutPiecePath> > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern); QFuture<QVector<VLayoutPiecePath> > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern);
QFuture<QVector<QLineF> > futurePassmarksLines = QtConcurrent::run(piece, &VPiece::PassmarksLines, pattern, QFuture<QVector<QLineF> > futurePassmarksLines = QtConcurrent::run(piece, &VPiece::PassmarksLines, pattern);
QVector<QPointF>());
QFuture<QVector<VLayoutPlaceLabel> > futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern); QFuture<QVector<VLayoutPlaceLabel> > futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern);
VLayoutPiece det; VLayoutPiece det;

View File

@ -39,9 +39,6 @@
#include <QDebug> #include <QDebug>
#include <QPainterPath> #include <QPainterPath>
const qreal passmarkFactor = 0.5;
const qreal maxPassmarkLength = (10/*mm*/ / 25.4) * PrintDPI;
namespace namespace
{ {
QVector<quint32> PieceMissingNodes(const QVector<quint32> &d1Nodes, const QVector<quint32> &d2Nodes) QVector<quint32> PieceMissingNodes(const QVector<quint32> &d1Nodes, const QVector<quint32> &d2Nodes)
@ -319,7 +316,18 @@ bool FixNotchPoint(const QVector<QPointF> &seamAllowance, const QPointF &notchBa
return fixed; return fixed;
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<VPieceNode> RotatePath(const QVector<VPieceNode> &path, int index)
{
if (index < 0 || index >= path.size())
{
return path;
}
return path.mid(index) + path.mid(0, index);
} }
} // anonymous namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPiece::VPiece() VPiece::VPiece()
@ -382,88 +390,7 @@ QVector<VPointF> VPiece::MainPathNodePoints(const VContainer *data, bool showExc
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
{ {
SCASSERT(data != nullptr); return SeamAllowancePointsWithRotation(data, -1);
if (not IsSeamAllowance() || IsSeamAllowanceBuiltIn())
{
return QVector<QPointF>();
}
const QVector<CustomSARecord> records = FilterRecords(GetValidRecords());
int recordIndex = -1;
bool insertingCSA = false;
const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit());
const QVector<VPieceNode> unitedPath = GetUnitedPath(data);
QVector<VSAPoint> pointsEkv;
for (int i = 0; i< unitedPath.size(); ++i)
{
const VPieceNode &node = unitedPath.at(i);
if (node.IsExcluded())
{
continue;// skip excluded node
}
switch (node.GetTypeTool())
{
case (Tool::NodePoint):
{
if (not insertingCSA)
{
pointsEkv.append(VPiecePath::PreparePointEkv(node, data));
recordIndex = IsCSAStart(records, node.GetId());
if (recordIndex != -1 && records.at(recordIndex).includeType == PiecePathIncludeType::AsCustomSA)
{
insertingCSA = true;
const VPiecePath path = data->GetPiecePath(records.at(recordIndex).path);
QVector<VSAPoint> r = path.SeamAllowancePoints(data, width, records.at(recordIndex).reverse);
for (int j = 0; j < r.size(); ++j)
{
r[j].SetAngleType(PieceNodeAngle::ByLengthCurve);
r[j].SetSABefore(0);
r[j].SetSAAfter(0);
}
pointsEkv += r;
}
}
else
{
if (records.at(recordIndex).endPoint == node.GetId())
{
insertingCSA = false;
recordIndex = -1;
pointsEkv.append(VPiecePath::PreparePointEkv(node, data));
}
}
}
break;
case (Tool::NodeArc):
case (Tool::NodeElArc):
case (Tool::NodeSpline):
case (Tool::NodeSplinePath):
{
if (not insertingCSA)
{
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId());
pointsEkv += VPiecePath::CurveSeamAllowanceSegment(data, unitedPath, curve, i, node.GetReverse(),
width);
}
}
break;
default:
qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(node.GetTypeTool());
break;
}
}
return Equidistant(pointsEkv, width);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -480,7 +407,7 @@ QVector<QPointF> VPiece::CuttingPathPoints(const VContainer *data) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPiece::PassmarksLines(const VContainer *data, const QVector<QPointF> &seamAllowance) const QVector<QLineF> VPiece::PassmarksLines(const VContainer *data) const
{ {
const QVector<VPieceNode> unitedPath = GetUnitedPath(data); const QVector<VPieceNode> unitedPath = GetUnitedPath(data);
if (not IsSeamAllowance() || not IsPassmarksPossible(unitedPath)) if (not IsSeamAllowance() || not IsPassmarksPossible(unitedPath))
@ -490,10 +417,6 @@ QVector<QLineF> VPiece::PassmarksLines(const VContainer *data, const QVector<QPo
QVector<QLineF> passmarks; QVector<QLineF> passmarks;
QVector<QPointF> seamPoints;
seamAllowance.isEmpty() && not IsSeamAllowanceBuiltIn() ? seamPoints = SeamAllowancePoints(data) :
seamPoints = seamAllowance;
for (int i = 0; i< unitedPath.size(); ++i) for (int i = 0; i< unitedPath.size(); ++i)
{ {
const VPieceNode &node = unitedPath.at(i); const VPieceNode &node = unitedPath.at(i);
@ -505,7 +428,7 @@ QVector<QLineF> VPiece::PassmarksLines(const VContainer *data, const QVector<QPo
const int previousIndex = VPiecePath::FindInLoopNotExcludedUp(i, unitedPath); const int previousIndex = VPiecePath::FindInLoopNotExcludedUp(i, unitedPath);
const int nextIndex = VPiecePath::FindInLoopNotExcludedDown(i, unitedPath); const int nextIndex = VPiecePath::FindInLoopNotExcludedDown(i, unitedPath);
passmarks += CreatePassmark(unitedPath, previousIndex, i, nextIndex, data, seamPoints); passmarks += CreatePassmark(unitedPath, previousIndex, i, nextIndex, data);
} }
return passmarks; return passmarks;
@ -594,9 +517,9 @@ QPainterPath VPiece::SeamAllowancePath(const QVector<QPointF> &points) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VPiece::PassmarksPath(const VContainer *data, const QVector<QPointF> &seamAllowance) const QPainterPath VPiece::PassmarksPath(const VContainer *data) const
{ {
const QVector<QLineF> passmarks = PassmarksLines(data, seamAllowance); const QVector<QLineF> passmarks = PassmarksLines(data);
QPainterPath path; QPainterPath path;
// seam allowence // seam allowence
@ -902,6 +825,93 @@ const VGrainlineData &VPiece::GetGrainlineGeometry() const
return d->m_glGrainline; return d->m_glGrainline;
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::SeamAllowancePointsWithRotation(const VContainer *data, int makeFirst) const
{
SCASSERT(data != nullptr);
if (not IsSeamAllowance() || IsSeamAllowanceBuiltIn())
{
return QVector<QPointF>();
}
const QVector<CustomSARecord> records = FilterRecords(GetValidRecords());
int recordIndex = -1;
bool insertingCSA = false;
const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit());
const QVector<VPieceNode> unitedPath = makeFirst > 0 ? RotatePath(GetUnitedPath(data), makeFirst)
: GetUnitedPath(data);
QVector<VSAPoint> pointsEkv;
for (int i = 0; i< unitedPath.size(); ++i)
{
const VPieceNode &node = unitedPath.at(i);
if (node.IsExcluded())
{
continue;// skip excluded node
}
switch (node.GetTypeTool())
{
case (Tool::NodePoint):
{
if (not insertingCSA)
{
pointsEkv.append(VPiecePath::PreparePointEkv(node, data));
recordIndex = IsCSAStart(records, node.GetId());
if (recordIndex != -1 && records.at(recordIndex).includeType == PiecePathIncludeType::AsCustomSA)
{
insertingCSA = true;
const VPiecePath path = data->GetPiecePath(records.at(recordIndex).path);
QVector<VSAPoint> r = path.SeamAllowancePoints(data, width, records.at(recordIndex).reverse);
for (int j = 0; j < r.size(); ++j)
{
r[j].SetAngleType(PieceNodeAngle::ByLengthCurve);
r[j].SetSABefore(0);
r[j].SetSAAfter(0);
}
pointsEkv += r;
}
}
else
{
if (records.at(recordIndex).endPoint == node.GetId())
{
insertingCSA = false;
recordIndex = -1;
pointsEkv.append(VPiecePath::PreparePointEkv(node, data));
}
}
}
break;
case (Tool::NodeArc):
case (Tool::NodeElArc):
case (Tool::NodeSpline):
case (Tool::NodeSplinePath):
{
if (not insertingCSA)
{
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId());
pointsEkv += VPiecePath::CurveSeamAllowanceSegment(data, unitedPath, curve, i, node.GetReverse(),
width);
}
}
break;
default:
qDebug()<<"Get wrong tool type. Ignore."<< static_cast<char>(node.GetTypeTool());
break;
}
}
return Equidistant(pointsEkv, width);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<VPieceNode> VPiece::GetUnitedPath(const VContainer *data) const QVector<VPieceNode> VPiece::GetUnitedPath(const VContainer *data) const
{ {
@ -1117,7 +1127,7 @@ bool VPiece::GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int in
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
int VPiece::GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint, bool VPiece::GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, VSAPoint &point, int passmarkIndex) const const VContainer *data, VSAPoint &point, int passmarkIndex) const
{ {
SCASSERT(data != nullptr) SCASSERT(data != nullptr)
@ -1155,26 +1165,33 @@ int VPiece::GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index,
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VPiece::GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, VSAPoint passmarkSAPoint, PassmarkStatus VPiece::GetSeamPassmarkSAPoint(VPiecePassmarkData passmarkData, const QVector<QPointF> &seamAllowance,
const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const QPointF &point)
{ {
SCASSERT(data != nullptr)
// Correct distorsion // Correct distorsion
if (VGObject::IsPointOnLineSegment(passmarkSAPoint, previousSAPoint, nextSAPoint)) if (VGObject::IsPointOnLineSegment(passmarkData.passmarkSAPoint, passmarkData.previousSAPoint,
passmarkData.nextSAPoint))
{ {
const QPointF p = VGObject::CorrectDistortion(passmarkSAPoint, previousSAPoint, nextSAPoint); const QPointF p = VGObject::CorrectDistortion(passmarkData.passmarkSAPoint, passmarkData.previousSAPoint,
passmarkSAPoint.setX(p.x()); passmarkData.nextSAPoint);
passmarkSAPoint.setY(p.y()); passmarkData.passmarkSAPoint.setX(p.x());
passmarkData.passmarkSAPoint.setY(p.y());
} }
bool needRollback = false; // no need for rollback
QVector<QPointF> ekvPoints; QVector<QPointF> ekvPoints;
ekvPoints = EkvPoint(ekvPoints, previousSAPoint, passmarkSAPoint, nextSAPoint, passmarkSAPoint, ekvPoints = EkvPoint(ekvPoints, passmarkData.previousSAPoint, passmarkData.passmarkSAPoint,
ToPixel(GetSAWidth(), *data->GetPatternUnit())); passmarkData.nextSAPoint, passmarkData.passmarkSAPoint, passmarkData.saWidth, &needRollback);
if (needRollback && not seamAllowance.isEmpty())
{
ekvPoints.clear();
ekvPoints += seamAllowance.at(seamAllowance.size()-2);
}
if (ekvPoints.isEmpty()) if (ekvPoints.isEmpty())
{ // Just in case { // Just in case
return false; // Something wrong return PassmarkStatus::Error; // Something wrong
} }
if (ekvPoints.size() == 1 || ekvPoints.size() > 2) if (ekvPoints.size() == 1 || ekvPoints.size() > 2)
@ -1183,11 +1200,19 @@ bool VPiece::GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, VSAPoint pa
} }
else if (ekvPoints.size() == 2) else if (ekvPoints.size() == 2)
{ {
QLineF line = QLineF(ekvPoints.at(0), ekvPoints.at(1)); if(passmarkData.passmarkSAPoint.GetAngleType() == PieceNodeAngle::ByFirstEdgeSymmetry ||
line.setLength(line.length()/2.); passmarkData.passmarkSAPoint.GetAngleType() == PieceNodeAngle::ByFirstEdgeRightAngle)
point = line.p2(); {
point = ekvPoints.first();
}
else
{
QLineF line = QLineF(ekvPoints.at(0), ekvPoints.at(1));
line.setLength(line.length()/2.);
point = line.p2();
}
} }
return true; return needRollback ? PassmarkStatus::Rollback : PassmarkStatus::Common;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1232,8 +1257,7 @@ bool VPiece::IsPassmarkVisible(const QVector<VPieceNode> &path, int passmarkInde
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPiece::CreatePassmark(const QVector<VPieceNode> &path, int previousIndex, int passmarkIndex, QVector<QLineF> VPiece::CreatePassmark(const QVector<VPieceNode> &path, int previousIndex, int passmarkIndex,
int nextIndex, const VContainer *data, int nextIndex, const VContainer *data) const
const QVector<QPointF> &seamAllowance) const
{ {
SCASSERT(data != nullptr); SCASSERT(data != nullptr);
@ -1265,10 +1289,23 @@ QVector<QLineF> VPiece::CreatePassmark(const QVector<VPieceNode> &path, int prev
return QVector<QLineF>(); // Something wrong return QVector<QLineF>(); // Something wrong
} }
VPiecePassmarkData passmarkData;
passmarkData.previousSAPoint = previousSAPoint;
passmarkData.passmarkSAPoint = passmarkSAPoint;
passmarkData.nextSAPoint = nextSAPoint;
passmarkData.saWidth = ToPixel(GetSAWidth(), *data->GetPatternUnit());
passmarkData.nodeName = VPiecePath::NodeName(path, passmarkIndex, data);
passmarkData.pieceName = GetName();
passmarkData.passmarkLineType = path.at(passmarkIndex).GetPassmarkLineType();
passmarkData.passmarkAngleType = path.at(passmarkIndex).GetPassmarkAngleType();
if (not IsSeamAllowanceBuiltIn()) if (not IsSeamAllowanceBuiltIn())
{ {
// Because rollback cannot be calulated if passmark is not first point in main path we rotate it.
const QVector<QPointF> seamAllowance = SeamAllowancePointsWithRotation(data, passmarkIndex);
QVector<QLineF> lines; QVector<QLineF> lines;
lines += SAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex, seamAllowance); lines += SAPassmark(passmarkData, seamAllowance);
if (qApp->Settings()->IsDoublePassmark() if (qApp->Settings()->IsDoublePassmark()
&& not IsHideMainPath() && not IsHideMainPath()
&& path.at(passmarkIndex).IsMainPathNode() && path.at(passmarkIndex).IsMainPathNode()
@ -1280,129 +1317,129 @@ QVector<QLineF> VPiece::CreatePassmark(const QVector<VPieceNode> &path, int prev
&& path.at(passmarkIndex).GetPassmarkAngleType() != PassmarkAngleType::Intersection2OnlyRight && path.at(passmarkIndex).GetPassmarkAngleType() != PassmarkAngleType::Intersection2OnlyRight
&& path.at(passmarkIndex).IsShowSecondPassmark()) && path.at(passmarkIndex).IsShowSecondPassmark())
{ {
lines += BuiltInSAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex); lines += BuiltInSAPassmark(passmarkData);
} }
return lines; return lines;
} }
else
{ return BuiltInSAPassmark(passmarkData);
return BuiltInSAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex);
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, VSAPoint &previousSAPoint, QVector<QLineF> VPiece::SAPassmark(const VPiecePassmarkData &passmarkData, const QVector<QPointF> &seamAllowance)
const VSAPoint &passmarkSAPoint, VSAPoint &nextSAPoint, const VContainer *data,
int passmarkIndex, const QVector<QPointF> &seamAllowance) const
{ {
if (seamAllowance.size() < 2) if (seamAllowance.size() < 2)
{ {
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Seam allowance is " const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Seam allowance is "
"empty.").arg(VPiecePath::NodeName(path, passmarkIndex, data), GetName()); "empty.").arg(passmarkData.nodeName, passmarkData.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
return QVector<QLineF>(); // Something wrong return QVector<QLineF>(); // Something wrong
} }
QPointF seamPassmarkSAPoint; QPointF seamPassmarkSAPoint;
if (not GetSeamPassmarkSAPoint(previousSAPoint, passmarkSAPoint, nextSAPoint, data, seamPassmarkSAPoint)) const PassmarkStatus seamPassmarkType = GetSeamPassmarkSAPoint(passmarkData, seamAllowance, seamPassmarkSAPoint);
if (seamPassmarkType == PassmarkStatus::Error)
{ {
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Cannot find " const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Cannot find "
"position for a notch.") "position for a notch.")
.arg(VPiecePath::NodeName(path, passmarkIndex, data), GetName()); .arg(passmarkData.nodeName, passmarkData.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
return QVector<QLineF>(); // Something wrong return QVector<QLineF>(); // Something wrong
} }
if (not FixNotchPoint(seamAllowance, passmarkSAPoint, &seamPassmarkSAPoint)) if (not FixNotchPoint(seamAllowance, passmarkData.passmarkSAPoint, &seamPassmarkSAPoint))
{ {
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Unable to fix a " const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Unable to fix a "
"notch position.") "notch position.")
.arg(VPiecePath::NodeName(path, passmarkIndex, data), GetName()); .arg(passmarkData.nodeName, passmarkData.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
} }
const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit());
QVector<QLineF> passmarksLines; QVector<QLineF> passmarksLines;
qreal passmarkLength = passmarkSAPoint.MaxLocalSA(width) * passmarkFactor; auto PassmarkIntersection = [&passmarksLines, passmarkData, seamAllowance]
passmarkLength = qMin(passmarkLength, maxPassmarkLength); (QLineF line, qreal width)
const VPieceNode &node = path.at(passmarkIndex);
auto PassmarkIntersection = [&passmarksLines, passmarkSAPoint, node](QLineF line,
const QVector<QPointF> &seamPoints, qreal width)
{ {
line.setLength(line.length()*100); // Hope 100 is enough line.setLength(line.length()*100); // Hope 100 is enough
const QVector<QPointF> intersections = VAbstractCurve::CurveIntersectLine(seamPoints, line); const QVector<QPointF> intersections = VAbstractCurve::CurveIntersectLine(seamAllowance, line);
if (not intersections.isEmpty()) if (not intersections.isEmpty())
{ {
line = QLineF(intersections.last(), passmarkSAPoint); if (intersections.last() != passmarkData.passmarkSAPoint)
line.setLength(qMin(width * passmarkFactor, maxPassmarkLength)); {
line = QLineF(intersections.last(), passmarkData.passmarkSAPoint);
line.setLength(qMin(width * VSAPoint::passmarkFactor, VSAPoint::maxPassmarkLength));
passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line); passmarksLines += CreatePassmarkLines(passmarkData.passmarkLineType, passmarkData.passmarkAngleType,
line);
}
else
{
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Notch "
"collapse.")
.arg(passmarkData.nodeName, passmarkData.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
}
}
else
{
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Cannot find "
"intersection.")
.arg(passmarkData.nodeName, passmarkData.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
} }
}; };
if (node.GetPassmarkAngleType() == PassmarkAngleType::Straightforward) if (passmarkData.passmarkAngleType == PassmarkAngleType::Straightforward)
{ {
QLineF line = QLineF(seamPassmarkSAPoint, passmarkSAPoint); QLineF line = QLineF(seamPassmarkSAPoint, passmarkData.passmarkSAPoint);
line.setLength(passmarkLength); line.setLength(passmarkData.passmarkSAPoint.PassmarkLength(passmarkData.saWidth));
passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line); passmarksLines += CreatePassmarkLines(passmarkData.passmarkLineType, passmarkData.passmarkAngleType, line);
} }
else if (node.GetPassmarkAngleType() == PassmarkAngleType::Bisector) else if (passmarkData.passmarkAngleType == PassmarkAngleType::Bisector)
{ {
const QLineF bigLine1 = ParallelLine(previousSAPoint, passmarkSAPoint, width ); passmarksLines += PassmarkBisector(seamPassmarkType, passmarkData, seamPassmarkSAPoint, seamAllowance);
const QLineF bigLine2 = ParallelLine(passmarkSAPoint, nextSAPoint, width );
QLineF edge1 = QLineF(seamPassmarkSAPoint, bigLine1.p1());
QLineF edge2 = QLineF(seamPassmarkSAPoint, bigLine2.p2());
edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.);
edge1.setLength(passmarkLength);
passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), edge1);
} }
else if (node.GetPassmarkAngleType() == PassmarkAngleType::Intersection else if (passmarkData.passmarkAngleType == PassmarkAngleType::Intersection
|| node.GetPassmarkAngleType() == PassmarkAngleType::IntersectionOnlyLeft || passmarkData.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft
|| node.GetPassmarkAngleType() == PassmarkAngleType::IntersectionOnlyRight) || passmarkData.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight)
{ {
if (node.GetPassmarkAngleType() == PassmarkAngleType::Intersection if (passmarkData.passmarkAngleType == PassmarkAngleType::Intersection
|| node.GetPassmarkAngleType() == PassmarkAngleType::IntersectionOnlyRight) || passmarkData.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight)
{ {
// first passmark // first passmark
PassmarkIntersection(QLineF(previousSAPoint, passmarkSAPoint), seamAllowance, PassmarkIntersection(QLineF(passmarkData.previousSAPoint, passmarkData.passmarkSAPoint),
passmarkSAPoint.GetSAAfter(width)); passmarkData.passmarkSAPoint.GetSAAfter(passmarkData.saWidth));
} }
if (node.GetPassmarkAngleType() == PassmarkAngleType::Intersection if (passmarkData.passmarkAngleType == PassmarkAngleType::Intersection
|| node.GetPassmarkAngleType() == PassmarkAngleType::IntersectionOnlyLeft) || passmarkData.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft)
{ {
// second passmark // second passmark
PassmarkIntersection(QLineF(nextSAPoint, passmarkSAPoint), seamAllowance, PassmarkIntersection(QLineF(passmarkData.nextSAPoint, passmarkData.passmarkSAPoint),
passmarkSAPoint.GetSABefore(width)); passmarkData.passmarkSAPoint.GetSABefore(passmarkData.saWidth));
} }
} }
else if (node.GetPassmarkAngleType() == PassmarkAngleType::Intersection2 else if (passmarkData.passmarkAngleType == PassmarkAngleType::Intersection2
|| node.GetPassmarkAngleType() == PassmarkAngleType::Intersection2OnlyLeft || passmarkData.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft
|| node.GetPassmarkAngleType() == PassmarkAngleType::Intersection2OnlyRight) || passmarkData.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight)
{ {
if (node.GetPassmarkAngleType() == PassmarkAngleType::Intersection2 if (passmarkData.passmarkAngleType == PassmarkAngleType::Intersection2
|| node.GetPassmarkAngleType() == PassmarkAngleType::Intersection2OnlyRight) || passmarkData.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight)
{ {
// first passmark // first passmark
QLineF line(passmarkSAPoint, nextSAPoint); QLineF line(passmarkData.passmarkSAPoint, passmarkData.nextSAPoint);
line.setAngle(line.angle()+90); line.setAngle(line.angle()+90);
PassmarkIntersection(line, seamAllowance, passmarkSAPoint.GetSAAfter(width)); PassmarkIntersection(line, passmarkData.passmarkSAPoint.GetSAAfter(passmarkData.saWidth));
} }
if (node.GetPassmarkAngleType() == PassmarkAngleType::Intersection2 if (passmarkData.passmarkAngleType == PassmarkAngleType::Intersection2
|| node.GetPassmarkAngleType() == PassmarkAngleType::Intersection2OnlyLeft) || passmarkData.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft)
{ {
// second passmark // second passmark
QLineF line(passmarkSAPoint, previousSAPoint); QLineF line(passmarkData.passmarkSAPoint, passmarkData.previousSAPoint);
line.setAngle(line.angle()-90); line.setAngle(line.angle()-90);
PassmarkIntersection(line, seamAllowance, passmarkSAPoint.GetSABefore(width)); PassmarkIntersection(line, passmarkData.passmarkSAPoint.GetSABefore(passmarkData.saWidth));
} }
} }
@ -1410,24 +1447,17 @@ QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, VSAPoint &pr
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPiece::BuiltInSAPassmark(const QVector<VPieceNode> &path, const VSAPoint &previousSAPoint, QVector<QLineF> VPiece::BuiltInSAPassmark(const VPiecePassmarkData &passmarkData)
const VSAPoint &passmarkSAPoint, const VSAPoint &nextSAPoint,
const VContainer *data, int passmarkIndex) const
{ {
QVector<QLineF> passmarksLines; QVector<QLineF> passmarksLines;
const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit()); QLineF edge1 = QLineF(passmarkData.passmarkSAPoint, passmarkData.previousSAPoint);
qreal passmarkLength = passmarkSAPoint.MaxLocalSA(width) * passmarkFactor; QLineF edge2 = QLineF(passmarkData.passmarkSAPoint, passmarkData.nextSAPoint);
passmarkLength = qMin(passmarkLength, maxPassmarkLength);
QLineF edge1 = QLineF(passmarkSAPoint, previousSAPoint);
QLineF edge2 = QLineF(passmarkSAPoint, nextSAPoint);
edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.); edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.);
edge1.setLength(passmarkLength); edge1.setLength(passmarkData.passmarkSAPoint.PassmarkLength(passmarkData.saWidth));
const VPieceNode &node = path.at(passmarkIndex); passmarksLines += CreatePassmarkLines(passmarkData.passmarkLineType, passmarkData.passmarkAngleType, edge1);
passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), edge1);
return passmarksLines; return passmarksLines;
} }
@ -1445,3 +1475,44 @@ int VPiece::IsCSAStart(const QVector<CustomSARecord> &records, quint32 id)
return -1; return -1;
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPiece::PassmarkBisector(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData,
const QPointF &seamPassmarkSAPoint, const QVector<QPointF> &seamAllowance)
{
QLineF edge1;
QLineF edge2;
if (seamPassmarkType == PassmarkStatus::Common)
{
if (passmarkData.passmarkSAPoint.GetAngleType() == PieceNodeAngle::ByFirstEdgeSymmetry)
{
edge1 = QLineF(seamPassmarkSAPoint, seamAllowance.at(seamAllowance.size() - 2));
edge2 = QLineF(seamPassmarkSAPoint, seamAllowance.at(1));
}
else
{
const QLineF bigLine1 = ParallelLine(passmarkData.previousSAPoint, passmarkData.passmarkSAPoint,
passmarkData.saWidth );
const QLineF bigLine2 = ParallelLine(passmarkData.passmarkSAPoint, passmarkData.nextSAPoint,
passmarkData.saWidth );
edge1 = QLineF(seamPassmarkSAPoint, bigLine1.p1());
edge2 = QLineF(seamPassmarkSAPoint, bigLine2.p2());
}
}
else if(seamPassmarkType == PassmarkStatus::Rollback)
{
edge1 = QLineF(seamPassmarkSAPoint, seamAllowance.at(seamAllowance.size() - 3));
edge2 = QLineF(seamPassmarkSAPoint, seamAllowance.at(0));
}
else
{ // Should never happen
return QVector<QLineF>();
}
edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.);
edge1.setLength(passmarkData.passmarkSAPoint.PassmarkLength(passmarkData.saWidth));
return CreatePassmarkLines(passmarkData.passmarkLineType, passmarkData.passmarkAngleType, edge1);
}

View File

@ -47,6 +47,33 @@ class VContainer;
class QPainterPath; class QPainterPath;
class VPointF; class VPointF;
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++")
enum class PassmarkStatus: char
{
Error = 0,
Common = 1,
Rollback = -1
};
struct VPiecePassmarkData
{
VSAPoint previousSAPoint;
VSAPoint passmarkSAPoint;
VSAPoint nextSAPoint;
qreal saWidth;
QString nodeName;
QString pieceName;
PassmarkLineType passmarkLineType;
PassmarkAngleType passmarkAngleType;
};
Q_DECLARE_METATYPE(VPiecePassmarkData)
Q_DECLARE_TYPEINFO(VPiecePassmarkData, Q_MOVABLE_TYPE);
QT_WARNING_POP
class VPiece : public VAbstractPiece class VPiece : public VAbstractPiece
{ {
public: public:
@ -71,8 +98,7 @@ public:
QVector<VPointF> MainPathNodePoints(const VContainer *data, bool showExcluded = false) const; QVector<VPointF> MainPathNodePoints(const VContainer *data, bool showExcluded = false) const;
QVector<QPointF> SeamAllowancePoints(const VContainer *data) const; QVector<QPointF> SeamAllowancePoints(const VContainer *data) const;
QVector<QPointF> CuttingPathPoints(const VContainer *data) const; QVector<QPointF> CuttingPathPoints(const VContainer *data) const;
QVector<QLineF> PassmarksLines(const VContainer *data, QVector<QLineF> PassmarksLines(const VContainer *data) const;
const QVector<QPointF> &seamAllowance = QVector<QPointF>()) const;
QVector<PlaceLabelImg> PlaceLabelPoints(const VContainer *data) const; QVector<PlaceLabelImg> PlaceLabelPoints(const VContainer *data) const;
QVector<QPainterPath> CurvesPainterPath(const VContainer *data) const; QVector<QPainterPath> CurvesPainterPath(const VContainer *data) const;
@ -82,8 +108,7 @@ public:
QPainterPath SeamAllowancePath(const VContainer *data) const; QPainterPath SeamAllowancePath(const VContainer *data) const;
QPainterPath SeamAllowancePath(const QVector<QPointF> &points) const; QPainterPath SeamAllowancePath(const QVector<QPointF> &points) const;
QPainterPath PassmarksPath(const VContainer *data, QPainterPath PassmarksPath(const VContainer *data) const;
const QVector<QPointF> &seamAllowance = QVector<QPointF>()) const;
QPainterPath PlaceLabelPath(const VContainer *data) const; QPainterPath PlaceLabelPath(const VContainer *data) const;
bool IsInLayout() const; bool IsInLayout() const;
@ -130,6 +155,9 @@ public:
VGrainlineData& GetGrainlineGeometry(); VGrainlineData& GetGrainlineGeometry();
const VGrainlineData& GetGrainlineGeometry() const; const VGrainlineData& GetGrainlineGeometry() const;
static QVector<QLineF> SAPassmark(const VPiecePassmarkData &passmarkData, const QVector<QPointF> &seamAllowance);
protected:
QVector<QPointF> SeamAllowancePointsWithRotation(const VContainer *data, int makeFirst) const;
private: private:
QSharedDataPointer<VPieceData> d; QSharedDataPointer<VPieceData> d;
@ -143,22 +171,19 @@ private:
bool GetPassmarkSAPoint(const QVector<VPieceNode> &path, int index, const VContainer *data, VSAPoint &point) const; bool GetPassmarkSAPoint(const QVector<VPieceNode> &path, int index, const VContainer *data, VSAPoint &point) const;
bool GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint, bool GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, VSAPoint &point, int passmarkIndex) const; const VContainer *data, VSAPoint &point, int passmarkIndex) const;
int GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint, bool GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, VSAPoint &point, int passmarkIndex) const; const VContainer *data, VSAPoint &point, int passmarkIndex) const;
bool GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, VSAPoint passmarkSAPoint, static PassmarkStatus GetSeamPassmarkSAPoint(VPiecePassmarkData passmarkData,
const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const; const QVector<QPointF> &seamAllowance, QPointF &point);
bool IsPassmarkVisible(const QVector<VPieceNode> &path, int passmarkIndex) const; bool IsPassmarkVisible(const QVector<VPieceNode> &path, int passmarkIndex) const;
QVector<QLineF> CreatePassmark(const QVector<VPieceNode> &path, int previousIndex, int passmarkIndex, int nextIndex, QVector<QLineF> CreatePassmark(const QVector<VPieceNode> &path, int previousIndex, int passmarkIndex, int nextIndex,
const VContainer *data, const VContainer *data) const;
const QVector<QPointF> &seamAllowance = QVector<QPointF>()) const;
QVector<QLineF> SAPassmark(const QVector<VPieceNode> &path, VSAPoint &previousSAPoint, static QVector<QLineF> BuiltInSAPassmark(const VPiecePassmarkData &passmarkData);
const VSAPoint &passmarkSAPoint, VSAPoint &nextSAPoint, const VContainer *data, static QVector<QLineF> PassmarkBisector(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData,
int passmarkIndex, const QVector<QPointF> &seamAllowance = QVector<QPointF>()) const; const QPointF &seamPassmarkSAPoint, const QVector<QPointF>& seamAllowance);
QVector<QLineF> BuiltInSAPassmark(const QVector<VPieceNode> &path, const VSAPoint &previousSAPoint,
const VSAPoint &passmarkSAPoint, const VSAPoint &nextSAPoint,
const VContainer *data, int passmarkIndex) const;
static int IsCSAStart(const QVector<CustomSARecord> &records, quint32 id); static int IsCSAStart(const QVector<CustomSARecord> &records, quint32 id);

View File

@ -45,6 +45,7 @@
#include <QStringList> #include <QStringList>
#include <QVector> #include <QVector>
#include <QtGlobal> #include <QtGlobal>
#include <QLineF>
#include "logging.h" #include "logging.h"
#include "vsysexits.h" #include "vsysexits.h"
@ -82,6 +83,35 @@ void AbstractTest::Comparison(const QPointF &result, const QPointF &expected) co
QVERIFY2(VFuzzyComparePoints(result, expected), qUtf8Printable(msg)); QVERIFY2(VFuzzyComparePoints(result, expected), qUtf8Printable(msg));
} }
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::Comparison(const QVector<QLineF> &result, const QVector<QLineF> &expected) const
{
// Begin comparison
QCOMPARE(result.size(), expected.size());// First check if sizes equal
for (int i=0; i < result.size(); i++)
{
const QLineF &line1 = result.at(i);
const QLineF &line2 = expected.at(i);
// Check each point. Don't use comparison float values
QVERIFY2(VFuzzyComparePoints(line1.p1(), line2.p1()) && VFuzzyComparePoints(line1.p2(), line2.p2()),
qUtf8Printable(
QStringLiteral("Index: %1. Got line '(%2;%3):(%4;%5)', Expected line '(%6;%7):(%8;%9)'.")
.arg(i)
.arg(line1.p1().x())
.arg(line1.p1().y())
.arg(line1.p2().x())
.arg(line1.p2().y())
.arg(line2.p1().x())
.arg(line2.p1().y())
.arg(line2.p2().x())
.arg(line2.p2().y())
)
);
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QString AbstractTest::ValentinaPath() const QString AbstractTest::ValentinaPath() const
{ {

View File

@ -64,6 +64,7 @@ public:
protected: protected:
void Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const; void Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const;
void Comparison(const QPointF &result, const QPointF &expected) const; void Comparison(const QPointF &result, const QPointF &expected) const;
void Comparison(const QVector<QLineF> &result, const QVector<QLineF> &expected) const;
QString ValentinaPath() const; QString ValentinaPath() const;
QString TapePath() const; QString TapePath() const;

View File

@ -1366,6 +1366,8 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
QFuture<QPainterPath > futurePath = QtConcurrent::run(detail, QFuture<QPainterPath > futurePath = QtConcurrent::run(detail,
QOverload<const VContainer *>::of(&VPiece::MainPathPath), QOverload<const VContainer *>::of(&VPiece::MainPathPath),
this->getData()); this->getData());
QFuture<QPainterPath > futurePassmarks = QtConcurrent::run(detail, &VPiece::PassmarksPath, this->getData());
QFuture<QVector<QPointF> > futureSeamAllowance; QFuture<QVector<QPointF> > futureSeamAllowance;
if (detail.IsSeamAllowance()) if (detail.IsSeamAllowance())
@ -1397,19 +1399,9 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
m_placeLabels->setPath(detail.PlaceLabelPath(this->getData())); m_placeLabels->setPath(detail.PlaceLabelPath(this->getData()));
QVector<QPointF> seamAllowancePoints;
if (detail.IsSeamAllowance())
{
seamAllowancePoints = futureSeamAllowance.result();
}
QFuture<QPainterPath > futurePassmarks = QtConcurrent::run(detail, &VPiece::PassmarksPath, this->getData(),
seamAllowancePoints);
if (detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn()) if (detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn())
{ {
path.addPath(detail.SeamAllowancePath(seamAllowancePoints)); path.addPath(detail.SeamAllowancePath(futureSeamAllowance.result()));
path.setFillRule(Qt::OddEvenFill); path.setFillRule(Qt::OddEvenFill);
m_seamAllowance->setPath(path); m_seamAllowance->setPath(path);
} }

View File

@ -35,6 +35,463 @@
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include <QtTest> #include <QtTest>
#include "../vpatterndb/vpiece.h"
namespace
{
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> Issue924SeamAllowanceTest1()
{
QVector<QPointF> points;
points += QPointF(-814.714960629921279, -46.738127408018386);
points += QPointF(-778.560274683193597, -50.549491761193529);
points += QPointF(-737.960891197081651, -56.790170478391879);
points += QPointF(-709.273784936183347, -62.545071142283753);
points += QPointF(-681.358329676571884, -69.772421317304676);
points += QPointF(-662.734996979773655, -76.086662659765864);
points += QPointF(-652.000013358218780, -80.530014885308333);
points += QPointF(-647.534742107878174, -82.700492263504771);
points += QPointF(-631.585239468780856, -90.995118061836052);
points += QPointF(-616.328020233970847, -100.594267156991847);
points += QPointF(-594.096383910663576, -115.972155307751649);
points += QPointF(-184.048650148745537, 76.198374399107223);
points += QPointF(-202.588712626694274, 128.531217087733864);
points += QPointF(-214.844352980142077, 166.709615345349164);
points += QPointF(-224.900721916665105, 202.786707734969326);
points += QPointF(-232.934347140993879, 237.080856834901624);
points += QPointF(-239.089037151700012, 269.817045957384835);
points += QPointF(-243.506611386394923, 301.230502874877175);
points += QPointF(-246.324245680472586, 331.565901059170528);
points += QPointF(-247.367542640672326, 354.406709505752815);
points += QPointF(-268.813396242720216, 365.986520876589054);
points += QPointF(-274.509592479190928, 368.544465142904016);
points += QPointF(-280.430827138279028, 370.738996867416517);
points += QPointF(-286.539948778692178, 372.651089393540587);
points += QPointF(-295.760523769485246, 375.070669023642552);
points += QPointF(-309.108660665237892, 377.812272271559323);
points += QPointF(-323.791841306461833, 380.189287868544909);
points += QPointF(-339.746492379944868, 382.263575885265993);
points += QPointF(-356.936262185776172, 384.077045039880318);
points += QPointF(-375.281527662442841, 385.653208859628023);
points += QPointF(-394.678657394273387, 387.006850647147644);
points += QPointF(-414.787606696514558, 388.135795504608552);
points += QPointF(-435.952026976937020, 389.076617984501581);
points += QPointF(-457.785958239726995, 389.818484035948188);
points += QPointF(-480.155299343825106, 390.367355935354340);
points += QPointF(-502.923072127811622, 390.728524359010180);
points += QPointF(-525.950383000425973, 390.906843496429246);
points += QPointF(-549.097086395700558, 390.906868034847378);
points += QPointF(-572.222272868468281, 390.732932110765603);
points += QPointF(-595.184660101380132, 390.389190982770685);
points += QPointF(-617.842942744172888, 389.879635420374768);
points += QPointF(-640.056148626075128, 389.208081776045162);
points += QPointF(-661.684051740050222, 388.378134611085102);
points += QPointF(-682.587707903001387, 387.393111203977753);
points += QPointF(-702.630213610816895, 386.255904969512756);
points += QPointF(-721.913933492959586, 384.952760768153212);
points += QPointF(-739.883081019170959, 383.510162372720174);
points += QPointF(-756.628370632600195, 381.913999891517676);
points += QPointF(-772.055707410166860, 380.156385631636169);
points += QPointF(-786.107417616341536, 378.217868080938274);
points += QPointF(-798.800506212061464, 376.051179682426266);
points += QPointF(-810.181063245406790, 373.562456117723798);
points += QPointF(-814.714960629921279, 372.254255263452592);
points += QPointF(-814.714960629921279, -46.738127408018386);
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> Issue924SeamAllowanceTest2()
{
QVector<QPointF> points;
points += QPointF(-814.714960629921279, 331.313196850393751);
points += QPointF(-814.714960629921279, -46.738127408018386);
points += QPointF(-778.560274683193597, -50.549491761193529);
points += QPointF(-737.960891197081651, -56.790170478391879);
points += QPointF(-709.273784936183347, -62.545071142283753);
points += QPointF(-681.358329676571884, -69.772421317304676);
points += QPointF(-662.734996979773655, -76.086662659765864);
points += QPointF(-652.000013358218780, -80.530014885308333);
points += QPointF(-647.534742107878174, -82.700492263504771);
points += QPointF(-631.585239468780856, -90.995118061836052);
points += QPointF(-616.328020233970847, -100.594267156991847);
points += QPointF(-594.096383910663576, -115.972155307751649);
points += QPointF(-184.048650148745537, 76.198374399107223);
points += QPointF(-202.588712626694274, 128.531217087733864);
points += QPointF(-214.844352980142077, 166.709615345349164);
points += QPointF(-224.900721916665105, 202.786707734969326);
points += QPointF(-232.934347140993879, 237.080856834901624);
points += QPointF(-239.089037151700012, 269.817045957384835);
points += QPointF(-243.506611386394923, 301.230502874877175);
points += QPointF(-246.324245680472586, 331.565901059170528);
points += QPointF(-247.367542640672326, 354.406709505752815);
points += QPointF(-268.813396242720216, 365.986520876589054);
points += QPointF(-274.509592479190928, 368.544465142904016);
points += QPointF(-280.430827138279028, 370.738996867416517);
points += QPointF(-286.539948778692178, 372.651089393540587);
points += QPointF(-295.760523769485246, 375.070669023642552);
points += QPointF(-309.108660665237892, 377.812272271559323);
points += QPointF(-323.791841306461833, 380.189287868544909);
points += QPointF(-339.746492379944868, 382.263575885265993);
points += QPointF(-356.936262185776172, 384.077045039880318);
points += QPointF(-375.281527662442841, 385.653208859628023);
points += QPointF(-394.678657394273387, 387.006850647147644);
points += QPointF(-414.787606696514558, 388.135795504608552);
points += QPointF(-435.952026976937020, 389.076617984501581);
points += QPointF(-457.785958239726995, 389.818484035948188);
points += QPointF(-480.155299343825106, 390.367355935354340);
points += QPointF(-502.923072127811622, 390.728524359010180);
points += QPointF(-525.950383000425973, 390.906843496429246);
points += QPointF(-549.097086395700558, 390.906868034847378);
points += QPointF(-572.222272868468281, 390.732932110765603);
points += QPointF(-595.184660101380132, 390.389190982770685);
points += QPointF(-617.842942744172888, 389.879635420374768);
points += QPointF(-640.056148626075128, 389.208081776045162);
points += QPointF(-661.684051740050222, 388.378134611085102);
points += QPointF(-682.587707903001387, 387.393111203977753);
points += QPointF(-702.630213610816895, 386.255904969512756);
points += QPointF(-721.913933492959586, 384.952760768153212);
points += QPointF(-739.883081019170959, 383.510162372720174);
points += QPointF(-756.628370632600195, 381.913999891517676);
points += QPointF(-772.055707410166860, 380.156385631636169);
points += QPointF(-786.107417616341536, 378.217868080938274);
points += QPointF(-798.800506212061464, 376.051179682426266);
points += QPointF(-810.181063245406790, 373.562456117723798);
points += QPointF(-814.714960629921279, 372.254255263452592);
points += QPointF(-814.714960629921279, 331.313196850393751);
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> Issue924SeamAllowanceTest3()
{
QVector<QPointF> points;
points += QPointF(-844.490345580522785, 355.767273366986956);
points += QPointF(-814.714960629921279, 331.313196850393751);
points += QPointF(-814.714960629921279, -46.738127408018386);
points += QPointF(-778.560274683193597, -50.549491761193529);
points += QPointF(-737.960891197081651, -56.790170478391879);
points += QPointF(-709.273784936183347, -62.545071142283753);
points += QPointF(-681.358329676571884, -69.772421317304676);
points += QPointF(-662.734996979773655, -76.086662659765864);
points += QPointF(-652.000013358218780, -80.530014885308333);
points += QPointF(-647.534742107878174, -82.700492263504771);
points += QPointF(-631.585239468780856, -90.995118061836052);
points += QPointF(-616.328020233970847, -100.594267156991847);
points += QPointF(-594.096383910663576, -115.972155307751649);
points += QPointF(-184.048650148745537, 76.198374399107223);
points += QPointF(-202.588712626694274, 128.531217087733864);
points += QPointF(-214.844352980142077, 166.709615345349164);
points += QPointF(-224.900721916665105, 202.786707734969326);
points += QPointF(-232.934347140993879, 237.080856834901624);
points += QPointF(-239.089037151700012, 269.817045957384835);
points += QPointF(-243.506611386394923, 301.230502874877175);
points += QPointF(-246.324245680472586, 331.565901059170528);
points += QPointF(-247.367542640672326, 354.406709505752815);
points += QPointF(-268.813396242720216, 365.986520876589054);
points += QPointF(-274.509592479190928, 368.544465142904016);
points += QPointF(-280.430827138279028, 370.738996867416517);
points += QPointF(-286.539948778692178, 372.651089393540587);
points += QPointF(-295.760523769485246, 375.070669023642552);
points += QPointF(-309.108660665237892, 377.812272271559323);
points += QPointF(-323.791841306461833, 380.189287868544909);
points += QPointF(-339.746492379944868, 382.263575885265993);
points += QPointF(-356.936262185776172, 384.077045039880318);
points += QPointF(-375.281527662442841, 385.653208859628023);
points += QPointF(-394.678657394273387, 387.006850647147644);
points += QPointF(-414.787606696514558, 388.135795504608552);
points += QPointF(-435.952026976937020, 389.076617984501581);
points += QPointF(-457.785958239726995, 389.818484035948188);
points += QPointF(-480.155299343825106, 390.367355935354340);
points += QPointF(-502.923072127811622, 390.728524359010180);
points += QPointF(-525.950383000425973, 390.906843496429246);
points += QPointF(-549.097086395700558, 390.906868034847378);
points += QPointF(-572.222272868468281, 390.732932110765603);
points += QPointF(-595.184660101380132, 390.389190982770685);
points += QPointF(-617.842942744172888, 389.879635420374768);
points += QPointF(-640.056148626075128, 389.208081776045162);
points += QPointF(-661.684051740050222, 388.378134611085102);
points += QPointF(-682.587707903001387, 387.393111203977753);
points += QPointF(-702.630213610816895, 386.255904969512756);
points += QPointF(-721.913933492959586, 384.952760768153212);
points += QPointF(-739.883081019170959, 383.510162372720174);
points += QPointF(-756.628370632600195, 381.913999891517676);
points += QPointF(-772.055707410166860, 380.156385631636169);
points += QPointF(-786.107417616341536, 378.217868080938274);
points += QPointF(-798.800506212061464, 376.051179682426266);
points += QPointF(-810.181063245406790, 373.562456117723798);
points += QPointF(-818.092955780502393, 371.279575916538420);
points += QPointF(-823.692975528084730, 369.271805550997954);
points += QPointF(-829.575336882823422, 366.626948794191208);
points += QPointF(-835.815139714856855, 362.892089667033019);
points += QPointF(-844.490345580522785, 355.767273366986956);
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> Issue924SeamAllowanceTest4()
{
QVector<QPointF> points;
points += QPointF(-814.714960629921279, -46.738127408018386);
points += QPointF(-778.560274683193597, -50.549491761193529);
points += QPointF(-737.960891197081651, -56.790170478391879);
points += QPointF(-709.273784936183347, -62.545071142283753);
points += QPointF(-681.358329676571884, -69.772421317304676);
points += QPointF(-662.734996979773655, -76.086662659765864);
points += QPointF(-652.000013358218780, -80.530014885308333);
points += QPointF(-647.534742107878174, -82.700492263504771);
points += QPointF(-631.585239468780856, -90.995118061836052);
points += QPointF(-616.328020233970847, -100.594267156991847);
points += QPointF(-594.096383910663576, -115.972155307751649);
points += QPointF(-184.048650148745537, 76.198374399107223);
points += QPointF(-202.588712626694274, 128.531217087733864);
points += QPointF(-214.844352980142077, 166.709615345349164);
points += QPointF(-224.900721916665105, 202.786707734969326);
points += QPointF(-232.934347140993879, 237.080856834901624);
points += QPointF(-239.089037151700012, 269.817045957384835);
points += QPointF(-243.506611386394923, 301.230502874877175);
points += QPointF(-246.324245680472586, 331.565901059170528);
points += QPointF(-247.367542640672326, 354.406709505752815);
points += QPointF(-268.813396242720216, 365.986520876589054);
points += QPointF(-274.509592479190928, 368.544465142904016);
points += QPointF(-280.430827138279028, 370.738996867416517);
points += QPointF(-286.539948778692178, 372.651089393540587);
points += QPointF(-295.760523769485246, 375.070669023642552);
points += QPointF(-309.108660665237892, 377.812272271559323);
points += QPointF(-323.791841306461833, 380.189287868544909);
points += QPointF(-339.746492379944868, 382.263575885265993);
points += QPointF(-356.936262185776172, 384.077045039880318);
points += QPointF(-375.281527662442841, 385.653208859628023);
points += QPointF(-394.678657394273387, 387.006850647147644);
points += QPointF(-414.787606696514558, 388.135795504608552);
points += QPointF(-435.952026976937020, 389.076617984501581);
points += QPointF(-457.785958239726995, 389.818484035948188);
points += QPointF(-480.155299343825106, 390.367355935354340);
points += QPointF(-502.923072127811622, 390.728524359010180);
points += QPointF(-525.950383000425973, 390.906843496429246);
points += QPointF(-549.097086395700558, 390.906868034847378);
points += QPointF(-572.222272868468281, 390.732932110765603);
points += QPointF(-595.184660101380132, 390.389190982770685);
points += QPointF(-617.842942744172888, 389.879635420374768);
points += QPointF(-640.056148626075128, 389.208081776045162);
points += QPointF(-661.684051740050222, 388.378134611085102);
points += QPointF(-682.587707903001387, 387.393111203977753);
points += QPointF(-702.630213610816895, 386.255904969512756);
points += QPointF(-721.913933492959586, 384.952760768153212);
points += QPointF(-739.883081019170959, 383.510162372720174);
points += QPointF(-756.628370632600195, 381.913999891517676);
points += QPointF(-772.055707410166860, 380.156385631636169);
points += QPointF(-786.107417616341536, 378.217868080938274);
points += QPointF(-798.800506212061464, 376.051179682426266);
points += QPointF(-810.181063245406790, 373.562456117723798);
points += QPointF(-814.714960629921279, 372.254255263452592);
points += QPointF(-814.714960629921279, -46.738127408018386);
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> Issue924SeamAllowanceTest5()
{
QVector<QPointF> points;
points += QPointF(-838.702607797801647, 360.520655492237381);
points += QPointF(-814.714960629921279, 331.313196850393751);
points += QPointF(-814.714960629921279, -46.738127408018386);
points += QPointF(-778.560274683193597, -50.549491761193529);
points += QPointF(-737.960891197081651, -56.790170478391879);
points += QPointF(-709.273784936183347, -62.545071142283753);
points += QPointF(-681.358329676571884, -69.772421317304676);
points += QPointF(-662.734996979773655, -76.086662659765864);
points += QPointF(-652.000013358218780, -80.530014885308333);
points += QPointF(-647.534742107878174, -82.700492263504771);
points += QPointF(-631.585239468780856, -90.995118061836052);
points += QPointF(-616.328020233970847, -100.594267156991847);
points += QPointF(-594.096383910663576, -115.972155307751649);
points += QPointF(-184.048650148745537, 76.198374399107223);
points += QPointF(-202.588712626694274, 128.531217087733864);
points += QPointF(-214.844352980142077, 166.709615345349164);
points += QPointF(-224.900721916665105, 202.786707734969326);
points += QPointF(-232.934347140993879, 237.080856834901624);
points += QPointF(-239.089037151700012, 269.817045957384835);
points += QPointF(-243.506611386394923, 301.230502874877175);
points += QPointF(-246.324245680472586, 331.565901059170528);
points += QPointF(-247.367542640672326, 354.406709505752815);
points += QPointF(-268.813396242720216, 365.986520876589054);
points += QPointF(-274.509592479190928, 368.544465142904016);
points += QPointF(-280.430827138279028, 370.738996867416517);
points += QPointF(-286.539948778692178, 372.651089393540587);
points += QPointF(-295.760523769485246, 375.070669023642552);
points += QPointF(-309.108660665237892, 377.812272271559323);
points += QPointF(-323.791841306461833, 380.189287868544909);
points += QPointF(-339.746492379944868, 382.263575885265993);
points += QPointF(-356.936262185776172, 384.077045039880318);
points += QPointF(-375.281527662442841, 385.653208859628023);
points += QPointF(-394.678657394273387, 387.006850647147644);
points += QPointF(-414.787606696514558, 388.135795504608552);
points += QPointF(-435.952026976937020, 389.076617984501581);
points += QPointF(-457.785958239726995, 389.818484035948188);
points += QPointF(-480.155299343825106, 390.367355935354340);
points += QPointF(-502.923072127811622, 390.728524359010180);
points += QPointF(-525.950383000425973, 390.906843496429246);
points += QPointF(-549.097086395700558, 390.906868034847378);
points += QPointF(-572.222272868468281, 390.732932110765603);
points += QPointF(-595.184660101380132, 390.389190982770685);
points += QPointF(-617.842942744172888, 389.879635420374768);
points += QPointF(-640.056148626075128, 389.208081776045162);
points += QPointF(-661.684051740050222, 388.378134611085102);
points += QPointF(-682.587707903001387, 387.393111203977753);
points += QPointF(-702.630213610816895, 386.255904969512756);
points += QPointF(-721.913933492959586, 384.952760768153212);
points += QPointF(-739.883081019170959, 383.510162372720174);
points += QPointF(-756.628370632600195, 381.913999891517676);
points += QPointF(-772.055707410166860, 380.156385631636169);
points += QPointF(-786.107417616341536, 378.217868080938274);
points += QPointF(-798.800506212061464, 376.051179682426266);
points += QPointF(-810.181063245406790, 373.562456117723798);
points += QPointF(-818.092955780502393, 371.279575916538420);
points += QPointF(-823.692975528084730, 369.271805550997954);
points += QPointF(-829.575336882823422, 366.626948794191208);
points += QPointF(-835.815139714856855, 362.892089667033019);
points += QPointF(-838.702607797801647, 360.520655492237381);
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> Issue924SeamAllowanceTest6()
{
QVector<QPointF> points;
points += QPointF(-814.714960629921279, -46.738127408018386);
points += QPointF(-778.560274683193597, -50.549491761193529);
points += QPointF(-737.960891197081651, -56.790170478391879);
points += QPointF(-709.273784936183347, -62.545071142283753);
points += QPointF(-681.358329676571884, -69.772421317304676);
points += QPointF(-662.734996979773655, -76.086662659765864);
points += QPointF(-652.000013358218780, -80.530014885308333);
points += QPointF(-647.534742107878174, -82.700492263504771);
points += QPointF(-631.585239468780856, -90.995118061836052);
points += QPointF(-616.328020233970847, -100.594267156991847);
points += QPointF(-594.096383910663576, -115.972155307751649);
points += QPointF(-184.048650148745537, 76.198374399107223);
points += QPointF(-202.588712626694274, 128.531217087733864);
points += QPointF(-214.844352980142077, 166.709615345349164);
points += QPointF(-224.900721916665105, 202.786707734969326);
points += QPointF(-232.934347140993879, 237.080856834901624);
points += QPointF(-239.089037151700012, 269.817045957384835);
points += QPointF(-243.506611386394923, 301.230502874877175);
points += QPointF(-246.324245680472586, 331.565901059170528);
points += QPointF(-247.367542640672326, 354.406709505752815);
points += QPointF(-268.813396242720216, 365.986520876589054);
points += QPointF(-274.509592479190928, 368.544465142904016);
points += QPointF(-280.430827138279028, 370.738996867416517);
points += QPointF(-286.539948778692178, 372.651089393540587);
points += QPointF(-295.760523769485246, 375.070669023642552);
points += QPointF(-309.108660665237892, 377.812272271559323);
points += QPointF(-323.791841306461833, 380.189287868544909);
points += QPointF(-339.746492379944868, 382.263575885265993);
points += QPointF(-356.936262185776172, 384.077045039880318);
points += QPointF(-375.281527662442841, 385.653208859628023);
points += QPointF(-394.678657394273387, 387.006850647147644);
points += QPointF(-414.787606696514558, 388.135795504608552);
points += QPointF(-435.952026976937020, 389.076617984501581);
points += QPointF(-457.785958239726995, 389.818484035948188);
points += QPointF(-480.155299343825106, 390.367355935354340);
points += QPointF(-502.923072127811622, 390.728524359010180);
points += QPointF(-525.950383000425973, 390.906843496429246);
points += QPointF(-549.097086395700558, 390.906868034847378);
points += QPointF(-572.222272868468281, 390.732932110765603);
points += QPointF(-595.184660101380132, 390.389190982770685);
points += QPointF(-617.842942744172888, 389.879635420374768);
points += QPointF(-640.056148626075128, 389.208081776045162);
points += QPointF(-661.684051740050222, 388.378134611085102);
points += QPointF(-682.587707903001387, 387.393111203977753);
points += QPointF(-702.630213610816895, 386.255904969512756);
points += QPointF(-721.913933492959586, 384.952760768153212);
points += QPointF(-739.883081019170959, 383.510162372720174);
points += QPointF(-756.628370632600195, 381.913999891517676);
points += QPointF(-772.055707410166860, 380.156385631636169);
points += QPointF(-786.107417616341536, 378.217868080938274);
points += QPointF(-798.800506212061464, 376.051179682426266);
points += QPointF(-810.181063245406790, 373.562456117723798);
points += QPointF(-814.714960629921279, 372.254255263452592);
points += QPointF(-814.714960629921279, -46.738127408018386);
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> Issue924SeamAllowanceTest1_1()
{
QVector<QPointF> points;
points += QPointF(-814.714960629921279, -46.738127408018386);
points += QPointF(-778.560274683193597, -50.549491761193529);
points += QPointF(-737.960891197081651, -56.790170478391879);
points += QPointF(-709.273784936183347, -62.545071142283753);
points += QPointF(-681.358329676571884, -69.772421317304676);
points += QPointF(-662.734996979773655, -76.086662659765864);
points += QPointF(-652.000013358218780, -80.530014885308333);
points += QPointF(-647.534742107878174, -82.700492263504771);
points += QPointF(-631.585239468780856, -90.995118061836052);
points += QPointF(-616.328020233970847, -100.594267156991847);
points += QPointF(-594.096383910663576, -115.972155307751649);
points += QPointF(-184.048650148745537, 76.198374399107223);
points += QPointF(-202.588712626694274, 128.531217087733864);
points += QPointF(-214.844352980142077, 166.709615345349164);
points += QPointF(-224.900721916665105, 202.786707734969326);
points += QPointF(-232.934347140993879, 237.080856834901624);
points += QPointF(-239.089037151700012, 269.817045957384835);
points += QPointF(-243.506611386394923, 301.230502874877175);
points += QPointF(-246.324245680472586, 331.565901059170528);
points += QPointF(-247.367542640672326, 354.406709505752815);
points += QPointF(-268.813396242720216, 365.986520876589054);
points += QPointF(-274.509592479190928, 368.544465142904016);
points += QPointF(-280.430827138279028, 370.738996867416517);
points += QPointF(-286.539948778692178, 372.651089393540587);
points += QPointF(-295.760523769485246, 375.070669023642552);
points += QPointF(-309.108660665237892, 377.812272271559323);
points += QPointF(-323.791841306461833, 380.189287868544909);
points += QPointF(-339.746492379944868, 382.263575885265993);
points += QPointF(-356.936262185776172, 384.077045039880318);
points += QPointF(-375.281527662442841, 385.653208859628023);
points += QPointF(-394.678657394273387, 387.006850647147644);
points += QPointF(-414.787606696514558, 388.135795504608552);
points += QPointF(-435.952026976937020, 389.076617984501581);
points += QPointF(-457.785958239726995, 389.818484035948188);
points += QPointF(-480.155299343825106, 390.367355935354340);
points += QPointF(-502.923072127811622, 390.728524359010180);
points += QPointF(-525.950383000425973, 390.906843496429246);
points += QPointF(-549.097086395700558, 390.906868034847378);
points += QPointF(-572.222272868468281, 390.732932110765603);
points += QPointF(-595.184660101380132, 390.389190982770685);
points += QPointF(-617.842942744172888, 389.879635420374768);
points += QPointF(-640.056148626075128, 389.208081776045162);
points += QPointF(-661.684051740050222, 388.378134611085102);
points += QPointF(-682.587707903001387, 387.393111203977753);
points += QPointF(-702.630213610816895, 386.255904969512756);
points += QPointF(-721.913933492959586, 384.952760768153212);
points += QPointF(-739.883081019170959, 383.510162372720174);
points += QPointF(-756.628370632600195, 381.913999891517676);
points += QPointF(-772.055707410166860, 380.156385631636169);
points += QPointF(-786.107417616341536, 378.217868080938274);
points += QPointF(-798.800506212061464, 376.051179682426266);
points += QPointF(-810.181063245406790, 373.562456117723798);
points += QPointF(-814.714960629921279, 372.254255263452592);
points += QPointF(-814.714960629921279, -46.738127408018386);
return points;
}
} // anonymous namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
TST_VPiece::TST_VPiece(QObject *parent) TST_VPiece::TST_VPiece(QObject *parent)
@ -403,3 +860,125 @@ void TST_VPiece::Issue620()
// Begin comparison // Begin comparison
Comparison(pointsEkv, origPoints); Comparison(pointsEkv, origPoints);
} }
//---------------------------------------------------------------------------------------------------------------------
void TST_VPiece::TestSAPassmark_data()
{
QTest::addColumn<VPiecePassmarkData>("passmarkData");
QTest::addColumn<QVector<QPointF>>("seamAllowance");
QTest::addColumn<QVector<QLineF>>("expectedResult");
VSAPoint nextSAPoint(-814.7149606299213, -8.844283464566928);
nextSAPoint.SetSABefore(0);
nextSAPoint.SetSAAfter(37.795275590551185);
VSAPoint passmarkSAPoint(-814.7149606299213, 331.31319685039375);
passmarkSAPoint.SetSABefore(37.795275590551185);
passmarkSAPoint.SetSAAfter(0);
VSAPoint previousSAPoint(-813.9961742743915, 331.90352529002166);
previousSAPoint.SetSABefore(37.795275590551185);
previousSAPoint.SetSAAfter(37.795275590551185);
previousSAPoint.SetAngleType(PieceNodeAngle::ByLengthCurve);
VPiecePassmarkData passmarkData;
passmarkData.previousSAPoint = previousSAPoint;
passmarkData.passmarkSAPoint = passmarkSAPoint;
passmarkData.nextSAPoint = nextSAPoint;
passmarkData.saWidth = 37.795275590551185;
passmarkData.nodeName = QStringLiteral("А4");
passmarkData.pieceName = QStringLiteral("Test 1");
passmarkData.passmarkLineType = PassmarkLineType::TMark;
passmarkData.passmarkAngleType = PassmarkAngleType::Bisector;
QVector<QLineF> lines = {QLineF(QPointF(-814.7149606299213, 372.2542552634526),
QPointF(-799.6132275149633, 360.8938692151714)),
QLineF(QPointF(-803.8733722830686, 355.23071929706197),
QPointF(-795.353082746858, 366.5570191332808))};
// See file src/app/share/collection/bugs/Issue_#924.val
QTest::newRow("Test 1.") << passmarkData << Issue924SeamAllowanceTest1() << lines;
passmarkSAPoint.SetAngleType(PieceNodeAngle::ByPointsIntersection);
passmarkData.passmarkSAPoint = passmarkSAPoint;
passmarkData.pieceName = QStringLiteral("Test 2");
// See file src/app/share/collection/bugs/Issue_#924.val
QTest::newRow("Test 2.") << passmarkData << Issue924SeamAllowanceTest2() << lines;
passmarkSAPoint.SetAngleType(PieceNodeAngle::ByFirstEdgeSymmetry);
passmarkData.passmarkSAPoint = passmarkSAPoint;
passmarkData.pieceName = QStringLiteral("Test 3");
lines = {QLineF(QPointF(-844.4903455805228, 355.76727336698696),
QPointF(-825.5927077852472, 355.76727336698696)),
QLineF(QPointF(-825.5927077852472, 348.68065919375863),
QPointF(-825.5927077852472, 362.8538875402153))};
// See file src/app/share/collection/bugs/Issue_#924.val
QTest::newRow("Test 3.") << passmarkData << Issue924SeamAllowanceTest3() << lines;
passmarkSAPoint.SetAngleType(PieceNodeAngle::BySecondEdgeSymmetry);
passmarkData.passmarkSAPoint = passmarkSAPoint;
passmarkData.pieceName = QStringLiteral("Test 4");
lines = {QLineF(QPointF(-814.7149606299213, 372.2542552634526),
QPointF(-799.6132275149633, 360.8938692151714)),
QLineF(QPointF(-803.8733722830686, 355.23071929706197),
QPointF(-795.353082746858, 366.5570191332808))};
// See file src/app/share/collection/bugs/Issue_#924.val
QTest::newRow("Test 4.") << passmarkData << Issue924SeamAllowanceTest4() << lines;
passmarkSAPoint.SetAngleType(PieceNodeAngle::ByFirstEdgeRightAngle);
passmarkData.passmarkSAPoint = passmarkSAPoint;
passmarkData.pieceName = QStringLiteral("Test 5");
lines = {QLineF(QPointF(-838.7026077978016, 360.5206554922374),
QPointF(-821.3650156381559, 353.002104278923)),
QLineF(QPointF(-824.1844723431489, 346.50050721905575),
QPointF(-818.545558933163, 359.5037013387903))};
// See file src/app/share/collection/bugs/Issue_#924.val
QTest::newRow("Test 5.") << passmarkData << Issue924SeamAllowanceTest5() << lines;
passmarkSAPoint.SetAngleType(PieceNodeAngle::BySecondEdgeRightAngle);
passmarkData.passmarkSAPoint = passmarkSAPoint;
passmarkData.pieceName = QStringLiteral("Test 6");
lines = {QLineF(QPointF(-814.7149606299213, 372.2542552634526),
QPointF(-799.6132275149633, 360.8938692151714)),
QLineF(QPointF(-803.8733722830686, 355.23071929706197),
QPointF(-795.353082746858, 366.5570191332808))};
// See file src/app/share/collection/bugs/Issue_#924.val
QTest::newRow("Test 6.") << passmarkData << Issue924SeamAllowanceTest6() << lines;
passmarkSAPoint.SetAngleType(PieceNodeAngle::ByLength);
passmarkData.passmarkSAPoint = passmarkSAPoint;
passmarkData.pieceName = QStringLiteral("Test 1.1");
lines = {QLineF(QPointF(-814.7149606299213, 372.2542552634526),
QPointF(-799.6132275149633, 360.8938692151714)),
QLineF(QPointF(-803.8733722830686, 355.23071929706197),
QPointF(-795.353082746858, 366.5570191332808))};
// See file src/app/share/collection/bugs/Issue_#924.val
QTest::newRow("Test 1.1.") << passmarkData << Issue924SeamAllowanceTest1_1() << lines;
}
//---------------------------------------------------------------------------------------------------------------------
void TST_VPiece::TestSAPassmark()
{
QFETCH(VPiecePassmarkData, passmarkData);
QFETCH(QVector<QPointF>, seamAllowance);
QFETCH(QVector<QLineF>, expectedResult);
Comparison(VPiece::SAPassmark(passmarkData, seamAllowance), expectedResult);
}

View File

@ -40,6 +40,8 @@ public:
private slots: private slots:
void ClearLoop(); void ClearLoop();
void Issue620(); void Issue620();
void TestSAPassmark_data();
void TestSAPassmark();
private: private:
Q_DISABLE_COPY(TST_VPiece) Q_DISABLE_COPY(TST_VPiece)