Fixed issues with seam allowance.
More cases. --HG-- branch : release
This commit is contained in:
parent
f2218aa0b2
commit
695bcea062
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue
Block a user