ifc5d.qto.IfcOpenShell - get_weight function

Added support for it in .json for the same elements that support it in IFC4QtoBaseQuantitiesBlender
This commit is contained in:
Andrej730
2025-03-14 12:37:56 +05:00
parent 86ebc968e5
commit 4c53c2ab1f
3 changed files with 74 additions and 41 deletions
+18 -18
View File
@@ -40,11 +40,11 @@
"CrossSectionArea": null,
"GrossSurfaceArea": "gross_get_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_max_xyz",
"NetSurfaceArea": "net_get_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": "net_get_outer_surface_area"
}
},
@@ -134,11 +134,11 @@
"CrossSectionArea": null,
"GrossSurfaceArea": "gross_get_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_max_xyz",
"NetSurfaceArea": "net_get_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": "net_get_outer_surface_area"
}
},
@@ -317,11 +317,11 @@
"CrossSectionArea": null,
"GrossSurfaceArea": null,
"GrossVolume": null,
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Height": "net_get_z",
"Length": "net_get_max_xy",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": null,
"Width": null
}
@@ -368,11 +368,11 @@
"CrossSectionArea": null,
"GrossSurfaceArea": "gross_get_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_max_xyz",
"NetSurfaceArea": "net_get_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": "net_get_outer_surface_area"
}
},
@@ -400,10 +400,10 @@
"CrossSectionArea": null,
"GrossSurfaceArea": null,
"GrossVolume": null,
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_z",
"NetVolume": null,
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": null
}
},
@@ -420,10 +420,10 @@
"IfcPipeSegment": {
"Qto_PipeSegmentBaseQuantities": {
"GrossCrossSectionArea": null,
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_segment_length",
"NetCrossSectionArea": null,
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": null
}
},
@@ -431,10 +431,10 @@
"Qto_PlateBaseQuantities": {
"GrossArea": "gross_get_max_side_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"NetArea": "net_get_max_side_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"Perimeter": null,
"Width": "net_get_min_xyz"
}
@@ -510,11 +510,11 @@
"Depth": "net_get_z",
"GrossArea": "gross_get_footprint_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_x",
"NetArea": "net_get_footprint_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"Perimeter": "net_get_footprint_perimeter",
"Width": "net_get_y"
}
@@ -609,13 +609,13 @@
"GrossFootprintArea": null,
"GrossSideArea": "gross_get_side_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Height": "net_get_z",
"Length": "net_get_x",
"NetFootprintArea": null,
"NetSideArea": "net_get_side_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"Width": "net_get_y"
}
},
+18 -18
View File
@@ -40,11 +40,11 @@
"CrossSectionArea": null,
"GrossSurfaceArea": "gross_get_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_max_xyz",
"NetSurfaceArea": "net_get_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": "net_get_outer_surface_area"
}
},
@@ -140,11 +140,11 @@
"CrossSectionArea": null,
"GrossSurfaceArea": "gross_get_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_max_xyz",
"NetSurfaceArea": "net_get_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": "net_get_outer_surface_area"
}
},
@@ -362,11 +362,11 @@
"CrossSectionArea": null,
"GrossSurfaceArea": null,
"GrossVolume": null,
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Height": "net_get_z",
"Length": "net_get_max_xy",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": null,
"Width": null
}
@@ -457,11 +457,11 @@
"CrossSectionArea": null,
"GrossSurfaceArea": "gross_get_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_max_xyz",
"NetSurfaceArea": "net_get_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": "net_get_outer_surface_area"
}
},
@@ -500,10 +500,10 @@
"CrossSectionArea": null,
"GrossSurfaceArea": null,
"GrossVolume": null,
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_z",
"NetVolume": null,
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": null
}
},
@@ -521,10 +521,10 @@
"Qto_PipeSegmentBaseQuantities": {
"FootPrintArea": null,
"GrossCrossSectionArea": null,
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_segment_length",
"NetCrossSectionArea": null,
"NetWeight": null,
"NetWeight": "net_get_weight",
"OuterSurfaceArea": null
}
},
@@ -532,10 +532,10 @@
"Qto_PlateBaseQuantities": {
"GrossArea": "gross_get_max_side_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"NetArea": "net_get_max_side_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"Perimeter": null,
"Width": "net_get_min_xyz"
}
@@ -656,11 +656,11 @@
"Depth": "net_get_z",
"GrossArea": "gross_get_footprint_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Length": "net_get_x",
"NetArea": "net_get_footprint_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"Perimeter": "net_get_footprint_perimeter",
"Width": "net_get_y"
}
@@ -782,13 +782,13 @@
"GrossFootPrintArea": null,
"GrossSideArea": "gross_get_side_area",
"GrossVolume": "gross_get_volume",
"GrossWeight": null,
"GrossWeight": "gross_get_weight",
"Height": "net_get_z",
"Length": "net_get_x",
"NetFootPrintArea": null,
"NetSideArea": "net_get_side_area",
"NetVolume": "net_get_volume",
"NetWeight": null,
"NetWeight": "net_get_weight",
"Width": "net_get_y"
}
},
+38 -5
View File
@@ -234,6 +234,12 @@ class IfcOpenShell(QtoCalculator):
),
# IfcVolumeMeasure
"get_volume": Function("IfcVolumeMeasure", "Volume", "Calculates the volume of a manifold shape"),
# IfcMassMeasure
"get_weight": Function(
"IfcMassMeasure",
"Weight",
"The weight of the object based on it's volume and material density (from Pset_MaterialCommon.MassDensity).",
),
}
functions = {}
@@ -241,6 +247,11 @@ class IfcOpenShell(QtoCalculator):
functions[f"gross_{k}"] = Function(v.measure, f"Gross {v.name}", v.description)
functions[f"net_{k}"] = Function(v.measure, f"Net {v.name}", v.description)
internal_functions = (
"get_segment_length",
"get_weight",
)
@classmethod
def calculate(cls, ifc_file, elements, qtos, results):
formula_functions: dict[str, types.FunctionType] = {}
@@ -258,7 +269,7 @@ class IfcOpenShell(QtoCalculator):
if not formula:
continue
gross_or_net_qtos = gross_qtos if formula.startswith("gross_") else net_qtos
if formula.endswith("get_segment_length"):
if formula.endswith(cls.internal_functions):
gross_or_net_qtos.setdefault(name, {})[quantity] = formula.partition("_")[2]
elif formula.startswith(("gross_", "net_")):
formula = formula.partition("_")[2]
@@ -280,6 +291,7 @@ class IfcOpenShell(QtoCalculator):
for iterator, qtos_ in tasks:
if iterator.initialize():
while True:
geometry: ifcopenshell.geom.main.ShapeType
if isinstance(iterator, ifcopenshell.geom.iterator):
shape = iterator.get()
geometry = shape.geometry
@@ -293,11 +305,15 @@ class IfcOpenShell(QtoCalculator):
for quantity, formula in quantities.items():
if formula == "get_segment_length":
results[element][name][quantity] = cls.get_segment_length(element)
elif formula == "get_weight":
value = cls.get_weight(element, geometry)
if value is None:
continue
else:
results[element][name][quantity] = cls.unit_converter.convert(
formula_functions[formula](geometry),
IfcOpenShell.raw_functions[formula].measure,
)
value = formula_functions[formula](geometry)
assert isinstance(value, (float, int))
value = cls.unit_converter.convert(value, IfcOpenShell.raw_functions[formula].measure)
results[element][name][quantity] = value
if not iterator.next():
break
@@ -341,6 +357,23 @@ class IfcOpenShell(QtoCalculator):
z = item.Depth
return max([x, y, z])
@classmethod
def get_weight(
cls, element: ifcopenshell.entity_instance, geometry: ifcopenshell.geom.ShapeType
) -> Union[float, None]:
"""Get element's weight.
:param element: IFC element entity.
:return: ``float`` weight in project units
or ``None`` if mass density calculation for this element is not supported.
"""
density = ifcopenshell.util.element.get_element_mass_density(element)
if density is None:
return
volume = ifcopenshell.util.shape.get_volume(geometry)
return volume * density
class Blender(QtoCalculator):
"""Calculates geometry based on currently loaded Blender objects."""