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
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
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
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
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