Correct area/volume calculations from intersect with new return type of ShapeList

This commit is contained in:
Jonathan Wagenet 2025-10-28 23:45:29 -04:00
parent c13ef47cef
commit 315605f485
7 changed files with 20 additions and 18 deletions

View file

@ -453,7 +453,7 @@ class DimensionLine(BaseSketchObject):
if self_intersection is None: if self_intersection is None:
self_intersection_area = 0.0 self_intersection_area = 0.0
else: else:
self_intersection_area = self_intersection.area self_intersection_area = sum(f.area for f in self_intersection.faces())
d_line += placed_label d_line += placed_label
bbox_size = d_line.bounding_box().diagonal bbox_size = d_line.bounding_box().diagonal
@ -467,7 +467,7 @@ class DimensionLine(BaseSketchObject):
if line_intersection is None: if line_intersection is None:
common_area = 0.0 common_area = 0.0
else: else:
common_area = line_intersection.area common_area = sum(f.area for f in line_intersection.faces())
common_area += self_intersection_area common_area += self_intersection_area
score = (d_line.area - 10 * common_area) / bbox_size score = (d_line.area - 10 * common_area) / bbox_size
d_lines[d_line] = score d_lines[d_line] = score

View file

@ -649,11 +649,7 @@ class Compound(Mixin3D, Shape[TopoDS_Compound]):
children[child_index_pair[1]] children[child_index_pair[1]]
) )
if obj_intersection is not None: if obj_intersection is not None:
common_volume = ( common_volume = sum(s.volume for s in obj_intersection.solids())
0.0
if isinstance(obj_intersection, list)
else obj_intersection.volume
)
if common_volume > tolerance: if common_volume > tolerance:
return ( return (
True, True,

View file

@ -778,15 +778,13 @@ class Face(Mixin2D, Shape[TopoDS_Face]):
).sort_by(Axis(cog, cross_dir)) ).sort_by(Axis(cog, cross_dir))
bottom_area = sum(f.area for f in bottom_list) bottom_area = sum(f.area for f in bottom_list)
intersect_area = 0.0
for flipped_face, bottom_face in zip(top_flipped_list, bottom_list): for flipped_face, bottom_face in zip(top_flipped_list, bottom_list):
intersection = flipped_face.intersect(bottom_face) intersection = flipped_face.intersect(bottom_face)
if intersection is None or isinstance(intersection, list): if intersection is None:
intersect_area = -1.0 intersect_area = -1.0
break break
else: else:
assert isinstance(intersection, Face) intersect_area = sum(f.area for f in intersection.faces())
intersect_area += intersection.area
if intersect_area == -1.0: if intersect_area == -1.0:
continue continue

View file

@ -229,13 +229,15 @@ class TestOrientedBoundBox(unittest.TestCase):
obb = OrientedBoundBox(rect) obb = OrientedBoundBox(rect)
corners = obb.corners corners = obb.corners
poly = Polygon(*corners, align=None) poly = Polygon(*corners, align=None)
self.assertAlmostEqual(rect.intersect(poly).area, rect.area, 5) area = sum(f.area for f in rect.intersect(poly).faces())
self.assertAlmostEqual(area, rect.area, 5)
for face in Box(1, 2, 3).faces(): for face in Box(1, 2, 3).faces():
obb = OrientedBoundBox(face) obb = OrientedBoundBox(face)
corners = obb.corners corners = obb.corners
poly = Polygon(*corners, align=None) poly = Polygon(*corners, align=None)
self.assertAlmostEqual(face.intersect(poly).area, face.area, 5) area = sum(f.area for f in face.intersect(poly).faces())
self.assertAlmostEqual(area, face.area, 5)
def test_line_corners(self): def test_line_corners(self):
""" """

View file

