mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -08:00
154 lines
5.1 KiB
Python
154 lines
5.1 KiB
Python
"""
|
|
build123d imports
|
|
|
|
name: test_mixin3_d.py
|
|
by: Gumyr
|
|
date: January 22, 2025
|
|
|
|
desc:
|
|
This python module contains tests for the build123d project.
|
|
|
|
license:
|
|
|
|
Copyright 2025 Gumyr
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
"""
|
|
|
|
import unittest
|
|
from unittest.mock import patch, PropertyMock
|
|
|
|
from build123d.build_enums import CenterOf, Kind
|
|
from build123d.geometry import Axis, Plane
|
|
from build123d.topology import Face, Shape, Solid
|
|
|
|
|
|
class TestMixin3D(unittest.TestCase):
|
|
"""Test that 3D add ins"""
|
|
|
|
def test_chamfer(self):
|
|
box = Solid.make_box(1, 1, 1)
|
|
chamfer_box = box.chamfer(0.1, None, box.edges().sort_by(Axis.Z)[-1:])
|
|
self.assertAlmostEqual(chamfer_box.volume, 1 - 0.005, 5)
|
|
|
|
def test_chamfer_asym_length(self):
|
|
box = Solid.make_box(1, 1, 1)
|
|
chamfer_box = box.chamfer(0.1, 0.2, box.edges().sort_by(Axis.Z)[-1:])
|
|
self.assertAlmostEqual(chamfer_box.volume, 1 - 0.01, 5)
|
|
|
|
def test_chamfer_asym_length_with_face(self):
|
|
box = Solid.make_box(1, 1, 1)
|
|
face = box.faces().sort_by(Axis.Z)[0]
|
|
edge = [face.edges().sort_by(Axis.Y)[0]]
|
|
chamfer_box = box.chamfer(0.1, 0.2, edge, face=face)
|
|
self.assertAlmostEqual(chamfer_box.volume, 1 - 0.01, 5)
|
|
|
|
def test_chamfer_too_high_length(self):
|
|
box = Solid.make_box(1, 1, 1)
|
|
face = box.faces
|
|
self.assertRaises(
|
|
ValueError, box.chamfer, 2, None, box.edges().sort_by(Axis.Z)[-1:]
|
|
)
|
|
|
|
def test_chamfer_edge_not_part_of_face(self):
|
|
box = Solid.make_box(1, 1, 1)
|
|
edge = box.edges().sort_by(Axis.Z)[-1:]
|
|
face = box.faces().sort_by(Axis.Z)[0]
|
|
self.assertRaises(ValueError, box.chamfer, 0.1, None, edge, face=face)
|
|
|
|
@patch.object(Shape, "is_valid", new_callable=PropertyMock, return_value=False)
|
|
def test_chamfer_invalid_shape_raises_error(self, mock_is_valid):
|
|
box = Solid.make_box(1, 1, 1)
|
|
|
|
# Assert that ValueError is raised
|
|
with self.assertRaises(ValueError) as chamfer_context:
|
|
max = box.chamfer(0.1, None, box.edges())
|
|
|
|
# Check the error message
|
|
self.assertEqual(
|
|
str(chamfer_context.exception),
|
|
"Failed creating a chamfer, try a smaller length value(s)",
|
|
)
|
|
|
|
# Verify is_valid was called
|
|
mock_is_valid.assert_called_once()
|
|
|
|
def test_hollow(self):
|
|
shell_box = Solid.make_box(1, 1, 1).hollow([], thickness=-0.1)
|
|
self.assertAlmostEqual(shell_box.volume, 1 - 0.8**3, 5)
|
|
|
|
shell_box = Solid.make_box(1, 1, 1)
|
|
shell_box = shell_box.hollow(
|
|
shell_box.faces().filter_by(Axis.Z), thickness=0.1, kind=Kind.INTERSECTION
|
|
)
|
|
self.assertAlmostEqual(shell_box.volume, 1 * 1.2**2 - 1**3, 5)
|
|
|
|
shell_box = Solid.make_box(1, 1, 1).hollow(
|
|
[], thickness=0.1, kind=Kind.INTERSECTION
|
|
)
|
|
self.assertAlmostEqual(shell_box.volume, 1.2**3 - 1**3, 5)
|
|
|
|
with self.assertRaises(ValueError):
|
|
Solid.make_box(1, 1, 1).hollow([], thickness=0.1, kind=Kind.TANGENT)
|
|
|
|
def test_is_inside(self):
|
|
self.assertTrue(Solid.make_box(1, 1, 1).is_inside((0.5, 0.5, 0.5)))
|
|
|
|
def test_dprism(self):
|
|
# face
|
|
f = Face.make_rect(0.5, 0.5)
|
|
d = Solid.make_box(1, 1, 1, Plane((-0.5, -0.5, 0))).dprism(
|
|
None, [f], additive=False
|
|
)
|
|
self.assertTrue(d.is_valid)
|
|
self.assertAlmostEqual(d.volume, 1 - 0.5**2, 5)
|
|
|
|
# face with depth
|
|
f = Face.make_rect(0.5, 0.5)
|
|
d = Solid.make_box(1, 1, 1, Plane((-0.5, -0.5, 0))).dprism(
|
|
None, [f], depth=0.5, thru_all=False, additive=False
|
|
)
|
|
self.assertTrue(d.is_valid)
|
|
self.assertAlmostEqual(d.volume, 1 - 0.5**3, 5)
|
|
|
|
# face until
|
|
f = Face.make_rect(0.5, 0.5)
|
|
limit = Face.make_rect(1, 1, Plane((0, 0, 0.5)))
|
|
d = Solid.make_box(1, 1, 1, Plane((-0.5, -0.5, 0))).dprism(
|
|
None, [f], up_to_face=limit, thru_all=False, additive=False
|
|
)
|
|
self.assertTrue(d.is_valid)
|
|
self.assertAlmostEqual(d.volume, 1 - 0.5**3, 5)
|
|
|
|
# wire
|
|
w = Face.make_rect(0.5, 0.5).outer_wire()
|
|
d = Solid.make_box(1, 1, 1, Plane((-0.5, -0.5, 0))).dprism(
|
|
None, [w], additive=False
|
|
)
|
|
self.assertTrue(d.is_valid)
|
|
self.assertAlmostEqual(d.volume, 1 - 0.5**2, 5)
|
|
|
|
def test_center(self):
|
|
with self.assertRaises(ValueError):
|
|
Solid.make_box(1, 1, 1).center(CenterOf.GEOMETRY)
|
|
|
|
self.assertAlmostEqual(
|
|
Solid.make_box(1, 1, 1).center(CenterOf.BOUNDING_BOX),
|
|
(0.5, 0.5, 0.5),
|
|
5,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|