tool: Light panel #9

Open
aniva wants to merge 7 commits from tool/lighting into main
3 changed files with 130 additions and 3 deletions

View File

@ -90,7 +90,7 @@ class Target:
x = ( x = (
Cq.Workplane() Cq.Workplane()
.add(x._faces) .add(x._faces)
.add(x._wires) .add(x.wires)
.add(x._edges) .add(x._edges)
) )
assert isinstance(x, Cq.Workplane) assert isinstance(x, Cq.Workplane)
@ -214,7 +214,7 @@ class Submodel:
def write_to(self, obj, path: str): def write_to(self, obj, path: str):
x = self._method(obj) x = self._method(obj)
assert isinstance(x, Model), f"Unexpected type: {type(x)}" assert isinstance(x, Model), f"Unexpected type: {type(x)}"
x.build_all(path) x.build_all(path, prefix=False)
@classmethod @classmethod
def methods(cls, subject): def methods(cls, subject):
@ -271,11 +271,17 @@ class Model:
total += 1 total += 1
return total return total
def build_all(self, output_dir: Union[Path, str] = "build", verbose=1): def build_all(
self,
output_dir: Union[Path, str] = "build",
prefix: bool = True,
verbose=1):
""" """
Build all targets in this model and write the results to file Build all targets in this model and write the results to file
""" """
output_dir = Path(output_dir) output_dir = Path(output_dir)
if prefix:
output_dir = output_dir / self.name
targets = Target.methods(self) targets = Target.methods(self)
for t in targets.values(): for t in targets.values():
file_name = t.file_name file_name = t.file_name

0
nhf/tool/__init__.py Normal file
View File

121
nhf/tool/light_panel.py Normal file
View File

@ -0,0 +1,121 @@
from dataclasses import dataclass
import cadquery as Cq
from nhf import Material, Role
from nhf.build import Model, target, assembly, TargetKind, submodel
from nhf.parts.box import MountingBox, Hole
from nhf.parts.electronics import ArduinoUnoR3
import nhf.utils
@dataclass
class LightPanel(Model):
# Dimensions of the base panel
length: float = 300.0
width: float = 200.0
grid_height: float = 30.0
grid_top_height: float = 5.0
# Distance from grid to edge
grid_margin: float = 20.0
# Number of holes in each row of the grid
grid_holes: int = 9
grid_layers: int = 6
grid_hole_width: float = 15.0
base_thickness: float = 25.4/16
grid_thickness: float = 25.4/4
base_material: Material = Material.WOOD_BIRCH
grid_material: Material = Material.ACRYLIC_TRANSPARENT
controller: ArduinoUnoR3 = ArduinoUnoR3()
def __post_init__(self):
assert self.grid_holes >= 2
super().__init__(name="light-panel")
@target(name="grid", kind=TargetKind.DXF)
def grid_profile(self):
w = self.length - self.grid_margin * 2
h = self.grid_height + self.grid_top_height
# The width of one hole (w0) satisfies
# n * w0 + (n+1) t = w
# where t is the thickness of the edge
n = self.grid_holes
w0 = self.grid_hole_width
t = (w - n * w0) / (n + 1)
# The spacing is such that the first and last holes are a distance `margin`
# away from the edges, so it satisfies
# t + w0/2 + (n-1) * s + w0/2 + t = w
step = (w - t*2 - w0) / (n - 1)
return (
Cq.Sketch()
.push([(0, h/2)])
.rect(w, h)
.push([
(i * step + t + w0/2 - w/2, self.grid_height/2)
for i in range(0, n)
])
.rect(w0, self.grid_height, mode='s')
)
def grid(self) -> Cq.Workplane:
return (
Cq.Workplane('XY')
.placeSketch(self.grid_profile())
.extrude(self.grid_thickness)
)
@submodel(name="base")
def base(self) -> MountingBox:
xshift = self.length / 2 - self.controller.length - self.grid_margin / 2
yshift = self.grid_margin / 2
holes = [
Hole(
x=x + xshift, y=y + yshift,
diam=self.controller.hole_diam,
tag=f"controller_conn{i}",
)
for i, (x, y) in enumerate(self.controller.holes)
]
return MountingBox(
holes=holes,
hole_diam=self.controller.hole_diam,
length=self.length,
width=self.width,
centred=(True, False),
thickness=self.base_thickness,
)
def assembly(self) -> Cq.Assembly:
assembly = (
Cq.Assembly()
.addS(
self.base().generate(),
name="base",
role=Role.STRUCTURE,
material=self.base_material,
)
)
# Grid thickness t is fixed, so the spacing of the grid satisfies
# margin + t + (n-1) * spacing + margin = width
spacing = (self.width - 2 * self.grid_margin - self.grid_thickness) / (self.grid_layers - 1)
shift = self.grid_margin + self.grid_thickness / 2
for i in range(self.grid_layers):
assembly = assembly.addS(
self.grid(),
name=f"grid_{i}",
role=Role.STRUCTURE,
material=self.grid_material,
loc=Cq.Location(0, spacing * i + shift, self.base_thickness, 90, 0, 0),
)
return assembly
if __name__ == '__main__':
import sys
p = LightPanel()
if len(sys.argv) == 1:
p.build_all()
sys.exit(0)