From 8dec59ef009fb8095362f1a9a7136c4afe017d45 Mon Sep 17 00:00:00 2001 From: dismine Date: Mon, 12 Jan 2015 17:23:25 +0200 Subject: [PATCH] Also check shift for each edge. --HG-- branch : feature --- src/libs/vlayout/vlayoutgenerator.cpp | 16 +- src/libs/vlayout/vlayoutgenerator.h | 4 + src/libs/vlayout/vlayoutpaper.cpp | 276 ++++++++++++++++++-------- src/libs/vlayout/vlayoutpaper.h | 7 + src/libs/vlayout/vlayoutpaper_p.h | 9 +- 5 files changed, 223 insertions(+), 89 deletions(-) diff --git a/src/libs/vlayout/vlayoutgenerator.cpp b/src/libs/vlayout/vlayoutgenerator.cpp index b4e6782df..396fedabe 100644 --- a/src/libs/vlayout/vlayoutgenerator.cpp +++ b/src/libs/vlayout/vlayoutgenerator.cpp @@ -35,7 +35,7 @@ //--------------------------------------------------------------------------------------------------------------------- VLayoutGenerator::VLayoutGenerator(QObject *parent) :QObject(parent), papers(QVector()), bank(new VBank()), paperHeight(0), paperWidth(0), - stopGeneration(false), state(LayoutErrors::NoError) + stopGeneration(false), state(LayoutErrors::NoError), shift(0) {} //--------------------------------------------------------------------------------------------------------------------- @@ -88,6 +88,7 @@ void VLayoutGenerator::Generate() } VLayoutPaper paper(paperHeight, paperWidth); + paper.SetShift(shift); if (bank->LeftArrange() > 0) { const int index = bank->GetTiket(); @@ -160,6 +161,18 @@ void VLayoutGenerator::SetPaperWidth(int value) paperWidth = value; } +//--------------------------------------------------------------------------------------------------------------------- +unsigned int VLayoutGenerator::GetShift() const +{ + return shift; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutGenerator::SetShift(unsigned int shift) +{ + this->shift = shift; +} + //--------------------------------------------------------------------------------------------------------------------- int VLayoutGenerator::GetPaperHeight() const { @@ -171,4 +184,3 @@ void VLayoutGenerator::SetPaperHeight(int value) { paperHeight = value; } - diff --git a/src/libs/vlayout/vlayoutgenerator.h b/src/libs/vlayout/vlayoutgenerator.h index b70fab62e..8ebfc8d89 100644 --- a/src/libs/vlayout/vlayoutgenerator.h +++ b/src/libs/vlayout/vlayoutgenerator.h @@ -55,6 +55,9 @@ public: int GetPaperWidth() const; void SetPaperWidth(int value); + unsigned int GetShift() const; + void SetShift(unsigned int shift); + void Generate(); LayoutErrors State() const; @@ -76,6 +79,7 @@ private: int paperWidth; bool stopGeneration; LayoutErrors state; + unsigned int shift; void CheckDetailsSize(); }; diff --git a/src/libs/vlayout/vlayoutpaper.cpp b/src/libs/vlayout/vlayoutpaper.cpp index 7c9fd071b..3119ad74a 100644 --- a/src/libs/vlayout/vlayoutpaper.cpp +++ b/src/libs/vlayout/vlayoutpaper.cpp @@ -31,6 +31,7 @@ #include #include +#include class BestResult { @@ -158,6 +159,18 @@ void VLayoutPaper::SetWidth(int width) d->paperWidth = width; } +//--------------------------------------------------------------------------------------------------------------------- +unsigned int VLayoutPaper::GetShift() const +{ + return d->shift; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutPaper::SetShift(unsigned int shift) +{ + d->shift = shift; +} + //--------------------------------------------------------------------------------------------------------------------- bool VLayoutPaper::ArrangeDetail(const VLayoutDetail &detail) { @@ -193,36 +206,31 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail) { BestResult bestResult; - // We should use copy of the detail. - VLayoutDetail workDetail = detail; - - for (int i=1; i<= detail.EdgesCount(); i++) + for (int j=1; j <= EdgesCount(); ++j) { - int dEdge = i;// For mirror detail edge will be different - if (CheckPosition(workDetail, 1, dEdge)) + // We should use copy of the detail. + VLayoutDetail workDetail = detail; + + for (int i=1; i<= detail.EdgesCount(); i++) { - const QRectF rec = workDetail.BoundingRect(); - if (SheetContains(rec)) + int dEdge = i;// For mirror detail edge will be different + if (CheckPosition(workDetail, j, dEdge)) { - bestResult.NewResult(static_cast(rec.width()*rec.height()), 1, dEdge, workDetail.GetMatrix()); - } - else - { - continue; // Outside of sheet. + const QRectF rec = workDetail.BoundingRect(); + if (SheetContains(rec)) + { + bestResult.NewResult(static_cast(rec.width()*rec.height()), j, dEdge, + workDetail.GetMatrix()); + } + else + { + continue; // Outside of sheet. + } } } } - if (bestResult.ValideResult()) - { - VLayoutDetail workDetail = detail; - workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix - d->details.append(workDetail); - // First detail, just simple take all points - d->globalContour = workDetail.GetLayoutAllowencePoints(); - } - - return bestResult.ValideResult(); // Do we have the best result? + return SaveResult(bestResult, detail); } //--------------------------------------------------------------------------------------------------------------------- @@ -256,22 +264,7 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail) } } - if (bestResult.ValideResult()) - { - VLayoutDetail workDetail = detail; - workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix - const QVector newGContour = UniteWithContour(workDetail, bestResult.GContourEdge(), - bestResult.DetailEdge()); - if (newGContour.isEmpty()) - { - return false; - } - d->details.append(workDetail); - // First detail, just simple take all points - d->globalContour = newGContour; - } - - return bestResult.ValideResult(); // Do we have the best result? + return SaveResult(bestResult, detail); } //--------------------------------------------------------------------------------------------------------------------- @@ -483,42 +476,63 @@ void VLayoutPaper::CombineEdges(VLayoutDetail &detail, const QLineF &globalEdge, //--------------------------------------------------------------------------------------------------------------------- QVector VLayoutPaper::UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ) const { + QVector newContour; if (d->globalContour.isEmpty()) { - return detail.GetLayoutAllowencePoints(); - } - - if (globalI <= 0 || globalI > EdgesCount()) - { - return QVector(); - } - - if (detJ <= 0 || detJ > detail.EdgesCount()) - { - return QVector(); - } - - QVector newContour; - for(int i=0; i < d->globalContour.count(); ++i) - { - newContour.append(d->globalContour.at(i)); - ++i; - if (i==globalI) + int processedEdges = 0; + const int nD = detail.EdgesCount(); + int j = detJ+1; + do { - const QVector dPoints = detail.GetLayoutAllowencePoints(); - const int nD = dPoints.count(); - int processedPoints = 0; - int j = detJ; - do + if (j > nD) { - if (j > nD-1) + j=0; + } + const QVector points = CutEdge(detail.Edge(j)); + for (int i = 0; i < points.size()-1; ++i) + { + newContour.append(points.at(i)); + } + ++processedEdges; + ++j; + }while (processedEdges < nD); + } + else + { + if (globalI <= 0 || globalI > EdgesCount()) + { + return QVector(); + } + + if (detJ <= 0 || detJ > detail.EdgesCount()) + { + return QVector(); + } + + for(int i=0; i < d->globalContour.count(); ++i) + { + newContour.append(d->globalContour.at(i)); + ++i; + if (i==globalI) + { + int processedEdges = 0; + const int nD = detail.EdgesCount(); + int j = detJ+1; + do { - j=0; - } - newContour.append(dPoints.at(j)); - ++processedPoints; - ++j; - }while (processedPoints nD) + { + j=0; + } + const QVector points = CutEdge(detail.Edge(j)); + for (int i = 0; i < points.size()-1; ++i) + { + newContour.append(points.at(i)); + } + ++processedEdges; + ++j; + }while (processedEdges < nD); + } } } return newContour; @@ -530,29 +544,73 @@ QLineF VLayoutPaper::GlobalEdge(int i) const if (d->details.isEmpty()) { // Because sheet is blank we have one global edge for all cases - Ox axis. - return QLineF(0, 0, d->paperWidth, 0); - } + const QLineF axis = QLineF(0, 0, d->paperWidth, 0); + if (d->shift == 0) + { + return axis; + } - if (i < 1 || i > EdgesCount()) - { // Doesn't exist such edge - return QLineF(); - } - QLineF edge; - if (i < EdgesCount()) - { - edge = QLineF(d->globalContour.at(i-1), d->globalContour.at(i)); + const int n = qFloor(axis.length()/d->shift); + + if (i < 1 || i > n) + { // Doesn't exist such edge + return QLineF(); + } + + if (n <= 0) + { + return axis; + } + else + { + const qreal nShift = axis.length()/n; + return QLineF(nShift*(i-1), 0, nShift*i, 0); + } } else - { // Closed countour - edge = QLineF(d->globalContour.at(EdgesCount()-1), d->globalContour.at(0)); + { + if (i < 1 || i > EdgesCount()) + { // Doesn't exist such edge + return QLineF(); + } + QLineF edge; + if (i < EdgesCount()) + { + edge = QLineF(d->globalContour.at(i-1), d->globalContour.at(i)); + } + else + { // Closed countour + edge = QLineF(d->globalContour.at(EdgesCount()-1), d->globalContour.at(0)); + } + return edge; } - return edge; } //--------------------------------------------------------------------------------------------------------------------- int VLayoutPaper::EdgesCount() const { - return d->globalContour.count(); + if (d->details.isEmpty()) + { + if (d->shift == 0) + { + return 1; + } + + const QLineF axis = QLineF(0, 0, d->paperWidth, 0); + const int n = qFloor(axis.length()/d->shift); + if (n <= 0) + { + return 1; + } + else + { + return n; + } + } + else + { + return d->globalContour.count(); + } } //--------------------------------------------------------------------------------------------------------------------- @@ -562,3 +620,53 @@ QPolygonF VLayoutPaper::GlobalPolygon() const points.append(points.first()); return QPolygonF(points); } + +//--------------------------------------------------------------------------------------------------------------------- +QVector VLayoutPaper::CutEdge(const QLineF &edge) const +{ + QVector points; + if (d->shift == 0) + { + points.append(edge.p1()); + points.append(edge.p2()); + } + + const int n = qFloor(edge.length()/d->shift); + + if (n <= 0) + { + points.append(edge.p1()); + points.append(edge.p2()); + } + else + { + const qreal nShift = edge.length()/n; + for (int i = 1; i <= n+1; ++i) + { + QLineF l1 = edge; + l1.setLength(nShift*(i-1)); + points.append(l1.p2()); + } + } + return points; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VLayoutPaper::SaveResult(const BestResult &bestResult, const VLayoutDetail &detail) +{ + if (bestResult.ValideResult()) + { + VLayoutDetail workDetail = detail; + workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix + const QVector newGContour = UniteWithContour(workDetail, bestResult.GContourEdge(), + bestResult.DetailEdge()); + if (newGContour.isEmpty()) + { + return false; + } + d->details.append(workDetail); + d->globalContour = newGContour; + } + + return bestResult.ValideResult(); // Do we have the best result? +} diff --git a/src/libs/vlayout/vlayoutpaper.h b/src/libs/vlayout/vlayoutpaper.h index 5e231fc0e..d22682be5 100644 --- a/src/libs/vlayout/vlayoutpaper.h +++ b/src/libs/vlayout/vlayoutpaper.h @@ -36,6 +36,7 @@ class VLayoutDetail; class QPointF; class QLineF; class QPolygonF; +class BestResult; class VLayoutPaper { @@ -52,6 +53,9 @@ public: int GetWidth() const; void SetWidth(int width); + unsigned int GetShift() const; + void SetShift(unsigned int shift); + bool ArrangeDetail(const VLayoutDetail &detail); int Count() const; private: @@ -86,6 +90,9 @@ private: int EdgesCount() const; QPolygonF GlobalPolygon() const; + QVector CutEdge(const QLineF &edge) const; + + bool SaveResult(const BestResult &bestResult, const VLayoutDetail &detail); }; #endif // VLAYOUTPAPER_H diff --git a/src/libs/vlayout/vlayoutpaper_p.h b/src/libs/vlayout/vlayoutpaper_p.h index 3a9e3b23b..523e7aec3 100644 --- a/src/libs/vlayout/vlayoutpaper_p.h +++ b/src/libs/vlayout/vlayoutpaper_p.h @@ -44,16 +44,17 @@ class VLayoutPaperData : public QSharedData { public: VLayoutPaperData() - :details(QVector()), globalContour(QVector()), paperHeight(0), paperWidth(0) + :details(QVector()), globalContour(QVector()), paperHeight(0), paperWidth(0), shift(0) {} VLayoutPaperData(int height, int width) - :details(QVector()), globalContour(QVector()), paperHeight(height), paperWidth(width) + :details(QVector()), globalContour(QVector()), paperHeight(height), paperWidth(width), + shift(0) {} VLayoutPaperData(const VLayoutPaperData &paper) :QSharedData(paper), details(paper.details), globalContour(paper.globalContour), paperHeight(paper.paperHeight), - paperWidth(paper.paperWidth) + paperWidth(paper.paperWidth), shift(paper.shift) {} ~VLayoutPaperData() {} @@ -69,6 +70,8 @@ public: /** @brief paperWidth width of paper in pixels*/ int paperWidth; + + unsigned int shift; }; #ifdef Q_CC_GNU