New wall tool, slab tool, etc in toolshelf to improve usability.

This commit is contained in:
Dion Moult
2023-07-21 17:27:52 +10:00
parent 4b03cace3e
commit 4ca203cb1e
24 changed files with 206 additions and 32 deletions
@@ -114,7 +114,7 @@ classes = (
def register():
if not bpy.app.background:
bpy.utils.register_tool(workspace.AnnotationTool, after={"bim.bim_tool"}, separator=False, group=True)
bpy.utils.register_tool(workspace.AnnotationTool, after={"bim.bim_tool"}, separator=True, group=False)
bpy.types.Scene.DocProperties = bpy.props.PointerProperty(type=prop.DocProperties)
bpy.types.Scene.BIMAnnotationProperties = bpy.props.PointerProperty(type=prop.BIMAnnotationProperties)
bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties)
@@ -52,6 +52,7 @@ classes = (
array.Input3DCursorYArray,
array.Input3DCursorZArray,
product.AddConstrTypeInstance,
product.AddDefaultType,
product.AddEmptyType,
product.AlignProduct,
product.ChangeTypePage,
@@ -177,7 +178,15 @@ addon_keymaps = []
def register():
if not bpy.app.background:
bpy.utils.register_tool(workspace.BimTool, after={"builtin.scale_cage"}, separator=True, group=True)
bpy.utils.register_tool(workspace.WallTool, after={"builtin.transform"}, separator=True, group=False)
bpy.utils.register_tool(workspace.SlabTool, after={"bim.wall_tool"}, separator=False, group=False)
bpy.utils.register_tool(workspace.DoorTool, after={"bim.slab_tool"}, separator=False, group=False)
bpy.utils.register_tool(workspace.WindowTool, after={"bim.door_tool"}, separator=False, group=False)
bpy.utils.register_tool(workspace.ColumnTool, after={"bim.window_tool"}, separator=False, group=False)
bpy.utils.register_tool(workspace.BeamTool, after={"bim.column_tool"}, separator=False, group=False)
bpy.utils.register_tool(workspace.DuctTool, after={"bim.beam_tool"}, separator=False, group=False)
bpy.utils.register_tool(workspace.PipeTool, after={"bim.duct_tool"}, separator=False, group=False)
bpy.utils.register_tool(workspace.BimTool, after={"bim.pipe_tool"}, separator=False, group=False)
bpy.types.Scene.BIMModelProperties = bpy.props.PointerProperty(type=prop.BIMModelProperties)
bpy.types.Object.BIMArrayProperties = bpy.props.PointerProperty(type=prop.BIMArrayProperties)
bpy.types.Object.BIMStairProperties = bpy.props.PointerProperty(type=prop.BIMStairProperties)
@@ -204,6 +213,14 @@ def register():
def unregister():
if not bpy.app.background:
bpy.utils.unregister_tool(workspace.WallTool)
bpy.utils.unregister_tool(workspace.SlabTool)
bpy.utils.unregister_tool(workspace.DoorTool)
bpy.utils.unregister_tool(workspace.WindowTool)
bpy.utils.unregister_tool(workspace.ColumnTool)
bpy.utils.unregister_tool(workspace.BeamTool)
bpy.utils.unregister_tool(workspace.DuctTool)
bpy.utils.unregister_tool(workspace.PipeTool)
bpy.utils.unregister_tool(workspace.BimTool)
del bpy.types.Scene.BIMModelProperties
del bpy.types.Object.BIMArrayProperties
@@ -44,9 +44,11 @@ class AuthoringData:
is_loaded = False
@classmethod
def load(cls):
def load(cls, ifc_element_type=False):
cls.is_loaded = True
cls.props = bpy.context.scene.BIMModelProperties
if ifc_element_type is not False:
cls.data["ifc_element_type"] = ifc_element_type
cls.data["ifc_classes"] = cls.ifc_classes()
cls.data["relating_type_id"] = cls.relating_type_id() # only after .ifc_classes()
cls.data["type_class"] = cls.type_class()
@@ -212,6 +214,10 @@ class AuthoringData:
@classmethod
def ifc_classes(cls):
if cls.data["ifc_element_type"]:
if tool.Ifc.get().by_type(cls.data["ifc_element_type"]):
return [(cls.data["ifc_element_type"], cls.data["ifc_element_type"], "")]
return []
results = []
classes = {
e.is_a() for e in (tool.Ifc.get().by_type("IfcElementType") + tool.Ifc.get().by_type("IfcSpaceType"))
@@ -35,8 +35,7 @@ import json
import collections
def update_door_modifier_representation(context):
obj = context.active_object
def update_door_modifier_representation(context, obj):
props = obj.BIMDoorProperties
element = tool.Ifc.get_entity(obj)
ifc_file = tool.Ifc.get()
@@ -290,9 +289,7 @@ def update_door_modifier_bmesh(context):
lining_depth = props.lining_depth
lining_thickness_default = props.lining_thickness
lining_offset = props.lining_offset
lining_to_panel_offset_x = (
props.lining_to_panel_offset_x if not sliding_door else lining_thickness_default
)
lining_to_panel_offset_x = props.lining_to_panel_offset_x if not sliding_door else lining_thickness_default
panel_depth = props.panel_depth
lining_to_panel_offset_y = props.lining_to_panel_offset_y if not sliding_door else -panel_depth
@@ -486,7 +483,7 @@ class BIM_OT_add_door(bpy.types.Operator, tool.Ifc.Operator):
obj.location = spawn_location
collection = context.view_layer.active_layer_collection.collection
collection.objects.link(obj)
element = blenderbim.core.root.assign_class(
tool.Ifc, tool.Collector, tool.Root, obj=obj, ifc_class="IfcDoor", should_add_representation=False
)
@@ -507,9 +504,10 @@ class AddDoor(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_door"
bl_label = "Add Door"
bl_options = {"REGISTER"}
obj: bpy.props.StringProperty()
def _execute(self, context):
obj = context.active_object
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
element = tool.Ifc.get_entity(obj)
props = obj.BIMDoorProperties
@@ -530,7 +528,7 @@ class AddDoor(bpy.types.Operator, tool.Ifc.Operator):
pset=pset,
properties={"Data": json.dumps(door_data, default=list)},
)
update_door_modifier_representation(context)
update_door_modifier_representation(context, obj)
return {"FINISHED"}
@@ -584,7 +582,7 @@ class FinishEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
props.is_editing = False
update_door_modifier_representation(context)
update_door_modifier_representation(context, obj)
pset = tool.Pset.get_element_pset(element, "BBIM_Door")
door_data = json.dumps(door_data, default=list)
@@ -72,6 +72,40 @@ def add_empty_type_button(self, context):
self.layout.operator(AddEmptyType.bl_idname, icon="FILE_3D")
class AddDefaultType(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_default_type"
bl_label = "Add Default Type"
bl_options = {"REGISTER", "UNDO"}
ifc_element_type: bpy.props.StringProperty()
def _execute(self, context):
props = context.scene.BIMModelProperties
props.type_class = self.ifc_element_type
if self.ifc_element_type == "IfcWallType":
props.type_predefined_type = "SOLIDWALL"
props.type_template = "LAYERSET_AXIS2"
elif self.ifc_element_type == "IfcSlabType":
props.type_predefined_type = "FLOOR"
props.type_template = "LAYERSET_AXIS3"
elif self.ifc_element_type == "IfcDoorType":
props.type_predefined_type = "DOOR"
props.type_template = "DOOR"
elif self.ifc_element_type == "IfcWindowType":
props.type_predefined_type = "WINDOW"
props.type_template = "WINDOW"
elif self.ifc_element_type == "IfcColumnType":
props.type_predefined_type = "COLUMN"
props.type_template = "PROFILESET"
elif self.ifc_element_type == "IfcBeamType":
props.type_predefined_type = "BEAM"
props.type_template = "PROFILESET"
elif self.ifc_element_type == "IfcDuctSegmentType":
return
elif self.ifc_element_type == "IfcPipeSegmentType":
return
bpy.ops.bim.add_type()
class AddConstrTypeInstance(bpy.types.Operator):
bl_idname = "bim.add_constr_type_instance"
bl_label = "Add"
@@ -439,7 +439,7 @@ class BIM_PT_window(bpy.types.Panel):
else:
row = self.layout.row()
row.label(text="No Window Found")
row.operator("bim.add_window", icon="ADD", text="")
row.operator("bim.add_window", icon="ADD", text="").obj = ""
class BIM_PT_door(bpy.types.Panel):
@@ -512,7 +512,7 @@ class BIM_PT_door(bpy.types.Panel):
else:
row = self.layout.row()
row.label(text="No Door Found")
row.operator("bim.add_door", icon="ADD", text="")
row.operator("bim.add_door", icon="ADD", text="").obj = ""
class BIM_PT_railing(bpy.types.Panel):
@@ -96,8 +96,7 @@ def update_simple_openings(element, opening_width, opening_height):
)
def update_window_modifier_representation(context):
obj = context.active_object
def update_window_modifier_representation(context, obj):
element = tool.Ifc.get_entity(obj)
props = obj.BIMWindowProperties
ifc_file = tool.Ifc.get()
@@ -455,7 +454,7 @@ class BIM_OT_add_window(bpy.types.Operator, tool.Ifc.Operator):
obj.location = spawn_location
collection = context.view_layer.active_layer_collection.collection
collection.objects.link(obj)
element = blenderbim.core.root.assign_class(
tool.Ifc, tool.Collector, tool.Root, obj=obj, ifc_class="IfcWindow", should_add_representation=False
)
@@ -476,9 +475,10 @@ class AddWindow(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_window"
bl_label = "Add Window"
bl_options = {"REGISTER"}
obj: bpy.props.StringProperty()
def _execute(self, context):
obj = context.active_object
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
element = tool.Ifc.get_entity(obj)
props = obj.BIMWindowProperties
@@ -498,7 +498,7 @@ class AddWindow(bpy.types.Operator, tool.Ifc.Operator):
pset=pset,
properties={"Data": json.dumps(window_data, default=list)},
)
update_window_modifier_representation(context)
update_window_modifier_representation(context, obj)
return {"FINISHED"}
@@ -550,7 +550,7 @@ class FinishEditingWindow(bpy.types.Operator, tool.Ifc.Operator):
props.is_editing = False
update_window_modifier_representation(context)
update_window_modifier_representation(context, obj)
pset = tool.Pset.get_element_pset(element, "BBIM_Window")
window_data = json.dumps(window_data, default=list)
@@ -34,7 +34,7 @@ class BimTool(WorkSpaceTool):
bl_context_mode = "OBJECT"
bl_idname = "bim.bim_tool"
bl_label = "BIM Tool"
bl_label = "Create Element"
bl_description = "Gives you BIM authoring related superpowers"
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.bim")
bl_widget = None
@@ -69,6 +69,110 @@ class BimTool(WorkSpaceTool):
BimToolUI.draw(context, layout)
class WallTool(BimTool):
bl_space_type = "VIEW_3D"
bl_context_mode = "OBJECT"
bl_idname = "bim.wall_tool"
bl_label = "Create Wall"
bl_description = "Create and edit walls"
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.wall")
bl_widget = None
def draw_settings(context, layout, ws_tool):
BimToolUI.draw(context, layout, ifc_element_type="IfcWallType")
class SlabTool(BimTool):
bl_space_type = "VIEW_3D"
bl_context_mode = "OBJECT"
bl_idname = "bim.slab_tool"
bl_label = "Create Slab"
bl_description = "Create and edit slabs"
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.slab")
bl_widget = None
def draw_settings(context, layout, ws_tool):
BimToolUI.draw(context, layout, ifc_element_type="IfcSlabType")
class DoorTool(BimTool):
bl_space_type = "VIEW_3D"
bl_context_mode = "OBJECT"
bl_idname = "bim.door_tool"
bl_label = "Create Door"
bl_description = "Create and edit doors"
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.door")
bl_widget = None
def draw_settings(context, layout, ws_tool):
BimToolUI.draw(context, layout, ifc_element_type="IfcDoorType")
class WindowTool(BimTool):
bl_space_type = "VIEW_3D"
bl_context_mode = "OBJECT"
bl_idname = "bim.window_tool"
bl_label = "Create Window"
bl_description = "Create and edit windows"
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.window")
bl_widget = None
def draw_settings(context, layout, ws_tool):
BimToolUI.draw(context, layout, ifc_element_type="IfcWindowType")
class ColumnTool(BimTool):
bl_space_type = "VIEW_3D"
bl_context_mode = "OBJECT"
bl_idname = "bim.column_tool"
bl_label = "Create Column"
bl_description = "Create and edit columns"
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.column")
bl_widget = None
def draw_settings(context, layout, ws_tool):
BimToolUI.draw(context, layout, ifc_element_type="IfcColumnType")
class BeamTool(BimTool):
bl_space_type = "VIEW_3D"
bl_context_mode = "OBJECT"
bl_idname = "bim.beam_tool"
bl_label = "Create Beam"
bl_description = "Create and edit beams"
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.beam")
bl_widget = None
def draw_settings(context, layout, ws_tool):
BimToolUI.draw(context, layout, ifc_element_type="IfcBeamType")
class DuctTool(BimTool):
bl_space_type = "VIEW_3D"
bl_context_mode = "OBJECT"
bl_idname = "bim.duct_tool"
bl_label = "Create Duct"
bl_description = "Create and edit ducks" # No, not a typo.
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.duct")
bl_widget = None
def draw_settings(context, layout, ws_tool):
BimToolUI.draw(context, layout, ifc_element_type="IfcDuctSegmentType")
class PipeTool(BimTool):
bl_space_type = "VIEW_3D"
bl_context_mode = "OBJECT"
bl_idname = "bim.pipe_tool"
bl_label = "Create Pipe"
bl_description = "Create and edit pipes"
bl_icon = os.path.join(os.path.dirname(__file__), "ops.authoring.pipe")
bl_widget = None
def draw_settings(context, layout, ws_tool):
BimToolUI.draw(context, layout, ifc_element_type="IfcPipeSegmentType")
def add_layout_hotkey_operator(layout, text, hotkey, description):
modifiers = {
"A": "EVENT_ALT",
@@ -88,7 +192,7 @@ def add_layout_hotkey_operator(layout, text, hotkey, description):
class BimToolUI:
@classmethod
def draw(cls, context, layout):
def draw(cls, context, layout, ifc_element_type=None):
cls.layout = layout
cls.props = context.scene.BIMModelProperties
@@ -98,7 +202,9 @@ class BimToolUI:
return
if not AuthoringData.is_loaded:
AuthoringData.load()
AuthoringData.load(ifc_element_type)
elif AuthoringData.data["ifc_element_type"] != ifc_element_type:
AuthoringData.load(ifc_element_type)
if context.region.type == "TOOL_HEADER":
cls.draw_header_interface()
@@ -303,8 +409,9 @@ class BimToolUI:
# shared by both sidebar and header
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="")
if not AuthoringData.data["ifc_element_type"]:
row.label(text="", icon="FILE_VOLUME")
prop_with_search(row, cls.props, "ifc_class", text="")
row = cls.layout.row(align=True)
if AuthoringData.data["relating_type_id"]:
@@ -312,9 +419,20 @@ class BimToolUI:
prop_with_search(row, cls.props, "relating_type_id", text="")
else:
row.label(text="No Construction Type", icon="FILE_3D")
row.operator("bim.launch_type_manager", icon="LIGHTPROBE_GRID", text="")
else:
row.label(text="No Construction Class", icon="FILE_VOLUME")
row.operator("bim.launch_type_manager", icon="LIGHTPROBE_GRID", text="")
if AuthoringData.data["ifc_element_type"]:
row.label(text=f"No {AuthoringData.data['ifc_element_type']} Found", icon="ERROR")
row = cls.layout.row()
row.prop(cls.props, "type_name")
row = cls.layout.row()
op = row.operator(
"bim.add_default_type", icon="ADD", text=f"Add {AuthoringData.data['ifc_element_type']}"
)
op.ifc_element_type = AuthoringData.data["ifc_element_type"]
else:
row.label(text="No Element Types Found", icon="ERROR")
row.operator("bim.launch_type_manager", icon="LIGHTPROBE_GRID", text="Launch Type Manager")
@classmethod
def draw_basic_bim_tool_interface(cls):
@@ -53,7 +53,7 @@ classes = (
def register():
if not bpy.app.background:
bpy.utils.register_tool(workspace.SpatialTool, after={"bim.annotation_tool"}, separator=False, group=True)
bpy.utils.register_tool(workspace.SpatialTool, after={"bim.annotation_tool"}, separator=False, group=False)
bpy.types.Scene.BIMSpatialProperties = bpy.props.PointerProperty(type=prop.BIMSpatialProperties)
bpy.types.Object.BIMObjectSpatialProperties = bpy.props.PointerProperty(type=prop.BIMObjectSpatialProperties)
bpy.types.Scene.BIMSpatialManagerProperties = bpy.props.PointerProperty(type=prop.BIMSpatialManagerProperties)
@@ -94,7 +94,7 @@ classes = (
def register():
if not bpy.app.background:
bpy.utils.register_tool(workspace.StructuralTool, after={"bim.spatial_tool"}, separator=False, group=True)
bpy.utils.register_tool(workspace.StructuralTool, after={"bim.spatial_tool"}, separator=False, group=False)
bpy.types.Scene.BIMStructuralProperties = bpy.props.PointerProperty(type=prop.BIMStructuralProperties)
bpy.types.Object.BIMStructuralProperties = bpy.props.PointerProperty(type=prop.BIMObjectStructuralProperties)
@@ -375,7 +375,7 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator):
should_add_representation=False,
)
tool.Blender.select_and_activate_single_object(context, obj)
bpy.ops.bim.add_window()
bpy.ops.bim.add_window(obj=obj.name)
elif template == "DOOR":
mesh = bpy.data.meshes.new(name)
@@ -390,7 +390,7 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator):
should_add_representation=False,
)
tool.Blender.select_and_activate_single_object(context, obj)
bpy.ops.bim.add_door()
bpy.ops.bim.add_door(obj=obj.name)
elif template == "STAIR":
mesh = bpy.data.meshes.new(name)
@@ -222,6 +222,7 @@ class Collector(blenderbim.core.tool.Collector):
collection = bpy.data.collections.new(name)
project_obj = tool.Ifc.get_object(tool.Ifc.get().by_type("IfcProject")[0])
project_obj.BIMObjectProperties.collection.children.link(collection)
collection.hide_viewport = True
return collection
@classmethod
Binary file not shown.
+1 -1
View File
@@ -150,7 +150,7 @@ class SvIfcSverchokToIfcRepr(
representations_ids_obj = []
for item in obj:
representation = ifcopenshell.api.run(
"geometry.add_sverchok_representation",
"geometry.add_mesh_representation",
self.file,
should_run_listeners=False,
context=self.context,