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.DisableCulling,
operator.DisableEditingHeader, operator.DisableEditingHeader,
operator.EditHeader, operator.EditHeader,
operator.EditProjectLibrary,
operator.EnableCulling, operator.EnableCulling,
operator.EnableEditingHeader, operator.EnableEditingHeader,
operator.ExportIFC, operator.ExportIFC,
+7 -5
View File
@@ -132,13 +132,15 @@ class ProjectLibraryData:
return results return results
@classmethod @classmethod
def project_libraries_enum(cls) -> list[tuple[str, str, str]]: def project_libraries_enum(cls) -> list[tuple[str, str, str, str, int]]:
results = [ results = [
("*", "All Libraries", "Show all elements"), ("*", "All Libraries", "Show all elements", "", 0),
("-", "No Library", "Show elements without library assigned"), ("-", "No Library", "Show elements without library assigned", "", 1),
] ]
for data in cls.data["project_libraries"].values(): props = tool.Project.get_project_props()
results.append((str(data["id"]), data["Name"] or "", data["Description"] or "")) 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 return results
@@ -25,6 +25,7 @@ import tempfile
import traceback import traceback
import subprocess import subprocess
import datetime import datetime
import ifcopenshell.api.attribute
import numpy as np import numpy as np
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
@@ -604,6 +605,40 @@ class AppendLibraryElement(bpy.types.Operator, tool.Ifc.Operator):
ifc_importer.create_style(element) 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): class EnableEditingHeader(bpy.types.Operator):
bl_idname = "bim.enable_editing_header" bl_idname = "bim.enable_editing_header"
bl_label = "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.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
import bonsai.tool as tool import bonsai.tool as tool
import bonsai.bim.helper
from bonsai.bim.module.project.data import ProjectData, ProjectLibraryData from bonsai.bim.module.project.data import ProjectData, ProjectLibraryData
from bonsai.bim.ifc import IfcStore 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.types import PropertyGroup
from bpy.props import ( from bpy.props import (
PointerProperty, PointerProperty,
@@ -88,6 +89,22 @@ def filter_by_library_update(self: "BIMProjectProperties", context: bpy.types.Co
bpy.ops.bim.refresh_library() 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: def update_filter_mode(self: "BIMProjectProperties", context: bpy.types.Context) -> None:
self.filter_categories.clear() self.filter_categories.clear()
if self.filter_mode == "NONE": if self.filter_mode == "NONE":
@@ -300,6 +317,15 @@ class BIMProjectProperties(PropertyGroup):
default=True, default=True,
update=filter_by_library_update, 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) use_relative_project_path: BoolProperty(name="Use Relative Project Path", default=False)
queried_obj: bpy.props.PointerProperty(type=bpy.types.Object) queried_obj: bpy.props.PointerProperty(type=bpy.types.Object)
@@ -367,6 +393,9 @@ class BIMProjectProperties(PropertyGroup):
library_file: str library_file: str
selected_project_library: Union[Literal["*", "-"], str] selected_project_library: Union[Literal["*", "-"], str]
filter_by_library: bool 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 use_relative_project_path: bool
queried_obj: Union[bpy.types.Object, None] queried_obj: Union[bpy.types.Object, None]
+15 -2
View File
@@ -21,7 +21,7 @@ import bpy
import os import os
import bonsai.bim import bonsai.bim
import bonsai.tool as tool 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 bpy.types import Panel, Menu, UIList
from bonsai.bim.ifc import IfcStore from bonsai.bim.ifc import IfcStore
from bonsai.bim.module.project.data import ProjectData, LinksData from bonsai.bim.module.project.data import ProjectData, LinksData
@@ -344,7 +344,7 @@ class BIM_PT_project_library(Panel):
def draw(self, context): def draw(self, context):
self.layout.use_property_decorate = False self.layout.use_property_decorate = False
self.layout.use_property_split = True 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 = self.layout.row(align=True)
row.prop(self.props, "library_file", text="") row.prop(self.props, "library_file", text="")
if self.props.library_file == "0": if self.props.library_file == "0":
@@ -364,16 +364,29 @@ class BIM_PT_project_library(Panel):
def draw_library_ul(self): def draw_library_ul(self):
layout = self.layout layout = self.layout
props = self.props
if not self.props.library_elements: if not self.props.library_elements:
row = self.layout.row() row = self.layout.row()
row.label(text="No Assets Found", icon="ERROR") row.label(text="No Assets Found", icon="ERROR")
return return
library_is_selected = props.selected_project_library not in ("*", "-")
row = layout.row(align=True) row = layout.row(align=True)
row.prop(self.props, "selected_project_library", text="") 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") 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 = self.layout.row(align=True)
row.label(text=self.props.active_library_element or "Top Level Assets") row.label(text=self.props.active_library_element or "Top Level Assets")
if self.props.active_library_element: if self.props.active_library_element: