mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 14:07:43 +00:00
Project library UI - make filter optional and allow assigning to different libraries
This commit is contained in:
@@ -288,11 +288,17 @@ class ChangeLibraryElement(bpy.types.Operator):
|
|||||||
is_declarable = project_libraries_exist and element.is_a("IfcObjectDefinition")
|
is_declarable = project_libraries_exist and element.is_a("IfcObjectDefinition")
|
||||||
new.is_declarable = is_declarable
|
new.is_declarable = is_declarable
|
||||||
|
|
||||||
|
selected_library = self.props.selected_project_library
|
||||||
# is_declared.
|
# is_declared.
|
||||||
if not is_declarable:
|
if not is_declarable:
|
||||||
new.is_declared = False
|
new.is_declared = False
|
||||||
elif (has_context := element.HasContext) and has_context[0].RelatingContext.is_a("IfcProjectLibrary"):
|
elif has_context := element.HasContext:
|
||||||
new.is_declared = True
|
relating_context: ifcopenshell.entity_instance
|
||||||
|
relating_context = has_context[0].RelatingContext
|
||||||
|
if selected_library in ("-", "*"):
|
||||||
|
new.is_declared = relating_context.is_a("IfcProjectLibrary")
|
||||||
|
else:
|
||||||
|
new.is_declared = relating_context == self.library_file.by_id(int(selected_library))
|
||||||
|
|
||||||
# is_appended.
|
# is_appended.
|
||||||
try:
|
try:
|
||||||
@@ -328,9 +334,13 @@ class RewindLibrary(bpy.types.Operator):
|
|||||||
class AssignLibraryDeclaration(bpy.types.Operator):
|
class AssignLibraryDeclaration(bpy.types.Operator):
|
||||||
bl_idname = "bim.assign_library_declaration"
|
bl_idname = "bim.assign_library_declaration"
|
||||||
bl_label = "Assign Library Declaration"
|
bl_label = "Assign Library Declaration"
|
||||||
|
bl_description = "Assign element to the active library. If no specific library selected, will assign it to the first library in the file."
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
definition: bpy.props.IntProperty()
|
definition: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
definition: int
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
IfcStore.begin_transaction(self)
|
IfcStore.begin_transaction(self)
|
||||||
IfcStore.library_file.begin_transaction()
|
IfcStore.library_file.begin_transaction()
|
||||||
@@ -341,17 +351,22 @@ class AssignLibraryDeclaration(bpy.types.Operator):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.props = context.scene.BIMProjectProperties
|
props = tool.Project.get_project_props()
|
||||||
self.file = IfcStore.library_file
|
library_file = IfcStore.library_file
|
||||||
ifcopenshell.api.run(
|
assert library_file
|
||||||
"project.assign_declaration",
|
|
||||||
self.file,
|
if props.selected_project_library in ("*", "-"):
|
||||||
definitions=[self.file.by_id(self.definition)],
|
project_library = library_file.by_type("IfcProjectLibrary")[0]
|
||||||
relating_context=self.file.by_type("IfcProjectLibrary")[0],
|
else:
|
||||||
|
project_library = library_file.by_id(int(props.selected_project_library))
|
||||||
|
|
||||||
|
ifcopenshell.api.project.assign_declaration(
|
||||||
|
library_file,
|
||||||
|
definitions=[library_file.by_id(self.definition)],
|
||||||
|
relating_context=project_library,
|
||||||
)
|
)
|
||||||
element_name = self.props.active_library_element
|
|
||||||
bpy.ops.bim.rewind_library()
|
tool.Project.update_current_library_page()
|
||||||
bpy.ops.bim.change_library_element(element_name=element_name)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def rollback(self, data):
|
def rollback(self, data):
|
||||||
@@ -367,6 +382,9 @@ class UnassignLibraryDeclaration(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
definition: bpy.props.IntProperty()
|
definition: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
definition: int
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
IfcStore.begin_transaction(self)
|
IfcStore.begin_transaction(self)
|
||||||
IfcStore.library_file.begin_transaction()
|
IfcStore.library_file.begin_transaction()
|
||||||
@@ -377,17 +395,18 @@ class UnassignLibraryDeclaration(bpy.types.Operator):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.props = context.scene.BIMProjectProperties
|
props = tool.Project.get_project_props()
|
||||||
self.file = IfcStore.library_file
|
library_file = IfcStore.library_file
|
||||||
ifcopenshell.api.run(
|
assert library_file
|
||||||
"project.unassign_declaration",
|
|
||||||
self.file,
|
element = library_file.by_id(self.definition)
|
||||||
definitions=[self.file.by_id(self.definition)],
|
ifcopenshell.api.project.unassign_declaration(
|
||||||
relating_context=self.file.by_type("IfcProjectLibrary")[0],
|
library_file,
|
||||||
|
definitions=[library_file.by_id(self.definition)],
|
||||||
|
relating_context=element.HasContext[0].RelatingContext,
|
||||||
)
|
)
|
||||||
element_name = self.props.active_library_element
|
|
||||||
bpy.ops.bim.rewind_library()
|
tool.Project.update_current_library_page()
|
||||||
bpy.ops.bim.change_library_element(element_name=element_name)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def rollback(self, data):
|
def rollback(self, data):
|
||||||
|
|||||||
@@ -67,7 +67,11 @@ def update_library_file(self: "BIMProjectProperties", context: bpy.types.Context
|
|||||||
|
|
||||||
|
|
||||||
def update_selected_project_library(self: "BIMProjectProperties", context: bpy.types.Context) -> None:
|
def update_selected_project_library(self: "BIMProjectProperties", context: bpy.types.Context) -> None:
|
||||||
bpy.ops.bim.refresh_library()
|
if self.filter_by_library:
|
||||||
|
bpy.ops.bim.refresh_library()
|
||||||
|
else:
|
||||||
|
# Ensure `.is_declared` up to date.
|
||||||
|
tool.Project.update_current_library_page()
|
||||||
|
|
||||||
|
|
||||||
def get_project_libaries(self: "BIMProjectProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
|
def get_project_libaries(self: "BIMProjectProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
|
||||||
@@ -76,6 +80,13 @@ def get_project_libaries(self: "BIMProjectProperties", context: bpy.types.Contex
|
|||||||
return ProjectLibraryData.data["project_libraries_enum"]
|
return ProjectLibraryData.data["project_libraries_enum"]
|
||||||
|
|
||||||
|
|
||||||
|
def filter_by_library_update(self: "BIMProjectProperties", context: bpy.types.Context) -> None:
|
||||||
|
if self.filter_by_library and self.selected_project_library == "*":
|
||||||
|
# Filter is toggled from OFF to ON, so it was showing all elements previously either way.
|
||||||
|
return
|
||||||
|
bpy.ops.bim.refresh_library()
|
||||||
|
|
||||||
|
|
||||||
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":
|
||||||
@@ -282,6 +293,12 @@ class BIMProjectProperties(PropertyGroup):
|
|||||||
description="Project library to display elements from",
|
description="Project library to display elements from",
|
||||||
update=update_selected_project_library,
|
update=update_selected_project_library,
|
||||||
)
|
)
|
||||||
|
filter_by_library: BoolProperty(
|
||||||
|
name="Filter by Library",
|
||||||
|
description="Filter library elements based on selected library. If unselected can be used to assign selected library to library elements.",
|
||||||
|
default=True,
|
||||||
|
update=filter_by_library_update,
|
||||||
|
)
|
||||||
|
|
||||||
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)
|
||||||
@@ -348,6 +365,7 @@ 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
|
||||||
|
|
||||||
use_relative_project_path: bool
|
use_relative_project_path: bool
|
||||||
queried_obj: Union[bpy.types.Object, None]
|
queried_obj: Union[bpy.types.Object, None]
|
||||||
|
|||||||
@@ -363,11 +363,17 @@ class BIM_PT_project_library(Panel):
|
|||||||
row.label(text="No Library Loaded", icon="ASSET_MANAGER")
|
row.label(text="No Library Loaded", icon="ASSET_MANAGER")
|
||||||
|
|
||||||
def draw_library_ul(self):
|
def draw_library_ul(self):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
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
|
||||||
self.layout.prop(self.props, "selected_project_library", text="")
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.prop(self.props, "selected_project_library", text="")
|
||||||
|
row.prop(self.props, "filter_by_library", text="", icon="FILTER")
|
||||||
|
|
||||||
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:
|
||||||
|
|||||||
@@ -303,12 +303,14 @@ class Project(bonsai.core.tool.Project):
|
|||||||
library_file = IfcStore.library_file
|
library_file = IfcStore.library_file
|
||||||
assert library_file
|
assert library_file
|
||||||
|
|
||||||
if props.selected_project_library == "*":
|
selected_project_library = props.selected_project_library if props.filter_by_library else "*"
|
||||||
|
|
||||||
|
if selected_project_library == "*":
|
||||||
|
|
||||||
def condition(elements: list[ifcopenshell.entity_instance]):
|
def condition(elements: list[ifcopenshell.entity_instance]):
|
||||||
yield from elements
|
yield from elements
|
||||||
|
|
||||||
elif props.selected_project_library == "-":
|
elif selected_project_library == "-":
|
||||||
|
|
||||||
def condition(elements: list[ifcopenshell.entity_instance]):
|
def condition(elements: list[ifcopenshell.entity_instance]):
|
||||||
for element in elements:
|
for element in elements:
|
||||||
@@ -316,7 +318,7 @@ class Project(bonsai.core.tool.Project):
|
|||||||
yield element
|
yield element
|
||||||
|
|
||||||
else:
|
else:
|
||||||
project_library = library_file.by_id(int(props.selected_project_library))
|
project_library = library_file.by_id(int(selected_project_library))
|
||||||
project_library_rels = set(project_library.Declares)
|
project_library_rels = set(project_library.Declares)
|
||||||
if project_library_rels:
|
if project_library_rels:
|
||||||
|
|
||||||
@@ -333,3 +335,10 @@ class Project(bonsai.core.tool.Project):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
return condition
|
return condition
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_current_library_page(cls):
|
||||||
|
props = cls.get_project_props()
|
||||||
|
element_name = props.active_library_element
|
||||||
|
bpy.ops.bim.rewind_library()
|
||||||
|
bpy.ops.bim.change_library_element(element_name=element_name)
|
||||||
|
|||||||
Reference in New Issue
Block a user