From ca437c385531cfb205ca06bf3a14d8a1ded2b826 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Fri, 6 Dec 2024 16:40:07 -0800 Subject: [PATCH 1/7] feat: Light panel layer --- nhf/tool/__init__.py | 0 nhf/tool/light_panel.py | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 nhf/tool/__init__.py create mode 100644 nhf/tool/light_panel.py diff --git a/nhf/tool/__init__.py b/nhf/tool/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nhf/tool/light_panel.py b/nhf/tool/light_panel.py new file mode 100644 index 0000000..81c2942 --- /dev/null +++ b/nhf/tool/light_panel.py @@ -0,0 +1,54 @@ +from dataclasses import dataclass +import cadquery as Cq +from nhf import Material, Role +from nhf.build import Model, target, assembly, TargetKind +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 = 10.0 + # Distance from grid to edge + grid_margin: float = 20.0 + # Number of holes in each row of the grid + grid_holes: int = 5 + grid_layers: int = 10 + grid_hole_width: float = 10.0 + + base_thickness: float = 25.4/16 + grid_thickness: float = 25.4/8 + + def __post_init__(self): + assert self.grid_holes >= 2 + super().__init__(name="crown") + + @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 `t` + # 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') + ) From 3884d75f1ce797571dff8eccdf729ba6029eb57d Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Fri, 6 Dec 2024 16:43:12 -0800 Subject: [PATCH 2/7] chore: Add build function --- nhf/tool/light_panel.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nhf/tool/light_panel.py b/nhf/tool/light_panel.py index 81c2942..1818b17 100644 --- a/nhf/tool/light_panel.py +++ b/nhf/tool/light_panel.py @@ -52,3 +52,12 @@ class LightPanel(Model): ]) .rect(w0, self.grid_height, mode='s') ) + + +if __name__ == '__main__': + import sys + + p = LightPanel() + if len(sys.argv) == 1: + p.build_all() + sys.exit(0) From d1fd8307661c34fa856e07ba1252e184c6bb4c99 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Sat, 7 Dec 2024 12:09:41 -0800 Subject: [PATCH 3/7] feat: Light panel assembly --- nhf/tool/light_panel.py | 66 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/nhf/tool/light_panel.py b/nhf/tool/light_panel.py index 1818b17..86d9983 100644 --- a/nhf/tool/light_panel.py +++ b/nhf/tool/light_panel.py @@ -1,7 +1,9 @@ from dataclasses import dataclass import cadquery as Cq from nhf import Material, Role -from nhf.build import Model, target, assembly, TargetKind +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 @@ -16,12 +18,16 @@ class LightPanel(Model): # Distance from grid to edge grid_margin: float = 20.0 # Number of holes in each row of the grid - grid_holes: int = 5 - grid_layers: int = 10 - grid_hole_width: float = 10.0 + 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/8 + base_material: Material = Material.WOOD_BIRCH + grid_material: Material = Material.ACRYLIC_TRANSPARENT + + controller: ArduinoUnoR3 = ArduinoUnoR3() def __post_init__(self): assert self.grid_holes >= 2 @@ -38,7 +44,7 @@ class LightPanel(Model): 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 `t` + # 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) @@ -53,6 +59,56 @@ class LightPanel(Model): .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: + holes = [ + Hole( + x=x, y=y, + 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) * (t + spacing) + margin = width + spacing = (self.width - 2 * self.grid_margin - self.grid_thickness) / (self.grid_layers - 1) - self.grid_thickness + 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 From 418e6517a013c8fbffc31eb29e8f6612013b26ea Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Sat, 7 Dec 2024 13:44:35 -0800 Subject: [PATCH 4/7] fix: Sketch object attribute --- nhf/build.py | 2 +- nhf/tool/light_panel.py | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/nhf/build.py b/nhf/build.py index 106577c..4d4c6c2 100644 --- a/nhf/build.py +++ b/nhf/build.py @@ -90,7 +90,7 @@ class Target: x = ( Cq.Workplane() .add(x._faces) - .add(x._wires) + .add(x.wires) .add(x._edges) ) assert isinstance(x, Cq.Workplane) diff --git a/nhf/tool/light_panel.py b/nhf/tool/light_panel.py index 86d9983..631637f 100644 --- a/nhf/tool/light_panel.py +++ b/nhf/tool/light_panel.py @@ -14,7 +14,7 @@ class LightPanel(Model): width: float = 200.0 grid_height: float = 30.0 - grid_top_height: float = 10.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 @@ -23,7 +23,7 @@ class LightPanel(Model): grid_hole_width: float = 15.0 base_thickness: float = 25.4/16 - grid_thickness: float = 25.4/8 + grid_thickness: float = 25.4/4 base_material: Material = Material.WOOD_BIRCH grid_material: Material = Material.ACRYLIC_TRANSPARENT @@ -68,9 +68,11 @@ class LightPanel(Model): @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, y=y, + x=x + xshift, y=y + yshift, diam=self.controller.hole_diam, tag=f"controller_conn{i}", ) @@ -96,9 +98,9 @@ class LightPanel(Model): ) ) # Grid thickness t is fixed, so the spacing of the grid satisfies - # margin + t + (n-1) * (t + spacing) + margin = width - spacing = (self.width - 2 * self.grid_margin - self.grid_thickness) / (self.grid_layers - 1) - self.grid_thickness - shift = self.grid_margin + self.grid_thickness * 2 + # 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(), From 6470010da686fb864b4eb70fb6dc58b223783b39 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Sat, 7 Dec 2024 13:47:32 -0800 Subject: [PATCH 5/7] fix: Model name --- nhf/tool/light_panel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nhf/tool/light_panel.py b/nhf/tool/light_panel.py index 631637f..44c7920 100644 --- a/nhf/tool/light_panel.py +++ b/nhf/tool/light_panel.py @@ -31,7 +31,7 @@ class LightPanel(Model): def __post_init__(self): assert self.grid_holes >= 2 - super().__init__(name="crown") + super().__init__(name="light-panel") @target(name="grid", kind=TargetKind.DXF) def grid_profile(self): From 596311f326805c3b723d79079927837d7ce29486 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Thu, 23 Jan 2025 13:52:37 -0800 Subject: [PATCH 6/7] feat: Improve spacing --- nhf/tool/light_panel.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nhf/tool/light_panel.py b/nhf/tool/light_panel.py index 44c7920..82d7e5f 100644 --- a/nhf/tool/light_panel.py +++ b/nhf/tool/light_panel.py @@ -13,7 +13,7 @@ class LightPanel(Model): length: float = 300.0 width: float = 200.0 - grid_height: float = 30.0 + grid_height: float = 20.0 grid_top_height: float = 5.0 # Distance from grid to edge grid_margin: float = 20.0 @@ -33,6 +33,10 @@ class LightPanel(Model): assert self.grid_holes >= 2 super().__init__(name="light-panel") + @property + def grid_spacing_y(self) -> float: + return (self.width - 2 * self.grid_margin - self.grid_thickness) / (self.grid_layers - 1) + @target(name="grid", kind=TargetKind.DXF) def grid_profile(self): w = self.length - self.grid_margin * 2 @@ -99,7 +103,7 @@ class LightPanel(Model): ) # 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) + spacing = self.grid_spacing_y shift = self.grid_margin + self.grid_thickness / 2 for i in range(self.grid_layers): assembly = assembly.addS( @@ -116,6 +120,8 @@ if __name__ == '__main__': import sys p = LightPanel() + print(p.grid_spacing_y) + if len(sys.argv) == 1: p.build_all() sys.exit(0) From 9d78bf604acc54744357756d1a8bb24874cf35f3 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Tue, 28 Jan 2025 17:15:38 -0800 Subject: [PATCH 7/7] feat: Add tripod attachment point --- nhf/tool/light_panel.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/nhf/tool/light_panel.py b/nhf/tool/light_panel.py index 82d7e5f..646165e 100644 --- a/nhf/tool/light_panel.py +++ b/nhf/tool/light_panel.py @@ -13,6 +13,10 @@ class LightPanel(Model): length: float = 300.0 width: float = 200.0 + attach_height: float = 20.0 + attach_diam: float = 8.0 + attach_depth: float = 12.7 + grid_height: float = 20.0 grid_top_height: float = 5.0 # Distance from grid to edge @@ -91,6 +95,21 @@ class LightPanel(Model): thickness=self.base_thickness, ) + @target(name="attachment") + def attachment(self) -> Cq.Workplane: + l = self.length / 2 + w = self.width / 2 + return ( + Cq.Workplane('XY') + .box( + l, w, self.attach_height, + centered=(True, True, False), + ) + .faces(">Z") + .hole(self.attach_diam, self.attach_depth) + ) + + def assembly(self) -> Cq.Assembly: assembly = ( Cq.Assembly()