From de66ed85bae757f678fe7b6f78480cc804fc8065 Mon Sep 17 00:00:00 2001 From: pullusb Date: Thu, 18 Apr 2024 18:12:18 +0200 Subject: [PATCH] initial support for template in output base path and slots --- fn.py | 47 ++++++++++++++++++++++++++------------- gen_vlayer.py | 61 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 24 deletions(-) diff --git a/fn.py b/fn.py index 83dfad2..7c39644 100644 --- a/fn.py +++ b/fn.py @@ -1930,6 +1930,7 @@ def connect_to_file_output(node_list, file_out=None, base_path='', excludes=None if not fo: # color = (0.2,0.3,0.5) fo = create_node('CompositorNodeOutputFile', tree=scene.node_tree, location=(real_loc(node)[0]+500, real_loc(node)[1]+50), width=600) + fo.inputs.remove(fo.inputs[0]) # Remove default image input if file_format: for k, v in file_format.items(): setattr(fo.format, k, v) @@ -1952,11 +1953,21 @@ def connect_to_file_output(node_list, file_out=None, base_path='', excludes=None if next((l for l in o.links if recursive_node_connect_check(l, fo)), None): continue slot_name = bpy.path.clean_name(o.name) - if fo.format.file_format == 'OPEN_EXR_MULTILAYER': - slot_name = slot_name - else: - slot_name = f'{slot_name}/{slot_name}_' - fo.file_slots.new(slot_name) + # if fo.format.file_format == 'OPEN_EXR_MULTILAYER': + # slot_name = slot_name + # else: + # slot_name = f'{slot_name}/{slot_name}_' + # fo.file_slots.new(slot_name) + fs = fo.file_slots.new('tmp') # slot_name) + ls = fo.layer_slots.new('tmp') # slot_name + 'layer') + + ls = fo.layer_slots[-1] + ls.name = slot_name + + fs = fo.file_slots[-1] + fs.path = f'{slot_name}/{slot_name}_' # Error 'NodeSocketColor' object has no attribute 'path' + + out_input = fo.inputs[-1] links.new(o, out_input) @@ -1972,6 +1983,7 @@ def connect_to_file_output(node_list, file_out=None, base_path='', excludes=None if not fo: # color = (0.2,0.3,0.5) fo = create_node('CompositorNodeOutputFile', tree=scene.node_tree, location=(real_loc(node)[0]+400, real_loc(node)[1]-200), width=220) + fo.inputs.remove(fo.inputs[0]) # Remove default image input if file_format: for k, v in file_format.items(): setattr(fo.format, k, v) @@ -2001,17 +2013,22 @@ def connect_to_file_output(node_list, file_out=None, base_path='', excludes=None slot_name = bpy.path.clean_name(o.name) # directly use name in multi layer exr - if fo.format.file_format == 'OPEN_EXR_MULTILAYER': - slot_name = slot_name - else: - slot_name = f'{slot_name}/{slot_name}_' - fo.file_slots.new(slot_name) + # if fo.format.file_format == 'OPEN_EXR_MULTILAYER': + # slot_name = slot_name + # else: + # slot_name = f'{slot_name}/{slot_name}_' + # fo.file_slots.new(slot_name) + + # Setting both file_slots and layer_slots... + fs = fo.file_slots.new('tmp') + ls = fo.layer_slots.new('tmp') + + ls = fo.layer_slots[-1] + ls.name = slot_name + + fs = fo.file_slots[-1] + fs.path = f'{slot_name}/{slot_name}_' # Error 'NodeSocketColor' object has no attribute 'path' - ## Setting both file_slots and layer_slots... - # fs = fo.file_slots.new(slot_name) - # fs.path = f'{slot_name}/{slot_name}_' # Error 'NodeSocketColor' object has no attribute 'path' - # ls = fo.layer_slots.new(slot_name) - # ls.name = slot_name out_input = fo.inputs[-1] links.new(o, out_input) diff --git a/gen_vlayer.py b/gen_vlayer.py index 2fb5edb..28a1496 100644 --- a/gen_vlayer.py +++ b/gen_vlayer.py @@ -50,7 +50,30 @@ def add_rlayer(layer_name, scene=None, node_scene=None, location=None, color=Non comp.show_preview = False return comp -def connect_render_layer(rlayer, ng=None, out=None, frame=None): +# FIXME (Maybe just use "base_path") + +def connect_render_layer(rlayer, ng=None, out=None, frame=None, + base_path='//render/{object}', file_slot='{gplayer}/{gplayer}_', + multi_base_path='//render/{object}/{object}_', layer_slot='{gplayer}' + ): + '''Connect a render layer node to a fileoutput + Return existing or created nodegroup and file output nodes + + Args: + rlayer (node): the renderlayuer node to connect + ng (node, optional): Nodegroup to connect to if given + out (node, optional): Fileoutput node to connect to if given + frame (node, optional): frame node to use as parent if given + + base_path (str, optional): Template for base path when used with EXR + file_slot (str, optional): Template for slots when used with EXR + multi_base_path (str, optional): Template for base path when used with Multilayer EXR + layer_slot (str, optional): Template for slots when used with Multilayer EXR + Available keyword : {object} {gplayer} + + Return: + tuple(node, node) Nodegroup node, file_output node + ''' node_tree = rlayer.id_data # get node_tree from rlayer @@ -225,6 +248,8 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None): return out_name = f'OUT_{obname}' # or get output from frame + out_base = bpy.path.clean_name(obname) + if not out: out = nodes.get(out_name) @@ -232,29 +257,47 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None): # color = (0.2,0.3,0.5) out = fn.create_node('CompositorNodeOutputFile', tree=node_tree, location=(fn.real_loc(ng)[0]+500, fn.real_loc(ng)[1]+50), width=600) # =(ng.location[0]+600, ng.location[1]+50) fn.set_file_output_format(out) + out.name = out_name out.parent = frame - out_base = bpy.path.clean_name(obname) + if out.format.file_format == 'OPEN_EXR_MULTILAYER': - out.base_path = f'//render/{out_base}/{out_base}_' + out.base_path = multi_base_path.format(object=out_base, gplayer=lname) + # out.base_path = f'//render/{out_base}/{out_base}_' else: - out.base_path = f'//render/{out_base}' + out.base_path = base_path.format(object=out_base, gplayer=lname) + # out.base_path = f'//render/{out_base}' if out.format.file_format == 'OPEN_EXR_MULTILAYER': # Direct name in multilayer - slot_name = lname + # slot_name = lname + slot_name = layer_slot.format(object=out_base, gplayer=lname) else: # base_path/ named_folder/image_#### - slot_name = f'{lname}/{lname}_' + # slot_name = f'{lname}/{lname}_' + slot_name = file_slot.format(object=out_base, gplayer=lname) - ## out_input = out.inputs.get(slot_name) # ok for non-numbered outputs + + ## out_input = out.inputs.get(slot_name) # Ok for non-numbered outputs out_input = None out_input = fn.get_numbered_output(out, slot_name) if not out_input: - out.file_slots.new(slot_name) - out_input = out.inputs[-1] # assigning directly above doesn't link afterwards + ## Assigning directly does not work + # out.file_slots.new(file_slot.format(object=out_base, gplayer=lname)) + # out.layer_slots.new(layer_slot.format(object=out_base, gplayer=lname)) + + out.file_slots.new('file_slots_temp_name') + out.layer_slots.new('layer_slots_temp_name') + + fs = out.file_slots[-1] + fs.path = file_slot.format(object=out_base, gplayer=lname) + + ls = out.layer_slots[-1] + ls.name = layer_slot.format(object=out_base, gplayer=lname) + # out.file_slots.new(slot_name) + out_input = out.inputs[-1] # assigning directly as above doesn't link afterwards # print(f'new filouput entry: {out_input}') # link to FileOut