Remove project library from UI #7057

Example - https://files.catbox.moe/940mhn.mp4
This commit is contained in:
Andrej730
2025-08-28 17:04:21 +05:00
parent 71a6bf25bc
commit b5aeab6404
4 changed files with 80 additions and 0 deletions
@@ -55,6 +55,7 @@ classes = (
operator.RefreshClippingPlanes,
operator.RefreshLibrary,
operator.ReloadLink,
operator.RemoveProjectLibrary,
operator.RevertProject,
operator.RewindLibrary,
operator.SaveLibraryFile,
@@ -774,6 +774,45 @@ class AddProjectLibrary(bpy.types.Operator):
IfcStore.library_file.redo()
class RemoveProjectLibrary(bpy.types.Operator):
bl_idname = "bim.remove_project_library"
bl_label = "Remove Project Library"
bl_description = "Remove the currently selected IfcProjectLibrary."
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
IfcStore.begin_transaction(self)
library_file = IfcStore.library_file
assert library_file
library_file.begin_transaction()
result = self._execute(context)
library_file.end_transaction()
IfcStore.add_transaction_operation(self)
IfcStore.end_transaction(self)
return result
def _execute(self, context):
props = tool.Project.get_project_props()
library_file = IfcStore.library_file
assert library_file
project_library = library_file.by_id(int(props.selected_project_library))
tool.Project.remove_project_library(project_library)
ProjectLibraryData.load() # Update enum.
enum_len = len(ProjectLibraryData.data["project_libraries_enum"])
if props.is_property_set("selected_project_library"):
props["selected_project_library"] = min(enum_len - 1, props["selected_project_library"])
bpy.ops.bim.refresh_library()
return {"FINISHED"}
def rollback(self, data):
IfcStore.library_file.undo()
def commit(self, data):
IfcStore.library_file.redo()
class EnableEditingHeader(bpy.types.Operator):
bl_idname = "bim.enable_editing_header"
bl_label = "Enable Editing Header"
@@ -406,6 +406,7 @@ class BIM_PT_project_library(Panel):
if library_is_selected and not props.is_editing_project_library:
row.prop(props, "is_editing_project_library", text="", icon="GREASEPENCIL")
row.operator("bim.remove_project_library", text="", icon="X")
row.prop(self.props, "show_library_tree", text="", icon="OUTLINER")
+39
View File
@@ -21,6 +21,7 @@ import os
import bpy
import ifcopenshell
import ifcopenshell.api.document
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.util.unit
import bonsai.core.aggregate
@@ -398,3 +399,41 @@ class Project(bonsai.core.tool.Project):
if library_element.is_a("IfcProfileDef"):
return "ProfileName"
return "Name"
# TODO: Move to ifcopenshell.api and add tests.
@classmethod
def remove_project_library(cls, project_library: ifcopenshell.entity_instance) -> None:
ifc_file = project_library.file
roots_to_remove = {project_library}
rels_to_clean_up: set[ifcopenshell.entity_instance] = set()
queue = [project_library]
while queue:
current = queue.pop()
inverses = ifc_file.get_inverse(current)
rels_to_clean_up.update(i for i in inverses if i.is_a() in ("IfcRelNests", "IfcRelDeclares"))
children = ifcopenshell.util.element.get_components(current)
queue.extend(children)
roots_to_remove.update(children)
def remove_root(root: ifcopenshell.entity_instance) -> None:
history = root.OwnerHistory
ifc_file.remove(root)
if history:
ifcopenshell.util.element.remove_deep2(ifc_file, history)
for root in roots_to_remove:
remove_root(root)
# Clean up invalidated rels.
for rel in rels_to_clean_up:
if rel.is_a("IfcRelDeclares"):
# Project library was either assigned to Project or some types were assigned to it.
if not rel.RelatingContext or not rel.RelatedDefinitions:
remove_root(rel)
elif rel.is_a("IfcRelNests"):
# Project library was either parent or child to other project libraries.
if not rel.RelatingObject or not rel.RelatedObjects:
remove_root(rel)
else:
assert False, f"Shouldn't be here, {rel}"