Files
cadSet/SimpleCADAPI/test/test_tracking_features.py
T

145 lines
5.2 KiB
Python

"""Tests for tracking transforms and feature operations."""
import unittest
import numpy as np
import simplecadapi as scad
from simplecadapi.topology import TopoKind, TopoEvent, TopoRef, TopoDelta
from simplecadapi.tracking import (
tracked_translate,
tracked_rotate,
tracked_extrude,
tracked_fillet,
tracked_chamfer,
TrackedResult,
)
class TestTrackedTranslate(unittest.TestCase):
def setUp(self):
self.box = scad.make_box_rsolid(10, 10, 10)
def test_translate_returns_tracked_result(self):
result = tracked_translate(self.box, (5, 0, 0))
self.assertIsInstance(result, TrackedResult)
self.assertIsNotNone(result.shape)
def test_translate_preserves_volume(self):
result = tracked_translate(self.box, (5, 0, 0))
self.assertAlmostEqual(
result.shape.get_volume(), self.box.get_volume(), places=6
)
def test_translate_all_faces_modified(self):
result = tracked_translate(self.box, (5, 0, 0))
modified = [r for r in result.delta.modified if r.kind == TopoKind.FACE]
original_faces = len(self.box.get_faces())
self.assertEqual(len(modified), original_faces)
def test_translate_no_generated(self):
result = tracked_translate(self.box, (5, 0, 0))
self.assertEqual(len(result.delta.generated), 0)
self.assertEqual(len(result.delta.deleted), 0)
def test_translate_result_is_solid(self):
result = tracked_translate(self.box, (5, 0, 0))
self.assertIsInstance(result.shape, scad.Solid)
class TestTrackedRotate(unittest.TestCase):
def setUp(self):
self.box = scad.make_box_rsolid(10, 10, 10)
def test_rotate_returns_tracked_result(self):
result = tracked_rotate(self.box, 45.0, (0, 0, 1))
self.assertIsInstance(result, TrackedResult)
self.assertIsNotNone(result.shape)
def test_rotate_preserves_volume(self):
result = tracked_rotate(self.box, 45.0, (0, 0, 1))
self.assertAlmostEqual(
result.shape.get_volume(), self.box.get_volume(), places=4
)
def test_rotate_all_faces_modified(self):
result = tracked_rotate(self.box, 45.0, (0, 0, 1))
modified = [r for r in result.delta.modified if r.kind == TopoKind.FACE]
original_faces = len(self.box.get_faces())
self.assertEqual(len(modified), original_faces)
def test_rotate_no_generated(self):
result = tracked_rotate(self.box, 45.0, (0, 0, 1))
self.assertEqual(len(result.delta.generated), 0)
class TestTrackedExtrude(unittest.TestCase):
def setUp(self):
self.profile = scad.make_rectangle_rface(5.0, 3.0)
def test_extrude_returns_tracked_result(self):
result = tracked_extrude(self.profile, (0, 0, 1), 10.0)
self.assertIsInstance(result, TrackedResult)
self.assertIsNotNone(result.shape)
def test_extrude_has_correct_volume(self):
result = tracked_extrude(self.profile, (0, 0, 1), 10.0)
expected_vol = self.profile.get_area() * 10.0
self.assertAlmostEqual(result.shape.get_volume(), expected_vol, places=5)
def test_extrude_generates_new_faces(self):
result = tracked_extrude(self.profile, (0, 0, 1), 10.0)
self.assertGreater(len(result.delta.generated), 0)
def test_extrude_has_modified_or_preserved_face(self):
result = tracked_extrude(self.profile, (0, 0, 1), 10.0)
# The profile face becomes part of the extruded solid (either modified or
# generated depending on OCC version)
has_changes = (
len(result.delta.modified) > 0
or len(result.delta.preserved) > 0
or len(result.delta.generated) > 0
)
self.assertTrue(has_changes)
class TestTrackedFillet(unittest.TestCase):
def setUp(self):
self.box = scad.make_box_rsolid(10, 10, 10)
# Select some edges for filleting
self.edges = [self.box.get_edges(i) for i in range(4)]
def test_fillet_returns_tracked_result(self):
result = tracked_fillet(self.box, self.edges, 0.5)
self.assertIsInstance(result, TrackedResult)
self.assertIsNotNone(result.shape)
def test_fillet_volume_decreased(self):
result = tracked_fillet(self.box, self.edges, 0.5)
self.assertLess(result.shape.get_volume(), self.box.get_volume())
def test_fillet_has_modified_faces(self):
result = tracked_fillet(self.box, self.edges, 0.5)
# Fillet modifies edge-adjacent faces; OCC may report new toroidal faces
# as Modified rather than Generated
total_changes = len(result.delta.modified) + len(result.delta.generated)
self.assertGreater(total_changes, 0)
class TestTrackedChamfer(unittest.TestCase):
def setUp(self):
self.box = scad.make_box_rsolid(10, 10, 10)
self.edges = [self.box.get_edges(i) for i in range(4)]
def test_chamfer_returns_tracked_result(self):
result = tracked_chamfer(self.box, self.edges, 0.5)
self.assertIsInstance(result, TrackedResult)
self.assertIsNotNone(result.shape)
def test_chamfer_volume_decreased(self):
result = tracked_chamfer(self.box, self.edges, 0.5)
self.assertLess(result.shape.get_volume(), self.box.get_volume())
if __name__ == "__main__":
unittest.main()