1 /************************************************************************
2  **
3  **  @file   visualization.cpp
4  **  @author Roman Telezhynskyi <dismine(at)gmail.com>
5  **  @date   15 8, 2014
6  **
7  **  @brief
8  **  @copyright
9  **  This source code is part of the Valentina project, a pattern making
10  **  program, whose allow create and modeling patterns of clothing.
11  **  Copyright (C) 2013-2015 Valentina project
12  **  <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
13  **
14  **  Valentina is free software: you can redistribute it and/or modify
15  **  it under the terms of the GNU General Public License as published by
16  **  the Free Software Foundation, either version 3 of the License, or
17  **  (at your option) any later version.
18  **
19  **  Valentina is distributed in the hope that it will be useful,
20  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  **  GNU General Public License for more details.
23  **
24  **  You should have received a copy of the GNU General Public License
25  **  along with Valentina.  If not, see <http://www.gnu.org/licenses/>.
26  **
27  *************************************************************************/
28 
29 #include "visualization.h"
30 
31 #include <qnumeric.h>
32 #include <QBrush>
33 #include <QColor>
34 #include <QGraphicsEllipseItem>
35 #include <QGraphicsItem>
36 #include <QGraphicsLineItem>
37 #include <QLineF>
38 #include <QMessageLogger>
39 #include <QPen>
40 #include <QPointF>
41 #include <QRectF>
42 #include <QScopedPointer>
43 #include <QString>
44 #include <Qt>
45 #include <QtDebug>
46 
47 #include "../vpatterndb/calculator.h"
48 #include "../vpatterndb/vtranslatevars.h"
49 #include "../qmuparser/qmuparsererror.h"
50 #include "../tools/drawTools/vdrawtool.h"
51 #include "../ifc/ifcdef.h"
52 #include "../vmisc/vcommonsettings.h"
53 #include "../vpatterndb/vcontainer.h"
54 #include "../vwidgets/vmaingraphicsscene.h"
55 #include "../vwidgets/vcurvepathitem.h"
56 #include "../vwidgets/scalesceneitems.h"
57 
58 template <class K, class V> class QHash;
59 
60 Q_LOGGING_CATEGORY(vVis, "v.visualization")
61 
62 namespace
63 {
64 //---------------------------------------------------------------------------------------------------------------------
InitPointItem(const QColor & color,QGraphicsItem * parent,qreal z=0)65 VScaledEllipse *InitPointItem(const QColor &color, QGraphicsItem *parent, qreal z = 0)
66 {
67     VScaledEllipse *point = new VScaledEllipse(parent);
68     point->setZValue(1);
69     point->setBrush(QBrush(Qt::NoBrush));
70 
71     QPen visPen = point->pen();
72     visPen.setColor(color);
73 
74     point->setPen(visPen);
75     point->setRect(PointRect(ScaledRadius(SceneScale(VAbstractValApplication::VApp()->getCurrentScene()))));
76     point->setPos(QPointF());
77     point->setFlags(QGraphicsItem::ItemStacksBehindParent);
78     point->setZValue(z);
79     point->setVisible(false);
80     return point;
81 }
82 
83 //---------------------------------------------------------------------------------------------------------------------
InitCurveItem(const QColor & color,QGraphicsItem * parent,qreal z=0)84 VCurvePathItem *InitCurveItem(const QColor &color, QGraphicsItem *parent, qreal z = 0)
85 {
86     VCurvePathItem *curve = new VCurvePathItem(parent);
87     curve->setBrush(QBrush(Qt::NoBrush));
88 
89     QPen visPen = curve->pen();
90     visPen.setColor(color);
91     curve->setPen(visPen);
92 
93     curve->setFlags(QGraphicsItem::ItemStacksBehindParent);
94     curve->setZValue(z);
95     curve->setVisible(false);
96     return curve;
97 }
98 }
99 
100 //---------------------------------------------------------------------------------------------------------------------
Visualization(const VContainer * data)101 Visualization::Visualization(const VContainer *data)
102     :QObject(),
103       data(data),
104       scenePos(QPointF()),
105       mainColor(Qt::red),
106       supportColor(Qt::magenta),
107       lineStyle(Qt::SolidLine),
108       object1Id(NULL_ID),
109       toolTip(QString()),
110       mode(Mode::Creation)
111 {}
112 
113 //---------------------------------------------------------------------------------------------------------------------
setObject1Id(const quint32 & value)114 void Visualization::setObject1Id(const quint32 &value)
115 {
116     object1Id = value;
117 }
118 
119 //---------------------------------------------------------------------------------------------------------------------
setLineStyle(const Qt::PenStyle & value)120 void Visualization::setLineStyle(const Qt::PenStyle &value)
121 {
122     lineStyle = value;
123     InitPen();
124 }
125 
126 //---------------------------------------------------------------------------------------------------------------------
127 // cppcheck-suppress unusedFunction
setScenePos(const QPointF & value)128 void Visualization::setScenePos(const QPointF &value)
129 {
130     scenePos = value;
131 }
132 
133 //---------------------------------------------------------------------------------------------------------------------
VisualMode(const quint32 & pointId)134 void Visualization::VisualMode(const quint32 &pointId)
135 {
136     VMainGraphicsScene *scene = qobject_cast<VMainGraphicsScene *>(VAbstractValApplication::VApp()->getCurrentScene());
137     SCASSERT(scene != nullptr)
138 
139     this->object1Id = pointId;
140     this->scenePos = scene->getScenePos();
141     RefreshGeometry();
142 
143     AddOnScene();
144 }
145 
146 //---------------------------------------------------------------------------------------------------------------------
147 // cppcheck-suppress unusedFunction
setMainColor(const QColor & value)148 void Visualization::setMainColor(const QColor &value)
149 {
150     mainColor = value;
151     InitPen();
152 }
153 
154 //---------------------------------------------------------------------------------------------------------------------
GetData() const155 const VContainer *Visualization::GetData() const
156 {
157     return data;
158 }
159 
160 //---------------------------------------------------------------------------------------------------------------------
SetData(const VContainer * data)161 void Visualization::SetData(const VContainer *data)
162 {
163     this->data = data;
164 }
165 
166 //---------------------------------------------------------------------------------------------------------------------
MousePos(const QPointF & scenePos)167 void Visualization::MousePos(const QPointF &scenePos)
168 {
169     this->scenePos = scenePos;
170     RefreshGeometry();
171     if (toolTip.isEmpty() == false)
172     {
173         emit ToolTip(toolTip);
174     }
175 }
176 
177 //---------------------------------------------------------------------------------------------------------------------
InitPoint(const QColor & color,QGraphicsItem * parent,qreal z) const178 VScaledEllipse *Visualization::InitPoint(const QColor &color, QGraphicsItem *parent, qreal z) const
179 {
180     return InitPointItem(color, parent, z);
181 }
182 
183 //---------------------------------------------------------------------------------------------------------------------
FindLengthFromUser(const QString & expression,const QHash<QString,QSharedPointer<VInternalVariable>> * vars,bool fromUser)184 qreal Visualization::FindLengthFromUser(const QString &expression,
185                                         const QHash<QString, QSharedPointer<VInternalVariable> > *vars, bool fromUser)
186 {
187     return VAbstractValApplication::VApp()->toPixel(FindValFromUser(expression, vars, fromUser));
188 }
189 
190 //---------------------------------------------------------------------------------------------------------------------
FindValFromUser(const QString & expression,const QHash<QString,QSharedPointer<VInternalVariable>> * vars,bool fromUser)191 qreal Visualization::FindValFromUser(const QString &expression,
192                                      const QHash<QString, QSharedPointer<VInternalVariable> > *vars, bool fromUser)
193 {
194     qreal val = 0;
195     if (expression.isEmpty())
196     {
197         val = 0;
198     }
199     else
200     {
201         try
202         {
203             // Replace line return with spaces for calc if exist
204             QString formula = expression;
205             if (fromUser)
206             {
207                 formula = VAbstractApplication::VApp()->TrVars()
208                         ->FormulaFromUser(formula, VAbstractApplication::VApp()->Settings()->GetOsSeparator());
209             }
210 
211             QScopedPointer<Calculator> cal(new Calculator());
212             val = cal->EvalFormula(vars, formula);
213 
214             if (qIsInf(val) || qIsNaN(val))
215             {
216                 val = 0;
217             }
218         }
219         catch (qmu::QmuParserError &e)
220         {
221             val = 0;
222             qDebug() << "\nMath parser error:\n"
223                      << "--------------------------------------\n"
224                      << "Message:     " << e.GetMsg()  << "\n"
225                      << "Expression:  " << e.GetExpr() << "\n"
226                      << "--------------------------------------";
227         }
228     }
229     return val;
230 }
231 
232 //---------------------------------------------------------------------------------------------------------------------
DrawPoint(QGraphicsEllipseItem * point,const QPointF & pos,const QColor & color,Qt::PenStyle style)233 void Visualization::DrawPoint(QGraphicsEllipseItem *point, const QPointF &pos, const QColor &color, Qt::PenStyle style)
234 {
235     SCASSERT (point != nullptr)
236 
237     point->setPos(pos);
238 
239     QPen visPen = point->pen();
240     visPen.setColor(color);
241     visPen.setStyle(style);
242 
243     point->setPen(visPen);
244     point->setVisible(true);
245 }
246 
247 //---------------------------------------------------------------------------------------------------------------------
DrawLine(VScaledLine * lineItem,const QLineF & line,const QColor & color,Qt::PenStyle style)248 void Visualization::DrawLine(VScaledLine *lineItem, const QLineF &line, const QColor &color, Qt::PenStyle style)
249 {
250     SCASSERT (lineItem != nullptr)
251 
252     QPen visPen = lineItem->pen();
253     visPen.setColor(color);
254     visPen.setStyle(style);
255 
256     lineItem->setPen(visPen);
257     if (not line.isNull())
258     {
259         lineItem->setLine(line);
260     }
261 
262     lineItem->setVisible(not line.isNull());
263 }
264 
265 //---------------------------------------------------------------------------------------------------------------------
DrawPath(VCurvePathItem * pathItem,const QPainterPath & path,const QColor & color,Qt::PenStyle style,Qt::PenCapStyle cap)266 void Visualization::DrawPath(VCurvePathItem *pathItem, const QPainterPath &path, const QColor &color,
267                              Qt::PenStyle style, Qt::PenCapStyle cap)
268 {
269     DrawPath(pathItem, path, QVector<DirectionArrow>(), color, style, cap);
270 }
271 
272 //---------------------------------------------------------------------------------------------------------------------
DrawPath(VCurvePathItem * pathItem,const QPainterPath & path,const QVector<DirectionArrow> & directionArrows,const QColor & color,Qt::PenStyle style,Qt::PenCapStyle cap)273 void Visualization::DrawPath(VCurvePathItem *pathItem, const QPainterPath &path,
274                              const QVector<DirectionArrow> &directionArrows, const QColor &color, Qt::PenStyle style,
275                              Qt::PenCapStyle cap)
276 {
277     SCASSERT (pathItem != nullptr)
278 
279     QPen visPen = pathItem->pen();
280     visPen.setColor(color);
281     visPen.setStyle(style);
282     visPen.setCapStyle(cap);
283 
284     pathItem->setPen(visPen);
285     pathItem->setPath(path);
286     pathItem->SetDirectionArrows(directionArrows);
287     pathItem->setVisible(true);
288 }
289 
290 //---------------------------------------------------------------------------------------------------------------------
GetPointItem(QVector<VScaledEllipse * > & points,quint32 i,const QColor & color,QGraphicsItem * parent)291 VScaledEllipse *Visualization::GetPointItem(QVector<VScaledEllipse *> &points, quint32 i,
292                                             const QColor &color, QGraphicsItem *parent)
293 {
294     if (not points.isEmpty() && static_cast<quint32>(points.size() - 1) >= i)
295     {
296         return points.at(static_cast<int>(i));
297     }
298     else
299     {
300         auto point = InitPointItem(color, parent);
301         points.append(point);
302         return point;
303     }
304 }
305 
306 //---------------------------------------------------------------------------------------------------------------------
GetCurveItem(QVector<VCurvePathItem * > & curves,quint32 i,const QColor & color,QGraphicsItem * parent)307 VCurvePathItem *Visualization::GetCurveItem(QVector<VCurvePathItem *> &curves, quint32 i, const QColor &color,
308                                             QGraphicsItem *parent)
309 {
310     if (not curves.isEmpty() && static_cast<quint32>(curves.size() - 1) >= i)
311     {
312         return curves.at(static_cast<int>(i));
313     }
314     else
315     {
316         auto point = InitCurveItem(color, parent);
317         curves.append(point);
318         return point;
319     }
320 }
321 
322 //---------------------------------------------------------------------------------------------------------------------
GetMode() const323 Mode Visualization::GetMode() const
324 {
325     return mode;
326 }
327 
328 //---------------------------------------------------------------------------------------------------------------------
SetMode(const Mode & value)329 void Visualization::SetMode(const Mode &value)
330 {
331     mode = value;
332 }
333