gp_render/OP_merge_layers.py

178 lines
5.5 KiB
Python
Raw Normal View History

2021-09-07 18:06:54 +02:00
import bpy
from . import fn
2021-09-07 18:06:54 +02:00
def merge_layers(rlayers, obname=None, active=None):
2021-09-07 18:06:54 +02:00
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
2021-09-07 18:06:54 +02:00
# change colors of those nodes
color = fn.random_color()
2021-09-07 18:06:54 +02:00
for n in rlayers:
n.use_custom_color = True
n.color = color
obname, lname = vl_name.split(' / ')
lname = bpy.path.clean_name(lname)
2021-09-07 18:06:54 +02:00
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)
2021-09-07 18:06:54 +02:00
if not ngroup:
# delete and recreate ?
print(f'create nodegroup {ng_name}')
ngroup = bpy.data.node_groups.new(ng_name, 'CompositorNodeTree')
2021-09-07 18:06:54 +02:00
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))
"""
2021-09-07 18:06:54 +02:00
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
"""
2021-09-07 18:06:54 +02:00
##
# 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
2021-09-07 18:06:54 +02:00
if len(layer_names) < 2:
print(f'Should select multiple layers for merging')
return
2021-09-07 18:06:54 +02:00
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
2021-09-07 18:06:54 +02:00
nodes = render.node_tree.nodes
selection = [n for n in nodes if n.select and n.type == 'R_LAYERS']
2021-09-07 18:06:54 +02:00
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'}
2021-09-07 18:06:54 +02:00
# 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')
2021-09-07 18:06:54 +02:00
# obname = selection[0].layer.split('.')[0]
merge_layers(selection, nodes.active)
2021-09-07 18:06:54 +02:00
return {"FINISHED"}
2021-09-07 18:06:54 +02:00
classes=(
GPEXP_OT_merge_selected_dopesheet_layers,
GPEXP_OT_merge_selected_viewlayer_nodes,
)
2021-09-07 18:06:54 +02:00
def register():
for cls in classes:
bpy.utils.register_class(cls)
2021-09-07 18:06:54 +02:00
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)