Nesting with timeout.

--HG--
branch : feature
This commit is contained in:
Roman Telezhynskyi 2019-03-29 19:52:37 +02:00
parent 290676a2a6
commit 46bf68521e
19 changed files with 350 additions and 177 deletions

View File

@ -35,23 +35,26 @@
#include <QPushButton>
#include <QMovie>
#include <QtDebug>
#include <QTime>
//---------------------------------------------------------------------------------------------------------------------
DialogLayoutProgress::DialogLayoutProgress(int count, QWidget *parent)
:QDialog(parent), ui(new Ui::DialogLayoutProgress), maxCount(count), movie(nullptr), isInitialized(false)
DialogLayoutProgress::DialogLayoutProgress(QElapsedTimer timer, qint64 timeout, QWidget *parent)
: QDialog(parent),
ui(new Ui::DialogLayoutProgress),
m_movie(new QMovie(QStringLiteral("://icon/16x16/progress.gif"))),
m_timer(timer),
m_timeout(timeout),
progressTimer(new QTimer(this))
{
ui->setupUi(this);
qApp->ValentinaSettings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c());
ui->progressBar->setMaximum(maxCount);
ui->progressBar->setMaximum(static_cast<int>(timeout/1000));
ui->progressBar->setValue(0);
ui->labelMessage->setText(tr("Arranged workpieces: %1 from %2").arg(0).arg(count));
movie = new QMovie("://icon/16x16/progress.gif");
ui->labelProgress->setMovie (movie);
movie->start ();
ui->labelProgress->setMovie(m_movie);
m_movie->start();
QPushButton *bCancel = ui->buttonBox->button(QDialogButtonBox::Cancel);
SCASSERT(bCancel != nullptr)
@ -59,13 +62,29 @@ DialogLayoutProgress::DialogLayoutProgress(int count, QWidget *parent)
setModal(true);
this->setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
connect(progressTimer, &QTimer::timeout, this, [this]()
{
const qint64 elapsed = m_timer.elapsed();
const int timeout = static_cast<int>(m_timeout - elapsed);
QTime t;
t = t.addMSecs(timeout);
ui->labelTimeLeft->setText(tr("Time left: %1").arg(t.toString()));
ui->progressBar->setValue(static_cast<int>(elapsed/1000));
if (timeout <= 1000)
{
emit Abort();
}
});
progressTimer->start(1000);
}
//---------------------------------------------------------------------------------------------------------------------
DialogLayoutProgress::~DialogLayoutProgress()
{
delete m_movie;
delete ui;
delete movie;
}
//---------------------------------------------------------------------------------------------------------------------
@ -74,41 +93,19 @@ void DialogLayoutProgress::Start()
show();
}
//---------------------------------------------------------------------------------------------------------------------
void DialogLayoutProgress::Arranged(int count)
{
ui->progressBar->setValue(count);
ui->labelMessage->setText(tr("Arranged workpieces: %1 from %2").arg(count).arg(maxCount));
}
//---------------------------------------------------------------------------------------------------------------------
void DialogLayoutProgress::Error(const LayoutErrors &state)
{
switch (state)
{
case LayoutErrors::NoError:
return;
case LayoutErrors::PrepareLayoutError:
qCritical() << tr("Couldn't prepare data for creation layout");
break;
case LayoutErrors::EmptyPaperError:
qCritical() << tr("One or more pattern pieces are bigger than the paper format you selected. Please, "
"select a bigger paper format.");
break;
case LayoutErrors::ProcessStoped:
default:
break;
}
done(QDialog::Rejected);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogLayoutProgress::Finished()
{
progressTimer->stop();
done(QDialog::Accepted);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogLayoutProgress::Efficiency(qreal value)
{
ui->labelMessage->setText(tr("Efficiency coefficient: %1").arg(qRound(value * 10) / 10));
}
//---------------------------------------------------------------------------------------------------------------------
void DialogLayoutProgress::showEvent(QShowEvent *event)
{

View File

@ -30,6 +30,8 @@
#define DIALOGLAYOUTPROGRESS_H
#include <QDialog>
#include <QElapsedTimer>
#include <QTimer>
#include "../vlayout/vlayoutdef.h"
@ -43,7 +45,7 @@ class DialogLayoutProgress : public QDialog
Q_OBJECT
public:
explicit DialogLayoutProgress(int count, QWidget *parent = nullptr);
explicit DialogLayoutProgress(QElapsedTimer timer, qint64 timeout, QWidget *parent = nullptr);
~DialogLayoutProgress();
signals:
@ -51,9 +53,8 @@ signals:
public slots:
void Start();
void Arranged(int count);
void Error(const LayoutErrors &state);
void Finished();
void Efficiency(qreal value);
protected:
virtual void showEvent(QShowEvent *event) override;
@ -61,9 +62,11 @@ protected:
private:
Q_DISABLE_COPY(DialogLayoutProgress)
Ui::DialogLayoutProgress *ui;
const int maxCount;
QMovie *movie;
bool isInitialized;
QMovie *m_movie;
QElapsedTimer m_timer;
qint64 m_timeout;
bool isInitialized{false};
QTimer *progressTimer;
};
#endif // DIALOGLAYOUTPROGRESS_H

View File

@ -33,7 +33,7 @@
</sizepolicy>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Finding best position for workpieces. Please, wait.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>Nesting. Please, wait.</string>
</property>
</widget>
</item>
@ -48,6 +48,15 @@
<property name="value">
<number>24</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
<property name="textDirection">
<enum>QProgressBar::TopToBottom</enum>
</property>
<property name="format">
<string notr="true">%p%</string>
</property>
</widget>
</item>
<item>
@ -62,7 +71,14 @@
<item>
<widget class="QLabel" name="labelMessage">
<property name="text">
<string notr="true">Arranged:</string>
<string notr="true">Efficiency coefficient: -</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelTimeLeft">
<property name="text">
<string>Time left:</string>
</property>
</widget>
</item>

View File

@ -123,6 +123,22 @@ void InsertGlobalContours(const QList<QGraphicsScene *> &scenes, const QList<QGr
scenes.at(i)->addItem(gcontours.at(i));
}
}
//---------------------------------------------------------------------------------------------------------------------
qreal BiggestEdge(const QVector<VLayoutPiece> &pieces)
{
qreal edge = 0;
for(auto &piece : pieces)
{
const qreal pieceEdge = piece.BiggestEdge();
if (pieceEdge > edge)
{
edge = pieceEdge;
}
}
return edge;
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -207,37 +223,82 @@ void MainWindowsNoGUI::ToolLayoutSettings(bool checked)
bool MainWindowsNoGUI::LayoutSettings(VLayoutGenerator& lGenerator)
{
lGenerator.SetDetails(listDetails);
DialogLayoutProgress progress(listDetails.count(), this);
QElapsedTimer timer;
timer.start();
#if defined(Q_OS_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
QTimer *progressTimer = nullptr;
#endif
DialogLayoutProgress *progress = new DialogLayoutProgress(timer, lGenerator.GetNestingTime()*1000, this);
if (VApplication::IsGUIMode())
{
#if defined(Q_OS_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
m_taskbarProgress->setVisible(true);
m_taskbarProgress->setValue(0);
m_taskbarProgress->setMaximum(listDetails.count());
connect(&lGenerator, &VLayoutGenerator::Arranged, m_taskbarProgress, &QWinTaskbarProgress::setValue);
#endif
connect(&lGenerator, &VLayoutGenerator::Start, &progress, &DialogLayoutProgress::Start);
connect(&lGenerator, &VLayoutGenerator::Arranged, &progress, &DialogLayoutProgress::Arranged);
connect(&lGenerator, &VLayoutGenerator::Error, &progress, &DialogLayoutProgress::Error);
connect(&lGenerator, &VLayoutGenerator::Finished, &progress, &DialogLayoutProgress::Finished);
connect(&progress, &DialogLayoutProgress::Abort, &lGenerator, &VLayoutGenerator::Abort);
}
else
m_taskbarProgress->setMaximum(lGenerator.GetNestingTime());
progressTimer = new QTimer(this);
connect(progressTimer, &QTimer::timeout, this, [timer, &lGenerator]()
{
connect(&lGenerator, &VLayoutGenerator::Error, this, &MainWindowsNoGUI::ErrorConsoleMode);
const qint64 elapsed = timer.elapsed();
const int timeout = static_cast<int>(lGenerator.GetNestingTime() * 1000 - elapsed);
m_taskbarProgress->setValue(static_cast<int>(elapsed/1000));
});
progressTimer->start(1000);
#endif
connect(progress, &DialogLayoutProgress::Abort, &lGenerator, &VLayoutGenerator::Abort);
}
progress->Start();
LayoutErrors nestingState = LayoutErrors::NoError;
auto IsTimeout = [progress, &lGenerator, timer, &nestingState]()
{
if (lGenerator.GetNestingTime() * 1000 - timer.elapsed() <= 0)
{
nestingState = LayoutErrors::Timeout;
progress->Finished();
return true;
}
return false;
};
bool rotationUsed = false;
int rotatate = 1;
lGenerator.SetShift(BiggestEdge(listDetails) + 1);
int papersCount = INT_MAX;
qreal efficiency = 0;
forever
{
if (IsTimeout())
{
break;
}
lGenerator.Generate();
#if defined(Q_OS_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
if (VApplication::IsGUIMode())
if (IsTimeout())
{
m_taskbarProgress->setVisible(false);
break;
}
#endif
switch (lGenerator.State())
nestingState = lGenerator.State();
switch (nestingState)
{
case LayoutErrors::NoError:
if (lGenerator.PapersCount() <= papersCount)
{
const qreal layoutEfficiency = lGenerator.LayoutEfficiency();
if (efficiency > layoutEfficiency)
{
efficiency = layoutEfficiency;
progress->Efficiency(efficiency);
CleanLayout();
papers = lGenerator.GetPapersItems();// Blank sheets
details = lGenerator.GetAllDetailsItems();// All details items
@ -245,8 +306,8 @@ bool MainWindowsNoGUI::LayoutSettings(VLayoutGenerator& lGenerator)
shadows = CreateShadows(papers);
scenes = CreateScenes(papers, shadows, details);
//Uncomment to debug, shows global contour
// gcontours = lGenerator.GetGlobalContours(); // uncomment for debugging
// InsertGlobalContours(scenes, gcontours); // uncomment for debugging
// gcontours = lGenerator.GetGlobalContours(); // uncomment for debugging
// InsertGlobalContours(scenes, gcontours); // uncomment for debugging
PrepareSceneList();
ignorePrinterFields = not lGenerator.IsUsePrinterFields();
margins = lGenerator.GetPrinterFields();
@ -254,27 +315,75 @@ bool MainWindowsNoGUI::LayoutSettings(VLayoutGenerator& lGenerator)
isAutoCrop = lGenerator.GetAutoCrop();
isUnitePages = lGenerator.IsUnitePages();
isLayoutStale = false;
if (VApplication::IsGUIMode())
}
}
lGenerator.SetShift(lGenerator.GetShift()/2.0);
break;
case LayoutErrors::EmptyPaperError:
if (not rotationUsed)
{
QApplication::alert(this);
lGenerator.SetRotate(true);
lGenerator.SetRotationNumber(++rotatate);
rotationUsed = true;
}
else
{
lGenerator.SetShift(lGenerator.GetShift()/2.0);
rotationUsed = false;
}
break;
case LayoutErrors::ProcessStoped:
case LayoutErrors::Timeout:
Q_UNREACHABLE();
break;
case LayoutErrors::PrepareLayoutError:
case LayoutErrors::EmptyPaperError:
if (VApplication::IsGUIMode())
{
QApplication::alert(this);
}
return false;
case LayoutErrors::ProcessStoped:
default:
break;
}
if (nestingState == LayoutErrors::PrepareLayoutError || nestingState == LayoutErrors::ProcessStoped
|| (nestingState == LayoutErrors::NoError && not qFuzzyIsNull(lGenerator.GetEfficiencyCoefficient())
&& efficiency >= lGenerator.GetEfficiencyCoefficient()))
{
break;
}
if (IsTimeout())
{
break;
}
}
#if defined(Q_OS_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
if (VApplication::IsGUIMode())
{
progressTimer->stop();
m_taskbarProgress->setVisible(false);
}
#endif
if (VApplication::IsGUIMode())
{
QApplication::alert(this);
}
if (nestingState == LayoutErrors::NoError)
{
return true;
}
else
{
ShowLayoutError(nestingState);
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_DATAERR);
}
return false;
}
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindowsNoGUI::ErrorConsoleMode(const LayoutErrors &state)
void MainWindowsNoGUI::ShowLayoutError(const LayoutErrors &state)
{
switch (state)
{
@ -287,12 +396,13 @@ void MainWindowsNoGUI::ErrorConsoleMode(const LayoutErrors &state)
qCritical() << tr("One or more pattern pieces are bigger than the paper format you selected. Please, "
"select a bigger paper format.");
break;
case LayoutErrors::Timeout:
qCritical() << tr("Timeout.");
break;
case LayoutErrors::ProcessStoped:
default:
break;
}
qApp->exit(V_EX_DATAERR);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -146,7 +146,6 @@ protected:
void CheckRequiredMeasurements(const VMeasurements *m) const;
private slots:
void PrintPages (QPrinter *printer);
void ErrorConsoleMode(const LayoutErrors &state);
private:
Q_DISABLE_COPY(MainWindowsNoGUI)
@ -212,6 +211,8 @@ private:
bool ignorePrinterFields, const QMarginsF &margins);
void ExportDetailsAsFlatLayout(const QVector<VLayoutPiece> &listDetails);
void ShowLayoutError(const LayoutErrors &state);
};
#endif // MAINWINDOWSNOGUI_H

