mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 08:46:53 +00:00
Add search bar with simple filter function to the type manager
This commit is contained in:
@@ -57,20 +57,22 @@ class AuthoringData:
|
|||||||
cls.data["ifc_element_type"] = cls.ifc_element_type
|
cls.data["ifc_element_type"] = cls.ifc_element_type
|
||||||
cls.data["ifc_classes"] = cls.ifc_classes()
|
cls.data["ifc_classes"] = cls.ifc_classes()
|
||||||
cls.data["ifc_class_current"] = cls.ifc_class_current()
|
cls.data["ifc_class_current"] = cls.ifc_class_current()
|
||||||
cls.data["relating_type_id"] = cls.relating_type_id() # only after .ifc_classes()
|
# Make sure .ifc_classes() was run before next lines
|
||||||
cls.data["relating_type_id_current"] = cls.relating_type_id_current() # only after .ifc_classes()
|
cls.data["filtered_type_elements"] = cls.filtered_type_elements()
|
||||||
cls.data["relating_type_name"] = cls.relating_type_name() # only after .relating_type_id()
|
# Make sure .filtered_type_elements() was run before next lines
|
||||||
cls.data["relating_type_description"] = cls.relating_type_description() # only after .relating_type_id()
|
cls.data["relating_type_id"] = cls.relating_type_id()
|
||||||
cls.data["predefined_type"] = cls.predefined_type() # only after .relating_type_id()
|
# Make sure .relating_type_id() was run before next lines
|
||||||
|
cls.data["relating_type_id_current"] = cls.relating_type_id_current()
|
||||||
# Only after .ifc_classes()
|
cls.data["relating_type_name"] = cls.relating_type_name()
|
||||||
|
cls.data["relating_type_description"] = cls.relating_type_description()
|
||||||
|
cls.data["predefined_type"] = cls.predefined_type()
|
||||||
cls.data["total_types"] = cls.total_types()
|
cls.data["total_types"] = cls.total_types()
|
||||||
cls.data["total_pages"] = cls.total_pages()
|
cls.data["total_pages"] = cls.total_pages() # Only after .total_types()
|
||||||
cls.data["next_page"] = cls.next_page()
|
cls.data["next_page"] = cls.next_page()
|
||||||
cls.data["prev_page"] = cls.prev_page()
|
cls.data["prev_page"] = cls.prev_page()
|
||||||
cls.data["paginated_relating_types"] = cls.paginated_relating_types()
|
cls.data["paginated_relating_types"] = cls.paginated_relating_types()
|
||||||
|
|
||||||
cls.data["type_thumbnail"] = cls.type_thumbnail() # Only after .relating_type_id()
|
cls.data["type_thumbnail"] = cls.type_thumbnail()
|
||||||
cls.data["is_voidable_element"] = cls.is_voidable_element()
|
cls.data["is_voidable_element"] = cls.is_voidable_element()
|
||||||
cls.data["has_visible_openings"] = cls.has_visible_openings()
|
cls.data["has_visible_openings"] = cls.has_visible_openings()
|
||||||
cls.data["has_visible_boundaries"] = cls.has_visible_boundaries()
|
cls.data["has_visible_boundaries"] = cls.has_visible_boundaries()
|
||||||
@@ -114,13 +116,11 @@ class AuthoringData:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def total_types(cls):
|
def total_types(cls):
|
||||||
ifc_class = cls.data["ifc_class_current"]
|
return len(cls.data["filtered_type_elements"])
|
||||||
return len(tool.Ifc.get().by_type(ifc_class)) if ifc_class else 0
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def total_pages(cls):
|
def total_pages(cls):
|
||||||
ifc_class = cls.data["ifc_class_current"]
|
total_types = cls.data["total_types"]
|
||||||
total_types = len(tool.Ifc.get().by_type(ifc_class)) if ifc_class else 0
|
|
||||||
return math.ceil(total_types / cls.types_per_page)
|
return math.ceil(total_types / cls.types_per_page)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -134,12 +134,19 @@ class AuthoringData:
|
|||||||
return cls.props.type_page - 1
|
return cls.props.type_page - 1
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def paginated_relating_types(cls):
|
def filtered_type_elements(cls):
|
||||||
ifc_class = cls.data["ifc_class_current"]
|
ifc_class = cls.data["ifc_class_current"]
|
||||||
if not ifc_class:
|
if not ifc_class:
|
||||||
return []
|
return []
|
||||||
|
elements = list(tool.Ifc.get().by_type(ifc_class))
|
||||||
|
if cls.props.search_name:
|
||||||
|
elements = [e for e in elements if cls.props.search_name.lower() in (e.Name or "Unnamed").lower()]
|
||||||
|
return natsorted(elements, key=lambda s: (s.Name or "Unnamed").lower())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def paginated_relating_types(cls):
|
||||||
results = []
|
results = []
|
||||||
elements = natsorted(tool.Ifc.get().by_type(ifc_class), key=lambda e: e.Name or "Unnamed")
|
elements = cls.data["filtered_type_elements"]
|
||||||
elements = elements[(cls.props.type_page - 1) * cls.types_per_page : cls.props.type_page * cls.types_per_page]
|
elements = elements[(cls.props.type_page - 1) * cls.types_per_page : cls.props.type_page * cls.types_per_page]
|
||||||
for element in elements:
|
for element in elements:
|
||||||
predefined_type = ifcopenshell.util.element.get_predefined_type(element)
|
predefined_type = ifcopenshell.util.element.get_predefined_type(element)
|
||||||
@@ -266,13 +273,8 @@ class AuthoringData:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def relating_type_id(cls):
|
def relating_type_id(cls):
|
||||||
results = []
|
elements = cls.data["filtered_type_elements"]
|
||||||
ifc_class = cls.data["ifc_class_current"]
|
return [(str(e.id()), e.Name or "Unnamed", e.Description or "") for e in elements]
|
||||||
if ifc_class:
|
|
||||||
elements = natsorted(tool.Ifc.get().by_type(ifc_class), key=lambda s: (s.Name or "Unnamed").lower())
|
|
||||||
results.extend(elements)
|
|
||||||
return [(str(e.id()), e.Name or "Unnamed", e.Description or "") for e in results]
|
|
||||||
return []
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def relating_type_id_current(cls):
|
def relating_type_id_current(cls):
|
||||||
|
|||||||
@@ -566,7 +566,9 @@ class LoadTypeThumbnails(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
processing = set()
|
processing = set()
|
||||||
# Only process at most one paginated class at a time.
|
# Only process at most one paginated class at a time.
|
||||||
# Large projects have hundreds of types which can lead to unnecessary lag.
|
# Large projects have hundreds of types which can lead to unnecessary lag.
|
||||||
queue = sorted(tool.Ifc.get().by_type(self.ifc_class), key=lambda e: e.Name or "Unnamed")
|
if not AuthoringData.is_loaded:
|
||||||
|
AuthoringData.load()
|
||||||
|
queue = AuthoringData.data["filtered_type_elements"]
|
||||||
if self.limit:
|
if self.limit:
|
||||||
queue = queue[self.offset : self.offset + self.limit]
|
queue = queue[self.offset : self.offset + self.limit]
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -97,11 +97,26 @@ def update_slab_direction_decorator(self, context):
|
|||||||
SlabDirectionDecorator.uninstall()
|
SlabDirectionDecorator.uninstall()
|
||||||
|
|
||||||
|
|
||||||
|
def update_search_name(self, context):
|
||||||
|
AuthoringData.load()
|
||||||
|
# Total number of pages may decrease when using the search bar :
|
||||||
|
if self.type_page > AuthoringData.data["total_pages"]:
|
||||||
|
self.type_page = AuthoringData.data["total_pages"]
|
||||||
|
bpy.ops.bim.load_type_thumbnails(ifc_class=self.ifc_class)
|
||||||
|
|
||||||
|
|
||||||
class BIMModelProperties(PropertyGroup):
|
class BIMModelProperties(PropertyGroup):
|
||||||
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="Construction Class", update=update_ifc_class)
|
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="Construction Class", update=update_ifc_class)
|
||||||
relating_type_id: bpy.props.EnumProperty(
|
relating_type_id: bpy.props.EnumProperty(
|
||||||
items=get_relating_type_id, name="Relating Type", update=update_relating_type_id
|
items=get_relating_type_id, name="Relating Type", update=update_relating_type_id
|
||||||
)
|
)
|
||||||
|
search_name: bpy.props.StringProperty(
|
||||||
|
name="Search Name",
|
||||||
|
default="",
|
||||||
|
description="Use this property to filter the list of available types",
|
||||||
|
update=update_search_name,
|
||||||
|
options={"SKIP_SAVE", "TEXTEDIT_UPDATE"},
|
||||||
|
)
|
||||||
menu_relating_type_id: bpy.props.IntProperty()
|
menu_relating_type_id: bpy.props.IntProperty()
|
||||||
icon_id: bpy.props.IntProperty()
|
icon_id: bpy.props.IntProperty()
|
||||||
updating: bpy.props.BoolProperty(default=False)
|
updating: bpy.props.BoolProperty(default=False)
|
||||||
|
|||||||
@@ -108,12 +108,10 @@ class LaunchTypeManager(bpy.types.Operator):
|
|||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
props = context.scene.BIMModelProperties
|
props = context.scene.BIMModelProperties
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
|
text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type']}"
|
||||||
if AuthoringData.data["total_types"] > 1:
|
if AuthoringData.data["total_types"] > 1:
|
||||||
text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type']}s"
|
text += "s"
|
||||||
else:
|
|
||||||
text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type']}"
|
|
||||||
row.label(text=text, icon="FILE_VOLUME")
|
row.label(text=text, icon="FILE_VOLUME")
|
||||||
# prop_with_search(row, props, "ifc_class", text="", should_click_ok_to_validate=True)
|
|
||||||
row.menu("BIM_MT_type_manager_menu", text="", icon="PREFERENCES")
|
row.menu("BIM_MT_type_manager_menu", text="", icon="PREFERENCES")
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.operator("bim.launch_add_element", text=f"Create New {AuthoringData.data['ifc_element_type']}", icon="ADD")
|
row.operator("bim.launch_add_element", text=f"Create New {AuthoringData.data['ifc_element_type']}", icon="ADD")
|
||||||
@@ -121,9 +119,6 @@ class LaunchTypeManager(bpy.types.Operator):
|
|||||||
columns = self.layout.column_flow(columns=3)
|
columns = self.layout.column_flow(columns=3)
|
||||||
row = columns.row(align=True)
|
row = columns.row(align=True)
|
||||||
row.alignment = "CENTER"
|
row.alignment = "CENTER"
|
||||||
### In case you want something here in the future
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
row = columns.row(align=True)
|
row = columns.row(align=True)
|
||||||
row.alignment = "RIGHT"
|
row.alignment = "RIGHT"
|
||||||
@@ -136,6 +131,8 @@ class LaunchTypeManager(bpy.types.Operator):
|
|||||||
op = row.operator("bim.change_type_page", icon="TRIA_RIGHT", text="")
|
op = row.operator("bim.change_type_page", icon="TRIA_RIGHT", text="")
|
||||||
op.page = AuthoringData.data["next_page"]
|
op.page = AuthoringData.data["next_page"]
|
||||||
|
|
||||||
|
self.layout.prop(props, "search_name", icon="VIEWZOOM", text="")
|
||||||
|
|
||||||
flow = self.layout.grid_flow(row_major=True, columns=3, even_columns=True, even_rows=True, align=True)
|
flow = self.layout.grid_flow(row_major=True, columns=3, even_columns=True, even_rows=True, align=True)
|
||||||
|
|
||||||
for relating_type in AuthoringData.data["paginated_relating_types"]:
|
for relating_type in AuthoringData.data["paginated_relating_types"]:
|
||||||
|
|||||||
Reference in New Issue
Block a user