Merge with feature. A simple curve controled by formulas.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2016-02-28 21:49:52 +02:00
commit 33b6256896
50 changed files with 2537 additions and 557 deletions

View File

@ -1298,20 +1298,45 @@ void VToolOptionsPropertyBrowser::ChangeDataToolSpline(VProperty *property)
QVariant value = property->data(VProperty::DPC_Data, Qt::DisplayRole);
const QString id = propertyToId[property];
VToolSpline *i = qgraphicsitem_cast<VToolSpline *>(currentItem);
auto i = qgraphicsitem_cast<VToolSpline *>(currentItem);
SCASSERT(i != nullptr);
VSpline spl = i->getSpline();
const VFormula f = value.value<VFormula>();
switch (PropertiesList().indexOf(id))
{
case 0: // AttrName
Q_UNREACHABLE();//The attribute is read only
break;
case 25: // AttrKCurve
{
VSpline spl = i->getSpline();
spl.SetKcurve(value.toDouble());
i->setSpline(spl);
case 9: // AttrAngle1
if (not f.error())
{
spl.SetStartAngle(f.getDoubleValue(), f.GetFormula(FormulaType::FromUser));
i->setSpline(spl);
}
break;
case 10: // AttrAngle2
if (not f.error())
{
spl.SetEndAngle(f.getDoubleValue(), f.GetFormula(FormulaType::FromUser));
i->setSpline(spl);
}
break;
case 36: // AttrLength1
if (not f.error() && f.getDoubleValue() >= 0)
{
spl.SetC1Length(qApp->toPixel(f.getDoubleValue()), f.GetFormula(FormulaType::FromUser));
i->setSpline(spl);
}
break;
case 37: // AttrLength2
if (not f.error() && f.getDoubleValue() >= 0)
{
spl.SetC2Length(qApp->toPixel(f.getDoubleValue()), f.GetFormula(FormulaType::FromUser));
i->setSpline(spl);
}
break;
}
case 27: // AttrTypeColor
i->SetLineColor(value.toString());
break;
@ -1709,20 +1734,38 @@ void VToolOptionsPropertyBrowser::ShowOptionsToolShoulderPoint(QGraphicsItem *it
//---------------------------------------------------------------------------------------------------------------------
void VToolOptionsPropertyBrowser::ShowOptionsToolSpline(QGraphicsItem *item)
{
VToolSpline *i = qgraphicsitem_cast<VToolSpline *>(item);
auto i = qgraphicsitem_cast<VToolSpline *>(item);
i->ShowVisualization(true);
formView->setTitle(tr("Curve tool"));
const auto spl = i->getSpline();
AddPropertyObjectName(i, tr("Name"), true);
VDoubleProperty* itemFactor = new VDoubleProperty(tr("Curve factor"));
VSpline spl = i->getSpline();
itemFactor->setSetting("Min", 0.1);
itemFactor->setSetting("Max", 1000);
itemFactor->setSetting("Step", 0.01);
itemFactor->setSetting("Precision", 3);
itemFactor->setValue(spl.GetKcurve());
AddProperty(itemFactor, AttrKCurve);
VFormula angle1(spl.GetStartAngleFormula(), i->getData());
angle1.setCheckZero(false);
angle1.setToolId(i->getId());
angle1.setPostfix(degreeSymbol);
AddPropertyFormula(tr("C1: angle"), angle1, AttrAngle1);
VFormula length1(spl.GetC1LengthFormula(), i->getData());
length1.setCheckZero(false);
length1.setToolId(i->getId());
length1.setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit()));
AddPropertyFormula(tr("C1: length"), length1, AttrLength1);
VFormula angle2(spl.GetEndAngleFormula(), i->getData());
angle2.setCheckZero(false);
angle2.setToolId(i->getId());
angle2.setPostfix(degreeSymbol);
AddPropertyFormula(tr("C2: angle"), angle2, AttrAngle2);
VFormula length2(spl.GetC2LengthFormula(), i->getData());
length2.setCheckZero(false);
length2.setToolId(i->getId());
length2.setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit()));
AddPropertyFormula(tr("C2: length"), length2, AttrLength2);
AddPropertyLineColor(i, tr("Color"), VAbstractTool::ColorsList(), AttrColor);
}
@ -2124,9 +2167,42 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolShoulderPoint()
void VToolOptionsPropertyBrowser::UpdateOptionsToolSpline()
{
auto i = qgraphicsitem_cast<VToolSpline *>(currentItem);
const VSpline spl = i->getSpline();
idToProperty[AttrName]->setValue(i->name());
idToProperty[AttrKCurve]->setValue(i->getSpline().GetKcurve());
VFormula angle1F(spl.GetStartAngleFormula(), i->getData());
angle1F.setCheckZero(false);
angle1F.setToolId(i->getId());
angle1F.setPostfix(degreeSymbol);
QVariant angle1;
angle1.setValue(angle1F);
idToProperty[AttrAngle1]->setValue(angle1);
VFormula length1F(spl.GetC1LengthFormula(), i->getData());
length1F.setCheckZero(false);
length1F.setToolId(i->getId());
length1F.setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit()));
QVariant length1;
length1.setValue(length1F);
idToProperty[AttrLength1]->setValue(length1);
VFormula angle2F(spl.GetEndAngleFormula(), i->getData());
angle2F.setCheckZero(false);
angle2F.setToolId(i->getId());
angle2F.setPostfix(degreeSymbol);
QVariant angle2;
angle2.setValue(angle2F);
idToProperty[AttrAngle2]->setValue(angle2);
VFormula length2F(spl.GetC2LengthFormula(), i->getData());
length2F.setCheckZero(false);
length2F.setToolId(i->getId());
length2F.setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit()));
QVariant length2;
length2.setValue(length2F);
idToProperty[AttrLength2]->setValue(length2);
idToProperty[AttrColor]->setValue(VLineColorProperty::IndexOfColor(VAbstractTool::ColorsList(), i->GetLineColor()));
}
@ -2218,7 +2294,7 @@ QStringList VToolOptionsPropertyBrowser::PropertiesList() const
<< AttrPShoulder /* 22 */
<< AttrAxisP1 /* 23 */
<< AttrAxisP2 /* 24 */
<< AttrKCurve /* 25 */
<< AttrKCurve /*Not used*/ /* 25 */
<< AttrLineColor /* 26 */
<< AttrColor /* 27 */
<< AttrCrossPoint /* 28 */
@ -2228,6 +2304,8 @@ QStringList VToolOptionsPropertyBrowser::PropertiesList() const
<< AttrName1 /* 32 */
<< AttrName2 /* 33 */
<< AttrVCrossPoint /* 34 */
<< AttrHCrossPoint; /* 35 */
<< AttrHCrossPoint /* 35 */
<< AttrLength1 /* 36 */
<< AttrLength2; /* 37 */
return attr;
}

View File

