mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-07 04:46:25 +00:00
Implement ability to add SI units
This commit is contained in:
@@ -8,6 +8,7 @@ classes = (
|
|||||||
operator.DisableUnitEditingUI,
|
operator.DisableUnitEditingUI,
|
||||||
operator.RemoveUnit,
|
operator.RemoveUnit,
|
||||||
operator.AddMonetaryUnit,
|
operator.AddMonetaryUnit,
|
||||||
|
operator.AddSIUnit,
|
||||||
operator.EnableEditingUnit,
|
operator.EnableEditingUnit,
|
||||||
operator.DisableEditingUnit,
|
operator.DisableEditingUnit,
|
||||||
operator.EditUnit,
|
operator.EditUnit,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
|
import ifcopenshell.util.unit
|
||||||
import blenderbim.bim.helper
|
import blenderbim.bim.helper
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from ifcopenshell.api.unit.data import Data
|
from ifcopenshell.api.unit.data import Data
|
||||||
@@ -156,8 +157,29 @@ class AddMonetaryUnit(bpy.types.Operator):
|
|||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMUnitProperties
|
props = context.scene.BIMUnitProperties
|
||||||
self.file = IfcStore.get_file()
|
self.file = IfcStore.get_file()
|
||||||
unit = ifcopenshell.api.run("unit.add_monetary_unit", self.file)
|
ifcopenshell.api.run("unit.add_monetary_unit", self.file)
|
||||||
ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit])
|
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)
|
Data.load(self.file)
|
||||||
bpy.ops.bim.load_units()
|
bpy.ops.bim.load_units()
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.schema
|
import ifcopenshell.util.schema
|
||||||
|
import ifcopenshell.util.attribute
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.prop import StrProperty, Attribute
|
from blenderbim.bim.prop import StrProperty, Attribute
|
||||||
from bpy.types import PropertyGroup
|
from bpy.types import PropertyGroup
|
||||||
@@ -17,11 +18,14 @@ from bpy.props import (
|
|||||||
|
|
||||||
|
|
||||||
unitclasses_enum = []
|
unitclasses_enum = []
|
||||||
|
namedunittypes_enum = []
|
||||||
|
|
||||||
|
|
||||||
def purge():
|
def purge():
|
||||||
global unitclasses_enum
|
global unitclasses_enum
|
||||||
|
global namedunittypes_enum
|
||||||
unitclasses_enum = []
|
unitclasses_enum = []
|
||||||
|
namedunittypes_enum = []
|
||||||
|
|
||||||
|
|
||||||
def getUnitClasses(self, context):
|
def getUnitClasses(self, context):
|
||||||
@@ -33,6 +37,16 @@ def getUnitClasses(self, context):
|
|||||||
return unitclasses_enum
|
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):
|
class Unit(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
name: StringProperty(name="Name")
|
||||||
unit_type: StringProperty(name="Unit Type")
|
unit_type: StringProperty(name="Unit Type")
|
||||||
@@ -47,4 +61,5 @@ class BIMUnitProperties(PropertyGroup):
|
|||||||
active_unit_index: IntProperty(name="Active Unit Index")
|
active_unit_index: IntProperty(name="Active Unit Index")
|
||||||
active_unit_id: IntProperty(name="Active Unit Id")
|
active_unit_id: IntProperty(name="Active Unit Id")
|
||||||
unit_classes: EnumProperty(items=getUnitClasses, name="Unit Classes")
|
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)
|
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")
|
row.operator("bim.add_monetary_unit", text="", icon="ADD")
|
||||||
elif self.props.unit_classes == "IfcDerivedUnit":
|
elif self.props.unit_classes == "IfcDerivedUnit":
|
||||||
pass # TODO
|
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:
|
else:
|
||||||
pass # TODO
|
row.prop(self.props, "named_unit_types", text="")
|
||||||
|
|
||||||
self.layout.template_list(
|
self.layout.template_list(
|
||||||
"BIM_UL_units",
|
"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",
|
"CANDELA",
|
||||||
"COULOMB",
|
"COULOMB",
|
||||||
"CUBIC_METRE",
|
"CUBIC_METRE",
|
||||||
"DEGREE CELSIUS",
|
"DEGREE_CELSIUS",
|
||||||
"FARAD",
|
"FARAD",
|
||||||
"GRAM",
|
"GRAM",
|
||||||
"GRAY",
|
"GRAY",
|
||||||
@@ -43,7 +43,7 @@ unit_names = [
|
|||||||
"SECOND",
|
"SECOND",
|
||||||
"SIEMENS",
|
"SIEMENS",
|
||||||
"SIEVERT",
|
"SIEVERT",
|
||||||
"SQUARE METRE",
|
"SQUARE_METRE",
|
||||||
"METRE",
|
"METRE",
|
||||||
"STERADIAN",
|
"STERADIAN",
|
||||||
"TESLA",
|
"TESLA",
|
||||||
@@ -52,7 +52,6 @@ unit_names = [
|
|||||||
"WEBER",
|
"WEBER",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
si_dimensions = {
|
si_dimensions = {
|
||||||
"METRE": (1, 0, 0, 0, 0, 0, 0),
|
"METRE": (1, 0, 0, 0, 0, 0, 0),
|
||||||
"SQUARE_METRE": (2, 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),
|
"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 = {
|
si_conversions = {
|
||||||
"inch": 0.0254,
|
"inch": 0.0254,
|
||||||
"foot": 0.3048,
|
"foot": 0.3048,
|
||||||
@@ -169,7 +201,7 @@ def get_prefix_multiplier(text):
|
|||||||
def get_unit_name(text):
|
def get_unit_name(text):
|
||||||
text = text.upper().replace("METER", "METRE")
|
text = text.upper().replace("METER", "METRE")
|
||||||
for name in unit_names:
|
for name in unit_names:
|
||||||
if name in text:
|
if name.replace("_", " ") in text:
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
@@ -263,19 +295,17 @@ def convert(value, from_prefix, from_unit, to_prefix, to_unit):
|
|||||||
return value
|
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):
|
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]
|
units = file.by_type("IfcUnitAssignment")[0]
|
||||||
unit_scale = 1
|
unit_scale = 1
|
||||||
for unit in units.Units:
|
for unit in units.Units:
|
||||||
|
|||||||
Reference in New Issue
Block a user