def basic_geometry(): # SolidPython code can look a lot like OpenSCAD code. It also has # some syntactic sugar built in that can make it look more pythonic. # Here are two identical pieces of geometry, one left and one right. # left_piece uses standard OpenSCAD grammar (note the commas between # block elements; OpenSCAD doesn't require this) left_piece = union()(translate((-15, 0, 0))(cube([10, 5, 3], center=True)), translate( (-10, 0, 0))(difference()(cylinder(r=5, h=15, center=True), cylinder(r=4, h=16, center=True)))) # Right piece uses a more Pythonic grammar. + (plus) is equivalent to union(), # - (minus) is equivalent to difference() and * (star) is equivalent to intersection # solid.utils also defines up(), down(), left(), right(), forward(), and back() # for common transforms. right_piece = right(15)(cube([10, 5, 3], center=True)) cyl = cylinder(r=5, h=15, center=True) - cylinder(r=4, h=16, center=True) right_piece += right(10)(cyl) return union()(left_piece, right_piece)
def doohickey(): hole_cyl = translate( (0, 0, -EPSILON))(cylinder(r=m3_rad, h=doohickey_h + 2 * EPSILON)) d = difference()(cube([30, 10, doohickey_h], center=True), translate((-10, 0, 0))(hole_cyl), hole_cyl, translate((10, 0, 0))(hole_cyl)) return d
def m3_nut(): hx = cylinder(r=nut_rad, h=nut_height) hx.add_param('$fn', 6) # make the nut hexagonal n = difference()( hx, translate((0, 0, -EPSILON))( cylinder(r=m3_rad, h=nut_height + 2 * EPSILON) ) ) return n
def bottom_part(): top = difference() u = union() u2 = union() top.add(u) d = difference() d.add(cylinder(r=innerR + wall + gap, h=toph)) d.add(translate((0, 0, baseH)).add(cylinder(r=innerR + gap, h=toph))) u.add(d) top.add(u2) for i in range(0, 3): a = i * 2 * pi / 3 r = innerR + gap + wall / 2 u.add( translate(((r - 0.3) * cos(a), (r - 0.3) * sin(a), toph - 6)).add(sphere(r=2.4))) u2.add( translate(((r + wall - 0.3) * cos(a), (r + wall - 0.3) * sin(a), toph - 6)).add(sphere(r=2.4))) return top
def top_part(): maze_path = os.path.join(os.path.dirname(__file__), 'maze7.png') depth_map = build_depth_map(maze_path) d = difference() u = union() u.add(bumpMapCylinder(depth_map, innerR, hn, 0, 255)) u.add(cylinder(r=innerR + wall + gap, h=gripH)) d.add(u) d.add(intersection().add( bumpMapCylinder(depth_map, innerR, hn + 2, wall, 0).set_modifier("")).add( translate((0, 0, baseH)).add( cylinder(r=innerR + 2 * wall, h=h * 1.1).set_modifier("")))) return d
def ipadminiholderfront(): # Back (wall mount) # o = sizedipad(IPAD_W + WALL * 2 + SLIP * 2, IPAD_H + WALL * 2 + SLIP * 2, BACK) o = union() # Front supports o += sizedipad( TOTAL_W, IPAD_H + WALL * 2 + SLIP * 2 + INNER_WALL + WALL_PADDING, IPAD_D + WALL + SLIP + BACK, ) sides = WALL + INNER_WALL + WALL_PADDING + SLIP # Cutouts for buttons, round curves around the button o -= translate([ IPAD_W + WALL + SLIP * 2 + INNER_WALL + WALL_PADDING - BUTTON_D / 2 - BUTTON_TO_EDGE, (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING, BACK, ])(cylinder(d=BUTTON_D, h=50)) o -= translate([ sides + SCREEN_SIDE_EDGE - SCREEN_BORDER + IPAD_W - (SCREEN_SIDE_EDGE - SCREEN_BORDER) * 2 + BUTTON_D / 2, (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING + BUTTON_D, BACK, ])(difference()( translate([-BUTTON_D, -BUTTON_D, 0])(cube([BUTTON_D, BUTTON_D, 50])), cylinder(d=BUTTON_D, h=50), )) o -= translate([ sides + SCREEN_SIDE_EDGE - SCREEN_BORDER + IPAD_W - (SCREEN_SIDE_EDGE - SCREEN_BORDER) * 2 + BUTTON_D / 2, (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING - BUTTON_D, BACK, ])(difference()( translate([-BUTTON_D, 0, 0])(cube([BUTTON_D, BUTTON_D, 50])), cylinder(d=BUTTON_D, h=50), )) # Camera o -= translate([ sides + BUTTON_TO_EDGE + BUTTON_D / 2, (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING, BACK, ])(cylinder(d=BUTTON_D, h=50)) o -= translate([ sides + SCREEN_SIDE_EDGE - SCREEN_BORDER - BUTTON_D / 2, (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING + BUTTON_D, BACK, ])(difference()( translate([0, -BUTTON_D, 0])(cube([BUTTON_D, BUTTON_D, 50])), cylinder(d=BUTTON_D, h=50), )) o -= translate([ sides + SCREEN_SIDE_EDGE - SCREEN_BORDER - BUTTON_D / 2, (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING - BUTTON_D, BACK, ])(difference()( translate([0, 0, 0])(cube([BUTTON_D, BUTTON_D, 50])), cylinder(d=BUTTON_D, h=50), )) # # Camera # o -= translate([WALL + SIDE_EDGE / 2, (IPAD_H + WALL * 2 + SLIP * 2) / 2, BACK])( # cylinder(d=BUTTON_D, h=50) # ) # Cutout for actual iPad, made very tall to allow sliding in/out if ALLOW_IPAD_SLIDE_IN: height = IPAD_H * 2 + INNER_WALL + WALL_PADDING else: height = IPAD_H + INNER_WALL * 2 + WALL_PADDING o -= translate([WALL, WALL, -1])(sizedipad( IPAD_W + SLIP * 2 + INNER_WALL * 2 + WALL_PADDING * 2, height, IPAD_D + SLIP + BACK + 1, )) # Cutout for remaining material around where the extra overhang is for the power # connector o -= translate([WALL, WALL, -1])(sizedipad( TOTAL_W - WALL * 2, IPAD_H + INNER_WALL * 2 + WALL_PADDING, IPAD_D + SLIP + BACK + 1, )) # Cutout for screen o -= translate([ sides + SCREEN_SIDE_EDGE - SCREEN_BORDER, sides + SCREEN_BOTTOM_EDGE - SCREEN_BORDER, BACK, ])(cube([ IPAD_W - (SCREEN_SIDE_EDGE - SCREEN_BORDER) * 2, IPAD_H - (SCREEN_BOTTOM_EDGE - SCREEN_BORDER) * 2, IPAD_D * 3, ])) # Side "hooks" o += translate([WALL, (IPAD_H - 15 * 2) + 15, 0])(rotate([90, 0, 0])( linear_extrude(IPAD_H - 15 * 2)(polygon([[0, 0], [1, 0], [0, 1]])))) o += translate([TOTAL_W - WALL * 2 + WALL, 15, 0])(rotate([-90, 180, 0])( linear_extrude(IPAD_H - 15 * 2)(polygon([[0, 0], [1, 0], [0, 1]])))) o += translate([ (TOTAL_W - 15 * 2) + 15, WALL, 0 ])(rotate([0, -90, 0])(linear_extrude(TOTAL_W - 15 * 2)(polygon([[0, 0], [1, 0], [0, 1]])))) # o += translate([15, WALL, 0])(cube([IPAD_W - 15 * 2, WALL, WALL])) # Power connector if POWER_CONNECTOR_ACCESSIBLE: o -= translate([ IPAD_W / 2, (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING - POWER_UNDERHANG - BUTTON_D / 2, -1, ])(cube([IPAD_W, BUTTON_D + POWER_UNDERHANG, IPAD_D + SLIP + BACK + 1])) # Lock Button if ALLOW_IPAD_SLIDE_IN: extra = 100 else: extra = 0 o -= translate([ -1, (IPAD_H + WALL * 2 + SLIP * 2) - LOCK_BUTTON_TO_EDGE - LOCK_BUTTON_LEN + INNER_WALL + WALL_PADDING, 0, ])(cube([50, LOCK_BUTTON_LEN + extra, IPAD_D + SLIP + BACK])) # Screws o -= screws() if SHOW_IPAD: o += translate([ WALL + INNER_WALL + SLIP + WALL_PADDING, WALL + INNER_WALL + SLIP + WALL_PADDING, BACK, ])(IPAD_STL).set_modifier("") return o
def main(params: Params): # face face_profile = roundrect( [LGX_FACE_WIDTH, LGX_FACE_HEIGHT + params.lgx_face_extra_height], params.face_radius, ) cutout_profile = roundrect([params.poe_face_width, params.poe_face_height], params.poe_face_radius) cutout_x = LGX_FACE_WIDTH / 2 - params.poe_face_width / 2 cutout_y = params.poe_face_lift + params.platform_thickness cutout = translate([cutout_x, cutout_y, 0])(cutout_profile) cutout_extrude = debug( down(params.lgx_rack_thickness)( linear_extrude(params.face_thickness + params.lgx_rack_thickness)(cutout))) post = circle(d=params.face_post_d) posts = post + right(params.face_post_separation)(post) posts = translate([ LGX_FACE_WIDTH / 2 - params.face_post_separation / 2, LGX_FACE_HEIGHT / 2, 0 ])(posts) face = difference()(face_profile, posts) face_extrusion = linear_extrude(height=params.face_thickness)(face) tray_depth = (params.platform_thickness + params.poe_depth + params.lgx_rack_thickness) # tray tray = linear_extrude(height=params.platform_thickness)( square(size=[LGX_PLATFORM_WIDTH, tray_depth])) poe_holder_outer_params = [ params.poe_width + params.platform_thickness * 2, tray_depth, ] poe_holder_profile = difference()( square(poe_holder_outer_params), right(params.platform_thickness)(forward(params.lgx_rack_thickness)( square([ params.poe_width, params.poe_depth, ]))), ) poe_holder_extrude = linear_extrude( height=params.poe_retainer_height)(poe_holder_profile) poe_holder = translate([ LGX_PLATFORM_WIDTH / 2 - poe_holder_outer_params[0] / 2, 0, params.platform_thickness, ])(poe_holder_extrude) tray = union()(poe_holder, tray) tray = rotate([270, 0, 0])(translate( [LGX_FACE_WIDTH / 2 - LGX_PLATFORM_WIDTH / 2, 0, 0])(tray)) # support support_start_inset = (params.platform_thickness + LGX_FACE_WIDTH / 2 - LGX_PLATFORM_WIDTH / 2) point_extent = LGX_FACE_HEIGHT - params.platform_thickness support_profile = polygon([[0, 0], [0, point_extent], [point_extent, 0]]) support = linear_extrude(height=params.platform_thickness)(support_profile) support = rotate([270, 0, 90])(support) support_left = translate([support_start_inset, 0, 0])(support) support_right = translate([ support_start_inset + LGX_PLATFORM_WIDTH - params.platform_thickness, 0, 0 ])(support) return difference()(union()(face_extrusion, tray, support_left, support_right), cutout_extrude)