diff --git a/src/app/dialogs/dialogs.h b/src/app/dialogs/dialogs.h index 44da6ae42..e83eedc77 100644 --- a/src/app/dialogs/dialogs.h +++ b/src/app/dialogs/dialogs.h @@ -50,6 +50,7 @@ #include "tools/dialogtriangle.h" #include "tools/dialogpointofintersection.h" #include "tools/dialoglineintersectaxis.h" +#include "tools/dialogcurveintersectaxis.h" #include "app/dialoghistory.h" #include "app/dialogincrements.h" diff --git a/src/app/dialogs/dialogs.pri b/src/app/dialogs/dialogs.pri index f19de3229..a154dcdd8 100644 --- a/src/app/dialogs/dialogs.pri +++ b/src/app/dialogs/dialogs.pri @@ -37,7 +37,8 @@ HEADERS += \ dialogs/app/configpages/patternpage.h \ dialogs/app/configpages/communitypage.h \ dialogs/app/configpages/pathpage.h \ - dialogs/app/dialogundo.h + dialogs/app/dialogundo.h \ + dialogs/tools/dialogcurveintersectaxis.h SOURCES += \ dialogs/tools/dialogtriangle.cpp \ @@ -76,7 +77,8 @@ SOURCES += \ dialogs/app/configpages/patternpage.cpp \ dialogs/app/configpages/communitypage.cpp \ dialogs/app/configpages/pathpage.cpp \ - dialogs/app/dialogundo.cpp + dialogs/app/dialogundo.cpp \ + dialogs/tools/dialogcurveintersectaxis.cpp FORMS += \ dialogs/tools/dialogtriangle.ui \ @@ -110,3 +112,4 @@ FORMS += \ dialogs/app/dialogaboutapp.ui \ dialogs/app/dialogpatternxmledit.ui \ dialogs/app/dialogundo.ui \ + dialogs/tools/dialogcurveintersectaxis.ui diff --git a/src/app/dialogs/tools/dialogcurveintersectaxis.cpp b/src/app/dialogs/tools/dialogcurveintersectaxis.cpp new file mode 100644 index 000000000..2b9c05bff --- /dev/null +++ b/src/app/dialogs/tools/dialogcurveintersectaxis.cpp @@ -0,0 +1,269 @@ +/************************************************************************ + ** + ** @file dialogcurveintersectaxis.cpp + ** @author Roman Telezhynskyi + ** @date 21 10, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "dialogcurveintersectaxis.h" +#include "ui_dialogcurveintersectaxis.h" + +#include "../../geometry/vpointf.h" +#include "../../container/vcontainer.h" +#include "../../visualization/vistoolcurveintersectaxis.h" +#include "../../widgets/vmaingraphicsscene.h" +#include "../../tools/vabstracttool.h" +#include + +//--------------------------------------------------------------------------------------------------------------------- +DialogCurveIntersectAxis::DialogCurveIntersectAxis(const VContainer *data, const quint32 &toolId, QWidget *parent) + :DialogTool(data, toolId, parent), ui(new Ui::DialogCurveIntersectAxis), number(0), typeLine(QString()), + formulaAngle(QString()), basePointId(NULL_ID), curveId(NULL_ID), formulaBaseHeightAngle(0), line(nullptr) +{ + ui->setupUi(this); + + InitVariables(ui); + InitFormulaUI(ui); + ui->lineEditNamePoint->setText(qApp->getCurrentDocument()->GenerateLabel(LabelType::NewLabel)); + labelEditNamePoint = ui->labelEditNamePoint; + this->formulaBaseHeightAngle = ui->plainTextEditFormula->height(); + + InitOkCancelApply(ui); + flagFormula = false; + CheckState(); + + FillComboBoxPoints(ui->comboBoxAxisPoint); + FillComboBoxCurves(ui->comboBoxCurve); + FillComboBoxTypeLine(ui->comboBoxLineType); + + connect(ui->toolButtonPutHereAngle, &QPushButton::clicked, this, &DialogCurveIntersectAxis::PutAngle); + connect(listWidget, &QListWidget::itemDoubleClicked, this, &DialogCurveIntersectAxis::PutVal); + connect(ui->toolButtonEqualAngle, &QPushButton::clicked, this, &DialogCurveIntersectAxis::EvalAngle); + connect(ui->lineEditNamePoint, &QLineEdit::textChanged, this, &DialogCurveIntersectAxis::NamePointChanged); + connect(ui->plainTextEditFormula, &QPlainTextEdit::textChanged, this, &DialogCurveIntersectAxis::AngleTextChanged); + connect(ui->pushButtonGrowLengthAngle, &QPushButton::clicked, this, &DialogCurveIntersectAxis::DeployAngleTextEdit); + connect(timerFormula, &QTimer::timeout, this, &DialogCurveIntersectAxis::EvalAngle); + + line = new VisToolCurveIntersectAxis(data); +} + +//--------------------------------------------------------------------------------------------------------------------- +DialogCurveIntersectAxis::~DialogCurveIntersectAxis() +{ + delete line; + delete ui; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogCurveIntersectAxis::getPointName() const +{ + return pointName; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::setPointName(const QString &value) +{ + pointName = value; + ui->lineEditNamePoint->setText(pointName); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogCurveIntersectAxis::getTypeLine() const +{ + return typeLine; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::setTypeLine(const QString &value) +{ + typeLine = value; + SetupTypeLine(ui->comboBoxLineType, value); + line->setLineStyle(VAbstractTool::LineStyle(typeLine)); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogCurveIntersectAxis::getAngle() const +{ + return qApp->FormulaFromUser(formulaAngle); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::setAngle(const QString &value) +{ + formulaAngle = qApp->FormulaToUser(value); + // increase height if needed. TODO : see if I can get the max number of caracters in one line + // of this PlainTextEdit to change 80 to this value + if (formulaAngle.length() > 80) + { + this->DeployAngleTextEdit(); + } + ui->plainTextEditFormula->setPlainText(formulaAngle); + line->setAngle(formulaAngle); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 DialogCurveIntersectAxis::getBasePointId() const +{ + return basePointId; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::setBasePointId(const quint32 &value) +{ + setCurrentPointId(ui->comboBoxAxisPoint, basePointId, value); + line->setAxisPointId(value); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 DialogCurveIntersectAxis::getCurveId() const +{ + return curveId; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::setCurveId(const quint32 &value) +{ + setCurrentCurveId(ui->comboBoxCurve, curveId, value); + line->setPoint1Id(value); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::ShowDialog(bool click) +{ + if (prepare) + { + if (click) + { + /*We will ignore click if poinet is in point circle*/ + VMainGraphicsScene *scene = qApp->getCurrentScene(); + SCASSERT(scene != nullptr); + const QSharedPointer point = data->GeometricObject(basePointId); + QLineF line = QLineF(point->toQPointF(), scene->getScenePos()); + + //Radius of point circle, but little bigger. Need handle with hover sizes. + qreal radius = qApp->toPixel(DefPointRadius/*mm*/, Unit::Mm)*1.5; + if (line.length() <= radius) + { + return; + } + } + this->setModal(true); + this->setAngle(line->Angle());//Show in dialog angle what user choose + emit ToolTip(""); + timerFormula->start(); + this->show(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::ChosenObject(quint32 id, const SceneObject &type) +{ + if (prepare == false)// After first choose we ignore all objects + { + switch (number) + { + case (0): + if (type == SceneObject::Spline || type == SceneObject::Arc || type == SceneObject::SplinePath) + { + if (SetObject(id, ui->comboBoxCurve, tr("Select axis point"))) + { + number++; + line->VisualMode(id); + } + } + break; + case (1): + if (type == SceneObject::Point) + { + if (SetObject(id, ui->comboBoxAxisPoint, "")) + { + basePointId = id; + line->setAxisPointId(id); + line->RefreshGeometry(); + prepare = true; + } + } + break; + default: + break; + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::PutAngle() +{ + PutValHere(ui->plainTextEditFormula, ui->listWidget); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::EvalAngle() +{ + const QString postfix = QStringLiteral("°"); + Eval(ui->plainTextEditFormula->toPlainText(), flagError, ui->labelResultCalculation, postfix, false); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::AngleTextChanged() +{ + ValFormulaChanged(flagError, ui->plainTextEditFormula, timerFormula); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::DeployAngleTextEdit() +{ + DeployFormula(ui->plainTextEditFormula, ui->pushButtonGrowLengthAngle, formulaBaseHeightAngle); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::ShowVisualization() +{ + if (prepare == false) + { + //TODO move to parent class! + VMainGraphicsScene *scene = qApp->getCurrentScene(); + connect(scene, &VMainGraphicsScene::NewFactor, line, &VisToolCurveIntersectAxis::SetFactor); + scene->addItem(line); + line->RefreshGeometry(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogCurveIntersectAxis::SaveData() +{ + pointName = ui->lineEditNamePoint->text(); + typeLine = GetTypeLine(ui->comboBoxLineType); + + formulaAngle = ui->plainTextEditFormula->toPlainText(); + formulaAngle.replace("\n", " "); + + basePointId = getCurrentObjectId(ui->comboBoxAxisPoint); + curveId = getCurrentObjectId(ui->comboBoxCurve); + + line->setPoint1Id(curveId); + line->setAxisPointId(basePointId); + line->setAngle(formulaAngle); + line->setLineStyle(VAbstractTool::LineStyle(typeLine)); + line->RefreshGeometry(); +} diff --git a/src/app/dialogs/tools/dialogcurveintersectaxis.h b/src/app/dialogs/tools/dialogcurveintersectaxis.h new file mode 100644 index 000000000..19b83efc6 --- /dev/null +++ b/src/app/dialogs/tools/dialogcurveintersectaxis.h @@ -0,0 +1,94 @@ +/************************************************************************ + ** + ** @file dialogcurveintersectaxis.h + ** @author Roman Telezhynskyi + ** @date 21 10, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef DIALOGCURVEINTERSECTAXIS_H +#define DIALOGCURVEINTERSECTAXIS_H + +#include "dialogtool.h" + +namespace Ui { +class DialogCurveIntersectAxis; +} + +class VisToolCurveIntersectAxis; + +class DialogCurveIntersectAxis : public DialogTool +{ + Q_OBJECT + +public: + DialogCurveIntersectAxis(const VContainer *data, const quint32 &toolId, QWidget *parent = nullptr); + ~DialogCurveIntersectAxis(); + + QString getPointName() const; + void setPointName(const QString &value); + + QString getTypeLine() const; + void setTypeLine(const QString &value); + + QString getAngle() const; + void setAngle(const QString &value); + + quint32 getBasePointId() const; + void setBasePointId(const quint32 &value); + + quint32 getCurveId() const; + void setCurveId(const quint32 &value); + + virtual void ShowDialog(bool click); +public slots: + virtual void ChosenObject(quint32 id, const SceneObject &type); + void PutAngle(); + void EvalAngle(); + void AngleTextChanged(); + void DeployAngleTextEdit(); +protected: + virtual void ShowVisualization(); + /** + * @brief SaveData Put dialog data in local variables + */ + virtual void SaveData(); +private: + Q_DISABLE_COPY(DialogCurveIntersectAxis) + Ui::DialogCurveIntersectAxis *ui; + + /** @brief number number of handled objects */ + qint32 number; + + /** @brief typeLine type of line */ + QString typeLine; + + QString formulaAngle; + quint32 basePointId; + quint32 curveId; + int formulaBaseHeightAngle; + + VisToolCurveIntersectAxis *line; +}; + +#endif // DIALOGCURVEINTERSECTAXIS_H diff --git a/src/app/dialogs/tools/dialogcurveintersectaxis.ui b/src/app/dialogs/tools/dialogcurveintersectaxis.ui new file mode 100644 index 000000000..9e4509880 --- /dev/null +++ b/src/app/dialogs/tools/dialogcurveintersectaxis.ui @@ -0,0 +1,494 @@ + + + DialogCurveIntersectAxis + + + + 0 + 0 + 469 + 499 + + + + Dialog + + + + + + + + + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + Angle + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + ... + + + + :/icon/24x24/putHere.png:/icon/24x24/putHere.png + + + + 24 + 24 + + + + + + + + Calculate value + + + ... + + + + :/icon/24x24/equal.png:/icon/24x24/equal.png + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + + 87 + 0 + + + + Value of angle + + + _ + + + + + + + + + + + + 16777215 + 24 + + + + + 4 + 0 + + + + true + + + QPlainTextEdit::NoWrap + + + + + + + + 16 + 16 + + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + + + + + + 16 + 16 + + + + true + + + + + + + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + + 0 + 0 + + + + Axis point + + + + + + + First point of line + + + + + + + + 0 + 0 + + + + Curve + + + + + + + First point of line + + + + + + + + 0 + 0 + + + + Point label + + + + + + + + 0 + 0 + + + + + + + + Type of line + + + + + + + Show line from first point to this point + + + + + + + + + Input data + + + + + + + + 0 + 0 + + + + Size and height + + + true + + + + + + + + 0 + 0 + + + + Standard table + + + + + + + + 0 + 0 + + + + Increments + + + + + + + true + + + + 0 + 0 + + + + Length of lines + + + + + + + true + + + + 0 + 0 + + + + Length of arcs + + + + + + + true + + + + 0 + 0 + + + + Length of curves + + + + + + + true + + + + 0 + 0 + + + + Angle of lines + + + + + + + + + + + + + Hide empty measurements + + + true + + + + + + + Variables + + + + + + + + + + + + 0 + 0 + + + + Qt::PlainText + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + DialogCurveIntersectAxis + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DialogCurveIntersectAxis + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/app/dialogs/tools/dialogheight.cpp b/src/app/dialogs/tools/dialogheight.cpp index 020c12a7b..01c17f079 100644 --- a/src/app/dialogs/tools/dialogheight.cpp +++ b/src/app/dialogs/tools/dialogheight.cpp @@ -208,8 +208,8 @@ void DialogHeight::PointNameChanged() const QSharedPointer p2Line = data->GeometricObject(p2LineId); QColor color = okColor; - if (set.size() != 3 || VAbstractTool::ClosestPoint(QLineF(p1Line->toQPointF(), p2Line->toQPointF()), - basePoint->toQPointF()) == QPointF()) + if (set.size() != 3 || VGObject::ClosestPoint(QLineF(p1Line->toQPointF(), p2Line->toQPointF()), + basePoint->toQPointF()) == QPointF()) { flagError = false; color = errorColor; diff --git a/src/app/dialogs/tools/dialogtool.cpp b/src/app/dialogs/tools/dialogtool.cpp index fc902b4c4..acec39c50 100644 --- a/src/app/dialogs/tools/dialogtool.cpp +++ b/src/app/dialogs/tools/dialogtool.cpp @@ -257,6 +257,29 @@ void DialogTool::FillComboBoxSplinesPath(QComboBox *box, ComboBoxCutSpline cut) FillList(box, list); } +//--------------------------------------------------------------------------------------------------------------------- +void DialogTool::FillComboBoxCurves(QComboBox *box) const +{ + SCASSERT(box != nullptr); + const QHash > *objs = data->DataGObjects(); + QMap list; + QHash >::const_iterator i; + for (i = objs->constBegin(); i != objs->constEnd(); ++i) + { + if (i.key() != toolId) + { + QSharedPointer obj = i.value(); + if ((obj->getType() == GOType::Arc || obj->getType() == GOType::Spline || + obj->getType() == GOType::SplinePath) && obj->getMode() == Draw::Calculation) + { + const QSharedPointer curve = data->GeometricObject(i.key()); + list[curve->name()] = i.key(); + } + } + } + FillList(box, list); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief FillComboBoxTypeLine fill comboBox list of type lines @@ -544,6 +567,15 @@ void DialogTool::setCurrentSplinePathId(QComboBox *box, quint32 &splinePathId, c ChangeCurrentData(box, value); } +//--------------------------------------------------------------------------------------------------------------------- +void DialogTool::setCurrentCurveId(QComboBox *box, quint32 &curveId, const quint32 &value) const +{ + SCASSERT(box != nullptr); + FillComboBoxCurves(box); + curveId = value; + ChangeCurrentData(box, value); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief getCurrentPointId return current point id stored in combobox diff --git a/src/app/dialogs/tools/dialogtool.h b/src/app/dialogs/tools/dialogtool.h index fc94d2a03..c5a93281a 100644 --- a/src/app/dialogs/tools/dialogtool.h +++ b/src/app/dialogs/tools/dialogtool.h @@ -213,6 +213,7 @@ protected: void FillComboBoxSplines(QComboBox *box, ComboBoxCutSpline cut = ComboBoxCutSpline::NoCutSpline)const; void FillComboBoxSplinesPath(QComboBox *box, ComboBoxCutSpline cut = ComboBoxCutSpline::NoCutSpline)const; + void FillComboBoxCurves(QComboBox *box)const; void FillComboBoxTypeLine(QComboBox *box) const; virtual void CheckState(); QString GetTypeLine(const QComboBox *box)const; @@ -233,6 +234,7 @@ protected: ComboBoxCutArc cut = ComboBoxCutArc::NoCutArc) const; void setCurrentSplinePathId(QComboBox *box, quint32 &splinePathId, const quint32 &value, ComboBoxCutSpline cut = ComboBoxCutSpline::NoCutSpline) const; + void setCurrentCurveId(QComboBox *box, quint32 &curveId, const quint32 &value) const; quint32 getCurrentObjectId(QComboBox *box) const; bool SetObject(const quint32 &id, QComboBox *box, const QString &toolTip); void DeployFormula(QPlainTextEdit *formula, QPushButton *buttonGrowLength, int formulaBaseHeight); diff --git a/src/app/geometry/vabstractcurve.cpp b/src/app/geometry/vabstractcurve.cpp index 006f143bb..dc9297ed2 100644 --- a/src/app/geometry/vabstractcurve.cpp +++ b/src/app/geometry/vabstractcurve.cpp @@ -77,6 +77,29 @@ QPainterPath VAbstractCurve::GetPath(PathDirection direction) const return path; } +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief IntersectLine return list of points for real intersection with line + * @param line line that intersect with curve + * @return list of intersection points + */ +QVector VAbstractCurve::IntersectLine(const QLineF &line) const +{ + QVector points = this->GetPoints(); + QVector intersections; + for ( qint32 i = 0; i < points.count()-1; ++i ) + { + QPointF crosPoint; + QLineF::IntersectType type = QLineF::NoIntersection; + type = line.intersect(QLineF ( points.at(i), points.at(i+1)), &crosPoint); + if ( type == QLineF::BoundedIntersection ) + { + intersections.append(crosPoint); + } + } + return intersections; +} + //--------------------------------------------------------------------------------------------------------------------- QPainterPath VAbstractCurve::ShowDirection(const QVector &points) const { diff --git a/src/app/geometry/vabstractcurve.h b/src/app/geometry/vabstractcurve.h index f157eb8af..82065f79d 100644 --- a/src/app/geometry/vabstractcurve.h +++ b/src/app/geometry/vabstractcurve.h @@ -35,6 +35,7 @@ enum class PathDirection : char { Hide, Show }; class QPainterPath; +class QLineF; class VAbstractCurve :public VGObject { @@ -45,6 +46,7 @@ public: virtual QVector GetPoints() const =0; virtual QPainterPath GetPath(PathDirection direction = PathDirection::Hide) const; virtual qreal GetLength() const =0; + virtual QVector IntersectLine(const QLineF &line) const; protected: QPainterPath ShowDirection(const QVector &points) const; }; diff --git a/src/app/geometry/vgobject.cpp b/src/app/geometry/vgobject.cpp index d5e069eec..360b7e318 100644 --- a/src/app/geometry/vgobject.cpp +++ b/src/app/geometry/vgobject.cpp @@ -29,6 +29,11 @@ #include "vgobject.h" #include "vgobject_p.h" +#include +#include +#include +#include + //--------------------------------------------------------------------------------------------------------------------- /** * @brief VGObject default constructor. @@ -172,3 +177,165 @@ void VGObject::setId(const quint32 &id) { d->_id = id; } + +//--------------------------------------------------------------------------------------------------------------------- +QLineF VGObject::BuildLine(const QPointF &p1, const qreal &length, const qreal &angle) +{ + QLineF line = QLineF(); + line.setP1(p1); + line.setLength(length); + line.setAngle(angle); + return line; +} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VGObject::BuildRay(const QPointF &firstPoint, const qreal &angle, const QRectF &scRect) +{ + qreal diagonal = qSqrt(pow(scRect.height(), 2) + pow(scRect.width(), 2)); + QLineF line = BuildLine(firstPoint, diagonal, angle); + + return LineIntersectRect(scRect, line); +} + +//--------------------------------------------------------------------------------------------------------------------- +QLineF VGObject::BuildAxis(const QPointF &p, const qreal &angle, const QRectF &scRect) +{ + QPointF endP1 = BuildRay(p, angle+180, scRect); + QPointF endP2 = BuildRay(p, angle, scRect); + return QLineF(endP1, endP2); +} + +//--------------------------------------------------------------------------------------------------------------------- +QLineF VGObject::BuildAxis(const QPointF &p1, const QPointF &p2, const QRectF &scRect) +{ + QLineF line(p1, p2); + return BuildAxis(p1, line.angle(), scRect); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief LineIntersectRect find point intersection line and rect. + * @param rec rect. + * @param line line. + * @return point intersection. + */ +QPointF VGObject::LineIntersectRect(QRectF rec, QLineF line) +{ + qreal x1, y1, x2, y2; + rec.getCoords(&x1, &y1, &x2, &y2); + QPointF point; + QLineF::IntersectType type = line.intersect(QLineF(QPointF(x1, y1), QPointF(x1, y2)), &point); + if ( type == QLineF::BoundedIntersection ) + { + return point; + } + type = line.intersect(QLineF(QPointF(x1, y1), QPointF(x2, y1)), &point); + if ( type == QLineF::BoundedIntersection ) + { + return point; + } + type = line.intersect(QLineF(QPointF(x1, y2), QPointF(x2, y2)), &point); + if ( type == QLineF::BoundedIntersection ) + { + return point; + } + type = line.intersect(QLineF(QPointF(x2, y1), QPointF(x2, y2)), &point); + if ( type == QLineF::BoundedIntersection ) + { + return point; + } + Q_ASSERT_X(type != QLineF::BoundedIntersection, Q_FUNC_INFO, "There is no point of intersection."); + return point; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief LineIntersectCircle find point intersection line and circle. + * @param center arc center. + * @param radius arc radius. + * @param line line + * @param p1 first intersection point. + * @param p2 second intersection point. + * @return 0 - intersection doesn't exist, 1 - one intersection point, 2 - two intersection points. + */ +qint32 VGObject::LineIntersectCircle(const QPointF ¢er, qreal radius, const QLineF &line, QPointF &p1, QPointF &p2) +{ + //coefficient for equation of segment + qreal a = 0, b = 0, c = 0; + LineCoefficients(line, &a, &b, &c); + // projection center of circle on to line + QPointF p = ClosestPoint (line, center); + // how many solutions? + qint32 flag = 0; + qreal d = QLineF (center, p).length(); + if (qFuzzyCompare(d, radius)) + { + flag = 1; + } + else + { + if (radius > d) + { + flag = 2; + } + else + { + return 0; + } + } + // find distance from projection to points of intersection + qreal k = qSqrt (qAbs(radius * radius - d * d)); + qreal t = QLineF (QPointF (0, 0), QPointF (b, - a)).length(); + // add to projection a vectors aimed to points of intersection + p1 = addVector (p, QPointF (0, 0), QPointF (- b, a), k / t); + p2 = addVector (p, QPointF (0, 0), QPointF (b, - a), k / t); + return flag; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief ClosestPoint find point projection of point onto line. + * @param line line. + * @return point on line or extended line if origin size too small. + */ +QPointF VGObject::ClosestPoint(const QLineF &line, const QPointF &point) +{ + qreal a = 0, b = 0, c = 0; + LineCoefficients(line, &a, &b, &c); + qreal x = point.x() + a; + qreal y = b + point.y(); + QLineF lin (point, QPointF(x, y)); + QPointF p; + QLineF::IntersectType intersect = line.intersect(lin, &p); + if (intersect == QLineF::UnboundedIntersection || intersect == QLineF::BoundedIntersection) + { + return p; + } + else + { + return QPointF(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VGObject::addVector(const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k) +{ + return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief LineCoefficients coefficient for equation of segment. Segment equestion ax+by+c=0. + * @param line line + * @param a a value + * @param b b value + * @param c c value + */ +void VGObject::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c) +{ + //coefficient for equation of segment + QPointF p1 = line.p1(); + *a = line.p2().y() - p1.y(); + *b = p1.x() - line.p2().x(); + *c = - *a * p1.x() - *b * p1.y(); +} diff --git a/src/app/geometry/vgobject.h b/src/app/geometry/vgobject.h index 88c5df56d..45ff5e227 100644 --- a/src/app/geometry/vgobject.h +++ b/src/app/geometry/vgobject.h @@ -35,6 +35,9 @@ #include class VGObjectData; +class QLineF; +class QPointF; +class QRectF; /** * @brief The VGObject class keep information graphical objects. @@ -62,6 +65,18 @@ public: quint32 id() const; virtual void setId(const quint32 &id); + + static QLineF BuildLine(const QPointF &p1, const qreal& length, const qreal &angle); + static QPointF BuildRay(const QPointF &firstPoint, const qreal &angle, const QRectF &scRect); + static QLineF BuildAxis(const QPointF &p, const qreal &angle, const QRectF &scRect); + static QLineF BuildAxis(const QPointF &p1, const QPointF &p2, const QRectF &scRect); + + static QPointF LineIntersectRect(QRectF rec, QLineF line); + static qint32 LineIntersectCircle(const QPointF ¢er, qreal radius, const QLineF &line, QPointF &p1, + QPointF &p2); + static QPointF ClosestPoint(const QLineF &line, const QPointF &point); + static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k); + static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c); private: QSharedDataPointer d; }; diff --git a/src/app/geometry/vspline.cpp b/src/app/geometry/vspline.cpp index 150603ec5..e6d48a9d9 100644 --- a/src/app/geometry/vspline.cpp +++ b/src/app/geometry/vspline.cpp @@ -96,43 +96,6 @@ qreal VSpline::GetLength () const return LengthBezier ( GetP1().toQPointF(), d->p2, d->p3, GetP4().toQPointF()); } -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief CrossingSplLine check intersection spline with line. - * @param line line. - * @param intersectionPoint intersection point. - * @return result intersection. - */ -// cppcheck-suppress unusedFunction -QLineF::IntersectType VSpline::CrossingSplLine ( const QLineF &line, QPointF *intersectionPoint ) const -{ - QVector px; - QVector py; - px.append ( GetP1 ().x () ); - py.append ( GetP1 ().y () ); - QVector& wpx = px; - QVector& wpy = py; - PointBezier_r ( GetP1 ().x (), GetP1 ().y (), GetP2 ().x (), GetP2 ().y (), - GetP3 ().x (), GetP3 ().y (), GetP4 ().x (), GetP4 ().y (), - 0, wpx, wpy); - px.append ( GetP4 ().x () ); - py.append ( GetP4 ().y () ); - qint32 i = 0; - QPointF crosPoint; - QLineF::IntersectType type = QLineF::NoIntersection; - for ( i = 0; i < px.count()-1; ++i ) - { - type = line.intersect(QLineF ( QPointF ( px.at(i), py.at(i) ), - QPointF ( px.at(i+1), py.at(i+1) )), &crosPoint); - if ( type == QLineF::BoundedIntersection ) - { - *intersectionPoint = crosPoint; - return type; - } - } - throw "Can't found point of intersection spline and line."; -} - //--------------------------------------------------------------------------------------------------------------------- qreal VSpline::LengthT(qreal t) const { diff --git a/src/app/geometry/vspline.h b/src/app/geometry/vspline.h index 9b08e2e66..d363f8b0f 100644 --- a/src/app/geometry/vspline.h +++ b/src/app/geometry/vspline.h @@ -64,11 +64,9 @@ public: qreal GetKasm2() const; qreal GetKcurve() const; void SetKcurve(qreal factor); - // cppcheck-suppress unusedFunction - QLineF::IntersectType CrossingSplLine(const QLineF &line, QPointF *intersectionPoint ) const; - qreal LengthT(qreal t) const; - QPointF CutSpline ( qreal length, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, QPointF &spl2p3) const; - QPointF CutSpline ( qreal length, VSpline &spl1, VSpline &spl2) const; + qreal LengthT(qreal t) const; + QPointF CutSpline ( qreal length, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, QPointF &spl2p3) const; + QPointF CutSpline ( qreal length, VSpline &spl1, VSpline &spl2) const; QVector GetPoints () const; // cppcheck-suppress unusedFunction static QVector SplinePoints(const QPointF &p1, const QPointF &p4, qreal angle1, qreal angle2, qreal kAsm1, diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index dd0fca429..fcefbb624 100644 --- a/src/app/mainwindow.cpp +++ b/src/app/mainwindow.cpp @@ -675,6 +675,16 @@ void MainWindow::ToolLineIntersectAxis(bool checked) &MainWindow::ApplyDialog); } +//--------------------------------------------------------------------------------------------------------------------- +void MainWindow::ToolCurveIntersectAxis(bool checked) +{ + SetToolButtonWithApply(checked, Tool::CurveIntersectAxis, + ":/cursor/curve_intersect_axis_cursor.png", + tr("Select curve"), + &MainWindow::ClosedDialogWithApply, + &MainWindow::ApplyDialog); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief About show widows about. @@ -941,6 +951,7 @@ void MainWindow::InitToolButtons() connect(ui->toolButtonUnionDetails, &QToolButton::clicked, this, &MainWindow::ToolUnionDetails); connect(ui->toolButtonArcCutPoint, &QToolButton::clicked, this, &MainWindow::ToolCutArc); connect(ui->toolButtonLineIntersectAxis, &QToolButton::clicked, this, &MainWindow::ToolLineIntersectAxis); + connect(ui->toolButtonCurveIntersectAxis, &QToolButton::clicked, this, &MainWindow::ToolCurveIntersectAxis); } //--------------------------------------------------------------------------------------------------------------------- @@ -1085,6 +1096,11 @@ void MainWindow::CancelTool() currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; + case Tool::CurveIntersectAxis: + ui->toolButtonCurveIntersectAxis->setChecked(false); + currentScene->setFocus(Qt::OtherFocusReason); + currentScene->clearSelection(); + break; case Tool::NodePoint: case Tool::NodeArc: case Tool::NodeSpline: @@ -1789,6 +1805,7 @@ void MainWindow::SetEnableTool(bool enable) ui->toolButtonSplinePathCutPoint->setEnabled(drawTools); ui->toolButtonArcCutPoint->setEnabled(drawTools); ui->toolButtonLineIntersectAxis->setEnabled(drawTools); + ui->toolButtonCurveIntersectAxis->setEnabled(drawTools); //Modeling Tools ui->toolButtonUnionDetails->setEnabled(modelingTools); diff --git a/src/app/mainwindow.h b/src/app/mainwindow.h index ba460ef5a..57279c026 100644 --- a/src/app/mainwindow.h +++ b/src/app/mainwindow.h @@ -107,6 +107,7 @@ public slots: void ToolUnionDetails(bool checked); void ToolCutArc(bool checked); void ToolLineIntersectAxis(bool checked); + void ToolCurveIntersectAxis(bool checked); void ClosedDialogDetail(int result); void ClosedDialogUnionDetails(int result); diff --git a/src/app/mainwindow.ui b/src/app/mainwindow.ui index dc3ec5687..e6e32d2fe 100644 --- a/src/app/mainwindow.ui +++ b/src/app/mainwindow.ui @@ -40,7 +40,7 @@ - 0 + 3 @@ -411,7 +411,7 @@ 0 0 105 - 110 + 156 @@ -531,6 +531,29 @@ + + + + false + + + ... + + + + :/icon/32x32/curve_intersect_axis.png:/icon/32x32/curve_intersect_axis.png + + + + 32 + 32 + + + + true + + + @@ -539,7 +562,7 @@ 0 0 105 - 58 + 104 @@ -607,6 +630,29 @@ + + + + false + + + ... + + + + :/icon/32x32/arc_intersect_axis.png:/icon/32x32/arc_intersect_axis.png + + + + 32 + 32 + + + + true + + + diff --git a/src/app/options.h b/src/app/options.h index 147a065a9..089c81384 100644 --- a/src/app/options.h +++ b/src/app/options.h @@ -81,14 +81,14 @@ enum class Tool : unsigned char Height, Triangle, LineIntersectAxis, + CurveIntersectAxis, PointOfIntersection, - - UnionDetails + UnionDetails // 30 }; enum class Vis : unsigned char { - ControlPointSpline = 29, // increase this value if need more positions in Tool enum + ControlPointSpline = 31, // increase this value if need more positions in Tool enum GraphicsSimpleTextItem, SimpleSplinePath, Line, @@ -110,7 +110,8 @@ enum class Vis : unsigned char ToolCutSpline, ToolSplinePath, ToolCutSplinePath, - ToolLineIntersectAxis + ToolLineIntersectAxis, + ToolCurveIntersectAxis }; enum class Source : char { FromGui, FromFile, FromTool }; diff --git a/src/app/share/resources/cursor.qrc b/src/app/share/resources/cursor.qrc index 7e2665aeb..1aec9decd 100644 --- a/src/app/share/resources/cursor.qrc +++ b/src/app/share/resources/cursor.qrc @@ -22,5 +22,7 @@ cursor/cursor-arrow-closehand.png cursor/cursor-arrow-openhand.png cursor/line_intersect_axis_cursor.png + cursor/arc_intersect_axis_cursor.png + cursor/curve_intersect_axis_cursor.png diff --git a/src/app/share/resources/cursor/arc_intersect_axis_cursor.png b/src/app/share/resources/cursor/arc_intersect_axis_cursor.png new file mode 100644 index 000000000..f58f219db Binary files /dev/null and b/src/app/share/resources/cursor/arc_intersect_axis_cursor.png differ diff --git a/src/app/share/resources/cursor/curve_intersect_axis_cursor.png b/src/app/share/resources/cursor/curve_intersect_axis_cursor.png new file mode 100644 index 000000000..4f4470024 Binary files /dev/null and b/src/app/share/resources/cursor/curve_intersect_axis_cursor.png differ diff --git a/src/app/share/resources/icon.qrc b/src/app/share/resources/icon.qrc index 4c411ae0a..4e2425a66 100644 --- a/src/app/share/resources/icon.qrc +++ b/src/app/share/resources/icon.qrc @@ -59,5 +59,7 @@ icon/16x16/info.png icon/16x16/measurement.png icon/32x32/line_intersect_axis.png + icon/32x32/arc_intersect_axis.png + icon/32x32/curve_intersect_axis.png diff --git a/src/app/share/resources/schema/pattern.xsd b/src/app/share/resources/schema/pattern.xsd index 7f0a5f96a..9c8d49a7e 100644 --- a/src/app/share/resources/schema/pattern.xsd +++ b/src/app/share/resources/schema/pattern.xsd @@ -120,6 +120,7 @@ + diff --git a/src/app/tools/drawTools/drawtools.h b/src/app/tools/drawTools/drawtools.h index 2a3329ff5..50930c440 100644 --- a/src/app/tools/drawTools/drawtools.h +++ b/src/app/tools/drawTools/drawtools.h @@ -48,5 +48,6 @@ #include "vtoolcutsplinepath.h" #include "vtoolcutarc.h" #include "vtoollineintersectaxis.h" +#include "vtoolcurveintersectaxis.h" #endif // DRAWTOOLS_H diff --git a/src/app/tools/drawTools/vtoolcurveintersectaxis.cpp b/src/app/tools/drawTools/vtoolcurveintersectaxis.cpp new file mode 100644 index 000000000..92c939392 --- /dev/null +++ b/src/app/tools/drawTools/vtoolcurveintersectaxis.cpp @@ -0,0 +1,315 @@ +/************************************************************************ + ** + ** @file vtoolcurveintersectaxis.cpp + ** @author Roman Telezhynskyi + ** @date 21 10, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vtoolcurveintersectaxis.h" +#include "../../widgets/vmaingraphicsscene.h" +#include "../../container/calculator.h" +#include "../../dialogs/tools/dialogcurveintersectaxis.h" +#include "../../dialogs/tools/dialogeditwrongformula.h" +#include "../../geometry/vpointf.h" +#include "./../visualization/vistoolcurveintersectaxis.h" + +const QString VToolCurveIntersectAxis::ToolType = QStringLiteral("curveIntersectAxis"); + +//--------------------------------------------------------------------------------------------------------------------- +VToolCurveIntersectAxis::VToolCurveIntersectAxis(VPattern *doc, VContainer *data, const quint32 &id, + const QString &typeLine, const QString &formulaAngle, + const quint32 &basePointId, const quint32 &curveId, + const Source &typeCreation, QGraphicsItem *parent) + :VToolLinePoint(doc, data, id, typeLine, QString(), basePointId, 0, parent), formulaAngle(formulaAngle), + curveId(curveId) +{ + if (typeCreation == Source::FromGui) + { + AddToFile(); + } + else + { + RefreshDataInFile(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolCurveIntersectAxis::~VToolCurveIntersectAxis() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::setDialog() +{ + SCASSERT(dialog != nullptr); + dialog->setModal(true); + DialogCurveIntersectAxis *dialogTool = qobject_cast(dialog); + SCASSERT(dialogTool != nullptr); + const QSharedPointer p = VAbstractTool::data.GeometricObject(id); + dialogTool->setTypeLine(typeLine); + dialogTool->setAngle(formulaAngle); + dialogTool->setBasePointId(basePointId); + dialogTool->setCurveId(curveId); + dialogTool->setPointName(p->name()); +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolCurveIntersectAxis *VToolCurveIntersectAxis::Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, + VContainer *data) +{ + SCASSERT(dialog != nullptr); + DialogCurveIntersectAxis *dialogTool = qobject_cast(dialog); + SCASSERT(dialogTool); + const QString pointName = dialogTool->getPointName(); + const QString typeLine = dialogTool->getTypeLine(); + QString formulaAngle = dialogTool->getAngle(); + const quint32 basePointId = dialogTool->getBasePointId(); + const quint32 curveId = dialogTool->getCurveId(); + + VToolCurveIntersectAxis *point = nullptr; + point=Create(0, pointName, typeLine, formulaAngle, basePointId, curveId, 5, 10, scene, doc, data, + Document::FullParse, Source::FromGui); + if (point != nullptr) + { + point->dialog=dialogTool; + } + return point; +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolCurveIntersectAxis *VToolCurveIntersectAxis::Create(const quint32 _id, const QString &pointName, + const QString &typeLine, QString &formulaAngle, + const quint32 &basePointId, const quint32 &curveId, + const qreal &mx, const qreal &my, + VMainGraphicsScene *scene, VPattern *doc, VContainer *data, + const Document &parse, const Source &typeCreation) +{ + const QSharedPointer basePoint = data->GeometricObject(basePointId); + qreal angle = CheckFormula(_id, formulaAngle, data); + const QSharedPointer curve = data->GeometricObject(curveId); + + QPointF fPoint = FindPoint(basePoint->toQPointF(), angle, curve); + quint32 id = _id; + if (typeCreation == Source::FromGui) + { + id = data->AddGObject(new VPointF(fPoint, pointName, mx, my)); + data->AddLine(basePointId, id); + } + else + { + data->UpdateGObject(id, new VPointF(fPoint, pointName, mx, my)); + data->AddLine(basePointId, id); + if (parse != Document::FullParse) + { + doc->UpdateToolData(id, data); + } + } + VDrawTool::AddRecord(id, Tool::CurveIntersectAxis, doc); + if (parse == Document::FullParse) + { + VToolCurveIntersectAxis *point = new VToolCurveIntersectAxis(doc, data, id, typeLine, formulaAngle, basePointId, + curveId, typeCreation); + scene->addItem(point); + connect(point, &VToolPoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); + connect(scene, &VMainGraphicsScene::NewFactor, point, &VToolPoint::SetFactor); + connect(scene, &VMainGraphicsScene::DisableItem, point, &VToolPoint::Disable); + doc->AddTool(id, point); + doc->IncrementReferens(basePointId); + doc->IncrementReferens(curveId); + return point; + } + return nullptr; +} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VToolCurveIntersectAxis::FindPoint(const QPointF &point, qreal angle, + const QSharedPointer &curve) +{ + QLineF axis = VGObject::BuildAxis(point, angle, qApp->getCurrentScene()->sceneRect()); + QVector points = curve->IntersectLine(axis); + + if (points.size() > 0) + { + if (points.size() == 1) + { + return points.at(0); + } + + QMap lengths; + + for ( qint32 i = 0; i < points.size(); ++i ) + { + lengths.insert(QLineF(points.at(i), point).length(), i); + } + + QMap::const_iterator i = lengths.constBegin(); + if (i != lengths.constEnd()) + { + return points.at(i.value()); + } + } + + return QPointF(); +} + +//--------------------------------------------------------------------------------------------------------------------- +VFormula VToolCurveIntersectAxis::getFormulaAngle() const +{ + VFormula fAngle(formulaAngle, getData()); + fAngle.setCheckZero(false); + fAngle.setToolId(id); + fAngle.setPostfix(QStringLiteral("°")); + return fAngle; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::setFormulaAngle(const VFormula &value) +{ + if (value.error() == false) + { + formulaAngle = value.getFormula(FormulaType::FromUser); + + QSharedPointer obj = VAbstractTool::data.GetGObject(id); + SaveOption(obj); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 VToolCurveIntersectAxis::getCurveId() const +{ + return curveId; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::setCurveId(const quint32 &value) +{ + if (value != NULL_ID) + { + curveId = value; + + QSharedPointer obj = VAbstractTool::data.GetGObject(id); + SaveOption(obj); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::ShowVisualization(bool show) +{ + if (show) + { + if (vis == nullptr) + { + VisToolCurveIntersectAxis * visual = new VisToolCurveIntersectAxis(getData()); + VMainGraphicsScene *scene = qApp->getCurrentScene(); + connect(scene, &VMainGraphicsScene::NewFactor, visual, &Visualization::SetFactor); + scene->addItem(visual); + + visual->setPoint1Id(curveId); + visual->setAxisPointId(basePointId); + visual->setAngle(qApp->FormulaToUser(formulaAngle)); + visual->setLineStyle(VAbstractTool::LineStyle(typeLine)); + visual->RefreshGeometry(); + vis = visual; + } + else + { + VisToolCurveIntersectAxis *visual = qobject_cast(vis); + if (visual != nullptr) + { + visual->show(); + } + } + } + else + { + delete vis; + vis = nullptr; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::FullUpdateFromFile() +{ + QDomElement domElement = doc->elementById(QString().setNum(id)); + if (domElement.isElement()) + { + typeLine = domElement.attribute(AttrTypeLine, ""); + basePointId = domElement.attribute(AttrBasePoint, "").toUInt(); + curveId = domElement.attribute(AttrCurve, "").toUInt(); + formulaAngle = domElement.attribute(AttrAngle, ""); + } + RefreshGeometry(); + + if (vis != nullptr) + { + VisToolCurveIntersectAxis *visual = qobject_cast(vis); + visual->setPoint1Id(curveId); + visual->setAxisPointId(basePointId); + visual->setAngle(qApp->FormulaToUser(formulaAngle)); + visual->setLineStyle(VAbstractTool::LineStyle(typeLine)); + visual->RefreshGeometry(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::ShowContextMenu(QGraphicsSceneContextMenuEvent *event) +{ + ContextMenu(this, event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + ContextMenu(this, event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::SaveDialog(QDomElement &domElement) +{ + SCASSERT(dialog != nullptr); + DialogCurveIntersectAxis *dialogTool = qobject_cast(dialog); + SCASSERT(dialogTool != nullptr); + doc->SetAttribute(domElement, AttrName, dialogTool->getPointName()); + doc->SetAttribute(domElement, AttrTypeLine, dialogTool->getTypeLine()); + doc->SetAttribute(domElement, AttrAngle, dialogTool->getAngle()); + doc->SetAttribute(domElement, AttrBasePoint, QString().setNum(dialogTool->getBasePointId())); + doc->SetAttribute(domElement, AttrCurve, QString().setNum(dialogTool->getCurveId())); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolCurveIntersectAxis::SaveOptions(QDomElement &tag, QSharedPointer &obj) +{ + QSharedPointer point = qSharedPointerDynamicCast(obj); + SCASSERT(point.isNull() == false); + + doc->SetAttribute(tag, VDomDocument::AttrId, id); + doc->SetAttribute(tag, AttrType, ToolType); + doc->SetAttribute(tag, AttrName, point->name()); + doc->SetAttribute(tag, AttrMx, qApp->fromPixel(point->mx())); + doc->SetAttribute(tag, AttrMy, qApp->fromPixel(point->my())); + + doc->SetAttribute(tag, AttrTypeLine, typeLine); + doc->SetAttribute(tag, AttrAngle, formulaAngle); + doc->SetAttribute(tag, AttrBasePoint, basePointId); + doc->SetAttribute(tag, AttrCurve, curveId); +} diff --git a/src/app/tools/drawTools/vtoolcurveintersectaxis.h b/src/app/tools/drawTools/vtoolcurveintersectaxis.h new file mode 100644 index 000000000..fedd78c8b --- /dev/null +++ b/src/app/tools/drawTools/vtoolcurveintersectaxis.h @@ -0,0 +1,77 @@ +/************************************************************************ + ** + ** @file vtoolcurveintersectaxis.h + ** @author Roman Telezhynskyi + ** @date 21 10, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VTOOLCURVEINTERSECTAXIS_H +#define VTOOLCURVEINTERSECTAXIS_H + +#include "vtoollinepoint.h" + +class VToolCurveIntersectAxis : public VToolLinePoint +{ + Q_OBJECT +public: + VToolCurveIntersectAxis(VPattern *doc, VContainer *data, const quint32 &id, const QString &typeLine, + const QString &formulaAngle, const quint32 &basePointId, const quint32 &curveId, + const Source &typeCreation, QGraphicsItem * parent = nullptr); + virtual ~VToolCurveIntersectAxis(); + virtual void setDialog(); + + static VToolCurveIntersectAxis *Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, + VContainer *data); + static VToolCurveIntersectAxis *Create(const quint32 _id, const QString &pointName, const QString &typeLine, + QString &formulaAngle, const quint32 &basePointId, const quint32 &curveId, + const qreal &mx, const qreal &my, VMainGraphicsScene *scene, VPattern *doc, + VContainer *data, const Document &parse, const Source &typeCreation); + + static QPointF FindPoint(const QPointF &point, qreal angle, const QSharedPointer &curve); + + static const QString ToolType; + virtual int type() const {return Type;} + enum { Type = UserType + static_cast(Tool::CurveIntersectAxis)}; + + VFormula getFormulaAngle() const; + void setFormulaAngle(const VFormula &value); + + quint32 getCurveId() const; + void setCurveId(const quint32 &value); + + virtual void ShowVisualization(bool show); +public slots: + virtual void FullUpdateFromFile(); + virtual void ShowContextMenu(QGraphicsSceneContextMenuEvent *event); +protected: + virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ); + virtual void SaveDialog(QDomElement &domElement); + virtual void SaveOptions(QDomElement &tag, QSharedPointer &obj); +private: + Q_DISABLE_COPY(VToolCurveIntersectAxis) + QString formulaAngle; + quint32 curveId; +}; + +#endif // VTOOLCURVEINTERSECTAXIS_H diff --git a/src/app/tools/drawTools/vtoolheight.cpp b/src/app/tools/drawTools/vtoolheight.cpp index 56c1ab598..25ea2a864 100644 --- a/src/app/tools/drawTools/vtoolheight.cpp +++ b/src/app/tools/drawTools/vtoolheight.cpp @@ -184,7 +184,7 @@ VToolHeight* VToolHeight::Create(const quint32 _id, const QString &pointName, co */ QPointF VToolHeight::FindPoint(const QLineF &line, const QPointF &point) { - return VAbstractTool::ClosestPoint(line, point); + return VGObject::ClosestPoint(line, point); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/tools/drawTools/vtoolpoint.cpp b/src/app/tools/drawTools/vtoolpoint.cpp index c22bea1dc..eb92abb4c 100644 --- a/src/app/tools/drawTools/vtoolpoint.cpp +++ b/src/app/tools/drawTools/vtoolpoint.cpp @@ -256,8 +256,9 @@ void VToolPoint::RefreshLine() { QRectF nameRec = namePoint->sceneBoundingRect(); QPointF p1, p2; - LineIntersectCircle(QPointF(), radius/factor, QLineF(QPointF(), nameRec.center() - scenePos()), p1, p2); - QPointF pRec = LineIntersectRect(nameRec, QLineF(scenePos(), nameRec.center())); + VGObject::LineIntersectCircle(QPointF(), radius/factor, QLineF(QPointF(), nameRec.center() - scenePos()), p1, + p2); + QPointF pRec = VGObject::LineIntersectRect(nameRec, QLineF(scenePos(), nameRec.center())); lineName->setLine(QLineF(p1, pRec - scenePos())); if (currentColor == Qt::gray) { diff --git a/src/app/tools/drawTools/vtoolpointofcontact.cpp b/src/app/tools/drawTools/vtoolpointofcontact.cpp index 8745497f1..96e4eabe7 100644 --- a/src/app/tools/drawTools/vtoolpointofcontact.cpp +++ b/src/app/tools/drawTools/vtoolpointofcontact.cpp @@ -96,7 +96,7 @@ QPointF VToolPointOfContact::FindPoint(const qreal &radius, const QPointF ¢e const QPointF &secondPoint) { QPointF p1, p2; - qint32 res = LineIntersectCircle(center, radius, QLineF(firstPoint, secondPoint), p1, p2); + qint32 res = VGObject::LineIntersectCircle(center, radius, QLineF(firstPoint, secondPoint), p1, p2); switch (res) { case 0: diff --git a/src/app/tools/nodeDetails/vnodepoint.cpp b/src/app/tools/nodeDetails/vnodepoint.cpp index 2fe4673e8..baaea5ed0 100644 --- a/src/app/tools/nodeDetails/vnodepoint.cpp +++ b/src/app/tools/nodeDetails/vnodepoint.cpp @@ -290,8 +290,8 @@ void VNodePoint::RefreshLine() { QRectF nameRec = namePoint->sceneBoundingRect(); QPointF p1, p2; - LineIntersectCircle(QPointF(), radius, QLineF(QPointF(), nameRec.center()- scenePos()), p1, p2); - QPointF pRec = LineIntersectRect(nameRec, QLineF(scenePos(), nameRec.center())); + VGObject::LineIntersectCircle(QPointF(), radius, QLineF(QPointF(), nameRec.center()- scenePos()), p1, p2); + QPointF pRec = VGObject::LineIntersectRect(nameRec, QLineF(scenePos(), nameRec.center())); lineName->setLine(QLineF(p1, pRec - scenePos())); if (QLineF(p1, pRec - scenePos()).length() <= qApp->toPixel(4)) { diff --git a/src/app/tools/tools.pri b/src/app/tools/tools.pri index 91b9f8e7e..aeefc0f4b 100644 --- a/src/app/tools/tools.pri +++ b/src/app/tools/tools.pri @@ -34,7 +34,8 @@ HEADERS += \ tools/drawTools/vtoolcutarc.h \ tools/drawTools/vabstractspline.h \ tools/drawTools/vtoolcut.h \ - tools/drawTools/vtoollineintersectaxis.h + tools/drawTools/vtoollineintersectaxis.h \ + tools/drawTools/vtoolcurveintersectaxis.h SOURCES += \ tools/vtooldetail.cpp \ @@ -69,4 +70,5 @@ SOURCES += \ tools/drawTools/vtoolcutarc.cpp \ tools/drawTools/vabstractspline.cpp \ tools/drawTools/vtoolcut.cpp \ - tools/drawTools/vtoollineintersectaxis.cpp + tools/drawTools/vtoollineintersectaxis.cpp \ + tools/drawTools/vtoolcurveintersectaxis.cpp diff --git a/src/app/tools/vabstracttool.cpp b/src/app/tools/vabstracttool.cpp index c30d047ac..df4efa59d 100644 --- a/src/app/tools/vabstracttool.cpp +++ b/src/app/tools/vabstracttool.cpp @@ -69,6 +69,7 @@ const QString VAbstractTool::AttrPathPoint = QStringLiteral("pathPoint"); const QString VAbstractTool::AttrPSpline = QStringLiteral("pSpline"); const QString VAbstractTool::AttrAxisP1 = QStringLiteral("axisP1"); const QString VAbstractTool::AttrAxisP2 = QStringLiteral("axisP2"); +const QString VAbstractTool::AttrCurve = QStringLiteral("curve"); const QString VAbstractTool::TypeLineNone = QStringLiteral("none"); const QString VAbstractTool::TypeLineLine = QStringLiteral("hair"); @@ -133,118 +134,6 @@ void VAbstractTool::NewSceneRect(QGraphicsScene *sc, QGraphicsView *view) sc->setSceneRect(rec1); } -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief LineIntersectRect find point intersection line and rect. - * @param rec rect. - * @param line line. - * @return point intersection. - */ -QPointF VAbstractTool::LineIntersectRect(QRectF rec, QLineF line) -{ - qreal x1, y1, x2, y2; - rec.getCoords(&x1, &y1, &x2, &y2); - QPointF point; - QLineF::IntersectType type = line.intersect(QLineF(QPointF(x1, y1), QPointF(x1, y2)), &point); - if ( type == QLineF::BoundedIntersection ) - { - return point; - } - type = line.intersect(QLineF(QPointF(x1, y1), QPointF(x2, y1)), &point); - if ( type == QLineF::BoundedIntersection ) - { - return point; - } - type = line.intersect(QLineF(QPointF(x1, y2), QPointF(x2, y2)), &point); - if ( type == QLineF::BoundedIntersection ) - { - return point; - } - type = line.intersect(QLineF(QPointF(x2, y1), QPointF(x2, y2)), &point); - if ( type == QLineF::BoundedIntersection ) - { - return point; - } - Q_ASSERT_X(type != QLineF::BoundedIntersection, Q_FUNC_INFO, "There is no point of intersection."); - return point; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief LineIntersectCircle find point intersection line and circle. - * @param center arc center. - * @param radius arc radius. - * @param line line - * @param p1 first intersection point. - * @param p2 second intersection point. - * @return 0 - intersection doesn't exist, 1 - one intersection point, 2 - two intersection points. - */ -qint32 VAbstractTool::LineIntersectCircle(const QPointF ¢er, qreal radius, const QLineF &line, QPointF &p1, - QPointF &p2) -{ - //coefficient for equation of segment - qreal a = 0, b = 0, c = 0; - LineCoefficients(line, &a, &b, &c); - // projection center of circle on to line - QPointF p = ClosestPoint (line, center); - // how many solutions? - qint32 flag = 0; - qreal d = QLineF (center, p).length(); - if (qFuzzyCompare(d, radius)) - { - flag = 1; - } - else - { - if (radius > d) - { - flag = 2; - } - else - { - return 0; - } - } - // find distance from projection to points of intersection - qreal k = qSqrt (qAbs(radius * radius - d * d)); - qreal t = QLineF (QPointF (0, 0), QPointF (b, - a)).length(); - // add to projection a vectors aimed to points of intersection - p1 = addVector (p, QPointF (0, 0), QPointF (- b, a), k / t); - p2 = addVector (p, QPointF (0, 0), QPointF (b, - a), k / t); - return flag; -} - -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief ClosestPoint find point projection of point onto line. - * @param line line. - * @return point on line or extended line if origin size too small. - */ -QPointF VAbstractTool::ClosestPoint(const QLineF &line, const QPointF &point) -{ - qreal a = 0, b = 0, c = 0; - LineCoefficients(line, &a, &b, &c); - qreal x = point.x() + a; - qreal y = b + point.y(); - QLineF lin (point, QPointF(x, y)); - QPointF p; - QLineF::IntersectType intersect = line.intersect(lin, &p); - if (intersect == QLineF::UnboundedIntersection || intersect == QLineF::BoundedIntersection) - { - return p; - } - else - { - return QPointF(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -QPointF VAbstractTool::addVector(const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k) -{ - return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k); -} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief DeleteTool full delete object form scene and file. @@ -369,23 +258,6 @@ void VAbstractTool::SaveOption(QSharedPointer &obj) } } -//--------------------------------------------------------------------------------------------------------------------- -/** - * @brief LineCoefficients coefficient for equation of segment. Segment equestion ax+by+c=0. - * @param line line - * @param a a value - * @param b b value - * @param c c value - */ -void VAbstractTool::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c) -{ - //coefficient for equation of segment - QPointF p1 = line.p1(); - *a = line.p2().y() - p1.y(); - *b = p1.x() - line.p2().x(); - *c = - *a * p1.x() - *b * p1.y(); -} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief Styles return list of all line styles. diff --git a/src/app/tools/vabstracttool.h b/src/app/tools/vabstracttool.h index ed9256066..f69a1339b 100644 --- a/src/app/tools/vabstracttool.h +++ b/src/app/tools/vabstracttool.h @@ -51,13 +51,7 @@ public: VAbstractTool(VPattern *doc, VContainer *data, quint32 id, QObject *parent = nullptr); virtual ~VAbstractTool(); static void NewSceneRect(QGraphicsScene *sc, QGraphicsView *view); - static QPointF LineIntersectRect(QRectF rec, QLineF line); - static qint32 LineIntersectCircle(const QPointF ¢er, qreal radius, const QLineF &line, QPointF &p1, - QPointF &p2); - static QPointF ClosestPoint(const QLineF &line, const QPointF &point); - static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k); quint32 getId() const; - static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c); static const QString AttrType; static const QString AttrMx; static const QString AttrMy; @@ -91,6 +85,7 @@ public: static const QString AttrPSpline; static const QString AttrAxisP1; static const QString AttrAxisP2; + static const QString AttrCurve; static const QString TypeLineNone; static const QString TypeLineLine; static const QString TypeLineDashLine; diff --git a/src/app/visualization/vcontrolpointspline.cpp b/src/app/visualization/vcontrolpointspline.cpp index 84aa95953..31c22d7aa 100644 --- a/src/app/visualization/vcontrolpointspline.cpp +++ b/src/app/visualization/vcontrolpointspline.cpp @@ -63,7 +63,7 @@ VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointP this->setZValue(100); QPointF p1, p2; - VAbstractTool::LineIntersectCircle(QPointF(), radius, QLineF( QPointF(), splinePoint-controlPoint), p1, p2); + VGObject::LineIntersectCircle(QPointF(), radius, QLineF( QPointF(), splinePoint-controlPoint), p1, p2); controlLine = new QGraphicsLineItem(QLineF(splinePoint-controlPoint, p1), this); controlLine->setPen(QPen(Qt::red, qApp->toPixel(qApp->widthHairLine()))); controlLine->setFlag(QGraphicsItem::ItemStacksBehindParent, true); @@ -156,7 +156,7 @@ void VControlPointSpline::RefreshLine(const qint32 &indexSpline, SplinePointPosi if (this->indexSpline == indexSpline && this->position == pos) { QPointF p1, p2; - VAbstractTool::LineIntersectCircle(QPointF(), radius, QLineF( QPointF(), splinePoint-controlPoint), p1, p2); + VGObject::LineIntersectCircle(QPointF(), radius, QLineF( QPointF(), splinePoint-controlPoint), p1, p2); controlLine->setLine(QLineF(splinePoint-controlPoint, p1)); } } diff --git a/src/app/visualization/visline.cpp b/src/app/visualization/visline.cpp index 2cacce052..6a8371f22 100644 --- a/src/app/visualization/visline.cpp +++ b/src/app/visualization/visline.cpp @@ -42,16 +42,6 @@ VisLine::VisLine(const VContainer *data, QGraphicsItem *parent) VisLine::~VisLine() {} -//--------------------------------------------------------------------------------------------------------------------- -QLineF VisLine::Line(const QPointF &p1, const qreal &length, const qreal &angle) -{ - QLineF line = QLineF(); - line.setP1(p1); - line.setLength(length); - line.setAngle(angle); - return line; -} - //--------------------------------------------------------------------------------------------------------------------- qreal VisLine::CorrectAngle(const qreal &angle) const { @@ -94,18 +84,15 @@ QPointF VisLine::Ray(const QPointF &firstPoint, const qreal &angle) const return line.p2();// We can't find ray because item doesn't have scene. We will return cursor position on scene. } - QLineF line = QLineF(); - line.setP1(firstPoint); - line.setAngle(angle); - QRectF scRect = this->scene()->sceneRect(); - qreal diagonal = qSqrt(pow(scRect.height(), 2) + pow(scRect.width(), 2)); - line.setLength(diagonal); if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) { - line.setAngle(CorrectAngle(line.angle())); + return VGObject::BuildRay(firstPoint, CorrectAngle(angle), scRect); + } + else + { + return VGObject::BuildRay(firstPoint, angle, scRect); } - return VAbstractTool::LineIntersectRect(scRect, line); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/visualization/visline.h b/src/app/visualization/visline.h index 8f8c4d884..d22389c3a 100644 --- a/src/app/visualization/visline.h +++ b/src/app/visualization/visline.h @@ -45,7 +45,6 @@ public: virtual int type() const {return Type;} enum { Type = UserType + static_cast(Vis::Line)}; protected: - QLineF Line(const QPointF &p1, const qreal& length, const qreal &angle); qreal CorrectAngle(const qreal &angle) const; QPointF Ray(const QPointF &firstPoint, const qreal &angle) const; QPointF Ray(const QPointF &firstPoint) const; diff --git a/src/app/visualization/vispath.cpp b/src/app/visualization/vispath.cpp index 61b3bc092..715d4000d 100644 --- a/src/app/visualization/vispath.cpp +++ b/src/app/visualization/vispath.cpp @@ -51,13 +51,3 @@ void VisPath::AddOnScene() { AddItem(this); } - -//--------------------------------------------------------------------------------------------------------------------- -void VisPath::DrawPath(QGraphicsPathItem *pathItem, const QPainterPath &path, const QColor &color, Qt::PenStyle style, - Qt::PenCapStyle cap) -{ - SCASSERT (pathItem != nullptr); - - pathItem->setPen(QPen(color, qApp->toPixel(qApp->widthMainLine())/factor, style, cap)); - pathItem->setPath(path); -} diff --git a/src/app/visualization/vispath.h b/src/app/visualization/vispath.h index 54d226863..4ac4e6fcb 100644 --- a/src/app/visualization/vispath.h +++ b/src/app/visualization/vispath.h @@ -44,9 +44,6 @@ public: protected: virtual void InitPen(); virtual void AddOnScene(); - - void DrawPath(QGraphicsPathItem *pathItem, const QPainterPath &path, const QColor &color, - Qt::PenStyle style = Qt::SolidLine, Qt::PenCapStyle cap = Qt::SquareCap); private: Q_DISABLE_COPY(VisPath) }; diff --git a/src/app/visualization/vistoolalongline.cpp b/src/app/visualization/vistoolalongline.cpp index 9e378b862..257dc4b5e 100644 --- a/src/app/visualization/vistoolalongline.cpp +++ b/src/app/visualization/vistoolalongline.cpp @@ -81,7 +81,7 @@ void VisToolAlongLine::RefreshGeometry() if (qFuzzyCompare(1 + length, 1 + 0) == false) { - QLineF mainLine = Line(first->toQPointF(), length, line->line().angle()); + QLineF mainLine = VGObject::BuildLine(first->toQPointF(), length, line->line().angle()); DrawLine(this, mainLine, mainColor, lineStyle); DrawPoint(point, mainLine.p2(), mainColor); diff --git a/src/app/visualization/vistoolbisector.cpp b/src/app/visualization/vistoolbisector.cpp index 695933f5a..97c59cd4f 100644 --- a/src/app/visualization/vistoolbisector.cpp +++ b/src/app/visualization/vistoolbisector.cpp @@ -102,7 +102,7 @@ void VisToolBisector::RefreshGeometry() { qreal angle = VToolBisector::BisectorAngle(first->toQPointF(), second->toQPointF(), third->toQPointF()); - QLineF mainLine = Line(second->toQPointF(), length, angle); + QLineF mainLine = VGObject::BuildLine(second->toQPointF(), length, angle); DrawLine(this, mainLine, mainColor, lineStyle); DrawPoint(point, mainLine.p2(), mainColor); @@ -112,7 +112,8 @@ void VisToolBisector::RefreshGeometry() qreal angle = VToolBisector::BisectorAngle(first->toQPointF(), second->toQPointF(), third->toQPointF()); QPointF endRay = Ray(second->toQPointF(), angle); - QLineF mainLine = Line(second->toQPointF(), QLineF(second->toQPointF(), endRay).length(), angle); + QLineF mainLine = VGObject::BuildLine(second->toQPointF(), + QLineF(second->toQPointF(), endRay).length(), angle); DrawLine(this, mainLine, mainColor, lineStyle); } } diff --git a/src/app/visualization/vistoolcurveintersectaxis.cpp b/src/app/visualization/vistoolcurveintersectaxis.cpp new file mode 100644 index 000000000..d3cabc903 --- /dev/null +++ b/src/app/visualization/vistoolcurveintersectaxis.cpp @@ -0,0 +1,104 @@ +/************************************************************************ + ** + ** @file vistoolcurveintersectaxis.cpp + ** @author Roman Telezhynskyi + ** @date 21 10, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vistoolcurveintersectaxis.h" +#include "../container/vcontainer.h" +#include "../geometry/vpointf.h" +#include "../tools/drawTools/vtoolcurveintersectaxis.h" + +//--------------------------------------------------------------------------------------------------------------------- +VisToolCurveIntersectAxis::VisToolCurveIntersectAxis(const VContainer *data, QGraphicsItem *parent) + : VisLine(data, parent), axisPointId(NULL_ID), angle(-1), point(nullptr), basePoint(nullptr), baseLine(nullptr), + axisLine(nullptr), visCurve(nullptr) +{ + this->mainColor = Qt::red; + + visCurve = InitItem(Qt::darkGreen, this); + basePoint = InitPoint(supportColor, this); + baseLine = InitItem(supportColor, this); + axisLine = InitItem(supportColor, this); + point = InitPoint(mainColor, this); +} + +//--------------------------------------------------------------------------------------------------------------------- +VisToolCurveIntersectAxis::~VisToolCurveIntersectAxis() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolCurveIntersectAxis::RefreshGeometry() +{ + if (point1Id > NULL_ID) + { + const QSharedPointer curve = Visualization::data->GeometricObject(point1Id); + DrawPath(visCurve, curve->GetPath(PathDirection::Show), supportColor, Qt::SolidLine, Qt::RoundCap); + + if (axisPointId > NULL_ID) + { + QLineF axis; + const QSharedPointer first = Visualization::data->GeometricObject(axisPointId); + if (qFuzzyCompare(angle, -1)) + { + axis = Axis(first->toQPointF(), Visualization::scenePos); + } + else + { + axis = Axis(first->toQPointF(), angle); + } + DrawPoint(basePoint, first->toQPointF(), mainColor); + DrawLine(axisLine, axis, supportColor, Qt::DashLine); + + QPointF p = VToolCurveIntersectAxis::FindPoint(first->toQPointF(), axis.angle(), curve); + QLineF axis_line(first->toQPointF(), p); + DrawLine(this, axis_line, mainColor, lineStyle); + + DrawPoint(point, p, mainColor); + + Visualization::toolTip = QString(tr("Intersection curve and axis: angle = %1°; Shift - " + "sticking angle, Enter - finish creation")) + .arg(this->line().angle()); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VisToolCurveIntersectAxis::Angle() const +{ + return QString("%1").arg(this->line().angle()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolCurveIntersectAxis::setAngle(const QString &expression) +{ + angle = FindVal(expression); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolCurveIntersectAxis::setAxisPointId(const quint32 &value) +{ + axisPointId = value; +} diff --git a/src/app/visualization/vistoolcurveintersectaxis.h b/src/app/visualization/vistoolcurveintersectaxis.h new file mode 100644 index 000000000..d6481bf48 --- /dev/null +++ b/src/app/visualization/vistoolcurveintersectaxis.h @@ -0,0 +1,62 @@ +/************************************************************************ + ** + ** @file vistoolcurveintersectaxis.h + ** @author Roman Telezhynskyi + ** @date 21 10, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2014 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VISTOOLCURVEINTERSECTAXIS_H +#define VISTOOLCURVEINTERSECTAXIS_H + +#include "visline.h" + +class QGraphicsEllipseItem; + +class VisToolCurveIntersectAxis : public VisLine +{ + Q_OBJECT +public: + VisToolCurveIntersectAxis(const VContainer *data, QGraphicsItem *parent = 0); + virtual ~VisToolCurveIntersectAxis(); + + virtual void RefreshGeometry(); + + QString Angle() const; + void setAngle(const QString &expression); + void setAxisPointId(const quint32 &value); + + virtual int type() const {return Type;} + enum { Type = UserType + static_cast(Vis::ToolLineIntersectAxis)}; +private: + Q_DISABLE_COPY(VisToolCurveIntersectAxis) + quint32 axisPointId; + qreal angle; + QGraphicsEllipseItem *point; + QGraphicsEllipseItem *basePoint; + QGraphicsLineItem *baseLine; + QGraphicsLineItem *axisLine; + QGraphicsPathItem *visCurve; +}; + +#endif // VISTOOLCURVEINTERSECTAXIS_H diff --git a/src/app/visualization/vistoolendline.cpp b/src/app/visualization/vistoolendline.cpp index d27d7be9c..0bd977362 100644 --- a/src/app/visualization/vistoolendline.cpp +++ b/src/app/visualization/vistoolendline.cpp @@ -57,7 +57,7 @@ void VisToolEndLine::RefreshGeometry() } else { - line = Line(first->toQPointF(), length, angle); + line = VGObject::BuildLine(first->toQPointF(), length, angle); DrawPoint(point, line.p2(), mainColor); } DrawLine(this, line, mainColor, lineStyle); diff --git a/src/app/visualization/vistoolshoulderpoint.cpp b/src/app/visualization/vistoolshoulderpoint.cpp index 49283788f..e5db76083 100644 --- a/src/app/visualization/vistoolshoulderpoint.cpp +++ b/src/app/visualization/vistoolshoulderpoint.cpp @@ -94,7 +94,8 @@ void VisToolShoulderPoint::RefreshGeometry() { qreal angle = QLineF(second->toQPointF(), third->toQPointF()).angle(); QPointF endRay = Ray(second->toQPointF(), angle); - QLineF mainLine = Line(second->toQPointF(), QLineF(second->toQPointF(), endRay).length(), angle); + QLineF mainLine = VGObject::BuildLine(second->toQPointF(), + QLineF(second->toQPointF(), endRay).length(), angle); DrawLine(this, mainLine, mainColor, lineStyle); } } diff --git a/src/app/visualization/visualization.cpp b/src/app/visualization/visualization.cpp index 914d8ba06..6b27f3f02 100644 --- a/src/app/visualization/visualization.cpp +++ b/src/app/visualization/visualization.cpp @@ -177,3 +177,13 @@ void Visualization::DrawLine(QGraphicsLineItem *lineItem, const QLineF &line, co lineItem->setPen(QPen(color, qApp->toPixel(qApp->widthHairLine())/factor, style)); lineItem->setLine(line); } + +//--------------------------------------------------------------------------------------------------------------------- +void Visualization::DrawPath(QGraphicsPathItem *pathItem, const QPainterPath &path, const QColor &color, + Qt::PenStyle style, Qt::PenCapStyle cap) +{ + SCASSERT (pathItem != nullptr); + + pathItem->setPen(QPen(color, qApp->toPixel(qApp->widthMainLine())/factor, style, cap)); + pathItem->setPath(path); +} diff --git a/src/app/visualization/visualization.h b/src/app/visualization/visualization.h index 49f02c674..3ff9a59e5 100644 --- a/src/app/visualization/visualization.h +++ b/src/app/visualization/visualization.h @@ -76,6 +76,8 @@ protected: Qt::PenStyle style = Qt::SolidLine); virtual void DrawLine(QGraphicsLineItem *lineItem, const QLineF &line, const QColor &color, Qt::PenStyle style = Qt::SolidLine); + void DrawPath(QGraphicsPathItem *pathItem, const QPainterPath &path, const QColor &color, + Qt::PenStyle style = Qt::SolidLine, Qt::PenCapStyle cap = Qt::SquareCap); template void AddItem(Item *item) diff --git a/src/app/visualization/visualization.pri b/src/app/visualization/visualization.pri index 9ef86c176..b304d535a 100644 --- a/src/app/visualization/visualization.pri +++ b/src/app/visualization/visualization.pri @@ -22,7 +22,8 @@ HEADERS += \ visualization/vistoolcutspline.h \ visualization/vistoolsplinepath.h \ visualization/vistoolcutsplinepath.h \ - visualization/vistoollineintersectaxis.h + visualization/vistoollineintersectaxis.h \ + visualization/vistoolcurveintersectaxis.h SOURCES += \ visualization/vgraphicssimpletextitem.cpp \ @@ -48,4 +49,5 @@ SOURCES += \ visualization/vistoolcutspline.cpp \ visualization/vistoolsplinepath.cpp \ visualization/vistoolcutsplinepath.cpp \ - visualization/vistoollineintersectaxis.cpp + visualization/vistoollineintersectaxis.cpp \ + visualization/vistoolcurveintersectaxis.cpp diff --git a/src/app/widgets/vtooloptionspropertybrowser.cpp b/src/app/widgets/vtooloptionspropertybrowser.cpp index 13f6d9e62..2832c54a0 100644 --- a/src/app/widgets/vtooloptionspropertybrowser.cpp +++ b/src/app/widgets/vtooloptionspropertybrowser.cpp @@ -134,6 +134,9 @@ void VToolOptionsPropertyBrowser::ShowItemOptions(QGraphicsItem *item) case VToolLineIntersectAxis::Type: ShowOptionsToolLineIntersectAxis(item); break; + case VToolCurveIntersectAxis::Type: + ShowOptionsToolCurveIntersectAxis(item); + break; default: break; } @@ -212,6 +215,9 @@ void VToolOptionsPropertyBrowser::UpdateOptions() case VToolLineIntersectAxis::Type: UpdateOptionsToolLineIntersectAxis(); break; + case VToolCurveIntersectAxis::Type: + UpdateOptionsToolCurveIntersectAxis(); + break; default: break; } @@ -297,6 +303,9 @@ void VToolOptionsPropertyBrowser::userChangedData(VProperty *property) case VToolLineIntersectAxis::Type: ChangeDataToolLineIntersectAxis(prop); break; + case VToolCurveIntersectAxis::Type: + ChangeDataToolCurveIntersectAxis(prop); + break; default: break; } @@ -878,6 +887,33 @@ void VToolOptionsPropertyBrowser::ChangeDataToolLineIntersectAxis(VProperty *pro } } +//--------------------------------------------------------------------------------------------------------------------- +void VToolOptionsPropertyBrowser::ChangeDataToolCurveIntersectAxis(VProperty *property) +{ + SCASSERT(property != nullptr) + + QVariant value = property->data(VProperty::DPC_Data, Qt::DisplayRole); + const QString id = propertyToId[property]; + + VToolCurveIntersectAxis *i = qgraphicsitem_cast(currentItem); + SCASSERT(i != nullptr); + switch (PropertiesList().indexOf(id)) + { + case 0: // VAbstractTool::AttrName + SetPointName(value.toString()); + break; + case 3: // VAbstractTool::AttrTypeLine + i->setTypeLine(value.toString()); + break; + case 5: // VAbstractTool::AttrAngle + i->setFormulaAngle(value.value()); + break; + default: + qWarning()<<"Unknown property type. id = "<getFormulaAngle(), VAbstractTool::AttrAngle); } +//--------------------------------------------------------------------------------------------------------------------- +void VToolOptionsPropertyBrowser::ShowOptionsToolCurveIntersectAxis(QGraphicsItem *item) +{ + VToolCurveIntersectAxis *i = qgraphicsitem_cast(item); + i->ShowVisualization(true); + formView->setTitle(tr("Point intersection line and axis")); + + AddPropertyPointName(i, tr("Point label")); + AddPropertyLineType(i, tr("Line type")); + AddPropertyFormula(tr("Angle"), i->getFormulaAngle(), VAbstractTool::AttrAngle); +} + //--------------------------------------------------------------------------------------------------------------------- void VToolOptionsPropertyBrowser::UpdateOptionsToolSinglePoint() { @@ -1351,6 +1399,21 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolLineIntersectAxis() idToProperty[VAbstractTool::AttrAngle]->setValue(valueAngle); } +//--------------------------------------------------------------------------------------------------------------------- +void VToolOptionsPropertyBrowser::UpdateOptionsToolCurveIntersectAxis() +{ + VToolCurveIntersectAxis *i = qgraphicsitem_cast(currentItem); + idToProperty[VAbstractTool::AttrName]->setValue(i->name()); + + QStringList styles = VAbstractTool::Styles(); + qint32 index = styles.indexOf(i->getLineType()); + idToProperty[VAbstractTool::AttrTypeLine]->setValue(index); + + QVariant valueAngle; + valueAngle.setValue(i->getFormulaAngle()); + idToProperty[VAbstractTool::AttrAngle]->setValue(valueAngle); +} + //--------------------------------------------------------------------------------------------------------------------- QStringList VToolOptionsPropertyBrowser::PropertiesList() const { diff --git a/src/app/widgets/vtooloptionspropertybrowser.h b/src/app/widgets/vtooloptionspropertybrowser.h index 99d346558..e558b46ca 100644 --- a/src/app/widgets/vtooloptionspropertybrowser.h +++ b/src/app/widgets/vtooloptionspropertybrowser.h @@ -95,6 +95,7 @@ private: void ChangeDataToolSplinePath(VPE::VProperty *property); void ChangeDataToolTriangle(VPE::VProperty *property); void ChangeDataToolLineIntersectAxis(VPE::VProperty *property); + void ChangeDataToolCurveIntersectAxis(VPE::VProperty *property); void ShowOptionsToolSinglePoint(QGraphicsItem *item); void ShowOptionsToolEndLine(QGraphicsItem *item); @@ -115,6 +116,7 @@ private: void ShowOptionsToolSplinePath(QGraphicsItem *item); void ShowOptionsToolTriangle(QGraphicsItem *item); void ShowOptionsToolLineIntersectAxis(QGraphicsItem *item); + void ShowOptionsToolCurveIntersectAxis(QGraphicsItem *item); void UpdateOptionsToolSinglePoint(); void UpdateOptionsToolEndLine(); @@ -135,6 +137,7 @@ private: void UpdateOptionsToolSplinePath(); void UpdateOptionsToolTriangle(); void UpdateOptionsToolLineIntersectAxis(); + void UpdateOptionsToolCurveIntersectAxis(); }; #endif // VTOOLOPTIONSPROPERTYBROWSER_H diff --git a/src/app/xml/vpattern.cpp b/src/app/xml/vpattern.cpp index 49f878ea2..5312563d1 100644 --- a/src/app/xml/vpattern.cpp +++ b/src/app/xml/vpattern.cpp @@ -1078,7 +1078,7 @@ void VPattern::ParsePointElement(VMainGraphicsScene *scene, QDomElement &domElem << VNodePoint::ToolType << VToolHeight::ToolType << VToolTriangle::ToolType << VToolPointOfIntersection::ToolType << VToolCutSpline::ToolType << VToolCutSplinePath::ToolType << VToolCutArc::ToolType - << VToolLineIntersectAxis::ToolType; + << VToolLineIntersectAxis::ToolType << VToolCurveIntersectAxis::ToolType; switch (points.indexOf(type)) { case 0: //VToolSinglePoint::ToolType @@ -1526,6 +1526,40 @@ void VPattern::ParsePointElement(VMainGraphicsScene *scene, QDomElement &domElem throw excep; } break; + case 16: //VToolCurveIntersectAxis::ToolType + try + { + PointsCommonAttributes(domElement, id, name, mx, my, typeLine); + + const quint32 basePointId = GetParametrUInt(domElement, VAbstractTool::AttrBasePoint, "0"); + const quint32 curveId = GetParametrUInt(domElement, VAbstractTool::AttrCurve, "0"); + const QString angle = GetParametrString(domElement, VAbstractTool::AttrAngle, "0.0"); + QString angleFix = angle; + + VToolCurveIntersectAxis::Create(id, name, typeLine, angleFix, basePointId, curveId, mx, my, scene, this, + data, parse, Source::FromFile); + //Rewrite attribute formula. Need for situation when we have wrong formula. + if (angleFix != angle) + { + SetAttribute(domElement, VAbstractTool::AttrAngle, angleFix); + haveLiteChange(); + } + } + catch (const VExceptionBadId &e) + { + VExceptionObjectError excep(tr("Error creating or updating point of intersection curve and axis"), + domElement); + excep.AddMoreInformation(e.ErrorMessage()); + throw excep; + } + catch (qmu::QmuParserError &e) + { + VExceptionObjectError excep(tr("Error creating or updating point of intersection curve and axis"), + domElement); + excep.AddMoreInformation(QString("Message: " + e.GetMsg() + "\n"+ "Expression: " + e.GetExpr())); + throw excep; + } + break; default: qDebug() << "Illegal point type in VDomDocument::ParsePointElement()."; break;