diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py new file mode 100644 index 0000000000..316b226886 --- /dev/null +++ b/src/ifcsverchok/__init__.py @@ -0,0 +1,115 @@ +bl_info = { + "name": "IFC for Sverchok", + "author": "Dion Moult", + "version": (0, 0, 0, 1), + "blender": (2, 90, 0), + "location": "Node Editor", + "category": "Node", + "description": "An extension to Sverchok to generate IFC data", + "warning": "", +} + +import sys +import importlib +import nodeitems_utils +import sverchok +from sverchok.core import sv_registration_utils, make_node_list +from sverchok.utils import auto_gather_node_classes, get_node_class_reference +from sverchok.menu import SverchNodeItem, SverchNodeCategory, register_node_panels +from sverchok.utils.extra_categories import register_extra_category_provider, unregister_extra_category_provider +from sverchok.ui.nodeview_space_menu import make_extra_category_menus +from sverchok.utils.logging import info, debug + +def nodes_index(): + return [("IFC", [ + ("ifc.create_ifc", "SvCreateIfc"), + ("ifc.read_ifc", "SvReadIfc"), + ("ifc.write_ifc", "SvWriteIfc"), + ])] + +def make_node_list(): + modules = [] + base_name = "ifcsverchok.nodes" + index = nodes_index() + for category, items in index: + for module_name, node_name in items: + module = importlib.import_module(f".{module_name}", base_name) + modules.append(module) + return modules + +imported_modules = make_node_list() + +reload_event = False + +import bpy + +def register_nodes(): + node_modules = make_node_list() + for module in node_modules: + module.register() + info("Registered %s nodes", len(node_modules)) + +def unregister_nodes(): + global imported_modules + for module in reversed(imported_modules): + module.unregister() + +def make_menu(): + menu = [] + index = nodes_index() + for category, items in index: + identifier = "IFCSVERCHOK_" + category.replace(' ', '_') + node_items = [] + for item in items: + nodetype = item[1] + rna = get_node_class_reference(nodetype) + if not rna: + info("Node `%s' is not available (probably due to missing dependencies).", nodetype) + else: + node_item = SverchNodeItem.new(nodetype) + node_items.append(node_item) + if node_items: + cat = SverchNodeCategory( + identifier, + category, + items=node_items + ) + menu.append(cat) + return menu + +class SvExCategoryProvider(object): + def __init__(self, identifier, menu): + self.identifier = identifier + self.menu = menu + + def get_categories(self): + return self.menu + +our_menu_classes = [] + +def register(): + global our_menu_classes + + debug("Registering ifcsverchok") + + register_nodes() + extra_nodes = importlib.import_module(".nodes", "ifcsverchok") + auto_gather_node_classes(extra_nodes) + menu = make_menu() + menu_category_provider = SvExCategoryProvider("IFCSVERCHOK", menu) + register_extra_category_provider(menu_category_provider) #if 'IFCSVERCHOK' in nodeitems_utils._node_categories: + nodeitems_utils.register_node_categories("IFCSVERCHOK", menu) + our_menu_classes = make_extra_category_menus() + +def unregister(): + global our_menu_classes + if 'IFCSVERCHOK' in nodeitems_utils._node_categories: + nodeitems_utils.unregister_node_categories("IFCSVERCHOK") + for clazz in our_menu_classes: + try: + bpy.utils.unregister_class(clazz) + except Exception as e: + print("Can't unregister menu class %s" % clazz) + print(e) + unregister_extra_category_provider("IFCSVERCHOK") + unregister_nodes() diff --git a/src/ifcsverchok/helper.py b/src/ifcsverchok/helper.py new file mode 100644 index 0000000000..809d9719f5 --- /dev/null +++ b/src/ifcsverchok/helper.py @@ -0,0 +1,14 @@ +import bpy +from sverchok.data_structure import zip_long_repeat + +ifc_files = {} + +class SvIfcCore(): + def process(self): + sv_inputs_nested = [] + for name in self.sv_input_names: + sv_inputs_nested.append(self.inputs[name].sv_get()) + for sv_input_nested in zip_long_repeat(*sv_inputs_nested): + for sv_input in zip_long_repeat(*sv_input_nested): + sv_input = list(sv_input) + self.process_ifc(*sv_input) diff --git a/src/ifcsverchok/nodes/__init__.py b/src/ifcsverchok/nodes/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/ifcsverchok/nodes/ifc/__init__.py b/src/ifcsverchok/nodes/ifc/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/ifcsverchok/nodes/ifc/create_ifc.py b/src/ifcsverchok/nodes/ifc/create_ifc.py new file mode 100644 index 0000000000..8c61e54296 --- /dev/null +++ b/src/ifcsverchok/nodes/ifc/create_ifc.py @@ -0,0 +1,31 @@ +import bpy +import ifcopenshell +import ifcsverchok.helper +from bpy.props import StringProperty +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode + + +class SvCreateIfc(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): + bl_idname = 'SvCreateIfc' + bl_label = 'Create IFC' + schema: StringProperty(name='schema', update=updateNode, default='IFC4') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', 'schema').prop_name = 'schema' + self.outputs.new('SvVerticesSocket', 'file') + + def process(self): + self.sv_input_names = ['schema'] + super().process() + + def process_ifc(self, schema): + guid = ifcopenshell.guid.new() + ifcsverchok.helper.ifc_files[guid] = ifcopenshell.file(schema=schema) + self.outputs['file'].sv_set([[ifcsverchok.helper.ifc_files[guid]]]) + +def register(): + bpy.utils.register_class(SvCreateIfc) + +def unregister(): + bpy.utils.unregister_class(SvCreateIfc) diff --git a/src/ifcsverchok/nodes/ifc/read_ifc.py b/src/ifcsverchok/nodes/ifc/read_ifc.py new file mode 100644 index 0000000000..7814543c2b --- /dev/null +++ b/src/ifcsverchok/nodes/ifc/read_ifc.py @@ -0,0 +1,31 @@ +import bpy +import ifcopenshell +import ifcsverchok.helper +from bpy.props import StringProperty +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode + + +class SvReadIfc(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): + bl_idname = 'SvReadIfc' + bl_label = 'Read IFC' + path: StringProperty(name='path', update=updateNode) + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', 'path').prop_name = 'path' + self.outputs.new('SvVerticesSocket', 'file') + + def process(self): + self.sv_input_names = ['path'] + super().process() + + def process_ifc(self, path): + guid = ifcopenshell.guid.new() + ifcsverchok.helper.ifc_files[guid] = ifcopenshell.open(path) + self.outputs['file'].sv_set([[ifcsverchok.helper.ifc_files[guid]]]) + +def register(): + bpy.utils.register_class(SvReadIfc) + +def unregister(): + bpy.utils.unregister_class(SvReadIfc) diff --git a/src/ifcsverchok/nodes/ifc/write_ifc.py b/src/ifcsverchok/nodes/ifc/write_ifc.py new file mode 100644 index 0000000000..c6da806398 --- /dev/null +++ b/src/ifcsverchok/nodes/ifc/write_ifc.py @@ -0,0 +1,30 @@ +import bpy +import ifcopenshell +import ifcsverchok.helper +from bpy.props import StringProperty +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode + + +class SvWriteIfc(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): + bl_idname = 'SvWriteIfc' + bl_label = 'Write IFC' + file: StringProperty(name='file', update=updateNode) + path: StringProperty(name='path', update=updateNode) + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', 'file').prop_name = 'file' + self.inputs.new('SvStringsSocket', 'path').prop_name = 'path' + + def process(self): + self.sv_input_names = ['file', 'path'] + super().process() + + def process_ifc(self, file, path): + file.write(path) + +def register(): + bpy.utils.register_class(SvWriteIfc) + +def unregister(): + bpy.utils.unregister_class(SvWriteIfc)