@ -1842,7 +1842,8 @@ void VPattern::ParseToolTrueDarts(VMainGraphicsScene *scene, const QDomElement &
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::ParseToolSpline(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse)
// TODO. Delete if minimal supported version is 0.2.7
void VPattern::ParseOldToolSpline(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse)
{
SCASSERT(scene != nullptr);
Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null");
@ -1865,10 +1866,10 @@ void VPattern::ParseToolSpline(VMainGraphicsScene *scene, const QDomElement &dom
const auto p1 = data->GeometricObject<VPointF>(point1);
const auto p4 = data->GeometricObject<VPointF>(point4);
VSpline spline(*p1, *p4, angle1, angle2, kAsm1, kAsm2, kCurve);
auto spline = new VSpline(*p1, *p4, angle1, angle2, kAsm1, kAsm2, kCurve);
if (duplicate > 0)
{
spline.SetDuplicate(duplicate);
spline->SetDuplicate(duplicate);
}
VToolSpline::Create(id, spline, color, scene, this, data, parse, Source::FromFile);
@ -1881,6 +1882,62 @@ void VPattern::ParseToolSpline(VMainGraphicsScene *scene, const QDomElement &dom
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::ParseToolSpline(VMainGraphicsScene *scene, 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 quint32 point1 = GetParametrUInt(domElement, AttrPoint1, NULL_ID_STR);
const quint32 point4 = GetParametrUInt(domElement, AttrPoint4, NULL_ID_STR);
const QString angle1 = GetParametrString(domElement, AttrAngle1, "0");
QString a1 = angle1;//need for saving fixed formula;
const QString angle2 = GetParametrString(domElement, AttrAngle2, "0");
QString a2 = angle2;//need for saving fixed formula;
const QString length1 = GetParametrString(domElement, AttrLength1, "0");
QString l1 = length1;//need for saving fixed formula;
const QString length2 = GetParametrString(domElement, AttrLength2, "0");
QString l2 = length2;//need for saving fixed formula;
const QString color = GetParametrString(domElement, AttrColor, ColorBlack);
const quint32 duplicate = GetParametrUInt(domElement, AttrDuplicate, "0");
VToolSpline::Create(id, point1, point4, a1, a2, l1, l2, duplicate, color, scene, this, data, parse,
Source::FromFile);
//Rewrite attribute formula. Need for situation when we have wrong formula.
if (a1 != angle1 || a2 != angle2 || l1 != length1 || l2 != length2)
{
SetAttribute(domElement, AttrAngle1, a1);
SetAttribute(domElement, AttrAngle2, a2);
SetAttribute(domElement, AttrLength1, l1);
SetAttribute(domElement, AttrLength2, l2);
modified = true;
haveLiteChange();
}
}
catch (const VExceptionBadId &e)
{
VExceptionObjectError excep(tr("Error creating or updating simple curve"), domElement);
excep.AddMoreInformation(e.ErrorMessage());
throw excep;
}
catch (qmu::QmuParserError &e)
{
VExceptionObjectError excep(tr("Error creating or updating simple interactive spline"), domElement);
excep.AddMoreInformation(QString("Message: " + e.GetMsg() + "\n"+ "Expression: " + e.GetExpr()));
throw excep;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::ParseToolSplinePath(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse)
{
@ -2217,32 +2274,37 @@ void VPattern::GarbageCollector()
* @param parse parser file mode.
* @param type type of spline.
*/
void VPattern::ParseSplineElement(VMainGraphicsScene *scene, const QDomElement &domElement,
void VPattern::ParseSplineElement(VMainGraphicsScene *scene, QDomElement &domElement,
const Document &parse, const QString &type)
{
SCASSERT(scene != nullptr);
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::ToolType /*0*/
<< VToolSplinePath::ToolType /*1*/
<< VNodeSpline::ToolType /*2*/
<< VNodeSplinePath::ToolType; /*3*/
QStringList splines = QStringList() << VToolSpline::OldToolType /*0*/
<< VToolSpline::ToolType /*1*/
<< VToolSplinePath::ToolType /*2*/
<< VNodeSpline::ToolType /*3*/
<< VNodeSplinePath::ToolType; /*4*/
switch (splines.indexOf(type))
{
case 0: //VToolSpline::ToolType
case 0: //VToolSpline::OldToolType
qCDebug(vXML, "VToolSpline.");
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 1: //VToolSplinePath::ToolType
case 2: //VToolSplinePath::ToolType
qCDebug(vXML, "VToolSplinePath.");
ParseToolSplinePath(scene, domElement, parse);
break;
case 2: //VNodeSpline::ToolType
case 3: //VNodeSpline::ToolType
qCDebug(vXML, "VNodeSpline.");
ParseNodeSpline(domElement, parse);
break;
case 3: //VNodeSplinePath::ToolType
case 4: //VNodeSplinePath::ToolType
qCDebug(vXML, "VNodeSplinePath.");
ParseNodeSplinePath(domElement, parse);
break;

View File

@ -119,7 +119,7 @@ private:
const Document &parse, const QString &type);
void ParseLineElement(VMainGraphicsScene *scene, const QDomElement& domElement,
const Document &parse);
void ParseSplineElement(VMainGraphicsScene *scene, const QDomElement& domElement,
void ParseSplineElement(VMainGraphicsScene *scene, QDomElement &domElement,
const Document &parse, const QString& type);
void ParseArcElement(VMainGraphicsScene *scene, QDomElement &domElement,
const Document &parse, const QString& type);
@ -167,7 +167,10 @@ private:
const Document &parse);
void ParseToolTrueDarts(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse);
void ParseToolSpline(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse);
// TODO. Delete if minimal supported version is 0.2.7
void ParseOldToolSpline(VMainGraphicsScene *scene, const QDomElement &domElement, const Document &parse);
void ParseToolSpline(VMainGraphicsScene *scene, 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

@ -89,6 +89,8 @@ const QString AttrRadius = QStringLiteral("radius");
const QString AttrAngle = QStringLiteral("angle");
const QString AttrAngle1 = QStringLiteral("angle1");
const QString AttrAngle2 = QStringLiteral("angle2");
const QString AttrLength1 = QStringLiteral("length1");
const QString AttrLength2 = QStringLiteral("length2");
const QString AttrP1Line = QStringLiteral("p1Line");
const QString AttrP2Line = QStringLiteral("p2Line");
const QString AttrP1Line1 = QStringLiteral("p1Line1");

View File

@ -91,6 +91,8 @@ extern const QString AttrRadius;
extern const QString AttrAngle;
extern const QString AttrAngle1;
extern const QString AttrAngle2;
extern const QString AttrLength1;
extern const QString AttrLength2;
extern const QString AttrP1Line;
extern const QString AttrP2Line;
extern const QString AttrP1Line1;
@ -101,9 +103,9 @@ extern const QString AttrPShoulder;
extern const QString AttrPoint1;
extern const QString AttrPoint2;
extern const QString AttrPoint4;
extern const QString AttrKAsm1;
extern const QString AttrKAsm2;
extern const QString AttrKCurve;
extern const QString AttrKAsm1;// TODO. Delete if minimal supported version is 0.2.7
extern const QString AttrKAsm2;// TODO. Delete if minimal supported version is 0.2.7
extern const QString AttrKCurve;// TODO. Delete if minimal supported version is 0.2.7
extern const QString AttrDuplicate;
extern const QString AttrPathPoint;
extern const QString AttrPSpline;

View File

@ -12,6 +12,7 @@
<file>schema/pattern/v0.2.4.xsd</file>
<file>schema/pattern/v0.2.5.xsd</file>
<file>schema/pattern/v0.2.6.xsd</file>
<file>schema/pattern/v0.2.7.xsd</file>
<file>schema/standard_measurements/v0.3.0.xsd</file>
<file>schema/standard_measurements/v0.4.0.xsd</file>
<file>schema/standard_measurements/v0.4.1.xsd</file>

View File

@ -0,0 +1,437 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- XML Schema Generated from XML Document-->
<xs:element name="pattern">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="version" type="formatVersion"></xs:element>
<xs:element name="unit" type="units"></xs:element>
<xs:element name="author" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="gradation" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="heights">
<xs:complexType>
<xs:attribute name="all" type="xs:boolean" use="required"></xs:attribute>
<xs:attribute name="h92" type="xs:boolean"></xs:attribute>
<xs:attribute name="h98" type="xs:boolean"></xs:attribute>
<xs:attribute name="h104" type="xs:boolean"></xs:attribute>
<xs:attribute name="h110" type="xs:boolean"></xs:attribute>
<xs:attribute name="h116" type="xs:boolean"></xs:attribute>
<xs:attribute name="h122" type="xs:boolean"></xs:attribute>
<xs:attribute name="h128" type="xs:boolean"></xs:attribute>
<xs:attribute name="h134" type="xs:boolean"></xs:attribute>
<xs:attribute name="h140" type="xs:boolean"></xs:attribute>
<xs:attribute name="h146" type="xs:boolean"></xs:attribute>
<xs:attribute name="h152" type="xs:boolean"></xs:attribute>
<xs:attribute name="h158" type="xs:boolean"></xs:attribute>
<xs:attribute name="h164" type="xs:boolean"></xs:attribute>
<xs:attribute name="h170" type="xs:boolean"></xs:attribute>
<xs:attribute name="h176" type="xs:boolean"></xs:attribute>
<xs:attribute name="h182" type="xs:boolean"></xs:attribute>
<xs:attribute name="h188" type="xs:boolean"></xs:attribute>
<xs:attribute name="h194" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="sizes">
<xs:complexType>
<xs:attribute name="all" type="xs:boolean" use="required"></xs:attribute>
<xs:attribute name="s22" type="xs:boolean"></xs:attribute>
<xs:attribute name="s24" type="xs:boolean"></xs:attribute>
<xs:attribute name="s26" type="xs:boolean"></xs:attribute>
<xs:attribute name="s28" type="xs:boolean"></xs:attribute>
<xs:attribute name="s30" type="xs:boolean"></xs:attribute>
<xs:attribute name="s32" type="xs:boolean"></xs:attribute>
<xs:attribute name="s34" type="xs:boolean"></xs:attribute>
<xs:attribute name="s36" type="xs:boolean"></xs:attribute>
<xs:attribute name="s38" type="xs:boolean"></xs:attribute>
<xs:attribute name="s40" type="xs:boolean"></xs:attribute>
<xs:attribute name="s42" type="xs:boolean"></xs:attribute>
<xs:attribute name="s44" type="xs:boolean"></xs:attribute>
<xs:attribute name="s46" type="xs:boolean"></xs:attribute>
<xs:attribute name="s48" type="xs:boolean"></xs:attribute>
<xs:attribute name="s50" type="xs:boolean"></xs:attribute>
<xs:attribute name="s52" type="xs:boolean"></xs:attribute>
<xs:attribute name="s54" type="xs:boolean"></xs:attribute>
<xs:attribute name="s56" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="custom" type="xs:boolean"></xs:attribute>
<xs:attribute name="defHeight" type="baseHeight"></xs:attribute>
<xs:attribute name="defSize" type="baseSize"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="measurements" type="xs:string"></xs:element>
<xs:element name="increments" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="increment" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="description" type="xs:string" use="required"></xs:attribute>
<xs:attribute name="name" type="shortName" use="required"></xs:attribute>
<xs:attribute name="formula" type="xs:string" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="incrementName">
<xs:selector xpath="increment"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:element name="draw" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="calculation" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="x" type="xs:double"></xs:attribute>
<xs:attribute name="y" type="xs:double"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="name" type="shortName"></xs:attribute>
<xs:attribute name="firstPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="secondPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="thirdPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="basePoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="pShoulder" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="length" type="xs:string"></xs:attribute>
<xs:attribute name="angle" type="xs:string"></xs:attribute>
<xs:attribute name="typeLine" type="xs:string"></xs:attribute>
<xs:attribute name="splinePath" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="spline" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="radius" type="xs:string"></xs:attribute>
<xs:attribute name="axisP1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="axisP2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="arc" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="curve" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="curve1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="curve2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="lineColor" type="colors"></xs:attribute>
<xs:attribute name="color" type="colors"></xs:attribute>
<xs:attribute name="firstArc" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="secondArc" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="crossPoint" type="crossType"></xs:attribute>
<xs:attribute name="vCrossPoint" type="crossType"></xs:attribute>
<xs:attribute name="hCrossPoint" type="crossType"></xs:attribute>
<xs:attribute name="c1Center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="c2Center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="c1Radius" type="xs:string"></xs:attribute>
<xs:attribute name="c2Radius" type="xs:string"></xs:attribute>
<xs:attribute name="cRadius" type="xs:string"></xs:attribute>
<xs:attribute name="tangent" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="cCenter" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="name1" type="shortName"></xs:attribute>
<xs:attribute name="mx1" type="xs:double"></xs:attribute>
<xs:attribute name="my1" type="xs:double"></xs:attribute>
<xs:attribute name="name2" type="shortName"></xs:attribute>
<xs:attribute name="mx2" type="xs:double"></xs:attribute>
<xs:attribute name="my2" type="xs:double"></xs:attribute>
<xs:attribute name="point1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="point2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="dartP1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="dartP2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="dartP3" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="baseLineP1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="baseLineP2" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="firstPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="secondPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeLine" type="xs:string"></xs:attribute>
<xs:attribute name="lineColor" type="colors"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="angle1" type="xs:string"></xs:attribute>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="angle2" type="xs:string"></xs:attribute>
<xs:attribute name="radius" type="xs:string"></xs:attribute>
<xs:attribute name="center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="color" type="colors"></xs:attribute>
<xs:attribute name="length" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="pathPoint" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<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="kAsm1" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="kCurve" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="kAsm1" type="xs:double"></xs:attribute>
<xs:attribute name="kAsm2" type="xs:double"></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="point1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="point4" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="color" type="colors"></xs:attribute>
<xs:attribute name="duplicate" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="modeling" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="inUse" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="inUse" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="inUse" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="tools" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="det" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="nodeType" type="xs:string"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="reverse" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="children" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="child" type="xs:unsignedInt" minOccurs="1" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="indexD1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="indexD2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="inUse" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="details" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="detail" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="nodeType" type="xs:string"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="reverse" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="supplement" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="width" type="xs:double"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
<xs:attribute name="closed" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="readOnly" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:simpleType name="shortName">
<xs:restriction base="xs:string">
<xs:pattern value="^([^0-9*/^+\-=\s()?%:;!.,`'\&quot;]){1,1}([^*/^+\-=\s()?%:;!.,`'\&quot;]){0,}$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="units">
<xs:restriction base="xs:string">
<xs:enumeration value="mm"/>
<xs:enumeration value="cm"/>
<xs:enumeration value="inch"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="measurementsTypes">
<xs:restriction base="xs:string">
<xs:enumeration value="standard"/>
<xs:enumeration value="individual"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="formatVersion">
<xs:restriction base="xs:string">
<xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="colors">
<xs:restriction base="xs:string">
<xs:enumeration value="black"/>
<xs:enumeration value="green"/>
<xs:enumeration value="blue"/>
<xs:enumeration value="darkRed"/>
<xs:enumeration value="darkGreen"/>
<xs:enumeration value="darkBlue"/>
<xs:enumeration value="yellow"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="baseHeight">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="92"/>
<xs:enumeration value="98"/>
<xs:enumeration value="104"/>
<xs:enumeration value="110"/>
<xs:enumeration value="116"/>
<xs:enumeration value="122"/>
<xs:enumeration value="128"/>
<xs:enumeration value="134"/>
<xs:enumeration value="140"/>
<xs:enumeration value="146"/>
<xs:enumeration value="152"/>
<xs:enumeration value="158"/>
<xs:enumeration value="164"/>
<xs:enumeration value="170"/>
<xs:enumeration value="176"/>
<xs:enumeration value="182"/>
<xs:enumeration value="188"/>
<xs:enumeration value="194"/>
<xs:enumeration value="920"/>
<xs:enumeration value="980"/>
<xs:enumeration value="1040"/>
<xs:enumeration value="1100"/>
<xs:enumeration value="1160"/>
<xs:enumeration value="1220"/>
<xs:enumeration value="1280"/>
<xs:enumeration value="1340"/>
<xs:enumeration value="1400"/>
<xs:enumeration value="1460"/>
<xs:enumeration value="1520"/>
<xs:enumeration value="1580"/>
<xs:enumeration value="1640"/>
<xs:enumeration value="1700"/>
<xs:enumeration value="1760"/>
<xs:enumeration value="1820"/>
<xs:enumeration value="1880"/>
<xs:enumeration value="1940"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="baseSize">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="22"/>
<xs:enumeration value="24"/>
<xs:enumeration value="26"/>
<xs:enumeration value="28"/>
<xs:enumeration value="30"/>
<xs:enumeration value="32"/>
<xs:enumeration value="34"/>
<xs:enumeration value="36"/>
<xs:enumeration value="38"/>
<xs:enumeration value="40"/>
<xs:enumeration value="42"/>
<xs:enumeration value="44"/>
<xs:enumeration value="46"/>
<xs:enumeration value="48"/>
<xs:enumeration value="50"/>
<xs:enumeration value="52"/>
<xs:enumeration value="54"/>
<xs:enumeration value="56"/>
<xs:enumeration value="220"/>
<xs:enumeration value="240"/>
<xs:enumeration value="260"/>
<xs:enumeration value="280"/>
<xs:enumeration value="300"/>
<xs:enumeration value="320"/>
<xs:enumeration value="340"/>
<xs:enumeration value="360"/>
<xs:enumeration value="380"/>
<xs:enumeration value="400"/>
<xs:enumeration value="420"/>
<xs:enumeration value="440"/>
<xs:enumeration value="460"/>
<xs:enumeration value="480"/>
<xs:enumeration value="500"/>
<xs:enumeration value="520"/>
<xs:enumeration value="540"/>
<xs:enumeration value="560"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="crossType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="1"/>
<xs:enumeration value="2"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View File

@ -43,8 +43,8 @@
*/
const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.0");
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.2.6");
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.2.6.xsd");
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.2.7");
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.2.7.xsd");
//---------------------------------------------------------------------------------------------------------------------
VPatternConverter::VPatternConverter(const QString &fileName)
@ -109,6 +109,8 @@ QString VPatternConverter::XSDSchema(int ver) const
case (0x000205):
return QStringLiteral("://schema/pattern/v0.2.5.xsd");
case (0x000206):
return QStringLiteral("://schema/pattern/v0.2.6.xsd");
case (0x000207):
return CurrentSchema;
default:
InvalidVersion(ver);
@ -201,6 +203,13 @@ void VPatternConverter::ApplyPatches()
V_FALLTHROUGH
}
case (0x000206):
{
ToV0_2_7();
const QString schema = XSDSchema(0x000207);
ValidateXML(schema, fileName);
V_FALLTHROUGH
}
case (0x000207):
break;
default:
break;
@ -315,6 +324,13 @@ void VPatternConverter::ToV0_2_6()
Save();
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::ToV0_2_7()
{
SetVersion(QStringLiteral("0.2.7"));
Save();
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::TagUnitToV0_2_0()
{

View File

@ -67,6 +67,7 @@ private:
void ToV0_2_4();
void ToV0_2_5();
void ToV0_2_6();
void ToV0_2_7();
void TagUnitToV0_2_0();
void TagIncrementToV0_2_0();

View File

@ -75,8 +75,35 @@ VSpline::VSpline (VPointF p1, VPointF p4, qreal angle1, qreal angle2, qreal kAsm
* @param p3 second control point.
* @param p4 second point spline.
*/
VSpline::VSpline (VPointF p1, QPointF p2, QPointF p3, VPointF p4, qreal kCurve, quint32 idObject, Draw mode)
:VAbstractCurve(GOType::Spline, idObject, mode), d(new VSplineData(p1, p2, p3, p4, kCurve))
VSpline::VSpline (VPointF p1, QPointF p2, QPointF p3, VPointF p4, quint32 idObject, Draw mode)
:VAbstractCurve(GOType::Spline, idObject, mode), d(new VSplineData(p1, p2, p3, p4))
{
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief VSpline constructor
* @param p1 first point spline.
* @param p4 first control point.
* @param angle1 angle from first point to first control point.
* @param angle1Formula formula angle from first point to first control point.
* @param angle2 angle from second point to second control point.
* @param angle2Formula formula angle from second point to second control point.
* @param c1Length length from first point to first control point.
* @param c1LengthFormula formula length from first point to first control point.
* @param c2Length length from second point to first control point.
* @param c2LengthFormula formula length from second point to first control point.
* @param idObject
* @param mode
*/
VSpline::VSpline(VPointF p1, VPointF p4, qreal angle1, const QString &angle1Formula, qreal angle2,
const QString &angle2Formula, qreal c1Length, const QString &c1LengthFormula, qreal c2Length,
const QString &c2LengthFormula, quint32 idObject, Draw mode)
: VAbstractCurve(GOType::Spline, idObject, mode),
d(new VSplineData(p1, p4, angle1, angle1Formula, angle2,angle2Formula, c1Length, c1LengthFormula, c2Length,
c2LengthFormula))
{
CreateName();
}
@ -93,7 +120,7 @@ VSpline::~VSpline()
*/
qreal VSpline::GetLength () const
{
return LengthBezier ( GetP1().toQPointF(), d->p2, d->p3, GetP4().toQPointF());
return LengthBezier ( GetP1().toQPointF(), GetP2(), GetP3(), GetP4().toQPointF());
}
//---------------------------------------------------------------------------------------------------------------------
@ -210,8 +237,8 @@ QPointF VSpline::CutSpline(qreal length, VSpline &spl1, VSpline &spl2) const
QPointF spl2p3;
QPointF cutPoint = CutSpline (length, spl1p2, spl1p3, spl2p2, spl2p3 );
spl1 = VSpline(GetP1(), spl1p2, spl1p3, cutPoint, GetKcurve());
spl2 = VSpline(cutPoint, spl2p2, spl2p3, GetP4(), GetKcurve());
spl1 = VSpline(GetP1(), spl1p2, spl1p3, cutPoint);
spl2 = VSpline(cutPoint, spl2p2, spl2p3, GetP4());
return cutPoint;
}
@ -222,7 +249,7 @@ QPointF VSpline::CutSpline(qreal length, VSpline &spl1, VSpline &spl2) const
*/
QVector<QPointF> VSpline::GetPoints () const
{
return GetPoints(GetP1().toQPointF(), d->p2, d->p3, GetP4().toQPointF());
return GetPoints(GetP1().toQPointF(), GetP2(), GetP3(), GetP4().toQPointF());
}
//---------------------------------------------------------------------------------------------------------------------
@ -589,8 +616,8 @@ void VSpline::PointBezier_r ( qreal x1, qreal y1, qreal x2, qreal y2,
*/
qreal VSpline::CalcSqDistance (qreal x1, qreal y1, qreal x2, qreal y2)
{
qreal dx = x2 - x1;
qreal dy = y2 - y1;
const qreal dx = x2 - x1;
const qreal dy = y2 - y1;
return dx * dx + dy * dy;
}
@ -661,6 +688,12 @@ VPointF VSpline::GetP1() const
return d->p1;
}
//---------------------------------------------------------------------------------------------------------------------
void VSpline::SetP1(const VPointF &p)
{
d->p1 = p;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetP2 return first control point.
@ -668,7 +701,9 @@ VPointF VSpline::GetP1() const
*/
QPointF VSpline::GetP2() const
{
return d->p2;
QLineF p1p2(d->p1.x(), d->p1.y(), d->p1.x() + d->c1Length, d->p1.y());
p1p2.setAngle(d->angle1);
return p1p2.p2();
}
//---------------------------------------------------------------------------------------------------------------------
@ -678,7 +713,9 @@ QPointF VSpline::GetP2() const
*/
QPointF VSpline::GetP3() const
{
return d->p3;
QLineF p4p3(d->p4.x(), d->p4.y(), d->p4.x() + d->c2Length, d->p4.y());
p4p3.setAngle(d->angle2);
return p4p3.p2();
}
//---------------------------------------------------------------------------------------------------------------------
@ -691,6 +728,12 @@ VPointF VSpline::GetP4() const
return d->p4;
}
//---------------------------------------------------------------------------------------------------------------------
void VSpline::SetP4(const VPointF &p)
{
d->p4 = p;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetAngle1 return first angle control line.
@ -711,6 +754,70 @@ qreal VSpline::GetEndAngle() const
return d->angle2;
}
//---------------------------------------------------------------------------------------------------------------------
QString VSpline::GetStartAngleFormula() const
{
return d->angle1F;
}
//---------------------------------------------------------------------------------------------------------------------
QString VSpline::GetEndAngleFormula() const
{
return d->angle2F;
}
//---------------------------------------------------------------------------------------------------------------------
void VSpline::SetStartAngle(qreal angle, const QString &formula)
{
d->angle1 = angle;
d->angle1F = formula;
}
//---------------------------------------------------------------------------------------------------------------------
void VSpline::SetEndAngle(qreal angle, const QString &formula)
{
d->angle2 = angle;
d->angle2F = formula;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VSpline::GetC1Length() const
{
return d->c1Length;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VSpline::GetC2Length() const
{
return d->c2Length;
}
//---------------------------------------------------------------------------------------------------------------------
QString VSpline::GetC1LengthFormula() const
{
return d->c1LengthF;
}
//---------------------------------------------------------------------------------------------------------------------
QString VSpline::GetC2LengthFormula() const
{
return d->c2LengthF;
}
//---------------------------------------------------------------------------------------------------------------------
void VSpline::SetC1Length(qreal length, const QString &formula)
{
d->c1Length = length;
d->c1LengthF = formula;
}
//---------------------------------------------------------------------------------------------------------------------
void VSpline::SetC2Length(qreal length, const QString &formula)
{
d->c2Length = length;
d->c2LengthF = formula;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetKasm1 return coefficient of length first control line.
@ -718,7 +825,8 @@ qreal VSpline::GetEndAngle() const
*/
qreal VSpline::GetKasm1() const
{
return d->kAsm1;
return QLineF(d->p1.toQPointF(), GetP2()).length() / VSplineData::GetL(d->p1.toQPointF(), d->p4.toQPointF(),
d->kCurve);
}
//---------------------------------------------------------------------------------------------------------------------
@ -728,7 +836,8 @@ qreal VSpline::GetKasm1() const
*/
qreal VSpline::GetKasm2() const
{
return d->kAsm2;
return QLineF(d->p4.toQPointF(), GetP3()).length() / VSplineData::GetL(d->p1.toQPointF(), d->p4.toQPointF(),
d->kCurve);
}
//---------------------------------------------------------------------------------------------------------------------
@ -741,15 +850,6 @@ qreal VSpline::GetKcurve() const
return d->kCurve;
}
//---------------------------------------------------------------------------------------------------------------------
void VSpline::SetKcurve(qreal factor)
{
if (factor > 0)
{
d->kCurve = factor;
}
}
//---------------------------------------------------------------------------------------------------------------------
int VSpline::Sign(long double ld)
{
@ -846,8 +946,8 @@ qreal VSpline::ParamT (const QPointF &pBt) const
{
QVector<qreal> ts;
// Calculate t coefficient for each axis
ts += CalcT (GetP1().toQPointF().x(), d->p2.x(), d->p3.x(), GetP4().toQPointF().x(), pBt.x());
ts += CalcT (GetP1().toQPointF().y(), d->p2.y(), d->p3.y(), GetP4().toQPointF().y(), pBt.y());
ts += CalcT (GetP1().toQPointF().x(), GetP2().x(), GetP3().x(), GetP4().toQPointF().x(), pBt.x());
ts += CalcT (GetP1().toQPointF().y(), GetP2().y(), GetP3().y(), GetP4().toQPointF().y(), pBt.y());
if (ts.isEmpty())
{
@ -863,8 +963,8 @@ qreal VSpline::ParamT (const QPointF &pBt) const
{
const qreal t = ts.at(i);
const QPointF p0 = GetP1().toQPointF();
const QPointF p1 = d->p2;
const QPointF p2 = d->p3;
const QPointF p1 = GetP2();
const QPointF p2 = GetP3();
const QPointF p3 = GetP4().toQPointF();
//The explicit form of the Cubic Bézier curve
const qreal pointX = pow(1-t, 3)*p0.x() + 3*pow(1-t, 2)*t*p1.x() + 3*(1-t)*pow(t, 2)*p2.x() + pow(t, 3)*p3.x();

View File

@ -49,23 +49,45 @@ public:
VSpline (const VSpline &spline );
VSpline (VPointF p1, VPointF p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2, qreal kCurve,
quint32 idObject = 0, Draw mode = Draw::Calculation);
VSpline (VPointF p1, QPointF p2, QPointF p3, VPointF p4, qreal kCurve, quint32 idObject = 0,
VSpline (VPointF p1, QPointF p2, QPointF p3, VPointF p4, quint32 idObject = 0,
Draw mode = Draw::Calculation);
VSpline (VPointF p1, VPointF p4, qreal angle1, const QString &angle1Formula, qreal angle2,
const QString &angle2Formula, qreal c1Length, const QString &c1LengthFormula, qreal c2Length,
const QString &c2LengthFormula, quint32 idObject = 0, Draw mode = Draw::Calculation);
virtual ~VSpline() Q_DECL_OVERRIDE;
VSpline &operator=(const VSpline &spl);
VPointF GetP1 () const;
void SetP1 (const VPointF &p);
QPointF GetP2 () const;
QPointF GetP3 () const;
VPointF GetP4 () const;
void SetP4 (const VPointF &p);
virtual qreal GetStartAngle () const Q_DECL_OVERRIDE;
virtual qreal GetEndAngle() const Q_DECL_OVERRIDE;
QString GetStartAngleFormula () const;
QString GetEndAngleFormula() const;
void SetStartAngle(qreal angle, const QString &formula);
void SetEndAngle(qreal angle, const QString &formula);
qreal GetC1Length() const;
qreal GetC2Length() const;
QString GetC1LengthFormula() const;
QString GetC2LengthFormula() const;
void SetC1Length(qreal length, const QString &formula);
void SetC2Length(qreal length, const QString &formula);
qreal GetLength () const;
qreal GetKasm1() const;
qreal GetKasm2() const;
qreal GetKcurve() const;
void SetKcurve(qreal factor);
qreal LengthT(qreal t) const;
QPointF CutSpline ( qreal length, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, QPointF &spl2p3) const;
QPointF CutSpline ( qreal length, VSpline &spl1, VSpline &spl2) const;

View File

@ -30,10 +30,12 @@
#define VSPLINE_P_H
#include <QSharedData>
#include "vpointf.h"
#include <QLineF>
#include <QtCore/qmath.h>
#include "vpointf.h"
#include "../vmisc/vabstractapplication.h"
#ifdef Q_CC_GNU
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
@ -42,85 +44,171 @@
class VSplineData : public QSharedData
{
public:
VSplineData()
:p1(VPointF()), p2(QPointF()), p3(QPointF()), p4(VPointF()), angle1(0), angle2(0), kAsm1(1), kAsm2(1), kCurve(1)
{}
VSplineData ( const VSplineData &spline )
:QSharedData(spline), p1(spline.p1), p2(spline.p2), p3(spline.p3), p4(spline.p4), angle1(spline.angle1),
angle2(spline.angle2), kAsm1(spline.kAsm1), kAsm2(spline.kAsm2), kCurve(spline.kCurve)
{}
VSplineData (VPointF p1, VPointF p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2, qreal kCurve)
:p1(p1), p2(QPointF()), p3(QPointF()), p4(p4), angle1(angle1), angle2(angle2), kAsm1(kAsm1), kAsm2(kAsm2),
kCurve(kCurve)
{
qreal L = 0, radius = 0, angle = 90;
QPointF point1 = this->p1.toQPointF();
QPointF point4 = this->p4.toQPointF();
radius = QLineF(point1, point4).length()/M_SQRT2;
L = kCurve * radius * 4 / 3 * tan( angle * M_PI / 180.0 / 4 );
QLineF p1p2(this->p1.x(), this->p1.y(), this->p1.x() + L * kAsm1, this->p1.y());
p1p2.setAngle(angle1);
QLineF p4p3(this->p4.x(), this->p4.y(), this->p4.x() + L * kAsm2, this->p4.y());
p4p3.setAngle(angle2);
this->p2 = p1p2.p2();
this->p3 = p4p3.p2();
}
VSplineData (VPointF p1, QPointF p2, QPointF p3, VPointF p4, qreal kCurve)
:p1(p1), p2(p2), p3(p3), p4(p4), angle1(0), angle2(0), kAsm1(1), kAsm2(1), kCurve(1)
{
this->angle1 = QLineF ( this->p1.toQPointF(), this->p2 ).angle();
this->angle2 = QLineF ( this->p4.toQPointF(), this->p3 ).angle();
qreal L = 0, radius = 0, angle = 90;
QPointF point1 = this->p1.toQPointF();
QPointF point4 = this->p4.toQPointF();
radius = QLineF(point1, point4).length()/M_SQRT2;
L = kCurve * radius * 4 / 3 * tan( angle * M_PI / 180.0 / 4 );
this->kCurve = kCurve;
this->kAsm1 = QLineF ( this->p1.toQPointF(), this->p2 ).length()/L;
this->kAsm2 = QLineF ( this->p4.toQPointF(), this->p3 ).length()/L;
}
VSplineData();
VSplineData(const VSplineData &spline);
VSplineData(VPointF p1, VPointF p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2, qreal kCurve);
VSplineData(VPointF p1, QPointF p2, QPointF p3, VPointF p4);
VSplineData(VPointF p1, VPointF p4, qreal angle1, const QString &angle1F, qreal angle2, const QString &angle2F,
qreal c1Length, const QString &c1LengthF, qreal c2Length, const QString &c2LengthF);
virtual ~VSplineData();
static qreal GetL(const QPointF &p1, const QPointF &p4, qreal kCurve);
/** @brief p1 first spline point. */
VPointF p1;
VPointF p1;
/** @brief p2 first control point. */
QPointF p2;
/** @brief p3 second control point. */
QPointF p3;
/** @brief p4 last spline point. */
VPointF p4;
/** @brief p4 fourth spline point. */
VPointF p4;
/** @brief angle1 first angle control line. */
qreal angle1;
qreal angle1;
/** @brief angle1F the first control point angle formula*/
QString angle1F;
/** @brief angle2 second angle control line. */
qreal angle2;
qreal angle2;
/** @brief kAsm1 coefficient of length first control line. */
qreal kAsm1;
/** @brief angle2F the second control point angle formula*/
QString angle2F;
/** @brief kAsm2 coefficient of length second control line. */
qreal kAsm2;
/** @brief c1Length the length from the first spline point to the first control point. */
qreal c1Length;
/** @brief c1LengthF the formula from the first spline point to the first control point. */
QString c1LengthF;
/** @brief c2Length the length from the fourth spline point to the second control point. */
qreal c2Length;
/** @brief c2LengthF the formula length from the fourth spline point to the second control point. */
QString c2LengthF;
/** @brief kCurve coefficient of curvature spline. */
qreal kCurve;
qreal kCurve;
private:
VSplineData &operator=(const VSplineData &) Q_DECL_EQ_DELETE;
};
//---------------------------------------------------------------------------------------------------------------------
VSplineData::VSplineData()
: p1(),
p4(),
angle1(0),
angle1F("0"),
angle2(0),
angle2F("0"),
c1Length(0),
c1LengthF("0"),
c2Length(0),
c2LengthF("0"),
kCurve(1)
{}
//---------------------------------------------------------------------------------------------------------------------
VSplineData::VSplineData(const VSplineData &spline)
: QSharedData(spline),
p1(spline.p1),
p4(spline.p4),
angle1(spline.angle1),
angle1F(spline.angle1F),
angle2(spline.angle2),
angle2F(spline.angle2F),
c1Length(spline.c1Length),
c1LengthF(spline.c1LengthF),
c2Length(spline.c2Length),
c2LengthF(spline.c2LengthF),
kCurve(spline.kCurve)
{}
//---------------------------------------------------------------------------------------------------------------------
VSplineData::VSplineData(VPointF p1, VPointF p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2, qreal kCurve)
: p1(p1),
p4(p4),
angle1(angle1),
angle1F(QString().number(angle1)),
angle2(angle2),
angle2F(QString().number(angle2)),
c1Length(0),
c1LengthF("0"),
c2Length(0),
c2LengthF("0"),
kCurve(kCurve)
{
const qreal L = GetL(p1.toQPointF(), p4.toQPointF(), kCurve);
QLineF p1p2(p1.x(), p1.y(), p1.x() + L * kAsm1, p1.y());
p1p2.setAngle(angle1);
c1Length = p1p2.length();
c1LengthF = QString().number(qApp->fromPixel(c1Length));
QLineF p4p3(p4.x(), p4.y(), p4.x() + L * kAsm2, p4.y());
p4p3.setAngle(angle2);
c2Length = p4p3.length();
c2LengthF = QString().number(qApp->fromPixel(c2Length));
}
//---------------------------------------------------------------------------------------------------------------------
VSplineData::VSplineData(VPointF p1, QPointF p2, QPointF p3, VPointF p4)
: p1(p1),
p4(p4),
angle1(0),
angle1F("0"),
angle2(0),
angle2F("0"),
c1Length(0),
c1LengthF("0"),
c2Length(0),
c2LengthF("0"),
kCurve(1)
{
QLineF p1p2(p1.toQPointF(), p2);
angle1 = p1p2.angle();
angle1F = QString().number(angle1);
c1Length = p1p2.length();
c1LengthF = QString().number(qApp->fromPixel(c1Length));
QLineF p4p3(p4.toQPointF(), p3);
angle2 = p4p3.angle();
angle2F = QString().number(angle2);
c2Length = p4p3.length();
c2LengthF = QString().number(qApp->fromPixel(c2Length));
}
//---------------------------------------------------------------------------------------------------------------------
VSplineData::VSplineData(VPointF p1, VPointF p4, qreal angle1, const QString &angle1F, qreal angle2,
const QString &angle2F, qreal c1Length, const QString &c1LengthF,
qreal c2Length, const QString &c2LengthF)
: p1(p1),
p4(p4),
angle1(angle1),
angle1F(angle1F),
angle2(angle2),
angle2F(angle2F),
c1Length(c1Length),
c1LengthF(c1LengthF),
c2Length(c2Length),
c2LengthF(c2LengthF),
kCurve(1)
{}
//---------------------------------------------------------------------------------------------------------------------
VSplineData::~VSplineData()
{}
//---------------------------------------------------------------------------------------------------------------------
qreal VSplineData::GetL(const QPointF &p1, const QPointF &p4, qreal kCurve)
{
static const qreal angle = 90;
const qreal radius = QLineF(p1, p4).length()/M_SQRT2;
return kCurve * radius * 4 / 3 * qTan( angle * M_PI_4 / 180.0 );
}
#ifdef Q_CC_GNU
#pragma GCC diagnostic pop
#endif

View File

@ -889,7 +889,8 @@ QString VTranslateVars::FormulaToUser(const QString &formula) const
}
loc = QLocale::system();// To user locale
const QString dStr = loc.toString(d);// Number string in user locale
QString dStr = loc.toString(d);// Number string in user locale
dStr.replace(" ", ""); // Remove thousand separator
newFormula.replace(nKeys.at(i), nValues.at(i).length(), dStr);
const int bias = nValues.at(i).length() - dStr.length();
if (bias != 0)

View File

@ -33,8 +33,10 @@
#include "../vgeometry/vspline.h"
#include "../vpatterndb/vcontainer.h"
#include "../../visualization/vistoolspline.h"
#include "../support/dialogeditwrongformula.h"
#include <QDebug>
#include <QTimer>
//---------------------------------------------------------------------------------------------------------------------
/**
@ -43,9 +45,42 @@
* @param parent parent widget
*/
DialogSpline::DialogSpline(const VContainer *data, const quint32 &toolId, QWidget *parent)
:DialogTool(data, toolId, parent), ui(new Ui::DialogSpline), spl(), newDuplicate(-1)
: DialogTool(data, toolId, parent),
ui(new Ui::DialogSpline),
spl(),
newDuplicate(-1),
formulaBaseHeightAngle1(0),
formulaBaseHeightAngle2(0),
formulaBaseHeightLength1(0),
formulaBaseHeightLength2(0),
timerAngle1(new QTimer(this)),
timerAngle2(new QTimer(this)),
timerLength1(new QTimer(this)),
timerLength2(new QTimer(this)),
flagAngle1(false),
flagAngle2(false),
flagLength1(false),
flagLength2(false)
{
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);
connect(timerAngle1, &QTimer::timeout, this, &DialogSpline::EvalAngle1);
connect(timerAngle2, &QTimer::timeout, this, &DialogSpline::EvalAngle2);
connect(timerLength1, &QTimer::timeout, this, &DialogSpline::EvalLength1);
connect(timerLength2, &QTimer::timeout, this, &DialogSpline::EvalLength2);
InitOkCancelApply(ui);
FillComboBoxPoints(ui->comboBoxP1);
@ -59,6 +94,21 @@ DialogSpline::DialogSpline(const VContainer *data, const quint32 &toolId, QWidge
connect(ui->comboBoxP4, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged),
this, &DialogSpline::PointNameChanged);
connect(ui->toolButtonExprAngle1, &QPushButton::clicked, this, &DialogSpline::FXAngle1);
connect(ui->toolButtonExprAngle2, &QPushButton::clicked, this, &DialogSpline::FXAngle2);
connect(ui->toolButtonExprLength1, &QPushButton::clicked, this, &DialogSpline::FXLength1);
connect(ui->toolButtonExprLength2, &QPushButton::clicked, this, &DialogSpline::FXLength2);
connect(ui->plainTextEditAngle1F, &QPlainTextEdit::textChanged, this, &DialogSpline::Angle1Changed);
connect(ui->plainTextEditAngle2F, &QPlainTextEdit::textChanged, this, &DialogSpline::Angle2Changed);
connect(ui->plainTextEditLength1F, &QPlainTextEdit::textChanged, this, &DialogSpline::Length1Changed);
connect(ui->plainTextEditLength2F, &QPlainTextEdit::textChanged, this, &DialogSpline::Length2Changed);
connect(ui->pushButtonGrowAngle1, &QPushButton::clicked, this, &DialogSpline::DeployAngle1TextEdit);
connect(ui->pushButtonGrowAngle2, &QPushButton::clicked, this, &DialogSpline::DeployAngle2TextEdit);
connect(ui->pushButtonGrowLength1, &QPushButton::clicked, this, &DialogSpline::DeployLength1TextEdit);
connect(ui->pushButtonGrowLength2, &QPushButton::clicked, this, &DialogSpline::DeployLength2TextEdit);
vis = new VisToolSpline(data);
auto path = qobject_cast<VisToolSpline *>(vis);
SCASSERT(path != nullptr);
@ -125,14 +175,8 @@ void DialogSpline::ChosenObject(quint32 id, const SceneObject &type)
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::SaveData()
{
const qreal angle1 = ui->spinBoxAngle1->value();
const qreal angle2 = ui->spinBoxAngle2->value();
const qreal kAsm1 = ui->doubleSpinBoxKasm1->value();
const qreal kAsm2 = ui->doubleSpinBoxKasm2->value();
const qreal kCurve = ui->doubleSpinBoxKcurve->value();
const quint32 d = spl.GetDuplicate();//Save previous value
spl = VSpline(*GetP1(), *GetP4(), angle1, angle2, kAsm1, kAsm2, kCurve);
spl = CurrentSpline();
newDuplicate <= -1 ? spl.SetDuplicate(d) : spl.SetDuplicate(static_cast<quint32>(newDuplicate));
@ -141,15 +185,173 @@ void DialogSpline::SaveData()
path->setObject1Id(GetP1()->id());
path->setObject4Id(GetP4()->id());
path->SetAngle1(angle1);
path->SetAngle2(angle2);
path->SetKAsm1(kAsm1);
path->SetKAsm2(kAsm2);
path->SetKCurve(kCurve);
path->SetAngle1(spl.GetStartAngle());
path->SetAngle2(spl.GetEndAngle());
path->SetKAsm1(spl.GetKasm1());
path->SetKAsm2(spl.GetKasm2());
path->SetKCurve(spl.GetKcurve());
path->SetMode(Mode::Show);
path->RefreshGeometry();
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::closeEvent(QCloseEvent *event)
{
ui->plainTextEditAngle1F->blockSignals(true);
ui->plainTextEditAngle2F->blockSignals(true);
ui->plainTextEditLength1F->blockSignals(true);
ui->plainTextEditLength2F->blockSignals(true);
DialogTool::closeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::DeployAngle1TextEdit()
{
DeployFormula(ui->plainTextEditAngle1F, ui->pushButtonGrowAngle1, formulaBaseHeightAngle1);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::DeployAngle2TextEdit()
{
DeployFormula(ui->plainTextEditAngle2F, ui->pushButtonGrowAngle2, formulaBaseHeightAngle2);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::DeployLength1TextEdit()
{
DeployFormula(ui->plainTextEditLength1F, ui->pushButtonGrowLength1, formulaBaseHeightLength1);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::DeployLength2TextEdit()
{
DeployFormula(ui->plainTextEditLength2F, ui->pushButtonGrowLength2, formulaBaseHeightLength2);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::Angle1Changed()
{
labelEditFormula = ui->labelEditAngle1;
labelResultCalculation = ui->labelResultAngle1;
ValFormulaChanged(flagAngle1, ui->plainTextEditAngle1F, timerAngle1);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::Angle2Changed()
{
labelEditFormula = ui->labelEditAngle2;
labelResultCalculation = ui->labelResultAngle2;
ValFormulaChanged(flagAngle2, ui->plainTextEditAngle2F, timerAngle2);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::Length1Changed()
{
labelEditFormula = ui->labelEditLength1;
labelResultCalculation = ui->labelResultLength1;
ValFormulaChanged(flagLength1, ui->plainTextEditLength1F, timerLength1);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::Length2Changed()
{
labelEditFormula = ui->labelEditLength2;
labelResultCalculation = ui->labelResultLength2;
ValFormulaChanged(flagLength2, ui->plainTextEditLength2F, timerLength2);
}
//---------------------------------------------------------------------------------------------------------------------
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());
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 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());
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 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());
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 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());
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;
}
//---------------------------------------------------------------------------------------------------------------------
const QSharedPointer<VPointF> DialogSpline::GetP1() const
{
@ -162,6 +364,90 @@ const QSharedPointer<VPointF> DialogSpline::GetP4() const
return data->GeometricObject<VPointF>(getCurrentObjectId(ui->comboBoxP4));
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::EvalAngle1()
{
labelEditFormula = ui->labelEditAngle1;
Eval(ui->plainTextEditAngle1F->toPlainText(), flagAngle1, ui->labelResultAngle1, degreeSymbol, false);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::EvalAngle2()
{
labelEditFormula = ui->labelEditAngle2;
Eval(ui->plainTextEditAngle2F->toPlainText(), flagAngle2, ui->labelResultAngle2, degreeSymbol, false);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::EvalLength1()
{
labelEditFormula = ui->labelEditLength1;
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
const qreal length1 = Eval(ui->plainTextEditLength1F->toPlainText(), flagLength1, ui->labelResultLength1, postfix);
if (length1 < 0)
{
flagLength1 = false;
ChangeColor(labelEditFormula, Qt::red);
ui->labelResultLength1->setText(tr("Error") + " (" + postfix + ")");
ui->labelResultLength1->setToolTip(tr("Length can't be negative"));
DialogSpline::CheckState();
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::EvalLength2()
{
labelEditFormula = ui->labelEditLength2;
const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true);
const qreal length2 = Eval(ui->plainTextEditLength2F->toPlainText(), flagLength2, ui->labelResultLength2, postfix);
if (length2 < 0)
{
flagLength2 = false;
ChangeColor(labelEditFormula, Qt::red);
ui->labelResultLength2->setText(tr("Error") + " (" + postfix + ")");
ui->labelResultLength2->setToolTip(tr("Length can't be negative"));
DialogSpline::CheckState();
}
}
//---------------------------------------------------------------------------------------------------------------------
VSpline DialogSpline::CurrentSpline() const
{
QString angle1F = ui->plainTextEditAngle1F->toPlainText();
angle1F.replace("\n", " ");
QString angle2F = ui->plainTextEditAngle2F->toPlainText();
angle2F.replace("\n", " ");
QString length1F = ui->plainTextEditLength1F->toPlainText();
length1F.replace("\n", " ");
QString length2F = ui->plainTextEditLength2F->toPlainText();
length2F.replace("\n", " ");
const QHash<QString, qreal *> vars = data->PlainVariables();
const qreal angle1 = Visualization::FindVal(angle1F, vars);
const qreal angle2 = Visualization::FindVal(angle2F, vars);
const qreal length1 = Visualization::FindLength(length1F, vars);
const qreal length2 = Visualization::FindLength(length2F, vars);
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);
VSpline spline(*GetP1(), *GetP4(), angle1, angle1F, angle2, angle2F, length1, length1F, length2, length2F);
return spline;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::PointNameChanged()
{
@ -215,13 +501,15 @@ void DialogSpline::ShowDialog(bool click)
auto *path = qobject_cast<VisToolSpline *>(vis);
SCASSERT(path != nullptr);
spl = VSpline(*GetP1(), path->GetP2(), path->GetP3(), *GetP4(), ui->doubleSpinBoxKcurve->value());
spl = VSpline(*GetP1(), path->GetP2(), path->GetP3(), *GetP4());
ui->spinBoxAngle1->setValue(static_cast<qint32>(spl.GetStartAngle()));
ui->spinBoxAngle2->setValue(static_cast<qint32>(spl.GetEndAngle()));
const QString angle1F = qApp->TrVars()->FormulaToUser(spl.GetStartAngleFormula());
const QString angle2F = qApp->TrVars()->FormulaToUser(spl.GetEndAngleFormula());
ui->doubleSpinBoxKasm1->setValue(spl.GetKasm1());
ui->doubleSpinBoxKasm2->setValue(spl.GetKasm2());
ui->plainTextEditAngle1F->setPlainText(angle1F);
ui->plainTextEditAngle2F->setPlainText(angle2F);
ui->plainTextEditLength1F->setPlainText(qApp->TrVars()->FormulaToUser(spl.GetC1LengthFormula()));
ui->plainTextEditLength2F->setPlainText(qApp->TrVars()->FormulaToUser(spl.GetC2LengthFormula()));
if (not data->IsUnique(spl.name()))
{
@ -234,6 +522,18 @@ void DialogSpline::ShowDialog(bool click)
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::CheckState()
{
SCASSERT(bOk != nullptr);
bOk->setEnabled(flagAngle1 && flagAngle2 && flagLength1 && flagLength2 && flagError);
// In case dialog hasn't apply button
if ( bApply != nullptr)
{
bApply->setEnabled(bOk->isEnabled());
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSpline::ShowVisualization()
{
@ -253,12 +553,18 @@ void DialogSpline::SetSpline(const VSpline &spline)
setCurrentPointId(ui->comboBoxP1, spl.GetP1().id());
setCurrentPointId(ui->comboBoxP4, spl.GetP4().id());
ui->spinBoxAngle1->setValue(static_cast<qint32>(spl.GetStartAngle()));
ui->spinBoxAngle2->setValue(static_cast<qint32>(spl.GetEndAngle()));
ui->doubleSpinBoxKasm1->setValue(spl.GetKasm1());
ui->doubleSpinBoxKasm2->setValue(spl.GetKasm2());
ui->doubleSpinBoxKcurve->setValue(spl.GetKcurve());
const QString angle1F = qApp->TrVars()->FormulaToUser(spl.GetStartAngleFormula());
const QString angle2F = qApp->TrVars()->FormulaToUser(spl.GetEndAngleFormula());
ui->plainTextEditAngle1F->setPlainText(angle1F);
ui->plainTextEditAngle2F->setPlainText(angle2F);
const QString length1F = qApp->TrVars()->FormulaToUser(spl.GetC1LengthFormula());
const QString length2F = qApp->TrVars()->FormulaToUser(spl.GetC2LengthFormula());
ui->plainTextEditLength1F->setPlainText(length1F);
ui->plainTextEditLength2F->setPlainText(length2F);
ui->lineEditSplineName->setText(spl.name());
auto path = qobject_cast<VisToolSpline *>(vis);

View File

@ -57,11 +57,28 @@ public slots:
virtual void PointNameChanged() Q_DECL_OVERRIDE;
virtual void ShowDialog(bool click) Q_DECL_OVERRIDE;
protected:
virtual void CheckState() Q_DECL_OVERRIDE;
virtual void ShowVisualization() Q_DECL_OVERRIDE;
/**
* @brief SaveData Put dialog data in local variables
*/
virtual void SaveData() Q_DECL_OVERRIDE;
virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
private slots:
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(DialogSpline)
@ -73,8 +90,33 @@ private:
qint32 newDuplicate;
/** @brief formulaBaseHeight base height defined by dialogui */
int formulaBaseHeightAngle1;
int formulaBaseHeightAngle2;
int formulaBaseHeightLength1;
int formulaBaseHeightLength2;
/** @brief timerAngle1 timer of check first angle formula */
QTimer *timerAngle1;
QTimer *timerAngle2;
QTimer *timerLength1;
QTimer *timerLength2;
/** @brief flagAngle1 true if value of first angle is correct */
bool flagAngle1;
bool flagAngle2;
bool flagLength1;
bool flagLength2;
const QSharedPointer<VPointF> GetP1() const;
const QSharedPointer<VPointF> GetP4() const;
void EvalAngle1();
void EvalAngle2();
void EvalLength1();
void EvalLength2();
VSpline CurrentSpline() const;
};
#endif // DIALOGSPLINE_H

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>459</width>
<height>289</height>
<width>524</width>
<height>342</height>
</rect>
</property>
<property name="windowTitle">
@ -22,10 +22,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="spacing">
<number>6</number>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@ -62,79 +59,368 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxKasm1">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
<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_5">
<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 row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Angle:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<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 row="1" column="1">
<widget class="QSpinBox" name="spinBoxAngle1">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>360</number>
</property>
</widget>
<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_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="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 row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Length ratio:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<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>
@ -173,79 +459,368 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Length ratio:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<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_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="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 row="0" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxKasm2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
<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 row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Angle:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<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_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="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 row="1" column="1">
<widget class="QSpinBox" name="spinBoxAngle2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>360</number>
</property>
</widget>
<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>
@ -262,54 +837,13 @@
<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="Preferred">
<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">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -319,14 +853,14 @@
</property>
</widget>
</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="lineEditSplineName">
<property name="readOnly">
<bool>true</bool>
@ -349,12 +883,7 @@
</widget>
<tabstops>
<tabstop>comboBoxP1</tabstop>
<tabstop>doubleSpinBoxKasm1</tabstop>
<tabstop>spinBoxAngle1</tabstop>
<tabstop>comboBoxP4</tabstop>
<tabstop>doubleSpinBoxKasm2</tabstop>
<tabstop>spinBoxAngle2</tabstop>
<tabstop>doubleSpinBoxKcurve</tabstop>
<tabstop>comboBoxColor</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>

View File

@ -546,6 +546,12 @@ void DialogTool::DeployFormula(QPlainTextEdit *formula, QPushButton *buttonGrowL
const QTextCursor cursor = formula->textCursor();
//Before deploy ned to release dialog size
//I don't know why, but don't need to fixate again.
//A dialog will be lefted fixated. That's what we need.
setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
setMinimumSize(QSize(0, 0));
if (formula->height() < DIALOG_MAX_FORMULA_HEIGHT)
{
formula->setFixedHeight(DIALOG_MAX_FORMULA_HEIGHT);

View File

@ -32,6 +32,7 @@
#include "../../../undocommands/movespline.h"
#include "../../../visualization/vistoolspline.h"
#include "../vwidgets/vcontrolpointspline.h"
#include "../qmuparser/qmutokenparser.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
# include "../vmisc/vmath.h"
@ -39,7 +40,8 @@
# include <QtMath>
#endif
const QString VToolSpline::ToolType = QStringLiteral("simple");
const QString VToolSpline::ToolType = QStringLiteral("simpleInteractive");
const QString VToolSpline::OldToolType = QStringLiteral("simple");
//---------------------------------------------------------------------------------------------------------------------
/**
@ -67,16 +69,24 @@ VToolSpline::VToolSpline(VAbstractPattern *doc, VContainer *data, quint32 id, co
const auto spl = VAbstractTool::data.GeometricObject<VSpline>(id);
const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl->GetStartAngleFormula());
const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl->GetC1LengthFormula());
auto *controlPoint1 = new VControlPointSpline(1, SplinePointPosition::FirstPoint, spl->GetP2(),
spl->GetP1().toQPointF(), *data->GetPatternUnit(), this);
spl->GetP1().toQPointF(), *data->GetPatternUnit(), freeAngle1,
freeLength1, this);
connect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSpline::ControlPointChangePosition);
connect(this, &VToolSpline::setEnabledPoint, controlPoint1, &VControlPointSpline::setEnabledPoint);
connect(controlPoint1, &VControlPointSpline::ShowContextMenu, this, &VToolSpline::contextMenuEvent);
controlPoints.append(controlPoint1);
const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl->GetEndAngleFormula());
const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl->GetC2LengthFormula());
auto *controlPoint2 = new VControlPointSpline(1, SplinePointPosition::LastPoint, spl->GetP3(),
spl->GetP4().toQPointF(), *data->GetPatternUnit(), this);
spl->GetP4().toQPointF(), *data->GetPatternUnit(), freeAngle2,
freeLength2, this);
connect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSpline::ControlPointChangePosition);
connect(this, &VToolSpline::setEnabledPoint, controlPoint2, &VControlPointSpline::setEnabledPoint);
@ -124,8 +134,8 @@ VToolSpline* VToolSpline::Create(DialogTool *dialog, VMainGraphicsScene *scene,
auto dialogTool = qobject_cast<DialogSpline*>(dialog);
SCASSERT(dialogTool != nullptr);
auto spl = Create(0, dialogTool->GetSpline(), dialogTool->GetColor(), scene, doc, data, Document::FullParse,
Source::FromGui);
auto spl = Create(0, new VSpline(dialogTool->GetSpline()), dialogTool->GetColor(), scene, doc, data,
Document::FullParse, Source::FromGui);
if (spl != nullptr)
{
@ -138,7 +148,7 @@ VToolSpline* VToolSpline::Create(DialogTool *dialog, VMainGraphicsScene *scene,
/**
* @brief Create help create tool.
* @param _id tool id, 0 if tool doesn't exist yet.
* @param spl spline.
* @param spline spline.
* @param color spline color.
* @param scene pointer to scene.
* @param doc dom document container.
@ -147,11 +157,10 @@ VToolSpline* VToolSpline::Create(DialogTool *dialog, VMainGraphicsScene *scene,
* @param typeCreation way we create this tool.
* @return the created tool
*/
VToolSpline* VToolSpline::Create(const quint32 _id, const VSpline &spl, const QString &color, VMainGraphicsScene *scene,
VToolSpline* VToolSpline::Create(const quint32 _id, VSpline *spline, const QString &color, VMainGraphicsScene *scene,
VAbstractPattern *doc, VContainer *data, const Document &parse,
const Source &typeCreation)
{
auto spline = new VSpline(spl);
quint32 id = _id;
if (typeCreation == Source::FromGui)
{
@ -185,10 +194,34 @@ VToolSpline* VToolSpline::Create(const quint32 _id, const VSpline &spl, const QS
return nullptr;
}
//---------------------------------------------------------------------------------------------------------------------
VToolSpline *VToolSpline::Create(const quint32 _id, quint32 point1, quint32 point4, QString &a1, QString &a2,
QString &l1, QString &l2, quint32 duplicate, const QString &color,
VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data,
const Document &parse, const Source &typeCreation)
{
qreal calcAngle1 = CheckFormula(_id, a1, data);
qreal calcAngle2 = CheckFormula(_id, a2, data);
qreal calcLength1 = qApp->toPixel(CheckFormula(_id, l1, data));
qreal calcLength2 = qApp->toPixel(CheckFormula(_id, l2, data));
auto p1 = data->GeometricObject<VPointF>(point1);
auto p4 = data->GeometricObject<VPointF>(point4);
auto spline = new VSpline(*p1, *p4, calcAngle1, a1, calcAngle2, a2, calcLength1, l1, calcLength2, l2);
if (duplicate > 0)
{
spline->SetDuplicate(duplicate);
}
return VToolSpline::Create(_id, spline, color, scene, doc, data, parse, typeCreation);
}
//---------------------------------------------------------------------------------------------------------------------
VSpline VToolSpline::getSpline() const
{
QSharedPointer<VSpline> spline = VAbstractTool::data.GeometricObject<VSpline>(id);
auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
return *spline.data();
}
@ -222,11 +255,54 @@ void VToolSpline::ControlPointChangePosition(const qint32 &indexSpline, const Sp
VSpline spl;
if (position == SplinePointPosition::FirstPoint)
{
spl = VSpline(spline->GetP1(), pos, spline->GetP3(), spline->GetP4(), spline->GetKcurve());
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
{
spl = VSpline(spline->GetP1(), spline->GetP2(), pos, spline->GetP4(), spline->GetKcurve());
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);
}
MoveSpline *moveSpl = new MoveSpline(doc, spline.data(), spl, id, this->scene());
@ -290,14 +366,8 @@ void VToolSpline::SaveDialog(QDomElement &domElement)
controlPoints[0]->blockSignals(false);
controlPoints[1]->blockSignals(false);
doc->SetAttribute(domElement, AttrPoint1, spl.GetP1().id());
doc->SetAttribute(domElement, AttrPoint4, spl.GetP4().id());
doc->SetAttribute(domElement, AttrAngle1, spl.GetStartAngle());
doc->SetAttribute(domElement, AttrAngle2, spl.GetEndAngle());
doc->SetAttribute(domElement, AttrKAsm1, spl.GetKasm1());
doc->SetAttribute(domElement, AttrKAsm2, spl.GetKasm2());
doc->SetAttribute(domElement, AttrKCurve, spl.GetKcurve());
doc->SetAttribute(domElement, AttrColor, dialogTool->GetColor());
SetSplineAttributes(domElement, spl);
doc->SetAttribute(domElement, AttrColor, dialogTool->GetColor());
}
//---------------------------------------------------------------------------------------------------------------------
@ -305,29 +375,9 @@ void VToolSpline::SaveOptions(QDomElement &tag, QSharedPointer<VGObject> &obj)
{
VAbstractSpline::SaveOptions(tag, obj);
QSharedPointer<VSpline> spl = qSharedPointerDynamicCast<VSpline>(obj);
auto spl = qSharedPointerDynamicCast<VSpline>(obj);
SCASSERT(spl.isNull() == false);
doc->SetAttribute(tag, AttrType, ToolType);
doc->SetAttribute(tag, AttrPoint1, spl->GetP1().id());
doc->SetAttribute(tag, AttrPoint4, spl->GetP4().id());
doc->SetAttribute(tag, AttrAngle1, spl->GetStartAngle());
doc->SetAttribute(tag, AttrAngle2, spl->GetEndAngle());
doc->SetAttribute(tag, AttrKAsm1, spl->GetKasm1());
doc->SetAttribute(tag, AttrKAsm2, spl->GetKasm2());
doc->SetAttribute(tag, AttrKCurve, spl->GetKcurve());
if (spl->GetDuplicate() > 0)
{
doc->SetAttribute(tag, AttrDuplicate, spl->GetDuplicate());
}
else
{
if (tag.hasAttribute(AttrDuplicate))
{
tag.removeAttribute(AttrDuplicate);
}
}
SetSplineAttributes(tag, *spl);
}
//---------------------------------------------------------------------------------------------------------------------
@ -337,9 +387,17 @@ void VToolSpline::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
oldPosition = event->scenePos();
event->accept();
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()))
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
oldPosition = event->scenePos();
event->accept();
}
}
}
VAbstractSpline::mousePressEvent(event);
@ -352,8 +410,16 @@ void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
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()))
{
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
}
}
}
VAbstractSpline::mouseReleaseEvent(event);
@ -362,74 +428,81 @@ void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
//---------------------------------------------------------------------------------------------------------------------
void VToolSpline::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
// 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
// mouse grabber.".
const auto spline = VAbstractTool::data.GeometricObject<VSpline>(id);
// 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.
const QSharedPointer<VSpline> spline = VAbstractTool::data.GeometricObject<VSpline>(id);
const qreal t = spline->ParamT(oldPosition);
if (qFloor(t) == -1)
if (qmu::QmuTokenParser::IsSingle(spline->GetStartAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetEndAngleFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC1LengthFormula()) &&
qmu::QmuTokenParser::IsSingle(spline->GetC2LengthFormula()))
{
return;
}
// 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
// mouse grabber.".
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;
}
// 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.
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 qreal t = spline->ParamT(oldPosition);
const QPointF p2 = spline->GetP2() + offset0;
const QPointF p3 = spline->GetP3() + offset1;
if (qFloor(t) == -1)
{
return;
}
oldPosition = event->scenePos(); // Now mouse here
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;
}
VSpline spl = VSpline(spline->GetP1(), p2, p3, spline->GetP4(), spline->GetKcurve());
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;
MoveSpline *moveSpl = new MoveSpline(doc, spline.data(), spl, id, this->scene());
connect(moveSpl, &MoveSpline::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
qApp->getUndoStack()->push(moveSpl);
const QPointF p2 = spline->GetP2() + offset0;
const QPointF p3 = spline->GetP3() + offset1;
// 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;
oldPosition = event->scenePos(); // Now mouse here
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
{
if (QGraphicsView *view = viewList.at(0))
VSpline spl = VSpline(spline->GetP1(), p2, p3, spline->GetP4());
MoveSpline *moveSpl = new MoveSpline(doc, spline.data(), spl, id, this->scene());
connect(moveSpl, &MoveSpline::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
qApp->getUndoStack()->push(moveSpl);
// 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())
{
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;
}
}
}
@ -438,7 +511,15 @@ void VToolSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
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()))
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
}
}
VAbstractSpline::hoverEnterEvent(event);
@ -449,8 +530,16 @@ void VToolSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
if (flags() & QGraphicsItem::ItemIsMovable)
{
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
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()))
{
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
}
}
VAbstractSpline::hoverLeaveEvent(event);
@ -506,13 +595,21 @@ void VToolSpline::RefreshGeometry()
const auto spl = VAbstractTool::data.GeometricObject<VSpline>(id);
{
const bool freeAngle1 = qmu::QmuTokenParser::IsSingle(spl->GetStartAngleFormula());
const bool freeLength1 = qmu::QmuTokenParser::IsSingle(spl->GetC1LengthFormula());
const QPointF splinePoint = VAbstractTool::data.GeometricObject<VPointF>(spl->GetP1().id())->toQPointF();
controlPoints[0]->RefreshCtrlPoint(1, SplinePointPosition::FirstPoint, spl->GetP2(), splinePoint);
controlPoints[0]->RefreshCtrlPoint(1, SplinePointPosition::FirstPoint, spl->GetP2(), splinePoint, freeAngle1,
freeLength1);
}
{
const bool freeAngle2 = qmu::QmuTokenParser::IsSingle(spl->GetEndAngleFormula());
const bool freeLength2 = qmu::QmuTokenParser::IsSingle(spl->GetC2LengthFormula());
const QPointF splinePoint = VAbstractTool::data.GeometricObject<VPointF>(spl->GetP4().id())->toQPointF();
controlPoints[1]->RefreshCtrlPoint(1, SplinePointPosition::LastPoint, spl->GetP3(), splinePoint);
controlPoints[1]->RefreshCtrlPoint(1, SplinePointPosition::LastPoint, spl->GetP3(), splinePoint, freeAngle2,
freeLength2);
}
controlPoints[0]->blockSignals(false);
@ -525,3 +622,44 @@ void VToolSpline::RefreshGeometry()
point->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VToolSpline::SetSplineAttributes(QDomElement &domElement, const VSpline &spl)
{
SCASSERT(doc != nullptr);
doc->SetAttribute(domElement, AttrType, ToolType);
doc->SetAttribute(domElement, AttrPoint1, spl.GetP1().id());
doc->SetAttribute(domElement, AttrPoint4, spl.GetP4().id());
doc->SetAttribute(domElement, AttrAngle1, spl.GetStartAngleFormula());
doc->SetAttribute(domElement, AttrAngle2, spl.GetEndAngleFormula());
doc->SetAttribute(domElement, AttrLength1, spl.GetC1LengthFormula());
doc->SetAttribute(domElement, AttrLength2, spl.GetC2LengthFormula());
if (spl.GetDuplicate() > 0)
{
doc->SetAttribute(domElement, AttrDuplicate, spl.GetDuplicate());
}
else
{
if (domElement.hasAttribute(AttrDuplicate))
{
domElement.removeAttribute(AttrDuplicate);
}
}
if (domElement.hasAttribute(AttrKCurve))
{
domElement.removeAttribute(AttrKCurve);
}
if (domElement.hasAttribute(AttrKAsm1))
{
domElement.removeAttribute(AttrKAsm1);
}
if (domElement.hasAttribute(AttrKAsm2))
{
domElement.removeAttribute(AttrKAsm2);
}
}

View File

@ -45,10 +45,15 @@ public:
virtual ~VToolSpline() Q_DECL_OVERRIDE;
virtual void setDialog() Q_DECL_OVERRIDE;
static VToolSpline *Create(DialogTool *dialog, VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data);
static VToolSpline *Create(const quint32 _id, const VSpline &spl, const QString &color, VMainGraphicsScene *scene,
static VToolSpline *Create(const quint32 _id, VSpline *spline, const QString &color, VMainGraphicsScene *scene,
VAbstractPattern *doc, VContainer *data, const Document &parse,
const Source &typeCreation);
static VToolSpline *Create(const quint32 _id, quint32 point1, quint32 point4, QString &a1, QString &a2, QString &l1,
QString &l2, quint32 duplicate, const QString &color,
VMainGraphicsScene *scene, VAbstractPattern *doc, VContainer *data,
const Document &parse, const Source &typeCreation);
static const QString ToolType;
static const QString OldToolType;
virtual int type() const Q_DECL_OVERRIDE {return Type;}
enum { Type = UserType + static_cast<int>(Tool::Spline)};
@ -73,8 +78,10 @@ protected:
virtual void SetVisualization() Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(VToolSpline)
void RefreshGeometry ();
QPointF oldPosition;
void RefreshGeometry ();
void SetSplineAttributes(QDomElement &domElement, const VSpline &spl);
};
#endif // VTOOLSPLINE_H

View File

@ -68,7 +68,7 @@ VToolSplinePath::VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint3
{
VSpline spl = splPath->GetSpline(i);
auto *controlPoint = new VControlPointSpline(i, SplinePointPosition::FirstPoint, spl.GetP2(),
spl.GetP1().toQPointF(), *data->GetPatternUnit(), this);
spl.GetP1().toQPointF(), *data->GetPatternUnit(), true, true, this);
connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSplinePath::ControlPointChangePosition);
connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint);
@ -76,7 +76,7 @@ VToolSplinePath::VToolSplinePath(VAbstractPattern *doc, VContainer *data, quint3
controlPoints.append(controlPoint);
controlPoint = new VControlPointSpline(i, SplinePointPosition::LastPoint, spl.GetP3(), spl.GetP4().toQPointF(),
*data->GetPatternUnit(), this);
*data->GetPatternUnit(), true, true, this);
connect(controlPoint, &VControlPointSpline::ControlPointChangePosition, this,
&VToolSplinePath::ControlPointChangePosition);
connect(this, &VToolSplinePath::setEnabledPoint, controlPoint, &VControlPointSpline::setEnabledPoint);
@ -199,11 +199,11 @@ void VToolSplinePath::ControlPointChangePosition(const qint32 &indexSpline, cons
VSpline spl = newSplPath.GetSpline(indexSpline);
if (position == SplinePointPosition::FirstPoint)
{
spl = VSpline(spl.GetP1(), pos, spl.GetP3(), spl.GetP4(), spl.GetKcurve());
spl = VSpline(spl.GetP1(), pos, spl.GetP3(), spl.GetP4());
}
else
{
spl = VSpline(spl.GetP1(), spl.GetP2(), pos, spl.GetP4(), spl.GetKcurve());
spl = VSpline(spl.GetP1(), spl.GetP2(), pos, spl.GetP4());
}
UpdateControlPoints(spl, newSplPath, indexSpline);
@ -256,8 +256,7 @@ void VToolSplinePath::RefreshSplinePath(VSplinePath &splPath)
controlPoints[j-2]->blockSignals(false);
controlPoints[j-1]->blockSignals(false);
spl = VSpline (spl.GetP1(), controlPoints[j-2]->pos(), controlPoints[j-1]->pos(), spl.GetP4(),
splPath.GetKCurve());
spl = VSpline (spl.GetP1(), controlPoints[j-2]->pos(), controlPoints[j-1]->pos(), spl.GetP4());
UpdateControlPoints(spl, splPath, i);
}
}
@ -506,7 +505,7 @@ void VToolSplinePath::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
oldPosition = event->scenePos(); // Now mouse here
const VSpline spl = VSpline(spline.GetP1(), p2, p3, spline.GetP4(), spline.GetKcurve());
const VSpline spl = VSpline(spline.GetP1(), p2, p3, spline.GetP4());
UpdateControlPoints(spl, newSplPath, indexSpline);

View File

@ -135,11 +135,11 @@ VToolCutSpline* VToolCutSpline::Create(const quint32 _id, const QString &pointNa
VPointF *p = new VPointF(point, pointName, mx, my);
id = data->AddGObject(p);
VSpline *spline1 = new VSpline(spl->GetP1(), spl1p2, spl1p3, *p, spl->GetKcurve());
VSpline *spline1 = new VSpline(spl->GetP1(), spl1p2, spl1p3, *p);
spl1id = data->AddGObject(spline1);
data->AddCurve<VSpline>(spl1id, id);
VSpline *spline2 = new VSpline(*p, spl2p2, spl2p3, spl->GetP4(), spl->GetKcurve());
VSpline *spline2 = new VSpline(*p, spl2p2, spl2p3, spl->GetP4());
spl2id = data->AddGObject(spline2);
data->AddCurve<VSpline>(spl2id, id);
}
@ -151,11 +151,11 @@ VToolCutSpline* VToolCutSpline::Create(const quint32 _id, const QString &pointNa
spl1id = id + 1;
spl2id = id + 2;
VSpline *spline1 = new VSpline(spl->GetP1(), spl1p2, spl1p3, *p, spl->GetKcurve());
VSpline *spline1 = new VSpline(spl->GetP1(), spl1p2, spl1p3, *p);
data->UpdateGObject(spl1id, spline1);
data->AddCurve<VSpline>(spl1id, id);
VSpline *spline2 = new VSpline(*p, spl2p2, spl2p3, spl->GetP4(), spl->GetKcurve());
VSpline *spline2 = new VSpline(*p, spl2p2, spl2p3, spl->GetP4());
data->UpdateGObject(spl2id, spline2);
data->AddCurve<VSpline>(spl2id, id);

View File

@ -148,8 +148,8 @@ VToolCutSplinePath* VToolCutSplinePath::Create(const quint32 _id, const QString
VSplinePoint splP1 = splPath->at(p1);
VSplinePoint splP2 = splPath->at(p2);
const VSpline spl1 = VSpline(splP1.P(), spl1p2, spl1p3, *p, splPath->GetKCurve());
const VSpline spl2 = VSpline(*p, spl2p2, spl2p3, splP2.P(), splPath->GetKCurve());
const VSpline spl1 = VSpline(splP1.P(), spl1p2, spl1p3, *p);
const VSpline spl2 = VSpline(*p, spl2p2, spl2p3, splP2.P());
VSplinePath *splPath1 = new VSplinePath();
VSplinePath *splPath2 = new VSplinePath();

View File

@ -191,8 +191,7 @@ void VToolUnionDetails::AddToNewDetail(VMainGraphicsScene *scene, VAbstractPatte
VPointF *p4 = new VPointF(spline->GetP4());
BiasRotatePoint(p4, dx, dy, p, angle);
VSpline *spl = new VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, spline->GetKcurve(), 0,
Draw::Modeling);
VSpline *spl = new VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, 0, Draw::Modeling);
idObject = data->AddGObject(spl);
children.append(idObject);
@ -238,7 +237,7 @@ void VToolUnionDetails::AddToNewDetail(VMainGraphicsScene *scene, VAbstractPatte
VPointF *p4 = new VPointF(spline.GetP4());
BiasRotatePoint(p4, dx, dy, p, angle);
VSpline spl = VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, spline.GetKcurve());
VSpline spl = VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4);
if (i==1)
{
path->append(VSplinePoint(*p1, point1.KAsm1(), spl.GetStartAngle()+180,
@ -342,8 +341,7 @@ void VToolUnionDetails::UpdatePoints(VContainer *data, const VDetail &det, const
VPointF *p4 = new VPointF(spline->GetP4());
BiasRotatePoint(p4, dx, dy, p, angle);
VSpline *spl = new VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, spline->GetKcurve(), 0,
Draw::Modeling);
VSpline *spl = new VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, 0, Draw::Modeling);
data->UpdateGObject(TakeNextId(children), spl);
delete p1;
delete p4;
@ -379,7 +377,7 @@ void VToolUnionDetails::UpdatePoints(VContainer *data, const VDetail &det, const
VPointF *p4 = new VPointF(spline.GetP4());
BiasRotatePoint(p4, dx, dy, p, angle);
VSpline spl = VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4, spline.GetKcurve());
VSpline spl = VSpline(*p1, p2.toQPointF(), p3.toQPointF(), *p4);
if (i==1)
{
path->append(VSplinePoint(*p1, point1.KAsm1(), spl.GetStartAngle()+180,

View File

@ -92,11 +92,12 @@ void MoveSpline::Do(const VSpline &spl)
QDomElement domElement = doc->elementById(nodeId);
if (domElement.isElement())
{
doc->SetAttribute(domElement, AttrAngle1, QString().setNum(spl.GetStartAngle()));
doc->SetAttribute(domElement, AttrAngle2, QString().setNum(spl.GetEndAngle()));
doc->SetAttribute(domElement, AttrKAsm1, QString().setNum(spl.GetKasm1()));
doc->SetAttribute(domElement, AttrKAsm2, QString().setNum(spl.GetKasm2()));
doc->SetAttribute(domElement, AttrKCurve, QString().setNum(spl.GetKcurve()));
doc->SetAttribute(domElement, AttrPoint1, spl.GetP1().id());
doc->SetAttribute(domElement, AttrPoint4, spl.GetP4().id());
doc->SetAttribute(domElement, AttrAngle1, spl.GetStartAngleFormula());
doc->SetAttribute(domElement, AttrAngle2, spl.GetEndAngleFormula());
doc->SetAttribute(domElement, AttrLength1, spl.GetC1LengthFormula());
doc->SetAttribute(domElement, AttrLength2, spl.GetC2LengthFormula());
emit NeedLiteParsing(Document::LiteParse);
}

View File

@ -57,7 +57,7 @@ void VisToolAlongLine::setObject2Id(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
void VisToolAlongLine::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -61,17 +61,17 @@ void VisToolArc::RefreshGeometry()
//---------------------------------------------------------------------------------------------------------------------
void VisToolArc::setRadius(const QString &expression)
{
radius = FindLength(expression);
radius = FindLength(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolArc::setF1(const QString &expression)
{
f1 = FindVal(expression);
f1 = FindVal(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolArc::setF2(const QString &expression)
{
f2 = FindVal(expression);
f2 = FindVal(expression, Visualization::data->PlainVariables());
}

View File

@ -61,17 +61,17 @@ void VisToolArcWithLength::RefreshGeometry()
//---------------------------------------------------------------------------------------------------------------------
void VisToolArcWithLength::setRadius(const QString &expression)
{
radius = FindLength(expression);
radius = FindLength(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolArcWithLength::setF1(const QString &expression)
{
f1 = FindVal(expression);
f1 = FindVal(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolArcWithLength::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}

View File

@ -61,7 +61,7 @@ void VisToolBisector::setObject3Id(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
void VisToolBisector::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -94,7 +94,7 @@ QString VisToolCurveIntersectAxis::Angle() const
//---------------------------------------------------------------------------------------------------------------------
void VisToolCurveIntersectAxis::SetAngle(const QString &expression)
{
angle = FindVal(expression);
angle = FindVal(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -72,5 +72,5 @@ void VisToolCutArc::RefreshGeometry()
//---------------------------------------------------------------------------------------------------------------------
void VisToolCutArc::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}

View File

@ -72,5 +72,5 @@ void VisToolCutSpline::RefreshGeometry()
//---------------------------------------------------------------------------------------------------------------------
void VisToolCutSpline::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}

View File

@ -67,8 +67,8 @@ void VisToolCutSplinePath::RefreshGeometry()
VSplinePoint splP1 = splPath->at(p1);
VSplinePoint splP2 = splPath->at(p2);
const VSpline spl1 = VSpline(splP1.P(), spl1p2, spl1p3, p, splPath->GetKCurve());
const VSpline spl2 = VSpline(p, spl2p2, spl2p3, splP2.P(), splPath->GetKCurve());
const VSpline spl1 = VSpline(splP1.P(), spl1p2, spl1p3, p);
const VSpline spl2 = VSpline(p, spl2p2, spl2p3, splP2.P());
VSplinePath spPath1 = VSplinePath();
VSplinePath spPath2 = VSplinePath();
@ -118,5 +118,5 @@ void VisToolCutSplinePath::RefreshGeometry()
//---------------------------------------------------------------------------------------------------------------------
void VisToolCutSplinePath::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}

View File

@ -74,11 +74,11 @@ QString VisToolEndLine::Angle() const
//---------------------------------------------------------------------------------------------------------------------
void VisToolEndLine::SetAngle(const QString &expression)
{
angle = FindVal(expression);
angle = FindVal(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolEndLine::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}

View File

@ -110,7 +110,7 @@ QString VisToolLineIntersectAxis::Angle() const
//---------------------------------------------------------------------------------------------------------------------
void VisToolLineIntersectAxis::SetAngle(const QString &expression)
{
angle = FindVal(expression);
angle = FindVal(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -100,7 +100,7 @@ void VisToolNormal::setObject2Id(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
void VisToolNormal::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -84,7 +84,7 @@ void VisToolPointFromCircleAndTangent::setObject2Id(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
void VisToolPointFromCircleAndTangent::setCRadius(const QString &value)
{
cRadius = FindLength(value);
cRadius = FindLength(value, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -103,5 +103,5 @@ void VisToolPointOfContact::setRadiusId(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
void VisToolPointOfContact::setRadius(const QString &expression)
{
radius = FindLength(expression);
radius = FindLength(expression, Visualization::data->PlainVariables());
}

View File

@ -102,13 +102,13 @@ void VisToolPointOfIntersectionCircles::setObject2Id(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
void VisToolPointOfIntersectionCircles::setC1Radius(const QString &value)
{
c1Radius = FindLength(value);
c1Radius = FindLength(value, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------
void VisToolPointOfIntersectionCircles::setC2Radius(const QString &value)
{
c2Radius = FindLength(value);
c2Radius = FindLength(value, Visualization::data->PlainVariables());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -118,5 +118,5 @@ void VisToolShoulderPoint::setLineP2Id(const quint32 &value)
//---------------------------------------------------------------------------------------------------------------------
void VisToolShoulderPoint::setLength(const QString &expression)
{
length = FindLength(expression);
length = FindLength(expression, Visualization::data->PlainVariables());
}

View File

@ -106,7 +106,7 @@ void VisToolSpline::RefreshGeometry()
if (object4Id <= NULL_ID)
{
VSpline spline(*first, p2, Visualization::scenePos, VPointF(Visualization::scenePos), kCurve);
VSpline spline(*first, p2, Visualization::scenePos, VPointF(Visualization::scenePos));
DrawPath(this, spline.GetPath(PathDirection::Hide), mainColor, Qt::SolidLine, Qt::RoundCap);
}
else
@ -143,7 +143,7 @@ void VisToolSpline::RefreshGeometry()
if (qFuzzyCompare(angle1, EMPTY_ANGLE) || qFuzzyCompare(angle2, EMPTY_ANGLE))
{
VSpline spline(*first, p2, p3, *second, kCurve);
VSpline spline(*first, p2, p3, *second);
DrawPath(this, spline.GetPath(PathDirection::Hide), mainColor, Qt::SolidLine, Qt::RoundCap);
}
else

View File

@ -230,8 +230,7 @@ void VisToolSplinePath::Creating(const QPointF &pSpl, int size)
ctrlPoints[lastPoint]->RefreshCtrlPoint(size, SplinePointPosition::FirstPoint, ctrlPoint, pSpl);
}
VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos,
VPointF(Visualization::scenePos), path.GetKCurve());
VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos, VPointF(Visualization::scenePos));
if (size == 1)
{
@ -249,7 +248,7 @@ void VisToolSplinePath::Creating(const QPointF &pSpl, int size)
else
{
const VSpline spl = path.GetSpline(size - 1);
VSpline preSpl(spl.GetP1(), spl.GetP2(), ctrlLine.p2(), VPointF(pSpl), path.GetKCurve());
VSpline preSpl(spl.GetP1(), spl.GetP2(), ctrlLine.p2(), VPointF(pSpl));
path[size-1].SetAngle2(spline.GetStartAngle());
if (ctrlPoint != pSpl)
@ -269,8 +268,7 @@ void VisToolSplinePath::Creating(const QPointF &pSpl, int size)
{
pointSelected = true;
VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos,
VPointF(Visualization::scenePos), path.GetKCurve());
VSpline spline(VPointF(pSpl), ctrlPoint, Visualization::scenePos, VPointF(Visualization::scenePos));
path[size-1].SetAngle2(spline.GetStartAngle());

View File

@ -135,13 +135,13 @@ QRectF Visualization::PointRect(const qreal &radius) const
}
//---------------------------------------------------------------------------------------------------------------------
qreal Visualization::FindLength(const QString &expression)
qreal Visualization::FindLength(const QString &expression, const QHash<QString, qreal *> &vars)
{
return qApp->toPixel(FindVal(expression));
return qApp->toPixel(FindVal(expression, vars));
}
//---------------------------------------------------------------------------------------------------------------------
qreal Visualization::FindVal(const QString &expression)
qreal Visualization::FindVal(const QString &expression, const QHash<QString, qreal *> &vars)
{
qreal val = 0;
if (expression.isEmpty())
@ -157,7 +157,7 @@ qreal Visualization::FindVal(const QString &expression)
formula.replace("\n", " ");
formula = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
Calculator *cal = new Calculator();
val = cal->EvalFormula(data->PlainVariables(), formula);
val = cal->EvalFormula(vars, formula);
delete cal;
}
catch (qmu::QmuParserError &e)

View File

@ -58,6 +58,9 @@ public:
Mode GetMode() const;
void SetMode(const Mode &value);
static qreal FindLength(const QString &expression, const QHash<QString, qreal *> &vars);
static qreal FindVal(const QString &expression, const QHash<QString, qreal *> &vars);
signals:
void ToolTip(const QString &toolTip);
public slots:
@ -79,8 +82,6 @@ protected:
QGraphicsEllipseItem *InitPoint(const QColor &color, QGraphicsItem *parent) const;
QRectF PointRect(const qreal &radius) const;
qreal FindLength(const QString &expression);
qreal FindVal(const QString &expression);
void DrawPoint(QGraphicsEllipseItem *point, const QPointF &pos, const QColor &color,
Qt::PenStyle style = Qt::SolidLine);
virtual void DrawLine(QGraphicsLineItem *lineItem, const QLineF &line, const QColor &color,

View File

@ -44,7 +44,9 @@ VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointP
controlLine(nullptr),
indexSpline(indexSpline),
position(position),
patternUnit(patternUnit)
patternUnit(patternUnit),
freeAngle(true),
freeLength(true)
{
Init();
}
@ -60,13 +62,15 @@ VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointP
*/
VControlPointSpline::VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position,
const QPointF &controlPoint, const QPointF &splinePoint, Unit patternUnit,
QGraphicsItem *parent)
bool freeAngle, bool freeLength, QGraphicsItem *parent)
:QGraphicsEllipseItem(parent),
radius(CircleRadius()),
controlLine(nullptr),
indexSpline(indexSpline),
position(position),
patternUnit(patternUnit)
patternUnit(patternUnit),
freeAngle(freeAngle),
freeLength(freeLength)
{
Init();
@ -107,7 +111,10 @@ void VControlPointSpline::paint(QPainter *painter, const QStyleOptionGraphicsIte
void VControlPointSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
this->setPen(QPen(Qt::black, ToPixel(WidthMainLine(patternUnit), patternUnit)));
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
if (freeAngle || freeLength)
{
SetOverrideCursor(cursorArrowOpenHand, 1, 1);
}
QGraphicsEllipseItem::hoverEnterEvent(event);
}
@ -115,8 +122,11 @@ void VControlPointSpline::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
this->setPen(QPen(Qt::black, ToPixel(WidthHairLine(patternUnit), patternUnit)));
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
if (freeAngle || freeLength)
{
//Disable cursor-arrow-openhand
RestoreOverrideCursor(cursorArrowOpenHand);
}
QGraphicsEllipseItem::hoverLeaveEvent(event);
}
@ -129,49 +139,81 @@ void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/
QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene())
switch (change)
{
// 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)
case ItemPositionChange:
{
changeFinished = false;
// value - new position.
QPointF newPos = value.toPointF();
emit ControlPointChangePosition(indexSpline, position, newPos);
if (scene())
if (not freeAngle || not freeLength)
{
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
const QPointF splPoint = controlLine->line().p1() + pos();
QLineF newLine(splPoint, value.toPointF());// value - new position.
QLineF oldLine(splPoint, pos());// pos() - old position.
if (not freeAngle)
{
if (QGraphicsView *view = viewList.at(0))
newLine.setAngle(oldLine.angle());
}
if (not freeLength)
{
qreal length = controlLine->line().length();
qreal l2 = oldLine.length();
newLine.setLength(oldLine.length());
}
return newLine.p2();
}
break;
}
case ItemPositionHasChanged:
{
// 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;
// value - new position.
emit ControlPointChangePosition(indexSpline, position, value.toPointF());
if (scene())
{
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
{
const int xmargin = 50;
const int ymargin = 50;
const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
const QRectF itemRect = mapToScene(boundingRect()).boundingRect();
// If item's rect is bigger than view's rect ensureVisible works very unstable.
if (itemRect.height() + 2*ymargin < viewRect.height() &&
itemRect.width() + 2*xmargin < viewRect.width())
if (QGraphicsView *view = viewList.at(0))
{
view->ensureVisible(itemRect, xmargin, ymargin);
}
else
{
// Ensure visible only small rect around a cursor
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene);
const QPointF cursorPosition = currentScene->getScenePos();
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
const int xmargin = 50;
const int ymargin = 50;
const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
const QRectF itemRect = mapToScene(boundingRect()).boundingRect();
// If item's rect is bigger than view's rect ensureVisible works very unstable.
if (itemRect.height() + 2*ymargin < viewRect.height() &&
itemRect.width() + 2*xmargin < viewRect.width())
{
view->ensureVisible(itemRect, xmargin, ymargin);
}
else
{
// Ensure visible only small rect around a cursor
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;
break;
}
default:
break;
}
return QGraphicsItem::itemChange(change, value);
}
@ -181,7 +223,10 @@ void VControlPointSpline::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
if (freeAngle || freeLength)
{
SetOverrideCursor(cursorArrowCloseHand, 1, 1);
}
}
QGraphicsEllipseItem::mousePressEvent(event);
}
@ -191,8 +236,11 @@ void VControlPointSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
{
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
if (freeAngle || freeLength)
{
//Disable cursor-arrow-closehand
RestoreOverrideCursor(cursorArrowCloseHand);
}
}
QGraphicsEllipseItem::mouseReleaseEvent(event);
}
@ -235,10 +283,13 @@ void VControlPointSpline::SetCtrlLine(const QPointF &controlPoint, const QPointF
* @param splinePoint spline point.
*/
void VControlPointSpline::RefreshCtrlPoint(const qint32 &indexSpline, SplinePointPosition pos,
const QPointF &controlPoint, const QPointF &splinePoint)
const QPointF &controlPoint, const QPointF &splinePoint, bool freeAngle,
bool freeLength)
{
if (this->indexSpline == indexSpline && this->position == pos)
{
this->freeAngle = freeAngle;
this->freeLength = freeLength;
this->setPos(controlPoint);
SetCtrlLine(controlPoint, splinePoint);
}

View File

@ -44,7 +44,8 @@ public:
VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position, Unit patternUnit,
QGraphicsItem * parent = nullptr);
VControlPointSpline(const qint32 &indexSpline, SplinePointPosition position, const QPointF &controlPoint,
const QPointF &splinePoint, Unit patternUnit, QGraphicsItem * parent = nullptr);
const QPointF &splinePoint, Unit patternUnit, bool freeAngle, bool freeLength,
QGraphicsItem * parent = nullptr);
virtual ~VControlPointSpline() Q_DECL_OVERRIDE;
virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option,
QWidget * widget = 0) Q_DECL_OVERRIDE;
@ -66,7 +67,7 @@ signals:
void ShowContextMenu(QGraphicsSceneContextMenuEvent *event);
public slots:
void RefreshCtrlPoint(const qint32 &indexSpline, SplinePointPosition pos, const QPointF &controlPoint,
const QPointF &splinePoint);
const QPointF &splinePoint, bool freeAngle = true, bool freeLength = true);
void setEnabledPoint(bool enable);
protected:
/** @brief radius radius circle. */
@ -91,6 +92,9 @@ private:
Unit patternUnit;
bool freeAngle;
bool freeLength;
inline qreal CircleRadius() const;
void Init();
void SetCtrlLine(const QPointF &controlPoint, const QPointF &splinePoint);

View File

@ -130,3 +130,26 @@ void TST_Misc::TestAbsoluteFilePath()
const QString result = AbsoluteMPath(patternPath, relativeMPath);
QCOMPARE(output, result);
}
//---------------------------------------------------------------------------------------------------------------------
void TST_Misc::TestCLocale_data()
{
QTest::addColumn<qreal>("number");
QTest::addColumn<QString>("expected");
QTest::newRow("10000") << 10000.0 << "10000";
QTest::newRow("10000.5") << 10000.5 << "10000.5";
}
//---------------------------------------------------------------------------------------------------------------------
// Need for testing thousand separator in the C locale.
// Better be sure that the C locale have not thousand separator
void TST_Misc::TestCLocale()
{
QFETCH(qreal, number);
QFETCH(QString, expected);
const QString localized = QString().number(number);
QCOMPARE(localized, expected);
}

View File

@ -44,6 +44,9 @@ private slots:
void TestAbsoluteFilePath_data();
void TestAbsoluteFilePath();
void TestCLocale_data();
void TestCLocale();
private:
Q_DISABLE_COPY(TST_Misc)
};

View File

@ -52,6 +52,12 @@ void TST_QmuTokenParser::IsSingle_data()
QTest::newRow("Empty string") << "" << false;
QTest::newRow("Several spaces") << " " << false;
QTest::newRow("Invalid formula") << "2*)))" << false;
QTest::newRow("Incorrect thousand separator 15 500") << "15 500" << false;
QTest::newRow("Correct C locale 15500") << "15500" << true;
QTest::newRow("Correct C locale 15,500") << "15,500" << true;
QTest::newRow("Correct C locale 15,500.1") << "15,500.1" << true;
QTest::newRow("Not C locale 15,5") << "15,5" << false;
QTest::newRow("Not C locale 15.500,1") << "15.500,1" << false;
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -179,3 +179,51 @@ void TST_VSpline::GetSegmentPoints_TestPuzzle()
// Begin comparison
Comparison(points, origPoints);
}
//---------------------------------------------------------------------------------------------------------------------
void TST_VSpline::CompareThreeWays()
{
// Input data taken from real case
// See the file <root>/src/app/share/collection/TestPuzzle.val
VPointF p1(1168.8582803149607, 39.999874015748034, "p1", 5.0000125984251973, 9.9999874015748045);
VPointF p4(681.33729132409951, 1815.7969526662778, "p4", 5.0000125984251973, 9.9999874015748045);
VSpline spl1(p1, p4, 229.381, 41.6325, 0.96294100000000005, 1.00054, 1);
VSpline spl2(spl1.GetP1(), spl1.GetP2(), spl1.GetP3(), spl1.GetP4(), 1);
VSpline spl3(spl1.GetP1(), spl1.GetP4(), spl1.GetStartAngle(), "", spl2.GetEndAngle(), "", spl2.GetC1Length(), "",
spl2.GetC2Length(), "", 1);
QWARN("Comparing first and second splines.");
CompareSplines(spl1, spl2);
QWARN("Comparing second and third splines.");
CompareSplines(spl2, spl3);
QWARN("Comparing third and first splines.");
CompareSplines(spl3, spl1);
}
//---------------------------------------------------------------------------------------------------------------------
void TST_VSpline::CompareSplines(const VSpline &spl1, const VSpline &spl2) const
{
QCOMPARE(spl1.GetP1().toQPointF().toPoint(), spl2.GetP1().toQPointF().toPoint());
QCOMPARE(spl1.GetP2().toPoint(), spl2.GetP2().toPoint());
QCOMPARE(spl1.GetP3().toPoint(), spl2.GetP3().toPoint());
QCOMPARE(spl1.GetP4().toQPointF().toPoint(), spl2.GetP4().toQPointF().toPoint());
QCOMPARE(spl1.GetStartAngle(), spl2.GetStartAngle());
QCOMPARE(spl1.GetEndAngle(), spl2.GetEndAngle());
QCOMPARE(spl1.GetC1Length(), spl2.GetC1Length());
QCOMPARE(spl1.GetC2Length(), spl2.GetC2Length());
QCOMPARE(spl1.GetLength(), spl2.GetLength());
QCOMPARE(spl1.GetKasm1(), spl2.GetKasm1());
QCOMPARE(spl1.GetKasm2(), spl2.GetKasm2());
QCOMPARE(spl1.GetKcurve(), spl2.GetKcurve());
// Compare points
Comparison(spl1.GetPoints(), spl2.GetPoints());
}

View File

@ -31,6 +31,8 @@
#include "abstracttest.h"
class VSpline;
class TST_VSpline : public AbstractTest
{
Q_OBJECT
@ -43,6 +45,11 @@ private slots:
void GetSegmentPoints();
void GetSegmentPoints_issue412();
void GetSegmentPoints_TestPuzzle();
void CompareThreeWays();
private:
Q_DISABLE_COPY(TST_VSpline)
void CompareSplines(const VSpline &spl1, const VSpline &spl2) const;
};
#endif // TST_VSPLINE_H