Use QtConcurrent::mapped to run nesting. This will allow to use QFutureWatcher
and create a barier to wait when all jobs finish. Reduced number of jobs. All piece edges checked in one thread. --HG-- branch : develop
This commit is contained in:
parent
ab6413fb36
commit
d930e94c42
|
@ -41,6 +41,11 @@ Q_DECL_CONSTEXPR inline qint64 Square(QSizeF size)
|
||||||
}
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VBestSquare::VBestSquare()
|
||||||
|
: d(new VBestSquareData())
|
||||||
|
{}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
VBestSquare::VBestSquare(QSizeF sheetSize, bool saveLength, bool isPortrait)
|
VBestSquare::VBestSquare(QSizeF sheetSize, bool saveLength, bool isPortrait)
|
||||||
: d(new VBestSquareData(sheetSize, saveLength, isPortrait))
|
: d(new VBestSquareData(sheetSize, saveLength, isPortrait))
|
||||||
|
@ -111,7 +116,7 @@ void VBestSquare::NewResult(const VBestSquareResData &data)
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VBestSquare::NewResult(const VBestSquare &best)
|
void VBestSquare::NewResult(const VBestSquare &best)
|
||||||
{
|
{
|
||||||
if (best.HasValidResult() && d->saveLength == best.IsSaveLength())
|
if (best.d->isValid && best.HasValidResult() && d->saveLength == best.IsSaveLength())
|
||||||
{
|
{
|
||||||
NewResult(best.BestResultData());
|
NewResult(best.BestResultData());
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ class VBestSquareData;
|
||||||
class VBestSquare
|
class VBestSquare
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
VBestSquare();
|
||||||
VBestSquare(QSizeF sheetSize, bool saveLength, bool isPortrait);
|
VBestSquare(QSizeF sheetSize, bool saveLength, bool isPortrait);
|
||||||
VBestSquare(const VBestSquare &res);
|
VBestSquare(const VBestSquare &res);
|
||||||
virtual ~VBestSquare();
|
virtual ~VBestSquare();
|
||||||
|
|
|
@ -42,8 +42,12 @@ QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
|
||||||
class VBestSquareData : public QSharedData
|
class VBestSquareData : public QSharedData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
VBestSquareData()
|
||||||
|
{}
|
||||||
|
|
||||||
VBestSquareData(const QSizeF &sheetSize, bool saveLength, bool isPortrait)
|
VBestSquareData(const QSizeF &sheetSize, bool saveLength, bool isPortrait)
|
||||||
: sheetSize(sheetSize),
|
: isValid(true),
|
||||||
|
sheetSize(sheetSize),
|
||||||
saveLength(saveLength),
|
saveLength(saveLength),
|
||||||
isPortrait(isPortrait)
|
isPortrait(isPortrait)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +56,7 @@ public:
|
||||||
|
|
||||||
VBestSquareData(const VBestSquareData &res)
|
VBestSquareData(const VBestSquareData &res)
|
||||||
: QSharedData(res),
|
: QSharedData(res),
|
||||||
|
isValid(res.isValid),
|
||||||
sheetSize(res.sheetSize),
|
sheetSize(res.sheetSize),
|
||||||
valideResult(res.valideResult),
|
valideResult(res.valideResult),
|
||||||
saveLength(res.saveLength),
|
saveLength(res.saveLength),
|
||||||
|
@ -63,9 +68,10 @@ public:
|
||||||
|
|
||||||
~VBestSquareData() {}
|
~VBestSquareData() {}
|
||||||
|
|
||||||
QSizeF sheetSize;
|
bool isValid{false};
|
||||||
|
QSizeF sheetSize{};
|
||||||
bool valideResult{false};
|
bool valideResult{false};
|
||||||
bool saveLength;
|
bool saveLength{false};
|
||||||
VBestSquareResData data{};
|
VBestSquareResData data{};
|
||||||
bool isPortrait{true};
|
bool isPortrait{true};
|
||||||
bool terminatedByException{false};
|
bool terminatedByException{false};
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "vposition.h"
|
#include "vposition.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QtConcurrent>
|
||||||
|
#include <QFutureWatcher>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QLineF>
|
#include <QLineF>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
@ -58,9 +60,13 @@
|
||||||
#include <QScopeGuard>
|
#include <QScopeGuard>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VPosition::VPosition()
|
||||||
|
{}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
VPosition::VPosition(const VPositionData &data, std::atomic_bool *stop, bool saveLength)
|
VPosition::VPosition(const VPositionData &data, std::atomic_bool *stop, bool saveLength)
|
||||||
: QRunnable(),
|
: m_isValid(true),
|
||||||
m_bestResult(VBestSquare(data.gContour.GetSize(), saveLength, data.isOriginPaperOrientationPortrait)),
|
m_bestResult(VBestSquare(data.gContour.GetSize(), saveLength, data.isOriginPaperOrientationPortrait)),
|
||||||
m_data(data),
|
m_data(data),
|
||||||
stop(stop),
|
stop(stop),
|
||||||
|
@ -75,6 +81,11 @@ VPosition::VPosition(const VPositionData &data, std::atomic_bool *stop, bool sav
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VPosition::run()
|
void VPosition::run()
|
||||||
{
|
{
|
||||||
|
if (not m_isValid)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (stop->load())
|
if (stop->load())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -82,7 +93,21 @@ void VPosition::run()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FindBestPosition();
|
for (int i=1; i<= m_data.detail.LayoutEdgesCount(); ++i)
|
||||||
|
{
|
||||||
|
if (stop->load())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_data.i = i;
|
||||||
|
FindBestPosition();
|
||||||
|
|
||||||
|
if (stop->load())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const VException &e)
|
catch (const VException &e)
|
||||||
{
|
{
|
||||||
|
@ -125,33 +150,33 @@ VBestSquare VPosition::ArrangeDetail(const VPositionData &data, std::atomic_bool
|
||||||
return bestResult;//Not enough edges
|
return bestResult;//Not enough edges
|
||||||
}
|
}
|
||||||
|
|
||||||
QScopedPointer<QThreadPool> thread_pool(new QThreadPool());
|
QFutureWatcher<VBestSquare> watcher;
|
||||||
QVector<VPosition *> threads;
|
QVector<VPosition> jobs;
|
||||||
|
jobs.reserve(data.gContour.GlobalEdgesCount());
|
||||||
auto Cleanup = qScopeGuard([&threads]
|
|
||||||
{
|
|
||||||
Q_ASSERT(not threads.isEmpty());
|
|
||||||
qDeleteAll(threads.begin(), threads.end());
|
|
||||||
});
|
|
||||||
|
|
||||||
for (int j=1; j <= data.gContour.GlobalEdgesCount(); ++j)
|
for (int j=1; j <= data.gContour.GlobalEdgesCount(); ++j)
|
||||||
{
|
{
|
||||||
QCoreApplication::processEvents();
|
VPositionData linkedData = data;
|
||||||
|
linkedData.j = j;
|
||||||
|
|
||||||
for (int i=1; i<= detailEdgesCount; ++i)
|
jobs.append(VPosition(linkedData, stop, saveLength));
|
||||||
{
|
|
||||||
VPositionData linkedData = data;
|
|
||||||
linkedData.i = i;
|
|
||||||
linkedData.j = j;
|
|
||||||
|
|
||||||
auto *thread = new VPosition(linkedData, stop, saveLength);
|
|
||||||
thread->setAutoDelete(false);
|
|
||||||
threads.append(thread);
|
|
||||||
thread_pool->start(thread);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(not threads.isEmpty());
|
Q_ASSERT(not jobs.isEmpty());
|
||||||
|
|
||||||
|
std::function<VBestSquare (VPosition position)> Nest = [](VPosition position)
|
||||||
|
{
|
||||||
|
position.run();
|
||||||
|
return position.getBestResult();
|
||||||
|
};
|
||||||
|
|
||||||
|
watcher.setFuture(QtConcurrent::mapped(jobs, Nest));
|
||||||
|
|
||||||
|
while(not watcher.isStarted())
|
||||||
|
{
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QThread::msleep(250);
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for done
|
// Wait for done
|
||||||
do
|
do
|
||||||
|
@ -159,16 +184,24 @@ VBestSquare VPosition::ArrangeDetail(const VPositionData &data, std::atomic_bool
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
QThread::msleep(250);
|
QThread::msleep(250);
|
||||||
}
|
}
|
||||||
while(thread_pool->activeThreadCount() > 0 && not stop->load());
|
while(watcher.isRunning() && not stop->load());
|
||||||
|
|
||||||
if (stop->load())
|
if (stop->load())
|
||||||
{
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
QThread::msleep(250);
|
||||||
|
}
|
||||||
|
while(watcher.isRunning());
|
||||||
|
|
||||||
return bestResult;
|
return bestResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &thread : threads)
|
QList<VBestSquare> results = watcher.future().results();
|
||||||
|
for (auto &result : results)
|
||||||
{
|
{
|
||||||
bestResult.NewResult(thread->getBestResult());
|
bestResult.NewResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestResult;
|
return bestResult;
|
||||||
|
@ -427,6 +460,11 @@ void VPosition::FollowGrainline()
|
||||||
detailGrainline = workDetail.GetMatrix().map(detailGrainline);
|
detailGrainline = workDetail.GetMatrix().map(detailGrainline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stop->load())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const qreal angle = detailGrainline.angleTo(FabricGrainline());
|
const qreal angle = detailGrainline.angleTo(FabricGrainline());
|
||||||
|
|
||||||
if (m_data.detail.GrainlineArrowType() == ArrowType::atBoth ||
|
if (m_data.detail.GrainlineArrowType() == ArrowType::atBoth ||
|
||||||
|
@ -435,6 +473,11 @@ void VPosition::FollowGrainline()
|
||||||
RotateOnAngle(angle);
|
RotateOnAngle(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stop->load())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_data.detail.GrainlineArrowType() == ArrowType::atBoth ||
|
if (m_data.detail.GrainlineArrowType() == ArrowType::atBoth ||
|
||||||
m_data.detail.GrainlineArrowType() == ArrowType::atRear)
|
m_data.detail.GrainlineArrowType() == ArrowType::atRear)
|
||||||
{
|
{
|
||||||
|
@ -456,6 +499,11 @@ void VPosition::FindBestPosition()
|
||||||
SaveCandidate(m_bestResult, workDetail, m_data.j, dEdge, BestFrom::Combine);
|
SaveCandidate(m_bestResult, workDetail, m_data.j, dEdge, BestFrom::Combine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stop->load())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_data.rotate)
|
if (m_data.rotate)
|
||||||
{
|
{
|
||||||
Rotate(m_data.rotationNumber);
|
Rotate(m_data.rotationNumber);
|
||||||
|
|
|
@ -53,27 +53,28 @@ struct VPositionData
|
||||||
bool isOriginPaperOrientationPortrait{true};
|
bool isOriginPaperOrientationPortrait{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
class VPosition : public QRunnable
|
class VPosition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
VPosition();
|
||||||
VPosition(const VPositionData &data, std::atomic_bool *stop, bool saveLength);
|
VPosition(const VPositionData &data, std::atomic_bool *stop, bool saveLength);
|
||||||
virtual ~VPosition() override = default;
|
virtual ~VPosition()= default;
|
||||||
|
|
||||||
virtual void run() override;
|
virtual void run();
|
||||||
|
|
||||||
VBestSquare getBestResult() const;
|
VBestSquare getBestResult() const;
|
||||||
|
|
||||||
static VBestSquare ArrangeDetail(const VPositionData &data, std::atomic_bool *stop, bool saveLength);
|
static VBestSquare ArrangeDetail(const VPositionData &data, std::atomic_bool *stop, bool saveLength);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(VPosition)
|
bool m_isValid{false};
|
||||||
VBestSquare m_bestResult;
|
VBestSquare m_bestResult{};
|
||||||
VPositionData m_data;
|
VPositionData m_data{};
|
||||||
std::atomic_bool *stop;
|
std::atomic_bool *stop{nullptr};
|
||||||
/**
|
/**
|
||||||
* @brief angle_between keep angle between global edge and detail edge. Need for optimization rotation.
|
* @brief angle_between keep angle between global edge and detail edge. Need for optimization rotation.
|
||||||
*/
|
*/
|
||||||
qreal angle_between;
|
qreal angle_between{0};
|
||||||
|
|
||||||
enum class CrossingType : char
|
enum class CrossingType : char
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user