Merge with feature. An interactive spline path tool controled by formulas.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2016-03-05 23:08:04 +02:00
commit 56f41bbde6
54 changed files with 2606 additions and 952 deletions

View File

@ -1006,19 +1006,8 @@ void TMainWindow::Fx()
DialogEditWrongFormula *dialog = new DialogEditWrongFormula(meash->GetData(), NULL_ID, this);
dialog->setWindowTitle(tr("Edit measurement"));
QString text = ui->plainTextEditFormula->toPlainText();
text.replace("\n", " ");
try
{
text = qApp->TrVars()->FormulaFromUser(text, true);
}
catch (qmu::QmuParserError &e) // Just in case something bad will happen
{
Q_UNUSED(e)
text = ui->plainTextEditFormula->toPlainText();
}
dialog->SetFormula(text);
dialog->SetFormula(qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditFormula->toPlainText().replace("\n", " "),
true));
const QString postfix = VDomDocument::UnitsToStr(mUnit, true);//Show unit in dialog lable (cm, mm or inch)
dialog->setPostfix(postfix);

View File

@ -358,8 +358,9 @@ bool VApplication::notify(QObject *receiver, QEvent *event)
qUtf8Printable(e.ErrorMessage()), qUtf8Printable(e.DetailedInformation()));
return true;
}
// These last two cases special. I found that we can't show here modal dialog with error message.
// Somehow program doesn't waite untile an error dialog will be closed. But if ignore this program will hang.
// These last two cases are special. I found that we can't show here a modal dialog with an error message.
// Somehow program doesn't wait until an error dialog will be closed. But if ignore the exception the program will
// hang.
catch (const qmu::QmuParserError &e)
{
qCCritical(vApp, "%s", qUtf8Printable(tr("Parser error: %1. Program will be terminated.").arg(e.GetMsg())));

View File

@ -1361,13 +1361,6 @@ void VToolOptionsPropertyBrowser::ChangeDataToolSplinePath(VProperty *property)
case 0: // AttrName
Q_UNREACHABLE();//The attribute is read only
break;
case 25: // AttrKCurve
{
VSplinePath splPath = i->getSplinePath();
splPath.SetKCurve(value.toDouble());
i->setSplinePath(splPath);
break;
}
case 27: // AttrTypeColor
i->SetLineColor(value.toString());
break;
@ -1777,15 +1770,6 @@ void VToolOptionsPropertyBrowser::ShowOptionsToolSplinePath(QGraphicsItem *item)
formView->setTitle(tr("Tool for path curve"));
AddPropertyObjectName(i, tr("Name"), true);
VDoubleProperty* itemFactor = new VDoubleProperty(tr("Curve factor"));
VSplinePath splPath = i->getSplinePath();
itemFactor->setSetting("Min", 0.1);
itemFactor->setSetting("Max", 1000);
itemFactor->setSetting("Step", 0.01);
itemFactor->setSetting("Precision", 3);
itemFactor->setValue(splPath.GetKCurve());
AddProperty(itemFactor, AttrKCurve);
AddPropertyLineColor(i, tr("Color"), VAbstractTool::ColorsList(), AttrColor);
}
@ -2212,7 +2196,6 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolSplinePath()
auto i = qgraphicsitem_cast<VToolSplinePath *>(currentItem);
idToProperty[AttrName]->setValue(i->name());
idToProperty[AttrKCurve]->setValue(i->getSplinePath().GetKCurve());
idToProperty[AttrColor]->setValue(VLineColorProperty::IndexOfColor(VAbstractTool::ColorsList(), i->GetLineColor()));
}

View File

@ -634,7 +634,7 @@ void DialogIncrements::SaveIncrFormula()
const QString formula = qApp->TrVars()->FormulaFromUser(text, qApp->Settings()->GetOsSeparator());
doc->SetIncrementFormula(nameField->text(), formula);
}
catch (qmu::QmuParserError &e) // Just in case something bad happens
catch (qmu::QmuParserError &e) // Just in case something bad will happen
{
Q_UNUSED(e)
return;
@ -697,11 +697,8 @@ void DialogIncrements::Fx()
DialogEditWrongFormula *dialog = new DialogEditWrongFormula(incr->GetData(), NULL_ID, this);
dialog->setWindowTitle(tr("Edit increment"));
QString text = ui->plainTextEditFormula->toPlainText();
text.replace("\n", " ");
text = qApp->TrVars()->FormulaFromUser(text, qApp->Settings()->GetOsSeparator());
dialog->SetFormula(text);
dialog->SetFormula(qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditFormula->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator()));
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
dialog->setPostfix(postfix);//Show unit in dialog lable (cm, mm or inch)

View File

