From 3ea2facbb2b66f7a590b3ac66f907a9bfc109641 Mon Sep 17 00:00:00 2001 From: CyrilWaechter Date: Mon, 3 Aug 2026 14:28:56 +0200 Subject: [PATCH] Add regression tests for sloped slab, curved wall Cover a curved vertical wall (EXTRUDE_CLIP strategy) in test_space.py and a sloped slab (clipped extrusion) in test_spatial.py. Generated with the assistance of an AI coding tool. --- src/bonsai/test/tool/test_spatial.py | 33 +++++++++++++++++++ .../test/util/test_space.py | 18 ++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/bonsai/test/tool/test_spatial.py b/src/bonsai/test/tool/test_spatial.py index 2fc67eb423..d0f396c300 100644 --- a/src/bonsai/test/tool/test_spatial.py +++ b/src/bonsai/test/tool/test_spatial.py @@ -573,4 +573,37 @@ class TestSpaceVolumeStrategy(NewFile): assert len(top) == 1 assert len(bottom) == 0 + @staticmethod + def _create_sloped_slab(ifc, z=4.0, rise=3.0): + """Create an IfcSlab whose underside is a sloped plane across the footprint.""" + ctx = ifcopenshell.util.representation.get_context(ifc, "Model", "Body", "MODEL_VIEW") + slab = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcSlab") + pts = [ + ifc.createIfcCartesianPoint((0.0, -5.0)), + ifc.createIfcCartesianPoint((float(rise), -5.0)), + ifc.createIfcCartesianPoint((float(rise), 5.0)), + ] + polyline = ifc.createIfcPolyline(pts) + profile = ifc.createIfcArbitraryClosedProfileDef(ProfileType="CURVE", OuterCurve=polyline) + placement = ifc.createIfcAxis2Placement3D( + ifc.createIfcCartesianPoint((-5.0, 0.0, z)), + ifc.createIfcDirection((1.0, 0.0, 0.0)), + ifc.createIfcDirection((0.0, 0.0, 1.0)), + ) + extrude_dir = ifc.createIfcDirection((0.0, 0.0, 1.0)) + solid = ifc.createIfcExtrudedAreaSolid(profile, placement, extrude_dir, 10.0) + rep = ifc.createIfcShapeRepresentation(ctx, "Body", "SweptSolid", [solid]) + ifcopenshell.api.geometry.assign_representation(ifc, product=slab, representation=rep) + return slab + + def test_sloped_slab_returns_extrude_clip(self): + bpy.ops.bim.create_project() + ifc = tool.Ifc.get() + self._create_sloped_slab(ifc, z=4.0, rise=3.0) + space_polygon = shapely.box(-5, -5, 5, 5) + strategy, top, bottom = subject.get_space_volume_strategy(space_polygon, 0.0, []) + assert strategy == "EXTRUDE_CLIP" + assert len(top) == 1 + assert len(bottom) == 0 + class TestGenerateSpaceSlopedRoof(NewFile): diff --git a/src/ifcopenshell-python/test/util/test_space.py b/src/ifcopenshell-python/test/util/test_space.py index b757eafd2e..b556b4756c 100644 --- a/src/ifcopenshell-python/test/util/test_space.py +++ b/src/ifcopenshell-python/test/util/test_space.py @@ -22,6 +22,7 @@ import ifcopenshell.geom import ifcopenshell.guid import ifcopenshell.util.shape import ifcopenshell.util.space as subject +import math import numpy as np import pytest import shapely @@ -266,6 +267,23 @@ class TestDetectSpaceVolumeStrategy(test.bootstrap.IFC4): ) assert strategy == "BREP" + def test_curved_vertical_wall_returns_extrude_clip(self): + wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + pts = [] + for i in range(9): + angle = -math.pi / 2.0 + math.pi * i / 8.0 + pts.append((5.0 * math.cos(angle), 5.0 * math.sin(angle))) + _add_extruded_body(self.file, wall, pts, 6.0) + shapes = _build_shapes_dict(self.file, [wall]) + tree = ifcopenshell.geom.tree(self.file) + tree.add_file(self.file, ifcopenshell.geom.settings()) + strategy, top, bottom = subject.detect_space_volume_strategy( + self.file, shapes, tree, shapely.box(-4, -4, 4, 4), 0.0, [wall] + ) + assert strategy == "EXTRUDE_CLIP" + assert len(top) == 1 + assert len(bottom) == 0 + class TestBuildExtrudedClippedSpace(test.bootstrap.IFC4): def test_shed_roof_clips_to_sloped_plane(self):