Compare commits

...

12 commits

Author SHA1 Message Date
Roman Telezhynskyi a7073dbeae Fix build. 2023-11-29 11:57:30 +02:00
Roman Telezhynskyi 458c36f08c Fix build. 2023-11-29 11:09:49 +02:00
Roman Telezhynskyi 5dec82606c Lupdate. 2023-11-29 10:44:06 +02:00
Roman Telezhynskyi 5724c9611a New feature. Boundary together with notches. 2023-11-28 16:40:27 +02:00
Roman Telezhynskyi fef322116b Fix reading a detail node label position. 2023-11-25 15:38:22 +02:00
Roman Telezhynskyi c7379122a8 Improve cutting spline and curved path.
Loose cutting restrictions.
2023-11-22 14:58:00 +02:00
Roman Telezhynskyi aee93b01b9 Optimize U-notch shape. 2023-11-22 13:59:50 +02:00
Roman Telezhynskyi ddb921d468 Fix duplicate items in the list of known measurements. 2023-11-21 12:33:15 +02:00
Roman Telezhynskyi 6041dd52b6 Added support for notch data type dependency. 2023-11-20 15:15:58 +02:00
Roman Telezhynskyi 348b7c4e8a Refactoring.
Code style.
2023-11-20 13:28:31 +02:00
Roman Telezhynskyi f5256c514c libdxfrw. C++14 support 2023-11-20 12:23:56 +02:00
Roman Telezhynskyi d704cf9322 Fix compatibility with old compilers. 2023-11-18 06:16:06 +02:00
117 changed files with 22122 additions and 18791 deletions

View file

@ -57,6 +57,8 @@
- [smart-pattern/valentina#188] Label %mFileName% file name punctuation. - [smart-pattern/valentina#188] Label %mFileName% file name punctuation.
- 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.
- 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>"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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

@ -337,6 +337,9 @@ void TapePreferencesConfigurationPage::InitKnownMeasurements(QComboBox *combo)
VKnownMeasurementsDatabase *db = MApplication::VApp()->KnownMeasurementsDatabase(); VKnownMeasurementsDatabase *db = MApplication::VApp()->KnownMeasurementsDatabase();
QHash<QUuid, VKnownMeasurementsHeader> known = db->AllKnownMeasurements(); QHash<QUuid, VKnownMeasurementsHeader> known = db->AllKnownMeasurements();
combo->blockSignals(true);
combo->clear();
SCASSERT(combo != nullptr) SCASSERT(combo != nullptr)
combo->addItem(tr("None"), QUuid()); combo->addItem(tr("None"), QUuid());
@ -355,6 +358,8 @@ void TapePreferencesConfigurationPage::InitKnownMeasurements(QComboBox *combo)
combo->addItem(name, i.key()); combo->addItem(name, i.key());
++i; ++i;
} }
combo->blockSignals(false);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View file

@ -71,7 +71,7 @@ private:
void InitShortcuts(bool defaults = false); void InitShortcuts(bool defaults = false);
void UpdateShortcutsTable(); void UpdateShortcutsTable();
void RetranslateShortcutsTable(); void RetranslateShortcutsTable();
void InitKnownMeasurements(QComboBox *combo); static void InitKnownMeasurements(QComboBox *combo);
void InitKnownMeasurementsDescription(); void InitKnownMeasurementsDescription();
}; };

View file

@ -44,7 +44,6 @@
#include "dialogs/dialogknownmeasurementscsvcolumns.h" #include "dialogs/dialogknownmeasurementscsvcolumns.h"
#include "knownmeasurements/vknownmeasurements.h" #include "knownmeasurements/vknownmeasurements.h"
#include "mapplication.h" // Should be last because of definning qApp #include "mapplication.h" // Should be last because of definning qApp
#include "quuid.h"
#include "ui_tkmmainwindow.h" #include "ui_tkmmainwindow.h"
#include <QAbstractButton> #include <QAbstractButton>
@ -61,6 +60,7 @@
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QStringListModel> #include <QStringListModel>
#include <QTimer> #include <QTimer>
#include <QUuid>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include "../vmisc/vtextcodec.h" #include "../vmisc/vtextcodec.h"
@ -68,6 +68,10 @@
#include <QTextCodec> #include <QTextCodec>
#endif #endif
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#if (defined(Q_CC_GNU) && Q_CC_GNU < 409) && !defined(Q_CC_CLANG) #if (defined(Q_CC_GNU) && Q_CC_GNU < 409) && !defined(Q_CC_CLANG)
// DO NOT WORK WITH GCC 4.8 // DO NOT WORK WITH GCC 4.8
#else #else

View file

