mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
Adding a preview popup for IFC Type additions
This commit is contained in:
@@ -17,11 +17,13 @@
|
|||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from . import handler, prop, ui, grid, product, wall, slab, stair, opening, pie, workspace
|
from . import handler, prop, ui, grid, product, wall, slab, stair, opening, pie, workspace, profile
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
product.AddEmptyType,
|
product.AddEmptyType,
|
||||||
product.AddTypeInstance,
|
product.AddTypeInstance,
|
||||||
|
product.DisplayIFCTypes,
|
||||||
|
product.AddIFCTypeInstance,
|
||||||
product.AlignProduct,
|
product.AlignProduct,
|
||||||
product.DynamicallyVoidProduct,
|
product.DynamicallyVoidProduct,
|
||||||
workspace.Hotkey,
|
workspace.Hotkey,
|
||||||
@@ -32,6 +34,7 @@ classes = (
|
|||||||
opening.AddElementOpening,
|
opening.AddElementOpening,
|
||||||
profile.ExtendProfile,
|
profile.ExtendProfile,
|
||||||
prop.BIMModelProperties,
|
prop.BIMModelProperties,
|
||||||
|
prop.IfcTypeInfo,
|
||||||
ui.BIM_PT_authoring,
|
ui.BIM_PT_authoring,
|
||||||
ui.BIM_PT_authoring_architectural,
|
ui.BIM_PT_authoring_architectural,
|
||||||
grid.BIM_OT_add_object,
|
grid.BIM_OT_add_object,
|
||||||
@@ -51,6 +54,7 @@ def register():
|
|||||||
if not bpy.app.background:
|
if not bpy.app.background:
|
||||||
bpy.utils.register_tool(workspace.BimTool, after={"builtin.scale_cage"}, separator=True, group=True)
|
bpy.utils.register_tool(workspace.BimTool, after={"builtin.scale_cage"}, separator=True, group=True)
|
||||||
bpy.types.Scene.BIMModelProperties = bpy.props.PointerProperty(type=prop.BIMModelProperties)
|
bpy.types.Scene.BIMModelProperties = bpy.props.PointerProperty(type=prop.BIMModelProperties)
|
||||||
|
bpy.types.Scene.IfcTypeInfo = bpy.props.CollectionProperty(type=prop.IfcTypeInfo)
|
||||||
bpy.types.VIEW3D_MT_mesh_add.append(grid.add_object_button)
|
bpy.types.VIEW3D_MT_mesh_add.append(grid.add_object_button)
|
||||||
bpy.types.VIEW3D_MT_mesh_add.append(stair.add_object_button)
|
bpy.types.VIEW3D_MT_mesh_add.append(stair.add_object_button)
|
||||||
bpy.types.VIEW3D_MT_mesh_add.append(opening.add_object_button)
|
bpy.types.VIEW3D_MT_mesh_add.append(opening.add_object_button)
|
||||||
@@ -68,6 +72,7 @@ def unregister():
|
|||||||
if not bpy.app.background:
|
if not bpy.app.background:
|
||||||
bpy.utils.unregister_tool(workspace.BimTool)
|
bpy.utils.unregister_tool(workspace.BimTool)
|
||||||
del bpy.types.Scene.BIMModelProperties
|
del bpy.types.Scene.BIMModelProperties
|
||||||
|
del bpy.types.Scene.IfcTypeInfo
|
||||||
bpy.app.handlers.load_post.remove(handler.load_post)
|
bpy.app.handlers.load_post.remove(handler.load_post)
|
||||||
bpy.types.VIEW3D_MT_mesh_add.remove(grid.add_object_button)
|
bpy.types.VIEW3D_MT_mesh_add.remove(grid.add_object_button)
|
||||||
bpy.types.VIEW3D_MT_mesh_add.remove(stair.add_object_button)
|
bpy.types.VIEW3D_MT_mesh_add.remove(stair.add_object_button)
|
||||||
|
|||||||
@@ -18,6 +18,10 @@
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
|
||||||
|
|
||||||
|
preview_icon_ids = {}
|
||||||
|
|
||||||
|
|
||||||
def refresh():
|
def refresh():
|
||||||
@@ -31,10 +35,23 @@ class AuthoringData:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def load(cls):
|
def load(cls):
|
||||||
cls.is_loaded = True
|
cls.is_loaded = True
|
||||||
cls.data = {
|
if not hasattr(cls, "data"):
|
||||||
"ifc_classes": cls.ifc_classes(),
|
cls.data = {}
|
||||||
"relating_types": cls.relating_types(),
|
cls.load_ifc_classes()
|
||||||
}
|
cls.load_relating_types()
|
||||||
|
cls.load_preview_ifc_types()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_ifc_classes(cls):
|
||||||
|
cls.data["ifc_classes"] = cls.ifc_classes()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_relating_types(cls):
|
||||||
|
cls.data["relating_types"] = cls.relating_types()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_preview_ifc_types(cls):
|
||||||
|
cls.data["preview_ifc_types"] = preview_icon_ids
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def ifc_classes(cls):
|
def ifc_classes(cls):
|
||||||
@@ -49,16 +66,71 @@ class AuthoringData:
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def relating_types(cls):
|
def ifc_class_entities(cls, ifc_class=None):
|
||||||
ifc_classes = cls.ifc_classes()
|
ifc_classes = cls.data["ifc_classes"]
|
||||||
if not ifc_classes:
|
if not ifc_classes:
|
||||||
return []
|
return []
|
||||||
results = []
|
results = []
|
||||||
ifc_class = bpy.context.scene.BIMModelProperties.ifc_class
|
if ifc_class is None:
|
||||||
|
ifc_class = bpy.context.scene.BIMModelProperties.ifc_class
|
||||||
if not ifc_class and ifc_classes:
|
if not ifc_class and ifc_classes:
|
||||||
ifc_class = ifc_classes[0][0]
|
ifc_class = ifc_classes[0][0]
|
||||||
if ifc_class:
|
if ifc_class:
|
||||||
elements = [(str(e.id()), e.Name, e.Description or "") for e in tool.Ifc.get().by_type(ifc_class)]
|
elements = sorted(tool.Ifc.get().by_type(ifc_class), key=lambda s: s.Name)
|
||||||
results.extend(sorted(elements, key=lambda s: s[1]))
|
results.extend(elements)
|
||||||
return results
|
return results
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def relating_types(cls, ifc_class=None):
|
||||||
|
return [(str(e.id()), e.Name, e.Description or "") for e in cls.ifc_class_entities(ifc_class=ifc_class)]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def assetize_relating_type_from_selection(cls):
|
||||||
|
props = bpy.context.scene.BIMModelProperties
|
||||||
|
ifc_class = props.ifc_class
|
||||||
|
relating_type_id = props.relating_type
|
||||||
|
ifc_class_occurrences = cls.ifc_class_entities(ifc_class=ifc_class)
|
||||||
|
ifc_class_occurrences = [entity for entity in ifc_class_occurrences if entity.id() == int(relating_type_id)]
|
||||||
|
if len(ifc_class_occurrences) == 0:
|
||||||
|
return
|
||||||
|
ifc_class_entity = ifc_class_occurrences[0]
|
||||||
|
obj = tool.Ifc.get_object(ifc_class_entity)
|
||||||
|
relating_type = ifc_class_entity.Name
|
||||||
|
to_be_deleted = False
|
||||||
|
if obj.type == 'EMPTY':
|
||||||
|
bpy.ops.bim.add_type_instance()
|
||||||
|
new_obj = bpy.context.selected_objects[-1]
|
||||||
|
if new_obj is not None:
|
||||||
|
to_be_deleted = True
|
||||||
|
obj = new_obj
|
||||||
|
obj.asset_mark()
|
||||||
|
obj.asset_generate_preview()
|
||||||
|
icon_id = obj.preview.icon_id
|
||||||
|
if ifc_class not in cls.data["preview_ifc_types"]:
|
||||||
|
cls.data["preview_ifc_types"][ifc_class] = {}
|
||||||
|
cls.data["preview_ifc_types"][ifc_class][relating_type] = {"icon_id": icon_id, "object": obj}
|
||||||
|
if to_be_deleted:
|
||||||
|
for col in obj.users_collection:
|
||||||
|
col.objects.unlink(obj)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def ifc_type_info(ifc_class):
|
||||||
|
ifc_type_infos = [element for element in bpy.context.scene.IfcTypeInfo if element.ifc_class == ifc_class]
|
||||||
|
return None if len(ifc_type_infos) == 0 else ifc_type_infos[0]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def new_ifc_type_instance(cls, ifc_class, relating_type_id):
|
||||||
|
props = bpy.context.scene.BIMModelProperties
|
||||||
|
props.ifc_class = ifc_class
|
||||||
|
props.relating_type = str(relating_type_id)
|
||||||
|
bpy.ops.bim.add_type_instance()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def relating_type_name_by_id(ifc_class, relating_type_id):
|
||||||
|
file = IfcStore.get_file()
|
||||||
|
try:
|
||||||
|
ifc_class_entity = file.by_id(int(relating_type_id))
|
||||||
|
except (RuntimeError, ValueError):
|
||||||
|
return None
|
||||||
|
return ifc_class_entity.Name if ifc_class_entity.is_a() == ifc_class else None
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import blenderbim.core.type
|
|||||||
import blenderbim.core.geometry
|
import blenderbim.core.geometry
|
||||||
from . import wall, slab, profile, mep
|
from . import wall, slab, profile, mep
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
from blenderbim.bim.module.model.data import AuthoringData
|
||||||
from ifcopenshell.api.pset.data import Data as PsetData
|
from ifcopenshell.api.pset.data import Data as PsetData
|
||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from bpy_extras.object_utils import AddObjectHelper
|
from bpy_extras.object_utils import AddObjectHelper
|
||||||
@@ -152,7 +153,8 @@ class AddTypeInstance(bpy.types.Operator):
|
|||||||
context.view_layer.objects.active = obj
|
context.view_layer.objects.active = obj
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def generate_layered_element(self, ifc_class, relating_type):
|
@staticmethod
|
||||||
|
def generate_layered_element(ifc_class, relating_type):
|
||||||
layer_set_direction = None
|
layer_set_direction = None
|
||||||
|
|
||||||
parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric")
|
parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric")
|
||||||
@@ -174,6 +176,83 @@ class AddTypeInstance(bpy.types.Operator):
|
|||||||
pass # Dumb block generator? Eh? :)
|
pass # Dumb block generator? Eh? :)
|
||||||
|
|
||||||
|
|
||||||
|
class DisplayIFCTypes(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.display_ifc_types"
|
||||||
|
bl_label = "Browse IFC Types"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Display all possible IFC types for new instances"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
bpy.ops.object.mode_set(mode="OBJECT")
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
if not AuthoringData.is_loaded:
|
||||||
|
AuthoringData.load()
|
||||||
|
props = context.scene.BIMModelProperties
|
||||||
|
props.relating_type = props.relating_type
|
||||||
|
min_width = 250
|
||||||
|
width = max([min_width, int(context.region.width / 7)])
|
||||||
|
return context.window_manager.invoke_popup(self, width=width)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
props = context.scene.BIMModelProperties
|
||||||
|
split = layout.split(align=True, factor=0.6)
|
||||||
|
col = split.column(align=True)
|
||||||
|
row = col.row()
|
||||||
|
row.label(text="Select IFC Type to add:")
|
||||||
|
col.row().separator(factor=2)
|
||||||
|
enabled = True
|
||||||
|
if AuthoringData.data["ifc_classes"]:
|
||||||
|
row = col.row()
|
||||||
|
row.prop(data=props, property="ifc_class", text="", icon="FILE_VOLUME")
|
||||||
|
col.row().separator()
|
||||||
|
else:
|
||||||
|
enabled = False
|
||||||
|
if AuthoringData.data["relating_types"]:
|
||||||
|
row = col.row()
|
||||||
|
row.prop(data=props, property="relating_type", text="", icon="FILE_3D")
|
||||||
|
col.row().separator()
|
||||||
|
else:
|
||||||
|
enabled = False
|
||||||
|
col.row().separator(factor=4)
|
||||||
|
row = col.row()
|
||||||
|
op = row.operator("bim.add_ifc_type_instance", icon="ADD")
|
||||||
|
row.enabled = enabled
|
||||||
|
op.ifc_class = props.ifc_class
|
||||||
|
op.relating_type_id = props.relating_type
|
||||||
|
col = split.column()
|
||||||
|
box = col.box()
|
||||||
|
if enabled:
|
||||||
|
box.template_icon(icon_value=props.icon_id, scale=6.)
|
||||||
|
|
||||||
|
|
||||||
|
class AddIFCTypeInstance(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_ifc_type_instance"
|
||||||
|
bl_label = "Add"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Add an instance of this IFC type"
|
||||||
|
ifc_class: bpy.props.StringProperty()
|
||||||
|
relating_type_id: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
def close_panel(self, event):
|
||||||
|
x, y = event.mouse_x, event.mouse_y
|
||||||
|
bpy.context.window.cursor_warp(10, 10)
|
||||||
|
move_back = lambda: bpy.context.window.cursor_warp(x, y)
|
||||||
|
bpy.app.timers.register(move_back, first_interval=0.001)
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
self.close_panel(event)
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = context.scene.BIMModelProperties
|
||||||
|
props.ifc_class, props.relating_type = self.ifc_class, self.relating_type_id
|
||||||
|
bpy.ops.bim.add_type_instance()
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class AlignProduct(bpy.types.Operator):
|
class AlignProduct(bpy.types.Operator):
|
||||||
bl_idname = "bim.align_product"
|
bl_idname = "bim.align_product"
|
||||||
bl_label = "Align Product"
|
bl_label = "Align Product"
|
||||||
|
|||||||
@@ -21,17 +21,8 @@ import ifcopenshell.util.type
|
|||||||
from blenderbim.bim.module.model.data import AuthoringData
|
from blenderbim.bim.module.model.data import AuthoringData
|
||||||
from blenderbim.bim.prop import StrProperty, Attribute
|
from blenderbim.bim.prop import StrProperty, Attribute
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
import blenderbim.tool as tool
|
||||||
from bpy.types import PropertyGroup
|
from bpy.types import PropertyGroup
|
||||||
from bpy.props import (
|
|
||||||
PointerProperty,
|
|
||||||
StringProperty,
|
|
||||||
EnumProperty,
|
|
||||||
BoolProperty,
|
|
||||||
IntProperty,
|
|
||||||
FloatProperty,
|
|
||||||
FloatVectorProperty,
|
|
||||||
CollectionProperty,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_ifc_class(self, context):
|
def get_ifc_class(self, context):
|
||||||
@@ -46,15 +37,50 @@ def get_relating_type(self, context):
|
|||||||
return AuthoringData.data["relating_types"]
|
return AuthoringData.data["relating_types"]
|
||||||
|
|
||||||
|
|
||||||
|
def update_icon_id(self, context):
|
||||||
|
ifc_class = self.ifc_class
|
||||||
|
relating_type_id = self.relating_type
|
||||||
|
relating_type = AuthoringData.relating_type_name_by_id(ifc_class, relating_type_id)
|
||||||
|
if ((ifc_class not in AuthoringData.data["preview_ifc_types"]
|
||||||
|
or relating_type not in AuthoringData.data["preview_ifc_types"][ifc_class])
|
||||||
|
and relating_type is not None):
|
||||||
|
AuthoringData.assetize_relating_type_from_selection()
|
||||||
|
props = bpy.context.scene.BIMModelProperties
|
||||||
|
props.icon_id = AuthoringData.data["preview_ifc_types"][ifc_class][relating_type]["icon_id"]
|
||||||
|
|
||||||
|
|
||||||
def update_ifc_class(self, context):
|
def update_ifc_class(self, context):
|
||||||
AuthoringData.is_loaded = False
|
AuthoringData.load_ifc_classes()
|
||||||
|
AuthoringData.load_relating_types()
|
||||||
|
self.relating_type = AuthoringData.data["relating_types"][0][0]
|
||||||
|
update_icon_id(self, context)
|
||||||
|
|
||||||
|
|
||||||
|
def update_relating_type(self, context):
|
||||||
|
AuthoringData.load_relating_types()
|
||||||
|
update_icon_id(self, context)
|
||||||
|
|
||||||
|
|
||||||
class BIMModelProperties(PropertyGroup):
|
class BIMModelProperties(PropertyGroup):
|
||||||
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="IFC Class", update=update_ifc_class)
|
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="IFC Class", update=update_ifc_class)
|
||||||
relating_type: bpy.props.EnumProperty(items=get_relating_type, name="Relating Type")
|
relating_type: bpy.props.EnumProperty(items=get_relating_type, name="Relating Type", update=update_relating_type)
|
||||||
|
icon_id: bpy.props.IntProperty()
|
||||||
occurrence_name_style: bpy.props.EnumProperty(
|
occurrence_name_style: bpy.props.EnumProperty(
|
||||||
items=[("CLASS", "By Class", ""), ("TYPE", "By Type", ""), ("CUSTOM", "Custom", "")],
|
items=[("CLASS", "By Class", ""), ("TYPE", "By Type", ""), ("CUSTOM", "Custom", "")],
|
||||||
name="Occurrence Name Style",
|
name="Occurrence Name Style",
|
||||||
)
|
)
|
||||||
occurrence_name_function: bpy.props.StringProperty(name="Occurrence Name Function")
|
occurrence_name_function: bpy.props.StringProperty(name="Occurrence Name Function")
|
||||||
|
|
||||||
|
|
||||||
|
def get_ifc_type_info_relating_types(self, context):
|
||||||
|
ifc_class = self.ifc_class
|
||||||
|
return AuthoringData.relating_types(ifc_class=ifc_class)
|
||||||
|
|
||||||
|
|
||||||
|
class IfcTypeInfo(PropertyGroup):
|
||||||
|
ifc_class: bpy.props.StringProperty(name="IFC class", description="IFC class")
|
||||||
|
relating_type: bpy.props.EnumProperty(
|
||||||
|
name="Relating type", description="Relating type", items=get_ifc_type_info_relating_types
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class BimTool(WorkSpaceTool):
|
|||||||
bl_keymap = (
|
bl_keymap = (
|
||||||
# ("bim.wall_tool_op", {"type": 'MOUSEMOVE', "value": 'ANY'}, {"properties": []}),
|
# ("bim.wall_tool_op", {"type": 'MOUSEMOVE', "value": 'ANY'}, {"properties": []}),
|
||||||
# ("mesh.add_wall", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": []}),
|
# ("mesh.add_wall", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": []}),
|
||||||
("bim.hotkey", {"type": "A", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_A")]}),
|
|
||||||
("bim.hotkey", {"type": "E", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_E")]}),
|
("bim.hotkey", {"type": "E", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_E")]}),
|
||||||
("bim.join_wall", {"type": "T", "value": "PRESS", "shift": True}, {"properties": [("join_type", "L")]}),
|
("bim.join_wall", {"type": "T", "value": "PRESS", "shift": True}, {"properties": [("join_type", "L")]}),
|
||||||
("bim.join_wall", {"type": "Y", "value": "PRESS", "shift": True}, {"properties": [("join_type", "V")]}),
|
("bim.join_wall", {"type": "Y", "value": "PRESS", "shift": True}, {"properties": [("join_type", "V")]}),
|
||||||
@@ -61,20 +60,14 @@ class BimTool(WorkSpaceTool):
|
|||||||
return
|
return
|
||||||
props = context.scene.BIMModelProperties
|
props = context.scene.BIMModelProperties
|
||||||
if AuthoringData.data["ifc_classes"]:
|
if AuthoringData.data["ifc_classes"]:
|
||||||
row.prop(props, "ifc_class", text="")
|
row.operator("bim.display_ifc_types", icon="COLLAPSEMENU")
|
||||||
else:
|
else:
|
||||||
row.label(text="No IFC Class")
|
row.label(text="No IFC Class")
|
||||||
if AuthoringData.data["relating_types"]:
|
if not AuthoringData.data["relating_types"]:
|
||||||
row.prop(props, "relating_type", text="")
|
|
||||||
else:
|
|
||||||
row.label(text="No Relating Type")
|
row.label(text="No Relating Type")
|
||||||
|
|
||||||
row.label(text="", icon="BLANK1")
|
row.label(text="", icon="BLANK1")
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
|
||||||
row.label(text="Add Type Instance", icon="EVENT_A")
|
|
||||||
|
|
||||||
if AuthoringData.data["ifc_classes"]:
|
if AuthoringData.data["ifc_classes"]:
|
||||||
if props.ifc_class == "IfcWallType":
|
if props.ifc_class == "IfcWallType":
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
@@ -155,9 +148,6 @@ class Hotkey(bpy.types.Operator):
|
|||||||
getattr(self, f"hotkey_{self.hotkey}")()
|
getattr(self, f"hotkey_{self.hotkey}")()
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def hotkey_S_A(self):
|
|
||||||
bpy.ops.bim.add_type_instance()
|
|
||||||
|
|
||||||
def hotkey_S_C(self):
|
def hotkey_S_C(self):
|
||||||
if self.has_ifc_class and self.props.ifc_class == "IfcWallType":
|
if self.has_ifc_class and self.props.ifc_class == "IfcWallType":
|
||||||
bpy.ops.bim.align_wall(align_type="CENTERLINE")
|
bpy.ops.bim.align_wall(align_type="CENTERLINE")
|
||||||
|
|||||||
Reference in New Issue
Block a user