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

Last change on this file since 4158 was 4158, checked in by duncan, 17 years ago

committing files that should've been committed in r4144

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