@ -4796,9 +4796,10 @@ void TMainWindow::InitKnownMeasurements(QComboBox *combo)
SCASSERT(combo != nullptr) SCASSERT(combo != nullptr)
combo->addItem(tr("None"), QUuid()); combo->addItem(tr("None"), QUuid());
if (!known.contains(m_m->KnownMeasurements())) QUuid kmId = m_m->KnownMeasurements();
if (!kmId.isNull() && !known.contains(kmId))
{ {
combo->addItem(tr("Invalid link"), m_m->KnownMeasurements()); combo->addItem(tr("Invalid link"), kmId);
} }
int index = 1; int index = 1;

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;
} }
} }
@ -1945,6 +1944,8 @@ void VPattern::ParseNodePoint(const QDomElement &domElement, const Document &par
p->setIdObject(initData.idObject); p->setIdObject(initData.idObject);
p->setMode(Draw::Modeling); p->setMode(Draw::Modeling);
p->SetShowLabel(GetParametrBool(domElement, AttrShowLabel, trueStr)); p->SetShowLabel(GetParametrBool(domElement, AttrShowLabel, trueStr));
p->setMx(mx);
p->setMy(my);
initData.data->UpdateGObject(initData.id, p); initData.data->UpdateGObject(initData.id, p);
VNodePoint::Create(initData); VNodePoint::Create(initData);

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

@ -10,19 +10,20 @@
******************************************************************************/ ******************************************************************************/
#include "dxiface.h" #include "dxiface.h"
#include "libdxfrw/libdxfrw.h"
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include "libdxfrw/drw_entities.h"
#include "libdxfrw/libdxfrw.h"
#include <iostream>
#include <algorithm>
#include <QDateTime> #include <QDateTime>
#include <QFont> #include <QFont>
#include <QLocale> #include <QLocale>
#include <algorithm>
#include <iostream>
dx_iface::dx_iface(const std::string &file, DRW::Version v, VarMeasurement varMeasurement, VarInsunits varInsunits) dx_iface::dx_iface(const std::string &file, DRW::Version v, VarMeasurement varMeasurement, VarInsunits varInsunits)
: dxfW(new dxfRW(file.c_str())), : dxfW(new dxfRW(file.c_str())),
cData(), cData(),
version(v) version(v)
{ {
InitHeader(varMeasurement, varInsunits); InitHeader(varMeasurement, varInsunits);
InitTextstyles(); InitTextstyles();
@ -41,72 +42,77 @@ auto dx_iface::fileExport(bool binary) -> bool
return success; return success;
} }
void dx_iface::writeEntity(DRW_Entity* e){ void dx_iface::writeEntity(DRW_Entity *e)
switch (e->eType) { {
case DRW::POINT: switch (e->eType)
dxfW->writePoint(static_cast<DRW_Point*>(e)); {
break; case DRW::POINT:
case DRW::ASTMNOTCH: dxfW->writePoint(static_cast<DRW_Point *>(e));
dxfW->writeASTMNotch(static_cast<DRW_ASTMNotch*>(e)); break;
break; case DRW::ASTMNOTCH:
case DRW::LINE: dxfW->writeASTMNotch(static_cast<DRW_ASTMNotch *>(e));
dxfW->writeLine(static_cast<DRW_Line*>(e)); break;
break; case DRW::ATTDEF:
case DRW::CIRCLE: dxfW->writeATTDEF(static_cast<DRW_ATTDEF *>(e));
dxfW->writeCircle(static_cast<DRW_Circle*>(e)); break;
break; case DRW::LINE:
case DRW::ARC: dxfW->writeLine(static_cast<DRW_Line *>(e));
dxfW->writeArc(static_cast<DRW_Arc*>(e)); break;
break; case DRW::CIRCLE:
case DRW::SOLID: dxfW->writeCircle(static_cast<DRW_Circle *>(e));
dxfW->writeSolid(static_cast<DRW_Solid*>(e)); break;
break; case DRW::ARC:
case DRW::ELLIPSE: dxfW->writeArc(static_cast<DRW_Arc *>(e));
dxfW->writeEllipse(static_cast<DRW_Ellipse*>(e)); break;
break; case DRW::SOLID:
case DRW::LWPOLYLINE: dxfW->writeSolid(static_cast<DRW_Solid *>(e));
dxfW->writeLWPolyline(static_cast<DRW_LWPolyline*>(e)); break;
break; case DRW::ELLIPSE:
case DRW::POLYLINE: dxfW->writeEllipse(static_cast<DRW_Ellipse *>(e));
dxfW->writePolyline(static_cast<DRW_Polyline*>(e)); break;
break; case DRW::LWPOLYLINE:
case DRW::SPLINE: dxfW->writeLWPolyline(static_cast<DRW_LWPolyline *>(e));
dxfW->writeSpline(static_cast<DRW_Spline*>(e)); break;
break; case DRW::POLYLINE:
// case RS2::EntitySplinePoints: dxfW->writePolyline(static_cast<DRW_Polyline *>(e));
// writeSplinePoints(static_cast<DRW_Point*>(e)); break;
// break; case DRW::SPLINE:
// case RS2::EntityVertex: dxfW->writeSpline(static_cast<DRW_Spline *>(e));
// break; break;
case DRW::INSERT: // case RS2::EntitySplinePoints:
dxfW->writeInsert(static_cast<DRW_Insert*>(e)); // writeSplinePoints(static_cast<DRW_Point*>(e));
break; // break;
case DRW::MTEXT: // case RS2::EntityVertex:
dxfW->writeMText(static_cast<DRW_MText*>(e)); // break;
break; case DRW::INSERT:
case DRW::TEXT: dxfW->writeInsert(static_cast<DRW_Insert *>(e));
dxfW->writeText(static_cast<DRW_Text*>(e)); break;
break; case DRW::MTEXT:
case DRW::DIMLINEAR: dxfW->writeMText(static_cast<DRW_MText *>(e));
case DRW::DIMALIGNED: break;
case DRW::DIMANGULAR: case DRW::TEXT:
case DRW::DIMANGULAR3P: dxfW->writeText(static_cast<DRW_Text *>(e));
case DRW::DIMRADIAL: break;
case DRW::DIMDIAMETRIC: case DRW::DIMLINEAR:
case DRW::DIMORDINATE: case DRW::DIMALIGNED:
dxfW->writeDimension(static_cast<DRW_Dimension*>(e)); case DRW::DIMANGULAR:
break; case DRW::DIMANGULAR3P:
case DRW::LEADER: case DRW::DIMRADIAL:
dxfW->writeLeader(static_cast<DRW_Leader*>(e)); case DRW::DIMDIAMETRIC:
break; case DRW::DIMORDINATE:
case DRW::HATCH: dxfW->writeDimension(static_cast<DRW_Dimension *>(e));
dxfW->writeHatch(static_cast<DRW_Hatch*>(e)); break;
break; case DRW::LEADER:
case DRW::IMAGE: dxfW->writeLeader(static_cast<DRW_Leader *>(e));
dxfW->writeImage(static_cast<DRW_Image*>(e), static_cast<dx_ifaceImg*>(e)->path); break;
break; case DRW::HATCH:
default: dxfW->writeHatch(static_cast<DRW_Hatch *>(e));
break; break;
case DRW::IMAGE:
dxfW->writeImage(static_cast<DRW_Image *>(e), static_cast<dx_ifaceImg *>(e)->path);
break;
default:
break;
} }
} }
@ -115,56 +121,66 @@ auto dx_iface::ErrorString() const -> std::string
return dxfW->ErrorString(); return dxfW->ErrorString();
} }
void dx_iface::writeHeader(DRW_Header &data){ void dx_iface::writeHeader(DRW_Header &data)
//complete copy of header vars: {
// complete copy of header vars:
data = cData.headerC; data = cData.headerC;
//or copy one by one: // or copy one by one:
// for (auto it=cData->headerC.vars.begin(); it != cData->headerC.vars.end(); ++it) // for (auto it=cData->headerC.vars.begin(); it != cData->headerC.vars.end(); ++it)
// data.vars[it->first] = new DRW_Variant( *(it->second) ); // data.vars[it->first] = new DRW_Variant( *(it->second) );
} }
void dx_iface::writeBlocks(){ void dx_iface::writeBlocks()
//write each block {
for (auto *bk : cData.blocks){ // write each block
for (auto *bk : cData.blocks)
{
dxfW->writeBlock(bk); dxfW->writeBlock(bk);
//and write each entity in block // and write each entity in block
for (std::list<DRW_Entity*>::const_iterator it=bk->ent.begin(); it!=bk->ent.end(); ++it) for (std::list<DRW_Entity *>::const_iterator it = bk->ent.begin(); it != bk->ent.end(); ++it)
writeEntity(*it); writeEntity(*it);
} }
} }
void dx_iface::writeBlockRecords(){ void dx_iface::writeBlockRecords()
for (std::list<dx_ifaceBlock*>::iterator it=cData.blocks.begin(); it != cData.blocks.end(); ++it) {
for (std::list<dx_ifaceBlock *>::iterator it = cData.blocks.begin(); it != cData.blocks.end(); ++it)
dxfW->writeBlockRecord((*it)->name); dxfW->writeBlockRecord((*it)->name);
} }
void dx_iface::writeEntities(){ void dx_iface::writeEntities()
for (std::list<DRW_Entity*>::const_iterator it=cData.mBlock->ent.begin(); it!=cData.mBlock->ent.end(); ++it) {
for (std::list<DRW_Entity *>::const_iterator it = cData.mBlock->ent.begin(); it != cData.mBlock->ent.end(); ++it)
writeEntity(*it); writeEntity(*it);
} }
void dx_iface::writeLTypes(){ void dx_iface::writeLTypes()
for (std::list<DRW_LType>::iterator it=cData.lineTypes.begin(); it != cData.lineTypes.end(); ++it) {
for (std::list<DRW_LType>::iterator it = cData.lineTypes.begin(); it != cData.lineTypes.end(); ++it)
dxfW->writeLineType(&(*it)); dxfW->writeLineType(&(*it));
} }
void dx_iface::writeLayers(){ void dx_iface::writeLayers()
for (std::list<DRW_Layer>::iterator it=cData.layers.begin(); it != cData.layers.end(); ++it) {
for (std::list<DRW_Layer>::iterator it = cData.layers.begin(); it != cData.layers.end(); ++it)
dxfW->writeLayer(&(*it)); dxfW->writeLayer(&(*it));
} }
void dx_iface::writeTextstyles(){ void dx_iface::writeTextstyles()
for (std::list<DRW_Textstyle>::iterator it=cData.textStyles.begin(); it != cData.textStyles.end(); ++it) {
for (std::list<DRW_Textstyle>::iterator it = cData.textStyles.begin(); it != cData.textStyles.end(); ++it)
dxfW->writeTextstyle(&(*it)); dxfW->writeTextstyle(&(*it));
} }
void dx_iface::writeVports(){ void dx_iface::writeVports()
for (std::list<DRW_Vport>::iterator it=cData.VPorts.begin(); it != cData.VPorts.end(); ++it) {
for (std::list<DRW_Vport>::iterator it = cData.VPorts.begin(); it != cData.VPorts.end(); ++it)
dxfW->writeVport(&(*it)); dxfW->writeVport(&(*it));
} }
void dx_iface::writeDimstyles(){ void dx_iface::writeDimstyles()
for (std::list<DRW_Dimstyle>::iterator it=cData.dimStyles.begin(); it != cData.dimStyles.end(); ++it) {
for (std::list<DRW_Dimstyle>::iterator it = cData.dimStyles.begin(); it != cData.dimStyles.end(); ++it)
dxfW->writeDimstyle(&(*it)); dxfW->writeDimstyle(&(*it));
} }
@ -173,8 +189,9 @@ void dx_iface::writeObjects()
// default implementation for new DRW_Interface method // default implementation for new DRW_Interface method
} }
void dx_iface::writeAppId(){ void dx_iface::writeAppId()
for (auto it=cData.appIds.begin(); it != cData.appIds.end(); ++it) {
for (auto it = cData.appIds.begin(); it != cData.appIds.end(); ++it)
dxfW->writeAppId(&(*it)); dxfW->writeAppId(&(*it));
} }
@ -183,14 +200,14 @@ void dx_iface::InitHeader(VarMeasurement varMeasurement, VarInsunits varInsunits
cData.headerC.addComment("Valentina DXF File"); cData.headerC.addComment("Valentina DXF File");
// 1 = Clockwise angles, 0 = Counterclockwise // 1 = Clockwise angles, 0 = Counterclockwise
cData.headerC.addInt("$ANGDIR", 0, 70);// Qt use counterclockwise cData.headerC.addInt("$ANGDIR", 0, 70); // Qt use counterclockwise
// Sets drawing units: 0 = English; 1 = Metric // Sets drawing units: 0 = English; 1 = Metric
cData.headerC.addInt("$MEASUREMENT", static_cast<int>(varMeasurement), 70); cData.headerC.addInt("$MEASUREMENT", static_cast<int>(varMeasurement), 70);
cData.headerC.addInt("$INSUNITS", static_cast<int>(varInsunits), 70); cData.headerC.addInt("$INSUNITS", static_cast<int>(varInsunits), 70);
QString dateTime = QDateTime::currentDateTime().toString("yyyyMMdd.HHmmsszzz"); QString dateTime = QDateTime::currentDateTime().toString("yyyyMMdd.HHmmsszzz");
dateTime.chop(1);// we need hundredths of a second dateTime.chop(1); // we need hundredths of a second
cData.headerC.addStr("$TDCREATE", dateTime.toStdString(), 40); cData.headerC.addStr("$TDCREATE", dateTime.toStdString(), 40);
if (version >= DRW::AC1021) if (version >= DRW::AC1021)
@ -252,41 +269,41 @@ void dx_iface::AddAAMALayers()
{ {
DRW_Layer layer; DRW_Layer layer;
layer.name = '1';// CUT, OUTLINE layer.name = '1'; // CUT, OUTLINE
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = '8';// DRAW, INK layer.name = '8'; // DRAW, INK
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = '7';// GRAINLINE layer.name = '7'; // GRAINLINE
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
// layer.name = '6';// MIRROR LINES // layer.name = '6';// MIRROR LINES
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
layer.name = "11";// INTCUT layer.name = "11"; // INTCUT
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "13";// DRILL layer.name = "13"; // DRILL
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = '4';// NOTCH layer.name = '4'; // NOTCH
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
// Optitex doesn't like this layer // Optitex doesn't like this layer
// layer.name = "19";// TEXT // layer.name = "19";// TEXT
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
// layer.name = "26";// REF // layer.name = "26";// REF
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
} }
@ -306,99 +323,99 @@ void dx_iface::AddASTMLayers()
{ {
DRW_Layer layer; DRW_Layer layer;
layer.name = '1';// piece boundary layer.name = '1'; // piece boundary
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
// Do not support // Do not support
// layer.name = '2';// turn points // layer.name = '2';// turn points
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
// Do not support // Do not support
// layer.name = '3';// curve points // layer.name = '3';// curve points
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
layer.name = '4';// V-notch and slit notch layer.name = '4'; // V-notch and slit notch
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
// Do not support // Do not support
// layer.name = '5';// grade reference and alternate grade reference line(s) // layer.name = '5';// grade reference and alternate grade reference line(s)
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
// Do not support // Do not support
// layer.name = '6';// mirror line // layer.name = '6';// mirror line
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
layer.name = '7';// grainline layer.name = '7'; // grainline
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = '8';// internal line(s) layer.name = '8'; // internal line(s)
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
// Do not support // Do not support
// layer.name = '9';// stripe reference line(s) // layer.name = '9';// stripe reference line(s)
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
// Do not support // Do not support
// layer.name = '10';// plaid reference line(s) // layer.name = '10';// plaid reference line(s)
// layer.color = DRW::black; // layer.color = DRW::black;
// cData.layers.push_back(layer); // cData.layers.push_back(layer);
layer.name = "11";// internal cutout(s) layer.name = "11"; // internal cutout(s)
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
// Layer 12 intentionally left blank by the standard // Layer 12 intentionally left blank by the standard
layer.name = "13";// drill holes layer.name = "13"; // drill holes
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "14";// sew line(s) layer.name = "14"; // sew line(s)
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "15";// annotation text layer.name = "15"; // annotation text
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "80";// T-notch layer.name = "80"; // T-notch
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "81";// castle notch layer.name = "81"; // castle notch
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "82";// check notch layer.name = "82"; // check notch
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "83";// U-notch layer.name = "83"; // U-notch
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "84";// piece boundary quality validation curves layer.name = "84"; // piece boundary quality validation curves
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "85";// internal lines quality validation curves layer.name = "85"; // internal lines quality validation curves
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "86";// internal cutouts quality validation curves layer.name = "86"; // internal cutouts quality validation curves
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
layer.name = "87";// sew lines quality validation curves layer.name = "87"; // sew lines quality validation curves
layer.color = DRW::black; layer.color = DRW::black;
cData.layers.push_back(layer); cData.layers.push_back(layer);
} }
@ -460,7 +477,7 @@ auto dx_iface::AddFont(const QFont &f) -> UTF8STRING
ts.fontFamily += 0x1000000; ts.fontFamily += 0x1000000;
} }
for (auto it = cData.textStyles.begin() ; it !=cData.textStyles.end() ; ++it) for (auto it = cData.textStyles.begin(); it != cData.textStyles.end(); ++it)
{ {
if ((*it).name == ts.name) if ((*it).name == ts.name)
{ {
@ -482,7 +499,7 @@ void dx_iface::AddBlock(dx_ifaceBlock *block)
auto dx_iface::LocaleToISO() -> std::string auto dx_iface::LocaleToISO() -> std::string
{ {
QMap <QString, QString> locMap = LocaleMap(); QMap<QString, QString> locMap = LocaleMap();
return locMap.value(QLocale(VAbstractApplication::VApp()->Settings()->GetLocale()).name(), return locMap.value(QLocale(VAbstractApplication::VApp()->Settings()->GetLocale()).name(), "ISO8859-1")
"ISO8859-1").toStdString(); .toStdString();
} }

View file

@ -71,7 +71,7 @@ void DRW_Entity::extrudePoint(DRW_Coord extPoint, DRW_Coord *point) const
point->z = pz; point->z = pz;
} }
auto DRW_Entity::parseCode(int code, dxfReader *reader) -> bool auto DRW_Entity::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -160,7 +160,7 @@ auto DRW_Entity::parseCode(int code, dxfReader *reader) -> bool
} }
// parses dxf 102 groups to read entity // parses dxf 102 groups to read entity
auto DRW_Entity::parseDxfGroups(int code, dxfReader *reader) -> bool auto DRW_Entity::parseDxfGroups(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
std::list<DRW_Variant> ls; std::list<DRW_Variant> ls;
DRW_Variant c; DRW_Variant c;
@ -206,7 +206,7 @@ auto DRW_Entity::parseDxfGroups(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Point::parseCode(int code, dxfReader *reader) -> bool auto DRW_Point::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -239,7 +239,7 @@ auto DRW_Point::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_ASTMNotch::parseCode(int code, dxfReader *reader) -> bool auto DRW_ASTMNotch::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -253,7 +253,7 @@ auto DRW_ASTMNotch::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Line::parseCode(int code, dxfReader *reader) -> bool auto DRW_Line::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -284,7 +284,7 @@ void DRW_Circle::applyExtrusion()
} }
} }
auto DRW_Circle::parseCode(int code, dxfReader *reader) -> bool auto DRW_Circle::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -321,7 +321,7 @@ void DRW_Arc::applyExtrusion()
} }
} }
auto DRW_Arc::parseCode(int code, dxfReader *reader) -> bool auto DRW_Arc::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -338,7 +338,7 @@ auto DRW_Arc::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Ellipse::parseCode(int code, dxfReader *reader) -> bool auto DRW_Ellipse::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -453,7 +453,7 @@ void DRW_Trace::applyExtrusion()
} }
} }
auto DRW_Trace::parseCode(int code, dxfReader *reader) -> bool auto DRW_Trace::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -482,7 +482,7 @@ auto DRW_Trace::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_3Dface::parseCode(int code, dxfReader *reader) -> bool auto DRW_3Dface::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -496,7 +496,7 @@ auto DRW_3Dface::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Block::parseCode(int code, dxfReader *reader) -> bool auto DRW_Block::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -513,7 +513,7 @@ auto DRW_Block::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Insert::parseCode(int code, dxfReader *reader) -> bool auto DRW_Insert::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -568,7 +568,7 @@ void DRW_LWPolyline::applyExtrusion()
} }
} }
auto DRW_LWPolyline::parseCode(int code, dxfReader *reader) -> bool auto DRW_LWPolyline::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -627,7 +627,7 @@ auto DRW_LWPolyline::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Text::parseCode(int code, dxfReader *reader) -> bool auto DRW_Text::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -665,7 +665,7 @@ auto DRW_Text::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_MText::parseCode(int code, dxfReader *reader) -> bool auto DRW_MText::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -758,7 +758,7 @@ void DRW_MText::updateAngle()
} }
} }
auto DRW_Polyline::parseCode(int code, dxfReader *reader) -> bool auto DRW_Polyline::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -793,7 +793,7 @@ auto DRW_Polyline::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Vertex::parseCode(int code, dxfReader *reader) -> bool auto DRW_Vertex::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -834,7 +834,7 @@ auto DRW_Vertex::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Hatch::parseCode(int code, dxfReader *reader) -> bool auto DRW_Hatch::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -974,7 +974,7 @@ auto DRW_Hatch::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Spline::parseCode(int code, dxfReader *reader) -> bool auto DRW_Spline::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -1072,7 +1072,7 @@ auto DRW_Spline::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Image::parseCode(int code, dxfReader *reader) -> bool auto DRW_Image::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -1113,7 +1113,7 @@ auto DRW_Image::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Dimension::parseCode(int code, dxfReader *reader) -> bool auto DRW_Dimension::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -1236,7 +1236,7 @@ auto DRW_Dimension::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Leader::parseCode(int code, dxfReader *reader) -> bool auto DRW_Leader::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -1331,7 +1331,7 @@ auto DRW_Leader::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_Viewport::parseCode(int code, dxfReader *reader) -> bool auto DRW_Viewport::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{ {
switch (code) switch (code)
{ {
@ -1348,10 +1348,8 @@ auto DRW_Viewport::parseCode(int code, dxfReader *reader) -> bool
vpID = reader->getInt32(); vpID = reader->getInt32();
break; break;
case 12: case 12:
{
centerPX = reader->getDouble(); centerPX = reader->getDouble();
break; break;
}
case 22: case 22:
centerPY = reader->getDouble(); centerPY = reader->getDouble();
break; break;
@ -1361,3 +1359,31 @@ auto DRW_Viewport::parseCode(int code, dxfReader *reader) -> bool
return true; return true;
} }
auto DRW_ATTDEF::parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool
{
switch (code)
{
case 40:
height = reader->getDouble();
break;
case 1:
text = reader->getString();
break;
case 2:
name = reader->getString();
break;
case 3:
promptString = reader->getString();
break;
case 70:
flags = reader->getInt32();
break;
case 73:
horizontalAdjustment = reader->getInt32();
break;
default:
return DRW_Point::parseCode(code, reader);
}
return true;
}

View file

@ -18,6 +18,7 @@
#include <QtGlobal> #include <QtGlobal>
#include <algorithm> #include <algorithm>
#include <list> #include <list>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -34,7 +35,7 @@ enum ETYPE
// E3DSOLID, //encripted propietry data // E3DSOLID, //encripted propietry data
// ACAD_PROXY_ENTITY, // ACAD_PROXY_ENTITY,
ARC, ARC,
// ATTDEF, ATTDEF,
// ATTRIB, // ATTRIB,
BLOCK, // and ENDBLK BLOCK, // and ENDBLK
// BODY, //encripted propietry data // BODY, //encripted propietry data
@ -195,14 +196,14 @@ public:
protected: protected:
// parses dxf pair to read entity // parses dxf pair to read entity
virtual auto parseCode(int code, dxfReader *reader) -> bool; virtual auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool;
// calculates extrusion axis (normal vector) // calculates extrusion axis (normal vector)
void calculateAxis(DRW_Coord extPoint); void calculateAxis(DRW_Coord extPoint);
// apply extrusion to @extPoint and return data in @point // apply extrusion to @extPoint and return data in @point
void extrudePoint(DRW_Coord extPoint, DRW_Coord *point) const; void extrudePoint(DRW_Coord extPoint, DRW_Coord *point) const;
// parses dxf 102 groups to read entity // parses dxf 102 groups to read entity
auto parseDxfGroups(int code, dxfReader *reader) -> bool; auto parseDxfGroups(int code, const std::unique_ptr<dxfReader> &reader) -> bool;
public: public:
DRW::ETYPE eType; /*!< enum: entity type, code 0 */ DRW::ETYPE eType; /*!< enum: entity type, code 0 */
@ -249,7 +250,7 @@ public:
void applyExtrusion() override {} void applyExtrusion() override {}
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
DRW_Coord basePoint{}; /*!< base point, code 10, 20 & 30 */ DRW_Coord basePoint{}; /*!< base point, code 10, 20 & 30 */
@ -267,12 +268,32 @@ public:
DRW_ASTMNotch() { eType = DRW::ASTMNOTCH; } DRW_ASTMNotch() { eType = DRW::ASTMNOTCH; }
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
double angle{0}; /*!< angle, code 50 */ double angle{0}; /*!< angle, code 50 */
}; };
class DRW_ATTDEF : public DRW_Point
{
SETENTFRIENDS
public:
DRW_ATTDEF() { eType = DRW::ATTDEF; }
protected:
auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public:
DRW_Coord adjustmentPoint{}; /*!< alignment point, code 11, 21 & 31 */
double height{0}; /*!< height text, code 40 */
UTF8STRING text{}; /*!< text string, code 1 */
UTF8STRING name{}; /*!< name, code 2 */
UTF8STRING promptString{}; /*!< prompt string, code 3 */
int flags{0}; /*!< flags, code 70 */
int horizontalAdjustment{0}; /*!< Horizontal text justification, code 72, default 0 */
};
//! Class to handle line entity //! Class to handle line entity
/*! /*!
* Class to handle line entity * Class to handle line entity
@ -292,7 +313,7 @@ public:
void applyExtrusion() override {} void applyExtrusion() override {}
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
DRW_Coord secPoint; /*!< second point, code 11, 21 & 31 */ DRW_Coord secPoint; /*!< second point, code 11, 21 & 31 */
@ -341,7 +362,7 @@ public:
void applyExtrusion() override; void applyExtrusion() override;
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
double radious; /*!< radius, code 40 */ double radious; /*!< radius, code 40 */
@ -382,7 +403,7 @@ public:
protected: protected:
//! interpret code in dxf reading process or dispatch to inherited class //! interpret code in dxf reading process or dispatch to inherited class
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
double staangle; /*!< start angle, code 50 in radians*/ double staangle; /*!< start angle, code 50 in radians*/
@ -416,7 +437,7 @@ public:
protected: protected:
//! interpret code in dxf reading process or dispatch to inherited class //! interpret code in dxf reading process or dispatch to inherited class
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
private: private:
void correctAxis(); void correctAxis();
@ -448,7 +469,7 @@ public:
void applyExtrusion() override; void applyExtrusion() override;
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
DRW_Coord thirdPoint; /*!< third point, code 12, 22 & 32 */ DRW_Coord thirdPoint; /*!< third point, code 12, 22 & 32 */
@ -525,7 +546,7 @@ public:
protected: protected:
//! interpret code in dxf reading process or dispatch to inherited class //! interpret code in dxf reading process or dispatch to inherited class
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
int invisibleflag; /*!< invisible edge flag, code 70 */ int invisibleflag; /*!< invisible edge flag, code 70 */
@ -552,7 +573,7 @@ public:
void applyExtrusion() override {} void applyExtrusion() override {}
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
UTF8STRING name; /*!< block name, code 2 */ UTF8STRING name; /*!< block name, code 2 */
@ -584,7 +605,7 @@ public:
} }
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
UTF8STRING name; /*!< block name, code 2 */ UTF8STRING name; /*!< block name, code 2 */
@ -664,7 +685,7 @@ public:
} }
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
int vertexnum; /*!< number of vertex, code 90 */ int vertexnum; /*!< number of vertex, code 90 */
@ -727,7 +748,7 @@ public:
void applyExtrusion() override {} // RLZ TODO void applyExtrusion() override {} // RLZ TODO
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
double height; /*!< height text, code 40 */ double height; /*!< height text, code 40 */
@ -775,7 +796,7 @@ public:
} }
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
void updateAngle(); // recalculate angle if 'haveXAxis' is true void updateAngle(); // recalculate angle if 'haveXAxis' is true
public: public:
@ -828,7 +849,7 @@ public:
} }
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
double stawidth; /*!< Start width, code 40 */ double stawidth; /*!< Start width, code 40 */
@ -910,7 +931,7 @@ public:
void appendVertex(DRW_Vertex *v) { vertlist.push_back(v); } void appendVertex(DRW_Vertex *v) { vertlist.push_back(v); }
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
int flags; /*!< polyline flag, code 70, default 0 */ int flags; /*!< polyline flag, code 70, default 0 */
@ -1003,7 +1024,7 @@ public:
void applyExtrusion() override {} void applyExtrusion() override {}
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
// double ex; /*!< normal vector x coordinate, code 210 */ // double ex; /*!< normal vector x coordinate, code 210 */
@ -1119,7 +1140,7 @@ public:
void applyExtrusion() override {} void applyExtrusion() override {}
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
UTF8STRING name; /*!< hatch pattern name, code 2 */ UTF8STRING name; /*!< hatch pattern name, code 2 */
@ -1225,7 +1246,7 @@ public:
} }
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
duint32 ref; /*!< Hard reference to imagedef object, code 340 */ duint32 ref; /*!< Hard reference to imagedef object, code 340 */
@ -1307,12 +1328,12 @@ public:
eType = DRW::DIMENSION; eType = DRW::DIMENSION;
// RLZ needed a def value for this: hdir = ??? // RLZ needed a def value for this: hdir = ???
} }
virtual ~DRW_Dimension() = default; ~DRW_Dimension() override = default;
void applyExtrusion() override {} void applyExtrusion() override {}
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
auto getDefPoint() const -> DRW_Coord { return defPoint; } /*!< Definition point, code 10, 20 & 30 */ auto getDefPoint() const -> DRW_Coord { return defPoint; } /*!< Definition point, code 10, 20 & 30 */
@ -1671,7 +1692,7 @@ public:
void applyExtrusion() override {} void applyExtrusion() override {}
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
UTF8STRING style; /*!< Dimension style name, code 3 */ UTF8STRING style; /*!< Dimension style name, code 3 */
@ -1734,7 +1755,7 @@ public:
void applyExtrusion() override {} void applyExtrusion() override {}
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool override; auto parseCode(int code, const std::unique_ptr<dxfReader> &reader) -> bool override;
public: public:
double pswidth; /*!< Width in paper space units, code 40 */ double pswidth; /*!< Width in paper space units, code 40 */

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,7 @@
#include <map> #include <map>
#include <memory>
#include "drw_base.h" #include "drw_base.h"
class dxfReader; class dxfReader;
@ -111,11 +112,11 @@ public:
void addStr(std::string key, const std::string &value, int code); void addStr(std::string key, const std::string &value, int code);
void addCoord(std::string key, const DRW_Coord &value, int code); void addCoord(std::string key, const DRW_Coord &value, int code);
auto getComments() const -> std::string { return comments; } auto getComments() const -> std::string { return comments; }
void write(dxfWriter *writer, DRW::Version ver); void write(const std::unique_ptr<dxfWriter>& writer, DRW::Version ver);
void addComment(const std::string &c); void addComment(const std::string &c);
protected: protected:
auto parseCode(int code, dxfReader *reader) -> bool; auto parseCode(int code, const std::unique_ptr<dxfReader>& reader) -> bool;
private: private:
auto getDouble(const std::string &key, double *varDouble) const -> bool; auto getDouble(const std::string &key, double *varDouble) const -> bool;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,7 @@ public:
auto getDouble() const -> double { return doubleData; } auto getDouble() const -> double { return doubleData; }
auto getInt32() const -> int { return intData; } auto getInt32() const -> int { return intData; }
auto getInt64() const -> unsigned long long int { return int64; } auto getInt64() const -> unsigned long long int { return int64; }
auto getBool() const -> bool { return (intData == 0) ? false : true; } auto getBool() const -> bool { return intData != 0; }
auto getVersion() const -> int { return decoder.getVersion(); } auto getVersion() const -> int { return decoder.getVersion(); }
void setVersion(const std::string &v, bool dxfFormat) { decoder.setVersion(v, dxfFormat); } void setVersion(const std::string &v, bool dxfFormat) { decoder.setVersion(v, dxfFormat); }
void setCodePage(const std::string &c) { decoder.setCodePage(c, true); } void setCodePage(const std::string &c) { decoder.setCodePage(c, true); }

