Fix case with custom piece path as part of main path. ref #668.

--HG--
branch : release
This commit is contained in:
Roman Telezhynskyi 2017-04-25 20:48:32 +03:00
parent b300c2a83a
commit 585213412c
6 changed files with 97 additions and 190 deletions

View file

@ -755,51 +755,6 @@ QLineF VAbstractPiece::ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qrea
return paralel;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractPiece::ParallelCurve(const QVector<VSAPoint> &points, qreal width)
{
QVector<QPointF> curvePoints;
bool removeFirstAndLast = false;
const QVector<VSAPoint> p = CorrectEquidistantPoints(points, removeFirstAndLast);
if (p.size() < 2)
{
return QVector<QPointF>();
}
else if (p.size() < 3)
{
const QLineF line = ParallelLine(p.at(0), p.at(1), width);
curvePoints << line.p1();
curvePoints << line.p2();
}
else
{
for (qint32 i = 0; i < p.size(); ++i)
{
if ( i == 0)
{//first point
curvePoints << ParallelLine(p.at(i), p.at(i+1), width).p1();
continue;
}
if (i == p.size()-1)
{//last point
if (not curvePoints.isEmpty())
{
curvePoints << ParallelLine(p.at(i-1), p.at(i), width).p2();
}
continue;
}
//points in the middle of polyline
curvePoints << EkvPoint(p.at(i-1), p.at(i), p.at(i+1), p.at(i), width);
}
}
curvePoints = CheckLoops(CorrectEquidistantPoints(curvePoints, removeFirstAndLast));//Result path can contain loops
return curvePoints;
}
//---------------------------------------------------------------------------------------------------------------------
QLineF VAbstractPiece::ParallelLine(const QPointF &p1, const QPointF &p2, qreal width)
{

View file

@ -173,7 +173,6 @@ public:
static QVector<QPointF> EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1,
const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width);
static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width);
static QVector<QPointF> ParallelCurve(const QVector<VSAPoint> &points, qreal width);
template <class T>
static QVector<T> CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast = true);

View file

