You can now assign types with a smart type filter, without needing to first import types into Blender

This commit is contained in:
Dion Moult
2021-02-13 18:29:52 +11:00
parent e4dee2258d
commit 1b2bebecb0
6 changed files with 87 additions and 32 deletions
@@ -1,6 +1,5 @@
import os import os
from pathlib import Path from pathlib import Path
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.prop import StrProperty from blenderbim.bim.prop import StrProperty
from blenderbim.bim.module.root.prop import getIfcClasses from blenderbim.bim.module.root.prop import getIfcClasses
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
@@ -1,5 +1,5 @@
import bpy import bpy
from . import ui, operator from . import ui, prop, operator
classes = ( classes = (
operator.AssignType, operator.AssignType,
@@ -7,13 +7,14 @@ classes = (
operator.EnableEditingType, operator.EnableEditingType,
operator.DisableEditingType, operator.DisableEditingType,
operator.SelectSimilarType, operator.SelectSimilarType,
prop.BIMTypeProperties,
ui.BIM_PT_type, ui.BIM_PT_type,
) )
def register(): def register():
pass bpy.types.Object.BIMTypeProperties = bpy.props.PointerProperty(type=prop.BIMTypeProperties)
def unregister(): def unregister():
pass del bpy.types.Object.BIMTypeProperties
@@ -10,24 +10,23 @@ from blenderbim.bim.module.type.data import Data
class AssignType(bpy.types.Operator): class AssignType(bpy.types.Operator):
bl_idname = "bim.assign_type" bl_idname = "bim.assign_type"
bl_label = "Assign Type" bl_label = "Assign Type"
relating_type: bpy.props.StringProperty() relating_type: bpy.props.IntProperty()
related_object: bpy.props.StringProperty() related_object: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
related_object = bpy.data.objects.get(self.related_object) if self.related_object else bpy.context.active_object related_object = bpy.data.objects.get(self.related_object) if self.related_object else bpy.context.active_object
props = related_object.BIMObjectProperties oprops = related_object.BIMObjectProperties
relating_type = bpy.data.objects.get(self.relating_type) if self.relating_type else props.relating_type props = related_object.BIMTypeProperties
if not relating_type or not relating_type.BIMObjectProperties.ifc_definition_id: relating_type = self.relating_type or int(props.relating_type)
return {"FINISHED"}
assign_type.Usecase( assign_type.Usecase(
self.file, self.file,
{ {
"related_object": self.file.by_id(props.ifc_definition_id), "related_object": self.file.by_id(oprops.ifc_definition_id),
"relating_type": self.file.by_id(relating_type.BIMObjectProperties.ifc_definition_id), "relating_type": self.file.by_id(relating_type),
}, },
).execute() ).execute()
Data.load(props.ifc_definition_id) Data.load(oprops.ifc_definition_id)
bpy.ops.bim.disable_editing_type(obj=related_object.name) bpy.ops.bim.disable_editing_type(obj=related_object.name)
return {"FINISHED"} return {"FINISHED"}
@@ -40,14 +39,14 @@ class UnassignType(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
related_object = bpy.data.objects.get(self.related_object) if self.related_object else bpy.context.active_object related_object = bpy.data.objects.get(self.related_object) if self.related_object else bpy.context.active_object
props = related_object.BIMObjectProperties oprops = related_object.BIMObjectProperties
unassign_type.Usecase( unassign_type.Usecase(
self.file, self.file,
{ {
"related_object": self.file.by_id(props.ifc_definition_id), "related_object": self.file.by_id(oprops.ifc_definition_id),
}, },
).execute() ).execute()
Data.load(props.ifc_definition_id) Data.load(oprops.ifc_definition_id)
return {"FINISHED"} return {"FINISHED"}
@@ -56,8 +55,7 @@ class EnableEditingType(bpy.types.Operator):
bl_label = "Enable Editing Type" bl_label = "Enable Editing Type"
def execute(self, context): def execute(self, context):
bpy.context.active_object.BIMObjectProperties.relating_type = None bpy.context.active_object.BIMTypeProperties.is_editing_type = True
bpy.context.active_object.BIMObjectProperties.is_editing_type = True
return {"FINISHED"} return {"FINISHED"}
@@ -68,7 +66,7 @@ class DisableEditingType(bpy.types.Operator):
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
obj.BIMObjectProperties.is_editing_type = False obj.BIMTypeProperties.is_editing_type = False
return {"FINISHED"} return {"FINISHED"}
@@ -80,16 +78,16 @@ class SelectSimilarType(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
related_object = bpy.data.objects.get(self.related_object) if self.related_object else bpy.context.active_object related_object = bpy.data.objects.get(self.related_object) if self.related_object else bpy.context.active_object
props = related_object.BIMObjectProperties oprops = related_object.BIMObjectProperties
product = self.file.by_id(props.ifc_definition_id) product = self.file.by_id(oprops.ifc_definition_id)
declaration = IfcStore.get_schema().declaration_by_name(product.is_a()) declaration = IfcStore.get_schema().declaration_by_name(product.is_a())
if ifcopenshell.util.schema.is_a(declaration, "IfcElementType"): if ifcopenshell.util.schema.is_a(declaration, "IfcElementType"):
related_objects = get_related_objects.Usecase(self.file, { related_objects = get_related_objects.Usecase(self.file, {
"relating_type": self.file.by_id(props.ifc_definition_id) "relating_type": self.file.by_id(oprops.ifc_definition_id)
}).execute() }).execute()
else: else:
related_objects = get_related_objects.Usecase(self.file, { related_objects = get_related_objects.Usecase(self.file, {
"related_object": self.file.by_id(props.ifc_definition_id) "related_object": self.file.by_id(oprops.ifc_definition_id)
}).execute() }).execute()
for obj in bpy.context.visible_objects: for obj in bpy.context.visible_objects:
if obj.BIMObjectProperties.ifc_definition_id in related_objects: if obj.BIMObjectProperties.ifc_definition_id in related_objects:
@@ -0,0 +1,51 @@
import bpy
import ifcopenshell.util.type
from blenderbim.bim.prop import StrProperty, Attribute
from blenderbim.bim.ifc import IfcStore
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
)
applicable_types_enum = []
relating_types_enum = []
def getApplicableTypes(self, context):
global applicable_types_enum
if len(applicable_types_enum) < 1:
element = IfcStore.get_file().by_id(context.active_object.BIMObjectProperties.ifc_definition_id)
types = ifcopenshell.util.type.get_applicable_types(element.is_a(), schema=IfcStore.get_file().schema)
applicable_types_enum.extend((t, t, "") for t in types)
return applicable_types_enum
def getRelatingTypes(self, context):
global relating_types_enum
if len(relating_types_enum) < 1:
elements = IfcStore.get_file().by_type(context.active_object.BIMTypeProperties.relating_type_class)
relating_types_enum.extend((str(e.id()), e.Name, "") for e in elements)
return relating_types_enum
def updateTypeDropdowns(self, context):
global applicable_types_enum
global relating_types_enum
applicable_types_enum.clear()
relating_types_enum.clear()
class BIMTypeProperties(PropertyGroup):
is_editing_type: BoolProperty(name="Is Editing Type", update=updateTypeDropdowns)
relating_type_class: EnumProperty(items=getApplicableTypes, name="Relating Type Class")
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")
@@ -22,21 +22,30 @@ class BIM_PT_type(Panel):
def draw(self, context): def draw(self, context):
props = context.active_object.BIMObjectProperties props = context.active_object.BIMTypeProperties
if not props.ifc_definition_id: oprops = context.active_object.BIMObjectProperties
if not oprops.ifc_definition_id:
return return
if props.ifc_definition_id not in Data.products: if oprops.ifc_definition_id not in Data.products:
Data.load(props.ifc_definition_id) Data.load(oprops.ifc_definition_id)
if props.is_editing_type: if props.is_editing_type:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.prop(props, "relating_type", text="")
row.operator("bim.assign_type", icon="CHECKMARK", text="") row.prop(props, "relating_type_class", text="")
if props.relating_type:
row.prop(props, "relating_type", text="")
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.operator("bim.disable_editing_type", icon="X", text="")
row = self.layout.row(align=True)
row.prop(props, "should_map_representations")
else: else:
row = self.layout.row(align=True) row = self.layout.row(align=True)
name = "{}/{}".format( name = "{}/{}".format(
Data.products[props.ifc_definition_id]["type"], Data.products[props.ifc_definition_id]["Name"] Data.products[oprops.ifc_definition_id]["type"], Data.products[oprops.ifc_definition_id]["Name"]
) )
if name == "None/None": if name == "None/None":
label = "This object has no type" label = "This object has no type"
@@ -484,9 +484,6 @@ class BIMObjectProperties(PropertyGroup):
relating_object: PointerProperty(name="Aggregate", type=bpy.types.Object) relating_object: PointerProperty(name="Aggregate", type=bpy.types.Object)
is_editing_aggregate: BoolProperty(name="Is Editing Aggregate") is_editing_aggregate: BoolProperty(name="Is Editing Aggregate")
is_editing_container: BoolProperty(name="Is Editing Container") is_editing_container: BoolProperty(name="Is Editing Container")
relating_type: PointerProperty(name="Type", type=bpy.types.Object)
is_editing_type: BoolProperty(name="Is Editing Type")
relating_type: PointerProperty(name="Type Product", type=bpy.types.Object)
relating_structure: PointerProperty(name="Spatial Container", type=bpy.types.Object) relating_structure: PointerProperty(name="Spatial Container", type=bpy.types.Object)
psets: CollectionProperty(name="Psets", type=PsetQto) psets: CollectionProperty(name="Psets", type=PsetQto)
qtos: CollectionProperty(name="Qtos", type=PsetQto) qtos: CollectionProperty(name="Qtos", type=PsetQto)