| 45 | } |
| 46 | |
| 47 | void BoundaryFaces::extract_boundary(const Mesh& mesh) { |
| 48 | typedef TripletMap<size_t> FaceVoxelMap; |
| 49 | FaceVoxelMap face_voxel_map; |
| 50 | |
| 51 | const size_t num_vertex_per_voxel = mesh.get_vertex_per_voxel(); |
| 52 | const size_t num_voxels = mesh.get_num_voxels(); |
| 53 | |
| 54 | if (num_voxels == 0) { |
| 55 | throw RuntimeError("Mesh has zero voxels!"); |
| 56 | } |
| 57 | if (num_vertex_per_voxel != 4) { |
| 58 | throw NotImplementedError("Only tet mesh is supported"); |
| 59 | } |
| 60 | |
| 61 | for (size_t i=0; i<num_voxels; i++) { |
| 62 | VectorI voxel = mesh.get_voxel(i); |
| 63 | Triplet voxel_faces[4] = { |
| 64 | {voxel[0], voxel[2], voxel[1]}, |
| 65 | {voxel[0], voxel[1], voxel[3]}, |
| 66 | {voxel[0], voxel[3], voxel[2]}, |
| 67 | {voxel[1], voxel[2], voxel[3]} |
| 68 | }; |
| 69 | face_voxel_map.insert(voxel_faces[0], i); |
| 70 | face_voxel_map.insert(voxel_faces[1], i); |
| 71 | face_voxel_map.insert(voxel_faces[2], i); |
| 72 | face_voxel_map.insert(voxel_faces[3], i); |
| 73 | } |
| 74 | |
| 75 | std::vector<size_t> boundaries; |
| 76 | std::vector<size_t> boundary_voxels; |
| 77 | for (FaceVoxelMap::const_iterator itr = face_voxel_map.begin(); |
| 78 | itr != face_voxel_map.end(); itr++) { |
| 79 | if (itr->second.size() == 1) { |
| 80 | boundaries.insert(boundaries.end(), |
| 81 | itr->first.get_ori_data().data(), |
| 82 | itr->first.get_ori_data().data()+3); |
| 83 | boundary_voxels.push_back(itr->second[0]); |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | m_boundaries.resize(boundaries.size() / 3, 3); |
| 88 | std::copy(boundaries.begin(), boundaries.end(), m_boundaries.data()); |
| 89 | m_boundary_voxels.resize(boundary_voxels.size()); |
| 90 | std::copy(boundary_voxels.begin(), boundary_voxels.end(), |
| 91 | m_boundary_voxels.data()); |
| 92 | } |
| 93 | |
| 94 | void BoundaryFaces::extract_boundary_nodes() { |
| 95 | size_t num_entries = m_boundaries.rows() * m_boundaries.cols(); |
nothing calls this directly
no test coverage detected