From 08c6a40fde5609aed61676d9fa03fc6b1b07166e Mon Sep 17 00:00:00 2001 From: dismine Date: Tue, 28 Jan 2014 20:53:35 +0200 Subject: [PATCH] New class VEquidistant. --HG-- branch : develop --- src/container/vcontainer.cpp | 410 ------------------------------ src/container/vcontainer.h | 75 ------ src/geometry/geometry.pri | 6 +- src/geometry/vequidistant.cpp | 431 ++++++++++++++++++++++++++++++++ src/geometry/vequidistant.h | 115 +++++++++ src/mainwindow.cpp | 10 +- src/tools/vtooldetail.cpp | 3 +- src/tools/vtooluniondetails.cpp | 2 +- 8 files changed, 562 insertions(+), 490 deletions(-) create mode 100644 src/geometry/vequidistant.cpp create mode 100644 src/geometry/vequidistant.h diff --git a/src/container/vcontainer.cpp b/src/container/vcontainer.cpp index d78ca5b30..e2a33e8f7 100644 --- a/src/container/vcontainer.cpp +++ b/src/container/vcontainer.cpp @@ -215,392 +215,6 @@ void VContainer::UpdateId(qint64 newId) } } -QVector VContainer::CorrectEquidistantPoints(const QVector &points) -{ - QVector correctPoints; - if (points.size()<4)//Better don't check if only three points. We can destroy equidistant. - { - qWarning()<<"Only three points."; - return points; - } - //Clear equivalent points - for (qint32 i = 0; i points; - QVector pointsEkv; - for (ptrdiff_t i = 0; i< detail.CountNode(); ++i) - { - switch (detail.at(i).getTypeTool()) - { - case (Tool::NodePoint): - { - const VPointF *point = GeometricObject(detail.at(i).getId()); - points.append(point->toQPointF()); - if (detail.getSeamAllowance() == true) - { - QPointF pEkv = point->toQPointF(); - pEkv.setX(pEkv.x()+detail.at(i).getMx()); - pEkv.setY(pEkv.y()+detail.at(i).getMy()); - pointsEkv.append(pEkv); - } - } - break; - case (Tool::NodeArc): - { - const VArc *arc = GeometricObject(detail.at(i).getId()); - qreal len1 = GetLengthContour(points, arc->GetPoints()); - qreal lenReverse = GetLengthContour(points, GetReversePoint(arc->GetPoints())); - if (len1 <= lenReverse) - { - points << arc->GetPoints(); - if (detail.getSeamAllowance() == true) - { - pointsEkv << biasPoints(arc->GetPoints(), detail.at(i).getMx(), detail.at(i).getMy()); - } - } - else - { - points << GetReversePoint(arc->GetPoints()); - if (detail.getSeamAllowance() == true) - { - pointsEkv << biasPoints(GetReversePoint(arc->GetPoints()), detail.at(i).getMx(), - detail.at(i).getMy()); - } - } - } - break; - case (Tool::NodeSpline): - { - const VSpline *spline = GeometricObject(detail.at(i).getId()); - qreal len1 = GetLengthContour(points, spline->GetPoints()); - qreal lenReverse = GetLengthContour(points, GetReversePoint(spline->GetPoints())); - if (len1 <= lenReverse) - { - points << spline->GetPoints(); - if (detail.getSeamAllowance() == true) - { - pointsEkv << biasPoints(spline->GetPoints(), detail.at(i).getMx(), detail.at(i).getMy()); - } - } - else - { - points << GetReversePoint(spline->GetPoints()); - if (detail.getSeamAllowance() == true) - { - pointsEkv << biasPoints(GetReversePoint(spline->GetPoints()), detail.at(i).getMx(), - detail.at(i).getMy()); - } - } - } - break; - case (Tool::NodeSplinePath): - { - const VSplinePath *splinePath = GeometricObject(detail.at(i).getId()); - qreal len1 = GetLengthContour(points, splinePath->GetPathPoints()); - qreal lenReverse = GetLengthContour(points, GetReversePoint(splinePath->GetPathPoints())); - if (len1 <= lenReverse) - { - points << splinePath->GetPathPoints(); - if (detail.getSeamAllowance() == true) - { - pointsEkv << biasPoints(splinePath->GetPathPoints(), detail.at(i).getMx(), detail.at(i).getMy()); - } - } - else - { - points << GetReversePoint(splinePath->GetPathPoints()); - if (detail.getSeamAllowance() == true) - { - pointsEkv << biasPoints(GetReversePoint(splinePath->GetPathPoints()), detail.at(i).getMx(), - detail.at(i).getMy()); - } - } - } - break; - default: - qWarning()<<"Get wrong tool type. Ignore."< VContainer::biasPoints(const QVector &points, const qreal &mx, const qreal &my) -{ - QVector p; - for (qint32 i = 0; i < points.size(); ++i) - { - QPointF point = points.at(i); - point.setX(point.x() + mx); - point.setY(point.y() + my); - p.append(point); - } - return p; -} - -QPainterPath VContainer::Equidistant(QVector points, const Detail::Equidistant &eqv, const qreal &width) -{ - QPainterPath ekv; - QVector ekvPoints; - if ( points.size() < 3 ) - { - qDebug()<<"Not enough points for building the equidistant.\n"; - return ekv; - } - for (qint32 i = 0; i < points.size(); ++i ) - { - if (i != points.size()-1) - { - if (points[i] == points[i+1]) - { - points.remove(i+1); - } - } - else - { - if (points[i] == points[0]) - { - points.remove(i); - } - } - } - if (eqv == Detail::CloseEquidistant) - { - points.append(points.at(0)); - } - for (qint32 i = 0; i < points.size(); ++i ) - { - if ( i == 0 && eqv == Detail::CloseEquidistant) - {//first point, polyline closed - ekvPoints< 0); - QLineF paralel = QLineF (SingleParallelPoint(line, 90, width), SingleParallelPoint(QLineF(line.p2(), line.p1()), - -90, width)); - return paralel; -} - -QPointF VContainer::SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width) -{ - Q_ASSERT(width > 0); - QLineF pLine = line; - pLine.setAngle( pLine.angle() + angle ); - pLine.setLength( width ); - return pLine.p2(); -} - -QVector VContainer::EkvPoint(const QLineF &line1, const QLineF &line2, const qreal &width) -{ - Q_ASSERT(width > 0); - QVector points; - if (line1.p2() != line2.p2()) - { - qWarning()<<"Last point of two lines must be equal."; - } - QPointF CrosPoint; - QLineF bigLine1 = ParallelLine(line1, width ); - QLineF bigLine2 = ParallelLine(QLineF(line2.p2(), line2.p1()), width ); - QLineF::IntersectType type = bigLine1.intersect( bigLine2, &CrosPoint ); - switch (type) - { - case (QLineF::BoundedIntersection): - points.append(CrosPoint); - return points; - break; - case (QLineF::UnboundedIntersection): - { - QLineF line( line1.p2(), CrosPoint ); - if (line.length() > width + toPixel(8)) - { - QLineF lineL; - lineL = QLineF(bigLine1.p2(), CrosPoint); - lineL.setLength(width); - points.append(lineL.p2()); - - lineL = QLineF(bigLine2.p1(), CrosPoint); - lineL.setLength(width); - points.append(lineL.p2()); - } - else - { - points.append(CrosPoint); - return points; - } - break; - } - case (QLineF::NoIntersection): - /*If we have correct lines this means lines lie on a line.*/ - points.append(bigLine1.p2()); - return points; - break; - default: - break; - } - return points; -} - -QVector VContainer::CheckLoops(const QVector &points) -{ - QVector ekvPoints; - /*If we got less than 4 points no need seek loops.*/ - if (points.size() < 4) - { - return ekvPoints; - } - bool closed = false; - if (points.at(0) == points.at(points.size()-1)) - { - closed = true; - } - qint32 i, j; - for (i = 0; i < points.size(); ++i) - { - /*Last three points no need check.*/ - if (i >= points.size()-3) - { - ekvPoints.append(points.at(i)); - continue; - } - QPointF crosPoint; - QLineF::IntersectType intersect = QLineF::NoIntersection; - QLineF line1(points.at(i), points.at(i+1)); - for (j = i+2; j < points.size()-1; ++j) - { - QLineF line2(points.at(j), points.at(j+1)); - intersect = line1.intersect(line2, &crosPoint); - if (intersect == QLineF::BoundedIntersection) - { - break; - } - } - if (intersect == QLineF::BoundedIntersection) - { - if (i == 0 && j+1 == points.size()-1 && closed) - { - /*We got closed contour.*/ - ekvPoints.append(points.at(i)); - } - else - { - /*We found loop.*/ - ekvPoints.append(points.at(i)); - ekvPoints.append(crosPoint); - i = j + 2; - } - } - else - { - /*We did not found loop.*/ - ekvPoints.append(points.at(i)); - } - } - return ekvPoints; -} - -void VContainer::PrepareDetails(QVector &list) const -{ - QHashIterator idetail(details); - while (idetail.hasNext()) - { - idetail.next(); - list.append(new VItem(ContourPath(idetail.key()), list.size())); - } -} - template void VContainer::UpdateObject(QHash &obj, const qint64 &id, val point) { @@ -847,27 +461,3 @@ void VContainer::CreateManTableIGroup () //AddStandardTableCell("Sb", VStandardTableRow(504, 15, 4)); AddStandardTableCell("Sb", VStandardTableRow(492, 15, 5)); } - -QVector VContainer::GetReversePoint(const QVector &points) -{ - Q_ASSERT(points.size() > 0); - QVector reversePoints; - for (qint32 i = points.size() - 1; i >= 0; --i) - { - reversePoints.append(points.at(i)); - } - return reversePoints; -} - -qreal VContainer::GetLengthContour(const QVector &contour, const QVector &newPoints) -{ - qreal length = 0; - QVector points; - points << contour << newPoints; - for (qint32 i = 0; i < points.size()-1; ++i) - { - QLineF line(points.at(i), points.at(i+1)); - length += line.length(); - } - return length; -} diff --git a/src/container/vcontainer.h b/src/container/vcontainer.h index 344f8af65..8d0d25df9 100644 --- a/src/container/vcontainer.h +++ b/src/container/vcontainer.h @@ -375,68 +375,6 @@ public: * @param newId id */ static void UpdateId(qint64 newId); - /** - * @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant. - * @param points list of points equdistant. - * @return corrected list. - */ - static QVector CorrectEquidistantPoints(const QVector &points); - /** - * @brief ContourPath create painter path for detail - * @param idDetail id of detail - * @return return painter path of contour detail - */ - QPainterPath ContourPath(qint64 idDetail) const; - /** - * @brief biasPoints bias point - * @param points vector of points - * @param mx offset respect to x - * @param my offset respect to y - * @return new vector biased points - */ - static QVector biasPoints(const QVector &points, const qreal &mx, const qreal &my); - /** - * @brief Equidistant create equidistant painter path for detail - * @param points vector of points - * @param eqv type of equidistant - * @param width width of equidistant - * @return return painter path of equidistant - */ - static QPainterPath Equidistant(QVector points, const Detail::Equidistant &eqv, const qreal &width); - /** - * @brief ParallelLine create parallel line - * @param line starting line - * @param width width to parallel line - * @return parallel line - */ - static QLineF ParallelLine(const QLineF &line, qreal width ); - /** - * @brief SingleParallelPoint return point of parallel line - * @param line starting line - * @param angle angle in degree - * @param width width to parallel line - * @return point of parallel line - */ - static QPointF SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width); - /** - * @brief EkvPoint return vector of points of equidistant two lines. Last point of two lines must be equal. - * @param line1 first line - * @param line2 second line - * @param width width of equidistant - * @return vector of points - */ - static QVector EkvPoint(const QLineF &line1, const QLineF &line2, const qreal &width); - /** - * @brief CheckLoops seek and delete loops in equidistant - * @param points vector of points of equidistant - * @return vector of points of equidistant - */ - static QVector CheckLoops(const QVector &points); - /** - * @brief PrepareDetails prepare detail for creation layout - * @param list list of details - */ - void PrepareDetails(QVector & list) const; /** * @brief CreateManTableIGroup generate man standard table of measurements */ @@ -482,19 +420,6 @@ private: * @brief details container of details */ QHash details; - /** - * @brief GetReversePoint return revers container of points - * @param points container with points - * @return reverced points - */ - static QVector GetReversePoint(const QVector &points); - /** - * @brief GetLengthContour return length of contour - * @param contour container with points of contour - * @param newPoints point whos we try to add to contour - * @return length length of contour - */ - static qreal GetLengthContour(const QVector &contour, const QVector &newPoints); template /** * @brief GetObject return object from container diff --git a/src/geometry/geometry.pri b/src/geometry/geometry.pri index 6d6a337ed..40815e6cf 100644 --- a/src/geometry/geometry.pri +++ b/src/geometry/geometry.pri @@ -6,7 +6,8 @@ HEADERS += \ src/geometry/vdetail.h \ src/geometry/varc.h \ src/geometry/vgobject.h \ - src/geometry/vpointf.h + src/geometry/vpointf.h \ + src/geometry/vequidistant.h SOURCES += \ src/geometry/vsplinepoint.cpp \ @@ -16,4 +17,5 @@ SOURCES += \ src/geometry/vdetail.cpp \ src/geometry/varc.cpp \ src/geometry/vgobject.cpp \ - src/geometry/vpointf.cpp + src/geometry/vpointf.cpp \ + src/geometry/vequidistant.cpp diff --git a/src/geometry/vequidistant.cpp b/src/geometry/vequidistant.cpp new file mode 100644 index 000000000..539dc009d --- /dev/null +++ b/src/geometry/vequidistant.cpp @@ -0,0 +1,431 @@ +/************************************************************************ + ** + ** @file vequidistant.cpp + ** @author Roman Telezhinsky + ** @date 28 1, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vequidistant.h" + +QPainterPath VEquidistant::ContourPath(const qint64 &idDetail, const VContainer *data) const +{ + Q_ASSERT(data != 0); + VDetail detail = data->GetDetail(idDetail); + QVector points; + QVector pointsEkv; + for (ptrdiff_t i = 0; i< detail.CountNode(); ++i) + { + switch (detail.at(i).getTypeTool()) + { + case (Tool::NodePoint): + { + const VPointF *point = data->GeometricObject(detail.at(i).getId()); + points.append(point->toQPointF()); + if (detail.getSeamAllowance() == true) + { + QPointF pEkv = point->toQPointF(); + pEkv.setX(pEkv.x()+detail.at(i).getMx()); + pEkv.setY(pEkv.y()+detail.at(i).getMy()); + pointsEkv.append(pEkv); + } + } + break; + case (Tool::NodeArc): + { + const VArc *arc = data->GeometricObject(detail.at(i).getId()); + qreal len1 = GetLengthContour(points, arc->GetPoints()); + qreal lenReverse = GetLengthContour(points, GetReversePoint(arc->GetPoints())); + if (len1 <= lenReverse) + { + points << arc->GetPoints(); + if (detail.getSeamAllowance() == true) + { + pointsEkv << biasPoints(arc->GetPoints(), detail.at(i).getMx(), detail.at(i).getMy()); + } + } + else + { + points << GetReversePoint(arc->GetPoints()); + if (detail.getSeamAllowance() == true) + { + pointsEkv << biasPoints(GetReversePoint(arc->GetPoints()), detail.at(i).getMx(), + detail.at(i).getMy()); + } + } + } + break; + case (Tool::NodeSpline): + { + const VSpline *spline = data->GeometricObject(detail.at(i).getId()); + qreal len1 = GetLengthContour(points, spline->GetPoints()); + qreal lenReverse = GetLengthContour(points, GetReversePoint(spline->GetPoints())); + if (len1 <= lenReverse) + { + points << spline->GetPoints(); + if (detail.getSeamAllowance() == true) + { + pointsEkv << biasPoints(spline->GetPoints(), detail.at(i).getMx(), detail.at(i).getMy()); + } + } + else + { + points << GetReversePoint(spline->GetPoints()); + if (detail.getSeamAllowance() == true) + { + pointsEkv << biasPoints(GetReversePoint(spline->GetPoints()), detail.at(i).getMx(), + detail.at(i).getMy()); + } + } + } + break; + case (Tool::NodeSplinePath): + { + const VSplinePath *splinePath = data->GeometricObject(detail.at(i).getId()); + qreal len1 = GetLengthContour(points, splinePath->GetPathPoints()); + qreal lenReverse = GetLengthContour(points, GetReversePoint(splinePath->GetPathPoints())); + if (len1 <= lenReverse) + { + points << splinePath->GetPathPoints(); + if (detail.getSeamAllowance() == true) + { + pointsEkv << biasPoints(splinePath->GetPathPoints(), detail.at(i).getMx(), detail.at(i).getMy()); + } + } + else + { + points << GetReversePoint(splinePath->GetPathPoints()); + if (detail.getSeamAllowance() == true) + { + pointsEkv << biasPoints(GetReversePoint(splinePath->GetPathPoints()), detail.at(i).getMx(), + detail.at(i).getMy()); + } + } + } + break; + default: + qWarning()<<"Get wrong tool type. Ignore."< &contour, const QVector &newPoints) const +{ + qreal length = 0; + QVector points; + points << contour << newPoints; + for (qint32 i = 0; i < points.size()-1; ++i) + { + QLineF line(points.at(i), points.at(i+1)); + length += line.length(); + } + return length; +} + +QVector VEquidistant::biasPoints(const QVector &points, const qreal &mx, const qreal &my) const +{ + QVector p; + for (qint32 i = 0; i < points.size(); ++i) + { + QPointF point = points.at(i); + point.setX(point.x() + mx); + point.setY(point.y() + my); + p.append(point); + } + return p; +} + +QVector VEquidistant::CorrectEquidistantPoints(const QVector &points) const +{ + QVector correctPoints; + if (points.size()<4)//Better don't check if only three points. We can destroy equidistant. + { + qWarning()<<"Only three points."; + return points; + } + //Clear equivalent points + for (qint32 i = 0; i points, const Detail::Equidistant &eqv, + const qreal &width) const +{ + QPainterPath ekv; + QVector ekvPoints; + if ( points.size() < 3 ) + { + qDebug()<<"Not enough points for building the equidistant.\n"; + return ekv; + } + for (qint32 i = 0; i < points.size(); ++i ) + { + if (i != points.size()-1) + { + if (points[i] == points[i+1]) + { + points.remove(i+1); + } + } + else + { + if (points[i] == points[0]) + { + points.remove(i); + } + } + } + if (eqv == Detail::CloseEquidistant) + { + points.append(points.at(0)); + } + for (qint32 i = 0; i < points.size(); ++i ) + { + if ( i == 0 && eqv == Detail::CloseEquidistant) + {//first point, polyline closed + ekvPoints< VEquidistant::CheckLoops(const QVector &points) const +{ + QVector ekvPoints; + /*If we got less than 4 points no need seek loops.*/ + if (points.size() < 4) + { + return ekvPoints; + } + bool closed = false; + if (points.at(0) == points.at(points.size()-1)) + { + closed = true; + } + qint32 i, j; + for (i = 0; i < points.size(); ++i) + { + /*Last three points no need check.*/ + if (i >= points.size()-3) + { + ekvPoints.append(points.at(i)); + continue; + } + QPointF crosPoint; + QLineF::IntersectType intersect = QLineF::NoIntersection; + QLineF line1(points.at(i), points.at(i+1)); + for (j = i+2; j < points.size()-1; ++j) + { + QLineF line2(points.at(j), points.at(j+1)); + intersect = line1.intersect(line2, &crosPoint); + if (intersect == QLineF::BoundedIntersection) + { + break; + } + } + if (intersect == QLineF::BoundedIntersection) + { + if (i == 0 && j+1 == points.size()-1 && closed) + { + /*We got closed contour.*/ + ekvPoints.append(points.at(i)); + } + else + { + /*We found loop.*/ + ekvPoints.append(points.at(i)); + ekvPoints.append(crosPoint); + i = j + 2; + } + } + else + { + /*We did not found loop.*/ + ekvPoints.append(points.at(i)); + } + } + return ekvPoints; +} + +QVector VEquidistant::GetReversePoint(const QVector &points) const +{ + Q_ASSERT(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) const +{ + Q_ASSERT(width > 0); + QVector points; + if (line1.p2() != line2.p2()) + { + qWarning()<<"Last point of two lines must be equal."; + } + QPointF CrosPoint; + QLineF bigLine1 = ParallelLine(line1, width ); + QLineF bigLine2 = ParallelLine(QLineF(line2.p2(), line2.p1()), width ); + QLineF::IntersectType type = bigLine1.intersect( bigLine2, &CrosPoint ); + switch (type) + { + case (QLineF::BoundedIntersection): + points.append(CrosPoint); + return points; + break; + case (QLineF::UnboundedIntersection): + { + QLineF line( line1.p2(), CrosPoint ); + if (line.length() > width + toPixel(8)) + { + QLineF lineL = QLineF(bigLine1.p2(), CrosPoint); + lineL.setLength(width); + points.append(lineL.p2()); + + lineL = QLineF(bigLine2.p1(), CrosPoint); + lineL.setLength(width); + points.append(lineL.p2()); + } + else + { + points.append(CrosPoint); + return points; + } + break; + } + case (QLineF::NoIntersection): + /*If we have correct lines this means lines lie on a line.*/ + points.append(bigLine1.p2()); + return points; + break; + default: + break; + } + return points; +} + +QLineF VEquidistant::ParallelLine(const QLineF &line, qreal width) const +{ + Q_ASSERT(width > 0); + QLineF paralel = QLineF (SingleParallelPoint(line, 90, width), SingleParallelPoint(QLineF(line.p2(), line.p1()), + -90, width)); + return paralel; +} + +QPointF VEquidistant::SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width) const +{ + Q_ASSERT(width > 0); + QLineF pLine = line; + pLine.setAngle( pLine.angle() + angle ); + pLine.setLength( width ); + return pLine.p2(); +} diff --git a/src/geometry/vequidistant.h b/src/geometry/vequidistant.h new file mode 100644 index 000000000..a35ab3a83 --- /dev/null +++ b/src/geometry/vequidistant.h @@ -0,0 +1,115 @@ +/************************************************************************ + ** + ** @file vequidistant.h + ** @author Roman Telezhinsky + ** @date 28 1, 2014 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VEQUIDISTANT_H +#define VEQUIDISTANT_H + +#include +#include "../container/vcontainer.h" + +/** + * @brief The VEquidistant class calculate equidistant for detail. + */ +class VEquidistant +{ +public: + /** + * @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 qint64 &idDetail, const VContainer *data) const; +private: + /** + * @brief GetLengthContour return length of contour. + * @param contour container with points of contour. + * @param newPoints point whos we try to add to contour. + * @return length length of contour. + */ + qreal GetLengthContour(const QVector &contour, const QVector &newPoints) const; + /** + * @brief biasPoints bias point. + * @param points vector of points. + * @param mx offset respect to x. + * @param my offset respect to y. + * @return new vector biased points. + */ + QVector biasPoints(const QVector &points, const qreal &mx, const qreal &my) const; + /** + * @brief CorrectEquidistantPoints clear equivalent points and remove point on line from equdistant. + * @param points list of points equdistant. + * @return corrected list. + */ + QVector CorrectEquidistantPoints(const QVector &points) const; + /** + * @brief Equidistant create equidistant painter path for detail. + * @param points vector of points. + * @param eqv type of equidistant. + * @param width width of equidistant. + * @return return painter path of equidistant. + */ + QPainterPath Equidistant(QVector points, const Detail::Equidistant &eqv, const qreal &width) const; + /** + * @brief CheckLoops seek and delete loops in equidistant. + * @param points vector of points of equidistant. + * @return vector of points of equidistant. + */ + QVector CheckLoops(const QVector &points) const; + /** + * @brief GetReversePoint return revers container of points. + * @param points container with points. + * @return reverced points. + */ + QVector GetReversePoint(const QVector &points) const; + /** + * @brief EkvPoint return vector of points of equidistant two lines. Last point of two lines must be equal. + * @param line1 first line. + * @param line2 second line. + * @param width width of equidistant. + * @return vector of points. + */ + QVector EkvPoint(const QLineF &line1, const QLineF &line2, const qreal &width) const; + /** + * @brief ParallelLine create parallel line. + * @param line starting line. + * @param width width to parallel line. + * @return parallel line. + */ + QLineF ParallelLine(const QLineF &line, qreal width ) const; + /** + * @brief SingleParallelPoint return point of parallel line. + * @param line starting line. + * @param angle angle in degree. + * @param width width to parallel line. + * @return point of parallel line. + */ + QPointF SingleParallelPoint(const QLineF &line, const qreal &angle, const qreal &width) const; +}; + +#endif // VEQUIDISTANT_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 47a15daa6..8a562d87e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -29,6 +29,7 @@ #include "mainwindow.h" #include "ui_mainwindow.h" #include "geometry/vspline.h" +#include "geometry/vequidistant.h" #include "exception/vexceptionobjecterror.h" #include "exception/vexceptionconversionerror.h" #include "exception/vexceptionemptyparameter.h" @@ -1177,7 +1178,14 @@ void MainWindow::ActionLayout(bool checked) Q_UNUSED(checked); hide(); QVector listDetails; - pattern->PrepareDetails(listDetails); + const QHash *details = pattern->DataDetails(); + QHashIterator idetail(*details); + while (idetail.hasNext()) + { + idetail.next(); + QPainterPath path = VEquidistant().ContourPath(idetail.key(), pattern); + listDetails.append(new VItem(path, listDetails.size())); + } emit ModelChosen(listDetails, fileName); } diff --git a/src/tools/vtooldetail.cpp b/src/tools/vtooldetail.cpp index 0a8632066..bab623d8b 100644 --- a/src/tools/vtooldetail.cpp +++ b/src/tools/vtooldetail.cpp @@ -28,6 +28,7 @@ #include "vtooldetail.h" #include "nodeDetails/nodedetails.h" +#include "../geometry/vequidistant.h" const QString VToolDetail::TagName = QStringLiteral("detail"); const QString VToolDetail::TagNode = QStringLiteral("node"); @@ -380,7 +381,7 @@ void VToolDetail::AddNode(QDomElement &domElement, const VNodeDetail &node) void VToolDetail::RefreshGeometry() { - QPainterPath path = VAbstractTool::data.ContourPath(id); + QPainterPath path = VEquidistant().ContourPath(id, this->getData()); this->setPath(path); } diff --git a/src/tools/vtooluniondetails.cpp b/src/tools/vtooluniondetails.cpp index 550fd3708..834763205 100644 --- a/src/tools/vtooluniondetails.cpp +++ b/src/tools/vtooluniondetails.cpp @@ -607,7 +607,7 @@ void VToolUnionDetails::Create(const qint64 _id, const VDetail &d1, const VDetai ++j; } while (pointsD2 < nD2); } - } while(i