diff --git a/ChangeLog.txt b/ChangeLog.txt index 0d0ab8011..2d83b844c 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -53,6 +53,7 @@ - [#862] Force Valentina to immediately terminate if a pattern contains a parsing warning. - [#865] New feature. Dynamic Way to define Material in piece label. - [#867] Visibility control for place labels. +- [#868] New feature. Connect internal path with cutting contour. # Version 0.5.1 (unreleased) - [#683] Tool Seam allowance's dialog is off screen on small resolutions. diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp index de073314e..c8c557f77 100644 --- a/src/app/valentina/xml/vpattern.cpp +++ b/src/app/valentina/xml/vpattern.cpp @@ -3746,10 +3746,12 @@ void VPattern::ParsePathElement(VMainGraphicsScene *scene, QDomElement &domEleme initData.path.SetType(static_cast(GetParametrUInt(domElement, AttrType, defType))); initData.path.SetName(GetParametrString(domElement, AttrName, tr("Unnamed path"))); initData.path.SetPenType(LineStyleToPenStyle(GetParametrString(domElement, AttrTypeLine, TypeLineLine))); - initData.path.SetCutPath(GetParametrBool(domElement, AttrCut, falseStr)); if (initData.path.GetType() == PiecePathType::InternalPath) { + initData.path.SetCutPath(GetParametrBool(domElement, AttrCut, falseStr)); + initData.path.SetFirstToCuttingCountour(GetParametrBool(domElement, AttrFirstToCountour, falseStr)); + initData.path.SetLastToCuttingCountour(GetParametrBool(domElement, AttrLastToCountour, falseStr)); initData.path.SetVisibilityTrigger(GetParametrString(domElement, AttrVisible, QChar('1'))); } diff --git a/src/libs/ifc/ifcdef.cpp b/src/libs/ifc/ifcdef.cpp index 11e0d788b..f702c1aea 100644 --- a/src/libs/ifc/ifcdef.cpp +++ b/src/libs/ifc/ifcdef.cpp @@ -130,6 +130,8 @@ const QString AttrWidth = QStringLiteral("width"); const QString AttrHeight = QStringLiteral("height"); const QString AttrPlaceLabelType = QStringLiteral("placeLabelType"); const QString AttrVersion = QStringLiteral("version"); +const QString AttrFirstToCountour = QStringLiteral("firstToCountour"); +const QString AttrLastToCountour = QStringLiteral("lastToCountour"); const QString TypeLineNone = QStringLiteral("none"); const QString TypeLineLine = QStringLiteral("hair"); diff --git a/src/libs/ifc/ifcdef.h b/src/libs/ifc/ifcdef.h index f3b472e7e..471d2f929 100644 --- a/src/libs/ifc/ifcdef.h +++ b/src/libs/ifc/ifcdef.h @@ -151,6 +151,8 @@ extern const QString AttrWidth; extern const QString AttrHeight; extern const QString AttrPlaceLabelType; extern const QString AttrVersion; +extern const QString AttrFirstToCountour; +extern const QString AttrLastToCountour; extern const QString TypeLineNone; extern const QString TypeLineLine; diff --git a/src/libs/ifc/schema.qrc b/src/libs/ifc/schema.qrc index 851514a50..d326aa2dc 100644 --- a/src/libs/ifc/schema.qrc +++ b/src/libs/ifc/schema.qrc @@ -51,6 +51,7 @@ schema/pattern/v0.7.7.xsd schema/pattern/v0.7.8.xsd schema/pattern/v0.7.9.xsd + schema/pattern/v0.7.10.xsd schema/standard_measurements/v0.3.0.xsd schema/standard_measurements/v0.4.0.xsd schema/standard_measurements/v0.4.1.xsd diff --git a/src/libs/ifc/schema/pattern/v0.7.10.xsd b/src/libs/ifc/schema/pattern/v0.7.10.xsd new file mode 100644 index 000000000..c50be206f --- /dev/null +++ b/src/libs/ifc/schema/pattern/v0.7.10.xsd @@ -0,0 +1,1064 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/ifc/xml/vpatternconverter.cpp b/src/libs/ifc/xml/vpatternconverter.cpp index b8112eecf..3a47c373a 100644 --- a/src/libs/ifc/xml/vpatternconverter.cpp +++ b/src/libs/ifc/xml/vpatternconverter.cpp @@ -59,8 +59,8 @@ class QDomElement; */ const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.0"); -const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.7.9"); -const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.7.9.xsd"); +const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.7.10"); +const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.7.10.xsd"); //VPatternConverter::PatternMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! //VPatternConverter::PatternMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! @@ -229,7 +229,8 @@ QString VPatternConverter::XSDSchema(int ver) const std::make_pair(0x000706, QStringLiteral("://schema/pattern/v0.7.6.xsd")), std::make_pair(0x000707, QStringLiteral("://schema/pattern/v0.7.7.xsd")), std::make_pair(0x000708, QStringLiteral("://schema/pattern/v0.7.8.xsd")), - std::make_pair(0x000709, CurrentSchema) + std::make_pair(0x000709, QStringLiteral("://schema/pattern/v0.7.9.xsd")), + std::make_pair(0x00070A, CurrentSchema) }; if (schemas.contains(ver)) @@ -448,6 +449,10 @@ void VPatternConverter::ApplyPatches() ValidateXML(XSDSchema(0x000709), m_convertedFileName); V_FALLTHROUGH case (0x000709): + ToV0_7_10(); + ValidateXML(XSDSchema(0x00070A), m_convertedFileName); + V_FALLTHROUGH + case (0x00070A): break; default: InvalidVersion(m_ver); @@ -465,7 +470,7 @@ void VPatternConverter::DowngradeToCurrentMaxVersion() bool VPatternConverter::IsReadOnly() const { // Check if attribute readOnly was not changed in file format - Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 7, 9), + Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 7, 10), "Check attribute readOnly."); // Possibly in future attribute readOnly will change position etc. @@ -1029,6 +1034,16 @@ void VPatternConverter::ToV0_7_9() Save(); } +//--------------------------------------------------------------------------------------------------------------------- +void VPatternConverter::ToV0_7_10() +{ + // TODO. Delete if minimal supported version is 0.7.10 + Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 7, 10), + "Time to refactor the code."); + SetVersion(QStringLiteral("0.7.10")); + Save(); +} + //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::TagUnitToV0_2_0() { diff --git a/src/libs/ifc/xml/vpatternconverter.h b/src/libs/ifc/xml/vpatternconverter.h index 0592d20ec..a29499ae3 100644 --- a/src/libs/ifc/xml/vpatternconverter.h +++ b/src/libs/ifc/xml/vpatternconverter.h @@ -53,7 +53,7 @@ public: static const QString PatternMaxVerStr; static const QString CurrentSchema; static Q_DECL_CONSTEXPR const int PatternMinVer = CONVERTER_VERSION_CHECK(0, 1, 0); - static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 7, 9); + static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 7, 10); protected: virtual int MinVer() const override; @@ -122,6 +122,7 @@ private: void ToV0_7_7(); void ToV0_7_8(); void ToV0_7_9(); + void ToV0_7_10(); void TagUnitToV0_2_0(); void TagIncrementToV0_2_0(); diff --git a/src/libs/vgeometry/vabstractcurve.cpp b/src/libs/vgeometry/vabstractcurve.cpp index 2fe372621..d64690084 100644 --- a/src/libs/vgeometry/vabstractcurve.cpp +++ b/src/libs/vgeometry/vabstractcurve.cpp @@ -327,6 +327,63 @@ QVector VAbstractCurve::CurveIntersectLine(const QVector &poin return intersections; } +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractCurve::CurveIntersectAxis(const QPointF &point, qreal angle, const QVector &curvePoints, + QPointF *intersectionPoint) +{ + SCASSERT(intersectionPoint != nullptr) + + QRectF rec = QRectF(0, 0, INT_MAX, INT_MAX); + rec.translate(-INT_MAX/2.0, -INT_MAX/2.0); + + const QLineF axis = VGObject::BuildAxis(point, angle, rec); + const QVector points = VAbstractCurve::CurveIntersectLine(curvePoints, axis); + + if (points.size() > 0) + { + if (points.size() == 1) + { + *intersectionPoint = points.at(0); + return true; + } + + QMap forward; + QMap backward; + + for ( qint32 i = 0; i < points.size(); ++i ) + { + if (points.at(i) == point) + { // Always seek unique intersection + continue; + } + + const QLineF length(point, points.at(i)); + if (qAbs(length.angle()-angle) < 0.1) + { + forward.insert(length.length(), i); + } + else + { + backward.insert(length.length(), i); + } + } + + // Closest point is not always want we need. First return point in forward direction if exists. + if (not forward.isEmpty()) + { + *intersectionPoint = points.at(forward.first()); + return true; + } + else if (not backward.isEmpty()) + { + *intersectionPoint = points.at(backward.first()); + return true; + } + } + + return false; +} + //--------------------------------------------------------------------------------------------------------------------- QVector VAbstractCurve::DirectionArrows() const { diff --git a/src/libs/vgeometry/vabstractcurve.h b/src/libs/vgeometry/vabstractcurve.h index 84495e1ef..c57e5e5b8 100644 --- a/src/libs/vgeometry/vabstractcurve.h +++ b/src/libs/vgeometry/vabstractcurve.h @@ -95,6 +95,8 @@ public: static qreal PathLength(const QVector &path); static QVector CurveIntersectLine(const QVector &points, const QLineF &line); + static bool CurveIntersectAxis(const QPointF &point, qreal angle, const QVector &curvePoints, + QPointF *intersectionPoint); virtual QString NameForHistory(const QString &toolName) const=0; virtual QVector DirectionArrows() const; diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index 9945cfd94..da7c63278 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -66,12 +66,13 @@ QVector ConvertInternalPaths(const VPiece &piece, const VConta QVector paths; const QVector pathsId = piece.GetInternalPaths(); + const QVector cuttingPath = piece.CuttingPathPoints(pattern); for (auto id : pathsId) { const VPiecePath path = pattern->GetPiecePath(id); if (path.GetType() == PiecePathType::InternalPath && path.IsVisible(pattern->DataVariables())) { - paths.append(VLayoutPiecePath(path.PathPoints(pattern), path.IsCutPath(), path.GetPenType())); + paths.append(VLayoutPiecePath(path.PathPoints(pattern, cuttingPath), path.IsCutPath(), path.GetPenType())); } } return paths; diff --git a/src/libs/vpatterndb/vcontainer.cpp b/src/libs/vpatterndb/vcontainer.cpp index 1d16a0491..ba44d3055 100644 --- a/src/libs/vpatterndb/vcontainer.cpp +++ b/src/libs/vpatterndb/vcontainer.cpp @@ -163,6 +163,22 @@ VPiecePath VContainer::GetPiecePath(quint32 id) const } } +//--------------------------------------------------------------------------------------------------------------------- +quint32 VContainer::GetPieceForPiecePath(quint32 id) const +{ + auto i = d->pieces->constBegin(); + while (i != d->pieces->constEnd()) + { + if (i.value().GetInternalPaths().contains(id)) + { + return i.key(); + } + ++i; + } + + return NULL_ID; +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief AddGObject add new GObject to container diff --git a/src/libs/vpatterndb/vcontainer.h b/src/libs/vpatterndb/vcontainer.h index c2059e860..264d23adb 100644 --- a/src/libs/vpatterndb/vcontainer.h +++ b/src/libs/vpatterndb/vcontainer.h @@ -136,6 +136,7 @@ public: static const QSharedPointer GetFakeGObject(quint32 id); VPiece GetPiece(quint32 id) const; VPiecePath GetPiecePath(quint32 id) const; + quint32 GetPieceForPiecePath(quint32 id) const; template QSharedPointer GetVariable(QString name) const; static quint32 getId(); diff --git a/src/libs/vpatterndb/vpiece.cpp b/src/libs/vpatterndb/vpiece.cpp index dfad10a6b..233dacae7 100644 --- a/src/libs/vpatterndb/vpiece.cpp +++ b/src/libs/vpatterndb/vpiece.cpp @@ -415,6 +415,19 @@ QVector VPiece::SeamAllowancePoints(const VContainer *data) const return Equidistant(pointsEkv, width); } +//--------------------------------------------------------------------------------------------------------------------- +QVector VPiece::CuttingPathPoints(const VContainer *data) const +{ + if (IsSeamAllowance() and not IsSeamAllowanceBuiltIn()) + { + return SeamAllowancePoints(data); + } + else + { + return MainPathPoints(data); + } +} + //--------------------------------------------------------------------------------------------------------------------- QVector VPiece::PassmarksLines(const VContainer *data, const QVector &seamAllowance) const { diff --git a/src/libs/vpatterndb/vpiece.h b/src/libs/vpatterndb/vpiece.h index 5f751fbb5..4f1c65810 100644 --- a/src/libs/vpatterndb/vpiece.h +++ b/src/libs/vpatterndb/vpiece.h @@ -70,6 +70,7 @@ public: QVector MainPathPoints(const VContainer *data) const; QVector MainPathNodePoints(const VContainer *data, bool showExcluded = false) const; QVector SeamAllowancePoints(const VContainer *data) const; + QVector CuttingPathPoints(const VContainer *data) const; QVector PassmarksLines(const VContainer *data, const QVector &seamAllowance = QVector()) const; QVector PlaceLabelPoints(const VContainer *data) const; diff --git a/src/libs/vpatterndb/vpiecepath.cpp b/src/libs/vpatterndb/vpiecepath.cpp index 1d233ac59..004d54a1d 100644 --- a/src/libs/vpatterndb/vpiecepath.cpp +++ b/src/libs/vpatterndb/vpiecepath.cpp @@ -32,6 +32,8 @@ #include "../vgeometry/vpointf.h" #include "../vlayout/vabstractpiece.h" #include "calculator.h" +#include "../vmisc/vabstractapplication.h" +#include "../ifc/exception/vexceptionobjecterror.h" #include @@ -142,6 +144,51 @@ QPainterPath MakePainterPath(const QVector &points) return path; } + +//--------------------------------------------------------------------------------------------------------------------- +qreal FindTipDirection(const QVector &points) +{ + if (points.size() <= 1) + { + return 0; + } + + const QPointF first = points.first(); + + for(int i = 1; i < points.size(); ++i) + { + if (first != points.at(i)) + { + QLineF line(first, points.at(i)); + line.setAngle(line.angle() + 180); + return line.angle(); + } + } + + return 0; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool IntersectionWithCuttingCountour(const QVector &cuttingPath, const QVector &points, + QPointF *firstConnection) +{ + if (points.size() <= 1) + { + return false; + } + + const QPointF first = points.first(); + + if (VAbstractCurve::IsPointOnCurve(cuttingPath, first)) + { // Point is already part of a cutting countour + *firstConnection = first; + return true; + } + else + { + return VAbstractCurve::CurveIntersectAxis(first, FindTipDirection(points), cuttingPath, firstConnection); + } +} } //--------------------------------------------------------------------------------------------------------------------- @@ -277,7 +324,31 @@ void VPiecePath::SetVisibilityTrigger(const QString &formula) } //--------------------------------------------------------------------------------------------------------------------- -QVector VPiecePath::PathPoints(const VContainer *data) const +void VPiecePath::SetFirstToCuttingCountour(bool value) +{ + d->m_firstToCuttingCountour = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPiecePath::IsFirstToCuttingCountour() const +{ + return d->m_firstToCuttingCountour; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPiecePath::SetLastToCuttingCountour(bool value) +{ + d->m_lastToCuttingCountour = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPiecePath::IsLastToCuttingCountour() const +{ + return d->m_lastToCuttingCountour; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VPiecePath::PathPoints(const VContainer *data, const QVector &cuttingPath) const { QVector points; for (int i = 0; i < CountNodes(); ++i) @@ -314,6 +385,46 @@ QVector VPiecePath::PathPoints(const VContainer *data) const } } + if (GetType() == PiecePathType::InternalPath && not cuttingPath.isEmpty() && points.size() > 1) + { + QVector extended = points; + + if (IsFirstToCuttingCountour()) + { + QPointF firstConnection; + if (IntersectionWithCuttingCountour(cuttingPath, points, &firstConnection)) + { + extended.prepend(firstConnection); + } + else + { + const QString errorMsg = QObject::tr("Error in internal path '%1'. There is no intersection of first " + "point with cutting countour") + .arg(GetName()); + qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg; + } + } + + if (IsLastToCuttingCountour()) + { + QPointF lastConnection; + if (IntersectionWithCuttingCountour(cuttingPath, VGObject::GetReversePoints(points), + &lastConnection)) + { + extended.append(lastConnection); + } + else + { + const QString errorMsg = QObject::tr("Error in internal path '%1'. There is no intersection of last " + "point with cutting countour") + .arg(GetName()); + qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg; + } + } + + points = extended; + } + return points; } @@ -421,9 +532,9 @@ QVector VPiecePath::SeamAllowancePoints(const VContainer *data, qreal } //--------------------------------------------------------------------------------------------------------------------- -QPainterPath VPiecePath::PainterPath(const VContainer *data) const +QPainterPath VPiecePath::PainterPath(const VContainer *data, const QVector &cuttingPath) const { - return MakePainterPath(PathPoints(data)); + return MakePainterPath(PathPoints(data, cuttingPath)); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vpatterndb/vpiecepath.h b/src/libs/vpatterndb/vpiecepath.h index b4a3b8a32..36548f73f 100644 --- a/src/libs/vpatterndb/vpiecepath.h +++ b/src/libs/vpatterndb/vpiecepath.h @@ -85,12 +85,19 @@ public: QString GetVisibilityTrigger() const; void SetVisibilityTrigger(const QString &formula); - QVector PathPoints(const VContainer *data) const; + void SetFirstToCuttingCountour(bool value); + bool IsFirstToCuttingCountour() const; + + void SetLastToCuttingCountour(bool value); + bool IsLastToCuttingCountour() const; + + QVector PathPoints(const VContainer *data, + const QVector &cuttingPath = QVector()) const; QVector PathNodePoints(const VContainer *data, bool showExcluded = true) const; QVector > PathCurvePoints(const VContainer *data) const; QVector SeamAllowancePoints(const VContainer *data, qreal width, bool reverse) const; - QPainterPath PainterPath(const VContainer *data) const; + QPainterPath PainterPath(const VContainer *data, const QVector &cuttingPath) const; QVector CurvesPainterPath(const VContainer *data) const; QList Dependencies() const; diff --git a/src/libs/vpatterndb/vpiecepath_p.h b/src/libs/vpatterndb/vpiecepath_p.h index 08f22c268..5ee4303b4 100644 --- a/src/libs/vpatterndb/vpiecepath_p.h +++ b/src/libs/vpatterndb/vpiecepath_p.h @@ -48,7 +48,9 @@ public: m_name(), m_penType(Qt::SolidLine), m_cut(false), - m_visibilityTrigger('1') + m_visibilityTrigger('1'), + m_firstToCuttingCountour(false), + m_lastToCuttingCountour(false) {} explicit VPiecePathData(PiecePathType type) @@ -57,7 +59,9 @@ public: m_name(), m_penType(Qt::SolidLine), m_cut(false), - m_visibilityTrigger('1') + m_visibilityTrigger('1'), + m_firstToCuttingCountour(false), + m_lastToCuttingCountour(false) {} VPiecePathData(const VPiecePathData &path) @@ -67,7 +71,9 @@ public: m_name(path.m_name), m_penType(path.m_penType), m_cut(path.m_cut), - m_visibilityTrigger(path.m_visibilityTrigger) + m_visibilityTrigger(path.m_visibilityTrigger), + m_firstToCuttingCountour(path.m_firstToCuttingCountour), + m_lastToCuttingCountour(path.m_lastToCuttingCountour) {} ~VPiecePathData(); @@ -78,6 +84,8 @@ public: Qt::PenStyle m_penType; bool m_cut; QString m_visibilityTrigger; + bool m_firstToCuttingCountour; + bool m_lastToCuttingCountour; private: VPiecePathData &operator=(const VPiecePathData &) Q_DECL_EQ_DELETE; diff --git a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.cpp b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.cpp index 2b86fdc2a..34c52a033 100644 --- a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.cpp +++ b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.cpp @@ -37,6 +37,21 @@ #include #include +namespace +{ +QVector CuttingPath(quint32 id, const VContainer *data) +{ + QVector path; + const quint32 pieceId = data->GetPieceForPiecePath(id); + if (pieceId > NULL_ID) + { + path = data->GetPiece(pieceId).CuttingPathPoints(data); + } + + return path; +} +} + //--------------------------------------------------------------------------------------------------------------------- DialogPiecePath::DialogPiecePath(const VContainer *data, quint32 toolId, QWidget *parent) : DialogTool(data, toolId, parent), @@ -151,6 +166,7 @@ void DialogPiecePath::ChosenObject(quint32 id, const SceneObject &type) SCASSERT(visPath != nullptr); const VPiecePath p = CreatePath(); visPath->SetPath(p); + visPath->SetCuttingPath(CuttingPath(toolId, data)); if (p.CountNodes() == 1) { @@ -347,6 +363,7 @@ void DialogPiecePath::ListChanged() auto visPath = qobject_cast(vis); SCASSERT(visPath != nullptr); visPath->SetPath(CreatePath()); + visPath->SetCuttingPath(CuttingPath(toolId, data)); visPath->RefreshGeometry(); } @@ -882,9 +899,12 @@ void DialogPiecePath::InitPathTab() InitPathTypes(); connect(ui->comboBoxType, QOverload::of(&QComboBox::currentIndexChanged), this, [this]() { - ui->comboBoxPenType->setEnabled(GetType() == PiecePathType::InternalPath); - ui->checkBoxCut->setEnabled(GetType() == PiecePathType::InternalPath); - ui->tabControl->setEnabled(GetType() == PiecePathType::InternalPath); + const bool isInternalPath = GetType() == PiecePathType::InternalPath; + ui->comboBoxPenType->setEnabled(isInternalPath); + ui->checkBoxCut->setEnabled(isInternalPath); + ui->tabControl->setEnabled(isInternalPath); + ui->checkBoxFirstPointToCuttingContour->setEnabled(isInternalPath); + ui->checkBoxLastPointToCuttingContour->setEnabled(isInternalPath); ValidObjects(PathIsValid()); }); @@ -1092,8 +1112,12 @@ void DialogPiecePath::SetPiecePath(const VPiecePath &path) VisToolPiecePath *visPath = qobject_cast(vis); SCASSERT(visPath != nullptr); visPath->SetPath(path); + visPath->SetCuttingPath(CuttingPath(toolId, data)); + SetPenType(path.GetPenType()); SetCutPath(path.IsCutPath()); + ui->checkBoxFirstPointToCuttingContour->setChecked(path.IsFirstToCuttingCountour()); + ui->checkBoxLastPointToCuttingContour->setChecked(path.IsLastToCuttingCountour()); if (path.GetType() == PiecePathType::InternalPath) { @@ -1126,6 +1150,8 @@ void DialogPiecePath::SetType(PiecePathType type) ui->comboBoxPenType->setEnabled(type == PiecePathType::InternalPath); ui->checkBoxCut->setEnabled(type == PiecePathType::InternalPath); + ui->checkBoxFirstPointToCuttingContour->setEnabled(type == PiecePathType::InternalPath); + ui->checkBoxLastPointToCuttingContour->setEnabled(type == PiecePathType::InternalPath); } //--------------------------------------------------------------------------------------------------------------------- @@ -1250,6 +1276,7 @@ void DialogPiecePath::SetFormulaSAWidth(const QString &formula) VisToolPiecePath *path = qobject_cast(vis); SCASSERT(path != nullptr) path->SetPath(CreatePath()); + path->SetCuttingPath(CuttingPath(toolId, data)); if (ui->tabWidget->indexOf(ui->tabSeamAllowance) == -1) { @@ -1314,19 +1341,14 @@ VPiecePath DialogPiecePath::CreatePath() const path.Append(qvariant_cast(item->data(Qt::UserRole))); } + const bool isInternalPath = (GetType() == PiecePathType::InternalPath); path.SetType(GetType()); path.SetName(ui->lineEditName->text()); - path.SetPenType(GetType() == PiecePathType::InternalPath ? GetPenType() : Qt::SolidLine); - path.SetCutPath(GetType() == PiecePathType::InternalPath ? IsCutPath() : false); - - if (GetType() == PiecePathType::InternalPath) - { - path.SetVisibilityTrigger(GetFormulaVisible()); - } - else - { - path.SetVisibilityTrigger(QChar('1')); - } + path.SetPenType(isInternalPath ? GetPenType() : Qt::SolidLine); + path.SetCutPath(isInternalPath ? IsCutPath() : false); + path.SetFirstToCuttingCountour(isInternalPath ? ui->checkBoxFirstPointToCuttingContour->isChecked() : false); + path.SetLastToCuttingCountour(isInternalPath ? ui->checkBoxLastPointToCuttingContour->isChecked() : false); + path.SetVisibilityTrigger(isInternalPath ? GetFormulaVisible() : QChar('1')); return path; } diff --git a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.ui b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.ui index 843f6c43d..a116deb01 100644 --- a/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.ui +++ b/src/libs/vtools/dialogs/tools/piece/dialogpiecepath.ui @@ -95,6 +95,20 @@ + + + + Continue the first point to the cutting contour + + + + + + + Continue the last point to the cutting contour + + + @@ -1403,7 +1417,7 @@ - + diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/toollinepoint/vtoolcurveintersectaxis.cpp b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/toollinepoint/vtoolcurveintersectaxis.cpp index 3583f0a99..ae0bf77d8 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/toollinepoint/vtoolcurveintersectaxis.cpp +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/toollinepoint/vtoolcurveintersectaxis.cpp @@ -190,57 +190,7 @@ VToolCurveIntersectAxis *VToolCurveIntersectAxis::Create(VToolCurveIntersectAxis bool VToolCurveIntersectAxis::FindPoint(const QPointF &point, qreal angle, const QVector &curvePoints, QPointF *intersectionPoint) { - SCASSERT(intersectionPoint != nullptr) - - QRectF rec = QRectF(0, 0, INT_MAX, INT_MAX); - rec.translate(-INT_MAX/2.0, -INT_MAX/2.0); - - const QLineF axis = VGObject::BuildAxis(point, angle, rec); - const QVector points = VAbstractCurve::CurveIntersectLine(curvePoints, axis); - - if (points.size() > 0) - { - if (points.size() == 1) - { - *intersectionPoint = points.at(0); - return true; - } - - QMap forward; - QMap backward; - - for ( qint32 i = 0; i < points.size(); ++i ) - { - if (points.at(i) == point) - { // Always seek unique intersection - continue; - } - - const QLineF length(point, points.at(i)); - if (qAbs(length.angle()-angle) < 0.1) - { - forward.insert(length.length(), i); - } - else - { - backward.insert(length.length(), i); - } - } - - // Closest point is not always want we need. First return point in forward direction if exists. - if (not forward.isEmpty()) - { - *intersectionPoint = points.at(forward.first()); - return true; - } - else if (not backward.isEmpty()) - { - *intersectionPoint = points.at(backward.first()); - return true; - } - } - - return false; + return VAbstractCurve::CurveIntersectAxis(point, angle, curvePoints, intersectionPoint); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.cpp b/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.cpp index a7fa08f43..cc2b77cd3 100644 --- a/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.cpp +++ b/src/libs/vtools/tools/nodeDetails/vtoolpiecepath.cpp @@ -32,6 +32,7 @@ #include "../vpatterndb/vpiecenode.h" #include "../../undocommands/savepieceoptions.h" #include "../vtoolseamallowance.h" +#include "../ifc/xml/vabstractpattern.h" //--------------------------------------------------------------------------------------------------------------------- VToolPiecePath *VToolPiecePath::Create(const QPointer &dialog, VMainGraphicsScene *scene, @@ -194,6 +195,8 @@ void VToolPiecePath::AddAttributes(VAbstractPattern *doc, QDomElement &domElemen { doc->SetAttribute(domElement, VAbstractPattern::AttrVisible, path.GetVisibilityTrigger()); doc->SetAttribute(domElement, AttrCut, path.IsCutPath()); + doc->SetAttribute(domElement, AttrFirstToCountour, path.IsFirstToCuttingCountour()); + doc->SetAttribute(domElement, AttrLastToCountour, path.IsLastToCuttingCountour()); } } @@ -302,7 +305,16 @@ void VToolPiecePath::RefreshGeometry() const VPiecePath path = VAbstractTool::data.GetPiecePath(m_id); if (path.GetType() == PiecePathType::InternalPath) { - QPainterPath p = path.PainterPath(this->getData()); + QVector cuttingPath; + const quint32 pieceId = VAbstractTool::data.GetPieceForPiecePath(m_id); + if (pieceId > NULL_ID) + { + VPiece piece = VAbstractTool::data.GetPiece(pieceId); + // We cannot use current VContainer because it doesn't have current seam allowance value + const VContainer pData = VAbstractPattern::getTool(pieceId)->getData(); + cuttingPath = piece.CuttingPathPoints(&pData); + } + QPainterPath p = path.PainterPath(this->getData(), cuttingPath); p.setFillRule(Qt::OddEvenFill); this->setPath(p); diff --git a/src/libs/vtools/tools/vtoolseamallowance.cpp b/src/libs/vtools/tools/vtoolseamallowance.cpp index 44a583e66..1985ca1a4 100644 --- a/src/libs/vtools/tools/vtoolseamallowance.cpp +++ b/src/libs/vtools/tools/vtoolseamallowance.cpp @@ -145,6 +145,7 @@ VToolSeamAllowance *VToolSeamAllowance::Create(VToolSeamAllowanceInitData &initD initData.scene->addItem(piece); VMainGraphicsView::NewSceneRect(initData.scene, qApp->getSceneView(), piece); VAbstractPattern::AddTool(initData.id, piece); + piece->RefreshGeometry(true); // Refresh internal paths } //Very important to delete it. Only this tool need this special variable. initData.data->RemoveVariable(currentSeamAllowance); @@ -1297,7 +1298,6 @@ VToolSeamAllowance::VToolSeamAllowance(const VToolSeamAllowanceInitData &initDat AllowSelecting(true); EnableToolMove(true); AllowHover(true); - RefreshGeometry(); this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); this->setFlag(QGraphicsItem::ItemIsFocusable, true);// For keyboard input focus diff --git a/src/libs/vtools/visualization/path/vistoolpiecepath.cpp b/src/libs/vtools/visualization/path/vistoolpiecepath.cpp index 31ce60bc4..8e5a94f61 100644 --- a/src/libs/vtools/visualization/path/vistoolpiecepath.cpp +++ b/src/libs/vtools/visualization/path/vistoolpiecepath.cpp @@ -38,7 +38,8 @@ VisToolPiecePath::VisToolPiecePath(const VContainer *data, QGraphicsItem *parent : VisPath(data, parent), m_points(), m_line(nullptr), - m_path() + m_path(), + m_cuttingPath() { m_line = InitItem(supportColor, this); } @@ -50,7 +51,8 @@ void VisToolPiecePath::RefreshGeometry() if (m_path.CountNodes() > 0) { - DrawPath(this, m_path.PainterPath(Visualization::data), mainColor, m_path.GetPenType(), Qt::RoundCap); + DrawPath(this, m_path.PainterPath(Visualization::data, m_cuttingPath), mainColor, m_path.GetPenType(), + Qt::RoundCap); const QVector nodes = m_path.PathNodePoints(Visualization::data); @@ -79,6 +81,12 @@ void VisToolPiecePath::SetPath(const VPiecePath &path) m_path = path; } +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPiecePath::SetCuttingPath(const QVector &cuttingPath) +{ + m_cuttingPath = cuttingPath; +} + //--------------------------------------------------------------------------------------------------------------------- void VisToolPiecePath::mousePressEvent(QGraphicsSceneMouseEvent *event) { diff --git a/src/libs/vtools/visualization/path/vistoolpiecepath.h b/src/libs/vtools/visualization/path/vistoolpiecepath.h index 82a998e78..1208d5466 100644 --- a/src/libs/vtools/visualization/path/vistoolpiecepath.h +++ b/src/libs/vtools/visualization/path/vistoolpiecepath.h @@ -46,6 +46,7 @@ public: virtual void RefreshGeometry() override; void SetPath(const VPiecePath &path); + void SetCuttingPath(const QVector &cuttingPath); virtual int type() const override {return Type;} enum { Type = UserType + static_cast(Vis::ToolPiecePath)}; protected: @@ -59,6 +60,8 @@ private: VPiecePath m_path; + QVector m_cuttingPath; + VSimplePoint *GetPoint(quint32 i, const QColor &color); void HideAllItems();