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:
parent
30d1fad26f
commit
aed090aed3
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user