"""Proof of concept models for SpoolStore.""" from math import cos, radians, sin import solid2 as sp from libdsps.grids import hex_grid from libdsps.shapes import rect_frame DRAWER_INNER_WIDTH = 75 DRAWER_INNER_LENGTH = 240 DRAWER_INNER_DEPTH = 220 SPOOL_OUTER_D = 200 SPOOL_INNER_D = 55 SPOOL_WIDTH = 67 SPOOL_SIDE_THICK = 3.5 LID_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 GRID_STRIDE = 38 GRID_FILL_RATIO = 0.08 XX = .1 def _gen_hex_frame( # noqa: PLR0913 width: float, length: float, height: float, frame_size: float, stride: float, fill_ratio: float ) -> sp.OpenSCADObjectPlus: frame = rect_frame(width, length, height, frame_size) grid = hex_grid(width - frame_size * 2, length - frame_size * 2, height, stride, fill_ratio) return sp.union()(frame, grid) def _gen_spool(color: sp.Vec3 = (0, 1, 0), alpha: float = .3) -> sp.OpenSCADObjectPlus: side = sp.cylinder(h=SPOOL_SIDE_THICK, d=SPOOL_OUTER_D, _fn=36, center=True) side = sp.rotateY(90)(side) left = sp.left(SPOOL_WIDTH / 2 - SPOOL_SIDE_THICK/2)(side) right = sp.right(SPOOL_WIDTH / 2 - SPOOL_SIDE_THICK/2)(side) core = sp.cylinder(h=SPOOL_WIDTH - SPOOL_SIDE_THICK * 2, d=SPOOL_INNER_D, center=True) core = sp.rotateY(90)(core) spool = sp.union()(left, right, core) spool = sp.up(SPOOL_OUTER_D / 2)(spool) spool = sp.color(color, alpha)(spool) return spool def _gen_side() -> sp.OpenSCADObjectPlus: face = _gen_hex_frame( DRAWER_INNER_DEPTH, DRAWER_INNER_LENGTH, SIDE_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO ) return face 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: left = _gen_side() left = sp.rotateY(-90)(left) left = sp.left(DRAWER_INNER_WIDTH / 2)(left) left = sp.up(DRAWER_INNER_DEPTH / 2)(left) right = _gen_side() right = sp.rotateY(90)(right) right = sp.right(DRAWER_INNER_WIDTH / 2)(right) right = sp.up(DRAWER_INNER_DEPTH / 2)(right) bottom = _gen_bottom() bottom = sp.down(FLOOR_THICKNESS)(bottom) bottom = sp.color((0.2, 0.2, 0.2))(bottom) rails = _gen_spool_rails() final = sp.union()(left, right, bottom, rails) final = sp.up(FLOOR_THICKNESS)(final) return final