| 10 | using namespace PyMesh; |
| 11 | |
| 12 | void VertexSnapper::snap_vertices_to_border( |
| 13 | MatrixFr& vertices, MatrixIr& faces, |
| 14 | const VectorF& bbox_min, const VectorF& bbox_max, Float tol) { |
| 15 | const size_t num_faces = faces.rows(); |
| 16 | const size_t vertex_per_face = faces.cols(); |
| 17 | Float sq_tol = tol * tol; |
| 18 | |
| 19 | BoxChecker bbox_checker(bbox_min, bbox_max); |
| 20 | |
| 21 | for (size_t i=0; i<num_faces; i++) { |
| 22 | const VectorI& f = faces.row(i); |
| 23 | for (size_t j=0; j<vertex_per_face; j++) { |
| 24 | size_t v0_idx = f[j]; |
| 25 | size_t v1_idx = f[(j+1)%vertex_per_face]; |
| 26 | |
| 27 | const VectorF& v0 = vertices.row(v0_idx); |
| 28 | const VectorF& v1 = vertices.row(v1_idx); |
| 29 | Float sq_len = (v1 - v0).squaredNorm(); |
| 30 | if (sq_len < sq_tol) { |
| 31 | if ( bbox_checker.is_on_boundary(v0) && |
| 32 | !bbox_checker.is_on_boundary(v1)) { |
| 33 | vertices.row(v1_idx) = v0.transpose(); |
| 34 | } else if ( bbox_checker.is_on_boundary(v1) && |
| 35 | !bbox_checker.is_on_boundary(v0)) { |
| 36 | vertices.row(v0_idx) = v1.transpose(); |
| 37 | } |
| 38 | } |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | bool updated = true; |
| 43 | |
| 44 | while (updated) { |
| 45 | ObtuseTriangleRemoval slim_tri_remover(vertices, faces); |
| 46 | size_t num_slim_tri_removed = slim_tri_remover.run(M_PI * 0.99); |
| 47 | |
| 48 | ShortEdgeRemoval edge_remover( |
| 49 | slim_tri_remover.get_vertices(), |
| 50 | slim_tri_remover.get_faces()); |
| 51 | edge_remover.run(1e-12); |
| 52 | |
| 53 | vertices = edge_remover.get_vertices(); |
| 54 | faces = edge_remover.get_faces(); |
| 55 | |
| 56 | updated = (num_slim_tri_removed > 0); |
| 57 | } |
| 58 | } |
| 59 |
nothing calls this directly
no test coverage detected