From 55763ea7dfd552005629e9579f7dcd57a284615a Mon Sep 17 00:00:00 2001 From: Massimo Fabbro Date: Fri, 10 Nov 2023 22:06:54 +0100 Subject: [PATCH] Covering Tool now it is possible to add ceiling coverings from selected walls --- .../bim/module/covering/workspace.py | 12 +++++- .../blenderbim/bim/module/model/__init__.py | 1 + .../blenderbim/bim/module/model/covering.py | 39 +++++++++++++++++++ src/blenderbim/blenderbim/core/covering.py | 24 +++++++++++- 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/covering/workspace.py b/src/blenderbim/blenderbim/bim/module/covering/workspace.py index 47b85fc904..abae481529 100644 --- a/src/blenderbim/blenderbim/bim/module/covering/workspace.py +++ b/src/blenderbim/blenderbim/bim/module/covering/workspace.py @@ -139,6 +139,16 @@ class CoveringToolUI: row.label(text="", icon="EVENT_A") op = row.operator("bim.add_instance_flooring_coverings_from_walls") + elif (AuthoringData.data["predefined_type"] == "CEILING" and + type_material_usage == "IfcMaterialLayerSet" and + element and + bpy.context.selected_objects and + element.is_a("IfcWall")): + row = cls.layout.row(align=True) + row.label(text="", icon="EVENT_SHIFT") + row.label(text="", icon="EVENT_A") + op = row.operator("bim.add_instance_ceiling_coverings_from_walls") + elif (element and bpy.context.selected_objects and element.is_a("IfcCovering") and @@ -243,7 +253,7 @@ class Hotkey(bpy.types.Operator, Operator): bpy.ops.bim.add_constr_type_instance() elif AuthoringData.data["predefined_type"] == "CEILING": if element and bpy.context.selected_objects and element.is_a("IfcWall"): - pass + bpy.ops.bim.add_instance_ceiling_coverings_from_walls() elif tool.Ifc.get_entity(collection_obj): bpy.ops.bim.add_instance_ceiling_covering_from_cursor() else: diff --git a/src/blenderbim/blenderbim/bim/module/model/__init__.py b/src/blenderbim/blenderbim/bim/module/model/__init__.py index 7fe9bc021e..47253d5047 100644 --- a/src/blenderbim/blenderbim/bim/module/model/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/model/__init__.py @@ -108,6 +108,7 @@ classes = ( space.GenerateSpace, space.GenerateSpacesFromWalls, covering.AddInstanceFlooringCoveringsFromWalls, + covering.AddInstanceCeilingCoveringsFromWalls, covering.AddInstanceFlooringCoveringFromCursor, covering.AddInstanceCeilingCoveringFromCursor, covering.RegenSelectedCoveringObject, diff --git a/src/blenderbim/blenderbim/bim/module/model/covering.py b/src/blenderbim/blenderbim/bim/module/model/covering.py index 17256b56f0..9d9729be56 100644 --- a/src/blenderbim/blenderbim/bim/module/model/covering.py +++ b/src/blenderbim/blenderbim/bim/module/model/covering.py @@ -145,3 +145,42 @@ class AddInstanceFlooringCoveringsFromWalls(bpy.types.Operator, tool.Ifc.Operato core.add_instance_flooring_coverings_from_walls(tool.Ifc, tool.Spatial, tool.Collector, tool.Geometry) +class AddInstanceCeilingCoveringsFromWalls(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.add_instance_ceiling_coverings_from_walls" + bl_label = "Add Ceilings From Walls" + bl_options = {"REGISTER", "UNDO"} + bl_description = "Add instance ceiling coverings from selected walls. The active object must be a wall and layered vertically" + + @classmethod + def poll(cls, context): + active_obj = bpy.context.active_object + element = tool.Ifc.get_entity(active_obj) + if element: + if element.is_a("IfcWall") and tool.Model.get_usage_type(element) == "LAYER2": + return context.selected_objects + + def _execute(self, context): + # This only works based on a 2D plan only considering the standard + # walls (i.e. prismatic) in the active object storey. + # In order to run, the active object must be a wall and + # there must be selected walls + + active_obj = bpy.context.active_object + if not active_obj: + self.report({"ERROR"}, "No active object. Please select a wall") + return + + element = tool.Ifc.get_entity(active_obj) + if element and not element.is_a("IfcWall"): + return self.report({"ERROR"}, "The active object is not a wall. Please select a wall.") + + container = ifcopenshell.util.element.get_container(element) + if not container: + self.report({"ERROR"}, "The wall is not contained.") + + if not bpy.context.selected_objects: + self.report({"ERROR"}, "No selected objects found. Please select walls.") + return + + core.add_instance_ceiling_coverings_from_walls(tool.Ifc, tool.Spatial, tool.Collector, tool.Geometry, tool.Covering) + diff --git a/src/blenderbim/blenderbim/core/covering.py b/src/blenderbim/blenderbim/core/covering.py index 65b07bcee0..e764dd4c78 100644 --- a/src/blenderbim/blenderbim/core/covering.py +++ b/src/blenderbim/blenderbim/core/covering.py @@ -124,7 +124,7 @@ def regen_selected_covering_object(ifc, spatial, model, Type, geometry): body = spatial.get_body_representation(active_obj) spatial.regen_obj_representation(ifc, geometry, active_obj, body) - +#TODO CHECK IF IT IS POSSIBLE TO CREATE ONLY ONE CORE FUNCTION FOR _FROM_WALLS def add_instance_flooring_coverings_from_walls(ifc, spatial, collector, geometry): z = spatial.get_active_obj_z() union = spatial.get_union_shape_from_selected_objects() @@ -148,3 +148,25 @@ def add_instance_flooring_coverings_from_walls(ifc, spatial, collector, geometry body = spatial.get_body_representation(obj) spatial.regen_obj_representation(ifc, geometry, obj, body) +def add_instance_ceiling_coverings_from_walls(ifc, spatial, collector, geometry, covering): + z = covering.get_z_from_ceiling_height() + union = spatial.get_union_shape_from_selected_objects() + for i, linear_ring in enumerate(union.interiors): + poly = spatial.get_buffered_poly_from_linear_ring(linear_ring) + bm = spatial.get_bmesh_from_polygon(poly, h=0) + + name = "Covering" + str(i) + obj = spatial.get_named_obj_from_bmesh(name, bmesh = bm) + + spatial.set_obj_origin_to_bboxcenter(obj) + spatial.traslate_obj_to_z_location(obj, z) + spatial.link_obj_to_active_collection(obj) + + points = spatial.get_2d_vertices_from_obj(obj) + + spatial.assign_type_to_obj(obj) + spatial.assign_container_to_obj(obj) + + spatial.assign_swept_area_outer_curve_from_2d_vertices(obj, vertices = points) + body = spatial.get_body_representation(obj) + spatial.regen_obj_representation(ifc, geometry, obj, body)