From 1259607a9f3d2e4425790fe0ca28bbef2c869ee7 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 10 Mar 2025 18:10:05 +1100 Subject: [PATCH] See #1227. Fix slicing normal calculation for AXIS3 elements. --- src/bonsai/bonsai/tool/loader.py | 12 ++++++++---- .../ifcopenshell/util/representation.py | 11 ++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/bonsai/bonsai/tool/loader.py b/src/bonsai/bonsai/tool/loader.py index 17fbdb82d6..e7fd1185a5 100644 --- a/src/bonsai/bonsai/tool/loader.py +++ b/src/bonsai/bonsai/tool/loader.py @@ -1037,13 +1037,17 @@ class Loader(bonsai.core.tool.Loader): bm.from_mesh(mesh) prev_co = None # no = Vector((0.0, 1.0, 0.0)) - no = cls.get_extrusion_vector(element).normalized() - if usage and usage.LayerSetDirection == "AXIS2": + if not usage: + sense_factor = 1 # Assume the extrusion vector points in the direction sense + no = cls.get_extrusion_vector(element).normalized() + co = Vector((0.0, 0.0, offset)) + elif usage.LayerSetDirection == "AXIS2": co = Vector((0.0, offset, 0.0)) no = no.cross(Vector([1.0, 0.0, 0.0])) - else: - sense_factor = 1 # If it isn't AXIS2, then the normal points in the direction sense + elif usage.LayerSetDirection == "AXIS3": co = Vector((0.0, 0.0, offset)) + no = cls.get_extrusion_vector(element).normalized() + no = Vector([0.0, 0.0, 1.0 if no.z > 0 else -1.0]) # Cache this body = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW") styles = {} diff --git a/src/ifcopenshell-python/ifcopenshell/util/representation.py b/src/ifcopenshell-python/ifcopenshell/util/representation.py index 1b1423cf1f..31ba5a7bee 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/representation.py +++ b/src/ifcopenshell-python/ifcopenshell/util/representation.py @@ -463,10 +463,19 @@ def get_material_style( return style -def get_reference_line(wall: ifcopenshell.entity_instance, fallback_length: float = 1.0): +def get_reference_line(wall: ifcopenshell.entity_instance, fallback_length: float = 1.0) -> list[npt.NDArray]: """Fetch the reference axis that goes in the +X direction + A base line will then be offset from this reference line based on the + material usage. From that base line, the layer thicknesses will offset + again, and be extruded to form the body representation. + :param wall: ifcopenshell.entity_instance + :param fallback_length: If there is no reference axis, assume it starts at + the object placement (i.e. 0.0, 0.0) and extends for this fallback + length along the +X axis. + :return: A list of two 2D coordinates representing the start and end of the + axis. The axis always goes in the +X direction. """ if axis := ifcopenshell.util.representation.get_representation(wall, "Plan", "Axis", "GRAPH_VIEW"): for item in ifcopenshell.util.representation.resolve_representation(axis).Items: