Purge unused materials to consider materials with styles and psets #3914

If material has a style or a pset it creates an inverse that shouldn't prevent material from being purged.
This commit is contained in:
Andrej730
2024-09-13 12:45:04 +05:00
parent c41a4607d1
commit 4d149e8a78
3 changed files with 48 additions and 6 deletions
@@ -632,14 +632,11 @@ class PurgeUnusedObjects(bpy.types.Operator, tool.Ifc.Operator):
elif object_type == "PROFILE": elif object_type == "PROFILE":
purged = bonsai.core.profile.purge_unused_profiles(tool.Ifc, tool.Profile) purged = bonsai.core.profile.purge_unused_profiles(tool.Ifc, tool.Profile)
elif object_type == "STYLE": elif object_type == "STYLE":
# It's okay to remove IfcPresentationStyle if just remove_deep
# as there are no white listed inverses.
purged = tool.Debug.purge_unused_class("IfcPresentationStyle") purged = tool.Debug.purge_unused_class("IfcPresentationStyle")
elif object_type == "MATERIAL": elif object_type == "MATERIAL":
ifc_file = tool.Ifc.get() purged = tool.Material.purge_unused_materials()
is_ifc2x3 = ifc_file.schema == "IFC2X3"
if is_ifc2x3:
purged = tool.Debug.purge_unused_class("IfcMaterial")
else:
purged = tool.Debug.purge_unused_class("IfcMaterialDefinition")
else: else:
self.report({"ERROR"}, f"Invalid object type {object_type}.") self.report({"ERROR"}, f"Invalid object type {object_type}.")
return {"CANCELLED"} return {"CANCELLED"}
+26
View File
@@ -388,3 +388,29 @@ class Material(bonsai.core.tool.Material):
material.Materials = [default_material] material.Materials = [default_material]
else: else:
assert False, f"Invalid material type found: {material_type}." assert False, f"Invalid material type found: {material_type}."
@classmethod
def purge_unused_materials(cls) -> int:
ifc_file = tool.Ifc.get()
is_ifc2x3 = ifc_file.schema == "IFC2X3"
ifc_class = "IfcMaterial" if is_ifc2x3 else "IfcMaterialDefinition"
skip_inverses = {
"IfcMaterialDefinitionRepresentation",
"IfcMaterialProperties",
}
def is_safe_to_purge(material: ifcopenshell.entity_instance) -> bool:
for i in ifc_file.get_inverse(material):
if i.is_a() not in skip_inverses:
return False
return True
materials = ifc_file.by_type(ifc_class)
i = 0
for material in materials:
if ifc_file.get_total_inverses(material) != 0 and not is_safe_to_purge(material):
continue
ifcopenshell.api.material.remove_material(ifc_file, material)
i += 1
return i
+19
View File
@@ -19,6 +19,9 @@
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.material
import ifcopenshell.api.pset
import ifcopenshell.api.style
import bonsai.core.tool import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
from test.bim.bootstrap import NewFile from test.bim.bootstrap import NewFile
@@ -183,3 +186,19 @@ class TestEnsureNewMaterialSetIsValid(NewFile):
material_set = ifc.create_entity("IfcMaterialList") material_set = ifc.create_entity("IfcMaterialList")
subject.ensure_new_material_set_is_valid(material_set) subject.ensure_new_material_set_is_valid(material_set)
assert len(material_set.Materials) == 1 assert len(material_set.Materials) == 1
class TestPurgeUnusedMaterials(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
material = ifcopenshell.api.material.add_material(ifc)
# Add pset.
ifcopenshell.api.pset.add_pset(ifc, material, "Foo")
# Add style.
style = ifcopenshell.api.style.add_style(ifc)
context = ifc.create_entity("IfcRepresentationContext")
ifcopenshell.api.style.assign_material_style(ifc, material, style, context)
assert subject.purge_unused_materials() == 1
assert not ifc.by_type("IfcMaterial")