mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 11:24:19 +00:00
Fix #9278. calculate_unit_scale raises the SI prefix to the length exponent for prefixed SQUARE_METRE/CUBIC_METRE units.
An SI prefix attaches to the base unit symbol and the prefixed symbol is raised to the power as a whole: DECI CUBIC_METRE is dm3 = a litre = 1e-3 m3, not 0.1 m3. The scale factor previously applied the prefix multiplier linearly for all IfcSIUnits, inflating volumes x100 and areas x10 for such declarations (produced e.g. by MagiCAD for Revit MEP exports). Following the reviewer note in #9278, the exponent is taken from the derived attribute IfcSIUnit.Dimensions rather than from substring matching on the unit name: the multiplier is raised to LengthExponent only when the unit's dimensions are a pure power of length, so prefixed derived units (KILO PASCAL, MEGA NEWTON) and non-length units (KILO GRAM) correctly keep the linear multiplier. This matches the exponent handling already present in convert() and named_dimensions in the same module. Adds regression tests for prefixed AREAUNIT/VOLUMEUNIT and for the linear-prefix behaviour of PRESSUREUNIT/MASSUNIT.
This commit is contained in:
committed by
Thomas Krijnen
parent
7ed8584edc
commit
f05dd4aea5
@@ -720,7 +720,29 @@ def calculate_unit_scale(ifc_file: ifcopenshell.file, unit_type: str = "LENGTHUN
|
||||
unit_scale *= conversion_factor.ValueComponent.wrappedValue
|
||||
unit = conversion_factor.UnitComponent
|
||||
if unit.is_a("IfcSIUnit"):
|
||||
unit_scale *= get_prefix_multiplier(unit.Prefix)
|
||||
prefix_multiplier = get_prefix_multiplier(unit.Prefix)
|
||||
# An SI prefix attaches to the base unit symbol, and the prefixed
|
||||
# symbol is raised to the power as a whole: dm3 = (dm)3 = 1e-3 m3,
|
||||
# not 0.1 m3. For units whose dimensions are a pure power of length
|
||||
# (METRE, SQUARE_METRE, CUBIC_METRE) the prefix multiplier must
|
||||
# therefore be raised to the length exponent. Units with mixed or
|
||||
# non-length dimensions (PASCAL, NEWTON, GRAM, ...) keep the linear
|
||||
# multiplier, as there the prefix scales the derived unit itself.
|
||||
# https://github.com/IfcOpenShell/IfcOpenShell/issues/9278
|
||||
dimensions = unit.Dimensions
|
||||
length_exponent = dimensions.LengthExponent
|
||||
if length_exponent > 0 and not any(
|
||||
(
|
||||
dimensions.MassExponent,
|
||||
dimensions.TimeExponent,
|
||||
dimensions.ElectricCurrentExponent,
|
||||
dimensions.ThermodynamicTemperatureExponent,
|
||||
dimensions.AmountOfSubstanceExponent,
|
||||
dimensions.LuminousIntensityExponent,
|
||||
)
|
||||
):
|
||||
prefix_multiplier **= length_exponent
|
||||
unit_scale *= prefix_multiplier
|
||||
return unit_scale
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user