178 lines
5.5 KiB
Python
178 lines
5.5 KiB
Python
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) |