Refactor to allow separate gp render scene and compositing scene
1.7.0 - fix: problem when removing render layers - changed: node distribution refactor, allow separate compositing scene - Compositing scene (holding nodes) can be separated from render scene (holding GP objects and related viewlayers) - Default render named changed from `Render` to `RenderGP` - New properties in exposed Dopesheet N panel to manually set Render scene and Compo scene - Operator expose a `node_scene` parameter to separate where to send nodes - Switch scene button can have an extra button to go in compo scene if found
This commit is contained in:
+46
-34
@@ -2,9 +2,10 @@ import bpy
|
||||
import re
|
||||
from pathlib import Path
|
||||
from . import gen_vlayer, fn
|
||||
from bpy.props import (BoolProperty, StringProperty)
|
||||
|
||||
|
||||
def batch_setup_render_scene(context=None, render_scn=None, preview=True):
|
||||
def batch_setup_render_scene(context=None, render_scn=None, node_scene=None, preview=True):
|
||||
'''A series of setup actions for Render scene:
|
||||
- renumber fileout
|
||||
- Clean compo Tree
|
||||
@@ -15,10 +16,12 @@ def batch_setup_render_scene(context=None, render_scn=None, preview=True):
|
||||
if context is None:
|
||||
context = bpy.context
|
||||
if render_scn is None:
|
||||
render_scn = bpy.data.scenes.get('Render')
|
||||
render_scn = fn.get_render_scene(create=False)
|
||||
if not render_scn:
|
||||
print('"Render" scene not found in batch_setup_render_scene')
|
||||
print('Render scene not found in batch_setup_render_scene')
|
||||
return
|
||||
if node_scene is None:
|
||||
node_scene = render_scn
|
||||
|
||||
## Renumber File outputs
|
||||
print('Renumber File outputs')
|
||||
@@ -49,8 +52,7 @@ def batch_setup_render_scene(context=None, render_scn=None, preview=True):
|
||||
## Clean compo Tree
|
||||
print('Clean compo Tree')
|
||||
|
||||
bpy.ops.gp.clean_compo_tree('EXEC_DEFAULT', use_render_scene=True)
|
||||
# bpy.ops.gp.clean_compo_tree('INVOKE_DEFAULT', use_render_scene=True)
|
||||
bpy.ops.gp.clean_compo_tree('EXEC_DEFAULT', scene=render_scn.name, node_scene=node_scene.name)
|
||||
|
||||
## Trigger check file before finishing ?
|
||||
# bpy.ops.gp.check_render_scene('INVOKE_DEFAULT')
|
||||
@@ -63,55 +65,57 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||
bl_description = "Trigger all operation to make build render scene with default settings"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
# @classmethod
|
||||
# def poll(cls, context):
|
||||
# return context.object and context.object.type == 'GPENCIL'
|
||||
scene : StringProperty(name="Target Scene Name",
|
||||
description="Render scene to send GP to on a named scene, abort if not exists (not exposed)",
|
||||
default='', options={'SKIP_SAVE'})
|
||||
|
||||
# timer : bpy.props.FloatProperty(default=0.1, options={'SKIP_SAVE'})
|
||||
node_scene : StringProperty(name="Compositing Scene",
|
||||
description="Name of the scene holding compositing nodes",
|
||||
default='', options={'SKIP_SAVE'})
|
||||
|
||||
make_gp_single_user : bpy.props.BoolProperty(name='Set Single User Data', default=True,
|
||||
make_gp_single_user : BoolProperty(name='Set Single User Data', default=True,
|
||||
description='Set single user on all objects GP data')
|
||||
|
||||
excluded_prefix : bpy.props.StringProperty(
|
||||
excluded_prefix : StringProperty(
|
||||
name='Excluded Layer By Prefix', default='GP, RG, PO, MA',
|
||||
description='Exclude layer to send to render by prefix (comma separated list)')
|
||||
|
||||
clean_name_and_visibility : bpy.props.BoolProperty(name='Clean Name And Visibility', default=True,
|
||||
clean_name_and_visibility : BoolProperty(name='Clean Name And Visibility', default=True,
|
||||
description='Add object name to layer name when there is only prefix (ex: "CO_")\
|
||||
\nEnable visibility for layer with prefix included in Prefix Filter')
|
||||
|
||||
clean_material_duplication : bpy.props.BoolProperty(name='Clean Material Duplication', default=True,
|
||||
clean_material_duplication : BoolProperty(name='Clean Material Duplication', default=True,
|
||||
description='Clean material stack. i.e: Replace "mat.001" in material stack if "mat" exists and has same color')
|
||||
|
||||
prefix_filter : bpy.props.StringProperty(name='Prefix Filter', default='CO, CU, FX, TO', # , MA # exclude MA if mask are applied
|
||||
prefix_filter : StringProperty(name='Prefix Filter', default='CO, CU, FX, TO', # , MA # exclude MA if mask are applied
|
||||
description='Comma separated prefix to render. Set the other prefix and non-prefixed layer to exluded viewlayer')
|
||||
|
||||
set_layers_colors : bpy.props.BoolProperty(name='Set Layers Colors', default=True,
|
||||
set_layers_colors : BoolProperty(name='Set Layers Colors', default=True,
|
||||
description='Set colors for on layers according to prefix (hadrcoded color set)')
|
||||
|
||||
trigger_rename_lowercase : bpy.props.BoolProperty(name='Trigger Rename Lowercase', default=True,
|
||||
trigger_rename_lowercase : BoolProperty(name='Trigger Rename Lowercase', default=True,
|
||||
description='Rename all layer names lowercase')
|
||||
|
||||
trigger_renumber_by_distance : bpy.props.BoolProperty(name='Trigger Renumber By Distance', default=True,
|
||||
trigger_renumber_by_distance : BoolProperty(name='Trigger Renumber By Distance', default=True,
|
||||
description='Renumber object accordind to distance from camera and In-Front value')
|
||||
|
||||
export_layer_infos : bpy.props.BoolProperty(name='Export Layer Infos', default=True,
|
||||
export_layer_infos : BoolProperty(name='Export Layer Infos', default=True,
|
||||
description='Export layers infos to a Json file')
|
||||
|
||||
group_all_adjacent_layer_type : bpy.props.BoolProperty(name='Group All Adjacent Layer Type', default=False,
|
||||
group_all_adjacent_layer_type : BoolProperty(name='Group All Adjacent Layer Type', default=False,
|
||||
description='Fuse output Viewlayer according to adjacent Prefix in layer stack')
|
||||
|
||||
change_to_gp_workspace : bpy.props.BoolProperty(name='Change To Gp Workspace', default=True,
|
||||
change_to_gp_workspace : BoolProperty(name='Change To Gp Workspace', default=True,
|
||||
description='Switch to "GP Render" workspace shipped with addon')
|
||||
|
||||
batch_setup_render_scene : bpy.props.BoolProperty(name='Batch Setup Render Scene', default=True,
|
||||
batch_setup_render_scene : BoolProperty(name='Batch Setup Render Scene', default=True,
|
||||
description='- Renumber fileoutputs\
|
||||
\n- Clean compo Tree\
|
||||
\n- Go to camera view in visible viewports\
|
||||
\n- Swap to bg cam'
|
||||
)
|
||||
|
||||
add_preview : bpy.props.BoolProperty(name='Add Preview', default=True,
|
||||
add_preview : BoolProperty(name='Add Preview', default=True,
|
||||
description='Create preview with stacked alpha over on render layers')
|
||||
|
||||
def invoke(self, context, event):
|
||||
@@ -153,10 +157,21 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||
prefix_to_render = [p.strip() for p in self.prefix_filter.split(',')]
|
||||
print('prefix_to_render: ', prefix_to_render)
|
||||
|
||||
render_scn = bpy.data.scenes.get('Render')
|
||||
if render_scn:
|
||||
self.report({'ERROR'}, 'A "Render" scene already exists')
|
||||
return {'CANCELLED'}
|
||||
render_scn = fn.get_render_scene(create=False)
|
||||
if self.scene:
|
||||
render_scn = bpy.data.scenes.get(self.scene)
|
||||
if render_scn:
|
||||
self.report({'ERROR'}, f'Abort, scene "{render_scn.name}" already exists')
|
||||
return {'CANCELLED'}
|
||||
|
||||
if self.node_scene:
|
||||
node_scene = fn.get_compo_scene(scene_name=self.node_scene, create=True) # create if not exists
|
||||
## Set scene target in source scene
|
||||
context.scene.gp_render_settings.node_scene = node_scene.name
|
||||
else:
|
||||
node_scene = fn.get_compo_scene(create=True)
|
||||
if not node_scene:
|
||||
node_scene = render_scn
|
||||
|
||||
all_gp_objects = [o for o in context.scene.objects if o.type == 'GPENCIL']
|
||||
|
||||
@@ -206,13 +221,11 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||
if self.trigger_rename_lowercase:
|
||||
print('Trigger rename lowercase')
|
||||
bpy.ops.gp.lower_layers_name('EXEC_DEFAULT')
|
||||
# bpy.ops.gp.lower_layers_name('INVOKE_DEFAULT')
|
||||
|
||||
## Trigger renumber by distance
|
||||
if self.trigger_renumber_by_distance:
|
||||
print('Trigger renumber by distance')
|
||||
bpy.ops.gp.auto_number_object('EXEC_DEFAULT')
|
||||
# bpy.ops.gp.auto_number_object('INVOKE_DEFAULT')
|
||||
|
||||
## Export layer infos ? (skip if json already exists)
|
||||
if self.export_layer_infos:
|
||||
@@ -226,13 +239,13 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||
o.data = o.data.copy()
|
||||
|
||||
## Send all GP to render scene
|
||||
print('Send all GP to render scene')
|
||||
print('Send all GP to render scene (Create render scene if needed)')
|
||||
# bpy.ops.gp.add_object_to_render(mode="ALL") # Ops to send all
|
||||
gen_vlayer.export_gp_objects(ob_list, exclude_list=self.excluded_prefix) # Create render scene OTF
|
||||
gen_vlayer.export_gp_objects(ob_list, exclude_list=self.excluded_prefix, scene=render_scn, node_scene=node_scene) # Create render scene OTF
|
||||
|
||||
## Switch to new Render Scene
|
||||
print('Switch to new Render Scene')
|
||||
render_scn = bpy.data.scenes.get('Render')
|
||||
render_scn = fn.get_render_scene(create=False)
|
||||
if not render_scn:
|
||||
self.report({'ERROR'}, 'No render scene found')
|
||||
return {'CANCELLED'}
|
||||
@@ -268,13 +281,13 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||
# context.scene.update_tag()
|
||||
|
||||
## Batch setup render scene
|
||||
batch_setup_render_scene(render_scn=render_scn)
|
||||
batch_setup_render_scene(render_scn=render_scn, node_scene=node_scene)
|
||||
|
||||
## create preview
|
||||
|
||||
if self.add_preview:
|
||||
from .OP_merge_layers import merge_compositor_preview
|
||||
merge_compositor_preview(scene=render_scn)
|
||||
merge_compositor_preview(scene=node_scene)
|
||||
|
||||
## No need for timer anymore !
|
||||
# if batch_setup_render_scene:
|
||||
@@ -295,7 +308,6 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||
# bpy.ops.gp.check_render_scene('INVOKE_DEFAULT')
|
||||
## Note: After all these operation, a ctrl+Z might crash
|
||||
|
||||
|
||||
print('\nDone.\n')
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user