Skip to content

Commit 60ebb99

Browse files
Moultclaude
andcommitted
Fix covering geometry not persisting to IFC, same root cause as IfcOpenShell#7055
The covering tool used bmesh as an intermediate and relied on type.assign_type post-listeners (removed in 44a5286) to generate the IfcExtrudedAreaSolid body. With those listeners gone, coverings had no body representation and assign_swept_area_outer_curve crashed. Build covering representations from scratch using ShapeBuilder, reading the extrusion depth from the type's IfcMaterialLayerSet. Also replace bpy.ops.bim.assign_class with bonsai.core.root.assign_class using should_add_representation=False, consistent with the space fix. Refactored shared coordinate-conversion and extrusion-building logic into get_2d_vertices_from_polygon and set_extrusion_representation_from_polygon, used by both space and covering code paths. Removed all bmesh-dependent dead code from the spatial tool. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ab96add commit 60ebb99

3 files changed

Lines changed: 84 additions & 214 deletions

File tree

src/bonsai/bonsai/core/covering.py

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,11 @@ def add_instance_flooring_covering_from_cursor(
5151
if isinstance(space_polygon, str):
5252
return
5353

54-
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0, polygon_is_si=True)
55-
name = "Covering"
56-
mesh = spatial.get_named_mesh_from_bmesh(name=name, bmesh=bm)
57-
58-
obj = spatial.get_named_obj_from_mesh(name, mesh)
59-
54+
obj = spatial.create_object("Covering")
6055
spatial.set_obj_origin_to_cursor_position_and_zero_elevation(obj)
6156
spatial.translate_obj_to_z_location(obj, z)
62-
points = spatial.get_2d_vertices_from_obj(obj)
63-
points = spatial.get_scaled_2d_vertices(points)
6457
spatial.assign_type_to_obj(obj)
65-
66-
spatial.assign_swept_area_outer_curve_from_2d_vertices(obj, vertices=points)
67-
body = spatial.get_body_representation(obj)
68-
spatial.regen_obj_representation(obj, body)
58+
spatial.set_covering_representation_from_polygon(obj, space_polygon, polygon_is_si=True)
6959

7060

