mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-11 06:18:09 +00:00
See #1848. Some straggling refactoring for resource data.
This commit is contained in:
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
from ifcopenshell.api.cost.data import CostValueTrait
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
|
||||||
|
|
||||||
@@ -26,7 +25,7 @@ def refresh():
|
|||||||
ResourceData.is_loaded = False
|
ResourceData.is_loaded = False
|
||||||
|
|
||||||
|
|
||||||
class ResourceData(CostValueTrait):
|
class ResourceData:
|
||||||
data = {}
|
data = {}
|
||||||
is_loaded = False
|
is_loaded = False
|
||||||
cost_values = {}
|
cost_values = {}
|
||||||
@@ -34,56 +33,49 @@ class ResourceData(CostValueTrait):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def load(cls):
|
def load(cls):
|
||||||
cls.data = {
|
cls.data = {
|
||||||
"has_resources": cls.has_resources(),
|
"total_resources": cls.total_resources(),
|
||||||
|
"resources": cls.resources(),
|
||||||
|
"active_resource_ids": cls.active_resource_ids(),
|
||||||
|
"cost_values": cls.cost_values(),
|
||||||
}
|
}
|
||||||
cls.load_resources()
|
|
||||||
cls.is_loaded = True
|
cls.is_loaded = True
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def has_resources(cls):
|
def total_resources(cls):
|
||||||
return bool(tool.Ifc.get().by_type("IfcResource"))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def number_of_resources_loaded(cls):
|
|
||||||
return len(tool.Ifc.get().by_type("IfcResource"))
|
return len(tool.Ifc.get().by_type("IfcResource"))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_resources(cls):
|
def resources(cls):
|
||||||
cls.data["resources"] = {}
|
results = {}
|
||||||
for resource in tool.Ifc.get().by_type("IfcResource"):
|
for resource in tool.Ifc.get().by_type("IfcResource"):
|
||||||
data = resource.get_info()
|
base_quantity = None
|
||||||
del data["OwnerHistory"]
|
|
||||||
data["IsNestedBy"] = []
|
|
||||||
for rel in resource.IsNestedBy:
|
|
||||||
[data["IsNestedBy"].append(o.id()) for o in rel.RelatedObjects]
|
|
||||||
data["Nests"] = []
|
|
||||||
for rel in resource.Nests:
|
|
||||||
[data["Nests"].append(rel.RelatingObject.id())]
|
|
||||||
data["ResourceOf"] = []
|
|
||||||
for rel in resource.ResourceOf:
|
|
||||||
[data["ResourceOf"].append(o.id()) for o in rel.RelatedObjects]
|
|
||||||
data["HasContext"] = resource.HasContext[0].RelatingContext.id() if resource.HasContext else None
|
|
||||||
if resource.Usage:
|
|
||||||
data["Usage"] = data["Usage"].id()
|
|
||||||
data["TotalCostQuantity"] = cls.get_total_quantity(resource)
|
|
||||||
if resource.BaseQuantity:
|
if resource.BaseQuantity:
|
||||||
data["BaseQuantity"] = resource.BaseQuantity.get_info()
|
base_quantity = resource.BaseQuantity.get_info()
|
||||||
del data["BaseQuantity"]["Unit"]
|
del base_quantity["Unit"]
|
||||||
if resource.BaseCosts:
|
results[resource.id()] = {"type": resource.is_a(), "BaseQuantity": base_quantity}
|
||||||
data["BaseCosts"] = [e.id() for e in resource.BaseCosts]
|
return results
|
||||||
cls.load_cost_values(resource, data)
|
|
||||||
cls.data["resources"][resource.id()] = data
|
|
||||||
cls.data["number_of_resources_loaded"] = cls.number_of_resources_loaded()
|
|
||||||
|
|
||||||
def load_resource_times(cls):
|
@classmethod
|
||||||
cls.data["resource_times"] = {}
|
def cost_values(cls):
|
||||||
for resource_time in tool.Ifc.get().by_type("IfcResourceTime"):
|
results = []
|
||||||
data = resource_time.get_info()
|
ifc_id = bpy.context.scene.BIMResourceProperties.active_resource_id
|
||||||
for key, value in data.items():
|
if not ifc_id:
|
||||||
if not value:
|
return results
|
||||||
continue
|
resource = tool.Ifc.get().by_id(ifc_id)
|
||||||
if "Start" in key or "Finish" in key or key == "StatusTime":
|
for cost_value in resource.BaseCosts or []:
|
||||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
label = "{0:.2f}".format(ifcopenshell.util.cost.calculate_applied_value(resource, cost_value))
|
||||||
elif "Work" in key or key == "LevelingDelay":
|
label += " = {}".format(ifcopenshell.util.cost.serialise_cost_value(cost_value))
|
||||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
results.append({"id": cost_value.id(), "label": label})
|
||||||
cls.data["resource_times"][resource_time.id()] = data
|
return results
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def active_resource_ids(cls):
|
||||||
|
obj = bpy.context.active_object
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if not element:
|
||||||
|
return []
|
||||||
|
results = []
|
||||||
|
for rel in getattr(element, "HasAssignments", []) or []:
|
||||||
|
if rel.is_a("IfcRelAssignsToResource"):
|
||||||
|
results.append(rel.RelatingResource.id())
|
||||||
|
return results
|
||||||
|
|||||||
@@ -43,18 +43,15 @@ class BIM_PT_resources(Panel):
|
|||||||
ResourceData.load()
|
ResourceData.load()
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
if ResourceData.data["has_resources"]:
|
if ResourceData.data["total_resources"]:
|
||||||
row.label(
|
row.label(text=f"{ResourceData.data['total_resources']} Resources Found", icon="TEXT")
|
||||||
text="{} Resources Found".format(ResourceData.data["number_of_resources_loaded"]),
|
|
||||||
icon="TEXT",
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
row.label(text="No Resources found.", icon="COMMUNITY")
|
row.label(text="No Resources found.", icon="COMMUNITY")
|
||||||
if self.props.is_editing:
|
if self.props.is_editing:
|
||||||
row.operator("bim.disable_resource_editing_ui", text="", icon="CANCEL")
|
row.operator("bim.disable_resource_editing_ui", text="", icon="CANCEL")
|
||||||
else:
|
else:
|
||||||
row.operator("bim.load_resources", text="Load Resources", icon="GREASEPENCIL")
|
row.operator("bim.load_resources", text="", icon="GREASEPENCIL")
|
||||||
row.operator("import_resources.bim", text="Import Resources", icon="IMPORT")
|
row.operator("import_resources.bim", text="", icon="IMPORT")
|
||||||
if not self.props.is_editing:
|
if not self.props.is_editing:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -170,25 +167,20 @@ class BIM_PT_resources(Panel):
|
|||||||
if self.props.cost_types == "CATEGORY":
|
if self.props.cost_types == "CATEGORY":
|
||||||
op.cost_category = self.props.cost_category
|
op.cost_category = self.props.cost_category
|
||||||
|
|
||||||
for cost_value_id in ResourceData.data["resources"][self.props.active_resource_id]["BaseCosts"] or []:
|
for cost_value in ResourceData.data["cost_values"]:
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
self.draw_readonly_cost_value_ui(row, cost_value_id)
|
self.draw_readonly_cost_value_ui(row, cost_value)
|
||||||
|
|
||||||
if self.props.cost_value_editing_type == "ATTRIBUTES":
|
if self.props.cost_value_editing_type == "ATTRIBUTES":
|
||||||
box = self.layout.box()
|
blenderbim.bim.helper.draw_attributes(self.props.cost_value_attributes, self.layout.box())
|
||||||
self.draw_editable_cost_value_ui(box, ResourceData.cost_values[self.props.active_cost_value_id])
|
|
||||||
|
|
||||||
def draw_readonly_cost_value_ui(self, layout, cost_value_id):
|
def draw_readonly_cost_value_ui(self, layout, cost_value):
|
||||||
cost_value = ResourceData.cost_values[cost_value_id]
|
if self.props.active_cost_value_id == cost_value["id"] and self.props.cost_value_editing_type == "FORMULA":
|
||||||
|
|
||||||
if self.props.active_cost_value_id == cost_value_id and self.props.cost_value_editing_type == "FORMULA":
|
|
||||||
layout.prop(self.props, "cost_value_formula", text="")
|
layout.prop(self.props, "cost_value_formula", text="")
|
||||||
else:
|
else:
|
||||||
cost_value_label = "{0:.2f}".format(cost_value["AppliedValue"])
|
layout.label(text=cost_value["label"], icon="DISC")
|
||||||
cost_value_label += " = " + cost_value["Formula"]
|
|
||||||
layout.label(text=cost_value_label, icon="DISC")
|
|
||||||
|
|
||||||
self.draw_cost_value_operator_ui(layout, cost_value_id, self.props.active_resource_id)
|
self.draw_cost_value_operator_ui(layout, cost_value["id"], self.props.active_resource_id)
|
||||||
|
|
||||||
def draw_cost_value_operator_ui(self, layout, cost_value_id, parent_id):
|
def draw_cost_value_operator_ui(self, layout, cost_value_id, parent_id):
|
||||||
if self.props.active_cost_value_id and self.props.active_cost_value_id == cost_value_id:
|
if self.props.active_cost_value_id and self.props.active_cost_value_id == cost_value_id:
|
||||||
@@ -212,9 +204,6 @@ class BIM_PT_resources(Panel):
|
|||||||
op.parent = parent_id
|
op.parent = parent_id
|
||||||
op.cost_value = cost_value_id
|
op.cost_value = cost_value_id
|
||||||
|
|
||||||
def draw_editable_cost_value_ui(self, layout, cost_value):
|
|
||||||
blenderbim.bim.helper.draw_attributes(self.props.cost_value_attributes, layout)
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_UL_resources(UIList):
|
class BIM_UL_resources(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
@@ -246,9 +235,8 @@ class BIM_UL_resources(UIList):
|
|||||||
row.prop(item, "name", emboss=False, text="", icon=icon_map[resource["type"]])
|
row.prop(item, "name", emboss=False, text="", icon=icon_map[resource["type"]])
|
||||||
row.prop(item, "schedule_usage", text="", emboss=False)
|
row.prop(item, "schedule_usage", text="", emboss=False)
|
||||||
if context.active_object and not props.active_resource_id:
|
if context.active_object and not props.active_resource_id:
|
||||||
oprops = context.active_object.BIMObjectProperties
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
if oprops.ifc_definition_id in ResourceData.data["resources"][item.ifc_definition_id]["ResourceOf"]:
|
if item.ifc_definition_id in ResourceData.data["active_resource_ids"]:
|
||||||
op = row.operator("bim.unassign_resource", text="", icon="KEYFRAME_HLT", emboss=False)
|
op = row.operator("bim.unassign_resource", text="", icon="KEYFRAME_HLT", emboss=False)
|
||||||
op.resource = item.ifc_definition_id
|
op.resource = item.ifc_definition_id
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ from datetime import datetime
|
|||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
import ifcopenshell.util.date as ifcdateutils
|
import ifcopenshell.util.date as ifcdateutils
|
||||||
import ifcopenshell.util.cost
|
import ifcopenshell.util.cost
|
||||||
from ifcopenshell.api.unit.data import Data as UnitData
|
|
||||||
|
|
||||||
|
|
||||||
class Resource(blenderbim.core.tool.Resource):
|
class Resource(blenderbim.core.tool.Resource):
|
||||||
@@ -190,10 +189,8 @@ class Resource(blenderbim.core.tool.Resource):
|
|||||||
prop.data_type = "enum"
|
prop.data_type = "enum"
|
||||||
prop.is_null = prop.is_optional = False
|
prop.is_null = prop.is_optional = False
|
||||||
units = {}
|
units = {}
|
||||||
if not UnitData.is_loaded:
|
for unit in tool.Ifc.get().by_type("IfcNamedUnit"):
|
||||||
UnitData.load(tool.Ifc.get())
|
if getattr(unit, "UnitType", None) in [
|
||||||
for unit_id, unit in UnitData.units.items():
|
|
||||||
if unit.get("UnitType", None) in [
|
|
||||||
"AREAUNIT",
|
"AREAUNIT",
|
||||||
"LENGTHUNIT",
|
"LENGTHUNIT",
|
||||||
"TIMEUNIT",
|
"TIMEUNIT",
|
||||||
@@ -201,13 +198,13 @@ class Resource(blenderbim.core.tool.Resource):
|
|||||||
"MASSUNIT",
|
"MASSUNIT",
|
||||||
"USERDEFINED",
|
"USERDEFINED",
|
||||||
]:
|
]:
|
||||||
if unit["type"] == "IfcContextDependentUnit":
|
if unit.is_a("IfcContextDependentUnit"):
|
||||||
units[unit_id] = f"{unit['UnitType']} / {unit['Name']}"
|
units[unit.id()] = f"{unit.is_a()} / {unit.Name}"
|
||||||
else:
|
else:
|
||||||
name = unit["Name"]
|
name = unit.Name
|
||||||
if unit.get("Prefix", None):
|
if getattr(unit, "Prefix", None):
|
||||||
name = f"(unit['Prefix']) {name}"
|
name = f"(unit.Prefix) {name}"
|
||||||
units[unit_id] = f"{unit['UnitType']} / {name}"
|
units[unit.id()] = f"{unit.UnitType} / {name}"
|
||||||
prop.enum_items = json.dumps(units)
|
prop.enum_items = json.dumps(units)
|
||||||
if data["UnitBasis"] and data["UnitBasis"].UnitComponent:
|
if data["UnitBasis"] and data["UnitBasis"].UnitComponent:
|
||||||
name = data["UnitBasis"].UnitComponent.Name
|
name = data["UnitBasis"].UnitComponent.Name
|
||||||
|
|||||||
Reference in New Issue
Block a user