mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
proposal to add massunit and timeunit in project creation wizard
This commit is contained in:
@@ -98,6 +98,8 @@ 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"
|
||||
@@ -105,6 +107,8 @@ 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"
|
||||
@@ -112,6 +116,8 @@ 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"
|
||||
@@ -119,6 +125,8 @@ 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 = "IFC4 Demo Template.ifc"
|
||||
|
||||
if self.preset != "wizard":
|
||||
|
||||
@@ -356,6 +356,10 @@ class BIM_PT_new_project_wizard(Panel):
|
||||
row.prop(props, "area_unit", text="Area Unit")
|
||||
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")
|
||||
|
||||
row = self.layout.row()
|
||||
|
||||
@@ -586,7 +586,28 @@ class BIMProperties(PropertyGroup):
|
||||
],
|
||||
name="IFC Volume Unit",
|
||||
)
|
||||
mass_unit: EnumProperty(
|
||||
items=[
|
||||
("KILOGRAM", "Kilogram", "Kilograms"),
|
||||
("GRAM", "Gram", "Grams"),
|
||||
("POUND", "Pound (Mass)", "Pounds"),
|
||||
("OUNCE", "Ounce", "Ounces"),
|
||||
("TON", "Ton", "Metric Tons"),
|
||||
],
|
||||
name="Mass Unit",
|
||||
default="KILOGRAM",
|
||||
)
|
||||
|
||||
time_unit: EnumProperty(
|
||||
items=[
|
||||
("SECOND", "Second", "Seconds"),
|
||||
("MINUTE", "Minutes", "Minutes"),
|
||||
("HOUR", "Hour", "Hours"),
|
||||
("DAY", "Day", "Days"),
|
||||
],
|
||||
name="Time Unit",
|
||||
default="HOUR",
|
||||
)
|
||||
if TYPE_CHECKING:
|
||||
is_dirty: bool
|
||||
schema_dir: str
|
||||
@@ -599,6 +620,8 @@ class BIMProperties(PropertyGroup):
|
||||
section_line_decorator_width: float
|
||||
area_unit: str
|
||||
volume_unit: str
|
||||
mass_unit: str
|
||||
time_unit: str
|
||||
|
||||
|
||||
class IfcParameter(PropertyGroup):
|
||||
|
||||
@@ -34,14 +34,29 @@ def assign_scene_units(ifc: type[tool.Ifc], unit: type[tool.Unit]) -> None:
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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"))
|
||||
timeunit = ifc.run("unit.add_conversion_based_unit", name=unit.get_scene_unit_name("TIMEUNIT"))
|
||||
|
||||
planeangleunit = ifc.run("unit.add_conversion_based_unit", name="degree")
|
||||
|
||||
ifc.run("unit.assign_unit", units=[lengthunit, areaunit, volumeunit, planeangleunit])
|
||||
ifc.run("unit.assign_unit", units=[lengthunit, areaunit, volumeunit, planeangleunit, massunit, timeunit])
|
||||
|
||||
|
||||
def assign_unit(ifc: type[tool.Ifc], unit_tool: type[tool.Unit], unit: ifcopenshell.entity_instance) -> None:
|
||||
|
||||
@@ -266,7 +266,7 @@ def parse_distance_string(input_string: str, use_project_unit: bool = True) -> t
|
||||
|
||||
|
||||
class Unit(bonsai.core.tool.Unit):
|
||||
UNIT_TYPE = Literal["LENGTHUNIT", "AREAUNIT", "VOLUMEUNIT"]
|
||||
UNIT_TYPE = Literal["LENGTHUNIT", "AREAUNIT", "VOLUMEUNIT", "MASSUNIT", "TIMEUNIT"]
|
||||
|
||||
@staticmethod
|
||||
def format_distance(meters: float, use_imperial: bool = None, **kwargs) -> str:
|
||||
@@ -343,6 +343,10 @@ class Unit(bonsai.core.tool.Unit):
|
||||
return bim_props.area_unit
|
||||
elif unit_type == "VOLUMEUNIT":
|
||||
return bim_props.volume_unit
|
||||
elif unit_type == "MASSUNIT":
|
||||
return bim_props.mass_unit
|
||||
elif unit_type == "TIMEUNIT":
|
||||
return bim_props.time_unit
|
||||
else:
|
||||
assert_never(unit_type)
|
||||
|
||||
@@ -359,6 +363,26 @@ class Unit(bonsai.core.tool.Unit):
|
||||
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 == "KILOGRAM":
|
||||
return "KILO"
|
||||
elif unit == "GRAM":
|
||||
return None
|
||||
elif unit == "TON":
|
||||
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:
|
||||
|
||||
@@ -27,6 +27,8 @@ def assign_unit(
|
||||
length: Optional[dict] = None,
|
||||
area: Optional[dict] = None,
|
||||
volume: Optional[dict] = None,
|
||||
mass: Optional[dict] = None,
|
||||
time: Optional[dict] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assign default project units
|
||||
|
||||
@@ -51,9 +53,11 @@ def assign_unit(
|
||||
# You need a project before you can assign units.
|
||||
ifcopenshell.api.root.create_entity(model, ifc_class="IfcProject")
|
||||
|
||||
# Millimeters and square meters
|
||||
# Millimeters, square meters, kilograms, and seconds
|
||||
length = ifcopenshell.api.unit.add_si_unit(model, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
area = ifcopenshell.api.unit.add_si_unit(model, unit_type="AREAUNIT")
|
||||
mass = ifcopenshell.api.unit.add_si_unit(model, unit_type="MASSUNIT", prefix="KILO")
|
||||
time = ifcopenshell.api.unit.add_si_unit(model, unit_type="TIMEUNIT")
|
||||
|
||||
# Make it our default units, if we are doing a metric building
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[length, area])
|
||||
@@ -71,6 +75,8 @@ def assign_unit(
|
||||
usecase.settings["length"] = length or {"is_metric": True, "raw": "MILLIMETERS"}
|
||||
usecase.settings["area"] = area or {"is_metric": True, "raw": "METERS"}
|
||||
usecase.settings["volume"] = volume or {"is_metric": True, "raw": "METERS"}
|
||||
usecase.settings["mass"] = mass or {"is_metric": True, "raw": "KILOGRAM"}
|
||||
usecase.settings["time"] = time or {"is_metric": True, "raw": "SECOND"}
|
||||
return usecase.execute()
|
||||
|
||||
|
||||
@@ -116,7 +122,45 @@ class Usecase:
|
||||
units.add(unit)
|
||||
unit_assignment.Units = list(units)
|
||||
|
||||
def create_time_conversion_unit(self, name: str, factor: float) -> ifcopenshell.entity_instance:
|
||||
"""Create a conversion-based time unit"""
|
||||
dimensional_exponents = self.file.createIfcDimensionalExponents(0, 0, 1, 0, 0, 0, 0)
|
||||
si_unit = self.file.createIfcSIUnit(None, "TIMEUNIT", None, "SECOND")
|
||||
value_component = self.file.create_entity("IfcReal", **{"wrappedValue": factor})
|
||||
conversion_factor = self.file.createIfcMeasureWithUnit(value_component, si_unit)
|
||||
return self.file.createIfcConversionBasedUnit(dimensional_exponents, "TIMEUNIT", name, conversion_factor)
|
||||
|
||||
def create_mass_conversion_unit(self, name: str, factor: float) -> ifcopenshell.entity_instance:
|
||||
"""Create a conversion-based mass unit"""
|
||||
dimensional_exponents = self.file.createIfcDimensionalExponents(0, 1, 0, 0, 0, 0, 0) # Mass dimension
|
||||
si_unit = self.file.createIfcSIUnit(None, "MASSUNIT", "KILO", "GRAM")
|
||||
value_component = self.file.create_entity("IfcReal", **{"wrappedValue": factor})
|
||||
conversion_factor = self.file.createIfcMeasureWithUnit(value_component, si_unit)
|
||||
return self.file.createIfcConversionBasedUnit(dimensional_exponents, "MASSUNIT", name, conversion_factor)
|
||||
|
||||
def create_metric_unit(self, unit_type: str, data: dict) -> ifcopenshell.entity_instance:
|
||||
if unit_type == "mass":
|
||||
if data["raw"] == "KILOGRAM":
|
||||
return self.file.createIfcSIUnit(None, "MASSUNIT", "KILO", "GRAM")
|
||||
elif data["raw"] == "GRAM":
|
||||
return self.file.createIfcSIUnit(None, "MASSUNIT", None, "GRAM")
|
||||
elif data["raw"] == "TON":
|
||||
return self.file.createIfcSIUnit(None, "MASSUNIT", "MEGA", "GRAM")
|
||||
else:
|
||||
return self.file.createIfcSIUnit(None, "MASSUNIT", "KILO", "GRAM")
|
||||
|
||||
elif unit_type == "time":
|
||||
if data["raw"] == "SECOND":
|
||||
return self.file.createIfcSIUnit(None, "TIMEUNIT", None, "SECOND")
|
||||
elif data["raw"] == "MINUTE":
|
||||
return self.create_time_conversion_unit("minute", 60.0)
|
||||
elif data["raw"] == "HOUR":
|
||||
return self.create_time_conversion_unit("hour", 3600.0)
|
||||
elif data["raw"] == "DAY":
|
||||
return self.create_time_conversion_unit("day", 86400.0)
|
||||
else:
|
||||
return self.file.createIfcSIUnit(None, "TIMEUNIT", None, "SECOND")
|
||||
|
||||
type_prefix = ""
|
||||
if unit_type == "area":
|
||||
type_prefix = "SQUARE_"
|
||||
@@ -139,6 +183,26 @@ class Usecase:
|
||||
elif unit_type == "volume":
|
||||
dimensional_exponents = self.file.createIfcDimensionalExponents(3, 0, 0, 0, 0, 0, 0)
|
||||
name_prefix = "cubic"
|
||||
elif unit_type == "mass":
|
||||
if data["raw"] == "POUND":
|
||||
return self.create_mass_conversion_unit("pound", 0.45359237)
|
||||
elif data["raw"] == "OUNCE":
|
||||
return self.create_mass_conversion_unit("ounce", 0.0283495)
|
||||
else:
|
||||
return self.create_mass_conversion_unit("pound", 0.45359237)
|
||||
|
||||
elif unit_type == "time":
|
||||
if data["raw"] == "SECOND":
|
||||
return self.file.createIfcSIUnit(None, "TIMEUNIT", None, "SECOND")
|
||||
elif data["raw"] == "MINUTE":
|
||||
return self.create_time_conversion_unit("minute", 60.0)
|
||||
elif data["raw"] == "HOUR":
|
||||
return self.create_time_conversion_unit("hour", 3600.0)
|
||||
elif data["raw"] == "DAY":
|
||||
return self.create_time_conversion_unit("day", 86400.0)
|
||||
else:
|
||||
return self.file.createIfcSIUnit(None, "TIMEUNIT", None, "SECOND")
|
||||
|
||||
si_unit = self.file.createIfcSIUnit(
|
||||
None,
|
||||
"{}UNIT".format(unit_type.upper()),
|
||||
|
||||
Reference in New Issue
Block a user