@ -299,7 +299,8 @@ class TestShape(unittest.TestCase):
predicted_location = Location(offset) * Rotation(*rotation) predicted_location = Location(offset) * Rotation(*rotation)
located_shape = Solid.make_box(1, 1, 1).locate(predicted_location) located_shape = Solid.make_box(1, 1, 1).locate(predicted_location)
intersect = shape.intersect(located_shape) intersect = shape.intersect(located_shape)
self.assertAlmostEqual(intersect.volume, 1, 5) volume = sum(s.volume for s in intersect.solids())
self.assertAlmostEqual(volume, 1, 5)
def test_position_and_orientation(self): def test_position_and_orientation(self):
box = Solid.make_box(1, 1, 1).locate(Location((1, 2, 3), (10, 20, 30))) box = Solid.make_box(1, 1, 1).locate(Location((1, 2, 3), (10, 20, 30)))
@ -588,7 +589,7 @@ class TestShape(unittest.TestCase):
empty.distance_to_with_closest_points(Vector(1, 1, 1)) empty.distance_to_with_closest_points(Vector(1, 1, 1))
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
empty.distance_to(Vector(1, 1, 1)) empty.distance_to(Vector(1, 1, 1))
with self.assertRaises(ValueError): with self.assertRaises(AttributeError):
box.intersect(empty_loc) box.intersect(empty_loc)
self.assertEqual(empty._ocp_section(Vertex(1, 1, 1)), ([], [])) self.assertEqual(empty._ocp_section(Vertex(1, 1, 1)), ([], []))
self.assertEqual(empty.faces_intersected_by_axis(Axis.Z), ShapeList()) self.assertEqual(empty.faces_intersected_by_axis(Axis.Z), ShapeList())

View file

@ -153,7 +153,9 @@ class TestSolid(unittest.TestCase):
self.assertAlmostEqual(twist.volume, 1, 5) self.assertAlmostEqual(twist.volume, 1, 5)
top = twist.faces().sort_by(Axis.Z)[-1].rotate(Axis.Z, 45) top = twist.faces().sort_by(Axis.Z)[-1].rotate(Axis.Z, 45)
bottom = twist.faces().sort_by(Axis.Z)[0] bottom = twist.faces().sort_by(Axis.Z)[0]
self.assertAlmostEqual(top.translate((0, 0, -1)).intersect(bottom).area, 1, 5) intersect = top.translate((0, 0, -1)).intersect(bottom)
area = sum(f.area for f in intersect.faces())
self.assertAlmostEqual(area, 1, 5)
# Wire # Wire
base = Wire.make_rect(1, 1) base = Wire.make_rect(1, 1)
twist = Solid.extrude_linear_with_rotation( twist = Solid.extrude_linear_with_rotation(
@ -162,7 +164,9 @@ class TestSolid(unittest.TestCase):
self.assertAlmostEqual(twist.volume, 1, 5) self.assertAlmostEqual(twist.volume, 1, 5)
top = twist.faces().sort_by(Axis.Z)[-1].rotate(Axis.Z, 45) top = twist.faces().sort_by(Axis.Z)[-1].rotate(Axis.Z, 45)
bottom = twist.faces().sort_by(Axis.Z)[0] bottom = twist.faces().sort_by(Axis.Z)[0]
self.assertAlmostEqual(top.translate((0, 0, -1)).intersect(bottom).area, 1, 5) intersect = top.translate((0, 0, -1)).intersect(bottom)
area = sum(f.area for f in intersect.faces())
self.assertAlmostEqual(area, 1, 5)
def test_make_loft(self): def test_make_loft(self):
loft = Solid.make_loft( loft = Solid.make_loft(

View file

@ -231,7 +231,8 @@ class DimensionLineTestCase(unittest.TestCase):
], ],
draft=metric, draft=metric,
) )
self.assertGreater(hole.intersect(d_line).area, 0) area = sum(f.area for f in hole.intersect(d_line).faces())
self.assertGreater(area, 0)
def test_outside_arrows(self): def test_outside_arrows(self):
d_line = DimensionLine([(0, 0, 0), (15, 0, 0)], draft=metric) d_line = DimensionLine([(0, 0, 0), (15, 0, 0)], draft=metric)