diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/add_conversion_based_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/add_conversion_based_unit.py index 915a882caf..8636252e26 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/unit/add_conversion_based_unit.py +++ b/src/ifcopenshell-python/ifcopenshell/api/unit/add_conversion_based_unit.py @@ -5,33 +5,29 @@ import ifcopenshell.util.unit class Usecase: def __init__(self, file, **settings): self.file = file - self.settings = {"unit_type": "LENGTHUNIT", "name": "METRE", "prefix": None, "conversion_offset": None} + self.settings = {"name": "foot", "conversion_offset": None} for key, value in settings.items(): self.settings[key] = value def execute(self): - if self.settings["unit_type"] == "LENGTHUNIT": - dimensional_exponents = self.file.createIfcDimensionalExponents(1, 0, 0, 0, 0, 0, 0) - si_unit = self.file.createIfcSIUnit(UnitType=self.settings["unit_type"], Name="METRE") - elif self.settings["unit_type"] == "AREAUNIT": - dimensional_exponents = self.file.createIfcDimensionalExponents(2, 0, 0, 0, 0, 0, 0) - si_unit = self.file.createIfcSIUnit(UnitType=self.settings["unit_type"], Name="SQUARE_METRE") - elif self.settings["unit_type"] == "VOLUMEUNIT": - dimensional_exponents = self.file.createIfcDimensionalExponents(3, 0, 0, 0, 0, 0, 0) - si_unit = self.file.createIfcSIUnit(UnitType=self.settings["unit_type"], Name="CUBIC_METRE") + unit_type = ifcopenshell.util.unit.imperial_types.get(self.settings["name"], "USERDEFINED") + dimensions = ifcopenshell.util.unit.named_dimensions[unit_type] + exponents = self.file.createIfcDimensionalExponents(*dimensions) + si_name = ifcopenshell.util.unit.si_type_names[unit_type] + si_unit = self.file.createIfcSIUnit(UnitType=unit_type, Name=si_name) conversion_real = ifcopenshell.util.unit.si_conversions.get(self.settings["name"], 1) value_component = self.file.create_entity("IfcReal", **{"wrappedValue": conversion_real}) conversion_factor = self.file.createIfcMeasureWithUnit(value_component, si_unit) - if self.settings["conversion_offset"]: - return self.file.createIfcConversionBasedUnit( - dimensional_exponents, - self.settings["unit_type"], - self.settings["name"], - conversion_factor, - self.settings["conversion_offset"], + conversion_offset = self.settings["conversion_offset"] + if not conversion_offset: + conversion_offset = ifcopenshell.util.unit.si_offsets.get(self.settings["name"], 0) + + if conversion_offset: + return self.file.createIfcConversionBasedUnitWithOffset( + exponents, unit_type, self.settings["name"], conversion_factor, conversion_offset, ) return self.file.createIfcConversionBasedUnit( - dimensional_exponents, self.settings["unit_type"], self.settings["name"], conversion_factor + exponents, unit_type, self.settings["name"], conversion_factor ) diff --git a/src/ifcopenshell-python/ifcopenshell/util/unit.py b/src/ifcopenshell-python/ifcopenshell/util/unit.py index 1027bd52c7..f50caa37e6 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/unit.py +++ b/src/ifcopenshell-python/ifcopenshell/util/unit.py @@ -192,9 +192,14 @@ si_conversions = { "hour": 3600, "day": 86400, "btu": 1055.056, + "fahrenheit": 1.8, } +si_offsets = { + "fahrenheit": -459.67, +} + imperial_types = { "thou": "LENGTHUNIT", @@ -233,6 +238,7 @@ imperial_types = { "hour": "TIMEUNIT", "day": "TIMEUNIT", "btu": "ENERGYUNIT", + "fahrenheit": "THERMODYNAMICTEMPERATUREUNIT", } diff --git a/src/ifcopenshell-python/test/api/unit/test_add_conversion_based_unit.py b/src/ifcopenshell-python/test/api/unit/test_add_conversion_based_unit.py new file mode 100644 index 0000000000..027a7dcac8 --- /dev/null +++ b/src/ifcopenshell-python/test/api/unit/test_add_conversion_based_unit.py @@ -0,0 +1,43 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestAddConversionBasedUnit(test.bootstrap.IFC4): + def test_run(self): + unit = ifcopenshell.api.run("unit.add_conversion_based_unit", self.file, name="foot") + assert unit.is_a("IfcConversionBasedUnit") + assert unit.Dimensions.LengthExponent == 1 + assert unit.Dimensions.MassExponent == 0 + assert unit.Dimensions.TimeExponent == 0 + assert unit.Dimensions.ElectricCurrentExponent == 0 + assert unit.Dimensions.ThermodynamicTemperatureExponent == 0 + assert unit.Dimensions.AmountOfSubstanceExponent == 0 + assert unit.Dimensions.LuminousIntensityExponent == 0 + assert unit.UnitType == "LENGTHUNIT" + assert unit.Name == "foot" + assert unit.ConversionFactor.ValueComponent.wrappedValue == 0.3048 + si_unit = unit.ConversionFactor.UnitComponent + assert si_unit.is_a("IfcSIUnit") + assert si_unit.UnitType == "LENGTHUNIT" + assert si_unit.Prefix is None + assert si_unit.Name == "METRE" + + def test_adding_a_unit_with_offset(self): + unit = ifcopenshell.api.run("unit.add_conversion_based_unit", self.file, name="fahrenheit") + assert unit.is_a("IfcConversionBasedUnitWithOffset") + assert unit.Dimensions.LengthExponent == 0 + assert unit.Dimensions.MassExponent == 0 + assert unit.Dimensions.TimeExponent == 0 + assert unit.Dimensions.ElectricCurrentExponent == 0 + assert unit.Dimensions.ThermodynamicTemperatureExponent == 1 + assert unit.Dimensions.AmountOfSubstanceExponent == 0 + assert unit.Dimensions.LuminousIntensityExponent == 0 + assert unit.UnitType == "THERMODYNAMICTEMPERATUREUNIT" + assert unit.Name == "fahrenheit" + assert unit.ConversionFactor.ValueComponent.wrappedValue == 1.8 + si_unit = unit.ConversionFactor.UnitComponent + assert si_unit.is_a("IfcSIUnit") + assert si_unit.UnitType == "THERMODYNAMICTEMPERATUREUNIT" + assert si_unit.Prefix is None + assert si_unit.Name == "KELVIN" + assert unit.ConversionOffset == -459.67