Successful compilation.

This commit is contained in:
Roman Telezhynskyi 2022-10-28 16:16:02 +03:00
parent 704bbecd2e
commit bd10a78f55
61 changed files with 2854 additions and 1488 deletions

View File

@ -33,6 +33,7 @@
#include "vplayout.h" #include "vplayout.h"
#include "../vlayout/vtextmanager.h" #include "../vlayout/vtextmanager.h"
#include "../vlayout/vlayoutpiecepath.h" #include "../vlayout/vlayoutpiecepath.h"
#include "../vgeometry/vlayoutplacelabel.h"
#include <QIcon> #include <QIcon>
#include <QLoggingCategory> #include <QLoggingCategory>
@ -408,7 +409,7 @@ auto VPPiece::StickyPosition(qreal &dx, qreal &dy) const -> bool
return false; return false;
} }
QVector<QPointF> path = GetMappedExternalContourPoints(); QVector<QPointF> path = CastTo<QPointF>(GetMappedExternalContourPoints());
QRectF boundingRect = VLayoutPiece::BoundingRect(path); QRectF boundingRect = VLayoutPiece::BoundingRect(path);
const qreal stickyDistance = pieceGap+minStickyDistance; const qreal stickyDistance = pieceGap+minStickyDistance;
QRectF stickyZone = QRectF(boundingRect.topLeft().x()-stickyDistance, boundingRect.topLeft().y()-stickyDistance, QRectF stickyZone = QRectF(boundingRect.topLeft().x()-stickyDistance, boundingRect.topLeft().y()-stickyDistance,
@ -424,7 +425,7 @@ auto VPPiece::StickyPosition(qreal &dx, qreal &dy) const -> bool
continue; continue;
} }
QVector<QPointF> piecePath = piece->GetMappedExternalContourPoints(); QVector<QPointF> piecePath = CastTo<QPointF>(piece->GetMappedExternalContourPoints());
QRectF pieceBoundingRect = VLayoutPiece::BoundingRect(piecePath); QRectF pieceBoundingRect = VLayoutPiece::BoundingRect(piecePath);
if (stickyZone.intersects(pieceBoundingRect) || pieceBoundingRect.contains(stickyZone) || if (stickyZone.intersects(pieceBoundingRect) || pieceBoundingRect.contains(stickyZone) ||

View File

@ -507,7 +507,7 @@ void VPSheet::ValidateSuperpositionOfPieces() const
} }
const bool oldSuperpositionOfPieces = piece->HasSuperpositionWithPieces(); const bool oldSuperpositionOfPieces = piece->HasSuperpositionWithPieces();
QVector<QPointF> path1 = piece->GetMappedExternalContourPoints(); QVector<QPointF> path1 = CastTo<QPointF>(piece->GetMappedExternalContourPoints());
bool hasSuperposition = false; bool hasSuperposition = false;
for (const auto &p : pieces) for (const auto &p : pieces)
@ -517,7 +517,7 @@ void VPSheet::ValidateSuperpositionOfPieces() const
continue; continue;
} }
QVector<QPointF> path2 = p->GetMappedExternalContourPoints(); QVector<QPointF> path2 = CastTo<QPointF>(p->GetMappedExternalContourPoints());
bool superposition = VPPiece::PathsSuperposition(path1, path2); bool superposition = VPPiece::PathsSuperposition(path1, path2);
if (superposition) if (superposition)

View File

