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

View File

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

View File

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

View File

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