View File

@ -112,13 +112,13 @@ QVector<QPointF> VContour::GetContour() const
}
//---------------------------------------------------------------------------------------------------------------------
quint32 VContour::GetShift() const
qreal VContour::GetShift() const
{
return d->shift;
}
//---------------------------------------------------------------------------------------------------------------------
void VContour::SetShift(quint32 shift)
void VContour::SetShift(qreal shift)
{
d->shift = shift;
}
@ -207,7 +207,7 @@ int VContour::GlobalEdgesCount() const
}
else
{
const qreal shift = d->shift == 0 ? ToPixel(0.5, Unit::Cm) : d->shift;
const qreal shift = qFuzzyIsNull(d->shift) ? ToPixel(0.5, Unit::Cm) : d->shift;
count = qFloor(EmptySheetEdge().length()/shift);
}
return count;
@ -251,7 +251,7 @@ QLineF VContour::GlobalEdge(int i) const
QVector<QPointF> VContour::CutEdge(const QLineF &edge) const
{
QVector<QPointF> points;
if (d->shift == 0)
if (qFuzzyIsNull(d->shift))
{
points.append(edge.p1());
points.append(edge.p2());

View File

@ -66,8 +66,8 @@ public:
void SetContour(const QVector<QPointF> &contour);
QVector<QPointF> GetContour() const;
quint32 GetShift() const;
void SetShift(quint32 shift);
qreal GetShift() const;
void SetShift(qreal shift);
int GetHeight() const;
void SetHeight(int height);

View File

@ -71,7 +71,7 @@ public:
/** @brief paperWidth width of paper in pixels*/
int paperWidth{0};
quint32 shift{0};
qreal shift{0};
qreal layoutWidth{0};

View File

@ -40,7 +40,8 @@ enum class LayoutErrors : char
NoError,
PrepareLayoutError,
ProcessStoped,
EmptyPaperError
EmptyPaperError,
Timeout
};
enum class BestFrom : char

View File

@ -56,7 +56,7 @@ VLayoutGenerator::VLayoutGenerator(QObject *parent)
shift(0),
rotate(true),
followGrainline(false),
rotationIncrease(180),
rotationNumber(2),
autoCrop(false),
saveLength(false),
unitePages(false),
@ -111,8 +111,6 @@ void VLayoutGenerator::Generate()
debugDir.mkpath(path);
#endif
emit Start();
if (bank->Prepare())
{
int width = PageWidth();
@ -146,7 +144,7 @@ void VLayoutGenerator::Generate()
paper.SetPaperIndex(static_cast<quint32>(papers.count()));
paper.SetRotate(rotate);
paper.SetFollowGrainline(followGrainline);
paper.SetRotationIncrease(rotationIncrease);
paper.SetRotationNumber(rotationNumber);
paper.SetSaveLength(saveLength);
do
{
@ -154,7 +152,6 @@ void VLayoutGenerator::Generate()
if (paper.ArrangeDetail(bank->GetDetail(index), stopGeneration))
{
bank->Arranged(index);
emit Arranged(bank->ArrangedCount());
}
else
{
@ -179,7 +176,6 @@ void VLayoutGenerator::Generate()
else
{
state = LayoutErrors::EmptyPaperError;
emit Error(state);
return;
}
}
@ -187,7 +183,6 @@ void VLayoutGenerator::Generate()
else
{
state = LayoutErrors::PrepareLayoutError;
emit Error(state);
return;
}
@ -200,8 +195,22 @@ void VLayoutGenerator::Generate()
{
UnitePages();
}
}
emit Finished();
//---------------------------------------------------------------------------------------------------------------------
qreal VLayoutGenerator::LayoutEfficiency() const
{
qreal efficiency = 0;
if (not papers.isEmpty())
{
for(auto &paper : papers)
{
efficiency += paper.Efficiency();
}
efficiency /= papers.size();
}
return efficiency;
}
//---------------------------------------------------------------------------------------------------------------------
@ -395,7 +404,7 @@ void VLayoutGenerator::GatherPages()
paper.SetPaperIndex(static_cast<quint32>(i));
paper.SetRotate(rotate);
paper.SetFollowGrainline(followGrainline);
paper.SetRotationIncrease(rotationIncrease);
paper.SetRotationNumber(rotationNumber);
paper.SetSaveLength(saveLength);
paper.SetDetails(nDetails.at(i));
@ -498,7 +507,7 @@ void VLayoutGenerator::UnitePages()
paper.SetPaperIndex(static_cast<quint32>(i));
paper.SetRotate(rotate);
paper.SetFollowGrainline(followGrainline);
paper.SetRotationIncrease(rotationIncrease);
paper.SetRotationNumber(rotationNumber);
paper.SetSaveLength(saveLength);
paper.SetDetails(nDetails.at(i));
@ -591,19 +600,19 @@ void VLayoutGenerator::SetAutoCrop(bool value)
//---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction
int VLayoutGenerator::GetRotationIncrease() const
int VLayoutGenerator::GetRotationNumber() const
{
return rotationIncrease;
return rotationNumber;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutGenerator::SetRotationIncrease(int value)
void VLayoutGenerator::SetRotationNumber(int value)
{
rotationIncrease = value;
rotationNumber = value;
if (not (rotationIncrease >= 1 && rotationIncrease <= 180 && 360 % rotationIncrease == 0))
if (rotationNumber > 360 || rotationNumber < 1)
{
rotationIncrease = 180;
rotationNumber = 2;
}
}
@ -656,7 +665,7 @@ void VLayoutGenerator::SetNestingTime(int value)
}
//---------------------------------------------------------------------------------------------------------------------
qreal VLayoutGenerator::GetEfficiencyRatio() const
qreal VLayoutGenerator::GetEfficiencyCoefficient() const
{
return efficiencyCoefficient;
}
@ -687,13 +696,13 @@ void VLayoutGenerator::SetPrinterFields(bool usePrinterFields, const QMarginsF &
}
//---------------------------------------------------------------------------------------------------------------------
quint32 VLayoutGenerator::GetShift() const
qreal VLayoutGenerator::GetShift() const
{
return shift;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutGenerator::SetShift(quint32 shift)
void VLayoutGenerator::SetShift(qreal shift)
{
this->shift = shift;
}

View File

@ -74,20 +74,24 @@ public:
int GetNestingTime() const;
void SetNestingTime(int value);
qreal GetEfficiencyRatio() const;
qreal GetEfficiencyCoefficient() const;
void SetEfficiencyCoefficient(qreal coefficient);
bool IsUsePrinterFields() const;
QMarginsF GetPrinterFields() const;
void SetPrinterFields(bool usePrinterFields, const QMarginsF &value);
quint32 GetShift() const;
void SetShift(quint32 shift);
qreal GetShift() const;
void SetShift(qreal shift);
void Generate();
qreal LayoutEfficiency() const;
LayoutErrors State() const;
int PapersCount() const {return papers.size();}
Q_REQUIRED_RESULT QList<QGraphicsItem *> GetPapersItems() const;
Q_REQUIRED_RESULT QList<QGraphicsItem *> GetGlobalContours() const;
Q_REQUIRED_RESULT QList<QList<QGraphicsItem *>> GetAllDetailsItems() const;
@ -100,8 +104,8 @@ public:
bool GetFollowGrainline() const;
void SetFollowGrainline(bool value);
int GetRotationIncrease() const;
void SetRotationIncrease(int value);
int GetRotationNumber() const;
void SetRotationNumber(int value);
bool GetAutoCrop() const;
void SetAutoCrop(bool value);
@ -121,12 +125,6 @@ public:
bool IsTestAsPaths() const;
void SetTextAsPaths(bool value);
signals:
void Start();
void Arranged(int count);
void Error(const LayoutErrors &state);
void Finished();
public slots:
void Abort();
@ -140,10 +138,10 @@ private:
bool usePrinterFields;
std::atomic_bool stopGeneration;
LayoutErrors state;
quint32 shift;
qreal shift;
bool rotate;
bool followGrainline;
int rotationIncrease;
int rotationNumber;
bool autoCrop;
bool saveLength;
bool unitePages;

View File

@ -119,13 +119,13 @@ void VLayoutPaper::SetLayoutWidth(qreal width)
}
//---------------------------------------------------------------------------------------------------------------------
quint32 VLayoutPaper::GetShift() const
qreal VLayoutPaper::GetShift() const
{
return d->globalContour.GetShift();
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPaper::SetShift(quint32 shift)
void VLayoutPaper::SetShift(qreal shift)
{
d->globalContour.SetShift(shift);
}
@ -156,24 +156,22 @@ void VLayoutPaper::SetFollowGrainline(bool value)
}
//---------------------------------------------------------------------------------------------------------------------
int VLayoutPaper::GetRotationIncrease() const
int VLayoutPaper::GetRotationNumber() const
{
return d->globalRotationIncrease;
return d->globalRotationNumber;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPaper::SetRotationIncrease(int value)
void VLayoutPaper::SetRotationNumber(int value)
{
d->globalRotationIncrease = value;
d->globalRotationNumber = value;
if (not (d->globalRotationIncrease >= 1
&& d->globalRotationIncrease <= 180
&& 360 % d->globalRotationIncrease == 0))
if (d->globalRotationNumber > 360 || d->globalRotationNumber < 1)
{
d->globalRotationIncrease = 180;
d->globalRotationNumber = 2;
}
d->localRotationIncrease = d->globalRotationIncrease;
d->localRotationNumber = d->globalRotationNumber;
}
//---------------------------------------------------------------------------------------------------------------------
@ -211,12 +209,12 @@ bool VLayoutPaper::ArrangeDetail(const VLayoutPiece &detail, std::atomic_bool &s
if ((detail.IsForceFlipping() || detail.IsForbidFlipping()) && not d->globalRotate)
{ // Compensate forbidden flipping by rotating. 180 degree will be enough.
d->localRotate = true;
d->localRotationIncrease = 180;
d->localRotationNumber = 2;
}
else
{ // Return to global values if was changed
d->localRotate = d->globalRotate;
d->localRotationIncrease = d->globalRotationIncrease;
d->localRotationNumber = d->globalRotationNumber;
}
d->frame = 0;
@ -250,7 +248,7 @@ bool VLayoutPaper::AddToSheet(const VLayoutPiece &detail, std::atomic_bool &stop
data.i = i;
data.j = j;
data.rotate = d->localRotate;
data.rotationIncrease = d->localRotationIncrease;
data.rotationNumber = d->localRotationNumber;
data.followGrainline = d->followGrainline;
auto *thread = new VPosition(data, &stop, d->saveLength);
@ -426,3 +424,15 @@ QRectF VLayoutPaper::DetailsBoundingRect() const
return rec;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VLayoutPaper::Efficiency() const
{
qreal efficiency = 0;
for(auto &detail : d->details)
{
efficiency += detail.Square();
}
return efficiency / (d->globalContour.GetWidth() * d->globalContour.GetHeight()) * 100;
}

View File

@ -73,8 +73,8 @@ public:
qreal GetLayoutWidth() const;
void SetLayoutWidth(qreal width);
quint32 GetShift() const;
void SetShift(quint32 shift);
qreal GetShift() const;
void SetShift(qreal shift);
bool GetRotate() const;
void SetRotate(bool value);
@ -82,8 +82,8 @@ public:
bool GetFollowGrainline() const;
void SetFollowGrainline(bool value);
int GetRotationIncrease() const;
void SetRotationIncrease(int value);
int GetRotationNumber() const;
void SetRotationNumber(int value);
bool IsSaveLength() const;
void SetSaveLength(bool value);
@ -101,6 +101,8 @@ public:
QRectF DetailsBoundingRect() const;
qreal Efficiency() const;
private:
QSharedDataPointer<VLayoutPaperData> d;

View File

@ -60,8 +60,8 @@ public:
layoutWidth(paper.layoutWidth),
globalRotate(paper.globalRotate),
localRotate(paper.localRotate),
globalRotationIncrease(paper.globalRotationIncrease),
localRotationIncrease(paper.localRotationIncrease),
globalRotationNumber(paper.globalRotationNumber),
localRotationNumber(paper.localRotationNumber),
saveLength(paper.saveLength),
followGrainline(paper.followGrainline)
{}
@ -79,8 +79,8 @@ public:
qreal layoutWidth{0};
bool globalRotate{true};
bool localRotate{true};
int globalRotationIncrease{180};
int localRotationIncrease{180};
int globalRotationNumber{2};
int localRotationNumber{2};
bool saveLength{false};
bool followGrainline{false};

View File

@ -742,15 +742,7 @@ bool VLayoutPiece::isNull() const
//---------------------------------------------------------------------------------------------------------------------
qint64 VLayoutPiece::Square() const
{
if (d->layoutAllowance.isEmpty()) //-V807
{
return 0;
}
const qreal res = SumTrapezoids(d->layoutAllowance);
const qint64 sq = qFloor(qAbs(res/2.0));
return sq;
return d->m_square;
}
//---------------------------------------------------------------------------------------------------------------------
@ -779,6 +771,13 @@ void VLayoutPiece::SetLayoutAllowancePoints()
{
d->layoutAllowance.clear();
}
if (d->layoutAllowance.isEmpty()) //-V807
{
d->m_square = 0;
}
d->m_square = qFloor(qAbs(SumTrapezoids(d->layoutAllowance)/2.0));
}
//---------------------------------------------------------------------------------------------------------------------
@ -945,6 +944,28 @@ bool VLayoutPiece::IsLayoutAllowanceValid() const
return VAbstractPiece::IsAllowanceValid(base, d->layoutAllowance);
}
//---------------------------------------------------------------------------------------------------------------------
qreal VLayoutPiece::BiggestEdge() const
{
qreal edge = 0;
if (d->layoutAllowance.size() < 2)
{
return edge;
}
for (int i = 1; i < d->layoutAllowance.size() - 1; ++i)
{
const qreal length = QLineF(d->layoutAllowance.at(i-1), d->layoutAllowance.at(i)).length();
if (length > edge)
{
edge = length;
}
}
return edge;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector<QPointF> &labelShape,
const VTextManager &tm, bool textAsPaths) const

View File

@ -144,6 +144,8 @@ public:
bool IsLayoutAllowanceValid() const;
qreal BiggestEdge() const;
private:
QSharedDataPointer<VLayoutPieceData> d;

View File

@ -137,6 +137,8 @@ public:
/** @brief m_placeLabels list of place labels. */
QVector<VLayoutPlaceLabel> m_placeLabels;
qint64 m_square{0};
private:
VLayoutPieceData &operator=(const VLayoutPieceData &) Q_DECL_EQ_DELETE;
};

View File

@ -147,9 +147,9 @@ VPosition::VPosition(const VPositionData &data, std::atomic_bool *stop, bool sav
stop(stop),
angle_between(0)
{
if (not (m_data.rotationIncrease >= 1 && m_data.rotationIncrease <= 180 && 360 % m_data.rotationIncrease == 0))
if (m_data.rotationNumber > 360 || m_data.rotationNumber < 1)
{
m_data.rotationIncrease = 180;
m_data.rotationNumber = 2;
}
}
@ -566,14 +566,15 @@ void VPosition::RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int
}
//---------------------------------------------------------------------------------------------------------------------
void VPosition::Rotate(int increase)
void VPosition::Rotate(int number)
{
int startAngle = 0;
const qreal step = 360/number;
qreal startAngle = 0;
if (VFuzzyComparePossibleNulls(angle_between, 360))
{
startAngle = increase;
startAngle = step;
}
for (int angle = startAngle; angle < 360; angle = angle+increase)
for (qreal angle = startAngle; angle < 360; angle = angle+step)
{
if (stop->load())
{
@ -642,13 +643,13 @@ void VPosition::FindBestPosition()
if (m_data.rotate)
{
Rotate(m_data.rotationIncrease);
Rotate(m_data.rotationNumber);
}
else
{
if (m_data.gContour.GetContour().isEmpty())
{
Rotate(m_data.rotationIncrease);
Rotate(m_data.rotationNumber);
}
}
}

View File

@ -47,7 +47,7 @@ struct VPositionData
int i{-1};
int j{-1};
bool rotate{false};
int rotationIncrease{0};
int rotationNumber{0};
bool followGrainline{false};
};
@ -124,7 +124,7 @@ private:
void CombineEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge);
void RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge, qreal angle) const;
void Rotate(int increase);
void Rotate(int number);
void FollowGrainline();
QLineF FabricGrainline() const;