Skip to content

Commit feecb89

Browse files
committed
Fix #7212. IfcTester now supports IFC2X3 type element mapping.
1 parent cb5c488 commit feecb89

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/ifctester/ifctester/facet.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ def filter(
206206
except:
207207
# If the user has specified a class that doesn't exist in the version
208208
results = []
209+
if not self.name.endswith("TYPE"):
210+
try:
211+
for element_type in ifc_file.by_type(f"{self.name}Type"):
212+
results.extend(ifcopenshell.util.element.get_types(element_type))
213+
except:
214+
pass
209215
else:
210216
results = []
211217
ifc_classes = [t for t in ifc_file.wrapped_data.types() if t.upper() == self.name]
@@ -223,7 +229,15 @@ def __call__(self, inst: ifcopenshell.entity_instance, logger: Optional[Logger]
223229
is_pass = inst.is_a().upper() == self.name
224230
reason = None
225231

226-
if not is_pass:
232+
if (
233+
not is_pass
234+
and inst.file.schema == "IFC2X3"
235+
and not self.name.endswith("TYPE")
236+
and (element_type := ifcopenshell.util.element.get_type(inst))
237+
):
238+
is_pass = element_type.is_a().upper() == f"{self.name}TYPE"
239+
reason = {"type": "NAME", "actual": element_type.is_a().upper()[:-4]}
240+
elif not is_pass:
227241
reason = {"type": "NAME", "actual": inst.is_a().upper()}
228242

229243
if is_pass and self.predefinedType:

src/ifctester/test/test_facet.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,32 @@ def test_filtering_using_an_entity_facet(self):
230230
wall3 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall", predefined_type="BAZFOO")
231231
run("Restrictions an be specified for the predefined type 3/3", facet=facet, inst=wall3, expected=False)
232232

233+
def test_ifc2x3_occurrence_type_mapping(self):
234+
set_facet("entity")
235+
236+
ifc = ifcopenshell.file(schema="IFC2X3")
237+
application = ifcopenshell.api.owner.add_application(ifc)
238+
person = ifcopenshell.api.owner.add_person(
239+
ifc, identification="LPARTEE", family_name="Partee", given_name="Leeable"
240+
)
241+
organisation = ifcopenshell.api.owner.add_organisation(
242+
ifc, identification="AWB", name="Architects Without Ballpens"
243+
)
244+
user = ifcopenshell.api.owner.add_person_and_organisation(ifc, person=person, organisation=organisation)
245+
ifcopenshell.api.owner.settings.get_user = lambda x: user
246+
ifcopenshell.api.owner.settings.get_application = lambda x: application
247+
248+
element = ifcopenshell.api.root.create_entity(ifc, "IfcFlowTerminal")
249+
element_type = ifcopenshell.api.root.create_entity(ifc, "IfcAirTerminalType")
250+
ifcopenshell.api.type.assign_type(ifc, related_objects=[element], relating_type=element_type)
251+
facet = Entity(name="IFCAIRTERMINAL")
252+
assert facet.filter(ifc) == [element]
253+
run("In IFC2X3 the type class is checked instead 1/2", facet=facet, inst=element, expected=True)
254+
255+
facet = Entity(name="IFCELECTRICAPPLIANCE")
256+
assert facet.filter(ifc) == []
257+
run("In IFC2X3 the type class is checked instead 2/2", facet=facet, inst=element, expected=False)
258+
233259
def test_to_string_required_applicability(self):
234260
spec = ifctester.ids.Specification(name="Foo", minOccurs=1, maxOccurs="unbounded")
235261
facet = Entity(name="IFCWALL")

0 commit comments

Comments
 (0)