From 309f1909219419697d78a50b70cabb75365ec88a Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 9 Aug 2013 09:49:34 +0300 Subject: [PATCH] Add tool splinepath --- Valentina.pro | 15 +- container/calculator.cpp | 2 +- container/vcontainer.cpp | 42 +++ container/vcontainer.h | 7 + cursor.qrc | 1 + cursor/splinepath_cursor.png | Bin 0 -> 1279 bytes dialogs/dialogsplinepath.cpp | 179 ++++++++++++ dialogs/dialogsplinepath.h | 38 +++ dialogs/dialogsplinepath.ui | 219 ++++++++++++++ geometry/vsplinepath.cpp | 116 ++++++++ geometry/vsplinepath.h | 61 ++++ geometry/vsplinepoint.cpp | 61 ++++ geometry/vsplinepoint.h | 75 +++++ icon.qrc | 1 + icon/32x32/splinePath.png | Bin 0 -> 771 bytes mainwindow.cpp | 42 ++- mainwindow.h | 7 +- mainwindow.ui | 25 +- options.h | 3 +- tools/vtoolspline.cpp | 84 +++--- tools/vtoolspline.h | 37 ++- tools/vtoolsplinepath.cpp | 243 ++++++++++++++++ tools/vtoolsplinepath.h | 45 +++ widgets/vcontrolpointspline.cpp | 37 ++- widgets/vcontrolpointspline.h | 34 ++- xml/vdomdocument.cpp | 499 +++++++++++++++++--------------- 26 files changed, 1542 insertions(+), 331 deletions(-) create mode 100644 cursor/splinepath_cursor.png create mode 100644 dialogs/dialogsplinepath.cpp create mode 100644 dialogs/dialogsplinepath.h create mode 100644 dialogs/dialogsplinepath.ui create mode 100644 geometry/vsplinepath.cpp create mode 100644 geometry/vsplinepath.h create mode 100644 geometry/vsplinepoint.cpp create mode 100644 geometry/vsplinepoint.h create mode 100644 icon/32x32/splinePath.png create mode 100644 tools/vtoolsplinepath.cpp create mode 100644 tools/vtoolsplinepath.h diff --git a/Valentina.pro b/Valentina.pro index 28883567a..7a14b0eba 100644 --- a/Valentina.pro +++ b/Valentina.pro @@ -50,7 +50,11 @@ SOURCES += main.cpp\ tools/vtoolspline.cpp \ dialogs/dialogspline.cpp \ tools/vtoolarc.cpp \ - dialogs/dialogarc.cpp + dialogs/dialogarc.cpp \ + geometry/vsplinepoint.cpp \ + geometry/vsplinepath.cpp \ + tools/vtoolsplinepath.cpp \ + dialogs/dialogsplinepath.cpp HEADERS += mainwindow.h \ widgets/vmaingraphicsscene.h \ @@ -91,7 +95,11 @@ HEADERS += mainwindow.h \ tools/vtoolspline.h \ dialogs/dialogspline.h \ tools/vtoolarc.h \ - dialogs/dialogarc.h + dialogs/dialogarc.h \ + geometry/vsplinepoint.h \ + geometry/vsplinepath.h \ + tools/vtoolsplinepath.h \ + dialogs/dialogsplinepath.h FORMS += mainwindow.ui \ dialogs/dialogsinglepoint.ui \ @@ -104,7 +112,8 @@ FORMS += mainwindow.ui \ dialogs/dialogbisector.ui \ dialogs/dialoglineintersect.ui \ dialogs/dialogspline.ui \ - dialogs/dialogarc.ui + dialogs/dialogarc.ui \ + dialogs/dialogsplinepath.ui RESOURCES += \ icon.qrc \ diff --git a/container/calculator.cpp b/container/calculator.cpp index 4bd9e6e8c..8141059fb 100644 --- a/container/calculator.cpp +++ b/container/calculator.cpp @@ -89,7 +89,7 @@ void Calculator::level5(qreal *result){ QChar op; op = '\0'; - if((token_type==DELIMITER) && token[0]=='+' || token[0]=='-') { + if((token_type==DELIMITER) && (token[0]=='+' || token[0]=='-')) { op = token[0]; get_token(); } diff --git a/container/vcontainer.cpp b/container/vcontainer.cpp index 99e53fc76..79f7218bd 100644 --- a/container/vcontainer.cpp +++ b/container/vcontainer.cpp @@ -80,6 +80,13 @@ void VContainer::UpdateSpline(qint64 id, const VSpline &spl){ } } +void VContainer::UpdateSplinePath(qint64 id, const VSplinePath &splPath){ + splinePaths[id] = splPath; + if(id > _id){ + _id = id; + } +} + void VContainer::UpdateArc(qint64 id, const VArc &arc){ arcs[id] = arc; if(id > _id){ @@ -238,6 +245,12 @@ qint64 VContainer::AddSpline(const VSpline &spl){ return id; } +qint64 VContainer::AddSplinePath(const VSplinePath &splPath){ + qint64 id = getNextId(); + splinePaths[id] = splPath; + return id; +} + qint64 VContainer::AddArc(const VArc &arc){ qint64 id = getNextId(); arcs[id] = arc; @@ -262,6 +275,21 @@ QString VContainer::GetNameSpline(const qint64 &firstPoint, const qint64 &second return QString("Spl_%1_%2").arg(first.name(), second.name()); } +QString VContainer::GetNameSplinePath(const VSplinePath &path) const{ + if(path.Count() == 0){ + return QString(); + } + QString name("SplPath"); + for(qint32 i = 1; i <= path.Count(); ++i){ + VSpline spl = path.GetSpline(i); + VPointF first = GetPoint(spl.GetP1()); + VPointF second = GetPoint(spl.GetP4()); + QString splName = QString("_%1_%2").arg(first.name(), second.name()); + name.append(splName); + } + return name; +} + QString VContainer::GetNameArc(const qint64 ¢er, const qint64 &id) const{ VPointF centerPoint = GetPoint(center); return QString ("Arc(%1)%2").arg(centerPoint.name(), id); @@ -340,6 +368,16 @@ VArc VContainer::GetArc(qint64 id) const{ return VArc(); } +VSplinePath VContainer::GetSplinePath(qint64 id) const{ + if(splinePaths.contains(id)){ + return splinePaths.value(id); + } else { + qCritical()<<"Не можу знайти id = "< *VContainer::DataLengthArcs() const{ return &lengthArcs; @@ -348,3 +386,7 @@ const QMap *VContainer::DataLengthArcs() const{ const QMap *VContainer::DataLineArcs() const{ return &lineArcs; } + +const QMap *VContainer::DataSplinePaths() const{ + return &splinePaths; +} diff --git a/container/vcontainer.h b/container/vcontainer.h index 0be810f59..0ee302208 100644 --- a/container/vcontainer.h +++ b/container/vcontainer.h @@ -8,6 +8,7 @@ #include "vincrementtablerow.h" #include "../geometry/vspline.h" #include "../geometry/varc.h" +#include "../geometry/vsplinepath.h" /** * @brief The VContainer class @@ -31,6 +32,7 @@ public: qint32 GetLineArc(const QString &name) const; VSpline GetSpline(qint64 id) const; VArc GetArc(qint64 id) const; + VSplinePath GetSplinePath(qint64 id) const; qint64 getId(); qint64 AddPoint(const VPointF& point); void AddStandartTableCell(const QString& name, const VStandartTableCell& cell); @@ -43,13 +45,16 @@ public: void AddLineArc(const QString &name, const qint32 &value); void AddLine(const qint64 &firstPointId, const qint64 &secondPointId); qint64 AddSpline(const VSpline& spl); + qint64 AddSplinePath(const VSplinePath& splPath); qint64 AddArc(const VArc& arc); QString GetNameLine(const qint64 &firstPoint, const qint64 &secondPoint) const; QString GetNameLineArc(const qint64 &firstPoint, const qint64 &secondPoint) const; QString GetNameSpline(const qint64 &firstPoint, const qint64 &secondPoint) const; + QString GetNameSplinePath(const VSplinePath &path) const; QString GetNameArc(const qint64 ¢er, const qint64 &id) const; void UpdatePoint(qint64 id, const VPointF& point); void UpdateSpline(qint64 id, const VSpline& spl); + void UpdateSplinePath(qint64 id, const VSplinePath& splPath); void UpdateArc(qint64 id, const VArc& arc); void UpdateStandartTableCell(const QString& name, const VStandartTableCell& cell); void UpdateIncrementTableRow(const QString& name, const VIncrementTableRow& cell); @@ -79,6 +84,7 @@ public: const QMap *DataLengthSplines() const; const QMap *DataLengthArcs() const; const QMap *DataLineArcs() const; + const QMap *DataSplinePaths() const; private: qint64 _id; QMap base; @@ -91,6 +97,7 @@ private: QMap lengthSplines; QMap arcs; QMap lengthArcs; + QMap splinePaths; }; #endif // VCONTAINER_H diff --git a/cursor.qrc b/cursor.qrc index afd4b988a..3d19a93e9 100644 --- a/cursor.qrc +++ b/cursor.qrc @@ -10,5 +10,6 @@ cursor/intersect_cursor.png cursor/spline_cursor.png cursor/arc_cursor.png + cursor/splinepath_cursor.png diff --git a/cursor/splinepath_cursor.png b/cursor/splinepath_cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..26bb8a7abca9acd6a6819c97d9145ed89d98b5d3 GIT binary patch literal 1279 zcmVVl&|00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru-3SK=C?(gK{d@ob06}y` zSad^gZEa<4bO1wAML|?gQaT`KWG!lNWoICEF)lD5D0OpbZf77#N=G0{P(?=|b~Z98 zEFf`pVQgu1c_2L?IWP*aMOc#n00citL_t(Y$HkXlOj~sn$3MS&Z^I}nYpa9~nVVBV z4eiF#hmk-Qfn_pTHc$)?q9!DUCdgna$y}mNjaxKod^7QdWSS8ejt70>Vb&}Glf~&0 zh>PH#De9Q8&H&1Kdyfy?+qC1)nvCK}eo247{(8?j-|zRFa|{2c9Xoa`ZQt73s@64t zuCA_Mg2ABF*Vl`PJiM;X>+0$*0a8*@BB|#WE?mf}Ujx7}3;0lUN`7_%Ieq#xN+}5h0#Z>? z;m#W84&SM!l)^9!M1i(fiMxJLjpYs+z2+skwGXf?E#yz5|W} zhk-KSdRpWM4<1a;b3imrOO{weL&NRL$phr2aj9udz~6u`1>w(uKUd`3vMe-BOHMRL zSpEI|tBuq*fY)s}o#%XQ2es$aC#PtAK4Jo0KmqVnd*@3_Id`B2Xm4-7TvSwa#_#u! zG&MD?Hd4O?P5^HKH|(=3z^lO7mZw`vfgkMk74YWF%=Nw{umj?9xdf1-M~|M#u=*YX zEMPm}20ThBFW?701Ab3s7>EHI+YcXEgxwYkKA%t8+S(?8&Uifj@d~A>*@(I9H4B*b znE*FMWY%`lY4iU0t{oxl>^A`0LZR}-C)U>1UIL`7tZX%L>8ZS?nBUGW`L36j=cYVZ zihciA;I*w=?g8)uabR!cg_jpIHw@zy;F;0U(UyxBFYaF^TLmPX`n<&!fFFTM=isru zk7AmMwBJr$n`Y~lqL_U@G(UUewtVUtw%`x#x(48#6K}Jtti;hn9N3eSlgs8nA$HAA z0ncd}wBJm|<`+N-@GQX2@^Uuc8^BilA3m=)>e=YVla~u{68IFTyWOkM2H@WeRe#cM zr+)$803o0dc<_setupUi(this); + bOk = ui->buttonBox->button(QDialogButtonBox::Ok); + connect(bOk, &QPushButton::clicked, this, &DialogSplinePath::DialogAccepted); + + QPushButton *bCansel = ui->buttonBox->button(QDialogButtonBox::Cancel); + connect(bCansel, &QPushButton::clicked, this, &DialogSplinePath::DialogRejected); + FillComboBoxPoints(ui->comboBoxPoint); + + path = VSplinePath(data->DataPoints()); + + connect(ui->listWidget, &QListWidget::currentRowChanged, this, &DialogSplinePath::PointChenged); + connect(ui->comboBoxPoint, static_cast(&QComboBox::currentIndexChanged), + this, &DialogSplinePath::currentPointChanged); + connect(ui->spinBoxAngle1, static_cast(&QSpinBox::valueChanged), + this, &DialogSplinePath::Angle1Changed); + connect(ui->spinBoxAngle2, static_cast(&QSpinBox::valueChanged), + this, &DialogSplinePath::Angle2Changed); + connect(ui->doubleSpinBoxKasm1, static_cast(&QDoubleSpinBox::valueChanged), + this, &DialogSplinePath::KAsm1Changed); + connect(ui->doubleSpinBoxKasm2, static_cast(&QDoubleSpinBox::valueChanged), + this, &DialogSplinePath::KAsm2Changed); +} + +DialogSplinePath::~DialogSplinePath() +{ + delete ui; +} + +VSplinePath DialogSplinePath::GetPath() const{ + return path; +} + +void DialogSplinePath::SetPath(const VSplinePath &value){ + this->path = value; + ui->listWidget->clear(); + for(qint32 i = 0; i < path.CountPoint(); ++i){ + NewItem(path[i].P(), path[i].KAsm1(), path[i].Angle2(), path[i].KAsm2()); + } + ui->listWidget->setFocus(Qt::OtherFocusReason); + ui->doubleSpinBoxKcurve->setValue(path.getKCurve()); +} + + +void DialogSplinePath::ChoosedObject(qint64 id, Scene::Type type){ + if(type == Scene::Point){ + NewItem(id, 1, 0, 1); + this->show(); + } +} + +void DialogSplinePath::DialogAccepted(){ + path.Clear(); + for(qint32 i = 0; i < ui->listWidget->count(); ++i){ + QListWidgetItem *item = ui->listWidget->item(i); + path.append( qvariant_cast(item->data(Qt::UserRole))); + } + path.setKCurve(ui->doubleSpinBoxKcurve->value()); + emit DialogClosed(QDialog::Accepted); +} + +void DialogSplinePath::PointChenged(int row){ + if(ui->listWidget->count() == 0){ + return; + } + QListWidgetItem *item = ui->listWidget->item( row ); + VSplinePoint p = qvariant_cast(item->data(Qt::UserRole)); + DataPoint(p.P(), p.KAsm1(), p.Angle1(), p.KAsm2(), p.Angle2()); + EnableFields(); +} + +void DialogSplinePath::currentPointChanged(int index){ + qint64 id = qvariant_cast(ui->comboBoxPoint->itemData(index)); + qint32 row = ui->listWidget->currentRow(); + QListWidgetItem *item = ui->listWidget->item( row ); + VSplinePoint p = qvariant_cast(item->data(Qt::UserRole)); + p.SetP(id); + DataPoint(p.P(), p.KAsm1(), p.Angle1(), p.KAsm2(), p.Angle2()); + EnableFields(); + item->setData(Qt::UserRole, QVariant::fromValue(p)); +} + +void DialogSplinePath::Angle1Changed(int index){ + SetAngle(index+180); +} + +void DialogSplinePath::Angle2Changed(int index){ + SetAngle(index); +} + +void DialogSplinePath::KAsm1Changed(qreal d){ + qint32 row = ui->listWidget->currentRow(); + QListWidgetItem *item = ui->listWidget->item( row ); + VSplinePoint p = qvariant_cast(item->data(Qt::UserRole)); + p.SetKAsm1(d); + item->setData(Qt::UserRole, QVariant::fromValue(p)); +} + +void DialogSplinePath::KAsm2Changed(qreal d){ + qint32 row = ui->listWidget->currentRow(); + QListWidgetItem *item = ui->listWidget->item( row ); + VSplinePoint p = qvariant_cast(item->data(Qt::UserRole)); + p.SetKAsm2(d); + item->setData(Qt::UserRole, QVariant::fromValue(p)); +} + +void DialogSplinePath::NewItem(qint64 id, qreal kAsm1, qreal angle, qreal kAsm2){ + VPointF point = data->GetPoint(id); + QListWidgetItem *item = new QListWidgetItem(point.name()); + item->setFont(QFont("Times", 12, QFont::Bold)); + VSplinePoint p(id, kAsm1, angle, kAsm2); + DataPoint(id, kAsm1, angle+180, kAsm2, angle); + item->setData(Qt::UserRole, QVariant::fromValue(p)); + ui->listWidget->addItem(item); + EnableFields(); +} + +void DialogSplinePath::DataPoint(qint64 id, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2){ + disconnect(ui->comboBoxPoint, static_cast(&QComboBox::currentIndexChanged), + this, &DialogSplinePath::currentPointChanged); + disconnect(ui->spinBoxAngle1, static_cast(&QSpinBox::valueChanged), + this, &DialogSplinePath::Angle1Changed); + disconnect(ui->spinBoxAngle2, static_cast(&QSpinBox::valueChanged), + this, &DialogSplinePath::Angle2Changed); + disconnect(ui->doubleSpinBoxKasm1, static_cast(&QDoubleSpinBox::valueChanged), + this, &DialogSplinePath::KAsm1Changed); + disconnect(ui->doubleSpinBoxKasm2, static_cast(&QDoubleSpinBox::valueChanged), + this, &DialogSplinePath::KAsm2Changed); + + ChangeCurrentData(ui->comboBoxPoint, id); + ui->doubleSpinBoxKasm1->setValue(kAsm1); + ui->doubleSpinBoxKasm2->setValue(kAsm2); + ui->spinBoxAngle2->setValue(angle2); + ui->spinBoxAngle1->setValue(angle1); + + connect(ui->comboBoxPoint, static_cast(&QComboBox::currentIndexChanged), + this, &DialogSplinePath::currentPointChanged); + connect(ui->spinBoxAngle1, static_cast(&QSpinBox::valueChanged), + this, &DialogSplinePath::Angle1Changed); + connect(ui->spinBoxAngle2, static_cast(&QSpinBox::valueChanged), + this, &DialogSplinePath::Angle2Changed); + connect(ui->doubleSpinBoxKasm1, static_cast(&QDoubleSpinBox::valueChanged), + this, &DialogSplinePath::KAsm1Changed); + connect(ui->doubleSpinBoxKasm2, static_cast(&QDoubleSpinBox::valueChanged), + this, &DialogSplinePath::KAsm2Changed); +} + +void DialogSplinePath::EnableFields(){ + ui->doubleSpinBoxKasm1->setEnabled(true); + ui->spinBoxAngle1->setEnabled(true); + ui->doubleSpinBoxKasm2->setEnabled(true); + ui->spinBoxAngle2->setEnabled(true); + qint32 row = ui->listWidget->currentRow(); + if(row == 0){ + ui->doubleSpinBoxKasm1->setEnabled(false); + ui->spinBoxAngle1->setEnabled(false); + return; + } + if(row == ui->listWidget->count()-1){ + ui->doubleSpinBoxKasm2->setEnabled(false); + ui->spinBoxAngle2->setEnabled(false); + return; + } +} + +void DialogSplinePath::SetAngle(qint32 angle){ + qint32 row = ui->listWidget->currentRow(); + QListWidgetItem *item = ui->listWidget->item( row ); + VSplinePoint p = qvariant_cast(item->data(Qt::UserRole)); + p.SetAngle(angle); + DataPoint(p.P(), p.KAsm1(), p.Angle1(), p.KAsm2(), p.Angle2()); + item->setData(Qt::UserRole, QVariant::fromValue(p)); +} diff --git a/dialogs/dialogsplinepath.h b/dialogs/dialogsplinepath.h new file mode 100644 index 000000000..607cbfe3e --- /dev/null +++ b/dialogs/dialogsplinepath.h @@ -0,0 +1,38 @@ +#ifndef DIALOGSPLINEPATH_H +#define DIALOGSPLINEPATH_H + +#include "dialogtool.h" +#include "../container/vcontainer.h" +#include "../geometry/vsplinepath.h" + +namespace Ui { +class DialogSplinePath; +} + +class DialogSplinePath : public DialogTool +{ + Q_OBJECT +public: + explicit DialogSplinePath(const VContainer *data, QWidget *parent = 0); + ~DialogSplinePath(); + VSplinePath GetPath() const; + void SetPath(const VSplinePath &value); +public slots: + virtual void ChoosedObject(qint64 id, Scene::Type type); + virtual void DialogAccepted(); + void PointChenged(int row); + void currentPointChanged( int index ); + void Angle1Changed( int index ); + void Angle2Changed( int index ); + void KAsm1Changed(qreal d); + void KAsm2Changed(qreal d); +private: + Ui::DialogSplinePath *ui; + VSplinePath path; + void NewItem(qint64 id, qreal kAsm1, qreal angle, qreal kAsm2); + void DataPoint(qint64 id, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2); + void EnableFields(); + void SetAngle(qint32 angle); +}; + +#endif // DIALOGSPLINEPATH_H diff --git a/dialogs/dialogsplinepath.ui b/dialogs/dialogsplinepath.ui new file mode 100644 index 000000000..4fb4a1af0 --- /dev/null +++ b/dialogs/dialogsplinepath.ui @@ -0,0 +1,219 @@ + + + DialogSplinePath + + + + 0 + 0 + 524 + 321 + + + + Dialog + + + + + + + + + + + + Точка сплайну + + + + + + + + + + + + + + Коефіцієнт довжини першої контрольної точки + + + true + + + + + + + 1.000000000000000 + + + + + + + + + + + Кут першої контрольної точки + + + true + + + + + + + 360 + + + + + + + + + + + Коефіцієнт довжини другої контрольної точки + + + true + + + + + + + 1.000000000000000 + + + + + + + + + + + Кут другої контрольної точки + + + true + + + + + + + 360 + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Коефіцієнт кривизни сплайну + + + + + + + + 0 + 0 + + + + + 72 + 0 + + + + 1.000000000000000 + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + buttonBox + layoutWidget_2 + + horizontalLayoutWidget + + + + + buttonBox + accepted() + DialogSplinePath + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DialogSplinePath + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/geometry/vsplinepath.cpp b/geometry/vsplinepath.cpp new file mode 100644 index 000000000..195b7b7a5 --- /dev/null +++ b/geometry/vsplinepath.cpp @@ -0,0 +1,116 @@ +#include "vsplinepath.h" + +VSplinePath::VSplinePath(){ + points = 0; + kCurve = 1; +} + +VSplinePath::VSplinePath(const QMap *points, qreal kCurve){ + this->points = points; + this->kCurve = kCurve; +} + +void VSplinePath::append(VSplinePoint point){ + path.append(point); +} + +qint32 VSplinePath::Count() const{ + if(path.size() == 0){ + return 0; + } else { + return path.size() - 1; + } +} + +qint32 VSplinePath::CountPoint() const{ + return path.size(); +} + +VSpline VSplinePath::GetSpline(qint32 index) const{ + if(Count()<1){ + throw "Недостатня кількість точок для створення сплайну."; + } + if(index < 1 || index > Count()){ + throw "Такого сплайну немає."; + } + VSpline spl(points, path[index-1].P(), path[index].P(), path[index-1].Angle2(), path[index].Angle1(), + path[index-1].KAsm2(), path[index].KAsm1(), this->kCurve); + return spl; +} + +QPainterPath VSplinePath::GetPath() const{ + QPainterPath painterPath; + for(qint32 i = 1; i <= Count(); ++i){ + VSpline spl(points, path[i-1].P(), path[i].P(), path[i-1].Angle2(), path[i].Angle1(), path[i-1].KAsm2(), + path[i].KAsm1(), this->kCurve); + painterPath.addPath(spl.GetPath()); + } + return painterPath; +} + +QVector VSplinePath::GetSplinePath() const{ + return path; +} + +qreal VSplinePath::GetLength() const{ + qreal length = 0; + for(qint32 i = 1; i <= Count(); ++i){ + VSpline spl(points, path[i-1].P(), path[i].P(), path[i-1].Angle2(), path[i].Angle1(), path[i-1].KAsm2(), + path[i].KAsm1(), kCurve); + length += spl.GetLength(); + } + return length; +} + +const QMap *VSplinePath::GetDataPoints() const{ + return points; +} + +void VSplinePath::UpdatePoint(qint32 indexSpline, SplinePoint::Position pos, VSplinePoint point){ + if(indexSpline < 1 || indexSpline > Count()){ + throw "Такого сплайну немає."; + } + if(pos == SplinePoint::FirstPoint){ + path[indexSpline-1] = point; + } else { + path[indexSpline] = point; + } +} + +VSplinePoint VSplinePath::GetSplinePoint(qint32 indexSpline, SplinePoint::Position pos){ + if(indexSpline < 1 || indexSpline > Count()){ + throw "Такого сплайну немає."; + } + if(pos == SplinePoint::FirstPoint){ + return path[indexSpline-1]; + } else { + return path[indexSpline]; + } +} + +void VSplinePath::Clear(){ + path.clear(); +} + +qreal VSplinePath::getKCurve() const{ + return kCurve; +} + +void VSplinePath::setKCurve(const qreal &value){ + kCurve = value; +} + +const QVector *VSplinePath::GetPoint() const{ + return &path; +} + +VSplinePath &VSplinePath::operator =(const VSplinePath &path){ + this->path = path.GetSplinePath(); + this->kCurve = path.getKCurve(); + this->points = path.GetDataPoints(); + return *this; +} + +VSplinePoint & VSplinePath::operator[](int indx){ + return path[indx]; +} diff --git a/geometry/vsplinepath.h b/geometry/vsplinepath.h new file mode 100644 index 000000000..7563f735a --- /dev/null +++ b/geometry/vsplinepath.h @@ -0,0 +1,61 @@ +#ifndef VSPLINEPATH_H +#define VSPLINEPATH_H + +#include "vsplinepoint.h" +#include +#include "vspline.h" + +namespace SplinePoint{ + enum Position + { + FirstPoint, + LastPoint + }; +} + +/** + * @brief The VSplinePath клас, що розраховує шлях сплайнів. + */ +class VSplinePath{ +public: + /** + * @brief VSplinePath конструктор по замовчуванню. + */ + VSplinePath(); + /** + * @brief VSplinePath конструктор по замовчуванню. + */ + VSplinePath(const QMap *points, qreal kCurve = 1); + /** + * @brief append додає точку сплайну до шляху. + * @param point точка. + */ + void append(VSplinePoint point); + qint32 Count() const; + qint32 CountPoint() const; + VSpline GetSpline(qint32 index) const; + QPainterPath GetPath() const; + QVector GetSplinePath() const; + qreal GetLength() const; + const QMap *GetDataPoints() const; + void UpdatePoint(qint32 indexSpline, SplinePoint::Position pos, VSplinePoint point); + VSplinePoint GetSplinePoint(qint32 indexSpline, SplinePoint::Position pos); + /** + * @brief Clear очищає шлях сплайнів. + */ + void Clear(); + qreal getKCurve() const; + void setKCurve(const qreal &value); + const QVector *GetPoint() const; + VSplinePath& operator=(const VSplinePath &path); + VSplinePoint & operator[](int indx); +protected: + /** + * @brief path вектор з точок сплайна. + */ + QVector path; + qreal kCurve; + const QMap *points; +}; + +#endif // VSPLINEPATH_H diff --git a/geometry/vsplinepoint.cpp b/geometry/vsplinepoint.cpp new file mode 100644 index 000000000..26560f096 --- /dev/null +++ b/geometry/vsplinepoint.cpp @@ -0,0 +1,61 @@ +#include "vsplinepoint.h" + +VSplinePoint::VSplinePoint(){ + this->pSpline = 0; + this->angle = 0; + this->kAsm1 = 1; + this->kAsm2 = 1; +} + +VSplinePoint::VSplinePoint(qint64 pSpline, qreal kAsm1, qreal angle , qreal kAsm2){ + this->pSpline = pSpline; + this->angle = angle; + this->kAsm1 = kAsm1; + this->kAsm2 = kAsm2; +} + +VSplinePoint::VSplinePoint(const VSplinePoint &point){ + this->pSpline = point.P(); + this->angle = point.Angle2(); + this->kAsm1 = point.KAsm1(); + this->kAsm2 = point.KAsm2(); +} + +VSplinePoint::~VSplinePoint(){ +} + +qint64 VSplinePoint::P() const{ + return pSpline; +} + +void VSplinePoint::SetP(const qint64 &value){ + pSpline = value; +} + +qreal VSplinePoint::Angle1() const{ + return angle+180; +} + +void VSplinePoint::SetAngle(const qreal &value){ + angle = value; +} + +qreal VSplinePoint::Angle2() const{ + return angle; +} + +qreal VSplinePoint::KAsm1() const{ + return kAsm1; +} + +void VSplinePoint::SetKAsm1(const qreal &value){ + kAsm1 = value; +} + +qreal VSplinePoint::KAsm2() const{ + return kAsm2; +} + +void VSplinePoint::SetKAsm2(const qreal &value){ + kAsm2 = value; +} diff --git a/geometry/vsplinepoint.h b/geometry/vsplinepoint.h new file mode 100644 index 000000000..0ada5094f --- /dev/null +++ b/geometry/vsplinepoint.h @@ -0,0 +1,75 @@ +#ifndef VSPLINEPOINT_H +#define VSPLINEPOINT_H + +#include "QtGlobal" +#include + +/** + * @brief The VSplinePoint клас, що містить у собі інформацію про точки сплайну. + */ +class VSplinePoint{ +public: + /** + * @brief VSplinePoint конструктор по замповчуванню. + */ + VSplinePoint(); + /** + * @brief VSplinePoint конструктор. + * @param pSpline точка сплайну. + * @param angle кут дотичної сплайна. + * @param factor коефіцієнт довжини дотичної. + */ + VSplinePoint(qint64 pSpline, qreal kAsm1, qreal angle, qreal kAsm2); + VSplinePoint(const VSplinePoint &point); + ~VSplinePoint(); + /** + * @brief P повертає точку. + * @return точка. + */ + qint64 P() const; + void SetP(const qint64 &value); + /** + * @brief Angle1 повертає кут дотичної сплайна. + * @return кут в градусах. + */ + qreal Angle1() const; + void SetAngle(const qreal &value); + /** + * @brief Angle2 повертає кут дотичної сплайна. + * @return кут в градусах. + */ + qreal Angle2() const; + /** + * @brief KAsm1 повертає коефіцієнт довжини дотичної. + * @return коефіцієнт. + */ + qreal KAsm1() const; + void SetKAsm1(const qreal &value); + /** + * @brief KAsm2 повертає коефіцієнт довжини дотичної. + * @return коефіцієнт. + */ + qreal KAsm2() const; + void SetKAsm2(const qreal &value); +protected: + /** + * @brief pSpline точка сплайну. + */ + qint64 pSpline; + /** + * @brief angle кут дотичної сплайну. + */ + qreal angle; + /** + * @brief kAsm1 коефіцієнт довжини дотичної сплайну. + */ + qreal kAsm1; + /** + * @brief kAsm2 коефіцієнт довжини дотичної сплайну. + */ + qreal kAsm2; +}; + +Q_DECLARE_METATYPE(VSplinePoint) + +#endif // VSPLINEPOINT_H diff --git a/icon.qrc b/icon.qrc index 35d21353f..467aa830d 100644 --- a/icon.qrc +++ b/icon.qrc @@ -28,5 +28,6 @@ icon/32x32/spline.png icon/32x32/arc.png icon/24x24/putHereLeft.png + icon/32x32/splinePath.png diff --git a/icon/32x32/splinePath.png b/icon/32x32/splinePath.png new file mode 100644 index 0000000000000000000000000000000000000000..b244e58b2823a4dd4e82208be792d71b49a88d11 GIT binary patch literal 771 zcmV+e1N{7nP)FYA*l)0+2~W zK~z}7?U!GOOko(te|BaE%h;ve*!(Lbe@fYvwp@6$&e6=?@Ybnw`kwQ=&-uRh-+_PKX4HUV z6VM7w0*`_Gbcyc;#(TKm#EJtN?xpp96LTVAmP$v%pM0P!hOr zfYq!4IBM|Y!0rJ2h;U;-vy1SEA>0;1L=$icDC(ULz(xo5xZz&qBHXFsQ36hf%!Wqg zewq9Vknq86F_>N#S%fu4{828@91Rf^V#XJV=-OkHL%t>H2jK-z8a&w#lh=E-wvU|Hb0AE@7u ze%ID@dS<(J;GklrJoWTM%pB*yngq^!wkiYM0xoODOPNksZeVe0XbE+$e3kLLq*h+n zKc_>$bNzJWbd4+GS5N1!SsSoexjqVftoolButtonArc, &QToolButton::clicked, this, &MainWindow::ToolArc); + connect(ui->toolButtonSplinePath, &QToolButton::clicked, this, + &MainWindow::ToolSplinePath); data = new VContainer; CreateManTableIGroup (); @@ -589,6 +592,37 @@ void MainWindow::ClosedDialogArc(int result){ ArrowTool(); } +void MainWindow::ToolSplinePath(bool checked){ + if(checked){ + CanselTool(); + tool = Tools::SplinePathTool; + QPixmap pixmap(":/cursor/splinepath_cursor.png"); + QCursor cur(pixmap, 2, 3); + ui->graphicsView->setCursor(cur); + helpLabel->setText("Виберіть точку."); + dialogSplinePath = new DialogSplinePath(data, this); + connect(scene, &VMainGraphicsScene::ChoosedObject, dialogSplinePath, + &DialogSplinePath::ChoosedObject); + connect(dialogSplinePath, &DialogSplinePath::DialogClosed, this, + &MainWindow::ClosedDialogSplinePath); + } else { + ui->toolButtonSplinePath->setChecked(true); + } +} + +void MainWindow::ClosedDialogSplinePath(int result){ + if(result == QDialog::Accepted){ + VSplinePath path = dialogSplinePath->GetPath(); + + qint64 id = data->AddSplinePath(path); + data->AddLengthSpline(data->GetNameSplinePath(path), path.GetLength()); + VToolSplinePath *tool = new VToolSplinePath(doc, data, id, Tool::FromGui); + scene->addItem(tool); + connect(tool, &VToolSplinePath::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); + } + ArrowTool(); +} + void MainWindow::showEvent( QShowEvent *event ){ QMainWindow::showEvent( event ); if( event->spontaneous() ){ @@ -598,7 +632,6 @@ void MainWindow::showEvent( QShowEvent *event ){ if(isInitialized){ return; } - // do your init stuff here QScrollBar *horScrollBar = ui->graphicsView->horizontalScrollBar(); horScrollBar->setValue(horScrollBar->minimum()); @@ -751,6 +784,12 @@ void MainWindow::CanselTool(){ scene->setFocus(Qt::OtherFocusReason); scene->clearSelection(); break; + case Tools::SplinePathTool: + delete dialogSplinePath; + ui->toolButtonSplinePath->setChecked(false); + scene->setFocus(Qt::OtherFocusReason); + scene->clearSelection(); + break; } } @@ -1015,6 +1054,7 @@ void MainWindow::SetEnableTool(bool enable){ ui->toolButtonLineIntersect->setEnabled(enable); ui->toolButtonSpline->setEnabled(enable); ui->toolButtonArc->setEnabled(enable); + ui->toolButtonSplinePath->setEnabled(enable); } MainWindow::~MainWindow(){ diff --git a/mainwindow.h b/mainwindow.h index 106acdaf9..c6c91ea4b 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -19,6 +19,7 @@ #include "dialogs/dialoglineintersect.h" #include "dialogs/dialogspline.h" #include "dialogs/dialogarc.h" +#include "dialogs/dialogsplinepath.h" #include "tools/vtoolsinglepoint.h" #include "xml/vdomdocument.h" #include "container/vcontainer.h" @@ -40,7 +41,8 @@ namespace Tools{ BisectorTool, LineIntersectTool, SplineTool, - ArcTool + ArcTool, + SplinePathTool }; } @@ -87,6 +89,8 @@ public slots: void ClosedDialogSpline(int result); void ToolArc(bool checked); void ClosedDialogArc(int result); + void ToolSplinePath(bool checked); + void ClosedDialogSplinePath(int result); protected: virtual void keyPressEvent ( QKeyEvent * event ); virtual void showEvent( QShowEvent *event ); @@ -108,6 +112,7 @@ private: DialogLineIntersect *dialogLineIntersect; DialogSpline *dialogSpline; DialogArc *dialogArc; + DialogSplinePath *dialogSplinePath; VDomDocument *doc; VContainer *data; QComboBox *comboBoxDraws; diff --git a/mainwindow.ui b/mainwindow.ui index c0053113f..0fd36237e 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -57,7 +57,7 @@ - 3 + 2 @@ -333,6 +333,29 @@ + + + + false + + + ... + + + + :/icon/32x32/splinePath.png:/icon/32x32/splinePath.png + + + + 32 + 32 + + + + true + + + diff --git a/options.h b/options.h index 3c3c170f3..1541e1b76 100644 --- a/options.h +++ b/options.h @@ -12,7 +12,8 @@ namespace Scene{ Point, Line, Spline, - Arc + Arc, + SplinePath }; } diff --git a/tools/vtoolspline.cpp b/tools/vtoolspline.cpp index d159f980e..1b7afe906 100644 --- a/tools/vtoolspline.cpp +++ b/tools/vtoolspline.cpp @@ -15,13 +15,21 @@ VToolSpline::VToolSpline(VDomDocument *doc, VContainer *data, qint64 id, Tool::E this->setFlag(QGraphicsItem::ItemIsSelectable, true); this->setAcceptHoverEvents(true); - controlPoint1 = new VControlPointSpline(spl.GetP2(), spl.GetPointP1(), this); + VControlPointSpline *controlPoint1 = new VControlPointSpline(1, SplinePoint::FirstPoint, spl.GetP2(), + spl.GetPointP1(), this); connect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this, - &VToolSpline::ControlPoint1ChangePosition); + &VToolSpline::ControlPointChangePosition); + connect(this, &VToolSpline::RefreshLine, controlPoint1, &VControlPointSpline::RefreshLine); + connect(this, &VToolSpline::setEnabledPoint, controlPoint1, &VControlPointSpline::setEnabledPoint); + controlPoints.append(controlPoint1); - controlPoint2 = new VControlPointSpline(spl.GetP3(), spl.GetPointP4(), this); + VControlPointSpline *controlPoint2 = new VControlPointSpline(1, SplinePoint::LastPoint, spl.GetP3(), + spl.GetPointP4(), this); connect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this, - &VToolSpline::ControlPoint2ChangePosition); + &VToolSpline::ControlPointChangePosition); + connect(this, &VToolSpline::RefreshLine, controlPoint2, &VControlPointSpline::RefreshLine); + connect(this, &VToolSpline::setEnabledPoint, controlPoint2, &VControlPointSpline::setEnabledPoint); + controlPoints.append(controlPoint2); if(typeCreation == Tool::FromGui){ AddToFile(); @@ -38,19 +46,19 @@ void VToolSpline::FullUpdateFromGui(int result){ dialogSpline->getP4(), dialogSpline->getAngle1(), dialogSpline->getAngle2(), dialogSpline->getKAsm1(), dialogSpline->getKAsm2(), dialogSpline->getKCurve()); - disconnect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this, - &VToolSpline::ControlPoint1ChangePosition); - disconnect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this, - &VToolSpline::ControlPoint2ChangePosition); - controlPoint1->setPos(spl.GetP2()); - controlPoint2->setPos(spl.GetP3()); - connect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this, - &VToolSpline::ControlPoint1ChangePosition); - connect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this, - &VToolSpline::ControlPoint2ChangePosition); + disconnect(controlPoints[0], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSpline::ControlPointChangePosition); + disconnect(controlPoints[1], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSpline::ControlPointChangePosition); + controlPoints[0]->setPos(spl.GetP2()); + controlPoints[1]->setPos(spl.GetP3()); + connect(controlPoints[0], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSpline::ControlPointChangePosition); + connect(controlPoints[1], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSpline::ControlPointChangePosition); - spl = VSpline (VAbstractTool::data->DataPoints(), dialogSpline->getP1(), controlPoint1->pos(), - controlPoint2->pos(), dialogSpline->getP4(), dialogSpline->getKCurve()); + spl = VSpline (VAbstractTool::data->DataPoints(), dialogSpline->getP1(), controlPoints[0]->pos(), + controlPoints[1]->pos(), dialogSpline->getP4(), dialogSpline->getKCurve()); QDomElement domElement = doc->elementById(QString().setNum(id)); if(domElement.isElement()){ domElement.setAttribute("point1", QString().setNum(spl.GetP1())); @@ -66,23 +74,15 @@ void VToolSpline::FullUpdateFromGui(int result){ dialogSpline.clear(); } -void VToolSpline::ControlPoint1ChangePosition(const QPointF pos){ +void VToolSpline::ControlPointChangePosition(const qint32 &indexSpline, SplinePoint::Position position, + const QPointF pos){ + Q_UNUSED(indexSpline); VSpline spl = VAbstractTool::data->GetSpline(id); - spl.ModifiSpl (spl.GetP1(), pos, spl.GetP3(), spl.GetP4(), spl.GetKcurve()); - QDomElement domElement = doc->elementById(QString().setNum(id)); - if(domElement.isElement()){ - domElement.setAttribute("angle1", QString().setNum(spl.GetAngle1())); - domElement.setAttribute("angle2", QString().setNum(spl.GetAngle2())); - domElement.setAttribute("kAsm1", QString().setNum(spl.GetKasm1())); - domElement.setAttribute("kAsm2", QString().setNum(spl.GetKasm2())); - domElement.setAttribute("kCurve", QString().setNum(spl.GetKcurve())); - emit FullUpdateTree(); + if(position == SplinePoint::FirstPoint){ + spl.ModifiSpl (spl.GetP1(), pos, spl.GetP3(), spl.GetP4(), spl.GetKcurve()); + } else { + spl.ModifiSpl (spl.GetP1(), spl.GetP2(), pos, spl.GetP4(), spl.GetKcurve()); } -} - -void VToolSpline::ControlPoint2ChangePosition(const QPointF pos){ - VSpline spl = VAbstractTool::data->GetSpline(id); - spl.ModifiSpl (spl.GetP1(), spl.GetP2(), pos, spl.GetP4(), spl.GetKcurve()); QDomElement domElement = doc->elementById(QString().setNum(id)); if(domElement.isElement()){ domElement.setAttribute("angle1", QString().setNum(spl.GetAngle1())); @@ -164,10 +164,10 @@ void VToolSpline::RefreshGeometry(){ this->setPath(path); QPointF splinePoint = VAbstractTool::data->GetPoint(spl.GetP1()); QPointF controlPoint = spl.GetP2(); - controlPoint1->RefreshLine(controlPoint, splinePoint); + emit RefreshLine(1, SplinePoint::FirstPoint, controlPoint, splinePoint); splinePoint = VAbstractTool::data->GetPoint(spl.GetP4()); controlPoint = spl.GetP3(); - controlPoint2->RefreshLine(controlPoint, splinePoint); + emit RefreshLine(1, SplinePoint::LastPoint, controlPoint, splinePoint); } @@ -176,27 +176,13 @@ void VToolSpline::ChangedActivDraw(const QString newName){ this->setPen(QPen(Qt::black, widthHairLine)); this->setFlag(QGraphicsItem::ItemIsSelectable, true); this->setAcceptHoverEvents(true); - controlPoint1->setPen(QPen(Qt::black, widthHairLine)); - controlPoint1->setFlag(QGraphicsItem::ItemIsSelectable, true); - controlPoint1->setFlag(QGraphicsItem::ItemIsMovable, true); - controlPoint1->setAcceptHoverEvents(true); - controlPoint2->setPen(QPen(Qt::black, widthHairLine)); - controlPoint2->setFlag(QGraphicsItem::ItemIsSelectable, true); - controlPoint2->setFlag(QGraphicsItem::ItemIsMovable, true); - controlPoint2->setAcceptHoverEvents(true); + emit setEnabledPoint(true); VAbstractTool::ChangedActivDraw(newName); } else { this->setPen(QPen(Qt::gray, widthHairLine)); this->setFlag(QGraphicsItem::ItemIsSelectable, false); this->setAcceptHoverEvents (false); - controlPoint1->setPen(QPen(Qt::gray, widthHairLine)); - controlPoint1->setFlag(QGraphicsItem::ItemIsSelectable, false); - controlPoint1->setFlag(QGraphicsItem::ItemIsMovable, false); - controlPoint1->setAcceptHoverEvents(false); - controlPoint2->setPen(QPen(Qt::gray, widthHairLine)); - controlPoint2->setFlag(QGraphicsItem::ItemIsSelectable, false); - controlPoint2->setFlag(QGraphicsItem::ItemIsMovable, false); - controlPoint2->setAcceptHoverEvents(false); + emit setEnabledPoint(false); VAbstractTool::ChangedActivDraw(newName); } } diff --git a/tools/vtoolspline.h b/tools/vtoolspline.h index 471cd0aaf..5b3cbb590 100644 --- a/tools/vtoolspline.h +++ b/tools/vtoolspline.h @@ -7,30 +7,35 @@ #include #include "../dialogs/dialogspline.h" #include "../widgets/vcontrolpointspline.h" +#include "../geometry/vsplinepath.h" class VToolSpline:public VAbstractTool, public QGraphicsPathItem { Q_OBJECT public: - VToolSpline(VDomDocument *doc, VContainer *data, qint64 id, - Tool::Enum typeCreation, QGraphicsItem * parent = 0); + VToolSpline ( VDomDocument *doc, VContainer *data, qint64 id, + Tool::Enum typeCreation, QGraphicsItem * parent = 0 ); +signals: + void RefreshLine ( const qint32 &indexSpline, SplinePoint::Position position, + const QPointF &controlPoint, const QPointF &splinePoint ); + void setEnabledPoint ( bool enable ); public slots: - virtual void FullUpdateFromFile(); - virtual void FullUpdateFromGui(int result); - void ControlPoint1ChangePosition(const QPointF pos); - void ControlPoint2ChangePosition(const QPointF pos); - virtual void ChangedActivDraw(const QString newName); + virtual void FullUpdateFromFile (); + virtual void FullUpdateFromGui ( int result ); + void ControlPointChangePosition ( const qint32 &indexSpline, + SplinePoint::Position position, + const QPointF pos); + virtual void ChangedActivDraw ( const QString newName ); protected: - virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ); - virtual void AddToFile(); - virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ); - virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event ); - virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); + virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ); + virtual void AddToFile (); + virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ); + virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event ); + virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); private: - QSharedPointer dialogSpline; - VControlPointSpline *controlPoint1; - VControlPointSpline *controlPoint2; - void RefreshGeometry(); + QSharedPointer dialogSpline; + QVector controlPoints; + void RefreshGeometry (); }; #endif // VTOOLSPLINE_H diff --git a/tools/vtoolsplinepath.cpp b/tools/vtoolsplinepath.cpp new file mode 100644 index 000000000..75c87409e --- /dev/null +++ b/tools/vtoolsplinepath.cpp @@ -0,0 +1,243 @@ +#include "vtoolsplinepath.h" +#include + +VToolSplinePath::VToolSplinePath(VDomDocument *doc, VContainer *data, qint64 id, Tool::Enum typeCreation, + QGraphicsItem *parent):VAbstractTool(doc, data, id), + QGraphicsPathItem(parent){ + VSplinePath splPath = data->GetSplinePath(id); + QPainterPath path; + path.addPath(splPath.GetPath()); + path.setFillRule( Qt::WindingFill ); + this->setPath(path); + this->setPen(QPen(Qt::black, widthHairLine)); + this->setFlag(QGraphicsItem::ItemIsSelectable, true); + this->setAcceptHoverEvents(true); + + for(qint32 i = 1; i<=splPath.Count(); ++i){ + VSpline spl = splPath.GetSpline(i); + VControlPointSpline *controlPoint = new VControlPointSpline(i, SplinePoint::FirstPoint, spl.GetP2(), + spl.GetPointP1(), this); + connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + connect(this, &VToolSplinePath::RefreshLine, controlPoint, &VControlPointSpline::RefreshLine); + connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint); + controlPoints.append(controlPoint); + + controlPoint = new VControlPointSpline(i, SplinePoint::LastPoint, spl.GetP3(),spl.GetPointP4(), this); + connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + connect(this, &VToolSplinePath::RefreshLine, controlPoint, &VControlPointSpline::RefreshLine); + connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint); + controlPoints.append(controlPoint); + } + + if(typeCreation == Tool::FromGui){ + AddToFile(); + } +} + +void VToolSplinePath::FullUpdateFromFile(){ + RefreshGeometry(); +} + +void VToolSplinePath::FullUpdateFromGui(int result){ + if(result == QDialog::Accepted){ + VSplinePath splPath = dialogSplinePath->GetPath(); + for(qint32 i = 1; i<=splPath.Count(); ++i){ + VSpline spl = splPath.GetSpline(i); + qint32 j = i*2; + disconnect(controlPoints[j-2], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + disconnect(controlPoints[j-1], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + controlPoints[j-2]->setPos(spl.GetP2()); + controlPoints[j-1]->setPos(spl.GetP3()); + connect(controlPoints[j-2], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + connect(controlPoints[j-1], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + + spl = VSpline (VAbstractTool::data->DataPoints(), spl.GetP1(), controlPoints[j-2]->pos(), + controlPoints[j-1]->pos(), spl.GetP4(), splPath.getKCurve()); + CorectControlPoints(spl, splPath, i-1, i, SplinePoint::FirstPoint); + CorectControlPoints(spl, splPath, i, i, SplinePoint::LastPoint); + + QDomElement domElement = doc->elementById(QString().setNum(id)); + if(domElement.isElement()){ + domElement.setAttribute("kCurve", QString().setNum(splPath.getKCurve())); + UpdatePathPoint(domElement, splPath); + emit FullUpdateTree(); + } + + } + } + dialogSplinePath.clear(); +} + +void VToolSplinePath::ControlPointChangePosition(const qint32 &indexSpline, SplinePoint::Position position, + const QPointF pos) +{ + qint32 index = 0; + VSplinePath splPath = VAbstractTool::data->GetSplinePath(id); + VSpline spl = splPath.GetSpline(indexSpline); + if(position == SplinePoint::FirstPoint){ + spl.ModifiSpl (spl.GetP1(), pos, spl.GetP3(), spl.GetP4(), spl.GetKcurve()); + index = indexSpline - 1; + } else { + spl.ModifiSpl (spl.GetP1(), spl.GetP2(), pos, spl.GetP4(), spl.GetKcurve()); + index = indexSpline; + } + + CorectControlPoints(spl, splPath, index, indexSpline, position); + QDomElement domElement = doc->elementById(QString().setNum(id)); + if(domElement.isElement()){ + domElement.setAttribute("kCurve", QString().setNum(splPath.getKCurve())); + UpdatePathPoint(domElement, splPath); + emit FullUpdateTree(); + } +} + +void VToolSplinePath::CorectControlPoints(const VSpline &spl, VSplinePath &splPath, qint32 index, + const qint32 &indexSpline, SplinePoint::Position position){ + VSplinePoint p = splPath.GetSplinePoint(indexSpline, SplinePoint::FirstPoint); + p.SetAngle(spl.GetAngle1()); + p.SetKAsm2(spl.GetKasm1()); + splPath.UpdatePoint(indexSpline, SplinePoint::FirstPoint, p); + + p = splPath.GetSplinePoint(indexSpline, SplinePoint::LastPoint); + p.SetAngle(spl.GetAngle2()-180); + p.SetKAsm1(spl.GetKasm2()); + splPath.UpdatePoint(indexSpline, SplinePoint::LastPoint, p); + + if(index > 0 && index < splPath.CountPoint()-1){ + if(position == SplinePoint::FirstPoint){ + VSpline spl = splPath.GetSpline(indexSpline-1); + qint32 i = (indexSpline-1)*2-1; + disconnect(controlPoints[i], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + controlPoints[i]->setPos(spl.GetP3()); + connect(controlPoints[i], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + } else { + VSpline spl = splPath.GetSpline(indexSpline+1); + qint32 i = (indexSpline+1)*2-2; + disconnect(controlPoints[i], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + controlPoints[i]->setPos(spl.GetP2()); + connect(controlPoints[i], &VControlPointSpline::ControlPointChangePosition, this, + &VToolSplinePath::ControlPointChangePosition); + } + } +} + +void VToolSplinePath::UpdatePathPoint(QDomNode& node, VSplinePath &path){ + QDomNodeList nodeList = node.childNodes(); + qint32 num = nodeList.size(); + for(qint32 i = 0; i < num; ++i){ + QDomElement domElement = nodeList.at(i).toElement(); + if(!domElement.isNull()){ + VSplinePoint p = path[i]; + domElement.setAttribute("pSpline", QString().setNum(p.P())); + domElement.setAttribute("kAsm1", QString().setNum(p.KAsm1())); + domElement.setAttribute("kAsm2", QString().setNum(p.KAsm2())); + domElement.setAttribute("angle", QString().setNum(p.Angle2())); + } + } +} + +void VToolSplinePath::ChangedActivDraw(const QString newName){ + if(nameActivDraw == newName){ + this->setPen(QPen(Qt::black, widthHairLine)); + this->setFlag(QGraphicsItem::ItemIsSelectable, true); + this->setAcceptHoverEvents(true); + emit setEnabledPoint(true); + VAbstractTool::ChangedActivDraw(newName); + } else { + this->setPen(QPen(Qt::gray, widthHairLine)); + this->setFlag(QGraphicsItem::ItemIsSelectable, false); + this->setAcceptHoverEvents (false); + emit setEnabledPoint(false); + VAbstractTool::ChangedActivDraw(newName); + } +} + +void VToolSplinePath::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){ + if(!ignoreContextMenuEvent){ + QMenu menu; + QAction *actionOption = menu.addAction("Властивості"); + QAction *selectedAction = menu.exec(event->screenPos()); + if(selectedAction == actionOption){ + dialogSplinePath = QSharedPointer(new DialogSplinePath(VAbstractTool::data)); + + connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject, + dialogSplinePath.data(), &DialogSplinePath::ChoosedObject); + connect(dialogSplinePath.data(), &DialogSplinePath::DialogClosed, this, + &VToolSplinePath::FullUpdateFromGui); + + VSplinePath splPath = VAbstractTool::data->GetSplinePath(id); + dialogSplinePath->SetPath(splPath); + dialogSplinePath->show(); + } + } +} + +void VToolSplinePath::AddToFile(){ + VSplinePath splPath = VAbstractTool::data->GetSplinePath(id); + QDomElement domElement = doc->createElement("spline"); + + AddAttribute(domElement, "id", id); + AddAttribute(domElement, "type", "path"); + AddAttribute(domElement, "kCurve", splPath.getKCurve()); + + for(qint32 i = 0; i < splPath.CountPoint(); ++i){ + AddPathPoint(domElement, splPath[i]); + } + + AddToCalculation(domElement); +} + +void VToolSplinePath::AddPathPoint(QDomElement &domElement, const VSplinePoint &splPoint){ + QDomElement pathPoint = doc->createElement("pathPoint"); + + AddAttribute(pathPoint, "pSpline", splPoint.P()); + AddAttribute(pathPoint, "kAsm1", splPoint.KAsm1()); + AddAttribute(pathPoint, "kAsm2", splPoint.KAsm2()); + AddAttribute(pathPoint, "angle", splPoint.Angle2()); + + domElement.appendChild(pathPoint); +} + +void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + emit ChoosedTool(id, Scene::SplinePath); + } + QGraphicsItem::mouseReleaseEvent(event); +} + +void VToolSplinePath::hoverMoveEvent(QGraphicsSceneHoverEvent *event){ + Q_UNUSED(event); + this->setPen(QPen(Qt::black, widthMainLine)); +} + +void VToolSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event){ + Q_UNUSED(event); + this->setPen(QPen(Qt::black, widthHairLine)); +} + +void VToolSplinePath::RefreshGeometry(){ + VSplinePath splPath = VAbstractTool::data->GetSplinePath(id); + QPainterPath path; + path.addPath(splPath.GetPath()); + path.setFillRule( Qt::WindingFill ); + this->setPath(path); + for(qint32 i = 1; i<=splPath.Count(); ++i){ + VSpline spl = splPath.GetSpline(i); + QPointF splinePoint = VAbstractTool::data->GetPoint(spl.GetP1()); + QPointF controlPoint = spl.GetP2(); + emit RefreshLine(i, SplinePoint::FirstPoint, controlPoint, splinePoint); + splinePoint = VAbstractTool::data->GetPoint(spl.GetP4()); + controlPoint = spl.GetP3(); + emit RefreshLine(i, SplinePoint::LastPoint, controlPoint, splinePoint); + } + +} diff --git a/tools/vtoolsplinepath.h b/tools/vtoolsplinepath.h new file mode 100644 index 000000000..1a72e937e --- /dev/null +++ b/tools/vtoolsplinepath.h @@ -0,0 +1,45 @@ +#ifndef VTOOLSPLINEPATH_H +#define VTOOLSPLINEPATH_H + +#include "vabstracttool.h" +#include "../container/vcontainer.h" +#include "../xml/vdomdocument.h" +#include +#include "../dialogs/dialogsplinepath.h" +#include "../widgets/vcontrolpointspline.h" + +class VToolSplinePath:public VAbstractTool, public QGraphicsPathItem +{ + Q_OBJECT +public: + VToolSplinePath(VDomDocument *doc, VContainer *data, qint64 id, + Tool::Enum typeCreation, QGraphicsItem * parent = 0); +signals: + void RefreshLine(const qint32 &indexSpline, SplinePoint::Position pos, + const QPointF &controlPoint, const QPointF &splinePoint); + void setEnabledPoint(bool enable); +public slots: + virtual void FullUpdateFromFile(); + virtual void FullUpdateFromGui(int result); + void ControlPointChangePosition(const qint32 &indexSpline, + SplinePoint::Position position, + const QPointF pos); + virtual void ChangedActivDraw(const QString newName); +protected: + virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ); + virtual void AddToFile(); + virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ); + virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event ); + virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); +private: + QSharedPointer dialogSplinePath; + QVector controlPoints; + void RefreshGeometry(); + void AddPathPoint(QDomElement &domElement, const VSplinePoint &splPoint); + void UpdatePathPoint(QDomNode& node, VSplinePath &path); + void CorectControlPoints(const VSpline &spl, VSplinePath &splPath, qint32 index, + const qint32 &indexSpline, + SplinePoint::Position position); +}; + +#endif // VTOOLSPLINEPATH_H diff --git a/widgets/vcontrolpointspline.cpp b/widgets/vcontrolpointspline.cpp index ae55a588a..c0ef24698 100644 --- a/widgets/vcontrolpointspline.cpp +++ b/widgets/vcontrolpointspline.cpp @@ -4,9 +4,12 @@ #include #include -VControlPointSpline::VControlPointSpline(const QPointF &controlPoint, const QPointF &splinePoint, +VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePoint::Position position, + const QPointF &controlPoint, const QPointF &splinePoint, QGraphicsItem *parent):QGraphicsEllipseItem(parent){ radius = 1.5*PrintDPI/25.4; + this->indexSpline = indexSpline; + this->position = position; //create circle QRectF rec = QRectF(0, 0, radius*2, radius*2); rec.translate(-rec.center().x(), -rec.center().y()); @@ -48,10 +51,10 @@ QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange chang newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left()))); newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top()))); - emit ControlPointChangePosition(newPos); + emit ControlPointChangePosition(indexSpline, position, newPos); return newPos; } - emit ControlPointChangePosition(newPos); + emit ControlPointChangePosition(indexSpline, position, newPos); } return QGraphicsItem::itemChange(change, value); } @@ -109,11 +112,25 @@ QPointF VControlPointSpline::addVector(QPointF p, QPointF p1, QPointF p2, qreal return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k); } -void VControlPointSpline::RefreshLine(const QPointF &controlPoint, const QPointF &splinePoint){ -// QRectF rec = QRectF(0, 0, radius*2, radius*2); -// rec.translate(0-rec.center().x(), 0-rec.center().y()); -// this->setRect(rec); - QPointF p1, p2; - LineIntersectCircle(QPointF(), radius, QLineF( QPointF(), splinePoint-controlPoint), p1, p2); - controlLine->setLine(QLineF(splinePoint-controlPoint, p1)); +void VControlPointSpline::RefreshLine(const qint32 &indexSpline, SplinePoint::Position pos, + const QPointF &controlPoint, const QPointF &splinePoint){ + if(this->indexSpline == indexSpline && this->position == pos){ + QPointF p1, p2; + LineIntersectCircle(QPointF(), radius, QLineF( QPointF(), splinePoint-controlPoint), p1, p2); + controlLine->setLine(QLineF(splinePoint-controlPoint, p1)); + } +} + +void VControlPointSpline::setEnabledPoint(bool enable){ + if(enable == true){ + this->setPen(QPen(Qt::black, widthHairLine)); + this->setFlag(QGraphicsItem::ItemIsSelectable, true); + this->setFlag(QGraphicsItem::ItemIsMovable, true); + this->setAcceptHoverEvents(true); + } else { + this->setPen(QPen(Qt::gray, widthHairLine)); + this->setFlag(QGraphicsItem::ItemIsSelectable, false); + this->setFlag(QGraphicsItem::ItemIsMovable, false); + this->setAcceptHoverEvents(false); + } } diff --git a/widgets/vcontrolpointspline.h b/widgets/vcontrolpointspline.h index 9cf89fa03..019a7f21d 100644 --- a/widgets/vcontrolpointspline.h +++ b/widgets/vcontrolpointspline.h @@ -5,25 +5,35 @@ #include #include #include "../options.h" +#include "../geometry/vsplinepath.h" + class VControlPointSpline : public QObject, public QGraphicsEllipseItem { Q_OBJECT public: - VControlPointSpline(const QPointF &controlPoint, const QPointF &splinePoint, QGraphicsItem * parent = 0); - void RefreshLine(const QPointF &controlPoint, const QPointF &splinePoint); + VControlPointSpline(const qint32 &indexSpline, SplinePoint::Position position, + const QPointF &controlPoint, const QPointF &splinePoint, + QGraphicsItem * parent = 0); signals: - void ControlPointChangePosition(const QPointF pos); + void ControlPointChangePosition(const qint32 &indexSpline, SplinePoint::Position position, + const QPointF pos); +public slots: + void RefreshLine(const qint32 &indexSpline, SplinePoint::Position pos, + const QPointF &controlPoint, const QPointF &splinePoint); + void setEnabledPoint(bool enable); protected: - qreal radius; - QGraphicsLineItem *controlLine; - virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event ); - virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); - QVariant itemChange ( GraphicsItemChange change, const QVariant &value ); + qreal radius; + QGraphicsLineItem *controlLine; + virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event ); + virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); + QVariant itemChange ( GraphicsItemChange change, const QVariant &value ); private: - qint32 LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1, - QPointF &p2) const; - QPointF ClosestPoint(QLineF line, QPointF p) const; - QPointF addVector (QPointF p, QPointF p1, QPointF p2, qreal k) const; + qint32 indexSpline; + SplinePoint::Position position; + qint32 LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1, + QPointF &p2) const; + QPointF ClosestPoint(QLineF line, QPointF p) const; + QPointF addVector (QPointF p, QPointF p1, QPointF p2, qreal k) const; }; diff --git a/xml/vdomdocument.cpp b/xml/vdomdocument.cpp index 3f8ef4b7d..cda330a3b 100644 --- a/xml/vdomdocument.cpp +++ b/xml/vdomdocument.cpp @@ -11,8 +11,10 @@ #include "../tools/vtoollineintersect.h" #include "../tools/vtoolspline.h" #include "../tools/vtoolarc.h" +#include "../tools/vtoolsplinepath.h" #include "../options.h" #include "../container/calculator.h" +#include "../geometry/vsplinepoint.h" VDomDocument::VDomDocument(VContainer *data) : QDomDocument() { @@ -367,20 +369,19 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen QString name; qreal mx=5, my=10, x, y; qint64 id; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - name = domElement.attribute("name", ""); - x = domElement.attribute("x","").toDouble()*PrintDPI/25.4; - y = domElement.attribute("y","").toDouble()*PrintDPI/25.4; - mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; - my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - data->UpdatePoint(id, VPointF(x, y, name, mx, my)); - if(parse == Document::FullParse){ - VToolSinglePoint *spoint = new VToolSinglePoint(this, data, id, Tool::FromFile); - scene->addItem(spoint); - connect(spoint, &VToolSinglePoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - } + id = domElement.attribute("id", "").toLongLong(); + name = domElement.attribute("name", ""); + x = domElement.attribute("x","").toDouble()*PrintDPI/25.4; + y = domElement.attribute("y","").toDouble()*PrintDPI/25.4; + mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; + my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; + + data->UpdatePoint(id, VPointF(x, y, name, mx, my)); + if(parse == Document::FullParse){ + VToolSinglePoint *spoint = new VToolSinglePoint(this, data, id, Tool::FromFile); + scene->addItem(spoint); + connect(spoint, &VToolSinglePoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); } } return; @@ -391,33 +392,32 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen qreal mx=5, my=10; qint64 id, basePointId; qint32 angle; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - name = domElement.attribute("name", ""); - mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; - my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - typeLine = domElement.attribute("typeLine", ""); - formula = domElement.attribute("length", ""); - basePointId = domElement.attribute("basePoint", "").toLongLong(); - angle = domElement.attribute("angle", "").toInt(); + id = domElement.attribute("id", "").toLongLong(); + name = domElement.attribute("name", ""); + mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; + my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - VPointF basePoint = data->GetPoint(basePointId); - QLineF line = QLineF(basePoint.toQPointF(), QPointF(basePoint.x()+100, basePoint.y())); - Calculator cal(data); - QString errorMsg; - qreal result = cal.eval(formula, &errorMsg); - if(errorMsg.isEmpty()){ - line.setLength(result*PrintDPI/25.4); - line.setAngle(angle); - data->UpdatePoint(id, VPointF(line.p2().x(), line.p2().y(), name, mx, my)); - data->AddLine(basePointId, id); - if(parse == Document::FullParse){ - VToolEndLine *point = new VToolEndLine(this, data, id, typeLine, formula, angle, - basePointId, Tool::FromFile); - scene->addItem(point); - connect(point, &VToolPoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - } + typeLine = domElement.attribute("typeLine", ""); + formula = domElement.attribute("length", ""); + basePointId = domElement.attribute("basePoint", "").toLongLong(); + angle = domElement.attribute("angle", "").toInt(); + + VPointF basePoint = data->GetPoint(basePointId); + QLineF line = QLineF(basePoint.toQPointF(), QPointF(basePoint.x()+100, basePoint.y())); + Calculator cal(data); + QString errorMsg; + qreal result = cal.eval(formula, &errorMsg); + if(errorMsg.isEmpty()){ + line.setLength(result*PrintDPI/25.4); + line.setAngle(angle); + data->UpdatePoint(id, VPointF(line.p2().x(), line.p2().y(), name, mx, my)); + data->AddLine(basePointId, id); + if(parse == Document::FullParse){ + VToolEndLine *point = new VToolEndLine(this, data, id, typeLine, formula, angle, + basePointId, Tool::FromFile); + scene->addItem(point); + connect(point, &VToolPoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); } } } @@ -428,34 +428,33 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen QString name, typeLine, formula; qreal mx=5, my=10; qint64 id, firstPointId, secondPointId; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - name = domElement.attribute("name", ""); - mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; - my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - typeLine = domElement.attribute("typeLine", ""); - formula = domElement.attribute("length", ""); - firstPointId = domElement.attribute("firstPoint", "").toLongLong(); - secondPointId = domElement.attribute("secondPoint", "").toLongLong(); + id = domElement.attribute("id", "").toLongLong(); + name = domElement.attribute("name", ""); + mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; + my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - VPointF firstPoint = data->GetPoint(firstPointId); - VPointF secondPoint = data->GetPoint(secondPointId); - QLineF line = QLineF(firstPoint.toQPointF(), secondPoint.toQPointF()); - Calculator cal(data); - QString errorMsg; - qreal result = cal.eval(formula, &errorMsg); - if(errorMsg.isEmpty()){ - line.setLength(result*PrintDPI/25.4); - data->UpdatePoint(id, VPointF(line.p2().x(), line.p2().y(), name, mx, my)); - data->AddLine(firstPointId, id); - data->AddLine(id, secondPointId); - if(parse == Document::FullParse){ - VToolAlongLine *point = new VToolAlongLine(this, data, id, formula, firstPointId, - secondPointId, typeLine, Tool::FromGui); - scene->addItem(point); - connect(point, &VToolAlongLine::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - } + typeLine = domElement.attribute("typeLine", ""); + formula = domElement.attribute("length", ""); + firstPointId = domElement.attribute("firstPoint", "").toLongLong(); + secondPointId = domElement.attribute("secondPoint", "").toLongLong(); + + VPointF firstPoint = data->GetPoint(firstPointId); + VPointF secondPoint = data->GetPoint(secondPointId); + QLineF line = QLineF(firstPoint.toQPointF(), secondPoint.toQPointF()); + Calculator cal(data); + QString errorMsg; + qreal result = cal.eval(formula, &errorMsg); + if(errorMsg.isEmpty()){ + line.setLength(result*PrintDPI/25.4); + data->UpdatePoint(id, VPointF(line.p2().x(), line.p2().y(), name, mx, my)); + data->AddLine(firstPointId, id); + data->AddLine(id, secondPointId); + if(parse == Document::FullParse){ + VToolAlongLine *point = new VToolAlongLine(this, data, id, formula, firstPointId, + secondPointId, typeLine, Tool::FromGui); + scene->addItem(point); + connect(point, &VToolAlongLine::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); } } } @@ -466,41 +465,41 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen QString name, typeLine, formula; qreal mx=5, my=10; qint64 id, p1Line, p2Line, pShoulder; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - name = domElement.attribute("name", ""); - mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; - my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - typeLine = domElement.attribute("typeLine", ""); - formula = domElement.attribute("length", ""); - p1Line = domElement.attribute("p1Line", "").toLongLong(); - p2Line = domElement.attribute("p2Line", "").toLongLong(); - pShoulder = domElement.attribute("pShoulder", "").toLongLong(); + id = domElement.attribute("id", "").toLongLong(); + name = domElement.attribute("name", ""); + mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; + my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - VPointF firstPoint = data->GetPoint(p1Line); - VPointF secondPoint = data->GetPoint(p2Line); - VPointF shoulderPoint = data->GetPoint(pShoulder); + typeLine = domElement.attribute("typeLine", ""); + formula = domElement.attribute("length", ""); + p1Line = domElement.attribute("p1Line", "").toLongLong(); + p2Line = domElement.attribute("p2Line", "").toLongLong(); + pShoulder = domElement.attribute("pShoulder", "").toLongLong(); - Calculator cal(data); - QString errorMsg; - qreal result = cal.eval(formula, &errorMsg); - if(errorMsg.isEmpty()){ - QPointF fPoint = VToolShoulderPoint::FindPoint(firstPoint, secondPoint, shoulderPoint, - result*PrintDPI/25.4); - data->UpdatePoint(id,VPointF(fPoint.x(), fPoint.y(), name, mx, my)); - data->AddLine(p1Line, id); - data->AddLine(p2Line, id); - if(parse == Document::FullParse){ - VToolShoulderPoint *point = new VToolShoulderPoint(this, data, id, typeLine, formula, - p1Line, p2Line, pShoulder, - Tool::FromGui); - scene->addItem(point); - connect(point, &VToolShoulderPoint::ChoosedTool, scene, - &VMainGraphicsScene::ChoosedItem); - } + VPointF firstPoint = data->GetPoint(p1Line); + VPointF secondPoint = data->GetPoint(p2Line); + VPointF shoulderPoint = data->GetPoint(pShoulder); + + Calculator cal(data); + QString errorMsg; + qreal result = cal.eval(formula, &errorMsg); + if(errorMsg.isEmpty()){ + QPointF fPoint = VToolShoulderPoint::FindPoint(firstPoint, secondPoint, shoulderPoint, + result*PrintDPI/25.4); + data->UpdatePoint(id,VPointF(fPoint.x(), fPoint.y(), name, mx, my)); + data->AddLine(p1Line, id); + data->AddLine(p2Line, id); + if(parse == Document::FullParse){ + VToolShoulderPoint *point = new VToolShoulderPoint(this, data, id, typeLine, formula, + p1Line, p2Line, pShoulder, + Tool::FromGui); + scene->addItem(point); + connect(point, &VToolShoulderPoint::ChoosedTool, scene, + &VMainGraphicsScene::ChoosedItem); } } + } return; } @@ -509,34 +508,33 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen QString name, typeLine, formula; qreal mx=5, my=10, angle; qint64 id, firstPointId, secondPointId; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - name = domElement.attribute("name", ""); - mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; - my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - typeLine = domElement.attribute("typeLine", ""); - formula = domElement.attribute("length", ""); - firstPointId = domElement.attribute("firstPoint", "").toLongLong(); - secondPointId = domElement.attribute("secondPoint", "").toLongLong(); - angle = domElement.attribute("angle", "").toInt(); + id = domElement.attribute("id", "").toLongLong(); + name = domElement.attribute("name", ""); + mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; + my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - VPointF firstPoint = data->GetPoint(firstPointId); - VPointF secondPoint = data->GetPoint(secondPointId); - Calculator cal(data); - QString errorMsg; - qreal result = cal.eval(formula, &errorMsg); - if(errorMsg.isEmpty()){ - QPointF fPoint = VToolNormal::FindPoint(firstPoint, secondPoint, result*PrintDPI/25.4, - angle); - data->UpdatePoint(id, VPointF(fPoint.x(), fPoint.y(), name, mx, my)); - data->AddLine(firstPointId, id); - if(parse == Document::FullParse){ - VToolNormal *point = new VToolNormal(this, data, id, typeLine, formula, angle, - firstPointId, secondPointId, Tool::FromFile); - scene->addItem(point); - connect(point, &VToolNormal::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - } + typeLine = domElement.attribute("typeLine", ""); + formula = domElement.attribute("length", ""); + firstPointId = domElement.attribute("firstPoint", "").toLongLong(); + secondPointId = domElement.attribute("secondPoint", "").toLongLong(); + angle = domElement.attribute("angle", "").toInt(); + + VPointF firstPoint = data->GetPoint(firstPointId); + VPointF secondPoint = data->GetPoint(secondPointId); + Calculator cal(data); + QString errorMsg; + qreal result = cal.eval(formula, &errorMsg); + if(errorMsg.isEmpty()){ + QPointF fPoint = VToolNormal::FindPoint(firstPoint, secondPoint, result*PrintDPI/25.4, + angle); + data->UpdatePoint(id, VPointF(fPoint.x(), fPoint.y(), name, mx, my)); + data->AddLine(firstPointId, id); + if(parse == Document::FullParse){ + VToolNormal *point = new VToolNormal(this, data, id, typeLine, formula, angle, + firstPointId, secondPointId, Tool::FromFile); + scene->addItem(point); + connect(point, &VToolNormal::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); } } } @@ -547,37 +545,36 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen QString name, typeLine, formula; qreal mx=5, my=10; qint64 id, firstPointId, secondPointId, thirdPointId; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - name = domElement.attribute("name", ""); - mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; - my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - typeLine = domElement.attribute("typeLine", ""); - formula = domElement.attribute("length", ""); - firstPointId = domElement.attribute("firstPoint", "").toLongLong(); - secondPointId = domElement.attribute("secondPoint", "").toLongLong(); - thirdPointId = domElement.attribute("thirdPoint", "").toLongLong(); + id = domElement.attribute("id", "").toLongLong(); + name = domElement.attribute("name", ""); + mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; + my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - VPointF firstPoint = data->GetPoint(firstPointId); - VPointF secondPoint = data->GetPoint(secondPointId); - VPointF thirdPoint = data->GetPoint(thirdPointId); + typeLine = domElement.attribute("typeLine", ""); + formula = domElement.attribute("length", ""); + firstPointId = domElement.attribute("firstPoint", "").toLongLong(); + secondPointId = domElement.attribute("secondPoint", "").toLongLong(); + thirdPointId = domElement.attribute("thirdPoint", "").toLongLong(); - Calculator cal(data); - QString errorMsg; - qreal result = cal.eval(formula, &errorMsg); - if(errorMsg.isEmpty()){ - QPointF fPoint = VToolBisector::FindPoint(firstPoint, secondPoint, thirdPoint, - result*PrintDPI/25.4); - data->UpdatePoint(id, VPointF(fPoint.x(), fPoint.y(), name, mx, my)); - data->AddLine(firstPointId, id); - if(parse == Document::FullParse){ - VToolBisector *point = new VToolBisector(this, data, id, typeLine, formula, - firstPointId, secondPointId, thirdPointId, - Tool::FromFile); - scene->addItem(point); - connect(point, &VToolBisector::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - } + VPointF firstPoint = data->GetPoint(firstPointId); + VPointF secondPoint = data->GetPoint(secondPointId); + VPointF thirdPoint = data->GetPoint(thirdPointId); + + Calculator cal(data); + QString errorMsg; + qreal result = cal.eval(formula, &errorMsg); + if(errorMsg.isEmpty()){ + QPointF fPoint = VToolBisector::FindPoint(firstPoint, secondPoint, thirdPoint, + result*PrintDPI/25.4); + data->UpdatePoint(id, VPointF(fPoint.x(), fPoint.y(), name, mx, my)); + data->AddLine(firstPointId, id); + if(parse == Document::FullParse){ + VToolBisector *point = new VToolBisector(this, data, id, typeLine, formula, + firstPointId, secondPointId, thirdPointId, + Tool::FromFile); + scene->addItem(point); + connect(point, &VToolBisector::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); } } } @@ -588,40 +585,39 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen QString name; qreal mx=5, my=10; qint64 id, p1Line1Id, p2Line1Id, p1Line2Id, p2Line2Id; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - name = domElement.attribute("name", ""); - mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; - my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - p1Line1Id = domElement.attribute("p1Line1", "").toLongLong(); - p2Line1Id = domElement.attribute("p2Line1", "").toLongLong(); - p1Line2Id = domElement.attribute("p1Line2", "").toLongLong(); - p2Line2Id = domElement.attribute("p2Line2", "").toLongLong(); + id = domElement.attribute("id", "").toLongLong(); + name = domElement.attribute("name", ""); + mx = domElement.attribute("mx","").toDouble()*PrintDPI/25.4; + my = domElement.attribute("my","").toDouble()*PrintDPI/25.4; - VPointF p1Line1 = data->GetPoint(p1Line1Id); - VPointF p2Line1 = data->GetPoint(p2Line1Id); - VPointF p1Line2 = data->GetPoint(p1Line2Id); - VPointF p2Line2 = data->GetPoint(p2Line2Id); + p1Line1Id = domElement.attribute("p1Line1", "").toLongLong(); + p2Line1Id = domElement.attribute("p2Line1", "").toLongLong(); + p1Line2Id = domElement.attribute("p1Line2", "").toLongLong(); + p2Line2Id = domElement.attribute("p2Line2", "").toLongLong(); - QLineF line1(p1Line1, p2Line1); - QLineF line2(p1Line2, p2Line2); - QPointF fPoint; - QLineF::IntersectType intersect = line1.intersect(line2, &fPoint); - if(intersect == QLineF::UnboundedIntersection || intersect == QLineF::BoundedIntersection){ - data->UpdatePoint(id, VPointF(fPoint.x(), fPoint.y(), name, mx, my)); - data->AddLine(p1Line1Id, id); - data->AddLine(id, p2Line1Id); - data->AddLine(p1Line2Id, id); - data->AddLine(id, p2Line2Id); - if(parse == Document::FullParse){ - VToolLineIntersect *point = new VToolLineIntersect(this, data, id, p1Line1Id, - p2Line1Id, p1Line2Id, - p2Line2Id, Tool::FromFile); - scene->addItem(point); - connect(point, &VToolLineIntersect::ChoosedTool, scene, - &VMainGraphicsScene::ChoosedItem); - } + VPointF p1Line1 = data->GetPoint(p1Line1Id); + VPointF p2Line1 = data->GetPoint(p2Line1Id); + VPointF p1Line2 = data->GetPoint(p1Line2Id); + VPointF p2Line2 = data->GetPoint(p2Line2Id); + + QLineF line1(p1Line1, p2Line1); + QLineF line2(p1Line2, p2Line2); + QPointF fPoint; + QLineF::IntersectType intersect = line1.intersect(line2, &fPoint); + if(intersect == QLineF::UnboundedIntersection || intersect == QLineF::BoundedIntersection){ + data->UpdatePoint(id, VPointF(fPoint.x(), fPoint.y(), name, mx, my)); + data->AddLine(p1Line1Id, id); + data->AddLine(id, p2Line1Id); + data->AddLine(p1Line2Id, id); + data->AddLine(id, p2Line2Id); + if(parse == Document::FullParse){ + VToolLineIntersect *point = new VToolLineIntersect(this, data, id, p1Line1Id, + p2Line1Id, p1Line2Id, + p2Line2Id, Tool::FromFile); + scene->addItem(point); + connect(point, &VToolLineIntersect::ChoosedTool, scene, + &VMainGraphicsScene::ChoosedItem); } } } @@ -634,16 +630,15 @@ void VDomDocument::ParseLineElement(VMainGraphicsScene *scene, const QDomElement if(!domElement.isNull()){ qint64 firstPoint; qint64 secondPoint; - if(!domElement.isNull()){ - firstPoint = domElement.attribute("firstPoint", "").toLongLong(); - secondPoint = domElement.attribute("secondPoint", "").toLongLong(); - data->AddLine(firstPoint, secondPoint); - if(parse == Document::FullParse){ - qint64 id = data->getNextId(); - VToolLine *line = new VToolLine(this, data, id, firstPoint, secondPoint, Tool::FromFile); - scene->addItem(line); - connect(line, &VToolLine::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - } + + firstPoint = domElement.attribute("firstPoint", "").toLongLong(); + secondPoint = domElement.attribute("secondPoint", "").toLongLong(); + data->AddLine(firstPoint, secondPoint); + if(parse == Document::FullParse){ + qint64 id = data->getNextId(); + VToolLine *line = new VToolLine(this, data, id, firstPoint, secondPoint, Tool::FromFile); + scene->addItem(line); + connect(line, &VToolLine::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); } } } @@ -654,25 +649,58 @@ void VDomDocument::ParseSplineElement(VMainGraphicsScene *scene, const QDomEleme if(!domElement.isNull()){ qreal angle1, angle2, kAsm1, kAsm2, kCurve; qint64 id, point1, point4; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - point1 = domElement.attribute("point1", "").toLongLong(); - point4 = domElement.attribute("point4", "").toLongLong(); - angle1 = domElement.attribute("angle1","").toDouble(); - angle2 = domElement.attribute("angle2","").toDouble(); - kAsm1 = domElement.attribute("kAsm1","").toDouble(); - kAsm2 = domElement.attribute("kAsm2","").toDouble(); - kCurve = domElement.attribute("kCurve","").toDouble(); - VSpline spline = VSpline(data->DataPoints(), point1, point4, angle1, angle2, kAsm1, kAsm2, kCurve); - data->UpdateSpline(id, spline); - data->AddLengthSpline(data->GetNameSpline(point1, point4), spline.GetLength()); - if(parse == Document::FullParse){ - VToolSpline *spl = new VToolSpline(this, data, id, Tool::FromFile); - scene->addItem(spl); - connect(spl, &VToolSpline::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); + id = domElement.attribute("id", "").toLongLong(); + point1 = domElement.attribute("point1", "").toLongLong(); + point4 = domElement.attribute("point4", "").toLongLong(); + angle1 = domElement.attribute("angle1","").toDouble(); + angle2 = domElement.attribute("angle2","").toDouble(); + kAsm1 = domElement.attribute("kAsm1","").toDouble(); + kAsm2 = domElement.attribute("kAsm2","").toDouble(); + kCurve = domElement.attribute("kCurve","").toDouble(); + + VSpline spline = VSpline(data->DataPoints(), point1, point4, angle1, angle2, kAsm1, kAsm2, kCurve); + data->UpdateSpline(id, spline); + data->AddLengthSpline(data->GetNameSpline(point1, point4), spline.GetLength()); + if(parse == Document::FullParse){ + VToolSpline *spl = new VToolSpline(this, data, id, Tool::FromFile); + scene->addItem(spl); + connect(spl, &VToolSpline::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); + } + } + return; + } + if(type == "path"){ + if(!domElement.isNull()){ + + qint64 id = domElement.attribute("id", "").toLongLong(); + qreal kCurve = domElement.attribute("kCurve","").toDouble(); + VSplinePath path(data->DataPoints(), kCurve); + + QDomNodeList nodeList = domElement.childNodes(); + qint32 num = nodeList.size(); + for(qint32 i = 0; i < num; ++i){ + QDomElement element = nodeList.at(i).toElement(); + if(!element.isNull()){ + if(element.tagName() == "pathPoint"){ + qint64 pSpline = element.attribute("pSpline","").toLongLong(); + qreal kAsm1 = element.attribute("kAsm1","").toDouble(); + qreal angle = element.attribute("angle","").toDouble(); + qreal kAsm2 = element.attribute("kAsm2","").toDouble(); + VSplinePoint splPoint(pSpline, kAsm1, angle, kAsm2); + path.append(splPoint); + } + } } + + data->UpdateSplinePath(id, path); + data->AddLengthSpline(data->GetNameSplinePath(path), path.GetLength()); + if(parse == Document::FullParse){ + VToolSplinePath *spl = new VToolSplinePath(this, data, id, Tool::FromFile); + scene->addItem(spl); + connect(spl, &VToolSplinePath::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); + } } return; } @@ -684,42 +712,41 @@ void VDomDocument::ParseArcElement(VMainGraphicsScene *scene, const QDomElement if(!domElement.isNull()){ QString radius, f1, f2; qint64 id, center; - if(!domElement.isNull()){ - id = domElement.attribute("id", "").toLongLong(); - center = domElement.attribute("center", "").toLongLong(); - radius = domElement.attribute("radius", ""); - f1 = domElement.attribute("angle1", ""); - f2 = domElement.attribute("angle2",""); - qreal calcRadius = 0, calcF1 = 0, calcF2 = 0; + id = domElement.attribute("id", "").toLongLong(); + center = domElement.attribute("center", "").toLongLong(); + radius = domElement.attribute("radius", ""); + f1 = domElement.attribute("angle1", ""); + f2 = domElement.attribute("angle2",""); - Calculator cal(data); - QString errorMsg; - qreal result = cal.eval(radius, &errorMsg); - if(errorMsg.isEmpty()){ - calcRadius = result*PrintDPI/25.4; - } + qreal calcRadius = 0, calcF1 = 0, calcF2 = 0; - errorMsg.clear(); - result = cal.eval(f1, &errorMsg); - if(errorMsg.isEmpty()){ - calcF1 = result; - } + Calculator cal(data); + QString errorMsg; + qreal result = cal.eval(radius, &errorMsg); + if(errorMsg.isEmpty()){ + calcRadius = result*PrintDPI/25.4; + } - errorMsg.clear(); - result = cal.eval(f2, &errorMsg); - if(errorMsg.isEmpty()){ - calcF2 = result; - } + errorMsg.clear(); + result = cal.eval(f1, &errorMsg); + if(errorMsg.isEmpty()){ + calcF1 = result; + } - VArc arc = VArc(data->DataPoints(), center, calcRadius, radius, calcF1, f1, calcF2, f2 ); - data->UpdateArc(id, arc); - data->AddLengthArc(data->GetNameArc(center,id), arc.GetLength()); - if(parse == Document::FullParse){ - VToolArc *toolArc = new VToolArc(this, data, id, Tool::FromFile); - scene->addItem(toolArc); - connect(toolArc, &VToolArc::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); - } + errorMsg.clear(); + result = cal.eval(f2, &errorMsg); + if(errorMsg.isEmpty()){ + calcF2 = result; + } + + VArc arc = VArc(data->DataPoints(), center, calcRadius, radius, calcF1, f1, calcF2, f2 ); + data->UpdateArc(id, arc); + data->AddLengthArc(data->GetNameArc(center,id), arc.GetLength()); + if(parse == Document::FullParse){ + VToolArc *toolArc = new VToolArc(this, data, id, Tool::FromFile); + scene->addItem(toolArc); + connect(toolArc, &VToolArc::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); } } return;