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
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VBestSquare::VBestSquare()
|
||||
: d(new VBestSquareData())
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VBestSquare::VBestSquare(QSizeF sheetSize, bool saveLength, bool isPortrait)
|
||||
: d(new VBestSquareData(sheetSize, saveLength, isPortrait))
|
||||
|
@ -111,7 +116,7 @@ void VBestSquare::NewResult(const VBestSquareResData &data)
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ class VBestSquareData;
|
|||
class VBestSquare
|
||||
{
|
||||
public:
|
||||
VBestSquare();
|
||||
VBestSquare(QSizeF sheetSize, bool saveLength, bool isPortrait);
|
||||
VBestSquare(const VBestSquare &res);
|
||||
virtual ~VBestSquare();
|
||||
|
|
|
@ -42,8 +42,12 @@ QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
|
|||
class VBestSquareData : public QSharedData
|
||||
{
|
||||
public:
|
||||
VBestSquareData()
|
||||
{}
|
||||
|
||||
VBestSquareData(const QSizeF &sheetSize, bool saveLength, bool isPortrait)
|
||||
: sheetSize(sheetSize),
|
||||
: isValid(true),
|
||||
sheetSize(sheetSize),
|
||||
saveLength(saveLength),
|
||||
isPortrait(isPortrait)
|
||||
{
|
||||
|
@ -52,6 +56,7 @@ public:
|
|||
|
||||
VBestSquareData(const VBestSquareData &res)
|
||||
: QSharedData(res),
|
||||
isValid(res.isValid),
|
||||
sheetSize(res.sheetSize),
|
||||
valideResult(res.valideResult),
|
||||
saveLength(res.saveLength),
|
||||
|
@ -63,9 +68,10 @@ public:
|
|||
|
||||
~VBestSquareData() {}
|
||||
|
||||
QSizeF sheetSize;
|
||||
bool isValid{false};
|
||||
QSizeF sheetSize{};
|
||||
bool valideResult{false};
|
||||
bool saveLength;
|
||||
bool saveLength{false};
|
||||
VBestSquareResData data{};
|
||||
bool isPortrait{true};
|
||||
bool terminatedByException{false};
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "vposition.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QtConcurrent>
|
||||
#include <QFutureWatcher>
|
||||
#include <QImage>
|
||||
#include <QLineF>
|
||||
#include <QPainter>
|
||||
|
@ -58,9 +60,13 @@
|
|||
#include <QScopeGuard>
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPosition::VPosition()
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
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_data(data),
|
||||
stop(stop),
|
||||
|
@ -75,6 +81,11 @@ VPosition::VPosition(const VPositionData &data, std::atomic_bool *stop, bool sav
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPosition::run()
|
||||
{
|
||||
if (not m_isValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (stop->load())
|
||||
{
|
||||
return;
|
||||
|
@ -82,7 +93,21 @@ void VPosition::run()
|
|||
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -125,33 +150,33 @@ VBestSquare VPosition::ArrangeDetail(const VPositionData &data, std::atomic_bool
|
|||
return bestResult;//Not enough edges
|
||||
}
|
||||
|
||||
QScopedPointer<QThreadPool> thread_pool(new QThreadPool());
|
||||
QVector<VPosition *> threads;
|
||||
|
||||
auto Cleanup = qScopeGuard([&threads]
|
||||
{
|
||||
Q_ASSERT(not threads.isEmpty());
|
||||
qDeleteAll(threads.begin(), threads.end());
|
||||
});
|
||||
QFutureWatcher<VBestSquare> watcher;
|
||||
QVector<VPosition> jobs;
|
||||
jobs.reserve(data.gContour.GlobalEdgesCount());
|
||||
|
||||
for (int j=1; j <= data.gContour.GlobalEdgesCount(); ++j)
|
||||
{
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
for (int i=1; i<= detailEdgesCount; ++i)
|
||||
{
|
||||
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);
|
||||
}
|
||||
jobs.append(VPosition(linkedData, stop, saveLength));
|
||||
}
|
||||
|
||||
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
|
||||
do
|
||||
|
@ -159,16 +184,24 @@ VBestSquare VPosition::ArrangeDetail(const VPositionData &data, std::atomic_bool
|
|||
QCoreApplication::processEvents();
|
||||
QThread::msleep(250);
|
||||
}
|
||||
while(thread_pool->activeThreadCount() > 0 && not stop->load());
|
||||
while(watcher.isRunning() && not stop->load());
|
||||
|
||||
if (stop->load())
|
||||
{
|
||||
do
|
||||
{
|
||||
QCoreApplication::processEvents();
|
||||
QThread::msleep(250);
|
||||
}
|
||||
while(watcher.isRunning());
|
||||
|
||||
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;
|
||||
|
@ -427,6 +460,11 @@ void VPosition::FollowGrainline()
|
|||
detailGrainline = workDetail.GetMatrix().map(detailGrainline);
|
||||
}
|
||||
|
||||
if (stop->load())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const qreal angle = detailGrainline.angleTo(FabricGrainline());
|
||||
|
||||
if (m_data.detail.GrainlineArrowType() == ArrowType::atBoth ||
|
||||
|
@ -435,6 +473,11 @@ void VPosition::FollowGrainline()
|
|||
RotateOnAngle(angle);
|
||||
}
|
||||
|
||||
if (stop->load())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_data.detail.GrainlineArrowType() == ArrowType::atBoth ||
|
||||
m_data.detail.GrainlineArrowType() == ArrowType::atRear)
|
||||
{
|
||||
|
@ -456,6 +499,11 @@ void VPosition::FindBestPosition()
|
|||
SaveCandidate(m_bestResult, workDetail, m_data.j, dEdge, BestFrom::Combine);
|
||||
}
|
||||
|
||||
if (stop->load())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_data.rotate)
|
||||
{
|
||||
Rotate(m_data.rotationNumber);
|
||||
|
|
|
@ -53,27 +53,28 @@ struct VPositionData
|
|||
bool isOriginPaperOrientationPortrait{true};
|
||||
};
|
||||
|
||||
class VPosition : public QRunnable
|
||||
class VPosition
|
||||
{
|
||||
public:
|
||||
VPosition();
|
||||
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;
|
||||
|
||||
static VBestSquare ArrangeDetail(const VPositionData &data, std::atomic_bool *stop, bool saveLength);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(VPosition)
|
||||
VBestSquare m_bestResult;
|
||||
VPositionData m_data;
|
||||
std::atomic_bool *stop;
|
||||
bool m_isValid{false};
|
||||
VBestSquare m_bestResult{};
|
||||
VPositionData m_data{};
|
||||
std::atomic_bool *stop{nullptr};
|
||||
/**
|
||||
* @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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user