| 200 | } |
| 201 | |
| 202 | size_t MeshChecker::get_num_duplicated_faces() const { |
| 203 | const size_t num_faces = m_faces.rows(); |
| 204 | auto hash_fn = [](const VectorI& key) -> size_t { |
| 205 | const size_t size = key.size(); |
| 206 | size_t hash = 0; |
| 207 | for (size_t i=0; i<size; i++) |
| 208 | hash += std::hash<int>()(key[i]); |
| 209 | return hash; |
| 210 | }; |
| 211 | typedef std::unordered_map<VectorI, size_t, decltype(hash_fn)> FaceMap; |
| 212 | FaceMap face_counts( num_faces, hash_fn); |
| 213 | |
| 214 | for (size_t i=0; i<num_faces; i++) { |
| 215 | const auto& f = m_faces.row(i); |
| 216 | Vector3I key(f.minCoeff(), f.maxCoeff(), f.sum()); |
| 217 | auto itr = face_counts.find(key); |
| 218 | if (itr == face_counts.end()) { |
| 219 | face_counts.insert(itr, std::make_pair(key, 1)); |
| 220 | } else { |
| 221 | itr->second ++; |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | return std::count_if(face_counts.begin(), face_counts.end(), |
| 226 | [](FaceMap::value_type& p) { |
| 227 | return p.second != 1; }); |
| 228 | } |
| 229 | |
| 230 | Float MeshChecker::compute_signed_volume_from_surface() const { |
| 231 | const size_t num_faces = m_faces.rows(); |