Add ability to detect data types from property set templates so that psets are easier to insert

This commit is contained in:
Dion Moult
2019-09-08 18:30:16 +10:00
parent 22bb5cc276
commit 70ec98a9e0
3 changed files with 23368 additions and 31 deletions
@@ -1,9 +1,8 @@
PropertyType,ValueType,Name,Description,NominalValue,Unit
IfcPropertySingleValue,IfcIdentifier,Reference,,Some reference,
IfcPropertySingleValue,IfcLabel,Status,,EXISTING,
IfcPropertySingleValue,IfcLabel,Style,,Some style,
IfcPropertySingleValue,IfcPositiveLengthMeasure,NominalHeight,,1.2,
IfcPropertySingleValue,IfcPositiveLengthMeasure,NominalLength,,1.3,
IfcPropertySingleValue,IfcPositiveLengthMeasure,NominalDepth,,1.5,
IfcPropertySingleValue,IfcLabel,MainColor,,Blue,
IfcPropertySingleValue,IfcBoolean,IsBuiltIn,,Uh-huh,
Reference,Some reference
Status,EXISTING
Style,Some style
NominalHeight,1.2
NominalLength,1.3
NominalDepth,1.5
MainColor,Blue
IsBuiltIn,Uh-huh
1 PropertyType Reference ValueType Some reference Name Description NominalValue Unit
2 IfcPropertySingleValue Status IfcIdentifier EXISTING Reference Some reference
3 IfcPropertySingleValue Style IfcLabel Some style Status EXISTING
4 IfcPropertySingleValue NominalHeight IfcLabel 1.2 Style Some style
5 IfcPropertySingleValue NominalLength IfcPositiveLengthMeasure 1.3 NominalHeight 1.2
6 IfcPropertySingleValue NominalDepth IfcPositiveLengthMeasure 1.5 NominalLength 1.3
7 IfcPropertySingleValue MainColor IfcPositiveLengthMeasure Blue NominalDepth 1.5
8 IfcPropertySingleValue IsBuiltIn IfcLabel Uh-huh MainColor Blue
IfcPropertySingleValue IfcBoolean IsBuiltIn Uh-huh
+50 -22
View File
@@ -62,16 +62,32 @@ class QtoCalculator():
volume += v1.dot(v2.cross(v3)) / 6.0
return volume
class IfcParser():
def __init__(self, ifc_export_settings):
self.data_dir = '/home/dion/Projects/blender-bim-ifc/data/'
self.schema_dir = '/home/dion/Projects/blender-bim-ifc/schema/'
self.ifc_export_settings = ifc_export_settings
class IfcSchema():
def __init__(self):
self.schema_dir = '/home/dion/Projects/IfcOpenShell/src/ifcblenderexport/schema/'
self.property_file = ifcopenshell.open(self.schema_dir + 'IFC4_ADD2.ifc')
self.psets = {}
self.qtos = {}
self.load()
with open(self.schema_dir + 'ifc_types_IFC4.json') as f:
self.type_map = json.load(f)
def load(self):
for property in self.property_file.by_type('IfcPropertySetTemplate'):
if property.Name[0:4] == 'Qto_':
# self.qtos.append({ })
pass
else:
self.psets[property.Name] = {
'HasPropertyTemplates': { p.Name: p for p in property.HasPropertyTemplates}}
class IfcParser():
def __init__(self, ifc_export_settings):
self.data_dir = '/home/dion/Projects/IfcOpenShell/src/ifcblenderexport/data/'
self.ifc_export_settings = ifc_export_settings
self.selected_products = []
self.product_index = 0
@@ -228,7 +244,7 @@ class IfcParser():
with open(filename, 'r') as f:
psets.append({
'ifc': None,
'raw': list(csv.reader(f)),
'raw': { x[0]: x[1] for x in list(csv.reader(f)) },
'attributes': {
'Name': filename.parts[-2],
'Description': filename.stem }
@@ -446,10 +462,11 @@ class SIUnitHelper:
return name
class IfcExporter():
def __init__(self, ifc_export_settings, ifc_parser, qto_calculator):
self.template_file = '/home/dion/Projects/blender-bim-ifc/template.ifc'
self.output_file = '/home/dion/Projects/blender-bim-ifc/output.ifc'
def __init__(self, ifc_export_settings, ifc_schema, ifc_parser, qto_calculator):
self.template_file = '/home/dion/Projects/IfcOpenShell/src/ifcblenderexport/template.ifc'
self.output_file = '/home/dion/Projects/IfcOpenShell/src/ifcblenderexport/output.ifc'
self.ifc_export_settings = ifc_export_settings
self.ifc_schema = ifc_schema
self.ifc_parser = ifc_parser
self.qto_calculator = qto_calculator
@@ -498,22 +515,32 @@ class IfcExporter():
def create_pset_properties(self, pset):
properties = []
headers = pset['raw'].pop(0)[2:]
for data in pset['raw']:
type = data[1]
value = self.cast_to_base_type(type, data[4])
nominal_value = self.file.create_entity(type, value)
attributes = { header: data[i+2] if data[i+2] else None for i, header in enumerate(headers)}
attributes['NominalValue'] = nominal_value
properties.append(self.file.create_entity(data[0], **attributes))
templates = self.ifc_schema.psets[pset['attributes']['Name']]['HasPropertyTemplates']
for name, data in templates.items():
if name not in pset['raw']:
continue
if data.TemplateType == 'P_SINGLEVALUE':
if data.PrimaryMeasureType:
value_type = data.PrimaryMeasureType
else:
# The IFC spec is missing some, so we provide a fallback
value_type = 'IfcLabel'
nominal_value = self.file.create_entity(
value_type,
self.cast_to_base_type(value_type, pset['raw'][name]))
properties.append(
self.file.create_entity('IfcPropertySingleValue', **{
'Name': name,
'NominalValue': nominal_value
}))
return properties
def cast_to_base_type(self, type, value):
if self.ifc_parser.type_map[type] == 'float':
if self.ifc_schema.type_map[type] == 'float':
return float(value)
elif self.ifc_parser.type_map[type] == 'integer':
elif self.ifc_schema.type_map[type] == 'integer':
return int(value)
elif self.ifc_parser.type_map[type] == 'bool':
elif self.ifc_schema.type_map[type] == 'bool':
return True if value.lower() in ['1', 't', 'true', 'yes', 'y', 'uh-huh'] else False
return str(value)
@@ -753,7 +780,8 @@ print('# Starting export')
start = time.time()
ifc_export_settings = IfcExportSettings()
ifc_parser = IfcParser(ifc_export_settings)
ifc_schema = IfcSchema()
qto_calculator = QtoCalculator()
ifc_exporter = IfcExporter(ifc_export_settings, ifc_parser, qto_calculator)
ifc_exporter = IfcExporter(ifc_export_settings, ifc_schema, ifc_parser, qto_calculator)
ifc_exporter.export()
print('# Export finished in {:.2f} seconds'.format(time.time() - start))
File diff suppressed because it is too large Load Diff