mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +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
|
||||
# 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.
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 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.
|
||||
#
|
||||
@@ -39,6 +39,7 @@ class BimTool(WorkSpaceTool):
|
||||
bl_keymap = (
|
||||
# ("bim.wall_tool_op", {"type": 'MOUSEMOVE', "value": 'ANY'}, {"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": "C", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_C")]}),
|
||||
("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")]}),
|
||||
)
|
||||
|
||||
def draw_settings(context, layout, something):
|
||||
props = context.scene.BIMModelProperties
|
||||
is_tool_header = context.region.type == "TOOL_HEADER"
|
||||
is_sidebar = context.region.type == "UI"
|
||||
def draw_settings(context, layout, ws_tool):
|
||||
# Unlike operators, Blender doesn't treat workspace tools as a class, so we'll create our own.
|
||||
BimToolUI.draw(context, layout)
|
||||
|
||||
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():
|
||||
row.label(text="No IFC Project", icon="ERROR")
|
||||
return
|
||||
@@ -69,121 +76,87 @@ class BimTool(WorkSpaceTool):
|
||||
if not AuthoringData.is_loaded:
|
||||
AuthoringData.load()
|
||||
|
||||
ifc_classes = AuthoringData.data["ifc_classes"] if "ifc_classes" in AuthoringData.data else False
|
||||
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:
|
||||
#if ifc_classes and relating_types_ids and not cls.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
|
||||
# bpy.app.timers.register(lambda: prop.update_ifc_class(props, "lost_context"))
|
||||
# bpy.app.timers.register(lambda: prop.update_relating_type(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(cls.props, "lost_context"))
|
||||
|
||||
ifc_class = props.ifc_class
|
||||
relating_type_id = props.relating_type_id
|
||||
if context.region.type == "TOOL_HEADER":
|
||||
cls.draw_header_interface()
|
||||
elif context.region.type == "UI":
|
||||
cls.draw_sidebar_interface()
|
||||
|
||||
if is_tool_header:
|
||||
row = layout.row(align=True)
|
||||
if ifc_classes:
|
||||
row.label(text="", icon="FILE_VOLUME")
|
||||
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="")
|
||||
if context.active_object:
|
||||
cls.draw_edit_object_interface(context)
|
||||
elif not context.selected_objects:
|
||||
cls.draw_create_object_interface()
|
||||
|
||||
row = 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 = ifc_class
|
||||
if relating_type_id.isnumeric():
|
||||
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")
|
||||
@classmethod
|
||||
def draw_create_object_interface(cls):
|
||||
if not AuthoringData.data["relating_types_ids"]:
|
||||
return
|
||||
if cls.props.ifc_class == "IfcWallType":
|
||||
row = cls.layout.row(align=True)
|
||||
row.prop(data=cls.props, property="extrusion_depth", text="Height")
|
||||
|
||||
box = 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 = props.ifc_class
|
||||
row = cls.layout.row(align=True)
|
||||
row.prop(data=cls.props, property="length", text="Length")
|
||||
elif cls.props.ifc_class in ("IfcColumnType", "IfcBeamType", "IfcMemberType"):
|
||||
row = cls.layout.row(align=True)
|
||||
row.prop(data=cls.props, property="cardinal_point", text="Axis")
|
||||
|
||||
if ifc_classes:
|
||||
row = 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 = ifc_class
|
||||
if relating_type_id.isnumeric():
|
||||
op.relating_type_id = int(relating_type_id)
|
||||
row = cls.layout.row(align=True)
|
||||
label = "Height" if cls.props.ifc_class == "IfcColumn" else "Length"
|
||||
row.prop(data=cls.props, property="extrusion_depth", text=label)
|
||||
elif cls.props.ifc_class in ("IfcWindowType", "IfcWindowStyle", "IfcDoorType", "IfcDoorStyle"):
|
||||
row = cls.layout.row(align=True)
|
||||
row.prop(data=cls.props, property="rl", text="RL")
|
||||
|
||||
@classmethod
|
||||
def draw_edit_object_interface(cls, context):
|
||||
if AuthoringData.data["active_class"] in ("IfcWall", "IfcWallStandardCase"):
|
||||
row = layout.row(align=True)
|
||||
row.prop(data=props, property="extrusion_depth", text="Height")
|
||||
row = cls.layout.row(align=True)
|
||||
row.prop(data=cls.props, property="extrusion_depth", text="Height")
|
||||
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.prop(data=props, property="length", text="Length")
|
||||
row = cls.layout.row(align=True)
|
||||
row.prop(data=cls.props, property="length", text="Length")
|
||||
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_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_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_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_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_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_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_G")
|
||||
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
||||
row.operator("bim.join_wall", icon="X", text="").join_type = ""
|
||||
elif AuthoringData.data["active_class"] in ("IfcSlab", "IfcSlabStandardCase"):
|
||||
if not context.active_object:
|
||||
pass
|
||||
elif context.active_object.mode == "OBJECT":
|
||||
row = layout.row(align=True)
|
||||
if context.active_object.mode == "OBJECT":
|
||||
row = cls.layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
row.label(text="", icon="EVENT_E")
|
||||
row.operator("bim.hotkey", text="Edit Profile").hotkey = "S_E"
|
||||
@@ -195,34 +168,34 @@ class BimTool(WorkSpaceTool):
|
||||
"IfcMember",
|
||||
"IfcMemberStandardCase",
|
||||
):
|
||||
row = layout.row(align=True)
|
||||
row.prop(data=props, property="cardinal_point", text="Axis")
|
||||
row = cls.layout.row(align=True)
|
||||
row.prop(data=cls.props, property="cardinal_point", text="Axis")
|
||||
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)
|
||||
label = "Height" if ifc_class == "IfcColumnType" else "Length"
|
||||
row.prop(data=props, property="extrusion_depth", text=label)
|
||||
row = cls.layout.row(align=True)
|
||||
label = "Height" if AuthoringData.data["active_class"] in ("IfcColumn", "IfcColumnStandardCase") else "Length"
|
||||
row.prop(data=cls.props, property="extrusion_depth", text=label)
|
||||
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_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_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_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_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_G")
|
||||
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
||||
@@ -233,25 +206,24 @@ class BimTool(WorkSpaceTool):
|
||||
"IfcDoor",
|
||||
"IfcDoorStandardCase",
|
||||
):
|
||||
row = layout.row(align=True)
|
||||
row.prop(data=props, property="rl", text="RL")
|
||||
row = cls.layout.row(align=True)
|
||||
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_G")
|
||||
row.operator("bim.hotkey", text="Regen").hotkey = "S_G"
|
||||
|
||||
if props.ifc_class in (
|
||||
elif AuthoringData.data["active_class"] in (
|
||||
"IfcCableCarrierSegmentType",
|
||||
"IfcCableSegmentType",
|
||||
"IfcDuctSegmentType",
|
||||
"IfcPipeSegmentType",
|
||||
):
|
||||
row = layout.row(align=True)
|
||||
row = cls.layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
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_O")
|
||||
if len(context.selected_objects) == 2:
|
||||
@@ -265,30 +237,90 @@ class BimTool(WorkSpaceTool):
|
||||
else:
|
||||
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 = layout.row(align=True)
|
||||
row = cls.layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_SHIFT")
|
||||
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="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="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 = layout.row(align=True)
|
||||
row = cls.layout.row(align=True)
|
||||
row.label(text="", icon="EVENT_ALT")
|
||||
row.label(text="", icon="EVENT_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_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):
|
||||
bl_idname = "bim.hotkey"
|
||||
|
||||
@@ -56,10 +56,6 @@ class CreateProject(bpy.types.Operator):
|
||||
props = context.scene.BIMProjectProperties
|
||||
template = None if props.template_file == "0" else props.template_file
|
||||
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):
|
||||
IfcStore.file = None
|
||||
@@ -596,10 +592,9 @@ class LoadProjectElements(bpy.types.Operator):
|
||||
print("Import finished in {:.2f} seconds".format(time.time() - start))
|
||||
context.scene.BIMProjectProperties.is_loading = False
|
||||
|
||||
# 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)
|
||||
tool.Project.load_default_thumbnails()
|
||||
tool.Project.set_default_context()
|
||||
tool.Project.set_default_modeling_dimensions()
|
||||
return {"FINISHED"}
|
||||
|
||||
def get_decomposition_elements(self):
|
||||
|
||||
@@ -74,3 +74,7 @@ def create_project(ifc, project, schema=None, template=None):
|
||||
|
||||
if 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:
|
||||
def append_all_types_from_template(cls, template): 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_context_add_context(cls, context_type=None, context_identifier=None, target_view=None, parent=None): pass
|
||||
def run_owner_add_organisation(cls): pass
|
||||
@@ -389,6 +390,8 @@ class Project:
|
||||
def run_unit_assign_scene_units(cls): pass
|
||||
def set_active_spatial_element(cls, obj): pass
|
||||
def set_context(cls, context): pass
|
||||
def set_default_context(cls): pass
|
||||
def set_default_modeling_dimensions(cls): pass
|
||||
|
||||
|
||||
@interface
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.unit
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
@@ -36,6 +38,12 @@ class Project(blenderbim.core.tool.Project):
|
||||
def create_empty(cls, name):
|
||||
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
|
||||
def run_aggregate_assign_object(cls, relating_obj=None, related_obj=None):
|
||||
return blenderbim.core.aggregate.assign_object(
|
||||
@@ -114,3 +122,20 @@ class Project(blenderbim.core.tool.Project):
|
||||
def set_context(cls, context):
|
||||
blenderbim.bim.handler.refresh_ui_data()
|
||||
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_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)
|
||||
|
||||
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.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")
|
||||
|
||||
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_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)
|
||||
|
||||
@@ -42,6 +42,11 @@ class TestCreateEmpty(NewFile):
|
||||
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):
|
||||
def test_nothing(self):
|
||||
pass
|
||||
@@ -101,3 +106,30 @@ class TestSetContext(NewFile):
|
||||
context = ifc.createIfcGeometricRepresentationContext()
|
||||
subject.set_context(context)
|
||||
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
|
||||
:rtype: float
|
||||
"""
|
||||
if not file.by_type("IfcUnitAssignment"):
|
||||
return 1
|
||||
units = file.by_type("IfcUnitAssignment")[0]
|
||||
unit_scale = 1
|
||||
for unit in units.Units:
|
||||
|
||||
Reference in New Issue
Block a user