~ubuntu-branches/ubuntu/trusty/qhull/trusty-proposed

« back to all changes in this revision

Viewing changes to src/user.c

  • Committer: Package Import Robot
  • Author(s): Barak A. Pearlmutter
  • Date: 2014-02-13 11:09:12 UTC
  • mfrom: (8.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20140213110912-ifwyxorlsnnl1ebh
Tags: 2012.1-4
Add convenience link to #include <qhull/qhull.h> to simplify transition.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
      use qh_NOmem in mem.h to turn off memory management
16
 
      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 "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
 
                               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