diff --git a/src/ifcblenderexport/io_export_ifc/export_ifc.py b/src/ifcblenderexport/io_export_ifc/export_ifc.py index 1d1e453303..c2e932b80f 100644 --- a/src/ifcblenderexport/io_export_ifc/export_ifc.py +++ b/src/ifcblenderexport/io_export_ifc/export_ifc.py @@ -4,6 +4,7 @@ import json import time from pathlib import Path from mathutils import Vector, Matrix +from .helper import SIUnitHelper from . import ifcopenshell class ArrayModifier: @@ -754,28 +755,6 @@ class IfcParser(): def is_a_type(self, class_name): return class_name[0:3] == 'Ifc' and class_name[-4:] == 'Type' -class SIUnitHelper: - prefixes = ["EXA", "PETA", "TERA", "GIGA", "MEGA", "KILO", "HECTO", - "DECA", "DECI", "CENTI", "MILLI", "MICRO", "NANO", "PICO", "FEMTO", - "ATTO"] - unit_names = ["AMPERE", "BECQUEREL", "CANDELA", "COULOMB", - "CUBIC_METRE", "DEGREE CELSIUS", "FARAD", "GRAM", "GRAY", "HENRY", - "HERTZ", "JOULE", "KELVIN", "LUMEN", "LUX", "MOLE", "NEWTON", "OHM", - "PASCAL", "RADIAN", "SECOND", "SIEMENS", "SIEVERT", "SQUARE METRE", - "METRE", "STERADIAN", "TESLA", "VOLT", "WATT", "WEBER"] - - @staticmethod - def get_prefix(text): - for prefix in SIUnitHelper.prefixes: - if prefix in text.upper(): - return prefix - - @staticmethod - def get_unit_name(text): - for name in SIUnitHelper.unit_names: - if name in text.upper().replace('METER', 'METRE'): - return name - class IfcExporter(): def __init__(self, ifc_export_settings, ifc_schema, ifc_parser, qto_calculator): self.template_file = '{}template.ifc'.format(ifc_export_settings.schema_dir) diff --git a/src/ifcblenderexport/io_export_ifc/helper.py b/src/ifcblenderexport/io_export_ifc/helper.py new file mode 100644 index 0000000000..aa00fc0273 --- /dev/null +++ b/src/ifcblenderexport/io_export_ifc/helper.py @@ -0,0 +1,66 @@ +import math + +class SIUnitHelper: + prefixes = {"EXA": 1e18, "PETA": 1e15, "TERA": 1e12, "GIGA": 1e9, "MEGA": + 1e6, "KILO": 1e3, "HECTO": 1e2, "DECA": 1e1, "DECI": 1e-1, "CENTI": + 1e-2, "MILLI": 1e-3, "MICRO": 1e-6, "NANO": 1e-9, "PICO": 1e-12, + "FEMTO": 1e-15, "ATTO": 1e-18} + unit_names = ["AMPERE", "BECQUEREL", "CANDELA", "COULOMB", + "CUBIC_METRE", "DEGREE CELSIUS", "FARAD", "GRAM", "GRAY", "HENRY", + "HERTZ", "JOULE", "KELVIN", "LUMEN", "LUX", "MOLE", "NEWTON", "OHM", + "PASCAL", "RADIAN", "SECOND", "SIEMENS", "SIEVERT", "SQUARE METRE", + "METRE", "STERADIAN", "TESLA", "VOLT", "WATT", "WEBER"] + si_conversions = { + 'inch': 0.0254, + 'foot': 0.3048, + 'yard': 0.914, + 'mile': 1609, + 'square inch': 0.0006452, + 'square foot': 0.09290, + 'square yard': 0.83612736, + 'acre': 4046.86, + 'square mile': 2588881, + 'cubic inch': 0.00001639, + 'cubic foot': 0.02832, + 'cubic yard': 0.7636, + 'litre': 0.001, + 'fluid ounce UK': 0.0000284130625, + 'fluid ounce US': 0.00002957353, + 'pint UK': 0.000568, + 'pint US': 0.000473, + 'gallon UK': 0.004546, + 'gallon US': 0.003785, + 'degree': math.pi/180, + 'ounce': 0.02835, + 'pound': 0.454, + 'ton UK': 1016.0469088, + 'ton US': 907.18474, + 'lbf': 4.4482216153, + 'kip': 4448.2216153, + 'psi': 6894.7572932, + 'ksi': 6894757.2932, + 'minute': 60, + 'hour': 3600, + 'day': 86400, + 'btu': 1055.056} + + @staticmethod + def get_prefix(text): + for prefix in SIUnitHelper.prefixes.keys(): + if prefix in text.upper(): + return prefix + + @staticmethod + def get_prefix_multiplier(text): + if not text: + return 1 + prefix = SIUnitHelper.get_prefix(text) + if prefix: + return SIUnitHelper.prefixes[prefix] + return 1 + + @staticmethod + def get_unit_name(text): + for name in SIUnitHelper.unit_names: + if name in text.upper().replace('METER', 'METRE'): + return name diff --git a/src/ifcblenderexport/io_export_ifc/import_ifc.py b/src/ifcblenderexport/io_export_ifc/import_ifc.py index 7637a7af32..df4eaecf19 100644 --- a/src/ifcblenderexport/io_export_ifc/import_ifc.py +++ b/src/ifcblenderexport/io_export_ifc/import_ifc.py @@ -5,6 +5,7 @@ import os import json import time import mathutils +from .helper import SIUnitHelper cwd = os.path.dirname(os.path.realpath(__file__)) + os.path.sep @@ -125,11 +126,14 @@ class IfcImporter(): def calculate_unit_scale(self): units = self.file.by_type('IfcUnitAssignment')[0] for unit in units.Units: - if unit.is_a('IfcSIUnit') \ - and unit.UnitType == 'LENGTHUNIT': - if unit.Prefix: - if unit.Prefix == 'MILLI': - self.unit_scale *= 0.001 + if not hasattr(unit, 'UnitType') \ + or unit.UnitType != 'LENGTHUNIT': + continue + while unit.is_a('IfcConversionBasedUnit'): + self.unit_scale *= unit.ConversionFactor.ValueComponent.wrappedValue + unit = unit.ConversionFactor.UnitComponent + if unit.is_a('IfcSIUnit'): + self.unit_scale *= SIUnitHelper.get_prefix_multiplier(unit.Prefix) def create_project(self): self.project = { 'ifc': self.file.by_type('IfcProject')[0] }