assign_type not to remap if it's type was assigned previously

This commit is contained in:
Andrej730
2024-04-11 14:00:49 +05:00
parent 949ff535eb
commit d6fb508517
2 changed files with 83 additions and 4 deletions
@@ -19,7 +19,7 @@
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
from typing import Union
from typing import Union, Iterable
class Usecase:
@@ -98,6 +98,7 @@ class Usecase:
IFC requires all occurrences to map those representations. Some IFC
vendors might disobey this, or you might want to handle it
yourself. In this scenario, you may set this to False.
This also enabled adding material usages mapping.
:type should_map_representations: bool
:return: The IfcRelDefinesByType relationship
or `None` if `related_objects` was empty list.
@@ -250,17 +251,17 @@ class Usecase:
if self.settings["should_map_representations"]:
if getattr(relating_type, "RepresentationMaps", None):
for related_object in related_objects:
for related_object in objects_to_change:
ifcopenshell.api.run(
"type.map_type_representations",
self.file,
related_object=related_object,
relating_type=relating_type,
)
self.map_material_usages(related_objects)
self.map_material_usages(objects_to_change)
return types
def map_material_usages(self, related_objects: set[ifcopenshell.entity_instance]) -> None:
def map_material_usages(self, related_objects: Iterable[ifcopenshell.entity_instance]) -> None:
type_material = ifcopenshell.util.element.get_material(self.settings["relating_type"])
if not type_material:
return
@@ -19,6 +19,7 @@
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.representation
import pytest
@@ -65,6 +66,83 @@ class TestAssignType(test.bootstrap.IFC4):
with pytest.raises(RuntimeError):
self.file.by_id(rel_id)
def test_map_representation_disabled(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
context = self.file.createIfcGeometricRepresentationContext()
rep = self.file.createIfcShapeRepresentation(ContextOfItems=context)
ifcopenshell.api.run("geometry.assign_representation", self.file, product=element_type, representation=rep)
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialLayerSet")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"type.assign_type",
self.file,
related_objects=[element],
relating_type=element_type,
should_map_representations=False,
)
# no representation mapping and no material usage
assert ifcopenshell.util.representation.get_representation(element, context=context) == None
assert ifcopenshell.util.element.get_material(element, should_inherit=False) == None
def test_map_representation(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
context = self.file.createIfcGeometricRepresentationContext()
rep = self.file.createIfcShapeRepresentation(ContextOfItems=context)
ifcopenshell.api.run("geometry.assign_representation", self.file, product=element_type, representation=rep)
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
mapped_rep = ifcopenshell.util.representation.get_representation(element, context=context)
assert mapped_rep.RepresentationType == "MappedRepresentation"
assert mapped_rep.Items[0].MappingSource.MappedRepresentation == rep
def test_map_representation(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
context = self.file.createIfcGeometricRepresentationContext()
rep = self.file.createIfcShapeRepresentation(ContextOfItems=context)
ifcopenshell.api.run("geometry.assign_representation", self.file, product=element_type, representation=rep)
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element1], relating_type=element_type)
assert (mapped_rep := ifcopenshell.util.representation.get_representation(element1, context=context))
mapped_rep_id = mapped_rep.id()
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"type.assign_type", self.file, related_objects=[element1, element2], relating_type=element_type
)
assert (mapped_rep := ifcopenshell.util.representation.get_representation(element1, context=context))
assert mapped_rep.id() == mapped_rep_id
def test_map_material_usages(self):
material_types = ("IfcMaterialLayerSet",)
if self.file.schema != "IFC2X3":
material_types += ("IfcMaterialProfileSet",)
for material_type in material_types:
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type=material_type)
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.util.element.get_material(element)
assert material
assert material.is_a(f"{material_type}Usage")
def test_do_not_reassign_material_if_it_was_assigned_previously(self):
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialLayerSet")
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element1], relating_type=element_type)
assert (material := ifcopenshell.util.element.get_material(element1))
material_id = material.id()
# use 2 elements to trigger material assignment code block
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"type.assign_type", self.file, related_objects=[element1, element2], relating_type=element_type
)
assert (material := ifcopenshell.util.element.get_material(element1))
assert material.id() == material_id
class TestAssignTypeIFC2X3(test.bootstrap.IFC2X3, TestAssignType):
pass