Fix multiscene ops and batch script generation
0.6.0: - feat: button to generate a background rendering script to batch multi-scene - fix: exposed checkbox to change scene AA settings, should be on except if there are NG_merges. (auto-off when using merge nodes buttons) - fix: default generated scene have native AA - fix: adding layers from object in other scene use active scene (stop always rerouting to 'Render' scene)main
parent
d3871dcc88
commit
7b79542c6a
|
@ -14,6 +14,13 @@ Activate / deactivate layer opaticty according to prefix
|
||||||
Activate / deactivate all masks using MA layers
|
Activate / deactivate all masks using MA layers
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
0.6.0:
|
||||||
|
|
||||||
|
- feat: button to generate a background rendering script to batch multi-scene
|
||||||
|
- fix: exposed checkbox to change scene AA settings, should be on except if there are NG_merges. (auto-off when using merge nodes buttons)
|
||||||
|
- fix: default generated scene have native AA
|
||||||
|
- fix: adding layers from object in other scene use active scene (stop always rerouting to 'Render' scene)
|
||||||
|
|
||||||
0.5.9
|
0.5.9
|
||||||
|
|
||||||
- feat: Select which scene to render
|
- feat: Select which scene to render
|
||||||
|
|
|
@ -44,7 +44,7 @@ class GPEXP_OT_add_layer_to_render(bpy.types.Operator):
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
def export_gp_objects(oblist, exclude_list=[]):
|
def export_gp_objects(oblist, exclude_list=[], scene=None):
|
||||||
# Skip layer containing element in excluyde list
|
# Skip layer containing element in excluyde list
|
||||||
if not isinstance(oblist, list):
|
if not isinstance(oblist, list):
|
||||||
oblist = [oblist]
|
oblist = [oblist]
|
||||||
|
@ -54,10 +54,10 @@ def export_gp_objects(oblist, exclude_list=[]):
|
||||||
# if l.hide:
|
# if l.hide:
|
||||||
# continue
|
# continue
|
||||||
if l.hide or any(x + '_' in l.info for x in exclude_list): # exclude hided ?
|
if l.hide or any(x + '_' in l.info for x in exclude_list): # exclude hided ?
|
||||||
l.viewlayer_render = fn.get_view_layer('exclude').name # assign "exclude"
|
l.viewlayer_render = fn.get_view_layer('exclude', scene=scene).name # assign "exclude"
|
||||||
continue
|
continue
|
||||||
|
|
||||||
_vl, _cp = gen_vlayer.get_set_viewlayer_from_gp(ob, l) # scene=fn.get_render_scene())
|
_vl, _cp = gen_vlayer.get_set_viewlayer_from_gp(ob, l, scene=scene) # scene=fn.get_render_scene())
|
||||||
|
|
||||||
|
|
||||||
## send operator with mode ALL or SELECTED to batch build
|
## send operator with mode ALL or SELECTED to batch build
|
||||||
|
@ -75,17 +75,22 @@ class GPEXP_OT_add_objects_to_render(bpy.types.Operator):
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
# create render scene
|
# create render scene
|
||||||
fn.get_render_scene()
|
if context.scene.name == 'Scene':
|
||||||
|
scn = fn.get_render_scene()
|
||||||
|
else:
|
||||||
|
scn = context.scene
|
||||||
|
|
||||||
|
|
||||||
excludes = [] # ['MA', 'IN'] # Get list dynamically
|
excludes = [] # ['MA', 'IN'] # Get list dynamically
|
||||||
if self.mode == 'SELECTED':
|
if self.mode == 'SELECTED':
|
||||||
export_gp_objects([o for o in context.selected_objects if o.type == 'GPENCIL'], exclude_list=excludes) # excludes
|
export_gp_objects([o for o in context.selected_objects if o.type == 'GPENCIL'], exclude_list=excludes, scene=scn)
|
||||||
|
|
||||||
elif self.mode == 'ALL':
|
elif self.mode == 'ALL':
|
||||||
scn = bpy.data.scenes.get('Scene')
|
# scn = bpy.data.scenes.get('Scene')
|
||||||
if not scn:
|
# if not scn:
|
||||||
self.report({'ERROR'}, 'Could not found default scene')
|
# self.report({'ERROR'}, 'Could not found default scene')
|
||||||
return {"CANCELLED"}
|
# return {"CANCELLED"}
|
||||||
export_gp_objects([o for o in scn.objects if o.type == 'GPENCIL' and not o.hide_get()], exclude_list=excludes) # excludes
|
export_gp_objects([o for o in scn.objects if o.type == 'GPENCIL' and not o.hide_get()], exclude_list=excludes, scene=scn)
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
|
@ -211,12 +211,48 @@ class GPEXP_OT_activate_only_selected_layers(bpy.types.Operator):
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
### TODO reset scene settings (set settings )
|
||||||
|
|
||||||
|
class GPEXP_OT_reset_render_settings(bpy.types.Operator):
|
||||||
|
bl_idname = "gp.reset_render_settings"
|
||||||
|
bl_label = "Reset Render Settings"
|
||||||
|
bl_description = "Reset render settings on all scene, disabling AA nodes when there is no Merge nodegroup"
|
||||||
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
for scn in bpy.data.scenes:
|
||||||
|
if scn.name == 'Scene':
|
||||||
|
# don't touch original scene
|
||||||
|
continue
|
||||||
|
|
||||||
|
# set a unique preview output
|
||||||
|
# - avoid possible write/sync overlap (point to tmp on linux ?)
|
||||||
|
# - allow to monitor output of a scene and possibly use Overwrite
|
||||||
|
|
||||||
|
if scn.render.filepath.startswith('//render/preview/'):
|
||||||
|
scn.render.filepath = f'//render/preview/{bpy.path.clean_nam(scn.name)}/preview_'
|
||||||
|
|
||||||
|
if not scn.use_nodes:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# set the settings depending on merges node presences
|
||||||
|
use_native_aa = True
|
||||||
|
for n in scn.node_tree.nodes:
|
||||||
|
if n.name.startswith('merge_NG_'):
|
||||||
|
use_native_aa = False
|
||||||
|
break
|
||||||
|
|
||||||
|
fn.scene_aa(scene=scn, toggle=use_native_aa)
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
classes=(
|
classes=(
|
||||||
GPEXP_OT_mute_toggle_output_nodes,
|
GPEXP_OT_mute_toggle_output_nodes,
|
||||||
GPEXP_OT_set_output_node_format,
|
GPEXP_OT_set_output_node_format,
|
||||||
GPEXP_OT_number_outputs,
|
GPEXP_OT_number_outputs,
|
||||||
GPEXP_OT_enable_all_viewlayers,
|
GPEXP_OT_enable_all_viewlayers,
|
||||||
GPEXP_OT_activate_only_selected_layers,
|
GPEXP_OT_activate_only_selected_layers,
|
||||||
|
GPEXP_OT_reset_render_settings,
|
||||||
# GPEXP_OT_normalize_outnames,
|
# GPEXP_OT_normalize_outnames,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,8 @@ def merge_layers(rlayers, obname=None, active=None, disconnect=True, color=None)
|
||||||
# fn.clean_nodegroup_inputs(dg)
|
# fn.clean_nodegroup_inputs(dg)
|
||||||
# # fn.clear_nodegroup_content_if_disconnected(dg.node_tree)
|
# # fn.clear_nodegroup_content_if_disconnected(dg.node_tree)
|
||||||
|
|
||||||
|
bpy.context.scene.use_aa = False # trigger fn.scene_aa(toggle=False)
|
||||||
|
|
||||||
return ng, out
|
return ng, out
|
||||||
|
|
||||||
class GPEXP_OT_merge_viewlayers_to_active(bpy.types.Operator):
|
class GPEXP_OT_merge_viewlayers_to_active(bpy.types.Operator):
|
||||||
|
@ -265,7 +267,11 @@ class GPEXP_OT_merge_selected_viewlayer_nodes(bpy.types.Operator):
|
||||||
disconnect : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'})
|
disconnect : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'})
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
render = bpy.data.scenes.get('Render')
|
if context.scene.name == 'Scene':
|
||||||
|
render = bpy.data.scenes.get('Render')
|
||||||
|
else:
|
||||||
|
render = context.scene
|
||||||
|
|
||||||
if not render:
|
if not render:
|
||||||
self.report({'ERROR'}, 'No render scene')
|
self.report({'ERROR'}, 'No render scene')
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import bpy
|
import bpy
|
||||||
from . import fn
|
from . import fn
|
||||||
from time import time
|
from time import time, strftime
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
from bpy.types import Panel, UIList, Operator, PropertyGroup, Menu
|
from bpy.types import Panel, UIList, Operator, PropertyGroup, Menu
|
||||||
from bpy.props import PointerProperty, IntProperty, BoolProperty, StringProperty, EnumProperty, FloatProperty
|
from bpy.props import PointerProperty, IntProperty, BoolProperty, StringProperty, EnumProperty, FloatProperty
|
||||||
|
@ -101,10 +103,98 @@ class GPEXP_OT_render_selected_scene(bpy.types.Operator):
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class GPEXP_OT_bg_render_script_selected_scene(bpy.types.Operator):
|
||||||
|
bl_idname = "gp.bg_render_script_selected_scenes"
|
||||||
|
bl_label = "Create Selected Scene Render Batch "
|
||||||
|
bl_description = "Create a batch script to render all selected scenes in a selection popup"
|
||||||
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
context.scene.scenes_list.clear()
|
||||||
|
for s in bpy.data.scenes:
|
||||||
|
scn_item = context.scene.scenes_list.add()
|
||||||
|
scn_item.name = s.name
|
||||||
|
scn_item.select = s.name != 'Scene'
|
||||||
|
|
||||||
|
return context.window_manager.invoke_props_dialog(self, width=500)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
col = layout.column()
|
||||||
|
for si in context.scene.scenes_list:
|
||||||
|
row = col.row()
|
||||||
|
row.prop(si, 'select',text='')
|
||||||
|
row.label(text=si.name)
|
||||||
|
|
||||||
|
## Display warnings
|
||||||
|
scn = bpy.data.scenes.get(si.name)
|
||||||
|
# compare to existing Rlayers (overkill ?)
|
||||||
|
# vls = [scn.view_layers.get(n.layer) for n in rlayers_nodes if scn.view_layers.get(n.layer)]
|
||||||
|
|
||||||
|
vls = [vl for vl in scn.view_layers if vl.name != 'View Layer']
|
||||||
|
|
||||||
|
if vls:
|
||||||
|
exclude_count = len([vl for vl in vls if not vl.use])
|
||||||
|
if exclude_count:
|
||||||
|
row.label(text=f'{exclude_count}/{len(vls)} excluded viewlayers', icon='ERROR')
|
||||||
|
|
||||||
|
if not scn.use_nodes:
|
||||||
|
row.label(text='use_node deactivated', icon='ERROR')
|
||||||
|
continue
|
||||||
|
|
||||||
|
outfiles = [n for n in scn.node_tree.nodes if n.type == 'OUTPUT_FILE']
|
||||||
|
if not outfiles:
|
||||||
|
row.label(text='No output files nodes', icon='ERROR')
|
||||||
|
continue
|
||||||
|
|
||||||
|
outnum = len(outfiles)
|
||||||
|
muted = len([x for x in outfiles if x.mute])
|
||||||
|
if muted == outnum:
|
||||||
|
row.label(text='All output file are muted', icon='ERROR')
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif muted:
|
||||||
|
row.label(text=f'{muted}/{outnum} output file muted', icon='ERROR')
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
platform = sys.platform
|
||||||
|
|
||||||
|
blend = Path(bpy.data.filepath)
|
||||||
|
|
||||||
|
scn_to_render = [si.name for si in context.scene.scenes_list if si.select]
|
||||||
|
batch_file = blend.parent / f'{blend.stem}--{len(scn_to_render)}batch_{strftime("%m-%d-%H")}.sh'
|
||||||
|
|
||||||
|
if platform.startswith('win'):
|
||||||
|
script_text = ['@ECHO OFF']
|
||||||
|
batch_file = batch_file.with_suffix('.bat')
|
||||||
|
else:
|
||||||
|
script_text = ['#!/bin/bash']
|
||||||
|
|
||||||
|
print('batch_file: ', batch_file)
|
||||||
|
for scn_name in scn_to_render:
|
||||||
|
cmd = f'"{bpy.app.binary_path}" -b "{bpy.data.filepath}" -S "{scn_name}" -a'
|
||||||
|
script_text.append(cmd)
|
||||||
|
|
||||||
|
script_text.append('echo --- END BATCH ---')
|
||||||
|
script_text.append('pause')
|
||||||
|
|
||||||
|
with batch_file.open('w') as fd:
|
||||||
|
fd.write('\n'.join(script_text))
|
||||||
|
|
||||||
|
self.report({'INFO'}, f'Batch script generated: {batch_file}')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
classes=(
|
classes=(
|
||||||
GPEXP_scene_select_prop,
|
GPEXP_scene_select_prop,
|
||||||
GPEXP_OT_render_selected_scene,
|
GPEXP_OT_render_selected_scene,
|
||||||
GPEXP_OT_render_all_scenes,
|
GPEXP_OT_render_all_scenes,
|
||||||
|
GPEXP_OT_bg_render_script_selected_scene,
|
||||||
)
|
)
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|
17
__init__.py
17
__init__.py
|
@ -2,7 +2,7 @@ bl_info = {
|
||||||
"name": "GP Render",
|
"name": "GP Render",
|
||||||
"description": "Organise export of gp layers through compositor output",
|
"description": "Organise export of gp layers through compositor output",
|
||||||
"author": "Samuel Bernou",
|
"author": "Samuel Bernou",
|
||||||
"version": (0, 5, 9),
|
"version": (0, 6, 0),
|
||||||
"blender": (2, 93, 0),
|
"blender": (2, 93, 0),
|
||||||
"location": "View3D",
|
"location": "View3D",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
@ -25,6 +25,11 @@ from . import prefs
|
||||||
from . import OP_setup_layers
|
from . import OP_setup_layers
|
||||||
from . import ui
|
from . import ui
|
||||||
|
|
||||||
|
from .fn import scene_aa
|
||||||
|
|
||||||
|
def update_scene_aa(context, scene):
|
||||||
|
scene_aa(toggle=bpy.context.scene.use_aa)
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
@ -46,6 +51,14 @@ def register():
|
||||||
OP_setup_layers.register()
|
OP_setup_layers.register()
|
||||||
ui.register()
|
ui.register()
|
||||||
# bpy.types.Scene.pgroup_name = bpy.props.PointerProperty(type = PROJ_PGT_settings)
|
# bpy.types.Scene.pgroup_name = bpy.props.PointerProperty(type = PROJ_PGT_settings)
|
||||||
|
bpy.types.Scene.use_aa = bpy.props.BoolProperty(
|
||||||
|
name='Use Native Anti Aliasing',
|
||||||
|
default=True,
|
||||||
|
description='\
|
||||||
|
Should be Off only if tree contains a merge_NG or alpha-over-combined renderlayers.\n\
|
||||||
|
Auto-set to Off when using node merge button\n\
|
||||||
|
Toggle: AA settings of and muting AA nested-nodegroup',
|
||||||
|
update=update_scene_aa)
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
if bpy.app.background:
|
if bpy.app.background:
|
||||||
|
@ -66,7 +79,7 @@ def unregister():
|
||||||
OP_add_layer.unregister()
|
OP_add_layer.unregister()
|
||||||
prefs.unregister()
|
prefs.unregister()
|
||||||
|
|
||||||
# del bpy.types.Scene.pgroup_name
|
del bpy.types.Scene.use_aa
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
register()
|
register()
|
96
fn.py
96
fn.py
|
@ -107,12 +107,26 @@ def set_file_output_format(fo):
|
||||||
# fo.format.color_depth = '8'
|
# fo.format.color_depth = '8'
|
||||||
# fo.format.compression = 15
|
# fo.format.compression = 15
|
||||||
|
|
||||||
def set_settings(scene=None):
|
|
||||||
|
def set_scene_aa_settings(scene=None, aa=True):
|
||||||
|
'''aa == using native AA, else disable scene AA'''
|
||||||
if not scene:
|
if not scene:
|
||||||
scene = bpy.context.scene
|
scene = bpy.context.scene
|
||||||
|
if aa:
|
||||||
|
scene.eevee.taa_render_samples = 32
|
||||||
|
scene.grease_pencil_settings.antialias_threshold = 1
|
||||||
|
else:
|
||||||
|
scene.eevee.taa_render_samples = 1
|
||||||
|
scene.grease_pencil_settings.antialias_threshold = 0
|
||||||
|
|
||||||
|
def set_settings(scene=None, aa=True):
|
||||||
|
'''aa == using native AA, else disable scene AA'''
|
||||||
|
if not scene:
|
||||||
|
scene = bpy.context.scene
|
||||||
|
|
||||||
# specify scene settings for these kind of render
|
# specify scene settings for these kind of render
|
||||||
scene.eevee.taa_render_samples = 1
|
set_scene_aa_settings(scene=scene, aa=aa)
|
||||||
scene.grease_pencil_settings.antialias_threshold = 0
|
|
||||||
scene.render.film_transparent = True
|
scene.render.film_transparent = True
|
||||||
scene.render.use_compositing = True
|
scene.render.use_compositing = True
|
||||||
scene.render.use_sequencer = False
|
scene.render.use_sequencer = False
|
||||||
|
@ -121,11 +135,25 @@ def set_settings(scene=None):
|
||||||
scene.render.resolution_percentage = 100
|
scene.render.resolution_percentage = 100
|
||||||
|
|
||||||
# output (fast write settings since this is just to delete afterwards...)
|
# output (fast write settings since this is just to delete afterwards...)
|
||||||
scene.render.filepath = '//render/preview/preview_'
|
scene.render.filepath = f'//render/preview/{scene.name}/preview_'
|
||||||
scene.render.image_settings.file_format = 'JPEG'
|
scene.render.image_settings.file_format = 'JPEG'
|
||||||
scene.render.image_settings.color_mode = 'RGB'
|
scene.render.image_settings.color_mode = 'RGB'
|
||||||
scene.render.image_settings.quality = 0
|
scene.render.image_settings.quality = 0
|
||||||
|
|
||||||
|
def scene_aa(scene=None, toggle=True):
|
||||||
|
'''Change scene AA settings and commute AA nodes according to toggle'''
|
||||||
|
if not scene:
|
||||||
|
scene=bpy.context.scene
|
||||||
|
|
||||||
|
# enable/disable native anti-alias on active scene
|
||||||
|
set_scene_aa_settings(scene=scene, aa=toggle)
|
||||||
|
# mute/unmute AA nodegroups
|
||||||
|
for n in scene.node_tree.nodes:
|
||||||
|
if n.type == 'GROUP' and n.name.startswith('NG_'):
|
||||||
|
# n.mute = False # mute whole nodegroup ?
|
||||||
|
for gn in n.node_tree.nodes:
|
||||||
|
if gn.type == 'GROUP' and gn.node_tree.name == 'AA':
|
||||||
|
gn.mute = toggle
|
||||||
|
|
||||||
def new_scene_from(name, src_scn=None, regen=True, crop=True, link_cam=True, link_light=True):
|
def new_scene_from(name, src_scn=None, regen=True, crop=True, link_cam=True, link_light=True):
|
||||||
'''Get / Create a scene from name and source scene to get settings from'''
|
'''Get / Create a scene from name and source scene to get settings from'''
|
||||||
|
@ -179,10 +207,11 @@ def get_render_scene():
|
||||||
render_scn.collection.objects.link(ob)
|
render_scn.collection.objects.link(ob)
|
||||||
|
|
||||||
render_scn.use_nodes = True
|
render_scn.use_nodes = True
|
||||||
|
|
||||||
# TODO Clear node tree (initial view layer stuff)
|
# TODO Clear node tree (initial view layer stuff)
|
||||||
# set adapted render settings (no AA)
|
|
||||||
set_settings(render_scn)
|
|
||||||
|
|
||||||
|
set_settings(render_scn, with_aa=False) # set adapted render settings (no AA by default)
|
||||||
|
render_scn.use_aa = True
|
||||||
return render_scn
|
return render_scn
|
||||||
|
|
||||||
def get_view_layer(name, scene=None):
|
def get_view_layer(name, scene=None):
|
||||||
|
@ -1054,8 +1083,8 @@ def split_object_to_scene():
|
||||||
coords = get_gp_box_all_frame_selection(oblist=gp_objs, scn=new, cam=new.camera)
|
coords = get_gp_box_all_frame_selection(oblist=gp_objs, scn=new, cam=new.camera)
|
||||||
if not coords:
|
if not coords:
|
||||||
return f'Scene "{scene_name}" created. But Border was not set (Timeout during GP analysis), should be done by hand if needed then use export crop to json'
|
return f'Scene "{scene_name}" created. But Border was not set (Timeout during GP analysis), should be done by hand if needed then use export crop to json'
|
||||||
|
|
||||||
set_border_region_from_coord(coords, margin=30, scn=new, export_json=True)
|
set_border_region_from_coord(coords, margin=30, scn=new, export_json=True)
|
||||||
|
|
||||||
export_crop_to_json()
|
export_crop_to_json()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1106,56 +1135,3 @@ def clear_frame_out_of_range_all_object():
|
||||||
ct += nct
|
ct += nct
|
||||||
print(f'{ct} gp frames deleted')
|
print(f'{ct} gp frames deleted')
|
||||||
return ct
|
return ct
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
def split_object_to_scene():
|
|
||||||
'''Create a new scene from selection'''
|
|
||||||
|
|
||||||
# send objects in a new render scene
|
|
||||||
## define new scene name with active object names
|
|
||||||
active = bpy.context.object
|
|
||||||
scene_name = active.name
|
|
||||||
objs = [o for o in bpy.context.selected_objects]
|
|
||||||
|
|
||||||
rd_scn = bpy.data.scenes.get('Render')
|
|
||||||
## create scene and copy settings from render scene or current
|
|
||||||
# src_scn = bpy.data.scenes.get('Render')
|
|
||||||
# src_scn = src_scn or bpy.context.scene
|
|
||||||
# if src_scn.name == scene_name:
|
|
||||||
# print('! Problem ! Trying to to create new render scene without source')
|
|
||||||
# return
|
|
||||||
|
|
||||||
|
|
||||||
## From current scene (might be Render OR Scene)
|
|
||||||
src_scn = bpy.context.scene
|
|
||||||
|
|
||||||
new = new_scene_from(scene_name, src_scn=src_scn, regen=True) # crop=True, link_cam=True, link_light=True
|
|
||||||
|
|
||||||
for ob in objs:
|
|
||||||
new.collection.objects.link(ob)
|
|
||||||
if ob.type == 'GPENCIL':
|
|
||||||
# recreate VL
|
|
||||||
vl_names = [l.viewlayer_render for l in ob.data.layers if l.viewlayer_render]
|
|
||||||
for names in vl_names:
|
|
||||||
new.view_layers.new(names)
|
|
||||||
# get_set_viewlayer_from_gp(ob, l, scene=new)
|
|
||||||
|
|
||||||
|
|
||||||
def set_crop_bbox_2d(ob, cam=None):
|
|
||||||
'''Basic crop using bouding box on current frame'''
|
|
||||||
from bpy_extras.object_utils import world_to_camera_view
|
|
||||||
|
|
||||||
scn = bpy.context.scene
|
|
||||||
cam = cam or scn.camera
|
|
||||||
# bbox = [ob.matrix_world @ Vector(b) for b in bbox_coords]
|
|
||||||
coords2d = [world_to_camera_view(scn, cam, p) for p in get_bbox_3d(ob)]
|
|
||||||
|
|
||||||
coords2d_x = sorted([c[0] for c in coords2d])
|
|
||||||
coords2d_y = sorted([c[1] for c in coords2d])
|
|
||||||
scn.render.border_min_x = coords2d_x[0]
|
|
||||||
scn.render.border_max_x = coords2d_x[-1]
|
|
||||||
scn.render.border_min_y = coords2d_y[0]
|
|
||||||
scn.render.border_max_y = coords2d_y[-1]
|
|
||||||
return
|
|
||||||
"""
|
|
|
@ -40,7 +40,11 @@ def add_rlayer(layer_name, scene=None, location=None, color=None, node_name=None
|
||||||
return comp
|
return comp
|
||||||
|
|
||||||
def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||||
scene = fn.get_render_scene()
|
if bpy.context.scene.name == 'Scene':
|
||||||
|
scene = fn.get_render_scene()
|
||||||
|
else:
|
||||||
|
scene = bpy.context.scene
|
||||||
|
|
||||||
nodes = scene.node_tree.nodes
|
nodes = scene.node_tree.nodes
|
||||||
links = scene.node_tree.links
|
links = scene.node_tree.links
|
||||||
|
|
||||||
|
@ -147,6 +151,9 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||||
# ng_in.outputs[vl_name]
|
# ng_in.outputs[vl_name]
|
||||||
ngroup.links.new(ng_in.outputs[vl_name], aa.inputs[0]) # node_tree
|
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
|
ngroup.links.new(aa.outputs[0], ng_out.inputs[vl_name]) # node_tree
|
||||||
|
|
||||||
|
aa.mute = scene.use_aa # mute if native AA is used
|
||||||
|
|
||||||
|
|
||||||
fn.reorganise_NG_nodegroup(ng) # decorative
|
fn.reorganise_NG_nodegroup(ng) # decorative
|
||||||
|
|
||||||
|
@ -210,8 +217,10 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||||
def get_set_viewlayer_from_gp(ob, l, scene=None):
|
def get_set_viewlayer_from_gp(ob, l, scene=None):
|
||||||
'''setup ouptut from passed gp obj > layer'''
|
'''setup ouptut from passed gp obj > layer'''
|
||||||
if not scene:
|
if not scene:
|
||||||
# scene = bpy.context.scene
|
if bpy.context.scene.name != 'Scene':
|
||||||
scene = fn.get_render_scene() # create if necessary
|
scene = bpy.context.scene
|
||||||
|
else:
|
||||||
|
scene = fn.get_render_scene()
|
||||||
|
|
||||||
node_tree = scene.node_tree
|
node_tree = scene.node_tree
|
||||||
nodes = node_tree.nodes
|
nodes = node_tree.nodes
|
||||||
|
|
6
ui.py
6
ui.py
|
@ -104,6 +104,7 @@ class GPEXP_PT_gp_node_ui(Panel):
|
||||||
col.separator()
|
col.separator()
|
||||||
|
|
||||||
col.operator('gp.clean_compo_tree', icon='BRUSHES_ALL', text='Clean Nodes') # NODE_CORNER
|
col.operator('gp.clean_compo_tree', icon='BRUSHES_ALL', text='Clean Nodes') # NODE_CORNER
|
||||||
|
col.operator('gp.reset_render_settings', icon='SCENE', text='Reset All Scenes Render Settings')
|
||||||
|
|
||||||
col.separator()
|
col.separator()
|
||||||
|
|
||||||
|
@ -129,17 +130,20 @@ class GPEXP_PT_gp_node_ui(Panel):
|
||||||
col.operator('gp.clear_render_tree', icon='X', text='Clear & Delete Render Scene').mode = "COMPLETE"
|
col.operator('gp.clear_render_tree', icon='X', text='Clear & Delete Render Scene').mode = "COMPLETE"
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.label(text='Sub Scenes:')
|
layout.label(text='Scenes:')
|
||||||
layout.operator('gp.split_to_scene', icon='DUPLICATE', text='Split Selected Obj To Scene')
|
layout.operator('gp.split_to_scene', icon='DUPLICATE', text='Split Selected Obj To Scene')
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator('gp.set_crop_from_selection', icon='CON_OBJECTSOLVER', text='Autoset Crop')
|
row.operator('gp.set_crop_from_selection', icon='CON_OBJECTSOLVER', text='Autoset Crop')
|
||||||
row.operator('gp.export_crop_coord_to_json', icon='FILE', text='Export json')
|
row.operator('gp.export_crop_coord_to_json', icon='FILE', text='Export json')
|
||||||
|
|
||||||
|
layout.label(text='Render:')
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator('gp.render_selected_scenes', icon='RENDER_ANIMATION', text='Render Selected Scene')
|
row.operator('gp.render_selected_scenes', icon='RENDER_ANIMATION', text='Render Selected Scene')
|
||||||
|
row.operator('gp.bg_render_script_selected_scenes', icon='TEXT', text='Gen Batch')
|
||||||
# row.operator('gp.render_all_scenes', icon='RENDER_ANIMATION', text='Render All')
|
# row.operator('gp.render_all_scenes', icon='RENDER_ANIMATION', text='Render All')
|
||||||
|
|
||||||
|
layout.prop(context.scene, 'use_aa', text='Use Native AA Settings')
|
||||||
layout.prop(prefs, 'advanced', text='Show Advanced Options')
|
layout.prop(prefs, 'advanced', text='Show Advanced Options')
|
||||||
# layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'ALL'
|
# layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'ALL'
|
||||||
# layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'SELECTED'
|
# layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'SELECTED'
|
||||||
|
|
Loading…
Reference in New Issue