From 857e38422123ae45d4da132cd88fffc58f9a1d7f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Fri, 7 Apr 2023 10:05:29 +0300 Subject: [PATCH] New grainline type: Four way. --- ChangeLog.txt | 1 + src/app/puzzle/layout/vppiece.cpp | 18 +- src/app/puzzle/xml/vplayoutfilereader.cpp | 12 +- src/app/puzzle/xml/vplayoutfilewriter.cpp | 2 + src/app/puzzle/xml/vplayoutliterals.cpp | 1 + src/app/puzzle/xml/vplayoutliterals.h | 1 + src/libs/ifc/schema.qrc | 1 + src/libs/ifc/schema/layout/v0.1.4.xsd | 568 ++++++++++++++++++ src/libs/ifc/schema/pattern/v0.9.2.xsd | 2 + src/libs/ifc/xml/vlayoutconverter.cpp | 22 +- src/libs/ifc/xml/vlayoutconverter.h | 3 +- src/libs/vlayout/vabstractpiece.cpp | 32 +- src/libs/vlayout/vposition.cpp | 19 +- .../vpatterndb/floatItemData/floatitemdef.h | 3 +- .../tools/piece/dialogseamallowance.cpp | 1 + src/libs/vwidgets/vgrainlineitem.cpp | 64 +- src/libs/vwidgets/vgrainlineitem.h | 6 +- 17 files changed, 722 insertions(+), 34 deletions(-) create mode 100644 src/libs/ifc/schema/layout/v0.1.4.xsd diff --git a/ChangeLog.txt b/ChangeLog.txt index 415a203b3..293ac5215 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -21,6 +21,7 @@ - Fix compatibility with Richpeace DXF-AAMA/ASTM R12. - Fix seam allowance. Loose requirements to case with prong. - Fix list of dimension popup list. Make sure it will always has enough space for values. +- New grainline type: Four way. # Valentina 0.7.52 September 12, 2022 - Fix crash when default locale is ru. diff --git a/src/app/puzzle/layout/vppiece.cpp b/src/app/puzzle/layout/vppiece.cpp index 8fd65d179..c46d0d056 100644 --- a/src/app/puzzle/layout/vppiece.cpp +++ b/src/app/puzzle/layout/vppiece.cpp @@ -270,7 +270,7 @@ void VPPiece::RotateToGrainline(const VPTransformationOrigon &origin) { degrees = DegreesAtRear(); } - else + else if (type == GrainlineArrowDirection::atBoth) { const qreal atFront = DegreesAtFront(); if (atFront <= 90 || atFront >= 270) @@ -282,6 +282,22 @@ void VPPiece::RotateToGrainline(const VPTransformationOrigon &origin) degrees = DegreesAtRear(); } } + else + { + const qreal atFront = DegreesAtFront(); + if (atFront <= 45) + { + degrees = atFront; + } + else if (atFront > 45 && atFront < 90) + { + degrees = atFront - 90; + } + else + { + degrees = atFront - 90 * qFloor(atFront / 90); + } + } if (origin.custom) { diff --git a/src/app/puzzle/xml/vplayoutfilereader.cpp b/src/app/puzzle/xml/vplayoutfilereader.cpp index 68407e0cf..cae09b089 100644 --- a/src/app/puzzle/xml/vplayoutfilereader.cpp +++ b/src/app/puzzle/xml/vplayoutfilereader.cpp @@ -111,9 +111,10 @@ auto StringToGrainlineArrowDirrection(const QString &dirrection) -> GrainlineArr { const QStringList arrows { - ML::atFrontStr, // 0 - ML::atRearStr, // 1 - ML::atBothStr // 2 + ML::atFrontStr, // 0 + ML::atRearStr, // 1 + ML::atFourWayStr, // 2 + ML::atBothStr // 3 }; GrainlineArrowDirection arrowDirection = GrainlineArrowDirection::atBoth; @@ -125,7 +126,10 @@ auto StringToGrainlineArrowDirrection(const QString &dirrection) -> GrainlineArr case 1:// at rear arrowDirection = GrainlineArrowDirection::atRear; break; - case 2:// at both + case 2:// at four way + arrowDirection = GrainlineArrowDirection::atFourWay; + break; + case 3:// at both default: arrowDirection = GrainlineArrowDirection::atBoth; break; diff --git a/src/app/puzzle/xml/vplayoutfilewriter.cpp b/src/app/puzzle/xml/vplayoutfilewriter.cpp index 3fd969cdd..e73cb913f 100644 --- a/src/app/puzzle/xml/vplayoutfilewriter.cpp +++ b/src/app/puzzle/xml/vplayoutfilewriter.cpp @@ -121,6 +121,8 @@ auto GrainlineArrowDirrectionToString(GrainlineArrowDirection type) -> QString return ML::atFrontStr; case GrainlineArrowDirection::atRear: return ML::atRearStr; + case GrainlineArrowDirection::atFourWay: + return ML::atFourWayStr; case GrainlineArrowDirection::atBoth: default: return ML::atBothStr; diff --git a/src/app/puzzle/xml/vplayoutliterals.cpp b/src/app/puzzle/xml/vplayoutliterals.cpp index 114eb50de..fbd1ea9ff 100644 --- a/src/app/puzzle/xml/vplayoutliterals.cpp +++ b/src/app/puzzle/xml/vplayoutliterals.cpp @@ -117,6 +117,7 @@ const QString AttrCurvePoint = QStringLiteral("curvePoint"); // NOLINT const QString atFrontStr = QStringLiteral("atFront"); // NOLINT(cert-err58-cpp) const QString atRearStr = QStringLiteral("atRear"); // NOLINT(cert-err58-cpp) +const QString atFourWayStr = QStringLiteral("atFourWay"); // NOLINT(cert-err58-cpp) const QString atBothStr = QStringLiteral("atBoth"); // NOLINT(cert-err58-cpp) const QChar groupSep = QLatin1Char(';'); diff --git a/src/app/puzzle/xml/vplayoutliterals.h b/src/app/puzzle/xml/vplayoutliterals.h index a71920a76..e9cc450fa 100644 --- a/src/app/puzzle/xml/vplayoutliterals.h +++ b/src/app/puzzle/xml/vplayoutliterals.h @@ -122,6 +122,7 @@ extern const QString AttrCurvePoint; extern const QString atFrontStr; extern const QString atRearStr; +extern const QString atFourWayStr; extern const QString atBothStr; extern const QChar groupSep; diff --git a/src/libs/ifc/schema.qrc b/src/libs/ifc/schema.qrc index 39525ec5d..c4ec8f211 100644 --- a/src/libs/ifc/schema.qrc +++ b/src/libs/ifc/schema.qrc @@ -95,5 +95,6 @@ schema/layout/v0.1.1.xsd schema/layout/v0.1.2.xsd schema/layout/v0.1.3.xsd + schema/layout/v0.1.4.xsd diff --git a/src/libs/ifc/schema/layout/v0.1.4.xsd b/src/libs/ifc/schema/layout/v0.1.4.xsd new file mode 100644 index 000000000..5978c1438 --- /dev/null +++ b/src/libs/ifc/schema/layout/v0.1.4.xsd @@ -0,0 +1,568 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/ifc/schema/pattern/v0.9.2.xsd b/src/libs/ifc/schema/pattern/v0.9.2.xsd index b9a8f96e1..39e92a10c 100644 --- a/src/libs/ifc/schema/pattern/v0.9.2.xsd +++ b/src/libs/ifc/schema/pattern/v0.9.2.xsd @@ -953,6 +953,8 @@ + + diff --git a/src/libs/ifc/xml/vlayoutconverter.cpp b/src/libs/ifc/xml/vlayoutconverter.cpp index 6c93c9086..b7dc8d2dd 100644 --- a/src/libs/ifc/xml/vlayoutconverter.cpp +++ b/src/libs/ifc/xml/vlayoutconverter.cpp @@ -39,8 +39,8 @@ */ const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0"); -const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.3"); -const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.3.xsd"); +const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.4"); +const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.4.xsd"); //VLayoutConverter::LayoutMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! //VLayoutConverter::LayoutMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! @@ -125,7 +125,8 @@ auto VLayoutConverter::XSDSchemas() -> QHash std::make_pair(FormatVersion(0, 1, 0), QStringLiteral("://schema/layout/v0.1.0.xsd")), std::make_pair(FormatVersion(0, 1, 1), QStringLiteral("://schema/layout/v0.1.1.xsd")), std::make_pair(FormatVersion(0, 1, 2), QStringLiteral("://schema/layout/v0.1.2.xsd")), - std::make_pair(FormatVersion(0, 1, 3), CurrentSchema), + std::make_pair(FormatVersion(0, 1, 3), QStringLiteral("://schema/layout/v0.1.3.xsd")), + std::make_pair(FormatVersion(0, 1, 4), CurrentSchema), }; return schemas; @@ -156,9 +157,12 @@ void VLayoutConverter::ApplyPatches() case (FormatVersion(0, 1, 1)): case (FormatVersion(0, 1, 2)): ToV0_1_3(); - ValidateXML(XSDSchema(FormatVersion(0, 1, 3))); Q_FALLTHROUGH(); case (FormatVersion(0, 1, 3)): + ToV0_1_4(); + ValidateXML(CurrentSchema); + Q_FALLTHROUGH(); + case (FormatVersion(0, 1, 4)): break; default: InvalidVersion(m_ver); @@ -271,3 +275,13 @@ void VLayoutConverter::ToV0_1_3() SetVersion(QStringLiteral("0.1.3")); Save(); } + +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutConverter::ToV0_1_4() +{ + // TODO. Delete if minimal supported version is 0.1.4 + Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 4), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.1.4")); + Save(); +} diff --git a/src/libs/ifc/xml/vlayoutconverter.h b/src/libs/ifc/xml/vlayoutconverter.h index 65277b2c7..604af5289 100644 --- a/src/libs/ifc/xml/vlayoutconverter.h +++ b/src/libs/ifc/xml/vlayoutconverter.h @@ -46,7 +46,7 @@ public: static const QString LayoutMaxVerStr; static const QString CurrentSchema; static Q_DECL_CONSTEXPR const unsigned LayoutMinVer = FormatVersion(0, 1, 0); - static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 3); + static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 4); static auto XSDSchemas() -> QHash ; @@ -70,6 +70,7 @@ protected: void ConvertPathToV0_1_3(QDomElement &node); void ToV0_1_3(); + void ToV0_1_4(); private: Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT diff --git a/src/libs/vlayout/vabstractpiece.cpp b/src/libs/vlayout/vabstractpiece.cpp index decb9ece4..96942b8d9 100644 --- a/src/libs/vlayout/vabstractpiece.cpp +++ b/src/libs/vlayout/vabstractpiece.cpp @@ -1778,14 +1778,44 @@ auto VAbstractPiece::GrainlinePoints(const VGrainlineData &geom, const VContaine v << QPointF(pt1.x() + dArrowLen * qCos(rotation - dArrowAng), pt1.y() - dArrowLen * qSin(rotation - dArrowAng)); v << pt1; + + if (geom.GetArrowType() == GrainlineArrowDirection::atFourWay) + { // second double arrow + QLineF line(pt2, pt1); + line.setLength(line.length() - dArrowLen - dArrowLen*0.5); + + v << line.p2(); + v << QPointF(line.p2().x() + dArrowLen * qCos(rotation + dArrowAng), + line.p2().y() - dArrowLen * qSin(rotation + dArrowAng)); + v << QPointF(line.p2().x() + dArrowLen * qCos(rotation - dArrowAng), + line.p2().y() - dArrowLen * qSin(rotation - dArrowAng)); + v << line.p2(); + } } - v << pt2; + if (geom.GetArrowType() != GrainlineArrowDirection::atFourWay) + { + v << pt2; + } if (geom.GetArrowType() != GrainlineArrowDirection::atRear) { rotation += M_PI; + if (geom.GetArrowType() == GrainlineArrowDirection::atFourWay) + { // first double arrow + QLineF line(pt1, pt2); + line.setLength(line.length() - dArrowLen - dArrowLen*0.5); + + v << line.p2(); + v << QPointF(line.p2().x() + dArrowLen * qCos(rotation + dArrowAng), + line.p2().y() - dArrowLen * qSin(rotation + dArrowAng)); + v << QPointF(line.p2().x() + dArrowLen * qCos(rotation - dArrowAng), + line.p2().y() - dArrowLen * qSin(rotation - dArrowAng)); + v << line.p2(); + v << pt2; + } + v << QPointF(pt2.x() + dArrowLen * qCos(rotation + dArrowAng), pt2.y() - dArrowLen * qSin(rotation + dArrowAng)); v << QPointF(pt2.x() + dArrowLen * qCos(rotation - dArrowAng), diff --git a/src/libs/vlayout/vposition.cpp b/src/libs/vlayout/vposition.cpp index 37595054b..9911721c3 100644 --- a/src/libs/vlayout/vposition.cpp +++ b/src/libs/vlayout/vposition.cpp @@ -588,7 +588,24 @@ void VPosition::FollowGrainline() if (m_data.detail.GrainlineArrowType() == GrainlineArrowDirection::atBoth || m_data.detail.GrainlineArrowType() == GrainlineArrowDirection::atRear) { - RotateOnAngle(angle+180); + RotateOnAngle(angle + 180); + } + + if (stop->load()) + { + return; + } + + if (m_data.detail.GrainlineArrowType() == GrainlineArrowDirection::atFourWay) + { + RotateOnAngle(angle + 90); + + if (stop->load()) + { + return; + } + + RotateOnAngle(angle - 90); } } diff --git a/src/libs/vpatterndb/floatItemData/floatitemdef.h b/src/libs/vpatterndb/floatItemData/floatitemdef.h index 81cb2bd9c..cd115b2f8 100644 --- a/src/libs/vpatterndb/floatItemData/floatitemdef.h +++ b/src/libs/vpatterndb/floatItemData/floatitemdef.h @@ -37,7 +37,8 @@ enum class GrainlineArrowDirection : qint8 { atBoth, atFront, - atRear + atRear, + atFourWay }; #endif // FLOATITEMDEF_H diff --git a/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.cpp b/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.cpp index f6de22fea..0c1c0dcda 100644 --- a/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.cpp +++ b/src/libs/vtools/dialogs/tools/piece/dialogseamallowance.cpp @@ -3383,6 +3383,7 @@ void DialogSeamAllowance::InitGrainlineTab() uiTabGrainline->comboBoxArrow->addItem(tr("Both")); uiTabGrainline->comboBoxArrow->addItem(tr("Just front")); uiTabGrainline->comboBoxArrow->addItem(tr("Just rear")); + uiTabGrainline->comboBoxArrow->addItem(tr("Four way")); m_iRotBaseHeight = uiTabGrainline->lineEditRotFormula->height(); m_iLenBaseHeight = uiTabGrainline->lineEditLenFormula->height(); diff --git a/src/libs/vwidgets/vgrainlineitem.cpp b/src/libs/vwidgets/vgrainlineitem.cpp index b4e57545e..3698b5a1c 100644 --- a/src/libs/vwidgets/vgrainlineitem.cpp +++ b/src/libs/vwidgets/vgrainlineitem.cpp @@ -122,12 +122,26 @@ void VGrainlineItem::paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption if (m_eArrowType != GrainlineArrowDirection::atRear) { // first arrow - pP->drawPolygon(FirstArrow(dArrLen)); + pP->drawPolygon(FirstArrow(MainLine().p2(), dArrLen)); + + if (m_eArrowType == GrainlineArrowDirection::atFourWay) + { // first double arrow + QLineF line = MainLine(); + line.setLength(line.length() - dArrLen - dArrLen*0.5); + pP->drawPolygon(FirstArrow(line.p2(), dArrLen)); + } } if (m_eArrowType != GrainlineArrowDirection::atFront) { // second arrow - pP->drawPolygon(SecondArrow(dArrLen)); + pP->drawPolygon(SecondArrow(MainLine().p1(), dArrLen)); + + if (m_eArrowType == GrainlineArrowDirection::atFourWay) + { // second double arrow + QLineF line(MainLine().p2(), MainLine().p1()); + line.setLength(line.length() - dArrLen - dArrLen*0.5); + pP->drawPolygon(SecondArrow(line.p2(), dArrLen)); + } } if (m_eMode != mNormal) @@ -636,28 +650,26 @@ QLineF VGrainlineItem::MainLine() const } //--------------------------------------------------------------------------------------------------------------------- -QPolygonF VGrainlineItem::FirstArrow(qreal dArrLen) const +QPolygonF VGrainlineItem::FirstArrow(const QPointF &pt, qreal dArrLen) const { - const QPointF pt2 = MainLine().p2(); QPolygonF poly; - poly << pt2; - poly << QPointF(pt2.x() + dArrLen*cos(M_PI + m_dRotation + ARROW_ANGLE), - pt2.y() - dArrLen*sin(M_PI + m_dRotation + ARROW_ANGLE)); - poly << QPointF(pt2.x() + dArrLen*cos(M_PI + m_dRotation - ARROW_ANGLE), - pt2.y() - dArrLen*sin(M_PI + m_dRotation - ARROW_ANGLE)); + poly << pt; + poly << QPointF(pt.x() + dArrLen*cos(M_PI + m_dRotation + ARROW_ANGLE), + pt.y() - dArrLen*sin(M_PI + m_dRotation + ARROW_ANGLE)); + poly << QPointF(pt.x() + dArrLen*cos(M_PI + m_dRotation - ARROW_ANGLE), + pt.y() - dArrLen*sin(M_PI + m_dRotation - ARROW_ANGLE)); return poly; } //--------------------------------------------------------------------------------------------------------------------- -QPolygonF VGrainlineItem::SecondArrow(qreal dArrLen) const +QPolygonF VGrainlineItem::SecondArrow(const QPointF &pt, qreal dArrLen) const { - const QPointF pt1 = MainLine().p1(); QPolygonF poly; - poly << pt1; - poly << QPointF(pt1.x() + dArrLen*cos(m_dRotation + ARROW_ANGLE), - pt1.y() - dArrLen*sin(m_dRotation + ARROW_ANGLE)); - poly << QPointF(pt1.x() + dArrLen*cos(m_dRotation - ARROW_ANGLE), - pt1.y() - dArrLen*sin(m_dRotation - ARROW_ANGLE)); + poly << pt; + poly << QPointF(pt.x() + dArrLen*cos(m_dRotation + ARROW_ANGLE), + pt.y() - dArrLen*sin(m_dRotation + ARROW_ANGLE)); + poly << QPointF(pt.x() + dArrLen*cos(m_dRotation - ARROW_ANGLE), + pt.y() - dArrLen*sin(m_dRotation - ARROW_ANGLE)); return poly; } @@ -681,7 +693,15 @@ QPainterPath VGrainlineItem::MainShape() const { // first arrow QPainterPath polyPath; - polyPath.addPolygon(FirstArrow(dArrLen)); + polyPath.addPolygon(FirstArrow(MainLine().p2(), dArrLen)); + + if (m_eArrowType == GrainlineArrowDirection::atFourWay) + { // first double arrow + QLineF line = MainLine(); + line.setLength(line.length() - dArrLen - 0.5); + polyPath.addPolygon(FirstArrow(line.p2(), dArrLen)); + } + path.addPath((stroker.createStroke(polyPath) + polyPath).simplified()); path.closeSubpath(); } @@ -690,7 +710,15 @@ QPainterPath VGrainlineItem::MainShape() const { // second arrow QPainterPath polyPath; - polyPath.addPolygon(SecondArrow(dArrLen)); + polyPath.addPolygon(SecondArrow(MainLine().p1(), dArrLen)); + + if (m_eArrowType == GrainlineArrowDirection::atFourWay) + { // second double arrow + QLineF line(MainLine().p2(), MainLine().p1()); + line.setLength(line.length() - dArrLen - 0.5); + polyPath.addPolygon(SecondArrow(line.p2(), dArrLen)); + } + path.addPath((stroker.createStroke(polyPath) + polyPath).simplified()); path.closeSubpath(); } diff --git a/src/libs/vwidgets/vgrainlineitem.h b/src/libs/vwidgets/vgrainlineitem.h index 7dfbe82ae..43ea382c5 100644 --- a/src/libs/vwidgets/vgrainlineitem.h +++ b/src/libs/vwidgets/vgrainlineitem.h @@ -84,12 +84,12 @@ private: QPointF m_ptFinish; QPointF m_ptCenter; qreal m_dAngle; - GrainlineArrowDirection m_eArrowType; + GrainlineArrowDirection m_eArrowType; double m_penWidth{1}; QLineF MainLine() const; - QPolygonF FirstArrow(qreal dArrLen) const; - QPolygonF SecondArrow(qreal dArrLen) const; + QPolygonF FirstArrow(const QPointF &pt, qreal dArrLen) const; + QPolygonF SecondArrow(const QPointF &pt, qreal dArrLen) const; QPainterPath MainShape() const;