mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 13:46:54 +00:00
Fix calculating resource work based from parent's productivity and improve UI to show this
This commit is contained in:
@@ -58,6 +58,7 @@ class ResourceData:
|
|||||||
}
|
}
|
||||||
if resource.is_a() in ["IfcLaborResource", "IfcConstructionEquipmentResource"]:
|
if resource.is_a() in ["IfcLaborResource", "IfcConstructionEquipmentResource"]:
|
||||||
results[resource.id()]["Productivity"] = {}
|
results[resource.id()]["Productivity"] = {}
|
||||||
|
results[resource.id()]["InheritedProductivity"] = {}
|
||||||
productivity = cls.get_productivity(resource)
|
productivity = cls.get_productivity(resource)
|
||||||
if productivity:
|
if productivity:
|
||||||
results[resource.id()]["Productivity"] = {
|
results[resource.id()]["Productivity"] = {
|
||||||
@@ -65,12 +66,34 @@ class ResourceData:
|
|||||||
"TimeConsumed": ifcopenshell.util.resource.get_unit_consumed(productivity),
|
"TimeConsumed": ifcopenshell.util.resource.get_unit_consumed(productivity),
|
||||||
"QuantityProducedName": ifcopenshell.util.resource.get_quantity_produced_name(productivity),
|
"QuantityProducedName": ifcopenshell.util.resource.get_quantity_produced_name(productivity),
|
||||||
}
|
}
|
||||||
|
inherited_productivity = cls.get_parent_productivity(resource)
|
||||||
|
if inherited_productivity:
|
||||||
|
results[resource.id()]["InheritedProductivity"] = {
|
||||||
|
"QuantityProduced": ifcopenshell.util.resource.get_quantity_produced(inherited_productivity),
|
||||||
|
"TimeConsumed": ifcopenshell.util.resource.get_unit_consumed(inherited_productivity),
|
||||||
|
"QuantityProducedName": ifcopenshell.util.resource.get_quantity_produced_name(
|
||||||
|
inherited_productivity
|
||||||
|
),
|
||||||
|
}
|
||||||
|
if resource.Usage:
|
||||||
|
results[resource.id()]["ScheduleWork"] = (
|
||||||
|
ifcopenshell.util.date.readable_ifc_duration(resource.Usage.ScheduleWork)
|
||||||
|
if resource.Usage.ScheduleWork
|
||||||
|
else "Calculate",
|
||||||
|
)
|
||||||
|
results[resource.id()]["ScheduleUsage"] = (
|
||||||
|
resource.Usage.ScheduleUsage if resource.Usage.ScheduleUsage else ""
|
||||||
|
)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_productivity(cls, resource):
|
def get_productivity(cls, resource):
|
||||||
return ifcopenshell.util.resource.get_productivity(resource, should_inherit=False)
|
return ifcopenshell.util.resource.get_productivity(resource, should_inherit=False)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_parent_productivity(cls, resource):
|
||||||
|
return ifcopenshell.util.resource.get_parent_productivity(resource)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def cost_values(cls):
|
def cost_values(cls):
|
||||||
results = []
|
results = []
|
||||||
|
|||||||
@@ -198,6 +198,13 @@ class CalculateResourceWork(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
active_resource = tool.Resource.get_highlighted_resource()
|
||||||
|
if active_resource:
|
||||||
|
if tool.Resource.get_productivity(active_resource, should_inherit=True):
|
||||||
|
return True
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
core.calculate_resource_work(tool.Ifc, tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
core.calculate_resource_work(tool.Ifc, tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import ifcopenshell.util.resource
|
|||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
import blenderbim.bim.module.pset.data
|
import blenderbim.bim.module.pset.data
|
||||||
|
from blenderbim.bim.module.resource.data import refresh
|
||||||
|
from blenderbim.bim.module.sequence.data import refresh as refresh_sequence
|
||||||
from blenderbim.bim.prop import StrProperty, Attribute
|
from blenderbim.bim.prop import StrProperty, Attribute
|
||||||
from bpy.types import PropertyGroup
|
from bpy.types import PropertyGroup
|
||||||
from bpy.props import (
|
from bpy.props import (
|
||||||
@@ -56,6 +58,8 @@ def updateResourceName(self, context):
|
|||||||
if props.active_resource_id == self.ifc_definition_id:
|
if props.active_resource_id == self.ifc_definition_id:
|
||||||
attribute = props.resource_attributes.get("Name")
|
attribute = props.resource_attributes.get("Name")
|
||||||
attribute.string_value = self.name
|
attribute.string_value = self.name
|
||||||
|
refresh()
|
||||||
|
tool.Sequence.refresh_task_resources()
|
||||||
|
|
||||||
|
|
||||||
def get_quantity_types(self, context):
|
def get_quantity_types(self, context):
|
||||||
@@ -72,7 +76,7 @@ def get_quantity_types(self, context):
|
|||||||
|
|
||||||
def update_active_resource_index(self, context):
|
def update_active_resource_index(self, context):
|
||||||
blenderbim.bim.module.pset.data.refresh()
|
blenderbim.bim.module.pset.data.refresh()
|
||||||
if self.should_show_productivity:
|
if self.should_show_resource_tools:
|
||||||
tool.Resource.load_productivity_data()
|
tool.Resource.load_productivity_data()
|
||||||
|
|
||||||
|
|
||||||
@@ -91,7 +95,9 @@ def updateResourceUsage(self, context):
|
|||||||
)
|
)
|
||||||
resource.Usage.ScheduleUsage = self.schedule_usage
|
resource.Usage.ScheduleUsage = self.schedule_usage
|
||||||
blenderbim.bim.module.pset.data.refresh()
|
blenderbim.bim.module.pset.data.refresh()
|
||||||
|
refresh()
|
||||||
tool.Resource.load_resource_properties()
|
tool.Resource.load_resource_properties()
|
||||||
|
tool.Sequence.refresh_task_resources()
|
||||||
|
|
||||||
|
|
||||||
class ISODuration(PropertyGroup):
|
class ISODuration(PropertyGroup):
|
||||||
@@ -144,7 +150,7 @@ class BIMResourceProperties(PropertyGroup):
|
|||||||
quantity_types: EnumProperty(items=get_quantity_types, name="Quantity Types")
|
quantity_types: EnumProperty(items=get_quantity_types, name="Quantity Types")
|
||||||
is_editing_quantity: BoolProperty(name="Is Editing Quantity")
|
is_editing_quantity: BoolProperty(name="Is Editing Quantity")
|
||||||
quantity_attributes: CollectionProperty(name="Quantity Attributes", type=Attribute)
|
quantity_attributes: CollectionProperty(name="Quantity Attributes", type=Attribute)
|
||||||
should_show_productivity: BoolProperty(name="Edit Productivity", update=update_active_resource_index)
|
should_show_resource_tools: BoolProperty(name="Edit Productivity", update=update_active_resource_index)
|
||||||
|
|
||||||
|
|
||||||
class BIMResourceProductivity(PropertyGroup):
|
class BIMResourceProductivity(PropertyGroup):
|
||||||
|
|||||||
@@ -64,11 +64,8 @@ class BIM_PT_resources(Panel):
|
|||||||
self.props,
|
self.props,
|
||||||
"active_resource_index",
|
"active_resource_index",
|
||||||
)
|
)
|
||||||
row = self.layout.row(align=True)
|
self.draw_productivity_ui(context)
|
||||||
row.alignment = "RIGHT"
|
|
||||||
row.prop(self.props, "should_show_productivity", icon="RECOVER_LAST")
|
|
||||||
if self.props.should_show_productivity:
|
|
||||||
self.draw_productivity_ui(context)
|
|
||||||
if self.props.active_resource_id and self.props.editing_resource_type == "ATTRIBUTES":
|
if self.props.active_resource_id and self.props.editing_resource_type == "ATTRIBUTES":
|
||||||
self.draw_editable_resource_attributes_ui()
|
self.draw_editable_resource_attributes_ui()
|
||||||
elif self.props.active_resource_id and self.props.editing_resource_type == "QUANTITY":
|
elif self.props.active_resource_id and self.props.editing_resource_type == "QUANTITY":
|
||||||
@@ -79,43 +76,66 @@ class BIM_PT_resources(Panel):
|
|||||||
self.draw_editable_resource_time_attributes_ui()
|
self.draw_editable_resource_time_attributes_ui()
|
||||||
|
|
||||||
def draw_productivity_ui(self, context):
|
def draw_productivity_ui(self, context):
|
||||||
total_resources = len(self.tprops.resources)
|
|
||||||
if not total_resources or self.props.active_resource_index >= total_resources:
|
|
||||||
return
|
|
||||||
|
|
||||||
ifc_definition_id = self.tprops.resources[self.props.active_resource_index].ifc_definition_id
|
|
||||||
resource = ResourceData.data["resources"][ifc_definition_id]
|
|
||||||
|
|
||||||
if not resource["type"] in ["IfcConstructionEquipmentResource", "IfcLaborResource"]:
|
|
||||||
row = self.layout.row(align=True)
|
|
||||||
row.label(text="Resource type cannot have productivity data", icon="ERROR")
|
|
||||||
return
|
|
||||||
|
|
||||||
self.productivity_props = context.scene.BIMResourceProductivity
|
|
||||||
|
|
||||||
if resource["Productivity"]:
|
|
||||||
produtivitiy_rate_message = "Current Rate: {}/{}".format(
|
|
||||||
resource["Productivity"]["QuantityProduced"], resource["Productivity"]["TimeConsumed"]
|
|
||||||
)
|
|
||||||
row = self.layout.row()
|
|
||||||
row.alignment = "LEFT"
|
|
||||||
row.label(text=produtivitiy_rate_message, icon="ARMATURE_DATA")
|
|
||||||
else:
|
|
||||||
row = self.layout.row(align=True)
|
|
||||||
row.alignment = "LEFT"
|
|
||||||
produtivitiy_rate_message = "No productivity data found"
|
|
||||||
row.label(text=produtivitiy_rate_message, icon="ARMATURE_DATA")
|
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.alignment = "RIGHT"
|
row.alignment = "RIGHT"
|
||||||
row.prop(self.productivity_props, "quantity_produced", text="Quantity Produced")
|
row.prop(self.props, "should_show_resource_tools", icon="RECOVER_LAST")
|
||||||
row.prop(self.productivity_props, "quantity_produced_name", text="Quantity Name")
|
if self.props.should_show_resource_tools:
|
||||||
row = self.layout.row()
|
total_resources = len(self.tprops.resources)
|
||||||
row.alignment = "RIGHT"
|
if not total_resources or self.props.active_resource_index >= total_resources:
|
||||||
self.draw_duration_property(self.productivity_props.quantity_consumed, row)
|
return
|
||||||
row = self.layout.row()
|
|
||||||
row.alignment = "RIGHT"
|
ifc_definition_id = self.tprops.resources[self.props.active_resource_index].ifc_definition_id
|
||||||
row.operator("bim.edit_productivity_data", text="Apply", icon="CHECKMARK")
|
resource = ResourceData.data["resources"][ifc_definition_id]
|
||||||
|
|
||||||
|
if not resource["type"] in ["IfcConstructionEquipmentResource", "IfcLaborResource"]:
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.label(text="Resource type cannot have productivity data", icon="ERROR")
|
||||||
|
else:
|
||||||
|
productivity = resource["Productivity"]
|
||||||
|
parent_productivity = resource["InheritedProductivity"]
|
||||||
|
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator(
|
||||||
|
"bim.calculate_resource_work", text="Calculate Work", icon="TEMP"
|
||||||
|
).resource = ifc_definition_id
|
||||||
|
|
||||||
|
row = self.layout.row()
|
||||||
|
row.label(text="Productivity")
|
||||||
|
row = self.layout.row()
|
||||||
|
if productivity:
|
||||||
|
produtivitiy_rate_message = "Current Productivity Rate: {} {} / {}".format(
|
||||||
|
productivity["QuantityProduced"],
|
||||||
|
productivity["QuantityProducedName"],
|
||||||
|
productivity["TimeConsumed"],
|
||||||
|
)
|
||||||
|
row.alignment = "LEFT"
|
||||||
|
row.label(text=produtivitiy_rate_message, icon="ARMATURE_DATA")
|
||||||
|
elif parent_productivity:
|
||||||
|
produtivitiy_rate_message = "Inherited Productivity Rate: {} {} / {}*".format(
|
||||||
|
parent_productivity["QuantityProduced"],
|
||||||
|
parent_productivity["QuantityProducedName"],
|
||||||
|
parent_productivity["TimeConsumed"],
|
||||||
|
)
|
||||||
|
row.alignment = "LEFT"
|
||||||
|
row.label(text=produtivitiy_rate_message, icon="ARMATURE_DATA")
|
||||||
|
else:
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.alignment = "LEFT"
|
||||||
|
produtivitiy_rate_message = "No productivity data found"
|
||||||
|
row.label(text=produtivitiy_rate_message, icon="ARMATURE_DATA")
|
||||||
|
|
||||||
|
productivity_props = context.scene.BIMResourceProductivity
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.alignment = "RIGHT"
|
||||||
|
row.prop(productivity_props, "quantity_produced", text="Quantity Produced")
|
||||||
|
row.prop(productivity_props, "quantity_produced_name", text="Quantity Name")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.alignment = "RIGHT"
|
||||||
|
self.draw_duration_property(productivity_props.quantity_consumed, row)
|
||||||
|
row = self.layout.row()
|
||||||
|
row.alignment = "RIGHT"
|
||||||
|
row.operator("bim.edit_productivity_data", text="Apply", icon="CHECKMARK")
|
||||||
|
|
||||||
def draw_resource_operators(self):
|
def draw_resource_operators(self):
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
@@ -153,9 +173,6 @@ class BIM_PT_resources(Panel):
|
|||||||
|
|
||||||
if not self.props.active_resource_id:
|
if not self.props.active_resource_id:
|
||||||
if resource["type"] in ["IfcLaborResource", "IfcConstructionEquipmentResource"]:
|
if resource["type"] in ["IfcLaborResource", "IfcConstructionEquipmentResource"]:
|
||||||
if resource["Productivity"]:
|
|
||||||
op = row.operator("bim.calculate_resource_work", text="", icon="TEMP")
|
|
||||||
op.resource = ifc_definition_id
|
|
||||||
row.operator("bim.enable_editing_resource_time", text="", icon="TIME").resource = ifc_definition_id
|
row.operator("bim.enable_editing_resource_time", text="", icon="TIME").resource = ifc_definition_id
|
||||||
op = row.operator("bim.enable_editing_resource_base_quantity", text="", icon="PROPERTIES")
|
op = row.operator("bim.enable_editing_resource_base_quantity", text="", icon="PROPERTIES")
|
||||||
op.resource = ifc_definition_id
|
op.resource = ifc_definition_id
|
||||||
|
|||||||
@@ -23,14 +23,18 @@ import ifcopenshell.util.date
|
|||||||
def get_productivity(resource, should_inherit=True):
|
def get_productivity(resource, should_inherit=True):
|
||||||
productivity = ifcopenshell.util.element.get_psets(resource).get("EPset_Productivity", None)
|
productivity = ifcopenshell.util.element.get_psets(resource).get("EPset_Productivity", None)
|
||||||
if should_inherit and not productivity:
|
if should_inherit and not productivity:
|
||||||
# Proposal for Schema - If instance doesn't have any productivity, inherit it's parent's productivity
|
#Note: This is not part of the Schema - but it makes sense to inherit from parent
|
||||||
if not resource.Nests:
|
productivity = get_parent_productivity(resource)
|
||||||
return None
|
|
||||||
else:
|
|
||||||
parent_resource = resource.Nests[0].RelatingObject
|
|
||||||
productivity = ifcopenshell.util.element.get_psets(parent_resource).get("EPset_Productivity", None)
|
|
||||||
return productivity
|
return productivity
|
||||||
|
|
||||||
|
def get_parent_productivity(resource):
|
||||||
|
if not resource.Nests:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
parent_resource = resource.Nests[0].RelatingObject
|
||||||
|
productivity = ifcopenshell.util.element.get_psets(parent_resource).get("EPset_Productivity", None)
|
||||||
|
return productivity
|
||||||
|
|
||||||
|
|
||||||
def get_unit_consumed(productivity):
|
def get_unit_consumed(productivity):
|
||||||
duration = productivity.get("BaseQuantityConsumed", None)
|
duration = productivity.get("BaseQuantityConsumed", None)
|
||||||
|
|||||||
Reference in New Issue
Block a user