diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index f2fc5461a8..a1c92b3bb4 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -216,7 +216,7 @@ if bpy is not None: def menu_func_export(self, context): self.layout.operator(operator.ExportIFC.bl_idname, - text="Industry Foundation Classes (.ifc/.ifczip)") + text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)") def menu_func_import(self, context): self.layout.operator(operator.ImportIFC.bl_idname, diff --git a/src/ifcblenderexport/blenderbim/bim/export_ifc.py b/src/ifcblenderexport/blenderbim/bim/export_ifc.py index af20ccd357..2ed77ca14d 100644 --- a/src/ifcblenderexport/blenderbim/bim/export_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/export_ifc.py @@ -12,6 +12,7 @@ from .helper import SIUnitHelper from . import schema import ifcopenshell import addon_utils +from .ifc2json import IFC2JSON class ArrayModifier: count: int @@ -2617,6 +2618,10 @@ class IfcExporter(): zf.write(tmp_file) elif extension == 'ifc': self.file.write(self.ifc_export_settings.output_file) + elif extension == 'ifcjson': + ifc2json = IFC2JSON(self.file).convert() + with open(self.ifc_export_settings.output_file, 'w') as f: + f.write(json.dumps(ifc2json, indent = 4)) class IfcExportSettings: diff --git a/src/ifcblenderexport/blenderbim/bim/ifc2json.py b/src/ifcblenderexport/blenderbim/bim/ifc2json.py new file mode 100644 index 0000000000..5d64261db2 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/ifc2json.py @@ -0,0 +1,106 @@ +import ifcopenshell + +class IFC2JSON: + def __init__(self, file): + self.file = file + self.id_objects = {} + self.jsonObjects = [] + + def convert(self): + # schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(self.file.schema) + entityIter = iter(self.file) + for entity in entityIter: + self.entityToDict(entity) + for key in self.id_objects: + self.jsonObjects.append(self.id_objects[key]) + + return { + 'data': self.jsonObjects + } + + def entityToDict(self, entity): + ref = { + 'Type': entity.is_a() + } + attr_dict = entity.__dict__ + + # check for globalid + if 'GlobalId' in attr_dict: + ref['ref'] = attr_dict['GlobalId'] + if not attr_dict['GlobalId'] in self.id_objects: + d = { + 'Type': entity.is_a() + } + + for i in range(0,len(entity)): + attr = entity.attribute_name(i) + if attr in attr_dict: + if not attr == 'OwnerHistory': + jsonValue = self.getEntityValue(attr_dict[attr]) + if jsonValue: + d[attr] = jsonValue + if attr_dict[attr] == None: + continue + elif isinstance(attr_dict[attr], ifcopenshell.entity_instance): + d[attr] = self.entityToDict(attr_dict[attr]) + elif isinstance(attr_dict[attr], tuple): + subEnts = [] + for subEntity in attr_dict[attr]: + if isinstance(subEntity, ifcopenshell.entity_instance): + subEntJson = self.entityToDict(subEntity) + if subEntJson: + subEnts.append(subEntJson) + else: + subEnts.append(subEntity) + if len(subEnts) > 0: + d[attr] = subEnts + else: + d[attr] = attr_dict[attr] + self.id_objects[attr_dict['GlobalId']] = d + return ref + else: + d = { + 'Type': entity.is_a() + } + + for i in range(0,len(entity)): + attr = entity.attribute_name(i) + if attr in attr_dict: + if not attr == 'OwnerHistory': + jsonValue = self.getEntityValue(attr_dict[attr]) + if jsonValue: + d[attr] = jsonValue + if attr_dict[attr] == None: + continue + elif isinstance(attr_dict[attr], ifcopenshell.entity_instance): + d[attr] = self.entityToDict(attr_dict[attr]) + elif isinstance(attr_dict[attr], tuple): + subEnts = [] + for subEntity in attr_dict[attr]: + if isinstance(subEntity, ifcopenshell.entity_instance): + # subEnts.append(None) + subEntJson = self.entityToDict(subEntity) + if subEntJson: + subEnts.append(subEntJson) + else: + subEnts.append(subEntity) + if len(subEnts) > 0: + d[attr] = subEnts + else: + d[attr] = attr_dict[attr] + return d + + def getEntityValue(self, value): + if value == None: + jsonValue = None + elif isinstance(value, ifcopenshell.entity_instance): + jsonValue = self.entityToDict(value) + elif isinstance(value, tuple): + jsonValue = None + subEnts = [] + for subEntity in value: + subEnts.append(self.getEntityValue(subEntity)) + jsonValue = subEnts + else: + jsonValue = value + return jsonValue diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 218bed3b1d..68806c4c4b 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -57,6 +57,8 @@ class ExportIFC(bpy.types.Operator): extension = self.filepath.split('.')[-1] if extension == 'ifczip': output_file = bpy.path.ensure_ext(self.filepath, '.ifczip') + elif extension == 'ifcjson': + output_file = bpy.path.ensure_ext(self.filepath, '.ifcjson') else: output_file = bpy.path.ensure_ext(self.filepath, '.ifc') ifc_export_settings = export_ifc.IfcExportSettings.factory(context, output_file, logger)