diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index 34d6cdb91d..26850ce85a 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -98,8 +98,6 @@ class NewProject(bpy.types.Operator): bpy.context.scene.unit_settings.length_unit = "METERS" bim_props.area_unit = "SQUARE_METRE" bim_props.volume_unit = "CUBIC_METRE" - bim_props.mass_unit = "KILOGRAM" - bim_props.time_unit = "SECOND" pprops.template_file = "0" elif self.preset == "metric_mm": pprops.export_schema = "IFC4" @@ -107,8 +105,6 @@ class NewProject(bpy.types.Operator): bpy.context.scene.unit_settings.length_unit = "MILLIMETERS" bim_props.area_unit = "SQUARE_METRE" bim_props.volume_unit = "CUBIC_METRE" - bim_props.mass_unit = "KILOGRAM" - bim_props.time_unit = "SECOND" pprops.template_file = "0" elif self.preset == "imperial_ft": pprops.export_schema = "IFC4" @@ -116,8 +112,6 @@ class NewProject(bpy.types.Operator): bpy.context.scene.unit_settings.length_unit = "FEET" bim_props.area_unit = "square foot" bim_props.volume_unit = "cubic foot" - bim_props.mass_unit = "POUND" - bim_props.time_unit = "SECOND" pprops.template_file = "0" elif self.preset == "demo": pprops.export_schema = "IFC4" diff --git a/src/bonsai/bonsai/bim/module/project/ui.py b/src/bonsai/bonsai/bim/module/project/ui.py index 731a9d0688..ed6e65e674 100644 --- a/src/bonsai/bonsai/bim/module/project/ui.py +++ b/src/bonsai/bonsai/bim/module/project/ui.py @@ -357,15 +357,20 @@ class BIM_PT_new_project_wizard(Panel): row = self.layout.row() row.prop(props, "volume_unit", text="Volume Unit") row = self.layout.row() - row.prop(props, "mass_unit", text="Mass Unit") - row = self.layout.row() - row.prop(props, "time_unit", text="Time Unit") prop_with_search(self.layout, pprops, "template_file", text="Template") - + self.layout.use_property_split = False + row = self.layout.row() + label = "Add Mass and Time Units" if not props.add_mass_time_units else "Remove Mass and Time Units" + row.prop(props, "add_mass_time_units", toggle=True, text=label) + self.layout.use_property_split = True + if props.add_mass_time_units: + row = self.layout.row() + row.prop(props, "mass_unit", text="Mass Unit") + row = self.layout.row() + row.prop(props, "time_unit", text="Time Unit") row = self.layout.row() row.operator("bim.create_project") - class BIM_PT_project_library(Panel): bl_label = "Project Library" bl_idname = "BIM_PT_project_library" diff --git a/src/bonsai/bonsai/bim/prop.py b/src/bonsai/bonsai/bim/prop.py index 7b24d2a1d1..c5a5bd9300 100644 --- a/src/bonsai/bonsai/bim/prop.py +++ b/src/bonsai/bonsai/bim/prop.py @@ -586,6 +586,11 @@ class BIMProperties(PropertyGroup): ], name="IFC Volume Unit", ) + add_mass_time_units: bpy.props.BoolProperty( + name="Add Mass and Time Units", + description="Enable to define mass and time units for the project", + default=False + ) mass_unit: EnumProperty( items=[ ("KILOGRAM", "Kilogram", "Kilograms"), diff --git a/src/bonsai/bonsai/core/tool.py b/src/bonsai/bonsai/core/tool.py index 7fcfd25fde..d8e4dd2396 100644 --- a/src/bonsai/bonsai/core/tool.py +++ b/src/bonsai/bonsai/core/tool.py @@ -1123,7 +1123,7 @@ class Unit: def set_active_unit(cls, unit): pass def get_project_currency_unit(cls): pass def get_currency_name(cls): pass - + def add_mass_and_time_units(cls): pass @interface class Voider: diff --git a/src/bonsai/bonsai/core/unit.py b/src/bonsai/bonsai/core/unit.py index 2e8e627cb7..a4c52508f1 100644 --- a/src/bonsai/bonsai/core/unit.py +++ b/src/bonsai/bonsai/core/unit.py @@ -28,40 +28,43 @@ if TYPE_CHECKING: def assign_scene_units(ifc: type[tool.Ifc], unit: type[tool.Unit]) -> None: if unit.is_scene_unit_metric(): - prefix = unit.get_scene_unit_si_prefix("LENGTHUNIT") - lengthunit = ifc.run("unit.add_si_unit", unit_type="LENGTHUNIT", prefix=prefix) - prefix = unit.get_scene_unit_si_prefix("AREAUNIT") - areaunit = ifc.run("unit.add_si_unit", unit_type="AREAUNIT", prefix=prefix) - prefix = unit.get_scene_unit_si_prefix("VOLUMEUNIT") - volumeunit = ifc.run("unit.add_si_unit", unit_type="VOLUMEUNIT", prefix=prefix) + lengthunit = ifc.run("unit.add_si_unit", unit_type="LENGTHUNIT", prefix=unit.get_scene_unit_si_prefix("LENGTHUNIT")) + areaunit = ifc.run("unit.add_si_unit", unit_type="AREAUNIT", prefix=unit.get_scene_unit_si_prefix("AREAUNIT")) + volumeunit = ifc.run("unit.add_si_unit", unit_type="VOLUMEUNIT", prefix=unit.get_scene_unit_si_prefix("VOLUMEUNIT")) + planeangleunit = ifc.run("unit.add_conversion_based_unit", name="degree") + units = [lengthunit, areaunit, volumeunit, planeangleunit] - prefix = unit.get_scene_unit_si_prefix("MASSUNIT") - if prefix == "CONVERSION": - mass_unit_name = unit.get_scene_unit_name("MASSUNIT") - massunit = ifc.run("unit.add_conversion_based_unit", name=mass_unit_name.lower()) - else: - massunit = ifc.run("unit.add_si_unit", unit_type="MASSUNIT", prefix=prefix) + if unit.add_mass_and_time_units(): + prefix = unit.get_scene_unit_si_prefix("MASSUNIT") + if prefix == "CONVERSION": + massunit = ifc.run("unit.add_conversion_based_unit", name=unit.get_scene_unit_name("MASSUNIT").lower()) + else: + massunit = ifc.run("unit.add_si_unit", unit_type="MASSUNIT", prefix=prefix) + prefix = unit.get_scene_unit_si_prefix("TIMEUNIT") + if prefix == "CONVERSION": + timeunit = ifc.run("unit.add_conversion_based_unit", name=unit.get_scene_unit_name("TIMEUNIT").lower()) + else: + timeunit = ifc.run("unit.add_si_unit", unit_type="TIMEUNIT", prefix=prefix) + units += [massunit, timeunit] - prefix = unit.get_scene_unit_si_prefix("TIMEUNIT") - if prefix == "CONVERSION": - time_unit_name = unit.get_scene_unit_name("TIMEUNIT") - timeunit = ifc.run("unit.add_conversion_based_unit", name=time_unit_name.lower()) - else: - timeunit = ifc.run("unit.add_si_unit", unit_type="TIMEUNIT", prefix=prefix) else: lengthunit = ifc.run("unit.add_conversion_based_unit", name=unit.get_scene_unit_name("LENGTHUNIT")) areaunit = ifc.run("unit.add_conversion_based_unit", name=unit.get_scene_unit_name("AREAUNIT")) volumeunit = ifc.run("unit.add_conversion_based_unit", name=unit.get_scene_unit_name("VOLUMEUNIT")) - massunit = ifc.run("unit.add_conversion_based_unit", name=unit.get_scene_unit_name("MASSUNIT").lower()) + planeangleunit = ifc.run("unit.add_conversion_based_unit", name="degree") + units = [lengthunit, areaunit, volumeunit, planeangleunit] - time_unit_name = unit.get_scene_unit_name("TIMEUNIT") - if time_unit_name == "SECOND": - timeunit = ifc.run("unit.add_si_unit", unit_type="TIMEUNIT", prefix=None) - else: - timeunit = ifc.run("unit.add_conversion_based_unit", name=time_unit_name.lower()) - - planeangleunit = ifc.run("unit.add_conversion_based_unit", name="degree") - ifc.run("unit.assign_unit", units=[lengthunit, areaunit, volumeunit, planeangleunit, massunit, timeunit]) + if unit.add_mass_and_time_units(): + massunit = ifc.run("unit.add_conversion_based_unit", name=unit.get_scene_unit_name("MASSUNIT").lower()) + time_unit_name = unit.get_scene_unit_name("TIMEUNIT") + if time_unit_name == "SECOND": + timeunit = ifc.run("unit.add_si_unit", unit_type="TIMEUNIT", prefix=None) + else: + timeunit = ifc.run("unit.add_conversion_based_unit", name=time_unit_name.lower()) + units += [massunit, timeunit] + print("Add mass and time units:", unit.add_mass_and_time_units()) + print("Assigning units:", units) + ifc.run("unit.assign_unit", units=units) def assign_unit(ifc: type[tool.Ifc], unit_tool: type[tool.Unit], unit: ifcopenshell.entity_instance) -> None: diff --git a/src/bonsai/bonsai/tool/unit.py b/src/bonsai/bonsai/tool/unit.py index a3c9569d62..c982c43523 100644 --- a/src/bonsai/bonsai/tool/unit.py +++ b/src/bonsai/bonsai/tool/unit.py @@ -499,3 +499,9 @@ class Unit(bonsai.core.tool.Unit): elif ifc_class == "IfcMonetaryUnit": return "COPY_ID" return "MOD_MESHDEFORM" + + @classmethod + def add_mass_and_time_units(cls) -> bool: + """Return True if the user wants to add mass and time units, False otherwise.""" + bim_props = tool.Blender.get_bim_props() + return getattr(bim_props, "add_mass_time_units", False) diff --git a/src/bonsai/test/core/test_unit.py b/src/bonsai/test/core/test_unit.py index 818ad72021..2bbd783cc3 100644 --- a/src/bonsai/test/core/test_unit.py +++ b/src/bonsai/test/core/test_unit.py @@ -26,6 +26,7 @@ class TestAssignSceneUnits: unit.get_scene_unit_si_prefix("LENGTHUNIT").should_be_called().will_return("prefix") unit.get_scene_unit_si_prefix("AREAUNIT").should_be_called().will_return("prefix") unit.get_scene_unit_si_prefix("VOLUMEUNIT").should_be_called().will_return("prefix") + unit.add_mass_and_time_units().should_be_called().will_return(True) unit.get_scene_unit_si_prefix("MASSUNIT").should_be_called().will_return("KILO") unit.get_scene_unit_si_prefix("TIMEUNIT").should_be_called().will_return(None) @@ -45,11 +46,25 @@ class TestAssignSceneUnits: ).should_be_called() subject.assign_scene_units(ifc, unit) + def test_creating_and_assigning_metric_units_without_mass_and_time(self, ifc, unit): + unit.is_scene_unit_metric().should_be_called().will_return(True) + unit.get_scene_unit_si_prefix("LENGTHUNIT").should_be_called().will_return("CENTI") + unit.get_scene_unit_si_prefix("AREAUNIT").should_be_called().will_return("CENTI") + unit.get_scene_unit_si_prefix("VOLUMEUNIT").should_be_called().will_return("CENTI") + unit.add_mass_and_time_units().should_be_called().will_return(False) + ifc.run("unit.add_si_unit", unit_type="LENGTHUNIT", prefix="CENTI").should_be_called().will_return("lengthunit") + ifc.run("unit.add_si_unit", unit_type="AREAUNIT", prefix="CENTI").should_be_called().will_return("areaunit") + ifc.run("unit.add_si_unit", unit_type="VOLUMEUNIT", prefix="CENTI").should_be_called().will_return("volumeunit") + ifc.run("unit.add_conversion_based_unit", name="degree").should_be_called().will_return("planeangleunit") + ifc.run("unit.assign_unit", units=["lengthunit", "areaunit", "volumeunit", "planeangleunit"]).should_be_called() + subject.assign_scene_units(ifc, unit) + def test_creating_and_assigning_imperial_units(self, ifc, unit): unit.is_scene_unit_metric().should_be_called().will_return(False) unit.get_scene_unit_name("LENGTHUNIT").should_be_called().will_return("foot") unit.get_scene_unit_name("AREAUNIT").should_be_called().will_return("square foot") unit.get_scene_unit_name("VOLUMEUNIT").should_be_called().will_return("cubic foot") + unit.add_mass_and_time_units().should_be_called().will_return(True) unit.get_scene_unit_name("MASSUNIT").should_be_called().will_return("pound") unit.get_scene_unit_name("TIMEUNIT").should_be_called().will_return("SECOND") @@ -65,11 +80,26 @@ class TestAssignSceneUnits: ).should_be_called() subject.assign_scene_units(ifc, unit) + def test_creating_and_assigning_imperial_units_without_mass_and_time(self, ifc, unit): + unit.is_scene_unit_metric().should_be_called().will_return(False) + unit.get_scene_unit_name("LENGTHUNIT").should_be_called().will_return("yard") + unit.get_scene_unit_name("AREAUNIT").should_be_called().will_return("square yard") + unit.get_scene_unit_name("VOLUMEUNIT").should_be_called().will_return("cubic yard") + unit.add_mass_and_time_units().should_be_called().will_return(False) + ifc.run("unit.add_conversion_based_unit", name="yard").should_be_called().will_return("lengthunit") + ifc.run("unit.add_conversion_based_unit", name="square yard").should_be_called().will_return("areaunit") + ifc.run("unit.add_conversion_based_unit", name="cubic yard").should_be_called().will_return("volumeunit") + ifc.run("unit.add_conversion_based_unit", name="degree").should_be_called().will_return("planeangleunit") + ifc.run("unit.assign_unit", units=["lengthunit", "areaunit", "volumeunit", "planeangleunit"]).should_be_called() + subject.assign_scene_units(ifc, unit) + + def test_creating_metric_units_with_conversion_based_mass_and_time(self, ifc, unit): unit.is_scene_unit_metric().should_be_called().will_return(True) unit.get_scene_unit_si_prefix("LENGTHUNIT").should_be_called().will_return("MILLI") unit.get_scene_unit_si_prefix("AREAUNIT").should_be_called().will_return(None) unit.get_scene_unit_si_prefix("VOLUMEUNIT").should_be_called().will_return(None) + unit.add_mass_and_time_units().should_be_called().will_return(True) unit.get_scene_unit_si_prefix("MASSUNIT").should_be_called().will_return("CONVERSION") unit.get_scene_unit_name("MASSUNIT").should_be_called().will_return("tonne") unit.get_scene_unit_si_prefix("TIMEUNIT").should_be_called().will_return("CONVERSION") @@ -92,6 +122,7 @@ class TestAssignSceneUnits: unit.get_scene_unit_name("LENGTHUNIT").should_be_called().will_return("inch") unit.get_scene_unit_name("AREAUNIT").should_be_called().will_return("square inch") unit.get_scene_unit_name("VOLUMEUNIT").should_be_called().will_return("cubic inch") + unit.add_mass_and_time_units().should_be_called().will_return(True) unit.get_scene_unit_name("MASSUNIT").should_be_called().will_return("ounce") unit.get_scene_unit_name("TIMEUNIT").should_be_called().will_return("hour")