$search
00001 /* 00002 Szymon Rusinkiewicz 00003 Stanford Graphics Lab 00004 00005 trimesh_remove.cc 00006 Removing sets of vertices or faces from trimeshes. 00007 */ 00008 00009 #include <stdio.h> 00010 #include "triutil.h" 00011 #include "trimesh.h" 00012 #include <vector> 00013 using std::vector; 00014 00015 namespace trimesh { 00016 00017 // Remove the indicated vertices from the TriMesh. 00018 // 00019 // Faces are renumbered to reflect the new numbering of vertices, and any 00020 // faces that included a vertex to be removed will also be removed. 00021 // 00022 // Any per-vertex properties are renumbered along with the vertices. 00023 // Any triangle strips, neighbor lists, or adjacency lists are deleted. 00024 // Note that memory for vertices and properties is not reallocated. 00025 void TriMesh::RemoveVertices(const vector<bool> &toremove) 00026 { 00027 // Build a table that tells how the vertices will be remapped 00028 if (!numvertices) 00029 return; 00030 printf("Removing vertices... "); fflush(stdout); 00031 vector<int> remap_table(numvertices); 00032 int next=0; 00033 for (int i=0; i < numvertices; i++) { 00034 if (toremove[i]) 00035 remap_table[i] = -1; 00036 else 00037 remap_table[i] = next++; 00038 } 00039 00040 // Nothing to delete? 00041 if (next == numvertices) { 00042 printf("None removed.\n"); 00043 return; 00044 } 00045 00046 // Remap the vertices and per-vertex properties 00047 for (int i=0; i < numvertices; i++) { 00048 if (remap_table[i] == -1) continue; 00049 vertices[remap_table[i]][0] = vertices[i][0]; 00050 vertices[remap_table[i]][1] = vertices[i][1]; 00051 vertices[remap_table[i]][2] = vertices[i][2]; 00052 if (normals) { 00053 normals[remap_table[i]][0] = normals[i][0]; 00054 normals[remap_table[i]][1] = normals[i][1]; 00055 normals[remap_table[i]][2] = normals[i][2]; 00056 } 00057 if (colors) { 00058 colors[remap_table[i]][0] = colors[i][0]; 00059 colors[remap_table[i]][1] = colors[i][1]; 00060 colors[remap_table[i]][2] = colors[i][2]; 00061 } 00062 if (confidences) 00063 confidences[remap_table[i]] = confidences[i]; 00064 } 00065 printf("%d vertices removed... Done.\n", numvertices - next); 00066 numvertices = next; 00067 00068 // Nuke neighbor and adjacency lists 00069 free_adjacentfaces(); 00070 free_neighbors(); 00071 00072 // Renumber faces 00073 need_faces(); 00074 free_tstrips(); 00075 int nextface=0; 00076 for (int i=0; i < numfaces; i++) { 00077 int n0 = (faces[nextface][0] = remap_table[faces[i][0]]); 00078 int n1 = (faces[nextface][1] = remap_table[faces[i][1]]); 00079 int n2 = (faces[nextface][2] = remap_table[faces[i][2]]); 00080 if ((n0 != -1) && (n1 != -1) && (n2 != -1)) 00081 nextface++; 00082 } 00083 numfaces = nextface; 00084 } 00085 00086 00087 // Remove vertices that aren't referenced by any face 00088 void TriMesh::RemoveUnusedVertices() 00089 { 00090 if (!numvertices) 00091 return; 00092 need_faces(); 00093 vector<bool> unused(numvertices, true); 00094 for (int i=0; i < numfaces; i++) 00095 unused[faces[i][0]] = unused[faces[i][1]] = 00096 unused[faces[i][2]] = false; 00097 RemoveVertices(unused); 00098 } 00099 00100 00101 // Remove faces as indicated by toremove. Should probably be 00102 // followed by a call to RemoveUnusedVertices() 00103 void TriMesh::RemoveFaces(const vector<bool> &toremove) 00104 { 00105 need_faces(); 00106 free_tstrips(); 00107 if (!numfaces) 00108 return; 00109 printf("Removing faces... "); fflush(stdout); 00110 00111 int next=0; 00112 for (int i=0; i < numfaces; i++) { 00113 if (toremove[i]) 00114 continue; 00115 faces[next][0] = faces[i][0]; 00116 faces[next][1] = faces[i][1]; 00117 faces[next][2] = faces[i][2]; 00118 next++; 00119 } 00120 if (next == numfaces) { 00121 printf("None removed.\n"); 00122 return; 00123 } 00124 00125 printf("%d faces removed... Done.\n", numfaces - next); 00126 numfaces = next; 00127 } 00128 00129 } // namespace trimesh