import bpy from . import fn def merge_layers(rlayers, obname=None, active=None): print(f'Merging {len(rlayers)} layers') print('->', [r.layer for r in rlayers]) print() if not rlayers: return ('ERROR', 'No render layer sent to merge') # get node group # ng = rlayers[0].outputs[0].links[0].to_node # sort RL descending rlayers.sort(key=lambda n: fn.real_loc(n).y, reverse=True) vl_name = active.layer if not vl_name: vl_name = rlayers[0].layer # change colors of those nodes color = fn.random_color() for n in rlayers: n.use_custom_color = True n.color = color obname, lname = vl_name.split(' / ') lname = bpy.path.clean_name(lname) ng_name = f'merge_NG_{obname}' # only object name ## clear nodes groups duplication (.00?) fn.clear_nodegroup(ng_name, full_clear=False) # get set nodegroup from vlayer name if not ng: ng = nodes.get(ng_name) if not ng: ngroup = bpy.data.node_groups.get(ng_name) # full clear True if exists but not used if ngroup and ngroup.users == 0: ngroup = None fn.clear_nodegroup(ng_name, full_clear=True) if not ngroup: # delete and recreate ? print(f'create nodegroup {ng_name}') ngroup = bpy.data.node_groups.new(ng_name, 'CompositorNodeTree') ng = fn.create_node('CompositorNodeGroup', tree=scene.node_tree, location=(fn.real_loc(rlayer)[0] + 600, fn.real_loc(rlayer)[1]), width=400) # (rlayer.location[0] + 600, rlayer.location[1]) if frame: ng.parent= frame ng.node_tree = ngroup ng.name = ngroup.name ng_in = fn.create_node('NodeGroupInput', tree=ngroup, location=(-600,0)) ng_out = fn.create_node('NodeGroupOutput', tree=ngroup, location=(600,0)) """ socket_list = [] grp_sockets = [] for n in rlayers: if n.outputs[0].links[0].to_node != ng: print(f'Skip {n.layer}, connect to {n.outputs[0].links[0].to_node} instead of {ng.name}') continue sock_in = n.outputs[0].links[0].to_socket for i, s in enumerate(ng.inputs): if s == sock_in: print(i, s.name) socket_list.append(s) grp_sockets.append(ng.node_tree.nodes['Group Input'].outputs[i]) break # debug for inp, grps in zip(socket_list, grp_sockets): if inp.name != grps.name: print(f'\n! Problem ! : {inp.name}, {grps.name}') return """ ## # JUST CREATE ANOTHER GROUP NODE FOR THE MERGE ! ## class GPEXP_OT_merge_selected_dopesheet_layers(bpy.types.Operator): bl_idname = "gp.merge_selected_dopesheet_layers" bl_label = "Merge selected layers view_layers " bl_description = "Merge view layers of selected gp layers to a new dedicated file output" bl_options = {"REGISTER"} @classmethod def poll(cls, context): return context.object and context.object.type == 'GPENCIL' def execute(self, context): # merge_selected_layers() # function to merge from GP dopesheet ob = bpy.context.object layer_names = [l.info for l in ob.data.layers if l.select and not l.hide] print("layer_names", layer_names)#Dbg if len(layer_names) < 2: print(f'Should select multiple layers for merging') return render = bpy.data.scenes.get('Render') if render: nodes = render.node_tree.nodes clean_ob_name = bpy.path.clean_name(ob.name) rlayers = [] for l in layer_names: ## identifier is clean_name(ob.name).layer_name idname = f'{clean_ob_name}.{l}' # check the render layer that have a parent frame rlayer = [n for n in nodes if n.type == 'R_LAYERS' and n.layer == idname and n.parent] if not rlayer: # send to function to generate the rlayer and connect # rlayer = creation continue rlayers.append(rlayer) merge_layers(rlayers, obname=clean_ob_name) return {"FINISHED"} class GPEXP_OT_merge_selected_viewlayer_nodes(bpy.types.Operator): bl_idname = "gp.merge_selected_viewlayer_nodes" bl_label = "Merge selected view_layers " bl_description = "Merge selected view layers to a new dedicated file output" bl_options = {"REGISTER"} def execute(self, context): render = bpy.data.scenes.get('Render') if not render: print('No render scene') return nodes = render.node_tree.nodes selection = [n for n in nodes if n.select and n.type == 'R_LAYERS'] if not nodes.active in selection: self.report({'ERROR'}, 'The active node not within the render layer selection (used to define out name)') return {'CANCELLED'} # should be from the same object: if not all(selection[0].layer.split('.')[0] == n.layer.split('.')[0] for n in selection): print('Merge -> Not every nodes start with the same object') # obname = selection[0].layer.split('.')[0] merge_layers(selection, nodes.active) return {"FINISHED"} classes=( GPEXP_OT_merge_selected_dopesheet_layers, GPEXP_OT_merge_selected_viewlayer_nodes, ) def register(): for cls in classes: bpy.utils.register_class(cls) def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls)