mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 02:47:48 +00:00
typing
This commit is contained in:
@@ -25,8 +25,6 @@ from typing import Union
|
||||
def copy_cost_item(
|
||||
file: ifcopenshell.file, cost_item: ifcopenshell.entity_instance
|
||||
) -> Union[ifcopenshell.entity_instance, list[ifcopenshell.entity_instance]]:
|
||||
# TODO: currently it never returns list of duplicated cost items
|
||||
# though it is stated in the docs
|
||||
"""Copies all cost items and related relationships
|
||||
|
||||
The following relationships are also duplicated:
|
||||
@@ -36,9 +34,7 @@ def copy_cost_item(
|
||||
* The copy will have duplicated nested cost items
|
||||
|
||||
:param cost_item: The cost item to be duplicated
|
||||
:type cost_item: ifcopenshell.entity_instance
|
||||
:return: The duplicated cost item or the list of duplicated cost items if the latter has children
|
||||
:rtype: ifcopenshell.entity_instance or list[ifcopenshell.entity_instance]
|
||||
|
||||
Example:
|
||||
.. code:: python
|
||||
@@ -53,22 +49,29 @@ def copy_cost_item(
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {"cost_item": cost_item}
|
||||
return usecase.execute()
|
||||
return usecase.execute(cost_item)
|
||||
|
||||
|
||||
class Usecase:
|
||||
def execute(self):
|
||||
self.new_cost_items = []
|
||||
return self.duplicate_cost_item(self.settings["cost_item"])
|
||||
file: ifcopenshell.file
|
||||
new_cost_items: list[ifcopenshell.entity_instance]
|
||||
|
||||
def duplicate_cost_item(self, cost_item):
|
||||
def execute(
|
||||
self, cost_item: ifcopenshell.entity_instance
|
||||
) -> Union[ifcopenshell.entity_instance, list[ifcopenshell.entity_instance]]:
|
||||
self.new_cost_items = []
|
||||
self.duplicate_cost_item(cost_item)
|
||||
return self.new_cost_items[0] if len(self.new_cost_items) == 1 else self.new_cost_items
|
||||
|
||||
def duplicate_cost_item(self, cost_item: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
new_cost_item = ifcopenshell.util.element.copy_deep(self.file, cost_item)
|
||||
self.new_cost_items.append(new_cost_item)
|
||||
self.copy_indirect_attributes(cost_item, new_cost_item)
|
||||
return new_cost_item
|
||||
|
||||
def copy_indirect_attributes(self, from_element, to_element):
|
||||
def copy_indirect_attributes(
|
||||
self, from_element: ifcopenshell.entity_instance, to_element: ifcopenshell.entity_instance
|
||||
) -> None:
|
||||
for inverse in self.file.get_inverse(from_element):
|
||||
if inverse.is_a("IfcRelDefinesByProperties"):
|
||||
inverse = ifcopenshell.util.element.copy(self.file, inverse)
|
||||
|
||||
@@ -28,11 +28,8 @@ def edit_cost_item(
|
||||
IfcCostItem, consult the IFC documentation.
|
||||
|
||||
:param cost_item: The IfcCostItem entity you want to edit
|
||||
:type cost_item: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -42,7 +39,5 @@ def edit_cost_item(
|
||||
item = ifcopenshell.api.cost.add_cost_item(model, cost_schedule=schedule)
|
||||
ifcopenshell.api.cost.edit_cost_item(model, cost_item=item, attributes={"Name": "Foo"})
|
||||
"""
|
||||
settings = {"cost_item": cost_item, "attributes": attributes or {}}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
setattr(settings["cost_item"], name, value)
|
||||
for name, value in attributes.items():
|
||||
setattr(cost_item, name, value)
|
||||
|
||||
@@ -28,11 +28,8 @@ def edit_cost_item_quantity(
|
||||
IfcPhysicalQuantity, consult the IFC documentation.
|
||||
|
||||
:param physical_quantity: The IfcPhysicalQuantity entity you want to edit
|
||||
:type physical_quantity: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -50,7 +47,5 @@ def edit_cost_item_quantity(
|
||||
ifcopenshell.api.cost.edit_cost_item_quantity(model,
|
||||
physical_quantity=quantity, "attributes": {"VolumeValue": 3.0})
|
||||
"""
|
||||
settings = {"physical_quantity": physical_quantity, "attributes": attributes or {}}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
setattr(settings["physical_quantity"], name, value)
|
||||
for name, value in attributes.items():
|
||||
setattr(physical_quantity, name, value)
|
||||
|
||||
@@ -28,11 +28,8 @@ def edit_cost_schedule(
|
||||
IfcCostSchedule, consult the IFC documentation.
|
||||
|
||||
:param cost_schedule: The IfcCostSchedule entity you want to edit
|
||||
:type cost_schedule: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -42,8 +39,5 @@ def edit_cost_schedule(
|
||||
ifcopenshell.api.cost.edit_cost_schedule(model,
|
||||
cost_schedule=schedule, attributes={"Name": "Foo"})
|
||||
"""
|
||||
|
||||
settings = {"cost_schedule": cost_schedule, "attributes": attributes or {}}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
setattr(settings["cost_schedule"], name, value)
|
||||
for name, value in attributes.items():
|
||||
setattr(cost_schedule, name, value)
|
||||
|
||||
@@ -31,11 +31,8 @@ def edit_cost_value(
|
||||
IfcCostValue, consult the IFC documentation.
|
||||
|
||||
:param cost_value: The IfcCostValue entity you want to edit
|
||||
:type cost_value: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -49,14 +46,12 @@ def edit_cost_value(
|
||||
ifcopenshell.api.cost.edit_cost_value(model, cost_value=value,
|
||||
attributes={"AppliedValue": 42.0})
|
||||
"""
|
||||
settings = {"cost_value": cost_value, "attributes": attributes or {}}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
for name, value in attributes.items():
|
||||
if name == "AppliedValue" and value is not None:
|
||||
# TODO: support all applied value select types
|
||||
value = file.createIfcMonetaryMeasure(value)
|
||||
elif name == "UnitBasis":
|
||||
old_unit_basis = settings["cost_value"].UnitBasis
|
||||
old_unit_basis = cost_value.UnitBasis
|
||||
if value:
|
||||
value_component = file.create_entity(
|
||||
ifcopenshell.util.unit.get_unit_measure_class(value["UnitComponent"].UnitType),
|
||||
@@ -65,4 +60,4 @@ def edit_cost_value(
|
||||
value = file.create_entity("IfcMeasureWithUnit", value_component, value["UnitComponent"])
|
||||
if old_unit_basis and len(file.get_inverse(old_unit_basis)) == 0:
|
||||
ifcopenshell.util.element.remove_deep(file, old_unit_basis)
|
||||
setattr(settings["cost_value"], name, value)
|
||||
setattr(cost_value, name, value)
|
||||
|
||||
@@ -30,12 +30,9 @@ def unassign_cost_item_quantity(
|
||||
have any impact on the cost item.
|
||||
|
||||
:param cost_item: The IfcCostItem to remove quantities from
|
||||
:type cost_item: ifcopenshell.entity_instance
|
||||
:param products: A list of IfcProducts that may have parametrically
|
||||
connected quantities to the cost item
|
||||
:type products: list[ifcopenshell.entity_instance]
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -69,38 +66,39 @@ def unassign_cost_item_quantity(
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {"cost_item": cost_item, "products": products or []}
|
||||
return usecase.execute()
|
||||
return usecase.execute(cost_item, products or [])
|
||||
|
||||
|
||||
class Usecase:
|
||||
def execute(self):
|
||||
self.quantities = set(self.settings["cost_item"].CostQuantities or [])
|
||||
for quantity in self.settings["cost_item"].CostQuantities or []:
|
||||
file: ifcopenshell.file
|
||||
|
||||
def execute(self, cost_item: ifcopenshell.entity_instance, products: list[ifcopenshell.entity_instance]) -> None:
|
||||
quantities = set(cost_item.CostQuantities or [])
|
||||
for quantity in cost_item.CostQuantities or []:
|
||||
for inverse in self.file.get_inverse(quantity):
|
||||
if not inverse.is_a("IfcElementQuantity"):
|
||||
continue
|
||||
for rel in inverse.DefinesOccurrence or []:
|
||||
for related_object in rel.RelatedObjects:
|
||||
if related_object in self.settings["products"]:
|
||||
self.quantities.remove(quantity)
|
||||
self.settings["cost_item"].CostQuantities = list(self.quantities)
|
||||
for product in self.settings["products"]:
|
||||
if related_object in products:
|
||||
quantities.remove(quantity)
|
||||
cost_item.CostQuantities = list(quantities)
|
||||
for product in products:
|
||||
ifcopenshell.api.control.unassign_control(
|
||||
self.file,
|
||||
related_object=product,
|
||||
relating_control=self.settings["cost_item"],
|
||||
relating_control=cost_item,
|
||||
)
|
||||
self.update_cost_item_count()
|
||||
self.update_cost_item_count(cost_item)
|
||||
|
||||
def update_cost_item_count(self):
|
||||
def update_cost_item_count(self, cost_item: ifcopenshell.entity_instance) -> None:
|
||||
# This is a bold assumption
|
||||
# https://forums.buildingsmart.org/t/how-does-a-cost-item-know-that-it-is-counting-a-controlled-product/3564
|
||||
if len(self.settings["cost_item"].CostQuantities) == 1:
|
||||
quantity = self.settings["cost_item"].CostQuantities[0]
|
||||
if len(cost_item.CostQuantities) == 1:
|
||||
quantity = cost_item.CostQuantities[0]
|
||||
if quantity.is_a("IfcQuantityCount"):
|
||||
count = 0
|
||||
for rel in self.settings["cost_item"].Controls:
|
||||
for rel in cost_item.Controls:
|
||||
count += len(rel.RelatedObjects)
|
||||
if count:
|
||||
quantity[3] = count
|
||||
|
||||
Reference in New Issue
Block a user