You can now add type instances, and mapped representations are enforced.

This commit is contained in:
Dion Moult
2021-02-20 10:11:27 +11:00
parent 2db4a6f89f
commit a65b9f2ba7
4 changed files with 90 additions and 8 deletions
@@ -7,6 +7,7 @@ classes = (
operator.EnableEditingType,
operator.DisableEditingType,
operator.SelectSimilarType,
operator.AddTypeInstance,
prop.BIMTypeProperties,
ui.BIM_PT_type,
)
@@ -14,7 +15,9 @@ classes = (
def register():
bpy.types.Object.BIMTypeProperties = bpy.props.PointerProperty(type=prop.BIMTypeProperties)
bpy.types.VIEW3D_MT_mesh_add.append(ui.add_object_button)
def unregister():
del bpy.types.Object.BIMTypeProperties
bpy.types.VIEW3D_MT_mesh_add.remove(ui.add_object_button)
@@ -1,10 +1,13 @@
import bpy
import ifcopenshell.util.schema
import ifcopenshell.util.type
import blenderbim.bim.module.type.assign_type as assign_type
import blenderbim.bim.module.type.unassign_type as unassign_type
import blenderbim.bim.module.type.get_related_objects as get_related_objects
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.type.data import Data
from blenderbim.bim.module.type.prop import getIfcTypes, getAvailableTypes, updateTypeInstanceIfcClass
from mathutils import Vector
class AssignType(bpy.types.Operator):
@@ -12,7 +15,6 @@ class AssignType(bpy.types.Operator):
bl_label = "Assign Type"
relating_type: bpy.props.IntProperty()
related_object: bpy.props.StringProperty()
should_map_representations: bpy.props.BoolProperty()
def execute(self, context):
self.file = IfcStore.get_file()
@@ -29,7 +31,7 @@ class AssignType(bpy.types.Operator):
).execute()
Data.load(oprops.ifc_definition_id)
if self.should_map_representations:
if self.file.by_id(relating_type).RepresentationMaps:
bpy.ops.bim.map_representations(product_id=oprops.ifc_definition_id, type_product_id=relating_type)
bpy.ops.bim.disable_editing_type(obj=related_object.name)
@@ -98,3 +100,47 @@ class SelectSimilarType(bpy.types.Operator):
if obj.BIMObjectProperties.ifc_definition_id in related_objects:
obj.select_set(True)
return {"FINISHED"}
class AddTypeInstance(bpy.types.Operator):
bl_idname = "bim.add_type_instance"
bl_label = "Add Type Instance"
ifc_class: bpy.props.EnumProperty(items=getIfcTypes, name="IFC Class", update=updateTypeInstanceIfcClass)
relating_type: bpy.props.EnumProperty(items=getAvailableTypes, name="Relating Type")
def execute(self, context):
if not self.ifc_class or not self.relating_type:
return {"FINISHED"}
# A cube
verts = [
Vector((-1, -1, -1)),
Vector((-1, -1, 1)),
Vector((-1, 1, -1)),
Vector((-1, 1, 1)),
Vector((1, -1, -1)),
Vector((1, -1, 1)),
Vector((1, 1, -1)),
Vector((1, 1, 1)),
]
edges = []
faces = [
[0, 2, 3, 1],
[2, 3, 7, 6],
[4, 5, 7, 6],
[0, 1, 5, 4],
[1, 3, 7, 5],
]
mesh = bpy.data.meshes.new(name="Instance")
mesh.from_pydata(verts, edges, faces)
obj = bpy.data.objects.new("Instance", mesh)
obj.location = context.scene.cursor.location
context.view_layer.active_layer_collection.collection.objects.link(obj)
self.file = IfcStore.get_file()
instance_class = ifcopenshell.util.type.get_applicable_entities(self.ifc_class, self.file.schema)[0]
bpy.ops.bim.assign_class(obj=obj.name, ifc_class=instance_class)
bpy.ops.bim.assign_type(relating_type=int(self.relating_type), related_object=obj.name)
return {"FINISHED"}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
@@ -16,6 +16,40 @@ from bpy.props import (
applicable_types_enum = []
relating_types_enum = []
type_classes_enum = []
available_types_enum = []
def getIfcTypes(self, context):
global type_classes_enum
file = IfcStore.get_file()
if len(type_classes_enum) < 1 and file:
declaration = IfcStore.get_schema().declaration_by_name("IfcElementType")
def get_classes(declaration):
results = []
if not declaration.is_abstract():
results.append(declaration.name())
for subtype in declaration.subtypes():
results.extend(get_classes(subtype))
return results
classes = get_classes(declaration)
type_classes_enum.extend([(c, c, "") for c in sorted(classes)])
return type_classes_enum
def getAvailableTypes(self, context):
global available_types_enum
if len(available_types_enum) < 1:
elements = IfcStore.get_file().by_type(self.ifc_class)
available_types_enum.extend((str(e.id()), e.Name, "") for e in elements)
return available_types_enum
def updateTypeInstanceIfcClass(self, context):
global available_types_enum
available_types_enum.clear()
def getApplicableTypes(self, context):
@@ -48,4 +82,3 @@ class BIMTypeProperties(PropertyGroup):
relating_type: EnumProperty(items=getRelatingTypes, name="Relating Type")
# This is purely a UX thing
blank_relating_type: EnumProperty(items=[("None", "No Types Found", "")], name="Relating Type")
should_map_representations: BoolProperty(name="Should Map Representations")
@@ -35,14 +35,10 @@ class BIM_PT_type(Panel):
row.prop(props, "relating_type_class", text="")
if props.relating_type:
row.prop(props, "relating_type", text="")
op = row.operator("bim.assign_type", icon="CHECKMARK", text="")
op.should_map_representations = props.should_map_representations
row.operator("bim.assign_type", icon="CHECKMARK", text="")
else:
row.prop(props, "blank_relating_type", text="")
row.operator("bim.disable_editing_type", icon="X", text="")
row = self.layout.row(align=True)
row.prop(props, "should_map_representations")
else:
row = self.layout.row(align=True)
name = "{}/{}".format(
@@ -57,3 +53,7 @@ class BIM_PT_type(Panel):
row.operator("bim.enable_editing_type", icon="GREASEPENCIL", text="")
if name != "None/None":
row.operator("bim.unassign_type", icon="X", text="")
def add_object_button(self, context):
self.layout.operator("bim.add_type_instance", icon="PLUGIN")