diff --git a/src/blenderbim/blenderbim/bim/module/geometry/__init__.py b/src/blenderbim/blenderbim/bim/module/geometry/__init__.py index 5766368c50..d8c7b4b8ee 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/__init__.py @@ -22,7 +22,9 @@ from . import ui, prop, operator classes = ( operator.AddRepresentation, operator.CopyRepresentation, + operator.DisableEditingRepresentationItems, operator.EditObjectPlacement, + operator.EnableEditingRepresentationItems, operator.FlipObject, operator.GetRepresentationIfcParameters, operator.OverrideDelete, @@ -47,16 +49,19 @@ classes = ( operator.SwitchRepresentation, operator.UpdateParametricRepresentation, operator.UpdateRepresentation, + prop.RepresentationItem, prop.BIMObjectGeometryProperties, prop.BIMGeometryProperties, ui.BIM_PT_placement, ui.BIM_PT_representations, + ui.BIM_PT_representation_items, ui.BIM_PT_connections, ui.BIM_PT_mesh, ui.BIM_PT_derived_coordinates, ui.BIM_PT_workarounds, ui.BIM_MT_object_set_origin, ui.BIM_MT_separate, + ui.BIM_UL_representation_items, ) diff --git a/src/blenderbim/blenderbim/bim/module/geometry/data.py b/src/blenderbim/blenderbim/bim/module/geometry/data.py index b5536fa53a..bdf7e53a09 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/data.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/data.py @@ -26,6 +26,7 @@ def refresh(): PlacementData.is_loaded = False DerivedCoordinatesData.is_loaded = False RepresentationsData.is_loaded = False + RepresentationItemsData.is_loaded = False ConnectionsData.is_loaded = False @@ -92,6 +93,34 @@ class RepresentationsData: return results +class RepresentationItemsData: + data = {} + is_loaded = False + + @classmethod + def load(cls): + cls.data = {"total_items": cls.total_items()} + cls.is_loaded = True + + @classmethod + def total_items(cls): + active_representation_id = None + result = 0 + if bpy.context.active_object.data and hasattr(bpy.context.active_object.data, "BIMMeshProperties"): + active_representation_id = bpy.context.active_object.data.BIMMeshProperties.ifc_definition_id + element = tool.Ifc.get().by_id(active_representation_id) + if not element.is_a("IfcShapeRepresentation"): + return 0 + queue = list(element.Items) + while queue: + item = queue.pop() + if item.is_a("IfcMappedItem"): + queue.extend(item.MappingSource.MappedRepresentation.Items) + else: + result += 1 + return result + + class ConnectionsData: data = {} is_loaded = False diff --git a/src/blenderbim/blenderbim/bim/module/geometry/operator.py b/src/blenderbim/blenderbim/bim/module/geometry/operator.py index 723cd2f4b7..caf7c54dd8 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/operator.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/operator.py @@ -1727,3 +1727,53 @@ class FlipObject(bpy.types.Operator): for obj in context.selected_objects: tool.Geometry.flip_object(obj, self.flip_local_axes) return {"FINISHED"} + + +class EnableEditingRepresentationItems(bpy.types.Operator, Operator): + bl_idname = "bim.enable_editing_representation_items" + bl_label = "Enable Editing Representation Items" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + obj = context.active_object + + props = obj.BIMGeometryProperties + props.is_editing = True + + props.items.clear() + + if bpy.context.active_object.data and hasattr(bpy.context.active_object.data, "BIMMeshProperties"): + active_representation_id = bpy.context.active_object.data.BIMMeshProperties.ifc_definition_id + element = tool.Ifc.get().by_id(active_representation_id) + if not element.is_a("IfcShapeRepresentation"): + return + queue = list(element.Items) + while queue: + item = queue.pop() + if item.is_a("IfcMappedItem"): + queue.extend(item.MappingSource.MappedRepresentation.Items) + else: + new = props.items.add() + new.name = item.is_a() + new.ifc_definition_id = item.id() + + styles = [] + for inverse in tool.Ifc.get().get_inverse(item): + if inverse.is_a("IfcStyledItem"): + styles = inverse.Styles + if styles and styles[0].is_a("IfcPresentationStyleAssignment"): + styles = styles[0].Styles + for style in styles: + if style.is_a("IfcSurfaceStyle"): + new.surface_style = style.Name or "Unnamed" + break + + +class DisableEditingRepresentationItems(bpy.types.Operator, Operator): + bl_idname = "bim.disable_editing_representation_items" + bl_label = "Disable Editing Representation Items" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + obj = context.active_object + obj.BIMGeometryProperties.is_editing = False diff --git a/src/blenderbim/blenderbim/bim/module/geometry/prop.py b/src/blenderbim/blenderbim/bim/module/geometry/prop.py index e3fbd5517b..ae16daa751 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/prop.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/prop.py @@ -38,8 +38,17 @@ def get_contexts(self, context): return RepresentationsData.data["contexts"] +class RepresentationItem(PropertyGroup): + name: StringProperty(name="Name") + surface_style: StringProperty(name="Surface Style") + ifc_definition_id: IntProperty(name="IFC Definition ID") + + class BIMObjectGeometryProperties(PropertyGroup): contexts: EnumProperty(items=get_contexts, name="Contexts") + is_editing: BoolProperty(name="Is Editing", default=False) + items: CollectionProperty(name="Representation Items", type=RepresentationItem) + active_item_index: IntProperty(name="Active Representation Item Index") class BIMGeometryProperties(PropertyGroup): diff --git a/src/blenderbim/blenderbim/bim/module/geometry/ui.py b/src/blenderbim/blenderbim/bim/module/geometry/ui.py index 6be3897dca..a824dcf895 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/ui.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/ui.py @@ -18,11 +18,12 @@ import bpy import blenderbim.tool as tool -from bpy.types import Panel, Menu +from bpy.types import Panel, Menu, UIList from blenderbim.bim.ifc import IfcStore from blenderbim.bim.helper import prop_with_search from blenderbim.bim.module.geometry.data import ( RepresentationsData, + RepresentationItemsData, ConnectionsData, PlacementData, DerivedCoordinatesData, @@ -129,6 +130,41 @@ class BIM_PT_representations(Panel): row.operator("bim.remove_representation", icon="X", text="").representation_id = representation["id"] +class BIM_PT_representation_items(Panel): + bl_label = "Representation Items" + bl_idname = "BIM_PT_representation_items" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + bl_order = 1 + bl_parent_id = "BIM_PT_tab_representations" + + @classmethod + def poll(cls, context): + if not context.active_object: + return False + if not IfcStore.get_element(context.active_object.BIMObjectProperties.ifc_definition_id): + return False + return IfcStore.get_file() + + def draw(self, context): + if not RepresentationItemsData.is_loaded: + RepresentationItemsData.load() + + props = context.active_object.BIMGeometryProperties + + row = self.layout.row(align=True) + row.label(text=f"{RepresentationItemsData.data['total_items']} Items Found") + + if props.is_editing: + row.operator("bim.disable_editing_representation_items", icon="CANCEL", text="") + else: + row.operator("bim.enable_editing_representation_items", icon="IMPORT", text="") + return + + self.layout.template_list("BIM_UL_representation_items", "", props, "items", props, "active_item_index") + + class BIM_PT_connections(Panel): bl_label = "Connections" bl_idname = "BIM_PT_connections" @@ -267,7 +303,7 @@ class BIM_PT_mesh(Panel): row.prop(ifc_parameter, "name", text="") row.prop(ifc_parameter, "value", text="") row.operator("bim.update_parametric_representation", icon="FILE_REFRESH", text="").index = index - + class BIM_PT_placement(Panel): bl_label = "Placement" @@ -327,7 +363,7 @@ class BIM_PT_derived_coordinates(Panel): row.label(text="XYZ Dimensions") row = self.layout.row(align=True) - row.enabled=False + row.enabled = False row.prop(context.active_object, "dimensions", text="X", index=0, slider=True) row.prop(context.active_object, "dimensions", text="Y", index=1, slider=True) row.prop(context.active_object, "dimensions", text="Z", index=2, slider=True) @@ -379,3 +415,13 @@ class BIM_PT_workarounds(Panel): row.prop(props, "should_force_triangulation") row = self.layout.row() row.prop(props, "should_use_presentation_style_assignment") + + +class BIM_UL_representation_items(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + if item: + icon = "MATERIAL" if item.surface_style else "MESH_UVSPHERE" + row = layout.row(align=True) + row.label(text=item.name, icon=icon) + if item.surface_style: + row.label(text=item.surface_style)