Fixed issues with seam allowance.

More cases.
(grafted from 7324a77cb8851a215d26269a8db7106a653915fd)

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2018-10-19 16:54:06 +03:00
parent 81d2eb513a
commit 2211e2b7ee
7 changed files with 599 additions and 440 deletions

View File

@ -472,6 +472,21 @@ bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const Q
return IsPointOnLineviaPDP(t, p1, p2);
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VGObject::CorrectDistortion(const QPointF &t, const QPointF &p1, const QPointF &p2)
{
if (not VFuzzyComparePoints(p1, p2))
{
QLineF line = QLineF(p1, p2);
line.setLength(QLineF(p1, VGObject::ClosestPoint(QLineF(p1, p2), t)).length());
return line.p2();
}
else
{
return t;
}
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief IsPointOnLineviaPDP use the perp dot product (PDP) way.

View File

@ -97,6 +97,7 @@ public:
static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k);
static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c);
static bool IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2);
static QPointF CorrectDistortion(const QPointF &t, const QPointF &p1, const QPointF &p2);
static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2);
template <typename T>

View File

@ -263,8 +263,15 @@ QVector<QPointF> AngleByLength(QVector<QPointF> points, QPointF p2, const QLineF
{
if (not IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), sp2))
{
bool success = false;
points = RollbackSeamAllowance(points, bigLine2, &success);
if (p.GetAngleType() != PieceNodeAngle::ByLengthCurve)
{
bool success = false;
points = RollbackSeamAllowance(points, bigLine2, &success);
}
else
{
points.append(sp2);
}
}
else
{
@ -871,6 +878,9 @@ QVector<QPointF> VAbstractPiece::Equidistant(QVector<VSAPoint> points, qreal wid
return QVector<QPointF>();
}
// Fix distorsion
points = CorrectPathDistortion(points);
if (points.last().toPoint() != points.first().toPoint())
{
points.append(points.at(0));// Should be always closed
@ -1102,21 +1112,15 @@ QVector<QPointF> VAbstractPiece::EkvPoint(QVector<QPointF> points, const VSAPoin
return QVector<QPointF>(); // Wrong edges
}
// Correct distorsion
if (VGObject::IsPointOnLineSegment(p2Line1, p1Line1, p1Line2))
{
QLineF line = QLineF(p1Line1, p1Line2);
line.setLength(QLineF(p1Line1, p2Line1).length());
p2Line1.setX(line.p2().x());
p2Line1.setY(line.p2().y());
p2Line2.setX(line.p2().x());
p2Line2.setY(line.p2().y());
}
const QLineF bigLine1 = ParallelLine(p1Line1, p2Line1, width );
const QLineF bigLine2 = ParallelLine(p2Line2, p1Line2, width );
if (VFuzzyComparePoints(bigLine1.p2(), bigLine2.p1()))
{
points.append(bigLine1.p2());
return points;
}
QPointF crosPoint;
const QLineF::IntersectType type = bigLine1.intersect( bigLine2, &crosPoint );
switch (type)
@ -1129,8 +1133,21 @@ QVector<QPointF> VAbstractPiece::EkvPoint(QVector<QPointF> points, const VSAPoin
{ // Most common case
/* Case when a path has point on line (both segments lie on the same line) and seam allowance creates
* prong. */
auto IsOnLine = [](const QPointF &base, const QPointF &sp1, const QPointF &sp2)
{
if (not VFuzzyComparePoints(base, sp1))
{
return VGObject::IsPointOnLineviaPDP(sp2, base, sp1);
}
if (not VFuzzyComparePoints(base, sp2))
{
return VGObject::IsPointOnLineviaPDP(sp1, base, sp2);
}
return true;
};
if (VGObject::IsPointOnLineSegment(p2Line1, p1Line1, p1Line2)
&& qAbs(QLineF(p2Line1, bigLine1.p2()).angle() - QLineF(p2Line1, bigLine2.p1()).angle()) < 0.001)
&& IsOnLine(p2Line1, bigLine1.p2(), bigLine2.p1()))
{
points.append(bigLine1.p2());
points.append(bigLine2.p1());

View File

@ -190,6 +190,9 @@ public:
const VSAPoint &p1Line2, VSAPoint p2Line2, qreal width);
static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width);
template <class T>
static QVector<T> CorrectPathDistortion(QVector<T> path);
template <class T>
static QVector<T> CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast = true);
@ -207,6 +210,44 @@ private:
Q_DECLARE_TYPEINFO(VAbstractPiece, Q_MOVABLE_TYPE);
//---------------------------------------------------------------------------------------------------------------------
template<class T>
QVector<T> VAbstractPiece::CorrectPathDistortion(QVector<T> path)
{
if (path.size() < 3)
{
return path;
}
int prev = -1;
for (qint32 i = 0; i < path.size(); ++i)
{
if (prev == -1)
{
i == 0 ? prev = path.size() - 1 : prev = i-1;
}
int next = i+1;
if (i == path.size() - 1)
{
next = 0;
}
const QPointF &iPoint = path.at(i);
const QPointF &prevPoint = path.at(prev);
const QPointF &nextPoint = path.at(next);
if (VGObject::IsPointOnLineSegment(iPoint, prevPoint, nextPoint))
{
const QPointF p = VGObject::CorrectDistortion(iPoint, prevPoint, nextPoint);
path[i].setX(p.x());
path[i].setY(p.y());
}
}
return path;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant.

View File

@ -1104,7 +1104,7 @@ bool VPiece::GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int in
do
{
const VSAPoint previous = points.at(nodeIndex);
if (passmarkSAPoint.toPoint() != previous.toPoint())
if (not VFuzzyComparePoints(passmarkSAPoint, previous))
{
point = previous;
found = true;
@ -1141,7 +1141,7 @@ int VPiece::GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index,
do
{
const VSAPoint next = points.at(nodeIndex);
if (passmarkSAPoint.toPoint() != next.toPoint())
if (not VFuzzyComparePoints(passmarkSAPoint, next))
{
point = next;
found = true;
@ -1159,32 +1159,22 @@ int VPiece::GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index,
}
//---------------------------------------------------------------------------------------------------------------------
bool VPiece::GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, const VSAPoint &passmarkSAPoint,
bool VPiece::GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, VSAPoint passmarkSAPoint,
const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const
{
SCASSERT(data != nullptr)
QVector<QPointF> ekvPoints;
const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit());
// Correct distorsion
if (VGObject::IsPointOnLineSegment(passmarkSAPoint, previousSAPoint, nextSAPoint))
{
const QPointF p = VGObject::CorrectDistortion(passmarkSAPoint, previousSAPoint, nextSAPoint);
passmarkSAPoint.setX(p.x());
passmarkSAPoint.setY(p.y());
}
/* Because method VAbstractPiece::EkvPoint has troubles with edges on a same line we should specially treat such
cases.
First check if two edges and seam alowance create paralell lines.
Second case check if two edges are on a same line geometrically and a passmark point has equal SA width.*/
if (IsEkvPointOnLine(passmarkSAPoint, previousSAPoint, nextSAPoint)// see issue #665
|| (IsEkvPointOnLine(static_cast<QPointF>(passmarkSAPoint), static_cast<QPointF>(previousSAPoint),
static_cast<QPointF>(nextSAPoint))
&& qAbs(passmarkSAPoint.GetSABefore(width) - passmarkSAPoint.GetSAAfter(width)) < accuracyPointOnLine))
{
QLineF line (passmarkSAPoint, nextSAPoint);
line.setAngle(line.angle() + 90);
line.setLength(passmarkSAPoint.MaxLocalSA(width));
ekvPoints.append(line.p2());
}
else
{
ekvPoints = EkvPoint(ekvPoints, previousSAPoint, passmarkSAPoint, nextSAPoint, passmarkSAPoint, width);
}
QVector<QPointF> ekvPoints;
ekvPoints = EkvPoint(ekvPoints, previousSAPoint, passmarkSAPoint, nextSAPoint, passmarkSAPoint,
ToPixel(GetSAWidth(), *data->GetPatternUnit()));
if (ekvPoints.isEmpty())
{ // Just in case

View File

@ -145,7 +145,7 @@ private:
const VContainer *data, VSAPoint &point, int passmarkIndex) const;
int GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, VSAPoint &point, int passmarkIndex) const;
bool GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, const VSAPoint &passmarkSAPoint,
bool GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, VSAPoint passmarkSAPoint,
const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const;
bool IsPassmarkVisible(const QVector<VPieceNode> &path, int passmarkIndex) const;

File diff suppressed because it is too large Load Diff