00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "qhull_a.h"
00016
00017 #ifdef USE_DMALLOC
00018 #include "dmalloc.h"
00019 #endif
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 void qh_appendfacet(facetT *facet) {
00038 facetT *tail= qh facet_tail;
00039
00040 if (tail == qh newfacet_list)
00041 qh newfacet_list= facet;
00042 if (tail == qh facet_next)
00043 qh facet_next= facet;
00044 facet->previous= tail->previous;
00045 facet->next= tail;
00046 if (tail->previous)
00047 tail->previous->next= facet;
00048 else
00049 qh facet_list= facet;
00050 tail->previous= facet;
00051 qh num_facets++;
00052 trace4((qh ferr, "qh_appendfacet: append f%d to facet_list\n", facet->id));
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 void qh_appendvertex (vertexT *vertex) {
00072 vertexT *tail= qh vertex_tail;
00073
00074 if (tail == qh newvertex_list)
00075 qh newvertex_list= vertex;
00076 vertex->newlist= True;
00077 vertex->previous= tail->previous;
00078 vertex->next= tail;
00079 if (tail->previous)
00080 tail->previous->next= vertex;
00081 else
00082 qh vertex_list= vertex;
00083 tail->previous= vertex;
00084 qh num_vertices++;
00085 trace4((qh ferr, "qh_appendvertex: append v%d to vertex_list\n", vertex->id));
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 void qh_attachnewfacets (void ) {
00129 facetT *newfacet= NULL, *neighbor, **neighborp, *horizon, *visible;
00130 ridgeT *ridge, **ridgep;
00131
00132 qh NEWfacets= True;
00133 trace3((qh ferr, "qh_attachnewfacets: delete interior ridges\n"));
00134 qh visit_id++;
00135 FORALLvisible_facets {
00136 visible->visitid= qh visit_id;
00137 if (visible->ridges) {
00138 FOREACHridge_(visible->ridges) {
00139 neighbor= otherfacet_(ridge, visible);
00140 if (neighbor->visitid == qh visit_id
00141 || (!neighbor->visible && neighbor->simplicial)) {
00142 if (!neighbor->visible)
00143 qh_setdel (neighbor->ridges, ridge);
00144 qh_setfree (&(ridge->vertices));
00145 qh_memfree (ridge, sizeof(ridgeT));
00146 }
00147 }
00148 SETfirst_(visible->ridges)= NULL;
00149 }
00150 SETfirst_(visible->neighbors)= NULL;
00151 }
00152 trace1((qh ferr, "qh_attachnewfacets: attach horizon facets to new facets\n"));
00153 FORALLnew_facets {
00154 horizon= SETfirstt_(newfacet->neighbors, facetT);
00155 if (horizon->simplicial) {
00156 visible= NULL;
00157 FOREACHneighbor_(horizon) {
00158 if (neighbor->visible) {
00159 if (visible) {
00160 if (qh_setequal_skip (newfacet->vertices, 0, horizon->vertices,
00161 SETindex_(horizon->neighbors, neighbor))) {
00162 visible= neighbor;
00163 break;
00164 }
00165 }else
00166 visible= neighbor;
00167 }
00168 }
00169 if (visible) {
00170 visible->f.replace= newfacet;
00171 qh_setreplace (horizon->neighbors, visible, newfacet);
00172 }else {
00173 fprintf (qh ferr, "qhull internal error (qh_attachnewfacets): couldn't find visible facet for horizon f%d of newfacet f%d\n",
00174 horizon->id, newfacet->id);
00175 qh_errexit2 (qh_ERRqhull, horizon, newfacet);
00176 }
00177 }else {
00178 FOREACHneighbor_(horizon) {
00179 if (neighbor->visible) {
00180 neighbor->f.replace= newfacet;
00181 qh_setdelnth (horizon->neighbors,
00182 SETindex_(horizon->neighbors, neighbor));
00183 neighborp--;
00184 }
00185 }
00186 qh_setappend (&horizon->neighbors, newfacet);
00187 ridge= SETfirstt_(newfacet->ridges, ridgeT);
00188 if (ridge->top == horizon)
00189 ridge->bottom= newfacet;
00190 else
00191 ridge->top= newfacet;
00192 }
00193 }
00194 if (qh PRINTstatistics) {
00195 FORALLvisible_facets {
00196 if (!visible->f.replace)
00197 zinc_(Zinsidevisible);
00198 }
00199 }
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 boolT qh_checkflipped (facetT *facet, realT *distp, boolT allerror) {
00218 realT dist;
00219
00220 if (facet->flipped && !distp)
00221 return False;
00222 zzinc_(Zdistcheck);
00223 qh_distplane(qh interior_point, facet, &dist);
00224 if (distp)
00225 *distp= dist;
00226 if ((allerror && dist > -qh DISTround)|| (!allerror && dist >= 0.0)) {
00227 facet->flipped= True;
00228 zzinc_(Zflippedfacets);
00229 trace0((qh ferr, "qh_checkflipped: facet f%d is flipped, distance= %6.12g during p%d\n",
00230 facet->id, dist, qh furthest_id));
00231 qh_precision ("flipped facet");
00232 return False;
00233 }
00234 return True;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 void qh_delfacet(facetT *facet) {
00247 void **freelistp;
00248
00249 trace5((qh ferr, "qh_delfacet: delete f%d\n", facet->id));
00250 if (facet == qh tracefacet)
00251 qh tracefacet= NULL;
00252 if (facet == qh GOODclosest)
00253 qh GOODclosest= NULL;
00254 qh_removefacet(facet);
00255 qh_memfree_(facet->normal, qh normal_size, freelistp);
00256 if (qh CENTERtype == qh_ASvoronoi) {
00257 qh_memfree_(facet->center, qh center_size, freelistp);
00258 }else {
00259 qh_memfree_(facet->center, qh normal_size, freelistp);
00260 }
00261 qh_setfree(&(facet->neighbors));
00262 if (facet->ridges)
00263 qh_setfree(&(facet->ridges));
00264 qh_setfree(&(facet->vertices));
00265 if (facet->outsideset)
00266 qh_setfree(&(facet->outsideset));
00267 if (facet->coplanarset)
00268 qh_setfree(&(facet->coplanarset));
00269 qh_memfree_(facet, sizeof(facetT), freelistp);
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 void qh_deletevisible (void ) {
00290 facetT *visible, *nextfacet;
00291 vertexT *vertex, **vertexp;
00292 int numvisible= 0, numdel= qh_setsize(qh del_vertices);
00293
00294 trace1((qh ferr, "qh_deletevisible: delete %d visible facets and %d vertices\n",
00295 qh num_visible, numdel));
00296 for (visible= qh visible_list; visible && visible->visible;
00297 visible= nextfacet) {
00298 nextfacet= visible->next;
00299 numvisible++;
00300 qh_delfacet(visible);
00301 }
00302 if (numvisible != qh num_visible) {
00303 fprintf (qh ferr, "qhull internal error (qh_deletevisible): qh num_visible %d is not number of visible facets %d\n",
00304 qh num_visible, numvisible);
00305 qh_errexit (qh_ERRqhull, NULL, NULL);
00306 }
00307 qh num_visible= 0;
00308 zadd_(Zvisfacettot, numvisible);
00309 zmax_(Zvisfacetmax, numvisible);
00310 zadd_(Zdelvertextot, numdel);
00311 zmax_(Zdelvertexmax, numdel);
00312 FOREACHvertex_(qh del_vertices)
00313 qh_delvertex (vertex);
00314 qh_settruncate (qh del_vertices, 0);
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
00340 setT *qh_facetintersect (facetT *facetA, facetT *facetB,
00341 int *skipA,int *skipB, int prepend) {
00342 setT *intersect;
00343 int dim= qh hull_dim, i, j;
00344 facetT **neighborsA, **neighborsB;
00345
00346 neighborsA= SETaddr_(facetA->neighbors, facetT);
00347 neighborsB= SETaddr_(facetB->neighbors, facetT);
00348 i= j= 0;
00349 if (facetB == *neighborsA++)
00350 *skipA= 0;
00351 else if (facetB == *neighborsA++)
00352 *skipA= 1;
00353 else if (facetB == *neighborsA++)
00354 *skipA= 2;
00355 else {
00356 for (i= 3; i < dim; i++) {
00357 if (facetB == *neighborsA++) {
00358 *skipA= i;
00359 break;
00360 }
00361 }
00362 }
00363 if (facetA == *neighborsB++)
00364 *skipB= 0;
00365 else if (facetA == *neighborsB++)
00366 *skipB= 1;
00367 else if (facetA == *neighborsB++)
00368 *skipB= 2;
00369 else {
00370 for (j= 3; j < dim; j++) {
00371 if (facetA == *neighborsB++) {
00372 *skipB= j;
00373 break;
00374 }
00375 }
00376 }
00377 if (i >= dim || j >= dim) {
00378 fprintf (qh ferr, "qhull internal error (qh_facetintersect): f%d or f%d not in others neighbors\n",
00379 facetA->id, facetB->id);
00380 qh_errexit2 (qh_ERRqhull, facetA, facetB);
00381 }
00382 intersect= qh_setnew_delnthsorted (facetA->vertices, qh hull_dim, *skipA, prepend);
00383 trace4((qh ferr, "qh_facetintersect: f%d skip %d matches f%d skip %d\n",
00384 facetA->id, *skipA, facetB->id, *skipB));
00385 return(intersect);
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem) {
00402 void **elemp= SETelemaddr_(set, firstindex, void);
00403 ptr_intT hash = 0, elem;
00404 int i;
00405
00406 switch (size-firstindex) {
00407 case 1:
00408 hash= (ptr_intT)(*elemp) - (ptr_intT) skipelem;
00409 break;
00410 case 2:
00411 hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] - (ptr_intT) skipelem;
00412 break;
00413 case 3:
00414 hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
00415 - (ptr_intT) skipelem;
00416 break;
00417 case 4:
00418 hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
00419 + (ptr_intT)elemp[3] - (ptr_intT) skipelem;
00420 break;
00421 case 5:
00422 hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
00423 + (ptr_intT)elemp[3] + (ptr_intT)elemp[4] - (ptr_intT) skipelem;
00424 break;
00425 case 6:
00426 hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
00427 + (ptr_intT)elemp[3] + (ptr_intT)elemp[4]+ (ptr_intT)elemp[5]
00428 - (ptr_intT) skipelem;
00429 break;
00430 default:
00431 hash= 0;
00432 i= 3;
00433 do {
00434 if ((elem= (ptr_intT)*elemp++) != (ptr_intT)skipelem) {
00435 hash ^= (elem << i) + (elem >> (32-i));
00436 i += 3;
00437 if (i >= 32)
00438 i -= 32;
00439 }
00440 }while(*elemp);
00441 break;
00442 }
00443 hash %= (ptr_intT) hashsize;
00444
00445 return hash;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 facetT *qh_makenewfacet(setT *vertices, boolT toporient,facetT *horizon) {
00462 facetT *newfacet;
00463 vertexT *vertex, **vertexp;
00464
00465 FOREACHvertex_(vertices) {
00466 if (!vertex->newlist) {
00467 qh_removevertex (vertex);
00468 qh_appendvertex (vertex);
00469 }
00470 }
00471 newfacet= qh_newfacet();
00472 newfacet->vertices= vertices;
00473 newfacet->toporient= toporient;
00474 qh_setappend(&(newfacet->neighbors), horizon);
00475 qh_appendfacet(newfacet);
00476 return(newfacet);
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 void qh_makenewplanes (void ) {
00495 facetT *newfacet;
00496
00497 FORALLnew_facets {
00498 if (!newfacet->mergehorizon)
00499 qh_setfacetplane (newfacet);
00500 }
00501 if (qh JOGGLEmax < REALmax/2)
00502 minimize_(qh min_vertex, -wwval_(Wnewvertexmax));
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
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 #ifndef qh_NOmerge
00543 facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) {
00544 void **freelistp;
00545 ridgeT *ridge, **ridgep;
00546 facetT *neighbor, *newfacet= NULL, *samecycle;
00547 setT *vertices;
00548 boolT toporient;
00549 int ridgeid;
00550
00551 FOREACHridge_(visible->ridges) {
00552 ridgeid= ridge->id;
00553 neighbor= otherfacet_(ridge, visible);
00554 if (neighbor->visible) {
00555 if (!qh ONLYgood) {
00556 if (neighbor->visitid == qh visit_id) {
00557 qh_setfree (&(ridge->vertices));
00558 qh_memfree_(ridge, sizeof(ridgeT), freelistp);
00559 }
00560 }
00561 }else {
00562 toporient= (ridge->top == visible);
00563 vertices= qh_setnew (qh hull_dim);
00564 qh_setappend (&vertices, apex);
00565 qh_setappend_set (&vertices, ridge->vertices);
00566 newfacet= qh_makenewfacet(vertices, toporient, neighbor);
00567 (*numnew)++;
00568 if (neighbor->coplanar) {
00569 newfacet->mergehorizon= True;
00570 if (!neighbor->seen) {
00571 newfacet->f.samecycle= newfacet;
00572 neighbor->f.newcycle= newfacet;
00573 }else {
00574 samecycle= neighbor->f.newcycle;
00575 newfacet->f.samecycle= samecycle->f.samecycle;
00576 samecycle->f.samecycle= newfacet;
00577 }
00578 }
00579 if (qh ONLYgood) {
00580 if (!neighbor->simplicial)
00581 qh_setappend(&(newfacet->ridges), ridge);
00582 }else {
00583 if (neighbor->seen) {
00584 if (neighbor->simplicial) {
00585 fprintf (qh ferr, "qhull internal error (qh_makenew_nonsimplicial): simplicial f%d sharing two ridges with f%d\n",
00586 neighbor->id, visible->id);
00587 qh_errexit2 (qh_ERRqhull, neighbor, visible);
00588 }
00589 qh_setappend (&(neighbor->neighbors), newfacet);
00590 }else
00591 qh_setreplace (neighbor->neighbors, visible, newfacet);
00592 if (neighbor->simplicial) {
00593 qh_setdel (neighbor->ridges, ridge);
00594 qh_setfree (&(ridge->vertices));
00595 qh_memfree (ridge, sizeof(ridgeT));
00596 }else {
00597 qh_setappend(&(newfacet->ridges), ridge);
00598 if (toporient)
00599 ridge->top= newfacet;
00600 else
00601 ridge->bottom= newfacet;
00602 }
00603 trace4((qh ferr, "qh_makenew_nonsimplicial: created facet f%d from v%d and r%d of horizon f%d\n",
00604 newfacet->id, apex->id, ridgeid, neighbor->id));
00605 }
00606 }
00607 neighbor->seen= True;
00608 }
00609 if (!qh ONLYgood)
00610 SETfirst_(visible->ridges)= NULL;
00611 return newfacet;
00612 }
00613 #else
00614 facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) {
00615 return NULL;
00616 }
00617 #endif
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew) {
00641 facetT *neighbor, **neighborp, *newfacet= NULL;
00642 setT *vertices;
00643 boolT flip, toporient;
00644 int horizonskip, visibleskip;
00645
00646 FOREACHneighbor_(visible) {
00647 if (!neighbor->seen && !neighbor->visible) {
00648 vertices= qh_facetintersect(neighbor,visible, &horizonskip, &visibleskip, 1);
00649 SETfirst_(vertices)= apex;
00650 flip= ((horizonskip & 0x1) ^ (visibleskip & 0x1));
00651 if (neighbor->toporient)
00652 toporient= horizonskip & 0x1;
00653 else
00654 toporient= (horizonskip & 0x1) ^ 0x1;
00655 newfacet= qh_makenewfacet(vertices, toporient, neighbor);
00656 (*numnew)++;
00657 if (neighbor->coplanar && (qh PREmerge || qh MERGEexact)) {
00658 #ifndef qh_NOmerge
00659 newfacet->f.samecycle= newfacet;
00660 newfacet->mergehorizon= True;
00661 #endif
00662 }
00663 if (!qh ONLYgood)
00664 SETelem_(neighbor->neighbors, horizonskip)= newfacet;
00665 trace4((qh ferr, "qh_makenew_simplicial: create facet f%d top %d from v%d and horizon f%d skip %d top %d and visible f%d skip %d, flip? %d\n",
00666 newfacet->id, toporient, apex->id, neighbor->id, horizonskip,
00667 neighbor->toporient, visible->id, visibleskip, flip));
00668 }
00669 }
00670 return newfacet;
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 void qh_matchneighbor (facetT *newfacet, int newskip, int hashsize, int *hashcount) {
00705 boolT newfound= False;
00706 boolT same, ismatch;
00707 int hash, scan;
00708 facetT *facet, *matchfacet;
00709 int skip, matchskip;
00710
00711 hash= (int)qh_gethash (hashsize, newfacet->vertices, qh hull_dim, 1,
00712 SETelem_(newfacet->vertices, newskip));
00713 trace4((qh ferr, "qh_matchneighbor: newfacet f%d skip %d hash %d hashcount %d\n",
00714 newfacet->id, newskip, hash, *hashcount));
00715 zinc_(Zhashlookup);
00716 for (scan= hash; (facet= SETelemt_(qh hash_table, scan, facetT));
00717 scan= (++scan >= hashsize ? 0 : scan)) {
00718 if (facet == newfacet) {
00719 newfound= True;
00720 continue;
00721 }
00722 zinc_(Zhashtests);
00723 if (qh_matchvertices (1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
00724 if (SETelem_(newfacet->vertices, newskip) ==
00725 SETelem_(facet->vertices, skip)) {
00726 qh_precision ("two facets with the same vertices");
00727 fprintf (qh ferr, "qhull precision error: Vertex sets are the same for f%d and f%d. Can not force output.\n",
00728 facet->id, newfacet->id);
00729 qh_errexit2 (qh_ERRprec, facet, newfacet);
00730 }
00731 ismatch= (same == (newfacet->toporient ^ facet->toporient));
00732 matchfacet= SETelemt_(facet->neighbors, skip, facetT);
00733 if (ismatch && !matchfacet) {
00734 SETelem_(facet->neighbors, skip)= newfacet;
00735 SETelem_(newfacet->neighbors, newskip)= facet;
00736 (*hashcount)--;
00737 trace4((qh ferr, "qh_matchneighbor: f%d skip %d matched with new f%d skip %d\n",
00738 facet->id, skip, newfacet->id, newskip));
00739 return;
00740 }
00741 if (!qh PREmerge && !qh MERGEexact) {
00742 qh_precision ("a ridge with more than two neighbors");
00743 fprintf (qh ferr, "qhull precision error: facets f%d, f%d and f%d meet at a ridge with more than 2 neighbors. Can not continue.\n",
00744 facet->id, newfacet->id, getid_(matchfacet));
00745 qh_errexit2 (qh_ERRprec, facet, newfacet);
00746 }
00747 SETelem_(newfacet->neighbors, newskip)= qh_DUPLICATEridge;
00748 newfacet->dupridge= True;
00749 if (!newfacet->normal)
00750 qh_setfacetplane (newfacet);
00751 qh_addhash (newfacet, qh hash_table, hashsize, hash);
00752 (*hashcount)++;
00753 if (!facet->normal)
00754 qh_setfacetplane (facet);
00755 if (matchfacet != qh_DUPLICATEridge) {
00756 SETelem_(facet->neighbors, skip)= qh_DUPLICATEridge;
00757 facet->dupridge= True;
00758 if (!facet->normal)
00759 qh_setfacetplane (facet);
00760 if (matchfacet) {
00761 matchskip= qh_setindex (matchfacet->neighbors, facet);
00762 SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge;
00763 matchfacet->dupridge= True;
00764 if (!matchfacet->normal)
00765 qh_setfacetplane (matchfacet);
00766 qh_addhash (matchfacet, qh hash_table, hashsize, hash);
00767 *hashcount += 2;
00768 }
00769 }
00770 trace4((qh ferr, "qh_matchneighbor: new f%d skip %d duplicates ridge for f%d skip %d matching f%d ismatch %d at hash %d\n",
00771 newfacet->id, newskip, facet->id, skip,
00772 (matchfacet == qh_DUPLICATEridge ? -2 : getid_(matchfacet)),
00773 ismatch, hash));
00774 return;
00775 }
00776 }
00777 if (!newfound)
00778 SETelem_(qh hash_table, scan)= newfacet;
00779 (*hashcount)++;
00780 trace4((qh ferr, "qh_matchneighbor: no match for f%d skip %d at hash %d\n",
00781 newfacet->id, newskip, hash));
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 void qh_matchnewfacets (void) {
00817 int numnew=0, hashcount=0, newskip;
00818 facetT *newfacet, *neighbor;
00819 int dim= qh hull_dim, hashsize, neighbor_i, neighbor_n;
00820 setT *neighbors;
00821 #ifndef qh_NOtrace
00822 int facet_i, facet_n, numfree= 0;
00823 facetT *facet;
00824 #endif
00825
00826 trace1((qh ferr, "qh_matchnewfacets: match neighbors for new facets.\n"));
00827 FORALLnew_facets {
00828 numnew++;
00829 {
00830 neighbors= newfacet->neighbors;
00831 neighbors->e[neighbors->maxsize].i= dim+1;
00832 memset ((char *)SETelemaddr_(neighbors, 1, void), 0, dim * SETelemsize);
00833 }
00834 }
00835 qh_newhashtable (numnew*(qh hull_dim-1));
00836
00837 hashsize= qh_setsize (qh hash_table);
00838 FORALLnew_facets {
00839 for (newskip=1; newskip<qh hull_dim; newskip++)
00840 qh_matchneighbor (newfacet, newskip, hashsize, &hashcount);
00841 #if 0
00842 {
00843 int count= 0, k;
00844 facetT *facet, *neighbor;
00845
00846 count= 0;
00847 FORALLfacet_(qh newfacet_list) {
00848 for (k=1; k < qh hull_dim; k++) {
00849 neighbor= SETelemt_(facet->neighbors, k, facetT);
00850 if (!neighbor || neighbor == qh_DUPLICATEridge)
00851 count++;
00852 }
00853 if (facet == newfacet)
00854 break;
00855 }
00856 if (count != hashcount) {
00857 fprintf (qh ferr, "qh_matchnewfacets: after adding facet %d, hashcount %d != count %d\n",
00858 newfacet->id, hashcount, count);
00859 qh_errexit (qh_ERRqhull, newfacet, NULL);
00860 }
00861 }
00862 #endif
00863 }
00864 if (hashcount) {
00865 FORALLnew_facets {
00866 if (newfacet->dupridge) {
00867 FOREACHneighbor_i_(newfacet) {
00868 if (neighbor == qh_DUPLICATEridge) {
00869 qh_matchduplicates (newfacet, neighbor_i, hashsize, &hashcount);
00870
00871 }
00872 }
00873 }
00874 }
00875 }
00876 if (hashcount) {
00877 fprintf (qh ferr, "qhull internal error (qh_matchnewfacets): %d neighbors did not match up\n",
00878 hashcount);
00879 qh_printhashtable (qh ferr);
00880 qh_errexit (qh_ERRqhull, NULL, NULL);
00881 }
00882 #ifndef qh_NOtrace
00883 if (qh IStracing >= 2) {
00884 FOREACHfacet_i_(qh hash_table) {
00885 if (!facet)
00886 numfree++;
00887 }
00888 fprintf (qh ferr, "qh_matchnewfacets: %d new facets, %d unused hash entries . hashsize %d\n",
00889 numnew, numfree, qh_setsize (qh hash_table));
00890 }
00891 #endif
00892 qh_setfree (&qh hash_table);
00893 if (qh PREmerge || qh MERGEexact) {
00894 if (qh IStracing >= 4)
00895 qh_printfacetlist (qh newfacet_list, NULL, qh_ALL);
00896 FORALLnew_facets {
00897 if (newfacet->normal)
00898 qh_checkflipped (newfacet, NULL, qh_ALL);
00899 }
00900 }else if (qh FORCEoutput)
00901 qh_checkflipped_all (qh newfacet_list);
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 boolT qh_matchvertices (int firstindex, setT *verticesA, int skipA,
00926 setT *verticesB, int *skipB, boolT *same) {
00927 vertexT **elemAp, **elemBp, **skipBp=NULL, **skipAp;
00928
00929 elemAp= SETelemaddr_(verticesA, firstindex, vertexT);
00930 elemBp= SETelemaddr_(verticesB, firstindex, vertexT);
00931 skipAp= SETelemaddr_(verticesA, skipA, vertexT);
00932 do if (elemAp != skipAp) {
00933 while (*elemAp != *elemBp++) {
00934 if (skipBp)
00935 return False;
00936 skipBp= elemBp;
00937 }
00938 }while(*(++elemAp));
00939 if (!skipBp)
00940 skipBp= ++elemBp;
00941 *skipB= SETindex_(verticesB, skipB);
00942 *same= !(((ptr_intT)skipA & 0x1) ^ ((ptr_intT)*skipB & 0x1));
00943 trace4((qh ferr, "qh_matchvertices: matched by skip %d (v%d) and skip %d (v%d) same? %d\n",
00944 skipA, (*skipAp)->id, *skipB, (*(skipBp-1))->id, *same));
00945 return (True);
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 facetT *qh_newfacet(void) {
00959 facetT *facet;
00960 void **freelistp;
00961
00962 qh_memalloc_(sizeof(facetT), freelistp, facet, facetT);
00963 memset ((char *)facet, 0, sizeof(facetT));
00964 if (qh facet_id == qh tracefacet_id)
00965 qh tracefacet= facet;
00966 facet->id= qh facet_id++;
00967 facet->neighbors= qh_setnew(qh hull_dim);
00968 #if !qh_COMPUTEfurthest
00969 facet->furthestdist= 0.0;
00970 #endif
00971 #if qh_MAXoutside
00972 if (qh FORCEoutput && qh APPROXhull)
00973 facet->maxoutside= qh MINoutside;
00974 else
00975 facet->maxoutside= qh DISTround;
00976 #endif
00977 facet->simplicial= True;
00978 facet->good= True;
00979 facet->newfacet= True;
00980 trace4((qh ferr, "qh_newfacet: created facet f%d\n", facet->id));
00981 return (facet);
00982 }
00983
00984
00985
00986
00987
00988
00989
00990
00991 ridgeT *qh_newridge(void) {
00992 ridgeT *ridge;
00993 void **freelistp;
00994
00995 qh_memalloc_(sizeof(ridgeT), freelistp, ridge, ridgeT);
00996 memset ((char *)ridge, 0, sizeof(ridgeT));
00997 zinc_(Ztotridges);
00998 if (qh ridge_id == 0xFFFFFF) {
00999 fprintf(qh ferr, "\
01000 qhull warning: more than %d ridges. Id field overflows and two ridges\n\
01001 may have the same identifier. Otherwise output ok.\n", 0xFFFFFF);
01002 }
01003 ridge->id= qh ridge_id++;
01004 trace4((qh ferr, "qh_newridge: created ridge r%d\n", ridge->id));
01005 return (ridge);
01006 }
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024 int qh_pointid (pointT *point) {
01025 long offset, id;
01026
01027 if (!point)
01028 id= -3;
01029 else if (point == qh interior_point)
01030 id= -2;
01031 else if (point >= qh first_point
01032 && point < qh first_point + qh num_points * qh hull_dim) {
01033 offset= point - qh first_point;
01034 id= offset / qh hull_dim;
01035 }else if ((id= qh_setindex (qh other_points, point)) != -1)
01036 id += qh num_points;
01037 else
01038 id= -1;
01039 return (int) id;
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 void qh_removefacet(facetT *facet) {
01053 facetT *next= facet->next, *previous= facet->previous;
01054
01055 if (facet == qh newfacet_list)
01056 qh newfacet_list= next;
01057 if (facet == qh facet_next)
01058 qh facet_next= next;
01059 if (facet == qh visible_list)
01060 qh visible_list= next;
01061 if (previous) {
01062 previous->next= next;
01063 next->previous= previous;
01064 }else {
01065 qh facet_list= next;
01066 qh facet_list->previous= NULL;
01067 }
01068 qh num_facets--;
01069 trace4((qh ferr, "qh_removefacet: remove f%d from facet_list\n", facet->id));
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 void qh_removevertex(vertexT *vertex) {
01084 vertexT *next= vertex->next, *previous= vertex->previous;
01085
01086 if (vertex == qh newvertex_list)
01087 qh newvertex_list= next;
01088 if (previous) {
01089 previous->next= next;
01090 next->previous= previous;
01091 }else {
01092 qh vertex_list= vertex->next;
01093 qh vertex_list->previous= NULL;
01094 }
01095 qh num_vertices--;
01096 trace4((qh ferr, "qh_removevertex: remove v%d from vertex_list\n", vertex->id));
01097 }
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119 void qh_updatevertices (void) {
01120 facetT *newfacet= NULL, *neighbor, **neighborp, *visible;
01121 vertexT *vertex, **vertexp;
01122
01123 trace3((qh ferr, "qh_updatevertices: delete interior vertices and update vertex->neighbors\n"));
01124 if (qh VERTEXneighbors) {
01125 FORALLvertex_(qh newvertex_list) {
01126 FOREACHneighbor_(vertex) {
01127 if (neighbor->visible)
01128 SETref_(neighbor)= NULL;
01129 }
01130 qh_setcompact (vertex->neighbors);
01131 }
01132 FORALLnew_facets {
01133 FOREACHvertex_(newfacet->vertices)
01134 qh_setappend (&vertex->neighbors, newfacet);
01135 }
01136 FORALLvisible_facets {
01137 FOREACHvertex_(visible->vertices) {
01138 if (!vertex->newlist && !vertex->deleted) {
01139 FOREACHneighbor_(vertex) {
01140 if (!neighbor->visible)
01141 break;
01142 }
01143 if (neighbor)
01144 qh_setdel (vertex->neighbors, visible);
01145 else {
01146 vertex->deleted= True;
01147 qh_setappend (&qh del_vertices, vertex);
01148 trace2((qh ferr, "qh_updatevertices: delete vertex p%d (v%d) in f%d\n",
01149 qh_pointid(vertex->point), vertex->id, visible->id));
01150 }
01151 }
01152 }
01153 }
01154 }else {
01155 FORALLvisible_facets {
01156 FOREACHvertex_(visible->vertices) {
01157 if (!vertex->newlist && !vertex->deleted) {
01158 vertex->deleted= True;
01159 qh_setappend (&qh del_vertices, vertex);
01160 trace2((qh ferr, "qh_updatevertices: delete vertex p%d (v%d) in f%d\n",
01161 qh_pointid(vertex->point), vertex->id, visible->id));
01162 }
01163 }
01164 }
01165 }
01166 }
01167
01168
01169