Alternative approach to search intersection in layout.
--HG-- branch : develop
This commit is contained in:
parent
2565f88038
commit
aa1d30bdb8
|
@ -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
|
||||
|
|
|
@ -89,10 +89,6 @@ public:
|
|||
|
||||
const QPointF & at(int i) const;
|
||||
|
||||
QRectF BoundingRect() const;
|
||||
|
||||
QPainterPath ContourPath() const;
|
||||
|
||||
private:
|
||||
QSharedDataPointer<VContourData> d;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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{};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -49,6 +49,7 @@ struct VPositionData
|
|||
bool rotate{false};
|
||||
int rotationNumber{0};
|
||||
bool followGrainline{false};
|
||||
QVector<VCachedPositions> positionsCache{};
|
||||
};
|
||||
|
||||
class VPosition : public QRunnable
|
||||
|
|
Loading…
Reference in New Issue
Block a user