mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-18 14:31:39 +00:00
Fix #6640. Fix invalid association of annotations to grids.
There was already some half written code with this intent it seems, so I just finished it up.
This commit is contained in:
@@ -1342,17 +1342,32 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
) -> Union[ifcopenshell.entity_instance, bool, None]:
|
) -> Union[ifcopenshell.entity_instance, bool, None]:
|
||||||
if drawing == reference_element:
|
if drawing == reference_element:
|
||||||
return True
|
return True
|
||||||
|
if reference_element.is_a("IfcGridAxis"):
|
||||||
|
# We cannot associate IfcGridAxis directly, so we establish a convention:
|
||||||
|
# IfcRelAssignsToProduct.RelatingProduct = IfcGrid
|
||||||
|
# IfcRelAssignsToProduct.Name = IfcGridAxis.AxisTag
|
||||||
|
grid = None
|
||||||
|
for attribute in ("PartOfW", "PartOfV", "PartOfU"):
|
||||||
|
if getattr(reference_element, attribute, None):
|
||||||
|
grid = getattr(reference_element, attribute)[0]
|
||||||
|
break
|
||||||
|
|
||||||
|
for element in cls.get_group_elements(cls.get_drawing_group(drawing)):
|
||||||
|
if not element.is_a("IfcAnnotation"):
|
||||||
|
continue
|
||||||
|
for rel in element.HasAssignments:
|
||||||
|
if (
|
||||||
|
rel.is_a("IfcRelAssignsToProduct")
|
||||||
|
and rel.RelatingProduct == grid
|
||||||
|
and rel.Name == reference_element.AxisTag
|
||||||
|
):
|
||||||
|
return element
|
||||||
|
return
|
||||||
for element in cls.get_group_elements(cls.get_drawing_group(drawing)):
|
for element in cls.get_group_elements(cls.get_drawing_group(drawing)):
|
||||||
if element.is_a("IfcAnnotation"):
|
if element.is_a("IfcAnnotation"):
|
||||||
for rel in element.HasAssignments:
|
for rel in element.HasAssignments:
|
||||||
if rel.is_a("IfcRelAssignsToProduct"):
|
if rel.is_a("IfcRelAssignsToProduct") and rel.RelatingProduct == reference_element:
|
||||||
if rel.RelatingProduct == reference_element:
|
return element
|
||||||
return element
|
|
||||||
# We cannot associate IfcGridAxis directly, so we establish a convention:
|
|
||||||
# IfcRelAssignsToProduct.RelatingProduct = IfcGrid
|
|
||||||
# IfcRelAssignsToProduct.Name = IfcGridAxis.AxisTag
|
|
||||||
elif reference_element.is_a("IfcGridAxis") and rel.Name == reference_element.AxisTag:
|
|
||||||
return element
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_reference_annotation(
|
def generate_reference_annotation(
|
||||||
|
|||||||
@@ -59,49 +59,47 @@ def assign_product(
|
|||||||
ifcopenshell.api.drawing.assign_product(model,
|
ifcopenshell.api.drawing.assign_product(model,
|
||||||
relating_product=furniture, related_object=annotation)
|
relating_product=furniture, related_object=annotation)
|
||||||
"""
|
"""
|
||||||
is_grid_axis = relating_product.is_a("IfcGridAxis")
|
if relating_product.is_a("IfcGridAxis"):
|
||||||
|
|
||||||
if is_grid_axis:
|
|
||||||
if related_object.HasAssignments:
|
|
||||||
for rel in related_object.HasAssignments:
|
|
||||||
if rel.is_a("IfcRelAssignsToProduct") and rel.Name == relating_product.AxisTag:
|
|
||||||
return
|
|
||||||
elif related_object.HasAssignments:
|
|
||||||
for rel in related_object.HasAssignments:
|
|
||||||
if rel.is_a("IfcRelAssignsToProduct") and rel.RelatingProduct == relating_product:
|
|
||||||
return
|
|
||||||
|
|
||||||
referenced_by = None
|
|
||||||
|
|
||||||
if is_grid_axis:
|
|
||||||
axis = relating_product
|
axis = relating_product
|
||||||
grid = None
|
grid = None
|
||||||
for attribute in ("PartOfW", "PartOfV", "PartOfU"):
|
for attribute in ("PartOfW", "PartOfV", "PartOfU"):
|
||||||
if getattr(axis, attribute, None):
|
if getattr(axis, attribute, None):
|
||||||
grid = getattr(axis, attribute)[0]
|
grid = getattr(axis, attribute)[0]
|
||||||
for rel in grid.ReferencedBy:
|
|
||||||
if rel.Name == axis.AxisTag:
|
|
||||||
referenced_by = rel
|
|
||||||
break
|
break
|
||||||
elif relating_product.ReferencedBy:
|
for rel in grid.ReferencedBy or []:
|
||||||
|
if rel.Name == axis.AxisTag and related_object in rel.RelatedObjects:
|
||||||
|
return
|
||||||
|
|
||||||
|
return file.create_entity(
|
||||||
|
"IfcRelAssignsToProduct",
|
||||||
|
GlobalId=ifcopenshell.guid.new(),
|
||||||
|
Name=axis.AxisTag,
|
||||||
|
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
|
||||||
|
RelatedObjects=[related_object],
|
||||||
|
RelatingProduct=grid,
|
||||||
|
)
|
||||||
|
|
||||||
|
if related_object.HasAssignments:
|
||||||
|
for rel in related_object.HasAssignments:
|
||||||
|
if rel.is_a("IfcRelAssignsToProduct") and rel.RelatingProduct == relating_product:
|
||||||
|
return
|
||||||
|
|
||||||
|
referenced_by = None
|
||||||
|
if relating_product.ReferencedBy:
|
||||||
referenced_by = relating_product.ReferencedBy[0]
|
referenced_by = relating_product.ReferencedBy[0]
|
||||||
|
|
||||||
if referenced_by:
|
if referenced_by:
|
||||||
related_objects = list(referenced_by.RelatedObjects)
|
related_objects = list(referenced_by.RelatedObjects)
|
||||||
related_objects.append(related_object)
|
related_objects.append(related_object)
|
||||||
referenced_by.RelatedObjects = related_objects
|
referenced_by.RelatedObjects = related_objects
|
||||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": referenced_by})
|
ifcopenshell.api.owner.update_owner_history(file, element=referenced_by)
|
||||||
else:
|
else:
|
||||||
referenced_by = file.create_entity(
|
referenced_by = file.create_entity(
|
||||||
"IfcRelAssignsToProduct",
|
"IfcRelAssignsToProduct",
|
||||||
**{
|
GlobalId=ifcopenshell.guid.new(),
|
||||||
"GlobalId": ifcopenshell.guid.new(),
|
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
|
||||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
RelatedObjects=[related_object],
|
||||||
"RelatedObjects": [related_object],
|
RelatingProduct=relating_product,
|
||||||
"RelatingProduct": relating_product,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_grid_axis:
|
|
||||||
referenced_by.Name = axis.AxisTag
|
|
||||||
return referenced_by
|
return referenced_by
|
||||||
|
|||||||
@@ -51,6 +51,14 @@ def unassign_product(
|
|||||||
ifcopenshell.api.drawing.unassign_product(model,
|
ifcopenshell.api.drawing.unassign_product(model,
|
||||||
relating_product=furniture, related_object=annotation)
|
relating_product=furniture, related_object=annotation)
|
||||||
"""
|
"""
|
||||||
|
if relating_product.is_a("IfcGridAxis"):
|
||||||
|
grid = None
|
||||||
|
for attribute in ("PartOfW", "PartOfV", "PartOfU"):
|
||||||
|
if getattr(relating_product, attribute, None):
|
||||||
|
grid = getattr(relating_product, attribute)[0]
|
||||||
|
break
|
||||||
|
relating_product = grid
|
||||||
|
|
||||||
for rel in related_object.HasAssignments or []:
|
for rel in related_object.HasAssignments or []:
|
||||||
if not rel.is_a("IfcRelAssignsToProduct") or rel.RelatingProduct != relating_product:
|
if not rel.is_a("IfcRelAssignsToProduct") or rel.RelatingProduct != relating_product:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -38,6 +38,17 @@ class TestAssignProduct(test.bootstrap.IFC4):
|
|||||||
assert len(wall.ReferencedBy) == 1
|
assert len(wall.ReferencedBy) == 1
|
||||||
assert wall.ReferencedBy[0].RelatedObjects == (label,)
|
assert wall.ReferencedBy[0].RelatedObjects == (label,)
|
||||||
|
|
||||||
|
def test_assigning_a_grid_axis(self):
|
||||||
|
axis = self.file.createIfcGridAxis(AxisTag="A")
|
||||||
|
grid = self.file.createIfcGrid(UAxes=[axis])
|
||||||
|
line = self.file.createIfcAnnotation()
|
||||||
|
ifcopenshell.api.drawing.assign_product(self.file, relating_product=axis, related_object=line)
|
||||||
|
assert grid.ReferencedBy[0].RelatedObjects == (line,)
|
||||||
|
assert grid.ReferencedBy[0].Name == "A"
|
||||||
|
assert len(self.file.by_type("IfcRelAssignsToProduct")) == 1
|
||||||
|
ifcopenshell.api.drawing.assign_product(self.file, relating_product=axis, related_object=line)
|
||||||
|
assert len(self.file.by_type("IfcRelAssignsToProduct")) == 1
|
||||||
|
|
||||||
|
|
||||||
class TestAssignProductIFC2X3(test.bootstrap.IFC2X3, TestAssignProduct):
|
class TestAssignProductIFC2X3(test.bootstrap.IFC2X3, TestAssignProduct):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ class TestUnassignProduct(test.bootstrap.IFC4):
|
|||||||
ifcopenshell.api.drawing.unassign_product(self.file, relating_product=wall, related_object=label)
|
ifcopenshell.api.drawing.unassign_product(self.file, relating_product=wall, related_object=label)
|
||||||
assert len(self.file.by_type("IfcRelAssignsToProduct")) == 0
|
assert len(self.file.by_type("IfcRelAssignsToProduct")) == 0
|
||||||
|
|
||||||
|
def test_unassigning_a_grid_axis(self):
|
||||||
|
axis = self.file.createIfcGridAxis(AxisTag="A")
|
||||||
|
grid = self.file.createIfcGrid(UAxes=[axis])
|
||||||
|
line = self.file.createIfcAnnotation()
|
||||||
|
ifcopenshell.api.drawing.assign_product(self.file, relating_product=axis, related_object=line)
|
||||||
|
ifcopenshell.api.drawing.unassign_product(self.file, relating_product=axis, related_object=line)
|
||||||
|
assert len(self.file.by_type("IfcRelAssignsToProduct")) == 0
|
||||||
|
|
||||||
|
|
||||||
class TestUnassignProductIFC2X3(test.bootstrap.IFC2X3, TestUnassignProduct):
|
class TestUnassignProductIFC2X3(test.bootstrap.IFC2X3, TestUnassignProduct):
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user