Fix #4086. Add support for non predefined bSDD pset and qto values.

This commit is contained in:
Dion Moult
2023-12-08 15:07:46 +11:00
parent e469886cdd
commit e40336be2a
5 changed files with 60 additions and 18 deletions
@@ -34,10 +34,10 @@ class LoadBSDDDomains(bpy.types.Operator):
props.domains.clear()
client = bsdd.Client()
if props.load_activated_domains:
domains = [d for d in client.Domain() if d["status"] == "Active"]
else:
if props.load_preview_domains:
domains = client.Domain()
else:
domains = [d for d in client.Domain() if d["status"] == "Active"]
for domain in sorted(domains, key=lambda x: x["name"]):
new = props.domains.add()
@@ -125,14 +125,23 @@ class GetBSDDClassificationProperties(bpy.types.Operator):
possible_values = prop.get("possibleValues", []) or []
possible_values = [v["value"] for v in possible_values]
psets[pset][prop["name"]] = possible_values
psets[pset][prop["name"]] = {"data_type": prop["dataType"], "possible_values": possible_values}
data_type_map = {
"String": "string",
"Real": "float",
"Boolean": "boolean",
}
for pset_name, pset in psets.items():
new = bprops.classification_psets.add()
new.name = pset_name
for name, values in pset.items():
for name, data in pset.items():
new2 = new.properties.add()
new2.name = name
new2.enum_items = json.dumps(values)
new2.data_type = "enum"
if data["possible_values"]:
new2.enum_items = json.dumps(data["possible_values"])
new2.data_type = "enum"
else:
new2.data_type = data_type_map[data["data_type"]]
return {"FINISHED"}
@@ -63,5 +63,5 @@ 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)
load_activated_domains: BoolProperty(name="Load Activated Domains Only", default=True)
load_preview_domains: BoolProperty(name="Load Preview Domains", default=False)
classification_psets: CollectionProperty(name="Classification Psets", type=BSDDPset)
@@ -32,8 +32,10 @@ class BIM_PT_bsdd(Panel):
def draw(self, context):
props = context.scene.BIMBSDDProperties
row = self.layout.row()
row.prop(props, "load_activated_domains")
row = self.layout.row(align=True)
row.prop(props, "load_preview_domains")
if len(props.domains):
row.operator("bim.load_bsdd_domains", text="", icon="FILE_REFRESH")
if props.active_domain:
row = self.layout.row()
@@ -51,8 +53,6 @@ class BIM_PT_bsdd(Panel):
props,
"active_domain_index",
)
row = self.layout.row()
row.operator("bim.load_bsdd_domains", text="Reload bSDD Domains")
else:
row = self.layout.row()
row.operator("bim.load_bsdd_domains")
@@ -62,8 +62,10 @@ class BIM_UL_bsdd_domains(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item:
row = layout.row(align=True)
row.label(text=f"{item.name} ({item.organization_name_owner})")
row.label(text=item.status)
if item.status != "Active":
row.label(text=f"{item.name} ({item.organization_name_owner}) - {item.status}", icon="ERROR")
else:
row.label(text=f"{item.name} ({item.organization_name_owner})")
op = row.operator("bim.set_active_bsdd_domain", text="", icon="RESTRICT_SELECT_OFF")
op.name = item.name
op.uri = item.namespace_uri
@@ -324,17 +324,32 @@ class AddClassificationReferenceFromBSDD(bpy.types.Operator, tool.Ifc.Operator):
reference.Location = bsdd_classification.namespace_uri
for classification_pset in bprops.classification_psets:
pset = ifcopenshell.util.element.get_pset(element, classification_pset.name)
is_pset = not classification_pset.name.startswith("Qto_")
if is_pset:
pset = ifcopenshell.util.element.get_pset(element, classification_pset.name, psets_only=True)
else:
pset = ifcopenshell.util.element.get_pset(element, classification_pset.name, qtos_only=True)
if pset:
pset = tool.Ifc.get().by_id(pset["id"])
else:
elif is_pset:
pset = ifcopenshell.api.run(
"pset.add_pset", tool.Ifc.get(), product=element, name=classification_pset.name
)
else:
pset = ifcopenshell.api.run(
"pset.add_qto", 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)
if is_pset:
ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties=properties)
else:
ifcopenshell.api.run("pset.edit_qto", tool.Ifc.get(), qto=pset, properties=properties)
class ChangeClassificationLevel(bpy.types.Operator):
@@ -19,7 +19,7 @@
import ifcopenshell
def get_pset(element, name, prop=None, should_inherit=True, verbose=False):
def get_pset(element, name, prop=None, psets_only=False, qtos_only=False, should_inherit=True, verbose=False):
"""Retrieve a single property set or single property
This is more efficient than ifcopenshell.util.element.get_psets if you know
@@ -34,6 +34,10 @@ def get_pset(element, name, prop=None, should_inherit=True, verbose=False):
:type name: str
:param prop: The name of the property
:type prop: str,optional
:param psets_only: Default as False. Set to true if only property sets are needed.
:type psets_only: bool,optional
:param qtos_only: Default as False. Set to true if only quantities are needed.
:type qtos_only: bool,optional
:param should_inherit: Default as True. Set to false if you don't want to inherit property sets from the Type.
:type should_inherit: bool,optional
:return: A dictionary of property names and values, or a single value if a
@@ -72,6 +76,18 @@ def get_pset(element, name, prop=None, should_inherit=True, verbose=False):
pset = definition
break
if pset:
if psets_only and not pset.is_a("IfcPropertySet"):
pset = None
elif qtos_only and not pset.is_a("IfcElementQuantity"):
pset = None
if type_pset:
if psets_only and not type_pset.is_a("IfcPropertySet"):
type_pset = None
elif qtos_only and not type_pset.is_a("IfcElementQuantity"):
type_pset = None
if not pset and not type_pset:
return