Cosplay/nhf/test.py

168 lines
5.1 KiB
Python

"""
Unit tests for tooling
"""
import unittest
import cadquery as Cq
from nhf.build import Model, target
import nhf.checks
import nhf.utils
# Color presets for testing purposes
color_parent = Cq.Color(0.7, 0.7, 0.5, 0.5)
color_child = Cq.Color(0.5, 0.7, 0.7, 0.5)
def makeSphere(r: float) -> Cq.Solid:
"""
Makes a full sphere. The default function makes a hemisphere
"""
return Cq.Solid.makeSphere(r, angleDegrees1=-90)
class BuildScaffold(Model):
def __init__(self):
super().__init__(name="scaffold")
@target(name="obj1")
def o1(self):
return Cq.Solid.makeBox(10, 10, 10)
def o2(self):
return Cq.Solid.makeCylinder(10, 20)
class TestBuild(unittest.TestCase):
def test_build_scaffold(self):
s = BuildScaffold()
names = ["obj1"]
self.assertEqual(s.target_names, names)
self.assertEqual(s.check_all(), len(names))
class TestChecks(unittest.TestCase):
def intersect_test_case(self, offset):
assembly = (
Cq.Assembly()
.add(Cq.Solid.makeBox(10, 10, 10),
name="c1",
loc=Cq.Location((0, 0, 0)))
.add(Cq.Solid.makeBox(10, 10, 10),
name="c2",
loc=Cq.Location((0, 0, offset)))
)
coll = nhf.checks.pairwise_intersection(assembly)
if -10 < offset and offset < 10:
self.assertEqual(len(coll), 1)
else:
self.assertEqual(coll, [])
def test_intersect(self):
for offset in [9, 10, 11, -10]:
with self.subTest(offset=offset):
self.intersect_test_case(offset)
class TestUtils(unittest.TestCase):
def test_2d_orientation(self):
l1 = Cq.Location.from2d(1.2, 0)
l2 = Cq.Location.from2d(0, 0, 90)
l3 = l2 * l1
(x, y), r = l3.to2d()
self.assertAlmostEqual(x, 0)
self.assertAlmostEqual(y, 1.2)
self.assertAlmostEqual(r, 90)
def test_2d_planar(self):
l1 = Cq.Location.from2d(1.2, 4.5, 67)
l2 = Cq.Location.from2d(98, 5.4, 36)
l3 = Cq.Location.from2d(10, 10, 0)
l = l3 * l2 * l1
self.assertTrue(l.is2d())
def test_tag_point(self):
"""
A board with 3 holes of unequal sizes. Each hole is marked
"""
p4x, p4y = 5, 5
p3x, p3y = 0, 0
p2x, p2y = -5, 0
board = (
Cq.Workplane('XY')
.box(15, 15, 5)
.faces("<Z")
.workplane()
.pushPoints([(p4x, p4y)])
.hole(4, depth=2)
.pushPoints([(p3x, p3y)])
.hole(3, depth=1.5)
.pushPoints([(p2x, p2y)])
.hole(2, depth=1)
)
board.moveTo(p4x, p4y).tagPoint("h4")
board.moveTo(p3x, p3y).tagPoint("h3")
board.moveTo(p2x, p2y).tagPoint("h2")
assembly = (
Cq.Assembly()
.add(board, name="board", color=color_parent)
.add(makeSphere(2), name="s4", color=color_child)
.add(makeSphere(1.5), name="s3", color=color_child)
.add(makeSphere(1), name="s2", color=color_child)
.constrain("board?h4", "s4", "Point")
.constrain("board?h3", "s3", "Point")
.constrain("board?h2", "s2", "Point")
.solve()
)
self.assertEqual(nhf.checks.pairwise_intersection(assembly), [])
bbox = assembly.toCompound().BoundingBox()
self.assertAlmostEqual(bbox.xlen, 15)
self.assertAlmostEqual(bbox.ylen, 15)
self.assertAlmostEqual(bbox.zlen, 7)
def test_tag_plane(self):
p4x, p4y = 5, 5
p3x, p3y = 0, 0
p2x, p2y = -5, 0
board = (
Cq.Workplane('XY')
.box(15, 15, 5)
.faces("<Z")
.workplane()
.pushPoints([(p4x, p4y)])
.hole(4, depth=2)
.pushPoints([(p3x, p3y)])
.hole(3, depth=1.5)
.pushPoints([(p2x, p2y)])
.hole(2, depth=1)
)
board.moveTo(p4x, p4y).tagPlane("h4")
board.moveTo(p3x, p3y).tagPlane("h3")
board.moveTo(p2x, p2y).tagPlane("h2")
def markedCylOf(r):
cyl = (
Cq.Workplane('XY')
.cylinder(radius=r, height=r)
)
cyl.faces("<Z").tag("mate")
return cyl
assembly = (
Cq.Assembly()
.add(board, name="board", color=color_parent)
.add(markedCylOf(2), name="c4", color=color_child)
.add(markedCylOf(1.5), name="c3", color=color_child)
.add(markedCylOf(1), name="c2", color=color_child)
.constrain("board?h4", "c4?mate", "Plane", param=0)
.constrain("board?h3", "c3?mate", "Plane", param=0)
.constrain("board?h2", "c2?mate", "Plane", param=0)
.solve()
)
self.assertEqual(nhf.checks.pairwise_intersection(assembly), [])
bbox = assembly.toCompound().BoundingBox()
self.assertAlmostEqual(bbox.xlen, 15)
self.assertAlmostEqual(bbox.ylen, 15)
self.assertAlmostEqual(bbox.zlen, 5)
if __name__ == '__main__':
unittest.main()