gp_render/OP_merge_layers.py

113 lines
3.2 KiB
Python
Raw Normal View History

2021-09-07 18:06:54 +02:00
import bpy
def merge_layers(rlayers, obname=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')
ng = rlayers[0].outputs[0].links[0].to_node
rlayers.sort(key=lambda x: x.location.y, reverse=True)
# change colors of those nodes
color = random_color()
for n in rlayers:
n.use_custom_color = True
n.color = color
# get inside socket (group input) from outside socket list (should be already ordered)
## by name
# for i, inp in enumerate(ng.node_tree.inputs):
# if inp.name ==
# by connection order
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 !
##
def merge_selected_layers():
'''Merge command from selected GP layers'''
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)
def merge_selected_render_layers():
'''Merge command from selected render layers nodes'''
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']
# should be from the same object:
assert all(selection[0].layer.split('.')[0] == n.layer.split('.')[0] for n in selection), 'Not every nodes start with the same object'
# obname = selection[0].layer.split('.')[0]
merge_layers(selection)
# merge_selected_layers() # function to merge from GP dopesheet
merge_selected_render_layers() # function to merge from nodegroup