def rounded_cube(size, corner_radius, segments=None, center=False): if isinstance(corner_radius, (int, float)): corner_radius = XYZ( (corner_radius, corner_radius, corner_radius, corner_radius), (corner_radius, corner_radius, corner_radius, corner_radius), (corner_radius, corner_radius, corner_radius, corner_radius), ) else: corner_radius = XYZ(*corner_radius) if isinstance(size, (int, float)): size = XYZ(size, size, size) else: size = XYZ(*size) shapex = linear_extrude(size.x)(rounded_rectangle(XY(size.z, size.y), corner_radius.z, segments)) shapex = rotate((0, 90, 0))(shapex) shapex = translate(XYZ(0, 0, size.z))(shapex) shapey = linear_extrude(size.y)(rounded_rectangle(XY(size.x, size.z), corner_radius.y, segments)) shapey = rotate((90, 0, 0))(shapey) shapey = translate(XYZ(0, size.y, 0))(shapey) shapez = linear_extrude(size.z)(rounded_rectangle(XY(size.x, size.y), corner_radius.x, segments)) rc = intersection()(shapex, shapey, shapez) return rc
def arc(rad:float, start_degrees:float, end_degrees:float, segments:int=None) -> OpenSCADObject: # Note: the circle that this arc is drawn from gets segments, # not the arc itself. That means a quarter-circle arc will # have segments/4 segments. bottom_half_square = back(rad)(square([3 * rad, 2 * rad], center=True)) top_half_square = forward(rad)(square([3 * rad, 2 * rad], center=True)) start_shape = circle(rad, segments=segments) if abs((end_degrees - start_degrees) % 360) <= 180: end_angle = end_degrees - 180 ret = difference()( start_shape, rotate(a=start_degrees)(bottom_half_square.copy()), rotate(a=end_angle)(bottom_half_square.copy()) ) else: ret = intersection()( start_shape, union()( rotate(a=start_degrees)(top_half_square.copy()), rotate(a=end_degrees)(bottom_half_square.copy()) ) ) return ret
def conic_section(theta): line = solid.polygon(points = [[0,0],[50,50],[49.9,50],[0,.1]]) cone = solid.rotate_extrude( convexity = 20)(line) plane = solid.translate([0,0,5])(solid.cube([50,50,.1],center = True)) plane = solid.rotate([0,theta,0])(plane) section = solid.rotate([0,-1*theta, 0])(solid.intersection()(cone, plane)) return section
def arc(radius): a = solid.difference()( solid.cylinder(r=radius, h=thick, segments=48), solid.cylinder(r=radius-width, h=thick, segments=48)) a = solid.intersection()(a, solid.cube([radius, radius, thick])) a = solid.difference()(a, solid.translate(v=[.75*outerD, radius-width/2, 0]) (solid.cylinder(r=bolt/2, h=2*thick, segments=20, center=True))) a = solid.difference()(a, solid.translate(v=[radius-width/2, .75*outerD, width/2.0]) (solid.cylinder(r=bolt/2, h=2*thick, segments=20, center=True))) c = solid.translate(v=[radius-width/2, 0, 0])\ (solid.cylinder(r=bolt/2, h=2*thick, segments=20, center=True)) # Add bolt holes for fastening the two sheets of acryllic together for step in range(1,3): a = solid.difference()(a, solid.rotate(a = [0,0, step * 30])(c)) PolyLine(generator = solid.projection()(a)).save("heliodon/a" + str(radius) + ".dxf") return PolyMesh(generator=a)
def make_insert(key: Key, stem_inset: float = 1, radius=1) -> s.OpenSCADObject: stem = key.stem() shell = key shell.connector = None # hardcoding cherry mx dimensions for now stem_depth = 4 dims = [ *[d * .9 for d in shell.top_dims], shell.z - stem_depth - shell.depth - stem_inset ] insert = rounded_rectangle(dims, shape=s.sphere, radius=radius) insert = s.translate([0, 0, stem_depth + radius])(insert) insert = s.union()(insert, stem) insert = s.intersection()(insert, s.translate([0, 0, stem_depth])(s.cube( [*dims[0:2], dims[2] + stem_depth + radius], center=True))) return s.difference()(shell.key, s.translate([0, 0, stem_inset])(insert)), insert
import solid import math inf = 1000 upper_half_space = solid.cube(2 * inf, center=True) upper_half_space = solid.translate([0, 0, inf])(upper_half_space) outer_d = 155 outer_w = 2.5 core_d = 29.5 core_w = 14 base = solid.sphere(d=1) base = solid.scale([3 * core_d, outer_d, core_d])(base) base = solid.intersection()(base, upper_half_space) disc_cut = solid.cylinder(d=outer_d, h=outer_w, center=True) disc_cut = solid.rotate([0, 90, 0])(disc_cut) disc_cut = solid.translate([0, 0, outer_d / 2])(disc_cut) drain_hole = solid.cylinder(d=3 * outer_w, h=outer_d, center=True) horiz = core_w * 1.1 vert = outer_d * .125 lift = 2 xy_shift = [(0, -vert), (-horiz, vert), (horiz, vert)] for x, y in xy_shift: base -= solid.translate([x, y, lift])(disc_cut) base -= solid.translate([x, y, lift])(drain_hole)
def shrink(thickness, target): return intersection()([ translate(corner)(target) for corner in corners([thickness, thickness, thickness]) ])
def y_symmetric_intersection(target): return intersection()([target, y_symmetric(target)])
def top_peco_motor_mount(): return intersection()([ peco_motor_mount(), top_clipper(), ])
def short_peco_motor_mount(): return intersection()([ peco_motor_mount(), short_clipper(), ])
def ur_corner_peco_motor_mount(): return intersection()([ peco_motor_mount(), ur_corner_clipper_clipper(), ])
def side_peco_motor_mount(): return intersection()([ peco_motor_mount(), side_clipper(), ])
def narrow_peco_motor_mount(): return intersection()([ peco_motor_mount(), narrow_clipper(), ])
def rounded_rect_tray(r): extra_width = 25 r = r + extra_width / 2 edge_r = 1 min_th = 1.5 brim_w = 2.5 h = 11 slant_dx = h / 4 edge_circ_pt = np.array([slant_dx + brim_w - edge_r, h - edge_r]) # point where edge circle meets cutout ellipse # Decide the slope we want, then find the point on the circle with that slope meet_slope = math.pi / 6 # TODO: better math upper_meet_pt = edge_circ_pt + edge_r * np.array( [math.sin(meet_slope), -math.cos(meet_slope)]) bottom_meet_pt = np.array([min_th, 0]) # upper brim outer edge circle brim_edge_circ = S.translate(edge_circ_pt)(S.circle(edge_r)) upper_inner_circ = S.translate([slant_dx + edge_r, edge_circ_pt[1] - 0.5])(S.circle(edge_r)) bottom_rect = S.square([min_th, 0.1]) # ell_scale = ellV / ellH # print("sc: %f" % ell_scale) prof_p1 = S.hull()(bottom_rect, brim_edge_circ, upper_inner_circ) prof_n1 = S.union() main_tray = S.union()(util.generalized_pot( lambda prof: util.rounded_rect_extrude_func( prof, r, sizes=[pot_l + extra_width, pot_w + extra_width]), prof_p1=prof_p1, prof_n1=prof_n1, pot_l=pot_l, pot_w=pot_w, holes=False, base_th=2), ) pot = rounded_rect_pot(rpot_r) slice_ht = h - 1 slice_th = 2 slice_inset = 30 slice_y_inset = 30 + 20 pot_z_inset = 3 sides = S.union()( S.translate([-slice_th / 2, -pot_l, 0])(S.cube([slice_th, pot_l - slice_y_inset, slice_ht])), S.translate([-slice_th / 2, slice_y_inset, 0])(S.cube([slice_th, pot_l, slice_ht])), ) for y in [-25, 25]: sides.add( S.translate([-pot_w, y, 0])(S.cube([pot_w - slice_inset, slice_th, slice_ht]))) sides.add( S.translate([slice_inset, y, 0])(S.cube([pot_w, slice_th, slice_ht]))) main_tray = S.union()( main_tray, S.difference()( S.intersection()( sides, S.hull()(main_tray), ), # TODO: cutout pot S.translate([0, 0, h - pot_z_inset])(S.hull()(pot)), )) return main_tray
def main_vent(): return sp.intersection()( sp.square([d - 2. for d in size], center=True), sp.circle(d=64.), )
import os import sys import random import numpy as np import solid as sld import solid.utils as sutil from math import sin, cos, pi T = [sld.intersection(), sld.union(), sld.difference()] C = range(-5, 5) R = range(8, 24, 4) H = range(8, 32, 4) ROT = range(0, 360, 30) def sph2cart(s): # Assuming sphe_cord is [r, phi, theta] cord = np.array([ s[0] * sin(s[1]) * cos(s[2]), s[0] * sin(s[1]) * sin(s[2]), s[0] * cos(s[1]) ]) return cord def rand_phi(): return random.uniform(0, pi) def rand_theta(): return random.uniform(0, 2 * pi)
Dhollow = 68.2 Hhollow = 150 Dsmoke = 1.5 * 25.4 Hsmoke = 5 * 25.4 upper_plane = solid.cube(BIG, center=True) upper_plane = solid.translate([0, 0, BIG / 2])(upper_plane) ball_min = solid.sphere(d=Dmin, segments=resolution) ball_min = solid.translate([0, 0, H])(ball_min) ball_max = solid.sphere(d=Dmax, segments=resolution) nosecone = solid.hull()(ball_min, ball_max) # nosecone = solid.intersection()(upper_plane, nosecone) taper = solid.cylinder(d1=Dbase, d2=BIG + Dbase, h=BIG, segments=resolution) nosecone = solid.intersection()(taper, nosecone) minifin_top = solid.cube([17, 2.5, 10 + 3.6], center=True) minifin_bot = solid.cube([17 + 7.2, 2, 10], center=True) minifin = solid.hull()(minifin_top, minifin_bot) minifin = solid.rotate([0, 90 - theta, 0])(minifin) minifin = solid.translate([-60, 0, 24])(minifin) nosecone += minifin nose_groove = solid.translate([22, 0, 0])(solid.circle(2)) nose_groove = solid.rotate_extrude()(nose_groove) nose_groove = solid.translate([0, 0, H - 22])(nose_groove) nosecone -= nose_groove nosecone = solid.translate([-Dmax / 2, 0, 0])(nosecone) nosecone = solid.rotate([0, 90 - theta, 0])(nosecone) nosecone = solid.translate([Dmax / 2, 0, 0])(nosecone) nosecone += solid.sphere(d=Dbase, segments=resolution) nosecone = solid.intersection()(upper_plane, nosecone)
R_carve = 140.7 / 2 shift = .6 * 25.4 upper_plane = solid.cube(BIG, center=True) upper_plane = solid.translate([0, 0, BIG / 2])(upper_plane) block = solid.cylinder(d1=Dmax, d2=Dmin, h=H - trans, segments=resolution) block = solid.translate([0, 0, trans])(block) block += solid.cylinder(d=Dmax, h=trans, segments=resolution) lower = solid.cylinder(d=ID, h=id_insert + epsilon, segments=resolution) lower = solid.translate([0, 0, -id_insert])(lower) block += lower block = solid.sphere(d=Dmax, segments=resolution) block = solid.scale([1, 1, 2])(block) block = solid.intersection()(block, upper_plane) carve = solid.cylinder(r=R_carve, h=3 * H, center=True, segments=resolution) carve = solid.hull()( carve, solid.translate([BIG * np.cos(theta), BIG * np.sin(theta), 0])(carve), solid.translate([BIG * np.cos(theta), -BIG * np.sin(theta), 0])(carve), ) carve = solid.translate([R_carve + shift, 0, 0])(carve) carve = solid.union()( carve, solid.rotate([0, 0, 120])(carve), solid.rotate([0, 0, 240])(carve), ) total = solid.union()(block, )