| 183 | } |
| 184 | |
| 185 | void IsotropicPeriodicInflator::reflect() { |
| 186 | const Float tol = get_distance_threshold(); |
| 187 | typedef std::function<bool(const VectorF&)> IndicatorFunc; |
| 188 | std::vector<IndicatorFunc> min_bd_indicators; |
| 189 | min_bd_indicators.push_back([=](const VectorF& v) |
| 190 | { return fabs(v[0] - m_octa_cell_bbox_min[0]) < tol; }); |
| 191 | min_bd_indicators.push_back([=](const VectorF& v) |
| 192 | { return fabs(v[1] - m_octa_cell_bbox_min[1]) < tol; }); |
| 193 | min_bd_indicators.push_back([=](const VectorF& v) |
| 194 | { return fabs(v[2] - m_octa_cell_bbox_min[2]) < tol; }); |
| 195 | |
| 196 | for (auto f : min_bd_indicators) { |
| 197 | SubMesh::Ptr submesh = SubMesh::create_raw(m_vertices, m_faces); |
| 198 | submesh->filter_vertex_with_custom_function(f); |
| 199 | submesh->finalize(); |
| 200 | m_vertices = submesh->get_unselected_vertices(); |
| 201 | m_faces = submesh->get_unselected_faces(); |
| 202 | } |
| 203 | |
| 204 | for (size_t i=0; i<3; i++) { |
| 205 | size_t num_vertices = m_vertices.rows(); |
| 206 | MatrixFr r_vts = m_vertices; |
| 207 | for (size_t j=0; j<num_vertices; j++) { |
| 208 | r_vts(j, i) = -r_vts(j, i) + 2 * m_octa_cell_bbox_min[i]; |
| 209 | } |
| 210 | |
| 211 | MatrixIr r_faces = m_faces.array() + num_vertices; |
| 212 | r_faces.col(0).swap(r_faces.col(1)); |
| 213 | |
| 214 | m_vertices = MatrixUtils::vstack<MatrixFr>({m_vertices, r_vts}); |
| 215 | m_faces = MatrixUtils::vstack<MatrixIr>({m_faces, r_faces}); |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | void IsotropicPeriodicInflator::merge_boundary() { |
| 220 | auto bd = Boundary::extract_surface_boundary_raw(m_vertices, m_faces); |
nothing calls this directly
no test coverage detected