def generate_layout(fullpath, nodes_json): '''cummulative function ''' # it may be necessary to store monads as dicts instead of string/json # this will handle both scenarios if isinstance(nodes_json, str): nodes_json = json.loads(nodes_json) print('==== loading monad ====') print('#' * 12, nodes_json['export_version']) ''' create all nodes and groups ''' update_lists = nodes_json['update_lists'] nodes_to_import = nodes_json['nodes'] groups_to_import = nodes_json.get('groups', {}) add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(ng, nodes_to_import, nodes, create_texts) ''' now connect them ''' # prevent unnecessary updates ng.freeze(hard=True) make_links(update_lists, name_remap) ''' set frame parents ''' place_frames(ng, nodes_json, name_remap) ''' clean up ''' old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update()
def generate_layout(fullpath, nodes_json): # it may be necessary to store monads as dicts instead of string/json # this will handle both scenarios if isinstance(nodes_json, str): nodes_json = json.loads(nodes_json) debug('==== loading monad ====') info(('#' * 12) + nodes_json['export_version']) # create all nodes and groups ''' update_lists = nodes_json['update_lists'] nodes_to_import = nodes_json['nodes'] if center is not None: center_nodes(nodes_to_import, center) groups_to_import = nodes_json.get('groups', {}) add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(ng, nodes_to_import, nodes, create_texts) # now connect them / prevent unnecessary updates ng.freeze(hard=True) make_links(update_lists, name_remap) # set frame parents ''' place_frames(ng, nodes_json, name_remap) # clean up old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update() ng.update_tag()
def generate_layout(fullpath, nodes_json): '''cummulative function ''' # it may be necessary to store monads as dicts instead of string/json # this will handle both scenarios if isinstance(nodes_json, str): nodes_json = json.loads(nodes_json) print('==== loading monad ====') print('#' * 12, nodes_json['export_version']) ''' create all nodes and groups ''' update_lists = nodes_json['update_lists'] nodes_to_import = nodes_json['nodes'] groups_to_import = nodes_json.get('groups', {}) add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(ng, nodes_to_import, nodes, create_texts) ''' now connect them ''' # prevent unnecessary updates ng.freeze(hard=True) make_links(update_lists, name_remap) ''' set frame parents ''' place_frames(ng, nodes_json, name_remap) ''' clean up ''' old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update()
def generate_layout(fullpath, nodes_json): """cummulative function """ # it may be necessary to store monads as dicts instead of string/json # this will handle both scenarios if isinstance(nodes_json, str): nodes_json = json.loads(nodes_json) print("==== loading monad ====") print("#" * 12, nodes_json["export_version"]) """ create all nodes and groups """ update_lists = nodes_json["update_lists"] nodes_to_import = nodes_json["nodes"] groups_to_import = nodes_json.get("groups", {}) add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(nodes_to_import, nodes, create_texts) """ now connect them """ # prevent unnecessary updates ng.freeze(hard=True) make_links(update_lists, name_remap) """ set frame parents """ place_frames(ng, nodes_json, name_remap) """ clean up """ old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update()
def generate_layout(fullpath, nodes_json): # it may be necessary to store monads as dicts instead of string/json # this will handle both scenarios if isinstance(nodes_json, str): nodes_json = json.loads(nodes_json) debug('==== loading monad ====') info(('#' * 12) + nodes_json['export_version']) # create all nodes and groups ''' update_lists = nodes_json['update_lists'] nodes_to_import = nodes_json['nodes'] if center is not None: center_nodes(nodes_to_import, center) groups_to_import = nodes_json.get('groups', {}) add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(ng, nodes_to_import, nodes, create_texts) # now connect them / prevent unnecessary updates ng.freeze(hard=True) make_links(update_lists, name_remap) # set frame parents ''' place_frames(ng, nodes_json, name_remap) # clean up old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update() ng.update_tag()
def generate_layout(fullpath, nodes_json): """ fullpath can be - a path on disk, or - an empty string when the nodes_json is passed """ # it may be necessary to store monads as dicts instead of string/json # this will handle both scenarios if isinstance(nodes_json, str): nodes_json = json.loads(nodes_json) debug('==== loading monad ====') passed_fullpath = '' if not fullpath else basename(fullpath) hash_separator = ('#' * 12) info( f"{hash_separator} {nodes_json['export_version']} {passed_fullpath}" ) # create all nodes and groups ''' update_lists = nodes_json['update_lists'] nodes_to_import = nodes_json['nodes'] if center is not None: center_nodes(nodes_to_import, center) groups_to_import = nodes_json.get('groups', {}) previous_state = ng.sv_process ng.sv_process = False add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(ng, nodes_to_import, nodes, create_texts) ng.freeze(hard=True) # now connect them / prevent unnecessary updates make_links(update_lists, name_remap) # set frame parents ''' place_frames(ng, nodes_json, name_remap) # clean up old_nodes.scan_for_old(ng) dummy_nodes.scan_for_dummy(ng) ng.unfreeze(hard=True) ng.sv_process = True ng.update() ng.update_tag() ng.sv_process = previous_state
def generate_layout(fullpath, nodes_json): print('#' * 12, nodes_json['export_version']) ''' first create all nodes. ''' nodes_to_import = nodes_json['nodes'] groups_to_import = nodes_json.get('groups', {}) group_name_remap = {} for name in groups_to_import: group_ng = bpy.data.node_groups.new(name, 'SverchGroupTreeType') if group_ng.name != name: group_name_remap[name] = ng.name import_tree(group_ng, '', groups_to_import[name]) name_remap = {} texts = bpy.data.texts for n in sorted(nodes_to_import): node_ref = nodes_to_import[n] bl_idname = node_ref['bl_idname'] try: if old_nodes.is_old(bl_idname): old_nodes.register_old(bl_idname) node = nodes.new(bl_idname) except Exception as err: print(traceback.format_exc()) print(bl_idname, 'not currently registered, skipping') continue if create_texts: if node.bl_idname in SCRIPTED_NODES: ''' Scripted Node will no longer create alternative versions of a file. If a scripted node wants to make a file called 'inverse.py' and the current .blend already contains such a file, then for simplicity the importer will not try to create 'inverse.001.py' and reference that. It will instead do nothing and assume the existing python file is functionally the same. If you have files that work differently but have the same name, stop. ''' params = node_ref.get('params') if params: script_name = params.get('script_name') script_content = params.get('script_str') if script_name and not (script_name in texts): new_text = texts.new(script_name) new_text.from_string(script_content) node.script_name = script_name node.script_str = script_content if node.bl_idname == 'SvScriptNode': node.user_name = "templates" # best would be in the node. node.files_popup = "sv_lang_template.sn" # import to reset easy fix node.load() else: node.files_popup = node.avail_templates(None)[0][0] node.load() elif node.bl_idname == 'SvProfileNode': new_text = texts.new(node_ref['params']['filename']) new_text.from_string(node_ref['path_file']) node.update() # as it's a beta service, old IO json may not be compatible - in this interest # of neat code we assume it finds everything. elif node.bl_idname == 'SvTextInNode': params = node_ref.get('params') current_text = params['current_text'] node.textmode = params['textmode'] if not current_text: print(node.name, "doesn't store a current_text in params") elif not (current_text in texts): new_text = texts.new(current_text) if node.textmode == 'JSON': json_str = json.dumps(node_ref['text_lines']['stored_as_json']) new_text.from_string(json_str) else: new_text.from_string(node_ref['text_lines']) else: texts[current_text].from_string(node_ref['text_lines']) ''' When n is assigned to node.name, blender will decide whether or not it can do that, if there exists already a node with that name, then the assignment to node.name is not n, but n.00x. Hence on the following line we check if the assignment was accepted, and store a remapped name if it wasn't. ''' node.name = n if not (node.name == n): name_remap[n] = node.name params = node_ref['params'] # print(node.name, params) for p in params: val = params[p] setattr(node, p, val) node.location = node_ref['location'] node.height = node_ref['height'] node.width = node_ref['width'] node.label = node_ref['label'] node.hide = node_ref['hide'] node.color = node_ref['color'] ''' Nodes that require post processing to work properly ''' if node.bl_idname in {'SvGroupInputsNode', 'SvGroupOutputsNode'}: node.load() elif node.bl_idname in {'SvGroupNode'}: node.load() group_name = node.group_name node.group_name = group_name_remap.get(group_name, group_name) elif node.bl_idname == 'SvTextInNode': # node.reload() # node.reset() # node.reload() node.load() update_lists = nodes_json['update_lists'] print('update lists:') for ulist in update_lists: print(ulist) ''' now connect them ''' # naive # freeze updates while connecting the tree, otherwise # each connection will cause an update event ng.freeze(hard=True) failed_connections = [] for link in update_lists: try: ng.links.new(*resolve_socket(*link, name_dict=name_remap)) except Exception as err: print(traceback.format_exc()) failed_connections.append(link) continue if failed_connections: print('failed total {0}'.format(len(failed_connections))) print(failed_connections) else: print('no failed connections! awesome.') ''' set frame parents ''' finalize = lambda name: name_remap.get(name, name) framed_nodes = nodes_json['framed_nodes'] for node_name, parent in framed_nodes.items(): ng.nodes[finalize(node_name)].parent = ng.nodes[finalize(parent)] old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update()
def generate_layout(fullpath, nodes_json): print('#' * 12, nodes_json['export_version']) ''' first create all nodes. ''' nodes_to_import = nodes_json['nodes'] groups_to_import = nodes_json.get('groups', {}) group_name_remap = {} for name in groups_to_import: group_ng = bpy.data.node_groups.new(name, 'SverchGroupTreeType') if group_ng.name != name: group_name_remap[name] = ng.name import_tree(group_ng, '', groups_to_import[name]) name_remap = {} texts = bpy.data.texts for n in sorted(nodes_to_import): node_ref = nodes_to_import[n] bl_idname = node_ref['bl_idname'] try: if old_nodes.is_old(bl_idname): old_nodes.register_old(bl_idname) node = nodes.new(bl_idname) except Exception as err: print(traceback.format_exc()) print(bl_idname, 'not currently registered, skipping') continue ''' maintenance warning: for the creation of new text files. If this script is run in a file which contains these Text names already, then the script/file names stored in the node must be updated to reflect this. Also is a script/profile is used for more than one node it will lead to duplication. All names have to collected and then fixed at end ''' if create_texts: if node.bl_idname in ('SvScriptNode', 'SvScriptNodeMK2'): new_text = texts.new(node.script_name) # there is no gurantee that we get the name we request if new_text.name != node.script_name: node.script_name = new_text.name new_text.from_string(node.script_str) node.user_name = "templates" # best would be in the node. node.files_popup = "sv_lang_template.sn" # import to reset easy fix node.load() elif node.bl_idname == 'SvProfileNode': new_text = texts.new(node.filename) new_text.from_string(node_ref['path_file']) # needed! node.update() elif node.bl_idname == 'SvTextInNode': if node_ref['current_text'] not in [a.name for a in texts]: new_text = texts.new(node.current_text) new_text.name = node_ref['current_text'] new_text.from_string(node_ref['text_lines']) else: texts[node_ref['current_text']].from_string(node_ref['text_lines']) ''' When n is assigned to node.name, blender will decide whether or not it can do that, if there exists already a node with that name, then the assignment to node.name is not n, but n.00x. Hence on the following line we check if the assignment was accepted, and store a remapped name if it wasn't. ''' node.name = n if not (node.name == n): name_remap[n] = node.name params = node_ref['params'] print(node.name, params) for p in params: val = params[p] setattr(node, p, val) node.location = node_ref['location'] node.height = node_ref['height'] node.width = node_ref['width'] node.label = node_ref['label'] node.hide = node_ref['hide'] node.color = node_ref['color'] ''' Nodes that require post processing to work properly ''' if node.bl_idname in {'SvGroupInputsNode', 'SvGroupOutputsNode'}: node.load() elif node.bl_idname in {'SvGroupNode'}: node.load() group_name = node.group_name node.group_name = group_name_remap.get(group_name, group_name) elif node.bl_idname == 'SvTextInNode': node.reload() #node.reset() #node.load() update_lists = nodes_json['update_lists'] print('update lists:') for ulist in update_lists: print(ulist) ''' now connect them ''' # naive # freeze updates while connecting the tree, otherwise # each connection will cause an update event ng.freeze(hard=True) failed_connections = [] for link in update_lists: try: ng.links.new(*resolve_socket(*link, name_dict=name_remap)) except Exception as err: print(traceback.format_exc()) failed_connections.append(link) continue if failed_connections: print('failed total {0}'.format(len(failed_connections))) print(failed_connections) else: print('no failed connections! awesome.') ''' set frame parents ''' finalize = lambda name: name_remap.get(name, name) framed_nodes = nodes_json['framed_nodes'] for node_name, parent in framed_nodes.items(): ng.nodes[finalize(node_name)].parent = ng.nodes[finalize(parent)] old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update()
def generate_layout(fullpath, nodes_json): print('#' * 12, nodes_json['export_version']) ''' first create all nodes. ''' nodes_to_import = nodes_json['nodes'] groups_to_import = nodes_json.get('groups', {}) group_name_remap = {} for name in groups_to_import: group_ng = bpy.data.node_groups.new(name, 'SverchGroupTreeType') if group_ng.name != name: group_name_remap[name] = ng.name import_tree(group_ng, '', groups_to_import[name]) name_remap = {} texts = bpy.data.texts for n in sorted(nodes_to_import): node_ref = nodes_to_import[n] bl_idname = node_ref['bl_idname'] try: if old_nodes.is_old(bl_idname): old_nodes.register_old(bl_idname) node = nodes.new(bl_idname) except Exception as err: print(traceback.format_exc()) print(bl_idname, 'not currently registered, skipping') continue ''' When n is assigned to node.name, blender will decide whether or not it can do that, if there exists already a node with that name, then the assignment to node.name is not n, but n.00x. Hence on the following line we check if the assignment was accepted, and store a remapped name if it wasn't. ''' node.name = n if not (node.name == n): name_remap[n] = node.name params = node_ref['params'] print(node.name, params) for p in params: val = params[p] setattr(node, p, val) node.location = node_ref['location'] node.height = node_ref['height'] node.width = node_ref['width'] node.label = node_ref['label'] node.hide = node_ref['hide'] node.color = node_ref['color'] ''' maintenance warning: for the creation of new text files. If this script is run in a file which contains these Text names already, then the script/file names stored in the node must be updated to reflect this. Also is a script/profile is used for more than one node it will lead to duplication. All names have to collected and then fixed at end ''' if create_texts: if node.bl_idname in ('SvScriptNode', 'SvScriptNodeMK2'): new_text = texts.new(node.script_name) # there is no gurantee that we get the name we request if new_text.name != node.script_name: node.script_name = new_text.name new_text.from_string(node.script_str) node.user_name = "templates" # best would be in the node. node.files_popup = "sv_lang_template.sn" # import to reset easy fix node.load() elif node.bl_idname == 'SvProfileNode': new_text = texts.new(node.filename) new_text.from_string(node_ref['path_file']) # needed! node.update() ''' Nodes that require post processing to work properly ''' if node.bl_idname in {'SvGroupInputsNode', 'SvGroupOutputsNode'}: node.load() elif node.bl_idname in {'SvGroupNode'}: node.load() group_name = node.group_name node.group_name = group_name_remap.get(group_name, group_name) update_lists = nodes_json['update_lists'] print('update lists:') for ulist in update_lists: print(ulist) ''' now connect them ''' # naive # freeze updates while connecting the tree, otherwise # each connection will cause an update event ng.freeze(hard=True) failed_connections = [] for link in update_lists: try: ng.links.new(*resolve_socket(*link, name_dict=name_remap)) except Exception as err: print(traceback.format_exc()) failed_connections.append(link) continue if failed_connections: print('failed total {0}'.format(len(failed_connections))) print(failed_connections) else: print('no failed connections! awesome.') ''' set frame parents ''' finalize = lambda name: name_remap.get(name, name) framed_nodes = nodes_json['framed_nodes'] for node_name, parent in framed_nodes.items(): ng.nodes[finalize(node_name)].parent = ng.nodes[finalize(parent)] old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update()
def generate_layout(fullpath, nodes_json): print('#' * 12, nodes_json['export_version']) ''' first create all nodes. ''' nodes_to_import = nodes_json['nodes'] groups_to_import = nodes_json.get('groups', {}) group_name_remap = {} for name in groups_to_import: group_ng = bpy.data.node_groups.new(name, 'SverchGroupTreeType') if group_ng.name != name: group_name_remap[name] = ng.name import_tree(group_ng, '', groups_to_import[name]) name_remap = {} texts = bpy.data.texts for n in sorted(nodes_to_import): node_ref = nodes_to_import[n] bl_idname = node_ref['bl_idname'] try: if old_nodes.is_old(bl_idname): old_nodes.register_old(bl_idname) node = nodes.new(bl_idname) except Exception as err: print(traceback.format_exc()) print(bl_idname, 'not currently registered, skipping') continue if create_texts: if node.bl_idname in SCRIPTED_NODES: ''' Scripted Node will no longer create alternative versions of a file. If a scripted node wants to make a file called 'inverse.py' and the current .blend already contains such a file, then for simplicity the importer will not try to create 'inverse.001.py' and reference that. It will instead do nothing and assume the existing python file is functionally the same. If you have files that work differently but have the same name, stop. ''' params = node_ref.get('params') if params: script_name = params.get('script_name') script_content = params.get('script_str') if script_name and not (script_name in texts): new_text = texts.new(script_name) new_text.from_string(script_content) node.script_name = script_name node.script_str = script_content if node.bl_idname == 'SvScriptNode': node.user_name = "templates" # best would be in the node. node.files_popup = "sv_lang_template.sn" # import to reset easy fix node.load() else: node.files_popup = node.avail_templates(None)[0][0] node.load() elif node.bl_idname == 'SvProfileNode': new_text = texts.new(node_ref['params']['filename']) new_text.from_string(node_ref['path_file']) node.update() # as it's a beta service, old IO json may not be compatible - in this interest # of neat code we assume it finds everything. elif node.bl_idname == 'SvTextInNode': params = node_ref.get('params') current_text = params['current_text'] node.textmode = params['textmode'] if not current_text: print(node.name, "doesn't store a current_text in params") elif not (current_text in texts): new_text = texts.new(current_text) if node.textmode == 'JSON': json_str = json.dumps( node_ref['text_lines']['stored_as_json']) new_text.from_string(json_str) else: new_text.from_string(node_ref['text_lines']) else: texts[current_text].from_string(node_ref['text_lines']) ''' When n is assigned to node.name, blender will decide whether or not it can do that, if there exists already a node with that name, then the assignment to node.name is not n, but n.00x. Hence on the following line we check if the assignment was accepted, and store a remapped name if it wasn't. ''' node.name = n if not (node.name == n): name_remap[n] = node.name params = node_ref['params'] # print(node.name, params) for p in params: val = params[p] setattr(node, p, val) node.location = node_ref['location'] node.height = node_ref['height'] node.width = node_ref['width'] node.label = node_ref['label'] node.hide = node_ref['hide'] node.color = node_ref['color'] ''' Nodes that require post processing to work properly ''' if node.bl_idname in {'SvGroupInputsNode', 'SvGroupOutputsNode'}: node.load() elif node.bl_idname in {'SvGroupNode'}: node.load() group_name = node.group_name node.group_name = group_name_remap.get(group_name, group_name) elif node.bl_idname == 'SvTextInNode': # node.reload() # node.reset() # node.reload() node.load() update_lists = nodes_json['update_lists'] print('update lists:') for ulist in update_lists: print(ulist) ''' now connect them ''' # naive # freeze updates while connecting the tree, otherwise # each connection will cause an update event ng.freeze(hard=True) failed_connections = [] for link in update_lists: try: ng.links.new(*resolve_socket(*link, name_dict=name_remap)) except Exception as err: print(traceback.format_exc()) failed_connections.append(link) continue if failed_connections: print('failed total {0}'.format(len(failed_connections))) print(failed_connections) else: print('no failed connections! awesome.') ''' set frame parents ''' finalize = lambda name: name_remap.get(name, name) framed_nodes = nodes_json['framed_nodes'] for node_name, parent in framed_nodes.items(): ng.nodes[finalize(node_name)].parent = ng.nodes[finalize(parent)] old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) ng.update()