Material psets now include category-specific psets and docstrings

Previously it was not possible to get concrete / steel material psets. Yikes!
This commit is contained in:
Dion Moult
2024-05-26 11:23:08 +10:00
parent b9b0e81d25
commit 9a59b8cdae
4 changed files with 38 additions and 17 deletions
@@ -61,6 +61,15 @@ class Data:
)
return sorted(results, key=lambda v: v["Name"])
@classmethod
def format_pset_enum(cls, psets):
enum_items = []
version = tool.Ifc.get_schema()
for pset in psets:
doc = ifcopenshell.util.doc.get_property_set_doc(version, pset.Name) or {}
enum_items.append((pset.Name, pset.Name, doc.get("description", "")))
return enum_items
class ObjectPsetsData(Data):
data = {}
@@ -114,15 +123,6 @@ class ObjectPsetsData(Data):
)
return cls.format_pset_enum(qtos)
@classmethod
def format_pset_enum(cls, psets):
enum_items = []
version = tool.Ifc.get_schema()
for pset in psets:
doc = ifcopenshell.util.doc.get_property_set_doc(version, pset.Name) or {}
enum_items.append((pset.Name, pset.Name, doc.get("description", "")))
return enum_items
class ObjectQtosData(Data):
data = {}
@@ -165,9 +165,26 @@ class MaterialPsetsData(Data):
cls.data = {
"ifc_definition_id": ifc_definition_id,
"psets": cls.psetqtos(tool.Ifc.get().by_id(ifc_definition_id)),
"pset_name": cls.pset_name(),
}
cls.is_loaded = True
@classmethod
def pset_name(cls):
props = bpy.context.scene.BIMMaterialProperties
if props.materials and props.active_material_index < len(props.materials):
material = props.materials[props.active_material_index]
if material.ifc_definition_id:
material = tool.Ifc.get().by_id(material.ifc_definition_id)
category = getattr(material, "Category", None) or None
psets = blenderbim.bim.schema.ifc.psetqto.get_applicable("IfcMaterial", category, pset_only=True)
psetnames = cls.format_pset_enum(psets)
assigned_names = ifcopenshell.util.element.get_psets(
material, psets_only=True, should_inherit=False
).keys()
return [p for p in psetnames if p[0] not in assigned_names]
return []
class MaterialSetPsetsData(Data):
data = {}
@@ -23,7 +23,7 @@ import ifcopenshell.util.attribute
import ifcopenshell.util.element
import blenderbim.tool as tool
from blenderbim.bim.prop import Attribute, StrProperty
from blenderbim.bim.module.pset.data import AddEditCustomPropertiesData, ObjectPsetsData
from blenderbim.bim.module.pset.data import AddEditCustomPropertiesData, ObjectPsetsData, MaterialPsetsData
from blenderbim.bim.ifc import IfcStore
from bpy.types import PropertyGroup
from bpy.props import (
@@ -89,12 +89,9 @@ def get_object_pset_name(self, context):
def get_material_pset_names(self, context):
global psetnames
ifc_class = "IfcMaterial"
if ifc_class not in psetnames:
psets = blenderbim.bim.schema.ifc.psetqto.get_applicable(ifc_class, pset_only=True)
psetnames[ifc_class] = blender_formatted_enum_from_psets(psets)
return psetnames[ifc_class]
if not MaterialPsetsData.is_loaded:
MaterialPsetsData.load()
return MaterialPsetsData.data["pset_name"]
def get_material_set_pset_names(self, context):
@@ -103,7 +103,8 @@ class PsetQto:
matched_type = match.group(3)
if matched_type and not predefined_type:
continue
elif matched_type and predefined_type != match.group(3):
# Case insensitive to handle things like material categories
elif matched_type and predefined_type.lower() != match.group(3).lower():
continue
applicable_class = match.group(1)
@@ -60,3 +60,9 @@ class TestPsetQto:
names = self.pset_qto.get_applicable_names("IfcFurnitureType" )
names2 = self.pset_qto.get_applicable_names("IfcFurnitureType", "CUSTOM")
assert names == names2
def test_getting_applicables_for_a_material_category(self):
names = self.pset_qto.get_applicable_names("IfcMaterial")
assert "Pset_MaterialConcrete" not in names
names = self.pset_qto.get_applicable_names("IfcMaterial", "concrete")
assert "Pset_MaterialConcrete" in names