Seamly2D
Code documentation
vnodedetail.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 vnodedetail.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date November 15, 2013
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) 2013-2015 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 "vnodedetail.h"
53 #include "vnodedetail_p.h"
54 #include "vpiecenode.h"
55 #include "vpiecepath.h"
56 #include "../vgeometry/vpointf.h"
57 #include "../vpatterndb/vcontainer.h"
58 
59 #include <QLineF>
60 #include <QVector>
61 
62 namespace
63 {
64 //---------------------------------------------------------------------------------------------------------------------
65 bool IsOX(const QLineF &line)
66 {
67  return VFuzzyComparePossibleNulls(line.angle(), 0)
68  || VFuzzyComparePossibleNulls(line.angle(), 360)
69  || VFuzzyComparePossibleNulls(line.angle(), 180);
70 }
71 
72 //---------------------------------------------------------------------------------------------------------------------
73 bool IsOY(const QLineF &line)
74 {
75  return VFuzzyComparePossibleNulls(line.angle(), 90) || VFuzzyComparePossibleNulls(line.angle(), 270);
76 }
77 
78 //---------------------------------------------------------------------------------------------------------------------
79 QString LocalWidth(const QLineF &line, const QLineF &movedLine)
80 {
81  if (VFuzzyComparePossibleNulls(line.angle(), movedLine.angle()))
82  {
83  return QString().setNum(movedLine.length());
84  }
85  else
86  {// different direction means value is negative
87  return QString("0");
88  }
89 }
90 
91 //---------------------------------------------------------------------------------------------------------------------
92 void ConvertBefore(VPieceNode &node, const QLineF &line, qreal mX, qreal mY)
93 {
94  if (not qFuzzyIsNull(mX) && IsOX(line))
95  {
96  const QLineF movedLine(line.p1().x(), line.p1().y(), line.p2().x() + mX, line.p2().y());
97  node.setBeforeSAFormula(LocalWidth(line, movedLine));
98  }
99  else if (not qFuzzyIsNull(mY) && IsOY(line))
100  {
101  const QLineF movedLine(line.p1().x(), line.p1().y(), line.p2().x(), line.p2().y() + mY);
102  node.setBeforeSAFormula(LocalWidth(line, movedLine));
103  }
104 }
105 
106 //---------------------------------------------------------------------------------------------------------------------
107 void ConvertAfter(VPieceNode &node, const QLineF &line, qreal mX, qreal mY)
108 {
109  if (not qFuzzyIsNull(mX) && IsOX(line))
110  {
111  const QLineF movedLine(line.p1().x(), line.p1().y(), line.p2().x() + mX, line.p2().y());
112  node.setAfterSAFormula(LocalWidth(line, movedLine));
113  }
114  else if (not qFuzzyIsNull(mY) && IsOY(line))
115  {
116  const QLineF movedLine(line.p1().x(), line.p1().y(), line.p2().x(), line.p2().y() + mY);
117  node.setAfterSAFormula(LocalWidth(line, movedLine));
118  }
119 }
120 }//static functions
121 
122 #ifdef Q_COMPILER_RVALUE_REFS
123 VNodeDetail &VNodeDetail::operator=(VNodeDetail &&node) Q_DECL_NOTHROW
124 { Swap(node); return *this; }
125 #endif
126 
127 void VNodeDetail::Swap(VNodeDetail &node) Q_DECL_NOTHROW
128 { std::swap(d, node.d); }
129 
130 //---------------------------------------------------------------------------------------------------------------------
132  :d(new VNodeDetailData)
133 {}
134 
135 //---------------------------------------------------------------------------------------------------------------------
136 VNodeDetail::VNodeDetail(quint32 id, Tool typeTool, NodeDetail typeNode, qreal mx, qreal my, bool reverse)
137  :d(new VNodeDetailData(id, typeTool, typeNode, mx, my, reverse))
138 {}
139 
140 //---------------------------------------------------------------------------------------------------------------------
142  :d (node.d)
143 {}
144 
145 //---------------------------------------------------------------------------------------------------------------------
147 {
148  if ( &node == this )
149  {
150  return *this;
151  }
152  d = node.d;
153  return *this;
154 }
155 
156 //---------------------------------------------------------------------------------------------------------------------
158 {}
159 
160 //---------------------------------------------------------------------------------------------------------------------
161 quint32 VNodeDetail::getId() const
162 {
163  return d->id;
164 }
165 
166 //---------------------------------------------------------------------------------------------------------------------
167 void VNodeDetail::setId(const quint32 &value)
168 {
169  d->id = value;
170 }
171 
172 //---------------------------------------------------------------------------------------------------------------------
174 {
175  return d->typeTool;
176 }
177 
178 //---------------------------------------------------------------------------------------------------------------------
179 // cppcheck-suppress unusedFunction
180 void VNodeDetail::setTypeTool(const Tool &value)
181 {
182  d->typeTool = value;
183 }
184 
185 //---------------------------------------------------------------------------------------------------------------------
187 {
188  return d->typeNode;
189 }
190 
191 //---------------------------------------------------------------------------------------------------------------------
192 // cppcheck-suppress unusedFunction
194 {
195  d->typeNode = value;
196 }
197 
198 //---------------------------------------------------------------------------------------------------------------------
199 qreal VNodeDetail::getMx() const
200 {
201  return d->mx;
202 }
203 
204 //---------------------------------------------------------------------------------------------------------------------
205 void VNodeDetail::setMx(const qreal &value)
206 {
207  d->mx = value;
208 }
209 
210 //---------------------------------------------------------------------------------------------------------------------
211 qreal VNodeDetail::getMy() const
212 {
213  return d->my;
214 }
215 
216 //---------------------------------------------------------------------------------------------------------------------
217 void VNodeDetail::setMy(const qreal &value)
218 {
219  d->my = value;
220 }
221 
222 //---------------------------------------------------------------------------------------------------------------------
224 {
225  if (getTypeTool() == Tool::NodePoint)
226  {
227  return false;
228  }
229  else
230  {
231  return d->reverse;
232  }
233 }
234 
235 //---------------------------------------------------------------------------------------------------------------------
236 void VNodeDetail::setReverse(bool reverse)
237 {
238  if (getTypeTool() == Tool::NodePoint)
239  {
240  d->reverse = false;
241  }
242  else
243  {
244  d->reverse = reverse;
245  }
246 }
247 
248 //---------------------------------------------------------------------------------------------------------------------
250  bool closed)
251 {
252  if (width < 0)
253  {
254  width = 0;
255  }
256 
257  VPiecePath path;
258  for (int i = 0; i < nodes.size(); ++i)
259  {
260  const VNodeDetail &node = nodes.at(i);
261  path.Append(VPieceNode(node.getId(), node.getTypeTool(), node.getReverse()));
262  }
263 
264  if (path.PathPoints(data).size() > 2)
265  {
266  for (int i = 0; i < nodes.size(); ++i)
267  {
268  const VNodeDetail &node = nodes.at(i);
269  if (node.getTypeTool() == Tool::NodePoint)
270  {
271  if (not qFuzzyIsNull(node.getMx()) || not qFuzzyIsNull(node.getMy()))
272  {
273  const QPointF previosPoint = path.NodePreviousPoint(data, i);
274  const QPointF nextPoint = path.NodeNextPoint(data, i);
275 
276  const QPointF point = data->GeometricObject<VPointF>(node.getId())->toQPointF();
277 
278  QLineF lineBefore(point, previosPoint);
279  lineBefore.setAngle(lineBefore.angle()-90);
280  lineBefore.setLength(width);
281 
282  ConvertBefore(path[i], lineBefore, node.getMx(), node.getMy());
283 
284  QLineF lineAfter(point, nextPoint);
285  lineAfter.setAngle(lineAfter.angle()+90);
286  lineAfter.setLength(width);
287 
288  ConvertAfter(path[i], lineAfter, node.getMx(), node.getMy());
289  }
290  }
291  }
292  }
293 
294  if (not closed && path.CountNodes() > 1)
295  {
296  path[0].setBeforeSAFormula("0");
297  path[path.CountNodes()-1].setAfterSAFormula("0");
298  }
299 
300  return path.GetNodes();
301 }
The VContainer class container of all variables.
Definition: vcontainer.h:141
const QSharedPointer< T > GeometricObject(const quint32 &id) const
Definition: vcontainer.h:266
The VNodeDetail class keep information about detail node.
Definition: vnodedetail.h:70
Tool getTypeTool() const
getTypeTool return tool type.
quint32 getId() const
getId return object id.
void setMy(const qreal &value)
setMy set object bias y axis.
static QVector< VPieceNode > Convert(const VContainer *data, const QVector< VNodeDetail > &nodes, qreal width, bool closed)
qreal getMx() const
getMx return object bias x axis.
VNodeDetail & operator=(const VNodeDetail &node)
operator = assignment operator
void setMx(const qreal &value)
setMx set object bias x axis.
bool getReverse() const
void setTypeNode(const NodeDetail &value)
setTypeNode set node type.
void Swap(VNodeDetail &node) Q_DECL_NOTHROW
NodeDetail getTypeNode() const
getTypeNode return node type.
void setTypeTool(const Tool &value)
setTypeTool set tool type.
void setId(const quint32 &value)
setId set object id.
VNodeDetail()
VNodeDetail default constructor.
qreal getMy() const
getMy return object bias y axis.
void setReverse(bool reverse)
QSharedDataPointer< VNodeDetailData > d
Definition: vnodedetail.h:162
void setBeforeSAFormula(const QString &formula)
Definition: vpiecenode.cpp:221
void setAfterSAFormula(const QString &formula)
Definition: vpiecenode.cpp:263
QVector< QPointF > PathPoints(const VContainer *data) const
Definition: vpiecepath.cpp:287
qint32 CountNodes() const
Definition: vpiecepath.cpp:209
void Append(const VPieceNode &node)
Definition: vpiecepath.cpp:197
QVector< VPieceNode > GetNodes() const
Definition: vpiecepath.cpp:227
QPointF NodePreviousPoint(const VContainer *data, int i) const
Definition: vpiecepath.cpp:701
QPointF NodeNextPoint(const VContainer *data, int i) const
Definition: vpiecepath.cpp:752
The VPointF class keep data of point.
Definition: vpointf.h:75
NodeDetail
Definition: def.h:102
static Q_REQUIRED_RESULT bool VFuzzyComparePossibleNulls(double p1, double p2)
Definition: def.h:490
Tool
Definition: def.h:161
@ NodePoint
bool IsOY(const QLineF &line)
Definition: vnodedetail.cpp:73
void ConvertAfter(VPieceNode &node, const QLineF &line, qreal mX, qreal mY)
bool IsOX(const QLineF &line)
Definition: vnodedetail.cpp:65
void ConvertBefore(VPieceNode &node, const QLineF &line, qreal mX, qreal mY)
Definition: vnodedetail.cpp:92
QString LocalWidth(const QLineF &line, const QLineF &movedLine)
Definition: vnodedetail.cpp:79