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 <QSet>
|
||||
#include <QVector>
|
||||
#include <QDebug>
|
||||
|
||||
#include "../vgeometry/vgobject.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
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>();
|
||||
}
|
||||
|
||||
QVector<QPointF> p = CorrectEquidistantPoints(points);
|
||||
QVector<VSAPoint> p = CorrectEquidistantPoints(points);
|
||||
if ( p.size() < 3 )
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
QVector<QPointF> ekvPoints;
|
||||
for (qint32 i = 0; i < p.size(); ++i )
|
||||
{
|
||||
if ( i == 0)
|
||||
|
@ -326,90 +322,16 @@ QVector<QPointF> VAbstractPiece::CheckLoops(const QVector<QPointF> &points)
|
|||
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.
|
||||
* @param width width of equidistant.
|
||||
* @return vector of points.
|
||||
*/
|
||||
QVector<QPointF> VAbstractPiece::EkvPoint(const QPointF &p1Line1, const QPointF &p2Line1,
|
||||
const QPointF &p1Line2, const QPointF &p2Line2, qreal width)
|
||||
QVector<QPointF> VAbstractPiece::EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1,
|
||||
const VSAPoint &p1Line2, const VSAPoint &p2Line2, qreal width)
|
||||
{
|
||||
if (width <= 0)
|
||||
if (width < 0)
|
||||
{
|
||||
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),
|
||||
SingleParallelPoint(p2, p1, -90, width));
|
||||
|
|
|
@ -32,8 +32,10 @@
|
|||
#include <QtGlobal>
|
||||
#include <QSharedDataPointer>
|
||||
#include <QPointF>
|
||||
#include <QDebug>
|
||||
|
||||
#include "../vmisc/diagnostic.h"
|
||||
#include "../vgeometry/vgobject.h"
|
||||
|
||||
template <class T> class QVector;
|
||||
|
||||
|
@ -125,22 +127,101 @@ public:
|
|||
qreal GetSAWidth() const;
|
||||
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 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:
|
||||
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:
|
||||
QSharedDataPointer<VAbstractPieceData> d;
|
||||
|
||||
static QVector<QPointF> EkvPoint(const QPointF &p1Line1, const QPointF &p2Line1,
|
||||
const QPointF &p1Line2, const QPointF &p2Line2, qreal width);
|
||||
static QLineF ParallelLine(const QPointF &p1, const QPointF &p2, qreal width);
|
||||
static QVector<QPointF> EkvPoint(const VSAPoint &p1Line1, const VSAPoint &p2Line1,
|
||||
const VSAPoint &p1Line2, const VSAPoint &p2Line2, 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 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
|
||||
|
|
|
@ -205,12 +205,13 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
|||
{
|
||||
SCASSERT(data != nullptr);
|
||||
|
||||
QVector<QPointF> pointsEkv;
|
||||
|
||||
if (not IsSeamAllowance())
|
||||
{
|
||||
return pointsEkv;
|
||||
return QVector<QPointF>();
|
||||
}
|
||||
|
||||
QVector<VSAPoint> pointsEkv;
|
||||
for (int i = 0; i< CountNodes(); ++i)
|
||||
{
|
||||
switch (at(i).GetTypeTool())
|
||||
|
@ -218,7 +219,7 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
|||
case (Tool::NodePoint):
|
||||
{
|
||||
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).GetId());
|
||||
pointsEkv.append(*point);
|
||||
pointsEkv.append(VSAPoint(point->toQPointF()));
|
||||
}
|
||||
break;
|
||||
case (Tool::NodeArc):
|
||||
|
@ -226,11 +227,7 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
|||
case (Tool::NodeSplinePath):
|
||||
{
|
||||
const QSharedPointer<VAbstractCurve> curve = data->GeometricObject<VAbstractCurve>(at(i).GetId());
|
||||
|
||||
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());
|
||||
CurveSeamAllowanceSegment(pointsEkv, data, curve, i, at(i).GetReverse());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -239,9 +236,7 @@ QVector<QPointF> VPiece::SeamAllowancePoints(const VContainer *data) const
|
|||
}
|
||||
}
|
||||
|
||||
pointsEkv = CheckLoops(CorrectEquidistantPoints(pointsEkv));//A path can contains loops
|
||||
pointsEkv = Equidistant(pointsEkv, ToPixel(GetSAWidth(), *data->GetPatternUnit()));
|
||||
return pointsEkv;
|
||||
return Equidistant(pointsEkv, ToPixel(GetSAWidth(), *data->GetPatternUnit()));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -375,6 +370,21 @@ int VPiece::indexOfNode(const quint32 &id) const
|
|||
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
|
||||
{
|
||||
|
|
|
@ -40,6 +40,8 @@ class VPieceNode;
|
|||
class QPointF;
|
||||
class VContainer;
|
||||
template <class T> class QVector;
|
||||
template <class T>class QSharedPointer;
|
||||
class VAbstractCurve;
|
||||
|
||||
class VPiece : public VAbstractPiece
|
||||
{
|
||||
|
@ -83,6 +85,8 @@ public:
|
|||
private:
|
||||
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 EndSegment(const VContainer *data, const int &i, bool reverse) const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user