mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
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:
@@ -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"}
|
||||
|
||||
@@ -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,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")
|
||||
|
||||
Reference in New Issue
Block a user