diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index dbbb189e63..57e29aaae0 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -85,6 +85,7 @@ classes = [ operator.RemoveIfcFile, operator.ConfigureVisibility, prop.StrProperty, + prop.ObjProperty, prop.Attribute, prop.ModuleVisibility, prop.BIMProperties, diff --git a/src/blenderbim/blenderbim/bim/module/search/__init__.py b/src/blenderbim/blenderbim/bim/module/search/__init__.py index 6aeb84fa7a..ec56174d69 100644 --- a/src/blenderbim/blenderbim/bim/module/search/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/search/__init__.py @@ -20,28 +20,25 @@ import bpy from . import ui, prop, operator classes = ( + operator.ActivateIfcTypeFilter, + operator.ColourByAttribute, + operator.ColourByClass, + operator.ColourByPset, + operator.ResetObjectColours, + operator.SelectAttribute, operator.SelectGlobalId, operator.SelectIfcClass, - operator.SelectAttribute, operator.SelectPset, - operator.ColourByAttribute, - operator.ColourByPset, - operator.ColourByClass, - operator.ResetObjectColours, + prop.BIMFilterClasses, prop.BIMSearchProperties, ui.BIM_PT_search, - #ifcType Filter - operator.BIM_UL_ifctype_filter, - operator.BIM_OT_ifctype_filter, - prop.BIMIfcTypeFilterProperties + ui.BIM_UL_ifctype_filter, ) + def register(): bpy.types.Scene.BIMSearchProperties = bpy.props.PointerProperty(type=prop.BIMSearchProperties) - bpy.types.Scene.BIM_IfcTypeFilter_collprops = bpy.props.CollectionProperty(type=prop.BIMIfcTypeFilterProperties) - bpy.types.Scene.BIM_IfcTypeFilter_int = bpy.props.IntProperty() + def unregister(): del bpy.types.Scene.BIMSearchProperties - del bpy.types.Scene.BIM_IfcTypeFilter_collprops - del bpy.types.Scene.BIM_IfcTypeFilter_int \ No newline at end of file diff --git a/src/blenderbim/blenderbim/bim/module/search/operator.py b/src/blenderbim/blenderbim/bim/module/search/operator.py index 167dcc05f2..8be0800cc1 100644 --- a/src/blenderbim/blenderbim/bim/module/search/operator.py +++ b/src/blenderbim/blenderbim/bim/module/search/operator.py @@ -20,6 +20,7 @@ import re import bpy import ifcopenshell import ifcopenshell.util.element +import blenderbim.tool as tool from blenderbim.bim.ifc import IfcStore from itertools import cycle @@ -321,105 +322,40 @@ class ResetObjectColours(bpy.types.Operator): obj.color = (1, 1, 1, 1) return {"FINISHED"} -# ------------------------------------------------------------------- -# IfcType Filter -# ------------------------------------------------------------------- -def BIM_ifctypefilterupdate(self, context): #Trigger action - typename = self.typename - typebool = self.typebool - typenum = self.typenum - if typebool == False: - action = "deselecting" - else: - action = "selecting" - print(f"{action} {typenum} {typename} ") +class ActivateIfcTypeFilter(bpy.types.Operator): + "It helps you to filter your selection by IFC class" + bl_idname = "bim.activate_ifc_type_filter" + bl_label = "Activate IfcType Filter" - for ele,ifctype in elementsDict.items(): - if typename == ifctype: - if typebool == False: - ele.select_set(False) - else: - ele.select_set(True) - -class BIM_UL_ifctype_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): - #layout.prop(self, "use_filter_linked", text="", icon="ADD") - #layout.prop(item, "name", text="",emboss=False,toggle=True, icon="CON_ROTLIKE") - #split = layout.split(factor=0.1) - split= layout - split.use_property_split = True - split.use_property_decorate = False - #split.label(text=a[0]) - #split.label(text=item.name) - split.prop(item, 'typebool', text="",icon="ADD") - split.prop(item, 'typename', text="",emboss=False, slider=True) - split = split.column() - split.scale_x=0.5 - split.prop(item, 'typenum', text="",emboss=False) - -class BIM_OT_ifctype_filter(bpy.types.Operator): - "Click to activate IfcType Filter. It helps you to filter out IfcType with current selection" - bl_idname = "bim.ifctype_filter" - bl_label = "IfcType Filter" - def invoke(self, context, event): - print(f"{self.bl_label} Activated") - #clear collection property data - try: - bpy.context.scene.BIM_IfcTypeFilter_collprops.clear() - except: - pass - - self.importedIfcFile = IfcStore.get_file() + bpy.context.scene.BIMSearchProperties.filter_classes.clear() - #Preparing IFC infomation - elements = bpy.context.selected_objects #Get selected objects - eleIfcTypeList = [] - for ele in elements: #Get elements IfcType - eleAttr = self.importedIfcFile.by_id(ele.BIMObjectProperties.ifc_definition_id) - eleIfcTypeList.append(eleAttr.get_info()["type"]) + ifc_types = {} + for obj in context.selected_objects: + element = tool.Ifc.get_entity(obj) + if not element: + continue + ifc_types.setdefault(element.is_a(), 0) + ifc_types[element.is_a()] += 1 - #use global to let BIM_ifctypefilterupdate function grabs the user selection - global elementsDict - elementsDict={} - for ele, type in zip(elements, eleIfcTypeList): - elementsDict[ele] = type + for name, total in ifc_types.items(): + new = context.scene.BIMSearchProperties.filter_classes.add() + new.name = name + new.total = total - #use global to let draw function grabs the user selection - global ifcTypeUniqueList - ifcTypeUniqueList =sorted(list(set((eleIfcTypeList)))) - ifcTypeUniqueCount = [] - for type in ifcTypeUniqueList: - ifcTypeUniqueCount.append(eleIfcTypeList.count(type)) - - #adding IfcType name into collection property - for type,count in zip(ifcTypeUniqueList,ifcTypeUniqueCount): - BIM_IfcTypeFilter_item = bpy.context.scene.BIM_IfcTypeFilter_collprops.add() - BIM_IfcTypeFilter_item.typename = type - BIM_IfcTypeFilter_item.typenum = str(count) - return context.window_manager.invoke_props_dialog(self, width = 250) + return context.window_manager.invoke_props_dialog(self, width=250) - def execute(self, context): #This def will execute after clicking OK - print(f"{self.bl_label} Closed") - bpy.context.scene.BIM_IfcTypeFilter_collprops.clear() - return {'FINISHED'} + def execute(self, context): + bpy.context.scene.BIMSearchProperties.filter_classes.clear() + return {"FINISHED"} def draw(self, context): - layout = self.layout - scn = context.scene - if len(ifcTypeUniqueList) > 20: - rowsNum = 20 - else: - rowsNum = len(ifcTypeUniqueList) - layout.template_list( + self.layout.template_list( "BIM_UL_ifctype_filter", "", - scn, - "BIM_IfcTypeFilter_collprops", - scn, - "BIM_IfcTypeFilter_int", - rows = rowsNum - ) \ No newline at end of file + context.scene.BIMSearchProperties, + "filter_classes", + context.scene.BIMSearchProperties, + "filter_classes_index", + ) diff --git a/src/blenderbim/blenderbim/bim/module/search/prop.py b/src/blenderbim/blenderbim/bim/module/search/prop.py index c6d16d51cb..5efb411845 100644 --- a/src/blenderbim/blenderbim/bim/module/search/prop.py +++ b/src/blenderbim/blenderbim/bim/module/search/prop.py @@ -17,6 +17,8 @@ # along with BlenderBIM Add-on. If not, see . import bpy +import blenderbim.tool as tool +from blenderbim.bim.prop import ObjProperty from bpy.types import PropertyGroup from . import ui, prop, operator from bpy.props import ( @@ -31,6 +33,27 @@ from bpy.props import ( ) +def update_is_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: + element = tool.Ifc.get_entity(obj) + if element and element.is_a() == self.name: + obj.select_set(False) + new = self.unselected_objects.add() + new.obj = obj + + +class BIMFilterClasses(PropertyGroup): + name: StringProperty(name="Name") + is_selected: BoolProperty(name="Is Selected", default=True, update=update_is_selected) + total: IntProperty(name="Total") + unselected_objects: CollectionProperty(type=ObjProperty, name="Unfiltered Objects") + + class BIMSearchProperties(PropertyGroup): should_use_regex: BoolProperty(name="Search With Regex", default=False) should_ignorecase: BoolProperty(name="Search Ignoring Case", default=True) @@ -41,11 +64,5 @@ class BIMSearchProperties(PropertyGroup): search_pset_name: StringProperty(name="Search Pset Name") search_prop_name: StringProperty(name="Search Prop Name") search_pset_value: StringProperty(name="Search Pset Value") - -# ------------------------------------------------------------------- -# IfcType Filter -# ------------------------------------------------------------------- -class BIMIfcTypeFilterProperties(PropertyGroup): - typename: StringProperty() - typebool: BoolProperty(default=True, update=operator.BIM_ifctypefilterupdate) - typenum: StringProperty() \ No newline at end of file + filter_classes: CollectionProperty(type=BIMFilterClasses, name="Filter Classes") + filter_classes_index: IntProperty(name="Filter Classes Index") diff --git a/src/blenderbim/blenderbim/bim/module/search/ui.py b/src/blenderbim/blenderbim/bim/module/search/ui.py index c8e2fdd609..dab581d945 100644 --- a/src/blenderbim/blenderbim/bim/module/search/ui.py +++ b/src/blenderbim/blenderbim/bim/module/search/ui.py @@ -66,6 +66,20 @@ class BIM_PT_search(Panel): row.operator("bim.select_pset", text="", icon="VIEWZOOM") row.operator("bim.colour_by_pset", text="", icon="BRUSH_DATA") - #IfcType Filter row = self.layout.row(align=True) - row.operator("bim.ifctype_filter",icon = "FILTER") \ No newline at end of file + row.operator("bim.activate_ifc_type_filter", icon="FILTER") + + +class BIM_UL_ifctype_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="", icon="ADD" if item.is_selected else "REMOVE") + split.prop(item, "name", text="", emboss=False, slider=True) + split = split.column() + split.scale_x = 0.5 + split.prop(item, "total", text="", emboss=False) diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index 03a77f4d79..d8a8a5e066 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -123,6 +123,10 @@ class StrProperty(PropertyGroup): pass +class ObjProperty(PropertyGroup): + obj: bpy.props.PointerProperty(type=bpy.types.Object) + + def updateAttributeValue(self, context): value_name = self.get_value_name() if value_name: