diff --git a/src/blenderbim/blenderbim/bim/module/bsdd/__init__.py b/src/blenderbim/blenderbim/bim/module/bsdd/__init__.py index d56f214697..63f62931a6 100644 --- a/src/blenderbim/blenderbim/bim/module/bsdd/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/bsdd/__init__.py @@ -20,11 +20,13 @@ import bpy from . import ui, prop, operator classes = ( + operator.GetBSDDClassificationProperties, operator.LoadBSDDDomains, operator.SearchBSDDClassifications, operator.SetActiveBSDDDomain, prop.BSDDDomain, prop.BSDDClassification, + prop.BSDDPset, prop.BIMBSDDProperties, ui.BIM_UL_bsdd_domains, ui.BIM_UL_bsdd_classifications, diff --git a/src/blenderbim/blenderbim/bim/module/bsdd/operator.py b/src/blenderbim/blenderbim/bim/module/bsdd/operator.py index 44a009c664..f3ecba2204 100644 --- a/src/blenderbim/blenderbim/bim/module/bsdd/operator.py +++ b/src/blenderbim/blenderbim/bim/module/bsdd/operator.py @@ -19,6 +19,7 @@ import os import bpy import bsdd +import json import ifcopenshell import blenderbim.tool as tool @@ -83,3 +84,49 @@ class SearchBSDDClassifications(bpy.types.Operator): new.domain_name = result["domainName"] new.domain_namespace_uri = result["domainNamespaceUri"] return {"FINISHED"} + + +class GetBSDDClassificationProperties(bpy.types.Operator): + bl_idname = "bim.get_bsdd_classification_properties" + bl_label = "Search bSDD Classifications" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + bprops = context.scene.BIMBSDDProperties + bprops.classification_psets.clear() + bsdd_classification = bprops.classifications[bprops.active_classification_index] + client = bsdd.Client() + data = client.Classification(bsdd_classification.namespace_uri) + + properties = data.get("classificationProperties", None) + if not properties: + return {"FINISHED"} + + psets = {} + + for prop in properties: + if prop.get("propertyDomainName") != "IFC": + continue + pset = prop.get("propertySet", None) + if not pset: + continue + psets.setdefault(pset, {}) + + predefined_value = prop.get("predefinedValue") + if predefined_value: + possible_values = [predefined_value] + else: + possible_values = prop.get("possibleValues", []) or [] + possible_values = [v["value"] for v in possible_values] + + psets[pset][prop["name"]] = possible_values + + for pset_name, pset in psets.items(): + new = bprops.classification_psets.add() + new.name = pset_name + for name, values in pset.items(): + new2 = new.properties.add() + new2.name = name + new2.enum_items = json.dumps(values) + new2.data_type = "enum" + return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/bsdd/prop.py b/src/blenderbim/blenderbim/bim/module/bsdd/prop.py index 1a12b32809..cf8e3e95e1 100644 --- a/src/blenderbim/blenderbim/bim/module/bsdd/prop.py +++ b/src/blenderbim/blenderbim/bim/module/bsdd/prop.py @@ -18,6 +18,7 @@ import bpy from bpy.types import PropertyGroup +from blenderbim.bim.prop import Attribute, StrProperty from bpy.props import ( PointerProperty, StringProperty, @@ -48,6 +49,11 @@ class BSDDClassification(PropertyGroup): domain_namespace_uri: StringProperty(name="Domain Namespace URI") +class BSDDPset(PropertyGroup): + name: StringProperty(name="Name") + properties: CollectionProperty(name="Properties", type=Attribute) + + class BIMBSDDProperties(PropertyGroup): active_domain: StringProperty(name="Active Domain") active_uri: StringProperty(name="Active URI") @@ -57,3 +63,4 @@ class BIMBSDDProperties(PropertyGroup): active_classification_index: IntProperty(name="Active Classification Index") keyword: StringProperty(name="Keyword") should_filter_ifc_class: BoolProperty(name="Filter Active IFC Class", default=True) + classification_psets: CollectionProperty(name="Classification Psets", type=BSDDPset) diff --git a/src/blenderbim/blenderbim/bim/module/classification/operator.py b/src/blenderbim/blenderbim/bim/module/classification/operator.py index 9af38e5058..8ec27ad731 100644 --- a/src/blenderbim/blenderbim/bim/module/classification/operator.py +++ b/src/blenderbim/blenderbim/bim/module/classification/operator.py @@ -312,16 +312,30 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator): ifc_definition_id = blenderbim.bim.helper.get_obj_ifc_definition_id(context, obj, self.obj_type) if not ifc_definition_id: continue + element = tool.Ifc.get().by_id(ifc_definition_id) reference = ifcopenshell.api.run( "classification.add_reference", tool.Ifc.get(), - product=tool.Ifc.get().by_id(ifc_definition_id), + product=element, classification=classification, identification=bsdd_classification.reference_code, name=bsdd_classification.name, ) reference.Location = bsdd_classification.namespace_uri + for classification_pset in bprops.classification_psets: + pset = ifcopenshell.util.element.get_pset(element, classification_pset.name) + if pset: + pset = tool.Ifc.get().by_id(pset["id"]) + else: + pset = ifcopenshell.api.run( + "pset.add_pset", tool.Ifc.get(), product=element, name=classification_pset.name + ) + properties = {} + for prop in classification_pset.properties: + properties[prop.name] = prop.get_value() + ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties=properties) + class ChangeClassificationLevel(bpy.types.Operator): bl_idname = "bim.change_classification_level" diff --git a/src/blenderbim/blenderbim/bim/module/classification/ui.py b/src/blenderbim/blenderbim/bim/module/classification/ui.py index 965b215643..f63c887fdf 100644 --- a/src/blenderbim/blenderbim/bim/module/classification/ui.py +++ b/src/blenderbim/blenderbim/bim/module/classification/ui.py @@ -176,12 +176,20 @@ class ReferenceUI: row.label(text="No Search Results") if self.bprops.active_classification_index < len(self.bprops.classifications): - row = self.layout.row() + row = self.layout.row(align=True) op = row.operator( "bim.add_classification_reference_from_bsdd", text="Add Classification Reference", icon="ADD" ) op.obj = self.obj op.obj_type = self.obj_type + row.operator("bim.get_bsdd_classification_properties", text="", icon="COPY_ID") + + if len(self.bprops.classification_psets): + for pset in self.bprops.classification_psets: + box = self.layout.box() + row = box.row() + row.label(text=pset.name, icon="COPY_ID") + blenderbim.bim.helper.draw_attributes(pset.properties, box) def draw_add_file_ui(self, context): if not self.data.data["active_classification_library"]: