From 74132dcd4905ead0108986e6d9dca2b3b29dbab0 Mon Sep 17 00:00:00 2001 From: Massimo Fabbro Date: Sun, 22 Oct 2023 22:12:56 +0200 Subject: [PATCH] New operator that creates a ceiling from cursor position in covering tool --- .../blenderbim/bim/module/covering/prop.py | 10 ++-- .../bim/module/covering/workspace.py | 40 +++++++++++---- .../blenderbim/bim/module/model/__init__.py | 3 +- .../blenderbim/bim/module/model/covering.py | 39 ++++++++++++-- src/blenderbim/blenderbim/core/covering.py | 51 ++++++++++++++++--- src/blenderbim/blenderbim/core/tool.py | 3 ++ src/blenderbim/blenderbim/tool/__init__.py | 1 + src/blenderbim/blenderbim/tool/covering.py | 4 ++ 8 files changed, 121 insertions(+), 30 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/covering/prop.py b/src/blenderbim/blenderbim/bim/module/covering/prop.py index 330632ab05..76cd6ee3e0 100644 --- a/src/blenderbim/blenderbim/bim/module/covering/prop.py +++ b/src/blenderbim/blenderbim/bim/module/covering/prop.py @@ -30,12 +30,10 @@ from bpy.props import ( FloatVectorProperty, CollectionProperty, ) -import blenderbim.tool as tool -import blenderbim.core.geometry -import ifcopenshell +#import blenderbim.tool as tool +#import blenderbim.core.geometry +#import ifcopenshell class BIMCoveringProperties(PropertyGroup): - pass -# depth: bpy.props.FloatProperty(name="Depth", default=0.1, subtype="DISTANCE", description="Flooring depth") - depth: bpy.props.FloatProperty(name="ceiling_height", default=2.7, subtype="DISTANCE", description="Ceiling height") + ceiling_height: bpy.props.FloatProperty(name="ceiling_height", default=2.7, subtype="DISTANCE", description="Ceiling height") diff --git a/src/blenderbim/blenderbim/bim/module/covering/workspace.py b/src/blenderbim/blenderbim/bim/module/covering/workspace.py index 1fae82b3c4..47b85fc904 100644 --- a/src/blenderbim/blenderbim/bim/module/covering/workspace.py +++ b/src/blenderbim/blenderbim/bim/module/covering/workspace.py @@ -92,6 +92,8 @@ class CoveringToolUI: def draw_default_interface(cls): row = cls.layout.row(align=True) row.prop(data=cls.props, property="rl3", text="RL") + row = cls.layout.row(align=True) + row.prop(data=cls.covering_props, property="ceiling_height", text="Ceiling Height") if AuthoringData.data["ifc_classes"]: active_obj = bpy.context.active_object element = tool.Ifc.get_entity(active_obj) @@ -101,17 +103,26 @@ class CoveringToolUI: relating_type_id = int(cls.props.relating_type_id) type_material_usage = ifcopenshell.util.element.get_material(tool.Ifc.get().by_id(relating_type_id)).is_a() - if (AuthoringData.data["predefined_type"] == "FLOORING" and - type_material_usage == "IfcMaterialLayerSet" and +# PLEASE KEEP COMMENTS AS A REMINDER +# elif element and bpy.context.selected_objects and element.is_a("IfcSpace"): +# op. = row.operator("bim.add_istance_flooring_from_spaces"): + + if (type_material_usage == "IfcMaterialLayerSet" and not bpy.context.selected_objects): row = cls.layout.row(align=True) row.label(text="", icon="EVENT_SHIFT") row.label(text="", icon="EVENT_A") -# PLEASE KEEP COMMENTS AS A REMINDER -# elif element and bpy.context.selected_objects and element.is_a("IfcSpace"): -# op. = row.operator("bim.add_istance_flooring_from_spaces"): if tool.Ifc.get_entity(collection_obj): - op = row.operator("bim.add_instance_flooring_covering_from_cursor") + if AuthoringData.data["predefined_type"] == "FLOORING": + op = row.operator("bim.add_instance_flooring_covering_from_cursor") + elif AuthoringData.data["predefined_type"] == "CEILING": + op = row.operator("bim.add_instance_ceiling_covering_from_cursor") + else: + op = row.operator("bim.add_constr_type_instance", text="Add") + op.from_invoke = True + if cls.props.relating_type_id.isnumeric(): + op.relating_type_id = int(cls.props.relating_type_id) + else: op = row.operator("bim.add_constr_type_instance", text="Add") op.from_invoke = True @@ -136,7 +147,7 @@ class CoveringToolUI: row = cls.layout.row(align=True) row.label(text="", icon="EVENT_SHIFT") row.label(text="", icon="EVENT_G") - op = row.operator("bim.regen_selected_flooring_object") + op = row.operator("bim.regen_selected_covering_object") @@ -230,13 +241,22 @@ class Hotkey(bpy.types.Operator, Operator): bpy.ops.bim.add_instance_flooring_covering_from_cursor() else: 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 + elif tool.Ifc.get_entity(collection_obj): + bpy.ops.bim.add_instance_ceiling_covering_from_cursor() + else: + bpy.ops.bim.add_constr_type_instance() else: bpy.ops.bim.add_constr_type_instance() def hotkey_S_G(self): active_obj = bpy.context.active_object element = tool.Ifc.get_entity(active_obj) + if (element and + bpy.context.selected_objects and + element.is_a("IfcCovering") and + AuthoringData.data["active_material_usage"] == "LAYER3"): + bpy.ops.bim.regen_selected_covering_object() - if AuthoringData.data["predefined_type"] == "FLOORING": - if element and bpy.context.selected_objects and element.is_a("IfcCovering"): - bpy.ops.bim.regen_selected_flooring_object() diff --git a/src/blenderbim/blenderbim/bim/module/model/__init__.py b/src/blenderbim/blenderbim/bim/module/model/__init__.py index ee8f23eca5..7fe9bc021e 100644 --- a/src/blenderbim/blenderbim/bim/module/model/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/model/__init__.py @@ -109,7 +109,8 @@ classes = ( space.GenerateSpacesFromWalls, covering.AddInstanceFlooringCoveringsFromWalls, covering.AddInstanceFlooringCoveringFromCursor, - covering.RegenSelectedFlooringObject, + covering.AddInstanceCeilingCoveringFromCursor, + covering.RegenSelectedCoveringObject, space.ToggleSpaceVisibility, mep.FitFlowSegments, mep.RegenerateDistributionElement, diff --git a/src/blenderbim/blenderbim/bim/module/model/covering.py b/src/blenderbim/blenderbim/bim/module/model/covering.py index 81e2c3cfcd..17256b56f0 100644 --- a/src/blenderbim/blenderbim/bim/module/model/covering.py +++ b/src/blenderbim/blenderbim/bim/module/model/covering.py @@ -51,11 +51,40 @@ class AddInstanceFlooringCoveringFromCursor(bpy.types.Operator, tool.Ifc.Operato core.add_instance_flooring_covering_from_cursor(tool.Ifc, tool.Spatial, tool.Model, tool.Type, tool.Geometry) -class RegenSelectedFlooringObject(bpy.types.Operator, tool.Ifc.Operator): - bl_idname = "bim.regen_selected_flooring_object" - bl_label = "Regen Flooring" +class AddInstanceCeilingCoveringFromCursor(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.add_instance_ceiling_covering_from_cursor" + bl_label = "Add Ceiling From Cursor" bl_options = {"REGISTER"} - bl_description = "Regen selected flooring object" + bl_description = "Add a typed instance ceiling covering from cursor position. Move the cursor position into the desired position, select the right space collection and run the operator" + + @classmethod + def poll(cls, context): + collection = context.view_layer.active_layer_collection.collection + collection_obj = collection.BIMCollectionProperties.obj + return tool.Ifc.get_entity(collection_obj) + + def _execute(self, context): + + def msg(self, context): + self.layout.label(text="NO ACTIVE STOREY") + + collection = context.view_layer.active_layer_collection.collection + collection_obj = collection.BIMCollectionProperties.obj + if not collection_obj: + bpy.context.window_manager.popup_menu(msg, title="Error", icon="ERROR") + return + spatial_element = tool.Ifc.get_entity(collection_obj) + if not spatial_element: + bpy.context.window_manager.popup_menu(msg, title="Error", icon="ERROR") + return + + core.add_instance_ceiling_covering_from_cursor(tool.Ifc, tool.Spatial, tool.Model, tool.Type, tool.Geometry, tool.Covering) + +class RegenSelectedCoveringObject(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.regen_selected_covering_object" + bl_label = "Regen" + bl_options = {"REGISTER"} + bl_description = "Regen selected covering object" @classmethod def poll(cls, context): @@ -74,7 +103,7 @@ class RegenSelectedFlooringObject(bpy.types.Operator, tool.Ifc.Operator): bpy.context.window_manager.popup_menu(msg, title="Error", icon="ERROR") return - core.regen_selected_flooring_object(tool.Ifc, tool.Spatial, tool.Model, tool.Type, tool.Geometry) + core.regen_selected_covering_object(tool.Ifc, tool.Spatial, tool.Model, tool.Type, tool.Geometry) class AddInstanceFlooringCoveringsFromWalls(bpy.types.Operator, tool.Ifc.Operator): diff --git a/src/blenderbim/blenderbim/core/covering.py b/src/blenderbim/blenderbim/core/covering.py index b7aebf457e..65b07bcee0 100644 --- a/src/blenderbim/blenderbim/core/covering.py +++ b/src/blenderbim/blenderbim/core/covering.py @@ -44,13 +44,6 @@ def add_instance_flooring_covering_from_cursor(ifc, spatial, model, Type, geomet name = "Covering" mesh = spatial.get_named_mesh_from_bmesh(name = name, bmesh = bm) - -# spatial.edit_active_space_obj_from_mesh(mesh) -# else: -# if relating_type: -# name = model.generate_occurrence_name(relating_type, "IfcCovering") -# else: - obj = spatial.get_named_obj_from_mesh(name, mesh) spatial.set_obj_origin_to_cursor_position(obj) @@ -63,7 +56,49 @@ def add_instance_flooring_covering_from_cursor(ifc, spatial, model, Type, geomet body = spatial.get_body_representation(obj) spatial.regen_obj_representation(ifc, geometry, obj, body) -def regen_selected_flooring_object(ifc, spatial, model, Type, geometry): +def add_instance_ceiling_covering_from_cursor(ifc, spatial, model, Type, geometry, covering): + active_obj = spatial.get_active_obj() + selected_objects = spatial.get_selected_objects() + element = None + relating_type_id = spatial.get_relating_type_id() + + relating_type = None + if relating_type_id: + relating_type = ifc.get().by_id(int(relating_type_id)) + if not relating_type.is_a("IfcCoveringType"): + relating_type = None + + if selected_objects and active_obj: + x, y, z, h, mat = spatial.get_x_y_z_h_mat_from_active_obj(active_obj) + element = ifc.get_entity(active_obj) + + else: + x, y, z, h, mat = spatial.get_x_y_z_h_mat_from_cursor() + z = covering.get_z_from_ceiling_height() + + space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y) + + if not space_polygon: + return + + bm = spatial.get_bmesh_from_polygon(space_polygon, h=0) + name = "Covering" + mesh = spatial.get_named_mesh_from_bmesh(name = name, bmesh = bm) + + obj = spatial.get_named_obj_from_mesh(name, mesh) + + spatial.set_obj_origin_to_cursor_position(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_swept_area_outer_curve_from_2d_vertices(obj, vertices = points) + body = spatial.get_body_representation(obj) + spatial.regen_obj_representation(ifc, geometry, obj, body) + + +def regen_selected_covering_object(ifc, spatial, model, Type, geometry): active_obj = spatial.get_active_obj() selected_objects = spatial.get_selected_objects() diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 076787b378..a373531533 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -851,6 +851,9 @@ class Spatial: def regen_obj_representation(cls, ifc, geometry, obj, body): pass def toggle_spaces_visibility_wired_and_textured(cls, spaces): pass +@interface +class Covering: + def get_z_from_ceiling_height(cls): pass @interface class Structural: diff --git a/src/blenderbim/blenderbim/tool/__init__.py b/src/blenderbim/blenderbim/tool/__init__.py index 54f5e9ea57..5b63b278d7 100644 --- a/src/blenderbim/blenderbim/tool/__init__.py +++ b/src/blenderbim/blenderbim/tool/__init__.py @@ -47,6 +47,7 @@ from blenderbim.tool.resource import Resource from blenderbim.tool.root import Root from blenderbim.tool.sequence import Sequence from blenderbim.tool.spatial import Spatial +from blenderbim.tool.covering import Covering from blenderbim.tool.structural import Structural from blenderbim.tool.style import Style from blenderbim.tool.surveyor import Surveyor diff --git a/src/blenderbim/blenderbim/tool/covering.py b/src/blenderbim/blenderbim/tool/covering.py index cfbae2f807..decc60bc06 100644 --- a/src/blenderbim/blenderbim/tool/covering.py +++ b/src/blenderbim/blenderbim/tool/covering.py @@ -32,6 +32,10 @@ from shapely import Polygon, MultiPolygon class Covering(blenderbim.core.tool.Covering): @classmethod + def get_z_from_ceiling_height(cls): + props = bpy.context.scene.BIMCoveringProperties + return props.ceiling_height + # def toggle_spaces_visibility_wired_and_textured(cls, spaces): # first_obj = tool.Ifc.get_object(spaces[0]) # if bpy.data.objects[first_obj.name].display_type == "TEXTURED":