Esempio n. 1
0
    def export_node(self, node: SverchCustomTreeNode, groups: dict) -> dict:
        """It returns structure of given node"""
        self._add_mandatory_attributes(node)
        self._add_node_properties(node)
        self._add_socket_properties(node)

        if hasattr(node, 'monad') and node.monad:
            self._structure['bl_idname'] = 'SvMonadGenericNode'
            pack_monad(node, self._structure['params'], groups,
                       TreeExporter01().export_tree)

        if node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
            self._structure[node.node_kind] = node.stash()

        if hasattr(node, 'save_to_json'):
            node.save_to_json(self._structure)
        return self._structure
Esempio n. 2
0
def create_dict_of_tree(ng, skip_set={}, selected=False, identified_node=None, save_defaults = False):
    nodes = ng.nodes
    layout_dict = {}
    nodes_dict = {}
    groups_dict = {}

    if not skip_set:
        skip_set = {'Sv3DviewPropsNode'}

    if selected:
        nodes = list(filter(lambda n: n.select, nodes))

    if identified_node:
        # this mode will import one node only.
        nodes = [identified_node]

    # get nodes and params
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        node_dict = {}
        node_items = {}
        node_enums = find_enumerators(node)

        IsMonadInstanceNode = (node.bl_idname.startswith('SvGroupNodeMonad'))

        if save_defaults:
            node_props = get_node_annotations(node)
        else:
            node_props = node.items()

        for k, v in node_props:

            display_introspection_info(node, k, v)

            if can_skip_property(node, k):
                continue
            elif has_state_switch_protection(node, k):
                continue

            handle_old_groupnode(node, k, v, groups_dict, create_dict_of_tree)

            if isinstance(v, (float, int, str)):
                node_items[k] = v
            elif node.bl_idname in {'ScalarMathNode', 'SvLogicNode'} and k == 'prop_types':
                node_items[k] = getattr(node, k)[:]
                continue
            else:
                ann = node.bl_rna.__annotations__

                # this will only ever encounter pointerproperties that are interactive with
                # by the user, or they happen to be visible in the UI by defailt. arguably
                # we should be iterating over `node_props from get_node_annotations(node)`
                if k in ann:
                    prop_type, prop_details = ann[k]
                    if prop_type == bpy.props.PointerProperty:
                        info(f"skipping {node.name}.{k} (a PointerProperty)")
                        continue

                node_items[k] = v[:]

            handle_enum_property(node, k, v, node_items, node_enums)


        if IsMonadInstanceNode and node.monad:
            pack_monad(node, node_items, groups_dict, create_dict_of_tree)

        if hasattr(node, "storage_get_data"):
            node.storage_get_data(node_dict)

        node_dict['params'] = node_items

        collect_custom_socket_properties(node, node_dict)

        # if node.bl_idname == 'NodeFrame':
        #    frame_props = 'shrink', 'use_custom_color', 'label_size'
        #    node_dict['params'].update({fpv: getattr(node, fpv) for fpv in frame_props})

        if IsMonadInstanceNode:
            node_dict['bl_idname'] = 'SvMonadGenericNode'
            # these are indeed stored. as ints. which is fine.
            # must also store (.vectorize, bool) (.loop_me, bool) (.loops, int)
        else:
            node_dict['bl_idname'] = node.bl_idname

        if node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
            node_dict[node.node_kind] = node.stash()

        get_superficial_props(node_dict, node)
        nodes_dict[node.name] = node_dict

        # -------------------

    layout_dict['nodes'] = nodes_dict
    layout_dict['groups'] = groups_dict

    # ''' get connections '''
    # links = (compile_socket(l) for l in ng.links)
    # connections_dict = {idx: link for idx, link in enumerate(links)}
    # layout_dict['connections'] = connections_dict

    ''' get framed nodes '''
    framed_nodes = {}
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        if node.parent:
            if selected and node.parent.select:
                framed_nodes[node.name] = node.parent.name
            elif not selected:
                framed_nodes[node.name] = node.parent.name

    layout_dict['framed_nodes'] = framed_nodes

    ''' get update list (cache, order to link) '''
    # try/except for now, node tree links might be invalid
    # among other things. auto rebuild on F8
    try:
        build_update_list(ng)
        links_out = []
        for name in chain(*get_update_lists(ng)[0]):
            for socket in ng.nodes[name].inputs:
                if selected and not ng.nodes[name].select:
                    continue
                if socket.links:
                    link = socket.links[0]
                    if selected and not link.from_node.select:
                        continue
                    links_out.append(compile_socket(link))
        layout_dict['update_lists'] = links_out
    except Exception as err:
        exception(err)
        error('no update lists found or other error!')
        error(' - trigger an update and retry')
        return

    layout_dict['export_version'] = _EXPORTER_REVISION_
    return layout_dict
