Optimize layout algorithm after profiling.

--HG--
branch : feature
This commit is contained in:
Roman Telezhynskyi 2019-04-02 15:30:31 +03:00
parent 4adce13a4d
commit 7b72ea5bc1
6 changed files with 87 additions and 60 deletions

View file

@ -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<QPointF> &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<QPointF> 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<QPointF> 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<QPointF> 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<QPointF> 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<QPointF> &contour, const VLayoutPiece &detai
while (processedEdges <= nD);
}
//---------------------------------------------------------------------------------------------------------------------
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
{
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
{

View file

@ -98,6 +98,10 @@ private:
void AppendWhole(QVector<QPointF> &contour, const VLayoutPiece &detail, int detJ) const;
void InsertDetail(QVector<QPointF> &contour, const VLayoutPiece &detail, int detJ) const;
void ResetAttributes();
int EmptySheetEdgesCount() const;
};
Q_DECLARE_TYPEINFO(VContour, Q_MOVABLE_TYPE);

View file

@ -32,6 +32,8 @@
#include <QSharedData>
#include <QPointF>
#include <QVector>
#include <QRectF>
#include <QPainterPath>
#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;
};

View file

@ -314,45 +314,36 @@ VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern
//---------------------------------------------------------------------------------------------------------------------
template <class T>
QVector<T> VLayoutPiece::Map(const QVector<T> &points) const
QVector<T> VLayoutPiece::Map(QVector<T> points) const
{
QVector<T> 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<T> list = p.toList();
QList<T> list = points.toList();
for (int k=0, s=list.size(), max=(s/2); k<max; k++)
{
list.swap(k, s-(1+k));
}
p = list.toVector();
points = list.toVector();
}
return p;
return points;
}
//---------------------------------------------------------------------------------------------------------------------
template <>
QVector<VLayoutPlaceLabel> VLayoutPiece::Map<VLayoutPlaceLabel>(const QVector<VLayoutPlaceLabel> &points) const
QVector<VLayoutPlaceLabel> VLayoutPiece::Map<VLayoutPlaceLabel>(QVector<VLayoutPlaceLabel> points) const
{
QVector<VLayoutPlaceLabel> 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;
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -159,7 +159,7 @@ private:
void CreateGrainlineItem(QGraphicsItem *parent) const;
template <class T>
QVector<T> Map(const QVector<T> &points) const;
QVector<T> Map(QVector<T> points) const;
QLineF Edge(const QVector<QPointF> &path, int i) const;
int EdgeByPoint(const QVector<QPointF> &path, const QPointF &p1) const;

View file

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