From 7b72ea5bc1fb92f40079d8efa9b254eb5ad1d29f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Tue, 2 Apr 2019 15:30:31 +0300 Subject: [PATCH] Optimize layout algorithm after profiling. --HG-- branch : feature --- src/libs/vlayout/vcontour.cpp | 89 ++++++++++++++++++++----------- src/libs/vlayout/vcontour.h | 4 ++ src/libs/vlayout/vcontour_p.h | 12 ++++- src/libs/vlayout/vlayoutpiece.cpp | 31 ++++------- src/libs/vlayout/vlayoutpiece.h | 2 +- src/libs/vlayout/vposition.cpp | 9 +--- 6 files changed, 87 insertions(+), 60 deletions(-) diff --git a/src/libs/vlayout/vcontour.cpp b/src/libs/vlayout/vcontour.cpp index 311c49813..0fb6b73f2 100644 --- a/src/libs/vlayout/vcontour.cpp +++ b/src/libs/vlayout/vcontour.cpp @@ -96,6 +96,8 @@ void VContour::CeateEmptySheetContour() { d->globalContour = CutEmptySheetEdge(); d->globalContour.append(d->globalContour.first()); // Close path + + ResetAttributes(); } } @@ -103,6 +105,8 @@ void VContour::CeateEmptySheetContour() void VContour::SetContour(const QVector &contour) { d->globalContour = contour; + + ResetAttributes(); } //--------------------------------------------------------------------------------------------------------------------- @@ -121,6 +125,8 @@ qreal VContour::GetShift() const void VContour::SetShift(qreal shift) { d->shift = shift; + + ResetAttributes(); } //--------------------------------------------------------------------------------------------------------------------- @@ -200,17 +206,7 @@ QVector VContour::UniteWithContour(const VLayoutPiece &detail, int glob //--------------------------------------------------------------------------------------------------------------------- int VContour::GlobalEdgesCount() const { - int count = 0; - if (not d->globalContour.isEmpty()) - { - count = d->globalContour.count(); - } - else - { - const qreal shift = qFuzzyIsNull(d->shift) ? ToPixel(0.5, Unit::Cm) : d->shift; - count = qFloor(EmptySheetEdge().length()/shift); - } - return count; + return d->m_emptySheetEdgesCount; } //--------------------------------------------------------------------------------------------------------------------- @@ -267,6 +263,7 @@ QVector VContour::CutEdge(const QLineF &edge) const } else { + points.reserve(n); const qreal nShift = edge.length()/n; for (int i = 1; i <= n+1; ++i) { @@ -302,30 +299,13 @@ const QPointF &VContour::at(int i) const //--------------------------------------------------------------------------------------------------------------------- QRectF VContour::BoundingRect() const { - QVector points = GetContour(); - if (points.isEmpty()) - { - return QRectF(); - } - points.append(points.first()); - return QPolygonF(points).boundingRect(); + return d->m_boundingRect; } //--------------------------------------------------------------------------------------------------------------------- QPainterPath VContour::ContourPath() const { - QPainterPath path; - path.setFillRule(Qt::WindingFill); - - const QVector points = GetContour(); - path.moveTo(points.at(0)); - for (qint32 i = 1; i < points.count(); ++i) - { - path.lineTo(points.at(i)); - } - path.lineTo(points.at(0)); - - return path; + return d->m_contourPath; } //--------------------------------------------------------------------------------------------------------------------- @@ -375,6 +355,55 @@ void VContour::InsertDetail(QVector &contour, const VLayoutPiece &detai while (processedEdges <= nD); } +//--------------------------------------------------------------------------------------------------------------------- +void VContour::ResetAttributes() +{ + if (not d->globalContour.isEmpty()) + { + // Bounding rect + { + QVector points = d->globalContour; + if (points.isEmpty()) + { + d->m_boundingRect = QRectF(); + } + else + { + points.append(points.first()); + d->m_boundingRect = QPolygonF(points).boundingRect(); + } + } + + { + // Countour path + QPainterPath path; + path.setFillRule(Qt::WindingFill); + const QVector points = d->globalContour; + path.moveTo(points.at(0)); + for (qint32 i = 1; i < points.count(); ++i) + { + path.lineTo(points.at(i)); + } + path.lineTo(points.at(0)); + + d->m_contourPath = path; + } + + d->m_emptySheetEdgesCount = d->globalContour.count(); // Edges count + } + else + { + d->m_emptySheetEdgesCount = EmptySheetEdgesCount(); // Edges count + } +} + +//--------------------------------------------------------------------------------------------------------------------- +int VContour::EmptySheetEdgesCount() const +{ + const qreal shift = qFuzzyIsNull(d->shift) ? ToPixel(0.5, Unit::Cm) : d->shift; + return qFloor(EmptySheetEdge().length()/shift); +} + //--------------------------------------------------------------------------------------------------------------------- bool VContour::IsPortrait() const { diff --git a/src/libs/vlayout/vcontour.h b/src/libs/vlayout/vcontour.h index 6e76cb4e7..6cb352607 100644 --- a/src/libs/vlayout/vcontour.h +++ b/src/libs/vlayout/vcontour.h @@ -98,6 +98,10 @@ private: void AppendWhole(QVector &contour, const VLayoutPiece &detail, int detJ) const; void InsertDetail(QVector &contour, const VLayoutPiece &detail, int detJ) const; + + void ResetAttributes(); + + int EmptySheetEdgesCount() const; }; Q_DECLARE_TYPEINFO(VContour, Q_MOVABLE_TYPE); diff --git a/src/libs/vlayout/vcontour_p.h b/src/libs/vlayout/vcontour_p.h index 31b18b1fd..db62a50a9 100644 --- a/src/libs/vlayout/vcontour_p.h +++ b/src/libs/vlayout/vcontour_p.h @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include "../vmisc/diagnostic.h" @@ -57,7 +59,10 @@ public: paperHeight(contour.paperHeight), paperWidth(contour.paperWidth), shift(contour.shift), - layoutWidth(contour.layoutWidth) + layoutWidth(contour.layoutWidth), + m_boundingRect(contour.m_boundingRect), + m_contourPath(contour.m_contourPath), + m_emptySheetEdgesCount(contour.m_emptySheetEdgesCount) {} ~VContourData() {} @@ -75,6 +80,11 @@ public: qreal layoutWidth{0}; + QRectF m_boundingRect{}; + QPainterPath m_contourPath{}; + + int m_emptySheetEdgesCount{0}; + private: VContourData &operator=(const VContourData &) Q_DECL_EQ_DELETE; }; diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index c770ddb8f..6084f4201 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -314,45 +314,36 @@ VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern //--------------------------------------------------------------------------------------------------------------------- template -QVector VLayoutPiece::Map(const QVector &points) const +QVector VLayoutPiece::Map(QVector points) const { - QVector p; - for (auto point : points) + for (int i = 0; i < points.size(); ++i) { - p.append(d->matrix.map(point)); + points[i] = d->matrix.map(points.at(i)); } if (d->mirror) { - QList list = p.toList(); + QList list = points.toList(); for (int k=0, s=list.size(), max=(s/2); k -QVector VLayoutPiece::Map(const QVector &points) const +QVector VLayoutPiece::Map(QVector points) const { - QVector p; - p.reserve(points.size()); - for (auto &label : points) + for (int i = 0; i < points.size(); ++i) { - VLayoutPlaceLabel mappedLabel; - mappedLabel.type = label.type; - mappedLabel.center = d->matrix.map(label.center); - for (const auto &p : label.shape) - { - mappedLabel.shape.append(d->matrix.map(p)); - } - p.append(mappedLabel); + points[i].center = d->matrix.map(points.at(i).center); + points[i].shape = Map(points.at(i).shape); } - return p; + return points; } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vlayout/vlayoutpiece.h b/src/libs/vlayout/vlayoutpiece.h index 163a4eab6..cf0f97d8d 100644 --- a/src/libs/vlayout/vlayoutpiece.h +++ b/src/libs/vlayout/vlayoutpiece.h @@ -159,7 +159,7 @@ private: void CreateGrainlineItem(QGraphicsItem *parent) const; template - QVector Map(const QVector &points) const; + QVector Map(QVector points) const; QLineF Edge(const QVector &path, int i) const; int EdgeByPoint(const QVector &path, const QPointF &p1) const; diff --git a/src/libs/vlayout/vposition.cpp b/src/libs/vlayout/vposition.cpp index ab06684c7..9a92108e4 100644 --- a/src/libs/vlayout/vposition.cpp +++ b/src/libs/vlayout/vposition.cpp @@ -493,7 +493,7 @@ VPosition::CrossingType VPosition::Crossing(const VLayoutPiece &detail) const const QPainterPath gPath = m_data.gContour.ContourPath(); CrossingType crossing = CrossingType::EdgeError; - if (not gPath.intersects(detail.LayoutAllowancePath()) && not gPath.contains(detail.ContourPath())) + if (not gPath.contains(detail.ContourPath()) && not gPath.intersects(detail.LayoutAllowancePath())) { crossing = CrossingType::NoIntersection; } @@ -645,13 +645,6 @@ void VPosition::FindBestPosition() { Rotate(m_data.rotationNumber); } - else - { - if (m_data.gContour.GetContour().isEmpty()) - { - Rotate(m_data.rotationNumber); - } - } } else {