mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 13:46:54 +00:00
BlenderBIM Feature - Filter By Building Storey
This commit is contained in:
@@ -20,7 +20,8 @@ import bpy
|
|||||||
from . import ui, prop, operator
|
from . import ui, prop, operator
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
operator.ActivateIfcTypeFilter,
|
operator.ActivateIfcClassFilter,
|
||||||
|
operator.ActivateIfcBuildingStoreyFilter,
|
||||||
operator.ColourByAttribute,
|
operator.ColourByAttribute,
|
||||||
operator.ColourByClass,
|
operator.ColourByClass,
|
||||||
operator.ColourByPset,
|
operator.ColourByPset,
|
||||||
@@ -31,9 +32,11 @@ classes = (
|
|||||||
operator.SelectIfcClass,
|
operator.SelectIfcClass,
|
||||||
operator.SelectPset,
|
operator.SelectPset,
|
||||||
prop.BIMFilterClasses,
|
prop.BIMFilterClasses,
|
||||||
|
prop.BIMFilterBuildingStoreys,
|
||||||
prop.BIMSearchProperties,
|
prop.BIMSearchProperties,
|
||||||
ui.BIM_PT_search,
|
ui.BIM_PT_search,
|
||||||
ui.BIM_UL_ifctype_filter,
|
ui.BIM_UL_ifc_class_filter,
|
||||||
|
ui.BIM_UL_ifc_building_storey_filter,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -321,29 +321,35 @@ class ResetObjectColours(bpy.types.Operator):
|
|||||||
|
|
||||||
|
|
||||||
class ToggleFilterSelection(bpy.types.Operator):
|
class ToggleFilterSelection(bpy.types.Operator):
|
||||||
"Click to select/deselect all ifctype"
|
"Click to select/deselect current selection"
|
||||||
bl_idname = "bim.toggle_filter_selection"
|
bl_idname = "bim.toggle_filter_selection"
|
||||||
bl_label = "Toggle Filter Selection"
|
bl_label = "Toggle Filter Selection"
|
||||||
action: bpy.props.EnumProperty(items=(("SELECT", "Select", ""), ("DESELECT", "Deselect", "")))
|
action: bpy.props.EnumProperty(items=(("SELECT", "Select", ""), ("DESELECT", "Deselect", "")))
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.BIMSearchProperties
|
||||||
if self.action == "SELECT":
|
if self.action == "SELECT":
|
||||||
self.selecting_actionbool = True
|
self.selecting_actionbool = True
|
||||||
else:
|
else:
|
||||||
self.selecting_actionbool = False
|
self.selecting_actionbool = False
|
||||||
for ifcelement in bpy.context.scene.BIMSearchProperties.filter_classes:
|
if props.filter_type == "CLASSES":
|
||||||
ifcelement.is_selected = self.selecting_actionbool
|
for ifc_class in props.filter_classes:
|
||||||
|
ifc_class.is_selected = self.selecting_actionbool
|
||||||
|
elif props.filter_type == "BUILDINGSTOREYS":
|
||||||
|
for building_storey in props.filter_building_storeys:
|
||||||
|
building_storey.is_selected = self.selecting_actionbool
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class ActivateIfcTypeFilter(bpy.types.Operator):
|
class ActivateIfcClassFilter(bpy.types.Operator):
|
||||||
"It helps you to filter your selection by IFC class"
|
"""Filter the current selection by IFC class"""
|
||||||
bl_idname = "bim.activate_ifc_type_filter"
|
|
||||||
bl_label = "Activate IfcType Filter"
|
bl_idname = "bim.activate_ifc_class_filter"
|
||||||
|
bl_label = "Filter by Class"
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
bpy.context.scene.BIMSearchProperties.filter_classes.clear()
|
props = bpy.context.scene.BIMSearchProperties
|
||||||
|
props.filter_classes.clear()
|
||||||
ifc_types = {}
|
ifc_types = {}
|
||||||
for obj in context.selected_objects:
|
for obj in context.selected_objects:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
@@ -353,9 +359,10 @@ class ActivateIfcTypeFilter(bpy.types.Operator):
|
|||||||
ifc_types[element.is_a()] += 1
|
ifc_types[element.is_a()] += 1
|
||||||
|
|
||||||
for name, total in dict(sorted(ifc_types.items())).items():
|
for name, total in dict(sorted(ifc_types.items())).items():
|
||||||
new = context.scene.BIMSearchProperties.filter_classes.add()
|
new = props.filter_classes.add()
|
||||||
new.name = name
|
new.name = name
|
||||||
new.total = total
|
new.total = total
|
||||||
|
props.filter_type = "CLASSES"
|
||||||
|
|
||||||
return context.window_manager.invoke_props_dialog(self, width=250)
|
return context.window_manager.invoke_props_dialog(self, width=250)
|
||||||
|
|
||||||
@@ -365,7 +372,7 @@ class ActivateIfcTypeFilter(bpy.types.Operator):
|
|||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
self.layout.template_list(
|
self.layout.template_list(
|
||||||
"BIM_UL_ifctype_filter",
|
"BIM_UL_ifc_class_filter",
|
||||||
"",
|
"",
|
||||||
context.scene.BIMSearchProperties,
|
context.scene.BIMSearchProperties,
|
||||||
"filter_classes",
|
"filter_classes",
|
||||||
@@ -378,3 +385,51 @@ class ActivateIfcTypeFilter(bpy.types.Operator):
|
|||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.operator("bim.toggle_filter_selection", text="Select All").action = "SELECT"
|
row.operator("bim.toggle_filter_selection", text="Select All").action = "SELECT"
|
||||||
row.operator("bim.toggle_filter_selection", text="Deselect All").action = "DESELECT"
|
row.operator("bim.toggle_filter_selection", text="Deselect All").action = "DESELECT"
|
||||||
|
|
||||||
|
|
||||||
|
class ActivateIfcBuildingStoreyFilter(bpy.types.Operator):
|
||||||
|
"""Filter the current selection by Building Storey"""
|
||||||
|
|
||||||
|
bl_idname = "bim.activate_ifc_building_storey_filter"
|
||||||
|
bl_label = "Filter by Building Storey"
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
props = bpy.context.scene.BIMSearchProperties
|
||||||
|
props.filter_building_storeys.clear()
|
||||||
|
|
||||||
|
ifc_building_storeys = {}
|
||||||
|
for obj in context.selected_objects:
|
||||||
|
storey = tool.Misc.get_object_storey(obj)
|
||||||
|
if not storey:
|
||||||
|
continue
|
||||||
|
ifc_building_storeys.setdefault(storey.Name, 0)
|
||||||
|
ifc_building_storeys[storey.Name] += 1
|
||||||
|
|
||||||
|
for name, total in dict(sorted(ifc_building_storeys.items())).items():
|
||||||
|
new = props.filter_building_storeys.add()
|
||||||
|
new.name = name
|
||||||
|
new.total = total
|
||||||
|
|
||||||
|
props.filter_type = "BUILDINGSTOREYS"
|
||||||
|
|
||||||
|
return context.window_manager.invoke_props_dialog(self, width=250)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
bpy.context.scene.BIMSearchProperties.filter_building_storeys.clear()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
self.layout.template_list(
|
||||||
|
"BIM_UL_ifc_building_storey_filter",
|
||||||
|
"",
|
||||||
|
context.scene.BIMSearchProperties,
|
||||||
|
"filter_building_storeys",
|
||||||
|
context.scene.BIMSearchProperties,
|
||||||
|
"filter_building_storeys_index",
|
||||||
|
rows=20
|
||||||
|
if len(bpy.context.scene.BIMSearchProperties.filter_building_storeys) > 20
|
||||||
|
else len(bpy.context.scene.BIMSearchProperties.filter_building_storeys),
|
||||||
|
)
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.operator("bim.toggle_filter_selection", text="Select All").action = "SELECT"
|
||||||
|
row.operator("bim.toggle_filter_selection", text="Deselect All").action = "DESELECT"
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ from bpy.props import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_is_selected(self, context):
|
def update_is_class_selected(self, context):
|
||||||
if self.is_selected:
|
if self.is_selected:
|
||||||
for obj in self.unselected_objects:
|
for obj in self.unselected_objects:
|
||||||
obj.obj.select_set(True)
|
obj.obj.select_set(True)
|
||||||
@@ -46,10 +46,29 @@ def update_is_selected(self, context):
|
|||||||
new = self.unselected_objects.add()
|
new = self.unselected_objects.add()
|
||||||
new.obj = obj
|
new.obj = obj
|
||||||
|
|
||||||
|
def update_is_level_selected(self, context):
|
||||||
|
if self.is_selected:
|
||||||
|
for obj in self.unselected_objects:
|
||||||
|
obj.obj.select_set(True)
|
||||||
|
self.unselected_objects.clear()
|
||||||
|
else:
|
||||||
|
for obj in context.selected_objects:
|
||||||
|
level = tool.Misc.get_object_storey(obj)
|
||||||
|
if level and level.Name == self.name:
|
||||||
|
obj.select_set(False)
|
||||||
|
new = self.unselected_objects.add()
|
||||||
|
new.obj = obj
|
||||||
|
|
||||||
class BIMFilterClasses(PropertyGroup):
|
class BIMFilterClasses(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
name: StringProperty(name="Name")
|
||||||
is_selected: BoolProperty(name="Is Selected", default=True, update=update_is_selected)
|
is_selected: BoolProperty(name="Is Selected", default=True, update=update_is_class_selected)
|
||||||
|
total: IntProperty(name="Total")
|
||||||
|
unselected_objects: CollectionProperty(type=ObjProperty, name="Unfiltered Objects")
|
||||||
|
|
||||||
|
|
||||||
|
class BIMFilterBuildingStoreys(PropertyGroup):
|
||||||
|
name: StringProperty(name="Name")
|
||||||
|
is_selected: BoolProperty(name="Is Level Selected", default=True, update=update_is_level_selected)
|
||||||
total: IntProperty(name="Total")
|
total: IntProperty(name="Total")
|
||||||
unselected_objects: CollectionProperty(type=ObjProperty, name="Unfiltered Objects")
|
unselected_objects: CollectionProperty(type=ObjProperty, name="Unfiltered Objects")
|
||||||
|
|
||||||
@@ -64,5 +83,8 @@ class BIMSearchProperties(PropertyGroup):
|
|||||||
search_pset_name: StringProperty(name="Search Pset Name")
|
search_pset_name: StringProperty(name="Search Pset Name")
|
||||||
search_prop_name: StringProperty(name="Search Prop Name")
|
search_prop_name: StringProperty(name="Search Prop Name")
|
||||||
search_pset_value: StringProperty(name="Search Pset Value")
|
search_pset_value: StringProperty(name="Search Pset Value")
|
||||||
|
filter_type: StringProperty(name="Filter Type")
|
||||||
filter_classes: CollectionProperty(type=BIMFilterClasses, name="Filter Classes")
|
filter_classes: CollectionProperty(type=BIMFilterClasses, name="Filter Classes")
|
||||||
filter_classes_index: IntProperty(name="Filter Classes Index")
|
filter_classes_index: IntProperty(name="Filter Classes Index")
|
||||||
|
filter_building_storeys: CollectionProperty(type=BIMFilterBuildingStoreys, name="Filter Level")
|
||||||
|
filter_building_storeys_index: IntProperty(name="Filter Level Index")
|
||||||
|
|||||||
@@ -67,11 +67,27 @@ class BIM_PT_search(Panel):
|
|||||||
row.operator("bim.colour_by_pset", text="", icon="BRUSH_DATA")
|
row.operator("bim.colour_by_pset", text="", icon="BRUSH_DATA")
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.operator("bim.activate_ifc_type_filter", icon="FILTER")
|
row.operator("bim.activate_ifc_class_filter", icon="FILTER")
|
||||||
|
row.operator("bim.activate_ifc_building_storey_filter", icon="FILTER")
|
||||||
|
|
||||||
|
|
||||||
class BIM_UL_ifctype_filter(bpy.types.UIList):
|
class BIM_UL_ifc_class_filter(bpy.types.UIList):
|
||||||
"This UI List is to list out all the selected IfcType and number of it as well as providing the BoolProperty to select/deselect"
|
use_filter_linked: bpy.props.BoolProperty(name="Included", default=True, options=set(), description="Filter")
|
||||||
|
|
||||||
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||||
|
split = layout
|
||||||
|
split.use_property_split = True
|
||||||
|
split.use_property_decorate = False
|
||||||
|
split.prop(
|
||||||
|
item, "is_selected", text="", emboss=False, icon="CHECKBOX_HLT" if item.is_selected else "CHECKBOX_DEHLT"
|
||||||
|
)
|
||||||
|
split.prop(item, "name", text="", emboss=False, slider=True)
|
||||||
|
split = split.column()
|
||||||
|
split.scale_x = 0.5
|
||||||
|
split.label(text=str(item.total))
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_UL_ifc_building_storey_filter(bpy.types.UIList):
|
||||||
use_filter_linked: bpy.props.BoolProperty(name="Included", default=True, options=set(), description="Filter")
|
use_filter_linked: bpy.props.BoolProperty(name="Included", default=True, options=set(), description="Filter")
|
||||||
|
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||||
|
|||||||
Reference in New Issue
Block a user