00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "qhull_a.h"
00020
00021
00022
00023 int qhull_inuse= 0;
00024
00025 #if qh_QHpointer
00026 qhT *qh_qh= NULL;
00027 #else
00028 qhT qh_qh;
00029
00030
00031 #endif
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 const char *qh_version = "2011.2 2011/11/29";
00051
00052
00053
00054
00055
00056
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 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 void qh_checkflags(char *command, char *hiddenflags) {
00086 char *s= command, *t, *chkerr;
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))
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')) {
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 }
00159
00160
00161
00162
00163
00164
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--; ) {
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);
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);
00221 else {
00222 qh qhull_options[qh qhull_optionsiz2]= '\0';
00223 qh qhull_optionlen= qh_OPTIONline;
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 unsigned long qh_clock(void) {
00239
00240 #if (qh_CLOCKtype == 2)
00241 struct tms time;
00242 static long clktck;
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);
00262 return 0;
00263 #endif
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 void qh_freebuffers(void) {
00276
00277 trace5((qh ferr, 5001, "qh_freebuffers: freeing up global memory buffers\n"));
00278
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)
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)
00300 qh_free(qh feasible_point);
00301 if (qh feasible_string)
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
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) {
00311 qh_free(qh input_points);
00312 qh input_points= NULL;
00313 }
00314 trace5((qh ferr, 5002, "qh_freebuffers: finished\n"));
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
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;
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)
00411 qh_memfree(merge, (int)sizeof(mergeT));
00412 qh facet_mergeset= NULL;
00413 qh degen_mergeset= NULL;
00414 qh_settempfree_all();
00415 }
00416
00417
00418
00419
00420
00421
00422
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
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 void qh_freeqhull2(boolT allmem) {
00452
00453 trace1((qh ferr, 1006, "qh_freeqhull2: free global memory\n"));
00454 qh NOerrexit= True;
00455 qh_freebuild(allmem);
00456 qh_freebuffers();
00457 qh_freestatistics();
00458 #if qh_QHpointer
00459 memset((char *)qh_qh, 0, sizeof(qhT));
00460
00461 #else
00462 memset((char *)&qh_qh, 0, sizeof(qhT));
00463 #endif
00464 qh NOerrexit= True;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
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 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
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
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 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
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
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);
00579 }
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
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))
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
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
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':
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':
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;
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;
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;
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
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;
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));
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));
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
01416 }
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
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;
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--; ) {
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 }
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
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;
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)
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 }
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
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;
01684 qh_memsize(i);
01685 qh_memsize(qh normal_size);
01686 i += SETelemsize;
01687 qh_memsize(i);
01688 qh_user_memsizes();
01689 qh_memsetup();
01690 }
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
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
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) {
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 }
01806
01807
01808
01809
01810
01811
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);
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);
01823 }
01824 #endif
01825 qh_initstatistics();
01826 qh_initqhull_start2(infile, outfile, errfile);
01827 }
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842 void qh_initqhull_start2(FILE *infile, FILE *outfile, FILE *errfile) {
01843 time_t timedata;
01844 int seed;
01845
01846 qh_CPUclock;
01847 #if qh_QHpointer
01848 memset((char *)qh_qh, 0, sizeof(qhT));
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);
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;
01886 qh tracefacet_id= UINT_MAX;
01887 qh tracevertex_id= UINT_MAX;
01888 seed= (int)time(&timedata);
01889 qh_RANDOMseed_(seed);
01890 qh run_id= qh_RANDOMint+1;
01891 qh_option("run-id", &qh run_id, NULL);
01892 strcat(qh qhull, "qhull");
01893 }
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915 void qh_initthresholds(char *command) {
01916 realT value;
01917 int idx, maxdim, k;
01918 char *s= command;
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 }
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
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);
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 }
02044
02045 #if qh_QHpointer
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
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 }
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
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 }
02125
02126 #endif
02127