Esempio n. 3
0
def create_dict_of_tree(ng, skip_set={}, selected=False):
    nodes = ng.nodes
    layout_dict = {}
    nodes_dict = {}
    groups_dict = {}

    if not skip_set:
        skip_set = {'Sv3DviewPropsNode'}

    if selected:
        nodes = list(filter(lambda n: n.select, nodes))

    # get nodes and params
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        node_dict = {}
        node_items = {}
        node_enums = find_enumerators(node)

        IsMonadInstanceNode = (node.bl_idname.startswith('SvGroupNodeMonad'))

        for k, v in node.items():

            display_introspection_info(node, k, v)

            if can_skip_property(node, k):
                continue
            elif has_state_switch_protection(node, k):
                continue

            handle_old_groupnode(node, k, v, groups_dict, create_dict_of_tree)

            if isinstance(v, (float, int, str)):
                node_items[k] = v
            elif node.bl_idname in {'ScalarMathNode', 'SvLogicNode'
                                    } and k == 'prop_types':
                node_items[k] = getattr(node, k)[:]
                continue
            else:
                node_items[k] = v[:]

            handle_enum_property(node, k, v, node_items, node_enums)

        if IsMonadInstanceNode and node.monad:
            pack_monad(node, node_items, groups_dict, create_dict_of_tree)

        if hasattr(node, "storage_get_data"):
            node.storage_get_data(node_dict)

        node_dict['params'] = node_items

        collect_custom_socket_properties(node, node_dict)

        # if node.bl_idname == 'NodeFrame':
        #    frame_props = 'shrink', 'use_custom_color', 'label_size'
        #    node_dict['params'].update({fpv: getattr(node, fpv) for fpv in frame_props})

        if IsMonadInstanceNode:
            node_dict['bl_idname'] = 'SvMonadGenericNode'
        else:
            node_dict['bl_idname'] = node.bl_idname

        if node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
            node_dict[node.node_kind] = node.stash()

        get_superficial_props(node_dict, node)
        nodes_dict[node.name] = node_dict

        # -------------------

    layout_dict['nodes'] = nodes_dict
    layout_dict['groups'] = groups_dict

    # ''' get connections '''
    # links = (compile_socket(l) for l in ng.links)
    # connections_dict = {idx: link for idx, link in enumerate(links)}
    # layout_dict['connections'] = connections_dict
    ''' get framed nodes '''
    framed_nodes = {}
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        if node.parent:
            if selected and node.parent.select:
                framed_nodes[node.name] = node.parent.name
            elif not selected:
                framed_nodes[node.name] = node.parent.name

    layout_dict['framed_nodes'] = framed_nodes
    ''' get update list (cache, order to link) '''
    # try/except for now, node tree links might be invalid
    # among other things. auto rebuild on F8
    try:
        ng.build_update_list()
        links_out = []
        for name in chain(*ng.get_update_lists()[0]):
            for socket in ng.nodes[name].inputs:
                if selected and not ng.nodes[name].select:
                    continue
                if socket.links:
                    link = socket.links[0]
                    if selected and not link.from_node.select:
                        continue
                    links_out.append(compile_socket(link))
        layout_dict['update_lists'] = links_out
    except Exception as err:
        exception(err)
        error('no update lists found or other error!')
        error(' - trigger an update and retry')
        return

    layout_dict['export_version'] = _EXPORTER_REVISION_
    return layout_dict
