source: branches/source_numpy_conversion/anuga/mesh_engine/mesh_engine_c_layer.c @ 6768

Last change on this file since 6768 was 5911, checked in by rwilson, 16 years ago

NumPy? conversion.

File size: 12.9 KB
Line 
1/* this appears to be necessary to run on Linux */
2
3#undef _STDLIB_H_
4#define _STDLIB_H_
5
6
7/*
8
9    This code interfaces pmesh directly with "triangle", a general       
10    purpose triangulation code. In doing so, Python Numeric data structures
11     are passed to C for  use by "triangle" and the results are then         
12    converted back. This was accomplished using the Python/C API.           
13                                                                           
14    I. Arrays of points,edges,holes, and regions must normally be
15     created for proper triangulation. However, if there are no holes,
16     the  hole list need not be specified (however, a
17     measure of control over the shape of the convex hull is lost;
18     triangle decides).
19     
20     points array: [(x1,y1),(x2,y2),...] ( doubles)                 
21     edge array: [(Ea,Eb),(Ef,Eg),...] ( integers)                   
22     hole array: [(x1,y1),...]( doubles, one inside each hole region)
23     region array: [ (x1,y1,index,area),...] ( doubles)               
24     pointattribute array:[ (a1,a2..),...] (doubles)
25     mode: String - the commands sent to triangle
26         
27     This is all that is needed to accomplish an intial triangulation.       
28     A dictionary of the Triangle output is returned.
29           
30     I thought this function was leaking. That the returned data
31     structure didn't get garbage collected.  I decided this using 
32     gc.get_objects() and seeing the dic still hanging around.
33     I'm not so sure this means its leaking.  Check by looking at
34     the overall memory use.  Anyhow, I delete the lists that are
35     returned in the dic structre after they are used now, in alpha
36     shape and mesh_engine.
37
38         
39     Precondition
40     End list in the pointattributelist has to have the same length
41     
42                                                 */
43
44
45#ifdef SINGLE 
46#define REAL float
47#else 
48#define REAL double
49#endif
50
51#include "triangle.h"
52
53#ifndef _STDLIB_H_
54#ifndef _WIN32
55extern "C" void *malloc(); 
56extern "C" void free(); 
57#endif
58#endif 
59
60#include "Python.h"
61
62//#define PY_ARRAY_UNIQUE_SYMBOL API_YEAH
63
64#define PY_ARRAY_UNIQUE_SYMBOL API_YEAH
65//#define NO_IMPORT_ARRAY
66//#include "numpy/oldnumeric.h"
67#include "numpy/arrayobject.h"
68#include <sys/types.h>
69
70 static PyObject *triang_genMesh(PyObject *self, PyObject *args){
71     
72  /* Mesh generation routine
73     pre-conditions:
74     mode must have a 'z' switch, to avoid segmentation faults
75     
76     shallow_water_ext.c gravity function
77  */
78   
79  struct triangulateio in,out;
80
81  struct triangulateio in_test;
82 
83  PyArrayObject *pointlist;
84  PyArrayObject *seglist;
85  PyArrayObject *holelist;
86  PyArrayObject *regionlist;
87  PyObject *mode;
88  PyArrayObject *pointattributelist;
89  PyArrayObject *segmarkerlist;
90  PyArrayObject *test;
91 
92 
93  PyArrayObject *gentrianglelist;
94  PyArrayObject *genpointlist;
95  PyArrayObject *genseglist;
96  PyArrayObject *genpointmarkerlist;
97  PyArrayObject *genpointattributelist;
98  PyArrayObject *gentriangleattributelist;
99  PyArrayObject *gensegmentlist;
100  PyArrayObject *gensegmentmarkerlist;
101  PyArrayObject *genneighborlist;
102  PyObject *R;
103
104  int dimensions[2];
105   
106  REAL Attr;
107  int i, j, iatt, n, write_here,N;
108  int a,b,c;
109  int marker;
110  int tuplesize;
111   
112  int index = 0;
113  double x,y;
114  PyObject *elems;
115  PyObject *pair;
116     
117  char *mod;
118   
119  if(!PyArg_ParseTuple(args,(char *)"OOOOOOO",&pointlist,&seglist,&holelist,&regionlist,&pointattributelist,&segmarkerlist,&mode)){
120    return NULL;
121  }
122 
123  /* Initialize  points */
124  in.numberofpoints =  pointlist-> dimensions[0]; 
125  in.pointlist = (double *) pointlist -> data;
126  in.pointmarkerlist = (int *)NULL; 
127 
128  /* Initialize and fill up region list */
129  in.numberofregions = regionlist-> dimensions[0]; 
130 
131  in.regionlist = (double *) regionlist -> data;
132 
133  /*Initialize segments and segment markers */
134  in.numberofsegments = seglist -> dimensions[0]; 
135  in.segmentlist = (int *) seglist -> data;
136  in.segmentmarkerlist = (int *) segmarkerlist -> data;
137  //in.segmentmarkerlist = (int *) NULL;
138 
139  /*Initialize triangles */
140  in.numberoftriangles = 0;
141  in.trianglelist = (int *)NULL;
142  in.numberoftriangleattributes = 0; 
143  in.triangleattributelist  = (REAL *)NULL; 
144  in.trianglearealist  = (REAL *)NULL; 
145  in.neighborlist = (int *)NULL;
146  in.numberofcorners = 0;
147     
148  /*Initialize holes */
149  in.numberofholes = holelist  -> dimensions[0];
150  if (in.numberofholes != 0) {
151    in.holelist =  (double *) holelist -> data; 
152  } else {
153    in.holelist = (REAL *)NULL;
154  }     
155 
156  /* Point attribute list */
157   /*printf ("in.pointattributelist -> dimensions[0] %i\n", pointattributelist -> dimensions[0]);
158  printf ("in.pointattributelist -> dimensions[1] %i\n", pointattributelist -> dimensions[1]); */
159  if (0 == pointattributelist -> dimensions[0]) {
160    in.numberofpointattributes = 0;
161    in.pointattributelist =  (double *) NULL;
162  } else {
163    if (0 == pointattributelist -> dimensions[1]) {
164    in.numberofpointattributes = 0;
165    in.pointattributelist =  (double *) NULL;
166    } else {
167      in.numberofpointattributes = pointattributelist -> dimensions[1];
168      in.pointattributelist =  (double *) pointattributelist -> data;
169    }
170  }
171   
172  /* DEBUGGING
173  printf(" ***  hello world\n" ); 
174 
175  printf ("numberofpoints %i\n", in.numberofpoints);
176  printf ("numberofpointattributes %i\n", in.numberofpointattributes);
177  for(i = 0; i < in.numberofpoints; i++) {
178    printf("(%f,%f)\n",in.pointlist[i* 2+ 0],in.pointlist[i* 2+ 1]);
179    for(j = 0; j < in.numberofpointattributes; j++) {
180      printf("point att (%f)\n",in.pointattributelist[i* in.numberofpointattributes + j]);
181    }
182   
183  }
184     
185  printf ("numberofregions %i\n", in.numberofregions);
186  for(i = 0; i < in.numberofregions; i++) {
187    printf("(%f,%f)  ",in.regionlist[i* 4+ 0],in.regionlist[i* 4+ 1]);
188    printf("index %f Area %f\n",in.regionlist[i* 4+ 2],in.regionlist[i* 4+ 3]);
189  }
190   
191  printf ("numberofsegments %i\n", in.numberofsegments);
192  for(i = 0; i < in.numberofsegments; i++) {
193      printf("(%i,%i)\n",in.segmentlist[i* 2+ 0],in.segmentlist[i* 2+ 1]);
194      printf("Segment marker (%i)\n",in.segmentmarkerlist[i + 0]);
195      }
196 
197 
198  printf ("numberofholess %i\n", in.numberofholes);
199  for(i = 0; i < in.numberofholes; i++) {
200    printf("(%f,%f)\n",in.holelist[i* 2+ 0],in.holelist[i* 2+ 1]);
201  }
202     
203      printf ("numberoftriangles %i\n", in.numberoftriangles);
204      for(i = 0; i < in.numberoftriangles; i++) {
205      printf("(%i,%i,%i)",in.trianglelist[i* 3+ 0],in.trianglelist[i* 3+ 1], in.trianglelist[i* 3+ 2]);
206      }
207  printf(" ***  see ya world\n" );       
208      */
209  /* set up the switch arguments to the triangulation routine */
210  mod = PyString_AS_STRING(mode);
211     
212         
213  out.pointlist = (REAL *)NULL;
214  out.pointmarkerlist = (int *)NULL;
215  //out.numberofpointattributes = in.numberofpointattributes;
216  out.pointattributelist = (REAL *)NULL;
217 
218  out.trianglelist = (int *)NULL;
219  out.triangleattributelist = (REAL *)NULL;                   
220  out.trianglearealist = (REAL *)NULL;                       
221  out.neighborlist = (int *)NULL;
222     
223  out.segmentlist = (int *)NULL;
224  out.segmentmarkerlist = (int *)NULL;
225     
226  out.edgelist = (int *)NULL;
227  out.edgemarkerlist = (int *)NULL;
228     
229  out.holelist = (REAL *)NULL;
230  out.regionlist = (REAL *)NULL;
231   
232 
233  triangulate(mod, &in, &out, (struct triangulateio *)NULL );
234 
235 
236   
237  /*
238    ------- Pass point numbers,coordinates and neighbors back to Python ------
239    we send back a dictionary:                                               
240    { index : [ coordinates, [connections], Attribute ] }
241  */ 
242 
243  /*
244 
245     to return numeric arrays, check how it is done in
246     abs quantity_ext.c compute_gradients
247     
248  PyArray_FromDims allolws you to create a Numeric array with unitialized data.
249   The first argument is the size of the second argument (
250   the dimensions array).
251    The dimension array argument is just a 1D C array where each element of
252     the array is the size of that dimension.
253     (int dimensions[2] = { 4, 3 }; defines a 4 by 3 array.)
254     The third argument is just the desired type.
255  */
256 
257 
258  /* Add triangle list */
259  dimensions[0] = out.numberoftriangles;
260  dimensions[1] = 3;   
261  gentrianglelist = (PyArrayObject *) PyArray_FromDimsAndData(2,
262                                            dimensions,
263                                            PyArray_INT, 
264                                            (char*) out.trianglelist); 
265   
266  /* Add pointlist */
267  dimensions[0] = out.numberofpoints;
268  dimensions[1] = 2;   
269  genpointlist = (PyArrayObject *) PyArray_FromDimsAndData(2,
270                                         dimensions,
271                                         PyArray_DOUBLE, 
272                                         (char*) out.pointlist);
273                                           
274 
275  /* Add point marker list */
276  dimensions[0] = out.numberofpoints;
277  genpointmarkerlist = (PyArrayObject *) PyArray_FromDimsAndData(1, 
278                                         dimensions, 
279                                         PyArray_INT,
280                                        (char*) out.pointmarkerlist);
281 
282  /* Add point attribute list */
283  dimensions[0] = out.numberofpoints;
284  dimensions[1] = out.numberofpointattributes;   
285  genpointattributelist = (PyArrayObject *) PyArray_FromDimsAndData(2, 
286                                          dimensions, 
287                                          PyArray_DOUBLE,
288                                          (char*) out.pointattributelist);
289 
290 
291 
292  /* Add triangle attribute list */
293  dimensions[0] = out.numberoftriangles;
294  dimensions[1] = out.numberoftriangleattributes;   
295  gentriangleattributelist = (PyArrayObject *) PyArray_FromDimsAndData(2, 
296                                           dimensions, 
297                                           PyArray_DOUBLE,
298                                          (char*)out.triangleattributelist);
299 
300  /* Add segment list */
301  dimensions[0] = out.numberofsegments;
302  dimensions[1] = 2;   
303  gensegmentlist = (PyArrayObject *) PyArray_FromDimsAndData(2, 
304                                                    dimensions, 
305                                                    PyArray_INT,
306                                                    (char*)out.segmentlist);
307 
308 
309  /* Add segment marker list */
310  dimensions[0] = out.numberofsegments;
311  gensegmentmarkerlist = (PyArrayObject *) PyArray_FromDimsAndData(1, 
312                                            dimensions, 
313                                            PyArray_INT,
314                                           (char*)out.segmentmarkerlist);
315 
316  /* Add triangle neighbor list */
317  if (out.neighborlist != NULL) {
318    dimensions[0] = out.numberoftriangles;
319    dimensions[1] = 3;   
320    genneighborlist = (PyArrayObject *) PyArray_FromDimsAndData(2, 
321                                                 dimensions, 
322                                                 PyArray_INT,
323                                                 (char*)out.neighborlist);
324  }else{ 
325    dimensions[0] = 0;
326    dimensions[1] = 0;   
327    genneighborlist = (PyArrayObject *) PyArray_FromDims(2, 
328                                                         dimensions, 
329                                                         PyArray_INT);
330  }
331 
332 
333  R = Py_BuildValue((char *)"OOOOOOOO"
334                    ,PyArray_Return(gentrianglelist)
335                    ,PyArray_Return(genpointlist)
336                    ,PyArray_Return(genpointmarkerlist)
337                    ,PyArray_Return(genpointattributelist)
338                    ,PyArray_Return(gentriangleattributelist)
339                    ,PyArray_Return(gensegmentlist)
340                    ,PyArray_Return(gensegmentmarkerlist)
341                    ,PyArray_Return(genneighborlist)
342                    );
343                   
344  Py_DECREF(gentrianglelist);
345  Py_DECREF(genpointlist);
346  Py_DECREF(genpointmarkerlist);
347  Py_DECREF(genpointattributelist);
348  Py_DECREF(gentriangleattributelist);
349  Py_DECREF(gensegmentlist);
350  Py_DECREF(gensegmentmarkerlist);
351  Py_DECREF(genneighborlist);
352 
353 
354  /* These memory blocks are passed into Numeric arrays
355   so don't free them  */
356  /*
357  if(!out.trianglelist){   
358    free(out.trianglelist); out.trianglelist=NULL;
359   
360   
361  if(!out.pointlist){
362    free(out.pointlist);  out.pointlist=NULL;
363  } 
364 
365  if(!out.pointmarkerlist){   
366    free(out.pointmarkerlist); out.pointmarkerlist=NULL;
367  }
368 
369  if(!out.pointattributelist){   
370    free(out.pointattributelist); out.pointattributelist=NULL;
371  }   
372 
373  if(!out.triangleattributelist){   
374    free(out.triangleattributelist); out.triangleattributelist=NULL;
375  }
376  if(!out.segmentlist){
377    free(out.segmentlist); out.segmentlist =NULL;
378  }
379  if(!out.segmentmarkerlist){
380    free(out.segmentmarkerlist); out.segmentmarkerlist  =NULL;
381  }
382  if(!out.neighborlist){   
383    free(out.neighborlist); out.neighborlist=NULL;
384  }
385   */
386
387   
388 
389  /* Free in/out structure memory */
390 
391  if(!out.trianglearealist){   
392    free(out.trianglearealist); out.trianglearealist=NULL;
393  }
394  if(!out.edgelist){
395    free(out.edgelist);  out.edgelist=NULL;
396  }
397  if(!out.edgemarkerlist){
398    free(out.edgemarkerlist);  out.edgemarkerlist=NULL;
399  }
400  if(!out.holelist){
401    free(out.holelist); out.holelist=NULL;
402  }
403  if(!out.regionlist){
404    free(out.regionlist); out.regionlist=NULL;
405  }
406  return R;
407}
408
409/* end of my function*/
410 
411static PyMethodDef triang_methods[] = {
412  {(char *)"genMesh", triang_genMesh, 1, (char *)"Passes hull points to triangle.All arguments are lists.(<hull>,<seglist>,<holelist>,<regionlist>)-><hull>"}, 
413  {NULL,NULL}
414};
415
416void initmesh_engine_c_layer(){
417  Py_InitModule((char *)"mesh_engine_c_layer",triang_methods);
418 
419  import_array(); // Necessary for handling of NumPY structures
420}   
Note: See TracBrowser for help on using the repository browser.