Also check shift for each edge.

--HG--
branch : feature
This commit is contained in:
dismine 2015-01-12 17:23:25 +02:00
parent 98d5dde2e1
commit 8dec59ef00
5 changed files with 223 additions and 89 deletions

View file

@ -35,7 +35,7 @@
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VLayoutGenerator::VLayoutGenerator(QObject *parent) VLayoutGenerator::VLayoutGenerator(QObject *parent)
:QObject(parent), papers(QVector<VLayoutPaper>()), bank(new VBank()), paperHeight(0), paperWidth(0), :QObject(parent), papers(QVector<VLayoutPaper>()), 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); VLayoutPaper paper(paperHeight, paperWidth);
paper.SetShift(shift);
if (bank->LeftArrange() > 0) if (bank->LeftArrange() > 0)
{ {
const int index = bank->GetTiket(); const int index = bank->GetTiket();
@ -160,6 +161,18 @@ void VLayoutGenerator::SetPaperWidth(int value)
paperWidth = value; paperWidth = value;
} }
//---------------------------------------------------------------------------------------------------------------------
unsigned int VLayoutGenerator::GetShift() const
{
return shift;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutGenerator::SetShift(unsigned int shift)
{
this->shift = shift;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
int VLayoutGenerator::GetPaperHeight() const int VLayoutGenerator::GetPaperHeight() const
{ {
@ -171,4 +184,3 @@ void VLayoutGenerator::SetPaperHeight(int value)
{ {
paperHeight = value; paperHeight = value;
} }

View file

@ -55,6 +55,9 @@ public:
int GetPaperWidth() const; int GetPaperWidth() const;
void SetPaperWidth(int value); void SetPaperWidth(int value);
unsigned int GetShift() const;
void SetShift(unsigned int shift);
void Generate(); void Generate();
LayoutErrors State() const; LayoutErrors State() const;
@ -76,6 +79,7 @@ private:
int paperWidth; int paperWidth;
bool stopGeneration; bool stopGeneration;
LayoutErrors state; LayoutErrors state;
unsigned int shift;
void CheckDetailsSize(); void CheckDetailsSize();
}; };

View file

@ -31,6 +31,7 @@
#include <climits> #include <climits>
#include <QPointF> #include <QPointF>
#include <QtMath>
class BestResult class BestResult
{ {
@ -158,6 +159,18 @@ void VLayoutPaper::SetWidth(int width)
d->paperWidth = 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) bool VLayoutPaper::ArrangeDetail(const VLayoutDetail &detail)
{ {
@ -193,36 +206,31 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail)
{ {
BestResult bestResult; BestResult bestResult;
// We should use copy of the detail. for (int j=1; j <= EdgesCount(); ++j)
VLayoutDetail workDetail = detail;
for (int i=1; i<= detail.EdgesCount(); i++)
{ {
int dEdge = i;// For mirror detail edge will be different // We should use copy of the detail.
if (CheckPosition(workDetail, 1, dEdge)) VLayoutDetail workDetail = detail;
for (int i=1; i<= detail.EdgesCount(); i++)
{ {
const QRectF rec = workDetail.BoundingRect(); int dEdge = i;// For mirror detail edge will be different
if (SheetContains(rec)) if (CheckPosition(workDetail, j, dEdge))
{ {
bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), 1, dEdge, workDetail.GetMatrix()); const QRectF rec = workDetail.BoundingRect();
} if (SheetContains(rec))
else {
{ bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), j, dEdge,
continue; // Outside of sheet. workDetail.GetMatrix());
}
else
{
continue; // Outside of sheet.
}
} }
} }
} }
if (bestResult.ValideResult()) return SaveResult(bestResult, detail);
{
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?
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -256,22 +264,7 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail)
} }
} }
if (bestResult.ValideResult()) return SaveResult(bestResult, detail);
{
VLayoutDetail workDetail = detail;
workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix
const QVector<QPointF> 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?
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -483,42 +476,63 @@ void VLayoutPaper::CombineEdges(VLayoutDetail &detail, const QLineF &globalEdge,
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPaper::UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ) const QVector<QPointF> VLayoutPaper::UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ) const
{ {
QVector<QPointF> newContour;
if (d->globalContour.isEmpty()) if (d->globalContour.isEmpty())
{ {
return detail.GetLayoutAllowencePoints(); int processedEdges = 0;
} const int nD = detail.EdgesCount();
int j = detJ+1;
if (globalI <= 0 || globalI > EdgesCount()) do
{
return QVector<QPointF>();
}
if (detJ <= 0 || detJ > detail.EdgesCount())
{
return QVector<QPointF>();
}
QVector<QPointF> newContour;
for(int i=0; i < d->globalContour.count(); ++i)
{
newContour.append(d->globalContour.at(i));
++i;
if (i==globalI)
{ {
const QVector<QPointF> dPoints = detail.GetLayoutAllowencePoints(); if (j > nD)
const int nD = dPoints.count();
int processedPoints = 0;
int j = detJ;
do
{ {
if (j > nD-1) j=0;
}
const QVector<QPointF> 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<QPointF>();
}
if (detJ <= 0 || detJ > detail.EdgesCount())
{
return QVector<QPointF>();
}
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; if (j > nD)
} {
newContour.append(dPoints.at(j)); j=0;
++processedPoints; }
++j; const QVector<QPointF> points = CutEdge(detail.Edge(j));
}while (processedPoints<nD); for (int i = 0; i < points.size()-1; ++i)
{
newContour.append(points.at(i));
}
++processedEdges;
++j;
}while (processedEdges < nD);
}
} }
} }
return newContour; return newContour;
@ -530,29 +544,73 @@ QLineF VLayoutPaper::GlobalEdge(int i) const
if (d->details.isEmpty()) if (d->details.isEmpty())
{ {
// Because sheet is blank we have one global edge for all cases - Ox axis. // 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()) const int n = qFloor(axis.length()/d->shift);
{ // Doesn't exist such edge
return QLineF(); if (i < 1 || i > n)
} { // Doesn't exist such edge
QLineF edge; return QLineF();
if (i < EdgesCount()) }
{
edge = QLineF(d->globalContour.at(i-1), d->globalContour.at(i)); if (n <= 0)
{
return axis;
}
else
{
const qreal nShift = axis.length()/n;
return QLineF(nShift*(i-1), 0, nShift*i, 0);
}
} }
else 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 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()); points.append(points.first());
return QPolygonF(points); return QPolygonF(points);
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPaper::CutEdge(const QLineF &edge) const
{
QVector<QPointF> 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<QPointF> 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?
}

