source: trunk/anuga_core/source/anuga/utilities/quad_tree_ext.c @ 8709

Last change on this file since 8709 was 8709, checked in by wilsonp, 11 years ago

Changes to fitsmooth.c to use PyCObject when Python version is detected as lower than 2.7.3. Also, small fixes to caching of quad tree.

File size: 7.5 KB
Line 
1
2#include "Python.h"
3
4#include <stdio.h>   /* gets */
5#include <stdlib.h>  /* atoi, malloc */
6#include <string.h>  /* strcpy */
7#include "numpy/arrayobject.h"
8#include "math.h"
9
10#include "util_ext.h" /* in utilities */
11#include "quad_tree.h"
12
13
14
15/*
16static int _serialise(quad_tree * quadtree, PyObject * serial_quadtree)
17{
18
19   
20    quad_tree_ll * nodelist = new_quad_tree_ll(quadtree,0);
21    quad_tree_ll * last = nodelist;
22    quad_tree_ll * temp;
23    int i;
24    int nlist = 0;
25    while(nodelist !=NULL){
26       
27        PyObject * nodedata = PyList_New(2);
28        quadtree=nodelist->tree;
29        // if children have been added, add to the linked list
30        PyObject * child_index;
31        if (quadtree->q[0]!=NULL){
32            child_index = PyList_New(4);
33            for (i=0;i<4;i++){
34                nlist++;
35                quad_tree_ll * child = new_quad_tree_ll(quadtree->q[i],nlist);
36                last->next=child;
37                last=child;
38                PyList_SET_ITEM(child_index,i,PyInt_FromLong((long) nlist));
39            }
40        }
41        else{
42            child_index = PyList_New(1);
43            PyList_SET_ITEM(child_index,0,PyInt_FromLong(0));
44        }
45        // get list of triangle indicies
46        triangle * T = quadtree->leaves;
47        int n_tris = 0 ;
48        while(T!=NULL)
49        {
50            n_tris+=1;
51            T=T->next;
52        }
53        PyObject * tri_list = PyList_New(n_tris);
54        T = quadtree->leaves;
55        i=0;
56        while(T!=NULL)
57        {
58            PyList_SET_ITEM(tri_list,i,PyInt_FromLong((long)T->index));
59            T=T->next;
60            i++;
61        }
62
63        // set data
64        PyList_SET_ITEM(nodedata,0,child_index);
65        PyList_SET_ITEM(nodedata,1,tri_list);
66        // add data to overall list
67        PyList_SET_ITEM(serial_quadtree, nodelist->index, nodedata);
68       
69        // set up next quad_tree to visit
70        temp = nodelist;
71        nodelist=nodelist->next;
72        free(temp);
73    }
74
75    return 0;
76}
77
78static void _deserialise_recursive(quad_tree * quadtree, PyListObject * serial_quadtree,
79        long * triangles,
80        double *vertex_coordinates,
81        long n)
82{
83
84    int k,k6;
85    double x0,y0,x1,y1,x2,y2;
86    PyObject * node = (PyObject*) PyList_GET_ITEM(serial_quadtree,n);
87    PyObject * children = (PyObject*) PyList_GET_ITEM(node,0);
88    PyObject * leaves = (PyObject*) PyList_GET_ITEM(node,1);
89
90    if((long)PyList_Size(children) == 4){
91        // has children
92        quad_tree_make_children(quadtree);
93        int i;
94        for(i=0;i<4;i++){
95            _deserialise_recursive(quadtree->q[i], serial_quadtree,
96                triangles,
97                vertex_coordinates,PyInt_AsLong(PyList_GET_ITEM(children,i)));
98        }
99    }
100
101    // add leaves
102    long n_leaves = (long) PyList_Size(leaves);
103    int i;
104    for(i=0;i<n_leaves;i++){
105        k = (int) PyInt_AsLong(PyList_GET_ITEM(leaves,i));
106        k6=k*6;
107        x0 = vertex_coordinates[k6];
108        y0 = vertex_coordinates[k6 + 1];
109        x1 = vertex_coordinates[k6 + 2];
110        y1 = vertex_coordinates[k6 + 3];
111        x2 = vertex_coordinates[k6 + 4];
112        y2 = vertex_coordinates[k6 + 5];
113        triangle * T = new_triangle(k,x0,y0,x1,y1,x2,y2);
114        quad_tree_add_triangle_to_list(quadtree,T);
115
116    }
117};
118
119static int _deserialise(quad_tree * quadtree, PyListObject * serial_quadtree,
120        long * triangles,
121        double *vertex_coordinates)
122
123{
124
125    int k,k6;
126    double x0,y0,x1,y1,x2,y2;
127    long n = 0;
128    // if the root node has children, build children, and then call recursive
129    // build on them
130    PyObject * node = (PyObject*) PyList_GET_ITEM(serial_quadtree,n);
131    PyObject * children = (PyObject*) PyList_GET_ITEM(node,0);
132    PyObject * leaves = (PyObject*) PyList_GET_ITEM(node,1);
133
134    if((long)PyList_Size(children) == 4){
135        // has children
136        quad_tree_make_children(quadtree);
137        int i;
138        for(i=0;i<4;i++){
139            _deserialise_recursive(quadtree->q[i], serial_quadtree,
140                triangles,
141                vertex_coordinates,PyInt_AsLong(PyList_GET_ITEM(children,i)));
142        }
143    }
144
145    // add leaves
146    long n_leaves = (long) PyList_Size(leaves);
147    int i;
148    for(i=0;i<n_leaves;i++){
149        k = (int) PyInt_AsLong(PyList_GET_ITEM(leaves,i));
150        k6=k*6;
151        x0 = vertex_coordinates[k6];
152        y0 = vertex_coordinates[k6 + 1];
153        x1 = vertex_coordinates[k6 + 2];
154        y1 = vertex_coordinates[k6 + 3];
155        x2 = vertex_coordinates[k6 + 4];
156        y2 = vertex_coordinates[k6 + 5];
157        triangle * T = new_triangle(k,x0,y0,x1,y1,x2,y2);
158        quad_tree_add_triangle_to_list(quadtree,T);
159    }
160
161    return 0;
162
163}
164
165*/
166
167static void delete_quad_tree_cap(PyObject * cap){
168
169    quad_tree * kill = (quad_tree*) PyCapsule_GetPointer(cap,"quad tree");
170    if(kill!=NULL){
171        delete_quad_tree(kill);
172    }
173}
174
175//----------------------- PYTHON WRAPPER FUNCTION -----------------------------
176
177/*
178static PyObject *serialise(PyObject *self, PyObject *args) {
179
180    int err;
181    PyObject *tree;
182    PyObject *serial_quadtree;
183
184    // Convert Python arguments to C
185    if (!PyArg_ParseTuple(args, "O",&tree
186                                            )) {
187      PyErr_SetString(PyExc_RuntimeError,
188              "quad_tree_ext.serialise: could not parse input");
189      return NULL;
190    }
191
192    quad_tree * quadtree = (quad_tree*) PyCapsule_GetPointer(tree,"quad tree");
193   
194    int nodes = quad_tree_node_count(quadtree);
195    serial_quadtree = PyList_New(nodes);
196
197    err = _serialise(quadtree,serial_quadtree);
198
199    if (err != 0) {
200      PyErr_SetString(PyExc_RuntimeError,
201              "quad_tree_ext.serialise: error in serialising quad tree");
202      return NULL;
203    }
204
205    return serial_quadtree;
206
207}
208
209static PyObject *deserialise(PyObject *self, PyObject *args) {
210
211    int err;
212    PyArrayObject *triangles;
213    PyArrayObject *vertex_coordinates;
214    PyArrayObject *extents;
215    PyListObject *serial_quadtree;
216
217    // Convert Python arguments to C
218    if (!PyArg_ParseTuple(args, "OOOO",&serial_quadtree,
219                                            &triangles,
220                                            &vertex_coordinates,
221                                            &extents
222                                            )) {
223      PyErr_SetString(PyExc_RuntimeError,
224              "quad_tree_ext.deserialise: could not parse input");
225      return NULL;
226    }
227    double * extents_v = (double *) extents->data;
228    quad_tree *quadtree = new_quad_tree(extents_v[0],extents_v[1],extents_v[2],extents_v[3]);
229    err = _deserialise(quadtree, serial_quadtree,
230        (long*) triangles->data,
231        (double*) vertex_coordinates -> data);
232
233    return  PyCapsule_New((void*) quadtree,
234                      "quad tree",
235                      &delete_quad_tree_cap);
236
237}
238*/
239
240//------------------------------------------------------------------------------
241
242
243// ------------------------------ PYTHON GLUE ----------------------------------
244
245//==============================================================================
246// Structures to allow calling from python
247//==============================================================================
248
249// Method table for python module
250static struct PyMethodDef MethodTable[] = {
251  //  {"serialise",serialise, METH_VARARGS, "Print out"},
252  //  {"deserialise",deserialise, METH_VARARGS, "Print out"},
253        {NULL, NULL, 0, NULL}   // sentinel
254};
255
256
257// Module initialisation
258void initquad_tree_ext(void){
259 
260  Py_InitModule("quad_tree_ext", MethodTable);
261  import_array(); // Necessary for handling of NumPY structures
262
263}
264
265// --------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.