New struct VLayoutPassmark to store data about a passmark.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2019-05-27 14:57:36 +03:00
parent bd611bf333
commit 6294dc0748
7 changed files with 319 additions and 133 deletions

View File

@ -732,12 +732,15 @@ void VDxfEngine::ExportAAMANotch(dx_ifaceBlock *detailBlock, const VLayoutPiece
{ {
if (detail.IsSeamAllowance()) if (detail.IsSeamAllowance())
{ {
const QVector<QLineF> passmarks = detail.GetPassmarks(); const QVector<VLayoutPassmark> passmarks = detail.GetPassmarks();
for(auto passmark : passmarks) for(auto &passmark : passmarks)
{ {
if (DRW_Entity *e = AAMALine(passmark, QChar('4'))) for (auto &line : passmark.lines)
{ {
detailBlock->ent.push_back(e); if (DRW_Entity *e = AAMALine(line, QChar('4')))
{
detailBlock->ent.push_back(e);
}
} }
} }
} }

View File

@ -80,5 +80,15 @@ struct VLayoutPlaceLabel
QTransform rotationMatrix{}; QTransform rotationMatrix{};
QRectF box{}; QRectF box{};
}; };
Q_DECLARE_METATYPE(VLayoutPlaceLabel)
struct VLayoutPassmark
{
QVector<QLineF> lines{};
PassmarkLineType type{PassmarkLineType::OneLine};
QLineF baseLine{};
bool isBuiltIn{false};
};
Q_DECLARE_METATYPE(VLayoutPassmark)
#endif // VGEOMETRYDEF_H #endif // VGEOMETRYDEF_H

View File

@ -50,6 +50,7 @@
#include "../vmisc/vmath.h" #include "../vmisc/vmath.h"
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include "../vpatterndb/calculator.h" #include "../vpatterndb/calculator.h"
#include "../vpatterndb/vpassmark.h"
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vgeometry/vplacelabelitem.h" #include "../vgeometry/vplacelabelitem.h"
#include "vlayoutdef.h" #include "vlayoutdef.h"
@ -227,6 +228,108 @@ QVector<VLayoutPlaceLabel> ConvertPlaceLabels(const VPiece &piece, const VContai
} }
return labels; return labels;
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<VLayoutPassmark> ConvertPassmarks(const VPiece &piece, const VContainer *pattern)
{
const QVector<VPassmark> passmarks = piece.Passmarks(pattern);
QVector<VLayoutPassmark> layoutPassmarks;
for(auto &passmark : passmarks)
{
if (not passmark.IsNull())
{
VPiecePassmarkData pData = passmark.Data();
auto PreapreBuiltInSAPassmark = [pData, passmark, piece, &layoutPassmarks, pattern]()
{
VLayoutPassmark layoutPassmark;
VPiecePath path = piece.GetPath();
const int nodeIndex = path.indexOfNode(pData.id);
if (nodeIndex != -1)
{
layoutPassmark.lines = passmark.BuiltInSAPassmark(piece, pattern);
layoutPassmark.baseLine = passmark.BuiltInSAPassmarkBaseLine(piece);
layoutPassmark.type = pData.passmarkLineType;
layoutPassmark.isBuiltIn = true;
layoutPassmarks.append(layoutPassmark);
}
};
auto PrepareSAPassmark = [pData, passmark, piece, &layoutPassmarks, pattern](PassmarkSide side)
{
VLayoutPassmark layoutPassmark;
VPiecePath path = piece.GetPath();
const int nodeIndex = path.indexOfNode(pData.id);
if (nodeIndex != -1)
{
layoutPassmark.lines = passmark.SAPassmark(piece, pattern, static_cast<PassmarkSide>(side));
layoutPassmark.baseLine =
passmark.SAPassmarkBaseLine(piece, pattern, static_cast<PassmarkSide>(side));
layoutPassmark.type = pData.passmarkLineType;
layoutPassmark.isBuiltIn = false;
layoutPassmarks.append(layoutPassmark);
}
};
if (not piece.IsSeamAllowanceBuiltIn())
{
if (pData.passmarkAngleType == PassmarkAngleType::Straightforward
|| pData.passmarkAngleType == PassmarkAngleType::Bisector)
{
PrepareSAPassmark(PassmarkSide::All);
}
else if (pData.passmarkAngleType == PassmarkAngleType::Intersection
|| pData.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft
|| pData.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight
|| pData.passmarkAngleType == PassmarkAngleType::Intersection2
|| pData.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft
|| pData.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight)
{
if (pData.passmarkAngleType == PassmarkAngleType::Intersection ||
pData.passmarkAngleType == PassmarkAngleType::Intersection2)
{
PrepareSAPassmark(PassmarkSide::Left);
PrepareSAPassmark(PassmarkSide::Right);
}
else if (pData.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft ||
pData.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft)
{
PrepareSAPassmark(PassmarkSide::Left);
}
else if (pData.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight ||
pData.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight)
{
PrepareSAPassmark(PassmarkSide::Right);
}
}
if (qApp->Settings()->IsDoublePassmark()
&& not piece.IsHideMainPath()
&& pData.isMainPathNode
&& pData.passmarkAngleType != PassmarkAngleType::Intersection
&& pData.passmarkAngleType != PassmarkAngleType::IntersectionOnlyLeft
&& pData.passmarkAngleType != PassmarkAngleType::IntersectionOnlyRight
&& pData.passmarkAngleType != PassmarkAngleType::Intersection2
&& pData.passmarkAngleType != PassmarkAngleType::Intersection2OnlyLeft
&& pData.passmarkAngleType != PassmarkAngleType::Intersection2OnlyRight
&& pData.isShowSecondPassmark)
{
PreapreBuiltInSAPassmark();
}
}
else
{
PreapreBuiltInSAPassmark();
}
}
}
return layoutPassmarks;
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -262,7 +365,7 @@ VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern
QFuture<bool> futureSeamAllowanceValid = QtConcurrent::run(piece, &VPiece::IsSeamAllowanceValid, pattern); QFuture<bool> futureSeamAllowanceValid = QtConcurrent::run(piece, &VPiece::IsSeamAllowanceValid, pattern);
QFuture<QVector<QPointF> > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern); QFuture<QVector<QPointF> > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern);
QFuture<QVector<VLayoutPiecePath> > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern); QFuture<QVector<VLayoutPiecePath> > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern);
QFuture<QVector<QLineF> > futurePassmarksLines = QtConcurrent::run(piece, &VPiece::PassmarksLines, pattern); QFuture<QVector<VLayoutPassmark> > futurePassmarks = QtConcurrent::run(ConvertPassmarks, piece, pattern);
QFuture<QVector<VLayoutPlaceLabel> > futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern); QFuture<QVector<VLayoutPlaceLabel> > futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern);
VLayoutPiece det; VLayoutPiece det;
@ -286,7 +389,7 @@ VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern
det.SetCountourPoints(futureMainPath.result(), piece.IsHideMainPath()); det.SetCountourPoints(futureMainPath.result(), piece.IsHideMainPath());
det.SetSeamAllowancePoints(futureSeamAllowance.result(), piece.IsSeamAllowance(), piece.IsSeamAllowanceBuiltIn()); det.SetSeamAllowancePoints(futureSeamAllowance.result(), piece.IsSeamAllowance(), piece.IsSeamAllowanceBuiltIn());
det.SetInternalPaths(futureInternalPaths.result()); det.SetInternalPaths(futureInternalPaths.result());
det.SetPassmarks(futurePassmarksLines.result()); det.SetPassmarks(futurePassmarks.result());
det.SetPlaceLabels(futurePlaceLabels.result()); det.SetPlaceLabels(futurePlaceLabels.result());
// Very important to set main path first! // Very important to set main path first!
@ -344,13 +447,24 @@ QVector<VLayoutPlaceLabel> VLayoutPiece::Map<VLayoutPlaceLabel>(QVector<VLayoutP
{ {
for (int i = 0; i < points.size(); ++i) for (int i = 0; i < points.size(); ++i)
{ {
points[i].center = d->matrix.map(points.at(i).center);
points[i].shape = Map(points.at(i).shape); points[i].shape = Map(points.at(i).shape);
} }
return points; return points;
} }
//---------------------------------------------------------------------------------------------------------------------
template <>
QVector<VLayoutPassmark> VLayoutPiece::Map<VLayoutPassmark>(QVector<VLayoutPassmark> passmarks) const
{
for (int i = 0; i < passmarks.size(); ++i)
{
passmarks[i].lines = Map(passmarks.at(i).lines);
}
return passmarks;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
QVector<QPointF> VLayoutPiece::GetContourPoints() const QVector<QPointF> VLayoutPiece::GetContourPoints() const
@ -765,13 +879,13 @@ void VLayoutPiece::SetLayoutAllowancePoints()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VLayoutPiece::GetPassmarks() const QVector<VLayoutPassmark> VLayoutPiece::GetPassmarks() const
{ {
return Map(d->passmarks); return Map(d->passmarks);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetPassmarks(const QVector<QLineF> &passmarks) void VLayoutPiece::SetPassmarks(const QVector<VLayoutPassmark> &passmarks)
{ {
if (IsSeamAllowance()) if (IsSeamAllowance())
{ {
@ -854,12 +968,15 @@ QPainterPath VLayoutPiece::ContourPath() const
} }
// Draw passmarks // Draw passmarks
const QVector<QLineF> passmarks = GetPassmarks();
QPainterPath passmaksPath; QPainterPath passmaksPath;
for (qint32 i = 0; i < passmarks.count(); ++i) const QVector<VLayoutPassmark> passmarks = GetPassmarks();
for(auto &passmark : passmarks)
{ {
passmaksPath.moveTo(passmarks.at(i).p1()); for (auto &line : passmark.lines)
passmaksPath.lineTo(passmarks.at(i).p2()); {
passmaksPath.moveTo(line.p1());
passmaksPath.lineTo(line.p2());
}
} }
path.addPath(passmaksPath); path.addPath(passmaksPath);

View File

@ -83,8 +83,8 @@ public:
QVector<QPointF> GetLayoutAllowancePoints() const; QVector<QPointF> GetLayoutAllowancePoints() const;
void SetLayoutAllowancePoints(); void SetLayoutAllowancePoints();
QVector<QLineF> GetPassmarks() const; QVector<VLayoutPassmark> GetPassmarks() const;
void SetPassmarks(const QVector<QLineF> &passmarks); void SetPassmarks(const QVector<VLayoutPassmark> &passmarks);
QVector<VLayoutPlaceLabel> GetPlaceLabels() const; QVector<VLayoutPlaceLabel> GetPlaceLabels() const;
void SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels); void SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels);

View File

@ -103,7 +103,7 @@ public:
QVector<QPointF> layoutAllowance; QVector<QPointF> layoutAllowance;
/** @brief passmarks list of passmakrs. */ /** @brief passmarks list of passmakrs. */
QVector<QLineF> passmarks; QVector<VLayoutPassmark> passmarks;
/** @brief m_internalPaths list of internal paths. */ /** @brief m_internalPaths list of internal paths. */
QVector<VLayoutPiecePath> m_internalPaths; QVector<VLayoutPiecePath> m_internalPaths;

View File

@ -32,22 +32,14 @@
#include "../vgeometry/vabstractcurve.h" #include "../vgeometry/vabstractcurve.h"
#include "../vgeometry/varc.h" #include "../vgeometry/varc.h"
const qreal VPassmark::passmarkRadiusFactor = 0.45;
namespace namespace
{ {
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
PassmarkStatus GetSeamPassmarkSAPoint(VPiecePassmarkData passmarkData, const QVector<QPointF> &seamAllowance, PassmarkStatus GetSeamPassmarkSAPoint(const VPiecePassmarkData &passmarkData, const QVector<QPointF> &seamAllowance,
QPointF &point) QPointF &point)
{ {
// Correct distorsion
if (VGObject::IsPointOnLineSegment(passmarkData.passmarkSAPoint, passmarkData.previousSAPoint,
passmarkData.nextSAPoint))
{
const QPointF p = VGObject::CorrectDistortion(passmarkData.passmarkSAPoint, passmarkData.previousSAPoint,
passmarkData.nextSAPoint);
passmarkData.passmarkSAPoint.setX(p.x());
passmarkData.passmarkSAPoint.setY(p.y());
}
bool needRollback = false; // no need for rollback bool needRollback = false; // no need for rollback
QVector<QPointF> ekvPoints; QVector<QPointF> ekvPoints;
ekvPoints = VAbstractPiece::EkvPoint(ekvPoints, passmarkData.previousSAPoint, passmarkData.passmarkSAPoint, ekvPoints = VAbstractPiece::EkvPoint(ekvPoints, passmarkData.previousSAPoint, passmarkData.passmarkSAPoint,
@ -147,20 +139,6 @@ bool FixNotchPoint(const QVector<QPointF> &seamAllowance, const QPointF &notchBa
} }
const qreal passmarkGap = (1.5/*mm*/ / 25.4) * PrintDPI; const qreal passmarkGap = (1.5/*mm*/ / 25.4) * PrintDPI;
//---------------------------------------------------------------------------------------------------------------------
QLineF FindIntersection(const QLineF &line, const QVector<QPointF> &seamAllowance)
{
QLineF testLine = line;
testLine.setLength(testLine.length()*10);
QVector<QPointF> intersections = VAbstractCurve::CurveIntersectLine(seamAllowance, testLine);
if (not intersections.isEmpty())
{
return QLineF(line.p1(), intersections.last());
}
return line;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> CreateTwoPassmarkLines(const QLineF &line, const QVector<QPointF> &seamAllowance) QVector<QLineF> CreateTwoPassmarkLines(const QLineF &line, const QVector<QPointF> &seamAllowance)
{ {
@ -197,10 +175,10 @@ QVector<QLineF> CreateTwoPassmarkLines(const QLineF &line, const QVector<QPointF
} }
QVector<QLineF> lines; QVector<QLineF> lines;
QLineF seg = FindIntersection(QLineF(l1p2, l1p1), seamAllowance); QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance);
lines.append(QLineF(seg.p2(), seg.p1())); lines.append(QLineF(seg.p2(), seg.p1()));
seg = FindIntersection(QLineF(l2p2, l2p1), seamAllowance); seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance);
lines.append(QLineF(seg.p2(), seg.p1())); lines.append(QLineF(seg.p2(), seg.p1()));
return lines; return lines;
} }
@ -241,12 +219,12 @@ QVector<QLineF> CreateThreePassmarkLines(const QLineF &line, const QVector<QPoin
} }
QVector<QLineF> lines; QVector<QLineF> lines;
QLineF seg = FindIntersection(QLineF(l1p2, l1p1), seamAllowance); QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance);
lines.append(QLineF(seg.p2(), seg.p1())); lines.append(QLineF(seg.p2(), seg.p1()));
lines.append(line); lines.append(line);
seg = FindIntersection(QLineF(l2p2, l2p1), seamAllowance); seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance);
lines.append(QLineF(seg.p2(), seg.p1())); lines.append(QLineF(seg.p2(), seg.p1()));
return lines; return lines;
} }
@ -301,8 +279,8 @@ QVector<QLineF> CreateVMark2Passmark(const QLineF &line, const QVector<QPointF>
l2.setAngle(l2.angle() - 35); l2.setAngle(l2.angle() - 35);
QVector<QLineF> lines; QVector<QLineF> lines;
lines.append(FindIntersection(l1, seamAllowance)); lines.append(VPassmark::FindIntersection(l1, seamAllowance));
lines.append(FindIntersection(l2, seamAllowance)); lines.append(VPassmark::FindIntersection(l2, seamAllowance));
return lines; return lines;
} }
@ -324,12 +302,10 @@ QVector<QLineF> PointsToSegments(const QVector<QPointF> &points)
return lines; return lines;
} }
const qreal passmarkRadiusFactor = 0.45;
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> CreateUMarkPassmark(const QLineF &line, const QVector<QPointF> &seamAllowance) QVector<QLineF> CreateUMarkPassmark(const QLineF &line, const QVector<QPointF> &seamAllowance)
{ {
const qreal radius = line.length() * passmarkRadiusFactor; const qreal radius = line.length() * VPassmark::passmarkRadiusFactor;
QPointF l1p1; QPointF l1p1;
{ {
@ -368,7 +344,7 @@ QVector<QLineF> CreateUMarkPassmark(const QLineF &line, const QVector<QPointF> &
QVector<QPointF> points; QVector<QPointF> points;
QLineF seg = FindIntersection(QLineF(l2p2, l2p1), seamAllowance); QLineF seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance);
seg = QLineF(seg.p2(), seg.p1()); seg = QLineF(seg.p2(), seg.p1());
seg.setLength(seg.length() - radius); seg.setLength(seg.length() - radius);
points.append(seg.p1()); points.append(seg.p1());
@ -378,7 +354,7 @@ QVector<QLineF> CreateUMarkPassmark(const QLineF &line, const QVector<QPointF> &
arc.SetApproximationScale(10); arc.SetApproximationScale(10);
points += arc.GetPoints(); points += arc.GetPoints();
seg = FindIntersection(QLineF(l1p2, l1p1), seamAllowance); seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance);
seg = QLineF(seg.p2(), seg.p1()); seg = QLineF(seg.p2(), seg.p1());
seg.setLength(seg.length() - radius); seg.setLength(seg.length() - radius);
points.append(seg.p2()); points.append(seg.p2());
@ -390,7 +366,7 @@ QVector<QLineF> CreateUMarkPassmark(const QLineF &line, const QVector<QPointF> &
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> CreateBoxMarkPassmark(const QLineF &line, const QVector<QPointF> &seamAllowance) QVector<QLineF> CreateBoxMarkPassmark(const QLineF &line, const QVector<QPointF> &seamAllowance)
{ {
const qreal radius = line.length() * passmarkRadiusFactor; const qreal radius = line.length() * VPassmark::passmarkRadiusFactor;
QPointF l1p1; QPointF l1p1;
{ {
@ -426,11 +402,11 @@ QVector<QLineF> CreateBoxMarkPassmark(const QLineF &line, const QVector<QPointF>
QVector<QPointF> points; QVector<QPointF> points;
QLineF seg = FindIntersection(QLineF(l1p2, l1p1), seamAllowance); QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance);
points.append(seg.p2()); points.append(seg.p2());
points.append(seg.p1()); points.append(seg.p1());
seg = FindIntersection(QLineF(l2p2, l2p1), seamAllowance); seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance);
points.append(seg.p1()); points.append(seg.p1());
points.append(seg.p2()); points.append(seg.p2());
@ -441,6 +417,11 @@ QVector<QLineF> CreateBoxMarkPassmark(const QLineF &line, const QVector<QPointF>
QVector<QLineF> CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType angleType, const QLineF &line, QVector<QLineF> CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType angleType, const QLineF &line,
const QVector<QPointF> &seamAllowance) const QVector<QPointF> &seamAllowance)
{ {
if (line.isNull())
{
return QVector<QLineF>();
}
QVector<QLineF> passmarksLines; QVector<QLineF> passmarksLines;
if (angleType == PassmarkAngleType::Straightforward if (angleType == PassmarkAngleType::Straightforward
@ -504,8 +485,8 @@ QVector<QLineF> CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> PassmarkBisector(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData, QLineF PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData,
const QPointF &seamPassmarkSAPoint, const QVector<QPointF> &seamAllowance) const QPointF &seamPassmarkSAPoint, const QVector<QPointF> &seamAllowance)
{ {
QLineF edge1; QLineF edge1;
QLineF edge2; QLineF edge2;
@ -535,7 +516,7 @@ QVector<QLineF> PassmarkBisector(PassmarkStatus seamPassmarkType, const VPiecePa
} }
else else
{ // Should never happen { // Should never happen
return QVector<QLineF>(); return QLineF();
} }
const qreal length = passmarkData.passmarkSAPoint.PassmarkLength(passmarkData.saWidth); const qreal length = passmarkData.passmarkSAPoint.PassmarkLength(passmarkData.saWidth);
@ -545,13 +526,13 @@ QVector<QLineF> PassmarkBisector(PassmarkStatus seamPassmarkType, const VPiecePa
"than minimal allowed.") "than minimal allowed.")
.arg(passmarkData.nodeName, passmarkData.pieceName); .arg(passmarkData.nodeName, passmarkData.pieceName);
qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg;
return QVector<QLineF>(); return QLineF();
} }
edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.); edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.);
edge1.setLength(length); edge1.setLength(length);
return CreatePassmarkLines(passmarkData.passmarkLineType, passmarkData.passmarkAngleType, edge1, seamAllowance); return edge1;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -574,14 +555,23 @@ QPainterPath PassmarkToPath(const QVector<QLineF> &passmark)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPassmark::VPassmark() VPassmark::VPassmark()
: m_data()
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPassmark::VPassmark(const VPiecePassmarkData &data) VPassmark::VPassmark(const VPiecePassmarkData &data)
: m_data(data), : m_data(data),
m_null(false) m_null(false)
{} {
// Correct distorsion
if (VGObject::IsPointOnLineSegment(m_data.passmarkSAPoint, m_data.previousSAPoint,
m_data.nextSAPoint))
{
const QPointF p = VGObject::CorrectDistortion(m_data.passmarkSAPoint, m_data.previousSAPoint,
m_data.nextSAPoint);
m_data.passmarkSAPoint.setX(p.x());
m_data.passmarkSAPoint.setY(p.y());
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPassmark::FullPassmark(const VPiece &piece, const VContainer *data) const QVector<QLineF> VPassmark::FullPassmark(const VPiece &piece, const VContainer *data) const
@ -639,7 +629,7 @@ QVector<QLineF> VPassmark::SAPassmark(const QVector<QPointF> &seamAllowance, Pas
return QVector<QLineF>(); return QVector<QLineF>();
} }
// Because rollback cannot be calulated if passmark is not first point in main path we rotate it. // Because rollback @seamAllowance must be rotated here.
return MakeSAPassmark(seamAllowance, side); return MakeSAPassmark(seamAllowance, side);
} }
@ -655,15 +645,126 @@ VPiecePassmarkData VPassmark::Data() const
return m_data; return m_data;
} }
//---------------------------------------------------------------------------------------------------------------------
QLineF VPassmark::FindIntersection(const QLineF &line, const QVector<QPointF> &seamAllowance)
{
QLineF testLine = line;
testLine.setLength(testLine.length()*10);
QVector<QPointF> intersections = VAbstractCurve::CurveIntersectLine(seamAllowance, testLine);
if (not intersections.isEmpty())
{
return QLineF(line.p1(), intersections.last());
}
return line;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance, PassmarkSide side) const QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance, PassmarkSide side) const
{ {
const QLineF line = SAPassmarkBaseLine(seamAllowance, side);
if (line.isNull())
{
return QVector<QLineF>();
}
return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, line, seamAllowance);
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContainer *data) const
{
if (m_null)
{
return QVector<QLineF>();
}
const QLineF line = BuiltInSAPassmarkBaseLine(piece);
if (line.isNull())
{
return QVector<QLineF>();
}
return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, line, piece.MainPathPoints(data));
}
//---------------------------------------------------------------------------------------------------------------------
QLineF VPassmark::BuiltInSAPassmarkBaseLine(const VPiece &piece) const
{
if (m_null)
{
return QLineF();
}
qreal length = 0;
if (not piece.IsSeamAllowanceBuiltIn())
{
length = m_data.passmarkSAPoint.PassmarkLength(m_data.saWidth);
if (not m_data.passmarkSAPoint.IsManualPasskmarkLength() && length <= accuracyPointOnLine)
{
const QString errorMsg = QObject::tr("Found null notch for point '%1' in piece '%2'. Length is less "
"than minimal allowed.")
.arg(m_data.nodeName, m_data.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
return QLineF();
}
}
else
{
if (m_data.passmarkSAPoint.IsManualPasskmarkLength())
{
length = m_data.passmarkSAPoint.GetPasskmarkLength();
}
else
{
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2' with built in "
"seam allowance. User must manually provide length.")
.arg(m_data.nodeName, m_data.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
return QLineF();
}
}
QLineF edge1 = QLineF(m_data.passmarkSAPoint, m_data.previousSAPoint);
QLineF edge2 = QLineF(m_data.passmarkSAPoint, m_data.nextSAPoint);
edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.);
edge1.setLength(length);
return edge1;
}
//---------------------------------------------------------------------------------------------------------------------
QLineF VPassmark::SAPassmarkBaseLine(const VPiece &piece, const VContainer *data, PassmarkSide side) const
{
if (m_null)
{
return QLineF();
}
if (not piece.IsSeamAllowanceBuiltIn())
{
// Because rollback cannot be calulated if passmark is not first point in main path we rotate it.
return SAPassmarkBaseLine(piece.SeamAllowancePointsWithRotation(data, m_data.passmarkIndex), side);
}
return QLineF();
}
//---------------------------------------------------------------------------------------------------------------------
QLineF VPassmark::SAPassmarkBaseLine(const QVector<QPointF> &seamAllowance, PassmarkSide side) const
{
if (m_null)
{
return QLineF();
}
if (seamAllowance.size() < 2) if (seamAllowance.size() < 2)
{ {
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Seam allowance is " const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2'. Seam allowance is "
"empty.").arg(m_data.nodeName, m_data.pieceName); "empty.").arg(m_data.nodeName, m_data.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
return QVector<QLineF>(); // Something wrong return QLineF(); // Something wrong
} }
QPointF seamPassmarkSAPoint; QPointF seamPassmarkSAPoint;
@ -674,7 +775,7 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
"position for a notch.") "position for a notch.")
.arg(m_data.nodeName, m_data.pieceName); .arg(m_data.nodeName, m_data.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
return QVector<QLineF>(); // Something wrong return QLineF(); // Something wrong
} }
if (not FixNotchPoint(seamAllowance, m_data.passmarkSAPoint, &seamPassmarkSAPoint)) if (not FixNotchPoint(seamAllowance, m_data.passmarkSAPoint, &seamPassmarkSAPoint))
@ -685,10 +786,7 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
} }
QVector<QLineF> passmarksLines; auto PassmarkIntersection = [this, seamAllowance] (QLineF line, qreal width)
auto PassmarkIntersection = [&passmarksLines, this, seamAllowance]
(QLineF line, qreal width)
{ {
line.setLength(line.length()*100); // Hope 100 is enough line.setLength(line.length()*100); // Hope 100 is enough
@ -707,7 +805,7 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
"less than minimal allowed.") "less than minimal allowed.")
.arg(m_data.nodeName, m_data.pieceName); .arg(m_data.nodeName, m_data.pieceName);
qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg;
return; return QLineF();
} }
line.setLength(length); line.setLength(length);
} }
@ -715,8 +813,7 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
{ {
line.setLength(m_data.passmarkSAPoint.GetPasskmarkLength()); line.setLength(m_data.passmarkSAPoint.GetPasskmarkLength());
} }
passmarksLines += CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, return line;
line, seamAllowance);
} }
else else
{ {
@ -733,6 +830,8 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
.arg(m_data.nodeName, m_data.pieceName); .arg(m_data.nodeName, m_data.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
} }
return QLineF();
}; };
if (m_data.passmarkAngleType == PassmarkAngleType::Straightforward) if (m_data.passmarkAngleType == PassmarkAngleType::Straightforward)
@ -749,13 +848,12 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
{ {
QLineF line = QLineF(seamPassmarkSAPoint, m_data.passmarkSAPoint); QLineF line = QLineF(seamPassmarkSAPoint, m_data.passmarkSAPoint);
line.setLength(length); line.setLength(length);
passmarksLines += CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, line, return line;
seamAllowance);
} }
} }
else if (m_data.passmarkAngleType == PassmarkAngleType::Bisector) else if (m_data.passmarkAngleType == PassmarkAngleType::Bisector)
{ {
passmarksLines += PassmarkBisector(seamPassmarkType, m_data, seamPassmarkSAPoint, seamAllowance); return PassmarkBisectorBaseLine(seamPassmarkType, m_data, seamPassmarkSAPoint, seamAllowance);
} }
else if (m_data.passmarkAngleType == PassmarkAngleType::Intersection else if (m_data.passmarkAngleType == PassmarkAngleType::Intersection
|| m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft
@ -766,8 +864,8 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
&& (side == PassmarkSide::All || side == PassmarkSide::Right)) && (side == PassmarkSide::All || side == PassmarkSide::Right))
{ {
// first passmark // first passmark
PassmarkIntersection(QLineF(m_data.previousSAPoint, m_data.passmarkSAPoint), return PassmarkIntersection(QLineF(m_data.previousSAPoint, m_data.passmarkSAPoint),
m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth));
} }
if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection
@ -775,8 +873,8 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
&& (side == PassmarkSide::All || side == PassmarkSide::Left)) && (side == PassmarkSide::All || side == PassmarkSide::Left))
{ {
// second passmark // second passmark
PassmarkIntersection(QLineF(m_data.nextSAPoint, m_data.passmarkSAPoint), return PassmarkIntersection(QLineF(m_data.nextSAPoint, m_data.passmarkSAPoint),
m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); m_data.passmarkSAPoint.GetSABefore(m_data.saWidth));
} }
} }
else if (m_data.passmarkAngleType == PassmarkAngleType::Intersection2 else if (m_data.passmarkAngleType == PassmarkAngleType::Intersection2
@ -790,7 +888,7 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
// first passmark // first passmark
QLineF line(m_data.passmarkSAPoint, m_data.nextSAPoint); QLineF line(m_data.passmarkSAPoint, m_data.nextSAPoint);
line.setAngle(line.angle()+90); line.setAngle(line.angle()+90);
PassmarkIntersection(line, m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); return PassmarkIntersection(line, m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth));
} }
if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2 if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2
@ -800,61 +898,11 @@ QVector<QLineF> VPassmark::MakeSAPassmark(const QVector<QPointF> &seamAllowance,
// second passmark // second passmark
QLineF line(m_data.passmarkSAPoint, m_data.previousSAPoint); QLineF line(m_data.passmarkSAPoint, m_data.previousSAPoint);
line.setAngle(line.angle()-90); line.setAngle(line.angle()-90);
PassmarkIntersection(line, m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); return PassmarkIntersection(line, m_data.passmarkSAPoint.GetSABefore(m_data.saWidth));
} }
} }
return passmarksLines; return QLineF();
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QLineF> VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContainer *data) const
{
if (m_null)
{
return QVector<QLineF>();
}
const QVector<QPointF> mainPath = piece.MainPathPoints(data);
qreal length = 0;
if (not piece.IsSeamAllowanceBuiltIn())
{
length = m_data.passmarkSAPoint.PassmarkLength(m_data.saWidth);
if (not m_data.passmarkSAPoint.IsManualPasskmarkLength() && length <= accuracyPointOnLine)
{
const QString errorMsg = QObject::tr("Found null notch for point '%1' in piece '%2'. Length is less "
"than minimal allowed.")
.arg(m_data.nodeName, m_data.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
return QVector<QLineF>();
}
}
else
{
if (m_data.passmarkSAPoint.IsManualPasskmarkLength())
{
length = m_data.passmarkSAPoint.GetPasskmarkLength();
}
else
{
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2' with built in "
"seam allowance. User must manually provide length.")
.arg(m_data.nodeName, m_data.pieceName);
qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg;
return QVector<QLineF>();
}
}
QVector<QLineF> passmarksLines;
QLineF edge1 = QLineF(m_data.passmarkSAPoint, m_data.previousSAPoint);
QLineF edge2 = QLineF(m_data.passmarkSAPoint, m_data.nextSAPoint);
edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.);
edge1.setLength(length);
passmarksLines += CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, edge1, mainPath);
return passmarksLines;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -79,14 +79,22 @@ public:
QVector<QLineF> SAPassmark(const QVector<QPointF> &seamAllowance, PassmarkSide side) const; QVector<QLineF> SAPassmark(const QVector<QPointF> &seamAllowance, PassmarkSide side) const;
QVector<QLineF> BuiltInSAPassmark(const VPiece &piece, const VContainer *data) const; QVector<QLineF> BuiltInSAPassmark(const VPiece &piece, const VContainer *data) const;
QLineF BuiltInSAPassmarkBaseLine(const VPiece &piece) const;
QLineF SAPassmarkBaseLine(const VPiece &piece, const VContainer *data, PassmarkSide side) const;
QLineF SAPassmarkBaseLine(const QVector<QPointF> &seamAllowance, PassmarkSide side) const;
QPainterPath SAPassmarkPath(const VPiece& piece, const VContainer *data, PassmarkSide side) const; QPainterPath SAPassmarkPath(const VPiece& piece, const VContainer *data, PassmarkSide side) const;
QPainterPath BuiltInSAPassmarkPath(const VPiece &piece, const VContainer *data) const; QPainterPath BuiltInSAPassmarkPath(const VPiece &piece, const VContainer *data) const;
bool IsNull() const; bool IsNull() const;
VPiecePassmarkData Data() const; VPiecePassmarkData Data() const;
static QLineF FindIntersection(const QLineF &line, const QVector<QPointF> &seamAllowance);
static const qreal passmarkRadiusFactor;
private: private:
VPiecePassmarkData m_data; VPiecePassmarkData m_data{};
bool m_null{true}; bool m_null{true};
QVector<QLineF> MakeSAPassmark(const QVector<QPointF> &seamAllowance, PassmarkSide side) const; QVector<QLineF> MakeSAPassmark(const QVector<QPointF> &seamAllowance, PassmarkSide side) const;