source: anuga_core/source/anuga/mesh_engine/mesh_engine_c_layer.c @ 4893

Last change on this file since 4893 was 4893, checked in by duncan, 16 years ago

comments

File size: 12.6 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     to return numeric arrays, check how it is done in
39     quantity_ext.c compute_gradients
40         
41     Precondition
42     End list in the pointattributelist has to have the same length
43     
44                                                 */
45
46
47#ifdef SINGLE 
48#define REAL float
49#else 
50#define REAL double
51#endif
52
53#include "triangle.h"
54
55#ifndef _STDLIB_H_
56#ifndef _WIN32
57extern "C" void *malloc(); 
58extern "C" void free(); 
59#endif
60#endif 
61
62#include "Python.h"
63
64#include "Numeric/arrayobject.h"
65
66
67 static PyObject *triang_genMesh(PyObject *self, PyObject *args){
68     
69  /* Mesh generation routine
70     pre-conditions:
71     mode must have a 'z' switch, to avoid segmentation faults
72     
73     shallow_water_ext.c gravity function
74  */
75   
76  struct triangulateio in,out;
77
78  struct triangulateio in_test;
79 
80  PyArrayObject *pointlist;
81  PyArrayObject *seglist;
82  PyArrayObject *holelist;
83  PyArrayObject *regionlist;
84  PyObject *mode;
85  PyArrayObject *pointattributelist;
86  PyArrayObject *segmarkerlist;
87  PyArrayObject *test;
88 
89 
90  PyArrayObject *r_test;
91  PyObject *R;
92
93  int dimensions[1];
94   
95  REAL Attr;
96  int i, j, iatt, n, write_here,N;
97  int a,b,c;
98  int marker;
99  int tuplesize;
100   
101  int index = 0;
102  double x,y;
103  PyObject *elems;
104  PyObject *pair;
105     
106  char *mod;
107  PyObject *holder, *holderlist, *attributelist;
108  int listsize,attsize ;
109  PyObject  *ii;
110 
111  /* used for testing numeric arrays*/
112  int n_test;     
113  if(!PyArg_ParseTuple(args,(char *)"OOOOOOOO",&pointlist,&seglist,&holelist,&regionlist,&pointattributelist,&segmarkerlist,&mode,&test)){
114    return NULL;
115  }
116 
117  /* Initialize  points */
118  in.numberofpoints =  pointlist-> dimensions[0]; 
119  in.pointlist = (double *) pointlist -> data;
120  in.pointmarkerlist = (int *)NULL; 
121 
122  /* Initialize and fill up region list */
123  in.numberofregions = regionlist-> dimensions[0]; 
124  in.regionlist = (double *) regionlist -> data;
125 
126  /*Initialize segments and segment markers */
127  in.numberofsegments = seglist -> dimensions[0]; 
128  in.segmentlist = (int *) seglist -> data;
129  /* in.segmentlist = (int *) test -> data; */
130  in.segmentmarkerlist = (int *) segmarkerlist -> data;
131 
132  /*Initialize triangles */
133  in.numberoftriangles = 0;
134  in.trianglelist = (int *)NULL;
135  in.numberoftriangleattributes = 0; 
136  in.triangleattributelist  = (REAL *)NULL; 
137     
138  /*Initialize holes */
139  in.numberofholes = holelist  -> dimensions[0];
140  if (in.numberofholes != 0) {
141    in.holelist =  (double *) holelist -> data; 
142  } else {
143    in.holelist = (REAL *)NULL;
144  }     
145 
146  /* Point attribute list */
147  if (0 == pointattributelist -> dimensions[0]) {
148    in.numberofpointattributes = 0;
149    in.pointattributelist =  NULL;
150  } else {
151    if (0 == pointattributelist -> dimensions[1]) {
152    in.numberofpointattributes = 0;
153    in.pointattributelist =  NULL;
154    } else {
155      in.numberofpointattributes = pointattributelist -> dimensions[1];
156      in.pointattributelist =  (double *) pointattributelist -> data;
157    }
158  }
159   
160  /* DEBUGGING
161  printf(" ***  hello world\n" ); 
162 
163  printf ("numberofpoints %i\n", in.numberofpoints);
164  for(i = 0; i < in.numberofpoints; i++) {
165    printf("(%f,%f)\n",in.pointlist[i* 2+ 0],in.pointlist[i* 2+ 1]);
166  }
167     
168  printf ("numberofregions %i\n", in.numberofregions);
169  for(i = 0; i < in.numberofregions; i++) {
170    printf("(%f,%f)\n",in.regionlist[i* 2+ 0],in.regionlist[i* 2+ 1]);
171  }
172   
173  printf ("numberofsegments %i\n", in.numberofsegments);
174  for(i = 0; i < in.numberofsegments; i++) {
175      printf("(%i,%i)",in.segmentlist[i* 2+ 0],in.segmentlist[i* 2+ 1]);
176      }
177 
178 
179  printf ("numberofholess %i\n", in.numberofholes);
180  for(i = 0; i < in.numberofholes; i++) {
181    printf("(%f,%f)\n",in.holelist[i* 2+ 0],in.holelist[i* 2+ 1]);
182  }
183     
184      printf ("numberoftriangles %i\n", in.numberoftriangles);
185      for(i = 0; i < in.numberoftriangles; i++) {
186      printf("(%i,%i,%i)",in.trianglelist[i* 3+ 0],in.trianglelist[i* 3+ 1], in.trianglelist[i* 3+ 2]);
187      }
188  printf(" ***  see ya world\n" );       */
189     
190  /* set up the switch arguments to the triangulation routine */
191  mod = PyString_AS_STRING(mode);
192     
193         
194  out.pointlist = (REAL *)NULL;
195  out.pointmarkerlist = (int *)NULL;
196  out.numberofpointattributes = in.numberofpointattributes;
197  out.pointattributelist = (REAL *)NULL;
198 
199  out.trianglelist = (int *)NULL;
200  out.triangleattributelist = (REAL *)NULL;                   
201  out.trianglearealist = (REAL *)NULL;                       
202  out.neighborlist = (int *)NULL;
203     
204  out.segmentlist = (int *)NULL;
205  out.segmentmarkerlist = (int *)NULL;
206     
207  out.edgelist = (int *)NULL;
208  out.edgemarkerlist = (int *)NULL;
209     
210  out.holelist = (REAL *)NULL;
211  out.regionlist = (REAL *)NULL;
212   
213 
214  /*printf("\n\nTriangulate input args: %s \n\n", mod); */
215  triangulate(mod, &in, &out, (struct triangulateio *)NULL );
216
217  /* printf(" ***  back from triangulate\n" );    */
218  /*
219    ------- Pass point numbers,coordinates and neighbors back to Python ------
220    we send back a dictionary:                                               
221    { index : [ coordinates, [connections], Attribute ] }
222  */
223  holder = PyDict_New();   
224 
225  /* Add triangle list */
226  listsize = out.numberoftriangles;
227  /* printf(" out.numberoftriangles %i\n", out.numberoftriangles ); */
228  holderlist = PyList_New(listsize);
229  for(i=0; i<listsize;i++){
230    PyObject *mlist = Py_BuildValue((char *)"(i,i,i)", 
231                                    out.trianglelist[i*3  ], out.trianglelist [i*3+1], out.trianglelist [i*3+2]);   
232    PyList_SetItem(holderlist,i, mlist);
233  }   
234  ii=PyString_FromString("generatedtrianglelist");
235  PyDict_SetItem(holder, ii, holderlist); Py_DECREF(ii); Py_DECREF(holderlist);
236     
237  /* Add pointlist */
238  listsize = out.numberofpoints;
239  holderlist = PyList_New(listsize);
240     
241  for(i=0; i<out.numberofpoints;i++){
242    PyObject *mlist = Py_BuildValue((char *)"(d,d)", 
243                                    out.pointlist[i*2  ], out.pointlist[i*2+1]); 
244    PyList_SetItem(holderlist,i, mlist);
245  } 
246  ii=PyString_FromString("generatedpointlist");
247  PyDict_SetItem(holder, ii, holderlist); Py_DECREF(ii); Py_DECREF(holderlist);
248 
249  /* Add point marker list */
250  listsize = out.numberofpoints;
251  holderlist = PyList_New(listsize);
252 
253  for(i=0; i<listsize;i++){
254    PyObject *mlist = Py_BuildValue((char *)"d", 
255                                    out.pointmarkerlist[i]);     
256    PyList_SetItem(holderlist,i, mlist); 
257  } 
258  ii=PyString_FromString("generatedpointmarkerlist");
259  PyDict_SetItem(holder, ii, holderlist); Py_DECREF(ii); Py_DECREF(holderlist);
260   
261  /* Add point attribute list */
262  listsize = out.numberofpoints;
263  holderlist = PyList_New(listsize);
264 
265  for(i=0; i<listsize;i++){
266    attsize = out.numberofpointattributes;
267    attributelist = PyList_New(attsize);
268    for(iatt=0; iatt<attsize;iatt++){
269      PyObject *mlist = Py_BuildValue((char *)"d", 
270                                      out.pointattributelist[i*attsize + iatt]);     
271      PyList_SetItem(attributelist,iatt, mlist);
272    }     
273    PyList_SetItem(holderlist,i, attributelist);
274  } 
275  ii=PyString_FromString("generatedpointattributelist");
276  PyDict_SetItem(holder, ii, holderlist); Py_DECREF(ii); Py_DECREF(holderlist); 
277 
278 
279  /* Add triangle attribute list */
280  listsize = out.numberoftriangles;
281  holderlist = PyList_New(listsize);
282     
283  for(i=0; i<listsize; i++){
284    attsize = out.numberoftriangleattributes;
285    attributelist = PyList_New(attsize);       
286    for(iatt=0; iatt<attsize;iatt++){
287      PyObject *mlist = Py_BuildValue((char *)"d",out.triangleattributelist[i*attsize + iatt]); 
288      PyList_SetItem(attributelist,iatt, mlist);
289    }     
290    PyList_SetItem(holderlist,i, attributelist);
291  } 
292  ii=PyString_FromString("generatedtriangleattributelist");
293  PyDict_SetItem(holder, ii, holderlist); Py_DECREF(ii); Py_DECREF(holderlist);
294 
295  /* Add segment list */
296  listsize = out.numberofsegments;
297  holderlist = PyList_New(listsize);
298  for(i=0; i<listsize;i++){
299    PyObject *mlist = Py_BuildValue((char *)"(i,i)", 
300                                    out.segmentlist[i*2  ],
301                                    out.segmentlist [i*2+1]);
302    PyList_SetItem(holderlist,i, mlist);
303  }   
304  ii=PyString_FromString("generatedsegmentlist");
305  PyDict_SetItem(holder, ii, holderlist); Py_DECREF(ii); Py_DECREF(holderlist); 
306 
307  /* Add segment marker list */
308  listsize = out.numberofsegments;
309  holderlist = PyList_New(listsize);
310  for(i=0; i<listsize;i++){
311    PyObject *mlist = Py_BuildValue((char *)"i", 
312                                    out.segmentmarkerlist[i]);
313    PyList_SetItem(holderlist,i, mlist);
314  }   
315  ii=PyString_FromString("generatedsegmentmarkerlist");
316  PyDict_SetItem(holder, ii, holderlist); Py_DECREF(ii); Py_DECREF(holderlist); 
317  /* Add triangle neighbor list */
318  if (out.neighborlist != NULL) {
319    listsize = out.numberoftriangles;
320    holderlist = PyList_New(listsize);
321    for(i=0; i<listsize;i++){
322      PyObject *mlist = Py_BuildValue((char *)"(i,i,i)", 
323                                      out.neighborlist[i*3  ],
324                                      out.neighborlist [i*3+1],
325                                      out.neighborlist [i*3+2]);   
326      PyList_SetItem(holderlist,i, mlist);
327    }   
328    ii=PyString_FromString("generatedtriangleneighborlist");
329    PyDict_SetItem(holder, ii, holderlist);
330    Py_DECREF(ii); Py_DECREF(holderlist);
331  }   
332  /*
333  // Testing passing a numeric array out
334  dimensions[0] = 4;
335  // Allocate space for return vectors a and b (don't DECREF)
336  // This is crashing - don't know why
337  r_test = (PyArrayObject *) PyArray_FromDims(1, dimensions, PyArray_DOUBLE);
338  */ 
339 
340  /* Free in/out structure memory */
341 
342  /* OUT */
343
344  if(!out.pointlist){
345    free(out.pointlist);  out.pointlist=NULL;
346  }
347  if(!out.pointmarkerlist){   
348    free(out.pointmarkerlist); out.pointmarkerlist=NULL;
349  }
350  if(!out.pointattributelist){   
351    free(out.pointattributelist); out.pointattributelist=NULL;
352  }   
353  if(!out.trianglelist){   
354    free(out.trianglelist); out.trianglelist=NULL;
355  }
356  if(!out.triangleattributelist){   
357    free(out.triangleattributelist); out.triangleattributelist=NULL;
358  }
359  if(!out.trianglearealist){   
360    free(out.trianglearealist); out.trianglearealist=NULL;
361  }
362  if(!out.neighborlist){   
363    free(out.neighborlist); out.neighborlist=NULL;
364  }
365  if(!out.segmentlist){
366    free(out.segmentlist); out.segmentlist =NULL;
367  }
368  if(!out.segmentmarkerlist){
369    free(out.segmentmarkerlist); out.segmentmarkerlist  =NULL;
370  }
371  if(!out.edgelist){
372    free(out.edgelist);  out.edgelist=NULL;
373  }
374  if(!out.edgemarkerlist){
375    free(out.edgemarkerlist);  out.edgemarkerlist=NULL;
376  }
377  if(!out.holelist){
378    free(out.holelist); out.holelist=NULL;
379  }
380  if(!out.regionlist){
381    free(out.regionlist); out.regionlist=NULL;
382  }
383 
384  /*Py_DECREF(holder);*/
385  R = Py_BuildValue((char *)"O", holder);
386  /*Py_DECREF(holder);* Try this to fix memory problems */
387  return R;
388}
389
390/* end of my function*/
391 
392static PyMethodDef triang_methods[] = {
393  {(char *)"genMesh", triang_genMesh, 1, (char *)"Passes hull points to triangle.All arguments are lists.(<hull>,<seglist>,<holelist>,<regionlist>)-><hull>"}, 
394  {NULL,NULL}
395};
396
397void initmesh_engine_c_layer(){
398  Py_InitModule((char *)"mesh_engine_c_layer",triang_methods);
399}   
Note: See TracBrowser for help on using the repository browser.