Migrate Fileoutput and viewlayer management ops from gp_render

Better overall UI.
Split file output in a separate panel
This commit is contained in:
pullusb
2025-07-30 18:16:32 +02:00
parent 422574f1bf
commit b6b090d4ea
5 changed files with 327 additions and 47 deletions
+155 -14
View File
@@ -4,6 +4,41 @@ from bpy.types import Panel
from . import fn
# region viewlayer layout
def viewlayer_layout(layout, scn):
for vl in scn.view_layers:
row = layout.row()
row.prop(vl, 'use', text=vl.name, icon='RESTRICT_RENDER_OFF' if vl.use else 'RESTRICT_RENDER_ON', emboss=False, toggle=0)
class RT_PT_viewlayers_ui(Panel):
bl_space_type = "NODE_EDITOR"
bl_region_type = "UI"
bl_label = "View Layers"
def draw(self, context):
layout = self.layout
layout.label(text=f'{context.scene.name} :: View layers')
col = layout.column(align=True)
viewlayer_layout(col, context.scene)
class RT_PT_viewlayers_multi_ui(Panel):
bl_space_type = "NODE_EDITOR"
bl_region_type = "UI"
bl_label = "Multi View Layers"
def draw(self, context):
layout = self.layout
layout.label(text=f'{len(bpy.data.scenes)} scenes view layers:')
for s in bpy.data.scenes:
col = layout.column()
# col.label(text=f'{s.name}:')
col.label(text=s.name)
viewlayer_layout(col, s)
layout.separator()
# region main panel
class RT_PT_render_toolbox_ui(Panel):
bl_space_type = "NODE_EDITOR"
bl_region_type = "UI"
@@ -12,10 +47,106 @@ class RT_PT_render_toolbox_ui(Panel):
def draw(self, context):
layout = self.layout
layout.operator("rt.create_output_layers", icon="NODE")
layout.operator("rt.outputs_search_and_replace", text='Search and replace outputs', icon="BORDERMOVE")
# layout.separator()
## Scene infos recap
scn = context.scene
text = f'{scn.render.resolution_x}x{scn.render.resolution_y} @ {scn.render.fps} fps'
cam = context.scene.camera
if cam:
text = f'{cam.name} : {text}'
else:
text = f'No Camera ! : {text}'
box = layout.box()
col = box.column()
col.label(text=text, icon='SCENE_DATA') # VIEW_CAMERA
# col.label(text=f"{scn.render.fps} fps")
if scn.render.resolution_percentage != 100:
col.label(text='Percentage not 100%', icon='INFO')
col.prop(scn.render, 'resolution_percentage', text="Resolution Percentage")
percent = scn.render.resolution_percentage
col.label(text=f"{int(scn.render.resolution_x * percent / 100)}x{int(scn.render.resolution_y * percent / 100)}", icon='INFO')
if cam and cam.data.shift_x != 0 or cam.data.shift_y != 0:
col.label(text='Camera has Shift', icon='INFO')
# col.prop(cam.data, 'shift_x', text="Shift X")
# col.prop(cam.data, 'shift_y', text="Shift Y")
## viewlayer section
layout.label(text='View layers:')
ct = len([n for n in context.scene.node_tree.nodes if n.type == 'R_LAYERS' and n.select])
# col = layout.column(align=True)
# row=col.row(align=True)
col = layout.column(align=False)
row = col.row(align=True)
row.operator("wm.call_panel", text="View layers", icon='RENDERLAYERS').name = "RT_PT_viewlayers_ui"
row.operator("wm.call_panel", text="All View layers", icon='SCENE_DATA').name = "RT_PT_viewlayers_multi_ui"
# row=layout.row(align=True)
row1 = col.row(align=True)
row1.operator('rt.activate_only_selected_layers', text=f'Activate Only {ct} RenderLayer Nodes')
row1.enabled = ct > 0
exclude_count = len([vl for vl in scn.view_layers if not vl.use and vl.name not in {'exclude',}]) # 'View Layer',
if exclude_count:
# layout.label(text=f'{exclude_count} Excluded View Layers !')
layout.operator('rt.enable_all_viewlayers', text=f'Reactivate {exclude_count} Excluded View Layers')
# col = layout.column()
# col.label(text='Clean and updates:')
# col.operator('rt.clean_compo_tree', icon='BRUSHES_ALL', text='Clean Nodes') # NODE_CORNER
# region file output ui
class RT_PT_file_output_ui(bpy.types.Panel):
bl_space_type = "NODE_EDITOR"
bl_region_type = "UI"
bl_category = "Render"
bl_label = "File Output Manager"
# bl_parent_id = "RT_PT_render_toolbox_ui"
def draw(self, context):
layout = self.layout
col = layout.column()
col.operator("rt.create_output_layers", text='Create File Output', icon="NODE")
col.operator("rt.outputs_search_and_replace", text='Search And Replace Outputs', icon="BORDERMOVE")
col.separator()
col.operator('rt.set_output_node_format', icon='OUTPUT', text='Copy Output Format To Selected')
col.operator('rt.set_active_file_output_slot_to_composite', icon='OUTPUT', text='Active Slot To Composite')
layout.label(text='All Outputs:')
row=layout.row(align=True)
row.operator('rt.mute_toggle_output_nodes', icon='NODE_INSERT_ON', text='Mute').mute = True
row.operator('rt.mute_toggle_output_nodes', icon='NODE_INSERT_OFF', text='Unmute').mute = False
scn = context.scene
disabled_output = [n for n in scn.node_tree.nodes if n.type == 'OUTPUT_FILE' and n.mute]
if disabled_output:
output_ct = len([n for n in scn.node_tree.nodes if n.type == 'OUTPUT_FILE'])
layout.label(text=f'{len(disabled_output)}/{output_ct} Output Muted', icon='INFO')
col = layout.column()
## (re)number exports
ct = len([n for n in context.scene.node_tree.nodes if n.type == 'OUTPUT_FILE' and n.select])
txt = f'Renumber {ct} Selected Outputs'
subcol = col.column()
subcol.enabled = bool(ct)
row = subcol.row(align=True)
row.operator('rt.number_outputs', icon='LINENUMBERS_ON', text=txt).mode = 'SELECTED'
op = row.operator('rt.number_outputs', icon='X', text='')
op.mode = 'SELECTED'
op.clear = True
# region visibility ui
# Base panel for drawing
class RT_PT_visibility_check_ui_base(bpy.types.Panel):
@@ -31,13 +162,14 @@ class RT_PT_visibility_check_ui_base(bpy.types.Panel):
def draw(self, context):
layout = self.layout
# layout.label(text="Visibily Checks:")
layout.operator("rt.list_object_visibility_conflicts", icon="OBJECT_DATAMODE")
layout.operator("rt.list_viewport_render_visibility", text="List Viewport Vs Render Visibility", icon="OBJECT_DATAMODE")
layout.operator("rt.list_modifier_visibility", text="List Modifiers Visibility Conflicts", icon="MODIFIER")
layout.operator("rt.list_collection_visibility_conflicts", text="List Collections Visibility Conflicts", icon="OUTLINER_COLLECTION")
col = layout.column(align=True)
col .label(text="List Visibility Conflicts:") # , icon='HIDE_OFF'
row = col.row(align=True)
row.operator("rt.list_object_visibility_conflicts", text="Objects", icon="OBJECT_DATAMODE")
row.operator("rt.list_viewport_render_visibility", text="Viewport Vs Render") # , icon="OBJECT_DATAMODE"
col.operator("rt.list_modifier_visibility", text="Modifiers", icon="MODIFIER")
col.operator("rt.list_collection_visibility_conflicts", text="Collections", icon="OUTLINER_COLLECTION")
layout.separator()
layout.operator("rt.list_object_affected_by_simplify", text="List Object Affected By Simplify", icon="MOD_SIMPLIFY")
@@ -53,6 +185,8 @@ class RT_PT_visibility_check_ui_node(RT_PT_visibility_check_ui_base):
bl_region_type = 'UI'
bl_category = "Render" # Wrangler ?
# region conformation ui
class RT_PT_conformation_ui(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
@@ -100,7 +234,9 @@ class RT_PT_conformation_ui(bpy.types.Panel):
# tgt_row = layout.row(align=True)
# tgt_row.label(text="", icon='TRIA_RIGHT')
tgt_row.label(text=ref_collection.name, icon='OUTLINER_COLLECTION')
col.operator("rt.store_visibility_states", text='Store target State', icon="DISK_DRIVE")
col = layout.column(align=False)
col.operator("rt.store_visibility_states", text='Store Target Hierarchy State', icon="DISK_DRIVE")
## Show current collection state (behave badly when changed, should be tweaked before)
# col = layout.column(align=True)
@@ -118,7 +254,7 @@ class RT_PT_conformation_ui(bpy.types.Panel):
col = layout.column(align=True)
row = col.row(align=True)
row.label(text="Parameter To Conform:")
row.label(text="To Conform:")
## Same order, greyout unused options
collec_row = row.row(align=True)
collec_row.prop(props, "conform_exclude", text="", icon='CHECKBOX_DEHLT' if ref_vlc.exclude else 'CHECKBOX_HLT') # Exclude from View Layer
@@ -148,7 +284,7 @@ class RT_PT_conformation_ui(bpy.types.Panel):
tgt_row.label(text=ref_obj.name, icon='OBJECT_DATA')
if not ref_obj.children_recursive:
tgt_row.label(text="Object has no children", icon='ERROR')
tgt_row.label(text="No Children", icon='ERROR')
return
layout.separator()
@@ -165,7 +301,7 @@ class RT_PT_conformation_ui(bpy.types.Panel):
layout.separator()
col = layout.column(align=True)
row = col.row(align=True)
row.label(text="Parameter To Conform:")
row.label(text="To Conform:")
row.prop(props, "conform_selectability", text="", icon='RESTRICT_SELECT_ON' if ref_obj.hide_select else 'RESTRICT_SELECT_OFF') # Hide Select
row.prop(props, "conform_viewlayer", text="", icon='HIDE_ON' if ref_obj.hide_get() else 'HIDE_OFF') # Hide in current viewlayer (eye)
row.prop(props, "conform_viewport", text="", icon='RESTRICT_VIEW_ON' if ref_obj.hide_viewport else 'RESTRICT_VIEW_OFF') # Disable in Viewports
@@ -175,6 +311,8 @@ class RT_PT_conformation_ui(bpy.types.Panel):
layout.operator("rt.conform_collection_hierarchy",text="Conform Hierarchy", icon="CHECKMARK")
# region outliner state
class RT_PT_outliner_state_ui(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
@@ -235,7 +373,10 @@ class RT_PT_outliner_state_ui(bpy.types.Panel):
classes = (
RT_PT_viewlayers_ui,
RT_PT_viewlayers_multi_ui,
RT_PT_render_toolbox_ui,
RT_PT_file_output_ui,
RT_PT_visibility_check_ui_viewport,
RT_PT_visibility_check_ui_node,
RT_PT_conformation_ui,