bool IndexedTriangle::Equal(const IndexedTriangle& tri) const
{
	// Test all vertex references
	return (HasVertex(tri.mVRef[0]) && 
			HasVertex(tri.mVRef[1]) &&
			HasVertex(tri.mVRef[2]));
}
Exemple #2
0
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);