diff --git a/src/blenderbim/blenderbim/bim/module/geometry/__init__.py b/src/blenderbim/blenderbim/bim/module/geometry/__init__.py index ae49984a51..27e6de0790 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/__init__.py @@ -53,6 +53,7 @@ classes = ( operator.EditRepresentationItemStyle, operator.DisableEditingRepresentationItemStyle, operator.UnassignRepresentationItemStyle, + operator.RemoveRepresentationItemFromShapeAspect, prop.RepresentationItem, prop.BIMObjectGeometryProperties, prop.BIMGeometryProperties, diff --git a/src/blenderbim/blenderbim/bim/module/geometry/operator.py b/src/blenderbim/blenderbim/bim/module/geometry/operator.py index 2d594abced..e8e7075cfb 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/operator.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/operator.py @@ -1601,6 +1601,7 @@ class EnableEditingRepresentationItems(bpy.types.Operator, Operator): if inverse.OfShapeAspect: shape_aspect = inverse.OfShapeAspect[0] new.shape_aspect = shape_aspect.Name + new.shape_aspect_id = shape_aspect.id() class DisableEditingRepresentationItems(bpy.types.Operator, Operator): @@ -1685,3 +1686,23 @@ class UnassignRepresentationItemStyle(bpy.types.Operator, Operator): # reload style ui bpy.ops.bim.disable_editing_representation_items() bpy.ops.bim.enable_editing_representation_items() + + +class RemoveRepresentationItemFromShapeAspect(bpy.types.Operator, Operator): + bl_idname = "bim.remove_representation_item_from_shape_aspect" + bl_label = "Remove Representation Item From Shape Aspect" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + obj = context.active_object + props = obj.BIMGeometryProperties + ifc_file = tool.Ifc.get() + + representation_item_id = props.items[props.active_item_index].ifc_definition_id + representation_item = ifc_file.by_id(representation_item_id) + shape_aspect = ifc_file.by_id(props.items[props.active_item_index].shape_aspect_id) + + tool.Geometry.remove_representation_item_from_shape_aspect(representation_item, shape_aspect) + # reload style ui + bpy.ops.bim.disable_editing_representation_items() + bpy.ops.bim.enable_editing_representation_items() diff --git a/src/blenderbim/blenderbim/bim/module/geometry/prop.py b/src/blenderbim/blenderbim/bim/module/geometry/prop.py index ff1a97c3d4..8877541044 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/prop.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/prop.py @@ -62,6 +62,7 @@ class RepresentationItem(PropertyGroup): layer: StringProperty(name="Layer") ifc_definition_id: IntProperty(name="IFC Definition ID") shape_aspect: StringProperty(name="Shape Aspect") + shape_aspect_id: IntProperty(name="Shape Aspect IFC ID") class BIMObjectGeometryProperties(PropertyGroup): diff --git a/src/blenderbim/blenderbim/bim/module/geometry/ui.py b/src/blenderbim/blenderbim/bim/module/geometry/ui.py index d736ac700f..20a711a6f2 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/ui.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/ui.py @@ -215,6 +215,8 @@ class BIM_PT_representation_items(Panel): row = self.layout.row() row.label(text=shape_aspect or "No Shape Aspect", icon="SHAPEKEY_DATA") + if shape_aspect: + row.operator("bim.remove_representation_item_from_shape_aspect", icon="X", text="") class BIM_PT_connections(Panel): diff --git a/src/blenderbim/blenderbim/tool/geometry.py b/src/blenderbim/blenderbim/tool/geometry.py index 9543fe2ce9..0f50c97068 100644 --- a/src/blenderbim/blenderbim/tool/geometry.py +++ b/src/blenderbim/blenderbim/tool/geometry.py @@ -730,3 +730,24 @@ class Geometry(blenderbim.core.tool.Geometry): should_sync_changes_first=False, apply_openings=True, ) + + @classmethod + def remove_representation_item_from_shape_aspect(cls, representation_item, shape_aspect): + ifc_file = tool.Ifc.get() + # as shape aspect might have multiple representations + # it's easier to find it from the item + for inverse in ifc_file.get_inverse(representation_item): + if inverse.is_a("IfcShapeRepresentation") and shape_aspect in inverse.OfShapeAspect: + representation = inverse + break + + # removing last item would make representation invalid + if len(representation.Items) == 1: + # removing last representation would make shape aspect invalid. + # remove shape aspect first otherwise remove_representation won't remove it because of the inverse + if len(shape_aspect.ShapeRepresentations) == 1: + ifc_file.remove(shape_aspect) + tool.Ifc.run("geometry.remove_representation", representation=representation) + else: + items = set(representation.Items) - {representation_item} + representation.Items = tuple(items)