Revision: 7621
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7621&view=rev
Author:   mdboom
Date:     2009-08-31 20:10:35 +0000 (Mon, 31 Aug 2009)

Log Message:
-----------
Add "draw_gouraud_triangles" (note the 's') backend method.  Add initial 
support in Pdf backend (working in xpdf and evince, but not in acroread, 
strangely).

Modified Paths:
--------------
    trunk/matplotlib/lib/matplotlib/backend_bases.py
    trunk/matplotlib/lib/matplotlib/backends/backend_agg.py
    trunk/matplotlib/lib/matplotlib/backends/backend_mixed.py
    trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
    trunk/matplotlib/lib/matplotlib/collections.py
    trunk/matplotlib/src/_backend_agg.cpp
    trunk/matplotlib/src/_backend_agg.h

Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py    2009-08-31 19:50:13 UTC 
(rev 7620)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py    2009-08-31 20:10:35 UTC 
(rev 7621)
@@ -170,10 +170,31 @@
         """
         Draw a Gouraud-shaded triangle.
 
-        EXPERIMENTAL
+        *points* is a 3x2 array of (x, y) points for the triangle.
+
+        *colors* is a 3x4 array of RGBA colors for each point of the
+        triangle.
+
+        *transform* is an affine transform to apply to the points.
         """
         raise NotImplementedError
 
+    def draw_gouraud_triangles(self, gc, triangles_array, colors_array,
+                               transform):
+        """
+        Draws a series of Gouraud triangles.
+
+        *points* is a Nx3x2 array of (x, y) points for the trianglex.
+
+        *colors* is a Nx3x4 array of RGBA colors for each point of the
+        triangles.
+
+        *transform* is an affine transform to apply to the points.
+        """
+        transform = transform.frozen()
+        for tri, col in zip(triangles_array, colors_array):
+            self.draw_gouraud_triangle(gc, tri, col, transform)
+
     def _iter_collection_raw_paths(self, master_transform, paths,
                                    all_transforms):
         """
@@ -410,7 +431,7 @@
 
     def start_rasterizing(self):
         """
-        Used in MixedModeRenderer. Switch to the raster renderer. 
+        Used in MixedModeRenderer. Switch to the raster renderer.
         """
         pass
 
@@ -425,7 +446,7 @@
     def start_filter(self):
         """
         Used in AggRenderer. Switch to a temporary renderer for image
-        filtering effects. 
+        filtering effects.
         """
         pass
 

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py     2009-08-31 
19:50:13 UTC (rev 7620)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py     2009-08-31 
20:10:35 UTC (rev 7621)
@@ -80,6 +80,7 @@
         self.draw_path_collection = self._renderer.draw_path_collection
         self.draw_quad_mesh = self._renderer.draw_quad_mesh
         self.draw_gouraud_triangle = self._renderer.draw_gouraud_triangle
+        self.draw_gouraud_triangles = self._renderer.draw_gouraud_triangles
         self.draw_image = self._renderer.draw_image
         self.copy_from_bbox = self._renderer.copy_from_bbox
         self.tostring_rgba_minimized = self._renderer.tostring_rgba_minimized

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_mixed.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_mixed.py   2009-08-31 
19:50:13 UTC (rev 7620)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_mixed.py   2009-08-31 
20:10:35 UTC (rev 7621)
@@ -58,7 +58,8 @@
         finalize flipy get_canvas_width_height get_image_magnification
         get_texmanager get_text_width_height_descent new_gc open_group
         option_image_nocomposite points_to_pixels strip_math
-        start_filter stop_filter
+        start_filter stop_filter draw_gouraud_triangle
+        draw_gouraud_triangles
         """.split()
     def _set_current_renderer(self, renderer):
         self._renderer = renderer

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py     2009-08-31 
19:50:13 UTC (rev 7620)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py     2009-08-31 
20:10:35 UTC (rev 7621)
@@ -17,6 +17,7 @@
 from cStringIO import StringIO
 from datetime import datetime
 from math import ceil, cos, floor, pi, sin
+import struct
 try:
     set
 except NameError:
@@ -268,7 +269,7 @@
                gsave='q', grestore='Q',
                textpos='Td', selectfont='Tf', textmatrix='Tm',
                show='Tj', showkern='TJ',
-               setlinewidth='w', clip='W')
+               setlinewidth='w', clip='W', shading='sh')
 
 Op = Bunch(**dict([(name, Operator(value))
                    for name, value in _pdfops.items()]))
