mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
Add ability to detect data types from property set templates so that psets are easier to insert
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
PropertyType,ValueType,Name,Description,NominalValue,Unit
|
Reference,Some reference
|
||||||
IfcPropertySingleValue,IfcIdentifier,Reference,,Some reference,
|
Status,EXISTING
|
||||||
IfcPropertySingleValue,IfcLabel,Status,,EXISTING,
|
Style,Some style
|
||||||
IfcPropertySingleValue,IfcLabel,Style,,Some style,
|
NominalHeight,1.2
|
||||||
IfcPropertySingleValue,IfcPositiveLengthMeasure,NominalHeight,,1.2,
|
NominalLength,1.3
|
||||||
IfcPropertySingleValue,IfcPositiveLengthMeasure,NominalLength,,1.3,
|
NominalDepth,1.5
|
||||||
IfcPropertySingleValue,IfcPositiveLengthMeasure,NominalDepth,,1.5,
|
MainColor,Blue
|
||||||
IfcPropertySingleValue,IfcLabel,MainColor,,Blue,
|
IsBuiltIn,Uh-huh
|
||||||
IfcPropertySingleValue,IfcBoolean,IsBuiltIn,,Uh-huh,
|
|
||||||
|
|||||||
|
@@ -62,16 +62,32 @@ class QtoCalculator():
|
|||||||
volume += v1.dot(v2.cross(v3)) / 6.0
|
volume += v1.dot(v2.cross(v3)) / 6.0
|
||||||
return volume
|
return volume
|
||||||
|
|
||||||
class IfcParser():
|
class IfcSchema():
|
||||||
def __init__(self, ifc_export_settings):
|
def __init__(self):
|
||||||
self.data_dir = '/home/dion/Projects/blender-bim-ifc/data/'
|
self.schema_dir = '/home/dion/Projects/IfcOpenShell/src/ifcblenderexport/schema/'
|
||||||
self.schema_dir = '/home/dion/Projects/blender-bim-ifc/schema/'
|
self.property_file = ifcopenshell.open(self.schema_dir + 'IFC4_ADD2.ifc')
|
||||||
|
self.psets = {}
|
||||||
self.ifc_export_settings = ifc_export_settings
|
self.qtos = {}
|
||||||
|
self.load()
|
||||||
|
|
||||||
with open(self.schema_dir + 'ifc_types_IFC4.json') as f:
|
with open(self.schema_dir + 'ifc_types_IFC4.json') as f:
|
||||||
self.type_map = json.load(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.selected_products = []
|
||||||
|
|
||||||
self.product_index = 0
|
self.product_index = 0
|
||||||
@@ -228,7 +244,7 @@ class IfcParser():
|
|||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
psets.append({
|
psets.append({
|
||||||
'ifc': None,
|
'ifc': None,
|
||||||
'raw': list(csv.reader(f)),
|
'raw': { x[0]: x[1] for x in list(csv.reader(f)) },
|
||||||
'attributes': {
|
'attributes': {
|
||||||
'Name': filename.parts[-2],
|
'Name': filename.parts[-2],
|
||||||
'Description': filename.stem }
|
'Description': filename.stem }
|
||||||
@@ -446,10 +462,11 @@ class SIUnitHelper:
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
class IfcExporter():
|
class IfcExporter():
|
||||||
def __init__(self, ifc_export_settings, ifc_parser, qto_calculator):
|
def __init__(self, ifc_export_settings, ifc_schema, ifc_parser, qto_calculator):
|
||||||
self.template_file = '/home/dion/Projects/blender-bim-ifc/template.ifc'
|
self.template_file = '/home/dion/Projects/IfcOpenShell/src/ifcblenderexport/template.ifc'
|
||||||
self.output_file = '/home/dion/Projects/blender-bim-ifc/output.ifc'
|
self.output_file = '/home/dion/Projects/IfcOpenShell/src/ifcblenderexport/output.ifc'
|
||||||
self.ifc_export_settings = ifc_export_settings
|
self.ifc_export_settings = ifc_export_settings
|
||||||
|
self.ifc_schema = ifc_schema
|
||||||
self.ifc_parser = ifc_parser
|
self.ifc_parser = ifc_parser
|
||||||
self.qto_calculator = qto_calculator
|
self.qto_calculator = qto_calculator
|
||||||
|
|
||||||
@@ -498,22 +515,32 @@ class IfcExporter():
|
|||||||
|
|
||||||
def create_pset_properties(self, pset):
|
def create_pset_properties(self, pset):
|
||||||
properties = []
|
properties = []
|
||||||
headers = pset['raw'].pop(0)[2:]
|
templates = self.ifc_schema.psets[pset['attributes']['Name']]['HasPropertyTemplates']
|
||||||
for data in pset['raw']:
|
for name, data in templates.items():
|
||||||
type = data[1]
|
if name not in pset['raw']:
|
||||||
value = self.cast_to_base_type(type, data[4])
|
continue
|
||||||
nominal_value = self.file.create_entity(type, value)
|
if data.TemplateType == 'P_SINGLEVALUE':
|
||||||
attributes = { header: data[i+2] if data[i+2] else None for i, header in enumerate(headers)}
|
if data.PrimaryMeasureType:
|
||||||
attributes['NominalValue'] = nominal_value
|
value_type = data.PrimaryMeasureType
|
||||||
properties.append(self.file.create_entity(data[0], **attributes))
|
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
|
return properties
|
||||||
|
|
||||||
def cast_to_base_type(self, type, value):
|
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)
|
return float(value)
|
||||||
elif self.ifc_parser.type_map[type] == 'integer':
|
elif self.ifc_schema.type_map[type] == 'integer':
|
||||||
return int(value)
|
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 True if value.lower() in ['1', 't', 'true', 'yes', 'y', 'uh-huh'] else False
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
@@ -753,7 +780,8 @@ print('# Starting export')
|
|||||||
start = time.time()
|
start = time.time()
|
||||||
ifc_export_settings = IfcExportSettings()
|
ifc_export_settings = IfcExportSettings()
|
||||||
ifc_parser = IfcParser(ifc_export_settings)
|
ifc_parser = IfcParser(ifc_export_settings)
|
||||||
|
ifc_schema = IfcSchema()
|
||||||
qto_calculator = QtoCalculator()
|
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()
|
ifc_exporter.export()
|
||||||
print('# Export finished in {:.2f} seconds'.format(time.time() - start))
|
print('# Export finished in {:.2f} seconds'.format(time.time() - start))
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user