diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py index 316b226886..05a8d4ce32 100644 --- a/src/ifcsverchok/__init__.py +++ b/src/ifcsverchok/__init__.py @@ -22,9 +22,10 @@ from sverchok.utils.logging import info, debug def nodes_index(): return [("IFC", [ - ("ifc.create_ifc", "SvCreateIfc"), - ("ifc.read_ifc", "SvReadIfc"), - ("ifc.write_ifc", "SvWriteIfc"), + ("ifc.create_file", "SvIfcCreateFile"), + ("ifc.read_file", "SvIfcReadFile"), + ("ifc.write_file", "SvIfcWriteFile"), + ("ifc.create_entity", "SvIfcCreateEntity"), ])] def make_node_list(): diff --git a/src/ifcsverchok/nodes/ifc/create_entity.py b/src/ifcsverchok/nodes/ifc/create_entity.py new file mode 100644 index 0000000000..7b636dddd1 --- /dev/null +++ b/src/ifcsverchok/nodes/ifc/create_entity.py @@ -0,0 +1,92 @@ +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 SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): + bl_idname = 'SvIfcCreateEntity' + bl_label = 'IFC Create Entity' + file: StringProperty(name='file', update=updateNode) + ifc_class: StringProperty(name='ifc_class', update=updateNode) + current_ifc_class: StringProperty(name='current_ifc_class') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', 'file').prop_name = 'file' + self.inputs.new('SvStringsSocket', 'ifc_class').prop_name = 'ifc_class' + self.outputs.new('SvStringsSocket', 'file') + self.outputs.new('SvStringsSocket', 'entity') + + def process(self): + self.sv_input_names = ['file', 'ifc_class'] + ifc_class = self.inputs['ifc_class'].sv_get()[0][0] + if ifc_class: + file = self.inputs['file'].sv_get()[0][0] + if file: + schema_name = file.wrapped_data.schema + else: + schema_name = 'IFC4' + self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(schema_name) + self.entity_schema = self.schema.declaration_by_name(ifc_class) + + if ifc_class != self.current_ifc_class: + self.generate_inputs(ifc_class) + try: + for i in range(0, len(self.inputs)): + self.inputs[i].sv_get() + except: + # This occurs when a blender save file is reloaded + self.generate_inputs(ifc_class) + + for i in range(0, self.entity_schema.attribute_count()): + self.sv_input_names.append(self.entity_schema.attribute_by_index(i).name()) + super().process() + + def generate_inputs(self, ifc_class): + while len(self.inputs) > 2: + self.inputs.remove(self.inputs[-1]) + for i in range(0, self.entity_schema.attribute_count()): + name = self.entity_schema.attribute_by_index(i).name() + setattr(SvIfcCreateEntity, name, StringProperty(name=name)) + self.inputs.new('SvStringsSocket', name).prop_name = name + self.current_ifc_class = ifc_class + + def process_ifc(self, file, ifc_class, *attributes): + entity = file.create_entity(ifc_class) + for i in range(0, len(entity)): + try: + value = attributes[i] + if isinstance(value, str) and value == '': + value = None + except: + value = None + if value is None and entity.is_a('IfcRoot') and i==0: + value = ifcopenshell.guid.new() + if value is not None: + value = self.cast_value(self.entity_schema.attribute_by_index(i), value) + try: + entity[i] = value + except: + raise Exception('The IFC class {} requires a valid value for {} - you provided {}'.format( + ifc_class, entity.attribute_name(i), value)) + self.outputs['file'].sv_set([[file]]) + self.outputs['entity'].sv_set([[entity]]) + + def cast_value(self, attribute, value): + data_type = self.get_attribute_data_type(attribute.type_of_attribute()) + if data_type == 'integer': + value = int(value) + return value + + def get_attribute_data_type(self, data_type): + if hasattr(data_type, 'declared_type'): + return self.get_attribute_data_type(data_type.declared_type()) + return data_type + +def register(): + bpy.utils.register_class(SvIfcCreateEntity) + +def unregister(): + bpy.utils.unregister_class(SvIfcCreateEntity) diff --git a/src/ifcsverchok/nodes/ifc/create_file.py b/src/ifcsverchok/nodes/ifc/create_file.py new file mode 100644 index 0000000000..27133960d8 --- /dev/null +++ b/src/ifcsverchok/nodes/ifc/create_file.py @@ -0,0 +1,50 @@ +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 SvIfcCreateFileRefresh(bpy.types.Operator): + bl_idname = "node.sv_ifc_create_file_refresh" + bl_label = "LB Out" + + idtree: StringProperty(default='') + idname: StringProperty(default='') + has_baked: bpy.props.BoolProperty(name='Has Baked', default=False) + + def execute(self, context): + node = bpy.data.node_groups[self.idtree].nodes[self.idname] + node.process() + return {'FINISHED'} + + +class SvIfcCreateFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): + bl_idname = 'SvIfcCreateFile' + bl_label = 'IFC Create File' + 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 draw_buttons(self, context, layout): + self.wrapper_tracked_ui_draw_op(layout, 'node.sv_ifc_create_file_refresh', icon='FILE_REFRESH', text='Refresh') + + 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(SvIfcCreateFile) + bpy.utils.register_class(SvIfcCreateFileRefresh) + +def unregister(): + bpy.utils.unregister_class(SvIfcCreateFile) + bpy.utils.unregister_class(SvIfcCreateFileRefresh) diff --git a/src/ifcsverchok/nodes/ifc/create_ifc.py b/src/ifcsverchok/nodes/ifc/create_ifc.py deleted file mode 100644 index 8c61e54296..0000000000 --- a/src/ifcsverchok/nodes/ifc/create_ifc.py +++ /dev/null @@ -1,31 +0,0 @@ -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_file.py similarity index 75% rename from src/ifcsverchok/nodes/ifc/read_ifc.py rename to src/ifcsverchok/nodes/ifc/read_file.py index 7814543c2b..2ba9978441 100644 --- a/src/ifcsverchok/nodes/ifc/read_ifc.py +++ b/src/ifcsverchok/nodes/ifc/read_file.py @@ -6,9 +6,9 @@ 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' +class SvIfcReadFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): + bl_idname = 'SvIfcReadFile' + bl_label = 'IFC Read File' path: StringProperty(name='path', update=updateNode) def sv_init(self, context): @@ -25,7 +25,7 @@ class SvReadIfc(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCo self.outputs['file'].sv_set([[ifcsverchok.helper.ifc_files[guid]]]) def register(): - bpy.utils.register_class(SvReadIfc) + bpy.utils.register_class(SvIfcReadFile) def unregister(): - bpy.utils.unregister_class(SvReadIfc) + bpy.utils.unregister_class(SvIfcReadFile) diff --git a/src/ifcsverchok/nodes/ifc/write_ifc.py b/src/ifcsverchok/nodes/ifc/write_file.py similarity index 73% rename from src/ifcsverchok/nodes/ifc/write_ifc.py rename to src/ifcsverchok/nodes/ifc/write_file.py index c6da806398..76e223dee3 100644 --- a/src/ifcsverchok/nodes/ifc/write_ifc.py +++ b/src/ifcsverchok/nodes/ifc/write_file.py @@ -6,9 +6,9 @@ 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' +class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): + bl_idname = 'SvIfcWriteFile' + bl_label = 'IFC Write File' file: StringProperty(name='file', update=updateNode) path: StringProperty(name='path', update=updateNode) @@ -24,7 +24,7 @@ class SvWriteIfc(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcC file.write(path) def register(): - bpy.utils.register_class(SvWriteIfc) + bpy.utils.register_class(SvIfcWriteFile) def unregister(): - bpy.utils.unregister_class(SvWriteIfc) + bpy.utils.unregister_class(SvIfcWriteFile)