mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
Update export_ifc.py
Fix function names, spaces, "type" shadowing improve vertices export using list comprehension Check for empty material slot
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
# -*- coding:utf-8 -*-
|
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
@@ -297,7 +295,6 @@ class IfcParser():
|
|||||||
'has_scale': obj.scale != Vector((1, 1, 1)),
|
'has_scale': obj.scale != Vector((1, 1, 1)),
|
||||||
'scale': obj.scale,
|
'scale': obj.scale,
|
||||||
'class': self.get_ifc_class(obj.name),
|
'class': self.get_ifc_class(obj.name),
|
||||||
|
|
||||||
'relating_structure': None,
|
'relating_structure': None,
|
||||||
'relating_host': None,
|
'relating_host': None,
|
||||||
'relating_qtos_key': None,
|
'relating_qtos_key': None,
|
||||||
@@ -448,9 +445,9 @@ class IfcParser():
|
|||||||
def get_window_attributes(self):
|
def get_window_attributes(self):
|
||||||
return self.get_predefined_attributes('window')
|
return self.get_predefined_attributes('window')
|
||||||
|
|
||||||
def get_predefined_attributes(self, type):
|
def get_predefined_attributes(self, attr):
|
||||||
results = {}
|
results = {}
|
||||||
for filename in Path(self.data_dir + type + '/').glob('**/*.csv'):
|
for filename in Path(self.data_dir + attr + '/').glob('**/*.csv'):
|
||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
type_name = filename.parts[-2]
|
type_name = filename.parts[-2]
|
||||||
pset_name = filename.stem
|
pset_name = filename.stem
|
||||||
@@ -659,25 +656,26 @@ class IfcParser():
|
|||||||
if obj.data is None:
|
if obj.data is None:
|
||||||
continue
|
continue
|
||||||
for slot in obj.material_slots:
|
for slot in obj.material_slots:
|
||||||
if slot.material.name in results \
|
if slot.material is None:
|
||||||
or slot.link == 'OBJECT':
|
continue
|
||||||
|
if slot.material.name in results or slot.link == 'OBJECT':
|
||||||
continue
|
continue
|
||||||
results[slot.material.name] = {
|
results[slot.material.name] = {
|
||||||
'ifc': None,
|
'ifc': None,
|
||||||
'layer_ifc': None,
|
'layer_ifc': None,
|
||||||
'constituent_ifc': None,
|
'constituent_ifc': None,
|
||||||
'raw': slot.material,
|
'raw': slot.material,
|
||||||
'is_material_layer_set': True if 'IsMaterialLayerSet' in obj.keys() else False,
|
'is_material_layer_set': 'IsMaterialLayerSet' in obj.keys(),
|
||||||
'is_material_constituent_set': True if 'IsMaterialConstituentSet' in obj.keys() else False,
|
'is_material_constituent_set': 'IsMaterialConstituentSet' in obj.keys(),
|
||||||
'attributes': {'Name': slot.material.name},
|
'attributes': {'Name': slot.material.name},
|
||||||
'layer_attributes': {
|
'layer_attributes': {
|
||||||
key[3:]: slot.material[key]
|
key[3:]: slot.material[key]
|
||||||
for key in slot.material.keys()
|
for key in slot.material.keys()
|
||||||
if key[0:3] == 'Ifc'
|
if key[0:3] == 'Ifc'
|
||||||
},
|
},
|
||||||
'constituent_attributes': {
|
'constituent_attributes': {
|
||||||
key[3:]: slot.material[key]
|
key[3:]: slot.material[key]
|
||||||
for key in slot.material.keys()
|
for key in slot.material.keys()
|
||||||
if key[0:3] == 'Ifc'
|
if key[0:3] == 'Ifc'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -689,13 +687,14 @@ class IfcParser():
|
|||||||
return results
|
return results
|
||||||
for product in self.selected_products + self.type_products:
|
for product in self.selected_products + self.type_products:
|
||||||
obj = product['raw']
|
obj = product['raw']
|
||||||
if not obj.data:
|
if obj.data is None:
|
||||||
continue
|
continue
|
||||||
for slot in obj.material_slots:
|
for slot in obj.material_slots:
|
||||||
if not self.ifc_export_settings.should_export_all_materials_as_styled_items:
|
if slot.material is None:
|
||||||
if slot.material.name in results \
|
continue
|
||||||
or slot.link == 'DATA':
|
if not self.ifc_export_settings.should_export_all_materials_as_styled_items and (
|
||||||
continue
|
slot.material.name in results or slot.link == 'DATA'):
|
||||||
|
continue
|
||||||
results.append({
|
results.append({
|
||||||
'ifc': None,
|
'ifc': None,
|
||||||
'raw': slot.material,
|
'raw': slot.material,
|
||||||
@@ -734,31 +733,31 @@ class IfcParser():
|
|||||||
if not self.is_a_type(self.get_ifc_class(obj.name)):
|
if not self.is_a_type(self.get_ifc_class(obj.name)):
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
type = {
|
type_product = {
|
||||||
'ifc': None,
|
'ifc': None,
|
||||||
'raw': obj,
|
'raw': obj,
|
||||||
'location': obj.matrix_world.translation,
|
'location': obj.matrix_world.translation,
|
||||||
'up_axis': self.get_axis(obj.matrix_world, 2),
|
'up_axis': self.get_axis(obj.matrix_world, 2),
|
||||||
'forward_axis': self.get_axis(obj.matrix_world, 0),
|
'forward_axis': self.get_axis(obj.matrix_world, 0),
|
||||||
'psets': ['{}/{}'.format(pset.name, pset.file)
|
'psets': ['{}/{}'.format(pset.name, pset.file) for pset in
|
||||||
for pset in obj.BIMObjectProperties.psets],
|
obj.BIMObjectProperties.psets],
|
||||||
'class': self.get_ifc_class(obj.name),
|
'class': self.get_ifc_class(obj.name),
|
||||||
'representations': self.get_object_representation_names(obj),
|
'representations': self.get_object_representation_names(obj),
|
||||||
'attributes': self.get_object_attributes(obj)
|
'attributes': self.get_object_attributes(obj)
|
||||||
}
|
}
|
||||||
results.append(type)
|
results.append(type_product)
|
||||||
library['rel_declares_type_products'].append(index)
|
library['rel_declares_type_products'].append(index)
|
||||||
|
|
||||||
for key in obj.keys():
|
for key in obj.keys():
|
||||||
if key[0:3] == 'Doc':
|
if key[0:3] == 'Doc':
|
||||||
self.rel_associates_document_type.setdefault(
|
self.rel_associates_document_type.setdefault(
|
||||||
obj[key], []).append(type)
|
obj[key], []).append(type_product)
|
||||||
elif key[0:5] == 'Class':
|
elif key[0:5] == 'Class':
|
||||||
self.rel_associates_classification_type.setdefault(
|
self.rel_associates_classification_type.setdefault(
|
||||||
obj[key], []).append(type)
|
obj[key], []).append(type_product)
|
||||||
elif key[0:9] == 'Objective':
|
elif key[0:9] == 'Objective':
|
||||||
self.rel_associates_constraint_objective_type.setdefault(
|
self.rel_associates_constraint_objective_type.setdefault(
|
||||||
obj[key], []).append(type)
|
obj[key], []).append(type_product)
|
||||||
|
|
||||||
index += 1
|
index += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -802,11 +801,12 @@ class IfcParser():
|
|||||||
return collection_tree
|
return collection_tree
|
||||||
|
|
||||||
def get_spatial_structure_element_reference(self, name):
|
def get_spatial_structure_element_reference(self, name):
|
||||||
return ['{}/{}'.format(e['class'], e['attributes']['Name']) for e in
|
return ['{}/{}'.format(e['class'], e['attributes']['Name'])
|
||||||
self.spatial_structure_elements].index(name)
|
for e in self.spatial_structure_elements].index(name)
|
||||||
|
|
||||||
def get_type_product_reference(self, name):
|
def get_type_product_reference(self, name):
|
||||||
return [p['attributes']['Name'] for p in self.type_products].index(self.get_ifc_name(name))
|
return [p['attributes']['Name']
|
||||||
|
for p in self.type_products].index(self.get_ifc_name(name))
|
||||||
|
|
||||||
def get_ifc_class(self, name):
|
def get_ifc_class(self, name):
|
||||||
return name.split('/')[0]
|
return name.split('/')[0]
|
||||||
@@ -876,10 +876,8 @@ class IfcExporter():
|
|||||||
self.relate_objects_to_types()
|
self.relate_objects_to_types()
|
||||||
self.relate_objects_to_qtos()
|
self.relate_objects_to_qtos()
|
||||||
self.relate_objects_to_psets()
|
self.relate_objects_to_psets()
|
||||||
|
self.relate_objects_to_opening_elements()
|
||||||
self.relate_voids_elements()
|
self.relate_opening_elements_to_fillings()
|
||||||
self.relate_fills_elements()
|
|
||||||
|
|
||||||
self.relate_objects_to_materials()
|
self.relate_objects_to_materials()
|
||||||
self.relate_objects_to_material_layer_sets()
|
self.relate_objects_to_material_layer_sets()
|
||||||
self.relate_objects_to_material_constituent_sets()
|
self.relate_objects_to_material_constituent_sets()
|
||||||
@@ -898,46 +896,57 @@ class IfcExporter():
|
|||||||
self.owner_history = self.file.by_type('IfcOwnerHistory')[0]
|
self.owner_history = self.file.by_type('IfcOwnerHistory')[0]
|
||||||
|
|
||||||
def create_units(self):
|
def create_units(self):
|
||||||
for type, data in self.ifc_parser.units.items():
|
for unit_type, data in self.ifc_parser.units.items():
|
||||||
if data['is_metric']:
|
if data['is_metric']:
|
||||||
data['ifc'] = self.create_metric_unit(type, data)
|
data['ifc'] = self.create_metric_unit(unit_type, data)
|
||||||
else:
|
else:
|
||||||
data['ifc'] = self.create_imperial_unit(type, data)
|
data['ifc'] = self.create_imperial_unit(unit_type, data)
|
||||||
self.file.createIfcUnitAssignment([u['ifc'] for u in self.ifc_parser.units.values()])
|
self.file.createIfcUnitAssignment([u['ifc'] for u in self.ifc_parser.units.values()])
|
||||||
|
|
||||||
def create_metric_unit(self, type, data):
|
def create_metric_unit(self, unit_type, data):
|
||||||
type_prefix = ''
|
type_prefix = ''
|
||||||
if type == 'area':
|
if unit_type == 'area':
|
||||||
type_prefix = 'SQUARE_'
|
type_prefix = 'SQUARE_'
|
||||||
elif type == 'volume':
|
elif unit_type == 'volume':
|
||||||
type_prefix = 'CUBIC_'
|
type_prefix = 'CUBIC_'
|
||||||
return self.file.createIfcSIUnit(None,
|
return self.file.createIfcSIUnit(
|
||||||
'{}UNIT'.format(type.upper()),
|
None,
|
||||||
SIUnitHelper.get_prefix(data['raw']),
|
'{}UNIT'.format(unit_type.upper()),
|
||||||
type_prefix + SIUnitHelper.get_unit_name(data['raw']))
|
SIUnitHelper.get_prefix(data['raw']),
|
||||||
|
type_prefix + SIUnitHelper.get_unit_name(data['raw'])
|
||||||
|
)
|
||||||
|
|
||||||
def create_imperial_unit(self, type, data):
|
def create_imperial_unit(self, unit_type, data):
|
||||||
if type == 'length':
|
if unit_type == 'length':
|
||||||
dimensional_exponents = self.file.createIfcDimensionalExponents(1, 0, 0, 0, 0, 0, 0)
|
dimensional_exponents = self.file.createIfcDimensionalExponents(1, 0, 0, 0, 0, 0, 0)
|
||||||
name_prefix = ''
|
name_prefix = ''
|
||||||
elif type == 'area':
|
elif unit_type == 'area':
|
||||||
dimensional_exponents = self.file.createIfcDimensionalExponents(2, 0, 0, 0, 0, 0, 0)
|
dimensional_exponents = self.file.createIfcDimensionalExponents(2, 0, 0, 0, 0, 0, 0)
|
||||||
name_prefix = 'square'
|
name_prefix = 'square'
|
||||||
elif type == 'volume':
|
elif unit_type == 'volume':
|
||||||
dimensional_exponents = self.file.createIfcDimensionalExponents(3, 0, 0, 0, 0, 0, 0)
|
dimensional_exponents = self.file.createIfcDimensionalExponents(3, 0, 0, 0, 0, 0, 0)
|
||||||
name_prefix = 'cubic'
|
name_prefix = 'cubic'
|
||||||
si_unit = self.file.createIfcSIUnit(None, '{}UNIT'.format(type.upper()), None,
|
si_unit = self.file.createIfcSIUnit(
|
||||||
'{}METRE'.format(name_prefix.upper() + '_' if name_prefix else ''))
|
None,
|
||||||
|
'{}UNIT'.format(unit_type.upper()),
|
||||||
|
None,
|
||||||
|
'{}METRE'.format(name_prefix.upper() + '_' if name_prefix else '')
|
||||||
|
)
|
||||||
if data['raw'] == 'INCHES':
|
if data['raw'] == 'INCHES':
|
||||||
name = '{}inch'.format(name_prefix + ' ' if name_prefix else '')
|
name = '{}inch'.format(name_prefix + ' ' if name_prefix else '')
|
||||||
elif data['raw'] == 'FEET':
|
elif data['raw'] == 'FEET':
|
||||||
name = '{}foot'.format(name_prefix + ' ' if name_prefix else '')
|
name = '{}foot'.format(name_prefix + ' ' if name_prefix else '')
|
||||||
value_component = self.file.create_entity('IfcReal',
|
value_component = self.file.create_entity(
|
||||||
**{'wrappedValue': SIUnitHelper.si_conversions[name]})
|
'IfcReal',
|
||||||
|
**{'wrappedValue': SIUnitHelper.si_conversions[name]}
|
||||||
|
)
|
||||||
conversion_factor = self.file.createIfcMeasureWithUnit(value_component, si_unit)
|
conversion_factor = self.file.createIfcMeasureWithUnit(value_component, si_unit)
|
||||||
return self.file.createIfcConversionBasedUnit(
|
return self.file.createIfcConversionBasedUnit(
|
||||||
dimensional_exponents, '{}UNIT'.format(type.upper()),
|
dimensional_exponents,
|
||||||
name, conversion_factor)
|
'{}UNIT'.format(unit_type.upper()),
|
||||||
|
name,
|
||||||
|
conversion_factor
|
||||||
|
)
|
||||||
|
|
||||||
def create_people(self):
|
def create_people(self):
|
||||||
for person in self.ifc_parser.people:
|
for person in self.ifc_parser.people:
|
||||||
@@ -986,7 +995,9 @@ class IfcExporter():
|
|||||||
def create_classifications(self):
|
def create_classifications(self):
|
||||||
for classification in self.ifc_parser.classifications:
|
for classification in self.ifc_parser.classifications:
|
||||||
classification['ifc'] = self.file.create_entity(
|
classification['ifc'] = self.file.create_entity(
|
||||||
'IfcClassification', **classification['attributes'])
|
'IfcClassification',
|
||||||
|
**classification['attributes']
|
||||||
|
)
|
||||||
self.file.createIfcRelAssociatesClassification(
|
self.file.createIfcRelAssociatesClassification(
|
||||||
ifcopenshell.guid.new(), None, None, None,
|
ifcopenshell.guid.new(), None, None, None,
|
||||||
[self.ifc_parser.project['ifc']], classification['ifc'])
|
[self.ifc_parser.project['ifc']], classification['ifc'])
|
||||||
@@ -994,7 +1005,7 @@ class IfcExporter():
|
|||||||
def create_classification_references(self):
|
def create_classification_references(self):
|
||||||
for reference in self.ifc_parser.classification_references.values():
|
for reference in self.ifc_parser.classification_references.values():
|
||||||
reference['attributes']['ReferencedSource'] = \
|
reference['attributes']['ReferencedSource'] = \
|
||||||
self.ifc_parser.classifications[reference['referenced_source']]['ifc']
|
self.ifc_parser.classifications[reference['referenced_source']]['ifc']
|
||||||
reference['ifc'] = self.file.create_entity(
|
reference['ifc'] = self.file.create_entity(
|
||||||
'IfcClassificationReference', **reference['attributes'])
|
'IfcClassificationReference', **reference['attributes'])
|
||||||
|
|
||||||
@@ -1063,14 +1074,14 @@ class IfcExporter():
|
|||||||
invalid_pset_keys))
|
invalid_pset_keys))
|
||||||
return properties
|
return properties
|
||||||
|
|
||||||
def cast_to_base_type(self, type, value):
|
def cast_to_base_type(self, var_type, value):
|
||||||
if type not in self.ifc_schema.type_map:
|
if var_type not in self.ifc_schema.type_map:
|
||||||
return value
|
return value
|
||||||
elif self.ifc_schema.type_map[type] == 'float':
|
elif self.ifc_schema.type_map[var_type] == 'float':
|
||||||
return float(value)
|
return float(value)
|
||||||
elif self.ifc_schema.type_map[type] == 'integer':
|
elif self.ifc_schema.type_map[var_type] == 'integer':
|
||||||
return int(value)
|
return int(value)
|
||||||
elif self.ifc_schema.type_map[type] == 'bool':
|
elif self.ifc_schema.type_map[var_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)
|
||||||
|
|
||||||
@@ -1115,21 +1126,30 @@ class IfcExporter():
|
|||||||
# TODO should this be hardcoded?
|
# TODO should this be hardcoded?
|
||||||
self.ifc_parser.map_conversion['attributes']['SourceCRS'] = self.ifc_rep_context['Model']['ifc']
|
self.ifc_parser.map_conversion['attributes']['SourceCRS'] = self.ifc_rep_context['Model']['ifc']
|
||||||
self.ifc_parser.map_conversion['attributes']['TargetCRS'] = self.ifc_parser.target_crs['ifc']
|
self.ifc_parser.map_conversion['attributes']['TargetCRS'] = self.ifc_parser.target_crs['ifc']
|
||||||
self.ifc_parser.map_conversion['ifc'] = self.file.create_entity('IfcMapConversion',
|
self.ifc_parser.map_conversion['ifc'] = self.file.create_entity(
|
||||||
**self.ifc_parser.map_conversion['attributes'])
|
'IfcMapConversion',
|
||||||
|
**self.ifc_parser.map_conversion['attributes']
|
||||||
|
)
|
||||||
|
|
||||||
def create_target_crs(self):
|
def create_target_crs(self):
|
||||||
self.ifc_parser.target_crs['attributes']['MapUnit'] = self.file.createIfcSIUnit(
|
self.ifc_parser.target_crs['attributes']['MapUnit'] = self.file.createIfcSIUnit(
|
||||||
None, 'LENGTHUNIT',
|
None,
|
||||||
|
'LENGTHUNIT',
|
||||||
SIUnitHelper.get_prefix(self.ifc_parser.target_crs['attributes']['MapUnit']),
|
SIUnitHelper.get_prefix(self.ifc_parser.target_crs['attributes']['MapUnit']),
|
||||||
SIUnitHelper.get_unit_name(self.ifc_parser.target_crs['attributes']['MapUnit']))
|
SIUnitHelper.get_unit_name(self.ifc_parser.target_crs['attributes']['MapUnit'])
|
||||||
|
)
|
||||||
self.ifc_parser.target_crs['ifc'] = self.file.create_entity(
|
self.ifc_parser.target_crs['ifc'] = self.file.create_entity(
|
||||||
'IfcProjectedCRS', **self.ifc_parser.target_crs['attributes'])
|
'IfcProjectedCRS',
|
||||||
|
**self.ifc_parser.target_crs['attributes']
|
||||||
|
)
|
||||||
|
|
||||||
def create_type_products(self):
|
def create_type_products(self):
|
||||||
for product in self.ifc_parser.type_products:
|
for product in self.ifc_parser.type_products:
|
||||||
placement = self.create_ifc_axis_2_placement_3d(product['location'], product['up_axis'],
|
placement = self.create_ifc_axis_2_placement_3d(
|
||||||
product['forward_axis'])
|
product['location'],
|
||||||
|
product['up_axis'],
|
||||||
|
product['forward_axis']
|
||||||
|
)
|
||||||
|
|
||||||
if product['representations']:
|
if product['representations']:
|
||||||
maps = []
|
maps = []
|
||||||
@@ -1139,9 +1159,10 @@ class IfcExporter():
|
|||||||
product['attributes']['RepresentationMaps'] = maps
|
product['attributes']['RepresentationMaps'] = maps
|
||||||
|
|
||||||
if product['psets']:
|
if product['psets']:
|
||||||
product['attributes'].update({'HasPropertySets':
|
product['attributes'].update({'HasPropertySets':[
|
||||||
[self.ifc_parser.psets[pset]['ifc'] for pset in
|
self.ifc_parser.psets[pset]['ifc']
|
||||||
product['psets']]})
|
for pset in product['psets']]
|
||||||
|
})
|
||||||
|
|
||||||
if product['class'] == 'IfcDoorType' \
|
if product['class'] == 'IfcDoorType' \
|
||||||
and product['attributes']['Name'] in self.ifc_parser.door_attributes:
|
and product['attributes']['Name'] in self.ifc_parser.door_attributes:
|
||||||
@@ -1163,7 +1184,8 @@ class IfcExporter():
|
|||||||
'The type product "{}/{}" could not be created: {}'.format(
|
'The type product "{}/{}" could not be created: {}'.format(
|
||||||
product['class'],
|
product['class'],
|
||||||
product['attributes']['Name'],
|
product['attributes']['Name'],
|
||||||
e.args)
|
e.args
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_predefined_attributes_to_type_product(self, product, attributes):
|
def add_predefined_attributes_to_type_product(self, product, attributes):
|
||||||
@@ -1176,10 +1198,8 @@ class IfcExporter():
|
|||||||
for attribute in attributes:
|
for attribute in attributes:
|
||||||
attribute['ifc'] = self.file.create_entity(
|
attribute['ifc'] = self.file.create_entity(
|
||||||
attribute['pset_name'],
|
attribute['pset_name'],
|
||||||
**{
|
**{k: float(v) if v.replace('.', '', 1).isdigit() else v
|
||||||
k: float(v) if v.replace('.', '', 1).isdigit() else v
|
for k, v in attribute['raw'].items()}
|
||||||
for k, v in attribute['raw'].items()
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def relate_definitions_to_contexts(self):
|
def relate_definitions_to_contexts(self):
|
||||||
@@ -1192,8 +1212,8 @@ class IfcExporter():
|
|||||||
def relate_objects_to_objects(self):
|
def relate_objects_to_objects(self):
|
||||||
for relating_object, related_objects_reference in self.ifc_parser.rel_aggregates.items():
|
for relating_object, related_objects_reference in self.ifc_parser.rel_aggregates.items():
|
||||||
relating_object = self.ifc_parser.products[relating_object]
|
relating_object = self.ifc_parser.products[relating_object]
|
||||||
related_objects = [self.ifc_parser.products[o]['ifc'] for o in
|
related_objects = [self.ifc_parser.products[o]['ifc']
|
||||||
self.ifc_parser.aggregates[related_objects_reference]]
|
for o in self.ifc_parser.aggregates[related_objects_reference]]
|
||||||
self.file.createIfcRelAggregates(
|
self.file.createIfcRelAggregates(
|
||||||
ifcopenshell.guid.new(), self.owner_history, relating_object['attributes']['Name'], None,
|
ifcopenshell.guid.new(), self.owner_history, relating_object['attributes']['Name'], None,
|
||||||
relating_object['ifc'], related_objects)
|
relating_object['ifc'], related_objects)
|
||||||
@@ -1329,17 +1349,20 @@ class IfcExporter():
|
|||||||
})
|
})
|
||||||
|
|
||||||
for key, value in product['attributes'].items():
|
for key, value in product['attributes'].items():
|
||||||
type = self.get_product_attribute_type(product['class'], key)
|
var_type = self.get_product_attribute_type(product['class'], key)
|
||||||
if type is None:
|
if var_type is None:
|
||||||
continue
|
continue
|
||||||
product['attributes'][key] = self.cast_to_base_type(type, value)
|
product['attributes'][key] = self.cast_to_base_type(var_type, value)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
product['ifc'] = self.file.create_entity(product['class'], **product['attributes'])
|
product['ifc'] = self.file.create_entity(product['class'], **product['attributes'])
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
self.ifc_export_settings.logger.error(
|
self.ifc_export_settings.logger.error(
|
||||||
'The product "{}/{}" could not be created: {}'.format(product['class'], product['attributes']['Name'],
|
'The product "{}/{}" could not be created: {}'.format(
|
||||||
e.args))
|
product['class'],
|
||||||
|
product['attributes']['Name'],
|
||||||
|
e.args)
|
||||||
|
)
|
||||||
|
|
||||||
def get_product_attribute_type(self, product_class, attribute_name):
|
def get_product_attribute_type(self, product_class, attribute_name):
|
||||||
element_schema = self.ifc_schema.elements[product_class]
|
element_schema = self.ifc_schema.elements[product_class]
|
||||||
@@ -1376,7 +1399,8 @@ class IfcExporter():
|
|||||||
self.create_cartesian_point(
|
self.create_cartesian_point(
|
||||||
product['location'].x,
|
product['location'].x,
|
||||||
product['location'].y,
|
product['location'].y,
|
||||||
product['location'].z),
|
product['location'].z
|
||||||
|
),
|
||||||
product['scale'].x,
|
product['scale'].x,
|
||||||
self.create_direction(product['up_axis']),
|
self.create_direction(product['up_axis']),
|
||||||
product['scale'].y,
|
product['scale'].y,
|
||||||
@@ -1388,7 +1412,6 @@ class IfcExporter():
|
|||||||
shape_representation.RepresentationType,
|
shape_representation.RepresentationType,
|
||||||
[mapped_item])
|
[mapped_item])
|
||||||
|
|
||||||
|
|
||||||
def calculate_quantities(self, qto_name, obj):
|
def calculate_quantities(self, qto_name, obj):
|
||||||
quantities = []
|
quantities = []
|
||||||
for index, vg in enumerate(obj.vertex_groups):
|
for index, vg in enumerate(obj.vertex_groups):
|
||||||
@@ -1448,10 +1471,12 @@ class IfcExporter():
|
|||||||
self.create_cartesian_point(
|
self.create_cartesian_point(
|
||||||
obj.bound_box[0][0],
|
obj.bound_box[0][0],
|
||||||
obj.bound_box[0][1],
|
obj.bound_box[0][1],
|
||||||
obj.bound_box[0][2]),
|
obj.bound_box[0][2]
|
||||||
|
),
|
||||||
obj.dimensions[0],
|
obj.dimensions[0],
|
||||||
obj.dimensions[1],
|
obj.dimensions[1],
|
||||||
obj.dimensions[2])
|
obj.dimensions[2]
|
||||||
|
)
|
||||||
return self.file.createIfcShapeRepresentation(
|
return self.file.createIfcShapeRepresentation(
|
||||||
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
||||||
representation['target_view']]['ifc'],
|
representation['target_view']]['ifc'],
|
||||||
@@ -1464,7 +1489,9 @@ class IfcExporter():
|
|||||||
return self.file.createIfcShapeRepresentation(
|
return self.file.createIfcShapeRepresentation(
|
||||||
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
||||||
representation['target_view']]['ifc'],
|
representation['target_view']]['ifc'],
|
||||||
representation['subcontext'], 'BoundingBox', [cog])
|
representation['subcontext'],
|
||||||
|
'BoundingBox',
|
||||||
|
[cog])
|
||||||
|
|
||||||
def create_wireframe_representation(self, representation):
|
def create_wireframe_representation(self, representation):
|
||||||
mesh = representation['raw']
|
mesh = representation['raw']
|
||||||
@@ -1475,7 +1502,8 @@ class IfcExporter():
|
|||||||
return self.file.createIfcShapeRepresentation(
|
return self.file.createIfcShapeRepresentation(
|
||||||
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
||||||
representation['target_view']]['ifc'],
|
representation['target_view']]['ifc'],
|
||||||
representation['subcontext'], 'Curve',
|
representation['subcontext'],
|
||||||
|
'Curve',
|
||||||
self.ifc_edges)
|
self.ifc_edges)
|
||||||
|
|
||||||
def create_geometric_curve_set_representation(self, representation):
|
def create_geometric_curve_set_representation(self, representation):
|
||||||
@@ -1654,8 +1682,8 @@ class IfcExporter():
|
|||||||
return loop
|
return loop
|
||||||
|
|
||||||
def get_edges_in_v_indices(self, obj, indices):
|
def get_edges_in_v_indices(self, obj, indices):
|
||||||
return [e for e in obj.data.edges if (
|
return [e for e in obj.data.edges
|
||||||
e.vertices[0] in indices and e.vertices[1] in indices)]
|
if (e.vertices[0] in indices and e.vertices[1] in indices)]
|
||||||
|
|
||||||
def get_loop_from_edges(self, edges):
|
def get_loop_from_edges(self, edges):
|
||||||
while edges:
|
while edges:
|
||||||
@@ -1707,9 +1735,9 @@ class IfcExporter():
|
|||||||
[self.file.createIfcFacetedBrep(self.file.createIfcClosedShell(self.ifc_faces))])
|
[self.file.createIfcFacetedBrep(self.file.createIfcClosedShell(self.ifc_faces))])
|
||||||
|
|
||||||
def create_vertices(self, vertices):
|
def create_vertices(self, vertices):
|
||||||
for vertice in vertices:
|
self.ifc_vertices.extend(
|
||||||
self.ifc_vertices.append(self.create_cartesian_point(
|
[self.file.createIfcCartesianPoint(self.convert_si_to_unit(v.co)) for v in vertices]
|
||||||
vertice.co.x, vertice.co.y, vertice.co.z))
|
)
|
||||||
|
|
||||||
def create_cartesian_point(self, x, y, z=None):
|
def create_cartesian_point(self, x, y, z=None):
|
||||||
x = self.convert_si_to_unit(x)
|
x = self.convert_si_to_unit(x)
|
||||||
@@ -1722,22 +1750,22 @@ class IfcExporter():
|
|||||||
def create_direction(self, vector):
|
def create_direction(self, vector):
|
||||||
return self.file.createIfcDirection((vector.x, vector.y, vector.z))
|
return self.file.createIfcDirection((vector.x, vector.y, vector.z))
|
||||||
|
|
||||||
def relate_voids_elements(self):
|
def relate_objects_to_opening_elements(self):
|
||||||
for relate_object, related_voids in self.ifc_parser.rel_voids_elements.items():
|
for relating_building_element, related_opening_elements in self.ifc_parser.rel_voids_elements.items():
|
||||||
for related_void in related_voids:
|
for related_opening_element in related_opening_elements:
|
||||||
self.file.createIfcRelVoidsElement(
|
self.file.createIfcRelVoidsElement(
|
||||||
ifcopenshell.guid.new(), self.owner_history, None, None,
|
ifcopenshell.guid.new(), self.owner_history, None, None,
|
||||||
relate_object,
|
related_building_element,
|
||||||
related_void
|
related_opening_element
|
||||||
)
|
)
|
||||||
|
|
||||||
def relate_fills_elements(self):
|
def relate_opening_elements_to_fillings(self):
|
||||||
for relate_object, related_fills in self.ifc_parser.rel_fills_elements.items():
|
for relating_opening_element, related_building_elements in self.ifc_parser.rel_fills_elements.items():
|
||||||
for related_fill in related_fills:
|
for related_building_element in related_building_elements:
|
||||||
self.file.createIfcRelFillsElement(
|
self.file.createIfcRelFillsElement(
|
||||||
ifcopenshell.guid.new(), self.owner_history, None, None,
|
ifcopenshell.guid.new(), self.owner_history, None, None,
|
||||||
relate_object,
|
relating_opening_element,
|
||||||
related_fill
|
related_building_element
|
||||||
)
|
)
|
||||||
|
|
||||||
def relate_elements_to_spatial_structures(self):
|
def relate_elements_to_spatial_structures(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user