diff --git a/ChangeLog.txt b/ChangeLog.txt index c11e25937..7819c4515 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -4,6 +4,7 @@ - [#485] Error when drawing a curved path. - [#491] Valentina doesn't update fractional separator. - [#492] Valentina crashes when add an increment. +- [#493] Error in seam allowance drawing. # Version 0.4.4 April 12, 2016 - Updated measurement templates with all measurements. Added new template Aldrich/Women measurements. diff --git a/src/app/share/collection/bugs/Issue_#493.val b/src/app/share/collection/bugs/Issue_#493.val new file mode 100644 index 000000000..2ed081c1f --- /dev/null +++ b/src/app/share/collection/bugs/Issue_#493.val @@ -0,0 +1,100 @@ + + + + 0.2.4 + mm + + + + Issue_#493.vit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
diff --git a/src/app/share/collection/bugs/Issue_#493.vit b/src/app/share/collection/bugs/Issue_#493.vit new file mode 100644 index 000000000..77927926c --- /dev/null +++ b/src/app/share/collection/bugs/Issue_#493.vit @@ -0,0 +1,73 @@ + + + + 0.3.3 + false + + mm + 998 + + + + 1800-01-01 + female + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/vgeometry/vgobject.cpp b/src/libs/vgeometry/vgobject.cpp index ab25ae179..b67bdee4e 100644 --- a/src/libs/vgeometry/vgobject.cpp +++ b/src/libs/vgeometry/vgobject.cpp @@ -505,7 +505,7 @@ double VGObject::GetEpsilon(const QPointF &p1, const QPointF &p2) { const double dx1 = p2.x() - p1.x(); const double dy1 = p2.y() - p1.y(); - const double epsilon = 0.03 * (dx1 * dx1 + dy1 * dy1); //-V636 + const double epsilon = 0.06 * (dx1 * dx1 + dy1 * dy1); //-V636 return epsilon; } diff --git a/src/libs/vgeometry/vgobject.h b/src/libs/vgeometry/vgobject.h index bd58c4170..99ea48418 100644 --- a/src/libs/vgeometry/vgobject.h +++ b/src/libs/vgeometry/vgobject.h @@ -85,13 +85,13 @@ public: 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 IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2); + static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2); static QVector GetReversePoints(const QVector &points); static int GetLengthContour(const QVector &contour, const QVector &newPoints); private: QSharedDataPointer d; - static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2); static double PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t); static double GetEpsilon(const QPointF &p1, const QPointF &p2); diff --git a/src/libs/vlayout/vabstractdetail.cpp b/src/libs/vlayout/vabstractdetail.cpp index 3e65dafe2..c820722d1 100644 --- a/src/libs/vlayout/vabstractdetail.cpp +++ b/src/libs/vlayout/vabstractdetail.cpp @@ -29,6 +29,8 @@ #include "vabstractdetail.h" #include "vabstractdetail_p.h" +#include "../vgeometry/vgobject.h" + #include #include #include @@ -327,37 +329,83 @@ QVector VAbstractDetail::CheckLoops(const QVector &points) continue; } + enum LoopIntersectType { NoIntersection, BoundedIntersection, ParallelIntersection }; + QPointF crosPoint; - QLineF::IntersectType intersect = QLineF::NoIntersection; + LoopIntersectType status = NoIntersection; const QLineF line1(points.at(i), points.at(i+1)); // Because a path can contains several loops we will seek the last and only then remove the loop(s) // That's why we parse from the end for (j = count-2; j >= i+2; --j) { const QLineF line2(points.at(j), points.at(j+1)); - intersect = line1.intersect(line2, &crosPoint); - if (intersect == QLineF::BoundedIntersection && not (i == 0 && j+1 == count-1 && closed)) + const QLineF::IntersectType intersect = line1.intersect(line2, &crosPoint); + if (intersect == QLineF::NoIntersection) + { // According to the documentation QLineF::NoIntersection indicates that the lines do not intersect; + // i.e. they are parallel. But parallel also mean they can be on the same line. + // Method IsPointOnLineviaPDP will check it. + if (VGObject::IsPointOnLineviaPDP(points.at(j), points.at(i), points.at(i+1)) + // Next cases are valid for us. + && line1.p2() != line2.p2() + && line1.p1() != line2.p1() + && line1.p2() != line2.p1() + && line1.p1() != line2.p2()) + { + // Left to catch case where segments are on the same line, but do not have real intersections. + QLineF tmpLine1 = line1; + QLineF tmpLine2 = line2; + + tmpLine1.setAngle(tmpLine1.angle()+90); + + QPointF tmpCrosPoint; + const QLineF::IntersectType tmpIntrs1 = tmpLine1.intersect(tmpLine2, &tmpCrosPoint); + + tmpLine1 = line1; + tmpLine2.setAngle(tmpLine2.angle()+90); + + const QLineF::IntersectType tmpIntrs2 = tmpLine1.intersect(tmpLine2, &tmpCrosPoint); + + if (tmpIntrs1 == QLineF::BoundedIntersection || tmpIntrs2 == QLineF::BoundedIntersection) + { // Now we really sure that lines are on the same lines and have real intersections. + status = ParallelIntersection; + break; + } + } + } + else if (intersect == QLineF::BoundedIntersection && not (i == 0 && j+1 == count-1 && closed)) { // Break, but not if intersects the first edge and the last edge in closed path if (line1.p1() != crosPoint && line1.p2() != crosPoint && line2.p1() != crosPoint && line2.p2() != crosPoint) { // Break, but not if loop creates crosPoint when it is first or last point of lines + status = BoundedIntersection; break; } } - intersect = QLineF::NoIntersection; + status = NoIntersection; } - if (intersect == QLineF::BoundedIntersection) + switch (status) { - /*We have found loop.*/ - ekvPoints.append(points.at(i)); - ekvPoints.append(crosPoint); - i = j; - } - else - { - /*We have not found loop.*/ - ekvPoints.append(points.at(i)); + case ParallelIntersection: + /*We have found a loop.*/ + // Theoretically there is no big difference which point j or j+1 to select. + // In the end we will draw a line in any case. + ekvPoints.append(points.at(i)); + ekvPoints.append(points.at(j+1)); + i = j; + break; + case BoundedIntersection: + /*We have found a loop.*/ + ekvPoints.append(points.at(i)); + ekvPoints.append(crosPoint); + i = j; + break; + case NoIntersection: + /*We have not found loop.*/ + ekvPoints.append(points.at(i)); + break; + default: + break; } } return ekvPoints; diff --git a/src/test/ValentinaTest/tst_vabstractdetail.cpp b/src/test/ValentinaTest/tst_vabstractdetail.cpp index 4b41575ea..ac60b3a81 100644 --- a/src/test/ValentinaTest/tst_vabstractdetail.cpp +++ b/src/test/ValentinaTest/tst_vabstractdetail.cpp @@ -199,6 +199,44 @@ void TST_VAbstractDetail::PathRemoveLoop_data() const path.removeLast(); QTest::newRow("Corect unclosed a path, point on line (six unique points)") << path << path; + + path.clear(); + path << QPointF(100.96979100571033, 1797.6153764073072); + path << QPointF(168.3888427659865, 1807.2395034187866); + path << QPointF(206.78076137364403, 1812.2910842036706); + path << QPointF(239.1630793382262, 1815.951361623424); + path << QPointF(267.5320085054171, 1818.4827543754482); + path << QPointF(293.9502505847841, 1820.144031725603); + path << QPointF(320.48133946750147, 1821.175819320443); + path << QPointF(364.5960626489172, 1822.0507669842166); + path << QPointF(400.66867742260206, 1822.488188976378); + path << QPointF(623.3126833308274, 1822.488188976378); + path << QPointF(653.5489038032683, 2162.6456692913384); + path << QPointF(570.545584385708, 2162.6456692913384); + path << QPointF(600.7818048581489, 1822.488188976378); + path << QPointF(1001.3385826771654, 1822.488188976378); + path << QPointF(1001.3385826771654, 2680.44094488189); + path << QPointF(-22.11646613738226, 2680.44094488189); + path << QPointF(100.96979100571033, 1797.6153764073072); + + res.clear(); + res << QPointF(100.96979100571033, 1797.6153764073072); + res << QPointF(168.3888427659865, 1807.2395034187866); + res << QPointF(206.78076137364403, 1812.2910842036706); + res << QPointF(239.1630793382262, 1815.951361623424); + res << QPointF(267.5320085054171, 1818.4827543754482); + res << QPointF(293.9502505847841, 1820.144031725603); + res << QPointF(320.48133946750147, 1821.175819320443); + res << QPointF(364.5960626489172, 1822.0507669842166); + res << QPointF(400.66867742260206, 1822.488188976378); + res << QPointF(1001.3385826771654, 1822.488188976378); + res << QPointF(1001.3385826771654, 1822.488188976378); + res << QPointF(1001.3385826771654, 2680.44094488189); + res << QPointF(-22.11646613738226, 2680.44094488189); + res << QPointF(100.96979100571033, 1797.6153764073072); + + // See the file "collection/bugs/Issue_#493.val" + QTest::newRow("Test case issue #493") << path << res; } //---------------------------------------------------------------------------------------------------------------------