mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-23 13:36:25 +00:00
Update IDS to support process types and require uppercase entities
This commit is contained in:
@@ -536,10 +536,7 @@ class entity(facet):
|
|||||||
:return: result of the validation as bool and message
|
:return: result of the validation as bool and message
|
||||||
:rtype: facet_evaluation(bool, str)
|
:rtype: facet_evaluation(bool, str)
|
||||||
"""
|
"""
|
||||||
if isinstance(self.name, str):
|
is_pass = inst.is_a().upper() == self.name
|
||||||
is_pass = inst.is_a().lower() == self.name.lower()
|
|
||||||
else:
|
|
||||||
is_pass = inst.is_a() == self.name
|
|
||||||
if is_pass and self.predefinedType:
|
if is_pass and self.predefinedType:
|
||||||
predefined_type = ifcopenshell.util.element.get_predefined_type(inst)
|
predefined_type = ifcopenshell.util.element.get_predefined_type(inst)
|
||||||
is_pass = predefined_type == self.predefinedType
|
is_pass = predefined_type == self.predefinedType
|
||||||
|
|||||||
@@ -344,13 +344,13 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
|
|
||||||
# Wrong IFC classes are never matched.
|
# Wrong IFC classes are never matched.
|
||||||
facet = ids.entity.create(name="IfcRabbit")
|
facet = ids.entity.create(name="IFCRABBIT")
|
||||||
case("Non-existent entity name", facet=facet, inst=ifc.createIfcWall(), expected=False)
|
case("Non-existent entity name", facet=facet, inst=ifc.createIfcWall(), expected=False)
|
||||||
|
|
||||||
# IFC class is checked for an exact match. Subclasses should not match.
|
# IFC class is checked for an exact match. Subclasses should not match.
|
||||||
# TODO: Some votes to prefer inheritance (For: Moult, Evandro, Artur)
|
# TODO: Some votes to prefer inheritance (For: Moult, Evandro, Artur)
|
||||||
# Possible argument: CAD tools don't understand IFC
|
# Possible argument: CAD tools don't understand IFC
|
||||||
facet = ids.entity.create(name="IfcWall")
|
facet = ids.entity.create(name="IFCWALL")
|
||||||
case("Entity matching", facet=facet, inst=ifc.createIfcWall(), expected=True)
|
case("Entity matching", facet=facet, inst=ifc.createIfcWall(), expected=True)
|
||||||
case(
|
case(
|
||||||
"Entity with PredefinedType", facet=facet, inst=ifc.createIfcWall(PredefinedType="SOLIDWALL"), expected=True
|
"Entity with PredefinedType", facet=facet, inst=ifc.createIfcWall(PredefinedType="SOLIDWALL"), expected=True
|
||||||
@@ -358,16 +358,13 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
case("Entity matching", facet=facet, inst=ifc.createIfcSlab(), expected=False)
|
case("Entity matching", facet=facet, inst=ifc.createIfcSlab(), expected=False)
|
||||||
case("Entity subtype", facet=facet, inst=ifc.createIfcWallStandardCase(), expected=False)
|
case("Entity subtype", facet=facet, inst=ifc.createIfcWallStandardCase(), expected=False)
|
||||||
|
|
||||||
# IFC class is case insensitive.
|
# IFC class is case sensitive and has to be uppercase.
|
||||||
# WRONG WRONG WRONG should be UPPERCASE
|
# TODO But in that case why are the enumerations for things like partOf using the IFC capitalisation?
|
||||||
# But in that case why are the enumerations for things like partOf using the IFC capitalisation?
|
facet = ids.entity.create(name="IfcWall")
|
||||||
facet = ids.entity.create(name="IFCWALL")
|
case("Entity case", facet=facet, inst=ifc.createIfcWall(), expected=False)
|
||||||
case("Entity case 0", facet=facet, inst=ifc.createIfcWall(), expected=True)
|
|
||||||
case("Entity case 1", facet=facet, inst=ifc.createIfcWall(PredefinedType="SOLIDWALL"), expected=True)
|
|
||||||
case("Entity case 2", facet=facet, inst=ifc.createIfcSlab(), expected=False)
|
|
||||||
|
|
||||||
# Predefined types are checked from standard enumeration values
|
# Predefined types are checked from standard enumeration values
|
||||||
facet = ids.entity.create(name="IfcWall", predefinedType="SOLIDWALL")
|
facet = ids.entity.create(name="IFCWALL", predefinedType="SOLIDWALL")
|
||||||
case("Entity PredefinedType 0", facet=facet, inst=ifc.createIfcWall(), expected=False)
|
case("Entity PredefinedType 0", facet=facet, inst=ifc.createIfcWall(), expected=False)
|
||||||
case("Entity PredefinedType 1", facet=facet, inst=ifc.createIfcWall(PredefinedType="SOLIDWALL"), expected=True)
|
case("Entity PredefinedType 1", facet=facet, inst=ifc.createIfcWall(PredefinedType="SOLIDWALL"), expected=True)
|
||||||
case(
|
case(
|
||||||
@@ -378,11 +375,11 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Predefined Type must be uppercase, exactly the same as defined in the enumeration
|
# Predefined Type must be uppercase, exactly the same as defined in the enumeration
|
||||||
facet = ids.entity.create(name="IfcWall", predefinedType="solidwall")
|
facet = ids.entity.create(name="IFCWALL", predefinedType="solidwall")
|
||||||
assert bool(facet(ifc.createIfcWall(PredefinedType="SOLIDWALL"))) is False
|
assert bool(facet(ifc.createIfcWall(PredefinedType="SOLIDWALL"))) is False
|
||||||
|
|
||||||
# Predefined types are checked from the object type field if not standard
|
# Predefined types are checked from the object type field if not standard
|
||||||
facet = ids.entity.create(name="IfcWall", predefinedType="WALDO")
|
facet = ids.entity.create(name="IFCWALL", predefinedType="WALDO")
|
||||||
case(
|
case(
|
||||||
"Entity user-defined type",
|
"Entity user-defined type",
|
||||||
facet=facet,
|
facet=facet,
|
||||||
@@ -391,7 +388,7 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Predefined types are checked from the element type field if not standard for types
|
# Predefined types are checked from the element type field if not standard for types
|
||||||
facet = ids.entity.create(name="IfcWallType", predefinedType="WALDO")
|
facet = ids.entity.create(name="IFCWALLTYPE", predefinedType="WALDO")
|
||||||
case(
|
case(
|
||||||
"Entity ElementType",
|
"Entity ElementType",
|
||||||
facet=facet,
|
facet=facet,
|
||||||
@@ -400,10 +397,16 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Predefined types are checked from the process type field if not standard for processes
|
# Predefined types are checked from the process type field if not standard for processes
|
||||||
# TODO
|
facet = ids.entity.create(name="IFCTASKTYPE", predefinedType="TASKY")
|
||||||
|
case(
|
||||||
|
"Entity ProcessType",
|
||||||
|
facet=facet,
|
||||||
|
inst=ifc.createIfcTaskType(PredefinedType="USERDEFINED", ProcessType="TASKY"),
|
||||||
|
expected=True,
|
||||||
|
)
|
||||||
|
|
||||||
# Userdefined is not an allowed filter because userdefined implies a specified object or element type
|
# Userdefined is not an allowed filter because userdefined implies a specified object or element type
|
||||||
facet = ids.entity.create(name="IfcWall", predefinedType="USERDEFINED")
|
facet = ids.entity.create(name="IFCWALL", predefinedType="USERDEFINED")
|
||||||
case(
|
case(
|
||||||
"Entity no USERDEFINED",
|
"Entity no USERDEFINED",
|
||||||
facet=facet,
|
facet=facet,
|
||||||
@@ -415,7 +418,7 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||||
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="X")
|
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="X")
|
||||||
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type)
|
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type)
|
||||||
facet = ids.entity.create(name="IfcWall", predefinedType="X")
|
facet = ids.entity.create(name="IFCWALL", predefinedType="X")
|
||||||
case("Entity PredefinedType inheritance 0", facet=facet, inst=wall, expected=True)
|
case("Entity PredefinedType inheritance 0", facet=facet, inst=wall, expected=True)
|
||||||
|
|
||||||
# Predefined types should match overridden predefined types from the element type
|
# Predefined types should match overridden predefined types from the element type
|
||||||
@@ -424,11 +427,11 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
"root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="NOTDEFINED"
|
"root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="NOTDEFINED"
|
||||||
)
|
)
|
||||||
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type)
|
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type)
|
||||||
facet = ids.entity.create(name="IfcWall", predefinedType="X")
|
facet = ids.entity.create(name="IFCWALL", predefinedType="X")
|
||||||
case("Entity PredefinedType inheritance 1", facet=facet, inst=wall, expected=True)
|
case("Entity PredefinedType inheritance 1", facet=facet, inst=wall, expected=True)
|
||||||
|
|
||||||
# Restrictions are allowed when matching the IFC class
|
# Restrictions are allowed when matching the IFC class
|
||||||
restriction = ids.restriction.create(options=["IfcWall", "IfcSlab"], type="enumeration")
|
restriction = ids.restriction.create(options=["IFCWALL", "IFCSLAB"], type="enumeration")
|
||||||
facet = ids.entity.create(name=restriction)
|
facet = ids.entity.create(name=restriction)
|
||||||
case("Entity enumeration 0", facet=facet, inst=ifc.createIfcWall(), expected=True)
|
case("Entity enumeration 0", facet=facet, inst=ifc.createIfcWall(), expected=True)
|
||||||
case("Entity enumeration 1", facet=facet, inst=ifc.createIfcSlab(), expected=True)
|
case("Entity enumeration 1", facet=facet, inst=ifc.createIfcSlab(), expected=True)
|
||||||
@@ -436,14 +439,14 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
|
|
||||||
# Another example of how restrictions are allowed when matching the IFC class
|
# Another example of how restrictions are allowed when matching the IFC class
|
||||||
# Note: Regex patterns follow the XSD flavour
|
# Note: Regex patterns follow the XSD flavour
|
||||||
restriction = ids.restriction.create(options="Ifc.*Type", type="pattern")
|
restriction = ids.restriction.create(options="IFC.*TYPE", type="pattern")
|
||||||
facet = ids.entity.create(name=restriction)
|
facet = ids.entity.create(name=restriction)
|
||||||
case("Entity pattern 0", facet=facet, inst=ifc.createIfcWall(), expected=False)
|
case("Entity pattern 0", facet=facet, inst=ifc.createIfcWall(), expected=False)
|
||||||
case("Entity pattern 1", facet=facet, inst=ifc.createIfcWallType(), expected=True)
|
case("Entity pattern 1", facet=facet, inst=ifc.createIfcWallType(), expected=True)
|
||||||
|
|
||||||
# Restrictions are allowed when matching the predefined type
|
# Restrictions are allowed when matching the predefined type
|
||||||
restriction = ids.restriction.create(options="FOO.*", type="pattern")
|
restriction = ids.restriction.create(options="FOO.*", type="pattern")
|
||||||
facet = ids.entity.create(name="IfcWall", predefinedType=restriction)
|
facet = ids.entity.create(name="IFCWALL", predefinedType=restriction)
|
||||||
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="FOOBAR")
|
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="FOOBAR")
|
||||||
wall2 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="FOOBAZ")
|
wall2 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="FOOBAZ")
|
||||||
wall3 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="BAZFOO")
|
wall3 = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall", predefined_type="BAZFOO")
|
||||||
@@ -1160,7 +1163,7 @@ class TestIfcValidation(unittest.TestCase):
|
|||||||
def test_creating_a_minimal_ids_and_validating(self):
|
def test_creating_a_minimal_ids_and_validating(self):
|
||||||
specs = ids.ids(title="Title")
|
specs = ids.ids(title="Title")
|
||||||
spec = ids.specification(name="Name")
|
spec = ids.specification(name="Name")
|
||||||
spec.add_applicability(ids.entity.create(name="IfcWall"))
|
spec.add_applicability(ids.entity.create(name="IFCWALL"))
|
||||||
spec.add_requirement(ids.attribute.create(name="Name", value="Waldo"))
|
spec.add_requirement(ids.attribute.create(name="Name", value="Waldo"))
|
||||||
specs.specifications.append(spec)
|
specs.specifications.append(spec)
|
||||||
assert "http://standards.buildingsmart.org/IDS" in specs.to_string()
|
assert "http://standards.buildingsmart.org/IDS" in specs.to_string()
|
||||||
@@ -1178,12 +1181,12 @@ class TestIfcValidation(unittest.TestCase):
|
|||||||
def test_creating_multiple_specifications(self):
|
def test_creating_multiple_specifications(self):
|
||||||
specs = ids.ids(title="Title")
|
specs = ids.ids(title="Title")
|
||||||
spec = ids.specification(name="Name")
|
spec = ids.specification(name="Name")
|
||||||
spec.add_applicability(ids.entity.create(name="IfcWall"))
|
spec.add_applicability(ids.entity.create(name="IFCWALL"))
|
||||||
spec.add_requirement(ids.attribute.create(name="Name", value="Waldo"))
|
spec.add_requirement(ids.attribute.create(name="Name", value="Waldo"))
|
||||||
specs.specifications.append(spec)
|
specs.specifications.append(spec)
|
||||||
|
|
||||||
spec2 = ids.specification(name="Name")
|
spec2 = ids.specification(name="Name")
|
||||||
spec2.add_applicability(ids.entity.create(name="IfcWall"))
|
spec2.add_applicability(ids.entity.create(name="IFCWALL"))
|
||||||
spec2.add_requirement(ids.attribute.create(name="Name", value="Waldo"))
|
spec2.add_requirement(ids.attribute.create(name="Name", value="Waldo"))
|
||||||
specs.specifications.append(spec2)
|
specs.specifications.append(spec2)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user