Revision: 6827
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6827&view=rev
Author:   mdboom
Date:     2009-01-26 14:32:42 +0000 (Mon, 26 Jan 2009)

Log Message:
-----------
Make curves and NaNs play nice together

Modified Paths:
--------------
    branches/v0_98_5_maint/CHANGELOG
    branches/v0_98_5_maint/lib/matplotlib/patches.py
    branches/v0_98_5_maint/lib/matplotlib/path.py
    branches/v0_98_5_maint/src/agg_py_path_iterator.h

Modified: branches/v0_98_5_maint/CHANGELOG
===================================================================
--- branches/v0_98_5_maint/CHANGELOG    2009-01-25 14:38:48 UTC (rev 6826)
+++ branches/v0_98_5_maint/CHANGELOG    2009-01-26 14:32:42 UTC (rev 6827)
@@ -1,3 +1,5 @@
+2009-01-26 Make curves and NaNs play nice together - MGD
+
 2009-01-19 Fix bug in quiver argument handling. - EF
 
 2009-01-19 Fix bug in backend_gtk: don't delete nonexistent toolbar. - EF

Modified: branches/v0_98_5_maint/lib/matplotlib/patches.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/patches.py    2009-01-25 14:38:48 UTC 
(rev 6826)
+++ branches/v0_98_5_maint/lib/matplotlib/patches.py    2009-01-26 14:32:42 UTC 
(rev 6827)
@@ -298,8 +298,7 @@
         tpath = transform.transform_path_non_affine(path)
         affine = transform.get_affine()
 
-        if not np.isnan(tpath.vertices).any():
-            renderer.draw_path(gc, tpath, affine, rgbFace)
+        renderer.draw_path(gc, tpath, affine, rgbFace)
 
         #renderer.close_group('patch')
 

Modified: branches/v0_98_5_maint/lib/matplotlib/path.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/path.py       2009-01-25 14:38:48 UTC 
(rev 6826)
+++ branches/v0_98_5_maint/lib/matplotlib/path.py       2009-01-26 14:32:42 UTC 
(rev 6827)
@@ -214,7 +214,8 @@
                     if not isfinite(curr_vertices).all():
                         was_nan = True
                     elif was_nan:
-                        yield curr_vertices[-2:], MOVETO
+                        yield curr_vertices[:2], MOVETO
+                        yield curr_vertices, code
                         was_nan = False
                     else:
                         yield curr_vertices, code

Modified: branches/v0_98_5_maint/src/agg_py_path_iterator.h
===================================================================
--- branches/v0_98_5_maint/src/agg_py_path_iterator.h   2009-01-25 14:38:48 UTC 
(rev 6826)
+++ branches/v0_98_5_maint/src/agg_py_path_iterator.h   2009-01-26 14:32:42 UTC 
(rev 6827)
@@ -15,7 +15,10 @@
     PyArrayObject* m_codes;
     size_t m_iterator;
     size_t m_total_vertices;
+    size_t m_ok;
     bool m_should_simplify;
+    static const unsigned char num_extra_points_map[16];
+    static const unsigned code_map[];
 
 public:
     PathIterator(const Py::Object& path_obj) :
@@ -41,6 +44,7 @@
                 throw Py::ValueError("Invalid codes array.");
             if (PyArray_DIM(m_codes, 0) != PyArray_DIM(m_vertices, 0))
                 throw Py::ValueError("Codes array is wrong length");
+            m_ok = 0;
         }
 
         m_should_simplify = should_simplify_obj.isTrue();
@@ -53,8 +57,6 @@
         Py_XDECREF(m_codes);
     }
 
-    static const unsigned code_map[];
-
 private:
     inline void vertex(const unsigned idx, double* x, double* y)
     {
@@ -82,20 +84,86 @@
         if (m_iterator >= m_total_vertices) return agg::path_cmd_stop;
         unsigned code = vertex_with_code(m_iterator++, x, y);
 
-        if (MPL_notisfinite64(*x) || MPL_notisfinite64(*y))
-        {
-            do
+        if (!m_codes) {
+            // This is the fast path for when we know we have no curves
+            if (MPL_notisfinite64(*x) || MPL_notisfinite64(*y))
             {
-                if (m_iterator < m_total_vertices)
+                do
                 {
-                    vertex(m_iterator++, x, y);
+                    if (m_iterator < m_total_vertices)
+                    {
+                        vertex(m_iterator++, x, y);
+                    }
+                    else
+                    {
+                        return agg::path_cmd_stop;
+                    }
+                } while (MPL_notisfinite64(*x) || MPL_notisfinite64(*y));
+                return agg::path_cmd_move_to;
+            }
+        }
+        else
+        {
+            // This is the slow method for when there might be curves.
+
+            /* If m_ok is 0, we look ahead to see if the next curve
+               segment has any NaNs.  If it does, we skip the whole
+               thing and return a move_to to the first point of the
+               next curve segment.  This move_to may include NaNs,
+               which is ok, since in that case, it will always be
+               followed by another non-NaN move_to before any other
+               curves are actually drawn.  If the current curve
+               segment doesn't have NaNs, we set the m_ok counter to
+               the number of points in the curve segment, which will
+               skip this check for the next N points.
+            */
+            if (m_ok == 0) {
+                if (code == agg::path_cmd_stop ||
+                    code == (agg::path_cmd_end_poly | agg::path_flags_close))
+                {
+                    return code;
                 }
-                else
+
+                size_t num_extra_points = num_extra_points_map[code & 0xF];
+                bool has_nan = (MPL_notisfinite64(*x) || 
MPL_notisfinite64(*y));
+                for (size_t i = 0; !has_nan && i < num_extra_points; ++i)
                 {
-                    return agg::path_cmd_stop;
+                    double x0, y0;
+                    vertex(m_iterator + i, &x0, &y0);
+                    has_nan = (MPL_notisfinite64(x0) || MPL_notisfinite64(y0));
                 }
-            } while (MPL_notisfinite64(*x) || MPL_notisfinite64(*y));
-            return agg::path_cmd_move_to;
+
+                if (has_nan)
+                {
+                    m_iterator += num_extra_points;
+                    if (m_iterator < m_total_vertices)
+                    {
+                        code = vertex_with_code(m_iterator, x, y);
+                        if (code == agg::path_cmd_stop ||
+                            code == (agg::path_cmd_end_poly | 
agg::path_flags_close))
+                        {
+                            return code;
+                        }
+                        else
+                        {
+                            return agg::path_cmd_move_to;
+                        }
+                    }
+                    else
+                    {
+                        return agg::path_cmd_stop;
+                    }
+                }
+                else /* !has_nan */
+                {
+                    m_ok = num_extra_points;
+                    return code;
+                }
+            }
+            else /* m_ok != 0 */
+            {
+                m_ok--;
+            }
         }
 
         return code;
@@ -127,6 +195,12 @@
      agg::path_cmd_end_poly | agg::path_flags_close
     };
 
+const unsigned char PathIterator::num_extra_points_map[] =
+    {0, 0, 0, 1,
+     2, 0, 0, 0,
+     0, 0, 0, 0,
+     0, 0, 0, 0};
+
 #define DEBUG_SIMPLIFY 0
 
 template<class VertexSource>


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to