def create_dict_of_tree(ng, skip_set={}, selected=False):
    nodes = ng.nodes
    layout_dict = {}
    nodes_dict = {}
    groups_dict = {}
    texts = bpy.data.texts
    if not skip_set:
        skip_set = {'Sv3DviewPropsNode'}

    if selected:
        nodes = list(filter(lambda n: n.select, nodes))
    ''' get nodes and params '''
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        node_dict = {}
        node_items = {}
        node_enums = find_enumerators(node)

        ObjectsNode = (node.bl_idname == 'ObjectsNode')
        ObjectsNode3 = (node.bl_idname == 'SvObjectsNodeMK3')
        ObjNodeLite = (node.bl_idname == 'SvObjInLite')
        MeshEvalNode = (node.bl_idname == 'SvMeshEvalNode')

        ScriptNodeLite = (node.bl_idname == 'SvScriptNodeLite')
        ProfileParamNode = (node.bl_idname == 'SvProfileNode')
        IsGroupNode = (node.bl_idname == 'SvGroupNode')
        IsMonadInstanceNode = (node.bl_idname.startswith('SvGroupNodeMonad'))
        TextInput = (node.bl_idname == 'SvTextInNode')
        SvExecNodeMod = (node.bl_idname == 'SvExecNodeMod')

        for k, v in node.items():

            if not isinstance(v, (float, int, str)):
                print('//')
                print(node.name, ' -> property:', k, type(v))
                print(type(node.bl_rna.properties[k]))
                print('\\\\')

            if k in {
                    'n_id', 'typ', 'newsock', 'dynamic_strings',
                    'frame_collection_name', 'type_collection_name'
            }:
                """
                n_id: 
                    used to store the hash of the current Node,
                    this is created along with the Node anyway. skip.
                typ, newsock:
                    reserved variables for changeable sockets
                dynamic_strings:
                    reserved by exec node
                frame_collection_name / type_collection_name both store Collection properties..avoiding for now
                """
                continue

            if has_state_switch_protection(node, k):
                continue

            if ObjectsNode and (k == "objects_local"):
                # this silences the import error when items not found.
                continue
            elif ObjectsNode3 and (k == 'object_names'):
                node_dict['object_names'] = [o.name for o in node.object_names]
                continue

            if TextInput and (k == 'current_text'):
                node_dict['current_text'] = node.text
                node_dict['textmode'] = node.textmode
                if node.textmode == 'JSON':
                    # add the json as full member to the tree :)
                    text_str = texts[node.text].as_string()
                    json_as_dict = json.loads(text_str)
                    node_dict['text_lines'] = {}
                    node_dict['text_lines']['stored_as_json'] = json_as_dict
                else:
                    node_dict['text_lines'] = texts[node.text].as_string()

            if ProfileParamNode and (k == "filename"):
                '''add file content to dict'''
                node_dict['path_file'] = texts[node.filename].as_string()

            if IsGroupNode and (k == "group_name"):
                if v not in groups_dict:
                    group_ng = bpy.data.node_groups[v]
                    group_dict = create_dict_of_tree(group_ng)
                    group_json = json.dumps(group_dict)
                    groups_dict[v] = group_json

            if isinstance(v, (float, int, str)):
                node_items[k] = v
            elif node.bl_idname in {'ScalarMathNode', 'SvLogicNode'
                                    } and k == 'prop_types':
                node_items[k] = getattr(node, k)[:]
                continue
            else:
                node_items[k] = v[:]

            if k in node_enums:
                v = getattr(node, k)
                node_items[k] = v

        if IsMonadInstanceNode and node.monad:
            pack_monad(node, node_items, groups_dict, create_dict_of_tree)

        # if hasattr(node, "storage_get_data"):
        if any([ScriptNodeLite, ObjNodeLite, SvExecNodeMod, MeshEvalNode]):
            node.storage_get_data(node_dict)

        # collect socket properties
        # inputs = node.inputs
        # for s in inputs:
        #     if (s.bl_label == 'Vertices') and hasattr(node, s.prop_name):
        #         prop = s.prop_name
        #         if prop:
        #            node_dict['custom_socket_props'][prop] = getattr(node, prop)[:]

        node_dict['params'] = node_items

        #if node.bl_idname == 'NodeFrame':
        #    frame_props = 'shrink', 'use_custom_color', 'label_size'
        #    node_dict['params'].update({fpv: getattr(node, fpv) for fpv in frame_props})

        if IsMonadInstanceNode:
            node_dict['bl_idname'] = 'SvMonadGenericNode'
        else:
            node_dict['bl_idname'] = node.bl_idname

        if node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
            node_dict[node.node_kind] = node.stash()

        get_superficial_props(node_dict, node)
        nodes_dict[node.name] = node_dict

        # -------------------

    layout_dict['nodes'] = nodes_dict
    layout_dict['groups'] = groups_dict

    # ''' get connections '''
    # links = (compile_socket(l) for l in ng.links)
    # connections_dict = {idx: link for idx, link in enumerate(links)}
    # layout_dict['connections'] = connections_dict
    ''' get framed nodes '''
    framed_nodes = {}
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        if node.parent:
            if selected and node.parent.select:
                framed_nodes[node.name] = node.parent.name
            elif not selected:
                framed_nodes[node.name] = node.parent.name

    layout_dict['framed_nodes'] = framed_nodes
    ''' get update list (cache, order to link) '''
    # try/except for now, node tree links might be invalid
    # among other things. auto rebuild on F8
    try:
        ng.build_update_list()
        links_out = []
        for name in chain(*ng.get_update_lists()[0]):
            for socket in ng.nodes[name].inputs:
                if selected and not ng.nodes[name].select:
                    continue
                if socket.links:
                    link = socket.links[0]
                    if selected and not link.from_node.select:
                        continue
                    links_out.append(compile_socket(link))
        layout_dict['update_lists'] = links_out
    except Exception as err:
        print(traceback.format_exc())
        print('no update lists found or other error!')
        print(' - trigger an update and retry')
        return

    layout_dict['export_version'] = _EXPORTER_REVISION_
    return layout_dict
