Add tool splinepath

This commit is contained in:
dismine 2013-08-09 09:49:34 +03:00
parent 30ec4ed2f2
commit 309f190921
26 changed files with 1542 additions and 331 deletions

View File

@ -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 \

View File

@ -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();
}

View File

@ -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 &center, 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 = "<<id<<" в таблиці.";
throw"Не можу знайти дугу за id.";
}
return VSplinePath();
}
const QMap<QString, qreal> *VContainer::DataLengthArcs() const{
return &lengthArcs;
@ -348,3 +386,7 @@ const QMap<QString, qreal> *VContainer::DataLengthArcs() const{
const QMap<QString, qreal> *VContainer::DataLineArcs() const{
return &lineArcs;
}
const QMap<qint64, VSplinePath> *VContainer::DataSplinePaths() const{
return &splinePaths;
}

View File

@ -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 &center, 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<QString, qreal> *DataLengthSplines() const;
const QMap<QString, qreal> *DataLengthArcs() const;
const QMap<QString, qreal> *DataLineArcs() const;
const QMap<qint64, VSplinePath> *DataSplinePaths() const;
private:
qint64 _id;
QMap<QString, qint32> base;
@ -91,6 +97,7 @@ private:
QMap<QString, qreal> lengthSplines;
QMap<qint64, VArc> arcs;
QMap<QString, qreal> lengthArcs;
QMap<qint64, VSplinePath> splinePaths;
};
#endif // VCONTAINER_H

View File

@ -10,5 +10,6 @@
<file>cursor/intersect_cursor.png</file>
<file>cursor/spline_cursor.png</file>
<file>cursor/arc_cursor.png</file>
<file>cursor/splinepath_cursor.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,179 @@
#include "dialogsplinepath.h"
#include "ui_dialogsplinepath.h"
#include "../geometry/vsplinepoint.h"
DialogSplinePath::DialogSplinePath(const VContainer *data, QWidget *parent) :
DialogTool(data, parent), ui(new Ui::DialogSplinePath)
{
ui->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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &DialogSplinePath::currentPointChanged);
connect(ui->spinBoxAngle1, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &DialogSplinePath::Angle1Changed);
connect(ui->spinBoxAngle2, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &DialogSplinePath::Angle2Changed);
connect(ui->doubleSpinBoxKasm1, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &DialogSplinePath::KAsm1Changed);
connect(ui->doubleSpinBoxKasm2, static_cast<void (QDoubleSpinBox::*)(double)>(&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<VSplinePoint>(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<VSplinePoint>(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<qint64>(ui->comboBoxPoint->itemData(index));
qint32 row = ui->listWidget->currentRow();
QListWidgetItem *item = ui->listWidget->item( row );
VSplinePoint p = qvariant_cast<VSplinePoint>(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<VSplinePoint>(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<VSplinePoint>(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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &DialogSplinePath::currentPointChanged);
disconnect(ui->spinBoxAngle1, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &DialogSplinePath::Angle1Changed);
disconnect(ui->spinBoxAngle2, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &DialogSplinePath::Angle2Changed);
disconnect(ui->doubleSpinBoxKasm1, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &DialogSplinePath::KAsm1Changed);
disconnect(ui->doubleSpinBoxKasm2, static_cast<void (QDoubleSpinBox::*)(double)>(&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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &DialogSplinePath::currentPointChanged);
connect(ui->spinBoxAngle1, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &DialogSplinePath::Angle1Changed);
connect(ui->spinBoxAngle2, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &DialogSplinePath::Angle2Changed);
connect(ui->doubleSpinBoxKasm1, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &DialogSplinePath::KAsm1Changed);
connect(ui->doubleSpinBoxKasm2, static_cast<void (QDoubleSpinBox::*)(double)>(&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<VSplinePoint>(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));
}

View File

@ -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

219
dialogs/dialogsplinepath.ui Normal file
View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogSplinePath</class>
<widget class="QDialog" name="DialogSplinePath">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>524</width>
<height>321</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Точка сплайну</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxPoint"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Коефіцієнт довжини першої контрольної точки</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBoxKasm1">
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Кут першої контрольної точки</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBoxAngle1">
<property name="maximum">
<number>360</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Коефіцієнт довжини другої контрольної точки</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBoxKasm2">
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Кут другої контрольної точки</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBoxAngle2">
<property name="maximum">
<number>360</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Коефіцієнт кривизни сплайну</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBoxKcurve">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>72</width>
<height>0</height>
</size>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
<zorder>buttonBox</zorder>
<zorder>layoutWidget_2</zorder>
<zorder></zorder>
<zorder>horizontalLayoutWidget</zorder>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DialogSplinePath</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DialogSplinePath</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

116
geometry/vsplinepath.cpp Normal file
View File

@ -0,0 +1,116 @@
#include "vsplinepath.h"
VSplinePath::VSplinePath(){
points = 0;
kCurve = 1;
}
VSplinePath::VSplinePath(const QMap<qint64, VPointF> *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<VSplinePoint> 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<qint64, VPointF> *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<VSplinePoint> *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];
}

61
geometry/vsplinepath.h Normal file
View File

@ -0,0 +1,61 @@
#ifndef VSPLINEPATH_H
#define VSPLINEPATH_H
#include "vsplinepoint.h"
#include <QVector>
#include "vspline.h"
namespace SplinePoint{
enum Position
{
FirstPoint,
LastPoint
};
}
/**
* @brief The VSplinePath клас, що розраховує шлях сплайнів.
*/
class VSplinePath{
public:
/**
* @brief VSplinePath конструктор по замовчуванню.
*/
VSplinePath();
/**
* @brief VSplinePath конструктор по замовчуванню.
*/
VSplinePath(const QMap<qint64, VPointF> *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<VSplinePoint> GetSplinePath() const;
qreal GetLength() const;
const QMap<qint64, VPointF> *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<VSplinePoint> *GetPoint() const;
VSplinePath& operator=(const VSplinePath &path);
VSplinePoint & operator[](int indx);
protected:
/**
* @brief path вектор з точок сплайна.
*/
QVector<VSplinePoint> path;
qreal kCurve;
const QMap<qint64, VPointF> *points;
};
#endif // VSPLINEPATH_H

61
geometry/vsplinepoint.cpp Normal file
View File

@ -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;
}

75
geometry/vsplinepoint.h Normal file
View File

@ -0,0 +1,75 @@
#ifndef VSPLINEPOINT_H
#define VSPLINEPOINT_H
#include "QtGlobal"
#include <QMetaType>
/**
* @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

View File

@ -28,5 +28,6 @@
<file>icon/32x32/spline.png</file>
<file>icon/32x32/arc.png</file>
<file>icon/24x24/putHereLeft.png</file>
<file>icon/32x32/splinePath.png</file>
</qresource>
</RCC>

BIN
icon/32x32/splinePath.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

View File

@ -20,6 +20,7 @@
#include "tools/vtoollineintersect.h"
#include "tools/vtoolspline.h"
#include "tools/vtoolarc.h"
#include "tools/vtoolsplinepath.h"
#include "geometry/vspline.h"
MainWindow::MainWindow(QWidget *parent) :
@ -68,6 +69,8 @@ MainWindow::MainWindow(QWidget *parent) :
&MainWindow::ToolSpline);
connect(ui->toolButtonArc, &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(){

View File

@ -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;

View File

@ -57,7 +57,7 @@
</sizepolicy>
</property>
<property name="currentIndex">
<number>3</number>
<number>2</number>
</property>
<widget class="QWidget" name="page">
<property name="geometry">
@ -333,6 +333,29 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="toolButtonSplinePath">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="icon.qrc">
<normaloff>:/icon/32x32/splinePath.png</normaloff>:/icon/32x32/splinePath.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_4">

View File

@ -12,7 +12,8 @@ namespace Scene{
Point,
Line,
Spline,
Arc
Arc,
SplinePath
};
}

View File

@ -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);
if(position == SplinePoint::FirstPoint){
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();
}
}
void VToolSpline::ControlPoint2ChangePosition(const QPointF pos){
VSpline spl = VAbstractTool::data->GetSpline(id);
} else {
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);
}
}

View File

@ -7,6 +7,7 @@
#include <QGraphicsPathItem>
#include "../dialogs/dialogspline.h"
#include "../widgets/vcontrolpointspline.h"
#include "../geometry/vsplinepath.h"
class VToolSpline:public VAbstractTool, public QGraphicsPathItem
{
@ -14,11 +15,16 @@ class VToolSpline:public VAbstractTool, public QGraphicsPathItem
public:
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);
void ControlPointChangePosition ( const qint32 &indexSpline,
SplinePoint::Position position,
const QPointF pos);
virtual void ChangedActivDraw ( const QString newName );
protected:
virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event );
@ -28,8 +34,7 @@ protected:
virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event );
private:
QSharedPointer<DialogSpline> dialogSpline;
VControlPointSpline *controlPoint1;
VControlPointSpline *controlPoint2;
QVector<VControlPointSpline *> controlPoints;
void RefreshGeometry ();
};

243
tools/vtoolsplinepath.cpp Normal file
View File

@ -0,0 +1,243 @@
#include "vtoolsplinepath.h"
#include <QMenu>
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<DialogSplinePath>(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);
}
}

45
tools/vtoolsplinepath.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef VTOOLSPLINEPATH_H
#define VTOOLSPLINEPATH_H
#include "vabstracttool.h"
#include "../container/vcontainer.h"
#include "../xml/vdomdocument.h"
#include <QGraphicsPathItem>
#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> dialogSplinePath;
QVector<VControlPointSpline *> 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

View File

@ -4,9 +4,12 @@
#include <QGraphicsScene>
#include <QDebug>
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);
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);
}
}

View File

@ -5,14 +5,22 @@
#include <QGraphicsLineItem>
#include <QObject>
#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;
@ -20,6 +28,8 @@ protected:
virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event );
QVariant itemChange ( GraphicsItemChange change, const QVariant &value );
private:
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;

View File

@ -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,7 +369,7 @@ 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;
@ -382,7 +384,6 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
connect(spoint, &VToolSinglePoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
}
}
}
return;
}
if(type == "endLine"){
@ -391,7 +392,7 @@ 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;
@ -420,7 +421,6 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
}
}
}
}
return;
}
if(type == "alongLine"){
@ -428,7 +428,7 @@ 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;
@ -458,7 +458,6 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
}
}
}
}
return;
}
if(type == "shoulder"){
@ -466,7 +465,7 @@ 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;
@ -500,7 +499,7 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
&VMainGraphicsScene::ChoosedItem);
}
}
}
}
return;
}
@ -509,7 +508,7 @@ 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;
@ -539,7 +538,6 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
}
}
}
}
return;
}
if(type == "bisector"){
@ -547,7 +545,7 @@ 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;
@ -580,7 +578,6 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
}
}
}
}
return;
}
if(type == "lineIntersect"){
@ -588,7 +585,7 @@ 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;
@ -624,7 +621,6 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
}
}
}
}
return;
}
}
@ -634,7 +630,7 @@ 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);
@ -646,7 +642,6 @@ void VDomDocument::ParseLineElement(VMainGraphicsScene *scene, const QDomElement
}
}
}
}
void VDomDocument::ParseSplineElement(VMainGraphicsScene *scene, const QDomElement &domElement,
Document::Enum parse, const QString &type){
@ -654,7 +649,7 @@ 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();
@ -673,6 +668,39 @@ void VDomDocument::ParseSplineElement(VMainGraphicsScene *scene, const QDomEleme
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,7 +712,7 @@ 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", "");
@ -721,7 +749,6 @@ void VDomDocument::ParseArcElement(VMainGraphicsScene *scene, const QDomElement
connect(toolArc, &VToolArc::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
}
}
}
return;
}
}