View file

@ -40,8 +40,6 @@ dxfRW::dxfRW(const char *name)
dxfRW::~dxfRW() dxfRW::~dxfRW()
{ {
delete reader;
delete writer;
for (auto &it : imageDef) for (auto &it : imageDef)
{ {
delete it; delete it;
@ -92,19 +90,19 @@ auto dxfRW::read(DRW_Interface *interface_, bool ext) -> bool
binFile = true; binFile = true;
// skip sentinel // skip sentinel
filestr.seekg(22, std::ios::beg); filestr.seekg(22, std::ios::beg);
reader = new dxfReaderBinary(&filestr); reader = std::make_unique<dxfReaderBinary>(&filestr);
DRW_DBG("dxfRW::read binary file\n"); DRW_DBG("dxfRW::read binary file\n");
} }
else else
{ {
binFile = false; binFile = false;
filestr.open(fileName.c_str(), std::ios_base::in); filestr.open(fileName.c_str(), std::ios_base::in);
reader = new dxfReaderAscii(&filestr); reader = std::make_unique<dxfReaderAscii>(&filestr);
} }
bool isOk = processDxf(); bool isOk = processDxf();
filestr.close(); filestr.close();
delete reader; reader.reset();
reader = nullptr; reader = nullptr;
return isOk; return isOk;
} }
@ -124,13 +122,13 @@ auto dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin) -> bool
filestr.open(fileName.c_str(), std::ios_base::out | std::ios::binary | std::ios::trunc); filestr.open(fileName.c_str(), std::ios_base::out | std::ios::binary | std::ios::trunc);
// write sentinel // write sentinel
filestr << "AutoCAD Binary DXF\r\n" << static_cast<char>(26) << '\0'; filestr << "AutoCAD Binary DXF\r\n" << static_cast<char>(26) << '\0';
writer = new dxfWriterBinary(&filestr); writer = std::make_unique<dxfWriterBinary>(&filestr);
DRW_DBG("dxfRW::read binary file\n"); DRW_DBG("dxfRW::read binary file\n");
} }
else else
{ {
filestr.open(fileName.c_str(), std::ios_base::out | std::ios::trunc); filestr.open(fileName.c_str(), std::ios_base::out | std::ios::trunc);
writer = new dxfWriterAscii(&filestr); writer = std::make_unique<dxfWriterAscii>(&filestr);
std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION); std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION);
writer->writeString(999, comm); writer->writeString(999, comm);
} }
@ -174,13 +172,11 @@ auto dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin) -> bool
catch (std::ofstream::failure &writeErr) catch (std::ofstream::failure &writeErr)
{ {
errorString = writeErr.what(); errorString = writeErr.what();
delete writer; writer.reset();
writer = nullptr;
return isOk; return isOk;
} }
isOk = true; isOk = true;
delete writer; writer.reset();
writer = nullptr;
return isOk; return isOk;
} }
@ -736,6 +732,45 @@ auto dxfRW::writeASTMNotch(DRW_ASTMNotch *ent) -> bool
return true; return true;
} }
auto dxfRW::writeATTDEF(DRW_ATTDEF *ent) -> bool
{
writer->writeString(0, "ATTDEF");
writeEntity(ent);
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbText");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
if (not qFuzzyIsNull(ent->basePoint.z))
{
writer->writeDouble(30, ent->basePoint.z);
}
writer->writeDouble(11, ent->adjustmentPoint.x);
writer->writeDouble(21, ent->adjustmentPoint.y);
if (not qFuzzyIsNull(ent->adjustmentPoint.z))
{
writer->writeDouble(31, ent->adjustmentPoint.z);
}
writer->writeDouble(40, ent->height);
writer->writeString(1, ent->text);
UTF8STRING name = ent->name;
std::replace(name.begin(), name.end(), ' ', '_');
writer->writeString(2, name);
writer->writeString(3, ent->promptString);
writer->writeInt16(70, ent->flags);
writer->writeInt16(73, ent->horizontalAdjustment);
return true;
}
auto dxfRW::writeLine(DRW_Line *ent) -> bool auto dxfRW::writeLine(DRW_Line *ent) -> bool
{ {
writer->writeString(0, "LINE"); writer->writeString(0, "LINE");

View file

@ -56,6 +56,7 @@ public:
auto writeAppId(DRW_AppId *ent) -> bool; auto writeAppId(DRW_AppId *ent) -> bool;
auto writePoint(DRW_Point *ent) -> bool; auto writePoint(DRW_Point *ent) -> bool;
auto writeASTMNotch(DRW_ASTMNotch *ent) -> bool; auto writeASTMNotch(DRW_ASTMNotch *ent) -> bool;
auto writeATTDEF(DRW_ATTDEF *ent) -> bool;
auto writeLine(DRW_Line *ent) -> bool; auto writeLine(DRW_Line *ent) -> bool;
auto writeRay(DRW_Ray *ent) -> bool; auto writeRay(DRW_Ray *ent) -> bool;
auto writeXline(DRW_Xline *ent) -> bool; auto writeXline(DRW_Xline *ent) -> bool;
@ -146,8 +147,8 @@ private:
std::string codePage{}; std::string codePage{};
bool binFile{false}; bool binFile{false};
bool m_xSpaceBlock{true}; bool m_xSpaceBlock{true};
dxfReader *reader{nullptr}; std::unique_ptr<dxfReader> reader{};
dxfWriter *writer{nullptr}; std::unique_ptr<dxfWriter> writer{};
DRW_Interface *iface{nullptr}; DRW_Interface *iface{nullptr};
DRW_Header header{}; DRW_Header header{};
// int section; // int section;

View file

@ -27,7 +27,6 @@
*************************************************************************/ *************************************************************************/
#include "vdxfengine.h" #include "vdxfengine.h"
#include <QLineF>
#include <QByteArray> #include <QByteArray>
#include <QColor> #include <QColor>
@ -55,10 +54,13 @@
#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"
#include "libdxfrw/drw_entities.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.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)
@ -976,7 +1044,7 @@ auto VDxfEngine::ExportToASTM(const QVector<VLayoutPiece> &details) -> bool
ExportASTMSewLine(detailBlock, detail); ExportASTMSewLine(detailBlock, detail);
ExportASTMInternalLine(detailBlock, detail); ExportASTMInternalLine(detailBlock, detail);
ExportASTMInternalCutout(detailBlock, detail); ExportASTMInternalCutout(detailBlock, detail);
ExportASTMNotch(detailBlock, detail); ExportASTMNotches(detailBlock, detail);
ExportAAMAGrainline(detailBlock, detail); ExportAAMAGrainline(detailBlock, detail);
ExportPieceText(detailBlock, detail); ExportPieceText(detailBlock, detail);
ExportASTMDrill(detailBlock, detail); ExportASTMDrill(detailBlock, detail);
@ -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);
} }
} }
} }
@ -1152,90 +1267,135 @@ void VDxfEngine::ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBloc
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportASTMNotch(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)
{ {
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks(); return;
for (const auto &passmark : passmarks) }
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
for (const auto &passmark : passmarks)
{
DRW_ASTMNotch *notch = ExportASTMNotch(passmark);
DRW_ATTDEF *attdef = ExportASTMNotchDataDependecy(passmark, notch->layer, detail);
detailBlock->ent.push_back(notch);
if (attdef)
{ {
auto *notch = new DRW_ASTMNotch(); detailBlock->ent.push_back(attdef);
const QPointF center = passmark.baseLine.p1();
notch->basePoint = DRW_Coord(FromPixel(center.x(), m_varInsunits),
FromPixel(GetSize().height() - center.y(), m_varInsunits),
FromPixel(passmark.baseLine.length(), m_varInsunits));
notch->angle = passmark.baseLine.angle();
switch (passmark.type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::TwoLines:
case PassmarkLineType::ThreeLines:
// Slit notch
notch->layer = *layer4;
break;
case PassmarkLineType::ExternalVMark:
case PassmarkLineType::InternalVMark:
{ // V-Notch
QLineF boundaryLine(passmark.lines.constFirst().p1(), passmark.lines.constLast().p2());
notch->thickness = FromPixel(boundaryLine.length(), m_varInsunits); // width
notch->layer = *layer4;
break;
}
case PassmarkLineType::TMark:
// T-Notch
notch->thickness = FromPixel(passmark.lines.constLast().length(), m_varInsunits); // width
notch->layer = *layer80;
break;
case PassmarkLineType::BoxMark:
{ // Castle Notch
QPointF start = passmark.lines.constFirst().p1();
QPointF end = passmark.lines.constLast().p2();
notch->layer = *layer81;
notch->thickness = FromPixel(QLineF(start, end).length(), m_varInsunits); // width
break;
}
case PassmarkLineType::UMark:
{ // U-Notch
QPointF start = passmark.lines.constFirst().p1();
QPointF end = passmark.lines.constLast().p2();
notch->thickness = FromPixel(QLineF(start, end).length(), m_varInsunits); // width
notch->layer = *layer83;
break;
}
case PassmarkLineType::CheckMark:
{ // Check Notch
const QLineF &line1 = passmark.lines.constFirst();
const QLineF &line2 = passmark.lines.constLast();
qreal width = QLineF(line1.p1(), line2.p2()).length();
if (not passmark.isClockwiseOpening)
{ // a counter clockwise opening
width *= -1;
}
notch->thickness = FromPixel(width, m_varInsunits); // width
notch->layer = *layer82;
break;
}
case PassmarkLineType::LAST_ONE_DO_NOT_USE:
Q_UNREACHABLE();
break;
default:
break;
};
detailBlock->ent.push_back(notch);
} }
} }
} }
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::ExportASTMNotch(const VLayoutPassmark &passmark) -> DRW_ASTMNotch *
{
auto *notch = new DRW_ASTMNotch();
const QPointF center = passmark.baseLine.p1();
notch->basePoint =
DRW_Coord(FromPixel(center.x(), m_varInsunits), FromPixel(GetSize().height() - center.y(), m_varInsunits),
FromPixel(passmark.baseLine.length(), m_varInsunits));
notch->angle = passmark.baseLine.angle();
switch (passmark.type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::TwoLines:
case PassmarkLineType::ThreeLines:
// Slit notch
notch->layer = *layer4;
break;
case PassmarkLineType::ExternalVMark:
case PassmarkLineType::InternalVMark:
{ // V-Notch
QLineF boundaryLine(passmark.lines.constFirst().p1(), passmark.lines.constLast().p2());
notch->thickness = FromPixel(boundaryLine.length(), m_varInsunits); // width
notch->layer = *layer4;
break;
}
case PassmarkLineType::TMark:
// T-Notch
notch->thickness = FromPixel(passmark.lines.constLast().length(), m_varInsunits); // width
notch->layer = *layer80;
break;
case PassmarkLineType::BoxMark:
{ // Castle Notch
QPointF start = passmark.lines.constFirst().p1();
QPointF end = passmark.lines.constLast().p2();
notch->layer = *layer81;
notch->thickness = FromPixel(QLineF(start, end).length(), m_varInsunits); // width
break;
}
case PassmarkLineType::UMark:
{ // U-Notch
QPointF start = passmark.lines.constFirst().p1();
QPointF end = passmark.lines.constLast().p2();
notch->thickness = FromPixel(QLineF(start, end).length(), m_varInsunits); // width
notch->layer = *layer83;
break;
}
case PassmarkLineType::CheckMark:
{ // Check Notch
const QLineF &line1 = passmark.lines.constFirst();
const QLineF &line2 = passmark.lines.constLast();
qreal width = QLineF(line1.p1(), line2.p2()).length();
if (not passmark.isClockwiseOpening)
{ // a counter clockwise opening
width *= -1;
}
notch->thickness = FromPixel(width, m_varInsunits); // width
notch->layer = *layer82;
break;
}
case PassmarkLineType::LAST_ONE_DO_NOT_USE:
Q_UNREACHABLE();
break;
default:
break;
};
return notch;
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::ExportASTMNotchDataDependecy(const VLayoutPassmark &passmark, const UTF8STRING &notchLayer,
const VLayoutPiece &detail) -> DRW_ATTDEF *
{
QVector<VLayoutPoint> boundary = not detail.IsSeamAllowanceBuiltIn() && !passmark.isBuiltIn
? detail.GetMappedSeamAllowancePoints()
: detail.GetMappedContourPoints();
const QPointF center = passmark.baseLine.p1();
QPointF referencePoint;
if (not NotchPrecedingPoint(boundary, center, referencePoint))
{
return nullptr;
}
auto *attdef = new DRW_ATTDEF();
attdef->layer = not detail.IsSeamAllowanceBuiltIn() && !passmark.isBuiltIn ? *layer1 : *layer14;
attdef->basePoint = DRW_Coord(FromPixel(referencePoint.x(), m_varInsunits),
FromPixel(GetSize().height() - referencePoint.y(), m_varInsunits), 0);
attdef->adjustmentPoint =
DRW_Coord(FromPixel(center.x(), m_varInsunits), FromPixel(GetSize().height() - center.y(), m_varInsunits), 0);
attdef->height = 3.0;
attdef->text = "Link:" + notchLayer;
attdef->name = "Dependency";
attdef->flags = 2; // this is a constant attribute
attdef->horizontalAdjustment = 3; // aligned (if vertical alignment = 0)
return attdef;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::ExportTurnPoints(const QSharedPointer<dx_ifaceBlock> &detailBlock, void VDxfEngine::ExportTurnPoints(const QSharedPointer<dx_ifaceBlock> &detailBlock,
const QVector<VLayoutPoint> &points) const const QVector<VLayoutPoint> &points) const
@ -1335,6 +1495,55 @@ auto VDxfEngine::GetFileNameForLocale() const -> std::string
#endif #endif
} }
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::NotchPrecedingPoint(const QVector<VLayoutPoint> &boundary, QPointF notchBase, QPointF &point) -> bool
{
if (boundary.count() < 2)
{
return false;
}
if (VFuzzyComparePoints(boundary.constFirst(), notchBase))
{
point = boundary.constFirst();
return true;
}
if (VFuzzyComparePoints(boundary.constLast(), notchBase))
{
point = boundary.constLast();
return true;
}
QPointF candidatePoint;
qreal bestDistance = INT_MAX;
bool found = false;
for (qint32 i = 0; i < boundary.count() - 1; ++i)
{
const QPointF cPoint = VGObject::ClosestPoint(QLineF(boundary.at(i), boundary.at(i + 1)), notchBase);
if (VGObject::IsPointOnLineSegment(cPoint, boundary.at(i), boundary.at(i + 1)))
{
const qreal length = QLineF(notchBase, cPoint).length();
if (length < bestDistance)
{
candidatePoint = boundary.at(i);
bestDistance = length;
found = true;
}
}
}
if (found)
{
point = candidatePoint;
return true;
}
return found;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <class P, class V, class C> template <class P, class V, class C>
auto VDxfEngine::CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer, bool forceClosed) -> P * auto VDxfEngine::CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer, bool forceClosed) -> P *

