Seamly2D
Code documentation
vlayoutpiece.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ** @file vlayoutpiece.cpp
3  ** @author Douglas S Caskey
4  ** @date Dec 27, 2022
5  **
6  ** @copyright
7  ** Copyright (C) 2017 - 2022 Seamly, LLC
8  ** https://github.com/fashionfreedom/seamly2d
9  **
10  ** @brief
11  ** Seamly2D is free software: you can redistribute it and/or modify
12  ** it under the terms of the GNU General Public License as published by
13  ** the Free Software Foundation, either version 3 of the License, or
14  ** (at your option) any later version.
15  **
16  ** Seamly2D is distributed in the hope that it will be useful,
17  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  ** GNU General Public License for more details.
20  **
21  ** You should have received a copy of the GNU General Public License
22  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
23  **************************************************************************/
24 
25 /************************************************************************
26  **
27  ** @file vlayoutdetail.cpp
28  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
29  ** @date 2 1, 2015
30  **
31  ** @brief
32  ** @copyright
33  ** This source code is part of the Valentina project, a pattern making
34  ** program, whose allow create and modeling patterns of clothing.
35  ** Copyright (C) 2013-2015 Valentina project
36  ** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
37  **
38  ** Valentina is free software: you can redistribute it and/or modify
39  ** it under the terms of the GNU General Public License as published by
40  ** the Free Software Foundation, either version 3 of the License, or
41  ** (at your option) any later version.
42  **
43  ** Valentina is distributed in the hope that it will be useful,
44  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
45  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46  ** GNU General Public License for more details.
47  **
48  ** You should have received a copy of the GNU General Public License
49  ** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
50  **
51  *************************************************************************/
52 
53 #include "vlayoutpiece.h"
54 
55 #include <QBrush>
56 #include <QFlags>
57 #include <QFont>
58 #include <QFontMetrics>
59 #include <QGraphicsPathItem>
60 #include <QList>
61 #include <QMatrix>
62 #include <QMessageLogger>
63 #include <QPainterPath>
64 #include <QPoint>
65 #include <QPolygonF>
66 #include <QTransform>
67 #include <Qt>
68 #include <QtDebug>
69 
70 #include "global.h"
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"
79 #include "vlayoutdef.h"
80 #include "vlayoutpiece_p.h"
81 #include "vtextmanager.h"
82 #include "vgraphicsfillitem.h"
83 
84 namespace
85 {
86 //---------------------------------------------------------------------------------------------------------------------
87 QVector<VLayoutPiecePath> ConvertInternalPaths(const VPiece &piece, const VContainer *pattern, const bool isCut)
88 {
89  SCASSERT(pattern != nullptr)
90 
92  const QVector<quint32> pathIds = piece.GetInternalPaths();
93  for (int i = 0; i < pathIds.size(); ++i)
94  {
95  const VPiecePath path = pattern->GetPiecePath(pathIds.at(i));
97  {
98  if (isCut && path.IsCutPath())
99  {
100  paths.append(VLayoutPiecePath(path.PathPoints(pattern), path.IsCutPath(), path.GetPenType()));
101  }
102  else if (!isCut && !path.IsCutPath())
103  {
104  paths.append(VLayoutPiecePath(path.PathPoints(pattern), path.IsCutPath(), path.GetPenType()));
105  }
106  }
107  }
108  return paths;
109 }
110 
111 //---------------------------------------------------------------------------------------------------------------------
112 bool FindLabelGeometry(const VPatternLabelData &labelData, const VContainer *pattern, qreal &rotationAngle,
113  qreal &labelWidth, qreal &labelHeight, QPointF &pos)
114 {
115  SCASSERT(pattern != nullptr)
116 
117  try
118  {
119  Calculator cal1;
120  rotationAngle = cal1.EvalFormula(pattern->DataVariables(), labelData.GetRotation());
121  }
122  catch(qmu::QmuParserError &e)
123  {
124  Q_UNUSED(e);
125  return false;
126  }
127 
128  const quint32 topLeftAnchorPoint = labelData.topLeftAnchorPoint();
129  const quint32 bottomRightAnchorPoint = labelData.bottomRightAnchorPoint();
130 
131  if (topLeftAnchorPoint != NULL_ID && bottomRightAnchorPoint != NULL_ID)
132  {
133  try
134  {
135  const auto topLeftAnchorPointPoint = pattern->GeometricObject<VPointF>(topLeftAnchorPoint);
136  const auto bottomRightAnchorPointPoint = pattern->GeometricObject<VPointF>(bottomRightAnchorPoint);
137 
138  const QRectF labelRect = QRectF(static_cast<QPointF>(*topLeftAnchorPointPoint),
139  static_cast<QPointF>(*bottomRightAnchorPointPoint));
140  labelWidth = qAbs(labelRect.width());
141  labelHeight = qAbs(labelRect.height());
142 
143  pos = labelRect.topLeft();
144 
145  return true;
146  }
147  catch(const VExceptionBadId &)
148  {
149  // do nothing.
150  }
151  }
152 
153  try
154  {
155  Calculator cal1;
156  labelWidth = cal1.EvalFormula(pattern->DataVariables(), labelData.GetLabelWidth());
157 
158  Calculator cal2;
159  labelHeight = cal2.EvalFormula(pattern->DataVariables(), labelData.GetLabelHeight());
160  }
161  catch(qmu::QmuParserError &e)
162  {
163  Q_UNUSED(e);
164  return false;
165  }
166 
167  const quint32 centerAnchor = labelData.centerAnchorPoint();
168  if (centerAnchor != NULL_ID)
169  {
170  try
171  {
172  const auto centerAnchorPoint = pattern->GeometricObject<VPointF>(centerAnchor);
173 
174  const qreal lWidth = ToPixel(labelWidth, *pattern->GetPatternUnit());
175  const qreal lHeight = ToPixel(labelHeight, *pattern->GetPatternUnit());
176 
177  pos = static_cast<QPointF>(*centerAnchorPoint) - QRectF(0, 0, lWidth, lHeight).center();
178  }
179  catch(const VExceptionBadId &)
180  {
181  pos = labelData.GetPos();
182  }
183  }
184  else
185  {
186  pos = labelData.GetPos();
187  }
188 
189  return true;
190 }
191 
192 //---------------------------------------------------------------------------------------------------------------------
193 bool FindGrainlineGeometry(const VGrainlineData& data, const VContainer *pattern, qreal &length, qreal &rotationAngle,
194  QPointF &pos)
195 {
196  SCASSERT(pattern != nullptr)
197 
198  const quint32 topAnchorPoint = data.topAnchorPoint();
199  const quint32 bottomAnchorPoint = data.bottomAnchorPoint();
200 
201  if (topAnchorPoint != NULL_ID && bottomAnchorPoint != NULL_ID)
202  {
203  try
204  {
205  const auto topAnchor_Point = pattern->GeometricObject<VPointF>(topAnchorPoint);
206  const auto bottomAnchor_Point = pattern->GeometricObject<VPointF>(bottomAnchorPoint);
207 
208  QLineF grainline(static_cast<QPointF>(*bottomAnchor_Point), static_cast<QPointF>(*topAnchor_Point));
209  length = grainline.length();
210  rotationAngle = grainline.angle();
211 
212  if (not VFuzzyComparePossibleNulls(rotationAngle, 0))
213  {
214  grainline.setAngle(0);
215  }
216 
217  pos = grainline.p1();
218  rotationAngle = qDegreesToRadians(rotationAngle);
219 
220  return true;
221  }
222  catch(const VExceptionBadId &)
223  {
224  // do nothing.
225  }
226  }
227 
228  try
229  {
230  Calculator cal1;
231  rotationAngle = cal1.EvalFormula(pattern->DataVariables(), data.GetRotation());
232  rotationAngle = qDegreesToRadians(rotationAngle);
233 
234  Calculator cal2;
235  length = cal2.EvalFormula(pattern->DataVariables(), data.GetLength());
236  length = ToPixel(length, *pattern->GetPatternUnit());
237  }
238  catch(qmu::QmuParserError &e)
239  {
240  Q_UNUSED(e);
241  return false;
242  }
243 
244  const quint32 centerAnchor = data.centerAnchorPoint();
245  if (centerAnchor != NULL_ID)
246  {
247  try
248  {
249  const auto centerAnchorPoint = pattern->GeometricObject<VPointF>(centerAnchor);
250 
251  QLineF grainline(centerAnchorPoint->x(), centerAnchorPoint->y(),
252  centerAnchorPoint->x() + length / 2.0, centerAnchorPoint->y());
253 
254  grainline.setAngle(qRadiansToDegrees(rotationAngle));
255  grainline = QLineF(grainline.p2(), grainline.p1());
256  grainline.setLength(length);
257 
258  pos = grainline.p2();
259  }
260  catch(const VExceptionBadId &)
261  {
262  pos = data.GetPos();
263  }
264  }
265  else
266  {
267  pos = data.GetPos();
268  }
269  return true;
270 }
271 
272 //---------------------------------------------------------------------------------------------------------------------
273 bool IsItemContained(const QRectF &parentBoundingRect, const QVector<QPointF> &shape, qreal &dX, qreal &dY)
274 {
275  dX = 0;
276  dY = 0;
277  // single point differences
278  bool bInside = true;
279 
280  for (int i = 0; i < shape.size(); ++i)
281  {
282  qreal dPtX = 0;
283  qreal dPtY = 0;
284  if (not parentBoundingRect.contains(shape.at(i)))
285  {
286  if (shape.at(i).x() < parentBoundingRect.left())
287  {
288  dPtX = parentBoundingRect.left() - shape.at(i).x();
289  }
290  else if (shape.at(i).x() > parentBoundingRect.right())
291  {
292  dPtX = parentBoundingRect.right() - shape.at(i).x();
293  }
294 
295  if (shape.at(i).y() < parentBoundingRect.top())
296  {
297  dPtY = parentBoundingRect.top() - shape.at(i).y();
298  }
299  else if (shape.at(i).y() > parentBoundingRect.bottom())
300  {
301  dPtY = parentBoundingRect.bottom() - shape.at(i).y();
302  }
303 
304  if (fabs(dPtX) > fabs(dX))
305  {
306  dX = dPtX;
307  }
308 
309  if (fabs(dPtY) > fabs(dY))
310  {
311  dY = dPtY;
312  }
313 
314  bInside = false;
315  }
316  }
317  return bInside;
318 }
319 
320 //---------------------------------------------------------------------------------------------------------------------
321 QVector<QPointF> CorrectPosition(const QRectF &parentBoundingRect, QVector<QPointF> points)
322 {
323  qreal dX = 0;
324  qreal dY = 0;
325  if (not IsItemContained(parentBoundingRect, points, dX, dY))
326  {
327  for (int i =0; i < points.size(); ++i)
328  {
329  points[i] = QPointF(points.at(i).x() + dX, points.at(i).y() + dY);
330  }
331  }
332  return points;
333 }
334 
335 //---------------------------------------------------------------------------------------------------------------------
337 {
338  QVector<VSAPoint> allowancePoints;
339  for(int i = 0; i < points.size(); ++i)
340  {
341  allowancePoints.append(VSAPoint(points.at(i)));
342  }
343  return allowancePoints;
344 }
345 
346 //---------------------------------------------------------------------------------------------------------------------
347 /**
348  * @brief VLayoutPiece::RotatePoint rotates a point around the center for given angle
349  * @param ptCenter center around which the point is rotated
350  * @param pt point, which is rotated around the center
351  * @param rotationAngle angle of rotation
352  * @return position of point pt after rotating it around the center for rotation radians
353  */
354 QPointF RotatePoint(const QPointF &ptCenter, const QPointF& pt, qreal rotationAngle)
355 {
356  QPointF ptDest;
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());
360 
361  return ptDest + ptCenter;
362 }
363 
364 //---------------------------------------------------------------------------------------------------------------------
365 QStringList PieceLabelText(const QVector<QPointF> &labelShape, const VTextManager &tm)
366 {
367  QStringList text;
368  if (labelShape.count() > 2)
369  {
370  for (int i = 0; i < tm.GetSourceLinesCount(); ++i)
371  {
372  text.append(tm.GetSourceLine(i).m_text);
373  }
374  }
375  return text;
376 }
377 }
378 
379 //---------------------------------------------------------------------------------------------------------------------
380 
381 #ifdef Q_COMPILER_RVALUE_REFS
382 VLayoutPiece &VLayoutPiece::operator=(VLayoutPiece &&piece) Q_DECL_NOTHROW { Swap(piece); return *this; }
383 #endif
384 
385 void VLayoutPiece::Swap(VLayoutPiece &piece) Q_DECL_NOTHROW
386 { VAbstractPiece::Swap(piece); std::swap(d, piece.d); }
387 
388 //---------------------------------------------------------------------------------------------------------------------
390  : VAbstractPiece(),
391  d(new VLayoutPieceData)
392 {}
393 
394 //---------------------------------------------------------------------------------------------------------------------
396  : VAbstractPiece(piece),
397  d(piece.d)
398 {}
399 
400 //---------------------------------------------------------------------------------------------------------------------
402 {
403  if ( &piece == this )
404  {
405  return *this;
406  }
408  d = piece.d;
409  return *this;
410 }
411 
412 //---------------------------------------------------------------------------------------------------------------------
414 {}
415 
416 //---------------------------------------------------------------------------------------------------------------------
417 VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern)
418 {
419  VLayoutPiece layoutPiece;
420 
421  layoutPiece.SetMx(piece.GetMx());
422  layoutPiece.SetMy(piece.GetMy());
423 
424  layoutPiece.SetCountourPoints(piece.MainPathPoints(pattern), piece.isHideSeamLine());
425  layoutPiece.setSeamAllowancePoints(piece.SeamAllowancePoints(pattern), piece.IsSeamAllowance(),
426  piece.IsSeamAllowanceBuiltIn());
427  layoutPiece.setInternalPaths(ConvertInternalPaths(piece, pattern, false));
428  layoutPiece.setCutoutPaths(ConvertInternalPaths(piece, pattern, true));
429  layoutPiece.setNotches(piece.createNotchLines(pattern));
430 
431  layoutPiece.SetName(piece.GetName());
432 
433  // Very important to set main path first!
434  if (layoutPiece.createMainPath().isEmpty() && layoutPiece.createAllowancePath().isEmpty())
435  {
436  throw VException (tr("Piece %1 doesn't have shape.").arg(piece.GetName()));
437  }
438 
439  const VPieceLabelData& pieceLabelData = piece.GetPatternPieceData();
440  if (pieceLabelData.IsVisible() == true)
441  {
442  layoutPiece.SetPieceText(piece.GetName(), pieceLabelData, qApp->Settings()->getLabelFont(), pattern);
443  }
444 
445  const VPatternLabelData& patternLabelData = piece.GetPatternInfo();
446  if (patternLabelData.IsVisible() == true)
447  {
448  VAbstractPattern* pDoc = qApp->getCurrentDocument();
449  layoutPiece.SetPatternInfo(pDoc, patternLabelData, qApp->Settings()->getLabelFont(), pattern);
450  }
451 
452  const VGrainlineData& grainlineGeom = piece.GetGrainlineGeometry();
453  if (grainlineGeom.IsVisible() == true)
454  {
455  layoutPiece.setGrainline(grainlineGeom, pattern);
456  }
457 
458  layoutPiece.SetSAWidth(qApp->toPixel(piece.GetSAWidth()));
459  layoutPiece.SetForbidFlipping(piece.IsForbidFlipping());
460 
461  return layoutPiece;
462 }
463 
464 //---------------------------------------------------------------------------------------------------------------------
465 // cppcheck-suppress unusedFunction
467 {
468  return Map(d->contour);
469 }
470 
471 //---------------------------------------------------------------------------------------------------------------------
472 void VLayoutPiece::SetCountourPoints(const QVector<QPointF> &points, bool hideMainPath)
473 {
474  d->contour = RemoveDublicates(points, false);
475  setHideSeamLine(hideMainPath);
476 }
477 
478 //---------------------------------------------------------------------------------------------------------------------
479 // cppcheck-suppress unusedFunction
481 {
482  return Map(d->seamAllowance);
483 }
484 
485 //---------------------------------------------------------------------------------------------------------------------
486 void VLayoutPiece::setSeamAllowancePoints(const QVector<QPointF> &points, bool seamAllowance, bool seamAllowanceBuiltIn)
487 {
488  if (seamAllowance)
489  {
490  SetSeamAllowance(seamAllowance);
491  SetSeamAllowanceBuiltIn(seamAllowanceBuiltIn);
492  d->seamAllowance = points;
493  if (not d->seamAllowance.isEmpty())
494  {
495  d->seamAllowance = RemoveDublicates(d->seamAllowance, false);
496  }
497  else if (not IsSeamAllowanceBuiltIn())
498  {
499  qWarning()<<"Seam allowance is empty.";
500  SetSeamAllowance(false);
501  }
502  }
503 }
504 
505 //---------------------------------------------------------------------------------------------------------------------
507 {
508  return Map(d->layoutAllowance);
509 }
510 
511 //---------------------------------------------------------------------------------------------------------------------
513 {
514  if (d->pieceLabel.count() > 2)
515  {
516  return d->transform.map(d->pieceLabel.first());
517  }
518  else
519  {
520  return QPointF();
521  }
522 }
523 
524 //---------------------------------------------------------------------------------------------------------------------
525 QStringList VLayoutPiece::GetPieceText() const
526 {
527  return PieceLabelText(d->pieceLabel, d->m_tmPiece);
528 }
529 
530 //---------------------------------------------------------------------------------------------------------------------
531 void VLayoutPiece::SetPieceText(const QString& qsName, const VPieceLabelData& data, const QFont &font,
532  const VContainer *pattern)
533 {
534  QPointF ptPos;
535  qreal labelWidth = 0;
536  qreal labelHeight = 0;
537  qreal labelAngle = 0;
538  if (not FindLabelGeometry(data, pattern, labelAngle, labelWidth, labelHeight, ptPos))
539  {
540  return;
541  }
542 
543  labelWidth = ToPixel(labelWidth, *pattern->GetPatternUnit());
544  labelHeight = ToPixel(labelHeight, *pattern->GetPatternUnit());
545 
547  v << ptPos
548  << QPointF(ptPos.x() + labelWidth, ptPos.y())
549  << QPointF(ptPos.x() + labelWidth, ptPos.y() + labelHeight)
550  << QPointF(ptPos.x(), ptPos.y() + labelHeight);
551 
552  const qreal rotationAngle = qDegreesToRadians(-labelAngle);
553  const QPointF ptCenter(ptPos.x() + labelWidth/2, ptPos.y() + labelHeight/2);
554 
555  for (int i = 0; i < v.count(); ++i)
556  {
557  v[i] = RotatePoint(ptCenter, v.at(i), rotationAngle);
558  }
559 
560  QScopedPointer<QGraphicsItem> item(getMainPathItem());
561  d->pieceLabel = CorrectPosition(item->boundingRect(), v);
562 
563  // generate text
564  d->m_tmPiece.setFont(font);
565  d->m_tmPiece.SetFontSize(data.getFontSize());
566  d->m_tmPiece.Update(qsName, data);
567  // this will generate the lines of text
568  d->m_tmPiece.SetFontSize(data.getFontSize());
569  d->m_tmPiece.FitFontSize(labelWidth, labelHeight);
570 }
571 
572 //---------------------------------------------------------------------------------------------------------------------
574 {
575  if (d->patternInfo.count() > 2)
576  {
577  return d->transform.map(d->patternInfo.first());
578  }
579  else
580  {
581  return QPointF();
582  }
583 }
584 
585 //---------------------------------------------------------------------------------------------------------------------
586 QStringList VLayoutPiece::GetPatternText() const
587 {
588  return PieceLabelText(d->patternInfo, d->m_tmPattern);
589 }
590 
591 //---------------------------------------------------------------------------------------------------------------------
592 void VLayoutPiece::SetPatternInfo(VAbstractPattern* pDoc, const VPatternLabelData& data, const QFont &font,
593  const VContainer *pattern)
594 {
595  QPointF ptPos;
596  qreal labelWidth = 0;
597  qreal labelHeight = 0;
598  qreal labelAngle = 0;
599  if (not FindLabelGeometry(data, pattern, labelAngle, labelWidth, labelHeight, ptPos))
600  {
601  return;
602  }
603 
604  labelWidth = ToPixel(labelWidth, *pattern->GetPatternUnit());
605  labelHeight = ToPixel(labelHeight, *pattern->GetPatternUnit());
606 
608  v << ptPos
609  << QPointF(ptPos.x() + labelWidth, ptPos.y())
610  << QPointF(ptPos.x() + labelWidth, ptPos.y() + labelHeight)
611  << QPointF(ptPos.x(), ptPos.y() + labelHeight);
612 
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)
616  {
617  v[i] = RotatePoint(ptCenter, v.at(i), rotationAngle);
618  }
619  QScopedPointer<QGraphicsItem> item(getMainPathItem());
620  d->patternInfo = CorrectPosition(item->boundingRect(), v);
621 
622  // Generate text
623  d->m_tmPattern.setFont(font);
624  d->m_tmPattern.SetFontSize(data.getFontSize());
625 
626  d->m_tmPattern.Update(pDoc);
627 
628  // generate lines of text
629  d->m_tmPattern.SetFontSize(data.getFontSize());
630  d->m_tmPattern.FitFontSize(labelWidth, labelHeight);
631 }
632 
633 //---------------------------------------------------------------------------------------------------------------------
634 void VLayoutPiece::setGrainline(const VGrainlineData& data, const VContainer* pattern)
635 {
636  SCASSERT(pattern != nullptr)
637 
638  QPointF pt1;
639  qreal rotationAngle = 0;
640  qreal length = 0;
641  if ( not FindGrainlineGeometry(data, pattern, length, rotationAngle, pt1))
642  {
643  return;
644  }
645 
646  const qreal arrowLength = 45;
647  const qreal arrowAngle = M_PI/9;
648 
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));
655 
657  v << pt2;
658  if (data.GetArrowType() != ArrowType::atFront)
659  {
660  v << QPointF(pt1.x() + arrowLength * qCos(rotationAngle + arrowAngle),
661  pt1.y() - arrowLength * qSin(rotationAngle + arrowAngle));
662  v << pt1;
663  v << QPointF(pt1.x() + arrowLength * qCos(rotationAngle - arrowAngle),
664  pt1.y() - arrowLength * qSin(rotationAngle - arrowAngle));
665  v << pt2;
666  }
667 
668  v << pt4;
669  if (data.GetArrowType() != ArrowType::atRear)
670  {
671  rotationAngle += M_PI;
672  v << QPointF(pt3.x() + arrowLength * qCos(rotationAngle + arrowAngle),
673  pt3.y() - arrowLength * qSin(rotationAngle + arrowAngle));
674  v << pt3;
675  v << QPointF(pt3.x() + arrowLength * qCos(rotationAngle - arrowAngle),
676  pt3.y() - arrowLength * qSin(rotationAngle - arrowAngle));
677  v << pt4;
678  }
679 
680  QScopedPointer<QGraphicsItem> item(getMainPathItem());
681  d->grainlinePoints = CorrectPosition(item->boundingRect(), v);
682 }
683 
684 //---------------------------------------------------------------------------------------------------------------------
686 {
687  return Map(d->grainlinePoints);
688 }
689 
690 //---------------------------------------------------------------------------------------------------------------------
691 QTransform VLayoutPiece::getTransform() const
692 {
693  return d->transform;
694 }
695 
696 //---------------------------------------------------------------------------------------------------------------------
697 void VLayoutPiece::setTransform(const QTransform &transform)
698 {
699  d->transform = transform;
700 }
701 
702 //---------------------------------------------------------------------------------------------------------------------
704 {
705  return d->layoutWidth;
706 }
707 
708 //---------------------------------------------------------------------------------------------------------------------
709 void VLayoutPiece::SetLayoutWidth(const qreal &value)
710 {
711  d->layoutWidth = value;
712 }
713 
714 //---------------------------------------------------------------------------------------------------------------------
715 void VLayoutPiece::Translate(qreal dx, qreal dy)
716 {
717  QTransform m;
718  m.translate(dx, dy);
719  d->transform *= m;
720 }
721 
722 //---------------------------------------------------------------------------------------------------------------------
723 void VLayoutPiece::Rotate(const QPointF &originPoint, qreal degrees)
724 {
725  QTransform m;
726  m.translate(originPoint.x(), originPoint.y());
727  m.rotate(-degrees);
728  m.translate(-originPoint.x(), -originPoint.y());
729  d->transform *= m;
730 }
731 
732 //---------------------------------------------------------------------------------------------------------------------
733 void VLayoutPiece::Mirror(const QLineF &edge)
734 {
735  if (edge.isNull())
736  {
737  return;
738  }
739 
740  const QLineF axis = QLineF(edge.x2(), edge.y2(), edge.x2() + 100, edge.y2()); // Ox axis
741 
742  const qreal angle = edge.angleTo(axis);
743  const QPointF p2 = edge.p2();
744  QTransform m;
745  m.translate(p2.x(), p2.y());
746  m.rotate(-angle);
747  m.translate(-p2.x(), -p2.y());
748  d->transform *= m;
749 
750  m.reset();
751  m.translate(p2.x(), p2.y());
752  m.scale(m.m11(), m.m22()*-1);
753  m.translate(-p2.x(), -p2.y());
754  d->transform *= m;
755 
756  m.reset();
757  m.translate(p2.x(), p2.y());
758  m.rotate(-(360-angle));
759  m.translate(-p2.x(), -p2.y());
760  d->transform *= m;
761 
762  d->mirror = !d->mirror;
763 }
764 
765 //---------------------------------------------------------------------------------------------------------------------
767 {
768  return piecePath().count();
769 }
770 
771 //---------------------------------------------------------------------------------------------------------------------
773 {
774  return d->layoutAllowance.count();
775 }
776 
777 //---------------------------------------------------------------------------------------------------------------------
778 QLineF VLayoutPiece::pieceEdge(int i) const
779 {
780  return Edge(piecePath(), i);
781 }
782 
783 //---------------------------------------------------------------------------------------------------------------------
784 QLineF VLayoutPiece::LayoutEdge(int i) const
785 {
786  return Edge(d->layoutAllowance, i);
787 }
788 
789 //---------------------------------------------------------------------------------------------------------------------
790 int VLayoutPiece::pieceEdgeByPoint(const QPointF &p1) const
791 {
792  return EdgeByPoint(piecePath(), p1);
793 }
794 
795 //---------------------------------------------------------------------------------------------------------------------
796 int VLayoutPiece::LayoutEdgeByPoint(const QPointF &p1) const
797 {
798  return EdgeByPoint(d->layoutAllowance, p1);
799 }
800 
801 //---------------------------------------------------------------------------------------------------------------------
803 {
804  QVector<QPointF> points;
806  {
807  points = GetSeamAllowancePoints();
808  }
809  else
810  {
811  points = getContourPoints();
812  }
813 
814  points.append(points.first());
815  return QPolygonF(points).boundingRect();
816 }
817 
818 //---------------------------------------------------------------------------------------------------------------------
820 {
822  points.append(points.first());
823  return QPolygonF(points).boundingRect();
824 }
825 
826 //---------------------------------------------------------------------------------------------------------------------
828 {
829  const QRectF rec = LayoutBoundingRect();
830  return qSqrt(pow(rec.height(), 2) + pow(rec.width(), 2));
831 }
832 
833 //---------------------------------------------------------------------------------------------------------------------
835 {
836  if (d->contour.isEmpty() == false && d->layoutWidth > 0)
837  {
838  if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn() && d->seamAllowance.isEmpty() == false)
839  {
840  return false;
841  }
842  else
843  {
844  return true;
845  }
846  }
847  else
848  {
849  return true;
850  }
851 }
852 
853 //---------------------------------------------------------------------------------------------------------------------
854 qint64 VLayoutPiece::Square() const
855 {
856  if (d->layoutAllowance.isEmpty()) //-V807
857  {
858  return 0;
859  }
860 
861  const qreal res = sumTrapezoids(d->layoutAllowance);
862 
863  const qint64 sq = qFloor(qAbs(res/2.0));
864  return sq;
865 }
866 
867 //---------------------------------------------------------------------------------------------------------------------
869 {
870  if (d->layoutWidth > 0)
871  {
873  {
874  d->layoutAllowance = Equidistant(PrepareAllowance(GetSeamAllowancePoints()), d->layoutWidth);
875  if (d->layoutAllowance.isEmpty() == false)
876  {
877  d->layoutAllowance.removeLast();
878  }
879  }
880  else
881  {
882  d->layoutAllowance = Equidistant(PrepareAllowance(getContourPoints()), d->layoutWidth);
883  if (d->layoutAllowance.isEmpty() == false)
884  {
885  d->layoutAllowance.removeLast();
886  }
887  }
888  }
889  else
890  {
891  d->layoutAllowance.clear();
892  }
893 }
894 
895 //---------------------------------------------------------------------------------------------------------------------
897 {
898  return Map(d->notches);
899 }
900 
901 //---------------------------------------------------------------------------------------------------------------------
903 {
904  if (IsSeamAllowance())
905  {
906  d->notches = notches;
907  }
908 }
909 
910 //---------------------------------------------------------------------------------------------------------------------
912 {
913  QVector<QVector<QPointF> > paths;
914 
915  for (int i=0;i < d->m_internalPaths.count(); ++i)
916  {
917  if (d->m_internalPaths.at(i).IsCutPath() == cut)
918  {
919  paths.append(Map(d->m_internalPaths.at(i).Points()));
920  }
921  }
922 
923  return paths;
924 }
925 
926 //---------------------------------------------------------------------------------------------------------------------
928 {
929  return d->m_internalPaths;
930 }
931 
932 //---------------------------------------------------------------------------------------------------------------------
934 {
935  d->m_internalPaths = internalPaths;
936 }
937 
938 //---------------------------------------------------------------------------------------------------------------------
940 {
941  return d->m_cutoutPaths;
942 }
943 
944 //---------------------------------------------------------------------------------------------------------------------
946 {
947  d->m_cutoutPaths = cutoutPaths;
948 }
949 
950 //---------------------------------------------------------------------------------------------------------------------
951 template <class T>
953 {
954  QVector<T> p;
955  for (int i = 0; i < points.size(); ++i)
956  {
957  p.append(d->transform.map(points.at(i)));
958  }
959 
960  if (d->mirror)
961  {
962  QList<T> list = p.toList();
963  for (int k=0, s=list.size(), max=(s/2); k<max; k++)
964  {
965  list.swapItemsAt(k, s-(1+k));
966  }
967  p = list.toVector();
968  }
969  return p;
970 }
971 
972 //---------------------------------------------------------------------------------------------------------------------
973 QPainterPath VLayoutPiece::createMainPath() const
974 {
975  QPainterPath path;
976 
977  // contour
979 
980  if (not isHideSeamLine() || not IsSeamAllowance() || IsSeamAllowanceBuiltIn())
981  {
982  path.moveTo(points.at(0));
983  for (qint32 i = 1; i < points.count(); ++i)
984  {
985  path.lineTo(points.at(i));
986  }
987  path.lineTo(points.at(0));
988  }
989  return path;
990 }
991 
992 //---------------------------------------------------------------------------------------------------------------------
994 {
995  QPainterPath path;
996 
997  // seam allowance
998  if (IsSeamAllowance())
999  {
1000  if (not IsSeamAllowanceBuiltIn())
1001  {
1002  // Draw seam allowance
1004 
1005  if (points.last().toPoint() != points.first().toPoint())
1006  {
1007  points.append(points.at(0));// Should be always closed
1008  }
1009 
1010  QPainterPath ekv;
1011  ekv.moveTo(points.at(0));
1012  for (qint32 i = 1; i < points.count(); ++i)
1013  {
1014  ekv.lineTo(points.at(i));
1015  }
1016 
1017  path.addPath(ekv);
1018  }
1019  }
1020 
1021  return path;
1022 }
1023 
1024 //---------------------------------------------------------------------------------------------------------------------
1026 {
1027  QPainterPath path;
1028 
1029  const QVector<QLineF> notches = getNotches();
1030  QPainterPath notchesPath;
1031 
1032  for (qint32 i = 0; i < notches.count(); ++i)
1033  {
1034  notchesPath.moveTo(notches.at(i).p1());
1035  notchesPath.lineTo(notches.at(i).p2());
1036  }
1037 
1038  path.addPath(notchesPath);
1039  path.setFillRule(Qt::WindingFill);
1040 
1041  return path;
1042 }
1043 
1044 //---------------------------------------------------------------------------------------------------------------------
1045 void VLayoutPiece::createInternalPathItem(int i, QGraphicsItem *parent) const
1046 {
1047  SCASSERT(parent != nullptr)
1048  QColor color = QColor(qApp->Settings()->getDefaultInternalColor());
1049  QString lineType = qApp->Settings()->getDefaultInternalLinetype();
1050  qreal lineWeight = ToPixel(qApp->Settings()->getDefaultInternalLineweight(), Unit::Mm);
1051 
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));
1055 }
1056 
1057 //---------------------------------------------------------------------------------------------------------------------
1058 void VLayoutPiece::createCutoutPathItem(int i, QGraphicsItem *parent) const
1059 {
1060  SCASSERT(parent != nullptr)
1061  QColor color = QColor(qApp->Settings()->getDefaultCutoutColor());
1062  QString lineType = qApp->Settings()->getDefaultCutoutLinetype();
1063  qreal lineWeight = ToPixel(qApp->Settings()->getDefaultCutoutLineweight(), Unit::Mm);
1064 
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));
1068 }
1069 
1070 //---------------------------------------------------------------------------------------------------------------------
1072 {
1073  QPainterPath path;
1074  path.setFillRule(Qt::WindingFill);
1075 
1076  const QVector<QPointF> points = getLayoutAllowancePoints();
1077  path.moveTo(points.at(0));
1078  for (qint32 i = 1; i < points.count(); ++i)
1079  {
1080  path.lineTo(points.at(i));
1081  }
1082  path.lineTo(points.at(0));
1083 
1084  return path;
1085 }
1086 
1087 //---------------------------------------------------------------------------------------------------------------------
1088 QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const
1089 {
1090  QGraphicsPathItem *item = createMainItem();
1091  createAllowanceItem(item);
1092  createNotchesItem(item);
1093 
1094  for (int i = 0; i < d->m_internalPaths.count(); ++i)
1095  {
1096  createInternalPathItem(i, item);
1097  }
1098 
1099  for (int i = 0; i < d->m_cutoutPaths.count(); ++i)
1100  {
1101  createCutoutPathItem(i, item);
1102  }
1103 
1104  createLabelItem(item, d->pieceLabel, d->m_tmPiece, textAsPaths);
1105  createLabelItem(item, d->patternInfo, d->m_tmPattern, textAsPaths);
1106  createGrainlineItem(item, textAsPaths);
1107 
1108  return item;
1109 }
1110 
1111 //---------------------------------------------------------------------------------------------------------------------
1112 void VLayoutPiece::createLabelItem(QGraphicsItem *parent, const QVector<QPointF> &labelShape,
1113  const VTextManager &tm, bool textAsPaths) const
1114 {
1115  SCASSERT(parent != nullptr)
1116  QColor color = QColor(qApp->Settings()->getDefaultLabelColor());
1117 
1118  if (labelShape.count() > 2)
1119  {
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();
1123  qreal dY = 0;
1124  qreal dX = 0;
1125 
1126  for (int i = 0; i < tm.GetSourceLinesCount(); ++i)
1127  {
1128  const TextLine& tl = tm.GetSourceLine(i);
1129  QFont fnt = tm.GetFont();
1130  fnt.setPixelSize(tm.GetFont().pixelSize() + tl.m_iFontSize);
1131  fnt.setBold(tl.bold);
1132  fnt.setItalic(tl.italic);
1133 
1134  QFontMetrics fm(fnt);
1135 
1136  if (textAsPaths)
1137  {
1138  dY += fm.height();
1139  }
1140 
1141  if (dY > dH)
1142  {
1143  break;
1144  }
1145 
1146  QString qsText = tl.m_text;
1147  if (fm.horizontalAdvance(qsText) > dW)
1148  {
1149  qsText = fm.elidedText(qsText, Qt::ElideMiddle, static_cast<int>(dW));
1150  }
1151  if ((tl.m_eAlign & Qt::AlignLeft) > 0)
1152  {
1153  dX = 0;
1154  }
1155  else if ((tl.m_eAlign & Qt::AlignHCenter) > 0)
1156  {
1157  dX = (dW - fm.horizontalAdvance(qsText))/2;
1158  }
1159  else
1160  {
1161  dX = dW - fm.horizontalAdvance(qsText);
1162  }
1163 
1164  // set up the rotation around top-left corner matrix
1165  QTransform labelTransform;
1166  labelTransform.translate(labelShape.at(0).x(), labelShape.at(0).y());
1167  if (d->mirror)
1168  {
1169  labelTransform.scale(-1, 1);
1170  labelTransform.rotate(-angle);
1171  labelTransform.translate(-dW, 0);
1172  labelTransform.translate(dX, dY); // Each string has own position
1173  }
1174  else
1175  {
1176  labelTransform.rotate(angle);
1177  labelTransform.translate(dX, dY); // Each string has own position
1178  }
1179 
1180  labelTransform *= d->transform;
1181 
1182  if (textAsPaths)
1183  {
1184  QPainterPath path;
1185  path.addText(0, - static_cast<qreal>(fm.ascent())/6., fnt, qsText);
1186 
1187  QGraphicsPathItem* item = new QGraphicsPathItem(parent);
1188  item->setPath(path);
1189  item->setPen(QPen(color, widthHairLine));
1190  item->setBrush(QBrush(Qt::NoBrush));
1191  item->setTransform(labelTransform);
1192 
1193  dY += tm.GetSpacing();
1194  }
1195  else
1196  {
1197  QGraphicsSimpleTextItem* item = new QGraphicsSimpleTextItem(parent);
1198  item->setFont(fnt);
1199  item->setText(qsText);
1200  item->setTransform(labelTransform);
1201  item->setPen(QPen(color));
1202  item->setBrush(QBrush(color));
1203 
1204  dY += (fm.height() + tm.GetSpacing());
1205  }
1206  }
1207  }
1208 }
1209 
1210 //---------------------------------------------------------------------------------------------------------------------
1211 void VLayoutPiece::createGrainlineItem(QGraphicsItem *parent, bool textAsPaths) const
1212 {
1213  SCASSERT(parent != nullptr)
1214  QColor color = QColor(qApp->Settings()->getDefaultGrainlineColor());
1215 
1216  if (d->grainlinePoints.count() < 2)
1217  {
1218  return;
1219  }
1220  VGraphicsFillItem* item = new VGraphicsFillItem(color, textAsPaths, parent);
1221  QPainterPath path;
1222 
1223  QVector<QPointF> gPoints = getGrainline();
1224  path.moveTo(gPoints.at(0));
1225  for (int i = 1; i < gPoints.count(); ++i)
1226  {
1227  path.lineTo(gPoints.at(i));
1228  }
1229  item->setPath(path);
1230 }
1231 
1232 //---------------------------------------------------------------------------------------------------------------------
1234 {
1235  if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
1236  {
1237  return d->seamAllowance;
1238  }
1239  else
1240  {
1241  return d->contour;
1242  }
1243 }
1244 
1245 //---------------------------------------------------------------------------------------------------------------------
1246 QGraphicsPathItem *VLayoutPiece::createMainItem() const
1247 {
1248  QColor color;
1249  QString lineType;
1250  qreal lineWeight;
1252  {
1253  color = QColor(qApp->Settings()->getDefaultSeamColor());
1254  lineType = qApp->Settings()->getDefaultSeamLinetype();
1255  lineWeight = ToPixel(qApp->Settings()->getDefaultSeamLineweight(), Unit::Mm);
1256  }
1257  else
1258  {
1259  color = QColor(qApp->Settings()->getDefaultCutColor());
1260  lineType = qApp->Settings()->getDefaultCutLinetype();
1261  lineWeight = ToPixel(qApp->Settings()->getDefaultCutLineweight(), Unit::Mm);
1262  }
1263  QGraphicsPathItem *item = new QGraphicsPathItem();
1264  item->setPath(createMainPath());
1265  item->setPen(QPen(color, lineWeight, lineTypeToPenStyle(lineType), Qt::RoundCap, Qt::RoundJoin));
1266  return item;
1267 }
1268 
1269 //---------------------------------------------------------------------------------------------------------------------
1270 void VLayoutPiece::createAllowanceItem(QGraphicsItem *parent) const
1271 {
1272  QColor color = QColor(qApp->Settings()->getDefaultCutColor());
1273  QString lineType = qApp->Settings()->getDefaultCutLinetype();
1274  qreal lineWeight = ToPixel(qApp->Settings()->getDefaultCutLineweight(), Unit::Mm);
1275 
1276  QGraphicsPathItem *item = new QGraphicsPathItem(parent);
1277  item->setPath(createAllowancePath());
1278  item->setPen(QPen(color, lineWeight, lineTypeToPenStyle(lineType), Qt::RoundCap, Qt::RoundJoin));
1279 }
1280 
1281 //---------------------------------------------------------------------------------------------------------------------
1282 void VLayoutPiece::createNotchesItem(QGraphicsItem *parent) const
1283 {
1284  QColor color = QColor(qApp->Settings()->getDefaultNotchColor());
1285 
1286  QGraphicsPathItem *item = new QGraphicsPathItem(parent);
1287  item->setPath(createNotchesPath());
1288  item->setPen(QPen(color, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
1289 }
1290 
1291 //---------------------------------------------------------------------------------------------------------------------
1292 QGraphicsPathItem *VLayoutPiece::getMainPathItem() const
1293 {
1294  QGraphicsPathItem *item = new QGraphicsPathItem();
1295 
1296  QPainterPath path;
1297 
1298  // contour
1300 
1301  path.moveTo(points.at(0));
1302  for (qint32 i = 1; i < points.count(); ++i)
1303  {
1304  path.lineTo(points.at(i));
1305  }
1306  path.lineTo(points.at(0));
1307 
1308  item->setPath(path);
1309  return item;
1310 }
1311 
1312 //---------------------------------------------------------------------------------------------------------------------
1314 {
1315  return d->mirror;
1316 }
1317 
1318 //---------------------------------------------------------------------------------------------------------------------
1319 void VLayoutPiece::SetMirror(bool value)
1320 {
1321  d->mirror = value;
1322 }
1323 
1324 //---------------------------------------------------------------------------------------------------------------------
1325 QLineF VLayoutPiece::Edge(const QVector<QPointF> &path, int i) const
1326 {
1327  if (i < 1 || i > path.count())
1328  { // Doesn't exist such edge
1329  return QLineF();
1330  }
1331 
1332  int i1, i2;
1333  if (i < path.count())
1334  {
1335  i1 = i-1;
1336  i2 = i;
1337  }
1338  else
1339  {
1340  i1 = path.count()-1;
1341  i2 = 0;
1342  }
1343 
1344  if (d->mirror)
1345  {
1346  const int oldI1 = i1;
1347  const int size = path.size()-1; //-V807
1348  i1 = size - i2;
1349  i2 = size - oldI1;
1350  return QLineF(d->transform.map(path.at(i2)), d->transform.map(path.at(i1)));
1351  }
1352  else
1353  {
1354  return QLineF(d->transform.map(path.at(i1)), d->transform.map(path.at(i2)));
1355  }
1356 }
1357 
1358 //---------------------------------------------------------------------------------------------------------------------
1359 int VLayoutPiece::EdgeByPoint(const QVector<QPointF> &path, const QPointF &p1) const
1360 {
1361  if (p1.isNull())
1362  {
1363  return 0;
1364  }
1365 
1366  if (path.count() < 3)
1367  {
1368  return 0;
1369  }
1370 
1371  const QVector<QPointF> points = Map(path);
1372  for (int i=0; i < points.size(); i++)
1373  {
1374  if (points.at(i) == p1)
1375  {
1376  return i+1;
1377  }
1378  }
1379  return 0; // Did not find edge
1380 }
The Calculator class for calculation formula.
Definition: calculator.h:84
qreal EvalFormula(const QHash< QString, QSharedPointer< VInternalVariable > > *vars, const QString &formula)
eval calculate formula.
Definition: calculator.cpp:96
bool IsSeamAllowanceBuiltIn() const
bool IsSeamAllowance() const
bool isHideSeamLine() const
void SetMx(qreal value)
static QVector< QPointF > Equidistant(const QVector< VSAPoint > &points, qreal width)
qreal GetSAWidth() const
static qreal sumTrapezoids(const QVector< QPointF > &points)
qreal GetMx() const
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)
QString GetName() const
qreal GetMy() const
bool IsForbidFlipping() const
void SetMy(qreal value)
VAbstractPiece & operator=(const VAbstractPiece &piece)
The VContainer class container of all variables.
Definition: vcontainer.h:141
const QHash< QString, QSharedPointer< VInternalVariable > > * DataVariables() const
Definition: vcontainer.cpp:718
const QSharedPointer< T > GeometricObject(const quint32 &id) const
Definition: vcontainer.h:266
VPiecePath GetPiecePath(quint32 id) const
Definition: vcontainer.cpp:198
const Unit * GetPatternUnit() const
Definition: vcontainer.cpp:599
The VExceptionBadId class for exception bad id.
The VException class parent for all exception. Could be use for abstract exception.
Definition: vexception.h:66
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
qint64 Square() 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
bool isNull() 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
Definition: vlayoutpiece.h:169
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 > &notches)
Q_REQUIRED_RESULT QGraphicsPathItem * createMainItem() const
int pieceEdgeByPoint(const QPointF &p1) const
QRectF pieceBoundingRect() const
qreal Diagonal() 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
bool isMirror() 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
Definition: vpiecepath.cpp:287
PiecePathType GetType() const
Definition: vpiecepath.cpp:239
Qt::PenStyle GetPenType() const
Definition: vpiecepath.cpp:263
bool IsCutPath() const
Definition: vpiecepath.cpp:275
Definition: vpiece.h:88
VPieceLabelData & GetPatternPieceData()
Returns full access to the pattern piece data object.
Definition: vpiece.cpp:532
QVector< QLineF > createNotchLines(const VContainer *data, const QVector< QPointF > &seamAllowance=QVector< QPointF >()) const
Definition: vpiece.cpp:275
QVector< quint32 > GetInternalPaths() const
Definition: vpiece.cpp:426
QVector< QPointF > SeamAllowancePoints(const VContainer *data) const
Definition: vpiece.cpp:188
QVector< QPointF > MainPathPoints(const VContainer *data) const
Definition: vpiece.cpp:174
VGrainlineData & GetGrainlineGeometry()
VDetail::GetGrainlineGeometry full access to the grainline geometry object.
Definition: vpiece.cpp:578
VPatternLabelData & GetPatternInfo()
Returns full access to the pattern info geometry object.
Definition: vpiece.cpp:558
The VPointF class keep data of point.
Definition: vpointf.h:75
The VSAPoint class seam allowance point.
The VTextManager class this class is used to determine whether a collection of text lines can fit int...
Definition: vtextmanager.h:66
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)
Definition: def.cpp:231
#define SCASSERT(cond)
Definition: def.h:317
static Q_REQUIRED_RESULT bool VFuzzyComparePossibleNulls(double p1, double p2)
Definition: def.h:490
const qreal widthHairLine
Definition: global.cpp:61
Qt::PenStyle lineTypeToPenStyle(const QString &lineType)
LineStyle return pen style for current line style.
Definition: ifcdef.cpp:183
#define NULL_ID
Definition: ifcdef.h:76
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.
Definition: vtextmanager.h:51
QString m_text
Definition: vtextmanager.h:52
bool bold
Definition: vtextmanager.h:54
int m_iFontSize
Definition: vtextmanager.h:53
Qt::Alignment m_eAlign
Definition: vtextmanager.h:56
bool italic
Definition: vtextmanager.h:55
#define qApp
Definition: vapplication.h:67