mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 18:43:26 +00:00
New interface to view physical products assigned to a cost item
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user