From aed090aed3e7b1d17efd08fdb2e1e361d72e7226 Mon Sep 17 00:00:00 2001 From: dismine Date: Mon, 15 Dec 2014 16:25:40 +0200 Subject: [PATCH] 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 --- src/app/geometry/vabstractcurve.cpp | 66 +++++++++++++ src/app/geometry/vabstractcurve.h | 6 ++ src/app/geometry/varc.cpp | 3 +- src/app/geometry/vequidistant.cpp | 93 +++++++++++++------ src/app/geometry/vequidistant.h | 17 ++-- src/app/geometry/vgobject.cpp | 42 +++++++++ src/app/geometry/vgobject.h | 8 ++ src/app/mainwindow.cpp | 2 +- src/app/tools/nodeDetails/vnodearc.cpp | 10 +- src/app/tools/nodeDetails/vnodespline.cpp | 10 +- src/app/tools/nodeDetails/vnodesplinepath.cpp | 10 +- src/app/tools/vtooldetail.cpp | 3 +- 12 files changed, 215 insertions(+), 55 deletions(-) diff --git a/src/app/geometry/vabstractcurve.cpp b/src/app/geometry/vabstractcurve.cpp index d91ca5ed6..2f863d21f 100644 --- a/src/app/geometry/vabstractcurve.cpp +++ b/src/app/geometry/vabstractcurve.cpp @@ -51,6 +51,72 @@ VAbstractCurve &VAbstractCurve::operator=(const VAbstractCurve &curve) return *this; } +//--------------------------------------------------------------------------------------------------------------------- +QVector VAbstractCurve::GetSegmentPoints(const QPointF &begin, const QPointF &end) const +{ + QVector points = GetPoints(); + points = FromBegin(points, begin); + points = ToEnd(points, end); + return points; +} + + +//--------------------------------------------------------------------------------------------------------------------- +QVector VAbstractCurve::FromBegin(const QVector &points, const QPointF &begin) const +{ + if (points.count() >= 2) + { + QVector 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 VAbstractCurve::ToEnd(const QVector &points, const QPointF &end) const +{ + QVector reversed = GetReversePoints(points); + reversed = FromBegin(reversed, end); + return GetReversePoints(reversed); +} + //--------------------------------------------------------------------------------------------------------------------- QPainterPath VAbstractCurve::GetPath(PathDirection direction) const { diff --git a/src/app/geometry/vabstractcurve.h b/src/app/geometry/vabstractcurve.h index 82065f79d..b0bc65cce 100644 --- a/src/app/geometry/vabstractcurve.h +++ b/src/app/geometry/vabstractcurve.h @@ -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 GetPoints() const =0; + QVector GetSegmentPoints(const QPointF &begin, const QPointF &end) const; + virtual QPainterPath GetPath(PathDirection direction = PathDirection::Hide) const; virtual qreal GetLength() const =0; virtual QVector IntersectLine(const QLineF &line) const; protected: QPainterPath ShowDirection(const QVector &points) const; +private: + QVector FromBegin(const QVector &points, const QPointF &begin) const; + QVector ToEnd(const QVector &points, const QPointF &end) const; }; #endif // VABSTRACTCURVE_H diff --git a/src/app/geometry/varc.cpp b/src/app/geometry/varc.cpp index 83546cfa3..2f9c434b8 100644 --- a/src/app/geometry/varc.cpp +++ b/src/app/geometry/varc.cpp @@ -181,7 +181,8 @@ QVector 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); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/geometry/vequidistant.cpp b/src/app/geometry/vequidistant.cpp index a5547de35..f57bba431 100644 --- a/src/app/geometry/vequidistant.cpp +++ b/src/app/geometry/vequidistant.cpp @@ -38,7 +38,14 @@ #include //--------------------------------------------------------------------------------------------------------------------- -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 arc = data->GeometricObject(detail.at(i).getId()); - // Detail points clockwise, but arc we draw counterclockwise. Main contour need reverse. - const QVector reversedPoints = GetReversePoint(arc->GetPoints()); - AddContour(reversedPoints, points, pointsEkv, detail, i); - } - break; case (Tool::NodeSpline): - { - const QSharedPointer spline = data->GeometricObject(detail.at(i).getId()); - AddContour(spline->GetPoints(), points, pointsEkv, detail, i); - } - break; case (Tool::NodeSplinePath): { - const QSharedPointer splinePath = data->GeometricObject(detail.at(i).getId()); - AddContour(splinePath->GetPoints(), points, pointsEkv, detail, i); + const QSharedPointer curve=data->GeometricObject(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(detail.at(detail.CountNode()-1).getId())->toQPointF(); + } + } + else + { + if (detail.at(i-1).getTypeTool() == Tool::NodePoint) + { + begin = data->GeometricObject(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(detail.at(0).getId())->toQPointF(); + } + } + else + { + if (detail.at(i+1).getTypeTool() == Tool::NodePoint) + { + end = data->GeometricObject(detail.at(i+1).getId())->toQPointF(); + } + } + } + return end; +} + //--------------------------------------------------------------------------------------------------------------------- int VEquidistant::GetLengthContour(const QVector &contour, const QVector &newPoints) { @@ -320,18 +367,6 @@ QVector VEquidistant::CheckLoops(const QVector &points) return ekvPoints; } -//--------------------------------------------------------------------------------------------------------------------- -QVector VEquidistant::GetReversePoint(const QVector &points) -{ - SCASSERT(points.size() > 0); - QVector reversePoints; - for (qint32 i = points.size() - 1; i >= 0; --i) - { - reversePoints.append(points.at(i)); - } - return reversePoints; -} - //--------------------------------------------------------------------------------------------------------------------- QVector 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 &nodePoints, QVector &points, QVector &pointsEkv, +void VEquidistant::AddContourPoints(const QVector &nodePoints, QVector &points, QVector &pointsEkv, const VDetail &detail, int i) { int len1 = GetLengthContour(points, nodePoints); - QVector reversedPoints = GetReversePoint(nodePoints); + QVector reversedPoints = VGObject::GetReversePoints(nodePoints); int lenReverse = GetLengthContour(points, reversedPoints); if (len1 <= lenReverse) { diff --git a/src/app/geometry/vequidistant.h b/src/app/geometry/vequidistant.h index 8d89bc678..a6eda3376 100644 --- a/src/app/geometry/vequidistant.h +++ b/src/app/geometry/vequidistant.h @@ -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 CheckLoops(const QVector &points); - /** - * @brief GetReversePoint return revers container of points. - * @param points container with points. - * @return reverced points. - */ - static QVector GetReversePoint(const QVector &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 &nodePoints, QVector &points, + static void AddContourPoints(const QVector &nodePoints, QVector &points, QVector &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 diff --git a/src/app/geometry/vgobject.cpp b/src/app/geometry/vgobject.cpp index 0c17fc860..143b08e97 100644 --- a/src/app/geometry/vgobject.cpp +++ b/src/app/geometry/vgobject.cpp @@ -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 VGObject::GetReversePoints(const QVector &points) +{ + if (points.isEmpty()) + { + return points; + } + QVector reversePoints; + for (qint32 i = points.size() - 1; i >= 0; --i) + { + reversePoints.append(points.at(i)); + } + return reversePoints; +} diff --git a/src/app/geometry/vgobject.h b/src/app/geometry/vgobject.h index 04e963fa0..15af49cd9 100644 --- a/src/app/geometry/vgobject.h +++ b/src/app/geometry/vgobject.h @@ -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 GetReversePoints(const QVector &points); private: QSharedDataPointer d; }; diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index 25fb334b8..970d3839d 100644 --- a/src/app/mainwindow.cpp +++ b/src/app/mainwindow.cpp @@ -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(); diff --git a/src/app/tools/nodeDetails/vnodearc.cpp b/src/app/tools/nodeDetails/vnodearc.cpp index 0e51c5755..d7c0aeb68 100644 --- a/src/app/tools/nodeDetails/vnodearc.cpp +++ b/src/app/tools/nodeDetails/vnodearc.cpp @@ -217,9 +217,9 @@ void VNodeArc::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) */ void VNodeArc::RefreshGeometry() { - const QSharedPointer arc = VAbstractTool::data.GeometricObject(id); - QPainterPath path; - path.addPath(arc->GetPath()); - path.setFillRule( Qt::WindingFill ); - this->setPath(path); +// const QSharedPointer arc = VAbstractTool::data.GeometricObject(id); +// QPainterPath path; +// path.addPath(arc->GetPath()); +// path.setFillRule( Qt::WindingFill ); +// this->setPath(path); } diff --git a/src/app/tools/nodeDetails/vnodespline.cpp b/src/app/tools/nodeDetails/vnodespline.cpp index a875ebf46..a83545287 100644 --- a/src/app/tools/nodeDetails/vnodespline.cpp +++ b/src/app/tools/nodeDetails/vnodespline.cpp @@ -220,9 +220,9 @@ void VNodeSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) */ void VNodeSpline::RefreshGeometry() { - const QSharedPointer spl = VAbstractTool::data.GeometricObject(id); - QPainterPath path; - path.addPath(spl->GetPath()); - path.setFillRule( Qt::WindingFill ); - this->setPath(path); +// const QSharedPointer spl = VAbstractTool::data.GeometricObject(id); +// QPainterPath path; +// path.addPath(spl->GetPath()); +// path.setFillRule( Qt::WindingFill ); +// this->setPath(path); } diff --git a/src/app/tools/nodeDetails/vnodesplinepath.cpp b/src/app/tools/nodeDetails/vnodesplinepath.cpp index b1f523b0b..a2654e473 100644 --- a/src/app/tools/nodeDetails/vnodesplinepath.cpp +++ b/src/app/tools/nodeDetails/vnodesplinepath.cpp @@ -223,9 +223,9 @@ void VNodeSplinePath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) */ void VNodeSplinePath::RefreshGeometry() { - const QSharedPointer splPath = VAbstractTool::data.GeometricObject(id); - QPainterPath path; - path.addPath(splPath->GetPath()); - path.setFillRule( Qt::WindingFill ); - this->setPath(path); +// const QSharedPointer splPath = VAbstractTool::data.GeometricObject(id); +// QPainterPath path; +// path.addPath(splPath->GetPath()); +// path.setFillRule( Qt::WindingFill ); +// this->setPath(path); } diff --git a/src/app/tools/vtooldetail.cpp b/src/app/tools/vtooldetail.cpp index 24e9572b1..ab308f822 100644 --- a/src/app/tools/vtooldetail.cpp +++ b/src/app/tools/vtooldetail.cpp @@ -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);