Support editing project library attributes

Example - https://imgur.com/a/MFtLDlh
This commit is contained in:
Andrej730
2025-01-31 13:19:42 +05:00
parent 67aa8f1413
commit 9f17ec5bf5
5 changed files with 88 additions and 8 deletions
@@ -35,6 +35,7 @@ classes = (
operator.DisableCulling,
operator.DisableEditingHeader,
operator.EditHeader,
operator.EditProjectLibrary,
operator.EnableCulling,
operator.EnableEditingHeader,
operator.ExportIFC,
+7 -5
View File
@@ -132,13 +132,15 @@ class ProjectLibraryData:
return results
@classmethod
def project_libraries_enum(cls) -> list[tuple[str, str, str]]:
def project_libraries_enum(cls) -> list[tuple[str, str, str, str, int]]:
results = [
("*", "All Libraries", "Show all elements"),
("-", "No Library", "Show elements without library assigned"),
("*", "All Libraries", "Show all elements", "", 0),
("-", "No Library", "Show elements without library assigned", "", 1),
]
for data in cls.data["project_libraries"].values():
results.append((str(data["id"]), data["Name"] or "", data["Description"] or ""))
props = tool.Project.get_project_props()
for i, data in enumerate(cls.data["project_libraries"].values(), len(results)):
icon = "GREASEPENCIL" if props.editing_project_library_id == data["id"] else ""
results.append((str(data["id"]), data["Name"] or "", data["Description"] or "", icon, i))
return results
@@ -25,6 +25,7 @@ import tempfile
import traceback
import subprocess
import datetime
import ifcopenshell.api.attribute
import numpy as np
import ifcopenshell
import ifcopenshell.api
@@ -604,6 +605,40 @@ class AppendLibraryElement(bpy.types.Operator, tool.Ifc.Operator):
ifc_importer.create_style(element)
class EditProjectLibrary(bpy.types.Operator):
bl_idname = "bim.edit_project_library"
bl_label = "Edit Project Library"
bl_description = "Apply changes for currently edited library."
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(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)
props.is_editing_project_library = False
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"
+30 -1
View File
@@ -21,9 +21,10 @@ import bpy
import ifcopenshell.util.element
import ifcopenshell.util.placement
import bonsai.tool as tool
import bonsai.bim.helper
from bonsai.bim.module.project.data import ProjectData, ProjectLibraryData
from bonsai.bim.ifc import IfcStore
from bonsai.bim.prop import StrProperty, ObjProperty
from bonsai.bim.prop import StrProperty, ObjProperty, Attribute
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
@@ -88,6 +89,22 @@ def filter_by_library_update(self: "BIMProjectProperties", context: bpy.types.Co
bpy.ops.bim.refresh_library()
def is_editing_project_library_update(self: "BIMProjectProperties", context: bpy.types.Context) -> None:
if self.is_editing_project_library:
library_file = IfcStore.library_file
assert library_file
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)
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()
ProjectLibraryData.load() # Hide edit icon in enum.
def update_filter_mode(self: "BIMProjectProperties", context: bpy.types.Context) -> None:
self.filter_categories.clear()
if self.filter_mode == "NONE":
@@ -300,6 +317,15 @@ class BIMProjectProperties(PropertyGroup):
default=True,
update=filter_by_library_update,
)
is_editing_project_library: BoolProperty(
name="Is Editing Project Library",
description="Toggle editing for currently selected project library",
update=is_editing_project_library_update,
)
editing_project_library_id: IntProperty(
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)
use_relative_project_path: BoolProperty(name="Use Relative Project Path", default=False)
queried_obj: bpy.props.PointerProperty(type=bpy.types.Object)
@@ -367,6 +393,9 @@ class BIMProjectProperties(PropertyGroup):
library_file: str
selected_project_library: Union[Literal["*", "-"], str]
filter_by_library: bool
is_editing_project_library: bool
editing_project_library_id: int
project_library_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
use_relative_project_path: bool
queried_obj: Union[bpy.types.Object, None]
+15 -2
View File
@@ -21,7 +21,7 @@ import bpy
import os
import bonsai.bim
import bonsai.tool as tool
from bonsai.bim.helper import prop_with_search
from bonsai.bim.helper import prop_with_search, draw_attributes
from bpy.types import Panel, Menu, UIList
from bonsai.bim.ifc import IfcStore
from bonsai.bim.module.project.data import ProjectData, LinksData
@@ -344,7 +344,7 @@ class BIM_PT_project_library(Panel):
def draw(self, context):
self.layout.use_property_decorate = False
self.layout.use_property_split = True
self.props = context.scene.BIMProjectProperties
self.props = tool.Project.get_project_props()
row = self.layout.row(align=True)
row.prop(self.props, "library_file", text="")
if self.props.library_file == "0":
@@ -364,16 +364,29 @@ class BIM_PT_project_library(Panel):
def draw_library_ul(self):
layout = self.layout
props = self.props
if not self.props.library_elements:
row = self.layout.row()
row.label(text="No Assets Found", icon="ERROR")
return
library_is_selected = props.selected_project_library not in ("*", "-")
row = layout.row(align=True)
row.prop(self.props, "selected_project_library", text="")
if library_is_selected and not props.is_editing_project_library:
row.prop(props, "is_editing_project_library", text="", icon="GREASEPENCIL")
row.prop(self.props, "filter_by_library", text="", icon="FILTER")
if props.is_editing_project_library:
row = layout.row(align=True)
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)
layout.separator()
row = self.layout.row(align=True)
row.label(text=self.props.active_library_element or "Top Level Assets")
if self.props.active_library_element: