diff --git a/src/libs/vdxf/vdxfengine.cpp b/src/libs/vdxf/vdxfengine.cpp index 06b2e750c..7771e66ea 100644 --- a/src/libs/vdxf/vdxfengine.cpp +++ b/src/libs/vdxf/vdxfengine.cpp @@ -732,12 +732,15 @@ void VDxfEngine::ExportAAMANotch(dx_ifaceBlock *detailBlock, const VLayoutPiece { if (detail.IsSeamAllowance()) { - const QVector passmarks = detail.GetPassmarks(); - for(auto passmark : passmarks) + const QVector passmarks = detail.GetPassmarks(); + 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); + } } } } diff --git a/src/libs/vgeometry/vgeometrydef.h b/src/libs/vgeometry/vgeometrydef.h index a63c20fc9..edc97e51b 100644 --- a/src/libs/vgeometry/vgeometrydef.h +++ b/src/libs/vgeometry/vgeometrydef.h @@ -80,5 +80,15 @@ struct VLayoutPlaceLabel QTransform rotationMatrix{}; QRectF box{}; }; +Q_DECLARE_METATYPE(VLayoutPlaceLabel) + +struct VLayoutPassmark +{ + QVector lines{}; + PassmarkLineType type{PassmarkLineType::OneLine}; + QLineF baseLine{}; + bool isBuiltIn{false}; +}; +Q_DECLARE_METATYPE(VLayoutPassmark) #endif // VGEOMETRYDEF_H diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index a4cbb42a9..368ebdc2a 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -50,6 +50,7 @@ #include "../vmisc/vmath.h" #include "../vmisc/vabstractapplication.h" #include "../vpatterndb/calculator.h" +#include "../vpatterndb/vpassmark.h" #include "../vgeometry/vpointf.h" #include "../vgeometry/vplacelabelitem.h" #include "vlayoutdef.h" @@ -227,6 +228,108 @@ QVector ConvertPlaceLabels(const VPiece &piece, const VContai } return labels; } + +//--------------------------------------------------------------------------------------------------------------------- +QVector ConvertPassmarks(const VPiece &piece, const VContainer *pattern) +{ + const QVector passmarks = piece.Passmarks(pattern); + QVector 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(side)); + layoutPassmark.baseLine = + passmark.SAPassmarkBaseLine(piece, pattern, static_cast(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 futureSeamAllowanceValid = QtConcurrent::run(piece, &VPiece::IsSeamAllowanceValid, pattern); QFuture > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern); QFuture > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern); - QFuture > futurePassmarksLines = QtConcurrent::run(piece, &VPiece::PassmarksLines, pattern); + QFuture > futurePassmarks = QtConcurrent::run(ConvertPassmarks, piece, pattern); QFuture > futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern); VLayoutPiece det; @@ -286,7 +389,7 @@ VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern det.SetCountourPoints(futureMainPath.result(), piece.IsHideMainPath()); det.SetSeamAllowancePoints(futureSeamAllowance.result(), piece.IsSeamAllowance(), piece.IsSeamAllowanceBuiltIn()); det.SetInternalPaths(futureInternalPaths.result()); - det.SetPassmarks(futurePassmarksLines.result()); + det.SetPassmarks(futurePassmarks.result()); det.SetPlaceLabels(futurePlaceLabels.result()); // Very important to set main path first! @@ -344,13 +447,24 @@ QVector VLayoutPiece::Map(QVectormatrix.map(points.at(i).center); points[i].shape = Map(points.at(i).shape); } return points; } +//--------------------------------------------------------------------------------------------------------------------- +template <> +QVector VLayoutPiece::Map(QVector passmarks) const +{ + for (int i = 0; i < passmarks.size(); ++i) + { + passmarks[i].lines = Map(passmarks.at(i).lines); + } + + return passmarks; +} + //--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction QVector VLayoutPiece::GetContourPoints() const @@ -765,13 +879,13 @@ void VLayoutPiece::SetLayoutAllowancePoints() } //--------------------------------------------------------------------------------------------------------------------- -QVector VLayoutPiece::GetPassmarks() const +QVector VLayoutPiece::GetPassmarks() const { return Map(d->passmarks); } //--------------------------------------------------------------------------------------------------------------------- -void VLayoutPiece::SetPassmarks(const QVector &passmarks) +void VLayoutPiece::SetPassmarks(const QVector &passmarks) { if (IsSeamAllowance()) { @@ -854,12 +968,15 @@ QPainterPath VLayoutPiece::ContourPath() const } // Draw passmarks - const QVector passmarks = GetPassmarks(); QPainterPath passmaksPath; - for (qint32 i = 0; i < passmarks.count(); ++i) + const QVector passmarks = GetPassmarks(); + for(auto &passmark : passmarks) { - passmaksPath.moveTo(passmarks.at(i).p1()); - passmaksPath.lineTo(passmarks.at(i).p2()); + for (auto &line : passmark.lines) + { + passmaksPath.moveTo(line.p1()); + passmaksPath.lineTo(line.p2()); + } } path.addPath(passmaksPath); diff --git a/src/libs/vlayout/vlayoutpiece.h b/src/libs/vlayout/vlayoutpiece.h index f521a267c..e70783e18 100644 --- a/src/libs/vlayout/vlayoutpiece.h +++ b/src/libs/vlayout/vlayoutpiece.h @@ -83,8 +83,8 @@ public: QVector GetLayoutAllowancePoints() const; void SetLayoutAllowancePoints(); - QVector GetPassmarks() const; - void SetPassmarks(const QVector &passmarks); + QVector GetPassmarks() const; + void SetPassmarks(const QVector &passmarks); QVector GetPlaceLabels() const; void SetPlaceLabels(const QVector &labels); diff --git a/src/libs/vlayout/vlayoutpiece_p.h b/src/libs/vlayout/vlayoutpiece_p.h index 0453f67d0..192ffdde8 100644 --- a/src/libs/vlayout/vlayoutpiece_p.h +++ b/src/libs/vlayout/vlayoutpiece_p.h @@ -103,7 +103,7 @@ public: QVector layoutAllowance; /** @brief passmarks list of passmakrs. */ - QVector passmarks; + QVector passmarks; /** @brief m_internalPaths list of internal paths. */ QVector m_internalPaths; diff --git a/src/libs/vpatterndb/vpassmark.cpp b/src/libs/vpatterndb/vpassmark.cpp index 4942a1ff4..125587cd3 100644 --- a/src/libs/vpatterndb/vpassmark.cpp +++ b/src/libs/vpatterndb/vpassmark.cpp @@ -32,22 +32,14 @@ #include "../vgeometry/vabstractcurve.h" #include "../vgeometry/varc.h" +const qreal VPassmark::passmarkRadiusFactor = 0.45; + namespace { //--------------------------------------------------------------------------------------------------------------------- -PassmarkStatus GetSeamPassmarkSAPoint(VPiecePassmarkData passmarkData, const QVector &seamAllowance, +PassmarkStatus GetSeamPassmarkSAPoint(const VPiecePassmarkData &passmarkData, const QVector &seamAllowance, 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 QVector ekvPoints; ekvPoints = VAbstractPiece::EkvPoint(ekvPoints, passmarkData.previousSAPoint, passmarkData.passmarkSAPoint, @@ -147,20 +139,6 @@ bool FixNotchPoint(const QVector &seamAllowance, const QPointF ¬chBa } const qreal passmarkGap = (1.5/*mm*/ / 25.4) * PrintDPI; -//--------------------------------------------------------------------------------------------------------------------- -QLineF FindIntersection(const QLineF &line, const QVector &seamAllowance) -{ - QLineF testLine = line; - testLine.setLength(testLine.length()*10); - QVector intersections = VAbstractCurve::CurveIntersectLine(seamAllowance, testLine); - if (not intersections.isEmpty()) - { - return QLineF(line.p1(), intersections.last()); - } - - return line; -} - //--------------------------------------------------------------------------------------------------------------------- QVector CreateTwoPassmarkLines(const QLineF &line, const QVector &seamAllowance) { @@ -197,10 +175,10 @@ QVector CreateTwoPassmarkLines(const QLineF &line, const QVector lines; - QLineF seg = FindIntersection(QLineF(l1p2, l1p1), seamAllowance); + QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); 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())); return lines; } @@ -241,12 +219,12 @@ QVector CreateThreePassmarkLines(const QLineF &line, const QVector 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(line); - seg = FindIntersection(QLineF(l2p2, l2p1), seamAllowance); + seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); lines.append(QLineF(seg.p2(), seg.p1())); return lines; } @@ -301,8 +279,8 @@ QVector CreateVMark2Passmark(const QLineF &line, const QVector l2.setAngle(l2.angle() - 35); QVector lines; - lines.append(FindIntersection(l1, seamAllowance)); - lines.append(FindIntersection(l2, seamAllowance)); + lines.append(VPassmark::FindIntersection(l1, seamAllowance)); + lines.append(VPassmark::FindIntersection(l2, seamAllowance)); return lines; } @@ -324,12 +302,10 @@ QVector PointsToSegments(const QVector &points) return lines; } -const qreal passmarkRadiusFactor = 0.45; - //--------------------------------------------------------------------------------------------------------------------- QVector CreateUMarkPassmark(const QLineF &line, const QVector &seamAllowance) { - const qreal radius = line.length() * passmarkRadiusFactor; + const qreal radius = line.length() * VPassmark::passmarkRadiusFactor; QPointF l1p1; { @@ -368,7 +344,7 @@ QVector CreateUMarkPassmark(const QLineF &line, const QVector & QVector points; - QLineF seg = FindIntersection(QLineF(l2p2, l2p1), seamAllowance); + QLineF seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); seg = QLineF(seg.p2(), seg.p1()); seg.setLength(seg.length() - radius); points.append(seg.p1()); @@ -378,7 +354,7 @@ QVector CreateUMarkPassmark(const QLineF &line, const QVector & arc.SetApproximationScale(10); points += arc.GetPoints(); - seg = FindIntersection(QLineF(l1p2, l1p1), seamAllowance); + seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); seg = QLineF(seg.p2(), seg.p1()); seg.setLength(seg.length() - radius); points.append(seg.p2()); @@ -390,7 +366,7 @@ QVector CreateUMarkPassmark(const QLineF &line, const QVector & //--------------------------------------------------------------------------------------------------------------------- QVector CreateBoxMarkPassmark(const QLineF &line, const QVector &seamAllowance) { - const qreal radius = line.length() * passmarkRadiusFactor; + const qreal radius = line.length() * VPassmark::passmarkRadiusFactor; QPointF l1p1; { @@ -426,11 +402,11 @@ QVector CreateBoxMarkPassmark(const QLineF &line, const QVector QVector points; - QLineF seg = FindIntersection(QLineF(l1p2, l1p1), seamAllowance); + QLineF seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); points.append(seg.p2()); points.append(seg.p1()); - seg = FindIntersection(QLineF(l2p2, l2p1), seamAllowance); + seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); points.append(seg.p1()); points.append(seg.p2()); @@ -441,6 +417,11 @@ QVector CreateBoxMarkPassmark(const QLineF &line, const QVector QVector CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType angleType, const QLineF &line, const QVector &seamAllowance) { + if (line.isNull()) + { + return QVector(); + } + QVector passmarksLines; if (angleType == PassmarkAngleType::Straightforward @@ -504,8 +485,8 @@ QVector CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType } //--------------------------------------------------------------------------------------------------------------------- -QVector PassmarkBisector(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData, - const QPointF &seamPassmarkSAPoint, const QVector &seamAllowance) +QLineF PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData, + const QPointF &seamPassmarkSAPoint, const QVector &seamAllowance) { QLineF edge1; QLineF edge2; @@ -535,7 +516,7 @@ QVector PassmarkBisector(PassmarkStatus seamPassmarkType, const VPiecePa } else { // Should never happen - return QVector(); + return QLineF(); } const qreal length = passmarkData.passmarkSAPoint.PassmarkLength(passmarkData.saWidth); @@ -545,13 +526,13 @@ QVector PassmarkBisector(PassmarkStatus seamPassmarkType, const VPiecePa "than minimal allowed.") .arg(passmarkData.nodeName, passmarkData.pieceName); qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg; - return QVector(); + return QLineF(); } edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.); edge1.setLength(length); - return CreatePassmarkLines(passmarkData.passmarkLineType, passmarkData.passmarkAngleType, edge1, seamAllowance); + return edge1; } //--------------------------------------------------------------------------------------------------------------------- @@ -574,14 +555,23 @@ QPainterPath PassmarkToPath(const QVector &passmark) //--------------------------------------------------------------------------------------------------------------------- VPassmark::VPassmark() - : m_data() {} //--------------------------------------------------------------------------------------------------------------------- VPassmark::VPassmark(const VPiecePassmarkData &data) : m_data(data), 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 VPassmark::FullPassmark(const VPiece &piece, const VContainer *data) const @@ -639,7 +629,7 @@ QVector VPassmark::SAPassmark(const QVector &seamAllowance, Pas return QVector(); } - // 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); } @@ -655,15 +645,126 @@ VPiecePassmarkData VPassmark::Data() const return m_data; } +//--------------------------------------------------------------------------------------------------------------------- +QLineF VPassmark::FindIntersection(const QLineF &line, const QVector &seamAllowance) +{ + QLineF testLine = line; + testLine.setLength(testLine.length()*10); + QVector intersections = VAbstractCurve::CurveIntersectLine(seamAllowance, testLine); + if (not intersections.isEmpty()) + { + return QLineF(line.p1(), intersections.last()); + } + + return line; +} + //--------------------------------------------------------------------------------------------------------------------- QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, PassmarkSide side) const { + const QLineF line = SAPassmarkBaseLine(seamAllowance, side); + if (line.isNull()) + { + return QVector(); + } + + return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, line, seamAllowance); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContainer *data) const +{ + if (m_null) + { + return QVector(); + } + + const QLineF line = BuiltInSAPassmarkBaseLine(piece); + if (line.isNull()) + { + return QVector(); + } + + 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 &seamAllowance, PassmarkSide side) const +{ + if (m_null) + { + return QLineF(); + } + if (seamAllowance.size() < 2) { 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); qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; - return QVector(); // Something wrong + return QLineF(); // Something wrong } QPointF seamPassmarkSAPoint; @@ -674,7 +775,7 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, "position for a notch.") .arg(m_data.nodeName, m_data.pieceName); qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; - return QVector(); // Something wrong + return QLineF(); // Something wrong } if (not FixNotchPoint(seamAllowance, m_data.passmarkSAPoint, &seamPassmarkSAPoint)) @@ -685,10 +786,7 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; } - QVector passmarksLines; - - auto PassmarkIntersection = [&passmarksLines, this, seamAllowance] - (QLineF line, qreal width) + auto PassmarkIntersection = [this, seamAllowance] (QLineF line, qreal width) { line.setLength(line.length()*100); // Hope 100 is enough @@ -707,7 +805,7 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, "less than minimal allowed.") .arg(m_data.nodeName, m_data.pieceName); qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg; - return; + return QLineF(); } line.setLength(length); } @@ -715,8 +813,7 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, { line.setLength(m_data.passmarkSAPoint.GetPasskmarkLength()); } - passmarksLines += CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, - line, seamAllowance); + return line; } else { @@ -733,6 +830,8 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, .arg(m_data.nodeName, m_data.pieceName); qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; } + + return QLineF(); }; if (m_data.passmarkAngleType == PassmarkAngleType::Straightforward) @@ -749,13 +848,12 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, { QLineF line = QLineF(seamPassmarkSAPoint, m_data.passmarkSAPoint); line.setLength(length); - passmarksLines += CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, line, - seamAllowance); + return line; } } 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 || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft @@ -766,8 +864,8 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, && (side == PassmarkSide::All || side == PassmarkSide::Right)) { // first passmark - PassmarkIntersection(QLineF(m_data.previousSAPoint, m_data.passmarkSAPoint), - m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); + return PassmarkIntersection(QLineF(m_data.previousSAPoint, m_data.passmarkSAPoint), + m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); } if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection @@ -775,8 +873,8 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, && (side == PassmarkSide::All || side == PassmarkSide::Left)) { // second passmark - PassmarkIntersection(QLineF(m_data.nextSAPoint, m_data.passmarkSAPoint), - m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); + return PassmarkIntersection(QLineF(m_data.nextSAPoint, m_data.passmarkSAPoint), + m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); } } else if (m_data.passmarkAngleType == PassmarkAngleType::Intersection2 @@ -790,7 +888,7 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, // first passmark QLineF line(m_data.passmarkSAPoint, m_data.nextSAPoint); 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 @@ -800,61 +898,11 @@ QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, // second passmark QLineF line(m_data.passmarkSAPoint, m_data.previousSAPoint); 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; -} - -//--------------------------------------------------------------------------------------------------------------------- -QVector VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContainer *data) const -{ - if (m_null) - { - return QVector(); - } - - const QVector 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(); - } - } - 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(); - } - } - QVector 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; + return QLineF(); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vpatterndb/vpassmark.h b/src/libs/vpatterndb/vpassmark.h index 6ea81d4ad..fa2d0f34a 100644 --- a/src/libs/vpatterndb/vpassmark.h +++ b/src/libs/vpatterndb/vpassmark.h @@ -79,14 +79,22 @@ public: QVector SAPassmark(const QVector &seamAllowance, PassmarkSide side) const; QVector 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 &seamAllowance, PassmarkSide side) const; + QPainterPath SAPassmarkPath(const VPiece& piece, const VContainer *data, PassmarkSide side) const; QPainterPath BuiltInSAPassmarkPath(const VPiece &piece, const VContainer *data) const; bool IsNull() const; VPiecePassmarkData Data() const; + + static QLineF FindIntersection(const QLineF &line, const QVector &seamAllowance); + + static const qreal passmarkRadiusFactor; private: - VPiecePassmarkData m_data; + VPiecePassmarkData m_data{}; bool m_null{true}; QVector MakeSAPassmark(const QVector &seamAllowance, PassmarkSide side) const;