Seamly2D
Code documentation
intersect_circletangent_tool.cpp
Go to the documentation of this file.
1 /**************************************************************************
2  **
3  ** @file intersect_circletangent_tool.cpp
4  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
5  ** @date 3 6, 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 
33 
34 #include "vtoolsinglepoint.h"
35 #include "../ifc/ifcdef.h"
36 #include "../ifc/exception/vexception.h"
37 #include "../ifc/xml/vdomdocument.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_circletangent_dialog.h"
47 #include "../../../../dialogs/tools/dialogtool.h"
48 #include "../../../../visualization/visualization.h"
49 #include "../../../../visualization/line/intersect_circletangent_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 IntersectCircleTangentTool::ToolType = QStringLiteral("pointFromCircleAndTangent");
61 
62 //---------------------------------------------------------------------------------------------------------------------
64  const quint32 &id,
65  quint32 circleCenterId, const QString &circleRadius,
66  quint32 tangentPointId, CrossCirclesPoint crossPoint,
67  const Source &typeCreation, QGraphicsItem *parent)
68  : VToolSinglePoint(doc, data, id, QColor(qApp->Settings()->getPointNameColor()), parent)
69  , circleCenterId(circleCenterId)
70  , tangentPointId(tangentPointId)
71  , circleRadius(circleRadius)
72  , crossPoint(crossPoint)
73 {
74  ToolCreation(typeCreation);
75 }
76 
77 //---------------------------------------------------------------------------------------------------------------------
79 {
80  SCASSERT(not m_dialog.isNull())
82  SCASSERT(not dialogTool.isNull())
84  dialogTool->SetCircleCenterId(circleCenterId);
85  dialogTool->SetCircleRadius(circleRadius);
86  dialogTool->setCirclesCrossPoint(crossPoint);
87  dialogTool->SetTangentPointId(tangentPointId);
88  dialogTool->SetPointName(p->name());
89 }
90 
91 //---------------------------------------------------------------------------------------------------------------------
93  VMainGraphicsScene *scene,
94  VAbstractPattern *doc, VContainer *data)
95 {
96  SCASSERT(not dialog.isNull())
98  SCASSERT(not dialogTool.isNull())
99  const quint32 circleCenterId = dialogTool->GetCircleCenterId();
100  QString circleRadius = dialogTool->GetCircleRadius();
101  const quint32 tangentPointId = dialogTool->GetTangentPointId();
102  const CrossCirclesPoint pType = dialogTool->GetCrossCirclesPoint();
103  const QString pointName = dialogTool->getPointName();
105  5, 10, true, scene, doc, data, Document::FullParse, Source::FromGui);
106  if (point != nullptr)
107  {
108  point->m_dialog = dialogTool;
109  }
110  return point;
111 }
112 
113 //---------------------------------------------------------------------------------------------------------------------
114 IntersectCircleTangentTool *IntersectCircleTangentTool::Create(const quint32 _id, const QString &pointName,
115  quint32 circleCenterId, QString &circleRadius,
116  quint32 tangentPointId,
117  CrossCirclesPoint crossPoint,
118  qreal mx, qreal my,
119  bool showPointName,
120  VMainGraphicsScene *scene,
121  VAbstractPattern *doc, VContainer *data,
122  const Document &parse,
123  const Source &typeCreation)
124 {
125  const qreal radius = qApp->toPixel(CheckFormula(_id, circleRadius, data));
128 
129  const QPointF point = IntersectCircleTangentTool::FindPoint(static_cast<QPointF>(tPoint),
130  static_cast<QPointF>(cPoint), radius, crossPoint);
131 
132  if (point == QPointF())
133  {
134  const QString msg = tr("<b><big>Can't find intersection point %1 of</big></b><br>"
135  "<b><big>Circle and Tangent</big></b><br><br>"
136  "Using origin point as a place holder until pattern is corrected.")
137  .arg(pointName);
138 
139  QMessageBox msgBox(qApp->getMainWindow());
140  msgBox.setWindowTitle(tr("Intersect Circle and Tangent"));
141  msgBox.setWindowFlags(msgBox.windowFlags() & ~Qt::WindowContextHelpButtonHint);
142  msgBox.setWindowIcon(QIcon(":/toolicon/32x32/point_from_circle_and_tangent.png"));
143  msgBox.setIcon(QMessageBox::Warning);
144  msgBox.setText(msg);
145  msgBox.setStandardButtons(QMessageBox::Ok);
146  msgBox.exec();
147  }
148 
149  quint32 id = _id;
150 
151  VPointF *p = new VPointF(point, pointName, mx, my);
152  p->setShowPointName(showPointName);
153 
154  if (typeCreation == Source::FromGui)
155  {
156  id = data->AddGObject(p);
157  }
158  else
159  {
160  data->UpdateGObject(id, p);
161  if (parse != Document::FullParse)
162  {
163  doc->UpdateToolData(id, data);
164  }
165  }
166 
167  if (parse == Document::FullParse)
168  {
172  crossPoint, typeCreation);
173  scene->addItem(point);
174  InitToolConnections(scene, point);
175  VAbstractPattern::AddTool(id, point);
176  doc->IncrementReferens(cPoint.getIdTool());
177  doc->IncrementReferens(tPoint.getIdTool());
178  return point;
179  }
180  return nullptr;
181 }
182 
183 //---------------------------------------------------------------------------------------------------------------------
184 QPointF IntersectCircleTangentTool::FindPoint(const QPointF &p, const QPointF &center, qreal radius,
185  const CrossCirclesPoint crossPoint)
186 {
187  QPointF p1, p2;
188  const int res = VGObject::ContactPoints (p, center, radius, p1, p2);
189 
190  switch(res)
191  {
192  case 2:
194  {
195  return p1;
196  }
197  else
198  {
199  return p2;
200  }
201  case 1:
202  return p1;
203  case 3:
204  case 0:
205  default:
206  return QPointF();
207  }
208 }
209 
210 //---------------------------------------------------------------------------------------------------------------------
212 {
214 }
215 
216 //---------------------------------------------------------------------------------------------------------------------
218 {
220 }
221 
222 //---------------------------------------------------------------------------------------------------------------------
224 {
225  return tangentPointId;
226 }
227 
228 //---------------------------------------------------------------------------------------------------------------------
230 {
231  if (value != NULL_ID)
232  {
233  tangentPointId = value;
234 
236  SaveOption(obj);
237  }
238 }
239 
240 //---------------------------------------------------------------------------------------------------------------------
242 {
243  return circleCenterId;
244 }
245 
246 //---------------------------------------------------------------------------------------------------------------------
248 {
249  if (value != NULL_ID)
250  {
251  circleCenterId = value;
252 
254  SaveOption(obj);
255  }
256 }
257 
258 //---------------------------------------------------------------------------------------------------------------------
260 {
261  VFormula radius(circleRadius, getData());
262  radius.setCheckZero(true);
263  radius.setToolId(m_id);
264  radius.setPostfix(UnitsToStr(qApp->patternUnit()));
265  return radius;
266 }
267 
268 //---------------------------------------------------------------------------------------------------------------------
270 {
271  if (value.error() == false)
272  {
273  if (value.getDoubleValue() > 0)// Formula don't check this, but radius can't be 0 or negative
274  {
277  SaveOption(obj);
278  }
279  }
280 }
281 
282 //---------------------------------------------------------------------------------------------------------------------
284 {
285  return crossPoint;
286 }
287 
288 //---------------------------------------------------------------------------------------------------------------------
290 {
291  crossPoint = value;
292 
294  SaveOption(obj);
295 }
296 
297 //---------------------------------------------------------------------------------------------------------------------
299 {
300  ShowToolVisualization<IntersectCircleTangentVisual>(show);
301 }
302 
303 //---------------------------------------------------------------------------------------------------------------------
305 {
306  const auto circleCenter = VAbstractTool::data.GetGObject(circleCenterId);
307  const auto tangentPoint = VAbstractTool::data.GetGObject(tangentPointId);
308 
309  doc->DecrementReferens(circleCenter->getIdTool());
310  doc->DecrementReferens(tangentPoint->getIdTool());
311 }
312 
313 //---------------------------------------------------------------------------------------------------------------------
314 void IntersectCircleTangentTool::showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id)
315 {
316  try
317  {
318  ContextMenu<IntersectCircleTangentDialog>(event, id);
319  }
320  catch(const VExceptionToolWasDeleted &e)
321  {
322  Q_UNUSED(e)
323  return;//Leave this method immediately!!!
324  }
325 }
326 
327 //---------------------------------------------------------------------------------------------------------------------
328 void IntersectCircleTangentTool::SaveDialog(QDomElement &domElement)
329 {
330  SCASSERT(not m_dialog.isNull())
332  SCASSERT(not dialogTool.isNull())
333  doc->SetAttribute(domElement, AttrName, dialogTool->getPointName());
334  doc->SetAttribute(domElement, AttrCCenter, QString().setNum(dialogTool->GetCircleCenterId()));
335  doc->SetAttribute(domElement, AttrTangent, QString().setNum(dialogTool->GetTangentPointId()));
336  doc->SetAttribute(domElement, AttrCRadius, dialogTool->GetCircleRadius());
337  doc->SetAttribute(domElement, AttrCrossPoint,
338  QString().setNum(static_cast<int>(dialogTool->GetCrossCirclesPoint())));
339 }
340 
341 //---------------------------------------------------------------------------------------------------------------------
343 {
345 
350  doc->SetAttribute(tag, AttrCrossPoint, static_cast<int>(crossPoint));
351 }
352 
353 //---------------------------------------------------------------------------------------------------------------------
354 void IntersectCircleTangentTool::ReadToolAttributes(const QDomElement &domElement)
355 {
359  crossPoint = static_cast<CrossCirclesPoint>(doc->GetParametrUInt(domElement, AttrCrossPoint, "1"));
360 }
361 
362 //---------------------------------------------------------------------------------------------------------------------
364 {
365  if (not vis.isNull())
366  {
367  IntersectCircleTangentVisual *visual = qobject_cast<IntersectCircleTangentVisual *>(vis);
368  SCASSERT(visual != nullptr)
369 
370  visual->setObject1Id(tangentPointId);
371  visual->setObject2Id(circleCenterId);
372  visual->setCRadius(circleRadius);
373  visual->setCrossPoint(crossPoint);
374  visual->RefreshGeometry();
375  }
376 }
virtual void setDialog() Q_DECL_OVERRIDE
setDialog set dialog when user want change tool option.
virtual void showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id=NULL_ID) Q_DECL_OVERRIDE
void SetCircleCenterId(const quint32 &value)
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
virtual void ReadToolAttributes(const QDomElement &domElement) Q_DECL_OVERRIDE
void SetCircleRadius(const VFormula &value)
virtual void SaveDialog(QDomElement &domElement) Q_DECL_OVERRIDE
SaveDialog save options into file after change in dialog.
void SetTangentPointId(const quint32 &value)
CrossCirclesPoint GetCrossCirclesPoint() const
IntersectCircleTangentTool(VAbstractPattern *doc, VContainer *data, const quint32 &id, quint32 circleCenterId, const QString &circleRadius, quint32 tangentPointId, CrossCirclesPoint crossPoint, const Source &typeCreation, QGraphicsItem *parent=nullptr)
void setCirclesCrossPoint(const CrossCirclesPoint &value)
virtual void RemoveReferens() Q_DECL_OVERRIDE
RemoveReferens decrement value of reference.
static IntersectCircleTangentTool * Create(QSharedPointer< DialogTool > dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data)
virtual void SetVisualization() Q_DECL_OVERRIDE
static QPointF FindPoint(const QPointF &p, const QPointF &center, qreal radius, const CrossCirclesPoint crossPoint)
virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE
virtual void RefreshGeometry() Q_DECL_OVERRIDE
void setCrossPoint(const CrossCirclesPoint &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 ContactPoints(const QPointF &p, const QPointF &center, qreal radius, QPointF &p1, QPointF &p2)
Definition: vgobject.cpp:286
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
@ PointFromCircleAndTangent
Source
Definition: def.h:106
const QString AttrName
Definition: ifcdef.cpp:76
const QString AttrCrossPoint
Definition: ifcdef.cpp:135
const QString AttrTangent
Definition: ifcdef.cpp:144
const QString AttrType
Definition: ifcdef.cpp:73
const QString AttrCRadius
Definition: ifcdef.cpp:145
const QString AttrCCenter
Definition: ifcdef.cpp:143
#define NULL_ID
Definition: ifcdef.h:76
#define NULL_ID_STR
Definition: ifcdef.h:77
Document
CrossCirclesPoint
#define qApp
Definition: vapplication.h:67