@ -1939,7 +1939,7 @@ void VPattern::ParseToolSpline(VMainGraphicsScene *scene, QDomElement &domElemen
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::ParseToolSplinePath(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse)
void VPattern::ParseOldToolSplinePath(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse)
{
SCASSERT(scene != nullptr);
Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null");
@ -1953,11 +1953,7 @@ void VPattern::ParseToolSplinePath(VMainGraphicsScene *scene, const QDomElement
const QString color = GetParametrString(domElement, AttrColor, ColorBlack);
const quint32 duplicate = GetParametrUInt(domElement, AttrDuplicate, "0");
auto path = new VSplinePath(kCurve);
if (duplicate > 0)
{
path->SetDuplicate(duplicate);
}
QVector<VFSplinePoint> points;
const QDomNodeList nodeList = domElement.childNodes();
const qint32 num = nodeList.size();
@ -1977,8 +1973,8 @@ void VPattern::ParseToolSplinePath(VMainGraphicsScene *scene, const QDomElement
QLineF line(0, 0, 100, 0);
line.setAngle(angle+180);
VSplinePoint splPoint(p, kAsm1, line.angle(), kAsm2, angle);
path->append(splPoint);
VFSplinePoint splPoint(p, kAsm1, line.angle(), kAsm2, angle);
points.append(splPoint);
if (parse == Document::FullParse)
{
IncrementReferens(p.getIdTool());
@ -1987,6 +1983,12 @@ void VPattern::ParseToolSplinePath(VMainGraphicsScene *scene, const QDomElement
}
}
auto path = new VSplinePath(points, kCurve);
if (duplicate > 0)
{
path->SetDuplicate(duplicate);
}
VToolSplinePath::Create(id, path, color, scene, this, data, parse, Source::FromFile);
}
catch (const VExceptionBadId &e)
@ -1997,6 +1999,95 @@ void VPattern::ParseToolSplinePath(VMainGraphicsScene *scene, const QDomElement
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::ParseToolSplinePath(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse)
{
SCASSERT(scene != nullptr);
Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null");
try
{
quint32 id = 0;
ToolsCommonAttributes(domElement, id);
const QString color = GetParametrString(domElement, AttrColor, ColorBlack);
const quint32 duplicate = GetParametrUInt(domElement, AttrDuplicate, "0");
auto path = new VSplinePath();
if (duplicate > 0)
{
path->SetDuplicate(duplicate);
}
QVector<quint32> points;
QVector<QString> angle1, a1;
QVector<QString> angle2, a2;
QVector<QString> length1, l1;
QVector<QString> length2, l2;
const QDomNodeList nodeList = domElement.childNodes();
const qint32 num = nodeList.size();
for (qint32 i = 0; i < num; ++i)
{
const QDomElement element = nodeList.at(i).toElement();
if (not element.isNull() && element.tagName() == AttrPathPoint)
{
angle1.append(GetParametrString(element, AttrAngle1, "0"));
angle2.append(GetParametrString(element, AttrAngle2, "0"));
length1.append(GetParametrString(element, AttrLength1, "0"));
length2.append(GetParametrString(element, AttrLength2, "0"));
const quint32 pSpline = GetParametrUInt(element, AttrPSpline, NULL_ID_STR);
points.append(pSpline);
if (parse == Document::FullParse)
{
IncrementReferens(data->GeometricObject<VPointF>(pSpline)->getIdTool());
}
}
}
//need for saving fixed formula;
a1 = angle1;
a2 = angle2;
l1 = length1;
l2 = length2;
VToolSplinePath::Create(id, points, a1, a2, l1, l2, color, scene, this, data, parse, Source::FromFile);
//Rewrite attribute formula. Need for situation when we have wrong formula.
int count = 0;
for (qint32 i = 0; i < num; ++i)
{
QDomElement element = nodeList.at(i).toElement();
if (not element.isNull() && element.tagName() == AttrPathPoint)
{
if (a1.at(count) != angle1.at(count) || a2.at(count) != angle2.at(count) ||
l1.at(count) != length1.at(count) || l2.at(count) != length2.at(count))
{
SetAttribute(element, AttrAngle1, a1.at(count));
SetAttribute(element, AttrAngle2, a2.at(count));
SetAttribute(element, AttrLength1, l1.at(count));
SetAttribute(element, AttrLength2, l2.at(count));
modified = true;
haveLiteChange();
}
++count;
}
}
}
catch (const VExceptionBadId &e)
{
VExceptionObjectError excep(tr("Error creating or updating curve path"), domElement);
excep.AddMoreInformation(e.ErrorMessage());
throw excep;
}
catch (qmu::QmuParserError &e)
{
VExceptionObjectError excep(tr("Error creating or updating interactive spline path"), domElement);
excep.AddMoreInformation(QString("Message: " + e.GetMsg() + "\n"+ "Expression: " + e.GetExpr()));
throw excep;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::ParseNodeSpline(const QDomElement &domElement, const Document &parse)
{
@ -2281,30 +2372,35 @@ void VPattern::ParseSplineElement(VMainGraphicsScene *scene, QDomElement &domEle
Q_ASSERT_X(domElement.isNull() == false, Q_FUNC_INFO, "domElement is null");
Q_ASSERT_X(type.isEmpty() == false, Q_FUNC_INFO, "type of spline is empty");
QStringList splines = QStringList() << VToolSpline::OldToolType /*0*/
<< VToolSpline::ToolType /*1*/
<< VToolSplinePath::ToolType /*2*/
<< VNodeSpline::ToolType /*3*/
<< VNodeSplinePath::ToolType; /*4*/
QStringList splines = QStringList() << VToolSpline::OldToolType /*0*/
<< VToolSpline::ToolType /*1*/
<< VToolSplinePath::OldToolType /*2*/
<< VToolSplinePath::ToolType /*3*/
<< VNodeSpline::ToolType /*4*/
<< VNodeSplinePath::ToolType; /*5*/
switch (splines.indexOf(type))
{
case 0: //VToolSpline::OldToolType
qCDebug(vXML, "VToolSpline.");
qCDebug(vXML, "VOldToolSpline.");
ParseOldToolSpline(scene, domElement, parse);// TODO. Delete if minimal supported version is 0.2.7
break;
case 1: //VToolSpline::ToolType
qCDebug(vXML, "VToolSpline.");
ParseToolSpline(scene, domElement, parse);
break;
case 2: //VToolSplinePath::ToolType
case 2: //VToolSplinePath::OldToolType
qCDebug(vXML, "VOldToolSplinePath.");
ParseOldToolSplinePath(scene, domElement, parse);// TODO. Delete if minimal supported version is 0.2.7
break;
case 3: //VToolSplinePath::ToolType
qCDebug(vXML, "VToolSplinePath.");
ParseToolSplinePath(scene, domElement, parse);
break;
case 3: //VNodeSpline::ToolType
case 4: //VNodeSpline::ToolType
qCDebug(vXML, "VNodeSpline.");
ParseNodeSpline(domElement, parse);
break;
case 4: //VNodeSplinePath::ToolType
case 5: //VNodeSplinePath::ToolType
qCDebug(vXML, "VNodeSplinePath.");
ParseNodeSplinePath(domElement, parse);
break;

View File

@ -171,6 +171,10 @@ private:
void ParseOldToolSpline(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse);
void ParseToolSpline(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse);
// TODO. Delete if minimal supported version is 0.2.7
void ParseOldToolSplinePath(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse);
void ParseToolSplinePath(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse);
void ParseNodeSpline(const QDomElement &domElement, const Document &parse);
void ParseNodeSplinePath(const QDomElement &domElement, const Document &parse);

View File

@ -180,6 +180,10 @@
<xs:attribute name="kAsm2" type="xs:string"></xs:attribute>
<xs:attribute name="pSpline" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="angle" type="xs:string"></xs:attribute>
<xs:attribute name="angle1" type="xs:string"></xs:attribute>
<xs:attribute name="angle2" type="xs:string"></xs:attribute>
<xs:attribute name="length1" type="xs:string"></xs:attribute>
<xs:attribute name="length2" type="xs:string"></xs:attribute>
<xs:attribute name="kAsm1" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>

View File

@ -145,28 +145,6 @@ QDomElement VDomDocument::elementById(quint32 id)
return elementById(QString().setNum(id));
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Removes all children of a given element tag. RENAME: removeAllChildren
* @param element tag
*/
void VDomDocument::removeAllChilds(QDomElement &element)
{
QDomNode domNode = element.firstChild();
while (domNode.isNull() == false)
{
if (domNode.isElement())
{
QDomElement domElement = domNode.toElement();
if (domElement.isNull() == false)
{
element.removeChild(domElement);
}
}
domNode = element.firstChild();
}
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Find element by id.
@ -740,10 +718,10 @@ bool VDomDocument::setTagText(const QString &tag, const QString &text)
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief RemoveAllChild remove all child from file.
* @brief RemoveAllChildren remove all children from file.
* @param domElement tag in xml tree.
*/
void VDomDocument::RemoveAllChild(QDomElement &domElement)
void VDomDocument::RemoveAllChildren(QDomElement &domElement)
{
if ( domElement.hasChildNodes() )
{

View File

@ -80,7 +80,6 @@ public:
virtual ~VDomDocument();
QDomElement elementById(const QString& id);
QDomElement elementById(quint32 id);
void removeAllChilds(QDomElement &element);
template <typename T>
void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const;
@ -106,7 +105,7 @@ public:
QString Major() const;
QString Minor() const;
QString Patch() const;
static void RemoveAllChild(QDomElement &domElement);
static void RemoveAllChildren(QDomElement &domElement);
QDomNode ParentNodeById(const quint32 &nodeId);
QDomElement CloneNodeById(const quint32 &nodeId);

View File

@ -37,13 +37,73 @@
#endif
//---------------------------------------------------------------------------------------------------------------------
VSplinePath::VSplinePath(qreal kCurve, quint32 idObject, Draw mode)
: VAbstractCurve(GOType::SplinePath, idObject, mode), d(new VSplinePathData(kCurve))
/**
* @brief VSplinePath constructor.
* @param idObject parent id.
* @param mode mode creation spline path.
*/
VSplinePath::VSplinePath(quint32 idObject, Draw mode)
: VAbstractCurve(GOType::SplinePath, idObject, mode),
d(new VSplinePathData())
{}
//---------------------------------------------------------------------------------------------------------------------
VSplinePath::VSplinePath(const QVector<VFSplinePoint> &points, qreal kCurve, quint32 idObject, Draw mode)
: VAbstractCurve(GOType::SplinePath, idObject, mode),
d(new VSplinePathData())
{
if (points.size() < 3)
{
return;
}
QVector<VSplinePoint> newPoints;
for (int i=0; i < points.size(); ++i)
{
newPoints.append(VSplinePoint());
}
for (qint32 i = 1; i <= points.size()-1; ++i)
{
const VFSplinePoint &p1 = points.at(i-1);
const VFSplinePoint &p2 = points.at(i);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p2.Angle1(), p1.KAsm2(), p2.KAsm1(), kCurve);
newPoints[i-1].SetP(p1.P());
newPoints[i-1].SetAngle2(p1.Angle2(), spl.GetStartAngleFormula());
newPoints[i-1].SetLength2(spl.GetC1Length(), spl.GetC1LengthFormula());
newPoints[i].SetP(p2.P());
newPoints[i].SetAngle1(p2.Angle1(), spl.GetEndAngleFormula());
newPoints[i].SetLength1(spl.GetC2Length(), spl.GetC2LengthFormula());
}
d->path = newPoints;
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
VSplinePath::VSplinePath(const QVector<VSplinePoint> &points, quint32 idObject, Draw mode)
: VAbstractCurve(GOType::SplinePath, idObject, mode),
d(new VSplinePathData())
{
if (points.isEmpty())
{
return;
}
d->path = points;
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief VSplinePath copy constructor.
* @param splPath spline path.
*/
VSplinePath::VSplinePath(const VSplinePath &splPath)
: VAbstractCurve(splPath), d(splPath.d)
: VAbstractCurve(splPath),
d(splPath.d)
{}
//---------------------------------------------------------------------------------------------------------------------
@ -51,6 +111,10 @@ VSplinePath::~VSplinePath()
{}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief append add point in the end of list points.
* @param point new point.
*/
void VSplinePath::append(const VSplinePoint &point)
{
if (d->path.size() > 0 && d->path.last().P().toQPointF() == point.P().toQPointF()) //-V807
@ -63,6 +127,10 @@ void VSplinePath::append(const VSplinePoint &point)
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Count return count point.
* @return count.
*/
qint32 VSplinePath::Count() const
{
if (d->path.size() == 0)
@ -76,6 +144,11 @@ qint32 VSplinePath::Count() const
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetSpline return spline by index.
* @param index index spline in spline path.
* @return spline
*/
VSpline VSplinePath::GetSpline(qint32 index) const
{
if (Count()<1)
@ -88,11 +161,16 @@ VSpline VSplinePath::GetSpline(qint32 index) const
}
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);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p1.Angle2Formula(), p2.Angle1(), p2.Angle1Formula(), p1.Length2(),
p1.Length2Formula(), p2.Length1(), p2.Length1Formula(), 1);
return spl;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetPath return QPainterPath which reprezent spline path.
* @return path.
*/
QPainterPath VSplinePath::GetPath(PathDirection direction) const
{
QPainterPath painterPath;
@ -100,13 +178,18 @@ QPainterPath VSplinePath::GetPath(PathDirection direction) const
{
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);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p1.Angle2Formula(), p2.Angle1(), p2.Angle1Formula(), p1.Length2(),
p1.Length2Formula(), p2.Length1(), p2.Length1Formula(), 1);
painterPath.addPath(spl.GetPath(direction));
}
return painterPath;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetPathPoints return list of points what located on path.
* @return list.
*/
QVector<QPointF> VSplinePath::GetPoints() const
{
QVector<QPointF> pathPoints;
@ -114,13 +197,18 @@ QVector<QPointF> VSplinePath::GetPoints() const
{
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);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p1.Angle2Formula(), p2.Angle1(), p2.Angle1Formula(), p1.Length2(),
p1.Length2Formula(), p2.Length1(), p2.Length1Formula(), 1);
pathPoints += spl.GetPoints();
}
return pathPoints;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetLength return length of spline path.
* @return length.
*/
qreal VSplinePath::GetLength() const
{
qreal length = 0;
@ -128,14 +216,20 @@ qreal VSplinePath::GetLength() const
{
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);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p1.Angle2Formula(), p2.Angle1(), p2.Angle1Formula(), p1.Length2(),
p1.Length2Formula(), p2.Length1(), p2.Length1Formula(), 1);
length += spl.GetLength();
}
return length;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief UpdatePoint update spline point in list.
* @param indexSpline spline index in list.
* @param pos position point in spline.
* @param point point.
*/
void VSplinePath::UpdatePoint(qint32 indexSpline, const SplinePointPosition &pos, const VSplinePoint &point)
{
if (indexSpline < 1 || indexSpline > Count())
@ -153,6 +247,12 @@ void VSplinePath::UpdatePoint(qint32 indexSpline, const SplinePointPosition &pos
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetSplinePoint return spline point from list.
* @param indexSpline spline index in list.
* @param pos position point in spline.
* @return spline point.
*/
VSplinePoint VSplinePath::GetSplinePoint(qint32 indexSpline, SplinePointPosition pos) const
{
if (indexSpline < 1 || indexSpline > Count())
@ -170,6 +270,11 @@ VSplinePoint VSplinePath::GetSplinePoint(qint32 indexSpline, SplinePointPosition
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief operator = assignment operator.
* @param path spline path.
* @return spline path.
*/
VSplinePath &VSplinePath::operator =(const VSplinePath &path)
{
if ( &path == this )
@ -182,18 +287,49 @@ VSplinePath &VSplinePath::operator =(const VSplinePath &path)
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief operator [] return spline point by index.
* @param indx index in list.
* @return spline point.
*/
VSplinePoint & VSplinePath::operator[](int indx)
{
return d->path[indx];
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief at return spline point by index.
* @param indx index in list.
* @return spline point.
*/
const VSplinePoint &VSplinePath::at(int indx) const
{
return d->path[indx];
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief CutSplinePath cut spline path into two. This method don't return two spline path. You must create spline
* paths by yourself.
* Example:
* QPointF spl1p2, spl1p3, spl2p2, spl2p3;
* qint32 p1 = 0, p2 = 0;
* QPointF point = splPath->CutSplinePath(length, p1, p2, spl1p2, spl1p3, spl2p2, spl2p3);
*
* VSplinePoint splP1 = splPath->at(p1);
* VSplinePoint splP2 = splPath->at(p2);
* VSpline spl1 = VSpline(splP1.P(), spl1p2, spl1p3, *p, splPath->GetKCurve());
* VSpline spl2 = VSpline(*p, spl2p2, spl2p3, splP2.P(), splPath->GetKCurve());
* @param length length first spline path.
* @param p1 index first spline point in list.
* @param p2 index second spline point in list.
* @param spl1p2 first control point first spline.
* @param spl1p3 second control point first spline.
* @param spl2p2 first control point second spline.
* @param spl2p3 second control point second spline.
* @return cutting point.
*/
QPointF VSplinePath::CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF &spl1p2, QPointF &spl1p3,
QPointF &spl2p2, QPointF &spl2p3) const
{
@ -218,8 +354,9 @@ QPointF VSplinePath::CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF
{
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);
VSpline spl = VSpline(point1.P(), point2.P(), point1.Angle2(), point1.Angle2Formula(), point2.Angle1(),
point2.Angle1Formula(), point1.Length2(), point1.Length2Formula(), point2.Length1(),
point2.Length1Formula(), 1);
fullLength += spl.GetLength();
if (fullLength > length)
{
@ -239,7 +376,8 @@ int VSplinePath::Segment(const QPointF &p) const
{
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);
VSpline spl = VSpline(p1.P(), p2.P(), p1.Angle2(), p1.Angle2Formula(), p2.Angle1(), p2.Angle1Formula(),
p1.Length2(), p1.Length2Formula(), p2.Length1(), p2.Length1Formula(), 1.0);
const qreal t = spl.ParamT(p);
@ -304,41 +442,56 @@ void VSplinePath::CreateName()
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief CountPoint return count point.
* @return count.
*/
qint32 VSplinePath::CountPoint() const
{
return d->path.size();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetSplinePath return list with spline points.
* @return list.
*/
QVector<VSplinePoint> VSplinePath::GetSplinePath() const
{
return d->path;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<VFSplinePoint> VSplinePath::GetFSplinePath() const
{
QVector<VFSplinePoint> points;
points.reserve(d->path.size());
for (qint32 i = 1; i <= Count(); ++i)
{
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
VSpline spl(p1.P(), p2.P(), p1.Angle2(), p1.Angle2Formula(), p2.Angle1(), p2.Angle1Formula(), p1.Length2(),
p1.Length2Formula(), p2.Length1(), p2.Length1Formula(), 1);
points[i-1].SetP(p1.P());
points[i-1].SetAngle2(p1.Angle2());
points[i-1].SetKAsm2(spl.GetKasm1());
points[i].SetP(p2.P());
points[i].SetAngle1(p2.Angle1());
points[i].SetKAsm1(spl.GetKasm2());
}
return points;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Clear clear list of points.
*/
void VSplinePath::Clear()
{
d->path.clear();
SetDuplicate(0);
}
//---------------------------------------------------------------------------------------------------------------------
qreal VSplinePath::GetKCurve() const
{
return d->kCurve;
}
//---------------------------------------------------------------------------------------------------------------------
void VSplinePath::SetKCurve(const qreal &value)
{
if (value > 0)
{
d->kCurve = value;
}
}
//---------------------------------------------------------------------------------------------------------------------
const QVector<VSplinePoint> *VSplinePath::GetPoint() const
{
return &d->path;
}

View File

@ -45,139 +45,41 @@ class VSplinePath :public VAbstractCurve
{
Q_DECLARE_TR_FUNCTIONS(VSplinePath)
public:
/**
* @brief VSplinePath constructor.
* @param kCurve coefficient of curvature spline path.
* @param idObject parent id.
* @param mode mode creation spline path.
*/
explicit VSplinePath(qreal kCurve = 1, quint32 idObject = 0, Draw mode = Draw::Calculation);
/**
* @brief VSplinePath copy constructor.
* @param splPath spline path.
*/
explicit VSplinePath(quint32 idObject = 0, Draw mode = Draw::Calculation);
VSplinePath(const QVector<VFSplinePoint> &points, qreal kCurve = 1, quint32 idObject = 0,
Draw mode = Draw::Calculation);
VSplinePath(const QVector<VSplinePoint> &points, quint32 idObject = 0, Draw mode = Draw::Calculation);
VSplinePath(const VSplinePath& splPath);
virtual ~VSplinePath() Q_DECL_OVERRIDE;
/**
* @brief append add point in the end of list points.
* @param point new point.
*/
void append(const VSplinePoint &point);
/**
* @brief Count return count point.
* @return count.
*/
qint32 Count() const;
/**
* @brief CountPoint return count point.
* @return count.
*/
qint32 CountPoint() const;
/**
* @brief GetSpline return spline by index.
* @param index index spline in spline path.
* @return spline
*/
VSpline GetSpline(qint32 index) const;
/**
* @brief GetPath return QPainterPath which reprezent spline path.
* @return path.
*/
QPainterPath GetPath(PathDirection direction = PathDirection::Hide) const;
/**
* @brief GetPathPoints return list of points what located on path.
* @return list.
*/
QVector<QPointF> GetPoints() const;
/**
* @brief GetSplinePath return list with spline points.
* @return list.
*/
QVector<VSplinePoint> GetSplinePath() const;
/**
* @brief GetLength return length of spline path.
* @return length.
*/
qreal GetLength() const;
/**
* @brief UpdatePoint update spline point in list.
* @param indexSpline spline index in list.
* @param pos position point in spline.
* @param point point.
*/
void UpdatePoint(qint32 indexSpline, const SplinePointPosition &pos, const VSplinePoint &point);
/**
* @brief GetSplinePoint return spline point from list.
* @param indexSpline spline index in list.
* @param pos position point in spline.
* @return spline point.
*/
VSplinePoint GetSplinePoint(qint32 indexSpline, SplinePointPosition pos) const;
/**
* @brief Clear clear list of points.
*/
void Clear();
/**
* @brief GetKCurve return coefficient of curvature spline path.
* @return coefficient of curvature spline.
*/
qreal GetKCurve() const;
/**
* @brief SetKCurve set coefficient of curvature spline path.
* @param value coefficient of curvature spline path.
*/
void SetKCurve(const qreal &value);
/**
* @brief GetPoint pointer to list spline point.
* @return list.
*/
const QVector<VSplinePoint> *GetPoint() const;
/**
* @brief operator = assignment operator.
* @param path spline path.
* @return spline path.
*/
VSplinePath &operator=(const VSplinePath &path);
/**
* @brief operator [] return spline point by index.
* @param indx index in list.
* @return spline point.
*/
VSplinePoint &operator[](int indx);
/**
* @brief at return spline point by index.
* @param indx index in list.
* @return spline point.
*/
const VSplinePoint &at(int indx) const;
/**
* @brief CutSplinePath cut spline path into two. This method don't return two spline path. You must create spline
* paths by yourself.
* Example:
* QPointF spl1p2, spl1p3, spl2p2, spl2p3;
* qint32 p1 = 0, p2 = 0;
* QPointF point = splPath->CutSplinePath(length, p1, p2, spl1p2, spl1p3, spl2p2, spl2p3);
*
* VSplinePoint splP1 = splPath->at(p1);
* VSplinePoint splP2 = splPath->at(p2);
* VSpline spl1 = VSpline(splP1.P(), spl1p2, spl1p3, *p, splPath->GetKCurve());
* VSpline spl2 = VSpline(*p, spl2p2, spl2p3, splP2.P(), splPath->GetKCurve());
* @param length length first spline path.
* @param p1 index first spline point in list.
* @param p2 index second spline point in list.
* @param spl1p2 first control point first spline.
* @param spl1p3 second control point first spline.
* @param spl2p2 first control point second spline.
* @param spl2p3 second control point second spline.
* @return cutting point.
*/
QPointF CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2,
QPointF &spl2p3) const;
int Segment(const QPointF &p) const;
VSplinePath &operator=(const VSplinePath &path);
VSplinePoint &operator[](int indx);
void append(const VSplinePoint &point);
qint32 Count() const;
qint32 CountPoint() const;
void Clear();
VSpline GetSpline(qint32 index) const;
QPainterPath GetPath(PathDirection direction = PathDirection::Hide) const;
QVector<QPointF> GetPoints() const;
qreal GetLength() const;
QVector<VSplinePoint> GetSplinePath() const;
QVector<VFSplinePoint> GetFSplinePath() const;
virtual qreal GetStartAngle () const Q_DECL_OVERRIDE;
virtual qreal GetEndAngle () const Q_DECL_OVERRIDE;
void UpdatePoint(qint32 indexSpline, const SplinePointPosition &pos, const VSplinePoint &point);
VSplinePoint GetSplinePoint(qint32 indexSpline, SplinePointPosition pos) const;
const VSplinePoint &at(int indx) const;
QPointF CutSplinePath(qreal length, qint32 &p1, qint32 &p2, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2,
QPointF &spl2p3) const;
int Segment(const QPointF &p) const;
protected:
virtual void CreateName() Q_DECL_OVERRIDE;
private:

View File

@ -42,15 +42,12 @@ class VSplinePathData : public QSharedData
public:
VSplinePathData()
: path(QVector<VSplinePoint>()), kCurve(1)
{}
explicit VSplinePathData(qreal kCurve)
: path(QVector<VSplinePoint>()), kCurve(kCurve)
: path(QVector<VSplinePoint>())
{}
VSplinePathData(const VSplinePathData &splPath)
: QSharedData(splPath), path(splPath.path), kCurve(splPath.kCurve)
: QSharedData(splPath),
path(splPath.path)
{}
virtual ~VSplinePathData();
@ -59,10 +56,6 @@ public:
* @brief path list spline point.
*/
QVector<VSplinePoint> path;
/**
* @brief kCurve coefficient of curvature spline.
*/
qreal kCurve;
private:
VSplinePathData &operator=(const VSplinePathData &) Q_DECL_EQ_DELETE;

View File

@ -28,41 +28,43 @@
#include "vsplinepoint.h"
#include "vsplinepoint_p.h"
#include "../qmuparser/qmutokenparser.h"
#include <QDebug>
#include <QLineF>
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief VSplinePoint default constructor.
* @brief VFSplinePoint default constructor.
*/
VSplinePoint::VSplinePoint()
:d(new VSplinePointData)
VFSplinePoint::VFSplinePoint()
:d(new VFSplinePointData)
{}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief VSplinePoint constructor.
* @brief VFSplinePoint constructor.
* @param pSpline spline point.
* @param kAsm1 coefficient of length first control line.
* @param angle1 first angle control line.
* @param kAsm2 coefficient of length second control line.
* @param angle2 second angle control line.
*/
VSplinePoint::VSplinePoint(VPointF pSpline, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2)
:d(new VSplinePointData(pSpline, kAsm1, angle1, kAsm2, angle2))
VFSplinePoint::VFSplinePoint(VPointF pSpline, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2)
:d(new VFSplinePointData(pSpline, kAsm1, angle1, kAsm2, angle2))
{}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief VSplinePoint copy constructor
* @brief VFSplinePoint copy constructor
* @param point point
*/
VSplinePoint::VSplinePoint(const VSplinePoint &point)
VFSplinePoint::VFSplinePoint(const VFSplinePoint &point)
:d(point.d)
{}
//---------------------------------------------------------------------------------------------------------------------
VSplinePoint &VSplinePoint::operator=(const VSplinePoint &point)
VFSplinePoint &VFSplinePoint::operator=(const VFSplinePoint &point)
{
if ( &point == this )
{
@ -73,7 +75,7 @@ VSplinePoint &VSplinePoint::operator=(const VSplinePoint &point)
}
//---------------------------------------------------------------------------------------------------------------------
VSplinePoint::~VSplinePoint()
VFSplinePoint::~VFSplinePoint()
{}
//---------------------------------------------------------------------------------------------------------------------
@ -81,7 +83,7 @@ VSplinePoint::~VSplinePoint()
* @brief SetAngle1 set first angle of spline.
* @param value angle.
*/
void VSplinePoint::SetAngle1(const qreal &value)
void VFSplinePoint::SetAngle1(const qreal &value)
{
QLineF line(0, 0, 100, 0);
line.setAngle(value);
@ -96,7 +98,7 @@ void VSplinePoint::SetAngle1(const qreal &value)
* @brief SetAngle2 set second angle of spline.
* @param value angle.
*/
void VSplinePoint::SetAngle2(const qreal &value)
void VFSplinePoint::SetAngle2(const qreal &value)
{
QLineF line(0, 0, 100, 0);
line.setAngle(value);
@ -111,7 +113,7 @@ void VSplinePoint::SetAngle2(const qreal &value)
* @brief P return point.
* @return point.
*/
VPointF VSplinePoint::P() const
VPointF VFSplinePoint::P() const
{
return d->pSpline;
}
@ -121,7 +123,7 @@ VPointF VSplinePoint::P() const
* @brief SetP set point.
* @param value point.
*/
void VSplinePoint::SetP(const VPointF &value)
void VFSplinePoint::SetP(const VPointF &value)
{
d->pSpline = value;
}
@ -131,7 +133,7 @@ void VSplinePoint::SetP(const VPointF &value)
* @brief Angle1 return first angle of spline.
* @return angle.
*/
qreal VSplinePoint::Angle1() const
qreal VFSplinePoint::Angle1() const
{
return d->angle1;
}
@ -141,7 +143,7 @@ qreal VSplinePoint::Angle1() const
* @brief Angle2 return second angle of spline.
* @return angle.
*/
qreal VSplinePoint::Angle2() const
qreal VFSplinePoint::Angle2() const
{
return d->angle2;
}
@ -151,7 +153,7 @@ qreal VSplinePoint::Angle2() const
* @brief KAsm1 return coefficient of length first control line.
* @return coefficient.
*/
qreal VSplinePoint::KAsm1() const
qreal VFSplinePoint::KAsm1() const
{
return d->kAsm1;
}
@ -161,7 +163,7 @@ qreal VSplinePoint::KAsm1() const
* @brief SetKAsm1 set coefficient of length first control line.
* @param value coefficient.
*/
void VSplinePoint::SetKAsm1(const qreal &value)
void VFSplinePoint::SetKAsm1(const qreal &value)
{
d->kAsm1 = value;
}
@ -171,7 +173,7 @@ void VSplinePoint::SetKAsm1(const qreal &value)
* @brief KAsm2 return coefficient of length second control line.
* @return coefficient.
*/
qreal VSplinePoint::KAsm2() const
qreal VFSplinePoint::KAsm2() const
{
return d->kAsm2;
}
@ -181,7 +183,151 @@ qreal VSplinePoint::KAsm2() const
* @brief SetKAsm2 set coefficient of length second control line.
* @param value coefficient.
*/
void VSplinePoint::SetKAsm2(const qreal &value)
void VFSplinePoint::SetKAsm2(const qreal &value)
{
d->kAsm2 = value;
}
//------------------------------------------VSplinePoint---------------------------------------------------------------
VSplinePoint::VSplinePoint()
: d(new VSplinePointData)
{
}
//---------------------------------------------------------------------------------------------------------------------
VSplinePoint::VSplinePoint(VPointF pSpline, qreal angle1, const QString &angle1F, qreal angle2, const QString &angle2F,
qreal length1, const QString &length1F, qreal length2, const QString &length2F)
: d(new VSplinePointData(pSpline, angle1, angle1F, angle2, angle2F, length1, length1F, length2, length2F))
{
}
//---------------------------------------------------------------------------------------------------------------------
VSplinePoint::VSplinePoint(const VSplinePoint &point)
: d(point.d)
{
}
//---------------------------------------------------------------------------------------------------------------------
VSplinePoint &VSplinePoint::operator=(const VSplinePoint &point)
{
if ( &point == this )
{
return *this;
}
d = point.d;
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
VSplinePoint::~VSplinePoint()
{
}
//---------------------------------------------------------------------------------------------------------------------
VPointF VSplinePoint::P() const
{
return d->pSpline;
}
//---------------------------------------------------------------------------------------------------------------------
void VSplinePoint::SetP(const VPointF &value)
{
d->pSpline = value;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VSplinePoint::Angle1() const
{
return d->angle1;
}
//---------------------------------------------------------------------------------------------------------------------
QString VSplinePoint::Angle1Formula() const
{
return d->angle1F;
}
//---------------------------------------------------------------------------------------------------------------------
void VSplinePoint::SetAngle1(const qreal &value, const QString &angle1F)
{
d->angle1F = angle1F;
QLineF line(0, 0, 100, 0);
line.setAngle(value);
d->angle1 = line.angle();
line.setAngle(d->angle1+180);
d->angle2 = line.angle();
d->angle2F = QString().number(d->angle2);
}
//---------------------------------------------------------------------------------------------------------------------
qreal VSplinePoint::Angle2() const
{
return d->angle2;
}
//---------------------------------------------------------------------------------------------------------------------
QString VSplinePoint::Angle2Formula() const
{
return d->angle2F;
}
//---------------------------------------------------------------------------------------------------------------------
void VSplinePoint::SetAngle2(const qreal &value, const QString &angle2F)
{
d->angle2F = angle2F;
QLineF line(0, 0, 100, 0);
line.setAngle(value);
d->angle2 = line.angle();
line.setAngle(d->angle2+180);
d->angle1 = line.angle();
d->angle1F = QString().number(d->angle1);
}
//---------------------------------------------------------------------------------------------------------------------
qreal VSplinePoint::Length1() const
{
return d->length1;
}
//---------------------------------------------------------------------------------------------------------------------
QString VSplinePoint::Length1Formula() const
{
return d->length1F;
}
//---------------------------------------------------------------------------------------------------------------------
void VSplinePoint::SetLength1(const qreal &value, const QString &length1F)
{
d->length1 = value;
d->length1F = length1F;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VSplinePoint::Length2() const
{
return d->length2;
}
//---------------------------------------------------------------------------------------------------------------------
QString VSplinePoint::Length2Formula() const
{
return d->length2F;
}
//---------------------------------------------------------------------------------------------------------------------
void VSplinePoint::SetLength2(const qreal &value, const QString &length2F)
{
d->length2 = value;
d->length2F = length2F;
}
//---------------------------------------------------------------------------------------------------------------------
bool VSplinePoint::IsMovable() const
{
return qmu::QmuTokenParser::IsSingle(d->angle1F) && qmu::QmuTokenParser::IsSingle(d->angle2F) &&
qmu::QmuTokenParser::IsSingle(d->length1F) && qmu::QmuTokenParser::IsSingle(d->length2F);
}

View File

@ -32,20 +32,20 @@
#include "vpointf.h"
#include <QMetaType>
class VSplinePointData;
class VFSplinePointData;
/**
* @brief The VSplinePoint class keep information about point in spline path. Each point have two angles and two
* coefficient. Point represent at the same time first and last point of spline.
* @brief The VFSplinePoint class keep information about point in spline path. Each point have two angles and two
* coefficient. Point represent at the same time first and last point of a spline.
*/
class VSplinePoint
class VFSplinePoint
{
public:
VSplinePoint();
VSplinePoint(VPointF pSpline, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2);
VSplinePoint(const VSplinePoint &point);
VSplinePoint &operator=(const VSplinePoint &point);
~VSplinePoint();
VFSplinePoint();
VFSplinePoint(VPointF pSpline, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2);
VFSplinePoint(const VFSplinePoint &point);
VFSplinePoint &operator=(const VFSplinePoint &point);
~VFSplinePoint();
VPointF P() const;
void SetP(const VPointF &value);
@ -57,6 +57,49 @@ public:
void SetKAsm1(const qreal &value);
qreal KAsm2() const;
void SetKAsm2(const qreal &value);
protected:
QSharedDataPointer<VFSplinePointData> d;
};
Q_DECLARE_METATYPE(VFSplinePoint)
Q_DECLARE_TYPEINFO(VFSplinePoint, Q_MOVABLE_TYPE);
class VSplinePointData;
/**
* @brief The VSplinePoint class keep information about point in spline path. Each point have two angles and two
* lengths. Point represent at the same time first and last point of a spline.
*/
class VSplinePoint
{
public:
VSplinePoint();
VSplinePoint(VPointF pSpline, qreal angle1, const QString &angle1F, qreal angle2, const QString &angle2F,
qreal length1, const QString &length1F, qreal length2, const QString &length2F);
VSplinePoint(const VSplinePoint &point);
VSplinePoint &operator=(const VSplinePoint &point);
~VSplinePoint();
VPointF P() const;
void SetP(const VPointF &value);
qreal Angle1() const;
QString Angle1Formula() const;
void SetAngle1(const qreal &value, const QString &angle1F);
qreal Angle2() const;
QString Angle2Formula() const;
void SetAngle2(const qreal &value, const QString &angle2F);
qreal Length1() const;
QString Length1Formula() const;
void SetLength1(const qreal &value, const QString &length1F);
qreal Length2() const;
QString Length2Formula() const;
void SetLength2(const qreal &value, const QString &length2F);
bool IsMovable() const;
protected:
QSharedDataPointer<VSplinePointData> d;
};

View File

@ -38,46 +38,136 @@
#pragma GCC diagnostic ignored "-Weffc++"
#endif
class VSplinePointData : public QSharedData
class VFSplinePointData : public QSharedData
{
public:
VSplinePointData()
:pSpline(VPointF()), angle1(0), angle2(180), kAsm1(1), kAsm2(1)
VFSplinePointData()
: pSpline(VPointF()),
angle1(0),
angle2(180),
kAsm1(1),
kAsm2(1)
{}
VSplinePointData(VPointF pSpline, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2)
:pSpline(pSpline), angle1(angle1), angle2(angle2), kAsm1(kAsm1), kAsm2(kAsm2)
VFSplinePointData(VPointF pSpline, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2)
: pSpline(pSpline),
angle1(angle1),
angle2(angle2),
kAsm1(kAsm1),
kAsm2(kAsm2)
{
if (qFuzzyCompare(qAbs(angle1-angle2), 180) == false)
if (not qFuzzyCompare(qAbs(angle1-angle2), 180) || qFuzzyIsNull(qAbs(angle1-angle2)))
{
qWarning()<<"angle1 and angle2 are not equal.";
qDebug()<<"angle1 and angle2 are not equal.";
this->angle1 = angle1;
this->angle2 = angle1 + 180;
}
}
VSplinePointData(const VSplinePointData &point)
:QSharedData(point), pSpline(point.pSpline), angle1(point.angle1), angle2(point.angle2), kAsm1(point.kAsm1),
VFSplinePointData(const VFSplinePointData &point)
: QSharedData(point),
pSpline(point.pSpline),
angle1(point.angle1),
angle2(point.angle2),
kAsm1(point.kAsm1),
kAsm2(point.kAsm2)
{}
virtual ~VFSplinePointData();
/** @brief pSpline point. */
VPointF pSpline;
/** @brief angle1 first angle spline. */
qreal angle1;
/** @brief angle2 second angle spline. */
qreal angle2;
/** @brief kAsm1 coefficient of length first control line. */
qreal kAsm1;
/** @brief kAsm2 coefficient of length second control line. */
qreal kAsm2;
private:
VFSplinePointData &operator=(const VFSplinePointData &) Q_DECL_EQ_DELETE;
};
VFSplinePointData::~VFSplinePointData()
{}
//--------------------------------------VSplinePointData---------------------------------------------------------------
class VSplinePointData : public QSharedData
{
public:
VSplinePointData()
: pSpline(),
angle1(0),
angle1F("0"),
angle2(180),
angle2F("180"),
length1(0),
length1F("0"),
length2(0),
length2F("0")
{}
VSplinePointData(VPointF pSpline, qreal angle1, const QString &angle1F, qreal angle2, const QString &angle2F,
qreal length1, const QString &length1F, qreal length2, const QString &length2F)
: pSpline(pSpline),
angle1(angle1),
angle1F(angle1F),
angle2(angle2),
angle2F(angle2F),
length1(length1),
length1F(length1F),
length2(length2),
length2F(length2F)
{
if (not qFuzzyCompare(qAbs(angle1-angle2), 180) || qFuzzyIsNull(qAbs(angle1-angle2)))
{
qDebug()<<"angle1 and angle2 are not equal.";
this->angle2 = angle1 + 180;
this->angle2F = QString().number(angle2);
}
}
VSplinePointData(const VSplinePointData &point)
: QSharedData(point),
pSpline(point.pSpline),
angle1(point.angle1),
angle1F(point.angle1F),
angle2(point.angle2),
angle2F(point.angle2F),
length1(point.length1),
length1F(point.length1F),
length2(point.length2),
length2F(point.length2F)
{}
virtual ~VSplinePointData();
/** @brief pSpline point. */
VPointF pSpline;
VPointF pSpline;
/** @brief angle1 first angle spline. */
qreal angle1;
qreal angle1;
QString angle1F;
/** @brief angle2 second angle spline. */
qreal angle2;
qreal angle2;
QString angle2F;
/** @brief kAsm1 coefficient of length first control line. */
qreal kAsm1;
/** @brief length1 length a first control line. */
qreal length1;
QString length1F;
/** @brief kAsm2 coefficient of length second control line. */
qreal kAsm2;
/** @brief length2 length a second control line. */
qreal length2;
QString length2F;
private:
VSplinePointData &operator=(const VSplinePointData &) Q_DECL_EQ_DELETE;

View File

@ -103,7 +103,7 @@ QString VFormula::GetFormula(FormulaType type) const
}
else
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
}

View File

@ -29,6 +29,7 @@
#include "vtranslatevars.h"
#include "calculator.h"
#include "../vmisc/def.h"
#include "../vmisc/vabstractapplication.h"
#include "../vgeometry/vgeometrydef.h"
#include "../qmuparser/qmutokenparser.h"
#include "../ifc/ifcdef.h"
@ -781,6 +782,20 @@ QString VTranslateVars::FormulaFromUser(const QString &formula, bool osSeparator
return newFormula;
}
//---------------------------------------------------------------------------------------------------------------------
QString VTranslateVars::TryFormulaFromUser(const QString &formula, bool osSeparator) const
{
try
{
return qApp->TrVars()->FormulaFromUser(formula, osSeparator);
}
catch (qmu::QmuParserError &e)// In case something bad will happen
{
Q_UNUSED(e)
return formula;
}
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief FormulaToUser replace all known tokens in formula to user look. Also change decimal

View File

@ -54,6 +54,7 @@ public:
QString PostfixOperator(const QString &name) const;
QString FormulaFromUser(const QString &formula, bool osSeparator) const;
QString TryFormulaFromUser(const QString &formula, bool osSeparator) const;
QString FormulaToUser(const QString &formula) const;
virtual void Retranslate() Q_DECL_OVERRIDE;

View File

@ -349,7 +349,7 @@ void DialogEditWrongFormula::setPostfix(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
QString DialogEditWrongFormula::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -316,7 +316,7 @@ QString DialogAlongLine::GetTypeLine() const
*/
QString DialogAlongLine::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -272,7 +272,8 @@ void DialogArc::RadiusChanged()
{
labelEditFormula = ui->labelEditRadius;
labelResultCalculation = ui->labelResultRadius;
ValFormulaChanged(flagRadius, ui->plainTextEditFormula, timerRadius);
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
ValFormulaChanged(flagRadius, ui->plainTextEditFormula, timerRadius, postfix);
}
//---------------------------------------------------------------------------------------------------------------------
@ -283,7 +284,7 @@ void DialogArc::F1Changed()
{
labelEditFormula = ui->labelEditF1;
labelResultCalculation = ui->labelResultF1;
ValFormulaChanged(flagF1, ui->plainTextEditF1, timerF1);
ValFormulaChanged(flagF1, ui->plainTextEditF1, timerF1, degreeSymbol);
}
//---------------------------------------------------------------------------------------------------------------------
@ -294,7 +295,7 @@ void DialogArc::F2Changed()
{
labelEditFormula = ui->labelEditF2;
labelResultCalculation = ui->labelResultF2;
ValFormulaChanged(flagF2, ui->plainTextEditF2, timerF2);
ValFormulaChanged(flagF2, ui->plainTextEditF2, timerF2, degreeSymbol);
}
//---------------------------------------------------------------------------------------------------------------------
@ -428,7 +429,7 @@ quint32 DialogArc::GetCenter() const
*/
QString DialogArc::GetRadius() const
{
return qApp->TrVars()->FormulaFromUser(radius, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(radius, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -438,7 +439,7 @@ QString DialogArc::GetRadius() const
*/
QString DialogArc::GetF1() const
{
return qApp->TrVars()->FormulaFromUser(f1, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(f1, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -448,5 +449,5 @@ QString DialogArc::GetF1() const
*/
QString DialogArc::GetF2() const
{
return qApp->TrVars()->FormulaFromUser(f2, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(f2, qApp->Settings()->GetOsSeparator());
}

View File

@ -110,7 +110,7 @@ void DialogArcWithLength::SetCenter(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
QString DialogArcWithLength::GetRadius() const
{
return qApp->TrVars()->FormulaFromUser(radius, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(radius, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -134,7 +134,7 @@ void DialogArcWithLength::SetRadius(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
QString DialogArcWithLength::GetF1() const
{
return qApp->TrVars()->FormulaFromUser(f1, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(f1, qApp->Settings()->GetOsSeparator());
}
void DialogArcWithLength::SetF1(const QString &value)
@ -157,7 +157,7 @@ void DialogArcWithLength::SetF1(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
QString DialogArcWithLength::GetLength() const
{
return qApp->TrVars()->FormulaFromUser(length, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(length, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -231,7 +231,8 @@ void DialogArcWithLength::RadiusChanged()
{
labelEditFormula = ui->labelEditRadius;
labelResultCalculation = ui->labelResultRadius;
ValFormulaChanged(flagRadius, ui->plainTextEditRadius, timerRadius);
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
ValFormulaChanged(flagRadius, ui->plainTextEditRadius, timerRadius, postfix);
}
//---------------------------------------------------------------------------------------------------------------------
@ -239,7 +240,7 @@ void DialogArcWithLength::F1Changed()
{
labelEditFormula = ui->labelEditF1;
labelResultCalculation = ui->labelResultF1;
ValFormulaChanged(flagF1, ui->plainTextEditF1, timerF1);
ValFormulaChanged(flagF1, ui->plainTextEditF1, timerF1, degreeSymbol);
}
//---------------------------------------------------------------------------------------------------------------------
@ -247,7 +248,8 @@ void DialogArcWithLength::LengthChanged()
{
labelEditFormula = ui->labelEditLength;
labelResultCalculation = ui->labelResultLength;
ValFormulaChanged(flagLength, ui->plainTextEditLength, timerLength);
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
ValFormulaChanged(flagLength, ui->plainTextEditLength, timerLength, postfix);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -349,7 +349,7 @@ QString DialogBisector::GetTypeLine() const
*/
QString DialogBisector::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -104,7 +104,7 @@ void DialogCurveIntersectAxis::SetTypeLine(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
QString DialogCurveIntersectAxis::GetAngle() const
{
return qApp->TrVars()->FormulaFromUser(formulaAngle, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formulaAngle, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -248,7 +248,7 @@ void DialogCurveIntersectAxis::EvalAngle()
//---------------------------------------------------------------------------------------------------------------------
void DialogCurveIntersectAxis::AngleTextChanged()
{
ValFormulaChanged(flagError, ui->plainTextEditFormula, timerFormula);
ValFormulaChanged(flagError, ui->plainTextEditFormula, timerFormula, degreeSymbol);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -231,7 +231,7 @@ void DialogCutArc::SetPointName(const QString &value)
*/
QString DialogCutArc::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -225,7 +225,7 @@ void DialogCutSpline::ShowVisualization()
*/
QString DialogCutSpline::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -225,7 +225,7 @@ void DialogCutSplinePath::ShowVisualization()
*/
QString DialogCutSplinePath::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -108,7 +108,7 @@ void DialogEndLine::FormulaTextChanged()
void DialogEndLine::AngleTextChanged()
{
labelEditFormula = ui->labelEditAngle;
ValFormulaChanged(flagError, ui->plainTextEditAngle, timerFormula);
ValFormulaChanged(flagError, ui->plainTextEditAngle, timerFormula, degreeSymbol);
labelEditFormula = ui->labelEditFormula;
}
@ -363,7 +363,7 @@ QString DialogEndLine::GetTypeLine() const
*/
QString DialogEndLine::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formulaLength, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formulaLength, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -373,7 +373,7 @@ QString DialogEndLine::GetFormula() const
*/
QString DialogEndLine::GetAngle() const
{
return qApp->TrVars()->FormulaFromUser(formulaAngle, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formulaAngle, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -113,7 +113,7 @@ void DialogLineIntersectAxis::SetTypeLine(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
QString DialogLineIntersectAxis::GetAngle() const
{
return qApp->TrVars()->FormulaFromUser(formulaAngle, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formulaAngle, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -291,7 +291,7 @@ void DialogLineIntersectAxis::EvalAngle()
//---------------------------------------------------------------------------------------------------------------------
void DialogLineIntersectAxis::AngleTextChanged()
{
ValFormulaChanged(flagError, ui->plainTextEditFormula, timerFormula);
ValFormulaChanged(flagError, ui->plainTextEditFormula, timerFormula, degreeSymbol);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -322,7 +322,7 @@ QString DialogNormal::GetTypeLine() const
*/
QString DialogNormal::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -118,8 +118,8 @@ void DialogPointFromCircleAndTangent::SetCircleCenterId(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
QString DialogPointFromCircleAndTangent::GetCircleRadius() const
{
return qApp->TrVars()->FormulaFromUser(ui->plainTextEditRadius->toPlainText(),
qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditRadius->toPlainText(),
qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -246,7 +246,8 @@ void DialogPointFromCircleAndTangent::CircleRadiusChanged()
{
labelEditFormula = ui->labelEditRadius;
labelResultCalculation = ui->labelResultCircleRadius;
ValFormulaChanged(flagCircleRadius, ui->plainTextEditRadius, timerCircleRadius);
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
ValFormulaChanged(flagCircleRadius, ui->plainTextEditRadius, timerCircleRadius, postfix);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -310,7 +310,7 @@ void DialogPointOfContact::SetPointName(const QString &value)
*/
QString DialogPointOfContact::getRadius() const
{
return qApp->TrVars()->FormulaFromUser(radius, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(radius, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -150,8 +150,8 @@ void DialogPointOfIntersectionCircles::SetSecondCircleCenterId(const quint32 &va
//---------------------------------------------------------------------------------------------------------------------
QString DialogPointOfIntersectionCircles::GetFirstCircleRadius() const
{
return qApp->TrVars()->FormulaFromUser(ui->plainTextEditCircle1Radius->toPlainText(),
qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditCircle1Radius->toPlainText(),
qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -175,8 +175,8 @@ void DialogPointOfIntersectionCircles::SetFirstCircleRadius(const QString &value
//---------------------------------------------------------------------------------------------------------------------
QString DialogPointOfIntersectionCircles::GetSecondCircleRadius() const
{
return qApp->TrVars()->FormulaFromUser(ui->plainTextEditCircle2Radius->toPlainText(),
qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditCircle2Radius->toPlainText(),
qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
@ -293,7 +293,8 @@ void DialogPointOfIntersectionCircles::Circle1RadiusChanged()
{
labelEditFormula = ui->labelEditCircle1Radius;
labelResultCalculation = ui->labelResultCircle1Radius;
ValFormulaChanged(flagCircle1Radius, ui->plainTextEditCircle1Radius, timerCircle1Radius);
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
ValFormulaChanged(flagCircle1Radius, ui->plainTextEditCircle1Radius, timerCircle1Radius, postfix);
}
//---------------------------------------------------------------------------------------------------------------------
@ -301,7 +302,8 @@ void DialogPointOfIntersectionCircles::Circle2RadiusChanged()
{
labelEditFormula = ui->labelEditCircle2Radius;
labelResultCalculation = ui->labelResultCircle2Radius;
ValFormulaChanged(flagCircle2Radius, ui->plainTextEditCircle2Radius, timerCircle2Radius);
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
ValFormulaChanged(flagCircle2Radius, ui->plainTextEditCircle2Radius, timerCircle2Radius, postfix);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -348,7 +348,7 @@ QString DialogShoulderPoint::GetTypeLine() const
*/
QString DialogShoulderPoint::GetFormula() const
{
return qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
return qApp->TrVars()->TryFormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -233,7 +233,7 @@ void DialogSpline::Angle1Changed()
{
labelEditFormula = ui->labelEditAngle1;
labelResultCalculation = ui->labelResultAngle1;
ValFormulaChanged(flagAngle1, ui->plainTextEditAngle1F, timerAngle1);
ValFormulaChanged(flagAngle1, ui->plainTextEditAngle1F, timerAngle1, degreeSymbol);
}
//---------------------------------------------------------------------------------------------------------------------
@ -241,7 +241,7 @@ void DialogSpline::Angle2Changed()
{
labelEditFormula = ui->labelEditAngle2;
labelResultCalculation = ui->labelResultAngle2;
ValFormulaChanged(flagAngle2, ui->plainTextEditAngle2F, timerAngle2);
ValFormulaChanged(flagAngle2, ui->plainTextEditAngle2F, timerAngle2, degreeSymbol);
}
//---------------------------------------------------------------------------------------------------------------------
@ -249,7 +249,8 @@ void DialogSpline::Length1Changed()
{
labelEditFormula = ui->labelEditLength1;
labelResultCalculation = ui->labelResultLength1;
ValFormulaChanged(flagLength1, ui->plainTextEditLength1F, timerLength1);
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
ValFormulaChanged(flagLength1, ui->plainTextEditLength1F, timerLength1, postfix);
}
//---------------------------------------------------------------------------------------------------------------------
@ -257,7 +258,8 @@ void DialogSpline::Length2Changed()
{
labelEditFormula = ui->labelEditLength2;
labelResultCalculation = ui->labelResultLength2;
ValFormulaChanged(flagLength2, ui->plainTextEditLength2F, timerLength2);
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
ValFormulaChanged(flagLength2, ui->plainTextEditLength2F, timerLength2, postfix);
}
//---------------------------------------------------------------------------------------------------------------------
@ -265,8 +267,8 @@ void DialogSpline::FXAngle1()
{
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit first control point angle"));
QString angle1F = qApp->TrVars()->FormulaFromUser(ui->plainTextEditAngle1F->toPlainText(),
qApp->Settings()->GetOsSeparator());
QString angle1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle1F->toPlainText(),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(angle1F);
dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
@ -288,8 +290,8 @@ void DialogSpline::FXAngle2()
{
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit second control point angle"));
QString angle2F = qApp->TrVars()->FormulaFromUser(ui->plainTextEditAngle2F->toPlainText(),
qApp->Settings()->GetOsSeparator());
QString angle2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle2F->toPlainText(),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(angle2F);
dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
@ -311,8 +313,8 @@ void DialogSpline::FXLength1()
{
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit first control point length"));
QString length1F = qApp->TrVars()->FormulaFromUser(ui->plainTextEditLength1F->toPlainText(),
qApp->Settings()->GetOsSeparator());
QString length1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength1F->toPlainText(),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(length1F);
dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
@ -334,8 +336,8 @@ void DialogSpline::FXLength2()
{
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit second control point length"));
QString length2F = qApp->TrVars()->FormulaFromUser(ui->plainTextEditLength2F->toPlainText(),
qApp->Settings()->GetOsSeparator());
QString length2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength2F->toPlainText(),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(length2F);
dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
@ -438,10 +440,10 @@ VSpline DialogSpline::CurrentSpline() const
const bool separator = qApp->Settings()->GetOsSeparator();
angle1F = qApp->TrVars()->FormulaFromUser(angle1F, separator);
angle2F = qApp->TrVars()->FormulaFromUser(angle2F, separator);
length1F = qApp->TrVars()->FormulaFromUser(length1F, separator);
length2F = qApp->TrVars()->FormulaFromUser(length2F, separator);
angle1F = qApp->TrVars()->TryFormulaFromUser(angle1F, separator);
angle2F = qApp->TrVars()->TryFormulaFromUser(angle2F, separator);
length1F = qApp->TrVars()->TryFormulaFromUser(length1F, separator);
length2F = qApp->TrVars()->TryFormulaFromUser(length2F, separator);
VSpline spline(*GetP1(), *GetP4(), angle1, angle1F, angle2, angle2F, length1, length1F, length2, length2F);

View File

@ -31,6 +31,10 @@
#include "../vgeometry/vsplinepoint.h"
#include "../vpatterndb/vcontainer.h"
#include "../../visualization/vistoolsplinepath.h"
#include "../support/dialogeditwrongformula.h"
#include "../qmuparser/qmuparsererror.h"
#include <QTimer>
//---------------------------------------------------------------------------------------------------------------------
/**
@ -39,9 +43,33 @@
* @param parent parent widget
*/
DialogSplinePath::DialogSplinePath(const VContainer *data, const quint32 &toolId, QWidget *parent)
:DialogTool(data, toolId, parent), ui(new Ui::DialogSplinePath), path(VSplinePath()), newDuplicate(-1)
: DialogTool(data, toolId, parent),
ui(new Ui::DialogSplinePath),
path(),
newDuplicate(-1),
formulaBaseHeightAngle1(0),
formulaBaseHeightAngle2(0),
formulaBaseHeightLength1(0),
formulaBaseHeightLength2(0),
flagAngle1(),
flagAngle2(),
flagLength1(),
flagLength2()
{
ui->setupUi(this);
plainTextEditFormula = ui->plainTextEditAngle1F;
formulaBaseHeightAngle1 = ui->plainTextEditAngle1F->height();
formulaBaseHeightAngle2 = ui->plainTextEditAngle2F->height();
formulaBaseHeightLength1 = ui->plainTextEditLength1F->height();
formulaBaseHeightLength2 = ui->plainTextEditLength2F->height();
ui->plainTextEditAngle1F->installEventFilter(this);
ui->plainTextEditAngle2F->installEventFilter(this);
ui->plainTextEditLength1F->installEventFilter(this);
ui->plainTextEditLength2F->installEventFilter(this);
InitOkCancelApply(ui);
bOk->setEnabled(false);
@ -51,14 +79,21 @@ DialogSplinePath::DialogSplinePath(const VContainer *data, const quint32 &toolId
connect(ui->listWidget, &QListWidget::currentRowChanged, this, &DialogSplinePath::PointChanged);
connect(ui->comboBoxPoint, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &DialogSplinePath::currentPointChanged);
connect(ui->doubleSpinBoxAngle1, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &DialogSplinePath::Angle1Changed);
connect(ui->doubleSpinBoxAngle2, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &DialogSplinePath::Angle2Changed);
connect(ui->doubleSpinBoxKasm1, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &DialogSplinePath::KAsm1Changed);
connect(ui->doubleSpinBoxKasm2, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &DialogSplinePath::KAsm2Changed);
connect(ui->toolButtonExprAngle1, &QPushButton::clicked, this, &DialogSplinePath::FXAngle1);
connect(ui->toolButtonExprAngle2, &QPushButton::clicked, this, &DialogSplinePath::FXAngle2);
connect(ui->toolButtonExprLength1, &QPushButton::clicked, this, &DialogSplinePath::FXLength1);
connect(ui->toolButtonExprLength2, &QPushButton::clicked, this, &DialogSplinePath::FXLength2);
connect(ui->plainTextEditAngle1F, &QPlainTextEdit::textChanged, this, &DialogSplinePath::Angle1Changed);
connect(ui->plainTextEditAngle2F, &QPlainTextEdit::textChanged, this, &DialogSplinePath::Angle2Changed);
connect(ui->plainTextEditLength1F, &QPlainTextEdit::textChanged, this, &DialogSplinePath::Length1Changed);
connect(ui->plainTextEditLength2F, &QPlainTextEdit::textChanged, this, &DialogSplinePath::Length2Changed);
connect(ui->pushButtonGrowAngle1, &QPushButton::clicked, this, &DialogSplinePath::DeployAngle1TextEdit);
connect(ui->pushButtonGrowAngle2, &QPushButton::clicked, this, &DialogSplinePath::DeployAngle2TextEdit);
connect(ui->pushButtonGrowLength1, &QPushButton::clicked, this, &DialogSplinePath::DeployLength1TextEdit);
connect(ui->pushButtonGrowLength2, &QPushButton::clicked, this, &DialogSplinePath::DeployLength2TextEdit);
vis = new VisToolSplinePath(data);
auto path = qobject_cast<VisToolSplinePath *>(vis);
@ -84,16 +119,19 @@ DialogSplinePath::~DialogSplinePath()
*/
void DialogSplinePath::SetPath(const VSplinePath &value)
{
flagAngle1.clear();
flagAngle2.clear();
flagLength1.clear();
flagLength2.clear();
this->path = value;
ui->listWidget->blockSignals(true);
ui->listWidget->clear();
for (qint32 i = 0; i < path.CountPoint(); ++i)
{
const VSplinePoint &point = path.at(i);
NewItem(point.P().id(), point.KAsm1(), point.Angle1(), point.KAsm2(), point.Angle2());
NewItem(path.at(i));
}
ui->listWidget->setFocus(Qt::OtherFocusReason);
ui->doubleSpinBoxKcurve->setValue(path.GetKCurve());
ui->lineEditSplPathName->setText(path.name());
auto visPath = qobject_cast<VisToolSplinePath *>(vis);
@ -129,7 +167,10 @@ void DialogSplinePath::ChosenObject(quint32 id, const SceneObject &type)
return;
}
NewItem(id, 1, 0, 1, 180);
const auto point = data->GeometricObject<VPointF>(id);
VSplinePoint p;
p.SetP(*point);
NewItem(p);
emit ToolTip(tr("Select point of curve path"));
SavePath();
@ -152,6 +193,9 @@ void DialogSplinePath::ChosenObject(quint32 id, const SceneObject &type)
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief SaveData Put dialog data in local variables
*/
void DialogSplinePath::SaveData()
{
const quint32 d = path.GetDuplicate();//Save previous value
@ -165,6 +209,415 @@ void DialogSplinePath::SaveData()
visPath->RefreshGeometry();
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::CheckState()
{
SCASSERT(bOk != nullptr);
bool fAngle1 = true, fAngle2 = true, fLength1 = true, fLength2 = true;
for (qint32 i = 0; i < ui->listWidget->count(); ++i)
{
fAngle1 = fAngle1 && flagAngle1.at(i);
fAngle2 = fAngle2 && flagAngle2.at(i);
fLength1 = fLength1 && flagLength1.at(i);
fLength2 = fLength2 && flagLength2.at(i);
}
bOk->setEnabled(fAngle1 && fAngle2 && fLength1 && fLength2 && flagError);
// In case dialog hasn't apply button
if (bApply != nullptr)
{
bApply->setEnabled(bOk->isEnabled());
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::closeEvent(QCloseEvent *event)
{
ui->plainTextEditAngle1F->blockSignals(true);
ui->plainTextEditAngle2F->blockSignals(true);
ui->plainTextEditLength1F->blockSignals(true);
ui->plainTextEditLength2F->blockSignals(true);
DialogTool::closeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::DeployAngle1TextEdit()
{
DeployFormula(ui->plainTextEditAngle1F, ui->pushButtonGrowAngle1, formulaBaseHeightAngle1);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::DeployAngle2TextEdit()
{
DeployFormula(ui->plainTextEditAngle2F, ui->pushButtonGrowAngle2, formulaBaseHeightAngle2);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::DeployLength1TextEdit()
{
DeployFormula(ui->plainTextEditLength1F, ui->pushButtonGrowLength1, formulaBaseHeightLength1);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::DeployLength2TextEdit()
{
DeployFormula(ui->plainTextEditLength2F, ui->pushButtonGrowLength2, formulaBaseHeightLength2);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::Angle1Changed()
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
if (row != 0)
{
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
const QString angle1F = ui->plainTextEditAngle1F->toPlainText().replace("\n", " ");
const qreal angle1 = Visualization::FindVal(angle1F, data->PlainVariables());
try
{
p.SetAngle1(angle1, qApp->TrVars()->FormulaFromUser(angle1F, qApp->Settings()->GetOsSeparator()));
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
p.SetAngle1(angle1, angle1F);
}
item->setData(Qt::UserRole, QVariant::fromValue(p));
EvalAngle1();
if (row != ui->listWidget->count()-1)
{
ui->plainTextEditAngle2F->blockSignals(true);
ui->plainTextEditAngle2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle2Formula()));
EvalAngle2();
ui->plainTextEditAngle2F->blockSignals(false);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::Angle2Changed()
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
if (row != ui->listWidget->count()-1)
{
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
const QString angle2F = ui->plainTextEditAngle2F->toPlainText().replace("\n", " ");
const qreal angle2 = Visualization::FindVal(angle2F, data->PlainVariables());
try
{
p.SetAngle2(angle2, qApp->TrVars()->FormulaFromUser(angle2F, qApp->Settings()->GetOsSeparator()));
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
p.SetAngle2(angle2, angle2F);
}
item->setData(Qt::UserRole, QVariant::fromValue(p));
EvalAngle2();
if (row != 0)
{
ui->plainTextEditAngle1F->blockSignals(true);
ui->plainTextEditAngle1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle1Formula()));
EvalAngle1();
ui->plainTextEditAngle1F->blockSignals(false);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::Length1Changed()
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
if (row != 0)
{
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
const QString length1F = ui->plainTextEditLength1F->toPlainText().replace("\n", " ");
const qreal length1 = Visualization::FindLength(length1F, data->PlainVariables());
try
{
p.SetLength1(length1, qApp->TrVars()->FormulaFromUser(length1F, qApp->Settings()->GetOsSeparator()));
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
p.SetLength1(length1, length1F);
}
item->setData(Qt::UserRole, QVariant::fromValue(p));
EvalLength1();
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::Length2Changed()
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
if (row != ui->listWidget->count()-1)
{
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
const QString length2F = ui->plainTextEditLength2F->toPlainText().replace("\n", " ");
const qreal length2 = Visualization::FindLength(length2F, data->PlainVariables());
try
{
p.SetLength2(length2, qApp->TrVars()->FormulaFromUser(length2F, qApp->Settings()->GetOsSeparator()));
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
p.SetLength2(length2, length2F);
}
item->setData(Qt::UserRole, QVariant::fromValue(p));
EvalLength2();
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::FXAngle1()
{
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit first control point angle"));
QString angle1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle1F->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(angle1F);
dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
{
angle1F = qApp->TrVars()->FormulaToUser(dialog->GetFormula());
// increase height if needed.
if (angle1F.length() > 80)
{
DeployAngle1TextEdit();
}
ui->plainTextEditAngle1F->setPlainText(angle1F);
MoveCursorToEnd(ui->plainTextEditAngle1F);
}
delete dialog;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::FXAngle2()
{
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit second control point angle"));
QString angle2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle2F->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(angle2F);
dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
{
angle2F = qApp->TrVars()->FormulaToUser(dialog->GetFormula());
// increase height if needed.
if (angle2F.length() > 80)
{
DeployAngle1TextEdit();
}
ui->plainTextEditAngle2F->setPlainText(angle2F);
MoveCursorToEnd(ui->plainTextEditAngle2F);
}
delete dialog;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::FXLength1()
{
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit first control point length"));
QString length1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength1F->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(length1F);
dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
{
length1F = qApp->TrVars()->FormulaToUser(dialog->GetFormula());
// increase height if needed.
if (length1F.length() > 80)
{
DeployLength1TextEdit();
}
ui->plainTextEditLength1F->setPlainText(length1F);
MoveCursorToEnd(ui->plainTextEditLength1F);
}
delete dialog;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::FXLength2()
{
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit second control point length"));
QString length2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength2F->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(length2F);
dialog->setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
{
length2F = qApp->TrVars()->FormulaToUser(dialog->GetFormula());
// increase height if needed.
if (length2F.length() > 80)
{
DeployLength2TextEdit();
}
ui->plainTextEditLength2F->setPlainText(length2F);
MoveCursorToEnd(ui->plainTextEditLength2F);
}
delete dialog;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::EvalAngle1()
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
labelEditFormula = ui->labelEditAngle1;
Eval(ui->plainTextEditAngle1F->toPlainText(), flagAngle1[row], ui->labelResultAngle1, degreeSymbol, false);
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
ShowPointIssue(p.P().name());
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::EvalAngle2()
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
labelEditFormula = ui->labelEditAngle2;
Eval(ui->plainTextEditAngle2F->toPlainText(), flagAngle2[row], ui->labelResultAngle2, degreeSymbol, false);
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
ShowPointIssue(p.P().name());
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::EvalLength1()
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
labelEditFormula = ui->labelEditLength1;
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
const qreal length1 = Eval(ui->plainTextEditLength1F->toPlainText(), flagLength1[row], ui->labelResultLength1,
postfix);
if (length1 < 0)
{
flagLength1[row] = false;
ChangeColor(labelEditFormula, Qt::red);
ui->labelResultLength1->setText(tr("Error") + " (" + postfix + ")");
ui->labelResultLength1->setToolTip(tr("Length can't be negative"));
CheckState();
}
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
ShowPointIssue(p.P().name());
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::EvalLength2()
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
labelEditFormula = ui->labelEditLength2;
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
const qreal length2 = Eval(ui->plainTextEditLength2F->toPlainText(), flagLength2[row], ui->labelResultLength2,
postfix);
if (length2 < 0)
{
flagLength2[row] = false;
ChangeColor(labelEditFormula, Qt::red);
ui->labelResultLength2->setText(tr("Error") + " (" + postfix + ")");
ui->labelResultLength2->setToolTip(tr("Length can't be negative"));
CheckState();
}
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
ShowPointIssue(p.P().name());
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief PointChanged selected another point in list
@ -176,10 +629,9 @@ void DialogSplinePath::PointChanged(int row)
{
return;
}
QListWidgetItem *item = ui->listWidget->item( row );
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
DataPoint(p.P().id(), p.KAsm1(), p.Angle1(), p.KAsm2(), p.Angle2());
EnableFields();
const auto p = qvariant_cast<VSplinePoint>(ui->listWidget->item(row)->data(Qt::UserRole));
DataPoint(p);
}
//---------------------------------------------------------------------------------------------------------------------
@ -189,16 +641,14 @@ void DialogSplinePath::PointChanged(int row)
*/
void DialogSplinePath::currentPointChanged(int index)
{
quint32 id = qvariant_cast<quint32>(ui->comboBoxPoint->itemData(index));
qint32 row = ui->listWidget->currentRow();
QListWidgetItem *item = ui->listWidget->item( row );
const quint32 id = qvariant_cast<quint32>(ui->comboBoxPoint->itemData(index));
QListWidgetItem *item = ui->listWidget->item( ui->listWidget->currentRow() );
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(id);
const auto point = data->GeometricObject<VPointF>(id);
p.SetP(*point);
DataPoint(p.P().id(), p.KAsm1(), p.Angle1(), p.KAsm2(), p.Angle2());
EnableFields();
DataPoint(p);
item->setData(Qt::UserRole, QVariant::fromValue(p));
item->setText(p.P().name());
ShowPointIssue(p.P().name());
QColor color = okColor;
if (not IsPathValid())
@ -239,66 +689,6 @@ void DialogSplinePath::currentPointChanged(int index)
CheckState();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Angle1Changed changed first angle
* @param index index in list
*/
void DialogSplinePath::Angle1Changed(qreal index)
{
qint32 row = ui->listWidget->currentRow();
QListWidgetItem *item = ui->listWidget->item( row );
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
p.SetAngle1(index);
DataPoint(p.P().id(), p.KAsm1(), p.Angle1(), p.KAsm2(), p.Angle2());
item->setData(Qt::UserRole, QVariant::fromValue(p));
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Angle2Changed changed second angle
* @param index index in list
*/
void DialogSplinePath::Angle2Changed(qreal index)
{
qint32 row = ui->listWidget->currentRow();
QListWidgetItem *item = ui->listWidget->item( row );
SCASSERT(item != nullptr);
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
p.SetAngle2(index);
DataPoint(p.P().id(), p.KAsm1(), p.Angle1(), p.KAsm2(), p.Angle2());
item->setData(Qt::UserRole, QVariant::fromValue(p));
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief KAsm1Changed changed first coefficient asymmetry
* @param d value
*/
void DialogSplinePath::KAsm1Changed(qreal d)
{
qint32 row = ui->listWidget->currentRow();
QListWidgetItem *item = ui->listWidget->item( row );
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
p.SetKAsm1(d);
item->setData(Qt::UserRole, QVariant::fromValue(p));
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief KAsm2Changed changed second coefficient asymmetry
* @param d value
*/
void DialogSplinePath::KAsm2Changed(qreal d)
{
qint32 row = ui->listWidget->currentRow();
QListWidgetItem *item = ui->listWidget->item( row );
VSplinePoint p = qvariant_cast<VSplinePoint>(item->data(Qt::UserRole));
p.SetKAsm2(d);
item->setData(Qt::UserRole, QVariant::fromValue(p));
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::ShowDialog(bool click)
{
@ -333,20 +723,19 @@ void DialogSplinePath::ShowVisualization()
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief NewItem add point to list
* @param id id
* @param kAsm1 first coefficient asymmetry
* @param angle1 first angle in degree
* @param kAsm2 second coefficient asymmetry
* @param angle2 second angle in degree
* @param point spline path point
*/
void DialogSplinePath::NewItem(quint32 id, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2)
void DialogSplinePath::NewItem(const VSplinePoint &point)
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(id);
QListWidgetItem *item = new QListWidgetItem(point->name());
flagAngle1.append(true);
flagLength1.append(true);
flagAngle2.append(true);
flagLength2.append(true);
auto item = new QListWidgetItem(point.P().name());
item->setFont(QFont("Times", 12, QFont::Bold));
VSplinePoint p(*point.data(), kAsm1, angle1, kAsm2, angle2);
DataPoint(point->id(), kAsm1, angle1, kAsm2, angle2);
item->setData(Qt::UserRole, QVariant::fromValue(p));
item->setData(Qt::UserRole, QVariant::fromValue(point));
ui->listWidget->addItem(item);
ui->listWidget->setCurrentItem(item);
if (ui->listWidget->count() >= 2)
@ -354,61 +743,126 @@ void DialogSplinePath::NewItem(quint32 id, qreal kAsm1, qreal angle1, qreal kAsm
bOk = ui->buttonBox->button(QDialogButtonBox::Ok);
bOk->setEnabled(true);
}
EnableFields();
DataPoint(point);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief dataPoint show data of point in fields
* @param id id
* @param kAsm1 first coefficient asymmetry
* @param angle1 first angle of spline
* @param kAsm2 second coefficient asymmetry
* @param angle2 second angle of spline
* @param p spline path point
*/
void DialogSplinePath::DataPoint(quint32 id, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2)
void DialogSplinePath::DataPoint(const VSplinePoint &p)
{
ui->comboBoxPoint->blockSignals(true);
ui->doubleSpinBoxAngle1->blockSignals(true);
ui->doubleSpinBoxAngle2->blockSignals(true);
ui->doubleSpinBoxKasm1->blockSignals(true);
ui->doubleSpinBoxKasm2->blockSignals(true);
ChangeCurrentData(ui->comboBoxPoint, id);
ui->doubleSpinBoxKasm1->setValue(kAsm1);
ui->doubleSpinBoxKasm2->setValue(kAsm2);
ui->doubleSpinBoxAngle2->setValue(angle2);
ui->doubleSpinBoxAngle1->setValue(angle1);
ChangeCurrentData(ui->comboBoxPoint, p.P().id());
ui->comboBoxPoint->blockSignals(false);
ui->doubleSpinBoxAngle1->blockSignals(false);
ui->doubleSpinBoxAngle2->blockSignals(false);
ui->doubleSpinBoxKasm1->blockSignals(false);
ui->doubleSpinBoxKasm2->blockSignals(false);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief EnableFields enable or disable fields
*/
void DialogSplinePath::EnableFields()
{
ui->doubleSpinBoxKasm1->setEnabled(true);
ui->doubleSpinBoxAngle1->setEnabled(true);
ui->doubleSpinBoxKasm2->setEnabled(true);
ui->doubleSpinBoxAngle2->setEnabled(true);
qint32 row = ui->listWidget->currentRow();
int row = ui->listWidget->currentRow();
const QString field = tr("Not used");
const QString emptyRes = QString("_");
if (row == 0)
{
ui->doubleSpinBoxKasm1->setEnabled(false);
ui->doubleSpinBoxAngle1->setEnabled(false);
return;
ui->toolButtonExprAngle1->setEnabled(false);
ui->labelResultAngle1->setText(emptyRes);
ui->labelResultAngle1->setToolTip(tr("Value"));
ChangeColor(ui->labelEditAngle1, okColor);
ui->plainTextEditAngle1F->blockSignals(true);
ui->plainTextEditAngle1F->setPlainText(field);
ui->plainTextEditAngle1F->setEnabled(false);
ui->plainTextEditAngle1F->blockSignals(false);
ui->toolButtonExprLength1->setEnabled(false);
ui->labelResultLength1->setText(emptyRes);
ui->labelResultLength1->setToolTip(tr("Value"));
ChangeColor(ui->labelEditLength1, okColor);
ui->plainTextEditLength1F->blockSignals(true);
ui->plainTextEditLength1F->setPlainText(field);
ui->plainTextEditLength1F->setEnabled(false);
ui->plainTextEditLength1F->blockSignals(false);
ui->plainTextEditAngle2F->setEnabled(true);
ui->plainTextEditLength2F->setEnabled(true);
ui->toolButtonExprAngle2->setEnabled(true);
ui->toolButtonExprLength2->setEnabled(true);
ui->plainTextEditAngle2F->blockSignals(true);
ui->plainTextEditLength2F->blockSignals(true);
ui->plainTextEditAngle2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle2Formula()));
EvalAngle2();
ui->plainTextEditLength2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Length2Formula()));
EvalLength2();
ui->plainTextEditAngle2F->blockSignals(false);
ui->plainTextEditLength2F->blockSignals(false);
}
if (row == ui->listWidget->count()-1)
else if (row == ui->listWidget->count()-1)
{
ui->doubleSpinBoxKasm2->setEnabled(false);
ui->doubleSpinBoxAngle2->setEnabled(false);
return;
ui->toolButtonExprAngle2->setEnabled(false);
ui->labelResultAngle2->setText(emptyRes);
ui->labelResultAngle2->setToolTip(tr("Value"));
ChangeColor(ui->labelEditAngle2, okColor);
ui->plainTextEditAngle2F->blockSignals(true);
ui->plainTextEditAngle2F->setPlainText(field);
ui->plainTextEditAngle2F->setEnabled(false);
ui->plainTextEditAngle2F->blockSignals(false);
ui->toolButtonExprLength2->setEnabled(false);
ui->labelResultLength2->setText(emptyRes);
ui->labelResultLength2->setToolTip(tr("Value"));
ChangeColor(ui->labelEditLength2, okColor);
ui->plainTextEditLength2F->blockSignals(true);
ui->plainTextEditLength2F->setPlainText(field);
ui->plainTextEditLength2F->setEnabled(false);
ui->plainTextEditLength2F->blockSignals(false);
ui->plainTextEditAngle1F->setEnabled(true);
ui->plainTextEditLength1F->setEnabled(true);
ui->toolButtonExprAngle1->setEnabled(true);
ui->toolButtonExprLength1->setEnabled(true);
ui->plainTextEditAngle1F->blockSignals(true);
ui->plainTextEditLength1F->blockSignals(true);
ui->plainTextEditAngle1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle1Formula()));
EvalAngle1();
ui->plainTextEditLength1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Length1Formula()));
EvalLength1();
ui->plainTextEditAngle1F->blockSignals(false);
ui->plainTextEditLength1F->blockSignals(false);
}
else
{
ui->toolButtonExprAngle1->setEnabled(true);
ui->toolButtonExprLength1->setEnabled(true);
ui->toolButtonExprAngle2->setEnabled(true);
ui->toolButtonExprLength2->setEnabled(true);
ui->plainTextEditAngle1F->setEnabled(true);
ui->plainTextEditLength1F->setEnabled(true);
ui->plainTextEditAngle2F->setEnabled(true);
ui->plainTextEditLength2F->setEnabled(true);
ui->plainTextEditAngle1F->blockSignals(true);
ui->plainTextEditLength1F->blockSignals(true);
ui->plainTextEditAngle2F->blockSignals(true);
ui->plainTextEditLength2F->blockSignals(true);
ui->plainTextEditAngle1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle1Formula()));
ui->plainTextEditAngle2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Angle2Formula()));
ui->plainTextEditLength1F->setPlainText(qApp->TrVars()->FormulaToUser(p.Length1Formula()));
ui->plainTextEditLength2F->setPlainText(qApp->TrVars()->FormulaToUser(p.Length2Formula()));
EvalAngle1();
EvalLength1();
EvalAngle2();
EvalLength2();
ui->plainTextEditAngle1F->blockSignals(false);
ui->plainTextEditLength1F->blockSignals(false);
ui->plainTextEditAngle2F->blockSignals(false);
ui->plainTextEditLength2F->blockSignals(false);
}
}
@ -445,10 +899,32 @@ bool DialogSplinePath::IsPathValid() const
//---------------------------------------------------------------------------------------------------------------------
VSplinePath DialogSplinePath::ExtractPath() const
{
VSplinePath path(ui->doubleSpinBoxKcurve->value());
QVector<VSplinePoint> points;
for (qint32 i = 0; i < ui->listWidget->count(); ++i)
{
path.append( qvariant_cast<VSplinePoint>(ui->listWidget->item(i)->data(Qt::UserRole)));
points.append(qvariant_cast<VSplinePoint>(ui->listWidget->item(i)->data(Qt::UserRole)));
}
return VSplinePath(points);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSplinePath::ShowPointIssue(const QString &pName)
{
const int row = ui->listWidget->currentRow();
if (row == -1)
{
return;
}
QListWidgetItem *item = ui->listWidget->item(row);
SCASSERT(item != nullptr);
if (flagAngle1.at(row) && flagAngle2.at(row) && flagLength1.at(row) && flagLength2.at(row))
{
item->setText(pName);
}
else
{
item->setText(pName + QLatin1Literal("(!)"));
}
return path;
}

View File

@ -47,27 +47,38 @@ public:
DialogSplinePath(const VContainer *data, const quint32 &toolId, QWidget *parent = nullptr);
virtual ~DialogSplinePath() Q_DECL_OVERRIDE;
VSplinePath GetPath() const;
void SetPath(const VSplinePath &value);
VSplinePath GetPath() const;
void SetPath(const VSplinePath &value);
QString GetColor() const;
void SetColor(const QString &value);
QString GetColor() const;
void SetColor(const QString &value);
public slots:
virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE;
void PointChanged(int row);
void currentPointChanged( int index );
void Angle1Changed(qreal index );
void Angle2Changed( qreal index );
void KAsm1Changed(qreal d);
void KAsm2Changed(qreal d);
virtual void ShowDialog(bool click) Q_DECL_OVERRIDE;
void PathUpdated(const VSplinePath &path);
virtual void ChosenObject(quint32 id, const SceneObject &type) Q_DECL_OVERRIDE;
virtual void ShowDialog(bool click) Q_DECL_OVERRIDE;
void PathUpdated(const VSplinePath &path);
protected:
virtual void ShowVisualization() Q_DECL_OVERRIDE;
/**
* @brief SaveData Put dialog data in local variables
*/
virtual void SaveData() Q_DECL_OVERRIDE;
virtual void ShowVisualization() Q_DECL_OVERRIDE;
virtual void SaveData() Q_DECL_OVERRIDE;
virtual void CheckState() Q_DECL_OVERRIDE;
virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
private slots:
void PointChanged(int row);
void currentPointChanged(int index);
void DeployAngle1TextEdit();
void DeployAngle2TextEdit();
void DeployLength1TextEdit();
void DeployLength2TextEdit();
void Angle1Changed();
void Angle2Changed();
void Length1Changed();
void Length2Changed();
void FXAngle1();
void FXAngle2();
void FXLength1();
void FXLength2();
private:
Q_DISABLE_COPY(DialogSplinePath)
@ -75,17 +86,34 @@ private:
Ui::DialogSplinePath *ui;
/** @brief path spline path */
VSplinePath path;
VSplinePath path;
qint32 newDuplicate;
qint32 newDuplicate;
void NewItem(quint32 id, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2);
void DataPoint(quint32 id, qreal kAsm1, qreal angle1, qreal kAsm2, qreal angle2);
void EnableFields();
void SavePath();
QSet<quint32> AllIds() const;
bool IsPathValid() const;
VSplinePath ExtractPath() const;
/** @brief formulaBaseHeight base height defined by dialogui */
int formulaBaseHeightAngle1;
int formulaBaseHeightAngle2;
int formulaBaseHeightLength1;
int formulaBaseHeightLength2;
/** @brief flagAngle1 true if value of first angle is correct */
QVector<bool> flagAngle1;
QVector<bool> flagAngle2;
QVector<bool> flagLength1;
QVector<bool> flagLength2;
void EvalAngle1();
void EvalAngle2();
void EvalLength1();
void EvalLength2();
void NewItem(const VSplinePoint &point);
void DataPoint(const VSplinePoint &p);
void SavePath();
QSet<quint32> AllIds() const;
bool IsPathValid() const;
VSplinePath ExtractPath() const;
void ShowPointIssue(const QString &pName);
};
//---------------------------------------------------------------------------------------------------------------------

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>519</width>
<height>401</height>
<width>456</width>
<height>532</height>
</rect>
</property>
<property name="windowTitle">
@ -20,7 +20,7 @@
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
@ -44,46 +44,372 @@
<property name="title">
<string>First control point</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Angle:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxAngle1">
<property name="maximum">
<double>360.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxKasm1">
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Length ratio:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item alignment="Qt::AlignLeft">
<widget class="QLabel" name="labelEditLength1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>159</red>
<green>158</green>
<blue>158</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>Length:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item alignment="Qt::AlignRight">
<widget class="QToolButton" name="toolButtonExprLength1">
<property name="toolTip">
<string>Formula wizard</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset resource="../../../vmisc/share/resources/icon.qrc">
<normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="label_8">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="labelResultLength1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>87</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Value</string>
</property>
<property name="text">
<string notr="true">_</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QPlainTextEdit" name="plainTextEditLength1F">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>28</height>
</size>
</property>
<property name="toolTip">
<string>Calulation</string>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonGrowLength1">
<property name="maximumSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show full calculation in message box&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset theme="go-down">
<normaloff/>
</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item alignment="Qt::AlignLeft">
<widget class="QLabel" name="labelEditAngle1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>159</red>
<green>158</green>
<blue>158</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>Angle:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item alignment="Qt::AlignRight">
<widget class="QToolButton" name="toolButtonExprAngle1">
<property name="toolTip">
<string>Formula wizard</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset resource="../../../vmisc/share/resources/icon.qrc">
<normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="label_9">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="labelResultAngle1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>87</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Value</string>
</property>
<property name="text">
<string notr="true">_</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QPlainTextEdit" name="plainTextEditAngle1F">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>28</height>
</size>
</property>
<property name="toolTip">
<string>Calulation</string>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonGrowAngle1">
<property name="maximumSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show full calculation in message box&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset theme="go-down">
<normaloff/>
</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
@ -93,45 +419,376 @@
<property name="title">
<string>Second control point</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Length ratio:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxKasm2">
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Angle:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxAngle2">
<property name="maximum">
<double>360.000000000000000</double>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item alignment="Qt::AlignLeft">
<widget class="QLabel" name="labelEditLength2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>159</red>
<green>158</green>
<blue>158</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>Length:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item alignment="Qt::AlignRight">
<widget class="QToolButton" name="toolButtonExprLength2">
<property name="toolTip">
<string>Formula wizard</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset resource="../../../vmisc/share/resources/icon.qrc">
<normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="label_10">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="labelResultLength2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>87</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Value</string>
</property>
<property name="text">
<string notr="true">_</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QPlainTextEdit" name="plainTextEditLength2F">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>28</height>
</size>
</property>
<property name="toolTip">
<string>Calulation</string>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonGrowLength2">
<property name="maximumSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show full calculation in message box&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset theme="go-down">
<normaloff/>
</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item alignment="Qt::AlignLeft">
<widget class="QLabel" name="labelEditAngle2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>159</red>
<green>158</green>
<blue>158</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>Angle:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item alignment="Qt::AlignRight">
<widget class="QToolButton" name="toolButtonExprAngle2">
<property name="toolTip">
<string>Formula wizard</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset resource="../../../vmisc/share/resources/icon.qrc">
<normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="label_11">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../vmisc/share/resources/icon.qrc">:/icon/24x24/equal.png</pixmap>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="labelResultAngle2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>87</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Value</string>
</property>
<property name="text">
<string notr="true">_</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QPlainTextEdit" name="plainTextEditAngle2F">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>28</height>
</size>
</property>
<property name="toolTip">
<string>Calulation</string>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonGrowAngle2">
<property name="maximumSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show full calculation in message box&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset theme="go-down">
<normaloff/>
</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
<zorder>layoutWidget_2</zorder>
<zorder>layoutWidget_2</zorder>
</widget>
</item>
</layout>
@ -151,64 +808,23 @@
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Coefficient of curvature of the curve:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxKcurve">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>72</width>
<height>0</height>
</size>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxColor"/>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="labelName">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditSplPathName">
<property name="readOnly">
<bool>true</bool>

View File

@ -332,7 +332,7 @@ quint32 DialogTool::DNumber(const QString &baseName) const
* @param edit LineEdit
* @param timer timer of formula
*/
void DialogTool::ValFormulaChanged(bool &flag, QLineEdit *edit, QTimer *timer)
void DialogTool::ValFormulaChanged(bool &flag, QLineEdit *edit, QTimer *timer, const QString& postfix)
{
SCASSERT(edit != nullptr);
SCASSERT(timer != nullptr);
@ -343,14 +343,21 @@ void DialogTool::ValFormulaChanged(bool &flag, QLineEdit *edit, QTimer *timer)
flag = false;
CheckState();
ChangeColor(labelEditFormula, Qt::red);
labelResultCalculation->setText(tr("Error"));
if (postfix.isEmpty())
{
labelResultCalculation->setText(tr("Error"));
}
else
{
labelResultCalculation->setText(tr("Error") + " (" + postfix + ")");
}
labelResultCalculation->setToolTip(tr("Empty field"));
return;
}
timer->start(1000);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogTool::ValFormulaChanged(bool &flag, QPlainTextEdit *edit, QTimer *timer)
void DialogTool::ValFormulaChanged(bool &flag, QPlainTextEdit *edit, QTimer *timer, const QString& postfix)
{
SCASSERT(edit != nullptr);
SCASSERT(timer != nullptr);
@ -361,7 +368,15 @@ void DialogTool::ValFormulaChanged(bool &flag, QPlainTextEdit *edit, QTimer *tim
flag = false;
CheckState();
ChangeColor(labelEditFormula, Qt::red);
labelResultCalculation->setText(tr("Error"));
if (postfix.isEmpty())
{
labelResultCalculation->setText(tr("Error"));
}
else
{
labelResultCalculation->setText(tr("Error") + " (" + postfix + ")");
}
labelResultCalculation->setToolTip(tr("Empty field"));
return;
}

View File

@ -202,8 +202,9 @@ protected:
virtual void CheckState();
QString GetComboBoxCurrentData(const QComboBox *box)const;
void ChangeCurrentData(QComboBox *box, const QVariant &value) const;
void ValFormulaChanged(bool &flag, QLineEdit *edit, QTimer * timer);
void ValFormulaChanged(bool &flag, QPlainTextEdit *edit, QTimer * timer);
void ValFormulaChanged(bool &flag, QLineEdit *edit, QTimer * timer, const QString &postfix = QString());
void ValFormulaChanged(bool &flag, QPlainTextEdit *edit, QTimer * timer,
const QString &postfix = QString());
qreal Eval(const QString &text, bool &flag, QLabel *label, const QString &postfix,
bool checkZero = true);

View File

@ -28,6 +28,7 @@
#include "vabstractspline.h"
#include "../vwidgets/vcontrolpointspline.h"
#include "../qmuparser/qmutokenparser.h"
#include <QKeyEvent>
@ -242,6 +243,66 @@ void VAbstractSpline::SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &ob
doc->SetAttribute(tag, AttrColor, lineColor);
}
//---------------------------------------------------------------------------------------------------------------------
VSpline VAbstractSpline::CorrectedSpline(const VSpline &spline, const SplinePointPosition &position,
const QPointF &pos) const
{
VSpline spl;
if (position == SplinePointPosition::FirstPoint)
{
QLineF line(spline.GetP1().toQPointF(), pos);
qreal newAngle1 = line.angle();
QString newAngle1F = QString().setNum(newAngle1);
qreal newLength1 = line.length();
QString newLength1F = QString().setNum(qApp->fromPixel(newLength1));
if (not qmu::QmuTokenParser::IsSingle(spline.GetStartAngleFormula()))
{
newAngle1 = spline.GetStartAngle();
newAngle1F = spline.GetStartAngleFormula();
}
if (not qmu::QmuTokenParser::IsSingle(spline.GetC1LengthFormula()))
{
newLength1 = spline.GetC1Length();
newLength1F = spline.GetC1LengthFormula();
}
spl = VSpline(spline.GetP1(), spline.GetP4(), newAngle1, newAngle1F, spline.GetEndAngle(),
spline.GetEndAngleFormula(), newLength1, newLength1F, spline.GetC2Length(),
spline.GetC2LengthFormula());
}
else
{
QLineF line(spline.GetP4().toQPointF(), pos);
qreal newAngle2 = line.angle();
QString newAngle2F = QString().setNum(newAngle2);
qreal newLength2 = line.length();
QString newLength2F = QString().setNum(qApp->fromPixel(newLength2));
if (not qmu::QmuTokenParser::IsSingle(spline.GetEndAngleFormula()))
{
newAngle2 = spline.GetEndAngle();
newAngle2F = spline.GetEndAngleFormula();
}
if (not qmu::QmuTokenParser::IsSingle(spline.GetC2LengthFormula()))
{
newLength2 = spline.GetC2Length();
newLength2F = spline.GetC2LengthFormula();
}
spl = VSpline(spline.GetP1(), spline.GetP4(), spline.GetStartAngle(), spline.GetStartAngleFormula(),
newAngle2, newAngle2F, spline.GetC1Length(), spline.GetC1LengthFormula(),
newLength2, newLength2F);
}
return spl;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractSpline::ShowHandles(bool show)
{

View File

@ -34,6 +34,7 @@
#include <QGraphicsPathItem>
class VControlPointSpline;
class VSpline;
class VAbstractSpline:public VDrawTool, public QGraphicsPathItem
{
@ -87,6 +88,8 @@ protected:
virtual void ReadToolAttributes(const QDomElement &domElement) Q_DECL_OVERRIDE;
virtual void SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &obj) Q_DECL_OVERRIDE;
VSpline CorrectedSpline(const VSpline &spline, const SplinePointPosition &position, const QPointF &pos) const;
template <typename T>
void ShowToolVisualization(bool show);

View File

@ -200,11 +200,11 @@ VToolSpline *VToolSpline::Create(const quint32 _id, quint32 point1, quint32 poin
VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data,
const Document &parse, const Source &typeCreation)
{
qreal calcAngle1 = CheckFormula(_id, a1, data);
qreal calcAngle2 = CheckFormula(_id, a2, data);
const qreal calcAngle1 = CheckFormula(_id, a1, data);
const qreal calcAngle2 = CheckFormula(_id, a2, data);
qreal calcLength1 = qApp->toPixel(CheckFormula(_id, l1, data));
qreal calcLength2 = qApp->toPixel(CheckFormula(_id, l2, data));
const qreal calcLength1 = qApp->toPixel(CheckFormula(_id, l1, data));
const qreal calcLength2 = qApp->toPixel(CheckFormula(_id, l2, data));
auto p1 = data->GeometricObject<VPointF>(point1);
auto p4 = data->GeometricObject<VPointF>(point4);
@ -252,58 +252,7 @@ void VToolSpline::ControlPointChangePosition(const qint32 &indexSpline, const Sp
{
Q_UNUSED(indexSpline);
const QSharedPointer<VSpline> spline = VAbstractTool::data.GeometricObject<VSpline>(id);
VSpline spl;
if (position == SplinePointPosition::FirstPoint)
{
QLineF line(spline->GetP1().toQPointF(), pos);
qreal newAngle1 = line.angle();
QString newAngle1F = QString().setNum(newAngle1);
qreal newLength1 = line.length();
QString newLength1F = QString().setNum(qApp->fromPixel(newLength1));
if (not qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()))
{
newAngle1 = spline->GetStartAngle();
newAngle1F = spline->GetStartAngleFormula();
}
if (not qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()))
{
newLength1 = spline->GetC1Length();
newLength1F = spline->GetC1LengthFormula();
}
spl = VSpline(spline->GetP1(), spline->GetP4(), newAngle1, newAngle1F, spline->GetEndAngle(),
spline->GetEndAngleFormula(), newLength1, newLength1F, spline->GetC2Length(),
spline->GetC2LengthFormula());
}
else
{
QLineF line(spline->GetP4().toQPointF(), pos);
qreal newAngle2 = line.angle();
QString newAngle2F = QString().setNum(newAngle2);
qreal newLength2 = line.length();
QString newLength2F = QString().setNum(qApp->fromPixel(newLength2));
if (not qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()))
{
newAngle2 = spline->GetEndAngle();
newAngle2F = spline->GetEndAngleFormula();
}
if (not qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
{
newLength2 = spline->GetC2Length();
newLength2F = spline->GetC2LengthFormula();
}
spl = VSpline(spline->GetP1(), spline->GetP4(), spline->GetStartAngle(), spline->GetStartAngleFormula(),
newAngle2, newAngle2F, spline->GetC1Length(), spline->GetC1LengthFormula(),
newLength2, newLength2F);
}
const VSpline spl = CorrectedSpline(*spline, position, pos);
MoveSpline *moveSpl = new MoveSpline(doc, spline.data(), spl, id, this->scene());
connect(moveSpl, &MoveSpline::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
@ -387,12 +336,7 @@ void VToolSpline::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
oldPosition = event->scenePos();
@ -410,12 +354,7 @@ void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
@ -428,12 +367,7 @@ void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
//---------------------------------------------------------------------------------------------------------------------
void VToolSpline::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
// Don't need check if left mouse button was pressed. According to the Qt documentation "If you do receive this
// event, you can be certain that this item also received a mouse press event, and that this item is the current
@ -443,6 +377,7 @@ void VToolSpline::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
// "weight" describes how the influence of the drag should be distributed
// among the handles; 0 = front handle only, 1 = back handle only.
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
const qreal t = spline->ParamT(oldPosition);
if (qFloor(t) == -1)
@ -511,12 +446,7 @@ void VToolSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
}
@ -530,12 +460,7 @@ void VToolSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
if (IsMovable())
{
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
@ -566,6 +491,17 @@ void VToolSpline::SetVisualization()
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VToolSpline::IsMovable() const
{
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
return qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula());
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief RefreshGeometry refresh item on scene.

View File

@ -80,6 +80,7 @@ private:
Q_DISABLE_COPY(VToolSpline)
QPointF oldPosition;
bool IsMovable() const;
void RefreshGeometry ();
void SetSplineAttributes(QDomElement &domElement, const VSpline &spl);
};

View File

@ -31,6 +31,7 @@
#include "../../../undocommands/movesplinepath.h"
#include "../../../visualization/vistoolsplinepath.h"
#include "../vwidgets/vcontrolpointspline.h"
#include "../qmuparser/qmutokenparser.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
# include "../vmisc/vmath.h"
@ -38,7 +39,8 @@
# include <QtMath>
#endif
const QString VToolSplinePath::ToolType = QStringLiteral("path");
const QString VToolSplinePath::ToolType = QStringLiteral("pathInteractive");
const QString VToolSplinePath::OldToolType = QStringLiteral("path");
//---------------------------------------------------------------------------------------------------------------------
/**
@ -51,7 +53,9 @@ const QString VToolSplinePath::ToolType = QStringLiteral("path");
*/
VToolSplinePath::VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint32 id, const QString &color,
const Source &typeCreation, QGraphicsItem *parent)
:VAbstractSpline(doc, data, id, parent), oldPosition()
: VAbstractSpline(doc, data, id, parent),
oldPosition(),
splIndex(-1)
{
sceneType = SceneObject::SplinePath;
lineColor = color;
@ -66,17 +70,25 @@ VToolSplinePath::VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint3
const QSharedPointer<VSplinePath> splPath = data->GeometricObject<VSplinePath>(id);
for (qint32 i = 1; i<=splPath->Count(); ++i)
{
VSpline spl = splPath->GetSpline(i);
const VSpline spl = splPath->GetSpline(i);
const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula());
const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl.GetC1LengthFormula());
auto *controlPoint = new VControlPointSpline(i, SplinePointPosition::FirstPoint, spl.GetP2(),
spl.GetP1().toQPointF(), *data->GetPatternUnit(), true, true, this);
spl.GetP1().toQPointF(), *data->GetPatternUnit(), freeAngle1,
freeLength1, this);
connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSplinePath::ControlPointChangePosition);
connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint);
connect(controlPoint, &VControlPointSpline::ShowContextMenu, this, &VToolSplinePath::contextMenuEvent);
controlPoints.append(controlPoint);
const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula());
const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl.GetC2LengthFormula());
controlPoint = new VControlPointSpline(i, SplinePointPosition::LastPoint, spl.GetP3(), spl.GetP4().toQPointF(),
*data->GetPatternUnit(), true, true, this);
*data->GetPatternUnit(), freeAngle2, freeLength2, this);
connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSplinePath::ControlPointChangePosition);
connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint);
@ -184,6 +196,31 @@ VToolSplinePath* VToolSplinePath::Create(const quint32 _id, VSplinePath *path, c
return nullptr;
}
//---------------------------------------------------------------------------------------------------------------------
VToolSplinePath *VToolSplinePath::Create(const quint32 _id, const QVector<quint32> &points, QVector<QString> &a1,
QVector<QString> &a2, QVector<QString> &l1, QVector<QString> &l2,
const QString &color, VMainGraphicsScene *scene, VAbstractPattern *doc,
VContainer *data, const Document &parse, const Source &typeCreation)
{
auto path = new VSplinePath();
for (int i = 0; i < points.size(); ++i)
{
const qreal calcAngle1 = CheckFormula(_id, a1[i], data);
const qreal calcAngle2 = CheckFormula(_id, a2[i], data);
const qreal calcLength1 = qApp->toPixel(CheckFormula(_id, l1[i], data));
const qreal calcLength2 = qApp->toPixel(CheckFormula(_id, l2[i], data));
const auto p = *data->GeometricObject<VPointF>(points.at(i));
path->append(VSplinePoint(p, calcAngle1, a1.at(i), calcAngle2, a2.at(i), calcLength1, l1.at(i), calcLength2,
l2.at(i)));
}
return VToolSplinePath::Create(_id, path, color, scene, doc, data, parse, typeCreation);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief ControlPointChangePosition handle change position control point.
@ -194,18 +231,9 @@ VToolSplinePath* VToolSplinePath::Create(const quint32 _id, VSplinePath *path, c
void VToolSplinePath::ControlPointChangePosition(const qint32 &indexSpline, const SplinePointPosition &position,
const QPointF &pos)
{
VSplinePath oldSplPath = *VAbstractTool::data.GeometricObject<VSplinePath>(id);
const VSplinePath oldSplPath = *VAbstractTool::data.GeometricObject<VSplinePath>(id);
VSplinePath newSplPath = oldSplPath;
VSpline spl = newSplPath.GetSpline(indexSpline);
if (position == SplinePointPosition::FirstPoint)
{
spl = VSpline(spl.GetP1(), pos, spl.GetP3(), spl.GetP4());
}
else
{
spl = VSpline(spl.GetP1(), spl.GetP2(), pos, spl.GetP4());
}
const VSpline spl = CorrectedSpline(newSplPath.GetSpline(indexSpline), position, pos);
UpdateControlPoints(spl, newSplPath, indexSpline);
MoveSplinePath *moveSplPath = new MoveSplinePath(doc, oldSplPath, newSplPath, id, this->scene());
@ -229,56 +257,51 @@ void VToolSplinePath::EnableToolMove(bool move)
void VToolSplinePath::UpdateControlPoints(const VSpline &spl, VSplinePath &splPath, const qint32 &indexSpline) const
{
VSplinePoint p = splPath.GetSplinePoint(indexSpline, SplinePointPosition::FirstPoint);
p.SetAngle2(spl.GetStartAngle());
p.SetKAsm2(spl.GetKasm1());
p.SetAngle2(spl.GetStartAngle(), spl.GetStartAngleFormula());
p.SetLength2(spl.GetC1Length(), spl.GetC1LengthFormula());
splPath.UpdatePoint(indexSpline, SplinePointPosition::FirstPoint, p);
p = splPath.GetSplinePoint(indexSpline, SplinePointPosition::LastPoint);
p.SetAngle2(spl.GetEndAngle()-180);
p.SetKAsm1(spl.GetKasm2());
p.SetAngle1(spl.GetEndAngle(), spl.GetEndAngleFormula());
p.SetLength1(spl.GetC2Length(), spl.GetC2LengthFormula());
splPath.UpdatePoint(indexSpline, SplinePointPosition::LastPoint, p);
}
//---------------------------------------------------------------------------------------------------------------------
void VToolSplinePath::RefreshSplinePath(VSplinePath &splPath)
void VToolSplinePath::SetSplinePathAttributes(QDomElement &domElement, const VSplinePath &path)
{
for (qint32 i = 1; i<=splPath.Count(); ++i)
doc->SetAttribute(domElement, AttrType, ToolType);
if (path.GetDuplicate() > 0)
{
VSpline spl = splPath.GetSpline(i);
qint32 j = i*2;
controlPoints[j-2]->blockSignals(true);
controlPoints[j-1]->blockSignals(true);
controlPoints[j-2]->setPos(spl.GetP2());
controlPoints[j-1]->setPos(spl.GetP3());
controlPoints[j-2]->blockSignals(false);
controlPoints[j-1]->blockSignals(false);
spl = VSpline (spl.GetP1(), controlPoints[j-2]->pos(), controlPoints[j-1]->pos(), spl.GetP4());
UpdateControlPoints(spl, splPath, i);
doc->SetAttribute(domElement, AttrDuplicate, path.GetDuplicate());
}
else
{
if (domElement.hasAttribute(AttrDuplicate))
{
domElement.removeAttribute(AttrDuplicate);
}
}
if (domElement.hasAttribute(AttrKCurve))
{
domElement.removeAttribute(AttrKCurve);
}
UpdatePathPoints(doc, domElement, path);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief UpdatePathPoint update spline path in pattern file.
* @brief UpdatePathPoints update spline path in pattern file.
* @param doc dom document container.
* @param node tag in file.
* @param path spline path.
*/
void VToolSplinePath::UpdatePathPoint(VAbstractPattern *doc, QDomNode& node, const VSplinePath &path)
void VToolSplinePath::UpdatePathPoints(VAbstractPattern *doc, QDomElement &element, const VSplinePath &path)
{
SCASSERT(doc != nullptr);
QDomElement element = node.toElement();
if (element.isElement() == false)
{
qDebug()<<"Couldn't convert parent to element.";
return;
}
doc->removeAllChilds(element);
VDomDocument::RemoveAllChildren(element);
for (qint32 i = 0; i < path.CountPoint(); ++i)
{
AddPathPoint(doc, element, path.at(i));
@ -325,24 +348,6 @@ void VToolSplinePath::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
}
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief RefreshDataInFile refresh attributes in file. If attributes don't exist create them.
*/
void VToolSplinePath::RefreshDataInFile()
{
QDomElement domElement = doc->elementById(id);
if (domElement.isElement() == false)
{
qDebug()<<"Can't find element with id="<<id<<"in pattern file";
return;
}
VSplinePath splPath = *VAbstractTool::data.GeometricObject<VSplinePath>(id);
RefreshSplinePath(splPath);
doc->SetAttribute(domElement, AttrKCurve, QString().setNum(splPath.GetKCurve()));
UpdatePathPoint(doc, domElement, splPath);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief AddPathPoint write path point to pattern file.
@ -355,9 +360,25 @@ void VToolSplinePath::AddPathPoint(VAbstractPattern *doc, QDomElement &domElemen
QDomElement pathPoint = doc->createElement(AttrPathPoint);
doc->SetAttribute(pathPoint, AttrPSpline, splPoint.P().id());
doc->SetAttribute(pathPoint, AttrKAsm1, splPoint.KAsm1());
doc->SetAttribute(pathPoint, AttrKAsm2, splPoint.KAsm2());
doc->SetAttribute(pathPoint, AttrAngle, splPoint.Angle2());
doc->SetAttribute(pathPoint, AttrLength1, splPoint.Length1Formula());
doc->SetAttribute(pathPoint, AttrLength2, splPoint.Length2Formula());
doc->SetAttribute(pathPoint, AttrAngle1, splPoint.Angle1Formula());
doc->SetAttribute(pathPoint, AttrAngle2, splPoint.Angle2Formula());
if (domElement.hasAttribute(AttrKAsm1))
{
domElement.removeAttribute(AttrKAsm1);
}
if (domElement.hasAttribute(AttrKAsm2))
{
domElement.removeAttribute(AttrKAsm2);
}
if (domElement.hasAttribute(AttrAngle))
{
domElement.removeAttribute(AttrAngle);
}
domElement.appendChild(pathPoint);
}
@ -385,11 +406,24 @@ void VToolSplinePath::SaveDialog(QDomElement &domElement)
DialogSplinePath *dialogTool = qobject_cast<DialogSplinePath*>(dialog);
SCASSERT(dialogTool != nullptr);
VSplinePath splPath = dialogTool->GetPath();
RefreshSplinePath(splPath);
doc->SetAttribute(domElement, AttrKCurve, QString().setNum(splPath.GetKCurve()));
const VSplinePath splPath = dialogTool->GetPath();
for (qint32 i = 1; i <= splPath.Count(); ++i)
{
VSpline spl = splPath.GetSpline(i);
qint32 j = i*2;
controlPoints[j-2]->blockSignals(true);
controlPoints[j-1]->blockSignals(true);
controlPoints[j-2]->setPos(spl.GetP2());
controlPoints[j-1]->setPos(spl.GetP3());
controlPoints[j-2]->blockSignals(false);
controlPoints[j-1]->blockSignals(false);
}
doc->SetAttribute(domElement, AttrColor, dialogTool->GetColor());
UpdatePathPoint(doc, domElement, splPath);
SetSplinePathAttributes(domElement, splPath);
}
//---------------------------------------------------------------------------------------------------------------------
@ -400,26 +434,7 @@ void VToolSplinePath::SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &ob
QSharedPointer<VSplinePath> splPath = qSharedPointerDynamicCast<VSplinePath>(obj);
SCASSERT(splPath.isNull() == false);
doc->SetAttribute(tag, AttrType, ToolType);
doc->SetAttribute(tag, AttrKCurve, splPath->GetKCurve());
if (splPath->GetDuplicate() > 0)
{
doc->SetAttribute(tag, AttrDuplicate, splPath->GetDuplicate());
}
else
{
if (tag.hasAttribute(AttrDuplicate))
{
tag.removeAttribute(AttrDuplicate);
}
}
doc->RemoveAllChild(tag);
for (qint32 i = 0; i < splPath->CountPoint(); ++i)
{
AddPathPoint(doc, tag, splPath->at(i));
}
SetSplinePathAttributes(tag, *splPath);
}
//---------------------------------------------------------------------------------------------------------------------
@ -429,9 +444,14 @@ void VToolSplinePath::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
oldPosition = event->scenePos();
event->accept();
const auto splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
splIndex = splPath->Segment(oldPosition);
if (IsMovable(splIndex))
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
event->accept();
}
}
}
VAbstractSpline::mousePressEvent(event);
@ -444,6 +464,7 @@ void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
oldPosition = event->scenePos();
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
}
@ -454,84 +475,82 @@ void VToolSplinePath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
//---------------------------------------------------------------------------------------------------------------------
void VToolSplinePath::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
// Don't need check if left mouse button was pressed. According to the Qt documentation "If you do receive this
// Don't need to check if left mouse button was pressed. According to the Qt documentation "If you do receive this
// event, you can be certain that this item also received a mouse press event, and that this item is the current
// mouse grabber.".
VSplinePath oldSplPath = *VAbstractTool::data.GeometricObject<VSplinePath>(id);
VSplinePath newSplPath = oldSplPath;
int indexSpline = oldSplPath.Segment(oldPosition);
if (indexSpline == -1)
if (IsMovable(splIndex))
{
return;
}
VSplinePath oldSplPath = *VAbstractTool::data.GeometricObject<VSplinePath>(id);
VSplinePath newSplPath = oldSplPath;
VSpline spline = newSplPath.GetSpline(indexSpline);
const qreal t = spline.ParamT(oldPosition);
VSpline spline = newSplPath.GetSpline(splIndex);
const qreal t = spline.ParamT(oldPosition);
if (qFloor(t) == -1)
{
return;
}
if (qFloor(t) == -1)
{
return;
}
// Magic Bezier Drag Equations follow!
// "weight" describes how the influence of the drag should be distributed
// among the handles; 0 = front handle only, 1 = back handle only.
// Magic Bezier Drag Equations follow!
// "weight" describes how the influence of the drag should be distributed
// among the handles; 0 = front handle only, 1 = back handle only.
double weight;
if (t <= 1.0 / 6.0)
{
weight = 0;
}
else if (t <= 0.5)
{
weight = (pow((6 * t - 1) / 2.0, 3)) / 2;
}
else if (t <= 5.0 / 6.0)
{
weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
}
else
{
weight = 1;
}
double weight;
if (t <= 1.0 / 6.0)
{
weight = 0;
}
else if (t <= 0.5)
{
weight = (pow((6 * t - 1) / 2.0, 3)) / 2;
}
else if (t <= 5.0 / 6.0)
{
weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
}
else
{
weight = 1;
}
const QPointF delta = event->scenePos() - oldPosition;
const QPointF offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta;
const QPointF offset1 = (weight/(3*t*t*(1-t))) * delta;
const QPointF delta = event->scenePos() - oldPosition;
const QPointF offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta;
const QPointF offset1 = (weight/(3*t*t*(1-t))) * delta;
const QPointF p2 = spline.GetP2() + offset0;
const QPointF p3 = spline.GetP3() + offset1;
const QPointF p2 = spline.GetP2() + offset0;
const QPointF p3 = spline.GetP3() + offset1;
oldPosition = event->scenePos(); // Now mouse here
oldPosition = event->scenePos(); // Now mouse here
const VSpline spl = VSpline(spline.GetP1(), p2, p3, spline.GetP4());
const VSpline spl = VSpline(spline.GetP1(), p2, p3, spline.GetP4());
UpdateControlPoints(spl, newSplPath, indexSpline);
UpdateControlPoints(spl, newSplPath, splIndex);
MoveSplinePath *moveSplPath = new MoveSplinePath(doc, oldSplPath, newSplPath, id, this->scene());
connect(moveSplPath, &VUndoCommand::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
qApp->getUndoStack()->push(moveSplPath);
MoveSplinePath *moveSplPath = new MoveSplinePath(doc, oldSplPath, newSplPath, id, this->scene());
connect(moveSplPath, &VUndoCommand::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
qApp->getUndoStack()->push(moveSplPath);
// Each time we move something we call recalculation scene rect. In some cases this can cause moving
// objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
static bool changeFinished = true;
if (changeFinished)
{
changeFinished = false;
// Each time we move something we call recalculation scene rect. In some cases this can cause moving
// objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
static bool changeFinished = true;
if (changeFinished)
{
changeFinished = false;
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
{
if (QGraphicsView *view = viewList.at(0))
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
{
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene);
const QPointF cursorPosition = currentScene->getScenePos();
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
if (QGraphicsView *view = viewList.at(0))
{
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene);
const QPointF cursorPosition = currentScene->getScenePos();
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
}
}
}
changeFinished = true;
changeFinished = true;
}
}
}
@ -540,7 +559,13 @@ void VToolSplinePath::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
oldPosition = event->scenePos();
const auto splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
splIndex = splPath->Segment(oldPosition);
if (IsMovable(splIndex))
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
}
}
VAbstractSpline::hoverEnterEvent(event);
@ -551,6 +576,7 @@ void VToolSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
oldPosition = event->scenePos();
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
}
@ -573,6 +599,23 @@ void VToolSplinePath::SetVisualization()
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VToolSplinePath::IsMovable(int index) const
{
const auto splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
//index == -1 - can delete, but decided to left
if (index == -1 || index < 1 || index > splPath->Count())
{
return false;
}
const VSplinePoint p1 = splPath->GetSplinePoint(index, SplinePointPosition::FirstPoint);
const VSplinePoint p2 = splPath->GetSplinePoint(index, SplinePointPosition::LastPoint);
return p1.IsMovable() && p2.IsMovable();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief RefreshGeometry refresh item on scene.
@ -608,13 +651,21 @@ void VToolSplinePath::RefreshGeometry()
const auto spl = splPath->GetSpline(i);
{
const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl.GetStartAngleFormula());
const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl.GetC1LengthFormula());
const auto splinePoint = spl.GetP1().toQPointF();
controlPoints[j-2]->RefreshCtrlPoint(i, SplinePointPosition::FirstPoint, spl.GetP2(), splinePoint);
controlPoints[j-2]->RefreshCtrlPoint(i, SplinePointPosition::FirstPoint, spl.GetP2(), splinePoint,
freeAngle1, freeLength1);
}
{
const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl.GetEndAngleFormula());
const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl.GetC2LengthFormula());
const auto splinePoint = spl.GetP4().toQPointF();
controlPoints[j-1]->RefreshCtrlPoint(i, SplinePointPosition::LastPoint, spl.GetP3(), splinePoint);
controlPoints[j-1]->RefreshCtrlPoint(i, SplinePointPosition::LastPoint, spl.GetP3(), splinePoint,
freeAngle2, freeLength2);
}
controlPoints[j-2]->blockSignals(false);

View File

@ -53,8 +53,14 @@ public:
VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data,
const Document &parse,
const Source &typeCreation);
static VToolSplinePath *Create(const quint32 _id, const QVector<quint32> &points, QVector<QString> &a1,
QVector<QString> &a2, QVector<QString> &l1, QVector<QString> &l2,
const QString &color, VMainGraphicsScene *scene, VAbstractPattern *doc,
VContainer *data, const Document &parse, const Source &typeCreation);
static const QString ToolType;
static void UpdatePathPoint(VAbstractPattern *doc, QDomNode& node, const VSplinePath &path);
static const QString OldToolType;
static void UpdatePathPoints(VAbstractPattern *doc, QDomElement &element, const VSplinePath &path);
virtual int type() const Q_DECL_OVERRIDE {return Type;}
enum { Type = UserType + static_cast<int>(Tool::SplinePath)};
@ -84,7 +90,6 @@ public slots:
virtual void EnableToolMove(bool move) Q_DECL_OVERRIDE;
protected:
virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ) Q_DECL_OVERRIDE;
virtual void RefreshDataInFile() Q_DECL_OVERRIDE;
virtual void RemoveReferens() Q_DECL_OVERRIDE;
virtual void SaveDialog(QDomElement &domElement) Q_DECL_OVERRIDE;
virtual void SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &obj) Q_DECL_OVERRIDE;
@ -96,11 +101,13 @@ protected:
virtual void SetVisualization() Q_DECL_OVERRIDE;
private:
QPointF oldPosition;
int splIndex;
bool IsMovable(int index) const;
void RefreshGeometry();
static void AddPathPoint(VAbstractPattern *doc, QDomElement &domElement, const VSplinePoint &splPoint);
void UpdateControlPoints(const VSpline &spl, VSplinePath &splPath, const qint32 &indexSpline) const;
void RefreshSplinePath(VSplinePath &splPath);
void SetSplinePathAttributes(QDomElement &domElement, const VSplinePath &path);
};
#endif // VTOOLSPLINEPATH_H

View File

@ -160,10 +160,19 @@ VToolCutSplinePath* VToolCutSplinePath::Create(const quint32 _id, const QString
{
if (i == p1)
{
splPath1->append(VSplinePoint(splP1.P(), splP1.KAsm1(), spl1.GetStartAngle()+180, spl1.GetKasm1(),
spl1.GetStartAngle()));
VSplinePoint cutPoint;
cutPoint = VSplinePoint(*p, spl1.GetKasm2(), spl1.GetEndAngle(), spl2.GetKasm1(), spl1.GetEndAngle()+180);
const qreal angle1 = spl1.GetStartAngle()+180;
const QString angle1F = QString().number(angle1);
splPath1->append(VSplinePoint(splP1.P(), angle1, angle1F, spl1.GetStartAngle(),
spl1.GetStartAngleFormula(), splP1.Length1(), splP1.Length1Formula(),
spl1.GetC1Length(), spl1.GetC1LengthFormula()));
const qreal angle2 = spl1.GetEndAngle()+180;
const QString angle2F = QString().number(angle2);
const auto cutPoint = VSplinePoint(*p, spl1.GetEndAngle(), spl1.GetEndAngleFormula(), angle2, angle2F,
spl1.GetC2Length(), spl1.GetC2LengthFormula(), spl2.GetC1Length(),
spl2.GetC1LengthFormula());
splPath1->append(cutPoint);
continue;
}
@ -173,18 +182,27 @@ VToolCutSplinePath* VToolCutSplinePath::Create(const quint32 _id, const QString
{
if (i == p2)
{
const VSplinePoint cutPoint = VSplinePoint(*p, spl1.GetKasm2(), spl2.GetStartAngle()+180,
spl2.GetKasm1(), spl2.GetStartAngle());
const qreal angle1 = spl2.GetStartAngle()+180;
const QString angle1F = QString().number(angle1);
const auto cutPoint = VSplinePoint(*p, angle1, angle1F, spl2.GetStartAngle(),
spl2.GetStartAngleFormula(), spl1.GetC2Length(),
spl1.GetC2LengthFormula(), spl2.GetC1Length(),
spl2.GetC1LengthFormula());
splPath2->append(cutPoint);
splPath2->append(VSplinePoint(splP2.P(), spl2.GetKasm2(), spl2.GetEndAngle(), splP2.KAsm2(),
spl2.GetEndAngle()+180));
const qreal angle2 = spl2.GetEndAngle()+180;
const QString angle2F = QString().number(angle2);
splPath2->append(VSplinePoint(splP2.P(), spl2.GetEndAngle(), spl2.GetEndAngleFormula(), angle2, angle2F,
spl2.GetC2Length(), spl2.GetC2LengthFormula(), splP2.Length2(),
splP2.Length2Formula()));
continue;
}
splPath2->append(splPath->at(i));
}
}
splPath1->SetKCurve(splPath->GetKCurve());
splPath2->SetKCurve(splPath->GetKCurve());
if (typeCreation == Source::FromGui)
{

View File

@ -330,7 +330,7 @@ void VToolDetail::RefreshDataInFile()
doc->SetAttribute(domElement, AttrSupplement, QString().setNum(static_cast<quint8>(det.getSeamAllowance())));
doc->SetAttribute(domElement, AttrClosed, QString().setNum(static_cast<quint8>(det.getClosed())));
doc->SetAttribute(domElement, AttrWidth, QString().setNum(det.getWidth()));
doc->RemoveAllChild(domElement);
doc->RemoveAllChildren(domElement);
for (int i = 0; i < det.CountNode(); ++i)
{
AddNode(doc, domElement, det.at(i));

View File

@ -220,9 +220,9 @@ void VToolUnionDetails::AddToNewDetail(VMainGraphicsScene *scene, VAbstractPatte
{
const VSplinePoint &point1 = splinePath->at(i-1);
const VSplinePoint &point2 = splinePath->at(i);
VSpline spline(point1.P(), point2.P(),
point1.Angle2(), point2.Angle1(), point1.KAsm2(),
point2.KAsm1(), splinePath->GetKCurve());
VSpline spline(point1.P(), point2.P(), point1.Angle2(), point1.Angle2Formula(), point2.Angle1(),
point2.Angle1Formula(), point1.Length2(), point1.Length2Formula(), point2.Length1(),
point2.Length1Formula());
const QPointF p = data->GeometricObject<VPointF>(pRotate)->toQPointF();
VPointF *p1 = new VPointF(spline.GetP1());
@ -240,11 +240,21 @@ void VToolUnionDetails::AddToNewDetail(VMainGraphicsScene *scene, VAbstractPatte
VSpline spl = VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4);
if (i==1)
{
path->append(VSplinePoint(*p1, point1.KAsm1(), spl.GetStartAngle()+180,
point1.KAsm2(), spl.GetStartAngle()));
const qreal angle1 = spl.GetStartAngle()+180;
const QString angle1F = QString().number(angle1);
path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(),
point1.Length1(), point1.Length1Formula(), point1.Length2(),
point1.Length2Formula()));
}
path->append(VSplinePoint(*p4, point2.KAsm1(), spl.GetEndAngle(),
point2.KAsm2(), spl.GetEndAngle()+180));
const qreal angle2 = spl.GetEndAngle()+180;
const QString angle2F = QString().number(angle2);
path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F,
point2.Length1(), point2.Length1Formula(), point2.Length2(),
point2.Length2Formula()));
delete p4;
delete p1;
}
@ -360,9 +370,10 @@ void VToolUnionDetails::UpdatePoints(VContainer *data, const VDetail &det, const
{
const VSplinePoint &point1 = splinePath->at(i-1);
const VSplinePoint &point2 = splinePath->at(i);
VSpline spline(point1.P(), point2.P(),
point1.Angle2(), point2.Angle1(), point1.KAsm2(),
point2.KAsm1(), splinePath->GetKCurve());
VSpline spline(point1.P(), point2.P(), point1.Angle2(), point1.Angle2Formula(), point2.Angle1(),
point2.Angle1Formula(), point1.Length2(), point1.Length2Formula(), point2.Length1(),
point2.Length1Formula());
const QPointF p = data->GeometricObject<VPointF>(pRotate)->toQPointF();
VPointF *p1 = new VPointF(spline.GetP1());
@ -380,11 +391,21 @@ void VToolUnionDetails::UpdatePoints(VContainer *data, const VDetail &det, const
VSpline spl = VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4);
if (i==1)
{
path->append(VSplinePoint(*p1, point1.KAsm1(), spl.GetStartAngle()+180,
point1.KAsm2(), spl.GetStartAngle()));
const qreal angle1 = spl.GetStartAngle()+180;
const QString angle1F = QString().number(angle1);
path->append(VSplinePoint(*p1, angle1, angle1F, spl.GetStartAngle(), spl.GetStartAngleFormula(),
point1.Length1(), point1.Length1Formula(), point1.Length2(),
point1.Length2Formula()));
}
path->append(VSplinePoint(*p4, point2.KAsm1(), spl.GetEndAngle(),
point2.KAsm2(), spl.GetEndAngle()+180));
const qreal angle2 = spl.GetEndAngle()+180;
const QString angle2F = QString().number(angle2);
path->append(VSplinePoint(*p4, spl.GetEndAngle(), spl.GetEndAngleFormula(), angle2, angle2F,
point2.Length1(), point2.Length1Formula(), point2.Length2(),
point2.Length2Formula()));
delete p1;
delete p4;
}
@ -847,7 +868,7 @@ QDomNode VToolUnionDetails::UpdateDetail(const QDomNode &domNode, const VDetail
{
if (domElement.tagName() == VToolUnionDetails::TagDetail)
{
doc->removeAllChilds(domElement);//delete all nodes in detail
VDomDocument::RemoveAllChildren(domElement);//delete all nodes in detail
for (int i = 0; i < d.CountNode(); ++i)
{
AddNode(domElement, d.at(i));//rewrite nodes of detail

View File

@ -89,8 +89,7 @@ void MoveSplinePath::Do(const VSplinePath &splPath)
QDomElement domElement = doc->elementById(nodeId);
if (domElement.isElement())
{
doc->SetAttribute(domElement, AttrKCurve, QString().setNum(splPath.GetKCurve()));
VToolSplinePath::UpdatePathPoint(doc, domElement, splPath);
VToolSplinePath::UpdatePathPoints(doc, domElement, splPath);
emit NeedLiteParsing(Document::LiteParse);
}

View File

@ -54,7 +54,7 @@ void SaveDetailOptions::undo()
if (domElement.isElement())
{
SaveDet(domElement, oldDet);
doc->RemoveAllChild(domElement);
doc->RemoveAllChildren(domElement);
for (int i = 0; i < oldDet.CountNode(); ++i)
{
VToolDetail::AddNode(doc, domElement, oldDet.at(i));
@ -85,7 +85,7 @@ void SaveDetailOptions::redo()
if (domElement.isElement())
{
SaveDet(domElement, newDet);
doc->RemoveAllChild(domElement);
doc->RemoveAllChildren(domElement);
for (int i = 0; i < newDet.CountNode(); ++i)
{
VToolDetail::AddNode(doc, domElement, newDet.at(i));

View File

@ -79,11 +79,21 @@ void VisToolCutSplinePath::RefreshGeometry()
{
if (i == p1)
{
spPath1.append(VSplinePoint(splP1.P(), splP1.KAsm1(), spl1.GetStartAngle()+180, spl1.GetKasm1(),
spl1.GetStartAngle()));
VSplinePoint cutPoint;
cutPoint = VSplinePoint(p, spl1.GetKasm2(), spl1.GetEndAngle(), spl2.GetKasm1(),
spl1.GetEndAngle()+180);
const qreal angle1 = spl1.GetStartAngle()+180;
const QString angle1F = QString().number(angle1);
spPath1.append(VSplinePoint(splP1.P(), angle1, angle1F, spl1.GetStartAngle(),
spl1.GetStartAngleFormula(), splP1.Length1(),
splP1.Length1Formula(), spl1.GetC1Length(),
spl1.GetC1LengthFormula()));
const qreal angle2 = spl1.GetEndAngle()+180;
const QString angle2F = QString().number(angle2);
const auto cutPoint = VSplinePoint(p, spl1.GetEndAngle(), spl1.GetEndAngleFormula(), angle2,
angle2F, spl1.GetC2Length(), spl1.GetC2LengthFormula(),
spl2.GetC1Length(), spl2.GetC1LengthFormula());
spPath1.append(cutPoint);
continue;
}
@ -93,20 +103,29 @@ void VisToolCutSplinePath::RefreshGeometry()
{
if (i == p2)
{
const VSplinePoint cutPoint = VSplinePoint(p, spl1.GetKasm2(), spl2.GetStartAngle()+180,
spl2.GetKasm1(), spl2.GetStartAngle());
const qreal angle1 = spl2.GetStartAngle()+180;
const QString angle1F = QString().number(angle1);
const auto cutPoint = VSplinePoint(p, angle1, angle1F, spl2.GetStartAngle(),
spl2.GetStartAngleFormula(), spl1.GetC2Length(),
spl1.GetC2LengthFormula(), spl2.GetC1Length(),
spl2.GetC1LengthFormula());
spPath2.append(cutPoint);
spPath2.append(VSplinePoint(splP2.P(), spl2.GetKasm2(), spl2.GetEndAngle(), splP2.KAsm2(),
spl2.GetEndAngle()+180));
const qreal angle2 = spl2.GetEndAngle()+180;
const QString angle2F = QString().number(angle2);
spPath2.append(VSplinePoint(splP2.P(), spl2.GetEndAngle(), spl2.GetEndAngleFormula(), angle2,
angle2F, spl2.GetC2Length(), spl2.GetC2LengthFormula(),
splP2.Length2(), splP2.Length2Formula()));
continue;
}
spPath2.append(splPath->at(i));
}
}
spPath1.SetKCurve(splPath->GetKCurve());
spPath2.SetKCurve(splPath->GetKCurve());
DrawPoint(point, cutPoint, mainColor);
DrawPath(splPath1, spPath1.GetPath(PathDirection::Show), Qt::darkGreen, Qt::SolidLine, Qt::RoundCap);

View File

@ -234,14 +234,14 @@ void VisToolSplinePath::Creating(const QPointF &pSpl, int size)
if (size == 1)
{
path[size-1].SetAngle2(spline.GetStartAngle());
path[size-1].SetAngle2(spline.GetStartAngle(), spline.GetStartAngleFormula());
if (ctrlPoint != pSpl)
{
path[size-1].SetKAsm2(spline.GetKasm1());
path[size-1].SetLength2(spline.GetC1Length(), spline.GetC1LengthFormula());
}
else
{
path[size-1].SetKAsm2(0);
path[size-1].SetLength2(0, "0");
}
emit PathChanged(path);
}
@ -250,16 +250,16 @@ void VisToolSplinePath::Creating(const QPointF &pSpl, int size)
const VSpline spl = path.GetSpline(size - 1);
VSpline preSpl(spl.GetP1(), spl.GetP2(), ctrlLine.p2(), VPointF(pSpl));
path[size-1].SetAngle2(spline.GetStartAngle());
path[size-1].SetAngle2(spline.GetStartAngle(), spline.GetStartAngleFormula());
if (ctrlPoint != pSpl)
{
path[size-1].SetKAsm1(preSpl.GetKasm2());
path[size-1].SetKAsm2(spline.GetKasm1());
path[size-1].SetLength1(preSpl.GetC2Length(), preSpl.GetC2LengthFormula());
path[size-1].SetLength2(spline.GetC1Length(), spline.GetC1LengthFormula());
}
else
{
path[size-1].SetKAsm1(0);
path[size-1].SetKAsm2(0);
path[size-1].SetLength1(0, "0");
path[size-1].SetLength2(0, "0");
}
emit PathChanged(path);
}
@ -270,15 +270,15 @@ void VisToolSplinePath::Creating(const QPointF &pSpl, int size)
VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos, VPointF(Visualization::scenePos));
path[size-1].SetAngle2(spline.GetStartAngle());
path[size-1].SetAngle2(spline.GetStartAngle(), spline.GetStartAngleFormula());
if (ctrlPoint != pSpl)
{
path[size-1].SetKAsm2(spline.GetKasm1());
path[size-1].SetLength2(spline.GetC1Length(), spline.GetC1LengthFormula());
}
else
{
path[size-1].SetKAsm2(0);
path[size-1].SetLength2(0, "0");
}
emit PathChanged(path);

View File

@ -59,27 +59,27 @@ void TST_VDetail::ClearLoop()
data->UpdateGObject(203, new VPointF(642.96276692900597, 581.21895343695326, "С1", 88.99993700787401,
50.000125984251973));
VSplinePath *path = new VSplinePath();
QVector<VFSplinePoint> points;
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(203);
VSplinePoint p(*point.data(), 0.79455646129695412, 449.62747641208136, 1.6867283804609809, 269.62747641208136);
path->append(p);
VFSplinePoint p(*point.data(), 0.79455646129695412, 449.62747641208136, 1.6867283804609809, 269.62747641208136);
points.append(p);
}
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(57);
VSplinePoint p(*point.data(), 0.4456850846354396, 120.24000000000034, 1.0255399999999999, 300.24000000000035);
path->append(p);
VFSplinePoint p(*point.data(), 0.4456850846354396, 120.24000000000034, 1.0255399999999999, 300.24000000000035);
points.append(p);
}
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(56);
VSplinePoint p(*point.data(), 1.0085299999999999, 184.58891, 1, 4.5889100000000003);
path->append(p);
VFSplinePoint p(*point.data(), 1.0085299999999999, 184.58891, 1, 4.5889100000000003);
points.append(p);
}
data->UpdateGObject(308, path);
data->UpdateGObject(308, new VSplinePath(points));
data->UpdateGObject(309, new VPointF(799.45989815267649, 850.6707401574804, "Г8", -30.431206299212597,
29.487155905511813));