def test_boolean1(self): if platform.system() == "Windows": return root_folder = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "3rdparty", "data") csg_tree = { "operation": "difference", "left": { "operation": "intersection", "left": os.path.join(root_folder, "csg_input", "box.stl"), "right": os.path.join(root_folder, "csg_input", "ball.stl") }, "right": { "operation": "union", "left": os.path.join(root_folder, "csg_input", "x.stl"), "right": { "operation": "union", "left": os.path.join(root_folder, "csg_input", "y.stl"), "right": os.path.join(root_folder, "csg_input", "z.stl") } } } tetra = wm.Tetrahedralizer(stop_quality=1000) tetra.load_csg_tree(json.dumps(csg_tree)) tetra.tetrahedralize() VT, TT = tetra.get_tet_mesh()
def test_sizing_field(self): cubeV = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], dtype=np.float64) cubeF = np.array( [[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [1, 2, 6], [1, 6, 5], [0, 4, 7], [0, 7, 3], [0, 1, 5], [0, 5, 4], [2, 3, 7], [2, 7, 6]], dtype=np.int32) v = np.array([[-0.1, -0.1, -0.1], [1.1, -0.1, -0.1], [-0.1, 1.1, -0.1], [1.1, 1.1, -0.1], [-0.1, -0.1, 1.1], [1.1, -0.1, 1.1], [-0.1, 1.1, 1.1], [1.1, 1.1, 1.1]], dtype=np.float64) t = np.array([[5, 0, 3, 1], [5, 6, 0, 4], [5, 3, 6, 7], [0, 6, 3, 2], [5, 0, 6, 3]], dtype=np.int32) a = np.array([[0.1], [0.1], [0.1], [0.1], [0.1], [0.1], [0.1], [0.1]], dtype=np.float64) tetra = wm.Tetrahedralizer() tetra.set_mesh(cubeV, cubeF) tetra.set_sizing_field(v, t, a) tetra.tetrahedralize() VT, TT, _ = tetra.get_tet_mesh()
def test_data(self): root_folder = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "3rdparty", "data") V = np.load(os.path.join(root_folder, "V.npy")) F = np.load(os.path.join(root_folder, "F.npy")) tetra = wm.Tetrahedralizer(stop_quality=1000) tetra.set_mesh(V, F) tetra.tetrahedralize() VT, TT = tetra.get_tet_mesh()
def test_tet(self): cubeV = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], dtype=np.float64) cubeF = np.array( [[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [1, 2, 6], [1, 6, 5], [0, 4, 7], [0, 7, 3], [0, 1, 5], [0, 5, 4], [2, 3, 7], [2, 7, 6]], dtype=np.int32) tetra = wm.Tetrahedralizer() tetra.set_mesh(cubeV, cubeF) tetra.tetrahedralize() VT, TT, _ = tetra.get_tet_mesh()
def tetrahedralize(): parser = argparse.ArgumentParser() parser.add_argument("-i", "--input", type=str, help="Input surface mesh INPUT in .off/.obj/.stl/.ply format. (string, required)") parser.add_argument("-o", "--output", type=str, help="Output tetmesh OUTPUT in .msh format. (string, optional, default: input_file+postfix+'.msh')") parser.add_argument("-l", "--lr", type=float, default=0.05, help="ideal_edge_length = diag_of_bbox * L. (double, optional, default: 0.05)") parser.add_argument("-e", "--epsr", type=float, default=1e-3, help="epsilon = diag_of_bbox * EPS. (double, optional, default: 1e-3)") parser.add_argument("--stop-energy", type=float, default=10, help="Stop optimization when max energy is lower than this.") parser.add_argument("--level", type=int, default=2, help="Log level (0 = most verbose, 6 = off).") parser.add_argument("--skip-simplify", type=bool, default=False, help="skip preprocessing.") parser.add_argument("--no-binary", type=bool, default=False, help="export meshes as ascii") parser.add_argument("--smooth-open-boundary", type=bool, default=False, help="Smooth the open boundary.") parser.add_argument("--manifold-surface", type=bool, default=False, help="Force the output to be manifold.") parser.add_argument("--coarsen", type=bool, default=True, help="Coarsen the output as much as possible.") parser.add_argument("--csg", type=str, default="", help="json file containg a csg tree") parser.add_argument("--disable-filtering", type=bool, default=False, help="Disable filtering out outside elements.") parser.add_argument("--use-floodfill", type=bool, default=False, help="Use flood-fill to extract interior volume.") parser.add_argument("--use-input-for-wn", type=bool, default=False, help="Use input surface for winding number.") parser.add_argument("--bg-mesh", type=str, default="", help="Background mesh for sizing field (.msh file).") parser.add_argument("--epsr-tags", type=str, default="", help="List of envelope size for each input faces.") args = parser.parse_args() tetra = wm.Tetrahedralizer(stop_quality=args.stop_energy, epsilon=args.epsr, edge_length_r=args.lr, skip_simplify=args.skip_simplify, coarsen=args.coarsen) tetra.set_log_level(args.level) if(len(args.bg_mesh) > 0): tetra.load_sizing_field(args.bg_mesh) if len(args.csg) > 0: with open(args.csg, "r") as f: data = json.load(f) tetra.load_csg_tree(data) else: tetra.load_mesh(args.input) tetra.tetrahedralize() tetra.save(args.output, all_mesh=args.disable_filtering, smooth_open_boundary=args.smooth_open_boundary, floodfill=args.use_floodfill, use_input_for_wn=args.use_input_for_wn, manifold_surface=args.manifold_surface, binary=not args.no_binary)