New feature to toggle default project unit assignment

This commit is contained in:
Dion Moult
2021-08-13 14:58:25 +10:00
parent 2a6d6cfdbf
commit 671f1ab9cf
8 changed files with 77 additions and 20 deletions
+18 -16
View File
@@ -38,6 +38,7 @@ def import_attributes(ifc_class, props, data, callback=None):
for attribute in IfcStore.get_schema().declaration_by_name(ifc_class).all_attributes():
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
if data_type == "entity" or (isinstance(data_type, tuple) and "entity" in ".".join(data_type)):
callback(attribute.name(), None, data) if callback else None
continue
new = props.add()
new.name = attribute.name()
@@ -65,20 +66,21 @@ def import_attributes(ifc_class, props, data, callback=None):
def export_attributes(props, callback=None):
attributes = {}
for attribute in props:
is_handled_by_callback = callback(attributes, attribute) if callback else False
if attribute.is_null:
attributes[attribute.name] = None
elif is_handled_by_callback:
pass # Our job is done
elif attribute.data_type == "string":
attributes[attribute.name] = attribute.string_value
elif attribute.data_type == "boolean":
attributes[attribute.name] = attribute.bool_value
elif attribute.data_type == "integer":
attributes[attribute.name] = attribute.int_value
elif attribute.data_type == "float":
attributes[attribute.name] = attribute.float_value
elif attribute.data_type == "enum":
attributes[attribute.name] = attribute.enum_value
for prop in props:
is_handled_by_callback = callback(attributes, prop) if callback else False
if is_handled_by_callback:
continue # Our job is done
if prop.is_null:
attributes[prop.name] = None
elif prop.data_type == "string":
attributes[prop.name] = prop.string_value
elif prop.data_type == "boolean":
attributes[prop.name] = prop.bool_value
elif prop.data_type == "integer":
attributes[prop.name] = prop.int_value
elif prop.data_type == "float":
attributes[prop.name] = prop.float_value
elif prop.data_type == "enum":
attributes[prop.name] = prop.enum_value
return attributes
@@ -3,6 +3,7 @@ from . import ui, prop, operator
classes = (
operator.AssignUnit,
operator.UnassignUnit,
operator.LoadUnits,
operator.DisableUnitEditingUI,
operator.RemoveUnit,
@@ -9,13 +9,20 @@ class AssignUnit(bpy.types.Operator):
bl_idname = "bim.assign_unit"
bl_label = "Assign Unit"
bl_options = {"REGISTER", "UNDO"}
unit: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context):
ifcopenshell.api.run("unit.assign_unit", IfcStore.get_file(), **self.get_units(context))
Data.load(IfcStore.get_file())
self.file = IfcStore.get_file()
if self.unit:
ifcopenshell.api.run("unit.assign_unit", self.file, units=[self.file.by_id(self.unit)])
else:
ifcopenshell.api.run("unit.assign_unit", self.file, **self.get_units(context))
Data.load(self.file)
if self.unit:
bpy.ops.bim.load_units()
return {"FINISHED"}
def get_units(self, context):
@@ -46,6 +53,23 @@ class AssignUnit(bpy.types.Operator):
return units
class UnassignUnit(bpy.types.Operator):
bl_idname = "bim.unassign_unit"
bl_label = "Unassign Unit"
bl_options = {"REGISTER", "UNDO"}
unit: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context):
self.file = IfcStore.get_file()
ifcopenshell.api.run("unit.unassign_unit", IfcStore.get_file(), units=[self.file.by_id(self.unit)])
Data.load(self.file)
bpy.ops.bim.load_units()
return {"FINISHED"}
class LoadUnits(bpy.types.Operator):
bl_idname = "bim.load_units"
bl_label = "Load Units"
@@ -56,8 +80,7 @@ class LoadUnits(bpy.types.Operator):
while len(props.units) > 0:
props.units.remove(0)
for ifc_definition_id in Data.unit_assignment:
unit = Data.units[ifc_definition_id]
for ifc_definition_id, unit in Data.units.items():
name = unit.get("Name", "")
if unit["type"] == "IfcMonetaryUnit":
@@ -86,6 +109,7 @@ class LoadUnits(bpy.types.Operator):
new.ifc_definition_id = ifc_definition_id
new.name = name
new.unit_type = unit_type
new.is_assigned = ifc_definition_id in Data.unit_assignment
new.icon = icon
props.is_editing = True
@@ -36,6 +36,7 @@ def getUnitClasses(self, context):
class Unit(PropertyGroup):
name: StringProperty(name="Name")
unit_type: StringProperty(name="Unit Type")
is_assigned: BoolProperty(name="Is Assigned")
icon: StringProperty(name="Icon")
ifc_definition_id: IntProperty(name="IFC Definition ID")
@@ -67,6 +67,13 @@ class BIM_UL_units(UIList):
row.label(text=item.unit_type or "No Type", icon=item.icon)
row.label(text=item.name or "Unnamed")
if item.is_assigned:
op = row.operator("bim.unassign_unit", text="", icon="KEYFRAME_HLT", emboss=False)
op.unit = item.ifc_definition_id
else:
op = row.operator("bim.assign_unit", text="", icon="KEYFRAME", emboss=False)
op.unit = item.ifc_definition_id
if props.active_unit_id == item.ifc_definition_id:
row.operator("bim.edit_unit", text="", icon="CHECKMARK")
row.operator("bim.disable_editing_unit", text="", icon="CANCEL")
@@ -24,6 +24,9 @@ class Data:
return
for unit in unit_assignment[0].Units:
cls.unit_assignment.append(unit.id())
for unit in (
cls.file.by_type("IfcDerivedUnit") + cls.file.by_type("IfcNamedUnit") + cls.file.by_type("IfcMonetaryUnit")
):
cls.load_unit(unit)
cls.is_loaded = True
@@ -0,0 +1,17 @@
class Usecase:
def __init__(self, file, **settings):
self.file = file
self.settings = {"units": None}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
unit_assignment = self.file.by_type("IfcUnitAssignment")
if not unit_assignment:
return
unit_assignment = unit_assignment[0]
units = set(unit_assignment.Units or [])
units = units - set(self.settings["units"])
if units:
unit_assignment.Units = list(units)
return unit_assignment
@@ -29,6 +29,8 @@ class Patcher:
self.args = args
def patch(self):
if self.file.schema == "IFC2X3":
return
curve_map = {}
for curve in self.file.by_type("IfcIndexedPolyCurve"):