1 /************************************************************************
2 **
3 ** @file
4 ** @author Roman Telezhynskyi <dismine(at)gmail.com>
5 ** @date 3 11, 2016
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) 2016 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 "vpiecenode.h"
30 #include "vpiecenode_p.h"
31 #include "vcontainer.h"
32 #include "calculator.h"
33 #include "vformula.h"
34 #include "../vmisc/vabstractvalapplication.h"
35
36 #include <QDataStream>
37 #include <QtNumeric>
38
39 const quint32 VPieceNodeData::streamHeader = 0x2198CBC8; // CRC-32Q string "VPieceNodeData"
40 const quint16 VPieceNodeData::classVersion = 1;
41
42 //---------------------------------------------------------------------------------------------------------------------
VPieceNode()43 VPieceNode::VPieceNode()
44 : d(new VPieceNodeData)
45 {}
46
47 //---------------------------------------------------------------------------------------------------------------------
VPieceNode(quint32 id,Tool typeTool,bool reverse)48 VPieceNode::VPieceNode(quint32 id, Tool typeTool, bool reverse)
49 : d(new VPieceNodeData(id, typeTool, reverse))
50 {}
51
52 //---------------------------------------------------------------------------------------------------------------------
VPieceNode(const VPieceNode & node)53 VPieceNode::VPieceNode(const VPieceNode &node)
54 : d (node.d)
55 {}
56
57 //---------------------------------------------------------------------------------------------------------------------
operator =(const VPieceNode & node)58 VPieceNode &VPieceNode::operator=(const VPieceNode &node)
59 {
60 if ( &node == this )
61 {
62 return *this;
63 }
64 d = node.d;
65 return *this;
66 }
67
68 #ifdef Q_COMPILER_RVALUE_REFS
69 //---------------------------------------------------------------------------------------------------------------------
VPieceNode(const VPieceNode && node)70 VPieceNode::VPieceNode(const VPieceNode &&node) Q_DECL_NOTHROW
71 : d (node.d)
72 {}
73
74 //---------------------------------------------------------------------------------------------------------------------
operator =(VPieceNode && node)75 VPieceNode &VPieceNode::operator=(VPieceNode &&node) Q_DECL_NOTHROW
76 {
77 std::swap(d, node.d);
78 return *this;
79 }
80 #endif
81
82 //---------------------------------------------------------------------------------------------------------------------
~VPieceNode()83 VPieceNode::~VPieceNode()
84 {}
85
86 // Friend functions
87 //---------------------------------------------------------------------------------------------------------------------
operator <<(QDataStream & out,const VPieceNode & p)88 QDataStream &operator<<(QDataStream &out, const VPieceNode &p)
89 {
90 out << *p.d;
91 return out;
92 }
93
94 //---------------------------------------------------------------------------------------------------------------------
operator >>(QDataStream & in,VPieceNode & p)95 QDataStream &operator>>(QDataStream &in, VPieceNode &p)
96 {
97 in >> *p.d;
98 return in;
99 }
100
101 //---------------------------------------------------------------------------------------------------------------------
GetId() const102 quint32 VPieceNode::GetId() const
103 {
104 return d->m_id;
105 }
106
107 //---------------------------------------------------------------------------------------------------------------------
SetId(quint32 id)108 void VPieceNode::SetId(quint32 id)
109 {
110 d->m_id = id;
111 }
112
113 //---------------------------------------------------------------------------------------------------------------------
GetTypeTool() const114 Tool VPieceNode::GetTypeTool() const
115 {
116 return d->m_typeTool;
117 }
118
119 //---------------------------------------------------------------------------------------------------------------------
SetTypeTool(Tool value)120 void VPieceNode::SetTypeTool(Tool value)
121 {
122 d->m_typeTool = value;
123 }
124
125 //---------------------------------------------------------------------------------------------------------------------
GetReverse() const126 bool VPieceNode::GetReverse() const
127 {
128 return d->m_reverse;
129 }
130
131 //---------------------------------------------------------------------------------------------------------------------
SetReverse(bool reverse)132 void VPieceNode::SetReverse(bool reverse)
133 {
134 if (d->m_typeTool != Tool::NodePoint)
135 {
136 d->m_reverse = reverse;
137 }
138 }
139
140 //---------------------------------------------------------------------------------------------------------------------
GetSABefore(const VContainer * data) const141 qreal VPieceNode::GetSABefore(const VContainer *data) const
142 {
143 if (d->m_formulaWidthBefore == currentSeamAllowance)
144 {
145 return -1;
146 }
147
148 VFormula formula(d->m_formulaWidthBefore, data);
149 formula.setCheckZero(false);
150 formula.Eval();
151
152 if (formula.error())
153 {
154 QString nodeName;
155 try
156 {
157 nodeName = data->GetGObject(d->m_id)->name();
158 }
159 catch (const VExceptionBadId &)
160 {}
161
162 const QString errorMsg = QObject::tr("Cannot calculate seam allowance before for point '%1'. Reason: %2.")
163 .arg(nodeName, formula.Reason());
164 VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
165 qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
166 return -1;
167 }
168 return formula.getDoubleValue();
169 }
170
171 //---------------------------------------------------------------------------------------------------------------------
GetSABefore(const VContainer * data,Unit unit) const172 qreal VPieceNode::GetSABefore(const VContainer *data, Unit unit) const
173 {
174 if (d->m_formulaWidthBefore == currentSeamAllowance)
175 {
176 return -1;
177 }
178
179 VFormula formula(d->m_formulaWidthBefore, data);
180 formula.setCheckZero(false);
181 formula.Eval();
182
183 if (formula.error())
184 {
185 QString nodeName;
186 try
187 {
188 nodeName = data->GetGObject(d->m_id)->name();
189 }
190 catch (const VExceptionBadId &)
191 {}
192
193 const QString errorMsg = QObject::tr("Cannot calculate seam allowance before for point '%1'. Reason: %2.")
194 .arg(nodeName, formula.Reason());
195 VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
196 qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
197 return -1;
198 }
199
200 qreal value = formula.getDoubleValue();
201 if (value >= 0)
202 {
203 value = ToPixel(value, unit);
204 }
205 return value;
206 }
207
208 //---------------------------------------------------------------------------------------------------------------------
GetFormulaSABefore() const209 QString VPieceNode::GetFormulaSABefore() const
210 {
211 return d->m_formulaWidthBefore;
212 }
213
214 //---------------------------------------------------------------------------------------------------------------------
SetFormulaSABefore(const QString & formula)215 void VPieceNode::SetFormulaSABefore(const QString &formula)
216 {
217 if (d->m_typeTool == Tool::NodePoint)
218 {
219 d->m_formulaWidthBefore = formula;
220 }
221 }
222
223 //---------------------------------------------------------------------------------------------------------------------
GetSAAfter(const VContainer * data) const224 qreal VPieceNode::GetSAAfter(const VContainer *data) const
225 {
226 if (d->m_formulaWidthAfter == currentSeamAllowance)
227 {
228 return -1;
229 }
230
231 VFormula formula(d->m_formulaWidthAfter, data);
232 formula.setCheckZero(false);
233 formula.Eval();
234
235 if (formula.error())
236 {
237 QString nodeName;
238 try
239 {
240 nodeName = data->GetGObject(d->m_id)->name();
241 }
242 catch (const VExceptionBadId &)
243 {}
244
245 const QString errorMsg = QObject::tr("Cannot calculate seam allowance after for point '%1'. Reason: %2.")
246 .arg(nodeName, formula.Reason());
247 VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
248 qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
249 return -1;
250 }
251
252 return formula.getDoubleValue();
253 }
254
255 //---------------------------------------------------------------------------------------------------------------------
GetSAAfter(const VContainer * data,Unit unit) const256 qreal VPieceNode::GetSAAfter(const VContainer *data, Unit unit) const
257 {
258 if (d->m_formulaWidthAfter == currentSeamAllowance)
259 {
260 return -1;
261 }
262
263 VFormula formula(d->m_formulaWidthAfter, data);
264 formula.setCheckZero(false);
265 formula.Eval();
266
267 if (formula.error())
268 {
269 QString nodeName;
270 try
271 {
272 nodeName = data->GetGObject(d->m_id)->name();
273 }
274 catch (const VExceptionBadId &)
275 {}
276
277 const QString errorMsg = QObject::tr("Cannot calculate seam allowance after for point '%1'. Reason: ")
278 .arg(nodeName, formula.Reason());
279 VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
280 qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
281 return -1;
282 }
283
284 qreal value = formula.getDoubleValue();
285
286 if (value >= 0)
287 {
288 value = ToPixel(value, unit);
289 }
290 return value;
291 }
292
293 //---------------------------------------------------------------------------------------------------------------------
GetFormulaSAAfter() const294 QString VPieceNode::GetFormulaSAAfter() const
295 {
296 return d->m_formulaWidthAfter;
297 }
298
299 //---------------------------------------------------------------------------------------------------------------------
SetFormulaSAAfter(const QString & formula)300 void VPieceNode::SetFormulaSAAfter(const QString &formula)
301 {
302 if (d->m_typeTool == Tool::NodePoint)
303 {
304 d->m_formulaWidthAfter = formula;
305 }
306 }
307
308 //---------------------------------------------------------------------------------------------------------------------
GetFormulaPassmarkLength() const309 QString VPieceNode::GetFormulaPassmarkLength() const
310 {
311 return d->m_formulaPassmarkLength;
312 }
313
314 //---------------------------------------------------------------------------------------------------------------------
SetFormulaPassmarkLength(const QString & formula)315 void VPieceNode::SetFormulaPassmarkLength(const QString &formula)
316 {
317 if (d->m_typeTool == Tool::NodePoint)
318 {
319 d->m_formulaPassmarkLength = formula;
320 }
321 }
322
323 //---------------------------------------------------------------------------------------------------------------------
GetPassmarkLength(const VContainer * data,Unit unit) const324 qreal VPieceNode::GetPassmarkLength(const VContainer *data, Unit unit) const
325 {
326 if (d->m_manualPassmarkLength)
327 {
328 VFormula formula(d->m_formulaPassmarkLength, data);
329 formula.setCheckZero(false);
330 formula.setCheckLessThanZero(false);
331 formula.Eval();
332
333 if (formula.error())
334 {
335 QString nodeName;
336 try
337 {
338 nodeName = data->GetGObject(d->m_id)->name();
339 }
340 catch (const VExceptionBadId &)
341 {}
342
343 const QString errorMsg = QObject::tr("Cannot calculate passmark length for point '%1'. Reason: %2.")
344 .arg(nodeName, formula.Reason());
345 VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
346 qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
347 return VSAPoint::maxPassmarkLength;
348 }
349
350 return ToPixel(formula.getDoubleValue(), unit);
351 }
352 return -1;
353 }
354
355 //---------------------------------------------------------------------------------------------------------------------
GetAngleType() const356 PieceNodeAngle VPieceNode::GetAngleType() const
357 {
358 return d->m_angleType;
359 }
360
361 //---------------------------------------------------------------------------------------------------------------------
SetAngleType(PieceNodeAngle type)362 void VPieceNode::SetAngleType(PieceNodeAngle type)
363 {
364 if (d->m_typeTool == Tool::NodePoint)
365 {
366 d->m_angleType = type;
367 }
368 }
369
370 //---------------------------------------------------------------------------------------------------------------------
IsPassmark() const371 bool VPieceNode::IsPassmark() const
372 {
373 return d->m_isPassmark;
374 }
375
376 //---------------------------------------------------------------------------------------------------------------------
SetPassmark(bool passmark)377 void VPieceNode::SetPassmark(bool passmark)
378 {
379 if (GetTypeTool() == Tool::NodePoint)
380 {
381 d->m_isPassmark = passmark;
382 }
383 }
384
385 //---------------------------------------------------------------------------------------------------------------------
IsMainPathNode() const386 bool VPieceNode::IsMainPathNode() const
387 {
388 return d->m_isMainPathNode;
389 }
390
391 //---------------------------------------------------------------------------------------------------------------------
SetMainPathNode(bool value)392 void VPieceNode::SetMainPathNode(bool value)
393 {
394 d->m_isMainPathNode = value;
395 }
396
397 //---------------------------------------------------------------------------------------------------------------------
GetPassmarkLineType() const398 PassmarkLineType VPieceNode::GetPassmarkLineType() const
399 {
400 return d->m_passmarkLineType;
401 }
402
403 //---------------------------------------------------------------------------------------------------------------------
SetPassmarkLineType(PassmarkLineType lineType)404 void VPieceNode::SetPassmarkLineType(PassmarkLineType lineType)
405 {
406 d->m_passmarkLineType = lineType;
407 }
408
409 //---------------------------------------------------------------------------------------------------------------------
GetPassmarkAngleType() const410 PassmarkAngleType VPieceNode::GetPassmarkAngleType() const
411 {
412 return d->m_passmarkAngleType;
413 }
414
415 //---------------------------------------------------------------------------------------------------------------------
SetPassmarkAngleType(PassmarkAngleType angleType)416 void VPieceNode::SetPassmarkAngleType(PassmarkAngleType angleType)
417 {
418 d->m_passmarkAngleType = angleType;
419 }
420
421 //---------------------------------------------------------------------------------------------------------------------
IsShowSecondPassmark() const422 bool VPieceNode::IsShowSecondPassmark() const
423 {
424 return d->m_isShowSecondPassmark;
425 }
426
427 //---------------------------------------------------------------------------------------------------------------------
SetShowSecondPassmark(bool value)428 void VPieceNode::SetShowSecondPassmark(bool value)
429 {
430 d->m_isShowSecondPassmark = value;
431 }
432
433 //---------------------------------------------------------------------------------------------------------------------
IsCheckUniqueness() const434 bool VPieceNode::IsCheckUniqueness() const
435 {
436 return d->m_checkUniqueness;
437 }
438
439 //---------------------------------------------------------------------------------------------------------------------
SetCheckUniqueness(bool value)440 void VPieceNode::SetCheckUniqueness(bool value)
441 {
442 d->m_checkUniqueness = (d->m_typeTool == Tool::NodePoint ? value : true);
443 }
444
445 //---------------------------------------------------------------------------------------------------------------------
IsManualPassmarkLength() const446 bool VPieceNode::IsManualPassmarkLength() const
447 {
448 return d->m_manualPassmarkLength;
449 }
450
451 //---------------------------------------------------------------------------------------------------------------------
SetManualPassmarkLength(bool value)452 void VPieceNode::SetManualPassmarkLength(bool value)
453 {
454 d->m_manualPassmarkLength = value;
455 }
456
457 //---------------------------------------------------------------------------------------------------------------------
IsExcluded() const458 bool VPieceNode::IsExcluded() const
459 {
460 return d->m_excluded;
461 }
462
463 //---------------------------------------------------------------------------------------------------------------------
SetExcluded(bool exclude)464 void VPieceNode::SetExcluded(bool exclude)
465 {
466 d->m_excluded = exclude;
467 }
468