Untested changes for the tool Spline.

--HG--
branch : feature
This commit is contained in:
Roman Telezhynskyi 2016-02-15 16:30:48 +02:00
parent f264206aab
commit be3fc296f4
17 changed files with 263 additions and 38 deletions

View file

@ -1860,11 +1860,16 @@ void VPattern::ParseToolSpline(VMainGraphicsScene *scene, const QDomElement &dom
const qreal kAsm2 = GetParametrDouble(domElement, AttrKAsm2, "1.0");
const qreal kCurve = GetParametrDouble(domElement, AttrKCurve, "1.0");
const QString color = GetParametrString(domElement, AttrColor, ColorBlack);
const quint32 duplicate = GetParametrUInt(domElement, AttrDuplicate, "0");
const auto p1 = data->GeometricObject<VPointF>(point1);
const auto p4 = data->GeometricObject<VPointF>(point4);
VSpline spline(*p1, *p4, angle1, angle2, kAsm1, kAsm2, kCurve);
if (duplicate > 0)
{
spline.SetDuplicate(duplicate);
}
VToolSpline::Create(id, spline, color, scene, this, data, parse, Source::FromFile);
}

View file

@ -102,6 +102,7 @@ const QString AttrPoint4 = QStringLiteral("point4");
const QString AttrKAsm1 = QStringLiteral("kAsm1");
const QString AttrKAsm2 = QStringLiteral("kAsm2");
const QString AttrKCurve = QStringLiteral("kCurve");
const QString AttrDuplicate = QStringLiteral("duplicate");
const QString AttrPathPoint = QStringLiteral("pathPoint");
const QString AttrPSpline = QStringLiteral("pSpline");
const QString AttrAxisP1 = QStringLiteral("axisP1");

View file

@ -104,6 +104,7 @@ extern const QString AttrPoint4;
extern const QString AttrKAsm1;
extern const QString AttrKAsm2;
extern const QString AttrKCurve;
extern const QString AttrDuplicate;
extern const QString AttrPathPoint;
extern const QString AttrPSpline;
extern const QString AttrAxisP1;

View file

