113 lines
3.2 KiB
Python
113 lines
3.2 KiB
Python
|
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
|
||
|
|