diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py
index 6703bda0dc..8dc2442216 100644
--- a/src/blenderbim/blenderbim/bim/helper.py
+++ b/src/blenderbim/blenderbim/bim/helper.py
@@ -40,7 +40,7 @@ def draw_attribute(attribute, layout, copy_operator=None):
return
if len(attribute.enumerated_values) != 0:
layout.label(text=attribute.name)
- grid = layout.column_flow(columns=4)
+ grid = layout.column_flow(columns=3)
for e in attribute.enumerated_values:
grid.prop(
e,
diff --git a/src/blenderbim/blenderbim/bim/module/brick/prop.py b/src/blenderbim/blenderbim/bim/module/brick/prop.py
index 6e0ba7c814..0d4eec7a6d 100644
--- a/src/blenderbim/blenderbim/bim/module/brick/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/brick/prop.py
@@ -69,3 +69,9 @@ class BIMBrickProperties(PropertyGroup):
libraries: EnumProperty(name="Libraries", items=get_libraries)
namespace: EnumProperty(name="Namespace", items=get_namespaces)
brick_equipment_class: EnumProperty(name="Brick Equipment Class", items=get_brick_equipment_classes)
+
+ getter_enum = {
+ "libraries": get_libraries,
+ "namespace": get_namespaces,
+ "brick_equipment_class": get_brick_equipment_classes,
+ }
diff --git a/src/blenderbim/blenderbim/bim/module/brick/ui.py b/src/blenderbim/blenderbim/bim/module/brick/ui.py
index da3647ab6d..f0b1cedce7 100644
--- a/src/blenderbim/blenderbim/bim/module/brick/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/brick/ui.py
@@ -18,6 +18,7 @@
import blenderbim.tool as tool
from bpy.types import Panel, UIList
+from blenderbim.bim.ui import prop_with_search
from blenderbim.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
@@ -48,7 +49,8 @@ class BIM_PT_brickschema(Panel):
row.operator("bim.close_brick_project", text="", icon="CANCEL")
row = self.layout.row(align=True)
- row.prop(self.props, "namespace", text="")
+ prop_with_search(row, self.props, "namespace", text="")
+ prop_with_search(row, self.props, "brick_equipment_class", text="")
row.prop(self.props, "brick_equipment_class", text="")
row.operator("bim.add_brick", text="", icon="ADD")
@@ -101,7 +103,7 @@ class BIM_PT_ifc_brickschema_references(Panel):
return
row = self.layout.row(align=True)
- row.prop(self.props, "libraries")
+ prop_with_search(row, self.props, "libraries")
row.operator("bim.convert_brick_project", text="", icon="ADD")
row = self.layout.row(align=True)
diff --git a/src/blenderbim/blenderbim/bim/module/geometry/ui.py b/src/blenderbim/blenderbim/bim/module/geometry/ui.py
index 78c8e21414..4ce050ffb9 100644
--- a/src/blenderbim/blenderbim/bim/module/geometry/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/geometry/ui.py
@@ -19,6 +19,7 @@
import bpy
from bpy.types import Panel
from blenderbim.bim.ifc import IfcStore
+from blenderbim.bim.ui import prop_with_search
from blenderbim.bim.module.geometry.data import RepresentationsData, DerivedPlacementsData
@@ -50,7 +51,7 @@ class BIM_PT_representations(Panel):
layout.label(text="No representations found")
row = layout.row(align=True)
- row.prop(context.scene.BIMRootProperties, "contexts", text="")
+ prop_with_search(row, context.scene.BIMRootProperties, "contexts", text="")
row.operator("bim.add_representation", icon="ADD", text="")
for representation in RepresentationsData.data["representations"]:
diff --git a/src/blenderbim/blenderbim/bim/module/patch/prop.py b/src/blenderbim/blenderbim/bim/module/patch/prop.py
index 27c0e44ab5..0fb0a5f341 100644
--- a/src/blenderbim/blenderbim/bim/module/patch/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/patch/prop.py
@@ -66,3 +66,7 @@ class BIMPatchProperties(PropertyGroup):
ifc_patch_output: StringProperty(default="", name="IFC Patch Output IFC")
ifc_patch_args: StringProperty(default="", name="Arguments")
ifc_patch_args_attr: CollectionProperty(type=Attribute, name="Arguments")
+
+ getter_enum = {
+ "ifc_patch_recipes": get_ifcpatch_recipes,
+ }
diff --git a/src/blenderbim/blenderbim/bim/module/patch/ui.py b/src/blenderbim/blenderbim/bim/module/patch/ui.py
index 618a5077ca..9d58971d7d 100644
--- a/src/blenderbim/blenderbim/bim/module/patch/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/patch/ui.py
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see .
+from blenderbim.bim.ui import prop_with_search
import bpy
from blenderbim.bim.helper import draw_attributes
@@ -37,7 +38,7 @@ class BIM_PT_patch(bpy.types.Panel):
scene = context.scene
props = scene.BIMPatchProperties
row = layout.row()
- row.prop(props, "ifc_patch_recipes")
+ prop_with_search(row, props, "ifc_patch_recipes")
row = layout.row(align=True)
row.prop(props, "ifc_patch_input")
diff --git a/src/blenderbim/blenderbim/bim/module/project/prop.py b/src/blenderbim/blenderbim/bim/module/project/prop.py
index 3fe5e5077f..4d38d465fe 100644
--- a/src/blenderbim/blenderbim/bim/module/project/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/project/prop.py
@@ -167,3 +167,28 @@ class BIMProjectProperties(PropertyGroup):
def get_library_element_index(self, lib_element):
return next((i for i in range(len(self.library_elements)) if self.library_elements[i] == lib_element))
+
+ getter_enum = {
+ "collection_mode": lambda self, context: [
+ ("DECOMPOSITION", "Decomposition", "Collections represent aggregates and spatial containers"),
+ ("SPATIAL_DECOMPOSITION", "Spatial Decomposition", "Collections represent spatial containers"),
+ ("IFC_CLASS", "IFC Class", "Collections represent IFC class"),
+ ("NONE", "None", "No collections are created"),
+ ],
+ "filter_mode": lambda self, context: [
+ ("NONE", "None", "No filtering is performed"),
+ ("DECOMPOSITION", "Decomposition", "Filter objects by decomposition"),
+ ("IFC_CLASS", "IFC Class", "Filter objects by class"),
+ ("IFC_TYPE", "IFC Type", "Filter objects by type"),
+ ("WHITELIST", "Whitelist", "Filter objects using a custom whitelist query"),
+ ("BLACKLIST", "Blacklist", "Filter objects using a custom blacklist query"),
+ ],
+ "merge_mode": lambda self, context: [
+ ("NONE", "None", "No objects are merged"),
+ ("IFC_CLASS", "IFC Class", "One object per IFC class"),
+ ("IFC_TYPE", "IFC Type", "One object per IFC construction type"),
+ ("MATERIAL", "Material", "One object per material"),
+ ],
+ "export_schema": get_export_schema,
+ "template_file": get_template_file,
+ }
diff --git a/src/blenderbim/blenderbim/bim/module/project/ui.py b/src/blenderbim/blenderbim/bim/module/project/ui.py
index c8be2f2933..8a0a21f109 100644
--- a/src/blenderbim/blenderbim/bim/module/project/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/project/ui.py
@@ -17,6 +17,7 @@
# along with BlenderBIM Add-on. If not, see .
import os
+from blenderbim.bim.ui import prop_with_search
from bpy.types import Panel, UIList
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.project.data import ProjectData
@@ -48,10 +49,8 @@ class BIM_PT_project(Panel):
def draw_load_ui(self, context):
pprops = context.scene.BIMProjectProperties
- row = self.layout.row()
- row.prop(pprops, "collection_mode")
- row = self.layout.row()
- row.prop(pprops, "filter_mode")
+ prop_with_search(self.layout, pprops, "collection_mode")
+ prop_with_search(self.layout, pprops, "filter_mode")
if pprops.filter_mode in ["DECOMPOSITION", "IFC_CLASS", "IFC_TYPE"]:
row = self.layout.row(align=True)
row.label(text=f"Total: {pprops.total_elements}")
@@ -84,8 +83,7 @@ class BIM_PT_project(Panel):
row = self.layout.row()
row.prop(pprops, "is_coordinating")
if pprops.is_coordinating:
- row = self.layout.row()
- row.prop(pprops, "merge_mode")
+ prop_with_search(self.layout, pprops, "merge_mode")
row = self.layout.row()
row.prop(pprops, "deflection_tolerance")
row = self.layout.row()
@@ -170,8 +168,7 @@ class BIM_PT_project(Panel):
def draw_create_project_ui(self, context):
props = context.scene.BIMProperties
pprops = context.scene.BIMProjectProperties
- row = self.layout.row()
- row.prop(pprops, "export_schema")
+ prop_with_search(self.layout, pprops, "export_schema")
row = self.layout.row()
row.prop(context.scene.unit_settings, "system")
row = self.layout.row()
@@ -180,8 +177,7 @@ class BIM_PT_project(Panel):
row.prop(props, "area_unit", text="Area Unit")
row = self.layout.row()
row.prop(props, "volume_unit", text="Volume Unit")
- row = self.layout.row()
- row.prop(pprops, "template_file", text="Template")
+ prop_with_search(self.layout, pprops, "template_file", text="Template")
row = self.layout.row(align=True)
row.operator("bim.create_project")
diff --git a/src/blenderbim/blenderbim/bim/module/pset/operator.py b/src/blenderbim/blenderbim/bim/module/pset/operator.py
index 1829ebee78..72d03570ad 100644
--- a/src/blenderbim/blenderbim/bim/module/pset/operator.py
+++ b/src/blenderbim/blenderbim/bim/module/pset/operator.py
@@ -412,7 +412,7 @@ class BIM_OT_add_property_to_edit(bpy.types.Operator):
bl_idname = "bim.add_property_to_edit"
bl_options = {"REGISTER", "UNDO"}
option: bpy.props.StringProperty()
- index: bpy.props.IntProperty()
+ index: bpy.props.IntProperty(default=-1)
def execute(self, context):
if self.index == -1:
diff --git a/src/blenderbim/blenderbim/bim/module/pset/prop.py b/src/blenderbim/blenderbim/bim/module/pset/prop.py
index 14fedf0f33..9510329013 100644
--- a/src/blenderbim/blenderbim/bim/module/pset/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/pset/prop.py
@@ -18,7 +18,7 @@
import bpy
import blenderbim.bim.schema
-from blenderbim.bim.prop import Attribute
+from blenderbim.bim.prop import Attribute, StrProperty
import ifcopenshell
from ifcopenshell.api.pset.data import Data
from blenderbim.bim.module.pset.data import AddEditCustomPropertiesData
@@ -47,7 +47,7 @@ def purge():
qtonames = {}
-def getPsetNames(self, context):
+def get_pset_names(self, context):
global psetnames
obj = context.active_object
if not obj.BIMObjectProperties.ifc_definition_id:
@@ -122,7 +122,7 @@ def getWorkSchedulePsetNames(self, context):
return psetnames[ifc_class]
-def getQtoNames(self, context):
+def get_qto_names(self, context):
global qtonames
if "/" in context.active_object.name:
ifc_class = context.active_object.name.split("/")[0]
@@ -145,22 +145,27 @@ class EnumerationValues(PropertyGroup):
int_value: IntProperty(name="Value")
float_value: FloatProperty(name="Value")
is_selected: BoolProperty(default=False)
-
-
+
+
class IfcSimpleProperty(Attribute):
- #bounded_values:
+ # bounded_values:
enumerated_values: CollectionProperty(type=EnumerationValues)
- #list_values:
- #reference_values:
- #table_values:
-
-
+ # list_values:
+ # reference_values:
+ # table_values:
+
+
class PsetProperties(PropertyGroup):
active_pset_id: IntProperty(name="Active Pset ID")
active_pset_name: StringProperty(name="Pset Name")
properties: CollectionProperty(name="Properties", type=IfcSimpleProperty)
- pset_name: EnumProperty(items=getPsetNames, name="Pset Name")
- qto_name: EnumProperty(items=getQtoNames, name="Qto Name")
+ pset_name: EnumProperty(items=get_pset_names, name="Pset Name")
+ qto_name: EnumProperty(items=get_qto_names, name="Qto Name")
+
+ getter_enum = {
+ "qto_name": get_qto_names,
+ "pset_name": get_pset_names,
+ }
class MaterialPsetProperties(PropertyGroup):
@@ -215,13 +220,21 @@ class AddEditProperties(PropertyGroup):
primary_measure_type: EnumProperty(items=get_primary_measure_type, name="Primary Measure Type")
template_type: EnumProperty(
items=[
- ("IfcPropertySingleValue","IfcPropertySingleValue","IfcPropertySingleValue"),
- ("IfcPropertyEnumeratedValue","IfcPropertyEnumeratedValue","IfcPropertyEnumeratedValue")
+ ("IfcPropertySingleValue", "IfcPropertySingleValue", "IfcPropertySingleValue"),
+ ("IfcPropertyEnumeratedValue", "IfcPropertyEnumeratedValue", "IfcPropertyEnumeratedValue"),
],
- name="Template Type"
+ name="Template Type",
)
enum_values: CollectionProperty(name="Enum Values", type=EnumerationValues)
+ getter_enum = {
+ "primary_measure_type": get_primary_measure_type,
+ "template_type": lambda self, context: [
+ ("IfcPropertySingleValue", "IfcPropertySingleValue", "IfcPropertySingleValue"),
+ ("IfcPropertyEnumeratedValue", "IfcPropertyEnumeratedValue", "IfcPropertyEnumeratedValue"),
+ ],
+ }
+
def get_value_name(self):
ifc_data_type = IfcStore.get_schema().declaration_by_name(self.primary_measure_type)
data_type = ifcopenshell.util.attribute.get_primitive_type(ifc_data_type)
diff --git a/src/blenderbim/blenderbim/bim/module/pset/ui.py b/src/blenderbim/blenderbim/bim/module/pset/ui.py
index 25adeb2156..ebc421420c 100644
--- a/src/blenderbim/blenderbim/bim/module/pset/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/pset/ui.py
@@ -18,6 +18,7 @@
from bpy.types import Panel
from blenderbim.bim.ifc import IfcStore
+from blenderbim.bim.ui import prop_with_search
from blenderbim.bim.helper import draw_attribute
from blenderbim.bim.module.pset.data import (
ObjectPsetsData,
@@ -95,7 +96,7 @@ def draw_psetqto_ui(context, pset_id, pset, props, layout, obj_type):
def draw_psetqto_editable_ui(box, props, prop):
row = box.row(align=True)
- draw_attribute(box, prop, row, copy_operator="bim.copy_property_to_selection")
+ draw_attribute(prop, row, copy_operator="bim.copy_property_to_selection")
if (
"length" in prop.name.lower()
or "width" in prop.name.lower()
@@ -138,7 +139,7 @@ class BIM_PT_object_psets(Panel):
props = context.active_object.PsetProperties
row = self.layout.row(align=True)
- row.prop(props, "pset_name", text="")
+ prop_with_search(row, props, "pset_name", text="")
op = row.operator("bim.add_pset", icon="ADD", text="")
op.obj = context.active_object.name
op.obj_type = "Object"
@@ -177,7 +178,7 @@ class BIM_PT_object_qtos(Panel):
props = context.active_object.PsetProperties
row = self.layout.row(align=True)
- row.prop(props, "qto_name", text="")
+ prop_with_search(row, props, "qto_name", text="")
op = row.operator("bim.add_qto", icon="ADD", text="")
op.obj = context.active_object.name
op.obj_type = "Object"
@@ -450,12 +451,12 @@ class BIM_PT_add_edit_custom_properties(Panel):
row.prop(prop, "property_name", text="")
if prop.template_type == "IfcPropertySingleValue":
row.prop(prop, prop.get_value_name(), text="")
- row.prop(prop, "primary_measure_type", text="")
- row.prop(prop, "template_type", text="")
+ prop_with_search(row, prop, "primary_measure_type", text="")
+ prop_with_search(row, prop, "template_type", text="")
op = row.operator("bim.remove_property_to_edit", icon="X", text="")
op.index = index
op.option = "AddEditProperties"
-
+
if prop.template_type == "IfcPropertyEnumeratedValue":
op = row.operator("bim.add_property_to_edit", icon="ADD", text="Add Enum")
op.option = "AddEditProperties"
@@ -494,7 +495,7 @@ class BIM_PT_delete_psets(Panel):
row = layout.row()
op = row.operator("bim.add_property_to_edit", icon="ADD")
op.option = "DeletePsets"
-
+
if props:
for index, prop in enumerate(props):
row = layout.row(align=True)
diff --git a/src/blenderbim/blenderbim/bim/module/pset_template/__init__.py b/src/blenderbim/blenderbim/bim/module/pset_template/__init__.py
index e4e5591da4..1f822620da 100644
--- a/src/blenderbim/blenderbim/bim/module/pset_template/__init__.py
+++ b/src/blenderbim/blenderbim/bim/module/pset_template/__init__.py
@@ -20,6 +20,8 @@ import bpy
from . import ui, prop, operator
classes = (
+ operator.RefreshPsetTemplates,
+ operator.AddPsetFile,
operator.SavePsetTemplateFile,
operator.AddPsetTemplate,
operator.EditPsetTemplate,
@@ -30,8 +32,11 @@ classes = (
operator.EnableEditingPsetTemplate,
operator.DisableEditingPsetTemplate,
operator.EnableEditingPropTemplate,
+ operator.DeletePropEnum,
+ operator.AddPropEnum,
operator.DisableEditingPropTemplate,
prop.PsetTemplate,
+ prop.EnumerationValues,
prop.PropTemplate,
prop.BIMPsetTemplateProperties,
ui.BIM_PT_pset_template,
diff --git a/src/blenderbim/blenderbim/bim/module/pset_template/operator.py b/src/blenderbim/blenderbim/bim/module/pset_template/operator.py
index 8699f6d327..9013a6901f 100644
--- a/src/blenderbim/blenderbim/bim/module/pset_template/operator.py
+++ b/src/blenderbim/blenderbim/bim/module/pset_template/operator.py
@@ -16,16 +16,66 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see .
+import os
import bpy
import ifcopenshell
import ifcopenshell.api
import blenderbim.bim.schema
import blenderbim.bim.handler
-from blenderbim.bim.module.pset_template.prop import updatePsetTemplateFiles, updatePsetTemplates, getPsetTemplates
+from blenderbim.bim.module.pset_template.prop import purge as purge_templates, updatePsetTemplates, getPsetTemplates
+from blenderbim.bim.module.pset.prop import purge as purge_psets
from ifcopenshell.api.pset_template.data import Data
from blenderbim.bim.ifc import IfcStore
+#This is just a temporary operator until
+#@Moult performs some of his refactor-magic ;) - vulevukusej
+class RefreshPsetTemplates(bpy.types.Operator):
+ bl_idname = "bim.refresh_psettemplates"
+ bl_label = "Refresh the data for PsetTemplates"
+ bl_options = {"REGISTER", "UNDO"}
+
+ def execute(self, context):
+ purge_templates()
+ purge_psets()
+ return {"FINISHED"}
+
+
+class AddPsetFile(bpy.types.Operator):
+ bl_idname = "bim.add_pset_file"
+ bl_label = "Add Pset File"
+ bl_options = {"REGISTER", "UNDO"}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_props_dialog(self, width=250)
+
+ def draw(self, context):
+ self.props = context.scene.BIMPsetTemplateProperties
+ self.layout.prop(self.props, "new_template_filename", text="Filename:")
+
+ def execute(self, context):
+ template = ifcopenshell.file()
+ filepath = os.path.join(
+ context.scene.BIMProperties.data_dir,
+ "pset",
+ self.props.new_template_filename + ".ifc",
+ )
+
+ template.create_entity(
+ "IFCPROPERTYSETTEMPLATE",
+ **{
+ "GlobalId": ifcopenshell.guid.new(),
+ "Name": "Name",
+ "Description": "Description",
+ "TemplateType": "PSET_TYPEDRIVENONLY",
+ "ApplicableEntity": "IfcTypeObject"
+ }
+ )
+ template.write(filepath)
+ self.props.new_template_filename = ""
+ return {"FINISHED"}
+
+
class AddPsetTemplate(bpy.types.Operator):
bl_idname = "bim.add_pset_template"
bl_label = "Add Pset Template"
@@ -41,7 +91,6 @@ class AddPsetTemplate(bpy.types.Operator):
return result
def _execute(self, context):
- props = context.scene.BIMPsetTemplateProperties
ifcopenshell.api.run("pset_template.add_pset_template", IfcStore.pset_template_file)
Data.load(IfcStore.pset_template_file)
updatePsetTemplates(self, context)
@@ -139,6 +188,38 @@ class EnableEditingPropTemplate(bpy.types.Operator):
props.active_prop_template.name = template["Name"] or ""
props.active_prop_template.description = template["Description"] or ""
props.active_prop_template.primary_measure_type = template["PrimaryMeasureType"]
+ props.active_prop_template.template_type = template["TemplateType"]
+ props.active_prop_template.enum_values.clear()
+
+ if template["Enumerators"]:
+ props.active_prop_template.enum_values.clear()
+ data_type = props.active_prop_template.get_value_name()
+ for e in template["Enumerators"].EnumerationValues:
+ new = props.active_prop_template.enum_values.add()
+ setattr(new, data_type, e.wrappedValue)
+
+ return {"FINISHED"}
+
+class DeletePropEnum(bpy.types.Operator):
+ bl_idname = "bim.delete_prop_enum"
+ bl_label = "delete property enumeration"
+ bl_options = {"REGISTER", "UNDO"}
+ index: bpy.props.IntProperty()
+
+ def execute(self, context):
+ active_prop = context.scene.BIMPsetTemplateProperties.active_prop_template
+ active_prop.enum_values.remove(self.index)
+ return {"FINISHED"}
+
+class AddPropEnum(bpy.types.Operator):
+ bl_idname = "bim.add_prop_enum"
+ bl_label = "add property enumeration"
+ bl_options = {"REGISTER", "UNDO"}
+ index: bpy.props.IntProperty()
+
+ def execute(self, context):
+ active_prop = context.scene.BIMPsetTemplateProperties.active_prop_template
+ active_prop.enum_values.add()
return {"FINISHED"}
@@ -285,6 +366,10 @@ class EditPropTemplate(bpy.types.Operator):
def _execute(self, context):
props = context.scene.BIMPsetTemplateProperties
+ if props.active_prop_template.template_type == "P_ENUMERATEDVALUE":
+ enumerator = self.generate_prop_enum(props)
+ else:
+ enumerator = None
ifcopenshell.api.run(
"pset_template.edit_prop_template",
IfcStore.pset_template_file,
@@ -294,12 +379,28 @@ class EditPropTemplate(bpy.types.Operator):
"Name": props.active_prop_template.name,
"Description": props.active_prop_template.description,
"PrimaryMeasureType": props.active_prop_template.primary_measure_type,
+ "TemplateType": props.active_prop_template.template_type,
+ "Enumerators": enumerator
},
}
)
Data.load(IfcStore.pset_template_file)
bpy.ops.bim.disable_editing_prop_template()
return {"FINISHED"}
+
+ #TODO -This will need to go into the
+ # api code at some point - vulevukusej
+ def generate_prop_enum(self, props):
+ self.file = IfcStore.pset_template_file
+ data_type = props.active_prop_template.get_value_name()
+ prop = props.active_prop_template
+ prop_enum = self.file.create_entity(
+ "IFCPROPERTYENUMERATION",
+ Name=prop.name,
+ EnumerationValues=tuple(self.file.create_entity(
+ prop.primary_measure_type, ev[data_type]) for ev in prop.enum_values)
+ )
+ return prop_enum
def rollback(self, data):
IfcStore.pset_template_file.undo()
diff --git a/src/blenderbim/blenderbim/bim/module/pset_template/prop.py b/src/blenderbim/blenderbim/bim/module/pset_template/prop.py
index 0d6a46a94e..4554c229c4 100644
--- a/src/blenderbim/blenderbim/bim/module/pset_template/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/pset_template/prop.py
@@ -146,11 +146,42 @@ class PsetTemplate(PropertyGroup):
applicable_entity: StringProperty(name="Applicable Entity")
+class EnumerationValues(PropertyGroup):
+ string_value: StringProperty(name="Value")
+ bool_value: BoolProperty(name="Value")
+ int_value: IntProperty(name="Value")
+ float_value: FloatProperty(name="Value")
+
+
class PropTemplate(PropertyGroup):
global_id: StringProperty(name="Global ID")
name: StringProperty(name="Name")
description: StringProperty(name="Description")
primary_measure_type: EnumProperty(items=get_primary_measure_type, name="Primary Measure Type")
+ template_type: EnumProperty(
+ items=[
+ ("P_SINGLEVALUE","P_SINGLEVALUE",""),
+ ("P_ENUMERATEDVALUE","P_ENUMERATEDVALUE","")
+ ],
+ name="Template Type"
+ )
+ enum_values: CollectionProperty(type=EnumerationValues)
+ getter_enum = {
+ "primary_measure_type": get_primary_measure_type,
+ }
+
+
+ def get_value_name(self):
+ ifc_data_type = IfcStore.get_schema().declaration_by_name(self.primary_measure_type)
+ data_type = ifcopenshell.util.attribute.get_primitive_type(ifc_data_type)
+ if data_type == "string":
+ return "string_value"
+ elif data_type == "boolean":
+ return "bool_value"
+ elif data_type == "integer":
+ return "int_value"
+ elif data_type == "float":
+ return "float_value"
class BIMPsetTemplateProperties(PropertyGroup):
@@ -162,3 +193,9 @@ class BIMPsetTemplateProperties(PropertyGroup):
active_prop_template_id: IntProperty(name="Active Prop Template Id")
active_pset_template: PointerProperty(type=PsetTemplate)
active_prop_template: PointerProperty(type=PropTemplate)
+ new_template_filename: StringProperty("New TemplateFileName")
+
+ getter_enum = {
+ "pset_template_files": getPsetTemplateFiles,
+ "pset_templates": getPsetTemplates,
+ }
diff --git a/src/blenderbim/blenderbim/bim/module/pset_template/ui.py b/src/blenderbim/blenderbim/bim/module/pset_template/ui.py
index 91f90f82d8..858f856711 100644
--- a/src/blenderbim/blenderbim/bim/module/pset_template/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/pset_template/ui.py
@@ -19,6 +19,7 @@
import bpy
from bpy.types import Panel
from blenderbim.bim.ifc import IfcStore
+from blenderbim.bim.ui import prop_with_search
from blenderbim.bim.module.pset_template.prop import (
getPsetTemplates,
)
@@ -37,15 +38,17 @@ class BIM_PT_pset_template(Panel):
def draw(self, context):
layout = self.layout
props = context.scene.BIMPsetTemplateProperties
-
+
row = layout.row(align=True)
- row.prop(props, "pset_template_files", text="")
+ prop_with_search(row, props, "pset_template_files", text="")
row.operator("bim.save_pset_template_file", text="", icon="EXPORT")
-
+ row.operator("bim.add_pset_file",icon="ADD",text="")
+ row.operator("bim.refresh_psettemplates", icon="FILE_REFRESH", text="")
+
row = layout.row(align=True)
if bool(getPsetTemplates(props, context)):
- row.prop(props, "pset_templates", text="", icon="COPY_ID")
+ prop_with_search(row, props, "pset_templates", text="", icon="COPY_ID")
else:
row.label(text="No Pset Templates", icon="COPY_ID")
@@ -73,7 +76,7 @@ class BIM_PT_pset_template(Panel):
row.prop(props.active_pset_template, "template_type")
row = layout.row()
row.prop(props.active_pset_template, "applicable_entity")
- else:
+ else:
pset_template = Data.pset_templates[int(props.pset_templates)]
for name, value in pset_template.items():
if name == "id" or name == "type" or name == "HasPropertyTemplates":
@@ -85,6 +88,9 @@ class BIM_PT_pset_template(Panel):
row = layout.row(align=True)
row.label(text="Property Templates", icon="COPY_ID")
row.operator("bim.add_prop_template", icon="ADD", text="")
+
+ row = layout.row()
+ row.label(text="Name | Description | PrimaryMeasureType | TemplateType")
for prop_template_id in pset_template["HasPropertyTemplates"]:
prop_template = Data.prop_templates[prop_template_id]
@@ -93,11 +99,33 @@ class BIM_PT_pset_template(Panel):
if props.active_prop_template_id and props.active_prop_template_id == prop_template_id:
row.prop(props.active_prop_template, "name", text="")
row.prop(props.active_prop_template, "description", text="")
- row.prop(props.active_prop_template, "primary_measure_type", text="")
+ prop_with_search(row, props.active_prop_template, "primary_measure_type", text="")
+ row.prop(props.active_prop_template, "template_type", text="")
+
+ if props.active_prop_template.template_type == "P_ENUMERATEDVALUE":
+ row = layout.row(align=True)
+ split = row.split(factor=0.2)
+ c=split.column()
+ c.label(text="Enumerations:",)
+
+ c=split.column()
+ box = c.box()
+ grid = box.column_flow(columns=4)
+ value_name = props.active_prop_template.get_value_name()
+ r = grid.row()
+ r.operator("bim.add_prop_enum", text="Add Enum")
+ for k,v in enumerate(props.active_prop_template.enum_values):
+ r = grid.row(align=True)
+ r.prop(v, value_name, text="")
+ op = r.operator("bim.delete_prop_enum", icon="X", text="")
+ op.index = k
+
+
else:
row.label(text=prop_template["Name"])
row.label(text=prop_template["Description"])
row.label(text=prop_template["PrimaryMeasureType"])
+ row.label(text=prop_template["TemplateType"])
if props.active_prop_template_id and props.active_prop_template_id == prop_template_id:
op = row.operator("bim.edit_prop_template", icon="CHECKMARK", text="")
diff --git a/src/blenderbim/blenderbim/bim/module/root/__init__.py b/src/blenderbim/blenderbim/bim/module/root/__init__.py
index 00a36e0817..523f3b77cd 100644
--- a/src/blenderbim/blenderbim/bim/module/root/__init__.py
+++ b/src/blenderbim/blenderbim/bim/module/root/__init__.py
@@ -26,6 +26,7 @@ classes = (
operator.EnableReassignClass,
operator.ReassignClass,
operator.UnlinkObject,
+ operator.BIM_OT_enum_property_search,
prop.BIMRootProperties,
ui.BIM_PT_class,
)
diff --git a/src/blenderbim/blenderbim/bim/module/root/operator.py b/src/blenderbim/blenderbim/bim/module/root/operator.py
index e64b2e5920..ee57c74f0f 100644
--- a/src/blenderbim/blenderbim/bim/module/root/operator.py
+++ b/src/blenderbim/blenderbim/bim/module/root/operator.py
@@ -32,6 +32,7 @@ import blenderbim.tool as tool
from ifcopenshell.api.void.data import Data as VoidData
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.root.prop import get_contexts
+from blenderbim.bim.prop import StrProperty
class Operator:
@@ -189,3 +190,27 @@ class CopyClass(bpy.types.Operator, Operator):
for obj in objects:
core.copy_class(tool.Ifc, tool.Collector, tool.Geometry, tool.Root, obj=obj)
blenderbim.bim.handler.purge_module_data()
+
+
+class BIM_OT_enum_property_search(bpy.types.Operator):
+ bl_idname = "bim.enum_property_search"
+ bl_label = "Search For Property"
+ bl_options = {"REGISTER", "UNDO"}
+ prop_name: bpy.props.StringProperty()
+ collection: bpy.props.CollectionProperty(type=StrProperty)
+
+ def invoke(self, context, event):
+ self.data = context.data
+ getter = self.data.getter_enum.get(self.prop_name, None)
+ if getter is None:
+ return {"FINISHED"}
+ self.collection.clear()
+ for item in getter(self.data, context):
+ self.collection.add().name = item[0]
+ return context.window_manager.invoke_props_dialog(self)
+
+ def execute(self, context):
+ return {"FINISHED"}
+
+ def draw(self, context):
+ self.layout.prop_search(self.data, self.prop_name, self, "collection")
diff --git a/src/blenderbim/blenderbim/bim/module/root/prop.py b/src/blenderbim/blenderbim/bim/module/root/prop.py
index 8b598a2338..8e3fbeca94 100644
--- a/src/blenderbim/blenderbim/bim/module/root/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/root/prop.py
@@ -21,6 +21,7 @@ import ifcopenshell
import ifcopenshell.util.schema
from blenderbim.bim.module.root.data import IfcClassData
from blenderbim.bim.ifc import IfcStore
+from blenderbim.bim.prop import StrProperty
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
@@ -34,11 +35,14 @@ from bpy.props import (
)
types_enum = []
+classes_enum = []
def purge():
global types_enum
types_enum = []
+ global classes_enum
+ classes_enum = []
def getIfcPredefinedTypes(self, context):
@@ -69,6 +73,10 @@ def refreshPredefinedTypes(self, context):
context.scene.BIMRootProperties.ifc_predefined_type = enum[0][0]
+def update_class_enum(self, context):
+ self.ifc_class = self.ifc_class_filter_enum
+
+
def get_ifc_products(self, context):
if not IfcClassData.is_loaded:
IfcClassData.load()
@@ -93,3 +101,10 @@ class BIMRootProperties(PropertyGroup):
ifc_class: EnumProperty(items=get_ifc_classes, name="Class", update=refreshPredefinedTypes)
ifc_predefined_type: EnumProperty(items=getIfcPredefinedTypes, name="Predefined Type", default=None)
ifc_userdefined_type: StringProperty(name="Userdefined Type")
+
+ getter_enum = {
+ "contexts": get_contexts,
+ "ifc_product": get_ifc_products,
+ "ifc_class": get_ifc_classes,
+ "ifc_predefined_type": getIfcPredefinedTypes,
+ }
diff --git a/src/blenderbim/blenderbim/bim/module/root/ui.py b/src/blenderbim/blenderbim/bim/module/root/ui.py
index 369f0b50e8..b6a5f99268 100644
--- a/src/blenderbim/blenderbim/bim/module/root/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/root/ui.py
@@ -20,6 +20,7 @@ import bpy
import blenderbim.bim.module.root.prop as root_prop
from bpy.types import Panel
from blenderbim.bim.ifc import IfcStore
+from blenderbim.bim.ui import prop_with_search
from blenderbim.bim.module.root.data import IfcClassData
@@ -76,17 +77,14 @@ class BIM_PT_class(Panel):
def draw_class_dropdowns(self, context, ifc_predefined_types, is_reassigning_class=False):
props = context.scene.BIMRootProperties
+ layout = self.layout
if not is_reassigning_class:
- row = self.layout.row()
- row.prop(props, "ifc_product")
- row = self.layout.row()
- row.prop(props, "ifc_class")
+ prop_with_search(layout, props, "ifc_product")
+ prop_with_search(layout, props, "ifc_class")
if ifc_predefined_types:
- row = self.layout.row()
- row.prop(props, "ifc_predefined_type")
- if ifc_predefined_types == "USERDEFINED":
- row = self.layout.row()
- row.prop(props, "ifc_userdefined_type")
+ prop_with_search(layout, props, "ifc_predefined_type")
+ if props.ifc_predefined_type == "USERDEFINED":
+ row = layout.row()
+ row.prop(props, "ifc_userdefined_type")
if not is_reassigning_class:
- row = self.layout.row()
- row.prop(context.scene.BIMRootProperties, "contexts")
+ prop_with_search(layout, props, "contexts")
diff --git a/src/blenderbim/blenderbim/bim/module/unit/prop.py b/src/blenderbim/blenderbim/bim/module/unit/prop.py
index 22ef9c7a0e..f631ac1b69 100644
--- a/src/blenderbim/blenderbim/bim/module/unit/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/unit/prop.py
@@ -68,3 +68,9 @@ class BIMUnitProperties(PropertyGroup):
conversion_unit_types: EnumProperty(items=get_conversion_unit_types, name="Conversion Unit Types")
named_unit_types: EnumProperty(items=get_named_unit_types, name="Named Unit Types")
unit_attributes: CollectionProperty(name="Unit Attributes", type=Attribute)
+
+ getter_enum = {
+ "unit_classes": get_unit_classes,
+ "conversion_unit_types": get_conversion_unit_types,
+ "named_unit_types": get_named_unit_types,
+ }
diff --git a/src/blenderbim/blenderbim/bim/module/unit/ui.py b/src/blenderbim/blenderbim/bim/module/unit/ui.py
index a6d13447f5..183ed5cbe7 100644
--- a/src/blenderbim/blenderbim/bim/module/unit/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/unit/ui.py
@@ -19,6 +19,7 @@
import blenderbim.bim.helper
from bpy.types import Panel, UIList
from blenderbim.bim.ifc import IfcStore
+from blenderbim.bim.ui import prop_with_search
from blenderbim.bim.module.unit.data import UnitsData
@@ -53,22 +54,22 @@ class BIM_PT_units(Panel):
return
row = self.layout.row(align=True)
- row.prop(self.props, "unit_classes", text="")
+ prop_with_search(row, self.props, "unit_classes", text="")
if self.props.unit_classes == "IfcMonetaryUnit":
row.operator("bim.add_monetary_unit", text="", icon="ADD")
elif self.props.unit_classes in ("IfcConversionBasedUnit", "IfcConversionBasedUnitWithOffset"):
- row.prop(self.props, "conversion_unit_types", text="")
+ prop_with_search(row, self.props, "conversion_unit_types", text="")
op = row.operator("bim.add_conversion_based_unit", text="", icon="ADD")
op.name = self.props.conversion_unit_types
elif self.props.unit_classes == "IfcDerivedUnit":
pass # TODO
elif self.props.unit_classes == "IfcSIUnit":
- row.prop(self.props, "named_unit_types", text="")
+ prop_with_search(row, self.props, "named_unit_types", text="")
op = row.operator("bim.add_si_unit", text="", icon="ADD")
op.unit_type = self.props.named_unit_types
elif self.props.unit_classes == "IfcContextDependentUnit":
- row.prop(self.props, "named_unit_types", text="")
+ prop_with_search(row, self.props, "named_unit_types", text="")
op = row.operator("bim.add_context_dependent_unit", text="", icon="ADD")
op.name = "THINGAMAJIG"
op.unit_type = self.props.named_unit_types
diff --git a/src/blenderbim/blenderbim/bim/ui.py b/src/blenderbim/blenderbim/bim/ui.py
index 2457cd99bf..e04e05d5be 100644
--- a/src/blenderbim/blenderbim/bim/ui.py
+++ b/src/blenderbim/blenderbim/bim/ui.py
@@ -170,6 +170,15 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
row.operator("bim.configure_visibility")
+def prop_with_search(layout, data, prop_name, **kwargs): # Kwargs are layout.prop arguments (text, icon, etc.)
+ row = layout.row(align=True)
+ # Magick courtesy of https://blender.stackexchange.com/a/203443/86891
+ row.context_pointer_set(name="data", data=data)
+ row.prop(data, prop_name, **kwargs)
+ op = row.operator("bim.enum_property_search", text="", icon="VIEWZOOM")
+ op.prop_name = prop_name
+
+
def ifc_units(self, context):
scene = context.scene
props = scene.BIMProperties
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py
index d6b234071d..28c307756c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py
@@ -102,9 +102,11 @@ class Usecase:
if value is None:
continue
if isinstance(value, ifcopenshell.entity_instance):
- nominal_value = value
if value.is_a(True) == "IFC4.IfcPropertyEnumeratedValue":
properties.append(value)
+ continue
+ else:
+ nominal_value = value
#TODO-The following "elif" is temporary code, will need to refactor at some point - vulevukusej
elif isinstance(value, list):
for pset_template in self.settings["pset_template"].HasPropertyTemplates:
@@ -122,17 +124,18 @@ class Usecase:
EnumerationReference=prop_enum
)
properties.append(prop_enum_value)
+ continue
else:
primary_measure_type = self.get_primary_measure_type(name, new_value=value)
value = self.cast_value_to_primary_measure_type(value, primary_measure_type)
nominal_value = self.file.create_entity(primary_measure_type, value)
- properties.append(
- self.file.create_entity(
- "IfcPropertySingleValue",
- **{"Name": name, "NominalValue": nominal_value},
- )
+ properties.append(
+ self.file.create_entity(
+ "IfcPropertySingleValue",
+ **{"Name": name, "NominalValue": nominal_value},
)
+ )
return properties
def extend_pset_with_new_properties(self, new_properties):
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset_template/add_prop_template.py b/src/ifcopenshell-python/ifcopenshell/api/pset_template/add_prop_template.py
index 3c3d9cc334..10061e2ec3 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset_template/add_prop_template.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset_template/add_prop_template.py
@@ -35,6 +35,7 @@ class Usecase:
"PrimaryMeasureType": "IfcLabel",
"TemplateType": "P_SINGLEVALUE",
"AccessState": "READWRITE",
+ "Enumerators": None
}
)
has_property_templates = list(self.settings["pset_template"].HasPropertyTemplates or [])
diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset_template/data.py b/src/ifcopenshell-python/ifcopenshell/api/pset_template/data.py
index 2a1adda379..71b255cc41 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/pset_template/data.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/pset_template/data.py
@@ -49,5 +49,7 @@ class Data:
"Name": data["Name"],
"Description": data["Description"],
"PrimaryMeasureType": data["PrimaryMeasureType"],
+ "TemplateType": data["TemplateType"],
+ "Enumerators": data["Enumerators"]
}
cls.is_loaded = True