You can now view all assigned project units

This commit is contained in:
Dion Moult
2021-08-06 12:38:18 +10:00
parent 3b5bc531cb
commit 7d087d2919
7 changed files with 165 additions and 7 deletions
@@ -86,6 +86,8 @@ class BimTool(WorkSpaceTool):
row.label(text="Align Interior", icon="EVENT_V")
row = layout.row(align=True)
row = layout.row(align=True)
row.label(text="Mode")
row = layout.row(align=True)
row.label(text="", icon="EVENT_ALT")
row.label(text="Opening", icon="EVENT_O")
@@ -18,7 +18,7 @@ class BIM_PT_work_plans(Panel):
@classmethod
def poll(cls, context):
file = IfcStore.get_file()
return file and hasattr(file, "schema") and file.schema != "IFC2X3"
return file and file.schema != "IFC2X3"
def draw(self, context):
if not Data.is_loaded:
@@ -1,14 +1,19 @@
import bpy
from . import ui, operator
from . import ui, prop, operator
classes = (
operator.AssignUnit,
operator.LoadUnits,
prop.Unit,
prop.BIMUnitProperties,
ui.BIM_PT_units,
ui.BIM_UL_units,
)
def register():
pass
bpy.types.Scene.BIMUnitProperties = bpy.props.PointerProperty(type=prop.BIMUnitProperties)
def unregister():
pass
del bpy.types.Scene.BIMUnitProperties
@@ -43,3 +43,48 @@ class AssignUnit(bpy.types.Operator):
else:
data["raw"] = "FEET"
return units
class LoadUnits(bpy.types.Operator):
bl_idname = "bim.load_units"
bl_label = "Load Units"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
props = context.scene.BIMUnitProperties
while len(props.units) > 0:
props.units.remove(0)
for ifc_definition_id in Data.unit_assignment:
unit = Data.units[ifc_definition_id]
name = unit.get("Name", "")
if unit["type"] == "IfcMonetaryUnit":
name = unit["Currency"]
if unit["type"] == "IfcSIUnit" and unit["Prefix"]:
if "_" in name:
name_components = name.split("_")
name = f"{name_components[0]} {unit['Prefix']}{name_components[1]}"
else:
name = f"{unit['Prefix']}{name}"
icon = "MOD_MESHDEFORM"
if unit["type"] == "IfcSIUnit":
icon = "SNAP_GRID"
elif unit["type"] == "IfcMonetaryUnit":
icon = "COPY_ID"
unit_type = unit.get("UserDefinedType", None)
if not unit_type:
unit_type = unit.get("UnitType", None)
new = props.units.add()
new.ifc_definition_id = ifc_definition_id
new.name = name
new.unit_type = unit_type
new.icon = icon
props.is_editing = True
# bpy.ops.bim.disable_editing_unit()
return {"FINISHED"}
@@ -0,0 +1,26 @@
import bpy
from blenderbim.bim.prop import StrProperty, Attribute
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
)
class Unit(PropertyGroup):
name: StringProperty(name="Name")
unit_type: StringProperty(name="Unit Type")
icon: StringProperty(name="Icon")
ifc_definition_id: IntProperty(name="IFC Definition ID")
class BIMUnitProperties(PropertyGroup):
is_editing: BoolProperty(name="Is Editing")
units: CollectionProperty(name="Units", type=Unit)
active_unit_index: IntProperty(name="Active Unit Index")
@@ -0,0 +1,51 @@
import blenderbim.bim.helper
from bpy.types import Panel, UIList
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.unit.data import Data
class BIM_PT_units(Panel):
bl_label = "IFC Units"
bl_idname = "BIM_PT_units"
bl_options = {"DEFAULT_CLOSED"}
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
@classmethod
def poll(cls, context):
file = IfcStore.get_file()
return file
def draw(self, context):
self.file = IfcStore.get_file()
if not Data.is_loaded:
Data.load(self.file)
self.props = context.scene.BIMUnitProperties
row = self.layout.row(align=True)
row.label(text="{} Units Found".format(len(Data.unit_assignment)), icon="SNAP_GRID")
if self.props.is_editing:
row.operator("bim.add_group", text="", icon="ADD")
row.operator("bim.disable_group_editing_ui", text="", icon="CANCEL")
else:
row.operator("bim.load_units", text="", icon="GREASEPENCIL")
if self.props.is_editing:
self.layout.template_list(
"BIM_UL_units",
"",
self.props,
"units",
self.props,
"active_unit_index",
)
class BIM_UL_units(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
props = context.scene.BIMUnitProperties
if item:
row = layout.row(align=True)
row.label(text=item.unit_type or "No Type", icon=item.icon)
row.label(text=item.name or "Unnamed")
@@ -1,3 +1,7 @@
import ifcopenshell
import ifcopenshell.util.unit
class Data:
is_loaded = False
units = {}
@@ -5,16 +9,41 @@ class Data:
@classmethod
def purge(cls):
cls.is_loaded = False
cls.unit_assignment = []
cls.units = {}
@classmethod
def load(cls, file):
if not file:
return
unit_assignment = file.by_type("IfcUnitAssignment")
cls.file = file
unit_assignment = cls.file.by_type("IfcUnitAssignment")
if not unit_assignment:
return
for unit in unit_assignment[0].Units:
pass
# TODO: implement along with UI
cls.unit_assignment.append(unit.id())
cls.load_unit(unit)
cls.is_loaded = True
@classmethod
def load_unit(cls, unit):
if unit.is_a("IfcDerivedUnit"):
data = unit.get_info()
data["Elements"] = [{"Unit": e.Unit.id(), "Exponent": e.Exponent} for e in unit.Elements]
for element in unit.Elements:
cls.load_unit(element.Unit)
cls.units[unit.id()] = data
elif unit.is_a("IfcNamedUnit"):
data = unit.get_info()
if unit.is_a("IfcSIUnit"):
data["Dimensions"] = ifcopenshell.util.unit.get_si_dimensions(unit.Name)
else:
data["Dimensions"] = unit.Dimensions.get_info()
if unit.is_a("IfcConversionBasedUnit"):
conversion_factor = unit.ConversionFactor.get_info()
cls.load_unit(unit.ConversionFactor.UnitComponent)
conversion_factor["UnitComponent"] = unit.ConversionFactor.UnitComponent.id()
data["ConversionFactor"] = conversion_factor
cls.units[unit.id()] = data
elif unit.is_a("IfcMonetaryUnit"):
cls.units[unit.id()] = unit.get_info()