New feature. Boundary together with notches.

This commit is contained in:
Roman Telezhynskyi 2023-11-28 16:40:27 +02:00
parent fef322116b
commit 5724c9611a
72 changed files with 2670 additions and 692 deletions

View File

@ -58,6 +58,7 @@
- Adding removing nodes of curved path. - Adding removing nodes of curved path.
- New tools: Arc start point, Arc end point. - New tools: Arc start point, Arc end point.
- Optimize U-notch shape. - Optimize U-notch shape.
- New feature. Boundary together with notches.
# Valentina 0.7.52 September 12, 2022 # Valentina 0.7.52 September 12, 2022
- Fix crash when default locale is ru. - Fix crash when default locale is ru.

View File

@ -1,6 +1,6 @@
.\" Manpage for valentina. .\" Manpage for valentina.
.\" Contact dismine@gmail.com to correct errors. .\" Contact dismine@gmail.com to correct errors.
.TH valentina 1 "July 10, 2023" "valentina man page" .TH valentina 1 "28 November, 2023" "valentina man page"
.SH NAME .SH NAME
Valentina \- Pattern making program. Valentina \- Pattern making program.
.SH SYNOPSIS .SH SYNOPSIS
@ -199,6 +199,8 @@ The path to output destination folder. By default the directory at which the app
.RB "Unite pages if possible (" "export mode" "). Maximum value limited by QImage that supports only a maximum of " "32768x32768 px" " images." .RB "Unite pages if possible (" "export mode" "). Maximum value limited by QImage that supports only a maximum of " "32768x32768 px" " images."
.IP "--preferOneSheetSolution" .IP "--preferOneSheetSolution"
.RB "Prefer one sheet layout solution (" "export mode" ")." .RB "Prefer one sheet layout solution (" "export mode" ")."
.IP "--boundaryTogetherWithNotches"
.RB "Export boundary together with notches (" "export mode" ")."
.IP "-S, --savelen" .IP "-S, --savelen"
.RB "Save length of the sheet if set (" "export mode" "). The option tells the program to use as much as possible width of sheet. Quality of a layout can be worse when this option was used." .RB "Save length of the sheet if set (" "export mode" "). The option tells the program to use as much as possible width of sheet. Quality of a layout can be worse when this option was used."
.IP "-l, --layounits <The unit>" .IP "-l, --layounits <The unit>"

View File

@ -1,6 +1,6 @@
.\" Manpage for valentina. .\" Manpage for valentina.
.\" Contact dismine@gmail.com to correct errors. .\" Contact dismine@gmail.com to correct errors.
.TH valentina 1 "July 10, 2023" "valentina man page" .TH valentina 1 "28 November, 2023" "valentina man page"
.SH NAME .SH NAME
Valentina \- Pattern making program. Valentina \- Pattern making program.
.SH SYNOPSIS .SH SYNOPSIS
@ -199,6 +199,8 @@ The path to output destination folder. By default the directory at which the app
.RB "Unite pages if possible (" "export mode" "). Maximum value limited by QImage that supports only a maximum of " "32768x32768 px" " images." .RB "Unite pages if possible (" "export mode" "). Maximum value limited by QImage that supports only a maximum of " "32768x32768 px" " images."
.IP "--preferOneSheetSolution" .IP "--preferOneSheetSolution"
.RB "Prefer one sheet layout solution (" "export mode" ")." .RB "Prefer one sheet layout solution (" "export mode" ")."
.IP "--boundaryTogetherWithNotches"
.RB "Export boundary together with notches (" "export mode" ")."
.IP "-S, --savelen" .IP "-S, --savelen"
.RB "Save length of the sheet if set (" "export mode" "). The option tells the program to use as much as possible width of sheet. Quality of a layout can be worse when this option was used." .RB "Save length of the sheet if set (" "export mode" "). The option tells the program to use as much as possible width of sheet. Quality of a layout can be worse when this option was used."
.IP "-l, --layounits <The unit>" .IP "-l, --layounits <The unit>"

View File

