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

View file

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

View file

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

View file

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

View file

@ -39,6 +39,7 @@
#include "../ifc/exception/vexceptionconversionerror.h"
#include "../vpatterndb/floatItemData/floatitemdef.h"
#include "../vgeometry/vgeometrydef.h"
#include "../vgeometry/vlayoutplacelabel.h"
#include "../layout/vplayout.h"
#include "../layout/vppiece.h"
@ -169,20 +170,6 @@ auto StringToRect(const QString &string) -> QRectF
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
//---------------------------------------------------------------------------------------------------------------------
@ -499,7 +486,7 @@ void VPLayoutFileReader::ReadPiece(const VPPiecePtr &piece)
switch (tags.indexOf(name().toString()))
{
case 0: // seam line
piece->SetCountourPoints(StringToPath(readElementText()));
ReadSeamLine(piece);
break;
case 1: // seam allowance
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)
{
@ -537,18 +568,15 @@ void VPLayoutFileReader::ReadSeamAllowance(const VPPiecePtr &piece)
piece->SetSeamAllowance(enabled);
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()));
}
piece->SetSeamAllowancePoints(path);
throw VException(tr("Error in line %1. Seam allowance is empty.").arg(lineNumber()));
}
piece->SetSeamAllowancePoints(path);
}
}
@ -658,7 +686,7 @@ auto VPLayoutFileReader::ReadInternalPath() -> VLayoutPiecePath
path.SetCutPath(ReadAttributeBool(attribs, ML::AttrCut, falseStr));
path.SetPenStyle(LineStyleToPenStyle(ReadAttributeString(attribs, ML::AttrPenStyle, TypeLineLine)));
QVector<QPointF> shape = StringToPath(readElementText());
QVector<VLayoutPoint> shape = ReadLayoutPoints();
if (shape.isEmpty())
{
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();
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.center = StringToPoint(ReadAttributeEmptyString(attribs, ML::AttrCenter));
marker.box = 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;
marker.SetType(static_cast<PlaceLabelType>(ReadAttributeUInt(attribs, ML::AttrType, QChar('0'))));
marker.SetCenter(StringToPoint(ReadAttributeEmptyString(attribs, ML::AttrCenter)));
marker.SetBox(StringToRect(ReadAttributeEmptyString(attribs, ML::AttrBox)));
// cppcheck-suppress unknownMacro
QT_WARNING_POP

View file

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

View file

@ -35,6 +35,7 @@
#include "../vmisc/projectversion.h"
#include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vtextmanager.h"
#include "../vgeometry/vlayoutplacelabel.h"
namespace
{
@ -93,18 +94,6 @@ auto RectToString(const QRectF &r) -> QString
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
{
@ -284,7 +273,11 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
[](qreal z) noexcept {return VFuzzyComparePossibleNulls(z, 1.0);});
writeStartElement(ML::TagSeamLine);
writeCharacters(PathToString(piece->GetContourPoints()));
QVector<VLayoutPoint> contourPoints = piece->GetContourPoints();
for (auto &point : contourPoints)
{
WriteLayoutPoint(point);
}
writeEndElement();
writeStartElement(ML::TagSeamAllowance);
@ -294,7 +287,11 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
[](bool builtin) noexcept {return not builtin;});
if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn())
{
writeCharacters(PathToString(piece->GetSeamAllowancePoints()));
QVector<VLayoutPoint> seamAllowancePoints = piece->GetSeamAllowancePoints();
for (auto &point : seamAllowancePoints)
{
WriteLayoutPoint(point);
}
}
writeEndElement();
@ -329,7 +326,13 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
writeStartElement(ML::TagInternalPath);
SetAttribute(ML::AttrCut, path.IsCutPath());
SetAttribute(ML::AttrPenStyle, PenStyleToLineStyle(path.PenStyle()));
writeCharacters(PathToString(path.Points()));
QVector<VLayoutPoint> points = path.Points();
for (auto &point : points)
{
WriteLayoutPoint(point);
}
writeEndElement();
}
writeEndElement();
@ -339,12 +342,10 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
for (const auto& label : placelabels)
{
writeStartElement(ML::TagMarker);
SetAttribute(ML::AttrTransform, TransformToString(label.rotationMatrix));
SetAttribute(ML::AttrType, static_cast<int>(label.type));
SetAttribute(ML::AttrCenter, PointToString(label.center));
SetAttribute(ML::AttrBox, RectToString(label.box));
writeCharacters(MarkerShapeToString(label.shape));
SetAttribute(ML::AttrTransform, TransformToString(label.RotationMatrix()));
SetAttribute(ML::AttrType, static_cast<int>(label.Type()));
SetAttribute(ML::AttrCenter, PointToString(label.Center()));
SetAttribute(ML::AttrBox, RectToString(label.Box()));
writeEndElement();
}
writeEndElement();
@ -425,3 +426,14 @@ void VPLayoutFileWriter::WriteSize(QSizeF size)
SetAttribute(ML::AttrLength, length);
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 QMarginsF;
class VTextManager;
class VLayoutPoint;
class VPLayoutFileWriter : public QXmlStreamWriter
{
@ -68,6 +69,7 @@ private:
void WritePiece(const VPPiecePtr &piece);
void WriteLabel(const QVector<QPointF> &labelShape, const VTextManager &tm, const QString &tagName);
void WriteLabelLines(const VTextManager &tm);
auto WriteLayoutPoint(const VLayoutPoint &point) -> void;
void WriteMargins(const QMarginsF &margins, bool ignore);
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 TagScale = QStringLiteral("scale"); // 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 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 AttrTileNumber = QStringLiteral("tileNumber"); // 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 atRearStr = QStringLiteral("atRear"); // NOLINT(cert-err58-cpp)

View file

@ -65,6 +65,7 @@ extern const QString TagLines;
extern const QString TagLine;
extern const QString TagScale;
extern const QString TagWatermark;
extern const QString TagPoint;
extern const QString AttrWarningSuperposition;
extern const QString AttrWarningOutOfBound;
@ -113,6 +114,10 @@ extern const QString AttrShowPreview;
extern const QString AttrPrintScheme;
extern const QString AttrTileNumber;
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 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 "../exception/vexception.h"
#include "ifcdef.h"
#include "../vlayout/vlayoutpoint.h"
/*
* Version rules:
@ -38,12 +39,61 @@
*/
const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0");
const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.2");
const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.2.xsd");
const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.3");
const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.3.xsd");
//VLayoutConverter::LayoutMinVer; // <== 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)
: 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, 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))
@ -108,10 +159,11 @@ void VLayoutConverter::ApplyPatches()
{
case (FormatVersion(0, 1, 0)):
case (FormatVersion(0, 1, 1)):
ToV0_1_2();
ValidateXML(XSDSchema(FormatVersion(0, 1, 2)));
Q_FALLTHROUGH();
case (FormatVersion(0, 1, 2)):
ToV0_1_3();
ValidateXML(XSDSchema(FormatVersion(0, 1, 3)));
Q_FALLTHROUGH();
case (FormatVersion(0, 1, 3)):
break;
default:
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
Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 2),
// 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.");
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();
}

View file

@ -44,7 +44,7 @@ public:
static const QString LayoutMaxVerStr;
static const QString CurrentSchema;
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:
void SetVersion(const QString &version) override;
@ -61,7 +61,11 @@ protected:
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:
Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT

View file

@ -53,7 +53,9 @@
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "dxiface.h"
#include "../vlayout/vlayoutpiece.h"
#include "../vlayout/vlayoutpoint.h"
#include "../vgeometry/vgeometrydef.h"
#include "../vgeometry/vlayoutplacelabel.h"
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, layer1, (UTF8STRING("1"))) // 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, layer2, (UTF8STRING("2"))) // 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, layer5, (UTF8STRING("5"))) // 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
//---------------------------------------------------------------------------------------------------------------------
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())
{
outline = detail.GetMappedSeamAllowancePoints();
@ -692,8 +694,7 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
return false;
}
m_input = QSharedPointer<dx_iface>(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement,
m_varInsunits));
m_input = QSharedPointer<dx_iface>::create(GetFileNameForLocale(), m_version, m_varMeasurement, m_varInsunits);
m_input->AddAAMAHeaderData();
if (m_version > DRW::AC1009)
{
@ -705,7 +706,8 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
for(auto detail : details)
{
auto *detailBlock = new dx_ifaceBlock();
auto detailBlock = QSharedPointer<dx_ifaceBlock>::create();
QString blockName = detail.GetName();
if (m_version <= DRW::AC1009)
@ -726,80 +728,98 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
ExportPieceText(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->layer = *layer1;
m_input->AddEntity(insert);
m_input->AddEntity(insert.take());
}
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);
if (e)
QVector<VLayoutPoint> points = PieceOutline(detail);
if (DRW_Entity *e = AAMAPolygon(points, *layer1, true))
{
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())
{
QVector<VLayoutPoint> points = detail.GetMappedContourPoints();
if (DRW_Entity *e = AAMAPolygon(detail.GetMappedContourPoints(), *layer8, true))
{
detailBlock->ent.push_back(e);
}
ExportTurnPoints(detailBlock, points);
ExportCurvePoints(detailBlock, points);
}
const QVector<QVector<QPointF>> drawIntCut = detail.MappedInternalPathsForCut(false);
for(const auto &intCut : drawIntCut)
const QVector<QVector<VLayoutPoint>> drawIntLine = detail.MappedInternalPathsForCut(false);
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);
}
ExportTurnPoints(detailBlock, intLine);
ExportCurvePoints(detailBlock, intLine);
}
const QVector<VLayoutPlaceLabel> labels = detail.GetMappedPlaceLabels();
const QVector<VLayoutPlaceLabel> labels = detail.GetPlaceLabels();
for(const auto &label : labels)
{
if (label.type != PlaceLabelType::Doubletree && label.type != PlaceLabelType::Button
&& label.type != PlaceLabelType::Circle)
if (label.Type() != PlaceLabelType::Doubletree && label.Type() != PlaceLabelType::Button
&& 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);
}
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)
{
if (DRW_Entity *e = AAMAPolygon(intCut, *layer11, false))
{
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())
{
@ -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();
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 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)
{
if (label.type == PlaceLabelType::Doubletree || label.type == PlaceLabelType::Button
|| label.type == PlaceLabelType::Circle)
if (label.Type() == PlaceLabelType::Doubletree || label.Type() == PlaceLabelType::Button
|| label.Type() == PlaceLabelType::Circle)
{
const QPointF center = detail.GetMatrix().map(label.center);
auto *point = new DRW_Point();
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);
const QPointF center = detail.GetMatrix().map(label.Center());
detailBlock->ent.push_back(AAMAPoint(center, *layer13));
}
}
}
@ -906,7 +921,7 @@ auto VDxfEngine::ExportToASTM(const QVector<VLayoutPiece> &details) -> bool
for(auto detail : details)
{
auto *detailBlock = new dx_ifaceBlock();
auto detailBlock = QSharedPointer<dx_ifaceBlock>::create();
QString blockName = detail.GetName();
if (m_version <= DRW::AC1009)
@ -929,44 +944,45 @@ auto VDxfEngine::ExportToASTM(const QVector<VLayoutPiece> &details) -> bool
ExportASTMDrill(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->layer = *layer1;
m_input->AddEntity(insert);
m_input->AddEntity(insert.take());
}
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
DRW_Entity *e = AAMAPolygon(pieceBoundary, *layer1, true);
if (e)
if (DRW_Entity *e = AAMAPolygon(pieceBoundary, *layer1, true))
{
detailBlock->ent.push_back(e);
}
ExportTurnPoints(detailBlock, pieceBoundary);
ExportCurvePoints(detailBlock, pieceBoundary);
// Piece boundary quality validation curves
DRW_Entity *q = AAMAPolygon(pieceBoundary, *layer84, true);
if (q)
if (DRW_Entity *q = AAMAPolygon(pieceBoundary, *layer84, true))
{
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())
{
QVector<QPointF> sewLine = detail.GetMappedContourPoints();
QVector<VLayoutPoint> sewLine = detail.GetMappedContourPoints();
// Sew lines
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);
}
ExportTurnPoints(detailBlock, sewLine);
ExportCurvePoints(detailBlock, sewLine);
// Sew lines quality validation curves
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);
for(const auto &intCut : drawIntCut)
const QVector<QVector<VLayoutPoint>> drawIntLine = detail.MappedInternalPathsForCut(false);
for(const auto &intLine : drawIntLine)
{
// Internal line
if (DRW_Entity *e = AAMAPolygon(intCut, *layer8, false))
if (DRW_Entity *e = AAMAPolygon(intLine, *layer8, false))
{
detailBlock->ent.push_back(e);
}
ExportTurnPoints(detailBlock, intLine);
ExportCurvePoints(detailBlock, intLine);
// 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);
}
}
const QVector<VLayoutPlaceLabel> labels = detail.GetMappedPlaceLabels();
const QVector<VLayoutPlaceLabel> labels = detail.GetPlaceLabels();
for(const auto &label : labels)
{
if (label.type != PlaceLabelType::Doubletree && label.type != PlaceLabelType::Button
&& label.type != PlaceLabelType::Circle)
if (label.Type() != PlaceLabelType::Doubletree && label.Type() != PlaceLabelType::Button
&& 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)
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);
}
ExportTurnPoints(detailBlock, p);
ExportCurvePoints(detailBlock, p);
// Internal lines quality validation curves
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)
{
// Internal cutout
@ -1037,6 +1063,9 @@ void VDxfEngine::ExportASTMInternalCutout(dx_ifaceBlock *detailBlock, const VLay
detailBlock->ent.push_back(e);
}
ExportTurnPoints(detailBlock, intCut);
ExportCurvePoints(detailBlock, intCut);
// Internal cutouts quality validation curves
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();
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)
{
if (label.type == PlaceLabelType::Doubletree || label.type == PlaceLabelType::Button
|| label.type == PlaceLabelType::Circle)
if (label.Type() == PlaceLabelType::Doubletree || label.Type() == PlaceLabelType::Button
|| label.Type() == PlaceLabelType::Circle)
{
const QPointF center = detail.GetMatrix().map(label.center);
auto *point = new DRW_Point();
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);
const QPointF center = detail.GetMatrix().map(label.Center());
detailBlock->ent.push_back(AAMAPoint(center, *layer13));
// TODO. Investigate drill category
// 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())
{
@ -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())
{
@ -1186,6 +1237,16 @@ auto VDxfEngine::AAMAText(const QPointF &pos, const QString &text, const UTF8STR
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
{
@ -1203,8 +1264,9 @@ auto VDxfEngine::GetFileNameForLocale() const -> std::string
}
//---------------------------------------------------------------------------------------------------------------------
template<class P, class V>
auto VDxfEngine::CreateAAMAPolygon(const QVector<QPointF> &polygon, const UTF8STRING &layer, bool forceClosed) -> P *
template<class P, class V, class C>
auto VDxfEngine::CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer,
bool forceClosed) -> P *
{
auto *poly = new P();
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),
FromPixel(GetSize().height() - p.y(), m_varInsunits)));

