mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
Remove preference to mass/time and make it default with simpler code
I generally like to minimise knobs and dials, so this is now part of the wizard but now defaults to a "NONE" unit. You also now have the option to choose "NONE" for area / volume units which makes things consistent. Enum names also match the IFC lowercase convention for conversion based units. This also simplifies the core logic and treats all units the same way instead of special cases for each unit type. (length is still special and required in Bonsai as we are inherently graphical)
This commit is contained in:
@@ -368,21 +368,11 @@ 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")
|
||||
|
||||
if tool.Blender.get_addon_preferences().mass_time_units_in_wizard:
|
||||
header, body = self.layout.panel("Mass and Time Units", default_closed=True)
|
||||
if header:
|
||||
header.label(text="Mass and Time Units")
|
||||
if body:
|
||||
label = "Add Mass and Time Units" if not props.add_mass_time_units else "Remove Mass and Time Units"
|
||||
body.prop(props, "add_mass_time_units", toggle=True, text=label)
|
||||
if props.add_mass_time_units:
|
||||
row = body.row()
|
||||
row.prop(props, "mass_unit", text="Mass Unit")
|
||||
row = body.row()
|
||||
row.prop(props, "time_unit", text="Time Unit")
|
||||
|
||||
self.layout.use_property_split = True
|
||||
row = self.layout.row()
|
||||
row.operator("bim.create_project")
|
||||
|
||||
@@ -589,6 +589,7 @@ class BIMProperties(PropertyGroup):
|
||||
area_unit: EnumProperty(
|
||||
default="SQUARE_METRE",
|
||||
items=[
|
||||
("NONE", "None", ""),
|
||||
("NANO/SQUARE_METRE", "Square Nanometre", ""),
|
||||
("MICRO/SQUARE_METRE", "Square Micrometre", ""),
|
||||
("MILLI/SQUARE_METRE", "Square Millimetre", ""),
|
||||
@@ -606,6 +607,7 @@ class BIMProperties(PropertyGroup):
|
||||
volume_unit: EnumProperty(
|
||||
default="CUBIC_METRE",
|
||||
items=[
|
||||
("NONE", "None", ""),
|
||||
("NANO/CUBIC_METRE", "Cubic Nanometre", ""),
|
||||
("MICRO/CUBIC_METRE", "Cubic Micrometre", ""),
|
||||
("MILLI/CUBIC_METRE", "Cubic Millimetre", ""),
|
||||
@@ -619,31 +621,28 @@ 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"),
|
||||
("NONE", "None", ""),
|
||||
("GRAM", "Gram", "Grams"),
|
||||
("POUND", "Pound", "Pounds"),
|
||||
("OUNCE", "Ounce", "Ounces"),
|
||||
("TONNE", "Tonne", "Metric Tons"),
|
||||
("KILO/KILOGRAM", "Kilogram", "Kilograms"),
|
||||
("MEGA/TONNE", "Tonne", "Metric Tons"),
|
||||
("pound", "Pound", "Pounds"),
|
||||
("ounce", "Ounce", "Ounces"),
|
||||
],
|
||||
name="Mass Unit",
|
||||
default="KILOGRAM",
|
||||
default="NONE",
|
||||
)
|
||||
time_unit: EnumProperty(
|
||||
items=[
|
||||
("NONE", "None", ""),
|
||||
("SECOND", "Second", "Seconds"),
|
||||
("MINUTE", "Minute", "Minutes"),
|
||||
("HOUR", "Hour", "Hours"),
|
||||
("DAY", "Day", "Days"),
|
||||
("minute", "Minute", "Minutes"),
|
||||
("hour", "Hour", "Hours"),
|
||||
("day", "Day", "Days"),
|
||||
],
|
||||
name="Time Unit",
|
||||
default="HOUR",
|
||||
default="NONE",
|
||||
)
|
||||
tab_visibilities: CollectionProperty(type=BIMTabVisibility, name="Tab Visibilities")
|
||||
active_tab_visibility_index: IntProperty(name="Active Tab Visibility Index")
|
||||
|
||||
@@ -717,12 +717,6 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
||||
default=False,
|
||||
)
|
||||
|
||||
mass_time_units_in_wizard: BoolProperty(
|
||||
name="Mass and time units in project wizard",
|
||||
description="Show mass and time units section in the new project wizard panel",
|
||||
default=False,
|
||||
)
|
||||
|
||||
chain_filter_with_set_operations: BoolProperty(
|
||||
name="NEW Filter mode: Enable chained filters with set operations",
|
||||
description="Enable chaining search filters with set operations: ADD (union: combine sets), SUBTRACT (difference: remove from set), FILTER (intersection: only elements in both sets), with autocomplete suggestions for filter values",
|
||||
|
||||
@@ -1124,7 +1124,7 @@ class Unit:
|
||||
def enable_editing_units(cls): pass
|
||||
def export_unit_attributes(cls): pass
|
||||
def get_scene_unit_name(cls, unit_type): pass
|
||||
def get_scene_unit_si_prefix(cls, unit_type): pass
|
||||
def get_scene_unit_si_prefix(cls, name): pass
|
||||
def import_unit_attributes(cls, unit): pass
|
||||
def import_units(cls): pass
|
||||
def is_scene_unit_metric(cls): pass
|
||||
|
||||
@@ -27,46 +27,17 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
def assign_scene_units(ifc: type[tool.Ifc], unit: type[tool.Unit]) -> None:
|
||||
if unit.is_scene_unit_metric():
|
||||
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]
|
||||
|
||||
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())
|
||||
units = []
|
||||
for unit_type in ["LENGTHUNIT", "AREAUNIT", "VOLUMEUNIT", "MASSUNIT", "TIMEUNIT"]:
|
||||
if name := unit.get_scene_unit_name(unit_type):
|
||||
if unit.is_si_unit(name):
|
||||
units.append(
|
||||
ifc.run("unit.add_si_unit", unit_type=unit_type, prefix=unit.get_scene_unit_si_prefix(name))
|
||||
)
|
||||
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]
|
||||
|
||||
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"))
|
||||
planeangleunit = ifc.run("unit.add_conversion_based_unit", name="degree")
|
||||
units = [lengthunit, areaunit, volumeunit, planeangleunit]
|
||||
|
||||
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]
|
||||
ifc.run("unit.assign_unit", units=units)
|
||||
units.append(ifc.run("unit.add_conversion_based_unit", name=name))
|
||||
if 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:
|
||||
|
||||
@@ -330,66 +330,26 @@ class Unit(bonsai.core.tool.Unit):
|
||||
return bonsai.bim.helper.export_attributes(props.unit_attributes, callback=callback)
|
||||
|
||||
@classmethod
|
||||
def get_scene_unit_name(cls, unit_type: UNIT_TYPE) -> str:
|
||||
bim_props = tool.Blender.get_bim_props()
|
||||
def get_scene_unit_name(cls, unit_type: UNIT_TYPE) -> str | None:
|
||||
if unit_type == "LENGTHUNIT":
|
||||
assert bpy.context.scene
|
||||
props = bpy.context.scene.unit_settings
|
||||
if props.length_unit == "MILES":
|
||||
return "mile"
|
||||
elif props.length_unit == "FEET" or props.length_unit == "ADAPTIVE":
|
||||
return "foot"
|
||||
elif props.length_unit == "INCHES":
|
||||
return "inch"
|
||||
elif props.length_unit == "THOU":
|
||||
return "thou"
|
||||
return "foot"
|
||||
elif unit_type == "AREAUNIT":
|
||||
return bim_props.area_unit
|
||||
elif unit_type == "VOLUMEUNIT":
|
||||
return bim_props.volume_unit
|
||||
elif unit_type == "MASSUNIT":
|
||||
return bim_props.mass_unit.lower()
|
||||
elif unit_type == "TIMEUNIT":
|
||||
return bim_props.time_unit.lower()
|
||||
else:
|
||||
assert_never(unit_type)
|
||||
name = bpy.context.scene.unit_settings.length_unit
|
||||
name = {"MILES": "mile", "FEET": "foot", "INCHES": "inch", "THOU": "thou", "ADAPTIVE": "METERS"}.get(
|
||||
name, name
|
||||
)
|
||||
if len(name) > len("METERS") and name.endswith("METERS"):
|
||||
return f"{name[:-6]}/METRE"
|
||||
return name
|
||||
bim_props = tool.Blender.get_bim_props()
|
||||
if (name := getattr(bim_props, f"{unit_type[:-4].lower()}_unit")) != "NONE":
|
||||
return name
|
||||
|
||||
@classmethod
|
||||
def get_scene_unit_si_prefix(cls, unit_type: UNIT_TYPE) -> Union[str, None]:
|
||||
bim_props = tool.Blender.get_bim_props()
|
||||
if unit_type == "LENGTHUNIT":
|
||||
assert bpy.context.scene
|
||||
props = bpy.context.scene.unit_settings
|
||||
if props.length_unit == "ADAPTIVE" or props.length_unit == "METERS":
|
||||
return
|
||||
return props.length_unit.replace("METERS", "")
|
||||
elif unit_type == "AREAUNIT":
|
||||
unit = bim_props.area_unit
|
||||
elif unit_type == "VOLUMEUNIT":
|
||||
unit = bim_props.volume_unit
|
||||
elif unit_type == "MASSUNIT":
|
||||
unit = bim_props.mass_unit
|
||||
if unit == "GRAM":
|
||||
return None
|
||||
elif unit == "KILOGRAM":
|
||||
return "KILO"
|
||||
elif unit == "TONNE":
|
||||
return "MEGA"
|
||||
elif unit in ["POUND", "OUNCE"]:
|
||||
return "CONVERSION"
|
||||
else:
|
||||
return None
|
||||
elif unit_type == "TIMEUNIT":
|
||||
unit = bim_props.time_unit
|
||||
if unit == "SECOND":
|
||||
return None
|
||||
else:
|
||||
return "CONVERSION"
|
||||
else:
|
||||
assert_never(unit_type)
|
||||
if "/" in unit:
|
||||
return unit.split("/")[0]
|
||||
def is_si_unit(cls, name: str) -> bool:
|
||||
return name[0].isupper()
|
||||
|
||||
@classmethod
|
||||
def get_scene_unit_si_prefix(cls, name: str) -> str | None:
|
||||
return name.split("/")[0] if "/" in name else None
|
||||
|
||||
@classmethod
|
||||
def import_unit_attributes(cls, unit: ifcopenshell.entity_instance) -> None:
|
||||
@@ -504,9 +464,3 @@ 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)
|
||||
|
||||
Reference in New Issue
Block a user