View file

@ -50,6 +50,9 @@ class DRW_Entity;
class dx_ifaceBlock; class dx_ifaceBlock;
class VLayoutPoint; class VLayoutPoint;
class DRW_Point; class DRW_Point;
class DRW_ASTMNotch;
struct VLayoutPassmark;
class DRW_ATTDEF;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
class VTextCodec; class VTextCodec;
@ -110,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:
@ -127,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;
@ -134,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);
@ -148,7 +156,11 @@ private:
void ExportASTMInternalCutout(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMInternalCutout(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMAnnotationText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMAnnotationText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMNotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMNotches(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
Q_REQUIRED_RESULT auto ExportASTMNotch(const VLayoutPassmark &passmark) -> DRW_ASTMNotch *;
Q_REQUIRED_RESULT auto ExportASTMNotchDataDependecy(const VLayoutPassmark &passmark, const UTF8STRING &notchLayer,
const VLayoutPiece &detail) -> DRW_ATTDEF *;
void ExportTurnPoints(const QSharedPointer<dx_ifaceBlock> &detailBlock, const QVector<VLayoutPoint> &points) const; void ExportTurnPoints(const QSharedPointer<dx_ifaceBlock> &detailBlock, const QVector<VLayoutPoint> &points) const;
void ExportCurvePoints(const QSharedPointer<dx_ifaceBlock> &detailBlock, const QVector<VLayoutPoint> &points) const; void ExportCurvePoints(const QSharedPointer<dx_ifaceBlock> &detailBlock, const QVector<VLayoutPoint> &points) const;
@ -165,6 +177,8 @@ private:
static auto FromUnicodeToCodec(const QString &str, VTextCodec *codec) -> std::string; static auto FromUnicodeToCodec(const QString &str, VTextCodec *codec) -> std::string;
auto GetFileNameForLocale() const -> std::string; auto GetFileNameForLocale() const -> std::string;
static auto NotchPrecedingPoint(const QVector<VLayoutPoint> &boundary, QPointF notchBase, QPointF &point) -> bool;
}; };
#endif // VDXFENGINE_H #endif // VDXFENGINE_H

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

@ -32,14 +32,14 @@
#include <QLineF> #include <QLineF>
#include <QMessageLogger> #include <QMessageLogger>
#include <QPoint> #include <QPoint>
#include <QtDebug>
#include <QtConcurrent> #include <QtConcurrent>
#include <QtDebug>
#include "../vmisc/def.h"
#include "../vmisc/vmath.h"
#include "../vgeometry/vpointf.h"
#include "../vmisc/vabstractapplication.h"
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "../vgeometry/vpointf.h"
#include "../vmisc/def.h"
#include "../vmisc/vabstractapplication.h"
#include "../vmisc/vmath.h"
namespace namespace
{ {
@ -74,28 +74,31 @@ inline auto CalcSqDistance(qreal x1, qreal y1, qreal x2, qreal y2) -> qreal
* @param points spline points coordinates. * @param points spline points coordinates.
* @param approximationScale curve approximation scale. * @param approximationScale curve approximation scale.
*/ */
auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4, auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4, qint16 level,
qint16 level, QVector<QPointF> points, qreal approximationScale) -> QVector<QPointF> QVector<QPointF> points, qreal approximationScale) -> QVector<QPointF>
{ {
if (points.size() >= 2) if (points.size() >= 2)
{ {
for (int i=1; i < points.size(); ++i) for (int i = 1; i < points.size(); ++i)
{ {
if (points.at(i-1) == points.at(i)) if (points.at(i - 1) == points.at(i))
{ {
qDebug("All neighbors points in path must be unique."); qDebug("All neighbors points in path must be unique.");
} }
} }
} }
const double curve_collinearity_epsilon = 1e-30; const double curve_collinearity_epsilon = 1e-30;
const double curve_angle_tolerance_epsilon = 0.01; const double curve_angle_tolerance_epsilon = 0.01;
const double m_angle_tolerance = 0.0; const double m_angle_tolerance = 0.0;
enum curve_recursion_limit_e { curve_recursion_limit = 32 }; enum curve_recursion_limit_e
{
curve_recursion_limit = 32
};
const double m_cusp_limit = 0.0; const double m_cusp_limit = 0.0;
double m_approximation_scale = approximationScale; double m_approximation_scale = approximationScale;
if(m_approximation_scale < minCurveApproximationScale || m_approximation_scale > maxCurveApproximationScale) if (m_approximation_scale < minCurveApproximationScale || m_approximation_scale > maxCurveApproximationScale)
{ {
m_approximation_scale = VAbstractApplication::VApp()->Settings()->GetCurveApproximationScale(); m_approximation_scale = VAbstractApplication::VApp()->Settings()->GetCurveApproximationScale();
} }
@ -112,35 +115,35 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
// Calculate all the mid-points of the line segments // Calculate all the mid-points of the line segments
//---------------------- //----------------------
const double x12 = (x1 + x2) / 2; const double x12 = (x1 + x2) / 2;
const double y12 = (y1 + y2) / 2; const double y12 = (y1 + y2) / 2;
const double x23 = (x2 + x3) / 2; const double x23 = (x2 + x3) / 2;
const double y23 = (y2 + y3) / 2; const double y23 = (y2 + y3) / 2;
const double x34 = (x3 + x4) / 2; const double x34 = (x3 + x4) / 2;
const double y34 = (y3 + y4) / 2; const double y34 = (y3 + y4) / 2;
const double x123 = (x12 + x23) / 2; const double x123 = (x12 + x23) / 2;
const double y123 = (y12 + y23) / 2; const double y123 = (y12 + y23) / 2;
const double x234 = (x23 + x34) / 2; const double x234 = (x23 + x34) / 2;
const double y234 = (y23 + y34) / 2; const double y234 = (y23 + y34) / 2;
const double x1234 = (x123 + x234) / 2; const double x1234 = (x123 + x234) / 2;
const double y1234 = (y123 + y234) / 2; const double y1234 = (y123 + y234) / 2;
// Try to approximate the full cubic curve by a single straight line // Try to approximate the full cubic curve by a single straight line
//------------------ //------------------
const double dx = x4-x1; const double dx = x4 - x1;
const double dy = y4-y1; const double dy = y4 - y1;
double d2 = fabs((x2 - x4) * dy - (y2 - y4) * dx); double d2 = fabs((x2 - x4) * dy - (y2 - y4) * dx);
double d3 = fabs((x3 - x4) * dy - (y3 - y4) * dx); double d3 = fabs((x3 - x4) * dy - (y3 - y4) * dx);
switch ((static_cast<int>(d2 > curve_collinearity_epsilon) << 1) + switch ((static_cast<int>(d2 > curve_collinearity_epsilon) << 1) +
static_cast<int>(d3 > curve_collinearity_epsilon)) static_cast<int>(d3 > curve_collinearity_epsilon))
{ {
case 0: case 0:
{ {
// All collinear OR p1==p4 // All collinear OR p1==p4
//---------------------- //----------------------
double k = dx*dx + dy*dy; double k = dx * dx + dy * dy;
if (k < 0.000000001) if (k < 0.000000001)
{ {
d2 = CalcSqDistance(x1, y1, x2, y2); d2 = CalcSqDistance(x1, y1, x2, y2);
@ -148,16 +151,16 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
} }
else else
{ {
k = 1 / k; k = 1 / k;
{ {
const double da1 = x2 - x1; const double da1 = x2 - x1;
const double da2 = y2 - y1; const double da2 = y2 - y1;
d2 = k * (da1*dx + da2*dy); d2 = k * (da1 * dx + da2 * dy);
} }
{ {
const double da1 = x3 - x1; const double da1 = x3 - x1;
const double da2 = y3 - y1; const double da2 = y3 - y1;
d3 = k * (da1*dx + da2*dy); d3 = k * (da1 * dx + da2 * dy);
} }
if (d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) if (d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1)
{ {
@ -175,7 +178,7 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
} }
else else
{ {
d2 = CalcSqDistance(x2, y2, x1 + d2*dx, y1 + d2*dy); d2 = CalcSqDistance(x2, y2, x1 + d2 * dx, y1 + d2 * dy);
} }
if (d3 <= 0) if (d3 <= 0)
@ -188,7 +191,7 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
} }
else else
{ {
d3 = CalcSqDistance(x3, y3, x1 + d3*dx, y1 + d3*dy); d3 = CalcSqDistance(x3, y3, x1 + d3 * dx, y1 + d3 * dy);
} }
} }
if (d2 > d3) if (d2 > d3)
@ -213,7 +216,7 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
{ {
// p1,p2,p4 are collinear, p3 is significant // p1,p2,p4 are collinear, p3 is significant
//---------------------- //----------------------
if (d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy)) if (d3 * d3 <= m_distance_tolerance_square * (dx * dx + dy * dy))
{ {
if (m_angle_tolerance < curve_angle_tolerance_epsilon) if (m_angle_tolerance < curve_angle_tolerance_epsilon)
{ {
@ -251,7 +254,7 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
{ {
// p1,p3,p4 are collinear, p2 is significant // p1,p3,p4 are collinear, p2 is significant
//---------------------- //----------------------
if (d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy)) if (d2 * d2 <= m_distance_tolerance_square * (dx * dx + dy * dy))
{ {
if (m_angle_tolerance < curve_angle_tolerance_epsilon) if (m_angle_tolerance < curve_angle_tolerance_epsilon)
{ {
@ -290,7 +293,7 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
{ {
// Regular case // Regular case
//----------------- //-----------------
if ((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy)) if ((d2 + d3) * (d2 + d3) <= m_distance_tolerance_square * (dx * dx + dy * dy))
{ {
// If the curvature doesn't exceed the distance_tolerance value // If the curvature doesn't exceed the distance_tolerance value
// we tend to finish subdivisions. // we tend to finish subdivisions.
@ -303,7 +306,7 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
// Angle & Cusp Condition // Angle & Cusp Condition
//---------------------- //----------------------
const double k = atan2(y3 - y2, x3 - x2); const double k = atan2(y3 - y2, x3 - x2);
double da1 = fabs(k - atan2(y2 - y1, x2 - x1)); double da1 = fabs(k - atan2(y2 - y1, x2 - x1));
double da2 = fabs(atan2(y4 - y3, x4 - x3) - k); double da2 = fabs(atan2(y4 - y3, x4 - x3) - k);
if (da1 >= M_PI) if (da1 >= M_PI)
@ -368,17 +371,18 @@ auto PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, q
} }
return BezierPoints() + BezierTailPoints(); return BezierPoints() + BezierTailPoints();
} }
} // namespace } // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VAbstractCubicBezier::VAbstractCubicBezier(const GOType &type, const quint32 &idObject, const Draw &mode) VAbstractCubicBezier::VAbstractCubicBezier(const GOType &type, const quint32 &idObject, const Draw &mode)
: VAbstractBezier(type, idObject, mode) : VAbstractBezier(type, idObject, mode)
{} {
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractCubicBezier::operator=(const VAbstractCubicBezier &curve) -> VAbstractCubicBezier & auto VAbstractCubicBezier::operator=(const VAbstractCubicBezier &curve) -> VAbstractCubicBezier &
{ {
if ( &curve == this ) if (&curve == this)
{ {
return *this; return *this;
} }
@ -397,86 +401,86 @@ auto VAbstractCubicBezier::operator=(const VAbstractCubicBezier &curve) -> VAbst
* @param pointName cutting point name. * @param pointName cutting point name.
* @return point of cutting. This point is forth point of first spline and first point of second spline. * @return point of cutting. This point is forth point of first spline and first point of second spline.
*/ */
auto VAbstractCubicBezier::CutSpline(qreal length, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, auto VAbstractCubicBezier::CutSpline(qreal length, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, QPointF &spl2p3,
QPointF &spl2p3, const QString &pointName) const -> QPointF const QString &pointName) const -> QPointF
{ {
//Always need return two splines, so we must correct wrong length. // Always need return two splines, so we must correct wrong length.
const qreal fullLength = GetLength(); const qreal fullLength = GetLength();
if (fullLength <= minLength) if (qFuzzyIsNull(fullLength))
{ {
spl1p2 = spl1p3 = spl2p2 = spl2p3 = QPointF(); spl1p2 = spl1p3 = spl2p2 = spl2p3 = static_cast<QPointF>(GetP1());
const QString errorMsg = QObject::tr("Unable to cut curve '%1'. The curve is too short.").arg(name()); return static_cast<QPointF>(GetP1());
VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
return {};
} }
const qreal maxLength = fullLength - minLength; if (length < 0)
if (length < minLength)
{ {
length = minLength; length = fullLength + length;
}
if (length < 0)
{
QString errorMsg; QString errorMsg;
if (not pointName.isEmpty()) if (not pointName.isEmpty())
{ {
errorMsg = QObject::tr("Curve '%1'. Length of a cut segment (%2) is too small. Optimize it to minimal " errorMsg = QObject::tr("Curve '%1'. Length of a cut segment (%2) is too small. Optimize it to minimal "
"value.").arg(name(), pointName); "value.")
.arg(name(), pointName);
} }
else else
{ {
errorMsg = QObject::tr("Curve '%1'. Length of a cut segment is too small. Optimize it to minimal value.") errorMsg = QObject::tr("Curve '%1'. Length of a cut segment is too small. Optimize it to minimal value.")
.arg(name()); .arg(name());
} }
VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) : VAbstractApplication::VApp()->IsPedantic()
qWarning() << VAbstractApplication::warningMessageSignature + errorMsg; ? throw VException(errorMsg)
: qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
} }
else if (length > maxLength) else if (length > fullLength)
{ {
length = maxLength;
QString errorMsg; QString errorMsg;
if (not pointName.isEmpty()) if (not pointName.isEmpty())
{ {
errorMsg = QObject::tr("Curve '%1'. Length of a cut segment (%2) is too big. Optimize it to maximal value.") errorMsg = QObject::tr("Curve '%1'. Length of a cut segment (%2) is too big. Optimize it to maximal value.")
.arg(name(), pointName); .arg(name(), pointName);
} }
else else
{ {
errorMsg = QObject::tr("Curve '%1'. Length of a cut segment is too big. Optimize it to maximal value.") errorMsg = QObject::tr("Curve '%1'. Length of a cut segment is too big. Optimize it to maximal value.")
.arg(name()); .arg(name());
} }
VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) : VAbstractApplication::VApp()->IsPedantic()
qWarning() << VAbstractApplication::warningMessageSignature + errorMsg; ? throw VException(errorMsg)
: qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
} }
length = qBound(0.0, length, fullLength);
const qreal parT = GetParmT(length); const qreal parT = GetParmT(length);
QLineF seg1_2 ( static_cast<QPointF>(GetP1 ()), GetControlPoint1 () ); QLineF seg1_2(static_cast<QPointF>(GetP1()), GetControlPoint1());
seg1_2.setLength(seg1_2.length () * parT); seg1_2.setLength(seg1_2.length() * parT);
const QPointF p12 = seg1_2.p2(); const QPointF p12 = seg1_2.p2();
QLineF seg2_3 ( GetControlPoint1(), GetControlPoint2 () ); QLineF seg2_3(GetControlPoint1(), GetControlPoint2());
seg2_3.setLength(seg2_3.length () * parT); seg2_3.setLength(seg2_3.length() * parT);
const QPointF p23 = seg2_3.p2(); const QPointF p23 = seg2_3.p2();
QLineF seg12_23 ( p12, p23 ); QLineF seg12_23(p12, p23);
seg12_23.setLength(seg12_23.length () * parT); seg12_23.setLength(seg12_23.length() * parT);
const QPointF p123 = seg12_23.p2(); const QPointF p123 = seg12_23.p2();
QLineF seg3_4 ( GetControlPoint2 (), static_cast<QPointF>(GetP4 ()) ); QLineF seg3_4(GetControlPoint2(), static_cast<QPointF>(GetP4()));
seg3_4.setLength(seg3_4.length () * parT); seg3_4.setLength(seg3_4.length() * parT);
const QPointF p34 = seg3_4.p2(); const QPointF p34 = seg3_4.p2();
QLineF seg23_34 ( p23, p34 ); QLineF seg23_34(p23, p34);
seg23_34.setLength(seg23_34.length () * parT); seg23_34.setLength(seg23_34.length() * parT);
const QPointF p234 = seg23_34.p2(); const QPointF p234 = seg23_34.p2();
QLineF seg123_234 ( p123, p234 ); QLineF seg123_234(p123, p234);
seg123_234.setLength(seg123_234.length () * parT); seg123_234.setLength(seg123_234.length() * parT);
const QPointF p1234 = seg123_234.p2(); const QPointF p1234 = seg123_234.p2();
spl1p2 = p12; spl1p2 = p12;
@ -535,8 +539,7 @@ auto VAbstractCubicBezier::GetParmT(qreal length) const -> qreal
} }
splLength > length ? parT -= step : parT += step; splLength > length ? parT -= step : parT += step;
} } while (qAbs(splLength - length) > eps);
while (qAbs(splLength - length) > eps);
return parT; return parT;
} }
@ -581,8 +584,8 @@ auto VAbstractCubicBezier::GetCubicBezierPoints(const QPointF &p1, const QPointF
{ {
QVector<QPointF> pvector; QVector<QPointF> pvector;
pvector.append(p1); pvector.append(p1);
pvector = PointBezier_r(p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y(), p4.x(), p4.y(), 0, pvector, pvector =
approximationScale); PointBezier_r(p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y(), p4.x(), p4.y(), 0, pvector, approximationScale);
pvector.append(p4); pvector.append(p4);
return pvector; return pvector;
} }
@ -608,32 +611,32 @@ auto VAbstractCubicBezier::RealLengthByT(qreal t) const -> qreal
{ {
if (t < 0 || t > 1) if (t < 0 || t > 1)
{ {
qDebug()<<"Wrong value t."; qDebug() << "Wrong value t.";
return 0; return 0;
} }
QLineF seg1_2 ( static_cast<QPointF>(GetP1 ()), GetControlPoint1 () ); QLineF seg1_2(static_cast<QPointF>(GetP1()), GetControlPoint1());
seg1_2.setLength(seg1_2.length () * t); seg1_2.setLength(seg1_2.length() * t);
const QPointF p12 = seg1_2.p2(); const QPointF p12 = seg1_2.p2();
QLineF seg2_3 ( GetControlPoint1 (), GetControlPoint2 () ); QLineF seg2_3(GetControlPoint1(), GetControlPoint2());
seg2_3.setLength(seg2_3.length () * t); seg2_3.setLength(seg2_3.length() * t);
const QPointF p23 = seg2_3.p2(); const QPointF p23 = seg2_3.p2();
QLineF seg12_23 ( p12, p23 ); QLineF seg12_23(p12, p23);
seg12_23.setLength(seg12_23.length () * t); seg12_23.setLength(seg12_23.length() * t);
const QPointF p123 = seg12_23.p2(); const QPointF p123 = seg12_23.p2();
QLineF seg3_4 ( GetControlPoint2 (), static_cast<QPointF>(GetP4 ()) ); QLineF seg3_4(GetControlPoint2(), static_cast<QPointF>(GetP4()));
seg3_4.setLength(seg3_4.length () * t); seg3_4.setLength(seg3_4.length() * t);
const QPointF p34 = seg3_4.p2(); const QPointF p34 = seg3_4.p2();
QLineF seg23_34 ( p23, p34 ); QLineF seg23_34(p23, p34);
seg23_34.setLength(seg23_34.length () * t); seg23_34.setLength(seg23_34.length() * t);
const QPointF p234 = seg23_34.p2(); const QPointF p234 = seg23_34.p2();
QLineF seg123_234 ( p123, p234 ); QLineF seg123_234(p123, p234);
seg123_234.setLength(seg123_234.length () * t); seg123_234.setLength(seg123_234.length() * t);
const QPointF p1234 = seg123_234.p2(); const QPointF p1234 = seg123_234.p2();
return LengthBezier ( static_cast<QPointF>(GetP1()), p12, p123, p1234, maxCurveApproximationScale); return LengthBezier(static_cast<QPointF>(GetP1()), p12, p123, p1234, maxCurveApproximationScale);
} }

View file

@ -179,25 +179,20 @@ auto VAbstractCubicBezierPath::CutSplinePath(qreal length, qint32 &p1, qint32 &p
// Always need return two spline paths, so we must correct wrong length. // Always need return two spline paths, so we must correct wrong length.
qreal fullLength = GetLength(); qreal fullLength = GetLength();
if (fullLength <= minLength) if (qFuzzyIsNull(fullLength))
{ {
p1 = p2 = -1;
spl1p2 = spl1p3 = spl2p2 = spl2p3 = QPointF(); spl1p2 = spl1p3 = spl2p2 = spl2p3 = QPointF();
const QString errorMsg = tr("Unable to cut curve '%1'. The curve is too short.").arg(name());
VAbstractApplication::VApp()->IsPedantic()
? throw VException(errorMsg)
: qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
return {}; return {};
} }
const qreal maxLength = fullLength - minLength; if (length < 0)
if (length < minLength)
{ {
length = minLength; length = fullLength + length;
}
if (length < 0)
{
QString errorMsg; QString errorMsg;
if (not pointName.isEmpty()) if (not pointName.isEmpty())
{ {
@ -213,10 +208,8 @@ auto VAbstractCubicBezierPath::CutSplinePath(qreal length, qint32 &p1, qint32 &p
? throw VException(errorMsg) ? throw VException(errorMsg)
: qWarning() << VAbstractApplication::warningMessageSignature + errorMsg; : qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
} }
else if (length > maxLength) else if (length > fullLength)
{ {
length = maxLength;
QString errorMsg; QString errorMsg;
if (not pointName.isEmpty()) if (not pointName.isEmpty())
{ {
@ -232,13 +225,15 @@ auto VAbstractCubicBezierPath::CutSplinePath(qreal length, qint32 &p1, qint32 &p
: qWarning() << VAbstractApplication::warningMessageSignature + errorMsg; : qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
} }
length = qBound(0.0, length, fullLength);
fullLength = 0; fullLength = 0;
for (qint32 i = 1; i <= CountSubSpl(); ++i) for (qint32 i = 1; i <= CountSubSpl(); ++i)
{ {
const VSpline spl = GetSpline(i); const VSpline spl = GetSpline(i);
const qreal splLength = spl.GetLength(); const qreal splLength = spl.GetLength();
fullLength += splLength; fullLength += splLength;
if (fullLength > length) if (fullLength >= length)
{ {
p1 = i - 1; p1 = i - 1;
p2 = i; p2 = i;

View file

@ -34,6 +34,7 @@
#include <QPainterPath> #include <QPainterPath>
#include <QPoint> #include <QPoint>
#include <QtDebug> #include <QtDebug>
#include <QtMath>
#include "../ifc/exception/vexceptionobjecterror.h" #include "../ifc/exception/vexceptionobjecterror.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
@ -45,6 +46,39 @@
constexpr qreal VAbstractCurve::minLength; // NOLINT(readability-redundant-declaration) constexpr qreal VAbstractCurve::minLength; // NOLINT(readability-redundant-declaration)
#endif #endif
namespace
{
//---------------------------------------------------------------------------------------------------------------------
auto NodeCurvature(const QPointF &p1, const QPointF &p2, const QPointF &p3, double length) -> double
{
QLineF l1(p2, p1);
l1.setAngle(l1.angle() + 180);
QLineF l2(p2, p3);
double angle = qDegreesToRadians(l2.angleTo(l1));
return qSin(angle / 2.0) / length;
}
//---------------------------------------------------------------------------------------------------------------------
auto MinimalLength(const QVector<QPointF> &points) -> double
{
vsizetype numPoints = points.size();
double smallestDistance = std::numeric_limits<double>::max();
for (int i = 0; i < numPoints - 1; ++i)
{
double distance = QLineF(points[i], points[i + 1]).length();
if (!qFuzzyIsNull(distance))
{
smallestDistance = std::min(smallestDistance, distance);
}
}
return smallestDistance;
}
} // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VAbstractCurve::VAbstractCurve(const GOType &type, const quint32 &idObject, const Draw &mode) VAbstractCurve::VAbstractCurve(const GOType &type, const quint32 &idObject, const Draw &mode)
: VGObject(type, idObject, mode), : VGObject(type, idObject, mode),
@ -382,74 +416,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
{ {
@ -687,6 +653,27 @@ void VAbstractCurve::SetAliasSuffix(const QString &aliasSuffix)
CreateAlias(); CreateAlias();
} }
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractCurve::Curvature(const QVector<QPointF> &vertices) -> double
{
vsizetype numVertices = vertices.size();
if (numVertices < 3)
{
// A polygonal chain needs at least 3 vertices
return 0.0;
}
qreal minLength = MinimalLength(vertices);
double sumCurvature = 0.0;
for (vsizetype i = 1; i < vertices.size() - 1; ++i)
{
sumCurvature += NodeCurvature(vertices[i - 1], vertices[i], vertices[i + 1], minLength);
}
return sumCurvature / static_cast<double>(vertices.size() - 2);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractCurve::PathLength(const QVector<QPointF> &path) -> qreal auto VAbstractCurve::PathLength(const QVector<QPointF> &path) -> qreal
{ {

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;
@ -112,7 +109,7 @@ public:
void SetAliasSuffix(const QString &aliasSuffix) override; void SetAliasSuffix(const QString &aliasSuffix) override;
static constexpr qreal minLength = MmToPixel(1.); static auto Curvature(const QVector<QPointF> &vertices) -> double;
protected: protected:
virtual void CreateName() = 0; virtual void CreateName() = 0;

View file

@ -36,6 +36,7 @@
#include "../ifc/ifcdef.h" #include "../ifc/ifcdef.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../vmisc/defglobal.h"
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include "../vmisc/vmath.h" #include "../vmisc/vmath.h"
#include "vabstractcurve.h" #include "vabstractcurve.h"
@ -405,6 +406,33 @@ auto VArc::CutArc(qreal length, const QString &pointName) const -> QPointF
return CutArc(length, arc1, arc2, pointName); return CutArc(length, arc1, arc2, pointName);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VArc::OptimalApproximationScale(qreal radius, qreal f1, qreal f2, qreal tolerance) -> qreal
{
if (qFuzzyIsNull(radius))
{
return maxCurveApproximationScale;
}
const qreal expectedCurvature = 1 / qAbs(radius);
qreal scale = minCurveApproximationScale;
do
{
VArc arc(VPointF(), radius, f1, f2);
arc.SetApproximationScale(scale);
qreal curvature = Curvature(arc.GetPoints());
if (expectedCurvature - curvature <= expectedCurvature * tolerance)
{
return scale;
}
scale += 0.1;
} while (scale <= maxCurveApproximationScale);
return maxCurveApproximationScale;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VArc::CreateName() void VArc::CreateName()
{ {

View file

@ -83,6 +83,8 @@ public:
auto CutArc(qreal length, VArc &arc1, VArc &arc2, const QString &pointName) const -> QPointF; auto CutArc(qreal length, VArc &arc1, VArc &arc2, const QString &pointName) const -> QPointF;
auto CutArc(qreal length, const QString &pointName) const -> QPointF; auto CutArc(qreal length, const QString &pointName) const -> QPointF;
static auto OptimalApproximationScale(qreal radius, qreal f1, qreal f2, qreal tolerance) -> qreal;
protected: protected:
void CreateName() override; void CreateName() override;
void CreateAlias() override; void CreateAlias() override;

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,645 @@
/************************************************************************
**
** @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>
#include <QtDebug>
#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

Some files were not shown because too many files have changed in this diff Show more