import sys import stl3d def points(seed, max_x, dx, dy, max_z, dz): "Generate the rows of the heightfield, a sequence of lists of 3-tuples." generator = random.Random() generator.seed(seed) nx = int(max_x // dx) y = [0] * nx zi = int(max_z // dz) def row(): return [(xi * dx, yi, zi * dz) for xi, yi in enumerate(y)] while zi > 0: yield row() y = [yi + (generator.random() * 2 - 1) * dy for yi in y] # smooth to keep things manageable? zi -= 1 yield row() if __name__ == '__main__': seed = 0 if len(sys.argv) < 2 else int(sys.argv[1]) pp = list(points(seed=seed, max_x=40, dx=3, dy=.5, max_z=20, dz=2.5)) pp.reverse() for line in stl3d.stl_file(stl3d.extrude_mesh(pp, (0, .75, 0)), name="brownian surface seed %s" % seed): sys.stdout.write(line)
def main(argv): rod_diameter = 25 # mm rr = rod_diameter / 2.0 # radius of rod strip_width = 6 gap = 1 # radian rr_adjusted = rr * 2*pi / (2*pi - gap) # inner circumference after closing ri = rr_adjusted + 2 # leave some slip space ro = ri + strip_width # radius outer fn = 256 # number of different angles to use for the arc angles = [ii * 2 * pi / fn for ii in range(int(gap*fn/2/pi), fn+1)] thickness = 0.4 # mm; stiff but flexible disp = (0, 0, thickness) # displacement vector between the sides t_width = 2 # width of the T stem t_height = 2*t_width # height of the T stem t_incut = (strip_width - t_width) / 2.0 clearance = 0.25 # mm to leave between parts to slide smoothly t_top_width = strip_width spacing = 5 # mm between objects (beyond outside radius) inner_edge = arc(ri, 0, 2*pi-gap, fn) outer_edge = arc(ro, 0, 2*pi-gap, fn) bottom = list(stl3d.mesh(zip(outer_edge, inner_edge))) inner_edge_top = stl3d.translate_verts(disp, inner_edge) outer_edge_top = stl3d.translate_verts(disp, outer_edge) top = list(stl3d.mesh(zip(inner_edge_top, outer_edge_top))) inner_surface = list(stl3d.mesh(zip(inner_edge, inner_edge_top))) outer_surface = list(stl3d.mesh(zip(outer_edge_top, outer_edge))) # The circles start off going y+ from the positive X-axis. t_start = (stl3d.Polyline(inner_edge[0]) .rlineto((t_incut, 0, 0)) .rlineto((0, -t_height, 0)) .verts()) t_start.reverse() t_end = (stl3d.Polyline(outer_edge[0]) .rlineto((-t_incut, 0, 0)) .rlineto((0, -t_height, 0)) .verts()) t_center = ((ri + ro)/2.0, -t_height, 0) t_cap_line = stl3d.translate_verts(t_center, arc(t_top_width/2.0, pi, 2*pi, fn)) t_cap_line.reverse() t_path = t_end + t_cap_line + t_start t_path_top = stl3d.translate_verts(disp, t_path) t_surface = list(stl3d.mesh(zip(t_path, t_path_top))) t_fill_center = stl3d.translate(t_center, (0, -t_top_width/4.0, 0)) t_fill = list(stl3d.convex_fill(t_fill_center, t_path[1:-1])) t_fill_top = list(stl3d.flipped(disp, t_fill)) tt = t_surface + t_fill + t_fill_top # We’ll construct the slot in a convenient place, then rotate it # into place. slot_width = t_width + 2*clearance slot_length = t_top_width + 2*clearance slot_cap_center = ((ri+ro)/2.0, slot_length, 0) slot_outer_arc = stl3d.translate_verts(slot_cap_center, arc(strip_width/2.0, 0, pi, fn)) slot_outer_arc.reverse() slot_arc_fill = list(stl3d.convex_fill(slot_cap_center, slot_outer_arc)) slot_arc_fill_top = list(stl3d.flipped(disp, slot_arc_fill)) slot_outer_path = ([inner_edge[0]] + slot_outer_arc + [outer_edge[0]]) slot_outer_path_top = stl3d.translate_verts(disp, slot_outer_path) slot_outer_surface = list(stl3d.mesh(zip(slot_outer_path, slot_outer_path_top))) slot_side_width = (strip_width - slot_width) / 2.0 slot_inside_edge = (stl3d.Polyline(inner_edge[0]) .rlineto((slot_side_width, 0, 0)) .rlineto(disp) .rlineto((-slot_side_width, 0, 0)) .verts()) slot_inside_edge_2 = stl3d.translate_verts((0, slot_length, 0), slot_inside_edge) slot_inside_surface = list(stl3d.mesh(zip(slot_inside_edge, slot_inside_edge_2))) slot_outside_edge = (stl3d.Polyline(outer_edge[0]) .rlineto((-slot_side_width, 0, 0)) .rlineto(disp) .rlineto((slot_side_width, 0, 0)) .verts()) slot_outside_edge.reverse() slot_outside_edge_2 = stl3d.translate_verts((0, slot_length, 0), slot_outside_edge) slot_outside_surface = list(stl3d.mesh(zip(slot_outside_edge, slot_outside_edge_2))) slot_end_line = [slot_outside_edge_2[2], slot_inside_edge_2[1]] slot_end_line_2 = stl3d.translate_verts(disp, slot_end_line) slot_end_surface = list(stl3d.mesh(zip(slot_end_line, slot_end_line_2))) slot_start_surface = list(stl3d.flipped((0, -slot_length, 0), slot_end_surface)) slot_unrotated = (slot_arc_fill + slot_arc_fill_top + slot_outer_surface + slot_inside_surface + slot_outside_surface + slot_end_surface + slot_start_surface ) slot_rotate_fragment_count = fragment_count(fn, -gap) slot_rotate_angle = 2*pi*slot_rotate_fragment_count / fn slot = list(stl3d.z_rotate_surface(slot_rotate_angle, slot_unrotated)) shower_ring = bottom + top + inner_surface + outer_surface + tt + slot outer_shower_ring = list(stl3d.translate_surface((0, ro*2 + spacing, 0), shower_ring)) outer_shower_rings = [list(stl3d.z_rotate_surface(ii * pi / 3, outer_shower_ring)) for ii in range(6)] shower_rings = shower_ring + sum(outer_shower_rings, []) for line in stl3d.stl_file(shower_rings, name="shower rings"): sys.stdout.write(line)