From 0f5264af993627f465a0ddf17c6470195da68b77 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Mon, 6 Feb 2023 14:42:40 +0500 Subject: [PATCH] Door - added to type manager Also added predefined type for door and bit of refactoring --- .../blenderbim/bim/module/model/door.py | 55 +++------------- .../blenderbim/bim/module/model/helper.py | 64 +++++++++++++++++++ .../blenderbim/bim/module/model/prop.py | 1 + .../blenderbim/bim/module/model/window.py | 43 ++----------- .../blenderbim/bim/module/type/operator.py | 17 +++++ 5 files changed, 96 insertions(+), 84 deletions(-) create mode 100644 src/blenderbim/blenderbim/bim/module/model/helper.py diff --git a/src/blenderbim/blenderbim/bim/module/model/door.py b/src/blenderbim/blenderbim/bim/module/model/door.py index ad5dc9750a..dc36918425 100644 --- a/src/blenderbim/blenderbim/bim/module/model/door.py +++ b/src/blenderbim/blenderbim/bim/module/model/door.py @@ -30,7 +30,9 @@ import blenderbim.tool as tool import blenderbim.core.geometry as core from blenderbim.bim.helper import convert_property_group_from_si from blenderbim.bim.ifc import IfcStore -from blenderbim.bim.module.model.window import create_bm_window_frame, create_bm_window, create_bm_box +from blenderbim.bim.module.model.window import create_bm_window, create_bm_box +from blenderbim.bim.module.model.helper import get_ifc_context_or_create, replace_ifc_representation_for_object + from mathutils import Vector from pprint import pprint @@ -75,66 +77,27 @@ def update_door_modifier_representation(context): }, } - def get_context_or_create(context_type, context_identifier, target_view): - ifc_context = ifcopenshell.util.representation.get_context(ifc_file, context_type, context_identifier, target_view) - if not ifc_context: - parent_context = ifcopenshell.util.representation.get_context(ifc_file, context_type) - ifc_context = ifcopenshell.api.run( - "context.add_context", - ifc_file, - context_type=context_type, - context_identifier=context_identifier, - target_view=target_view, - parent=model_context, - ) - return ifc_context - # ELEVATION_VIEW representation - ifc_context = get_context_or_create("Model", "Profile", "ELEVATION_VIEW") + ifc_context = get_ifc_context_or_create(ifc_file, "Model", "Profile", "ELEVATION_VIEW") representation_data["context"] = ifc_context elevation_representation = ifcopenshell.api.run( "geometry.add_door_representation", ifc_file, **representation_data ) - replace_representation_for_object(ifc_file, ifc_context, obj, elevation_representation) + replace_ifc_representation_for_object(ifc_file, ifc_context, obj, elevation_representation) # PLAN_VIEW representation - ifc_context = get_context_or_create("Plan", "Annotation", "PLAN_VIEW") + ifc_context = get_ifc_context_or_create(ifc_file, "Plan", "Annotation", "PLAN_VIEW") representation_data["context"] = ifc_context elevation_representation = ifcopenshell.api.run( "geometry.add_door_representation", ifc_file, **representation_data ) - replace_representation_for_object(ifc_file, ifc_context, obj, elevation_representation) + replace_ifc_representation_for_object(ifc_file, ifc_context, obj, elevation_representation) # MODEL_VIEW representation ifc_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") representation_data["context"] = ifc_context model_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data) - replace_representation_for_object(ifc_file, ifc_context, obj, model_representation) - - -def replace_representation_for_object(ifc_file, ifc_context, obj, new_representation): - ifc_element = tool.Ifc.get_entity(obj) - old_representation = ifcopenshell.util.representation.get_representation( - ifc_element, ifc_context.ContextType, ifc_context.ContextIdentifier, ifc_context.TargetView - ) - - if old_representation: - for inverse in ifc_file.get_inverse(old_representation): - ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation) - core.remove_representation(tool.Ifc, tool.Geometry, obj=obj, representation=old_representation) - else: - ifcopenshell.api.run( - "geometry.assign_representation", ifc_file, product=ifc_element, representation=new_representation - ) - core.switch_representation( - tool.Ifc, - tool.Geometry, - obj=obj, - representation=new_representation, - should_reload=True, - is_global=False, - should_sync_changes_first=True, - ) + replace_ifc_representation_for_object(ifc_file, ifc_context, obj, model_representation) def create_bm_door_lining(bm, size: Vector, thickness: Vector, position:Vector=V(0,0,0).freeze()): @@ -363,6 +326,8 @@ class BIM_OT_add_door(Operator): ifc_class="IfcDoor", should_add_representation=False ) + element.PredefinedType = "DOOR" + bpy.ops.object.select_all(action="DESELECT") bpy.context.view_layer.objects.active = None bpy.context.view_layer.objects.active = obj diff --git a/src/blenderbim/blenderbim/bim/module/model/helper.py b/src/blenderbim/blenderbim/bim/module/model/helper.py new file mode 100644 index 0000000000..61a6b07798 --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/model/helper.py @@ -0,0 +1,64 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2023 @Andrej730 +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +import bmesh +import ifcopenshell +import ifcopenshell.util.unit +import blenderbim.core.geometry as core +import blenderbim.tool as tool + + +def get_ifc_context_or_create(ifc_file, context_type, context_identifier, target_view): + ifc_context = ifcopenshell.util.representation.get_context(ifc_file, context_type, context_identifier, target_view) + if not ifc_context: + parent_context = ifcopenshell.util.representation.get_context(ifc_file, context_type) + ifc_context = ifcopenshell.api.run( + "context.add_context", + ifc_file, + context_type=context_type, + context_identifier=context_identifier, + target_view=target_view, + parent=parent_context, + ) + return ifc_context + + +def replace_ifc_representation_for_object(ifc_file, ifc_context, obj, new_representation): + ifc_element = tool.Ifc.get_entity(obj) + old_representation = ifcopenshell.util.representation.get_representation( + ifc_element, ifc_context.ContextType, ifc_context.ContextIdentifier, ifc_context.TargetView + ) + + if old_representation: + for inverse in ifc_file.get_inverse(old_representation): + ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation) + core.remove_representation(tool.Ifc, tool.Geometry, obj=obj, representation=old_representation) + else: + ifcopenshell.api.run( + "geometry.assign_representation", ifc_file, product=ifc_element, representation=new_representation + ) + core.switch_representation( + tool.Ifc, + tool.Geometry, + obj=obj, + representation=new_representation, + should_reload=True, + is_global=False, + should_sync_changes_first=True, + ) \ No newline at end of file diff --git a/src/blenderbim/blenderbim/bim/module/model/prop.py b/src/blenderbim/blenderbim/bim/module/model/prop.py index 563d915998..e634ddec74 100644 --- a/src/blenderbim/blenderbim/bim/module/model/prop.py +++ b/src/blenderbim/blenderbim/bim/module/model/prop.py @@ -242,6 +242,7 @@ class BIMModelProperties(PropertyGroup): ("PROFILESET", "Extruded Profile", ""), ("EMPTY", "Non-Geometric Type", ""), ("WINDOW", "Window", ""), + ("DOOR", "Door", ""), ("STAIR", "Stair", ""), ), name="Type Template", diff --git a/src/blenderbim/blenderbim/bim/module/model/window.py b/src/blenderbim/blenderbim/bim/module/model/window.py index 13ae289e0a..2d588c4ab4 100644 --- a/src/blenderbim/blenderbim/bim/module/model/window.py +++ b/src/blenderbim/blenderbim/bim/module/model/window.py @@ -31,6 +31,7 @@ import blenderbim.tool as tool import blenderbim.core.geometry as core from blenderbim.bim.helper import convert_property_group_from_si from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.module.model.helper import get_ifc_context_or_create, replace_ifc_representation_for_object from mathutils import Vector from pprint import pprint @@ -75,54 +76,18 @@ def update_window_modifier_representation(context): representation_data["panel_properties"].append(panel_data) # ELEVATION_VIEW representation - ifc_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Profile", "ELEVATION_VIEW") - if not ifc_context: - model_context = ifcopenshell.util.representation.get_context(ifc_file, "Model") - ifc_context = ifcopenshell.api.run( - "context.add_context", - ifc_file, - context_type="Model", - context_identifier="Profile", - target_view="ELEVATION_VIEW", - parent=model_context, - ) - + ifc_context = get_ifc_context_or_create(ifc_file, "Model", "Profile", "ELEVATION_VIEW") representation_data["context"] = ifc_context elevation_representation = ifcopenshell.api.run( "geometry.add_window_representation", ifc_file, **representation_data ) - replace_representation_for_object(ifc_file, ifc_context, obj, elevation_representation) + replace_ifc_representation_for_object(ifc_file, ifc_context, obj, elevation_representation) # MODEL_VIEW representation ifc_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") representation_data["context"] = ifc_context model_representation = ifcopenshell.api.run("geometry.add_window_representation", ifc_file, **representation_data) - replace_representation_for_object(ifc_file, ifc_context, obj, model_representation) - - -def replace_representation_for_object(ifc_file, ifc_context, obj, new_representation): - ifc_element = tool.Ifc.get_entity(obj) - old_representation = ifcopenshell.util.representation.get_representation( - ifc_element, ifc_context.ContextType, ifc_context.ContextIdentifier, ifc_context.TargetView - ) - - if old_representation: - for inverse in ifc_file.get_inverse(old_representation): - ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation) - core.remove_representation(tool.Ifc, tool.Geometry, obj=obj, representation=old_representation) - else: - ifcopenshell.api.run( - "geometry.assign_representation", ifc_file, product=ifc_element, representation=new_representation - ) - core.switch_representation( - tool.Ifc, - tool.Geometry, - obj=obj, - representation=new_representation, - should_reload=True, - is_global=False, - should_sync_changes_first=True, - ) + replace_ifc_representation_for_object(ifc_file, ifc_context, obj, model_representation) def create_bm_window_frame(bm, size: Vector, thickness: Vector, position: Vector = V(0,0,0)): diff --git a/src/blenderbim/blenderbim/bim/module/type/operator.py b/src/blenderbim/blenderbim/bim/module/type/operator.py index 07b736ef46..5cb5da0833 100644 --- a/src/blenderbim/blenderbim/bim/module/type/operator.py +++ b/src/blenderbim/blenderbim/bim/module/type/operator.py @@ -167,6 +167,7 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator): body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") if not body: return {"FINISHED"} + if template == "MESH": location = context.scene.cursor.location if context.active_object and context.selected_objects and context.active_object.data: @@ -289,6 +290,22 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator): bpy.context.view_layer.objects.active = obj obj.select_set(True) bpy.ops.bim.add_window() + elif template == "DOOR": + mesh = bpy.data.meshes.new("IfcDoor") + obj = bpy.data.objects.new("TYPEX", mesh) + element = blenderbim.core.root.assign_class( + tool.Ifc, + tool.Collector, + tool.Root, + obj=obj, + ifc_class="IfcDoorType", + should_add_representation=False + ) + bpy.ops.object.select_all(action="DESELECT") + bpy.context.view_layer.objects.active = None + bpy.context.view_layer.objects.active = obj + obj.select_set(True) + bpy.ops.bim.add_door() elif template == "STAIR": mesh = bpy.data.meshes.new("IfcStairFlight")