add env variable and prefs for tech passes split, and allow customization ofr tech passes split in popup
This commit is contained in:
parent
aa4293c7d7
commit
f95fe2eff7
@ -2,7 +2,7 @@ bl_info = {
|
||||
"name": "Render Toolbox",
|
||||
"description": "Setup outputs and perform cheks for rendering",
|
||||
"author": "Samuel Bernou",
|
||||
"version": (0, 8, 0),
|
||||
"version": (1, 0, 0),
|
||||
"blender": (4, 0, 0),
|
||||
"location": "View3D",
|
||||
"warning": "",
|
||||
|
17
fn.py
17
fn.py
@ -7,6 +7,9 @@ from .constant import TECH_PASS_KEYWORDS
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_addon_prefs():
|
||||
return bpy.context.preferences.addons[__package__].preferences
|
||||
|
||||
# region Manage nodes
|
||||
|
||||
def real_loc(n):
|
||||
@ -208,7 +211,7 @@ def create_and_connect_file_output(node, outputs, file_out, out_name, base_path,
|
||||
|
||||
|
||||
def connect_to_file_output(node_list, file_out=None, base_path='', excludes=None, remap_names=None,
|
||||
file_format=None, split_tech_passes=False, tech_file_format=None, template=None):
|
||||
file_format=None, tech_pass_names=None, tech_file_format=None, template=None):
|
||||
"""Connect selected nodes output to file output(s)
|
||||
if a file output is selected, add intputs on it
|
||||
|
||||
@ -230,8 +233,12 @@ def connect_to_file_output(node_list, file_out=None, base_path='', excludes=None
|
||||
|
||||
remap_names (dict, optionnal): List of output names to remap {node_name: {output_name: new_name}}.
|
||||
|
||||
split_tech_passes (bool, optional): When True, create a separate file output for technical passes
|
||||
Defaults to False.
|
||||
tech_pass_names (list[str], optional): list of of socket names to set as separate file output for technical passes
|
||||
Defaults to None
|
||||
|
||||
tech_file_format (dict, optionnal): converts each dictionary key into a file output format for tech passes
|
||||
if not passed, will use file_format.
|
||||
Defaults to None.
|
||||
|
||||
Returns:
|
||||
list[bpy.types.CompositorNode]: All nodes created.
|
||||
@ -278,9 +285,9 @@ def connect_to_file_output(node_list, file_out=None, base_path='', excludes=None
|
||||
# Categorize outputs
|
||||
crypto_outputs = [o for o in all_outputs if 'crypto' in o.name.lower()]
|
||||
|
||||
if split_tech_passes:
|
||||
if tech_pass_names:
|
||||
# Filter tech passes
|
||||
tech_outputs = [o for o in all_outputs if o.name.lower() in TECH_PASS_KEYWORDS] # any(keyword in o.name.lower() for keyword in TECH_PASS_KEYWORDS)]
|
||||
tech_outputs = [o for o in all_outputs if o.name.lower() in tech_pass_names] # TECH_PASS_KEYWORDS
|
||||
# Regular outputs (excluding crypto and tech passes)
|
||||
regular_outputs = [o for o in all_outputs if o not in crypto_outputs and o not in tech_outputs]
|
||||
else:
|
||||
|
@ -7,9 +7,6 @@ from bpy.props import (StringProperty,
|
||||
EnumProperty,
|
||||
CollectionProperty)
|
||||
|
||||
from ..constant import TECH_PASS_KEYWORDS
|
||||
|
||||
|
||||
class RT_OT_outputs_search_and_replace(bpy.types.Operator):
|
||||
bl_idname = "rt.outputs_search_and_replace"
|
||||
bl_label = "Search And Replace Outputs Paths"
|
||||
|
@ -122,6 +122,7 @@ class RT_PG_selectable_prop(bpy.types.PropertyGroup):
|
||||
socket_name: StringProperty(name="Source socket Name") # Source socket name as reference
|
||||
select: BoolProperty(name="Selected", default=True)
|
||||
is_linked: BoolProperty(name="Linked", default=False)
|
||||
is_tech_pass: BoolProperty(name="Tech Pass", default=False)
|
||||
# is_valid: BoolProperty(name="Valid", default=True)
|
||||
|
||||
## Specific to render layer nodes
|
||||
@ -337,6 +338,14 @@ class RT_OT_create_output_layers(bpy.types.Operator):
|
||||
# self.blend_name = Path(self.blend_name).stem
|
||||
# self.version = fn.get_rightmost_number_in_string(self.blend_name)
|
||||
|
||||
## tech_passes
|
||||
prefs = fn.get_addon_prefs()
|
||||
tech_passes_names = prefs.tech_passes_names
|
||||
if prefs.use_env_technical_passes:
|
||||
tech_passes_names = os.getenv('RENDERTOOLBOX_TECH_PASSES', prefs.tech_passes_names)
|
||||
|
||||
tech_passes_names = [tp.strip().lower() for tp in tech_passes_names.split(',') if tp.strip()]
|
||||
|
||||
selected = [n for n in context.scene.node_tree.nodes if n.select and n.type != 'OUTPUT_FILE']
|
||||
if not selected:
|
||||
self.report({'ERROR'}, 'No render layer nodes selected')
|
||||
@ -382,6 +391,10 @@ class RT_OT_create_output_layers(bpy.types.Operator):
|
||||
item.is_linked = True
|
||||
item.select = False
|
||||
|
||||
if item.socket_name.lower() in tech_passes_names:
|
||||
item.is_tech_pass = True
|
||||
|
||||
|
||||
## Assign default template values (Disabled for now)
|
||||
## TRIGGER update to firstly fill template slot/names
|
||||
# self.template_file_slot = context.scene.render_toolbox.default_file_slot
|
||||
@ -401,7 +414,7 @@ class RT_OT_create_output_layers(bpy.types.Operator):
|
||||
self.scene_name = ref.scene.name
|
||||
self.view_layer_name = ref.layer
|
||||
self.final_base_path_template = ''
|
||||
return context.window_manager.invoke_props_dialog(self, width=500)
|
||||
return context.window_manager.invoke_props_dialog(self, width=530)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -483,8 +496,12 @@ Possible variables:
|
||||
col.prop(self, 'exr_codec')
|
||||
col.row().prop(self, 'color_depth', expand=True)
|
||||
col.prop(self, 'split_tech_passes')
|
||||
if self.split_tech_passes:
|
||||
col.prop(self, 'tech_exr_codec', text='Tech Passes Codec')
|
||||
|
||||
row = col.row()
|
||||
row.prop(self, 'tech_exr_codec', text='Tech Passes Codec')
|
||||
row.active = self.split_tech_passes
|
||||
# if self.split_tech_passes:
|
||||
# col.prop(self, 'tech_exr_codec', text='Tech Passes Codec')
|
||||
|
||||
search_row = layout.row()
|
||||
op = search_row.operator("rt.colprop_search_and_replace", icon='BORDERMOVE')
|
||||
@ -520,6 +537,7 @@ Possible variables:
|
||||
col.label(text=display_node_name, icon='NODE_SEL')
|
||||
|
||||
row = col.row()
|
||||
row.active = item.select
|
||||
if item.is_linked:
|
||||
row.label(text='', icon='LINKED') # NODETREE
|
||||
else:
|
||||
@ -529,7 +547,7 @@ Possible variables:
|
||||
display_name = item.socket_name
|
||||
if 'crypto' in display_name.lower():
|
||||
display_name = f'{display_name} -> 32bit output node'
|
||||
elif self.split_tech_passes and display_name.lower() in TECH_PASS_KEYWORDS:
|
||||
elif self.split_tech_passes and item.is_tech_pass:
|
||||
display_name = f'{display_name} -> Tech pass'
|
||||
|
||||
row.label(text=display_name)
|
||||
@ -546,6 +564,9 @@ Possible variables:
|
||||
elif self.name_type == 'template':
|
||||
row.prop(item, 'name_from_template', text='')
|
||||
|
||||
if self.split_tech_passes:
|
||||
row.prop(item, 'is_tech_pass', text='')
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
# Build exclude dict from selection
|
||||
@ -560,6 +581,8 @@ Possible variables:
|
||||
# elif item.socket_name != item.name:
|
||||
# remap_names[item.socket_name] = item.name
|
||||
|
||||
tech_pass_names = []
|
||||
|
||||
if len(self.socket_collection):
|
||||
for item in self.socket_collection:
|
||||
final_name = item.name
|
||||
@ -580,6 +603,9 @@ Possible variables:
|
||||
remap_names.setdefault(item.node_name, {})[item.socket_name] = final_name
|
||||
# remap_names[item.socket_name] = final_name
|
||||
|
||||
if self.split_tech_passes and item.is_tech_pass:
|
||||
tech_pass_names.append(item.socket_name.lower())
|
||||
|
||||
## Handle default file format
|
||||
file_ext = self.file_format
|
||||
if self.file_format == 'NONE':
|
||||
@ -615,7 +641,7 @@ Possible variables:
|
||||
excludes=excludes,
|
||||
remap_names=remap_names,
|
||||
file_format=file_format,
|
||||
split_tech_passes=self.split_tech_passes,
|
||||
tech_pass_names=tech_pass_names,
|
||||
tech_file_format=tech_file_format,
|
||||
template=self.final_base_path_template)
|
||||
|
||||
|
@ -18,11 +18,12 @@ from bpy.app.handlers import persistent
|
||||
class RT_prefs(bpy.types.AddonPreferences):
|
||||
bl_idname = __package__
|
||||
|
||||
## path templates
|
||||
use_env_base_path_templates : BoolProperty(
|
||||
name="Use Environment Base Path Templates",
|
||||
description="Use environmenet variables to set base path for file output templates\
|
||||
\nFollowing env variable are available:\
|
||||
\nRENDERTOOLBOX_EXR_PATH_TEMPLATE fo single base path file output\
|
||||
\nRENDERTOOLBOX_EXR_PATH_TEMPLATE for single base path file output\
|
||||
\nRENDERTOOLBOX_MULTILAYER_PATH_TEMPLATE for multilayer base path file output",
|
||||
default=True,
|
||||
)
|
||||
@ -39,24 +40,74 @@ class RT_prefs(bpy.types.AddonPreferences):
|
||||
default="//render/{node_label}/{node_label}_",
|
||||
)
|
||||
|
||||
## Tech passes
|
||||
use_env_technical_passes : BoolProperty(
|
||||
name="Use Environment Technical Passes",
|
||||
description="Use environmenet variables to set the technical passes name:\
|
||||
\nRENDERTOOLBOX_TECH_PASSES",
|
||||
default=True,
|
||||
)
|
||||
|
||||
tech_passes_names : StringProperty(
|
||||
name="Tech Passes Names",
|
||||
description="Comma separated list of tech passes names to use for file output creation (Use lossless EXR 32bit)",
|
||||
default="uv, normal, depth, position, vector, ao",
|
||||
)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(self, "use_env_base_path_templates", text="Use Environment Base Path Templates")
|
||||
col = layout.column()
|
||||
col.label(text="Output files path templates:")
|
||||
col.prop(self, "use_env_base_path_templates", text="Use Environment Base Path Templates")
|
||||
# col.active = not self.use_env_base_path_templates
|
||||
col.prop(self, "base_path_template", text="Base Path Template")
|
||||
col.prop(self, "base_path_multilayer_template", text="Base Path Multilayer Template")
|
||||
|
||||
if self.use_env_base_path_templates:
|
||||
col.separator()
|
||||
col.label(text="Environment variables will override above templates if set", icon='INFO')
|
||||
# col.label(text="RENDERTOOLBOX_EXR_PATH_TEMPLATE for single base path file output")
|
||||
# col.label(text="RENDERTOOLBOX_MULTILAYER_PATH_TEMPLATE for multilayer base path file output")
|
||||
col.label(text='If environment variables are not found, preferences will be used instead')
|
||||
box=col.box()
|
||||
boxcol = box.column()
|
||||
env_path_template = os.getenv('RENDERTOOLBOX_EXR_PATH_TEMPLATE')
|
||||
env_multi_template = os.getenv('RENDERTOOLBOX_MULTILAYER_PATH_TEMPLATE')
|
||||
|
||||
if not env_path_template or not env_multi_template:
|
||||
boxcol.label(text="Environment variables override above templates if set", icon='INFO')
|
||||
|
||||
if env_path_template or env_multi_template:
|
||||
boxcol.label(text="Environment variables found:", icon='CHECKMARK')
|
||||
|
||||
if env_path_template:
|
||||
boxcol.label(text=f"RENDERTOOLBOX_EXR_PATH_TEMPLATE:")
|
||||
boxcol.label(text=env_path_template)
|
||||
else:
|
||||
boxcol.label(text="RENDERTOOLBOX_EXR_PATH_TEMPLATE env not found, using preferences ") # (single base path file output)
|
||||
|
||||
if env_multi_template:
|
||||
boxcol.label(text=f"RENDERTOOLBOX_MULTILAYER_PATH_TEMPLATE:")
|
||||
boxcol.label(text=env_multi_template)
|
||||
else:
|
||||
boxcol.label(text="RENDERTOOLBOX_MULTILAYER_PATH_TEMPLATE env not found, using preferences") # (multilayer base path file output)
|
||||
|
||||
layout.separator()
|
||||
col = layout.column()
|
||||
col.label(text="Default Separated Technical Passes:")
|
||||
col.prop(self, "use_env_technical_passes", text="Use Environment Technical Passes")
|
||||
|
||||
col.prop(self, "tech_passes_names", text="Technical Passes Names", placeholder="e.g. uv, normal, depth, vector, ...")
|
||||
if self.use_env_technical_passes:
|
||||
box=col.box()
|
||||
boxcol = box.column()
|
||||
|
||||
env_tech_pass = os.getenv('RENDERTOOLBOX_TECH_PASSES')
|
||||
if env_tech_pass:
|
||||
boxcol.label(text="Environment variable found:", icon='CHECKMARK')
|
||||
boxcol.label(text=f"RENDERTOOLBOX_TECH_PASSES:")
|
||||
boxcol.label(text=env_tech_pass)
|
||||
else:
|
||||
boxcol.label(text="Environment variable override tech passes names if set", icon='INFO')
|
||||
boxcol.label(text='RENDERTOOLBOX_TECH_PASSES env not found, using preferences')
|
||||
|
||||
# region Handlers
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user