fix batch

0.6.4

- ui: render selected scene has hints on popup panekl like gen batch
- changed: always re-export crop info when using render all scene and generate batch
- changed: batch file has minutes at the end of the name
- fix: windows dynamic batch problem
main
Pullusb 2021-10-29 16:42:35 +02:00
parent 1f551da12e
commit 2a0c173048
5 changed files with 89 additions and 57 deletions

View File

@ -14,6 +14,13 @@ Activate / deactivate layer opaticty according to prefix
Activate / deactivate all masks using MA layers
-->
0.6.4
- ui: render selected scene has hints on popup panekl like gen batch
- changed: always re-export crop info when using render all scene and generate batch
- changed: batch file has minutes at the end of the name
- fix: windows dynamic batch problem
0.6.3
- fix: show in ui when there is an active dopesheet layer that is not in active object

View File

@ -37,7 +37,9 @@ class GPEXP_OT_export_crop_coord_to_json(bpy.types.Operator):
# if not scn.render.use_border or not scn.render.use_crop_to_border:
# self.report({'ERROR'}, 'Current scene have cropping disabled or use crop_to_border disabled!')
# return {'CANCELLED'}
fn.export_crop_to_json()
crop_dic = fn.export_crop_to_json()
if not crop_dic:
self.report({'ERROR'}, 'No crop to export (Border might be deactivated in all scenes)')
return {"FINISHED"}

View File

@ -47,82 +47,9 @@ class GPEXP_OT_render_all_scenes(bpy.types.Operator):
class GPEXP_scene_select_prop(PropertyGroup):
name : StringProperty()
select: BoolProperty()
class GPEXP_OT_render_selected_scene(bpy.types.Operator):
bl_idname = "gp.render_selected_scenes"
bl_label = "Render Selected Scenes"
bl_description = "Launch render of selected scenes with 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=250)
def draw(self, context):
layout = self.layout
col = layout.column()
for si in context.scene.scenes_list:
row = col.row()
row.label(text=si.name)
row.prop(si, 'select',text='')
def execute(self, context):
scn_to_render = [si.name for si in context.scene.scenes_list if si.select]
start = time()
ct = 0
for scn_name in scn_to_render:
scn = bpy.data.scenes.get(scn_name)
if not scn.use_nodes:
print(f'{scn.name} has use node deactivated')
continue
outfiles = [n for n in scn.node_tree.nodes if n.type == 'OUTPUT_FILE']
if not outfiles:
print(f'\n -!-> Skip {scn.name}, No output files')
continue
if all(x.mute for x in outfiles):
print(f'\n -!-> Skip {scn.name}, All output file are muted')
continue
print(f'\n --> Rendering {scn.name}')
# bpy.context.window.scene = scn # no need
bpy.ops.render.render(animation=True, scene=scn.name)
ct += 1
print(f'\nDone. {ct} scenes rendered in {time()-start:.2f}s')
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):
def scene_render_popup_ui(self, context):
layout = self.layout
col = layout.column()
for si in context.scene.scenes_list:
@ -161,14 +88,105 @@ class GPEXP_OT_bg_render_script_selected_scene(bpy.types.Operator):
row.label(text=f'{muted}/{outnum} output file muted', icon='ERROR')
continue
class GPEXP_OT_render_selected_scene(bpy.types.Operator):
bl_idname = "gp.render_selected_scenes"
bl_label = "Render Selected Scenes"
bl_description = "Launch render of selected scenes with a selection popup"
bl_options = {"REGISTER"}
@classmethod
def poll(cls, context):
return bpy.data.is_saved
def invoke(self, context, event):
# if not bpy.data.is_saved:
# self.report({'ERROR'}, 'File needs to be saved')
# return {'CANCELLED'}
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=250)
def draw(self, context):
## Basic (without hints)
# layout = self.layout
# col = layout.column()
# for si in context.scene.scenes_list:
# row = col.row()
# row.label(text=si.name)
# row.prop(si, 'select',text='')
scene_render_popup_ui(self, context)
def execute(self, context):
d = fn.export_crop_to_json()
if not d:
print('No crop to export, border disabled in all scenes')
scn_to_render = [si.name for si in context.scene.scenes_list if si.select]
start = time()
ct = 0
for scn_name in scn_to_render:
scn = bpy.data.scenes.get(scn_name)
if not scn.use_nodes:
print(f'{scn.name} has use node deactivated')
continue
outfiles = [n for n in scn.node_tree.nodes if n.type == 'OUTPUT_FILE']
if not outfiles:
print(f'\n -!-> Skip {scn.name}, No output files')
continue
if all(x.mute for x in outfiles):
print(f'\n -!-> Skip {scn.name}, All output file are muted')
continue
print(f'\n --> Rendering {scn.name}')
# bpy.context.window.scene = scn # no need
bpy.ops.render.render(animation=True, scene=scn.name)
ct += 1
print(f'\nDone. {ct} scenes rendered in {time()-start:.2f}s')
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 bpy.data.is_saved
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):
scene_render_popup_ui(self, context)
def execute(self, context):
d = fn.export_crop_to_json()
if not d:
print('No crop to export, border disabled in all scenes')
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'
batch_file = blend.parent / f'{blend.stem}--{len(scn_to_render)}batch_{strftime("%m-%d_%H-%M")}.sh'
if platform.startswith('win'):
script_text = ['@ECHO OFF']
@ -177,27 +195,31 @@ class GPEXP_OT_bg_render_script_selected_scene(bpy.types.Operator):
script_text = ['#!/bin/bash']
print('batch_file: ', batch_file)
bin_path = bpy.app.binary_path
for scn_name in scn_to_render:
if platform.startswith('win'):
import re
pattern = r'users[\/\\](.*?)[\/\\]softs' # or point to user dit with %UserProfile%
re_user = re.search(pattern, bpy.app.binary_path)
re_user = re.search(pattern, bin_path, re.I)
if not re_user:
cmd = f'"{bpy.app.binary_path}" -b "{bpy.data.filepath}" -S "{scn_name}" -a'
cmd = f'"{bin_path}" -b "{bpy.data.filepath}" -S "{scn_name}" -a'
else:
bin_path = bpy.app.binary_path.replace(re_user.group(1), '%USERNAME%')
bin_path = bin_path.replace(re_user.group(1), '%USERNAME%')
cmd = f'"{bin_path}" -b "{bpy.data.filepath}" -S "{scn_name}" -a'
else: # Unix : point same for each user
cmd = f'"{bpy.app.binary_path}" -b "{bpy.data.filepath}" -S "{scn_name}" -a'
cmd = f'"{bin_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))
print(f'Using following binary path: {bin_path}')
self.report({'INFO'}, f'Batch script generated: {batch_file}')
return {"FINISHED"}

View File

@ -2,7 +2,7 @@ bl_info = {
"name": "GP Render",
"description": "Organise export of gp layers through compositor output",
"author": "Samuel Bernou",
"version": (0, 6, 3),
"version": (0, 6, 4),
"blender": (2, 93, 0),
"location": "View3D",
"warning": "",

1
fn.py
View File

@ -828,6 +828,7 @@ def export_crop_to_json():
for ob in [o for o in scn.objects if o.type == 'GPENCIL']:
coord_dic[ob.name] = scn_border
if coord_dic:
# save bbox
with json_path.open('w') as fd:
json.dump(coord_dic, fd, indent='\t')