mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-27 10:51:13 +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
|
return True
|
||||||
|
|
||||||
def _execute(self, context):
|
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()
|
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)
|
||||||
tool.Geometry.remove_representation_item(representation_item)
|
tool.Geometry.remove_representation_item(representation_item, element)
|
||||||
tool.Geometry.reload_representation(obj)
|
tool.Geometry.reload_representation(obj)
|
||||||
|
|
||||||
# reload items ui
|
# reload items ui
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete_ifc_item(cls, obj: bpy.types.Object) -> None:
|
def delete_ifc_item(cls, obj: bpy.types.Object) -> None:
|
||||||
|
"""Delete IfcRepresentationItem's Object."""
|
||||||
props = tool.Geometry.get_geometry_props()
|
props = tool.Geometry.get_geometry_props()
|
||||||
if len(props.item_objs) == 1:
|
if len(props.item_objs) == 1:
|
||||||
return
|
return
|
||||||
@@ -212,7 +213,9 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
mesh = obj.data
|
mesh = obj.data
|
||||||
assert isinstance(mesh, bpy.types.Mesh)
|
assert isinstance(mesh, bpy.types.Mesh)
|
||||||
item = tool.Ifc.get().by_id(tool.Geometry.get_mesh_props(mesh).ifc_definition_id)
|
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)
|
cls.reload_representation(props.representation_obj)
|
||||||
bpy.data.objects.remove(obj)
|
bpy.data.objects.remove(obj)
|
||||||
|
|
||||||
@@ -1344,12 +1347,19 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@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
|
# NOTE: we assume it's not the last representation item
|
||||||
# otherwise we probably would need to remove representation too
|
# otherwise we probably would need to remove representation too
|
||||||
# NOTE: a lot of shared code with `geometry.remove_representation`
|
# NOTE: a lot of shared code with `geometry.remove_representation`
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
shape_aspects = []
|
shape_aspects: list[ifcopenshell.entity_instance] = []
|
||||||
|
|
||||||
consider_inverses = []
|
consider_inverses = []
|
||||||
styled_item, colour, texture, layer = None, None, None, None
|
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", [])]
|
[consider_inverses.append(texture := t) for t in getattr(representation_item, "HasTextures", [])]
|
||||||
|
|
||||||
representation = None
|
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):
|
for inverse in ifc_file.get_inverse(representation_item):
|
||||||
if inverse.is_a("IfcShapeRepresentation"):
|
if inverse.is_a("IfcShapeRepresentation"):
|
||||||
if inverse.OfShapeAspect:
|
if inverse.OfShapeAspect:
|
||||||
@@ -1409,11 +1419,9 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
also_consider = list(consider_inverses)
|
also_consider = list(consider_inverses)
|
||||||
ifcopenshell.util.element.remove_deep2(ifc_file, representation_item, also_consider=also_consider)
|
ifcopenshell.util.element.remove_deep2(ifc_file, representation_item, also_consider=also_consider)
|
||||||
|
|
||||||
props = tool.Geometry.get_geometry_props()
|
tool.Model.unmark_manual_booleans(element, [b.id() for b in boolean_results_to_remove])
|
||||||
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])
|
|
||||||
for boolean_result 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
|
@classmethod
|
||||||
def create_shape_aspect(
|
def create_shape_aspect(
|
||||||
|
|||||||
@@ -687,8 +687,12 @@ class Model(bonsai.core.tool.Model):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def unmark_manual_booleans(cls, element: ifcopenshell.entity_instance, boolean_ids: list[int]) -> None:
|
def unmark_manual_booleans(cls, element: ifcopenshell.entity_instance, boolean_ids: list[int]) -> None:
|
||||||
# NOTE: we use use boolean_ids instead of boolean entities
|
"""Remove boolean ids from ``element``'s 'BBIM_Boolean' pset.
|
||||||
# so it will be possible to unmark manual booleans after they already was deleted
|
|
||||||
|
: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")
|
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
|
||||||
if not pset:
|
if not pset:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import bpy
|
|||||||
import math
|
import math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
import ifcopenshell.api.geometry
|
||||||
import ifcopenshell.api.type
|
import ifcopenshell.api.type
|
||||||
import bonsai.core.tool
|
import bonsai.core.tool
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
@@ -606,13 +607,13 @@ class TestRemoveRepresentationItem(NewFile):
|
|||||||
|
|
||||||
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
|
items = [ifc.createIfcExtrudedAreaSolid(), ifc.createIfcExtrudedAreaSolid()]
|
||||||
representation = ifc.createIfcShapeRepresentation(Items=items, ContextOfItems=context)
|
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
|
product_shape = element.Representation
|
||||||
shape_aspect = subject.create_shape_aspect(product_shape, representation, items[:1], None)
|
shape_aspect = subject.create_shape_aspect(product_shape, representation, items[:1], None)
|
||||||
shape_aspect_id = shape_aspect.id()
|
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 tool.Ifc.get_entity_by_id(shape_aspect_id) is None
|
||||||
assert set(representation.Items) == {items[1]}
|
assert set(representation.Items) == {items[1]}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user