213 lines
7.3 KiB
Python
Executable File
213 lines
7.3 KiB
Python
Executable File
import bpy
|
|
import os
|
|
|
|
from bpy.types import PropertyGroup
|
|
from bpy.props import (BoolProperty,
|
|
EnumProperty,
|
|
PointerProperty,
|
|
CollectionProperty,
|
|
StringProperty)
|
|
|
|
|
|
# region template props
|
|
class RT_PG_render_toolbox_props(PropertyGroup):
|
|
default_base_path : StringProperty(
|
|
name="Base Path Template",
|
|
description="Template for file output base path\
|
|
\nFolder containing subsequent filepath",
|
|
default="//render/{node_label}/",
|
|
# options={'SKIP_SAVE'}
|
|
)
|
|
|
|
## Multilayer base path : output on file instead of folder
|
|
default_multilayer_base_path : StringProperty(
|
|
name="Base Path Template",
|
|
description="Template for multilayer file output base paths\
|
|
\nOutput of the file sequence",
|
|
default="//render/{node_label}/{node_label}_",
|
|
# options={'SKIP_SAVE'}
|
|
)
|
|
|
|
### file slots (not used currently)
|
|
|
|
default_file_slot : StringProperty(
|
|
name="File Slot Template",
|
|
description="Template for file output file slots\
|
|
\nSubpath added to base path for file sequence",
|
|
default="{socket_name}/{socket_name}_",
|
|
# options={'SKIP_SAVE'}
|
|
)
|
|
|
|
## Multilayer's layer: layer name in EXR instead of subpath to file
|
|
default_multilayer_name : StringProperty(
|
|
name="Layer Name Template",
|
|
description="Template for multilayer file output layer names\
|
|
\nLayer name in EXR multilayer file",
|
|
default="{socket_name}",
|
|
# options={'SKIP_SAVE'}
|
|
)
|
|
|
|
# default_tech_pass_name : StringProperty(
|
|
# name="Tech Pass Name Template",
|
|
# description="Template for tech pass file output layer names\
|
|
# \nLayer name in EXR multilayer file",
|
|
# default="tech",
|
|
# # options={'SKIP_SAVE'}
|
|
# )
|
|
|
|
# default_crypto_name : StringProperty(
|
|
# name="Crypto Pass Name Template",
|
|
# description="Template for crypto pass file output layer names\
|
|
# \nLayer name in EXR multilayer file",
|
|
# default="crypto",
|
|
# # options={'SKIP_SAVE'}
|
|
# )
|
|
|
|
# endregion
|
|
|
|
# region visibility states
|
|
|
|
def name_search_callback(self, context, edit_text):
|
|
"""Search callback for collection names"""
|
|
## second arg is not displayed, can be and empty string...
|
|
if self.hierarchy_type == 'COLLECTION':
|
|
return [(c.name, '') for c in bpy.context.scene.collection.children_recursive if edit_text.lower() in c.name.lower()]
|
|
else:
|
|
return [(o.name, '') for o in bpy.context.scene.collection.all_objects if edit_text.lower() in o.name.lower()]
|
|
|
|
class RT_PG_render_toolbox_conform_props(PropertyGroup):
|
|
hierarchy_type: EnumProperty(
|
|
name="Hierarchy Type",
|
|
description="Choose whether to conform object hierarchy or collection hierarchy",
|
|
items=(
|
|
('COLLECTION', "Collection Hierarchy", "Conform collection hierarchy"),
|
|
('OBJECT', "Object Hierarchy", "Conform object hierarchy"),
|
|
),
|
|
default='COLLECTION'
|
|
)
|
|
|
|
## Utility prop : expose and control view layer hide state for active object
|
|
## just used for the update (actual bool value means nothing)
|
|
## can also use RT_PG_object_visibility from vis_conflict ops
|
|
## TODO: make an ops for this instead ?
|
|
# active_object_viewlayer_hide : BoolProperty(
|
|
# name="Active Object View Layer Hide",
|
|
# description="show / hide active object in current viewlayer",
|
|
# default=True,
|
|
# update=toggle_viewlayer_hide_state
|
|
# )
|
|
|
|
target_name: StringProperty(
|
|
name="Root Item",
|
|
description="Collection or object to target", # or object name # (useful for excluded collections)
|
|
default="",
|
|
search=name_search_callback
|
|
## basic collection fetch:
|
|
# search=lambda self, context, edit_text: [(c.name, '') for c in bpy.context.scene.collection.children_recursive if edit_text.lower() in c.name.lower()]
|
|
)
|
|
|
|
affect_target: EnumProperty(
|
|
name="Affect Target",
|
|
description="Choose whether to affect collections, objects, or both",
|
|
items=[
|
|
('COLLECTION', "Collection", "Affect collections only"),
|
|
('OBJECT', "Object", "Affect objects only"),
|
|
('ALL', "All", "Affect both collections and objects")
|
|
],
|
|
default='ALL'
|
|
)
|
|
|
|
## Common object and collection
|
|
|
|
conform_selectability: BoolProperty(
|
|
name="Hide Select State",
|
|
description="Conform hide select select",
|
|
default=False
|
|
)
|
|
|
|
conform_viewlayer: BoolProperty(
|
|
name="Hide in Viewlayer State",
|
|
description="Conform viewlayer temporary hide",
|
|
default=True
|
|
)
|
|
|
|
conform_viewport: BoolProperty(
|
|
name="Disable in Viewports State",
|
|
description="Conform the monitor icon (global viewport disable)",
|
|
default=False
|
|
)
|
|
|
|
conform_render: BoolProperty(
|
|
name="Disable in Renders State",
|
|
description="Conform the camera icon (render visibility)",
|
|
default=False
|
|
)
|
|
|
|
## Specific to collections
|
|
|
|
conform_exclude: BoolProperty(
|
|
name="Exclude View Layer State",
|
|
description="Conform the exclude from view layer",
|
|
default=True
|
|
)
|
|
|
|
conform_holdout: BoolProperty(
|
|
name="Holdout State",
|
|
description="Conform Collection Holdout State",
|
|
default=True
|
|
)
|
|
|
|
conform_use_indirect: BoolProperty(
|
|
name="Indirect Only State",
|
|
description="Conform Collection Indirect Only",
|
|
default=True
|
|
)
|
|
|
|
# endregion
|
|
|
|
# region reset template functions
|
|
|
|
def reset_scene_path_templates():
|
|
## set default template from environment variable if available, or fallback to preferences defaults
|
|
prefs = bpy.context.preferences.addons[__package__].preferences
|
|
if not prefs.use_env_base_path_templates:
|
|
# set from preferences
|
|
bpy.context.scene.render_toolbox.default_base_path = prefs.base_path_template
|
|
bpy.context.scene.render_toolbox.default_multilayer_base_path = prefs.base_path_multilayer_template
|
|
return
|
|
|
|
# set from environment variables (fallback to preferences if not set)
|
|
exr_base_path_template = os.getenv('RENDERTOOLBOX_EXR_PATH_TEMPLATE')
|
|
if exr_base_path_template:
|
|
bpy.context.scene.render_toolbox.default_base_path = exr_base_path_template
|
|
else:
|
|
bpy.context.scene.render_toolbox.default_base_path = prefs.base_path_template
|
|
|
|
multilayer_base_path_template = os.getenv('RENDERTOOLBOX_MULTILAYER_PATH_TEMPLATE')
|
|
if multilayer_base_path_template:
|
|
bpy.context.scene.render_toolbox.default_multilayer_base_path = multilayer_base_path_template
|
|
else:
|
|
bpy.context.scene.render_toolbox.default_multilayer_base_path = prefs.base_path_multilayer_template
|
|
|
|
# endregion
|
|
|
|
# region register
|
|
|
|
classes = (
|
|
RT_PG_render_toolbox_props,
|
|
RT_PG_render_toolbox_conform_props,
|
|
)
|
|
|
|
def register():
|
|
for cls in classes:
|
|
bpy.utils.register_class(cls)
|
|
|
|
bpy.types.Scene.render_toolbox = bpy.props.PointerProperty(type=RT_PG_render_toolbox_props)
|
|
bpy.types.ViewLayer.render_toolbox_conform = bpy.props.PointerProperty(type=RT_PG_render_toolbox_conform_props) # not stored, no need to unregister
|
|
|
|
def unregister():
|
|
del bpy.types.Scene.render_toolbox
|
|
|
|
for cls in reversed(classes):
|
|
bpy.utils.unregister_class(cls)
|