View file

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

View file

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

View file

@ -93,64 +93,3 @@ QDataStream &operator>>(QDataStream &dataStream, VLayoutPassmark &data)
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
};
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
{
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_p.h"
#include "../vpatterndb/vcontainer.h"
#include "varc.h"
#include <qnumeric.h>
#include <QPolygonF>
@ -240,198 +239,3 @@ VPlaceLabelItem &VPlaceLabelItem::operator=(VPlaceLabelItem &&item) Q_DECL_NOTHR
return *this;
}
#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;
QRectF Box() const;
PlaceLabelImg LabelShape() const;
QPainterPath LabelShapePath() const;
static QPainterPath LabelShapePath(const PlaceLabelImg &shape);
private:
QSharedDataPointer<VPlaceLabelItemData> d;
};

View file

@ -30,6 +30,8 @@
#include "vabstractpiece_p.h"
#include "../vmisc/vabstractvalapplication.h"
#include "../vgeometry/vpointf.h"
#include "../vgeometry/vlayoutplacelabel.h"
#include "../vgeometry/varc.h"
#include "../ifc/exception/vexception.h"
#include "../vmisc/compatibility.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.";
}
points.append(px);
points.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
cutLine.setAngle(cutLine.angle()-180);
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.";
}
points.append(px);
points.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
}
else
{// The point just fine
points.append(sp2);
points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
}
}
else
@ -139,25 +141,25 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
{
QLineF loop(bigLine1.p2(), sp2);
loop.setLength(loop.length() + accuracyPointOnLine*2.);
points.append(loop.p2());
points.append(sp2);
points.append(VRawSAPoint(bigLine1.p2(), true));
points.append(VRawSAPoint(loop.p2(), p.CurvePoint(), p.TurnPoint()));
points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
points.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint(), true));
loop = QLineF(bigLine2.p2(), sp2);
loop.setLength(loop.length() + localWidth);
points.append(VRawSAPoint(loop.p2(), true));
points.append(VRawSAPoint(loop.p2(), p.CurvePoint(), p.TurnPoint(), true));
}
else
{
QLineF loop(sp2, bigLine1.p1());
loop.setLength(accuracyPointOnLine*2.);
points.append(loop.p2());
points.append(sp2);
points.append(VRawSAPoint(loop.p2(), p.CurvePoint(), p.TurnPoint()));
points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
loop = QLineF(bigLine1.p1(), sp2);
loop.setLength(loop.length() + localWidth);
points.append(VRawSAPoint(loop.p2(), true));
points.append(VRawSAPoint(bigLine2.p1(), true));
points.append(VRawSAPoint(loop.p2(), p.CurvePoint(), p.TurnPoint(), true));
points.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint(), true));
}
}
else
@ -168,7 +170,7 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
{
bool success = false;
QVector<VRawSAPoint> temp = points;
temp.append(bigLine1.p2());
temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, bigLine2, &success);
if (success)
@ -183,7 +185,7 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
}
else
{
points.append(sp2);
points.append(VRawSAPoint(sp2, p.CurvePoint(), p.TurnPoint()));
}
}
else
@ -194,16 +196,17 @@ auto AngleByLength(QVector<VRawSAPoint> points, QPointF p1, QPointF p2, QPointF
QLineF loop1(sp2, sp1);
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.setLength(localWidth);
points.append(loop1.p2());
points.append(bigLine2.p1());
points.append(VRawSAPoint(loop1.p2(), p.CurvePoint(), p.TurnPoint()));
points.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint()));
}
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);
}
pointsIntr.append(px);
pointsIntr.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
}
else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false;
QVector<VRawSAPoint> temp = pointsIntr;
temp.append(bigLine1.p2());
temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, edge2, &success);
if (success)
@ -283,16 +286,16 @@ auto AngleByIntersection(const QVector<VRawSAPoint> &points, QPointF p1, QPointF
if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px))
{
pointsIntr.append(px);
pointsIntr.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
}
else
{
pointsIntr.append(px);
pointsIntr.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
QLineF allowance(p2, px);
allowance.setLength(allowance.length() + localWidth * 3.);
pointsIntr.append(allowance.p2());
pointsIntr.append(bigLine2.p1());
pointsIntr.append(VRawSAPoint(allowance.p2(), p.CurvePoint(), p.TurnPoint()));
pointsIntr.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint()));
}
return pointsIntr;
@ -343,13 +346,13 @@ auto AngleByFirstSymmetry(const QVector<VRawSAPoint> &points, QPointF p1, QPoint
if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px1))
{
pointsIntr.append(px1);
pointsIntr.append(VRawSAPoint(px1, p.CurvePoint(), p.TurnPoint()));
}
else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false;
QVector<VRawSAPoint> temp = pointsIntr;
temp.append(bigLine1.p2());
temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, sEdge, &success);
if (success)
@ -365,15 +368,15 @@ auto AngleByFirstSymmetry(const QVector<VRawSAPoint> &points, QPointF p1, QPoint
if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px2))
{
pointsIntr.append(px2);
pointsIntr.append(VRawSAPoint(px2, p.CurvePoint(), p.TurnPoint()));
}
else
{
QLineF allowance(px2, p2);
allowance.setAngle(allowance.angle() + 90);
pointsIntr.append(px2);
pointsIntr.append(allowance.p2());
pointsIntr.append(bigLine2.p1());
pointsIntr.append(VRawSAPoint(px2, p.CurvePoint(), p.TurnPoint()));
pointsIntr.append(VRawSAPoint(allowance.p2(), p.CurvePoint(), p.TurnPoint()));
pointsIntr.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint()));
}
return pointsIntr;
@ -425,13 +428,13 @@ auto AngleBySecondSymmetry(const QVector<VRawSAPoint> &points, QPointF p1, QPoin
if (IsOutsidePoint(bigLine1.p1(), bigLine1.p2(), px1))
{
pointsIntr.append(px1);
pointsIntr.append(VRawSAPoint(px1, p.CurvePoint(), p.TurnPoint()));
}
else
{// Because artificial loop can lead to wrong clipping we must rollback current seam allowance points
bool success = false;
QVector<VRawSAPoint> temp = pointsIntr;
temp.append(bigLine1.p2());
temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, sEdge, &success);
if (success)
@ -447,16 +450,16 @@ auto AngleBySecondSymmetry(const QVector<VRawSAPoint> &points, QPointF p1, QPoin
if (IsOutsidePoint(bigLine2.p2(), bigLine2.p1(), px2))
{
pointsIntr.append(px2);
pointsIntr.append(VRawSAPoint(px2, p.CurvePoint(), p.TurnPoint()));
}
else
{
QLineF allowance(p2, px2);
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.);
pointsIntr.append(allowance.p2());
pointsIntr.append(bigLine2.p1());
pointsIntr.append(VRawSAPoint(allowance.p2(), p.CurvePoint(), p.TurnPoint()));
pointsIntr.append(VRawSAPoint(bigLine2.p1(), p.CurvePoint(), p.TurnPoint()));
}
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);
}
pointsRA.append(seam.p2());
pointsRA.append(seam.p1());
pointsRA.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
pointsRA.append(VRawSAPoint(seam.p1(), p.CurvePoint(), p.TurnPoint()));
}
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);
}
pointsRA.append(seam.p2());
pointsRA.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
QLineF loopLine(px, sp2);
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());
tmp.setLength(tmp.length()+length);
pointsRA.append(tmp.p2());
pointsRA.append(loopLine.p2());
pointsRA.append(VRawSAPoint(tmp.p2(), p.CurvePoint(), p.TurnPoint()));
pointsRA.append(VRawSAPoint(loopLine.p2(), p.CurvePoint(), p.TurnPoint()));
}
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);
}
points.append(px);
points.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
QLineF seam(px, p3);
seam.setAngle(seam.angle()+90);
seam.setLength(p.GetSAAfter(width));
points.append(seam.p2());
points.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
if (needRollback != nullptr)
{
@ -595,7 +598,7 @@ auto AngleBySecondRightAngle(QVector<VRawSAPoint> points, QPointF p1, QPointF p2
bool success = false;
const int countBefore = points.size();
QVector<VRawSAPoint> temp = points;
temp.append(bigLine1.p2());
temp.append(VRawSAPoint(bigLine1.p2(), p.CurvePoint(), p.TurnPoint()));
temp = VAbstractPiece::RollbackSeamAllowance(temp, edge, &success);
if (success)
@ -609,7 +612,7 @@ auto AngleBySecondRightAngle(QVector<VRawSAPoint> points, QPointF p1, QPointF p2
QLineF seam(px, p3);
seam.setAngle(seam.angle()+90);
seam.setLength(p.GetSAAfter(width));
points.append(seam.p2());
points.append(VRawSAPoint(seam.p2(), p.CurvePoint(), p.TurnPoint()));
}
else
{
@ -619,11 +622,11 @@ auto AngleBySecondRightAngle(QVector<VRawSAPoint> points, QPointF p1, QPointF p2
}
else if (IsSameDirection(bigLine1.p1(), bigLine1.p2(), px))
{
points.append(px);
points.append(VRawSAPoint(px, p.CurvePoint(), p.TurnPoint()));
QLineF seam(px, p3);
seam.setAngle(seam.angle()+90);
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);
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));
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()));
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);
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);
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);
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);
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)));
if (success)
@ -848,7 +851,7 @@ void RollbackBySecondEdgeRightAngle(QVector<VRawSAPoint> &ekvPoints, const QVect
ekvPoints.removeFirst();
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;
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);
if (success)
@ -868,7 +871,7 @@ void RollbackBySecondEdgeRightAngle(QVector<VRawSAPoint> &ekvPoints, const QVect
QLineF seam(px, points.at(1));
seam.setAngle(seam.angle()+90);
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())
{
@ -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
// 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)
{
@ -1136,19 +1123,14 @@ auto VAbstractPiece::Equidistant(QVector<VSAPoint> points, qreal width, const QS
}
// Uncomment for debug
// QVector<QPointF> cleaned;
// cleaned.reserve(ekvPoints.size());
// for (auto &point : ekvPoints)
// {
// cleaned.append(point);
// }
// QVector<VLayoutPoint> cleaned = CastTo<VLayoutPoint>(ekvPoints);
const bool removeFirstAndLast = false;
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 = 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;
}
@ -1188,131 +1170,6 @@ auto VAbstractPiece::SumTrapezoids(const QVector<QPointF> &points) -> qreal
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
@ -1342,7 +1199,7 @@ auto VAbstractPiece::EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Lin
if (VFuzzyComparePoints(bigLine1.p2(), bigLine2.p1()))
{
points.append(bigLine1.p2());
points.append(VRawSAPoint(bigLine1.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points;
}
@ -1357,16 +1214,16 @@ auto VAbstractPiece::EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Lin
ray.setLength(width*2);
QPointF crosPoint;
QLineF::IntersectType type = Intersects(ray, bigLine1, &crosPoint );
QLineF::IntersectType type = Intersects(ray, bigLine1, &crosPoint);
if (type != QLineF::NoIntersection)
{
points.append(crosPoint);
points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
}
type = Intersects(ray, bigLine2, &crosPoint );
if (type != QLineF::NoIntersection)
{
points.append(crosPoint);
points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
}
return points;
}
@ -1378,7 +1235,7 @@ auto VAbstractPiece::EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Lin
{// There are at least three big cases
case (QLineF::BoundedIntersection):
// The easiest, real intersection
points.append(crosPoint);
points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points;
case (QLineF::UnboundedIntersection):
{ // 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)) &&
IsOnLine(p2Line1, bigLine1.p2(), bigLine2.p1(), ToPixel(0.5, Unit::Mm)))
{
points.append(bigLine1.p2());
points.append(bigLine2.p1());
points.append(VRawSAPoint(bigLine1.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
points.append(VRawSAPoint(bigLine2.p1(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points;
}
@ -1473,7 +1330,7 @@ QT_WARNING_POP
const QLineF::IntersectType type = Intersects(bigEdge, line, &px);
if (type != QLineF::BoundedIntersection && line.length() < QLineF(p2Line1, px).length())
{
points.append(crosPoint);
points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points;
}
}
@ -1484,12 +1341,12 @@ QT_WARNING_POP
QLineF loop(crosPoint, bigLine1.p1());
loop.setAngle(loop.angle() + 180);
loop.setLength(accuracyPointOnLine*2.);
points.append(loop.p2());
points.append(crosPoint);
points.append(VRawSAPoint(loop.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
loop = QLineF(crosPoint, bigLine1.p1());
loop.setLength(loop.length() + localWidth*2.);
points.append(VRawSAPoint(loop.p2(), true));
points.append(VRawSAPoint(loop.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint(), true));
}
return points;
@ -1504,20 +1361,20 @@ QT_WARNING_POP
{// The cross point is still outside of a piece
if (line.length() >= localWidth)
{
points.append(crosPoint);
points.append(VRawSAPoint(crosPoint, p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points;
}
// but not enough far, fix it
line.setLength(localWidth);
points.append(line.p2());
points.append(VRawSAPoint(line.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points;
}
// Wrong cross point, probably inside of a piece. Manually creating correct seam allowance
const QLineF bigEdge = SimpleParallelLine(bigLine1.p2(), bigLine2.p1(), localWidth );
points.append(bigEdge.p1());
points.append(bigEdge.p2());
points.append(VRawSAPoint(bigEdge.p1(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
points.append(VRawSAPoint(bigEdge.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points;
}
}
@ -1525,8 +1382,9 @@ QT_WARNING_POP
}
case (QLineF::NoIntersection):
/*If we have correct lines this means lines lie on a line or parallel.*/
points.append(bigLine1.p2());
points.append(bigLine2.p1()); // Second point for parallel line
points.append(VRawSAPoint(bigLine1.p2(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
// Second point for parallel line
points.append(VRawSAPoint(bigLine2.p1(), p2Line1.CurvePoint(), p2Line1.TurnPoint()));
return points;
default:
break;
@ -1657,10 +1515,8 @@ auto VAbstractPiece::GetUniqueID() const -> QString
//---------------------------------------------------------------------------------------------------------------------
auto VSAPoint::toJson() const -> QJsonObject
{
QJsonObject pointObject;
QJsonObject pointObject = VLayoutPoint::toJson();
pointObject[QLatin1String("type")] = "VSAPoint";
pointObject[QLatin1String("x")] = x();
pointObject[QLatin1String("y")] = y();
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())
&& 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)
{
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))
{
points.append(crosPoint);
points.append(VRawSAPoint(crosPoint, points.at(points.size()-1).CurvePoint(),
points.at(points.size()-1).TurnPoint()));
*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;
path.setFillRule(Qt::WindingFill);
if (not points.isEmpty())
auto LayoutPoint = [label](QPointF p, bool turnPoint = false, bool curvePoint = false)
{
path.moveTo(points.at(0));
for (qint32 i = 1; i < points.count(); ++i)
VLayoutPoint point(label.RotationMatrix().map(p));
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;
}
//---------------------------------------------------------------------------------------------------------------------
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 VContainer;
class VRawSAPoint;
class VLayoutPlaceLabel;
using PlaceLabelImg = QVector<QVector<VLayoutPoint> >;
class VAbstractPiece
{
@ -100,10 +103,10 @@ public:
*/
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 CheckLoops(const QVector<QPointF> &points) -> QVector<QPointF>;
static auto CheckLoops(const QVector<VRawSAPoint> &points) -> QVector<QPointF>;
template <class T>
static auto CheckLoops(QVector<T> points) -> QVector<T>;
static auto EkvPoint(QVector<VRawSAPoint> points, const VSAPoint &p1Line1, const VSAPoint &p2Line1,
const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width,
bool *needRollback = nullptr) -> QVector<VRawSAPoint>;
@ -122,28 +125,81 @@ public:
static auto GrainlinePoints(const VGrainlineData &geom, const VContainer *pattern,
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, 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:
template <class 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 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,
qreal &dY) -> bool;
static auto CorrectPosition(const QRectF &parentBoundingRect, QVector<QPointF> points) -> QVector<QPointF>;
static auto FindGrainlineGeometry(const VGrainlineData& geom, const VContainer *pattern, qreal &length,
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:
QSharedDataPointer<VAbstractPieceData> d;
};
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.
@ -151,7 +207,7 @@ Q_DECLARE_TYPEINFO(VAbstractPiece, Q_MOVABLE_TYPE); // NOLINT
* @return corrected list.
*/
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
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;
//Remove point on line
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.
if (prev == -1)
{
@ -213,9 +269,8 @@ auto VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool rem
const T &prevPoint = buf1.at(prev);
const T &nextPoint = buf1.at(next);
if (not IsEkvPointOnLine(iPoint, prevPoint, nextPoint))
if (not CheckPointOnLine(buf2, iPoint, prevPoint, nextPoint))
{
buf2.append(iPoint);
prev = -1;
}
}
@ -233,7 +288,7 @@ auto VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool rem
//---------------------------------------------------------------------------------------------------------------------
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)
{
@ -252,9 +307,8 @@ auto VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirst
{
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;
break;
}
@ -267,10 +321,7 @@ auto VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirst
{
// Path can't be closed
// See issue #686
if (VFuzzyComparePoints(ConstFirst(p), ConstLast(p), accuracy))
{
p.removeLast();
}
CompareFirstAndLastPoints(p, accuracy);
}
}
@ -279,7 +330,7 @@ auto VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirst
//---------------------------------------------------------------------------------------------------------------------
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
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); });
}
//---------------------------------------------------------------------------------------------------------------------
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

View file

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

View file

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

View file

@ -45,10 +45,11 @@
#include <Qt>
#include <QtDebug>
#include <QUuid>
#include <QtMath>
#include "../vpatterndb/floatItemData/vpatternlabeldata.h"
#include "../vpatterndb/floatItemData/vpiecelabeldata.h"
#include "../vmisc/vmath.h"
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
#include "../vmisc/vabstractvalapplication.h"
#include "../vmisc/compatibility.h"
#include "../vmisc/literals.h"
@ -58,13 +59,10 @@
#include "../vpatterndb/vpiecenode.h"
#include "../vgeometry/vpointf.h"
#include "../vgeometry/vplacelabelitem.h"
#include "vlayoutdef.h"
#include "vlayoutpiece_p.h"
#include "vtextmanager.h"
#include "vgraphicsfillitem.h"
const quint32 VLayoutPieceData::streamHeader = 0x80D7D009; // CRC-32Q string "VLayoutPieceData"
const quint16 VLayoutPieceData::classVersion = 3;
#include "../vgeometry/vlayoutplacelabel.h"
namespace
{
@ -82,7 +80,7 @@ QVector<VLayoutPiecePath> ConvertInternalPaths(const VPiece &piece, const VConta
const VPiecePath path = pattern->GetPiecePath(id);
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.SetPenStyle(path.GetPenType());
paths.append(convertedPath);
@ -170,18 +168,6 @@ bool FindLabelGeometry(const VPatternLabelData &labelData, const VContainer *pat
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
@ -222,7 +208,7 @@ QVector<VLayoutPlaceLabel> ConvertPlaceLabels(const VPiece &piece, const VContai
QVector<VLayoutPlaceLabel> labels;
const auto placeLabels = piece.GetPlaceLabels();
labels.reserve(placeLabels.size());
for(auto &placeLabel : placeLabels)
for(const auto &placeLabel : placeLabels)
{
const auto label = pattern->GeometricObject<VPlaceLabelItem>(placeLabel);
if (label->IsVisible())
@ -231,13 +217,7 @@ QVector<VLayoutPlaceLabel> ConvertPlaceLabels(const VPiece &piece, const VContai
QT_WARNING_DISABLE_GCC("-Wnoexcept")
// noexcept-expression evaluates to 'false' because of a call to 'constexpr QPointF::QPointF()'
VLayoutPlaceLabel layoutLabel;
layoutLabel.shape = label->LabelShape();
layoutLabel.rotationMatrix = label->RotationMatrix();
layoutLabel.box = label->Box();
layoutLabel.center = label->toQPointF();
layoutLabel.type = label->GetLabelType();
labels.append(layoutLabel);
labels.append(VLayoutPlaceLabel(*label));
QT_WARNING_POP
}
@ -250,7 +230,7 @@ QVector<VLayoutPassmark> ConvertPassmarks(const VPiece &piece, const VContainer
{
const QVector<VPassmark> passmarks = piece.Passmarks(pattern);
QVector<VLayoutPassmark> layoutPassmarks;
for(auto &passmark : passmarks)
for(const auto &passmark : passmarks)
{
if (not passmark.IsNull())
{
@ -525,9 +505,35 @@ auto PrepareGradationId(const QString &label, const VContainer *pattern) -> QStr
const QMap<QString, QString> placeholders = PrepareGradationPlaceholders(pattern);
return ReplacePlaceholders(placeholders, label);
}
}
} // namespace
// 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)
{
@ -588,9 +594,10 @@ VLayoutPiece::~VLayoutPiece()
//---------------------------------------------------------------------------------------------------------------------
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<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<VLayoutPassmark> > futurePassmarks = QtConcurrent::run(ConvertPassmarks, 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>
{
std::transform(points.begin(), points.end(), points.begin(),
[this](const T &point) { return d->matrix.map(point); });
if (d->mirror)
[this](const T &point) { return d->m_matrix.map(point); });
if (d->m_mirror)
{
std::reverse(points.begin(), points.end());
}
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 <>
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)
{
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;
}
//---------------------------------------------------------------------------------------------------------------------
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
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);
}
//---------------------------------------------------------------------------------------------------------------------
// 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)
{
SetSeamAllowance(seamAllowance);
SetSeamAllowanceBuiltIn(seamAllowanceBuiltIn);
d->seamAllowance = points;
if (not d->seamAllowance.isEmpty())
d->m_seamAllowance = points;
if (not d->m_seamAllowance.isEmpty())
{
d->seamAllowance = RemoveDublicates(d->seamAllowance, false);
d->m_seamAllowance = RemoveDublicates(d->m_seamAllowance, false);
}
else if (not IsSeamAllowanceBuiltIn())
{
@ -762,21 +777,21 @@ void VLayoutPiece::SetSeamAllowancePoints(const QVector<QPointF> &points, bool s
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetMappedLayoutAllowancePoints() const
{
return Map(d->layoutAllowance);
return Map(d->m_layoutAllowance);
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetLayoutAllowancePoints() const
{
return d->layoutAllowance;
return d->m_layoutAllowance;
}
//---------------------------------------------------------------------------------------------------------------------
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
{
@ -787,7 +802,7 @@ QPointF VLayoutPiece::GetPieceTextPosition() 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());
d->detailLabel = CorrectPosition(item->boundingRect(), v);
d->m_detailLabel = CorrectPosition(item->boundingRect(), v);
// generate text
d->m_tmDetail.SetFont(font);
@ -832,13 +847,13 @@ void VLayoutPiece::SetPieceText(const QString& qsName, const VPieceLabelData& da
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetPieceLabelRect() const -> QVector<QPointF>
{
return d->detailLabel;
return d->m_detailLabel;
}
//---------------------------------------------------------------------------------------------------------------------
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
{
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
{
@ -869,7 +884,7 @@ QPointF VLayoutPiece::GetPatternTextPosition() 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);
}
QScopedPointer<QGraphicsItem> item(GetMainPathItem());
d->patternInfo = CorrectPosition(item->boundingRect(), v);
d->m_patternInfo = CorrectPosition(item->boundingRect(), v);
// Generate text
d->m_tmPattern.SetFont(font);
@ -914,13 +929,13 @@ void VLayoutPiece::SetPatternInfo(VAbstractPattern* pDoc, const VPatternLabelDat
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetPatternLabelRect() const -> QVector<QPointF>
{
return d->patternInfo;
return d->m_patternInfo;
}
//---------------------------------------------------------------------------------------------------------------------
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;
}
d->grainlineEnabled = true;
d->grainlineArrowType = geom.GetArrowType();
d->grainlineAngle = qRadiansToDegrees(dAng);
d->grainlinePoints = v;
d->m_grainlineEnabled = true;
d->m_grainlineArrowType = geom.GetArrowType();
d->m_grainlineAngle = qRadiansToDegrees(dAng);
d->m_grainlinePoints = v;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetMappedGrainline() const
{
return Map(d->grainlinePoints);
return Map(d->m_grainlinePoints);
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetGrainline() const
{
return d->grainlinePoints;
return d->m_grainlinePoints;
}
//---------------------------------------------------------------------------------------------------------------------
bool VLayoutPiece::IsGrainlineEnabled() const
{
return d->grainlineEnabled;
return d->m_grainlineEnabled;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainlineEnabled(bool enabled)
{
d->grainlineEnabled = enabled;
d->m_grainlineEnabled = enabled;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainlineAngle(qreal angle)
{
d->grainlineAngle = angle;
d->m_grainlineAngle = angle;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainlineArrowType(GrainlineArrowDirection type)
{
d->grainlineArrowType = type;
d->m_grainlineArrowType = type;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainlinePoints(const QVector<QPointF> &points)
{
d->grainlinePoints = points;
d->m_grainlinePoints = points;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VLayoutPiece::GrainlineAngle() const
{
return d->grainlineAngle;
return d->m_grainlineAngle;
}
//---------------------------------------------------------------------------------------------------------------------
GrainlineArrowDirection VLayoutPiece::GrainlineArrowType() const
{
return d->grainlineArrowType;
return d->m_grainlineArrowType;
}
//---------------------------------------------------------------------------------------------------------------------
QTransform VLayoutPiece::GetMatrix() const
{
return d->matrix;
return d->m_matrix;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetMatrix(const QTransform &matrix)
{
d->matrix = matrix;
d->m_matrix = matrix;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VLayoutPiece::GetLayoutWidth() const
{
return d->layoutWidth;
return d->m_layoutWidth;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetLayoutWidth(qreal value)
{
d->layoutWidth = value;
d->m_layoutWidth = value;
}
//---------------------------------------------------------------------------------------------------------------------
@ -1067,7 +1082,7 @@ void VLayoutPiece::Translate(const QPointF &p)
{
QTransform m;
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;
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.rotate(-degrees);
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.rotate(-angle);
m.translate(-p2.x(), -p2.y());
d->matrix *= m;
d->m_matrix *= m;
m.reset();
m.translate(p2.x(), p2.y());
m.scale(m.m11(), m.m22()*-1);
m.translate(-p2.x(), -p2.y());
d->matrix *= m;
d->m_matrix *= m;
m.reset();
m.translate(p2.x(), p2.y());
m.rotate(-(360-angle));
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;
m.scale(-1, 1);
d->matrix *= m;
d->mirror = !d->mirror;
d->m_matrix *= m;
d->m_mirror = !d->m_mirror;
}
//---------------------------------------------------------------------------------------------------------------------
@ -1142,32 +1157,32 @@ int VLayoutPiece::DetailEdgesCount() const
//---------------------------------------------------------------------------------------------------------------------
int VLayoutPiece::LayoutEdgesCount() const
{
const int count = d->layoutAllowance.count();
const int count = d->m_layoutAllowance.count();
return count > 2 ? count : 0;
}
//---------------------------------------------------------------------------------------------------------------------
QLineF VLayoutPiece::LayoutEdge(int i) const
{
return Edge(d->layoutAllowance, i);
return Edge(d->m_layoutAllowance, i);
}
//---------------------------------------------------------------------------------------------------------------------
int VLayoutPiece::LayoutEdgeByPoint(const QPointF &p1) const
{
return EdgeByPoint(d->layoutAllowance, p1);
return EdgeByPoint(d->m_layoutAllowance, p1);
}
//---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::MappedDetailBoundingRect() const
{
return BoundingRect(GetMappedExternalContourPoints());
return BoundingRect(CastTo<QPointF>(GetMappedExternalContourPoints()));
}
//---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::DetailBoundingRect() const
{
return BoundingRect(GetExternalContourPoints());
return BoundingRect(CastTo<QPointF>(GetExternalContourPoints()));
}
//---------------------------------------------------------------------------------------------------------------------
@ -1186,9 +1201,9 @@ qreal VLayoutPiece::Diagonal() 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;
}
@ -1214,45 +1229,46 @@ void VLayoutPiece::SetLayoutAllowancePoints()
{
d->m_square = 0;
if (d->layoutWidth > 0)
if (d->m_layoutWidth > 0)
{
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{
d->layoutAllowance = Equidistant(PrepareAllowance(GetMappedSeamAllowancePoints()), d->layoutWidth,
GetName());
if (not d->layoutAllowance.isEmpty())
d->m_layoutAllowance = CastTo<QPointF>(Equidistant(CastTo<VSAPoint>(GetMappedSeamAllowancePoints()),
d->m_layoutWidth, GetName()));
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
{
d->layoutAllowance = Equidistant(PrepareAllowance(GetMappedContourPoints()), d->layoutWidth, GetName());
if (not d->layoutAllowance.isEmpty())
d->m_layoutAllowance = CastTo<QPointF>(Equidistant(CastTo<VSAPoint>(GetMappedContourPoints()),
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
{
d->layoutAllowance.clear();
d->m_layoutAllowance.clear();
}
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetMappedExternalContourPoints() const
QVector<VLayoutPoint> VLayoutPiece::GetMappedExternalContourPoints() const
{
return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetMappedSeamAllowancePoints() :
GetMappedContourPoints();
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPiece::GetExternalContourPoints() const
QVector<VLayoutPoint> VLayoutPiece::GetExternalContourPoints() const
{
return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetSeamAllowancePoints() :
GetContourPoints();
@ -1261,13 +1277,13 @@ QVector<QPointF> VLayoutPiece::GetExternalContourPoints() const
//---------------------------------------------------------------------------------------------------------------------
QVector<VLayoutPassmark> VLayoutPiece::GetMappedPassmarks() const
{
return Map(d->passmarks);
return Map(d->m_passmarks);
}
//---------------------------------------------------------------------------------------------------------------------
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())
{
d->passmarks = passmarks;
d->m_passmarks = passmarks;
}
}
//---------------------------------------------------------------------------------------------------------------------
QVector<VLayoutPlaceLabel> VLayoutPiece::GetMappedPlaceLabels() const
{
return Map(d->m_placeLabels);
}
//---------------------------------------------------------------------------------------------------------------------
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)
{
@ -1328,7 +1339,7 @@ void VLayoutPiece::SetInternalPaths(const QVector<VLayoutPiecePath> &internalPat
//---------------------------------------------------------------------------------------------------------------------
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())
{
// Draw seam allowance
QVector<QPointF>points = GetSeamAllowancePoints();
QVector<VLayoutPoint> points = GetSeamAllowancePoints();
if (ConstLast(points).toPoint() != ConstFirst(points).toPoint())
{
@ -1410,7 +1421,7 @@ void VLayoutPiece::DrawMiniature(QPainter &painter) const
for (const auto &label : d->m_placeLabels)
{
painter.drawPath(VPlaceLabelItem::LabelShapePath(label.shape));
painter.drawPath(LabelShapePath(label));
}
QVector<QPointF> gPoints = GetGrainline();
@ -1431,10 +1442,10 @@ QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const
{
QGraphicsPathItem *item = GetMainItem();
for (auto &path : d->m_internalPaths)
for (const auto &path : d->m_internalPaths)
{
auto* pathItem = new QGraphicsPathItem(item);
pathItem->setPath(d->matrix.map(path.GetPainterPath()));
pathItem->setPath(d->m_matrix.map(path.GetPainterPath()));
QPen pen = pathItem->pen();
pen.setStyle(path.PenStyle());
@ -1448,11 +1459,11 @@ QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const
QPen pen = pathItem->pen();
pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine());
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->patternInfo, d->m_tmPattern, textAsPaths);
CreateLabelStrings(item, d->m_detailLabel, d->m_tmDetail, textAsPaths);
CreateLabelStrings(item, d->m_patternInfo, d->m_tmPattern, textAsPaths);
CreateGrainlineItem(item);
return item;
@ -1461,8 +1472,9 @@ QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const
//---------------------------------------------------------------------------------------------------------------------
bool VLayoutPiece::IsLayoutAllowanceValid() const
{
QVector<QPointF> base = (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? d->seamAllowance : d->contour;
return VAbstractPiece::IsAllowanceValid(base, d->layoutAllowance);
QVector<VLayoutPoint> base = (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ?
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;
}
//---------------------------------------------------------------------------------------------------------------------
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)
{
@ -1551,7 +1575,7 @@ void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector<QPoin
// set up the rotation around top-left corner matrix
QTransform labelMatrix;
labelMatrix.translate(labelShape.at(0).x(), labelShape.at(0).y());
if (d->mirror)
if (d->m_mirror)
{
labelMatrix.scale(-1, 1);
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 *= d->matrix;
labelMatrix *= d->m_matrix;
if (textAsPaths)
{
@ -1596,7 +1620,7 @@ void VLayoutPiece::CreateGrainlineItem(QGraphicsItem *parent) const
{
SCASSERT(parent != nullptr)
if (not d->grainlineEnabled || d->grainlinePoints.count() < 2)
if (not d->m_grainlineEnabled || d->m_grainlinePoints.count() < 2)
{
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())
{
return d->seamAllowance;
}
else
{
return d->contour;
return d->m_seamAllowance;
}
return d->m_contour;
}
//---------------------------------------------------------------------------------------------------------------------
@ -1649,7 +1671,7 @@ QGraphicsPathItem *VLayoutPiece::GetMainPathItem() const
QPainterPath path;
// contour
QVector<QPointF> points = GetMappedContourPoints();
QVector<VLayoutPoint> points = GetMappedContourPoints();
path.moveTo(points.at(0));
for (qint32 i = 1; i < points.count(); ++i)
@ -1665,13 +1687,13 @@ QGraphicsPathItem *VLayoutPiece::GetMainPathItem() const
//---------------------------------------------------------------------------------------------------------------------
bool VLayoutPiece::IsMirror() const
{
return d->mirror;
return d->m_mirror;
}
//---------------------------------------------------------------------------------------------------------------------
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;
}
if (d->mirror)
if (d->m_mirror)
{
QVector<QPointF> newPath = Map(path);
return QLineF(newPath.at(i1), newPath.at(i2));
}
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 VAbstractPattern;
class VPatternLabelData;
class VLayoutPoint;
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wsuggest-final-types")
@ -79,31 +80,30 @@ public:
virtual auto GetUniqueID() const -> QString override;
QVector<QPointF> GetMappedContourPoints() const;
QVector<QPointF> GetContourPoints() const;
void SetCountourPoints(const QVector<QPointF> &points, bool hideMainPath = false);
QVector<VLayoutPoint> GetMappedContourPoints() const;
QVector<VLayoutPoint> GetContourPoints() const;
void SetCountourPoints(const QVector<VLayoutPoint> &points, bool hideMainPath = false);
QVector<QPointF> GetMappedSeamAllowancePoints() const;
QVector<QPointF> GetSeamAllowancePoints() const;
void SetSeamAllowancePoints(const QVector<QPointF> &points, bool seamAllowance = true,
QVector<VLayoutPoint> GetMappedSeamAllowancePoints() const;
QVector<VLayoutPoint> GetSeamAllowancePoints() const;
void SetSeamAllowancePoints(const QVector<VLayoutPoint> &points, bool seamAllowance = true,
bool seamAllowanceBuiltIn = false);
QVector<QPointF> GetMappedLayoutAllowancePoints() const;
QVector<QPointF> GetLayoutAllowancePoints() const;
void SetLayoutAllowancePoints();
QVector<QPointF> GetMappedExternalContourPoints() const;
QVector<QPointF> GetExternalContourPoints() const;
QVector<VLayoutPoint> GetMappedExternalContourPoints() const;
QVector<VLayoutPoint> GetExternalContourPoints() const;
QVector<VLayoutPassmark> GetMappedPassmarks() const;
QVector<VLayoutPassmark> GetPassmarks() const;
void SetPassmarks(const QVector<VLayoutPassmark> &passmarks);
QVector<VLayoutPlaceLabel> GetMappedPlaceLabels() const;
QVector<VLayoutPlaceLabel> GetPlaceLabels() const;
void SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels);
QVector<QVector<QPointF>> MappedInternalPathsForCut(bool cut) const;
QVector<QVector<VLayoutPoint> > MappedInternalPathsForCut(bool cut) const;
QVector<VLayoutPiecePath> GetInternalPaths() const;
void SetInternalPaths(const QVector<VLayoutPiecePath> &internalPaths);
@ -185,6 +185,8 @@ public:
friend QDataStream& operator<< (QDataStream& dataStream, const VLayoutPiece& piece);
friend QDataStream& operator>> (QDataStream& dataStream, VLayoutPiece& piece);
auto MapPlaceLabelShape(PlaceLabelImg shape) const -> PlaceLabelImg;
protected:
void SetGrainlineEnabled(bool enabled);
void SetGrainlineAngle(qreal angle);
@ -206,7 +208,7 @@ protected:
private:
QSharedDataPointer<VLayoutPieceData> d;
QVector<QPointF> DetailPath() const;
QVector<VLayoutPoint> DetailPath() const;
Q_REQUIRED_RESULT QGraphicsPathItem *GetMainItem() const;
Q_REQUIRED_RESULT QGraphicsPathItem *GetMainPathItem() const;

View file

@ -34,9 +34,7 @@
#include <QVector>
#include <QTransform>
#include "../vpatterndb/floatItemData/vpiecelabeldata.h"
#include "../vpatterndb/floatItemData/vpatternlabeldata.h"
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
#include "../vpatterndb/floatItemData/floatitemdef.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "../vmisc/diagnostic.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
@ -47,6 +45,8 @@
#include "../vgeometry/vgeometrydef.h"
#include "vtextmanager.h"
#include "../ifc/exception/vexception.h"
#include "vlayoutpoint.h"
#include "vlayoutplacelabel.h"
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++")
@ -55,126 +55,99 @@ QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
class VLayoutPieceData : public QSharedData
{
public:
VLayoutPieceData()
{}
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(){} // NOLINT(modernize-use-equals-default)
VLayoutPieceData(const VLayoutPieceData &detail) = default;
~VLayoutPieceData() = default;
friend QDataStream& operator<<(QDataStream& dataStream, const VLayoutPieceData& piece);
friend QDataStream& operator>>(QDataStream& dataStream, VLayoutPieceData& piece);
friend auto operator<<(QDataStream& dataStream, const VLayoutPieceData& piece) -> QDataStream&;
friend auto operator>>(QDataStream& dataStream, VLayoutPieceData& piece) -> QDataStream&;
/** @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. */
QVector<QPointF> seamAllowance{};
QVector<VLayoutPoint> m_seamAllowance{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @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. */
QVector<VLayoutPassmark> passmarks{};
QVector<VLayoutPassmark> m_passmarks{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @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*/
QTransform matrix{};
QTransform m_matrix{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @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 */
QVector<QPointF> detailLabel{};
QVector<QPointF> m_detailLabel{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief patternInfo pattern info rectangle */
QVector<QPointF> patternInfo{};
QVector<QPointF> m_patternInfo{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @brief grainlineInfo line */
QVector<QPointF> grainlinePoints{};
QVector<QPointF> m_grainlinePoints{}; // NOLINT(misc-non-private-member-variables-in-classes)
GrainlineArrowDirection grainlineArrowType{GrainlineArrowDirection::atFront};
qreal grainlineAngle{0};
bool grainlineEnabled{false};
GrainlineArrowDirection m_grainlineArrowType{GrainlineArrowDirection::atFront}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal m_grainlineAngle{0}; // NOLINT(misc-non-private-member-variables-in-classes)
bool m_grainlineEnabled{false}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @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 */
VTextManager m_tmPattern{};
VTextManager m_tmPattern{}; // NOLINT(misc-non-private-member-variables-in-classes)
/** @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. */
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_yScale{1.0};
qreal m_xScale{1.0}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal m_yScale{1.0}; // NOLINT(misc-non-private-member-variables-in-classes)
private:
Q_DISABLE_ASSIGN(VLayoutPieceData)
Q_DISABLE_ASSIGN_MOVE(VLayoutPieceData) // NOLINT
static const quint32 streamHeader;
static const quint16 classVersion;
static constexpr quint32 streamHeader{0x80D7D009}; // CRC-32Q string "VLayoutPieceData"
static constexpr quint16 classVersion{4};
};
// Friend functions
//---------------------------------------------------------------------------------------------------------------------
inline QDataStream &operator<<(QDataStream &dataStream, const VLayoutPieceData &piece)
inline auto operator<<(QDataStream &dataStream, const VLayoutPieceData &piece) -> QDataStream &
{
dataStream << VLayoutPieceData::streamHeader << VLayoutPieceData::classVersion;
// Added in classVersion = 1
dataStream << piece.contour;
dataStream << piece.seamAllowance;
dataStream << piece.layoutAllowance;
dataStream << piece.passmarks;
dataStream << piece.m_contour;
dataStream << piece.m_seamAllowance;
dataStream << piece.m_layoutAllowance;
dataStream << piece.m_passmarks;
dataStream << piece.m_internalPaths;
dataStream << piece.matrix;
dataStream << piece.layoutWidth;
dataStream << piece.mirror;
dataStream << piece.detailLabel;
dataStream << piece.patternInfo;
dataStream << piece.grainlinePoints;
dataStream << piece.grainlineArrowType;
dataStream << piece.grainlineAngle;
dataStream << piece.grainlineEnabled;
dataStream << piece.m_matrix;
dataStream << piece.m_layoutWidth;
dataStream << piece.m_mirror;
dataStream << piece.m_detailLabel;
dataStream << piece.m_patternInfo;
dataStream << piece.m_grainlinePoints;
dataStream << piece.m_grainlineArrowType;
dataStream << piece.m_grainlineAngle;
dataStream << piece.m_grainlineEnabled;
dataStream << piece.m_placeLabels;
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;
dataStream >> actualStreamHeader;
@ -218,20 +191,35 @@ inline QDataStream &operator>>(QDataStream &dataStream, VLayoutPieceData &piece)
throw VException(message);
}
dataStream >> piece.contour;
dataStream >> piece.seamAllowance;
dataStream >> piece.layoutAllowance;
dataStream >> piece.passmarks;
if (actualClassVersion < 4)
{
auto ReadPoints = [&dataStream]()
{
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.matrix;
dataStream >> piece.layoutWidth;
dataStream >> piece.mirror;
dataStream >> piece.detailLabel;
dataStream >> piece.patternInfo;
dataStream >> piece.grainlinePoints;
dataStream >> piece.grainlineArrowType;
dataStream >> piece.grainlineAngle;
dataStream >> piece.grainlineEnabled;
dataStream >> piece.m_matrix;
dataStream >> piece.m_layoutWidth;
dataStream >> piece.m_mirror;
dataStream >> piece.m_detailLabel;
dataStream >> piece.m_patternInfo;
dataStream >> piece.m_grainlinePoints;
dataStream >> piece.m_grainlineArrowType;
dataStream >> piece.m_grainlineAngle;
dataStream >> piece.m_grainlineEnabled;
dataStream >> piece.m_placeLabels;
dataStream >> piece.m_square;

View file

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

View file

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

View file

@ -41,6 +41,7 @@
# include "../vmisc/vdatastreamenum.h"
#endif
#include "../ifc/exception/vexception.h"
#include "vlayoutpoint.h"
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++")
@ -52,24 +53,18 @@ public:
VLayoutPiecePathData()
{}
explicit VLayoutPiecePathData(const QVector<QPointF> &points)
explicit VLayoutPiecePathData(const QVector<VLayoutPoint> &points)
: m_points(points)
{}
VLayoutPiecePathData(const VLayoutPiecePathData &path)
: QSharedData(path),
m_points(path.m_points),
m_penStyle(path.m_penStyle),
m_cut(path.m_cut)
{}
VLayoutPiecePathData(const VLayoutPiecePathData &path) = default;
~VLayoutPiecePathData() = default;
friend QDataStream& operator<<(QDataStream& dataStream, const VLayoutPiecePathData& path);
friend QDataStream& operator>>(QDataStream& dataStream, VLayoutPiecePathData& path);
/** @brief m_points list of path points. */
QVector<QPointF> m_points{};
QVector<VLayoutPoint> m_points{};
/** @brief m_penStyle path pen style. */
Qt::PenStyle m_penStyle{Qt::SolidLine};
@ -79,8 +74,8 @@ public:
private:
Q_DISABLE_ASSIGN(VLayoutPiecePathData)
static const quint32 streamHeader;
static const quint16 classVersion;
static constexpr quint32 streamHeader = 0xA53F0225; // CRC-32Q string "VLayoutPiecePathData"
static constexpr quint16 classVersion = 2;
};
QT_WARNING_POP
@ -127,7 +122,16 @@ QDataStream& operator>>(QDataStream &dataStream, VLayoutPiecePathData &path)
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_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 "../ifc/exception/vexception.h"
#include "../vpatterndb/floatItemData/floatitemdef.h"
#include "../vlayout/vlayoutpoint.h"
namespace
{
@ -461,8 +462,9 @@ auto VPosition::Crossing(const VLayoutPiece &detail) const -> VPosition::Crossin
const QRectF layoutBoundingRect = VLayoutPiece::BoundingRect(layoutPoints);
const QPainterPath layoutAllowancePath = VAbstractPiece::PainterPath(layoutPoints);
const QVector<QPointF> contourPoints = detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() ?
detail.GetMappedSeamAllowancePoints() : detail.GetMappedContourPoints();
const QVector<QPointF> contourPoints =
CastTo<QPointF>(detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() ?
detail.GetMappedSeamAllowancePoints() : detail.GetMappedContourPoints());
const QRectF detailBoundingRect = VLayoutPiece::BoundingRect(contourPoints);
const QPainterPath contourPath = VAbstractPiece::PainterPath(contourPoints);

View file

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

View file

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

View file

@ -36,17 +36,17 @@
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "../vmisc/def.h"
#include "../vgeometry/vgeometrydef.h"
#include <QPointF>
#include "vlayoutpoint.h"
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++")
QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
QT_WARNING_DISABLE_CLANG("-Wnon-virtual-dtor")
/**
* @brief The VSAPoint class seam allowance point
*/
class VSAPoint : public QPointF
class VSAPoint : public VLayoutPoint
{
public:
QT_WARNING_PUSH
@ -58,6 +58,7 @@ public:
Q_DECL_CONSTEXPR VSAPoint(qreal xpos, qreal ypos);
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 GetSAAfter() const -> qreal;
@ -78,7 +79,7 @@ public:
Q_DECL_RELAXED_CONSTEXPR auto MaxLocalSA(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 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)
: QPointF(xpos, ypos)
: VLayoutPoint(xpos, ypos)
{}
//---------------------------------------------------------------------------------------------------------------------
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>
auto Reverse(const QVector<T> &container) -> QVector<T>
inline auto Reverse(const QVector<T> &container) -> QVector<T>
{
if (container.isEmpty())
{
@ -216,14 +216,14 @@ auto Reverse(const QVector<T> &container) -> QVector<T>
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)));
}
//---------------------------------------------------------------------------------------------------------------------
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);
}

View file

@ -33,7 +33,6 @@
#include "../ifc/exception/vexceptioninvalidnotch.h"
#include "../vgeometry/vabstractcurve.h"
#include "../vgeometry/varc.h"
#include "testpassmark.h"
#include "../vlayout/vrawsapoint.h"
const qreal VPassmark::passmarkRadiusFactor = 0.45;
@ -53,7 +52,7 @@ PassmarkStatus GetSeamPassmarkSAPoint(const VPiecePassmarkData &passmarkData, co
if (needRollback && not seamAllowance.isEmpty())
{
ekvPoints.clear();
ekvPoints += seamAllowance.at(seamAllowance.size()-2);
ekvPoints += VRawSAPoint(seamAllowance.at(seamAllowance.size()-2));
}
if (ekvPoints.isEmpty())
@ -726,7 +725,7 @@ QVector<QLineF> VPassmark::SAPassmark(const VPiece &piece, const VContainer *dat
if (not piece.IsSeamAllowanceBuiltIn())
{
// 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>();
@ -801,8 +800,8 @@ QVector<QLineF> VPassmark::BuiltInSAPassmark(const VPiece &piece, const VContain
return QVector<QLineF>();
}
return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, lines, piece.MainPathPoints(data),
PassmarkSide::All);
return CreatePassmarkLines(m_data.passmarkLineType, m_data.passmarkAngleType, lines,
CastTo<QPointF>(piece.MainPathPoints(data)), PassmarkSide::All);
}
//---------------------------------------------------------------------------------------------------------------------
@ -868,7 +867,8 @@ QVector<QLineF> VPassmark::SAPassmarkBaseLine(const VPiece &piece, const VContai
if (not piece.IsSeamAllowanceBuiltIn())
{
// 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>();

View file

@ -32,7 +32,7 @@
#include "../vgeometry/vpointf.h"
#include "../vgeometry/vabstractcurve.h"
#include "../vgeometry/vplacelabelitem.h"
#include "../vgeometry/varc.h"
#include "../vgeometry/vlayoutplacelabel.h"
#include "vcontainer.h"
#include "../vmisc/vabstractvalapplication.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
VPiecePath mainPath = GetPath();
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
// 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
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);
}
@ -208,14 +208,12 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VPiece::CuttingPathPoints(const VContainer *data) const
{
if (IsSeamAllowance() and not IsSeamAllowanceBuiltIn())
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{
return SeamAllowancePoints(data);
}
else
{
return MainPathPoints(data);
return CastTo<QPointF>(SeamAllowancePoints(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
{
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));
}
//---------------------------------------------------------------------------------------------------------------------
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
{
@ -370,7 +332,7 @@ QPainterPath VPiece::PlaceLabelPath(const VContainer *data) const
const auto label = data->GeometricObject<VPlaceLabelItem>(placeLabel);
if (label->IsVisible())
{
path.addPath(label->LabelShapePath());
path.addPath(LabelShapePath(VLayoutPlaceLabel(*label)));
}
}
catch (const VExceptionBadId &e)
@ -387,12 +349,11 @@ bool VPiece::IsSeamAllowanceValid(const VContainer *data) const
{
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
{
return VAbstractPiece::IsAllowanceValid(UniteMainPathPoints(data), SeamAllowancePoints(data));
}
else
{
return true;
return VAbstractPiece::IsAllowanceValid(CastTo<QPointF>(UniteMainPathPoints(data)),
CastTo<QPointF>(SeamAllowancePoints(data)));
}
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);
if (not IsSeamAllowance() || IsSeamAllowanceBuiltIn())
{
return QVector<QPointF>();
return {};
}
const QVector<CustomSARecord> records = FilterRecords(GetValidRecords());

View file

@ -33,7 +33,6 @@
#include <QSharedDataPointer>
#include "../vlayout/vabstractpiece.h"
#include "../vgeometry/vgeometrydef.h"
class VPieceData;
class VPieceNode;
@ -65,10 +64,10 @@ public:
VPiecePath &GetPath();
void SetPath(const VPiecePath &path);
QVector<QPointF> MainPathPoints(const VContainer *data) const;
QVector<QPointF> UniteMainPathPoints(const VContainer *data) const;
QVector<VLayoutPoint> MainPathPoints(const VContainer *data) const;
QVector<VLayoutPoint> UniteMainPathPoints(const VContainer *data) 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<QLineF> PassmarksLines(const VContainer *data) const;
@ -80,7 +79,8 @@ public:
static QPainterPath MainPathPath(const QVector<QPointF> &points);
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 PlaceLabelPath(const VContainer *data) const;
@ -132,7 +132,7 @@ public:
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);
auto GetGradationLabel() const -> QString;
@ -167,4 +167,41 @@ private:
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

View file

@ -36,9 +36,6 @@
#include <QDataStream>
#include <QtNumeric>
const quint32 VPieceNodeData::streamHeader = 0x2198CBC8; // CRC-32Q string "VPieceNodeData"
const quint16 VPieceNodeData::classVersion = 1;
//---------------------------------------------------------------------------------------------------------------------
VPieceNode::VPieceNode()
: d(new VPieceNodeData)
@ -454,6 +451,18 @@ void VPieceNode::SetManualPassmarkLength(bool 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
{

View file

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

View file

@ -63,24 +63,7 @@ public:
}
}
VPieceNodeData (const VPieceNodeData& node)
: 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 (const VPieceNodeData& node) = default;
~VPieceNodeData() = default;
@ -124,11 +107,13 @@ public:
bool m_manualPassmarkLength{false};
bool m_turnPoint{true};
private:
Q_DISABLE_ASSIGN(VPieceNodeData)
static const quint32 streamHeader;
static const quint16 classVersion;
static constexpr quint32 streamHeader = 0x2198CBC8; // CRC-32Q string "VPieceNodeData"
static constexpr quint16 classVersion = 2;
};
// Friend functions
@ -155,6 +140,8 @@ QDataStream &operator<<(QDataStream &out, const VPieceNodeData &p)
// Added in classVersion = 2
out << p.m_turnPoint;
return out;
}
@ -199,10 +186,10 @@ QDataStream &operator>>(QDataStream &in, VPieceNodeData &p)
>> p.m_checkUniqueness
>> p.m_manualPassmarkLength;
// if (actualClassVersion >= 2)
// {
// }
if (actualClassVersion >= 2)
{
in >> p.m_turnPoint;
}
return in;
}

View file

@ -30,7 +30,6 @@
#include "vpiecepath_p.h"
#include "vcontainer.h"
#include "../vgeometry/vpointf.h"
#include "../vlayout/vabstractpiece.h"
#include "calculator.h"
#include "../vmisc/vabstractvalapplication.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.SetSABefore(node.GetSABefore(data, *data->GetPatternUnit()));
candidate.SetAngleType(node.GetAngleType());
candidate.SetTurnPoint(node.IsTurnPoint());
}
}
return candidate;
@ -92,6 +92,7 @@ VSAPoint CurveStartPoint(VSAPoint candidate, const VContainer *data, const VPiec
}
candidate = VSAPoint(p);
candidate.SetTurnPoint(true);
break;
}
@ -131,6 +132,7 @@ VSAPoint CurveEndPoint(VSAPoint candidate, const VContainer *data, const VPieceN
}
candidate = VSAPoint(p);
candidate.SetTurnPoint(true);
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)
{
return 0;
}
const QPointF &first = ConstFirst(points);
const T &first = ConstFirst(points);
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,
QPointF *firstConnection)
bool IntersectionWithCuttingCountour(const QVector<QPointF> &cuttingPath, const QVector<VLayoutPoint> &points,
QPointF *connection)
{
if (points.size() <= 1)
{
@ -207,12 +210,35 @@ bool IntersectionWithCuttingCountour(const QVector<QPointF> &cuttingPath, const
if (VAbstractCurve::IsPointOnCurve(cuttingPath, first))
{ // Point is already part of a cutting countour
*firstConnection = first;
*connection = first;
return true;
}
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)
{
QVector<QPointF> extended = points;
QVector<VLayoutPoint> extended = points;
if (IsFirstToCuttingCountour())
{
QPointF firstConnection;
VLayoutPoint firstConnection;
if (IntersectionWithCuttingCountour(cuttingPath, points, &firstConnection))
{
firstConnection.SetTurnPoint(true);
extended.prepend(firstConnection);
}
else
@ -415,9 +442,10 @@ QVector<QPointF> VPiecePath::PathPoints(const VContainer *data, const QVector<QP
if (IsLastToCuttingCountour())
{
QPointF lastConnection;
VLayoutPoint lastConnection;
if (IntersectionWithCuttingCountour(cuttingPath, Reverse(points), &lastConnection))
{
lastConnection.SetTurnPoint(true);
extended.append(lastConnection);
}
else
@ -542,7 +570,7 @@ QVector<VSAPoint> VPiecePath::SeamAllowancePoints(const VContainer *data, qreal
//---------------------------------------------------------------------------------------------------------------------
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());
VSAPoint p(point->toQPointF());
p.SetTurnPoint(node.IsTurnPoint());
p.SetSAAfter(node.GetSAAfter(data, *data->GetPatternUnit()));
p.SetSABefore(node.GetSABefore(data, *data->GetPatternUnit()));
p.SetAngleType(node.GetAngleType());
@ -1138,18 +1167,23 @@ QVector<VSAPoint> VPiecePath::CurveSeamAllowanceSegment(const VContainer *data,
{
VSAPoint p(points.at(i));
p.SetAngleType(PieceNodeAngle::ByLengthCurve);
p.SetCurvePoint(true);
if (i == 0)
{ // first point
p.SetSAAfter(begin.GetSAAfter());
p.SetSABefore(begin.GetSABefore());
p.SetAngleType(begin.GetAngleType());
p.SetTurnPoint(VFuzzyComparePoints(p, begin) ? begin.TurnPoint() : true);
}
else if (i == points.size() - 1)
{ // last point
p.SetSAAfter(end.GetSAAfter());
p.SetSABefore(end.GetSABefore());
p.SetAngleType(end.GetAngleType());
p.SetTurnPoint(VFuzzyComparePoints(p, end) ? end.TurnPoint() : true);
}
pointsEkv.append(p);
}
}
@ -1165,13 +1199,15 @@ QVector<VSAPoint> VPiecePath::CurveSeamAllowanceSegment(const VContainer *data,
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);
VSAPoint p(points.at(0));//First point in the list
p.SetSAAfter(begin.GetSAAfter());
p.SetSABefore(begin.GetSABefore());
p.SetAngleType(begin.GetAngleType());
p.SetCurvePoint(true);
p.SetTurnPoint(VFuzzyComparePoints(p, begin) ? begin.TurnPoint() : true);
pointsEkv.append(p);
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)
{
p = VSAPoint(points.at(i));
p.SetCurvePoint(true);
if (i == points.size() - 1)
{// last point
p.SetSAAfter(end.GetSAAfter());
p.SetSABefore(end.GetSABefore());
p.SetAngleType(end.GetAngleType());
p.SetTurnPoint(VFuzzyComparePoints(p, end) ? end.TurnPoint() : true);
}
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,
const QString &piece)
QVector<VLayoutPoint> VPiecePath::NodesToPoints(const VContainer *data, const QVector<VPieceNode> &nodes,
const QString &piece)
{
QVector<QPointF> points;
QVector<VLayoutPoint> points;
for (int i = 0; i < nodes.size(); ++i)
{
const VPieceNode &node = nodes.at(i);
@ -1241,7 +1279,9 @@ QVector<QPointF> VPiecePath::NodesToPoints(const VContainer *data, const QVector
case (Tool::NodePoint):
{
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;
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 VSAPoint begin = StartSegment(data, nodes, i);
const VSAPoint end = EndSegment(data, nodes, i);
const QPointF begin = StartSegment(data, nodes, i);
const QPointF end = EndSegment(data, nodes, i);
points << curve->GetSegmentPoints(begin, end, node.GetReverse(), piece);
QVector<QPointF> segment = curve->GetSegmentPoints(begin, end, node.GetReverse(), piece);
AppendCurveSegment(points, segment, begin, end);
}
break;
default:

View file

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

View file

@ -46,17 +46,14 @@
#include <QVector>
#include <QtGlobal>
#include <QLineF>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include "vsysexits.h"
#include "../vgeometry/vgobject.h"
#include "../vgeometry/vpointf.h"
#include "../vgeometry/vspline.h"
#include "../vgeometry/vsplinepath.h"
#include "../vlayout/vabstractpiece.h"
#include "../vlayout/vrawsapoint.h"
#include "../vpatterndb/vcontainer.h"
#include "../vpatterndb/vpiece.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)
{
@ -217,17 +116,22 @@ void AbstractTest::PassmarkDataFromJson(const QString &json, VPiecePassmarkData
QJsonObject passmarkData = dataObject[dataKey].toObject();
VSAPoint previousSAPoint;
SAPointFromJson(passmarkData[QStringLiteral("previousSAPoint")].toObject(), previousSAPoint);
data.previousSAPoint = previousSAPoint;
try
{
auto previousSAPoint = PointFromJson<VSAPoint>(passmarkData[QStringLiteral("previousSAPoint")].toObject());
data.previousSAPoint = previousSAPoint;
VSAPoint passmarkSAPoint;
SAPointFromJson(passmarkData[QStringLiteral("passmarkSAPoint")].toObject(), passmarkSAPoint);
data.passmarkSAPoint = passmarkSAPoint;
auto passmarkSAPoint = PointFromJson<VSAPoint>(passmarkData[QStringLiteral("passmarkSAPoint")].toObject());
data.passmarkSAPoint = passmarkSAPoint;
VSAPoint nextSAPoint;
SAPointFromJson(passmarkData[QStringLiteral("nextSAPoint")].toObject(), nextSAPoint);
data.nextSAPoint = nextSAPoint;
auto nextSAPoint = PointFromJson<VSAPoint>(passmarkData[QStringLiteral("nextSAPoint")].toObject());
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;
AbstractTest::ReadDoubleValue(passmarkData, QStringLiteral("saWidth"), saWidth);
@ -287,28 +191,26 @@ void AbstractTest::PassmarkShapeFromJson(const QString &json, QVector<QLineF> &s
TestRoot(shapeObject, shapeKey, json);
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;
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'.")
.arg(json, lineObject[typeKey].toString());
QFAIL(qUtf8Printable(error));
}
QLineF line;
QLineFromJson(lineObject, line);
shape.append(line);
shape.append(QLineFromJson(lineObject));
}
}
//---------------------------------------------------------------------------------------------------------------------
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
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++)
{
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.")
.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
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);
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))
{
@ -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,
const QString &defaultValue) const
const QString &defaultValue)
{
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,
const QString &defaultValue) const
const QString &defaultValue)
{
if (itemObject.contains(attribute))
{
@ -624,8 +526,7 @@ void AbstractTest::ReadPointValue(const QJsonObject &itemObject, const QString &
{
if (itemObject.contains(attribute))
{
QJsonObject p1Object = itemObject[attribute].toObject();
VPointFromJson(p1Object, value);
value = PointFromJson<VPointF>(itemObject[attribute].toObject());
}
else
{
@ -706,22 +607,11 @@ void AbstractTest::ReadPieceNodeValue(const QJsonObject &itemObject, VPieceNode
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*>
void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue) const
const QString &defaultValue)
{
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*>
void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue) const
const QString &defaultValue)
{
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*>
void AbstractTest::ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue) const
const QString &defaultValue)
{
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;
AbstractTest::ReadDoubleValue(itemObject, QStringLiteral("id"), id);
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);
return {PointFromJson<QPointF>(itemObject[QStringLiteral("p1")].toObject()),
PointFromJson<QPointF>(itemObject[QStringLiteral("p2")].toObject())};
}
//---------------------------------------------------------------------------------------------------------------------
@ -999,8 +818,7 @@ void AbstractTest::DBFromJson(const QJsonObject &dbObject, QSharedPointer<VConta
{
case GOType::Point:
{
VPointF point;
VPointFromJson(itemObject, point);
VPointF point = PointFromJson<VPointF>(itemObject);
data->UpdateGObject(point.id(), new VPointF(point));
break;
}

View file

@ -32,9 +32,17 @@
#include <QMetaObject>
#include <QObject>
#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;
class VSAPoint;
#include <ciso646>
@ -69,9 +77,8 @@ class AbstractTest : public QObject
public:
explicit AbstractTest(QObject *parent = nullptr);
void VectorFromJson(const QString &json, QVector<QPointF>& vector) const;
void VectorFromJson(const QString &json, QVector<VSAPoint>& vector) const;
void VectorFromJson(const QString &json, QVector<VRawSAPoint>& vector) const;
template <class T>
static auto VectorFromJson(const QString &json) -> QVector<T>;
void PieceFromJson(const QString &json, VPiece &piece, QSharedPointer<VContainer> &data);
@ -79,45 +86,50 @@ public:
void PassmarkShapeFromJson(const QString &json, QVector<QLineF> &shape);
protected:
void Comparison(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const;
void Comparison(const QPointF &result, const QPointF &expected, qreal testAccuracy) const;
void Comparison(const QVector<QLineF> &result, const QVector<QLineF> &expected) const;
void ComparePathsDistance(const QVector<QPointF> &ekv, const QVector<QPointF> &ekvOrig) const;
void ComparePointsDistance(const QPointF &result, const QPointF &expected, qreal testAccuracy) const;
void CompareLinesDistance(const QVector<QLineF> &result, const QVector<QLineF> &expected) const;
QString ValentinaPath() const;
QString TapePath() const;
QString TranslationsPath() const;
auto ValentinaPath() const -> QString;
auto TapePath() const -> QString;
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);
bool CopyRecursively(const QString &srcFilePath, const QString &tgtFilePath) const;
auto Run(int exit, const QString &program, const QStringList &arguments, QString &error, int msecs = 120000) -> int;
auto CopyRecursively(const QString &srcFilePath, const QString &tgtFilePath) const -> bool;
void PrepareDocument(const QString &json, QByteArray &data) const;
void TestRoot(const QJsonObject &root, const QString &attribute, const QString &file) const;
static void PrepareDocument(const QString &json, QByteArray &data);
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>
void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString()) const;
static void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString());
template <typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString()) const;
static void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString());
template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString()) const;
void ReadStringValue(const QJsonObject &itemObject, const QString &attribute, QString &value,
const QString &defaultValue = QString()) const;
void ReadBooleanValue(const QJsonObject &itemObject, const QString &attribute, bool &value,
const QString &defaultValue = QString()) const;
static void ReadDoubleValue(const QJsonObject &itemObject, const QString &attribute, T &value,
const QString &defaultValue = QString());
static void ReadStringValue(const QJsonObject &itemObject, const QString &attribute, QString &value,
const QString &defaultValue = QString());
static void ReadBooleanValue(const QJsonObject &itemObject, const QString &attribute, bool &value,
const QString &defaultValue = QString());
void ReadPointValue(const QJsonObject &itemObject, const QString &attribute, VPointF &value);
void ReadSplinePointValues(const QJsonObject &itemObject, const QString &attribute, QVector<VSplinePoint> &points);
void ReadSplinePointValue(const QJsonObject &itemObject, VSplinePoint &point);
void ReadPieceNodeValue(const QJsonObject &itemObject, VPieceNode &node);
void QPointFromJson(const QJsonObject &itemObject, QPointF &point) const;
void VPointFromJson(const QJsonObject &itemObject, VPointF &point);
void QLineFromJson(const QJsonObject &itemObject, QLineF &line);
void SAPointFromJson(const QJsonObject &itemObject, VSAPoint &point) const;
void RawSAPointFromJson(const QJsonObject &itemObject, VRawSAPoint &point) const;
template <class T>
static void CheckClassType(const QJsonObject &itemObject);
template <class T>
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 SplinePathFromJson(const QJsonObject &itemObject, QSharedPointer<VContainer> &data);
@ -125,4 +137,168 @@ protected:
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

View file

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

View file

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

View file

@ -52,7 +52,7 @@ void VisToolPiece::RefreshGeometry()
if (GetMode() == Mode::Creation)
{
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);
}
else

View file

@ -31,6 +31,7 @@
#include "../vgeometry/vpointf.h"
#include "../vwidgets/scalesceneitems.h"
#include "../vmisc/compatibility.h"
#include "../vlayout/vlayoutpoint.h"
#include <QGraphicsSceneMouseEvent>
@ -63,7 +64,7 @@ void VisToolPiecePath::RefreshGeometry()
if (GetMode() == Mode::Creation)
{
const QVector<QPointF> points = m_path.PathPoints(GetData());
const QVector<VLayoutPoint> points = m_path.PathPoints(GetData());
if (not points.empty())
{
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<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);
Comparison(p1, expectP1, accuracyPointOnLine);
Comparison(p2, expectP2, accuracyPointOnLine);
ComparePointsDistance(p1, expectP1, accuracyPointOnLine);
ComparePointsDistance(p2, expectP2, accuracyPointOnLine);
}
//---------------------------------------------------------------------------------------------------------------------
@ -239,7 +239,7 @@ void TST_FindPoint::TestLineIntersectAxis()
QPointF resultPoint;
VToolLineIntersectAxis::FindPoint(axis, line, &resultPoint);
Comparison(resultPoint, point, accuracyPointOnLine);
ComparePointsDistance(resultPoint, point, accuracyPointOnLine);
}
//---------------------------------------------------------------------------------------------------------------------
@ -272,7 +272,7 @@ void TST_FindPoint::TestTriangle()
QPointF 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);
Comparison(point, resultPoint, accuracyPointOnLine);
ComparePointsDistance(point, resultPoint, accuracyPointOnLine);
}
//---------------------------------------------------------------------------------------------------------------------
@ -745,5 +745,5 @@ void TST_FindPoint::TestCurveIntersectAxis()
QPointF 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)
{
QVector<QPointF> points;
AbstractTest::VectorFromJson(input, points);
QVector<QPointF> intersections;
AbstractTest::VectorFromJson(output, intersections);
QVector<QPointF> points = AbstractTest::VectorFromJson<QPointF>(input);
QVector<QPointF> intersections = AbstractTest::VectorFromJson<QPointF>(output);
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)
{
QVector<VSAPoint> inputPoints;
AbstractTest::VectorFromJson(input, inputPoints);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QVector<VSAPoint> inputPoints = AbstractTest::VectorFromJson<VSAPoint>(input);
QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QTest::newRow(title) << inputPoints << width << outputPoints;
};
@ -312,10 +308,10 @@ void TST_VAbstractPiece::EquidistantRemoveLoop() const
QFETCH(qreal, width);
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
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)
{
QVector<VSAPoint> inputPoints;
AbstractTest::VectorFromJson(input, inputPoints);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QVector<VSAPoint> inputPoints = AbstractTest::VectorFromJson<VSAPoint>(input);
QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QTest::newRow(title) << inputPoints << width << outputPoints;
};
@ -368,10 +360,10 @@ void TST_VAbstractPiece::LayoutAllowanceRemoveLoop() const
QFETCH(qreal, width);
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
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)
{
QVector<VRawSAPoint> inputPoints;
AbstractTest::VectorFromJson(input, inputPoints);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QVector<VRawSAPoint> inputPoints = AbstractTest::VectorFromJson<VRawSAPoint>(input);
QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QTest::newRow(title) << inputPoints << outputPoints;
};
@ -414,8 +402,8 @@ void TST_VAbstractPiece::RawPathRemoveLoop() const
QFETCH(QVector<VRawSAPoint>, path);
QFETCH(QVector<QPointF>, expect);
QVector<QPointF> res = VAbstractPiece::CheckLoops(path);
Comparison(res, expect);
QVector<QPointF> res = CastTo<QPointF>(VAbstractPiece::CheckLoops(path));
ComparePathsDistance(res, expect);
}
//---------------------------------------------------------------------------------------------------------------------
@ -688,7 +676,7 @@ void TST_VAbstractPiece::PathRemoveLoop() const
QFETCH(QVector<QPointF>, expect);
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);
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)
{
QVector<VSAPoint> inputPoints;
AbstractTest::VectorFromJson(input, inputPoints);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QVector<VSAPoint> inputPoints = AbstractTest::VectorFromJson<VSAPoint>(input);
QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QTest::newRow(title) << inputPoints << width << outputPoints;
};
@ -978,10 +962,10 @@ void TST_VAbstractPiece::BrokenDetailEquidistant() const
QFETCH(qreal, width);
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
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)
{
QVector<VSAPoint> inputPoints;
AbstractTest::VectorFromJson(input, inputPoints);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QVector<VSAPoint> inputPoints = AbstractTest::VectorFromJson<VSAPoint>(input);
QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QTest::newRow(title) << inputPoints << width << outputPoints;
};
@ -1094,10 +1074,10 @@ void TST_VAbstractPiece::EquidistantAngleType() const
QFETCH(qreal, width);
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
Comparison(ekv, ekvOrig);
ComparePathsDistance(ekv, ekvOrig);
}
//---------------------------------------------------------------------------------------------------------------------
@ -1134,7 +1114,7 @@ void TST_VAbstractPiece::CorrectEquidistantPoints() const
const QVector<QPointF> res = VAbstractPiece::CorrectEquidistantPoints(points, removeFirstAndLast);
// 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)
{
QVector<QPointF> inputPoints;
AbstractTest::VectorFromJson(input, inputPoints);
QVector<QPointF> outputPoints;
AbstractTest::VectorFromJson(output, outputPoints);
QVector<QPointF> inputPoints = AbstractTest::VectorFromJson<QPointF>(input);
QVector<QPointF> outputPoints = AbstractTest::VectorFromJson<QPointF>(output);
QTest::newRow(title) << inputPoints << outputPoints;
};
@ -1172,7 +1148,7 @@ void TST_VAbstractPiece::TestCorrectEquidistantPoints() const
QFETCH(QVector<QPointF>, expect);
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);
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)
{
QVector<QPointF> basePoints;
AbstractTest::VectorFromJson(base, basePoints);
QVector<QPointF> allowancePoints;
AbstractTest::VectorFromJson(allowance, allowancePoints);
QVector<QPointF> basePoints = AbstractTest::VectorFromJson<QPointF>(base);
QVector<QPointF> allowancePoints = AbstractTest::VectorFromJson<QPointF>(allowance);
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);
QCOMPARE(found, result);
Comparison(intersectionPoint, crosPoint, accuracyPointOnLine);
ComparePointsDistance(intersectionPoint, crosPoint, accuracyPointOnLine);
}
//---------------------------------------------------------------------------------------------------------------------
@ -466,6 +466,6 @@ void TST_VArc::EmptyArc()
{
VArc empty;
Comparison(empty.GetPoints(), {QPointF()});
ComparePathsDistance(empty.GetPoints(), {QPointF()});
QCOMPARE(empty.GetLength(), 0.);
}

View file

@ -477,8 +477,8 @@ void TST_VEllipticalArc::TestGetPoints5()
if (points.size() > 2 && qFuzzyIsNull(rotationAngle))
{
const qreal testAccuracy = ToPixel(1.5, Unit::Mm);
Comparison(arc.GetP1(), ConstFirst(points), testAccuracy);
Comparison(arc.GetP2(), ConstLast(points), testAccuracy);
ComparePointsDistance(arc.GetP1(), ConstFirst(points), testAccuracy);
ComparePointsDistance(arc.GetP2(), ConstLast(points), testAccuracy);
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
VLayoutPiece det = VLayoutPiece();
det.SetCountourPoints(InputPointsCase1());
det.SetCountourPoints(CastTo<VLayoutPoint>(InputPointsCase1()));
// 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
{
VLayoutPiece det = VLayoutPiece();
det.SetCountourPoints(InputPointsCase2());
det.SetCountourPoints(CastTo<VLayoutPoint>(InputPointsCase2()));
// 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
{
VLayoutPiece det = VLayoutPiece();
det.SetCountourPoints(InputPointsCase3());
det.SetCountourPoints(CastTo<VLayoutPoint>(InputPointsCase3()));
// Begin comparison
Comparison(det.GetMappedContourPoints(), OutputPointsCase3());
ComparePathsDistance(CastTo<QPointF>(det.GetMappedContourPoints()), OutputPointsCase3());
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -53,13 +53,11 @@ void TST_VPiece::Issue620()
VPiece detail;
AbstractTest::PieceFromJson(QStringLiteral("://Issue_620/input.json"), detail, data);
const QVector<QPointF> pointsEkv = detail.MainPathPoints(data.data());
QVector<QPointF> origPoints;
AbstractTest::VectorFromJson(QStringLiteral("://Issue_620/output.json"), origPoints);
const QVector<QPointF> pointsEkv = CastTo<QPointF>(detail.MainPathPoints(data.data()));
QVector<QPointF> origPoints = AbstractTest::VectorFromJson<QPointF>(QStringLiteral("://Issue_620/output.json"));
// Begin comparison
Comparison(pointsEkv, origPoints);
ComparePathsDistance(pointsEkv, origPoints);
}
//---------------------------------------------------------------------------------------------------------------------
@ -78,8 +76,7 @@ void TST_VPiece::TestSAPassmark_data()
VPiecePassmarkData inputPassmarkData;
AbstractTest::PassmarkDataFromJson(passmarkData, inputPassmarkData);
QVector<QPointF> inputSeamAllowance;
AbstractTest::VectorFromJson(seamAllowance, inputSeamAllowance);
QVector<QPointF> inputSeamAllowance = AbstractTest::VectorFromJson<QPointF>(seamAllowance);
QVector<QLineF> inputOutputShape;
AbstractTest::PassmarkShapeFromJson(shape, inputOutputShape);
@ -105,5 +102,5 @@ void TST_VPiece::TestSAPassmark()
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));
// Begin comparison
Comparison(points, origPoints);
ComparePathsDistance(points, origPoints);
}
//---------------------------------------------------------------------------------------------------------------------
@ -251,7 +251,7 @@ void TST_VSpline::GetSegmentPoints_issue412()
origPoints.append(QPointF(758.4176810783842, 206.13572832247544));
// Begin comparison
Comparison(points, origPoints);
ComparePathsDistance(points, origPoints);
}
//---------------------------------------------------------------------------------------------------------------------
@ -370,7 +370,7 @@ void TST_VSpline::GetSegmentPoints_TestPuzzle()
origPoints.append(QPointF(957.69883966, 943.844812978));
// Begin comparison
Comparison(points, origPoints);
ComparePathsDistance(points, origPoints);
}
//---------------------------------------------------------------------------------------------------------------------
@ -525,7 +525,7 @@ void TST_VSpline::GetSegmentPoints_NullSegment()
origPoints.append(QPointF(146.3718263928647, 6.419281580065625));
// Begin comparison
Comparison(points, origPoints);
ComparePathsDistance(points, origPoints);
}
//---------------------------------------------------------------------------------------------------------------------
@ -627,7 +627,7 @@ void TST_VSpline::GetSegmentPoints_RotateTool()
origPoints.append(QPointF(46.623829088412336, 167.78988631718659));
// Begin comparison
Comparison(points, origPoints);
ComparePathsDistance(points, origPoints);
}
//---------------------------------------------------------------------------------------------------------------------
@ -687,7 +687,7 @@ void TST_VSpline::GetSegmentPoints_issue767()
origPoints.append(QPointF(4200.083592082314, 2559.5684873884893));
// 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());
// Compare points
Comparison(spl1.GetPoints(), spl2.GetPoints());
ComparePathsDistance(spl1.GetPoints(), spl2.GetPoints());
}