2015-01-10 14:47:46 +01:00
|
|
|
/************************************************************************
|
|
|
|
**
|
|
|
|
** @file vlayoutpaper.cpp
|
|
|
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
|
|
|
** @date 7 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 "vlayoutpaper.h"
|
|
|
|
#include "vlayoutpaper_p.h"
|
2015-01-21 19:56:59 +01:00
|
|
|
#include "vbestsquare.h"
|
2015-01-21 22:49:38 +01:00
|
|
|
#include "vposition.h"
|
2015-01-10 14:47:46 +01:00
|
|
|
|
|
|
|
#include <climits>
|
|
|
|
#include <QPointF>
|
2015-01-12 16:23:25 +01:00
|
|
|
#include <QtMath>
|
2015-01-12 21:35:32 +01:00
|
|
|
#include <QImage>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QPainter>
|
2015-01-13 11:38:51 +01:00
|
|
|
#include <QGraphicsItem>
|
2015-01-16 13:54:37 +01:00
|
|
|
#include <QCoreApplication>
|
2015-01-21 22:49:38 +01:00
|
|
|
#include <QThreadPool>
|
2015-01-10 14:47:46 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VLayoutPaper::VLayoutPaper()
|
|
|
|
:d(new VLayoutPaperData)
|
|
|
|
{}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VLayoutPaper::VLayoutPaper(int height, int width)
|
|
|
|
:d(new VLayoutPaperData(height, width))
|
|
|
|
{}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VLayoutPaper::VLayoutPaper(const VLayoutPaper &paper)
|
|
|
|
:d (paper.d)
|
|
|
|
{}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VLayoutPaper &VLayoutPaper::operator=(const VLayoutPaper &paper)
|
|
|
|
{
|
|
|
|
if ( &paper == this )
|
|
|
|
{
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
d = paper.d;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VLayoutPaper::~VLayoutPaper()
|
|
|
|
{}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
int VLayoutPaper::GetHeight() const
|
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
return d->globalContour.GetHeight();
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VLayoutPaper::SetHeight(int height)
|
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
d->globalContour.SetHeight(height);
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
int VLayoutPaper::GetWidth() const
|
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
return d->globalContour.GetWidth();
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VLayoutPaper::SetWidth(int width)
|
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
d->globalContour.SetWidth(width);
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
|
|
|
|
2015-01-17 15:00:46 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
qreal VLayoutPaper::GetLayoutWidth() const
|
|
|
|
{
|
|
|
|
return d->layoutWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VLayoutPaper::SetLayoutWidth(qreal width)
|
|
|
|
{
|
|
|
|
if (width >= 0)
|
|
|
|
{
|
|
|
|
d->layoutWidth = width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-12 16:23:25 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
unsigned int VLayoutPaper::GetShift() const
|
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
return d->globalContour.GetShift();
|
2015-01-12 16:23:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VLayoutPaper::SetShift(unsigned int shift)
|
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
d->globalContour.SetShift(shift);
|
2015-01-12 16:23:25 +01:00
|
|
|
}
|
|
|
|
|
2015-01-12 21:35:32 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VLayoutPaper::SetPaperIndex(quint32 index)
|
|
|
|
{
|
|
|
|
d->paperIndex = index;
|
|
|
|
}
|
|
|
|
|
2015-01-10 14:47:46 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2015-01-16 15:45:56 +01:00
|
|
|
bool VLayoutPaper::ArrangeDetail(const VLayoutDetail &detail, bool &stop)
|
2015-01-10 14:47:46 +01:00
|
|
|
{
|
|
|
|
// First need set size of paper
|
2015-01-21 19:56:59 +01:00
|
|
|
if (d->globalContour.GetHeight() <= 0 || d->globalContour.GetWidth() <= 0)
|
2015-01-10 14:47:46 +01:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (detail.EdgesCount() < 3)
|
|
|
|
{
|
|
|
|
return false;//Not enough edges
|
|
|
|
}
|
|
|
|
|
2015-01-12 21:35:32 +01:00
|
|
|
d->frame = 0;
|
|
|
|
|
2015-01-21 15:33:06 +01:00
|
|
|
return AddToSheet(detail, stop);
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
int VLayoutPaper::Count() const
|
|
|
|
{
|
|
|
|
return d->details.count();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2015-01-16 15:45:56 +01:00
|
|
|
bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail, bool &stop)
|
2015-01-10 14:47:46 +01:00
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
VBestSquare bestResult;
|
2015-01-21 22:49:38 +01:00
|
|
|
QThreadPool *thread_pool = QThreadPool::globalInstance();
|
|
|
|
QVector<VPosition *> threads;
|
2015-01-10 14:47:46 +01:00
|
|
|
|
2015-01-21 19:56:59 +01:00
|
|
|
for (int j=1; j <= d->globalContour.EdgesCount(); ++j)
|
2015-01-10 14:47:46 +01:00
|
|
|
{
|
2015-01-20 21:58:30 +01:00
|
|
|
for (int i=1; i<= detail.EdgesCount(); i++)
|
2015-01-10 14:47:46 +01:00
|
|
|
{
|
2015-01-21 22:49:38 +01:00
|
|
|
VPosition *thread = new VPosition(d->globalContour, j, detail, i);
|
|
|
|
//Info for debug
|
|
|
|
thread->setPaperIndex(d->paperIndex);
|
|
|
|
thread->setFrame(d->frame);
|
|
|
|
thread->setDetailsCount(d->details.count());
|
|
|
|
thread->setDetails(d->details);
|
|
|
|
|
|
|
|
thread->setAutoDelete(false);
|
|
|
|
threads.append(thread);
|
|
|
|
thread_pool->start(thread);
|
|
|
|
|
2015-01-22 12:26:09 +01:00
|
|
|
d->frame = d->frame + 3 + 360/180*2;
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-21 22:49:38 +01:00
|
|
|
if (thread_pool->waitForDone() == false)
|
2015-01-19 11:36:27 +01:00
|
|
|
{
|
2015-01-21 22:49:38 +01:00
|
|
|
return false;
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
|
|
|
|
2015-01-21 22:49:38 +01:00
|
|
|
QCoreApplication::processEvents();
|
2015-01-10 14:47:46 +01:00
|
|
|
|
2015-01-21 22:49:38 +01:00
|
|
|
if (stop)
|
2015-01-10 14:47:46 +01:00
|
|
|
{
|
2015-01-21 22:49:38 +01:00
|
|
|
return false;
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
|
|
|
|
2015-01-21 22:49:38 +01:00
|
|
|
for (int i=0; i < threads.size(); ++i)
|
2015-01-10 14:47:46 +01:00
|
|
|
{
|
2015-01-21 22:49:38 +01:00
|
|
|
bestResult.NewResult(threads.at(i)->getBestResult());
|
2015-01-10 14:47:46 +01:00
|
|
|
}
|
2015-01-18 19:56:01 +01:00
|
|
|
|
2015-01-21 22:49:38 +01:00
|
|
|
qDeleteAll(threads.begin(), threads.end());
|
|
|
|
threads.clear();
|
2015-01-18 19:56:01 +01:00
|
|
|
|
2015-01-21 22:49:38 +01:00
|
|
|
return SaveResult(bestResult, detail);
|
2015-01-12 16:59:15 +01:00
|
|
|
}
|
|
|
|
|
2015-01-10 14:47:46 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2015-01-21 19:56:59 +01:00
|
|
|
bool VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutDetail &detail)
|
2015-01-12 16:23:25 +01:00
|
|
|
{
|
|
|
|
if (bestResult.ValideResult())
|
|
|
|
{
|
|
|
|
VLayoutDetail workDetail = detail;
|
|
|
|
workDetail.SetMatrix(bestResult.Matrix());// Don't forget set matrix
|
2015-01-18 19:56:01 +01:00
|
|
|
workDetail.SetMirror(bestResult.Mirror());
|
2015-01-21 19:56:59 +01:00
|
|
|
const QVector<QPointF> newGContour = d->globalContour.UniteWithContour(workDetail, bestResult.GContourEdge(),
|
|
|
|
bestResult.DetailEdge(),
|
|
|
|
bestResult.Type());
|
2015-01-12 16:23:25 +01:00
|
|
|
if (newGContour.isEmpty())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
d->details.append(workDetail);
|
2015-01-21 19:56:59 +01:00
|
|
|
d->globalContour.SetContour(newGContour);
|
2015-01-18 19:56:01 +01:00
|
|
|
|
|
|
|
#ifdef LAYOUT_DEBUG
|
|
|
|
# ifdef SHOW_BEST
|
2015-01-21 22:49:38 +01:00
|
|
|
VPosition::DrawDebug(d->globalContour, workDetail, UINT_MAX, d->paperIndex, d->details.count(), d->details);
|
2015-01-18 19:56:01 +01:00
|
|
|
# endif
|
|
|
|
#endif
|
2015-01-12 16:23:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return bestResult.ValideResult(); // Do we have the best result?
|
|
|
|
}
|
2015-01-12 21:35:32 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2015-01-21 19:56:59 +01:00
|
|
|
void VLayoutPaper::SaveCandidate(VBestSquare &bestResult, const VLayoutDetail &detail, int globalI, int detJ,
|
|
|
|
BestFrom type)
|
2015-01-12 21:35:32 +01:00
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
QVector<QPointF> newGContour = d->globalContour.UniteWithContour(detail, globalI, detJ, type);
|
|
|
|
newGContour.append(newGContour.first());
|
|
|
|
const QRectF rec = QPolygonF(newGContour).boundingRect();
|
|
|
|
bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), globalI, detJ,
|
|
|
|
detail.GetMatrix(), detail.IsMirror(), type);
|
|
|
|
}
|
|
|
|
|
2015-01-13 11:38:51 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QGraphicsItem *VLayoutPaper::GetItem() const
|
|
|
|
{
|
2015-01-21 19:56:59 +01:00
|
|
|
QGraphicsRectItem *paper = new QGraphicsRectItem(QRectF(0, 0, d->globalContour.GetWidth(),
|
|
|
|
d->globalContour.GetHeight()));
|
2015-01-13 11:38:51 +01:00
|
|
|
paper->setPen(QPen(Qt::black, 1));
|
|
|
|
paper->setBrush(QBrush(Qt::white));
|
|
|
|
for (int i=0; i < d->details.count(); ++i)
|
|
|
|
{
|
|
|
|
QGraphicsItem *item = d->details.at(i).GetItem();
|
|
|
|
item->setParentItem(paper);
|
|
|
|
}
|
|
|
|
return paper;
|
|
|
|
}
|