bool IndexedTriangle::Equal(const IndexedTriangle& tri) const { // Test all vertex references return (HasVertex(tri.mVRef[0]) && HasVertex(tri.mVRef[1]) && HasVertex(tri.mVRef[2])); }
void FindPoleAntipole(int vsize, double* modelCenter) { tVertex cite; tList voronoiVertices = NULL; tVertex vorv = NULL; double vorDistance = 0.0; double maxDistance = 0.5; double minProduct = 1e+16; double minDistance = 0.5; tVertex pole = NULL; tVertex antipole = NULL; tVertex normal = NULL; vertexT* vertex = NULL; double dist = 0.0; facetT *neighbor, **neighborp; setT* neigborcites = NULL; vertexT* ncite[4]; int id = 0; int i = 0; double cv[3] = { 0.0, 0.0, 0.0 }; double oc[3] = { 0.0, 0.0, 0.0 }; double ab[3] = { 0.0, 0.0, 0.0 }; double ac[3] = { 0.0, 0.0, 0.0 }; double faceNormal[3] = { 0.0, 0.0, 0.0 }; NEW(normal, tsVertex); //loop through the valid cites, compute a pole and an antipole cite = vertices; do { voronoiVertices = cite->vvlist; //if there is no voronoi verticies, skip the cites. if (voronoiVertices == NULL) { cite = cite->next; continue; } //obtain neighbor facets. In case of bounded cell, this list is empty. vertex = (vertexT*)(voronoiVertices->p); voronoiVertices = voronoiVertices->next; //***** if voronoi cell is unbounded, find an average normal of adjacent triangles *****// if (vertex != NULL) { normal->v[0] = 0.0; normal->v[1] = 0.0; normal->v[2] = 0.0; FOREACHneighbor_(vertex) { neigborcites = neighbor->vertices; for (i = 0; i < 4; i++) { ncite[i] = (vertexT*)neigborcites->e[i].p; } //compute the vector from origin to cite oc[0] = vertex->point[0] - modelCenter[0]; oc[1] = vertex->point[1] - modelCenter[1]; oc[2] = vertex->point[2] - modelCenter[2]; //compute the outer normal of adjacent triangle with cite for (i = 0; i < 4; i++) { if (ncite[i % 4]->seen2 && ncite[(i + 1) % 4]->seen2 && ncite[(i + 2) % 4]->seen2) { ab[0] = ncite[(i + 1) % 4]->point[0] - ncite[i % 4]->point[0]; ab[1] = ncite[(i + 1) % 4]->point[1] - ncite[i % 4]->point[1]; ab[2] = ncite[(i + 1) % 4]->point[2] - ncite[i % 4]->point[2]; ac[0] = ncite[(i + 2) % 4]->point[0] - ncite[i % 4]->point[0]; ac[1] = ncite[(i + 2) % 4]->point[1] - ncite[i % 4]->point[1]; ac[2] = ncite[(i + 2) % 4]->point[2] - ncite[i % 4]->point[2]; qh_crossproduct(3, ab, ac, faceNormal); if (InnerProduct(oc, faceNormal) > ZERO) { normal->v[0] -= faceNormal[0]; normal->v[1] -= faceNormal[1]; normal->v[2] -= faceNormal[2]; } else{ normal->v[0] += faceNormal[0]; normal->v[1] += faceNormal[1]; normal->v[2] += faceNormal[2]; } } } } dist = sqrt(normal->v[0] * normal->v[0] + normal->v[1] * normal->v[1] + normal->v[2] * normal->v[2]); normal->v[0] /= dist; normal->v[1] /= dist; normal->v[2] /= dist; } else //***** if voronoi cell is bounded, find a pole and a normal *****// { normal->v[0] = 0.0; normal->v[1] = 0.0; normal->v[2] = 0.0; vorDistance = 0.0; do{ //compute the distance between a voronoi cite and a voronoi vertex vorv = (tVertex)(voronoiVertices->p); vorDistance = qh_pointdist(vorv->v, cite->v, 3); //If current voronoi vertex is farther than other candidates, store it as current and best candidates for pole if (vorDistance > maxDistance) { pole = vorv; maxDistance = vorDistance; } voronoiVertices = voronoiVertices->next; } while (voronoiVertices != cite->vvlist); //Test if pole is too far away from the model if (maxDistance > POLE_MAX_THRESHOLD) pole = NULL; else{ //compute normal vector cp (c:voronoi cite, p:pole) pole->ispole = true; normal->v[0] = pole->v[0] - cite->v[0]; normal->v[1] = pole->v[1] - cite->v[1]; normal->v[2] = pole->v[2] - cite->v[2]; dist = sqrt(normal->v[0] * normal->v[0] + normal->v[1] * normal->v[1] + normal->v[2] * normal->v[2]); normal->v[0] /= dist; normal->v[1] /= dist; normal->v[2] /= dist; } } //***** find a antipole *****// voronoiVertices = cite->vvlist; voronoiVertices = voronoiVertices->next; //skip bounded/unbounded information do{ vorv = (tVertex)(voronoiVertices->p); //if a pole exists and this voronoi vertex is a pole, skip the loop if (pole != NULL && SQR(vorv->v[0] - pole->v[0]) + SQR(vorv->v[1] - pole->v[1]) + SQR(vorv->v[2] - pole->v[2]) < ZERO) { voronoiVertices = voronoiVertices->next; continue; } //inner product normal with vector cv (c:voronoi cite, v:candidate antipole) cv[0] = vorv->v[0] - cite->v[0]; cv[1] = vorv->v[1] - cite->v[1]; cv[2] = vorv->v[2] - cite->v[2]; vorDistance = InnerProduct(cv, normal->v); if (vorDistance < minProduct) { antipole = vorv; minProduct = vorDistance; minDistance = qh_pointdist(vorv->v, cite->v, 3); } voronoiVertices = voronoiVertices->next; } while (voronoiVertices != cite->vvlist); if (antipole != NULL) { if (minDistance > POLE_MAX_THRESHOLD) antipole = NULL; else antipole->ispole = true; } //***** add a pole and an antipole to point set *****// if (pole != NULL && !HasVertex(pole)) { pole->vnum = vsize + id; id++; ADD(vertices, pole); } if (antipole != NULL && !HasVertex(antipole)) { antipole->vnum = vsize + id; id++; ADD(vertices, antipole); } pole = NULL; antipole = NULL; maxDistance = 0.5; minProduct = 1e+16; minDistance = 0.5; cite = cite->next; } while (cite != vertices);