selector.set_element_value to support 'predefined_type' keyword

See more details in https://community.osarch.org/discussion/comment/22134/#Comment_22134
This commit is contained in:
Andrej730
2024-09-06 17:35:31 +05:00
parent 39fd9ce462
commit 871cd45f53
2 changed files with 86 additions and 3 deletions
@@ -21,6 +21,7 @@ import lark
import numpy as np import numpy as np
import ifcopenshell.api.pset import ifcopenshell.api.pset
import ifcopenshell.api.geometry import ifcopenshell.api.geometry
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util import ifcopenshell.util
import ifcopenshell.util.attribute import ifcopenshell.util.attribute
import ifcopenshell.util.fm import ifcopenshell.util.fm
@@ -508,9 +509,40 @@ def set_element_value(
elif key == "id": elif key == "id":
return return
elif key == "predefined_type": elif key == "predefined_type":
print( current_value = ifcopenshell.util.element.get_predefined_type(element)
f"WARNING. Assigning 'predefined_type' is not yet supported. Skipping value '{value}' for element: '{element}'." if current_value == value:
) return
def set_predefined_type(
element: ifcopenshell.entity_instance, value: Union[str, None], *, is_type: bool
) -> None:
predefined_type = element.PredefinedType
declaration = element.wrapped_data.declaration()
entity = declaration.as_entity()
enum_attr = next(attr for attr in entity.attributes() if attr.name() == "PredefinedType")
enum_items = ifcopenshell.util.attribute.get_enum_items(enum_attr)
# USERDEFINED shouldn't occur here, if it does then it means
# then it was artificially added and PredefinedType is actually unset.
if value in (None, "NOTDEFINED", "USERDEFINED"):
element.PredefinedType = "NOTDEFINED"
setattr(element, "ElementType" if is_type else "ObjectType", None)
elif value in enum_items:
if predefined_type == value:
return
element.PredefinedType = value
return
# Value not in PredefinedType enum items.
if predefined_type != "USERDEFINED":
element.PredefinedType = "USERDEFINED"
setattr(element, "ElementType" if is_type else "ObjectType", value)
return
if element_type := ifcopenshell.util.element.get_type(element):
set_predefined_type(element_type, value, is_type=True)
return
set_predefined_type(element, value, is_type=False)
return return
elif key == "classification": elif key == "classification":
element = ifcopenshell.util.classification.get_references(element) element = ifcopenshell.util.classification.get_references(element)
@@ -28,6 +28,7 @@ import ifcopenshell.api.material
import ifcopenshell.api.geometry import ifcopenshell.api.geometry
import ifcopenshell.api.aggregate import ifcopenshell.api.aggregate
import ifcopenshell.api.group import ifcopenshell.api.group
import ifcopenshell.api.sequence
import ifcopenshell.util.selector as subject import ifcopenshell.util.selector as subject
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.pset import ifcopenshell.util.pset
@@ -352,3 +353,53 @@ class TestSetElementValue(test.bootstrap.IFC4):
layer.Material = material layer.Material = material
subject.set_element_value(self.file, layer, "Material.Name", "Foo") subject.set_element_value(self.file, layer, "Material.Name", "Foo")
assert material.Name == "Foo" assert material.Name == "Foo"
class TestSetElementValuePredefinedType(test.bootstrap.IFC4):
def test_setting_an_element_predefined_type(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindow")
subject.set_element_value(self.file, element, "predefined_type", "LIGHTDOME")
assert element.PredefinedType == "LIGHTDOME"
assert element.ObjectType == None
def test_setting_an_element_predefined_type_to_none(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindow")
subject.set_element_value(self.file, element, "predefined_type", None)
assert element.PredefinedType == None
assert element.ObjectType == None
def test_setting_an_element_userdefined_type(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindow")
subject.set_element_value(self.file, element, "predefined_type", "FOOBAR")
assert element.PredefinedType == "USERDEFINED"
assert element.ObjectType == "FOOBAR"
def test_setting_an_element_inherited_predefined_type(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindow")
element_type = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindowType")
ifcopenshell.api.type.assign_type(self.file, related_objects=[element], relating_type=element_type)
subject.set_element_value(self.file, element, "predefined_type", "LIGHTDOME")
assert element_type.PredefinedType == "LIGHTDOME"
assert element_type.ElementType == None
assert element.PredefinedType == None
assert element.ObjectType == None
def test_setting_an_element_inherited_predefined_type_to_none(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindow")
element_type = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindowType")
ifcopenshell.api.type.assign_type(self.file, related_objects=[element], relating_type=element_type)
subject.set_element_value(self.file, element, "predefined_type", None)
assert element_type.PredefinedType == "NOTDEFINED"
assert element_type.ElementType == None
assert element.PredefinedType == None
assert element.ObjectType == None
def test_setting_an_element_inherited_userdefined_type(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindow")
element_type = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWindowType")
ifcopenshell.api.type.assign_type(self.file, related_objects=[element], relating_type=element_type)
subject.set_element_value(self.file, element, "predefined_type", "FOOBAR")
assert element_type.PredefinedType == "USERDEFINED"
assert element_type.ElementType == "FOOBAR"
assert element.PredefinedType == None
assert element.ObjectType == None