diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index 9897266d0..db2ef1d92 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -249,7 +249,7 @@ QVector ConvertPassmarks(const VPiece &piece, const VContainer if (nodeIndex != -1) { layoutPassmark.lines = passmark.BuiltInSAPassmark(piece, pattern); - layoutPassmark.baseLine = passmark.BuiltInSAPassmarkBaseLine(piece); + layoutPassmark.baseLine = passmark.BuiltInSAPassmarkBaseLine(piece).constFirst(); layoutPassmark.type = pData.passmarkLineType; layoutPassmark.isBuiltIn = true; @@ -265,9 +265,18 @@ QVector ConvertPassmarks(const VPiece &piece, const VContainer const int nodeIndex = path.indexOfNode(pData.id); if (nodeIndex != -1) { - layoutPassmark.lines = passmark.SAPassmark(piece, pattern, static_cast(side)); - layoutPassmark.baseLine = + QVector lines = passmark.SAPassmarkBaseLine(piece, pattern, static_cast(side)); + + if (side == PassmarkSide::All || side == PassmarkSide::Right) + { + layoutPassmark.baseLine = lines.first(); + } + else if (side == PassmarkSide::Right) + { + layoutPassmark.baseLine = lines.last(); + } + layoutPassmark.lines = passmark.SAPassmark(piece, pattern, side); layoutPassmark.type = pData.passmarkLineType; layoutPassmark.isBuiltIn = false; diff --git a/src/libs/vpatterndb/vpassmark.cpp b/src/libs/vpatterndb/vpassmark.cpp index 125587cd3..e2e391c86 100644 --- a/src/libs/vpatterndb/vpassmark.cpp +++ b/src/libs/vpatterndb/vpassmark.cpp @@ -139,6 +139,12 @@ bool FixNotchPoint(const QVector &seamAllowance, const QPointF ¬chBa } const qreal passmarkGap = (1.5/*mm*/ / 25.4) * PrintDPI; +//--------------------------------------------------------------------------------------------------------------------- +QVector CreateOnePassmarkLines(const QLineF &line) +{ + return QVector({line}); +} + //--------------------------------------------------------------------------------------------------------------------- QVector CreateTwoPassmarkLines(const QLineF &line, const QVector &seamAllowance) { @@ -307,9 +313,12 @@ QVector CreateUMarkPassmark(const QLineF &line, const QVector & { const qreal radius = line.length() * VPassmark::passmarkRadiusFactor; + QLineF baseLine = line; + baseLine.setLength(baseLine.length() - radius); // keep defined depth + QPointF l1p1; { - QLineF line1 = line; + QLineF line1 = baseLine; line1.setAngle(line1.angle() + 90); line1.setLength(radius); l1p1 = line1.p2(); @@ -317,7 +326,7 @@ QVector CreateUMarkPassmark(const QLineF &line, const QVector & QPointF l2p1; { - QLineF line2 = line; + QLineF line2 = baseLine; line2.setAngle(line2.angle() - 90); line2.setLength(radius); l2p1 = line2.p2(); @@ -325,7 +334,7 @@ QVector CreateUMarkPassmark(const QLineF &line, const QVector & QPointF l1p2; { - QLineF line1 = QLineF(line.p2(), line.p1()); + QLineF line1 = QLineF(baseLine.p2(), baseLine.p1()); line1.setAngle(line1.angle() - 90); line1.setLength(radius); l1p2 = line1.p2(); @@ -333,30 +342,28 @@ QVector CreateUMarkPassmark(const QLineF &line, const QVector & QPointF l2p2; { - QLineF line2 = QLineF(line.p2(), line.p1()); + QLineF line2 = QLineF(baseLine.p2(), baseLine.p1()); line2.setAngle(line2.angle() + 90); line2.setLength(radius); l2p2 = line2.p2(); } - QLineF axis = QLineF(line.p2(), line.p1()); + QLineF axis = QLineF(baseLine.p2(), baseLine.p1()); axis.setLength(radius); QVector points; QLineF seg = VPassmark::FindIntersection(QLineF(l2p2, l2p1), seamAllowance); seg = QLineF(seg.p2(), seg.p1()); - seg.setLength(seg.length() - radius); points.append(seg.p1()); points.append(seg.p2()); - VArc arc(VPointF(axis.p2()), radius, QLineF(l1p2, l2p2).angle(), QLineF(l1p2, l2p2).angle()+180); + VArc arc(VPointF(baseLine.p2()), radius, QLineF(baseLine.p2(), l2p2).angle(), QLineF(baseLine.p2(), l1p2).angle()); arc.SetApproximationScale(10); points += arc.GetPoints(); seg = VPassmark::FindIntersection(QLineF(l1p2, l1p1), seamAllowance); seg = QLineF(seg.p2(), seg.p1()); - seg.setLength(seg.length() - radius); points.append(seg.p2()); points.append(seg.p1()); @@ -414,16 +421,58 @@ QVector CreateBoxMarkPassmark(const QLineF &line, const QVector } //--------------------------------------------------------------------------------------------------------------------- -QVector CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType angleType, const QLineF &line, - const QVector &seamAllowance) +QVector CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType angleType, + const QVector &lines, const QVector &seamAllowance, + PassmarkSide side) { - if (line.isNull()) + if (lines.isEmpty()) { return QVector(); } QVector passmarksLines; + auto CreateLinesWithCorrection = [&passmarksLines, side, angleType, lines, seamAllowance] + (QVector (*create)(const QLineF &, const QVector &)) + { + if (angleType == PassmarkAngleType::Straightforward) + { + passmarksLines += (*create)(lines.first(), seamAllowance); + } + else + { + if (side == PassmarkSide::All || side == PassmarkSide::Left) + { + passmarksLines += (*create)(lines.first(), seamAllowance); + } + + if (side == PassmarkSide::All || side == PassmarkSide::Right) + { + passmarksLines += (*create)(lines.last(), seamAllowance); + } + } + }; + + auto CreateLines = [&passmarksLines, side, angleType, lines](QVector (*create)(const QLineF &)) + { + if (angleType == PassmarkAngleType::Straightforward) + { + passmarksLines += (*create)(lines.first()); + } + else + { + if (side == PassmarkSide::All || side == PassmarkSide::Left) + { + passmarksLines += (*create)(lines.first()); + } + + if (side == PassmarkSide::All || side == PassmarkSide::Right) + { + passmarksLines += (*create)(lines.last()); + } + } + }; + if (angleType == PassmarkAngleType::Straightforward || angleType == PassmarkAngleType::Intersection || angleType == PassmarkAngleType::IntersectionOnlyLeft @@ -435,29 +484,29 @@ QVector CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType switch (lineType) { case PassmarkLineType::TwoLines: - passmarksLines += CreateTwoPassmarkLines(line, seamAllowance); + CreateLinesWithCorrection(CreateTwoPassmarkLines); break; case PassmarkLineType::ThreeLines: - passmarksLines += CreateThreePassmarkLines(line, seamAllowance); + CreateLinesWithCorrection(CreateThreePassmarkLines); break; case PassmarkLineType::TMark: - passmarksLines += CreateTMarkPassmark(line); + CreateLines(CreateTMarkPassmark); break; case PassmarkLineType::VMark: - passmarksLines += CreateVMarkPassmark(line); + CreateLines(CreateVMarkPassmark); break; case PassmarkLineType::VMark2: - passmarksLines += CreateVMark2Passmark(line, seamAllowance); + CreateLinesWithCorrection(CreateVMark2Passmark); break; case PassmarkLineType::UMark: - passmarksLines += CreateUMarkPassmark(line, seamAllowance); + CreateLinesWithCorrection(CreateUMarkPassmark); break; case PassmarkLineType::BoxMark: - passmarksLines += CreateBoxMarkPassmark(line, seamAllowance); + CreateLinesWithCorrection(CreateBoxMarkPassmark); break; case PassmarkLineType::OneLine: default: - passmarksLines.append(line); + CreateLines(CreateOnePassmarkLines); break; } } @@ -466,7 +515,7 @@ QVector CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType switch (lineType) { case PassmarkLineType::TMark: - passmarksLines += CreateTMarkPassmark(line); + passmarksLines += CreateTMarkPassmark(lines.first()); break; case PassmarkLineType::OneLine: case PassmarkLineType::TwoLines: @@ -476,7 +525,7 @@ QVector CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType case PassmarkLineType::UMark: case PassmarkLineType::BoxMark: default: - passmarksLines.append(line); + passmarksLines.append(lines.first()); break; } } @@ -485,8 +534,8 @@ QVector CreatePassmarkLines(PassmarkLineType lineType, PassmarkAngleType } //--------------------------------------------------------------------------------------------------------------------- -QLineF PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData, - const QPointF &seamPassmarkSAPoint, const QVector &seamAllowance) +QVector PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const VPiecePassmarkData &passmarkData, + const QPointF &seamPassmarkSAPoint, const QVector &seamAllowance) { QLineF edge1; QLineF edge2; @@ -516,7 +565,7 @@ QLineF PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const VPiecePas } else { // Should never happen - return QLineF(); + return QVector(); } const qreal length = passmarkData.passmarkSAPoint.PassmarkLength(passmarkData.saWidth); @@ -526,13 +575,13 @@ QLineF PassmarkBisectorBaseLine(PassmarkStatus seamPassmarkType, const VPiecePas "than minimal allowed.") .arg(passmarkData.nodeName, passmarkData.pieceName); qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg; - return QLineF(); + return QVector(); } edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.); edge1.setLength(length); - return edge1; + return QVector({edge1}); } //--------------------------------------------------------------------------------------------------------------------- @@ -662,13 +711,13 @@ QLineF VPassmark::FindIntersection(const QLineF &line, const QVector &s //--------------------------------------------------------------------------------------------------------------------- QVector VPassmark::MakeSAPassmark(const QVector &seamAllowance, PassmarkSide side) const { - const QLineF line = SAPassmarkBaseLine(seamAllowance, side); - if (line.isNull()) + const QVector lines = SAPassmarkBaseLine(seamAllowance, side); + if (lines.isEmpty()) { return QVector(); } - return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, line, seamAllowance); + return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, lines, seamAllowance, side); } //--------------------------------------------------------------------------------------------------------------------- @@ -679,21 +728,22 @@ QVector VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContain return QVector(); } - const QLineF line = BuiltInSAPassmarkBaseLine(piece); - if (line.isNull()) + const QVector lines = BuiltInSAPassmarkBaseLine(piece); + if (lines.isEmpty()) { return QVector(); } - return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, line, piece.MainPathPoints(data)); + return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, lines, piece.MainPathPoints(data), + PassmarkSide::All); } //--------------------------------------------------------------------------------------------------------------------- -QLineF VPassmark::BuiltInSAPassmarkBaseLine(const VPiece &piece) const +QVector VPassmark::BuiltInSAPassmarkBaseLine(const VPiece &piece) const { if (m_null) { - return QLineF(); + return QVector(); } qreal length = 0; @@ -706,7 +756,7 @@ QLineF VPassmark::BuiltInSAPassmarkBaseLine(const VPiece &piece) const "than minimal allowed.") .arg(m_data.nodeName, m_data.pieceName); qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; - return QLineF(); + return QVector(); } } else @@ -721,7 +771,7 @@ QLineF VPassmark::BuiltInSAPassmarkBaseLine(const VPiece &piece) const "seam allowance. User must manually provide length.") .arg(m_data.nodeName, m_data.pieceName); qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; - return QLineF(); + return QVector(); } } @@ -731,15 +781,15 @@ QLineF VPassmark::BuiltInSAPassmarkBaseLine(const VPiece &piece) const edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.); edge1.setLength(length); - return edge1; + return QVector({edge1}); } //--------------------------------------------------------------------------------------------------------------------- -QLineF VPassmark::SAPassmarkBaseLine(const VPiece &piece, const VContainer *data, PassmarkSide side) const +QVector VPassmark::SAPassmarkBaseLine(const VPiece &piece, const VContainer *data, PassmarkSide side) const { if (m_null) { - return QLineF(); + return QVector(); } if (not piece.IsSeamAllowanceBuiltIn()) @@ -748,15 +798,15 @@ QLineF VPassmark::SAPassmarkBaseLine(const VPiece &piece, const VContainer *data return SAPassmarkBaseLine(piece.SeamAllowancePointsWithRotation(data, m_data.passmarkIndex), side); } - return QLineF(); + return QVector(); } //--------------------------------------------------------------------------------------------------------------------- -QLineF VPassmark::SAPassmarkBaseLine(const QVector &seamAllowance, PassmarkSide side) const +QVector VPassmark::SAPassmarkBaseLine(const QVector &seamAllowance, PassmarkSide side) const { if (m_null) { - return QLineF(); + return QVector(); } if (seamAllowance.size() < 2) @@ -764,7 +814,7 @@ QLineF VPassmark::SAPassmarkBaseLine(const QVector &seamAllowance, Pass 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 QLineF(); // Something wrong + return QVector(); // Something wrong } QPointF seamPassmarkSAPoint; @@ -775,7 +825,7 @@ QLineF VPassmark::SAPassmarkBaseLine(const QVector &seamAllowance, Pass "position for a notch.") .arg(m_data.nodeName, m_data.pieceName); qApp->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : qWarning() << errorMsg; - return QLineF(); // Something wrong + return QVector(); // Something wrong } if (not FixNotchPoint(seamAllowance, m_data.passmarkSAPoint, &seamPassmarkSAPoint)) @@ -848,7 +898,7 @@ QLineF VPassmark::SAPassmarkBaseLine(const QVector &seamAllowance, Pass { QLineF line = QLineF(seamPassmarkSAPoint, m_data.passmarkSAPoint); line.setLength(length); - return line; + return QVector({line}); } } else if (m_data.passmarkAngleType == PassmarkAngleType::Bisector) @@ -859,50 +909,56 @@ QLineF VPassmark::SAPassmarkBaseLine(const QVector &seamAllowance, Pass || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight) { - if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection - || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight) - && (side == PassmarkSide::All || side == PassmarkSide::Right)) - { - // first passmark - return PassmarkIntersection(QLineF(m_data.previousSAPoint, m_data.passmarkSAPoint), - m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); - } - + QVector lines; if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyLeft) && (side == PassmarkSide::All || side == PassmarkSide::Left)) { - // second passmark - return PassmarkIntersection(QLineF(m_data.nextSAPoint, m_data.passmarkSAPoint), - m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); + // first passmark + lines += PassmarkIntersection(QLineF(m_data.nextSAPoint, m_data.passmarkSAPoint), + m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); } + + if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection + || m_data.passmarkAngleType == PassmarkAngleType::IntersectionOnlyRight) + && (side == PassmarkSide::All || side == PassmarkSide::Right)) + { + // second passmark + lines += PassmarkIntersection(QLineF(m_data.previousSAPoint, m_data.passmarkSAPoint), + m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); + } + + return lines; } else if (m_data.passmarkAngleType == PassmarkAngleType::Intersection2 || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight) { - if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2 - || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight) - && (side == PassmarkSide::All || side == PassmarkSide::Right)) - { - // first passmark - QLineF line(m_data.passmarkSAPoint, m_data.nextSAPoint); - line.setAngle(line.angle()+90); - return PassmarkIntersection(line, m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); - } - + QVector lines; if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2 || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyLeft) && (side == PassmarkSide::All || side == PassmarkSide::Left)) { - // second passmark + // first passmark QLineF line(m_data.passmarkSAPoint, m_data.previousSAPoint); line.setAngle(line.angle()-90); - return PassmarkIntersection(line, m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); + lines += PassmarkIntersection(line, m_data.passmarkSAPoint.GetSABefore(m_data.saWidth)); } + + if ((m_data.passmarkAngleType == PassmarkAngleType::Intersection2 + || m_data.passmarkAngleType == PassmarkAngleType::Intersection2OnlyRight) + && (side == PassmarkSide::All || side == PassmarkSide::Right)) + { + // second passmark + QLineF line(m_data.passmarkSAPoint, m_data.nextSAPoint); + line.setAngle(line.angle()+90); + lines += PassmarkIntersection(line, m_data.passmarkSAPoint.GetSAAfter(m_data.saWidth)); + } + + return lines; } - return QLineF(); + return QVector(); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vpatterndb/vpassmark.h b/src/libs/vpatterndb/vpassmark.h index fa2d0f34a..907ffc30b 100644 --- a/src/libs/vpatterndb/vpassmark.h +++ b/src/libs/vpatterndb/vpassmark.h @@ -79,9 +79,9 @@ 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; + QVector BuiltInSAPassmarkBaseLine(const VPiece &piece) const; + QVector SAPassmarkBaseLine(const VPiece &piece, const VContainer *data, PassmarkSide side) const; + QVector 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;