Seamly2D
Code documentation
intersect_circles_tool.cpp
Go to the documentation of this file.
1 /**************************************************************************
2  **
3  ** @file intersect_circles_tool.cpp
4  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
5  ** @date 29 5, 2015
6  **
7  ** @author Douglas S. Caskey
8  ** @date 7.16.2022
9  **
10  ** @copyright
11  ** Copyright (C) 2013-2022 Seamly2D project.
12  ** This source code is part of the Seamly2D project, a pattern making
13  ** program, whose allow create and modeling patterns of clothing.
14  **
15  ** <https://github.com/fashionfreedom/seamly2d> All Rights Reserved.
16  **
17  ** Seamly2D is free software: you can redistribute it and/or modify
18  ** it under the terms of the GNU General Public License as published
19  ** by the Free Software Foundation, either version 3 of the License,
20  ** or (at your option) any later version.
21  **
22  ** Seamly2D is distributed in the hope that it will be useful,
23  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
24  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  ** GNU General Public License for more details.
26  **
27  ** You should have received a copy of the GNU General Public License
28  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
29  **
30  *************************************************************************/
31 
32 #include "intersect_circles_tool.h"
33 
34 #include "vtoolsinglepoint.h"
35 #include "../ifc/exception/vexception.h"
36 #include "../ifc/xml/vdomdocument.h"
37 #include "../ifc/ifcdef.h"
38 #include "../vgeometry/vgobject.h"
39 #include "../vgeometry/vpointf.h"
40 #include "../vmisc/vabstractapplication.h"
41 #include "../vpatterndb/vcontainer.h"
42 #include "../vpatterndb/vformula.h"
43 #include "../vwidgets/vmaingraphicsscene.h"
44 #include "../../vdrawtool.h"
45 #include "../../../vabstracttool.h"
46 #include "../../../../dialogs/tools/intersect_circles_dialog.h"
47 #include "../../../../dialogs/tools/dialogtool.h"
48 #include "../../../../visualization/visualization.h"
49 #include "../../../../visualization/line/intersect_circles_visual.h"
50 
51 #include <QMessageBox>
52 #include <QSharedPointer>
53 #include <QStaticStringData>
54 #include <QStringData>
55 #include <QStringDataPtr>
56 #include <new>
57 
58 template <class T> class QSharedPointer;
59 
60 const QString IntersectCirclesTool::ToolType = QStringLiteral("pointOfIntersectionCircles");
61 
62 //---------------------------------------------------------------------------------------------------------------------
64  const quint32 &id,
65  quint32 firstCircleCenterId,
66  quint32 secondCircleCenterId,
67  const QString &firstCircleRadius,
68  const QString &secondCircleRadius,
69  CrossCirclesPoint crossPoint,
70  const Source &typeCreation, QGraphicsItem *parent)
71  : VToolSinglePoint(doc, data, id, QColor(qApp->Settings()->getPointNameColor()), parent)
72  , firstCircleCenterId(firstCircleCenterId)
73  , secondCircleCenterId(secondCircleCenterId)
74  , firstCircleRadius(firstCircleRadius)
75  , secondCircleRadius(secondCircleRadius)
76  , crossPoint(crossPoint)
77 {
78  ToolCreation(typeCreation);
79 }
80 
81 //---------------------------------------------------------------------------------------------------------------------
83 {
84  SCASSERT(not m_dialog.isNull())
86  m_dialog.objectCast<IntersectCirclesDialog>();
87  SCASSERT(not dialogTool.isNull())
89  dialogTool->SetFirstCircleCenterId(firstCircleCenterId);
90  dialogTool->SetSecondCircleCenterId(secondCircleCenterId);
91  dialogTool->SetFirstCircleRadius(firstCircleRadius);
92  dialogTool->SetSecondCircleRadius(secondCircleRadius);
93  dialogTool->setCirclesCrossPoint(crossPoint);
94  dialogTool->SetPointName(p->name());
95 }
96 
97 //---------------------------------------------------------------------------------------------------------------------
99  VMainGraphicsScene *scene,
100  VAbstractPattern *doc, VContainer *data)
101 {
102  SCASSERT(not dialog.isNull())
104  dialog.objectCast<IntersectCirclesDialog>();
105  SCASSERT(not dialogTool.isNull())
106  const quint32 firstCircleCenterId = dialogTool->GetFirstCircleCenterId();
107  const quint32 secondCircleCenterId = dialogTool->GetSecondCircleCenterId();
108  QString firstCircleRadius = dialogTool->GetFirstCircleRadius();
109  QString secondCircleRadius = dialogTool->GetSecondCircleRadius();
110  const CrossCirclesPoint pType = dialogTool->GetCrossCirclesPoint();
111  const QString pointName = dialogTool->getPointName();
113  firstCircleRadius, secondCircleRadius, pType, 5, 10, true, scene, doc,
115  if (point != nullptr)
116  {
117  point->m_dialog = dialogTool;
118  }
119  return point;
120 }
121 
122 //---------------------------------------------------------------------------------------------------------------------
123 IntersectCirclesTool *IntersectCirclesTool::Create(const quint32 _id, const QString &pointName,
124  quint32 firstCircleCenterId,
125  quint32 secondCircleCenterId,
126  QString &firstCircleRadius,
127  QString &secondCircleRadius,
128  CrossCirclesPoint crossPoint,
129  qreal mx, qreal my,
130  bool showPointName,
131  VMainGraphicsScene *scene,
132  VAbstractPattern *doc, VContainer *data,
133  const Document &parse,
134  const Source &typeCreation)
135 {
136  const qreal calcC1Radius = qApp->toPixel(CheckFormula(_id, firstCircleRadius, data));
137  const qreal calcC2Radius = qApp->toPixel(CheckFormula(_id, secondCircleRadius, data));
138 
141 
142  const QPointF point = FindPoint(static_cast<QPointF>(c1Point), static_cast<QPointF>(c2Point), calcC1Radius,
143  calcC2Radius, crossPoint);
144  if (point == QPointF())
145  {
146  const QString msg = tr("<b><big>Can't find intersection point %1 of Circles</big></b><br>"
147  "Using origin point as a place holder until pattern is corrected.")
148  .arg(pointName);
149 
150  QMessageBox msgBox(qApp->getMainWindow());
151  msgBox.setWindowTitle(tr("Point Intersect Circles"));
152  msgBox.setWindowFlags(msgBox.windowFlags() & ~Qt::WindowContextHelpButtonHint);
153  msgBox.setWindowIcon(QIcon(":/toolicon/32x32/point_of_intersection_circles.png"));
154  msgBox.setIcon(QMessageBox::Warning);
155  msgBox.setText(msg);
156  msgBox.setStandardButtons(QMessageBox::Ok);
157  msgBox.exec();
158  }
159 
160  quint32 id = _id;
161 
162  VPointF *p = new VPointF(point, pointName, mx, my);
163  p->setShowPointName(showPointName);
164 
165  if (typeCreation == Source::FromGui)
166  {
167  id = data->AddGObject(p);
168  }
169  else
170  {
171  data->UpdateGObject(id, p);
172  if (parse != Document::FullParse)
173  {
174  doc->UpdateToolData(id, data);
175  }
176  }
177 
178  if (parse == Document::FullParse)
179  {
185  typeCreation);
186  scene->addItem(point);
187  InitToolConnections(scene, point);
188  VAbstractPattern::AddTool(id, point);
189  doc->IncrementReferens(c1Point.getIdTool());
190  doc->IncrementReferens(c2Point.getIdTool());
191  return point;
192  }
193  return nullptr;
194 }
195 
196 //---------------------------------------------------------------------------------------------------------------------
197 QPointF IntersectCirclesTool::FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius,
198  qreal c2Radius, const CrossCirclesPoint crossPoint)
199 {
200  QPointF p1, p2;
201  const int res = VGObject::IntersectionCircles(c1Point, c1Radius, c2Point, c2Radius, p1, p2);
202 
203  switch(res)
204  {
205  case 2:
207  {
208  return p1;
209  }
210  else
211  {
212  return p2;
213  }
214  case 1:
215  return p1;
216  case 3:
217  case 0:
218  default:
219  return QPointF();
220  }
221 }
222 
223 //---------------------------------------------------------------------------------------------------------------------
225 {
227 }
228 
229 //---------------------------------------------------------------------------------------------------------------------
231 {
233 }
234 
235 //---------------------------------------------------------------------------------------------------------------------
237 {
238  return firstCircleCenterId;
239 }
240 
241 //---------------------------------------------------------------------------------------------------------------------
243 {
244  if (value != NULL_ID)
245  {
246  firstCircleCenterId = value;
247 
249  SaveOption(obj);
250  }
251 }
252 
253 //---------------------------------------------------------------------------------------------------------------------
255 {
256  return secondCircleCenterId;
257 }
258 
259 //---------------------------------------------------------------------------------------------------------------------
261 {
262  if (value != NULL_ID)
263  {
264  secondCircleCenterId = value;
265 
267  SaveOption(obj);
268  }
269 }
270 
271 //---------------------------------------------------------------------------------------------------------------------
273 {
275  radius.setCheckZero(true);
276  radius.setToolId(m_id);
277  radius.setPostfix(UnitsToStr(qApp->patternUnit()));
278  return radius;
279 }
280 
281 //---------------------------------------------------------------------------------------------------------------------
283 {
284  if (value.error() == false)
285  {
286  if (value.getDoubleValue() > 0)// Formula don't check this, but radius can't be 0 or negative
287  {
290  SaveOption(obj);
291  }
292  }
293 }
294 
295 //---------------------------------------------------------------------------------------------------------------------
297 {
299  radius.setCheckZero(true);
300  radius.setToolId(m_id);
301  radius.setPostfix(UnitsToStr(qApp->patternUnit()));
302  return radius;
303 }
304 
305 //---------------------------------------------------------------------------------------------------------------------
307 {
308  if (value.error() == false)
309  {
310  if (value.getDoubleValue() > 0)// Formula don't check this, but radius can't be 0 or negative
311  {
314  SaveOption(obj);
315  }
316  }
317 }
318 
319 //---------------------------------------------------------------------------------------------------------------------
321 {
322  return crossPoint;
323 }
324 
325 //---------------------------------------------------------------------------------------------------------------------
327 {
328  crossPoint = value;
329 
331  SaveOption(obj);
332 }
333 
334 //---------------------------------------------------------------------------------------------------------------------
336 {
337  ShowToolVisualization<IntersectCirclesVisual>(show);
338 }
339 
340 //---------------------------------------------------------------------------------------------------------------------
342 {
343  const auto firstCircleCenter = VAbstractTool::data.GetGObject(firstCircleCenterId);
344  const auto secondCircleCenter = VAbstractTool::data.GetGObject(secondCircleCenterId);
345 
346  doc->DecrementReferens(firstCircleCenter->getIdTool());
347  doc->DecrementReferens(secondCircleCenter->getIdTool());
348 }
349 
350 //---------------------------------------------------------------------------------------------------------------------
351 void IntersectCirclesTool::showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id)
352 {
353  try
354  {
355  ContextMenu<IntersectCirclesDialog>(event, id);
356  }
357  catch(const VExceptionToolWasDeleted &e)
358  {
359  Q_UNUSED(e)
360  return;//Leave this method immediately!!!
361  }
362 }
363 
364 //---------------------------------------------------------------------------------------------------------------------
365 void IntersectCirclesTool::SaveDialog(QDomElement &domElement)
366 {
367  SCASSERT(not m_dialog.isNull())
369  m_dialog.objectCast<IntersectCirclesDialog>();
370  SCASSERT(not dialogTool.isNull())
371  doc->SetAttribute(domElement, AttrName, dialogTool->getPointName());
372  doc->SetAttribute(domElement, AttrC1Center, QString().setNum(dialogTool->GetFirstCircleCenterId()));
373  doc->SetAttribute(domElement, AttrC2Center, QString().setNum(dialogTool->GetSecondCircleCenterId()));
374  doc->SetAttribute(domElement, AttrC1Radius, dialogTool->GetFirstCircleRadius());
375  doc->SetAttribute(domElement, AttrC2Radius, dialogTool->GetSecondCircleRadius());
376  doc->SetAttribute(domElement, AttrCrossPoint,
377  QString().setNum(static_cast<int>(dialogTool->GetCrossCirclesPoint())));
378 }
379 
380 //---------------------------------------------------------------------------------------------------------------------
382 {
384 
390  doc->SetAttribute(tag, AttrCrossPoint, static_cast<int>(crossPoint));
391 }
392 
393 //---------------------------------------------------------------------------------------------------------------------
394 void IntersectCirclesTool::ReadToolAttributes(const QDomElement &domElement)
395 {
400  crossPoint = static_cast<CrossCirclesPoint>(doc->GetParametrUInt(domElement, AttrCrossPoint, "1"));
401 }
402 
403 //---------------------------------------------------------------------------------------------------------------------
405 {
406  if (not vis.isNull())
407  {
408  IntersectCirclesVisual *visual = qobject_cast<IntersectCirclesVisual *>(vis);
409  SCASSERT(visual != nullptr)
410 
415  visual->setCrossPoint(crossPoint);
416  visual->RefreshGeometry();
417  }
418 }
virtual void ReadToolAttributes(const QDomElement &domElement) Q_DECL_OVERRIDE
void setCirclesCrossPoint(const CrossCirclesPoint &value)
CrossCirclesPoint crossPoint
static IntersectCirclesTool * Create(QSharedPointer< DialogTool > dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data)
virtual void SaveDialog(QDomElement &domElement) Q_DECL_OVERRIDE
SaveDialog save options into file after change in dialog.
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
QString FirstCircleCenterPointName() const
void SetSecondCircleRadius(const VFormula &value)
VFormula GetFirstCircleRadius() const
void SetFirstCircleCenterId(const quint32 &value)
VFormula GetSecondCircleRadius() const
IntersectCirclesTool(VAbstractPattern *doc, VContainer *data, const quint32 &id, const quint32 firstCircleCenterId, quint32 secondCircleCenterId, const QString &firstCircleRadius, const QString &secondCircleRadius, CrossCirclesPoint crossPoint, const Source &typeCreation, QGraphicsItem *parent=nullptr)
virtual void setDialog() Q_DECL_OVERRIDE
setDialog set dialog when user want change tool option.
quint32 GetSecondCircleCenterId() const
QString SecondCircleCenterPointName() const
virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE
virtual void showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id=NULL_ID) Q_DECL_OVERRIDE
static const QString ToolType
void SetSecondCircleCenterId(const quint32 &value)
virtual void SetVisualization() Q_DECL_OVERRIDE
CrossCirclesPoint GetCrossCirclesPoint() const
void SetFirstCircleRadius(const VFormula &value)
quint32 GetFirstCircleCenterId() const
static QPointF FindPoint(const QPointF &c1Point, const QPointF &c2Point, qreal c1Radius, qreal c2Radius, const CrossCirclesPoint crossPoint)
virtual void RemoveReferens() Q_DECL_OVERRIDE
RemoveReferens decrement value of reference.
void setC1Radius(const QString &value)
virtual void RefreshGeometry() Q_DECL_OVERRIDE
void setObject2Id(const quint32 &value)
void setCrossPoint(const CrossCirclesPoint &value)
void setC2Radius(const QString &value)
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
const VContainer * getData() const
getData return pointer to data container.
virtual void ToolCreation(const Source &typeCreation)
static void AddRecord(const quint32 id, const Tool &toolType, VAbstractPattern *doc)
AddRecord add record about tool in history.
static qreal CheckFormula(const quint32 &toolId, QString &formula, VContainer *data)
CheckFormula check formula.
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 QString GetParametrString(const QDomElement &domElement, const QString &name, const QString &defValue=QString())
Returns the string value of the given attribute. RENAME: see above.
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
bool error() const
Definition: vformula.cpp:238
qreal getDoubleValue() const
Definition: vformula.cpp:172
QString GetFormula(FormulaType type=FormulaType::ToUser) const
Definition: vformula.cpp:135
void setToolId(const quint32 &value)
Definition: vformula.cpp:216
void setCheckZero(bool value)
Definition: vformula.cpp:184
void setPostfix(const QString &value)
Definition: vformula.cpp:228
static int IntersectionCircles(const QPointF &c1, double r1, const QPointF &c2, double r2, QPointF &p1, QPointF &p2)
Definition: vgobject.cpp:342
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
The VToolSinglePoint class parent for all tools what create points.
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
void setObject1Id(const quint32 &value)
QString UnitsToStr(const Unit &unit, const bool translate)
UnitsToStr translate unit to string.
Definition: def.cpp:702
#define SCASSERT(cond)
Definition: def.h:317
@ PointOfIntersectionCircles
Source
Definition: def.h:106
const QString AttrC1Radius
Definition: ifcdef.cpp:141
const QString AttrName
Definition: ifcdef.cpp:76
const QString AttrC2Radius
Definition: ifcdef.cpp:142
const QString AttrC1Center
Definition: ifcdef.cpp:139
const QString AttrCrossPoint
Definition: ifcdef.cpp:135
const QString AttrC2Center
Definition: ifcdef.cpp:140
const QString AttrType
Definition: ifcdef.cpp:73
#define NULL_ID
Definition: ifcdef.h:76
#define NULL_ID_STR
Definition: ifcdef.h:77
Document
CrossCirclesPoint
#define qApp
Definition: vapplication.h:67