diff --git a/src/build123d/topology.py b/src/build123d/topology.py index cf4be394..c6d27a14 100644 --- a/src/build123d/topology.py +++ b/src/build123d/topology.py @@ -1693,11 +1693,13 @@ def __sub__(self, other: Shape) -> Self: """cut shape from self operator -""" others = other if isinstance(other, (list, tuple)) else [other] - if not all([type(other)._dim == type(self)._dim for other in others]): - raise ValueError( - f"Only shapes with the same dimension can be subtracted " - f"not {type(self).__name__} and {type(other).__name__}" - ) + for _other in others: + if type(_other)._dim < type(self)._dim: + raise ValueError( + f"Only shapes with equal or greater dimension can be subtracted: " + f"not {type(self).__name__} ({type(self)._dim}D) and " + f"{type(_other).__name__} ({type(_other)._dim}D)" + ) new_shape = None if self.wrapped is None: diff --git a/tests/test_algebra.py b/tests/test_algebra.py index 71ebda56..844a295d 100644 --- a/tests/test_algebra.py +++ b/tests/test_algebra.py @@ -602,6 +602,54 @@ def test_sketch_and_empty(self): with self.assertRaises(ValueError): r = b & Sketch() + def test_1d_2d_minus(self): + line = Line((0, 0), (1, 1)) + rectangle = Rectangle(1, 1) + r = line - rectangle + vertices = r.vertices() + self.assertEquals(len(vertices), 2) + self.assertTupleAlmostEquals(vertices[0], (0.5, 0.5, 0.0), 6) + self.assertTupleAlmostEquals(vertices[1], (1.0, 1.0, 0.0), 6) + + def test_1d_3d_minus(self): + line = Line((0, 0), (1, 1)) + box = Box(1, 1, 1) + r = line - box + vertices = r.vertices() + self.assertEquals(len(vertices), 2) + self.assertTupleAlmostEquals(vertices[0], (0.5, 0.5, 0.0), 6) + self.assertTupleAlmostEquals(vertices[1], (1.0, 1.0, 0.0), 6) + + def test_2d_3d_minus(self): + rectangle = Pos(0.5, 0, 0) * Rectangle(1, 1) + box = Box(1, 1, 1) + r = rectangle - box + vertices = r.vertices() + self.assertEquals(len(vertices), 4) + self.assertTupleAlmostEquals(vertices[0], (0.5, -0.5, 0.0), 6) + self.assertTupleAlmostEquals(vertices[1], (0.5, 0.5, 0.0), 6) + self.assertTupleAlmostEquals(vertices[2], (1.0, 0.5, 0.0), 6) + self.assertTupleAlmostEquals(vertices[3], (1.0, -0.5, 0.0), 6) + print(vertices) + + def test_3d_2d_minus(self): + box = Box(1, 1, 1) + rectangle = Rectangle(1, 1) + with self.assertRaises(ValueError): + _ = box - rectangle + + def test_3d_1d_minus(self): + box = Box(1, 1, 1) + line = Line((0, 0), (1, 1)) + with self.assertRaises(ValueError): + _ = box - line + + def test_2d_1d_minus(self): + rectangle = Rectangle(1, 1) + line = Line((0, 0), (1, 1)) + with self.assertRaises(ValueError): + _ = rectangle - line + class LocationTests(unittest.TestCase): def test_wheel(self):