void ExtremalQuery3BSP<Real>::CreateSphericalBisectors (BasicMesh& mesh, std::multiset<SphericalArc>& arcs) { // For each vertex, sort the normals into a counterclockwise spherical // polygon when viewed from outside the sphere. SortVertexAdjacents(mesh); int numVertices = mesh.GetNumVertices(); const BasicMesh::Vertex* vertices = mesh.GetVertices(); std::queue<std::pair<int,int> > queue; for (int i = 0; i < numVertices; ++i) { const BasicMesh::Vertex& vertex = vertices[i]; queue.push(std::make_pair(0, vertex.NumTriangles)); while (!queue.empty()) { std::pair<int,int> arc = queue.front(); queue.pop(); int i0 = arc.first, i1 = arc.second; int separation = i1 - i0; if (separation > 1 && separation != vertex.NumTriangles - 1) { if (i1 < vertex.NumTriangles) { SphericalArc arc; arc.NIndex[0] = vertex.T[i0]; arc.NIndex[1] = vertex.T[i1]; arc.Separation = separation; arc.Normal = mFaceNormals[arc.NIndex[0]].Cross( mFaceNormals[arc.NIndex[1]]); arc.PosVertex = i; arc.NegVertex = i; arcs.insert(arc); } int iMid = (i0 + i1 + 1)/2; if (iMid != i1) { queue.push(std::make_pair(i0, iMid)); queue.push(std::make_pair(iMid, i1)); } } } } }
void ExtremalQuery3BSP<Real>::SortVertexAdjacents (BasicMesh& mesh) { // The typecast is to allow modifying the vertices. As long as the // sorting algorithm is correct, this is a safe thing to do. int numVertices = mesh.GetNumVertices(); BasicMesh::Vertex* vertices = (BasicMesh::Vertex*)mesh.GetVertices(); const BasicMesh::Triangle* triangles = mesh.GetTriangles(); for (int i = 0; i < numVertices; ++i) { // This copy circumvents the constness of the mesh vertices, which // allows the sorting of the mesh triangles shared by a mesh vertex. BasicMesh::Vertex& vertex = vertices[i]; // This is a consequence of the mesh being a polyhedron. assertion(vertex.NumVertices == vertex.NumTriangles, "Unexpected condition\n"); // Once we have the first vertex to sort and an initial triangle // sharing it, we can walk around the vertex following triangle // adjacency links. It is safe to overwrite the vertex data. int t = vertex.T[0]; const BasicMesh::Triangle* tri = &triangles[t]; for (int adj = 0; adj < vertex.NumVertices; ++adj) { int prev, curr; for (prev = 2, curr = 0; curr < 3; prev = curr++) { if (tri->V[curr] == i) { vertex.V[adj] = tri->V[prev]; vertex.E[adj] = tri->E[prev]; vertex.T[adj] = t; // The next triangle to visit. t = tri->T[prev]; tri = &triangles[t]; break; } } assertion(curr < 3, "Unexpected condition\n"); } } }