Combine edges not enough for all cases. Was added checking position after

rotation around point.

--HG--
branch : feature
This commit is contained in:
dismine 2015-01-20 22:58:30 +02:00
parent 7970678575
commit dac95d00fe
3 changed files with 109 additions and 48 deletions

View File

@ -40,6 +40,12 @@ enum class LayoutErrors : char
EmptyPaperError EmptyPaperError
}; };
enum class BestFrom : char
{
Rotation = 0,
Combine = 1
};
//#define LAYOUT_DEBUG // Enable debug mode //#define LAYOUT_DEBUG // Enable debug mode
#ifdef LAYOUT_DEBUG #ifdef LAYOUT_DEBUG

View File

@ -43,7 +43,7 @@ class BestResult
public: public:
BestResult(); BestResult();
void NewResult(qint64 square, int i, int j, const QTransform &matrix, bool mirror); void NewResult(qint64 square, int i, int j, const QTransform &matrix, bool mirror, BestFrom type);
qint64 BestSquare() const; qint64 BestSquare() const;
int GContourEdge() const; int GContourEdge() const;
@ -51,6 +51,7 @@ public:
QTransform Matrix() const; QTransform Matrix() const;
bool ValideResult() const; bool ValideResult() const;
bool Mirror() const; bool Mirror() const;
BestFrom Type() const;
private: private:
// All nedded information about best result // All nedded information about best result
@ -60,18 +61,20 @@ private:
qint64 resSquare; // Best square size (least). For begin set max value. qint64 resSquare; // Best square size (least). For begin set max value.
bool valideResult; bool valideResult;
bool resMirror; bool resMirror;
BestFrom type;
}; };
//===================================================BestResult======================================================== //===================================================BestResult========================================================
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
BestResult::BestResult() BestResult::BestResult()
:resI(0), resJ(0), resMatrix(QMatrix()), resSquare(LLONG_MAX), valideResult(false), resMirror(false) :resI(0), resJ(0), resMatrix(QMatrix()), resSquare(LLONG_MAX), valideResult(false), resMirror(false),
type (BestFrom::Rotation)
{} {}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void BestResult::NewResult(qint64 square, int i, int j, const QTransform &matrix, bool mirror) void BestResult::NewResult(qint64 square, int i, int j, const QTransform &matrix, bool mirror, BestFrom type)
{ {
if (square <= resSquare && square > 0) if (square <= resSquare && square > 0 && type >= this->type)
{ {
resI = i; resI = i;
resJ = j; resJ = j;
@ -79,6 +82,7 @@ void BestResult::NewResult(qint64 square, int i, int j, const QTransform &matrix
resSquare = square; resSquare = square;
valideResult = true; valideResult = true;
resMirror = mirror; resMirror = mirror;
this->type = type;
} }
} }
@ -118,6 +122,12 @@ bool BestResult::Mirror() const
return resMirror; return resMirror;
} }
//---------------------------------------------------------------------------------------------------------------------
BestFrom BestResult::Type() const
{
return type;
}
//===================================================VLayoutPaper====================================================== //===================================================VLayoutPaper======================================================
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VLayoutPaper::VLayoutPaper() VLayoutPaper::VLayoutPaper()
@ -269,7 +279,7 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail, bool &stop)
const QRectF rec = workDetail.BoundingRect(); const QRectF rec = workDetail.BoundingRect();
bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), j, dEdge, bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), j, dEdge,
workDetail.GetMatrix(), workDetail.IsMirror()); workDetail.GetMatrix(), workDetail.IsMirror(), BestFrom::Combine);
} }
d->frame = d->frame + 3; d->frame = d->frame + 3;
@ -296,7 +306,7 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail, bool &stop)
const QRectF rec = workDetail.BoundingRect(); const QRectF rec = workDetail.BoundingRect();
bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), j, i, bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), j, i,
workDetail.GetMatrix(), workDetail.IsMirror()); workDetail.GetMatrix(), workDetail.IsMirror(), BestFrom::Rotation);
} }
++d->frame; ++d->frame;
} }
@ -313,10 +323,7 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail, bool &stop)
for (int j=1; j <= EdgesCount(); ++j) for (int j=1; j <= EdgesCount(); ++j)
{ {
// We should use copy of the detail. for (int i=1; i<= detail.EdgesCount(); i++)
VLayoutDetail workDetail = detail;
for (int i=1; i<= workDetail.EdgesCount(); i++)
{ {
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -325,6 +332,9 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail, bool &stop)
return false; return false;
} }
// We should use copy of the detail.
VLayoutDetail workDetail = detail;
int dEdge = i;// For mirror detail edge will be different int dEdge = i;// For mirror detail edge will be different
if (CheckCombineEdges(workDetail, j, dEdge)) if (CheckCombineEdges(workDetail, j, dEdge))
{ {
@ -334,13 +344,43 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail, bool &stop)
# endif # endif
#endif #endif
QVector<QPointF> newGContour = UniteWithContour(workDetail, j, dEdge); QVector<QPointF> newGContour = UniteWithContour(workDetail, j, dEdge, BestFrom::Combine);
newGContour.append(newGContour.first()); newGContour.append(newGContour.first());
const QRectF rec = QPolygonF(newGContour).boundingRect(); const QRectF rec = QPolygonF(newGContour).boundingRect();
bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), j, dEdge, bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), j, dEdge,
workDetail.GetMatrix(), workDetail.IsMirror()); workDetail.GetMatrix(), workDetail.IsMirror(), BestFrom::Combine);
} }
d->frame = d->frame + 3; d->frame = d->frame + 3;
for (int angle = 0; angle <= 360; angle = angle+20)
{
QCoreApplication::processEvents();
if (stop)
{
return false;
}
// We should use copy of the detail.
VLayoutDetail workDetail = detail;
if (CheckRotationEdges(workDetail, j, i, angle))
{
#ifdef LAYOUT_DEBUG
# ifdef SHOW_CANDIDATE_BEST
++d->frame;
DrawDebug(workDetail, d->frame);
# endif
#endif
QVector<QPointF> newGContour = UniteWithContour(workDetail, j, i, BestFrom::Rotation);
newGContour.append(newGContour.first());
const QRectF rec = QPolygonF(newGContour).boundingRect();
bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), j, i,
workDetail.GetMatrix(), workDetail.IsMirror(), BestFrom::Rotation);
}
++d->frame;
}
} }
} }
@ -694,28 +734,12 @@ void VLayoutPaper::RotateEdges(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, BestFrom type) const
{ {
QVector<QPointF> newContour; QVector<QPointF> newContour;
if (d->globalContour.isEmpty()) if (d->globalContour.isEmpty())
{ {
int processedEdges = 0; AppendWhole(newContour, detail, detJ);
const int nD = detail.EdgesCount();
int j = detJ+1;
do
{
if (j > nD)
{
j=1;
}
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 else
{ {
@ -744,26 +768,33 @@ QVector<QPointF> VLayoutPaper::UniteWithContour(const VLayoutDetail &detail, int
{ {
if (i == i2) if (i == i2)
{ {
int processedEdges = 0; if (type == BestFrom::Rotation)
const int nD = detail.EdgesCount();
int j = detJ+1;
do
{ {
if (j > nD) AppendWhole(newContour, detail, detJ);
}
else
{
int processedEdges = 0;
const int nD = detail.EdgesCount();
int j = detJ+1;
do
{ {
j=1; if (j > nD)
}
if (j != detJ)
{
const QVector<QPointF> points = CutEdge(detail.Edge(j));
for (int i = 0; i < points.size()-1; ++i)
{ {
newContour.append(points.at(i)); j=1;
} }
} if (j != detJ)
++processedEdges; {
++j; const QVector<QPointF> points = CutEdge(detail.Edge(j));
}while (processedEdges < nD); for (int i = 0; i < points.size()-1; ++i)
{
newContour.append(points.at(i));
}
}
++processedEdges;
++j;
}while (processedEdges < nD);
}
} }
if (newContour.isEmpty() == false) if (newContour.isEmpty() == false)
@ -783,6 +814,28 @@ QVector<QPointF> VLayoutPaper::UniteWithContour(const VLayoutDetail &detail, int
return newContour; return newContour;
} }
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPaper::AppendWhole(QVector<QPointF> &contour, const VLayoutDetail &detail, int detJ) const
{
int processedEdges = 0;
const int nD = detail.EdgesCount();
int j = detJ+1;
do
{
if (j > nD)
{
j=1;
}
const QVector<QPointF> points = CutEdge(detail.Edge(j));
for (int i = 0; i < points.size()-1; ++i)
{
contour.append(points.at(i));
}
++processedEdges;
++j;
}while (processedEdges < nD);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QLineF VLayoutPaper::GlobalEdge(int i) const QLineF VLayoutPaper::GlobalEdge(int i) const
{ {
@ -905,7 +958,7 @@ bool VLayoutPaper::SaveResult(const BestResult &bestResult, const VLayoutDetail
workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix
workDetail.SetMirror(bestResult.Mirror()); workDetail.SetMirror(bestResult.Mirror());
const QVector<QPointF> newGContour = UniteWithContour(workDetail, bestResult.GContourEdge(), const QVector<QPointF> newGContour = UniteWithContour(workDetail, bestResult.GContourEdge(),
bestResult.DetailEdge()); bestResult.DetailEdge(), bestResult.Type());
if (newGContour.isEmpty()) if (newGContour.isEmpty())
{ {
return false; return false;

View File

@ -30,6 +30,7 @@
#define VLAYOUTPAPER_H #define VLAYOUTPAPER_H
#include <QSharedDataPointer> #include <QSharedDataPointer>
#include "vlayoutdef.h"
class VLayoutPaperData; class VLayoutPaperData;
class VLayoutDetail; class VLayoutDetail;
@ -98,7 +99,8 @@ private:
void CombineEdges(VLayoutDetail &detail, const QLineF &globalEdge, const int &dEdge) const; void CombineEdges(VLayoutDetail &detail, const QLineF &globalEdge, const int &dEdge) const;
void RotateEdges(VLayoutDetail &detail, const QLineF &globalEdge, int dEdge, int angle) const; void RotateEdges(VLayoutDetail &detail, const QLineF &globalEdge, int dEdge, int angle) const;
QVector<QPointF> UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ) const; QVector<QPointF> UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ, BestFrom type) const;
void AppendWhole(QVector<QPointF> &contour, const VLayoutDetail &detail, int detJ) const;
QLineF GlobalEdge(int i) const; QLineF GlobalEdge(int i) const;
int EdgesCount() const; int EdgesCount() const;