Seamly2D
Code documentation
vtoolsplinepath.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 vtoolsplinepath.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 "vtoolsplinepath.h"
53 
54 #include <QDomElement>
55 #include <QEvent>
56 #include <QFlags>
57 #include <QGraphicsScene>
58 #include <QGraphicsSceneHoverEvent>
59 #include <QGraphicsSceneMouseEvent>
60 #include <QGraphicsView>
61 #include <QList>
62 #include <QPen>
63 #include <QPoint>
64 #include <QRectF>
65 #include <QSharedPointer>
66 #include <QStaticStringData>
67 #include <QStringData>
68 #include <QStringDataPtr>
69 #include <QUndoStack>
70 #include <Qt>
71 #include <new>
72 
73 #include "../../../dialogs/tools/dialogtool.h"
74 #include "../../../dialogs/tools/dialogsplinepath.h"
75 #include "../../../undocommands/movesplinepath.h"
76 #include "../../../undocommands/vundocommand.h"
77 #include "../../../visualization/visualization.h"
78 #include "../../../visualization/path/vistoolsplinepath.h"
79 #include "../ifc/exception/vexception.h"
80 #include "../ifc/xml/vdomdocument.h"
81 #include "../ifc/ifcdef.h"
82 #include "../qmuparser/qmutokenparser.h"
83 #include "../vgeometry/vabstractcubicbezierpath.h"
84 #include "../vgeometry/vabstractcurve.h"
85 #include "../vgeometry/vgobject.h"
86 #include "../vgeometry/vpointf.h"
87 #include "../vgeometry/vspline.h"
88 #include "../vgeometry/vsplinepoint.h"
89 #include "../vmisc/vabstractapplication.h"
90 #include "../vmisc/vmath.h"
91 #include "../vpatterndb/vcontainer.h"
92 #include "../vwidgets/../vgeometry/vsplinepath.h"
93 #include "../vwidgets/vcontrolpointspline.h"
94 #include "../vwidgets/vmaingraphicsscene.h"
95 #include "../../vabstracttool.h"
96 #include "../vdrawtool.h"
97 #include "vabstractspline.h"
98 
99 const QString VToolSplinePath::ToolType = QStringLiteral("pathInteractive");
100 const QString VToolSplinePath::OldToolType = QStringLiteral("path");
101 
102 //---------------------------------------------------------------------------------------------------------------------
103 /**
104  * @brief VToolSplinePath constructor.
105  * @param doc dom document container.
106  * @param data container with variables.
107  * @param id object id in container.
108  * @param typeCreation way we create this tool.
109  * @param parent parent object.
110  */
111 VToolSplinePath::VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint32 id, const Source &typeCreation,
112  QGraphicsItem *parent)
113  : VAbstractSpline(doc, data, id, parent),
114  oldPosition(),
115  splIndex(-1)
116 {
118 
119  this->setFlag(QGraphicsItem::ItemIsMovable, true);
120  this->setFlag(QGraphicsItem::ItemIsFocusable, true);// For keyboard input focus
121 
123  for (qint32 i = 1; i<=splPath->CountSubSpl(); ++i)
124  {
125  const VSpline spl = splPath->GetSpline(i);
126 
127  const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula());
128  const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl.GetC1LengthFormula());
129 
130  auto *controlPoint = new VControlPointSpline(i, SplinePointPosition::FirstPoint,
131  static_cast<QPointF>(spl.GetP2()),
132  static_cast<QPointF>(spl.GetP1()),
133  freeAngle1, freeLength1, this);
134  connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this,
138  controlPoints.append(controlPoint);
139 
140  const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula());
141  const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl.GetC2LengthFormula());
142 
143  controlPoint = new VControlPointSpline(i, SplinePointPosition::LastPoint, static_cast<QPointF>(spl.GetP3()),
144  static_cast<QPointF>(spl.GetP4()), freeAngle2, freeLength2, this);
145  connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this,
149  controlPoints.append(controlPoint);
150  }
151 
153 
154  ToolCreation(typeCreation);
155 }
156 
157 //---------------------------------------------------------------------------------------------------------------------
158 /**
159  * @brief setDialog set dialog when user want change tool option.
160  */
162 {
163  SCASSERT(not m_dialog.isNull())
165  SCASSERT(not dialogTool.isNull())
167  dialogTool->SetPath(*splPath);
168  dialogTool->setLineColor(splPath->getLineColor());
169  dialogTool->setLineWeight(splPath->getLineWeight());
170  dialogTool->setPenStyle(splPath->GetPenStyle());
171 }
172 
173 //---------------------------------------------------------------------------------------------------------------------
174 /**
175  * @brief Create help create tool from GUI.
176  * @param dialog dialog.
177  * @param scene pointer to scene.
178  * @param doc dom document container.
179  * @param data container with variables.
180  */
182  VAbstractPattern *doc, VContainer *data)
183 {
184  SCASSERT(not dialog.isNull())
185  QSharedPointer<DialogSplinePath> dialogTool = dialog.objectCast<DialogSplinePath>();
186  SCASSERT(not dialogTool.isNull())
187  VSplinePath *path = new VSplinePath(dialogTool->GetPath());
188  for (qint32 i = 0; i < path->CountPoints(); ++i)
189  {
190  doc->IncrementReferens((*path)[i].P().getIdTool());
191  }
192 
193  path->setLineColor(dialogTool->getLineColor());
194  path->SetPenStyle(dialogTool->getPenStyle());
195  path->setLineWeight(dialogTool->getLineWeight());
196 
198  if (spl != nullptr)
199  {
200  spl->m_dialog = dialogTool;
201  }
202  return spl;
203 }
204 
205 //---------------------------------------------------------------------------------------------------------------------
206 /**
207  * @brief Create help create tool.
208  * @param _id tool id, 0 if tool doesn't exist yet.
209  * @param path spline path.
210  * @param scene pointer to scene.
211  * @param doc dom document container.
212  * @param data container with variables.
213  * @param parse parser file mode.
214  * @param typeCreation way we create this tool.
215  */
217  VAbstractPattern *doc, VContainer *data, const Document &parse,
218  const Source &typeCreation)
219 {
220  quint32 id = _id;
221 
222  if (typeCreation == Source::FromGui)
223  {
224  id = data->AddGObject(path);
226  }
227  else
228  {
229  data->UpdateGObject(id, path);
231  if (parse != Document::FullParse)
232  {
233  doc->UpdateToolData(id, data);
234  }
235  }
236 
237  if (parse == Document::FullParse)
238  {
240  VToolSplinePath *spl = new VToolSplinePath(doc, data, id, typeCreation);
241  scene->addItem(spl);
242  InitSplinePathToolConnections(scene, spl);
243  VAbstractPattern::AddTool(id, spl);
244  return spl;
245  }
246  return nullptr;
247 }
248 
249 //---------------------------------------------------------------------------------------------------------------------
252  const QString &color, const QString &penStyle, const QString &lineWeight,
253  quint32 duplicate, VMainGraphicsScene *scene, VAbstractPattern *doc,
254  VContainer *data, const Document &parse, const Source &typeCreation)
255 {
256  auto path = new VSplinePath();
257 
258  if (duplicate > 0)
259  {
260  path->SetDuplicate(duplicate);
261  }
262 
263  for (int i = 0; i < points.size(); ++i)
264  {
265  const qreal calcAngle1 = CheckFormula(_id, a1[i], data);
266  const qreal calcAngle2 = CheckFormula(_id, a2[i], data);
267 
268  const qreal calcLength1 = qApp->toPixel(CheckFormula(_id, l1[i], data));
269  const qreal calcLength2 = qApp->toPixel(CheckFormula(_id, l2[i], data));
270 
271  const auto p = *data->GeometricObject<VPointF>(points.at(i));
272 
273  path->append(VSplinePoint(p, calcAngle1, a1.at(i), calcAngle2, a2.at(i), calcLength1, l1.at(i), calcLength2,
274  l2.at(i)));
275  }
276 
277  path->setLineColor(color);
278  path->SetPenStyle(penStyle);
279  path->setLineWeight(lineWeight);
280 
281  return VToolSplinePath::Create(_id, path, scene, doc, data, parse, typeCreation);
282 }
283 
284 //---------------------------------------------------------------------------------------------------------------------
285 /**
286  * @brief ControlPointChangePosition handle change position control point.
287  * @param indexSpline position spline in spline list.
288  * @param position position point in spline.
289  * @param pos new position.
290  */
291 void VToolSplinePath::ControlPointChangePosition(const qint32 &indexSpline, const SplinePointPosition &position,
292  const QPointF &pos)
293 {
295  VSplinePath newSplPath = oldSplPath;
296  const VSpline spl = CorrectedSpline(newSplPath.GetSpline(indexSpline), position, pos);
297  UpdateControlPoints(spl, newSplPath, indexSpline);
298 
299  MoveSplinePath *moveSplPath = new MoveSplinePath(doc, oldSplPath, newSplPath, m_id);
301  qApp->getUndoStack()->push(moveSplPath);
302 }
303 
304 //---------------------------------------------------------------------------------------------------------------------
306 {
307  this->setFlag(QGraphicsItem::ItemIsMovable, move);
308 }
309 
310 //---------------------------------------------------------------------------------------------------------------------
311 /**
312  * @brief UpdateControlPoints update position points control points in file.
313  * @param spl spline what was changed.
314  * @param splPath spline path.
315  * @param indexSpline index spline in spline path.
316  */
317 void VToolSplinePath::UpdateControlPoints(const VSpline &spl, VSplinePath &splPath, const qint32 &indexSpline) const
318 {
319  VSplinePoint p = splPath.GetSplinePoint(indexSpline, SplinePointPosition::FirstPoint);
321  p.SetLength2(spl.GetC1Length(), spl.GetC1LengthFormula());
322  splPath.UpdatePoint(indexSpline, SplinePointPosition::FirstPoint, p);
323 
324  p = splPath.GetSplinePoint(indexSpline, SplinePointPosition::LastPoint);
325  p.SetAngle1(spl.GetEndAngle(), spl.GetEndAngleFormula());
326  p.SetLength1(spl.GetC2Length(), spl.GetC2LengthFormula());
327  splPath.UpdatePoint(indexSpline, SplinePointPosition::LastPoint, p);
328 }
329 
330 //---------------------------------------------------------------------------------------------------------------------
331 void VToolSplinePath::SetSplinePathAttributes(QDomElement &domElement, const VSplinePath &path)
332 {
333  doc->SetAttribute(domElement, AttrType, ToolType);
334 
335  if (path.GetDuplicate() > 0)
336  {
337  doc->SetAttribute(domElement, AttrDuplicate, path.GetDuplicate());
338  }
339  else
340  {
341  if (domElement.hasAttribute(AttrDuplicate))
342  {
343  domElement.removeAttribute(AttrDuplicate);
344  }
345  }
346 
347  if (domElement.hasAttribute(AttrKCurve))
348  {
349  domElement.removeAttribute(AttrKCurve);
350  }
351 
352  UpdatePathPoints(doc, domElement, path);
353 }
354 
355 //---------------------------------------------------------------------------------------------------------------------
356 /**
357  * @brief UpdatePathPoints update spline path in pattern file.
358  * @param doc dom document container.
359  * @param element tag in file.
360  * @param path spline path.
361  */
362 void VToolSplinePath::UpdatePathPoints(VAbstractPattern *doc, QDomElement &element, const VSplinePath &path)
363 {
365  for (qint32 i = 0; i < path.CountPoints(); ++i)
366  {
367  AddPathPoint(doc, element, path.at(i));
368  }
369 }
370 
371 //---------------------------------------------------------------------------------------------------------------------
373 {
375  return *splPath.data();
376 }
377 
378 //---------------------------------------------------------------------------------------------------------------------
380 {
382  QSharedPointer<VSplinePath> splinePath = qSharedPointerDynamicCast<VSplinePath>(obj);
383  *splinePath.data() = splPath;
384  SaveOption(obj);
385 }
386 
387 //---------------------------------------------------------------------------------------------------------------------
389 {
390  ShowToolVisualization<VisToolSplinePath>(show);
391 }
392 
393 //---------------------------------------------------------------------------------------------------------------------
394 /**
395  * @brief contextMenuEvent handle context menu events.
396  * @param event context menu event.
397  */
398 void VToolSplinePath::showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id)
399 {
400  Q_UNUSED(id)
401 
402  try
403  {
404  ContextMenu<DialogSplinePath>(event);
405  }
406  catch(const VExceptionToolWasDeleted &e)
407  {
408  Q_UNUSED(e)
409  return;//Leave this method immediately!!!
410  }
411 }
412 
413 //---------------------------------------------------------------------------------------------------------------------
414 /**
415  * @brief AddPathPoint write path point to pattern file.
416  * @param domElement dom element.
417  * @param splPoint spline path point.
418  */
419 void VToolSplinePath::AddPathPoint(VAbstractPattern *doc, QDomElement &domElement, const VSplinePoint &splPoint)
420 {
421  SCASSERT(doc != nullptr)
422  QDomElement pathPoint = doc->createElement(AttrPathPoint);
423 
424  doc->SetAttribute(pathPoint, AttrPSpline, splPoint.P().id());
425  doc->SetAttribute(pathPoint, AttrLength1, splPoint.Length1Formula());
426  doc->SetAttribute(pathPoint, AttrLength2, splPoint.Length2Formula());
427  doc->SetAttribute(pathPoint, AttrAngle1, splPoint.Angle1Formula());
428  doc->SetAttribute(pathPoint, AttrAngle2, splPoint.Angle2Formula());
429 
430  if (domElement.hasAttribute(AttrKAsm1))
431  {
432  domElement.removeAttribute(AttrKAsm1);
433  }
434 
435  if (domElement.hasAttribute(AttrKAsm2))
436  {
437  domElement.removeAttribute(AttrKAsm2);
438  }
439 
440  if (domElement.hasAttribute(AttrAngle))
441  {
442  domElement.removeAttribute(AttrAngle);
443  }
444 
445  domElement.appendChild(pathPoint);
446 }
447 
448 //---------------------------------------------------------------------------------------------------------------------
449 /**
450  * @brief RemoveReferens decrement value of reference.
451  */
453 {
455  for (qint32 i = 0; i < splPath->CountSubSpl(); ++i)
456  {
457  doc->DecrementReferens(splPath->at(i).P().getIdTool());
458  }
459 }
460 
461 //---------------------------------------------------------------------------------------------------------------------
462 /**
463  * @brief SaveDialog save options into file after change in dialog.
464  */
465 void VToolSplinePath::SaveDialog(QDomElement &domElement)
466 {
467  SCASSERT(not m_dialog.isNull())
469  SCASSERT(not dialogTool.isNull())
470 
471  const VSplinePath splPath = dialogTool->GetPath();
472  for (qint32 i = 1; i <= splPath.CountSubSpl(); ++i)
473  {
474  VSpline spl = splPath.GetSpline(i);
475  qint32 j = i*2;
476 
477  controlPoints[j-2]->blockSignals(true);
478  controlPoints[j-1]->blockSignals(true);
479 
480  controlPoints[j-2]->setPos(static_cast<QPointF>(spl.GetP2()));
481  controlPoints[j-1]->setPos(static_cast<QPointF>(spl.GetP3()));
482 
483  controlPoints[j-2]->blockSignals(false);
484  controlPoints[j-1]->blockSignals(false);
485  }
486 
487  doc->SetAttribute(domElement, AttrColor, dialogTool->getLineColor());
488  doc->SetAttribute(domElement, AttrPenStyle, dialogTool->getPenStyle());
489  doc->SetAttribute(domElement, AttrLineWeight, dialogTool->getLineWeight());
490  SetSplinePathAttributes(domElement, splPath);
491 }
492 
493 //---------------------------------------------------------------------------------------------------------------------
495 {
497 
498  QSharedPointer<VSplinePath> splPath = qSharedPointerDynamicCast<VSplinePath>(obj);
499  SCASSERT(splPath.isNull() == false)
500 
502 }
503 
504 //---------------------------------------------------------------------------------------------------------------------
505 void VToolSplinePath::mousePressEvent(QGraphicsSceneMouseEvent *event)
506 {
507  if (flags() & QGraphicsItem::ItemIsMovable)
508  {
509  if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
510  {
511  oldPosition = event->scenePos();
513  splIndex = splPath->Segment(oldPosition);
514  if (IsMovable(splIndex))
515  {
517  event->accept();
518  }
519  }
520  }
522 }
523 
524 //---------------------------------------------------------------------------------------------------------------------
525 void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
526 {
527  if (flags() & QGraphicsItem::ItemIsMovable)
528  {
529  if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
530  {
531  oldPosition = event->scenePos();
533  }
534  }
536 }
537 
538 //---------------------------------------------------------------------------------------------------------------------
539 void VToolSplinePath::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
540 {
541  // Don't need to check if left mouse button was pressed. According to the Qt documentation "If you do receive this
542  // event, you can be certain that this item also received a mouse press event, and that this item is the current
543  // mouse grabber.".
544 
545  if (IsMovable(splIndex))
546  {
548  VSplinePath newSplPath = oldSplPath;
549 
550  VSpline spline = newSplPath.GetSpline(splIndex);
551  const qreal t = spline.ParamT(oldPosition);
552 
553  if (qFloor(t) == -1)
554  {
555  return;
556  }
557 
558  // Magic Bezier Drag Equations follow!
559  // "weight" describes how the influence of the drag should be distributed
560  // among the handles; 0 = front handle only, 1 = back handle only.
561 
562  double weight;
563  if (t <= 1.0 / 6.0)
564  {
565  weight = 0;
566  }
567  else if (t <= 0.5)
568  {
569  weight = (pow((6 * t - 1) / 2.0, 3)) / 2;
570  }
571  else if (t <= 5.0 / 6.0)
572  {
573  weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
574  }
575  else
576  {
577  weight = 1;
578  }
579 
580  const QPointF delta = event->scenePos() - oldPosition;
581  const QPointF offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta;
582  const QPointF offset1 = (weight/(3*t*t*(1-t))) * delta;
583 
584  const QPointF p2 = static_cast<QPointF>(spline.GetP2()) + offset0;
585  const QPointF p3 = static_cast<QPointF>(spline.GetP3()) + offset1;
586 
587  oldPosition = event->scenePos(); // Now mouse here
588 
589  const VSpline spl = VSpline(spline.GetP1(), p2, p3, spline.GetP4());
590 
591  UpdateControlPoints(spl, newSplPath, splIndex);
592 
593  MoveSplinePath *moveSplPath = new MoveSplinePath(doc, oldSplPath, newSplPath, m_id);
595  qApp->getUndoStack()->push(moveSplPath);
596 
597  // Each time we move something we call recalculation scene rect. In some cases this can cause moving
598  // objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
599  static bool changeFinished = true;
600  if (changeFinished)
601  {
602  changeFinished = false;
603 
604  const QList<QGraphicsView *> viewList = scene()->views();
605  if (not viewList.isEmpty())
606  {
607  if (QGraphicsView *view = viewList.at(0))
608  {
609  VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
610  SCASSERT(currentScene)
611  const QPointF cursorPosition = currentScene->getScenePos();
612  view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
613  }
614  }
615  changeFinished = true;
616  }
617  }
618 }
619 
620 //---------------------------------------------------------------------------------------------------------------------
621 void VToolSplinePath::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
622 {
623  if (flags() & QGraphicsItem::ItemIsMovable)
624  {
625  oldPosition = event->scenePos();
627  splIndex = splPath->Segment(oldPosition);
628  if (IsMovable(splIndex))
629  {
631  }
632  }
633 
635 }
636 
637 //---------------------------------------------------------------------------------------------------------------------
638 void VToolSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
639 {
640  if (flags() & QGraphicsItem::ItemIsMovable)
641  {
642  oldPosition = event->scenePos();
643  setCursor(QCursor());
644  }
645 
647 }
648 
649 //---------------------------------------------------------------------------------------------------------------------
651 {
652  if (not vis.isNull())
653  {
654  VisToolSplinePath *visual = qobject_cast<VisToolSplinePath *>(vis);
655  SCASSERT(visual != nullptr)
656 
658  visual->setPath(*splPath.data());
659  visual->setLineStyle(lineTypeToPenStyle(splPath->GetPenStyle()));
660  visual->setLineWeight(splPath->getLineWeight());
661  visual->SetMode(Mode::Show);
662  visual->RefreshGeometry();
663  }
664 }
665 
666 //---------------------------------------------------------------------------------------------------------------------
667 bool VToolSplinePath::IsMovable(int index) const
668 {
670 
671  //index == -1 - can delete, but decided to left
672  if (index == -1 || index < 1 || index > splPath->CountSubSpl())
673  {
674  return false;
675  }
676 
677  const VSplinePoint p1 = splPath->GetSplinePoint(index, SplinePointPosition::FirstPoint);
678  const VSplinePoint p2 = splPath->GetSplinePoint(index, SplinePointPosition::LastPoint);
679 
680  return p1.IsMovable() && p2.IsMovable();
681 }
682 
683 //---------------------------------------------------------------------------------------------------------------------
685 {
686  // Very important to disable control points. Without it the pogram can't move the curve.
687  foreach (auto *point, controlPoints)
688  {
689  point->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
690  }
691 
693 
694  for (qint32 i = 1; i<=splPath->CountSubSpl(); ++i)
695  {
696  const qint32 j = i*2;
697 
698  controlPoints[j-2]->blockSignals(true);
699  controlPoints[j-1]->blockSignals(true);
700 
701  const auto spl = splPath->GetSpline(i);
702 
703  {
704  const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula());
705  const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl.GetC1LengthFormula());
706 
707  const auto splinePoint = spl.GetP1();
708  controlPoints[j-2]->refreshCtrlPoint(i, SplinePointPosition::FirstPoint, static_cast<QPointF>(spl.GetP2()),
709  static_cast<QPointF>(splinePoint), freeAngle1, freeLength1);
710  }
711 
712  {
713  const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula());
714  const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl.GetC2LengthFormula());
715 
716  const auto splinePoint = spl.GetP4();
717  controlPoints[j-1]->refreshCtrlPoint(i, SplinePointPosition::LastPoint, static_cast<QPointF>(spl.GetP3()),
718  static_cast<QPointF>(splinePoint), freeAngle2, freeLength2);
719  }
720 
721  controlPoints[j-2]->blockSignals(false);
722  controlPoints[j-1]->blockSignals(false);
723  }
724 
725  foreach (auto *point, controlPoints)
726  {
727  point->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
728  }
729 }
The DialogSplinePath class dialog for ToolSplinePath. Help create spline path and edit option.
quint32 GetDuplicate() const
virtual void LiteParseTree(const Document &parse)=0
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
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
mouseReleaseEvent handle mouse release events.
static void InitSplinePathToolConnections(VMainGraphicsScene *scene, T *tool)
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) Q_DECL_OVERRIDE
void setEnabledPoint(bool enable)
setEnabledPoint disable control points.
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
hoverEnterEvent handle hover enter events.
SceneObject sceneType
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
hoverLeaveEvent handle hover leave events.
QVector< VControlPointSpline * > controlPoints
controlPoints list pointers of control points.
void ShowHandles(bool show)
VSpline CorrectedSpline(const VSpline &spline, const SplinePointPosition &position, const QPointF &pos) const
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.
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
void AddCurveWithSegments(const QSharedPointer< VAbstractCubicBezierPath > &curve, const quint32 &id, quint32 parentId=null_id)
Definition: vcontainer.cpp:452
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
The VControlPointSpline class control spline point.
void showContextMenu(QGraphicsSceneContextMenuEvent *event)
showContextMenu emit when need show tool's context menu.
void ControlPointChangePosition(const qint32 &indexSpline, SplinePointPosition position, const QPointF &pos)
ControlPointChangePosition emit when control point change position.
void setEnabledPoint(bool enable)
setEnabledPoint disable or enable control point.
VContainer data
data container with data
Definition: vdatatool.h:84
void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const
SetAttribute set attribute in pattern file. Replace "," by ".".
Definition: vdomdocument.h:185
static void RemoveAllChildren(QDomElement &domElement)
RemoveAllChildren remove all children from file.
void SaveOption(QSharedPointer< VGObject > &obj)
Definition: vdrawtool.cpp:142
quint32 id() const
id return id object.
Definition: vgobject.cpp:205
QSharedPointer< DialogTool > m_dialog
m_dialog tool's dialog options.
The VMainGraphicsScene class main scene.
QPointF getScenePos() const
The VPointF class keep data of point.
Definition: vpointf.h:75
The VSplinePath class keep information about splinePath.
Definition: vsplinepath.h:72
const VSplinePoint & at(int indx) const
at return spline point by index.
virtual qint32 CountPoints() const Q_DECL_OVERRIDE
CountPoints return count of points.
The VSplinePoint class keep information about point in spline path. Each point have two angles and tw...
Definition: vsplinepoint.h:108
QString Length1Formula() const
void SetAngle1(const qreal &value, const QString &angle1F)
QString Angle2Formula() const
void SetLength1(const qreal &value, const QString &length1F)
QString Length2Formula() const
QString Angle1Formula() const
void SetLength2(const qreal &value, const QString &length2F)
void SetAngle2(const qreal &value, const QString &angle2F)
bool IsMovable() const
VPointF P() const
VSpline class that implements the spline.
Definition: vspline.h:75
virtual qreal GetC2Length() const Q_DECL_OVERRIDE
Definition: vspline.cpp:385
virtual VPointF GetP4() const Q_DECL_OVERRIDE
GetP4 return last spline point.
Definition: vspline.cpp:321
QString GetC1LengthFormula() const
Definition: vspline.cpp:391
virtual qreal GetStartAngle() const Q_DECL_OVERRIDE
GetAngle1 return first angle control line.
Definition: vspline.cpp:337
qreal ParamT(const QPointF &pBt) const
VSpline::ParamT calculate t coeffient that reprezent point on curve.
Definition: vspline.cpp:540
virtual VPointF GetP1() const Q_DECL_OVERRIDE
GetP1 return first spline point.
Definition: vspline.cpp:281
virtual VPointF GetP2() const Q_DECL_OVERRIDE
GetP2 return first control point.
Definition: vspline.cpp:297
QString GetStartAngleFormula() const
Definition: vspline.cpp:353
QString GetEndAngleFormula() const
Definition: vspline.cpp:359
virtual qreal GetC1Length() const Q_DECL_OVERRIDE
Definition: vspline.cpp:379
virtual VPointF GetP3() const Q_DECL_OVERRIDE
GetP3 return second control point.
Definition: vspline.cpp:309
QString GetC2LengthFormula() const
Definition: vspline.cpp:397
virtual qreal GetEndAngle() const Q_DECL_OVERRIDE
GetAngle2 return second angle control line.
Definition: vspline.cpp:347
The VToolSplinePath class tool for creation spline path.
static void AddPathPoint(VAbstractPattern *doc, QDomElement &domElement, const VSplinePoint &splPoint)
AddPathPoint write path point to pattern file.
virtual void SaveDialog(QDomElement &domElement) Q_DECL_OVERRIDE
SaveDialog save options into file after change in dialog.
virtual void setDialog() Q_DECL_OVERRIDE
setDialog set dialog when user want change tool option.
static VToolSplinePath * Create(QSharedPointer< DialogTool > dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data)
Create help create tool from GUI.
virtual void SetVisualization() Q_DECL_OVERRIDE
static void UpdatePathPoints(VAbstractPattern *doc, QDomElement &element, const VSplinePath &path)
UpdatePathPoints update spline path in pattern file.
void SetSplinePathAttributes(QDomElement &domElement, const VSplinePath &path)
virtual void SaveOptions(QDomElement &tag, QSharedPointer< VGObject > &obj) Q_DECL_OVERRIDE
static const QString ToolType
virtual void showContextMenu(QGraphicsSceneContextMenuEvent *event, quint32 id=NULL_ID) Q_DECL_OVERRIDE
contextMenuEvent handle context menu events.
static const QString OldToolType
virtual void EnableToolMove(bool move) Q_DECL_OVERRIDE
void UpdateControlPoints(const VSpline &spl, VSplinePath &splPath, const qint32 &indexSpline) const
UpdateControlPoints update position points control points in file.
virtual void ShowVisualization(bool show) Q_DECL_OVERRIDE
virtual void refreshCtrlPoints() Q_DECL_OVERRIDE
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint32 id, const Source &typeCreation, QGraphicsItem *parent=nullptr)
VToolSplinePath constructor.
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
mouseReleaseEvent handle mouse release events.
void setSplinePath(const VSplinePath &splPath)
void ControlPointChangePosition(const qint32 &indexSpline, const SplinePointPosition &position, const QPointF &pos)
ControlPointChangePosition handle change position control point.
bool IsMovable(int index) const
VSplinePath getSplinePath() const
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
hoverLeaveEvent handle hover leave events.
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) Q_DECL_OVERRIDE
hoverEnterEvent handle hover enter events.
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE
virtual void RemoveReferens() Q_DECL_OVERRIDE
RemoveReferens decrement value of reference.
void NeedLiteParsing(const Document &parse)
void setPath(const VSplinePath &value)
virtual void RefreshGeometry() Q_DECL_OVERRIDE
void setLineWeight(const QString &value)
void SetMode(const Mode &value)
void setLineStyle(const Qt::PenStyle &value)
static bool IsSingle(const QString &formula)
IsSingle test formula and return true if it contain only one number.
const QString cursorArrowOpenHand
Definition: def.cpp:191
void SetItemOverrideCursor(QGraphicsItem *item, const QString &pixmapPath, int hotX, int hotY)
Definition: def.cpp:206
const QString cursorArrowCloseHand
Definition: def.cpp:192
#define SCASSERT(cond)
Definition: def.h:317
@ SplinePath
Source
Definition: def.h:106
const QString AttrKAsm2
Definition: ifcdef.cpp:120
const QString splPath
Definition: ifcdef.cpp:419
const QString AttrDuplicate
Definition: ifcdef.cpp:122
const QString AttrLineWeight
Definition: ifcdef.cpp:91
const QString AttrPSpline
Definition: ifcdef.cpp:124
const QString AttrPenStyle
Definition: ifcdef.cpp:132
const QString AttrAngle
Definition: ifcdef.cpp:103
const QString AttrLength2
Definition: ifcdef.cpp:107
const QString AttrLength1
Definition: ifcdef.cpp:106
const QString AttrKCurve
Definition: ifcdef.cpp:121
const QString AttrType
Definition: ifcdef.cpp:73
const QString AttrAngle2
Definition: ifcdef.cpp:105
const QString AttrPathPoint
Definition: ifcdef.cpp:123
const QString AttrColor
Definition: ifcdef.cpp:131
Qt::PenStyle lineTypeToPenStyle(const QString &lineType)
LineStyle return pen style for current line style.
Definition: ifcdef.cpp:183
const QString AttrAngle1
Definition: ifcdef.cpp:104
const QString AttrKAsm1
Definition: ifcdef.cpp:119
Document
#define qApp
Definition: vapplication.h:67
SplinePointPosition
Definition: vgeometrydef.h:58