@ -259,6 +259,12 @@ void VPCarrousel::SetOrientation(Qt::Orientation orientation)
RefreshOrientation(); RefreshOrientation();
} }
//---------------------------------------------------------------------------------------------------------------------
void VPCarrousel::RefreshPieceMiniature()
{
ui->listWidget->Refresh();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPCarrousel::RefreshOrientation() void VPCarrousel::RefreshOrientation()
{ {

View File

@ -68,6 +68,8 @@ public:
*/ */
void SetOrientation(Qt::Orientation orientation); void SetOrientation(Qt::Orientation orientation);
void RefreshPieceMiniature();
/** /**
* @brief RefreshOrientation Refreshes the orientation of the carrousel with the * @brief RefreshOrientation Refreshes the orientation of the carrousel with the
* m_orientation value; * m_orientation value;

View File

@ -32,6 +32,7 @@
#include <QMenu> #include <QMenu>
#include <QPainter> #include <QPainter>
#include "../layout/vplayout.h"
#include "../layout/vppiece.h" #include "../layout/vppiece.h"
#include "../vmisc/theme/vscenestylesheet.h" #include "../vmisc/theme/vscenestylesheet.h"
@ -139,7 +140,14 @@ auto VPCarrouselPiece::CreatePieceIcon(const QSize &size, bool isDragIcon) const
painter.setBrush(QBrush(iconMode == QIcon::Selected ? style.CarrouselPieceSelectedColor() painter.setBrush(QBrush(iconMode == QIcon::Selected ? style.CarrouselPieceSelectedColor()
: style.CarrouselPieceForegroundColor())); : style.CarrouselPieceForegroundColor()));
piece->DrawMiniature(painter); bool togetherWithNotches = false;
VPLayoutPtr pieceLayout = piece->Layout();
if (not pieceLayout.isNull())
{
togetherWithNotches = pieceLayout->LayoutSettings().IsBoundaryTogetherWithNotches();
}
piece->DrawMiniature(painter, togetherWithNotches);
painter.end(); painter.end();

View File

@ -106,6 +106,7 @@ signals:
void PieceSheetChanged(const VPPiecePtr &piece); void PieceSheetChanged(const VPPiecePtr &piece);
void ActiveSheetChanged(const VPSheetPtr &focusedSheet); void ActiveSheetChanged(const VPSheetPtr &focusedSheet);
void PieceTransformationChanged(const VPPiecePtr &piece); void PieceTransformationChanged(const VPPiecePtr &piece);
void BoundaryTogetherWithNotchesChanged(const VPPiecePtr &piece);
void PieceZValueChanged(const VPPiecePtr &piece); void PieceZValueChanged(const VPPiecePtr &piece);
void TransformationOriginChanged(); void TransformationOriginChanged();
void SheetListChanged(); void SheetListChanged();

View File

@ -113,10 +113,8 @@ void VPLayoutSettings::SetTilesSize(const QSizeF &size)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutSettings::SetTilesSizeConverted(const QSizeF &size) void VPLayoutSettings::SetTilesSizeConverted(const QSizeF &size)
{ {
m_tilesSize = QSizeF( m_tilesSize =
UnitConvertor(size.width(), GetUnit(), Unit::Px), QSizeF(UnitConvertor(size.width(), GetUnit(), Unit::Px), UnitConvertor(size.height(), GetUnit(), Unit::Px));
UnitConvertor(size.height(), GetUnit(), Unit::Px)
);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -134,8 +132,7 @@ auto VPLayoutSettings::GetTilesSize() const -> QSizeF
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPLayoutSettings::GetTilesSize(Unit unit) const -> QSizeF auto VPLayoutSettings::GetTilesSize(Unit unit) const -> QSizeF
{ {
return {UnitConvertor(m_tilesSize.width(), Unit::Px, unit), return {UnitConvertor(m_tilesSize.width(), Unit::Px, unit), UnitConvertor(m_tilesSize.height(), Unit::Px, unit)};
UnitConvertor(m_tilesSize.height(), Unit::Px, unit)};
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -240,7 +237,6 @@ auto VPLayoutSettings::GetPiecesGapConverted() const -> qreal
return UnitConvertor(m_piecesGap, Unit::Px, m_unit); return UnitConvertor(m_piecesGap, Unit::Px, m_unit);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutSettings::SetStickyEdges(bool state) void VPLayoutSettings::SetStickyEdges(bool state)
{ {
@ -396,3 +392,15 @@ void VPLayoutSettings::SetShowTileNumber(bool newTileNumbers)
{ {
m_showTileNumbers = newTileNumbers; m_showTileNumbers = newTileNumbers;
} }
//---------------------------------------------------------------------------------------------------------------------
void VPLayoutSettings::SetBoundaryTogetherWithNotches(bool value)
{
m_togetherWithNotches = value;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPLayoutSettings::IsBoundaryTogetherWithNotches() const -> bool
{
return m_togetherWithNotches;
}

View File

@ -28,16 +28,17 @@
#ifndef VPLAYOUTSETTINGS_H #ifndef VPLAYOUTSETTINGS_H
#define VPLAYOUTSETTINGS_H #define VPLAYOUTSETTINGS_H
#include <QCoreApplication>
#include <QMarginsF> #include <QMarginsF>
#include <QSizeF> #include <QSizeF>
#include <QString> #include <QString>
#include <QCoreApplication>
#include "../vmisc/def.h" #include "../vmisc/def.h"
class VPLayoutSettings class VPLayoutSettings
{ {
Q_DECLARE_TR_FUNCTIONS(VPLayoutSettings) // NOLINT Q_DECLARE_TR_FUNCTIONS(VPLayoutSettings) // NOLINT
public: public:
VPLayoutSettings() = default; VPLayoutSettings() = default;
@ -248,15 +249,15 @@ public:
void SetShowGrid(bool value); void SetShowGrid(bool value);
/** /**
* @brief GetGridColWidth returns the placement grid column width in Unit::Px * @brief GetGridColWidth returns the placement grid column width in Unit::Px
* @return the placement grid column width in Unit::Px * @return the placement grid column width in Unit::Px
*/ */
auto GetGridColWidth() const -> qreal; auto GetGridColWidth() const -> qreal;
/** /**
* @brief GetGridColWidth returns the placement grid column width in the layout's unit * @brief GetGridColWidth returns the placement grid column width in the layout's unit
* @return the placement grid column width in the layout's unit * @return the placement grid column width in the layout's unit
*/ */
auto GetGridColWidthConverted() const -> qreal; auto GetGridColWidthConverted() const -> qreal;
/** /**
@ -273,15 +274,15 @@ public:
void SetGridColWidthConverted(qreal value); void SetGridColWidthConverted(qreal value);
/** /**
* @brief GetGridRowHeight returns the placement grid row height in Unit::Px * @brief GetGridRowHeight returns the placement grid row height in Unit::Px
* @return the placement grid row height in Unit::Px * @return the placement grid row height in Unit::Px
*/ */
auto GetGridRowHeight() const -> qreal; auto GetGridRowHeight() const -> qreal;
/** /**
* @brief GetGridRowHeightConverted returns the placement grid row height in the layout's unit * @brief GetGridRowHeightConverted returns the placement grid row height in the layout's unit
* @return the placement grid row height in the layout's unit * @return the placement grid row height in the layout's unit
*/ */
auto GetGridRowHeightConverted() const -> qreal; auto GetGridRowHeightConverted() const -> qreal;
/** /**
@ -318,6 +319,9 @@ public:
auto GetShowTileNumber() const -> bool; auto GetShowTileNumber() const -> bool;
void SetShowTileNumber(bool newTileNumbers); void SetShowTileNumber(bool newTileNumbers);
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
private: private:
Unit m_unit{Unit::Cm}; Unit m_unit{Unit::Cm};
@ -376,6 +380,8 @@ private:
bool m_printTilesScheme{false}; bool m_printTilesScheme{false};
bool m_showTileNumbers{false}; bool m_showTileNumbers{false};
bool m_togetherWithNotches{false};
}; };
#endif // VPLAYOUTSETTINGS_H #endif // VPLAYOUTSETTINGS_H

View File

@ -334,6 +334,8 @@ void VPSheetSceneData::ConnectPiece(VPGraphicsPiece *piece)
&VPGraphicsPieceControls::on_HideHandles); &VPGraphicsPieceControls::on_HideHandles);
QObject::connect(piece, &VPGraphicsPiece::HideTransformationHandles, m_rotationOrigin, QObject::connect(piece, &VPGraphicsPiece::HideTransformationHandles, m_rotationOrigin,
&VPGraphicsTransformationOrigin::on_HideHandles); &VPGraphicsTransformationOrigin::on_HideHandles);
QObject::connect(layout.data(), &VPLayout::BoundaryTogetherWithNotchesChanged, piece,
&VPGraphicsPiece::on_RefreshPiece);
} }
// VPSheet // VPSheet

View File

@ -44,6 +44,7 @@
#include "../layout/vpsheet.h" #include "../layout/vpsheet.h"
#include "../vformat/vsinglelineoutlinechar.h" #include "../vformat/vsinglelineoutlinechar.h"
#include "../vgeometry/vlayoutplacelabel.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "../vlayout/vboundary.h"
#include "../vlayout/vgraphicsfillitem.h" #include "../vlayout/vgraphicsfillitem.h"
#include "../vlayout/vlayoutpiecepath.h" #include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vtextmanager.h" #include "../vlayout/vtextmanager.h"
@ -650,24 +651,59 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintSeamLine(QPainter *painter, const VPPiecePtr &piece) void VPGraphicsPiece::PaintSeamLine(QPainter *painter, const VPPiecePtr &piece)
{ {
if (not piece->IsHideMainPath() || not piece->IsSeamAllowance()) if (piece->IsSeamAllowance() && not piece->IsHideMainPath() && not piece->IsSeamAllowanceBuiltIn())
{ {
QVector<VLayoutPoint> seamLinePoints = piece->GetMappedContourPoints(); QVector<VLayoutPoint> seamLinePoints = piece->GetMappedContourPoints();
if (!seamLinePoints.isEmpty())
if (seamLinePoints.isEmpty())
{ {
m_seamLine.moveTo(seamLinePoints.constFirst()); return;
for (int i = 1; i < seamLinePoints.size(); i++) }
VPLayoutPtr layout = piece->Layout();
if (layout.isNull())
{
return;
}
if (layout->LayoutSettings().IsBoundaryTogetherWithNotches())
{
QVector<VLayoutPassmark> passmarks = piece->GetMappedPassmarks();
bool seamAllowance = piece->IsSeamAllowance() && piece->IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = piece->IsSeamAllowance() && piece->IsSeamAllowanceBuiltIn();
VBoundary boundary(seamLinePoints, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(piece->GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
QVector<QPointF> combinedBoundary;
for (const auto &item : sequence)
{ {
m_seamLine.lineTo(seamLinePoints.at(i)); const auto path = item.item.value<VLayoutPiecePath>().Points();
QVector<QPointF> convertedPoints;
CastTo(path, convertedPoints);
combinedBoundary += convertedPoints;
} }
if (painter != nullptr) m_seamLine.addPolygon(QPolygonF(combinedBoundary));
{ m_seamLine.closeSubpath();
painter->save(); }
painter->setBrush(piece->IsSelected() ? SelectionBrush() : NoBrush()); else
painter->drawPath(m_seamLine); {
painter->restore(); QVector<QPointF> convertedPoints;
} CastTo(seamLinePoints, convertedPoints);
m_seamLine.addPolygon(QPolygonF(convertedPoints));
m_seamLine.closeSubpath();
}
if (painter != nullptr)
{
painter->save();
painter->setBrush(piece->IsSelected() ? SelectionBrush() : NoBrush());
painter->drawPath(m_seamLine);
painter->restore();
} }
} }
} }
@ -678,21 +714,55 @@ void VPGraphicsPiece::PaintCuttingLine(QPainter *painter, const VPPiecePtr &piec
if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn()) if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn())
{ {
QVector<VLayoutPoint> cuttingLinepoints = piece->GetMappedSeamAllowancePoints(); QVector<VLayoutPoint> cuttingLinepoints = piece->GetMappedSeamAllowancePoints();
if (!cuttingLinepoints.isEmpty()) if (cuttingLinepoints.isEmpty())
{ {
m_cuttingLine.moveTo(cuttingLinepoints.constFirst()); return;
for (int i = 1; i < cuttingLinepoints.size(); i++) }
VPLayoutPtr layout = piece->Layout();
if (layout.isNull())
{
return;
}
if (layout->LayoutSettings().IsBoundaryTogetherWithNotches())
{
const QVector<VLayoutPassmark> passmarks = piece->GetMappedPassmarks();
bool seamAllowance = piece->IsSeamAllowance() && !piece->IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = piece->IsSeamAllowance() && piece->IsSeamAllowanceBuiltIn();
VBoundary boundary(cuttingLinepoints, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(piece->GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
QVector<QPointF> combinedBoundary;
for (const auto &item : sequence)
{ {
m_cuttingLine.lineTo(cuttingLinepoints.at(i)); const auto path = item.item.value<VLayoutPiecePath>().Points();
QVector<QPointF> convertedPoints;
CastTo(path, convertedPoints);
combinedBoundary += convertedPoints;
} }
if (painter != nullptr) m_cuttingLine.addPolygon(QPolygonF(combinedBoundary));
{ m_cuttingLine.closeSubpath();
painter->save(); }
painter->setBrush(piece->IsSelected() ? SelectionBrush() : NoBrush()); else
painter->drawPath(m_cuttingLine); {
painter->restore(); QVector<QPointF> convertedPoints;
} CastTo(cuttingLinepoints, convertedPoints);
m_cuttingLine.addPolygon(QPolygonF(convertedPoints));
m_cuttingLine.closeSubpath();
}
if (painter != nullptr)
{
painter->save();
painter->setBrush(piece->IsSelected() ? SelectionBrush() : NoBrush());
painter->drawPath(m_cuttingLine);
painter->restore();
} }
} }
} }
@ -721,6 +791,17 @@ void VPGraphicsPiece::PaintInternalPaths(QPainter *painter, const VPPiecePtr &pi
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintPassmarks(QPainter *painter, const VPPiecePtr &piece) void VPGraphicsPiece::PaintPassmarks(QPainter *painter, const VPPiecePtr &piece)
{ {
VPLayoutPtr layout = piece->Layout();
if (layout.isNull())
{
return;
}
if (layout->LayoutSettings().IsBoundaryTogetherWithNotches())
{
return;
}
QVector<VLayoutPassmark> passmarks = piece->GetMappedPassmarks(); QVector<VLayoutPassmark> passmarks = piece->GetMappedPassmarks();
for (auto &passmark : passmarks) for (auto &passmark : passmarks)
{ {

View File

@ -1205,6 +1205,8 @@ void VPMainWindow::InitPropertyTabLayout()
} }
}); });
connect(ui->checkBoxTogetherWithNotches, &QCheckBox::toggled, this, &VPMainWindow::TogetherWithNotchesChanged);
VPSettings *settings = VPApplication::VApp()->PuzzleSettings(); VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
ui->doubleSpinBoxSheetPiecesGap->setMaximum( ui->doubleSpinBoxSheetPiecesGap->setMaximum(
UnitConvertor(VPSettings::GetMaxLayoutPieceGap(), Unit::Px, settings->LayoutUnit())); UnitConvertor(VPSettings::GetMaxLayoutPieceGap(), Unit::Px, settings->LayoutUnit()));
@ -1523,6 +1525,7 @@ void VPMainWindow::SetPropertyTabLayoutData()
m_layout->LayoutSettings().GetWarningSuperpositionOfPieces()); m_layout->LayoutSettings().GetWarningSuperpositionOfPieces());
SetCheckBoxValue(ui->checkBoxSheetStickyEdges, m_layout->LayoutSettings().GetStickyEdges()); SetCheckBoxValue(ui->checkBoxSheetStickyEdges, m_layout->LayoutSettings().GetStickyEdges());
SetCheckBoxValue(ui->checkBoxFollowGainline, m_layout->LayoutSettings().GetFollowGrainline()); SetCheckBoxValue(ui->checkBoxFollowGainline, m_layout->LayoutSettings().GetFollowGrainline());
SetCheckBoxValue(ui->checkBoxTogetherWithNotches, m_layout->LayoutSettings().IsBoundaryTogetherWithNotches());
// set pieces gap // set pieces gap
SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetPiecesGap, m_layout->LayoutSettings().GetPiecesGapConverted()); SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetPiecesGap, m_layout->LayoutSettings().GetPiecesGapConverted());
@ -1559,6 +1562,7 @@ void VPMainWindow::SetPropertyTabLayoutData()
SetCheckBoxValue(ui->checkBoxLayoutWarningPiecesSuperposition, false); SetCheckBoxValue(ui->checkBoxLayoutWarningPiecesSuperposition, false);
SetCheckBoxValue(ui->checkBoxSheetStickyEdges, false); SetCheckBoxValue(ui->checkBoxSheetStickyEdges, false);
SetCheckBoxValue(ui->checkBoxFollowGainline, false); SetCheckBoxValue(ui->checkBoxFollowGainline, false);
SetCheckBoxValue(ui->checkBoxTogetherWithNotches, false);
SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetPiecesGap, 0); SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetPiecesGap, 0);
@ -4743,6 +4747,38 @@ void VPMainWindow::UpdateShortcuts()
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::TogetherWithNotchesChanged(bool checked)
{
if (m_layout.isNull())
{
return;
}
m_layout->LayoutSettings().SetBoundaryTogetherWithNotches(checked);
m_carrousel->RefreshPieceMiniature();
QList<VPSheetPtr> sheets = m_layout->GetAllSheets();
for (const auto &sheet : sheets)
{
if (sheet.isNull())
{
continue;
}
QList<VPPiecePtr> pieces = sheet->GetPieces();
for (const auto &piece : pieces)
{
if (not piece.isNull())
{
emit m_layout->BoundaryTogetherWithNotchesChanged(piece);
}
}
}
LayoutWasSaved(false);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
void VPMainWindow::AboutToShowDockMenu() void VPMainWindow::AboutToShowDockMenu()

View File

@ -297,6 +297,8 @@ private slots:
void UpdateShortcuts(); void UpdateShortcuts();
void TogetherWithNotchesChanged(bool checked);
private: private:
Q_DISABLE_COPY_MOVE(VPMainWindow) // NOLINT Q_DISABLE_COPY_MOVE(VPMainWindow) // NOLINT
Ui::VPMainWindow *ui; Ui::VPMainWindow *ui;

View File

@ -1715,6 +1715,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="checkBoxTogetherWithNotches">
<property name="text">
<string>Boundary together with notches</string>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
@ -2427,8 +2434,8 @@
</resources> </resources>
<connections/> <connections/>
<buttongroups> <buttongroups>
<buttongroup name="buttonGroupRotationDirection"/>
<buttongroup name="buttonGroupSheetOrientation"/>
<buttongroup name="buttonGroupTileOrientation"/> <buttongroup name="buttonGroupTileOrientation"/>
<buttongroup name="buttonGroupSheetOrientation"/>
<buttongroup name="buttonGroupRotationDirection"/>
</buttongroups> </buttongroups>
</ui> </ui>

View File

@ -341,6 +341,8 @@ void VPLayoutFileReader::ReadControl(const VPLayoutPtr &layout)
layout->LayoutSettings().SetStickyEdges(ReadAttributeBool(attribs, ML::AttrStickyEdges, trueStr)); layout->LayoutSettings().SetStickyEdges(ReadAttributeBool(attribs, ML::AttrStickyEdges, trueStr));
layout->LayoutSettings().SetPiecesGap(qMax(ReadAttributeDouble(attribs, ML::AttrPiecesGap, QChar('0')), 0.0)); layout->LayoutSettings().SetPiecesGap(qMax(ReadAttributeDouble(attribs, ML::AttrPiecesGap, QChar('0')), 0.0));
layout->LayoutSettings().SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainline, falseStr)); layout->LayoutSettings().SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainline, falseStr));
layout->LayoutSettings().SetBoundaryTogetherWithNotches(
ReadAttributeBool(attribs, ML::AttrBoundaryTogetherWithNotches, falseStr));
readElementText(); readElementText();
} }

View File

@ -173,6 +173,7 @@ void VPLayoutFileWriter::WriteLayoutProperties(const VPLayoutPtr &layout)
SetAttribute(ML::AttrStickyEdges, layout->LayoutSettings().GetStickyEdges()); SetAttribute(ML::AttrStickyEdges, layout->LayoutSettings().GetStickyEdges());
SetAttribute(ML::AttrPiecesGap, layout->LayoutSettings().GetPiecesGap()); SetAttribute(ML::AttrPiecesGap, layout->LayoutSettings().GetPiecesGap());
SetAttribute(ML::AttrFollowGrainline, layout->LayoutSettings().GetFollowGrainline()); SetAttribute(ML::AttrFollowGrainline, layout->LayoutSettings().GetFollowGrainline());
SetAttribute(ML::AttrBoundaryTogetherWithNotches, layout->LayoutSettings().IsBoundaryTogetherWithNotches());
writeEndElement(); // control writeEndElement(); // control
WriteTiles(layout); WriteTiles(layout);

View File

@ -68,59 +68,60 @@ const QString TagScale = QStringLiteral("scale"); // NOLINT(ce
const QString TagWatermark = QStringLiteral("watermark"); // NOLINT(cert-err58-cpp) const QString TagWatermark = QStringLiteral("watermark"); // NOLINT(cert-err58-cpp)
const QString TagPoint = QStringLiteral("point"); // NOLINT(cert-err58-cpp) const QString TagPoint = QStringLiteral("point"); // NOLINT(cert-err58-cpp)
const QString AttrWarningSuperposition = QStringLiteral("warningSuperposition"); // NOLINT(cert-err58-cpp) const QString AttrWarningSuperposition = QStringLiteral("warningSuperposition"); // NOLINT(cert-err58-cpp)
const QString AttrWarningOutOfBound = QStringLiteral("warningOutOfBound"); // NOLINT(cert-err58-cpp) const QString AttrWarningOutOfBound = QStringLiteral("warningOutOfBound"); // NOLINT(cert-err58-cpp)
const QString AttrStickyEdges = QStringLiteral("stickyEdges"); // NOLINT(cert-err58-cpp) const QString AttrStickyEdges = QStringLiteral("stickyEdges"); // NOLINT(cert-err58-cpp)
const QString AttrPiecesGap = QStringLiteral("piecesGap"); // NOLINT(cert-err58-cpp) const QString AttrPiecesGap = QStringLiteral("piecesGap"); // NOLINT(cert-err58-cpp)
const QString AttrVisible = QStringLiteral("visible"); // NOLINT(cert-err58-cpp) const QString AttrVisible = QStringLiteral("visible"); // NOLINT(cert-err58-cpp)
const QString AttrMatchingMarks = QStringLiteral("matchingMarks"); // NOLINT(cert-err58-cpp) const QString AttrMatchingMarks = QStringLiteral("matchingMarks"); // NOLINT(cert-err58-cpp)
const QString AttrName = QStringLiteral("name"); // NOLINT(cert-err58-cpp) const QString AttrName = QStringLiteral("name"); // NOLINT(cert-err58-cpp)
const QString AttrLeft = QStringLiteral("left"); // NOLINT(cert-err58-cpp) const QString AttrLeft = QStringLiteral("left"); // NOLINT(cert-err58-cpp)
const QString AttrTop = QStringLiteral("top"); // NOLINT(cert-err58-cpp) const QString AttrTop = QStringLiteral("top"); // NOLINT(cert-err58-cpp)
const QString AttrRight = QStringLiteral("right"); // NOLINT(cert-err58-cpp) const QString AttrRight = QStringLiteral("right"); // NOLINT(cert-err58-cpp)
const QString AttrBottom = QStringLiteral("bottom"); // NOLINT(cert-err58-cpp) const QString AttrBottom = QStringLiteral("bottom"); // NOLINT(cert-err58-cpp)
const QString AttrWidth = QStringLiteral("width"); // NOLINT(cert-err58-cpp) const QString AttrWidth = QStringLiteral("width"); // NOLINT(cert-err58-cpp)
const QString AttrLength = QStringLiteral("length"); // NOLINT(cert-err58-cpp) const QString AttrLength = QStringLiteral("length"); // NOLINT(cert-err58-cpp)
const QString AttrFollowGrainline = QStringLiteral("followGrainline"); // NOLINT(cert-err58-cpp) const QString AttrFollowGrainline = QStringLiteral("followGrainline"); // NOLINT(cert-err58-cpp)
const QString AttrUID = QStringLiteral("uid"); // NOLINT(cert-err58-cpp) const QString AttrBoundaryTogetherWithNotches = QStringLiteral("boundaryTogetherWithNotches"); // NOLINT(cert-err58-cpp)
const QString AttrMirrored = QStringLiteral("mirrored"); // NOLINT(cert-err58-cpp) const QString AttrUID = QStringLiteral("uid"); // NOLINT(cert-err58-cpp)
const QString AttrForbidFlipping = QStringLiteral("forbidFlipping"); // NOLINT(cert-err58-cpp) const QString AttrMirrored = QStringLiteral("mirrored"); // NOLINT(cert-err58-cpp)
const QString AttrForceFlipping = QStringLiteral("forceFlipping"); // NOLINT(cert-err58-cpp) const QString AttrForbidFlipping = QStringLiteral("forbidFlipping"); // NOLINT(cert-err58-cpp)
const QString AttrSewLineOnDrawing = QStringLiteral("sewLineOnDrawing"); // NOLINT(cert-err58-cpp) const QString AttrForceFlipping = QStringLiteral("forceFlipping"); // NOLINT(cert-err58-cpp)
const QString AttrTransform = QStringLiteral("transform"); // NOLINT(cert-err58-cpp) const QString AttrSewLineOnDrawing = QStringLiteral("sewLineOnDrawing"); // NOLINT(cert-err58-cpp)
const QString AttrShowSeamline = QStringLiteral("showSeamline"); // NOLINT(cert-err58-cpp) const QString AttrTransform = QStringLiteral("transform"); // NOLINT(cert-err58-cpp)
const QString AttrEnabled = QStringLiteral("enabled"); // NOLINT(cert-err58-cpp) const QString AttrShowSeamline = QStringLiteral("showSeamline"); // NOLINT(cert-err58-cpp)
const QString AttrBuiltIn = QStringLiteral("builtIn"); // NOLINT(cert-err58-cpp) const QString AttrEnabled = QStringLiteral("enabled"); // NOLINT(cert-err58-cpp)
const QString AttrArrowDirection = QStringLiteral("arrowDirection"); // NOLINT(cert-err58-cpp) const QString AttrBuiltIn = QStringLiteral("builtIn"); // NOLINT(cert-err58-cpp)
const QString AttrType = QStringLiteral("type"); // NOLINT(cert-err58-cpp) const QString AttrArrowDirection = QStringLiteral("arrowDirection"); // NOLINT(cert-err58-cpp)
const QString AttrBaseLine = QStringLiteral("baseLine"); // NOLINT(cert-err58-cpp) const QString AttrType = QStringLiteral("type"); // NOLINT(cert-err58-cpp)
const QString AttrPath = QStringLiteral("path"); // NOLINT(cert-err58-cpp) const QString AttrBaseLine = QStringLiteral("baseLine"); // NOLINT(cert-err58-cpp)
const QString AttrCut = QStringLiteral("cut"); // NOLINT(cert-err58-cpp) const QString AttrPath = QStringLiteral("path"); // NOLINT(cert-err58-cpp)
const QString AttrPenStyle = QStringLiteral("penStyle"); // NOLINT(cert-err58-cpp) const QString AttrCut = QStringLiteral("cut"); // NOLINT(cert-err58-cpp)
const QString AttrCenter = QStringLiteral("center"); // NOLINT(cert-err58-cpp) const QString AttrPenStyle = QStringLiteral("penStyle"); // NOLINT(cert-err58-cpp)
const QString AttrBox = QStringLiteral("box"); // NOLINT(cert-err58-cpp) const QString AttrCenter = QStringLiteral("center"); // NOLINT(cert-err58-cpp)
const QString AttrShape = QStringLiteral("shape"); // NOLINT(cert-err58-cpp) const QString AttrBox = QStringLiteral("box"); // NOLINT(cert-err58-cpp)
const QString AttrFont = QStringLiteral("font"); // NOLINT(cert-err58-cpp) const QString AttrShape = QStringLiteral("shape"); // NOLINT(cert-err58-cpp)
const QString AttrSVGFont = QStringLiteral("svgFont"); // NOLINT(cert-err58-cpp) const QString AttrFont = QStringLiteral("font"); // NOLINT(cert-err58-cpp)
const QString AttrFontSize = QStringLiteral("fontSize"); // NOLINT(cert-err58-cpp) const QString AttrSVGFont = QStringLiteral("svgFont"); // NOLINT(cert-err58-cpp)
const QString AttrBold = QStringLiteral("bold"); // NOLINT(cert-err58-cpp) const QString AttrFontSize = QStringLiteral("fontSize"); // NOLINT(cert-err58-cpp)
const QString AttrItalic = QStringLiteral("italic"); // NOLINT(cert-err58-cpp) const QString AttrBold = QStringLiteral("bold"); // NOLINT(cert-err58-cpp)
const QString AttrAlignment = QStringLiteral("alignment"); // NOLINT(cert-err58-cpp) const QString AttrItalic = QStringLiteral("italic"); // NOLINT(cert-err58-cpp)
const QString AttrGradationLabel = QStringLiteral("gradationLabel"); // NOLINT(cert-err58-cpp) const QString AttrAlignment = QStringLiteral("alignment"); // NOLINT(cert-err58-cpp)
const QString AttrCopyNumber = QStringLiteral("copyNumber"); // NOLINT(cert-err58-cpp) const QString AttrGradationLabel = QStringLiteral("gradationLabel"); // NOLINT(cert-err58-cpp)
const QString AttrGrainlineType = QStringLiteral("grainlineType"); // NOLINT(cert-err58-cpp) const QString AttrCopyNumber = QStringLiteral("copyNumber"); // NOLINT(cert-err58-cpp)
const QString AttrXScale = QStringLiteral("xScale"); // NOLINT(cert-err58-cpp) const QString AttrGrainlineType = QStringLiteral("grainlineType"); // NOLINT(cert-err58-cpp)
const QString AttrYScale = QStringLiteral("yScale"); // NOLINT(cert-err58-cpp) const QString AttrXScale = QStringLiteral("xScale"); // NOLINT(cert-err58-cpp)
const QString AttrIgnoreMargins = QStringLiteral("ignoreMargins"); // NOLINT(cert-err58-cpp) const QString AttrYScale = QStringLiteral("yScale"); // NOLINT(cert-err58-cpp)
const QString AttrShowPreview = QStringLiteral("showPreview"); // NOLINT(cert-err58-cpp) const QString AttrIgnoreMargins = QStringLiteral("ignoreMargins"); // NOLINT(cert-err58-cpp)
const QString AttrPrintScheme = QStringLiteral("printScheme"); // NOLINT(cert-err58-cpp) const QString AttrShowPreview = QStringLiteral("showPreview"); // NOLINT(cert-err58-cpp)
const QString AttrTileNumber = QStringLiteral("tileNumber"); // NOLINT(cert-err58-cpp) const QString AttrPrintScheme = QStringLiteral("printScheme"); // NOLINT(cert-err58-cpp)
const QString AttrZValue = QStringLiteral("zValue"); // NOLINT(cert-err58-cpp) const QString AttrTileNumber = QStringLiteral("tileNumber"); // NOLINT(cert-err58-cpp)
const QString AttrX = QStringLiteral("x"); // NOLINT(cert-err58-cpp) const QString AttrZValue = QStringLiteral("zValue"); // NOLINT(cert-err58-cpp)
const QString AttrY = QStringLiteral("y"); // NOLINT(cert-err58-cpp) const QString AttrX = QStringLiteral("x"); // NOLINT(cert-err58-cpp)
const QString AttrTurnPoint = QStringLiteral("turnPoint"); // NOLINT(cert-err58-cpp) const QString AttrY = QStringLiteral("y"); // NOLINT(cert-err58-cpp)
const QString AttrCurvePoint = QStringLiteral("curvePoint"); // NOLINT(cert-err58-cpp) const QString AttrTurnPoint = QStringLiteral("turnPoint"); // NOLINT(cert-err58-cpp)
const QString AttrClockwiseOpening = QStringLiteral("clockwiseOpening"); // NOLINT(cert-err58-cpp) const QString AttrCurvePoint = QStringLiteral("curvePoint"); // NOLINT(cert-err58-cpp)
const QString AttrClockwiseOpening = QStringLiteral("clockwiseOpening"); // NOLINT(cert-err58-cpp)
const QString oneWayUpStr = QStringLiteral("oneWayUp"); // NOLINT(cert-err58-cpp) const QString oneWayUpStr = QStringLiteral("oneWayUp"); // NOLINT(cert-err58-cpp)
const QString oneWayDownStr = QStringLiteral("oneWayDown"); // NOLINT(cert-err58-cpp) const QString oneWayDownStr = QStringLiteral("oneWayDown"); // NOLINT(cert-err58-cpp)

View File

@ -81,6 +81,7 @@ extern const QString AttrBottom;
extern const QString AttrWidth; extern const QString AttrWidth;
extern const QString AttrLength; extern const QString AttrLength;
extern const QString AttrFollowGrainline; extern const QString AttrFollowGrainline;
extern const QString AttrBoundaryTogetherWithNotches;
extern const QString AttrUID; extern const QString AttrUID;
extern const QString AttrMirrored; extern const QString AttrMirrored;
extern const QString AttrForbidFlipping; extern const QString AttrForbidFlipping;

View File

@ -165,6 +165,7 @@ auto VCommandLine::DefaultGenerator() const -> VLayoutGeneratorPtr
diag.SetUnitePages(IsOptionSet(LONG_OPTION_UNITE)); diag.SetUnitePages(IsOptionSet(LONG_OPTION_UNITE));
diag.SetSaveLength(IsOptionSet(LONG_OPTION_SAVELENGTH)); diag.SetSaveLength(IsOptionSet(LONG_OPTION_SAVELENGTH));
diag.SetPreferOneSheetSolution(IsOptionSet(LONG_OPTION_PREFER_ONE_SHEET_SOLUTION)); diag.SetPreferOneSheetSolution(IsOptionSet(LONG_OPTION_PREFER_ONE_SHEET_SOLUTION));
diag.SetBoundaryTogetherWithNotches(IsOptionSet(LONG_OPTION_BOUNDARY_TOGETHER_WITH_NOTCHES));
diag.SetGroup(OptGroup()); diag.SetGroup(OptGroup());
if (IsOptionSet(LONG_OPTION_IGNORE_MARGINS)) if (IsOptionSet(LONG_OPTION_IGNORE_MARGINS))
@ -718,6 +719,8 @@ void VCommandLine::InitCommandLineOptions()
"supports only a maximum of 32768x32768 px images.")}, "supports only a maximum of 32768x32768 px images.")},
{LONG_OPTION_PREFER_ONE_SHEET_SOLUTION, {LONG_OPTION_PREFER_ONE_SHEET_SOLUTION,
translate("VCommandLine", "Prefer one sheet layout solution (export mode).")}, translate("VCommandLine", "Prefer one sheet layout solution (export mode).")},
{LONG_OPTION_BOUNDARY_TOGETHER_WITH_NOTCHES,
translate("VCommandLine", "Export boundary together with notches (export mode).")},
//============================================================================================================== //==============================================================================================================
{{SINGLE_OPTION_SAVELENGTH, LONG_OPTION_SAVELENGTH}, {{SINGLE_OPTION_SAVELENGTH, LONG_OPTION_SAVELENGTH},
translate("VCommandLine", "Save length of the sheet if set (export mode). The option tells the program to use " translate("VCommandLine", "Save length of the sheet if set (export mode). The option tells the program to use "

View File

@ -383,6 +383,30 @@ void DialogLayoutSettings::SetNestQuantity(bool state)
ui->checkBoxNestQuantity->setChecked(state); ui->checkBoxNestQuantity->setChecked(state);
} }
//---------------------------------------------------------------------------------------------------------------------
void DialogLayoutSettings::SetBoundaryTogetherWithNotches(bool value)
{
ui->checkBoxTogetherWithNotches->setChecked(value);
}
//---------------------------------------------------------------------------------------------------------------------
auto DialogLayoutSettings::IsBoundaryTogetherWithNotches() const -> bool
{
return ui->checkBoxTogetherWithNotches->isChecked();
}
//---------------------------------------------------------------------------------------------------------------------
void DialogLayoutSettings::SetShowLayoutAllowance(bool value)
{
ui->checkBoxShowLayoutAllowance->setChecked(value);
}
//---------------------------------------------------------------------------------------------------------------------
auto DialogLayoutSettings::IsShowLayoutAllowance() const -> bool
{
return ui->checkBoxShowLayoutAllowance->isChecked();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto DialogLayoutSettings::SelectedPrinter() const -> QString auto DialogLayoutSettings::SelectedPrinter() const -> QString
{ {
@ -641,6 +665,8 @@ void DialogLayoutSettings::DialogAccepted()
m_generator->SetMultiplier(GetMultiplier()); m_generator->SetMultiplier(GetMultiplier());
m_generator->SetTextAsPaths(IsTextAsPaths()); m_generator->SetTextAsPaths(IsTextAsPaths());
m_generator->SetNestQuantity(IsNestQuantity()); m_generator->SetNestQuantity(IsNestQuantity());
m_generator->SetBoundaryTogetherWithNotches(IsBoundaryTogetherWithNotches());
m_generator->SetShowLayoutAllowance(IsShowLayoutAllowance());
if (IsIgnoreAllFields()) if (IsIgnoreAllFields())
{ {
@ -712,6 +738,7 @@ void DialogLayoutSettings::RestoreDefaults()
SetEfficiencyCoefficient(VValentinaSettings::GetDefEfficiencyCoefficient()); SetEfficiencyCoefficient(VValentinaSettings::GetDefEfficiencyCoefficient());
SetNestQuantity(VValentinaSettings::GetDefLayoutNestQuantity()); SetNestQuantity(VValentinaSettings::GetDefLayoutNestQuantity());
SetPreferOneSheetSolution(VValentinaSettings::GetDefLayoutPreferOneSheetSolution()); SetPreferOneSheetSolution(VValentinaSettings::GetDefLayoutPreferOneSheetSolution());
SetBoundaryTogetherWithNotches(VValentinaSettings::GetDefLayoutBoundaryTogetherWithNotches());
CorrectMaxFileds(); CorrectMaxFileds();
IgnoreAllFields(ui->checkBoxIgnoreFileds->isChecked()); IgnoreAllFields(ui->checkBoxIgnoreFileds->isChecked());
@ -1037,6 +1064,7 @@ void DialogLayoutSettings::ReadSettings()
SetMultiplier(settings->GetMultiplier()); SetMultiplier(settings->GetMultiplier());
SetTextAsPaths(settings->GetTextAsPaths()); SetTextAsPaths(settings->GetTextAsPaths());
SetNestQuantity(settings->GetLayoutNestQuantity()); SetNestQuantity(settings->GetLayoutNestQuantity());
SetBoundaryTogetherWithNotches(settings->GetLayoutBoundaryTogetherWithNotches());
FindTemplate(); FindTemplate();
@ -1067,6 +1095,7 @@ void DialogLayoutSettings::WriteSettings() const
settings->SetNestingTime(GetNestingTime()); settings->SetNestingTime(GetNestingTime());
settings->SetEfficiencyCoefficient(GetEfficiencyCoefficient()); settings->SetEfficiencyCoefficient(GetEfficiencyCoefficient());
settings->SetLayoutNestQuantity(IsNestQuantity()); settings->SetLayoutNestQuantity(IsNestQuantity());
settings->SetLayoutBoundaryTogetherWithNotches(IsBoundaryTogetherWithNotches());
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -37,7 +37,7 @@
namespace Ui namespace Ui
{ {
class DialogLayoutSettings; class DialogLayoutSettings;
} }
class VLayoutGenerator; class VLayoutGenerator;
@ -45,6 +45,7 @@ class VLayoutGenerator;
class DialogLayoutSettings : public VAbstractLayoutDialog class DialogLayoutSettings : public VAbstractLayoutDialog
{ {
Q_OBJECT // NOLINT Q_OBJECT // NOLINT
public: public:
explicit DialogLayoutSettings(VLayoutGenerator *generator, QWidget *parent = nullptr, bool disableSettings = false); explicit DialogLayoutSettings(VLayoutGenerator *generator, QWidget *parent = nullptr, bool disableSettings = false);
~DialogLayoutSettings() override; ~DialogLayoutSettings() override;
@ -106,19 +107,26 @@ public:
auto IsNestQuantity() const -> bool; auto IsNestQuantity() const -> bool;
void SetNestQuantity(bool state); void SetNestQuantity(bool state);
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
void SetShowLayoutAllowance(bool value);
auto IsShowLayoutAllowance() const -> bool;
auto SelectedPrinter() const -> QString; auto SelectedPrinter() const -> QString;
void EnableLandscapeOrientation(); void EnableLandscapeOrientation();
//support functions for the command line parser which uses invisible dialog to properly build layout generator // support functions for the command line parser which uses invisible dialog to properly build layout generator
auto SelectTemplate(const PaperSizeTemplate& id) -> bool; auto SelectTemplate(const PaperSizeTemplate &id) -> bool;
static auto MakeHelpTemplateList() -> QString; static auto MakeHelpTemplateList() -> QString;
static auto MakeHelpTiledPdfTemplateList() -> QString; static auto MakeHelpTiledPdfTemplateList() -> QString;
auto SelectPaperUnit(const QString& units) -> bool; auto SelectPaperUnit(const QString &units) -> bool;
auto SelectLayoutUnit(const QString& units) -> bool; auto SelectLayoutUnit(const QString &units) -> bool;
auto LayoutToPixels(qreal value) const -> qreal; auto LayoutToPixels(qreal value) const -> qreal;
auto PageToPixels(qreal value) const -> qreal; auto PageToPixels(qreal value) const -> qreal;
static auto MakeGroupsHelp() -> QString; static auto MakeGroupsHelp() -> QString;
protected: protected:
void showEvent(QShowEvent *event) override; void showEvent(QShowEvent *event) override;
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
@ -138,6 +146,7 @@ private slots:
void CorrectMaxFileds(); void CorrectMaxFileds();
void IgnoreAllFields(int state); void IgnoreAllFields(int state);
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(DialogLayoutSettings) // NOLINT Q_DISABLE_COPY_MOVE(DialogLayoutSettings) // NOLINT

View File

@ -340,6 +340,29 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="checkBoxTogetherWithNotches">
<property name="text">
<string>Boundary together with notches</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Debug</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QCheckBox" name="checkBoxShowLayoutAllowance">
<property name="text">
<string>Show layout allowance</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">

View File

@ -440,22 +440,26 @@ void DialogSaveLayout::ShowExample()
ui->checkBoxBinaryDXF->setVisible(false); ui->checkBoxBinaryDXF->setVisible(false);
ui->checkBoxTextAsPaths->setVisible(false); ui->checkBoxTextAsPaths->setVisible(false);
ui->checkBoxShowGrainline->setVisible(false); ui->checkBoxShowGrainline->setVisible(false);
ui->checkBoxTogetherWithNotches->setVisible(false);
switch (currentFormat) switch (currentFormat)
{ {
case LayoutExportFormats::DXF_AAMA: case LayoutExportFormats::DXF_AAMA:
case LayoutExportFormats::DXF_ASTM: case LayoutExportFormats::DXF_ASTM:
ui->checkBoxBinaryDXF->setVisible(true); ui->checkBoxBinaryDXF->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout);
break; break;
case LayoutExportFormats::PDFTiled: case LayoutExportFormats::PDFTiled:
ui->groupBoxPaperFormat->setEnabled(true); ui->groupBoxPaperFormat->setEnabled(true);
ui->groupBoxMargins->setEnabled(true); ui->groupBoxMargins->setEnabled(true);
ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout); ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout);
ui->checkBoxShowGrainline->setVisible(true); ui->checkBoxShowGrainline->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout);
break; break;
case LayoutExportFormats::HPGL: case LayoutExportFormats::HPGL:
case LayoutExportFormats::HPGL2: case LayoutExportFormats::HPGL2:
ui->checkBoxShowGrainline->setVisible(true); ui->checkBoxShowGrainline->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(true);
break; break;
case LayoutExportFormats::SVG: case LayoutExportFormats::SVG:
case LayoutExportFormats::PDF: case LayoutExportFormats::PDF:
@ -465,6 +469,7 @@ void DialogSaveLayout::ShowExample()
case LayoutExportFormats::TIF: case LayoutExportFormats::TIF:
ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout); ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout);
ui->checkBoxShowGrainline->setVisible(true); ui->checkBoxShowGrainline->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout);
break; break;
case LayoutExportFormats::DXF_AC1006_Flat: case LayoutExportFormats::DXF_AC1006_Flat:
case LayoutExportFormats::DXF_AC1009_Flat: case LayoutExportFormats::DXF_AC1009_Flat:
@ -478,6 +483,7 @@ void DialogSaveLayout::ShowExample()
ui->checkBoxBinaryDXF->setVisible(true); ui->checkBoxBinaryDXF->setVisible(true);
ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout); ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout);
ui->checkBoxShowGrainline->setVisible(true); ui->checkBoxShowGrainline->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout);
break; break;
default: default:
ui->labelOptionsNotAvailable->setVisible(true); ui->labelOptionsNotAvailable->setVisible(true);
@ -632,6 +638,18 @@ auto DialogSaveLayout::GetYScale() const -> qreal
return ui->doubleSpinBoxVerticalScale->value() / 100.; return ui->doubleSpinBoxVerticalScale->value() / 100.;
} }
//---------------------------------------------------------------------------------------------------------------------
void DialogSaveLayout::SetBoundaryTogetherWithNotches(bool value)
{
ui->checkBoxTogetherWithNotches->setChecked(value);
}
//---------------------------------------------------------------------------------------------------------------------
auto DialogSaveLayout::IsBoundaryTogetherWithNotches() const -> bool
{
return ui->checkBoxTogetherWithNotches->isChecked();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void DialogSaveLayout::showEvent(QShowEvent *event) void DialogSaveLayout::showEvent(QShowEvent *event)
{ {

View File

@ -35,10 +35,10 @@
namespace Ui namespace Ui
{ {
class DialogSaveLAyout; class DialogSaveLAyout;
} }
class DialogSaveLayout : public VAbstractLayoutDialog class DialogSaveLayout : public VAbstractLayoutDialog
{ {
Q_OBJECT // NOLINT Q_OBJECT // NOLINT
@ -60,7 +60,7 @@ public:
auto IsShowGrainline() const -> bool; auto IsShowGrainline() const -> bool;
static auto MakeHelpFormatList() -> QString; static auto MakeHelpFormatList() -> QString;
void SetDestinationPath(const QString& cmdDestinationPath); void SetDestinationPath(const QString &cmdDestinationPath);
auto Mode() const -> Draw; auto Mode() const -> Draw;
@ -84,6 +84,9 @@ public:
void SetYScale(qreal scale); void SetYScale(qreal scale);
auto GetYScale() const -> qreal; auto GetYScale() const -> qreal;
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
protected: protected:
void showEvent(QShowEvent *event) override; void showEvent(QShowEvent *event) override;
@ -94,6 +97,7 @@ private slots:
void ToggleScaleConnection(); void ToggleScaleConnection();
void HorizontalScaleChanged(double d); void HorizontalScaleChanged(double d);
void VerticalScaleChanged(double d); void VerticalScaleChanged(double d);
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(DialogSaveLayout) // NOLINT Q_DISABLE_COPY_MOVE(DialogSaveLayout) // NOLINT
@ -105,9 +109,9 @@ private:
bool m_scaleConnected{true}; bool m_scaleConnected{true};
static bool havePdf; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) static bool havePdf; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
static bool tested; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) static bool tested; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
static auto SupportPSTest() -> bool; static auto SupportPSTest() -> bool;
static auto InitFormats() -> QVector<std::pair<QString, LayoutExportFormats> >; static auto InitFormats() -> QVector<std::pair<QString, LayoutExportFormats>>;
void RemoveFormatFromList(LayoutExportFormats format); void RemoveFormatFromList(LayoutExportFormats format);

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>544</width> <width>544</width>
<height>401</height> <height>439</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -138,7 +138,14 @@
<string>Show grainline</string> <string>Show grainline</string>
</property> </property>
<property name="checked"> <property name="checked">
<bool>true</bool> <bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxTogetherWithNotches">
<property name="text">
<string>Boundary together with notches</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -275,7 +282,7 @@
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string notr="true"></string> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../libs/vmisc/share/resources/icon.qrc"> <iconset resource="../../../libs/vmisc/share/resources/icon.qrc">
@ -482,7 +489,7 @@
<item> <item>
<widget class="QToolButton" name="toolButtonPortrait"> <widget class="QToolButton" name="toolButtonPortrait">
<property name="text"> <property name="text">
<string notr="true"></string> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../libs/vmisc/share/resources/icon.qrc"> <iconset resource="../../../libs/vmisc/share/resources/icon.qrc">
@ -502,7 +509,7 @@
<item> <item>
<widget class="QToolButton" name="toolButtonLandscape"> <widget class="QToolButton" name="toolButtonLandscape">
<property name="text"> <property name="text">
<string notr="true"></string> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../libs/vmisc/share/resources/icon.qrc"> <iconset resource="../../../libs/vmisc/share/resources/icon.qrc">

View File

@ -4470,6 +4470,7 @@ void MainWindow::Clear()
ui->actionShowCurveDetails->setEnabled(false); ui->actionShowCurveDetails->setEnabled(false);
ui->actionShowAccuracyRadius->setEnabled(false); ui->actionShowAccuracyRadius->setEnabled(false);
ui->actionShowMainPath->setEnabled(false); ui->actionShowMainPath->setEnabled(false);
ui->actionBoundaryTogetherWithNotches->setEnabled(false);
ui->actionLoadIndividual->setEnabled(false); ui->actionLoadIndividual->setEnabled(false);
ui->actionLoadMultisize->setEnabled(false); ui->actionLoadMultisize->setEnabled(false);
ui->actionUnloadMeasurements->setEnabled(false); ui->actionUnloadMeasurements->setEnabled(false);
@ -4722,6 +4723,7 @@ void MainWindow::SetEnableWidgets(bool enable)
ui->actionShowCurveDetails->setEnabled(enableOnDrawStage); ui->actionShowCurveDetails->setEnabled(enableOnDrawStage);
ui->actionShowAccuracyRadius->setEnabled(enableOnDesignStage); ui->actionShowAccuracyRadius->setEnabled(enableOnDesignStage);
ui->actionShowMainPath->setEnabled(enableOnDetailsStage); ui->actionShowMainPath->setEnabled(enableOnDetailsStage);
ui->actionBoundaryTogetherWithNotches->setEnabled(enableOnDetailsStage);
ui->actionLoadIndividual->setEnabled(enableOnDesignStage); ui->actionLoadIndividual->setEnabled(enableOnDesignStage);
ui->actionLoadMultisize->setEnabled(enableOnDesignStage); ui->actionLoadMultisize->setEnabled(enableOnDesignStage);
ui->actionUnloadMeasurements->setEnabled(enableOnDesignStage); ui->actionUnloadMeasurements->setEnabled(enableOnDesignStage);
@ -5218,6 +5220,29 @@ void MainWindow::ActionShowMainPath_triggered(bool checked)
QGuiApplication::restoreOverrideCursor(); QGuiApplication::restoreOverrideCursor();
} }
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::ActionBoundaryTogetherWithNotches_triggered(bool checked)
{
VAbstractValApplication::VApp()->ValentinaSettings()->SetBoundaryTogetherWithNotches(checked);
const QList<quint32> ids = pattern->DataPieces()->keys();
const bool updateChildren = false;
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
for (const auto &id : ids)
{
try
{
if (auto *tool = qobject_cast<VToolSeamAllowance *>(VAbstractPattern::getTool(id)))
{
tool->RefreshGeometry(updateChildren);
}
}
catch (VExceptionBadId &)
{
}
}
QGuiApplication::restoreOverrideCursor();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void MainWindow::ActionOpenTape_triggered() void MainWindow::ActionOpenTape_triggered()
{ {
@ -6183,6 +6208,11 @@ void MainWindow::CreateActions()
ui->actionShowMainPath->setChecked(VAbstractValApplication::VApp()->ValentinaSettings()->IsPieceShowMainPath()); ui->actionShowMainPath->setChecked(VAbstractValApplication::VApp()->ValentinaSettings()->IsPieceShowMainPath());
connect(ui->actionShowMainPath, &QAction::triggered, this, &MainWindow::ActionShowMainPath_triggered); connect(ui->actionShowMainPath, &QAction::triggered, this, &MainWindow::ActionShowMainPath_triggered);
ui->actionBoundaryTogetherWithNotches->setChecked(
VAbstractValApplication::VApp()->ValentinaSettings()->IsBoundaryTogetherWithNotches());
connect(ui->actionBoundaryTogetherWithNotches, &QAction::triggered, this,
&MainWindow::ActionBoundaryTogetherWithNotches_triggered);
connect(ui->actionLoadIndividual, &QAction::triggered, this, &MainWindow::LoadIndividual); connect(ui->actionLoadIndividual, &QAction::triggered, this, &MainWindow::LoadIndividual);
connect(ui->actionLoadMultisize, &QAction::triggered, this, &MainWindow::LoadMultisize); connect(ui->actionLoadMultisize, &QAction::triggered, this, &MainWindow::LoadMultisize);
connect(ui->actionOpenTape, &QAction::triggered, this, &MainWindow::ActionOpenTape_triggered); connect(ui->actionOpenTape, &QAction::triggered, this, &MainWindow::ActionOpenTape_triggered);
@ -6777,6 +6807,7 @@ void MainWindow::ExportLayoutAs(bool checked)
{ {
m_dialogSaveLayout = QSharedPointer<DialogSaveLayout>(new DialogSaveLayout( m_dialogSaveLayout = QSharedPointer<DialogSaveLayout>(new DialogSaveLayout(
static_cast<int>(m_layoutSettings->LayoutScenes().size()), Draw::Layout, FileName(), this)); static_cast<int>(m_layoutSettings->LayoutScenes().size()), Draw::Layout, FileName(), this));
m_dialogSaveLayout->SetBoundaryTogetherWithNotches(m_layoutSettings->IsBoundaryTogetherWithNotches());
if (m_dialogSaveLayout->exec() == QDialog::Rejected) if (m_dialogSaveLayout->exec() == QDialog::Rejected)
{ {
@ -6821,9 +6852,8 @@ void MainWindow::ExportDetailsAs(bool checked)
} }
catch (VException &e) catch (VException &e)
{ {
QMessageBox::warning(this, tr("Export details"), QMessageBox::warning(this, tr("Export details"), tr("Can't export details.") + " \n"_L1 + e.ErrorMessage(),
tr("Can't export details.") + QStringLiteral(" \n") + e.ErrorMessage(), QMessageBox::Ok, QMessageBox::Ok, QMessageBox::Ok);
QMessageBox::Ok);
return; return;
} }
@ -6832,6 +6862,9 @@ void MainWindow::ExportDetailsAs(bool checked)
m_dialogSaveLayout = m_dialogSaveLayout =
QSharedPointer<DialogSaveLayout>(new DialogSaveLayout(1, Draw::Modeling, FileName(), this)); QSharedPointer<DialogSaveLayout>(new DialogSaveLayout(1, Draw::Modeling, FileName(), this));
VValentinaSettings *settings = VAbstractValApplication::VApp()->ValentinaSettings();
m_dialogSaveLayout->SetBoundaryTogetherWithNotches(settings->IsBoundaryTogetherWithNotches());
if (m_dialogSaveLayout->exec() == QDialog::Rejected) if (m_dialogSaveLayout->exec() == QDialog::Rejected)
{ {
m_dialogSaveLayout.clear(); m_dialogSaveLayout.clear();

View File

@ -255,6 +255,7 @@ private slots:
void ActionTable_triggered(); void ActionTable_triggered();
void ActionFinalMeasurements_triggered(); void ActionFinalMeasurements_triggered();
void ActionShowMainPath_triggered(bool checked); void ActionShowMainPath_triggered(bool checked);
void ActionBoundaryTogetherWithNotches_triggered(bool checked);
void ActionOpenTape_triggered(); void ActionOpenTape_triggered();
void UpdateShortcuts(); void UpdateShortcuts();

View File

@ -115,6 +115,7 @@
<addaction name="actionInteractiveTools"/> <addaction name="actionInteractiveTools"/>
<addaction name="actionShowCurveDetails"/> <addaction name="actionShowCurveDetails"/>
<addaction name="actionShowMainPath"/> <addaction name="actionShowMainPath"/>
<addaction name="actionBoundaryTogetherWithNotches"/>
<addaction name="actionShowAccuracyRadius"/> <addaction name="actionShowAccuracyRadius"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionAddBackgroundImage"/> <addaction name="actionAddBackgroundImage"/>
@ -2611,6 +2612,17 @@
<enum>QAction::NoRole</enum> <enum>QAction::NoRole</enum>
</property> </property>
</action> </action>
<action name="actionBoundaryTogetherWithNotches">
<property name="checkable">
<bool>true</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Boundary together with notches</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

View File

@ -338,6 +338,7 @@ auto MainWindowsNoGUI::GenerateLayout(VLayoutGenerator &lGenerator) -> bool
m_layoutSettings->SetAutoCropWidth(lGenerator.GetAutoCropWidth()); m_layoutSettings->SetAutoCropWidth(lGenerator.GetAutoCropWidth());
m_layoutSettings->SetUnitePages(lGenerator.IsUnitePages()); m_layoutSettings->SetUnitePages(lGenerator.IsUnitePages());
m_layoutSettings->SetLayoutStale(false); m_layoutSettings->SetLayoutStale(false);
m_layoutSettings->SetBoundaryTogetherWithNotches(lGenerator.IsBoundaryTogetherWithNotches());
papersCount = lGenerator.PapersCount(); papersCount = lGenerator.PapersCount();
hasResult = true; hasResult = true;
qDebug() << "Layout efficiency: " << efficiency; qDebug() << "Layout efficiency: " << efficiency;
@ -508,7 +509,7 @@ void MainWindowsNoGUI::ExportData(const QVector<VLayoutPiece> &listDetails)
{ {
for (int i = 0; i < detailsOnLayout.size(); ++i) for (int i = 0; i < detailsOnLayout.size(); ++i)
{ {
const QString name = m_dialogSaveLayout->Path() + '/' + m_dialogSaveLayout->FileName() + const QString name = m_dialogSaveLayout->Path() + '/'_L1 + m_dialogSaveLayout->FileName() +
QString::number(i + 1) + QString::number(i + 1) +
VLayoutExporter::ExportFormatSuffix(m_dialogSaveLayout->Format()); VLayoutExporter::ExportFormatSuffix(m_dialogSaveLayout->Format());
@ -582,13 +583,15 @@ void MainWindowsNoGUI::ExportDetailsAsFlatLayout(const QVector<VLayoutPiece> &li
list.reserve(listDetails.count()); list.reserve(listDetails.count());
for (auto piece : listDetails) for (auto piece : listDetails)
{ {
QGraphicsItem *item = piece.GetItem(m_dialogSaveLayout->IsTextAsPaths()); QGraphicsItem *item = piece.GetItem(m_dialogSaveLayout->IsTextAsPaths(),
m_dialogSaveLayout->IsBoundaryTogetherWithNotches(), false);
qreal diff = 0; qreal diff = 0;
if (piece.IsForceFlipping()) if (piece.IsForceFlipping())
{ {
const qreal x = item->boundingRect().x(); const qreal x = item->boundingRect().x();
piece.Mirror(); piece.Mirror();
item = piece.GetItem(m_dialogSaveLayout->IsTextAsPaths()); item = piece.GetItem(m_dialogSaveLayout->IsTextAsPaths(),
m_dialogSaveLayout->IsBoundaryTogetherWithNotches(), false);
diff = item->boundingRect().x() - x; diff = item->boundingRect().x() - x;
} }
@ -624,7 +627,7 @@ void MainWindowsNoGUI::ExportDetailsAsFlatLayout(const QVector<VLayoutPiece> &li
rect = scene->itemsBoundingRect().toRect(); rect = scene->itemsBoundingRect().toRect();
QGraphicsRectItem *paper = new QGraphicsRectItem(rect); auto *paper = new QGraphicsRectItem(rect);
paper->setPen(QPen(Qt::black, 1)); paper->setPen(QPen(Qt::black, 1));
paper->setBrush(QBrush(Qt::white)); paper->setBrush(QBrush(Qt::white));
papers.append(paper); papers.append(paper);
@ -671,6 +674,7 @@ void MainWindowsNoGUI::ExportApparelLayout(const QVector<VLayoutPiece> &details,
exporter.SetYScale(m_dialogSaveLayout->GetYScale()); exporter.SetYScale(m_dialogSaveLayout->GetYScale());
exporter.SetBinaryDxfFormat(m_dialogSaveLayout->IsBinaryDXFFormat()); exporter.SetBinaryDxfFormat(m_dialogSaveLayout->IsBinaryDXFFormat());
exporter.SetShowGrainline(m_dialogSaveLayout->IsShowGrainline()); exporter.SetShowGrainline(m_dialogSaveLayout->IsShowGrainline());
exporter.SetBoundaryTogetherWithNotches(m_dialogSaveLayout->IsBoundaryTogetherWithNotches());
switch (format) switch (format)
{ {
@ -720,14 +724,16 @@ void MainWindowsNoGUI::ExportDetailsAsApparelLayout(QVector<VLayoutPiece> listDe
for (int i = 0; i < listDetails.count(); ++i) for (int i = 0; i < listDetails.count(); ++i)
{ {
VLayoutPiece piece = listDetails.at(i); VLayoutPiece piece = listDetails.at(i);
QGraphicsItem *item = piece.GetItem(m_dialogSaveLayout->IsTextAsPaths()); QGraphicsItem *item = piece.GetItem(m_dialogSaveLayout->IsTextAsPaths(),
m_dialogSaveLayout->IsBoundaryTogetherWithNotches(), false);
qreal diff = 0; qreal diff = 0;
if (piece.IsForceFlipping()) if (piece.IsForceFlipping())
{ {
const qreal x = item->boundingRect().x(); const qreal x = item->boundingRect().x();
piece.Mirror(); piece.Mirror();
delete item; delete item;
item = piece.GetItem(m_dialogSaveLayout->IsTextAsPaths()); item = piece.GetItem(m_dialogSaveLayout->IsTextAsPaths(),
m_dialogSaveLayout->IsBoundaryTogetherWithNotches(), false);
diff = item->boundingRect().x() - x; diff = item->boundingRect().x() - x;
} }
@ -1064,6 +1070,7 @@ void MainWindowsNoGUI::ExportScene(const QList<QGraphicsScene *> &scenes, const
exporter.SetIgnorePrinterMargins(ignorePrinterFields); exporter.SetIgnorePrinterMargins(ignorePrinterFields);
exporter.SetBinaryDxfFormat(m_dialogSaveLayout->IsBinaryDXFFormat()); exporter.SetBinaryDxfFormat(m_dialogSaveLayout->IsBinaryDXFFormat());
exporter.SetShowGrainline(m_dialogSaveLayout->IsShowGrainline()); exporter.SetShowGrainline(m_dialogSaveLayout->IsShowGrainline());
exporter.SetBoundaryTogetherWithNotches(m_dialogSaveLayout->IsBoundaryTogetherWithNotches());
for (int i = 0; i < scenes.size(); ++i) for (int i = 0; i < scenes.size(); ++i)
{ {

View File

@ -1435,8 +1435,7 @@ void VPattern::ParsePointElement(VMainGraphicsScene *scene, QDomElement &domElem
ParsePlaceLabel(domElement, parse); ParsePlaceLabel(domElement, parse);
break; break;
default: default:
VException e(tr("Unknown point type '%1'.").arg(type)); throw VException(tr("Unknown point type '%1'.").arg(type));
throw e;
} }
} }

View File

@ -103,6 +103,7 @@
<file>schema/layout/v0.1.4.xsd</file> <file>schema/layout/v0.1.4.xsd</file>
<file>schema/layout/v0.1.5.xsd</file> <file>schema/layout/v0.1.5.xsd</file>
<file>schema/layout/v0.1.6.xsd</file> <file>schema/layout/v0.1.6.xsd</file>
<file>schema/layout/v0.1.7.xsd</file>
<file>schema/known_measurements/v1.0.0.xsd</file> <file>schema/known_measurements/v1.0.0.xsd</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,590 @@
<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:boolean" name="boundaryTogetherWithNotches"/>
<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:attribute type="xs:boolean" name="builtIn" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="grainline">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="LinePathOrEmpty">
<xs:attribute type="xs:boolean" name="enabled" 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:attribute type="xs:boolean" name="clockwiseOpening" 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="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:attribute type="xs:string" name="svgFont"/>
</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:attribute type="xs:string" name="svgFont"/>
</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="uid" 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="xs:boolean" name="followGrainline"/>
<xs:attribute type="xs:boolean" name="sewLineOnDrawing"/>
<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:attribute type="xs:boolean" name="builtIn" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="grainline">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="LinePathOrEmpty">
<xs:attribute type="xs:boolean" name="enabled" 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:attribute type="xs:boolean" name="clockwiseOpening" 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:attribute type="xs:string" name="svgFont"/>
</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:attribute type="xs:string" name="svgFont"/>
</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="uid" 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="xs:boolean" name="followGrainline"/>
<xs:attribute type="xs:boolean" name="sewLineOnDrawing"/>
<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="oneWayUp"/>
<xs:enumeration value="oneWayDown"/>
<xs:enumeration value="twoWaysUpDown"/>
<xs:enumeration value="fourWays"/>
<xs:enumeration value="twoWaysUpLeft"/>
<xs:enumeration value="twoWaysUpRight"/>
<xs:enumeration value="twoWaysDownLeft"/>
<xs:enumeration value="twoWaysDownRight"/>
<xs:enumeration value="threeWaysUpDownLeft"/>
<xs:enumeration value="threeWaysUpDownRight"/>
<xs:enumeration value="threeWaysUpLeftRight"/>
<xs:enumeration value="threeWaysDownLeftRight"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NotchType">
<xs:restriction base="xs:unsignedInt">
<!--OneLine-->
<xs:enumeration value="0"/>
<!--TwoLines-->
<xs:enumeration value="1"/>
<!--ThreeLines-->
<xs:enumeration value="2"/>
<!--TMark-->
<xs:enumeration value="3"/>
<!--VMark-->
<xs:enumeration value="4"/>
<!--VMark2-->
<xs:enumeration value="5"/>
<!--UMark-->
<xs:enumeration value="6"/>
<!--BoxMark-->
<xs:enumeration value="7"/>
<!--CheckMark-->
<xs:enumeration value="8"/>
</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="LinePathOrEmpty">
<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="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

@ -45,8 +45,8 @@ using namespace Qt::Literals::StringLiterals;
*/ */
const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0"); const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0");
const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.6"); const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.7");
const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.6.xsd"); const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.7.xsd");
// VLayoutConverter::LayoutMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! // VLayoutConverter::LayoutMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
// VLayoutConverter::LayoutMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! // VLayoutConverter::LayoutMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
@ -148,7 +148,8 @@ auto VLayoutConverter::XSDSchemas() -> QHash<unsigned int, QString>
std::make_pair(FormatVersion(0, 1, 3), QStringLiteral("://schema/layout/v0.1.3.xsd")), std::make_pair(FormatVersion(0, 1, 3), QStringLiteral("://schema/layout/v0.1.3.xsd")),
std::make_pair(FormatVersion(0, 1, 4), QStringLiteral("://schema/layout/v0.1.4.xsd")), std::make_pair(FormatVersion(0, 1, 4), QStringLiteral("://schema/layout/v0.1.4.xsd")),
std::make_pair(FormatVersion(0, 1, 5), QStringLiteral("://schema/layout/v0.1.5.xsd")), std::make_pair(FormatVersion(0, 1, 5), QStringLiteral("://schema/layout/v0.1.5.xsd")),
std::make_pair(FormatVersion(0, 1, 6), CurrentSchema), std::make_pair(FormatVersion(0, 1, 6), QStringLiteral("://schema/layout/v0.1.6.xsd")),
std::make_pair(FormatVersion(0, 1, 7), CurrentSchema),
}; };
return schemas; return schemas;
@ -185,10 +186,11 @@ void VLayoutConverter::ApplyPatches()
ToV0_1_5(); ToV0_1_5();
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case (FormatVersion(0, 1, 5)): case (FormatVersion(0, 1, 5)):
ToV0_1_6(); case (FormatVersion(0, 1, 6)):
ToV0_1_7();
ValidateXML(CurrentSchema); ValidateXML(CurrentSchema);
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case (FormatVersion(0, 1, 6)): case (FormatVersion(0, 1, 7)):
break; break;
default: default:
InvalidVersion(m_ver); InvalidVersion(m_ver);
@ -400,11 +402,11 @@ void VLayoutConverter::ToV0_1_5()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutConverter::ToV0_1_6() void VLayoutConverter::ToV0_1_7()
{ {
// TODO. Delete if minimal supported version is 0.1.6 // TODO. Delete if minimal supported version is 0.1.7
Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 6), "Time to refactor the code."); Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 7), "Time to refactor the code.");
SetVersion(QStringLiteral("0.1.6")); SetVersion(QStringLiteral("0.1.7"));
Save(); Save();
} }

