mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-23 13:26:36 +00:00
Modeling dimensions now have sensible defaults depending on units and show prior to element creation
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of BlenderBIM Add-on.
|
# This file is part of BlenderBIM Add-on.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of BlenderBIM Add-on.
|
# This file is part of BlenderBIM Add-on.
|
||||||
#
|
#
|
||||||
@@ -39,6 +39,7 @@ 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.sync_modeling", {"type": 'MOUSEMOVE', "value": 'ANY'}, {"properties": []}),
|
||||||
("bim.hotkey", {"type": "A", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_A")]}),
|
("bim.hotkey", {"type": "A", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_A")]}),
|
||||||
("bim.hotkey", {"type": "C", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_C")]}),
|
("bim.hotkey", {"type": "C", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_C")]}),
|
||||||
("bim.hotkey", {"type": "E", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_E")]}),
|
("bim.hotkey", {"type": "E", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_E")]}),
|
||||||
@@ -56,12 +57,18 @@ class BimTool(WorkSpaceTool):
|
|||||||
("bim.hotkey", {"type": "O", "value": "PRESS", "alt": True}, {"properties": [("hotkey", "A_O")]}),
|
("bim.hotkey", {"type": "O", "value": "PRESS", "alt": True}, {"properties": [("hotkey", "A_O")]}),
|
||||||
)
|
)
|
||||||
|
|
||||||
def draw_settings(context, layout, something):
|
def draw_settings(context, layout, ws_tool):
|
||||||
props = context.scene.BIMModelProperties
|
# Unlike operators, Blender doesn't treat workspace tools as a class, so we'll create our own.
|
||||||
is_tool_header = context.region.type == "TOOL_HEADER"
|
BimToolUI.draw(context, layout)
|
||||||
is_sidebar = context.region.type == "UI"
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
|
class BimToolUI:
|
||||||
|
@classmethod
|
||||||
|
def draw(cls, context, layout):
|
||||||
|
cls.layout = layout
|
||||||
|
cls.props = context.scene.BIMModelProperties
|
||||||
|
|
||||||
|
row = cls.layout.row(align=True)
|
||||||
if not tool.Ifc.get():
|
if not tool.Ifc.get():
|
||||||
row.label(text="No IFC Project", icon="ERROR")
|
row.label(text="No IFC Project", icon="ERROR")
|
||||||
return
|
return
|
||||||
@@ -69,121 +76,87 @@ class BimTool(WorkSpaceTool):
|
|||||||
if not AuthoringData.is_loaded:
|
if not AuthoringData.is_loaded:
|
||||||
AuthoringData.load()
|
AuthoringData.load()
|
||||||
|
|
||||||
ifc_classes = AuthoringData.data["ifc_classes"] if "ifc_classes" in AuthoringData.data else False
|
#if ifc_classes and relating_types_ids and not cls.props.icon_id and not is_tool_header:
|
||||||
relating_types_ids = (
|
|
||||||
AuthoringData.data["relating_types_ids"] if "relating_types_ids" in AuthoringData.data else False
|
|
||||||
)
|
|
||||||
|
|
||||||
#if ifc_classes and relating_types_ids and not props.icon_id and not is_tool_header:
|
|
||||||
# # hack Dion won't like to show a preview also on the first time the sidebar is shown
|
# # hack Dion won't like to show a preview also on the first time the sidebar is shown
|
||||||
# bpy.app.timers.register(lambda: prop.update_ifc_class(props, "lost_context"))
|
# bpy.app.timers.register(lambda: prop.update_ifc_class(cls.props, "lost_context"))
|
||||||
# bpy.app.timers.register(lambda: prop.update_relating_type(props, "lost_context"))
|
# bpy.app.timers.register(lambda: prop.update_relating_type(cls.props, "lost_context"))
|
||||||
|
|
||||||
ifc_class = props.ifc_class
|
if context.region.type == "TOOL_HEADER":
|
||||||
relating_type_id = props.relating_type_id
|
cls.draw_header_interface()
|
||||||
|
elif context.region.type == "UI":
|
||||||
|
cls.draw_sidebar_interface()
|
||||||
|
|
||||||
if is_tool_header:
|
if context.active_object:
|
||||||
row = layout.row(align=True)
|
cls.draw_edit_object_interface(context)
|
||||||
if ifc_classes:
|
elif not context.selected_objects:
|
||||||
row.label(text="", icon="FILE_VOLUME")
|
cls.draw_create_object_interface()
|
||||||
row.prop(data=props, property="ifc_class", text="")
|
|
||||||
else:
|
|
||||||
row.label(text="No Construction Class", icon="FILE_VOLUME")
|
|
||||||
row = layout.row(align=True)
|
|
||||||
if relating_types_ids:
|
|
||||||
row.label(text="", icon="FILE_3D")
|
|
||||||
prop_with_search(row, props, "relating_type_id", text="")
|
|
||||||
row.operator("bim.launch_type_manager", icon="LIGHTPROBE_GRID", text="")
|
|
||||||
else:
|
|
||||||
row.label(text="No Construction Type", icon="FILE_3D")
|
|
||||||
if ifc_classes:
|
|
||||||
#row = layout.row()
|
|
||||||
#row.operator("bim.display_constr_types", icon="TRIA_DOWN", text="")
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
@classmethod
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
def draw_create_object_interface(cls):
|
||||||
row.label(text="", icon="EVENT_A")
|
if not AuthoringData.data["relating_types_ids"]:
|
||||||
op = row.operator("bim.add_constr_type_instance", text="Add")
|
return
|
||||||
op.from_invoke = True
|
if cls.props.ifc_class == "IfcWallType":
|
||||||
op.ifc_class = ifc_class
|
row = cls.layout.row(align=True)
|
||||||
if relating_type_id.isnumeric():
|
row.prop(data=cls.props, property="extrusion_depth", text="Height")
|
||||||
op.relating_type_id = int(relating_type_id)
|
|
||||||
elif is_sidebar:
|
|
||||||
row = layout.row(align=True)
|
|
||||||
if ifc_classes:
|
|
||||||
row.label(text="", icon="FILE_VOLUME")
|
|
||||||
prop_with_search(row, props, "ifc_class", text="")
|
|
||||||
else:
|
|
||||||
row.label(text="No Construction Class", icon="FILE_VOLUME")
|
|
||||||
row = layout.row(align=True)
|
|
||||||
if relating_types_ids:
|
|
||||||
row.label(text="", icon="FILE_3D")
|
|
||||||
prop_with_search(row, props, "relating_type_id", text="")
|
|
||||||
else:
|
|
||||||
row.label(text="No Construction Type", icon="FILE_3D")
|
|
||||||
|
|
||||||
box = layout.box()
|
row = cls.layout.row(align=True)
|
||||||
if AuthoringData.data["type_thumbnail"]:
|
row.prop(data=cls.props, property="length", text="Length")
|
||||||
box.template_icon(icon_value=AuthoringData.data["type_thumbnail"], scale=5)
|
elif cls.props.ifc_class in ("IfcColumnType", "IfcBeamType", "IfcMemberType"):
|
||||||
else:
|
row = cls.layout.row(align=True)
|
||||||
op = box.operator("bim.load_type_thumbnails", text="Load Thumbnails", icon="FILE_REFRESH")
|
row.prop(data=cls.props, property="cardinal_point", text="Axis")
|
||||||
op.ifc_class = props.ifc_class
|
|
||||||
|
|
||||||
if ifc_classes:
|
row = cls.layout.row(align=True)
|
||||||
row = layout.row(align=True)
|
label = "Height" if cls.props.ifc_class == "IfcColumn" else "Length"
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.prop(data=cls.props, property="extrusion_depth", text=label)
|
||||||
row.label(text="", icon="EVENT_A")
|
elif cls.props.ifc_class in ("IfcWindowType", "IfcWindowStyle", "IfcDoorType", "IfcDoorStyle"):
|
||||||
op = row.operator("bim.add_constr_type_instance", text="Add")
|
row = cls.layout.row(align=True)
|
||||||
op.from_invoke = True
|
row.prop(data=cls.props, property="rl", text="RL")
|
||||||
op.ifc_class = ifc_class
|
|
||||||
if relating_type_id.isnumeric():
|
|
||||||
op.relating_type_id = int(relating_type_id)
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def draw_edit_object_interface(cls, context):
|
||||||
if AuthoringData.data["active_class"] in ("IfcWall", "IfcWallStandardCase"):
|
if AuthoringData.data["active_class"] in ("IfcWall", "IfcWallStandardCase"):
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.prop(data=props, property="extrusion_depth", text="Height")
|
row.prop(data=cls.props, property="extrusion_depth", text="Height")
|
||||||
op = row.operator("bim.change_extrusion_depth", icon="FILE_REFRESH", text="")
|
op = row.operator("bim.change_extrusion_depth", icon="FILE_REFRESH", text="")
|
||||||
op.depth = props.extrusion_depth
|
op.depth = cls.props.extrusion_depth
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.prop(data=props, property="length", text="Length")
|
row.prop(data=cls.props, property="length", text="Length")
|
||||||
op = row.operator("bim.change_layer_length", icon="FILE_REFRESH", text="")
|
op = row.operator("bim.change_layer_length", icon="FILE_REFRESH", text="")
|
||||||
op.length = props.length
|
op.length = cls.props.length
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_E")
|
row.label(text="", icon="EVENT_E")
|
||||||
row.operator("bim.hotkey", text="Extend").hotkey = "S_E"
|
row.operator("bim.hotkey", text="Extend").hotkey = "S_E"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_T")
|
row.label(text="", icon="EVENT_T")
|
||||||
row.operator("bim.hotkey", text="Butt").hotkey = "S_T"
|
row.operator("bim.hotkey", text="Butt").hotkey = "S_T"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_Y")
|
row.label(text="", icon="EVENT_Y")
|
||||||
row.operator("bim.hotkey", text="Mitre").hotkey = "S_Y"
|
row.operator("bim.hotkey", text="Mitre").hotkey = "S_Y"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_M")
|
row.label(text="", icon="EVENT_M")
|
||||||
row.operator("bim.hotkey", text="Merge").hotkey = "S_M"
|
row.operator("bim.hotkey", text="Merge").hotkey = "S_M"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_F")
|
row.label(text="", icon="EVENT_F")
|
||||||
row.operator("bim.hotkey", text="Flip").hotkey = "S_F"
|
row.operator("bim.hotkey", text="Flip").hotkey = "S_F"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_S")
|
row.label(text="", icon="EVENT_S")
|
||||||
row.operator("bim.hotkey", text="Split").hotkey = "S_S"
|
row.operator("bim.hotkey", text="Split").hotkey = "S_S"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_G")
|
row.label(text="", icon="EVENT_G")
|
||||||
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
||||||
row.operator("bim.join_wall", icon="X", text="").join_type = ""
|
row.operator("bim.join_wall", icon="X", text="").join_type = ""
|
||||||
elif AuthoringData.data["active_class"] in ("IfcSlab", "IfcSlabStandardCase"):
|
elif AuthoringData.data["active_class"] in ("IfcSlab", "IfcSlabStandardCase"):
|
||||||
if not context.active_object:
|
if context.active_object.mode == "OBJECT":
|
||||||
pass
|
row = cls.layout.row(align=True)
|
||||||
elif context.active_object.mode == "OBJECT":
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_E")
|
row.label(text="", icon="EVENT_E")
|
||||||
row.operator("bim.hotkey", text="Edit Profile").hotkey = "S_E"
|
row.operator("bim.hotkey", text="Edit Profile").hotkey = "S_E"
|
||||||
@@ -195,34 +168,34 @@ class BimTool(WorkSpaceTool):
|
|||||||
"IfcMember",
|
"IfcMember",
|
||||||
"IfcMemberStandardCase",
|
"IfcMemberStandardCase",
|
||||||
):
|
):
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.prop(data=props, property="cardinal_point", text="Axis")
|
row.prop(data=cls.props, property="cardinal_point", text="Axis")
|
||||||
op = row.operator("bim.change_cardinal_point", icon="FILE_REFRESH", text="")
|
op = row.operator("bim.change_cardinal_point", icon="FILE_REFRESH", text="")
|
||||||
op.cardinal_point = int(props.cardinal_point)
|
op.cardinal_point = int(cls.props.cardinal_point)
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
label = "Height" if ifc_class == "IfcColumnType" else "Length"
|
label = "Height" if AuthoringData.data["active_class"] in ("IfcColumn", "IfcColumnStandardCase") else "Length"
|
||||||
row.prop(data=props, property="extrusion_depth", text=label)
|
row.prop(data=cls.props, property="extrusion_depth", text=label)
|
||||||
op = row.operator("bim.change_profile_depth", icon="FILE_REFRESH", text="")
|
op = row.operator("bim.change_profile_depth", icon="FILE_REFRESH", text="")
|
||||||
op.depth = props.extrusion_depth
|
op.depth = cls.props.extrusion_depth
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_E")
|
row.label(text="", icon="EVENT_E")
|
||||||
row.operator("bim.hotkey", text="Extend").hotkey = "S_E"
|
row.operator("bim.hotkey", text="Extend").hotkey = "S_E"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_T")
|
row.label(text="", icon="EVENT_T")
|
||||||
row.operator("bim.hotkey", text="Butt").hotkey = "S_T"
|
row.operator("bim.hotkey", text="Butt").hotkey = "S_T"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_Y")
|
row.label(text="", icon="EVENT_Y")
|
||||||
row.operator("bim.hotkey", text="Mitre").hotkey = "S_Y"
|
row.operator("bim.hotkey", text="Mitre").hotkey = "S_Y"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_R")
|
row.label(text="", icon="EVENT_R")
|
||||||
row.operator("bim.hotkey", text="Rotate 90").hotkey = "S_R"
|
row.operator("bim.hotkey", text="Rotate 90").hotkey = "S_R"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_G")
|
row.label(text="", icon="EVENT_G")
|
||||||
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
||||||
@@ -233,25 +206,24 @@ class BimTool(WorkSpaceTool):
|
|||||||
"IfcDoor",
|
"IfcDoor",
|
||||||
"IfcDoorStandardCase",
|
"IfcDoorStandardCase",
|
||||||
):
|
):
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.prop(data=props, property="rl", text="RL")
|
row.prop(data=cls.props, property="rl", text="RL")
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_G")
|
row.label(text="", icon="EVENT_G")
|
||||||
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
||||||
|
elif AuthoringData.data["active_class"] in (
|
||||||
if props.ifc_class in (
|
|
||||||
"IfcCableCarrierSegmentType",
|
"IfcCableCarrierSegmentType",
|
||||||
"IfcCableSegmentType",
|
"IfcCableSegmentType",
|
||||||
"IfcDuctSegmentType",
|
"IfcDuctSegmentType",
|
||||||
"IfcPipeSegmentType",
|
"IfcPipeSegmentType",
|
||||||
):
|
):
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="Extend", icon="EVENT_E")
|
row.label(text="Extend", icon="EVENT_E")
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_O")
|
row.label(text="", icon="EVENT_O")
|
||||||
if len(context.selected_objects) == 2:
|
if len(context.selected_objects) == 2:
|
||||||
@@ -265,30 +237,90 @@ class BimTool(WorkSpaceTool):
|
|||||||
else:
|
else:
|
||||||
row.operator("bim.show_openings", icon="HIDE_OFF", text="")
|
row.operator("bim.show_openings", icon="HIDE_OFF", text="")
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="Align")
|
row.label(text="Align")
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="Align Exterior", icon="EVENT_X")
|
row.label(text="Align Exterior", icon="EVENT_X")
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="Align Centerline", icon="EVENT_C")
|
row.label(text="Align Centerline", icon="EVENT_C")
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="Align Interior", icon="EVENT_V")
|
row.label(text="Align Interior", icon="EVENT_V")
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="Mode")
|
row.label(text="Mode")
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_ALT")
|
row.label(text="", icon="EVENT_ALT")
|
||||||
row.label(text="", icon="EVENT_O")
|
row.label(text="", icon="EVENT_O")
|
||||||
row.operator("bim.hotkey", text="Void").hotkey = "A_O"
|
row.operator("bim.hotkey", text="Void").hotkey = "A_O"
|
||||||
row = layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_ALT")
|
row.label(text="", icon="EVENT_ALT")
|
||||||
row.label(text="", icon="EVENT_D")
|
row.label(text="", icon="EVENT_D")
|
||||||
row.operator("bim.hotkey", text="Decomposition").hotkey = "A_D"
|
row.operator("bim.hotkey", text="Decomposition").hotkey = "A_D"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def draw_header_interface(cls):
|
||||||
|
row = cls.layout.row(align=True)
|
||||||
|
if AuthoringData.data["ifc_classes"]:
|
||||||
|
row.label(text="", icon="FILE_VOLUME")
|
||||||
|
row.prop(data=cls.props, property="ifc_class", text="")
|
||||||
|
else:
|
||||||
|
row.label(text="No Construction Class", icon="FILE_VOLUME")
|
||||||
|
row = cls.layout.row(align=True)
|
||||||
|
if AuthoringData.data["relating_types_ids"]:
|
||||||
|
row.label(text="", icon="FILE_3D")
|
||||||
|
prop_with_search(row, cls.props, "relating_type_id", text="")
|
||||||
|
row.operator("bim.launch_type_manager", icon="LIGHTPROBE_GRID", text="")
|
||||||
|
else:
|
||||||
|
row.label(text="No Construction Type", icon="FILE_3D")
|
||||||
|
if AuthoringData.data["ifc_classes"]:
|
||||||
|
#row = cls.layout.row()
|
||||||
|
#row.operator("bim.display_constr_types", icon="TRIA_DOWN", text="")
|
||||||
|
|
||||||
|
row = cls.layout.row(align=True)
|
||||||
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
|
row.label(text="", icon="EVENT_A")
|
||||||
|
op = row.operator("bim.add_constr_type_instance", text="Add")
|
||||||
|
op.from_invoke = True
|
||||||
|
op.ifc_class = cls.props.ifc_class
|
||||||
|
if cls.props.relating_type_id.isnumeric():
|
||||||
|
op.relating_type_id = int(cls.props.relating_type_id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def draw_sidebar_interface(cls):
|
||||||
|
row = cls.layout.row(align=True)
|
||||||
|
if AuthoringData.data["ifc_classes"]:
|
||||||
|
row.label(text="", icon="FILE_VOLUME")
|
||||||
|
prop_with_search(row, cls.props, "ifc_class", text="")
|
||||||
|
else:
|
||||||
|
row.label(text="No Construction Class", icon="FILE_VOLUME")
|
||||||
|
row = cls.layout.row(align=True)
|
||||||
|
if AuthoringData.data["relating_types_ids"]:
|
||||||
|
row.label(text="", icon="FILE_3D")
|
||||||
|
prop_with_search(row, cls.props, "relating_type_id", text="")
|
||||||
|
else:
|
||||||
|
row.label(text="No Construction Type", icon="FILE_3D")
|
||||||
|
|
||||||
|
box = cls.layout.box()
|
||||||
|
if AuthoringData.data["type_thumbnail"]:
|
||||||
|
box.template_icon(icon_value=AuthoringData.data["type_thumbnail"], scale=5)
|
||||||
|
else:
|
||||||
|
op = box.operator("bim.load_type_thumbnails", text="Load Thumbnails", icon="FILE_REFRESH")
|
||||||
|
op.ifc_class = cls.props.ifc_class
|
||||||
|
|
||||||
|
if AuthoringData.data["ifc_classes"]:
|
||||||
|
row = cls.layout.row(align=True)
|
||||||
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
|
row.label(text="", icon="EVENT_A")
|
||||||
|
op = row.operator("bim.add_constr_type_instance", text="Add")
|
||||||
|
op.from_invoke = True
|
||||||
|
op.ifc_class = cls.props.ifc_class
|
||||||
|
if cls.props.relating_type_id.isnumeric():
|
||||||
|
op.relating_type_id = int(cls.props.relating_type_id)
|
||||||
|
|
||||||
|
|
||||||
class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.hotkey"
|
bl_idname = "bim.hotkey"
|
||||||
|
|||||||
@@ -56,10 +56,6 @@ class CreateProject(bpy.types.Operator):
|
|||||||
props = context.scene.BIMProjectProperties
|
props = context.scene.BIMProjectProperties
|
||||||
template = None if props.template_file == "0" else props.template_file
|
template = None if props.template_file == "0" else props.template_file
|
||||||
core.create_project(tool.Ifc, tool.Project, schema=props.export_schema, template=template)
|
core.create_project(tool.Ifc, tool.Project, schema=props.export_schema, template=template)
|
||||||
# Load thumbnails for the first time
|
|
||||||
if tool.Ifc.get().by_type("IfcElementType"):
|
|
||||||
ifc_class = sorted(tool.Ifc.get().by_type("IfcElementType"), key=lambda e: e.is_a())[0].is_a()
|
|
||||||
bpy.ops.bim.load_type_thumbnails(ifc_class=ifc_class)
|
|
||||||
|
|
||||||
def rollback(self, data):
|
def rollback(self, data):
|
||||||
IfcStore.file = None
|
IfcStore.file = None
|
||||||
@@ -596,10 +592,9 @@ class LoadProjectElements(bpy.types.Operator):
|
|||||||
print("Import finished in {:.2f} seconds".format(time.time() - start))
|
print("Import finished in {:.2f} seconds".format(time.time() - start))
|
||||||
context.scene.BIMProjectProperties.is_loading = False
|
context.scene.BIMProjectProperties.is_loading = False
|
||||||
|
|
||||||
# Load thumbnails for the first time
|
tool.Project.load_default_thumbnails()
|
||||||
if tool.Ifc.get().by_type("IfcElementType"):
|
tool.Project.set_default_context()
|
||||||
ifc_class = sorted(tool.Ifc.get().by_type("IfcElementType"), key=lambda e: e.is_a())[0].is_a()
|
tool.Project.set_default_modeling_dimensions()
|
||||||
bpy.ops.bim.load_type_thumbnails(ifc_class=ifc_class)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def get_decomposition_elements(self):
|
def get_decomposition_elements(self):
|
||||||
|
|||||||
@@ -74,3 +74,7 @@ def create_project(ifc, project, schema=None, template=None):
|
|||||||
|
|
||||||
if template:
|
if template:
|
||||||
project.append_all_types_from_template(template)
|
project.append_all_types_from_template(template)
|
||||||
|
|
||||||
|
project.load_default_thumbnails()
|
||||||
|
project.set_default_context()
|
||||||
|
project.set_default_modeling_dimensions()
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ class Owner:
|
|||||||
class Project:
|
class Project:
|
||||||
def append_all_types_from_template(cls, template): pass
|
def append_all_types_from_template(cls, template): pass
|
||||||
def create_empty(cls, name): pass
|
def create_empty(cls, name): pass
|
||||||
|
def load_default_thumbnails(cls): pass
|
||||||
def run_aggregate_assign_object(cls, relating_obj=None, related_obj=None): pass
|
def run_aggregate_assign_object(cls, relating_obj=None, related_obj=None): pass
|
||||||
def run_context_add_context(cls, context_type=None, context_identifier=None, target_view=None, parent=None): pass
|
def run_context_add_context(cls, context_type=None, context_identifier=None, target_view=None, parent=None): pass
|
||||||
def run_owner_add_organisation(cls): pass
|
def run_owner_add_organisation(cls): pass
|
||||||
@@ -389,6 +390,8 @@ class Project:
|
|||||||
def run_unit_assign_scene_units(cls): pass
|
def run_unit_assign_scene_units(cls): pass
|
||||||
def set_active_spatial_element(cls, obj): pass
|
def set_active_spatial_element(cls, obj): pass
|
||||||
def set_context(cls, context): pass
|
def set_context(cls, context): pass
|
||||||
|
def set_default_context(cls): pass
|
||||||
|
def set_default_modeling_dimensions(cls): pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import bpy
|
import bpy
|
||||||
|
import ifcopenshell
|
||||||
|
import ifcopenshell.util.unit
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
@@ -36,6 +38,12 @@ class Project(blenderbim.core.tool.Project):
|
|||||||
def create_empty(cls, name):
|
def create_empty(cls, name):
|
||||||
return bpy.data.objects.new(name, None)
|
return bpy.data.objects.new(name, None)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_default_thumbnails(cls):
|
||||||
|
if tool.Ifc.get().by_type("IfcElementType"):
|
||||||
|
ifc_class = sorted(tool.Ifc.get().by_type("IfcElementType"), key=lambda e: e.is_a())[0].is_a()
|
||||||
|
bpy.ops.bim.load_type_thumbnails(ifc_class=ifc_class)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run_aggregate_assign_object(cls, relating_obj=None, related_obj=None):
|
def run_aggregate_assign_object(cls, relating_obj=None, related_obj=None):
|
||||||
return blenderbim.core.aggregate.assign_object(
|
return blenderbim.core.aggregate.assign_object(
|
||||||
@@ -114,3 +122,20 @@ class Project(blenderbim.core.tool.Project):
|
|||||||
def set_context(cls, context):
|
def set_context(cls, context):
|
||||||
blenderbim.bim.handler.refresh_ui_data()
|
blenderbim.bim.handler.refresh_ui_data()
|
||||||
bpy.context.scene.BIMRootProperties.contexts = str(context.id())
|
bpy.context.scene.BIMRootProperties.contexts = str(context.id())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_default_context(cls):
|
||||||
|
context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
||||||
|
if context:
|
||||||
|
bpy.context.scene.BIMRootProperties.contexts = str(context.id())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_default_modeling_dimensions(cls):
|
||||||
|
props = bpy.context.scene.BIMModelProperties
|
||||||
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
|
props.extrusion_depth = 3 / unit_scale
|
||||||
|
props.length = 1 / unit_scale
|
||||||
|
props.rl = 1 / unit_scale
|
||||||
|
props.x = 0.5 / unit_scale
|
||||||
|
props.y = 0.5 / unit_scale
|
||||||
|
props.z = 0.5 / unit_scale
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ class TestCreateProject:
|
|||||||
project.set_context("body").should_be_called()
|
project.set_context("body").should_be_called()
|
||||||
project.set_active_spatial_element("storey").should_be_called()
|
project.set_active_spatial_element("storey").should_be_called()
|
||||||
|
|
||||||
|
project.load_default_thumbnails().should_be_called()
|
||||||
|
project.set_default_context().should_be_called()
|
||||||
|
project.set_default_modeling_dimensions().should_be_called()
|
||||||
|
|
||||||
subject.create_project(ifc, project, schema="IFC4", template=None)
|
subject.create_project(ifc, project, schema="IFC4", template=None)
|
||||||
|
|
||||||
def test_appending_project_template_types_if_specified(self, ifc, project):
|
def test_appending_project_template_types_if_specified(self, ifc, project):
|
||||||
@@ -132,6 +136,10 @@ class TestCreateProject:
|
|||||||
|
|
||||||
project.append_all_types_from_template("template").should_be_called()
|
project.append_all_types_from_template("template").should_be_called()
|
||||||
|
|
||||||
|
project.load_default_thumbnails().should_be_called()
|
||||||
|
project.set_default_context().should_be_called()
|
||||||
|
project.set_default_modeling_dimensions().should_be_called()
|
||||||
|
|
||||||
subject.create_project(ifc, project, schema="IFC4", template="template")
|
subject.create_project(ifc, project, schema="IFC4", template="template")
|
||||||
|
|
||||||
def test_create_an_ifc2x3_project_with_owner_defaults(self, ifc, project):
|
def test_create_an_ifc2x3_project_with_owner_defaults(self, ifc, project):
|
||||||
@@ -192,4 +200,8 @@ class TestCreateProject:
|
|||||||
project.set_context("body").should_be_called()
|
project.set_context("body").should_be_called()
|
||||||
project.set_active_spatial_element("storey").should_be_called()
|
project.set_active_spatial_element("storey").should_be_called()
|
||||||
|
|
||||||
|
project.load_default_thumbnails().should_be_called()
|
||||||
|
project.set_default_context().should_be_called()
|
||||||
|
project.set_default_modeling_dimensions().should_be_called()
|
||||||
|
|
||||||
subject.create_project(ifc, project, schema="IFC2X3", template=None)
|
subject.create_project(ifc, project, schema="IFC2X3", template=None)
|
||||||
|
|||||||
@@ -42,6 +42,11 @@ class TestCreateEmpty(NewFile):
|
|||||||
assert not bpy.data.objects.get("Foobar").data
|
assert not bpy.data.objects.get("Foobar").data
|
||||||
|
|
||||||
|
|
||||||
|
class TestLoadDefaultThumbnails(NewFile):
|
||||||
|
def test_nothing(self):
|
||||||
|
pass # Not possible to test this headlessly
|
||||||
|
|
||||||
|
|
||||||
class TestRunAggregateAssignObject(NewFile):
|
class TestRunAggregateAssignObject(NewFile):
|
||||||
def test_nothing(self):
|
def test_nothing(self):
|
||||||
pass
|
pass
|
||||||
@@ -101,3 +106,30 @@ class TestSetContext(NewFile):
|
|||||||
context = ifc.createIfcGeometricRepresentationContext()
|
context = ifc.createIfcGeometricRepresentationContext()
|
||||||
subject.set_context(context)
|
subject.set_context(context)
|
||||||
assert bpy.context.scene.BIMRootProperties.contexts == str(context.id())
|
assert bpy.context.scene.BIMRootProperties.contexts == str(context.id())
|
||||||
|
|
||||||
|
|
||||||
|
class TestSetDefaultContext(NewFile):
|
||||||
|
def test_run(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
ifc.createIfcProject()
|
||||||
|
model = ifcopenshell.api.run("context.add_context", ifc, context_type="Model")
|
||||||
|
body = ifcopenshell.api.run("context.add_context", ifc, parent=model, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW")
|
||||||
|
subject.set_default_context()
|
||||||
|
assert bpy.context.scene.BIMRootProperties.contexts == str(body.id())
|
||||||
|
|
||||||
|
|
||||||
|
class TestSetDefaultModelingDimensions(NewFile):
|
||||||
|
def test_run(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
ifc.createIfcProject()
|
||||||
|
ifcopenshell.api.run("unit.assign_unit", ifc)
|
||||||
|
subject.set_default_modeling_dimensions()
|
||||||
|
props = bpy.context.scene.BIMModelProperties
|
||||||
|
assert props.extrusion_depth == 3000
|
||||||
|
assert props.length == 1000
|
||||||
|
assert props.rl == 1000
|
||||||
|
assert props.x == 500
|
||||||
|
assert props.y == 500
|
||||||
|
assert props.z == 500
|
||||||
|
|||||||
@@ -477,6 +477,8 @@ def calculate_unit_scale(file):
|
|||||||
:returns: The scale factor
|
:returns: The scale factor
|
||||||
:rtype: float
|
:rtype: float
|
||||||
"""
|
"""
|
||||||
|
if not file.by_type("IfcUnitAssignment"):
|
||||||
|
return 1
|
||||||
units = file.by_type("IfcUnitAssignment")[0]
|
units = file.by_type("IfcUnitAssignment")[0]
|
||||||
unit_scale = 1
|
unit_scale = 1
|
||||||
for unit in units.Units:
|
for unit in units.Units:
|
||||||
|
|||||||
Reference in New Issue
Block a user