mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
You can now filter and search in the spatial decomposition panel
This commit is contained in:
@@ -249,8 +249,6 @@ class SelectDecomposedElements(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
should_filter: bpy.props.BoolProperty(name="Should Filter", default=True, options={"SKIP_SAVE"})
|
||||
container: bpy.props.IntProperty()
|
||||
ifc_class: bpy.props.StringProperty()
|
||||
relating_type: bpy.props.IntProperty()
|
||||
|
||||
@classmethod
|
||||
def description(cls, context, operator):
|
||||
@@ -262,20 +260,25 @@ class SelectDecomposedElements(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return self.execute(context)
|
||||
|
||||
def _execute(self, context):
|
||||
ifc_class = relating_type = is_untyped = None
|
||||
if self.should_filter:
|
||||
ifc_class = self.ifc_class
|
||||
relating_type = tool.Ifc.get().by_id(self.relating_type) if self.relating_type else None
|
||||
is_untyped = self.relating_type == 0
|
||||
else:
|
||||
ifc_class = ""
|
||||
relating_type = None
|
||||
is_untyped = False
|
||||
active_element = context.scene.BIMSpatialDecompositionProperties.active_element
|
||||
if active_element.is_class:
|
||||
ifc_class = active_element.name
|
||||
elif relating_type := active_element.ifc_definition_id:
|
||||
ifc_class = active_element.ifc_class
|
||||
relating_type = tool.Ifc.get().by_id(relating_type)
|
||||
else:
|
||||
ifc_class = active_element.ifc_class
|
||||
is_untyped = True
|
||||
element_filter = context.scene.BIMSpatialDecompositionProperties.element_filter
|
||||
core.select_decomposed_elements(
|
||||
tool.Spatial,
|
||||
container=tool.Ifc.get().by_id(self.container),
|
||||
ifc_class=ifc_class,
|
||||
relating_type=relating_type,
|
||||
is_untyped=is_untyped,
|
||||
element_filter = element_filter
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@ class BIMContainer(PropertyGroup):
|
||||
|
||||
class Element(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
ifc_class: StringProperty(name="Name")
|
||||
is_class: BoolProperty(name="Is Class", default=False)
|
||||
is_type: BoolProperty(name="Is Type", default=False)
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
@@ -118,6 +119,7 @@ class BIMSpatialDecompositionProperties(PropertyGroup):
|
||||
contracted_containers: StringProperty(name="Contracted containers", default="[]")
|
||||
expanded_containers: StringProperty(name="Expanded containers", default="[]")
|
||||
active_container_index: IntProperty(name="Active Container Index", update=update_active_container_index)
|
||||
element_filter: StringProperty(name="Element Filter", default="", options={"TEXTEDIT_UPDATE"})
|
||||
elements: CollectionProperty(name="Elements", type=Element)
|
||||
active_element_index: IntProperty(name="Active Element Index")
|
||||
total_elements: IntProperty(name="Total Elements")
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel, UIList
|
||||
from bonsai.bim.module.spatial.data import SpatialData, SpatialDecompositionData
|
||||
import bonsai.tool as tool
|
||||
@@ -169,12 +170,6 @@ class BIM_PT_spatial_decomposition(Panel):
|
||||
)
|
||||
row.prop(self.props, "should_include_children", text="", icon="OUTLINER")
|
||||
op = row.operator("bim.select_decomposed_elements", icon="RESTRICT_SELECT_OFF", text="")
|
||||
if self.props.active_element.is_class:
|
||||
op.ifc_class = self.props.active_element.name
|
||||
op.relating_type = 0
|
||||
elif self.props.active_element.is_type:
|
||||
op.ifc_class = ""
|
||||
op.relating_type = self.props.active_element.ifc_definition_id
|
||||
op.container = ifc_definition_id
|
||||
|
||||
self.layout.template_list(
|
||||
@@ -184,6 +179,7 @@ class BIM_PT_spatial_decomposition(Panel):
|
||||
"elements",
|
||||
self.props,
|
||||
"active_element_index",
|
||||
sort_lock=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -229,6 +225,9 @@ class BIM_UL_containers_manager(UIList):
|
||||
|
||||
|
||||
class BIM_UL_elements(UIList):
|
||||
def __init__(self):
|
||||
self.use_filter_show = True
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
@@ -244,3 +243,16 @@ class BIM_UL_elements(UIList):
|
||||
col = row.column()
|
||||
col.alignment = "RIGHT"
|
||||
col.label(text=str(item.total))
|
||||
|
||||
def draw_filter(self, context, layout):
|
||||
row = layout.row()
|
||||
row.prop(context.scene.BIMSpatialDecompositionProperties, "element_filter", text="", icon="VIEWZOOM")
|
||||
|
||||
def filter_items(self, context, data, propname):
|
||||
items = getattr(data, propname)
|
||||
filter_name = context.scene.BIMSpatialDecompositionProperties.element_filter
|
||||
filtered = bpy.types.UI_UL_list.filter_items_by_name(filter_name, self.bitflag_filter_item, items, "name")
|
||||
return filtered, []
|
||||
|
||||
def get_filter_name(self):
|
||||
return self.filter_name
|
||||
|
||||
@@ -147,14 +147,10 @@ def select_decomposed_elements(
|
||||
ifc_class: str | None = None,
|
||||
relating_type: ifcopenshell.entity_instance | None = None,
|
||||
is_untyped: bool = False,
|
||||
element_filter: str | None = None,
|
||||
) -> None:
|
||||
elements = spatial.get_decomposed_elements(container)
|
||||
if ifc_class:
|
||||
elements = spatial.filter_elements_by_class(elements, ifc_class)
|
||||
elif relating_type:
|
||||
elements = spatial.filter_elements_by_relating_type(elements, relating_type)
|
||||
elif is_untyped:
|
||||
elements = spatial.filter_elements_by_untyped(elements)
|
||||
elements = spatial.filter_elements(elements, ifc_class, relating_type, is_untyped, element_filter)
|
||||
spatial.select_products(elements)
|
||||
|
||||
|
||||
|
||||
@@ -233,6 +233,7 @@ class Spatial(bonsai.core.tool.Spatial):
|
||||
new2 = props.elements.add()
|
||||
new2.is_type = True
|
||||
new2.name = results[ifc_class][ifc_definition_id]["type_name"]
|
||||
new2.ifc_class = ifc_class
|
||||
new2.total = results[ifc_class][ifc_definition_id]["total"]
|
||||
new2.ifc_definition_id = ifc_definition_id
|
||||
total += new2.total
|
||||
@@ -242,18 +243,32 @@ class Spatial(bonsai.core.tool.Spatial):
|
||||
props.total_elements = total_elements
|
||||
|
||||
@classmethod
|
||||
def filter_elements_by_class(cls, elements: List[ifcopenshell.entity_instance], ifc_class: str):
|
||||
return [e for e in elements if e.is_a(ifc_class)]
|
||||
|
||||
@classmethod
|
||||
def filter_elements_by_relating_type(
|
||||
cls, elements: List[ifcopenshell.entity_instance], relating_type: ifcopenshell.entity_instance
|
||||
):
|
||||
return [e for e in elements if ifcopenshell.util.element.get_type(e) == relating_type]
|
||||
|
||||
@classmethod
|
||||
def filter_elements_by_untyped(cls, elements: List[ifcopenshell.entity_instance]):
|
||||
return [e for e in elements if not ifcopenshell.util.element.get_type(e)]
|
||||
def filter_elements(
|
||||
cls,
|
||||
elements: List[ifcopenshell.entity_instance],
|
||||
ifc_class: str | None,
|
||||
relating_type: ifcopenshell.entity_instance | None,
|
||||
is_untyped: bool | None,
|
||||
keyword: str | None,
|
||||
) -> filter[ifcopenshell.entity_instance]:
|
||||
keyword = keyword.lower() if keyword else keyword
|
||||
def filter_element(element):
|
||||
if ifc_class:
|
||||
if not element.is_a(ifc_class):
|
||||
return False
|
||||
element_type = ifcopenshell.util.element.get_type(element)
|
||||
if relating_type:
|
||||
if relating_type != element_type:
|
||||
return False
|
||||
if is_untyped:
|
||||
if element_type is not None:
|
||||
return False
|
||||
if keyword:
|
||||
type_name = getattr(element_type, "Name", "") or ""
|
||||
if keyword not in f"{element.is_a()} {type_name}".lower():
|
||||
return False
|
||||
return True
|
||||
return filter(filter_element, elements)
|
||||
|
||||
@classmethod
|
||||
def import_spatial_decomposition(cls) -> None:
|
||||
|
||||
Reference in New Issue
Block a user