mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Implement ability to add SI units
This commit is contained in:
@@ -8,6 +8,7 @@ classes = (
|
||||
operator.DisableUnitEditingUI,
|
||||
operator.RemoveUnit,
|
||||
operator.AddMonetaryUnit,
|
||||
operator.AddSIUnit,
|
||||
operator.EnableEditingUnit,
|
||||
operator.DisableEditingUnit,
|
||||
operator.EditUnit,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import bpy
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.unit
|
||||
import blenderbim.bim.helper
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.unit.data import Data
|
||||
@@ -156,8 +157,29 @@ class AddMonetaryUnit(bpy.types.Operator):
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMUnitProperties
|
||||
self.file = IfcStore.get_file()
|
||||
unit = ifcopenshell.api.run("unit.add_monetary_unit", self.file)
|
||||
ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit])
|
||||
ifcopenshell.api.run("unit.add_monetary_unit", self.file)
|
||||
Data.load(self.file)
|
||||
bpy.ops.bim.load_units()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddSIUnit(bpy.types.Operator):
|
||||
bl_idname = "bim.add_si_unit"
|
||||
bl_label = "Add SI Unit"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMUnitProperties
|
||||
self.file = IfcStore.get_file()
|
||||
unit = ifcopenshell.api.run(
|
||||
"unit.add_si_unit",
|
||||
self.file,
|
||||
unit_type=props.named_unit_types,
|
||||
name=ifcopenshell.util.unit.si_type_names[props.named_unit_types],
|
||||
)
|
||||
Data.load(self.file)
|
||||
bpy.ops.bim.load_units()
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.schema
|
||||
import ifcopenshell.util.attribute
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.prop import StrProperty, Attribute
|
||||
from bpy.types import PropertyGroup
|
||||
@@ -17,11 +18,14 @@ from bpy.props import (
|
||||
|
||||
|
||||
unitclasses_enum = []
|
||||
namedunittypes_enum = []
|
||||
|
||||
|
||||
def purge():
|
||||
global unitclasses_enum
|
||||
global namedunittypes_enum
|
||||
unitclasses_enum = []
|
||||
namedunittypes_enum = []
|
||||
|
||||
|
||||
def getUnitClasses(self, context):
|
||||
@@ -33,6 +37,16 @@ def getUnitClasses(self, context):
|
||||
return unitclasses_enum
|
||||
|
||||
|
||||
def getNamedUnitTypes(self, context):
|
||||
global namedunittypes_enum
|
||||
if not len(namedunittypes_enum) and IfcStore.get_file():
|
||||
values = ifcopenshell.util.attribute.get_enum_items(
|
||||
IfcStore.get_schema().declaration_by_name("IfcNamedUnit").all_attributes()[1]
|
||||
)
|
||||
namedunittypes_enum.extend([(c, c, "") for c in sorted(values)])
|
||||
return namedunittypes_enum
|
||||
|
||||
|
||||
class Unit(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
unit_type: StringProperty(name="Unit Type")
|
||||
@@ -47,4 +61,5 @@ class BIMUnitProperties(PropertyGroup):
|
||||
active_unit_index: IntProperty(name="Active Unit Index")
|
||||
active_unit_id: IntProperty(name="Active Unit Id")
|
||||
unit_classes: EnumProperty(items=getUnitClasses, name="Unit Classes")
|
||||
named_unit_types: EnumProperty(items=getNamedUnitTypes, name="Named Unit Types")
|
||||
unit_attributes: CollectionProperty(name="Unit Attributes", type=Attribute)
|
||||
|
||||
@@ -40,8 +40,11 @@ class BIM_PT_units(Panel):
|
||||
row.operator("bim.add_monetary_unit", text="", icon="ADD")
|
||||
elif self.props.unit_classes == "IfcDerivedUnit":
|
||||
pass # TODO
|
||||
elif self.props.unit_classes == "IfcSIUnit":
|
||||
row.prop(self.props, "named_unit_types", text="")
|
||||
row.operator("bim.add_si_unit", text="", icon="ADD")
|
||||
else:
|
||||
pass # TODO
|
||||
row.prop(self.props, "named_unit_types", text="")
|
||||
|
||||
self.layout.template_list(
|
||||
"BIM_UL_units",
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class Usecase:
|
||||
def __init__(self, file, **settings):
|
||||
self.file = file
|
||||
self.settings = {"unit_type": "LENGTHUNIT", "name": "METRE"}
|
||||
for key, value in settings.items():
|
||||
self.settings[key] = value
|
||||
|
||||
def execute(self):
|
||||
return self.file.create_entity("IfcSIUnit", UnitType=self.settings["unit_type"], Name=self.settings["name"])
|
||||
@@ -25,7 +25,7 @@ unit_names = [
|
||||
"CANDELA",
|
||||
"COULOMB",
|
||||
"CUBIC_METRE",
|
||||
"DEGREE CELSIUS",
|
||||
"DEGREE_CELSIUS",
|
||||
"FARAD",
|
||||
"GRAM",
|
||||
"GRAY",
|
||||
@@ -43,7 +43,7 @@ unit_names = [
|
||||
"SECOND",
|
||||
"SIEMENS",
|
||||
"SIEVERT",
|
||||
"SQUARE METRE",
|
||||
"SQUARE_METRE",
|
||||
"METRE",
|
||||
"STERADIAN",
|
||||
"TESLA",
|
||||
@@ -52,7 +52,6 @@ unit_names = [
|
||||
"WEBER",
|
||||
]
|
||||
|
||||
|
||||
si_dimensions = {
|
||||
"METRE": (1, 0, 0, 0, 0, 0, 0),
|
||||
"SQUARE_METRE": (2, 0, 0, 0, 0, 0, 0),
|
||||
@@ -87,6 +86,39 @@ si_dimensions = {
|
||||
"OTHERWISE": (0, 0, 0, 0, 0, 0, 0),
|
||||
}
|
||||
|
||||
# See https://github.com/buildingSMART/IFC4.3.x-development/issues/72
|
||||
si_type_names = {
|
||||
"ABSORBEDDOSEUNIT": "GRAY",
|
||||
"AMOUNTOFSUBSTANCEUNIT": "MOLE",
|
||||
"AREAUNIT": "SQUARE_METRE",
|
||||
"DOSEEQUIVALENTUNIT": "SIEVERT",
|
||||
"ELECTRICCAPACITANCEUNIT": "FARAD",
|
||||
"ELECTRICCHARGEUNIT": "COULOMB",
|
||||
"ELECTRICCONDUCTANCEUNIT": "SIEMENS",
|
||||
"ELECTRICCURRENTUNIT": "AMPERE",
|
||||
"ELECTRICRESISTANCEUNIT": "OHM",
|
||||
"ELECTRICVOLTAGEUNIT": "VOLT",
|
||||
"ENERGYUNIT": "JOULE",
|
||||
"FORCEUNIT": "NEWTON",
|
||||
"FREQUENCYUNIT": "HERTZ",
|
||||
"ILLUMINANCEUNIT": "LUX",
|
||||
"INDUCTANCEUNIT": "HENRY",
|
||||
"LENGTHUNIT": "METRE",
|
||||
"LUMINOUSFLUXUNIT": "LUMEN",
|
||||
"LUMINOUSINTENSITYUNIT": "CANDELA",
|
||||
"MAGNETICFLUXDENSITYUNIT": "TESLA",
|
||||
"MAGNETICFLUXUNIT": "WEBER",
|
||||
"MASSUNIT": "GRAM",
|
||||
"PLANEANGLEUNIT": "RADIAN",
|
||||
"POWERUNIT": "WATT",
|
||||
"PRESSUREUNIT": "PASCAL",
|
||||
"RADIOACTIVITYUNIT": "BECQUEREL",
|
||||
"SOLIDANGLEUNIT": "STERADIAN",
|
||||
"THERMODYNAMICTEMPERATUREUNIT": "KELVIN", # Or, DEGREE_CELSIUS, but this is a quirk of IFC
|
||||
"TIMEUNIT": "SECOND",
|
||||
"VOLUMEUNIT": "CUBIC_METRE",
|
||||
}
|
||||
|
||||
si_conversions = {
|
||||
"inch": 0.0254,
|
||||
"foot": 0.3048,
|
||||
@@ -169,7 +201,7 @@ def get_prefix_multiplier(text):
|
||||
def get_unit_name(text):
|
||||
text = text.upper().replace("METER", "METRE")
|
||||
for name in unit_names:
|
||||
if name in text:
|
||||
if name.replace("_", " ") in text:
|
||||
return name
|
||||
|
||||
|
||||
@@ -263,19 +295,17 @@ def convert(value, from_prefix, from_unit, to_prefix, to_unit):
|
||||
return value
|
||||
|
||||
|
||||
"""Returns a unit scale factor to convert to and from IFC project length units and SI meters
|
||||
|
||||
Example::
|
||||
|
||||
ifc_project_length * unit_scale = si_meters
|
||||
si_meters / unit_scale = ifc_project_length
|
||||
|
||||
:returns: The scale factor
|
||||
:rtype: float
|
||||
"""
|
||||
|
||||
|
||||
def calculate_unit_scale(file):
|
||||
"""Returns a unit scale factor to convert to and from IFC project length units and SI meters
|
||||
|
||||
Example::
|
||||
|
||||
ifc_project_length * unit_scale = si_meters
|
||||
si_meters / unit_scale = ifc_project_length
|
||||
|
||||
:returns: The scale factor
|
||||
:rtype: float
|
||||
"""
|
||||
units = file.by_type("IfcUnitAssignment")[0]
|
||||
unit_scale = 1
|
||||
for unit in units.Units:
|
||||
|
||||
Reference in New Issue
Block a user