Skip to content

Commit b77df18

Browse files
committed
further ifcopenshell.util.element optimization
and readibility for props addressed by the index
1 parent 4f2c5e4 commit b77df18

1 file changed

Lines changed: 68 additions & 29 deletions

File tree

  • src/ifcopenshell-python/ifcopenshell/util

src/ifcopenshell-python/ifcopenshell/util/element.py

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def get_pset(
7676
pset = definition
7777
break
7878
elif (is_defined_by := getattr(element, "IsDefinedBy", None)) is not None:
79+
# other IfcObjectDefinition
7980
if should_inherit:
8081
element_type = ifcopenshell.util.element.get_type(element)
8182
if element_type:
@@ -99,7 +100,7 @@ def get_pset(
99100
elif qtos_only and not type_pset.is_a("IfcElementQuantity"):
100101
type_pset = None
101102

102-
if not pset and type_pset is None:
103+
if pset is None and type_pset is None:
103104
return
104105

105106
if not prop:
@@ -160,6 +161,7 @@ def get_psets(
160161
continue
161162
psets[definition.Name] = get_property_definition(definition, verbose=verbose)
162163
elif (is_defined_by := getattr(element, "IsDefinedBy", None)) is not None:
164+
# other IfcObjectDefinition
163165
if should_inherit:
164166
element_type = ifcopenshell.util.element.get_type(element)
165167
if element_type:
@@ -202,29 +204,33 @@ def get_property_definition(
202204
elif ifc_class == "IfcPropertySet":
203205
return get_property(definition.HasProperties, prop, verbose=verbose)
204206
elif ifc_class == "IfcMaterialProperties" or ifc_class == "IfcProfileProperties":
207+
# IfcExtendedProperties
205208
return get_property(definition.Properties, prop, verbose=verbose)
206209
else:
207210
# Entity introduced in IFC4
208211
# definition.is_a('IfcPreDefinedPropertySet'):
209212
for i in range(4, len(definition)):
210-
if definition[i] is not None:
211-
if definition.attribute_name(i) == prop:
212-
return definition[i]
213+
if definition.attribute_name(i) == prop:
214+
if (v := definition[i]) is not None:
215+
return v
213216
return
214217

215218
props = {}
216219
if ifc_class == "IfcElementQuantity":
220+
# 5 IfcElementQuantity.Quantities
217221
props.update(get_quantities(definition[5], verbose=verbose))
218222
elif ifc_class == "IfcPropertySet":
223+
# 5 IfcPropertySet.HasProperties
219224
props.update(get_properties(definition[4], verbose=verbose))
220225
elif ifc_class == "IfcMaterialProperties" or ifc_class == "IfcProfileProperties":
226+
# 2 IfcExtendedProperties.Properties
221227
props.update(get_properties(definition[2], verbose=verbose))
222228
else:
223229
# Entity introduced in IFC4
224230
# definition.is_a('IfcPreDefinedPropertySet'):
225231
for prop_i in range(4, len(definition)):
226-
if definition[prop_i] is not None:
227-
props[definition.attribute_name(prop_i)] = definition[prop_i]
232+
if (v := definition[prop_i]) is not None:
233+
props[definition.attribute_name(prop_i)] = v
228234
props["id"] = definition.id()
229235
return props
230236

@@ -239,9 +245,11 @@ def get_quantity(
239245
quantities: list[ifcopenshell.entity_instance], name: str, verbose=False
240246
) -> Union[Any, dict[str, Any]]:
241247
for quantity in quantities or []:
248+
# 0 IfcPhysicalQuantity.Name
242249
if quantity[0] != name:
243250
continue
244251
if quantity.is_a("IfcPhysicalSimpleQuantity"):
252+
# 3 IfcPhysicalSimpleQuantity.Unit
245253
result = quantity[3]
246254
elif quantity.is_a("IfcPhysicalComplexQuantity"):
247255
data = {k: v for k, v in quantity.get_info().items() if v is not None and k != "Name"}
@@ -266,24 +274,27 @@ def get_quantities(
266274
) -> dict[str, Union[Any, dict[str, Any]]]:
267275
results = {}
268276
for quantity in quantities or []:
277+
# 0 IfcPhysicalQuantity.Name
278+
quantity_name = quantity[0]
269279
if quantity.is_a("IfcPhysicalSimpleQuantity"):
270-
results[quantity[0]] = quantity[3]
280+
# 3 IfcPhysicalSimpleQuantity.Unit
281+
results[quantity_name] = quantity[3]
271282
if verbose:
272-
results[quantity[0]] = {
283+
results[quantity_name] = {
273284
"id": quantity.id(),
274285
"class": quantity.is_a(),
275-
"value": results[quantity[0]],
286+
"value": results[quantity_name],
276287
}
277288
elif quantity.is_a("IfcPhysicalComplexQuantity"):
278289
data = {k: v for k, v in quantity.get_info().items() if v is not None and k != "Name"}
279290
data["properties"] = get_quantities(quantity.HasQuantities, verbose=verbose)
280291
del data["HasQuantities"]
281-
results[quantity[0]] = data
292+
results[quantity_name] = data
282293
if verbose:
283-
results[quantity[0]] = {
284-
"id": quantity.id(),
285-
"class": quantity.is_a(),
286-
"value": results[quantity[0]],
294+
results[quantity_name] = {
295+
"id": data["id"],
296+
"class": data["class"],
297+
"value": results[quantity_name],
287298
}
288299
return results
289300

@@ -301,11 +312,14 @@ def get_property(
301312
if prop.Name != name:
302313
continue
303314
if prop.is_a("IfcPropertySingleValue"):
304-
result = prop[2].wrappedValue if prop[2] else None
315+
# 2 IfcPropertySingleValue.NominalValue
316+
result = v.wrappedValue if (v := prop[2]) else None
305317
elif prop.is_a("IfcPropertyEnumeratedValue"):
306-
result = [v.wrappedValue for v in prop.EnumerationValues] if prop.EnumerationValues else None
318+
# 2 IfcPropertyEnumeratedValue.EnumerationValues
319+
result = [v.wrappedValue for v in values] if (values := prop[2]) else None
307320
elif prop.is_a("IfcPropertyListValue"):
308-
result = [v.wrappedValue for v in prop.ListValues] or None
321+
# 2 IfcPropertyListValue.ListValues
322+
result = [v.wrappedValue for v in values] if (values := prop[2]) else None
309323
elif prop.is_a("IfcPropertyBoundedValue"):
310324
data = prop.get_info()
311325
del data["Unit"]
@@ -336,35 +350,60 @@ def get_properties(
336350
results = {}
337351
for prop in properties or []:
338352
ifc_class = prop.is_a()
353+
prop_name = prop[0] # 0 IfcProperty.Name
339354
if ifc_class == "IfcPropertySingleValue":
340-
results[prop[0]] = prop[2].wrappedValue if prop[2] else None
355+
# 2 IfcPropertySingleValue.NominalValue
356+
results[prop_name] = v.wrappedValue if (v := prop[2]) else None
341357
if verbose:
342-
results[prop[0]] = {"id": prop.id(), "class": prop.is_a(), "value": results[prop[0]]}
358+
results[prop_name] = {
359+
"id": prop.id(),
360+
"class": prop.is_a(),
361+
"value": results[prop_name],
362+
}
343363
elif ifc_class == "IfcPropertyEnumeratedValue":
344-
results[prop[0]] = [v.wrappedValue for v in prop.EnumerationValues] if prop.EnumerationValues else None
364+
# 2 IfcPropertyEnumeratedValue.EnumerationValues
365+
results[prop_name] = [v.wrappedValue for v in values] if (values := prop[2]) else None
345366
if verbose:
346-
results[prop[0]] = {"id": prop.id(), "class": prop.is_a(), "value": results[prop[0]]}
367+
results[prop_name] = {
368+
"id": prop.id(),
369+
"class": prop.is_a(),
370+
"value": results[prop_name],
371+
}
347372
elif ifc_class == "IfcPropertyListValue":
348-
results[prop[0]] = [v.wrappedValue for v in prop.ListValues] or None
373+
# 2 IfcPropertyListValue.ListValues
374+
results[prop_name] = [v.wrappedValue for v in values] if (values := prop[2]) else None
349375
if verbose:
350-
results[prop[0]] = {"id": prop.id(), "class": prop.is_a(), "value": results[prop[0]]}
376+
results[prop_name] = {
377+
"id": prop.id(),
378+
"class": prop.is_a(),
379+
"value": results[prop_name],
380+
}
351381
elif ifc_class == "IfcPropertyBoundedValue":
352382
data = prop.get_info()
353383
del data["Unit"]
354-
results[prop[0]] = data
384+
results[prop_name] = data
355385
if verbose:
356-
results[prop[0]] = {"id": prop.id(), "class": prop.is_a(), "value": results[prop[0]]}
386+
results[prop_name] = {
387+
"id": data["id"],
388+
"class": data["type"],
389+
"value": results[prop_name],
390+
}
357391
elif ifc_class == "IfcPropertyTableValue":
358-
results[prop[0]] = prop.get_info()
392+
data = prop.get_info()
393+
results[prop_name] = data
359394
if verbose:
360-
results[prop[0]] = {"id": prop.id(), "class": prop.is_a(), "value": results[prop[0]]}
395+
results[prop_name] = {
396+
"id": data["id"],
397+
"class": data["type"],
398+
"value": results[prop_name],
399+
}
361400
elif ifc_class == "IfcComplexProperty":
362401
data = {k: v for k, v in prop.get_info().items() if v is not None and k != "Name"}
363402
data["properties"] = get_properties(prop.HasProperties, verbose=verbose)
364403
del data["HasProperties"]
365-
results[prop[0]] = data
404+
results[prop_name] = data
366405
if verbose:
367-
results[prop[0]] = {"id": prop.id(), "class": prop.is_a(), "value": results[prop[0]]}
406+
results[prop_name] = {"id": data["id"], "class": data["class"], "value": results[prop_name]}
368407
return results
369408

370409

0 commit comments

Comments
 (0)