From 5bceb6180e31b86b2397d78a642e69f557224c08 Mon Sep 17 00:00:00 2001 From: Leni Aniva Date: Thu, 4 Jul 2024 00:42:14 -0700 Subject: [PATCH] refactor: Move parts into nhf.parts --- nhf/build.py | 16 ++++++-- nhf/parts/__init__.py | 0 nhf/{ => parts}/handle.py | 10 ++--- nhf/{ => parts}/joints.py | 6 +-- nhf/{ => parts}/metric_threads.py | 0 nhf/{ => parts}/springs.py | 0 nhf/parts/test.py | 59 ++++++++++++++++++++++++++++++ nhf/primitive.py | 12 ------ nhf/test.py | 61 +++++++------------------------ nhf/touhou/houjuu_nue/__init__.py | 6 +-- nhf/touhou/houjuu_nue/trident.py | 2 +- nhf/touhou/houjuu_nue/wing.py | 2 +- 12 files changed, 97 insertions(+), 77 deletions(-) create mode 100644 nhf/parts/__init__.py rename nhf/{ => parts}/handle.py (96%) rename nhf/{ => parts}/joints.py (99%) rename nhf/{ => parts}/metric_threads.py (100%) rename nhf/{ => parts}/springs.py (100%) create mode 100644 nhf/parts/test.py delete mode 100644 nhf/primitive.py diff --git a/nhf/build.py b/nhf/build.py index f11b9c8..5da3d01 100644 --- a/nhf/build.py +++ b/nhf/build.py @@ -29,9 +29,11 @@ class Target: """ def g(): for name in dir(subject): + if name == 'target_names': + continue method = getattr(subject, name) - if hasattr(method, 'target'): - yield method.target + if hasattr(method, '_target'): + yield method._target return {method.name: method for method in g()} @@ -43,7 +45,7 @@ def target(name, **deco_kwargs): @wraps(method) def wrapper(self, *args, **kwargs): return method(self, *args, **kwargs) - wrapper.target = Target(method, name, **deco_kwargs) + wrapper._target = Target(method, name, **deco_kwargs) return wrapper return f @@ -60,12 +62,20 @@ class Model: Base class for a parametric assembly """ + @property def target_names(self) -> list[str]: """ List of decorated target functions """ return list(Target.methods(self).keys()) + def check_all(self) -> int: + total = 0 + for k, f in Target.methods(self).items(): + f(self) + total += 1 + return total + def build_all(self, output_dir: Union[Path, str] ="build", verbose=1): """ Build all targets in this model diff --git a/nhf/parts/__init__.py b/nhf/parts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nhf/handle.py b/nhf/parts/handle.py similarity index 96% rename from nhf/handle.py rename to nhf/parts/handle.py index 36c41a7..c6845ef 100644 --- a/nhf/handle.py +++ b/nhf/parts/handle.py @@ -3,7 +3,7 @@ This schematics file contains all designs related to tool handles """ from dataclasses import dataclass import cadquery as Cq -import nhf.metric_threads as NMt +import nhf.parts.metric_threads as metric_threads @dataclass class Handle: @@ -50,7 +50,7 @@ class Handle: @property def diam_insertion_internal(self): - r = NMt.metric_thread_major_radius( + r = metric_threads.metric_thread_major_radius( self.diam_threading, self.thread_pitch, internal=True) @@ -58,7 +58,7 @@ class Handle: @property def diam_connector_external(self): - r = NMt.metric_thread_minor_radius( + r = metric_threads.metric_thread_minor_radius( self.diam_threading, self.thread_pitch) return r * 2 @@ -77,13 +77,13 @@ class Handle: def _external_thread(self, length=None): if length is None: length = self.insertion_length - return NMt.external_metric_thread( + return metric_threads.external_metric_thread( self.diam_threading, self.thread_pitch, length, top_lead_in=True) def _internal_thread(self): - return NMt.internal_metric_thread( + return metric_threads.internal_metric_thread( self.diam_threading, self.thread_pitch, self.insertion_length) diff --git a/nhf/joints.py b/nhf/parts/joints.py similarity index 99% rename from nhf/joints.py rename to nhf/parts/joints.py index f8e5f8f..286776d 100644 --- a/nhf/joints.py +++ b/nhf/parts/joints.py @@ -1,7 +1,7 @@ from dataclasses import dataclass import math import cadquery as Cq -import nhf.springs as NS +import nhf.parts.springs as springs from nhf import Role @dataclass @@ -209,7 +209,7 @@ def comma_joint(radius=30, def comma_assembly(): joint1 = comma_joint() joint2 = comma_joint() - spring = NS.torsion_spring() + spring = springs.torsion_spring() result = ( Cq.Assembly() .add(joint1, name="joint1", color=Cq.Color(0.8,0.8,0.5,0.3)) @@ -298,7 +298,7 @@ class TorsionJoint: def spring(self): - return NS.torsion_spring( + return springs.torsion_spring( radius=self.radius_spring, height=self.spring_height, thickness=self.spring_thickness, diff --git a/nhf/metric_threads.py b/nhf/parts/metric_threads.py similarity index 100% rename from nhf/metric_threads.py rename to nhf/parts/metric_threads.py diff --git a/nhf/springs.py b/nhf/parts/springs.py similarity index 100% rename from nhf/springs.py rename to nhf/parts/springs.py diff --git a/nhf/parts/test.py b/nhf/parts/test.py new file mode 100644 index 0000000..d1e1768 --- /dev/null +++ b/nhf/parts/test.py @@ -0,0 +1,59 @@ +import unittest +import cadquery as Cq +from nhf.checks import binary_intersection +import nhf.parts.joints as joints +import nhf.parts.handle as handle +import nhf.parts.metric_threads as metric_threads + +class TestJoints(unittest.TestCase): + + def test_joint_hirth(self): + j = joints.HirthJoint() + obj = j.generate() + self.assertIsInstance( + obj.val().solids(), Cq.Solid, + msg="Hirth joint must be in one piece") + + def test_joints_hirth_assembly(self): + for n_tooth in [16, 20, 24]: + with self.subTest(n_tooth=n_tooth): + j = joints.HirthJoint() + assembly = j.assembly() + isect = binary_intersection(assembly) + self.assertLess(isect.Volume(), 1e-6, + "Hirth joint assembly must not have intersection") + def test_joints_comma_assembly(self): + joints.comma_assembly() + def test_torsion_joint(self): + j = joints.TorsionJoint() + assembly = j.rider_track_assembly() + bbox = assembly.toCompound().BoundingBox() + self.assertAlmostEqual(bbox.zlen, j.total_height) + + +class TestHandle(unittest.TestCase): + + def test_handle_assembly(self): + h = handle.Handle() + assembly = h.connector_insertion_assembly() + bbox = assembly.toCompound().BoundingBox() + self.assertAlmostEqual(bbox.xlen, h.diam) + self.assertAlmostEqual(bbox.ylen, h.diam) + assembly = h.connector_one_side_insertion_assembly() + bbox = assembly.toCompound().BoundingBox() + self.assertAlmostEqual(bbox.xlen, h.diam) + self.assertAlmostEqual(bbox.ylen, h.diam) + + +class TestMetricThreads(unittest.TestCase): + + def test_major_radius(self): + major = 3.0 + t = metric_threads.external_metric_thread(major, 0.5, 4.0, z_start= -0.85, top_lead_in=True) + bbox = t.val().BoundingBox() + self.assertAlmostEqual(bbox.xlen, major, places=3) + self.assertAlmostEqual(bbox.ylen, major, places=3) + + +if __name__ == '__main__': + unittest.main() diff --git a/nhf/primitive.py b/nhf/primitive.py deleted file mode 100644 index 35e1565..0000000 --- a/nhf/primitive.py +++ /dev/null @@ -1,12 +0,0 @@ -import cadquery as Cq - -def mystery(): - return ( - Cq.Workplane("XY") - .box(10, 5, 5) - .faces(">Z") - .workplane() - .hole(1) - .edges("|Z") - .fillet(2) - ) diff --git a/nhf/test.py b/nhf/test.py index 4f97602..c6e94a6 100644 --- a/nhf/test.py +++ b/nhf/test.py @@ -1,58 +1,23 @@ import unittest import cadquery as Cq -import nhf.joints -import nhf.handle -import nhf.metric_threads as NMt -from nhf.checks import binary_intersection +from nhf.build import Model, target -class TestJoints(unittest.TestCase): +class BuildScaffold(Model): - def test_joint_hirth(self): - j = nhf.joints.HirthJoint() - obj = j.generate() - self.assertIsInstance( - obj.val().solids(), Cq.Solid, - msg="Hirth joint must be in one piece") + @target(name="obj1") + def o1(self): + return Cq.Solid.makeBox(10, 10, 10) - def test_joints_hirth_assembly(self): - for n_tooth in [16, 20, 24]: - with self.subTest(n_tooth=n_tooth): - j = nhf.joints.HirthJoint() - assembly = j.assembly() - isect = binary_intersection(assembly) - self.assertLess(isect.Volume(), 1e-6, - "Hirth joint assembly must not have intersection") - def test_joints_comma_assembly(self): - nhf.joints.comma_assembly() - def test_torsion_joint(self): - j = nhf.joints.TorsionJoint() - assembly = j.rider_track_assembly() - bbox = assembly.toCompound().BoundingBox() - self.assertAlmostEqual(bbox.zlen, j.total_height) + def o2(self): + return Cq.Solid.makeCylinder(10, 20) +class TestBuild(unittest.TestCase): -class TestHandle(unittest.TestCase): - - def test_handle_assembly(self): - h = nhf.handle.Handle() - assembly = h.connector_insertion_assembly() - bbox = assembly.toCompound().BoundingBox() - self.assertAlmostEqual(bbox.xlen, h.diam) - self.assertAlmostEqual(bbox.ylen, h.diam) - assembly = h.connector_one_side_insertion_assembly() - bbox = assembly.toCompound().BoundingBox() - self.assertAlmostEqual(bbox.xlen, h.diam) - self.assertAlmostEqual(bbox.ylen, h.diam) - - -class TestMetricThreads(unittest.TestCase): - - def test_major_radius(self): - major = 3.0 - t = NMt.external_metric_thread(major, 0.5, 4.0, z_start= -0.85, top_lead_in=True) - bbox = t.val().BoundingBox() - self.assertAlmostEqual(bbox.xlen, major, places=3) - self.assertAlmostEqual(bbox.ylen, major, places=3) + def test_build_scaffold(self): + s = BuildScaffold() + names = ["obj1"] + self.assertEqual(s.target_names, names) + self.assertEqual(s.check_all(), len(names)) if __name__ == '__main__': diff --git a/nhf/touhou/houjuu_nue/__init__.py b/nhf/touhou/houjuu_nue/__init__.py index 3d00652..37a91a4 100644 --- a/nhf/touhou/houjuu_nue/__init__.py +++ b/nhf/touhou/houjuu_nue/__init__.py @@ -32,12 +32,10 @@ shoulder, elbow, wrist in analogy with human anatomy. from dataclasses import dataclass, field import unittest import cadquery as Cq -import nhf.joints -import nhf.handle from nhf import Material -from nhf.joints import HirthJoint -from nhf.handle import Handle from nhf.build import Model, target +from nhf.parts.joints import HirthJoint +from nhf.parts.handle import Handle import nhf.touhou.houjuu_nue.wing as MW import nhf.touhou.houjuu_nue.trident as MT diff --git a/nhf/touhou/houjuu_nue/trident.py b/nhf/touhou/houjuu_nue/trident.py index 71901ab..312ff85 100644 --- a/nhf/touhou/houjuu_nue/trident.py +++ b/nhf/touhou/houjuu_nue/trident.py @@ -1,7 +1,7 @@ import math import cadquery as Cq from nhf import Material -from nhf.handle import Handle +from nhf.parts.handle import Handle def trident_assembly( handle: Handle, diff --git a/nhf/touhou/houjuu_nue/wing.py b/nhf/touhou/houjuu_nue/wing.py index 04de65a..224183d 100644 --- a/nhf/touhou/houjuu_nue/wing.py +++ b/nhf/touhou/houjuu_nue/wing.py @@ -4,7 +4,7 @@ This file describes the shapes of the wing shells. The joints are defined in """ import math import cadquery as Cq -from nhf.joints import HirthJoint +from nhf.parts.joints import HirthJoint def wing_root_profiles( base_sweep=150,