diff --git a/src/ifcblenderexport/bimui.py b/src/ifcblenderexport/bimui.py deleted file mode 100644 index 0cb9563858..0000000000 --- a/src/ifcblenderexport/bimui.py +++ /dev/null @@ -1,78 +0,0 @@ -import bpy -import json - -class IfcSchema(): - def __init__(self): - with open('/home/dion/Projects/IfcOpenShell/src/ifcblenderexport/IfcElement.json') as f: - self.elements = json.load(f) - -ifc_schema = IfcSchema() - -class BIMProperties(bpy.types.PropertyGroup): - def getIfcClasses(self, context): - return [(e, e, '') for e in ifc_schema.elements] - - def getIfcPredefinedTypes(self, context): - results = [] - for name, data in ifc_schema.elements.items(): - if name != bpy.context.scene.BIMProperties.ifc_class: - continue - for attribute in data['attributes']: - if attribute['name'] != 'PredefinedType': - continue - return [(e, e, '') for e in attribute['enum_values']] - - data_dir: bpy.props.StringProperty(name="Data Directory") - ifc_class: bpy.props.EnumProperty(items = getIfcClasses, name="Class") - ifc_predefined_type: bpy.props.EnumProperty( - items = getIfcPredefinedTypes, - name="Predefined Type", default=None) - ifc_userdefined_type: bpy.props.StringProperty(name="Userdefined Type") - -class BIMPanel(bpy.types.Panel): - """Creates a Panel in the scene context of the properties editor""" - bl_label = "Building Information Modeling" - bl_idname = "SCENE_PT_layout" - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "scene" - - def draw(self, context): - layout = self.layout - - scene = context.scene - bim_properties = bpy.context.scene.BIMProperties - - layout.label(text="System Setup:") - - row = layout.row() - row.prop(bim_properties, "data_dir") - - layout.label(text="IFC Categorisation:") - - row = layout.row() - row.prop(bim_properties, "ifc_class") - row = layout.row() - row.prop(bim_properties, "ifc_predefined_type") - row = layout.row() - row.prop(bim_properties, "ifc_userdefined_type") - row = layout.row() - row.operator("render.render") - -classes = ( - BIMProperties, - BIMPanel -) - -def register(): - for cls in classes: - bpy.utils.register_class(cls) - bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=BIMProperties) - -def unregister(): - for cls in classes: - bpy.utils.unregister_class(cls) - del(bpy.types.Scene.BIMProperties) - -if __name__ == "__main__": - register() diff --git a/src/ifcblenderexport/io_export_ifc/__init__.py b/src/ifcblenderexport/io_export_ifc/__init__.py index f6273eddd4..52496c190f 100644 --- a/src/ifcblenderexport/io_export_ifc/__init__.py +++ b/src/ifcblenderexport/io_export_ifc/__init__.py @@ -17,8 +17,8 @@ if "bpy" in locals(): import bpy import time from . import export +from . import ui import os -from bpy.props import (StringProperty,) cwd = os.path.dirname(os.path.realpath(__file__)) + os.path.sep @@ -26,7 +26,7 @@ class ExportIFC(bpy.types.Operator): bl_idname = "export.ifc" bl_label = "Export .ifc file" filename_ext = ".ifc" - filepath: StringProperty(subtype='FILE_PATH') + filepath: bpy.props.StringProperty(subtype='FILE_PATH') def invoke(self, context, event): if not self.filepath: @@ -39,7 +39,8 @@ class ExportIFC(bpy.types.Operator): print('# Starting export') start = time.time() ifc_export_settings = export.IfcExportSettings() - ifc_export_settings.bim_path = cwd + ifc_export_settings.data_dir = bpy.context.scene.BIMProperties.data_dir + ifc_export_settings.schema_dir = bpy.context.scene.BIMProperties.schema_dir ifc_export_settings.output_file = bpy.path.ensure_ext(self.filepath, '.ifc') ifc_parser = export.IfcParser(ifc_export_settings) ifc_schema = export.IfcSchema(ifc_export_settings) @@ -53,17 +54,26 @@ def menu_func(self, context): self.layout.operator(ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc)") -classes = (ExportIFC,) +classes = ( + ui.BIMOpAssignClass, + ui.BIMOpSelectDataDir, + ui.BIMOpSelectSchemaDir, + ui.BIMProperties, + ui.BIMPanel, + ExportIFC, + ) def register(): for cls in classes: bpy.utils.register_class(cls) bpy.types.TOPBAR_MT_file_export.append(menu_func) + bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=ui.BIMProperties) def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls) bpy.types.TOPBAR_MT_file_export.remove(menu_func) + del(bpy.types.Scene.BIMProperties) if __name__ == "__main__": register() diff --git a/src/ifcblenderexport/io_export_ifc/export.py b/src/ifcblenderexport/io_export_ifc/export.py index 57905e400e..7e0e420d9b 100644 --- a/src/ifcblenderexport/io_export_ifc/export.py +++ b/src/ifcblenderexport/io_export_ifc/export.py @@ -64,7 +64,7 @@ class QtoCalculator(): class IfcSchema(): def __init__(self, ifc_export_settings): - self.schema_dir = '{}schema/'.format(ifc_export_settings.bim_path) + self.schema_dir = ifc_export_settings.schema_dir self.property_file = ifcopenshell.open(self.schema_dir + 'IFC4_ADD2.ifc') self.psets = {} self.qtos = {} @@ -84,7 +84,7 @@ class IfcSchema(): class IfcParser(): def __init__(self, ifc_export_settings): - self.data_dir = '{}data/'.format(ifc_export_settings.bim_path) + self.data_dir = ifc_export_settings.data_dir self.ifc_export_settings = ifc_export_settings @@ -746,7 +746,7 @@ class SIUnitHelper: class IfcExporter(): def __init__(self, ifc_export_settings, ifc_schema, ifc_parser, qto_calculator): - self.template_file = '{}template.ifc'.format(ifc_export_settings.bim_path) + self.template_file = '{}template.ifc'.format(ifc_export_settings.schema_dir) self.output_file = ifc_export_settings.output_file self.ifc_export_settings = ifc_export_settings self.ifc_schema = ifc_schema @@ -1414,7 +1414,8 @@ class IfcExporter(): class IfcExportSettings: def __init__(self): - self.bim_path = None + self.schema_dir = None + self.data_dir = None self.output_file = None self.has_representations = True self.has_quantities = True diff --git a/src/ifcblenderexport/IfcElement.json b/src/ifcblenderexport/io_export_ifc/schema/ifc_elements_IFC4.json similarity index 100% rename from src/ifcblenderexport/IfcElement.json rename to src/ifcblenderexport/io_export_ifc/schema/ifc_elements_IFC4.json diff --git a/src/ifcblenderexport/io_export_ifc/template.ifc b/src/ifcblenderexport/io_export_ifc/schema/template.ifc similarity index 100% rename from src/ifcblenderexport/io_export_ifc/template.ifc rename to src/ifcblenderexport/io_export_ifc/schema/template.ifc diff --git a/src/ifcblenderexport/io_export_ifc/ui.py b/src/ifcblenderexport/io_export_ifc/ui.py new file mode 100644 index 0000000000..36be3ddccb --- /dev/null +++ b/src/ifcblenderexport/io_export_ifc/ui.py @@ -0,0 +1,124 @@ +import bpy +import json +import os + +cwd = os.path.dirname(os.path.realpath(__file__)) + os.path.sep + +class BIMOpAssignClass(bpy.types.Operator): + bl_idname = 'bim.assign_class' + bl_label = 'Assign IFC Class' + + def execute(self, context): + for object in bpy.context.selected_objects: + existing_class = None + if '/' in object.name \ + and object.name[0:3] == 'Ifc': + existing_class = object.name.split('/')[0] + if existing_class: + object.name = '{}/{}'.format( + bpy.context.scene.BIMProperties.ifc_class, + object.name.split('/')[1]) + else: + object.name = '{}/{}'.format( + bpy.context.scene.BIMProperties.ifc_class, + object.name) + if existing_class != bpy.context.scene.BIMProperties.ifc_class \ + and 'IfcPredefinedType' in object.keys(): + del(object['IfcPredefinedType']) + object['IfcPredefinedType'] = bpy.context.scene.BIMProperties.ifc_predefined_type + if bpy.context.scene.BIMProperties.ifc_predefined_type == 'USERDEFINED': + object['IfcObjectType'] = bpy.context.scene.BIMProperties.ifc_userdefined_type + elif 'IfcObjectType' in object.keys(): + del(object['IfcObjectType']) + return {'FINISHED'} + +class BIMOpSelectDataDir(bpy.types.Operator): + bl_idname = "bim.select_data_dir" + bl_label = "Select Data Directory" + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + + def execute(self, context): + bpy.context.scene.BIMProperties.data_dir = self.filepath + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + +class BIMOpSelectSchemaDir(bpy.types.Operator): + bl_idname = "bim.select_schema_dir" + bl_label = "Select Schema Directory" + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + + def execute(self, context): + bpy.context.scene.BIMProperties.schema_dir = self.filepath + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + +class IfcSchema(): + def __init__(self): + with open('{}ifc_elements_IFC4.json'.format(cwd + 'schema/')) as f: + self.elements = json.load(f) + +ifc_schema = IfcSchema() + +class BIMProperties(bpy.types.PropertyGroup): + def getIfcClasses(self, context): + return [(e, e, '') for e in ifc_schema.elements] + + def getIfcPredefinedTypes(self, context): + results = [] + for name, data in ifc_schema.elements.items(): + if name != bpy.context.scene.BIMProperties.ifc_class: + continue + for attribute in data['attributes']: + if attribute['name'] != 'PredefinedType': + continue + return [(e, e, '') for e in attribute['enum_values']] + + schema_dir: bpy.props.StringProperty(default=cwd + 'schema/', name="Schema Directory") + data_dir: bpy.props.StringProperty(default=cwd + 'data/', name="Data Directory") + ifc_class: bpy.props.EnumProperty(items = getIfcClasses, name="Class") + ifc_predefined_type: bpy.props.EnumProperty( + items = getIfcPredefinedTypes, + name="Predefined Type", default=None) + ifc_userdefined_type: bpy.props.StringProperty(name="Userdefined Type") + +class BIMPanel(bpy.types.Panel): + bl_label = "Building Information Modeling" + bl_idname = "SCENE_PT_layout" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "scene" + + def draw(self, context): + layout = self.layout + + scene = context.scene + bim_properties = bpy.context.scene.BIMProperties + + layout.label(text="System Setup:") + + col = layout.column() + row = col.row(align=True) + row.prop(bim_properties, "schema_dir") + row.operator("bim.select_schema_dir", icon="FILE_FOLDER", text="") + + col = layout.column() + row = col.row(align=True) + row.prop(bim_properties, "data_dir") + row.operator("bim.select_data_dir", icon="FILE_FOLDER", text="") + + layout.label(text="IFC Categorisation:") + + row = layout.row() + row.prop(bim_properties, "ifc_class") + row = layout.row() + row.prop(bim_properties, "ifc_predefined_type") + row = layout.row() + row.prop(bim_properties, "ifc_userdefined_type") + row = layout.row() + row.operator("bim.assign_class")