global.c
Go to the documentation of this file.
00001 
00002 /*<html><pre>  -<a                             href="qh-globa.htm"
00003   >-------------------------------</a><a name="TOP">-</a>
00004 
00005    global.c
00006    initializes all the globals of the qhull application
00007 
00008    see README
00009 
00010    see libqhull.h for qh.globals and function prototypes
00011 
00012    see qhull_a.h for internal functions
00013 
00014    Copyright (c) 1993-2011 The Geometry Center.
00015    $Id: //main/2011/qhull/src/libqhull/global.c#9 $$Change: 1446 $
00016    $DateTime: 2011/11/29 20:37:41 $$Author: bbarber $
00017  */
00018 
00019 #include "qhull_a.h"
00020 
00021 /*========= qh definition -- globals defined in libqhull.h =======================*/
00022 
00023 int qhull_inuse= 0; /* not used */
00024 
00025 #if qh_QHpointer
00026 qhT *qh_qh= NULL;       /* pointer to all global variables */
00027 #else
00028 qhT qh_qh;              /* all global variables.
00029                            Add "= {0}" if this causes a compiler error.
00030                            Also qh_qhstat in stat.c and qhmem in mem.c.  */
00031 #endif
00032 
00033 /*-<a                             href  ="qh-globa.htm#TOC"
00034   >--------------------------------</a><a name="qh_version">-</a>
00035 
00036   qh_version
00037     version string by year and date
00038 
00039     the revision increases on code changes only
00040 
00041   notes:
00042     change date:    Changes.txt, Announce.txt, index.htm, README.txt,
00043                     qhull-news.html, Eudora signatures, CMakeLists.txt
00044     change version: README.txt, qh-get.htm, File_id.diz, Makefile.txt
00045     change year:    Copying.txt
00046     check download size
00047     recompile user_eg.c, rbox.c, libqhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c
00048 */
00049 
00050 const char *qh_version = "2011.2 2011/11/29";
00051 
00052 /*-<a                             href="qh-globa.htm#TOC"
00053   >-------------------------------</a><a name="appendprint">-</a>
00054 
00055   qh_appendprint( printFormat )
00056     append printFormat to qh.PRINTout unless already defined
00057 */
00058 void qh_appendprint(qh_PRINT format) {
00059   int i;
00060 
00061   for (i=0; i < qh_PRINTEND; i++) {
00062     if (qh PRINTout[i] == format && format != qh_PRINTqhull)
00063       break;
00064     if (!qh PRINTout[i]) {
00065       qh PRINTout[i]= format;
00066       break;
00067     }
00068   }
00069 } /* appendprint */
00070 
00071 /*-<a                             href="qh-globa.htm#TOC"
00072   >-------------------------------</a><a name="checkflags">-</a>
00073 
00074   qh_checkflags( commandStr, hiddenFlags )
00075     errors if commandStr contains hiddenFlags
00076     hiddenFlags starts and ends with a space and is space deliminated (checked)
00077 
00078   notes:
00079     ignores first word (e.g., "qconvex i")
00080     use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
00081 
00082   see:
00083     qh_initflags() initializes Qhull according to commandStr
00084 */
00085 void qh_checkflags(char *command, char *hiddenflags) {
00086   char *s= command, *t, *chkerr; /* qh_skipfilename is non-const */
00087   char key, opt, prevopt;
00088   char chkkey[]= "   ";
00089   char chkopt[]=  "    ";
00090   char chkopt2[]= "     ";
00091   boolT waserr= False;
00092 
00093   if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
00094     qh_fprintf(qh ferr, 6026, "qhull error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"", hiddenflags);
00095     qh_errexit(qh_ERRinput, NULL, NULL);
00096   }
00097   if (strpbrk(hiddenflags, ",\n\r\t")) {
00098     qh_fprintf(qh ferr, 6027, "qhull error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"", hiddenflags);
00099     qh_errexit(qh_ERRinput, NULL, NULL);
00100   }
00101   while (*s && !isspace(*s))  /* skip program name */
00102     s++;
00103   while (*s) {
00104     while (*s && isspace(*s))
00105       s++;
00106     if (*s == '-')
00107       s++;
00108     if (!*s)
00109       break;
00110     key = *s++;
00111     chkerr = NULL;
00112     if (key == 'T' && (*s == 'I' || *s == 'O')) {  /* TI or TO 'file name' */
00113       s= qh_skipfilename(++s);
00114       continue;
00115     }
00116     chkkey[1]= key;
00117     if (strstr(hiddenflags, chkkey)) {
00118       chkerr= chkkey;
00119     }else if (isupper(key)) {
00120       opt= ' ';
00121       prevopt= ' ';
00122       chkopt[1]= key;
00123       chkopt2[1]= key;
00124       while (!chkerr && *s && !isspace(*s)) {
00125         opt= *s++;
00126         if (isalpha(opt)) {
00127           chkopt[2]= opt;
00128           if (strstr(hiddenflags, chkopt))
00129             chkerr= chkopt;
00130           if (prevopt != ' ') {
00131             chkopt2[2]= prevopt;
00132             chkopt2[3]= opt;
00133             if (strstr(hiddenflags, chkopt2))
00134               chkerr= chkopt2;
00135           }
00136         }else if (key == 'Q' && isdigit(opt) && prevopt != 'b'
00137               && (prevopt == ' ' || islower(prevopt))) {
00138             chkopt[2]= opt;
00139             if (strstr(hiddenflags, chkopt))
00140               chkerr= chkopt;
00141         }else {
00142           qh_strtod(s-1, &t);
00143           if (s < t)
00144             s= t;
00145         }
00146         prevopt= opt;
00147       }
00148     }
00149     if (chkerr) {
00150       *chkerr= '\'';
00151       chkerr[strlen(chkerr)-1]=  '\'';
00152       qh_fprintf(qh ferr, 6029, "qhull error: option %s is not used with this program.\n             It may be used with qhull.\n", chkerr);
00153       waserr= True;
00154     }
00155   }
00156   if (waserr)
00157     qh_errexit(qh_ERRinput, NULL, NULL);
00158 } /* checkflags */
00159 
00160 /*-<a                             href="qh-globa.htm#TOC"
00161   >-------------------------------</a><a name="qh_clear_outputflags">-</a>
00162 
00163   qh_clear_outputflags()
00164     Clear output flags for QhullPoints
00165 */
00166 void qh_clear_outputflags(void) {
00167   int i,k;
00168 
00169   qh ANNOTATEoutput= False;
00170   qh DOintersections= False;
00171   qh DROPdim= -1;
00172   qh FORCEoutput= False;
00173   qh GETarea= False;
00174   qh GOODpoint= 0;
00175   qh GOODpointp= NULL;
00176   qh GOODthreshold= False;
00177   qh GOODvertex= 0;
00178   qh GOODvertexp= NULL;
00179   qh IStracing= 0;
00180   qh KEEParea= False;
00181   qh KEEPmerge= False;
00182   qh KEEPminArea= REALmax;
00183   qh PRINTcentrums= False;
00184   qh PRINTcoplanar= False;
00185   qh PRINTdots= False;
00186   qh PRINTgood= False;
00187   qh PRINTinner= False;
00188   qh PRINTneighbors= False;
00189   qh PRINTnoplanes= False;
00190   qh PRINToptions1st= False;
00191   qh PRINTouter= False;
00192   qh PRINTprecision= True;
00193   qh PRINTridges= False;
00194   qh PRINTspheres= False;
00195   qh PRINTstatistics= False;
00196   qh PRINTsummary= False;
00197   qh PRINTtransparent= False;
00198   qh SPLITthresholds= False;
00199   qh TRACElevel= 0;
00200   qh TRInormals= False;
00201   qh USEstdout= False;
00202   qh VERIFYoutput= False;
00203   for (k=qh input_dim+1; k--; ) {  /* duplicated in qh_initqhull_buffers and qh_clear_ouputflags */
00204     qh lower_threshold[k]= -REALmax;
00205     qh upper_threshold[k]= REALmax;
00206     qh lower_bound[k]= -REALmax;
00207     qh upper_bound[k]= REALmax;
00208   }
00209 
00210   for (i=0; i < qh_PRINTEND; i++) {
00211     qh PRINTout[i]= qh_PRINTnone;
00212   }
00213 
00214   if (!qh qhull_commandsiz2)
00215       qh qhull_commandsiz2= (int)strlen(qh qhull_command); /* WARN64 */
00216   else {
00217       qh qhull_command[qh qhull_commandsiz2]= '\0';
00218   }
00219   if (!qh qhull_optionsiz2)
00220     qh qhull_optionsiz2= (int)strlen(qh qhull_options);  /* WARN64 */
00221   else {
00222     qh qhull_options[qh qhull_optionsiz2]= '\0';
00223     qh qhull_optionlen= qh_OPTIONline;  /* start a new line */
00224   }
00225 } /* clear_outputflags */
00226 
00227 /*-<a                             href="qh-globa.htm#TOC"
00228   >-------------------------------</a><a name="clock">-</a>
00229 
00230   qh_clock()
00231     return user CPU time in 100ths (qh_SECtick)
00232     only defined for qh_CLOCKtype == 2
00233 
00234   notes:
00235     use first value to determine time 0
00236     from Stevens '92 8.15
00237 */
00238 unsigned long qh_clock(void) {
00239 
00240 #if (qh_CLOCKtype == 2)
00241   struct tms time;
00242   static long clktck;  /* initialized first call */
00243   double ratio, cpu;
00244   unsigned long ticks;
00245 
00246   if (!clktck) {
00247     if ((clktck= sysconf(_SC_CLK_TCK)) < 0) {
00248       qh_fprintf(qh ferr, 6030, "qhull internal error (qh_clock): sysconf() failed.  Use qh_CLOCKtype 1 in user.h\n");
00249       qh_errexit(qh_ERRqhull, NULL, NULL);
00250     }
00251   }
00252   if (times(&time) == -1) {
00253     qh_fprintf(qh ferr, 6031, "qhull internal error (qh_clock): times() failed.  Use qh_CLOCKtype 1 in user.h\n");
00254     qh_errexit(qh_ERRqhull, NULL, NULL);
00255   }
00256   ratio= qh_SECticks / (double)clktck;
00257   ticks= time.tms_utime * ratio;
00258   return ticks;
00259 #else
00260   qh_fprintf(qh ferr, 6032, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user.h\n");
00261   qh_errexit(qh_ERRqhull, NULL, NULL); /* never returns */
00262   return 0;
00263 #endif
00264 } /* clock */
00265 
00266 /*-<a                             href="qh-globa.htm#TOC"
00267   >-------------------------------</a><a name="freebuffers">-</a>
00268 
00269   qh_freebuffers()
00270     free up global memory buffers
00271 
00272   notes:
00273     must match qh_initbuffers()
00274 */
00275 void qh_freebuffers(void) {
00276 
00277   trace5((qh ferr, 5001, "qh_freebuffers: freeing up global memory buffers\n"));
00278   /* allocated by qh_initqhull_buffers */
00279   qh_memfree(qh NEARzero, qh hull_dim * sizeof(realT));
00280   qh_memfree(qh lower_threshold, (qh input_dim+1) * sizeof(realT));
00281   qh_memfree(qh upper_threshold, (qh input_dim+1) * sizeof(realT));
00282   qh_memfree(qh lower_bound, (qh input_dim+1) * sizeof(realT));
00283   qh_memfree(qh upper_bound, (qh input_dim+1) * sizeof(realT));
00284   qh_memfree(qh gm_matrix, (qh hull_dim+1) * qh hull_dim * sizeof(coordT));
00285   qh_memfree(qh gm_row, (qh hull_dim+1) * sizeof(coordT *));
00286   qh NEARzero= qh lower_threshold= qh upper_threshold= NULL;
00287   qh lower_bound= qh upper_bound= NULL;
00288   qh gm_matrix= NULL;
00289   qh gm_row= NULL;
00290   qh_setfree(&qh other_points);
00291   qh_setfree(&qh del_vertices);
00292   qh_setfree(&qh coplanarfacetset);
00293   if (qh line)                /* allocated by qh_readinput, freed if no error */
00294     qh_free(qh line);
00295   if (qh half_space)
00296     qh_free(qh half_space);
00297   if (qh temp_malloc)
00298     qh_free(qh temp_malloc);
00299   if (qh feasible_point)      /* allocated by qh_readfeasible */
00300     qh_free(qh feasible_point);
00301   if (qh feasible_string)     /* allocated by qh_initflags */
00302     qh_free(qh feasible_string);
00303   qh line= qh feasible_string= NULL;
00304   qh half_space= qh feasible_point= qh temp_malloc= NULL;
00305   /* usually allocated by qh_readinput */
00306   if (qh first_point && qh POINTSmalloc) {
00307     qh_free(qh first_point);
00308     qh first_point= NULL;
00309   }
00310   if (qh input_points && qh input_malloc) { /* set by qh_joggleinput */
00311     qh_free(qh input_points);
00312     qh input_points= NULL;
00313   }
00314   trace5((qh ferr, 5002, "qh_freebuffers: finished\n"));
00315 } /* freebuffers */
00316 
00317 
00318 /*-<a                             href="qh-globa.htm#TOC"
00319   >-------------------------------</a><a name="freebuild">-</a>
00320 
00321   qh_freebuild( allmem )
00322     free global memory used by qh_initbuild and qh_buildhull
00323     if !allmem,
00324       does not free short memory (e.g., facetT, freed by qh_memfreeshort)
00325 
00326   design:
00327     free centrums
00328     free each vertex
00329     mark unattached ridges
00330     for each facet
00331       free ridges
00332       free outside set, coplanar set, neighbor set, ridge set, vertex set
00333       free facet
00334     free hash table
00335     free interior point
00336     free merge set
00337     free temporary sets
00338 */
00339 void qh_freebuild(boolT allmem) {
00340   facetT *facet;
00341   vertexT *vertex;
00342   ridgeT *ridge, **ridgep;
00343   mergeT *merge, **mergep;
00344 
00345   trace1((qh ferr, 1005, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
00346   if (qh del_vertices)
00347     qh_settruncate(qh del_vertices, 0);
00348   if (allmem) {
00349     while ((vertex= qh vertex_list)) {
00350       if (vertex->next)
00351         qh_delvertex(vertex);
00352       else {
00353         qh_memfree(vertex, (int)sizeof(vertexT));
00354         qh newvertex_list= qh vertex_list= NULL;
00355       }
00356     }
00357   }else if (qh VERTEXneighbors) {
00358     FORALLvertices
00359       qh_setfreelong(&(vertex->neighbors));
00360   }
00361   qh VERTEXneighbors= False;
00362   qh GOODclosest= NULL;
00363   if (allmem) {
00364     FORALLfacets {
00365       FOREACHridge_(facet->ridges)
00366         ridge->seen= False;
00367     }
00368     FORALLfacets {
00369       if (facet->visible) {
00370         FOREACHridge_(facet->ridges) {
00371           if (!otherfacet_(ridge, facet)->visible)
00372             ridge->seen= True;  /* an unattached ridge */
00373         }
00374       }
00375     }
00376     while ((facet= qh facet_list)) {
00377       FOREACHridge_(facet->ridges) {
00378         if (ridge->seen) {
00379           qh_setfree(&(ridge->vertices));
00380           qh_memfree(ridge, (int)sizeof(ridgeT));
00381         }else
00382           ridge->seen= True;
00383       }
00384       qh_setfree(&(facet->outsideset));
00385       qh_setfree(&(facet->coplanarset));
00386       qh_setfree(&(facet->neighbors));
00387       qh_setfree(&(facet->ridges));
00388       qh_setfree(&(facet->vertices));
00389       if (facet->next)
00390         qh_delfacet(facet);
00391       else {
00392         qh_memfree(facet, (int)sizeof(facetT));
00393         qh visible_list= qh newfacet_list= qh facet_list= NULL;
00394       }
00395     }
00396   }else {
00397     FORALLfacets {
00398       qh_setfreelong(&(facet->outsideset));
00399       qh_setfreelong(&(facet->coplanarset));
00400       if (!facet->simplicial) {
00401         qh_setfreelong(&(facet->neighbors));
00402         qh_setfreelong(&(facet->ridges));
00403         qh_setfreelong(&(facet->vertices));
00404       }
00405     }
00406   }
00407   qh_setfree(&(qh hash_table));
00408   qh_memfree(qh interior_point, qh normal_size);
00409   qh interior_point= NULL;
00410   FOREACHmerge_(qh facet_mergeset)  /* usually empty */
00411     qh_memfree(merge, (int)sizeof(mergeT));
00412   qh facet_mergeset= NULL;  /* temp set */
00413   qh degen_mergeset= NULL;  /* temp set */
00414   qh_settempfree_all();
00415 } /* freebuild */
00416 
00417 /*-<a                             href="qh-globa.htm#TOC"
00418   >-------------------------------</a><a name="freeqhull">-</a>
00419 
00420   qh_freeqhull( allmem )
00421     see qh_freeqhull2
00422     if qh_QHpointer, frees qh_qh
00423 */
00424 void qh_freeqhull(boolT allmem) {
00425     qh_freeqhull2(allmem);
00426 #if qh_QHpointer
00427     qh_free(qh_qh);
00428     qh_qh= NULL;
00429 #endif
00430 }
00431 
00432 /*-<a                             href="qh-globa.htm#TOC"
00433 >-------------------------------</a><a name="freeqhull2">-</a>
00434 
00435 qh_freeqhull2( allmem )
00436   free global memory
00437   if !allmem,
00438     does not free short memory (freed by qh_memfreeshort)
00439 
00440 notes:
00441   sets qh.NOerrexit in case caller forgets to
00442 
00443 see:
00444   see qh_initqhull_start2()
00445 
00446 design:
00447   free global and temporary memory from qh_initbuild and qh_buildhull
00448   free buffers
00449   free statistics
00450 */
00451 void qh_freeqhull2(boolT allmem) {
00452 
00453   trace1((qh ferr, 1006, "qh_freeqhull2: free global memory\n"));
00454   qh NOerrexit= True;  /* no more setjmp since called at exit and ~QhullQh */
00455   qh_freebuild(allmem);
00456   qh_freebuffers();
00457   qh_freestatistics();
00458 #if qh_QHpointer
00459   memset((char *)qh_qh, 0, sizeof(qhT));
00460   /* qh_qh freed by caller, qh_freeqhull() */
00461 #else
00462   memset((char *)&qh_qh, 0, sizeof(qhT));
00463 #endif
00464   qh NOerrexit= True;
00465 } /* freeqhull2 */
00466 
00467 /*-<a                             href="qh-globa.htm#TOC"
00468   >-------------------------------</a><a name="init_A">-</a>
00469 
00470   qh_init_A( infile, outfile, errfile, argc, argv )
00471     initialize memory and stdio files
00472     convert input options to option string (qh.qhull_command)
00473 
00474   notes:
00475     infile may be NULL if qh_readpoints() is not called
00476 
00477     errfile should always be defined.  It is used for reporting
00478     errors.  outfile is used for output and format options.
00479 
00480     argc/argv may be 0/NULL
00481 
00482     called before error handling initialized
00483     qh_errexit() may not be used
00484 */
00485 void qh_init_A(FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]) {
00486   qh_meminit(errfile);
00487   qh_initqhull_start(infile, outfile, errfile);
00488   qh_init_qhull_command(argc, argv);
00489 } /* init_A */
00490 
00491 /*-<a                             href="qh-globa.htm#TOC"
00492   >-------------------------------</a><a name="init_B">-</a>
00493 
00494   qh_init_B( points, numpoints, dim, ismalloc )
00495     initialize globals for points array
00496 
00497     points has numpoints dim-dimensional points
00498       points[0] is the first coordinate of the first point
00499       points[1] is the second coordinate of the first point
00500       points[dim] is the first coordinate of the second point
00501 
00502     ismalloc=True
00503       Qhull will call qh_free(points) on exit or input transformation
00504     ismalloc=False
00505       Qhull will allocate a new point array if needed for input transformation
00506 
00507     qh.qhull_command
00508       is the option string.
00509       It is defined by qh_init_B(), qh_qhull_command(), or qh_initflags
00510 
00511   returns:
00512     if qh.PROJECTinput or (qh.DELAUNAY and qh.PROJECTdelaunay)
00513       projects the input to a new point array
00514 
00515         if qh.DELAUNAY,
00516           qh.hull_dim is increased by one
00517         if qh.ATinfinity,
00518           qh_projectinput adds point-at-infinity for Delaunay tri.
00519 
00520     if qh.SCALEinput
00521       changes the upper and lower bounds of the input, see qh_scaleinput()
00522 
00523     if qh.ROTATEinput
00524       rotates the input by a random rotation, see qh_rotateinput()
00525       if qh.DELAUNAY
00526         rotates about the last coordinate
00527 
00528   notes:
00529     called after points are defined
00530     qh_errexit() may be used
00531 */
00532 void qh_init_B(coordT *points, int numpoints, int dim, boolT ismalloc) {
00533   qh_initqhull_globals(points, numpoints, dim, ismalloc);
00534   if (qhmem.LASTsize == 0)
00535     qh_initqhull_mem();
00536   /* mem.c and qset.c are initialized */
00537   qh_initqhull_buffers();
00538   qh_initthresholds(qh qhull_command);
00539   if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay))
00540     qh_projectinput();
00541   if (qh SCALEinput)
00542     qh_scaleinput();
00543   if (qh ROTATErandom >= 0) {
00544     qh_randommatrix(qh gm_matrix, qh hull_dim, qh gm_row);
00545     if (qh DELAUNAY) {
00546       int k, lastk= qh hull_dim-1;
00547       for (k=0; k < lastk; k++) {
00548         qh gm_row[k][lastk]= 0.0;
00549         qh gm_row[lastk][k]= 0.0;
00550       }
00551       qh gm_row[lastk][lastk]= 1.0;
00552     }
00553     qh_gram_schmidt(qh hull_dim, qh gm_row);
00554     qh_rotateinput(qh gm_row);
00555   }
00556 } /* init_B */
00557 
00558 /*-<a                             href="qh-globa.htm#TOC"
00559   >-------------------------------</a><a name="init_qhull_command">-</a>
00560 
00561   qh_init_qhull_command( argc, argv )
00562     build qh.qhull_command from argc/argv
00563 
00564   returns:
00565     a space-delimited string of options (just as typed)
00566 
00567   notes:
00568     makes option string easy to input and output
00569 
00570     argc/argv may be 0/NULL
00571 */
00572 void qh_init_qhull_command(int argc, char *argv[]) {
00573 
00574   if (!qh_argv_to_command(argc, argv, qh qhull_command, (int)sizeof(qh qhull_command))){
00575     /* Assumes qh.ferr is defined. */
00576     qh_fprintf(qh ferr, 6033, "qhull input error: more than %d characters in command line\n",
00577           (int)sizeof(qh qhull_command));
00578     qh_exit(qh_ERRinput);  /* error reported, can not use qh_errexit */
00579   }
00580 } /* init_qhull_command */
00581 
00582 /*-<a                             href="qh-globa.htm#TOC"
00583   >-------------------------------</a><a name="initflags">-</a>
00584 
00585   qh_initflags( commandStr )
00586     set flags and initialized constants from commandStr
00587 
00588   returns:
00589     sets qh.qhull_command to command if needed
00590 
00591   notes:
00592     ignores first word (e.g., "qhull d")
00593     use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
00594 
00595   see:
00596     qh_initthresholds() continues processing of 'Pdn' and 'PDn'
00597     'prompt' in unix.c for documentation
00598 
00599   design:
00600     for each space-deliminated option group
00601       if top-level option
00602         check syntax
00603         append approriate option to option string
00604         set appropriate global variable or append printFormat to print options
00605       else
00606         for each sub-option
00607           check syntax
00608           append approriate option to option string
00609           set appropriate global variable or append printFormat to print options
00610 */
00611 void qh_initflags(char *command) {
00612   int k, i, lastproject;
00613   char *s= command, *t, *prev_s, *start, key;
00614   boolT isgeom= False, wasproject;
00615   realT r;
00616 
00617   if (command <= &qh qhull_command[0] || command > &qh qhull_command[0] + sizeof(qh qhull_command)) {
00618     if (command != &qh qhull_command[0]) {
00619       *qh qhull_command= '\0';
00620       strncat(qh qhull_command, command, sizeof(qh qhull_command)-strlen(qh qhull_command)-1);
00621     }
00622     while (*s && !isspace(*s))  /* skip program name */
00623       s++;
00624   }
00625   while (*s) {
00626     while (*s && isspace(*s))
00627       s++;
00628     if (*s == '-')
00629       s++;
00630     if (!*s)
00631       break;
00632     prev_s= s;
00633     switch (*s++) {
00634     case 'd':
00635       qh_option("delaunay", NULL, NULL);
00636       qh DELAUNAY= True;
00637       break;
00638     case 'f':
00639       qh_option("facets", NULL, NULL);
00640       qh_appendprint(qh_PRINTfacets);
00641       break;
00642     case 'i':
00643       qh_option("incidence", NULL, NULL);
00644       qh_appendprint(qh_PRINTincidences);
00645       break;
00646     case 'm':
00647       qh_option("mathematica", NULL, NULL);
00648       qh_appendprint(qh_PRINTmathematica);
00649       break;
00650     case 'n':
00651       qh_option("normals", NULL, NULL);
00652       qh_appendprint(qh_PRINTnormals);
00653       break;
00654     case 'o':
00655       qh_option("offFile", NULL, NULL);
00656       qh_appendprint(qh_PRINToff);
00657       break;
00658     case 'p':
00659       qh_option("points", NULL, NULL);
00660       qh_appendprint(qh_PRINTpoints);
00661       break;
00662     case 's':
00663       qh_option("summary", NULL, NULL);
00664       qh PRINTsummary= True;
00665       break;
00666     case 'v':
00667       qh_option("voronoi", NULL, NULL);
00668       qh VORONOI= True;
00669       qh DELAUNAY= True;
00670       break;
00671     case 'A':
00672       if (!isdigit(*s) && *s != '.' && *s != '-')
00673         qh_fprintf(qh ferr, 7002, "qhull warning: no maximum cosine angle given for option 'An'.  Ignored.\n");
00674       else {
00675         if (*s == '-') {
00676           qh premerge_cos= -qh_strtod(s, &s);
00677           qh_option("Angle-premerge-", NULL, &qh premerge_cos);
00678           qh PREmerge= True;
00679         }else {
00680           qh postmerge_cos= qh_strtod(s, &s);
00681           qh_option("Angle-postmerge", NULL, &qh postmerge_cos);
00682           qh POSTmerge= True;
00683         }
00684         qh MERGING= True;
00685       }
00686       break;
00687     case 'C':
00688       if (!isdigit(*s) && *s != '.' && *s != '-')
00689         qh_fprintf(qh ferr, 7003, "qhull warning: no centrum radius given for option 'Cn'.  Ignored.\n");
00690       else {
00691         if (*s == '-') {
00692           qh premerge_centrum= -qh_strtod(s, &s);
00693           qh_option("Centrum-premerge-", NULL, &qh premerge_centrum);
00694           qh PREmerge= True;
00695         }else {
00696           qh postmerge_centrum= qh_strtod(s, &s);
00697           qh_option("Centrum-postmerge", NULL, &qh postmerge_centrum);
00698           qh POSTmerge= True;
00699         }
00700         qh MERGING= True;
00701       }
00702       break;
00703     case 'E':
00704       if (*s == '-')
00705         qh_fprintf(qh ferr, 7004, "qhull warning: negative maximum roundoff given for option 'An'.  Ignored.\n");
00706       else if (!isdigit(*s))
00707         qh_fprintf(qh ferr, 7005, "qhull warning: no maximum roundoff given for option 'En'.  Ignored.\n");
00708       else {
00709         qh DISTround= qh_strtod(s, &s);
00710         qh_option("Distance-roundoff", NULL, &qh DISTround);
00711         qh SETroundoff= True;
00712       }
00713       break;
00714     case 'H':
00715       start= s;
00716       qh HALFspace= True;
00717       qh_strtod(s, &t);
00718       while (t > s)  {
00719         if (*t && !isspace(*t)) {
00720           if (*t == ',')
00721             t++;
00722           else
00723             qh_fprintf(qh ferr, 7006, "qhull warning: origin for Halfspace intersection should be 'Hn,n,n,...'\n");
00724         }
00725         s= t;
00726         qh_strtod(s, &t);
00727       }
00728       if (start < t) {
00729         if (!(qh feasible_string= (char*)calloc((size_t)(t-start+1), (size_t)1))) {
00730           qh_fprintf(qh ferr, 6034, "qhull error: insufficient memory for 'Hn,n,n'\n");
00731           qh_errexit(qh_ERRmem, NULL, NULL);
00732         }
00733         strncpy(qh feasible_string, start, (size_t)(t-start));
00734         qh_option("Halfspace-about", NULL, NULL);
00735         qh_option(qh feasible_string, NULL, NULL);
00736       }else
00737         qh_option("Halfspace", NULL, NULL);
00738       break;
00739     case 'R':
00740       if (!isdigit(*s))
00741         qh_fprintf(qh ferr, 7007, "qhull warning: missing random perturbation for option 'Rn'.  Ignored\n");
00742       else {
00743         qh RANDOMfactor= qh_strtod(s, &s);
00744         qh_option("Random_perturb", NULL, &qh RANDOMfactor);
00745         qh RANDOMdist= True;
00746       }
00747       break;
00748     case 'V':
00749       if (!isdigit(*s) && *s != '-')
00750         qh_fprintf(qh ferr, 7008, "qhull warning: missing visible distance for option 'Vn'.  Ignored\n");
00751       else {
00752         qh MINvisible= qh_strtod(s, &s);
00753         qh_option("Visible", NULL, &qh MINvisible);
00754       }
00755       break;
00756     case 'U':
00757       if (!isdigit(*s) && *s != '-')
00758         qh_fprintf(qh ferr, 7009, "qhull warning: missing coplanar distance for option 'Un'.  Ignored\n");
00759       else {
00760         qh MAXcoplanar= qh_strtod(s, &s);
00761         qh_option("U-coplanar", NULL, &qh MAXcoplanar);
00762       }
00763       break;
00764     case 'W':
00765       if (*s == '-')
00766         qh_fprintf(qh ferr, 7010, "qhull warning: negative outside width for option 'Wn'.  Ignored.\n");
00767       else if (!isdigit(*s))
00768         qh_fprintf(qh ferr, 7011, "qhull warning: missing outside width for option 'Wn'.  Ignored\n");
00769       else {
00770         qh MINoutside= qh_strtod(s, &s);
00771         qh_option("W-outside", NULL, &qh MINoutside);
00772         qh APPROXhull= True;
00773       }
00774       break;
00775     /************  sub menus ***************/
00776     case 'F':
00777       while (*s && !isspace(*s)) {
00778         switch (*s++) {
00779         case 'a':
00780           qh_option("Farea", NULL, NULL);
00781           qh_appendprint(qh_PRINTarea);
00782           qh GETarea= True;
00783           break;
00784         case 'A':
00785           qh_option("FArea-total", NULL, NULL);
00786           qh GETarea= True;
00787           break;
00788         case 'c':
00789           qh_option("Fcoplanars", NULL, NULL);
00790           qh_appendprint(qh_PRINTcoplanars);
00791           break;
00792         case 'C':
00793           qh_option("FCentrums", NULL, NULL);
00794           qh_appendprint(qh_PRINTcentrums);
00795           break;
00796         case 'd':
00797           qh_option("Fd-cdd-in", NULL, NULL);
00798           qh CDDinput= True;
00799           break;
00800         case 'D':
00801           qh_option("FD-cdd-out", NULL, NULL);
00802           qh CDDoutput= True;
00803           break;
00804         case 'F':
00805           qh_option("FFacets-xridge", NULL, NULL);
00806           qh_appendprint(qh_PRINTfacets_xridge);
00807           break;
00808         case 'i':
00809           qh_option("Finner", NULL, NULL);
00810           qh_appendprint(qh_PRINTinner);
00811           break;
00812         case 'I':
00813           qh_option("FIDs", NULL, NULL);
00814           qh_appendprint(qh_PRINTids);
00815           break;
00816         case 'm':
00817           qh_option("Fmerges", NULL, NULL);
00818           qh_appendprint(qh_PRINTmerges);
00819           break;
00820         case 'M':
00821           qh_option("FMaple", NULL, NULL);
00822           qh_appendprint(qh_PRINTmaple);
00823           break;
00824         case 'n':
00825           qh_option("Fneighbors", NULL, NULL);
00826           qh_appendprint(qh_PRINTneighbors);
00827           break;
00828         case 'N':
00829           qh_option("FNeighbors-vertex", NULL, NULL);
00830           qh_appendprint(qh_PRINTvneighbors);
00831           break;
00832         case 'o':
00833           qh_option("Fouter", NULL, NULL);
00834           qh_appendprint(qh_PRINTouter);
00835           break;
00836         case 'O':
00837           if (qh PRINToptions1st) {
00838             qh_option("FOptions", NULL, NULL);
00839             qh_appendprint(qh_PRINToptions);
00840           }else
00841             qh PRINToptions1st= True;
00842           break;
00843         case 'p':
00844           qh_option("Fpoint-intersect", NULL, NULL);
00845           qh_appendprint(qh_PRINTpointintersect);
00846           break;
00847         case 'P':
00848           qh_option("FPoint-nearest", NULL, NULL);
00849           qh_appendprint(qh_PRINTpointnearest);
00850           break;
00851         case 'Q':
00852           qh_option("FQhull", NULL, NULL);
00853           qh_appendprint(qh_PRINTqhull);
00854           break;
00855         case 's':
00856           qh_option("Fsummary", NULL, NULL);
00857           qh_appendprint(qh_PRINTsummary);
00858           break;
00859         case 'S':
00860           qh_option("FSize", NULL, NULL);
00861           qh_appendprint(qh_PRINTsize);
00862           qh GETarea= True;
00863           break;
00864         case 't':
00865           qh_option("Ftriangles", NULL, NULL);
00866           qh_appendprint(qh_PRINTtriangles);
00867           break;
00868         case 'v':
00869           /* option set in qh_initqhull_globals */
00870           qh_appendprint(qh_PRINTvertices);
00871           break;
00872         case 'V':
00873           qh_option("FVertex-average", NULL, NULL);
00874           qh_appendprint(qh_PRINTaverage);
00875           break;
00876         case 'x':
00877           qh_option("Fxtremes", NULL, NULL);
00878           qh_appendprint(qh_PRINTextremes);
00879           break;
00880         default:
00881           s--;
00882           qh_fprintf(qh ferr, 7012, "qhull warning: unknown 'F' output option %c, rest ignored\n", (int)s[0]);
00883           while (*++s && !isspace(*s));
00884           break;
00885         }
00886       }
00887       break;
00888     case 'G':
00889       isgeom= True;
00890       qh_appendprint(qh_PRINTgeom);
00891       while (*s && !isspace(*s)) {
00892         switch (*s++) {
00893         case 'a':
00894           qh_option("Gall-points", NULL, NULL);
00895           qh PRINTdots= True;
00896           break;
00897         case 'c':
00898           qh_option("Gcentrums", NULL, NULL);
00899           qh PRINTcentrums= True;
00900           break;
00901         case 'h':
00902           qh_option("Gintersections", NULL, NULL);
00903           qh DOintersections= True;
00904           break;
00905         case 'i':
00906           qh_option("Ginner", NULL, NULL);
00907           qh PRINTinner= True;
00908           break;
00909         case 'n':
00910           qh_option("Gno-planes", NULL, NULL);
00911           qh PRINTnoplanes= True;
00912           break;
00913         case 'o':
00914           qh_option("Gouter", NULL, NULL);
00915           qh PRINTouter= True;
00916           break;
00917         case 'p':
00918           qh_option("Gpoints", NULL, NULL);
00919           qh PRINTcoplanar= True;
00920           break;
00921         case 'r':
00922           qh_option("Gridges", NULL, NULL);
00923           qh PRINTridges= True;
00924           break;
00925         case 't':
00926           qh_option("Gtransparent", NULL, NULL);
00927           qh PRINTtransparent= True;
00928           break;
00929         case 'v':
00930           qh_option("Gvertices", NULL, NULL);
00931           qh PRINTspheres= True;
00932           break;
00933         case 'D':
00934           if (!isdigit(*s))
00935             qh_fprintf(qh ferr, 6035, "qhull input error: missing dimension for option 'GDn'\n");
00936           else {
00937             if (qh DROPdim >= 0)
00938               qh_fprintf(qh ferr, 7013, "qhull warning: can only drop one dimension.  Previous 'GD%d' ignored\n",
00939                    qh DROPdim);
00940             qh DROPdim= qh_strtol(s, &s);
00941             qh_option("GDrop-dim", &qh DROPdim, NULL);
00942           }
00943           break;
00944         default:
00945           s--;
00946           qh_fprintf(qh ferr, 7014, "qhull warning: unknown 'G' print option %c, rest ignored\n", (int)s[0]);
00947           while (*++s && !isspace(*s));
00948           break;
00949         }
00950       }
00951       break;
00952     case 'P':
00953       while (*s && !isspace(*s)) {
00954         switch (*s++) {
00955         case 'd': case 'D':  /* see qh_initthresholds() */
00956           key= s[-1];
00957           i= qh_strtol(s, &s);
00958           r= 0;
00959           if (*s == ':') {
00960             s++;
00961             r= qh_strtod(s, &s);
00962           }
00963           if (key == 'd')
00964             qh_option("Pdrop-facets-dim-less", &i, &r);
00965           else
00966             qh_option("PDrop-facets-dim-more", &i, &r);
00967           break;
00968         case 'g':
00969           qh_option("Pgood-facets", NULL, NULL);
00970           qh PRINTgood= True;
00971           break;
00972         case 'G':
00973           qh_option("PGood-facet-neighbors", NULL, NULL);
00974           qh PRINTneighbors= True;
00975           break;
00976         case 'o':
00977           qh_option("Poutput-forced", NULL, NULL);
00978           qh FORCEoutput= True;
00979           break;
00980         case 'p':
00981           qh_option("Pprecision-ignore", NULL, NULL);
00982           qh PRINTprecision= False;
00983           break;
00984         case 'A':
00985           if (!isdigit(*s))
00986             qh_fprintf(qh ferr, 6036, "qhull input error: missing facet count for keep area option 'PAn'\n");
00987           else {
00988             qh KEEParea= qh_strtol(s, &s);
00989             qh_option("PArea-keep", &qh KEEParea, NULL);
00990             qh GETarea= True;
00991           }
00992           break;
00993         case 'F':
00994           if (!isdigit(*s))
00995             qh_fprintf(qh ferr, 6037, "qhull input error: missing facet area for option 'PFn'\n");
00996           else {
00997             qh KEEPminArea= qh_strtod(s, &s);
00998             qh_option("PFacet-area-keep", NULL, &qh KEEPminArea);
00999             qh GETarea= True;
01000           }
01001           break;
01002         case 'M':
01003           if (!isdigit(*s))
01004             qh_fprintf(qh ferr, 6038, "qhull input error: missing merge count for option 'PMn'\n");
01005           else {
01006             qh KEEPmerge= qh_strtol(s, &s);
01007             qh_option("PMerge-keep", &qh KEEPmerge, NULL);
01008           }
01009           break;
01010         default:
01011           s--;
01012           qh_fprintf(qh ferr, 7015, "qhull warning: unknown 'P' print option %c, rest ignored\n", (int)s[0]);
01013           while (*++s && !isspace(*s));
01014           break;
01015         }
01016       }
01017       break;
01018     case 'Q':
01019       lastproject= -1;
01020       while (*s && !isspace(*s)) {
01021         switch (*s++) {
01022         case 'b': case 'B':  /* handled by qh_initthresholds */
01023           key= s[-1];
01024           if (key == 'b' && *s == 'B') {
01025             s++;
01026             r= qh_DEFAULTbox;
01027             qh SCALEinput= True;
01028             qh_option("QbBound-unit-box", NULL, &r);
01029             break;
01030           }
01031           if (key == 'b' && *s == 'b') {
01032             s++;
01033             qh SCALElast= True;
01034             qh_option("Qbbound-last", NULL, NULL);
01035             break;
01036           }
01037           k= qh_strtol(s, &s);
01038           r= 0.0;
01039           wasproject= False;
01040           if (*s == ':') {
01041             s++;
01042             if ((r= qh_strtod(s, &s)) == 0.0) {
01043               t= s;            /* need true dimension for memory allocation */
01044               while (*t && !isspace(*t)) {
01045                 if (toupper(*t++) == 'B'
01046                  && k == qh_strtol(t, &t)
01047                  && *t++ == ':'
01048                  && qh_strtod(t, &t) == 0.0) {
01049                   qh PROJECTinput++;
01050                   trace2((qh ferr, 2004, "qh_initflags: project dimension %d\n", k));
01051                   qh_option("Qb-project-dim", &k, NULL);
01052                   wasproject= True;
01053                   lastproject= k;
01054                   break;
01055                 }
01056               }
01057             }
01058           }
01059           if (!wasproject) {
01060             if (lastproject == k && r == 0.0)
01061               lastproject= -1;  /* doesn't catch all possible sequences */
01062             else if (key == 'b') {
01063               qh SCALEinput= True;
01064               if (r == 0.0)
01065                 r= -qh_DEFAULTbox;
01066               qh_option("Qbound-dim-low", &k, &r);
01067             }else {
01068               qh SCALEinput= True;
01069               if (r == 0.0)
01070                 r= qh_DEFAULTbox;
01071               qh_option("QBound-dim-high", &k, &r);
01072             }
01073           }
01074           break;
01075         case 'c':
01076           qh_option("Qcoplanar-keep", NULL, NULL);
01077           qh KEEPcoplanar= True;
01078           break;
01079         case 'f':
01080           qh_option("Qfurthest-outside", NULL, NULL);
01081           qh BESToutside= True;
01082           break;
01083         case 'g':
01084           qh_option("Qgood-facets-only", NULL, NULL);
01085           qh ONLYgood= True;
01086           break;
01087         case 'i':
01088           qh_option("Qinterior-keep", NULL, NULL);
01089           qh KEEPinside= True;
01090           break;
01091         case 'm':
01092           qh_option("Qmax-outside-only", NULL, NULL);
01093           qh ONLYmax= True;
01094           break;
01095         case 'r':
01096           qh_option("Qrandom-outside", NULL, NULL);
01097           qh RANDOMoutside= True;
01098           break;
01099         case 's':
01100           qh_option("Qsearch-initial-simplex", NULL, NULL);
01101           qh ALLpoints= True;
01102           break;
01103         case 't':
01104           qh_option("Qtriangulate", NULL, NULL);
01105           qh TRIangulate= True;
01106           break;
01107         case 'T':
01108           qh_option("QTestPoints", NULL, NULL);
01109           if (!isdigit(*s))
01110             qh_fprintf(qh ferr, 6039, "qhull input error: missing number of test points for option 'QTn'\n");
01111           else {
01112             qh TESTpoints= qh_strtol(s, &s);
01113             qh_option("QTestPoints", &qh TESTpoints, NULL);
01114           }
01115           break;
01116         case 'u':
01117           qh_option("QupperDelaunay", NULL, NULL);
01118           qh UPPERdelaunay= True;
01119           break;
01120         case 'v':
01121           qh_option("Qvertex-neighbors-convex", NULL, NULL);
01122           qh TESTvneighbors= True;
01123           break;
01124         case 'x':
01125           qh_option("Qxact-merge", NULL, NULL);
01126           qh MERGEexact= True;
01127           break;
01128         case 'z':
01129           qh_option("Qz-infinity-point", NULL, NULL);
01130           qh ATinfinity= True;
01131           break;
01132         case '0':
01133           qh_option("Q0-no-premerge", NULL, NULL);
01134           qh NOpremerge= True;
01135           break;
01136         case '1':
01137           if (!isdigit(*s)) {
01138             qh_option("Q1-no-angle-sort", NULL, NULL);
01139             qh ANGLEmerge= False;
01140             break;
01141           }
01142           switch (*s++) {
01143           case '0':
01144             qh_option("Q10-no-narrow", NULL, NULL);
01145             qh NOnarrow= True;
01146             break;
01147           case '1':
01148             qh_option("Q11-trinormals Qtriangulate", NULL, NULL);
01149             qh TRInormals= True;
01150             qh TRIangulate= True;
01151             break;
01152           default:
01153             s--;
01154             qh_fprintf(qh ferr, 7016, "qhull warning: unknown 'Q' qhull option 1%c, rest ignored\n", (int)s[0]);
01155             while (*++s && !isspace(*s));
01156             break;
01157           }
01158           break;
01159         case '2':
01160           qh_option("Q2-no-merge-independent", NULL, NULL);
01161           qh MERGEindependent= False;
01162           goto LABELcheckdigit;
01163           break; /* no warnings */
01164         case '3':
01165           qh_option("Q3-no-merge-vertices", NULL, NULL);
01166           qh MERGEvertices= False;
01167         LABELcheckdigit:
01168           if (isdigit(*s))
01169             qh_fprintf(qh ferr, 7017, "qhull warning: can not follow '1', '2', or '3' with a digit.  '%c' skipped.\n",
01170                      *s++);
01171           break;
01172         case '4':
01173           qh_option("Q4-avoid-old-into-new", NULL, NULL);
01174           qh AVOIDold= True;
01175           break;
01176         case '5':
01177           qh_option("Q5-no-check-outer", NULL, NULL);
01178           qh SKIPcheckmax= True;
01179           break;
01180         case '6':
01181           qh_option("Q6-no-concave-merge", NULL, NULL);
01182           qh SKIPconvex= True;
01183           break;
01184         case '7':
01185           qh_option("Q7-no-breadth-first", NULL, NULL);
01186           qh VIRTUALmemory= True;
01187           break;
01188         case '8':
01189           qh_option("Q8-no-near-inside", NULL, NULL);
01190           qh NOnearinside= True;
01191           break;
01192         case '9':
01193           qh_option("Q9-pick-furthest", NULL, NULL);
01194           qh PICKfurthest= True;
01195           break;
01196         case 'G':
01197           i= qh_strtol(s, &t);
01198           if (qh GOODpoint)
01199             qh_fprintf(qh ferr, 7018, "qhull warning: good point already defined for option 'QGn'.  Ignored\n");
01200           else if (s == t)
01201             qh_fprintf(qh ferr, 7019, "qhull warning: missing good point id for option 'QGn'.  Ignored\n");
01202           else if (i < 0 || *s == '-') {
01203             qh GOODpoint= i-1;
01204             qh_option("QGood-if-dont-see-point", &i, NULL);
01205           }else {
01206             qh GOODpoint= i+1;
01207             qh_option("QGood-if-see-point", &i, NULL);
01208           }
01209           s= t;
01210           break;
01211         case 'J':
01212           if (!isdigit(*s) && *s != '-')
01213             qh JOGGLEmax= 0.0;
01214           else {
01215             qh JOGGLEmax= (realT) qh_strtod(s, &s);
01216             qh_option("QJoggle", NULL, &qh JOGGLEmax);
01217           }
01218           break;
01219         case 'R':
01220           if (!isdigit(*s) && *s != '-')
01221             qh_fprintf(qh ferr, 7020, "qhull warning: missing random seed for option 'QRn'.  Ignored\n");
01222           else {
01223             qh ROTATErandom= i= qh_strtol(s, &s);
01224             if (i > 0)
01225               qh_option("QRotate-id", &i, NULL );
01226             else if (i < -1)
01227               qh_option("QRandom-seed", &i, NULL );
01228           }
01229           break;
01230         case 'V':
01231           i= qh_strtol(s, &t);
01232           if (qh GOODvertex)
01233             qh_fprintf(qh ferr, 7021, "qhull warning: good vertex already defined for option 'QVn'.  Ignored\n");
01234           else if (s == t)
01235             qh_fprintf(qh ferr, 7022, "qhull warning: no good point id given for option 'QVn'.  Ignored\n");
01236           else if (i < 0) {
01237             qh GOODvertex= i - 1;
01238             qh_option("QV-good-facets-not-point", &i, NULL);
01239           }else {
01240             qh_option("QV-good-facets-point", &i, NULL);
01241             qh GOODvertex= i + 1;
01242           }
01243           s= t;
01244           break;
01245         default:
01246           s--;
01247           qh_fprintf(qh ferr, 7023, "qhull warning: unknown 'Q' qhull option %c, rest ignored\n", (int)s[0]);
01248           while (*++s && !isspace(*s));
01249           break;
01250         }
01251       }
01252       break;
01253     case 'T':
01254       while (*s && !isspace(*s)) {
01255         if (isdigit(*s) || *s == '-')
01256           qh IStracing= qh_strtol(s, &s);
01257         else switch (*s++) {
01258         case 'a':
01259           qh_option("Tannotate-output", NULL, NULL);
01260           qh ANNOTATEoutput= True;
01261           break;
01262         case 'c':
01263           qh_option("Tcheck-frequently", NULL, NULL);
01264           qh CHECKfrequently= True;
01265           break;
01266         case 's':
01267           qh_option("Tstatistics", NULL, NULL);
01268           qh PRINTstatistics= True;
01269           break;
01270         case 'v':
01271           qh_option("Tverify", NULL, NULL);
01272           qh VERIFYoutput= True;
01273           break;
01274         case 'z':
01275           if (qh ferr == qh_FILEstderr) {
01276             /* The C++ interface captures the output in qh_fprint_qhull() */
01277             qh_option("Tz-stdout", NULL, NULL);
01278             qh USEstdout= True;
01279           }else if (!qh fout)
01280             qh_fprintf(qh ferr, 7024, "qhull warning: output file undefined(stdout).  Option 'Tz' ignored.\n");
01281           else {
01282             qh_option("Tz-stdout", NULL, NULL);
01283             qh USEstdout= True;
01284             qh ferr= qh fout;
01285             qhmem.ferr= qh fout;
01286           }
01287           break;
01288         case 'C':
01289           if (!isdigit(*s))
01290             qh_fprintf(qh ferr, 7025, "qhull warning: missing point id for cone for trace option 'TCn'.  Ignored\n");
01291           else {
01292             i= qh_strtol(s, &s);
01293             qh_option("TCone-stop", &i, NULL);
01294             qh STOPcone= i + 1;
01295           }
01296           break;
01297         case 'F':
01298           if (!isdigit(*s))
01299             qh_fprintf(qh ferr, 7026, "qhull warning: missing frequency count for trace option 'TFn'.  Ignored\n");
01300           else {
01301             qh REPORTfreq= qh_strtol(s, &s);
01302             qh_option("TFacet-log", &qh REPORTfreq, NULL);
01303             qh REPORTfreq2= qh REPORTfreq/2;  /* for tracemerging() */
01304           }
01305           break;
01306         case 'I':
01307           if (!isspace(*s))
01308             qh_fprintf(qh ferr, 7027, "qhull warning: missing space between 'TI' and filename, %s\n", s);
01309           while (isspace(*s))
01310             s++;
01311           t= qh_skipfilename(s);
01312           {
01313             char filename[qh_FILENAMElen];
01314 
01315             qh_copyfilename(filename, (int)sizeof(filename), s, (int)(t-s));   /* WARN64 */
01316             s= t;
01317             if (!freopen(filename, "r", stdin)) {
01318               qh_fprintf(qh ferr, 6041, "qhull error: could not open file \"%s\".", filename);
01319               qh_errexit(qh_ERRinput, NULL, NULL);
01320             }else {
01321               qh_option("TInput-file", NULL, NULL);
01322               qh_option(filename, NULL, NULL);
01323             }
01324           }
01325           break;
01326         case 'O':
01327             if (!isspace(*s))
01328                 qh_fprintf(qh ferr, 7028, "qhull warning: missing space between 'TO' and filename, %s\n", s);
01329             while (isspace(*s))
01330                 s++;
01331             t= qh_skipfilename(s);
01332             {
01333               char filename[qh_FILENAMElen];
01334 
01335               qh_copyfilename(filename, (int)sizeof(filename), s, (int)(t-s));  /* WARN64 */
01336               s= t;
01337               if (!freopen(filename, "w", stdout)) {
01338                 qh_fprintf(qh ferr, 6044, "qhull error: could not open file \"%s\".", filename);
01339                 qh_errexit(qh_ERRinput, NULL, NULL);
01340               }else {
01341                 qh_option("TOutput-file", NULL, NULL);
01342               qh_option(filename, NULL, NULL);
01343             }
01344           }
01345           break;
01346         case 'P':
01347           if (!isdigit(*s))
01348             qh_fprintf(qh ferr, 7029, "qhull warning: missing point id for trace option 'TPn'.  Ignored\n");
01349           else {
01350             qh TRACEpoint= qh_strtol(s, &s);
01351             qh_option("Trace-point", &qh TRACEpoint, NULL);
01352           }
01353           break;
01354         case 'M':
01355           if (!isdigit(*s))
01356             qh_fprintf(qh ferr, 7030, "qhull warning: missing merge id for trace option 'TMn'.  Ignored\n");
01357           else {
01358             qh TRACEmerge= qh_strtol(s, &s);
01359             qh_option("Trace-merge", &qh TRACEmerge, NULL);
01360           }
01361           break;
01362         case 'R':
01363           if (!isdigit(*s))
01364             qh_fprintf(qh ferr, 7031, "qhull warning: missing rerun count for trace option 'TRn'.  Ignored\n");
01365           else {
01366             qh RERUN= qh_strtol(s, &s);
01367             qh_option("TRerun", &qh RERUN, NULL);
01368           }
01369           break;
01370         case 'V':
01371           i= qh_strtol(s, &t);
01372           if (s == t)
01373             qh_fprintf(qh ferr, 7032, "qhull warning: missing furthest point id for trace option 'TVn'.  Ignored\n");
01374           else if (i < 0) {
01375             qh STOPpoint= i - 1;
01376             qh_option("TV-stop-before-point", &i, NULL);
01377           }else {
01378             qh STOPpoint= i + 1;
01379             qh_option("TV-stop-after-point", &i, NULL);
01380           }
01381           s= t;
01382           break;
01383         case 'W':
01384           if (!isdigit(*s))
01385             qh_fprintf(qh ferr, 7033, "qhull warning: missing max width for trace option 'TWn'.  Ignored\n");
01386           else {
01387             qh TRACEdist= (realT) qh_strtod(s, &s);
01388             qh_option("TWide-trace", NULL, &qh TRACEdist);
01389           }
01390           break;
01391         default:
01392           s--;
01393           qh_fprintf(qh ferr, 7034, "qhull warning: unknown 'T' trace option %c, rest ignored\n", (int)s[0]);
01394           while (*++s && !isspace(*s));
01395           break;
01396         }
01397       }
01398       break;
01399     default:
01400       qh_fprintf(qh ferr, 7035, "qhull warning: unknown flag %c(%x)\n", (int)s[-1],
01401                (int)s[-1]);
01402       break;
01403     }
01404     if (s-1 == prev_s && *s && !isspace(*s)) {
01405       qh_fprintf(qh ferr, 7036, "qhull warning: missing space after flag %c(%x); reserved for menu. Skipped.\n",
01406                (int)*prev_s, (int)*prev_s);
01407       while (*s && !isspace(*s))
01408         s++;
01409     }
01410   }
01411   if (qh STOPcone && qh JOGGLEmax < REALmax/2)
01412     qh_fprintf(qh ferr, 7078, "qhull warning: 'TCn' (stopCone) ignored when used with 'QJn' (joggle)\n");
01413   if (isgeom && !qh FORCEoutput && qh PRINTout[1])
01414     qh_fprintf(qh ferr, 7037, "qhull warning: additional output formats are not compatible with Geomview\n");
01415   /* set derived values in qh_initqhull_globals */
01416 } /* initflags */
01417 
01418 
01419 /*-<a                             href="qh-globa.htm#TOC"
01420   >-------------------------------</a><a name="initqhull_buffers">-</a>
01421 
01422   qh_initqhull_buffers()
01423     initialize global memory buffers
01424 
01425   notes:
01426     must match qh_freebuffers()
01427 */
01428 void qh_initqhull_buffers(void) {
01429   int k;
01430 
01431   qh TEMPsize= (qhmem.LASTsize - sizeof(setT))/SETelemsize;
01432   if (qh TEMPsize <= 0 || qh TEMPsize > qhmem.LASTsize)
01433     qh TEMPsize= 8;  /* e.g., if qh_NOmem */
01434   qh other_points= qh_setnew(qh TEMPsize);
01435   qh del_vertices= qh_setnew(qh TEMPsize);
01436   qh coplanarfacetset= qh_setnew(qh TEMPsize);
01437   qh NEARzero= (realT *)qh_memalloc(qh hull_dim * sizeof(realT));
01438   qh lower_threshold= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
01439   qh upper_threshold= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
01440   qh lower_bound= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
01441   qh upper_bound= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
01442   for (k=qh input_dim+1; k--; ) {  /* duplicated in qh_initqhull_buffers and qh_clear_ouputflags */
01443     qh lower_threshold[k]= -REALmax;
01444     qh upper_threshold[k]= REALmax;
01445     qh lower_bound[k]= -REALmax;
01446     qh upper_bound[k]= REALmax;
01447   }
01448   qh gm_matrix= (coordT *)qh_memalloc((qh hull_dim+1) * qh hull_dim * sizeof(coordT));
01449   qh gm_row= (coordT **)qh_memalloc((qh hull_dim+1) * sizeof(coordT *));
01450 } /* initqhull_buffers */
01451 
01452 /*-<a                             href="qh-globa.htm#TOC"
01453   >-------------------------------</a><a name="initqhull_globals">-</a>
01454 
01455   qh_initqhull_globals( points, numpoints, dim, ismalloc )
01456     initialize globals
01457     if ismalloc
01458       points were malloc'd and qhull should free at end
01459 
01460   returns:
01461     sets qh.first_point, num_points, input_dim, hull_dim and others
01462     seeds random number generator (seed=1 if tracing)
01463     modifies qh.hull_dim if ((qh.DELAUNAY and qh.PROJECTdelaunay) or qh.PROJECTinput)
01464     adjust user flags as needed
01465     also checks DIM3 dependencies and constants
01466 
01467   notes:
01468     do not use qh_point() since an input transformation may move them elsewhere
01469 
01470   see:
01471     qh_initqhull_start() sets default values for non-zero globals
01472 
01473   design:
01474     initialize points array from input arguments
01475     test for qh.ZEROcentrum
01476       (i.e., use opposite vertex instead of cetrum for convexity testing)
01477     initialize qh.CENTERtype, qh.normal_size,
01478       qh.center_size, qh.TRACEpoint/level,
01479     initialize and test random numbers
01480     qh_initqhull_outputflags() -- adjust and test output flags
01481 */
01482 void qh_initqhull_globals(coordT *points, int numpoints, int dim, boolT ismalloc) {
01483   int seed, pointsneeded, extra= 0, i, randi, k;
01484   realT randr;
01485   realT factorial;
01486 
01487   time_t timedata;
01488 
01489   trace0((qh ferr, 13, "qh_initqhull_globals: for %s | %s\n", qh rbox_command,
01490       qh qhull_command));
01491   qh POINTSmalloc= ismalloc;
01492   qh first_point= points;
01493   qh num_points= numpoints;
01494   qh hull_dim= qh input_dim= dim;
01495   if (!qh NOpremerge && !qh MERGEexact && !qh PREmerge && qh JOGGLEmax > REALmax/2) {
01496     qh MERGING= True;
01497     if (qh hull_dim <= 4) {
01498       qh PREmerge= True;
01499       qh_option("_pre-merge", NULL, NULL);
01500     }else {
01501       qh MERGEexact= True;
01502       qh_option("Qxact_merge", NULL, NULL);
01503     }
01504   }else if (qh MERGEexact)
01505     qh MERGING= True;
01506   if (!qh NOpremerge && qh JOGGLEmax > REALmax/2) {
01507 #ifdef qh_NOmerge
01508     qh JOGGLEmax= 0.0;
01509 #endif
01510   }
01511   if (qh TRIangulate && qh JOGGLEmax < REALmax/2 && qh PRINTprecision)
01512     qh_fprintf(qh ferr, 7038, "qhull warning: joggle('QJ') always produces simplicial output.  Triangulated output('Qt') does nothing.\n");
01513   if (qh JOGGLEmax < REALmax/2 && qh DELAUNAY && !qh SCALEinput && !qh SCALElast) {
01514     qh SCALElast= True;
01515     qh_option("Qbbound-last-qj", NULL, NULL);
01516   }
01517   if (qh MERGING && !qh POSTmerge && qh premerge_cos > REALmax/2
01518   && qh premerge_centrum == 0) {
01519     qh ZEROcentrum= True;
01520     qh ZEROall_ok= True;
01521     qh_option("_zero-centrum", NULL, NULL);
01522   }
01523   if (qh JOGGLEmax < REALmax/2 && REALepsilon > 2e-8 && qh PRINTprecision)
01524     qh_fprintf(qh ferr, 7039, "qhull warning: real epsilon, %2.2g, is probably too large for joggle('QJn')\nRecompile with double precision reals(see user.h).\n",
01525           REALepsilon);
01526 #ifdef qh_NOmerge
01527   if (qh MERGING) {
01528     qh_fprintf(qh ferr, 6045, "qhull input error: merging not installed(qh_NOmerge + 'Qx', 'Cn' or 'An')\n");
01529     qh_errexit(qh_ERRinput, NULL, NULL);
01530   }
01531 #endif
01532   if (qh DELAUNAY && qh KEEPcoplanar && !qh KEEPinside) {
01533     qh KEEPinside= True;
01534     qh_option("Qinterior-keep", NULL, NULL);
01535   }
01536   if (qh DELAUNAY && qh HALFspace) {
01537     qh_fprintf(qh ferr, 6046, "qhull input error: can not use Delaunay('d') or Voronoi('v') with halfspace intersection('H')\n");
01538     qh_errexit(qh_ERRinput, NULL, NULL);
01539   }
01540   if (!qh DELAUNAY && (qh UPPERdelaunay || qh ATinfinity)) {
01541     qh_fprintf(qh ferr, 6047, "qhull input error: use upper-Delaunay('Qu') or infinity-point('Qz') with Delaunay('d') or Voronoi('v')\n");
01542     qh_errexit(qh_ERRinput, NULL, NULL);
01543   }
01544   if (qh UPPERdelaunay && qh ATinfinity) {
01545     qh_fprintf(qh ferr, 6048, "qhull input error: can not use infinity-point('Qz') with upper-Delaunay('Qu')\n");
01546     qh_errexit(qh_ERRinput, NULL, NULL);
01547   }
01548   if (qh SCALElast && !qh DELAUNAY && qh PRINTprecision)
01549     qh_fprintf(qh ferr, 7040, "qhull input warning: option 'Qbb' (scale-last-coordinate) is normally used with 'd' or 'v'\n");
01550   qh DOcheckmax= (!qh SKIPcheckmax && qh MERGING );
01551   qh KEEPnearinside= (qh DOcheckmax && !(qh KEEPinside && qh KEEPcoplanar)
01552                           && !qh NOnearinside);
01553   if (qh MERGING)
01554     qh CENTERtype= qh_AScentrum;
01555   else if (qh VORONOI)
01556     qh CENTERtype= qh_ASvoronoi;
01557   if (qh TESTvneighbors && !qh MERGING) {
01558     qh_fprintf(qh ferr, 6049, "qhull input error: test vertex neighbors('Qv') needs a merge option\n");
01559     qh_errexit(qh_ERRinput, NULL ,NULL);
01560   }
01561   if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay)) {
01562     qh hull_dim -= qh PROJECTinput;
01563     if (qh DELAUNAY) {
01564       qh hull_dim++;
01565       if (qh ATinfinity)
01566         extra= 1;
01567     }
01568   }
01569   if (qh hull_dim <= 1) {
01570     qh_fprintf(qh ferr, 6050, "qhull error: dimension %d must be > 1\n", qh hull_dim);
01571     qh_errexit(qh_ERRinput, NULL, NULL);
01572   }
01573   for (k=2, factorial=1.0; k < qh hull_dim; k++)
01574     factorial *= k;
01575   qh AREAfactor= 1.0 / factorial;
01576   trace2((qh ferr, 2005, "qh_initqhull_globals: initialize globals.  dim %d numpoints %d malloc? %d projected %d to hull_dim %d\n",
01577         dim, numpoints, ismalloc, qh PROJECTinput, qh hull_dim));
01578   qh normal_size= qh hull_dim * sizeof(coordT);
01579   qh center_size= qh normal_size - sizeof(coordT);
01580   pointsneeded= qh hull_dim+1;
01581   if (qh hull_dim > qh_DIMmergeVertex) {
01582     qh MERGEvertices= False;
01583     qh_option("Q3-no-merge-vertices-dim-high", NULL, NULL);
01584   }
01585   if (qh GOODpoint)
01586     pointsneeded++;
01587 #ifdef qh_NOtrace
01588   if (qh IStracing) {
01589     qh_fprintf(qh ferr, 6051, "qhull input error: tracing is not installed(qh_NOtrace in user.h)");
01590     qh_errexit(qh_ERRqhull, NULL, NULL);
01591   }
01592 #endif
01593   if (qh RERUN > 1) {
01594     qh TRACElastrun= qh IStracing; /* qh_build_withrestart duplicates next conditional */
01595     if (qh IStracing != -1)
01596       qh IStracing= 0;
01597   }else if (qh TRACEpoint != -1 || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
01598     qh TRACElevel= (qh IStracing? qh IStracing : 3);
01599     qh IStracing= 0;
01600   }
01601   if (qh ROTATErandom == 0 || qh ROTATErandom == -1) {
01602     seed= (int)time(&timedata);
01603     if (qh ROTATErandom  == -1) {
01604       seed= -seed;
01605       qh_option("QRandom-seed", &seed, NULL );
01606     }else
01607       qh_option("QRotate-random", &seed, NULL);
01608     qh ROTATErandom= seed;
01609   }
01610   seed= qh ROTATErandom;
01611   if (seed == INT_MIN)    /* default value */
01612     seed= 1;
01613   else if (seed < 0)
01614     seed= -seed;
01615   qh_RANDOMseed_(seed);
01616   randr= 0.0;
01617   for (i=1000; i--; ) {
01618     randi= qh_RANDOMint;
01619     randr += randi;
01620     if (randi > qh_RANDOMmax) {
01621       qh_fprintf(qh ferr, 8036, "\
01622 qhull configuration error (qh_RANDOMmax in user.h):\n\
01623    random integer %d > qh_RANDOMmax(%.8g)\n",
01624                randi, qh_RANDOMmax);
01625       qh_errexit(qh_ERRinput, NULL, NULL);
01626     }
01627   }
01628   qh_RANDOMseed_(seed);
01629   randr = randr/1000;
01630   if (randr < qh_RANDOMmax * 0.1
01631   || randr > qh_RANDOMmax * 0.9)
01632     qh_fprintf(qh ferr, 8037, "\
01633 qhull configuration warning (qh_RANDOMmax in user.h):\n\
01634    average of 1000 random integers (%.2g) is much different than expected (%.2g).\n\
01635    Is qh_RANDOMmax (%.2g) wrong?\n",
01636              randr, qh_RANDOMmax * 0.5, qh_RANDOMmax);
01637   qh RANDOMa= 2.0 * qh RANDOMfactor/qh_RANDOMmax;
01638   qh RANDOMb= 1.0 - qh RANDOMfactor;
01639   if (qh_HASHfactor < 1.1) {
01640     qh_fprintf(qh ferr, 6052, "qhull internal error (qh_initqhull_globals): qh_HASHfactor %d must be at least 1.1.  Qhull uses linear hash probing\n",
01641       qh_HASHfactor);
01642     qh_errexit(qh_ERRqhull, NULL, NULL);
01643   }
01644   if (numpoints+extra < pointsneeded) {
01645     qh_fprintf(qh ferr, 6214, "qhull input error: not enough points(%d) to construct initial simplex(need %d)\n",
01646             numpoints, pointsneeded);
01647     qh_errexit(qh_ERRinput, NULL, NULL);
01648   }
01649   qh_initqhull_outputflags();
01650 } /* initqhull_globals */
01651 
01652 /*-<a                             href="qh-globa.htm#TOC"
01653   >-------------------------------</a><a name="initqhull_mem">-</a>
01654 
01655   qh_initqhull_mem(  )
01656     initialize mem.c for qhull
01657     qh.hull_dim and qh.normal_size determine some of the allocation sizes
01658     if qh.MERGING,
01659       includes ridgeT
01660     calls qh_user_memsizes() to add up to 10 additional sizes for quick allocation
01661       (see numsizes below)
01662 
01663   returns:
01664     mem.c already for qh_memalloc/qh_memfree (errors if called beforehand)
01665 
01666   notes:
01667     qh_produceoutput() prints memsizes
01668 
01669 */
01670 void qh_initqhull_mem(void) {
01671   int numsizes;
01672   int i;
01673 
01674   numsizes= 8+10;
01675   qh_meminitbuffers(qh IStracing, qh_MEMalign, numsizes,
01676                      qh_MEMbufsize,qh_MEMinitbuf);
01677   qh_memsize((int)sizeof(vertexT));
01678   if (qh MERGING) {
01679     qh_memsize((int)sizeof(ridgeT));
01680     qh_memsize((int)sizeof(mergeT));
01681   }
01682   qh_memsize((int)sizeof(facetT));
01683   i= sizeof(setT) + (qh hull_dim - 1) * SETelemsize;  /* ridge.vertices */
01684   qh_memsize(i);
01685   qh_memsize(qh normal_size);        /* normal */
01686   i += SETelemsize;                 /* facet.vertices, .ridges, .neighbors */
01687   qh_memsize(i);
01688   qh_user_memsizes();
01689   qh_memsetup();
01690 } /* initqhull_mem */
01691 
01692 /*-<a                             href="qh-globa.htm#TOC"
01693   >-------------------------------</a><a name="initqhull_outputflags">-</a>
01694 
01695   qh_initqhull_outputflags
01696     initialize flags concerned with output
01697 
01698   returns:
01699     adjust user flags as needed
01700 
01701   see:
01702     qh_clear_outputflags() resets the flags
01703 
01704   design:
01705     test for qh.PRINTgood (i.e., only print 'good' facets)
01706     check for conflicting print output options
01707 */
01708 void qh_initqhull_outputflags(void) {
01709   boolT printgeom= False, printmath= False, printcoplanar= False;
01710   int i;
01711 
01712   trace3((qh ferr, 3024, "qh_initqhull_outputflags: %s\n", qh qhull_command));
01713   if (!(qh PRINTgood || qh PRINTneighbors)) {
01714     if (qh KEEParea || qh KEEPminArea < REALmax/2 || qh KEEPmerge || qh DELAUNAY
01715         || (!qh ONLYgood && (qh GOODvertex || qh GOODpoint))) {
01716       qh PRINTgood= True;
01717       qh_option("Pgood", NULL, NULL);
01718     }
01719   }
01720   if (qh PRINTtransparent) {
01721     if (qh hull_dim != 4 || !qh DELAUNAY || qh VORONOI || qh DROPdim >= 0) {
01722       qh_fprintf(qh ferr, 6215, "qhull input error: transparent Delaunay('Gt') needs 3-d Delaunay('d') w/o 'GDn'\n");
01723       qh_errexit(qh_ERRinput, NULL, NULL);
01724     }
01725     qh DROPdim = 3;
01726     qh PRINTridges = True;
01727   }
01728   for (i=qh_PRINTEND; i--; ) {
01729     if (qh PRINTout[i] == qh_PRINTgeom)
01730       printgeom= True;
01731     else if (qh PRINTout[i] == qh_PRINTmathematica || qh PRINTout[i] == qh_PRINTmaple)
01732       printmath= True;
01733     else if (qh PRINTout[i] == qh_PRINTcoplanars)
01734       printcoplanar= True;
01735     else if (qh PRINTout[i] == qh_PRINTpointnearest)
01736       printcoplanar= True;
01737     else if (qh PRINTout[i] == qh_PRINTpointintersect && !qh HALFspace) {
01738       qh_fprintf(qh ferr, 6053, "qhull input error: option 'Fp' is only used for \nhalfspace intersection('Hn,n,n').\n");
01739       qh_errexit(qh_ERRinput, NULL, NULL);
01740     }else if (qh PRINTout[i] == qh_PRINTtriangles && (qh HALFspace || qh VORONOI)) {
01741       qh_fprintf(qh ferr, 6054, "qhull input error: option 'Ft' is not available for Voronoi vertices or halfspace intersection\n");
01742       qh_errexit(qh_ERRinput, NULL, NULL);
01743     }else if (qh PRINTout[i] == qh_PRINTcentrums && qh VORONOI) {
01744       qh_fprintf(qh ferr, 6055, "qhull input error: option 'FC' is not available for Voronoi vertices('v')\n");
01745       qh_errexit(qh_ERRinput, NULL, NULL);
01746     }else if (qh PRINTout[i] == qh_PRINTvertices) {
01747       if (qh VORONOI)
01748         qh_option("Fvoronoi", NULL, NULL);
01749       else
01750         qh_option("Fvertices", NULL, NULL);
01751     }
01752   }
01753   if (printcoplanar && qh DELAUNAY && qh JOGGLEmax < REALmax/2) {
01754     if (qh PRINTprecision)
01755       qh_fprintf(qh ferr, 7041, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n");
01756   }
01757   if (printmath && (qh hull_dim > 3 || qh VORONOI)) {
01758     qh_fprintf(qh ferr, 6056, "qhull input error: Mathematica and Maple output is only available for 2-d and 3-d convex hulls and 2-d Delaunay triangulations\n");
01759     qh_errexit(qh_ERRinput, NULL, NULL);
01760   }
01761   if (printgeom) {
01762     if (qh hull_dim > 4) {
01763       qh_fprintf(qh ferr, 6057, "qhull input error: Geomview output is only available for 2-d, 3-d and 4-d\n");
01764       qh_errexit(qh_ERRinput, NULL, NULL);
01765     }
01766     if (qh PRINTnoplanes && !(qh PRINTcoplanar + qh PRINTcentrums
01767      + qh PRINTdots + qh PRINTspheres + qh DOintersections + qh PRINTridges)) {
01768       qh_fprintf(qh ferr, 6058, "qhull input error: no output specified for Geomview\n");
01769       qh_errexit(qh_ERRinput, NULL, NULL);
01770     }
01771     if (qh VORONOI && (qh hull_dim > 3 || qh DROPdim >= 0)) {
01772       qh_fprintf(qh ferr, 6059, "qhull input error: Geomview output for Voronoi diagrams only for 2-d\n");
01773       qh_errexit(qh_ERRinput, NULL, NULL);
01774     }
01775     /* can not warn about furthest-site Geomview output: no lower_threshold */
01776     if (qh hull_dim == 4 && qh DROPdim == -1 &&
01777         (qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) {
01778       qh_fprintf(qh ferr, 7042, "qhull input warning: coplanars, vertices, and centrums output not\n\
01779 available for 4-d output(ignored).  Could use 'GDn' instead.\n");
01780       qh PRINTcoplanar= qh PRINTspheres= qh PRINTcentrums= False;
01781     }
01782   }
01783   if (!qh KEEPcoplanar && !qh KEEPinside && !qh ONLYgood) {
01784     if ((qh PRINTcoplanar && qh PRINTspheres) || printcoplanar) {
01785       if (qh QHULLfinished) {
01786         qh_fprintf(qh ferr, 7072, "qhull output warning: ignoring coplanar points, option 'Qc' was not set for the first run of qhull.\n");
01787       }else {
01788         qh KEEPcoplanar = True;
01789         qh_option("Qcoplanar", NULL, NULL);
01790       }
01791     }
01792   }
01793   qh PRINTdim= qh hull_dim;
01794   if (qh DROPdim >=0) {    /* after Geomview checks */
01795     if (qh DROPdim < qh hull_dim) {
01796       qh PRINTdim--;
01797       if (!printgeom || qh hull_dim < 3)
01798         qh_fprintf(qh ferr, 7043, "qhull input warning: drop dimension 'GD%d' is only available for 3-d/4-d Geomview\n", qh DROPdim);
01799     }else
01800       qh DROPdim= -1;
01801   }else if (qh VORONOI) {
01802     qh DROPdim= qh hull_dim-1;
01803     qh PRINTdim= qh hull_dim-1;
01804   }
01805 } /* qh_initqhull_outputflags */
01806 
01807 /*-<a                             href="qh-globa.htm#TOC"
01808   >-------------------------------</a><a name="initqhull_start">-</a>
01809 
01810   qh_initqhull_start( infile, outfile, errfile )
01811     allocate memory if needed and call qh_initqhull_start2()
01812 */
01813 void qh_initqhull_start(FILE *infile, FILE *outfile, FILE *errfile) {
01814 
01815 #if qh_QHpointer
01816   if (qh_qh) {
01817     qh_fprintf(errfile, 6205, "qhull error (qh_initqhull_start): qh_qh already defined.  Call qh_save_qhull() first\n");
01818     qh_exit(qh_ERRqhull);  /* no error handler */
01819   }
01820   if (!(qh_qh= (qhT *)qh_malloc(sizeof(qhT)))) {
01821     qh_fprintf(errfile, 6060, "qhull error (qh_initqhull_start): insufficient memory\n");
01822     qh_exit(qh_ERRmem);  /* no error handler */
01823   }
01824 #endif
01825   qh_initstatistics();
01826   qh_initqhull_start2(infile, outfile, errfile);
01827 } /* initqhull_start */
01828 
01829 /*-<a                             href="qh-globa.htm#TOC"
01830   >-------------------------------</a><a name="initqhull_start2">-</a>
01831 
01832   qh_initqhull_start2( infile, outfile, errfile )
01833     start initialization of qhull
01834     initialize statistics, stdio, default values for global variables
01835     assumes qh_qh is defined
01836   notes:
01837     report errors elsewhere, error handling and g_qhull_output [Qhull.cpp, QhullQh()] not in initialized
01838   see:
01839     qh_maxmin() determines the precision constants
01840     qh_freeqhull2()
01841 */
01842 void qh_initqhull_start2(FILE *infile, FILE *outfile, FILE *errfile) {
01843   time_t timedata;
01844   int seed;
01845 
01846   qh_CPUclock; /* start the clock(for qh_clock).  One-shot. */
01847 #if qh_QHpointer
01848   memset((char *)qh_qh, 0, sizeof(qhT));   /* every field is 0, FALSE, NULL */
01849 #else
01850   memset((char *)&qh_qh, 0, sizeof(qhT));
01851 #endif
01852   qh ANGLEmerge= True;
01853   qh DROPdim= -1;
01854   qh ferr= errfile;
01855   qh fin= infile;
01856   qh fout= outfile;
01857   qh furthest_id= -1;
01858   qh JOGGLEmax= REALmax;
01859   qh KEEPminArea = REALmax;
01860   qh last_low= REALmax;
01861   qh last_high= REALmax;
01862   qh last_newhigh= REALmax;
01863   qh max_outside= 0.0;
01864   qh max_vertex= 0.0;
01865   qh MAXabs_coord= 0.0;
01866   qh MAXsumcoord= 0.0;
01867   qh MAXwidth= -REALmax;
01868   qh MERGEindependent= True;
01869   qh MINdenom_1= fmax_(1.0/REALmax, REALmin); /* used by qh_scalepoints */
01870   qh MINoutside= 0.0;
01871   qh MINvisible= REALmax;
01872   qh MAXcoplanar= REALmax;
01873   qh outside_err= REALmax;
01874   qh premerge_centrum= 0.0;
01875   qh premerge_cos= REALmax;
01876   qh PRINTprecision= True;
01877   qh PRINTradius= 0.0;
01878   qh postmerge_cos= REALmax;
01879   qh postmerge_centrum= 0.0;
01880   qh ROTATErandom= INT_MIN;
01881   qh MERGEvertices= True;
01882   qh totarea= 0.0;
01883   qh totvol= 0.0;
01884   qh TRACEdist= REALmax;
01885   qh TRACEpoint= -1; /* recompile or use 'TPn' */
01886   qh tracefacet_id= UINT_MAX;  /* recompile to trace a facet */
01887   qh tracevertex_id= UINT_MAX; /* recompile to trace a vertex */
01888   seed= (int)time(&timedata);
01889   qh_RANDOMseed_(seed);
01890   qh run_id= qh_RANDOMint+1; /* disallow 0 [UsingLibQhull::NOqhRunId] */
01891   qh_option("run-id", &qh run_id, NULL);
01892   strcat(qh qhull, "qhull");
01893 } /* initqhull_start2 */
01894 
01895 /*-<a                             href="qh-globa.htm#TOC"
01896   >-------------------------------</a><a name="initthresholds">-</a>
01897 
01898   qh_initthresholds( commandString )
01899     set thresholds for printing and scaling from commandString
01900 
01901   returns:
01902     sets qh.GOODthreshold or qh.SPLITthreshold if 'Pd0D1' used
01903 
01904   see:
01905     qh_initflags(), 'Qbk' 'QBk' 'Pdk' and 'PDk'
01906     qh_inthresholds()
01907 
01908   design:
01909     for each 'Pdn' or 'PDn' option
01910       check syntax
01911       set qh.lower_threshold or qh.upper_threshold
01912     set qh.GOODthreshold if an unbounded threshold is used
01913     set qh.SPLITthreshold if a bounded threshold is used
01914 */
01915 void qh_initthresholds(char *command) {
01916   realT value;
01917   int idx, maxdim, k;
01918   char *s= command; /* non-const due to strtol */
01919   char key;
01920 
01921   maxdim= qh input_dim;
01922   if (qh DELAUNAY && (qh PROJECTdelaunay || qh PROJECTinput))
01923     maxdim++;
01924   while (*s) {
01925     if (*s == '-')
01926       s++;
01927     if (*s == 'P') {
01928       s++;
01929       while (*s && !isspace(key= *s++)) {
01930         if (key == 'd' || key == 'D') {
01931           if (!isdigit(*s)) {
01932             qh_fprintf(qh ferr, 7044, "qhull warning: no dimension given for Print option '%c' at: %s.  Ignored\n",
01933                     key, s-1);
01934             continue;
01935           }
01936           idx= qh_strtol(s, &s);
01937           if (idx >= qh hull_dim) {
01938             qh_fprintf(qh ferr, 7045, "qhull warning: dimension %d for Print option '%c' is >= %d.  Ignored\n",
01939                 idx, key, qh hull_dim);
01940             continue;
01941           }
01942           if (*s == ':') {
01943             s++;
01944             value= qh_strtod(s, &s);
01945             if (fabs((double)value) > 1.0) {
01946               qh_fprintf(qh ferr, 7046, "qhull warning: value %2.4g for Print option %c is > +1 or < -1.  Ignored\n",
01947                       value, key);
01948               continue;
01949             }
01950           }else
01951             value= 0.0;
01952           if (key == 'd')
01953             qh lower_threshold[idx]= value;
01954           else
01955             qh upper_threshold[idx]= value;
01956         }
01957       }
01958     }else if (*s == 'Q') {
01959       s++;
01960       while (*s && !isspace(key= *s++)) {
01961         if (key == 'b' && *s == 'B') {
01962           s++;
01963           for (k=maxdim; k--; ) {
01964             qh lower_bound[k]= -qh_DEFAULTbox;
01965             qh upper_bound[k]= qh_DEFAULTbox;
01966           }
01967         }else if (key == 'b' && *s == 'b')
01968           s++;
01969         else if (key == 'b' || key == 'B') {
01970           if (!isdigit(*s)) {
01971             qh_fprintf(qh ferr, 7047, "qhull warning: no dimension given for Qhull option %c.  Ignored\n",
01972                     key);
01973             continue;
01974           }
01975           idx= qh_strtol(s, &s);
01976           if (idx >= maxdim) {
01977             qh_fprintf(qh ferr, 7048, "qhull warning: dimension %d for Qhull option %c is >= %d.  Ignored\n",
01978                 idx, key, maxdim);
01979             continue;
01980           }
01981           if (*s == ':') {
01982             s++;
01983             value= qh_strtod(s, &s);
01984           }else if (key == 'b')
01985             value= -qh_DEFAULTbox;
01986           else
01987             value= qh_DEFAULTbox;
01988           if (key == 'b')
01989             qh lower_bound[idx]= value;
01990           else
01991             qh upper_bound[idx]= value;
01992         }
01993       }
01994     }else {
01995       while (*s && !isspace(*s))
01996         s++;
01997     }
01998     while (isspace(*s))
01999       s++;
02000   }
02001   for (k=qh hull_dim; k--; ) {
02002     if (qh lower_threshold[k] > -REALmax/2) {
02003       qh GOODthreshold= True;
02004       if (qh upper_threshold[k] < REALmax/2) {
02005         qh SPLITthresholds= True;
02006         qh GOODthreshold= False;
02007         break;
02008       }
02009     }else if (qh upper_threshold[k] < REALmax/2)
02010       qh GOODthreshold= True;
02011   }
02012 } /* initthresholds */
02013 
02014 /*-<a                             href="qh-globa.htm#TOC"
02015   >-------------------------------</a><a name="option">-</a>
02016 
02017   qh_option( option, intVal, realVal )
02018     add an option description to qh.qhull_options
02019 
02020   notes:
02021     NOerrors -- qh_option can not call qh_errexit() [qh_initqhull_start2]
02022     will be printed with statistics ('Ts') and errors
02023     strlen(option) < 40
02024 */
02025 void qh_option(const char *option, int *i, realT *r) {
02026   char buf[200];
02027   int len, maxlen;
02028 
02029   sprintf(buf, "  %s", option);
02030   if (i)
02031     sprintf(buf+strlen(buf), " %d", *i);
02032   if (r)
02033     sprintf(buf+strlen(buf), " %2.2g", *r);
02034   len= (int)strlen(buf);  /* WARN64 */
02035   qh qhull_optionlen += len;
02036   maxlen= sizeof(qh qhull_options) - len -1;
02037   maximize_(maxlen, 0);
02038   if (qh qhull_optionlen >= qh_OPTIONline && maxlen > 0) {
02039     qh qhull_optionlen= len;
02040     strncat(qh qhull_options, "\n", (size_t)(maxlen--));
02041   }
02042   strncat(qh qhull_options, buf, (size_t)maxlen);
02043 } /* option */
02044 
02045 #if qh_QHpointer
02046 /*-<a                             href="qh-globa.htm#TOC"
02047   >-------------------------------</a><a name="restore_qhull">-</a>
02048 
02049   qh_restore_qhull( oldqh )
02050     restores a previously saved qhull
02051     also restores qh_qhstat and qhmem.tempstack
02052     Sets *oldqh to NULL
02053   notes:
02054     errors if current qhull hasn't been saved or freed
02055     uses qhmem for error reporting
02056 
02057   NOTE 1998/5/11:
02058     Freeing memory after qh_save_qhull and qh_restore_qhull
02059     is complicated.  The procedures will be redesigned.
02060 
02061   see:
02062     qh_save_qhull(), UsingLibQhull
02063 */
02064 void qh_restore_qhull(qhT **oldqh) {
02065 
02066   if (*oldqh && strcmp((*oldqh)->qhull, "qhull")) {
02067     qh_fprintf(qhmem.ferr, 6061, "qhull internal error (qh_restore_qhull): %p is not a qhull data structure\n",
02068                   *oldqh);
02069     qh_errexit(qh_ERRqhull, NULL, NULL);
02070   }
02071   if (qh_qh) {
02072     qh_fprintf(qhmem.ferr, 6062, "qhull internal error (qh_restore_qhull): did not save or free existing qhull\n");
02073     qh_errexit(qh_ERRqhull, NULL, NULL);
02074   }
02075   if (!*oldqh || !(*oldqh)->old_qhstat) {
02076     qh_fprintf(qhmem.ferr, 6063, "qhull internal error (qh_restore_qhull): did not previously save qhull %p\n",
02077                   *oldqh);
02078     qh_errexit(qh_ERRqhull, NULL, NULL);
02079   }
02080   qh_qh= *oldqh;
02081   *oldqh= NULL;
02082   qh_qhstat= qh old_qhstat;
02083   qhmem.tempstack= qh old_tempstack;
02084   qh old_qhstat= 0;
02085   qh old_tempstack= 0;
02086   trace1((qh ferr, 1007, "qh_restore_qhull: restored qhull from %p\n", *oldqh));
02087 } /* restore_qhull */
02088 
02089 /*-<a                             href="qh-globa.htm#TOC"
02090   >-------------------------------</a><a name="save_qhull">-</a>
02091 
02092   qh_save_qhull(  )
02093     saves qhull for a later qh_restore_qhull
02094     also saves qh_qhstat and qhmem.tempstack
02095 
02096   returns:
02097     qh_qh=NULL
02098 
02099   notes:
02100     need to initialize qhull or call qh_restore_qhull before continuing
02101 
02102   NOTE 1998/5/11:
02103     Freeing memory after qh_save_qhull and qh_restore_qhull
02104     is complicated.  The procedures will be redesigned.
02105 
02106   see:
02107     qh_restore_qhull()
02108 */
02109 qhT *qh_save_qhull(void) {
02110   qhT *oldqh;
02111 
02112   trace1((qhmem.ferr, 1045, "qh_save_qhull: save qhull %p\n", qh_qh));
02113   if (!qh_qh) {
02114     qh_fprintf(qhmem.ferr, 6064, "qhull internal error (qh_save_qhull): qhull not initialized\n");
02115     qh_errexit(qh_ERRqhull, NULL, NULL);
02116   }
02117   qh old_qhstat= qh_qhstat;
02118   qh_qhstat= NULL;
02119   qh old_tempstack= qhmem.tempstack;
02120   qhmem.tempstack= NULL;
02121   oldqh= qh_qh;
02122   qh_qh= NULL;
02123   return oldqh;
02124 } /* save_qhull */
02125 
02126 #endif
02127 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


libqhull
Author(s): Robert Krug
autogenerated on Tue Jun 18 2013 12:38:49