mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 10:33:20 +00:00
geometry.remove_representation_item - add element argument
Use explicit element argument instead of props.representation_obj as representation_obj may not be there (e.g. removing rep items without item mode) or some other object might be in item mode and then booleans won't be unmarked.
Found the issue because of the failing test 🥳
This commit is contained in:
@@ -2509,11 +2509,12 @@ class RemoveRepresentationItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return True
|
||||
|
||||
def _execute(self, context):
|
||||
obj = tool.Geometry.get_active_or_representation_obj()
|
||||
assert (obj := tool.Geometry.get_active_or_representation_obj())
|
||||
assert (element := tool.Ifc.get_entity(obj))
|
||||
ifc_file = tool.Ifc.get()
|
||||
|
||||
representation_item = ifc_file.by_id(self.representation_item_id)
|
||||
tool.Geometry.remove_representation_item(representation_item)
|
||||
tool.Geometry.remove_representation_item(representation_item, element)
|
||||
tool.Geometry.reload_representation(obj)
|
||||
|
||||
# reload items ui
|
||||
|
||||
@@ -202,6 +202,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
|
||||
@classmethod
|
||||
def delete_ifc_item(cls, obj: bpy.types.Object) -> None:
|
||||
"""Delete IfcRepresentationItem's Object."""
|
||||
props = tool.Geometry.get_geometry_props()
|
||||
if len(props.item_objs) == 1:
|
||||
return
|
||||
@@ -212,7 +213,9 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
mesh = obj.data
|
||||
assert isinstance(mesh, bpy.types.Mesh)
|
||||
item = tool.Ifc.get().by_id(tool.Geometry.get_mesh_props(mesh).ifc_definition_id)
|
||||
cls.remove_representation_item(item)
|
||||
rep_obj = props.representation_obj
|
||||
assert (rep_obj := props.representation_obj) and (rep_element := tool.Ifc.get_entity(rep_obj))
|
||||
cls.remove_representation_item(item, rep_element)
|
||||
cls.reload_representation(props.representation_obj)
|
||||
bpy.data.objects.remove(obj)
|
||||
|
||||
@@ -1344,12 +1347,19 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def remove_representation_item(cls, representation_item: ifcopenshell.entity_instance) -> None:
|
||||
def remove_representation_item(
|
||||
cls, representation_item: ifcopenshell.entity_instance, element: ifcopenshell.entity_instance
|
||||
) -> None:
|
||||
"""Remove IfcRepresentationItem.
|
||||
|
||||
:param representation_item: item to remove.
|
||||
:param element: item's element. Is used to unmark manual booleans.
|
||||
"""
|
||||
# NOTE: we assume it's not the last representation item
|
||||
# otherwise we probably would need to remove representation too
|
||||
# NOTE: a lot of shared code with `geometry.remove_representation`
|
||||
ifc_file = tool.Ifc.get()
|
||||
shape_aspects = []
|
||||
shape_aspects: list[ifcopenshell.entity_instance] = []
|
||||
|
||||
consider_inverses = []
|
||||
styled_item, colour, texture, layer = None, None, None, None
|
||||
@@ -1366,7 +1376,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
[consider_inverses.append(texture := t) for t in getattr(representation_item, "HasTextures", [])]
|
||||
|
||||
representation = None
|
||||
boolean_results_to_remove = set()
|
||||
boolean_results_to_remove: set[ifcopenshell.entity_instance] = set()
|
||||
for inverse in ifc_file.get_inverse(representation_item):
|
||||
if inverse.is_a("IfcShapeRepresentation"):
|
||||
if inverse.OfShapeAspect:
|
||||
@@ -1409,11 +1419,9 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
also_consider = list(consider_inverses)
|
||||
ifcopenshell.util.element.remove_deep2(ifc_file, representation_item, also_consider=also_consider)
|
||||
|
||||
props = tool.Geometry.get_geometry_props()
|
||||
rep_element = tool.Ifc.get_entity(props.representation_obj)
|
||||
tool.Model.unmark_manual_booleans(rep_element, [b.id() for b in boolean_results_to_remove])
|
||||
tool.Model.unmark_manual_booleans(element, [b.id() for b in boolean_results_to_remove])
|
||||
for boolean_result in boolean_results_to_remove:
|
||||
cls.remove_representation_item(boolean_result)
|
||||
cls.remove_representation_item(boolean_result, element)
|
||||
|
||||
@classmethod
|
||||
def create_shape_aspect(
|
||||
|
||||
@@ -687,8 +687,12 @@ class Model(bonsai.core.tool.Model):
|
||||
|
||||
@classmethod
|
||||
def unmark_manual_booleans(cls, element: ifcopenshell.entity_instance, boolean_ids: list[int]) -> None:
|
||||
# NOTE: we use use boolean_ids instead of boolean entities
|
||||
# so it will be possible to unmark manual booleans after they already was deleted
|
||||
"""Remove boolean ids from ``element``'s 'BBIM_Boolean' pset.
|
||||
|
||||
:param boolean_ids: List of boolean ids to remove.
|
||||
Ids are used instead of entities to make it possible to unmark already removed booleans.
|
||||
Provided ids may not be marked as manual booleans previously.
|
||||
"""
|
||||
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
|
||||
if not pset:
|
||||
return
|
||||
|
||||
@@ -20,6 +20,7 @@ import bpy
|
||||
import math
|
||||
import numpy as np
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.type
|
||||
import bonsai.core.tool
|
||||
import bonsai.tool as tool
|
||||
@@ -606,13 +607,13 @@ class TestRemoveRepresentationItem(NewFile):
|
||||
|
||||
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
|
||||
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context)
|
||||
tool.Ifc.run("geometry.assign_representation", product=element, representation=representation)
|
||||
ifcopenshell.api.geometry.assign_representation(ifc, product=element, representation=representation)
|
||||
|
||||
product_shape = element.Representation
|
||||
shape_aspect = subject.create_shape_aspect(product_shape, representation, items[:1], None)
|
||||
shape_aspect_id = shape_aspect.id()
|
||||
|
||||
subject.remove_representation_item(items[0])
|
||||
subject.remove_representation_item(items[0], element)
|
||||
assert tool.Ifc.get_entity_by_id(shape_aspect_id) is None
|
||||
assert set(representation.Items) == {items[1]}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user