mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 13:46:54 +00:00
Some bugfixes and package IFC COBie for alpha release
This commit is contained in:
@@ -1,11 +1,30 @@
|
|||||||
|
# This can be packaged with `pyinstaller --onefile --clean --icon=icon.ico bimtester.py`
|
||||||
|
|
||||||
|
print('# IFC COBie')
|
||||||
|
print('''
|
||||||
|
IFC COBie is free software developed under the IfcOpenShell and BlenderBIM
|
||||||
|
projects. IFC COBie will convert IFC files, ideally produced with the COBie MVD
|
||||||
|
in mind, into a spreadsheet format for inspection. To learn more, visit:
|
||||||
|
|
||||||
|
- http://ifcopenshell.org
|
||||||
|
- https://blenderbim.org
|
||||||
|
|
||||||
|
To run, a `input.ifc` file is required in the current folder.
|
||||||
|
''')
|
||||||
|
|
||||||
|
value = input('Would you like to run IFC COBie? [Y/n] ')
|
||||||
|
if value == 'n':
|
||||||
|
quit()
|
||||||
|
|
||||||
|
print('Loading libraries ...')
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import logging
|
import logging
|
||||||
import pprint
|
|
||||||
import csv
|
import csv
|
||||||
from openpyxl import Workbook
|
from xlsxwriter import Workbook
|
||||||
from openpyxl.styles import PatternFill
|
|
||||||
|
|
||||||
class IfcCobieParser():
|
class IfcCobieParser():
|
||||||
def __init__(self, logger):
|
def __init__(self, logger):
|
||||||
@@ -101,7 +120,7 @@ class IfcCobieParser():
|
|||||||
self.default_date = (datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds = -2177452801)).isoformat()
|
self.default_date = (datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds = -2177452801)).isoformat()
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
self.file = ifcopenshell.open('C:/cygwin64/home/moud308/Projects/ifc2cobie/arch.ifc')
|
self.file = ifcopenshell.open('input.ifc')
|
||||||
self.get_contacts()
|
self.get_contacts()
|
||||||
self.get_facilities()
|
self.get_facilities()
|
||||||
self.get_floors()
|
self.get_floors()
|
||||||
@@ -492,7 +511,7 @@ class IfcCobieParser():
|
|||||||
'SheetName': 'Attributes',
|
'SheetName': 'Attributes',
|
||||||
'RowName': 'n/a', # I am not sure what this mapping is meant to be
|
'RowName': 'n/a', # I am not sure what this mapping is meant to be
|
||||||
'Value': self.get_object_attribute(property, 'NominalValue', default='n/a') if property.is_a('IfcPropertySingleValue') else 'n/a',
|
'Value': self.get_object_attribute(property, 'NominalValue', default='n/a') if property.is_a('IfcPropertySingleValue') else 'n/a',
|
||||||
'Unit': '{}{}'.format(property.Unit.Prefix, property.Unit.Name) if hasattr(property, 'Unit') and property.Unit else 'n/a',
|
'Unit': '{}{}'.format(property.Unit.Prefix if hasattr(property.Unit, 'Prefix') else '', property.Unit.Name if hasattr(property.Unit, 'Name') else 'n/a') if hasattr(property, 'Unit') and property.Unit else 'n/a',
|
||||||
'ExtSystem': self.get_ext_system_from_history(attribute.OwnerHistory),
|
'ExtSystem': self.get_ext_system_from_history(attribute.OwnerHistory),
|
||||||
'ExtObject': self.get_ext_object(attribute),
|
'ExtObject': self.get_ext_object(attribute),
|
||||||
'ExtIdentifier': attribute.GlobalId,
|
'ExtIdentifier': attribute.GlobalId,
|
||||||
@@ -595,7 +614,7 @@ class IfcCobieParser():
|
|||||||
if not connection.is_a('IfcRelConnectsPorts'):
|
if not connection.is_a('IfcRelConnectsPorts'):
|
||||||
return None
|
return None
|
||||||
object = getattr(connection, key)
|
object = getattr(connection, key)
|
||||||
if self.is_object_a_component_asset(object):
|
if object and self.is_object_a_component_asset(object):
|
||||||
return object.Name
|
return object.Name
|
||||||
self.logger.error('The connected object relationship {} is not a component asset for {}'.format(key, connection))
|
self.logger.error('The connected object relationship {} is not a component asset for {}'.format(key, connection))
|
||||||
|
|
||||||
@@ -679,7 +698,8 @@ class IfcCobieParser():
|
|||||||
|
|
||||||
def get_qto_from_object(self, object, name):
|
def get_qto_from_object(self, object, name):
|
||||||
for relationship in object.IsDefinedBy:
|
for relationship in object.IsDefinedBy:
|
||||||
if relationship.RelatingPropertyDefinition.is_a('IfcQuantitySet') \
|
if relationship.is_a('IfcRelDefinesByProperties') \
|
||||||
|
and relationship.RelatingPropertyDefinition.is_a('IfcQuantitySet') \
|
||||||
and relationship.RelatingPropertyDefinition.Name == name:
|
and relationship.RelatingPropertyDefinition.Name == name:
|
||||||
return relationship.RelatingPropertyDefinition
|
return relationship.RelatingPropertyDefinition
|
||||||
self.logger.warning('The qto {} was not found for {}'.format(name, object))
|
self.logger.warning('The qto {} was not found for {}'.format(name, object))
|
||||||
@@ -838,7 +858,7 @@ class IfcCobieParser():
|
|||||||
|
|
||||||
def get_name_from_person(self, person, attribute):
|
def get_name_from_person(self, person, attribute):
|
||||||
name = getattr(person, attribute)
|
name = getattr(person, attribute)
|
||||||
if not name.isalpha():
|
if not name or not name.isalpha():
|
||||||
self.logger.warning('The person\'s {} seems to be badly formatted ("{}") for {}'.format(attribute, name, person))
|
self.logger.warning('The person\'s {} seems to be badly formatted ("{}") for {}'.format(attribute, name, person))
|
||||||
return name if name else 'n/a'
|
return name if name else 'n/a'
|
||||||
|
|
||||||
@@ -1042,7 +1062,7 @@ class CobieCsvWriter():
|
|||||||
'ExtIdentifier',])
|
'ExtIdentifier',])
|
||||||
|
|
||||||
def write_file(self, csv_name, data, primary_key, fieldnames):
|
def write_file(self, csv_name, data, primary_key, fieldnames):
|
||||||
with open('C:/cygwin64/home/moud308/Projects/ifc2cobie/{}.csv'.format(csv_name), 'w', newline='') as file:
|
with open('{}.csv'.format(csv_name), 'w', newline='', encoding='utf-8') as file:
|
||||||
writer = csv.DictWriter(file, fieldnames=fieldnames)
|
writer = csv.DictWriter(file, fieldnames=fieldnames)
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
for name, row in data.items():
|
for name, row in data.items():
|
||||||
@@ -1061,8 +1081,13 @@ class CobieXlsWriter(CobieCsvWriter):
|
|||||||
'n': '000000' # Not used
|
'n': '000000' # Not used
|
||||||
}
|
}
|
||||||
super().write()
|
super().write()
|
||||||
self.workbook = Workbook()
|
self.workbook = Workbook('output.xlsx')
|
||||||
self.workbook.remove(self.workbook.active)
|
|
||||||
|
self.cell_formats = {}
|
||||||
|
for key, value in self.colours.items():
|
||||||
|
self.cell_formats[key] = self.workbook.add_format()
|
||||||
|
self.cell_formats[key].set_bg_color(value)
|
||||||
|
|
||||||
self.write_worksheet('Contact', self.colours['r'], 'ririrreeeoooooooooo')
|
self.write_worksheet('Contact', self.colours['r'], 'ririrreeeoooooooooo')
|
||||||
self.write_worksheet('Facility', self.colours['r'], 'ririrriiiireeeeeeeoooo')
|
self.write_worksheet('Facility', self.colours['r'], 'ririrriiiireeeeeeeoooo')
|
||||||
self.write_worksheet('Floor', self.colours['r'], 'ririeeeooo')
|
self.write_worksheet('Floor', self.colours['r'], 'ririeeeooo')
|
||||||
@@ -1081,34 +1106,39 @@ class CobieXlsWriter(CobieCsvWriter):
|
|||||||
self.write_worksheet('Attribute', self.colours['r'], 'ririiirreeeoo')
|
self.write_worksheet('Attribute', self.colours['r'], 'ririiirreeeoo')
|
||||||
self.write_worksheet('Coordinate', self.colours['r'], 'ririiooooeeeooo')
|
self.write_worksheet('Coordinate', self.colours['r'], 'ririiooooeeeooo')
|
||||||
self.write_worksheet('Issue', self.colours['r'], 'ririooooooooooeee')
|
self.write_worksheet('Issue', self.colours['r'], 'ririooooooooooeee')
|
||||||
self.workbook.save(filename='C:/cygwin64/home/moud308/Projects/ifc2cobie/out.xlsx')
|
|
||||||
self.workbook.close()
|
self.workbook.close()
|
||||||
|
|
||||||
def write_worksheet(self, name, tab_colour, fill_map):
|
def write_worksheet(self, name, tab_colour, fill_map):
|
||||||
worksheet = self.workbook.create_sheet(name)
|
worksheet = self.workbook.add_worksheet(name)
|
||||||
worksheet.sheet_properties.tabColor = tab_colour
|
|
||||||
|
|
||||||
with open('C:/cygwin64/home/moud308/Projects/ifc2cobie/{}.csv'.format(name),
|
with open('{}.csv'.format(name), 'r') as f:
|
||||||
'r') as f:
|
|
||||||
reader = csv.reader(f)
|
reader = csv.reader(f)
|
||||||
for r, row in enumerate(reader):
|
for r, row in enumerate(reader):
|
||||||
for c, col in enumerate(row):
|
for c, col in enumerate(row):
|
||||||
cell = worksheet.cell(column=c+1, row=r+1, value=col)
|
|
||||||
if r == 0:
|
if r == 0:
|
||||||
cell.fill = PatternFill(fill_type='solid', fgColor=self.colours['s'])
|
cell = worksheet.write(r, c, col, self.cell_formats['s'])
|
||||||
else:
|
else:
|
||||||
cell.fill = PatternFill(fill_type='solid', fgColor=self.colours[fill_map[c]])
|
cell = worksheet.write(r, c, col, self.cell_formats[fill_map[c]])
|
||||||
|
|
||||||
|
print('Processing IFC file ...')
|
||||||
|
print('Note: view issues with your file in `process.log` ...')
|
||||||
|
|
||||||
start = time.time()
|
start = time.time()
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
filename='C:/cygwin64/home/moud308/Projects/ifc2cobie/process.log',
|
filename='process.log',
|
||||||
filemode='a', level=logging.DEBUG)
|
filemode='a', level=logging.DEBUG)
|
||||||
logger = logging.getLogger('IFCtoCOBie')
|
logger = logging.getLogger('IFCtoCOBie')
|
||||||
logger.info('Starting conversion')
|
logger.info('Starting conversion')
|
||||||
parser = IfcCobieParser(logger)
|
parser = IfcCobieParser(logger)
|
||||||
parser.parse()
|
parser.parse()
|
||||||
|
|
||||||
|
print('Generating reports ...')
|
||||||
|
|
||||||
#writer = CobieCsvWriter(parser)
|
#writer = CobieCsvWriter(parser)
|
||||||
#writer.write()
|
#writer.write()
|
||||||
writer = CobieXlsWriter(parser)
|
writer = CobieXlsWriter(parser)
|
||||||
writer.write()
|
writer.write()
|
||||||
logger.info('Finished conversion in {}s'.format(time.time() - start))
|
logger.info('Finished conversion in {}s'.format(time.time() - start))
|
||||||
|
|
||||||
|
print('# All reports are complete :-)')
|
||||||
|
input('Press <enter> to quit.')
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
Reference in New Issue
Block a user