mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
complete costing module refactoring
This commit is contained in:
@@ -30,6 +30,7 @@ classes = (
|
|||||||
operator.EnableEditingCostSchedule,
|
operator.EnableEditingCostSchedule,
|
||||||
operator.EnableEditingCostItems,
|
operator.EnableEditingCostItems,
|
||||||
operator.EnableEditingCostItem,
|
operator.EnableEditingCostItem,
|
||||||
|
operator.ExpandCostItems,
|
||||||
operator.EnableEditingCostItemQuantities,
|
operator.EnableEditingCostItemQuantities,
|
||||||
operator.EnableEditingCostItemQuantity,
|
operator.EnableEditingCostItemQuantity,
|
||||||
operator.EnableEditingCostItemValues,
|
operator.EnableEditingCostItemValues,
|
||||||
|
|||||||
@@ -281,7 +281,9 @@ class CostItemQuantitiesData:
|
|||||||
total_resources = len(bpy.context.scene.BIMResourceTreeProperties.resources)
|
total_resources = len(bpy.context.scene.BIMResourceTreeProperties.resources)
|
||||||
if not total_resources or active_resource_index >= total_resources:
|
if not total_resources or active_resource_index >= total_resources:
|
||||||
return []
|
return []
|
||||||
ifc_definition_id = bpy.context.scene.BIMResourceTreeProperties.resources[active_resource_index].ifc_definition_id
|
ifc_definition_id = bpy.context.scene.BIMResourceTreeProperties.resources[
|
||||||
|
active_resource_index
|
||||||
|
].ifc_definition_id
|
||||||
element = tool.Ifc.get().by_id(ifc_definition_id)
|
element = tool.Ifc.get().by_id(ifc_definition_id)
|
||||||
names = set()
|
names = set()
|
||||||
qtos = ifcopenshell.util.element.get_psets(element, qtos_only=True)
|
qtos = ifcopenshell.util.element.get_psets(element, qtos_only=True)
|
||||||
|
|||||||
@@ -62,15 +62,16 @@ class RemoveCostSchedule(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
core.remove_cost_schedule(tool.Ifc, cost_schedule=tool.Ifc.get().by_id(self.cost_schedule))
|
core.remove_cost_schedule(tool.Ifc, cost_schedule=tool.Ifc.get().by_id(self.cost_schedule))
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingCostSchedule(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingCostSchedule(bpy.types.Operator):
|
||||||
bl_idname = "bim.enable_editing_cost_schedule_attributes"
|
bl_idname = "bim.enable_editing_cost_schedule_attributes"
|
||||||
bl_label = "Enable Editing Cost Schedule"
|
bl_label = "Enable Editing Cost Schedule"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
bl_description = "Enable editing cost schedule"
|
bl_description = "Enable editing cost schedule"
|
||||||
cost_schedule: bpy.props.IntProperty()
|
cost_schedule: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
core.enable_editing_cost_schedule_attributes(tool.Cost, cost_schedule=tool.Ifc.get().by_id(self.cost_schedule))
|
core.enable_editing_cost_schedule_attributes(tool.Cost, cost_schedule=tool.Ifc.get().by_id(self.cost_schedule))
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingCostItems(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingCostItems(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -194,18 +195,13 @@ class AssignCostItemType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
prop_name: bpy.props.StringProperty()
|
prop_name: bpy.props.StringProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.assign_cost_item_type(
|
||||||
cost_item = self.file.by_id(self.cost_item)
|
tool.Ifc,
|
||||||
for obj in context.selected_objects:
|
tool.Cost,
|
||||||
if not obj.BIMObjectProperties.ifc_definition_id:
|
tool.Spatial,
|
||||||
continue
|
cost_item=tool.Ifc.get().by_id(self.cost_item),
|
||||||
product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
prop_name=self.prop_name, # TODO: REVIEW PROP_NAME USABILITY
|
||||||
if product.is_a("IfcTypeProduct"):
|
)
|
||||||
ifcopenshell.api.run(
|
|
||||||
"control.assign_control", self.file, relating_control=cost_item, related_object=product
|
|
||||||
)
|
|
||||||
bpy.ops.bim.load_cost_item_types()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class UnassignCostItemType(bpy.types.Operator, tool.Ifc.Operator):
|
class UnassignCostItemType(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -216,22 +212,12 @@ class UnassignCostItemType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
related_object: bpy.props.IntProperty()
|
related_object: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.unassign_cost_item_type(
|
||||||
cost_item = self.file.by_id(self.cost_item)
|
tool.Ifc,
|
||||||
if self.related_object:
|
tool.Cost,
|
||||||
products = [self.file.by_id(self.related_object)]
|
self.cost_item,
|
||||||
else:
|
products=[tool.Ifc.get().by_id(self.related_object)] if 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
|
|
||||||
)
|
|
||||||
bpy.ops.bim.load_cost_item_types()
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -244,157 +230,106 @@ class AssignCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
prop_name: bpy.props.StringProperty()
|
prop_name: bpy.props.StringProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
if self.related_object_type == "PRODUCT":
|
core.assign_cost_item_quantity(
|
||||||
products = [
|
tool.Ifc,
|
||||||
tool.Ifc.get().by_id(o.BIMObjectProperties.ifc_definition_id)
|
tool.Cost,
|
||||||
for o in context.selected_objects
|
|
||||||
if o.BIMObjectProperties.ifc_definition_id
|
|
||||||
]
|
|
||||||
elif self.related_object_type == "PROCESS":
|
|
||||||
products = [
|
|
||||||
tool.Ifc.get().by_id(
|
|
||||||
context.scene.BIMTaskTreeProperties.tasks[
|
|
||||||
context.scene.BIMWorkScheduleProperties.active_task_index
|
|
||||||
].ifc_definition_id
|
|
||||||
)
|
|
||||||
]
|
|
||||||
elif self.related_object_type == "RESOURCE":
|
|
||||||
products = [
|
|
||||||
tool.Ifc.get().by_id(
|
|
||||||
context.scene.BIMResourceTreeProperties.resources[
|
|
||||||
context.scene.BIMResourceProperties.active_resource_index
|
|
||||||
].ifc_definition_id
|
|
||||||
)
|
|
||||||
]
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.assign_cost_item_quantity",
|
|
||||||
tool.Ifc.get(),
|
|
||||||
cost_item=tool.Ifc.get().by_id(self.cost_item),
|
cost_item=tool.Ifc.get().by_id(self.cost_item),
|
||||||
products=products,
|
related_object_type=self.related_object_type,
|
||||||
prop_name=self.prop_name,
|
prop_name=self.prop_name, # TODO: REVIEW PROP_NAME USABILITY
|
||||||
)
|
)
|
||||||
bpy.ops.bim.load_cost_item_quantities()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class UnassignCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
class UnassignCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.unassign_cost_item_quantity"
|
bl_idname = "bim.unassign_cost_item_quantity"
|
||||||
bl_label = "Unassign Cost Item Quantity"
|
bl_label = "Unassign Cost Item Quantity"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Unassign cost item quantity"
|
||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
related_object: bpy.props.IntProperty()
|
related_object: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.unassign_cost_item_quantity(
|
||||||
if self.related_object:
|
tool.Ifc,
|
||||||
products = [self.file.by_id(self.related_object)]
|
tool.Cost,
|
||||||
else:
|
cost_item=tool.Ifc.get().by_id(self.cost_item),
|
||||||
products = [
|
products=[tool.Ifc.get().by_id(self.related_object)]
|
||||||
self.file.by_id(o.BIMObjectProperties.ifc_definition_id)
|
if self.related_object
|
||||||
for o in context.selected_objects
|
else tool.Spatial.get_selected_products(),
|
||||||
if o.BIMObjectProperties.ifc_definition_id
|
|
||||||
]
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.unassign_cost_item_quantity",
|
|
||||||
self.file,
|
|
||||||
cost_item=self.file.by_id(self.cost_item),
|
|
||||||
products=products,
|
|
||||||
)
|
)
|
||||||
bpy.ops.bim.load_cost_item_quantities()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingCostItemQuantities(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingCostItemQuantities(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.enable_editing_cost_item_quantities"
|
bl_idname = "bim.enable_editing_cost_item_quantities"
|
||||||
bl_label = "Enable Editing Cost Item Quantities"
|
bl_label = "Enable Editing Cost Item Quantities"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Enable editing cost item quantities"
|
||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.enable_editing_cost_item_quantities(tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item))
|
||||||
props.active_cost_item_id = self.cost_item
|
|
||||||
props.cost_item_editing_type = "QUANTITIES"
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingCostItemValues(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingCostItemValues(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.enable_editing_cost_item_values"
|
bl_idname = "bim.enable_editing_cost_item_values"
|
||||||
bl_label = "Enable Editing Cost Item Values"
|
bl_label = "Enable Editing Cost Item Values"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Enable editing cost item values"
|
||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.enable_editing_cost_item_values(tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item))
|
||||||
props.active_cost_item_id = self.cost_item
|
|
||||||
props.cost_item_editing_type = "VALUES"
|
|
||||||
bpy.ops.bim.disable_editing_cost_item_value()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class AddCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
class AddCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.add_cost_item_quantity"
|
bl_idname = "bim.add_cost_item_quantity"
|
||||||
bl_label = "Add Cost Item Quantity"
|
bl_label = "Add Cost Item Quantity"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Add cost item quantity"
|
||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
ifc_class: bpy.props.StringProperty()
|
ifc_class: bpy.props.StringProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.add_cost_item_quantity(tool.Ifc, cost_item=tool.Ifc.get().by_id(self.cost_item), ifc_class=self.ifc_class)
|
||||||
self.props = context.scene.BIMCostProperties
|
|
||||||
self.add_manual_quantity()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
def add_manual_quantity(self):
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.add_cost_item_quantity",
|
|
||||||
self.file,
|
|
||||||
cost_item=self.file.by_id(self.cost_item),
|
|
||||||
ifc_class=self.ifc_class,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class RemoveCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
class RemoveCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.remove_cost_item_quantity"
|
bl_idname = "bim.remove_cost_item_quantity"
|
||||||
bl_label = "Remove Cost Item Quantity"
|
bl_label = "Remove Cost Item Quantity"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Remove cost item quantity"
|
||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
physical_quantity: bpy.props.IntProperty()
|
physical_quantity: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.remove_cost_item_quantity(
|
||||||
ifcopenshell.api.run(
|
tool.Ifc,
|
||||||
"cost.remove_cost_item_quantity",
|
cost_item=tool.Ifc.get().by_id(self.cost_item),
|
||||||
self.file,
|
physical_quantity=tool.Ifc.get().by_id(self.physical_quantity),
|
||||||
cost_item=self.file.by_id(self.cost_item),
|
|
||||||
physical_quantity=self.file.by_id(self.physical_quantity),
|
|
||||||
)
|
)
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingCostItemQuantity(bpy.types.Operator):
|
||||||
bl_idname = "bim.enable_editing_cost_item_quantity"
|
bl_idname = "bim.enable_editing_cost_item_quantity"
|
||||||
bl_label = "Enable Editing Cost Item Quantity"
|
bl_label = "Enable Editing Cost Item Quantity"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Enable editing cost item quantity"
|
||||||
physical_quantity: bpy.props.IntProperty()
|
physical_quantity: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
core.enable_editing_cost_item_quantity(
|
||||||
self.props.quantity_attributes.clear()
|
tool.Cost, physical_quantity=tool.Ifc.get().by_id(self.physical_quantity)
|
||||||
self.props.active_cost_item_quantity_id = self.physical_quantity
|
|
||||||
blenderbim.bim.helper.import_attributes2(
|
|
||||||
tool.Ifc.get().by_id(self.physical_quantity), self.props.quantity_attributes
|
|
||||||
)
|
)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class DisableEditingCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
class DisableEditingCostItemQuantity(bpy.types.Operator):
|
||||||
bl_idname = "bim.disable_editing_cost_item_quantity"
|
bl_idname = "bim.disable_editing_cost_item_quantity"
|
||||||
bl_label = "Disable Editing Cost Item Quantity"
|
bl_label = "Disable Editing Cost Item Quantity"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Disable editing cost item quantity"
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.disable_editing_cost_item_quantity(tool.Cost)
|
||||||
props.active_cost_item_quantity_id = 0
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -405,16 +340,9 @@ class EditCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
physical_quantity: bpy.props.IntProperty()
|
physical_quantity: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.edit_cost_item_quantity(
|
||||||
attributes = blenderbim.bim.helper.export_attributes(props.quantity_attributes)
|
tool.Ifc, tool.Cost, physical_quantity=tool.Ifc.get().by_id(self.physical_quantity)
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.edit_cost_item_quantity",
|
|
||||||
self.file,
|
|
||||||
**{"physical_quantity": self.file.by_id(self.physical_quantity), "attributes": attributes},
|
|
||||||
)
|
)
|
||||||
bpy.ops.bim.disable_editing_cost_item_quantity()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class AddCostValue(bpy.types.Operator, tool.Ifc.Operator):
|
class AddCostValue(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -426,19 +354,13 @@ class AddCostValue(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
cost_category: bpy.props.StringProperty()
|
cost_category: bpy.props.StringProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.add_cost_value(
|
||||||
parent = self.file.by_id(self.parent)
|
tool.Ifc,
|
||||||
if self.cost_type == "FIXED":
|
tool.Cost,
|
||||||
category = None
|
parent=tool.Ifc.get().by_id(self.parent),
|
||||||
attributes = {"AppliedValue": 0.0}
|
cost_type=self.cost_type,
|
||||||
elif self.cost_type == "SUM":
|
cost_category=self.cost_category,
|
||||||
category = "*"
|
)
|
||||||
attributes = {"Category": category}
|
|
||||||
elif self.cost_type == "CATEGORY":
|
|
||||||
category = self.cost_category
|
|
||||||
attributes = {"Category": category}
|
|
||||||
value = ifcopenshell.api.run("cost.add_cost_value", self.file, parent=parent)
|
|
||||||
ifcopenshell.api.run("cost.edit_cost_value", self.file, cost_value=value, attributes=attributes)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -450,114 +372,41 @@ class RemoveCostItemValue(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.remove_cost_value(
|
||||||
parent = self.file.by_id(self.parent)
|
tool.Ifc, parent=tool.Ifc.get().by_id(self.parent), cost_value=tool.Ifc.get().by_id(self.cost_value)
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.remove_cost_value",
|
|
||||||
self.file,
|
|
||||||
parent=parent,
|
|
||||||
cost_value=self.file.by_id(self.cost_value),
|
|
||||||
)
|
)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingCostItemValue(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingCostItemValue(bpy.types.Operator):
|
||||||
bl_idname = "bim.enable_editing_cost_item_value"
|
bl_idname = "bim.enable_editing_cost_item_value"
|
||||||
bl_label = "Enable Editing Cost Item Value"
|
bl_label = "Enable Editing Cost Item Value"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
core.enable_editing_cost_item_value(tool.Cost, cost_value=tool.Ifc.get().by_id(self.cost_value))
|
||||||
self.props.cost_value_attributes.clear()
|
|
||||||
self.props.active_cost_value_id = self.cost_value
|
|
||||||
self.props.cost_value_editing_type = "ATTRIBUTES"
|
|
||||||
schedule = tool.Ifc.get().by_id(context.scene.BIMCostProperties.active_cost_schedule_id)
|
|
||||||
is_rates = schedule.PredefinedType == "SCHEDULEOFRATES"
|
|
||||||
cost_value = tool.Ifc.get().by_id(self.cost_value)
|
|
||||||
callback = lambda name, prop, data: self.import_attributes(name, prop, data, cost_value, is_rates)
|
|
||||||
blenderbim.bim.helper.import_attributes2(cost_value, self.props.cost_value_attributes, callback=callback)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def import_attributes(self, name, prop, data, cost_value, is_rates):
|
|
||||||
if name == "AppliedValue":
|
|
||||||
# TODO: for now, only support simple IfcValues (which are effectively IfcMonetaryMeasure)
|
|
||||||
prop = self.props.cost_value_attributes.add()
|
|
||||||
prop.data_type = "float"
|
|
||||||
prop.name = "AppliedValue"
|
|
||||||
prop.is_optional = True
|
|
||||||
prop.float_value = (
|
|
||||||
0.0
|
|
||||||
if prop.is_null
|
|
||||||
else ifcopenshell.util.cost.calculate_applied_value(
|
|
||||||
tool.Ifc.get().by_id(self.props.active_cost_item_id), cost_value
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
if name == "UnitBasis" and is_rates:
|
|
||||||
prop = self.props.cost_value_attributes.add()
|
|
||||||
prop.name = "UnitBasisValue"
|
|
||||||
prop.data_type = "float"
|
|
||||||
prop.is_null = data["UnitBasis"] is None
|
|
||||||
prop.is_optional = True
|
|
||||||
if data["UnitBasis"]:
|
|
||||||
prop.float_value = data["UnitBasis"]["ValueComponent"] or 0
|
|
||||||
else:
|
|
||||||
prop.float_value = 0
|
|
||||||
|
|
||||||
prop = self.props.cost_value_attributes.add()
|
class DisableEditingCostItemValue(bpy.types.Operator):
|
||||||
prop.name = "UnitBasisUnit"
|
|
||||||
prop.data_type = "enum"
|
|
||||||
prop.is_null = prop.is_optional = False
|
|
||||||
units = {}
|
|
||||||
for unit in tool.Ifc.get().by_type("IfcNamedUnit"):
|
|
||||||
if unit.get("UnitType", None) in [
|
|
||||||
"AREAUNIT",
|
|
||||||
"LENGTHUNIT",
|
|
||||||
"TIMEUNIT",
|
|
||||||
"VOLUMEUNIT",
|
|
||||||
"MASSUNIT",
|
|
||||||
"USERDEFINED",
|
|
||||||
]:
|
|
||||||
if unit.is_a("IfcContextDependentUnit"):
|
|
||||||
units[unit.id()] = f"{unit.UnitType} / {unit.Name}"
|
|
||||||
else:
|
|
||||||
name = unit.Name
|
|
||||||
if unit.get("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"]:
|
|
||||||
prop.enum_value = str(data["UnitBasis"]["UnitComponent"])
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class DisableEditingCostItemValue(bpy.types.Operator, tool.Ifc.Operator):
|
|
||||||
bl_idname = "bim.disable_editing_cost_item_value"
|
bl_idname = "bim.disable_editing_cost_item_value"
|
||||||
bl_label = "Disable Editing Cost Item Value"
|
bl_label = "Disable Editing Cost Item Value"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.disable_editing_cost_item_value(tool.Cost)
|
||||||
props.active_cost_value_id = 0
|
|
||||||
props.cost_value_editing_type = ""
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingCostItemValueFormula(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingCostItemValueFormula(bpy.types.Operator):
|
||||||
bl_idname = "bim.enable_editing_cost_item_value_formula"
|
bl_idname = "bim.enable_editing_cost_item_value_formula"
|
||||||
bl_label = "Enable Editing Cost Item Value Formula"
|
bl_label = "Enable Editing Cost Item Value Formula"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
core.enable_editing_cost_item_value_formula(tool.Cost, cost_value=tool.Ifc.get().by_id(self.cost_value))
|
||||||
self.props.cost_value_attributes.clear()
|
|
||||||
self.props.active_cost_value_id = self.cost_value
|
|
||||||
self.props.cost_value_editing_type = "FORMULA"
|
|
||||||
self.props.cost_value_formula = ifcopenshell.util.cost.serialise_cost_value(
|
|
||||||
tool.Ifc.get().by_id(self.cost_value)
|
|
||||||
)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -568,14 +417,7 @@ class EditCostItemValueFormula(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.edit_cost_item_value_formula(tool.Ifc, tool.Cost, cost_value=tool.Ifc.get().by_id(self.cost_value))
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.edit_cost_value_formula",
|
|
||||||
self.file,
|
|
||||||
**{"cost_value": self.file.by_id(self.cost_value), "formula": props.cost_value_formula},
|
|
||||||
)
|
|
||||||
bpy.ops.bim.disable_editing_cost_item_value()
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -586,34 +428,9 @@ class EditCostItemValue(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.edit_cost_value(tool.Ifc, tool.Cost, cost_value=tool.Ifc.get().by_id(self.cost_value))
|
||||||
attributes = blenderbim.bim.helper.export_attributes(
|
|
||||||
props.cost_value_attributes, lambda attributes, prop: self.export_attributes(attributes, prop, context)
|
|
||||||
)
|
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.edit_cost_value",
|
|
||||||
self.file,
|
|
||||||
**{"cost_value": self.file.by_id(self.cost_value), "attributes": attributes},
|
|
||||||
)
|
|
||||||
bpy.ops.bim.disable_editing_cost_item_value()
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def export_attributes(self, attributes, prop, context):
|
|
||||||
if prop.name == "UnitBasisValue":
|
|
||||||
if prop.is_null:
|
|
||||||
attributes["UnitBasis"] = None
|
|
||||||
return True
|
|
||||||
attributes["UnitBasis"] = {
|
|
||||||
"ValueComponent": prop.float_value or 1,
|
|
||||||
"UnitComponent": IfcStore.get_file().by_id(
|
|
||||||
int(context.scene.BIMCostProperties.cost_value_attributes.get("UnitBasisUnit").enum_value)
|
|
||||||
),
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
if prop.name == "UnitBasisUnit":
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class CopyCostItemValues(bpy.types.Operator, tool.Ifc.Operator):
|
class CopyCostItemValues(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.copy_cost_item_values"
|
bl_idname = "bim.copy_cost_item_values"
|
||||||
@@ -623,11 +440,11 @@ class CopyCostItemValues(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
destination: bpy.props.IntProperty()
|
destination: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.copy_cost_item_values(
|
||||||
ifcopenshell.api.run(
|
tool.Ifc,
|
||||||
"cost.copy_cost_item_values",
|
tool.Cost,
|
||||||
self.file,
|
source=tool.Ifc.get().by_id(self.source),
|
||||||
**{"source": self.file.by_id(self.source), "destination": self.file.by_id(self.destination)},
|
destination=tool.Ifc.get().by_id(self.destination),
|
||||||
)
|
)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -639,40 +456,24 @@ class SelectCostItemProducts(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
related_objects = []
|
core.select_cost_item_products(
|
||||||
[related_objects.extend(r.RelatedObjects) for r in tool.Ifc.get().by_id(self.cost_item).Controls or []]
|
tool.Cost, tool.Spatial, cost_item=tool.Ifc.get().by_id(self.cost_item), include_nested=False
|
||||||
related_objects = set([r.id() for r in related_objects])
|
)
|
||||||
for obj in context.visible_objects:
|
|
||||||
obj.select_set(False)
|
|
||||||
if obj.BIMObjectProperties.ifc_definition_id in related_objects:
|
|
||||||
obj.select_set(True)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class SelectCostScheduleProducts(bpy.types.Operator, tool.Ifc.Operator):
|
class SelectCostScheduleProducts(bpy.types.Operator):
|
||||||
bl_idname = "bim.select_cost_schedule_products"
|
bl_idname = "bim.select_cost_schedule_products"
|
||||||
bl_label = "Select Cost Schedule Products"
|
bl_label = "Select Cost Schedule Products"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
cost_schedule: bpy.props.IntProperty()
|
cost_schedule: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.select_cost_schedule_products(
|
||||||
self.related_products = []
|
tool.Cost, tool.Spatial, cost_schedule=tool.Ifc.get().by_id(self.cost_schedule)
|
||||||
for cost_item in tool.Ifc.get().by_id(self.cost_schedule).Controls or []:
|
)
|
||||||
self.get_related_products(cost_item)
|
|
||||||
self.related_products = set(self.related_products)
|
|
||||||
for obj in context.visible_objects:
|
|
||||||
obj.select_set(False)
|
|
||||||
if obj.BIMObjectProperties.ifc_definition_id in self.related_products:
|
|
||||||
obj.select_set(True)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def get_related_products(self, cost_item):
|
|
||||||
[self.related_products.extend(r.RelatedObjects) for r in cost_item.Controls or []]
|
|
||||||
for rel in cost_item.IsNestedBy or []:
|
|
||||||
for sub_cost_item in rel.RelatedObjects:
|
|
||||||
self.get_related_products(sub_cost_item)
|
|
||||||
|
|
||||||
|
|
||||||
class ImportCostScheduleCsv(bpy.types.Operator, ImportHelper, tool.Ifc.Operator):
|
class ImportCostScheduleCsv(bpy.types.Operator, ImportHelper, tool.Ifc.Operator):
|
||||||
bl_idname = "import_cost_schedule_csv.bim"
|
bl_idname = "import_cost_schedule_csv.bim"
|
||||||
@@ -683,158 +484,75 @@ class ImportCostScheduleCsv(bpy.types.Operator, ImportHelper, tool.Ifc.Operator)
|
|||||||
is_schedule_of_rates: bpy.props.BoolProperty(name="Is Schedule Of Rates", default=False)
|
is_schedule_of_rates: bpy.props.BoolProperty(name="Is Schedule Of Rates", default=False)
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
from ifc5d.csv2ifc import Csv2Ifc
|
core.import_cost_schedule_csv(tool.Cost, self.filepath, self.is_schedule_of_rates)
|
||||||
|
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
start = time.time()
|
|
||||||
csv2ifc = Csv2Ifc()
|
|
||||||
csv2ifc.csv = self.filepath
|
|
||||||
csv2ifc.file = self.file
|
|
||||||
csv2ifc.is_schedule_of_rates = self.is_schedule_of_rates
|
|
||||||
csv2ifc.execute()
|
|
||||||
print("Import finished in {:.2f} seconds".format(time.time() - start))
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class AddCostColumn(bpy.types.Operator, tool.Ifc.Operator):
|
class AddCostColumn(bpy.types.Operator):
|
||||||
bl_idname = "bim.add_cost_column"
|
bl_idname = "bim.add_cost_column"
|
||||||
bl_label = "Add Cost Column"
|
bl_label = "Add Cost Column"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
name: bpy.props.StringProperty()
|
name: bpy.props.StringProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
core.add_cost_column(tool.Cost, self.name)
|
||||||
new = self.props.columns.add()
|
|
||||||
new.name = self.name
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class RemoveCostColumn(bpy.types.Operator, tool.Ifc.Operator):
|
class RemoveCostColumn(bpy.types.Operator):
|
||||||
bl_idname = "bim.remove_cost_column"
|
bl_idname = "bim.remove_cost_column"
|
||||||
bl_label = "Remove Cost Column"
|
bl_label = "Remove Cost Column"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
name: bpy.props.StringProperty()
|
name: bpy.props.StringProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
core.remove_cost_column(tool.Cost, self.name)
|
||||||
self.props.columns.remove(self.props.columns.find(self.name))
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class LoadCostItemQuantities(bpy.types.Operator, tool.Ifc.Operator):
|
class LoadCostItemQuantities(bpy.types.Operator):
|
||||||
bl_idname = "bim.load_cost_item_quantities"
|
bl_idname = "bim.load_cost_item_quantities"
|
||||||
bl_label = "Load Cost Item Quantities"
|
bl_label = "Load Cost Item Quantities"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
core.load_cost_item_quantities(tool.Cost)
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
self.props.cost_item_products.clear()
|
|
||||||
self.props.cost_item_processes.clear()
|
|
||||||
self.props.cost_item_resources.clear()
|
|
||||||
if self.props.active_cost_item_index < len(self.props.cost_items):
|
|
||||||
ifc_definition_id = self.props.cost_items[self.props.active_cost_item_index].ifc_definition_id
|
|
||||||
cost_item = tool.Ifc.get().by_id(ifc_definition_id)
|
|
||||||
# for control_id, quantity_ids in cost_item.Controls.items() or {}:
|
|
||||||
for rel in cost_item.Controls or []:
|
|
||||||
# control_id, quantity_ids
|
|
||||||
for related_object in rel.RelatedObjects:
|
|
||||||
if related_object.is_a("IfcProduct"):
|
|
||||||
new = self.props.cost_item_products.add()
|
|
||||||
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 = related_object.id()
|
|
||||||
new.name = related_object.Name or "Unnamed"
|
|
||||||
total_quantity = 0
|
|
||||||
qtos = ifcopenshell.util.element.get_psets(related_object, qtos_only=True)
|
|
||||||
for qset_name, quantities in qtos.items():
|
|
||||||
qto = tool.Ifc.get().by_id(quantities["id"])
|
|
||||||
for quantity in qto.Quantities:
|
|
||||||
if quantity in cost_item.CostQuantities:
|
|
||||||
total_quantity += quantity[3]
|
|
||||||
new.total_quantity = total_quantity
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class LoadCostItemTypes(bpy.types.Operator, tool.Ifc.Operator):
|
class LoadCostItemTypes(bpy.types.Operator):
|
||||||
bl_idname = "bim.load_cost_item_types"
|
bl_idname = "bim.load_cost_item_types"
|
||||||
bl_label = "Load Cost Item Types"
|
bl_label = "Load Cost Item Types"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
core.load_cost_item_types(tool.Cost)
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
self.props.cost_item_type_products.clear()
|
|
||||||
# TODO implement process and resource types
|
|
||||||
# self.props.cost_item_processes.clear()
|
|
||||||
# self.props.cost_item_resources.clear()
|
|
||||||
ifc_definition_id = self.props.cost_items[self.props.active_cost_item_index].ifc_definition_id
|
|
||||||
cost_item = tool.Ifc.get().by_id(ifc_definition_id)
|
|
||||||
for rel in cost_item.Controls or []:
|
|
||||||
for related_object in rel.RelatedObjects:
|
|
||||||
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 = related_object.id()
|
|
||||||
new.name = related_object.Name or "Unnamed"
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class AssignCostValue(bpy.types.Operator, tool.Ifc.Operator):
|
class AssignCostValue(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.assign_cost_value"
|
bl_idname = "bim.assign_cost_value"
|
||||||
bl_label = "Assign Cost Value"
|
bl_label = "Assign Cost Rate Value"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
cost_rate: bpy.props.IntProperty()
|
cost_rate: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.assign_cost_value(
|
||||||
ifcopenshell.api.run(
|
tool.Ifc, cost_item=tool.Ifc.get().by_id(self.cost_item), cost_rate=tool.Ifc.get().by_id(self.cost_rate)
|
||||||
"cost.assign_cost_value",
|
|
||||||
self.file,
|
|
||||||
cost_item=self.file.by_id(self.cost_item),
|
|
||||||
cost_rate=self.file.by_id(self.cost_rate),
|
|
||||||
)
|
)
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class LoadScheduleOfRates(bpy.types.Operator, tool.Ifc.Operator):
|
class LoadScheduleOfRates(bpy.types.Operator):
|
||||||
bl_idname = "bim.load_schedule_of_rates"
|
bl_idname = "bim.load_schedule_of_rates_tree"
|
||||||
bl_label = "Load Schedule of Rates"
|
bl_label = "Load Schedule of Rates"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
cost_schedule: bpy.props.IntProperty()
|
cost_schedule: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
core.load_schedule_of_rates_tree(tool.Cost, schedule_of_rates=tool.Ifc.get().by_id(self.cost_schedule))
|
||||||
self.props.is_cost_update_enabled = False
|
|
||||||
self.props.cost_item_rates.clear()
|
|
||||||
self.contracted_cost_item_rates = json.loads(self.props.contracted_cost_item_rates)
|
|
||||||
for rel in tool.Ifc.get().by_id(self.cost_schedule).Controls or []:
|
|
||||||
for cost_item in rel.RelatedObjects:
|
|
||||||
self.create_new_cost_item_li(cost_item, 0)
|
|
||||||
self.props.is_cost_update_enabled = True
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def create_new_cost_item_li(self, cost_item, level_index):
|
|
||||||
new = self.props.cost_item_rates.add()
|
|
||||||
new.ifc_definition_id = cost_item.id()
|
|
||||||
new.name = cost_item.Name or "Unnamed"
|
|
||||||
new.identification = cost_item.Identification or "XXX"
|
|
||||||
new.is_expanded = cost_item.id() not in self.contracted_cost_item_rates
|
|
||||||
new.level_index = level_index
|
|
||||||
if cost_item.IsNestedBy:
|
|
||||||
new.has_children = True
|
|
||||||
if new.is_expanded:
|
|
||||||
for rel in cost_item.IsNestedBy:
|
|
||||||
for sub_cost_item in rel.RelatedObjects:
|
|
||||||
self.create_new_cost_item_li(sub_cost_item, level_index + 1)
|
|
||||||
|
|
||||||
|
|
||||||
class ExpandCostItemRate(bpy.types.Operator, tool.Ifc.Operator):
|
class ExpandCostItemRate(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.expand_cost_item_rate"
|
bl_idname = "bim.expand_cost_item_rate"
|
||||||
@@ -843,12 +561,7 @@ class ExpandCostItemRate(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.expand_cost_item_rate(tool.Cost, self.cost_item)
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates)
|
|
||||||
contracted_cost_item_rates.remove(self.cost_item)
|
|
||||||
props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates)
|
|
||||||
bpy.ops.bim.load_schedule_of_rates(cost_schedule=int(props.schedule_of_rates))
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -859,12 +572,7 @@ class ContractCostItemRate(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMCostProperties
|
core.contract_cost_item_rate(tool.Cost, self.cost_item)
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates)
|
|
||||||
contracted_cost_item_rates.append(self.cost_item)
|
|
||||||
props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates)
|
|
||||||
bpy.ops.bim.load_schedule_of_rates(cost_schedule=int(props.schedule_of_rates))
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -875,8 +583,6 @@ class CalculateCostItemResourceValue(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
cost_item: bpy.props.IntProperty()
|
cost_item: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.calculate_cost_item_resource_value(tool.Ifc, cost_item=tool.Ifc.get().by_id(self.cost_item))
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.calculate_cost_item_resource_value", self.file, cost_item=self.file.by_id(self.cost_item)
|
|
||||||
)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ def get_schedule_of_rates(self, context):
|
|||||||
|
|
||||||
|
|
||||||
def update_schedule_of_rates(self, context):
|
def update_schedule_of_rates(self, context):
|
||||||
bpy.ops.bim.load_schedule_of_rates(cost_schedule=int(self.schedule_of_rates))
|
tool.Cost.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(self.schedule_of_rates)))
|
||||||
|
|
||||||
|
|
||||||
def get_quantity_types(self, context):
|
def get_quantity_types(self, context):
|
||||||
@@ -73,9 +73,9 @@ def get_resource_quantity_names(self, context):
|
|||||||
def update_active_cost_item_index(self, context):
|
def update_active_cost_item_index(self, context):
|
||||||
schedule = tool.Ifc.get().by_id(self.active_cost_schedule_id)
|
schedule = tool.Ifc.get().by_id(self.active_cost_schedule_id)
|
||||||
if schedule.PredefinedType == "SCHEDULEOFRATES":
|
if schedule.PredefinedType == "SCHEDULEOFRATES":
|
||||||
bpy.ops.bim.load_cost_item_types()
|
tool.Cost.load_cost_item_types()
|
||||||
else:
|
else:
|
||||||
bpy.ops.bim.load_cost_item_quantities()
|
tool.Cost.load_cost_item_quantities(cost_item=tool.Cost.get_highlighted_cost_item())
|
||||||
CostClassificationsData.load()
|
CostClassificationsData.load()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -470,13 +470,14 @@ class BIM_PT_cost_item_rates(Panel):
|
|||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
self.props = context.scene.BIMCostProperties
|
self.props = context.scene.BIMCostProperties
|
||||||
cost_item = self.props.cost_items[self.props.active_cost_item_index]
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(self.props, "schedule_of_rates", text="")
|
row.prop(self.props, "schedule_of_rates", text="")
|
||||||
if self.props.active_cost_item_rate_index < len(self.props.cost_item_rates):
|
if self.props.active_cost_item_rate_index < len(self.props.cost_item_rates):
|
||||||
|
cost_item = self.props.cost_items[self.props.active_cost_item_index]
|
||||||
|
cost_item_rate = self.props.cost_item_rates[self.props.active_cost_item_rate_index]
|
||||||
op = row.operator("bim.assign_cost_value", text="", icon="COPYDOWN")
|
op = row.operator("bim.assign_cost_value", text="", icon="COPYDOWN")
|
||||||
op.cost_item = self.props.cost_items[self.props.active_cost_item_index].ifc_definition_id
|
op.cost_item = cost_item.ifc_definition_id
|
||||||
op.cost_rate = self.props.cost_item_rates[self.props.active_cost_item_rate_index].ifc_definition_id
|
op.cost_rate = cost_item_rate.ifc_definition_id
|
||||||
self.layout.template_list(
|
self.layout.template_list(
|
||||||
"BIM_UL_cost_item_rates",
|
"BIM_UL_cost_item_rates",
|
||||||
"",
|
"",
|
||||||
|
|||||||
@@ -1,65 +1,212 @@
|
|||||||
def add_cost_schedule(ifc):
|
def add_cost_schedule(ifc):
|
||||||
ifc.run("cost.add_cost_schedule")
|
ifc.run("cost.add_cost_schedule")
|
||||||
|
|
||||||
|
|
||||||
def edit_cost_schedule(ifc, cost, cost_schedule):
|
def edit_cost_schedule(ifc, cost, cost_schedule):
|
||||||
attributes = cost.get_cost_schedule_attributes()
|
attributes = cost.get_cost_schedule_attributes()
|
||||||
ifc.run("cost.edit_cost_schedule", cost_schedule=cost_schedule, attributes=attributes)
|
ifc.run("cost.edit_cost_schedule", cost_schedule=cost_schedule, attributes=attributes)
|
||||||
cost.disable_editing_cost_schedule()
|
cost.disable_editing_cost_schedule()
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_cost_schedule(cost):
|
def disable_editing_cost_schedule(cost):
|
||||||
cost.disable_editing_cost_schedule()
|
cost.disable_editing_cost_schedule()
|
||||||
|
|
||||||
|
|
||||||
def remove_cost_schedule(ifc, cost_schedule):
|
def remove_cost_schedule(ifc, cost_schedule):
|
||||||
ifc.run("cost.remove_cost_schedule", cost_schedule=cost_schedule)
|
ifc.run("cost.remove_cost_schedule", cost_schedule=cost_schedule)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_cost_schedule_attributes(cost, cost_schedule):
|
def enable_editing_cost_schedule_attributes(cost, cost_schedule):
|
||||||
|
cost.load_cost_schedule_attributes(cost_schedule)
|
||||||
cost.enable_editing_cost_schedule_attributes(cost_schedule)
|
cost.enable_editing_cost_schedule_attributes(cost_schedule)
|
||||||
cost.load_cost_items()
|
cost.play_sound()
|
||||||
cost.play_chaching_sound()
|
|
||||||
|
|
||||||
def enable_editing_cost_items(cost, cost_schedule):
|
def enable_editing_cost_items(cost, cost_schedule):
|
||||||
cost.enable_editing_cost_items(cost_schedule)
|
cost.enable_editing_cost_items(cost_schedule)
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
|
cost.play_sound()
|
||||||
|
|
||||||
def add_summary_cost_item(ifc, cost, cost_schedule):
|
def add_summary_cost_item(ifc, cost, cost_schedule):
|
||||||
ifc.run("cost.add_cost_item", cost_schedule=cost_schedule)
|
ifc.run("cost.add_cost_item", cost_schedule=cost_schedule)
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
|
# cost.play_sound()
|
||||||
|
|
||||||
def add_cost_item(ifc, cost, cost_item):
|
def add_cost_item(ifc, cost, cost_item):
|
||||||
ifc.run("cost.add_cost_item", cost_item=cost_item)
|
ifc.run("cost.add_cost_item", cost_item=cost_item)
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
# cost.enable_editing_cost_schedule_attributes(cost_schedule)
|
# cost.enable_editing_cost_schedule_attributes(cost_schedule)
|
||||||
|
|
||||||
|
|
||||||
def expand_cost_item(cost, cost_item):
|
def expand_cost_item(cost, cost_item):
|
||||||
cost.expand_cost_item(cost_item)
|
cost.expand_cost_item(cost_item)
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
|
|
||||||
|
|
||||||
def expand_cost_items(cost):
|
def expand_cost_items(cost):
|
||||||
cost.expand_cost_items()
|
cost.expand_cost_items()
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
|
|
||||||
|
|
||||||
def contract_cost_item(cost, cost_item):
|
def contract_cost_item(cost, cost_item):
|
||||||
cost.contract_cost_item(cost_item)
|
cost.contract_cost_item(cost_item)
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
|
|
||||||
|
|
||||||
def contract_cost_items(cost):
|
def contract_cost_items(cost):
|
||||||
cost.contract_cost_items()
|
cost.contract_cost_items()
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
|
|
||||||
|
|
||||||
def remove_cost_item(ifc, cost, cost_item):
|
def remove_cost_item(ifc, cost, cost_item):
|
||||||
ifc.run("cost.remove_cost_item", cost_item=cost_item)
|
ifc.run("cost.remove_cost_item", cost_item=cost_item)
|
||||||
cost.clean_up_cost_item_tree(cost_item)
|
cost.clean_up_cost_item_tree(cost_item)
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_cost_item_attributes(cost, cost_item):
|
def enable_editing_cost_item_attributes(cost, cost_item):
|
||||||
cost.enable_editing_cost_item_attributes(cost_item)
|
cost.enable_editing_cost_item_attributes(cost_item)
|
||||||
cost.load_cost_item_attributes(cost_item)
|
cost.load_cost_item_attributes(cost_item)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_cost_item(cost):
|
def disable_editing_cost_item(cost):
|
||||||
cost.disable_editing_cost_item()
|
cost.disable_editing_cost_item()
|
||||||
|
|
||||||
|
|
||||||
def edit_cost_item(ifc, cost):
|
def edit_cost_item(ifc, cost):
|
||||||
attributes = cost.get_cost_item_attributes()
|
attributes = cost.get_cost_item_attributes()
|
||||||
ifc.run("cost.edit_cost_item", cost_item=cost.get_active_cost_item(), attributes=attributes)
|
ifc.run("cost.edit_cost_item", cost_item=cost.get_active_cost_item(), attributes=attributes)
|
||||||
cost.disable_editing_cost_item()
|
cost.disable_editing_cost_item()
|
||||||
cost.load_cost_items()
|
cost.load_cost_schedule_tree()
|
||||||
|
|
||||||
|
|
||||||
|
def assign_cost_item_type(ifc, cost, spatial, cost_item, prop_name):
|
||||||
|
product_types = spatial.get_selected_product_types()
|
||||||
|
[
|
||||||
|
ifc.run("control.assign_control", relating_control=cost_item, related_object=product_type)
|
||||||
|
for product_type in product_types
|
||||||
|
]
|
||||||
|
cost.load_cost_item_types(cost_item)
|
||||||
|
|
||||||
|
|
||||||
|
def unassign_cost_item_type(ifc, cost, spatial, cost_item, product_types):
|
||||||
|
if not product_types:
|
||||||
|
product_types = spatial.get_selected_product_types()
|
||||||
|
[
|
||||||
|
ifc.run("control.unassign_control", relating_control=cost_item, related_object=product_type)
|
||||||
|
for product_type in product_types
|
||||||
|
]
|
||||||
|
cost.load_cost_item_types(cost_item)
|
||||||
|
|
||||||
|
|
||||||
|
def load_cost_item_types(cost):
|
||||||
|
cost_item = cost.get_active_cost_item()
|
||||||
|
cost.load_cost_item_types(cost_item)
|
||||||
|
|
||||||
|
|
||||||
|
def assign_cost_item_quantity(ifc, cost, cost_item, related_object_type, prop_name):
|
||||||
|
products = cost.get_products(related_object_type)
|
||||||
|
if products:
|
||||||
|
ifc.run("cost.assign_cost_item_quantity", cost_item=cost_item, products=products, prop_name=prop_name)
|
||||||
|
cost.load_cost_item_quantities(cost_item)
|
||||||
|
|
||||||
|
|
||||||
|
def load_cost_item_quantities(cost):
|
||||||
|
cost_item = cost.get_highlighted_cost_item()
|
||||||
|
cost.load_cost_item_quantities(cost_item)
|
||||||
|
|
||||||
|
|
||||||
|
def assign_cost_value(ifc, cost_item, cost_rate):
|
||||||
|
ifc.run("cost.assign_cost_value", cost_item=cost_item, cost_rate=cost_rate)
|
||||||
|
|
||||||
|
def load_schedule_of_rates(cost, schedule_of_rates):
|
||||||
|
cost.load_schedule_of_rates(schedule_of_rates)
|
||||||
|
|
||||||
|
def unassign_cost_item_quantity(ifc, cost, cost_item, products):
|
||||||
|
ifc.run("cost.unassign_cost_item_quantity", cost_item=cost_item, products=products)
|
||||||
|
cost.load_cost_item_quantities(cost_item)
|
||||||
|
|
||||||
|
def enable_editing_cost_item_quantities(cost, cost_item):
|
||||||
|
cost.enable_editing_cost_item_quantities(cost_item)
|
||||||
|
|
||||||
|
def enable_editing_cost_item_values(cost, cost_item):
|
||||||
|
cost.enable_editing_cost_item_values(cost_item)
|
||||||
|
|
||||||
|
def add_cost_item_quantity(ifc, cost_item, ifc_class):
|
||||||
|
ifc.run("cost.add_cost_item_quantity", cost_item=cost_item, ifc_class=ifc_class)
|
||||||
|
|
||||||
|
def remove_cost_item_quantity(ifc, cost_item, physical_quantity):
|
||||||
|
ifc.run("cost.remove_cost_item_quantity", cost_item=cost_item, physical_quantity=physical_quantity)
|
||||||
|
|
||||||
|
def enable_editing_cost_item_quantity(cost, physical_quantity):
|
||||||
|
cost.load_cost_item_quantity_attributes(physical_quantity)
|
||||||
|
cost.enable_editing_cost_item_quantity(physical_quantity)
|
||||||
|
|
||||||
|
def disable_editing_cost_item_quantity(cost):
|
||||||
|
cost.disable_editing_cost_item_quantity()
|
||||||
|
|
||||||
|
def edit_cost_item_quantity(ifc, cost, physical_quantity):
|
||||||
|
attributes = cost.get_cost_item_quantity_attributes()
|
||||||
|
ifc.run("cost.edit_cost_item_quantity", physical_quantity=physical_quantity, attributes=attributes)
|
||||||
|
cost.disable_editing_cost_item_quantity()
|
||||||
|
# cost.load_cost_item_quantities(cost.get_active_cost_item())
|
||||||
|
|
||||||
|
def add_cost_value(ifc, cost, parent, cost_type, cost_category):
|
||||||
|
value = ifc.run("cost.add_cost_value", parent=parent)
|
||||||
|
ifc.run(
|
||||||
|
"cost.edit_cost_value",
|
||||||
|
cost_value=value,
|
||||||
|
attributes=cost.get_attributes_for_cost_value(cost_type, cost_category))
|
||||||
|
|
||||||
|
def remove_cost_value(ifc, parent, cost_value):
|
||||||
|
ifc.run("cost.remove_cost_value", parent=parent, cost_value=cost_value)
|
||||||
|
|
||||||
|
def enable_editing_cost_item_value(cost, cost_value):
|
||||||
|
cost.load_cost_item_value_attributes(cost_value)
|
||||||
|
cost.enable_editing_cost_item_value(cost_value)
|
||||||
|
|
||||||
|
def disable_editing_cost_item_value(cost):
|
||||||
|
cost.disable_editing_cost_item_value()
|
||||||
|
|
||||||
|
def enable_editing_cost_item_value_formula(cost, cost_value):
|
||||||
|
cost.load_cost_item_value_formula_attributes(cost_value)
|
||||||
|
cost.enable_editing_cost_item_value_formula(cost_value)
|
||||||
|
|
||||||
|
def edit_cost_item_value_formula(ifc, cost, cost_value):
|
||||||
|
formula = cost.get_cost_item_value_formula()
|
||||||
|
ifc.run("cost.edit_cost_value_formula", cost_value=cost_value, formula=formula)
|
||||||
|
cost.disable_editing_cost_item_value()
|
||||||
|
|
||||||
|
def edit_cost_value(ifc, cost, cost_value):
|
||||||
|
attributes = cost.get_cost_value_attributes()
|
||||||
|
ifc.run("cost.edit_cost_value", cost_value=cost_value, attributes=attributes)
|
||||||
|
cost.disable_editing_cost_item_value()
|
||||||
|
#cost.load_cost_item_values(cost.get_active_cost_item())
|
||||||
|
|
||||||
|
def copy_cost_item_values(ifc, cost, source, destination):
|
||||||
|
ifc.run("cost.copy_cost_item_values", source=source, destination=destination)
|
||||||
|
|
||||||
|
def select_cost_item_products(cost, spatial, cost_item, include_nested):
|
||||||
|
products = cost.get_cost_item_products(cost_item, include_nested)
|
||||||
|
spatial.select_products(products)
|
||||||
|
|
||||||
|
def select_cost_schedule_products(cost, spatial, cost_schedule):
|
||||||
|
products = cost.get_cost_schedule_products(cost_schedule)
|
||||||
|
spatial.select_products(products)
|
||||||
|
|
||||||
|
def import_cost_schedule_csv(cost, file_path, is_schedule_of_rates):
|
||||||
|
cost.import_cost_schedule_csv(file_path, is_schedule_of_rates)
|
||||||
|
|
||||||
|
def add_cost_column(cost, name):
|
||||||
|
cost.add_cost_column(name)
|
||||||
|
|
||||||
|
def remove_cost_column(cost, name):
|
||||||
|
cost.remove_cost_column(name)
|
||||||
|
|
||||||
|
def expand_cost_item_rate(cost, cost_item):
|
||||||
|
cost.expand_cost_item_rate(cost_item)
|
||||||
|
|
||||||
|
def contract_cost_item_rate(cost, cost_item):
|
||||||
|
cost.contract_cost_item_rate(cost_item)
|
||||||
|
|
||||||
|
def calculate_cost_item_resource_value(ifc, cost_item):
|
||||||
|
ifc.run("cost.calculate_cost_item_resource_value", cost_item=cost_item)
|
||||||
@@ -127,23 +127,57 @@ class Context:
|
|||||||
|
|
||||||
@interface
|
@interface
|
||||||
class Cost:
|
class Cost:
|
||||||
|
def add_cost_column(cls, name): pass
|
||||||
def clean_up_cost_item_tree(cls, cost_item): pass
|
def clean_up_cost_item_tree(cls, cost_item): pass
|
||||||
|
def contract_cost_item_rate(cls, cost_item): pass
|
||||||
def contract_cost_item(cls, cost_item): pass
|
def contract_cost_item(cls, cost_item): pass
|
||||||
def contract_cost_items(cls): pass
|
def contract_cost_items(cls): pass
|
||||||
def create_new_cost_item_li(cls, props, cost_item, level_index): pass
|
def create_new_cost_item_li(props_collection, cost_item, level_index, type): pass
|
||||||
|
def disable_editing_cost_item_quantity(cls): pass
|
||||||
|
def disable_editing_cost_item_value(cls): pass
|
||||||
def disable_editing_cost_item(cls): pass
|
def disable_editing_cost_item(cls): pass
|
||||||
def disable_editing_cost_schedule(cls): pass
|
def disable_editing_cost_schedule(cls): pass
|
||||||
def enable_editing_cost_item_attributes(cls, cost_item): pass
|
def enable_editing_cost_item_attributes(cls, cost_item): pass
|
||||||
|
def enable_editing_cost_item_quantities(cls, cost_item): pass
|
||||||
|
def enable_editing_cost_item_quantity(cls, physical_quantity): pass
|
||||||
|
def enable_editing_cost_item_value_formula(cls, cost_value): pass
|
||||||
|
def enable_editing_cost_item_value(cls, cost_value): pass
|
||||||
|
def enable_editing_cost_item_values(cls, cost_item): pass
|
||||||
def enable_editing_cost_items(cls, cost_schedule): pass
|
def enable_editing_cost_items(cls, cost_schedule): pass
|
||||||
def enable_editing_cost_schedule_attributes(cls, cost_schedule): pass
|
def enable_editing_cost_schedule_attributes(cls, cost_schedule): pass
|
||||||
|
def expand_cost_item_rate(cls, cost_item): pass
|
||||||
def expand_cost_item(cls, cost_item): pass
|
def expand_cost_item(cls, cost_item): pass
|
||||||
def expand_cost_items(cls): pass
|
def expand_cost_items(cls): pass
|
||||||
def get_active_cost_item(cls): pass
|
def get_active_cost_item(cls): pass
|
||||||
|
def get_all_nested_cost_items(cls, cost_item): pass
|
||||||
def get_cost_item_attributes(cls, cost_item): pass
|
def get_cost_item_attributes(cls, cost_item): pass
|
||||||
|
def get_cost_item_products(cls): pass
|
||||||
|
def get_cost_item_quantity_attributes(cls): pass
|
||||||
|
def get_cost_item_value_formula(cls): pass
|
||||||
def get_cost_schedule_attributes(cls): pass
|
def get_cost_schedule_attributes(cls): pass
|
||||||
def load_cost_items(cls): pass
|
def get_cost_schedule_products(cls, cost_schedule): pass
|
||||||
|
def get_attributes_for_cost_value(cls, cost_type, cost_category): pass
|
||||||
|
def get_cost_value_attributes(cls): pass
|
||||||
|
def get_cost_value_unit_component(cls): pass
|
||||||
|
def get_direct_cost_item_products(cls): pass
|
||||||
|
def get_highlighted_cost_item(cls): pass
|
||||||
|
def get_nested_cost_items(cls, cost_item): pass
|
||||||
|
def get_products(cls, related_object_type): pass
|
||||||
|
def get_root_cost_items(cls, cost_schedule): pass
|
||||||
|
def get_schedule_cost_items(cls, cost_schedule): pass
|
||||||
|
def import_cost_schedule_csv(cls, file_path, is_schedule_of_rates): pass
|
||||||
|
def is_active_schedule_of_rates(cls): pass
|
||||||
def load_cost_item_attributes(cls): pass
|
def load_cost_item_attributes(cls): pass
|
||||||
|
def load_cost_item_quantities(cls, cost_item): pass
|
||||||
|
def load_cost_item_quantity_attributes(cls, physical_quantity): pass
|
||||||
|
def load_cost_item_types(cls, cost_item): pass
|
||||||
|
def load_cost_item_value_attributes(cls, cost_value): pass
|
||||||
|
def load_cost_item_value_formula_attributes(cls, cost_value): pass
|
||||||
|
def load_cost_schedule_tree(cls): pass
|
||||||
|
def load_schedule_of_rates_tree(cls, schedule_of_rates): pass
|
||||||
def play_chaching_sound(cls): pass
|
def play_chaching_sound(cls): pass
|
||||||
|
def print_all_cost_items(cls, cost_schedule): pass
|
||||||
|
def remove_cost_column(cls, name): pass
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
class Debug:
|
class Debug:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
import bpy
|
import bpy
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
import ifcopenshell.util.date
|
import ifcopenshell.util.date
|
||||||
|
import ifcopenshell.util.cost
|
||||||
import blenderbim.bim.helper
|
import blenderbim.bim.helper
|
||||||
import json
|
import json
|
||||||
|
|
||||||
@@ -15,22 +16,34 @@ class Cost(blenderbim.core.tool.Cost):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def disable_editing_cost_schedule(cls):
|
def disable_editing_cost_schedule(cls):
|
||||||
bpy.context.scene.BIMCostProperties.active_cost_schedule_id = 0
|
bpy.context.scene.BIMCostProperties.active_cost_schedule_id = 0
|
||||||
|
cls.disable_editing_cost_item()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_cost_schedule_attributes(cls, cost_schedule):
|
def enable_editing_cost_schedule_attributes(cls, cost_schedule):
|
||||||
def special_import(name, prop, data):
|
|
||||||
if name in ["SubmittedOn", "UpdateDate"]:
|
|
||||||
prop.string_value = "" if prop.is_null else ifcopenshell.util.date.ifc2datetime(data[name]).isoformat()
|
|
||||||
return True
|
|
||||||
|
|
||||||
bpy.context.scene.BIMCostProperties.active_cost_schedule_id = cost_schedule.id()
|
bpy.context.scene.BIMCostProperties.active_cost_schedule_id = cost_schedule.id()
|
||||||
bpy.context.scene.BIMCostProperties.is_editing = "COST_SCHEDULE_ATTRIBUTES"
|
bpy.context.scene.BIMCostProperties.is_editing = "COST_SCHEDULE_ATTRIBUTES"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_cost_schedule_attributes(cls, cost_schedule):
|
def load_cost_schedule_attributes(cls, cost_schedule):
|
||||||
|
def special_import(name, prop, data):
|
||||||
|
if name in ["SubmittedOn", "UpdateDate"]:
|
||||||
|
prop.string_value = "" if prop.is_null else ifcopenshell.util.date.ifc2datetime(data[name]).isoformat()
|
||||||
|
return True
|
||||||
|
|
||||||
props = bpy.context.scene.BIMCostProperties
|
props = bpy.context.scene.BIMCostProperties
|
||||||
props.cost_schedule_attributes.clear()
|
props.cost_schedule_attributes.clear()
|
||||||
blenderbim.bim.helper.import_attributes(cost_schedule, props.cost_schedule_attributes)
|
blenderbim.bim.helper.import_attributes2(cost_schedule, props.cost_schedule_attributes, callback=special_import)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_cost_items(cls, cost_schedule):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.active_cost_schedule_id = cost_schedule.id()
|
||||||
|
props.is_editing = "COST_ITEMS"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def play_sound(cls):
|
||||||
|
if bpy.context.preferences.addons["blenderbim"].preferences.should_play_chaching_sound:
|
||||||
|
cls.play_chaching_sound() # lol
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def play_chaching_sound(cls):
|
def play_chaching_sound(cls):
|
||||||
@@ -50,55 +63,33 @@ class Cost(blenderbim.core.tool.Cost):
|
|||||||
pass # ah well
|
pass # ah well
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_cost_items(cls, cost_schedule):
|
def load_cost_schedule_tree(cls):
|
||||||
props = bpy.context.scene.BIMCostProperties
|
props = bpy.context.scene.BIMCostProperties
|
||||||
props.is_cost_update_enabled = False
|
props.is_cost_update_enabled = False
|
||||||
props.active_cost_schedule_id = cost_schedule.id()
|
|
||||||
props.is_editing = "COST_ITEMS"
|
|
||||||
props.is_cost_update_enabled = True
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def play_chaching_sound(cls):
|
|
||||||
if bpy.context.preferences.addons["blenderbim"].preferences.should_play_chaching_sound:
|
|
||||||
cls.play_chaching_sound() # lol
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def load_cost_items(cls):
|
|
||||||
props = bpy.context.scene.BIMCostProperties
|
|
||||||
cost_schedule = tool.Ifc.get().by_id(props.active_cost_schedule_id)
|
cost_schedule = tool.Ifc.get().by_id(props.active_cost_schedule_id)
|
||||||
props.cost_items.clear()
|
props.cost_items.clear()
|
||||||
if not hasattr(cls, "contracted_cost_items"):
|
if not hasattr(cls, "contracted_cost_items"):
|
||||||
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
||||||
for rel in cost_schedule.Controls or []:
|
[
|
||||||
for cost_item in rel.RelatedObjects:
|
cls.create_new_cost_item_li(props.cost_items, cost_item, 0, type="cost")
|
||||||
cls.create_new_cost_item_li(props, cost_item, 0)
|
for rel in cost_schedule.Controls or []
|
||||||
|
for cost_item in rel.RelatedObjects or []
|
||||||
@classmethod
|
]
|
||||||
def create_new_cost_item_li(cls, props, cost_item, level_index):
|
props.is_cost_update_enabled = True
|
||||||
new = props.cost_items.add()
|
|
||||||
new.ifc_definition_id = cost_item.id()
|
|
||||||
new.name = cost_item.Name or "Unnamed"
|
|
||||||
new.identification = cost_item.Identification or "XXX"
|
|
||||||
new.is_expanded = cost_item.id() not in cls.contracted_cost_items
|
|
||||||
new.level_index = level_index
|
|
||||||
if cost_item.IsNestedBy:
|
|
||||||
new.has_children = True
|
|
||||||
if new.is_expanded:
|
|
||||||
for rel in cost_item.IsNestedBy:
|
|
||||||
for sub_cost_item in rel.RelatedObjects:
|
|
||||||
cls.create_new_cost_item_li(props, sub_cost_item, level_index + 1)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def expand_cost_item(cls, cost_item):
|
def expand_cost_item(cls, cost_item):
|
||||||
props = bpy.context.scene.BIMCostProperties
|
props = bpy.context.scene.BIMCostProperties
|
||||||
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
if not hasattr(cls, "contracted_cost_items"):
|
||||||
|
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
||||||
cls.contracted_cost_items.remove(cost_item.id())
|
cls.contracted_cost_items.remove(cost_item.id())
|
||||||
props.contracted_cost_items = json.dumps(cls.contracted_cost_items)
|
props.contracted_cost_items = json.dumps(cls.contracted_cost_items)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def expand_cost_items(cls):
|
def expand_cost_items(cls):
|
||||||
props = bpy.context.scene.BIMCostProperties
|
props = bpy.context.scene.BIMCostProperties
|
||||||
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
if not hasattr(cls, "contracted_cost_items"):
|
||||||
|
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
||||||
for cost_item in props.cost_items:
|
for cost_item in props.cost_items:
|
||||||
if cost_item.ifc_definition_id in cls.contracted_cost_items:
|
if cost_item.ifc_definition_id in cls.contracted_cost_items:
|
||||||
cls.contracted_cost_items.remove(cost_item.ifc_definition_id)
|
cls.contracted_cost_items.remove(cost_item.ifc_definition_id)
|
||||||
@@ -107,14 +98,16 @@ class Cost(blenderbim.core.tool.Cost):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def contract_cost_item(cls, cost_item):
|
def contract_cost_item(cls, cost_item):
|
||||||
props = bpy.context.scene.BIMCostProperties
|
props = bpy.context.scene.BIMCostProperties
|
||||||
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
if not hasattr(cls, "contracted_cost_items"):
|
||||||
|
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
||||||
cls.contracted_cost_items.append(cost_item.id())
|
cls.contracted_cost_items.append(cost_item.id())
|
||||||
props.contracted_cost_items = json.dumps(cls.contracted_cost_items)
|
props.contracted_cost_items = json.dumps(cls.contracted_cost_items)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def contract_cost_items(cls):
|
def contract_cost_items(cls):
|
||||||
props = bpy.context.scene.BIMCostProperties
|
props = bpy.context.scene.BIMCostProperties
|
||||||
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
if not hasattr(cls, "contracted_cost_items"):
|
||||||
|
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
||||||
for cost_item in props.cost_items:
|
for cost_item in props.cost_items:
|
||||||
if cost_item.ifc_definition_id not in cls.contracted_cost_items:
|
if cost_item.ifc_definition_id not in cls.contracted_cost_items:
|
||||||
cls.contracted_cost_items.append(cost_item.ifc_definition_id)
|
cls.contracted_cost_items.append(cost_item.ifc_definition_id)
|
||||||
@@ -123,13 +116,14 @@ class Cost(blenderbim.core.tool.Cost):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def clean_up_cost_item_tree(cls, cost_item):
|
def clean_up_cost_item_tree(cls, cost_item):
|
||||||
props = bpy.context.scene.BIMCostProperties
|
props = bpy.context.scene.BIMCostProperties
|
||||||
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
if not hasattr(cls, "contracted_cost_items"):
|
||||||
|
cls.contracted_cost_items = json.loads(props.contracted_cost_items)
|
||||||
|
if props.active_cost_item_id == cost_item.id():
|
||||||
|
props.active_cost_item_id = 0
|
||||||
if props.active_cost_item_index in cls.contracted_cost_items:
|
if props.active_cost_item_index in cls.contracted_cost_items:
|
||||||
cls.contracted_cost_items.remove(props.active_cost_item_index)
|
cls.contracted_cost_items.remove(props.active_cost_item_index)
|
||||||
props.contracted_cost_items = json.dumps(cls.contracted_cost_items)
|
props.contracted_cost_items = json.dumps(cls.contracted_cost_items)
|
||||||
bpy.ops.bim.enable_editing_cost_items(cost_schedule=props.active_cost_schedule_id)
|
bpy.ops.bim.enable_editing_cost_items(cost_schedule=props.active_cost_schedule_id)
|
||||||
if props.active_cost_item_id == cost_item.id():
|
|
||||||
props.active_cost_item_id = 0
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_cost_item_attributes(cls, cost_item):
|
def enable_editing_cost_item_attributes(cls, cost_item):
|
||||||
@@ -153,6 +147,382 @@ class Cost(blenderbim.core.tool.Cost):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_active_cost_item(cls):
|
def get_active_cost_item(cls):
|
||||||
if bpy.context.scene.BIMCostProperties.active_cost_item_id == 0:
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
if props.active_cost_item_id == 0:
|
||||||
return None
|
return None
|
||||||
return tool.Ifc.get().by_id(bpy.context.scene.BIMCostProperties.active_cost_item_id)
|
return tool.Ifc.get().by_id(bpy.context.scene.BIMCostProperties.active_cost_item_id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_highlighted_cost_item(cls):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
if props.active_cost_item_index < len(props.cost_items):
|
||||||
|
return tool.Ifc.get().by_id(props.cost_items[props.active_cost_item_index].ifc_definition_id)
|
||||||
|
return None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_cost_item_types(cls, cost_item=None):
|
||||||
|
if not cost_item:
|
||||||
|
return
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.cost_item_type_products.clear()
|
||||||
|
# TODO implement process and resource types
|
||||||
|
# props.cost_item_processes.clear()
|
||||||
|
# props.cost_item_resources.clear()
|
||||||
|
for rel in cost_item.Controls or []:
|
||||||
|
for related_object in rel.RelatedObjects:
|
||||||
|
if related_object.is_a("IfcTypeProduct"):
|
||||||
|
new = props.cost_item_type_products.add()
|
||||||
|
# TODO implement process and resource types
|
||||||
|
# elif related_object.is_a("IfcProcess"):
|
||||||
|
# new = props.cost_item_processes.add()
|
||||||
|
# elif related_object.is_a("IfcResource"):
|
||||||
|
# new = props.cost_item_resources.add()
|
||||||
|
new.ifc_definition_id = related_object.id()
|
||||||
|
new.name = related_object.Name or "Unnamed"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_cost_item_quantities(cls, cost_item=None):
|
||||||
|
if not cost_item:
|
||||||
|
cost_item = cls.get_active_cost_item()
|
||||||
|
if not cost_item:
|
||||||
|
return
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.cost_item_products.clear()
|
||||||
|
props.cost_item_processes.clear()
|
||||||
|
props.cost_item_resources.clear()
|
||||||
|
|
||||||
|
# for control_id, quantity_ids in cost_item.Controls.items() or {}:
|
||||||
|
for rel in cost_item.Controls or []:
|
||||||
|
# control_id, quantity_ids
|
||||||
|
for related_object in rel.RelatedObjects:
|
||||||
|
if related_object.is_a("IfcProduct"):
|
||||||
|
new = props.cost_item_products.add()
|
||||||
|
elif related_object.is_a("IfcProcess"):
|
||||||
|
new = props.cost_item_processes.add()
|
||||||
|
elif related_object.is_a("IfcResource"):
|
||||||
|
new = props.cost_item_resources.add()
|
||||||
|
new.ifc_definition_id = related_object.id()
|
||||||
|
new.name = related_object.Name or "Unnamed"
|
||||||
|
total_quantity = 0
|
||||||
|
qtos = ifcopenshell.util.element.get_psets(related_object, qtos_only=True)
|
||||||
|
for qset_name, quantities in qtos.items():
|
||||||
|
qto = tool.Ifc.get().by_id(quantities["id"])
|
||||||
|
for quantity in qto.Quantities:
|
||||||
|
if quantity in cost_item.CostQuantities:
|
||||||
|
total_quantity += quantity[3]
|
||||||
|
new.total_quantity = total_quantity
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_products(cls, related_object_type=None):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
if related_object_type == "PRODUCT":
|
||||||
|
products = tool.Spatial.get_selected_products()
|
||||||
|
elif related_object_type == "PROCESS":
|
||||||
|
products = [tool.Sequence.get_highlighted_task()]
|
||||||
|
elif related_object_type == "RESOURCE":
|
||||||
|
products = [tool.Resource.get_highlighted_resource()]
|
||||||
|
return products or []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_cost_item_quantities(cls, cost_item=None):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.active_cost_item_id = cost_item.id()
|
||||||
|
props.cost_item_editing_type = "QUANTITIES"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_cost_item_quantity(cls, physical_quantity=None):
|
||||||
|
bpy.context.scene.BIMCostProperties.active_cost_item_quantity_id = physical_quantity.id()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_cost_item_quantity_attributes(cls, physical_quantity=None):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.quantity_attributes.clear()
|
||||||
|
blenderbim.bim.helper.import_attributes2(physical_quantity, props.quantity_attributes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_cost_item_values(cls, cost_item=None):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.active_cost_item_id = cost_item.id()
|
||||||
|
props.cost_item_editing_type = "VALUES"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def disable_editing_cost_item_quantity(cls):
|
||||||
|
bpy.context.scene.BIMCostProperties.active_cost_item_quantity_id = 0
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cost_item_quantity_attributes(cls):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
return blenderbim.bim.helper.export_attributes(props.quantity_attributes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_attributes_for_cost_value(cls, cost_type, cost_category):
|
||||||
|
if cost_type == "FIXED":
|
||||||
|
category = None
|
||||||
|
attributes = {"AppliedValue": 0.0}
|
||||||
|
elif cost_type == "SUM":
|
||||||
|
category = "*"
|
||||||
|
attributes = {"Category": category}
|
||||||
|
elif cost_type == "CATEGORY":
|
||||||
|
category = cost_category
|
||||||
|
attributes = {"Category": category}
|
||||||
|
return attributes
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_cost_item_value_attributes(cls, cost_value=None):
|
||||||
|
def import_attributes(name, prop, data, cost_value, is_rates, props_collection):
|
||||||
|
if name == "AppliedValue":
|
||||||
|
# TODO: for now, only support simple IfcValues (which are effectively IfcMonetaryMeasure)
|
||||||
|
prop = props_collection.add()
|
||||||
|
prop.data_type = "float"
|
||||||
|
prop.name = "AppliedValue"
|
||||||
|
prop.is_optional = True
|
||||||
|
prop.float_value = (
|
||||||
|
0.0
|
||||||
|
if prop.is_null
|
||||||
|
else ifcopenshell.util.cost.calculate_applied_value(
|
||||||
|
tool.Ifc.get().by_id(props.active_cost_item_id), cost_value
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
if name == "UnitBasis" and is_rates:
|
||||||
|
prop = props_collection.add()
|
||||||
|
prop.name = "UnitBasisValue"
|
||||||
|
prop.data_type = "float"
|
||||||
|
prop.is_null = data["UnitBasis"] is None
|
||||||
|
prop.is_optional = True
|
||||||
|
if data["UnitBasis"] and data["UnitBasis"].ValueComponent:
|
||||||
|
prop.float_value = data["UnitBasis"].ValueComponent.wrappedValue or 0
|
||||||
|
else:
|
||||||
|
prop.float_value = 0
|
||||||
|
|
||||||
|
prop = props_collection.add()
|
||||||
|
prop.name = "UnitBasisUnit"
|
||||||
|
prop.data_type = "enum"
|
||||||
|
prop.is_null = prop.is_optional = False
|
||||||
|
units = {}
|
||||||
|
|
||||||
|
def format_unit(unit):
|
||||||
|
if unit.is_a("IfcContextDependentUnit"):
|
||||||
|
return f"{unit.UnitType} / {unit.Name}"
|
||||||
|
else:
|
||||||
|
name = unit.Name
|
||||||
|
if unit.get_info().get("Prefix", None):
|
||||||
|
name = f"{unit.Prefix} {name}"
|
||||||
|
return f"{unit.UnitType} / {name}"
|
||||||
|
|
||||||
|
for unit in tool.Ifc.get().by_type("IfcNamedUnit"):
|
||||||
|
if unit.get_info().get("UnitType", None) in [
|
||||||
|
"AREAUNIT",
|
||||||
|
"LENGTHUNIT",
|
||||||
|
"TIMEUNIT",
|
||||||
|
"VOLUMEUNIT",
|
||||||
|
"MASSUNIT",
|
||||||
|
"USERDEFINED",
|
||||||
|
]:
|
||||||
|
units[unit.id()] = format_unit(unit)
|
||||||
|
prop.enum_items = json.dumps(units)
|
||||||
|
if data["UnitBasis"] and data["UnitBasis"].UnitComponent:
|
||||||
|
# prop.enum_value = prop.enum_items[data["UnitBasis"].UnitComponent.id()]
|
||||||
|
print(prop.enum_items)
|
||||||
|
for key, value in json.loads(prop.enum_items).items():
|
||||||
|
if value == format_unit(data["UnitBasis"].UnitComponent):
|
||||||
|
prop.enum_value = key
|
||||||
|
break
|
||||||
|
return True
|
||||||
|
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.cost_value_attributes.clear()
|
||||||
|
is_rates = cls.is_active_schedule_of_rates()
|
||||||
|
callback = lambda name, prop, data: import_attributes(
|
||||||
|
name, prop, data, cost_value, is_rates, props.cost_value_attributes
|
||||||
|
)
|
||||||
|
blenderbim.bim.helper.import_attributes2(cost_value, props.cost_value_attributes, callback=callback)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_active_schedule_of_rates(cls):
|
||||||
|
return (
|
||||||
|
tool.Ifc.get().by_id(bpy.context.scene.BIMCostProperties.active_cost_schedule_id).PredefinedType
|
||||||
|
== "SCHEDULEOFRATES"
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_cost_item_value(cls, cost_value=None):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.active_cost_value_id = cost_value.id()
|
||||||
|
props.cost_value_editing_type = "ATTRIBUTES"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def disable_editing_cost_item_value(cls):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.active_cost_value_id = 0
|
||||||
|
props.cost_value_editing_type = ""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_cost_item_value_formula_attributes(cls, cost_value=None):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.cost_value_attributes.clear() # why is this necessary?
|
||||||
|
bpy.context.scene.BIMCostProperties.cost_value_formula = ifcopenshell.util.cost.serialise_cost_value(cost_value)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_cost_item_value_formula(cls, cost_value=None):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.active_cost_value_id = cost_value.id()
|
||||||
|
props.cost_value_editing_type = "FORMULA"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cost_item_value_formula(cls):
|
||||||
|
return bpy.context.scene.BIMCostProperties.cost_value_formula
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cost_value_attributes(cls):
|
||||||
|
def export_attributes(attributes, prop):
|
||||||
|
if prop.name == "UnitBasisValue":
|
||||||
|
if prop.is_null:
|
||||||
|
attributes["UnitBasis"] = None
|
||||||
|
return True
|
||||||
|
attributes["UnitBasis"] = {
|
||||||
|
"ValueComponent": prop.float_value or 1,
|
||||||
|
"UnitComponent": cls.get_cost_value_unit_component(),
|
||||||
|
}
|
||||||
|
print(attributes)
|
||||||
|
return True
|
||||||
|
if prop.name == "UnitBasisUnit":
|
||||||
|
return True
|
||||||
|
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
callback = lambda attributes, prop: export_attributes(attributes, prop)
|
||||||
|
return blenderbim.bim.helper.export_attributes(props.cost_value_attributes, callback)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cost_value_unit_component(cls):
|
||||||
|
return tool.Ifc.get().by_id(
|
||||||
|
int(bpy.context.scene.BIMCostProperties.cost_value_attributes.get("UnitBasisUnit").enum_value)
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_direct_cost_item_products(cls, cost_item):
|
||||||
|
return [related_object for r in cost_item.Controls or [] for related_object in r.RelatedObjects]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cost_item_products(cls, cost_item, include_nested=False):
|
||||||
|
if not include_nested:
|
||||||
|
return cls.get_direct_cost_item_products(cost_item)
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
product
|
||||||
|
for nested_cost_item in cls.get_all_nested_cost_items(cost_item)
|
||||||
|
for product in cls.get_direct_cost_item_products(nested_cost_item)
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_all_nested_cost_items(cls, cost_item):
|
||||||
|
for cost_item in cls.get_nested_cost_items(cost_item):
|
||||||
|
yield cost_item
|
||||||
|
yield from cls.get_all_nested_cost_items(cost_item)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_nested_cost_items(cls, cost_item):
|
||||||
|
return [obj for rel in cost_item.IsNestedBy for obj in rel.RelatedObjects]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def print_all_cost_items(cls, cost_schedule):
|
||||||
|
print(cls.get_schedule_cost_items(cost_schedule))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_schedule_cost_items(cls, cost_schedule):
|
||||||
|
for cost_item in cls.get_root_cost_items(cost_schedule):
|
||||||
|
yield cost_item
|
||||||
|
yield from cls.get_all_nested_cost_items(cost_item)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_root_cost_items(cls, cost_schedule):
|
||||||
|
return [
|
||||||
|
related_object
|
||||||
|
for rel in cost_schedule.Controls or []
|
||||||
|
for related_object in rel.RelatedObjects
|
||||||
|
if related_object.is_a("IfcCostItem")
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cost_schedule_products(cls, cost_schedule):
|
||||||
|
products = []
|
||||||
|
for cost_item in cls.get_root_cost_items(cost_schedule):
|
||||||
|
products.extend(cls.get_cost_item_products(cost_item, include_nested=True))
|
||||||
|
return products
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def import_cost_schedule_csv(cls, file_path=None, is_schedule_of_rates=False):
|
||||||
|
if not file_path:
|
||||||
|
return
|
||||||
|
from ifc5d.csv2ifc import Csv2Ifc
|
||||||
|
import time
|
||||||
|
|
||||||
|
start = time.time()
|
||||||
|
csv2ifc = Csv2Ifc()
|
||||||
|
csv2ifc.csv = file_path
|
||||||
|
csv2ifc.file = tool.Ifc.get()
|
||||||
|
csv2ifc.is_schedule_of_rates = is_schedule_of_rates
|
||||||
|
csv2ifc.execute()
|
||||||
|
print("Import finished in {:.2f} seconds".format(time.time() - start))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_cost_column(cls, name):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
new = props.columns.add()
|
||||||
|
new.name = name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def remove_cost_column(cls, name):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.columns.remove(props.columns.find(name))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def expand_cost_item_rate(cls, cost_item):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates)
|
||||||
|
contracted_cost_item_rates.remove(cost_item)
|
||||||
|
props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates)
|
||||||
|
cls.load_schedule_of_rates(schedule_of_rates=tool.Ifc.get().by_id(int(props.schedule_of_rates)))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def contract_cost_item_rate(cls, cost_item):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates)
|
||||||
|
contracted_cost_item_rates.append(cost_item)
|
||||||
|
props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates)
|
||||||
|
cls.load_schedule_of_rates(schedule_of_rates=tool.Ifc.get().by_id(int(props.schedule_of_rates)))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_new_cost_item_li(cls, props_collection, cost_item, level_index, type="cost_rate"):
|
||||||
|
new = props_collection.add()
|
||||||
|
new.ifc_definition_id = cost_item.id()
|
||||||
|
new.name = cost_item.Name or "Unnamed"
|
||||||
|
new.identification = cost_item.Identification or "XXX"
|
||||||
|
new.is_expanded = (
|
||||||
|
cost_item.id() not in cls.contracted_cost_item_rates
|
||||||
|
if type == "cost_rate"
|
||||||
|
else cost_item.id() not in cls.contracted_cost_items
|
||||||
|
)
|
||||||
|
new.level_index = level_index
|
||||||
|
if cost_item.IsNestedBy:
|
||||||
|
new.has_children = True
|
||||||
|
if new.is_expanded:
|
||||||
|
[
|
||||||
|
cls.create_new_cost_item_li(props_collection, sub_cost_item, level_index + 1, type)
|
||||||
|
for rel in cost_item.IsNestedBy
|
||||||
|
for sub_cost_item in rel.RelatedObjects
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_schedule_of_rates_tree(cls, schedule_of_rates):
|
||||||
|
props = bpy.context.scene.BIMCostProperties
|
||||||
|
props.is_cost_update_enabled = False
|
||||||
|
props.cost_item_rates.clear()
|
||||||
|
props.columns.clear()
|
||||||
|
cls.contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates)
|
||||||
|
for rel in schedule_of_rates.Controls or []:
|
||||||
|
[
|
||||||
|
cls.create_new_cost_item_li(props.cost_item_rates, cost_item, 0, type="cost_rate")
|
||||||
|
for cost_item in rel.RelatedObjects
|
||||||
|
]
|
||||||
|
props.is_cost_update_enabled = True
|
||||||
|
|||||||
Reference in New Issue
Block a user