feat: Started move to vertical drawers
This commit is contained in:
@@ -1,119 +1,158 @@
|
|||||||
"""Proof of concept models for SpoolStore."""
|
"""Proof of concept models for SpoolStore."""
|
||||||
|
|
||||||
|
from math import cos, radians, sin
|
||||||
|
|
||||||
import solid2 as sp
|
import solid2 as sp
|
||||||
from libdsps.grids import hex_grid
|
from libdsps.grids import hex_grid
|
||||||
from libdsps.shapes import rect_frame
|
from libdsps.shapes import rect_frame
|
||||||
|
|
||||||
DRAWER_INNER_WIDTH = 220
|
DRAWER_INNER_WIDTH = 75
|
||||||
DRAWER_INNER_LENGTH = 270
|
DRAWER_INNER_LENGTH = 240
|
||||||
DRAWER_INNER_FLOOR_THICKNESS = 3
|
DRAWER_INNER_DEPTH = 220
|
||||||
DRAWER_INNER_DEPTH = 75
|
|
||||||
|
|
||||||
SPOOL_OUTER_D = 200
|
SPOOL_OUTER_D = 200
|
||||||
SPOOL_INNER_D = 55
|
SPOOL_INNER_D = 55
|
||||||
|
SPOOL_WIDTH = 67
|
||||||
SPOOLPIN_FRONT_OFFSET = 110
|
SPOOL_SIDE_THICK = 3.5
|
||||||
SPOOLPIN_D = SPOOL_INNER_D - 10
|
|
||||||
SPOOLPIN_HEIGHT = 20
|
|
||||||
SPOOLPIN_RAISE = 5
|
|
||||||
|
|
||||||
SPLITTER_THICKNESS = 3
|
|
||||||
SPLITTER_FRONT_OFFSET = 220
|
|
||||||
|
|
||||||
LID_THICKNESS = 3
|
LID_THICKNESS = 3
|
||||||
SIDE_THICKNESS = 3
|
SIDE_THICKNESS = 3
|
||||||
|
FLOOR_THICKNESS = 3
|
||||||
|
BACK_THICKNESS = 3
|
||||||
|
|
||||||
|
RAIL_RADIUS = 3
|
||||||
|
RAIL_FRONT_ANGLE = 20
|
||||||
|
RAIL_BACK_ANGLE = -40
|
||||||
|
RAIL_SUPPORT_THICKNESS = 4
|
||||||
|
RAIL_SUPPORT_EXTRA_RADIUS = 1
|
||||||
|
RAIL_SUPPORT_SIDE_MARGIN = 2
|
||||||
|
RAIL_WIDTH_MARGIN = 3
|
||||||
|
RAIL_SPOOL_HEIGHT = 5
|
||||||
|
RAIL_SPOOL_FRONT_DIST = 5
|
||||||
|
RAIL_PARKED_SPOOL = True
|
||||||
|
RAIL_CRITICAL_SPOOL = True
|
||||||
|
|
||||||
|
DRAWER_OUTER_WIDTH = DRAWER_INNER_WIDTH + SIDE_THICKNESS * 2
|
||||||
|
DRAWER_OUTER_LENGTH = DRAWER_INNER_LENGTH + LID_THICKNESS + BACK_THICKNESS
|
||||||
|
|
||||||
FRAME_MARGIN = 8
|
FRAME_MARGIN = 8
|
||||||
GRID_STRIDE = 38
|
GRID_STRIDE = 38
|
||||||
GRID_FILL_RATIO = 0.08
|
GRID_FILL_RATIO = 0.08
|
||||||
|
|
||||||
XX = 2
|
XX = .1
|
||||||
|
|
||||||
|
|
||||||
def _gen_hex_frame(
|
def _gen_hex_frame( # noqa: PLR0913
|
||||||
width: float, length: float, height: float, frame_size: float, stride: float, fill_ratio: float
|
width: float, length: float, height: float, frame_size: float, stride: float, fill_ratio: float
|
||||||
) -> sp.OpenSCADObjectPlus:
|
) -> sp.OpenSCADObjectPlus:
|
||||||
frame = rect_frame(width, length, height, frame_size)
|
frame = rect_frame(width, length, height, frame_size)
|
||||||
grid = hex_grid(width - frame_size * 2, length - frame_size * 2, height, stride, fill_ratio)
|
grid = hex_grid(width - frame_size * 2, length - frame_size * 2, height, stride, fill_ratio)
|
||||||
hex_frame = sp.union()(frame, grid)
|
return sp.union()(frame, grid)
|
||||||
return hex_frame
|
|
||||||
|
|
||||||
|
|
||||||
def _gen_spool_holder() -> sp.OpenSCADObjectPlus:
|
def _gen_spool(color: sp.Vec3 = (0, 1, 0), alpha: float = .3) -> sp.OpenSCADObjectPlus:
|
||||||
spool_raise = sp.cylinder(d=SPOOL_OUTER_D, h=SPOOLPIN_RAISE, center=False)
|
side = sp.cylinder(h=SPOOL_SIDE_THICK, d=SPOOL_OUTER_D, _fn=36, center=True)
|
||||||
pin = sp.cylinder(d=SPOOLPIN_D, h=SPOOLPIN_HEIGHT, center=False)
|
side = sp.rotateY(90)(side)
|
||||||
pin = sp.up(SPOOLPIN_RAISE)(pin)
|
|
||||||
spool_holder = sp.union()(pin, spool_raise)
|
|
||||||
spool_holder = sp.color((0.75, 0.5, 0.5))(spool_holder)
|
|
||||||
return spool_holder
|
|
||||||
|
|
||||||
|
left = sp.left(SPOOL_WIDTH / 2 - SPOOL_SIDE_THICK/2)(side)
|
||||||
|
right = sp.right(SPOOL_WIDTH / 2 - SPOOL_SIDE_THICK/2)(side)
|
||||||
|
|
||||||
def _gen_splitter() -> sp.OpenSCADObjectPlus:
|
core = sp.cylinder(h=SPOOL_WIDTH - SPOOL_SIDE_THICK * 2, d=SPOOL_INNER_D, center=True)
|
||||||
splitter = sp.cube([DRAWER_INNER_WIDTH - SIDE_THICKNESS * 2, SPLITTER_THICKNESS, DRAWER_INNER_DEPTH], center=True)
|
core = sp.rotateY(90)(core)
|
||||||
splitter = sp.up(DRAWER_INNER_DEPTH / 2)(splitter)
|
|
||||||
|
|
||||||
mask = sp.cube(
|
spool = sp.union()(left, right, core)
|
||||||
[
|
spool = sp.up(SPOOL_OUTER_D / 2)(spool)
|
||||||
DRAWER_INNER_WIDTH - SIDE_THICKNESS * 2 - FRAME_MARGIN * 2,
|
spool = sp.color(color, alpha)(spool)
|
||||||
SPLITTER_THICKNESS + XX,
|
return spool
|
||||||
DRAWER_INNER_DEPTH - FRAME_MARGIN + XX,
|
|
||||||
],
|
|
||||||
center=True,
|
|
||||||
)
|
|
||||||
mask = sp.up((DRAWER_INNER_DEPTH + FRAME_MARGIN + XX) / 2)(mask)
|
|
||||||
splitter = splitter - mask
|
|
||||||
|
|
||||||
splitter = sp.color((0.5, 0.75, 0.5))(splitter)
|
|
||||||
return splitter
|
|
||||||
|
|
||||||
|
|
||||||
def _gen_top() -> sp.OpenSCADObjectPlus:
|
|
||||||
lid = _gen_hex_frame(
|
|
||||||
DRAWER_INNER_WIDTH, SPLITTER_FRONT_OFFSET, LID_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO
|
|
||||||
)
|
|
||||||
lid = sp.forward(DRAWER_INNER_LENGTH / 2 - SPOOLPIN_FRONT_OFFSET)(lid)
|
|
||||||
|
|
||||||
frame = rect_frame(DRAWER_INNER_WIDTH, DRAWER_INNER_LENGTH - SPLITTER_FRONT_OFFSET, LID_THICKNESS, FRAME_MARGIN)
|
|
||||||
frame = sp.forward(-SPLITTER_FRONT_OFFSET / 2)(frame)
|
|
||||||
frame = sp.color((0.2, 0.2, 0.2))(frame)
|
|
||||||
|
|
||||||
top = sp.union()(frame, lid)
|
|
||||||
return top
|
|
||||||
|
|
||||||
|
|
||||||
def _gen_side() -> sp.OpenSCADObjectPlus:
|
def _gen_side() -> sp.OpenSCADObjectPlus:
|
||||||
return _gen_hex_frame(
|
face = _gen_hex_frame(
|
||||||
DRAWER_INNER_DEPTH, DRAWER_INNER_LENGTH, SIDE_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO
|
DRAWER_INNER_DEPTH, DRAWER_INNER_LENGTH, SIDE_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO
|
||||||
)
|
)
|
||||||
|
return face
|
||||||
|
|
||||||
#def _gen_back()
|
|
||||||
|
def _gen_bottom() -> sp.OpenSCADObjectPlus:
|
||||||
|
floor = sp.cube([DRAWER_OUTER_WIDTH, DRAWER_OUTER_LENGTH, FLOOR_THICKNESS], center=True)
|
||||||
|
floor = sp.up(FLOOR_THICKNESS / 2)(floor)
|
||||||
|
return floor
|
||||||
|
|
||||||
|
|
||||||
|
def _gen_rail() -> sp.OpenSCADObjectPlus:
|
||||||
|
rail = sp.cylinder(h=DRAWER_INNER_WIDTH - RAIL_WIDTH_MARGIN*2, r=RAIL_RADIUS, _fn=12, center=True)
|
||||||
|
rail = sp.rotateY(90)(rail)
|
||||||
|
return rail
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
b_y_off = sin(radians(RAIL_BACK_ANGLE)) * rail_pos_radius
|
||||||
|
b_z_off = (1-cos(radians(RAIL_BACK_ANGLE))) * rail_pos_radius - RAIL_RADIUS + RAIL_SPOOL_HEIGHT
|
||||||
|
|
||||||
|
back_rail = _gen_rail()
|
||||||
|
back_rail = sp.up(f_z_off)(back_rail)
|
||||||
|
back_rail = sp.forward(f_y_off)(back_rail)
|
||||||
|
|
||||||
|
front_rail = _gen_rail()
|
||||||
|
front_rail = sp.up(b_z_off)(front_rail)
|
||||||
|
front_rail = sp.forward(b_y_off)(front_rail)
|
||||||
|
|
||||||
|
rail_base = sp.cylinder(h=RAIL_SUPPORT_THICKNESS, r=RAIL_RADIUS+RAIL_SUPPORT_EXTRA_RADIUS, center=True)
|
||||||
|
rail_base = sp.rotateY(90)(rail_base)
|
||||||
|
back_rail_base = sp.up(b_z_off)(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.forward(f_y_off)(front_rail_base)
|
||||||
|
#TODO: Mid rail to reduce overlap with spool contents
|
||||||
|
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))
|
||||||
|
back_support = sp.hull()(back_rail_base, back_base)
|
||||||
|
front_support = sp.hull()(front_rail_base, front_base)
|
||||||
|
inter_support = sp.hull()(front_rail_base, back_rail_base)
|
||||||
|
rail_support = sp.union()(back_support, front_support, inter_support)
|
||||||
|
|
||||||
|
support_offset = SPOOL_WIDTH/2 - SPOOL_SIDE_THICK - RAIL_SUPPORT_THICKNESS/2 - RAIL_SUPPORT_SIDE_MARGIN
|
||||||
|
left_support = sp.left(support_offset)(rail_support)
|
||||||
|
right_support = sp.right(support_offset)(rail_support)
|
||||||
|
rail_supports = sp.union()(left_support, right_support)
|
||||||
|
|
||||||
|
critical_spool = _gen_spool((1, 0, 0), 0.3)
|
||||||
|
critical_spool = sp.up(f_z_off + RAIL_RADIUS)(critical_spool)
|
||||||
|
critical_spool = sp.forward(f_y_off)(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.forward(DRAWER_INNER_LENGTH/2 - SPOOL_OUTER_D/2 - RAIL_SPOOL_FRONT_DIST)(final)
|
||||||
|
return final
|
||||||
|
|
||||||
|
|
||||||
def gen_drawer() -> sp.OpenSCADObjectPlus:
|
def gen_drawer() -> sp.OpenSCADObjectPlus:
|
||||||
inner_floor = sp.cube([DRAWER_INNER_WIDTH, DRAWER_INNER_LENGTH, DRAWER_INNER_FLOOR_THICKNESS], center=True)
|
|
||||||
inner_floor = sp.up(DRAWER_INNER_FLOOR_THICKNESS / 2)(inner_floor)
|
|
||||||
|
|
||||||
spool_holder = _gen_spool_holder()
|
|
||||||
spool_holder = sp.forward(DRAWER_INNER_LENGTH / 2 - SPOOLPIN_FRONT_OFFSET)(spool_holder)
|
|
||||||
|
|
||||||
splitter = _gen_splitter()
|
|
||||||
splitter = sp.forward(DRAWER_INNER_LENGTH / 2 - SPLITTER_FRONT_OFFSET)(splitter)
|
|
||||||
|
|
||||||
top = _gen_top()
|
|
||||||
top = sp.up(DRAWER_INNER_DEPTH)(top)
|
|
||||||
|
|
||||||
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.up(DRAWER_INNER_DEPTH / 2)(left)
|
left = sp.up(DRAWER_INNER_DEPTH / 2)(left)
|
||||||
left = sp.left(-DRAWER_INNER_WIDTH / 2 + SIDE_THICKNESS)(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.up(DRAWER_INNER_DEPTH / 2)(right)
|
right = sp.up(DRAWER_INNER_DEPTH / 2)(right)
|
||||||
right = sp.right(-DRAWER_INNER_WIDTH / 2 + SIDE_THICKNESS)(right)
|
|
||||||
|
|
||||||
drawer = sp.up(DRAWER_INNER_FLOOR_THICKNESS)(
|
bottom = _gen_bottom()
|
||||||
sp.union()(sp.down(DRAWER_INNER_FLOOR_THICKNESS)(inner_floor), spool_holder, splitter, top, left, right)
|
bottom = sp.down(FLOOR_THICKNESS)(bottom)
|
||||||
)
|
bottom = sp.color((0.2, 0.2, 0.2))(bottom)
|
||||||
|
|
||||||
return drawer
|
rails = _gen_spool_rails()
|
||||||
|
|
||||||
|
final = sp.union()(left, right, bottom, rails)
|
||||||
|
final = sp.up(FLOOR_THICKNESS)(final)
|
||||||
|
return final
|
||||||
|
|||||||
Reference in New Issue
Block a user