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/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_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 1cb59a22ed..4554c229c4 100644 --- a/src/blenderbim/blenderbim/bim/module/pset_template/prop.py +++ b/src/blenderbim/blenderbim/bim/module/pset_template/prop.py @@ -146,16 +146,43 @@ 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): pset_template_files: EnumProperty( @@ -166,7 +193,8 @@ 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 058f4e9b59..858f856711 100644 --- a/src/blenderbim/blenderbim/bim/module/pset_template/ui.py +++ b/src/blenderbim/blenderbim/bim/module/pset_template/ui.py @@ -38,11 +38,13 @@ class BIM_PT_pset_template(Panel): def draw(self, context): layout = self.layout props = context.scene.BIMPsetTemplateProperties - + row = layout.row(align=True) 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)): @@ -74,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": @@ -86,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] @@ -95,10 +100,32 @@ class BIM_PT_pset_template(Panel): row.prop(props.active_prop_template, "name", text="") row.prop(props.active_prop_template, "description", 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/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