feat: Complete drawer, needs turning into parts

This commit is contained in:
2026-07-23 23:17:32 +01:00
parent 26831c47ef
commit 7c1e7a0e12

View File

@@ -32,6 +32,8 @@ RAIL_SPOOL_FRONT_DIST = 5
RAIL_PARKED_SPOOL = True RAIL_PARKED_SPOOL = True
RAIL_CRITICAL_SPOOL = True RAIL_CRITICAL_SPOOL = True
TOP_LID_RATIO = .4
DRAWER_OUTER_WIDTH = DRAWER_INNER_WIDTH + SIDE_THICKNESS * 2 DRAWER_OUTER_WIDTH = DRAWER_INNER_WIDTH + SIDE_THICKNESS * 2
DRAWER_OUTER_LENGTH = DRAWER_INNER_LENGTH + LID_THICKNESS + BACK_THICKNESS DRAWER_OUTER_LENGTH = DRAWER_INNER_LENGTH + LID_THICKNESS + BACK_THICKNESS
@@ -39,6 +41,13 @@ FRAME_MARGIN = 8
GRID_STRIDE = 38 GRID_STRIDE = 38
GRID_FILL_RATIO = 0.08 GRID_FILL_RATIO = 0.08
COLOR_BOTTOM = (.2, .2, .2)
COLOR_LEFT = (.0, .6, .0)
COLOR_RIGHT = (.6, .0, .0)
COLOR_BACK = (.6, .6, .0)
COLOR_TOP = (.0, .0, .6)
COLOR_LID = (.0, .6, .6)
XX = .1 XX = .1
@@ -86,9 +95,6 @@ def _gen_rail() -> sp.OpenSCADObjectPlus:
def _gen_spool_rails() -> sp.OpenSCADObjectPlus: def _gen_spool_rails() -> sp.OpenSCADObjectPlus:
parked_spool = _gen_spool()
parked_spool = sp.up(RAIL_SPOOL_HEIGHT)(parked_spool)
rail_pos_radius = SPOOL_OUTER_D / 2 + RAIL_RADIUS rail_pos_radius = SPOOL_OUTER_D / 2 + RAIL_RADIUS
f_y_off = sin(radians(RAIL_FRONT_ANGLE)) * rail_pos_radius f_y_off = sin(radians(RAIL_FRONT_ANGLE)) * rail_pos_radius
f_z_off = (1-cos(radians(RAIL_FRONT_ANGLE))) * rail_pos_radius - RAIL_RADIUS + RAIL_SPOOL_HEIGHT f_z_off = (1-cos(radians(RAIL_FRONT_ANGLE))) * rail_pos_radius - RAIL_RADIUS + RAIL_SPOOL_HEIGHT
@@ -105,54 +111,121 @@ def _gen_spool_rails() -> sp.OpenSCADObjectPlus:
rail_base = sp.cylinder(h=RAIL_SUPPORT_THICKNESS, r=RAIL_RADIUS+RAIL_SUPPORT_EXTRA_RADIUS, center=True) rail_base = sp.cylinder(h=RAIL_SUPPORT_THICKNESS, r=RAIL_RADIUS+RAIL_SUPPORT_EXTRA_RADIUS, center=True)
rail_base = sp.rotateY(90)(rail_base) rail_base = sp.rotateY(90)(rail_base)
back_rail_base = sp.up(b_z_off)(rail_base) back_rail_base = sp.up(b_z_off)(rail_base)
back_rail_base = sp.forward(b_y_off)(back_rail_base) back_rail_base = sp.forward(b_y_off)(back_rail_base)
front_rail_base = sp.up(f_z_off)(rail_base) front_rail_base = sp.up(f_z_off)(rail_base)
front_rail_base = sp.forward(f_y_off)(front_rail_base) front_rail_base = sp.forward(f_y_off)(front_rail_base)
#TODO: Mid rail to reduce overlap with spool contents
mid_base = sp.cube([RAIL_SUPPORT_THICKNESS, RAIL_RADIUS*2, 1], center=True)
back_base = sp.forward(b_y_off)(sp.cube([RAIL_SUPPORT_THICKNESS, RAIL_RADIUS*2, 1], center=True)) back_base = sp.forward(b_y_off)(sp.cube([RAIL_SUPPORT_THICKNESS, RAIL_RADIUS*2, 1], center=True))
front_base = sp.forward(f_y_off)(sp.cube([RAIL_SUPPORT_THICKNESS, RAIL_RADIUS*2, 1], center=True)) front_base = sp.forward(f_y_off)(sp.cube([RAIL_SUPPORT_THICKNESS, RAIL_RADIUS*2, 1], center=True))
back_support = sp.hull()(back_rail_base, back_base) back_support = sp.hull()(back_rail_base, back_base)
front_support = sp.hull()(front_rail_base, front_base) front_support = sp.hull()(front_rail_base, front_base)
inter_support = sp.hull()(front_rail_base, back_rail_base) back_mid_support = sp.hull()(mid_base, back_rail_base)
rail_support = sp.union()(back_support, front_support, inter_support) front_mid_support = sp.hull()(front_rail_base, mid_base)
rail_support = sp.union()(back_support, front_support, back_mid_support, front_mid_support)
support_offset = SPOOL_WIDTH/2 - SPOOL_SIDE_THICK - RAIL_SUPPORT_THICKNESS/2 - RAIL_SUPPORT_SIDE_MARGIN support_offset = SPOOL_WIDTH/2 - SPOOL_SIDE_THICK - RAIL_SUPPORT_THICKNESS/2 - RAIL_SUPPORT_SIDE_MARGIN
left_support = sp.left(support_offset)(rail_support) left_support = sp.left(support_offset)(rail_support)
right_support = sp.right(support_offset)(rail_support) right_support = sp.right(support_offset)(rail_support)
rail_supports = sp.union()(left_support, right_support) rail_supports = sp.union()(left_support, right_support)
final = sp.union()(back_rail, front_rail, rail_supports)
if RAIL_PARKED_SPOOL:
parked_spool = _gen_spool()
parked_spool = sp.up(RAIL_SPOOL_HEIGHT)(parked_spool)
final = sp.union()(final, parked_spool)
if RAIL_CRITICAL_SPOOL:
critical_spool = _gen_spool((1, 0, 0), 0.3) critical_spool = _gen_spool((1, 0, 0), 0.3)
critical_spool = sp.up(f_z_off + RAIL_RADIUS)(critical_spool) critical_spool = sp.up(f_z_off + RAIL_RADIUS)(critical_spool)
critical_spool = sp.forward(f_y_off)(critical_spool) critical_spool = sp.forward(f_y_off)(critical_spool)
critical_spool = sp.right(XX)(critical_spool) critical_spool = sp.right(XX)(critical_spool)
final = sp.union()(back_rail, front_rail, rail_supports)
if RAIL_PARKED_SPOOL:
final = sp.union()(final, parked_spool)
if RAIL_CRITICAL_SPOOL:
final = sp.union()(final, critical_spool) final = sp.union()(final, critical_spool)
final = sp.forward(DRAWER_INNER_LENGTH/2 - SPOOL_OUTER_D/2 - RAIL_SPOOL_FRONT_DIST)(final) final = sp.forward(DRAWER_INNER_LENGTH/2 - SPOOL_OUTER_D/2 - RAIL_SPOOL_FRONT_DIST)(final)
return final return final
def _gen_back() -> sp.OpenSCADObjectPlus:
face = _gen_hex_frame(
DRAWER_OUTER_WIDTH, DRAWER_INNER_DEPTH, BACK_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO
)
return face
def _gen_top() -> sp.OpenSCADObjectPlus:
top = _gen_hex_frame(
DRAWER_OUTER_WIDTH, DRAWER_OUTER_LENGTH * (1-TOP_LID_RATIO), LID_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO
)
return top
def _gen_lid() -> sp.OpenSCADObjectPlus:
front = _gen_hex_frame(
DRAWER_OUTER_WIDTH, DRAWER_INNER_DEPTH, LID_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO
)
front = sp.back(LID_THICKNESS/2)(front)
top = _gen_hex_frame(
DRAWER_OUTER_WIDTH, DRAWER_OUTER_LENGTH * TOP_LID_RATIO, LID_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO
)
top = sp.rotateX(-90)(top)
top = sp.up(DRAWER_OUTER_LENGTH * TOP_LID_RATIO / 2)(top)
top = sp.forward(DRAWER_INNER_DEPTH/2 - LID_THICKNESS/2)(top)
lid = sp.union()(front, top)
return lid
def _gen_lid_at_hinge(angle: float = 0) -> sp.OpenSCADObjectPlus:
lid = _gen_lid()
lid = sp.down(DRAWER_OUTER_LENGTH * TOP_LID_RATIO)(lid)
lid = sp.back(DRAWER_INNER_DEPTH/2 + LID_THICKNESS/2)(lid)
lid = sp.rotateX(90+angle)(lid)
return lid
def gen_drawer() -> sp.OpenSCADObjectPlus: def gen_drawer() -> sp.OpenSCADObjectPlus:
bottom = _gen_bottom()
bottom = sp.down(FLOOR_THICKNESS)(bottom)
bottom = sp.color(COLOR_BOTTOM)(bottom)
left = _gen_side() left = _gen_side()
left = sp.rotateY(-90)(left) left = sp.rotateY(-90)(left)
left = sp.left(DRAWER_INNER_WIDTH / 2)(left) left = sp.left(DRAWER_INNER_WIDTH / 2)(left)
left = sp.up(DRAWER_INNER_DEPTH / 2)(left) left = sp.up(DRAWER_INNER_DEPTH / 2)(left)
left = sp.color(COLOR_LEFT)(left)
right = _gen_side() right = _gen_side()
right = sp.rotateY(90)(right) right = sp.rotateY(90)(right)
right = sp.right(DRAWER_INNER_WIDTH / 2)(right) right = sp.right(DRAWER_INNER_WIDTH / 2)(right)
right = sp.up(DRAWER_INNER_DEPTH / 2)(right) right = sp.up(DRAWER_INNER_DEPTH / 2)(right)
right = sp.color(COLOR_RIGHT)(right)
bottom = _gen_bottom() back = _gen_back()
bottom = sp.down(FLOOR_THICKNESS)(bottom) back = sp.rotateX(90)(back)
bottom = sp.color((0.2, 0.2, 0.2))(bottom) back = sp.back(DRAWER_INNER_LENGTH/2)(back)
back = sp.up(DRAWER_INNER_DEPTH / 2)(back)
back = sp.color(COLOR_BACK)(back)
top = _gen_top()
top = sp.up(DRAWER_INNER_DEPTH)(top)
top = sp.back(DRAWER_OUTER_LENGTH*TOP_LID_RATIO/2)(top)
top = sp.color(COLOR_TOP)(top)
lid = _gen_lid_at_hinge()
lid = sp.up(DRAWER_INNER_DEPTH + LID_THICKNESS)(lid)
lid = sp.forward(DRAWER_OUTER_LENGTH * (.5 - TOP_LID_RATIO))(lid)
lid = sp.color(COLOR_LID)(lid)
rails = _gen_spool_rails() rails = _gen_spool_rails()
final = sp.union()(left, right, bottom, rails) final = sp.union()(bottom, left, right, back, top, lid, rails)
final = sp.up(FLOOR_THICKNESS)(final) final = sp.up(FLOOR_THICKNESS)(final)
return final return final