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);
}
//---------------------------------------------------------------------------------------------------------------------
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
{
@ -360,35 +348,6 @@ void VContour::ResetAttributes()
{
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
}
else

View File

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

View File

@ -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:

View File

@ -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
*/

View File

@ -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<QPointF> 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);

View File

@ -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<VLayoutPiece> details{};
QVector<VCachedPositions> positionsCache{};
/** @brief globalContour list of global points contour. */
VContour globalContour{};

View File

@ -681,26 +681,14 @@ int VLayoutPiece::LayoutEdgeByPoint(const QPointF &p1) const
//---------------------------------------------------------------------------------------------------------------------
QRectF VLayoutPiece::DetailBoundingRect() const
{
QVector<QPointF> 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<QPointF> 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<QPointF> 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<QPointF> &points)
{
QPainterPath path;
path.setFillRule(Qt::WindingFill);
const QVector<QPointF> 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<QPointF> points)
{
points.append(points.first());
return QPolygonF(points).boundingRect();
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector<QPointF> &labelShape,
const VTextManager &tm, bool textAsPaths) const

View File

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

View File

@ -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<QPointF> layoutPoints = detail.GetLayoutAllowancePoints();
const QRectF layoutBoundingRect = VLayoutPiece::BoundingRect(layoutPoints);
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
{
crossing = CrossingType::Intersection;
}
return crossing;
return CrossingType::NoIntersection;
}
//---------------------------------------------------------------------------------------------------------------------

View File

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