gp_render/standalone_scripts/rn_layer_merge.py

160 lines
4.3 KiB
Python

info = {
'icon': 'TRIA_DOWN_BAR',
'description': 'Merge layers',
}
import fnmatch
import glob
import os
import re
from math import degrees, radians
from os import listdir
from os.path import basename, dirname, exists, isdir, isfile, join, splitext
from pathlib import Path
import bpy
C = bpy.context
D = bpy.data
def random_color(alpha=False):
import random
if alpha:
return (random.uniform(0,1), random.uniform(0,1), random.uniform(0,1), 1)
return (random.uniform(0,1), random.uniform(0,1), random.uniform(0,1))
def create_node(type, tree=None, **kargs):
tree = tree or bpy.context.scene.node_tree
node = tree.nodes.new(type)
for k,v in kargs.items():
setattr(node, k, v)
return node
def new_aa_node(tree):
'''create AA node'''
aa = create_node('CompositorNodeAntiAliasing', tree) # type = ANTIALIASING
aa.threshold = 0.5
aa.contrast_limit = 0.5
aa.corner_rounding = 0.25
aa.hide = True
return aa
def get_render_scene():
render = bpy.data.scenes.get('Render')
if not render:
render = bpy.data.scenes.new('Render')
render.use_nodes = True
return render
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