Esempio n. 5
0
def create_dict_of_tree(ng, skip_set={}, selected=False):
    nodes = ng.nodes
    layout_dict = {}
    nodes_dict = {}
    groups_dict = {}
    texts = bpy.data.texts
    if not skip_set:
        skip_set = {'Sv3DviewPropsNode'}

    if selected:
        nodes = list(filter(lambda n: n.select, nodes))

    ''' get nodes and params '''
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        node_dict = {}
        node_items = {}
        node_enums = find_enumerators(node)

        ObjectsNode = (node.bl_idname == 'ObjectsNode')
        ObjectsNode3 = (node.bl_idname == 'SvObjectsNodeMK3')
        ObjNodeLite = (node.bl_idname == 'SvObjInLite')
        MeshEvalNode = (node.bl_idname == 'SvMeshEvalNode')

        ScriptNodeLite = (node.bl_idname == 'SvScriptNodeLite')
        ProfileParamNode = (node.bl_idname == 'SvProfileNode')
        IsGroupNode = (node.bl_idname == 'SvGroupNode')
        IsMonadInstanceNode = (node.bl_idname.startswith('SvGroupNodeMonad'))
        TextInput = (node.bl_idname == 'SvTextInNode')
        SvExecNodeMod = (node.bl_idname == 'SvExecNodeMod')

        for k, v in node.items():

            if not isinstance(v, (float, int, str)):
                print('//')
                print(node.name, ' -> property:', k, type(v))
                if k in node.bl_rna.properties:
                    print(type(node.bl_rna.properties[k]))
                elif k in node:
                    # something like node['lp']  , ID Property directly on the node instance.
                    print(type(node[k]))
                else:
                    print(k, 'is not bl_rna or IDproperty.. please report this')

                print('\\\\')

            if k in {'n_id', 'typ', 'newsock', 'dynamic_strings', 'frame_collection_name', 'type_collection_name'}:
                """
                n_id: 
                    used to store the hash of the current Node,
                    this is created along with the Node anyway. skip.
                typ, newsock:
                    reserved variables for changeable sockets
                dynamic_strings:
                    reserved by exec node
                frame_collection_name / type_collection_name both store Collection properties..avoiding for now
                """
                continue

            if has_state_switch_protection(node, k):
                continue

            if ObjectsNode and (k == "objects_local"):
                # this silences the import error when items not found.
                continue
            elif ObjectsNode3 and (k == 'object_names'):
                node_dict['object_names'] = [o.name for o in node.object_names]
                continue

            if TextInput and (k == 'current_text'):
                node_dict['current_text'] = node.text
                node_dict['textmode'] = node.textmode
                if node.textmode == 'JSON':
                    # add the json as full member to the tree :)
                    text_str = texts[node.text].as_string()
                    json_as_dict = json.loads(text_str)
                    node_dict['text_lines'] = {}
                    node_dict['text_lines']['stored_as_json'] = json_as_dict
                else:
                    node_dict['text_lines'] = texts[node.text].as_string()

            if ProfileParamNode and (k == "filename"):
                '''add file content to dict'''
                node_dict['path_file'] = texts[node.filename].as_string()

            if IsGroupNode and (k == "group_name"):
                if v not in groups_dict:
                    group_ng = bpy.data.node_groups[v]
                    group_dict = create_dict_of_tree(group_ng)
                    group_json = json.dumps(group_dict)
                    groups_dict[v] = group_json

            if isinstance(v, (float, int, str)):
                node_items[k] = v
            elif node.bl_idname in {'ScalarMathNode', 'SvLogicNode'} and k == 'prop_types':
                node_items[k] = getattr(node, k)[:]
                continue
            else:
                node_items[k] = v[:]

            if k in node_enums:
                v = getattr(node, k)
                node_items[k] = v

        if IsMonadInstanceNode and node.monad:
            pack_monad(node, node_items, groups_dict, create_dict_of_tree)

        # if hasattr(node, "storage_get_data"):
        if any([ScriptNodeLite, ObjNodeLite, SvExecNodeMod, MeshEvalNode]):
            node.storage_get_data(node_dict)

        # collect socket properties
        # inputs = node.inputs
        # for s in inputs:
        #     if (s.bl_label == 'Vertices') and hasattr(node, s.prop_name):
        #         prop = s.prop_name
        #         if prop:
        #            node_dict['custom_socket_props'][prop] = getattr(node, prop)[:]

        node_dict['params'] = node_items

        #if node.bl_idname == 'NodeFrame':
        #    frame_props = 'shrink', 'use_custom_color', 'label_size'
        #    node_dict['params'].update({fpv: getattr(node, fpv) for fpv in frame_props})

        
        if IsMonadInstanceNode:
            node_dict['bl_idname'] = 'SvMonadGenericNode'
        else:
            node_dict['bl_idname'] = node.bl_idname

        if node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
            node_dict[node.node_kind] = node.stash()

        get_superficial_props(node_dict, node)
        nodes_dict[node.name] = node_dict

        # -------------------

    layout_dict['nodes'] = nodes_dict
    layout_dict['groups'] = groups_dict

    # ''' get connections '''
    # links = (compile_socket(l) for l in ng.links)
    # connections_dict = {idx: link for idx, link in enumerate(links)}
    # layout_dict['connections'] = connections_dict

    ''' get framed nodes '''
    framed_nodes = {}
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        if node.parent:
            if selected and node.parent.select:
                framed_nodes[node.name] = node.parent.name
            elif not selected:
                framed_nodes[node.name] = node.parent.name

    layout_dict['framed_nodes'] = framed_nodes

    ''' get update list (cache, order to link) '''
    # try/except for now, node tree links might be invalid
    # among other things. auto rebuild on F8
    try:
        ng.build_update_list()
        links_out = []
        for name in chain(*ng.get_update_lists()[0]):
            for socket in ng.nodes[name].inputs:
                if selected and not ng.nodes[name].select:
                    continue
                if socket.links:
                    link = socket.links[0]
                    if selected and not link.from_node.select:
                        continue
                    links_out.append(compile_socket(link))
        layout_dict['update_lists'] = links_out
    except Exception as err:
        print(traceback.format_exc())
        print('no update lists found or other error!')
        print(' - trigger an update and retry')
        return

    layout_dict['export_version'] = _EXPORTER_REVISION_
    return layout_dict
