mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
See #1848. Some straggling refactoring for resource data.
This commit is contained in:
@@ -18,7 +18,6 @@
|
||||
|
||||
import bpy
|
||||
import blenderbim.tool as tool
|
||||
from ifcopenshell.api.cost.data import CostValueTrait
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
@@ -26,7 +25,7 @@ def refresh():
|
||||
ResourceData.is_loaded = False
|
||||
|
||||
|
||||
class ResourceData(CostValueTrait):
|
||||
class ResourceData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
cost_values = {}
|
||||
@@ -34,56 +33,49 @@ class ResourceData(CostValueTrait):
|
||||
@classmethod
|
||||
def load(cls):
|
||||
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
|
||||
|
||||
@classmethod
|
||||
def has_resources(cls):
|
||||
return bool(tool.Ifc.get().by_type("IfcResource"))
|
||||
|
||||
@classmethod
|
||||
def number_of_resources_loaded(cls):
|
||||
def total_resources(cls):
|
||||
return len(tool.Ifc.get().by_type("IfcResource"))
|
||||
|
||||
@classmethod
|
||||
def load_resources(cls):
|
||||
cls.data["resources"] = {}
|
||||
def resources(cls):
|
||||
results = {}
|
||||
for resource in tool.Ifc.get().by_type("IfcResource"):
|
||||
data = resource.get_info()
|
||||
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)
|
||||
base_quantity = None
|
||||
if resource.BaseQuantity:
|
||||
data["BaseQuantity"] = resource.BaseQuantity.get_info()
|
||||
del data["BaseQuantity"]["Unit"]
|
||||
if resource.BaseCosts:
|
||||
data["BaseCosts"] = [e.id() for e in resource.BaseCosts]
|
||||
cls.load_cost_values(resource, data)
|
||||
cls.data["resources"][resource.id()] = data
|
||||
cls.data["number_of_resources_loaded"] = cls.number_of_resources_loaded()
|
||||
base_quantity = resource.BaseQuantity.get_info()
|
||||
del base_quantity["Unit"]
|
||||
results[resource.id()] = {"type": resource.is_a(), "BaseQuantity": base_quantity}
|
||||
return results
|
||||
|
||||
def load_resource_times(cls):
|
||||
cls.data["resource_times"] = {}
|
||||
for resource_time in tool.Ifc.get().by_type("IfcResourceTime"):
|
||||
data = resource_time.get_info()
|
||||
for key, value in data.items():
|
||||
if not value:
|
||||
continue
|
||||
if "Start" in key or "Finish" in key or key == "StatusTime":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
elif "Work" in key or key == "LevelingDelay":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
cls.data["resource_times"][resource_time.id()] = data
|
||||
@classmethod
|
||||
def cost_values(cls):
|
||||
results = []
|
||||
ifc_id = bpy.context.scene.BIMResourceProperties.active_resource_id
|
||||
if not ifc_id:
|
||||
return results
|
||||
resource = tool.Ifc.get().by_id(ifc_id)
|
||||
for cost_value in resource.BaseCosts or []:
|
||||
label = "{0:.2f}".format(ifcopenshell.util.cost.calculate_applied_value(resource, cost_value))
|
||||
label += " = {}".format(ifcopenshell.util.cost.serialise_cost_value(cost_value))
|
||||
results.append({"id": cost_value.id(), "label": label})
|
||||
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()
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
if ResourceData.data["has_resources"]:
|
||||
row.label(
|
||||
text="{} Resources Found".format(ResourceData.data["number_of_resources_loaded"]),
|
||||
icon="TEXT",
|
||||
)
|
||||
if ResourceData.data["total_resources"]:
|
||||
row.label(text=f"{ResourceData.data['total_resources']} Resources Found", icon="TEXT")
|
||||
else:
|
||||
row.label(text="No Resources found.", icon="COMMUNITY")
|
||||
if self.props.is_editing:
|
||||
row.operator("bim.disable_resource_editing_ui", text="", icon="CANCEL")
|
||||
else:
|
||||
row.operator("bim.load_resources", text="Load Resources", icon="GREASEPENCIL")
|
||||
row.operator("import_resources.bim", text="Import Resources", icon="IMPORT")
|
||||
row.operator("bim.load_resources", text="", icon="GREASEPENCIL")
|
||||
row.operator("import_resources.bim", text="", icon="IMPORT")
|
||||
if not self.props.is_editing:
|
||||
return
|
||||
|
||||
@@ -170,25 +167,20 @@ class BIM_PT_resources(Panel):
|
||||
if self.props.cost_types == "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)
|
||||
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":
|
||||
box = self.layout.box()
|
||||
self.draw_editable_cost_value_ui(box, ResourceData.cost_values[self.props.active_cost_value_id])
|
||||
blenderbim.bim.helper.draw_attributes(self.props.cost_value_attributes, self.layout.box())
|
||||
|
||||
def draw_readonly_cost_value_ui(self, layout, cost_value_id):
|
||||
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":
|
||||
def draw_readonly_cost_value_ui(self, layout, cost_value):
|
||||
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="")
|
||||
else:
|
||||
cost_value_label = "{0:.2f}".format(cost_value["AppliedValue"])
|
||||
cost_value_label += " = " + cost_value["Formula"]
|
||||
layout.label(text=cost_value_label, icon="DISC")
|
||||
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):
|
||||
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.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):
|
||||
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, "schedule_usage", text="", emboss=False)
|
||||
if context.active_object and not props.active_resource_id:
|
||||
oprops = context.active_object.BIMObjectProperties
|
||||
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.resource = item.ifc_definition_id
|
||||
else:
|
||||
|
||||
@@ -30,7 +30,6 @@ from datetime import datetime
|
||||
from dateutil import parser
|
||||
import ifcopenshell.util.date as ifcdateutils
|
||||
import ifcopenshell.util.cost
|
||||
from ifcopenshell.api.unit.data import Data as UnitData
|
||||
|
||||
|
||||
class Resource(blenderbim.core.tool.Resource):
|
||||
@@ -190,10 +189,8 @@ class Resource(blenderbim.core.tool.Resource):
|
||||
prop.data_type = "enum"
|
||||
prop.is_null = prop.is_optional = False
|
||||
units = {}
|
||||
if not UnitData.is_loaded:
|
||||
UnitData.load(tool.Ifc.get())
|
||||
for unit_id, unit in UnitData.units.items():
|
||||
if unit.get("UnitType", None) in [
|
||||
for unit in tool.Ifc.get().by_type("IfcNamedUnit"):
|
||||
if getattr(unit, "UnitType", None) in [
|
||||
"AREAUNIT",
|
||||
"LENGTHUNIT",
|
||||
"TIMEUNIT",
|
||||
@@ -201,13 +198,13 @@ class Resource(blenderbim.core.tool.Resource):
|
||||
"MASSUNIT",
|
||||
"USERDEFINED",
|
||||
]:
|
||||
if unit["type"] == "IfcContextDependentUnit":
|
||||
units[unit_id] = f"{unit['UnitType']} / {unit['Name']}"
|
||||
if unit.is_a("IfcContextDependentUnit"):
|
||||
units[unit.id()] = f"{unit.is_a()} / {unit.Name}"
|
||||
else:
|
||||
name = unit["Name"]
|
||||
if unit.get("Prefix", None):
|
||||
name = f"(unit['Prefix']) {name}"
|
||||
units[unit_id] = f"{unit['UnitType']} / {name}"
|
||||
name = unit.Name
|
||||
if getattr(unit, "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:
|
||||
name = data["UnitBasis"].UnitComponent.Name
|
||||
|
||||
Reference in New Issue
Block a user