Alternative approach to search intersection in layout.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2019-04-10 15:54:18 +03:00
parent 2565f88038
commit aa1d30bdb8
10 changed files with 61 additions and 87 deletions

View File

@ -296,18 +296,6 @@ const QPointF &VContour::at(int i) const
return d->globalContour.at(i); 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<QPointF> &contour, const VLayoutPiece &detail, int detJ) const void VContour::AppendWhole(QVector<QPointF> &contour, const VLayoutPiece &detail, int detJ) const
{ {
@ -360,35 +348,6 @@ void VContour::ResetAttributes()
{ {
if (not d->globalContour.isEmpty()) if (not d->globalContour.isEmpty())
{ {
// Bounding rect
{
QVector<QPointF> 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<QPointF> 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 d->m_emptySheetEdgesCount = d->globalContour.count(); // Edges count
} }
else else

View File

@ -89,10 +89,6 @@ public:
const QPointF & at(int i) const; const QPointF & at(int i) const;
QRectF BoundingRect() const;
QPainterPath ContourPath() const;
private: private:
QSharedDataPointer<VContourData> d; QSharedDataPointer<VContourData> d;

View File

@ -60,8 +60,6 @@ public:
paperWidth(contour.paperWidth), paperWidth(contour.paperWidth),
shift(contour.shift), shift(contour.shift),
layoutWidth(contour.layoutWidth), layoutWidth(contour.layoutWidth),
m_boundingRect(contour.m_boundingRect),
m_contourPath(contour.m_contourPath),
m_emptySheetEdgesCount(contour.m_emptySheetEdgesCount) m_emptySheetEdgesCount(contour.m_emptySheetEdgesCount)
{} {}
@ -80,9 +78,6 @@ public:
qreal layoutWidth{0}; qreal layoutWidth{0};
QRectF m_boundingRect{};
QPainterPath m_contourPath{};
int m_emptySheetEdgesCount{0}; int m_emptySheetEdgesCount{0};
private: private:

View File

@ -65,6 +65,12 @@ struct VBestSquareResData
qreal depthPosition{INT_MAX}; 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 /* 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 * Address Sanitizer. See page https://bitbucket.org/dismine/valentina/wiki/developers/Address_Sanitizer
*/ */

View File

@ -252,6 +252,7 @@ bool VLayoutPaper::AddToSheet(const VLayoutPiece &detail, std::atomic_bool &stop
data.rotate = d->localRotate; data.rotate = d->localRotate;
data.rotationNumber = d->localRotationNumber; data.rotationNumber = d->localRotationNumber;
data.followGrainline = d->followGrainline; data.followGrainline = d->followGrainline;
data.positionsCache = d->positionsCache;
auto *thread = new VPosition(data, &stop, d->saveLength); auto *thread = new VPosition(data, &stop, d->saveLength);
//Info for debug //Info for debug
@ -322,6 +323,12 @@ bool VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutPiece
d->details.append(workDetail); d->details.append(workDetail);
d->globalContour.SetContour(newGContour); d->globalContour.SetContour(newGContour);
VCachedPositions positionChache;
QVector<QPointF> layoutPoints = workDetail.GetLayoutAllowancePoints();
positionChache.boundingRect = VLayoutPiece::BoundingRect(layoutPoints);
positionChache.layoutAllowancePath = VLayoutPiece::PainterPath(layoutPoints);
d->positionsCache.append(positionChache);
#ifdef LAYOUT_DEBUG #ifdef LAYOUT_DEBUG
# ifdef SHOW_BEST # ifdef SHOW_BEST
VPosition::DrawDebug(d->globalContour, workDetail, UINT_MAX, d->paperIndex, d->details.count(), d->details); VPosition::DrawDebug(d->globalContour, workDetail, UINT_MAX, d->paperIndex, d->details.count(), d->details);

View File

@ -54,6 +54,7 @@ public:
VLayoutPaperData(const VLayoutPaperData &paper) VLayoutPaperData(const VLayoutPaperData &paper)
: QSharedData(paper), : QSharedData(paper),
details(paper.details), details(paper.details),
positionsCache(paper.positionsCache),
globalContour(paper.globalContour), globalContour(paper.globalContour),
paperIndex(paper.paperIndex), paperIndex(paper.paperIndex),
frame(paper.frame), frame(paper.frame),
@ -71,6 +72,8 @@ public:
/** @brief details list of arranged details. */ /** @brief details list of arranged details. */
QVector<VLayoutPiece> details{}; QVector<VLayoutPiece> details{};
QVector<VCachedPositions> positionsCache{};
/** @brief globalContour list of global points contour. */ /** @brief globalContour list of global points contour. */
VContour globalContour{}; VContour globalContour{};

View File

@ -681,26 +681,14 @@ int VLayoutPiece::LayoutEdgeByPoint(const QPointF &p1) const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::DetailBoundingRect() const QRectF VLayoutPiece::DetailBoundingRect() const
{ {
QVector<QPointF> points; return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? BoundingRect(GetSeamAllowancePoints()) :
if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) BoundingRect(GetContourPoints());
{
points = GetSeamAllowancePoints();
}
else
{
points = GetContourPoints();
}
points.append(points.first());
return QPolygonF(points).boundingRect();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::LayoutBoundingRect() const QRectF VLayoutPiece::LayoutBoundingRect() const
{ {
QVector<QPointF> points = GetLayoutAllowancePoints(); return BoundingRect(GetLayoutAllowancePoints());
points.append(points.first());
return QPolygonF(points).boundingRect();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -832,16 +820,9 @@ QPainterPath VLayoutPiece::ContourPath() const
QPainterPath path; QPainterPath path;
// contour // contour
QVector<QPointF> points = GetContourPoints();
if (not IsHideMainPath() || not IsSeamAllowance() || IsSeamAllowanceBuiltIn()) if (not IsHideMainPath() || not IsSeamAllowance() || IsSeamAllowanceBuiltIn())
{ {
path.moveTo(points.at(0)); path = PainterPath(GetContourPoints());
for (qint32 i = 1; i < points.count(); ++i)
{
path.lineTo(points.at(i));
}
path.lineTo(points.at(0));
} }
// seam allowance // seam allowance
@ -885,11 +866,16 @@ QPainterPath VLayoutPiece::ContourPath() const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VLayoutPiece::LayoutAllowancePath() const QPainterPath VLayoutPiece::LayoutAllowancePath() const
{
return PainterPath(GetLayoutAllowancePoints());
}
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VLayoutPiece::PainterPath(const QVector<QPointF> &points)
{ {
QPainterPath path; QPainterPath path;
path.setFillRule(Qt::WindingFill); path.setFillRule(Qt::WindingFill);
const QVector<QPointF> points = GetLayoutAllowancePoints();
path.moveTo(points.at(0)); path.moveTo(points.at(0));
for (qint32 i = 1; i < points.count(); ++i) for (qint32 i = 1; i < points.count(); ++i)
{ {
@ -957,6 +943,13 @@ qreal VLayoutPiece::BiggestEdge() const
return edge; return edge;
} }
//---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::BoundingRect(QVector<QPointF> points)
{
points.append(points.first());
return QPolygonF(points).boundingRect();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector<QPointF> &labelShape, void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector<QPointF> &labelShape,
const VTextManager &tm, bool textAsPaths) const const VTextManager &tm, bool textAsPaths) const

View File

@ -135,11 +135,16 @@ public:
QRectF LayoutBoundingRect() const; QRectF LayoutBoundingRect() const;
qreal Diagonal() const; qreal Diagonal() const;
static QRectF BoundingRect(QVector<QPointF> points);
bool isNull() const; bool isNull() const;
qint64 Square() const; qint64 Square() const;
QPainterPath ContourPath() const;
QPainterPath ContourPath() const;
QPainterPath LayoutAllowancePath() const; QPainterPath LayoutAllowancePath() const;
static QPainterPath PainterPath(const QVector<QPointF> &points);
Q_REQUIRED_RESULT QGraphicsItem *GetItem(bool textAsPaths) const; Q_REQUIRED_RESULT QGraphicsItem *GetItem(bool textAsPaths) const;
bool IsLayoutAllowanceValid() const; bool IsLayoutAllowanceValid() const;

View File

@ -484,24 +484,33 @@ void VPosition::RotateOnAngle(qreal angle)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPosition::CrossingType VPosition::Crossing(const VLayoutPiece &detail) const VPosition::CrossingType VPosition::Crossing(const VLayoutPiece &detail) const
{ {
const QRectF gRect = m_data.gContour.BoundingRect(); if (m_data.positionsCache.isEmpty())
if (not gRect.intersects(detail.LayoutBoundingRect()) && not gRect.contains(detail.DetailBoundingRect()))
{ {
// This we can determine efficiently.
return CrossingType::NoIntersection; return CrossingType::NoIntersection;
} }
const QPainterPath gPath = m_data.gContour.ContourPath(); const QVector<QPointF> layoutPoints = detail.GetLayoutAllowancePoints();
CrossingType crossing = CrossingType::EdgeError; const QRectF layoutBoundingRect = VLayoutPiece::BoundingRect(layoutPoints);
if (not gPath.contains(detail.ContourPath()) && not gPath.intersects(detail.LayoutAllowancePath())) const QPainterPath layoutAllowancePath = VLayoutPiece::PainterPath(layoutPoints);
const QVector<QPointF> 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
{ return CrossingType::NoIntersection;
crossing = CrossingType::Intersection;
}
return crossing;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -49,6 +49,7 @@ struct VPositionData
bool rotate{false}; bool rotate{false};
int rotationNumber{0}; int rotationNumber{0};
bool followGrainline{false}; bool followGrainline{false};
QVector<VCachedPositions> positionsCache{};
}; };
class VPosition : public QRunnable class VPosition : public QRunnable