View file

@ -36,6 +36,7 @@ class VLayoutDetail;
class QPointF; class QPointF;
class QLineF; class QLineF;
class QPolygonF; class QPolygonF;
class BestResult;
class VLayoutPaper class VLayoutPaper
{ {
@ -52,6 +53,9 @@ public:
int GetWidth() const; int GetWidth() const;
void SetWidth(int width); void SetWidth(int width);
unsigned int GetShift() const;
void SetShift(unsigned int shift);
bool ArrangeDetail(const VLayoutDetail &detail); bool ArrangeDetail(const VLayoutDetail &detail);
int Count() const; int Count() const;
private: private:
@ -86,6 +90,9 @@ private:
int EdgesCount() const; int EdgesCount() const;
QPolygonF GlobalPolygon() const; QPolygonF GlobalPolygon() const;
QVector<QPointF> CutEdge(const QLineF &edge) const;
bool SaveResult(const BestResult &bestResult, const VLayoutDetail &detail);
}; };
#endif // VLAYOUTPAPER_H #endif // VLAYOUTPAPER_H

View file

@ -44,16 +44,17 @@ class VLayoutPaperData : public QSharedData
{ {
public: public:
VLayoutPaperData() VLayoutPaperData()
:details(QVector<VLayoutDetail>()), globalContour(QVector<QPointF>()), paperHeight(0), paperWidth(0) :details(QVector<VLayoutDetail>()), globalContour(QVector<QPointF>()), paperHeight(0), paperWidth(0), shift(0)
{} {}
VLayoutPaperData(int height, int width) VLayoutPaperData(int height, int width)
:details(QVector<VLayoutDetail>()), globalContour(QVector<QPointF>()), paperHeight(height), paperWidth(width) :details(QVector<VLayoutDetail>()), globalContour(QVector<QPointF>()), paperHeight(height), paperWidth(width),
shift(0)
{} {}
VLayoutPaperData(const VLayoutPaperData &paper) VLayoutPaperData(const VLayoutPaperData &paper)
:QSharedData(paper), details(paper.details), globalContour(paper.globalContour), paperHeight(paper.paperHeight), :QSharedData(paper), details(paper.details), globalContour(paper.globalContour), paperHeight(paper.paperHeight),
paperWidth(paper.paperWidth) paperWidth(paper.paperWidth), shift(paper.shift)
{} {}
~VLayoutPaperData() {} ~VLayoutPaperData() {}
@ -69,6 +70,8 @@ public:
/** @brief paperWidth width of paper in pixels*/ /** @brief paperWidth width of paper in pixels*/
int paperWidth; int paperWidth;
unsigned int shift;
}; };
#ifdef Q_CC_GNU #ifdef Q_CC_GNU