commit 0d68751a78f7bdc115e4881e6dc3f998971f998b Author: Diogo Cruz Diniz Date: Sun Jul 19 18:33:58 2026 +0100 chore: Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73a1085 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +out.scad +**__pycache__/ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..1325ff2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,36 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "spoolstore" +version = "0.1.0" +authors = [{ name = "Didas72" }] +requires-python = ">=3.9" +dependencies = [ "solidpython2", "libdsps" ] + +[tool.ruff] +line-length = 120 +indent-width = 4 + +[tool.ruff.lint] +select = ["ALL"] +ignore = [ + # Conflicting + "D203", + "D212", + "COM812", + + # Allow 'TODO' and 'HACK' in code + "FIX002", + "TD002", + "TD003", + "FIX004", +] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" + +[tool.mypy] +strict = true diff --git a/spoolstore/__init__.py b/spoolstore/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/spoolstore/__main__.py b/spoolstore/__main__.py new file mode 100644 index 0000000..ef56b82 --- /dev/null +++ b/spoolstore/__main__.py @@ -0,0 +1,13 @@ +# noqa: D100 + +from solid2 import scad_render_to_file + +from spoolstore.poc import gen_drawer + + +def _main() -> None: + drawer = gen_drawer() + scad_render_to_file(drawer, "out.scad") + +if __name__ == "__main__": + _main() diff --git a/spoolstore/poc.py b/spoolstore/poc.py new file mode 100644 index 0000000..6004114 --- /dev/null +++ b/spoolstore/poc.py @@ -0,0 +1,119 @@ +"""Proof of concept models for SpoolStore.""" + +import solid2 as sp +from libdsps.grids import hex_grid +from libdsps.shapes import rect_frame + +DRAWER_INNER_WIDTH = 220 +DRAWER_INNER_LENGTH = 270 +DRAWER_INNER_FLOOR_THICKNESS = 3 +DRAWER_INNER_DEPTH = 75 + +SPOOL_OUTER_D = 200 +SPOOL_INNER_D = 55 + +SPOOLPIN_FRONT_OFFSET = 110 +SPOOLPIN_D = SPOOL_INNER_D - 10 +SPOOLPIN_HEIGHT = 20 +SPOOLPIN_RAISE = 5 + +SPLITTER_THICKNESS = 3 +SPLITTER_FRONT_OFFSET = 220 + +LID_THICKNESS = 3 +SIDE_THICKNESS = 3 + +FRAME_MARGIN = 8 +GRID_STRIDE = 38 +GRID_FILL_RATIO = 0.08 + +XX = 2 + + +def _gen_hex_frame( + 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) + hex_frame = sp.union()(frame, grid) + return hex_frame + + +def _gen_spool_holder() -> sp.OpenSCADObjectPlus: + spool_raise = sp.cylinder(d=SPOOL_OUTER_D, h=SPOOLPIN_RAISE, center=False) + pin = sp.cylinder(d=SPOOLPIN_D, h=SPOOLPIN_HEIGHT, center=False) + 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 + + +def _gen_splitter() -> sp.OpenSCADObjectPlus: + splitter = sp.cube([DRAWER_INNER_WIDTH - SIDE_THICKNESS * 2, SPLITTER_THICKNESS, DRAWER_INNER_DEPTH], center=True) + splitter = sp.up(DRAWER_INNER_DEPTH / 2)(splitter) + + mask = sp.cube( + [ + DRAWER_INNER_WIDTH - SIDE_THICKNESS * 2 - FRAME_MARGIN * 2, + SPLITTER_THICKNESS + XX, + 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: + return _gen_hex_frame( + DRAWER_INNER_DEPTH, DRAWER_INNER_LENGTH, SIDE_THICKNESS, FRAME_MARGIN, GRID_STRIDE, GRID_FILL_RATIO + ) + +#def _gen_back() + + +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 = sp.rotateY(90)(left) + left = sp.up(DRAWER_INNER_DEPTH / 2)(left) + left = sp.left(-DRAWER_INNER_WIDTH / 2 + SIDE_THICKNESS)(left) + + right = _gen_side() + right = sp.rotateY(-90)(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)( + sp.union()(sp.down(DRAWER_INNER_FLOOR_THICKNESS)(inner_floor), spool_holder, splitter, top, left, right) + ) + + return drawer