Esempio n. 6
0
def create_dict_of_tree(ng, skip_set={}, selected=False, identified_node=None):
    nodes = ng.nodes
    layout_dict = {}
    nodes_dict = {}
    groups_dict = {}

    if not skip_set:
        skip_set = {'Sv3DviewPropsNode'}

    if selected:
        nodes = list(filter(lambda n: n.select, nodes))

    if identified_node:
        # this mode will import one node only.
        nodes = [identified_node]

    # get nodes and params
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        node_dict = {}
        node_items = {}
        node_enums = find_enumerators(node)

        IsMonadInstanceNode = (node.bl_idname.startswith('SvGroupNodeMonad'))

        for k, v in node.items():

            display_introspection_info(node, k, v)

            if can_skip_property(node, k):
                continue
            elif has_state_switch_protection(node, k):
                continue

            handle_old_groupnode(node, k, v, groups_dict, create_dict_of_tree)            

            if isinstance(v, (float, int, str)):
                node_items[k] = v
            elif node.bl_idname in {'ScalarMathNode', 'SvLogicNode'} and k == 'prop_types':
                node_items[k] = getattr(node, k)[:]
                continue
            else:
                node_items[k] = v[:]

            handle_enum_property(node, k, v, node_items, node_enums)


        if IsMonadInstanceNode and node.monad:
            pack_monad(node, node_items, groups_dict, create_dict_of_tree)

        if hasattr(node, "storage_get_data"):
            node.storage_get_data(node_dict)

        node_dict['params'] = node_items

        collect_custom_socket_properties(node, node_dict)

        # if node.bl_idname == 'NodeFrame':
        #    frame_props = 'shrink', 'use_custom_color', 'label_size'
        #    node_dict['params'].update({fpv: getattr(node, fpv) for fpv in frame_props})

        if IsMonadInstanceNode:
            node_dict['bl_idname'] = 'SvMonadGenericNode'
        else:
            node_dict['bl_idname'] = node.bl_idname

        if node.bl_idname in {'SvGroupInputsNodeExp', 'SvGroupOutputsNodeExp'}:
            node_dict[node.node_kind] = node.stash()

        get_superficial_props(node_dict, node)
        nodes_dict[node.name] = node_dict

        # -------------------

    layout_dict['nodes'] = nodes_dict
    layout_dict['groups'] = groups_dict

    # ''' get connections '''
    # links = (compile_socket(l) for l in ng.links)
    # connections_dict = {idx: link for idx, link in enumerate(links)}
    # layout_dict['connections'] = connections_dict

    ''' get framed nodes '''
    framed_nodes = {}
    for node in nodes:

        if node.bl_idname in skip_set:
            continue

        if node.parent:
            if selected and node.parent.select:
                framed_nodes[node.name] = node.parent.name
            elif not selected:
                framed_nodes[node.name] = node.parent.name

    layout_dict['framed_nodes'] = framed_nodes

    ''' get update list (cache, order to link) '''
    # try/except for now, node tree links might be invalid
    # among other things. auto rebuild on F8
    try:
        ng.build_update_list()
        links_out = []
        for name in chain(*ng.get_update_lists()[0]):
            for socket in ng.nodes[name].inputs:
                if selected and not ng.nodes[name].select:
                    continue
                if socket.links:
                    link = socket.links[0]
                    if selected and not link.from_node.select:
                        continue
                    links_out.append(compile_socket(link))
        layout_dict['update_lists'] = links_out
    except Exception as err:
        exception(err)
        error('no update lists found or other error!')
        error(' - trigger an update and retry')
        return

    layout_dict['export_version'] = _EXPORTER_REVISION_
    return layout_dict