int call_qhull (void) { int curlong, totlong, exitcode, numpoints, dim; coordT *points; boolT ismalloc; char *flags; qh_init_A (stdin, stdout, stderr, 0, NULL); exitcode= setjmp (qh errexit); if (!exitcode) { strcat (qh rbox_command, "user"); /* for documentation only */ qh_initflags ("qhull Tc (your flags go here)"); /* 1st word ignored */ /* define the input data */ points= array; /* an array of point coordinates */ ismalloc= False; /* True if qhull should 'free(points)' at end*/ dim= 3; /* dimension of points */ numpoints= 100; /* number of points */; /* For Delaunay triangulation ('d' or 'v'), set "qh PROJECTdelaunay= True" to project points to a paraboloid. You may project the points yourself. For halfspace intersection ('H'), compute the dual point array by "points= qh_sethalfspace_all (dim, numpoints, array, feasible);" */ qh_init_B (points, numpoints, dim, ismalloc); qh_qhull(); /* construct the hull */ /* For Voronoi centers ('v'), call qh_setvoronoi_all() */ qh_check_output(); /* optional */ qh_produce_output(); /* optional */ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone) qh_check_points(); /* optional */ /* exitcode == 0 */ } qh NOerrexit= True; qh_freeqhull(!qh_ALL); qh_memfreeshort (&curlong, &totlong); if (curlong || totlong) /* optional */ fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong); return exitcode; } /* call_qhull */
static PyObject* py_qconvex(PyObject *self, PyObject *args) { const char *arg; const char *data; int curlong, totlong; /* used !qh_NOmem */ int exitcode, numpoints, dim; coordT *points; boolT ismalloc; char* argv[10]; int argc = 1; char *rest; char *token; /* Defensively copy the string first */ char tempstr[30]; char* ptr; char *bp; size_t size; FILE* fin; FILE* fout; if (!PyArg_ParseTuple(args, "ss", &arg, &data)) return NULL; strcpy(tempstr, arg); ptr = tempstr; while(token = strtok_r(ptr, " ", &rest)) { argv[argc] = token; ptr = rest; argc += 1; } argv[0] = "qconvex"; /* Because qhull uses stdin and stdout streams for io, we need to create FILE* stream to simulate these io streams.*/ fin = fmemopen(data, strlen(data), "r"); fout = open_memstream(&bp, &size); if ((fin != NULL) && (fout != NULL)) { /* Now do the usual qhull code (modified from qconvex.c). */ qh_init_A(fin, fout, stderr, argc, argv); exitcode= setjmp(qh errexit); if (!exitcode) { qh_checkflags(qh qhull_command, hidden_options); qh_initflags(qh qhull_command); points= qh_readpoints(&numpoints, &dim, &ismalloc); if (dim >= 5) { qh_option("Qxact_merge", NULL, NULL); qh MERGEexact= True; } qh_init_B(points, numpoints, dim, ismalloc); qh_qhull(); qh_check_output(); qh_produce_output(); if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone) qh_check_points(); exitcode= qh_ERRnone; } qh NOerrexit= True; /* no more setjmp */ #ifdef qh_NOmem qh_freeqhull( True); #else qh_freeqhull( False); qh_memfreeshort(&curlong, &totlong); if (curlong || totlong) fprintf(stderr, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong); #endif fclose(fin); fclose(fout); return Py_BuildValue("s", bp); } else { return NULL; } }