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;