@@ -377,6 +378,7 @@
         self.fontObject = self.reserveObject('fonts')
         self.alphaStateObject = self.reserveObject('extended graphics states')
         self.hatchObject = self.reserveObject('tiling patterns')
+        self.gouraudObject = self.reserveObject('Gouraud triangles')
         self.XObjectObject = self.reserveObject('external objects')
         self.resourceObject = self.reserveObject('resources')
 
@@ -403,6 +405,7 @@
         self.nextAlphaState = 1
         self.hatchPatterns = {}
         self.nextHatch = 1
+        self.gouraudTriangles = []
 
         self.images = {}
         self.nextImage = 1
@@ -421,6 +424,7 @@
                       'XObject': self.XObjectObject,
                       'ExtGState': self.alphaStateObject,
                       'Pattern': self.hatchObject,
+                      'Shading': self.gouraudObject,
                       'ProcSet': procsets }
         self.writeObject(self.resourceObject, resources)
 
@@ -452,6 +456,7 @@
                          dict([(val[0], val[1])
                                for val in self.alphaStates.values()]))
         self.writeHatches()
+        self.writeGouraudTriangles()
         xobjects = dict(self.images.values())
         for tup in self.markers.values():
             xobjects[tup[0]] = tup[1]
@@ -1050,6 +1055,44 @@
             self.endStream()
         self.writeObject(self.hatchObject, hatchDict)
 
+    def addGouraudTriangles(self, points, colors):
+        name = Name('GT%d' % len(self.gouraudTriangles))
+        self.gouraudTriangles.append((name, points, colors))
+        return name
+
+    def writeGouraudTriangles(self):
+        gouraudDict = dict()
+        for name, points, colors in self.gouraudTriangles:
+            ob = self.reserveObject('Gouraud triangle')
+            gouraudDict[name] = ob
+            shape = points.shape
+            flat_points = points.reshape((shape[0] * shape[1], 2))
+            points_min = npy.min(flat_points, axis=0) - (1 << 8)
+            points_max = npy.max(flat_points, axis=0) + (1 << 8)
+            factor = float(0xffffffff) / (points_max - points_min)
+            adjpoints = npy.array((points - points_min) * factor, 
dtype=npy.uint32)
+            adjcolors = npy.array(colors * 255.0, dtype=npy.uint8)
+
+            self.beginStream(
+                ob.id, None,
+                { 'ShadingType': 4,
+                  'BitsPerCoordinate': 32,
+                  'BitsPerComponent': 8,
+                  'BitsPerFlag': 8,
+                  'ColorSpace': Name('DeviceRGB'),
+                  'AntiAlias': 1,
+                  'Decode': [points_min[0], points_max[0],
+                             points_min[1], points_max[1],
+                             0, 1, 0, 1, 0, 1]
+                  })
+
+            for tpoints, tcolors in zip(adjpoints, adjcolors):
+                for p, c in zip(tpoints, tcolors):
+                    values = [int(x) for x in [0] + list(p) + list(c[:3])]
+                    self.write(struct.pack('>BLLBBB', *values))
+            self.endStream()
+        self.writeObject(self.gouraudObject, gouraudDict)
+
     def imageObject(self, image):
         """Return name of an image XObject representing the given image."""
 
@@ -1326,6 +1369,18 @@
                 lastx, lasty = x, y
         output(Op.grestore)
 
+    def draw_gouraud_triangle(self, gc, points, colors, trans):
+        self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)),
+                                    colors.reshape((1, 3, 4)), trans)
+
+    def draw_gouraud_triangles(self, gc, points, colors, trans):
+        shape = points.shape
+        points = points.reshape((shape[0] * shape[1], 2))
+        tpoints = trans.transform(points)
+        tpoints = tpoints.reshape(shape)
+        name = self.file.addGouraudTriangles(tpoints, colors)
+        self.file.output(name, Op.shading)
+
     def _setup_textpos(self, x, y, descent, angle, oldx=0, oldy=0, 
olddescent=0, oldangle=0):
         if angle == oldangle == 0:
             self.file.output(x - oldx, (y + descent) - (oldy + olddescent), 
Op.textpos)

Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py      2009-08-31 19:50:13 UTC 
(rev 7620)
+++ trunk/matplotlib/lib/matplotlib/collections.py      2009-08-31 20:10:35 UTC 
(rev 7621)
@@ -1217,8 +1217,7 @@
             triangles, colors = self.convert_mesh_to_triangles(
                 self._meshWidth, self._meshHeight, coordinates)
             check = {}
