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; 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) 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, static QVector<QPointF> EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1,
const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width); const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width);
static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, 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> 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);

View File

@ -428,29 +428,10 @@ QVector<QLineF> VPiece::PassmarksLines(const VContainer *data) const
continue;// skip node continue;// skip node
} }
int passmarkIndex = i; const int previousIndex = VPiecePath::FindInLoopNotExcludedUp(i, unitedPath);
const int nextIndex = VPiecePath::FindInLoopNotExcludedDown(i, unitedPath);
int previousIndex = 0; passmarks += CreatePassmark(unitedPath, previousIndex, i, nextIndex, data);
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);
} }
return passmarks; 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, bool VPiece::GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, QVector<VSAPoint> &points) const const VContainer *data, VSAPoint &point) const
{ {
SCASSERT(data != nullptr) 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; bool found = false;
int nodeIndex = saPoints.size()-1; int nodeIndex = points.size()-1;
do do
{ {
const VSAPoint previous = saPoints.at(nodeIndex); const VSAPoint previous = points.at(nodeIndex);
if (passmarkSAPoint.toPoint() != previous.toPoint()) if (passmarkSAPoint.toPoint() != previous.toPoint())
{ {
saIndex = nodeIndex; point = previous;
found = true; found = true;
} }
--nodeIndex; --nodeIndex;
@ -964,44 +944,43 @@ int VPiece::GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int ind
if (not found) if (not found)
{ {
return -1; // Something wrong return false; // Something wrong
} }
points = saPoints; return true;
return saIndex;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
int VPiece::GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint, 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; bool found = false;
int nodeIndex = 0; int nodeIndex = 0;
do do
{ {
const VSAPoint next = saPoints.at(nodeIndex); const VSAPoint next = points.at(nodeIndex);
if (passmarkSAPoint.toPoint() != next.toPoint()) if (passmarkSAPoint.toPoint() != next.toPoint())
{ {
saIndex = nodeIndex; point = next;
found = true; found = true;
} }
++nodeIndex; ++nodeIndex;
} while (nodeIndex < saPoints.size() && not found); } while (nodeIndex < points.size() && not found);
if (not found) if (not found)
{ {
return -1; // Something wrong return false; // Something wrong
} }
points = saPoints; return true;
return saIndex;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1099,17 +1078,15 @@ QVector<QLineF> VPiece::CreatePassmark(const QVector<VPieceNode> &path, int prev
return QVector<QLineF>(); // Something wrong return QVector<QLineF>(); // Something wrong
} }
QVector<VSAPoint> previousSAPoints; VSAPoint previousSAPoint;
const int previousSAPointIndex = GetPassmarkPreviousSAPoints(path, previousIndex, passmarkSAPoint, data, if (not GetPassmarkPreviousSAPoints(path, previousIndex, passmarkSAPoint, data,
previousSAPoints); previousSAPoint))
if (previousSAPointIndex == -1)
{ {
return QVector<QLineF>(); // Something wrong return QVector<QLineF>(); // Something wrong
} }
QVector<VSAPoint> nextSAPoints; VSAPoint nextSAPoint;
const int nextSAPointIndex = GetPassmarkNextSAPoints(path, nextIndex, passmarkSAPoint, data, nextSAPoints); if (not GetPassmarkNextSAPoints(path, nextIndex, passmarkSAPoint, data, nextSAPoint))
if (nextSAPointIndex == -1)
{ {
return QVector<QLineF>(); // Something wrong return QVector<QLineF>(); // Something wrong
} }
@ -1117,33 +1094,26 @@ QVector<QLineF> VPiece::CreatePassmark(const QVector<VPieceNode> &path, int prev
if (not IsSeamAllowanceBuiltIn()) if (not IsSeamAllowanceBuiltIn())
{ {
QVector<QLineF> lines; QVector<QLineF> lines;
lines += SAPassmark(path, previousSAPoints, previousSAPointIndex, passmarkSAPoint, nextSAPoints, lines += SAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex);
nextSAPointIndex, data, passmarkIndex);
if (qApp->Settings()->IsDoublePassmark() if (qApp->Settings()->IsDoublePassmark()
&& path.at(passmarkIndex).IsMainPathNode() && path.at(passmarkIndex).IsMainPathNode()
&& path.at(passmarkIndex).GetPassmarkAngleType() != PassmarkAngleType::Intersection) && path.at(passmarkIndex).GetPassmarkAngleType() != PassmarkAngleType::Intersection)
{ {
lines += BuiltInSAPassmark(path, previousSAPoints.at(previousSAPointIndex), passmarkSAPoint, lines += BuiltInSAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex);
nextSAPoints.at(nextSAPointIndex), data, passmarkIndex);
} }
return lines; return lines;
} }
else else
{ {
return BuiltInSAPassmark(path, previousSAPoints.at(previousSAPointIndex), passmarkSAPoint, return BuiltInSAPassmark(path, previousSAPoint, passmarkSAPoint, nextSAPoint, data, passmarkIndex);
nextSAPoints.at(nextSAPointIndex), data, passmarkIndex);
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVector<VSAPoint> &previousSAPoints, QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, VSAPoint &previousSAPoint,
const int previousSAPointIndex, const VSAPoint &passmarkSAPoint, const VSAPoint &passmarkSAPoint, VSAPoint &nextSAPoint, const VContainer *data,
const QVector<VSAPoint> &nextSAPoints, const int nextSAPointIndex, int passmarkIndex) const
const VContainer *data, int passmarkIndex) const
{ {
const VSAPoint &previousSAPoint = previousSAPoints.at(previousSAPointIndex);
const VSAPoint &nextSAPoint = nextSAPoints.at(nextSAPointIndex);
QPointF seamPassmarkSAPoint; QPointF seamPassmarkSAPoint;
if (not GetSeamPassmarkSAPoint(previousSAPoint, passmarkSAPoint, nextSAPoint, data, 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 qreal width = ToPixel(GetSAWidth(), *data->GetPatternUnit());
const QLineF bigLine1 = ParallelLine(previousSAPoint, passmarkSAPoint, width );
const QLineF bigLine2 = ParallelLine(passmarkSAPoint, nextSAPoint, width );
QVector<QLineF> passmarksLines; QVector<QLineF> passmarksLines;
@ -1167,6 +1135,9 @@ QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVecto
} }
else if (node.GetPassmarkAngleType() == PassmarkAngleType::Bisector) 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 edge1 = QLineF(seamPassmarkSAPoint, bigLine1.p1());
QLineF edge2 = QLineF(seamPassmarkSAPoint, bigLine2.p2()); QLineF edge2 = QLineF(seamPassmarkSAPoint, bigLine2.p2());
@ -1179,38 +1150,16 @@ QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVecto
{ {
{ {
// first passmark // first passmark
QPointF p;
QLineF line(previousSAPoint, passmarkSAPoint); 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);
{
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()) if (intersections.isEmpty())
{ {
return QVector<QLineF>(); // Something wrong return QVector<QLineF>(); // Something wrong
} }
p = intersections.first(); line = QLineF(intersections.first(), passmarkSAPoint);
}
line = QLineF(p, passmarkSAPoint);
line.setLength(qMin(passmarkSAPoint.GetSAAfter(width) * passmarkFactor, maxPassmarkLength)); line.setLength(qMin(passmarkSAPoint.GetSAAfter(width) * passmarkFactor, maxPassmarkLength));
passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line); passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line);
@ -1218,38 +1167,17 @@ QVector<QLineF> VPiece::SAPassmark(const QVector<VPieceNode> &path, const QVecto
{ {
// second passmark // second passmark
QPointF p;
QLineF line(nextSAPoint, passmarkSAPoint); 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);
{
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()) if (intersections.isEmpty())
{ {
return QVector<QLineF>(); // Something wrong return QVector<QLineF>(); // Something wrong
} }
p = intersections.last(); line = QLineF(intersections.last(), passmarkSAPoint);
}
line = QLineF(p, passmarkSAPoint);
line.setLength(qMin(passmarkSAPoint.GetSABefore(width) * passmarkFactor, maxPassmarkLength)); line.setLength(qMin(passmarkSAPoint.GetSABefore(width) * passmarkFactor, maxPassmarkLength));
passmarksLines += CreatePassmarkLines(node.GetPassmarkLineType(), node.GetPassmarkAngleType(), line); 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; 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; 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, bool GetPassmarkPreviousSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint,
const VContainer *data, QVector<VSAPoint> &points) const; const VContainer *data, VSAPoint &point) const;
int GetPassmarkNextSAPoints(const QVector<VPieceNode> &path, int index, const VSAPoint &passmarkSAPoint, 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, bool GetSeamPassmarkSAPoint(const VSAPoint &previousSAPoint, const VSAPoint &passmarkSAPoint,
const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const; 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, QVector<QLineF> CreatePassmark(const QVector<VPieceNode> &path, int previousIndex, int passmarkIndex, int nextIndex,
const VContainer *data) const; const VContainer *data) const;
QVector<QLineF> SAPassmark(const QVector<VPieceNode> &path, const QVector<VSAPoint> &previousSAPoints, QVector<QLineF> SAPassmark(const QVector<VPieceNode> &path, VSAPoint &previousSAPoint,
const int previousSAPointIndex, const VSAPoint &passmarkSAPoint, const VSAPoint &passmarkSAPoint, VSAPoint &nextSAPoint, const VContainer *data,
const QVector<VSAPoint> &nextSAPoints, const int nextSAPointIndex, int passmarkIndex) const;
const VContainer *data, int passmarkIndex) const;
QVector<QLineF> BuiltInSAPassmark(const QVector<VPieceNode> &path, const VSAPoint &previousSAPoint, QVector<QLineF> BuiltInSAPassmark(const QVector<VPieceNode> &path, const VSAPoint &previousSAPoint,
const VSAPoint &passmarkSAPoint, const VSAPoint &nextSAPoint, const VSAPoint &passmarkSAPoint, const VSAPoint &nextSAPoint,
const VContainer *data, int passmarkIndex) const; 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) if (nodes.size() > 1)
{ {
int index = 0; const int index = FindInLoopNotExcludedUp(i, nodes);
i == 0 ? index = FindInLoopNotExcludedUp(nodes.size()-1, nodes) : index = FindInLoopNotExcludedUp(i-1, nodes);
if (index != i && index != -1) if (index != i && index != -1)
{ {
@ -418,8 +417,7 @@ VSAPoint VPiecePath::EndSegment(const VContainer *data, const QVector<VPieceNode
if (nodes.size() > 2) if (nodes.size() > 2)
{ {
int index = 0; const int index = FindInLoopNotExcludedDown(i, nodes);
i == nodes.size()-1 ? index=FindInLoopNotExcludedDown(0, nodes) : index=FindInLoopNotExcludedDown(i+1, nodes);
if (index != i && index != -1) 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; return -1;
} }
int checked = 0; int checked = 0;
int i = candidate; bool found = false;
do 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; break;
} }
@ -799,23 +811,37 @@ int VPiecePath::FindInLoopNotExcludedUp(int candidate, const QVector<VPieceNode>
} }
} while (checked < nodes.size()); } 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; return -1;
} }
int checked = 0; int checked = 0;
int i = candidate; bool found = false;
do 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; break;
} }
@ -827,7 +853,7 @@ int VPiecePath::FindInLoopNotExcludedDown(int candidate, const QVector<VPieceNod
} }
} while (checked < nodes.size()); } 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 indexOfNode(const QVector<VPieceNode> &nodes, quint32 id);
static int FindInLoopNotExcludedUp(int candidate, const QVector<VPieceNode> &nodes); static int FindInLoopNotExcludedUp(int start, const QVector<VPieceNode> &nodes);
static int FindInLoopNotExcludedDown(int candidate, 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 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); static VSAPoint EndSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse);