diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2014-05-25 11:16:00 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2014-05-25 14:47:49 +0400 |
commit | 08528f577dcb47f570413ce600137f3729a35d94 (patch) | |
tree | 6a3a3b792795383fb9180ec7c730eca2b050bbbf /source/blender | |
parent | aef443ab2d27a79160cca0588bc221457572cead (diff) |
Freestyle: Partial fix for thinning strokes due to flipping stroke directions at TVertices.
A description of the problem is found in https://developer.blender.org/T36425#19 .
The cause of the issue was identified as roudning errors in Operators::createStroke() due
to insufficient numerical precision. Precision promotion from float to double was done in
the return values of getPoint3D/2D methods in Interface0D and its subclasses in C++
(data members stored in the 0D classes have already been in double precision).
Diffstat (limited to 'source/blender')
7 files changed, 33 insertions, 32 deletions
diff --git a/source/blender/freestyle/intern/stroke/Curve.h b/source/blender/freestyle/intern/stroke/Curve.h index 17b9a5c0a1f..6b799c921a4 100644 --- a/source/blender/freestyle/intern/stroke/Curve.h +++ b/source/blender/freestyle/intern/stroke/Curve.h @@ -95,7 +95,7 @@ public: // Implementation of Interface0D } /*! Returns the 3D point. */ - virtual Vec3f getPoint3D() const + virtual Vec3r getPoint3D() const { return _Point3d; } @@ -119,9 +119,9 @@ public: // Implementation of Interface0D } /*! Returns the 2D point. */ - virtual Vec2f getPoint2D() const + virtual Vec2r getPoint2D() const { - return Vec2f((float)_Point2d.x(), (float)_Point2d.y()); + return Vec2r(_Point2d.x(), _Point2d.y()); } virtual FEdge *getFEdge(Interface0D& inter); diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp index 2e68aa0c1fa..2f05413fcbe 100644 --- a/source/blender/freestyle/intern/stroke/Operators.cpp +++ b/source/blender/freestyle/intern/stroke/Operators.cpp @@ -32,6 +32,7 @@ #include "Operators.h" #include "Canvas.h" #include "Stroke.h" +#include "StrokeIterators.h" #include "CurveIterators.h" #include "BKE_global.h" @@ -1092,20 +1093,20 @@ static Stroke *createStroke(Interface1D& inter) if (hasSingularity) { // Try to address singular points such that the distance between two subsequent vertices // are smaller than epsilon. - Interface0DIterator v = stroke->verticesBegin(); - Interface0DIterator vnext = v; + StrokeInternal::StrokeVertexIterator v = stroke->strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator vnext = v; ++vnext; - Vec2r next((*v).getPoint2D()); + Vec2r next((*v).getPoint()); while (!vnext.isEnd()) { current = next; - next = (*vnext).getPoint2D(); + next = (*vnext).getPoint(); if ((next - current).norm() < 1.0e-6) { - Interface0DIterator vprevious = v; + StrokeInternal::StrokeVertexIterator vprevious = v; if (!vprevious.isBegin()) --vprevious; // collect a set of overlapping vertices - std::vector<Interface0D *> overlapping_vertices; + std::vector<StrokeVertex *> overlapping_vertices; overlapping_vertices.push_back(&(*v)); do { overlapping_vertices.push_back(&(*vnext)); @@ -1114,17 +1115,17 @@ static Stroke *createStroke(Interface1D& inter) ++vnext; if (vnext.isEnd()) break; - next = (*vnext).getPoint2D(); + next = (*vnext).getPoint(); } while ((next - current).norm() < 1.0e-6); Vec2r target; bool reverse; if (!vnext.isEnd()) { - target = (*vnext).getPoint2D(); + target = (*vnext).getPoint(); reverse = false; } else if (!vprevious.isBegin()) { - target = (*vprevious).getPoint2D(); + target = (*vprevious).getPoint(); reverse = true; } else { @@ -1132,7 +1133,7 @@ static Stroke *createStroke(Interface1D& inter) delete stroke; return NULL; } - current = overlapping_vertices.front()->getPoint2D(); + current = overlapping_vertices.front()->getPoint(); Vec2r dir(target - current); real dist = dir.norm(); real len = 1.0e-3; // default offset length @@ -1144,10 +1145,10 @@ static Stroke *createStroke(Interface1D& inter) Vec2r offset(dir * len); // add the offset to the overlapping vertices StrokeVertex *sv; - std::vector<Interface0D *>::iterator it = overlapping_vertices.begin(); + std::vector<StrokeVertex *>::iterator it = overlapping_vertices.begin(); if (!reverse) { for (int n = 1; n < nvert; n++) { - sv = dynamic_cast<StrokeVertex*>(*it); + sv = (*it); sv->setPoint(sv->getPoint() + offset * n); ++it; } @@ -1155,7 +1156,7 @@ static Stroke *createStroke(Interface1D& inter) else { int last = nvert - 1; for (int n = 0; n < last; n++) { - sv = dynamic_cast<StrokeVertex*>(*it); + sv = (*it); sv->setPoint(sv->getPoint() + offset * (last - n)); ++it; } diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h index f6451d8e487..5e6c2fcf6cb 100644 --- a/source/blender/freestyle/intern/stroke/Stroke.h +++ b/source/blender/freestyle/intern/stroke/Stroke.h @@ -375,14 +375,14 @@ public: return _Point2d[1]; } - /*! Returns the 2D point coordinates as a Vec2d */ - Vec2f getPoint () + /*! Returns the 2D point coordinates as a Vec2r */ + inline Vec2r getPoint() const { - return Vec2f((float)point2d()[0], (float)point2d()[1]); + return getPoint2D(); } /*! Returns the ith 2D point coordinate (i=0 or 1)*/ - inline real operator[](const int i) const + inline real operator[](const int i) const { return _Point2d[i]; } @@ -438,7 +438,7 @@ public: } /*! sets the 2D x and y values */ - inline void setPoint(const Vec2f& p) + inline void setPoint(const Vec2r& p) { _Point2d[0] = p[0]; _Point2d[1] = p[1]; diff --git a/source/blender/freestyle/intern/view_map/Interface0D.cpp b/source/blender/freestyle/intern/view_map/Interface0D.cpp index 135a935d2fe..1d8515700d3 100644 --- a/source/blender/freestyle/intern/view_map/Interface0D.cpp +++ b/source/blender/freestyle/intern/view_map/Interface0D.cpp @@ -48,7 +48,7 @@ real Interface0D::getZ() const return 0; } -Geometry::Vec3f Interface0D::getPoint3D() const +Geometry::Vec3r Interface0D::getPoint3D() const { PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden"); return 0; @@ -72,7 +72,7 @@ real Interface0D::getProjectedZ() const return 0; } -Geometry::Vec2f Interface0D::getPoint2D() const +Geometry::Vec2r Interface0D::getPoint2D() const { PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden"); return 0; diff --git a/source/blender/freestyle/intern/view_map/Interface0D.h b/source/blender/freestyle/intern/view_map/Interface0D.h index e59ed4c96c8..123253bf3e1 100644 --- a/source/blender/freestyle/intern/view_map/Interface0D.h +++ b/source/blender/freestyle/intern/view_map/Interface0D.h @@ -86,7 +86,7 @@ public: virtual real getZ() const; /*! Returns the 3D point. */ - virtual Geometry::Vec3f getPoint3D() const; + virtual Geometry::Vec3r getPoint3D() const; /*! Returns the 2D x coordinate of the point. */ virtual real getProjectedX() const; @@ -98,7 +98,7 @@ public: virtual real getProjectedZ() const; /*! Returns the 2D point. */ - virtual Geometry::Vec2f getPoint2D() const; + virtual Geometry::Vec2r getPoint2D() const; /*! Returns the FEdge that lies between this Interface0D and the Interface0D given as argument. */ virtual FEdge *getFEdge(Interface0D&); diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h index e747f9c3e68..2d0acde3f2b 100644 --- a/source/blender/freestyle/intern/view_map/Silhouette.h +++ b/source/blender/freestyle/intern/view_map/Silhouette.h @@ -103,7 +103,7 @@ public: // Implementation of Interface0D } /*! Returns the 3D point. */ - virtual Vec3f getPoint3D() const + virtual Vec3r getPoint3D() const { return _Point3D; } @@ -127,9 +127,9 @@ public: // Implementation of Interface0D } /*! Returns the 2D point. */ - virtual Vec2f getPoint2D() const + virtual Vec2r getPoint2D() const { - return Vec2f((float)_Point2D.x(), (float)_Point2D.y()); + return Vec2f(_Point2D.x(), _Point2D.y()); } /*! Returns the FEdge that lies between this Svertex and the Interface0D given as argument. */ diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h index eeaeada5dc6..d87341503fa 100644 --- a/source/blender/freestyle/intern/view_map/ViewMap.h +++ b/source/blender/freestyle/intern/view_map/ViewMap.h @@ -419,7 +419,7 @@ public: // Implementation of Interface0D } /*! Returns the 3D point. */ - virtual Vec3f getPoint3D() const + virtual Vec3r getPoint3D() const { cerr << "Warning: getPoint3D() undefined for this point" << endl; return _FrontSVertex->getPoint3D(); @@ -443,7 +443,7 @@ public: // Implementation of Interface0D } /*! Returns the 2D point. */ - virtual Vec2f getPoint2D() const + virtual Vec2r getPoint2D() const { return _FrontSVertex->getPoint2D(); } @@ -692,7 +692,7 @@ public: // Implementation of Interface0D } /*! Returns the 3D point. */ - virtual Vec3f getPoint3D() const + virtual Vec3r getPoint3D() const { return _SVertex->getPoint3D(); } @@ -716,7 +716,7 @@ public: // Implementation of Interface0D } /*! Returns the 2D point. */ - virtual Vec2f getPoint2D() const + virtual Vec2r getPoint2D() const { return _SVertex->getPoint2D(); } |