custom_shelf initial commit

This commit is contained in:
Cos_Min
2022-03-04 12:28:53 +01:00
parent 705b6f2017
commit 232e5cc7f6
45 changed files with 4221 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
info = {
'icon' : 'COPYDOWN',
'description' : 'Go in render node mode waiting for jobs in watchfolder',
'checkfiles' : False,
'stamp' : False,
'cmds' : ''
}
import os
from os import listdir
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
import re
from time import sleep
import time
import datetime
## Blender
import bpy
from mathutils import Vector, Matrix
C = bpy.context
D = bpy.data
scn = scene = C.scene
def submit_to_watchfolder(checkfiles=False):
'''submitter (with or without file_copy)'''
if D.is_dirty or not D.is_saved:
print('!!! Not submitted : File must be saved first')
return
totalframes = scn.frame_end - scn.frame_start
if not overwrite:
#check if output path exists and have file
out = scn.render.filepath
outfolder = dirname(out)
if exists(outfolder):
outname = basename(out)
refile = re.compile(outname.rstrip('#') + r'\d{4}')
outlist = [f for f in listdir(outfolder) if refile.match(f)]
if outlist:
print(f'!!! Abort submission : Overwrite is False and {len(outlist)} files already exists ({totalframes} wanted)')
return
print(f'{totalframes} frames to render')
watchfolder = '/z/___SERIE/WIND-UPS/episodes/00/watchfolder'
if not exists(watchfolder):
print(f'watchfolder not found at {watchfolder}')
watchfolder = '/mnt/admserveur/prod/___SERIE/WIND-UPS/episodes/00/watchfolder'
if not exists(watchfolder):
print(f'ABORT : watchfolder not found at {watchfolder}')
return 1
#save a copy to the file ?
the_file = D.filepath
finalname = basename(D.filepath)
'''
if use_copy:
#save a copy
head, tail = os.path.split(D.filepath)
name, ext = splitext(tail)
uid = datetime.datetime.now().strftime('_rdtemp%Y%m%d%H%M%S')
finalname = name + uid + ext
the_file = join(head, finalname)
bpy.ops.wm.save_as_mainfile(filepath=the_file, copy=True)
link = join(watchfolder, finalname)
print(f'Create symlink:\n src: {finalname}\n dest: {link}')#the_file, complete path to finalname
os.symlink(the_file, link)#impossible to create symlink... so fuck-it.
'''
noext = splitext(finalname)[0]
stby = join(watchfolder, 'stby--' + noext)# + '.txt'
todo = join(watchfolder, 'todo--' + noext)# + '.txt'
running = join(watchfolder, 'runn--' + noext)# + '.txt'
done = join(watchfolder, 'done--' + noext)# + '.txt'
bad = 0
statelist = []
if exists(stby):
statelist.append(basename(stby))
if exists(todo):
statelist.append(basename(todo))
if exists(running):
statelist.append(basename(running))
if exists(done):
statelist.append(basename(done))
for f in os.listdir(watchfolder):
if splitext(f)[0][len('stby--'):] == noext:
print('Something already exists')
if exists(todo):
bad = 1
print(f'{noext}: Job already submitted')
if len(statelist) > 1:
print('problem : job exists in multiple states')
for state in statelist:
print(state)
bad = 1
if bad:
print('skip')
return
with open(todo, 'w') as fd:
fd.write(the_file+'\n')
if info['stamp']:
fd.write('stamp\n')
if info['cmds']:
fd.write(info['cmds'])
print(f'Created job {todo}')
print(f'Submit {basename(D.filepath)}')
submit_to_watchfolder(checkfiles=info['checkfiles'])
@@ -0,0 +1,215 @@
info = {
'icon' : 'RENDER_RESULT',
'description' : 'Pass in render node watchmode (freeze and get job from watchfolder when a todo is available)',
}
import os
from os import listdir
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
import re, fnmatch, glob
from math import radians, degrees
from time import sleep
import datetime
import time
import platform
# Blender
import bpy
from mathutils import Vector, Matrix
C = bpy.context
D = bpy.data
scene = C.scene
## General timer to disable ?
## How to push a key to stop the mega-loop ? (or barbaric ctrl-C in cmd)
def logit(message):
try:
print(message)
with open(log, 'a') as fd:
if not message.endswith('\n'):
message += '\n'
fd.write(message)#add trailing new line
except Exception as e:
print('Log failed', e)
def set_stamp(active_note=False):
rd = bpy.context.scene.render
rd.use_stamp = True
## Enable
rd.use_stamp_filename = True
rd.use_stamp_frame = True
rd.use_stamp_render_time = True
rd.use_stamp_time = True
rd.use_stamp_date = True
## Disable
rd.use_stamp_sequencer_strip = False
rd.use_stamp_marker = False
rd.use_stamp_scene = False
rd.use_stamp_lens = False
rd.use_stamp_camera = False
rd.use_stamp_hostname = False
rd.use_stamp_memory = False
rd.use_stamp_frame_range = False
## Notes
rd.use_stamp_note = active_note
if rd.use_stamp_note:
info = D.texts.get('info')
txt = ''
if info:
for l in info.lines[:2]:
if 'Created from' in l.body:
txt = l.body
if txt:
rd.stamp_note_text = txt
else:#disable notes
rd.use_stamp_note = False
def run(fp):
running = fp.replace('todo--', 'runn--')
stamp = False
warn = []
# Check if a running job already exists
if exists(running):
logit(f'Problem ! job already exists : {running}')
return 1
# Get blend path
with open(fp, 'r') as fd:
# blend = fd.read().strip()
lines = fd.readlines()
blend = lines[0].strip()
stamp = 'stamp' in lines
for l in lines[1:]:#skip filepath
if '=' in l:#skip simple keyword qand focus on assignation
try:
exec(l)
except Exception as e:
print(f'could not exec {l}:\n->{e}')
warn.append(f'could not exec {l}:\n->{e}')
if not blend:
logit(f'Problem reading {fp}')
return 1
# check path
logit(f'Target blend : {blend}')
if not exists(blend):
logit(f'ERROR ! job {basename(running)} give an invalid filepath')
#delete/rename running job
os.rename(running, running.replace('runn--', 'error-'))
return 1
# Pass on job mode
try:
os.rename(fp, running)
except Exception as e:
logit(f'Could not rename job to running mode : {fp} ')
return 1
# write the timestamp and launch the job
with open(running, 'a') as fd:
startmess = f'starting : {str(datetime.datetime.now())}\n'
logit(startmess)
fd.write(startmess)
# Blender time ! open, check output and render the job
start_time = time.time()# get start time
bpy.ops.wm.open_mainfile(filepath=blend)
scn = bpy.context.scene
#here change Ao/filepath/stuff if needed
if stamp:
set_stamp(active_note=True)
else:
bpy.context.scene.render.use_stamp = False
bpy.ops.render.render(animation=True)#anim render
print('Rendering done, launching make_video in 2 sec...')
## log end time and exit
elapsed_time = time.time() - start_time# seconds
full_time = str(datetime.timedelta(seconds=elapsed_time))# hh:mm:ss format
timecode = datetime.datetime.now().strftime('%m%d%H%M')#timecode format '02041139' month+day+hour+minutes
sleep(2)
#no disable auto folder opening after auto video making
if hasattr(scn, 'MVopen'):
scn.MVopen = False
bpy.ops.render.make_video()
with open(running, 'a') as fd:
endmess = f'ended : {str(datetime.datetime.now())}\nrender time: {full_time}\n'
logit(endmess)
fd.write(endmess)
if warn:
fd.write('\n'.join(warn)+'\n')
# rename and move into done folder
donename = basename(running).replace('runn--', 'done--') + f'__{timecode}'#.replace('.txt', f'__{timecode}.txt')
done = join(donefolder, donename)
try:
os.rename(running, done)
except Exception as e:
logit(f'Could not move/rename run job to done : {done} (from {running}) ')
return
print(f'Finished job {basename(running)}, Continue in 5 seconds')
sleep(5)
return 0
###================
def watchmode():
if not bpy.data.is_saved or bpy.data.is_dirty:
print('You need to start from a saved blender file (preferably empty)')
return
if not exists(watchfolder):
print(f'!!!! Abort, watchfolder ({watchfolder}) not found')
return
if not exists(logfolder):
os.mkdir(logfolder)
print('log folder created')
while True:#infinite loop
job_status = 1
todolist = [f for f in os.listdir(watchfolder) if f.startswith('todo--')]
if todolist:
first = todolist[0]
print(f'{len(todolist)} todo, starting: {first}')
fp = join(watchfolder, first)
job_status = run(fp)
print('job_status: ', job_status)
#reopen folder
bpy.ops.wm.open_mainfile(filepath=org_blend)
sleep(300)#5min wait before looping
org_blend = bpy.data.filepath
machine = platform.node().split('.')[0]
if machine:
machine = 'node_' + machine + '.txt'
if not machine:
print('Cannot find machine name')
machine = 'nodes.txt'
print(f'use machine name : {machine}')
watchfolder = '/z/___SERIE/WIND-UPS/episodes/00/watchfolder'
donefolder = join(watchfolder, 'done')
logfolder = join(watchfolder, 'logs')
log = join(logfolder, machine)
watchmode()
print('End of batch.\nEOF')