mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Fix failing product assignment test after 5a511ee
Moved code from `core`, added a warning so we could possibly narrow down #4014 in the future.
This commit is contained in:
@@ -61,20 +61,17 @@ def edit_assigned_product(
|
||||
element = ifc.get_entity(obj)
|
||||
assert element
|
||||
|
||||
# Get ALL existing products, not just one
|
||||
existing_products = []
|
||||
if hasattr(element, "HasAssignments"):
|
||||
for rel in element.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToProduct"):
|
||||
existing_products.append(rel.RelatingProduct)
|
||||
# Temporarily accomodate existing bug and check for multiple products.
|
||||
existing_products = drawing.get_assigned_product_workaround(element)
|
||||
if existing_products != [product]:
|
||||
|
||||
if product in existing_products:
|
||||
assert product is not None
|
||||
existing_products.remove(product)
|
||||
|
||||
# Only proceed if the assignment is different
|
||||
if not (len(existing_products) == 1 and existing_products[0] == product):
|
||||
# Unassign from ALL existing products
|
||||
for existing_product in existing_products:
|
||||
ifc.run("drawing.unassign_product", relating_product=existing_product, related_object=element)
|
||||
|
||||
# Assign to the new product
|
||||
if product:
|
||||
ifc.run("drawing.assign_product", relating_product=product, related_object=element)
|
||||
|
||||
|
||||
@@ -343,6 +343,7 @@ class Drawing:
|
||||
def get_annotation_context(cls, target_view, object_type=None): pass
|
||||
def get_annotation_representation(cls, element_type): pass
|
||||
def get_assigned_product(cls, element): pass
|
||||
def get_assigned_product_workaround(cls, element): pass
|
||||
def get_body_context(cls): pass
|
||||
def get_default_drawing_path(cls, name): pass
|
||||
def get_default_drawing_resource_path(cls, resource): pass
|
||||
|
||||
@@ -893,6 +893,33 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
return axis
|
||||
return product
|
||||
|
||||
@classmethod
|
||||
def get_assigned_product_workaround(
|
||||
cls, element: ifcopenshell.entity_instance
|
||||
) -> list[ifcopenshell.entity_instance]:
|
||||
"""Get all products assigned to the element.
|
||||
|
||||
A workaround allowing to unassign accumulated products until we properly resolve #4014.
|
||||
In theory annotations should have more than one product assigned,
|
||||
but there's still undefined bug causing that in some cases.
|
||||
"""
|
||||
|
||||
assigned_products: list[ifcopenshell.entity_instance] = []
|
||||
for rel in element.HasAssignments:
|
||||
if not rel.is_a("IfcRelAssignsToProduct"):
|
||||
continue
|
||||
assigned_products.append(rel.RelatingProduct)
|
||||
|
||||
if len(assigned_products) > 1:
|
||||
print(
|
||||
f"WARNING. Detected multiple assigned products ({len(assigned_products)}) for annotation '{element}'."
|
||||
"\nIf you can reproduce this, please report it to Bonsai developers "
|
||||
"at https://github.com/IfcOpenShell/IfcOpenShell/issues/4014."
|
||||
"\nAssigned products:\n" + "\n".join([str(p) for p in assigned_products])
|
||||
)
|
||||
|
||||
return assigned_products
|
||||
|
||||
@classmethod
|
||||
def import_annotations_in_group(cls, group: ifcopenshell.entity_instance) -> None:
|
||||
elements = set(
|
||||
|
||||
@@ -58,7 +58,7 @@ class TestDisableEditingAssignedProduct:
|
||||
class TestEditAssignedProduct:
|
||||
def test_text_annotation(self, ifc, drawing):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
drawing.get_assigned_product("element").should_be_called().will_return("existing_product")
|
||||
drawing.get_assigned_product_workaround("element").should_be_called().will_return(["existing_product"])
|
||||
ifc.run(
|
||||
"drawing.unassign_product", relating_product="existing_product", related_object="element"
|
||||
).should_be_called()
|
||||
@@ -68,7 +68,7 @@ class TestEditAssignedProduct:
|
||||
|
||||
def test_non_text_annotation(self, ifc, drawing):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
drawing.get_assigned_product("element").should_be_called().will_return("existing_product")
|
||||
drawing.get_assigned_product_workaround("element").should_be_called().will_return(["existing_product"])
|
||||
ifc.run(
|
||||
"drawing.unassign_product", relating_product="existing_product", related_object="element"
|
||||
).should_be_called()
|
||||
|
||||
Reference in New Issue
Block a user