Resolved issue #868. New feature. Connect internal path with cutting contour.
--HG-- branch : develop
This commit is contained in:
parent
44709728df
commit
8a29755a36
|
@ -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.
|
||||
|
|
|
@ -3746,10 +3746,12 @@ void VPattern::ParsePathElement(VMainGraphicsScene *scene, QDomElement &domEleme
|
|||
initData.path.SetType(static_cast<PiecePathType>(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')));
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
<file>schema/pattern/v0.7.7.xsd</file>
|
||||
<file>schema/pattern/v0.7.8.xsd</file>
|
||||
<file>schema/pattern/v0.7.9.xsd</file>
|
||||
<file>schema/pattern/v0.7.10.xsd</file>
|
||||
<file>schema/standard_measurements/v0.3.0.xsd</file>
|
||||
<file>schema/standard_measurements/v0.4.0.xsd</file>
|
||||
<file>schema/standard_measurements/v0.4.1.xsd</file>
|
||||
|
|
1064
src/libs/ifc/schema/pattern/v0.7.10.xsd
Normal file
1064
src/libs/ifc/schema/pattern/v0.7.10.xsd
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -327,6 +327,63 @@ QVector<QPointF> VAbstractCurve::CurveIntersectLine(const QVector<QPointF> &poin
|
|||
return intersections;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VAbstractCurve::CurveIntersectAxis(const QPointF &point, qreal angle, const QVector<QPointF> &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<QPointF> points = VAbstractCurve::CurveIntersectLine(curvePoints, axis);
|
||||
|
||||
if (points.size() > 0)
|
||||
{
|
||||
if (points.size() == 1)
|
||||
{
|
||||
*intersectionPoint = points.at(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
QMap<qreal, int> forward;
|
||||
QMap<qreal, int> 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<DirectionArrow> VAbstractCurve::DirectionArrows() const
|
||||
{
|
||||
|
|
|
@ -95,6 +95,8 @@ public:
|
|||
static qreal PathLength(const QVector<QPointF> &path);
|
||||
|
||||
static QVector<QPointF> CurveIntersectLine(const QVector<QPointF> &points, const QLineF &line);
|
||||
static bool CurveIntersectAxis(const QPointF &point, qreal angle, const QVector<QPointF> &curvePoints,
|
||||
QPointF *intersectionPoint);
|
||||
|
||||
virtual QString NameForHistory(const QString &toolName) const=0;
|
||||
virtual QVector<DirectionArrow> DirectionArrows() const;
|
||||
|
|
|
@ -66,12 +66,13 @@ QVector<VLayoutPiecePath> ConvertInternalPaths(const VPiece &piece, const VConta
|
|||
|
||||
QVector<VLayoutPiecePath> paths;
|
||||
const QVector<quint32> pathsId = piece.GetInternalPaths();
|
||||
const QVector<QPointF> 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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -136,6 +136,7 @@ public:
|
|||
static const QSharedPointer<VGObject> GetFakeGObject(quint32 id);
|
||||
VPiece GetPiece(quint32 id) const;
|
||||
VPiecePath GetPiecePath(quint32 id) const;
|
||||
quint32 GetPieceForPiecePath(quint32 id) const;
|
||||
template <typename T>
|
||||
QSharedPointer<T> GetVariable(QString name) const;
|
||||
static quint32 getId();
|
||||
|
|
|
@ -415,6 +415,19 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
|||
return Equidistant(pointsEkv, width);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QVector<QPointF> VPiece::CuttingPathPoints(const VContainer *data) const
|
||||
{
|
||||
if (IsSeamAllowance() and not IsSeamAllowanceBuiltIn())
|
||||
{
|
||||
return SeamAllowancePoints(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MainPathPoints(data);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QVector<QLineF> VPiece::PassmarksLines(const VContainer *data, const QVector<QPointF> &seamAllowance) const
|
||||
{
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
QVector<QPointF> MainPathPoints(const VContainer *data) const;
|
||||
QVector<VPointF> MainPathNodePoints(const VContainer *data, bool showExcluded = false) const;
|
||||
QVector<QPointF> SeamAllowancePoints(const VContainer *data) const;
|
||||
QVector<QPointF> CuttingPathPoints(const VContainer *data) const;
|
||||
QVector<QLineF> PassmarksLines(const VContainer *data,
|
||||
const QVector<QPointF> &seamAllowance = QVector<QPointF>()) const;
|
||||
QVector<PlaceLabelImg> PlaceLabelPoints(const VContainer *data) const;
|
||||
|
|
|
@ -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 <QPainterPath>
|
||||
|
||||
|
@ -142,6 +144,51 @@ QPainterPath MakePainterPath(const QVector<QPointF> &points)
|
|||
|
||||
return path;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
qreal FindTipDirection(const QVector<QPointF> &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<QPointF> &cuttingPath, const QVector<QPointF> &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<QPointF> 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<QPointF> VPiecePath::PathPoints(const VContainer *data, const QVector<QPointF> &cuttingPath) const
|
||||
{
|
||||
QVector<QPointF> points;
|
||||
for (int i = 0; i < CountNodes(); ++i)
|
||||
|
@ -314,6 +385,46 @@ QVector<QPointF> VPiecePath::PathPoints(const VContainer *data) const
|
|||
}
|
||||
}
|
||||
|
||||
if (GetType() == PiecePathType::InternalPath && not cuttingPath.isEmpty() && points.size() > 1)
|
||||
{
|
||||
QVector<QPointF> 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<VSAPoint> VPiecePath::SeamAllowancePoints(const VContainer *data, qreal
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VPiecePath::PainterPath(const VContainer *data) const
|
||||
QPainterPath VPiecePath::PainterPath(const VContainer *data, const QVector<QPointF> &cuttingPath) const
|
||||
{
|
||||
return MakePainterPath(PathPoints(data));
|
||||
return MakePainterPath(PathPoints(data, cuttingPath));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -85,12 +85,19 @@ public:
|
|||
QString GetVisibilityTrigger() const;
|
||||
void SetVisibilityTrigger(const QString &formula);
|
||||
|
||||
QVector<QPointF> PathPoints(const VContainer *data) const;
|
||||
void SetFirstToCuttingCountour(bool value);
|
||||
bool IsFirstToCuttingCountour() const;
|
||||
|
||||
void SetLastToCuttingCountour(bool value);
|
||||
bool IsLastToCuttingCountour() const;
|
||||
|
||||
QVector<QPointF> PathPoints(const VContainer *data,
|
||||
const QVector<QPointF> &cuttingPath = QVector<QPointF>()) const;
|
||||
QVector<VPointF> PathNodePoints(const VContainer *data, bool showExcluded = true) const;
|
||||
QVector<QVector<QPointF> > PathCurvePoints(const VContainer *data) const;
|
||||
QVector<VSAPoint> SeamAllowancePoints(const VContainer *data, qreal width, bool reverse) const;
|
||||
|
||||
QPainterPath PainterPath(const VContainer *data) const;
|
||||
QPainterPath PainterPath(const VContainer *data, const QVector<QPointF> &cuttingPath) const;
|
||||
QVector<QPainterPath> CurvesPainterPath(const VContainer *data) const;
|
||||
|
||||
QList<quint32> Dependencies() const;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -37,6 +37,21 @@
|
|||
#include <QMenu>
|
||||
#include <QTimer>
|
||||
|
||||
namespace
|
||||
{
|
||||
QVector<QPointF> CuttingPath(quint32 id, const VContainer *data)
|
||||
{
|
||||
QVector<QPointF> 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<VisToolPiecePath *>(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<int>::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<VisToolPiecePath *>(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<VisToolPiecePath *>(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<VPieceNode>(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;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,20 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxFirstPointToCuttingContour">
|
||||
<property name="text">
|
||||
<string>Continue the first point to the cutting contour</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxLastPointToCuttingContour">
|
||||
<property name="text">
|
||||
<string>Continue the last point to the cutting contour</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="dragDropMode">
|
||||
|
@ -1403,7 +1417,7 @@
|
|||
</connection>
|
||||
</connections>
|
||||
<buttongroups>
|
||||
<buttongroup name="buttonGroupAngleType"/>
|
||||
<buttongroup name="buttonGroupMarkType"/>
|
||||
<buttongroup name="buttonGroupAngleType"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
|
|
@ -190,57 +190,7 @@ VToolCurveIntersectAxis *VToolCurveIntersectAxis::Create(VToolCurveIntersectAxis
|
|||
bool VToolCurveIntersectAxis::FindPoint(const QPointF &point, qreal angle, const QVector<QPointF> &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<QPointF> points = VAbstractCurve::CurveIntersectLine(curvePoints, axis);
|
||||
|
||||
if (points.size() > 0)
|
||||
{
|
||||
if (points.size() == 1)
|
||||
{
|
||||
*intersectionPoint = points.at(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
QMap<qreal, int> forward;
|
||||
QMap<qreal, int> 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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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<DialogTool> &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<QPointF> 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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<VScaledLine>(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<VPointF> nodes = m_path.PathNodePoints(Visualization::data);
|
||||
|
||||
|
@ -79,6 +81,12 @@ void VisToolPiecePath::SetPath(const VPiecePath &path)
|
|||
m_path = path;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VisToolPiecePath::SetCuttingPath(const QVector<QPointF> &cuttingPath)
|
||||
{
|
||||
m_cuttingPath = cuttingPath;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VisToolPiecePath::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
|
||||
virtual void RefreshGeometry() override;
|
||||
void SetPath(const VPiecePath &path);
|
||||
void SetCuttingPath(const QVector<QPointF> &cuttingPath);
|
||||
virtual int type() const override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(Vis::ToolPiecePath)};
|
||||
protected:
|
||||
|
@ -59,6 +60,8 @@ private:
|
|||
|
||||
VPiecePath m_path;
|
||||
|
||||
QVector<QPointF> m_cuttingPath;
|
||||
|
||||
VSimplePoint *GetPoint(quint32 i, const QColor &color);
|
||||
|
||||
void HideAllItems();
|
||||
|
|
Loading…
Reference in New Issue
Block a user