You can now edit the unit basis of a cost value for a schedule of rates

This commit is contained in:
Dion Moult
2021-08-13 11:56:33 +10:00
parent 44c868caed
commit 2a6d6cfdbf
7 changed files with 120 additions and 20 deletions
@@ -8,6 +8,7 @@ from blenderbim.bim.module.cost.prop import purge
from blenderbim.bim.ifc import IfcStore
from bpy_extras.io_utils import ImportHelper
from ifcopenshell.api.cost.data import Data
from ifcopenshell.api.unit.data import Data as UnitData
class AddCostSchedule(bpy.types.Operator):
@@ -100,21 +101,7 @@ class EnableEditingCostItems(bpy.types.Operator):
def execute(self, context):
if context.preferences.addons["blenderbim"].preferences.should_play_chaching_sound:
# lol
# TODO: make pitch higher as costs rise
try:
import aud
device = aud.Device()
# chaching.mp3 is by Lucish_ CC-BY-3.0 https://freesound.org/people/Lucish_/sounds/554841/
sound = aud.Sound(os.path.join(context.scene.BIMProperties.data_dir, "chaching.mp3"))
handle = device.play(sound)
sound_buffered = aud.Sound.buffer(sound)
handle_buffered = device.play(sound_buffered)
handle.stop()
handle_buffered.stop()
except:
pass # ah well
self.play_chaching_sound() # lol
self.props = context.scene.BIMCostProperties
self.props.active_cost_schedule_id = self.cost_schedule
while len(self.props.cost_items) > 0:
@@ -126,6 +113,22 @@ class EnableEditingCostItems(bpy.types.Operator):
self.props.is_editing = "COST_ITEMS"
return {"FINISHED"}
def play_chaching_sound(self):
# TODO: make pitch higher as costs rise
try:
import aud
device = aud.Device()
# chaching.mp3 is by Lucish_ CC-BY-3.0 https://freesound.org/people/Lucish_/sounds/554841/
sound = aud.Sound(os.path.join(context.scene.BIMProperties.data_dir, "chaching.mp3"))
handle = device.play(sound)
sound_buffered = aud.Sound.buffer(sound)
handle_buffered = device.play(sound_buffered)
handle.stop()
handle_buffered.stop()
except:
pass # ah well
def create_new_cost_item_li(self, related_object_id, level_index):
cost_item = Data.cost_items[related_object_id]
new = self.props.cost_items.add()
@@ -566,6 +569,35 @@ class EnableEditingCostItemValue(bpy.types.Operator):
prop.data_type = "float"
prop.float_value = 0.0 if prop.is_null else data[name]
return True
if (
name == "UnitBasis"
and Data.cost_schedules[bpy.context.scene.BIMCostProperties.active_cost_schedule_id]["PredefinedType"]
== "SCHEDULEOFRATES"
):
prop = self.props.cost_value_attributes.add()
prop.name = "UnitBasisValue"
prop.data_type = "float"
prop.is_null = data["UnitBasis"] is None
prop.is_optional = True
if data["UnitBasis"]:
prop.float_value = data["UnitBasis"]["ValueComponent"] or 0
else:
prop.float_value = 0
prop = self.props.cost_value_attributes.add()
prop.name = "UnitBasisUnit"
prop.data_type = "enum"
prop.is_null = prop.is_optional = False
units = {}
for unit_id, unit in UnitData.units.items():
if unit.get("UnitType", None) in ["AREAUNIT", "LENGTHUNIT", "TIMEUNIT", "VOLUMEUNIT", "MASSUNIT"]:
name = unit["Name"]
if unit.get("Prefix", None):
name = f"(unit['Prefix']) {name}"
units[unit_id] = f"{unit['UnitType']} / {name}"
prop.enum_items = json.dumps(units)
if data["UnitBasis"] and data["UnitBasis"]["UnitComponent"]:
prop.enum_value = str(data["UnitBasis"]["UnitComponent"])
return True
class DisableEditingCostItemValue(bpy.types.Operator):
@@ -590,7 +622,7 @@ class EditCostValue(bpy.types.Operator):
def _execute(self, context):
props = context.scene.BIMCostProperties
attributes = blenderbim.bim.helper.export_attributes(props.cost_value_attributes)
attributes = blenderbim.bim.helper.export_attributes(props.cost_value_attributes, self.export_attributes)
self.file = IfcStore.get_file()
ifcopenshell.api.run(
"cost.edit_cost_value",
@@ -601,6 +633,21 @@ class EditCostValue(bpy.types.Operator):
bpy.ops.bim.disable_editing_cost_item_value()
return {"FINISHED"}
def export_attributes(self, attributes, prop):
if prop.name == "UnitBasisValue":
if prop.is_null:
attributes["UnitBasis"] = None
return True
attributes["UnitBasis"] = {
"ValueComponent": prop.float_value or 1,
"UnitComponent": IfcStore.get_file().by_id(
int(bpy.context.scene.BIMCostProperties.cost_value_attributes.get("UnitBasisUnit").enum_value)
),
}
return True
if prop.name == "UnitBasisUnit":
return True
class CopyCostItemValues(bpy.types.Operator):
bl_idname = "bim.copy_cost_item_values"
@@ -369,9 +369,10 @@ class BIM_UL_cost_items(UIList):
split1 = row.split(factor=0.7)
split1.prop(item, "name", emboss=False, text="")
op = row.operator("bim.enable_editing_cost_item_quantities", text="", icon="PROPERTIES")
op.cost_item = item.ifc_definition_id
row.label(text="{0:.2f}".format(cost_item["TotalCostQuantity"]) + f" ({cost_item['UnitSymbol']})")
if Data.cost_schedules[props.active_cost_schedule_id]["PredefinedType"] != "SCHEDULEOFRATES":
op = row.operator("bim.enable_editing_cost_item_quantities", text="", icon="PROPERTIES")
op.cost_item = item.ifc_definition_id
row.label(text="{0:.2f}".format(cost_item["TotalCostQuantity"]) + f" ({cost_item['UnitSymbol']})")
op = row.operator("bim.enable_editing_cost_item_values", text="", icon="DISC")
op.cost_item = item.ifc_definition_id
@@ -344,8 +344,14 @@ class EditResourceTime(bpy.types.Operator):
def export_attributes(self, attributes, prop):
if "Start" in prop.name or "Finish" in prop.name or prop.name == "StatusTime":
if prop.is_null:
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_datetime(prop.string_value)
return True
elif prop.name =="LevelingDelay" or "Work" in prop.name:
if prop.is_null:
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_duration(prop.string_value)
return True
@@ -58,9 +58,15 @@ class EditWorkPlan(bpy.types.Operator):
def export_attributes(self, attributes, prop):
if "Date" in prop.name or "Time" in prop.name:
if prop.is_null:
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_datetime(prop.string_value)
return True
elif prop.name == "Duration" or prop.name == "TotalFloat":
if prop.is_null:
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_duration(prop.string_value)
return True
@@ -214,9 +220,15 @@ class EditWorkSchedule(bpy.types.Operator):
def export_attributes(self, attributes, prop):
if "Date" in prop.name or "Time" in prop.name:
if prop.is_null:
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_datetime(prop.string_value)
return True
elif prop.name == "Duration" or prop.name == "TotalFloat":
if prop.is_null:
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_duration(prop.string_value)
return True
@@ -564,9 +576,15 @@ class EditTaskTime(bpy.types.Operator):
def export_attributes(self, attributes, prop):
if "Start" in prop.name or "Finish" in prop.name or prop.name == "StatusTime":
if prop.is_null:
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_datetime(prop.string_value)
return True
elif prop.name == "ScheduleDuration":
if prop.is_null:
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_duration(prop.string_value)
return True