From 963ba5fc302fa1d092ae83286072785b266b750a Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 21 Mar 2025 16:45:29 +1100 Subject: [PATCH] See #6404. See #1227. Create axis context if it does not exist for walls. --- src/bonsai/bonsai/bim/module/model/wall.py | 2 +- .../api/geometry/regenerate_wall_representation.py | 10 ++++++++++ .../ifcopenshell/util/representation.py | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/bonsai/bonsai/bim/module/model/wall.py b/src/bonsai/bonsai/bim/module/model/wall.py index 49811c8cbd..2ab37af2c4 100644 --- a/src/bonsai/bonsai/bim/module/model/wall.py +++ b/src/bonsai/bonsai/bim/module/model/wall.py @@ -1170,7 +1170,7 @@ class DumbWallJoiner: ifcopenshell.util.element.replace_element(old_rep, rep) ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_rep) else: - ifcopenshell.api.geometry.assign_representation(self.file, product=wall, representation=rep) + ifcopenshell.api.geometry.assign_representation(tool.Ifc.get(), product=wall, representation=rep) def extend(self, wall1, target): if tool.Ifc.is_moved(wall1): diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/regenerate_wall_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/regenerate_wall_representation.py index 43bb761f81..ae2a885d36 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/regenerate_wall_representation.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/regenerate_wall_representation.py @@ -73,6 +73,9 @@ def regenerate_wall_representation( 0.0)). This is a logical, consistent, and useful placement coordinate (especially for apps that can pivot using this point). + All this functionality relies on the Plan/Axis/GRAPH_VIEW representation + context. It will be created if it does not exist. + :param wall: The IfcWall for the representation, only Model/Body/MODEL_VIEW type of representations are currently supported. :param length: If the wall doesn't have an axis length, this is the default @@ -94,6 +97,13 @@ class Regenerator: self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file) self.is_angled = False + if not self.axis: + if not (plan := ifcopenshell.util.representation.get_context(file, "Plan")): + plan = ifcopenshell.api.context.add_context(file, context_type="Plan") + self.axis = ifcopenshell.api.context.add_context( + file, context_type="Plan", context_identifier="Axis", target_view="GRAPH_VIEW", parent=plan + ) + def regenerate(self, wall, length=1.0, height=1.0, angle=None): print("-" * 100) print(wall) diff --git a/src/ifcopenshell-python/ifcopenshell/util/representation.py b/src/ifcopenshell-python/ifcopenshell/util/representation.py index a628ea6c88..ca79c4ec88 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/representation.py +++ b/src/ifcopenshell-python/ifcopenshell/util/representation.py @@ -19,6 +19,7 @@ import numpy as np import numpy.typing as npt import ifcopenshell +import ifcopenshell.util.shape import ifcopenshell.util.placement from typing import Optional, Union, TypedDict, Literal, Generator, Sequence @@ -488,4 +489,13 @@ def get_reference_line(wall: ifcopenshell.entity_instance, fallback_length: floa if points[0][0] < points[1][0]: # An axis always goes in the +X direction return [np.array(points[0]), np.array(points[1])] return [np.array(points[1]), np.array(points[0])] + elif extrusions := ifcopenshell.util.shape.get_base_extrusions(wall): + for item in extrusions: + if item.is_a("IfcPolyline"): + x = [p[0][0] for p in item.Points] + elif item.is_a("IfcIndexedPolyCurve"): + x = [p[0] for p in item.Points.CoordList] + else: + continue + return [np.array((min(x), 0.0)), np.array((max(x), 0.0))] return [np.array((0.0, 0.0)), np.array((fallback_length, 0.0))]