@ -27,17 +27,18 @@
*************************************************************************/
#include "vabstractcurve.h"
#include "vabstractcurve_p.h"
#include <QPainterPath>
#include <QDebug>
VAbstractCurve::VAbstractCurve(const GOType &type, const quint32 &idObject, const Draw &mode)
:VGObject(type, idObject, mode)
:VGObject(type, idObject, mode), d (new VAbstractCurveData())
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractCurve::VAbstractCurve(const VAbstractCurve &curve)
:VGObject(curve)
:VGObject(curve), d (curve.d)
{}
//---------------------------------------------------------------------------------------------------------------------
@ -48,9 +49,14 @@ VAbstractCurve &VAbstractCurve::operator=(const VAbstractCurve &curve)
return *this;
}
VGObject::operator=(curve);
d = curve.d;
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
VAbstractCurve::~VAbstractCurve()
{}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse) const
{
@ -165,6 +171,19 @@ bool VAbstractCurve::IsIntersectLine(const QLineF &line) const
return not points.isEmpty();
}
//---------------------------------------------------------------------------------------------------------------------
quint32 VAbstractCurve::GetDuplicate() const
{
return d->duplicate;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractCurve::SetDuplicate(quint32 number)
{
d->duplicate = number;
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::CurveIntersectLine(const QVector<QPointF> &points, const QLineF &line)
{

View file

@ -37,6 +37,7 @@ enum class PathDirection : char { Hide, Show };
class QPainterPath;
class QLineF;
class VAbstractCurveData;
class VAbstractCurve :public VGObject
{
@ -45,6 +46,7 @@ public:
const Draw &mode = Draw::Calculation);
explicit VAbstractCurve(const VAbstractCurve &curve);
VAbstractCurve& operator= (const VAbstractCurve &curve);
virtual ~VAbstractCurve() Q_DECL_OVERRIDE;
virtual QVector<QPointF> GetPoints() const =0;
QVector<QPointF> GetSegmentPoints(const QPointF &begin, const QPointF &end, bool reverse = false) const;
@ -57,12 +59,20 @@ public:
virtual qreal GetStartAngle () const=0;
virtual qreal GetEndAngle () const=0;
quint32 GetDuplicate() const;
void SetDuplicate(quint32 number);
static QVector<QPointF> CurveIntersectLine(const QVector<QPointF> &points, const QLineF &line);
protected:
QPainterPath ShowDirection(const QVector<QPointF> &points) const;
virtual void CreateName() =0;
private:
QSharedDataPointer<VAbstractCurveData> d;
static QVector<QPointF> FromBegin(const QVector<QPointF> &points, const QPointF &begin);
static QVector<QPointF> ToEnd(const QVector<QPointF> &points, const QPointF &end);
};
Q_DECLARE_TYPEINFO(VAbstractCurve, Q_MOVABLE_TYPE);
#endif // VABSTRACTCURVE_H

View file

@ -0,0 +1,67 @@
/************************************************************************
**
** @file vabstractcurve_p.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 15 2, 2016
**
** @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) 2016 Valentina project
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VABSTRACTCURVE_P_H
#define VABSTRACTCURVE_P_H
#include <QSharedData>
#ifdef Q_CC_GNU
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#endif
class VAbstractCurveData : public QSharedData
{
public:
VAbstractCurveData ()
: duplicate(0)
{}
VAbstractCurveData(const VAbstractCurveData &curve)
: QSharedData(curve), duplicate(curve.duplicate)
{}
virtual ~VAbstractCurveData();
/** @brief duplicate helps create unique name for curves that connects the same start and finish points. */
quint32 duplicate;
private:
VAbstractCurveData &operator=(const VAbstractCurveData &) Q_DECL_EQ_DELETE;
};
VAbstractCurveData::~VAbstractCurveData()
{}
#ifdef Q_CC_GNU
#pragma GCC diagnostic pop
#endif
#endif // VABSTRACTCURVE_P_H

View file

@ -58,14 +58,14 @@ VArc::VArc (VPointF center, qreal radius, QString formulaRadius, qreal f1, QStri
: VAbstractCurve(GOType::Arc, idObject, mode),
d (new VArcData(center, radius, formulaRadius, f1, formulaF1, f2, formulaF2))
{
ArcName();
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
VArc::VArc(VPointF center, qreal radius, qreal f1, qreal f2)
: VAbstractCurve(GOType::Arc, NULL_ID, Draw::Calculation), d (new VArcData(center, radius, f1, f2))
{
ArcName();
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
@ -74,7 +74,7 @@ VArc::VArc(qreal length, QString formulaLength, VPointF center, qreal radius, QS
: VAbstractCurve(GOType::Arc, idObject, mode),
d (new VArcData(formulaLength, center, radius, formulaRadius, f1, formulaF1))
{
ArcName();
CreateName();
FindF2(length);
}
@ -82,7 +82,7 @@ VArc::VArc(qreal length, QString formulaLength, VPointF center, qreal radius, QS
VArc::VArc(qreal length, VPointF center, qreal radius, qreal f1)
: VAbstractCurve(GOType::Arc, NULL_ID, Draw::Calculation), d (new VArcData(center, radius, f1))
{
ArcName();
CreateName();
FindF2(length);
}
@ -126,7 +126,7 @@ qreal VArc::GetLength() const
qreal length = (M_PI * d->radius)/180 * AngleArc();
if (d->isFlipped)
{
length = length * -1;
length *= -1;
}
return length;
@ -312,13 +312,25 @@ QPointF VArc::CutArc(const qreal &length) const
void VArc::setId(const quint32 &id)
{
VAbstractCurve::setId(id);
setName(ARC_ + QString("%1_%2").arg(d->center.name()).arg(id));
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
void VArc::ArcName()
void VArc::CreateName()
{
setName(ARC_ + QString("%1").arg(this->GetCenter().name()));
QString name = ARC_ + QString("%1").arg(this->GetCenter().name());
if (VAbstractCurve::id() != NULL_ID)
{
name += QString("_%1").arg(VAbstractCurve::id());
}
if (GetDuplicate() > 0)
{
name += QString("_%1").arg(GetDuplicate());
}
setName(name);
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -80,10 +80,11 @@ public:
QPointF CutArc (const qreal &length, VArc &arc1, VArc &arc2) const;
QPointF CutArc (const qreal &length) const;
virtual void setId(const quint32 &id) Q_DECL_OVERRIDE;
protected:
virtual void CreateName() Q_DECL_OVERRIDE;
private:
QSharedDataPointer<VArcData> d;
void ArcName();
void FindF2(qreal length);
qreal MaxLength() const;

View file

@ -27,4 +27,5 @@ HEADERS += \
$$PWD/vsplinepath_p.h \
$$PWD/vsplinepoint.h \
$$PWD/vsplinepoint_p.h \
$$PWD/vgeometrydef.h
$$PWD/vgeometrydef.h \
$$PWD/vabstractcurve_p.h

View file

@ -600,7 +600,13 @@ qreal VSpline::CalcSqDistance (qreal x1, qreal y1, qreal x2, qreal y2)
*/
void VSpline::CreateName()
{
setName(SPL_ + QString("%1_%2").arg(this->GetP1().name(), this->GetP4().name()));
QString name = SPL_ + QString("%1_%2").arg(this->GetP1().name()).arg(this->GetP4().name());
if (GetDuplicate() > 0)
{
name += QString("_%1").arg(GetDuplicate());
}
setName(name);
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -76,13 +76,13 @@ public:
qreal ParamT(const QPointF &pBt) const;
protected:
static QVector<QPointF> GetPoints (const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4 );
virtual void CreateName() Q_DECL_OVERRIDE;
private:
QSharedDataPointer<VSplineData> d;
static qreal LengthBezier (const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4 );
static void PointBezier_r ( qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4,
qint16 level, QVector<qreal> &px, QVector<qreal> &py);
static qreal CalcSqDistance ( qreal x1, qreal y1, qreal x2, qreal y2);
void CreateName();
QVector<qreal> CalcT(qreal curveCoord1, qreal curveCoord2, qreal curveCoord3, qreal curveCoord4,
qreal pointCoord) const;
static qint32 Cubic(QVector<qreal> &x, qreal a, qreal b, qreal c);

View file

@ -59,13 +59,7 @@ void VSplinePath::append(const VSplinePoint &point)
}
d->path.append(point);
QString name = splPath;
name.append(QString("_%1").arg(d->path.first().P().name()));
if (d->path.size() > 1)
{
name.append(QString("_%1").arg(d->path.last().P().name()));
}
setName(name);
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
@ -92,8 +86,8 @@ VSpline VSplinePath::GetSpline(qint32 index) const
{
throw VException(tr("This spline does not exist."));
}
const VSplinePoint &p1 = d->path.at(index-1);
const VSplinePoint &p2 = d->path.at(index);
const VSplinePoint &p1 = d->path.at(index-1);
const VSplinePoint &p2 = d->path.at(index);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p2.Angle1(), p1.KAsm2(), p2.KAsm1(), d->kCurve);
return spl;
}
@ -104,8 +98,8 @@ QPainterPath VSplinePath::GetPath(PathDirection direction) const
QPainterPath painterPath;
for (qint32 i = 1; i <= Count(); ++i)
{
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p2.Angle1(), p1.KAsm2(), p2.KAsm1(), d->kCurve);
painterPath.addPath(spl.GetPath(direction));
}
@ -118,8 +112,8 @@ QVector<QPointF> VSplinePath::GetPoints() const
QVector<QPointF> pathPoints;
for (qint32 i = 1; i <= Count(); ++i)
{
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p2.Angle1(), p1.KAsm2(), p2.KAsm1(), d->kCurve);
pathPoints += spl.GetPoints();
}
@ -132,8 +126,8 @@ qreal VSplinePath::GetLength() const
qreal length = 0;
for (qint32 i = 1; i <= Count(); ++i)
{
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p2.Angle1(),
p1.KAsm2(), p2.KAsm1(), d->kCurve);
length += spl.GetLength();
@ -222,10 +216,10 @@ QPointF VSplinePath::CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF
fullLength = 0;
for (qint32 i = 1; i <= Count(); ++i)
{
const VSplinePoint &point1 = d->path.at(i-1);
const VSplinePoint &point2 = d->path.at(i);
VSpline spl = VSpline(point1.P(), point2.P(), point1.Angle2(), point2.Angle1(), point1.KAsm2(),
point2.KAsm1(), d->kCurve);
const VSplinePoint &point1 = d->path.at(i-1);
const VSplinePoint &point2 = d->path.at(i);
VSpline spl = VSpline(point1.P(), point2.P(), point1.Angle2(), point2.Angle1(), point1.KAsm2(),
point2.KAsm1(), d->kCurve);
fullLength += spl.GetLength();
if (fullLength > length)
{
@ -243,8 +237,8 @@ int VSplinePath::Segment(const QPointF &p) const
int index = -1;
for (qint32 i = 1; i <= Count(); ++i)
{
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
VSpline spl = VSpline(p1.P(), p2.P(), p1.Angle2(), p2.Angle1(), p1.KAsm2(), p2.KAsm1(), d->kCurve);
const qreal t = spl.ParamT(p);
@ -288,6 +282,27 @@ qreal VSplinePath::GetEndAngle() const
}
}
//---------------------------------------------------------------------------------------------------------------------
void VSplinePath::CreateName()
{
QString name;
if (not d->path.isEmpty())
{
name = splPath;
name.append(QString("_%1").arg(d->path.first().P().name()));
if (d->path.size() > 1)
{
name.append(QString("_%1").arg(d->path.last().P().name()));
}
if (GetDuplicate() > 0)
{
name += QString("_%1").arg(GetDuplicate());
}
}
setName(name);
}
//---------------------------------------------------------------------------------------------------------------------
qint32 VSplinePath::CountPoint() const
{

View file

@ -178,6 +178,8 @@ public:
virtual qreal GetStartAngle () const Q_DECL_OVERRIDE;
virtual qreal GetEndAngle () const Q_DECL_OVERRIDE;
protected:
virtual void CreateName() Q_DECL_OVERRIDE;
private:
QSharedDataPointer<VSplinePathData> d;
};

View file

@ -43,7 +43,7 @@
* @param parent parent widget
*/
DialogSpline::DialogSpline(const VContainer *data, const quint32 &toolId, QWidget *parent)
:DialogTool(data, toolId, parent), ui(new Ui::DialogSpline), spl()
:DialogTool(data, toolId, parent), ui(new Ui::DialogSpline), spl(), newDuplicate(-1)
{
ui->setupUi(this);
InitOkCancelApply(ui);
@ -129,8 +129,18 @@ void DialogSpline::SaveData()
const qreal kAsm2 = ui->doubleSpinBoxKasm2->value();
const qreal kCurve = ui->doubleSpinBoxKcurve->value();
const quint32 d = spl.GetDuplicate();//Save previous value
spl = VSpline(*GetP1(), *GetP4(), angle1, angle2, kAsm1, kAsm2, kCurve);
if (newDuplicate <= -1)
{
spl.SetDuplicate(d);
}
else
{
spl.SetDuplicate(static_cast<quint32>(newDuplicate));
}
auto path = qobject_cast<VisToolSpline *>(vis);
SCASSERT(path != nullptr);
@ -157,6 +167,20 @@ const QSharedPointer<VPointF> DialogSpline::GetP4() const
return data->GeometricObject<VPointF>(getCurrentObjectId(ui->comboBoxP4));
}
//---------------------------------------------------------------------------------------------------------------------
quint32 DialogSpline::DNumber(const QString &baseName) const
{
quint32 num = 1;
QString name;
do
{
name = baseName + QString("_%1").arg(num);
++num;
} while (not data->IsUnique(name));
return num;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::PointNameChanged()
{
@ -169,11 +193,33 @@ void DialogSpline::PointNameChanged()
{
flagError = false;
color = errorColor;
ui->lineEditSplineName->setText(QString());
}
else
{
flagError = true;
color = okColor;
if (getCurrentObjectId(ui->comboBoxP1) == spl.GetP1().id() &&
getCurrentObjectId(ui->comboBoxP4) == spl.GetP4().id())
{
newDuplicate = -1;
ui->lineEditSplineName->setText(spl.name());
}
else
{
VSpline spline(*GetP1(), *GetP4(), spl.GetStartAngle(), spl.GetEndAngle(), spl.GetKasm1(), spl.GetKasm2(),
spl.GetKcurve());
if (not data->IsUnique(spline.name()))
{
newDuplicate = DNumber(spline.name());
spline.SetDuplicate(newDuplicate);
ui->lineEditSplineName->setText(spline.name());
}
}
}
ChangeColor(ui->labelFirstPoint, color);
ChangeColor(ui->labelSecondPoint, color);
@ -188,7 +234,7 @@ void DialogSpline::ShowDialog(bool click)
auto *path = qobject_cast<VisToolSpline *>(vis);
SCASSERT(path != nullptr);
VSpline spl(*GetP1(), path->GetP2(), path->GetP3(), *GetP4(), 1);
spl = VSpline(*GetP1(), path->GetP2(), path->GetP3(), *GetP4(), ui->doubleSpinBoxKcurve->value());
ui->spinBoxAngle1->setValue(static_cast<qint32>(spl.GetStartAngle()));
ui->spinBoxAngle2->setValue(static_cast<qint32>(spl.GetEndAngle()));
@ -196,6 +242,13 @@ void DialogSpline::ShowDialog(bool click)
ui->doubleSpinBoxKasm1->setValue(spl.GetKasm1());
ui->doubleSpinBoxKasm2->setValue(spl.GetKasm2());
if (not data->IsUnique(spl.name()))
{
spl.SetDuplicate(DNumber(spl.name()));
}
ui->lineEditSplineName->setText(spl.name());
DialogAccepted();
}
}
@ -225,6 +278,8 @@ void DialogSpline::SetSpline(const VSpline &spline)
ui->doubleSpinBoxKasm2->setValue(spl.GetKasm2());
ui->doubleSpinBoxKcurve->setValue(spl.GetKcurve());
ui->lineEditSplineName->setText(spl.name());
auto path = qobject_cast<VisToolSpline *>(vis);
SCASSERT(path != nullptr);

View file

@ -71,8 +71,12 @@ private:
/** @brief spl spline */
VSpline spl;
qint32 newDuplicate;
const QSharedPointer<VPointF> GetP1() const;
const QSharedPointer<VPointF> GetP4() const;
quint32 DNumber(const QString &baseName) const;
};
#endif // DIALOGSPLINE_H

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>540</width>
<height>233</height>
<height>273</height>
</rect>
</property>
<property name="windowTitle">
@ -207,6 +207,20 @@
<item row="1" column="1">
<widget class="QComboBox" name="comboBoxColor"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelName">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEditSplineName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>

View file

@ -316,6 +316,18 @@ void VToolSpline::SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &obj)
doc->SetAttribute(tag, AttrKAsm1, spl->GetKasm1());
doc->SetAttribute(tag, AttrKAsm2, spl->GetKasm2());
doc->SetAttribute(tag, AttrKCurve, spl->GetKcurve());
if (spl->GetDuplicate() > 0)
{
doc->SetAttribute(tag, AttrDuplicate, spl->GetDuplicate());
}
else
{
if (tag.hasAttribute(AttrDuplicate))
{
tag.removeAttribute(AttrDuplicate);
}
}
}
//---------------------------------------------------------------------------------------------------------------------