From 472a66b7ed885839278ac83518a41f9500efdf93 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 18 Feb 2022 17:11:24 +1100 Subject: [PATCH] Fix bug where element types couldn't get psets applied to them due to lack of specificity in IFC templates --- src/ifcopenshell-python/ifcopenshell/util/pset.py | 11 +++++++++++ src/ifcopenshell-python/test/util/test_pset.py | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/src/ifcopenshell-python/ifcopenshell/util/pset.py b/src/ifcopenshell-python/ifcopenshell/util/pset.py index 5a84caaef8..77779ca2e6 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/pset.py +++ b/src/ifcopenshell-python/ifcopenshell/util/pset.py @@ -20,6 +20,7 @@ import re import pathlib import ifcopenshell import ifcopenshell.util.schema +import ifcopenshell.util.type from ifcopenshell.entity_instance import entity_instance from functools import lru_cache from typing import List, Generator, Optional @@ -98,6 +99,16 @@ class PsetQto: applicable_class = match.group(1) if ifcopenshell.util.schema.is_a(entity, applicable_class): return True + # There is an implementer agreement that if the template type is + # type based, the type need not be explicitly mentioned + # https://github.com/buildingSMART/IFC4.3.x-development/issues/22 + # This will be fixed in IFC4.3 + template_type = template_type or "" + if "TYPE" in template_type and ifcopenshell.util.schema.is_a(entity, "IfcTypeObject"): + types = ifcopenshell.util.type.get_applicable_types(applicable_class, "IFC4") + for ifc_type in types: + if ifcopenshell.util.schema.is_a(entity, ifc_type): + return True return False @lru_cache() diff --git a/src/ifcopenshell-python/test/util/test_pset.py b/src/ifcopenshell-python/test/util/test_pset.py index 99b1f3cb52..61331d2724 100644 --- a/src/ifcopenshell-python/test/util/test_pset.py +++ b/src/ifcopenshell-python/test/util/test_pset.py @@ -41,3 +41,10 @@ class TestPsetQto: names = self.pset_qto.get_applicable_names("IfcAudioVisualAppliance", predefined_type="AMPLIFIER") assert "Pset_AudioVisualApplianceTypeAmplifier" in names assert len(names) == 18 + + def test_getting_a_pset_of_a_type_where_the_type_class_is_not_explicitly_applicable(self): + names = self.pset_qto.get_applicable_names("IfcWall") + assert "Pset_WallCommon" in names + names = self.pset_qto.get_applicable_names("IfcWallType") + assert len(names) == 9 + assert "Pset_WallCommon" in names