mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 14:07:43 +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":
|
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"}
|
||||||
|
|||||||
@@ -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,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")
|
||||||
|
|||||||
Reference in New Issue
Block a user