Using class VSAPoint for drawing base seam allowance.
--HG-- branch : feature
This commit is contained in:
parent
703c2d589b
commit
faad0419cf
|
@ -32,9 +32,6 @@
|
||||||
#include <QLineF>
|
#include <QLineF>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include "../vgeometry/vgobject.h"
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
VAbstractPiece::VAbstractPiece()
|
VAbstractPiece::VAbstractPiece()
|
||||||
|
@ -110,17 +107,15 @@ void VAbstractPiece::SetSAWidth(qreal value)
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
QVector<QPointF> VAbstractPiece::Equidistant(const QVector<QPointF> &points, qreal width)
|
QVector<QPointF> VAbstractPiece::Equidistant(const QVector<VSAPoint> &points, qreal width)
|
||||||
{
|
{
|
||||||
QVector<QPointF> ekvPoints;
|
if (width < 0)
|
||||||
|
|
||||||
if (width <= 0)
|
|
||||||
{
|
{
|
||||||
qDebug()<<"Width <= 0.";
|
qDebug()<<"Width < 0.";
|
||||||
return QVector<QPointF>();
|
return QVector<QPointF>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QPointF> p = CorrectEquidistantPoints(points);
|
QVector<VSAPoint> p = CorrectEquidistantPoints(points);
|
||||||
if ( p.size() < 3 )
|
if ( p.size() < 3 )
|
||||||
{
|
{
|
||||||
qDebug()<<"Not enough points for building the equidistant.";
|
qDebug()<<"Not enough points for building the equidistant.";
|
||||||
|
@ -132,6 +127,7 @@ QVector<QPointF> VAbstractPiece::Equidistant(const QVector<QPointF> &points, qre
|
||||||
p.append(p.at(0));// Should be always closed
|
p.append(p.at(0));// Should be always closed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<QPointF> ekvPoints;
|
||||||
for (qint32 i = 0; i < p.size(); ++i )
|
for (qint32 i = 0; i < p.size(); ++i )
|
||||||
{
|
{
|
||||||
if ( i == 0)
|
if ( i == 0)
|
||||||
|
@ -326,90 +322,16 @@ QVector<QPointF> VAbstractPiece::CheckLoops(const QVector<QPointF> &points)
|
||||||
return ekvPoints;
|
return ekvPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant.
|
|
||||||
* @param points list of points equdistant.
|
|
||||||
* @return corrected list.
|
|
||||||
*/
|
|
||||||
QVector<QPointF> VAbstractPiece::CorrectEquidistantPoints(const QVector<QPointF> &points, bool removeFirstAndLast)
|
|
||||||
{
|
|
||||||
if (points.size()<4)//Better don't check if only three points. We can destroy equidistant.
|
|
||||||
{
|
|
||||||
qDebug()<<"Only three points.";
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Clear equivalent points
|
|
||||||
QVector<QPointF> correctPoints = RemoveDublicates(points, removeFirstAndLast);
|
|
||||||
|
|
||||||
if (correctPoints.size()<3)
|
|
||||||
{
|
|
||||||
return correctPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Remove point on line
|
|
||||||
for (qint32 i = 1; i <correctPoints.size()-1; ++i)
|
|
||||||
{// In this case we alwayse will have bounded intersection, so all is need is to check if point i is on line.
|
|
||||||
// Unfortunatelly QLineF::intersect can't be used in this case because of the floating-point accuraccy problem.
|
|
||||||
if (VGObject::IsPointOnLineviaPDP(correctPoints.at(i), correctPoints.at(i-1), correctPoints.at(i+1)))
|
|
||||||
{
|
|
||||||
correctPoints.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return correctPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
QVector<QPointF> VAbstractPiece::RemoveDublicates(const QVector<QPointF> &points, bool removeFirstAndLast)
|
|
||||||
{
|
|
||||||
QVector<QPointF> p = points;
|
|
||||||
|
|
||||||
if (removeFirstAndLast)
|
|
||||||
{
|
|
||||||
if (not p.isEmpty() && p.size() > 1)
|
|
||||||
{
|
|
||||||
// Path can't be closed
|
|
||||||
if (p.first() == p.last())
|
|
||||||
{
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
|
|
||||||
p.remove(p.size() - 1);
|
|
||||||
#else
|
|
||||||
p.removeLast();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < p.size()-1; ++i)
|
|
||||||
{
|
|
||||||
if (p.at(i) == p.at(i+1))
|
|
||||||
{
|
|
||||||
if (not removeFirstAndLast && (i == p.size()-1))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.erase(p.begin() + i + 1);
|
|
||||||
--i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* @brief EkvPoint return vector of points of equidistant two lines. Last point of two lines must be equal.
|
* @brief EkvPoint return vector of points of equidistant two lines. Last point of two lines must be equal.
|
||||||
* @param width width of equidistant.
|
* @param width width of equidistant.
|
||||||
* @return vector of points.
|
* @return vector of points.
|
||||||
*/
|
*/
|
||||||
QVector<QPointF> VAbstractPiece::EkvPoint(const QPointF &p1Line1, const QPointF &p2Line1,
|
QVector<QPointF> VAbstractPiece::EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1,
|
||||||
const QPointF &p1Line2, const QPointF &p2Line2, qreal width)
|
const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width)
|
||||||
{
|
{
|
||||||
if (width <= 0)
|
if (width < 0)
|
||||||
{
|
{
|
||||||
return QVector<QPointF>();
|
return QVector<QPointF>();
|
||||||
}
|
}
|
||||||
|
@ -496,7 +418,7 @@ QVector<QPointF> VAbstractPiece::EkvPoint(const QPointF &p1Line1, const QPointF
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
QLineF VAbstractPiece::ParallelLine(const QPointF &p1, const QPointF &p2, qreal width)
|
QLineF VAbstractPiece::ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width)
|
||||||
{
|
{
|
||||||
const QLineF paralel = QLineF(SingleParallelPoint(p1, p2, 90, width),
|
const QLineF paralel = QLineF(SingleParallelPoint(p1, p2, 90, width),
|
||||||
SingleParallelPoint(p2, p1, -90, width));
|
SingleParallelPoint(p2, p1, -90, width));
|
||||||
|
|
|
@ -32,8 +32,10 @@
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QSharedDataPointer>
|
#include <QSharedDataPointer>
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include "../vmisc/diagnostic.h"
|
#include "../vmisc/diagnostic.h"
|
||||||
|
#include "../vgeometry/vgobject.h"
|
||||||
|
|
||||||
template <class T> class QVector;
|
template <class T> class QVector;
|
||||||
|
|
||||||
|
@ -125,22 +127,101 @@ public:
|
||||||
qreal GetSAWidth() const;
|
qreal GetSAWidth() const;
|
||||||
void SetSAWidth(qreal value);
|
void SetSAWidth(qreal value);
|
||||||
|
|
||||||
static QVector<QPointF> Equidistant(const QVector<QPointF> &points, qreal width);
|
static QVector<QPointF> Equidistant(const QVector<VSAPoint> &points, qreal width);
|
||||||
static qreal SumTrapezoids(const QVector<QPointF> &points);
|
static qreal SumTrapezoids(const QVector<QPointF> &points);
|
||||||
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
|
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
|
||||||
static QVector<QPointF> CorrectEquidistantPoints(const QVector<QPointF> &points, bool removeFirstAndLast = true);
|
|
||||||
|
template <class T>
|
||||||
|
static QVector<T> CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast = true);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static QVector<QPointF> RemoveDublicates(const QVector<QPointF> &points, bool removeFirstAndLast = true);
|
template <class T>
|
||||||
|
static QVector<T> RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedDataPointer<VAbstractPieceData> d;
|
QSharedDataPointer<VAbstractPieceData> d;
|
||||||
|
|
||||||
static QVector<QPointF> EkvPoint(const QPointF &p1Line1, const QPointF &p2Line1,
|
static QVector<QPointF> EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1,
|
||||||
const QPointF &p1Line2, const QPointF &p2Line2, qreal width);
|
const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width);
|
||||||
static QLineF ParallelLine(const QPointF &p1, const QPointF &p2, qreal width);
|
static QLineF ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width);
|
||||||
static QPointF SingleParallelPoint(const QPointF &p1, const QPointF &p2, qreal angle, qreal width);
|
static QPointF SingleParallelPoint(const QPointF &p1, const QPointF &p2, qreal angle, qreal width);
|
||||||
static int BisectorAngle(const QPointF &p1, const QPointF &p2, const QPointF &p3);
|
static int BisectorAngle(const QPointF &p1, const QPointF &p2, const QPointF &p3);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant.
|
||||||
|
* @param points list of points equdistant.
|
||||||
|
* @return corrected list.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
QVector<T> VAbstractPiece::CorrectEquidistantPoints(const QVector<T> &points, bool removeFirstAndLast)
|
||||||
|
{
|
||||||
|
if (points.size()<4)//Better don't check if only three points. We can destroy equidistant.
|
||||||
|
{
|
||||||
|
qDebug()<<"Only three points.";
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Clear equivalent points
|
||||||
|
QVector<T> correctPoints = RemoveDublicates(points, removeFirstAndLast);
|
||||||
|
|
||||||
|
if (correctPoints.size()<3)
|
||||||
|
{
|
||||||
|
return correctPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove point on line
|
||||||
|
for (qint32 i = 1; i <correctPoints.size()-1; ++i)
|
||||||
|
{// In this case we alwayse will have bounded intersection, so all is need is to check if point i is on line.
|
||||||
|
// Unfortunatelly QLineF::intersect can't be used in this case because of the floating-point accuraccy problem.
|
||||||
|
if (VGObject::IsPointOnLineviaPDP(correctPoints.at(i), correctPoints.at(i-1), correctPoints.at(i+1)))
|
||||||
|
{
|
||||||
|
correctPoints.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return correctPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
template <class T>
|
||||||
|
QVector<T> VAbstractPiece::RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast)
|
||||||
|
{
|
||||||
|
QVector<T> p = points;
|
||||||
|
|
||||||
|
if (removeFirstAndLast)
|
||||||
|
{
|
||||||
|
if (not p.isEmpty() && p.size() > 1)
|
||||||
|
{
|
||||||
|
// Path can't be closed
|
||||||
|
if (p.first() == p.last())
|
||||||
|
{
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
|
||||||
|
p.remove(p.size() - 1);
|
||||||
|
#else
|
||||||
|
p.removeLast();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < p.size()-1; ++i)
|
||||||
|
{
|
||||||
|
if (p.at(i) == p.at(i+1))
|
||||||
|
{
|
||||||
|
if (not removeFirstAndLast && (i == p.size()-1))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.erase(p.begin() + i + 1);
|
||||||
|
--i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VABSTRACTPIECE_H
|
#endif // VABSTRACTPIECE_H
|
||||||
|
|
|
@ -205,12 +205,13 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
||||||
{
|
{
|
||||||
SCASSERT(data != nullptr);
|
SCASSERT(data != nullptr);
|
||||||
|
|
||||||
QVector<QPointF> pointsEkv;
|
|
||||||
if (not IsSeamAllowance())
|
if (not IsSeamAllowance())
|
||||||
{
|
{
|
||||||
return pointsEkv;
|
return QVector<QPointF>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<VSAPoint> pointsEkv;
|
||||||
for (int i = 0; i< CountNodes(); ++i)
|
for (int i = 0; i< CountNodes(); ++i)
|
||||||
{
|
{
|
||||||
switch (at(i).GetTypeTool())
|
switch (at(i).GetTypeTool())
|
||||||
|
@ -218,7 +219,7 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
||||||
case (Tool::NodePoint):
|
case (Tool::NodePoint):
|
||||||
{
|
{
|
||||||
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).GetId());
|
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).GetId());
|
||||||
pointsEkv.append(*point);
|
pointsEkv.append(VSAPoint(point->toQPointF()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (Tool::NodeArc):
|
case (Tool::NodeArc):
|
||||||
|
@ -226,11 +227,7 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
||||||
case (Tool::NodeSplinePath):
|
case (Tool::NodeSplinePath):
|
||||||
{
|
{
|
||||||
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).GetId());
|
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).GetId());
|
||||||
|
CurveSeamAllowanceSegment(pointsEkv, data, curve, i, at(i).GetReverse());
|
||||||
const QPointF begin = StartSegment(data, i, at(i).GetReverse());
|
|
||||||
const QPointF end = EndSegment(data, i, at(i).GetReverse());
|
|
||||||
|
|
||||||
pointsEkv << curve->GetSegmentPoints(begin, end, at(i).GetReverse());
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -239,9 +236,7 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pointsEkv = CheckLoops(CorrectEquidistantPoints(pointsEkv));//A path can contains loops
|
return Equidistant(pointsEkv, ToPixel(GetSAWidth(), *data->GetPatternUnit()));
|
||||||
pointsEkv = Equidistant(pointsEkv, ToPixel(GetSAWidth(), *data->GetPatternUnit()));
|
|
||||||
return pointsEkv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -375,6 +370,21 @@ int VPiece::indexOfNode(const quint32 &id) const
|
||||||
return indexOfNode(d->m_nodes, id);
|
return indexOfNode(d->m_nodes, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VPiece::CurveSeamAllowanceSegment(QVector<VSAPoint> &pointsEkv, const VContainer *data,
|
||||||
|
const QSharedPointer<VAbstractCurve> &curve, int i, bool reverse) const
|
||||||
|
{
|
||||||
|
const QPointF begin = StartSegment(data, i, reverse);
|
||||||
|
const QPointF end = EndSegment(data, i, reverse);
|
||||||
|
|
||||||
|
const QVector<QPointF> points = curve->GetSegmentPoints(begin, end, reverse);
|
||||||
|
|
||||||
|
for(int i = 0; i < points.size(); ++i)
|
||||||
|
{
|
||||||
|
pointsEkv.append(VSAPoint(points.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
QPointF VPiece::StartSegment(const VContainer *data, const int &i, bool reverse) const
|
QPointF VPiece::StartSegment(const VContainer *data, const int &i, bool reverse) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,8 @@ class VPieceNode;
|
||||||
class QPointF;
|
class QPointF;
|
||||||
class VContainer;
|
class VContainer;
|
||||||
template <class T> class QVector;
|
template <class T> class QVector;
|
||||||
|
template <class T>class QSharedPointer;
|
||||||
|
class VAbstractCurve;
|
||||||
|
|
||||||
class VPiece : public VAbstractPiece
|
class VPiece : public VAbstractPiece
|
||||||
{
|
{
|
||||||
|
@ -83,6 +85,8 @@ public:
|
||||||
private:
|
private:
|
||||||
QSharedDataPointer<VPieceData> d;
|
QSharedDataPointer<VPieceData> d;
|
||||||
|
|
||||||
|
void CurveSeamAllowanceSegment(QVector<VSAPoint> &pointsEkv, const VContainer *data,
|
||||||
|
const QSharedPointer<VAbstractCurve> &curve, int i, bool reverse) const;
|
||||||
QPointF StartSegment(const VContainer *data, const int &i, bool reverse) const;
|
QPointF StartSegment(const VContainer *data, const int &i, bool reverse) const;
|
||||||
QPointF EndSegment(const VContainer *data, const int &i, bool reverse) const;
|
QPointF EndSegment(const VContainer *data, const int &i, bool reverse) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user