Restore layout debug system.
This commit is contained in:
parent
bccc852931
commit
4041f9e154
|
@ -293,6 +293,13 @@ bool MainWindowsNoGUI::GenerateLayout(VLayoutGenerator& lGenerator)
|
|||
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
const QString path = QDir::homePath()+QStringLiteral("/LayoutDebug");
|
||||
QDir debugDir(path);
|
||||
debugDir.removeRecursively();
|
||||
debugDir.mkpath(path);
|
||||
#endif
|
||||
|
||||
forever
|
||||
{
|
||||
if (IsTimeout())
|
||||
|
@ -307,7 +314,9 @@ bool MainWindowsNoGUI::GenerateLayout(VLayoutGenerator& lGenerator)
|
|||
break;
|
||||
}
|
||||
|
||||
switch (lGenerator.State())
|
||||
nestingState = lGenerator.State();
|
||||
|
||||
switch (nestingState)
|
||||
{
|
||||
case LayoutErrors::NoError:
|
||||
if (lGenerator.PapersCount() <= papersCount)
|
||||
|
|
|
@ -115,4 +115,26 @@ struct VCachedPositions
|
|||
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
|
||||
*/
|
||||
//#define LAYOUT_DEBUG // Enable debug mode
|
||||
|
||||
// This block help rule debug mode. Don't turn all options at the same time!
|
||||
#ifdef LAYOUT_DEBUG
|
||||
// Nice looking
|
||||
# define SHOW_VERTICES // Show contour vertices
|
||||
# define SHOW_DIRECTION // Show contour direction
|
||||
# define ARRANGED_DETAILS // Show already arranged details
|
||||
# define SHOW_SHEET // Show sheet rect
|
||||
# define SHOW_CANDIDATE // Show each position
|
||||
|
||||
// Debugging
|
||||
//# define SHOW_ROTATION // For each position show rotation part
|
||||
//# define SHOW_COMBINE // For each position show edge combine part
|
||||
//# define SHOW_MIRROR // For each position show mirror part
|
||||
//# define SHOW_CANDIDATE_BEST // For only correct positions that pass checks
|
||||
# define SHOW_BEST // Show only best position for workpiece
|
||||
#endif//LAYOUT_DEBUG
|
||||
|
||||
#endif // VLAYOUTDEF_H
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
#include <Qt>
|
||||
#include <QtAlgorithms>
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
#include <QMutex>
|
||||
#endif
|
||||
|
||||
#include "vbestsquare.h"
|
||||
#include "vcontour.h"
|
||||
#include "vlayoutpiece.h"
|
||||
|
@ -239,6 +243,10 @@ bool VLayoutPaper::ArrangeDetail(const VLayoutPiece &detail, std::atomic_bool &s
|
|||
d->localRotationNumber = d->globalRotationNumber;
|
||||
}
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
QMutex mutex;
|
||||
#endif
|
||||
|
||||
VPositionData data;
|
||||
data.gContour = d->globalContour;
|
||||
data.detail = detail;
|
||||
|
@ -247,9 +255,17 @@ bool VLayoutPaper::ArrangeDetail(const VLayoutPiece &detail, std::atomic_bool &s
|
|||
data.followGrainline = d->followGrainline;
|
||||
data.positionsCache = d->positionsCache;
|
||||
data.isOriginPaperOrientationPortrait = d->originPaperOrientation;
|
||||
#ifdef LAYOUT_DEBUG
|
||||
data.details = d->details;
|
||||
data.mutex = &mutex;
|
||||
#endif
|
||||
|
||||
const VBestSquare result = VPosition::ArrangeDetail(data, &stop, d->saveLength);
|
||||
#ifdef LAYOUT_DEBUG
|
||||
return SaveResult(result, detail, &mutex);
|
||||
#else
|
||||
return SaveResult(result, detail);
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -259,7 +275,11 @@ int VLayoutPaper::Count() const
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutPiece &detail)
|
||||
bool VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutPiece &detail
|
||||
#ifdef LAYOUT_DEBUG
|
||||
, QMutex *mutex
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (bestResult.HasValidResult())
|
||||
{
|
||||
|
@ -287,6 +307,12 @@ bool VLayoutPaper::SaveResult(const VBestSquare &bestResult, const VLayoutPiece
|
|||
positionChache.boundingRect = VLayoutPiece::BoundingRect(layoutPoints);
|
||||
positionChache.layoutAllowancePath = VLayoutPiece::PainterPath(layoutPoints);
|
||||
d->positionsCache.append(positionChache);
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
# ifdef SHOW_BEST
|
||||
VPosition::DumpFrame(d->globalContour, workDetail, mutex, d->details);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
else if (bestResult.IsTerminatedByException())
|
||||
{
|
||||
|
|
|
@ -44,6 +44,7 @@ class VLayoutPiece;
|
|||
class QGraphicsRectItem;
|
||||
class QRectF;
|
||||
class QGraphicsItem;
|
||||
class QMutex;
|
||||
template <typename T> class QList;
|
||||
template <typename T> class QVector;
|
||||
|
||||
|
@ -107,7 +108,11 @@ public:
|
|||
private:
|
||||
QSharedDataPointer<VLayoutPaperData> d;
|
||||
|
||||
bool SaveResult(const VBestSquare &bestResult, const VLayoutPiece &detail);
|
||||
bool SaveResult(const VBestSquare &bestResult, const VLayoutPiece &detail
|
||||
#ifdef LAYOUT_DEBUG
|
||||
, QMutex *mutex
|
||||
#endif
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -61,6 +61,85 @@
|
|||
#include <QScopeGuard>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifdef LAYOUT_DEBUG
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath ShowDirection(const QLineF &edge)
|
||||
{
|
||||
const int arrowLength = 14;
|
||||
QPainterPath path;
|
||||
if (edge.length()/arrowLength < 5)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
QLineF arrow = edge;
|
||||
arrow.setLength(edge.length()/2.0);
|
||||
|
||||
//Reverse line because we want start arrow from this point
|
||||
arrow = QLineF(arrow.p2(), arrow.p1());
|
||||
const qreal angle = arrow.angle();//we each time change line angle, better save original angle value
|
||||
arrow.setLength(arrowLength);//arrow length in pixels
|
||||
|
||||
arrow.setAngle(angle-35);
|
||||
path.moveTo(arrow.p1());
|
||||
path.lineTo(arrow.p2());
|
||||
|
||||
arrow.setAngle(angle+35);
|
||||
path.moveTo(arrow.p1());
|
||||
path.lineTo(arrow.p2());
|
||||
return path;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath DumpContour(const QVector<QPointF> &points)
|
||||
{
|
||||
QPainterPath path;
|
||||
path.setFillRule(Qt::WindingFill);
|
||||
if (points.count() >= 2)
|
||||
{
|
||||
for (qint32 i = 0; i < points.count()-1; ++i)
|
||||
{
|
||||
path.moveTo(points.at(i));
|
||||
path.lineTo(points.at(i+1));
|
||||
}
|
||||
path.lineTo(points.at(0));
|
||||
|
||||
#ifdef SHOW_DIRECTION
|
||||
for (qint32 i = 0; i < points.count()-1; ++i)
|
||||
{
|
||||
path.addPath(ShowDirection(QLineF(points.at(i), points.at(i+1))));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SHOW_VERTICES
|
||||
for (qint32 i = 0; i < points.count(); ++i)
|
||||
{
|
||||
path.addRect(points.at(i).x()-3, points.at(i).y()-3, 6, 6);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath DumpDetails(const QVector<VLayoutPiece> &details)
|
||||
{
|
||||
QPainterPath path;
|
||||
path.setFillRule(Qt::WindingFill);
|
||||
if (details.count() > 0)
|
||||
{
|
||||
for (auto &detail : details)
|
||||
{
|
||||
path.addPath(detail.ContourPath());
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
} //anonymous namespace
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPosition::VPosition()
|
||||
{}
|
||||
|
@ -246,6 +325,12 @@ bool VPosition::CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge)
|
|||
|
||||
CombineEdges(detail, globalEdge, dEdge);
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
# ifdef SHOW_COMBINE
|
||||
DumpFrame(m_data.gContour, detail, m_data.mutex, m_data.details);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
CrossingType type = CrossingType::Intersection;
|
||||
if (not detail.IsForceFlipping() && SheetContains(detail.DetailBoundingRect()))
|
||||
{
|
||||
|
@ -276,6 +361,12 @@ bool VPosition::CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge)
|
|||
|
||||
if (flagMirror && not detail.IsForbidFlipping())
|
||||
{
|
||||
#ifdef LAYOUT_DEBUG
|
||||
# ifdef SHOW_MIRROR
|
||||
DumpFrame(m_data.gContour, detail, m_data.mutex, m_data.details);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
dEdge = detail.LayoutEdgeByPoint(globalEdge.p2());
|
||||
|
||||
if (dEdge <= 0)
|
||||
|
@ -319,6 +410,12 @@ bool VPosition::CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, qreal
|
|||
|
||||
RotateEdges(detail, globalEdge, dEdge, angle);
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
# ifdef SHOW_ROTATION
|
||||
DumpFrame(m_data.gContour, detail, m_data.mutex, m_data.details);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
CrossingType type = CrossingType::Intersection;
|
||||
if (SheetContains(detail.DetailBoundingRect()))
|
||||
{
|
||||
|
@ -349,6 +446,12 @@ void VPosition::RotateOnAngle(qreal angle)
|
|||
|
||||
if (CheckRotationEdges(workDetail, m_data.j, m_data.i, angle))
|
||||
{
|
||||
#ifdef LAYOUT_DEBUG
|
||||
# ifdef SHOW_CANDIDATE_BEST
|
||||
DumpFrame(m_data.gContour, workDetail, m_data.mutex, m_data.details);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
SaveCandidate(m_bestResult, workDetail, m_data.j, m_data.i, BestFrom::Rotation);
|
||||
}
|
||||
}
|
||||
|
@ -497,6 +600,12 @@ void VPosition::FindBestPosition()
|
|||
int dEdge = m_data.i;// For mirror detail edge will be different
|
||||
if (CheckCombineEdges(workDetail, m_data.j, dEdge))
|
||||
{
|
||||
#ifdef LAYOUT_DEBUG
|
||||
# ifdef SHOW_CANDIDATE_BEST
|
||||
DumpFrame(m_data.gContour, workDetail, m_data.mutex, m_data.details);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
SaveCandidate(m_bestResult, workDetail, m_data.j, dEdge, BestFrom::Combine);
|
||||
}
|
||||
|
||||
|
@ -515,3 +624,92 @@ void VPosition::FindBestPosition()
|
|||
FollowGrainline();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPosition::DumpFrame(const VContour &contour, const VLayoutPiece &detail, QMutex *mutex,
|
||||
const QVector<VLayoutPiece> &details = QVector<VLayoutPiece>())
|
||||
{
|
||||
auto Bias = [](int length, int maxLength)
|
||||
{
|
||||
return length < maxLength && length*2 < maxLength ? length : maxLength-length;
|
||||
};
|
||||
|
||||
const int biasWidth = Bias(contour.GetWidth(), QIMAGE_MAX);
|
||||
const int biasHeight = Bias(contour.GetHeight(), QIMAGE_MAX);
|
||||
|
||||
QPicture picture;
|
||||
QPainter paint;
|
||||
paint.begin(&picture);
|
||||
|
||||
paint.setPen(QPen(Qt::black, 6, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
|
||||
QPainterPath p;
|
||||
if (contour.GetContour().isEmpty())
|
||||
{
|
||||
p = DumpContour(contour.CutEmptySheetEdge());
|
||||
p.translate(biasWidth/2, biasHeight/2);
|
||||
paint.drawPath(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = DumpContour(contour.GetContour());
|
||||
p.translate(biasWidth/2, biasHeight/2);
|
||||
paint.drawPath(p);
|
||||
}
|
||||
|
||||
#ifdef SHOW_CANDIDATE
|
||||
paint.setPen(QPen(Qt::darkGreen, 6, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
|
||||
p = DumpContour(detail.GetLayoutAllowancePoints());
|
||||
p.translate(biasWidth/2, biasHeight/2);
|
||||
paint.drawPath(p);
|
||||
#else
|
||||
Q_UNUSED(detail)
|
||||
Q_UNUSED(details)
|
||||
#endif
|
||||
|
||||
#ifdef ARRANGED_DETAILS
|
||||
paint.setPen(QPen(Qt::blue, 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
|
||||
p = DumpDetails(details);
|
||||
p.translate(biasWidth/2, biasHeight/2);
|
||||
paint.drawPath(p);
|
||||
#else
|
||||
Q_UNUSED(details)
|
||||
#endif
|
||||
|
||||
// Calculate bounding rect before draw sheet rect
|
||||
const QRect pictureRect = picture.boundingRect();
|
||||
|
||||
// Sheet
|
||||
#ifdef SHOW_SHEET
|
||||
paint.setPen(QPen(Qt::darkRed, 15, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
|
||||
paint.drawRect(QRectF(biasWidth/2, biasHeight/2, contour.GetWidth(), contour.GetHeight()));
|
||||
#endif
|
||||
|
||||
paint.end();
|
||||
|
||||
// Dump frame to image
|
||||
// Note. If program was build with Address Sanitizer possible crashes. Address Sanitizer doesn't support big
|
||||
// allocations. See page https://bitbucket.org/dismine/valentina/wiki/developers/Address_Sanitizer
|
||||
QImage frameImage(pictureRect.width()+biasWidth, pictureRect.height()+biasHeight, QImage::Format_RGB32);
|
||||
|
||||
if (frameImage.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frameImage.fill(Qt::white);
|
||||
|
||||
QPainter paintFrameImage;
|
||||
paintFrameImage.begin(&frameImage);
|
||||
paintFrameImage.drawPicture(0, 0, picture);
|
||||
paintFrameImage.end();
|
||||
|
||||
QMutexLocker locker(mutex);
|
||||
|
||||
static int frame = 0;
|
||||
++frame;
|
||||
|
||||
const QString path = QDir::homePath()+QStringLiteral("/LayoutDebug/%1.png").arg(frame);
|
||||
frameImage.save (path);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
#include <QtGlobal>
|
||||
#include <atomic>
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
#include <QMutex>
|
||||
#endif
|
||||
|
||||
#include "vbestsquare.h"
|
||||
#include "vcontour.h"
|
||||
#include "vlayoutdef.h"
|
||||
|
@ -51,6 +55,10 @@ struct VPositionData
|
|||
bool followGrainline{false};
|
||||
QVector<VCachedPositions> positionsCache{};
|
||||
bool isOriginPaperOrientationPortrait{true};
|
||||
#ifdef LAYOUT_DEBUG
|
||||
QVector<VLayoutPiece> details{};
|
||||
QMutex *mutex{nullptr};
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_WARNING_PUSH
|
||||
|
@ -72,6 +80,11 @@ public:
|
|||
|
||||
static VBestSquare ArrangeDetail(const VPositionData &data, std::atomic_bool *stop, bool saveLength);
|
||||
|
||||
#ifdef LAYOUT_DEBUG
|
||||
static void DumpFrame(const VContour &contour, const VLayoutPiece &detail, QMutex *mutex,
|
||||
const QVector<VLayoutPiece> &details);
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool m_isValid{false};
|
||||
VBestSquare m_bestResult{};
|
||||
|
|
Loading…
Reference in New Issue
Block a user