From aa1d30bdb8d88cd5cc2a78e296656269f3e3a8f8 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Wed, 10 Apr 2019 15:54:18 +0300 Subject: [PATCH] Alternative approach to search intersection in layout. --HG-- branch : develop --- src/libs/vlayout/vcontour.cpp | 41 ------------------------------- src/libs/vlayout/vcontour.h | 4 --- src/libs/vlayout/vcontour_p.h | 5 ---- src/libs/vlayout/vlayoutdef.h | 6 +++++ src/libs/vlayout/vlayoutpaper.cpp | 7 ++++++ src/libs/vlayout/vlayoutpaper_p.h | 3 +++ src/libs/vlayout/vlayoutpiece.cpp | 41 +++++++++++++------------------ src/libs/vlayout/vlayoutpiece.h | 7 +++++- src/libs/vlayout/vposition.cpp | 33 ++++++++++++++++--------- src/libs/vlayout/vposition.h | 1 + 10 files changed, 61 insertions(+), 87 deletions(-) diff --git a/src/libs/vlayout/vcontour.cpp b/src/libs/vlayout/vcontour.cpp index 0fb6b73f2..fb59bf0c3 100644 --- a/src/libs/vlayout/vcontour.cpp +++ b/src/libs/vlayout/vcontour.cpp @@ -296,18 +296,6 @@ const QPointF &VContour::at(int i) const return d->globalContour.at(i); } -//--------------------------------------------------------------------------------------------------------------------- -QRectF VContour::BoundingRect() const -{ - return d->m_boundingRect; -} - -//--------------------------------------------------------------------------------------------------------------------- -QPainterPath VContour::ContourPath() const -{ - return d->m_contourPath; -} - //--------------------------------------------------------------------------------------------------------------------- void VContour::AppendWhole(QVector &contour, const VLayoutPiece &detail, int detJ) const { @@ -360,35 +348,6 @@ 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 diff --git a/src/libs/vlayout/vcontour.h b/src/libs/vlayout/vcontour.h index 6cb352607..535515082 100644 --- a/src/libs/vlayout/vcontour.h +++ b/src/libs/vlayout/vcontour.h @@ -89,10 +89,6 @@ public: const QPointF & at(int i) const; - QRectF BoundingRect() const; - - QPainterPath ContourPath() const; - private: QSharedDataPointer d; diff --git a/src/libs/vlayout/vcontour_p.h b/src/libs/vlayout/vcontour_p.h index db62a50a9..dde07b293 100644 --- a/src/libs/vlayout/vcontour_p.h +++ b/src/libs/vlayout/vcontour_p.h @@ -60,8 +60,6 @@ public: paperWidth(contour.paperWidth), shift(contour.shift), layoutWidth(contour.layoutWidth), - m_boundingRect(contour.m_boundingRect), - m_contourPath(contour.m_contourPath), m_emptySheetEdgesCount(contour.m_emptySheetEdgesCount) {} @@ -80,9 +78,6 @@ public: qreal layoutWidth{0}; - QRectF m_boundingRect{}; - QPainterPath m_contourPath{}; - int m_emptySheetEdgesCount{0}; private: diff --git a/src/libs/vlayout/vlayoutdef.h b/src/libs/vlayout/vlayoutdef.h index 6d8ffa0c3..995632bd8 100644 --- a/src/libs/vlayout/vlayoutdef.h +++ b/src/libs/vlayout/vlayoutdef.h @@ -65,6 +65,12 @@ struct VBestSquareResData qreal depthPosition{INT_MAX}; }; +struct VCachedPositions +{ + QRectF boundingRect{}; + QPainterPath layoutAllowancePath{}; +}; + /* Warning! Debugging doesn't work stable in debug mode. If you need big allocation use release mode. Or disable * Address Sanitizer. See page https://bitbucket.org/dismine/valentina/wiki/developers/Address_Sanitizer */ diff --git a/src/libs/vlayout/vlayoutpaper.cpp b/src/libs/vlayout/vlayoutpaper.cpp index f3329bda5..66da5fa62 100644 --- a/src/libs/vlayout/vlayoutpaper.cpp +++ b/src/libs/vlayout/vlayoutpaper.cpp @@ -252,6 +252,7 @@ bool VLayoutPaper::AddToSheet(const VLayoutPiece &detail, std::atomic_bool &stop data.rotate = d->localRotate; data.rotationNumber = d->localRotationNumber; data.followGrainline = d->followGrainline; + data.positionsCache = d->positionsCache; auto *thread = new VPosition(data, &stop, d->saveLength); //Info for debug @@ -322,6 +323,12 @@ bool VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutPiece d->details.append(workDetail); d->globalContour.SetContour(newGContour); + VCachedPositions positionChache; + QVector layoutPoints = workDetail.GetLayoutAllowancePoints(); + positionChache.boundingRect = VLayoutPiece::BoundingRect(layoutPoints); + positionChache.layoutAllowancePath = VLayoutPiece::PainterPath(layoutPoints); + d->positionsCache.append(positionChache); + #ifdef LAYOUT_DEBUG # ifdef SHOW_BEST VPosition::DrawDebug(d->globalContour, workDetail, UINT_MAX, d->paperIndex, d->details.count(), d->details); diff --git a/src/libs/vlayout/vlayoutpaper_p.h b/src/libs/vlayout/vlayoutpaper_p.h index f7635f821..39ae99ee9 100644 --- a/src/libs/vlayout/vlayoutpaper_p.h +++ b/src/libs/vlayout/vlayoutpaper_p.h @@ -54,6 +54,7 @@ public: VLayoutPaperData(const VLayoutPaperData &paper) : QSharedData(paper), details(paper.details), + positionsCache(paper.positionsCache), globalContour(paper.globalContour), paperIndex(paper.paperIndex), frame(paper.frame), @@ -71,6 +72,8 @@ public: /** @brief details list of arranged details. */ QVector details{}; + QVector positionsCache{}; + /** @brief globalContour list of global points contour. */ VContour globalContour{}; diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index 6084f4201..d5cf2e70a 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -681,26 +681,14 @@ int VLayoutPiece::LayoutEdgeByPoint(const QPointF &p1) const //--------------------------------------------------------------------------------------------------------------------- QRectF VLayoutPiece::DetailBoundingRect() const { - QVector points; - if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) - { - points = GetSeamAllowancePoints(); - } - else - { - points = GetContourPoints(); - } - - points.append(points.first()); - return QPolygonF(points).boundingRect(); + return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? BoundingRect(GetSeamAllowancePoints()) : + BoundingRect(GetContourPoints()); } //--------------------------------------------------------------------------------------------------------------------- QRectF VLayoutPiece::LayoutBoundingRect() const { - QVector points = GetLayoutAllowancePoints(); - points.append(points.first()); - return QPolygonF(points).boundingRect(); + return BoundingRect(GetLayoutAllowancePoints()); } //--------------------------------------------------------------------------------------------------------------------- @@ -832,16 +820,9 @@ QPainterPath VLayoutPiece::ContourPath() const QPainterPath path; // contour - QVector points = GetContourPoints(); - if (not IsHideMainPath() || not IsSeamAllowance() || IsSeamAllowanceBuiltIn()) { - path.moveTo(points.at(0)); - for (qint32 i = 1; i < points.count(); ++i) - { - path.lineTo(points.at(i)); - } - path.lineTo(points.at(0)); + path = PainterPath(GetContourPoints()); } // seam allowance @@ -885,11 +866,16 @@ QPainterPath VLayoutPiece::ContourPath() const //--------------------------------------------------------------------------------------------------------------------- QPainterPath VLayoutPiece::LayoutAllowancePath() const +{ + return PainterPath(GetLayoutAllowancePoints()); +} + +//--------------------------------------------------------------------------------------------------------------------- +QPainterPath VLayoutPiece::PainterPath(const QVector &points) { QPainterPath path; path.setFillRule(Qt::WindingFill); - const QVector points = GetLayoutAllowancePoints(); path.moveTo(points.at(0)); for (qint32 i = 1; i < points.count(); ++i) { @@ -957,6 +943,13 @@ qreal VLayoutPiece::BiggestEdge() const return edge; } +//--------------------------------------------------------------------------------------------------------------------- +QRectF VLayoutPiece::BoundingRect(QVector points) +{ + points.append(points.first()); + return QPolygonF(points).boundingRect(); +} + //--------------------------------------------------------------------------------------------------------------------- void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector &labelShape, const VTextManager &tm, bool textAsPaths) const diff --git a/src/libs/vlayout/vlayoutpiece.h b/src/libs/vlayout/vlayoutpiece.h index cf0f97d8d..f521a267c 100644 --- a/src/libs/vlayout/vlayoutpiece.h +++ b/src/libs/vlayout/vlayoutpiece.h @@ -135,11 +135,16 @@ public: QRectF LayoutBoundingRect() const; qreal Diagonal() const; + static QRectF BoundingRect(QVector points); + bool isNull() const; qint64 Square() const; - QPainterPath ContourPath() const; + QPainterPath ContourPath() const; QPainterPath LayoutAllowancePath() const; + + static QPainterPath PainterPath(const QVector &points); + Q_REQUIRED_RESULT QGraphicsItem *GetItem(bool textAsPaths) const; bool IsLayoutAllowanceValid() const; diff --git a/src/libs/vlayout/vposition.cpp b/src/libs/vlayout/vposition.cpp index 9a92108e4..3ca8ef265 100644 --- a/src/libs/vlayout/vposition.cpp +++ b/src/libs/vlayout/vposition.cpp @@ -484,24 +484,33 @@ void VPosition::RotateOnAngle(qreal angle) //--------------------------------------------------------------------------------------------------------------------- VPosition::CrossingType VPosition::Crossing(const VLayoutPiece &detail) const { - const QRectF gRect = m_data.gContour.BoundingRect(); - if (not gRect.intersects(detail.LayoutBoundingRect()) && not gRect.contains(detail.DetailBoundingRect())) + if (m_data.positionsCache.isEmpty()) { - // This we can determine efficiently. return CrossingType::NoIntersection; } - const QPainterPath gPath = m_data.gContour.ContourPath(); - CrossingType crossing = CrossingType::EdgeError; - if (not gPath.contains(detail.ContourPath()) && not gPath.intersects(detail.LayoutAllowancePath())) + const QVector layoutPoints = detail.GetLayoutAllowancePoints(); + const QRectF layoutBoundingRect = VLayoutPiece::BoundingRect(layoutPoints); + const QPainterPath layoutAllowancePath = VLayoutPiece::PainterPath(layoutPoints); + + const QVector contourPoints = detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() ? + detail.GetSeamAllowancePoints() : detail.GetContourPoints(); + const QRectF detailBoundingRect = VLayoutPiece::BoundingRect(contourPoints); + const QPainterPath contourPath = VLayoutPiece::PainterPath(contourPoints); + + for(auto &position : m_data.positionsCache) { - crossing = CrossingType::NoIntersection; + if (position.boundingRect.intersects(layoutBoundingRect) || position.boundingRect.contains(detailBoundingRect)) + { + if (position.layoutAllowancePath.contains(contourPath) || + position.layoutAllowancePath.intersects(layoutAllowancePath)) + { + return CrossingType::Intersection; + } + } } - else - { - crossing = CrossingType::Intersection; - } - return crossing; + + return CrossingType::NoIntersection; } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vlayout/vposition.h b/src/libs/vlayout/vposition.h index b7308c403..10934131b 100644 --- a/src/libs/vlayout/vposition.h +++ b/src/libs/vlayout/vposition.h @@ -49,6 +49,7 @@ struct VPositionData bool rotate{false}; int rotationNumber{0}; bool followGrainline{false}; + QVector positionsCache{}; }; class VPosition : public QRunnable