diff --git a/src/blenderbim/blenderbim/bim/module/unit/__init__.py b/src/blenderbim/blenderbim/bim/module/unit/__init__.py index a74eb70da1..c4fa9cf228 100644 --- a/src/blenderbim/blenderbim/bim/module/unit/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/unit/__init__.py @@ -9,6 +9,7 @@ classes = ( operator.RemoveUnit, operator.AddMonetaryUnit, operator.AddSIUnit, + operator.AddContextDependentUnit, operator.EnableEditingUnit, operator.DisableEditingUnit, operator.EditUnit, diff --git a/src/blenderbim/blenderbim/bim/module/unit/operator.py b/src/blenderbim/blenderbim/bim/module/unit/operator.py index 9a4f3bfc00..2c9664c870 100644 --- a/src/blenderbim/blenderbim/bim/module/unit/operator.py +++ b/src/blenderbim/blenderbim/bim/module/unit/operator.py @@ -1,4 +1,5 @@ import bpy +import json import ifcopenshell.api import ifcopenshell.util.unit import blenderbim.bim.helper @@ -174,7 +175,7 @@ class AddSIUnit(bpy.types.Operator): def _execute(self, context): props = context.scene.BIMUnitProperties self.file = IfcStore.get_file() - unit = ifcopenshell.api.run( + ifcopenshell.api.run( "unit.add_si_unit", self.file, unit_type=props.named_unit_types, @@ -185,6 +186,26 @@ class AddSIUnit(bpy.types.Operator): return {"FINISHED"} +class AddContextDependentUnit(bpy.types.Operator): + bl_idname = "bim.add_context_dependent_unit" + bl_label = "Add Context Dependent 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() + ifcopenshell.api.run( + "unit.add_context_dependent_unit", self.file, unit_type=props.named_unit_types, name="THINGAMAJIG" + ) + Data.load(self.file) + bpy.ops.bim.load_units() + return {"FINISHED"} + + + class EnableEditingUnit(bpy.types.Operator): bl_idname = "bim.enable_editing_unit" bl_label = "Enable Editing Unit" @@ -195,13 +216,21 @@ class EnableEditingUnit(bpy.types.Operator): props = context.scene.BIMUnitProperties while len(props.unit_attributes) > 0: props.unit_attributes.remove(0) - data = Data.units[self.unit] - - blenderbim.bim.helper.import_attributes(data["type"], props.unit_attributes, data) + blenderbim.bim.helper.import_attributes(data["type"], props.unit_attributes, data, self.import_attributes) props.active_unit_id = self.unit return {"FINISHED"} + def import_attributes(self, name, prop, data): + if name == "Dimensions": + new = bpy.context.scene.BIMUnitProperties.unit_attributes.add() + new.name = name + new.is_null = data[name] is None + new.is_optional = False + new.data_type = "string" + new.string_value = json.dumps([e for e in IfcStore.get_file().by_id(data["id"]).Dimensions]) + return True + class DisableEditingUnit(bpy.types.Operator): bl_idname = "bim.disable_editing_unit" @@ -223,7 +252,7 @@ class EditUnit(bpy.types.Operator): def _execute(self, context): props = context.scene.BIMUnitProperties - attributes = blenderbim.bim.helper.export_attributes(props.unit_attributes) + attributes = blenderbim.bim.helper.export_attributes(props.unit_attributes, self.export_attributes) self.file = IfcStore.get_file() unit = self.file.by_id(props.active_unit_id) if unit.is_a("IfcMonetaryUnit"): @@ -235,3 +264,11 @@ class EditUnit(bpy.types.Operator): Data.load(IfcStore.get_file()) bpy.ops.bim.load_units() return {"FINISHED"} + + def export_attributes(self, attributes, prop): + if prop.name == "Dimensions": + try: + attributes[prop.name] = json.loads(prop.get_value()) + except: + attributes[prop.name] = (0, 0, 0, 0, 0, 0, 0) + return True diff --git a/src/blenderbim/blenderbim/bim/module/unit/ui.py b/src/blenderbim/blenderbim/bim/module/unit/ui.py index d091e8bf2e..c31f9ff179 100644 --- a/src/blenderbim/blenderbim/bim/module/unit/ui.py +++ b/src/blenderbim/blenderbim/bim/module/unit/ui.py @@ -43,8 +43,9 @@ class BIM_PT_units(Panel): elif self.props.unit_classes == "IfcSIUnit": row.prop(self.props, "named_unit_types", text="") row.operator("bim.add_si_unit", text="", icon="ADD") - else: + elif self.props.unit_classes == "IfcContextDependentUnit": row.prop(self.props, "named_unit_types", text="") + row.operator("bim.add_context_dependent_unit", text="", icon="ADD") self.layout.template_list( "BIM_UL_units", diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/add_context_dependent_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/add_context_dependent_unit.py new file mode 100644 index 0000000000..5d6d8023a5 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/unit/add_context_dependent_unit.py @@ -0,0 +1,14 @@ +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"unit_type": "USERDEFINED", "name": "THINGAMAJIG", "dimensions": (0, 0, 0, 0, 0, 0, 0)} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + return self.file.create_entity( + "IfcContextDependentUnit", + Dimensions=self.file.createIfcDimensionalExponents(*self.settings["dimensions"]), + UnitType=self.settings["unit_type"], + Name=self.settings["name"], + ) diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/edit_named_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/edit_named_unit.py index 65f8cc871e..292b528675 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/unit/edit_named_unit.py +++ b/src/ifcopenshell-python/ifcopenshell/api/unit/edit_named_unit.py @@ -7,4 +7,12 @@ class Usecase: def execute(self): for name, value in self.settings["attributes"].items(): + if name == "Dimensions": + dimensions = self.settings["unit"].Dimensions + if len(self.file.get_inverse(dimensions)) > 1: + self.settings["unit"].Dimensions = self.file.createIfcDimensionalExponents(*value) + else: + for i, exponent in enumerate(value): + dimensions[i] = exponent + continue setattr(self.settings["unit"], name, value) diff --git a/src/ifcopenshell-python/ifcopenshell/api/unit/remove_unit.py b/src/ifcopenshell-python/ifcopenshell/api/unit/remove_unit.py index 949bf919e5..ceb8d7d401 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/unit/remove_unit.py +++ b/src/ifcopenshell-python/ifcopenshell/api/unit/remove_unit.py @@ -1,3 +1,4 @@ +import ifcopenshell.util.unit import ifcopenshell.util.element @@ -9,10 +10,12 @@ class Usecase(): self.settings[key] = value def execute(self): - unit_assignment = self.file.by_type("IfcUnitAssignment")[0] - units = list(unit_assignment.Units) - units.remove(self.settings["unit"]) - if not units: - return - unit_assignment.Units = units + unit_assignment = ifcopenshell.util.unit.get_unit_assignment(self.file) + if unit_assignment and self.settings["unit"] in unit_assignment.Units: + units = list(unit_assignment.Units) + units.remove(self.settings["unit"]) + if units: + unit_assignment.Units = units + else: + self.file.remove(unit_assignment) ifcopenshell.util.element.remove_deep(self.file, self.settings["unit"])