Skip to content

Commit ce0b45d

Browse files
Merge pull request #200 from robbievanleeuwen/sub_fix
2 parents f4b3604 + e873510 commit ce0b45d

File tree

2 files changed

+71
-20
lines changed

2 files changed

+71
-20
lines changed

sectionproperties/pre/geometry.py

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,25 +1058,56 @@ def __sub__(self, other):
10581058
"""
10591059
Perform difference on Geometry objects with the - operator
10601060
"""
1061-
material = self.material or other.material
1062-
try:
1063-
new_polygon = filter_non_polygons(self.geom - other.geom)
1064-
if isinstance(new_polygon, MultiPolygon):
1065-
return CompoundGeometry(
1066-
[Geometry(polygon, material) for polygon in new_polygon.geoms]
1061+
material = pre.DEFAULT_MATERIAL
1062+
if isinstance(self, CompoundGeometry):
1063+
subs_geom_acc = []
1064+
for geom in self.geoms:
1065+
new_geom = geom - other
1066+
subs_geom_acc.append(new_geom)
1067+
return CompoundGeometry(subs_geom_acc)
1068+
else:
1069+
material = self.material or pre.DEFAULT_MATERIAL
1070+
try:
1071+
new_polygon = filter_non_polygons(self.geom - other.geom)
1072+
if isinstance(new_polygon, GeometryCollection): # Non-polygon results
1073+
return None
1074+
elif isinstance(new_polygon, MultiPolygon):
1075+
return CompoundGeometry(
1076+
[Geometry(polygon, material) for polygon in new_polygon.geoms]
1077+
)
1078+
elif isinstance(new_polygon, Polygon):
1079+
if self.assigned_control_point and new_polygon.contains(
1080+
self.assigned_control_point
1081+
):
1082+
return Geometry(
1083+
new_polygon, material, self.assigned_control_point
1084+
)
1085+
else:
1086+
return Geometry(new_polygon, material)
1087+
except:
1088+
raise ValueError(
1089+
f"Cannot perform 'difference' on these two objects: {self} - {other}"
10671090
)
1068-
if isinstance(new_polygon, GeometryCollection):
1069-
return None
1070-
# Check to see if assigned_control_point is still valid
1071-
if self.assigned_control_point and new_polygon.contains(
1072-
self.assigned_control_point
1073-
):
1074-
return Geometry(new_polygon, material, self.control_points[0])
1075-
return Geometry(new_polygon, material)
1076-
except:
1077-
raise ValueError(
1078-
f"Cannot perform 'difference' on these two objects: {self} - {other}"
1079-
)
1091+
1092+
# material = self.material or other.material
1093+
# try:
1094+
# new_polygon = filter_non_polygons(self.geom - other.geom)
1095+
# if isinstance(new_polygon, MultiPolygon):
1096+
# return CompoundGeometry(
1097+
# [Geometry(polygon, material) for polygon in new_polygon.geoms]
1098+
# )
1099+
# if isinstance(new_polygon, GeometryCollection):
1100+
# return None
1101+
# # Check to see if assigned_control_point is still valid
1102+
# if self.assigned_control_point and new_polygon.contains(
1103+
# self.assigned_control_point
1104+
# ):
1105+
# return Geometry(new_polygon, material, self.control_points[0])
1106+
# return Geometry(new_polygon, material)
1107+
# except:
1108+
# raise ValueError(
1109+
# f"Cannot perform 'difference' on these two objects: {self} - {other}"
1110+
# )
10801111

10811112
def __add__(self, other):
10821113
"""

sectionproperties/tests/test_sections.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from sectionproperties.pre.library.steel_sections import *
77
from sectionproperties.pre.library.nastran_sections import *
88
from sectionproperties.analysis.section import Section
9-
from sectionproperties.pre.pre import Material
9+
from sectionproperties.pre.pre import DEFAULT_MATERIAL, Material
1010
from sectionproperties.pre.rhino import load_3dm, load_brep_encoding
1111
from shapely.geometry import (
1212
Polygon,
@@ -44,14 +44,15 @@
4444
overlay_geom.create_mesh([50])
4545
overlay_sec = Section(overlay_geom)
4646

47+
steel = Material("steel", 200e3, 0.3, 7.85e-6, 400, "grey")
48+
4749

4850
def test_material_persistence():
4951
# Test ensures that the material attribute gets transformed
5052
# through all of the Geometry transformation methods, each which
5153
# returns a new Geometry object.
5254
# The material assignment should persist through all of the
5355
# transformations
54-
steel = Material("steel", 200e3, 0.3, 7.85e-6, 400, "grey")
5556
big_sq.material = steel
5657
new_geom = (
5758
big_sq.align_to(small_sq, on="left", inner=False)
@@ -72,6 +73,25 @@ def test_for_incidental_holes():
7273
assert len(nested_geom.holes) == 0
7374

7475

76+
def test__sub__():
77+
small_hole.material = steel
78+
top_left = (
79+
small_hole.align_to(big_sq, on="left")
80+
.align_to(big_sq, on="top")
81+
.shift_section(20, -20)
82+
)
83+
top_right = top_left.shift_section(x_offset=200)
84+
85+
compound = big_sq - top_left
86+
compound = compound + top_left
87+
compound = compound - top_right
88+
compound = compound + top_right
89+
90+
assert len(compound.control_points) == 3
91+
# Incomplete test to validate that the iterative __sub__ produces
92+
# three distinct regions with proper material assignments
93+
94+
7595
def test_geometry_from_points():
7696
# Geometry.from_points() tests a shape with exactly one exterior
7797
# and an arbitrary number of interiors being built from the legacy

0 commit comments

Comments
 (0)