gp_render/OP_clean.py

139 lines
4.7 KiB
Python

import bpy
from . import fn
class GPEXP_OT_clean_compo_tree(bpy.types.Operator):
bl_idname = "gp.clean_compo_tree"
bl_label = "Clean Compo Tree"
bl_description = "Pop up menu with cleaning options"
bl_options = {"REGISTER", "UNDO"}
# Internal prop (use when launching from python)
use_render_scene : bpy.props.BoolProperty(name="Use Render Scene",
description="Force the clean on scene named Render, abort if not exists (not exposed)",
default=False, options={'SKIP_SAVE'})
clear_unused_view_layers : bpy.props.BoolProperty(name="Clear unused view layers",
description="Delete view layer that aren't used in the nodetree anymore",
default=True)
arrange_rl_nodes : bpy.props.BoolProperty(name="Arrange Render Node In Frames",
description="Re-arrange Render Layer Nodes Y positions within each existing frames" ,
default=True)
arrange_frames : bpy.props.BoolProperty(name="Arrange Frames",
description="Re-arrange all frames Y positions" ,
default=True)
reorder_inputs : bpy.props.BoolProperty(name="Reorder I/O Sockets",
description="Reorder inputs/outputs of all 'NG_' nodegroup and their connected file output",
default=True)
clear_isolated_node_in_groups : bpy.props.BoolProperty(name="Clear Isolated Node In Groups",
description="Clean content of 'NG_' nodegroup bpy deleting isolated nodes)",
default=True)
fo_clear_disconnected : bpy.props.BoolProperty(name="Remove Disconnected Export Inputs",
description="Clear any disconnected intput of every 'file output' node",
default=False)
@classmethod
def poll(cls, context):
return True
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
layout.prop(self, 'clear_unused_view_layers')
layout.prop(self, 'arrange_rl_nodes')
layout.prop(self, 'arrange_frames')
layout.prop(self, 'reorder_inputs')
layout.prop(self, 'clear_isolated_node_in_groups')
layout.separator()
layout.prop(self, 'fo_clear_disconnected')
if self.fo_clear_disconnected:
layout.label(text='Disconnected inputs are not exported', icon='INFO')
# box = layout.box()
# box.prop(self, 'arrange_frames')
# box.prop(self, 'reorder_inputs')
# box.prop(self, 'fo_clear_disconnected')
def execute(self, context):
if self.use_render_scene:
render = bpy.data.scenes.get('Render')
if not render:
print('SKIP clean_compo_tree, No "Render" scene !')
return {"CANCELLED"}
else:
render = context.scene
nodes = render.node_tree.nodes
for n in nodes:
n.update()
if self.clear_unused_view_layers:
used_rlayer_names = [n.layer for n in nodes if n.type == 'R_LAYERS']
for rl in reversed(render.view_layers):
if rl.name in used_rlayer_names or rl.name == 'View Layer':
continue
render.view_layers.remove(rl)
if self.arrange_rl_nodes:
fn.rearrange_rlayers_in_frames(render.node_tree)
if self.arrange_frames:
fn.rearrange_frames(render.node_tree)
if self.reorder_inputs:
for n in nodes:
if n.type != 'GROUP' or not n.name.startswith('NG_'):
continue
fn.reorder_inputs(n)
fn.reorder_outputs(n)
# get output node to reorder output
out = None
for s in n.outputs:
if not s.is_linked:
continue
out = s.links[0].to_node
if out.type == 'OUTPUT_FILE':
break
if out:
fn.reorder_fileout(out, ng=n)
# Clear input that do not exists
fn.clean_nodegroup_inputs(n, skip_existing_pass=True)
fn.bridge_reconnect_nodegroup(n)
if self.clear_isolated_node_in_groups:
for n in nodes:
if n.type != 'GROUP' or not n.name.startswith('NG_'):
continue
fn.clear_nodegroup_content_if_disconnected(n.node_tree)
if self.fo_clear_disconnected:
for fo in nodes:
if fo.type != 'OUTPUT_FILE':
continue
fn.clear_disconnected(fo)
return {"FINISHED"}
classes=(
GPEXP_OT_clean_compo_tree,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)