From 22d9bce59100994b8984ec8c7d885afbc8f0dbe6 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 24 May 2021 20:56:47 +1000 Subject: [PATCH] Dumb walls now automatically generate wall axis upon update --- .../bim/module/parametric/operator.py | 39 +++++++++++++++++++ .../api/geometry/add_representation.py | 6 ++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/parametric/operator.py b/src/blenderbim/blenderbim/bim/module/parametric/operator.py index bf76155294..43a3b97a4a 100644 --- a/src/blenderbim/blenderbim/bim/module/parametric/operator.py +++ b/src/blenderbim/blenderbim/bim/module/parametric/operator.py @@ -7,6 +7,7 @@ import ifcopenshell.util.element import ifcopenshell.util.representation from blenderbim.bim.ifc import IfcStore from ifcopenshell.api.pset.data import Data as PsetData +from mathutils import Vector def generate_box(usecase_path, ifc_file, **settings): @@ -33,6 +34,41 @@ def generate_box(usecase_path, ifc_file, **settings): ) +def generate_dumb_wall_axis(usecase_path, ifc_file, **settings): + axis_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Axis", "GRAPH_VIEW") + if not axis_context: + return + obj = settings["blender_object"] + product = ifc_file.by_id(obj.BIMObjectProperties.ifc_definition_id) + parametric = ifcopenshell.util.element.get_psets(product).get("EPset_Parametric") + if not parametric or parametric["Engine"] != "BlenderBIM.DumbWall": + return + old_axis = ifcopenshell.util.representation.get_representation(product, "Model", "Axis", "GRAPH_VIEW") + if settings["context"].ContextType == "Model" and getattr(settings["context"], "ContextIdentifier") == "Body": + if old_axis: + bpy.ops.bim.remove_representation(representation_id=old_axis.id(), obj=obj.name) + + new_settings = settings.copy() + new_settings["context"] = axis_context + + mesh = bpy.data.meshes.new("Temporary Axis") + start = (Vector(obj.bound_box[3]) + Vector(obj.bound_box[0])) / 2 + end = (Vector(obj.bound_box[7]) + Vector(obj.bound_box[4])) / 2 + mesh.from_pydata([start, end], [(0, 1)], []) + + new_settings["geometry"] = mesh + new_axis = ifcopenshell.api.run( + "geometry.add_representation", ifc_file, should_run_listeners=False, **new_settings + ) + ifcopenshell.api.run( + "geometry.assign_representation", + ifc_file, + should_run_listeners=False, + **{"product": product, "representation": new_axis} + ) + bpy.data.meshes.remove(mesh) + + def calculate_dumb_quantities(usecase_path, ifc_file, **settings): unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file) obj = settings["blender_object"] @@ -74,6 +110,9 @@ class ActivateParametricEngine(bpy.types.Operator): def execute(self, context): ifcopenshell.api.add_post_listener("geometry.add_representation", IfcStore.get_file(), generate_box) + ifcopenshell.api.add_post_listener( + "geometry.add_representation", IfcStore.get_file(), generate_dumb_wall_axis + ) ifcopenshell.api.add_post_listener( "geometry.add_representation", IfcStore.get_file(), calculate_dumb_quantities ) diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py index bcb6571175..3fdab2ac5d 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py @@ -33,7 +33,10 @@ class Usecase: self.settings[key] = value def execute(self): - if isinstance(self.settings["geometry"], bpy.types.Mesh): + if ( + isinstance(self.settings["geometry"], bpy.types.Mesh) + and self.settings["geometry"] == self.settings["blender_object"].data + ): self.evaluate_geometry() if self.settings["unit_scale"] is None: self.settings["unit_scale"] = ifcopenshell.util.unit.calculate_unit_scale(self.file) @@ -44,7 +47,6 @@ class Usecase: return self.create_variable_representation() def evaluate_geometry(self): - for modifier in self.settings["blender_object"].modifiers: if modifier.type == "BOOLEAN": modifier.show_viewport = False