WIP refactor model module with new pie menu for convenience. See #1222.

This commit is contained in:
Dion Moult
2021-01-25 14:58:12 +11:00
parent f9521eca54
commit b4ecdfba69
14 changed files with 322 additions and 182 deletions
@@ -181,7 +181,6 @@ if bpy is not None:
ui.BIM_PT_object_structural,
ui.BIM_PT_camera,
ui.BIM_PT_text,
ui.BIM_PT_modeling_utilities,
ui.BIM_PT_annotation_utilities,
ui.BIM_PT_clash_manager,
ui.BIM_PT_misc_utilities,
@@ -1570,22 +1570,22 @@ class IfcImportSettings:
self.logger = None
self.input_file = None
self.diff_file = None
self.should_import_type_representations: False
self.should_import_curves: False
self.should_import_spaces: False
self.should_auto_set_workarounds: True
self.should_use_cpu_multiprocessing: True
self.should_merge_by_class: False
self.should_merge_by_material: False
self.should_merge_materials_by_colour: False
self.should_clean_mesh: True
self.deflection_tolerance: 0.001
self.angular_tolerance: 0.5
self.should_allow_non_element_aggregates: False
self.should_offset_model: False
self.model_offset_coordinates: (0, 0, 0)
self.ifc_import_filter: "NONE"
self.ifc_selector: ""
self.should_import_type_representations = False
self.should_import_curves = False
self.should_import_spaces = False
self.should_auto_set_workarounds = True
self.should_use_cpu_multiprocessing = True
self.should_merge_by_class = False
self.should_merge_by_material = False
self.should_merge_materials_by_colour = False
self.should_clean_mesh = True
self.deflection_tolerance = 0.001
self.angular_tolerance = 0.5
self.should_allow_non_element_aggregates = False
self.should_offset_model = False
self.model_offset_coordinates = (0, 0, 0)
self.ifc_import_filter = "NONE"
self.ifc_selector = ""
@staticmethod
@@ -40,6 +40,7 @@ class Usecase:
inverse, self.settings["product"].ObjectPlacement, placement
)
old = self.settings["product"].ObjectPlacement
old.PlacementRelTo = None
self.settings["product"].ObjectPlacement = None
if not self.file.get_inverse(old):
ifcopenshell.util.element.remove_deep(self.file, old)
@@ -1,5 +1,5 @@
import bpy
from . import grid, wall, stair, door, window, slab, opening
from . import grid, wall, stair, door, window, slab, opening, pie
classes = (
grid.BIM_OT_add_object,
@@ -9,8 +9,20 @@ classes = (
window.BIM_OT_add_object,
slab.BIM_OT_add_object,
opening.BIM_OT_add_object,
pie.OpenPieClass,
pie.PieUpdateContainer,
pie.PieAddOpening,
pie.AssignIfcWall,
pie.AssignIfcSlab,
pie.AssignIfcStair,
pie.AssignIfcDoor,
pie.AssignIfcWindow,
pie.VIEW3D_MT_PIE_bim,
pie.VIEW3D_MT_PIE_bim_class,
)
addon_keymaps = []
def register():
bpy.types.VIEW3D_MT_mesh_add.append(grid.add_object_button)
@@ -20,6 +32,12 @@ def register():
bpy.types.VIEW3D_MT_mesh_add.append(window.add_object_button)
bpy.types.VIEW3D_MT_mesh_add.append(slab.add_object_button)
bpy.types.VIEW3D_MT_mesh_add.append(opening.add_object_button)
wm = bpy.context.window_manager
if wm.keyconfigs.addon:
km = wm.keyconfigs.addon.keymaps.new(name="3D View", space_type="VIEW_3D")
kmi = km.keymap_items.new("wm.call_menu_pie", "E", "PRESS", shift=True)
kmi.properties["name"] = "VIEW3D_MT_PIE_bim"
addon_keymaps.append((km, kmi))
def unregister():
@@ -30,3 +48,9 @@ def unregister():
bpy.types.VIEW3D_MT_mesh_add.remove(window.add_object_button)
bpy.types.VIEW3D_MT_mesh_add.remove(slab.add_object_button)
bpy.types.VIEW3D_MT_mesh_add.remove(opening.add_object_button)
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
@@ -10,60 +10,61 @@ from mathutils import Vector
def add_object(self, context):
guid = ifcopenshell.guid.new()
leaf_width = self.overall_width - 0.045 - 0.045
verts = [
# Left lining
Vector((0, 0, 0)),
Vector((0, self.depth, 0)),
Vector((0.04, self.depth, 0)),
Vector((0.04, self.depth - 0.04, 0)),
Vector((0.065, self.depth - 0.04, 0)),
Vector((0.065, 0, 0)),
# Right lining
Vector((self.overall_width, 0, 0)),
Vector((self.overall_width, self.depth, 0)),
Vector((self.overall_width - 0.04, self.depth, 0)),
Vector((self.overall_width - 0.04, self.depth - 0.04, 0)),
Vector((self.overall_width - 0.065, self.depth - 0.04, 0)),
Vector((self.overall_width - 0.065, 0, 0)),
# Door panel
Vector((0.045, self.depth, 0)),
Vector((0.045, self.depth + leaf_width, 0)),
Vector((0.080, self.depth + leaf_width, 0)),
Vector((0.080, self.depth, 0)),
]
edges = [
[0, 1],
[1, 2],
[2, 3],
[3, 4],
[4, 5], # Left lining
[6, 7],
[7, 8],
[8, 9],
[9, 10],
[10, 11], # Right lining
[12, 13],
[13, 14],
[14, 15],
[15, 12], # Door panel
]
# Door swing
for i in range(0, 9):
verts.append(
Vector(
(
0.045 + (leaf_width * math.cos((math.pi / 2) / 8 * i)),
self.depth + (leaf_width * math.sin((math.pi / 2) / 8 * i)),
0,
)
)
)
edges.append([16 + i, 17 + i])
edges.pop()
faces = []
mesh = bpy.data.meshes.new(name="Plan/Annotation/PLAN_VIEW/" + guid)
mesh.use_fake_user = True
mesh.from_pydata(verts, edges, faces)
# TODO reimplement 2D. See #1222.
#verts = [
# # Left lining
# Vector((0, 0, 0)),
# Vector((0, self.depth, 0)),
# Vector((0.04, self.depth, 0)),
# Vector((0.04, self.depth - 0.04, 0)),
# Vector((0.065, self.depth - 0.04, 0)),
# Vector((0.065, 0, 0)),
# # Right lining
# Vector((self.overall_width, 0, 0)),
# Vector((self.overall_width, self.depth, 0)),
# Vector((self.overall_width - 0.04, self.depth, 0)),
# Vector((self.overall_width - 0.04, self.depth - 0.04, 0)),
# Vector((self.overall_width - 0.065, self.depth - 0.04, 0)),
# Vector((self.overall_width - 0.065, 0, 0)),
# # Door panel
# Vector((0.045, self.depth, 0)),
# Vector((0.045, self.depth + leaf_width, 0)),
# Vector((0.080, self.depth + leaf_width, 0)),
# Vector((0.080, self.depth, 0)),
#]
#edges = [
# [0, 1],
# [1, 2],
# [2, 3],
# [3, 4],
# [4, 5], # Left lining
# [6, 7],
# [7, 8],
# [8, 9],
# [9, 10],
# [10, 11], # Right lining
# [12, 13],
# [13, 14],
# [14, 15],
# [15, 12], # Door panel
#]
## Door swing
#for i in range(0, 9):
# verts.append(
# Vector(
# (
# 0.045 + (leaf_width * math.cos((math.pi / 2) / 8 * i)),
# self.depth + (leaf_width * math.sin((math.pi / 2) / 8 * i)),
# 0,
# )
# )
# )
# edges.append([16 + i, 17 + i])
#edges.pop()
#faces = []
#mesh = bpy.data.meshes.new(name="Plan/Annotation/PLAN_VIEW/" + guid)
#mesh.use_fake_user = True
#mesh.from_pydata(verts, edges, faces)
# Door lining profile
verts = [
@@ -96,6 +97,7 @@ def add_object(self, context):
bpy.ops.object.convert(target="CURVE")
obj2.data.dimensions = "2D"
obj2.data.bevel_mode = "OBJECT"
obj2.data.bevel_object = obj
obj2.rotation_euler[0] = math.pi / 2
@@ -145,27 +147,22 @@ def add_object(self, context):
obj4.parent = obj2
obj4.matrix_parent_inverse = obj2.matrix_world.inverted()
obj4.hide_render = True
obj4.name = "IfcOpeningElement/Dumb Door Opening"
attribute = obj4.BIMObjectProperties.attributes.add()
attribute.name = "PredefinedType"
attribute.string_value = "OPENING"
obj4.name = "Door Opening"
obj2.name = "IfcDoor/Dumb Door"
attribute = obj2.BIMObjectProperties.attributes.add()
attribute.name = "PredefinedType"
attribute.string_value = "DOOR"
obj2.data.name = "Model/Body/MODEL_VIEW/" + guid
obj2.data.use_fake_user = True
obj2.name = "Door"
#obj2.data.name = "Model/Body/MODEL_VIEW/" + guid
#obj2.data.use_fake_user = True
rep = obj2.BIMObjectProperties.representation_contexts.add()
rep.context = "Model"
rep.name = "Body"
rep.target_view = "MODEL_VIEW"
# TODO: reimplement. See #1222.
#rep = obj2.BIMObjectProperties.representation_contexts.add()
#rep.context = "Model"
#rep.name = "Body"
#rep.target_view = "MODEL_VIEW"
rep = obj2.BIMObjectProperties.representation_contexts.add()
rep.context = "Plan"
rep.name = "Annotation"
rep.target_view = "PLAN_VIEW"
#rep = obj2.BIMObjectProperties.representation_contexts.add()
#rep.context = "Plan"
#rep.name = "Annotation"
#rep.target_view = "PLAN_VIEW"
class BIM_OT_add_object(Operator, AddObjectHelper):
@@ -15,11 +15,8 @@ def add_object(self, context):
bm.to_mesh(mesh)
bm.free()
obj = object_data_add(context, mesh, operator=self)
obj.name = "IfcOpening/Dumb Opening"
obj.name = "Opening"
obj.display_type = "WIRE"
attribute = obj.BIMObjectProperties.attributes.add()
attribute.name = "PredefinedType"
attribute.string_value = "OPENING"
class BIM_OT_add_object(Operator, AddObjectHelper):
@@ -0,0 +1,124 @@
import bpy
class OpenPieClass(bpy.types.Operator):
bl_idname = "bim.open_pie_class"
bl_label = "Open Pie Class"
def execute(self, context):
bpy.ops.wm.call_menu_pie(name="VIEW3D_MT_PIE_bim_class")
return {"FINISHED"}
class AssignIfcWall(bpy.types.Operator):
bl_idname = "bim.assign_ifc_wall"
bl_label = "IfcWall"
def execute(self, context):
for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id:
bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcWall")
return {"FINISHED"}
class AssignIfcSlab(bpy.types.Operator):
bl_idname = "bim.assign_ifc_slab"
bl_label = "IfcSlab"
def execute(self, context):
for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id:
bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcSlab")
return {"FINISHED"}
class AssignIfcStair(bpy.types.Operator):
bl_idname = "bim.assign_ifc_stair"
bl_label = "IfcStair"
def execute(self, context):
for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id:
bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcStair")
return {"FINISHED"}
class AssignIfcDoor(bpy.types.Operator):
bl_idname = "bim.assign_ifc_door"
bl_label = "IfcDoor"
def execute(self, context):
for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id:
bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcDoor")
return {"FINISHED"}
class AssignIfcWindow(bpy.types.Operator):
bl_idname = "bim.assign_ifc_window"
bl_label = "IfcWindow"
def execute(self, context):
for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id:
bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcWindow")
return {"FINISHED"}
class PieAddOpening(bpy.types.Operator):
bl_idname = "bim.pie_add_opening"
bl_label = "Add Opening"
def execute(self, context):
if len(context.selected_objects) == 2:
opening_name = None
obj_name = None
for obj in context.selected_objects:
if "IfcOpeningElement" in obj.name or not obj.BIMObjectProperties.ifc_definition_id:
opening_name = obj.name
else:
opj_name = obj.name
bpy.ops.bim.add_opening(obj=opj_name, opening=opening_name)
return {"FINISHED"}
class PieUpdateContainer(bpy.types.Operator):
bl_idname = "bim.pie_update_container"
bl_label = "Update Spatial Container"
def execute(self, context):
for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id:
continue
relating_structure = None
for collection in obj.users_collection:
relating_structure_obj = bpy.data.objects.get(collection.name)
if not relating_structure_obj or not relating_structure_obj.BIMObjectProperties.ifc_definition_id:
continue
relating_structure = relating_structure_obj
bpy.ops.bim.assign_container(relating_structure=relating_structure.name, related_element=obj.name)
return {"FINISHED"}
class VIEW3D_MT_PIE_bim(bpy.types.Menu):
bl_label = "Geometry"
def draw(self, context):
pie = self.layout.menu_pie()
pie.operator("bim.edit_object_placement")
pie.operator("bim.update_mesh_representation")
pie.operator("bim.pie_add_opening")
pie.operator("bim.pie_update_container")
pie.operator("bim.open_pie_class", text="Assign IFC Class")
class VIEW3D_MT_PIE_bim_class(bpy.types.Menu):
bl_label = "IFC Class"
def draw(self, context):
pie = self.layout.menu_pie()
pie.operator("bim.assign_ifc_wall")
pie.operator("bim.assign_ifc_slab")
pie.operator("bim.assign_ifc_stair")
pie.operator("bim.assign_ifc_door")
pie.operator("bim.assign_ifc_window")
@@ -22,10 +22,7 @@ def add_object(self, context):
modifier.use_even_offset = True
modifier.offset = 1
modifier.thickness = self.depth
obj.name = "IfcSlab/Dumb Slab"
attribute = obj.BIMObjectProperties.attributes.add()
attribute.name = "PredefinedType"
attribute.string_value = "FLOOR"
obj.name = "Slab"
class BIM_OT_add_object(Operator, AddObjectHelper):
@@ -28,14 +28,13 @@ def add_object(self, context):
modifier.relative_offset_displace[0] = 0
modifier.relative_offset_displace[1] = 1
modifier.use_constant_offset = True
modifier.constant_offset_displace[0] = 0
modifier.constant_offset_displace[1] = 0
modifier.constant_offset_displace[2] = self.height / self.number_of_treads
modifier.count = self.number_of_treads
self.riser_height = self.height / self.number_of_treads
self.length = self.number_of_treads * self.tread_length
obj.name = "IfcStairFlight/Dumb Stair"
attribute = obj.BIMObjectProperties.attributes.add()
attribute.name = "PredefinedType"
attribute.string_value = "STRAIGHT"
obj.name = "Stair"
class BIM_OT_add_object(Operator, AddObjectHelper):
@@ -38,10 +38,8 @@ def add_object(self, context):
modifier = obj.modifiers.new("Wall Width", "SOLIDIFY")
modifier.use_even_offset = True
modifier.thickness = self.width
obj.name = "IfcWall/Dumb Wall"
attribute = obj.BIMObjectProperties.attributes.add()
attribute.name = "PredefinedType"
attribute.string_value = "STANDARD"
obj.name = "Wall"
return obj
class BIM_OT_add_object(Operator, AddObjectHelper):
@@ -10,48 +10,48 @@ from mathutils import Vector
def add_object(self, context):
guid = ifcopenshell.guid.new()
leaf_width = self.overall_width - 0.045 - 0.045
verts = [
# Left lining
Vector((0, 0, 0)),
Vector((0, self.depth, 0)),
Vector((0.04, self.depth, 0)),
Vector((0.04, 0, 0)),
# Right lining
Vector((self.overall_width, 0, 0)),
Vector((self.overall_width, self.depth, 0)),
Vector((self.overall_width - 0.04, self.depth, 0)),
Vector((self.overall_width - 0.04, 0, 0)),
# Bottom lining
Vector((0, 0, 0)),
Vector((self.overall_width, 0, 0)),
Vector((0, self.depth, 0)),
Vector((self.overall_width, self.depth, 0)),
# Window panel
Vector((0.04, (self.depth / 2) + 0.005, 0)),
Vector((0.04, (self.depth / 2) - 0.005, 0)),
Vector((self.overall_width - 0.04, (self.depth / 2) - 0.005, 0)),
Vector((self.overall_width - 0.04, (self.depth / 2) + 0.005, 0)),
]
edges = [
[0, 1],
[1, 2],
[2, 3],
[3, 0], # Left lining
[4, 5],
[5, 6],
[6, 7],
[7, 4], # Right lining
[8, 9],
[10, 11], # Bottom lining
[12, 13],
[13, 14],
[14, 15],
[15, 12], # Window panel
]
faces = []
mesh = bpy.data.meshes.new(name="Plan/Annotation/PLAN_VIEW/" + guid)
mesh.use_fake_user = True
mesh.from_pydata(verts, edges, faces)
#verts = [
# # Left lining
# Vector((0, 0, 0)),
# Vector((0, self.depth, 0)),
# Vector((0.04, self.depth, 0)),
# Vector((0.04, 0, 0)),
# # Right lining
# Vector((self.overall_width, 0, 0)),
# Vector((self.overall_width, self.depth, 0)),
# Vector((self.overall_width - 0.04, self.depth, 0)),
# Vector((self.overall_width - 0.04, 0, 0)),
# # Bottom lining
# Vector((0, 0, 0)),
# Vector((self.overall_width, 0, 0)),
# Vector((0, self.depth, 0)),
# Vector((self.overall_width, self.depth, 0)),
# # Window panel
# Vector((0.04, (self.depth / 2) + 0.005, 0)),
# Vector((0.04, (self.depth / 2) - 0.005, 0)),
# Vector((self.overall_width - 0.04, (self.depth / 2) - 0.005, 0)),
# Vector((self.overall_width - 0.04, (self.depth / 2) + 0.005, 0)),
#]
#edges = [
# [0, 1],
# [1, 2],
# [2, 3],
# [3, 0], # Left lining
# [4, 5],
# [5, 6],
# [6, 7],
# [7, 4], # Right lining
# [8, 9],
# [10, 11], # Bottom lining
# [12, 13],
# [13, 14],
# [14, 15],
# [15, 12], # Window panel
#]
#faces = []
#mesh = bpy.data.meshes.new(name="Plan/Annotation/PLAN_VIEW/" + guid)
#mesh.use_fake_user = True
#mesh.from_pydata(verts, edges, faces)
# Window lining profile
verts = [
@@ -83,6 +83,7 @@ def add_object(self, context):
obj2.data.splines[0].use_cyclic_u = True
obj2.data.dimensions = "2D"
obj2.data.bevel_mode = "OBJECT"
obj2.data.bevel_object = obj
obj2.rotation_euler[0] = math.pi / 2
@@ -132,27 +133,21 @@ def add_object(self, context):
obj4.parent = obj2
obj4.matrix_parent_inverse = obj2.matrix_world.inverted()
obj4.hide_render = True
obj4.name = "IfcOpeningElement/Dumb Window Opening"
attribute = obj4.BIMObjectProperties.attributes.add()
attribute.name = "PredefinedType"
attribute.string_value = "OPENING"
obj4.name = "Window Opening"
obj2.name = "IfcWindow/Dumb Window"
attribute = obj2.BIMObjectProperties.attributes.add()
attribute.name = "PredefinedType"
attribute.string_value = "WINDOW"
obj2.data.name = "Model/Body/MODEL_VIEW/" + guid
obj2.data.use_fake_user = True
obj2.name = "Window"
#obj2.data.name = "Model/Body/MODEL_VIEW/" + guid
#obj2.data.use_fake_user = True
rep = obj2.BIMObjectProperties.representation_contexts.add()
rep.context = "Model"
rep.name = "Body"
rep.target_view = "MODEL_VIEW"
#rep = obj2.BIMObjectProperties.representation_contexts.add()
#rep.context = "Model"
#rep.name = "Body"
#rep.target_view = "MODEL_VIEW"
rep = obj2.BIMObjectProperties.representation_contexts.add()
rep.context = "Plan"
rep.name = "Annotation"
rep.target_view = "PLAN_VIEW"
#rep = obj2.BIMObjectProperties.representation_contexts.add()
#rep.context = "Plan"
#rep.name = "Annotation"
#rep.target_view = "PLAN_VIEW"
class BIM_OT_add_object(Operator, AddObjectHelper):
@@ -17,6 +17,7 @@ class AddOpening(bpy.types.Operator):
def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
opening = bpy.data.objects.get(self.opening)
opening.display_type = "WIRE"
if not opening.BIMObjectProperties.ifc_definition_id:
body_context_id = None
if not ContextData.is_loaded:
+24 -2
View File
@@ -270,7 +270,18 @@ def getSubcontexts(self, context):
global subcontexts_enum
subcontexts_enum.clear()
# TODO: allow override of generated subcontexts?
subcontexts = export_ifc.IfcExportSettings().subcontexts
subcontexts = [
"Annotation",
"Axis",
"Box",
"FootPrint",
"Reference",
"Body",
"Clearance",
"CoG",
"Profile",
"SurveyPoints",
]
for subcontext in subcontexts:
subcontexts_enum.append((subcontext, subcontext, ""))
return subcontexts_enum
@@ -279,7 +290,18 @@ def getSubcontexts(self, context):
def getTargetViews(self, context):
global target_views_enum
target_views_enum.clear()
for target_view in export_ifc.IfcExportSettings().target_views:
target_views = [
"GRAPH_VIEW",
"SKETCH_VIEW",
"MODEL_VIEW",
"PLAN_VIEW",
"REFLECTED_PLAN_VIEW",
"SECTION_VIEW",
"ELEVATION_VIEW",
"USERDEFINED",
"NOTDEFINED",
]
for target_view in target_views:
target_views_enum.append((target_view, target_view, ""))
return target_views_enum
-14
View File
@@ -565,20 +565,6 @@ class BIM_PT_ifcclash(Panel):
row.operator("bim.select_ifc_clash_results")
class BIM_PT_modeling_utilities(Panel):
bl_idname = "BIM_PT_modeling_utilities"
bl_label = "Architectural"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "BlenderBIM"
def draw(self, context):
layout = self.layout
row = layout.row(align=True)
row.operator("bim.add_opening")
class BIM_PT_annotation_utilities(Panel):
bl_idname = "BIM_PT_annotation_utilities"
bl_label = "Annotation"