mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 23:36:20 +00:00
See #6570. Formula column minor improvements and documentation
This commit is contained in:
committed by
Massimo Fabbro
parent
528964ca56
commit
f0b5ab860f
@@ -0,0 +1,14 @@
|
|||||||
|
Index,Identification,Name,Unit,Value,Quantity,Query,Property,Formula
|
||||||
|
1,E.01,Walls,m3,,,,,
|
||||||
|
2,E.01.01,Ground floor walls,m3,100,,"IfcWall, location=""Ground Floor""",GrossVolume,
|
||||||
|
2,E.01.02,First floor walls,m3,200,,"IfcWall, location=""First Floor""",GrossVolume,
|
||||||
|
1,A.02,Paintings,m2,,,,,
|
||||||
|
2,A.03,Paintings with water,m2,,,,,
|
||||||
|
3,B.05,White paintings,m2,25,,IfcWall,GrossVolume,
|
||||||
|
3,B.06,Colored paintings,m2,32,33,,,
|
||||||
|
3,B.07,Double paintings,m,,,IfcWall,,NetSideArea*2
|
||||||
|
2,C-01,Paintings with machine,m2,17,133,,,
|
||||||
|
2,C-02,Decorated paintings,m2,40,8,,,
|
||||||
|
1,D,Reinforcements,,,,,,
|
||||||
|
2,D.1,Walls reinforcements weight,kg,,,IfcWall,,Pset_ConcreteElementGeneral.ReinforcementVolumeRatio * GrossVolume
|
||||||
|
2,D.2,Beams reinforcements weight,kg,,,,,
|
||||||
|
@@ -39,6 +39,7 @@ See example files as a CSV file format reference:
|
|||||||
- Ex5 - SoR_with_description.csv (a simple SoR with description column)
|
- Ex5 - SoR_with_description.csv (a simple SoR with description column)
|
||||||
- Ex6 - BoQ with categories.csv (a simple BoQ with categories columns)
|
- Ex6 - BoQ with categories.csv (a simple BoQ with categories columns)
|
||||||
- Ex7 - BoQ with Rates.csv (a simple BoQ that connect to an existing SoR. It needs an already loaded SoR.)
|
- Ex7 - BoQ with Rates.csv (a simple BoQ that connect to an existing SoR. It needs an already loaded SoR.)
|
||||||
|
- Ex8 - Boq with formula.csv (a simple BoQ with formula field used to calculate quantities when specified)
|
||||||
- `sample_cost_schedule_house_FR.csv` / `.ods`
|
- `sample_cost_schedule_house_FR.csv` / `.ods`
|
||||||
- `schedule.csv`, `rates.csv` (schedule of rates example)
|
- `schedule.csv`, `rates.csv` (schedule of rates example)
|
||||||
|
|
||||||
|
|||||||
@@ -412,16 +412,13 @@ class Csv2Ifc:
|
|||||||
results = ifcopenshell.util.selector.filter_elements(self.file, cost_item["Query"])
|
results = ifcopenshell.util.selector.filter_elements(self.file, cost_item["Query"])
|
||||||
results = [r for r in results]
|
results = [r for r in results]
|
||||||
ifc_quantity_class = ifcopenshell.util.unit.get_symbol_quantity_class(cost_item["Unit"])
|
ifc_quantity_class = ifcopenshell.util.unit.get_symbol_quantity_class(cost_item["Unit"])
|
||||||
try:
|
quantity = ifcopenshell.api.cost.assign_cost_item_quantity(
|
||||||
quantity = ifcopenshell.api.cost.assign_cost_item_quantity(
|
self.file,
|
||||||
self.file,
|
cost_item=cost_item["ifc"],
|
||||||
cost_item=cost_item["ifc"],
|
products=results,
|
||||||
products=results,
|
formula=cost_item["Formula"],
|
||||||
formula=cost_item["Formula"],
|
ifc_class=ifc_quantity_class,
|
||||||
ifc_class=ifc_quantity_class,
|
|
||||||
)
|
)
|
||||||
except:
|
|
||||||
quantity=0
|
|
||||||
|
|
||||||
self.create_cost_items(cost_item["children"], cost_item["ifc"])
|
self.create_cost_items(cost_item["children"], cost_item["ifc"])
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from typing import Any
|
|||||||
|
|
||||||
import ifcopenshell.api.control
|
import ifcopenshell.api.control
|
||||||
import ifcopenshell.api.cost
|
import ifcopenshell.api.cost
|
||||||
|
import ifcopenshell.util.element
|
||||||
|
|
||||||
|
|
||||||
def assign_cost_item_quantity(
|
def assign_cost_item_quantity(
|
||||||
@@ -142,15 +143,18 @@ class Usecase:
|
|||||||
variables_modified[v] = self.get_value_from_pset(product, v, separator)
|
variables_modified[v] = self.get_value_from_pset(product, v, separator)
|
||||||
else:
|
else:
|
||||||
variables_modified[v] = self.get_value_from_qset(product, v)
|
variables_modified[v] = self.get_value_from_qset(product, v)
|
||||||
|
if variables_modified[v] == 0:
|
||||||
|
print(f"WARNING: {product.Name} hasn't the variable {v.replace(separator, '.')}")
|
||||||
|
|
||||||
formula_modified = self.settings["formula"].replace(".", separator)
|
formula_modified = self.settings["formula"].replace(".", separator)
|
||||||
if any(v is None for v in variables_modified.values()):
|
if any(v is None for v in variables_modified.values()):
|
||||||
for k, v in variables_modified.items():
|
for k, v in variables_modified.items():
|
||||||
if v == None:
|
if v == None:
|
||||||
print(f"Property {k.replace(separator, '.')} not found")
|
print(f"Property {k.replace(separator, '.')} not found")
|
||||||
raise ValueError("Formula contains variables that are not found in properties. Please check the output")
|
print("Formula contains variables that are not found in Psets or Qsets. Please check the output")
|
||||||
|
result = 0
|
||||||
result = eval(formula_modified, {}, variables_modified)
|
else:
|
||||||
|
result = eval(formula_modified, {}, variables_modified)
|
||||||
|
|
||||||
new_quantity = None
|
new_quantity = None
|
||||||
for quantity in self.quantities:
|
for quantity in self.quantities:
|
||||||
@@ -231,26 +235,19 @@ class Usecase:
|
|||||||
v: str,
|
v: str,
|
||||||
separator: str,
|
separator: str,
|
||||||
) -> float:
|
) -> float:
|
||||||
for relationship in product.IsDefinedBy:
|
pset_name = v.split(separator)[0]
|
||||||
if relationship.is_a("IfcRelDefinesByProperties"):
|
pset = ifcopenshell.util.element.get_pset(product, pset_name)
|
||||||
pset = relationship.RelatingPropertyDefinition
|
pset_property_name = v.split(separator)[1]
|
||||||
if pset.Name == v.split(separator)[0]:
|
return (pset or {}).get(pset_property_name,0)
|
||||||
for prop in pset.HasProperties:
|
|
||||||
if prop.Name.lower() == v.split(separator)[1].lower():
|
|
||||||
return prop[2].wrappedValue
|
|
||||||
|
|
||||||
def get_value_from_qset(
|
def get_value_from_qset(
|
||||||
self,
|
self,
|
||||||
product:ifcopenshell.entity_instance,
|
product:ifcopenshell.entity_instance,
|
||||||
v: str,
|
v: str,
|
||||||
) -> float:
|
) -> float:
|
||||||
for relationship in product.IsDefinedBy:
|
qtos = ifcopenshell.util.element.get_psets(product, qtos_only = True)
|
||||||
if relationship.is_a("IfcRelDefinesByProperties"):
|
quantities = next(iter(qtos.values()), {})
|
||||||
qto = relationship.RelatingPropertyDefinition
|
return (quantities or {}).get(v,0)
|
||||||
if qto.is_a("IfcElementQuantity"):
|
|
||||||
for prop in qto.Quantities:
|
|
||||||
if prop.is_a("IfcPhysicalSimpleQuantity") and prop.Name.lower() == v.lower():
|
|
||||||
return prop[3]
|
|
||||||
|
|
||||||
class VariableExtractor(ast.NodeVisitor):
|
class VariableExtractor(ast.NodeVisitor):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user