mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Add IfcTester support and test cases for bounded, table, and reference props
This commit is contained in:
@@ -86,6 +86,11 @@ def get_quantities(quantities):
|
||||
for quantity in quantities or []:
|
||||
if quantity.is_a("IfcPhysicalSimpleQuantity"):
|
||||
results[quantity.Name] = quantity[3]
|
||||
elif quantity.is_a("IfcPhysicalComplexQuantity"):
|
||||
data = {k: v for k, v in quantity.get_info().items() if v is not None and k != "Name"}
|
||||
data["properties"] = get_quantities(quantity.HasQuantities)
|
||||
del data["HasQuantities"]
|
||||
results[quantity.Name] = data
|
||||
return results
|
||||
|
||||
|
||||
@@ -98,6 +103,12 @@ def get_properties(properties):
|
||||
results[prop.Name] = [v.wrappedValue for v in prop.EnumerationValues] or None
|
||||
elif prop.is_a("IfcPropertyListValue"):
|
||||
results[prop.Name] = [v.wrappedValue for v in prop.ListValues] or None
|
||||
elif prop.is_a("IfcPropertyBoundedValue"):
|
||||
data = prop.get_info()
|
||||
del data["Unit"]
|
||||
results[prop.Name] = data
|
||||
elif prop.is_a("IfcPropertyTableValue"):
|
||||
results[prop.Name] = prop.get_info()
|
||||
elif prop.is_a("IfcComplexProperty"):
|
||||
data = {k: v for k, v in prop.get_info().items() if v is not None and k != "Name"}
|
||||
data["properties"] = get_properties(prop.HasProperties)
|
||||
|
||||
@@ -341,6 +341,29 @@ def get_property_unit(prop, ifc_file):
|
||||
measure_class = prop.EnumerationValues[0].is_a()
|
||||
elif prop.is_a("IfcPropertyListValue") and prop.ListValues:
|
||||
measure_class = prop.ListValues[0].is_a()
|
||||
elif prop.is_a("IfcPropertyBoundedValue"):
|
||||
if prop.UpperBoundValue:
|
||||
measure_class = prop.UpperBoundValue.is_a()
|
||||
elif prop.LowerBoundValue:
|
||||
measure_class = prop.LowerBoundValue.is_a()
|
||||
elif prop.SetPointValue:
|
||||
measure_class = prop.SetPointValue.is_a()
|
||||
elif prop.is_a("IfcPropertyTableValue"):
|
||||
table_units = {}
|
||||
for attribute in ["Defining", "Defined"]:
|
||||
if getattr(prop, f"{attribute}Unit"):
|
||||
table_units[f"{attribute}Unit"] = getattr(prop, f"{attribute}Unit")
|
||||
elif getattr(prop, f"{attribute}Values"):
|
||||
measure_class = getattr(prop, f"{attribute}Values")[0].is_a()
|
||||
unit_type = get_measure_unit_type(measure_class)
|
||||
units = [u for u in unit_assignment.Units if getattr(u, "UnitType", None) == unit_type]
|
||||
if units:
|
||||
table_units[f"{attribute}Unit"] = units[0]
|
||||
else:
|
||||
table_units[f"{attribute}Unit"] = None
|
||||
else:
|
||||
table_units[f"{attribute}Unit"] = None
|
||||
return table_units
|
||||
unit_type = get_measure_unit_type(measure_class)
|
||||
units = [u for u in unit_assignment.Units if getattr(u, "UnitType", None) == unit_type]
|
||||
if units:
|
||||
|
||||
@@ -517,7 +517,68 @@ class Property(Facet):
|
||||
break
|
||||
unit = ifcopenshell.util.unit.get_property_unit(prop_entity, inst.wrapped_data.file)
|
||||
if unit:
|
||||
props[pset_name][prop_entity.Name] = [ifcopenshell.util.unit.convert(v, getattr(unit, "Prefix", None), unit.Name, None, ifcopenshell.util.unit.si_type_names[unit.UnitType]) for v in props[pset_name][prop_entity.Name]]
|
||||
props[pset_name][prop_entity.Name] = [
|
||||
ifcopenshell.util.unit.convert(
|
||||
v,
|
||||
getattr(unit, "Prefix", None),
|
||||
unit.Name,
|
||||
None,
|
||||
ifcopenshell.util.unit.si_type_names[unit.UnitType],
|
||||
)
|
||||
for v in props[pset_name][prop_entity.Name]
|
||||
]
|
||||
elif prop_entity.is_a("IfcPropertyBoundedValue"):
|
||||
values = []
|
||||
for attribute in ["UpperBoundValue", "LowerBoundValue", "SetPointValue"]:
|
||||
value = getattr(prop_entity, attribute)
|
||||
if value is not None:
|
||||
data_type = value.is_a()
|
||||
values.append(value.wrappedValue)
|
||||
if data_type != self.measure:
|
||||
is_pass = False
|
||||
reason = {"type": "MEASURE", "actual": data_type}
|
||||
break
|
||||
unit = ifcopenshell.util.unit.get_property_unit(prop_entity, inst.wrapped_data.file)
|
||||
if unit:
|
||||
values = [
|
||||
ifcopenshell.util.unit.convert(
|
||||
v,
|
||||
getattr(unit, "Prefix", None),
|
||||
unit.Name,
|
||||
None,
|
||||
ifcopenshell.util.unit.si_type_names[unit.UnitType],
|
||||
)
|
||||
for v in values
|
||||
]
|
||||
props[pset_name][prop_entity.Name] = values
|
||||
elif prop_entity.is_a("IfcPropertyTableValue"):
|
||||
values = []
|
||||
units = ifcopenshell.util.unit.get_property_unit(prop_entity, inst.wrapped_data.file)
|
||||
for attribute in ["Defining", "Defined"]:
|
||||
column_values = props[pset_name][prop_entity.Name][f"{attribute}Values"]
|
||||
if not column_values:
|
||||
continue
|
||||
data_type = column_values[0].is_a()
|
||||
if data_type == self.measure:
|
||||
column_values = [v.wrappedValue for v in column_values]
|
||||
unit = units[f"{attribute}Unit"]
|
||||
if unit:
|
||||
column_values = [
|
||||
ifcopenshell.util.unit.convert(
|
||||
v,
|
||||
getattr(unit, "Prefix", None),
|
||||
unit.Name,
|
||||
None,
|
||||
ifcopenshell.util.unit.si_type_names[unit.UnitType],
|
||||
)
|
||||
for v in column_values
|
||||
]
|
||||
values.extend(column_values)
|
||||
if not values:
|
||||
is_pass = False
|
||||
reason = {"type": "MEASURE", "actual": data_type}
|
||||
break
|
||||
props[pset_name][prop_entity.Name] = values
|
||||
else:
|
||||
is_property_supported_class = False
|
||||
|
||||
@@ -538,7 +599,8 @@ class Property(Facet):
|
||||
break
|
||||
elif isinstance(self.value, str) and isinstance(value, list):
|
||||
# "i_require_foo" = ["a", "b"] such as in enumerated properties
|
||||
if self.value not in value:
|
||||
cast_value = cast_to_value(self.value, value[0])
|
||||
if cast_value not in value:
|
||||
is_pass = False
|
||||
reason = {"type": "VALUE", "actual": value}
|
||||
break
|
||||
|
||||
@@ -1039,6 +1039,43 @@ class TestProperty:
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", value="Z", measure="IfcLabel")
|
||||
run("Any matching value in a list property will pass 3/3", facet=facet, inst=element, expected=False)
|
||||
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
|
||||
bounded_property = ifc.createIfcPropertyBoundedValue(
|
||||
Name="Foo",
|
||||
UpperBoundValue=ifc.createIfcLengthMeasure(5000),
|
||||
LowerBoundValue=ifc.createIfcLengthMeasure(1000),
|
||||
SetPointValue=ifc.createIfcLengthMeasure(3000),
|
||||
)
|
||||
pset.HasProperties = [bounded_property]
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", value="1", measure="IfcLengthMeasure")
|
||||
run("Any matching value in a bounded property will pass 1/4", facet=facet, inst=element, expected=True)
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", value="5", measure="IfcLengthMeasure")
|
||||
run("Any matching value in a bounded property will pass 2/4", facet=facet, inst=element, expected=True)
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", value="3", measure="IfcLengthMeasure")
|
||||
run("Any matching value in a bounded property will pass 3/4", facet=facet, inst=element, expected=True)
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", value="2", measure="IfcLengthMeasure")
|
||||
run("Any matching value in a bounded property will pass 4/4", facet=facet, inst=element, expected=False)
|
||||
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
|
||||
table_property = ifc.createIfcPropertyTableValue(
|
||||
Name="Foo", DefiningValues=[ifc.createIfcLabel("X")], DefinedValues=[ifc.createIfcLengthMeasure(1000)]
|
||||
)
|
||||
pset.HasProperties = [table_property]
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", value="X", measure="IfcLabel")
|
||||
run("Any matching value in a table property will pass 1/3", facet=facet, inst=element, expected=True)
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", value="1", measure="IfcLengthMeasure")
|
||||
run("Any matching value in a table property will pass 2/3", facet=facet, inst=element, expected=True)
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", value="Y", measure="IfcLabel")
|
||||
run("Any matching value in a table property will pass 3/3", facet=facet, inst=element, expected=False)
|
||||
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
|
||||
pset.HasProperties = [ifc.createIfcPropertyReferenceValue(Name="Foo")]
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLabel")
|
||||
run("Reference properties are treated as objects and not supported", facet=facet, inst=element, expected=False)
|
||||
|
||||
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLengthMeasure")
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||
qto = ifcopenshell.api.run("pset.add_qto", ifc, product=element, name="Foo_Bar")
|
||||
|
||||
Reference in New Issue
Block a user