ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/QuickHull/user.c
Revision: 3138
Committed: Tue May 29 22:51:00 2007 UTC (17 years, 11 months ago) by chuckv
Content type: text/plain
File size: 11132 byte(s)
Log Message:
Addded QuickHull to cvs.

File Contents

# Content
1 /*<html><pre> -<a href="qh-user.htm"
2 >-------------------------------</a><a name="TOP">-</a>
3
4 user.c
5 user redefinable functions
6
7 see README.txt see COPYING.txt for copyright information.
8
9 see qhull.h for data structures, macros, and user-callable functions.
10
11 see user_eg.c, unix.c, and qhull_interface.cpp for examples.
12
13 see user.h for user-definable constants
14
15 please use qh_NOmem in mem.h to turn off memory management
16 please use qh_NOmerge in user.h to turn off facet merging
17 set qh_KEEPstatistics in user.h to 0 to turn off statistics
18
19 This is unsupported software. You're welcome to make changes,
20 but you're on your own if something goes wrong. Use 'Tc' to
21 check frequently. Usually qhull will report an error if
22 a data structure becomes inconsistent. If so, it also reports
23 the last point added to the hull, e.g., 102. You can then trace
24 the execution of qhull with "T4P102".
25
26 Please report any errors that you fix to qhull@qhull.org
27
28 call_qhull is a template for calling qhull from within your application
29
30 if you recompile and load this module, then user.o will not be loaded
31 from qhull.a
32
33 you can add additional quick allocation sizes in qh_user_memsizes
34
35 if the other functions here are redefined to not use qh_print...,
36 then io.o will not be loaded from qhull.a. See user_eg.c for an
37 example. We recommend keeping io.o for the extra debugging
38 information it supplies.
39 */
40
41 #include "QuickHull/qhull_a.h"
42
43 /*-<a href="qh-user.htm#TOC"
44 >-------------------------------</a><a name="call_qhull">-</a>
45
46 qh_call_qhull( void )
47 template for calling qhull from inside your program
48 remove #if 0, #endif to compile
49
50 returns:
51 exit code (see qh_ERR... in qhull.h)
52 all memory freed
53
54 notes:
55 This can be called any number of times.
56
57 see:
58 qh_call_qhull_once()
59
60 */
61 #if 0
62 {
63 int dim; /* dimension of points */
64 int numpoints; /* number of points */
65 coordT *points; /* array of coordinates for each point */
66 boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
67 char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
68 FILE *outfile= stdout; /* output from qh_produce_output()
69 please use NULL to skip qh_produce_output() */
70 FILE *errfile= stderr; /* error messages from qhull code */
71 int exitcode; /* 0 if no error from qhull */
72 facetT *facet; /* set by FORALLfacets */
73 int curlong, totlong; /* memory remaining after qh_memfreeshort */
74
75 /* initialize dim, numpoints, points[], ismalloc here */
76 exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
77 flags, outfile, errfile);
78 if (!exitcode) { /* if no error */
79 /* 'qh facet_list' contains the convex hull */
80 FORALLfacets {
81 /* ... your code ... */
82 }
83 }
84 qh_freeqhull(!qh_ALL);
85 qh_memfreeshort (&curlong, &totlong);
86 if (curlong || totlong)
87 fprintf (errfile, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
88 }
89 #endif
90
91 /*-<a href="qh-user.htm#TOC"
92 >-------------------------------</a><a name="new_qhull">-</a>
93
94 qh_new_qhull( dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
95 build new qhull data structure and return exitcode (0 if no errors)
96
97 notes:
98 do not modify points until finished with results.
99 The qhull data structure contains pointers into the points array.
100 do not call qhull functions before qh_new_qhull().
101 The qhull data structure is not initialized until qh_new_qhull().
102
103 outfile may be null
104 qhull_cmd must start with "qhull "
105 projects points to a new point array for Delaunay triangulations ('d' and 'v')
106 transforms points into a new point array for halfspace intersection ('H')
107
108
109 To allow multiple, concurrent calls to qhull()
110 - set qh_QHpointer in user.h
111 - use qh_save_qhull and qh_restore_qhull to swap the global data structure between calls.
112 - use qh_freeqhull(qh_ALL) to free intermediate convex hulls
113
114 see:
115 user_eg.c for an example
116 */
117 int qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc,
118 char *qhull_cmd, FILE *outfile, FILE *errfile) {
119 int exitcode, hulldim;
120 boolT new_ismalloc;
121 static boolT firstcall = True;
122 coordT *new_points;
123
124 if (firstcall) {
125 qh_meminit (errfile);
126 firstcall= False;
127 }
128 if (strncmp (qhull_cmd,"qhull ", 6)) {
129 fprintf (errfile, "qh_new_qhull: start qhull_cmd argument with \"qhull \"\n");
130 exit(1);
131 }
132 qh_initqhull_start (NULL, outfile, errfile);
133 trace1(( qh ferr, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
134 exitcode = setjmp (qh errexit);
135 if (!exitcode)
136 {
137 qh NOerrexit = False;
138 qh_initflags (qhull_cmd);
139 if (qh DELAUNAY)
140 qh PROJECTdelaunay= True;
141 if (qh HALFspace) {
142 /* points is an array of halfspaces,
143 the last coordinate of each halfspace is its offset */
144 hulldim= dim-1;
145 qh_setfeasible (hulldim);
146 new_points= qh_sethalfspace_all (dim, numpoints, points, qh feasible_point);
147 new_ismalloc= True;
148 if (ismalloc)
149 free (points);
150 }else {
151 hulldim= dim;
152 new_points= points;
153 new_ismalloc= ismalloc;
154 }
155 qh_init_B (new_points, numpoints, hulldim, new_ismalloc);
156 qh_qhull();
157 qh_check_output();
158 if (outfile)
159 qh_produce_output();
160 if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
161 qh_check_points();
162 }
163 qh NOerrexit = True;
164 return exitcode;
165 } /* new_qhull */
166
167 /*-<a href="qh-user.htm#TOC"
168 >-------------------------------</a><a name="errexit">-</a>
169
170 qh_errexit( exitcode, facet, ridge )
171 report and exit from an error
172 report facet and ridge if non-NULL
173 reports useful information such as last point processed
174 set qh.FORCEoutput to print neighborhood of facet
175
176 see:
177 qh_errexit2() in qhull.c for printing 2 facets
178
179 design:
180 check for error within error processing
181 compute qh.hulltime
182 print facet and ridge (if any)
183 report commandString, options, qh.furthest_id
184 print summary and statistics (including precision statistics)
185 if qh_ERRsingular
186 print help text for singular data set
187 exit program via long jump (if defined) or exit()
188 */
189 void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
190
191 if (qh ERREXITcalled) {
192 fprintf (qh ferr, "\nqhull error while processing previous error. Exit program\n");
193 exit(1);
194 }
195 qh ERREXITcalled= True;
196 if (!qh QHULLfinished)
197 qh hulltime= qh_CPUclock - qh hulltime;
198 qh_errprint("ERRONEOUS", facet, NULL, ridge, NULL);
199 fprintf (qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
200 fprintf(qh ferr, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options);
201 if (qh furthest_id >= 0) {
202 fprintf(qh ferr, "Last point added to hull was p%d.", qh furthest_id);
203 if (zzval_(Ztotmerge))
204 fprintf(qh ferr, " Last merge was #%d.", zzval_(Ztotmerge));
205 if (qh QHULLfinished)
206 fprintf(qh ferr, "\nQhull has finished constructing the hull.");
207 else if (qh POSTmerging)
208 fprintf(qh ferr, "\nQhull has started post-merging.");
209 fprintf (qh ferr, "\n");
210 }
211 if (qh FORCEoutput && (qh QHULLfinished || (!facet && !ridge)))
212 qh_produce_output();
213 else {
214 if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh hull_dim+1) {
215 fprintf (qh ferr, "\nAt error exit:\n");
216 qh_printsummary (qh ferr);
217 if (qh PRINTstatistics) {
218 qh_collectstatistics();
219 qh_printstatistics(qh ferr, "at error exit");
220 qh_memstatistics (qh ferr);
221 }
222 }
223 if (qh PRINTprecision)
224 qh_printstats (qh ferr, qhstat precision, NULL);
225 }
226 if (!exitcode)
227 exitcode= qh_ERRqhull;
228 else if (exitcode == qh_ERRsingular)
229 qh_printhelp_singular(qh ferr);
230 else if (exitcode == qh_ERRprec && !qh PREmerge)
231 qh_printhelp_degenerate (qh ferr);
232 if (qh NOerrexit) {
233 fprintf (qh ferr, "qhull error while ending program. Exit program\n");
234 exit(1);
235 }
236 qh NOerrexit= True;
237 longjmp(qh errexit, exitcode);
238 } /* errexit */
239
240
241 /*-<a href="qh-user.htm#TOC"
242 >-------------------------------</a><a name="errprint">-</a>
243
244 qh_errprint( fp, string, atfacet, otherfacet, atridge, atvertex )
245 prints out the information of facets and ridges to fp
246 also prints neighbors and geomview output
247
248 notes:
249 except for string, any parameter may be NULL
250 */
251 void qh_errprint(char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
252 int i;
253
254 if (atfacet) {
255 fprintf(qh ferr, "%s FACET:\n", string);
256 qh_printfacet(qh ferr, atfacet);
257 }
258 if (otherfacet) {
259 fprintf(qh ferr, "%s OTHER FACET:\n", string);
260 qh_printfacet(qh ferr, otherfacet);
261 }
262 if (atridge) {
263 fprintf(qh ferr, "%s RIDGE:\n", string);
264 qh_printridge(qh ferr, atridge);
265 if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
266 qh_printfacet(qh ferr, atridge->top);
267 if (atridge->bottom
268 && atridge->bottom != atfacet && atridge->bottom != otherfacet)
269 qh_printfacet(qh ferr, atridge->bottom);
270 if (!atfacet)
271 atfacet= atridge->top;
272 if (!otherfacet)
273 otherfacet= otherfacet_(atridge, atfacet);
274 }
275 if (atvertex) {
276 fprintf(qh ferr, "%s VERTEX:\n", string);
277 qh_printvertex (qh ferr, atvertex);
278 }
279 if (qh fout && qh FORCEoutput && atfacet && !qh QHULLfinished && !qh IStracing) {
280 fprintf(qh ferr, "ERRONEOUS and NEIGHBORING FACETS to output\n");
281 for (i= 0; i < qh_PRINTEND; i++) /* use fout for geomview output */
282 qh_printneighborhood (qh fout, qh PRINTout[i], atfacet, otherfacet,
283 !qh_ALL);
284 }
285 } /* errprint */
286
287
288 /*-<a href="qh-user.htm#TOC"
289 >-------------------------------</a><a name="printfacetlist">-</a>
290
291 qh_printfacetlist( fp, facetlist, facets, printall )
292 print all fields for a facet list and/or set of facets to fp
293 if !printall,
294 only prints good facets
295
296 notes:
297 also prints all vertices
298 */
299 void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
300 facetT *facet, **facetp;
301
302 qh_printbegin (qh ferr, qh_PRINTfacets, facetlist, facets, printall);
303 FORALLfacet_(facetlist)
304 qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
305 FOREACHfacet_(facets)
306 qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
307 qh_printend (qh ferr, qh_PRINTfacets, facetlist, facets, printall);
308 } /* printfacetlist */
309
310
311 /*-<a href="qh-globa.htm#TOC"
312 >-------------------------------</a><a name="user_memsizes">-</a>
313
314 qh_user_memsizes()
315 allocate up to 10 additional, quick allocation sizes
316
317 notes:
318 increase maximum number of allocations in qh_initqhull_mem()
319 */
320 void qh_user_memsizes (void) {
321
322 /* qh_memsize (size); */
323 } /* user_memsizes */
324