View File

@ -47,7 +47,7 @@ public:
static const QString LayoutMaxVerStr; static const QString LayoutMaxVerStr;
static const QString CurrentSchema; static const QString CurrentSchema;
static Q_DECL_CONSTEXPR const unsigned LayoutMinVer = FormatVersion(0, 1, 0); static Q_DECL_CONSTEXPR const unsigned LayoutMinVer = FormatVersion(0, 1, 0);
static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 6); static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 7);
static auto XSDSchemas() -> QHash<unsigned, QString>; static auto XSDSchemas() -> QHash<unsigned, QString>;
@ -74,7 +74,7 @@ protected:
void ToV0_1_3(); void ToV0_1_3();
void ToV0_1_5(); void ToV0_1_5();
void ToV0_1_6(); void ToV0_1_7();
private: private:
Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT

View File

@ -54,7 +54,9 @@
#include "../vgeometry/vgeometrydef.h" #include "../vgeometry/vgeometrydef.h"
#include "../vgeometry/vlayoutplacelabel.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "../vlayout/vboundary.h"
#include "../vlayout/vlayoutpiece.h" #include "../vlayout/vlayoutpiece.h"
#include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vlayoutpoint.h" #include "../vlayout/vlayoutpoint.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "dxiface.h" #include "dxiface.h"
@ -654,6 +656,19 @@ void VDxfEngine::SetYScale(const qreal &yscale)
m_yscale = yscale; m_yscale = yscale;
} }
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::SetBoundaryTogetherWithNotches(bool value)
{
Q_ASSERT(not isActive());
m_togetherWithNotches = value;
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::IsBoundaryTogetherWithNotches() const -> bool
{
return m_togetherWithNotches;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::ErrorString() const -> QString auto VDxfEngine::ErrorString() const -> QString
{ {
@ -768,6 +783,28 @@ void VDxfEngine::ExportAAMAOutline(const QSharedPointer<dx_ifaceBlock> &detailBl
{ {
QVector<VLayoutPoint> points = PieceOutline(detail); QVector<VLayoutPoint> points = PieceOutline(detail);
if (m_togetherWithNotches)
{
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
bool seamAllowance = detail.IsSeamAllowance() && !detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(points, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
points.clear();
for (const auto &item : sequence)
{
const auto path = item.item.value<VLayoutPiecePath>().Points();
points += path;
}
points = VAbstractPiece::RemoveDublicates(points, false);
}
if (DRW_Entity *e = AAMAPolygon(points, *layer1, true)) if (DRW_Entity *e = AAMAPolygon(points, *layer1, true))
{ {
detailBlock->ent.push_back(e); detailBlock->ent.push_back(e);
@ -780,19 +817,7 @@ void VDxfEngine::ExportAAMAOutline(const QSharedPointer<dx_ifaceBlock> &detailBl
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMADraw(const QSharedPointer<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()) ExportAAMADrawSewLine(detailBlock, detail);
{
QVector<VLayoutPoint> points = detail.GetMappedContourPoints();
const UTF8STRING &layer = not detail.IsSewLineOnDrawing() ? *layer14 : *layer8;
if (DRW_Entity *e = AAMAPolygon(points, layer, true))
{
detailBlock->ent.push_back(e);
}
ExportTurnPoints(detailBlock, points);
ExportCurvePoints(detailBlock, points);
}
const QVector<QVector<VLayoutPoint>> drawIntLine = detail.MappedInternalPathsForCut(false); const QVector<QVector<VLayoutPoint>> drawIntLine = detail.MappedInternalPathsForCut(false);
for (const auto &intLine : drawIntLine) for (const auto &intLine : drawIntLine)
@ -827,6 +852,49 @@ void VDxfEngine::ExportAAMADraw(const QSharedPointer<dx_ifaceBlock> &detailBlock
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMADrawSewLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{
if (detail.IsSeamAllowance() && not detail.IsHideMainPath() && not detail.IsSeamAllowanceBuiltIn())
{
const UTF8STRING &layer = not detail.IsSewLineOnDrawing() ? *layer14 : *layer8;
QVector<VLayoutPoint> points = detail.GetMappedContourPoints();
auto DrawPolygon = [this, detailBlock, layer](const QVector<VLayoutPoint> &points, bool forceClosed)
{
if (DRW_Entity *e = AAMAPolygon(points, layer, forceClosed))
{
detailBlock->ent.push_back(e);
}
ExportTurnPoints(detailBlock, points);
ExportCurvePoints(detailBlock, points);
};
if (m_togetherWithNotches)
{
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
bool seamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(points, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, true, false);
for (const auto &item : sequence)
{
const auto path = item.item.value<VLayoutPiecePath>().Points();
DrawPolygon(path, false);
}
}
else
{
DrawPolygon(points, true);
}
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMAIntcut(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportAAMAIntcut(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
@ -846,7 +914,7 @@ void VDxfEngine::ExportAAMAIntcut(const QSharedPointer<dx_ifaceBlock> &detailBlo
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportAAMANotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportAAMANotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
if (detail.IsSeamAllowance()) if (detail.IsSeamAllowance() && !m_togetherWithNotches)
{ {
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks(); const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
for (const auto &passmark : passmarks) for (const auto &passmark : passmarks)
@ -1001,6 +1069,28 @@ void VDxfEngine::ExportASTMPieceBoundary(const QSharedPointer<dx_ifaceBlock> &de
{ {
QVector<VLayoutPoint> pieceBoundary = PieceOutline(detail); QVector<VLayoutPoint> pieceBoundary = PieceOutline(detail);
if (m_togetherWithNotches)
{
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
bool seamAllowance = detail.IsSeamAllowance() && !detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(pieceBoundary, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
pieceBoundary.clear();
for (const auto &item : sequence)
{
const auto path = item.item.value<VLayoutPiecePath>().Points();
pieceBoundary += path;
}
pieceBoundary = VAbstractPiece::RemoveDublicates(pieceBoundary, false);
}
// Piece boundary // Piece boundary
if (DRW_Entity *e = AAMAPolygon(pieceBoundary, *layer1, true)) if (DRW_Entity *e = AAMAPolygon(pieceBoundary, *layer1, true))
{ {
@ -1024,19 +1114,44 @@ void VDxfEngine::ExportASTMSewLine(const QSharedPointer<dx_ifaceBlock> &detailBl
{ {
QVector<VLayoutPoint> sewLine = detail.GetMappedContourPoints(); QVector<VLayoutPoint> sewLine = detail.GetMappedContourPoints();
// Sew lines auto DrawPolygon = [this, detailBlock](const QVector<VLayoutPoint> &points, bool forceClosed)
if (DRW_Entity *e = AAMAPolygon(sewLine, *layer14, true))
{ {
detailBlock->ent.push_back(e); // Sew lines
if (DRW_Entity *e = AAMAPolygon(points, *layer14, forceClosed))
{
detailBlock->ent.push_back(e);
}
ExportTurnPoints(detailBlock, points);
ExportCurvePoints(detailBlock, points);
// Sew lines quality validation curves
if (DRW_Entity *e = AAMAPolygon(points, *layer87, forceClosed))
{
detailBlock->ent.push_back(e);
}
};
if (m_togetherWithNotches)
{
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
bool seamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(sewLine, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, true, false);
for (const auto &item : sequence)
{
const auto path = item.item.value<VLayoutPiecePath>().Points();
DrawPolygon(path, false);
}
} }
else
ExportTurnPoints(detailBlock, sewLine);
ExportCurvePoints(detailBlock, sewLine);
// Sew lines quality validation curves
if (DRW_Entity *e = AAMAPolygon(sewLine, *layer87, true))
{ {
detailBlock->ent.push_back(e); DrawPolygon(sewLine, true);
} }
} }
} }
@ -1154,7 +1269,7 @@ void VDxfEngine::ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBloc
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMNotches(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail) void VDxfEngine::ExportASTMNotches(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
{ {
if (!detail.IsSeamAllowance()) if (!detail.IsSeamAllowance() || m_togetherWithNotches)
{ {
return; return;
} }

View File

@ -113,6 +113,9 @@ public:
auto GetYScale() const -> qreal; auto GetYScale() const -> qreal;
void SetYScale(const qreal &yscale); void SetYScale(const qreal &yscale);
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
auto ErrorString() const -> QString; auto ErrorString() const -> QString;
private: private:
@ -130,6 +133,7 @@ private:
DRW_Text *m_textBuffer{nullptr}; DRW_Text *m_textBuffer{nullptr};
qreal m_xscale{1}; qreal m_xscale{1};
qreal m_yscale{1}; qreal m_yscale{1};
bool m_togetherWithNotches{false};
Q_REQUIRED_RESULT auto FromPixel(double pix, const VarInsunits &unit) const -> double; Q_REQUIRED_RESULT auto FromPixel(double pix, const VarInsunits &unit) const -> double;
Q_REQUIRED_RESULT auto ToPixel(double val, const VarInsunits &unit) const -> double; Q_REQUIRED_RESULT auto ToPixel(double val, const VarInsunits &unit) const -> double;
@ -137,6 +141,7 @@ private:
auto ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool; auto ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool;
void ExportAAMAOutline(const QSharedPointer<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 ExportAAMADraw(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMADrawSewLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMAIntcut(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 ExportAAMANotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMAGrainline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportAAMAGrainline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);

View File

@ -196,6 +196,24 @@ void VDxfPaintDevice::SetYScale(const qreal &yscale)
m_engine->SetYScale(yscale); m_engine->SetYScale(yscale);
} }
//---------------------------------------------------------------------------------------------------------------------
void VDxfPaintDevice::SetBoundaryTogetherWithNotches(bool value)
{
if (m_engine->isActive())
{
qWarning("VDxfPaintDevice::SetBoundaryTogetherWithNotches(), cannot set boundary together with notches while "
"Dxf is being generated");
return;
}
m_engine->SetBoundaryTogetherWithNotches(value);
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfPaintDevice::IsBoundaryTogetherWithNotches() const -> bool
{
return m_engine->IsBoundaryTogetherWithNotches();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VDxfPaintDevice::ExportToAAMA(const QVector<VLayoutPiece> &details) const -> bool auto VDxfPaintDevice::ExportToAAMA(const QVector<VLayoutPiece> &details) const -> bool
{ {

View File

@ -72,6 +72,9 @@ public:
auto GetYScale() const -> qreal; auto GetYScale() const -> qreal;
void SetYScale(const qreal &yscale); void SetYScale(const qreal &yscale);
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
auto ExportToAAMA(const QVector<VLayoutPiece> &details) const -> bool; auto ExportToAAMA(const QVector<VLayoutPiece> &details) const -> bool;
auto ExportToASTM(const QVector<VLayoutPiece> &details) const -> bool; auto ExportToASTM(const QVector<VLayoutPiece> &details) const -> bool;

View File

@ -415,74 +415,6 @@ auto VAbstractCurve::IsPointOnCurve(const QPointF &p) const -> bool
return IsPointOnCurve(GetPoints(), p); return IsPointOnCurve(GetPoints(), p);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractCurve::SubdividePath(const QVector<QPointF> &points, QPointF p, QVector<QPointF> &sub1,
QVector<QPointF> &sub2) -> bool
{
if (points.size() < 2)
{
return false;
}
bool found = false;
sub1.clear();
sub2.clear();
for (qint32 i = 0; i < points.count() - 1; ++i)
{
if (not found)
{
if (IsPointOnLineSegment(p, points.at(i), points.at(i + 1)))
{
if (not VFuzzyComparePoints(points.at(i), p))
{
sub1.append(points.at(i));
sub1.append(p);
}
else
{
if (not sub1.isEmpty())
{
sub1.append(p);
}
}
if (not VFuzzyComparePoints(points.at(i + 1), p))
{
sub2.append(p);
if (i + 1 == points.count() - 1)
{
sub2.append(points.at(i + 1));
}
}
found = true;
}
else
{
sub1.append(points.at(i));
}
}
else
{
sub2.append(points.at(i));
if (i + 1 == points.count() - 1)
{
sub2.append(points.at(i + 1));
}
}
}
if (not found)
{
sub1.clear();
}
return found;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractCurve::GetDuplicate() const -> quint32 auto VAbstractCurve::GetDuplicate() const -> quint32
{ {

View File

@ -78,9 +78,6 @@ public:
static auto IsPointOnCurve(const QVector<QPointF> &points, const QPointF &p) -> bool; static auto IsPointOnCurve(const QVector<QPointF> &points, const QPointF &p) -> bool;
auto IsPointOnCurve(const QPointF &p) const -> bool; auto IsPointOnCurve(const QPointF &p) const -> bool;
static auto SubdividePath(const QVector<QPointF> &points, QPointF p, QVector<QPointF> &sub1, QVector<QPointF> &sub2)
-> bool;
auto ClosestPoint(QPointF scenePoint) const -> QPointF; auto ClosestPoint(QPointF scenePoint) const -> QPointF;
virtual auto GetStartAngle() const -> qreal = 0; virtual auto GetStartAngle() const -> qreal = 0;

View File

@ -43,7 +43,7 @@
using namespace Qt::Literals::StringLiterals; using namespace Qt::Literals::StringLiterals;
const quint32 VLayoutPassmark::streamHeader = 0x943E2759; // CRC-32Q string "VLayoutPassmark" const quint32 VLayoutPassmark::streamHeader = 0x943E2759; // CRC-32Q string "VLayoutPassmark"
const quint16 VLayoutPassmark::classVersion = 2; const quint16 VLayoutPassmark::classVersion = 3;
// Friend functions // Friend functions
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -51,7 +51,7 @@ auto operator<<(QDataStream &dataStream, const VLayoutPassmark &data) -> QDataSt
{ {
dataStream << VLayoutPassmark::streamHeader << VLayoutPassmark::classVersion; dataStream << VLayoutPassmark::streamHeader << VLayoutPassmark::classVersion;
dataStream << data.lines << data.type << data.baseLine << data.isBuiltIn << data.isClockwiseOpening; dataStream << data.lines << data.type << data.baseLine << data.isBuiltIn << data.isClockwiseOpening << data.label;
return dataStream; return dataStream;
} }
@ -89,5 +89,10 @@ auto operator>>(QDataStream &dataStream, VLayoutPassmark &data) -> QDataStream &
dataStream >> data.isClockwiseOpening; dataStream >> data.isClockwiseOpening;
} }
if (actualClassVersion >= 3)
{
dataStream >> data.label;
}
return dataStream; return dataStream;
} }

View File

@ -29,9 +29,9 @@
#ifndef VGEOMETRYDEF_H #ifndef VGEOMETRYDEF_H
#define VGEOMETRYDEF_H #define VGEOMETRYDEF_H
#include <QVector>
#include <QPolygonF> #include <QPolygonF>
#include <QTransform> #include <QTransform>
#include <QVector>
#include "../vmisc/def.h" #include "../vmisc/def.h"
@ -47,12 +47,16 @@ enum class GOType : qint8
PlaceLabel, PlaceLabel,
Unknown Unknown
}; };
enum class SplinePointPosition : qint8 { FirstPoint, LastPoint }; enum class SplinePointPosition : qint8
{
FirstPoint,
LastPoint
};
// Keep synchronized with XSD schema // Keep synchronized with XSD schema
enum class PlaceLabelType : quint8 enum class PlaceLabelType : quint8
{ {
Segment= 0, Segment = 0,
Rectangle = 1, Rectangle = 1,
Cross = 2, Cross = 2,
Tshaped = 3, Tshaped = 3,
@ -71,9 +75,11 @@ struct VLayoutPassmark
QLineF baseLine{}; QLineF baseLine{};
bool isBuiltIn{false}; bool isBuiltIn{false};
bool isClockwiseOpening{false}; bool isClockwiseOpening{false};
QString label{};
friend auto operator<<(QDataStream &dataStream, const VLayoutPassmark &data) -> QDataStream &;
friend auto operator>>(QDataStream &dataStream, VLayoutPassmark &data) -> QDataStream &;
friend auto operator<<(QDataStream& dataStream, const VLayoutPassmark& data) -> QDataStream&;
friend auto operator>>(QDataStream& dataStream, VLayoutPassmark& data) -> QDataStream&;
private: private:
static const quint32 streamHeader; static const quint32 streamHeader;
static const quint16 classVersion; static const quint16 classVersion;

View File

@ -29,6 +29,7 @@
#include "../vformat/vsinglelineoutlinechar.h" #include "../vformat/vsinglelineoutlinechar.h"
#include "../vgeometry/vlayoutplacelabel.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "../vlayout/vboundary.h"
#include "../vlayout/vlayoutpiece.h" #include "../vlayout/vlayoutpiece.h"
#include "../vlayout/vlayoutpiecepath.h" #include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vlayoutpoint.h" #include "../vlayout/vlayoutpoint.h"
@ -39,7 +40,6 @@
#include "../vmisc/svgfont/vsvgfontdatabase.h" #include "../vmisc/svgfont/vsvgfontdatabase.h"
#include "../vmisc/svgfont/vsvgfontengine.h" #include "../vmisc/svgfont/vsvgfontengine.h"
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include "qmath.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
#include "../vmisc/backport/text.h" #include "../vmisc/backport/text.h"
@ -57,8 +57,6 @@ using namespace Qt::Literals::StringLiterals;
namespace namespace
{ {
const qreal accuracyPointOnLine{0.99};
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wunused-member-function") QT_WARNING_DISABLE_CLANG("-Wunused-member-function")
@ -83,92 +81,6 @@ Q_DECL_RELAXED_CONSTEXPR inline auto ConvertPixels(qreal pix) -> qreal
return FromPixel(pix, Unit::Mm) * 40.; return FromPixel(pix, Unit::Mm) * 40.;
} }
//---------------------------------------------------------------------------------------------------------------------
auto RemoveDublicates(QVector<QPoint> points) -> QVector<QPoint>
{
if (points.size() < 3)
{
return points;
}
for (int i = 0; i < points.size() - 1; ++i)
{
if (points.at(i) == points.at(i + 1))
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
points.erase(points.cbegin() + i + 1);
#else
points.erase(points.begin() + i + 1);
#endif
--i;
}
}
return points;
}
//---------------------------------------------------------------------------------------------------------------------
auto OptimizePath(QVector<QPoint> path) -> QVector<QPoint>
{
if (path.size() < 3)
{
return path;
}
path = RemoveDublicates(path);
if (path.size() < 3)
{
return path;
}
vsizetype prev = -1;
const bool closedPath = (path.first() == path.last());
const vsizetype startIndex = closedPath ? 0 : 1;
const vsizetype endIndex = closedPath ? path.size() : path.size() - 1;
QVector<QPoint> cleared;
cleared.reserve(path.size());
if (!closedPath)
{
cleared.append(path.first());
}
// Remove point on line
for (vsizetype i = startIndex; i < endIndex; ++i)
{
if (prev == -1)
{
prev = (i == 0) ? path.size() - 1 : i - 1;
}
const vsizetype next = (i == path.size() - 1) ? 0 : i + 1;
const QPoint &iPoint = path.at(i);
const QPoint &prevPoint = path.at(prev);
const QPoint &nextPoint = path.at(next);
// If RemoveDublicates does not remove these points it is a valid case.
// Case where last point equal first point
if (((i == 0 || i == path.size() - 1) && (iPoint == prevPoint || iPoint == nextPoint)) ||
not VGObject::IsPointOnLineviaPDP(iPoint, prevPoint, nextPoint, accuracyPointOnLine))
{
cleared.append(iPoint);
prev = -1;
}
}
if (!closedPath)
{
cleared.append(path.last());
}
cleared = RemoveDublicates(cleared);
return cleared;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <class T> inline auto CastToPoint(const QVector<T> &points) -> QVector<QPoint> template <class T> inline auto CastToPoint(const QVector<T> &points) -> QVector<QPoint>
{ {
@ -464,7 +376,7 @@ void VHPGLEngine::ExportDetails(QTextStream &out, const QList<VLayoutPiece> &det
detail.Scale(m_xscale, m_yscale); detail.Scale(m_xscale, m_yscale);
PlotSeamAllowance(out, detail); PlotSeamAllowance(out, detail);
PlotMainPath(out, detail); PlotSewLine(out, detail);
PlotInternalPaths(out, detail); PlotInternalPaths(out, detail);
PlotGrainline(out, detail); PlotGrainline(out, detail);
PlotPlaceLabels(out, detail); PlotPlaceLabels(out, detail);
@ -482,13 +394,72 @@ void VHPGLEngine::GenerateHPGLFooter(QTextStream &out)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotMainPath(QTextStream &out, const VLayoutPiece &detail) void VHPGLEngine::PlotSewLine(QTextStream &out, const VLayoutPiece &detail)
{ {
if (not detail.IsSeamAllowance() || if (detail.IsSeamAllowance() && not detail.IsHideMainPath() && not detail.IsSeamAllowanceBuiltIn())
(detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() && not detail.IsHideMainPath()))
{ {
QVector<QPoint> points = CastToPoint(ConvertPath(detail.GetMappedContourPoints())); QVector<VLayoutPoint> sewLine = detail.GetMappedContourPoints();
if (m_togetherWithNotches)
{
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
bool seamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(sewLine, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, true, false);
for (const auto &item : sequence)
{
const auto path = CastToPoint(ConvertPath(item.item.value<VLayoutPiecePath>().Points()));
PlotPath(out, path, Qt::SolidLine);
}
}
else
{
QVector<QPoint> points = CastToPoint(ConvertPath(sewLine));
if (points.size() > 1 && points.first() != points.last())
{
points.append(points.first()); // must be closed
}
PlotPath(out, points, Qt::SolidLine);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotSeamAllowance(QTextStream &out, const VLayoutPiece &detail)
{
QVector<VLayoutPoint> pieceBoundary = detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn()
? detail.GetMappedSeamAllowancePoints()
: detail.GetMappedContourPoints();
if (m_togetherWithNotches)
{
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
bool seamAllowance = detail.IsSeamAllowance() && !detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(pieceBoundary, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
pieceBoundary.clear();
for (const auto &item : sequence)
{
const auto path = CastToPoint(ConvertPath(item.item.value<VLayoutPiecePath>().Points()));
PlotPath(out, path, Qt::SolidLine);
}
}
else
{
QVector<QPoint> points = CastToPoint(ConvertPath(pieceBoundary));
if (points.size() > 1 && points.first() != points.last()) if (points.size() > 1 && points.first() != points.last())
{ {
points.append(points.first()); // must be closed points.append(points.first()); // must be closed
@ -498,21 +469,6 @@ void VHPGLEngine::PlotMainPath(QTextStream &out, const VLayoutPiece &detail)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotSeamAllowance(QTextStream &out, const VLayoutPiece &detail)
{
QVector<QPoint> points = detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn()
? CastToPoint(ConvertPath(detail.GetMappedSeamAllowancePoints()))
: CastToPoint(ConvertPath(detail.GetMappedContourPoints()));
if (points.size() > 1 && points.first() != points.last())
{
points.append(points.first()); // must be closed
}
PlotPath(out, points, Qt::SolidLine);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotInternalPaths(QTextStream &out, const VLayoutPiece &detail) void VHPGLEngine::PlotInternalPaths(QTextStream &out, const VLayoutPiece &detail)
{ {
@ -541,6 +497,11 @@ void VHPGLEngine::PlotPlaceLabels(QTextStream &out, const VLayoutPiece &detail)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotPassmarks(QTextStream &out, const VLayoutPiece &detail) void VHPGLEngine::PlotPassmarks(QTextStream &out, const VLayoutPiece &detail)
{ {
if (m_togetherWithNotches)
{
return;
}
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks(); const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
for (const auto &passmark : passmarks) for (const auto &passmark : passmarks)
{ {
@ -710,7 +671,6 @@ void VHPGLEngine::PlotLabelOutlineFont(QTextStream &out, const VLayoutPiece &det
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <class T> auto VHPGLEngine::ConvertPath(const QVector<T> &path) const -> QVector<T> template <class T> auto VHPGLEngine::ConvertPath(const QVector<T> &path) const -> QVector<T>
{ {
QVector<T> convertedPath; QVector<T> convertedPath;
@ -740,8 +700,6 @@ void VHPGLEngine::PlotPath(QTextStream &out, QVector<QPoint> path, Qt::PenStyle
return; return;
} }
path = OptimizePath(path);
if (penStyle != Qt::SolidLine && penStyle != Qt::DashLine && penStyle != Qt::DotLine && if (penStyle != Qt::SolidLine && penStyle != Qt::DashLine && penStyle != Qt::DotLine &&
penStyle != Qt::DashDotLine && penStyle != Qt::DashDotDotLine) penStyle != Qt::DashDotLine && penStyle != Qt::DashDotDotLine)
{ {

View File

@ -80,6 +80,9 @@ public:
auto GetYScale() const -> qreal; auto GetYScale() const -> qreal;
void SetYScale(const qreal &yscale); void SetYScale(const qreal &yscale);
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
void SetIsertNewLine(bool insert); void SetIsertNewLine(bool insert);
static auto SortDetails(const QVector<VLayoutPiece> &details) -> QList<VLayoutPiece>; static auto SortDetails(const QVector<VLayoutPiece> &details) -> QList<VLayoutPiece>;
@ -101,6 +104,7 @@ private:
qreal m_xscale{1}; qreal m_xscale{1};
qreal m_yscale{1}; qreal m_yscale{1};
bool m_showGrainline{true}; bool m_showGrainline{true};
bool m_togetherWithNotches{false};
auto GenerateHPGL(const QVector<VLayoutPiece> &details) -> bool; auto GenerateHPGL(const QVector<VLayoutPiece> &details) -> bool;
auto GenerateHPGL2(const QVector<VLayoutPiece> &details) -> bool; auto GenerateHPGL2(const QVector<VLayoutPiece> &details) -> bool;
@ -110,7 +114,7 @@ private:
void ExportDetails(QTextStream &out, const QList<VLayoutPiece> &details); void ExportDetails(QTextStream &out, const QList<VLayoutPiece> &details);
void GenerateHPGLFooter(QTextStream &out); void GenerateHPGLFooter(QTextStream &out);
void PlotMainPath(QTextStream &out, const VLayoutPiece &detail); void PlotSewLine(QTextStream &out, const VLayoutPiece &detail);
void PlotSeamAllowance(QTextStream &out, const VLayoutPiece &detail); void PlotSeamAllowance(QTextStream &out, const VLayoutPiece &detail);
void PlotInternalPaths(QTextStream &out, const VLayoutPiece &detail); void PlotInternalPaths(QTextStream &out, const VLayoutPiece &detail);
void PlotPlaceLabels(QTextStream &out, const VLayoutPiece &detail); void PlotPlaceLabels(QTextStream &out, const VLayoutPiece &detail);
@ -263,4 +267,17 @@ inline void VHPGLEngine::SetShowGrainline(bool newShowGrainline)
m_showGrainline = newShowGrainline; m_showGrainline = newShowGrainline;
} }
//---------------------------------------------------------------------------------------------------------------------
inline void VHPGLEngine::SetBoundaryTogetherWithNotches(bool value)
{
Q_ASSERT(not isActive());
m_togetherWithNotches = value;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VHPGLEngine::IsBoundaryTogetherWithNotches() const -> bool
{
return m_togetherWithNotches;
}
#endif // VHPGLENGINE_H #endif // VHPGLENGINE_H

View File

@ -199,3 +199,21 @@ void VHPGLPaintDevice::SetShowGrainline(bool newShowGrainline)
} }
m_engine->SetShowGrainline(newShowGrainline); m_engine->SetShowGrainline(newShowGrainline);
} }
//---------------------------------------------------------------------------------------------------------------------
void VHPGLPaintDevice::SetBoundaryTogetherWithNotches(bool value)
{
if (m_engine->isActive())
{
qWarning("VHPGLPaintDevice::SetBoundaryTogetherWithNotches(), cannot set boundary together with notches while "
"HPGL is being generated");
return;
}
m_engine->SetBoundaryTogetherWithNotches(value);
}
//---------------------------------------------------------------------------------------------------------------------
auto VHPGLPaintDevice::IsBoundaryTogetherWithNotches() const -> bool
{
return m_engine->IsBoundaryTogetherWithNotches();
}

View File

@ -68,6 +68,9 @@ public:
auto GetShowGrainline() const -> bool; auto GetShowGrainline() const -> bool;
void SetShowGrainline(bool newShowGrainline); void SetShowGrainline(bool newShowGrainline);
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
auto ExportToHPGL(const QVector<VLayoutPiece> &details) const -> bool; auto ExportToHPGL(const QVector<VLayoutPiece> &details) const -> bool;
auto ExportToHPGL2(const QVector<VLayoutPiece> &details) const -> bool; auto ExportToHPGL2(const QVector<VLayoutPiece> &details) const -> bool;

View File

@ -37,14 +37,14 @@
#include "../vpatterndb/floatItemData/vgrainlinedata.h" #include "../vpatterndb/floatItemData/vgrainlinedata.h"
#include "../vpatterndb/vcontainer.h" #include "../vpatterndb/vcontainer.h"
#include "../vwidgets/vpiecegrainline.h" #include "../vwidgets/vpiecegrainline.h"
#include "qline.h"
#include "qmath.h"
#include "vabstractpiece_p.h" #include "vabstractpiece_p.h"
#include "vlayoutpiecepath.h"
#include "vrawsapoint.h" #include "vrawsapoint.h"
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QLine>
#include <QLineF> #include <QLineF>
#include <QPainterPath> #include <QPainterPath>
#include <QSet> #include <QSet>

View File

@ -139,9 +139,10 @@ public:
static auto LabelShapePath(const VLayoutPlaceLabel &label) -> QPainterPath; static auto LabelShapePath(const VLayoutPlaceLabel &label) -> QPainterPath;
static auto LabelShapePath(const PlaceLabelImg &shape) -> QPainterPath; static auto LabelShapePath(const PlaceLabelImg &shape) -> QPainterPath;
protected:
template <class T> template <class T>
static auto RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true) -> QVector<T>; static auto RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true) -> QVector<T>;
protected:
static auto IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint) -> bool; static auto IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint) -> bool;
static auto IsEkvPointOnLine(const VSAPoint &iPoint, const VSAPoint &prevPoint, const VSAPoint &nextPoint) -> bool; static auto IsEkvPointOnLine(const VSAPoint &iPoint, const VSAPoint &prevPoint, const VSAPoint &nextPoint) -> bool;
template <class T> template <class T>

View File

@ -28,13 +28,13 @@
#include "vbank.h" #include "vbank.h"
#include <climits>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <climits>
#include "../vmisc/vabstractvalapplication.h"
#include "../vmisc/compatibility.h"
#include "vlayoutdef.h"
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "../vmisc/compatibility.h"
#include "../vmisc/vabstractvalapplication.h"
#include "vlayoutdef.h"
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes") QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes")
@ -47,7 +47,7 @@ QT_WARNING_POP
// An annoying char define, from the Windows team in <rpcndr.h> // An annoying char define, from the Windows team in <rpcndr.h>
// #define small char // #define small char
// http://stuartjames.info/Journal/c--visual-studio-2012-vs2012--win8--converting-projects-up-some-conflicts-i-found.aspx // http://stuartjames.info/Journal/c--visual-studio-2012-vs2012--win8--converting-projects-up-some-conflicts-i-found.aspx
#if defined (Q_OS_WIN) && defined (Q_CC_MSVC) #if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
#pragma push_macro("small") #pragma push_macro("small")
#undef small #undef small
#endif #endif
@ -160,11 +160,12 @@ auto TakeFirstForPriority(const QMap<uint, QHash<int, qint64>> &container, uint
return -1; return -1;
} }
} } // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VBank::VBank() VBank::VBank()
{} {
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VBank::GetLayoutWidth() const -> qreal auto VBank::GetLayoutWidth() const -> qreal
@ -245,7 +246,7 @@ auto VBank::GetNext() -> int
} }
}; };
for (auto &group: groups) for (auto &group : groups)
{ {
int next = -1; int next = -1;
if (group != 0) // Group 0 must go last if (group != 0) // Group 0 must go last
@ -327,14 +328,14 @@ auto VBank::PrepareUnsorted() -> bool
{ {
QSet<uint> uniqueGroup; QSet<uint> uniqueGroup;
for (int i=0; i < details.size(); ++i) for (int i = 0; i < details.size(); ++i)
{ {
const qint64 square = details.at(i).Square(); const qint64 square = details.at(i).Square();
if (square <= 0) if (square <= 0)
{ {
qCCritical(lBank) << VAbstractValApplication::warningMessageSignature + qCCritical(lBank)
tr("Error of preparing data for layout: Detail '%1' square <= 0") << VAbstractValApplication::warningMessageSignature +
.arg(details.at(i).GetName()); tr("Error of preparing data for layout: Detail '%1' square <= 0").arg(details.at(i).GetName());
prepare = false; prepare = false;
return prepare; return prepare;
} }
@ -353,7 +354,7 @@ auto VBank::PrepareUnsorted() -> bool
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VBank::PrepareDetails() -> bool auto VBank::PrepareDetails(bool togetherWithNotches) -> bool
{ {
if (layoutWidth <= 0) if (layoutWidth <= 0)
{ {
@ -378,20 +379,22 @@ auto VBank::PrepareDetails() -> bool
diagonal = 0; diagonal = 0;
for (int i=0; i < details.size(); ++i) for (auto &detail : details)
{ {
details[i].SetLayoutWidth(layoutWidth); detail.SetLayoutWidth(layoutWidth);
details[i].SetLayoutAllowancePoints(); detail.SetLayoutAllowancePoints(togetherWithNotches);
if (not details.at(i).IsLayoutAllowanceValid()) if (not detail.IsLayoutAllowanceValid(togetherWithNotches))
{ {
const QString errorMsg = QObject::tr("Piece '%1' has invalid layout allowance. Please, check seam allowance" const QString errorMsg = QObject::tr("Piece '%1' has invalid layout allowance. Please, check seam allowance"
" to check how seam allowance behave.").arg(details.at(i).GetName()); " to check how seam allowance behave.")
VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) : .arg(detail.GetName());
qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; VAbstractApplication::VApp()->IsPedantic()
? throw VException(errorMsg)
: qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
} }
const qreal d = details.at(i).Diagonal(); const qreal d = detail.Diagonal();
if (d > diagonal) if (d > diagonal)
{ {
diagonal = d; diagonal = d;
@ -478,8 +481,8 @@ void VBank::PrepareThreeGroups(uint priority)
SqMaxMin(sMax, sMin, priority); SqMaxMin(sMax, sMin, priority);
const qint64 s1 = sMax - (sMax - sMin)/3; const qint64 s1 = sMax - (sMax - sMin) / 3;
const qint64 s2 = sMin + (sMax - sMin)/3; const qint64 s2 = sMin + (sMax - sMin) / 3;
const QHash<int, qint64> usortedGroup = unsorted.value(priority); const QHash<int, qint64> usortedGroup = unsorted.value(priority);
QHash<int, qint64>::const_iterator i = usortedGroup.constBegin(); QHash<int, qint64>::const_iterator i = usortedGroup.constBegin();
@ -510,7 +513,7 @@ void VBank::PrepareTwoGroups(uint priority)
SqMaxMin(sMax, sMin, priority); SqMaxMin(sMax, sMin, priority);
const qint64 s = (sMax + sMin)/2; const qint64 s = (sMax + sMin) / 2;
const QHash<int, qint64> usortedGroup = unsorted.value(priority); const QHash<int, qint64> usortedGroup = unsorted.value(priority);
QHash<int, qint64>::const_iterator i = usortedGroup.constBegin(); QHash<int, qint64>::const_iterator i = usortedGroup.constBegin();
while (i != usortedGroup.constEnd()) while (i != usortedGroup.constEnd())
@ -683,7 +686,6 @@ auto VBank::IsRotationNeeded() const -> bool
return false; return false;
} }
#if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
#if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
#pragma pop_macro("small") #pragma pop_macro("small")
#endif #endif

View File

@ -30,31 +30,33 @@
#define VBANK_H #define VBANK_H
#include <QHash> #include <QHash>
#include <QLoggingCategory>
#include <QMap> #include <QMap>
#include <QRectF> #include <QRectF>
#include <QVector> #include <QVector>
#include <QtGlobal> #include <QtGlobal>
#include <QLoggingCategory>
#include "../vmisc/typedef.h" #include "../vmisc/typedef.h"
#include "vlayoutpiece.h"
#include "vlayoutdef.h" #include "vlayoutdef.h"
#include "vlayoutpiece.h"
// An annoying char define, from the Windows team in <rpcndr.h> // An annoying char define, from the Windows team in <rpcndr.h>
// #define small char // #define small char
// http://stuartjames.info/Journal/c--visual-studio-2012-vs2012--win8--converting-projects-up-some-conflicts-i-found.aspx // http://stuartjames.info/Journal/c--visual-studio-2012-vs2012--win8--converting-projects-up-some-conflicts-i-found.aspx
#if defined (Q_OS_WIN) && defined (Q_CC_MSVC) #if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
#pragma push_macro("small") #pragma push_macro("small")
#undef small #undef small
#endif #endif
Q_DECLARE_LOGGING_CATEGORY(lBank) Q_DECLARE_LOGGING_CATEGORY(lBank) // NOLINT
class VBank class VBank
{ {
Q_DECLARE_TR_FUNCTIONS(VBank) // NOLINT Q_DECLARE_TR_FUNCTIONS(VBank) // NOLINT
public: public:
VBank(); VBank();
~VBank() = default;
auto GetLayoutWidth() const -> qreal; auto GetLayoutWidth() const -> qreal;
void SetLayoutWidth(qreal value); void SetLayoutWidth(qreal value);
@ -73,7 +75,7 @@ public:
void NotArranged(int i); void NotArranged(int i);
auto PrepareUnsorted() -> bool; auto PrepareUnsorted() -> bool;
auto PrepareDetails() -> bool; auto PrepareDetails(bool togetherWithNotches) -> bool;
void Reset(); void Reset();
void SetCaseType(Cases caseType); void SetCaseType(Cases caseType);
@ -122,7 +124,7 @@ private:
auto ArrangedDetail(QMap<uint, QMultiMap<qint64, int>> &container, int i) -> bool; auto ArrangedDetail(QMap<uint, QMultiMap<qint64, int>> &container, int i) -> bool;
}; };
#if defined (Q_OS_WIN) && defined (Q_CC_MSVC) #if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
#pragma pop_macro("small") #pragma pop_macro("small")
#endif #endif

View File

@ -0,0 +1,644 @@
/************************************************************************
**
** @file vboundary.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 24 11, 2023
**
** @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) 2023 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 "vboundary.h"
#include "../ifc/exception/vexception.h"
#include "../vgeometry/vgobject.h"
#include "../vmisc/vabstractapplication.h"
#include "vlayoutpiecepath.h"
#include <QPoint>
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
#include "../vmisc/compatibility.h"
#endif
using namespace Qt::Literals::StringLiterals;
namespace
{
//---------------------------------------------------------------------------------------------------------------------
void FillSequance(VBoundarySequenceItemData itemData, QList<VBoundarySequenceItemData> &sequence)
{
if (itemData.number <= 0)
{
itemData.number = 0;
sequence.append(itemData);
}
else if (sequence.isEmpty())
{
sequence.append(itemData);
}
else
{
for (int i = 0; i < sequence.size(); ++i)
{
if (sequence.at(i).number > itemData.number || sequence.at(i).number == 0)
{
sequence.insert(i, itemData);
return;
}
}
sequence.append(itemData);
}
}
//---------------------------------------------------------------------------------------------------------------------
auto PrepareSequenceItem(const QVector<VLayoutPoint> &path, bool drawMode, VBoundarySequenceItem type)
-> VBoundarySequenceItemData
{
VLayoutPiecePath countur(path);
countur.SetCutPath(!drawMode);
VBoundarySequenceItemData itemData;
itemData.item = QVariant::fromValue(countur);
itemData.type = type;
return itemData;
}
//---------------------------------------------------------------------------------------------------------------------
auto PrepareTPassmarkShape(const VLayoutPassmark &passmark, bool drawMode) -> QVector<QVector<VLayoutPoint>>
{
QVector<VLayoutPoint> shape1;
if (passmark.lines.isEmpty())
{
return {};
}
auto TurnPoint = [](QPointF point)
{
VLayoutPoint p(point);
p.SetTurnPoint(true);
return p;
};
QLineF line1 = passmark.lines.constFirst();
shape1.append(TurnPoint(line1.p1()));
shape1.append(TurnPoint(line1.p2()));
if (passmark.lines.size() <= 1)
{
return {shape1};
}
const QLineF &line2 = passmark.lines.constLast();
if (!drawMode)
{
shape1.append(TurnPoint(line2.p1()));
shape1.append(TurnPoint(line2.p2()));
shape1.append(TurnPoint(line1.p2()));
return {shape1};
}
QVector<VLayoutPoint> shape2;
shape2.append(TurnPoint(line2.p1()));
shape2.append(TurnPoint(line2.p2()));
return {shape1, shape2};
}
//---------------------------------------------------------------------------------------------------------------------
auto PrepareNoneBreakingPassmarkShape(const VLayoutPassmark &passmark) -> QVector<QVector<VLayoutPoint>>
{
auto TurnPoint = [](QPointF point)
{
VLayoutPoint p(point);
p.SetTurnPoint(true);
return p;
};
QVector<VLayoutPoint> shape;
shape.reserve(passmark.lines.size() + 1);
for (int i = 0; i < passmark.lines.size(); ++i)
{
const QLineF &line = passmark.lines.at(i);
shape.append(TurnPoint(line.p1()));
if (passmark.lines.size() - 1 == i)
{
shape.append(TurnPoint(line.p2()));
}
}
return {shape};
}
//---------------------------------------------------------------------------------------------------------------------
auto PrepareUPassmarkShape(const VLayoutPassmark &passmark) -> QVector<QVector<VLayoutPoint>>
{
auto LayoutPoint = [](QPointF point, bool turnPoint, bool curvePoint)
{
VLayoutPoint p(point);
p.SetTurnPoint(turnPoint);
p.SetCurvePoint(curvePoint);
return p;
};
qreal radius = QLineF(passmark.baseLine.p1(), passmark.lines.constFirst().p1()).length();
if (passmark.baseLine.length() - radius > accuracyPointOnLine)
{
QVector<QLineF> lines = passmark.lines;
if (lines.size() < 3)
{
return {};
}
QLineF line1 = lines.takeFirst();
QVector<VLayoutPoint> shape;
shape.reserve(4 + passmark.lines.size() + 1);
shape.append(LayoutPoint(line1.p1(), true, false));
shape.append(LayoutPoint(line1.p2(), true, true));
QLineF line2 = lines.takeLast();
for (int i = 0; i < passmark.lines.size(); ++i)
{
const QLineF &line = passmark.lines.at(i);
shape.append(LayoutPoint(line.p1(), false, true));
if (passmark.lines.size() - 1 == i)
{
shape.append(LayoutPoint(line.p2(), false, true));
}
}
shape.append(LayoutPoint(line2.p1(), true, true));
shape.append(LayoutPoint(line2.p2(), true, false));
return {shape};
}
QVector<VLayoutPoint> shape;
shape.reserve(passmark.lines.size() + 1);
for (int i = 0; i < passmark.lines.size(); ++i)
{
const QLineF &line = passmark.lines.at(i);
shape.append(LayoutPoint(line.p1(), false, true));
if (passmark.lines.size() - 1 == i)
{
shape.append(LayoutPoint(line.p2(), false, true));
}
}
if (!shape.isEmpty())
{
shape.first().SetTurnPoint(true);
shape.last().SetTurnPoint(true);
}
return {shape};
}
//---------------------------------------------------------------------------------------------------------------------
auto PreparePassmarkShape(const VLayoutPassmark &passmark, bool drawMode) -> QVector<QVector<VLayoutPoint>>
{
switch (passmark.type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::InternalVMark:
case PassmarkLineType::ExternalVMark:
case PassmarkLineType::BoxMark:
case PassmarkLineType::CheckMark:
return PrepareNoneBreakingPassmarkShape(passmark);
break;
case PassmarkLineType::TMark:
return PrepareTPassmarkShape(passmark, drawMode);
break;
case PassmarkLineType::UMark:
return PrepareUPassmarkShape(passmark);
break;
default:
break;
}
return {};
}
//---------------------------------------------------------------------------------------------------------------------
void ConvertTwoLinesPassmark(const VLayoutPassmark &passmark, QList<VBoundarySequenceItemData> &notchSequence)
{
if (!passmark.lines.isEmpty())
{
VLayoutPassmark line1 = passmark;
line1.lines = {passmark.lines.constFirst()};
line1.type = PassmarkLineType::OneLine;
line1.baseLine = passmark.lines.constFirst();
VBoundarySequenceItemData itemData;
itemData.item = QVariant::fromValue(line1);
itemData.type = VBoundarySequenceItem::Passmark;
FillSequance(itemData, notchSequence);
}
if (passmark.lines.size() > 1)
{
VLayoutPassmark line2 = passmark;
line2.lines = {passmark.lines.constLast()};
line2.type = PassmarkLineType::OneLine;
line2.baseLine = passmark.lines.constLast();
VBoundarySequenceItemData itemData;
itemData.item = QVariant::fromValue(line2);
itemData.type = VBoundarySequenceItem::Passmark;
FillSequance(itemData, notchSequence);
}
}
//---------------------------------------------------------------------------------------------------------------------
void ConvertThreeLinesPassmark(const VLayoutPassmark &passmark, QList<VBoundarySequenceItemData> &notchSequence)
{
if (!passmark.lines.isEmpty())
{
VLayoutPassmark line1 = passmark;
line1.lines = {passmark.lines.constFirst()};
line1.type = PassmarkLineType::OneLine;
line1.baseLine = passmark.lines.constFirst();
VBoundarySequenceItemData itemData;
itemData.item = QVariant::fromValue(line1);
itemData.type = VBoundarySequenceItem::Passmark;
FillSequance(itemData, notchSequence);
}
if (passmark.lines.size() > 1)
{
VLayoutPassmark line2 = passmark;
line2.lines = {passmark.lines.at(1)};
line2.type = PassmarkLineType::OneLine;
line2.baseLine = passmark.lines.at(1);
VBoundarySequenceItemData itemData;
itemData.item = QVariant::fromValue(line2);
itemData.type = VBoundarySequenceItem::Passmark;
FillSequance(itemData, notchSequence);
}
if (passmark.lines.size() > 2)
{
VLayoutPassmark line3 = passmark;
line3.lines = {passmark.lines.constLast()};
line3.type = PassmarkLineType::OneLine;
line3.baseLine = passmark.lines.constLast();
VBoundarySequenceItemData itemData;
itemData.item = QVariant::fromValue(line3);
itemData.type = VBoundarySequenceItem::Passmark;
FillSequance(itemData, notchSequence);
}
}
//---------------------------------------------------------------------------------------------------------------------
auto SubdividePath(const QVector<VLayoutPoint> &boundary, const QPointF &p, QVector<VLayoutPoint> &sub1,
QVector<VLayoutPoint> &sub2) -> bool
{
if (boundary.size() < 2)
{
return false;
}
bool found = false;
sub1.clear();
sub2.clear();
auto BreakPoint = [p]()
{
VLayoutPoint breakPoint(p);
breakPoint.SetTurnPoint(true);
return breakPoint;
};
for (qint32 i = 0; i < boundary.count() - 1; ++i)
{
if (found)
{
sub2.append(boundary.at(i));
if (i + 1 == boundary.count() - 1)
{
sub2.append(boundary.at(i + 1));
}
continue;
}
if (!VGObject::IsPointOnLineSegment(p, static_cast<QPointF>(boundary.at(i)),
static_cast<QPointF>(boundary.at(i + 1))))
{
sub1.append(boundary.at(i));
continue;
}
if (not VFuzzyComparePoints(boundary.at(i), p))
{
sub1.append(boundary.at(i));
sub1.append(BreakPoint());
}
else
{
if (not sub1.isEmpty())
{
sub1.append(BreakPoint());
}
}
if (not VFuzzyComparePoints(boundary.at(i + 1), p))
{
sub2.append(BreakPoint());
if (i + 1 == boundary.count() - 1)
{
sub2.append(boundary.at(i + 1));
}
}
found = true;
}
if (not found)
{
sub1.clear();
}
return found;
}
//---------------------------------------------------------------------------------------------------------------------
auto InsertDisconnect(QList<VBoundarySequenceItemData> &sequence, int i, const VBoundarySequenceItemData &item,
bool drawMode) -> bool
{
auto passmark = item.item.value<VLayoutPassmark>();
bool inserted = false;
const auto boundary = sequence.at(i).item.value<VLayoutPiecePath>().Points();
QVector<VLayoutPoint> sub1;
QVector<VLayoutPoint> sub2;
if (!SubdividePath(boundary, passmark.baseLine.p1(), sub1, sub2))
{
return false;
}
sequence.removeAt(i);
if (not sub2.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(sub2, drawMode, VBoundarySequenceItem::Boundary));
}
QVector<QVector<VLayoutPoint>> shape = PreparePassmarkShape(passmark, drawMode);
for (auto &subShape : shape)
{
sequence.insert(i, PrepareSequenceItem(subShape, drawMode, VBoundarySequenceItem::PassmarkShape));
}
if (not sub1.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(sub1, drawMode, VBoundarySequenceItem::Boundary));
}
inserted = true;
return inserted;
}
//---------------------------------------------------------------------------------------------------------------------
auto InsertCutOut(QList<VBoundarySequenceItemData> &sequence, int i, const VBoundarySequenceItemData &item,
bool drawMode) -> bool
{
auto passmark = item.item.value<VLayoutPassmark>();
QVector<QVector<VLayoutPoint>> shape = PreparePassmarkShape(passmark, drawMode);
if (shape.isEmpty())
{
return false;
}
const QVector<VLayoutPoint> &subShape = shape.constFirst();
if (subShape.size() < 2)
{
return false;
}
const auto boundary = sequence.at(i).item.value<VLayoutPiecePath>().Points();
QVector<VLayoutPoint> startSub1;
QVector<VLayoutPoint> startSub2;
if (!SubdividePath(boundary, subShape.constFirst(), startSub1, startSub2))
{
return false;
}
QVector<VLayoutPoint> endSub1;
QVector<VLayoutPoint> endSub2;
if (!SubdividePath(boundary, subShape.constLast(), endSub1, endSub2))
{
return false;
}
sequence.removeAt(i);
if (not endSub2.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(endSub2, drawMode, VBoundarySequenceItem::Boundary));
}
sequence.insert(i, PrepareSequenceItem(subShape, drawMode, VBoundarySequenceItem::PassmarkShape));
if (not startSub1.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(startSub1, drawMode, VBoundarySequenceItem::Boundary));
}
return true;
}
} // namespace
//---------------------------------------------------------------------------------------------------------------------
VBoundary::VBoundary(const QVector<VLayoutPoint> &boundary, bool seamAllowance, bool builtInSeamAllowance)
: m_boundary(boundary),
m_seamAllowance(seamAllowance),
m_builtInSeamAllowance(builtInSeamAllowance)
{
}
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::Combine(const QVector<VLayoutPassmark> &passmarks, bool drawMode, bool layoutAllowance) const
-> QList<VBoundarySequenceItemData>
{
QList<VBoundarySequenceItemData> notchSequence;
for (const auto &passmark : passmarks)
{
if (SkipPassmark(passmark, drawMode, layoutAllowance))
{
continue;
}
if (passmark.type == PassmarkLineType::TwoLines)
{
ConvertTwoLinesPassmark(passmark, notchSequence);
continue;
}
if (passmark.type == PassmarkLineType::ThreeLines)
{
ConvertThreeLinesPassmark(passmark, notchSequence);
continue;
}
VBoundarySequenceItemData itemData;
itemData.item = QVariant::fromValue(passmark);
itemData.type = VBoundarySequenceItem::Passmark;
FillSequance(itemData, notchSequence);
}
QList<VBoundarySequenceItemData> sequence;
sequence.append(PrepareSequenceItem(m_boundary, drawMode, VBoundarySequenceItem::Boundary));
for (auto &item : notchSequence)
{
if (item.type == VBoundarySequenceItem::Passmark)
{
InsertPassmark(item, sequence, drawMode);
}
}
return sequence;
}
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::SkipPassmark(const VLayoutPassmark &passmark, bool drawMode, bool layoutAllowance) const -> bool
{
if (m_seamAllowance)
{
if ((m_builtInSeamAllowance && !passmark.isBuiltIn) || (!m_builtInSeamAllowance && passmark.isBuiltIn))
{
return true;
}
}
else
{
if (!passmark.isBuiltIn)
{
return true;
}
}
if (layoutAllowance && (passmark.type == PassmarkLineType::ExternalVMark ||
passmark.type == PassmarkLineType::OneLine || passmark.type == PassmarkLineType::TwoLines ||
passmark.type == PassmarkLineType::ThreeLines || passmark.type == PassmarkLineType::TMark))
{
return true;
}
if (!drawMode && passmark.type == PassmarkLineType::ExternalVMark)
{
return true;
}
return false;
}
//---------------------------------------------------------------------------------------------------------------------
void VBoundary::InsertPassmark(const VBoundarySequenceItemData &item, QList<VBoundarySequenceItemData> &sequence,
bool drawMode) const
{
auto passmark = item.item.value<VLayoutPassmark>();
bool inserted = false;
for (int i = 0; i < sequence.size(); ++i)
{
const VBoundarySequenceItemData &itemData = sequence.at(i);
if (itemData.type != VBoundarySequenceItem::Boundary)
{
continue;
}
switch (passmark.type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::TMark:
case PassmarkLineType::ExternalVMark:
inserted = InsertDisconnect(sequence, i, item, drawMode);
break;
case PassmarkLineType::UMark:
case PassmarkLineType::InternalVMark:
case PassmarkLineType::BoxMark:
case PassmarkLineType::CheckMark:
inserted = InsertCutOut(sequence, i, item, drawMode);
break;
default:
break;
}
if (inserted)
{
break;
}
}
if (not inserted)
{
QString pieceName;
if (!m_pieceName.isEmpty())
{
pieceName = tr("Piece '%1'.").arg(m_pieceName) + ' '_L1;
}
QString errorMsg;
if (!passmark.label.isEmpty())
{
errorMsg = pieceName + tr("Unable to insert notch for point '%1'.").arg(passmark.label);
}
else
{
errorMsg = pieceName + tr("Unable to insert notch.");
}
VAbstractApplication::VApp()->IsPedantic()
? throw VException(errorMsg)
: qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
}
}

View File

@ -0,0 +1,85 @@
/************************************************************************
**
** @file vboundary.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 24 11, 2023
**
** @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) 2023 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 VBOUNDARY_H
#define VBOUNDARY_H
#include "../vgeometry/vgeometrydef.h"
#include "vlayoutpoint.h"
#include <QCoreApplication>
#include <QList>
#include <QVariant>
#include <QVector>
enum class VBoundarySequenceItem : char
{
Boundary,
Passmark,
PassmarkShape,
Unknown
};
struct VBoundarySequenceItemData
{
int number{0};
VBoundarySequenceItem type{VBoundarySequenceItem::Unknown};
QVariant item{};
};
class VBoundary
{
Q_DECLARE_TR_FUNCTIONS(VBoundary) // NOLINT
public:
VBoundary(const QVector<VLayoutPoint> &boundary, bool seamAllowance, bool builtInSeamAllowance = false);
auto Combine(const QVector<VLayoutPassmark> &passmarks, bool drawMode, bool layoutAllowance = false) const
-> QList<VBoundarySequenceItemData>;
void SetPieceName(const QString &newPieceName);
private:
QVector<VLayoutPoint> m_boundary;
bool m_seamAllowance;
bool m_builtInSeamAllowance;
QString m_pieceName{};
auto SkipPassmark(const VLayoutPassmark &passmark, bool drawMode, bool layoutAllowance) const -> bool;
void InsertPassmark(const VBoundarySequenceItemData &item, QList<VBoundarySequenceItemData> &sequence,
bool drawMode) const;
};
//---------------------------------------------------------------------------------------------------------------------
inline void VBoundary::SetPieceName(const QString &newPieceName)
{
m_pieceName = newPieceName;
}
#endif // VBOUNDARY_H

View File

@ -30,7 +30,8 @@ HEADERS += \
$$PWD/vlayoutpiecepath.h \ $$PWD/vlayoutpiecepath.h \
$$PWD/vlayoutpiecepath_p.h \ $$PWD/vlayoutpiecepath_p.h \
$$PWD/vbestsquare_p.h \ $$PWD/vbestsquare_p.h \
$$PWD/vrawsapoint.h $$PWD/vrawsapoint.h \
$$PWD/vboundary.h
SOURCES += \ SOURCES += \
$$PWD/vlayoutexporter.cpp \ $$PWD/vlayoutexporter.cpp \
@ -50,6 +51,7 @@ SOURCES += \
$$PWD/vabstractpiece.cpp \ $$PWD/vabstractpiece.cpp \
$$PWD/vlayoutpiece.cpp \ $$PWD/vlayoutpiece.cpp \
$$PWD/vlayoutpiecepath.cpp \ $$PWD/vlayoutpiecepath.cpp \
$$PWD/vrawsapoint.cpp $$PWD/vrawsapoint.cpp \
$$PWD/vboundary.cpp
*msvc*:SOURCES += $$PWD/stable.cpp *msvc*:SOURCES += $$PWD/stable.cpp

View File

@ -55,7 +55,9 @@ VLib {
"vabstractpiece.cpp", "vabstractpiece.cpp",
"vlayoutpiece.cpp", "vlayoutpiece.cpp",
"vlayoutpiecepath.cpp", "vlayoutpiecepath.cpp",
"vrawsapoint.cpp" "vrawsapoint.cpp",
"vboundary.h",
"vboundary.cpp"
]; ];
if (Qt.core.versionMajor >= 5 && Qt.core.versionMinor < 12) { if (Qt.core.versionMajor >= 5 && Qt.core.versionMinor < 12) {

View File

@ -324,6 +324,7 @@ void VLayoutExporter::ExportToAAMADXF(const QVector<VLayoutPiece> &details) cons
generator.SetInsunits(VarInsunits::Millimeters); // Decided to always use mm. See issue #745 generator.SetInsunits(VarInsunits::Millimeters); // Decided to always use mm. See issue #745
generator.SetXScale(m_xScale); generator.SetXScale(m_xScale);
generator.SetYScale(m_yScale); generator.SetYScale(m_yScale);
generator.SetBoundaryTogetherWithNotches(m_togetherWithNotches);
if (not generator.ExportToAAMA(details)) if (not generator.ExportToAAMA(details))
{ {
qCritical() << tr("Can't create an AAMA dxf file.") << generator.ErrorString(); qCritical() << tr("Can't create an AAMA dxf file.") << generator.ErrorString();
@ -342,6 +343,7 @@ void VLayoutExporter::ExportToASTMDXF(const QVector<VLayoutPiece> &details) cons
generator.SetInsunits(VarInsunits::Millimeters); // Decided to always use mm. See issue #745 generator.SetInsunits(VarInsunits::Millimeters); // Decided to always use mm. See issue #745
generator.SetXScale(m_xScale); generator.SetXScale(m_xScale);
generator.SetYScale(m_yScale); generator.SetYScale(m_yScale);
generator.SetBoundaryTogetherWithNotches(m_togetherWithNotches);
if (not generator.ExportToASTM(details)) if (not generator.ExportToASTM(details))
{ {
qCritical() << tr("Can't create an ASTM dxf file.") << generator.ErrorString(); qCritical() << tr("Can't create an ASTM dxf file.") << generator.ErrorString();
@ -383,6 +385,7 @@ void VLayoutExporter::ExportToHPGL(const QVector<VLayoutPiece> &details) const
generator.SetSingleLineFont(m_singleLineFont); generator.SetSingleLineFont(m_singleLineFont);
generator.SetSingleStrokeOutlineFont(m_singleStrokeOutlineFont); generator.SetSingleStrokeOutlineFont(m_singleStrokeOutlineFont);
generator.SetPenWidth(m_penWidth); generator.SetPenWidth(m_penWidth);
generator.SetBoundaryTogetherWithNotches(m_togetherWithNotches);
if (not generator.ExportToHPGL(details)) if (not generator.ExportToHPGL(details))
{ {
qCritical() << tr("Can't create an HP-GL file."); qCritical() << tr("Can't create an HP-GL file.");
@ -401,6 +404,7 @@ void VLayoutExporter::ExportToHPGL2(const QVector<VLayoutPiece> &details) const
generator.SetSingleLineFont(m_singleLineFont); generator.SetSingleLineFont(m_singleLineFont);
generator.SetSingleStrokeOutlineFont(m_singleStrokeOutlineFont); generator.SetSingleStrokeOutlineFont(m_singleStrokeOutlineFont);
generator.SetPenWidth(m_penWidth); generator.SetPenWidth(m_penWidth);
generator.SetBoundaryTogetherWithNotches(m_togetherWithNotches);
if (not generator.ExportToHPGL2(details)) if (not generator.ExportToHPGL2(details))
{ {
qCritical() << tr("Can't create an HP-GL file."); qCritical() << tr("Can't create an HP-GL file.");

View File

@ -83,6 +83,9 @@ public:
auto DxfVersion() const -> int; auto DxfVersion() const -> int;
void SetDxfVersion(int dxfVersion); void SetDxfVersion(int dxfVersion);
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
void ExportToSVG(QGraphicsScene *scene, const QList<QGraphicsItem *> &details) const; void ExportToSVG(QGraphicsScene *scene, const QList<QGraphicsItem *> &details) const;
void ExportToPNG(QGraphicsScene *scene, const QList<QGraphicsItem *> &details) const; void ExportToPNG(QGraphicsScene *scene, const QList<QGraphicsItem *> &details) const;
void ExportToTIF(QGraphicsScene *scene, const QList<QGraphicsItem *> &details) const; void ExportToTIF(QGraphicsScene *scene, const QList<QGraphicsItem *> &details) const;
@ -134,6 +137,7 @@ private:
bool m_singleLineFont{false}; bool m_singleLineFont{false};
bool m_singleStrokeOutlineFont{false}; bool m_singleStrokeOutlineFont{false};
int m_penWidth{1}; int m_penWidth{1};
bool m_togetherWithNotches{false};
void ExportToPDF(QGraphicsScene *scene, const QList<QGraphicsItem *> &details, const QString &filename) const; void ExportToPDF(QGraphicsScene *scene, const QList<QGraphicsItem *> &details, const QString &filename) const;
}; };
@ -270,6 +274,18 @@ inline void VLayoutExporter::SetDxfVersion(int dxfVersion)
m_dxfVersion = dxfVersion; m_dxfVersion = dxfVersion;
} }
//---------------------------------------------------------------------------------------------------------------------
inline void VLayoutExporter::SetBoundaryTogetherWithNotches(bool value)
{
m_togetherWithNotches = value;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VLayoutExporter::IsBoundaryTogetherWithNotches() const -> bool
{
return m_togetherWithNotches;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
inline auto VLayoutExporter::offset() const -> QPointF inline auto VLayoutExporter::offset() const -> QPointF
{ {

View File

@ -42,32 +42,7 @@
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VLayoutGenerator::VLayoutGenerator(QObject *parent) VLayoutGenerator::VLayoutGenerator(QObject *parent)
: QObject(parent), : QObject(parent)
papers(),
bank(new VBank()),
paperHeight(0),
paperWidth(0),
margins(),
usePrinterFields(true),
#ifdef Q_CC_MSVC
// See https://stackoverflow.com/questions/15750917/initializing-stdatomic-bool
stopGeneration(ATOMIC_VAR_INIT(false)),
#else
stopGeneration(false),
#endif
state(LayoutErrors::NoError),
shift(0),
rotate(true),
followGrainline(false),
rotationNumber(2),
autoCropLength(false),
autoCropWidth(false),
saveLength(false),
unitePages(false),
stripOptimizationEnabled(false),
multiplier(1),
stripOptimization(false),
textAsPaths(false)
{ {
} }
@ -134,7 +109,7 @@ void VLayoutGenerator::Generate(const QElapsedTimer &timer, qint64 timeout, Layo
if (VFuzzyComparePossibleNulls(shift, -1)) if (VFuzzyComparePossibleNulls(shift, -1))
{ {
if (bank->PrepareDetails()) if (bank->PrepareDetails(togetherWithNotches))
{ {
SetShift(ToPixel(1, Unit::Cm)); SetShift(ToPixel(1, Unit::Cm));
} }
@ -308,7 +283,8 @@ auto VLayoutGenerator::GetPapersItems() const -> QList<QGraphicsItem *>
list.reserve(papers.count()); list.reserve(papers.count());
for (const auto &paper : papers) for (const auto &paper : papers)
{ {
list.append(paper.GetPaperItem(autoCropLength, autoCropWidth, IsTestAsPaths())); list.append(
paper.GetPaperItem(autoCropLength, autoCropWidth, textAsPaths, togetherWithNotches, showLayoutAllowance));
} }
return list; return list;
} }
@ -332,7 +308,7 @@ auto VLayoutGenerator::GetAllDetailsItems() const -> QList<QList<QGraphicsItem *
list.reserve(papers.count()); list.reserve(papers.count());
for (const auto &paper : papers) for (const auto &paper : papers)
{ {
list.append(paper.GetItemDetails(IsTestAsPaths())); list.append(paper.GetItemDetails(textAsPaths, togetherWithNotches, showLayoutAllowance));
} }
return list; return list;
} }
@ -390,6 +366,30 @@ void VLayoutGenerator::SetTextAsPaths(bool value)
textAsPaths = value; textAsPaths = value;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutGenerator::IsBoundaryTogetherWithNotches() const -> bool
{
return togetherWithNotches;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutGenerator::SetBoundaryTogetherWithNotches(bool value)
{
togetherWithNotches = value;
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutGenerator::IsShowLayoutAllowance() const -> bool
{
return showLayoutAllowance;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutGenerator::SetShowLayoutAllowance(bool value)
{
showLayoutAllowance = value;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutGenerator::IsRotationNeeded() const -> bool auto VLayoutGenerator::IsRotationNeeded() const -> bool
{ {
@ -397,10 +397,8 @@ auto VLayoutGenerator::IsRotationNeeded() const -> bool
{ {
return bank->IsRotationNeeded(); return bank->IsRotationNeeded();
} }
else
{ return true;
return true;
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -29,30 +29,30 @@
#ifndef VLAYOUTGENERATOR_H #ifndef VLAYOUTGENERATOR_H
#define VLAYOUTGENERATOR_H #define VLAYOUTGENERATOR_H
#include <QList> #include <QList>
#include <QMargins>
#include <QMetaObject> #include <QMetaObject>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QVector> #include <QVector>
#include <QtGlobal> #include <QtGlobal>
#include <memory>
#include <atomic> #include <atomic>
#include <QMargins> #include <memory>
#include "vbank.h" #include "vbank.h"
#include "vlayoutdef.h" #include "vlayoutdef.h"
#include "vlayoutpaper.h"
class QGraphicsItem; class QGraphicsItem;
class VLayoutPaper;
class QElapsedTimer; class QElapsedTimer;
class VLayoutGenerator :public QObject class VLayoutGenerator : public QObject
{ {
Q_OBJECT // NOLINT Q_OBJECT // NOLINT
public: public:
explicit VLayoutGenerator(QObject *parent = nullptr); explicit VLayoutGenerator(QObject *parent = nullptr);
virtual ~VLayoutGenerator() override; ~VLayoutGenerator() override;
void SetDetails(const QVector<VLayoutPiece> &details); void SetDetails(const QVector<VLayoutPiece> &details);
void SetLayoutWidth(qreal width); void SetLayoutWidth(qreal width);
@ -70,14 +70,14 @@ public:
void SetNestingTime(int value); void SetNestingTime(int value);
auto GetEfficiencyCoefficient() const -> qreal; auto GetEfficiencyCoefficient() const -> qreal;
void SetEfficiencyCoefficient(qreal coefficient); void SetEfficiencyCoefficient(qreal coefficient);
auto IsUsePrinterFields() const -> bool; auto IsUsePrinterFields() const -> bool;
auto GetPrinterFields() const -> QMarginsF; auto GetPrinterFields() const -> QMarginsF;
void SetPrinterFields(bool usePrinterFields, const QMarginsF &value); void SetPrinterFields(bool usePrinterFields, const QMarginsF &value);
auto GetShift() const -> qreal; auto GetShift() const -> qreal;
void SetShift(qreal shift); void SetShift(qreal shift);
void Generate(const QElapsedTimer &timer, qint64 timeout, LayoutErrors previousState = LayoutErrors::NoError); void Generate(const QElapsedTimer &timer, qint64 timeout, LayoutErrors previousState = LayoutErrors::NoError);
@ -124,7 +124,7 @@ public:
void SetUnitePages(bool value); void SetUnitePages(bool value);
auto GetMultiplier() const -> quint8; auto GetMultiplier() const -> quint8;
void SetMultiplier(quint8 value); void SetMultiplier(quint8 value);
auto IsStripOptimization() const -> bool; auto IsStripOptimization() const -> bool;
void SetStripOptimization(bool value); void SetStripOptimization(bool value);
@ -132,6 +132,12 @@ public:
auto IsTestAsPaths() const -> bool; auto IsTestAsPaths() const -> bool;
void SetTextAsPaths(bool value); void SetTextAsPaths(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
void SetBoundaryTogetherWithNotches(bool value);
auto IsShowLayoutAllowance() const -> bool;
void SetShowLayoutAllowance(bool value);
auto IsRotationNeeded() const -> bool; auto IsRotationNeeded() const -> bool;
auto IsPortrait() const -> bool; auto IsPortrait() const -> bool;
@ -142,29 +148,37 @@ public slots:
private: private:
Q_DISABLE_COPY_MOVE(VLayoutGenerator) // NOLINT Q_DISABLE_COPY_MOVE(VLayoutGenerator) // NOLINT
QVector<VLayoutPaper> papers; QVector<VLayoutPaper> papers{};
VBank *bank; VBank *bank{new VBank()};
qreal paperHeight; qreal paperHeight{0};
qreal paperWidth; qreal paperWidth{0};
QMarginsF margins; QMarginsF margins{};
bool usePrinterFields; bool usePrinterFields{true};
std::atomic_bool stopGeneration; std::atomic_bool stopGeneration{
LayoutErrors state; #ifdef Q_CC_MSVC
qreal shift; ATOMIC_VAR_INIT(false)
bool rotate; #else
bool followGrainline; false
int rotationNumber; #endif
bool autoCropLength; };
bool autoCropWidth; LayoutErrors state{LayoutErrors::NoError};
bool saveLength; qreal shift{0};
bool rotate{true};
bool followGrainline{false};
int rotationNumber{2};
bool autoCropLength{false};
bool autoCropWidth{false};
bool saveLength{false};
bool preferOneSheetSolution{false}; bool preferOneSheetSolution{false};
bool unitePages; bool unitePages{false};
bool stripOptimizationEnabled; bool stripOptimizationEnabled{false};
quint8 multiplier; quint8 multiplier{1};
bool stripOptimization; bool stripOptimization{false};
bool textAsPaths; bool textAsPaths{false};
bool togetherWithNotches{false};
int nestingTime{1}; int nestingTime{1};
qreal efficiencyCoefficient{0.0}; qreal efficiencyCoefficient{0.0};
bool showLayoutAllowance{false};
auto PageHeight() const -> int; auto PageHeight() const -> int;
auto PageWidth() const -> int; auto PageWidth() const -> int;
@ -172,7 +186,7 @@ private:
void OptimizeWidth(); void OptimizeWidth();
void GatherPages(); void GatherPages();
void UnitePages(); void UnitePages();
void UniteDetails(int j, QList<QList<VLayoutPiece> > &nDetails, qreal length, int i) const; void UniteDetails(int j, QList<QList<VLayoutPiece>> &nDetails, qreal length, int i) const;
void UnitePapers(int j, QList<qreal> &papersLength, qreal length); void UnitePapers(int j, QList<qreal> &papersLength, qreal length);
auto MoveDetails(qreal length, const QVector<VLayoutPiece> &details) const -> QList<VLayoutPiece>; auto MoveDetails(qreal length, const QVector<VLayoutPiece> &details) const -> QList<VLayoutPiece>;
auto MasterPage() const -> VLayoutPaper; auto MasterPage() const -> VLayoutPaper;

View File

@ -321,7 +321,8 @@ auto VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutPiece
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPaper::GetPaperItem(bool autoCropLength, bool autoCropWidth, bool textAsPaths) const -> QGraphicsRectItem * auto VLayoutPaper::GetPaperItem(bool autoCropLength, bool autoCropWidth, bool textAsPaths, bool togetherWithNotches,
bool showLayoutAllowance) const -> QGraphicsRectItem *
{ {
int height = d->globalContour.GetHeight(); int height = d->globalContour.GetHeight();
int width = d->globalContour.GetWidth(); int width = d->globalContour.GetWidth();
@ -329,7 +330,7 @@ auto VLayoutPaper::GetPaperItem(bool autoCropLength, bool autoCropWidth, bool te
if (autoCropLength || autoCropWidth) if (autoCropLength || autoCropWidth)
{ {
QScopedPointer<QGraphicsScene> scene(new QGraphicsScene()); QScopedPointer<QGraphicsScene> scene(new QGraphicsScene());
QList<QGraphicsItem *> list = GetItemDetails(textAsPaths); QList<QGraphicsItem *> list = GetItemDetails(textAsPaths, togetherWithNotches, showLayoutAllowance);
for (auto *item : list) for (auto *item : list)
{ {
scene->addItem(item); scene->addItem(item);
@ -417,13 +418,14 @@ auto VLayoutPaper::GetGlobalContour() const -> QGraphicsPathItem *
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPaper::GetItemDetails(bool textAsPaths) const -> QList<QGraphicsItem *> auto VLayoutPaper::GetItemDetails(bool textAsPaths, bool togetherWithNotches, bool showLayoutAllowance) const
-> QList<QGraphicsItem *>
{ {
QList<QGraphicsItem *> list; QList<QGraphicsItem *> list;
list.reserve(d->details.count()); list.reserve(d->details.count());
for (const auto &detail : d->details) for (const auto &detail : d->details)
{ {
list.append(detail.GetItem(textAsPaths)); list.append(detail.GetItem(textAsPaths, togetherWithNotches, showLayoutAllowance));
} }
return list; return list;
} }

View File

@ -92,10 +92,12 @@ public:
auto ArrangeDetail(const VLayoutPiece &detail, std::atomic_bool &stop) -> bool; auto ArrangeDetail(const VLayoutPiece &detail, std::atomic_bool &stop) -> bool;
auto Count() const -> vsizetype; auto Count() const -> vsizetype;
Q_REQUIRED_RESULT auto GetPaperItem(bool autoCropLength, bool autoCropWidth, bool textAsPaths) const Q_REQUIRED_RESULT auto GetPaperItem(bool autoCropLength, bool autoCropWidth, bool textAsPaths,
bool togetherWithNotches, bool showLayoutAllowance) const
-> QGraphicsRectItem *; -> QGraphicsRectItem *;
Q_REQUIRED_RESULT auto GetGlobalContour() const -> QGraphicsPathItem *; Q_REQUIRED_RESULT auto GetGlobalContour() const -> QGraphicsPathItem *;
Q_REQUIRED_RESULT auto GetItemDetails(bool textAsPaths) const -> QList<QGraphicsItem *>; Q_REQUIRED_RESULT auto GetItemDetails(bool textAsPaths, bool togetherWithNotches, bool showLayoutAllowance) const
-> QList<QGraphicsItem *>;
auto GetDetails() const -> QVector<VLayoutPiece>; auto GetDetails() const -> QVector<VLayoutPiece>;
void SetDetails(const QVector<VLayoutPiece> &details); void SetDetails(const QVector<VLayoutPiece> &details);

View File

@ -39,6 +39,7 @@
#include <QMessageLogger> #include <QMessageLogger>
#include <QPainterPath> #include <QPainterPath>
#include <QPoint> #include <QPoint>
#include <QPolygon>
#include <QPolygonF> #include <QPolygonF>
#include <QTransform> #include <QTransform>
#include <QUuid> #include <QUuid>
@ -51,6 +52,7 @@
#include "../vgeometry/vlayoutplacelabel.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "../vgeometry/vplacelabelitem.h" #include "../vgeometry/vplacelabelitem.h"
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vlayout/vabstractpiece.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vmisc/literals.h" #include "../vmisc/literals.h"
#include "../vmisc/svgfont/vsvgfontdatabase.h" #include "../vmisc/svgfont/vsvgfontdatabase.h"
@ -65,6 +67,7 @@
#include "../vpatterndb/vpassmark.h" #include "../vpatterndb/vpassmark.h"
#include "../vpatterndb/vpiecenode.h" #include "../vpatterndb/vpiecenode.h"
#include "../vwidgets/vpiecegrainline.h" #include "../vwidgets/vpiecegrainline.h"
#include "vboundary.h"
#include "vgraphicsfillitem.h" #include "vgraphicsfillitem.h"
#include "vlayoutpiece_p.h" #include "vlayoutpiece_p.h"
#include "vtextmanager.h" #include "vtextmanager.h"
@ -241,14 +244,6 @@ auto ConvertPlaceLabels(const VPiece &piece, const VContainer *pattern) -> QVect
auto PrepareSAPassmark(const VPiece &piece, const VContainer *pattern, const VPassmark &passmark, PassmarkSide side, auto PrepareSAPassmark(const VPiece &piece, const VContainer *pattern, const VPassmark &passmark, PassmarkSide side,
bool &ok) -> VLayoutPassmark bool &ok) -> VLayoutPassmark
{ {
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wnoexcept")
// noexcept-expression evaluates to 'false' because of a call to 'constexpr QPointF::QPointF()'
VLayoutPassmark layoutPassmark;
QT_WARNING_POP
VPiecePassmarkData pData = passmark.Data(); VPiecePassmarkData pData = passmark.Data();
const QVector<VPieceNode> path = piece.GetUnitedPath(pattern); const QVector<VPieceNode> path = piece.GetUnitedPath(pattern);
const int nodeIndex = VPiecePath::indexOfNode(path, pData.id); const int nodeIndex = VPiecePath::indexOfNode(path, pData.id);
@ -276,7 +271,15 @@ auto PrepareSAPassmark(const VPiece &piece, const VContainer *pattern, const VPa
return {}; return {};
} }
if (side == PassmarkSide::All || side == PassmarkSide::Right) QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wnoexcept")
// noexcept-expression evaluates to 'false' because of a call to 'constexpr QPointF::QPointF()'
VLayoutPassmark layoutPassmark;
QT_WARNING_POP
if (side == PassmarkSide::All || side == PassmarkSide::Left)
{ {
layoutPassmark.baseLine = baseLines.constFirst(); layoutPassmark.baseLine = baseLines.constFirst();
} }
@ -301,6 +304,7 @@ auto PrepareSAPassmark(const VPiece &piece, const VContainer *pattern, const VPa
layoutPassmark.type = pData.passmarkLineType; layoutPassmark.type = pData.passmarkLineType;
layoutPassmark.isBuiltIn = false; layoutPassmark.isBuiltIn = false;
layoutPassmark.isClockwiseOpening = pData.passmarkSAPoint.IsPassmarkClockwiseOpening(); layoutPassmark.isClockwiseOpening = pData.passmarkSAPoint.IsPassmarkClockwiseOpening();
layoutPassmark.label = pData.nodeName;
ok = true; ok = true;
return layoutPassmark; return layoutPassmark;
@ -364,92 +368,12 @@ auto PreapreBuiltInSAPassmark(const VPiece &piece, const VContainer *pattern, co
layoutPassmark.type = pData.passmarkLineType; layoutPassmark.type = pData.passmarkLineType;
layoutPassmark.isBuiltIn = true; layoutPassmark.isBuiltIn = true;
layoutPassmark.isClockwiseOpening = pData.passmarkSAPoint.IsPassmarkClockwiseOpening(); layoutPassmark.isClockwiseOpening = pData.passmarkSAPoint.IsPassmarkClockwiseOpening();
layoutPassmark.label = pData.nodeName;
ok = true; ok = true;
return layoutPassmark; return layoutPassmark;
} }
//---------------------------------------------------------------------------------------------------------------------
auto ConvertPassmarks(const VPiece &piece, const VContainer *pattern) -> QVector<VLayoutPassmark>
{
const QVector<VPassmark> passmarks = piece.Passmarks(pattern);
QVector<VLayoutPassmark> layoutPassmarks;
layoutPassmarks.reserve(passmarks.size());
for (const auto &passmark : passmarks)
{
if (passmark.IsNull())
{
continue;
}
auto AddPassmark = [passmark, piece, pattern, &layoutPassmarks](PassmarkSide side)
{
bool ok = false;
VLayoutPassmark layoutPassmark = PrepareSAPassmark(piece, pattern, passmark, side, ok);
if (ok)
{
layoutPassmarks.append(layoutPassmark);
}
};
auto AddBuiltInPassmark = [passmark, piece, pattern, &layoutPassmarks]()
{
bool ok = false;
VLayoutPassmark layoutPassmark = PreapreBuiltInSAPassmark(piece, pattern, passmark, ok);
if (ok)
{
layoutPassmarks.append(layoutPassmark);
}
};
if (piece.IsSeamAllowanceBuiltIn())
{
AddBuiltInPassmark();
continue;
}
VPiecePassmarkData pData = passmark.Data();
switch (pData.passmarkAngleType)
{
case PassmarkAngleType::Straightforward:
case PassmarkAngleType::Bisector:
AddPassmark(PassmarkSide::All);
break;
case PassmarkAngleType::Intersection:
case PassmarkAngleType::Intersection2:
AddPassmark(PassmarkSide::Left);
AddPassmark(PassmarkSide::Right);
break;
case PassmarkAngleType::IntersectionOnlyLeft:
case PassmarkAngleType::Intersection2OnlyLeft:
AddPassmark(PassmarkSide::Left);
break;
case PassmarkAngleType::IntersectionOnlyRight:
case PassmarkAngleType::Intersection2OnlyRight:
AddPassmark(PassmarkSide::Right);
break;
default:
break;
}
if (VAbstractApplication::VApp()->Settings()->IsDoublePassmark() &&
(VAbstractApplication::VApp()->Settings()->IsPieceShowMainPath() || not piece.IsHideMainPath()) &&
pData.isMainPathNode && pData.passmarkAngleType != PassmarkAngleType::Intersection &&
pData.passmarkAngleType != PassmarkAngleType::IntersectionOnlyLeft &&
pData.passmarkAngleType != PassmarkAngleType::IntersectionOnlyRight &&
pData.passmarkAngleType != PassmarkAngleType::Intersection2 &&
pData.passmarkAngleType != PassmarkAngleType::Intersection2OnlyLeft &&
pData.passmarkAngleType != PassmarkAngleType::Intersection2OnlyRight && pData.isShowSecondPassmark)
{
AddBuiltInPassmark();
}
}
return layoutPassmarks;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto PrepareGradationPlaceholders(const VContainer *data) -> QMap<QString, QString> auto PrepareGradationPlaceholders(const VContainer *data) -> QMap<QString, QString>
{ {
@ -640,7 +564,8 @@ auto VLayoutPiece::Create(const VPiece &piece, vidtype id, const VContainer *pat
QFuture<QVector<VLayoutPoint>> futureMainPath = QFuture<QVector<VLayoutPoint>> futureMainPath =
QtConcurrent::run([piece, pattern]() { return piece.MainPathPoints(pattern); }); QtConcurrent::run([piece, pattern]() { return piece.MainPathPoints(pattern); });
QFuture<QVector<VLayoutPiecePath>> futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern); QFuture<QVector<VLayoutPiecePath>> futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern);
QFuture<QVector<VLayoutPassmark>> futurePassmarks = QtConcurrent::run(ConvertPassmarks, piece, pattern); QFuture<QVector<VLayoutPassmark>> futurePassmarks =
QtConcurrent::run(VLayoutPiece::ConvertPassmarks, piece, pattern);
QFuture<QVector<VLayoutPlaceLabel>> futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern); QFuture<QVector<VLayoutPlaceLabel>> futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern);
VLayoutPiece det; VLayoutPiece det;
@ -676,7 +601,7 @@ auto VLayoutPiece::Create(const VPiece &piece, vidtype id, const VContainer *pat
det.SetPriority(piece.GetPriority()); det.SetPriority(piece.GetPriority());
// Very important to set main path first! // Very important to set main path first!
if (det.MappedContourPath().isEmpty()) if (det.MappedContourPath(false, false).isEmpty())
{ {
throw VException(tr("Piece %1 doesn't have shape.").arg(piece.GetName())); throw VException(tr("Piece %1 doesn't have shape.").arg(piece.GetName()));
} }
@ -1233,7 +1158,7 @@ auto VLayoutPiece::isNull() const -> bool
{ {
if (not d->m_contour.isEmpty() && d->m_layoutWidth > 0) if (not d->m_contour.isEmpty() && d->m_layoutWidth > 0)
{ {
return not(IsSeamAllowance() && not IsSeamAllowanceBuiltIn() && not d->m_seamAllowance.isEmpty()); return !IsSeamAllowance() || IsSeamAllowanceBuiltIn() || d->m_seamAllowance.isEmpty();
} }
return true; return true;
} }
@ -1245,40 +1170,46 @@ auto VLayoutPiece::Square() const -> qint64
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetLayoutAllowancePoints() void VLayoutPiece::SetLayoutAllowancePoints(bool togetherWithNotches)
{ {
d->m_square = 0; d->m_square = 0;
if (d->m_layoutWidth > 0) if (d->m_layoutWidth > 0)
{ {
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) QVector<VLayoutPoint> pieceBoundary = IsSeamAllowance() && not IsSeamAllowanceBuiltIn()
{ ? GetMappedSeamAllowancePoints()
QVector<VSAPoint> seamAllowancePoints; : GetMappedContourPoints();
CastTo(GetMappedSeamAllowancePoints(), seamAllowancePoints);
CastTo(Equidistant(seamAllowancePoints, d->m_layoutWidth, GetName()), d->m_layoutAllowance);
if (not d->m_layoutAllowance.isEmpty())
{
d->m_layoutAllowance.removeLast();
QVector<QPointF> points; if (togetherWithNotches)
CastTo(GetSeamAllowancePoints(), points); {
d->m_square = qFloor(qAbs(SumTrapezoids(points) / 2.0)); const QVector<VLayoutPassmark> passmarks = GetMappedPassmarks();
bool seamAllowance = IsSeamAllowance() && !IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = IsSeamAllowance() && IsSeamAllowanceBuiltIn();
VBoundary boundary(pieceBoundary, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, true);
pieceBoundary.clear();
for (const auto &item : sequence)
{
pieceBoundary += item.item.value<VLayoutPiecePath>().Points();
} }
} }
else
{
QVector<VSAPoint> seamLinePoints;
CastTo(GetMappedContourPoints(), seamLinePoints);
CastTo(Equidistant(seamLinePoints, d->m_layoutWidth, GetName()), d->m_layoutAllowance);
if (not d->m_layoutAllowance.isEmpty())
{
d->m_layoutAllowance.removeLast();
QVector<QPointF> points; QVector<VSAPoint> pieceBoundaryPoints;
CastTo(GetContourPoints(), points); CastTo(pieceBoundary, pieceBoundaryPoints);
d->m_square = qFloor(qAbs(SumTrapezoids(points) / 2.0)); CastTo(Equidistant(pieceBoundaryPoints, d->m_layoutWidth, GetName()), d->m_layoutAllowance);
} if (not d->m_layoutAllowance.isEmpty())
{
d->m_layoutAllowance.removeLast();
} }
QVector<QPointF> points;
CastTo(IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetSeamAllowancePoints() : GetContourPoints(),
points);
d->m_square = qFloor(qAbs(SumTrapezoids(points) / 2.0));
} }
else else
{ {
@ -1362,20 +1293,40 @@ void VLayoutPiece::SetInternalPaths(const QVector<VLayoutPiecePath> &internalPat
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::MappedContourPath() const -> QPainterPath auto VLayoutPiece::MappedContourPath(bool togetherWithNotches, bool showLayoutAllowance) const -> QPainterPath
{ {
return d->m_matrix.map(ContourPath()); return d->m_matrix.map(ContourPath(togetherWithNotches, showLayoutAllowance));
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::ContourPath() const -> QPainterPath auto VLayoutPiece::ContourPath(bool togetherWithNotches, bool showLayoutAllowance) const -> QPainterPath
{ {
QPainterPath path; QPainterPath path;
// contour // sew line
if (not IsHideMainPath() || not IsSeamAllowance() || IsSeamAllowanceBuiltIn()) if (not IsHideMainPath() || not IsSeamAllowance() || IsSeamAllowanceBuiltIn())
{ {
path = VGObject::PainterPath(GetContourPoints()); if (togetherWithNotches)
{
bool seamAllowance = IsSeamAllowance() && IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = IsSeamAllowance() && IsSeamAllowanceBuiltIn();
VBoundary boundary(d->m_contour, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(d->m_passmarks, true, false);
for (const auto &item : sequence)
{
const auto itemPath = item.item.value<VLayoutPiecePath>().Points();
QVector<QPointF> convertedPoints;
CastTo(itemPath, convertedPoints);
path.addPolygon(QPolygonF(convertedPoints));
}
}
else
{
path = VGObject::PainterPath(GetContourPoints());
}
} }
// seam allowance // seam allowance
@ -1384,39 +1335,55 @@ auto VLayoutPiece::ContourPath() const -> QPainterPath
if (not IsSeamAllowanceBuiltIn()) if (not IsSeamAllowanceBuiltIn())
{ {
// Draw seam allowance // Draw seam allowance
QVector<VLayoutPoint> points = GetSeamAllowancePoints(); if (togetherWithNotches)
if (points.constLast().toPoint() != points.constFirst().toPoint())
{ {
points.append(points.at(0)); // Should be always closed VBoundary boundary(d->m_seamAllowance, true);
} boundary.SetPieceName(GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(d->m_passmarks, true, false);
QPainterPath ekv; for (const auto &item : sequence)
ekv.moveTo(points.at(0)); {
for (qint32 i = 1; i < points.count(); ++i) const auto itemPath = item.item.value<VLayoutPiecePath>().Points();
QVector<QPointF> convertedPoints;
CastTo(itemPath, convertedPoints);
path.addPolygon(QPolygonF(convertedPoints));
}
}
else
{ {
ekv.lineTo(points.at(i)); QVector<VLayoutPoint> points = d->m_seamAllowance;
} if (points.constLast().toPoint() != points.constFirst().toPoint())
{
points.append(points.at(0)); // Should be always closed
}
path.addPath(ekv); path.addPath(VGObject::PainterPath(points));
}
} }
// Draw passmarks if (!togetherWithNotches)
QPainterPath passmaksPath;
const QVector<VLayoutPassmark> passmarks = GetPassmarks();
for (const auto &passmark : passmarks)
{ {
for (const auto &line : passmark.lines) // Draw passmarks
QPainterPath passmaksPath;
for (const auto &passmark : d->m_passmarks)
{ {
passmaksPath.moveTo(line.p1()); for (const auto &line : passmark.lines)
passmaksPath.lineTo(line.p2()); {
passmaksPath.moveTo(line.p1());
passmaksPath.lineTo(line.p2());
}
} }
path.addPath(passmaksPath);
} }
path.addPath(passmaksPath);
path.setFillRule(Qt::WindingFill); path.setFillRule(Qt::WindingFill);
} }
if (showLayoutAllowance)
{
path.addPath(VGObject::PainterPath(d->m_layoutAllowance));
}
return path; return path;
} }
@ -1427,9 +1394,9 @@ auto VLayoutPiece::MappedLayoutAllowancePath() const -> QPainterPath
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::DrawMiniature(QPainter &painter) const void VLayoutPiece::DrawMiniature(QPainter &painter, bool togetherWithNotches) const
{ {
painter.drawPath(ContourPath()); painter.drawPath(ContourPath(togetherWithNotches, false));
for (const auto &path : d->m_internalPaths) for (const auto &path : d->m_internalPaths)
{ {
@ -1453,9 +1420,10 @@ void VLayoutPiece::DrawMiniature(QPainter &painter) const
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetItem(bool textAsPaths) const -> QGraphicsItem * auto VLayoutPiece::GetItem(bool textAsPaths, bool togetherWithNotches, bool showLayoutAllowance) const
-> QGraphicsItem *
{ {
QGraphicsPathItem *item = GetMainItem(); QGraphicsPathItem *item = GetMainItem(togetherWithNotches, showLayoutAllowance);
for (const auto &path : d->m_internalPaths) for (const auto &path : d->m_internalPaths)
{ {
@ -1485,10 +1453,31 @@ auto VLayoutPiece::GetItem(bool textAsPaths) const -> QGraphicsItem *
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::IsLayoutAllowanceValid() const -> bool auto VLayoutPiece::IsLayoutAllowanceValid(bool togetherWithNotches) const -> bool
{ {
QVector<VLayoutPoint> base = QVector<VLayoutPoint> base =
(IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? d->m_seamAllowance : d->m_contour; (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? d->m_seamAllowance : d->m_contour;
if (togetherWithNotches)
{
const QVector<VLayoutPassmark> passmarks = GetMappedPassmarks();
bool seamAllowance = IsSeamAllowance() && !IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = IsSeamAllowance() && IsSeamAllowanceBuiltIn();
VBoundary boundary(base, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, true);
base.clear();
for (const auto &item : sequence)
{
base += item.item.value<VLayoutPiecePath>().Points();
}
base = VAbstractPiece::RemoveDublicates(base, false);
}
QVector<QPointF> points; QVector<QPointF> points;
CastTo(base, points); CastTo(base, points);
return VAbstractPiece::IsAllowanceValid(points, d->m_layoutAllowance); return VAbstractPiece::IsAllowanceValid(points, d->m_layoutAllowance);
@ -1820,13 +1809,13 @@ auto VLayoutPiece::DetailPath() const -> QVector<VLayoutPoint>
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetMainItem() const -> QGraphicsPathItem * auto VLayoutPiece::GetMainItem(bool togetherWithNotches, bool showLayoutAllowance) const -> QGraphicsPathItem *
{ {
auto *item = new QGraphicsPathItem(); auto *item = new QGraphicsPathItem();
QPen pen = item->pen(); QPen pen = item->pen();
pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine()); pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine());
item->setPen(pen); item->setPen(pen);
item->setPath(MappedContourPath()); item->setPath(MappedContourPath(togetherWithNotches, showLayoutAllowance));
return item; return item;
} }
@ -1953,3 +1942,84 @@ template <class T> auto VLayoutPiece::Map(QVector<T> points) const -> QVector<T>
{ {
return MapVector(points, d->m_matrix, d->m_mirror); return MapVector(points, d->m_matrix, d->m_mirror);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::ConvertPassmarks(const VPiece &piece, const VContainer *pattern) -> QVector<VLayoutPassmark>
{
const QVector<VPassmark> passmarks = piece.Passmarks(pattern);
QVector<VLayoutPassmark> layoutPassmarks;
layoutPassmarks.reserve(passmarks.size());
for (const auto &passmark : passmarks)
{
if (passmark.IsNull())
{
continue;
}
auto AddPassmark = [passmark, piece, pattern, &layoutPassmarks](PassmarkSide side)
{
bool ok = false;
VLayoutPassmark layoutPassmark = PrepareSAPassmark(piece, pattern, passmark, side, ok);
if (ok)
{
layoutPassmarks.append(layoutPassmark);
}
};
auto AddBuiltInPassmark = [passmark, piece, pattern, &layoutPassmarks]()
{
bool ok = false;
VLayoutPassmark layoutPassmark = PreapreBuiltInSAPassmark(piece, pattern, passmark, ok);
if (ok)
{
layoutPassmarks.append(layoutPassmark);
}
};
if (piece.IsSeamAllowanceBuiltIn())
{
AddBuiltInPassmark();
continue;
}
VPiecePassmarkData pData = passmark.Data();
switch (pData.passmarkAngleType)
{
case PassmarkAngleType::Straightforward:
case PassmarkAngleType::Bisector:
AddPassmark(PassmarkSide::All);
break;
case PassmarkAngleType::Intersection:
case PassmarkAngleType::Intersection2:
AddPassmark(PassmarkSide::Left);
AddPassmark(PassmarkSide::Right);
break;
case PassmarkAngleType::IntersectionOnlyLeft:
case PassmarkAngleType::Intersection2OnlyLeft:
AddPassmark(PassmarkSide::Left);
break;
case PassmarkAngleType::IntersectionOnlyRight:
case PassmarkAngleType::Intersection2OnlyRight:
AddPassmark(PassmarkSide::Right);
break;
default:
break;
}
if (VAbstractApplication::VApp()->Settings()->IsDoublePassmark() &&
(VAbstractApplication::VApp()->Settings()->IsPieceShowMainPath() || not piece.IsHideMainPath()) &&
pData.isMainPathNode && pData.passmarkAngleType != PassmarkAngleType::Intersection &&
pData.passmarkAngleType != PassmarkAngleType::IntersectionOnlyLeft &&
pData.passmarkAngleType != PassmarkAngleType::IntersectionOnlyRight &&
pData.passmarkAngleType != PassmarkAngleType::Intersection2 &&
pData.passmarkAngleType != PassmarkAngleType::Intersection2OnlyLeft &&
pData.passmarkAngleType != PassmarkAngleType::Intersection2OnlyRight && pData.isShowSecondPassmark)
{
AddBuiltInPassmark();
}
}
return layoutPassmarks;
}

View File

@ -95,6 +95,7 @@ public:
#endif #endif
static auto Create(const VPiece &piece, vidtype id, const VContainer *pattern) -> VLayoutPiece; static auto Create(const VPiece &piece, vidtype id, const VContainer *pattern) -> VLayoutPiece;
static auto ConvertPassmarks(const VPiece &piece, const VContainer *pattern) -> QVector<VLayoutPassmark>;
auto GetUniqueID() const -> QString override; auto GetUniqueID() const -> QString override;
@ -109,7 +110,7 @@ public:
auto GetMappedLayoutAllowancePoints() const -> QVector<QPointF>; auto GetMappedLayoutAllowancePoints() const -> QVector<QPointF>;
auto GetLayoutAllowancePoints() const -> QVector<QPointF>; auto GetLayoutAllowancePoints() const -> QVector<QPointF>;
void SetLayoutAllowancePoints(); void SetLayoutAllowancePoints(bool togetherWithNotches);
auto GetMappedExternalContourPoints() const -> QVector<VLayoutPoint>; auto GetMappedExternalContourPoints() const -> QVector<VLayoutPoint>;
auto GetExternalContourPoints() const -> QVector<VLayoutPoint>; auto GetExternalContourPoints() const -> QVector<VLayoutPoint>;
@ -204,15 +205,16 @@ public:
auto isNull() const -> bool; auto isNull() const -> bool;
auto Square() const -> qint64; auto Square() const -> qint64;
auto MappedContourPath() const -> QPainterPath; auto MappedContourPath(bool togetherWithNotches, bool showLayoutAllowance) const -> QPainterPath;
auto ContourPath() const -> QPainterPath; auto ContourPath(bool togetherWithNotches, bool showLayoutAllowance) const -> QPainterPath;
auto MappedLayoutAllowancePath() const -> QPainterPath; auto MappedLayoutAllowancePath() const -> QPainterPath;
void DrawMiniature(QPainter &painter) const; void DrawMiniature(QPainter &painter, bool togetherWithNotches) const;
Q_REQUIRED_RESULT auto GetItem(bool textAsPaths) const -> QGraphicsItem *; Q_REQUIRED_RESULT auto GetItem(bool textAsPaths, bool togetherWithNotches, bool showLayoutAllowance) const
-> QGraphicsItem *;
auto IsLayoutAllowanceValid() const -> bool; auto IsLayoutAllowanceValid(bool togetherWithNotches) const -> bool;
auto BiggestEdge() const -> qreal; auto BiggestEdge() const -> qreal;
@ -238,7 +240,7 @@ private:
auto DetailPath() const -> QVector<VLayoutPoint>; auto DetailPath() const -> QVector<VLayoutPoint>;
Q_REQUIRED_RESULT auto GetMainItem() const -> QGraphicsPathItem *; Q_REQUIRED_RESULT auto GetMainItem(bool togetherWithNotches, bool showLayoutAllowance) const -> QGraphicsPathItem *;
Q_REQUIRED_RESULT auto GetMainPathItem() const -> QGraphicsPathItem *; Q_REQUIRED_RESULT auto GetMainPathItem() const -> QGraphicsPathItem *;
void LabelStringsSVGFont(QGraphicsItem *parent, const QVector<QPointF> &labelShape, const VTextManager &tm, void LabelStringsSVGFont(QGraphicsItem *parent, const QVector<QPointF> &labelShape, const VTextManager &tm,

View File

@ -34,7 +34,12 @@
#include "../vmisc/def.h" #include "../vmisc/def.h"
enum class PrintType : qint8 {PrintPDF, PrintPreview, PrintNative}; enum class PrintType : qint8
{
PrintPDF,
PrintPreview,
PrintNative
};
class QPrinter; class QPrinter;
class QGraphicsScene; class QGraphicsScene;
@ -43,9 +48,10 @@ struct VWatermarkData;
class VPrintLayout : public QObject class VPrintLayout : public QObject
{ {
Q_OBJECT // NOLINT Q_OBJECT // NOLINT
public: public:
explicit VPrintLayout(QObject *parent = nullptr); explicit VPrintLayout(QObject *parent = nullptr);
virtual ~VPrintLayout(); ~VPrintLayout() override;
auto FileName() const -> QString; auto FileName() const -> QString;
void SetFileName(const QString &fileName); void SetFileName(const QString &fileName);
@ -107,8 +113,11 @@ public:
auto LayoutShadows() const -> QList<QGraphicsItem *>; auto LayoutShadows() const -> QList<QGraphicsItem *>;
void SetLayoutShadows(const QList<QGraphicsItem *> &layoutShadows); void SetLayoutShadows(const QList<QGraphicsItem *> &layoutShadows);
auto LayoutDetails() const -> QList<QList<QGraphicsItem *> >; auto LayoutDetails() const -> QList<QList<QGraphicsItem *>>;
void SetLayoutDetails(const QList<QList<QGraphicsItem *> > &layoutDetails); void SetLayoutDetails(const QList<QList<QGraphicsItem *>> &layoutDetails);
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
void PrintTiled(); void PrintTiled();
void PrintOrigin(); void PrintOrigin();
@ -125,34 +134,34 @@ public:
static auto PrinterScaleDiff(QPrinter *printer) -> QPair<qreal, qreal>; static auto PrinterScaleDiff(QPrinter *printer) -> QPair<qreal, qreal>;
private slots: private slots:
void PrintPages (QPrinter *printer); void PrintPages(QPrinter *printer);
private: private:
Q_DISABLE_COPY_MOVE(VPrintLayout) // NOLINT Q_DISABLE_COPY_MOVE(VPrintLayout) // NOLINT
QString m_fileName{}; QString m_fileName{};
QSizeF m_layoutPaperSize{}; QSizeF m_layoutPaperSize{};
QMarginsF m_layoutMargins{}; QMarginsF m_layoutMargins{};
QWidget *m_parentWidget{nullptr}; QWidget *m_parentWidget{nullptr};
bool m_isLayoutPortrait{true}; bool m_isLayoutPortrait{true};
bool m_ignorePrinterMargins{false}; bool m_ignorePrinterMargins{false};
bool m_isAutoCropLength{false}; bool m_isAutoCropLength{false};
bool m_isAutoCropWidth{false}; bool m_isAutoCropWidth{false};
bool m_isUnitePages{false}; bool m_isUnitePages{false};
QString m_layoutPrinterName{}; QString m_layoutPrinterName{};
bool m_isLayoutStale{false}; bool m_isLayoutStale{false};
QMarginsF m_tiledMargins{}; QMarginsF m_tiledMargins{};
PageOrientation m_tiledPDFOrientation{PageOrientation::Portrait}; PageOrientation m_tiledPDFOrientation{PageOrientation::Portrait};
QSizeF m_tiledPDFPaperSize{}; QSizeF m_tiledPDFPaperSize{};
QString m_watermarkPath{}; QString m_watermarkPath{};
bool m_togetherWithNotches{false};
QList<QGraphicsItem *> m_layoutPapers{};
QList<QGraphicsScene *> m_layoutScenes{};
QList<QGraphicsItem *> m_layoutShadows{};
QList<QList<QGraphicsItem *>> m_layoutDetails{};
QList<QGraphicsItem *> m_layoutPapers{}; bool m_isTiled{false};
QList<QGraphicsScene *> m_layoutScenes{};
QList<QGraphicsItem *> m_layoutShadows{};
QList<QList<QGraphicsItem *> > m_layoutDetails{};
bool m_isTiled{false};
qreal m_xscale{1}; qreal m_xscale{1};
qreal m_yscale{1}; qreal m_yscale{1};
@ -380,13 +389,13 @@ inline void VPrintLayout::SetLayoutShadows(const QList<QGraphicsItem *> &layoutS
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
inline auto VPrintLayout::LayoutDetails() const -> QList<QList<QGraphicsItem *> > inline auto VPrintLayout::LayoutDetails() const -> QList<QList<QGraphicsItem *>>
{ {
return m_layoutDetails; return m_layoutDetails;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
inline void VPrintLayout::SetLayoutDetails(const QList<QList<QGraphicsItem *> > &layoutDetails) inline void VPrintLayout::SetLayoutDetails(const QList<QList<QGraphicsItem *>> &layoutDetails)
{ {
m_layoutDetails = layoutDetails; m_layoutDetails = layoutDetails;
} }
@ -426,4 +435,17 @@ inline void VPrintLayout::SetWatermarkPath(const QString &watermarkPath)
{ {
m_watermarkPath = watermarkPath; m_watermarkPath = watermarkPath;
} }
//---------------------------------------------------------------------------------------------------------------------
inline void VPrintLayout::SetBoundaryTogetherWithNotches(bool value)
{
m_togetherWithNotches = value;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPrintLayout::IsBoundaryTogetherWithNotches() const -> bool
{
return m_togetherWithNotches;
}
#endif // VPRINTLAYOUT_H #endif // VPRINTLAYOUT_H

View File

@ -133,6 +133,7 @@ const QString LONG_OPTION_LANDSCAPE_ORIENTATION = QStringLiteral("landscapeOrien
const QString LONG_OPTION_NEST_QUANTITY = QStringLiteral("nestQuantity"); const QString LONG_OPTION_NEST_QUANTITY = QStringLiteral("nestQuantity");
const QString LONG_OPTION_PREFER_ONE_SHEET_SOLUTION = QStringLiteral("preferOneSheetSolution"); const QString LONG_OPTION_PREFER_ONE_SHEET_SOLUTION = QStringLiteral("preferOneSheetSolution");
const QString LONG_OPTION_BOUNDARY_TOGETHER_WITH_NOTCHES = QStringLiteral("boundaryTogetherWithNotches");
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
@ -212,5 +213,6 @@ auto AllKeys() -> QStringList
LONG_OPTION_MANUAL_PRIORITY, LONG_OPTION_MANUAL_PRIORITY,
LONG_OPTION_LANDSCAPE_ORIENTATION, LONG_OPTION_LANDSCAPE_ORIENTATION,
LONG_OPTION_NEST_QUANTITY, LONG_OPTION_NEST_QUANTITY,
LONG_OPTION_PREFER_ONE_SHEET_SOLUTION}; LONG_OPTION_PREFER_ONE_SHEET_SOLUTION,
LONG_OPTION_BOUNDARY_TOGETHER_WITH_NOTCHES};
} }

View File

@ -130,6 +130,7 @@ extern const QString LONG_OPTION_MANUAL_PRIORITY;
extern const QString LONG_OPTION_LANDSCAPE_ORIENTATION; extern const QString LONG_OPTION_LANDSCAPE_ORIENTATION;
extern const QString LONG_OPTION_NEST_QUANTITY; extern const QString LONG_OPTION_NEST_QUANTITY;
extern const QString LONG_OPTION_PREFER_ONE_SHEET_SOLUTION; extern const QString LONG_OPTION_PREFER_ONE_SHEET_SOLUTION;
extern const QString LONG_OPTION_BOUNDARY_TOGETHER_WITH_NOTCHES;
auto AllKeys() -> QStringList; auto AllKeys() -> QStringList;

View File

@ -74,6 +74,9 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPatternRememberMaterials, ("patt
// NOLINTNEXTLINE // NOLINTNEXTLINE
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPatternBackgroundImageDefOpacity, Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPatternBackgroundImageDefOpacity,
("pattern/backgroundImageDefOpacity"_L1)) ("pattern/backgroundImageDefOpacity"_L1))
// NOLINTNEXTLINE
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPatternBoundaryTogetherWithNotches,
("pattern/boundaryTogetherWithNotches"_L1))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutWidth, ("layout/width"_L1)) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutWidth, ("layout/width"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutSorting, ("layout/sorting"_L1)) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutSorting, ("layout/sorting"_L1)) // NOLINT
@ -90,6 +93,9 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutAutoCropWidth, ("layout/au
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutSaveLength, ("layout/saveLength"_L1)) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutSaveLength, ("layout/saveLength"_L1)) // NOLINT
// NOLINTNEXTLINE // NOLINTNEXTLINE
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutPreferOneSheetSolution, ("layout/preferOneSheetSolution"_L1)) Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutPreferOneSheetSolution, ("layout/preferOneSheetSolution"_L1))
// NOLINTNEXTLINE
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutBoundaryTogetherWithNotches,
("layout/boundaryTogetherWithNotches"_L1))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutUnitePages, ("layout/unitePages"_L1)) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutUnitePages, ("layout/unitePages"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutShowGrainline, ("layout/showGrainline"_L1)) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutShowGrainline, ("layout/showGrainline"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingFields, ("layout/fields"_L1)) // NOLINT Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingFields, ("layout/fields"_L1)) // NOLINT
@ -454,6 +460,24 @@ void VValentinaSettings::SetLayoutPreferOneSheetSolution(bool value)
setValue(*settingLayoutPreferOneSheetSolution, value); setValue(*settingLayoutPreferOneSheetSolution, value);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VValentinaSettings::GetLayoutBoundaryTogetherWithNotches() const -> bool
{
return value(*settingLayoutBoundaryTogetherWithNotches, GetDefLayoutBoundaryTogetherWithNotches()).toBool();
}
//---------------------------------------------------------------------------------------------------------------------
auto VValentinaSettings::GetDefLayoutBoundaryTogetherWithNotches() -> bool
{
return false;
}
//---------------------------------------------------------------------------------------------------------------------
void VValentinaSettings::SetLayoutBoundaryTogetherWithNotches(bool value)
{
setValue(*settingLayoutBoundaryTogetherWithNotches, value);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VValentinaSettings::GetLayoutUnitePages() const -> bool auto VValentinaSettings::GetLayoutUnitePages() const -> bool
{ {
@ -1045,6 +1069,18 @@ void VValentinaSettings::SetUseToolGroups(bool value)
setValue(*settingConfigurationUseToolGroups, value); setValue(*settingConfigurationUseToolGroups, value);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VValentinaSettings::IsBoundaryTogetherWithNotches() const -> bool
{
return value(*settingPatternBoundaryTogetherWithNotches, false).toBool();
}
//---------------------------------------------------------------------------------------------------------------------
void VValentinaSettings::SetBoundaryTogetherWithNotches(bool value)
{
setValue(*settingPatternBoundaryTogetherWithNotches, value);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
auto VValentinaSettings::GetCachedValue(T &cache, const QString &setting, T defValue, T valueMin, T valueMax) const -> T auto VValentinaSettings::GetCachedValue(T &cache, const QString &setting, T defValue, T valueMin, T valueMax) const -> T

View File

@ -115,6 +115,10 @@ public:
static auto GetDefLayoutPreferOneSheetSolution() -> bool; static auto GetDefLayoutPreferOneSheetSolution() -> bool;
void SetLayoutPreferOneSheetSolution(bool value); void SetLayoutPreferOneSheetSolution(bool value);
auto GetLayoutBoundaryTogetherWithNotches() const -> bool;
static auto GetDefLayoutBoundaryTogetherWithNotches() -> bool;
void SetLayoutBoundaryTogetherWithNotches(bool value);
auto GetLayoutUnitePages() const -> bool; auto GetLayoutUnitePages() const -> bool;
static auto GetDefLayoutUnitePages() -> bool; static auto GetDefLayoutUnitePages() -> bool;
void SetLayoutUnitePages(bool value); void SetLayoutUnitePages(bool value);
@ -250,6 +254,9 @@ public:
auto IsUseToolGroups() const -> bool; auto IsUseToolGroups() const -> bool;
void SetUseToolGroups(bool value); void SetUseToolGroups(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
void SetBoundaryTogetherWithNotches(bool value);
private: private:
Q_DISABLE_COPY_MOVE(VValentinaSettings) // NOLINT Q_DISABLE_COPY_MOVE(VValentinaSettings) // NOLINT

View File

@ -550,14 +550,14 @@ auto CreateCheckMarkPassmark(const VPiecePassmarkData &passmarkData, const QLine
if (width > 0) if (width > 0)
{ // clockwise { // clockwise
QLineF l1(line.p2(), line.p1()); QLineF l1(line.p2(), line.p1());
l1.setAngle(l1.angle() - angle); l1.setAngle(l1.angle() + angle);
l1 = VPassmark::FindIntersection(l1, seamAllowance); l1 = VPassmark::FindIntersection(l1, seamAllowance);
return {{l1.p2(), l1.p1()}, {line.p2(), line.p1()}}; return {{l1.p2(), l1.p1()}, {line.p2(), line.p1()}};
} }
QLineF l2(line.p2(), line.p1()); QLineF l2(line.p2(), line.p1());
l2.setAngle(l2.angle() + angle); l2.setAngle(l2.angle() - angle);
l2 = VPassmark::FindIntersection(l2, seamAllowance); l2 = VPassmark::FindIntersection(l2, seamAllowance);
return {line, l2}; return {line, l2};

View File

@ -28,15 +28,15 @@
#ifndef VPASSMARK_H #ifndef VPASSMARK_H
#define VPASSMARK_H #define VPASSMARK_H
#include <QtGlobal>
#include <QMetaType> #include <QMetaType>
#include <QtGlobal>
#include "vpiece.h"
#include "../vmisc/typedef.h" #include "../vmisc/typedef.h"
#include "vpiece.h"
class QPainterPath; class QPainterPath;
enum class PassmarkStatus: qint8 enum class PassmarkStatus : qint8
{ {
Error = 0, Error = 0,
Common = 1, Common = 1,
@ -48,22 +48,22 @@ QT_WARNING_DISABLE_GCC("-Weffc++")
struct VPiecePassmarkData struct VPiecePassmarkData
{ {
VSAPoint previousSAPoint{}; // NOLINT(misc-non-private-member-variables-in-classes) VSAPoint previousSAPoint{}; // NOLINT(misc-non-private-member-variables-in-classes)
VSAPoint passmarkSAPoint{}; // NOLINT(misc-non-private-member-variables-in-classes) VSAPoint passmarkSAPoint{}; // NOLINT(misc-non-private-member-variables-in-classes)
VSAPoint nextSAPoint{}; // NOLINT(misc-non-private-member-variables-in-classes) VSAPoint nextSAPoint{}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal saWidth{0}; // NOLINT(misc-non-private-member-variables-in-classes) qreal saWidth{0}; // NOLINT(misc-non-private-member-variables-in-classes)
QString nodeName{}; // NOLINT(misc-non-private-member-variables-in-classes) QString nodeName{}; // NOLINT(misc-non-private-member-variables-in-classes)
QString pieceName{}; // NOLINT(misc-non-private-member-variables-in-classes) QString pieceName{}; // NOLINT(misc-non-private-member-variables-in-classes)
PassmarkLineType passmarkLineType{// NOLINT(misc-non-private-member-variables-in-classes) // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
PassmarkLineType::OneLine}; PassmarkLineType passmarkLineType{PassmarkLineType::OneLine};
PassmarkAngleType passmarkAngleType{// NOLINT(misc-non-private-member-variables-in-classes) // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
PassmarkAngleType::Straightforward}; PassmarkAngleType passmarkAngleType{PassmarkAngleType::Straightforward};
bool isMainPathNode{true}; // NOLINT(misc-non-private-member-variables-in-classes) bool isMainPathNode{true}; // NOLINT(misc-non-private-member-variables-in-classes)
bool isShowSecondPassmark{true}; // NOLINT(misc-non-private-member-variables-in-classes) bool isShowSecondPassmark{true}; // NOLINT(misc-non-private-member-variables-in-classes)
vsizetype passmarkIndex{-1}; // NOLINT(misc-non-private-member-variables-in-classes) vsizetype passmarkIndex{-1}; // NOLINT(misc-non-private-member-variables-in-classes)
vidtype id{NULL_ID}; // NOLINT(misc-non-private-member-variables-in-classes) vidtype id{NULL_ID}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal globalPassmarkLength{0}; // NOLINT(misc-non-private-member-variables-in-classes) qreal globalPassmarkLength{0}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal globalPassmarkWidth{0}; // NOLINT(misc-non-private-member-variables-in-classes) qreal globalPassmarkWidth{0}; // NOLINT(misc-non-private-member-variables-in-classes)
auto toJson() const -> QJsonObject; auto toJson() const -> QJsonObject;
}; };
@ -73,7 +73,12 @@ Q_DECLARE_TYPEINFO(VPiecePassmarkData, Q_MOVABLE_TYPE); // NOLINT
QT_WARNING_POP QT_WARNING_POP
enum class PassmarkSide : qint8 { All=0, Left=1, Right=2 }; enum class PassmarkSide : qint8
{
All = 0,
Left = 1,
Right = 2
};
class VPassmark class VPassmark
{ {
@ -102,6 +107,7 @@ public:
static auto FindIntersection(const QLineF &line, const QVector<QPointF> &seamAllowance) -> QLineF; static auto FindIntersection(const QLineF &line, const QVector<QPointF> &seamAllowance) -> QLineF;
static const qreal passmarkRadiusFactor; static const qreal passmarkRadiusFactor;
private: private:
VPiecePassmarkData m_data{}; VPiecePassmarkData m_data{};
bool m_null{true}; bool m_null{true};

View File

@ -247,7 +247,7 @@ auto VPiece::Passmarks(const VContainer *data) const -> QVector<VPassmark>
const QVector<VPieceNode> unitedPath = GetUnitedPath(data); const QVector<VPieceNode> unitedPath = GetUnitedPath(data);
if (not IsSeamAllowance() || not IsPassmarksPossible(unitedPath)) if (not IsSeamAllowance() || not IsPassmarksPossible(unitedPath))
{ {
return QVector<VPassmark>(); return {};
} }
QVector<VPassmark> passmarks; QVector<VPassmark> passmarks;
@ -693,7 +693,7 @@ auto VPiece::SeamAllowancePointsWithRotation(const VContainer *data, vsizetype m
const VPiecePath path = data->GetPiecePath(records.at(recordIndex).path); const VPiecePath path = data->GetPiecePath(records.at(recordIndex).path);
QVector<VSAPoint> r = path.SeamAllowancePoints(data, width, records.at(recordIndex).reverse); QVector<VSAPoint> r = path.SeamAllowancePoints(data, width, records.at(recordIndex).reverse);
for (auto & j : r) for (auto &j : r)
{ {
j.SetAngleType(PieceNodeAngle::ByLengthCurve); j.SetAngleType(PieceNodeAngle::ByLengthCurve);
j.SetSABefore(0); j.SetSABefore(0);

View File

@ -38,12 +38,19 @@
#include "../undocommands/movepiece.h" #include "../undocommands/movepiece.h"
#include "../undocommands/savepieceoptions.h" #include "../undocommands/savepieceoptions.h"
#include "../undocommands/togglepiecestate.h" #include "../undocommands/togglepiecestate.h"
#include "../vformat/vlabeltemplate.h"
#include "../vgeometry/varc.h" #include "../vgeometry/varc.h"
#include "../vgeometry/vellipticalarc.h" #include "../vgeometry/vellipticalarc.h"
#include "../vgeometry/vplacelabelitem.h" #include "../vgeometry/vplacelabelitem.h"
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vlayout/vboundary.h"
#include "../vlayout/vlayoutpiece.h"
#include "../vlayout/vlayoutpiecepath.h"
#include "../vmisc/theme/themeDef.h"
#include "../vmisc/theme/vscenestylesheet.h" #include "../vmisc/theme/vscenestylesheet.h"
#include "../vmisc/vvalentinasettings.h"
#include "../vpatterndb/calculator.h" #include "../vpatterndb/calculator.h"
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
#include "../vpatterndb/floatItemData/vpatternlabeldata.h" #include "../vpatterndb/floatItemData/vpatternlabeldata.h"
#include "../vpatterndb/floatItemData/vpiecelabeldata.h" #include "../vpatterndb/floatItemData/vpiecelabeldata.h"
#include "../vpatterndb/variables/vincrement.h" #include "../vpatterndb/variables/vincrement.h"
@ -54,14 +61,6 @@
#include "../vwidgets/vmaingraphicsview.h" #include "../vwidgets/vmaingraphicsview.h"
#include "../vwidgets/vnobrushscalepathitem.h" #include "../vwidgets/vnobrushscalepathitem.h"
#include "../vwidgets/vpiecegrainline.h" #include "../vwidgets/vpiecegrainline.h"
#include "theme/themeDef.h"
#include "toolsdef.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vformat/vlabeltemplate.h"
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
#include "../vpatterndb/floatItemData/vpiecelabeldata.h"
#include "nodeDetails/vnodearc.h" #include "nodeDetails/vnodearc.h"
#include "nodeDetails/vnodeellipticalarc.h" #include "nodeDetails/vnodeellipticalarc.h"
#include "nodeDetails/vnodepoint.h" #include "nodeDetails/vnodepoint.h"
@ -70,6 +69,11 @@
#include "nodeDetails/vtoolpiecepath.h" #include "nodeDetails/vtoolpiecepath.h"
#include "nodeDetails/vtoolpin.h" #include "nodeDetails/vtoolpin.h"
#include "nodeDetails/vtoolplacelabel.h" #include "nodeDetails/vtoolplacelabel.h"
#include "toolsdef.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include <QFuture> #include <QFuture>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
@ -77,6 +81,7 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <QMenu> #include <QMenu>
#include <QMessageBox> #include <QMessageBox>
#include <QPainterPath>
#include <QTimer> #include <QTimer>
#include <QUuid> #include <QUuid>
#include <QtConcurrent/QtConcurrentRun> #include <QtConcurrent/QtConcurrentRun>
@ -1460,16 +1465,86 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
const VPiece detail = VAbstractTool::data.GetPiece(m_id); const VPiece detail = VAbstractTool::data.GetPiece(m_id);
QFuture<QPainterPath> futurePath = QtConcurrent::run([this, detail]() { return detail.MainPathPath(getData()); }); VValentinaSettings *settings = VAbstractValApplication::VApp()->ValentinaSettings();
QFuture<QPainterPath> futurePassmarks = const bool combineTogether = settings->IsBoundaryTogetherWithNotches();
QtConcurrent::run([this, detail]() { return detail.PassmarksPath(getData()); });
QFuture<QVector<VLayoutPoint>> futureSeamAllowance; QFuture<QPainterPath> futurePath = QtConcurrent::run(
[this, detail, combineTogether]()
{
if (combineTogether)
{
const QVector<VLayoutPassmark> passmarks = VLayoutPiece::ConvertPassmarks(detail, getData());
const QVector<VLayoutPoint> points = detail.MainPathPoints(getData());
bool seamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(points, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
QVector<QPointF> combinedBoundary;
for (const auto &item : sequence)
{
const auto path = item.item.value<VLayoutPiecePath>().Points();
QVector<QPointF> convertedPoints;
CastTo(path, convertedPoints);
combinedBoundary += convertedPoints;
}
QPainterPath combinedPath;
combinedPath.addPolygon(QPolygonF(combinedBoundary));
combinedPath.closeSubpath();
combinedPath.setFillRule(Qt::OddEvenFill);
return combinedPath;
}
return detail.MainPathPath(getData());
});
QFuture<QPainterPath> futurePassmarks;
if (!combineTogether)
{
futurePassmarks = QtConcurrent::run([this, detail]() { return detail.PassmarksPath(getData()); });
}
QFuture<QPainterPath> futureSeamAllowance;
QFuture<bool> futureSeamAllowanceValid; QFuture<bool> futureSeamAllowanceValid;
if (detail.IsSeamAllowance()) if (detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn())
{ {
futureSeamAllowance = QtConcurrent::run([this, detail]() { return detail.SeamAllowancePoints(getData()); }); futureSeamAllowance = QtConcurrent::run(
[this, detail, combineTogether]()
{
if (combineTogether)
{
const QVector<VLayoutPassmark> passmarks = VLayoutPiece::ConvertPassmarks(detail, getData());
const QVector<VLayoutPoint> points = detail.SeamAllowancePoints(getData());
VBoundary boundary(points, true);
boundary.SetPieceName(detail.GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
QVector<QPointF> combinedBoundary;
for (const auto &item : sequence)
{
const auto path = item.item.value<VLayoutPiecePath>().Points();
QVector<QPointF> convertedPoints;
CastTo(path, convertedPoints);
combinedBoundary += convertedPoints;
}
QPainterPath combinedPath;
combinedPath.addPolygon(QPolygonF(combinedBoundary));
combinedPath.closeSubpath();
combinedPath.setFillRule(Qt::OddEvenFill);
return combinedPath;
}
return detail.SeamAllowancePath(getData());
});
futureSeamAllowanceValid = futureSeamAllowanceValid =
QtConcurrent::run([this, detail]() { return detail.IsSeamAllowanceValid(getData()); }); QtConcurrent::run([this, detail]() { return detail.IsSeamAllowanceValid(getData()); });
} }
@ -1506,7 +1581,7 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
? throw VException(errorMsg) ? throw VException(errorMsg)
: qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
} }
path.addPath(detail.SeamAllowancePath(futureSeamAllowance.result())); path.addPath(futureSeamAllowance.result());
path.setFillRule(Qt::OddEvenFill); path.setFillRule(Qt::OddEvenFill);
m_seamAllowance->setPath(path); m_seamAllowance->setPath(path);
@ -1548,7 +1623,7 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
} }
} }
m_passmarks->setPath(futurePassmarks.result()); m_passmarks->setPath(!combineTogether ? futurePassmarks.result() : QPainterPath());
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);

View File

@ -33,16 +33,15 @@
#include "../ifc/ifcdef.h" #include "../ifc/ifcdef.h"
#include "../ifc/xml/vabstractpattern.h" #include "../ifc/xml/vabstractpattern.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractvalapplication.h"
#include "../vtools/tools/vabstracttool.h"
#include "../vundocommand.h" #include "../vundocommand.h"
#include "moveabstractlabel.h" #include "moveabstractlabel.h"
#include "../vtools/tools/vabstracttool.h"
#include "../vwidgets/vmaingraphicsview.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
MoveLabel::MoveLabel(VAbstractPattern *doc, const QPointF &pos, const quint32 &id, QUndoCommand *parent) MoveLabel::MoveLabel(VAbstractPattern *doc, const QPointF &pos, const quint32 &id, QUndoCommand *parent)
: MoveAbstractLabel(doc, id, pos, parent), : MoveAbstractLabel(doc, id, pos, parent),
m_scene(VAbstractValApplication::VApp()->getCurrentScene()) m_scene(VAbstractValApplication::VApp()->getCurrentScene())
{ {
setText(tr("move point label")); setText(tr("move point label"));
@ -64,7 +63,7 @@ MoveLabel::MoveLabel(VAbstractPattern *doc, const QPointF &pos, const quint32 &i
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto MoveLabel::mergeWith(const QUndoCommand *command) -> bool auto MoveLabel::mergeWith(const QUndoCommand *command) -> bool
{ {
const MoveLabel *moveCommand = static_cast<const MoveLabel *>(command); const auto *moveCommand = static_cast<const MoveLabel *>(command);
SCASSERT(moveCommand != nullptr) SCASSERT(moveCommand != nullptr)
if (moveCommand->GetPointId() != nodeId) if (moveCommand->GetPointId() != nodeId)
@ -97,7 +96,7 @@ void MoveLabel::Do(const QPointF &pos)
doc->SetAttribute(domElement, AttrMx, QString().setNum(VAbstractValApplication::VApp()->fromPixel(pos.x()))); doc->SetAttribute(domElement, AttrMx, QString().setNum(VAbstractValApplication::VApp()->fromPixel(pos.x())));
doc->SetAttribute(domElement, AttrMy, QString().setNum(VAbstractValApplication::VApp()->fromPixel(pos.y()))); doc->SetAttribute(domElement, AttrMy, QString().setNum(VAbstractValApplication::VApp()->fromPixel(pos.y())));
if (VAbstractTool *tool = qobject_cast<VAbstractTool *>(VAbstractPattern::getTool(nodeId))) if (auto *tool = qobject_cast<VAbstractTool *>(VAbstractPattern::getTool(nodeId)))
{ {
tool->ChangeLabelPosition(nodeId, pos); tool->ChangeLabelPosition(nodeId, pos);
} }