Change IfcProjectLibrary's parent library from UI

Example - https://imgur.com/a/4PZr0px
It's very clunky and mainly exposed just to be available in some way, it will all make more sense when we display project libraries as trees in project library ui.
This commit is contained in:
Andrej730
2025-02-04 13:31:47 +05:00
parent 56f0c19a85
commit 8f74f4d9f1
5 changed files with 55 additions and 0 deletions
@@ -118,6 +118,7 @@ class ProjectLibraryData:
cls.data["project_libraries"] = cls.project_libraries()
# After .project_libraries().
cls.data["project_libraries_enum"] = cls.project_libraries_enum()
cls.data["parent_libraries_enum"] = cls.parent_libraries_enum()
cls.is_loaded = True
@classmethod
@@ -146,6 +147,18 @@ class ProjectLibraryData:
results += libs
return results
@classmethod
def parent_libraries_enum(cls) -> list[tuple[str, str, str]]:
results: list[tuple[str, str, str]] = []
library_file = IfcStore.library_file
if library_file is None or library_file.schema == "IFC2X3":
return results
project = library_file.by_type("IfcProject")[0]
results.append((str(project.id()), f"IfcProject {project.Name or 'Unnamed'}", project.Description or ""))
for library_id, data in cls.data["project_libraries"].items():
results.append((str(library_id), data["Name"] or "Unnamed", data["Description"] or ""))
return results
class LinksData:
linked_data = {}
@@ -29,6 +29,7 @@ import ifcopenshell.api.attribute
import numpy as np
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.nest
import ifcopenshell.api.project
import ifcopenshell.api.root
import ifcopenshell.geom
@@ -631,6 +632,20 @@ class EditProjectLibrary(bpy.types.Operator):
project_library = library_file.by_id(props.editing_project_library_id)
attributes = bonsai.bim.helper.export_attributes(props.project_library_attributes)
ifcopenshell.api.attribute.edit_attributes(library_file, project_library, attributes)
# Update parent library.
previous_parent_library = tool.Project.get_parent_library(project_library)
new_parent_library = library_file.by_id(int(props.parent_library))
if previous_parent_library != new_parent_library:
if previous_parent_library.is_a("IfcProject"):
# Then new one is IfcProjectLibrary.
ifcopenshell.api.nest.assign_object(library_file, [project_library], new_parent_library)
else: # Previous is IfcProjectLibrary.
ifcopenshell.api.nest.unassign_object(library_file, [project_library])
# If new one is IfcProject, then it's already assigned by default.
if new_parent_library.is_a("IfcProjectLibrary"):
ifcopenshell.api.nest.assign_object(library_file, [project_library], new_parent_library)
props.is_editing_project_library = False
return {"FINISHED"}
@@ -98,15 +98,26 @@ def is_editing_project_library_update(self: "BIMProjectProperties", context: bpy
self.editing_project_library_id = int(self.selected_project_library)
project_library = library_file.by_id(int(self.selected_project_library))
bonsai.bim.helper.import_attributes2(project_library, self.project_library_attributes)
self.parent_library = str(tool.Project.get_parent_library(project_library).id())
ProjectLibraryData.load() # Show edit icon in enum.
return
del self["is_editing_project_library"]
del self["editing_project_library_id"]
self.project_library_attributes.clear()
del self["parent_library"]
ProjectLibraryData.load() # Hide edit icon in enum.
def get_parent_libaries(self: "BIMProjectProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
if not ProjectLibraryData.is_loaded:
ProjectLibraryData.load()
edited_library = str(self.editing_project_library_id)
# Prevent assigning library to itself.
enum_items = [i for i in ProjectLibraryData.data["parent_libraries_enum"] if i[0] != edited_library]
return enum_items
def update_filter_mode(self: "BIMProjectProperties", context: bpy.types.Context) -> None:
self.filter_categories.clear()
if self.filter_mode == "NONE":
@@ -328,6 +339,11 @@ class BIMProjectProperties(PropertyGroup):
description="Needed to keep track of currently edited library when user changes currently selected library in dropdown."
)
project_library_attributes: CollectionProperty(name="Project Library Attributes", type=Attribute)
parent_library: EnumProperty(
name="Parent Library",
description="Parent library that library is assigned to (either IfcProject or IfcProjectLibrary).",
items=get_parent_libaries,
)
use_relative_project_path: BoolProperty(name="Use Relative Project Path", default=False)
queried_obj: bpy.props.PointerProperty(type=bpy.types.Object)
@@ -398,6 +414,7 @@ class BIMProjectProperties(PropertyGroup):
is_editing_project_library: bool
editing_project_library_id: int
project_library_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
parent_library: str
use_relative_project_path: bool
queried_obj: Union[bpy.types.Object, None]
@@ -389,6 +389,8 @@ class BIM_PT_project_library(Panel):
row.operator("bim.edit_project_library", text="Save Attributes", icon="GREASEPENCIL")
row.prop(props, "is_editing_project_library", text="", icon="CANCEL")
draw_attributes(props.project_library_attributes, layout)
row = layout.row()
row.prop(props, "parent_library", text="Parent Library")
layout.separator()
if not self.props.library_elements:
+8
View File
@@ -344,3 +344,11 @@ class Project(bonsai.core.tool.Project):
element_name = props.active_library_element
bpy.ops.bim.rewind_library()
bpy.ops.bim.change_library_element(element_name=element_name)
@classmethod
def get_parent_library(cls, project_library: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
if nests := project_library.Nests:
# IfcProjectLibrary.
return nests[0].RelatingObject
# IfcProject.
return project_library.HasContext[0].RelatingContext