From 81cda14c0698edf5aa0f0bd748ea23a6bb93299e Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 26 Mar 2019 18:54:59 +0200 Subject: [PATCH] Refactoring. Pass position data as struct. --HG-- branch : develop --- src/libs/vlayout/vlayoutpaper.cpp | 26 ++--- src/libs/vlayout/vposition.cpp | 151 ++++++++++++++++-------------- src/libs/vlayout/vposition.h | 39 +++++--- 3 files changed, 122 insertions(+), 94 deletions(-) diff --git a/src/libs/vlayout/vlayoutpaper.cpp b/src/libs/vlayout/vlayoutpaper.cpp index e88ba6e5b..fcef8b617 100644 --- a/src/libs/vlayout/vlayoutpaper.cpp +++ b/src/libs/vlayout/vlayoutpaper.cpp @@ -238,23 +238,23 @@ bool VLayoutPaper::AddToSheet(const VLayoutPiece &detail, std::atomic_bool &stop thread_pool->setExpiryTimeout(1000); QVector threads; - int detailEdgesCount = 0; - - if (d->globalContour.GetContour().isEmpty()) - { - detailEdgesCount = detail.DetailEdgesCount(); - } - else - { - detailEdgesCount = detail.LayoutEdgesCount(); - } + int detailEdgesCount = d->globalContour.GetContour().isEmpty() ? detail.DetailEdgesCount() : + detail.LayoutEdgesCount(); for (int j=1; j <= d->globalContour.GlobalEdgesCount(); ++j) { for (int i=1; i<= detailEdgesCount; ++i) { - auto *thread = new VPosition(d->globalContour, j, detail, i, &stop, d->localRotate, - d->localRotationIncrease, d->saveLength, d->followGrainline); + VPositionData data; + data.gContour = d->globalContour; + data.detail = detail; + data.i = i; + data.j = j; + data.rotate = d->localRotate; + data.rotationIncrease = d->localRotationIncrease; + data.followGrainline = d->followGrainline; + + auto *thread = new VPosition(data, &stop, d->saveLength); //Info for debug #ifdef LAYOUT_DEBUG thread->setPaperIndex(d->paperIndex); @@ -267,7 +267,9 @@ bool VLayoutPaper::AddToSheet(const VLayoutPiece &detail, std::atomic_bool &stop threads.append(thread); thread_pool->start(thread); +#ifdef LAYOUT_DEBUG d->frame = d->frame + 3 + static_cast(360/d->localRotationIncrease*2); +#endif } } diff --git a/src/libs/vlayout/vposition.cpp b/src/libs/vlayout/vposition.cpp index c1c9394c5..9ca07f055 100644 --- a/src/libs/vlayout/vposition.cpp +++ b/src/libs/vlayout/vposition.cpp @@ -81,6 +81,7 @@ QPainterPath ShowDirection(const QLineF &edge) } #endif +#ifdef LAYOUT_DEBUG //--------------------------------------------------------------------------------------------------------------------- QPainterPath DrawContour(const QVector &points) { @@ -111,6 +112,7 @@ QPainterPath DrawContour(const QVector &points) } return path; } +#endif //--------------------------------------------------------------------------------------------------------------------- #ifdef ARRANGED_DETAILS @@ -132,27 +134,22 @@ QPainterPath DrawDetails(const QVector &details) } //anonymous namespace //--------------------------------------------------------------------------------------------------------------------- -VPosition::VPosition(const VContour &gContour, int j, const VLayoutPiece &detail, int i, std::atomic_bool *stop, - bool rotate, int rotationIncrease, bool saveLength, bool followGainline) +VPosition::VPosition(const VPositionData &data, std::atomic_bool *stop, bool saveLength) : QRunnable(), - bestResult(VBestSquare(gContour.GetSize(), saveLength)), - gContour(gContour), - detail(detail), - i(i), - j(j), + m_bestResult(VBestSquare(data.gContour.GetSize(), saveLength)), + m_data(data), +#ifdef LAYOUT_DEBUG paperIndex(0), frame(0), detailsCount(0), details(), +#endif stop(stop), - rotate(rotate), - rotationIncrease(rotationIncrease), - angle_between(0), - followGrainline(followGainline) + angle_between(0) { - if (not (rotationIncrease >= 1 && rotationIncrease <= 180 && 360 % rotationIncrease == 0)) + if (not (m_data.rotationIncrease >= 1 && m_data.rotationIncrease <= 180 && 360 % m_data.rotationIncrease == 0)) { - this->rotationIncrease = 180; + m_data.rotationIncrease = 180; } } @@ -164,42 +161,10 @@ void VPosition::run() return; } - if (not followGrainline || not detail.IsGrainlineEnabled()) - { - // We should use copy of the detail. - VLayoutPiece workDetail = detail; - - int dEdge = i;// For mirror detail edge will be different - if (CheckCombineEdges(workDetail, j, dEdge)) - { - #ifdef LAYOUT_DEBUG - # ifdef SHOW_CANDIDATE_BEST - DrawDebug(gContour, workDetail, frame+2, paperIndex, detailsCount, details); - # endif - #endif - - SaveCandidate(bestResult, workDetail, j, dEdge, BestFrom::Combine); - } - frame = frame + 3; - - if (rotate) - { - Rotate(rotationIncrease); - } - else - { - if (gContour.GetContour().isEmpty()) - { - Rotate(rotationIncrease); - } - } - } - else - { - FollowGrainline(); - } + FindBestPosition(); } +#ifdef LAYOUT_DEBUG //--------------------------------------------------------------------------------------------------------------------- // cppcheck-suppress unusedFunction quint32 VPosition::getPaperIndex() const @@ -244,13 +209,15 @@ void VPosition::setDetails(const QVector &details) { this->details = details; } +#endif //--------------------------------------------------------------------------------------------------------------------- VBestSquare VPosition::getBestResult() const { - return bestResult; + return m_bestResult; } +#ifdef LAYOUT_DEBUG //--------------------------------------------------------------------------------------------------------------------- void VPosition::DrawDebug(const VContour &contour, const VLayoutPiece &detail, int frame, quint32 paperIndex, int detailsCount, const QVector &details) @@ -334,16 +301,17 @@ int VPosition::Bias(int length, int maxLength) { return length < maxLength && length*2 < maxLength ? length : maxLength-length; } +#endif //--------------------------------------------------------------------------------------------------------------------- void VPosition::SaveCandidate(VBestSquare &bestResult, const VLayoutPiece &detail, int globalI, int detJ, BestFrom type) { - QVector newGContour = gContour.UniteWithContour(detail, globalI, detJ, type); + QVector newGContour = m_data.gContour.UniteWithContour(detail, globalI, detJ, type); newGContour.append(newGContour.first()); const QSizeF size = QPolygonF(newGContour).boundingRect().size(); - const bool isPortrait = gContour.GetSize().height() >= gContour.GetSize().width(); + const bool isPortrait = m_data.gContour.GetSize().height() >= m_data.gContour.GetSize().width(); const qreal position = isPortrait ? detail.DetailBoundingRect().y() : detail.DetailBoundingRect().x(); bestResult.NewResult(size, globalI, detJ, detail.GetMatrix(), detail.IsMirror(), position, type); @@ -352,7 +320,7 @@ void VPosition::SaveCandidate(VBestSquare &bestResult, const VLayoutPiece &detai //--------------------------------------------------------------------------------------------------------------------- bool VPosition::CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge) { - const QLineF globalEdge = gContour.GlobalEdge(j); + const QLineF globalEdge = m_data.gContour.GlobalEdge(j); bool flagMirror = false; bool flagSquare = false; @@ -367,7 +335,7 @@ bool VPosition::CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge) CrossingType type = CrossingType::Intersection; if (not detail.IsForceFlipping() && SheetContains(detail.DetailBoundingRect())) { - if (not gContour.GetContour().isEmpty()) + if (not m_data.gContour.GetContour().isEmpty()) { type = Crossing(detail); } @@ -400,7 +368,7 @@ bool VPosition::CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge) #endif #endif - if (gContour.GetContour().isEmpty()) + if (m_data.gContour.GetContour().isEmpty()) { dEdge = detail.DetailEdgeByPoint(globalEdge.p2()); } @@ -440,12 +408,12 @@ bool VPosition::CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge) //--------------------------------------------------------------------------------------------------------------------- bool VPosition::CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, qreal angle) const { - const QLineF globalEdge = gContour.GlobalEdge(j); + const QLineF globalEdge = m_data.gContour.GlobalEdge(j); bool flagSquare = false; if (detail.IsForceFlipping()) { - detail.Mirror(not followGrainline ? globalEdge : QLineF(10, 10, 10, 100)); + detail.Mirror(not m_data.followGrainline ? globalEdge : QLineF(10, 10, 10, 100)); } RotateEdges(detail, globalEdge, dEdge, angle); @@ -482,9 +450,9 @@ bool VPosition::CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, qreal void VPosition::RotateOnAngle(qreal angle) { // We should use copy of the detail. - VLayoutPiece workDetail = detail; + VLayoutPiece workDetail = m_data.detail; - if (CheckRotationEdges(workDetail, j, i, angle)) + if (CheckRotationEdges(workDetail, m_data.j, m_data.i, angle)) { #ifdef LAYOUT_DEBUG # ifdef SHOW_CANDIDATE_BEST @@ -493,22 +461,24 @@ void VPosition::RotateOnAngle(qreal angle) # endif #endif - SaveCandidate(bestResult, workDetail, j, i, BestFrom::Rotation); + SaveCandidate(m_bestResult, workDetail, m_data.j, m_data.i, BestFrom::Rotation); } +#ifdef LAYOUT_DEBUG ++frame; +#endif } //--------------------------------------------------------------------------------------------------------------------- VPosition::CrossingType VPosition::Crossing(const VLayoutPiece &detail) const { - const QRectF gRect = gContour.BoundingRect(); + const QRectF gRect = m_data.gContour.BoundingRect(); if (not gRect.intersects(detail.LayoutBoundingRect()) && not gRect.contains(detail.DetailBoundingRect())) { // This we can determine efficiently. return CrossingType::NoIntersection; } - const QPainterPath gPath = gContour.ContourPath(); + const QPainterPath gPath = m_data.gContour.ContourPath(); CrossingType crossing = CrossingType::EdgeError; if (not gPath.intersects(detail.LayoutAllowancePath()) && not gPath.contains(detail.ContourPath())) { @@ -524,7 +494,7 @@ VPosition::CrossingType VPosition::Crossing(const VLayoutPiece &detail) const //--------------------------------------------------------------------------------------------------------------------- bool VPosition::SheetContains(const QRectF &rect) const { - const QRectF bRect(0, 0, gContour.GetWidth(), gContour.GetHeight()); + const QRectF bRect(0, 0, m_data.gContour.GetWidth(), m_data.gContour.GetHeight()); return bRect.contains(rect); } @@ -532,7 +502,7 @@ bool VPosition::SheetContains(const QRectF &rect) const void VPosition::CombineEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge) { QLineF detailEdge; - if (gContour.GetContour().isEmpty()) + if (m_data.gContour.GetContour().isEmpty()) { detailEdge = detail.DetailEdge(dEdge); } @@ -561,7 +531,7 @@ void VPosition::CombineEdges(VLayoutPiece &detail, const QLineF &globalEdge, int void VPosition::RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge, qreal angle) const { QLineF detailEdge; - if (gContour.GetContour().isEmpty()) + if (m_data.gContour.GetContour().isEmpty()) { detailEdge = detail.DetailEdge(dEdge); } @@ -609,24 +579,67 @@ void VPosition::FollowGrainline() } QLineF detailGrainline(10, 10, 100, 10); - detailGrainline.setAngle(detail.GrainlineAngle()); + detailGrainline.setAngle(m_data.detail.GrainlineAngle()); - if (detail.IsForceFlipping()) + if (m_data.detail.IsForceFlipping()) { - VLayoutPiece workDetail = detail; // We need copy for temp change - workDetail.Mirror(not followGrainline ? gContour.GlobalEdge(j) : QLineF(10, 10, 10, 100)); + VLayoutPiece workDetail = m_data.detail; // We need copy for temp change + workDetail.Mirror(not m_data.followGrainline ? m_data.gContour.GlobalEdge(m_data.j) : QLineF(10, 10, 10, 100)); detailGrainline = workDetail.GetMatrix().map(detailGrainline); } const qreal angle = detailGrainline.angleTo(FabricGrainline()); - if (detail.GrainlineArrowType() == ArrowType::atBoth || detail.GrainlineArrowType() == ArrowType::atFront) + if (m_data.detail.GrainlineArrowType() == ArrowType::atBoth || + m_data.detail.GrainlineArrowType() == ArrowType::atFront) { RotateOnAngle(angle); } - if (detail.GrainlineArrowType() == ArrowType::atBoth || detail.GrainlineArrowType() == ArrowType::atRear) + if (m_data.detail.GrainlineArrowType() == ArrowType::atBoth || + m_data.detail.GrainlineArrowType() == ArrowType::atRear) { RotateOnAngle(angle+180); } } + +//--------------------------------------------------------------------------------------------------------------------- +void VPosition::FindBestPosition() +{ + if (not m_data.followGrainline || not m_data.detail.IsGrainlineEnabled()) + { + // We should use copy of the detail. + VLayoutPiece workDetail = m_data.detail; + + int dEdge = m_data.i;// For mirror detail edge will be different + if (CheckCombineEdges(workDetail, m_data.j, dEdge)) + { + #ifdef LAYOUT_DEBUG + # ifdef SHOW_CANDIDATE_BEST + DrawDebug(gContour, workDetail, frame+2, paperIndex, detailsCount, details); + # endif + #endif + + SaveCandidate(m_bestResult, workDetail, m_data.j, dEdge, BestFrom::Combine); + } +#ifdef LAYOUT_DEBUG + frame = frame + 3; +#endif + + if (m_data.rotate) + { + Rotate(m_data.rotationIncrease); + } + else + { + if (m_data.gContour.GetContour().isEmpty()) + { + Rotate(m_data.rotationIncrease); + } + } + } + else + { + FollowGrainline(); + } +} diff --git a/src/libs/vlayout/vposition.h b/src/libs/vlayout/vposition.h index 0129e1332..1a86b9d9a 100644 --- a/src/libs/vlayout/vposition.h +++ b/src/libs/vlayout/vposition.h @@ -40,13 +40,26 @@ #include "vlayoutdef.h" #include "vlayoutpiece.h" +struct VPositionData +{ + VContour gContour{}; + VLayoutPiece detail{}; + int i{-1}; + int j{-1}; + bool rotate{false}; + int rotationIncrease{0}; + bool followGrainline{false}; +}; + class VPosition : public QRunnable { public: - VPosition(const VContour &gContour, int j, const VLayoutPiece &detail, int i, std::atomic_bool *stop, bool rotate, - int rotationIncrease, bool saveLength, bool followGainline); + VPosition(const VPositionData &data, std::atomic_bool *stop, bool saveLength); virtual ~VPosition() override = default; + virtual void run() override; + +#ifdef LAYOUT_DEBUG quint32 getPaperIndex() const; void setPaperIndex(quint32 value); @@ -57,33 +70,32 @@ public: void setDetailsCount(quint32 value); void setDetails(const QVector &details); +#endif VBestSquare getBestResult() const; +#ifdef LAYOUT_DEBUG static void DrawDebug(const VContour &contour, const VLayoutPiece &detail, int frame, quint32 paperIndex, int detailsCount, const QVector &details = QVector()); static int Bias(int length, int maxLength); +#endif private: Q_DISABLE_COPY(VPosition) - VBestSquare bestResult; - const VContour gContour; - const VLayoutPiece detail; - int i; - int j; + VBestSquare m_bestResult; + VPositionData m_data; +#ifdef LAYOUT_DEBUG quint32 paperIndex; quint32 frame; quint32 detailsCount; QVector details; +#endif std::atomic_bool *stop; - bool rotate; - int rotationIncrease; /** * @brief angle_between keep angle between global edge and detail edge. Need for optimization rotation. */ qreal angle_between; - bool followGrainline; enum class CrossingType : char { @@ -99,8 +111,6 @@ private: EdgeError = 2 }; - virtual void run() override; - void SaveCandidate(VBestSquare &bestResult, const VLayoutPiece &detail, int globalI, int detJ, BestFrom type); bool CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge); @@ -118,6 +128,8 @@ private: void FollowGrainline(); QLineF FabricGrainline() const; + + void FindBestPosition(); }; //--------------------------------------------------------------------------------------------------------------------- @@ -127,7 +139,8 @@ private: */ inline QLineF VPosition::FabricGrainline() const { - return gContour.GetHeight() >= gContour.GetWidth() ? QLineF(10, 10, 10, 100) : QLineF(10, 10, 100, 10); + return m_data.gContour.GetHeight() >= m_data.gContour.GetWidth() ? QLineF(10, 10, 10, 100) : + QLineF(10, 10, 100, 10); } #endif // VPOSITION_H