Class that handle choose next detail.

--HG--
branch : feature
This commit is contained in:
dismine 2015-01-11 15:11:56 +02:00
parent 007bc1466f
commit b53d32225a
7 changed files with 565 additions and 19 deletions

View file

@ -1919,11 +1919,11 @@ void MainWindow::ActionLayout(bool checked)
{
idetail.next();
VLayoutDetail det = VLayoutDetail();
det.SetCountour(idetail.value().ContourPoints(pattern));
det.SetCountourPoints(idetail.value().ContourPoints(pattern));
det.SetSeamAllowencePoints(idetail.value().SeamAllowancePoints(pattern));
det.setSeamAllowance(idetail.value().getSeamAllowance());
det.setName(idetail.value().getName());
det.SetLayoutAllowence();
det.SetLayoutAllowencePoints();
listDetails.append(det);
}

383
src/libs/vlayout/vbank.cpp Normal file
View file

@ -0,0 +1,383 @@
/************************************************************************
**
** @file vbank.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 11 1, 2015
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2015 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vbank.h"
#include "vlayoutdetail.h"
#include <QPointF>
#include <climits>
//---------------------------------------------------------------------------------------------------------------------
VBank::VBank()
:details(QVector<VLayoutDetail>()), unsorted(QHash<int, qint64>()), big(QHash<int, qint64>()),
middle(QHash<int, qint64>()), small(QHash<int, qint64>()), layoutWidth(0), caseType(Cases::CaseDesc),
prepare(false)
{}
//---------------------------------------------------------------------------------------------------------------------
qreal VBank::GetLayoutWidth() const
{
return layoutWidth;
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::SetLayoutWidth(const qreal &value)
{
layoutWidth = value;
Reset();
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::SetDetails(const QVector<VLayoutDetail> &details)
{
this->details = details;
Reset();
}
//---------------------------------------------------------------------------------------------------------------------
int VBank::GetTiket()
{
if (prepare == false)
{
return -1;
}
if (LeftArrange() == 0)
{
if (unsorted.isEmpty())
{
return -1;
}
else
{
PrepareGroup();
}
}
switch(caseType)
{
case Cases::CaseThreeGroup:
return GetNextThreeGroups();
case Cases::CaseTwoGroup:
return GetNextTwoGroups();
case Cases::CaseDesc:
return GetNextDescGroup();
default:
return -1;
}
}
//---------------------------------------------------------------------------------------------------------------------
VLayoutDetail VBank::GetDetail(int i) const
{
if (i >= 0 && i < details.size())
{
return details.at(i);
}
else
{
return VLayoutDetail();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::Arranged(int i)
{
if (big.contains(i))
{
big.remove(i);
return;
}
if (middle.contains(i))
{
middle.remove(i);
return;
}
if (small.contains(i))
{
small.remove(i);
return;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::NotArranged(int i)
{
if (big.contains(i))
{
unsorted.insert(i, big.value(i));
big.remove(i);
return;
}
if (middle.contains(i))
{
unsorted.insert(i, middle.value(i));
middle.remove(i);
return;
}
if (small.contains(i))
{
unsorted.insert(i, small.value(i));
small.remove(i);
return;
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VBank::Prepare()
{
if (layoutWidth <= 0)
{
prepare = false;
return prepare;
}
if (details.isEmpty())
{
prepare = false;
return prepare;
}
for (int i=0; i < details.size(); ++i)
{
details[i].SetLayoutWidth(layoutWidth);
details[i].SetLayoutAllowencePoints();
const qint64 square = details.at(i).Square();
if (square <= 0)
{
prepare = false;
return prepare;
}
unsorted.insert(i, square);
}
PrepareGroup();
prepare = true;
return prepare;
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::Reset()
{
prepare = false;
unsorted.clear();
big.clear();
middle.clear();
small.clear();
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::SetCaseType(Cases caseType)
{
this->caseType = caseType;
}
//---------------------------------------------------------------------------------------------------------------------
int VBank::AllDetailsCount() const
{
return unsorted.count() + big.count() + middle.count() + small.count();
}
//---------------------------------------------------------------------------------------------------------------------
int VBank::LeftArrange() const
{
return big.count() + middle.count() + small.count();
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::PrepareGroup()
{
switch(caseType)
{
case Cases::CaseThreeGroup:
PrepareThreeGroups();
break;
case Cases::CaseTwoGroup:
PrepareTwoGroups();
break;
case Cases::CaseDesc:
PrepareDescGroup();
break;
default:
break;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::PrepareThreeGroups()
{
qint64 sMax = LLONG_MIN;
qint64 sMin = LLONG_MAX;
SqMaxMin(sMax, sMin);
const qint64 s1 = sMax - (sMax - sMin)/3;
const qint64 s2 = sMin + (sMax - sMin)/3;
QHash<int, qint64>::const_iterator i = unsorted.constBegin();
while (i != unsorted.constEnd())
{
if (i.value() > s1)
{
big.insert(i.key(), i.value());
}
else if (s1 > i.value() && i.value() > s2)
{
middle.insert(i.key(), i.value());
}
else
{
small.insert(i.key(), i.value());
}
++i;
}
unsorted.clear();
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::PrepareTwoGroups()
{
qint64 sMax = LLONG_MIN;
qint64 sMin = LLONG_MAX;
SqMaxMin(sMax, sMin);
const qint64 s = (sMax + sMin)/2;
QHash<int, qint64>::const_iterator i = unsorted.constBegin();
while (i != unsorted.constEnd())
{
if (i.value() >= s)
{
big.insert(i.key(), i.value());
}
else
{
small.insert(i.key(), i.value());
}
++i;
}
unsorted.clear();
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::PrepareDescGroup()
{
big = unsorted;
unsorted.clear();
}
//---------------------------------------------------------------------------------------------------------------------
int VBank::GetNextThreeGroups() const
{
if (big.isEmpty() == false)
{
QHash<int, qint64>::const_iterator i = big.constBegin();
return i.key();
}
if (middle.isEmpty() == false)
{
QHash<int, qint64>::const_iterator i = middle.constBegin();
return i.key();
}
if (small.isEmpty() == false)
{
QHash<int, qint64>::const_iterator i = small.constBegin();
return i.key();
}
return -1;
}
//---------------------------------------------------------------------------------------------------------------------
int VBank::GetNextTwoGroups() const
{
if (big.isEmpty() == false)
{
QHash<int, qint64>::const_iterator i = big.constBegin();
return i.key();
}
if (small.isEmpty() == false)
{
QHash<int, qint64>::const_iterator i = small.constBegin();
return i.key();
}
return -1;
}
//---------------------------------------------------------------------------------------------------------------------
int VBank::GetNextDescGroup() const
{
int index = -1;
qint64 sMax = LLONG_MIN;
QHash<int, qint64>::const_iterator i = big.constBegin();
while (i != big.constEnd())
{
if (i.value() > sMax)
{
sMax = i.value();
index = i.key();
}
++i;
}
return index;
}
//---------------------------------------------------------------------------------------------------------------------
void VBank::SqMaxMin(qint64 &sMax, qint64 &sMin) const
{
sMax = LLONG_MIN;
sMin = LLONG_MAX;
QHash<int, qint64>::const_iterator i = unsorted.constBegin();
while (i != unsorted.constEnd())
{
if (i.value() < sMin)
{
sMin = i.value();
}
if (i.value() > sMax)
{
sMax = i.value();
}
++i;
}
}

89
src/libs/vlayout/vbank.h Normal file
View file

@ -0,0 +1,89 @@
/************************************************************************
**
** @file vbank.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 11 1, 2015
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2015 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VBANK_H
#define VBANK_H
#include <QVector>
#include <QHash>
class QPointF;
class VLayoutDetail;
enum class Cases : char { CaseThreeGroup, CaseTwoGroup, CaseDesc};
class VBank
{
public:
VBank();
qreal GetLayoutWidth() const;
void SetLayoutWidth(const qreal &value);
void SetDetails(const QVector<VLayoutDetail> &details);
int GetTiket();
VLayoutDetail GetDetail(int i) const;
void Arranged(int i);
void NotArranged(int i);
bool Prepare();
void Reset();
void SetCaseType(Cases caseType);
int AllDetailsCount() const;
int LeftArrange() const;
private:
Q_DISABLE_COPY(VBank)
QVector<VLayoutDetail> details;
QHash<int, qint64> unsorted;
QHash<int, qint64> big;
QHash<int, qint64> middle;
QHash<int, qint64> small;
qreal layoutWidth;
Cases caseType;
bool prepare;
void PrepareGroup();
void PrepareThreeGroups();
void PrepareTwoGroups();
void PrepareDescGroup();
int GetNextThreeGroups() const;
int GetNextTwoGroups() const;
int GetNextDescGroup() const;
void SqMaxMin(qint64 &sMax, qint64 &sMin) const;
};
#endif // VBANK_H

View file

@ -10,11 +10,13 @@ HEADERS += \
$$PWD/vlayoutdetail_p.h \
$$PWD/vlayoutdef.h \
$$PWD/vlayoutpaper.h \
vlayoutpaper_p.h
$$PWD/vlayoutpaper_p.h \
$$PWD/vbank.h
SOURCES += \
$$PWD/stable.cpp \
$$PWD/vlayoutgenerator.cpp \
$$PWD/vlayoutdetail.cpp \
$$PWD/vabstractdetail.cpp \
$$PWD/vlayoutpaper.cpp
$$PWD/vlayoutpaper.cpp \
$$PWD/vbank.cpp

View file

@ -29,6 +29,8 @@
#include "vlayoutdetail.h"
#include "vlayoutdetail_p.h"
#include <QtMath>
//---------------------------------------------------------------------------------------------------------------------
VLayoutDetail::VLayoutDetail()
:VAbstractDetail(), d(new VLayoutDetailData)
@ -56,13 +58,13 @@ VLayoutDetail::~VLayoutDetail()
{}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutDetail::GetContour() const
QVector<QPointF> VLayoutDetail::GetContourPoints() const
{
return d->contour;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutDetail::SetCountour(const QVector<QPointF> &points)
void VLayoutDetail::SetCountourPoints(const QVector<QPointF> &points)
{
d->contour = points;
// Contour can't be closed
@ -90,7 +92,7 @@ void VLayoutDetail::SetSeamAllowencePoints(const QVector<QPointF> &points)
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutDetail::GetLayoutAllowence() const
QVector<QPointF> VLayoutDetail::GetLayoutAllowencePoints() const
{
return Map(d->layoutAllowence);
}
@ -162,7 +164,7 @@ QLineF VLayoutDetail::Edge(int i) const
{ // Doesn't exist such edge
return QLineF();
}
const QVector<QPointF> points = GetLayoutAllowence();
const QVector<QPointF> points = GetLayoutAllowencePoints();
QLineF edge;
if (i < EdgesCount())
{
@ -188,7 +190,7 @@ int VLayoutDetail::EdgeByPoint(const QPointF &p1) const
return 0;
}
const QVector<QPointF> points = GetLayoutAllowence();
const QVector<QPointF> points = GetLayoutAllowencePoints();
for (int i=0; i< points.size(); i++)
{
if (points.at(i) == p1)
@ -202,13 +204,80 @@ int VLayoutDetail::EdgeByPoint(const QPointF &p1) const
//---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutDetail::BoundingRect() const
{
QVector<QPointF> points = GetLayoutAllowence();
QVector<QPointF> points = GetLayoutAllowencePoints();
points.append(points.first());
return QPolygonF(points).boundingRect();
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutDetail::SetLayoutAllowence()
bool VLayoutDetail::isNull() const
{
if (d->contour.isEmpty() == false && d->layoutWidth > 0)
{
if (getSeamAllowance() && d->seamAllowence.isEmpty() == false)
{
return false;
}
else
{
return true;
}
}
else
{
return true;
}
}
//---------------------------------------------------------------------------------------------------------------------
qint64 VLayoutDetail::Square() const
{
if (d->layoutAllowence.isEmpty())
{
return 0;
}
const int n = d->layoutAllowence.count();
qreal s, res = 0;
qint64 sq = 0;
QVector<qreal> x;
QVector<qreal> y;
for(int i=0; i < n; ++i)
{
x.append(d->layoutAllowence.at(i).x());
y.append(d->layoutAllowence.at(i).y());
}
// Calculation a polygon area through the sum of the areas of trapezoids
for (int i = 0; i < n; ++i)
{
if (i == 0)
{
s = x.at(i)*(y.at(n-1) - y.at(i+1)); //if i == 0, then y[i-1] replace on y[n-1]
res += s;
}
else
{
if (i == n-1)
{
s = x.at(i)*(y.at(i-1) - y.at(0)); // if i == n-1, then y[i+1] replace on y[0]
res += s;
}
else
{
s = x.at(i)*(y.at(i-1) - y.at(i+1));
res += s;
}
}
}
sq = qFloor(qAbs(res/2.0));
return sq;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutDetail::SetLayoutAllowencePoints()
{
if (d->layoutWidth > 0)
{

View file

@ -44,14 +44,14 @@ public:
VLayoutDetail &operator=(const VLayoutDetail &detail);
virtual ~VLayoutDetail();
QVector<QPointF> GetContour() const;
void SetCountour(const QVector<QPointF> &points);
QVector<QPointF> GetContourPoints() const;
void SetCountourPoints(const QVector<QPointF> &points);
QVector<QPointF> GetSeamAllowencePoints() const;
void SetSeamAllowencePoints(const QVector<QPointF> &points);
QVector<QPointF> GetLayoutAllowence() const;
void SetLayoutAllowence();
QVector<QPointF> GetLayoutAllowencePoints() const;
void SetLayoutAllowencePoints();
QMatrix GetMatrix() const;
void SetMatrix(const QMatrix &matrix);
@ -69,6 +69,9 @@ public:
QRectF BoundingRect() const;
bool isNull() const;
qint64 Square() const;
private:
QSharedDataPointer<VLayoutDetailData> d;

View file

@ -219,7 +219,7 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail)
workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix
d->details.append(workDetail);
// First detail, just simple take all points
d->globalContour = workDetail.GetLayoutAllowence();
d->globalContour = workDetail.GetLayoutAllowencePoints();
}
return bestResult.ValideResult(); // Do we have the best result?
@ -407,7 +407,7 @@ VLayoutPaper::InsideType VLayoutPaper::InsideContour(const VLayoutDetail &detail
return InsideType::EdgeError;
}
const QVector<QPointF> lPoints = detail.GetLayoutAllowence();
const QVector<QPointF> lPoints = detail.GetLayoutAllowencePoints();
const QLineF detailEdge = detail.Edge(detailI);
if (detailEdge.isNull()) // Got null edge
@ -485,7 +485,7 @@ QVector<QPointF> VLayoutPaper::UniteWithContour(const VLayoutDetail &detail, int
{
if (d->globalContour.isEmpty())
{
return detail.GetLayoutAllowence();
return detail.GetLayoutAllowencePoints();
}
if (globalI <= 0 || globalI > EdgesCount())
@ -505,7 +505,7 @@ QVector<QPointF> VLayoutPaper::UniteWithContour(const VLayoutDetail &detail, int
++i;
if (i==globalI)
{
const QVector<QPointF> dPoints = detail.GetLayoutAllowence();
const QVector<QPointF> dPoints = detail.GetLayoutAllowencePoints();
const int nD = dPoints.count();
int processedPoints = 0;
int j = detJ;