Export area of piece in Final measurements.
This commit is contained in:
parent
b4256fb500
commit
d6e417b197
|
@ -7,6 +7,7 @@
|
|||
- Fix option Hide labels.
|
||||
- Improve segmenting a curve for calculating a piece path.
|
||||
- [smart-pattern/valentina#184] Fix incorrect seam allowance.
|
||||
- Export area of piece in Final measurements.
|
||||
|
||||
# Valentina 0.7.52 September 12, 2022
|
||||
- Fix crash when default locale is ru.
|
||||
|
|
|
@ -54,6 +54,8 @@ DialogFinalMeasurements::DialogFinalMeasurements(VPattern *doc, QWidget *parent)
|
|||
setWindowFlags(Qt::Window);
|
||||
#endif
|
||||
|
||||
m_data.FillPiecesAreas(VAbstractValApplication::VApp()->patternUnits());
|
||||
|
||||
ui->lineEditName->setClearButtonEnabled(true);
|
||||
|
||||
ui->lineEditFind->installEventFilter(this);
|
||||
|
@ -449,6 +451,7 @@ void DialogFinalMeasurements::Fx()
|
|||
dialog->setWindowTitle(tr("Edit measurement"));
|
||||
dialog->SetFormula(VTranslateVars::TryFormulaFromUser(ui->plainTextEditFormula->toPlainText(),
|
||||
VAbstractApplication::VApp()->Settings()->GetOsSeparator()));
|
||||
dialog->ShowPieceArea(true);
|
||||
const QString postfix = UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true);
|
||||
dialog->setPostfix(postfix);//Show unit in dialog lable (cm, mm or inch)
|
||||
|
||||
|
@ -466,6 +469,7 @@ void DialogFinalMeasurements::Fx()
|
|||
void DialogFinalMeasurements::FullUpdateFromFile()
|
||||
{
|
||||
m_data = m_doc->GetCompleteData();
|
||||
m_data.FillPiecesAreas(VAbstractValApplication::VApp()->patternUnits());
|
||||
m_measurements = m_doc->GetFinalMeasurements();
|
||||
|
||||
FillFinalMeasurements();
|
||||
|
|
|
@ -1260,7 +1260,8 @@ bool MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, boo
|
|||
}
|
||||
|
||||
const QVector<VFinalMeasurement> measurements = doc->GetFinalMeasurements();
|
||||
const VContainer completeData = doc->GetCompleteData();
|
||||
VContainer completeData = doc->GetCompleteData();
|
||||
completeData.FillPiecesAreas(VAbstractValApplication::VApp()->patternUnits());
|
||||
|
||||
for (int i=0; i < measurements.size(); ++i)
|
||||
{
|
||||
|
|
|
@ -532,7 +532,7 @@ void VPattern::LiteParseIncrements()
|
|||
|
||||
data->ClearUniqueIncrementNames();
|
||||
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 10, "Check that you used all types");
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 11, "Check that you used all types");
|
||||
data->ClearVariables(VarType::Increment);
|
||||
data->ClearVariables(VarType::IncrementSeparator);
|
||||
|
||||
|
@ -929,6 +929,7 @@ void VPattern::ParseDetailElement(QDomElement &domElement, const Document &parse
|
|||
initData.id = GetParametrId(domElement);
|
||||
initData.detail.SetName(GetParametrString(domElement, AttrName, tr("Detail")));
|
||||
initData.detail.SetUUID(GetParametrEmptyString(domElement, AttrUUID));
|
||||
initData.detail.SetShortName(GetParametrEmptyString(domElement, AttrShortName).left(25));
|
||||
initData.detail.SetGradationLabel(GetParametrEmptyString(domElement, AttrGradationLabel));
|
||||
initData.detail.SetMx(VAbstractValApplication::VApp()
|
||||
->toPixel(GetParametrDouble(domElement, AttrMx, QStringLiteral("0.0"))));
|
||||
|
@ -4446,13 +4447,14 @@ void VPattern::PrepareForParse(const Document &parse)
|
|||
}
|
||||
else if (parse == Document::LiteParse || parse == Document::FullLiteParse)
|
||||
{
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 10, "Check that you used all types");
|
||||
QVector<VarType> types({VarType::LineAngle,
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 11, "Check that you used all types");
|
||||
QVector<VarType> types{VarType::LineAngle,
|
||||
VarType::LineLength,
|
||||
VarType::CurveLength,
|
||||
VarType::CurveCLength,
|
||||
VarType::ArcRadius,
|
||||
VarType::CurveAngle});
|
||||
VarType::CurveAngle,
|
||||
VarType::PieceArea};
|
||||
if (parse == Document::FullLiteParse)
|
||||
{
|
||||
types.append(VarType::Increment);
|
||||
|
|
|
@ -49,6 +49,7 @@ const QString AttrType = QStringLiteral("type");
|
|||
const QString AttrMx = QStringLiteral("mx");
|
||||
const QString AttrMy = QStringLiteral("my");
|
||||
const QString AttrName = QStringLiteral("name");
|
||||
const QString AttrShortName = QStringLiteral("shortName");
|
||||
const QString AttrUUID = QStringLiteral("uuid");
|
||||
const QString AttrGradationLabel = QStringLiteral("gradationLabel");
|
||||
const QString AttrMx1 = QStringLiteral("mx1");
|
||||
|
@ -316,31 +317,36 @@ const QString currentLength = QStringLiteral("CurrentLength");
|
|||
const QString currentSeamAllowance = QStringLiteral("CurrentSeamAllowance");
|
||||
const QString rotation_V = QStringLiteral("Rotation");
|
||||
const QString rotationElArc_ = rotation_V + elarc_;
|
||||
const QString pieceArea_ = QStringLiteral("PieceArea_");
|
||||
|
||||
const QStringList builInVariables = QStringList() << measurement_
|
||||
<< increment_
|
||||
<< line_
|
||||
<< angleLine_
|
||||
<< arc_
|
||||
<< elarc_
|
||||
<< spl_
|
||||
<< splPath
|
||||
<< radiusArc_
|
||||
<< radius1ElArc_
|
||||
<< radius2ElArc_
|
||||
<< angle1Arc_
|
||||
<< angle2Arc_
|
||||
<< angle1ElArc_
|
||||
<< angle2ElArc_
|
||||
<< angle1Spl_
|
||||
<< angle2Spl_
|
||||
<< angle1SplPath
|
||||
<< angle2SplPath
|
||||
<< seg_
|
||||
<< currentLength
|
||||
<< currentSeamAllowance
|
||||
<< c1LengthSpl_
|
||||
<< c2LengthSpl_
|
||||
<< c1LengthSplPath
|
||||
<< c2LengthSplPath
|
||||
<< rotationElArc_;
|
||||
const QStringList builInVariables
|
||||
{
|
||||
measurement_,
|
||||
increment_,
|
||||
line_,
|
||||
angleLine_,
|
||||
arc_,
|
||||
elarc_,
|
||||
spl_,
|
||||
splPath,
|
||||
radiusArc_,
|
||||
radius1ElArc_,
|
||||
radius2ElArc_,
|
||||
angle1Arc_,
|
||||
angle2Arc_,
|
||||
angle1ElArc_,
|
||||
angle2ElArc_,
|
||||
angle1Spl_,
|
||||
angle2Spl_,
|
||||
angle1SplPath,
|
||||
angle2SplPath,
|
||||
seg_,
|
||||
currentLength,
|
||||
currentSeamAllowance,
|
||||
c1LengthSpl_,
|
||||
c2LengthSpl_,
|
||||
c1LengthSplPath,
|
||||
c2LengthSplPath,
|
||||
rotationElArc_,
|
||||
pieceArea_
|
||||
};
|
||||
|
|
|
@ -68,6 +68,7 @@ extern const QString AttrType;
|
|||
extern const QString AttrMx;
|
||||
extern const QString AttrMy;
|
||||
extern const QString AttrName;
|
||||
extern const QString AttrShortName;
|
||||
extern const QString AttrUUID;
|
||||
extern const QString AttrGradationLabel;
|
||||
extern const QString AttrMx1;
|
||||
|
@ -241,6 +242,7 @@ extern const QString currentLength;
|
|||
extern const QString currentSeamAllowance;
|
||||
extern const QString rotation_V;
|
||||
extern const QString rotationElArc_;
|
||||
extern const QString pieceArea_;
|
||||
|
||||
extern const QStringList builInVariables;
|
||||
|
||||
|
|
|
@ -744,6 +744,7 @@
|
|||
<xs:attribute name="mx" type="xs:double"/>
|
||||
<xs:attribute name="my" type="xs:double"/>
|
||||
<xs:attribute name="name" type="xs:string"/>
|
||||
<xs:attribute name="shortName" type="pieceShortName"/>
|
||||
<xs:attribute name="uuid" type="uuid"/>
|
||||
<xs:attribute name="gradationLabel" type="xs:string"/>
|
||||
<xs:attribute name="bufferName" type="xs:string"/>
|
||||
|
@ -820,7 +821,12 @@
|
|||
</xs:element>
|
||||
<xs:simpleType name="shortName">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="([^\p{Nd}\p{Zs}*/&|!<>^ \()\-−+.,٫, ٬.’=?:;'\"]){1,1}([^\p{Zs}*/&|!<>^ \()\-−+.,٫, ٬.’=?:;\"]){0,}"/>
|
||||
<xs:pattern value="([^\p{Nd}\p{Zs}*\/&|!<>^ \()\-−+.,٫, ٬.’=?:;'\"]){1,1}([^\p{Zs}*\/&|!<>^ \()\-−+.,٫, ٬.’=?:;\"]){0,}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="pieceShortName">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="([^\p{Zs}*\/&|!<>^ \()\-−+.,٫, ٬.’=?:;\"]){0,}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="uuid">
|
||||
|
|
|
@ -326,8 +326,8 @@ QString NameRegExp()
|
|||
// Here we use permanent start of string and end of string anchors \A and \z to match whole pattern as one
|
||||
// string. In some cases, a user may pass multiline or line that ends with a new line. To cover case with a new
|
||||
// line at the end of string use /z anchor.
|
||||
regex = QString("\\A([^\\p{Nd}\\p{Zs}*/&|!<>^\\n\\()%1%2%3%4=?:;'\"]){1,1}"
|
||||
"([^\\p{Zs}*/&|!<>^\\n\\()%1%2%3%4=?:;\"]){0,}\\z")
|
||||
regex = QString("\\A([^\\p{Nd}\\p{Zs}*\\/&|!<>^\\n\\()%1%2%3%4=?:;'\"]){1,1}"
|
||||
"([^\\p{Zs}*\\/&|!<>^\\n\\()%1%2%3%4=?:;\"]){0,}\\z")
|
||||
.arg(negativeSigns, positiveSigns, decimalPoints, groupSeparators);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ auto ConvertInternalPaths(const VPiece &piece, const VContainer *pattern) -> QVe
|
|||
{
|
||||
SCASSERT(pattern != nullptr)
|
||||
|
||||
piece.TestInternalPaths(pattern);
|
||||
|
||||
QVector<VLayoutPiecePath> paths;
|
||||
const QVector<quint32> pathsId = piece.GetInternalPaths();
|
||||
const QVector<QPointF> cuttingPath = piece.CuttingPathPoints(pattern);
|
||||
|
|
|
@ -275,7 +275,7 @@ enum class Vis : ToolVisHolderType
|
|||
};
|
||||
|
||||
enum class VarType : qint8 { Measurement, MeasurementSeparator, Increment, IncrementSeparator, LineLength, CurveLength,
|
||||
CurveCLength, LineAngle, CurveAngle, ArcRadius, Unknown };
|
||||
CurveCLength, LineAngle, CurveAngle, ArcRadius, PieceArea, Unknown };
|
||||
|
||||
enum class IncrementType : qint8 { Increment, Separator };
|
||||
|
||||
|
@ -398,9 +398,9 @@ Q_DECL_RELAXED_CONSTEXPR inline auto ToPixel(double val, const Unit &unit) -> do
|
|||
return 0;
|
||||
}
|
||||
|
||||
template<typename T> constexpr inline auto PixelToMm(T pix) -> T { return (pix / PrintDPI) * 25.4; }
|
||||
template<typename T> constexpr inline auto PixelToCm(T pix) -> T { return ((pix / PrintDPI) * 25.4) / 10.0; }
|
||||
template<typename T> constexpr inline auto PixelToInch(T pix) -> T { return pix / PrintDPI; }
|
||||
template<typename T> constexpr inline auto PixelToInch(T pix) -> T {return pix / PrintDPI;}
|
||||
template<typename T> constexpr inline auto PixelToMm(T pix) -> T {return PixelToInch(pix) * 25.4;}
|
||||
template<typename T> constexpr inline auto PixelToCm(T pix) -> T {return PixelToInch(pix) * 2.54;}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
Q_DECL_RELAXED_CONSTEXPR inline auto FromPixel(double pix, const Unit &unit) -> double
|
||||
|
@ -421,6 +421,52 @@ Q_DECL_RELAXED_CONSTEXPR inline auto FromPixel(double pix, const Unit &unit) ->
|
|||
return 0;
|
||||
}
|
||||
|
||||
template<typename T> constexpr inline auto Inch2ToPixel2(T val) -> T {return val * (PrintDPI * PrintDPI);}
|
||||
template<typename T> constexpr inline auto Mm2ToPixel2(T val) -> T {return Inch2ToPixel2(val * 0.001550031);}
|
||||
template<typename T> constexpr inline auto Cm2ToPixel2(T val) -> T {return Inch2ToPixel2(val * 0.15500031);}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
Q_DECL_RELAXED_CONSTEXPR inline auto ToPixel2(double val, const Unit &unit) -> double
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
case Unit::Mm:
|
||||
return Mm2ToPixel2(val);
|
||||
case Unit::Cm:
|
||||
return Cm2ToPixel2(val);
|
||||
case Unit::Inch:
|
||||
return Inch2ToPixel2(val);
|
||||
case Unit::Px:
|
||||
return val;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T> constexpr inline auto Pixel2ToInch2(T pix) -> T { return pix / (PrintDPI * PrintDPI);}
|
||||
template<typename T> constexpr inline auto Pixel2ToMm2(T pix) -> T { return Pixel2ToInch2(pix) / 0.001550031;}
|
||||
template<typename T> constexpr inline auto Pixel2ToCm2(T pix) -> T { return Pixel2ToInch2(pix) / 0.15500031;}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
Q_DECL_RELAXED_CONSTEXPR inline auto FromPixel2(double pix, const Unit &unit) -> double
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
case Unit::Mm:
|
||||
return Pixel2ToMm2(pix);
|
||||
case Unit::Cm:
|
||||
return Pixel2ToCm2(pix);
|
||||
case Unit::Inch:
|
||||
return Pixel2ToInch2(pix);
|
||||
case Unit::Px:
|
||||
return pix;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
Q_DECL_RELAXED_CONSTEXPR inline auto UnitConvertor(qreal value, const Unit &from, const Unit &to) -> qreal
|
||||
{
|
||||
|
|
|
@ -54,15 +54,15 @@ public:
|
|||
{
|
||||
// When we create an increment in the dialog it will get neccesary data. Such data must be removed because will
|
||||
// confuse a user. Increment should not know nothing about internal variables.
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 10, "Check that you used all types");
|
||||
this->data->ClearVariables(QVector<VarType>({VarType::LineAngle,
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 11, "Check that you used all types");
|
||||
this->data->ClearVariables(QVector<VarType>{VarType::LineAngle,
|
||||
VarType::LineLength,
|
||||
VarType::CurveLength,
|
||||
VarType::CurveCLength,
|
||||
VarType::ArcRadius,
|
||||
VarType::CurveAngle,
|
||||
VarType::IncrementSeparator
|
||||
}));
|
||||
VarType::IncrementSeparator,
|
||||
VarType::PieceArea});
|
||||
}
|
||||
|
||||
VIncrementData(const VIncrementData &incr)
|
||||
|
|
|
@ -78,12 +78,12 @@ VLineAngle &VLineAngle::operator=(const VLineAngle &var)
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VLineAngle::VLineAngle(VLineAngle &&var) Q_DECL_NOTHROW
|
||||
:VInternalVariable(std::move(var)), d(std::move(var.d))
|
||||
{}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VLineAngle &VLineAngle::operator=(VLineAngle &&var) Q_DECL_NOTHROW
|
||||
{
|
||||
|
|
107
src/libs/vpatterndb/variables/vpiecearea.cpp
Normal file
107
src/libs/vpatterndb/variables/vpiecearea.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpiecearea.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 8 11, 2022
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2022 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#include "vpiecearea.h"
|
||||
#include "vpiecearea_p.h"
|
||||
#include "../vpatterndb/vpiece.h"
|
||||
#include "../vpatterndb/vcontainer.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceArea::VPieceArea()
|
||||
:d(new VPieceAreaData)
|
||||
{
|
||||
SetType(VarType::PieceArea);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceArea::VPieceArea(quint32 pieceId, const VPiece &piece, const VContainer *data, Unit unit)
|
||||
:d(new VPieceAreaData(pieceId))
|
||||
{
|
||||
// cppcheck-suppress unknownMacro
|
||||
SCASSERT(data != nullptr)
|
||||
|
||||
SetType(VarType::PieceArea);
|
||||
|
||||
QString shortName = piece.GetShortName();
|
||||
if (shortName.isEmpty())
|
||||
{
|
||||
shortName = piece.GetName().replace(QChar(QChar::Space), '_').left(25);
|
||||
if (shortName.isEmpty() || not QRegularExpression(VPiece::ShortNameRegExp()).match(shortName).hasMatch())
|
||||
{
|
||||
shortName = QObject::tr("Unknown");
|
||||
}
|
||||
}
|
||||
SetName(pieceArea_ + shortName);
|
||||
VInternalVariable::SetValue(FromPixel2(piece.Area(data), unit));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceArea::operator=(const VPieceArea &var) -> VPieceArea &
|
||||
{
|
||||
if ( &var == this )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
VInternalVariable::operator=(var);
|
||||
d = var.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceArea::VPieceArea(VPieceArea &&var) Q_DECL_NOTHROW
|
||||
:VInternalVariable(std::move(var)), d(std::move(var.d))
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceArea::~VPieceArea() // NOLINT(modernize-use-equals-default)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceArea::operator=(VPieceArea &&var) Q_DECL_NOTHROW -> VPieceArea &
|
||||
{
|
||||
VInternalVariable::operator=(var);
|
||||
std::swap(d, var.d);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceArea::SetValue(quint32 pieceId, const VPiece &piece, const VContainer *data, Unit unit)
|
||||
{
|
||||
SCASSERT(data != nullptr)
|
||||
d->m_pieceId = pieceId;
|
||||
VInternalVariable::SetValue(FromPixel(piece.Area(data), unit));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceArea::GetPieceId() const -> quint32
|
||||
{
|
||||
return d->m_pieceId;
|
||||
}
|
60
src/libs/vpatterndb/variables/vpiecearea.h
Normal file
60
src/libs/vpatterndb/variables/vpiecearea.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpiecearea.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 8 11, 2022
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2022 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#ifndef VPIECEAREA_H
|
||||
#define VPIECEAREA_H
|
||||
|
||||
#include "vinternalvariable.h"
|
||||
|
||||
class VPiece;
|
||||
class VContainer;
|
||||
class VPieceAreaData;
|
||||
|
||||
class VPieceArea final :public VInternalVariable
|
||||
{
|
||||
public:
|
||||
VPieceArea();
|
||||
explicit VPieceArea(quint32 pieceId, const VPiece &piece, const VContainer *data, Unit unit);
|
||||
VPieceArea(const VPieceArea &var) = default;
|
||||
~VPieceArea() override;
|
||||
|
||||
auto operator=(const VPieceArea &var) -> VPieceArea &;
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
VPieceArea(VPieceArea &&var) Q_DECL_NOTHROW;
|
||||
auto operator=(VPieceArea &&var) Q_DECL_NOTHROW -> VPieceArea &;
|
||||
#endif
|
||||
|
||||
void SetValue(quint32 pieceId, const VPiece &piece, const VContainer *data, Unit unit);
|
||||
|
||||
auto GetPieceId() const -> quint32;
|
||||
private:
|
||||
QSharedDataPointer<VPieceAreaData> d;
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(VPieceArea, Q_MOVABLE_TYPE); // NOLINT
|
||||
|
||||
#endif // VPIECEAREA_H
|
60
src/libs/vpatterndb/variables/vpiecearea_p.h
Normal file
60
src/libs/vpatterndb/variables/vpiecearea_p.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpiecearea_p.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 9 11, 2022
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2022 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#ifndef VPIECEAREA_P_H
|
||||
#define VPIECEAREA_P_H
|
||||
|
||||
#include <QSharedData>
|
||||
|
||||
#include "../vmisc/defglobal.h"
|
||||
#include "../vmisc/typedef.h"
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_GCC("-Weffc++")
|
||||
QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
|
||||
|
||||
class VPieceAreaData final : public QSharedData
|
||||
{
|
||||
public:
|
||||
VPieceAreaData() = default;
|
||||
|
||||
explicit VPieceAreaData(quint32 pieceId)
|
||||
: m_pieceId(pieceId)
|
||||
{}
|
||||
|
||||
VPieceAreaData(const VPieceAreaData &var) = default;
|
||||
~VPieceAreaData() = default;
|
||||
|
||||
quint32 m_pieceId{NULL_ID}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
|
||||
private:
|
||||
Q_DISABLE_ASSIGN_MOVE(VPieceAreaData) // NOLINT
|
||||
};
|
||||
|
||||
QT_WARNING_POP
|
||||
|
||||
#endif // VPIECEAREA_P_H
|
|
@ -52,6 +52,7 @@
|
|||
#include "variables/vlineangle.h"
|
||||
#include "variables/vlinelength.h"
|
||||
#include "variables/vmeasurement.h"
|
||||
#include "variables/vpiecearea.h"
|
||||
#include "vtranslatevars.h"
|
||||
|
||||
QT_WARNING_PUSH
|
||||
|
@ -391,15 +392,16 @@ void VContainer::ClearForFullParse()
|
|||
|
||||
d->pieces->clear();
|
||||
d->piecePaths->clear();
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 10, "Check that you used all types");
|
||||
ClearVariables(QVector<VarType>({VarType::Increment,
|
||||
Q_STATIC_ASSERT_X(static_cast<int>(VarType::Unknown) == 11, "Check that you used all types");
|
||||
ClearVariables(QVector<VarType>{VarType::Increment,
|
||||
VarType::IncrementSeparator,
|
||||
VarType::LineAngle,
|
||||
VarType::LineLength,
|
||||
VarType::CurveLength,
|
||||
VarType::CurveCLength,
|
||||
VarType::ArcRadius,
|
||||
VarType::CurveAngle}));
|
||||
VarType::CurveAngle,
|
||||
VarType::PieceArea});
|
||||
ClearGObjects();
|
||||
ClearUniqueNames();
|
||||
}
|
||||
|
@ -570,6 +572,19 @@ void VContainer::RemoveIncrement(const QString &name)
|
|||
d->variables.remove(name);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VContainer::FillPiecesAreas(Unit unit)
|
||||
{
|
||||
QHash<quint32, VPiece> *pieces = d->pieces.data();
|
||||
|
||||
auto i = pieces->constBegin();
|
||||
while (i != pieces->constEnd())
|
||||
{
|
||||
AddVariable(QSharedPointer<VPieceArea>::create(i.key(), i.value(), this, unit));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
const QMap<QString, QSharedPointer<VMeasurement> > VContainer::DataMeasurements() const
|
||||
{
|
||||
|
@ -650,6 +665,12 @@ const QMap<QString, QSharedPointer<VCurveAngle> > VContainer::DataAnglesCurves()
|
|||
return DataVar<VCurveAngle>(VarType::CurveAngle);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
const QMap<QString, QSharedPointer<VPieceArea> > VContainer::DataPieceArea() const
|
||||
{
|
||||
return DataVar<VPieceArea>(VarType::PieceArea);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VContainer::IsUnique(const QString &name) const
|
||||
{
|
||||
|
|
|
@ -58,6 +58,15 @@
|
|||
#include "vtranslatevars.h"
|
||||
|
||||
class VEllipticalArc;
|
||||
class VMeasurement;
|
||||
class VIncrement;
|
||||
class VLengthLine;
|
||||
class VCurveLength;
|
||||
class VCurveCLength;
|
||||
class VLineAngle;
|
||||
class VArcRadius;
|
||||
class VCurveAngle;
|
||||
class VPieceArea;
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_GCC("-Weffc++")
|
||||
|
@ -195,6 +204,8 @@ public:
|
|||
|
||||
void RemoveIncrement(const QString& name);
|
||||
|
||||
void FillPiecesAreas(Unit unit);
|
||||
|
||||
const QHash<quint32, QSharedPointer<VGObject> > *CalculationGObjects() const;
|
||||
const QHash<quint32, VPiece> *DataPieces() const;
|
||||
const QHash<QString, QSharedPointer<VInternalVariable>> *DataVariables() const;
|
||||
|
@ -209,6 +220,7 @@ public:
|
|||
const QMap<QString, QSharedPointer<VLineAngle> > DataAngleLines() const;
|
||||
const QMap<QString, QSharedPointer<VArcRadius> > DataRadiusesArcs() const;
|
||||
const QMap<QString, QSharedPointer<VCurveAngle> > DataAnglesCurves() const;
|
||||
const QMap<QString, QSharedPointer<VPieceArea> > DataPieceArea() const;
|
||||
|
||||
bool IsUnique(const QString &name) const;
|
||||
static bool IsUnique(const QString &name, const QString &nspace);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
SOURCES += \
|
||||
$$PWD/testpassmark.cpp \
|
||||
$$PWD/variables/vpiecearea.cpp \
|
||||
$$PWD/vcontainer.cpp \
|
||||
$$PWD/calculator.cpp \
|
||||
$$PWD/vnodedetail.cpp \
|
||||
|
@ -34,6 +35,8 @@ SOURCES += \
|
|||
|
||||
HEADERS += \
|
||||
$$PWD/testpassmark.h \
|
||||
$$PWD/variables/vpiecearea.h \
|
||||
$$PWD/variables/vpiecearea_p.h \
|
||||
$$PWD/vcontainer.h \
|
||||
$$PWD/stable.h \
|
||||
$$PWD/calculator.h \
|
||||
|
|
|
@ -37,8 +37,10 @@
|
|||
#include "../vmisc/vabstractvalapplication.h"
|
||||
#include "../vmisc/compatibility.h"
|
||||
#include "../ifc/exception/vexceptioninvalidnotch.h"
|
||||
#include "../ifc/exception/vexceptionobjecterror.h"
|
||||
#include "../vmisc/testpath.h"
|
||||
#include "../ifc/xml/vabstractpattern.h"
|
||||
#include "../vpatterndb/vpiecenode.h"
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QDebug>
|
||||
|
@ -390,6 +392,18 @@ void VPiece::SetUnited(bool united)
|
|||
d->m_united = united;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPiece::GetShortName() const -> QString
|
||||
{
|
||||
return d->m_shortName;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPiece::SetShortName(const QString &value)
|
||||
{
|
||||
d->m_shortName = value;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QString VPiece::GetFormulaSAWidth() const
|
||||
{
|
||||
|
@ -1197,6 +1211,126 @@ auto VPiece::GlobalPassmarkLength(const VContainer *data) const -> qreal
|
|||
return length;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPiece::TestInternalPathCuttingPathIntersection(const VContainer *data) const
|
||||
{
|
||||
SCASSERT(data != nullptr)
|
||||
|
||||
const QVector<QPointF> cuttingPoints = CuttingPathPoints(data);
|
||||
const QPainterPath contourPath = VAbstractPiece::PainterPath(cuttingPoints);
|
||||
|
||||
// Internal path for cutting must not intersect cutting contour and be inside of it.
|
||||
const QVector<quint32> pathsId = GetInternalPaths();
|
||||
for (auto id : pathsId)
|
||||
{
|
||||
const VPiecePath path = data->GetPiecePath(id);
|
||||
if (path.GetType() != PiecePathType::InternalPath || not path.IsVisible(data->DataVariables()) ||
|
||||
not path.IsCutPath())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QVector<QPointF> points;
|
||||
CastTo(path.PathPoints(data, cuttingPoints), points);
|
||||
if (points.isEmpty() || not VFuzzyComparePoints(ConstFirst(points), ConstLast(points)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const QPainterPath internalPath = VAbstractPiece::PainterPath(points);
|
||||
|
||||
if (internalPath.intersects(contourPath))
|
||||
{
|
||||
const QString errorMsg = QObject::tr("Piece '%1'. Internal path '%2' intersects with cutting "
|
||||
"countour.").arg(GetName(), path.GetName());
|
||||
VAbstractApplication::VApp()->IsPedantic() ? throw VExceptionObjectError(errorMsg) :
|
||||
qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (not contourPath.contains(internalPath))
|
||||
{
|
||||
const QString errorMsg = QObject::tr("Piece '%1'. Internal path '%2' not inside of cutting "
|
||||
"countour.").arg(GetName(), path.GetName());
|
||||
VAbstractApplication::VApp()->IsPedantic() ? throw VExceptionObjectError(errorMsg) :
|
||||
qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPiece::TestInternalPathsIntersections(const VContainer *data) const
|
||||
{
|
||||
SCASSERT(data != nullptr)
|
||||
|
||||
const QVector<quint32> pathsId = GetInternalPaths();
|
||||
|
||||
if (pathsId.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector<QPointF> cuttingPoints = CuttingPathPoints(data);
|
||||
|
||||
// Internal pieces for cutting must not intersect
|
||||
QSet<QPair<int, int>> pairs;
|
||||
for (int k=0; k < pathsId.size(); ++k)
|
||||
{
|
||||
const VPiecePath path1 = data->GetPiecePath(pathsId.at(k));
|
||||
|
||||
if (path1.GetType() != PiecePathType::InternalPath || not path1.IsVisible(data->DataVariables()) ||
|
||||
not path1.IsCutPath())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QVector<QPointF> pointsPath1;
|
||||
CastTo(path1.PathPoints(data, cuttingPoints), pointsPath1);
|
||||
if (pointsPath1.isEmpty() || not VFuzzyComparePoints(ConstFirst(pointsPath1), ConstLast(pointsPath1)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const QPainterPath painterPath1 = VAbstractPiece::PainterPath(pointsPath1);
|
||||
|
||||
for (int i=0; i < pathsId.size(); ++i)
|
||||
{
|
||||
if (k == i || pairs.contains(qMakePair(k, i)) || pairs.contains(qMakePair(i, k)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const VPiecePath path2 = data->GetPiecePath(pathsId.at(i));
|
||||
|
||||
if (path2.GetType() != PiecePathType::InternalPath || not path2.IsVisible(data->DataVariables()) ||
|
||||
not path2.IsCutPath())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QVector<QPointF> pointsPath2;
|
||||
CastTo(path2.PathPoints(data, cuttingPoints), pointsPath2);
|
||||
if (pointsPath2.isEmpty() || not VFuzzyComparePoints(ConstFirst(pointsPath2), ConstLast(pointsPath2)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const QPainterPath painterPath2 = VAbstractPiece::PainterPath(pointsPath2);
|
||||
|
||||
pairs.insert(qMakePair(k, i));
|
||||
pairs.insert(qMakePair(i, k));
|
||||
|
||||
if (painterPath1.intersects(painterPath2))
|
||||
{
|
||||
const QString errorMsg = QObject::tr("Piece '%1'. Internal path '%2' intersects with internal path "
|
||||
"'%3'.").arg(GetName(), path1.GetName(), path2.GetName());
|
||||
VAbstractApplication::VApp()->IsPedantic() ? throw VExceptionObjectError(errorMsg) :
|
||||
qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPiece::DumpPiece(const VPiece &piece, const VContainer *data, const QString &templateName)
|
||||
{
|
||||
|
@ -1239,4 +1373,96 @@ void VPiece::DumpPiece(const VPiece &piece, const VContainer *data, const QStrin
|
|||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPiece::TestInternalPaths(const VContainer *data) const
|
||||
{
|
||||
TestInternalPathCuttingPathIntersection(data);
|
||||
TestInternalPathsIntersections(data);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPiece::Area(const VContainer *data) const -> qreal
|
||||
{
|
||||
SCASSERT(data != nullptr)
|
||||
|
||||
const QVector<QPointF> mainContour = CuttingPathPoints(data);
|
||||
const qreal mainArea = qAbs(VAbstractPiece::SumTrapezoids(mainContour))/2.0;
|
||||
|
||||
qreal internalPathArea = 0;
|
||||
const QVector<quint32> pathsId = GetInternalPaths();
|
||||
for (auto id : pathsId)
|
||||
{
|
||||
const VPiecePath path = data->GetPiecePath(id);
|
||||
if (path.GetType() != PiecePathType::InternalPath || not path.IsVisible(data->DataVariables()) ||
|
||||
not path.IsCutPath())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QVector<QPointF> points;
|
||||
CastTo(path.PathPoints(data, mainContour), points);
|
||||
if (points.isEmpty() || not VFuzzyComparePoints(ConstFirst(points), ConstLast(points)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
internalPathArea += qAbs(VAbstractPiece::SumTrapezoids(points))/2.0;
|
||||
}
|
||||
|
||||
return mainArea - internalPathArea;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPiece::ShortNameRegExp() -> QString
|
||||
{
|
||||
static QString regex;
|
||||
|
||||
if (regex.isEmpty())
|
||||
{
|
||||
const QList<QLocale> allLocales =
|
||||
QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||
|
||||
QString positiveSigns;
|
||||
QString negativeSigns;
|
||||
QString decimalPoints;
|
||||
QString groupSeparators;
|
||||
|
||||
for(const auto &locale : allLocales)
|
||||
{
|
||||
if (not positiveSigns.contains(locale.positiveSign()))
|
||||
{
|
||||
positiveSigns.append(locale.positiveSign());
|
||||
}
|
||||
|
||||
if (not negativeSigns.contains(locale.negativeSign()))
|
||||
{
|
||||
negativeSigns.append(locale.negativeSign());
|
||||
}
|
||||
|
||||
if (not decimalPoints.contains(locale.decimalPoint()))
|
||||
{
|
||||
decimalPoints.append(locale.decimalPoint());
|
||||
}
|
||||
|
||||
if (not groupSeparators.contains(locale.groupSeparator()))
|
||||
{
|
||||
groupSeparators.append(locale.groupSeparator());
|
||||
}
|
||||
}
|
||||
|
||||
negativeSigns.replace('-', QLatin1String("\\-"));
|
||||
groupSeparators.remove('\'');
|
||||
|
||||
//Same regexp in pattern.xsd shema file. Don't forget to synchronize.
|
||||
// \p{Zs} - \p{Space_Separator}
|
||||
// Here we use permanent start of string and end of string anchors \A and \z to match whole pattern as one
|
||||
// string. In some cases, a user may pass multiline or line that ends with a new line. To cover case with a new
|
||||
// line at the end of string use /z anchor.
|
||||
regex = QStringLiteral("\\A([^\\p{Zs}*\\/&|!<>^\\n\\()%1%2%3%4=?:;\"]){0,}\\z")
|
||||
.arg(negativeSigns, positiveSigns, decimalPoints, groupSeparators);
|
||||
}
|
||||
|
||||
return regex;
|
||||
}
|
||||
#endif // !defined(V_NO_ASSERT)
|
||||
|
|
|
@ -92,6 +92,9 @@ public:
|
|||
bool IsUnited() const;
|
||||
void SetUnited(bool united);
|
||||
|
||||
auto GetShortName() const -> QString;
|
||||
void SetShortName(const QString &value);
|
||||
|
||||
QString GetFormulaSAWidth() const;
|
||||
void SetFormulaSAWidth(const QString &formula, qreal value);
|
||||
|
||||
|
@ -138,6 +141,11 @@ public:
|
|||
auto GetGradationLabel() const -> QString;
|
||||
|
||||
static void DumpPiece(const VPiece &piece, const VContainer *data, const QString &templateName=QString());
|
||||
|
||||
void TestInternalPaths(const VContainer *data) const;
|
||||
|
||||
static auto ShortNameRegExp() -> QString;
|
||||
auto Area(const VContainer *data) const -> qreal;
|
||||
private:
|
||||
QSharedDataPointer<VPieceData> d;
|
||||
|
||||
|
@ -163,6 +171,9 @@ private:
|
|||
QJsonObject DBToJson(const VContainer *data) const;
|
||||
|
||||
qreal GlobalPassmarkLength(const VContainer *data) const;
|
||||
|
||||
void TestInternalPathCuttingPathIntersection(const VContainer *data) const;
|
||||
void TestInternalPathsIntersections(const VContainer *data) const;
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(VPiece, Q_MOVABLE_TYPE); // NOLINT
|
||||
|
|
|
@ -80,6 +80,8 @@ public:
|
|||
|
||||
QString m_gradationLabel{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
|
||||
QString m_shortName{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
|
||||
private:
|
||||
Q_DISABLE_ASSIGN_MOVE(VPieceData) // NOLINT
|
||||
};
|
||||
|
|
|
@ -393,6 +393,7 @@ void VTranslateVars::InitVariables()
|
|||
variables.insert(c2LengthSplPath, translate("VTranslateVars", "C2LengthSplPath",
|
||||
"Do not add symbol _ to the end of the name"));
|
||||
variables.insert(rotationElArc_, translate("VTranslateVars", "RotationElArc_", "Left symbol _ in the name"));
|
||||
variables.insert(pieceArea_, translate("VTranslateVars", "PieceArea_", "Left symbol _ in the name"));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "../vpatterndb/variables/vlineangle.h"
|
||||
#include "../vpatterndb/variables/vlinelength.h"
|
||||
#include "../vpatterndb/variables/vmeasurement.h"
|
||||
#include "../vpatterndb/variables/vpiecearea.h"
|
||||
#include "../vmisc/def.h"
|
||||
#include "../vmisc/vabstractapplication.h"
|
||||
#include "../vmisc/vcommonsettings.h"
|
||||
|
@ -85,6 +86,8 @@ DialogEditWrongFormula::DialogEditWrongFormula(const VContainer *data, quint32 t
|
|||
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->radioButtonPieceArea->setVisible(false);
|
||||
|
||||
timerFormula->setSingleShot(true);
|
||||
connect(timerFormula, &QTimer::timeout, this, &DialogEditWrongFormula::EvalFormula);
|
||||
|
||||
|
@ -233,6 +236,34 @@ void DialogEditWrongFormula::ValChanged(int row)
|
|||
SetDescription(item->text(), *m_data->GetVariable<VCurveAngle>(name)->GetValue(), specialUnits,
|
||||
tr("Curve angle"));
|
||||
}
|
||||
else if (ui->radioButtonCLength->isChecked())
|
||||
{
|
||||
const bool specialUnits = false;
|
||||
SetDescription(item->text(), *m_data->GetVariable<VCurveCLength>(name)->GetValue(), specialUnits,
|
||||
tr("Length to control point"));
|
||||
}
|
||||
else if (ui->radioButtonPieceArea->isChecked())
|
||||
{
|
||||
const bool specialUnits = false;
|
||||
const QSharedPointer<VPieceArea> var = m_data->GetVariable<VPieceArea>(name);
|
||||
QString description = tr("Area of piece");
|
||||
|
||||
try
|
||||
{
|
||||
VPiece piece = m_data->GetPiece(var->GetPieceId());
|
||||
QString name = piece.GetName();
|
||||
if (not name.isEmpty())
|
||||
{
|
||||
description += QStringLiteral(" '%1'").arg(piece.GetName());
|
||||
}
|
||||
}
|
||||
catch (const VExceptionBadId &)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
SetDescription(item->text(), *var->GetValue(), specialUnits, description, true);
|
||||
}
|
||||
else if (ui->radioButtonFunctions->isChecked())
|
||||
{
|
||||
ui->labelDescription->setText(item->toolTip());
|
||||
|
@ -356,6 +387,13 @@ void DialogEditWrongFormula::PreviewCalculations()
|
|||
ShowIncrementsInPreviewCalculation(true);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogEditWrongFormula::PieceArea()
|
||||
{
|
||||
ui->checkBoxHideEmpty->setEnabled(false);
|
||||
ShowVariable(m_data->DataPieceArea());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Functions show in list functions
|
||||
|
@ -479,6 +517,12 @@ void DialogEditWrongFormula::SetPreviewCalculationsMode()
|
|||
ui->radioButtonCLength->setDisabled(true);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogEditWrongFormula::ShowPieceArea(bool show) const
|
||||
{
|
||||
ui->radioButtonPieceArea->setVisible(show);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto DialogEditWrongFormula::GetFormula() const -> QString
|
||||
{
|
||||
|
@ -523,6 +567,9 @@ void DialogEditWrongFormula::InitVariables()
|
|||
connect(ui->radioButtonCLength, &QRadioButton::clicked, this, &DialogEditWrongFormula::CurvesCLength);
|
||||
connect(ui->radioButtonCLength, &QRadioButton::clicked, this, ClearFilterFormulaInputs);
|
||||
|
||||
connect(ui->radioButtonPieceArea, &QRadioButton::clicked, this, &DialogEditWrongFormula::PieceArea);
|
||||
connect(ui->radioButtonPieceArea, &QRadioButton::clicked, this, ClearFilterFormulaInputs);
|
||||
|
||||
connect(ui->radioButtonFunctions, &QRadioButton::clicked, this, &DialogEditWrongFormula::Functions);
|
||||
connect(ui->radioButtonFunctions, &QRadioButton::clicked, this, ClearFilterFormulaInputs);
|
||||
|
||||
|
@ -531,9 +578,15 @@ void DialogEditWrongFormula::InitVariables()
|
|||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogEditWrongFormula::SetDescription(const QString &name, qreal value, bool specialUnits,
|
||||
const QString &description)
|
||||
const QString &description, bool square)
|
||||
{
|
||||
const QString unit = specialUnits ? degreeSymbol : ' ' + postfix;
|
||||
QString unitName = postfix;
|
||||
if (not specialUnits && square)
|
||||
{
|
||||
unitName += QStringLiteral("²");
|
||||
}
|
||||
|
||||
const QString unit = specialUnits ? degreeSymbol : ' ' + unitName;
|
||||
const QString desc = QStringLiteral("%1(%2%3) - %4").arg(name).arg(value).arg(unit, description);
|
||||
ui->labelDescription->setText(desc);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
void SetMeasurementsMode();
|
||||
void SetIncrementsMode();
|
||||
void SetPreviewCalculationsMode();
|
||||
void ShowPieceArea(bool show) const;
|
||||
public slots:
|
||||
virtual void DialogAccepted();
|
||||
virtual void DialogRejected();
|
||||
|
@ -90,6 +91,7 @@ public slots:
|
|||
void AngleLines();
|
||||
void Increments();
|
||||
void PreviewCalculations();
|
||||
void PieceArea();
|
||||
void Functions();
|
||||
signals:
|
||||
/**
|
||||
|
@ -144,7 +146,8 @@ private:
|
|||
void ShowFunctions();
|
||||
void ShowIncrementsInPreviewCalculation(bool show);
|
||||
|
||||
void SetDescription(const QString &name, qreal value, bool specialUnits, const QString &description);
|
||||
void SetDescription(const QString &name, qreal value, bool specialUnits, const QString &description,
|
||||
bool square = false);
|
||||
|
||||
auto Eval(const FormulaData &formulaData, bool &flag) -> qreal;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>542</width>
|
||||
<height>481</height>
|
||||
<height>483</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -171,7 +171,7 @@
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="">
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="3,1">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
|
@ -309,6 +309,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonPieceArea">
|
||||
<property name="text">
|
||||
<string>Pieces areas</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonFunctions">
|
||||
<property name="sizePolicy">
|
||||
|
|
|
@ -357,6 +357,7 @@ void DialogSeamAllowance::SetPiece(const VPiece &piece)
|
|||
uiTabPaths->checkBoxBuiltIn->setChecked(piece.IsSeamAllowanceBuiltIn());
|
||||
uiTabPaths->lineEditName->setText(piece.GetName());
|
||||
uiTabPaths->lineEditUUID->setText(piece.GetUUID().toString());
|
||||
uiTabPaths->lineEditShortName->setText(piece.GetShortName());
|
||||
uiTabPaths->lineEditGradationLabel->setText(piece.GetGradationLabel());
|
||||
uiTabPaths->spinBoxPriority->setValue(static_cast<int>(piece.GetPriority()));
|
||||
|
||||
|
@ -2600,6 +2601,7 @@ VPiece DialogSeamAllowance::CreatePiece() const
|
|||
piece.SetHideMainPath(uiTabPaths->checkBoxHideMainPath->isChecked());
|
||||
piece.SetName(uiTabPaths->lineEditName->text());
|
||||
piece.SetUUID(uiTabPaths->lineEditUUID->text());
|
||||
piece.SetShortName(uiTabPaths->lineEditShortName->text());
|
||||
piece.SetGradationLabel(uiTabPaths->lineEditGradationLabel->text());
|
||||
piece.SetPriority(static_cast<uint>(uiTabPaths->spinBoxPriority->value()));
|
||||
piece.SetFormulaSAWidth(GetFormulaFromUser(uiTabPaths->plainTextEditFormulaWidth), m_saWidth);
|
||||
|
@ -3026,6 +3028,9 @@ void DialogSeamAllowance::InitPieceTab()
|
|||
{
|
||||
connect(uiTabPaths->lineEditName, &QLineEdit::textChanged, this, &DialogSeamAllowance::NameDetailChanged);
|
||||
|
||||
uiTabPaths->lineEditShortName->setValidator(
|
||||
new QRegularExpressionValidator(QRegularExpression(VPiece::ShortNameRegExp()), this));
|
||||
|
||||
uiTabPaths->lineEditName->setClearButtonEnabled(true);
|
||||
uiTabPaths->lineEditName->setText(GetDefaultPieceName());
|
||||
|
||||
|
|
|
@ -207,6 +207,19 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="lineEditUUID">
|
||||
<property name="toolTip">
|
||||
<string>Universally Unique IDentifier of piece. Used to identifier piece while updating manual layout. Left empty to generate new value.</string>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string notr="true">{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="VLineEdit" name="lineEditName">
|
||||
<property name="text">
|
||||
|
@ -217,7 +230,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Priority:</string>
|
||||
|
@ -231,41 +244,28 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxPriority">
|
||||
<property name="toolTip">
|
||||
<string>Controls priority in layout. 0 - no priority.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEditUUID">
|
||||
<property name="toolTip">
|
||||
<string>Universally Unique IDentifier of piece. Used to identifier piece while updating manual layout. Left empty to generate new value.</string>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string notr="true">{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelEditUUID">
|
||||
<property name="text">
|
||||
<string notr="true">UUID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Gradation label:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelEditUUID">
|
||||
<property name="text">
|
||||
<string notr="true">UUID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxPriority">
|
||||
<property name="toolTip">
|
||||
<string>Controls priority in layout. 0 - no priority.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditGradationLabel">
|
||||
|
@ -286,6 +286,23 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Short name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEditShortName">
|
||||
<property name="toolTip">
|
||||
<string>Name used to generate a variable</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>25</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -335,7 +335,7 @@ void VToolSeamAllowance::InsertNodes(const QVector<VPieceNode> &nodes, quint32 p
|
|||
newDet.GetPath().Append(node);
|
||||
|
||||
// Seam allowance tool already initializated and can't init the node
|
||||
VToolSeamAllowance *saTool = qobject_cast<VToolSeamAllowance*>(VAbstractPattern::getTool(pieceId));
|
||||
auto *saTool = qobject_cast<VToolSeamAllowance*>(VAbstractPattern::getTool(pieceId));
|
||||
SCASSERT(saTool != nullptr);
|
||||
|
||||
InitNode(node, scene, saTool);
|
||||
|
@ -352,6 +352,8 @@ void VToolSeamAllowance::AddAttributes(VAbstractPattern *doc, QDomElement &domEl
|
|||
|
||||
doc->SetAttribute(domElement, VDomDocument::AttrId, id);
|
||||
doc->SetAttribute(domElement, AttrName, piece.GetName());
|
||||
doc->SetAttributeOrRemoveIf<QString>(domElement, AttrShortName, piece.GetShortName(),
|
||||
[](const QString &name) noexcept {return name.isEmpty();});
|
||||
doc->SetAttribute(domElement, AttrUUID, piece.GetUUID().toString());
|
||||
doc->SetAttributeOrRemoveIf<QString>(domElement, AttrGradationLabel, piece.GetGradationLabel(),
|
||||
[](const QString &label) noexcept {return label.isEmpty();});
|
||||
|
@ -1365,7 +1367,9 @@ void VToolSeamAllowance::UpdateExcludeState()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VToolSeamAllowance::UpdateInternalPaths()
|
||||
{
|
||||
const QVector<quint32> paths = VAbstractTool::data.GetPiece(m_id).GetInternalPaths();
|
||||
VPiece piece = VAbstractTool::data.GetPiece(m_id);
|
||||
piece.TestInternalPaths(&(VAbstractTool::data));
|
||||
const QVector<quint32> paths = piece.GetInternalPaths();
|
||||
for (auto path : paths)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -170,6 +170,7 @@ void TST_BuitInRegExp::TestCheckUnderlineExists_data()
|
|||
data.insert(c1LengthSplPath, false);
|
||||
data.insert(c2LengthSplPath, false);
|
||||
data.insert(rotationElArc_, true);
|
||||
data.insert(pieceArea_, true);
|
||||
|
||||
//Catch case when new internal variable appears.
|
||||
QCOMPARE(data.size(), builInVariables.size());
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "tst_vabstractpiece.h"
|
||||
#include "../vlayout/vabstractpiece.h"
|
||||
#include "../vlayout/vrawsapoint.h"
|
||||
#include "../vgeometry/varc.h"
|
||||
#include "../vgeometry/vpointf.h"
|
||||
|
||||
#include <QPointF>
|
||||
#include <QVector>
|
||||
|
@ -379,6 +381,57 @@ void TST_VAbstractPiece::SumTrapezoids() const
|
|||
Case5();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TST_VAbstractPiece::TestAreaCalculation_data()
|
||||
{
|
||||
QTest::addColumn<QVector<QPointF>>("path");
|
||||
QTest::addColumn<qreal>("excpectedArea");
|
||||
|
||||
{
|
||||
QVector<QPointF> rect
|
||||
{
|
||||
QPointF(),
|
||||
QPointF(100, 0),
|
||||
QPointF(100, 50),
|
||||
QPointF(0, 50),
|
||||
QPointF()
|
||||
};
|
||||
|
||||
QTest::newRow("Rectangle 100 x 50") << rect << 100.0 * 50.0;
|
||||
}
|
||||
|
||||
{
|
||||
VArc circle(VPointF(100, 100, QChar('C'), 0, 0), 100, 35, 35);
|
||||
circle.SetApproximationScale(maxCurveApproximationScale);
|
||||
QVector<QPointF> circlePath = circle.GetPoints();
|
||||
if (not circlePath.isEmpty() && not VFuzzyComparePoints(ConstFirst(circlePath), ConstLast(circlePath)))
|
||||
{
|
||||
circlePath.append(ConstFirst(circlePath));
|
||||
}
|
||||
QTest::newRow("Circle radis 100") << circlePath << M_PI * pow(100, 2);
|
||||
}
|
||||
|
||||
{
|
||||
VPointF sectorCenter(100, 100, QChar('C'), 0, 0);
|
||||
VArc sector(sectorCenter, 100, 15, 45);
|
||||
sector.SetApproximationScale(maxCurveApproximationScale);
|
||||
QVector<QPointF> sectorPath = sector.GetPoints();
|
||||
sectorPath.append(sectorCenter.toQPointF());
|
||||
sectorPath.append(ConstFirst(sectorPath));
|
||||
QTest::newRow("Sector radius 100, 30 degree") << sectorPath << (M_PI * pow(100, 2) * 30.0) / 360.0;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TST_VAbstractPiece::TestAreaCalculation() const
|
||||
{
|
||||
QFETCH(QVector<QPointF>, path);
|
||||
QFETCH(qreal, excpectedArea);
|
||||
|
||||
const qreal result = qAbs(VAbstractPiece::SumTrapezoids(path)/2.0);
|
||||
QVERIFY(qAbs(result - excpectedArea) < MmToPixel(1.0));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TST_VAbstractPiece::RawPathRemoveLoop_data() const
|
||||
{
|
||||
|
|
|
@ -45,6 +45,8 @@ private slots:
|
|||
void LayoutAllowanceRemoveLoop_data();
|
||||
void LayoutAllowanceRemoveLoop() const;
|
||||
void SumTrapezoids() const;
|
||||
void TestAreaCalculation_data();
|
||||
void TestAreaCalculation() const;
|
||||
void RawPathRemoveLoop_data() const;
|
||||
void RawPathRemoveLoop() const;
|
||||
void PathRemoveLoop_data() const;
|
||||
|
|
Loading…
Reference in New Issue
Block a user