7161
def add_instance_ceiling_covering_from_cursor(
@@ -95,21 +85,11 @@ def add_instance_ceiling_covering_from_cursor(
9585
if isinstance(space_polygon, str):
9686
return
9787

98-
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0, polygon_is_si=True)
99-
name = "Covering"
100-
mesh = spatial.get_named_mesh_from_bmesh(name=name, bmesh=bm)
101-
102-
obj = spatial.get_named_obj_from_mesh(name, mesh)
103-
88+
obj = spatial.create_object("Covering")
10489
spatial.set_obj_origin_to_cursor_position_and_zero_elevation(obj)
10590
spatial.translate_obj_to_z_location(obj, z + ceiling_height)
106-
points = spatial.get_2d_vertices_from_obj(obj)
107-
points = spatial.get_scaled_2d_vertices(points)
10891
spatial.assign_type_to_obj(obj)
109-
110-
spatial.assign_swept_area_outer_curve_from_2d_vertices(obj, vertices=points)
111-
body = spatial.get_body_representation(obj)
112-
spatial.regen_obj_representation(obj, body)
92+
spatial.set_covering_representation_from_polygon(obj, space_polygon, polygon_is_si=True)
11393

11494

11595
def regen_selected_covering_object(root: type[tool.Root], spatial: type[tool.Spatial]) -> None:
@@ -127,19 +107,7 @@ def regen_selected_covering_object(root: type[tool.Root], spatial: type[tool.Spa
127107
if isinstance(space_polygon, str):
128108
return
129109

130-
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0, polygon_is_si=True)
131-
132-
name = "Aux"
133-
mesh = spatial.get_named_mesh_from_bmesh(name=name, bmesh=bm)
134-
mesh = spatial.get_transformed_mesh_from_local_to_global(mesh)
135-
obj = spatial.get_named_obj_from_mesh(name, mesh)
136-
137-
points = spatial.get_2d_vertices_from_obj(obj)
138-
points = spatial.get_scaled_2d_vertices(points)
139-
140-
spatial.assign_swept_area_outer_curve_from_2d_vertices(active_obj, vertices=points)
141-
body = spatial.get_body_representation(active_obj)
142-
spatial.regen_obj_representation(active_obj, body)
110+
spatial.set_covering_representation_from_polygon(active_obj, space_polygon, polygon_is_si=True)
143111

144112

145113
# TODO CHECK IF IT IS POSSIBLE TO CREATE ONLY ONE CORE FUNCTION FOR _FROM_WALLS
@@ -151,22 +119,13 @@ def add_instance_flooring_coverings_from_walls(root: type[tool.Root], spatial: t
151119
union = spatial.get_union_shape_from_selected_objects()
152120
for i, linear_ring in enumerate(union.interiors):
153121
poly = spatial.get_buffered_poly_from_linear_ring(linear_ring)
154-
bm = spatial.get_bmesh_from_polygon(poly, h=0, polygon_is_si=False)
155122

156123
name = "Covering" + str(i)
157-
obj = spatial.get_named_obj_from_bmesh(name, bmesh=bm)
158-
159-
spatial.set_obj_origin_to_bboxcenter(obj)
124+
obj = spatial.create_object(name)
125+
spatial.set_obj_origin_to_polygon_center(obj, poly, polygon_is_si=False)
160126
spatial.translate_obj_to_z_location(obj, z)
161-
162-
points = spatial.get_2d_vertices_from_obj(obj)
163-
points = spatial.get_scaled_2d_vertices(points)
164-
165127
spatial.assign_type_to_obj(obj)
166-
167-
spatial.assign_swept_area_outer_curve_from_2d_vertices(obj, vertices=points)
168-
body = spatial.get_body_representation(obj)
169-
spatial.regen_obj_representation(obj, body)
128+
spatial.set_covering_representation_from_polygon(obj, poly, polygon_is_si=False)
170129

171130

172131
def add_instance_ceiling_coverings_from_walls(
@@ -179,22 +138,13 @@ def add_instance_ceiling_coverings_from_walls(
179138
union = spatial.get_union_shape_from_selected_objects()
180139
for i, linear_ring in enumerate(union.interiors):
181140
poly = spatial.get_buffered_poly_from_linear_ring(linear_ring)
182-
bm = spatial.get_bmesh_from_polygon(poly, h=0, polygon_is_si=False)
183141

184142
name = "Covering" + str(i)
185-
obj = spatial.get_named_obj_from_bmesh(name, bmesh=bm)
186-
187-
spatial.set_obj_origin_to_bboxcenter(obj)
143+
obj = spatial.create_object(name)
144+
spatial.set_obj_origin_to_polygon_center(obj, poly, polygon_is_si=False)
188145
spatial.translate_obj_to_z_location(obj, z)
189-
190-
points = spatial.get_2d_vertices_from_obj(obj)
191-
points = spatial.get_scaled_2d_vertices(points)
192-
193146
spatial.assign_type_to_obj(obj)
194-
195-
spatial.assign_swept_area_outer_curve_from_2d_vertices(obj, vertices=points)
196-
body = spatial.get_body_representation(obj)
197-
spatial.regen_obj_representation(obj, body)
147+
spatial.set_covering_representation_from_polygon(obj, poly, polygon_is_si=False)
198148

199149

200150
class NoDefaultContainer(Exception):

src/bonsai/bonsai/core/tool.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -999,30 +999,22 @@ def get_converted_tolerance(cls, tolerance): pass
999999
def get_purged_inner_holes_poly(cls, union_geom, min_area): pass
10001000
def get_poly_valid_interior_list(cls, poly, min_area, interiors_list): pass
10011001
def get_buffered_poly_from_linear_ring(cls, linear_ring): pass
1002-
def get_bmesh_from_polygon(cls, poly, h, polygon_is_si=False): pass
1003-
def get_named_obj_from_bmesh(cls, name, bmesh): pass
1004-
def get_named_obj_from_mesh(cls, name, mesh): pass
1005-
def get_named_mesh_from_bmesh(cls, name, bmesh): pass
1006-
def get_transformed_mesh_from_local_to_global(cls, mesh): pass
1002+
def get_2d_vertices_from_polygon(cls, poly, obj, polygon_is_si=True): pass
1003+
def set_extrusion_representation_from_polygon(cls, obj, element, poly, depth_ifc, polygon_is_si=True): pass
10071004
def set_space_representation_from_polygon(cls, obj, element, poly, h, polygon_is_si=True): pass
1005+
def set_covering_representation_from_polygon(cls, obj, poly, polygon_is_si=True): pass
10081006
def create_object(cls, name): pass
10091007
def set_obj_origin_to_polygon_center(cls, obj, poly, polygon_is_si=True): pass
1010-
def set_obj_origin_to_bboxcenter(cls, obj): pass
10111008
def set_obj_origin_to_cursor_position_and_zero_elevation(cls, obj): pass
10121009
def get_selected_objects(cls): pass
10131010
def get_active_obj(cls): pass
10141011
def get_active_obj_z(cls): pass
10151012
def get_active_obj_height(cls): pass
10161013
def get_relating_type_id(cls): pass
10171014
def translate_obj_to_z_location(cls, obj, z): pass
1018-
def get_2d_vertices_from_obj(cls, obj): pass
1019-
def get_scaled_2d_vertices(cls, points): pass
1020-
def assign_swept_area_outer_curve_from_2d_vertices(cls, obj, vertices): pass
1021-
def get_body_representation(cls, obj): pass
10221015
def assign_ifcspace_class_to_obj(cls, obj): pass
10231016
def assign_type_to_obj(cls, obj): pass
10241017
def assign_relating_type_to_element(cls, ifc, type, element, relating_type): pass
1025-
def regen_obj_representation(cls, obj, body): pass
10261018
def toggle_spaces_visibility_wired_and_textured(cls, spaces): pass
10271019
def toggle_hide_spaces(cls, spaces): pass
10281020
def set_default_container(cls, container): pass

0 commit comments

Comments
 (0)