Seamly2D
Code documentation
vistoolmove.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2017 Seamly, LLC *
4  * *
5  * https://github.com/fashionfreedom/seamly2d *
6  * *
7  ***************************************************************************
8  **
9  ** Seamly2D is free software: you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation, either version 3 of the License, or
12  ** (at your option) any later version.
13  **
14  ** Seamly2D is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** You should have received a copy of the GNU General Public License
20  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
21  **
22  **************************************************************************
23 
24  ************************************************************************
25  **
26  ** @file
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date 1 10, 2016
29  **
30  ** @brief
31  ** @copyright
32  ** This source code is part of the Valentine project, a pattern making
33  ** program, whose allow create and modeling patterns of clothing.
34  ** Copyright (C) 2016 Seamly2D project
35  ** <https://github.com/fashionfreedom/seamly2d> All Rights Reserved.
36  **
37  ** Seamly2D is free software: you can redistribute it and/or modify
38  ** it under the terms of the GNU General Public License as published by
39  ** the Free Software Foundation, either version 3 of the License, or
40  ** (at your option) any later version.
41  **
42  ** Seamly2D is distributed in the hope that it will be useful,
43  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
44  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45  ** GNU General Public License for more details.
46  **
47  ** You should have received a copy of the GNU General Public License
48  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
49  **
50  *************************************************************************/
51 
52 #include "vistoolmove.h"
53 
54 #include <limits.h>
55 #include <QGraphicsLineItem>
56 #include <QGraphicsPathItem>
57 #include <QGuiApplication>
58 #include <QLineF>
59 #include <QPainterPath>
60 #include <QSharedPointer>
61 #include <Qt>
62 #include <QtAlgorithms>
63 #include <QPointF>
64 #include <new>
65 
66 #include "../ifc/xml/vdomdocument.h"
67 #include "../vmisc/diagnostic.h"
68 #include "../vgeometry/vabstractcurve.h"
69 #include "../vgeometry/varc.h"
70 #include "../vgeometry/vcubicbezier.h"
71 #include "../vgeometry/vcubicbezierpath.h"
72 #include "../vgeometry/vellipticalarc.h"
73 #include "../vgeometry/vgeometrydef.h"
74 #include "../vgeometry/vgobject.h"
75 #include "../vgeometry/vpointf.h"
76 #include "../vgeometry/vspline.h"
77 #include "../vgeometry/vsplinepath.h"
78 #include "../vgeometry/varc.h"
79 #include "../vmisc/vabstractapplication.h"
80 #include "../vpatterndb/vcontainer.h"
81 #include "../vwidgets/vmaingraphicsscene.h"
82 #include "visoperation.h"
83 #include "../vmisc/logging.h"
84 
85 Q_LOGGING_CATEGORY(visTool, "vistool")
86 
87 //---------------------------------------------------------------------------------------------------------------------
88 VisToolMove::VisToolMove(const VContainer *data, QGraphicsItem *parent)
89  : VisOperation(data, parent)
90  , angle(0)
91  , length(0)
92  , rotationAngle(INT_MIN)
93  , originPointItem(nullptr)
94  , rotationOriginPointItem(nullptr)
95  , rotationFinishPointItem(nullptr)
96  , moveLineItem(nullptr)
97  , rotationLineItem(nullptr)
98  , m_origin(QPointF())
99  , m_rotationPoint(QPointF())
100 {
101  originPointItem = InitPoint(supportColor2, this, 110);
102  originPointItem->setBrush(QBrush(supportColor2, Qt::SolidPattern));
103 
104  rotationOriginPointItem = InitPoint(supportColor2, this, 120);
105  rotationOriginPointItem->setBrush(QBrush(supportColor2, Qt::SolidPattern));
106 
107  rotationFinishPointItem = InitPoint(supportColor3, this, 130);
108  rotationFinishPointItem->setBrush(QBrush(supportColor3, Qt::SolidPattern));
109 
110  moveLineItem = InitItem<ArrowedLineItem>(supportColor2, this);
111  rotationLineItem = InitItem<VScaledLine>(supportColor3, this);
112 }
113 
114 //---------------------------------------------------------------------------------------------------------------------
116 {
117 }
118 
119 //---------------------------------------------------------------------------------------------------------------------
121 {
122  if (objects.isEmpty())
123  {
124  return;
125  }
126 
127  int iPoint = -1;
128  int iCurve = -1;
129 
130  createOriginObjects(iPoint, iCurve);
131 
132  qreal tempAngle = 0;
133  qreal tempLength = 0;
134  qreal tempRotation = 0;
135 
136  QLineF line;
137  if (qFuzzyIsNull(length))
138  {
139  if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier)
140  {
141  line = QLineF(m_origin, Visualization::scenePos);
142  line.setAngle(CorrectAngle(line.angle())); //contrain move line angle to preference setting
143  }
144  else
145  {
146  line = QLineF(m_origin, Visualization::scenePos);
147  }
148 
149  tempAngle = line.angle();
150  tempLength = line.length();
151  }
152  else
153  {
154  tempAngle = angle;
155  tempLength = length;
156 
157  if (object1Id != NULL_ID)
158  {
162  m_rotationPoint = line.p2();
163  originPointItem->setVisible(false);
164  }
165  else
166  {
169  m_rotationPoint = line.p2();
170  rotationOriginPointItem->setVisible(false);
171  }
172 
173  QLineF rotationLine;
175  {
176  rotationLine = QLineF(m_rotationPoint, Visualization::scenePos);
177 
178  if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier)
179  {
180  rotationLine.setAngle(CorrectAngle(rotationLine.angle())); //contrain rotation line angle to preference
181  }
182 
183  qreal cursorLength = rotationLine.length();
184  rotationLine.setP2(Ray(m_rotationPoint, rotationLine.angle()));
185 
186  qreal minL = scaledRadius(sceneScale(qApp->getCurrentScene())) * 1.5;
187 
188  if (cursorLength > minL)
189  {
190  tempRotation = rotationLine.angle();
191  }
192  else
193  {
194  rotationLine.setAngle(0);
195  }
196  }
197  else
198  {
199  rotationLine = QLineF(m_rotationPoint, Ray(m_rotationPoint, rotationAngle));
200  tempRotation = rotationAngle;
201  }
202 
203  DrawLine(rotationLineItem, rotationLine, supportColor3, lineWeight, Qt::DashLine);
204  }
205 
206  drawArrowedLine(moveLineItem, line, supportColor2, Qt::DashLine);
208 
209  static const QString prefix = UnitsToStr(qApp->patternUnit(), true);
210  if (qFuzzyIsNull(length))
211  {
212  Visualization::toolTip = tr("Length = %1%2, angle = %3°, <b>Shift</b> to constrain angle, "
213  "<b>Mouse click</b> - finish selecting a position")
214  .arg(qApp->TrVars()->FormulaToUser(QString::number(qApp->fromPixel(tempLength)),
215  qApp->Settings()->GetOsSeparator()))
216  .arg(prefix)
217  .arg(tempAngle);
218  }
219  else
220  {
221  Visualization::toolTip = tr("Length = %1%2, angle = %3°, rotation angle = %4° Hold <b>SHIFT</b> to constrain angle,"
222  "<b>CTRL</b> - change rotation origin point, <b>Mouse click</b> - finish creating")
223  .arg(qApp->TrVars()->FormulaToUser(QString::number(qApp->fromPixel(tempLength)),
224  qApp->Settings()->GetOsSeparator()))
225  .arg(prefix)
226  .arg(tempAngle)
227  .arg(tempRotation);
228  }
229  createRotatedObjects(iPoint, iCurve, tempLength, tempAngle, tempRotation, m_rotationPoint);
230 }
231 
232 //---------------------------------------------------------------------------------------------------------------------
233 QString VisToolMove::Angle() const
234 {
235  return QString::number(moveLineItem->line().angle());
236 }
237 
238 //---------------------------------------------------------------------------------------------------------------------
239 void VisToolMove::SetAngle(const QString &expression)
240 {
241  angle = FindVal(expression, Visualization::data->DataVariables());
242 }
243 
244 //---------------------------------------------------------------------------------------------------------------------
245 QString VisToolMove::Rotation() const
246 {
247  return QString::number(rotationLineItem->line().angle());
248 }
249 
250 //---------------------------------------------------------------------------------------------------------------------
251 void VisToolMove::setRotation(const QString &expression)
252 {
253  rotationAngle = FindVal(expression, Visualization::data->DataVariables());
254 }
255 
256 //---------------------------------------------------------------------------------------------------------------------
257 QString VisToolMove::Length() const
258 {
259  return QString::number(LengthValue());
260 }
261 
262 //---------------------------------------------------------------------------------------------------------------------
264 {
265  //return qApp->fromPixel(line().length());
266  return qApp->fromPixel(moveLineItem->line().length());
267 }
268 
269 //---------------------------------------------------------------------------------------------------------------------
270 void VisToolMove::SetLength(const QString &expression)
271 {
272  length = FindLength(expression, Visualization::data->DataVariables());
273 }
274 
275 //---------------------------------------------------------------------------------------------------------------------
276 void VisToolMove::setOriginPointId(quint32 value)
277 {
278  object1Id = value;
279 }
280 
281 //---------------------------------------------------------------------------------------------------------------------
282 template <class Item>
283 QGraphicsPathItem *VisToolMove::AddOriginCurve(quint32 id, int &i)
284 {
285  const QSharedPointer<Item> curve = Visualization::data->template GeometricObject<Item>(id);
286 
287  ++i;
288  VCurvePathItem *path = GetCurve(static_cast<quint32>(i), supportColor2);
289  DrawPath(path, curve->GetPath(), curve->DirectionArrows(), supportColor2, Qt::SolidLine,
290  lineWeight, Qt::RoundCap);
291 
292  return path;
293 }
294 
295 //---------------------------------------------------------------------------------------------------------------------
296 template <class Item>
297 int VisToolMove::AddDestinationCurve(qreal angle, qreal length, quint32 id, int i, qreal rotationAngle,
298  const QPointF &rotationOrigin)
299 {
300  const QSharedPointer<Item> curve = Visualization::data->template GeometricObject<Item>(id);
301 
302  ++i;
303  VCurvePathItem *path = GetCurve(static_cast<quint32>(i), supportColor);
304  const Item moved = curve->Move(length, angle).Rotate(rotationOrigin, rotationAngle);
305  DrawPath(path, moved.GetPath(), moved.DirectionArrows(), supportColor, Qt::SolidLine,
306  lineWeight, Qt::RoundCap);
307 
308  return i;
309 }
310 
311 //---------------------------------------------------------------------------------------------------------------------
312 QT_WARNING_PUSH
313 QT_WARNING_DISABLE_GCC("-Wswitch-default")
314 
315 void VisToolMove::createOriginObjects(int &iPoint, int &iCurve)
316 {
317  QPolygonF sourceObjects;
318 
319  for (int i = 0; i < objects.size(); ++i)
320  {
321  const quint32 id = objects.at(i);
323 
324  // This check helps to find missed objects in the switch
325  Q_STATIC_ASSERT_X(static_cast<int>(GOType::Unknown) == 7, "Not all objects were handled.");
326 
327  switch(static_cast<GOType>(obj->getType()))
328  {
329  case GOType::Point:
330  {
332 
333  ++iPoint;
334  VScaledEllipse *point = GetPoint(static_cast<quint32>(iPoint), supportColor2);
335  DrawPoint(point, static_cast<QPointF>(*p), supportColor2);
336  sourceObjects.append(p->toQPointF());
337  break;
338  }
339  case GOType::Arc:
340  AddOriginCurve<VArc>(id, iCurve);
341  sourceObjects.append(Visualization::data->GeometricObject<VAbstractCurve>(id)->getPoints());
342  break;
344  AddOriginCurve<VEllipticalArc>(id, iCurve);
345  sourceObjects.append(Visualization::data->GeometricObject<VAbstractCurve>(id)->getPoints());
346  break;
347  case GOType::Spline:
348  AddOriginCurve<VSpline>(id, iCurve);
349  sourceObjects.append(Visualization::data->GeometricObject<VAbstractCurve>(id)->getPoints());
350  break;
351  case GOType::SplinePath:
352  AddOriginCurve<VSplinePath>(id, iCurve);
353  sourceObjects.append(Visualization::data->GeometricObject<VAbstractCurve>(id)->getPoints());
354  break;
355  case GOType::CubicBezier:
356  AddOriginCurve<VCubicBezier>(id, iCurve);
357  sourceObjects.append(Visualization::data->GeometricObject<VAbstractCurve>(id)->getPoints());
358  break;
360  AddOriginCurve<VCubicBezierPath>(id, iCurve);
361  sourceObjects.append(Visualization::data->GeometricObject<VAbstractCurve>(id)->getPoints());
362  break;
363  case GOType::Unknown:
364  case GOType::Curve:
365  case GOType::Path:
366  case GOType::AllCurves:
367  default:
368  break;
369  }
370  }
371 
372  m_origin = sourceObjects.boundingRect().center();
373 }
374 
376 
377 //---------------------------------------------------------------------------------------------------------------------
378 QT_WARNING_PUSH
379 QT_WARNING_DISABLE_GCC("-Wswitch-default")
380 
381 void VisToolMove::createRotatedObjects(int &iPoint, int &iCurve, qreal length, qreal angle, qreal rotationAngle,
382  const QPointF &rotationOrigin)
383 {
384  for (int i = 0; i < objects.size(); ++i)
385  {
386  const quint32 id = objects.at(i);
388 
389  // This check helps to find missed objects in the switch
390  Q_STATIC_ASSERT_X(static_cast<int>(GOType::Unknown) == 7, "Not all objects was handled.");
391 
392  switch(static_cast<GOType>(obj->getType()))
393  {
394  case GOType::Point:
395  {
397 
398  ++iPoint;
399  VScaledEllipse *point = GetPoint(static_cast<quint32>(iPoint), supportColor);
400  DrawPoint(point, static_cast<QPointF>(p->Move(length, angle).Rotate(rotationOrigin, rotationAngle)),
401  supportColor);
402  break;
403  }
404  case GOType::Arc:
405  iCurve = AddDestinationCurve<VArc>(angle, length, id, iCurve, rotationAngle, rotationOrigin);
406  break;
408  iCurve = AddDestinationCurve<VEllipticalArc>(angle, length, id, iCurve, rotationAngle, rotationOrigin);
409  break;
410  case GOType::Spline:
411  iCurve = AddDestinationCurve<VSpline>(angle, length, id, iCurve, rotationAngle, rotationOrigin);
412  break;
413  case GOType::SplinePath:
414  iCurve = AddDestinationCurve<VSplinePath>(angle, length, id, iCurve, rotationAngle, rotationOrigin);
415  break;
416  case GOType::CubicBezier:
417  iCurve = AddDestinationCurve<VCubicBezier>(angle, length, id, iCurve, rotationAngle, rotationOrigin);
418  break;
420  iCurve = AddDestinationCurve<VCubicBezierPath>(angle, length, id, iCurve, rotationAngle, rotationOrigin);
421  break;
422  case GOType::Unknown:
423  case GOType::Curve:
424  case GOType::Path:
425  case GOType::AllCurves:
426  break;
427  }
428  }
429 }
430 
The VContainer class container of all variables.
Definition: vcontainer.h:141
const QSharedPointer< VGObject > GetGObject(quint32 id) const
GetGObject returns a point by id.
Definition: vcontainer.cpp:150
const QSharedPointer< T > GeometricObject(const quint32 &id) const
Definition: vcontainer.h:266
static QLineF BuildLine(const QPointF &p1, const qreal &length, const qreal &angle)
Definition: vgobject.cpp:241
The VPointF class keep data of point.
Definition: vpointf.h:75
static qreal CorrectAngle(const qreal &angle)
Definition: visline.cpp:54
QPointF Ray(const QPointF &firstPoint, const qreal &angle) const
Definition: visline.cpp:85
VCurvePathItem * GetCurve(quint32 i, const QColor &color)
QColor supportColor3
Definition: visoperation.h:76
QVector< quint32 > objects
Definition: visoperation.h:74
QColor supportColor2
Definition: visoperation.h:75
virtual void RefreshGeometry() Q_DECL_OVERRIDE
QString Length() const
VScaledEllipse * rotationOriginPointItem
Definition: vistoolmove.h:99
QPointF m_rotationPoint
Definition: vistoolmove.h:104
virtual ~VisToolMove()
QGraphicsPathItem * AddOriginCurve(quint32 id, int &i)
void createRotatedObjects(int &iPoint, int &iCurve, qreal length, qreal angle, qreal rotationAngle, const QPointF &rotationOrigin)
VScaledEllipse * originPointItem
Definition: vistoolmove.h:98
VScaledLine * rotationLineItem
Definition: vistoolmove.h:102
ArrowedLineItem * moveLineItem
Definition: vistoolmove.h:101
QString Angle() const
int AddDestinationCurve(qreal angle, qreal length, quint32 id, int i, qreal rotationAngle, const QPointF &rotationOrigin)
qreal angle
Definition: vistoolmove.h:95
void SetAngle(const QString &expression)
qreal rotationAngle
Definition: vistoolmove.h:97
QPointF m_origin
Definition: vistoolmove.h:103
void setOriginPointId(quint32 value)
void setRotation(const QString &expression)
void createOriginObjects(int &iPoint, int &iCurve)
QString Rotation() const
VScaledEllipse * rotationFinishPointItem
Definition: vistoolmove.h:100
qreal LengthValue() const
qreal length
Definition: vistoolmove.h:96
void SetLength(const QString &expression)
QColor supportColor
void DrawPoint(QGraphicsEllipseItem *point, const QPointF &pos, const QColor &color, Qt::PenStyle style=Qt::SolidLine)
static qreal FindLength(const QString &expression, const QHash< QString, QSharedPointer< VInternalVariable > > *vars)
const VContainer * data
Definition: visualization.h:97
void DrawPath(VCurvePathItem *pathItem, const QPainterPath &path, const QColor &color, Qt::PenStyle style=Qt::SolidLine, const qreal &weight=0.35, Qt::PenCapStyle cap=Qt::SquareCap)
QPointF scenePos
Definition: visualization.h:98
void drawArrowedLine(ArrowedLineItem *item, const QLineF &line, const QColor &color, Qt::PenStyle style=Qt::SolidLine)
virtual void DrawLine(VScaledLine *lineItem, const QLineF &line, const QColor &color, const qreal &lineWeight, Qt::PenStyle style=Qt::SolidLine)
quint32 object1Id
static qreal FindVal(const QString &expression, const QHash< QString, QSharedPointer< VInternalVariable > > *vars)
QString UnitsToStr(const Unit &unit, const bool translate)
UnitsToStr translate unit to string.
Definition: def.cpp:702
static Q_REQUIRED_RESULT bool VFuzzyComparePossibleNulls(double p1, double p2)
Definition: def.h:490
qreal sceneScale(QGraphicsScene *scene)
Definition: global.cpp:63
qreal scaledRadius(qreal scale)
Definition: global.cpp:103
#define NULL_ID
Definition: ifcdef.h:76
#define qApp
Definition: vapplication.h:67
GOType
Definition: vgeometrydef.h:56
@ CubicBezierPath
@ SplinePath
@ EllipticalArc
@ CubicBezier