mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Fixed issue reassigning class to type class with userdefined type #4018
When PredefinedType is not found in the related enum reassign_class is considering it USERDEFINED and trying to set .ObjectType. The problem was it was doing for type classes also, when it should have set .ElementType instead. Why it crashed BlenderBIM - in IfcClassData.data["has_entity"] we store currently active IFC entity which is recreated during `ifcopenshell.util.schema.reassign_class` making old entity invalid. Since `root.reassign_class` was failing in the process, related BBIM operator was failing too, IfcClassData wasn't updated and removed entity was accessed from UI leading to crash.
This commit is contained in:
@@ -73,13 +73,21 @@ class Usecase:
|
||||
element = ifcopenshell.util.schema.reassign_class(
|
||||
self.file, self.settings["product"], self.settings["ifc_class"]
|
||||
)
|
||||
is_type = element.is_a("IfcTypeProduct")
|
||||
if self.settings["predefined_type"] and hasattr(element, "PredefinedType"):
|
||||
try:
|
||||
element.PredefinedType = self.settings["predefined_type"]
|
||||
except:
|
||||
# PredefinedType wasn't in the respective enum, assume it's actually USERDEFINED
|
||||
# and set .ElementType / .ObjectType to the provided predefined type
|
||||
element.PredefinedType = "USERDEFINED"
|
||||
element.ObjectType = self.settings["predefined_type"]
|
||||
if element.is_a("IfcTypeProduct"):
|
||||
if is_type:
|
||||
element.ElementType = self.settings["predefined_type"]
|
||||
else:
|
||||
element.ObjectType = self.settings["predefined_type"]
|
||||
|
||||
# reassign classes for occurences connected to the type
|
||||
if is_type:
|
||||
for occurrence in ifcopenshell.util.element.get_types(element) or []:
|
||||
ifc_class = ifcopenshell.util.type.get_applicable_entities(self.settings["ifc_class"])[0]
|
||||
ifcopenshell.api.run(
|
||||
@@ -87,6 +95,6 @@ class Usecase:
|
||||
self.file,
|
||||
product=occurrence,
|
||||
ifc_class=ifc_class,
|
||||
predefined_type= self.settings["predefined_type"]
|
||||
predefined_type=self.settings["predefined_type"],
|
||||
)
|
||||
return element
|
||||
|
||||
@@ -35,10 +35,18 @@ class TestReassignClass(test.bootstrap.IFC4):
|
||||
)
|
||||
assert new.PredefinedType == "FLOOR"
|
||||
|
||||
def test_falling_back_to_userdefined_if_the_predefined_type_cannot_be_reassigned(self):
|
||||
def test_falling_back_to_userdefined_if_the_predefined_type_cannot_be_reassigned_for_occurrence_class(self):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||
new = ifcopenshell.api.run(
|
||||
"root.reassign_class", self.file, product=element, ifc_class="IfcSlab", predefined_type="FOO"
|
||||
)
|
||||
assert new.PredefinedType == "USERDEFINED"
|
||||
assert new.ObjectType == "FOO"
|
||||
|
||||
def test_falling_back_to_userdefined_if_the_predefined_type_cannot_be_reassigned_for_type_class(self):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
|
||||
new = ifcopenshell.api.run(
|
||||
"root.reassign_class", self.file, product=element, ifc_class="IfcSlabType", predefined_type="FOO"
|
||||
)
|
||||
assert new.PredefinedType == "USERDEFINED"
|
||||
assert new.ElementType == "FOO"
|
||||
|
||||
Reference in New Issue
Block a user