From e68c64e8f1856491eb80e11a390d5eebb5a69193 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sat, 13 Feb 2016 18:24:32 +0200 Subject: [PATCH] Implementation for tool Spline path. --HG-- branch : feature --- .../vtools/dialogs/tools/dialogsplinepath.cpp | 9 +- .../visualization/vistoolsplinepath.cpp | 213 +++++++++++++++--- .../vtools/visualization/vistoolsplinepath.h | 16 +- 3 files changed, 203 insertions(+), 35 deletions(-) diff --git a/src/libs/vtools/dialogs/tools/dialogsplinepath.cpp b/src/libs/vtools/dialogs/tools/dialogsplinepath.cpp index 2bb688d12..f53504de0 100644 --- a/src/libs/vtools/dialogs/tools/dialogsplinepath.cpp +++ b/src/libs/vtools/dialogs/tools/dialogsplinepath.cpp @@ -61,6 +61,13 @@ DialogSplinePath::DialogSplinePath(const VContainer *data, const quint32 &toolId this, &DialogSplinePath::KAsm2Changed); vis = new VisToolSplinePath(data); + auto path = qobject_cast(vis); + SCASSERT(path != nullptr); + + auto scene = qobject_cast(qApp->getCurrentScene()); + SCASSERT(scene != nullptr); + connect(scene, &VMainGraphicsScene::MouseLeftPressed, path, &VisToolSplinePath::MouseLeftPressed); + connect(scene, &VMainGraphicsScene::MouseLeftReleased, path, &VisToolSplinePath::MouseLeftReleased); } //--------------------------------------------------------------------------------------------------------------------- @@ -126,7 +133,7 @@ void DialogSplinePath::ChosenObject(quint32 id, const SceneObject &type) SavePath(); - VisToolSplinePath *visPath = qobject_cast(vis); + auto visPath = qobject_cast(vis); SCASSERT(visPath != nullptr); visPath->setPath(path); diff --git a/src/libs/vtools/visualization/vistoolsplinepath.cpp b/src/libs/vtools/visualization/vistoolsplinepath.cpp index 0e1af6107..3618257d9 100644 --- a/src/libs/vtools/visualization/vistoolsplinepath.cpp +++ b/src/libs/vtools/visualization/vistoolsplinepath.cpp @@ -27,18 +27,27 @@ *************************************************************************/ #include "vistoolsplinepath.h" +#include "../vwidgets/vcontrolpointspline.h" //--------------------------------------------------------------------------------------------------------------------- VisToolSplinePath::VisToolSplinePath(const VContainer *data, QGraphicsItem *parent) - : VisPath(data, parent), points(QVector()), line(nullptr), path(VSplinePath()) + : VisPath(data, parent), + points(QVector()), + ctrlPoints(QVector()), + newCurveSegment(nullptr), + path(VSplinePath()), + isLeftMousePressed(false), + pointSelected(false), + ctrlPoint() { - line = InitItem(mainColor, this); + newCurveSegment = InitItem(mainColor, this); } //--------------------------------------------------------------------------------------------------------------------- VisToolSplinePath::~VisToolSplinePath() { - qDeleteAll(points.begin(), points.end()); + qDeleteAll(ctrlPoints); + qDeleteAll(points); } //--------------------------------------------------------------------------------------------------------------------- @@ -46,41 +55,25 @@ void VisToolSplinePath::RefreshGeometry() { if (path.CountPoint() > 0) { - QVector pathPoints = path.GetSplinePath(); - if (path.CountPoint() == 1) + const QVector pathPoints = path.GetSplinePath(); + const int size = pathPoints.size(); + + for (int i = 0; i < size; ++i) { - QGraphicsEllipseItem *point = this->getPoint(0); - DrawPoint(point, pathPoints.at(0).P().toQPointF(), supportColor); - - if (mode == Mode::Creation) - { - QLineF sceneLine = QLineF(pathPoints.at(0).P().toQPointF(), Visualization::scenePos); - DrawLine(line, sceneLine, mainColor, lineStyle); - - path[0].SetAngle2(sceneLine.angle()); - emit PathChanged(path); - } + QGraphicsEllipseItem *point = this->getPoint(static_cast(i)); + DrawPoint(point, pathPoints.at(i).P().toQPointF(), supportColor); } - else + + if (mode == Mode::Creation) { - for (int i = 0; i < pathPoints.size(); ++i) - { - QGraphicsEllipseItem *point = this->getPoint(static_cast(i)); - DrawPoint(point, pathPoints.at(i).P().toQPointF(), supportColor); - } - - if (mode == Mode::Creation) - { - QLineF sceneLine = QLineF(pathPoints.at(pathPoints.size() - 1).P().toQPointF(), - Visualization::scenePos); - DrawLine(line, sceneLine, mainColor, lineStyle); - - path[pathPoints.size() - 1].SetAngle2(sceneLine.angle()); - emit PathChanged(path); - } + Creating(pathPoints.at(size-1).P().toQPointF(), size); + } + if (size > 1) + { DrawPath(this, path.GetPath(PathDirection::Show), mainColor, Qt::SolidLine, Qt::RoundCap); } + if (path.CountPoint() < 3) { Visualization::toolTip = tr("Curved path: select three or more points"); @@ -106,6 +99,25 @@ VSplinePath VisToolSplinePath::getPath() return path; } +//--------------------------------------------------------------------------------------------------------------------- +void VisToolSplinePath::MouseLeftPressed() +{ + if (mode == Mode::Creation) + { + isLeftMousePressed = true; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolSplinePath::MouseLeftReleased() +{ + if (mode == Mode::Creation) + { + isLeftMousePressed = false; + RefreshGeometry(); + } +} + //--------------------------------------------------------------------------------------------------------------------- QGraphicsEllipseItem *VisToolSplinePath::getPoint(quint32 i) { @@ -115,9 +127,144 @@ QGraphicsEllipseItem *VisToolSplinePath::getPoint(quint32 i) } else { - QGraphicsEllipseItem * point = InitPoint(supportColor, this); + pointSelected = false; + + auto point = InitPoint(supportColor, this); points.append(point); + + if (points.size() == 1) + { + auto *controlPoint1 = new VControlPointSpline(points.size(), SplinePointPosition::FirstPoint, + *Visualization::data->GetPatternUnit(), + this); + controlPoint1->hide(); + ctrlPoints.append(controlPoint1); + } + else + { + auto *controlPoint1 = new VControlPointSpline(points.size()-1, SplinePointPosition::LastPoint, + *Visualization::data->GetPatternUnit(), + this); + controlPoint1->hide(); + ctrlPoints.append(controlPoint1); + + auto *controlPoint2 = new VControlPointSpline(points.size(), SplinePointPosition::FirstPoint, + *Visualization::data->GetPatternUnit(), + this); + controlPoint2->hide(); + ctrlPoints.append(controlPoint2); + } + return point; } return nullptr; } + +//--------------------------------------------------------------------------------------------------------------------- +QSharedPointer VisToolSplinePath::NewCurveSegmen(const QPointF &pSpl, int size) +{ + auto spline = QSharedPointer(new VSpline(VPointF(pSpl), ctrlPoint, Visualization::scenePos, + VPointF(Visualization::scenePos), path.GetKCurve())); + + if (size == 1) + { + path[size-1].SetAngle2(spline->GetStartAngle()); + path[size-1].SetKAsm2(spline->GetKasm1()); + emit PathChanged(path); + } + else + { + path[size-1].SetAngle2(spline->GetStartAngle()); + path[size-1].SetKAsm1(spline->GetKasm1()); + path[size-1].SetKAsm2(spline->GetKasm1()); + emit PathChanged(path); + } + + return spline; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolSplinePath::Creating(const QPointF &pSpl, int size) +{ + //Radius of point circle, but little bigger. Need handle with hover sizes. + const static qreal radius = ToPixel(DefPointRadius/*mm*/, Unit::Mm)*1.5; + + int lastPoint = 0; + int preLastPoint = 0; + + if (size > 1) + { + lastPoint = (size - 1) * 2; + preLastPoint = lastPoint - 1; + } + + if (isLeftMousePressed && not pointSelected) + { + newCurveSegment->hide(); + + ctrlPoint = Visualization::scenePos; + + if (not ctrlPoints[lastPoint]->isVisible()) + { + if (QLineF(pSpl, ctrlPoint).length() > radius) + { + if (size == 1) + { + ctrlPoints[lastPoint]->show(); + } + else + { + ctrlPoints[preLastPoint]->show(); + ctrlPoints[lastPoint]->show(); + } + } + else + { + ctrlPoint = pSpl; + } + } + + if (size == 1) + { + ctrlPoints[lastPoint]->RefreshCtrlPoint(size, SplinePointPosition::FirstPoint, ctrlPoint, pSpl); + } + else + { + QLineF ctrlLine (pSpl, Visualization::scenePos); + ctrlLine.setAngle(ctrlLine.angle()+180); + + ctrlPoints[preLastPoint]->RefreshCtrlPoint(size-1, SplinePointPosition::LastPoint, ctrlLine.p2(), pSpl); + ctrlPoints[lastPoint]->RefreshCtrlPoint(size, SplinePointPosition::FirstPoint, ctrlPoint, pSpl); + } + + VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos, + VPointF(Visualization::scenePos), path.GetKCurve()); + + if (size == 1) + { + path[size-1].SetAngle2(spline.GetStartAngle()); + path[size-1].SetKAsm2(spline.GetKasm1()); + emit PathChanged(path); + } + else + { + path[size-1].SetAngle2(spline.GetStartAngle()); + path[size-1].SetKAsm1(spline.GetKasm1()); + path[size-1].SetKAsm2(spline.GetKasm1()); + emit PathChanged(path); + } + } + else + { + pointSelected = true; + + VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos, + VPointF(Visualization::scenePos), path.GetKCurve()); + + path[size-1].SetAngle2(spline.GetStartAngle()); + path[size-1].SetKAsm2(spline.GetKasm1()); + emit PathChanged(path); + + DrawPath(newCurveSegment, spline.GetPath(PathDirection::Hide), mainColor, Qt::SolidLine, Qt::RoundCap); + } +} diff --git a/src/libs/vtools/visualization/vistoolsplinepath.h b/src/libs/vtools/visualization/vistoolsplinepath.h index d37178326..309f57127 100644 --- a/src/libs/vtools/visualization/vistoolsplinepath.h +++ b/src/libs/vtools/visualization/vistoolsplinepath.h @@ -32,6 +32,8 @@ #include "vispath.h" #include "../../vgeometry/vsplinepath.h" +class VControlPointSpline; + class VisToolSplinePath : public VisPath { Q_OBJECT @@ -50,13 +52,25 @@ public: signals: void PathChanged(const VSplinePath &path); +public slots: + void MouseLeftPressed(); + void MouseLeftReleased(); + protected: Q_DISABLE_COPY(VisToolSplinePath) QVector points; - QGraphicsLineItem *line; + QVector ctrlPoints; + QGraphicsPathItem *newCurveSegment; VSplinePath path; + bool isLeftMousePressed; + bool pointSelected; + + QPointF ctrlPoint; + QGraphicsEllipseItem * getPoint(quint32 i); + QSharedPointer NewCurveSegmen(const QPointF &pSpl, int size); + void Creating(const QPointF &pSpl, int size); }; #endif // VISTOOLSPLINEPATH_H