mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 14:07:43 +00:00
Add support for userdefined predefined types in IDS entity facets
This commit is contained in:
@@ -173,7 +173,6 @@ class ids:
|
|||||||
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
# Consider other way around: for elem, for spec so we can see if an element pass all IDSes?
|
# Consider other way around: for elem, for spec so we can see if an element pass all IDSes?
|
||||||
for spec in self.specifications:
|
for spec in self.specifications:
|
||||||
self.ifc_applicable = 0
|
self.ifc_applicable = 0
|
||||||
@@ -216,8 +215,8 @@ class specification:
|
|||||||
):
|
):
|
||||||
"""Create a specification to be added in ids.
|
"""Create a specification to be added in ids.
|
||||||
|
|
||||||
:param name:, defaults to "Specification"
|
:param name: Name describing the specification to a contract reader
|
||||||
:type name: str, optional
|
:type name: str
|
||||||
:param use: 'required'|'optional', defaults to "required"
|
:param use: 'required'|'optional', defaults to "required"
|
||||||
:type use: str, optional
|
:type use: str, optional
|
||||||
"""
|
"""
|
||||||
@@ -287,17 +286,19 @@ class specification:
|
|||||||
return spec
|
return spec
|
||||||
|
|
||||||
def add_applicability(self, facet):
|
def add_applicability(self, facet):
|
||||||
"""Applicability specifies what conditions must be meet for an IFC object to be used for validation. Note, that at least one entity facet is required.
|
"""Applicability specifies a filter for IFC entities are to be validated.
|
||||||
|
|
||||||
:param facet: any of entity|classification|property|material
|
At least one filter must be added.
|
||||||
|
|
||||||
|
:param facet: any of entity|attribute|classification|property|material
|
||||||
:type facet: facet
|
:type facet: facet
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
i = ids.ids()
|
specs = ids.ids()
|
||||||
i.specifications.append(ids.specification(name="Test_Specification"))
|
spec = ids.specification(name="Test_Specification")
|
||||||
e = ids.entity.create(name="Test_Name", predefinedType="Test_PredefinedType")
|
spec.add_applicability(ids.entity.create(name="IfcWall"))
|
||||||
i.specifications[0].add_applicability(e)
|
specs.specifications.append(spec)
|
||||||
"""
|
"""
|
||||||
if self.applicability:
|
if self.applicability:
|
||||||
self.applicability = boolean_and(self.applicability.terms + [facet])
|
self.applicability = boolean_and(self.applicability.terms + [facet])
|
||||||
@@ -305,9 +306,11 @@ class specification:
|
|||||||
self.applicability = boolean_and([facet])
|
self.applicability = boolean_and([facet])
|
||||||
|
|
||||||
def add_requirement(self, facet):
|
def add_requirement(self, facet):
|
||||||
"""Requirement is validated on all applicable IFC elements. Note, that at least one facet of any type is required.
|
"""A requirement specifies data to be checked for all applicable entities.
|
||||||
|
|
||||||
:param facet: any of entity|classification|property|material
|
At least one requirement must be added.
|
||||||
|
|
||||||
|
:param facet: any of entity|attribute|classification|property|material|partOf
|
||||||
:type facet: facet
|
:type facet: facet
|
||||||
"""
|
"""
|
||||||
if self.requirements:
|
if self.requirements:
|
||||||
@@ -487,18 +490,17 @@ class entity(facet):
|
|||||||
:return: Xmlschema compliant dictionary.
|
:return: Xmlschema compliant dictionary.
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
fac_dict = {"name": parameter_asdict(self.name)}
|
results = {"name": parameter_asdict(self.name)}
|
||||||
if "predefinedType" in self:
|
if self.predefinedType:
|
||||||
if self.predefinedType:
|
results["predefinedType"] = parameter_asdict(self.predefinedType)
|
||||||
fac_dict["predefinedType"] = parameter_asdict(self.predefinedType)
|
return results
|
||||||
# try:
|
|
||||||
# fac_dict["predefinedType"] = parameter_asdict(self.predefinedType)
|
|
||||||
# except (RecursionError, UnboundLocalError) as e:
|
|
||||||
# print(e)
|
|
||||||
return fac_dict
|
|
||||||
|
|
||||||
def __call__(self, inst, logger):
|
def __call__(self, inst, logger=None):
|
||||||
"""Validate an ifc instance against that entity facet.
|
"""Validate an entity.
|
||||||
|
|
||||||
|
When a simple value is provided for the name, subclasses are also
|
||||||
|
treated as valid. PredefinedType checks support userdefined types for
|
||||||
|
both element and type elements.
|
||||||
|
|
||||||
:param inst: IFC entity element
|
:param inst: IFC entity element
|
||||||
:type inst: IFC entity
|
:type inst: IFC entity
|
||||||
@@ -507,13 +509,12 @@ 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 self.predefinedType:
|
||||||
# @nb with inheritance
|
predefined_type = ifcopenshell.util.element.get_predefined_type(inst)
|
||||||
if self.predefinedType and hasattr(inst, "PredefinedType"):
|
|
||||||
self.message = "an entity name '%(name)s' of predefined type '%(predefinedType)s'"
|
self.message = "an entity name '%(name)s' of predefined type '%(predefinedType)s'"
|
||||||
return facet_evaluation(
|
return facet_evaluation(
|
||||||
inst.is_a(self.name) and inst.PredefinedType == self.predefinedType,
|
inst.is_a(self.name) and predefined_type == self.predefinedType,
|
||||||
self.message % {"name": inst.is_a(), "predefinedType": inst.PredefinedType},
|
self.message % {"name": inst.is_a(), "predefinedType": predefined_type},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.message = "an entity name '%(name)s'"
|
self.message = "an entity name '%(name)s'"
|
||||||
@@ -558,7 +559,7 @@ class attribute(facet):
|
|||||||
fac_dict["@location"] = self.location
|
fac_dict["@location"] = self.location
|
||||||
return fac_dict
|
return fac_dict
|
||||||
|
|
||||||
def __call__(self, inst, logger):
|
def __call__(self, inst, logger=None):
|
||||||
"""Validate an ifc instance against that entity facet.
|
"""Validate an ifc instance against that entity facet.
|
||||||
|
|
||||||
:param inst: IFC entity element
|
:param inst: IFC entity element
|
||||||
|
|||||||
@@ -263,10 +263,33 @@ class TestIdsAuthoring(unittest.TestCase):
|
|||||||
i.specifications[0].add_requirement(m)
|
i.specifications[0].add_requirement(m)
|
||||||
self.assertEqual(i.specifications[0].requirements.terms[1].value, "Test_Value")
|
self.assertEqual(i.specifications[0].requirements.terms[1].value, "Test_Value")
|
||||||
|
|
||||||
def test_entity_create(self):
|
def test_create_an_entity_facet(self):
|
||||||
e = ids.entity.create(name="Test_Name", predefinedType="Test_PredefinedType")
|
facet = ids.entity.create(name="IfcName")
|
||||||
self.assertEqual(e.name, "Test_Name")
|
assert facet.asdict() == {"name": {"simpleValue": "IfcName"}}
|
||||||
self.assertEqual(e.predefinedType, "Test_PredefinedType")
|
facet = ids.entity.create(name="IfcName", predefinedType="predefinedType")
|
||||||
|
assert facet.asdict() == {
|
||||||
|
"name": {"simpleValue": "IfcName"},
|
||||||
|
"predefinedType": {"simpleValue": "predefinedType"},
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_filtering_using_an_entity_facet(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
|
||||||
|
facet = ids.entity.create(name="IfcWall")
|
||||||
|
assert bool(facet(ifc.createIfcWall())) is True
|
||||||
|
assert bool(facet(ifc.createIfcWall(PredefinedType="SOLIDWALL"))) is True
|
||||||
|
assert bool(facet(ifc.createIfcSlab())) is False
|
||||||
|
|
||||||
|
facet = ids.entity.create(name="IfcWall", predefinedType="SOLIDWALL")
|
||||||
|
assert bool(facet(ifc.createIfcWall())) is False
|
||||||
|
assert bool(facet(ifc.createIfcWall(PredefinedType="SOLIDWALL"))) is True
|
||||||
|
assert bool(facet(ifc.createIfcWall(PredefinedType="PARTITIONING"))) is False
|
||||||
|
|
||||||
|
facet = ids.entity.create(name="IfcWall", predefinedType="WALDO")
|
||||||
|
assert bool(facet(ifc.createIfcWall(PredefinedType="USERDEFINED", ObjectType="WALDO"))) is True
|
||||||
|
|
||||||
|
facet = ids.entity.create(name="IfcWallType", predefinedType="WALDO")
|
||||||
|
assert bool(facet(ifc.createIfcWallType(PredefinedType="USERDEFINED", ElementType="WALDO"))) is True
|
||||||
|
|
||||||
def test_attribute_create(self):
|
def test_attribute_create(self):
|
||||||
attribute = ids.attribute.create(name="Name", value="Value")
|
attribute = ids.attribute.create(name="Name", value="Value")
|
||||||
|
|||||||
Reference in New Issue
Block a user