Migrate Fileoutput and viewlayer management ops from gp_render
Better overall UI. Split file output in a separate panel
This commit is contained in:
@@ -3,6 +3,7 @@ from . import (
|
||||
output_search_and_replace,
|
||||
output_setup,
|
||||
output_management,
|
||||
viewlayer_management,
|
||||
visibility_conflicts,
|
||||
simplify_conflicts,
|
||||
store_visibility_states,
|
||||
@@ -15,6 +16,7 @@ mods = (
|
||||
output_setup,
|
||||
output_search_and_replace,
|
||||
output_management,
|
||||
viewlayer_management,
|
||||
visibility_conflicts,
|
||||
simplify_conflicts,
|
||||
store_visibility_states,
|
||||
|
||||
@@ -6,6 +6,7 @@ from bpy.props import (StringProperty,
|
||||
BoolProperty,
|
||||
)
|
||||
|
||||
from .. import fn
|
||||
|
||||
# region renumber outputs
|
||||
|
||||
@@ -177,7 +178,7 @@ def renumber_keep_existing(fo, offset=10, invert=True):
|
||||
if invert:
|
||||
reverse_fileout_inputs(fo)
|
||||
|
||||
class RT_OT_number_outputs(bpy.types.Operator):
|
||||
class RT_OT_number_outputs(Operator):
|
||||
bl_idname = "rt.number_outputs"
|
||||
bl_label = "Number Outputs"
|
||||
bl_description = "(Re)Number the outputs to have ordered file by name in export directories\
|
||||
@@ -225,7 +226,7 @@ class RT_OT_number_outputs(bpy.types.Operator):
|
||||
# region file output
|
||||
|
||||
|
||||
class RT_OT_mute_toggle_output_nodes(bpy.types.Operator):
|
||||
class RT_OT_mute_toggle_output_nodes(Operator):
|
||||
bl_idname = "rt.mute_toggle_output_nodes"
|
||||
bl_label = "Mute Toggle output nodes"
|
||||
bl_description = "Mute / Unmute all output nodes"
|
||||
@@ -246,10 +247,10 @@ class RT_OT_mute_toggle_output_nodes(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RT_OT_set_output_node_format(bpy.types.Operator):
|
||||
class RT_OT_set_output_node_format(Operator):
|
||||
bl_idname = "rt.set_output_node_format"
|
||||
bl_label = "Set output format from active"
|
||||
bl_description = "Change all selected output node to match active output node format"
|
||||
bl_label = "Set file output node format from active"
|
||||
bl_description = "Change all selected file output node format to match active"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
mute : BoolProperty(default=True, options={'SKIP_SAVE'})
|
||||
@@ -292,50 +293,94 @@ class RT_OT_set_output_node_format(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
# region view layers
|
||||
|
||||
class RT_OT_enable_all_viewlayers(bpy.types.Operator):
|
||||
bl_idname = "rt.enable_all_viewlayers"
|
||||
bl_label = "Enable All Viewlayers"
|
||||
bl_description = "Enable all View layers except those named 'exclude' 'View Layer'"
|
||||
class RT_OT_set_active_file_output_slot_to_composite(bpy.types.Operator):
|
||||
bl_idname = "rt.set_active_file_output_slot_to_composite"
|
||||
bl_label = "Set Active File Output Slot To Composite"
|
||||
bl_description = "Use active slot of active file output node to set scene output settings (swap connection)"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.use_nodes\
|
||||
and context.scene.node_tree\
|
||||
and context.scene.node_tree.nodes.active\
|
||||
and context.scene.node_tree.nodes.active.type == 'OUTPUT_FILE'
|
||||
|
||||
vl_list = [vl for vl in scn.view_layers if not vl.use and vl.name not in {'View Layer', 'exclude'}]
|
||||
for v in vl_list:
|
||||
v.use = True
|
||||
relink_composite : bpy.props.BoolProperty(
|
||||
name='Relink Composite',
|
||||
default=True,
|
||||
description='In case file slot is linked, swap link to Composite file',
|
||||
options={'SKIP_SAVE'},
|
||||
)
|
||||
|
||||
self.report({"INFO"}, f'{len(vl_list)} ViewLayers Reactivated')
|
||||
return {"FINISHED"}
|
||||
def invoke(self, context, event):
|
||||
self.fo = context.scene.node_tree.nodes.active
|
||||
if not len(self.fo.file_slots):
|
||||
self.report({'ERROR'}, 'no slots in active file output')
|
||||
return {'CANCELLED'}
|
||||
|
||||
class RT_OT_activate_only_selected_layers(bpy.types.Operator):
|
||||
bl_idname = "rt.activate_only_selected_layers"
|
||||
bl_label = "Activate Only Selected Layers"
|
||||
bl_description = "Activate only selected node view layer , excluding all others"
|
||||
bl_options = {"REGISTER"}
|
||||
# check if active slot has a source
|
||||
if not self.fo.inputs[self.fo.active_input_index].is_linked:
|
||||
return self.execute(context)
|
||||
|
||||
# check if composite linked
|
||||
out = context.scene.node_tree.nodes.get('Composite')
|
||||
if not out or not out.inputs[0].is_linked:
|
||||
self.compo_out_from_link = ''
|
||||
return self.execute(context)
|
||||
|
||||
# compo linked, pop panel to choose replace or not
|
||||
self.compo_out_from_link = out.inputs[0].links[0].from_node.name
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.label(text=f'Composite node connected to: {self.compo_out_from_link}')
|
||||
col.label(text=f'Would you like to replace by file output slot source ?')
|
||||
layout.prop(self, 'relink_composite')
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
# if comp
|
||||
fn.set_scene_output_from_active_fileout_item()
|
||||
idx = self.fo.active_input_index
|
||||
sl = self.fo.file_slots[idx]
|
||||
sk = self.fo.inputs[idx]
|
||||
|
||||
nodes = scn.node_tree.nodes
|
||||
if not sk.is_linked:
|
||||
self.report({'INFO'}, f'Outut changed to match {sl.path} (slot was not linked)')
|
||||
return {'FINISHED'}
|
||||
|
||||
rlayers_nodes = [n for n in nodes if n.select and n.type == 'R_LAYERS']
|
||||
vls = [scn.view_layers.get(n.layer) for n in rlayers_nodes if scn.view_layers.get(n.layer)]
|
||||
for v in scn.view_layers:
|
||||
v.use = v in vls
|
||||
## If linked replace links to Composite node
|
||||
if not self.relink_composite:
|
||||
return {'FINISHED'}
|
||||
|
||||
ntree = context.scene.node_tree
|
||||
links = context.scene.node_tree.links
|
||||
nodes = context.scene.node_tree.nodes
|
||||
|
||||
out = nodes.get('Composite')
|
||||
if not out:
|
||||
out = fn.create_node('COMPOSITE', tree=ntree)
|
||||
fo_loc = fn.real_loc(self.fo)
|
||||
out.location = (fo_loc.x, fo_loc.y + 160)
|
||||
|
||||
# if out.inputs[0].is_linked:
|
||||
# self.report({'WARNING'}, f'Outut changed to match {sl.path} (Composite node already linked)')
|
||||
|
||||
lnk = sk.links[0]
|
||||
from_sk = sk.links[0].from_socket
|
||||
links.remove(lnk)
|
||||
links.new(from_sk, out.inputs[0])
|
||||
|
||||
self.report({"INFO"}, f'Now only {len(vls)} viewlayer active (/{len(scn.view_layers)})')
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
classes = (
|
||||
RT_OT_number_outputs,
|
||||
RT_OT_mute_toggle_output_nodes,
|
||||
RT_OT_set_output_node_format,
|
||||
RT_OT_enable_all_viewlayers,
|
||||
RT_OT_activate_only_selected_layers
|
||||
RT_OT_set_active_file_output_slot_to_composite,
|
||||
)
|
||||
|
||||
def register():
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import bpy
|
||||
|
||||
from bpy.types import Operator
|
||||
from bpy.props import (StringProperty,
|
||||
BoolProperty,
|
||||
)
|
||||
|
||||
class RT_OT_enable_all_viewlayers(Operator):
|
||||
bl_idname = "rt.enable_all_viewlayers"
|
||||
bl_label = "Enable All Viewlayers"
|
||||
bl_description = "Enable all View layers except those named 'exclude'" # 'View Layer'
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
|
||||
vl_list = [vl for vl in scn.view_layers if not vl.use and vl.name not in {'exclude',}] # 'View Layer',
|
||||
for v in vl_list:
|
||||
v.use = True
|
||||
|
||||
self.report({"INFO"}, f'{len(vl_list)} ViewLayers Reactivated')
|
||||
return {"FINISHED"}
|
||||
|
||||
class RT_OT_activate_only_selected_layers(Operator):
|
||||
bl_idname = "rt.activate_only_selected_layers"
|
||||
bl_label = "Activate Only Selected Layers"
|
||||
bl_description = "Activate only selected node view layer , excluding all others"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
|
||||
nodes = scn.node_tree.nodes
|
||||
|
||||
rlayers_nodes = [n for n in nodes if n.select and n.type == 'R_LAYERS']
|
||||
vls = [scn.view_layers.get(n.layer) for n in rlayers_nodes if scn.view_layers.get(n.layer)]
|
||||
for v in scn.view_layers:
|
||||
v.use = v in vls
|
||||
|
||||
self.report({"INFO"}, f'Now only {len(vls)} viewlayer active (/{len(scn.view_layers)})')
|
||||
return {"FINISHED"}
|
||||
|
||||
classes = (
|
||||
RT_OT_enable_all_viewlayers,
|
||||
RT_OT_activate_only_selected_layers
|
||||
)
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
Reference in New Issue
Block a user