See #5973. Representation items UI now works in item mode.

This commit is contained in:
Dion Moult
2025-01-21 23:28:33 +11:00
parent 2452b1be50
commit b809bc89f0
7 changed files with 51 additions and 52 deletions
@@ -109,11 +109,12 @@ class RepresentationsData:
@classmethod @classmethod
def representations(cls): def representations(cls):
results = [] results = []
element = tool.Ifc.get_entity(bpy.context.active_object) obj = tool.Geometry.get_active_or_representation_obj()
element = tool.Ifc.get_entity(obj)
active_representation_id = None active_representation_id = None
if bpy.context.active_object.data and hasattr(bpy.context.active_object.data, "BIMMeshProperties"): if obj.data and hasattr(obj.data, "BIMMeshProperties"):
active_representation_id = bpy.context.active_object.data.BIMMeshProperties.ifc_definition_id active_representation_id = obj.data.BIMMeshProperties.ifc_definition_id
for representation in tool.Geometry.get_representations_iter(element): for representation in tool.Geometry.get_representations_iter(element):
representation_type = representation.RepresentationType representation_type = representation.RepresentationType
@@ -159,7 +160,7 @@ class RepresentationsData:
# Ignore objects without representations, e.g. IfcRelSpaceBoundary. # Ignore objects without representations, e.g. IfcRelSpaceBoundary.
if not cls.data["representations"]: if not cls.data["representations"]:
return [] return []
obj = bpy.context.active_object obj = tool.Geometry.get_active_or_representation_obj()
if not obj.data: if not obj.data:
return [] return []
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
@@ -192,7 +193,7 @@ class RepresentationItemsData:
@classmethod @classmethod
def total_items(cls) -> int: def total_items(cls) -> int:
result = 0 result = 0
obj = bpy.context.active_object obj = tool.Geometry.get_active_or_representation_obj()
assert obj assert obj
element = tool.Geometry.get_active_representation(obj) element = tool.Geometry.get_active_representation(obj)
if element: if element:
@@ -2314,7 +2314,7 @@ class EnableEditingRepresentationItems(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = tool.Geometry.get_active_or_representation_obj()
props = obj.BIMGeometryProperties props = obj.BIMGeometryProperties
props.is_editing = True props.is_editing = True
@@ -2326,8 +2326,8 @@ class EnableEditingRepresentationItems(bpy.types.Operator, tool.Ifc.Operator):
item.tags += "," item.tags += ","
item.tags += tag item.tags += tag
if bpy.context.active_object.data and hasattr(bpy.context.active_object.data, "BIMMeshProperties"): if obj.data and hasattr(obj.data, "BIMMeshProperties"):
active_representation_id = bpy.context.active_object.data.BIMMeshProperties.ifc_definition_id active_representation_id = obj.data.BIMMeshProperties.ifc_definition_id
element = tool.Ifc.get().by_id(active_representation_id) element = tool.Ifc.get().by_id(active_representation_id)
# IfcShapeRepresentation or IfcTopologyRepresentation. # IfcShapeRepresentation or IfcTopologyRepresentation.
if not element.is_a("IfcShapeModel"): if not element.is_a("IfcShapeModel"):
@@ -2376,7 +2376,7 @@ class DisableEditingRepresentationItems(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = tool.Geometry.get_active_or_representation_obj()
obj.BIMGeometryProperties.is_editing = False obj.BIMGeometryProperties.is_editing = False
@@ -2388,7 +2388,7 @@ class RemoveRepresentationItem(bpy.types.Operator, tool.Ifc.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
if context.active_object is None or len(context.active_object.BIMGeometryProperties.items) <= 1: if not (obj := tool.Geometry.get_active_or_representation_obj()) or len(obj.BIMGeometryProperties.items) <= 1:
cls.poll_message_set( cls.poll_message_set(
"Active object need to have more than 1 representation items to keep representation valid" "Active object need to have more than 1 representation items to keep representation valid"
) )
@@ -2396,7 +2396,7 @@ class RemoveRepresentationItem(bpy.types.Operator, tool.Ifc.Operator):
return True return True
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = tool.Geometry.get_active_or_representation_obj()
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
representation_item = ifc_file.by_id(self.representation_item_id) representation_item = ifc_file.by_id(self.representation_item_id)
@@ -2409,7 +2409,7 @@ class RemoveRepresentationItem(bpy.types.Operator, tool.Ifc.Operator):
def poll_editing_representation_item_style(cls, context): def poll_editing_representation_item_style(cls, context):
if not (obj := getattr(context, "active_object", None)): if not (obj := tool.Geometry.get_active_or_representation_obj()):
return False return False
props = obj.BIMGeometryProperties props = obj.BIMGeometryProperties
if not props.is_editing: if not props.is_editing:
@@ -2446,7 +2446,8 @@ class EnableEditingRepresentationItemStyle(bpy.types.Operator, tool.Ifc.Operator
return poll_editing_representation_item_style(cls, context) return poll_editing_representation_item_style(cls, context)
def _execute(self, context): def _execute(self, context):
props = context.active_object.BIMGeometryProperties obj = tool.Geometry.get_active_or_representation_obj()
props = obj.BIMGeometryProperties
props.is_editing_item_style = True props.is_editing_item_style = True
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
@@ -2464,7 +2465,7 @@ class EditRepresentationItemStyle(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = tool.Geometry.get_active_or_representation_obj()
props = obj.BIMGeometryProperties props = obj.BIMGeometryProperties
props.is_editing_item_style = False props.is_editing_item_style = False
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
@@ -2486,7 +2487,8 @@ class DisableEditingRepresentationItemStyle(bpy.types.Operator, tool.Ifc.Operato
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
props = context.active_object.BIMGeometryProperties obj = tool.Geometry.get_active_or_representation_obj()
props = obj.BIMGeometryProperties
props.is_editing_item_style = False props.is_editing_item_style = False
@@ -2501,7 +2503,7 @@ class UnassignRepresentationItemStyle(bpy.types.Operator, tool.Ifc.Operator):
return poll_editing_representation_item_style(cls, context) return poll_editing_representation_item_style(cls, context)
def _execute(self, context): def _execute(self, context):
active_obj = context.active_object active_obj = tool.Geometry.get_active_or_representation_obj()
active_props = active_obj.BIMGeometryProperties active_props = active_obj.BIMGeometryProperties
active_props.is_editing_item_style = False active_props.is_editing_item_style = False
@@ -2568,7 +2570,8 @@ class EnableEditingRepresentationItemShapeAspect(bpy.types.Operator, tool.Ifc.Op
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
props = context.active_object.BIMGeometryProperties obj = tool.Geometry.get_active_or_representation_obj()
props = obj.BIMGeometryProperties
props.is_editing_item_shape_aspect = True props.is_editing_item_shape_aspect = True
# set dropdown to currently active shape aspect # set dropdown to currently active shape aspect
@@ -2583,7 +2586,7 @@ class EditRepresentationItemShapeAspect(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = tool.Geometry.get_active_or_representation_obj()
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
props = obj.BIMGeometryProperties props = obj.BIMGeometryProperties
props.is_editing_item_shape_aspect = False props.is_editing_item_shape_aspect = False
@@ -2639,7 +2642,8 @@ class DisableEditingRepresentationItemShapeAspect(bpy.types.Operator, tool.Ifc.O
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
props = context.active_object.BIMGeometryProperties obj = tool.Geometry.get_active_or_representation_obj()
props = obj.BIMGeometryProperties
props.is_editing_item_shape_aspect = False props.is_editing_item_shape_aspect = False
@@ -2649,7 +2653,7 @@ class RemoveRepresentationItemFromShapeAspect(bpy.types.Operator, tool.Ifc.Opera
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = tool.Geometry.get_active_or_representation_obj()
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
props = obj.BIMGeometryProperties props = obj.BIMGeometryProperties
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
@@ -136,8 +136,8 @@ class ShapeAspect(PropertyGroup):
name: StringProperty( name: StringProperty(
name="Name", name="Name",
description=( description=(
"Note that IfcMaterialConstituent is applied based on shape aspects using the same name as material constituent.\n" "If applicable, shape aspect names should correlate with names of material constituents.\n"
"In dropdown suggestions you can see names of existing material constituents." "Click to see autocompletion for constituent names."
), ),
**({} if bpy.app.version < (3, 3, 0) else {"search": get_material_constituents}), **({} if bpy.app.version < (3, 3, 0) else {"search": get_material_constituents}),
) )
+12 -25
View File
@@ -119,25 +119,18 @@ class BIM_PT_representations(Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
if not context.active_object: return tool.Ifc.get() and (obj := tool.Blender.get_active_object()) and tool.Ifc.get_entity(obj)
return False
if not IfcStore.get_element(context.active_object.BIMObjectProperties.ifc_definition_id):
return False
return IfcStore.get_file()
def draw(self, context): def draw(self, context):
if not RepresentationsData.is_loaded: if not RepresentationsData.is_loaded:
RepresentationsData.load() RepresentationsData.load()
layout = self.layout row = self.layout.row(align=True)
props = context.active_object.BIMObjectProperties
row = layout.row(align=True)
prop_with_search(row, context.active_object.BIMGeometryProperties, "contexts", text="") prop_with_search(row, context.active_object.BIMGeometryProperties, "contexts", text="")
row.operator("bim.add_representation", icon="ADD", text="") row.operator("bim.add_representation", icon="ADD", text="")
if not RepresentationsData.data["representations"]: if not RepresentationsData.data["representations"]:
layout.label(text="No Representations Found") self.layout.label(text="No Representations Found")
return return
for representation in RepresentationsData.data["representations"]: for representation in RepresentationsData.data["representations"]:
@@ -156,18 +149,16 @@ class BIM_PT_representations(Panel):
op.ifc_definition_id = representation["id"] op.ifc_definition_id = representation["id"]
op.disable_opening_subtractions = False op.disable_opening_subtractions = False
row.operator("bim.remove_representation", icon="X", text="").representation_id = representation["id"] row.operator("bim.remove_representation", icon="X", text="").representation_id = representation["id"]
if representation["is_active"]:
active_representation = representation
layout.separator() self.layout.separator()
if not LayersData.is_loaded: if not LayersData.is_loaded:
LayersData.load() LayersData.load()
if LayersData.data["active_layers"]: if LayersData.data["active_layers"]:
layout.label(text="Representation Presentation Layers:") self.layout.label(text="Representation Presentation Layers:")
for layer_name in LayersData.data["active_layers"].values(): for layer_name in LayersData.data["active_layers"].values():
layout.label(text=layer_name, icon="STICKY_UVS_LOC") self.layout.label(text=layer_name, icon="STICKY_UVS_LOC")
else: else:
layout.label(text="Representation Has No Presentation Layers", icon="STICKY_UVS_LOC") self.layout.label(text="Representation Has No Presentation Layers", icon="STICKY_UVS_LOC")
class BIM_PT_representation_items(Panel): class BIM_PT_representation_items(Panel):
@@ -181,18 +172,14 @@ class BIM_PT_representation_items(Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
if not context.active_object: return tool.Ifc.get() and tool.Geometry.get_active_or_representation_obj()
return False
if not IfcStore.get_element(context.active_object.BIMObjectProperties.ifc_definition_id):
return False
return IfcStore.get_file()
def draw(self, context): def draw(self, context):
if not RepresentationItemsData.is_loaded: if not RepresentationItemsData.is_loaded:
RepresentationItemsData.load() RepresentationItemsData.load()
props = context.active_object.BIMGeometryProperties obj = context.scene.BIMGeometryProperties.representation_obj or tool.Blender.get_active_object()
layout = self.layout props = obj.BIMGeometryProperties
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text=f"{RepresentationItemsData.data['total_items']} Items Found") row.label(text=f"{RepresentationItemsData.data['total_items']} Items Found")
@@ -240,13 +227,13 @@ class BIM_PT_representation_items(Panel):
text = "Has UV mapping" text = "Has UV mapping"
else: else:
text = "Has no UV mapping" text = "Has no UV mapping"
layout.label(text=text, icon="UV") self.layout.label(text=text, icon="UV")
if "Colour" in active_item.tags: if "Colour" in active_item.tags:
text = "Has colour mapping" text = "Has colour mapping"
else: else:
text = "Has no colour mapping" text = "Has no colour mapping"
layout.label(text=text, icon="COLOR") self.layout.label(text=text, icon="COLOR")
row = self.layout.row(align=True) row = self.layout.row(align=True)
if props.is_editing_item_shape_aspect: if props.is_editing_item_shape_aspect:
@@ -175,7 +175,7 @@ class ObjectMaterialData:
@classmethod @classmethod
def material_class(cls) -> Union[str, None]: def material_class(cls) -> Union[str, None]:
element = tool.Ifc.get_entity(bpy.context.active_object) element = tool.Ifc.get_entity(tool.Geometry.get_active_or_representation_obj())
cls.material = ifcopenshell.util.element.get_material(element) cls.material = ifcopenshell.util.element.get_material(element)
if cls.material: if cls.material:
return cls.material.is_a() return cls.material.is_a()
@@ -338,7 +338,7 @@ class ObjectMaterialData:
@classmethod @classmethod
def type_material(cls): def type_material(cls):
element = tool.Ifc.get_entity(bpy.context.active_object) element = tool.Ifc.get_entity(tool.Geometry.get_active_or_representation_obj())
element_type = ifcopenshell.util.element.get_type(element) element_type = ifcopenshell.util.element.get_type(element)
if element_type and element_type != element: if element_type and element_type != element:
material = ifcopenshell.util.element.get_material(element_type) material = ifcopenshell.util.element.get_material(element_type)
+2 -3
View File
@@ -895,8 +895,7 @@ class BIM_PT_tab_representations(Panel):
return ( return (
tool.Blender.is_tab(context, "GEOMETRY") tool.Blender.is_tab(context, "GEOMETRY")
and tool.Ifc.get() and tool.Ifc.get()
and (obj := context.active_object) and tool.Geometry.get_active_or_representation_obj()
and tool.Ifc.get_entity(obj)
) )
def draw(self, context): def draw(self, context):
@@ -1234,6 +1233,7 @@ class BIM_PT_decorators_overlay(Panel):
row = col.row(align=True) row = col.row(align=True)
row.prop(model_props, "show_slab_direction", text="Slab Direction") row.prop(model_props, "show_slab_direction", text="Slab Direction")
class BIM_PT_snappping(Panel): class BIM_PT_snappping(Panel):
bl_space_type = "VIEW_3D" bl_space_type = "VIEW_3D"
bl_region_type = "HEADER" bl_region_type = "HEADER"
@@ -1252,4 +1252,3 @@ class BIM_PT_snappping(Panel):
col.prop(prop, "edge", toggle=True, icon="SNAP_EDGE") col.prop(prop, "edge", toggle=True, icon="SNAP_EDGE")
col.prop(prop, "edge_center", toggle=True, icon="SNAP_MIDPOINT") col.prop(prop, "edge_center", toggle=True, icon="SNAP_MIDPOINT")
col.prop(prop, "face", toggle=True, icon="SNAP_FACE") col.prop(prop, "face", toggle=True, icon="SNAP_FACE")
+8
View File
@@ -978,6 +978,14 @@ class Geometry(bonsai.core.tool.Geometry):
and tool.Ifc.get().by_id(ifc_id).is_a("IfcRepresentationItem") and tool.Ifc.get().by_id(ifc_id).is_a("IfcRepresentationItem")
) )
@classmethod
def get_active_or_representation_obj(cls) -> bpy.types.Object | None:
if obj := tool.Blender.get_active_object():
if tool.Ifc.get_entity(obj):
return obj
elif tool.Geometry.is_representation_item(obj):
return bpy.context.scene.BIMGeometryProperties.representation_obj
@classmethod @classmethod
def is_boolean_operand(cls, obj: bpy.types.Object) -> bool: def is_boolean_operand(cls, obj: bpy.types.Object) -> bool:
return bool( return bool(