Improve segmenting a curve for calculating a piece path.

This commit is contained in:
Roman Telezhynskyi 2022-10-15 18:20:49 +03:00
parent 867400332f
commit 704bbecd2e
3 changed files with 94 additions and 62 deletions

View File

@ -5,6 +5,7 @@
- [smart-pattern/valentina#187] Puzzle: message "Invalid version: Max supported version 0.1.2" when opening 0.1.1 file in Val 0.7.52. - [smart-pattern/valentina#187] Puzzle: message "Invalid version: Max supported version 0.1.2" when opening 0.1.1 file in Val 0.7.52.
- Fix export measurement separator to CSV. - Fix export measurement separator to CSV.
- Fix option Hide labels. - Fix option Hide labels.
- Improve segmenting a curve for calculating a piece path.
# Valentina 0.7.52 September 12, 2022 # Valentina 0.7.52 September 12, 2022
- Fix crash when default locale is ru. - Fix crash when default locale is ru.

View File

@ -67,22 +67,34 @@ VSAPoint CurveStartPoint(VSAPoint candidate, const VContainer *data, const VPiec
{ {
return CurvePoint(candidate, data, node, curvePoints); return CurvePoint(candidate, data, node, curvePoints);
} }
else
{
// See issue #620. Detail path not correct. Previous curve also should cut segment. // See issue #620. Detail path not correct. Previous curve also should cut segment.
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId());
const QVector<QPointF> points = curve->GetPoints(); const QVector<QPointF> points = curve->GetPoints();
if (not points.isEmpty())
if (points.isEmpty())
{ {
QPointF end; // Last point for this curve show start of next segment return candidate;
node.GetReverse() ? end = ConstFirst(points) : end = ConstLast(points); }
if (VAbstractCurve::IsPointOnCurve(curvePoints, end))
QVector<QPointF> intersections;
for (auto i = 0; i < curvePoints.count()-1; ++i)
{ {
candidate = VSAPoint(end); QLineF segment(curvePoints.at(i), curvePoints.at(i+1));
intersections << VAbstractCurve::CurveIntersectLine(points, segment);
} }
for(auto &p : intersections)
{
if (VFuzzyComparePoints(p, ConstFirst(curvePoints)) || VFuzzyComparePoints(p, ConstLast(curvePoints)))
{
continue;
} }
candidate = VSAPoint(p);
break;
} }
return candidate; return candidate;
} }
@ -94,22 +106,34 @@ VSAPoint CurveEndPoint(VSAPoint candidate, const VContainer *data, const VPieceN
{ {
return CurvePoint(candidate, data, node, curvePoints); return CurvePoint(candidate, data, node, curvePoints);
} }
else
{
// See issue #620. Detail path not correct. Previous curve also should cut segment. // See issue #620. Detail path not correct. Previous curve also should cut segment.
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId());
const QVector<QPointF> points = curve->GetPoints(); const QVector<QPointF> points = curve->GetPoints();
if (not points.isEmpty())
if (points.isEmpty())
{ {
QPointF begin;// First point for this curve show finish of previous segment return candidate;
node.GetReverse() ? begin = ConstLast(points) : begin = ConstFirst(points); }
if (VAbstractCurve::IsPointOnCurve(curvePoints, begin))
QVector<QPointF> intersections;
for (auto i = 0; i < curvePoints.count()-1; ++i)
{ {
candidate = VSAPoint(begin); QLineF segment(curvePoints.at(i), curvePoints.at(i+1));
intersections << VAbstractCurve::CurveIntersectLine(points, segment);
} }
for(auto &p : intersections)
{
if (VFuzzyComparePoints(p, ConstFirst(curvePoints)) || VFuzzyComparePoints(p, ConstLast(curvePoints)))
{
continue;
} }
candidate = VSAPoint(p);
break;
} }
return candidate; return candidate;
} }
@ -461,8 +485,8 @@ QVector<QVector<QPointF> > VPiecePath::PathCurvePoints(const VContainer *data) c
{ {
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).GetId());
const QPointF begin = StartSegment(data, i, at(i).GetReverse()); const QPointF begin = StartSegment(data, i);
const QPointF end = EndSegment(data, i, at(i).GetReverse()); const QPointF end = EndSegment(data, i);
curves.append(curve->GetSegmentPoints(begin, end, at(i).GetReverse(), GetName())); curves.append(curve->GetSegmentPoints(begin, end, at(i).GetReverse(), GetName()));
break; break;
@ -536,23 +560,27 @@ QVector<QPainterPath> VPiecePath::CurvesPainterPath(const VContainer *data) cons
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VSAPoint VPiecePath::StartSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse) VSAPoint VPiecePath::StartSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i)
{ {
if (i < 0 || i > nodes.size()-1) if (i < 0 || i > nodes.size()-1)
{ {
return VSAPoint(); return {};
} }
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(nodes.at(i).GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(nodes.at(i).GetId());
const QVector<QPointF> points = curve->GetPoints(); QVector<QPointF> points = curve->GetPoints();
if (points.isEmpty()) if (points.isEmpty())
{ {
return VSAPoint(); return {};
} }
VSAPoint begin; if (nodes.at(i).GetReverse())
reverse ? begin = VSAPoint(ConstLast(points)) : begin = VSAPoint(ConstFirst(points)); {
points = Reverse(points);
}
VSAPoint begin(ConstFirst(points));
if (nodes.size() > 1) if (nodes.size() > 1)
{ {
@ -567,23 +595,27 @@ VSAPoint VPiecePath::StartSegment(const VContainer *data, const QVector<VPieceNo
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VSAPoint VPiecePath::EndSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i, bool reverse) VSAPoint VPiecePath::EndSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i)
{ {
if (i < 0 || i > nodes.size()-1) if (i < 0 || i > nodes.size()-1)
{ {
return VSAPoint(); return {};
} }
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(nodes.at(i).GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(nodes.at(i).GetId());
const QVector<QPointF> points = curve->GetPoints(); QVector<QPointF> points = curve->GetPoints();
if (points.isEmpty()) if (points.isEmpty())
{ {
return VSAPoint(); return {};
} }
VSAPoint end; if (nodes.at(i).GetReverse())
reverse ? end = VSAPoint(ConstFirst(points)) : end = VSAPoint(ConstLast(points)); {
points = Reverse(points);
}
VSAPoint end(ConstLast(points));
if (nodes.size() > 2) if (nodes.size() > 2)
{ {
@ -836,15 +868,15 @@ VPiecePath VPiecePath::RemoveEdge(quint32 index) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VSAPoint VPiecePath::StartSegment(const VContainer *data, int i, bool reverse) const VSAPoint VPiecePath::StartSegment(const VContainer *data, int i) const
{ {
return StartSegment(data, d->m_nodes, i, reverse); return StartSegment(data, d->m_nodes, i);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VSAPoint VPiecePath::EndSegment(const VContainer *data, int i, bool reverse) const VSAPoint VPiecePath::EndSegment(const VContainer *data, int i) const
{ {
return EndSegment(data, d->m_nodes, i, reverse); return EndSegment(data, d->m_nodes, i);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -879,8 +911,8 @@ QPointF VPiecePath::NodePreviousPoint(const VContainer *data, int i) const
{ {
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId());
const VSAPoint begin = StartSegment(data, d->m_nodes, index, node.GetReverse()); const VSAPoint begin = StartSegment(data, d->m_nodes, index);
const VSAPoint end = EndSegment(data, d->m_nodes, index, node.GetReverse()); const VSAPoint end = EndSegment(data, d->m_nodes, index);
const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, node.GetReverse(), GetName()); const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, node.GetReverse(), GetName());
if (points.size() > 1) if (points.size() > 1)
@ -931,8 +963,8 @@ QPointF VPiecePath::NodeNextPoint(const VContainer *data, int i) const
{ {
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId());
const VSAPoint begin = StartSegment(data, d->m_nodes, index, node.GetReverse()); const VSAPoint begin = StartSegment(data, d->m_nodes, index);
const VSAPoint end = EndSegment(data, d->m_nodes, index, node.GetReverse()); const VSAPoint end = EndSegment(data, d->m_nodes, index);
const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, node.GetReverse(), GetName()); const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, node.GetReverse(), GetName());
if (points.size() > 1) if (points.size() > 1)
@ -1086,17 +1118,16 @@ QVector<VSAPoint> VPiecePath::CurveSeamAllowanceSegment(const VContainer *data,
const QSharedPointer<VAbstractCurve> &curve, int i, const QSharedPointer<VAbstractCurve> &curve, int i,
bool reverse, qreal width, const QString &piece) bool reverse, qreal width, const QString &piece)
{ {
QVector<VSAPoint> pointsEkv; const VSAPoint begin = StartSegment(data, nodes, i);
const VSAPoint end = EndSegment(data, nodes, i);
const VSAPoint begin = StartSegment(data, nodes, i, reverse);
const VSAPoint end = EndSegment(data, nodes, i, reverse);
const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, reverse, piece); const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, reverse, piece);
if (points.isEmpty()) if (points.isEmpty())
{ {
return pointsEkv; return {};
} }
QVector<VSAPoint> pointsEkv;
pointsEkv.reserve(points.size()); pointsEkv.reserve(points.size());
qreal w1 = begin.GetSAAfter(); qreal w1 = begin.GetSAAfter();
@ -1221,8 +1252,8 @@ QVector<QPointF> VPiecePath::NodesToPoints(const VContainer *data, const QVector
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId());
const QPointF begin = StartSegment(data, nodes, i, node.GetReverse()); const QPointF begin = StartSegment(data, nodes, i);
const QPointF end = EndSegment(data, nodes, i, node.GetReverse()); const QPointF end = EndSegment(data, nodes, i);
points << curve->GetSegmentPoints(begin, end, node.GetReverse(), piece); points << curve->GetSegmentPoints(begin, end, node.GetReverse(), piece);
} }

View File

@ -113,8 +113,8 @@ public:
VPiecePath RemoveEdge(quint32 index) const; VPiecePath RemoveEdge(quint32 index) const;
VSAPoint StartSegment(const VContainer *data, int i, bool reverse) const; VSAPoint StartSegment(const VContainer *data, int i) const;
VSAPoint EndSegment(const VContainer *data, int i, bool reverse) const; VSAPoint EndSegment(const VContainer *data, int i) const;
QPointF NodePreviousPoint(const VContainer *data, int i) const; QPointF NodePreviousPoint(const VContainer *data, int i) const;
QPointF NodeNextPoint(const VContainer *data, int i) const; QPointF NodeNextPoint(const VContainer *data, int i) const;
@ -126,8 +126,8 @@ public:
static int FindInLoopNotExcludedUp(int start, const QVector<VPieceNode> &nodes); static int FindInLoopNotExcludedUp(int start, const QVector<VPieceNode> &nodes);
static int FindInLoopNotExcludedDown(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 StartSegment(const VContainer *data, const QVector<VPieceNode> &nodes, int i);
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);
static VSAPoint PreparePointEkv(const VPieceNode &node, const VContainer *data); static VSAPoint PreparePointEkv(const VPieceNode &node, const VContainer *data);