Seamly2D
Code documentation
vabstractcubicbezierpath.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 vabstractcubicbezierpath.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date 16 3, 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 
53 
54 #include <QPainterPath>
55 
56 #include "../vmisc/def.h"
57 #include "../ifc/ifcdef.h"
58 #include "../ifc/exception/vexception.h"
59 #include "vpointf.h"
60 #include "vspline.h"
61 
62 //---------------------------------------------------------------------------------------------------------------------
63 VAbstractCubicBezierPath::VAbstractCubicBezierPath(const GOType &type, const quint32 &idObject, const Draw &mode)
64  : VAbstractBezier(type, idObject, mode)
65 {
66 }
67 
68 //---------------------------------------------------------------------------------------------------------------------
70  : VAbstractBezier(curve)
71 {
72 }
73 
74 //---------------------------------------------------------------------------------------------------------------------
76 {
77  if ( &curve == this )
78  {
79  return *this;
80  }
82  return *this;
83 }
84 
85 //---------------------------------------------------------------------------------------------------------------------
87 {
88 }
89 
90 //---------------------------------------------------------------------------------------------------------------------
91 /**
92  * @brief GetPath return QPainterPath which reprezent spline path.
93  * @return path.
94  */
96 {
97  QPainterPath painterPath;
98  for (qint32 i = 1; i <= CountSubSpl(); ++i)
99  {
100  painterPath.addPath(GetSpline(i).GetPath());
101  }
102  return painterPath;
103 }
104 
105 //---------------------------------------------------------------------------------------------------------------------
106 /**
107  * @brief GetPathPoints return list of points what located on path.
108  * @return list.
109  */
111 {
112  QVector<QPointF> pathPoints;
113  for (qint32 i = 1; i <= CountSubSpl(); ++i)
114  {
115  if (not pathPoints.isEmpty())
116  {
117  pathPoints.removeLast();
118  }
119 
120  pathPoints += GetSpline(i).getPoints();
121  }
122  return pathPoints;
123 }
124 
125 //---------------------------------------------------------------------------------------------------------------------
126 /**
127  * @brief GetLength return length of spline path.
128  * @return length.
129  */
131 {
132  qreal length = 0;
133  for (qint32 i = 1; i <= CountSubSpl(); ++i)
134  {
135  length += GetSpline(i).GetLength();
136  }
137  return length;
138 }
139 
140 //---------------------------------------------------------------------------------------------------------------------
142 {
144  for (qint32 i = 1; i <= CountSubSpl(); ++i)
145  {
146  arrows += GetSpline(i).DirectionArrows();
147  }
148  return arrows;
149 }
150 
151 //---------------------------------------------------------------------------------------------------------------------
152 int VAbstractCubicBezierPath::Segment(const QPointF &p) const
153 {
154  int index = -1;
155  for (qint32 i = 1; i <= CountSubSpl(); ++i)
156  {
157  const qreal t = GetSpline(i).ParamT(p);
158  if (qFuzzyIsNull(t) || not qFuzzyCompare(t, -1))
159  {
160  index = i;
161  break;
162  }
163  }
164  return index;
165 }
166 
167 //---------------------------------------------------------------------------------------------------------------------
168 /**
169  * @brief CutSplinePath cut spline path into two. This method don't return two spline path. You must create spline
170  * paths by yourself.
171  * Example:
172  * QPointF spl1p2, spl1p3, spl2p2, spl2p3;
173  * qint32 p1 = 0, p2 = 0;
174  * QPointF point = splPath->CutSplinePath(length, p1, p2, spl1p2, spl1p3, spl2p2, spl2p3);
175  *
176  * VSplinePoint splP1 = splPath->at(p1);
177  * VSplinePoint splP2 = splPath->at(p2);
178  * VSpline spl1 = VSpline(splP1.P(), spl1p2, spl1p3, *p, splPath->GetKCurve());
179  * VSpline spl2 = VSpline(*p, spl2p2, spl2p3, splP2.P(), splPath->GetKCurve());
180  * @param length length first spline path.
181  * @param p1 index first spline point in list.
182  * @param p2 index second spline point in list.
183  * @param spl1p2 first control point first spline.
184  * @param spl1p3 second control point first spline.
185  * @param spl2p2 first control point second spline.
186  * @param spl2p3 second control point second spline.
187  * @return cutting point.
188  */
189 QPointF VAbstractCubicBezierPath::CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF &spl1p2, QPointF &spl1p3,
190  QPointF &spl2p2, QPointF &spl2p3) const
191 {
192  if (CountSubSpl() < 1)
193  {
194  throw VException(tr("Can't cut this spline"));
195  }
196 
197  //Always need return two spline paths, so we must correct wrong length.
198  const qreal minLength = ToPixel(1, Unit::Mm);
199  qreal fullLength = GetLength();
200 
201  if (fullLength <= minLength)
202  {
203  p1 = p2 = -1;
204  spl1p2 = spl1p3 = spl2p2 = spl2p3 = QPointF();
205  return QPointF();
206  }
207 
208  const qreal maxLength = fullLength - minLength;
209 
210  if (length < minLength)
211  {
212  length = minLength;
213  }
214  else if (length > maxLength)
215  {
216  length = maxLength;
217  }
218 
219  fullLength = 0;
220  for (qint32 i = 1; i <= CountSubSpl(); ++i)
221  {
222  const VSpline spl = GetSpline(i);
223  const qreal splLength = spl.GetLength();
224  fullLength += splLength;
225  if (fullLength > length)
226  {
227  p1 = i-1;
228  p2 = i;
229  return spl.CutSpline(length - (fullLength - splLength), spl1p2, spl1p3, spl2p2, spl2p3);
230  }
231  }
232  p1 = p2 = -1;
233  spl1p2 = spl1p3 = spl2p2 = spl2p3 = QPointF();
234  return QPointF();
235 }
236 
237 //---------------------------------------------------------------------------------------------------------------------
238 /**
239  * @brief NameForHistory helps to create name for dialog History.
240  * @param toolName first part of name. Like 'Spline path' or 'Cubic Bezier path'.
241  * @return name of curve for history records.
242  */
243 QString VAbstractCubicBezierPath::NameForHistory(const QString &toolName) const
244 {
245  QString name = toolName;
246  if (CountPoints() > 0)
247  {
248  name += QString(" %1").arg(FirstPoint().name());
249  if (CountSubSpl() >= 1)
250  {
251  name += QString("_%1").arg(LastPoint().name());
252  }
253 
254  if (GetDuplicate() > 0)
255  {
256  name += QString("_%1").arg(GetDuplicate());
257  }
258  }
259  return name;
260 }
261 
262 //---------------------------------------------------------------------------------------------------------------------
264 {
265  QString name;
266  if (CountPoints() > 0)
267  {
268  name = splPath;
269  name.append(QString("_%1").arg(FirstPoint().name()));
270  if (CountSubSpl() >= 1)
271  {
272  name.append(QString("_%1").arg(LastPoint().name()));
273 
274  if (GetDuplicate() > 0)
275  {
276  name += QString("_%1").arg(GetDuplicate());
277  }
278  }
279  }
280  setName(name);
281 }
VAbstractBezier & operator=(const VAbstractBezier &curve)
virtual VPointF FirstPoint() const =0
virtual qreal GetLength() const Q_DECL_OVERRIDE
GetLength return length of spline path.
QPointF CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, QPointF &spl2p3) const
CutSplinePath cut spline path into two. This method don't return two spline path. You must create spl...
virtual QVector< QPointF > getPoints() const Q_DECL_OVERRIDE
GetPathPoints return list of points what located on path.
VAbstractCubicBezierPath & operator=(const VAbstractCubicBezierPath &curve)
virtual QString NameForHistory(const QString &toolName) const Q_DECL_OVERRIDE
NameForHistory helps to create name for dialog History.
virtual qint32 CountSubSpl() const =0
VAbstractCubicBezierPath(const GOType &type, const quint32 &idObject=null_id, const Draw &mode=Draw::Calculation)
int Segment(const QPointF &p) const
virtual void CreateName() Q_DECL_OVERRIDE
virtual qint32 CountPoints() const =0
virtual QPainterPath GetPath() const Q_DECL_OVERRIDE
GetPath return QPainterPath which reprezent spline path.
virtual QVector< DirectionArrow > DirectionArrows() const Q_DECL_OVERRIDE
virtual VSpline GetSpline(qint32 index) const =0
virtual VPointF LastPoint() const =0
virtual QVector< DirectionArrow > DirectionArrows() const
quint32 GetDuplicate() const
virtual QPainterPath GetPath() const
The VException class parent for all exception. Could be use for abstract exception.
Definition: vexception.h:66
virtual QString name() const
name return name graphical object.
Definition: vgobject.cpp:148
void setName(const QString &name)
setName set name graphical object.
Definition: vgobject.cpp:158
VSpline class that implements the spline.
Definition: vspline.h:75
QPointF CutSpline(qreal length, VSpline &spl1, VSpline &spl2) const
Definition: vspline.cpp:210
virtual qreal GetLength() const Q_DECL_OVERRIDE
GetLength return length of spline.
Definition: vspline.cpp:203
qreal ParamT(const QPointF &pBt) const
VSpline::ParamT calculate t coeffient that reprezent point on curve.
Definition: vspline.cpp:540
virtual QVector< QPointF > getPoints() const Q_DECL_OVERRIDE
GetPoints return list with spline points.
Definition: vspline.cpp:228
double ToPixel(double val, const Unit &unit)
Definition: def.cpp:231
const QString splPath
Definition: ifcdef.cpp:419
GOType
Definition: vgeometrydef.h:56
Draw
Definition: vgeometrydef.h:55