def test_simple(self): mesh_1 = generate_box_mesh(np.zeros(3), np.ones(3)); mesh_2 = generate_box_mesh(np.array([0.5, 0.5, 0.5]), np.ones(3)); out_mesh = merge_meshes([mesh_1, mesh_2]); components = separate_mesh(out_mesh); self.assertEqual(2, len(components)); for comp in components: self.assertEqual(8, comp.num_vertices); self.assertEqual(12, comp.num_faces);
def test_2_meshes(self): mesh_1 = generate_box_mesh(np.zeros(3), np.ones(3)); mesh_2 = generate_box_mesh(np.ones(3), np.ones(3)*2, subdiv_order=2); out_mesh = merge_meshes([mesh_1, mesh_2]); self.assertEqual(mesh_1.num_vertices + mesh_2.num_vertices, out_mesh.num_vertices); self.assertEqual(mesh_1.num_faces + mesh_2.num_faces, out_mesh.num_faces); self.assertEqual(mesh_1.num_voxels + mesh_2.num_voxels, out_mesh.num_voxels);
def test_2_meshes(self): mesh_1 = generate_box_mesh(np.zeros(3), np.ones(3)) mesh_2 = generate_box_mesh(np.ones(3), np.ones(3) * 2, subdiv_order=2) out_mesh = merge_meshes([mesh_1, mesh_2]) self.assertEqual(mesh_1.num_vertices + mesh_2.num_vertices, out_mesh.num_vertices) self.assertEqual(mesh_1.num_faces + mesh_2.num_faces, out_mesh.num_faces) self.assertEqual(mesh_1.num_voxels + mesh_2.num_voxels, out_mesh.num_voxels)
def test_map_vertex_attributes_sphere_box(self): """ Map vertex attribute from sphere to box. """ mesh1 = pymesh.generate_icosphere(2.0, [0.0, 0.0, 0.0], 2) mesh2 = pymesh.generate_box_mesh(np.ones(3) - 2, np.ones(3), 10) Z = np.array([0, 0, 1]) theta = np.arctan2( np.dot(mesh1.vertices, Z), numpy.linalg.norm(np.cross(mesh1.vertices, Z), axis=1)) mesh1.add_attribute("theta") mesh1.set_attribute("theta", theta) pymesh.map_vertex_attribute(mesh1, mesh2, "theta") self.assertTrue(mesh2.has_attribute("theta")) ground_truth = np.arctan2( np.dot(mesh2.vertices, Z), numpy.linalg.norm(np.cross(mesh2.vertices, Z), axis=1)) theta2 = mesh2.get_vertex_attribute("theta").ravel() residual = numpy.linalg.norm(ground_truth - theta2)**2 / mesh2.num_vertices self.assertLess(residual, 1e-2)
def save_cube_union(centers, tau, name): meshes = [] for s in centers: box = pymesh.generate_box_mesh(s - tau / 2, s + tau / 2) meshes.append({"mesh": box}) csg = pymesh.CSGTree({"union": meshes}) pymesh.save_mesh("models/{}.obj".format(name), csg.mesh)
def test_tile_with_guide_mesh(self): wire_network = self.get_brick5() params = Parameters(wire_network, 0.5) tiler = Tiler(wire_network) mesh = generate_box_mesh(np.zeros(3), np.ones(3), subdiv_order=1, using_simplex=False) tiler = Tiler(wire_network) tiler.tile_with_guide_mesh(mesh, params) tiled_wire_network = tiler.wire_network self.assertEqual(8 * wire_network.num_edges, tiled_wire_network.num_edges) self.assertEqual(8 * wire_network.num_vertices - 12, tiled_wire_network.num_vertices) self.assert_array_equal(mesh.bbox, tiled_wire_network.bbox) self.assertTrue(tiled_wire_network.has_attribute("thickness")) self.assertTrue(tiled_wire_network.has_attribute("vertex_offset")) self.assert_array_equal( np.ones(tiled_wire_network.num_vertices) * 0.5, tiled_wire_network.get_attribute("thickness").ravel())
def add_box(self, params: np.ndarray, translation: np.ndarray, rotation: np.ndarray): min_point = -params max_point = params box = pymesh.generate_box_mesh(min_point, max_point) box = transform_mesh(box, translation, rotation) self.per_layer_combinations[0].append( CSGEntry(box, OpType.NONE, used=False))
def test_vertex_to_vertex(self): mesh = generate_box_mesh(np.zeros(3), np.ones(3)) mesh.add_attribute("vertex_normal") vertex_normals = mesh.get_vertex_attribute("vertex_normal") vertex_normals2 = convert_to_vertex_attribute(mesh, vertex_normals.ravel()) self.assert_array_equal(vertex_normals.ravel(), vertex_normals2.ravel())
def test_no_degeneracy(self): mesh = generate_box_mesh(np.ones(3)*-1, np.ones(3)); result, info = remove_degenerated_triangles(mesh); self.assertEqual(8, result.num_vertices); self.assertEqual(12, result.num_faces); self.assert_array_equal(np.arange(12), sorted(info["ori_face_indices"]));
def test_no_degeneracy(self): mesh = generate_box_mesh(np.ones(3) * -1, np.ones(3)) result, info = remove_degenerated_triangles(mesh) self.assertEqual(8, result.num_vertices) self.assertEqual(12, result.num_faces) self.assert_array_equal(np.arange(12), sorted(info["ori_face_indices"]))
def test_vertex_to_vertex(self): mesh = generate_box_mesh(np.zeros(3), np.ones(3)); mesh.add_attribute("vertex_normal"); vertex_normals = mesh.get_vertex_attribute("vertex_normal"); vertex_normals2 = convert_to_vertex_attribute( mesh, vertex_normals.ravel()); self.assert_array_equal( vertex_normals.ravel(), vertex_normals2.ravel());
def save_list_cube(centers, tau, name): vertices = [] faces = [] for s in centers: box = pymesh.generate_box_mesh(s - tau / 2, s + tau / 2) ver_s = len(vertices) vertices.extend(box.vertices) faces.extend(box.faces + ver_s) mesh = pymesh.form_mesh(np.array(vertices), np.array(faces)) pymesh.save_mesh("models/{}.obj".format(name), mesh)
def main(): args = parse_args() mesh_1 = pymesh.load_mesh(args.input_mesh_1) mesh_2 = pymesh.load_mesh(args.input_mesh_2) assert (mesh_1.dim == 3) assert (mesh_2.dim == 3) bbox_min_1, bbox_max_1 = mesh_1.bbox bbox_min_2, bbox_max_2 = mesh_2.bbox bbox_min = np.minimum(bbox_min_1, bbox_min_2) bbox_max = np.maximum(bbox_max_1, bbox_max_2) #queries = grid_sample(bbox_min, bbox_max, args.num_samples); queries = random_sample(bbox_min, bbox_max, args.num_samples) winding_number_1 = pymesh.compute_winding_number( mesh_1, queries, engine=args.winding_number_engine) > 0.5 winding_number_2 = pymesh.compute_winding_number( mesh_2, queries, engine=args.winding_number_engine) > 0.5 diff = np.logical_xor(winding_number_1, winding_number_2) num_diff = np.count_nonzero(diff) print("Winding numbers of {} out of {} samples differ".format( num_diff, len(queries))) if args.output is not None: r = np.amax(bbox_max - bbox_min) * 0.01 box = pymesh.generate_box_mesh(np.ones(3) * -r, np.ones(3) * r) vertices = [] faces = [] for i in range(len(queries)): vertices.append(box.vertices + queries[i]) faces.append(box.faces + box.num_vertices * i) vertices = np.vstack(vertices) faces = np.vstack(faces) mesh = pymesh.form_mesh(vertices, faces) mesh.add_attribute("diff") mesh.set_attribute("diff", np.repeat(diff, box.num_faces)) pymesh.save_mesh(args.output, mesh, "diff") if args.export: info = load_info(args.input_mesh_2) info["diff"] = num_diff dump_info(args.input_mesh_2, info) if args.timing: pymesh.timethis.summarize()
def main(): args = parse_args() mesh = pymesh.load_mesh(args.input_mesh) if mesh.vertex_per_face == 4: logging.warning("Converting quad mesh to triangle mesh.") mesh = pymesh.quad_to_tri(mesh) if args.exact: name, ext = os.path.splitext(args.output_mesh) exact_mesh_file = name + ".xml" else: exact_mesh_file = None if mesh.num_vertices == 0 or mesh.num_faces == 0: # Empty input mesh, output empty mesh as well. result = pymesh.form_mesh(np.zeros((0, 3), dtype=float), np.zeros((0, 3), dtype=int)) if args.timing: update_info(args.output_mesh, 0) else: if args.engine == "igl": empty = pymesh.form_mesh(np.zeros((0, 3)), np.zeros((0, 3))) r = pymesh.boolean(mesh, empty, "union", engine=args.engine, with_timing=args.timing, exact_mesh_file=exact_mesh_file) else: # Empty mesh is valid for these libraries, using bbox instead. bbox = mesh.bbox center = (bbox[0] + bbox[1]) * 0.5 box = pymesh.generate_box_mesh(bbox[0] - np.ones(mesh.dim), bbox[1] + np.ones(mesh.dim)) r = pymesh.boolean(mesh, box, "intersection", engine=args.engine, with_timing=args.timing, exact_mesh_file=exact_mesh_file) if args.timing: result, timing = r update_info(args.output_mesh, timing) else: result = r pymesh.save_mesh(args.output_mesh, result)
def main(): args = parse_args(); mesh_1 = pymesh.load_mesh(args.input_mesh_1); mesh_2 = pymesh.load_mesh(args.input_mesh_2); assert(mesh_1.dim == 3); assert(mesh_2.dim == 3); bbox_min_1, bbox_max_1 = mesh_1.bbox; bbox_min_2, bbox_max_2 = mesh_2.bbox; bbox_min = np.minimum(bbox_min_1, bbox_min_2); bbox_max = np.maximum(bbox_max_1, bbox_max_2); #queries = grid_sample(bbox_min, bbox_max, args.num_samples); queries = random_sample(bbox_min, bbox_max, args.num_samples); winding_number_1 = pymesh.compute_winding_number(mesh_1, queries, engine=args.winding_number_engine) > 0.5; winding_number_2 = pymesh.compute_winding_number(mesh_2, queries, engine=args.winding_number_engine) > 0.5; diff = np.logical_xor(winding_number_1, winding_number_2); num_diff = np.count_nonzero(diff); print("Winding numbers of {} out of {} samples differ".format( num_diff, len(queries))); if args.output is not None: r = np.amax(bbox_max - bbox_min) * 0.01; box = pymesh.generate_box_mesh(np.ones(3) * -r, np.ones(3) * r); vertices = []; faces = []; for i in range(len(queries)): vertices.append(box.vertices + queries[i]); faces.append(box.faces + box.num_vertices * i); vertices = np.vstack(vertices); faces = np.vstack(faces); mesh = pymesh.form_mesh(vertices, faces); mesh.add_attribute("diff"); mesh.set_attribute("diff", np.repeat(diff, box.num_faces)); pymesh.save_mesh(args.output, mesh, "diff"); if args.export: info = load_info(args.input_mesh_2); info["diff"] = num_diff dump_info(args.input_mesh_2, info); if args.timing: pymesh.timethis.summarize();
def test_msh(self): mesh = generate_box_mesh(np.zeros(3), np.ones(3)); self.assertEqual(3, mesh.dim); self.assertEqual(3, mesh.vertex_per_face); self.assertEqual(8, mesh.num_vertices); self.assertEqual(12, mesh.num_faces); self.assertEqual(6, mesh.num_voxels); mesh.add_attribute("vertex_index"); mesh2 = self.write_and_load(mesh, "cube.msh", attr_names=["vertex_index"]); self.assert_mesh_equal(mesh, mesh2, attr_names=["vertex_index"]); mesh3 = self.write_and_load(mesh, "cube.msh", attr_names=["vertex_index"], use_ascii=True); self.assert_mesh_equal(mesh, mesh3, attr_names=["vertex_index"]);
def build_plane(direction, level, limit, eps=2): """ Generate the plane to perform the cut given a certain direction x, y or z and a certain level between limits """ if direction == 'y': Xa = np.array([limit, level, limit]) Xb = np.array([0, level + eps, 0]) elif direction == 'z': Xa = np.array([limit, limit, level]) Xb = np.array([0, 0, level + eps]) elif direction == 'x': Xa = np.array([level, limit, limit]) Xb = np.array([level + eps, 0, 0]) return pymesh.generate_box_mesh(Xa, Xb)
def test_msh(self): mesh = generate_box_mesh(np.zeros(3), np.ones(3)) self.assertEqual(3, mesh.dim) self.assertEqual(3, mesh.vertex_per_face) self.assertEqual(8, mesh.num_vertices) self.assertEqual(12, mesh.num_faces) self.assertEqual(6, mesh.num_voxels) mesh.add_attribute("vertex_index") mesh2 = self.write_and_load(mesh, "cube.msh", attr_names=["vertex_index"]) self.assert_mesh_equal(mesh, mesh2, attr_names=["vertex_index"]) mesh3 = self.write_and_load(mesh, "cube.msh", attr_names=["vertex_index"], use_ascii=True) self.assert_mesh_equal(mesh, mesh3, attr_names=["vertex_index"])
def slice_mesh(mesh, N): bbox_min, bbox_max = mesh.bbox; min_corner = [bbox_min[0] -1.0, bbox_min[1] - 1.0, bbox_min[2] - 1.0]; output_wires = []; for i in range(N): ratio = float(i) / float(N); slice_val = bbox_min[0] * ratio + bbox_max[0] * (1-ratio); max_corner = [slice_val, bbox_max[1] + 1.0, bbox_max[2] + 1.0]; box = pymesh.generate_box_mesh(min_corner, max_corner); diff = pymesh.boolean(box, mesh, "difference"); #pymesh.save_mesh("tmp_{}.msh".format(i), diff); vertices = diff.vertices; y_out_range = np.logical_or( vertices[:,1] < bbox_min[1], vertices[:,1] > bbox_max[1]); z_out_range = np.logical_or( vertices[:,2] < bbox_min[2], vertices[:,2] > bbox_max[2]); on_outside = np.logical_or(y_out_range, z_out_range); if not np.any(on_outside): continue; edges = []; for f in diff.faces: if np.sum(on_outside[f]) == 1: if on_outside[f[0]]: edges.append([f[1], f[2]]); if on_outside[f[1]]: edges.append([f[2], f[0]]); if on_outside[f[2]]: edges.append([f[0], f[1]]); if len(edges) == 0: continue; edges = np.array(edges, dtype=int); below_ground = vertices[:,1] < 0.5*(bbox_min[1]+bbox_max[1]); edges_below_ground = np.any(below_ground[edges], axis=1); edges = edges[np.logical_not(edges_below_ground)]; vertices, edges, __ = \ pymesh.remove_isolated_vertices_raw(vertices, edges); wires = pymesh.wires.WireNetwork.create_from_data(vertices, edges); output_wires.append(wires); print('.',end="",flush=True) print("done"); return output_wires;
def main(): args = parse_args(); mesh = pymesh.load_mesh(args.input_mesh); if mesh.vertex_per_face == 4: logging.warning("Converting quad mesh to triangle mesh."); mesh = pymesh.quad_to_tri(mesh); if args.exact: name,ext = os.path.splitext(args.output_mesh); exact_mesh_file = name + ".xml"; else: exact_mesh_file = None; if mesh.num_vertices ==0 or mesh.num_faces == 0: # Empty input mesh, output empty mesh as well. result = pymesh.form_mesh(np.zeros((0,3),dtype=float), np.zeros((0,3),dtype=int)); if args.timing: update_info(args.output_mesh, 0); else: if args.engine == "igl": empty = pymesh.form_mesh(np.zeros((0,3)), np.zeros((0,3))); r = pymesh.boolean( mesh, empty, "union", engine=args.engine, with_timing = args.timing, exact_mesh_file=exact_mesh_file); else: # Empty mesh is valid for these libraries, using bbox instead. bbox = mesh.bbox; center = (bbox[0] + bbox[1]) * 0.5; box = pymesh.generate_box_mesh( bbox[0] - np.ones(mesh.dim), bbox[1] + np.ones(mesh.dim)); r = pymesh.boolean( mesh, box, "intersection", engine=args.engine, with_timing = args.timing, exact_mesh_file=exact_mesh_file); if args.timing: result, timing = r; update_info(args.output_mesh, timing); else: result = r; pymesh.save_mesh(args.output_mesh, result);
def test_hex_connectivity(self): mesh = pymesh.generate_box_mesh([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], num_samples=2, using_simplex=False); mesh.enable_connectivity(); self.assertEqual(27, mesh.num_vertices); self.assertEqual(24, mesh.num_faces); self.assertEqual(8, mesh.num_voxels); self.assertEqual(3, len(mesh.get_voxel_adjacent_voxels(0))); self.assertEqual(3, len(mesh.get_voxel_adjacent_voxels(1))); self.assertEqual(3, len(mesh.get_voxel_adjacent_voxels(2))); self.assertEqual(3, len(mesh.get_voxel_adjacent_voxels(3))); self.assertEqual(3, len(mesh.get_voxel_adjacent_voxels(4))); self.assertEqual(3, len(mesh.get_voxel_adjacent_voxels(5))); self.assertEqual(3, len(mesh.get_voxel_adjacent_voxels(6))); self.assertEqual(3, len(mesh.get_voxel_adjacent_voxels(7)));
def main(): args = parse_args() mesh = pymesh.load_mesh(args.input_mesh) if args.initial_block is not None: block = pymesh.load_mesh(args.initial_block) else: bbox_min, bbox_max = mesh.bbox block = pymesh.generate_box_mesh(bbox_min, bbox_max, 2, keep_symmetry=True) block = pymesh.form_mesh(block.vertices, block.faces) block, __ = pymesh.remove_isolated_vertices(block) carved = carve_mesh(mesh, block, args.N, args.batch_size, args.output_mesh, args.initial_N, args.save_intermediate, args.debug) pymesh.save_mesh(args.output_mesh, carved)
def main(): args = parse_args(); mesh = pymesh.load_mesh(args.input_mesh); if args.initial_block is not None: block = pymesh.load_mesh(args.initial_block); else: bbox_min, bbox_max = mesh.bbox; block = pymesh.generate_box_mesh(bbox_min, bbox_max, 2, keep_symmetry=True); block = pymesh.form_mesh(block.vertices, block.faces); block, __ = pymesh.remove_isolated_vertices(block); carved = carve_mesh(mesh, block, args.N, args.batch_size, args.output_mesh, args.initial_N, args.save_intermediate, args.debug); pymesh.save_mesh(args.output_mesh, carved);
def test_tile_with_mixed_patterns(self): wire_networks = [self.get_brick5(), self.get_cross_3D()] params = [ Parameters(wire_networks[0], 0.1), Parameters(wire_networks[1], 0.0) ] params[0].load_default_isotropic_parameters() params[1].load_default_isotropic_parameters() max_num_dofs = max(params[0].num_dofs, params[1].num_dofs) pattern_id = np.array([0, 1, 1, 0, 1, 0, 0, 1]) mesh = generate_box_mesh(np.zeros(3), np.ones(3), subdiv_order=1, using_simplex=False) mesh.add_attribute("pattern_id") mesh.set_attribute("pattern_id", pattern_id) for i in range(max_num_dofs): dof_name = "dof_{}".format(i) dof = np.array([ params[j].dofs[i] if i < params[j].num_dofs else 0 for j in pattern_id ]) mesh.add_attribute(dof_name) mesh.set_attribute(dof_name, dof) tiler = Tiler(wire_networks) tiler.tile_with_mixed_patterns(mesh) tiled_wire_network = tiler.wire_network self.assert_array_equal(mesh.bbox, tiled_wire_network.bbox) self.assertEqual( (wire_networks[0].num_edges + wire_networks[1].num_edges) * 4, tiled_wire_network.num_edges) self.assertEqual( (wire_networks[0].num_vertices + wire_networks[1].num_vertices) * 4 - 4 * 3, tiled_wire_network.num_vertices)
def test_tile_with_mixed_patterns(self): wire_networks = [ self.get_brick5(), self.get_cross_3D() ]; params = [Parameters(wire_networks[0], 0.1), Parameters(wire_networks[1], 0.0)]; params[0].load_default_isotropic_parameters(); params[1].load_default_isotropic_parameters(); max_num_dofs = max(params[0].num_dofs, params[1].num_dofs); pattern_id = np.array([0, 1, 1, 0, 1, 0, 0, 1]); mesh = generate_box_mesh(np.zeros(3), np.ones(3), subdiv_order=1, using_simplex=False); mesh.add_attribute("pattern_id"); mesh.set_attribute("pattern_id", pattern_id); for i in range(max_num_dofs): dof_name = "dof_{}".format(i); dof = np.array([params[j].dofs[i] if i < params[j].num_dofs else 0 for j in pattern_id ]); mesh.add_attribute(dof_name); mesh.set_attribute(dof_name, dof); tiler = Tiler(wire_networks); tiler.tile_with_mixed_patterns(mesh); tiled_wire_network = tiler.wire_network; self.assert_array_equal( mesh.bbox, tiled_wire_network.bbox); self.assertEqual( (wire_networks[0].num_edges + wire_networks[1].num_edges) * 4, tiled_wire_network.num_edges); self.assertEqual( (wire_networks[0].num_vertices + wire_networks[1].num_vertices) * 4 - 4 * 3, tiled_wire_network.num_vertices);
def main(): args = parse_args(); side_lengths = np.ones(args.dim) * args.size; if (args.X is not None): side_lengths[0] = args.X if (args.Y is not None): side_lengths[1] = args.Y if (args.dim == 3 and args.Z is not None): side_lengths[2] = args.Z num_samples = np.ones(args.dim, dtype=int) * args.num_samples; if args.num_samples_X is not None: num_samples[0] = args.num_samples_X; if args.num_samples_Y is not None: num_samples[1] = args.num_samples_Y; if args.dim == 3 and args.num_samples_Z is not None: num_samples[2] = args.num_samples_Z; using_simplex = not(args.with_quad or args.with_hex); mesh = generate_box_mesh(-0.5 * side_lengths, 0.5 * side_lengths, num_samples, args.symmetric, args.subdiv, using_simplex); save_mesh(args.output, mesh, "cell_index");
def test_tile_with_guide_mesh(self): wire_network = self.get_brick5(); params = Parameters(wire_network, 0.5); tiler = Tiler(wire_network); mesh = generate_box_mesh(np.zeros(3), np.ones(3), subdiv_order=1, using_simplex=False); tiler = Tiler(wire_network); tiler.tile_with_guide_mesh(mesh, params); tiled_wire_network = tiler.wire_network; self.assertEqual(8 * wire_network.num_edges, tiled_wire_network.num_edges); self.assertEqual(8 * wire_network.num_vertices - 12, tiled_wire_network.num_vertices); self.assert_array_equal( mesh.bbox, tiled_wire_network.bbox); self.assertTrue(tiled_wire_network.has_attribute("thickness")); self.assertTrue(tiled_wire_network.has_attribute("vertex_offset")); self.assert_array_equal( np.ones(tiled_wire_network.num_vertices) * 0.5, tiled_wire_network.get_attribute("thickness").ravel());
def get_box_mesh(self): mesh = generate_box_mesh(np.zeros(3), np.ones(3)); mesh = form_mesh(mesh.vertices, mesh.faces); return mesh;
import pymesh js.set_export_mode() # In[24]: bunny = pymesh.load_mesh("HDbunny/bunny.obj") # In[25]: bunny.get_attribute_names() # In[26]: box_min = np.array([-0.11, +0.10, -0.01]) box_max = np.array([-0.04, +0.17, +0.06]) box = pymesh.generate_box_mesh(box_min, box_max) # In[27]: intersection = pymesh.boolean(box, bunny, "intersection", "carve") # In[28]: intersection.get_attribute_names() # In[29]: pymesh.save_mesh("output2.obj", intersection, *intersection.get_attribute_names()) # In[ ]:
def box(x,y,z): '''Generate a mesh for a GDML box primitive''' return pymesh.generate_box_mesh([-x/2,-y/2,-z/2],[x/2,y/2,z/2])
def test_vertex_to_face(self): mesh = generate_box_mesh(np.zeros(3), np.ones(3)); attr = np.ones(mesh.num_vertices); attr2 = convert_to_face_attribute(mesh, attr).ravel(); self.assert_array_equal(np.ones(mesh.num_faces), attr2);
def modify_solid(mesh, surface_height, code, opts): bbox = get_fast_bbox(mesh) if opts['crop']: bbox[0][0] += opts['crop'] bbox[0][1] += opts['crop'] bbox[1][0] -= opts['crop'] bbox[1][1] -= opts['crop'] if opts['crop_xyz']: crop0_x, crop0_y, crop0_z, crop1_x, crop1_y, crop1_z = opts[ 'crop_xyz'].split(",") bbox[0][0] += int(crop0_x) bbox[0][1] += int(crop0_y) bbox[0][2] += int(crop0_z) bbox[1][0] -= int(crop1_x) bbox[1][1] -= int(crop1_y) bbox[1][2] -= int(crop1_z) inner_box_dims = copy.deepcopy(bbox) inner_box = pymesh.generate_box_mesh(bbox[0], bbox[1]) bbox[0][0] -= OUTER_BOX_MM bbox[0][1] -= OUTER_BOX_MM bbox[0][2] -= OUTER_BOX_MM # tiny debug fudge to not have two faces intersecting each other bbox[0][2] -= .1 bbox[1][0] += OUTER_BOX_MM bbox[1][1] += OUTER_BOX_MM bbox[0][2] -= surface_height print("make modifications") outer_box = pymesh.generate_box_mesh(bbox[0], bbox[1]) outer_box = pymesh.boolean(outer_box, inner_box, operation="difference", engine="igl") magnet_center = (inner_box_dims[0][0] + (inner_box_dims[1][0] - inner_box_dims[0][0]) / 2.0, inner_box_dims[0][1] + (inner_box_dims[1][1] - inner_box_dims[0][1]) / 2.0, inner_box_dims[0][2]) magnet_center_top = (inner_box_dims[0][0] + (inner_box_dims[1][0] - inner_box_dims[0][0]) / 2.0, inner_box_dims[0][1] + (inner_box_dims[1][1] - inner_box_dims[0][1]) / 2.0, inner_box_dims[0][2] + MAGNET_DEPTH) magnet_cup = pymesh.generate_cylinder(magnet_center, magnet_center_top, MAGNET_RADIUS, MAGNET_RADIUS - .5, num_segments=64) # outer_box = pymesh.boolean(outer_box, magnet_cup, operation="union", engine="igl") hook_center = (inner_box_dims[1][0] - (inner_box_dims[1][0] - inner_box_dims[0][0]) / 8.0, inner_box_dims[0][1] + (inner_box_dims[1][1] - inner_box_dims[0][1]) / 2.0, inner_box_dims[0][2]) hook_box = pymesh.generate_box_mesh( (hook_center[0] - (HOOK_BOX_WIDTH / 2), hook_center[1] - (HOOK_BOX_HEIGHT / 2), hook_center[2] - (HOOK_BOX_DEPTH / 2)), (hook_center[0] + (HOOK_BOX_WIDTH / 2), hook_center[1] + (HOOK_BOX_HEIGHT / 2), hook_center[2] + (HOOK_BOX_DEPTH / 2))) # outer_box = pymesh.boolean(outer_box, hook_box, operation="union", engine="igl") # if opts['debug']: # save_mesh("modified", outer_box); if opts['url_top']: url_side = 'top' elif opts['url_bottom']: url_side = 'bottom' elif opts['url_left']: url_side = 'left' elif opts['url_right']: url_side = 'right' elif opts['url_floor']: url_side = 'floor' if opts['code_top']: code_side = 'top' elif opts['code_bottom']: code_side = 'bottom' elif opts['code_left']: code_side = 'left' elif opts['code_right']: code_side = 'right' elif opts['code_floor']: code_side = 'floor' if not opts['no_url']: print("make url") url = make_text_mesh("wearebeautiful.info", True) url = move_text_to_surface(url, inner_box_dims, url_side, opts, opts['url_scale'], opts['url_h_offset'], opts['url_v_offset']) outer_box = pymesh.boolean(outer_box, url, operation="union", engine="igl") if not opts['no_code']: print("make code") code = make_text_mesh(code, False) code = move_text_to_surface(code, inner_box_dims, code_side, opts, opts['code_scale'], opts['code_h_offset'], opts['code_v_offset']) outer_box = pymesh.boolean(outer_box, code, operation="union", engine="igl") if opts['debug']: save_mesh("before-subtract-outer-box", outer_box) print("final subtract") if surface_height: mesh = translate(mesh, (0, 0, -surface_height)) if opts['debug']: save_mesh("before-subtract-mesh", mesh) return pymesh.boolean(mesh, outer_box, operation="difference", engine="igl")
def get_box_mesh(self): mesh = generate_box_mesh(np.zeros(3), np.ones(3)) mesh = form_mesh(mesh.vertices, mesh.faces) return mesh
def main(): args = parse_args(); mesh = pymesh.load_mesh(args.input_mesh); bbox = mesh.bbox; bbox_mesh = pymesh.generate_box_mesh(bbox[0], bbox[1], 1); pymesh.save_mesh(args.output_mesh, bbox_mesh);
def test_vertex_to_face(self): mesh = generate_box_mesh(np.zeros(3), np.ones(3)) attr = np.ones(mesh.num_vertices) attr2 = convert_to_face_attribute(mesh, attr).ravel() self.assert_array_equal(np.ones(mesh.num_faces), attr2)