Skip to content

Commit 1a84939

Browse files
Moultclaude
andcommitted
Typo crashing edit tools panel when non-wall with wall selected
Fix IfcOpenShell#7034 bpy.ops.bim.extend_to_underside doesn't exist - the correct operator name is bim.extend_walls_to_underside. The AttributeError killed the entire panel draw, hiding mirror, align, aggregation, and QTO buttons. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 611273a commit 1a84939

3 files changed

Lines changed: 70 additions & 2 deletions

File tree

src/bonsai/bonsai/bim/module/model/workspace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ def draw_operations(cls, context):
943943
if "LAYER2" in AuthoringData.data["selected_material_usages"]:
944944
row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row
945945
add_layout_hotkey_operator(
946-
cls.layout, "Extend To Underside", "S_E", bpy.ops.bim.extend_to_underside.__doc__, ui_context
946+
cls.layout, "Extend To Underside", "S_E", bpy.ops.bim.extend_walls_to_underside.__doc__, ui_context
947947
)
948948

949949
if AuthoringData.data["is_flippable_element"]:

src/bonsai/test/bim/feature/model.feature

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,44 @@ Scenario: Add a slab
396396
And the object "IfcSlab/Slab" bottom left corner is at "0,0,0"
397397
And the object "IfcSlab/Slab" top right corner is at "1,1,0.2"
398398

399+
Scenario: Extend walls to underside
400+
Given an empty IFC project
401+
And I load the demo construction library
402+
And I set "scene.BIMModelProperties.ifc_class" to "IfcWallType"
403+
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcWallType') if e.Name == 'WAL100'][0].id()"
404+
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
405+
And I press "bim.add_occurrence"
406+
And I set "scene.BIMModelProperties.ifc_class" to "IfcSlabType"
407+
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcSlabType') if e.Name == 'FLR200'][0].id()"
408+
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
409+
And I press "bim.add_occurrence"
410+
And the object "IfcSlab/Slab" is moved to "0,0,2.5"
411+
When the object "IfcWall/Wall" is selected
412+
And additionally the object "IfcSlab/Slab" is selected
413+
And I look at the tool header
414+
And I click "Extend To Underside"
415+
Then the object "IfcWall/Wall" dimensions are "1,0.1,2.5"
416+
417+
Scenario: Extend walls to underside - extending to a tessellated gable roof
418+
Given an empty IFC project
419+
And I load the demo construction library
420+
And I set "scene.BIMModelProperties.ifc_class" to "IfcWallType"
421+
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcWallType') if e.Name == 'WAL100'][0].id()"
422+
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
423+
And I press "bim.add_occurrence"
424+
# Create gable roof: a cube turned into a prism with a ridge.
425+
And I add a cube of size "1" at "0.5,0.05,3"
426+
And the object "Cube" is selected
427+
And I evaluate expression "obj = bpy.context.active_object; [setattr(v.co, 'y', 0) for v in obj.data.vertices if v.co.z > 0]"
428+
And I set "scene.BIMRootProperties.ifc_product" to "IfcElement"
429+
And I set "scene.BIMRootProperties.ifc_class" to "IfcRoof"
430+
And I press "bim.assign_class"
431+
When the object "IfcWall/Wall" is selected
432+
And additionally the object "IfcRoof/Cube" is selected
433+
And I look at the tool header
434+
And I click "Extend To Underside"
435+
Then the object "IfcWall/Wall" dimensions are "1,0.1,2.5"
436+
399437
Scenario: Enable editing a slab profile
400438
Given an empty IFC project
401439
And I load the demo construction library

src/bonsai/test/bim/test_feature.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ def __call__(self, *args: Any, **kwargs: Any) -> PanelSpy | TemplateListSpy | Op
133133
self.spied_labels.append(kwargs["text"])
134134
return self
135135
elif self.spied_attr == "prop":
136-
props, name = args
136+
if args:
137+
props, name = args
138+
else:
139+
props = kwargs.get("data")
140+
name = kwargs.get("property")
137141
props: bpy.types.bpy_struct
138142
text = kwargs.get("text", props.bl_rna.properties[name].name)
139143
icon = kwargs.get("icon", None)
@@ -390,6 +394,32 @@ def i_look_at_the_panel_panel(panel: str) -> None:
390394
panel_spy.refresh_spy()
391395

392396

397+
@given(parsers.parse("I look at the tool header"))
398+
@when(parsers.parse("I look at the tool header"))
399+
@then(parsers.parse("I look at the tool header"))
400+
def i_look_at_the_tool_header() -> None:
401+
from bonsai.bim.module.model.workspace import EditObjectUI
402+
403+
class MockRegion:
404+
type = "UI"
405+
406+
class MockContext:
407+
def __getattr__(self, name):
408+
if name == "region":
409+
return MockRegion()
410+
return getattr(bpy.context, name)
411+
412+
global panel_spy
413+
panel_spy = PanelSpy(EditObjectUI)
414+
panel_spy.is_spy_dirty = False
415+
panel_spy.spied_attr = None
416+
panel_spy.spied_labels = []
417+
panel_spy.spied_props = []
418+
panel_spy.spied_operators = []
419+
panel_spy.spied_lists = []
420+
EditObjectUI.draw(MockContext(), panel_spy)
421+
422+
393423
@given(parsers.parse('I open the "{name}" menu'))
394424
@when(parsers.parse('I open the "{name}" menu'))
395425
@then(parsers.parse('I open the "{name}" menu'))

0 commit comments

Comments
 (0)