Seamly2D
Code documentation
vtoolpointofintersectioncurves.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 vtoolpointofintersectioncurves.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date 22 1, 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 "vtoolsinglepoint.h"
55 #include "../ifc/ifcdef.h"
56 #include "../ifc/exception/vexception.h"
57 #include "../vgeometry/vabstractcurve.h"
58 #include "../vgeometry/vgobject.h"
59 #include "../vgeometry/vpointf.h"
60 #include "../vmisc/vabstractapplication.h"
61 #include "../vpatterndb/vcontainer.h"
62 #include "../vwidgets/vmaingraphicsscene.h"
63 #include "../../vdrawtool.h"
64 #include "../../../vabstracttool.h"
65 #include "../../../../dialogs/tools/dialogtool.h"
66 #include "../../../../dialogs/tools/dialogpointofintersectioncurves.h"
67 #include "../../../../visualization/visualization.h"
68 #include "../../../../visualization/path/vistoolpointofintersectioncurves.h"
69 
70 #include <QLineF>
71 #include <QMessageBox>
72 #include <QSharedPointer>
73 #include <QStaticStringData>
74 #include <QStringData>
75 #include <QStringDataPtr>
76 #include <new>
77 
78 template <class T> class QSharedPointer;
79 
80 const QString VToolPointOfIntersectionCurves::ToolType = QStringLiteral("pointOfIntersectionCurves");
81 
82 //---------------------------------------------------------------------------------------------------------------------
84  const quint32 &id, const quint32 firstCurveId,
85  quint32 secondCurveId, VCrossCurvesPoint vCrossPoint,
86  HCrossCurvesPoint hCrossPoint, const Source &typeCreation,
87  QGraphicsItem *parent)
88  :VToolSinglePoint(doc, data, id, QColor(qApp->Settings()->getPointNameColor()), parent),
89  firstCurveId(firstCurveId),
90  secondCurveId(secondCurveId),
91  vCrossPoint(vCrossPoint),
92  hCrossPoint(hCrossPoint)
93 {
94  ToolCreation(typeCreation);
95 }
96 
97 //---------------------------------------------------------------------------------------------------------------------
99 {
100  SCASSERT(not m_dialog.isNull())
101  auto dialogTool = qobject_cast<DialogPointOfIntersectionCurves*>(m_dialog);
102  SCASSERT(dialogTool != nullptr)
104  dialogTool->SetFirstCurveId(firstCurveId);
105  dialogTool->SetSecondCurveId(secondCurveId);
106  dialogTool->SetVCrossPoint(vCrossPoint);
107  dialogTool->SetHCrossPoint(hCrossPoint);
108  dialogTool->SetPointName(p->name());
109 }
110 
111 //---------------------------------------------------------------------------------------------------------------------
113  VMainGraphicsScene *scene,
114  VAbstractPattern *doc, VContainer *data)
115 {
116  SCASSERT(not dialog.isNull())
118  SCASSERT(not dialogTool.isNull())
119  const quint32 firstCurveId = dialogTool->GetFirstCurveId();
120  const quint32 secondCurveId = dialogTool->GetSecondCurveId();
121  const VCrossCurvesPoint vCrossPoint = dialogTool->GetVCrossPoint();
122  const HCrossCurvesPoint hCrossPoint = dialogTool->GetHCrossPoint();
123  const QString pointName = dialogTool->getPointName();
125  5, 10, true, scene, doc, data, Document::FullParse, Source::FromGui);
126  if (point != nullptr)
127  {
128  point->m_dialog = dialogTool;
129  }
130  return point;
131 }
132 
133 //---------------------------------------------------------------------------------------------------------------------
134 VToolPointOfIntersectionCurves *VToolPointOfIntersectionCurves::Create(const quint32 _id, const QString &pointName,
135  quint32 firstCurveId,
136  quint32 secondCurveId,
137  VCrossCurvesPoint vCrossPoint,
138  HCrossCurvesPoint hCrossPoint,
139  qreal mx, qreal my,
140  bool showPointName,
141  VMainGraphicsScene *scene,
142  VAbstractPattern *doc, VContainer *data,
143  const Document &parse,
144  const Source &typeCreation)
145 {
148 
149  const QPointF point = VToolPointOfIntersectionCurves::FindPoint(curve1->getPoints(), curve2->getPoints(),
151 
152  if (point == QPointF())
153  {
154  const QString msg = tr("<b><big>Can't find intersection point %1 of Curves</big></b><br>"
155  "Using origin point as a place holder until pattern is corrected.")
156  .arg(pointName);
157 
158  QMessageBox msgBox(qApp->getMainWindow());
159  msgBox.setWindowTitle(tr("Point Intersect Curves"));
160  msgBox.setWindowFlags(msgBox.windowFlags() & ~Qt::WindowContextHelpButtonHint);
161  msgBox.setWindowIcon(QIcon(":/toolicon/32x32/intersection_curves.png"));
162  msgBox.setIcon(QMessageBox::Warning);
163  msgBox.setText(msg);
164  msgBox.setStandardButtons(QMessageBox::Ok);
165  msgBox.exec();
166  }
167  quint32 id = _id;
168 
169  VPointF *p = new VPointF(point, pointName, mx, my);
170  p->setShowPointName(showPointName);
171 
172  if (typeCreation == Source::FromGui)
173  {
174  id = data->AddGObject(p);
175  }
176  else
177  {
178  data->UpdateGObject(id, p);
179  if (parse != Document::FullParse)
180  {
181  doc->UpdateToolData(id, data);
182  }
183  }
184 
185  if (parse == Document::FullParse)
186  {
189  hCrossPoint, typeCreation);
190  scene->addItem(point);
191  InitToolConnections(scene, point);
192  VAbstractPattern::AddTool(id, point);
193  doc->IncrementReferens(curve1->getIdTool());
194  doc->IncrementReferens(curve2->getIdTool());
195  return point;
196  }
197  return nullptr;
198 }
199 
200 //---------------------------------------------------------------------------------------------------------------------
202  const QVector<QPointF> &curve2Points,
203  VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint)
204 {
205  if (curve1Points.isEmpty() || curve2Points.isEmpty())
206  {
207  return QPointF();
208  }
209 
210  QVector<QPointF> intersections;
211  for ( auto i = 0; i < curve1Points.count()-1; ++i )
212  {
213  intersections << VAbstractCurve::CurveIntersectLine(curve2Points,
214  QLineF(curve1Points.at(i), curve1Points.at(i+1)));
215  }
216 
217  if (intersections.isEmpty())
218  {
219  return QPointF();
220  }
221 
222  if (intersections.size() == 1)
223  {
224  return intersections.at(0);
225  }
226 
227  QVector<QPointF> vIntersections;
229  {
230  qreal minY = intersections.at(0).y();
231  vIntersections.append(intersections.at(0));
232 
233  for ( auto i = 1; i < intersections.count(); ++i )
234  {
235  const QPointF p = intersections.at(i);
236  if (p.y() > minY)
237  {
238  continue;
239  }
240  else if (p.y() < minY)
241  {
242  minY = p.y();
243  vIntersections.clear();
244  vIntersections.append(p);
245  }
246  else
247  {
248  vIntersections.append(p);
249  }
250  }
251  }
252  else
253  {
254  qreal maxY = intersections.at(0).y();
255  vIntersections.append(intersections.at(0));
256 
257  for ( auto i = 1; i < intersections.count(); ++i )
258  {
259  const QPointF p = intersections.at(i);
260  if (p.y() > maxY)
261  {
262  maxY = p.y();
263  vIntersections.clear();
264  vIntersections.append(p);
265  }
266  else if (p.y() < maxY)
267  {
268  continue;
269  }
270  else
271  {
272  vIntersections.append(p);
273  }
274  }
275  }
276 
277  if (vIntersections.isEmpty())
278  {
279  return QPointF();
280  }
281 
282  if (vIntersections.size() == 1)
283  {
284  return vIntersections.at(0);
285  }
286 
287  QPointF crossPoint = vIntersections.at(0);
288 
290  {
291  qreal maxX = vIntersections.at(0).x();
292 
293  for ( auto i = 1; i < vIntersections.count(); ++i )
294  {
295  const QPointF p = vIntersections.at(i);
296  if (p.x() > maxX)
297  {
298  maxX = p.x();
299  crossPoint = p;
300  }
301  }
302  }
303  else
304  {
305  qreal minX = vIntersections.at(0).x();
306 
307  for ( auto i = 1; i < vIntersections.count(); ++i )
308  {
309  const QPointF p = vIntersections.at(i);
310  if (p.x() < minX)
311  {
312  minX = p.x();
313  crossPoint = p;
314  }
315  }
316  }
317 
318  return crossPoint;
319 }
320 
321 //---------------------------------------------------------------------------------------------------------------------
323 {
325 }
326 
327 //---------------------------------------------------------------------------------------------------------------------
329 {
331 }
332 
333 //---------------------------------------------------------------------------------------------------------------------
335 {
336  return firstCurveId;
337 }
338 
339 //---------------------------------------------------------------------------------------------------------------------
341 {
342  if (value != NULL_ID)
343  {
344  firstCurveId = value;
345 
346  auto obj = VAbstractTool::data.GetGObject(m_id);
347  SaveOption(obj);
348  }
349 }
350 
351 //---------------------------------------------------------------------------------------------------------------------
353 {
354  return secondCurveId;
355 }
356 
357 //---------------------------------------------------------------------------------------------------------------------
359 {
360  if (value != NULL_ID)
361  {
362  secondCurveId = value;
363 
364  auto obj = VAbstractTool::data.GetGObject(m_id);
365  SaveOption(obj);
366  }
367 }
368 
369 //---------------------------------------------------------------------------------------------------------------------
371 {
372  return vCrossPoint;
373 }
374 
375 //---------------------------------------------------------------------------------------------------------------------
377 {
378  vCrossPoint = value;
379 
380  auto obj = VAbstractTool::data.GetGObject(m_id);
381  SaveOption(obj);
382 }
383 
384 //---------------------------------------------------------------------------------------------------------------------
386 {
387  return hCrossPoint;
388 }
389 
390 //---------------------------------------------------------------------------------------------------------------------
392 {
393  hCrossPoint = value;
394 
395  auto obj = VAbstractTool::data.GetGObject(m_id);
396  SaveOption(obj);
397 }
398 
399 //---------------------------------------------------------------------------------------------------------------------
401 {
402  ShowToolVisualization<VisToolPointOfIntersectionCurves>(show);
403 }
404 
405 //---------------------------------------------------------------------------------------------------------------------
407 {
408  const auto curve1 = VAbstractTool::data.GetGObject(firstCurveId);
409  const auto curve2 = VAbstractTool::data.GetGObject(secondCurveId);
410 
411  doc->DecrementReferens(curve1->getIdTool());
412  doc->DecrementReferens(curve2->getIdTool());
413 }
414 
415 //---------------------------------------------------------------------------------------------------------------------
416 void VToolPointOfIntersectionCurves::showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id)
417 {
418  try
419  {
420  ContextMenu<DialogPointOfIntersectionCurves>(event, id);
421  }
422  catch(const VExceptionToolWasDeleted &e)
423  {
424  Q_UNUSED(e)
425  return;//Leave this method immediately!!!
426  }
427 }
428 
429 //---------------------------------------------------------------------------------------------------------------------
430 void VToolPointOfIntersectionCurves::SaveDialog(QDomElement &domElement)
431 {
432  SCASSERT(not m_dialog.isNull())
433  auto dialogTool = qobject_cast<DialogPointOfIntersectionCurves*>(m_dialog);
434  SCASSERT(dialogTool != nullptr)
435  doc->SetAttribute(domElement, AttrName, dialogTool->getPointName());
436  doc->SetAttribute(domElement, AttrCurve1, QString().setNum(dialogTool->GetFirstCurveId()));
437  doc->SetAttribute(domElement, AttrCurve2, QString().setNum(dialogTool->GetSecondCurveId()));
438  doc->SetAttribute(domElement, AttrVCrossPoint, QString().setNum(static_cast<int>(dialogTool->GetVCrossPoint())));
439  doc->SetAttribute(domElement, AttrHCrossPoint, QString().setNum(static_cast<int>(dialogTool->GetHCrossPoint())));
440 }
441 
442 //---------------------------------------------------------------------------------------------------------------------
444 {
446 
450  doc->SetAttribute(tag, AttrVCrossPoint, static_cast<int>(vCrossPoint));
451  doc->SetAttribute(tag, AttrHCrossPoint, static_cast<int>(hCrossPoint));
452 }
453 
454 //---------------------------------------------------------------------------------------------------------------------
455 void VToolPointOfIntersectionCurves::ReadToolAttributes(const QDomElement &domElement)
456 {
459  vCrossPoint = static_cast<VCrossCurvesPoint>(doc->GetParametrUInt(domElement, AttrVCrossPoint, "1"));
460  hCrossPoint = static_cast<HCrossCurvesPoint>(doc->GetParametrUInt(domElement, AttrHCrossPoint, "1"));
461 }
462 
463 //---------------------------------------------------------------------------------------------------------------------
465 {
466  if (not vis.isNull())
467  {
468  auto visual = qobject_cast<VisToolPointOfIntersectionCurves *>(vis);
469  SCASSERT(visual != nullptr)
470 
471  visual->setObject1Id(firstCurveId);
472  visual->setObject2Id(secondCurveId);
473  visual->setVCrossPoint(vCrossPoint);
474  visual->setHCrossPoint(hCrossPoint);
475  visual->RefreshGeometry();
476  }
477 }
virtual QVector< QPointF > getPoints() const =0
static QVector< QPointF > CurveIntersectLine(const QVector< QPointF > &points, const QLineF &line)
virtual void UpdateToolData(const quint32 &id, VContainer *data)=0
virtual void IncrementReferens(quint32 id) const =0
static void AddTool(quint32 id, VDataTool *tool)
AddTool add tool to list tools.
virtual void DecrementReferens(quint32 id) const =0
static void InitToolConnections(VMainGraphicsScene *scene, T *tool)
VAbstractPattern * doc
doc dom document container
QPointer< Visualization > vis
virtual void ToolCreation(const Source &typeCreation)
static void AddRecord(const quint32 id, const Tool &toolType, VAbstractPattern *doc)
AddRecord add record about tool in history.
const quint32 m_id
id object id.
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
quint32 AddGObject(VGObject *obj)
AddGObject add new GObject to container.
Definition: vcontainer.cpp:216
void UpdateGObject(quint32 id, T *obj)
UpdateGObject update GObject by id.
Definition: vcontainer.h:374
VContainer data
data container with data
Definition: vdatatool.h:84
static quint32 GetParametrUInt(const QDomElement &domElement, const QString &name, const QString &defValue)
Returns the long long value of the given attribute. RENAME: GetParameterLongLong?
void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const
SetAttribute set attribute in pattern file. Replace "," by ".".
Definition: vdomdocument.h:185
void SaveOption(QSharedPointer< VGObject > &obj)
Definition: vdrawtool.cpp:142
quint32 getIdTool() const
Definition: vgobject.cpp:221
QSharedPointer< DialogTool > m_dialog
m_dialog tool's dialog options.
The VMainGraphicsScene class main scene.
The VPointF class keep data of point.
Definition: vpointf.h:75
void setShowPointName(bool show)
Definition: vpointf.cpp:265
virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
virtual void SaveDialog(QDomElement &domElement) Q_DECL_OVERRIDE
SaveDialog save options into file after change in dialog.
static QPointF FindPoint(const QVector< QPointF > &curve1Points, const QVector< QPointF > &curve2Points, VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint)
virtual void SetVisualization() Q_DECL_OVERRIDE
virtual void ReadToolAttributes(const QDomElement &domElement) Q_DECL_OVERRIDE
virtual void setDialog() Q_DECL_OVERRIDE
setDialog set dialog when user want change tool option.
void SetVCrossPoint(const VCrossCurvesPoint &value)
static VToolPointOfIntersectionCurves * Create(QSharedPointer< DialogTool > dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data)
virtual void showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id=NULL_ID) Q_DECL_OVERRIDE
VToolPointOfIntersectionCurves(VAbstractPattern *doc, VContainer *data, const quint32 &id, const quint32 firstCurveId, quint32 secondCurveId, VCrossCurvesPoint vCrossPoint, HCrossCurvesPoint hCrossPoint, const Source &typeCreation, QGraphicsItem *parent=nullptr)
void SetHCrossPoint(const HCrossCurvesPoint &value)
virtual void RemoveReferens() Q_DECL_OVERRIDE
RemoveReferens decrement value of reference.
The VToolSinglePoint class parent for all tools what create points.
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
#define SCASSERT(cond)
Definition: def.h:317
@ PointOfIntersectionCurves
Source
Definition: def.h:106
const QString AttrName
Definition: ifcdef.cpp:76
const QString AttrCurve2
Definition: ifcdef.cpp:129
const QString AttrCurve1
Definition: ifcdef.cpp:128
const QString AttrHCrossPoint
Definition: ifcdef.cpp:137
const QString AttrType
Definition: ifcdef.cpp:73
const QString AttrVCrossPoint
Definition: ifcdef.cpp:136
#define NULL_ID
Definition: ifcdef.h:76
#define NULL_ID_STR
Definition: ifcdef.h:77
Document
HCrossCurvesPoint
VCrossCurvesPoint
#define qApp
Definition: vapplication.h:67