IFC resources utility: batch import Resource Data from CSV

This commit is contained in:
Sigma Dimensions
2022-09-05 01:51:53 +01:00
parent b44a1cb2e2
commit 36576c8d40
2 changed files with 177 additions and 0 deletions
+147
View File
@@ -0,0 +1,147 @@
# IfcResources - IFC resources utility
# Copyright (C) 2021,2022 Dion Moult <dion@thinkmoult.com>, Yassine Oualid <yassine@sigmadimensions.com>
#
# This file is part of IfcResources.
#
# IfcResources is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcResources is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcResources. If not, see <http://www.gnu.org/licenses/>.
import csv
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.unit
class Csv2Ifc:
def __init__(self):
self.csv = None
self.file = None
self.resource_items = []
self.cost_schedule = None
self.is_schedule_of_rates = False
self.units = {}
def execute(self):
self.parse_csv()
self.create_ifc()
def parse_csv(self):
self.parents = {}
self.headers = {}
with open(self.csv, "r") as csv_file:
reader = csv.reader(csv_file)
for row in reader:
if not row[0]:
continue
if row[0] == "Hierarchy":
for i, col in enumerate(row):
if not col:
continue
self.headers[col] = i
continue
cost_data = self.get_row_resource_data(row)
hierarchy_key = int(row[0])
if hierarchy_key == 1:
self.resource_items.append(cost_data)
else:
self.parents[hierarchy_key - 1]["children"].append(cost_data)
self.parents[hierarchy_key] = cost_data
def get_row_resource_data(self, row):
name = row[self.headers["Name"]]
identification = row[self.headers["Identification"]] if "Identification" in self.headers else None
type = row[self.headers["Type"]]
base_cost_value = row[self.headers["BaseCostValue"]]
base_cost_quantity = row[self.headers["BaseCostQuantity"]]
base_cost_unit = row[self.headers["QuantityUnit"]]
productivity = {
"BaseQuantityConsumed": row[self.headers["BaseQuantityConsumed"]],
"BaseQuantityProducedName": row[self.headers["BaseQuantityProducedName"]],
"BaseQuantityProducedValue": row[self.headers["BaseQuantityProducedValue"]],
}
return {
"Identification": str(identification) if identification else None,
"Name": str(name) if name else None,
"Type": type,
"BaseCostValue": float(base_cost_value) if base_cost_value else None,
"BaseCostQuantity": float(base_cost_quantity) if base_cost_quantity else None,
"Unit": str(base_cost_unit) if base_cost_unit else None,
"Productivity": productivity if productivity["BaseQuantityProducedName"] else None,
"children": [],
}
def create_ifc(self):
if not self.file:
self.create_boilerplate_ifc()
self.create_resources(self.resource_items)
def create_resources(self, resource_items, parent=None):
for resource in resource_items:
self.create_resource(resource, parent)
def create_resource(self, resource, parent):
if parent is None:
resource["ifc"] = ifcopenshell.api.run("resource.add_resource", self.file, ifc_class=resource["Type"])
else:
resource["ifc"] = ifcopenshell.api.run(
"resource.add_resource", self.file, parent_resource=parent, ifc_class=resource["Type"]
)
resource["ifc"].Name = resource["Name"]
resource["ifc"].Identification = resource["Identification"]
productivity = resource["Productivity"]
if productivity:
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=resource["ifc"], name="EPset_Productivity")
ifcopenshell.api.run(
"pset.edit_pset",
self.file,
pset=pset,
properties=productivity,
)
if resource["BaseCostValue"]:
cost_value = ifcopenshell.api.run("cost.add_cost_value", self.file, parent=resource["ifc"])
cost_value.AppliedValue = self.file.createIfcMonetaryMeasure(resource["BaseCostValue"])
if resource["Unit"]:
measure_class = ifcopenshell.util.unit.get_symbol_measure_class(resource["Unit"])
value_component = self.file.create_entity(measure_class, resource["BaseCostQuantity"])
unit_component = None
if measure_class == "IfcNumericMeasure":
unit_component = self.create_unit(resource["Unit"])
else:
unit_type = ifcopenshell.util.unit.get_measure_unit_type(measure_class)
unit_assignment = ifcopenshell.util.unit.get_unit_assignment(self.file)
if unit_assignment:
units = [u for u in unit_assignment.Units if getattr(u, "UnitType", None) == unit_type]
if units:
unit_component = units[0]
if not unit_component:
unit_component = self.create_unit(resource["Unit"])
cost_value.UnitBasis = self.file.createIfcMeasureWithUnit(value_component, unit_component)
self.create_resources(resource["children"], resource["ifc"])
def create_unit(self, symbol):
unit = self.units.get(symbol, None)
if unit:
return unit
unit = self.file.createIfcContextDependentUnit(
self.file.createIfcDimensionalExponents(0, 0, 0, 0, 0, 0, 0), "USERDEFINED", symbol
)
self.units[symbol] = unit
return unit
def create_boilerplate_ifc(self):
self.file = ifcopenshell.file(schema="IFC4")
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
ifcopenshell.api.run("unit.assign_unit", self.file)
@@ -0,0 +1,30 @@
,,,,,,,Epset_Productivity,Epset_Productivity,Epset_Productivity
Hierarchy,Identification,Name,Type,BaseCostValue,BaseCostQuantity,QuantityUnit,BaseQuantityConsumed,BaseQuantityProducedName,BaseQuantityProducedValue
1,1,Self-Production,IfcCrewResource,,,,,,
,,,,,,,,,
2,1.1, Concrete Works,IfcLaborResource,,,,,,
,,,,,,,,,
3,1.1.1,In-situ Slabs,IfcLaborResource,220,9,hour ,15,GrossArea,10
3,1.1.2,In-situ Walls,IfcLaborResource,220,9,hour ,18,GrossArea,10
3,1.1.3,In-situ Beams,IfcLaborResource,220,9,hour ,8,Length,1
3,1.1.4,In-situ Columns,IfcLaborResource,220,9,hour ,5,Count,1
3,1.1.5,Finish Concrete,IfcLaborResource,220,9,hour ,5,GrossArea,10
3,1.1.6,Drainage,IfcLaborResource,220,9,hour ,35,Length,10
3,1.1.7,Piles Trimming,IfcLaborResource,220,9,hour ,5,Count,1
3,1.1.8,Pile Caps,IfcLaborResource,220,9,hour ,10,Count,1
3,1.1.9,Waterproofing/Insulation,IfcLaborResource,220,9,hour ,5,GrossArea,10
3,1.1.10,Slabs SteelWork,IfcSubContractResource,2500,1000,m3,,GrossWeight,75
,,,,,,,,,
2,1.2,Logistics,IfcLaborResource,,,,,,
,,,,,,,,,
3,1.2.1,Equipment,IfcConstructionEquipmentResource,,,,,,
,,,,,,,,,
4,1.2.1.1,Mobile Crane,IfcConstructionEquipmentResource,,,,,,
4,1.2.1.2,TC 1,IfcConstructionEquipmentResource,,,,,,
4,1.2.1.3,TC 2,IfcConstructionEquipmentResource,,,,,,
,,,,,,,,,
3,1.2.2,Logistics Team,IfcLaborResource,,,,,,
,,,,,,,,,
4,1.2.2.1,Crane Supervisor,IfcLaborResource,,,,,,
4,1.2.2.2,Crane Driver,IfcLaborResource,,,,,,
4,1.2.2.3,Slinger/Signaller,IfcLaborResource,,,,,,
1 Epset_Productivity Epset_Productivity Epset_Productivity
2 Hierarchy Identification Name Type BaseCostValue BaseCostQuantity QuantityUnit BaseQuantityConsumed BaseQuantityProducedName BaseQuantityProducedValue
3 1 1 Self-Production IfcCrewResource
4
5 2 1.1 Concrete Works IfcLaborResource
6
7 3 1.1.1 In-situ Slabs IfcLaborResource 220 9 hour 15 GrossArea 10
8 3 1.1.2 In-situ Walls IfcLaborResource 220 9 hour 18 GrossArea 10
9 3 1.1.3 In-situ Beams IfcLaborResource 220 9 hour 8 Length 1
10 3 1.1.4 In-situ Columns IfcLaborResource 220 9 hour 5 Count 1
11 3 1.1.5 Finish Concrete IfcLaborResource 220 9 hour 5 GrossArea 10
12 3 1.1.6 Drainage IfcLaborResource 220 9 hour 35 Length 10
13 3 1.1.7 Piles Trimming IfcLaborResource 220 9 hour 5 Count 1
14 3 1.1.8 Pile Caps IfcLaborResource 220 9 hour 10 Count 1
15 3 1.1.9 Waterproofing/Insulation IfcLaborResource 220 9 hour 5 GrossArea 10
16 3 1.1.10 Slabs SteelWork IfcSubContractResource 2500 1000 m3 GrossWeight 75
17
18 2 1.2 Logistics IfcLaborResource
19
20 3 1.2.1 Equipment IfcConstructionEquipmentResource
21
22 4 1.2.1.1 Mobile Crane IfcConstructionEquipmentResource
23 4 1.2.1.2 TC 1 IfcConstructionEquipmentResource
24 4 1.2.1.3 TC 2 IfcConstructionEquipmentResource
25
26 3 1.2.2 Logistics Team IfcLaborResource
27
28 4 1.2.2.1 Crane Supervisor IfcLaborResource
29 4 1.2.2.2 Crane Driver IfcLaborResource
30 4 1.2.2.3 Slinger/Signaller IfcLaborResource