// SimplerConvexUmbrellaSdfAlgo.cpp: implementation of the SimplerConvexUmbrellaSdfAlgo class. // ////////////////////////////////////////////////////////////////////// #include "SimplerConvexUmbrellaSdfAlgo.h" using namespace SDF; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// SimplerConvexUmbrellaSdfAlgo::SimplerConvexUmbrellaSdfAlgo() { } SimplerConvexUmbrellaSdfAlgo::~SimplerConvexUmbrellaSdfAlgo() { } //-------------------------------- // x - the closest point on the surface // p - the pt to classify // tris - the tris that share that closest pt //-------------------------------- SimplerConvexUmbrellaSdfAlgo::PointClass SimplerConvexUmbrellaSdfAlgo:: classify_pt_by_umbrella_tris(const TriangleList &tris, const Point &x, const Point &p) { // We do this by going through every triangle, and calculating other triangles' // relative positions to it. There are three possible relative positions: // COPLANAR - the two triangles are co-planar // B_BEHIND_A - tri B is behind A - meaning its centroid is behind A's face plane // B_INFRONT_A - ditto. // For any triangle A, if there exists two triangles B1 B2 such that B1 is behind // and B2 is in front, then A must NOT be a face on the convex umbrella. // But if B1 and B2 do not exist, then all other triangles B are either coplanar, // or ALL have relative position p - where p is either BEHIND or INFRONT. // If p is BEHIND, we classify the point as outside. // If p is INFRONT, we classify the point as inside. PointClass klass = DONT_KNOW; for(unsigned int i = 0; i < tris.size(); i++) { MeshTriangle *A = tris.at(i); // Relative position info for A int numBehind = 0; int numInFront = 0; //-------------------------------- // Go through all other tris // and calcualte relative positions //-------------------------------- for(unsigned int j = 0; j < tris.size(); j++ ) { if( j == i ) { continue; } MeshTriangle *B = tris.at(j); // Is this behind? RelativePosition relPos = calc_relative_position_of_umbrella_tris(*A, *B); if(relPos == COPLANAR) { // This doesn't help. // Ignore it. } else if(relPos == B_BEHIND_A) { numBehind++; } else if(relPos == B_INFRONT_A) { numInFront++; } else { // Weird..this shouldn't happen fprintf(stderr, "\n\n *** classify_pt_by_umbrella_tris: WE GOT RELPOS_DONT_KNOW for two tris.. \n\n"); } } //-------------------------------- // Now see - is A a face on the convex umbrella? //-------------------------------- if(numBehind > 0 && numInFront > 0) { // Some were in front, some were behind. // This is definitely NOT on the convex umb // Keep seraching. continue; } else if(numBehind > 0 && numInFront == 0) { // All other tris were coplanar or behind!! // We can classify the point as outside! klass = EXTERIOR; // We're done. break; } else if(numInFront > 0 && numBehind == 0) { // All other tris were coplanar or IN FRONT of A!! // We can classify the point as inside. klass = INTERIOR; // We're done. break; } else { // All the faces are coplanar. // OK, just use any one of them to classify the point. // Let's use A. //-------------------------------- // TODO - We should check that they all agree on the classification! //-------------------------------- klass = this->classify_pt_by_single_best_triangle(*A, this->); // ADDED this line 2005-12-06 break; } } return klass; }