ifc5d: measure openings in their real orientation on both take-off engines

See #6835. Qto_OpeningElementBaseQuantities came out axis-scrambled for
openings authored in a Z-up local frame (X along the voided wall, Y
through it, Z vertical), which is how Bonsai authors every wall opening:

- The IfcOpenShell engine mapped Height to the local Y extent and Depth
  to the local Z extent, so a 0.9 x 2.0 door opening with Bonsai's
  default 1.2m void depth reported Height 1.2 and Depth 2.0, and Area
  (max side area) picked the through-wall side, 2.4 instead of 1.8.
  This matches the wrong Height=1.2/Area=1.2 screenshots reported for a
  1x1 window opening in #6835.
- The Blender engine mapped opening Width to get_length, which returns
  the longest bounding box edge, i.e. the opening height for typical
  door openings (the same defect 4adaf0d fixed for IfcDoor Width), and
  get_opening_depth used min(x, y), which returns the opening width
  whenever the width is smaller than the void depth.

The IfcOpenShell engine now has opening-aware internal calculators
(get_opening_width/height/depth/area) that detect horizontal (slab
style) openings with the same heuristic as the Blender calculator, so
slab opening depths keep reporting the slab thickness. The Blender
ruleset uses get_x for opening Width, and get_opening_depth measures the
through-element Y extent for vertical openings.

Door and window quantities themselves are addressed separately: the
Blender engine door Width was fixed in 4adaf0d, and the remaining
door/window defects (door not quantified on the IfcOpenShell engine,
inflated areas) are fixed by the attribute-based calculators in #8389.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Petru Conduraru
2026-07-21 11:56:01 +03:00
committed by Massimo Fabbro
parent e52e5e2e58
commit efac8a0ec0
7 changed files with 152 additions and 11 deletions
@@ -225,7 +225,7 @@ def get_opening_depth(obj: bpy.types.Object) -> float:
if is_opening_horizontal(obj):
return get_height(obj)
else:
return get_width(obj)
return get_y(obj)
def get_opening_mapping_area(obj: bpy.types.Object) -> float: