mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
You can now assign / unassign cost items in a schedule of rates to type products
This commit is contained in:
@@ -26,6 +26,8 @@ classes = (
|
||||
operator.ExpandCostItem,
|
||||
operator.ContractCostItem,
|
||||
operator.RemoveCostItem,
|
||||
operator.AssignCostItemType,
|
||||
operator.UnassignCostItemType,
|
||||
operator.AssignCostItemQuantity,
|
||||
operator.UnassignCostItemQuantity,
|
||||
operator.AddCostItemQuantity,
|
||||
@@ -37,14 +39,18 @@ classes = (
|
||||
operator.SelectCostScheduleProducts,
|
||||
operator.ImportCostScheduleCsv,
|
||||
operator.LoadCostItemQuantities,
|
||||
operator.LoadCostItemTypes,
|
||||
prop.CostItem,
|
||||
prop.CostItemQuantity,
|
||||
prop.CostItemType,
|
||||
prop.BIMCostProperties,
|
||||
ui.BIM_PT_cost_schedules,
|
||||
ui.BIM_PT_cost_item_quantities,
|
||||
ui.BIM_PT_cost_item_types,
|
||||
ui.BIM_UL_cost_items,
|
||||
ui.BIM_UL_cost_columns,
|
||||
ui.BIM_UL_cost_item_quantities,
|
||||
ui.BIM_UL_cost_item_types,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -303,6 +303,63 @@ class EditCostItem(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AssignCostItemType(bpy.types.Operator):
|
||||
bl_idname = "bim.assign_cost_item_type"
|
||||
bl_label = "Assign Cost Item Type Product"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
cost_item: bpy.props.IntProperty()
|
||||
prop_name: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
cost_item = self.file.by_id(self.cost_item)
|
||||
for obj in context.selected_objects:
|
||||
if not obj.BIMObjectProperties.ifc_definition_id:
|
||||
continue
|
||||
product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
if product.is_a("IfcTypeProduct"):
|
||||
ifcopenshell.api.run(
|
||||
"control.assign_control", self.file, relating_control=cost_item, related_object=product
|
||||
)
|
||||
Data.load(self.file)
|
||||
bpy.ops.bim.load_cost_item_types()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class UnassignCostItemType(bpy.types.Operator):
|
||||
bl_idname = "bim.unassign_cost_item_type"
|
||||
bl_label = "Unassign Cost Item Type"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
cost_item: bpy.props.IntProperty()
|
||||
related_object: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
cost_item = self.file.by_id(self.cost_item)
|
||||
if self.related_object:
|
||||
products = [self.file.by_id(self.related_object)]
|
||||
else:
|
||||
for obj in context.selected_objects:
|
||||
if not obj.BIMObjectProperties.ifc_definition_id:
|
||||
continue
|
||||
product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
if product.is_a("IfcTypeProduct"):
|
||||
products.append(product)
|
||||
for product in products:
|
||||
ifcopenshell.api.run(
|
||||
"control.unassign_control", self.file, relating_control=cost_item, related_object=product
|
||||
)
|
||||
Data.load(self.file)
|
||||
bpy.ops.bim.load_cost_item_types()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AssignCostItemQuantity(bpy.types.Operator):
|
||||
bl_idname = "bim.assign_cost_item_quantity"
|
||||
bl_label = "Assign Cost Item Quantity"
|
||||
@@ -806,3 +863,33 @@ class LoadCostItemQuantities(bpy.types.Operator):
|
||||
total_quantity += self.file.by_id(quantity_id)[3]
|
||||
new.total_quantity = total_quantity
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class LoadCostItemTypes(bpy.types.Operator):
|
||||
bl_idname = "bim.load_cost_item_types"
|
||||
bl_label = "Load Cost Item Types"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
self.props = context.scene.BIMCostProperties
|
||||
self.file = IfcStore.get_file()
|
||||
while len(self.props.cost_item_type_products) > 0:
|
||||
self.props.cost_item_type_products.remove(0)
|
||||
# TODO implement process and resource types
|
||||
#while len(self.props.cost_item_processes) > 0:
|
||||
# self.props.cost_item_processes.remove(0)
|
||||
#while len(self.props.cost_item_resources) > 0:
|
||||
# self.props.cost_item_resources.remove(0)
|
||||
ifc_definition_id = self.props.cost_items[self.props.active_cost_item_index].ifc_definition_id
|
||||
for control_id, quantity_ids in Data.cost_items[ifc_definition_id]["Controls"].items():
|
||||
related_object = self.file.by_id(control_id)
|
||||
if related_object.is_a("IfcTypeProduct"):
|
||||
new = self.props.cost_item_type_products.add()
|
||||
# TODO implement process and resource types
|
||||
#elif related_object.is_a("IfcProcess"):
|
||||
# new = self.props.cost_item_processes.add()
|
||||
#elif related_object.is_a("IfcResource"):
|
||||
# new = self.props.cost_item_resources.add()
|
||||
new.ifc_definition_id = control_id
|
||||
new.name = related_object.Name or "Unnamed"
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -175,6 +175,11 @@ class CostItemQuantity(PropertyGroup):
|
||||
total_quantity: FloatProperty(name="Total Quantity")
|
||||
|
||||
|
||||
class CostItemType(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
|
||||
|
||||
class BIMCostProperties(PropertyGroup):
|
||||
is_cost_update_enabled: BoolProperty(name="Is Cost Update Enabled", default=True)
|
||||
cost_schedule_attributes: CollectionProperty(name="Cost Schedule Attributes", type=Attribute)
|
||||
@@ -213,3 +218,5 @@ class BIMCostProperties(PropertyGroup):
|
||||
active_cost_item_process_index: IntProperty(name="Active Cost Item Process Index")
|
||||
cost_item_resources: CollectionProperty(name="Cost Item Resources", type=CostItemQuantity)
|
||||
active_cost_item_resource_index: IntProperty(name="Active Cost Item Resource Index")
|
||||
cost_item_type_products: CollectionProperty(name="Cost Item Type Products", type=CostItemType)
|
||||
active_cost_item_type_product_index: IntProperty(name="Active Cost Item TYpe Product Index")
|
||||
|
||||
@@ -225,6 +225,93 @@ class BIM_PT_cost_schedules(Panel):
|
||||
def draw_editable_cost_value_ui(self, layout, cost_value):
|
||||
draw_attributes(self.props.cost_value_attributes, layout)
|
||||
|
||||
|
||||
class BIM_PT_cost_item_types(Panel):
|
||||
bl_label = "IFC Cost Item Types"
|
||||
bl_idname = "BIM_PT_cost_item_types"
|
||||
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 not props.active_cost_schedule_id:
|
||||
return False
|
||||
if Data.cost_schedules[props.active_cost_schedule_id]["PredefinedType"] != "SCHEDULEOFRATES":
|
||||
return False
|
||||
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]
|
||||
|
||||
grid = self.layout.grid_flow(columns=3, even_columns=True)
|
||||
|
||||
# Column1
|
||||
col = grid.column()
|
||||
|
||||
row2 = col.row(align=True)
|
||||
row2.label(text="Elements")
|
||||
op = row2.operator("bim.assign_cost_item_type", text="", icon="ADD")
|
||||
op.cost_item = cost_item.ifc_definition_id
|
||||
op = row2.operator("bim.unassign_cost_item_type", text="", icon="REMOVE")
|
||||
op.cost_item = cost_item.ifc_definition_id
|
||||
op.related_object = 0
|
||||
op = row2.operator("bim.select_cost_item_products", icon="RESTRICT_SELECT_OFF", text="")
|
||||
op.cost_item = cost_item.ifc_definition_id
|
||||
|
||||
row2 = col.row()
|
||||
row2.template_list(
|
||||
"BIM_UL_cost_item_types",
|
||||
"",
|
||||
self.props,
|
||||
"cost_item_type_products",
|
||||
self.props,
|
||||
"active_cost_item_type_product_index",
|
||||
)
|
||||
|
||||
# Column2
|
||||
# TODO
|
||||
col = grid.column()
|
||||
|
||||
row2 = col.row(align=True)
|
||||
row2.label(text="Tasks")
|
||||
|
||||
row2 = col.row()
|
||||
row2.template_list(
|
||||
"BIM_UL_cost_item_quantities",
|
||||
"",
|
||||
self.props,
|
||||
"cost_item_processes",
|
||||
self.props,
|
||||
"active_cost_item_process_index",
|
||||
)
|
||||
|
||||
# Column3
|
||||
# TODO
|
||||
col = grid.column()
|
||||
|
||||
row2 = col.row(align=True)
|
||||
row2.label(text="Resources")
|
||||
|
||||
row2 = col.row()
|
||||
row2.template_list(
|
||||
"BIM_UL_cost_item_quantities",
|
||||
"",
|
||||
self.props,
|
||||
"cost_item_resources",
|
||||
self.props,
|
||||
"active_cost_item_resource_index",
|
||||
)
|
||||
|
||||
|
||||
class BIM_PT_cost_item_quantities(Panel):
|
||||
bl_label = "IFC Cost Item Quantities"
|
||||
bl_idname = "BIM_PT_cost_item_quantities"
|
||||
@@ -238,6 +325,10 @@ class BIM_PT_cost_item_quantities(Panel):
|
||||
def poll(cls, context):
|
||||
props = context.scene.BIMCostProperties
|
||||
total_cost_items = len(props.cost_items)
|
||||
if not props.active_cost_schedule_id:
|
||||
return False
|
||||
if Data.cost_schedules[props.active_cost_schedule_id]["PredefinedType"] == "SCHEDULEOFRATES":
|
||||
return False
|
||||
if total_cost_items > 0 and props.active_cost_item_index < total_cost_items:
|
||||
return True
|
||||
return False
|
||||
@@ -355,7 +446,9 @@ class BIM_UL_cost_items(UIList):
|
||||
split2.prop(item, "name", emboss=False, text="")
|
||||
|
||||
if Data.cost_schedules[self.props.active_cost_schedule_id]["PredefinedType"] != "SCHEDULEOFRATES":
|
||||
split2.label(text="{0:.2f}".format(cost_item["TotalCostQuantity"]) + f" ({cost_item['UnitSymbol'] or '?'})")
|
||||
split2.label(
|
||||
text="{0:.2f}".format(cost_item["TotalCostQuantity"]) + f" ({cost_item['UnitSymbol'] or '?'})"
|
||||
)
|
||||
|
||||
split2.label(text="{0:.2f}".format(cost_item["TotalAppliedValue"]))
|
||||
|
||||
@@ -383,6 +476,19 @@ class BIM_UL_cost_columns(UIList):
|
||||
row.operator("bim.remove_cost_column", text="", icon="X").name = item.name
|
||||
|
||||
|
||||
class BIM_UL_cost_item_types(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.label(text=item.name)
|
||||
op = row.operator("bim.unassign_cost_item_type", text="", icon="X")
|
||||
op.cost_item = cost_item.ifc_definition_id
|
||||
op.related_object = item.ifc_definition_id
|
||||
|
||||
|
||||
class BIM_UL_cost_item_quantities(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
props = context.scene.BIMCostProperties
|
||||
|
||||
Reference in New Issue
Block a user