58 #include <QFontMetrics>
59 #include <QGraphicsPathItem>
62 #include <QMessageLogger>
63 #include <QPainterPath>
71 #include "../vpatterndb/floatItemData/vpatternlabeldata.h"
72 #include "../vpatterndb/floatItemData/vpiecelabeldata.h"
73 #include "../ifc/ifcdef.h"
74 #include "../vmisc/vmath.h"
75 #include "../vmisc/vabstractapplication.h"
76 #include "../vmisc/vcommonsettings.h"
77 #include "../vpatterndb/calculator.h"
78 #include "../vgeometry/vpointf.h"
93 for (
int i = 0; i < pathIds.size(); ++i)
113 qreal &labelWidth, qreal &labelHeight, QPointF &pos)
131 if (topLeftAnchorPoint !=
NULL_ID && bottomRightAnchorPoint !=
NULL_ID)
138 const QRectF labelRect = QRectF(
static_cast<QPointF
>(*topLeftAnchorPointPoint),
139 static_cast<QPointF
>(*bottomRightAnchorPointPoint));
140 labelWidth = qAbs(labelRect.width());
141 labelHeight = qAbs(labelRect.height());
143 pos = labelRect.topLeft();
177 pos =
static_cast<QPointF
>(*centerAnchorPoint) - QRectF(0, 0, lWidth, lHeight).center();
208 QLineF grainline(
static_cast<QPointF
>(*bottomAnchor_Point),
static_cast<QPointF
>(*topAnchor_Point));
209 length = grainline.length();
210 rotationAngle = grainline.angle();
214 grainline.setAngle(0);
217 pos = grainline.p1();
218 rotationAngle = qDegreesToRadians(rotationAngle);
232 rotationAngle = qDegreesToRadians(rotationAngle);
251 QLineF grainline(centerAnchorPoint->x(), centerAnchorPoint->y(),
252 centerAnchorPoint->x() + length / 2.0, centerAnchorPoint->y());
254 grainline.setAngle(qRadiansToDegrees(rotationAngle));
255 grainline = QLineF(grainline.p2(), grainline.p1());
256 grainline.setLength(length);
258 pos = grainline.p2();
280 for (
int i = 0; i < shape.size(); ++i)
284 if (not parentBoundingRect.contains(shape.at(i)))
286 if (shape.at(i).x() < parentBoundingRect.left())
288 dPtX = parentBoundingRect.left() - shape.at(i).x();
290 else if (shape.at(i).x() > parentBoundingRect.right())
292 dPtX = parentBoundingRect.right() - shape.at(i).x();
295 if (shape.at(i).y() < parentBoundingRect.top())
297 dPtY = parentBoundingRect.top() - shape.at(i).y();
299 else if (shape.at(i).y() > parentBoundingRect.bottom())
301 dPtY = parentBoundingRect.bottom() - shape.at(i).y();
304 if (fabs(dPtX) > fabs(dX))
309 if (fabs(dPtY) > fabs(dY))
327 for (
int i =0; i < points.size(); ++i)
329 points[i] = QPointF(points.at(i).x() + dX, points.at(i).y() + dY);
339 for(
int i = 0; i < points.size(); ++i)
341 allowancePoints.append(
VSAPoint(points.at(i)));
343 return allowancePoints;
354 QPointF
RotatePoint(
const QPointF &ptCenter,
const QPointF& pt, qreal rotationAngle)
357 QPointF ptRel = pt - ptCenter;
358 ptDest.setX(cos(rotationAngle)*ptRel.x() - sin(rotationAngle)*ptRel.y());
359 ptDest.setY(sin(rotationAngle)*ptRel.x() + cos(rotationAngle)*ptRel.y());
361 return ptDest + ptCenter;
368 if (labelShape.count() > 2)
381 #ifdef Q_COMPILER_RVALUE_REFS
403 if ( &piece ==
this )
446 if (patternLabelData.
IsVisible() ==
true)
449 layoutPiece.
SetPatternInfo(pDoc, patternLabelData,
qApp->Settings()->getLabelFont(), pattern);
468 return Map(
d->contour);
482 return Map(
d->seamAllowance);
492 d->seamAllowance = points;
493 if (not
d->seamAllowance.isEmpty())
499 qWarning()<<
"Seam allowance is empty.";
508 return Map(
d->layoutAllowance);
514 if (
d->pieceLabel.count() > 2)
516 return d->transform.map(
d->pieceLabel.first());
535 qreal labelWidth = 0;
536 qreal labelHeight = 0;
537 qreal labelAngle = 0;
538 if (not
FindLabelGeometry(data, pattern, labelAngle, labelWidth, labelHeight, ptPos))
548 << QPointF(ptPos.x() + labelWidth, ptPos.y())
549 << QPointF(ptPos.x() + labelWidth, ptPos.y() + labelHeight)
550 << QPointF(ptPos.x(), ptPos.y() + labelHeight);
552 const qreal rotationAngle = qDegreesToRadians(-labelAngle);
553 const QPointF ptCenter(ptPos.x() + labelWidth/2, ptPos.y() + labelHeight/2);
555 for (
int i = 0; i < v.count(); ++i)
557 v[i] =
RotatePoint(ptCenter, v.at(i), rotationAngle);
564 d->m_tmPiece.setFont(font);
566 d->m_tmPiece.Update(qsName, data);
569 d->m_tmPiece.FitFontSize(labelWidth, labelHeight);
575 if (
d->patternInfo.count() > 2)
577 return d->transform.map(
d->patternInfo.first());
596 qreal labelWidth = 0;
597 qreal labelHeight = 0;
598 qreal labelAngle = 0;
599 if (not
FindLabelGeometry(data, pattern, labelAngle, labelWidth, labelHeight, ptPos))
609 << QPointF(ptPos.x() + labelWidth, ptPos.y())
610 << QPointF(ptPos.x() + labelWidth, ptPos.y() + labelHeight)
611 << QPointF(ptPos.x(), ptPos.y() + labelHeight);
613 const qreal rotationAngle = qDegreesToRadians(-labelAngle);
614 const QPointF ptCenter(ptPos.x() + labelWidth/2, ptPos.y() + labelHeight/2);
615 for (
int i = 0; i < v.count(); ++i)
617 v[i] =
RotatePoint(ptCenter, v.at(i), rotationAngle);
623 d->m_tmPattern.setFont(font);
626 d->m_tmPattern.Update(pDoc);
630 d->m_tmPattern.FitFontSize(labelWidth, labelHeight);
639 qreal rotationAngle = 0;
646 const qreal arrowLength = 45;
647 const qreal arrowAngle = M_PI/9;
649 QPointF pt2(pt1.x() + arrowLength * qCos(rotationAngle),
650 pt1.y() - arrowLength * qSin(rotationAngle));
651 QPointF pt3(pt1.x() + length * qCos(rotationAngle),
652 pt1.y() - length * qSin(rotationAngle));
653 QPointF pt4(pt1.x() + (length - arrowLength) * qCos(rotationAngle),
654 pt1.y() - (length - arrowLength) * qSin(rotationAngle));
660 v << QPointF(pt1.x() + arrowLength * qCos(rotationAngle + arrowAngle),
661 pt1.y() - arrowLength * qSin(rotationAngle + arrowAngle));
663 v << QPointF(pt1.x() + arrowLength * qCos(rotationAngle - arrowAngle),
664 pt1.y() - arrowLength * qSin(rotationAngle - arrowAngle));
671 rotationAngle += M_PI;
672 v << QPointF(pt3.x() + arrowLength * qCos(rotationAngle + arrowAngle),
673 pt3.y() - arrowLength * qSin(rotationAngle + arrowAngle));
675 v << QPointF(pt3.x() + arrowLength * qCos(rotationAngle - arrowAngle),
676 pt3.y() - arrowLength * qSin(rotationAngle - arrowAngle));
687 return Map(
d->grainlinePoints);
699 d->transform = transform;
705 return d->layoutWidth;
711 d->layoutWidth = value;
726 m.translate(originPoint.x(), originPoint.y());
728 m.translate(-originPoint.x(), -originPoint.y());
740 const QLineF axis = QLineF(edge.x2(), edge.y2(), edge.x2() + 100, edge.y2());
742 const qreal angle = edge.angleTo(axis);
743 const QPointF p2 = edge.p2();
745 m.translate(p2.x(), p2.y());
747 m.translate(-p2.x(), -p2.y());
751 m.translate(p2.x(), p2.y());
752 m.scale(m.m11(), m.m22()*-1);
753 m.translate(-p2.x(), -p2.y());
757 m.translate(p2.x(), p2.y());
758 m.rotate(-(360-angle));
759 m.translate(-p2.x(), -p2.y());
762 d->mirror = !
d->mirror;
774 return d->layoutAllowance.count();
786 return Edge(
d->layoutAllowance, i);
814 points.append(points.first());
815 return QPolygonF(points).boundingRect();
822 points.append(points.first());
823 return QPolygonF(points).boundingRect();
830 return qSqrt(pow(rec.height(), 2) + pow(rec.width(), 2));
836 if (
d->contour.isEmpty() ==
false &&
d->layoutWidth > 0)
856 if (
d->layoutAllowance.isEmpty())
863 const qint64 sq = qFloor(qAbs(res/2.0));
870 if (
d->layoutWidth > 0)
875 if (
d->layoutAllowance.isEmpty() ==
false)
877 d->layoutAllowance.removeLast();
883 if (
d->layoutAllowance.isEmpty() ==
false)
885 d->layoutAllowance.removeLast();
891 d->layoutAllowance.clear();
898 return Map(
d->notches);
906 d->notches = notches;
915 for (
int i=0;i <
d->m_internalPaths.count(); ++i)
917 if (
d->m_internalPaths.at(i).IsCutPath() == cut)
919 paths.append(
Map(
d->m_internalPaths.at(i).Points()));
929 return d->m_internalPaths;
935 d->m_internalPaths = internalPaths;
941 return d->m_cutoutPaths;
947 d->m_cutoutPaths = cutoutPaths;
955 for (
int i = 0; i < points.size(); ++i)
957 p.append(
d->transform.map(points.at(i)));
963 for (
int k=0, s=list.size(), max=(s/2); k<max; k++)
965 list.swapItemsAt(k, s-(1+k));
982 path.moveTo(points.at(0));
983 for (qint32 i = 1; i < points.count(); ++i)
985 path.lineTo(points.at(i));
987 path.lineTo(points.at(0));
1005 if (points.last().toPoint() != points.first().toPoint())
1007 points.append(points.at(0));
1011 ekv.moveTo(points.at(0));
1012 for (qint32 i = 1; i < points.count(); ++i)
1014 ekv.lineTo(points.at(i));
1030 QPainterPath notchesPath;
1032 for (qint32 i = 0; i < notches.count(); ++i)
1034 notchesPath.moveTo(notches.at(i).p1());
1035 notchesPath.lineTo(notches.at(i).p2());
1038 path.addPath(notchesPath);
1039 path.setFillRule(Qt::WindingFill);
1048 QColor color = QColor(
qApp->Settings()->getDefaultInternalColor());
1049 QString lineType =
qApp->Settings()->getDefaultInternalLinetype();
1052 QGraphicsPathItem* item =
new QGraphicsPathItem(parent);
1053 item->setPath(
d->transform.map(
d->m_internalPaths.at(i).GetPainterPath()));
1054 item->setPen(QPen(color, lineWeight,
d->m_internalPaths.at(i).PenStyle(), Qt::RoundCap, Qt::RoundJoin));
1061 QColor color = QColor(
qApp->Settings()->getDefaultCutoutColor());
1062 QString lineType =
qApp->Settings()->getDefaultCutoutLinetype();
1065 QGraphicsPathItem* item =
new QGraphicsPathItem(parent);
1066 item->setPath(
d->transform.map(
d->m_cutoutPaths.at(i).GetPainterPath()));
1067 item->setPen(QPen(color, lineWeight,
d->m_cutoutPaths.at(i).PenStyle(), Qt::RoundCap, Qt::RoundJoin));
1074 path.setFillRule(Qt::WindingFill);
1077 path.moveTo(points.at(0));
1078 for (qint32 i = 1; i < points.count(); ++i)
1080 path.lineTo(points.at(i));
1082 path.lineTo(points.at(0));
1094 for (
int i = 0; i <
d->m_internalPaths.count(); ++i)
1099 for (
int i = 0; i <
d->m_cutoutPaths.count(); ++i)
1116 QColor color = QColor(
qApp->Settings()->getDefaultLabelColor());
1118 if (labelShape.count() > 2)
1120 const qreal dW = QLineF(labelShape.at(0), labelShape.at(1)).length();
1121 const qreal dH = QLineF(labelShape.at(1), labelShape.at(2)).length();
1122 const qreal angle = - QLineF(labelShape.at(0), labelShape.at(1)).angle();
1131 fnt.setBold(tl.
bold);
1132 fnt.setItalic(tl.
italic);
1134 QFontMetrics fm(fnt);
1146 QString qsText = tl.
m_text;
1147 if (fm.horizontalAdvance(qsText) > dW)
1149 qsText = fm.elidedText(qsText, Qt::ElideMiddle,
static_cast<int>(dW));
1151 if ((tl.
m_eAlign & Qt::AlignLeft) > 0)
1155 else if ((tl.
m_eAlign & Qt::AlignHCenter) > 0)
1157 dX = (dW - fm.horizontalAdvance(qsText))/2;
1161 dX = dW - fm.horizontalAdvance(qsText);
1165 QTransform labelTransform;
1166 labelTransform.translate(labelShape.at(0).x(), labelShape.at(0).y());
1169 labelTransform.scale(-1, 1);
1170 labelTransform.rotate(-angle);
1171 labelTransform.translate(-dW, 0);
1172 labelTransform.translate(dX, dY);
1176 labelTransform.rotate(angle);
1177 labelTransform.translate(dX, dY);
1180 labelTransform *=
d->transform;
1185 path.addText(0, -
static_cast<qreal
>(fm.ascent())/6., fnt, qsText);
1187 QGraphicsPathItem* item =
new QGraphicsPathItem(parent);
1188 item->setPath(path);
1190 item->setBrush(QBrush(Qt::NoBrush));
1191 item->setTransform(labelTransform);
1197 QGraphicsSimpleTextItem* item =
new QGraphicsSimpleTextItem(parent);
1199 item->setText(qsText);
1200 item->setTransform(labelTransform);
1201 item->setPen(QPen(color));
1202 item->setBrush(QBrush(color));
1214 QColor color = QColor(
qApp->Settings()->getDefaultGrainlineColor());
1216 if (
d->grainlinePoints.count() < 2)
1224 path.moveTo(gPoints.at(0));
1225 for (
int i = 1; i < gPoints.count(); ++i)
1227 path.lineTo(gPoints.at(i));
1229 item->setPath(path);
1237 return d->seamAllowance;
1253 color = QColor(
qApp->Settings()->getDefaultSeamColor());
1254 lineType =
qApp->Settings()->getDefaultSeamLinetype();
1259 color = QColor(
qApp->Settings()->getDefaultCutColor());
1260 lineType =
qApp->Settings()->getDefaultCutLinetype();
1263 QGraphicsPathItem *item =
new QGraphicsPathItem();
1265 item->setPen(QPen(color, lineWeight,
lineTypeToPenStyle(lineType), Qt::RoundCap, Qt::RoundJoin));
1272 QColor color = QColor(
qApp->Settings()->getDefaultCutColor());
1273 QString lineType =
qApp->Settings()->getDefaultCutLinetype();
1276 QGraphicsPathItem *item =
new QGraphicsPathItem(parent);
1278 item->setPen(QPen(color, lineWeight,
lineTypeToPenStyle(lineType), Qt::RoundCap, Qt::RoundJoin));
1284 QColor color = QColor(
qApp->Settings()->getDefaultNotchColor());
1286 QGraphicsPathItem *item =
new QGraphicsPathItem(parent);
1288 item->setPen(QPen(color, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
1294 QGraphicsPathItem *item =
new QGraphicsPathItem();
1301 path.moveTo(points.at(0));
1302 for (qint32 i = 1; i < points.count(); ++i)
1304 path.lineTo(points.at(i));
1306 path.lineTo(points.at(0));
1308 item->setPath(path);
1327 if (i < 1 || i > path.count())
1333 if (i < path.count())
1340 i1 = path.count()-1;
1346 const int oldI1 = i1;
1347 const int size = path.size()-1;
1350 return QLineF(
d->transform.map(path.at(i2)),
d->transform.map(path.at(i1)));
1354 return QLineF(
d->transform.map(path.at(i1)),
d->transform.map(path.at(i2)));
1366 if (path.count() < 3)
1372 for (
int i=0; i < points.size(); i++)
1374 if (points.at(i) == p1)
The Calculator class for calculation formula.
qreal EvalFormula(const QHash< QString, QSharedPointer< VInternalVariable > > *vars, const QString &formula)
eval calculate formula.
bool IsSeamAllowanceBuiltIn() const
bool IsSeamAllowance() const
bool isHideSeamLine() const
static QVector< QPointF > Equidistant(const QVector< VSAPoint > &points, qreal width)
static qreal sumTrapezoids(const QVector< QPointF > &points)
void SetSAWidth(qreal value)
void SetForbidFlipping(bool value)
void setHideSeamLine(bool value)
void SetName(const QString &value)
static QVector< T > RemoveDublicates(const QVector< T > &points, bool removeFirstAndLast=true)
void SetSeamAllowanceBuiltIn(bool value)
void Swap(VAbstractPiece &piece) Q_DECL_NOTHROW
void SetSeamAllowance(bool value)
bool IsForbidFlipping() const
VAbstractPiece & operator=(const VAbstractPiece &piece)
The VContainer class container of all variables.
const QHash< QString, QSharedPointer< VInternalVariable > > * DataVariables() const
const QSharedPointer< T > GeometricObject(const quint32 &id) const
VPiecePath GetPiecePath(quint32 id) const
const Unit * GetPatternUnit() const
The VExceptionBadId class for exception bad id.
The VException class parent for all exception. Could be use for abstract exception.
The VGrainlineData class holds information about a grainline like position, size, rotation and visibi...
ArrowType GetArrowType() const
quint32 centerAnchorPoint() const
QString GetRotation() const
quint32 bottomAnchorPoint() const
quint32 topAnchorPoint() const
QString GetLength() const
int pieceEdgesCount() const
int EdgeByPoint(const QVector< QPointF > &path, const QPointF &p1) const
void SetPieceText(const QString &qsName, const VPieceLabelData &data, const QFont &font, const VContainer *pattern)
void createGrainlineItem(QGraphicsItem *parent, bool textAsPaths) const
QStringList GetPieceText() const
void SetCountourPoints(const QVector< QPointF > &points, bool hideMainPath=false)
void SetLayoutWidth(const qreal &value)
void Mirror(const QLineF &edge)
QTransform getTransform() const
QPainterPath createMainPath() const
VLayoutPiece & operator=(const VLayoutPiece &detail)
QVector< QPointF > getContourPoints() const
QRectF LayoutBoundingRect() const
void Translate(qreal dx, qreal dy)
QSharedDataPointer< VLayoutPieceData > d
void setInternalPaths(const QVector< VLayoutPiecePath > &internalPaths)
void setGrainline(const VGrainlineData &geom, const VContainer *pattern)
void createLabelItem(QGraphicsItem *parent, const QVector< QPointF > &labelShape, const VTextManager &tm, bool textAsPaths) const
void createInternalPathItem(int i, QGraphicsItem *parent) const
void setNotches(const QVector< QLineF > ¬ches)
Q_REQUIRED_RESULT QGraphicsPathItem * createMainItem() const
int pieceEdgeByPoint(const QPointF &p1) const
QRectF pieceBoundingRect() const
int LayoutEdgesCount() const
virtual ~VLayoutPiece() Q_DECL_OVERRIDE
QVector< QLineF > getNotches() const
QVector< VLayoutPiecePath > getCutoutPaths() const
void SetLayoutAllowancePoints()
QVector< QVector< QPointF > > InternalPathsForCut(bool cut) const
Q_REQUIRED_RESULT QGraphicsPathItem * getMainPathItem() const
QPainterPath createNotchesPath() const
QVector< QPointF > piecePath() const
QLineF pieceEdge(int i) const
QVector< QPointF > getLayoutAllowancePoints() const
void setTransform(const QTransform &transform)
QVector< QPointF > GetSeamAllowancePoints() const
void Swap(VLayoutPiece &detail) Q_DECL_NOTHROW
void createCutoutPathItem(int i, QGraphicsItem *parent) const
QPointF GetPieceTextPosition() const
void setSeamAllowancePoints(const QVector< QPointF > &points, bool seamAllowance=true, bool seamAllowanceBuiltIn=false)
QLineF LayoutEdge(int i) const
void SetMirror(bool value)
int LayoutEdgeByPoint(const QPointF &p1) const
Q_REQUIRED_RESULT QGraphicsItem * GetItem(bool textAsPaths) const
static VLayoutPiece Create(const VPiece &piece, const VContainer *pattern)
void setCutoutPaths(const QVector< VLayoutPiecePath > &cutoutPaths)
QPainterPath createAllowancePath() const
void createNotchesItem(QGraphicsItem *parent) const
QLineF Edge(const QVector< QPointF > &path, int i) const
QVector< T > Map(const QVector< T > &points) const
void SetPatternInfo(VAbstractPattern *pDoc, const VPatternLabelData &geom, const QFont &font, const VContainer *pattern)
QStringList GetPatternText() const
QPainterPath LayoutAllowancePath() const
QVector< VLayoutPiecePath > getInternalPaths() const
qreal GetLayoutWidth() const
void Rotate(const QPointF &originPoint, qreal degrees)
void createAllowanceItem(QGraphicsItem *parent) const
QPointF GetPatternTextPosition() const
QVector< QPointF > getGrainline() const
The VPatternLabelData class holds the information about pattern info label geometry.
quint32 centerAnchorPoint() const
quint32 topLeftAnchorPoint() const
QString GetLabelWidth() const
QString GetRotation() const
quint32 bottomRightAnchorPoint() const
QString GetLabelHeight() const
The VPieceLabelData class holds some information about a single piece like letter,...
QVector< QPointF > PathPoints(const VContainer *data) const
PiecePathType GetType() const
Qt::PenStyle GetPenType() const
VPieceLabelData & GetPatternPieceData()
Returns full access to the pattern piece data object.
QVector< QLineF > createNotchLines(const VContainer *data, const QVector< QPointF > &seamAllowance=QVector< QPointF >()) const
QVector< quint32 > GetInternalPaths() const
QVector< QPointF > SeamAllowancePoints(const VContainer *data) const
QVector< QPointF > MainPathPoints(const VContainer *data) const
VGrainlineData & GetGrainlineGeometry()
VDetail::GetGrainlineGeometry full access to the grainline geometry object.
VPatternLabelData & GetPatternInfo()
Returns full access to the pattern info geometry object.
The VPointF class keep data of point.
The VSAPoint class seam allowance point.
The VTextManager class this class is used to determine whether a collection of text lines can fit int...
int GetSourceLinesCount() const
VTextManager::GetSourceLinesCount returns the number of input text lines.
virtual int GetSpacing() const
GetSpacing returns the vertical spacing between the lines.
const QFont & GetFont() const
GetFont returns the text base font.
const TextLine & GetSourceLine(int i) const
VTextManager::GetSourceLine returns the reference to i-th text line.
Error class of the parser.
double ToPixel(double val, const Unit &unit)
static Q_REQUIRED_RESULT bool VFuzzyComparePossibleNulls(double p1, double p2)
const qreal widthHairLine
Qt::PenStyle lineTypeToPenStyle(const QString &lineType)
LineStyle return pen style for current line style.
QVector< VLayoutPiecePath > ConvertInternalPaths(const VPiece &piece, const VContainer *pattern, const bool isCut)
bool FindLabelGeometry(const VPatternLabelData &labelData, const VContainer *pattern, qreal &rotationAngle, qreal &labelWidth, qreal &labelHeight, QPointF &pos)
bool IsItemContained(const QRectF &parentBoundingRect, const QVector< QPointF > &shape, qreal &dX, qreal &dY)
QVector< QPointF > CorrectPosition(const QRectF &parentBoundingRect, QVector< QPointF > points)
QStringList PieceLabelText(const QVector< QPointF > &labelShape, const VTextManager &tm)
QPointF RotatePoint(const QPointF &ptCenter, const QPointF &pt, qreal rotationAngle)
VLayoutPiece::RotatePoint rotates a point around the center for given angle.
QVector< VSAPoint > PrepareAllowance(const QVector< QPointF > &points)
bool FindGrainlineGeometry(const VGrainlineData &data, const VContainer *pattern, qreal &length, qreal &rotationAngle, QPointF &pos)
The TextLine struct holds the information about one text line.