@ -428,29 +428,10 @@ QVector<QLineF> VPiece::PassmarksLines(const VContainer *data) const
continue;// skip node
}
int passmarkIndex = i;
const int previousIndex = VPiecePath::FindInLoopNotExcludedUp(i, unitedPath);
const int nextIndex = VPiecePath::FindInLoopNotExcludedDown(i, unitedPath);
int previousIndex = 0;
if (passmarkIndex == 0)
{
previousIndex = VPiecePath::FindInLoopNotExcludedUp(unitedPath.size()-1, unitedPath);
}
else
{
previousIndex = VPiecePath::FindInLoopNotExcludedUp(passmarkIndex-1, unitedPath);
}
int nextIndex = 0;
if (passmarkIndex == unitedPath.size()-1)
{
nextIndex = VPiecePath::FindInLoopNotExcludedDown(0, unitedPath);
}
else
{
nextIndex = VPiecePath::FindInLoopNotExcludedDown(passmarkIndex+1, unitedPath);
}
passmarks += CreatePassmark(unitedPath, previousIndex, passmarkIndex, nextIndex, data);
passmarks += CreatePassmark(unitedPath, previousIndex, i, nextIndex, data);
}
return passmarks;
@ -936,27 +917,26 @@ bool VPiece::GetPassmarkSAPoint(const QVector<VPieceNode> &path, int index, cons
}
//---------------------------------------------------------------------------------------------------------------------
int VPiece::GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, QVector<VSAPoint> &points) const
bool VPiece::GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, VSAPoint &point) const
{
SCASSERT(data != nullptr)
const QVector<VSAPoint> saPoints = GetNodeSAPoints(path, index, data);
const QVector<VSAPoint> points = GetNodeSAPoints(path, index, data);
if (saPoints.isEmpty())
if (points.isEmpty())
{
return -1; // Something wrong
return false; // Something wrong
}
int saIndex = -1;
bool found = false;
int nodeIndex = saPoints.size()-1;
int nodeIndex = points.size()-1;
do
{
const VSAPoint previous = saPoints.at(nodeIndex);
const VSAPoint previous = points.at(nodeIndex);
if (passmarkSAPoint.toPoint() != previous.toPoint())
{
saIndex = nodeIndex;
point = previous;
found = true;
}
--nodeIndex;
@ -964,44 +944,43 @@ int VPiece::GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int ind
if (not found)
{
return -1; // Something wrong
return false; // Something wrong
}
points = saPoints;
return saIndex;
return true;
}
//---------------------------------------------------------------------------------------------------------------------
int VPiece::GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, QVector<VSAPoint> &points) const
const VContainer *data, VSAPoint &point) const
{
const QVector<VSAPoint> saPoints = GetNodeSAPoints(path, index, data);
SCASSERT(data != nullptr)
if (saPoints.isEmpty())
const QVector<VSAPoint> points = GetNodeSAPoints(path, index, data);
if (points.isEmpty())
{
return -1; // Something wrong
return false; // Something wrong
}
int saIndex = -1;
bool found = false;
int nodeIndex = 0;
do
{
const VSAPoint next = saPoints.at(nodeIndex);
const VSAPoint next = points.at(nodeIndex);
if (passmarkSAPoint.toPoint() != next.toPoint())
{
saIndex = nodeIndex;
point = next;
found = true;
}
++nodeIndex;
} while (nodeIndex < saPoints.size() && not found);
} while (nodeIndex < points.size() && not found);
if (not found)
{
return -1; // Something wrong
return false; // Something wrong
}
points = saPoints;
return saIndex;
return true;
}
//---------------------------------------------------------------------------------------------------------------------
@ -1099,17 +1078,15 @@ QVector<QLineF> VPiece::CreatePassmark(const QVector<VPieceNode> &path, int prev
return QVector<QLineF>(); // Something wrong
}
QVector<VSAPoint> previousSAPoints;
const int previousSAPointIndex = GetPassmarkPreviousSAPoints(path, previousIndex, passmarkSAPoint, data,
previousSAPoints);
if (previousSAPointIndex == -1)
VSAPoint previousSAPoint;
if (not GetPassmarkPreviousSAPoints(path, previousIndex, passmarkSAPoint, data,
previousSAPoint))
{
return QVector<QLineF>(); // Something wrong
}
QVector<VSAPoint> nextSAPoints;
const int nextSAPointIndex = GetPassmarkNextSAPoints(path, nextIndex, passmarkSAPoint, data, nextSAPoints);
if (nextSAPointIndex == -1)
VSAPoint nextSAPoint;
if (not GetPassmarkNextSAPoints(path, nextIndex, passmarkSAPoint, data, nextSAPoint))
{
return QVector<QLineF>(); // Something wrong
}
@ -1117,33 +1094,26 @@ QVector<QLineF> VPiece::CreatePassmark(const QVector<VPieceNode> &path, int prev
if (not IsSeamAllowanceBuiltIn())
{
QVector<QLineF> lines;
lines += SAPassmark(path, previousSAPoints, previousSAPointIndex, passmarkSAPoint, nextSAPoints,
nextSAPointIndex, data, passmarkIndex);
lines += SAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex);
if (qApp->Settings()->IsDoublePassmark()
&& path.at(passmarkIndex).IsMainPathNode()
&& path.at(passmarkIndex).GetPassmarkAngleType() != PassmarkAngleType::Intersection)
{
lines += BuiltInSAPassmark(path, previousSAPoints.at(previousSAPointIndex), passmarkSAPoint,
nextSAPoints.at(nextSAPointIndex), data, passmarkIndex);
lines += BuiltInSAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex);
}
return lines;
}
else
{
return BuiltInSAPassmark(path, previousSAPoints.at(previousSAPointIndex), passmarkSAPoint,
nextSAPoints.at(nextSAPointIndex), data, passmarkIndex);
return BuiltInSAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex);
}
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVector<VSAPoint> &previousSAPoints,
const int previousSAPointIndex, const VSAPoint &passmarkSAPoint,
const QVector<VSAPoint> &nextSAPoints, const int nextSAPointIndex,
const VContainer *data, int passmarkIndex) const
QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, VSAPoint &previousSAPoint,
const VSAPoint &passmarkSAPoint, VSAPoint &nextSAPoint, const VContainer *data,
int passmarkIndex) const
{
const VSAPoint &previousSAPoint = previousSAPoints.at(previousSAPointIndex);
const VSAPoint &nextSAPoint = nextSAPoints.at(nextSAPointIndex);
QPointF seamPassmarkSAPoint;
if (not GetSeamPassmarkSAPoint(previousSAPoint, passmarkSAPoint, nextSAPoint, data, seamPassmarkSAPoint))
{
@ -1151,8 +1121,6 @@ QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVecto
}
const qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit());
const QLineF bigLine1 = ParallelLine(previousSAPoint, passmarkSAPoint, width );
const QLineF bigLine2 = ParallelLine(passmarkSAPoint, nextSAPoint, width );
QVector<QLineF> passmarksLines;
@ -1167,6 +1135,9 @@ QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVecto
}
else if (node.GetPassmarkAngleType() == PassmarkAngleType::Bisector)
{
const QLineF bigLine1 = ParallelLine(previousSAPoint, passmarkSAPoint, width );
const QLineF bigLine2 = ParallelLine(passmarkSAPoint, nextSAPoint, width );
QLineF edge1 = QLineF(seamPassmarkSAPoint, bigLine1.p1());
QLineF edge2 = QLineF(seamPassmarkSAPoint, bigLine2.p2());
@ -1179,38 +1150,16 @@ QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVecto
{
{
// first passmark
QPointF p;
QLineF line(previousSAPoint, passmarkSAPoint);
line.setLength(line.length()*100); // Hope 100 is enough
if (nextSAPoints.size() < 2)
const QVector<QPointF> intersections = VAbstractCurve::CurveIntersectLine(SeamAllowancePoints(data), line);
if (intersections.isEmpty())
{
const QLineF::IntersectType type = line.intersect(bigLine2, &p);
if (type == QLineF::NoIntersection)
{
p = passmarkSAPoint;
}
}
else
{
line.setLength(line.length() + passmarkSAPoint.GetSAAfter(width)*2);
QVector<VSAPoint> vector;
vector << previousSAPoints;
vector.append(passmarkSAPoint);
vector << nextSAPoints;
const QVector<QPointF> curvePoints = ParallelCurve(vector, width);
const QVector<QPointF> intersections = VAbstractCurve::CurveIntersectLine(curvePoints, line);
if (intersections.isEmpty())
{
return QVector<QLineF>(); // Something wrong
}
p = intersections.first();
return QVector<QLineF>(); // Something wrong
}
line = QLineF(p, passmarkSAPoint);
line = QLineF(intersections.first(), passmarkSAPoint);
line.setLength(qMin(passmarkSAPoint.GetSAAfter(width) * passmarkFactor, maxPassmarkLength));
passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line);
@ -1218,38 +1167,17 @@ QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVecto
{
// second passmark
QPointF p;
QLineF line(nextSAPoint, passmarkSAPoint);
line.setLength(line.length()*100); // Hope 100 is enough
if (previousSAPoints.size() < 2)
const QVector<QPointF> intersections = VAbstractCurve::CurveIntersectLine(SeamAllowancePoints(data), line);
if (intersections.isEmpty())
{
const QLineF::IntersectType type = line.intersect(bigLine1, &p);
if (type == QLineF::NoIntersection)
{
p = passmarkSAPoint;
}
}
else
{
line.setLength(line.length() + passmarkSAPoint.GetSABefore(width)*2);
QVector<VSAPoint> vector;
vector << previousSAPoints;
vector.append(passmarkSAPoint);
vector << nextSAPoints;
const QVector<QPointF> curvePoints = ParallelCurve(vector, width);
const QVector<QPointF> intersections = VAbstractCurve::CurveIntersectLine(curvePoints, line);
if (intersections.isEmpty())
{
return QVector<QLineF>(); // Something wrong
}
p = intersections.last();
return QVector<QLineF>(); // Something wrong
}
line = QLineF(p, passmarkSAPoint);
line = QLineF(intersections.last(), passmarkSAPoint);
line.setLength(qMin(passmarkSAPoint.GetSABefore(width) * passmarkFactor, maxPassmarkLength));
passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line);

View file

@ -129,10 +129,10 @@ private:
QVector<VSAPoint> GetNodeSAPoints(const QVector<VPieceNode> &path, int index, const VContainer *data) const;
bool GetPassmarkSAPoint(const QVector<VPieceNode> &path, int index, const VContainer *data, VSAPoint &point) const;
int GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, QVector<VSAPoint> &points) const;
bool GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, VSAPoint &point) const;
int GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, QVector<VSAPoint> &points) const;
const VContainer *data, VSAPoint &point) const;
bool GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, const VSAPoint &passmarkSAPoint,
const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const;
@ -140,10 +140,9 @@ private:
QVector<QLineF> CreatePassmark(const QVector<VPieceNode> &path, int previousIndex, int passmarkIndex, int nextIndex,
const VContainer *data) const;
QVector<QLineF> SAPassmark(const QVector<VPieceNode> &path, const QVector<VSAPoint> &previousSAPoints,
const int previousSAPointIndex, const VSAPoint &passmarkSAPoint,
const QVector<VSAPoint> &nextSAPoints, const int nextSAPointIndex,
const VContainer *data, int passmarkIndex) const;
QVector<QLineF> SAPassmark(const QVector<VPieceNode> &path, VSAPoint &previousSAPoint,
const VSAPoint &passmarkSAPoint, VSAPoint &nextSAPoint, const VContainer *data,
int passmarkIndex) const;
QVector<QLineF> BuiltInSAPassmark(const QVector<VPieceNode> &path, const VSAPoint &previousSAPoint,
const VSAPoint &passmarkSAPoint, const VSAPoint &nextSAPoint,
const VContainer *data, int passmarkIndex) const;

