gp_render/OP_connect_toggle.py

149 lines
4.9 KiB
Python
Raw Normal View History

import bpy
from . import fn
class GPEXP_OT_reconnect_render_layer(bpy.types.Operator):
bl_idname = "gp.reconnect_render_layer"
bl_label = "Reconnect Render Layer"
bl_description = "Reconnect selected render layers"
bl_options = {"REGISTER"}
@classmethod
def poll(cls, context):
return True
# mode : bpy.props.StringProperty(default='NORMAL', options={'SKIP_SAVE'})
def execute(self, context):
node_tree = context.scene.node_tree
nodes = node_tree.nodes
changed = []
for n in nodes:
if not n.select or not n.type == 'R_LAYERS':
continue
if not ' / ' in n.layer:
continue
if n.outputs[0].is_linked: # already connected
continue
# get namme
obname = n.layer.split()[0]
grp_name = f'NG_{obname}'
# get nodegroup
grp = nodes.get(grp_name)
if not grp:
print(f'{n.name} Node group not found : {n.layer} !-> {grp_name}')
continue
inp = grp.inputs.get(n.layer)
if not inp:
print(f'{n.name} no inputs name "{n.layer}" in group {grp_name}')
continue
# reconnect
node_tree.links.new(n.outputs[0], inp)
changed.append(f'{n.name} ({n.layer}) to {grp_name}')
if changed:
self.report({'INFO'}, f'{len(changed)} nodes reconnected')
else:
self.report({'WARNING'}, f'Could not reconnect, see console')
return {"FINISHED"}
class GPEXP_OT_delete_render_layer(bpy.types.Operator):
bl_idname = "gp.delete_render_layer"
bl_label = "Delete Render Layer"
bl_description = "Delete selected render layers"
bl_options = {"REGISTER"}
@classmethod
def poll(cls, context):
return True
# mode : bpy.props.StringProperty(default='NORMAL', options={'SKIP_SAVE'})
def execute(self, context):
rd_scn = bpy.data.scenes.get('Render')
if not rd_scn:
self.report({'ERROR'}, 'Viewlayers needs to be generated first!')
return {'CANCELLED'}
nodes = rd_scn.node_tree.nodes
# list layers and viewlayers
# vls = [rd_scn.view_layers.get(l.viewlayer_render) for l in layers
# if l.viewlayer_render and l.viewlayer_render != act.viewlayer_render and rd_scn.view_layers.get(l.viewlayer_render)]
rlayers_nodes = [n for n in nodes if n.select and n.type == 'R_LAYERS']
vls = [rd_scn.view_layers.get(n.layer) for n in rlayers_nodes if rd_scn.view_layers.get(n.layer)]
vl_names = [v.name for v in vls]
## disable layers using those VL
for ob in [o for o in rd_scn.objects if o.type == 'GPENCIL']:
for l in ob.data.layers:
if l.viewlayer_render in vl_names:
l.viewlayer_render = fn.get_view_layer('exclude').name
for n in reversed(rlayers_nodes):
# Disconnect linked
for lnk in n.outputs[0].links:
grp = lnk.to_node
if grp.type != 'GROUP':
continue
if not grp.name.startswith('NG'):
continue
sockin = lnk.to_socket
sockout = grp.outputs.get(sockin.name)
if not sockout:
continue
for grplink in sockout.links:
if grplink.to_node.type != 'OUTPUT_FILE':
continue
fo_socket = grplink.to_socket
fo = grplink.to_node
fo.file_slots.remove(fo_socket)
inside_nodes = []
ngroup = grp.node_tree
for i in range(len(grp.inputs))[::-1]:
if grp.inputs[i].name == sockin.name:
ngroup.inputs.remove(ngroup.inputs[i])
gp_in_socket = ngroup.nodes['Group Input'].outputs[i]
for lnk in gp_in_socket.links:
inside_nodes += fn.all_connected_forward(lnk.to_node)
list(set(inside_nodes))
break
for i in range(len(grp.outputs))[::-1]:
if grp.outputs[i].name == sockout.name:
ngroup.outputs.remove(ngroup.outputs[i])
break
for sub_n in reversed(inside_nodes):
ngroup.nodes.remove(sub_n)
# remove render_layer node
rd_scn.node_tree.nodes.remove(n)
return {"FINISHED"}
classes=(
GPEXP_OT_reconnect_render_layer,
GPEXP_OT_delete_render_layer,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)