| 12 | import os.path |
| 13 | |
| 14 | def carve_mesh(target_mesh, block, N, batch_size, out_name, |
| 15 | initial_N=0, save_intermediate=True, debug=False): |
| 16 | name, ext = os.path.splitext(out_name); |
| 17 | tree = pymesh.AABBTree(); |
| 18 | tree.load_mesh(target_mesh); |
| 19 | |
| 20 | dodecahedron = pymesh.generate_dodecahedron(1.0, np.zeros(3)); |
| 21 | vertices = dodecahedron.vertices; |
| 22 | faces = dodecahedron.faces; |
| 23 | |
| 24 | for i in range(initial_N, N, batch_size): |
| 25 | pts = block.vertices; |
| 26 | squared_dist, face_indices, closest_pts = \ |
| 27 | tree.look_up_with_closest_points(pts); |
| 28 | n = np.min([batch_size, N-i, len(pts)]); |
| 29 | indices = np.argsort(squared_dist)[::-1][:n]; |
| 30 | radii = np.sqrt(squared_dist[indices]); |
| 31 | centers = pts[indices, :]; |
| 32 | to_remove = [pymesh.form_mesh( |
| 33 | np.dot(pymesh.Quaternion(numpy.random.rand(4)).to_matrix(), vertices.T * r).T + p, faces) |
| 34 | for r,p in zip(radii, centers)]; |
| 35 | to_remove = pymesh.merge_meshes(to_remove); |
| 36 | if debug: |
| 37 | pymesh.save_mesh("deubg_block.msh", block); |
| 38 | pymesh.save_mesh("deubg_cut.msh", to_remove); |
| 39 | block = pymesh.boolean(block, to_remove, "difference", engine="igl"); |
| 40 | block, __ = pymesh.collapse_short_edges(block, 1e-12, False); |
| 41 | if save_intermediate: |
| 42 | pymesh.save_mesh("{}_{:06}{}".format(name, i, ext), block); |
| 43 | return block; |
| 44 | |
| 45 | def parse_args(): |
| 46 | parser = argparse.ArgumentParser(description=__doc__); |