Using class VSAPoint for drawing base seam allowance.

--HG--
branch : feature
This commit is contained in:
Roman Telezhynskyi 2016-11-11 17:55:02 +02:00
parent 703c2d589b
commit faad0419cf
4 changed files with 121 additions and 104 deletions

View file

@ -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));

View file

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

View file

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

View file

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