-            for tri, col in zip(triangles, colors):
-                renderer.draw_gouraud_triangle(gc, tri, col, 
transform.frozen())
+            renderer.draw_gouraud_triangles(gc, triangles, colors, 
transform.frozen())
         else:
             renderer.draw_quad_mesh(
                 gc, transform.frozen(), self._meshWidth, self._meshHeight,

Modified: trunk/matplotlib/src/_backend_agg.cpp
===================================================================
--- trunk/matplotlib/src/_backend_agg.cpp       2009-08-31 19:50:13 UTC (rev 
7620)
+++ trunk/matplotlib/src/_backend_agg.cpp       2009-08-31 20:10:35 UTC (rev 
7621)
@@ -1455,21 +1455,14 @@
   return Py::Object();
 }
 
-Py::Object
-RendererAgg::draw_gouraud_triangle(const Py::Tuple& args) {
-  _VERBOSE("RendererAgg::draw_quad_mesh");
-  args.verify_length(4);
+void
+RendererAgg::_draw_gouraud_triangle(const GCAgg& gc,
+  const double* points, const double* colors, agg::trans_affine trans) {
 
   typedef agg::rgba8                      color_t;
   typedef agg::span_gouraud_rgba<color_t> span_gen_t;
   typedef agg::span_allocator<color_t>    span_alloc_t;
 
-  //segments, trans, clipbox, colors, linewidths, antialiaseds
-  GCAgg             gc(args[0], dpi);
-  Py::Object        points_obj = args[1];
-  Py::Object        colors_obj = args[2];
-  agg::trans_affine trans      = 
py_to_agg_transformation_matrix(args[3].ptr());
-
   theRasterizer.reset_clipping();
   rendererBase.reset_clipping(true);
   set_clipbox(gc.cliprect, theRasterizer);
@@ -1477,6 +1470,43 @@
   trans *= agg::trans_affine_scaling(1.0, -1.0);
   trans *= agg::trans_affine_translation(0.0, (double)height);
 
+  double tpoints[6];
+
+  for (int i = 0; i < 6; i += 2) {
+    tpoints[i] = points[i];
+    tpoints[i+1] = points[i+1];
+    trans.transform(&tpoints[i], &tpoints[i+1]);
+  }
+
+  span_alloc_t span_alloc;
+  span_gen_t span_gen;
+
+  span_gen.colors(
+    agg::rgba(colors[0], colors[1], colors[2], colors[3]),
+    agg::rgba(colors[4], colors[5], colors[6], colors[7]),
+    agg::rgba(colors[8], colors[9], colors[10], colors[11]));
+  span_gen.triangle(
+    tpoints[0], tpoints[1],
+    tpoints[2], tpoints[3],
+    tpoints[4], tpoints[5],
+    0.5);
+
+  theRasterizer.add_path(span_gen);
+  agg::render_scanlines_aa(
+    theRasterizer, slineP8, rendererBase, span_alloc, span_gen);
+}
+
+Py::Object
+RendererAgg::draw_gouraud_triangle(const Py::Tuple& args) {
+  _VERBOSE("RendererAgg::draw_gouraud_triangle");
+  args.verify_length(4);
+
+  //segments, trans, clipbox, colors, linewidths, antialiaseds
+  GCAgg             gc(args[0], dpi);
+  Py::Object        points_obj = args[1];
+  Py::Object        colors_obj = args[2];
+  agg::trans_affine trans      = 
py_to_agg_transformation_matrix(args[3].ptr());
+
   PyArrayObject* points = (PyArrayObject*)PyArray_ContiguousFromAny
     (points_obj.ptr(), PyArray_DOUBLE, 2, 2);
   if (!points ||
@@ -1490,32 +1520,57 @@
     throw Py::ValueError("colors must be a 3x4 numpy array");
 
   try {
-    double* opoints = (double*)PyArray_DATA(points);
-    double* c = (double*)PyArray_DATA(colors);
-    double tpoints[6];
+    _draw_gouraud_triangle(
+      gc, (double*)PyArray_DATA(points), (double*)PyArray_DATA(colors), trans);
+  } catch (...) {
+    Py_DECREF(points);
+    Py_DECREF(colors);
 
-    for (int i = 0; i < 6; i += 2) {
-      tpoints[i] = opoints[i];
-      tpoints[i+1] = opoints[i+1];
-      trans.transform(&tpoints[i], &tpoints[i+1]);
-    }
+    throw;
+  }
 
-    span_alloc_t span_alloc;
-    span_gen_t span_gen;
+  Py_DECREF(points);
+  Py_DECREF(colors);
 
-    span_gen.colors(
-      agg::rgba(c[0], c[1], c[2], c[3]),
-      agg::rgba(c[4], c[5], c[6], c[7]),
-      agg::rgba(c[8], c[9], c[10], c[11]));
-    span_gen.triangle(
-      tpoints[0], tpoints[1],
-      tpoints[2], tpoints[3],
-      tpoints[4], tpoints[5],
-      0.5);
+  return Py::Object();
+}
 
-    theRasterizer.add_path(span_gen);
-    agg::render_scanlines_aa(
-      theRasterizer, slineP8, rendererBase, span_alloc, span_gen);
+Py::Object
+RendererAgg::draw_gouraud_triangles(const Py::Tuple& args) {
+  _VERBOSE("RendererAgg::draw_gouraud_triangles");
+  args.verify_length(4);
+
+  typedef agg::rgba8                      color_t;
+  typedef agg::span_gouraud_rgba<color_t> span_gen_t;
+  typedef agg::span_allocator<color_t>    span_alloc_t;
+
+  //segments, trans, clipbox, colors, linewidths, antialiaseds
+  GCAgg             gc(args[0], dpi);
+  Py::Object        points_obj = args[1];
+  Py::Object        colors_obj = args[2];
+  agg::trans_affine trans      = 
py_to_agg_transformation_matrix(args[3].ptr());
+
+  PyArrayObject* points = (PyArrayObject*)PyArray_ContiguousFromAny
+    (points_obj.ptr(), PyArray_DOUBLE, 3, 3);
+  if (!points ||
+      PyArray_DIM(points, 1) != 3 || PyArray_DIM(points, 2) != 2)
+    throw Py::ValueError("points must be a Nx3x2 numpy array");
+
+  PyArrayObject* colors = (PyArrayObject*)PyArray_ContiguousFromAny
+    (colors_obj.ptr(), PyArray_DOUBLE, 3, 3);
+  if (!colors ||
+      PyArray_DIM(colors, 1) != 3 || PyArray_DIM(colors, 2) != 4)
+    throw Py::ValueError("colors must be a Nx3x4 numpy array");
+
+  if (PyArray_DIM(points, 0) != PyArray_DIM(colors, 0)) {
+    throw Py::ValueError("points and colors arrays must be the same length");
+  }
+
+  try {
+    for (int i = 0; i < PyArray_DIM(points, 0); ++i) {
+      _draw_gouraud_triangle(
+        gc, (double*)PyArray_GETPTR1(points, i), 
(double*)PyArray_GETPTR1(colors, i), trans);
+    }
   } catch (...) {
     Py_DECREF(points);
     Py_DECREF(colors);
@@ -1870,6 +1925,8 @@
                     "draw_quad_mesh(gc, master_transform, meshWidth, 
meshHeight, coordinates, offsets, offsetTrans, facecolors, antialiaseds, 
showedges)\n");
   add_varargs_method("draw_gouraud_triangle", 
&RendererAgg::draw_gouraud_triangle,
                     "draw_gouraud_triangle(gc, points, colors, 
master_transform)\n");
+  add_varargs_method("draw_gouraud_triangles", 
&RendererAgg::draw_gouraud_triangles,
+                    "draw_gouraud_triangles(gc, points, colors, 
master_transform)\n");
   add_varargs_method("draw_markers", &RendererAgg::draw_markers,
                     "draw_markers(gc, marker_path, marker_trans, path, 
rgbFace)\n");
   add_varargs_method("draw_text_image", &RendererAgg::draw_text_image,

Modified: trunk/matplotlib/src/_backend_agg.h
===================================================================
--- trunk/matplotlib/src/_backend_agg.h 2009-08-31 19:50:13 UTC (rev 7620)
+++ trunk/matplotlib/src/_backend_agg.h 2009-08-31 20:10:35 UTC (rev 7621)
@@ -165,6 +165,7 @@
   Py::Object draw_path_collection(const Py::Tuple & args);
   Py::Object draw_quad_mesh(const Py::Tuple& args);
   Py::Object draw_gouraud_triangle(const Py::Tuple& args);
+  Py::Object draw_gouraud_triangles(const Py::Tuple& args);
 
   Py::Object write_rgba(const Py::Tuple & args);
   Py::Object tostring_rgb(const Py::Tuple & args);
@@ -241,6 +242,11 @@
      const Py::SeqBase<Py::Object>& linestyles_obj,
      const Py::SeqBase<Py::Int>&    antialiaseds);
 
+  void
+  _draw_gouraud_triangle(
+      const GCAgg& gc,
+      const double* points, const double* colors, agg::trans_affine trans);
+
 private:
   void create_alpha_buffers();
 };


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

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to