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":
purged = bonsai.core.profile.purge_unused_profiles(tool.Ifc, tool.Profile)
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")
elif object_type == "MATERIAL":
ifc_file = tool.Ifc.get()
is_ifc2x3 = ifc_file.schema == "IFC2X3"
if is_ifc2x3:
purged = tool.Debug.purge_unused_class("IfcMaterial")
else:
purged = tool.Debug.purge_unused_class("IfcMaterialDefinition")
purged = tool.Material.purge_unused_materials()
else:
self.report({"ERROR"}, f"Invalid object type {object_type}.")
return {"CANCELLED"}
+26
View File
@@ -388,3 +388,29 @@ class Material(bonsai.core.tool.Material):
material.Materials = [default_material]
else:
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 ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.material
import ifcopenshell.api.pset
import ifcopenshell.api.style
import bonsai.core.tool
import bonsai.tool as tool
from test.bim.bootstrap import NewFile
@@ -183,3 +186,19 @@ class TestEnsureNewMaterialSetIsValid(NewFile):
material_set = ifc.create_entity("IfcMaterialList")
subject.ensure_new_material_set_is_valid(material_set)
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")