View file

@ -386,8 +386,7 @@ VSAPoint VPiecePath::StartSegment(const VContainer *data, const QVector<VPieceNo
if (nodes.size() > 1)
{
int index = 0;
i == 0 ? index = FindInLoopNotExcludedUp(nodes.size()-1, nodes) : index = FindInLoopNotExcludedUp(i-1, nodes);
const int index = FindInLoopNotExcludedUp(i, nodes);
if (index != i && index != -1)
{
@ -418,8 +417,7 @@ VSAPoint VPiecePath::EndSegment(const VContainer *data, const QVector<VPieceNode
if (nodes.size() > 2)
{
int index = 0;
i == nodes.size()-1 ? index=FindInLoopNotExcludedDown(0, nodes) : index=FindInLoopNotExcludedDown(i+1, nodes);
const int index = FindInLoopNotExcludedDown(i, nodes);
if (index != i && index != -1)
{
@ -775,19 +773,33 @@ int VPiecePath::indexOfNode(const QVector<VPieceNode> &nodes, quint32 id)
}
//---------------------------------------------------------------------------------------------------------------------
int VPiecePath::FindInLoopNotExcludedUp(int candidate, const QVector<VPieceNode> &nodes)
int VPiecePath::FindInLoopNotExcludedUp(int start, const QVector<VPieceNode> &nodes)
{
if (candidate < 0 || candidate >= nodes.size())
if (start < 0 || start >= nodes.size())
{
return -1;
}
int i = (start == 0) ? nodes.size()-1 : start-1;
if (i < 0 || i >= nodes.size())
{
return -1;
}
int checked = 0;
int i = candidate;
bool found = false;
do
{
if (not nodes.at(i).IsExcluded())
if (not nodes.at(i).IsExcluded()
&& (not nodes.at(start).IsMainPathNode()
|| (nodes.at(start).IsMainPathNode()
&& nodes.at(start).GetPassmarkAngleType() != PassmarkAngleType::Intersection)
|| (nodes.at(start).IsMainPathNode()
&& nodes.at(start).GetPassmarkAngleType() == PassmarkAngleType::Intersection
&& nodes.at(i).IsMainPathNode())))
{
found = true;
break;
}
@ -799,23 +811,37 @@ int VPiecePath::FindInLoopNotExcludedUp(int candidate, const QVector<VPieceNode>
}
} while (checked < nodes.size());
return i;
return (not found) ? -1 : i;
}
//---------------------------------------------------------------------------------------------------------------------
int VPiecePath::FindInLoopNotExcludedDown(int candidate, const QVector<VPieceNode> &nodes)
int VPiecePath::FindInLoopNotExcludedDown(int start, const QVector<VPieceNode> &nodes)
{
if (candidate < 0 || candidate >= nodes.size())
if (start < 0 || start >= nodes.size())
{
return -1;
}
int i = (start == nodes.size()-1) ? 0 : start+1;
if (i < 0 || i >= nodes.size())
{
return -1;
}
int checked = 0;
int i = candidate;
bool found = false;
do
{
if (not nodes.at(i).IsExcluded())
if (not nodes.at(i).IsExcluded()
&& (not nodes.at(start).IsMainPathNode()
|| (nodes.at(start).IsMainPathNode()
&& nodes.at(start).GetPassmarkAngleType() != PassmarkAngleType::Intersection)
|| (nodes.at(start).IsMainPathNode()
&& nodes.at(start).GetPassmarkAngleType() == PassmarkAngleType::Intersection
&& nodes.at(i).IsMainPathNode())))
{
found = true;
break;
}
@ -827,7 +853,7 @@ int VPiecePath::FindInLoopNotExcludedDown(int candidate, const QVector<VPieceNod
}
} while (checked < nodes.size());
return i;
return (not found) ? -1 : i;
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -104,8 +104,8 @@ public:
static int indexOfNode(const QVector<VPieceNode> &nodes, quint32 id);
static int FindInLoopNotExcludedUp(int candidate, const QVector<VPieceNode> &nodes);
static int FindInLoopNotExcludedDown(int candidate, const QVector<VPieceNode> &nodes);
static int FindInLoopNotExcludedUp(int start, const QVector<VPieceNode> &nodes);
static int FindInLoopNotExcludedDown(int start, const QVector<VPieceNode> &nodes);
static VSAPoint StartSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse);
static VSAPoint EndSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse);