56 #include "../vgeometry/vpointf.h"
57 #include "../vgeometry/vabstractcurve.h"
58 #include "../vgeometry/varc.h"
59 #include "../vmisc/vabstractapplication.h"
61 #include <QSharedPointer>
63 #include <QPainterPath>
69 if (d1Nodes.size() == d2Nodes.size())
75 for (qint32 i = 0; i < d1Nodes.size(); ++i)
77 set1.insert(d1Nodes.at(i));
81 for (qint32 j = 0; j < d2Nodes.size(); ++j)
83 set2.insert(d2Nodes.at(j));
88 for (qint32 i = 0; i < set3.size(); ++i)
99 int countPointNodes = 0;
102 for (
int i = 0; i< path.size(); ++i)
113 return countPointNodes >= 3 || (countPointNodes >= 1 && countOthers >= 1);
119 #ifdef Q_COMPILER_RVALUE_REFS
121 { Swap(piece);
return *
this; }
142 if ( &piece ==
this )
199 int recordIndex = -1;
200 bool insertingCSA =
false;
205 for (
int i = 0; i< unitedPath.size(); ++i)
217 if (not insertingCSA)
229 for (
int j = 0; j < r.size(); ++j)
241 if (records.at(recordIndex).endPoint == node.
GetId())
243 insertingCSA =
false;
256 if (not insertingCSA)
266 qDebug()<<
"Get wrong tool type. Ignore."<<
static_cast<char>(node.
GetTypeTool());
285 for (
int i = 0; i< unitedPath.size(); ++i)
296 notches +=
createNotch(unitedPath, previousIndex, i, nextIndex, data, seamAllowance);
308 if (not points.isEmpty())
310 path.moveTo(points[0]);
311 for (qint32 i = 1; i < points.count(); ++i)
313 path.lineTo(points.at(i));
315 path.lineTo(points.at(0));
316 path.setFillRule(Qt::WindingFill);
336 if (not points.isEmpty())
338 ekv.moveTo(points.at(0));
339 for (qint32 i = 1; i < points.count(); ++i)
341 ekv.lineTo(points.at(i));
344 ekv.setFillRule(Qt::WindingFill);
360 if (not notches.isEmpty())
362 for (qint32 i = 0; i < notches.count(); ++i)
364 path.moveTo(notches.at(i).p1());
365 path.lineTo(notches.at(i).p2());
368 path.setFillRule(Qt::WindingFill);
378 return d->m_inLayout;
384 d->m_inLayout = inLayout;
390 return d->m_isLocked;
408 d->m_united = united;
414 return d->m_formulaWidth;
422 width >= 0 ?
d->m_formulaWidth = formula :
d->m_formulaWidth = QLatin1String(
"0");
428 return d->m_internalPaths;
434 return d->m_internalPaths;
440 d->m_internalPaths = iPaths;
446 return d->m_customSARecords;
452 return d->m_customSARecords;
458 d->m_customSARecords = records;
476 d->m_anchors = anchors;
488 return d->m_path.MissingNodes(piece.
GetPath());
495 for (qint32 i = 0; i <
d->m_customSARecords.size(); ++i)
497 oldCSARecords.append(
d->m_customSARecords.at(i).path);
550 d->m_piPatternInfo = info;
560 return d->m_piPatternInfo;
570 return d->m_piPatternInfo;
580 return d->m_glGrainline;
590 return d->m_glGrainline;
607 for (
int i = 0; i < records.size(); ++i)
614 if (indexStartPoint == -1 || indexEndPoint == -1)
623 if (records.at(i).reverse)
628 for (
int j = 0; j < customNodes.size(); ++j)
631 if (records.at(i).reverse)
634 customNodes[j].SetReverse(not customNodes.at(j).GetReverse());
640 customNodes[j].setNotch(
false);
644 customNodes[j].SetMainPathNode(
false);
648 united = midBefore + customNodes + midAfter;
658 for (
int i = 0; i <
d->m_customSARecords.size(); ++i)
661 const int indexStartPoint =
d->m_path.indexOfNode(record.
startPoint);
662 const int indexEndPoint =
d->m_path.indexOfNode(record.
endPoint);
667 && indexStartPoint != -1
668 && not
d->m_path.at(indexStartPoint).isExcluded()
669 && indexEndPoint != -1
670 && not
d->m_path.at(indexEndPoint).isExcluded()
671 && indexStartPoint < indexEndPoint)
673 records.append(record);
682 if (records.size() < 2)
688 bool foundFilter =
false;
690 int startIndex =
d->m_path.CountNodes()-1;
692 for (
int i = 0; i < records.size(); ++i)
694 const int indexStartPoint =
d->m_path.indexOfNode(records.at(i).startPoint);
695 if (indexStartPoint < startIndex)
698 filter = records.at(i);
709 records.remove(startIndex);
712 for (
int i = 0; i < records.size(); ++i)
714 const int indexStartPoint =
d->m_path.indexOfNode(records.at(i).startPoint);
715 const int indexEndPoint =
d->m_path.indexOfNode(filter.
endPoint);
716 if (indexStartPoint > indexEndPoint)
718 secondRound.append(records.at(i));
723 filtered.append(filter);
735 if (index < 0 || index >= path.size())
765 if (points.isEmpty() || points.size() > 1)
770 point = points.first();
782 if (points.isEmpty())
788 int nodeIndex = points.size()-1;
791 const VSAPoint previous = points.at(nodeIndex);
792 if (notchSAPoint.toPoint() != previous.toPoint())
798 }
while (nodeIndex >= 0 && not found);
815 if (points.isEmpty())
824 const VSAPoint next = points.at(nodeIndex);
825 if (notchSAPoint.toPoint() != next.toPoint())
832 }
while (nodeIndex < points.size() && not found);
855 || (
IsEkvPointOnLine(
static_cast<QPointF
>(notchSAPoint),
static_cast<QPointF
>(previousSAPoint),
856 static_cast<QPointF
>(nextSAPoint))
860 QLineF line (notchSAPoint, nextSAPoint);
861 line.setAngle(line.angle() + 90);
863 ekvPoints.append(line.p2());
867 ekvPoints =
EkvPoint(previousSAPoint, notchSAPoint, nextSAPoint, notchSAPoint, width);
870 if (ekvPoints.isEmpty())
875 if (ekvPoints.size() == 1 || ekvPoints.size() > 2)
877 point = ekvPoints.first();
879 else if (ekvPoints.size() == 2)
881 QLineF line = QLineF(ekvPoints.at(0), ekvPoints.at(1));
882 line.setLength(line.length()/2.);
891 if (notchIndex < 0 || notchIndex >= path.size())
908 if (records.isEmpty())
913 for (
int i = 0; i < records.size(); ++i)
919 if (notchIndex > indexStartPoint && notchIndex < indexEndPoint)
962 if (path.at(notchIndex).showNotch())
965 data, notchIndex, pathPoints);
968 && path.at(notchIndex).IsMainPathNode()
970 && path.at(notchIndex).showSeamlineNotch())
973 notchIndex, mainPathPoints);
979 return createBuiltInSaNotch(path, previousSAPoint, notchSAPoint, nextSAPoint, data, notchIndex, mainPathPoints);
989 QPointF seamNotchSAPoint;
990 if (not
getSeamNotchSAPoint(previousSAPoint, notchSAPoint, nextSAPoint, data, seamNotchSAPoint))
1010 QLineF line = QLineF(seamNotchSAPoint, notchSAPoint);
1011 line.setLength(notchData.
length);
1012 notchData.
line = line;
1020 QLineF edge1 = QLineF(seamNotchSAPoint, bigLine1.p1());
1021 QLineF edge2 = QLineF(seamNotchSAPoint, bigLine2.p2());
1023 edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.);
1024 edge1.setLength(notchData.
length);
1026 notchData.
line = edge1;
1036 QLineF line(notchSAPoint, previousSAPoint);
1037 line.setAngle(line.angle() - 180.0);
1038 line.setLength(40000.0);
1041 intersections.removeOne(notchSAPoint);
1042 if (!intersections.isEmpty())
1044 line = QLineF(intersections.last(), notchSAPoint);
1045 line.setLength(notchData.
length);
1046 notchData.
line = line;
1054 QLineF line(notchSAPoint, nextSAPoint);
1055 line.setAngle(line.angle() - 180.0);
1056 line.setLength(40000.0);
1059 intersections.removeOne(notchSAPoint);
1060 if (!intersections.isEmpty())
1062 line = QLineF(intersections.last(), notchSAPoint);
1063 line.setLength(notchData.
length);
1064 notchData.
line = line;
1081 const VPieceNode &node = path.at(notchIndex);
1083 QLineF edge1 = QLineF(notchSAPoint, previousSAPoint);
1084 QLineF edge2 = QLineF(notchSAPoint, nextSAPoint);
1094 edge1.setAngle(edge1.angle() + edge1.angleTo(edge2)/2.);
1095 edge1.setLength(notchData.
length);
1096 notchData.
line = edge1;
1105 for (
int i = 0; i < records.size(); ++i)
1107 if (records.at(i).startPoint ==
id)
1119 QLineF refline = QLineF(notchData.
line);
1120 qreal angle = notchData.
angle;
1121 qreal offset = notchData.
offset;
1124 line.setAngle(line.angle() + angle);
1134 QLineF refline = QLineF(notchData.
line);
1135 qreal length = notchData.
length;
1136 qreal width = notchData.
width;
1137 qreal angle = notchData.
angle;
1138 qreal offset = notchData.
offset;
1141 tempLine.setAngle(tempLine.angle() + angle);
1142 tempLine =
findIntersection(pathPoints, QLineF(tempLine.p2(), tempLine.p1()));
1143 QLineF line = QLineF(tempLine.p2(), tempLine.p1());
1144 line.setLength(length);
1148 QLineF tempLine = QLineF(line.p2(), line.p1());
1149 tempLine.setAngle(tempLine.angle() - 90);
1150 tempLine.setLength(width * 0.75 / 2);
1156 QLineF tempLine = QLineF(line.p2(), line.p1());
1157 tempLine.setAngle(tempLine.angle() + 90);
1158 tempLine.setLength(width * 0.75 / 2);
1164 lines.append(QLineF(p1, p2));
1171 QLineF refline = QLineF(notchData.
line);
1172 qreal length = notchData.
length;
1173 qreal width = notchData.
width;
1174 qreal angle = notchData.
angle;
1175 qreal offset = notchData.
offset;
1180 line1.setLength(length / 2.);
1181 line1.setAngle(line1.angle() + angle);
1184 line2.setLength(length / 2.);
1185 line2.setAngle(line2.angle() + angle);
1187 centerLine.setLength(length / 2.);
1188 centerLine.setAngle(centerLine.angle() + angle);
1190 VArc arc(
VPointF(centerLine.p2()), width / 2., QLineF(centerLine.p2(), line2.p2()).angle(), QLineF(centerLine.p2(), line1.p2()).angle());
1194 lines.append(
findIntersection(pathPoints, QLineF(line1.p2(), line1.p1())));
1195 lines.append(
findIntersection(pathPoints, QLineF(line2.p2(), line2.p1())));
1202 QLineF refline = QLineF(notchData.
line);
1203 qreal length = notchData.
length;
1204 qreal width = notchData.
width;
1205 qreal angle = notchData.
angle;
1206 qreal offset = notchData.
offset;
1209 tempLine.setAngle(tempLine.angle() + angle);
1210 tempLine =
findIntersection(pathPoints, QLineF(tempLine.p2(), tempLine.p1()));
1211 QLineF line = QLineF(tempLine.p2(), tempLine.p1());
1212 line.setLength(length);
1216 QLineF tempLine = QLineF(line.p2(), line.p1());
1217 tempLine.setAngle(tempLine.angle() - 90);
1218 tempLine.setLength(width / 2);
1224 QLineF tempLine = QLineF(line.p2(), line.p1());
1225 tempLine.setAngle(tempLine.angle() + 90);
1226 tempLine.setLength(width / 2);
1231 lines.append(QLineF(line.p1(), p2));
1232 lines.append(QLineF(line.p1(), p1));
1239 QLineF refline = QLineF(notchData.
line);
1240 qreal width = notchData.
width;
1241 qreal angle = notchData.
angle;
1242 qreal offset = notchData.
offset;
1245 line.setAngle(line.angle() + angle);
1249 QLineF tempLine = QLineF(line.p1(), line.p2());
1250 tempLine.setAngle(tempLine.angle() - 90);
1251 tempLine.setLength(width / 2);
1257 QLineF tempLine = QLineF(line.p1(), line.p2());
1258 tempLine.setAngle(tempLine.angle() + 90);
1259 tempLine.setLength(width / 2);
1272 QLineF refline = notchData.
line;
1273 qreal width = notchData.
width;
1274 qreal angle = notchData.
angle;
1275 qreal offset = notchData.
offset;
1280 line1.setAngle(line1.angle() + angle);
1282 line2.setAngle(line2.angle() + angle);
1285 lines.append(QLineF(line1.p2(), line2.p2()));
1286 lines.append(
findIntersection(pathPoints, QLineF(line1.p2(), line1.p1())));
1287 lines.append(
findIntersection(pathPoints, QLineF(line2.p2(), line2.p1())));
1297 qreal angle = notchData.
angle;
1302 notchData.
angle = angle - 180;
1310 int count = notchData.
count;
1313 qreal width = notchData.
width;
1326 notchData.
offset = width * .625;
1328 notchData.
offset = -(width * .625);
1334 notchData.
offset = width * 1.25;
1336 notchData.
offset = -(width * 1.25);
1350 notchData.
offset = width * .625;
1352 notchData.
offset = -(width * .625);
1358 notchData.
offset = width * 1.375;
1360 notchData.
offset = -(width * 1.375);
1374 notchData.
offset = width * .625;
1376 notchData.
offset = -(width * .625);
1382 notchData.
offset = width * 1.25;
1384 notchData.
offset = -(width * 1.25);
1398 notchData.
offset = width * .625;
1400 notchData.
offset = -(width * .625);
1406 notchData.
offset = width * 1.25;
1408 notchData.
offset = -(width * 1.25);
1422 notchData.
offset = width * .625;
1424 notchData.
offset = -(width * .625);
1430 notchData.
offset = width * 1.375;
1432 notchData.
offset = -(width * 1.375);
1446 notchData.
offset = width * .625;
1448 notchData.
offset = -(width * .625);
1454 notchData.
offset = width * 1.375;
1456 notchData.
offset = -(width * 1.375);
1471 notchData.
offset = width * .625;
1473 notchData.
offset = -(width * .625);
1479 notchData.
offset = width * 1.25;
1481 notchData.
offset = -(width * 1.25);
1504 QLineF tempLine = line;
1505 tempLine.setLength(tempLine.length()*1.5);
1507 if (not intersections.isEmpty())
1509 return QLineF(line.p1(), intersections.last());
static QVector< QPointF > CurveIntersectLine(const QVector< QPointF > &points, const QLineF &line)
bool IsSeamAllowanceBuiltIn() const
bool IsSeamAllowance() const
bool isHideSeamLine() const
static bool IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint)
static QVector< QPointF > Equidistant(const QVector< VSAPoint > &points, qreal width)
static QLineF createParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width)
void SetSAWidth(qreal value)
static QVector< QPointF > EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1, const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width)
EkvPoint return seam allowance points in place of intersection of two edges. Last points of two edges...
static qreal MaxLocalSA(const VSAPoint &p, qreal width)
void Swap(VAbstractPiece &piece) Q_DECL_NOTHROW
static QVector< QPointF > CheckLoops(const QVector< QPointF > &points)
CheckLoops seek and delete loops in equidistant.
static QVector< T > CorrectEquidistantPoints(const QVector< T > &points, bool removeFirstAndLast=true)
CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant.
VAbstractPiece & operator=(const VAbstractPiece &piece)
VArc class for anticlockwise arc.
QVector< QLineF > getSegments() const
The VContainer class container of all variables.
const QSharedPointer< T > GeometricObject(const quint32 &id) const
VPiecePath GetPiecePath(quint32 id) const
const Unit * GetPatternUnit() const
static QVector< T > GetReversePoints(const QVector< T > &points)
GetReversePoint return revers container of points.
static const double accuracyPointOnLine
The VGrainlineData class holds information about a grainline like position, size, rotation and visibi...
The VPatternLabelData class holds the information about pattern info label geometry.
The VPieceLabelData class holds some information about a single piece like letter,...
NotchType getNotchType() const
qreal getNotchAngle() const
qreal getNotchLength() const
int getNotchCount() const
NotchSubType getNotchSubType() const
qreal getNotchWidth() const
QVector< QPointF > PathPoints(const VContainer *data) const
QVector< VSAPoint > SeamAllowancePoints(const VContainer *data, qreal width, bool reverse) const
static QVector< VSAPoint > CurveSeamAllowanceSegment(const VContainer *data, const QVector< VPieceNode > &nodes, const QSharedPointer< VAbstractCurve > &curve, int i, bool reverse, qreal width)
static int FindInLoopNotExcludedUp(int start, const QVector< VPieceNode > &nodes)
QVector< VPointF > PathNodePoints(const VContainer *data, bool showExcluded=true) const
QVector< VPieceNode > GetNodes() const
static VSAPoint PreparePointEkv(const VPieceNode &node, const VContainer *data)
static int FindInLoopNotExcludedDown(int start, const QVector< VPieceNode > &nodes)
int indexOfNode(quint32 id) const
QVector< CustomSARecord > FilterRecords(QVector< CustomSARecord > records) const
void setIsLocked(bool isLocked)
QPainterPath SeamAllowancePath(const VContainer *data) const
bool isNotchVisible(const QVector< VPieceNode > &path, int notchIndex) const
QVector< VPieceNode > GetUnitedPath(const VContainer *data) const
bool getSeamNotchSAPoint(const VSAPoint &previousSAPoint, const VSAPoint ¬chSAPoint, const VSAPoint &nextSAPoint, const VContainer *data, QPointF &point) const
VPieceLabelData & GetPatternPieceData()
Returns full access to the pattern piece data object.
QVector< CustomSARecord > GetCustomSARecords() const
bool getNotchSAPoint(const QVector< VPieceNode > &path, int index, const VContainer *data, VSAPoint &point) const
bool getNotchPreviousSAPoints(const QVector< VPieceNode > &path, int index, const VSAPoint ¬chSAPoint, const VContainer *data, VSAPoint &point) const
QString getSeamAllowanceWidthFormula() const
QSharedDataPointer< VPieceData > d
QVector< QLineF > createNotchLines(const VContainer *data, const QVector< QPointF > &seamAllowance=QVector< QPointF >()) const
QVector< VSAPoint > getNodeSAPoints(const QVector< VPieceNode > &path, int index, const VContainer *data) const
void Swap(VPiece &piece) Q_DECL_NOTHROW
QPainterPath getNotchesPath(const VContainer *data, const QVector< QPointF > &seamAllowance=QVector< QPointF >()) const
QVector< QLineF > createBuiltInSaNotch(const QVector< VPieceNode > &path, const VSAPoint &previousSAPoint, const VSAPoint ¬chSAPoint, const VSAPoint &nextSAPoint, const VContainer *data, int notchIndex, const QVector< QPointF > &pathPoints) const
QVector< quint32 > GetInternalPaths() const
QVector< QLineF > createTNotch(NotchData notchData, const QVector< QPointF > &pathPoints) const
QVector< QLineF > createNotch(const QVector< VPieceNode > &path, int previousIndex, int notchIndex, int nextIndex, const VContainer *data, const QVector< QPointF > &pathPoints=QVector< QPointF >()) const
QVector< QLineF > createSlitNotch(NotchData notchData, const QVector< QPointF > &seamAllowance) const
void SetPath(const VPiecePath &path)
void SetInLayout(bool inLayout)
QVector< quint32 > missingAnchors(const VPiece &piece) const
QVector< quint32 > getAnchors() const
VPiece & operator=(const VPiece &piece)
void setAnchors(const QVector< quint32 > &anchors)
QVector< QPointF > SeamAllowancePoints(const VContainer *data) const
QVector< QLineF > createVExternalNotch(NotchData notchData, const QVector< QPointF > &seamAllowance) const
static int IsCSAStart(const QVector< CustomSARecord > &records, quint32 id)
QPainterPath MainPathPath(const VContainer *data) const
QVector< QLineF > createDiamondNotch(NotchData notchData, const QVector< QPointF > &seamAllowance) const
QVector< quint32 > MissingInternalPaths(const VPiece &piece) const
void SetPatternPieceData(const VPieceLabelData &data)
QVector< VPointF > MainPathNodePoints(const VContainer *data, bool showExcluded=false) const
QVector< quint32 > MissingNodes(const VPiece &piece) const
MissingNodes find missing nodes in piece. When we deleted object in piece and return this piece need ...
void SetCustomSARecords(const QVector< CustomSARecord > &records)
QVector< QLineF > createVInternalNotch(NotchData notchData, const QVector< QPointF > &pathPoints) const
void setSeamAllowanceWidthFormula(const QString &formula, qreal value)
void SetInternalPaths(const QVector< quint32 > &iPaths)
QVector< QLineF > createUNotch(const NotchData notchData, const QVector< QPointF > &seamAllowance) const
QVector< QLineF > createSeamAllowanceNotch(const QVector< VPieceNode > &path, VSAPoint &previousSAPoint, const VSAPoint ¬chSAPoint, VSAPoint &nextSAPoint, const VContainer *data, int notchIndex, const QVector< QPointF > &pathPoints=QVector< QPointF >()) const
void SetUnited(bool united)
QLineF findIntersection(const QVector< QPointF > &seamAllowance, const QLineF &line) const
QVector< QPointF > MainPathPoints(const VContainer *data) const
QVector< CustomSARecord > GetValidRecords() const
QVector< QLineF > createCastleNotch(const NotchData notchData, const QVector< QPointF > &seamAllowance) const
void SetPatternInfo(const VPatternLabelData &info)
VGrainlineData & GetGrainlineGeometry()
VDetail::GetGrainlineGeometry full access to the grainline geometry object.
QVector< QLineF > createNotches(NotchData notchData, const QVector< QPointF > &seamAllowance) const
VPatternLabelData & GetPatternInfo()
Returns full access to the pattern info geometry object.
int getNextNotchSAPoints(const QVector< VPieceNode > &path, int index, const VSAPoint ¬chSAPoint, const VContainer *data, VSAPoint &point) const
QVector< quint32 > MissingCSAPath(const VPiece &piece) const
VPiecePath GetPath() const
The VPointF class keep data of point.
The VSAPoint class seam allowance point.
Q_DECL_CONSTEXPR qreal GetSABefore() const
Q_DECL_CONSTEXPR qreal GetSAAfter() const
double ToPixel(double val, const Unit &unit)
QVector< quint32 > PieceMissingNodes(const QVector< quint32 > &d1Nodes, const QVector< quint32 > &d2Nodes)
bool notchesPossible(const QVector< VPieceNode > &path)
The CustomSA struct contains record about custom seam allowanse (SA).