From: <md...@us...> - 2009-02-02 16:29:41
|
Revision: 6865 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6865&view=rev Author: mdboom Date: 2009-02-02 16:29:37 +0000 (Mon, 02 Feb 2009) Log Message: ----------- Create path_cleanup code for use by the Mac OS-X backend. Refactor C++ code to follow Numpy's guidelines for linking multiple C files into a single extension. Remove dependency of Agg backend on _image.cpp and _ft2font.cpp (simplifies linking problems and reduces generated code size). Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.cpp trunk/matplotlib/setupext.py trunk/matplotlib/src/_backend_agg.cpp trunk/matplotlib/src/_backend_gdk.c trunk/matplotlib/src/_gtkagg.cpp trunk/matplotlib/src/_image.cpp trunk/matplotlib/src/_image.h trunk/matplotlib/src/_path.cpp trunk/matplotlib/src/agg_py_path_iterator.h trunk/matplotlib/src/agg_py_transforms.h trunk/matplotlib/src/ft2font.cpp trunk/matplotlib/src/numerix.h trunk/matplotlib/src/path_converters.h Added Paths: ----------- trunk/matplotlib/src/agg_py_transforms.cpp trunk/matplotlib/src/path_cleanup.cpp trunk/matplotlib/src/path_cleanup.h Modified: trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.cpp =================================================================== --- trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.cpp 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.cpp 2009-02-02 16:29:37 UTC (rev 6865) @@ -12,9 +12,9 @@ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ -/* - * This code was originally written by Stephan Fortune in C code. Shane O'Sullivan, - * have since modified it, encapsulating it in a C++ class and, fixing memory leaks and +/* + * This code was originally written by Stephan Fortune in C code. Shane O'Sullivan, + * have since modified it, encapsulating it in a C++ class and, fixing memory leaks and * adding accessors to the Voronoi Edges. * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice @@ -26,13 +26,17 @@ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ - + /* * Subsequently, Robert Kern modified it to yield Python objects. * Copyright 2005 Robert Kern <rob...@gm...> * See LICENSE.txt in the scipy source directory. */ +#include <Python.h> +#define NO_IMPORT_ARRAY +#include "numpy/arrayobject.h" + #include "VoronoiDiagramGenerator.h" VoronoiDiagramGenerator::VoronoiDiagramGenerator() @@ -74,9 +78,9 @@ nsites=numPoints; plot = 0; - triangulate = 0; + triangulate = 0; debug = 1; - sorted = 0; + sorted = 0; freeinit(&sfl, sizeof (Site)); sites = (struct Site *) myalloc(nsites*sizeof( *sites)); @@ -108,9 +112,9 @@ //printf("\n%f %f\n",xValues[i],yValues[i]); } - + qsort(sites, nsites, sizeof (*sites), scomp); - + siteidx = 0; geominit(); double temp = 0; @@ -130,9 +134,9 @@ borderMinY = minY; borderMaxX = maxX; borderMaxY = maxY; - - siteidx = 0; + siteidx = 0; + voronoi(triangulate); return true; @@ -187,25 +191,25 @@ struct Halfedge * VoronoiDiagramGenerator::ELgethash(int b) { struct Halfedge *he; - - if(b<0 || b>=ELhashsize) + + if(b<0 || b>=ELhashsize) return((struct Halfedge *) NULL); - he = ELhash[b]; - if (he == (struct Halfedge *) NULL || he->ELedge != (struct Edge *) DELETED ) + he = ELhash[b]; + if (he == (struct Halfedge *) NULL || he->ELedge != (struct Edge *) DELETED ) return (he); - + /* Hash table points to deleted half edge. Patch as necessary. */ ELhash[b] = (struct Halfedge *) NULL; - if ((he -> ELrefcnt -= 1) == 0) + if ((he -> ELrefcnt -= 1) == 0) makefree((Freenode*)he, &hfl); return ((struct Halfedge *) NULL); -} +} struct Halfedge * VoronoiDiagramGenerator::ELleftbnd(struct Point *p) { int i, bucket; struct Halfedge *he; - + /* Use hash table to get close to desired halfedge */ bucket = (int)((p->x - xmin)/deltax * ELhashsize); //use the hash function to find the place in the hash map that this HalfEdge should be @@ -214,12 +218,12 @@ he = ELgethash(bucket); if(he == (struct Halfedge *) NULL) //if the HE isn't found, search backwards and forwards in the hash map for the first non-null entry - { + { for(i=1; 1 ; i += 1) - { - if ((he=ELgethash(bucket-i)) != (struct Halfedge *) NULL) + { + if ((he=ELgethash(bucket-i)) != (struct Halfedge *) NULL) break; - if ((he=ELgethash(bucket+i)) != (struct Halfedge *) NULL) + if ((he=ELgethash(bucket+i)) != (struct Halfedge *) NULL) break; }; totalsearch += i; @@ -228,22 +232,22 @@ /* Now search linear list of halfedges for the correct one */ if (he==ELleftend || (he != ELrightend && right_of(he,p))) { - do + do { he = he -> ELright; } while (he!=ELrightend && right_of(he,p)); //keep going right on the list until either the end is reached, or you find the 1st edge which the point he = he -> ELleft; //isn't to the right of } else //if the point is to the left of the HalfEdge, then search left for the HE just to the left of the point - do + do { he = he -> ELleft; } while (he!=ELleftend && !right_of(he,p)); - + /* Update hash table and reference counts */ if(bucket > 0 && bucket <ELhashsize-1) - { - if(ELhash[bucket] != (struct Halfedge *) NULL) + { + if(ELhash[bucket] != (struct Halfedge *) NULL) { ELhash[bucket] -> ELrefcnt -= 1; } @@ -277,9 +281,9 @@ struct Site * VoronoiDiagramGenerator::leftreg(struct Halfedge *he) { - if(he -> ELedge == (struct Edge *)NULL) + if(he -> ELedge == (struct Edge *)NULL) return(bottomsite); - return( he -> ELpm == le ? + return( he -> ELpm == le ? he -> ELedge -> reg[le] : he -> ELedge -> reg[re]); } @@ -293,7 +297,7 @@ } void VoronoiDiagramGenerator::geominit() -{ +{ double sn; freeinit(&efl, sizeof(Edge)); @@ -309,17 +313,17 @@ struct Edge * VoronoiDiagramGenerator::bisect(struct Site *s1, struct Site *s2) { double dx,dy,adx,ady; - struct Edge *newedge; + struct Edge *newedge; newedge = (struct Edge *) getfree(&efl); - + newedge -> reg[0] = s1; //store the sites that this edge is bisecting newedge -> reg[1] = s2; - ref(s1); + ref(s1); ref(s2); newedge -> ep[0] = (struct Site *) NULL; //to begin with, there are no endpoints on the bisector - it goes to infinity newedge -> ep[1] = (struct Site *) NULL; - + dx = s2->coord.x - s1->coord.x; //get the difference in x dist between the sites dy = s2->coord.y - s1->coord.y; adx = dx>0 ? dx : -dx; //make sure that the difference in positive @@ -327,18 +331,18 @@ newedge -> c = (double)(s1->coord.x * dx + s1->coord.y * dy + (dx*dx + dy*dy)*0.5);//get the slope of the line if (adx>ady) - { + { newedge -> a = 1.0; newedge -> b = dy/dx; newedge -> c /= dx;//set formula of line, with x fixed to 1 } else - { + { newedge -> b = 1.0; newedge -> a = dx/dy; newedge -> c /= dy;//set formula of line, with y fixed to 1 }; - + newedge -> edgenbr = nedges; //printf("\nbisect(%d) ((%f,%f) and (%f,%f)",nedges,s1->coord.x,s1->coord.y,s2->coord.x,s2->coord.y); - + nedges += 1; return(newedge); } @@ -351,40 +355,40 @@ double d, xint, yint; int right_of_site; struct Site *v; - + e1 = el1 -> ELedge; e2 = el2 -> ELedge; - if(e1 == (struct Edge*)NULL || e2 == (struct Edge*)NULL) + if(e1 == (struct Edge*)NULL || e2 == (struct Edge*)NULL) return ((struct Site *) NULL); //if the two edges bisect the same parent, return null - if (e1->reg[1] == e2->reg[1]) + if (e1->reg[1] == e2->reg[1]) return ((struct Site *) NULL); - + d = e1->a * e2->b - e1->b * e2->a; - if (-1.0e-10<d && d<1.0e-10) + if (-1.0e-10<d && d<1.0e-10) return ((struct Site *) NULL); - + xint = (e1->c*e2->b - e2->c*e1->b)/d; yint = (e2->c*e1->a - e1->c*e2->a)/d; - + if( (e1->reg[1]->coord.y < e2->reg[1]->coord.y) || (e1->reg[1]->coord.y == e2->reg[1]->coord.y && e1->reg[1]->coord.x < e2->reg[1]->coord.x) ) - { - el = el1; + { + el = el1; e = e1; } else - { - el = el2; + { + el = el2; e = e2; }; - + right_of_site = xint >= e -> reg[1] -> coord.x; - if ((right_of_site && el -> ELpm == le) || (!right_of_site && el -> ELpm == re)) + if ((right_of_site && el -> ELpm == le) || (!right_of_site && el -> ELpm == re)) return ((struct Site *) NULL); - + //create a new site at the point of intersection - this is a new vector event waiting to happen v = (struct Site *) getfree(&sfl); v -> refcnt = 0; @@ -400,22 +404,22 @@ struct Site *topsite; int right_of_site, above, fast; double dxp, dyp, dxs, t1, t2, t3, yl; - + e = el -> ELedge; topsite = e -> reg[1]; right_of_site = p -> x > topsite -> coord.x; if(right_of_site && el -> ELpm == le) return(1); if(!right_of_site && el -> ELpm == re) return (0); - + if (e->a == 1.0) { dyp = p->y - topsite->coord.y; dxp = p->x - topsite->coord.x; fast = 0; if ((!right_of_site & (e->b<0.0)) | (right_of_site & (e->b>=0.0)) ) - { above = dyp>= e->b*dxp; + { above = dyp>= e->b*dxp; fast = above; } - else + else { above = p->x + p->y*e->b > e-> c; if(e->b<0.0) above = !above; if (!above) fast = 1; @@ -442,7 +446,7 @@ { e -> ep[lr] = s; ref(s); - if(e -> ep[re-lr]== (struct Site *) NULL) + if(e -> ep[re-lr]== (struct Site *) NULL) return; clip_line(e); @@ -473,7 +477,7 @@ void VoronoiDiagramGenerator::deref(struct Site *v) { v -> refcnt -= 1; - if (v -> refcnt == 0 ) + if (v -> refcnt == 0 ) makefree((Freenode*)v, &sfl); } @@ -486,7 +490,7 @@ void VoronoiDiagramGenerator::PQinsert(struct Halfedge *he,struct Site * v, double offset) { struct Halfedge *last, *next; - + he -> vertex = v; ref(v); he -> ystar = (double)(v -> coord.y + offset); @@ -494,23 +498,23 @@ while ((next = last -> PQnext) != (struct Halfedge *) NULL && (he -> ystar > next -> ystar || (he -> ystar == next -> ystar && v -> coord.x > next->vertex->coord.x))) - { + { last = next; }; - he -> PQnext = last -> PQnext; + he -> PQnext = last -> PQnext; last -> PQnext = he; PQcount += 1; } -//remove the HalfEdge from the list of vertices +//remove the HalfEdge from the list of vertices void VoronoiDiagramGenerator::PQdelete(struct Halfedge *he) { struct Halfedge *last; - + if(he -> vertex != (struct Site *) NULL) - { + { last = &PQhash[PQbucket(he)]; - while (last -> PQnext != he) + while (last -> PQnext != he) last = last -> PQnext; last -> PQnext = he -> PQnext; @@ -523,7 +527,7 @@ int VoronoiDiagramGenerator::PQbucket(struct Halfedge *he) { int bucket; - + bucket = (int)((he->ystar - ymin)/deltay * PQhashsize); if (bucket<0) bucket = 0; if (bucket>=PQhashsize) bucket = PQhashsize-1 ; @@ -542,7 +546,7 @@ struct Point VoronoiDiagramGenerator::PQ_min() { struct Point answer; - + while(PQhash[PQmin].PQnext == (struct Halfedge *)NULL) {PQmin += 1;}; answer.x = PQhash[PQmin].PQnext -> vertex -> coord.x; answer.y = PQhash[PQmin].PQnext -> ystar; @@ -552,7 +556,7 @@ struct Halfedge * VoronoiDiagramGenerator::PQextractmin() { struct Halfedge *curr; - + curr = PQhash[PQmin].PQnext; PQhash[PQmin].PQnext = curr -> PQnext; PQcount -= 1; @@ -562,8 +566,8 @@ bool VoronoiDiagramGenerator::PQinitialize() { - int i; - + int i; + PQcount = 0; PQmin = 0; PQhashsize = 4 * sqrt_nsites; @@ -586,23 +590,23 @@ char * VoronoiDiagramGenerator::getfree(struct Freelist *fl) { - int i; + int i; struct Freenode *t; if(fl->head == (struct Freenode *) NULL) - { + { t = (struct Freenode *) myalloc(sqrt_nsites * fl->nodesize); if(t == 0) return 0; - + currentMemoryBlock->next = new FreeNodeArrayList; currentMemoryBlock = currentMemoryBlock->next; currentMemoryBlock->memory = t; currentMemoryBlock->next = 0; - for(i=0; i<sqrt_nsites; i+=1) - makefree((struct Freenode *)((char *)t+i*fl->nodesize), fl); + for(i=0; i<sqrt_nsites; i+=1) + makefree((struct Freenode *)((char *)t+i*fl->nodesize), fl); }; t = fl -> head; fl -> head = (fl -> head) -> nextfree; @@ -721,7 +725,7 @@ char * VoronoiDiagramGenerator::myalloc(unsigned n) { - char *t=0; + char *t=0; t=(char*)malloc(n); total_alloc += n; return(t); @@ -732,7 +736,7 @@ /* #include <plot.h> */ void VoronoiDiagramGenerator::openpl(){} void VoronoiDiagramGenerator::line(double x1, double y1, double x2, double y2) -{ +{ pushGraphEdge(x1,y1,x2,y2); } @@ -743,20 +747,20 @@ void VoronoiDiagramGenerator::out_bisector(struct Edge *e) { - + } void VoronoiDiagramGenerator::out_ep(struct Edge *e) { - - + + } void VoronoiDiagramGenerator::out_vertex(struct Site *v) { - + } @@ -764,13 +768,13 @@ { if(!triangulate & plot & !debug) circle (s->coord.x, s->coord.y, cradius); - + } void VoronoiDiagramGenerator::out_triple(struct Site *s1, struct Site *s2,struct Site * s3) { - + } @@ -778,7 +782,7 @@ void VoronoiDiagramGenerator::plotinit() { // double dx,dy,d; -// +// // dy = ymax - ymin; // dx = xmax - xmin; // d = (double)(( dx > dy ? dx : dy) * 1.1); @@ -804,7 +808,7 @@ // y1 = e->reg[0]->coord.y; // y2 = e->reg[1]->coord.y; // -// //if the distance between the two points this line was created from is less than +// //if the distance between the two points this line was created from is less than // //the square root of 2, then ignore it // if(sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))) < minDistanceBetweenSites) // { @@ -816,16 +820,16 @@ // pymax = borderMaxY; // // if(e -> a == 1.0 && e ->b >= 0.0) -// { +// { // s1 = e -> ep[1]; // s2 = e -> ep[0]; // } -// else +// else // { // s1 = e -> ep[0]; // s2 = e -> ep[1]; // }; -// +// // if(e -> a == 1.0) // { // y1 = pymin; @@ -833,7 +837,7 @@ // { // y1 = s1->coord.y; // } -// if(y1>pymax) +// if(y1>pymax) // { // // printf("\nClipped (1) y1 = %f to %f",y1,pymax); // y1 = pymax; @@ -841,17 +845,17 @@ // } // x1 = e -> c - e -> b * y1; // y2 = pymax; -// if (s2!=(struct Site *)NULL && s2->coord.y < pymax) +// if (s2!=(struct Site *)NULL && s2->coord.y < pymax) // y2 = s2->coord.y; // -// if(y2<pymin) +// if(y2<pymin) // { // //printf("\nClipped (2) y2 = %f to %f",y2,pymin); // y2 = pymin; // //return; // } // x2 = (e->c) - (e->b) * y2; -// if (((x1> pxmax) & (x2>pxmax)) | ((x1<pxmin)&(x2<pxmin))) +// if (((x1> pxmax) & (x2>pxmax)) | ((x1<pxmin)&(x2<pxmin))) // { // //printf("\nClipLine jumping out(3), x1 = %f, pxmin = %f, pxmax = %f",x1,pxmin,pxmax); // return; @@ -868,9 +872,9 @@ // else // { // x1 = pxmin; -// if (s1!=(struct Site *)NULL && s1->coord.x > pxmin) +// if (s1!=(struct Site *)NULL && s1->coord.x > pxmin) // x1 = s1->coord.x; -// if(x1>pxmax) +// if(x1>pxmax) // { // //printf("\nClipped (3) x1 = %f to %f",x1,pxmin); // //return; @@ -878,16 +882,16 @@ // } // y1 = e -> c - e -> a * x1; // x2 = pxmax; -// if (s2!=(struct Site *)NULL && s2->coord.x < pxmax) +// if (s2!=(struct Site *)NULL && s2->coord.x < pxmax) // x2 = s2->coord.x; -// if(x2<pxmin) +// if(x2<pxmin) // { // //printf("\nClipped (4) x2 = %f to %f",x2,pxmin); // //return; // x2 = pxmin; // } // y2 = e -> c - e -> a * x2; -// if (((y1> pymax) & (y2>pymax)) | ((y1<pymin)&(y2<pymin))) +// if (((y1> pymax) & (y2>pymax)) | ((y1<pymin)&(y2<pymin))) // { // //printf("\nClipLine jumping out(6), y1 = %f, pymin = %f, pymax = %f",y2,pymin,pymax); // return; @@ -901,7 +905,7 @@ // if(y2<pymin) // { y2 = pymin; x2 = (e -> c - y2)/e -> a;}; // }; -// +// // //printf("\nPushing line (%f,%f,%f,%f)",x1,y1,x2,y2); // line(x1,y1,x2,y2); } @@ -920,7 +924,7 @@ int pm; struct Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; struct Edge *e; - + PQinitialize(); bottomsite = nextone(); out_site(bottomsite); @@ -928,16 +932,16 @@ if(!retval) return false; - + newsite = nextone(); while(1) { - if(!PQempty()) + if(!PQempty()) newintstar = PQ_min(); - + //if the lowest site has a smaller y value than the lowest vector intersection, process the site - //otherwise process the vector intersection + //otherwise process the vector intersection if (newsite != (struct Site *)NULL && (PQempty() || newsite -> coord.y < newintstar.y || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) @@ -946,31 +950,31 @@ lbnd = ELleftbnd(&(newsite->coord)); //get the first HalfEdge to the LEFT of the new site rbnd = ELright(lbnd); //get the first HalfEdge to the RIGHT of the new site bot = rightreg(lbnd); //if this halfedge has no edge, , bot = bottom site (whatever that is) - e = bisect(bot, newsite); //create a new edge that bisects - bisector = HEcreate(e, le); //create a new HalfEdge, setting its ELpm field to 0 - ELinsert(lbnd, bisector); //insert this new bisector edge between the left and right vectors in a linked list + e = bisect(bot, newsite); //create a new edge that bisects + bisector = HEcreate(e, le); //create a new HalfEdge, setting its ELpm field to 0 + ELinsert(lbnd, bisector); //insert this new bisector edge between the left and right vectors in a linked list if ((p = intersect(lbnd, bisector)) != (struct Site *) NULL) //if the new bisector intersects with the left edge, remove the left edge's vertex, and put in the new one - { + { PQdelete(lbnd); PQinsert(lbnd, p, dist(p,newsite)); }; - lbnd = bisector; + lbnd = bisector; bisector = HEcreate(e, re); //create a new HalfEdge, setting its ELpm field to 1 ELinsert(lbnd, bisector); //insert the new HE to the right of the original bisector earlier in the IF stmt if ((p = intersect(bisector, rbnd)) != (struct Site *) NULL) //if this new bisector intersects with the - { + { PQinsert(bisector, p, dist(p,newsite)); //push the HE into the ordered linked list of vertices }; - newsite = nextone(); + newsite = nextone(); } - else if (!PQempty()) /* intersection is smallest - this is a vector event */ - { - lbnd = PQextractmin(); //pop the HalfEdge with the lowest vector off the ordered list of vectors + else if (!PQempty()) /* intersection is smallest - this is a vector event */ + { + lbnd = PQextractmin(); //pop the HalfEdge with the lowest vector off the ordered list of vectors llbnd = ELleft(lbnd); //get the HalfEdge to the left of the above HE rbnd = ELright(lbnd); //get the HalfEdge to the right of the above HE - rrbnd = ELright(rbnd); //get the HalfEdge to the right of the HE to the right of the lowest HE + rrbnd = ELright(rbnd); //get the HalfEdge to the right of the HE to the right of the lowest HE bot = leftreg(lbnd); //get the Site to the left of the left HE which it bisects top = rightreg(rbnd); //get the Site to the right of the right HE which it bisects @@ -980,16 +984,16 @@ makevertex(v); //set the vertex number - couldn't do this earlier since we didn't know when it would be processed endpoint(lbnd->ELedge,lbnd->ELpm,v); //set the endpoint of the left HalfEdge to be this vector endpoint(rbnd->ELedge,rbnd->ELpm,v); //set the endpoint of the right HalfEdge to be this vector - ELdelete(lbnd); //mark the lowest HE for deletion - can't delete yet because there might be pointers to it in Hash Map + ELdelete(lbnd); //mark the lowest HE for deletion - can't delete yet because there might be pointers to it in Hash Map PQdelete(rbnd); //remove all vertex events to do with the right HE - ELdelete(rbnd); //mark the right HE for deletion - can't delete yet because there might be pointers to it in Hash Map + ELdelete(rbnd); //mark the right HE for deletion - can't delete yet because there might be pointers to it in Hash Map pm = le; //set the pm variable to zero - + if (bot->coord.y > top->coord.y) //if the site to the left of the event is higher than the Site { //to the right of it, then swap them and set the 'pm' variable to 1 - temp = bot; - bot = top; - top = temp; + temp = bot; + bot = top; + top = temp; pm = re; } e = bisect(bot, top); //create an Edge (or line) that is between the two Sites. This creates @@ -1001,27 +1005,27 @@ //Site, then this endpoint is put in position 0; otherwise in pos 1 deref(v); //delete the vector 'v' - //if left HE and the new bisector don't intersect, then delete the left HE, and reinsert it + //if left HE and the new bisector don't intersect, then delete the left HE, and reinsert it if((p = intersect(llbnd, bisector)) != (struct Site *) NULL) - { + { PQdelete(llbnd); PQinsert(llbnd, p, dist(p,bot)); }; - //if right HE and the new bisector don't intersect, then reinsert it + //if right HE and the new bisector don't intersect, then reinsert it if ((p = intersect(bisector, rrbnd)) != (struct Site *) NULL) - { + { PQinsert(bisector, p, dist(p,bot)); }; } else break; }; - + for(lbnd=ELright(ELleftend); lbnd != ELrightend; lbnd=ELright(lbnd)) - { + { e = lbnd -> ELedge; clip_line(e); @@ -1031,7 +1035,7 @@ cleanup(); return true; - + } @@ -1050,16 +1054,16 @@ { struct Site *s; if(siteidx < nsites) - { + { s = &sites[siteidx]; siteidx += 1; return(s); } - else + else return( (struct Site *)NULL); } -bool VoronoiDiagramGenerator::getNextDelaunay(int& ep0, double& ep0x, double& ep0y, +bool VoronoiDiagramGenerator::getNextDelaunay(int& ep0, double& ep0x, double& ep0y, int& ep1, double& ep1x, double& ep1y, int& reg0, int& reg1) { @@ -1076,7 +1080,7 @@ reg1 = iterEdgeList->reg1nbr; iterEdgeList = iterEdgeList->next; - + return true; } Modified: trunk/matplotlib/setupext.py =================================================================== --- trunk/matplotlib/setupext.py 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/setupext.py 2009-02-02 16:29:37 UTC (rev 6865) @@ -1079,7 +1079,8 @@ deps.extend(glob.glob('CXX/*.cxx')) deps.extend(glob.glob('CXX/*.c')) - module = Extension('matplotlib.ft2font', deps) + module = Extension('matplotlib.ft2font', deps, + define_macros=[('PY_ARRAYAUNIQUE_SYMBOL', 'MPL_ARRAY_API')]) add_ft2font_flags(module) ext_modules.append(module) BUILT_FT2FONT = True @@ -1100,12 +1101,13 @@ def build_gtkagg(ext_modules, packages): global BUILT_GTKAGG if BUILT_GTKAGG: return # only build it if you you haven't already - deps = ['src/_gtkagg.cpp', 'src/mplutils.cpp']#, 'src/_transforms.cpp'] + deps = ['src/agg_py_transforms.cpp', 'src/_gtkagg.cpp', 'src/mplutils.cpp'] deps.extend(glob.glob('CXX/*.cxx')) deps.extend(glob.glob('CXX/*.c')) module = Extension('matplotlib.backends._gtkagg', deps, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) # add agg flags before pygtk because agg only supports freetype1 @@ -1164,6 +1166,7 @@ module = Extension('matplotlib.backends._macosx', ['src/_macosx.m'], extra_link_args = ['-framework','Cocoa'], + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) add_numpy_flags(module) ext_modules.append(module) @@ -1182,6 +1185,7 @@ 'matplotlib._png', deps, include_dirs=numpy_inc_dirs, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) add_png_flags(module) @@ -1194,7 +1198,6 @@ global BUILT_AGG if BUILT_AGG: return # only build it if you you haven't already - agg = ( 'agg_trans_affine.cpp', 'agg_bezier_arc.cpp', @@ -1204,22 +1207,20 @@ 'agg_image_filters.cpp', ) - deps = ['%s/src/%s'%(AGG_VERSION, name) for name in agg] - deps.extend(('src/_image.cpp', 'src/ft2font.cpp', 'src/mplutils.cpp')) + deps.extend(['src/mplutils.cpp', 'src/agg_py_transforms.cpp']) deps.extend(glob.glob('CXX/*.cxx')) deps.extend(glob.glob('CXX/*.c')) - temp_copy('src/_backend_agg.cpp', 'src/backend_agg.cpp') deps.append('src/backend_agg.cpp') module = Extension( 'matplotlib.backends._backend_agg', deps, include_dirs=numpy_inc_dirs, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) add_numpy_flags(module) - add_agg_flags(module) add_ft2font_flags(module) ext_modules.append(module) @@ -1242,11 +1243,14 @@ deps.extend(glob.glob('CXX/*.c')) temp_copy('src/_path.cpp', 'src/path.cpp') - deps.extend(['src/path.cpp']) + deps.extend(['src/agg_py_transforms.cpp', + 'src/path_cleanup.cpp', + 'src/path.cpp']) module = Extension( 'matplotlib._path', deps, include_dirs=numpy_inc_dirs, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) add_numpy_flags(module) @@ -1275,6 +1279,7 @@ 'matplotlib._image', deps, include_dirs=numpy_inc_dirs, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) add_numpy_flags(module) @@ -1294,7 +1299,9 @@ "delaunay_utils.cpp", "natneighbors.cpp"] sourcefiles = [os.path.join('lib/matplotlib/delaunay',s) for s in sourcefiles] delaunay = Extension('matplotlib._delaunay',sourcefiles, - include_dirs=numpy_inc_dirs) + include_dirs=numpy_inc_dirs, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] + ) add_numpy_flags(delaunay) add_base_flags(delaunay) ext_modules.append(delaunay) @@ -1310,6 +1317,7 @@ 'matplotlib._cntr', [ 'src/cntr.c'], include_dirs=numpy_inc_dirs, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) add_numpy_flags(module) add_base_flags(module) @@ -1325,6 +1333,7 @@ 'matplotlib.nxutils', [ 'src/nxutils.c'], include_dirs=numpy_inc_dirs, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) add_numpy_flags(module) add_base_flags(module) @@ -1343,6 +1352,7 @@ ['src/backend_gdk.c'], libraries = [], include_dirs=numpy_inc_dirs, + define_macros=[('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API')] ) add_numpy_flags(module) Modified: trunk/matplotlib/src/_backend_agg.cpp =================================================================== --- trunk/matplotlib/src/_backend_agg.cpp 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/_backend_agg.cpp 2009-02-02 16:29:37 UTC (rev 6865) @@ -37,7 +37,6 @@ #include "swig_runtime.h" #include "MPL_isnan.h" -#define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" #include "agg_py_transforms.h" @@ -253,7 +252,7 @@ Py::Tuple path_and_transform = method.apply(Py::Tuple()); if (path_and_transform[0].ptr() != Py_None) { clippath = path_and_transform[0]; - clippath_trans = py_to_agg_transformation_matrix(path_and_transform[1]); + clippath_trans = py_to_agg_transformation_matrix(path_and_transform[1].ptr()); } } @@ -471,9 +470,9 @@ Py::Object gc_obj = args[0]; Py::Object marker_path_obj = args[1]; - agg::trans_affine marker_trans = py_to_agg_transformation_matrix(args[2]); + agg::trans_affine marker_trans = py_to_agg_transformation_matrix(args[2].ptr()); Py::Object path_obj = args[3]; - agg::trans_affine trans = py_to_agg_transformation_matrix(args[4]); + agg::trans_affine trans = py_to_agg_transformation_matrix(args[4].ptr()); Py::Object face_obj; if (args.size() == 6) face_obj = args[5]; @@ -748,7 +747,7 @@ rendererBase.reset_clipping(true); if (args.size() == 6) { clippath = args[4]; - clippath_trans = py_to_agg_transformation_matrix(args[5], false); + clippath_trans = py_to_agg_transformation_matrix(args[5].ptr(), false); has_clippath = render_clippath(clippath, clippath_trans); } @@ -963,7 +962,7 @@ Py::Object gc_obj = args[0]; Py::Object path_obj = args[1]; - agg::trans_affine trans = py_to_agg_transformation_matrix(args[2]); + agg::trans_affine trans = py_to_agg_transformation_matrix(args[2].ptr()); Py::Object face_obj; if (args.size() == 4) face_obj = args[3]; @@ -1071,7 +1070,7 @@ transforms.reserve(Ntransforms); for (i = 0; i < Ntransforms; ++i) { agg::trans_affine trans = py_to_agg_transformation_matrix - (transforms_obj[i], false); + (transforms_obj[i].ptr(), false); trans *= master_transform; transforms.push_back(trans); @@ -1212,14 +1211,14 @@ args.verify_length(14); //segments, trans, clipbox, colors, linewidths, antialiaseds - agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[0]); + agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[0].ptr()); Py::Object cliprect = args[1]; Py::Object clippath = args[2]; - agg::trans_affine clippath_trans = py_to_agg_transformation_matrix(args[3], false); + agg::trans_affine clippath_trans = py_to_agg_transformation_matrix(args[3].ptr(), false); Py::SeqBase<Py::Object> paths = args[4]; Py::SeqBase<Py::Object> transforms_obj = args[5]; Py::Object offsets_obj = args[6]; - agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7]); + agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7].ptr()); Py::Object facecolors_obj = args[8]; Py::Object edgecolors_obj = args[9]; Py::SeqBase<Py::Float> linewidths = args[10]; @@ -1328,15 +1327,15 @@ //segments, trans, clipbox, colors, linewidths, antialiaseds - agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[0]); + agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[0].ptr()); Py::Object cliprect = args[1]; Py::Object clippath = args[2]; - agg::trans_affine clippath_trans = py_to_agg_transformation_matrix(args[3], false); + agg::trans_affine clippath_trans = py_to_agg_transformation_matrix(args[3].ptr(), false); size_t mesh_width = Py::Int(args[4]); size_t mesh_height = Py::Int(args[5]); PyObject* coordinates = args[6].ptr(); Py::Object offsets_obj = args[7]; - agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[8]); + agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[8].ptr()); Py::Object facecolors_obj = args[9]; bool antialiased = (bool)Py::Int(args[10]); bool showedges = (bool)Py::Int(args[11]); Modified: trunk/matplotlib/src/_backend_gdk.c =================================================================== --- trunk/matplotlib/src/_backend_gdk.c 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/_backend_gdk.c 2009-02-02 16:29:37 UTC (rev 6865) @@ -3,7 +3,6 @@ */ #include "Python.h" -#define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" #include <pygtk/pygtk.h> Modified: trunk/matplotlib/src/_gtkagg.cpp =================================================================== --- trunk/matplotlib/src/_gtkagg.cpp 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/_gtkagg.cpp 2009-02-02 16:29:37 UTC (rev 6865) @@ -10,9 +10,8 @@ #include <fstream> #include "agg_basics.h" -#include "_backend_agg.h" -#define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" +#include "_backend_agg.h" #include "agg_py_transforms.h" // the extension module Modified: trunk/matplotlib/src/_image.cpp =================================================================== --- trunk/matplotlib/src/_image.cpp 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/_image.cpp 2009-02-02 16:29:37 UTC (rev 6865) @@ -11,7 +11,6 @@ #include <cmath> #include <cstdio> -#define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" #include "agg_color_rgba.h" @@ -98,18 +97,7 @@ "\n" "Flip the output image upside down" ; -Py::Object -Image::flipud_out(const Py::Tuple& args) { - _VERBOSE("Image::flipud_out"); - args.verify_length(0); - int stride = rbufOut->stride(); - //std::cout << "flip before: " << rbufOut->stride() << std::endl; - rbufOut->attach(bufferOut, colsOut, rowsOut, -stride); - //std::cout << "flip after: " << rbufOut->stride() << std::endl; - return Py::Object(); -} - char Image::flipud_in__doc__[] = "flipud()\n" "\n" @@ -1756,8 +1744,6 @@ d["ASPECT_FREE"] = Py::Int(Image::ASPECT_FREE); d["ASPECT_PRESERVE"] = Py::Int(Image::ASPECT_PRESERVE); - - } Modified: trunk/matplotlib/src/_image.h =================================================================== --- trunk/matplotlib/src/_image.h 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/_image.h 2009-02-02 16:29:37 UTC (rev 6865) @@ -39,7 +39,15 @@ Py::Object set_interpolation(const Py::Tuple& args); Py::Object set_aspect(const Py::Tuple& args); Py::Object set_bg(const Py::Tuple& args); - Py::Object flipud_out(const Py::Tuple& args); + inline Py::Object flipud_out(const Py::Tuple& args) { + args.verify_length(0); + int stride = rbufOut->stride(); + //std::cout << "flip before: " << rbufOut->stride() << std::endl; + rbufOut->attach(bufferOut, colsOut, rowsOut, -stride); + //std::cout << "flip after: " << rbufOut->stride() << std::endl; + return Py::Object(); + } + Py::Object flipud_in(const Py::Tuple& args); Py::Object set_resample(const Py::Tuple& args); Py::Object get_resample(const Py::Tuple& args); Modified: trunk/matplotlib/src/_path.cpp =================================================================== --- trunk/matplotlib/src/_path.cpp 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/_path.cpp 2009-02-02 16:29:37 UTC (rev 6865) @@ -56,7 +56,10 @@ "convert_path_to_polygons(path, trans, width, height)"); add_varargs_method("cleanup_path", &_path_module::cleanup_path, "cleanup_path(path, trans, remove_nans, clip, quantize, simplify, curves)"); - + /* TEST CODE -- REMOVE LATER */ + add_varargs_method("cleanup_path_test", &_path_module::cleanup_path_test, + "TEST"); + /* **************************************** */ initialize("Helper functions for paths"); } @@ -76,6 +79,8 @@ Py::Object path_intersects_path(const Py::Tuple& args); Py::Object convert_path_to_polygons(const Py::Tuple& args); Py::Object cleanup_path(const Py::Tuple& args); + /* TEST CODE -- REMOVE LATER */ + Py::Object cleanup_path_test(const Py::Tuple& args); }; // @@ -244,7 +249,7 @@ double x = Py::Float(args[0]); double y = Py::Float(args[1]); PathIterator path(args[2]); - agg::trans_affine trans = py_to_agg_transformation_matrix(args[3], false); + agg::trans_affine trans = py_to_agg_transformation_matrix(args[3].ptr(), false); if (::point_in_path(x, y, path, trans)) return Py::Int(1); @@ -259,7 +264,7 @@ double y = Py::Float(args[1]); double r = Py::Float(args[2]); PathIterator path(args[3]); - agg::trans_affine trans = py_to_agg_transformation_matrix(args[4]); + agg::trans_affine trans = py_to_agg_transformation_matrix(args[4].ptr()); if (::point_on_path(x, y, r, path, trans)) return Py::Int(1); @@ -305,7 +310,7 @@ args.verify_length(2); PathIterator path(args[0]); - agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false); + agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); npy_intp extent_dims[] = { 2, 2, 0 }; double* extents_data = NULL; @@ -347,7 +352,7 @@ double x0, y0, x1, y1; PathIterator path(args[0]); - agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false); + agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); if (!py_convert_bbox(args[2].ptr(), x0, y0, x1, y1)) { throw Py::ValueError("Must pass Bbox object as arg 3 of update_path_extents"); @@ -465,11 +470,11 @@ args.verify_length(5); //segments, trans, clipbox, colors, linewidths, antialiaseds - agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[0]); + agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[0].ptr()); Py::SeqBase<Py::Object> paths = args[1]; Py::SeqBase<Py::Object> transforms_obj = args[2]; Py::Object offsets_obj = args[3]; - agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[4], false); + agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[4].ptr(), false); PyArrayObject* offsets = NULL; double x0, y0, x1, y1, xm, ym; @@ -497,7 +502,7 @@ for (i = 0; i < Ntransforms; ++i) { agg::trans_affine trans = py_to_agg_transformation_matrix - (transforms_obj[i], false); + (transforms_obj[i].ptr(), false); trans *= master_transform; transforms.push_back(trans); } @@ -558,11 +563,11 @@ double x = Py::Float(args[0]); double y = Py::Float(args[1]); double radius = Py::Float(args[2]); - agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[3]); + agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[3].ptr()); Py::SeqBase<Py::Object> paths = args[4]; Py::SeqBase<Py::Object> transforms_obj = args[5]; Py::SeqBase<Py::Object> offsets_obj = args[6]; - agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7]); + agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7].ptr()); bool filled = Py::Int(args[8]); PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 0, 2); @@ -586,7 +591,7 @@ for (i = 0; i < Ntransforms; ++i) { agg::trans_affine trans = py_to_agg_transformation_matrix - (transforms_obj[i], false); + (transforms_obj[i].ptr(), false); trans *= master_transform; transforms.push_back(trans); } @@ -658,9 +663,9 @@ args.verify_length(4); PathIterator a(args[0]); - agg::trans_affine atrans = py_to_agg_transformation_matrix(args[1], false); + agg::trans_affine atrans = py_to_agg_transformation_matrix(args[1].ptr(), false); PathIterator b(args[2]); - agg::trans_affine btrans = py_to_agg_transformation_matrix(args[3], false); + agg::trans_affine btrans = py_to_agg_transformation_matrix(args[3].ptr(), false); return Py::Int(::path_in_path(a, atrans, b, btrans)); } @@ -1153,7 +1158,7 @@ args.verify_length(4); PathIterator path(args[0]); - agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false); + agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); double width = Py::Float(args[2]); double height = Py::Float(args[3]); @@ -1256,7 +1261,7 @@ args.verify_length(7); PathIterator path(args[0]); - agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false); + agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); bool remove_nans = args[2].isTrue(); Py::Object clip_obj = args[3]; @@ -1349,6 +1354,39 @@ return result; } +/************************************************************/ +/* TEST CODE */ +extern "C" { + void* get_path_iterator( + PyObject* path, PyObject* trans, int remove_nans, int do_clip, + double rect[4], e_quantize_mode quantize_mode, int do_simplify); + + unsigned get_vertex(void* pipeline, double* x, double* y); + + void free_path_iterator(void* pipeline); +} + +Py::Object _path_module::cleanup_path_test(const Py::Tuple& args) +{ + args.verify_length(2); + + double rect[] = { 0.0, 0.0, 640.0, 480.0 }; + + void* iterator = get_path_iterator(args[0].ptr(), args[1].ptr(), 1, 1, rect, QUANTIZE_AUTO, 1); + + unsigned cmd; + double x, y; + while ((cmd = get_vertex(iterator, &x, &y)) != 0 /* STOP */) { + printf("%f %f %d\n", x, y, cmd); + } + + free_path_iterator(iterator); + + return Py::None(); +} +/* END OF TEST CODE */ +/************************************************************/ + extern "C" DL_EXPORT(void) init_path(void) Modified: trunk/matplotlib/src/agg_py_path_iterator.h =================================================================== --- trunk/matplotlib/src/agg_py_path_iterator.h 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/agg_py_path_iterator.h 2009-02-02 16:29:37 UTC (rev 6865) @@ -2,7 +2,6 @@ #define __AGG_PY_PATH_ITERATOR_H__ #include "CXX/Objects.hxx" -#define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" #include "agg_path_storage.h" @@ -39,7 +38,7 @@ public: /* path_obj is an instance of the class Path as defined in path.py */ - PathIterator(const Py::Object& path_obj) : + inline PathIterator(const Py::Object& path_obj) : m_vertices(NULL), m_codes(NULL), m_iterator(0), m_should_simplify(false), m_simplify_threshold(1.0 / 9.0) { Added: trunk/matplotlib/src/agg_py_transforms.cpp =================================================================== --- trunk/matplotlib/src/agg_py_transforms.cpp (rev 0) +++ trunk/matplotlib/src/agg_py_transforms.cpp 2009-02-02 16:29:37 UTC (rev 6865) @@ -0,0 +1,98 @@ +#include <Python.h> + +#define NO_IMPORT_ARRAY +#include "numpy/arrayobject.h" + +#include "CXX/Objects.hxx" +#include "agg_trans_affine.h" + +/** A helper function to convert from a Numpy affine transformation matrix + * to an agg::trans_affine. + */ +agg::trans_affine +py_to_agg_transformation_matrix(PyObject* obj, bool errors = true) +{ + PyArrayObject* matrix = NULL; + + try + { + if (obj == Py_None) + throw std::exception(); + matrix = (PyArrayObject*) PyArray_FromObject(obj, PyArray_DOUBLE, 2, 2); + if (!matrix) + throw std::exception(); + if (PyArray_NDIM(matrix) == 2 || PyArray_DIM(matrix, 0) == 3 || PyArray_DIM(matrix, 1) == 3) + { + size_t stride0 = PyArray_STRIDE(matrix, 0); + size_t stride1 = PyArray_STRIDE(matrix, 1); + char* row0 = PyArray_BYTES(matrix); + char* row1 = row0 + stride0; + + double a = *(double*)(row0); + row0 += stride1; + double c = *(double*)(row0); + row0 += stride1; + double e = *(double*)(row0); + + double b = *(double*)(row1); + row1 += stride1; + double d = *(double*)(row1); + row1 += stride1; + double f = *(double*)(row1); + + Py_XDECREF(matrix); + + return agg::trans_affine(a, b, c, d, e, f); + } + + throw std::exception(); + } + catch (...) + { + if (errors) + { + Py_XDECREF(matrix); + throw Py::TypeError("Invalid affine transformation matrix"); + } + } + + Py_XDECREF(matrix); + return agg::trans_affine(); +} + +bool +py_convert_bbox(PyObject* bbox_obj, double& l, double& b, double& r, double& t) +{ + PyArrayObject* bbox = NULL; + + if (bbox_obj == Py_None) + return false; + + try + { + bbox = (PyArrayObject*) PyArray_FromObject(bbox_obj, PyArray_DOUBLE, 2, 2); + + if (!bbox || PyArray_NDIM(bbox) != 2 || PyArray_DIM(bbox, 0) != 2 || PyArray_DIM(bbox, 1) != 2) + { + throw Py::TypeError + ("Argument 3 to agg_to_gtk_drawable must be a Bbox object."); + } + + l = *(double*)PyArray_GETPTR2(bbox, 0, 0); + b = *(double*)PyArray_GETPTR2(bbox, 0, 1); + r = *(double*)PyArray_GETPTR2(bbox, 1, 0); + t = *(double*)PyArray_GETPTR2(bbox, 1, 1); + + Py_XDECREF(bbox); + bbox = NULL; + return true; + } + catch (...) + { + Py_XDECREF(bbox); + bbox = NULL; + throw; + } + + return false; +} Modified: trunk/matplotlib/src/agg_py_transforms.h =================================================================== --- trunk/matplotlib/src/agg_py_transforms.h 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/agg_py_transforms.h 2009-02-02 16:29:37 UTC (rev 6865) @@ -1,99 +1,15 @@ #ifndef __AGG_PY_TRANSFORMS_H__ #define __AGG_PY_TRANSFORMS_H__ -#define PY_ARRAY_TYPES_PREFIX NumPy -#include "numpy/arrayobject.h" - -#include "CXX/Objects.hxx" #include "agg_trans_affine.h" /** A helper function to convert from a Numpy affine transformation matrix * to an agg::trans_affine. */ -agg::trans_affine py_to_agg_transformation_matrix(const Py::Object& obj, bool errors = true) -{ - PyArrayObject* matrix = NULL; +agg::trans_affine +py_to_agg_transformation_matrix(PyObject* obj, bool errors = true); - try - { - if (obj.ptr() == Py_None) - throw std::exception(); - matrix = (PyArrayObject*) PyArray_FromObject(obj.ptr(), PyArray_DOUBLE, 2, 2); - if (!matrix) - throw std::exception(); - if (PyArray_NDIM(matrix) == 2 || PyArray_DIM(matrix, 0) == 3 || PyArray_DIM(matrix, 1) == 3) - { - size_t stride0 = PyArray_STRIDE(matrix, 0); - size_t stride1 = PyArray_STRIDE(matrix, 1); - char* row0 = PyArray_BYTES(matrix); - char* row1 = row0 + stride0; +bool +py_convert_bbox(PyObject* bbox_obj, double& l, double& b, double& r, double& t); - double a = *(double*)(row0); - row0 += stride1; - double c = *(double*)(row0); - row0 += stride1; - double e = *(double*)(row0); - - double b = *(double*)(row1); - row1 += stride1; - double d = *(double*)(row1); - row1 += stride1; - double f = *(double*)(row1); - - Py_XDECREF(matrix); - - return agg::trans_affine(a, b, c, d, e, f); - } - - throw std::exception(); - } - catch (...) - { - if (errors) - { - Py_XDECREF(matrix); - throw Py::TypeError("Invalid affine transformation matrix"); - } - } - - Py_XDECREF(matrix); - return agg::trans_affine(); -} - -bool py_convert_bbox(PyObject* bbox_obj, double& l, double& b, double& r, double& t) -{ - PyArrayObject* bbox = NULL; - - if (bbox_obj == Py_None) - return false; - - try - { - bbox = (PyArrayObject*) PyArray_FromObject(bbox_obj, PyArray_DOUBLE, 2, 2); - - if (!bbox || PyArray_NDIM(bbox) != 2 || PyArray_DIM(bbox, 0) != 2 || PyArray_DIM(bbox, 1) != 2) - { - throw Py::TypeError - ("Argument 3 to agg_to_gtk_drawable must be a Bbox object."); - } - - l = *(double*)PyArray_GETPTR2(bbox, 0, 0); - b = *(double*)PyArray_GETPTR2(bbox, 0, 1); - r = *(double*)PyArray_GETPTR2(bbox, 1, 0); - t = *(double*)PyArray_GETPTR2(bbox, 1, 1); - - Py_XDECREF(bbox); - bbox = NULL; - return true; - } - catch (...) - { - Py_XDECREF(bbox); - bbox = NULL; - throw; - } - - return false; -} - #endif // __AGG_PY_TRANSFORMS_H__ Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/ft2font.cpp 2009-02-02 16:29:37 UTC (rev 6865) @@ -2,7 +2,6 @@ #include "mplutils.h" #include <sstream> -#define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" #define FIXED_MAJOR(val) (*((short *) &val+1)) Modified: trunk/matplotlib/src/numerix.h =================================================================== --- trunk/matplotlib/src/numerix.h 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/numerix.h 2009-02-02 16:29:37 UTC (rev 6865) @@ -3,7 +3,6 @@ #ifndef _NUMERIX_H #define _NUMERIX_H -#define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" #if (NDARRAY_VERSION >= 0x00090908) #include "numpy/oldnumeric.h" Added: trunk/matplotlib/src/path_cleanup.cpp =================================================================== --- trunk/matplotlib/src/path_cleanup.cpp (rev 0) +++ trunk/matplotlib/src/path_cleanup.cpp 2009-02-02 16:29:37 UTC (rev 6865) @@ -0,0 +1,84 @@ +#include <Python.h> +#define NO_IMPORT_ARRAY +#include "numpy/arrayobject.h" + +#include "agg_py_path_iterator.h" +#include "agg_conv_transform.h" +#include "agg_py_transforms.h" +#include "path_converters.h" + +class PathCleanupIterator { + typedef agg::conv_transform<PathIterator> transformed_path_t; + typedef PathNanRemover<transformed_path_t> nan_removal_t; + typedef PathClipper<nan_removal_t> clipped_t; + typedef PathQuantizer<clipped_t> quantized_t; + typedef PathSimplifier<quantized_t> simplify_t; + + Py::Object m_path_obj; + PathIterator m_path_iter; + agg::trans_affine m_transform; + transformed_path_t m_transformed; + nan_removal_t m_nan_removed; + clipped_t m_clipped; + quantized_t m_quantized; + simplify_t m_simplify; + +public: + PathCleanupIterator(PyObject* path, agg::trans_affine trans, + bool remove_nans, bool do_clip, + const agg::rect_base<double>& rect, + e_quantize_mode quantize_mode, bool do_simplify) : + m_path_obj(path, true), + m_path_iter(m_path_obj), + m_transform(trans), + m_transformed(m_path_iter, m_transform), + m_nan_removed(m_transformed, remove_nans, m_path_iter.has_curves()), + m_clipped(m_nan_removed, do_clip, rect), + m_quantized(m_clipped, quantize_mode, m_path_iter.total_vertices()), + m_simplify(m_quantized, do_simplify && m_path_iter.should_simplify(), + m_path_iter.simplify_threshold()) + { + Py_INCREF(path); + m_path_iter.rewind(0); + } + + unsigned vertex(double* x, double* y) + { + return m_simplify.vertex(x, y); + } +}; + +extern "C" { + void* + get_path_iterator( + PyObject* path, PyObject* trans, int remove_nans, int do_clip, + double rect[4], e_quantize_mode quantize_mode, int do_simplify) + { + agg::trans_affine agg_trans = py_to_agg_transformation_matrix(trans, false); + agg::rect_base<double> clip_rect(rect[0], rect[1], rect[2], rect[3]); + + PathCleanupIterator* pipeline = new PathCleanupIterator( + path, agg_trans, remove_nans != 0, do_clip != 0, + clip_rect, quantize_mode, do_simplify != 0); + + return (void*)pipeline; + } + + unsigned + get_vertex(void* pipeline, double* x, double* y) + { + PathCleanupIterator* pipeline_iter = (PathCleanupIterator*)pipeline; + + unsigned code = pipeline_iter->vertex(x, y); + return code; + } + + void + free_path_iterator(void* pipeline) + { + PathCleanupIterator* pipeline_iter = (PathCleanupIterator*)pipeline; + + delete pipeline_iter; + } +} + Added: trunk/matplotlib/src/path_cleanup.h =================================================================== --- trunk/matplotlib/src/path_cleanup.h (rev 0) +++ trunk/matplotlib/src/path_cleanup.h 2009-02-02 16:29:37 UTC (rev 6865) @@ -0,0 +1,24 @@ +#ifndef PATH_CLEANUP_H +#define PATH_CLEANUP_H + +#include <Python.h> + +enum e_quantize_mode +{ + QUANTIZE_AUTO, + QUANTIZE_FALSE, + QUANTIZE_TRUE +}; + +void* +get_path_iterator( + PyObject* path, PyObject* trans, int remove_nans, int do_clip, + double rect[4], e_quantize_mode quantize_mode, int do_simplify); + +unsigned +get_vertex(void* pipeline, double* x, double* y); + +void +free_path_iterator(void* pipeline); + +#endif /* PATH_CLEANUP_H */ Modified: trunk/matplotlib/src/path_converters.h =================================================================== --- trunk/matplotlib/src/path_converters.h 2009-02-02 16:19:33 UTC (rev 6864) +++ trunk/matplotlib/src/path_converters.h 2009-02-02 16:29:37 UTC (rev 6865) @@ -2,7 +2,6 @@ #define __PATH_CONVERTERS_H__ #include "CXX/Objects.hxx" -#define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" #include "agg_path_storage.h" #include "agg_clip_liang_barsky.h" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |