From 46bf68521e8f96d940ca975acbbfaf7acb153242 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Fri, 29 Mar 2019 19:52:37 +0200 Subject: [PATCH] Nesting with timeout. --HG-- branch : feature --- .../dialogs/dialoglayoutprogress.cpp | 73 +++--- .../valentina/dialogs/dialoglayoutprogress.h | 15 +- .../valentina/dialogs/dialoglayoutprogress.ui | 20 +- src/app/valentina/mainwindowsnogui.cpp | 208 +++++++++++++----- src/app/valentina/mainwindowsnogui.h | 3 +- src/libs/vlayout/vcontour.cpp | 8 +- src/libs/vlayout/vcontour.h | 4 +- src/libs/vlayout/vcontour_p.h | 2 +- src/libs/vlayout/vlayoutdef.h | 3 +- src/libs/vlayout/vlayoutgenerator.cpp | 47 ++-- src/libs/vlayout/vlayoutgenerator.h | 24 +- src/libs/vlayout/vlayoutpaper.cpp | 38 ++-- src/libs/vlayout/vlayoutpaper.h | 10 +- src/libs/vlayout/vlayoutpaper_p.h | 8 +- src/libs/vlayout/vlayoutpiece.cpp | 39 +++- src/libs/vlayout/vlayoutpiece.h | 2 + src/libs/vlayout/vlayoutpiece_p.h | 2 + src/libs/vlayout/vposition.cpp | 17 +- src/libs/vlayout/vposition.h | 4 +- 19 files changed, 350 insertions(+), 177 deletions(-) diff --git a/src/app/valentina/dialogs/dialoglayoutprogress.cpp b/src/app/valentina/dialogs/dialoglayoutprogress.cpp index 4d22f1732..ffbc4659a 100644 --- a/src/app/valentina/dialogs/dialoglayoutprogress.cpp +++ b/src/app/valentina/dialogs/dialoglayoutprogress.cpp @@ -35,23 +35,26 @@ #include #include #include +#include //--------------------------------------------------------------------------------------------------------------------- -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(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(m_timeout - elapsed); + QTime t; + t = t.addMSecs(timeout); + ui->labelTimeLeft->setText(tr("Time left: %1").arg(t.toString())); + ui->progressBar->setValue(static_cast(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) { diff --git a/src/app/valentina/dialogs/dialoglayoutprogress.h b/src/app/valentina/dialogs/dialoglayoutprogress.h index 13d09497a..5663d356d 100644 --- a/src/app/valentina/dialogs/dialoglayoutprogress.h +++ b/src/app/valentina/dialogs/dialoglayoutprogress.h @@ -30,6 +30,8 @@ #define DIALOGLAYOUTPROGRESS_H #include +#include +#include #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 diff --git a/src/app/valentina/dialogs/dialoglayoutprogress.ui b/src/app/valentina/dialogs/dialoglayoutprogress.ui index 06f6c86fb..c59adca10 100644 --- a/src/app/valentina/dialogs/dialoglayoutprogress.ui +++ b/src/app/valentina/dialogs/dialoglayoutprogress.ui @@ -33,7 +33,7 @@ - <html><head/><body><p>Finding best position for workpieces. Please, wait.</p></body></html> + Nesting. Please, wait. @@ -48,6 +48,15 @@ 24 + + false + + + QProgressBar::TopToBottom + + + %p% + @@ -62,7 +71,14 @@ - Arranged: + Efficiency coefficient: - + + + + + + + Time left: diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index 925b02087..9451f333e 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -123,6 +123,22 @@ void InsertGlobalContours(const QList &scenes, const QListaddItem(gcontours.at(i)); } } + +//--------------------------------------------------------------------------------------------------------------------- +qreal BiggestEdge(const QVector &pieces) +{ + qreal edge = 0; + for(auto &piece : pieces) + { + const qreal pieceEdge = piece.BiggestEdge(); + if (pieceEdge > edge) + { + edge = pieceEdge; + } + } + + return edge; +} } //--------------------------------------------------------------------------------------------------------------------- @@ -207,74 +223,167 @@ 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); + m_taskbarProgress->setMaximum(lGenerator.GetNestingTime()); + progressTimer = new QTimer(this); + connect(progressTimer, &QTimer::timeout, this, [timer, &lGenerator]() + { + const qint64 elapsed = timer.elapsed(); + const int timeout = static_cast(lGenerator.GetNestingTime() * 1000 - elapsed); + + m_taskbarProgress->setValue(static_cast(elapsed/1000)); + }); + progressTimer->start(1000); #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); + connect(progress, &DialogLayoutProgress::Abort, &lGenerator, &VLayoutGenerator::Abort); } - else + + progress->Start(); + + LayoutErrors nestingState = LayoutErrors::NoError; + + auto IsTimeout = [progress, &lGenerator, timer, &nestingState]() { - connect(&lGenerator, &VLayoutGenerator::Error, this, &MainWindowsNoGUI::ErrorConsoleMode); + 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 (IsTimeout()) + { + break; + } + + 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 + detailsOnLayout = lGenerator.GetAllDetails();// All details items + 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 + PrepareSceneList(); + ignorePrinterFields = not lGenerator.IsUsePrinterFields(); + margins = lGenerator.GetPrinterFields(); + paperSize = QSizeF(lGenerator.GetPaperWidth(), lGenerator.GetPaperHeight()); + isAutoCrop = lGenerator.GetAutoCrop(); + isUnitePages = lGenerator.IsUnitePages(); + isLayoutStale = false; + } + } + lGenerator.SetShift(lGenerator.GetShift()/2.0); + break; + case LayoutErrors::EmptyPaperError: + if (not rotationUsed) + { + lGenerator.SetRotate(true); + lGenerator.SetRotationNumber(++rotatate); + rotationUsed = true; + } + else + { + lGenerator.SetShift(lGenerator.GetShift()/2.0); + rotationUsed = false; + } + break; + case LayoutErrors::Timeout: + Q_UNREACHABLE(); + break; + case LayoutErrors::PrepareLayoutError: + 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; + } } - lGenerator.Generate(); #if defined(Q_OS_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) if (VApplication::IsGUIMode()) { + progressTimer->stop(); m_taskbarProgress->setVisible(false); } #endif - switch (lGenerator.State()) + if (VApplication::IsGUIMode()) { - case LayoutErrors::NoError: - CleanLayout(); - papers = lGenerator.GetPapersItems();// Blank sheets - details = lGenerator.GetAllDetailsItems();// All details items - detailsOnLayout = lGenerator.GetAllDetails();// All details items - 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 - PrepareSceneList(); - ignorePrinterFields = not lGenerator.IsUsePrinterFields(); - margins = lGenerator.GetPrinterFields(); - paperSize = QSizeF(lGenerator.GetPaperWidth(), lGenerator.GetPaperHeight()); - isAutoCrop = lGenerator.GetAutoCrop(); - isUnitePages = lGenerator.IsUnitePages(); - isLayoutStale = false; - if (VApplication::IsGUIMode()) - { - QApplication::alert(this); - } - break; - case LayoutErrors::ProcessStoped: - case LayoutErrors::PrepareLayoutError: - case LayoutErrors::EmptyPaperError: - if (VApplication::IsGUIMode()) - { - QApplication::alert(this); - } - return false; - default: - break; - + QApplication::alert(this); + } + + if (nestingState == LayoutErrors::NoError) + { + return true; + } + else + { + ShowLayoutError(nestingState); + if (not VApplication::IsGUIMode()) + { + qApp->exit(V_EX_DATAERR); + } + return false; } - return true; } + //--------------------------------------------------------------------------------------------------------------------- -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); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/valentina/mainwindowsnogui.h b/src/app/valentina/mainwindowsnogui.h index bdb7223c4..274c057a3 100644 --- a/src/app/valentina/mainwindowsnogui.h +++ b/src/app/valentina/mainwindowsnogui.h @@ -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 &listDetails); + + void ShowLayoutError(const LayoutErrors &state); }; #endif // MAINWINDOWSNOGUI_H diff --git a/src/libs/vlayout/vcontour.cpp b/src/libs/vlayout/vcontour.cpp index 58cfb7c51..311c49813 100644 --- a/src/libs/vlayout/vcontour.cpp +++ b/src/libs/vlayout/vcontour.cpp @@ -112,13 +112,13 @@ QVector 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 VContour::CutEdge(const QLineF &edge) const { QVector points; - if (d->shift == 0) + if (qFuzzyIsNull(d->shift)) { points.append(edge.p1()); points.append(edge.p2()); diff --git a/src/libs/vlayout/vcontour.h b/src/libs/vlayout/vcontour.h index d8f0ce02a..6e76cb4e7 100644 --- a/src/libs/vlayout/vcontour.h +++ b/src/libs/vlayout/vcontour.h @@ -66,8 +66,8 @@ public: void SetContour(const QVector &contour); QVector GetContour() const; - quint32 GetShift() const; - void SetShift(quint32 shift); + qreal GetShift() const; + void SetShift(qreal shift); int GetHeight() const; void SetHeight(int height); diff --git a/src/libs/vlayout/vcontour_p.h b/src/libs/vlayout/vcontour_p.h index 97a18cf5f..31b18b1fd 100644 --- a/src/libs/vlayout/vcontour_p.h +++ b/src/libs/vlayout/vcontour_p.h @@ -71,7 +71,7 @@ public: /** @brief paperWidth width of paper in pixels*/ int paperWidth{0}; - quint32 shift{0}; + qreal shift{0}; qreal layoutWidth{0}; diff --git a/src/libs/vlayout/vlayoutdef.h b/src/libs/vlayout/vlayoutdef.h index b93e8063d..6d8ffa0c3 100644 --- a/src/libs/vlayout/vlayoutdef.h +++ b/src/libs/vlayout/vlayoutdef.h @@ -40,7 +40,8 @@ enum class LayoutErrors : char NoError, PrepareLayoutError, ProcessStoped, - EmptyPaperError + EmptyPaperError, + Timeout }; enum class BestFrom : char diff --git a/src/libs/vlayout/vlayoutgenerator.cpp b/src/libs/vlayout/vlayoutgenerator.cpp index 31261fdba..766a3925f 100644 --- a/src/libs/vlayout/vlayoutgenerator.cpp +++ b/src/libs/vlayout/vlayoutgenerator.cpp @@ -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(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(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(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; } diff --git a/src/libs/vlayout/vlayoutgenerator.h b/src/libs/vlayout/vlayoutgenerator.h index c132f1a2a..14f35cd3e 100644 --- a/src/libs/vlayout/vlayoutgenerator.h +++ b/src/libs/vlayout/vlayoutgenerator.h @@ -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 GetPapersItems() const; Q_REQUIRED_RESULT QList GetGlobalContours() const; Q_REQUIRED_RESULT QList> 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; diff --git a/src/libs/vlayout/vlayoutpaper.cpp b/src/libs/vlayout/vlayoutpaper.cpp index 07d79ff64..8df587928 100644 --- a/src/libs/vlayout/vlayoutpaper.cpp +++ b/src/libs/vlayout/vlayoutpaper.cpp @@ -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; +} diff --git a/src/libs/vlayout/vlayoutpaper.h b/src/libs/vlayout/vlayoutpaper.h index 7ea6489d1..a70685c80 100644 --- a/src/libs/vlayout/vlayoutpaper.h +++ b/src/libs/vlayout/vlayoutpaper.h @@ -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 d; diff --git a/src/libs/vlayout/vlayoutpaper_p.h b/src/libs/vlayout/vlayoutpaper_p.h index 4e3d12389..f7635f821 100644 --- a/src/libs/vlayout/vlayoutpaper_p.h +++ b/src/libs/vlayout/vlayoutpaper_p.h @@ -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}; diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index 76a366012..c770ddb8f 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -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 &labelShape, const VTextManager &tm, bool textAsPaths) const diff --git a/src/libs/vlayout/vlayoutpiece.h b/src/libs/vlayout/vlayoutpiece.h index 5a55a15dd..163a4eab6 100644 --- a/src/libs/vlayout/vlayoutpiece.h +++ b/src/libs/vlayout/vlayoutpiece.h @@ -144,6 +144,8 @@ public: bool IsLayoutAllowanceValid() const; + qreal BiggestEdge() const; + private: QSharedDataPointer d; diff --git a/src/libs/vlayout/vlayoutpiece_p.h b/src/libs/vlayout/vlayoutpiece_p.h index f4207e284..abe179c6c 100644 --- a/src/libs/vlayout/vlayoutpiece_p.h +++ b/src/libs/vlayout/vlayoutpiece_p.h @@ -137,6 +137,8 @@ public: /** @brief m_placeLabels list of place labels. */ QVector m_placeLabels; + qint64 m_square{0}; + private: VLayoutPieceData &operator=(const VLayoutPieceData &) Q_DECL_EQ_DELETE; }; diff --git a/src/libs/vlayout/vposition.cpp b/src/libs/vlayout/vposition.cpp index f7923d27a..ab06684c7 100644 --- a/src/libs/vlayout/vposition.cpp +++ b/src/libs/vlayout/vposition.cpp @@ -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); } } } diff --git a/src/libs/vlayout/vposition.h b/src/libs/vlayout/vposition.h index 1a86b9d9a..b7308c403 100644 --- a/src/libs/vlayout/vposition.h +++ b/src/libs/vlayout/vposition.h @@ -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;