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
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins