New better way select objects for creation a detail.

Now the detail cutting points and use only cutted part for creation paths.

--HG--
branch : feature
This commit is contained in:
dismine 2014-12-15 16:25:40 +02:00
parent 30d1fad26f
commit aed090aed3
12 changed files with 215 additions and 55 deletions

View File

@ -51,6 +51,72 @@ VAbstractCurve &VAbstractCurve::operator=(const VAbstractCurve &curve)
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QPointF &end) const
{
QVector<QPointF> points = GetPoints();
points = FromBegin(points, begin);
points = ToEnd(points, end);
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::FromBegin(const QVector<QPointF> &points, const QPointF &begin) const
{
if (points.count() >= 2)
{
QVector<QPointF> segment;
bool theBegin = false;
for (qint32 i = 0; i < points.count()-1; ++i)
{
if (theBegin == false)
{
if (PointInSegment(begin, points.at(i), points.at(i+1)))
{
theBegin = true;
segment.append(begin);
if (i == points.count()-2)
{
segment.append(points.at(i+1));
}
continue;
}
}
else
{
segment.append(points.at(i));
if (i == points.count()-2)
{
segment.append(points.at(i+1));
}
}
}
if (segment.isEmpty())
{
return points;
}
else
{
return segment;
}
}
else
{
return points;
}
return points;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::ToEnd(const QVector<QPointF> &points, const QPointF &end) const
{
QVector<QPointF> reversed = GetReversePoints(points);
reversed = FromBegin(reversed, end);
return GetReversePoints(reversed);
}
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VAbstractCurve::GetPath(PathDirection direction) const
{

View File

@ -43,12 +43,18 @@ public:
VAbstractCurve(const GOType &type, const quint32 &idObject = NULL_ID, const Draw &mode = Draw::Calculation);
VAbstractCurve(const VAbstractCurve &curve);
VAbstractCurve& operator= (const VAbstractCurve &curve);
virtual QVector<QPointF> GetPoints() const =0;
QVector<QPointF> GetSegmentPoints(const QPointF &begin, const QPointF &end) const;
virtual QPainterPath GetPath(PathDirection direction = PathDirection::Hide) const;
virtual qreal GetLength() const =0;
virtual QVector<QPointF> IntersectLine(const QLineF &line) const;
protected:
QPainterPath ShowDirection(const QVector<QPointF> &points) const;
private:
QVector<QPointF> FromBegin(const QVector<QPointF> &points, const QPointF &begin) const;
QVector<QPointF> ToEnd(const QVector<QPointF> &points, const QPointF &end) const;
};
#endif // VABSTRACTCURVE_H

View File

@ -181,7 +181,8 @@ QVector<QPointF> VArc::GetPoints() const
points.append(line.p2());
}
} while (i <= angle);
return points;
// Detail points clockwise, but arc we draw counterclockwise. Main contour need reverse.
return GetReversePoints(points);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -38,7 +38,14 @@
#include <QtMath>
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VEquidistant::ContourPath(const quint32 &idDetail, const VContainer *data) const
VEquidistant::VEquidistant(const VContainer *data)
:data(data)
{
SCASSERT(data != nullptr);
}
//---------------------------------------------------------------------------------------------------------------------
QPainterPath VEquidistant::ContourPath(const quint32 &idDetail) const
{
SCASSERT(data != nullptr);
VDetail detail = data->GetDetail(idDetail);
@ -62,23 +69,15 @@ QPainterPath VEquidistant::ContourPath(const quint32 &idDetail, const VContainer
}
break;
case (Tool::NodeArc):
{
const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(detail.at(i).getId());
// Detail points clockwise, but arc we draw counterclockwise. Main contour need reverse.
const QVector<QPointF> reversedPoints = GetReversePoint(arc->GetPoints());
AddContour(reversedPoints, points, pointsEkv, detail, i);
}
break;
case (Tool::NodeSpline):
{
const QSharedPointer<VSpline> spline = data->GeometricObject<VSpline>(detail.at(i).getId());
AddContour(spline->GetPoints(), points, pointsEkv, detail, i);
}
break;
case (Tool::NodeSplinePath):
{
const QSharedPointer<VSplinePath> splinePath = data->GeometricObject<VSplinePath>(detail.at(i).getId());
AddContour(splinePath->GetPoints(), points, pointsEkv, detail, i);
const QSharedPointer<VAbstractCurve> curve=data->GeometricObject<VAbstractCurve>(detail.at(i).getId());
const QPointF begin = StartSegment(detail, i);
const QPointF end = EndSegment(detail, i);
AddContourPoints(curve->GetSegmentPoints(begin, end), points, pointsEkv, detail, i);
}
break;
default:
@ -115,6 +114,54 @@ QPainterPath VEquidistant::ContourPath(const quint32 &idDetail, const VContainer
return path;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VEquidistant::StartSegment(const VDetail &detail, const int &i) const
{
QPointF begin;
if (detail.CountNode() > 1)
{
if (i == 0)
{
if (detail.at(detail.CountNode()-1).getTypeTool() == Tool::NodePoint)
{
begin = data->GeometricObject<VPointF>(detail.at(detail.CountNode()-1).getId())->toQPointF();
}
}
else
{
if (detail.at(i-1).getTypeTool() == Tool::NodePoint)
{
begin = data->GeometricObject<VPointF>(detail.at(i-1).getId())->toQPointF();
}
}
}
return begin;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VEquidistant::EndSegment(const VDetail &detail, const int &i) const
{
QPointF end;
if (detail.CountNode() > 2)
{
if (i == detail.CountNode() - 1)
{
if (detail.at(0).getTypeTool() == Tool::NodePoint)
{
end = data->GeometricObject<VPointF>(detail.at(0).getId())->toQPointF();
}
}
else
{
if (detail.at(i+1).getTypeTool() == Tool::NodePoint)
{
end = data->GeometricObject<VPointF>(detail.at(i+1).getId())->toQPointF();
}
}
}
return end;
}
//---------------------------------------------------------------------------------------------------------------------
int VEquidistant::GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints)
{
@ -320,18 +367,6 @@ QVector<QPointF> VEquidistant::CheckLoops(const QVector<QPointF> &points)
return ekvPoints;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VEquidistant::GetReversePoint(const QVector<QPointF> &points)
{
SCASSERT(points.size() > 0);
QVector<QPointF> reversePoints;
for (qint32 i = points.size() - 1; i >= 0; --i)
{
reversePoints.append(points.at(i));
}
return reversePoints;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VEquidistant::EkvPoint(const QLineF &line1, const QLineF &line2, const qreal &width)
{
@ -402,11 +437,11 @@ QPointF VEquidistant::SingleParallelPoint(const QLineF &line, const qreal &angle
}
//---------------------------------------------------------------------------------------------------------------------
void VEquidistant::AddContour(const QVector<QPointF> &nodePoints, QVector<QPointF> &points, QVector<QPointF> &pointsEkv,
void VEquidistant::AddContourPoints(const QVector<QPointF> &nodePoints, QVector<QPointF> &points, QVector<QPointF> &pointsEkv,
const VDetail &detail, int i)
{
int len1 = GetLengthContour(points, nodePoints);
QVector<QPointF> reversedPoints = GetReversePoint(nodePoints);
QVector<QPointF> reversedPoints = VGObject::GetReversePoints(nodePoints);
int lenReverse = GetLengthContour(points, reversedPoints);
if (len1 <= lenReverse)
{

View File

@ -42,14 +42,18 @@ class QLineF;
class VEquidistant
{
public:
VEquidistant(const VContainer *data);
~VEquidistant(){}
/**
* @brief ContourPath create painter path for detail.
* @param idDetail id of detail.
* @param data container with objects (points, arcs, splines).
* @return return painter path of contour detail.
*/
QPainterPath ContourPath(const quint32 &idDetail, const VContainer *data) const;
QPainterPath ContourPath(const quint32 &idDetail) const;
private:
Q_DISABLE_COPY(VEquidistant)
const VContainer *data;
/**
* @brief GetLengthContour return length of contour.
* @param contour container with points of contour.
@ -85,12 +89,6 @@ private:
* @return vector of points of equidistant.
*/
static QVector<QPointF> CheckLoops(const QVector<QPointF> &points);
/**
* @brief GetReversePoint return revers container of points.
* @param points container with points.
* @return reverced points.
*/
static QVector<QPointF> GetReversePoint(const QVector<QPointF> &points);
/**
* @brief EkvPoint return vector of points of equidistant two lines. Last point of two lines must be equal.
* @param line1 first line.
@ -115,8 +113,11 @@ private:
*/
static QPointF SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width);
static void AddContour(const QVector<QPointF> &nodePoints, QVector<QPointF> &points,
static void AddContourPoints(const QVector<QPointF> &nodePoints, QVector<QPointF> &points,
QVector<QPointF> &pointsEkv, const VDetail &detail, int i);
QPointF StartSegment(const VDetail &detail, const int &i) const;
QPointF EndSegment(const VDetail &detail, const int &i) const;
};
#endif // VEQUIDISTANT_H

View File

@ -350,3 +350,45 @@ void VGObject::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c
*b = p1.x() - line.p2().x();
*c = - *a * p1.x() - *b * p1.y();
}
//---------------------------------------------------------------------------------------------------------------------
bool VGObject::PointInSegment(const QPointF &t, const QPointF &p1, const QPointF &p2)
{
const qreal eps = 1e-8;
qreal a = p2.y() - p1.y();
qreal b = p1.x() - p2.x();
qreal c = - a * p1.x() - b * p1.y();
if (qAbs(a * t.x() + b * t.y() + c) > eps)
{
return false;
}
return PointInBox (t, p1, p2);
}
//---------------------------------------------------------------------------------------------------------------------
bool VGObject::PointInBox(const QPointF &t, const QPointF &p1, const QPointF &p2)
{
const qreal eps = 1e-8;
return (qAbs (t.x() - qMin(p1.x(), p2.x())) <= eps || qMin(p1.x(), p2.x()) <= t.x()) &&
(qAbs (qMax(p1.x(), p2.x()) - t.x()) <= eps || qMax(p1.x(), p2.x()) >= t.x()) &&
(qAbs (t.y() - qMin(p1.y(), p2.y())) <= eps || qMin(p1.y(), p2.y()) <= t.y()) &&
(qAbs (qMax(p1.y(), p2.y()) - t.y()) <= eps || qMax(p1.y(), p2.y()) >= t.y());
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VGObject::GetReversePoints(const QVector<QPointF> &points)
{
if (points.isEmpty())
{
return points;
}
QVector<QPointF> reversePoints;
for (qint32 i = points.size() - 1; i >= 0; --i)
{
reversePoints.append(points.at(i));
}
return reversePoints;
}

View File

@ -77,6 +77,14 @@ public:
static QPointF ClosestPoint(const QLineF &line, const QPointF &point);
static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k);
static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c);
static bool PointInSegment (const QPointF &t, const QPointF &p1, const QPointF &p2);
static bool PointInBox (const QPointF &t, const QPointF &p1, const QPointF &p2);
/**
* @brief GetReversePoint return revers container of points.
* @param points container with points.
* @return reverced points.
*/
static QVector<QPointF> GetReversePoints(const QVector<QPointF> &points);
private:
QSharedDataPointer<VGObjectData> d;
};

View File

@ -1901,7 +1901,7 @@ void MainWindow::ActionLayout(bool checked)
while (idetail.hasNext())
{
idetail.next();
QPainterPath path = VEquidistant().ContourPath(idetail.key(), pattern);
QPainterPath path = VEquidistant(pattern).ContourPath(idetail.key());
listDetails.append(new VItem(path, listDetails.size()));
}
QString description = doc->GetDescription();

View File

@ -217,9 +217,9 @@ void VNodeArc::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/
void VNodeArc::RefreshGeometry()
{
const QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(id);
QPainterPath path;
path.addPath(arc->GetPath());
path.setFillRule( Qt::WindingFill );
this->setPath(path);
// const QSharedPointer<VArc> arc = VAbstractTool::data.GeometricObject<VArc>(id);
// QPainterPath path;
// path.addPath(arc->GetPath());
// path.setFillRule( Qt::WindingFill );
// this->setPath(path);
}

View File

@ -220,9 +220,9 @@ void VNodeSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/
void VNodeSpline::RefreshGeometry()
{
const QSharedPointer<VSpline> spl = VAbstractTool::data.GeometricObject<VSpline>(id);
QPainterPath path;
path.addPath(spl->GetPath());
path.setFillRule( Qt::WindingFill );
this->setPath(path);
// const QSharedPointer<VSpline> spl = VAbstractTool::data.GeometricObject<VSpline>(id);
// QPainterPath path;
// path.addPath(spl->GetPath());
// path.setFillRule( Qt::WindingFill );
// this->setPath(path);
}

View File

@ -223,9 +223,9 @@ void VNodeSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
*/
void VNodeSplinePath::RefreshGeometry()
{
const QSharedPointer<VSplinePath> splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
QPainterPath path;
path.addPath(splPath->GetPath());
path.setFillRule( Qt::WindingFill );
this->setPath(path);
// const QSharedPointer<VSplinePath> splPath = VAbstractTool::data.GeometricObject<VSplinePath>(id);
// QPainterPath path;
// path.addPath(splPath->GetPath());
// path.setFillRule( Qt::WindingFill );
// this->setPath(path);
}

View File

@ -503,7 +503,7 @@ void VToolDetail::ShowVisualization(bool show)
void VToolDetail::RefreshGeometry()
{
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
QPainterPath path = VEquidistant().ContourPath(id, this->getData());
QPainterPath path = VEquidistant(this->getData()).ContourPath(id);
this->setPath(path);
VDetail detail = VAbstractTool::data.GetDetail(id);
@ -511,6 +511,7 @@ void VToolDetail::RefreshGeometry()
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
//---------------------------------------------------------------------------------------------------------------------
void VToolDetail::DeleteTool(bool ask)
{
DeleteDetail *delDet = new DeleteDetail(doc, id);