New interface to view physical products assigned to a cost item

This commit is contained in:
Dion Moult
2021-08-11 20:56:07 +10:00
parent 62b8f10677
commit 858f48c49d
5 changed files with 154 additions and 22 deletions
@@ -36,11 +36,15 @@ classes = (
operator.SelectCostItemProducts,
operator.SelectCostScheduleProducts,
operator.ImportCostScheduleCsv,
operator.LoadCostItemProducts,
prop.CostItem,
prop.CostItemProduct,
prop.BIMCostProperties,
ui.BIM_PT_cost_schedules,
ui.BIM_PT_cost_item_quantities,
ui.BIM_UL_cost_items,
ui.BIM_UL_cost_columns,
ui.BIM_UL_cost_item_products,
)
@@ -702,3 +702,27 @@ class RemoveCostColumn(bpy.types.Operator):
Data.set_categories([c.name for c in self.props.columns])
Data.load(IfcStore.get_file())
return {"FINISHED"}
class LoadCostItemProducts(bpy.types.Operator):
bl_idname = "bim.load_cost_item_products"
bl_label = "Load Cost Item Products"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
self.props = context.scene.BIMCostProperties
self.file = IfcStore.get_file()
while len(self.props.cost_item_products) > 0:
self.props.cost_item_products.remove(0)
ifc_definition_id = self.props.cost_items[self.props.active_cost_item_index].ifc_definition_id
for control in Data.cost_items[ifc_definition_id]["Controls"]:
related_object = self.file.by_id(control)
if related_object.is_a("IfcProduct"):
new = self.props.cost_item_products.add()
new.ifc_definition_id = control
new.name = related_object.Name or "Unnamed"
elif related_object.is_a("IfcProduct"):
pass
elif related_object.is_a("IfcResource"):
pass
return {"FINISHED"}
@@ -19,13 +19,16 @@ from bpy.props import (
quantitytypes_enum = []
quantitynames_enum = []
quantitynames_count = []
def purge():
global quantitytypes_enum
global quantitynames_enum
global quantitynames_count
quantitytypes_enum = []
quantitynames_enum = []
quantitynames_count = []
def getQuantityTypes(self, context):
@@ -43,19 +46,32 @@ def getQuantityTypes(self, context):
def getQuantityNames(self, context):
global quantitynames_enum
global quantitynames_count
ifc_file = IfcStore.get_file()
if len(quantitynames_enum) == 0 and ifc_file:
total_selected_objects = len(context.selected_objects)
if total_selected_objects != quantitynames_count or total_selected_objects == 1:
quantitynames_enum = []
quantitynames_count = total_selected_objects
names = set()
for element_id in Data.cost_items[self.active_cost_item_id]["Controls"]:
for obj in context.selected_objects:
element_id = obj.BIMObjectProperties.ifc_definition_id
if not element_id:
continue
potential_names = set()
if element_id not in PsetData.products:
PsetData.load(IfcStore.get_file(), element_id)
PsetData.load(ifc_file, element_id)
for qto_id in PsetData.products[element_id]["qtos"]:
qto = PsetData.qtos[qto_id]
[names.add(PsetData.properties[p]["Name"]) for p in qto["Properties"]]
[potential_names.add(PsetData.properties[p]["Name"]) for p in qto["Properties"]]
names = names.intersection(potential_names) if names else potential_names
quantitynames_enum.extend([(n, n, "") for n in names])
return quantitynames_enum
def update_cost_item_index(self, context):
bpy.ops.bim.load_cost_item_products()
def updateCostItemName(self, context):
if self.name == "Unnamed":
return
@@ -80,6 +96,11 @@ class CostItem(PropertyGroup):
level_index: IntProperty(name="Level Index")
class CostItemProduct(PropertyGroup):
name: StringProperty(name="Name")
ifc_definition_id: IntProperty(name="IFC Definition ID")
class BIMCostProperties(PropertyGroup):
cost_schedule_attributes: CollectionProperty(name="Cost Schedule Attributes", type=Attribute)
is_editing: StringProperty(name="Is Editing")
@@ -87,7 +108,7 @@ class BIMCostProperties(PropertyGroup):
cost_items: CollectionProperty(name="Cost Items", type=CostItem)
active_cost_item_id: IntProperty(name="Active Cost Id")
cost_item_editing_type: StringProperty(name="Cost Item Editing Type")
active_cost_item_index: IntProperty(name="Active Cost Item Index")
active_cost_item_index: IntProperty(name="Active Cost Item Index", update=update_cost_item_index)
cost_item_attributes: CollectionProperty(name="Task Attributes", type=Attribute)
contracted_cost_items: StringProperty(name="Contracted Cost Items", default="[]")
quantity_types: EnumProperty(items=getQuantityTypes, name="Quantity Types")
@@ -109,3 +130,5 @@ class BIMCostProperties(PropertyGroup):
should_show_column_ui: BoolProperty(name="Should Show Column UI", default=False)
columns: CollectionProperty(name="Columns", type=StrProperty)
active_column_index: IntProperty(name="Active Column Index")
cost_item_products: CollectionProperty(name="Cost Item Products", type=CostItemProduct)
active_cost_item_product_index: IntProperty(name="Active Cost Item Product Index")
+93 -12
View File
@@ -244,6 +244,87 @@ class BIM_PT_cost_schedules(Panel):
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
class BIM_PT_cost_item_quantities(Panel):
bl_label = "IFC Cost Item Quantities"
bl_idname = "BIM_PT_cost_item_quantities"
bl_options = {"DEFAULT_CLOSED"}
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_parent_id = "BIM_PT_cost_schedules"
@classmethod
def poll(cls, context):
props = context.scene.BIMCostProperties
total_cost_items = len(props.cost_items)
if total_cost_items > 0 and props.active_cost_item_index < total_cost_items:
return True
return False
def draw(self, context):
self.props = context.scene.BIMCostProperties
cost_item = self.props.cost_items[self.props.active_cost_item_index]
row = self.layout.row(align=True)
row2 = row.row(align=True)
row2.label(text="Elements")
op = row.operator("bim.select_cost_item_products", icon="RESTRICT_SELECT_OFF", text="")
op.cost_item = cost_item.ifc_definition_id
row2 = row.row(align=True)
row2.label(text="Tasks")
op = row.operator("bim.select_cost_item_products", icon="RESTRICT_SELECT_OFF", text="")
op.cost_item = cost_item.ifc_definition_id
row2 = row.row(align=True)
row2.label(text="Resources")
op = row.operator("bim.select_cost_item_products", icon="RESTRICT_SELECT_OFF", text="")
op.cost_item = cost_item.ifc_definition_id
row = self.layout.row(align=True)
row.template_list(
"BIM_UL_cost_item_products",
"",
self.props,
"cost_item_products",
self.props,
"active_cost_item_product_index",
)
row.template_list(
"BIM_UL_cost_item_products",
"",
self.props,
"cost_item_products",
self.props,
"active_cost_item_product_index",
)
row.template_list(
"BIM_UL_cost_item_products",
"",
self.props,
"cost_item_products",
self.props,
"active_cost_item_product_index",
)
row = self.layout.row(align=True)
row2 = row.row(align=True)
row2.prop(self.props, "quantity_names", text="")
op = row.operator("bim.assign_cost_item_product", text="", icon="ADD")
op.cost_item = cost_item.ifc_definition_id
row2 = row.row(align=True)
row2.prop(self.props, "quantity_names", text="")
row2.operator("bim.unassign_cost_item_product", text="", icon="ADD")
row2 = row.row(align=True)
row2.prop(self.props, "quantity_names", text="")
row2.operator("bim.unassign_cost_item_product", text="", icon="ADD")
class BIM_UL_cost_items(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item:
@@ -281,16 +362,6 @@ class BIM_UL_cost_items(UIList):
row.label(text="{0:.2f}".format(cost_item["TotalCostValue"]), icon="CON_TRANSLIKE")
if context.active_object:
oprops = context.active_object.BIMObjectProperties
row = layout.row(align=True)
if oprops.ifc_definition_id in cost_item["Controls"]:
op = row.operator("bim.unassign_cost_item_product", text="", icon="KEYFRAME_HLT", emboss=False)
op.cost_item = item.ifc_definition_id
else:
op = row.operator("bim.assign_cost_item_product", text="", icon="KEYFRAME", emboss=False)
op.cost_item = item.ifc_definition_id
if props.active_cost_item_id == item.ifc_definition_id:
if props.cost_item_editing_type == "ATTRIBUTES":
row.operator("bim.edit_cost_item", text="", icon="CHECKMARK")
@@ -303,8 +374,6 @@ class BIM_UL_cost_items(UIList):
row.operator("bim.add_cost_item", text="", icon="ADD").cost_item = item.ifc_definition_id
row.operator("bim.remove_cost_item", text="", icon="X").cost_item = item.ifc_definition_id
else:
op = row.operator("bim.select_cost_item_products", icon="RESTRICT_SELECT_OFF", text="")
op.cost_item = item.ifc_definition_id
row.operator(
"bim.enable_editing_cost_item", text="", icon="GREASEPENCIL"
).cost_item = item.ifc_definition_id
@@ -319,3 +388,15 @@ class BIM_UL_cost_columns(UIList):
row = layout.row(align=True)
row.prop(item, "name", emboss=False, text="")
row.operator("bim.remove_cost_column", text="", icon="X").name = item.name
class BIM_UL_cost_item_products(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
props = context.scene.BIMCostProperties
cost_item = props.cost_items[props.active_cost_item_index]
if item:
row = layout.row(align=True)
row.prop(item, "name", emboss=False, text="")
op = row.operator("bim.unassign_cost_item_product", text="", icon="X")
op.cost_item = cost_item.ifc_definition_id
@@ -132,7 +132,7 @@ class BIM_PT_object_psets(Panel):
op.obj_type = "Object"
psets = [(pset_id, Data.psets[pset_id]) for pset_id in Data.products[oprops.ifc_definition_id]["psets"]]
for pset_id, pset in sorted(psets, key = lambda v: v[1]["Name"]):
for pset_id, pset in sorted(psets, key=lambda v: v[1]["Name"]):
draw_psetqto_ui(context, pset_id, pset, props, self.layout, "Object")
# TODO reimplement. See #1222.
@@ -177,7 +177,7 @@ class BIM_PT_object_qtos(Panel):
op.obj_type = "Object"
qtos = [(qto_id, Data.qtos[qto_id]) for qto_id in Data.products[oprops.ifc_definition_id]["qtos"]]
for qto_id, qto in sorted(qtos, key = lambda v: v[1]["Name"]):
for qto_id, qto in sorted(qtos, key=lambda v: v[1]["Name"]):
draw_psetqto_ui(context, qto_id, qto, props, self.layout, "Object")
@@ -219,7 +219,7 @@ class BIM_PT_material_psets(Panel):
op.obj_type = "Material"
psets = [(pset_id, Data.psets[pset_id]) for pset_id in Data.products[oprops.ifc_definition_id]["psets"]]
for pset_id, pset in sorted(psets, key = lambda v: v[1]["Name"]):
for pset_id, pset in sorted(psets, key=lambda v: v[1]["Name"]):
draw_psetqto_ui(context, pset_id, pset, props, self.layout, "Material")
@@ -252,7 +252,7 @@ class BIM_PT_task_qtos(Panel):
op.obj_type = "Task"
qtos = [(qto_id, Data.qtos[qto_id]) for qto_id in Data.products[ifc_definition_id]["qtos"]]
for qto_id, qto in sorted(qtos, key = lambda v: v[1]["Name"]):
for qto_id, qto in sorted(qtos, key=lambda v: v[1]["Name"]):
draw_psetqto_ui(context, qto_id, qto, props, self.layout, "Task")
@@ -285,5 +285,5 @@ class BIM_PT_resource_qtos(Panel):
op.obj_type = "Resource"
qtos = [(qto_id, Data.qtos[qto_id]) for qto_id in Data.products[ifc_definition_id]["qtos"]]
for qto_id, qto in sorted(qtos, key = lambda v: v[1]["Name"]):
for qto_id, qto in sorted(qtos, key=lambda v: v[1]["Name"]):
draw_psetqto_ui(context, qto_id, qto, props, self.layout, "Resource")