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:
+69
-39
@@ -2,19 +2,30 @@ import bpy
|
||||
from mathutils import Vector
|
||||
from . import fn
|
||||
|
||||
def add_rlayer(layer_name, scene=None, node_scene=None, location=None, color=None, node_name=None, width=400):
|
||||
'''Create a render layer node
|
||||
|
||||
def add_rlayer(layer_name, scene=None, location=None, color=None, node_name=None, width=400):
|
||||
'''create a render layer node
|
||||
if node_name is not specified, use passed layer name
|
||||
args:
|
||||
layer_name (str): Name of the viewlayer
|
||||
scene (Scene): Scene holding the viewlayer
|
||||
node_scene (Scene): scene where to add render layer
|
||||
if None: fallback scene pointed by compo scene property
|
||||
if compo scene property is empty: fallback to render scene.
|
||||
location (Vector2): Location of the node
|
||||
color (tuple): Color of the node
|
||||
node_name (str): if not specified, use layer_name
|
||||
width (int): width of the node
|
||||
'''
|
||||
|
||||
if not node_name:
|
||||
node_name = layer_name # 'RL_' +
|
||||
|
||||
if not scene:
|
||||
scene=bpy.context.scene
|
||||
if not node_scene:
|
||||
node_scene=fn.get_compo_scene(create=False)
|
||||
if not node_scene:
|
||||
node_scene=fn.get_render_scene(create=False)
|
||||
|
||||
nodes = scene.node_tree.nodes
|
||||
nodes = node_scene.node_tree.nodes
|
||||
|
||||
comp = nodes.get(node_name)
|
||||
if comp:
|
||||
@@ -40,13 +51,11 @@ def add_rlayer(layer_name, scene=None, location=None, color=None, node_name=None
|
||||
return comp
|
||||
|
||||
def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||
if bpy.context.scene.name == 'Scene':
|
||||
scene = fn.get_render_scene()
|
||||
else:
|
||||
scene = bpy.context.scene
|
||||
|
||||
nodes = scene.node_tree.nodes
|
||||
links = scene.node_tree.links
|
||||
node_tree = rlayer.id_data # get node_tree from rlayer
|
||||
|
||||
nodes = node_tree.nodes
|
||||
links = node_tree.links
|
||||
|
||||
vl_name = rlayer.layer
|
||||
if not vl_name or vl_name == 'View Layer':
|
||||
@@ -88,7 +97,7 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||
print(f'create nodegroup {ng_name}')
|
||||
ngroup = bpy.data.node_groups.new(ng_name, 'CompositorNodeTree')
|
||||
|
||||
ng = fn.create_node('CompositorNodeGroup', tree=scene.node_tree, location=(fn.real_loc(rlayer)[0] + 600, fn.real_loc(rlayer)[1]), width=400) # (rlayer.location[0] + 600, rlayer.location[1])
|
||||
ng = fn.create_node('CompositorNodeGroup', tree=node_tree, location=(fn.real_loc(rlayer)[0] + 600, fn.real_loc(rlayer)[1]), width=400) # (rlayer.location[0] + 600, rlayer.location[1])
|
||||
if frame:
|
||||
ng.parent= frame
|
||||
ng.node_tree = ngroup
|
||||
@@ -163,8 +172,17 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||
ngroup.links.new(ng_in.outputs[vl_name], aa.inputs[0]) # node_tree
|
||||
ngroup.links.new(aa.outputs[0], ng_out.inputs[vl_name]) # node_tree
|
||||
|
||||
aa.mute = scene.use_aa # mute if native AA is used
|
||||
|
||||
## Get use_aa prop from render scene ?
|
||||
# rd_scn = fn.get_render_scene(create=False)
|
||||
# if rd_scn:
|
||||
# aa.mute = rd_scn.gp_render_settings.use_aa # mute if native AA is used
|
||||
scene = next((s for s in bpy.data.scenes if s.node_tree == node_tree), None)
|
||||
if scene:
|
||||
print(f'set AA from scene {scene.name}')
|
||||
aa.mute = scene.gp_render_settings.use_aa # mute if native AA is used
|
||||
else:
|
||||
print('/!\ Scene could not be found to define if internal AA should be muted')
|
||||
|
||||
fn.reorganise_NG_nodegroup(ng) # decorative
|
||||
|
||||
@@ -206,7 +224,7 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||
out = nodes.get(out_name)
|
||||
if not out:
|
||||
# color = (0.2,0.3,0.5)
|
||||
out = fn.create_node('CompositorNodeOutputFile', tree=scene.node_tree, location=(fn.real_loc(ng)[0]+500, fn.real_loc(ng)[1]+50), width=600) # =(ng.location[0]+600, ng.location[1]+50)
|
||||
out = fn.create_node('CompositorNodeOutputFile', tree=node_tree, location=(fn.real_loc(ng)[0]+500, fn.real_loc(ng)[1]+50), width=600) # =(ng.location[0]+600, ng.location[1]+50)
|
||||
fn.set_file_output_format(out)
|
||||
out.name = out_name
|
||||
out.parent = frame
|
||||
@@ -233,16 +251,20 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||
return ng, out
|
||||
|
||||
|
||||
def get_set_viewlayer_from_gp(ob, l, scene=None):
|
||||
'''setup ouptut from passed gp obj > layer'''
|
||||
if not scene:
|
||||
if bpy.context.scene.name != 'Scene':
|
||||
scene = bpy.context.scene
|
||||
else:
|
||||
scene = fn.get_render_scene()
|
||||
def get_set_viewlayer_from_gp(ob, l, scene=None, node_scene=None):
|
||||
'''setup ouptut from passed gp obj > layer
|
||||
scene: scene to set viewlayer
|
||||
node_scene: where to add compo node (use scene if not passed)'''
|
||||
|
||||
# print('Set viewlayer Scene: ', scene.name)
|
||||
node_tree = scene.node_tree
|
||||
scene = scene or fn.get_render_scene()
|
||||
node_scene = node_scene or fn.get_compo_scene() or scene
|
||||
|
||||
print('Viewlayer Scene: ', scene.name)
|
||||
print('Compo Scene: ', node_scene.name)
|
||||
|
||||
## If not passed, identical to scene holding viewlayers
|
||||
|
||||
node_tree = node_scene.node_tree
|
||||
nodes = node_tree.nodes
|
||||
|
||||
in_rds = scene.collection.all_objects.get(ob.name)
|
||||
@@ -265,18 +287,26 @@ def get_set_viewlayer_from_gp(ob, l, scene=None):
|
||||
if nob:
|
||||
nob.select_set(True)
|
||||
|
||||
# create viewlayer
|
||||
# Create viewlayer
|
||||
vl_name = f'{ob.name} / {l.info}'
|
||||
vl = fn.get_view_layer(vl_name, scene=scene)
|
||||
vl_name = vl.name
|
||||
# affect layer to this vl
|
||||
|
||||
## To avoid potential error, transfer compo scene prop to renderscene.
|
||||
scn = bpy.context.scene
|
||||
if scn.gp_render_settings.node_scene and scn != scene:
|
||||
if scn.gp_render_settings.node_scene != scene.gp_render_settings.node_scene:
|
||||
print(f'Transfer compo scene target prop to render scene: "{scn.gp_render_settings.node_scene}"')
|
||||
scene.gp_render_settings.node_scene = scn.gp_render_settings.node_scene
|
||||
|
||||
# Affect layer to this vl
|
||||
l.viewlayer_render = vl_name
|
||||
|
||||
# check if already exists
|
||||
# Check if already exists
|
||||
rlayer_list = [n for n in nodes if n.type == 'R_LAYERS' and n.layer == vl_name]
|
||||
|
||||
# get frame object and their contents
|
||||
# dict like : {objname : [layer_nodeA, layer_nodeB,...]}
|
||||
# Get frame object and their contents
|
||||
# dict model : {objname : [layer_nodeA, layer_nodeB,...]}
|
||||
frame_dic = {f.label: [n for n in nodes if n.type == 'R_LAYERS' and n.parent and n.parent.name == f.name and '/' in n.layer] # n.layer != 'View Layer'
|
||||
for f in nodes if f.type == 'FRAME'}
|
||||
|
||||
@@ -323,7 +353,7 @@ def get_set_viewlayer_from_gp(ob, l, scene=None):
|
||||
frame.label_size = 50
|
||||
frame.location = (loc[0], loc[1] + 20)
|
||||
|
||||
cp = add_rlayer(vl_name, scene=scene, location=loc)
|
||||
cp = add_rlayer(vl_name, scene=scene, node_scene=node_scene, location=loc)
|
||||
cp.parent = frame
|
||||
# use same color as layer
|
||||
if fn.has_channel_color(l):
|
||||
@@ -341,23 +371,24 @@ def get_set_viewlayer_from_gp(ob, l, scene=None):
|
||||
print(f'\n {ob.name} -> {l.info} (connect to existing)')
|
||||
|
||||
## object frame exists: get framing and insert
|
||||
cp = add_rlayer(vl_name, scene=scene, location=(0,0))
|
||||
cp = add_rlayer(vl_name, scene=scene, node_scene=node_scene, location=(0,0))
|
||||
if cp.layer != vl_name:
|
||||
print(f'problem with {cp}: {cp.layer} != {vl_name}')
|
||||
return
|
||||
|
||||
if fn.has_channel_color(l):
|
||||
cp.use_custom_color = True
|
||||
cp.color = l.channel_color
|
||||
cp.use_custom_color = True
|
||||
cp.color = l.channel_color
|
||||
|
||||
frame = [f for f in nodes if f.type == 'FRAME' and f.label == ob.name][0]
|
||||
frame = next((f for f in nodes if f.type == 'FRAME' and f.label == ob.name), None)
|
||||
rl_nodes = frame_dic[frame.label] # get nodes from
|
||||
if rl_nodes:
|
||||
# get nodes order to insert
|
||||
rl_nodes.sort(key=lambda n: fn.real_loc(n).y, reverse=True) # descending
|
||||
top_loc = fn.real_loc(rl_nodes[0])
|
||||
else:
|
||||
top_loc = fn.get_frame_transform(frame[1], node_tree) - 60
|
||||
print('!! gen_viewlayer: No Render layers nodes !!')
|
||||
top_loc = fn.get_frame_transform(frame, node_tree) - 60
|
||||
|
||||
# cp.location = (top_loc[0], top_loc[1] + 100) # temp location to adjust x loc
|
||||
|
||||
@@ -381,10 +412,9 @@ def get_set_viewlayer_from_gp(ob, l, scene=None):
|
||||
# set x loc from first node in list (maybe use leftmost ?)
|
||||
n.location = Vector((fn.real_loc(ref_node)[0], top_loc[1] - offset)) - n.parent.location
|
||||
offset += 180
|
||||
|
||||
n.update()
|
||||
# reorder render layers nodes within frame
|
||||
|
||||
# reorder render layers nodes within frame
|
||||
connect_render_layer(cp, frame=frame)
|
||||
|
||||
# re-arrange all frames (since the offset probably overlapped)
|
||||
@@ -392,7 +422,7 @@ def get_set_viewlayer_from_gp(ob, l, scene=None):
|
||||
|
||||
return vl, cp
|
||||
|
||||
def export_gp_objects(oblist, exclude_list=[], scene=None):
|
||||
def export_gp_objects(oblist, exclude_list=[], scene=None, node_scene=None):
|
||||
# Skip layer containing element in exclude list
|
||||
if not isinstance(oblist, list):
|
||||
oblist = [oblist]
|
||||
@@ -410,4 +440,4 @@ def export_gp_objects(oblist, exclude_list=[], scene=None):
|
||||
l.viewlayer_render = fn.get_view_layer('exclude', scene=scene).name # assign "exclude"
|
||||
continue
|
||||
|
||||
_vl, _cp = get_set_viewlayer_from_gp(ob, l, scene=scene) # scene=fn.get_render_scene())
|
||||
_vl, _cp = get_set_viewlayer_from_gp(ob, l, scene=scene, node_scene=node_scene) # scene=fn.get_render_scene())
|
||||
Reference in New Issue
Block a user