@ -42,14 +42,14 @@
#include "../layout/vppiece.h" #include "../layout/vppiece.h"
#include "../layout/vplayout.h" #include "../layout/vplayout.h"
#include "../layout/vpsheet.h" #include "../layout/vpsheet.h"
#include "../vlayout/vtextmanager.h" #include "../vlayout/vtextmanager.h"
#include "../vpapplication.h" #include "../vpapplication.h"
#include "compatibility.h" #include "compatibility.h"
#include "vlayoutpiecepath.h" #include "vlayoutpiecepath.h"
#include "vplacelabelitem.h"
#include "../vgeometry/vlayoutplacelabel.h"
#include "undocommands/vpundopiecemove.h" #include "undocommands/vpundopiecemove.h"
#include "undocommands/vpundomovepieceonsheet.h" #include "undocommands/vpundomovepieceonsheet.h"
@ -494,7 +494,7 @@ void VPGraphicsPiece::PaintSeamLine(QPainter *painter, const VPPiecePtr &piece)
{ {
if (not piece->IsHideMainPath() || not piece->IsSeamAllowance()) if (not piece->IsHideMainPath() || not piece->IsSeamAllowance())
{ {
QVector<QPointF> seamLinePoints = piece->GetMappedContourPoints(); QVector<VLayoutPoint> seamLinePoints = piece->GetMappedContourPoints();
if(!seamLinePoints.isEmpty()) if(!seamLinePoints.isEmpty())
{ {
m_seamLine.moveTo(ConstFirst(seamLinePoints)); m_seamLine.moveTo(ConstFirst(seamLinePoints));
@ -519,7 +519,7 @@ void VPGraphicsPiece::PaintCuttingLine(QPainter *painter, const VPPiecePtr &piec
{ {
if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn()) if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn())
{ {
QVector<QPointF> cuttingLinepoints = piece->GetMappedSeamAllowancePoints(); QVector<VLayoutPoint> cuttingLinepoints = piece->GetMappedSeamAllowancePoints();
if(!cuttingLinepoints.isEmpty()) if(!cuttingLinepoints.isEmpty())
{ {
m_cuttingLine.moveTo(ConstFirst(cuttingLinepoints)); m_cuttingLine.moveTo(ConstFirst(cuttingLinepoints));
@ -617,10 +617,11 @@ void VPGraphicsPiece::PaintPassmarks(QPainter *painter, const VPPiecePtr &piece)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintPlaceLabels(QPainter *painter, const VPPiecePtr &piece) void VPGraphicsPiece::PaintPlaceLabels(QPainter *painter, const VPPiecePtr &piece)
{ {
QVector<VLayoutPlaceLabel> placeLabels = piece->GetMappedPlaceLabels(); QVector<VLayoutPlaceLabel> placeLabels = piece->GetPlaceLabels();
for(auto &placeLabel : placeLabels) for(auto &placeLabel : placeLabels)
{ {
QPainterPath path = VPlaceLabelItem::LabelShapePath(placeLabel.shape); QPainterPath path =
VAbstractPiece::LabelShapePath(piece->MapPlaceLabelShape(VAbstractPiece::PlaceLabelShape(placeLabel)));
if (painter != nullptr) if (painter != nullptr)
{ {
@ -708,7 +709,7 @@ void VPGraphicsPiece::GroupMove(const QPointF &pos)
QVector<QPointF> path; QVector<QPointF> path;
if (not p.isNull() && p->StickyPosition(m_stickyTranslateX, m_stickyTranslateY)) if (not p.isNull() && p->StickyPosition(m_stickyTranslateX, m_stickyTranslateY))
{ {
path = p->GetMappedExternalContourPoints(); path = CastTo<QPointF>(p->GetMappedExternalContourPoints());
QTransform m; QTransform m;
m.translate(m_stickyTranslateX, m_stickyTranslateY); m.translate(m_stickyTranslateX, m_stickyTranslateY);
path = m.map(path); path = m.map(path);

View File

@ -521,7 +521,7 @@ void VPMainGraphicsView::TranslatePiecesOn(qreal dx, qreal dy)
QVector<QPointF> path; QVector<QPointF> path;
if (not p.isNull() && p->StickyPosition(m_stickyTranslateX, m_stickyTranslateY)) if (not p.isNull() && p->StickyPosition(m_stickyTranslateX, m_stickyTranslateY))
{ {
path = p->GetMappedExternalContourPoints(); path = CastTo<QPointF>(p->GetMappedExternalContourPoints());
QTransform m; QTransform m;
m.translate(m_stickyTranslateX, m_stickyTranslateY); m.translate(m_stickyTranslateX, m_stickyTranslateY);
path = m.map(path); path = m.map(path);

View File

@ -39,6 +39,7 @@
#include "../ifc/exception/vexceptionconversionerror.h" #include "../ifc/exception/vexceptionconversionerror.h"
#include "../vpatterndb/floatItemData/floatitemdef.h" #include "../vpatterndb/floatItemData/floatitemdef.h"
#include "../vgeometry/vgeometrydef.h" #include "../vgeometry/vgeometrydef.h"
#include "../vgeometry/vlayoutplacelabel.h"
#include "../layout/vplayout.h" #include "../layout/vplayout.h"
#include "../layout/vppiece.h" #include "../layout/vppiece.h"
@ -169,20 +170,6 @@ auto StringToRect(const QString &string) -> QRectF
return {}; return {};
} }
//---------------------------------------------------------------------------------------------------------------------
auto StringToMarkerShape(const QString &string) -> PlaceLabelImg
{
PlaceLabelImg shape;
QStringList paths = string.split(ML::itemsSep);
shape.reserve(paths.size());
for (const auto& path : paths)
{
shape.append(StringToPath(path));
}
return shape;
}
} // namespace } // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -499,7 +486,7 @@ void VPLayoutFileReader::ReadPiece(const VPPiecePtr &piece)
switch (tags.indexOf(name().toString())) switch (tags.indexOf(name().toString()))
{ {
case 0: // seam line case 0: // seam line
piece->SetCountourPoints(StringToPath(readElementText())); ReadSeamLine(piece);
break; break;
case 1: // seam allowance case 1: // seam allowance
ReadSeamAllowance(piece); ReadSeamAllowance(piece);
@ -527,6 +514,50 @@ void VPLayoutFileReader::ReadPiece(const VPPiecePtr &piece)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
VLayoutPoint VPLayoutFileReader::ReadLayoutPoint()
{
AssertRootTag(ML::TagPoint);
VLayoutPoint point;
QXmlStreamAttributes attribs = attributes();
point.setX(ReadAttributeDouble(attribs, ML::AttrX, QChar('0')));
point.setY(ReadAttributeDouble(attribs, ML::AttrY, QChar('0')));
point.SetTurnPoint(ReadAttributeBool(attribs, ML::AttrTurnPoint, falseStr));
point.SetCurvePoint(ReadAttributeBool(attribs, ML::AttrCurvePoint, falseStr));
return point;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPLayoutFileReader::ReadLayoutPoints() -> QVector<VLayoutPoint>
{
QVector<VLayoutPoint> points;
while (readNextStartElement())
{
if (name() == ML::TagPoint)
{
points.append(ReadLayoutPoint());
}
else
{
qCDebug(MLReader, "Ignoring tag %s", qUtf8Printable(name().toString()));
skipCurrentElement();
}
}
return points;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadSeamLine(const VPPiecePtr &piece)
{
AssertRootTag(ML::TagSeamLine);
piece->SetCountourPoints(ReadLayoutPoints());
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadSeamAllowance(const VPPiecePtr &piece) void VPLayoutFileReader::ReadSeamAllowance(const VPPiecePtr &piece)
{ {
@ -537,18 +568,15 @@ void VPLayoutFileReader::ReadSeamAllowance(const VPPiecePtr &piece)
piece->SetSeamAllowance(enabled); piece->SetSeamAllowance(enabled);
bool builtIn = ReadAttributeBool(attribs, ML::AttrBuiltIn, falseStr); bool builtIn = ReadAttributeBool(attribs, ML::AttrBuiltIn, falseStr);
QVector<QPointF> path = StringToPath(readElementText());
if (enabled) if (enabled && not builtIn)
{ {
if (not builtIn) QVector<VLayoutPoint> path = ReadLayoutPoints();
if (path.isEmpty())
{ {
if (path.isEmpty()) throw VException(tr("Error in line %1. Seam allowance is empty.").arg(lineNumber()));
{
throw VException(tr("Error in line %1. Seam allowance is empty.").arg(lineNumber()));
}
piece->SetSeamAllowancePoints(path);
} }
piece->SetSeamAllowancePoints(path);
} }
} }
@ -658,7 +686,7 @@ auto VPLayoutFileReader::ReadInternalPath() -> VLayoutPiecePath
path.SetCutPath(ReadAttributeBool(attribs, ML::AttrCut, falseStr)); path.SetCutPath(ReadAttributeBool(attribs, ML::AttrCut, falseStr));
path.SetPenStyle(LineStyleToPenStyle(ReadAttributeString(attribs, ML::AttrPenStyle, TypeLineLine))); path.SetPenStyle(LineStyleToPenStyle(ReadAttributeString(attribs, ML::AttrPenStyle, TypeLineLine)));
QVector<QPointF> shape = StringToPath(readElementText()); QVector<VLayoutPoint> shape = ReadLayoutPoints();
if (shape.isEmpty()) if (shape.isEmpty())
{ {
throw VException(tr("Error in line %1. Internal path shape is empty.").arg(lineNumber())); throw VException(tr("Error in line %1. Internal path shape is empty.").arg(lineNumber()));
@ -705,19 +733,11 @@ auto VPLayoutFileReader::ReadMarker() -> VLayoutPlaceLabel
QXmlStreamAttributes attribs = attributes(); QXmlStreamAttributes attribs = attributes();
QString matrix = ReadAttributeEmptyString(attribs, ML::AttrTransform); QString matrix = ReadAttributeEmptyString(attribs, ML::AttrTransform);
marker.rotationMatrix = StringToTransfrom(matrix); marker.SetRotationMatrix(StringToTransfrom(matrix));
marker.type = static_cast<PlaceLabelType>(ReadAttributeUInt(attribs, ML::AttrType, QChar('0'))); marker.SetType(static_cast<PlaceLabelType>(ReadAttributeUInt(attribs, ML::AttrType, QChar('0'))));
marker.center = StringToPoint(ReadAttributeEmptyString(attribs, ML::AttrCenter)); marker.SetCenter(StringToPoint(ReadAttributeEmptyString(attribs, ML::AttrCenter)));
marker.box = StringToRect(ReadAttributeEmptyString(attribs, ML::AttrBox)); marker.SetBox(StringToRect(ReadAttributeEmptyString(attribs, ML::AttrBox)));
PlaceLabelImg shape = StringToMarkerShape(readElementText());
if (shape.isEmpty())
{
throw VException(tr("Error in line %1. Marker shape is empty.").arg(lineNumber()));
}
marker.shape = shape;
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
QT_WARNING_POP QT_WARNING_POP

View File

@ -43,6 +43,7 @@ struct VLayoutPassmark;
struct VLayoutPlaceLabel; struct VLayoutPlaceLabel;
class VLayoutPiecePath; class VLayoutPiecePath;
class VTextManager; class VTextManager;
class VLayoutPoint;
class VPLayoutFileReader : public QXmlStreamReader class VPLayoutFileReader : public QXmlStreamReader
{ {
@ -67,6 +68,9 @@ private:
void ReadSheet(const VPLayoutPtr &layout); void ReadSheet(const VPLayoutPtr &layout);
void ReadPieces(const VPLayoutPtr &layout, const VPSheetPtr &sheet=VPSheetPtr()); void ReadPieces(const VPLayoutPtr &layout, const VPSheetPtr &sheet=VPSheetPtr());
void ReadPiece(const VPPiecePtr &piece); void ReadPiece(const VPPiecePtr &piece);
auto ReadLayoutPoint() -> VLayoutPoint;
auto ReadLayoutPoints() -> QVector<VLayoutPoint>;
void ReadSeamLine(const VPPiecePtr &piece);
void ReadSeamAllowance(const VPPiecePtr &piece); void ReadSeamAllowance(const VPPiecePtr &piece);
void ReadGrainline(const VPPiecePtr &piece); void ReadGrainline(const VPPiecePtr &piece);
void ReadNotches(const VPPiecePtr &piece); void ReadNotches(const VPPiecePtr &piece);
@ -82,6 +86,7 @@ private:
auto ReadLabelLine() -> TextLine; auto ReadLabelLine() -> TextLine;
void ReadWatermark(const VPLayoutPtr &layout); void ReadWatermark(const VPLayoutPtr &layout);
void ReadLayoutMargins(const VPLayoutPtr &layout); void ReadLayoutMargins(const VPLayoutPtr &layout);
void ReadSheetMargins(const VPSheetPtr &sheet); void ReadSheetMargins(const VPSheetPtr &sheet);
auto ReadSize() -> QSizeF; auto ReadSize() -> QSizeF;

View File

@ -35,6 +35,7 @@
#include "../vmisc/projectversion.h" #include "../vmisc/projectversion.h"
#include "../vlayout/vlayoutpiecepath.h" #include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vtextmanager.h" #include "../vlayout/vtextmanager.h"
#include "../vgeometry/vlayoutplacelabel.h"
namespace namespace
{ {
@ -93,18 +94,6 @@ auto RectToString(const QRectF &r) -> QString
NumberToString(r.height()); NumberToString(r.height());
} }
//---------------------------------------------------------------------------------------------------------------------
auto MarkerShapeToString(const PlaceLabelImg &shape) -> QString
{
QStringList s;
s.reserve(shape.size());
for (const auto& path : shape)
{
s.append(PathToString(path));
}
return s.join(ML::itemsSep);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto LineToString(const QLineF &line) -> QString auto LineToString(const QLineF &line) -> QString
{ {
@ -284,7 +273,11 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
[](qreal z) noexcept {return VFuzzyComparePossibleNulls(z, 1.0);}); [](qreal z) noexcept {return VFuzzyComparePossibleNulls(z, 1.0);});
writeStartElement(ML::TagSeamLine); writeStartElement(ML::TagSeamLine);
writeCharacters(PathToString(piece->GetContourPoints())); QVector<VLayoutPoint> contourPoints = piece->GetContourPoints();
for (auto &point : contourPoints)
{
WriteLayoutPoint(point);
}
writeEndElement(); writeEndElement();
writeStartElement(ML::TagSeamAllowance); writeStartElement(ML::TagSeamAllowance);
@ -294,7 +287,11 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
[](bool builtin) noexcept {return not builtin;}); [](bool builtin) noexcept {return not builtin;});
if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn()) if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn())
{ {
writeCharacters(PathToString(piece->GetSeamAllowancePoints())); QVector<VLayoutPoint> seamAllowancePoints = piece->GetSeamAllowancePoints();
for (auto &point : seamAllowancePoints)
{
WriteLayoutPoint(point);
}
} }
writeEndElement(); writeEndElement();
@ -329,7 +326,13 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
writeStartElement(ML::TagInternalPath); writeStartElement(ML::TagInternalPath);
SetAttribute(ML::AttrCut, path.IsCutPath()); SetAttribute(ML::AttrCut, path.IsCutPath());
SetAttribute(ML::AttrPenStyle, PenStyleToLineStyle(path.PenStyle())); SetAttribute(ML::AttrPenStyle, PenStyleToLineStyle(path.PenStyle()));
writeCharacters(PathToString(path.Points()));
QVector<VLayoutPoint> points = path.Points();
for (auto &point : points)
{
WriteLayoutPoint(point);
}
writeEndElement(); writeEndElement();
} }
writeEndElement(); writeEndElement();
@ -339,12 +342,10 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
for (const auto& label : placelabels) for (const auto& label : placelabels)
{ {
writeStartElement(ML::TagMarker); writeStartElement(ML::TagMarker);
SetAttribute(ML::AttrTransform, TransformToString(label.rotationMatrix)); SetAttribute(ML::AttrTransform, TransformToString(label.RotationMatrix()));
SetAttribute(ML::AttrType, static_cast<int>(label.type)); SetAttribute(ML::AttrType, static_cast<int>(label.Type()));
SetAttribute(ML::AttrCenter, PointToString(label.center)); SetAttribute(ML::AttrCenter, PointToString(label.Center()));
SetAttribute(ML::AttrBox, RectToString(label.box)); SetAttribute(ML::AttrBox, RectToString(label.Box()));
writeCharacters(MarkerShapeToString(label.shape));
writeEndElement(); writeEndElement();
} }
writeEndElement(); writeEndElement();
@ -425,3 +426,14 @@ void VPLayoutFileWriter::WriteSize(QSizeF size)
SetAttribute(ML::AttrLength, length); SetAttribute(ML::AttrLength, length);
writeEndElement(); // size writeEndElement(); // size
} }
//---------------------------------------------------------------------------------------------------------------------
auto VPLayoutFileWriter::WriteLayoutPoint(const VLayoutPoint &point) -> void
{
writeStartElement(ML::TagPoint);
SetAttribute(ML::AttrX, point.x());
SetAttribute(ML::AttrY, point.y());
SetAttributeOrRemoveIf<bool>(ML::AttrTurnPoint, point.TurnPoint(), [](bool val) noexcept {return val;});
SetAttributeOrRemoveIf<bool>(ML::AttrCurvePoint, point.CurvePoint(), [](bool val) noexcept {return val;});
writeEndElement();
}

View File

@ -46,6 +46,7 @@ class VPPiece;
class QFile; class QFile;
class QMarginsF; class QMarginsF;
class VTextManager; class VTextManager;
class VLayoutPoint;
class VPLayoutFileWriter : public QXmlStreamWriter class VPLayoutFileWriter : public QXmlStreamWriter
{ {
@ -68,6 +69,7 @@ private:
void WritePiece(const VPPiecePtr &piece); void WritePiece(const VPPiecePtr &piece);
void WriteLabel(const QVector<QPointF> &labelShape, const VTextManager &tm, const QString &tagName); void WriteLabel(const QVector<QPointF> &labelShape, const VTextManager &tm, const QString &tagName);
void WriteLabelLines(const VTextManager &tm); void WriteLabelLines(const VTextManager &tm);
auto WriteLayoutPoint(const VLayoutPoint &point) -> void;
void WriteMargins(const QMarginsF &margins, bool ignore); void WriteMargins(const QMarginsF &margins, bool ignore);
void WriteSize(QSizeF size); void WriteSize(QSizeF size);

View File

@ -60,6 +60,7 @@ const QString TagLines = QStringLiteral("lines"); // NOLINT(cert-e
const QString TagLine = QStringLiteral("line"); // NOLINT(cert-err58-cpp) const QString TagLine = QStringLiteral("line"); // NOLINT(cert-err58-cpp)
const QString TagScale = QStringLiteral("scale"); // NOLINT(cert-err58-cpp) const QString TagScale = QStringLiteral("scale"); // NOLINT(cert-err58-cpp)
const QString TagWatermark = QStringLiteral("watermark"); // NOLINT(cert-err58-cpp) const QString TagWatermark = QStringLiteral("watermark"); // NOLINT(cert-err58-cpp)
const QString TagPoint = QStringLiteral("point"); // NOLINT(cert-err58-cpp)
const QString AttrWarningSuperposition = QStringLiteral("warningSuperposition"); // NOLINT(cert-err58-cpp) const QString AttrWarningSuperposition = QStringLiteral("warningSuperposition"); // NOLINT(cert-err58-cpp)
const QString AttrWarningOutOfBound = QStringLiteral("warningOutOfBound"); // NOLINT(cert-err58-cpp) const QString AttrWarningOutOfBound = QStringLiteral("warningOutOfBound"); // NOLINT(cert-err58-cpp)
@ -108,6 +109,10 @@ const QString AttrShowPreview = QStringLiteral("showPreview"); // NOLIN
const QString AttrPrintScheme = QStringLiteral("printScheme"); // NOLINT(cert-err58-cpp) const QString AttrPrintScheme = QStringLiteral("printScheme"); // NOLINT(cert-err58-cpp)
const QString AttrTileNumber = QStringLiteral("tileNumber"); // NOLINT(cert-err58-cpp) const QString AttrTileNumber = QStringLiteral("tileNumber"); // NOLINT(cert-err58-cpp)
const QString AttrZValue = QStringLiteral("zValue"); // NOLINT(cert-err58-cpp) const QString AttrZValue = QStringLiteral("zValue"); // NOLINT(cert-err58-cpp)
const QString AttrX = QStringLiteral("x"); // NOLINT(cert-err58-cpp)
const QString AttrY = QStringLiteral("y"); // NOLINT(cert-err58-cpp)
const QString AttrTurnPoint = QStringLiteral("turnPoint"); // NOLINT(cert-err58-cpp)
const QString AttrCurvePoint = QStringLiteral("curvePoint"); // NOLINT(cert-err58-cpp)
const QString atFrontStr = QStringLiteral("atFront"); // NOLINT(cert-err58-cpp) const QString atFrontStr = QStringLiteral("atFront"); // NOLINT(cert-err58-cpp)
const QString atRearStr = QStringLiteral("atRear"); // NOLINT(cert-err58-cpp) const QString atRearStr = QStringLiteral("atRear"); // NOLINT(cert-err58-cpp)

View File

@ -65,6 +65,7 @@ extern const QString TagLines;
extern const QString TagLine; extern const QString TagLine;
extern const QString TagScale; extern const QString TagScale;
extern const QString TagWatermark; extern const QString TagWatermark;
extern const QString TagPoint;
extern const QString AttrWarningSuperposition; extern const QString AttrWarningSuperposition;
extern const QString AttrWarningOutOfBound; extern const QString AttrWarningOutOfBound;
@ -113,6 +114,10 @@ extern const QString AttrShowPreview;
extern const QString AttrPrintScheme; extern const QString AttrPrintScheme;
extern const QString AttrTileNumber; extern const QString AttrTileNumber;
extern const QString AttrZValue; extern const QString AttrZValue;
extern const QString AttrX;
extern const QString AttrY;
extern const QString AttrTurnPoint;
extern const QString AttrCurvePoint;
extern const QString atFrontStr; extern const QString atFrontStr;
extern const QString atRearStr; extern const QString atRearStr;

View File

@ -0,0 +1,563 @@
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="layout">
<xs:complexType>
<xs:sequence>
<xs:element name="properties">
<xs:complexType>
<xs:sequence>
<xs:element type="units" name="unit"/>
<xs:element type="xs:string" name="title"/>
<xs:element type="xs:string" name="description"/>
<xs:element name="control">
<xs:complexType>
<xs:attribute type="xs:boolean" name="warningSuperposition"/>
<xs:attribute type="xs:boolean" name="warningOutOfBound"/>
<xs:attribute type="xs:boolean" name="stickyEdges"/>
<xs:attribute type="xs:boolean" name="followGrainline"/>
<xs:attribute type="xs:float" name="piecesGap"/>
</xs:complexType>
</xs:element>
<xs:element name="tiles">
<xs:complexType>
<xs:sequence>
<xs:element name="size">
<xs:complexType>
<xs:attribute type="xs:float" name="width" use="required"/>
<xs:attribute type="xs:float" name="length" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="margin">
<xs:complexType>
<xs:attribute type="xs:float" name="top"/>
<xs:attribute type="xs:float" name="right"/>
<xs:attribute type="xs:float" name="bottom"/>
<xs:attribute type="xs:float" name="left"/>
<xs:attribute type="xs:boolean" name="ignoreMargins"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="visible"/>
<xs:attribute type="xs:string" name="matchingMarks"/>
<xs:attribute type="xs:boolean" name="printScheme"/>
<xs:attribute type="xs:boolean" name="tileNumber"/>
</xs:complexType>
</xs:element>
<xs:element name="scale">
<xs:complexType>
<xs:attribute type="LayoutScale" name="xScale"/>
<xs:attribute type="LayoutScale" name="yScale"/>
</xs:complexType>
</xs:element>
<xs:element name="watermark">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="showPreview" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="unplacedPieces">
<xs:complexType>
<xs:sequence>
<xs:element name="piece" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="seamLine">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="3" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="seamAllowance">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="grainline">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="PathOrEmpty">
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
<xs:attribute type="xs:float" name="angle" use="optional"/>
<xs:attribute type="ArrowDirection" name="arrowDirection" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="notches">
<xs:complexType>
<xs:sequence>
<xs:element name="notch" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
<xs:attribute type="NotchType" name="type" use="optional"/>
<xs:attribute type="LinePath" name="baseLine" use="optional"/>
<xs:attribute type="LinesPath" name="path" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="internalPaths">
<xs:complexType>
<xs:sequence>
<xs:element name="internalPath" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="3" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="cut" use="optional"/>
<xs:attribute type="CurvePenStyle" name="penStyle" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="markers">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="marker" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:attribute type="Transformation" name="transform" use="required"/>
<xs:attribute type="MarkerType" name="type" use="required"/>
<xs:attribute type="PointPath" name="center" use="required"/>
<xs:attribute type="RectPath" name="box" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="labels">
<xs:complexType>
<xs:sequence>
<xs:element name="pieceLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="lines">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="alignment" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="font"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="shape" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="patternLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="lines">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="alignment" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="font"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="shape" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="uuid" use="required"/>
<xs:attribute type="xs:string" name="name"/>
<xs:attribute type="xs:boolean" name="mirrored"/>
<xs:attribute type="xs:boolean" name="forbidFlipping"/>
<xs:attribute type="xs:boolean" name="forceFlipping"/>
<xs:attribute type="Transformation" name="transform"/>
<xs:attribute type="xs:string" name="gradationLabel"/>
<xs:attribute type="xs:unsignedInt" name="copyNumber"/>
<xs:attribute type="xs:boolean" name="showSeamline"/>
<xs:attribute type="xs:float" name="xScale"/>
<xs:attribute type="xs:float" name="yScale"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sheets">
<xs:complexType>
<xs:sequence>
<xs:element name="sheet" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element name="size">
<xs:complexType>
<xs:attribute type="xs:float" name="width" use="required"/>
<xs:attribute type="xs:float" name="length" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="margin">
<xs:complexType>
<xs:attribute type="xs:float" name="top"/>
<xs:attribute type="xs:float" name="right"/>
<xs:attribute type="xs:float" name="bottom"/>
<xs:attribute type="xs:float" name="left"/>
<xs:attribute type="xs:boolean" name="ignoreMargins"/>
</xs:complexType>
</xs:element>
<xs:element name="pieces">
<xs:complexType>
<xs:sequence>
<xs:element name="piece" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="seamLine">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="3" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="seamAllowance">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="grainline">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="PathOrEmpty">
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
<xs:attribute type="xs:float" name="angle" use="optional"/>
<xs:attribute type="ArrowDirection" name="arrowDirection" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="notches">
<xs:complexType>
<xs:sequence>
<xs:element name="notch" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
<xs:attribute type="NotchType" name="type" use="optional"/>
<xs:attribute type="LinePath" name="baseLine" use="optional"/>
<xs:attribute type="LinesPath" name="path" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="internalPaths">
<xs:complexType>
<xs:sequence>
<xs:element name="internalPath" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="2" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="cut" use="optional"/>
<xs:attribute type="CurvePenStyle" name="penStyle" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="markers">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="marker" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:attribute type="Transformation" name="transform" use="required"/>
<xs:attribute type="MarkerType" name="type" use="required"/>
<xs:attribute type="PointPath" name="center" use="required"/>
<xs:attribute type="RectPath" name="box" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="labels">
<xs:complexType>
<xs:sequence>
<xs:element name="pieceLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="lines">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="AlignmentType" name="alignment" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="font"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="PathNotEmpty" name="shape" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="patternLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="lines">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="AlignmentType" name="alignment" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="font"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="PathNotEmpty" name="shape" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="uuid" use="required"/>
<xs:attribute type="xs:string" name="name"/>
<xs:attribute type="xs:boolean" name="mirrored"/>
<xs:attribute type="xs:boolean" name="forbidFlipping"/>
<xs:attribute type="xs:boolean" name="forceFlipping"/>
<xs:attribute type="Transformation" name="transform"/>
<xs:attribute type="xs:string" name="gradationLabel"/>
<xs:attribute type="xs:unsignedInt" name="copyNumber"/>
<xs:attribute type="xs:boolean" name="showSeamline"/>
<xs:attribute type="xs:float" name="xScale"/>
<xs:attribute type="xs:float" name="yScale"/>
<xs:attribute type="xs:float" name="zValue"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="GrainlineType" name="grainlineType"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="formatVersion" name="version" use="required"/>
</xs:complexType>
</xs:element>
<!--Types-->
<xs:simpleType name="formatVersion">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}"/>
</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="uuid">
<xs:restriction base="xs:string">
<xs:pattern value="|\{[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}\}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ArrowDirection">
<xs:restriction base="xs:string">
<xs:enumeration value="atFront"/>
<xs:enumeration value="atRear"/>
<xs:enumeration value="atBoth"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NotchType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/>
<!--OneLine-->
<xs:enumeration value="1"/>
<!--TwoLines-->
<xs:enumeration value="2"/>
<!--ThreeLines-->
<xs:enumeration value="3"/>
<!--TMark-->
<xs:enumeration value="4"/>
<!--VMark-->
<xs:enumeration value="5"/>
<!--VMark2-->
<xs:enumeration value="6"/>
<!--UMark-->
<xs:enumeration value="7"/>
<!--BoxMark-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CurvePenStyle">
<xs:restriction base="xs:string">
<xs:enumeration value="hair"/>
<xs:enumeration value="dashLine"/>
<xs:enumeration value="dotLine"/>
<xs:enumeration value="dashDotLine"/>
<xs:enumeration value="dashDotDotLine"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MarkerType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/><!--Segment-->
<xs:enumeration value="1"/><!--Rectangle-->
<xs:enumeration value="2"/><!--Cross-->
<xs:enumeration value="3"/><!--Tshaped-->
<xs:enumeration value="4"/><!--Doubletree-->
<xs:enumeration value="5"/><!--Corner-->
<xs:enumeration value="6"/><!--Triangle-->
<xs:enumeration value="7"/><!--Hshaped-->
<xs:enumeration value="8"/><!--Button-->
<xs:enumeration value="9"/><!--Circle-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AlignmentType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/><!--default (no aligns)-->
<xs:enumeration value="1"/><!--aligns with the left edge-->
<xs:enumeration value="2"/><!--aligns with the right edge-->
<xs:enumeration value="4"/><!--Centers horizontally in the available space-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Transformation">
<xs:restriction base="xs:string">
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?;){8,}[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PathNotEmpty">
<xs:restriction base="xs:string">
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\s){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PathOrEmpty">
<xs:restriction base="xs:string">
<xs:pattern value="|([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\s){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LinePath">
<xs:restriction base="xs:string">
<xs:pattern value="[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LinesPath">
<xs:restriction base="xs:string">
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\*){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PointPath">
<xs:restriction base="xs:string">
<xs:pattern value="[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="RectPath">
<xs:restriction base="xs:string">
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?;){3,}[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="GrainlineType">
<xs:restriction base="xs:string">
<xs:enumeration value="horizontal"/>
<xs:enumeration value="vertical"/>
<xs:enumeration value="notFixed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LayoutScale">
<xs:restriction base="xs:float">
<xs:minInclusive value="0.01"/>
<xs:maxInclusive value="3"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View File

@ -28,6 +28,7 @@
#include "vlayoutconverter.h" #include "vlayoutconverter.h"
#include "../exception/vexception.h" #include "../exception/vexception.h"
#include "ifcdef.h" #include "ifcdef.h"
#include "../vlayout/vlayoutpoint.h"
/* /*
* Version rules: * Version rules:
@ -38,12 +39,61 @@
*/ */
const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0"); const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0");
const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.2"); const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.3");
const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.2.xsd"); const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.3.xsd");
//VLayoutConverter::LayoutMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! //VLayoutConverter::LayoutMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
//VLayoutConverter::LayoutMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! //VLayoutConverter::LayoutMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
namespace
{
// The list of all string we use for conversion
// Better to use global variables because repeating QStringLiteral blows up code size
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strPieceTag, (QLatin1String("piece"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strSeamLineTag, (QLatin1String("seamLine"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strSeamAllowanceTag, (QLatin1String("seamAllowance"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strInternalPathsTag, (QLatin1String("internalPaths"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strInternalPathTag, (QLatin1String("internalPath"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strMarkersTag, (QLatin1String("markers"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strMarkerTag, (QLatin1String("marker"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strPointTag, (QLatin1String("point"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrX, (QLatin1String("x"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrY, (QLatin1String("y"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrTurnPoint, (QLatin1String("turnPoint"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrCurvePoint, (QLatin1String("curvePoint"))) // NOLINT
//const QChar groupSep = QLatin1Char(';');
const QChar coordintatesSep = QLatin1Char(',');
const QChar pointsSep = QLatin1Char(' ');
//const QChar itemsSep = QLatin1Char('*');
//---------------------------------------------------------------------------------------------------------------------
auto StringV0_1_2ToPoint(const QString &point) -> QPointF
{
QStringList coordinates = point.split(coordintatesSep);
if (coordinates.count() == 2)
{
return {coordinates.at(0).toDouble(), coordinates.at(1).toDouble()};
}
return {};
}
//---------------------------------------------------------------------------------------------------------------------
auto StringV0_1_2ToPath(const QString &path) -> QVector<QPointF>
{
QVector<QPointF> p;
QStringList points = path.split(pointsSep);
p.reserve(points.size());
for (const auto& point : points)
{
p.append(StringV0_1_2ToPoint(point));
}
return p;
}
} // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VLayoutConverter::VLayoutConverter(const QString &fileName) VLayoutConverter::VLayoutConverter(const QString &fileName)
: VAbstractConverter(fileName) : VAbstractConverter(fileName)
@ -90,7 +140,8 @@ auto VLayoutConverter::XSDSchema(unsigned ver) const -> QString
{ {
std::make_pair(FormatVersion(0, 1, 0), QStringLiteral("://schema/layout/v0.1.0.xsd")), std::make_pair(FormatVersion(0, 1, 0), QStringLiteral("://schema/layout/v0.1.0.xsd")),
std::make_pair(FormatVersion(0, 1, 1), QStringLiteral("://schema/layout/v0.1.1.xsd")), std::make_pair(FormatVersion(0, 1, 1), QStringLiteral("://schema/layout/v0.1.1.xsd")),
std::make_pair(FormatVersion(0, 1, 2), CurrentSchema), std::make_pair(FormatVersion(0, 1, 2), QStringLiteral("://schema/layout/v0.1.2.xsd")),
std::make_pair(FormatVersion(0, 1, 3), CurrentSchema),
}; };
if (schemas.contains(ver)) if (schemas.contains(ver))
@ -108,10 +159,11 @@ void VLayoutConverter::ApplyPatches()
{ {
case (FormatVersion(0, 1, 0)): case (FormatVersion(0, 1, 0)):
case (FormatVersion(0, 1, 1)): case (FormatVersion(0, 1, 1)):
ToV0_1_2();
ValidateXML(XSDSchema(FormatVersion(0, 1, 2)));
Q_FALLTHROUGH();
case (FormatVersion(0, 1, 2)): case (FormatVersion(0, 1, 2)):
ToV0_1_3();
ValidateXML(XSDSchema(FormatVersion(0, 1, 3)));
Q_FALLTHROUGH();
case (FormatVersion(0, 1, 3)):
break; break;
default: default:
InvalidVersion(m_ver); InvalidVersion(m_ver);
@ -132,12 +184,77 @@ auto VLayoutConverter::IsReadOnly() const -> bool
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutConverter::ToV0_1_2() void VLayoutConverter::ConvertPiecesToV0_1_3()
{ {
// TODO. Delete if minimal supported version is 0.1.2 // TODO. Delete if minimal supported version is 0.1.3
Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 2), Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 3),
"Time to refactor the code."); "Time to refactor the code.");
SetVersion(QStringLiteral("0.1.2")); const QStringList types
{
*strSeamLineTag,
*strSeamAllowanceTag,
*strInternalPathTag
};
for (const auto &tagType : types)
{
QDomNodeList tags = elementsByTagName(tagType);
for (int i=0; i < tags.size(); ++i)
{
QDomElement node = tags.at(i).toElement();
ConvertPathToV0_1_3(node);
}
}
QDomNodeList tags = elementsByTagName(*strMarkerTag);
for (int i=0; i < tags.size(); ++i)
{
QDomElement node = tags.at(i).toElement();
RemoveAllChildren(node);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutConverter::ConvertPathToV0_1_3(QDomElement &node)
{
QString oldPath = node.text();
if (oldPath.isEmpty())
{
return;
}
RemoveAllChildren(node);
QVector<VLayoutPoint> path = CastTo<VLayoutPoint>(StringV0_1_2ToPath(oldPath));
for (auto &point : path)
{
QDomElement pointTag = createElement(*strPointTag);
SetAttribute(pointTag, *strAttrX, point.x());
SetAttribute(pointTag, *strAttrY, point.y());
if (point.TurnPoint())
{
SetAttribute(pointTag, *strAttrTurnPoint, point.TurnPoint());
}
if (point.CurvePoint())
{
SetAttribute(pointTag, *strAttrCurvePoint, point.CurvePoint());
}
node.appendChild(pointTag);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutConverter::ToV0_1_3()
{
// TODO. Delete if minimal supported version is 0.1.3
Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 3),
"Time to refactor the code.");
ConvertPiecesToV0_1_3();
SetVersion(QStringLiteral("0.1.3"));
Save(); Save();
} }

View File

@ -44,7 +44,7 @@ public:
static const QString LayoutMaxVerStr; static const QString LayoutMaxVerStr;
static const QString CurrentSchema; static const QString CurrentSchema;
static Q_DECL_CONSTEXPR const unsigned LayoutMinVer = FormatVersion(0, 1, 0); static Q_DECL_CONSTEXPR const unsigned LayoutMinVer = FormatVersion(0, 1, 0);
static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 2); static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 3);
protected: protected:
void SetVersion(const QString &version) override; void SetVersion(const QString &version) override;
@ -61,7 +61,11 @@ protected:
auto IsReadOnly() const -> bool override; auto IsReadOnly() const -> bool override;
void ToV0_1_2(); void ConvertPiecesToV0_1_3();
void ConvertPieceToV0_1_3(const QDomElement &piece);
void ConvertPathToV0_1_3(QDomElement &node);
void ToV0_1_3();
private: private:
Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT

View File

@ -53,7 +53,9 @@
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "dxiface.h" #include "dxiface.h"
#include "../vlayout/vlayoutpiece.h" #include "../vlayout/vlayoutpiece.h"
#include "../vlayout/vlayoutpoint.h"
#include "../vgeometry/vgeometrydef.h" #include "../vgeometry/vgeometrydef.h"
#include "../vgeometry/vlayoutplacelabel.h"
static const qreal AAMATextHeight = 2.5; static const qreal AAMATextHeight = 2.5;
@ -61,8 +63,8 @@ namespace
{ {
Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer0, (UTF8STRING("0"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer0, (UTF8STRING("0"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer1, (UTF8STRING("1"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer1, (UTF8STRING("1"))) // NOLINT
//Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer2, (UTF8STRING("2"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer2, (UTF8STRING("2"))) // NOLINT
//Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer3, (UTF8STRING("3"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer3, (UTF8STRING("3"))) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer4, (UTF8STRING("4"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer4, (UTF8STRING("4"))) // NOLINT
//Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer5, (UTF8STRING("5"))) // NOLINT //Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer5, (UTF8STRING("5"))) // NOLINT
//Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer6, (UTF8STRING("6"))) // NOLINT //Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer6, (UTF8STRING("6"))) // NOLINT
@ -87,9 +89,9 @@ Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer86, (UTF8STRING("86"))) // NOLI
Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer87, (UTF8STRING("87"))) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const UTF8STRING, layer87, (UTF8STRING("87"))) // NOLINT
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto PieceOutline(const VLayoutPiece &detail) -> QVector<QPointF> auto PieceOutline(const VLayoutPiece &detail) -> QVector<VLayoutPoint>
{ {
QVector<QPointF> outline; QVector<VLayoutPoint> outline;
if (detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn()) if (detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn())
{ {
outline = detail.GetMappedSeamAllowancePoints(); outline = detail.GetMappedSeamAllowancePoints();
@ -692,8 +694,7 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
return false; return false;
} }
m_input = QSharedPointer<dx_iface>(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement, m_input = QSharedPointer<dx_iface>::create(GetFileNameForLocale(), m_version, m_varMeasurement, m_varInsunits);
m_varInsunits));
m_input->AddAAMAHeaderData(); m_input->AddAAMAHeaderData();
if (m_version > DRW::AC1009) if (m_version > DRW::AC1009)
{ {
@ -705,7 +706,8 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
for(auto detail : details) for(auto detail : details)
{ {
auto *detailBlock = new dx_ifaceBlock();
auto detailBlock = QSharedPointer<dx_ifaceBlock>::create();
QString blockName = detail.GetName(); QString blockName = detail.GetName();
if (m_version <= DRW::AC1009) if (m_version <= DRW::AC1009)
@ -726,80 +728,98 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
ExportPieceText(detailBlock, detail); ExportPieceText(detailBlock, detail);
ExportAAMADrill(detailBlock, detail); ExportAAMADrill(detailBlock, detail);
m_input->AddBlock(detailBlock); m_input->AddBlock(detailBlock.get());
auto *insert = new DRW_Insert(); QScopedPointer<DRW_Insert> insert(new DRW_Insert());
insert->name = blockName.toStdString(); insert->name = blockName.toStdString();
insert->layer = *layer1; insert->layer = *layer1;
m_input->AddEntity(insert); m_input->AddEntity(insert.take());
} }
return m_input->fileExport(m_binary); return m_input->fileExport(m_binary);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMAOutline(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportAAMAOutline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
DRW_Entity *e = AAMAPolygon(PieceOutline(detail), *layer1, true); QVector<VLayoutPoint> points = PieceOutline(detail);
if (e)
if (DRW_Entity *e = AAMAPolygon(points, *layer1, true))
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, points);
ExportCurvePoints(detailBlock, points);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMADraw(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportAAMADraw(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
if (detail.IsSeamAllowance() && not detail.IsHideMainPath() && not detail.IsSeamAllowanceBuiltIn()) if (detail.IsSeamAllowance() && not detail.IsHideMainPath() && not detail.IsSeamAllowanceBuiltIn())
{ {
QVector<VLayoutPoint> points = detail.GetMappedContourPoints();
if (DRW_Entity *e = AAMAPolygon(detail.GetMappedContourPoints(), *layer8, true)) if (DRW_Entity *e = AAMAPolygon(detail.GetMappedContourPoints(), *layer8, true))
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, points);
ExportCurvePoints(detailBlock, points);
} }
const QVector<QVector<QPointF>> drawIntCut = detail.MappedInternalPathsForCut(false); const QVector<QVector<VLayoutPoint>> drawIntLine = detail.MappedInternalPathsForCut(false);
for(const auto &intCut : drawIntCut) for(const auto &intLine : drawIntLine)
{ {
if (DRW_Entity *e = AAMAPolygon(intCut, *layer8, false)) if (DRW_Entity *e = AAMAPolygon(intLine, *layer8, false))
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, intLine);
ExportCurvePoints(detailBlock, intLine);
} }
const QVector<VLayoutPlaceLabel> labels = detail.GetMappedPlaceLabels(); const QVector<VLayoutPlaceLabel> labels = detail.GetPlaceLabels();
for(const auto &label : labels) for(const auto &label : labels)
{ {
if (label.type != PlaceLabelType::Doubletree && label.type != PlaceLabelType::Button if (label.Type() != PlaceLabelType::Doubletree && label.Type() != PlaceLabelType::Button
&& label.type != PlaceLabelType::Circle) && label.Type() != PlaceLabelType::Circle)
{ {
for(const auto &p : qAsConst(label.shape)) PlaceLabelImg shape = detail.MapPlaceLabelShape(VAbstractPiece::PlaceLabelShape(label));
for(const auto &points : shape)
{ {
if (DRW_Entity *e = AAMAPolygon(p, *layer8, false)) if (DRW_Entity *e = AAMAPolygon(points, *layer8, false))
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, points);
ExportCurvePoints(detailBlock, points);
} }
} }
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMAIntcut(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportAAMAIntcut(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
QVector<QVector<QPointF>> drawIntCut = detail.MappedInternalPathsForCut(true); QVector<QVector<VLayoutPoint>> drawIntCut = detail.MappedInternalPathsForCut(true);
for(auto &intCut : drawIntCut) for(auto &intCut : drawIntCut)
{ {
if (DRW_Entity *e = AAMAPolygon(intCut, *layer11, false)) if (DRW_Entity *e = AAMAPolygon(intCut, *layer11, false))
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, intCut);
ExportCurvePoints(detailBlock, intCut);
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMANotch(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportAAMANotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
if (detail.IsSeamAllowance()) if (detail.IsSeamAllowance())
{ {
@ -818,7 +838,7 @@ void VDxfEngine::ExportAAMANotch(dx_ifaceBlock *detailBlock, const VLayoutPiece
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMAGrainline(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportAAMAGrainline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
const QVector<QPointF> grainline = detail.GetMappedGrainline(); const QVector<QPointF> grainline = detail.GetMappedGrainline();
if (grainline.count() > 1) if (grainline.count() > 1)
@ -831,7 +851,7 @@ void VDxfEngine::ExportAAMAGrainline(dx_ifaceBlock *detailBlock, const VLayoutPi
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportPieceText(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportPieceText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
const QStringList list = detail.GetPieceText(); const QStringList list = detail.GetPieceText();
const QPointF startPos = detail.GetPieceTextPosition(); const QPointF startPos = detail.GetPieceTextPosition();
@ -863,22 +883,17 @@ void VDxfEngine::ExportStyleSystemText(const QSharedPointer<dx_iface> &input, co
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMADrill(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportAAMADrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
const QVector<VLayoutPlaceLabel> labels = detail.GetMappedPlaceLabels(); const QVector<VLayoutPlaceLabel> labels = detail.GetPlaceLabels();
for(const auto &label : labels) for(const auto &label : labels)
{ {
if (label.type == PlaceLabelType::Doubletree || label.type == PlaceLabelType::Button if (label.Type() == PlaceLabelType::Doubletree || label.Type() == PlaceLabelType::Button
|| label.type == PlaceLabelType::Circle) || label.Type() == PlaceLabelType::Circle)
{ {
const QPointF center = detail.GetMatrix().map(label.center); const QPointF center = detail.GetMatrix().map(label.Center());
auto *point = new DRW_Point(); detailBlock->ent.push_back(AAMAPoint(center, *layer13));
point->basePoint = DRW_Coord(FromPixel(center.x(), m_varInsunits),
FromPixel(GetSize().height() - center.y(), m_varInsunits), 0);
point->layer = *layer13;
detailBlock->ent.push_back(point);
} }
} }
} }
@ -906,7 +921,7 @@ auto VDxfEngine::ExportToASTM(const QVector<VLayoutPiece> &details) -> bool
for(auto detail : details) for(auto detail : details)
{ {
auto *detailBlock = new dx_ifaceBlock(); auto detailBlock = QSharedPointer<dx_ifaceBlock>::create();
QString blockName = detail.GetName(); QString blockName = detail.GetName();
if (m_version <= DRW::AC1009) if (m_version <= DRW::AC1009)
@ -929,44 +944,45 @@ auto VDxfEngine::ExportToASTM(const QVector<VLayoutPiece> &details) -> bool
ExportASTMDrill(detailBlock, detail); ExportASTMDrill(detailBlock, detail);
ExportASTMAnnotationText(detailBlock, detail); ExportASTMAnnotationText(detailBlock, detail);
m_input->AddBlock(detailBlock); m_input->AddBlock(detailBlock.get());
auto *insert = new DRW_Insert(); QScopedPointer<DRW_Insert> insert(new DRW_Insert());
insert->name = blockName.toStdString(); insert->name = blockName.toStdString();
insert->layer = *layer1; insert->layer = *layer1;
m_input->AddEntity(insert); m_input->AddEntity(insert.take());
} }
return m_input->fileExport(m_binary); return m_input->fileExport(m_binary);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMPieceBoundary(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportASTMPieceBoundary(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
QVector<QPointF> pieceBoundary = PieceOutline(detail); QVector<VLayoutPoint> pieceBoundary = PieceOutline(detail);
// Piece boundary // Piece boundary
DRW_Entity *e = AAMAPolygon(pieceBoundary, *layer1, true); if (DRW_Entity *e = AAMAPolygon(pieceBoundary, *layer1, true))
if (e)
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, pieceBoundary);
ExportCurvePoints(detailBlock, pieceBoundary);
// Piece boundary quality validation curves // Piece boundary quality validation curves
DRW_Entity *q = AAMAPolygon(pieceBoundary, *layer84, true); if (DRW_Entity *q = AAMAPolygon(pieceBoundary, *layer84, true))
if (q)
{ {
detailBlock->ent.push_back(q); detailBlock->ent.push_back(q);
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMSewLine(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportASTMSewLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
if (detail.IsSeamAllowance() && not detail.IsHideMainPath() && not detail.IsSeamAllowanceBuiltIn()) if (detail.IsSeamAllowance() && not detail.IsHideMainPath() && not detail.IsSeamAllowanceBuiltIn())
{ {
QVector<QPointF> sewLine = detail.GetMappedContourPoints(); QVector<VLayoutPoint> sewLine = detail.GetMappedContourPoints();
// Sew lines // Sew lines
if (DRW_Entity *e = AAMAPolygon(sewLine, *layer14, true)) if (DRW_Entity *e = AAMAPolygon(sewLine, *layer14, true))
@ -974,6 +990,9 @@ void VDxfEngine::ExportASTMSewLine(dx_ifaceBlock *detailBlock, const VLayoutPiec
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, sewLine);
ExportCurvePoints(detailBlock, sewLine);
// Sew lines quality validation curves // Sew lines quality validation curves
if (DRW_Entity *e = AAMAPolygon(sewLine, *layer87, true)) if (DRW_Entity *e = AAMAPolygon(sewLine, *layer87, true))
{ {
@ -983,31 +1002,35 @@ void VDxfEngine::ExportASTMSewLine(dx_ifaceBlock *detailBlock, const VLayoutPiec
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMInternalLine(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportASTMInternalLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
const QVector<QVector<QPointF>> drawIntCut = detail.MappedInternalPathsForCut(false); const QVector<QVector<VLayoutPoint>> drawIntLine = detail.MappedInternalPathsForCut(false);
for(const auto &intCut : drawIntCut) for(const auto &intLine : drawIntLine)
{ {
// Internal line // Internal line
if (DRW_Entity *e = AAMAPolygon(intCut, *layer8, false)) if (DRW_Entity *e = AAMAPolygon(intLine, *layer8, false))
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, intLine);
ExportCurvePoints(detailBlock, intLine);
// Internal lines quality validation curves // Internal lines quality validation curves
if (DRW_Entity *e = AAMAPolygon(intCut, *layer85, false)) if (DRW_Entity *e = AAMAPolygon(intLine, *layer85, false))
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
} }
const QVector<VLayoutPlaceLabel> labels = detail.GetMappedPlaceLabels(); const QVector<VLayoutPlaceLabel> labels = detail.GetPlaceLabels();
for(const auto &label : labels) for(const auto &label : labels)
{ {
if (label.type != PlaceLabelType::Doubletree && label.type != PlaceLabelType::Button if (label.Type() != PlaceLabelType::Doubletree && label.Type() != PlaceLabelType::Button
&& label.type != PlaceLabelType::Circle) && label.Type() != PlaceLabelType::Circle)
{ {
for(const auto &p : qAsConst(label.shape)) PlaceLabelImg shape = detail.MapPlaceLabelShape(VAbstractPiece::PlaceLabelShape(label));
for(const auto &p : shape)
{ {
// Internal line (placelabel) // Internal line (placelabel)
if (DRW_Entity *e = AAMAPolygon(p, *layer8, false)) if (DRW_Entity *e = AAMAPolygon(p, *layer8, false))
@ -1015,6 +1038,9 @@ void VDxfEngine::ExportASTMInternalLine(dx_ifaceBlock *detailBlock, const VLayou
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, p);
ExportCurvePoints(detailBlock, p);
// Internal lines quality validation curves // Internal lines quality validation curves
if (DRW_Entity *e = AAMAPolygon(p, *layer85, false)) if (DRW_Entity *e = AAMAPolygon(p, *layer85, false))
{ {
@ -1026,9 +1052,9 @@ void VDxfEngine::ExportASTMInternalLine(dx_ifaceBlock *detailBlock, const VLayou
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMInternalCutout(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportASTMInternalCutout(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
QVector<QVector<QPointF>> drawIntCut = detail.MappedInternalPathsForCut(true); QVector<QVector<VLayoutPoint>> drawIntCut = detail.MappedInternalPathsForCut(true);
for(auto &intCut : drawIntCut) for(auto &intCut : drawIntCut)
{ {
// Internal cutout // Internal cutout
@ -1037,6 +1063,9 @@ void VDxfEngine::ExportASTMInternalCutout(dx_ifaceBlock *detailBlock, const VLay
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
} }
ExportTurnPoints(detailBlock, intCut);
ExportCurvePoints(detailBlock, intCut);
// Internal cutouts quality validation curves // Internal cutouts quality validation curves
if (DRW_Entity *e = AAMAPolygon(intCut, *layer86, false)) if (DRW_Entity *e = AAMAPolygon(intCut, *layer86, false))
{ {
@ -1046,7 +1075,7 @@ void VDxfEngine::ExportASTMInternalCutout(dx_ifaceBlock *detailBlock, const VLay
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMAnnotationText(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportASTMAnnotationText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
QString name = detail.GetName(); QString name = detail.GetName();
QPointF textPos = detail.VLayoutPiece::DetailBoundingRect().center(); QPointF textPos = detail.VLayoutPiece::DetailBoundingRect().center();
@ -1056,22 +1085,17 @@ void VDxfEngine::ExportASTMAnnotationText(dx_ifaceBlock *detailBlock, const VLay
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMDrill(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
const QVector<VLayoutPlaceLabel> labels = detail.GetMappedPlaceLabels(); const QVector<VLayoutPlaceLabel> labels = detail.GetPlaceLabels();
for(const auto &label : labels) for(const auto &label : labels)
{ {
if (label.type == PlaceLabelType::Doubletree || label.type == PlaceLabelType::Button if (label.Type() == PlaceLabelType::Doubletree || label.Type() == PlaceLabelType::Button
|| label.type == PlaceLabelType::Circle) || label.Type() == PlaceLabelType::Circle)
{ {
const QPointF center = detail.GetMatrix().map(label.center); const QPointF center = detail.GetMatrix().map(label.Center());
auto *point = new DRW_Point(); detailBlock->ent.push_back(AAMAPoint(center, *layer13));
point->basePoint = DRW_Coord(FromPixel(center.x(), m_varInsunits),
FromPixel(GetSize().height() - center.y(), m_varInsunits), 0);
point->layer = *layer13;
detailBlock->ent.push_back(point);
// TODO. Investigate drill category // TODO. Investigate drill category
// QPointF pos(center.x(), center.y() - ToPixel(AAMATextHeight, varInsunits)); // QPointF pos(center.x(), center.y() - ToPixel(AAMATextHeight, varInsunits));
@ -1081,7 +1105,7 @@ void VDxfEngine::ExportASTMDrill(dx_ifaceBlock *detailBlock, const VLayoutPiece
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMNotch(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportASTMNotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
if (detail.IsSeamAllowance()) if (detail.IsSeamAllowance())
{ {
@ -1141,7 +1165,34 @@ void VDxfEngine::ExportASTMNotch(dx_ifaceBlock *detailBlock, const VLayoutPiece
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::AAMAPolygon(const QVector<QPointF> &polygon, const UTF8STRING &layer, bool forceClosed) -> DRW_Entity * void VDxfEngine::ExportTurnPoints(const QSharedPointer<dx_ifaceBlock> &detailBlock,
const QVector<VLayoutPoint> &points) const
{
for(const auto &p : qAsConst(points))
{
if (p.TurnPoint())
{
detailBlock->ent.push_back(AAMAPoint(p, *layer2));
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportCurvePoints(const QSharedPointer<dx_ifaceBlock> &detailBlock,
const QVector<VLayoutPoint> &points) const
{
for(const auto &p : qAsConst(points))
{
if (p.CurvePoint() && not p.TurnPoint())
{
detailBlock->ent.push_back(AAMAPoint(p, *layer3));
}
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::AAMAPolygon(const QVector<VLayoutPoint> &polygon, const UTF8STRING &layer,
bool forceClosed) -> DRW_Entity *
{ {
if (polygon.isEmpty()) if (polygon.isEmpty())
{ {
@ -1186,6 +1237,16 @@ auto VDxfEngine::AAMAText(const QPointF &pos, const QString &text, const UTF8STR
return textLine; return textLine;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::AAMAPoint(const QPointF &pos, const UTF8STRING &layer) const -> DRW_Point *
{
auto *point = new DRW_Point();
point->basePoint = DRW_Coord(FromPixel(pos.x(), m_varInsunits),
FromPixel(GetSize().height() - pos.y(), m_varInsunits), 0);
point->layer = layer;
return point;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::FromUnicodeToCodec(const QString &str, QTextCodec *codec) -> std::string auto VDxfEngine::FromUnicodeToCodec(const QString &str, QTextCodec *codec) -> std::string
{ {
@ -1203,8 +1264,9 @@ auto VDxfEngine::GetFileNameForLocale() const -> std::string
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template<class P, class V> template<class P, class V, class C>
auto VDxfEngine::CreateAAMAPolygon(const QVector<QPointF> &polygon, const UTF8STRING &layer, bool forceClosed) -> P * auto VDxfEngine::CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer,
bool forceClosed) -> P *
{ {
auto *poly = new P(); auto *poly = new P();
poly->layer = layer; poly->layer = layer;
@ -1221,7 +1283,7 @@ auto VDxfEngine::CreateAAMAPolygon(const QVector<QPointF> &polygon, const UTF8ST
} }
} }
for (auto p : polygon) for (const auto &p : polygon)
{ {
poly->addVertex(V(FromPixel(p.x(), m_varInsunits), poly->addVertex(V(FromPixel(p.x(), m_varInsunits),
FromPixel(GetSize().height() - p.y(), m_varInsunits))); FromPixel(GetSize().height() - p.y(), m_varInsunits)));

View File

@ -49,6 +49,8 @@ class DRW_Text;
class VLayoutPiece; class VLayoutPiece;
class DRW_Entity; class DRW_Entity;
class dx_ifaceBlock; class dx_ifaceBlock;
class VLayoutPoint;
class DRW_Point;
class VDxfEngine final : public QPaintEngine class VDxfEngine final : public QPaintEngine
{ {
@ -123,31 +125,37 @@ private:
Q_REQUIRED_RESULT auto ToPixel(double val, const VarInsunits &unit) const -> double; Q_REQUIRED_RESULT auto ToPixel(double val, const VarInsunits &unit) const -> double;
auto ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool; auto ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool;
void ExportAAMAOutline(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportAAMAOutline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMADraw(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportAAMADraw(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMAIntcut(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportAAMAIntcut(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMANotch(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportAAMANotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMAGrainline(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportAAMAGrainline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportPieceText(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportPieceText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportStyleSystemText(const QSharedPointer<dx_iface> &input, const QVector<VLayoutPiece> &details); void ExportStyleSystemText(const QSharedPointer<dx_iface> &input, const QVector<VLayoutPiece> &details);
void ExportAAMADrill(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportAAMADrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
auto ExportToASTM(const QVector<VLayoutPiece> &details) -> bool; auto ExportToASTM(const QVector<VLayoutPiece> &details) -> bool;
void ExportASTMPieceBoundary(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportASTMPieceBoundary(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMSewLine(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportASTMSewLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMInternalLine(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportASTMInternalLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMInternalCutout(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportASTMInternalCutout(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMAnnotationText(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportASTMAnnotationText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMDrill(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMNotch(dx_ifaceBlock *detailBlock, const VLayoutPiece &detail); void ExportASTMNotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
Q_REQUIRED_RESULT auto AAMAPolygon(const QVector<QPointF> &polygon, const UTF8STRING &layer, void ExportTurnPoints(const QSharedPointer<dx_ifaceBlock> &detailBlock,
const QVector<VLayoutPoint> &points) const;
void ExportCurvePoints(const QSharedPointer<dx_ifaceBlock> &detailBlock,
const QVector<VLayoutPoint> &points) const;
Q_REQUIRED_RESULT auto AAMAPolygon(const QVector<VLayoutPoint> &polygon, const UTF8STRING &layer,
bool forceClosed) -> DRW_Entity *; bool forceClosed) -> DRW_Entity *;
Q_REQUIRED_RESULT auto AAMALine(const QLineF &line, const UTF8STRING &layer) -> DRW_Entity *; Q_REQUIRED_RESULT auto AAMALine(const QLineF &line, const UTF8STRING &layer) -> DRW_Entity *;
Q_REQUIRED_RESULT auto AAMAText(const QPointF &pos, const QString &text, const UTF8STRING &layer) -> DRW_Entity *; Q_REQUIRED_RESULT auto AAMAText(const QPointF &pos, const QString &text, const UTF8STRING &layer) -> DRW_Entity *;
Q_REQUIRED_RESULT auto AAMAPoint(const QPointF &pos, const UTF8STRING &layer) const -> DRW_Point *;
template<class P, class V> template<class P, class V, class C>
Q_REQUIRED_RESULT auto CreateAAMAPolygon(const QVector<QPointF> &polygon, const UTF8STRING &layer, Q_REQUIRED_RESULT auto CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer,
bool forceClosed) -> P *; bool forceClosed) -> P *;
static auto FromUnicodeToCodec(const QString &str, QTextCodec *codec) -> std::string; static auto FromUnicodeToCodec(const QString &str, QTextCodec *codec) -> std::string;

View File

@ -6,6 +6,7 @@ SOURCES += \
$$PWD/vgobject.cpp \ $$PWD/vgobject.cpp \
$$PWD/vabstractcurve.cpp \ $$PWD/vabstractcurve.cpp \
$$PWD/varc.cpp \ $$PWD/varc.cpp \
$$PWD/vlayoutplacelabel.cpp \
$$PWD/vpointf.cpp \ $$PWD/vpointf.cpp \
$$PWD/vspline.cpp \ $$PWD/vspline.cpp \
$$PWD/vsplinepath.cpp \ $$PWD/vsplinepath.cpp \
@ -28,6 +29,7 @@ HEADERS += \
$$PWD/vabstractcurve.h \ $$PWD/vabstractcurve.h \
$$PWD/varc.h \ $$PWD/varc.h \
$$PWD/varc_p.h \ $$PWD/varc_p.h \
$$PWD/vlayoutplacelabel.h \
$$PWD/vpointf.h \ $$PWD/vpointf.h \
$$PWD/vpointf_p.h \ $$PWD/vpointf_p.h \
$$PWD/vspline.h \ $$PWD/vspline.h \

View File

@ -93,64 +93,3 @@ QDataStream &operator>>(QDataStream &dataStream, VLayoutPassmark &data)
return dataStream; return dataStream;
} }
const quint32 VLayoutPlaceLabel::streamHeader = 0xB282E284; // CRC-32Q string "VLayoutPlaceLabel"
const quint16 VLayoutPlaceLabel::classVersion = 1;
// Friend functions
//---------------------------------------------------------------------------------------------------------------------
QDataStream& operator<<(QDataStream &dataStream, const VLayoutPlaceLabel &data)
{
dataStream << VLayoutPlaceLabel::streamHeader << VLayoutPlaceLabel::classVersion;
// Added in classVersion = 1
dataStream << data.center;
dataStream << data.type;
dataStream << data.shape;
dataStream << data.rotationMatrix;
dataStream << data.box;
// Added in classVersion = 2
return dataStream;
}
//---------------------------------------------------------------------------------------------------------------------
QDataStream& operator>>(QDataStream &dataStream, VLayoutPlaceLabel &data)
{
quint32 actualStreamHeader = 0;
dataStream >> actualStreamHeader;
if (actualStreamHeader != VLayoutPlaceLabel::streamHeader)
{
QString message = QCoreApplication::tr("VLayoutPlaceLabel prefix mismatch error: actualStreamHeader = 0x%1 and "
"streamHeader = 0x%2")
.arg(actualStreamHeader, 8, 0x10, QChar('0'))
.arg(VLayoutPlaceLabel::streamHeader, 8, 0x10, QChar('0'));
throw VException(message);
}
quint16 actualClassVersion = 0;
dataStream >> actualClassVersion;
if (actualClassVersion > VLayoutPlaceLabel::classVersion)
{
QString message = QCoreApplication::tr("VLayoutPlaceLabel compatibility error: actualClassVersion = %1 and "
"classVersion = %2")
.arg(actualClassVersion).arg(VLayoutPlaceLabel::classVersion);
throw VException(message);
}
dataStream >> data.center;
dataStream >> data.type;
dataStream >> data.shape;
dataStream >> data.rotationMatrix;
dataStream >> data.box;
// if (actualClassVersion >= 2)
// {
// }
return dataStream;
}

View File

@ -64,24 +64,6 @@ enum class PlaceLabelType : quint8
Circle = 9 Circle = 9
}; };
typedef QVector<QPolygonF> PlaceLabelImg;
struct VLayoutPlaceLabel
{
QPointF center{};
PlaceLabelType type{PlaceLabelType::Button};
PlaceLabelImg shape{};
QTransform rotationMatrix{};
QRectF box{};
friend QDataStream& operator<<(QDataStream& dataStream, const VLayoutPlaceLabel& data);
friend QDataStream& operator>>(QDataStream& dataStream, VLayoutPlaceLabel& data);
private:
static const quint32 streamHeader;
static const quint16 classVersion;
};
Q_DECLARE_METATYPE(VLayoutPlaceLabel)
struct VLayoutPassmark struct VLayoutPassmark
{ {
QVector<QLineF> lines{}; QVector<QLineF> lines{};

View File

@ -0,0 +1,104 @@
/************************************************************************
**
** @file vlayoutplacelabel.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 12 10, 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 "vlayoutplacelabel.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
# include "../vmisc/vdatastreamenum.h"
#endif
#include "../ifc/exception/vexception.h"
//---------------------------------------------------------------------------------------------------------------------
VLayoutPlaceLabel::VLayoutPlaceLabel(const VPlaceLabelItem &item)
: m_center(item.toQPointF()),
m_type(item.GetLabelType()),
m_rotationMatrix(item.RotationMatrix()),
m_box(item.Box())
{}
// Friend functions
//---------------------------------------------------------------------------------------------------------------------
auto operator<<(QDataStream &dataStream, const VLayoutPlaceLabel &data) -> QDataStream&
{
dataStream << VLayoutPlaceLabel::streamHeader << VLayoutPlaceLabel::classVersion;
// Added in classVersion = 1
dataStream << data.m_center;
dataStream << data.m_type;
dataStream << data.m_rotationMatrix;
dataStream << data.m_box;
// Added in classVersion = 2
return dataStream;
}
//---------------------------------------------------------------------------------------------------------------------
auto operator>>(QDataStream &dataStream, VLayoutPlaceLabel &data) -> QDataStream&
{
quint32 actualStreamHeader = 0;
dataStream >> actualStreamHeader;
if (actualStreamHeader != VLayoutPlaceLabel::streamHeader)
{
QString message = QCoreApplication::tr("VLayoutPlaceLabel prefix mismatch error: actualStreamHeader = 0x%1 and "
"streamHeader = 0x%2")
.arg(actualStreamHeader, 8, 0x10, QChar('0'))
.arg(VLayoutPlaceLabel::streamHeader, 8, 0x10, QChar('0'));
throw VException(message);
}
quint16 actualClassVersion = 0;
dataStream >> actualClassVersion;
if (actualClassVersion > VLayoutPlaceLabel::classVersion)
{
QString message = QCoreApplication::tr("VLayoutPlaceLabel compatibility error: actualClassVersion = %1 and "
"classVersion = %2")
.arg(actualClassVersion).arg(VLayoutPlaceLabel::classVersion);
throw VException(message);
}
dataStream >> data.m_center;
dataStream >> data.m_type;
if (actualClassVersion == 1)
{
QVector<QPolygonF> shape;
dataStream >> shape; // no longer in use
}
dataStream >> data.m_rotationMatrix;
dataStream >> data.m_box;
// if (actualClassVersion >= 2)
// {
// }
return dataStream;
}

View File

@ -0,0 +1,118 @@
/************************************************************************
**
** @file vlayoutplacelabel.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 12 10, 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 VLAYOUTPLACELABEL_H
#define VLAYOUTPLACELABEL_H
#include <QPolygonF>
#include "vgeometrydef.h"
#include "vplacelabelitem.h"
class VLayoutPlaceLabel
{
public:
VLayoutPlaceLabel() = default;
explicit VLayoutPlaceLabel(const VPlaceLabelItem &item);
friend auto operator<<(QDataStream& dataStream, const VLayoutPlaceLabel& data) -> QDataStream&;
friend auto operator>>(QDataStream& dataStream, VLayoutPlaceLabel& data) -> QDataStream&;
auto Center() const -> QPointF;
void SetCenter(QPointF newCenter);
auto Type() const -> PlaceLabelType;
void SetType(PlaceLabelType newType);
auto RotationMatrix() const -> const QTransform &;
void SetRotationMatrix(const QTransform &newRotationMatrix);
auto Box() const -> const QRectF &;
void SetBox(const QRectF &newBox);
private:
static constexpr quint32 streamHeader = 0xB282E284; // CRC-32Q string "VLayoutPlaceLabel"
static constexpr quint16 classVersion = 2;
QPointF m_center{};
PlaceLabelType m_type{PlaceLabelType::Button};
QTransform m_rotationMatrix{};
QRectF m_box{};
};
Q_DECLARE_METATYPE(VLayoutPlaceLabel) // NOLINT
Q_DECLARE_TYPEINFO(VLayoutPlaceLabel, Q_MOVABLE_TYPE); // NOLINT
//---------------------------------------------------------------------------------------------------------------------
inline auto VLayoutPlaceLabel::Center() const -> QPointF
{
return m_center;
}
//---------------------------------------------------------------------------------------------------------------------
inline void VLayoutPlaceLabel::SetCenter(QPointF newCenter)
{
m_center = newCenter;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VLayoutPlaceLabel::Type() const -> PlaceLabelType
{
return m_type;
}
//---------------------------------------------------------------------------------------------------------------------
inline void VLayoutPlaceLabel::SetType(PlaceLabelType newType)
{
m_type = newType;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VLayoutPlaceLabel::RotationMatrix() const -> const QTransform &
{
return m_rotationMatrix;
}
//---------------------------------------------------------------------------------------------------------------------
inline void VLayoutPlaceLabel::SetRotationMatrix(const QTransform &newRotationMatrix)
{
m_rotationMatrix = newRotationMatrix;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VLayoutPlaceLabel::Box() const -> const QRectF &
{
return m_box;
}
//---------------------------------------------------------------------------------------------------------------------
inline void VLayoutPlaceLabel::SetBox(const QRectF &newBox)
{
m_box = newBox;
}
#endif // VLAYOUTPLACELABEL_H

View File

@ -28,7 +28,6 @@
#include "vplacelabelitem.h" #include "vplacelabelitem.h"
#include "vplacelabelitem_p.h" #include "vplacelabelitem_p.h"
#include "../vpatterndb/vcontainer.h" #include "../vpatterndb/vcontainer.h"
#include "varc.h"
#include <qnumeric.h> #include <qnumeric.h>
#include <QPolygonF> #include <QPolygonF>
@ -240,198 +239,3 @@ VPlaceLabelItem &VPlaceLabelItem::operator=(VPlaceLabelItem &&item) Q_DECL_NOTHR
return *this; return *this;
} }
#endif #endif
//---------------------------------------------------------------------------------------------------------------------
PlaceLabelImg VPlaceLabelItem::LabelShape() const
{
QTransform t = RotationMatrix();
auto SegmentShape = [t, this]()
{
QPolygonF shape;
shape << QPointF(x(), y() - d->hValue/2.0) << QPointF(x(), y() + d->hValue/2.0);
return PlaceLabelImg({t.map(shape)});
};
auto RectangleShape = [t, this]()
{
QRectF rect(QPointF(x() - d->wValue/2.0, y() - d->hValue/2.0),
QPointF(x() + d->wValue/2.0, y() + d->hValue/2.0));
QPolygonF shape;
shape << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft() << rect.topLeft();
return PlaceLabelImg({t.map(shape)});
};
auto CrossShape = [t, this]()
{
QPolygonF shape1;
shape1 << QPointF(x(), y() - d->hValue/2.0)
<< QPointF(x(), y() + d->hValue/2.0);
QPolygonF shape2;
shape2 << QPointF(x() - d->wValue/2.0, y())
<< QPointF(x() + d->wValue/2.0, y());
return PlaceLabelImg({t.map(shape1), t.map(shape2)});
};
auto TshapedShape = [t, this]()
{
QPointF center2(x(), y() + d->hValue/2.0);
QPolygonF shape1;
shape1 << QPointF(x(), y()) << center2;
QPolygonF shape2;
shape2 << QPointF(center2.x() - d->wValue/2.0, center2.y())
<< QPointF(center2.x() + d->wValue/2.0, center2.y());
return PlaceLabelImg({t.map(shape1), t.map(shape2)});
};
auto DoubletreeShape = [t, this]()
{
QRectF rect(QPointF(x() - d->wValue/2.0, y() - d->hValue/2.0),
QPointF(x() + d->wValue/2.0, y() + d->hValue/2.0));
QPolygonF shape1;
shape1 << rect.topLeft() << rect.bottomRight();
QPolygonF shape2;
shape2 << rect.topRight() << rect.bottomLeft();
return PlaceLabelImg({t.map(shape1), t.map(shape2)});
};
auto CornerShape = [t, this]()
{
QPolygonF shape1;
shape1 << QPointF(x(), y()) << QPointF(x(), y() + d->hValue/2.0);
QPolygonF shape2;
shape2 << QPointF(x() - d->wValue/2.0, y()) << QPointF(x(), y());
return PlaceLabelImg({t.map(shape1), t.map(shape2)});
};
auto TriangleShape = [t, this]()
{
QRectF rect(QPointF(x() - d->wValue/2.0, y() - d->hValue/2.0),
QPointF(x() + d->wValue/2.0, y() + d->hValue/2.0));
QPolygonF shape;
shape << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.topLeft();
return PlaceLabelImg({t.map(shape)});
};
auto HshapedShape = [t, this]()
{
const QPointF center1 (x(), y() - d->hValue/2.0);
const QPointF center2 (x(), y() + d->hValue/2.0);
QPolygonF shape1;
shape1 << center1 << center2;
QPolygonF shape2;
shape2 << QPointF(center1.x() - d->wValue/2.0, center1.y())
<< QPointF(center1.x() + d->wValue/2.0, center1.y());
QPolygonF shape3;
shape3 << QPointF(center2.x() - d->wValue/2.0, center2.y())
<< QPointF(center2.x() + d->wValue/2.0, center2.y());
return PlaceLabelImg({t.map(shape1), t.map(shape2), t.map(shape3)});
};
auto ButtonShape = [t, this]()
{
const qreal radius = qMin(d->wValue/2.0, d->hValue/2.0);
QPolygonF shape1;
shape1 << QPointF(x(), y() - radius)
<< QPointF(x(), y() + radius);
QPolygonF shape2;
shape2 << QPointF(x() - radius, y())
<< QPointF(x() + radius, y());
const qreal circleSize = 0.85;
VArc arc(*this, radius*circleSize, 0, 360);
arc.SetApproximationScale(10);
QPolygonF shape3(arc.GetPoints());
if (not shape3.isClosed() && not shape3.isEmpty())
{
shape3 << ConstFirst<QPointF>(shape3);
}
return PlaceLabelImg({t.map(shape1), t.map(shape2), t.map(shape3)});
};
auto CircleShape = [t, this]()
{
const qreal radius = qMin(d->wValue/2.0, d->hValue/2.0);
VArc arc(*this, radius, 0, 360);
arc.SetApproximationScale(10);
QPolygonF circle(arc.GetPoints());
if (not circle.isClosed() && not circle.isEmpty())
{
circle << ConstFirst<QPointF>(circle);
}
return PlaceLabelImg({t.map(circle)});
};
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wswitch-default")
switch(d->type)
{
case PlaceLabelType::Segment:
return SegmentShape();
case PlaceLabelType::Rectangle:
return RectangleShape();
case PlaceLabelType::Cross:
return CrossShape();
case PlaceLabelType::Tshaped:
return TshapedShape();
case PlaceLabelType::Doubletree:
return DoubletreeShape();
case PlaceLabelType::Corner:
return CornerShape();
case PlaceLabelType::Triangle:
return TriangleShape();
case PlaceLabelType::Hshaped:
return HshapedShape();
case PlaceLabelType::Button:
return ButtonShape();
case PlaceLabelType::Circle:
return CircleShape();
}
// cppcheck-suppress unknownMacro
QT_WARNING_POP
return PlaceLabelImg();
}
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VPlaceLabelItem::LabelShapePath() const
{
return LabelShapePath(LabelShape());
}
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VPlaceLabelItem::LabelShapePath(const PlaceLabelImg &shape)
{
QPainterPath path;
for (const auto &p : shape)
{
if (not p.isEmpty())
{
path.moveTo(ConstFirst<QPointF>(p));
path.addPolygon(p);
}
}
return path;
}

View File

@ -83,12 +83,6 @@ public:
QTransform RotationMatrix() const; QTransform RotationMatrix() const;
QRectF Box() const; QRectF Box() const;
PlaceLabelImg LabelShape() const;
QPainterPath LabelShapePath() const;
static QPainterPath LabelShapePath(const PlaceLabelImg &shape);
private: private:
QSharedDataPointer<VPlaceLabelItemData> d; QSharedDataPointer<VPlaceLabelItemData> d;
}; };

View File

@ -30,6 +30,8 @@
#include "vabstractpiece_p.h" #include "vabstractpiece_p.h"
#include "../vmisc/vabstractvalapplication.h" #include "../vmisc/vabstractvalapplication.h"
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vgeometry/vlayoutplacelabel.h"
#include "../vgeometry/varc.h"
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vpatterndb/floatItemData/vgrainlinedata.h" #include "../vpatterndb/floatItemData/vgrainlinedata.h"
@ -111,7 +113,7 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
{ {
qDebug()<<"Couldn't find intersection with cut line."; qDebug()<<"Couldn't find intersection with cut line.";
} }
points.append(px); points.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
cutLine.setAngle(cutLine.angle()-180); cutLine.setAngle(cutLine.angle()-180);
type = Intersects(QLineF(sp2, sp3), cutLine, &px); type = Intersects(QLineF(sp2, sp3), cutLine, &px);
@ -120,11 +122,11 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
{ {
qDebug()<<"Couldn't find intersection with cut line."; qDebug()<<"Couldn't find intersection with cut line.";
} }
points.append(px); points.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
} }
else else
{// The point just fine {// The point just fine
points.append(sp2); points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
} }
} }
else else
@ -139,25 +141,25 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
{ {
QLineF loop(bigLine1.p2(), sp2); QLineF loop(bigLine1.p2(), sp2);
loop.setLength(loop.length() + accuracyPointOnLine*2.); loop.setLength(loop.length() + accuracyPointOnLine*2.);
points.append(loop.p2()); points.append(VRawSAPoint(loop.p2(), p.CurvePoint(), p.TurnPoint()));
points.append(sp2); points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
points.append(VRawSAPoint(bigLine1.p2(), true)); points.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint(), true));
loop = QLineF(bigLine2.p2(), sp2); loop = QLineF(bigLine2.p2(), sp2);
loop.setLength(loop.length() + localWidth); loop.setLength(loop.length() + localWidth);
points.append(VRawSAPoint(loop.p2(), true)); points.append(VRawSAPoint(loop.p2(), p.CurvePoint(), p.TurnPoint(), true));
} }
else else
{ {
QLineF loop(sp2, bigLine1.p1()); QLineF loop(sp2, bigLine1.p1());
loop.setLength(accuracyPointOnLine*2.); loop.setLength(accuracyPointOnLine*2.);
points.append(loop.p2()); points.append(VRawSAPoint(loop.p2(), p.CurvePoint(), p.TurnPoint()));
points.append(sp2); points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
loop = QLineF(bigLine1.p1(), sp2); loop = QLineF(bigLine1.p1(), sp2);
loop.setLength(loop.length() + localWidth); loop.setLength(loop.length() + localWidth);
points.append(VRawSAPoint(loop.p2(), true)); points.append(VRawSAPoint(loop.p2(), p.CurvePoint(), p.TurnPoint(), true));
points.append(VRawSAPoint(bigLine2.p1(), true)); points.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint(), true));
} }
} }
else else
@ -168,7 +170,7 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
{ {
bool success = false; bool success = false;
QVector<VRawSAPoint> temp = points; QVector<VRawSAPoint> temp = points;
temp.append(bigLine1.p2()); temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, bigLine2, &success); temp = VAbstractPiece::RollbackSeamAllowance(temp, bigLine2, &success);
if (success) if (success)
@ -183,7 +185,7 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
} }
else else
{ {
points.append(sp2); points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
} }
} }
else else
@ -194,16 +196,17 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
QLineF loop1(sp2, sp1); QLineF loop1(sp2, sp1);
loop1.setLength(loop1.length()*0.2); loop1.setLength(loop1.length()*0.2);
points.append(loop1.p2()); // Need for the main path rule // Need for the main path rule
points.append(VRawSAPoint(loop1.p2(), p.CurvePoint(), p.TurnPoint()));
loop1.setAngle(loop1.angle() + 180); loop1.setAngle(loop1.angle() + 180);
loop1.setLength(localWidth); loop1.setLength(localWidth);
points.append(loop1.p2()); points.append(VRawSAPoint(loop1.p2(), p.CurvePoint(), p.TurnPoint()));
points.append(bigLine2.p1()); points.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint()));
} }
else else
{ {
points.append(sp2); points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
} }
} }
} }
@ -252,13 +255,13 @@ auto AngleByIntersection(const QVector<VRawSAPoint> &points, QPointF p1, QPointF
{ {
return AngleByLength(points, p1, p2, p3, bigLine1, sp2, bigLine2, p, width, needRollback); return AngleByLength(points, p1, p2, p3, bigLine1, sp2, bigLine2, p, width, needRollback);
} }
pointsIntr.append(px); pointsIntr.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
} }
else else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points {// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false; bool success = false;
QVector<VRawSAPoint> temp = pointsIntr; QVector<VRawSAPoint> temp = pointsIntr;
temp.append(bigLine1.p2()); temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, edge2, &success); temp = VAbstractPiece::RollbackSeamAllowance(temp, edge2, &success);
if (success) if (success)
@ -283,16 +286,16 @@ auto AngleByIntersection(const QVector<VRawSAPoint> &points, QPointF p1, QPointF
if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px)) if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px))
{ {
pointsIntr.append(px); pointsIntr.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
} }
else else
{ {
pointsIntr.append(px); pointsIntr.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
QLineF allowance(p2, px); QLineF allowance(p2, px);
allowance.setLength(allowance.length() + localWidth * 3.); allowance.setLength(allowance.length() + localWidth * 3.);
pointsIntr.append(allowance.p2()); pointsIntr.append(VRawSAPoint(allowance.p2(), p.CurvePoint(), p.TurnPoint()));
pointsIntr.append(bigLine2.p1()); pointsIntr.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint()));
} }
return pointsIntr; return pointsIntr;
@ -343,13 +346,13 @@ auto AngleByFirstSymmetry(const QVector<VRawSAPoint> &points, QPointF p1, QPoint
if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px1)) if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px1))
{ {
pointsIntr.append(px1); pointsIntr.append(VRawSAPoint(px1, p.CurvePoint(), p.TurnPoint()));
} }
else else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points {// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false; bool success = false;
QVector<VRawSAPoint> temp = pointsIntr; QVector<VRawSAPoint> temp = pointsIntr;
temp.append(bigLine1.p2()); temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, sEdge, &success); temp = VAbstractPiece::RollbackSeamAllowance(temp, sEdge, &success);
if (success) if (success)
@ -365,15 +368,15 @@ auto AngleByFirstSymmetry(const QVector<VRawSAPoint> &points, QPointF p1, QPoint
if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px2)) if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px2))
{ {
pointsIntr.append(px2); pointsIntr.append(VRawSAPoint(px2, p.CurvePoint(), p.TurnPoint()));
} }
else else
{ {
QLineF allowance(px2, p2); QLineF allowance(px2, p2);
allowance.setAngle(allowance.angle() + 90); allowance.setAngle(allowance.angle() + 90);
pointsIntr.append(px2); pointsIntr.append(VRawSAPoint(px2, p.CurvePoint(), p.TurnPoint()));
pointsIntr.append(allowance.p2()); pointsIntr.append(VRawSAPoint(allowance.p2(), p.CurvePoint(), p.TurnPoint()));
pointsIntr.append(bigLine2.p1()); pointsIntr.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint()));
} }
return pointsIntr; return pointsIntr;
@ -425,13 +428,13 @@ auto AngleBySecondSymmetry(const QVector<VRawSAPoint> &points, QPointF p1, QPoin
if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px1)) if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px1))
{ {
pointsIntr.append(px1); pointsIntr.append(VRawSAPoint(px1, p.CurvePoint(), p.TurnPoint()));
} }
else else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points {// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false; bool success = false;
QVector<VRawSAPoint> temp = pointsIntr; QVector<VRawSAPoint> temp = pointsIntr;
temp.append(bigLine1.p2()); temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, sEdge, &success); temp = VAbstractPiece::RollbackSeamAllowance(temp, sEdge, &success);
if (success) if (success)
@ -447,16 +450,16 @@ auto AngleBySecondSymmetry(const QVector<VRawSAPoint> &points, QPointF p1, QPoin
if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px2)) if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px2))
{ {
pointsIntr.append(px2); pointsIntr.append(VRawSAPoint(px2, p.CurvePoint(), p.TurnPoint()));
} }
else else
{ {
QLineF allowance(p2, px2); QLineF allowance(p2, px2);
allowance.setLength(p.GetSAAfter(width)*0.98); allowance.setLength(p.GetSAAfter(width)*0.98);
pointsIntr.append(allowance.p2()); pointsIntr.append(VRawSAPoint(allowance.p2(), p.CurvePoint(), p.TurnPoint()));
allowance.setLength(allowance.length() + localWidth * 3.); allowance.setLength(allowance.length() + localWidth * 3.);
pointsIntr.append(allowance.p2()); pointsIntr.append(VRawSAPoint(allowance.p2(), p.CurvePoint(), p.TurnPoint()));
pointsIntr.append(bigLine2.p1()); pointsIntr.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint()));
} }
return pointsIntr; return pointsIntr;
@ -500,8 +503,8 @@ auto AngleByFirstRightAngle(const QVector<VRawSAPoint> &points, QPointF p1, QPoi
{ {
return AngleByLength(points, p1, p2, p3, bigLine1, sp2, bigLine2, p, width, needRollback); return AngleByLength(points, p1, p2, p3, bigLine1, sp2, bigLine2, p, width, needRollback);
} }
pointsRA.append(seam.p2()); pointsRA.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
pointsRA.append(seam.p1()); pointsRA.append(VRawSAPoint(seam.p1(), p.CurvePoint(), p.TurnPoint()));
} }
else else
{ {
@ -514,7 +517,7 @@ auto AngleByFirstRightAngle(const QVector<VRawSAPoint> &points, QPointF p1, QPoi
return AngleByLength(points, p1, p2, p3, bigLine1, sp2, bigLine2, p, width, needRollback); return AngleByLength(points, p1, p2, p3, bigLine1, sp2, bigLine2, p, width, needRollback);
} }
pointsRA.append(seam.p2()); pointsRA.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
QLineF loopLine(px, sp2); QLineF loopLine(px, sp2);
const qreal length = loopLine.length()*0.98; const qreal length = loopLine.length()*0.98;
@ -523,8 +526,8 @@ auto AngleByFirstRightAngle(const QVector<VRawSAPoint> &points, QPointF p1, QPoi
QLineF tmp(seam.p2(), seam.p1()); QLineF tmp(seam.p2(), seam.p1());
tmp.setLength(tmp.length()+length); tmp.setLength(tmp.length()+length);
pointsRA.append(tmp.p2()); pointsRA.append(VRawSAPoint(tmp.p2(), p.CurvePoint(), p.TurnPoint()));
pointsRA.append(loopLine.p2()); pointsRA.append(VRawSAPoint(loopLine.p2(), p.CurvePoint(), p.TurnPoint()));
} }
return pointsRA; return pointsRA;
@ -568,12 +571,12 @@ auto AngleBySecondRightAngle(QVector<VRawSAPoint> points, QPointF p1, QPointF p2
{ {
return AngleByLength(points, p1, p2, p3, bigLine1, sp2, bigLine2, p, width, needRollback); return AngleByLength(points, p1, p2, p3, bigLine1, sp2, bigLine2, p, width, needRollback);
} }
points.append(px); points.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
QLineF seam(px, p3); QLineF seam(px, p3);
seam.setAngle(seam.angle()+90); seam.setAngle(seam.angle()+90);
seam.setLength(p.GetSAAfter(width)); seam.setLength(p.GetSAAfter(width));
points.append(seam.p2()); points.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
if (needRollback != nullptr) if (needRollback != nullptr)
{ {
@ -595,7 +598,7 @@ auto AngleBySecondRightAngle(QVector<VRawSAPoint> points, QPointF p1, QPointF p2
bool success = false; bool success = false;
const int countBefore = points.size(); const int countBefore = points.size();
QVector<VRawSAPoint> temp = points; QVector<VRawSAPoint> temp = points;
temp.append(bigLine1.p2()); temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, edge, &success); temp = VAbstractPiece::RollbackSeamAllowance(temp, edge, &success);
if (success) if (success)
@ -609,7 +612,7 @@ auto AngleBySecondRightAngle(QVector<VRawSAPoint> points, QPointF p1, QPointF p2
QLineF seam(px, p3); QLineF seam(px, p3);
seam.setAngle(seam.angle()+90); seam.setAngle(seam.angle()+90);
seam.setLength(p.GetSAAfter(width)); seam.setLength(p.GetSAAfter(width));
points.append(seam.p2()); points.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
} }
else else
{ {
@ -619,11 +622,11 @@ auto AngleBySecondRightAngle(QVector<VRawSAPoint> points, QPointF p1, QPointF p2
} }
else if (IsSameDirection(bigLine1.p1(), bigLine1.p2(), px)) else if (IsSameDirection(bigLine1.p1(), bigLine1.p2(), px))
{ {
points.append(px); points.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
QLineF seam(px, p3); QLineF seam(px, p3);
seam.setAngle(seam.angle()+90); seam.setAngle(seam.angle()+90);
seam.setLength(p.GetSAAfter(width)); seam.setLength(p.GetSAAfter(width));
points.append(seam.p2()); points.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
} }
} }
} }
@ -756,7 +759,7 @@ void RollbackByLength(QVector<VRawSAPoint> &ekvPoints, const QVector<VSAPoint> &
const QLineF bigLine1 = VAbstractPiece::ParallelLine(points.at(points.size()-2), points.at(0), width); const QLineF bigLine1 = VAbstractPiece::ParallelLine(points.at(points.size()-2), points.at(0), width);
QVector<VRawSAPoint> temp = ekvPoints; QVector<VRawSAPoint> temp = ekvPoints;
temp.insert(ekvPoints.size()-1, bigLine1.p2()); temp.insert(ekvPoints.size()-1, VRawSAPoint(bigLine1.p2(), points.at(0).CurvePoint(), points.at(0).TurnPoint()));
bool success = Rollback(temp, VAbstractPiece::ParallelLine(points.at(0), points.at(1), width)); bool success = Rollback(temp, VAbstractPiece::ParallelLine(points.at(0), points.at(1), width));
if (success) if (success)
@ -773,7 +776,7 @@ void RollbackBySecondEdgeSymmetry(QVector<VRawSAPoint> &ekvPoints, const QVector
QLineF sEdge(VPointF::FlipPF(axis, bigLine1.p1()), VPointF::FlipPF(axis, bigLine1.p2())); QLineF sEdge(VPointF::FlipPF(axis, bigLine1.p1()), VPointF::FlipPF(axis, bigLine1.p2()));
QVector<VRawSAPoint> temp = ekvPoints; QVector<VRawSAPoint> temp = ekvPoints;
temp.insert(ekvPoints.size()-1, bigLine1.p2()); temp.insert(ekvPoints.size()-1, VRawSAPoint(bigLine1.p2(), points.at(0).CurvePoint(), points.at(0).TurnPoint()));
bool success = Rollback(temp, sEdge); bool success = Rollback(temp, sEdge);
if (success) if (success)
@ -791,7 +794,7 @@ void RollbackByFirstEdgeSymmetry(QVector<VRawSAPoint> &ekvPoints, const QVector<
const QLineF bigLine1 = VAbstractPiece::ParallelLine(points.at(points.size()-2), points.at(0), width); const QLineF bigLine1 = VAbstractPiece::ParallelLine(points.at(points.size()-2), points.at(0), width);
QVector<VRawSAPoint> temp = ekvPoints; QVector<VRawSAPoint> temp = ekvPoints;
temp.insert(ekvPoints.size()-1, bigLine1.p2()); temp.insert(ekvPoints.size()-1, VRawSAPoint(bigLine1.p2(), points.at(0).CurvePoint(), points.at(0).TurnPoint()));
bool success = Rollback(temp, sEdge); bool success = Rollback(temp, sEdge);
if (success) if (success)
@ -805,7 +808,7 @@ void RollbackByPointsIntersection(QVector<VRawSAPoint> &ekvPoints, const QVector
{ {
const QLineF bigLine1 = VAbstractPiece::ParallelLine(points.at(points.size()-2), points.at(0), width); const QLineF bigLine1 = VAbstractPiece::ParallelLine(points.at(points.size()-2), points.at(0), width);
QVector<VRawSAPoint> temp = ekvPoints; QVector<VRawSAPoint> temp = ekvPoints;
temp.insert(ekvPoints.size()-1, bigLine1.p2()); temp.insert(ekvPoints.size()-1, VRawSAPoint(bigLine1.p2(), points.at(0).CurvePoint(), points.at(0).TurnPoint()));
bool success = Rollback(temp, QLineF(ConstLast(points), points.at(1))); bool success = Rollback(temp, QLineF(ConstLast(points), points.at(1)));
if (success) if (success)
@ -848,7 +851,7 @@ void RollbackBySecondEdgeRightAngle(QVector<VRawSAPoint> &ekvPoints, const QVect
ekvPoints.removeFirst(); ekvPoints.removeFirst();
ekvPoints.removeLast(); ekvPoints.removeLast();
ekvPoints.append(crosPoint); ekvPoints.append(VRawSAPoint(crosPoint, ekvPoints.at(0).CurvePoint(), ekvPoints.at(0).TurnPoint()));
} }
} }
} }
@ -856,7 +859,7 @@ void RollbackBySecondEdgeRightAngle(QVector<VRawSAPoint> &ekvPoints, const QVect
{ {
bool success = false; bool success = false;
QVector<VRawSAPoint> temp = ekvPoints; QVector<VRawSAPoint> temp = ekvPoints;
temp.append(bigLine1.p2()); temp.append(VRawSAPoint(bigLine1.p2(), ekvPoints.at(0).CurvePoint(), ekvPoints.at(0).TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, edge, &success); temp = VAbstractPiece::RollbackSeamAllowance(temp, edge, &success);
if (success) if (success)
@ -868,7 +871,7 @@ void RollbackBySecondEdgeRightAngle(QVector<VRawSAPoint> &ekvPoints, const QVect
QLineF seam(px, points.at(1)); QLineF seam(px, points.at(1));
seam.setAngle(seam.angle()+90); seam.setAngle(seam.angle()+90);
seam.setLength(points.at(0).GetSAAfter(width)); seam.setLength(points.at(0).GetSAAfter(width));
ekvPoints.append(seam.p2()); ekvPoints.append(VRawSAPoint(seam.p2(), ekvPoints.at(0).CurvePoint(), ekvPoints.at(0).TurnPoint()));
if (not ekvPoints.isEmpty()) if (not ekvPoints.isEmpty())
{ {
@ -885,22 +888,6 @@ void RollbackBySecondEdgeRightAngle(QVector<VRawSAPoint> &ekvPoints, const QVect
} }
} }
} }
//---------------------------------------------------------------------------------------------------------------------
auto CleanLoopArtifacts(const QVector<VRawSAPoint> &points) -> QVector<QPointF>
{
QVector<QPointF> cleaned;
cleaned.reserve(points.size());
for (const auto &point : points)
{
if (not point.LoopPoint())
{
cleaned.append(point);
}
}
return cleaned;
}
} // namespace } // namespace
// Friend functions // Friend functions
@ -1052,7 +1039,7 @@ void VAbstractPiece::SetSAWidth(qreal value)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::Equidistant(QVector<VSAPoint> points, qreal width, const QString &name) -> QVector<QPointF> auto VAbstractPiece::Equidistant(QVector<VSAPoint> points, qreal width, const QString &name) -> QVector<VLayoutPoint>
{ {
if (width < 0) if (width < 0)
{ {
@ -1136,19 +1123,14 @@ auto VAbstractPiece::Equidistant(QVector<VSAPoint> points, qreal width, const QS
} }
// Uncomment for debug // Uncomment for debug
// QVector<QPointF> cleaned; // QVector<VLayoutPoint> cleaned = CastTo<VLayoutPoint>(ekvPoints);
// cleaned.reserve(ekvPoints.size());
// for (auto &point : ekvPoints)
// {
// cleaned.append(point);
// }
const bool removeFirstAndLast = false; const bool removeFirstAndLast = false;
ekvPoints = RemoveDublicates(ekvPoints, removeFirstAndLast); ekvPoints = RemoveDublicates(ekvPoints, removeFirstAndLast);
QVector<QPointF> cleaned = CheckLoops(ekvPoints);//Result path can contain loops QVector<VLayoutPoint> cleaned = CastTo<VLayoutPoint>(CheckLoops(ekvPoints));//Result path can contain loops
cleaned = CorrectEquidistantPoints(cleaned, removeFirstAndLast); cleaned = CorrectEquidistantPoints(cleaned, removeFirstAndLast);
cleaned = CorrectPathDistortion(cleaned); cleaned = CorrectPathDistortion(cleaned);
// DumpVector(cleaned, QStringLiteral("output.json.XXXXXX")); // Uncomment for dumping test data // DumpVector(CastTo<QPointF>(cleaned), QStringLiteral("output.json.XXXXXX")); // Uncomment for dumping test data
return cleaned; return cleaned;
} }
@ -1188,131 +1170,6 @@ auto VAbstractPiece::SumTrapezoids(const QVector<QPointF> &points) -> qreal
return res; return res;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::CheckLoops(const QVector<QPointF> &points) -> QVector<QPointF>
{
QVector<VRawSAPoint> rawPath;
rawPath.reserve(points.size());
for (const auto &point : points)
{
rawPath.append(point);
}
return CheckLoops(rawPath);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief CheckLoops seek and delete loops in equidistant.
* @param points vector of points of equidistant.
* @return vector of points of equidistant.
*/
auto VAbstractPiece::CheckLoops(const QVector<VRawSAPoint> &points) -> QVector<QPointF>
{
// DumpVector(points, QStringLiteral("input.json.XXXXXX")); // Uncomment for dumping test data
/*If we got less than 4 points no need seek loops.*/
if (points.size() < 4)
{
return CleanLoopArtifacts(points);
}
bool loopFound = false;
auto CheckLoop = [&loopFound](const QVector<VRawSAPoint> &points)
{
loopFound = false;
const bool pathClosed = (ConstFirst(points) == ConstLast(points));
QVector<VRawSAPoint> ekvPoints;
ekvPoints.reserve(points.size());
qint32 i;
for (i = 0; i < points.size(); ++i)
{
/*Last three points no need to check.*/
/*Triangle can not contain a loop*/
if (loopFound || i > points.size()-4)
{
ekvPoints.append(points.at(i));
continue;
}
enum LoopIntersectType { NoIntersection, BoundedIntersection, ParallelIntersection };
QPointF crosPoint;
LoopIntersectType status = NoIntersection;
const QLineF line1(points.at(i), points.at(i+1));
const int limit = pathClosed && i == 0 ? 2 : 1;
qint32 j;
for (j = i+2; j < points.size()-limit; ++j)
{
QLineF line2(points.at(j), points.at(j+1));
const QLineF::IntersectType intersect = Intersects(line1, line2, &crosPoint);
if (intersect == QLineF::NoIntersection)
{ // According to the documentation QLineF::NoIntersection indicates that the lines do not intersect;
// i.e. they are parallel. But parallel also mean they can be on the same line.
// Method IsLineSegmentOnLineSegment will check it.
if (VGObject::IsLineSegmentOnLineSegment(line1, line2))
{// Now we really sure that segments are on the same line and have real intersections.
status = ParallelIntersection;
break;
}
}
else if (intersect == QLineF::BoundedIntersection)
{
status = BoundedIntersection;
break;
}
}
switch (status)
{
case ParallelIntersection:
/*We have found a loop.*/
ekvPoints.append(points.at(i));
ekvPoints.append(points.at(j+1));
i = j+1; // Skip a loop
loopFound = true;
break;
case BoundedIntersection:
ekvPoints.append(points.at(i));
ekvPoints.append(crosPoint);
i = j;
loopFound = true;
break;
case NoIntersection:
/*We have not found loop.*/
ekvPoints.append(points.at(i));
break;
default:
break;
}
}
return ekvPoints;
};
QVector<VRawSAPoint> ekvPoints = points;
qint32 i;
const int maxLoops = 10000; // limit number of loops to be removed
for (i = 0; i < maxLoops; ++i)
{
ekvPoints = CheckLoop(ekvPoints);
if (not loopFound)
{
break;
}
}
const QVector<QPointF> cleaned = CleanLoopArtifacts(ekvPoints);
// DumpVector(cleaned, QStringLiteral("output.json.XXXXXX")); // Uncomment for dumping test data
return cleaned;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief EkvPoint return seam aloowance points in place of intersection two edges. Last points of two edges should be * @brief EkvPoint return seam aloowance points in place of intersection two edges. Last points of two edges should be
@ -1342,7 +1199,7 @@ auto VAbstractPiece::EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Lin
if (VFuzzyComparePoints(bigLine1.p2(), bigLine2.p1())) if (VFuzzyComparePoints(bigLine1.p2(), bigLine2.p1()))
{ {
points.append(bigLine1.p2()); points.append(VRawSAPoint(bigLine1.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points; return points;
} }
@ -1357,16 +1214,16 @@ auto VAbstractPiece::EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Lin
ray.setLength(width*2); ray.setLength(width*2);
QPointF crosPoint; QPointF crosPoint;
QLineF::IntersectType type = Intersects(ray, bigLine1, &crosPoint ); QLineF::IntersectType type = Intersects(ray, bigLine1, &crosPoint);
if (type != QLineF::NoIntersection) if (type != QLineF::NoIntersection)
{ {
points.append(crosPoint); points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
} }
type = Intersects(ray, bigLine2, &crosPoint ); type = Intersects(ray, bigLine2, &crosPoint );
if (type != QLineF::NoIntersection) if (type != QLineF::NoIntersection)
{ {
points.append(crosPoint); points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
} }
return points; return points;
} }
@ -1378,7 +1235,7 @@ auto VAbstractPiece::EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Lin
{// There are at least three big cases {// There are at least three big cases
case (QLineF::BoundedIntersection): case (QLineF::BoundedIntersection):
// The easiest, real intersection // The easiest, real intersection
points.append(crosPoint); points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points; return points;
case (QLineF::UnboundedIntersection): case (QLineF::UnboundedIntersection):
{ // Most common case { // Most common case
@ -1400,8 +1257,8 @@ auto VAbstractPiece::EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Lin
if (VGObject::IsPointOnLineSegment(p2Line1, p1Line1, p1Line2, ToPixel(0.5, Unit::Mm)) && if (VGObject::IsPointOnLineSegment(p2Line1, p1Line1, p1Line2, ToPixel(0.5, Unit::Mm)) &&
IsOnLine(p2Line1, bigLine1.p2(), bigLine2.p1(), ToPixel(0.5, Unit::Mm))) IsOnLine(p2Line1, bigLine1.p2(), bigLine2.p1(), ToPixel(0.5, Unit::Mm)))
{ {
points.append(bigLine1.p2()); points.append(VRawSAPoint(bigLine1.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
points.append(bigLine2.p1()); points.append(VRawSAPoint(bigLine2.p1(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points; return points;
} }
@ -1473,7 +1330,7 @@ QT_WARNING_POP
const QLineF::IntersectType type = Intersects(bigEdge, line, &px); const QLineF::IntersectType type = Intersects(bigEdge, line, &px);
if (type != QLineF::BoundedIntersection && line.length() < QLineF(p2Line1, px).length()) if (type != QLineF::BoundedIntersection && line.length() < QLineF(p2Line1, px).length())
{ {
points.append(crosPoint); points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points; return points;
} }
} }
@ -1484,12 +1341,12 @@ QT_WARNING_POP
QLineF loop(crosPoint, bigLine1.p1()); QLineF loop(crosPoint, bigLine1.p1());
loop.setAngle(loop.angle() + 180); loop.setAngle(loop.angle() + 180);
loop.setLength(accuracyPointOnLine*2.); loop.setLength(accuracyPointOnLine*2.);
points.append(loop.p2()); points.append(VRawSAPoint(loop.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
points.append(crosPoint); points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
loop = QLineF(crosPoint, bigLine1.p1()); loop = QLineF(crosPoint, bigLine1.p1());
loop.setLength(loop.length() + localWidth*2.); loop.setLength(loop.length() + localWidth*2.);
points.append(VRawSAPoint(loop.p2(), true)); points.append(VRawSAPoint(loop.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint(), true));
} }
return points; return points;
@ -1504,20 +1361,20 @@ QT_WARNING_POP
{// The cross point is still outside of a piece {// The cross point is still outside of a piece
if (line.length() >= localWidth) if (line.length() >= localWidth)
{ {
points.append(crosPoint); points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points; return points;
} }
// but not enough far, fix it // but not enough far, fix it
line.setLength(localWidth); line.setLength(localWidth);
points.append(line.p2()); points.append(VRawSAPoint(line.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points; return points;
} }
// Wrong cross point, probably inside of a piece. Manually creating correct seam allowance // Wrong cross point, probably inside of a piece. Manually creating correct seam allowance
const QLineF bigEdge = SimpleParallelLine(bigLine1.p2(), bigLine2.p1(), localWidth ); const QLineF bigEdge = SimpleParallelLine(bigLine1.p2(), bigLine2.p1(), localWidth );
points.append(bigEdge.p1()); points.append(VRawSAPoint(bigEdge.p1(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
points.append(bigEdge.p2()); points.append(VRawSAPoint(bigEdge.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points; return points;
} }
} }
@ -1525,8 +1382,9 @@ QT_WARNING_POP
} }
case (QLineF::NoIntersection): case (QLineF::NoIntersection):
/*If we have correct lines this means lines lie on a line or parallel.*/ /*If we have correct lines this means lines lie on a line or parallel.*/
points.append(bigLine1.p2()); points.append(VRawSAPoint(bigLine1.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
points.append(bigLine2.p1()); // Second point for parallel line // Second point for parallel line
points.append(VRawSAPoint(bigLine2.p1(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points; return points;
default: default:
break; break;
@ -1657,10 +1515,8 @@ auto VAbstractPiece::GetUniqueID() const -> QString
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VSAPoint::toJson() const -> QJsonObject auto VSAPoint::toJson() const -> QJsonObject
{ {
QJsonObject pointObject; QJsonObject pointObject = VLayoutPoint::toJson();
pointObject[QLatin1String("type")] = "VSAPoint"; pointObject[QLatin1String("type")] = "VSAPoint";
pointObject[QLatin1String("x")] = x();
pointObject[QLatin1String("y")] = y();
if (not VFuzzyComparePossibleNulls(m_before, -1)) if (not VFuzzyComparePossibleNulls(m_before, -1))
{ {
@ -1698,7 +1554,7 @@ auto VAbstractPiece::RollbackSeamAllowance(QVector<VRawSAPoint> points, const QL
&& VGObject::IsPointOnLineSegment(crosPoint, segment.p1(), segment.p2()) && VGObject::IsPointOnLineSegment(crosPoint, segment.p1(), segment.p2())
&& IsSameDirection(cuttingEdge.p2(), cuttingEdge.p1(), crosPoint)) && IsSameDirection(cuttingEdge.p2(), cuttingEdge.p1(), crosPoint))
{ {
clipped.append(crosPoint); clipped.append(VRawSAPoint(crosPoint, points.at(i).CurvePoint(), points.at(i).TurnPoint()));
for (int j=i-1; j>=0; --j) for (int j=i-1; j>=0; --j)
{ {
clipped.append(points.at(j)); clipped.append(points.at(j));
@ -1717,7 +1573,8 @@ auto VAbstractPiece::RollbackSeamAllowance(QVector<VRawSAPoint> points, const QL
if (type != QLineF::NoIntersection && IsOutsidePoint(secondLast.p1(), secondLast.p2(), crosPoint)) if (type != QLineF::NoIntersection && IsOutsidePoint(secondLast.p1(), secondLast.p2(), crosPoint))
{ {
points.append(crosPoint); points.append(VRawSAPoint(crosPoint, points.at(points.size()-1).CurvePoint(),
points.at(points.size()-1).TurnPoint()));
*success = true; *success = true;
} }
} }
@ -1919,20 +1776,341 @@ auto VAbstractPiece::GrainlinePoints(const VGrainlineData &geom, const VContaine
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::PainterPath(const QVector<QPointF> &points) -> QPainterPath auto VAbstractPiece::PlaceLabelShape(const VLayoutPlaceLabel &label) -> PlaceLabelImg
{ {
QPainterPath path; auto LayoutPoint = [label](QPointF p, bool turnPoint = false, bool curvePoint = false)
path.setFillRule(Qt::WindingFill);
if (not points.isEmpty())
{ {
path.moveTo(points.at(0)); VLayoutPoint point(label.RotationMatrix().map(p));
for (qint32 i = 1; i < points.count(); ++i) point.SetTurnPoint(turnPoint);
point.SetCurvePoint(curvePoint);
return point;
};
const QPointF pos = label.Center();
const QRectF box = label.Box();
auto SegmentShape = [pos, box, LayoutPoint]()
{
QVector<VLayoutPoint> shape
{ {
path.lineTo(points.at(i)); LayoutPoint(QPointF(pos.x(), pos.y() - box.height()/2.0), true),
LayoutPoint(QPointF(pos.x(), pos.y() + box.height()/2.0), true)
};
return PlaceLabelImg{shape};
};
auto RectangleShape = [pos, box, LayoutPoint]()
{
QRectF rect(QPointF(pos.x() - box.width()/2.0, pos.y() - box.height()/2.0),
QPointF(pos.x() + box.width()/2.0, pos.y() + box.height()/2.0));
QVector<VLayoutPoint> shape
{
LayoutPoint(rect.topLeft(), true),
LayoutPoint(rect.topRight(), true),
LayoutPoint(rect.bottomRight(), true),
LayoutPoint(rect.bottomLeft(), true),
LayoutPoint(rect.topLeft(), true)
};
return PlaceLabelImg{shape};
};
auto CrossShape = [pos, box, LayoutPoint]()
{
QVector<VLayoutPoint> shape1
{
LayoutPoint(QPointF(pos.x(), pos.y() - box.height()/2.0), true),
LayoutPoint(QPointF(pos.x(), pos.y() + box.height()/2.0), true)
};
QVector<VLayoutPoint> shape2
{
LayoutPoint(QPointF(pos.x() - box.width()/2.0, pos.y()), true),
LayoutPoint(QPointF(pos.x() + box.width()/2.0, pos.y()), true)
};
return PlaceLabelImg{shape1, shape2};
};
auto TshapedShape = [pos, box, LayoutPoint]()
{
QPointF center2(pos.x(), pos.y() + box.height()/2.0);
QVector<VLayoutPoint> shape1
{
LayoutPoint(QPointF(pos.x(), pos.y()), true),
LayoutPoint(center2, true)
};
QVector<VLayoutPoint> shape2
{
LayoutPoint(QPointF(center2.x() - box.width()/2.0, center2.y()), true),
LayoutPoint(QPointF(center2.x() + box.width()/2.0, center2.y()), true)
};
return PlaceLabelImg{shape1, shape2};
};
auto DoubletreeShape = [pos, box, LayoutPoint]()
{
QRectF rect(QPointF(pos.x() - box.width()/2.0, pos.y() - box.height()/2.0),
QPointF(pos.x() + box.width()/2.0, pos.y() + box.height()/2.0));
QVector<VLayoutPoint> shape1
{
LayoutPoint(rect.topLeft(), true),
LayoutPoint(rect.bottomRight(), true)
};
QVector<VLayoutPoint> shape2
{
LayoutPoint(rect.topRight(), true),
LayoutPoint(rect.bottomLeft(), true)
};
return PlaceLabelImg{shape1, shape2};
};
auto CornerShape = [pos, box, LayoutPoint]()
{
QVector<VLayoutPoint> shape1
{
LayoutPoint(QPointF(pos.x(), pos.y()), true),
LayoutPoint(QPointF(pos.x(), pos.y() + box.height()/2.0), true)
};
QVector<VLayoutPoint> shape2
{
LayoutPoint(QPointF(pos.x() - box.width()/2.0, pos.y()), true),
LayoutPoint(QPointF(pos.x(), pos.y()), true)
};
return PlaceLabelImg{shape1, shape2};
};
auto TriangleShape = [pos, box, LayoutPoint]()
{
QRectF rect(QPointF(pos.x() - box.width()/2.0, pos.y() - box.height()/2.0),
QPointF(pos.x() + box.width()/2.0, pos.y() + box.height()/2.0));
QVector<VLayoutPoint> shape
{
LayoutPoint(rect.topLeft(), true),
LayoutPoint(rect.topRight(), true),
LayoutPoint(rect.bottomRight(), true),
LayoutPoint(rect.topLeft(), true)
};
return PlaceLabelImg{shape};
};
auto HshapedShape = [pos, box, LayoutPoint]()
{
const QPointF center1 (pos.x(), pos.y() - box.height()/2.0);
const QPointF center2 (pos.x(), pos.y() + box.height()/2.0);
QVector<VLayoutPoint> shape1
{
LayoutPoint(center1, true),
LayoutPoint(center2, true)
};
QVector<VLayoutPoint> shape2
{
LayoutPoint(QPointF(center1.x() - box.width()/2.0, center1.y()), true),
LayoutPoint(QPointF(center1.x() + box.width()/2.0, center1.y()), true)
};
QVector<VLayoutPoint> shape3
{
LayoutPoint(QPointF(center2.x() - box.width()/2.0, center2.y()), true),
LayoutPoint(QPointF(center2.x() + box.width()/2.0, center2.y()), true)
};
return PlaceLabelImg{shape1, shape2, shape3};
};
auto ButtonShape = [pos, box, LayoutPoint]()
{
const qreal radius = qMin(box.width()/2.0, box.height()/2.0);
QVector<VLayoutPoint> shape1
{
LayoutPoint(QPointF(pos.x(), pos.y() - radius), true),
LayoutPoint(QPointF(pos.x(), pos.y() + radius), true)
};
QVector<VLayoutPoint> shape2
{
LayoutPoint(QPointF(pos.x() - radius, pos.y()), true),
LayoutPoint(QPointF(pos.x() + radius, pos.y()), true)
};
const qreal circleSize = 0.85;
VArc arc(VPointF(pos), radius*circleSize, 0, 360);
arc.SetApproximationScale(10);
QVector<QPointF> points = arc.GetPoints();
if (not points.isEmpty() && ConstFirst(points) != ConstLast(points))
{
points.append(ConstFirst(points));
} }
path.lineTo(points.at(0));
QVector<VLayoutPoint> shape3;
for (int i=0; i < points.size(); ++i)
{
bool turnPoint = false;
if (i == 0 || i == points.size() -1)
{
turnPoint = true;
}
shape3.append(LayoutPoint(points.at(i), turnPoint, true));
}
return PlaceLabelImg{shape1, shape2, shape3};
};
auto CircleShape = [pos, box, LayoutPoint]()
{
const qreal radius = qMin(box.width()/2.0, box.height()/2.0);
VArc arc(VPointF(pos), radius, 0, 360);
arc.SetApproximationScale(10);
QVector<QPointF> points = arc.GetPoints();
if (not points.isEmpty() && ConstFirst(points) != ConstLast(points))
{
points.append(ConstFirst(points));
}
QVector<VLayoutPoint> circle;
for (int i=0; i < points.size(); ++i)
{
bool turnPoint = false;
if (i == 0 || i == points.size() -1)
{
turnPoint = true;
}
circle.append(LayoutPoint(points.at(i), turnPoint, true));
}
return PlaceLabelImg{circle};
};
switch(label.Type())
{
case PlaceLabelType::Segment:
return SegmentShape();
case PlaceLabelType::Rectangle:
return RectangleShape();
case PlaceLabelType::Cross:
return CrossShape();
case PlaceLabelType::Tshaped:
return TshapedShape();
case PlaceLabelType::Doubletree:
return DoubletreeShape();
case PlaceLabelType::Corner:
return CornerShape();
case PlaceLabelType::Triangle:
return TriangleShape();
case PlaceLabelType::Hshaped:
return HshapedShape();
case PlaceLabelType::Button:
return ButtonShape();
case PlaceLabelType::Circle:
return CircleShape();
default:
return {};
} }
return {};
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::LabelShapePath(const VLayoutPlaceLabel &label) -> QPainterPath
{
return LabelShapePath(PlaceLabelShape(label));
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::LabelShapePath(const PlaceLabelImg &shape) -> QPainterPath
{
QPainterPath path;
for (const auto &p : shape)
{
if (not p.isEmpty())
{
path.moveTo(ConstFirst<QPointF>(p));
path.addPolygon(CastTo<QPointF>(p));
}
}
return path; return path;
} }
//---------------------------------------------------------------------------------------------------------------------
template <class T>
auto VAbstractPiece::ComparePoints(QVector<T> &points, const T &p1, const T &p2, qreal accuracy) -> bool
{
if (not VFuzzyComparePoints(p1, p2, accuracy))
{
points.append(p2);
return false;
}
if (not points.isEmpty() && p2.TurnPoint())
{
points.last().SetTurnPoint(true);
}
if (not points.isEmpty() && p2.CurvePoint())
{
points.last().SetCurvePoint(true);
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
template <>
auto VAbstractPiece::ComparePoints<QPointF>(QVector<QPointF> &points, const QPointF &p1, const QPointF &p2,
qreal accuracy) -> bool
{
if (not VFuzzyComparePoints(p1, p2, accuracy))
{
points.append(p2);
return false;
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
template <class T>
auto VAbstractPiece::CompareFirstAndLastPoints(QVector<T> &points, qreal accuracy) -> void
{
if (VFuzzyComparePoints(ConstFirst(points), ConstLast(points), accuracy))
{
const T& l = ConstLast(points);
points.removeLast();
if (not points.isEmpty() && l.TurnPoint())
{
points.last().SetTurnPoint(true);
}
if (not points.isEmpty() && l.CurvePoint())
{
points.last().SetCurvePoint(true);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
template <>
auto VAbstractPiece::CompareFirstAndLastPoints<QPointF>(QVector<QPointF> &points, qreal accuracy) -> void
{
if (VFuzzyComparePoints(ConstFirst(points), ConstLast(points), accuracy))
{
points.removeLast();
}
}

View File

@ -45,6 +45,9 @@ class QPainterPath;
class VGrainlineData; class VGrainlineData;
class VContainer; class VContainer;
class VRawSAPoint; class VRawSAPoint;
class VLayoutPlaceLabel;
using PlaceLabelImg = QVector<QVector<VLayoutPoint> >;
class VAbstractPiece class VAbstractPiece
{ {
@ -100,10 +103,10 @@ public:
*/ */
virtual auto GetUniqueID() const -> QString; virtual auto GetUniqueID() const -> QString;
static auto Equidistant(QVector<VSAPoint> points, qreal width, const QString &name) -> QVector<QPointF>; static auto Equidistant(QVector<VSAPoint> points, qreal width, const QString &name) -> QVector<VLayoutPoint>;
static auto SumTrapezoids(const QVector<QPointF> &points) -> qreal; static auto SumTrapezoids(const QVector<QPointF> &points) -> qreal;
static auto CheckLoops(const QVector<QPointF> &points) -> QVector<QPointF>; template <class T>
static auto CheckLoops(const QVector<VRawSAPoint> &points) -> QVector<QPointF>; static auto CheckLoops(QVector<T> points) -> QVector<T>;
static auto EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Line1, const VSAPoint &p2Line1, static auto EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Line1, const VSAPoint &p2Line1,
const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width, const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width,
bool *needRollback = nullptr) -> QVector<VRawSAPoint>; bool *needRollback = nullptr) -> QVector<VRawSAPoint>;
@ -122,28 +125,81 @@ public:
static auto GrainlinePoints(const VGrainlineData &geom, const VContainer *pattern, static auto GrainlinePoints(const VGrainlineData &geom, const VContainer *pattern,
const QRectF &boundingRect, qreal &dAng) -> QVector<QPointF>; const QRectF &boundingRect, qreal &dAng) -> QVector<QPointF>;
static auto PainterPath(const QVector<QPointF> &points) -> QPainterPath; template <class T>
static auto PainterPath(const QVector<T> &points) -> QPainterPath;
friend auto operator<< (QDataStream& dataStream, const VAbstractPiece& piece) -> QDataStream&; friend auto operator<< (QDataStream& dataStream, const VAbstractPiece& piece) -> QDataStream&;
friend auto operator>> (QDataStream& dataStream, VAbstractPiece& piece) -> QDataStream&; friend auto operator>> (QDataStream& dataStream, VAbstractPiece& piece) -> QDataStream&;
static auto PlaceLabelShape(const VLayoutPlaceLabel &label) -> PlaceLabelImg;
static auto LabelShapePath(const VLayoutPlaceLabel &label) -> QPainterPath;
static auto LabelShapePath(const PlaceLabelImg &shape) -> QPainterPath;
protected: protected:
template <class T> template <class T>
static auto RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true) -> QVector<T>; static auto RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true) -> QVector<T>;
static auto IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint) -> bool; static auto IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint) -> bool;
static auto IsEkvPointOnLine(const VSAPoint &iPoint, const VSAPoint &prevPoint, const VSAPoint &nextPoint) -> bool; static auto IsEkvPointOnLine(const VSAPoint &iPoint, const VSAPoint &prevPoint, const VSAPoint &nextPoint) -> bool;
template <class T>
static auto CheckPointOnLine(QVector<T> &points, const T &iPoint, const T &prevPoint, const T &nextPoint) -> bool;
static auto IsItemContained(const QRectF &parentBoundingRect, const QVector<QPointF> &shape, qreal &dX, static auto IsItemContained(const QRectF &parentBoundingRect, const QVector<QPointF> &shape, qreal &dX,
qreal &dY) -> bool; qreal &dY) -> bool;
static auto CorrectPosition(const QRectF &parentBoundingRect, QVector<QPointF> points) -> QVector<QPointF>; static auto CorrectPosition(const QRectF &parentBoundingRect, QVector<QPointF> points) -> QVector<QPointF>;
static auto FindGrainlineGeometry(const VGrainlineData& geom, const VContainer *pattern, qreal &length, static auto FindGrainlineGeometry(const VGrainlineData& geom, const VContainer *pattern, qreal &length,
qreal &rotationAngle, QPointF &pos) -> bool; qreal &rotationAngle, QPointF &pos) -> bool;
template <class T>
static auto ComparePoints(QVector<T> &points, const T &p1, const T &p2, qreal accuracy) -> bool;
template <class T>
static auto CompareFirstAndLastPoints(QVector<T> &points, qreal accuracy) -> void;
template <class T>
static auto CheckLoop(const QVector<T> &points, bool &loopFound) -> QVector<T>;
template <class T>
static auto IntersectionPoint(QPointF crosPoint, const T &l1p1, const T &l1p2, const T &l2p1, const T &l2p2) -> T;
private: private:
QSharedDataPointer<VAbstractPieceData> d; QSharedDataPointer<VAbstractPieceData> d;
}; };
Q_DECLARE_TYPEINFO(VAbstractPiece, Q_MOVABLE_TYPE); // NOLINT Q_DECLARE_TYPEINFO(VAbstractPiece, Q_MOVABLE_TYPE); // NOLINT
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline auto VAbstractPiece::CheckPointOnLine(QVector<T> &points, const T &iPoint, const T &prevPoint,
const T &nextPoint) -> bool
{
if (not IsEkvPointOnLine(iPoint, prevPoint, nextPoint))
{
points.append(iPoint);
return false;
}
if (not points.isEmpty() && iPoint.TurnPoint())
{
points.last().SetTurnPoint(true);
}
if (not points.isEmpty() && iPoint.CurvePoint())
{
points.last().SetCurvePoint(true);
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
template <>
inline auto VAbstractPiece::CheckPointOnLine<QPointF>(QVector<QPointF> &points, const QPointF &iPoint,
const QPointF &prevPoint, const QPointF &nextPoint) -> bool
{
if (not IsEkvPointOnLine(iPoint, prevPoint, nextPoint))
{
points.append(iPoint);
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant. * @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant.
@ -151,7 +207,7 @@ Q_DECLARE_TYPEINFO(VAbstractPiece, Q_MOVABLE_TYPE); // NOLINT
* @return corrected list. * @return corrected list.
*/ */
template <class T> template <class T>
auto VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast) -> QVector<T> inline auto VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast) -> QVector<T>
{ {
// DumpVector(points, QStringLiteral("input.json.XXXXXX")); // Uncomment for dumping test data // DumpVector(points, QStringLiteral("input.json.XXXXXX")); // Uncomment for dumping test data
if (points.size()<4)//Better don't check if only three points. We can destroy equidistant. if (points.size()<4)//Better don't check if only three points. We can destroy equidistant.
@ -174,7 +230,7 @@ auto VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool rem
QVector<T> buf2; QVector<T> buf2;
//Remove point on line //Remove point on line
for (qint32 i = 0; i < buf1.size(); ++i) for (qint32 i = 0; i < buf1.size(); ++i)
{// In this case we alwayse will have bounded intersection, so all is need is to check if point i is on line. {// In this case we alwayse will have bounded intersection, so all is need is to check if point is on line.
// Unfortunatelly QLineF::intersect can't be used in this case because of the floating-point accuraccy problem. // Unfortunatelly QLineF::intersect can't be used in this case because of the floating-point accuraccy problem.
if (prev == -1) if (prev == -1)
{ {
@ -213,9 +269,8 @@ auto VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool rem
const T &prevPoint = buf1.at(prev); const T &prevPoint = buf1.at(prev);
const T &nextPoint = buf1.at(next); const T &nextPoint = buf1.at(next);
if (not IsEkvPointOnLine(iPoint, prevPoint, nextPoint)) if (not CheckPointOnLine(buf2, iPoint, prevPoint, nextPoint))
{ {
buf2.append(iPoint);
prev = -1; prev = -1;
} }
} }
@ -233,7 +288,7 @@ auto VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool rem
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <class T> template <class T>
auto VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast) -> QVector<T> inline auto VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast) -> QVector<T>
{ {
if (points.size() < 4) if (points.size() < 4)
{ {
@ -252,9 +307,8 @@ auto VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirst
{ {
for (int j = i+1; j < points.size(); ++j) for (int j = i+1; j < points.size(); ++j)
{ {
if (not VFuzzyComparePoints(points.at(i), points.at(j), accuracy)) if (not ComparePoints(p, points.at(i), points.at(j), accuracy))
{ {
p.append(points.at(j));
i = j-1; i = j-1;
break; break;
} }
@ -267,10 +321,7 @@ auto VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirst
{ {
// Path can't be closed // Path can't be closed
// See issue #686 // See issue #686
if (VFuzzyComparePoints(ConstFirst(p), ConstLast(p), accuracy)) CompareFirstAndLastPoints(p, accuracy);
{
p.removeLast();
}
} }
} }
@ -279,7 +330,7 @@ auto VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirst
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <class T> template <class T>
auto VAbstractPiece::IsInsidePolygon(const QVector<T> &path, const QVector<T> &polygon, qreal accuracy) -> bool inline auto VAbstractPiece::IsInsidePolygon(const QVector<T> &path, const QVector<T> &polygon, qreal accuracy) -> bool
{ {
// Edges must not intersect // Edges must not intersect
for (auto i = 0; i < path.count(); ++i) for (auto i = 0; i < path.count(); ++i)
@ -340,4 +391,167 @@ auto VAbstractPiece::IsInsidePolygon(const QVector<T> &path, const QVector<T> &p
{ return allowancePolygon.containsPoint(point, Qt::WindingFill); }); { return allowancePolygon.containsPoint(point, Qt::WindingFill); });
} }
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline auto VAbstractPiece::PainterPath(const QVector<T> &points) -> QPainterPath
{
QPainterPath path;
path.setFillRule(Qt::WindingFill);
if (not points.isEmpty())
{
path.moveTo(points.at(0));
for (qint32 i = 1; i < points.count(); ++i)
{
path.lineTo(points.at(i));
}
path.lineTo(points.at(0));
}
return path;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief CheckLoops seek and delete loops in equidistant.
* @param points vector of points of equidistant.
* @return vector of points of equidistant.
*/
template <class T>
inline auto VAbstractPiece::CheckLoops(QVector<T> points) -> QVector<T>
{
// DumpVector(points, QStringLiteral("input.json.XXXXXX")); // Uncomment for dumping test data
/*If we got less than 4 points no need seek loops.*/
if (points.size() < 4)
{
return points;
}
bool loopFound = false;
qint32 i;
const int maxLoops = 10000; // limit number of loops to be removed
for (i = 0; i < maxLoops; ++i)
{
points = CheckLoop(points, loopFound);
if (not loopFound)
{
break;
}
}
// DumpVector(ekvPoints, QStringLiteral("output.json.XXXXXX")); // Uncomment for dumping test data
return points;
}
//---------------------------------------------------------------------------------------------------------------------
template<class T>
inline auto VAbstractPiece::CheckLoop(const QVector<T> &points, bool &loopFound) -> QVector<T>
{
loopFound = false;
const bool pathClosed = (ConstFirst(points) == ConstLast(points));
QVector<T> ekvPoints;
ekvPoints.reserve(points.size());
qint32 i;
for (i = 0; i < points.size(); ++i)
{
/*Last three points no need to check.*/
/*Triangle can not contain a loop*/
if (loopFound || i > points.size()-4)
{
ekvPoints.append(points.at(i));
continue;
}
enum LoopIntersectType { NoIntersection, BoundedIntersection, ParallelIntersection };
QPointF crosPoint;
LoopIntersectType status = NoIntersection;
const QLineF line1(points.at(i), points.at(i+1));
const int limit = pathClosed && i == 0 ? 2 : 1;
qint32 j;
for (j = i+2; j < points.size()-limit; ++j)
{
QLineF line2(points.at(j), points.at(j+1));
const QLineF::IntersectType intersect = Intersects(line1, line2, &crosPoint);
if (intersect == QLineF::NoIntersection)
{ // According to the documentation QLineF::NoIntersection indicates that the lines do not intersect;
// i.e. they are parallel. But parallel also mean they can be on the same line.
// Method IsLineSegmentOnLineSegment will check it.
if (VGObject::IsLineSegmentOnLineSegment(line1, line2))
{// Now we really sure that segments are on the same line and have real intersections.
status = ParallelIntersection;
break;
}
}
else if (intersect == QLineF::BoundedIntersection)
{
status = BoundedIntersection;
break;
}
}
switch (status)
{
case ParallelIntersection:
/*We have found a loop.*/
ekvPoints.append(points.at(i));
ekvPoints.append(points.at(j+1));
i = j+1; // Skip a loop
loopFound = true;
break;
case BoundedIntersection:
ekvPoints.append(points.at(i));
ekvPoints.append(IntersectionPoint(crosPoint, points.at(i), points.at(i+1), points.at(j), points.at(j+1)));
i = j;
loopFound = true;
break;
case NoIntersection:
/*We have not found loop.*/
ekvPoints.append(points.at(i));
break;
default:
break;
}
}
return ekvPoints;
}
//---------------------------------------------------------------------------------------------------------------------
template<class T>
inline auto VAbstractPiece::IntersectionPoint(QPointF crosPoint, const T &l1p1, const T &l1p2, const T &l2p1,
const T &l2p2) -> T
{
T point(crosPoint);
if ((l1p1.CurvePoint() && l1p2.CurvePoint()) || (l2p1.CurvePoint() && l2p2.CurvePoint()) ||
(l1p1.CurvePoint() && l2p2.CurvePoint()))
{
point.SetCurvePoint(true);
}
if ((l1p1.TurnPoint() && l1p2.TurnPoint()) || (l2p1.TurnPoint() && l2p2.TurnPoint()) ||
(l1p1.TurnPoint() && l2p2.TurnPoint()))
{
point.SetTurnPoint(true);
}
return point;
}
//---------------------------------------------------------------------------------------------------------------------
template<>
inline auto VAbstractPiece::IntersectionPoint<QPointF>(QPointF crosPoint, const QPointF & /*unused*/,
const QPointF & /*unused*/, const QPointF & /*unused*/,
const QPointF & /*unused*/) -> QPointF
{
return crosPoint;
}
#endif // VABSTRACTPIECE_H #endif // VABSTRACTPIECE_H

View File

@ -15,6 +15,7 @@ HEADERS += \
$$PWD/vcontour.h \ $$PWD/vcontour.h \
$$PWD/vcontour_p.h \ $$PWD/vcontour_p.h \
$$PWD/vbestsquare.h \ $$PWD/vbestsquare.h \
$$PWD/vlayoutpoint.h \
$$PWD/vposition.h \ $$PWD/vposition.h \
$$PWD/vrawlayout.h \ $$PWD/vrawlayout.h \
$$PWD/vprintlayout.h \ $$PWD/vprintlayout.h \
@ -38,6 +39,7 @@ SOURCES += \
$$PWD/vbank.cpp \ $$PWD/vbank.cpp \
$$PWD/vcontour.cpp \ $$PWD/vcontour.cpp \
$$PWD/vbestsquare.cpp \ $$PWD/vbestsquare.cpp \
$$PWD/vlayoutpoint.cpp \
$$PWD/vposition.cpp \ $$PWD/vposition.cpp \
$$PWD/vrawlayout.cpp \ $$PWD/vrawlayout.cpp \
$$PWD/vprintlayout.cpp \ $$PWD/vprintlayout.cpp \

View File

@ -34,8 +34,6 @@
#include <QPainterPath> #include <QPainterPath>
#include <ciso646> #include <ciso646>
#include "../vmisc/typedef.h"
enum class LayoutExportFormats : qint8 enum class LayoutExportFormats : qint8
{ {
SVG = 0, SVG = 0,

View File

@ -45,10 +45,11 @@
#include <Qt> #include <Qt>
#include <QtDebug> #include <QtDebug>
#include <QUuid> #include <QUuid>
#include <QtMath>
#include "../vpatterndb/floatItemData/vpatternlabeldata.h" #include "../vpatterndb/floatItemData/vpatternlabeldata.h"
#include "../vpatterndb/floatItemData/vpiecelabeldata.h" #include "../vpatterndb/floatItemData/vpiecelabeldata.h"
#include "../vmisc/vmath.h" #include "../vpatterndb/floatItemData/vgrainlinedata.h"
#include "../vmisc/vabstractvalapplication.h" #include "../vmisc/vabstractvalapplication.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vmisc/literals.h" #include "../vmisc/literals.h"
@ -58,13 +59,10 @@
#include "../vpatterndb/vpiecenode.h" #include "../vpatterndb/vpiecenode.h"
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vgeometry/vplacelabelitem.h" #include "../vgeometry/vplacelabelitem.h"
#include "vlayoutdef.h"
#include "vlayoutpiece_p.h" #include "vlayoutpiece_p.h"
#include "vtextmanager.h" #include "vtextmanager.h"
#include "vgraphicsfillitem.h" #include "vgraphicsfillitem.h"
#include "../vgeometry/vlayoutplacelabel.h"
const quint32 VLayoutPieceData::streamHeader = 0x80D7D009; // CRC-32Q string "VLayoutPieceData"
const quint16 VLayoutPieceData::classVersion = 3;
namespace namespace
{ {
@ -82,7 +80,7 @@ QVector<VLayoutPiecePath> ConvertInternalPaths(const VPiece &piece, const VConta
const VPiecePath path = pattern->GetPiecePath(id); const VPiecePath path = pattern->GetPiecePath(id);
if (path.GetType() == PiecePathType::InternalPath && path.IsVisible(pattern->DataVariables())) if (path.GetType() == PiecePathType::InternalPath && path.IsVisible(pattern->DataVariables()))
{ {
VLayoutPiecePath convertedPath = VLayoutPiecePath(path.PathPoints(pattern, cuttingPath)); VLayoutPiecePath convertedPath(path.PathPoints(pattern, cuttingPath));
convertedPath.SetCutPath(path.IsCutPath()); convertedPath.SetCutPath(path.IsCutPath());
convertedPath.SetPenStyle(path.GetPenType()); convertedPath.SetPenStyle(path.GetPenType());
paths.append(convertedPath); paths.append(convertedPath);
@ -170,18 +168,6 @@ bool FindLabelGeometry(const VPatternLabelData &labelData, const VContainer *pat
return true; return true;
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<VSAPoint> PrepareAllowance(const QVector<QPointF> &points)
{
QVector<VSAPoint> allowancePoints;
allowancePoints.reserve(points.size());
for(auto &point : points)
{
allowancePoints.append(VSAPoint(point));
}
return allowancePoints;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief VLayoutDetail::RotatePoint rotates a point around the center for given angle * @brief VLayoutDetail::RotatePoint rotates a point around the center for given angle
@ -222,7 +208,7 @@ QVector<VLayoutPlaceLabel> ConvertPlaceLabels(const VPiece &piece, const VContai
QVector<VLayoutPlaceLabel> labels; QVector<VLayoutPlaceLabel> labels;
const auto placeLabels = piece.GetPlaceLabels(); const auto placeLabels = piece.GetPlaceLabels();
labels.reserve(placeLabels.size()); labels.reserve(placeLabels.size());
for(auto &placeLabel : placeLabels) for(const auto &placeLabel : placeLabels)
{ {
const auto label = pattern->GeometricObject<VPlaceLabelItem>(placeLabel); const auto label = pattern->GeometricObject<VPlaceLabelItem>(placeLabel);
if (label->IsVisible()) if (label->IsVisible())
@ -231,13 +217,7 @@ QVector<VLayoutPlaceLabel> ConvertPlaceLabels(const VPiece &piece, const VContai
QT_WARNING_DISABLE_GCC("-Wnoexcept") QT_WARNING_DISABLE_GCC("-Wnoexcept")
// noexcept-expression evaluates to 'false' because of a call to 'constexpr QPointF::QPointF()' // noexcept-expression evaluates to 'false' because of a call to 'constexpr QPointF::QPointF()'
VLayoutPlaceLabel layoutLabel; labels.append(VLayoutPlaceLabel(*label));
layoutLabel.shape = label->LabelShape();
layoutLabel.rotationMatrix = label->RotationMatrix();
layoutLabel.box = label->Box();
layoutLabel.center = label->toQPointF();
layoutLabel.type = label->GetLabelType();
labels.append(layoutLabel);
QT_WARNING_POP QT_WARNING_POP
} }
@ -250,7 +230,7 @@ QVector<VLayoutPassmark> ConvertPassmarks(const VPiece &piece, const VContainer
{ {
const QVector<VPassmark> passmarks = piece.Passmarks(pattern); const QVector<VPassmark> passmarks = piece.Passmarks(pattern);
QVector<VLayoutPassmark> layoutPassmarks; QVector<VLayoutPassmark> layoutPassmarks;
for(auto &passmark : passmarks) for(const auto &passmark : passmarks)
{ {
if (not passmark.IsNull()) if (not passmark.IsNull())
{ {
@ -525,9 +505,35 @@ auto PrepareGradationId(const QString &label, const VContainer *pattern) -> QStr
const QMap<QString, QString> placeholders = PrepareGradationPlaceholders(pattern); const QMap<QString, QString> placeholders = PrepareGradationPlaceholders(pattern);
return ReplacePlaceholders(placeholders, label); return ReplacePlaceholders(placeholders, label);
} }
} } // namespace
// Friend functions // Friend functions
//---------------------------------------------------------------------------------------------------------------------
QDataStream &operator<<(QDataStream &dataStream, const VLayoutPoint &p)
{
dataStream << static_cast<QPointF>(p);
dataStream << p.TurnPoint();
dataStream << p.CurvePoint();
return dataStream;
}
//---------------------------------------------------------------------------------------------------------------------
QDataStream &operator>>(QDataStream &dataStream, VLayoutPoint &p)
{
QPointF tmp;
bool turnPointFlag = false;
bool curvePointFlag = false;
dataStream >> tmp;
dataStream >> turnPointFlag;
dataStream >> curvePointFlag;
p = VLayoutPoint(tmp);
p.SetTurnPoint(turnPointFlag);
p.SetCurvePoint(curvePointFlag);
return dataStream;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QDataStream &operator<<(QDataStream &dataStream, const VLayoutPiece &piece) QDataStream &operator<<(QDataStream &dataStream, const VLayoutPiece &piece)
{ {
@ -588,9 +594,10 @@ VLayoutPiece::~VLayoutPiece()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VLayoutPiece VLayoutPiece::Create(const VPiece &piece, vidtype id, const VContainer *pattern) VLayoutPiece VLayoutPiece::Create(const VPiece &piece, vidtype id, const VContainer *pattern)
{ {
QFuture<QVector<QPointF> > futureSeamAllowance = QtConcurrent::run(piece, &VPiece::SeamAllowancePoints, pattern); QFuture<QVector<VLayoutPoint> > futureSeamAllowance = QtConcurrent::run(piece, &VPiece::SeamAllowancePoints,
pattern);
QFuture<bool> futureSeamAllowanceValid = QtConcurrent::run(piece, &VPiece::IsSeamAllowanceValid, pattern); QFuture<bool> futureSeamAllowanceValid = QtConcurrent::run(piece, &VPiece::IsSeamAllowanceValid, pattern);
QFuture<QVector<QPointF> > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern); QFuture<QVector<VLayoutPoint> > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern);
QFuture<QVector<VLayoutPiecePath> > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern); QFuture<QVector<VLayoutPiecePath> > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern);
QFuture<QVector<VLayoutPassmark> > futurePassmarks = QtConcurrent::run(ConvertPassmarks, piece, pattern); QFuture<QVector<VLayoutPassmark> > futurePassmarks = QtConcurrent::run(ConvertPassmarks, piece, pattern);
QFuture<QVector<VLayoutPlaceLabel> > futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern); QFuture<QVector<VLayoutPlaceLabel> > futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern);
@ -673,26 +680,14 @@ template <class T>
auto VLayoutPiece::Map(QVector<T> points) const -> QVector<T> auto VLayoutPiece::Map(QVector<T> points) const -> QVector<T>
{ {
std::transform(points.begin(), points.end(), points.begin(), std::transform(points.begin(), points.end(), points.begin(),
[this](const T &point) { return d->matrix.map(point); }); [this](const T &point) { return d->m_matrix.map(point); });
if (d->mirror) if (d->m_mirror)
{ {
std::reverse(points.begin(), points.end()); std::reverse(points.begin(), points.end());
} }
return points; return points;
} }
//---------------------------------------------------------------------------------------------------------------------
template <>
QVector<VLayoutPlaceLabel> VLayoutPiece::Map<VLayoutPlaceLabel>(QVector<VLayoutPlaceLabel> points) const
{
for (int i = 0; i < points.size(); ++i)
{
points[i].shape = Map(points.at(i).shape);
}
return points;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <> template <>
QVector<VLayoutPassmark> VLayoutPiece::Map<VLayoutPassmark>(QVector<VLayoutPassmark> passmarks) const QVector<VLayoutPassmark> VLayoutPiece::Map<VLayoutPassmark>(QVector<VLayoutPassmark> passmarks) const
@ -700,56 +695,76 @@ QVector<VLayoutPassmark> VLayoutPiece::Map<VLayoutPassmark>(QVector<VLayoutPassm
for (int i = 0; i < passmarks.size(); ++i) for (int i = 0; i < passmarks.size(); ++i)
{ {
passmarks[i].lines = Map(passmarks.at(i).lines); passmarks[i].lines = Map(passmarks.at(i).lines);
passmarks[i].baseLine = d->matrix.map(passmarks.at(i).baseLine); passmarks[i].baseLine = d->m_matrix.map(passmarks.at(i).baseLine);
} }
return passmarks; return passmarks;
} }
//---------------------------------------------------------------------------------------------------------------------
template <>
QVector<VLayoutPoint> VLayoutPiece::Map<VLayoutPoint>(QVector<VLayoutPoint> points) const
{
std::transform(points.begin(), points.end(), points.begin(), [this](VLayoutPoint point)
{
auto p = static_cast<QPointF>(point);
p = d->m_matrix.map(p);
point.rx() = p.x();
point.ry() = p.y();
return point;
});
if (d->m_mirror)
{
std::reverse(points.begin(), points.end());
}
return points;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
QVector<QPointF> VLayoutPiece::GetMappedContourPoints() const QVector<VLayoutPoint> VLayoutPiece::GetMappedContourPoints() const
{ {
return Map(d->contour); return Map(d->m_contour);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetContourPoints() const QVector<VLayoutPoint> VLayoutPiece::GetContourPoints() const
{ {
return d->contour; return d->m_contour;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetCountourPoints(const QVector<QPointF> &points, bool hideMainPath) void VLayoutPiece::SetCountourPoints(const QVector<VLayoutPoint> &points, bool hideMainPath)
{ {
d->contour = RemoveDublicates(points, false); d->m_contour = RemoveDublicates(points, false);
SetHideMainPath(hideMainPath); SetHideMainPath(hideMainPath);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
QVector<QPointF> VLayoutPiece::GetMappedSeamAllowancePoints() const QVector<VLayoutPoint> VLayoutPiece::GetMappedSeamAllowancePoints() const
{ {
return Map(d->seamAllowance); return Map(d->m_seamAllowance);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetSeamAllowancePoints() const QVector<VLayoutPoint> VLayoutPiece::GetSeamAllowancePoints() const
{ {
return d->seamAllowance; return d->m_seamAllowance;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetSeamAllowancePoints(const QVector<QPointF> &points, bool seamAllowance, bool seamAllowanceBuiltIn) void VLayoutPiece::SetSeamAllowancePoints(const QVector<VLayoutPoint> &points, bool seamAllowance,
bool seamAllowanceBuiltIn)
{ {
if (seamAllowance) if (seamAllowance)
{ {
SetSeamAllowance(seamAllowance); SetSeamAllowance(seamAllowance);
SetSeamAllowanceBuiltIn(seamAllowanceBuiltIn); SetSeamAllowanceBuiltIn(seamAllowanceBuiltIn);
d->seamAllowance = points; d->m_seamAllowance = points;
if (not d->seamAllowance.isEmpty()) if (not d->m_seamAllowance.isEmpty())
{ {
d->seamAllowance = RemoveDublicates(d->seamAllowance, false); d->m_seamAllowance = RemoveDublicates(d->m_seamAllowance, false);
} }
else if (not IsSeamAllowanceBuiltIn()) else if (not IsSeamAllowanceBuiltIn())
{ {
@ -762,21 +777,21 @@ void VLayoutPiece::SetSeamAllowancePoints(const QVector<QPointF> &points, bool s
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetMappedLayoutAllowancePoints() const QVector<QPointF> VLayoutPiece::GetMappedLayoutAllowancePoints() const
{ {
return Map(d->layoutAllowance); return Map(d->m_layoutAllowance);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetLayoutAllowancePoints() const QVector<QPointF> VLayoutPiece::GetLayoutAllowancePoints() const
{ {
return d->layoutAllowance; return d->m_layoutAllowance;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPointF VLayoutPiece::GetPieceTextPosition() const QPointF VLayoutPiece::GetPieceTextPosition() const
{ {
if (d->detailLabel.count() > 2) if (d->m_detailLabel.count() > 2)
{ {
return d->matrix.map(ConstFirst(d->detailLabel)); return d->m_matrix.map(ConstFirst(d->m_detailLabel));
} }
else else
{ {
@ -787,7 +802,7 @@ QPointF VLayoutPiece::GetPieceTextPosition() const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QStringList VLayoutPiece::GetPieceText() const QStringList VLayoutPiece::GetPieceText() const
{ {
return PieceLabelText(d->detailLabel, d->m_tmDetail); return PieceLabelText(d->m_detailLabel, d->m_tmDetail);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -818,7 +833,7 @@ void VLayoutPiece::SetPieceText(const QString& qsName, const VPieceLabelData& da
} }
QScopedPointer<QGraphicsItem> item(GetMainPathItem()); QScopedPointer<QGraphicsItem> item(GetMainPathItem());
d->detailLabel = CorrectPosition(item->boundingRect(), v); d->m_detailLabel = CorrectPosition(item->boundingRect(), v);
// generate text // generate text
d->m_tmDetail.SetFont(font); d->m_tmDetail.SetFont(font);
@ -832,13 +847,13 @@ void VLayoutPiece::SetPieceText(const QString& qsName, const VPieceLabelData& da
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetPieceLabelRect() const -> QVector<QPointF> auto VLayoutPiece::GetPieceLabelRect() const -> QVector<QPointF>
{ {
return d->detailLabel; return d->m_detailLabel;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetPieceLabelRect(const QVector<QPointF> &rect) void VLayoutPiece::SetPieceLabelRect(const QVector<QPointF> &rect)
{ {
d->detailLabel = rect; d->m_detailLabel = rect;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -856,9 +871,9 @@ void VLayoutPiece::SetPieceLabelData(const VTextManager &data)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPointF VLayoutPiece::GetPatternTextPosition() const QPointF VLayoutPiece::GetPatternTextPosition() const
{ {
if (d->patternInfo.count() > 2) if (d->m_patternInfo.count() > 2)
{ {
return d->matrix.map(ConstFirst(d->patternInfo)); return d->m_matrix.map(ConstFirst(d->m_patternInfo));
} }
else else
{ {
@ -869,7 +884,7 @@ QPointF VLayoutPiece::GetPatternTextPosition() const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QStringList VLayoutPiece::GetPatternText() const QStringList VLayoutPiece::GetPatternText() const
{ {
return PieceLabelText(d->patternInfo, d->m_tmPattern); return PieceLabelText(d->m_patternInfo, d->m_tmPattern);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -898,7 +913,7 @@ void VLayoutPiece::SetPatternInfo(VAbstractPattern* pDoc, const VPatternLabelDat
v[i] = RotatePoint(ptCenter, v.at(i), dAng); v[i] = RotatePoint(ptCenter, v.at(i), dAng);
} }
QScopedPointer<QGraphicsItem> item(GetMainPathItem()); QScopedPointer<QGraphicsItem> item(GetMainPathItem());
d->patternInfo = CorrectPosition(item->boundingRect(), v); d->m_patternInfo = CorrectPosition(item->boundingRect(), v);
// Generate text // Generate text
d->m_tmPattern.SetFont(font); d->m_tmPattern.SetFont(font);
@ -914,13 +929,13 @@ void VLayoutPiece::SetPatternInfo(VAbstractPattern* pDoc, const VPatternLabelDat
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetPatternLabelRect() const -> QVector<QPointF> auto VLayoutPiece::GetPatternLabelRect() const -> QVector<QPointF>
{ {
return d->patternInfo; return d->m_patternInfo;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetPatternLabelRect(const QVector<QPointF> &rect) void VLayoutPiece::SetPatternLabelRect(const QVector<QPointF> &rect)
{ {
d->patternInfo = rect; d->m_patternInfo = rect;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -948,88 +963,88 @@ void VLayoutPiece::SetGrainline(const VGrainlineData& geom, const VContainer* pa
return; return;
} }
d->grainlineEnabled = true; d->m_grainlineEnabled = true;
d->grainlineArrowType = geom.GetArrowType(); d->m_grainlineArrowType = geom.GetArrowType();
d->grainlineAngle = qRadiansToDegrees(dAng); d->m_grainlineAngle = qRadiansToDegrees(dAng);
d->grainlinePoints = v; d->m_grainlinePoints = v;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetMappedGrainline() const QVector<QPointF> VLayoutPiece::GetMappedGrainline() const
{ {
return Map(d->grainlinePoints); return Map(d->m_grainlinePoints);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetGrainline() const QVector<QPointF> VLayoutPiece::GetGrainline() const
{ {
return d->grainlinePoints; return d->m_grainlinePoints;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VLayoutPiece::IsGrainlineEnabled() const bool VLayoutPiece::IsGrainlineEnabled() const
{ {
return d->grainlineEnabled; return d->m_grainlineEnabled;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainlineEnabled(bool enabled) void VLayoutPiece::SetGrainlineEnabled(bool enabled)
{ {
d->grainlineEnabled = enabled; d->m_grainlineEnabled = enabled;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainlineAngle(qreal angle) void VLayoutPiece::SetGrainlineAngle(qreal angle)
{ {
d->grainlineAngle = angle; d->m_grainlineAngle = angle;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainlineArrowType(GrainlineArrowDirection type) void VLayoutPiece::SetGrainlineArrowType(GrainlineArrowDirection type)
{ {
d->grainlineArrowType = type; d->m_grainlineArrowType = type;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainlinePoints(const QVector<QPointF> &points) void VLayoutPiece::SetGrainlinePoints(const QVector<QPointF> &points)
{ {
d->grainlinePoints = points; d->m_grainlinePoints = points;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
qreal VLayoutPiece::GrainlineAngle() const qreal VLayoutPiece::GrainlineAngle() const
{ {
return d->grainlineAngle; return d->m_grainlineAngle;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
GrainlineArrowDirection VLayoutPiece::GrainlineArrowType() const GrainlineArrowDirection VLayoutPiece::GrainlineArrowType() const
{ {
return d->grainlineArrowType; return d->m_grainlineArrowType;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QTransform VLayoutPiece::GetMatrix() const QTransform VLayoutPiece::GetMatrix() const
{ {
return d->matrix; return d->m_matrix;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetMatrix(const QTransform &matrix) void VLayoutPiece::SetMatrix(const QTransform &matrix)
{ {
d->matrix = matrix; d->m_matrix = matrix;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
qreal VLayoutPiece::GetLayoutWidth() const qreal VLayoutPiece::GetLayoutWidth() const
{ {
return d->layoutWidth; return d->m_layoutWidth;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetLayoutWidth(qreal value) void VLayoutPiece::SetLayoutWidth(qreal value)
{ {
d->layoutWidth = value; d->m_layoutWidth = value;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1067,7 +1082,7 @@ void VLayoutPiece::Translate(const QPointF &p)
{ {
QTransform m; QTransform m;
m.translate(p.x(), p.y()); m.translate(p.x(), p.y());
d->matrix *= m; d->m_matrix *= m;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1078,7 +1093,7 @@ void VLayoutPiece::Scale(qreal sx, qreal sy)
QTransform m; QTransform m;
m.scale(sx, sy); m.scale(sx, sy);
d->matrix *= m; d->m_matrix *= m;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1088,7 +1103,7 @@ void VLayoutPiece::Rotate(const QPointF &originPoint, qreal degrees)
m.translate(originPoint.x(), originPoint.y()); m.translate(originPoint.x(), originPoint.y());
m.rotate(-degrees); m.rotate(-degrees);
m.translate(-originPoint.x(), -originPoint.y()); m.translate(-originPoint.x(), -originPoint.y());
d->matrix *= m; d->m_matrix *= m;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1107,21 +1122,21 @@ void VLayoutPiece::Mirror(const QLineF &edge)
m.translate(p2.x(), p2.y()); m.translate(p2.x(), p2.y());
m.rotate(-angle); m.rotate(-angle);
m.translate(-p2.x(), -p2.y()); m.translate(-p2.x(), -p2.y());
d->matrix *= m; d->m_matrix *= m;
m.reset(); m.reset();
m.translate(p2.x(), p2.y()); m.translate(p2.x(), p2.y());
m.scale(m.m11(), m.m22()*-1); m.scale(m.m11(), m.m22()*-1);
m.translate(-p2.x(), -p2.y()); m.translate(-p2.x(), -p2.y());
d->matrix *= m; d->m_matrix *= m;
m.reset(); m.reset();
m.translate(p2.x(), p2.y()); m.translate(p2.x(), p2.y());
m.rotate(-(360-angle)); m.rotate(-(360-angle));
m.translate(-p2.x(), -p2.y()); m.translate(-p2.x(), -p2.y());
d->matrix *= m; d->m_matrix *= m;
d->mirror = !d->mirror; d->m_mirror = !d->m_mirror;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1129,8 +1144,8 @@ void VLayoutPiece::Mirror()
{ {
QTransform m; QTransform m;
m.scale(-1, 1); m.scale(-1, 1);
d->matrix *= m; d->m_matrix *= m;
d->mirror = !d->mirror; d->m_mirror = !d->m_mirror;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1142,32 +1157,32 @@ int VLayoutPiece::DetailEdgesCount() const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
int VLayoutPiece::LayoutEdgesCount() const int VLayoutPiece::LayoutEdgesCount() const
{ {
const int count = d->layoutAllowance.count(); const int count = d->m_layoutAllowance.count();
return count > 2 ? count : 0; return count > 2 ? count : 0;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QLineF VLayoutPiece::LayoutEdge(int i) const QLineF VLayoutPiece::LayoutEdge(int i) const
{ {
return Edge(d->layoutAllowance, i); return Edge(d->m_layoutAllowance, i);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
int VLayoutPiece::LayoutEdgeByPoint(const QPointF &p1) const int VLayoutPiece::LayoutEdgeByPoint(const QPointF &p1) const
{ {
return EdgeByPoint(d->layoutAllowance, p1); return EdgeByPoint(d->m_layoutAllowance, p1);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::MappedDetailBoundingRect() const QRectF VLayoutPiece::MappedDetailBoundingRect() const
{ {
return BoundingRect(GetMappedExternalContourPoints()); return BoundingRect(CastTo<QPointF>(GetMappedExternalContourPoints()));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::DetailBoundingRect() const QRectF VLayoutPiece::DetailBoundingRect() const
{ {
return BoundingRect(GetExternalContourPoints()); return BoundingRect(CastTo<QPointF>(GetExternalContourPoints()));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1186,9 +1201,9 @@ qreal VLayoutPiece::Diagonal() const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VLayoutPiece::isNull() const bool VLayoutPiece::isNull() const
{ {
if (d->contour.isEmpty() == false && d->layoutWidth > 0) if (d->m_contour.isEmpty() == false && d->m_layoutWidth > 0)
{ {
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn() && d->seamAllowance.isEmpty() == false) if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn() && d->m_seamAllowance.isEmpty() == false)
{ {
return false; return false;
} }
@ -1214,45 +1229,46 @@ void VLayoutPiece::SetLayoutAllowancePoints()
{ {
d->m_square = 0; d->m_square = 0;
if (d->layoutWidth > 0) if (d->m_layoutWidth > 0)
{ {
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{ {
d->layoutAllowance = Equidistant(PrepareAllowance(GetMappedSeamAllowancePoints()), d->layoutWidth, d->m_layoutAllowance = CastTo<QPointF>(Equidistant(CastTo<VSAPoint>(GetMappedSeamAllowancePoints()),
GetName()); d->m_layoutWidth, GetName()));
if (not d->layoutAllowance.isEmpty()) if (not d->m_layoutAllowance.isEmpty())
{ {
d->layoutAllowance.removeLast(); d->m_layoutAllowance.removeLast();
d->m_square = qFloor(qAbs(SumTrapezoids(GetSeamAllowancePoints())/2.0)); d->m_square = qFloor(qAbs(SumTrapezoids(CastTo<QPointF>(GetSeamAllowancePoints()))/2.0));
} }
} }
else else
{ {
d->layoutAllowance = Equidistant(PrepareAllowance(GetMappedContourPoints()), d->layoutWidth, GetName()); d->m_layoutAllowance = CastTo<QPointF>(Equidistant(CastTo<VSAPoint>(GetMappedContourPoints()),
if (not d->layoutAllowance.isEmpty()) d->m_layoutWidth, GetName()));
if (not d->m_layoutAllowance.isEmpty())
{ {
d->layoutAllowance.removeLast(); d->m_layoutAllowance.removeLast();
d->m_square = qFloor(qAbs(SumTrapezoids(GetContourPoints())/2.0)); d->m_square = qFloor(qAbs(SumTrapezoids(CastTo<QPointF>(GetContourPoints()))/2.0));
} }
} }
} }
else else
{ {
d->layoutAllowance.clear(); d->m_layoutAllowance.clear();
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetMappedExternalContourPoints() const QVector<VLayoutPoint> VLayoutPiece::GetMappedExternalContourPoints() const
{ {
return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetMappedSeamAllowancePoints() : return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetMappedSeamAllowancePoints() :
GetMappedContourPoints(); GetMappedContourPoints();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetExternalContourPoints() const QVector<VLayoutPoint> VLayoutPiece::GetExternalContourPoints() const
{ {
return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetSeamAllowancePoints() : return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetSeamAllowancePoints() :
GetContourPoints(); GetContourPoints();
@ -1261,13 +1277,13 @@ QVector<QPointF> VLayoutPiece::GetExternalContourPoints() const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<VLayoutPassmark> VLayoutPiece::GetMappedPassmarks() const QVector<VLayoutPassmark> VLayoutPiece::GetMappedPassmarks() const
{ {
return Map(d->passmarks); return Map(d->m_passmarks);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<VLayoutPassmark> VLayoutPiece::GetPassmarks() const QVector<VLayoutPassmark> VLayoutPiece::GetPassmarks() const
{ {
return d->passmarks; return d->m_passmarks;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1275,16 +1291,10 @@ void VLayoutPiece::SetPassmarks(const QVector<VLayoutPassmark> &passmarks)
{ {
if (IsSeamAllowance()) if (IsSeamAllowance())
{ {
d->passmarks = passmarks; d->m_passmarks = passmarks;
} }
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<VLayoutPlaceLabel> VLayoutPiece::GetMappedPlaceLabels() const
{
return Map(d->m_placeLabels);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<VLayoutPlaceLabel> VLayoutPiece::GetPlaceLabels() const QVector<VLayoutPlaceLabel> VLayoutPiece::GetPlaceLabels() const
{ {
@ -1298,9 +1308,10 @@ void VLayoutPiece::SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QVector<QPointF> > VLayoutPiece::MappedInternalPathsForCut(bool cut) const QVector<QVector<VLayoutPoint> > VLayoutPiece::MappedInternalPathsForCut(bool cut) const
{ {
QVector<QVector<QPointF> > paths; QVector<QVector<VLayoutPoint> > paths;
paths.reserve(d->m_internalPaths.size());
for (const auto &path : d->m_internalPaths) for (const auto &path : d->m_internalPaths)
{ {
@ -1328,7 +1339,7 @@ void VLayoutPiece::SetInternalPaths(const QVector<VLayoutPiecePath> &internalPat
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VLayoutPiece::MappedContourPath() const QPainterPath VLayoutPiece::MappedContourPath() const
{ {
return d->matrix.map(ContourPath()); return d->m_matrix.map(ContourPath());
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1348,7 +1359,7 @@ QPainterPath VLayoutPiece::ContourPath() const
if (not IsSeamAllowanceBuiltIn()) if (not IsSeamAllowanceBuiltIn())
{ {
// Draw seam allowance // Draw seam allowance
QVector<QPointF>points = GetSeamAllowancePoints(); QVector<VLayoutPoint> points = GetSeamAllowancePoints();
if (ConstLast(points).toPoint() != ConstFirst(points).toPoint()) if (ConstLast(points).toPoint() != ConstFirst(points).toPoint())
{ {
@ -1410,7 +1421,7 @@ void VLayoutPiece::DrawMiniature(QPainter &painter) const
for (const auto &label : d->m_placeLabels) for (const auto &label : d->m_placeLabels)
{ {
painter.drawPath(VPlaceLabelItem::LabelShapePath(label.shape)); painter.drawPath(LabelShapePath(label));
} }
QVector<QPointF> gPoints = GetGrainline(); QVector<QPointF> gPoints = GetGrainline();
@ -1431,10 +1442,10 @@ QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const
{ {
QGraphicsPathItem *item = GetMainItem(); QGraphicsPathItem *item = GetMainItem();
for (auto &path : d->m_internalPaths) for (const auto &path : d->m_internalPaths)
{ {
auto* pathItem = new QGraphicsPathItem(item); auto* pathItem = new QGraphicsPathItem(item);
pathItem->setPath(d->matrix.map(path.GetPainterPath())); pathItem->setPath(d->m_matrix.map(path.GetPainterPath()));
QPen pen = pathItem->pen(); QPen pen = pathItem->pen();
pen.setStyle(path.PenStyle()); pen.setStyle(path.PenStyle());
@ -1448,11 +1459,11 @@ QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const
QPen pen = pathItem->pen(); QPen pen = pathItem->pen();
pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine()); pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine());
pathItem->setPen(pen); pathItem->setPen(pen);
pathItem->setPath(d->matrix.map(VPlaceLabelItem::LabelShapePath(label.shape))); pathItem->setPath(d->m_matrix.map(LabelShapePath(PlaceLabelShape(label))));
} }
CreateLabelStrings(item, d->detailLabel, d->m_tmDetail, textAsPaths); CreateLabelStrings(item, d->m_detailLabel, d->m_tmDetail, textAsPaths);
CreateLabelStrings(item, d->patternInfo, d->m_tmPattern, textAsPaths); CreateLabelStrings(item, d->m_patternInfo, d->m_tmPattern, textAsPaths);
CreateGrainlineItem(item); CreateGrainlineItem(item);
return item; return item;
@ -1461,8 +1472,9 @@ QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VLayoutPiece::IsLayoutAllowanceValid() const bool VLayoutPiece::IsLayoutAllowanceValid() const
{ {
QVector<QPointF> base = (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? d->seamAllowance : d->contour; QVector<VLayoutPoint> base = (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ?
return VAbstractPiece::IsAllowanceValid(base, d->layoutAllowance); d->m_seamAllowance : d->m_contour;
return VAbstractPiece::IsAllowanceValid(CastTo<QPointF>(base), d->m_layoutAllowance);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1487,6 +1499,18 @@ qreal VLayoutPiece::BiggestEdge() const
return edge; return edge;
} }
//---------------------------------------------------------------------------------------------------------------------
PlaceLabelImg VLayoutPiece::MapPlaceLabelShape(PlaceLabelImg shape) const
{
for (int i = 0; i < shape.size(); ++i)
{
shape[i] = Map(shape.at(i));
}
return shape;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::BoundingRect(QVector<QPointF> points) QRectF VLayoutPiece::BoundingRect(QVector<QPointF> points)
{ {
@ -1551,7 +1575,7 @@ void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector<QPoin
// set up the rotation around top-left corner matrix // set up the rotation around top-left corner matrix
QTransform labelMatrix; QTransform labelMatrix;
labelMatrix.translate(labelShape.at(0).x(), labelShape.at(0).y()); labelMatrix.translate(labelShape.at(0).x(), labelShape.at(0).y());
if (d->mirror) if (d->m_mirror)
{ {
labelMatrix.scale(-1, 1); labelMatrix.scale(-1, 1);
labelMatrix.rotate(-angle); labelMatrix.rotate(-angle);
@ -1564,7 +1588,7 @@ void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector<QPoin
labelMatrix.translate(dX, dY); // Each string has own position labelMatrix.translate(dX, dY); // Each string has own position
} }
labelMatrix *= d->matrix; labelMatrix *= d->m_matrix;
if (textAsPaths) if (textAsPaths)
{ {
@ -1596,7 +1620,7 @@ void VLayoutPiece::CreateGrainlineItem(QGraphicsItem *parent) const
{ {
SCASSERT(parent != nullptr) SCASSERT(parent != nullptr)
if (not d->grainlineEnabled || d->grainlinePoints.count() < 2) if (not d->m_grainlineEnabled || d->m_grainlinePoints.count() < 2)
{ {
return; return;
} }
@ -1615,16 +1639,14 @@ void VLayoutPiece::CreateGrainlineItem(QGraphicsItem *parent) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::DetailPath() const QVector<VLayoutPoint> VLayoutPiece::DetailPath() const
{ {
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{ {
return d->seamAllowance; return d->m_seamAllowance;
}
else
{
return d->contour;
} }
return d->m_contour;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1649,7 +1671,7 @@ QGraphicsPathItem *VLayoutPiece::GetMainPathItem() const
QPainterPath path; QPainterPath path;
// contour // contour
QVector<QPointF> points = GetMappedContourPoints(); QVector<VLayoutPoint> points = GetMappedContourPoints();
path.moveTo(points.at(0)); path.moveTo(points.at(0));
for (qint32 i = 1; i < points.count(); ++i) for (qint32 i = 1; i < points.count(); ++i)
@ -1665,13 +1687,13 @@ QGraphicsPathItem *VLayoutPiece::GetMainPathItem() const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VLayoutPiece::IsMirror() const bool VLayoutPiece::IsMirror() const
{ {
return d->mirror; return d->m_mirror;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetMirror(bool value) void VLayoutPiece::SetMirror(bool value)
{ {
d->mirror = value; d->m_mirror = value;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1730,14 +1752,14 @@ QLineF VLayoutPiece::Edge(const QVector<QPointF> &path, int i) const
i2 = 0; i2 = 0;
} }
if (d->mirror) if (d->m_mirror)
{ {
QVector<QPointF> newPath = Map(path); QVector<QPointF> newPath = Map(path);
return QLineF(newPath.at(i1), newPath.at(i2)); return QLineF(newPath.at(i1), newPath.at(i2));
} }
else else
{ {
return QLineF(d->matrix.map(path.at(i1)), d->matrix.map(path.at(i2))); return QLineF(d->m_matrix.map(path.at(i1)), d->m_matrix.map(path.at(i2)));
} }
} }

View File

@ -55,6 +55,7 @@ class VPiece;
class VPieceLabelData; class VPieceLabelData;
class VAbstractPattern; class VAbstractPattern;
class VPatternLabelData; class VPatternLabelData;
class VLayoutPoint;
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wsuggest-final-types") QT_WARNING_DISABLE_GCC("-Wsuggest-final-types")
@ -79,31 +80,30 @@ public:
virtual auto GetUniqueID() const -> QString override; virtual auto GetUniqueID() const -> QString override;
QVector<QPointF> GetMappedContourPoints() const; QVector<VLayoutPoint> GetMappedContourPoints() const;
QVector<QPointF> GetContourPoints() const; QVector<VLayoutPoint> GetContourPoints() const;
void SetCountourPoints(const QVector<QPointF> &points, bool hideMainPath = false); void SetCountourPoints(const QVector<VLayoutPoint> &points, bool hideMainPath = false);
QVector<QPointF> GetMappedSeamAllowancePoints() const; QVector<VLayoutPoint> GetMappedSeamAllowancePoints() const;
QVector<QPointF> GetSeamAllowancePoints() const; QVector<VLayoutPoint> GetSeamAllowancePoints() const;
void SetSeamAllowancePoints(const QVector<QPointF> &points, bool seamAllowance = true, void SetSeamAllowancePoints(const QVector<VLayoutPoint> &points, bool seamAllowance = true,
bool seamAllowanceBuiltIn = false); bool seamAllowanceBuiltIn = false);
QVector<QPointF> GetMappedLayoutAllowancePoints() const; QVector<QPointF> GetMappedLayoutAllowancePoints() const;
QVector<QPointF> GetLayoutAllowancePoints() const; QVector<QPointF> GetLayoutAllowancePoints() const;
void SetLayoutAllowancePoints(); void SetLayoutAllowancePoints();
QVector<QPointF> GetMappedExternalContourPoints() const; QVector<VLayoutPoint> GetMappedExternalContourPoints() const;
QVector<QPointF> GetExternalContourPoints() const; QVector<VLayoutPoint> GetExternalContourPoints() const;
QVector<VLayoutPassmark> GetMappedPassmarks() const; QVector<VLayoutPassmark> GetMappedPassmarks() const;
QVector<VLayoutPassmark> GetPassmarks() const; QVector<VLayoutPassmark> GetPassmarks() const;
void SetPassmarks(const QVector<VLayoutPassmark> &passmarks); void SetPassmarks(const QVector<VLayoutPassmark> &passmarks);
QVector<VLayoutPlaceLabel> GetMappedPlaceLabels() const;
QVector<VLayoutPlaceLabel> GetPlaceLabels() const; QVector<VLayoutPlaceLabel> GetPlaceLabels() const;
void SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels); void SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels);
QVector<QVector<QPointF>> MappedInternalPathsForCut(bool cut) const; QVector<QVector<VLayoutPoint> > MappedInternalPathsForCut(bool cut) const;
QVector<VLayoutPiecePath> GetInternalPaths() const; QVector<VLayoutPiecePath> GetInternalPaths() const;
void SetInternalPaths(const QVector<VLayoutPiecePath> &internalPaths); void SetInternalPaths(const QVector<VLayoutPiecePath> &internalPaths);
@ -185,6 +185,8 @@ public:
friend QDataStream& operator<< (QDataStream& dataStream, const VLayoutPiece& piece); friend QDataStream& operator<< (QDataStream& dataStream, const VLayoutPiece& piece);
friend QDataStream& operator>> (QDataStream& dataStream, VLayoutPiece& piece); friend QDataStream& operator>> (QDataStream& dataStream, VLayoutPiece& piece);
auto MapPlaceLabelShape(PlaceLabelImg shape) const -> PlaceLabelImg;
protected: protected:
void SetGrainlineEnabled(bool enabled); void SetGrainlineEnabled(bool enabled);
void SetGrainlineAngle(qreal angle); void SetGrainlineAngle(qreal angle);
@ -206,7 +208,7 @@ protected:
private: private:
QSharedDataPointer<VLayoutPieceData> d; QSharedDataPointer<VLayoutPieceData> d;
QVector<QPointF> DetailPath() const; QVector<VLayoutPoint> DetailPath() const;
Q_REQUIRED_RESULT QGraphicsPathItem *GetMainItem() const; Q_REQUIRED_RESULT QGraphicsPathItem *GetMainItem() const;
Q_REQUIRED_RESULT QGraphicsPathItem *GetMainPathItem() const; Q_REQUIRED_RESULT QGraphicsPathItem *GetMainPathItem() const;

View File

@ -34,9 +34,7 @@
#include <QVector> #include <QVector>
#include <QTransform> #include <QTransform>
#include "../vpatterndb/floatItemData/vpiecelabeldata.h" #include "../vpatterndb/floatItemData/floatitemdef.h"
#include "../vpatterndb/floatItemData/vpatternlabeldata.h"
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "../vmisc/diagnostic.h" #include "../vmisc/diagnostic.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
@ -47,6 +45,8 @@
#include "../vgeometry/vgeometrydef.h" #include "../vgeometry/vgeometrydef.h"
#include "vtextmanager.h" #include "vtextmanager.h"
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "vlayoutpoint.h"
#include "vlayoutplacelabel.h"
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++") QT_WARNING_DISABLE_GCC("-Weffc++")
@ -55,126 +55,99 @@ QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
class VLayoutPieceData : public QSharedData class VLayoutPieceData : public QSharedData
{ {
public: public:
VLayoutPieceData() VLayoutPieceData(){} // NOLINT(modernize-use-equals-default)
{}
VLayoutPieceData(const VLayoutPieceData &detail)
: QSharedData(detail),
contour(detail.contour),
seamAllowance(detail.seamAllowance),
layoutAllowance(detail.layoutAllowance),
passmarks(detail.passmarks),
m_internalPaths(detail.m_internalPaths),
matrix(detail.matrix),
layoutWidth(detail.layoutWidth),
mirror(detail.mirror),
detailLabel(detail.detailLabel),
patternInfo(detail.patternInfo),
grainlinePoints(detail.grainlinePoints),
grainlineArrowType(detail.grainlineArrowType),
grainlineAngle(detail.grainlineAngle),
grainlineEnabled(detail.grainlineEnabled),
m_tmDetail(detail.m_tmDetail),
m_tmPattern(detail.m_tmPattern),
m_placeLabels(detail.m_placeLabels),
m_square(detail.m_square),
m_quantity(detail.m_quantity),
m_id(detail.m_id),
m_gradationId(detail.m_gradationId),
m_xScale(detail.m_xScale),
m_yScale(detail.m_yScale)
{}
VLayoutPieceData(const VLayoutPieceData &detail) = default;
~VLayoutPieceData() = default; ~VLayoutPieceData() = default;
friend QDataStream& operator<<(QDataStream& dataStream, const VLayoutPieceData& piece); friend auto operator<<(QDataStream& dataStream, const VLayoutPieceData& piece) -> QDataStream&;
friend QDataStream& operator>>(QDataStream& dataStream, VLayoutPieceData& piece); friend auto operator>>(QDataStream& dataStream, VLayoutPieceData& piece) -> QDataStream&;
/** @brief contour list of contour points. */ /** @brief contour list of contour points. */
QVector<QPointF> contour{}; QVector<VLayoutPoint> m_contour{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief seamAllowance list of seam allowance points. */ /** @brief seamAllowance list of seam allowance points. */
QVector<QPointF> seamAllowance{}; QVector<VLayoutPoint> m_seamAllowance{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief layoutAllowance list of layout allowance points. */ /** @brief layoutAllowance list of layout allowance points. */
QVector<QPointF> layoutAllowance{}; QVector<QPointF> m_layoutAllowance{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief passmarks list of passmakrs. */ /** @brief passmarks list of passmakrs. */
QVector<VLayoutPassmark> passmarks{}; QVector<VLayoutPassmark> m_passmarks{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief m_internalPaths list of internal paths. */ /** @brief m_internalPaths list of internal paths. */
QVector<VLayoutPiecePath> m_internalPaths{}; QVector<VLayoutPiecePath> m_internalPaths{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief matrix transformation matrix*/ /** @brief matrix transformation matrix*/
QTransform matrix{}; QTransform m_matrix{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief layoutWidth value layout allowance width in pixels. */ /** @brief layoutWidth value layout allowance width in pixels. */
qreal layoutWidth{0}; qreal m_layoutWidth{0}; // NOLINT(misc-non-private-member-variables-in-classes)
bool mirror{false}; bool m_mirror{false}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief detailLabel detail label rectangle */ /** @brief detailLabel detail label rectangle */
QVector<QPointF> detailLabel{}; QVector<QPointF> m_detailLabel{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief patternInfo pattern info rectangle */ /** @brief patternInfo pattern info rectangle */
QVector<QPointF> patternInfo{}; QVector<QPointF> m_patternInfo{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief grainlineInfo line */ /** @brief grainlineInfo line */
QVector<QPointF> grainlinePoints{}; QVector<QPointF> m_grainlinePoints{}; // NOLINT(misc-non-private-member-variables-in-classes)
GrainlineArrowDirection grainlineArrowType{GrainlineArrowDirection::atFront}; GrainlineArrowDirection m_grainlineArrowType{GrainlineArrowDirection::atFront}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal grainlineAngle{0}; qreal m_grainlineAngle{0}; // NOLINT(misc-non-private-member-variables-in-classes)
bool grainlineEnabled{false}; bool m_grainlineEnabled{false}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief m_tmDetail text manager for laying out detail info */ /** @brief m_tmDetail text manager for laying out detail info */
VTextManager m_tmDetail{}; VTextManager m_tmDetail{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief m_tmPattern text manager for laying out pattern info */ /** @brief m_tmPattern text manager for laying out pattern info */
VTextManager m_tmPattern{}; VTextManager m_tmPattern{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief m_placeLabels list of place labels. */ /** @brief m_placeLabels list of place labels. */
QVector<VLayoutPlaceLabel> m_placeLabels{}; QVector<VLayoutPlaceLabel> m_placeLabels{}; // NOLINT(misc-non-private-member-variables-in-classes)
qint64 m_square{0}; qint64 m_square{0}; // NOLINT(misc-non-private-member-variables-in-classes)
quint16 m_quantity{1}; quint16 m_quantity{1}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief m_id keep id of original piece. */ /** @brief m_id keep id of original piece. */
vidtype m_id; vidtype m_id{NULL_ID}; // NOLINT(misc-non-private-member-variables-in-classes)
QString m_gradationId{}; QString m_gradationId{}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal m_xScale{1.0}; qreal m_xScale{1.0}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal m_yScale{1.0}; qreal m_yScale{1.0}; // NOLINT(misc-non-private-member-variables-in-classes)
private: private:
Q_DISABLE_ASSIGN(VLayoutPieceData) Q_DISABLE_ASSIGN_MOVE(VLayoutPieceData) // NOLINT
static const quint32 streamHeader; static constexpr quint32 streamHeader{0x80D7D009}; // CRC-32Q string "VLayoutPieceData"
static const quint16 classVersion; static constexpr quint16 classVersion{4};
}; };
// Friend functions // Friend functions
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
inline QDataStream &operator<<(QDataStream &dataStream, const VLayoutPieceData &piece) inline auto operator<<(QDataStream &dataStream, const VLayoutPieceData &piece) -> QDataStream &
{ {
dataStream << VLayoutPieceData::streamHeader << VLayoutPieceData::classVersion; dataStream << VLayoutPieceData::streamHeader << VLayoutPieceData::classVersion;
// Added in classVersion = 1 // Added in classVersion = 1
dataStream << piece.contour; dataStream << piece.m_contour;
dataStream << piece.seamAllowance; dataStream << piece.m_seamAllowance;
dataStream << piece.layoutAllowance; dataStream << piece.m_layoutAllowance;
dataStream << piece.passmarks; dataStream << piece.m_passmarks;
dataStream << piece.m_internalPaths; dataStream << piece.m_internalPaths;
dataStream << piece.matrix; dataStream << piece.m_matrix;
dataStream << piece.layoutWidth; dataStream << piece.m_layoutWidth;
dataStream << piece.mirror; dataStream << piece.m_mirror;
dataStream << piece.detailLabel; dataStream << piece.m_detailLabel;
dataStream << piece.patternInfo; dataStream << piece.m_patternInfo;
dataStream << piece.grainlinePoints; dataStream << piece.m_grainlinePoints;
dataStream << piece.grainlineArrowType; dataStream << piece.m_grainlineArrowType;
dataStream << piece.grainlineAngle; dataStream << piece.m_grainlineAngle;
dataStream << piece.grainlineEnabled; dataStream << piece.m_grainlineEnabled;
dataStream << piece.m_placeLabels; dataStream << piece.m_placeLabels;
dataStream << piece.m_square; dataStream << piece.m_square;
@ -193,7 +166,7 @@ inline QDataStream &operator<<(QDataStream &dataStream, const VLayoutPieceData &
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
inline QDataStream &operator>>(QDataStream &dataStream, VLayoutPieceData &piece) inline auto operator>>(QDataStream &dataStream, VLayoutPieceData &piece) -> QDataStream &
{ {
quint32 actualStreamHeader = 0; quint32 actualStreamHeader = 0;
dataStream >> actualStreamHeader; dataStream >> actualStreamHeader;
@ -218,20 +191,35 @@ inline QDataStream &operator>>(QDataStream &dataStream, VLayoutPieceData &piece)
throw VException(message); throw VException(message);
} }
dataStream >> piece.contour; if (actualClassVersion < 4)
dataStream >> piece.seamAllowance; {
dataStream >> piece.layoutAllowance; auto ReadPoints = [&dataStream]()
dataStream >> piece.passmarks; {
QVector<QPointF> points;
dataStream >> points;
return CastTo<VLayoutPoint>(points);
};
piece.m_contour = ReadPoints();
piece.m_seamAllowance = ReadPoints();
}
else
{
dataStream >> piece.m_contour;
dataStream >> piece.m_seamAllowance;
}
dataStream >> piece.m_layoutAllowance;
dataStream >> piece.m_passmarks;
dataStream >> piece.m_internalPaths; dataStream >> piece.m_internalPaths;
dataStream >> piece.matrix; dataStream >> piece.m_matrix;
dataStream >> piece.layoutWidth; dataStream >> piece.m_layoutWidth;
dataStream >> piece.mirror; dataStream >> piece.m_mirror;
dataStream >> piece.detailLabel; dataStream >> piece.m_detailLabel;
dataStream >> piece.patternInfo; dataStream >> piece.m_patternInfo;
dataStream >> piece.grainlinePoints; dataStream >> piece.m_grainlinePoints;
dataStream >> piece.grainlineArrowType; dataStream >> piece.m_grainlineArrowType;
dataStream >> piece.grainlineAngle; dataStream >> piece.m_grainlineAngle;
dataStream >> piece.grainlineEnabled; dataStream >> piece.m_grainlineEnabled;
dataStream >> piece.m_placeLabels; dataStream >> piece.m_placeLabels;
dataStream >> piece.m_square; dataStream >> piece.m_square;

View File

@ -28,13 +28,9 @@
#include "vlayoutpiecepath.h" #include "vlayoutpiecepath.h"
#include "vlayoutpiecepath_p.h" #include "vlayoutpiecepath_p.h"
#include "vlayoutdef.h"
#include <QPainterPath> #include <QPainterPath>
const quint32 VLayoutPiecePathData::streamHeader = 0xA53F0225; // CRC-32Q string "VLayoutPiecePathData"
const quint16 VLayoutPiecePathData::classVersion = 1;
// Friend functions // Friend functions
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QDataStream &operator<<(QDataStream &dataStream, const VLayoutPiecePath &path) QDataStream &operator<<(QDataStream &dataStream, const VLayoutPiecePath &path)
@ -57,7 +53,7 @@ VLayoutPiecePath::VLayoutPiecePath()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VLayoutPiecePath::VLayoutPiecePath(const QVector<QPointF> &points) VLayoutPiecePath::VLayoutPiecePath(const QVector<VLayoutPoint> &points)
: d(new VLayoutPiecePathData(points)) : d(new VLayoutPiecePathData(points))
{ {
} }
@ -104,20 +100,20 @@ QPainterPath VLayoutPiecePath::GetPainterPath() const
QPainterPath path; QPainterPath path;
if (not d->m_points.isEmpty()) if (not d->m_points.isEmpty())
{ {
path.addPolygon(QPolygonF(d->m_points)); path.addPolygon(QPolygonF(CastTo<QPointF>(d->m_points)));
path.setFillRule(Qt::WindingFill); path.setFillRule(Qt::WindingFill);
} }
return path; return path;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiecePath::Points() const QVector<VLayoutPoint> VLayoutPiecePath::Points() const
{ {
return d->m_points; return d->m_points;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiecePath::SetPoints(const QVector<QPointF> &points) void VLayoutPiecePath::SetPoints(const QVector<VLayoutPoint> &points)
{ {
d->m_points = points; d->m_points = points;
} }

View File

@ -29,6 +29,7 @@
#ifndef VLAYOUTPIECEPATH_H #ifndef VLAYOUTPIECEPATH_H
#define VLAYOUTPIECEPATH_H #define VLAYOUTPIECEPATH_H
#include "vlayoutpoint.h"
#include <QPointF> #include <QPointF>
#include <QSharedDataPointer> #include <QSharedDataPointer>
#include <QMetaType> #include <QMetaType>
@ -40,7 +41,7 @@ class VLayoutPiecePath
{ {
public: public:
VLayoutPiecePath(); VLayoutPiecePath();
explicit VLayoutPiecePath(const QVector<QPointF> &points); explicit VLayoutPiecePath(const QVector<VLayoutPoint> &points);
VLayoutPiecePath(const VLayoutPiecePath &path); VLayoutPiecePath(const VLayoutPiecePath &path);
virtual ~VLayoutPiecePath(); virtual ~VLayoutPiecePath();
@ -53,8 +54,8 @@ public:
QPainterPath GetPainterPath() const; QPainterPath GetPainterPath() const;
QVector<QPointF> Points() const; QVector<VLayoutPoint> Points() const;
void SetPoints(const QVector<QPointF> &points); void SetPoints(const QVector<VLayoutPoint> &points);
Qt::PenStyle PenStyle() const; Qt::PenStyle PenStyle() const;
void SetPenStyle(const Qt::PenStyle &penStyle); void SetPenStyle(const Qt::PenStyle &penStyle);

View File

@ -41,6 +41,7 @@
# include "../vmisc/vdatastreamenum.h" # include "../vmisc/vdatastreamenum.h"
#endif #endif
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "vlayoutpoint.h"
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++") QT_WARNING_DISABLE_GCC("-Weffc++")
@ -52,24 +53,18 @@ public:
VLayoutPiecePathData() VLayoutPiecePathData()
{} {}
explicit VLayoutPiecePathData(const QVector<QPointF> &points) explicit VLayoutPiecePathData(const QVector<VLayoutPoint> &points)
: m_points(points) : m_points(points)
{} {}
VLayoutPiecePathData(const VLayoutPiecePathData &path) VLayoutPiecePathData(const VLayoutPiecePathData &path) = default;
: QSharedData(path),
m_points(path.m_points),
m_penStyle(path.m_penStyle),
m_cut(path.m_cut)
{}
~VLayoutPiecePathData() = default; ~VLayoutPiecePathData() = default;
friend QDataStream& operator<<(QDataStream& dataStream, const VLayoutPiecePathData& path); friend QDataStream& operator<<(QDataStream& dataStream, const VLayoutPiecePathData& path);
friend QDataStream& operator>>(QDataStream& dataStream, VLayoutPiecePathData& path); friend QDataStream& operator>>(QDataStream& dataStream, VLayoutPiecePathData& path);
/** @brief m_points list of path points. */ /** @brief m_points list of path points. */
QVector<QPointF> m_points{}; QVector<VLayoutPoint> m_points{};
/** @brief m_penStyle path pen style. */ /** @brief m_penStyle path pen style. */
Qt::PenStyle m_penStyle{Qt::SolidLine}; Qt::PenStyle m_penStyle{Qt::SolidLine};
@ -79,8 +74,8 @@ public:
private: private:
Q_DISABLE_ASSIGN(VLayoutPiecePathData) Q_DISABLE_ASSIGN(VLayoutPiecePathData)
static const quint32 streamHeader; static constexpr quint32 streamHeader = 0xA53F0225; // CRC-32Q string "VLayoutPiecePathData"
static const quint16 classVersion; static constexpr quint16 classVersion = 2;
}; };
QT_WARNING_POP QT_WARNING_POP
@ -127,7 +122,16 @@ QDataStream& operator>>(QDataStream &dataStream, VLayoutPiecePathData &path)
throw VException(message); throw VException(message);
} }
dataStream >> path.m_points; if (actualClassVersion == 1)
{
QVector<QPointF> points;
dataStream >> points;
path.m_points = CastTo<VLayoutPoint>(points);
}
else
{
dataStream >> path.m_points;
}
dataStream >> path.m_penStyle; dataStream >> path.m_penStyle;
dataStream >> path.m_cut; dataStream >> path.m_cut;

View File

@ -0,0 +1,52 @@
/************************************************************************
**
** @file vlayoutpoint.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 17 10, 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 "vlayoutpoint.h"
#include <QJsonObject>
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPoint::toJson() const -> QJsonObject
{
QJsonObject pointObject;
pointObject[QLatin1String("type")] = "VLayoutPoint";
pointObject[QLatin1String("x")] = x();
pointObject[QLatin1String("y")] = y();
if (m_turnPoint)
{
pointObject[QLatin1String("turnPoint")] = m_turnPoint;
}
if (m_curvePoint)
{
pointObject[QLatin1String("curvePoint")] = m_curvePoint;
}
return pointObject;
}

View File

@ -0,0 +1,141 @@
/************************************************************************
**
** @file vlayoutpoint.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 8 10, 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 VLAYOUTPOINT_H
#define VLAYOUTPOINT_H
#include <QtGlobal>
#include <QPointF>
#include <QMetaType>
#include <QVector>
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "../vmisc/diagnostic.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++")
QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
QT_WARNING_DISABLE_CLANG("-Wnon-virtual-dtor")
class VLayoutPoint : public QPointF
{
public:
Q_DECL_CONSTEXPR VLayoutPoint() = default;
Q_DECL_CONSTEXPR VLayoutPoint(qreal xpos, qreal ypos);
Q_DECL_CONSTEXPR explicit VLayoutPoint(QPointF p);
Q_DECL_CONSTEXPR auto TurnPoint() const -> bool;
Q_DECL_CONSTEXPR auto CurvePoint() const -> bool;
Q_DECL_RELAXED_CONSTEXPR void SetTurnPoint(bool newTurnPoint);
Q_DECL_RELAXED_CONSTEXPR void SetCurvePoint(bool newCurvePoint);
virtual auto toJson() const -> QJsonObject;
private:
bool m_turnPoint{false};
bool m_curvePoint{false};
};
Q_DECLARE_METATYPE(VLayoutPoint) // NOLINT
Q_DECLARE_TYPEINFO(VLayoutPoint, Q_MOVABLE_TYPE); // NOLINT
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline auto CastTo(const QVector<T> &points) -> QVector<T>
{
return points;
}
//---------------------------------------------------------------------------------------------------------------------
// upcast
template <class Derived, class Base, typename std::enable_if<std::is_base_of<Base, Derived>::value>::type* = nullptr>
inline auto CastTo(const QVector<Base> &points) -> QVector<Derived>
{
QVector<Derived> castedPoints;
castedPoints.reserve(points.size());
std::transform(points.begin(), points.end(), castedPoints.begin(), [](const Base &p) { return Derived(p); });
return castedPoints;
}
//---------------------------------------------------------------------------------------------------------------------
// downcast
template <class Base, class Derived, typename std::enable_if<std::is_base_of<Base, Derived>::value>::type* = nullptr>
inline auto CastTo(const QVector<Derived> &points) -> QVector<Base>
{
QVector<Base> castedPoints;
castedPoints.reserve(points.size());
std::transform(points.begin(), points.end(), castedPoints.begin(), [](const Base &p) { return p; });
return castedPoints;
}
/*****************************************************************************
VLayoutPoint stream functions
*****************************************************************************/
#ifndef QT_NO_DATASTREAM
auto operator<<(QDataStream &, const VLayoutPoint &) -> QDataStream &;
auto operator>>(QDataStream &, VLayoutPoint &) -> QDataStream &;
#endif
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VLayoutPoint::VLayoutPoint(qreal xpos, qreal ypos)
: QPointF(xpos, ypos)
{}
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VLayoutPoint::VLayoutPoint(QPointF p)
: QPointF(p)
{}
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline auto VLayoutPoint::TurnPoint() const -> bool
{
return m_turnPoint;
}
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_RELAXED_CONSTEXPR inline void VLayoutPoint::SetTurnPoint(bool newTurnPoint)
{
m_turnPoint = newTurnPoint;
}
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline auto VLayoutPoint::CurvePoint() const -> bool
{
return m_curvePoint;
}
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_RELAXED_CONSTEXPR inline void VLayoutPoint::SetCurvePoint(bool newCurvePoint)
{
m_curvePoint = newCurvePoint;
}
QT_WARNING_POP
#endif // VLAYOUTPOINT_H

View File

@ -53,6 +53,7 @@
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "../vpatterndb/floatItemData/floatitemdef.h" #include "../vpatterndb/floatItemData/floatitemdef.h"
#include "../vlayout/vlayoutpoint.h"
namespace namespace
{ {
@ -461,8 +462,9 @@ auto VPosition::Crossing(const VLayoutPiece &detail) const -> VPosition::Crossin
const QRectF layoutBoundingRect = VLayoutPiece::BoundingRect(layoutPoints); const QRectF layoutBoundingRect = VLayoutPiece::BoundingRect(layoutPoints);
const QPainterPath layoutAllowancePath = VAbstractPiece::PainterPath(layoutPoints); const QPainterPath layoutAllowancePath = VAbstractPiece::PainterPath(layoutPoints);
const QVector<QPointF> contourPoints = detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() ? const QVector<QPointF> contourPoints =
detail.GetMappedSeamAllowancePoints() : detail.GetMappedContourPoints(); CastTo<QPointF>(detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() ?
detail.GetMappedSeamAllowancePoints() : detail.GetMappedContourPoints());
const QRectF detailBoundingRect = VLayoutPiece::BoundingRect(contourPoints); const QRectF detailBoundingRect = VLayoutPiece::BoundingRect(contourPoints);
const QPainterPath contourPath = VAbstractPiece::PainterPath(contourPoints); const QPainterPath contourPath = VAbstractPiece::PainterPath(contourPoints);

View File

@ -31,13 +31,11 @@
#include <QJsonObject> #include <QJsonObject>
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QJsonObject VRawSAPoint::toJson() const auto VRawSAPoint::toJson() const -> QJsonObject
{ {
QJsonObject pointObject; QJsonObject pointObject = VLayoutPoint::toJson();
pointObject[QLatin1String("type")] = "VRawSAPoint";
pointObject[QLatin1String("x")] = x();
pointObject[QLatin1String("y")] = y();
pointObject[QLatin1String("type")] = "VRawSAPoint";
pointObject[QLatin1String("loopPoint")] = m_loopPoint; pointObject[QLatin1String("loopPoint")] = m_loopPoint;
return pointObject; return pointObject;

View File

@ -28,59 +28,74 @@
#ifndef VRAWSAPOINT_H #ifndef VRAWSAPOINT_H
#define VRAWSAPOINT_H #define VRAWSAPOINT_H
#include <QPointF> #include <QtGlobal>
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "../vmisc/diagnostic.h" #include "../vmisc/diagnostic.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "../vmisc/def.h" #include "vlayoutpoint.h"
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++") QT_WARNING_DISABLE_GCC("-Weffc++")
QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor") QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
QT_WARNING_DISABLE_CLANG("-Wnon-virtual-dtor")
class VRawSAPoint : public QPointF class VRawSAPoint : public VLayoutPoint
{ {
public: public:
Q_DECL_CONSTEXPR VRawSAPoint(); Q_DECL_CONSTEXPR VRawSAPoint() = default;
Q_DECL_CONSTEXPR VRawSAPoint(qreal xpos, qreal ypos); Q_DECL_CONSTEXPR VRawSAPoint(qreal xpos, qreal ypos);
Q_DECL_CONSTEXPR VRawSAPoint(QPointF p); Q_DECL_CONSTEXPR explicit VRawSAPoint(QPointF p);
Q_DECL_CONSTEXPR VRawSAPoint(QPointF p, bool loopPoint); Q_DECL_CONSTEXPR explicit VRawSAPoint(const VLayoutPoint &p);
Q_DECL_CONSTEXPR VRawSAPoint(QPointF p, bool curvePoint, bool turnPoint);
Q_DECL_CONSTEXPR VRawSAPoint(QPointF p, bool curvePoint, bool turnPoint, bool loopPoint);
Q_DECL_CONSTEXPR bool LoopPoint() const; Q_DECL_CONSTEXPR auto LoopPoint() const -> bool;
Q_DECL_RELAXED_CONSTEXPR void SetLoopPoint(bool loopPoint); Q_DECL_RELAXED_CONSTEXPR void SetLoopPoint(bool loopPoint);
QJsonObject toJson() const; auto toJson() const -> QJsonObject override;
private: private:
bool m_loopPoint{false}; bool m_loopPoint{false};
}; };
Q_DECLARE_METATYPE(VRawSAPoint) Q_DECLARE_METATYPE(VRawSAPoint) // NOLINT
Q_DECLARE_TYPEINFO(VRawSAPoint, Q_MOVABLE_TYPE); // NOLINT Q_DECLARE_TYPEINFO(VRawSAPoint, Q_MOVABLE_TYPE); // NOLINT
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint()
{}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint(qreal xpos, qreal ypos) Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint(qreal xpos, qreal ypos)
: QPointF(xpos, ypos) : VLayoutPoint(xpos, ypos)
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint(QPointF p) Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint(QPointF p)
: QPointF(p) : VLayoutPoint(p)
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint(QPointF p, bool loopPoint) Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint(const VLayoutPoint &p)
: QPointF(p), : VLayoutPoint(p)
{}
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint(QPointF p, bool curvePoint, bool turnPoint)
: VLayoutPoint(p)
{
SetCurvePoint(curvePoint);
SetTurnPoint(turnPoint);
}
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VRawSAPoint::VRawSAPoint(QPointF p, bool curvePoint, bool turnPoint, bool loopPoint)
: VLayoutPoint(p),
m_loopPoint(loopPoint) m_loopPoint(loopPoint)
{} {
SetCurvePoint(curvePoint);
SetTurnPoint(turnPoint);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline bool VRawSAPoint::LoopPoint() const Q_DECL_CONSTEXPR inline auto VRawSAPoint::LoopPoint() const -> bool
{ {
return m_loopPoint; return m_loopPoint;
} }

View File

@ -36,17 +36,17 @@
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../vgeometry/vgeometrydef.h" #include "../vgeometry/vgeometrydef.h"
#include "vlayoutpoint.h"
#include <QPointF>
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++") QT_WARNING_DISABLE_GCC("-Weffc++")
QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor") QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
QT_WARNING_DISABLE_CLANG("-Wnon-virtual-dtor")
/** /**
* @brief The VSAPoint class seam allowance point * @brief The VSAPoint class seam allowance point
*/ */
class VSAPoint : public QPointF class VSAPoint : public VLayoutPoint
{ {
public: public:
QT_WARNING_PUSH QT_WARNING_PUSH
@ -58,6 +58,7 @@ public:
Q_DECL_CONSTEXPR VSAPoint(qreal xpos, qreal ypos); Q_DECL_CONSTEXPR VSAPoint(qreal xpos, qreal ypos);
Q_DECL_CONSTEXPR explicit VSAPoint(QPointF p); Q_DECL_CONSTEXPR explicit VSAPoint(QPointF p);
Q_DECL_CONSTEXPR explicit VSAPoint(const VLayoutPoint &p);
Q_DECL_CONSTEXPR auto GetSABefore() const -> qreal; Q_DECL_CONSTEXPR auto GetSABefore() const -> qreal;
Q_DECL_CONSTEXPR auto GetSAAfter() const -> qreal; Q_DECL_CONSTEXPR auto GetSAAfter() const -> qreal;
@ -78,7 +79,7 @@ public:
Q_DECL_RELAXED_CONSTEXPR auto MaxLocalSA(qreal width) const -> qreal; Q_DECL_RELAXED_CONSTEXPR auto MaxLocalSA(qreal width) const -> qreal;
Q_DECL_RELAXED_CONSTEXPR auto PassmarkLength(qreal width) const -> qreal; Q_DECL_RELAXED_CONSTEXPR auto PassmarkLength(qreal width) const -> qreal;
auto toJson() const -> QJsonObject; auto toJson() const -> QJsonObject override;
static constexpr qreal passmarkFactor{0.5}; static constexpr qreal passmarkFactor{0.5};
static constexpr qreal maxPassmarkLength{MmToPixel(10.)}; static constexpr qreal maxPassmarkLength{MmToPixel(10.)};
@ -97,12 +98,17 @@ Q_DECLARE_TYPEINFO(VSAPoint, Q_MOVABLE_TYPE); // NOLINT
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VSAPoint::VSAPoint(qreal xpos, qreal ypos) Q_DECL_CONSTEXPR inline VSAPoint::VSAPoint(qreal xpos, qreal ypos)
: QPointF(xpos, ypos) : VLayoutPoint(xpos, ypos)
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VSAPoint::VSAPoint(QPointF p) Q_DECL_CONSTEXPR inline VSAPoint::VSAPoint(QPointF p)
: QPointF(p) : VLayoutPoint(p)
{}
//---------------------------------------------------------------------------------------------------------------------
Q_DECL_CONSTEXPR inline VSAPoint::VSAPoint(const VLayoutPoint &p)
: VLayoutPoint(p)
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -198,7 +198,7 @@ inline void Move(T &vector, int from, int to)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
auto Reverse(const QVector<T> &container) -> QVector<T> inline auto Reverse(const QVector<T> &container) -> QVector<T>
{ {
if (container.isEmpty()) if (container.isEmpty())
{ {
@ -216,14 +216,14 @@ auto Reverse(const QVector<T> &container) -> QVector<T>
template <typename T, template <typename> class C> template <typename T, template <typename> class C>
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto Reverse(const C<T> &container) -> C<T> inline auto Reverse(const C<T> &container) -> C<T>
{ {
return ConvertToList(Reverse(ConvertToVector(container))); return ConvertToList(Reverse(ConvertToVector(container)));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <typename T, typename std::enable_if<std::is_same<T, QStringList>::value, T>::type* = nullptr> template <typename T, typename std::enable_if<std::is_same<T, QStringList>::value, T>::type* = nullptr>
auto Reverse(const T &container) -> T inline auto Reverse(const T &container) -> T
{ {
return Reverse<QString, QList>(container); return Reverse<QString, QList>(container);
} }

View File

@ -33,7 +33,6 @@
#include "../ifc/exception/vexceptioninvalidnotch.h" #include "../ifc/exception/vexceptioninvalidnotch.h"
#include "../vgeometry/vabstractcurve.h" #include "../vgeometry/vabstractcurve.h"
#include "../vgeometry/varc.h" #include "../vgeometry/varc.h"
#include "testpassmark.h"
#include "../vlayout/vrawsapoint.h" #include "../vlayout/vrawsapoint.h"
const qreal VPassmark::passmarkRadiusFactor = 0.45; const qreal VPassmark::passmarkRadiusFactor = 0.45;
@ -53,7 +52,7 @@ PassmarkStatus GetSeamPassmarkSAPoint(const VPiecePassmarkData &passmarkData, co
if (needRollback && not seamAllowance.isEmpty()) if (needRollback && not seamAllowance.isEmpty())
{ {
ekvPoints.clear(); ekvPoints.clear();
ekvPoints += seamAllowance.at(seamAllowance.size()-2); ekvPoints += VRawSAPoint(seamAllowance.at(seamAllowance.size()-2));
} }
if (ekvPoints.isEmpty()) if (ekvPoints.isEmpty())
@ -726,7 +725,7 @@ QVector<QLineF> VPassmark::SAPassmark(const VPiece &piece, const VContainer *dat
if (not piece.IsSeamAllowanceBuiltIn()) if (not piece.IsSeamAllowanceBuiltIn())
{ {
// Because rollback cannot be calulated if passmark is not first point in main path we rotate it. // Because rollback cannot be calulated if passmark is not first point in main path we rotate it.
return SAPassmark(piece.SeamAllowancePointsWithRotation(data, m_data.passmarkIndex), side); return SAPassmark(CastTo<QPointF>(piece.SeamAllowancePointsWithRotation(data, m_data.passmarkIndex)), side);
} }
return QVector<QLineF>(); return QVector<QLineF>();
@ -801,8 +800,8 @@ QVector<QLineF> VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContain
return QVector<QLineF>(); return QVector<QLineF>();
} }
return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, lines, piece.MainPathPoints(data), return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, lines,
PassmarkSide::All); CastTo<QPointF>(piece.MainPathPoints(data)), PassmarkSide::All);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -868,7 +867,8 @@ QVector<QLineF> VPassmark::SAPassmarkBaseLine(const VPiece &piece, const VContai
if (not piece.IsSeamAllowanceBuiltIn()) if (not piece.IsSeamAllowanceBuiltIn())
{ {
// Because rollback cannot be calulated if passmark is not first point in main path we rotate it. // Because rollback cannot be calulated if passmark is not first point in main path we rotate it.
return SAPassmarkBaseLine(piece.SeamAllowancePointsWithRotation(data, m_data.passmarkIndex), side); return SAPassmarkBaseLine(CastTo<QPointF>(piece.SeamAllowancePointsWithRotation(data, m_data.passmarkIndex)),
side);
} }
return QVector<QLineF>(); return QVector<QLineF>();

View File

@ -32,7 +32,7 @@
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vgeometry/vabstractcurve.h" #include "../vgeometry/vabstractcurve.h"
#include "../vgeometry/vplacelabelitem.h" #include "../vgeometry/vplacelabelitem.h"
#include "../vgeometry/varc.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "vcontainer.h" #include "vcontainer.h"
#include "../vmisc/vabstractvalapplication.h" #include "../vmisc/vabstractvalapplication.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
@ -171,14 +171,14 @@ void VPiece::SetPath(const VPiecePath &path)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::MainPathPoints(const VContainer *data) const QVector<VLayoutPoint> VPiece::MainPathPoints(const VContainer *data) const
{ {
// DumpPiece(*this, data, QStringLiteral("input.json.XXXXXX")); // Uncomment for dumping test data // DumpPiece(*this, data, QStringLiteral("input.json.XXXXXX")); // Uncomment for dumping test data
VPiecePath mainPath = GetPath(); VPiecePath mainPath = GetPath();
mainPath.SetName(tr("Main path of piece %1").arg(GetName())); mainPath.SetName(tr("Main path of piece %1").arg(GetName()));
QVector<QPointF> points = mainPath.PathPoints(data); QVector<VLayoutPoint> points = mainPath.PathPoints(data);
points = CheckLoops(CorrectEquidistantPoints(points));//A path can contains loops points = CheckLoops(CorrectEquidistantPoints(points));//A path can contains loops
// DumpVector(points, QStringLiteral("output.json.XXXXXX")); // Uncomment for dumping test data // DumpVector(points, QStringLiteral("output.json.XXXXXX")); // Uncomment for dumping test data
@ -186,9 +186,9 @@ QVector<QPointF> VPiece::MainPathPoints(const VContainer *data) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::UniteMainPathPoints(const VContainer *data) const QVector<VLayoutPoint> VPiece::UniteMainPathPoints(const VContainer *data) const
{ {
QVector<QPointF> points = VPiecePath::NodesToPoints(data, GetUnitedPath(data), GetName()); QVector<VLayoutPoint> points = VPiecePath::NodesToPoints(data, GetUnitedPath(data), GetName());
points = CheckLoops(CorrectEquidistantPoints(points));//A path can contains loops points = CheckLoops(CorrectEquidistantPoints(points));//A path can contains loops
return points; return points;
} }
@ -200,7 +200,7 @@ QVector<VPointF> VPiece::MainPathNodePoints(const VContainer *data, bool showExc
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const QVector<VLayoutPoint> VPiece::SeamAllowancePoints(const VContainer *data) const
{ {
return SeamAllowancePointsWithRotation(data, -1); return SeamAllowancePointsWithRotation(data, -1);
} }
@ -208,14 +208,12 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::CuttingPathPoints(const VContainer *data) const QVector<QPointF> VPiece::CuttingPathPoints(const VContainer *data) const
{ {
if (IsSeamAllowance() and not IsSeamAllowanceBuiltIn()) if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{ {
return SeamAllowancePoints(data); return CastTo<QPointF>(SeamAllowancePoints(data));
}
else
{
return MainPathPoints(data);
} }
return CastTo<QPointF>(MainPathPoints(data));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -271,7 +269,7 @@ QVector<QPainterPath> VPiece::CurvesPainterPath(const VContainer *data) const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VPiece::MainPathPath(const VContainer *data) const QPainterPath VPiece::MainPathPath(const VContainer *data) const
{ {
return VPiece::MainPathPath(MainPathPoints(data)); return VPiece::MainPathPath(CastTo<QPointF>(MainPathPoints(data)));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -299,42 +297,6 @@ QPainterPath VPiece::SeamAllowancePath(const VContainer *data) const
return SeamAllowancePath(SeamAllowancePoints(data)); return SeamAllowancePath(SeamAllowancePoints(data));
} }
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VPiece::SeamAllowancePath(const QVector<QPointF> &points) const
{
QPainterPath ekv;
// seam allowence
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{
if (not points.isEmpty())
{
ekv.moveTo(points.at(0));
for (qint32 i = 1; i < points.count(); ++i)
{
ekv.lineTo(points.at(i));
}
#if !defined(V_NO_ASSERT)
// uncomment for debug
// QFont font;
// font.setPixelSize(1);
// for (qint32 i = 0; i < points.count(); ++i)
// {
// ekv.addEllipse(points.at(i).x()-accuracyPointOnLine, points.at(i).y()-accuracyPointOnLine,
// accuracyPointOnLine*2., accuracyPointOnLine*2.);
// ekv.addText(points.at(i).x()-accuracyPointOnLine, points.at(i).y()-accuracyPointOnLine, font,
// QString::number(i+1));
// }
#endif
ekv.setFillRule(Qt::WindingFill);
}
}
return ekv;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VPiece::PassmarksPath(const VContainer *data) const QPainterPath VPiece::PassmarksPath(const VContainer *data) const
{ {
@ -370,7 +332,7 @@ QPainterPath VPiece::PlaceLabelPath(const VContainer *data) const
const auto label = data->GeometricObject<VPlaceLabelItem>(placeLabel); const auto label = data->GeometricObject<VPlaceLabelItem>(placeLabel);
if (label->IsVisible()) if (label->IsVisible())
{ {
path.addPath(label->LabelShapePath()); path.addPath(LabelShapePath(VLayoutPlaceLabel(*label)));
} }
} }
catch (const VExceptionBadId &e) catch (const VExceptionBadId &e)
@ -387,12 +349,11 @@ bool VPiece::IsSeamAllowanceValid(const VContainer *data) const
{ {
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{ {
return VAbstractPiece::IsAllowanceValid(UniteMainPathPoints(data), SeamAllowancePoints(data)); return VAbstractPiece::IsAllowanceValid(CastTo<QPointF>(UniteMainPathPoints(data)),
} CastTo<QPointF>(SeamAllowancePoints(data)));
else
{
return true;
} }
return true;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -662,13 +623,13 @@ const VGrainlineData &VPiece::GetGrainlineGeometry() const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::SeamAllowancePointsWithRotation(const VContainer *data, int makeFirst) const QVector<VLayoutPoint> VPiece::SeamAllowancePointsWithRotation(const VContainer *data, int makeFirst) const
{ {
SCASSERT(data != nullptr); SCASSERT(data != nullptr);
if (not IsSeamAllowance() || IsSeamAllowanceBuiltIn()) if (not IsSeamAllowance() || IsSeamAllowanceBuiltIn())
{ {
return QVector<QPointF>(); return {};
} }
const QVector<CustomSARecord> records = FilterRecords(GetValidRecords()); const QVector<CustomSARecord> records = FilterRecords(GetValidRecords());

View File

@ -33,7 +33,6 @@
#include <QSharedDataPointer> #include <QSharedDataPointer>
#include "../vlayout/vabstractpiece.h" #include "../vlayout/vabstractpiece.h"
#include "../vgeometry/vgeometrydef.h"
class VPieceData; class VPieceData;
class VPieceNode; class VPieceNode;
@ -65,10 +64,10 @@ public:
VPiecePath &GetPath(); VPiecePath &GetPath();
void SetPath(const VPiecePath &path); void SetPath(const VPiecePath &path);
QVector<QPointF> MainPathPoints(const VContainer *data) const; QVector<VLayoutPoint> MainPathPoints(const VContainer *data) const;
QVector<QPointF> UniteMainPathPoints(const VContainer *data) const; QVector<VLayoutPoint> UniteMainPathPoints(const VContainer *data) const;
QVector<VPointF> MainPathNodePoints(const VContainer *data, bool showExcluded = false) const; QVector<VPointF> MainPathNodePoints(const VContainer *data, bool showExcluded = false) const;
QVector<QPointF> SeamAllowancePoints(const VContainer *data) const; QVector<VLayoutPoint> SeamAllowancePoints(const VContainer *data) const;
QVector<QPointF> CuttingPathPoints(const VContainer *data) const; QVector<QPointF> CuttingPathPoints(const VContainer *data) const;
QVector<QLineF> PassmarksLines(const VContainer *data) const; QVector<QLineF> PassmarksLines(const VContainer *data) const;
@ -80,7 +79,8 @@ public:
static QPainterPath MainPathPath(const QVector<QPointF> &points); static QPainterPath MainPathPath(const QVector<QPointF> &points);
QPainterPath SeamAllowancePath(const VContainer *data) const; QPainterPath SeamAllowancePath(const VContainer *data) const;
QPainterPath SeamAllowancePath(const QVector<QPointF> &points) const; template <class T>
QPainterPath SeamAllowancePath(const QVector<T> &points) const;
QPainterPath PassmarksPath(const VContainer *data) const; QPainterPath PassmarksPath(const VContainer *data) const;
QPainterPath PlaceLabelPath(const VContainer *data) const; QPainterPath PlaceLabelPath(const VContainer *data) const;
@ -132,7 +132,7 @@ public:
QVector<VPieceNode> GetUnitedPath(const VContainer *data) const; QVector<VPieceNode> GetUnitedPath(const VContainer *data) const;
QVector<QPointF> SeamAllowancePointsWithRotation(const VContainer *data, int makeFirst) const; QVector<VLayoutPoint> SeamAllowancePointsWithRotation(const VContainer *data, int makeFirst) const;
void SetGradationLabel(const QString &label); void SetGradationLabel(const QString &label);
auto GetGradationLabel() const -> QString; auto GetGradationLabel() const -> QString;
@ -167,4 +167,41 @@ private:
Q_DECLARE_TYPEINFO(VPiece, Q_MOVABLE_TYPE); // NOLINT Q_DECLARE_TYPEINFO(VPiece, Q_MOVABLE_TYPE); // NOLINT
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline QPainterPath VPiece::SeamAllowancePath(const QVector<T> &points) const
{
QPainterPath ekv;
// seam allowence
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{
if (not points.isEmpty())
{
ekv.moveTo(points.at(0));
for (qint32 i = 1; i < points.count(); ++i)
{
ekv.lineTo(points.at(i));
}
#if !defined(V_NO_ASSERT)
// uncomment for debug
// QFont font;
// font.setPixelSize(1);
// for (qint32 i = 0; i < points.count(); ++i)
// {
// ekv.addEllipse(points.at(i).x()-accuracyPointOnLine, points.at(i).y()-accuracyPointOnLine,
// accuracyPointOnLine*2., accuracyPointOnLine*2.);
// ekv.addText(points.at(i).x()-accuracyPointOnLine, points.at(i).y()-accuracyPointOnLine, font,
// QString::number(i+1));
// }
#endif
ekv.setFillRule(Qt::WindingFill);
}
}
return ekv;
}
#endif // VPIECE_H #endif // VPIECE_H

View File

@ -36,9 +36,6 @@
#include <QDataStream> #include <QDataStream>
#include <QtNumeric> #include <QtNumeric>
const quint32 VPieceNodeData::streamHeader = 0x2198CBC8; // CRC-32Q string "VPieceNodeData"
const quint16 VPieceNodeData::classVersion = 1;
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPieceNode::VPieceNode() VPieceNode::VPieceNode()
: d(new VPieceNodeData) : d(new VPieceNodeData)
@ -454,6 +451,18 @@ void VPieceNode::SetManualPassmarkLength(bool value)
d->m_manualPassmarkLength = value; d->m_manualPassmarkLength = value;
} }
//---------------------------------------------------------------------------------------------------------------------
bool VPieceNode::IsTurnPoint() const
{
return d->m_typeTool == Tool::NodePoint ? d->m_turnPoint : false;
}
//---------------------------------------------------------------------------------------------------------------------
void VPieceNode::SetTurnPoint(bool value)
{
d->m_turnPoint = value;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VPieceNode::IsExcluded() const bool VPieceNode::IsExcluded() const
{ {

View File

@ -108,6 +108,9 @@ public:
bool IsManualPassmarkLength() const; bool IsManualPassmarkLength() const;
void SetManualPassmarkLength(bool value); void SetManualPassmarkLength(bool value);
bool IsTurnPoint() const;
void SetTurnPoint(bool value);
private: private:
QSharedDataPointer<VPieceNodeData> d; QSharedDataPointer<VPieceNodeData> d;
}; };

View File

@ -63,24 +63,7 @@ public:
} }
} }
VPieceNodeData (const VPieceNodeData& node) VPieceNodeData (const VPieceNodeData& node) = default;
: QSharedData(node),
m_id(node.m_id),
m_typeTool(node.m_typeTool),
m_reverse(node.m_reverse),
m_excluded(node.m_excluded),
m_isPassmark(node.m_isPassmark),
m_isMainPathNode(node.m_isMainPathNode),
m_formulaWidthBefore(node.m_formulaWidthBefore),
m_formulaWidthAfter(node.m_formulaWidthAfter),
m_formulaPassmarkLength(node.m_formulaPassmarkLength),
m_angleType(node.m_angleType),
m_passmarkLineType(node.m_passmarkLineType),
m_passmarkAngleType(node.m_passmarkAngleType),
m_isShowSecondPassmark(node.m_isShowSecondPassmark),
m_checkUniqueness(node.m_checkUniqueness),
m_manualPassmarkLength(node.m_manualPassmarkLength)
{}
~VPieceNodeData() = default; ~VPieceNodeData() = default;
@ -124,11 +107,13 @@ public:
bool m_manualPassmarkLength{false}; bool m_manualPassmarkLength{false};
bool m_turnPoint{true};
private: private:
Q_DISABLE_ASSIGN(VPieceNodeData) Q_DISABLE_ASSIGN(VPieceNodeData)
static const quint32 streamHeader; static constexpr quint32 streamHeader = 0x2198CBC8; // CRC-32Q string "VPieceNodeData"
static const quint16 classVersion; static constexpr quint16 classVersion = 2;
}; };
// Friend functions // Friend functions
@ -155,6 +140,8 @@ QDataStream &operator<<(QDataStream &out, const VPieceNodeData &p)
// Added in classVersion = 2 // Added in classVersion = 2
out << p.m_turnPoint;
return out; return out;
} }
@ -199,10 +186,10 @@ QDataStream &operator>>(QDataStream &in, VPieceNodeData &p)
>> p.m_checkUniqueness >> p.m_checkUniqueness
>> p.m_manualPassmarkLength; >> p.m_manualPassmarkLength;
// if (actualClassVersion >= 2) if (actualClassVersion >= 2)
// { {
in >> p.m_turnPoint;
// } }
return in; return in;
} }

View File

@ -30,7 +30,6 @@
#include "vpiecepath_p.h" #include "vpiecepath_p.h"
#include "vcontainer.h" #include "vcontainer.h"
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vlayout/vabstractpiece.h"
#include "calculator.h" #include "calculator.h"
#include "../vmisc/vabstractvalapplication.h" #include "../vmisc/vabstractvalapplication.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
@ -54,6 +53,7 @@ VSAPoint CurvePoint(VSAPoint candidate, const VContainer *data, const VPieceNode
candidate.SetSAAfter(node.GetSAAfter(data, *data->GetPatternUnit())); candidate.SetSAAfter(node.GetSAAfter(data, *data->GetPatternUnit()));
candidate.SetSABefore(node.GetSABefore(data, *data->GetPatternUnit())); candidate.SetSABefore(node.GetSABefore(data, *data->GetPatternUnit()));
candidate.SetAngleType(node.GetAngleType()); candidate.SetAngleType(node.GetAngleType());
candidate.SetTurnPoint(node.IsTurnPoint());
} }
} }
return candidate; return candidate;
@ -92,6 +92,7 @@ VSAPoint CurveStartPoint(VSAPoint candidate, const VContainer *data, const VPiec
} }
candidate = VSAPoint(p); candidate = VSAPoint(p);
candidate.SetTurnPoint(true);
break; break;
} }
@ -131,6 +132,7 @@ VSAPoint CurveEndPoint(VSAPoint candidate, const VContainer *data, const VPieceN
} }
candidate = VSAPoint(p); candidate = VSAPoint(p);
candidate.SetTurnPoint(true);
break; break;
} }
@ -172,14 +174,15 @@ QPainterPath MakePainterPath(const QVector<QPointF> &points)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
qreal FindTipDirection(const QVector<QPointF> &points) template <class T>
qreal FindTipDirection(const QVector<T> &points)
{ {
if (points.size() <= 1) if (points.size() <= 1)
{ {
return 0; return 0;
} }
const QPointF &first = ConstFirst(points); const T &first = ConstFirst(points);
for(int i = 1; i < points.size(); ++i) for(int i = 1; i < points.size(); ++i)
{ {
@ -195,8 +198,8 @@ qreal FindTipDirection(const QVector<QPointF> &points)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool IntersectionWithCuttingCountour(const QVector<QPointF> &cuttingPath, const QVector<QPointF> &points, bool IntersectionWithCuttingCountour(const QVector<QPointF> &cuttingPath, const QVector<VLayoutPoint> &points,
QPointF *firstConnection) QPointF *connection)
{ {
if (points.size() <= 1) if (points.size() <= 1)
{ {
@ -207,12 +210,35 @@ bool IntersectionWithCuttingCountour(const QVector<QPointF> &cuttingPath, const
if (VAbstractCurve::IsPointOnCurve(cuttingPath, first)) if (VAbstractCurve::IsPointOnCurve(cuttingPath, first))
{ // Point is already part of a cutting countour { // Point is already part of a cutting countour
*firstConnection = first; *connection = first;
return true; return true;
} }
else else
{ {
return VAbstractCurve::CurveIntersectAxis(first, FindTipDirection(points), cuttingPath, firstConnection); return VAbstractCurve::CurveIntersectAxis(first, FindTipDirection(points), cuttingPath, connection);
}
}
//---------------------------------------------------------------------------------------------------------------------
template <class T>
void AppendCurveSegment(QVector<T> &points, QVector<QPointF> &segment, const VSAPoint &begin, const VSAPoint &end)
{
points.reserve(points.size() + segment.size());
for(int i=0; i < segment.size(); ++i)
{
VLayoutPoint lp(segment.at(i));
if (i == 0)
{
lp.SetTurnPoint(VFuzzyComparePoints(lp, begin) ? begin.TurnPoint() : true);
}
else if (i == segment.size() - 1)
{
lp.SetTurnPoint(VFuzzyComparePoints(lp, end) ? end.TurnPoint() : true);
}
lp.SetCurvePoint(true);
points.append(lp);
} }
} }
} }
@ -388,19 +414,20 @@ bool VPiecePath::IsLastToCuttingCountour() const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiecePath::PathPoints(const VContainer *data, const QVector<QPointF> &cuttingPath) const QVector<VLayoutPoint> VPiecePath::PathPoints(const VContainer *data, const QVector<QPointF> &cuttingPath) const
{ {
QVector<QPointF> points = NodesToPoints(data, d->m_nodes, GetName()); QVector<VLayoutPoint> points = NodesToPoints(data, d->m_nodes, GetName());
if (GetType() == PiecePathType::InternalPath && not cuttingPath.isEmpty() && points.size() > 1) if (GetType() == PiecePathType::InternalPath && not cuttingPath.isEmpty() && points.size() > 1)
{ {
QVector<QPointF> extended = points; QVector<VLayoutPoint> extended = points;
if (IsFirstToCuttingCountour()) if (IsFirstToCuttingCountour())
{ {
QPointF firstConnection; VLayoutPoint firstConnection;
if (IntersectionWithCuttingCountour(cuttingPath, points, &firstConnection)) if (IntersectionWithCuttingCountour(cuttingPath, points, &firstConnection))
{ {
firstConnection.SetTurnPoint(true);
extended.prepend(firstConnection); extended.prepend(firstConnection);
} }
else else
@ -415,9 +442,10 @@ QVector<QPointF> VPiecePath::PathPoints(const VContainer *data, const QVector<QP
if (IsLastToCuttingCountour()) if (IsLastToCuttingCountour())
{ {
QPointF lastConnection; VLayoutPoint lastConnection;
if (IntersectionWithCuttingCountour(cuttingPath, Reverse(points), &lastConnection)) if (IntersectionWithCuttingCountour(cuttingPath, Reverse(points), &lastConnection))
{ {
lastConnection.SetTurnPoint(true);
extended.append(lastConnection); extended.append(lastConnection);
} }
else else
@ -542,7 +570,7 @@ QVector<VSAPoint> VPiecePath::SeamAllowancePoints(const VContainer *data, qreal
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VPiecePath::PainterPath(const VContainer *data, const QVector<QPointF> &cuttingPath) const QPainterPath VPiecePath::PainterPath(const VContainer *data, const QVector<QPointF> &cuttingPath) const
{ {
return MakePainterPath(PathPoints(data, cuttingPath)); return MakePainterPath(CastTo<QPointF>(PathPoints(data, cuttingPath)));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1104,6 +1132,7 @@ VSAPoint VPiecePath::PreparePointEkv(const VPieceNode &node, const VContainer *d
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(node.GetId()); const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(node.GetId());
VSAPoint p(point->toQPointF()); VSAPoint p(point->toQPointF());
p.SetTurnPoint(node.IsTurnPoint());
p.SetSAAfter(node.GetSAAfter(data, *data->GetPatternUnit())); p.SetSAAfter(node.GetSAAfter(data, *data->GetPatternUnit()));
p.SetSABefore(node.GetSABefore(data, *data->GetPatternUnit())); p.SetSABefore(node.GetSABefore(data, *data->GetPatternUnit()));
p.SetAngleType(node.GetAngleType()); p.SetAngleType(node.GetAngleType());
@ -1138,18 +1167,23 @@ QVector<VSAPoint> VPiecePath::CurveSeamAllowanceSegment(const VContainer *data,
{ {
VSAPoint p(points.at(i)); VSAPoint p(points.at(i));
p.SetAngleType(PieceNodeAngle::ByLengthCurve); p.SetAngleType(PieceNodeAngle::ByLengthCurve);
p.SetCurvePoint(true);
if (i == 0) if (i == 0)
{ // first point { // first point
p.SetSAAfter(begin.GetSAAfter()); p.SetSAAfter(begin.GetSAAfter());
p.SetSABefore(begin.GetSABefore()); p.SetSABefore(begin.GetSABefore());
p.SetAngleType(begin.GetAngleType()); p.SetAngleType(begin.GetAngleType());
p.SetTurnPoint(VFuzzyComparePoints(p, begin) ? begin.TurnPoint() : true);
} }
else if (i == points.size() - 1) else if (i == points.size() - 1)
{ // last point { // last point
p.SetSAAfter(end.GetSAAfter()); p.SetSAAfter(end.GetSAAfter());
p.SetSABefore(end.GetSABefore()); p.SetSABefore(end.GetSABefore());
p.SetAngleType(end.GetAngleType()); p.SetAngleType(end.GetAngleType());
p.SetTurnPoint(VFuzzyComparePoints(p, end) ? end.TurnPoint() : true);
} }
pointsEkv.append(p); pointsEkv.append(p);
} }
} }
@ -1165,13 +1199,15 @@ QVector<VSAPoint> VPiecePath::CurveSeamAllowanceSegment(const VContainer *data,
w2 = width; w2 = width;
} }
const qreal wDiff = w2 - w1;// Difference between to local widths const qreal wDiff = w2 - w1;// Difference between two local widths
const qreal fullLength = VAbstractCurve::PathLength(points); const qreal fullLength = VAbstractCurve::PathLength(points);
VSAPoint p(points.at(0));//First point in the list VSAPoint p(points.at(0));//First point in the list
p.SetSAAfter(begin.GetSAAfter()); p.SetSAAfter(begin.GetSAAfter());
p.SetSABefore(begin.GetSABefore()); p.SetSABefore(begin.GetSABefore());
p.SetAngleType(begin.GetAngleType()); p.SetAngleType(begin.GetAngleType());
p.SetCurvePoint(true);
p.SetTurnPoint(VFuzzyComparePoints(p, begin) ? begin.TurnPoint() : true);
pointsEkv.append(p); pointsEkv.append(p);
qreal length = 0; // how much we handle qreal length = 0; // how much we handle
@ -1179,12 +1215,14 @@ QVector<VSAPoint> VPiecePath::CurveSeamAllowanceSegment(const VContainer *data,
for(int i = 1; i < points.size(); ++i) for(int i = 1; i < points.size(); ++i)
{ {
p = VSAPoint(points.at(i)); p = VSAPoint(points.at(i));
p.SetCurvePoint(true);
if (i == points.size() - 1) if (i == points.size() - 1)
{// last point {// last point
p.SetSAAfter(end.GetSAAfter()); p.SetSAAfter(end.GetSAAfter());
p.SetSABefore(end.GetSABefore()); p.SetSABefore(end.GetSABefore());
p.SetAngleType(end.GetAngleType()); p.SetAngleType(end.GetAngleType());
p.SetTurnPoint(VFuzzyComparePoints(p, end) ? end.TurnPoint() : true);
} }
else else
{ {
@ -1224,10 +1262,10 @@ QString VPiecePath::NodeName(const QVector<VPieceNode> &nodes, int nodeIndex, co
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiecePath::NodesToPoints(const VContainer *data, const QVector<VPieceNode> &nodes, QVector<VLayoutPoint> VPiecePath::NodesToPoints(const VContainer *data, const QVector<VPieceNode> &nodes,
const QString &piece) const QString &piece)
{ {
QVector<QPointF> points; QVector<VLayoutPoint> points;
for (int i = 0; i < nodes.size(); ++i) for (int i = 0; i < nodes.size(); ++i)
{ {
const VPieceNode &node = nodes.at(i); const VPieceNode &node = nodes.at(i);
@ -1241,7 +1279,9 @@ QVector<QPointF> VPiecePath::NodesToPoints(const VContainer *data, const QVector
case (Tool::NodePoint): case (Tool::NodePoint):
{ {
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(node.GetId()); const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(node.GetId());
points.append(static_cast<QPointF>(*point)); VLayoutPoint layoutPoint(point->toQPointF());
layoutPoint.SetTurnPoint(node.IsTurnPoint());
points.append(layoutPoint);
} }
break; break;
case (Tool::NodeArc): case (Tool::NodeArc):
@ -1251,11 +1291,11 @@ QVector<QPointF> VPiecePath::NodesToPoints(const VContainer *data, const QVector
{ {
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId()); const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(node.GetId());
const VSAPoint begin = StartSegment(data, nodes, i);
const VSAPoint end = EndSegment(data, nodes, i);
const QPointF begin = StartSegment(data, nodes, i); QVector<QPointF> segment = curve->GetSegmentPoints(begin, end, node.GetReverse(), piece);
const QPointF end = EndSegment(data, nodes, i); AppendCurveSegment(points, segment, begin, end);
points << curve->GetSegmentPoints(begin, end, node.GetReverse(), piece);
} }
break; break;
default: default:

View File

@ -42,6 +42,7 @@ class QPainterPath;
class VPointF; class VPointF;
class VPieceNode; class VPieceNode;
class VInternalVariable; class VInternalVariable;
class VLayoutPoint;
class VPiecePath class VPiecePath
{ {
@ -89,7 +90,7 @@ public:
void SetLastToCuttingCountour(bool value); void SetLastToCuttingCountour(bool value);
bool IsLastToCuttingCountour() const; bool IsLastToCuttingCountour() const;
QVector<QPointF> PathPoints(const VContainer *data, QVector<VLayoutPoint> PathPoints(const VContainer *data,
const QVector<QPointF> &cuttingPath = QVector<QPointF>()) const; const QVector<QPointF> &cuttingPath = QVector<QPointF>()) const;
QVector<VPointF> PathNodePoints(const VContainer *data, bool showExcluded = true) const; QVector<VPointF> PathNodePoints(const VContainer *data, bool showExcluded = true) const;
QVector<QVector<QPointF> > PathCurvePoints(const VContainer *data) const; QVector<QVector<QPointF> > PathCurvePoints(const VContainer *data) const;
@ -138,8 +139,8 @@ public:
static QString NodeName(const QVector<VPieceNode> &nodes, int nodeIndex, const VContainer *data); static QString NodeName(const QVector<VPieceNode> &nodes, int nodeIndex, const VContainer *data);
static QVector<QPointF> NodesToPoints(const VContainer *data, const QVector<VPieceNode> &nodes, static QVector<VLayoutPoint> NodesToPoints(const VContainer *data, const QVector<VPieceNode> &nodes,
const QString &piece = QString()); const QString &piece = QString());
private: private:
QSharedDataPointer<VPiecePathData> d; QSharedDataPointer<VPiecePathData> d;

View File

@ -46,17 +46,14 @@
#include <QVector> #include <QVector>
#include <QtGlobal> #include <QtGlobal>
#include <QLineF> #include <QLineF>
#include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
#include "vsysexits.h"
#include "../vgeometry/vgobject.h" #include "../vgeometry/vgobject.h"
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vgeometry/vspline.h" #include "../vgeometry/vspline.h"
#include "../vgeometry/vsplinepath.h" #include "../vgeometry/vsplinepath.h"
#include "../vlayout/vabstractpiece.h" #include "../vlayout/vabstractpiece.h"
#include "../vlayout/vrawsapoint.h"
#include "../vpatterndb/vcontainer.h" #include "../vpatterndb/vcontainer.h"
#include "../vpatterndb/vpiece.h" #include "../vpatterndb/vpiece.h"
#include "../vpatterndb/vpiecenode.h" #include "../vpatterndb/vpiecenode.h"
@ -68,104 +65,6 @@ AbstractTest::AbstractTest(QObject *parent) :
{ {
} }
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::VectorFromJson(const QString &json, QVector<QPointF>& vector) const
{
QByteArray saveData;
PrepareDocument(json, saveData);
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
const QString vectorKey = QStringLiteral("vector");
const QString typeKey = QStringLiteral("type");
QJsonObject vectorObject = loadDoc.object();
TestRoot(vectorObject, vectorKey, json);
QJsonArray vectorArray = vectorObject[vectorKey].toArray();
for (int i = 0; i < vectorArray.size(); ++i)
{
QJsonObject pointObject = vectorArray[i].toObject();
QString type;
AbstractTest::ReadStringValue(pointObject, typeKey, type);
if (type != QLatin1String("QPointF"))
{
const QString error = QStringLiteral("Invalid json file '%1'. Unexpected class '%2'.")
.arg(json, pointObject[typeKey].toString());
QFAIL(qUtf8Printable(error));
}
QPointF point;
QPointFromJson(pointObject, point);
vector.append(point);
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::VectorFromJson(const QString &json, QVector<VSAPoint> &vector) const
{
QByteArray saveData;
PrepareDocument(json, saveData);
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
const QString vectorKey = QStringLiteral("vector");
QJsonObject vectorObject = loadDoc.object();
TestRoot(vectorObject, vectorKey, json);
QJsonArray vectorArray = vectorObject[vectorKey].toArray();
for (int i = 0; i < vectorArray.size(); ++i)
{
QJsonObject pointObject = vectorArray[i].toObject();
QString type;
AbstractTest::ReadStringValue(pointObject, QStringLiteral("type"), type);
if (type != QLatin1String("VSAPoint"))
{
const QString error = QStringLiteral("Invalid json file '%1'. Unexpected class '%2'.").arg(json, type);
QFAIL(qUtf8Printable(error));
}
VSAPoint point;
SAPointFromJson(pointObject, point);
vector.append(point);
}
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::VectorFromJson(const QString &json, QVector<VRawSAPoint> &vector) const
{
QByteArray saveData;
PrepareDocument(json, saveData);
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
const QString vectorKey = QStringLiteral("vector");
QJsonObject vectorObject = loadDoc.object();
TestRoot(vectorObject, vectorKey, json);
QJsonArray vectorArray = vectorObject[vectorKey].toArray();
for (int i = 0; i < vectorArray.size(); ++i)
{
QJsonObject pointObject = vectorArray[i].toObject();
QString type;
AbstractTest::ReadStringValue(pointObject, QStringLiteral("type"), type);
if (type != QLatin1String("VRawSAPoint"))
{
const QString error = QStringLiteral("Invalid json file '%1'. Unexpected class '%2'.").arg(json, type);
QFAIL(qUtf8Printable(error));
}
VRawSAPoint point;
RawSAPointFromJson(pointObject, point);
vector.append(point);
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::PieceFromJson(const QString &json, VPiece &piece, QSharedPointer<VContainer> &data) void AbstractTest::PieceFromJson(const QString &json, VPiece &piece, QSharedPointer<VContainer> &data)
{ {
@ -217,17 +116,22 @@ void AbstractTest::PassmarkDataFromJson(const QString &json, VPiecePassmarkData
QJsonObject passmarkData = dataObject[dataKey].toObject(); QJsonObject passmarkData = dataObject[dataKey].toObject();
VSAPoint previousSAPoint; try
SAPointFromJson(passmarkData[QStringLiteral("previousSAPoint")].toObject(), previousSAPoint); {
data.previousSAPoint = previousSAPoint; auto previousSAPoint = PointFromJson<VSAPoint>(passmarkData[QStringLiteral("previousSAPoint")].toObject());
data.previousSAPoint = previousSAPoint;
VSAPoint passmarkSAPoint; auto passmarkSAPoint = PointFromJson<VSAPoint>(passmarkData[QStringLiteral("passmarkSAPoint")].toObject());
SAPointFromJson(passmarkData[QStringLiteral("passmarkSAPoint")].toObject(), passmarkSAPoint); data.passmarkSAPoint = passmarkSAPoint;
data.passmarkSAPoint = passmarkSAPoint;
VSAPoint nextSAPoint; auto nextSAPoint = PointFromJson<VSAPoint>(passmarkData[QStringLiteral("nextSAPoint")].toObject());
SAPointFromJson(passmarkData[QStringLiteral("nextSAPoint")].toObject(), nextSAPoint); data.nextSAPoint = nextSAPoint;
data.nextSAPoint = nextSAPoint; }
catch (const VException &e)
{
const QString error = QStringLiteral("Invalid json file '%1'. %2").arg(json, e.ErrorMessage());
QFAIL(qUtf8Printable(error));
}
qreal saWidth = 0; qreal saWidth = 0;
AbstractTest::ReadDoubleValue(passmarkData, QStringLiteral("saWidth"), saWidth); AbstractTest::ReadDoubleValue(passmarkData, QStringLiteral("saWidth"), saWidth);
@ -287,28 +191,26 @@ void AbstractTest::PassmarkShapeFromJson(const QString &json, QVector<QLineF> &s
TestRoot(shapeObject, shapeKey, json); TestRoot(shapeObject, shapeKey, json);
QJsonArray vectorArray = shapeObject[shapeKey].toArray(); QJsonArray vectorArray = shapeObject[shapeKey].toArray();
for (int i = 0; i < vectorArray.size(); ++i) for (auto && item : vectorArray)
{ {
QJsonObject lineObject = vectorArray[i].toObject(); QJsonObject lineObject = item.toObject();
QString type; QString type;
AbstractTest::ReadStringValue(lineObject, typeKey, type); AbstractTest::ReadStringValue(lineObject, typeKey, type);
if (type != QLatin1String("QLineF")) if (type != typeid(QLineF).name())
{ {
const QString error = QStringLiteral("Invalid json file '%1'. Unexpected class '%2'.") const QString error = QStringLiteral("Invalid json file '%1'. Unexpected class '%2'.")
.arg(json, lineObject[typeKey].toString()); .arg(json, lineObject[typeKey].toString());
QFAIL(qUtf8Printable(error)); QFAIL(qUtf8Printable(error));
} }
QLineF line; shape.append(QLineFromJson(lineObject));
QLineFromJson(lineObject, line);
shape.append(line);
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const void AbstractTest::ComparePathsDistance(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const
{ {
// Begin comparison // Begin comparison
QCOMPARE(ekv.size(), ekvOrig.size());// First check if sizes equal QCOMPARE(ekv.size(), ekvOrig.size());// First check if sizes equal
@ -316,12 +218,12 @@ void AbstractTest::Comparison(const QVector<QPointF> &ekv, const QVector<QPointF
for (int i=0; i < ekv.size(); i++) for (int i=0; i < ekv.size(); i++)
{ {
Comparison(ekv.at(i), ekvOrig.at(i), testAccuracy); ComparePointsDistance(ekv.at(i), ekvOrig.at(i), testAccuracy);
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::Comparison(const QPointF &result, const QPointF &expected, qreal testAccuracy) const void AbstractTest::ComparePointsDistance(const QPointF &result, const QPointF &expected, qreal testAccuracy) const
{ {
const QString msg = QStringLiteral("Actual '%2;%3', Expected '%4;%5'. Distance between points %6 mm.") const QString msg = QStringLiteral("Actual '%2;%3', Expected '%4;%5'. Distance between points %6 mm.")
.arg(result.x()).arg(result.y()).arg(expected.x()).arg(expected.y()) .arg(result.x()).arg(result.y()).arg(expected.x()).arg(expected.y())
@ -332,7 +234,7 @@ void AbstractTest::Comparison(const QPointF &result, const QPointF &expected, qr
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::Comparison(const QVector<QLineF> &result, const QVector<QLineF> &expected) const void AbstractTest::CompareLinesDistance(const QVector<QLineF> &result, const QVector<QLineF> &expected) const
{ {
// Begin comparison // Begin comparison
QCOMPARE(result.size(), expected.size());// First check if sizes equal QCOMPARE(result.size(), expected.size());// First check if sizes equal
@ -525,7 +427,7 @@ bool AbstractTest::CopyRecursively(const QString &srcFilePath, const QString &tg
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::PrepareDocument(const QString &json, QByteArray &data) const void AbstractTest::PrepareDocument(const QString &json, QByteArray &data)
{ {
QFile loadFile(json); QFile loadFile(json);
if (not loadFile.open(QIODevice::ReadOnly)) if (not loadFile.open(QIODevice::ReadOnly))
@ -538,7 +440,7 @@ void AbstractTest::PrepareDocument(const QString &json, QByteArray &data) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::TestRoot(const QJsonObject &root, const QString &attribute, const QString &file) const void AbstractTest::TestRoot(const QJsonObject &root, const QString &attribute, const QString &file)
{ {
if (not root.contains(attribute)) if (not root.contains(attribute))
{ {
@ -549,7 +451,7 @@ void AbstractTest::TestRoot(const QJsonObject &root, const QString &attribute, c
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::ReadStringValue(const QJsonObject &itemObject, const QString &attribute, QString &value, void AbstractTest::ReadStringValue(const QJsonObject &itemObject, const QString &attribute, QString &value,
const QString &defaultValue) const const QString &defaultValue)
{ {
if (itemObject.contains(attribute)) if (itemObject.contains(attribute))
{ {
@ -580,7 +482,7 @@ void AbstractTest::ReadStringValue(const QJsonObject &itemObject, const QString
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::ReadBooleanValue(const QJsonObject &itemObject, const QString &attribute, bool &value, void AbstractTest::ReadBooleanValue(const QJsonObject &itemObject, const QString &attribute, bool &value,
const QString &defaultValue) const const QString &defaultValue)
{ {
if (itemObject.contains(attribute)) if (itemObject.contains(attribute))
{ {
@ -624,8 +526,7 @@ void AbstractTest::ReadPointValue(const QJsonObject &itemObject, const QString &
{ {
if (itemObject.contains(attribute)) if (itemObject.contains(attribute))
{ {
QJsonObject p1Object = itemObject[attribute].toObject(); value = PointFromJson<VPointF>(itemObject[attribute].toObject());
VPointFromJson(p1Object, value);
} }
else else
{ {
@ -706,22 +607,11 @@ void AbstractTest::ReadPieceNodeValue(const QJsonObject &itemObject, VPieceNode
node = VPieceNode(id, typeTool, reverse); node = VPieceNode(id, typeTool, reverse);
} }
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::QPointFromJson(const QJsonObject &itemObject, QPointF &point) const
{
qreal x = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("x"), x);
point.setX(x);
qreal y = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("y"), y);
point.setY(y);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template<typename T, typename std::enable_if<std::is_floating_point<T>::value>::type*> template<typename T, typename std::enable_if<std::is_floating_point<T>::value>::type*>
void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value, void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue) const const QString &defaultValue)
{ {
if (itemObject.contains(attribute)) if (itemObject.contains(attribute))
{ {
@ -760,7 +650,7 @@ void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template<typename T, typename std::enable_if<std::is_enum<T>::value>::type*> template<typename T, typename std::enable_if<std::is_enum<T>::value>::type*>
void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value, void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue) const const QString &defaultValue)
{ {
if (itemObject.contains(attribute)) if (itemObject.contains(attribute))
{ {
@ -799,7 +689,7 @@ void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template<typename T, typename std::enable_if<std::is_integral<T>::value>::type*> template<typename T, typename std::enable_if<std::is_integral<T>::value>::type*>
void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value, void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue) const const QString &defaultValue)
{ {
if (itemObject.contains(attribute)) if (itemObject.contains(attribute))
{ {
@ -836,81 +726,10 @@ void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void AbstractTest::VPointFromJson(const QJsonObject &itemObject, VPointF &point) auto AbstractTest::QLineFromJson(const QJsonObject &itemObject) -> QLineF
{ {
vidtype id = NULL_ID; return {PointFromJson<QPointF>(itemObject[QStringLiteral("p1")].toObject()),
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("id"), id); PointFromJson<QPointF>(itemObject[QStringLiteral("p2")].toObject())};
qreal mx = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("mx"), mx);
qreal my = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("my"), my);
QString name;
AbstractTest::ReadStringValue(itemObject, QStringLiteral("name"), name);
qreal x = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("x"), x);
qreal y = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("y"), y);
point = VPointF(x, y, name, mx, my);
point.setId(id);
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::QLineFromJson(const QJsonObject &itemObject, QLineF &line)
{
QPointF p1;
QPointFromJson(itemObject[QStringLiteral("p1")].toObject(), p1);
QPointF p2;
QPointFromJson(itemObject[QStringLiteral("p2")].toObject(), p2);
line = QLineF(p1, p2);
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::SAPointFromJson(const QJsonObject &itemObject, VSAPoint &point) const
{
qreal x = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("x"), x);
point.setX(x);
qreal y = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("y"), y);
point.setY(y);
qreal saBefore;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("saBefore"), saBefore, QStringLiteral("-1"));
point.SetSABefore(saBefore);
qreal saAfter;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("saAfter"), saAfter, QStringLiteral("-1"));
point.SetSAAfter(saAfter);
PieceNodeAngle angleType = PieceNodeAngle::ByLength;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("angle"), angleType,
QString::number(static_cast<int>(PieceNodeAngle::ByLength)));
point.SetAngleType(angleType);
}
//---------------------------------------------------------------------------------------------------------------------
void AbstractTest::RawSAPointFromJson(const QJsonObject &itemObject, VRawSAPoint &point) const
{
qreal x = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("x"), x);
point.setX(x);
qreal y = 0;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("y"), y);
point.setY(y);
bool loopPoint;
AbstractTest::ReadBooleanValue(itemObject, QStringLiteral("loopPoint"), loopPoint, QStringLiteral("0"));
point.SetLoopPoint(loopPoint);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -999,8 +818,7 @@ void AbstractTest::DBFromJson(const QJsonObject &dbObject, QSharedPointer<VConta
{ {
case GOType::Point: case GOType::Point:
{ {
VPointF point; VPointF point = PointFromJson<VPointF>(itemObject);
VPointFromJson(itemObject, point);
data->UpdateGObject(point.id(), new VPointF(point)); data->UpdateGObject(point.id(), new VPointF(point));
break; break;
} }

View File

@ -32,9 +32,17 @@
#include <QMetaObject> #include <QMetaObject>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <qtestcase.h>
#include "../vgeometry/vpointf.h"
#include "../vlayout/vsapoint.h"
#include "../vlayout/vrawsapoint.h"
#include "../ifc/exception/vexception.h"
template <class T> class QVector; template <class T> class QVector;
class VSAPoint;
#include <ciso646> #include <ciso646>
@ -69,9 +77,8 @@ class AbstractTest : public QObject
public: public:
explicit AbstractTest(QObject *parent = nullptr); explicit AbstractTest(QObject *parent = nullptr);
void VectorFromJson(const QString &json, QVector<QPointF>& vector) const; template <class T>
void VectorFromJson(const QString &json, QVector<VSAPoint>& vector) const; static auto VectorFromJson(const QString &json) -> QVector<T>;
void VectorFromJson(const QString &json, QVector<VRawSAPoint>& vector) const;
void PieceFromJson(const QString &json, VPiece &piece, QSharedPointer<VContainer> &data); void PieceFromJson(const QString &json, VPiece &piece, QSharedPointer<VContainer> &data);
@ -79,45 +86,50 @@ public:
void PassmarkShapeFromJson(const QString &json, QVector<QLineF> &shape); void PassmarkShapeFromJson(const QString &json, QVector<QLineF> &shape);
protected: protected:
void Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const; void ComparePathsDistance(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const;
void Comparison(const QPointF &result, const QPointF &expected, qreal testAccuracy) const; void ComparePointsDistance(const QPointF &result, const QPointF &expected, qreal testAccuracy) const;
void Comparison(const QVector<QLineF> &result, const QVector<QLineF> &expected) const; void CompareLinesDistance(const QVector<QLineF> &result, const QVector<QLineF> &expected) const;
QString ValentinaPath() const; auto ValentinaPath() const -> QString;
QString TapePath() const; auto TapePath() const -> QString;
QString TranslationsPath() const; auto TranslationsPath() const -> QString;
static int RunTimeout(int defMsecs); static auto RunTimeout(int defMsecs) -> int;
int Run(int exit, const QString &program, const QStringList &arguments, QString &error, int msecs = 120000); auto Run(int exit, const QString &program, const QStringList &arguments, QString &error, int msecs = 120000) -> int;
bool CopyRecursively(const QString &srcFilePath, const QString &tgtFilePath) const; auto CopyRecursively(const QString &srcFilePath, const QString &tgtFilePath) const -> bool;
void PrepareDocument(const QString &json, QByteArray &data) const; static void PrepareDocument(const QString &json, QByteArray &data);
void TestRoot(const QJsonObject &root, const QString &attribute, const QString &file) const; static void TestRoot(const QJsonObject &root, const QString &attribute, const QString &file);
template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr> template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value, static void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString()) const; const QString &defaultValue = QString());
template <typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr> template <typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value, static void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString()) const; const QString &defaultValue = QString());
template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value, static void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString()) const; const QString &defaultValue = QString());
void ReadStringValue(const QJsonObject &itemObject, const QString &attribute, QString &value, static void ReadStringValue(const QJsonObject &itemObject, const QString &attribute, QString &value,
const QString &defaultValue = QString()) const; const QString &defaultValue = QString());
void ReadBooleanValue(const QJsonObject &itemObject, const QString &attribute, bool &value, static void ReadBooleanValue(const QJsonObject &itemObject, const QString &attribute, bool &value,
const QString &defaultValue = QString()) const; const QString &defaultValue = QString());
void ReadPointValue(const QJsonObject &itemObject, const QString &attribute, VPointF &value); void ReadPointValue(const QJsonObject &itemObject, const QString &attribute, VPointF &value);
void ReadSplinePointValues(const QJsonObject &itemObject, const QString &attribute, QVector<VSplinePoint> &points); void ReadSplinePointValues(const QJsonObject &itemObject, const QString &attribute, QVector<VSplinePoint> &points);
void ReadSplinePointValue(const QJsonObject &itemObject, VSplinePoint &point); void ReadSplinePointValue(const QJsonObject &itemObject, VSplinePoint &point);
void ReadPieceNodeValue(const QJsonObject &itemObject, VPieceNode &node); void ReadPieceNodeValue(const QJsonObject &itemObject, VPieceNode &node);
void QPointFromJson(const QJsonObject &itemObject, QPointF &point) const; template <class T>
void VPointFromJson(const QJsonObject &itemObject, VPointF &point); static void CheckClassType(const QJsonObject &itemObject);
void QLineFromJson(const QJsonObject &itemObject, QLineF &line);
void SAPointFromJson(const QJsonObject &itemObject, VSAPoint &point) const; template <class T>
void RawSAPointFromJson(const QJsonObject &itemObject, VRawSAPoint &point) const; static auto ReadPointData(const QJsonObject &pointObject) -> T;
template <class T>
static auto PointFromJson(const QJsonObject &pointObject) -> T;
auto QLineFromJson(const QJsonObject &itemObject) -> QLineF;
void SplineFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data); void SplineFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data);
void SplinePathFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data); void SplinePathFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data);
@ -125,4 +137,168 @@ protected:
void MainPathFromJson(const QJsonObject &pieceObject, VPiece &piece); void MainPathFromJson(const QJsonObject &pieceObject, VPiece &piece);
}; };
//---------------------------------------------------------------------------------------------------------------------
template<class T>
inline auto AbstractTest::VectorFromJson(const QString &json) -> QVector<T>
{
QByteArray saveData;
PrepareDocument(json, saveData);
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
const QString vectorKey = QStringLiteral("vector");
QJsonObject vectorObject = loadDoc.object();
TestRoot(vectorObject, vectorKey, json);
QJsonArray vectorArray = vectorObject[vectorKey].toArray();
QVector<T> vector(vectorArray.size());
for (auto && item : vectorArray)
{
try
{
vector.append(PointFromJson<T>(item.toObject()));
}
catch (const VException &e)
{
throw VException(QStringLiteral("Invalid json file '%1'. %2").arg(json, e.ErrorMessage()));
}
}
return vector;
}
//---------------------------------------------------------------------------------------------------------------------
template<class T>
inline void AbstractTest::CheckClassType(const QJsonObject &itemObject)
{
const QString typeKey = QStringLiteral("type");
QString type;
AbstractTest::ReadStringValue(itemObject, typeKey, type);
if (type != typeid(T).name())
{
throw VException(QStringLiteral("Unexpected class '%2'.").arg(itemObject[typeKey].toString()));
}
}
//---------------------------------------------------------------------------------------------------------------------
template<class T>
inline auto AbstractTest::ReadPointData(const QJsonObject &pointObject) -> T
{
T point;
qreal x = 0;
AbstractTest::ReadDoubleValue(pointObject, QChar('x'), x);
point.setX(x);
qreal y = 0;
AbstractTest::ReadDoubleValue(pointObject, QChar('y'), y);
point.setY(y);
return point;
}
//---------------------------------------------------------------------------------------------------------------------
template<class T>
inline auto AbstractTest::PointFromJson(const QJsonObject &pointObject) -> T
{
CheckClassType<T>(pointObject);
return ReadPointData<T>(pointObject);
}
//---------------------------------------------------------------------------------------------------------------------
template<>
inline auto AbstractTest::PointFromJson(const QJsonObject &pointObject) -> VPointF
{
CheckClassType<VPointF>(pointObject);
vidtype id = NULL_ID;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("id"), id);
qreal mx = 0;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("mx"), mx);
qreal my = 0;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("my"), my);
QString name;
AbstractTest::ReadStringValue(pointObject, QStringLiteral("name"), name);
qreal x = 0;
AbstractTest::ReadDoubleValue(pointObject, QChar('x'), x);
qreal y = 0;
AbstractTest::ReadDoubleValue(pointObject, QChar('y'), y);
VPointF point(x, y, name, mx, my);
point.setId(id);
return point;
}
//---------------------------------------------------------------------------------------------------------------------
template<>
inline auto AbstractTest::ReadPointData(const QJsonObject &pointObject) -> VLayoutPoint
{
VLayoutPoint point(ReadPointData<QPointF>(pointObject));
bool turnPoint;
AbstractTest::ReadBooleanValue(pointObject, QStringLiteral("turnPoint"), turnPoint, QStringLiteral("0"));
point.SetTurnPoint(turnPoint);
bool curvePoint;
AbstractTest::ReadBooleanValue(pointObject, QStringLiteral("curvePoint"), curvePoint, QStringLiteral("0"));
point.SetCurvePoint(curvePoint);
return point;
}
//---------------------------------------------------------------------------------------------------------------------
template<>
inline auto AbstractTest::PointFromJson(const QJsonObject &pointObject) -> VLayoutPoint
{
CheckClassType<VLayoutPoint>(pointObject);
return ReadPointData<VLayoutPoint>(pointObject);
}
//---------------------------------------------------------------------------------------------------------------------
template<>
inline auto AbstractTest::PointFromJson(const QJsonObject &pointObject) -> VSAPoint
{
CheckClassType<VSAPoint>(pointObject);
VSAPoint point(ReadPointData<VLayoutPoint>(pointObject));
qreal saBefore;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("saBefore"), saBefore, QStringLiteral("-1"));
point.SetSABefore(saBefore);
qreal saAfter;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("saAfter"), saAfter, QStringLiteral("-1"));
point.SetSAAfter(saAfter);
PieceNodeAngle angleType = PieceNodeAngle::ByLength;
AbstractTest::ReadDoubleValue(pointObject, QStringLiteral("angle"), angleType,
QString::number(static_cast<int>(PieceNodeAngle::ByLength)));
point.SetAngleType(angleType);
return point;
}
//---------------------------------------------------------------------------------------------------------------------
template<>
inline auto AbstractTest::PointFromJson(const QJsonObject &pointObject) -> VRawSAPoint
{
CheckClassType<VRawSAPoint>(pointObject);
VRawSAPoint point(ReadPointData<VLayoutPoint>(pointObject));
bool loopPoint;
AbstractTest::ReadBooleanValue(pointObject, QStringLiteral("loopPoint"), loopPoint, QStringLiteral("0"));
point.SetLoopPoint(loopPoint);
return point;
}
#endif // ABSTRACTTEST_H #endif // ABSTRACTTEST_H

View File

@ -2750,7 +2750,7 @@ void DialogSeamAllowance::ValidObjects(bool value)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool DialogSeamAllowance::MainPathIsClockwise() const bool DialogSeamAllowance::MainPathIsClockwise() const
{ {
const QVector<QPointF> points = CreatePiece().MainPathPoints(data); const QVector<QPointF> points = CastTo<QPointF>(CreatePiece().MainPathPoints(data));
if(points.count() < 3) if(points.count() < 3)
{ {

View File

@ -1391,7 +1391,7 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
this->getData()); this->getData());
QFuture<QPainterPath > futurePassmarks = QtConcurrent::run(detail, &VPiece::PassmarksPath, this->getData()); QFuture<QPainterPath > futurePassmarks = QtConcurrent::run(detail, &VPiece::PassmarksPath, this->getData());
QFuture<QVector<QPointF> > futureSeamAllowance; QFuture<QVector<VLayoutPoint> > futureSeamAllowance;
QFuture<bool> futureSeamAllowanceValid; QFuture<bool> futureSeamAllowanceValid;
if (detail.IsSeamAllowance()) if (detail.IsSeamAllowance())
@ -2071,8 +2071,9 @@ auto VToolSeamAllowance::IsGrainlinePositionValid() const -> bool
{ {
QLineF grainLine = m_grainLine->Grainline(); QLineF grainLine = m_grainLine->Grainline();
const VPiece detail = VAbstractTool::data.GetPiece(m_id); const VPiece detail = VAbstractTool::data.GetPiece(m_id);
const QVector<QPointF> contourPoints = detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() ? const QVector<QPointF> contourPoints =
detail.SeamAllowancePoints(getData()) : detail.MainPathPoints(getData()); detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() ?
CastTo<QPointF>(detail.SeamAllowancePoints(getData())) : CastTo<QPointF>(detail.MainPathPoints(getData()));
QVector<QPointF> points = VAbstractCurve::CurveIntersectLine(contourPoints, grainLine); QVector<QPointF> points = VAbstractCurve::CurveIntersectLine(contourPoints, grainLine);
if (not points.isEmpty()) if (not points.isEmpty())

View File

@ -52,7 +52,7 @@ void VisToolPiece::RefreshGeometry()
if (GetMode() == Mode::Creation) if (GetMode() == Mode::Creation)
{ {
m_cachedCurvesPath = m_piece.CurvesPainterPath(GetData()); m_cachedCurvesPath = m_piece.CurvesPainterPath(GetData());
m_cachedMainPathPoints = m_piece.MainPathPoints(GetData()); m_cachedMainPathPoints = CastTo<QPointF>(m_piece.MainPathPoints(GetData()));
m_cachedMainPath = VPiece::MainPathPath(m_cachedMainPathPoints); m_cachedMainPath = VPiece::MainPathPath(m_cachedMainPathPoints);
} }
else else

View File

@ -31,6 +31,7 @@
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vwidgets/scalesceneitems.h" #include "../vwidgets/scalesceneitems.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vlayout/vlayoutpoint.h"
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
@ -63,7 +64,7 @@ void VisToolPiecePath::RefreshGeometry()
if (GetMode() == Mode::Creation) if (GetMode() == Mode::Creation)
{ {
const QVector<QPointF> points = m_path.PathPoints(GetData()); const QVector<VLayoutPoint> points = m_path.PathPoints(GetData());
if (not points.empty()) if (not points.empty())
{ {
DrawLine(m_line, QLineF(ConstLast(points), ScenePos()), Color(VColor::SupportColor), Qt::DashLine); DrawLine(m_line, QLineF(ConstLast(points), ScenePos()), Color(VColor::SupportColor), Qt::DashLine);

View File

@ -170,7 +170,7 @@ void TST_FindPoint::TestPointOfIntersectionCurves()
static_cast<VCrossCurvesPoint>(vCross), static_cast<VCrossCurvesPoint>(vCross),
static_cast<HCrossCurvesPoint>(hCross), &result); static_cast<HCrossCurvesPoint>(hCross), &result);
Comparison(result, expect, accuracyPointOnLine); ComparePointsDistance(result, expect, accuracyPointOnLine);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -211,8 +211,8 @@ void TST_FindPoint::TestTrueDarts()
VToolTrueDarts::FindPoint(baseLineP1, baseLineP2, dartP1, dartP2, dartP3, p1, p2); VToolTrueDarts::FindPoint(baseLineP1, baseLineP2, dartP1, dartP2, dartP3, p1, p2);
Comparison(p1, expectP1, accuracyPointOnLine); ComparePointsDistance(p1, expectP1, accuracyPointOnLine);
Comparison(p2, expectP2, accuracyPointOnLine); ComparePointsDistance(p2, expectP2, accuracyPointOnLine);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -239,7 +239,7 @@ void TST_FindPoint::TestLineIntersectAxis()
QPointF resultPoint; QPointF resultPoint;
VToolLineIntersectAxis::FindPoint(axis, line, &resultPoint); VToolLineIntersectAxis::FindPoint(axis, line, &resultPoint);
Comparison(resultPoint, point, accuracyPointOnLine); ComparePointsDistance(resultPoint, point, accuracyPointOnLine);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -272,7 +272,7 @@ void TST_FindPoint::TestTriangle()
QPointF resultPoint; QPointF resultPoint;
VToolTriangle::FindPoint(axisP1, axisP2, firstPoint, secondPoint, &resultPoint); VToolTriangle::FindPoint(axisP1, axisP2, firstPoint, secondPoint, &resultPoint);
Comparison(point, resultPoint, accuracyPointOnLine); ComparePointsDistance(point, resultPoint, accuracyPointOnLine);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -312,7 +312,7 @@ void TST_FindPoint::TestShoulderPoint()
QPointF resultPoint = VToolShoulderPoint::FindPoint(p1, p2, pShoulder, length); QPointF resultPoint = VToolShoulderPoint::FindPoint(p1, p2, pShoulder, length);
Comparison(point, resultPoint, accuracyPointOnLine); ComparePointsDistance(point, resultPoint, accuracyPointOnLine);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -745,5 +745,5 @@ void TST_FindPoint::TestCurveIntersectAxis()
QPointF resultPoint; QPointF resultPoint;
VToolCurveIntersectAxis::FindPoint(basePoint, angle, curvePoints, &resultPoint); VToolCurveIntersectAxis::FindPoint(basePoint, angle, curvePoints, &resultPoint);
Comparison(resultPoint, result, accuracyPointOnLine); ComparePointsDistance(resultPoint, result, accuracyPointOnLine);
} }

View File

@ -180,12 +180,8 @@ void TST_VAbstractCurve::CurveIntersectLine_data()
auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, QLineF line) auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, QLineF line)
{ {
QVector<QPointF> points; QVector<QPointF> points = AbstractTest::VectorFromJson<QPointF>(input);
AbstractTest::VectorFromJson(input, points); QVector<QPointF> intersections = AbstractTest::VectorFromJson<QPointF>(output);
QVector<QPointF> intersections;
AbstractTest::VectorFromJson(output, intersections);
QTest::newRow(title) << points << intersections << line; QTest::newRow(title) << points << intersections << line;
}; };

View File

@ -49,12 +49,8 @@ void TST_VAbstractPiece::EquidistantRemoveLoop_data()
auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, qreal width) auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, qreal width)
{ {
QVector<VSAPoint> inputPoints; QVector<VSAPoint> inputPoints = AbstractTest::VectorFromJson<VSAPoint>(input);
AbstractTest::VectorFromJson(input, inputPoints); QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QTest::newRow(title) << inputPoints << width << outputPoints; QTest::newRow(title) << inputPoints << width << outputPoints;
}; };
@ -312,10 +308,10 @@ void TST_VAbstractPiece::EquidistantRemoveLoop() const
QFETCH(qreal, width); QFETCH(qreal, width);
QFETCH(QVector<QPointF>, ekvOrig); QFETCH(QVector<QPointF>, ekvOrig);
const QVector<QPointF> ekv = VAbstractPiece::Equidistant(points, width, QString()); const QVector<QPointF> ekv = CastTo<QPointF>(VAbstractPiece::Equidistant(points, width, QString()));
// Begin comparison // Begin comparison
Comparison(ekv, ekvOrig); ComparePathsDistance(ekv, ekvOrig);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -327,12 +323,8 @@ void TST_VAbstractPiece::LayoutAllowanceRemoveLoop_data()
auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, qreal width) auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, qreal width)
{ {
QVector<VSAPoint> inputPoints; QVector<VSAPoint> inputPoints = AbstractTest::VectorFromJson<VSAPoint>(input);
AbstractTest::VectorFromJson(input, inputPoints); QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QTest::newRow(title) << inputPoints << width << outputPoints; QTest::newRow(title) << inputPoints << width << outputPoints;
}; };
@ -368,10 +360,10 @@ void TST_VAbstractPiece::LayoutAllowanceRemoveLoop() const
QFETCH(qreal, width); QFETCH(qreal, width);
QFETCH(QVector<QPointF>, ekvOrig); QFETCH(QVector<QPointF>, ekvOrig);
const QVector<QPointF> ekv = VAbstractPiece::Equidistant(points, width, QString()); const QVector<QPointF> ekv = CastTo<QPointF>(VAbstractPiece::Equidistant(points, width, QString()));
// Begin comparison // Begin comparison
Comparison(ekv, ekvOrig); ComparePathsDistance(ekv, ekvOrig);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -393,12 +385,8 @@ void TST_VAbstractPiece::RawPathRemoveLoop_data() const
auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output) auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output)
{ {
QVector<VRawSAPoint> inputPoints; QVector<VRawSAPoint> inputPoints = AbstractTest::VectorFromJson<VRawSAPoint>(input);
AbstractTest::VectorFromJson(input, inputPoints); QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QTest::newRow(title) << inputPoints << outputPoints; QTest::newRow(title) << inputPoints << outputPoints;
}; };
@ -414,8 +402,8 @@ void TST_VAbstractPiece::RawPathRemoveLoop() const
QFETCH(QVector<VRawSAPoint>, path); QFETCH(QVector<VRawSAPoint>, path);
QFETCH(QVector<QPointF>, expect); QFETCH(QVector<QPointF>, expect);
QVector<QPointF> res = VAbstractPiece::CheckLoops(path); QVector<QPointF> res = CastTo<QPointF>(VAbstractPiece::CheckLoops(path));
Comparison(res, expect); ComparePathsDistance(res, expect);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -688,7 +676,7 @@ void TST_VAbstractPiece::PathRemoveLoop() const
QFETCH(QVector<QPointF>, expect); QFETCH(QVector<QPointF>, expect);
QVector<QPointF> res = VAbstractPiece::CheckLoops(path); QVector<QPointF> res = VAbstractPiece::CheckLoops(path);
Comparison(res, expect); ComparePathsDistance(res, expect);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -874,7 +862,7 @@ void TST_VAbstractPiece::PathLoopsCase() const
QFETCH(QVector<QPointF>, expect); QFETCH(QVector<QPointF>, expect);
const QVector<QPointF> res = VAbstractPiece::CheckLoops(path); const QVector<QPointF> res = VAbstractPiece::CheckLoops(path);
Comparison(res, expect); ComparePathsDistance(res, expect);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -886,12 +874,8 @@ void TST_VAbstractPiece::BrokenDetailEquidistant_data()
auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, qreal width) auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, qreal width)
{ {
QVector<VSAPoint> inputPoints; QVector<VSAPoint> inputPoints = AbstractTest::VectorFromJson<VSAPoint>(input);
AbstractTest::VectorFromJson(input, inputPoints); QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QTest::newRow(title) << inputPoints << width << outputPoints; QTest::newRow(title) << inputPoints << width << outputPoints;
}; };
@ -978,10 +962,10 @@ void TST_VAbstractPiece::BrokenDetailEquidistant() const
QFETCH(qreal, width); QFETCH(qreal, width);
QFETCH(QVector<QPointF>, ekvOrig); QFETCH(QVector<QPointF>, ekvOrig);
const QVector<QPointF> ekv = VAbstractPiece::Equidistant(points, width, QString());// Take result const QVector<QPointF> ekv = CastTo<QPointF>(VAbstractPiece::Equidistant(points, width, QString()));// Take result
// Begin comparison // Begin comparison
Comparison(ekv, ekvOrig); ComparePathsDistance(ekv, ekvOrig);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -993,12 +977,8 @@ void TST_VAbstractPiece::EquidistantAngleType_data()
auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, qreal width) auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output, qreal width)
{ {
QVector<VSAPoint> inputPoints; QVector<VSAPoint> inputPoints = AbstractTest::VectorFromJson<VSAPoint>(input);
AbstractTest::VectorFromJson(input, inputPoints); QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QTest::newRow(title) << inputPoints << width << outputPoints; QTest::newRow(title) << inputPoints << width << outputPoints;
}; };
@ -1094,10 +1074,10 @@ void TST_VAbstractPiece::EquidistantAngleType() const
QFETCH(qreal, width); QFETCH(qreal, width);
QFETCH(QVector<QPointF>, ekvOrig); QFETCH(QVector<QPointF>, ekvOrig);
const QVector<QPointF> ekv = VAbstractPiece::Equidistant(points, width, QString());// Take result const QVector<QPointF> ekv = CastTo<QPointF>(VAbstractPiece::Equidistant(points, width, QString()));// Take result
// Begin comparison // Begin comparison
Comparison(ekv, ekvOrig); ComparePathsDistance(ekv, ekvOrig);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1134,7 +1114,7 @@ void TST_VAbstractPiece::CorrectEquidistantPoints() const
const QVector<QPointF> res = VAbstractPiece::CorrectEquidistantPoints(points, removeFirstAndLast); const QVector<QPointF> res = VAbstractPiece::CorrectEquidistantPoints(points, removeFirstAndLast);
// Begin comparison // Begin comparison
Comparison(res, expect); ComparePathsDistance(res, expect);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1145,12 +1125,8 @@ void TST_VAbstractPiece::TestCorrectEquidistantPoints_data()
auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output) auto ASSERT_TEST_CASE = [this](const char *title, const QString &input, const QString &output)
{ {
QVector<QPointF> inputPoints; QVector<QPointF> inputPoints = AbstractTest::VectorFromJson<QPointF>(input);
AbstractTest::VectorFromJson(input, inputPoints); QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QTest::newRow(title) << inputPoints << outputPoints; QTest::newRow(title) << inputPoints << outputPoints;
}; };
@ -1172,7 +1148,7 @@ void TST_VAbstractPiece::TestCorrectEquidistantPoints() const
QFETCH(QVector<QPointF>, expect); QFETCH(QVector<QPointF>, expect);
QVector<QPointF> after = VAbstractPiece::CorrectEquidistantPoints(before); QVector<QPointF> after = VAbstractPiece::CorrectEquidistantPoints(before);
Comparison(after, expect); ComparePathsDistance(after, expect);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1289,7 +1265,7 @@ void TST_VAbstractPiece::PossibleInfiniteClearLoops() const
QFETCH(QVector<QPointF>, expect); QFETCH(QVector<QPointF>, expect);
QVector<QPointF> res = VAbstractPiece::CheckLoops(path); QVector<QPointF> res = VAbstractPiece::CheckLoops(path);
Comparison(res, expect); ComparePathsDistance(res, expect);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1301,12 +1277,8 @@ void TST_VAbstractPiece::IsAllowanceValid_data() const
auto ASSERT_TEST_CASE = [this](const char *title, const QString &base, const QString &allowance, bool valid) auto ASSERT_TEST_CASE = [this](const char *title, const QString &base, const QString &allowance, bool valid)
{ {
QVector<QPointF> basePoints; QVector<QPointF> basePoints = AbstractTest::VectorFromJson<QPointF>(base);
AbstractTest::VectorFromJson(base, basePoints); QVector<QPointF> allowancePoints = AbstractTest::VectorFromJson<QPointF>(allowance);
QVector<QPointF> allowancePoints;
AbstractTest::VectorFromJson(allowance, allowancePoints);
QTest::newRow(title) << basePoints << allowancePoints << valid ; QTest::newRow(title) << basePoints << allowancePoints << valid ;
}; };

View File

@ -458,7 +458,7 @@ void TST_VArc::TestCurveIntersectAxis()
const bool found = VAbstractCurve::CurveIntersectAxis(basePoint, angle, curvePoints, &intersectionPoint); const bool found = VAbstractCurve::CurveIntersectAxis(basePoint, angle, curvePoints, &intersectionPoint);
QCOMPARE(found, result); QCOMPARE(found, result);
Comparison(intersectionPoint, crosPoint, accuracyPointOnLine); ComparePointsDistance(intersectionPoint, crosPoint, accuracyPointOnLine);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -466,6 +466,6 @@ void TST_VArc::EmptyArc()
{ {
VArc empty; VArc empty;
Comparison(empty.GetPoints(), {QPointF()}); ComparePathsDistance(empty.GetPoints(), {QPointF()});
QCOMPARE(empty.GetLength(), 0.); QCOMPARE(empty.GetLength(), 0.);
} }

View File

@ -477,8 +477,8 @@ void TST_VEllipticalArc::TestGetPoints5()
if (points.size() > 2 && qFuzzyIsNull(rotationAngle)) if (points.size() > 2 && qFuzzyIsNull(rotationAngle))
{ {
const qreal testAccuracy = ToPixel(1.5, Unit::Mm); const qreal testAccuracy = ToPixel(1.5, Unit::Mm);
Comparison(arc.GetP1(), ConstFirst(points), testAccuracy); ComparePointsDistance(arc.GetP1(), ConstFirst(points), testAccuracy);
Comparison(arc.GetP2(), ConstLast(points), testAccuracy); ComparePointsDistance(arc.GetP2(), ConstLast(points), testAccuracy);
const qreal eps = 0.15; const qreal eps = 0.15;

View File

@ -57,10 +57,10 @@ void TST_VLayoutDetail::Case1() const
// https://bitbucket.org/dismine/valentina/issue/304/layout-appears-different-than-my-pattern // https://bitbucket.org/dismine/valentina/issue/304/layout-appears-different-than-my-pattern
VLayoutPiece det = VLayoutPiece(); VLayoutPiece det = VLayoutPiece();
det.SetCountourPoints(InputPointsCase1()); det.SetCountourPoints(CastTo<VLayoutPoint>(InputPointsCase1()));
// Begin comparison // Begin comparison
Comparison(det.GetMappedContourPoints(), OutputPointsCase1()); ComparePathsDistance(CastTo<QPointF>(det.GetMappedContourPoints()), OutputPointsCase1());
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -119,10 +119,10 @@ QVector<QPointF> TST_VLayoutDetail::OutputPointsCase1() const //-V524
void TST_VLayoutDetail::Case2() const void TST_VLayoutDetail::Case2() const
{ {
VLayoutPiece det = VLayoutPiece(); VLayoutPiece det = VLayoutPiece();
det.SetCountourPoints(InputPointsCase2()); det.SetCountourPoints(CastTo<VLayoutPoint>(InputPointsCase2()));
// Begin comparison // Begin comparison
Comparison(det.GetMappedContourPoints(), OutputPointsCase2()); ComparePathsDistance(CastTo<QPointF>(det.GetMappedContourPoints()), OutputPointsCase2());
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -160,10 +160,10 @@ QVector<QPointF> TST_VLayoutDetail::OutputPointsCase2() const
void TST_VLayoutDetail::Case3() const void TST_VLayoutDetail::Case3() const
{ {
VLayoutPiece det = VLayoutPiece(); VLayoutPiece det = VLayoutPiece();
det.SetCountourPoints(InputPointsCase3()); det.SetCountourPoints(CastTo<VLayoutPoint>(InputPointsCase3()));
// Begin comparison // Begin comparison
Comparison(det.GetMappedContourPoints(), OutputPointsCase3()); ComparePathsDistance(CastTo<QPointF>(det.GetMappedContourPoints()), OutputPointsCase3());
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -53,13 +53,11 @@ void TST_VPiece::Issue620()
VPiece detail; VPiece detail;
AbstractTest::PieceFromJson(QStringLiteral("://Issue_620/input.json"), detail, data); AbstractTest::PieceFromJson(QStringLiteral("://Issue_620/input.json"), detail, data);
const QVector<QPointF> pointsEkv = detail.MainPathPoints(data.data()); const QVector<QPointF> pointsEkv = CastTo<QPointF>(detail.MainPathPoints(data.data()));
QVector<QPointF> origPoints = AbstractTest::VectorFromJson<QPointF>(QStringLiteral("://Issue_620/output.json"));
QVector<QPointF> origPoints;
AbstractTest::VectorFromJson(QStringLiteral("://Issue_620/output.json"), origPoints);
// Begin comparison // Begin comparison
Comparison(pointsEkv, origPoints); ComparePathsDistance(pointsEkv, origPoints);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -78,8 +76,7 @@ void TST_VPiece::TestSAPassmark_data()
VPiecePassmarkData inputPassmarkData; VPiecePassmarkData inputPassmarkData;
AbstractTest::PassmarkDataFromJson(passmarkData, inputPassmarkData); AbstractTest::PassmarkDataFromJson(passmarkData, inputPassmarkData);
QVector<QPointF> inputSeamAllowance; QVector<QPointF> inputSeamAllowance = AbstractTest::VectorFromJson<QPointF>(seamAllowance);
AbstractTest::VectorFromJson(seamAllowance, inputSeamAllowance);
QVector<QLineF> inputOutputShape; QVector<QLineF> inputOutputShape;
AbstractTest::PassmarkShapeFromJson(shape, inputOutputShape); AbstractTest::PassmarkShapeFromJson(shape, inputOutputShape);
@ -105,5 +102,5 @@ void TST_VPiece::TestSAPassmark()
VPassmark passmark(passmarkData); VPassmark passmark(passmarkData);
Comparison(passmark.SAPassmark(seamAllowance, PassmarkSide::All), expectedResult); CompareLinesDistance(passmark.SAPassmark(seamAllowance, PassmarkSide::All), expectedResult);
} }

View File

@ -162,7 +162,7 @@ void TST_VSpline::GetSegmentPoints()
origPoints.append(QPointF(681.3372913240995, 1815.7969526662778)); origPoints.append(QPointF(681.3372913240995, 1815.7969526662778));
// Begin comparison // Begin comparison
Comparison(points, origPoints); ComparePathsDistance(points, origPoints);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -251,7 +251,7 @@ void TST_VSpline::GetSegmentPoints_issue412()
origPoints.append(QPointF(758.4176810783842, 206.13572832247544)); origPoints.append(QPointF(758.4176810783842, 206.13572832247544));
// Begin comparison // Begin comparison
Comparison(points, origPoints); ComparePathsDistance(points, origPoints);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -370,7 +370,7 @@ void TST_VSpline::GetSegmentPoints_TestPuzzle()
origPoints.append(QPointF(957.69883966, 943.844812978)); origPoints.append(QPointF(957.69883966, 943.844812978));
// Begin comparison // Begin comparison
Comparison(points, origPoints); ComparePathsDistance(points, origPoints);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -525,7 +525,7 @@ void TST_VSpline::GetSegmentPoints_NullSegment()
origPoints.append(QPointF(146.3718263928647, 6.419281580065625)); origPoints.append(QPointF(146.3718263928647, 6.419281580065625));
// Begin comparison // Begin comparison
Comparison(points, origPoints); ComparePathsDistance(points, origPoints);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -627,7 +627,7 @@ void TST_VSpline::GetSegmentPoints_RotateTool()
origPoints.append(QPointF(46.623829088412336, 167.78988631718659)); origPoints.append(QPointF(46.623829088412336, 167.78988631718659));
// Begin comparison // Begin comparison
Comparison(points, origPoints); ComparePathsDistance(points, origPoints);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -687,7 +687,7 @@ void TST_VSpline::GetSegmentPoints_issue767()
origPoints.append(QPointF(4200.083592082314, 2559.5684873884893)); origPoints.append(QPointF(4200.083592082314, 2559.5684873884893));
// Begin comparison // Begin comparison
Comparison(res, origPoints); ComparePathsDistance(res, origPoints);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -928,5 +928,5 @@ void TST_VSpline::CompareSplines(const VSpline &spl1, const VSpline &spl2) const
QCOMPARE(spl1.GetKcurve(), spl2.GetKcurve()); QCOMPARE(spl1.GetKcurve(), spl2.GetKcurve());
// Compare points // Compare points
Comparison(spl1.GetPoints(), spl2.GetPoints()); ComparePathsDistance(spl1.GetPoints(), spl2.GetPoints());
} }