folder removed
parent
1bb4d722c6
commit
10afe009fb
|
@ -1,59 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'LIGHT_SPOT',
|
|
||||||
'description' : 'Save as lighting file from currently opened anim file',
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_lighting_file():
|
|
||||||
'''Create lighting_v001 file from anim'''
|
|
||||||
# if D.is_dirty:
|
|
||||||
# print('Current file is not saved')
|
|
||||||
# return
|
|
||||||
|
|
||||||
if 'lighting' in D.filepath:
|
|
||||||
print('File already detected as lighting')
|
|
||||||
return
|
|
||||||
|
|
||||||
if not 'animation' in D.filepath:
|
|
||||||
print('Not in animation folder')
|
|
||||||
return
|
|
||||||
|
|
||||||
name = re.sub(r'anim_v\d{3}', 'lighting_v001', basename(D.filepath))
|
|
||||||
print('name: ', name)
|
|
||||||
|
|
||||||
fp = dirname(dirname(D.filepath))
|
|
||||||
print('shot path: ', fp)
|
|
||||||
fp = join(fp, 'lighting', name)
|
|
||||||
print('light filepath: ', fp)
|
|
||||||
|
|
||||||
if exists(fp):
|
|
||||||
print('lighting_v001 already exists in folder')
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
info = D.texts.get('info')
|
|
||||||
if not info:
|
|
||||||
info = D.texts.new('info')
|
|
||||||
|
|
||||||
info.write(f'\nCreated from {basename(D.filepath)} at {str( datetime.datetime.now() )}')
|
|
||||||
print('Saving current file as lighting')
|
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=fp)
|
|
||||||
|
|
||||||
print('Done')
|
|
||||||
|
|
||||||
create_lighting_file()
|
|
|
@ -1,43 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'CHECKMARK',
|
|
||||||
'description' : 'Check objects modifiers',
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os, re, shutil
|
|
||||||
from os.path import dirname, basename, join, abspath, splitext, exists, isfile, isdir
|
|
||||||
from os import listdir
|
|
||||||
import datetime
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scn = scene = C.scene
|
|
||||||
|
|
||||||
## in scene syubloop ob.instance_collection.all_objects:
|
|
||||||
|
|
||||||
print(f'\n== Modifiers check {basename(D.filepath)} ==')
|
|
||||||
for ob in bpy.data.objects:
|
|
||||||
if ob.type != 'ARMATURE' and ob.hide_viewport != ob.hide_render:
|
|
||||||
print(f'/!\ {ob.name} view != render : hide_viewport {ob.hide_viewport}, hide_render {ob.hide_render}')
|
|
||||||
|
|
||||||
if ob.type in ('MESH', 'CURVE', 'TEXT') and len(ob.modifiers) > 0:
|
|
||||||
for mod in ob.modifiers:
|
|
||||||
#mod.show_viewport = True
|
|
||||||
#mod.show_render = True
|
|
||||||
if mod.type == 'SUBSURF':
|
|
||||||
# print (ob.name)
|
|
||||||
if mod.render_levels < mod.levels:
|
|
||||||
print(f'[M] {ob.name} subsurf render levels inferior to viewport : view {mod.levels} > render {mod.render_levels}')
|
|
||||||
elif mod.render_levels == 0:
|
|
||||||
print(f'[M] {ob.name} subsurf useless : render levels set to 0 : view {mod.levels} > render {mod.render_levels}')
|
|
||||||
'''
|
|
||||||
if mod.type == 'ARMATURE':
|
|
||||||
if mod.object:
|
|
||||||
print (mod.object.name)#print armatrue target
|
|
||||||
#ob.modifiers.remove(mod) #remove modifier
|
|
||||||
|
|
||||||
if mod.type == 'SOLIDIFY':
|
|
||||||
mod.thickness
|
|
||||||
mod.offset
|
|
||||||
'''
|
|
||||||
|
|
||||||
print('== check done.')
|
|
|
@ -1,68 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'DECORATE_LIBRARY_OVERRIDE',
|
|
||||||
'description' : 'Check available library update',
|
|
||||||
'update' : False,
|
|
||||||
'fullreport': False,
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir, scandir
|
|
||||||
from os.path import abspath, relpath, join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
auto_update = info['update']#False
|
|
||||||
fullreport = info['fullreport']
|
|
||||||
|
|
||||||
## 1: all execpt num, 2: num, 3:ext
|
|
||||||
rseq = re.compile('^(.*?)(\d+)(\D*)$')
|
|
||||||
|
|
||||||
|
|
||||||
print('\n--library check--')
|
|
||||||
for ob in bpy.context.scene.objects:
|
|
||||||
if not ob.type == 'EMPTY': continue
|
|
||||||
if not ob.instance_collection: continue
|
|
||||||
if not ob.instance_collection.library: continue
|
|
||||||
lib = ob.instance_collection.library
|
|
||||||
if not lib: continue
|
|
||||||
fp = lib.filepath
|
|
||||||
if not fp: continue
|
|
||||||
rel_dir = dirname(fp)
|
|
||||||
abs_lib = abspath(bpy.path.abspath(fp))
|
|
||||||
if not exists(abs_lib):
|
|
||||||
print(f'Lib not found: obj: {ob.name} > instance: {ob.instance_collection.name}\n-> {abs_lib}')
|
|
||||||
continue
|
|
||||||
lib_dir = dirname(abs_lib)
|
|
||||||
lib_name = basename(abs_lib)
|
|
||||||
|
|
||||||
#same length ? #last modified ? #last by name without #must be 90% identical ? # parts without rightmost number must be identical (good enough)
|
|
||||||
regname = rseq.search(lib_name)
|
|
||||||
if not regname:
|
|
||||||
print(f'X - {lib_name} : could not identify version using regex: {rseq.pattern}')
|
|
||||||
continue
|
|
||||||
name_base = regname.group(1)
|
|
||||||
|
|
||||||
# filelist = [f for f in scandir(lib_dir) if f.is_file() and len(f.name) == len(lib_name)]
|
|
||||||
|
|
||||||
# more strict with filename
|
|
||||||
filelist = [f for f in scandir(lib_dir) if f.is_file() and len(f.name) == len(lib_name) and rseq.search(f.name) and rseq.search(f.name).group(1) == name_base]
|
|
||||||
filelist.sort(key=lambda x : x.name)#sort in place alphabetically
|
|
||||||
|
|
||||||
last = filelist[-1]
|
|
||||||
if last.name != lib.name:
|
|
||||||
print(f'/!\ Lib update found : obj: {ob.name} > instance: {ob.instance_collection.name}\n {lib_name} >> {last.name}\n')
|
|
||||||
|
|
||||||
if auto_update:
|
|
||||||
### use relocate or do it automagically...
|
|
||||||
nfp = join(dirname(fp), last.name)
|
|
||||||
lib.filepath = nfp
|
|
||||||
continue
|
|
||||||
|
|
||||||
if fullreport: print(f'Lib OK : obj: {ob.name} > instance: {ob.instance_collection.name} > file: {lib_name}')
|
|
||||||
## make breakdown popup for addon version
|
|
||||||
|
|
|
@ -1,121 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'TOOL_SETTINGS',
|
|
||||||
'description' : 'Set render path for PNG - RGB out',
|
|
||||||
'stamp' : False
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scn = scene = C.scene
|
|
||||||
rd = scn.render
|
|
||||||
ev = scn.eevee
|
|
||||||
|
|
||||||
def render_anim(GL=False):
|
|
||||||
#openGl render
|
|
||||||
if GL:
|
|
||||||
bpy.ops.render.opengl(animation=True, view_context=False)#view_context False > look throughcam
|
|
||||||
else:
|
|
||||||
bpy.ops.render.render(animation=True)
|
|
||||||
|
|
||||||
def set_stamp(active_note=False):
|
|
||||||
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 setup_render_params(use_stamp=False):
|
|
||||||
'''set dimensions, percentage, fps...'''
|
|
||||||
if use_stamp:
|
|
||||||
set_stamp(active_note=True)
|
|
||||||
else:
|
|
||||||
rd.use_stamp = False
|
|
||||||
|
|
||||||
rd.resolution_x = 1920
|
|
||||||
rd.resolution_y = 1080
|
|
||||||
rd.resolution_percentage = 100
|
|
||||||
rd.use_border = False
|
|
||||||
rd.fps = 25
|
|
||||||
rd.use_sequencer = False
|
|
||||||
|
|
||||||
#sampling
|
|
||||||
ev.taa_render_samples = 128#push up sample for shadow mainly
|
|
||||||
|
|
||||||
#AO
|
|
||||||
ev.use_gtao = True
|
|
||||||
ev.gtao_distance = 0.7
|
|
||||||
ev.gtao_factor = 0.7
|
|
||||||
ev.gtao_quality = 0.2
|
|
||||||
ev.use_gtao_bent_normals = False#bent normal makes it lighter than shadows !
|
|
||||||
#not sure...
|
|
||||||
ev.use_gtao_bounce = True#no bounce is darker... (less AO on claer object)
|
|
||||||
|
|
||||||
#setup color management
|
|
||||||
scene.view_settings.look = 'Filmic - Medium High Contrast'
|
|
||||||
|
|
||||||
#no disable auto folder opening after auto video making
|
|
||||||
if hasattr(scene, 'MVopen'):
|
|
||||||
scene.MVopen = False
|
|
||||||
|
|
||||||
|
|
||||||
def set_render_path():
|
|
||||||
setup_render_params(use_stamp=info['stamp'])
|
|
||||||
rd.image_settings.file_format = 'PNG'
|
|
||||||
rd.image_settings.color_mode = 'RGB'#A
|
|
||||||
rd.image_settings.color_depth = '8'
|
|
||||||
rd.use_file_extension = True
|
|
||||||
rd.use_overwrite = True#erase file
|
|
||||||
rd.use_placeholder = False
|
|
||||||
rd.image_settings.compression = 50#default = 15, high = slower and lighter (same quality)
|
|
||||||
|
|
||||||
filename = splitext(basename(D.filepath))[0]
|
|
||||||
# fp = join(dirname(D.filepath), 'render')
|
|
||||||
|
|
||||||
|
|
||||||
rd.filepath = join(dirname(D.filepath), 'images', filename, filename + '.')# '.####' #let a dot to separate padding number
|
|
||||||
|
|
||||||
set_render_path()
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
start = time()
|
|
||||||
render_anim(GL=False)
|
|
||||||
print(f'elapsed {time() - start}')
|
|
||||||
'''
|
|
|
@ -1,155 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'TOOL_SETTINGS',
|
|
||||||
'description' : 'Set filepath and video settings for direct video out',
|
|
||||||
'stamp' : False
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scn = scene = C.scene
|
|
||||||
rd = scn.render
|
|
||||||
ev = scn.eevee
|
|
||||||
|
|
||||||
def set_stamp(active_note=False):
|
|
||||||
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 setup_render_params(use_stamp=False):
|
|
||||||
'''set dimensions, percentage, fps...'''
|
|
||||||
if use_stamp:
|
|
||||||
set_stamp(active_note=True)
|
|
||||||
else:
|
|
||||||
rd.use_stamp = False
|
|
||||||
|
|
||||||
rd.resolution_x = 1920
|
|
||||||
rd.resolution_y = 1080
|
|
||||||
rd.resolution_percentage = 100
|
|
||||||
rd.use_border = False
|
|
||||||
rd.fps = 25
|
|
||||||
rd.use_sequencer = False
|
|
||||||
|
|
||||||
#sampling
|
|
||||||
ev.taa_render_samples = 128#push up sample for shadow mainly
|
|
||||||
|
|
||||||
#AO
|
|
||||||
ev.use_gtao = True
|
|
||||||
ev.gtao_distance = 0.7
|
|
||||||
ev.gtao_factor = 0.7
|
|
||||||
ev.gtao_quality = 0.2
|
|
||||||
ev.use_gtao_bent_normals = False#bent normal makes it lighter than shadows !
|
|
||||||
#not sure...
|
|
||||||
ev.use_gtao_bounce = True#no bounce is darker... (less AO on claer object)
|
|
||||||
|
|
||||||
#setup color management
|
|
||||||
scene.view_settings.look = 'Filmic - Medium High Contrast'
|
|
||||||
|
|
||||||
#no disable auto folder opening after auto video making
|
|
||||||
if hasattr(scene, 'MVopen'):
|
|
||||||
scene.MVopen = False
|
|
||||||
|
|
||||||
def render_anim(GL=False):
|
|
||||||
#openGl render
|
|
||||||
if GL:
|
|
||||||
bpy.ops.render.opengl(animation=True, view_context=False)#view_context False > look throughcam
|
|
||||||
else:
|
|
||||||
bpy.ops.render.render(animation=True)
|
|
||||||
|
|
||||||
|
|
||||||
def check_name(name, fp):
|
|
||||||
filelist = [splitext(f)[0] for f in os.listdir(fp)]#raw names
|
|
||||||
if not name in filelist:
|
|
||||||
return name
|
|
||||||
|
|
||||||
ct = 2
|
|
||||||
new = name + '_' + str(ct).zfill(2)
|
|
||||||
while new in filelist:
|
|
||||||
new = name + '_' + str(ct).zfill(2)
|
|
||||||
ct+=1
|
|
||||||
if ct > 99:
|
|
||||||
return None
|
|
||||||
return new
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def set_video_path():
|
|
||||||
setup_render_params(use_stamp=info['stamp'])
|
|
||||||
rd.image_settings.file_format = 'FFMPEG'
|
|
||||||
rd.image_settings.color_mode = 'RGB'
|
|
||||||
rd.ffmpeg.codec = 'H264'
|
|
||||||
rd.ffmpeg.constant_rate_factor = 'HIGH'#default 'MEDIUM'
|
|
||||||
rd.ffmpeg.format = 'MPEG4'#'MKV', 'QUICKTIME'
|
|
||||||
rd.ffmpeg.ffmpeg_preset = 'GOOD'#default = 'GOOD'(compromise), BEST(light - slow), REALTIME(fat-fast)'
|
|
||||||
|
|
||||||
ext = ''
|
|
||||||
if rd.ffmpeg.format == 'MPEG4':
|
|
||||||
ext = '.mp4'
|
|
||||||
elif rd.ffmpeg.format == 'QUICKTIME':
|
|
||||||
ext = '.mov'
|
|
||||||
elif rd.ffmpeg.format == 'MKV':
|
|
||||||
ext = '.mkv'
|
|
||||||
|
|
||||||
filename = splitext(basename(D.filepath))[0]
|
|
||||||
fp = join(dirname(D.filepath), 'images')
|
|
||||||
|
|
||||||
if not exists(fp):
|
|
||||||
print(f'not found : {fp} ')
|
|
||||||
return
|
|
||||||
|
|
||||||
filename = check_name(filename, fp)
|
|
||||||
if not filename:
|
|
||||||
print('name not available')
|
|
||||||
return
|
|
||||||
|
|
||||||
rd.filepath = join(dirname(D.filepath), 'images', filename + ext)
|
|
||||||
|
|
||||||
|
|
||||||
set_video_path()
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
start = time()
|
|
||||||
render_anim(GL=False)
|
|
||||||
print(f'elapsed {time() - start}')
|
|
||||||
'''
|
|
|
@ -1,39 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'RENDER_ANIMATION',
|
|
||||||
'description' : 'render timed',
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
from time import time
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scn = scene = C.scene
|
|
||||||
rd = scn.render
|
|
||||||
|
|
||||||
|
|
||||||
def render_anim(GL=False):
|
|
||||||
#openGl render
|
|
||||||
if GL:
|
|
||||||
bpy.ops.render.opengl(animation=True, view_context=True)#view_context False > look throughcam
|
|
||||||
else:
|
|
||||||
bpy.ops.render.render(animation=True)
|
|
||||||
|
|
||||||
start = time()
|
|
||||||
|
|
||||||
render_anim()
|
|
||||||
|
|
||||||
secs = time() - start
|
|
||||||
timesec_str = f'elapsed {secs} seconds'
|
|
||||||
time_str = str(datetime.timedelta(seconds=secs))
|
|
||||||
|
|
||||||
print(timesec_str)
|
|
||||||
print(time_str)
|
|
||||||
C.window_manager.clipboard = time_str
|
|
|
@ -1,39 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'RENDER_ANIMATION',
|
|
||||||
'description' : 'render this viewport openGL',
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
from time import time
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scn = scene = C.scene
|
|
||||||
rd = scn.render
|
|
||||||
|
|
||||||
|
|
||||||
def render_anim(GL=False):
|
|
||||||
#openGl render
|
|
||||||
if GL:
|
|
||||||
bpy.ops.render.opengl(animation=True, view_context=True)#view_context False > look throughcam
|
|
||||||
else:
|
|
||||||
bpy.ops.render.render(animation=True)
|
|
||||||
|
|
||||||
start = time()
|
|
||||||
|
|
||||||
render_anim(GL=True)
|
|
||||||
|
|
||||||
secs = time() - start
|
|
||||||
timesec_str = f'elapsed {secs} seconds'
|
|
||||||
time_str = str(datetime.timedelta(seconds=secs))
|
|
||||||
|
|
||||||
print(timesec_str)
|
|
||||||
print(time_str)
|
|
||||||
C.window_manager.clipboard = time_str
|
|
|
@ -1,62 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'RENDER_STILL',
|
|
||||||
'description' : 'render still image timed',
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
from time import time
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scn = scene = C.scene
|
|
||||||
rd = scn.render
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def pad_with_current_frame(match):
|
|
||||||
return str(C.scene.frame_current).zfill(len(match.group(0)))
|
|
||||||
|
|
||||||
def add_frame_padding(name):
|
|
||||||
'''
|
|
||||||
return string padded with current blender frame
|
|
||||||
if # found, use this padding to write theframe
|
|
||||||
'''
|
|
||||||
import re
|
|
||||||
if not '#' in name: return name + str(C.scene.frame_current).zfill(4)
|
|
||||||
# return re.sub(r'\#{1,10}', pad_with_current_frame, name)# all '#...' in string
|
|
||||||
return re.sub(r'\#{1,10}(?!.*\#)', pad_with_current_frame, name)# only last '#...'
|
|
||||||
|
|
||||||
|
|
||||||
def render(anim=False, GL=False):
|
|
||||||
if GL:#openGl render
|
|
||||||
bpy.ops.render.opengl(animation=anim, write_still=True, view_context=True)#view_context False > look throughcam
|
|
||||||
else:
|
|
||||||
bpy.ops.render.render(animation=anim, write_still=True)
|
|
||||||
|
|
||||||
start = time()
|
|
||||||
|
|
||||||
orgfp = C.scene.render.filepath
|
|
||||||
C.scene.render.filepath = add_frame_padding(C.scene.render.filepath)
|
|
||||||
|
|
||||||
try:
|
|
||||||
render(anim=False)
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
finally:
|
|
||||||
C.scene.render.filepath = orgfp
|
|
||||||
|
|
||||||
secs = time() - start
|
|
||||||
timesec_str = f'elapsed {secs} seconds'
|
|
||||||
time_str = str(datetime.timedelta(seconds=secs))
|
|
||||||
|
|
||||||
print(timesec_str)
|
|
||||||
print(time_str)
|
|
||||||
C.window_manager.clipboard = time_str
|
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'PACKAGE',
|
|
||||||
'description' : 'pack all videos',
|
|
||||||
'dryrun' : False
|
|
||||||
}
|
|
||||||
|
|
||||||
import os, re, shutil
|
|
||||||
from os.path import dirname, basename, join, abspath, splitext, exists, isfile, isdir
|
|
||||||
from os import listdir
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
|
|
||||||
dryrun = info['dryrun']
|
|
||||||
|
|
||||||
resid = re.compile(r'\d{2}-\d{3}-\d{2}$')
|
|
||||||
|
|
||||||
shots = '/z/___SERIE/WIND-UPS/episodes/00/shots/'
|
|
||||||
|
|
||||||
packzone = '/z/___SERIE/WIND-UPS/medias/pack'
|
|
||||||
old_folder = join(packzone, '_old')
|
|
||||||
|
|
||||||
new_list = []
|
|
||||||
warning = []
|
|
||||||
|
|
||||||
extension_filter = ('mp4', 'mov',)#, 'mkv'
|
|
||||||
exclusion_words = ('test', 'old',)#use this for loose word search
|
|
||||||
rexclude = re.compile(r'[ _-]old|test')#old if after separator (' _-') and word test anywhere (might be too loose)
|
|
||||||
|
|
||||||
for f in os.scandir(shots):
|
|
||||||
if not resid.match(f.name):continue
|
|
||||||
|
|
||||||
imgfp = f'/z/___SERIE/WIND-UPS/episodes/00/shots/{f.name}/lighting/images'
|
|
||||||
if not exists(imgfp):continue
|
|
||||||
|
|
||||||
#need to be video file type
|
|
||||||
all_videos = [v for v in os.scandir(imgfp) if v.name.lower().endswith(extension_filter) and not rexclude.search(v.name)]#any(x in v.name for x in exclusion_words)
|
|
||||||
if not all_videos:continue
|
|
||||||
|
|
||||||
print(f'\n{f.name}')
|
|
||||||
|
|
||||||
bytime = sorted(all_videos, key=lambda x: x.stat().st_mtime)
|
|
||||||
byname = sorted(all_videos, key=lambda x: x.name)
|
|
||||||
# print('bytime: ', bytime[-1].name)
|
|
||||||
# print('byname: ', byname[-1].name)
|
|
||||||
|
|
||||||
if bytime[-1] != byname[-1]:
|
|
||||||
warn = f'''/!\\ {f.name}
|
|
||||||
last by name and by modif time different in {imgfp}
|
|
||||||
by time : {bytime[-1].name} ({datetime.datetime.fromtimestamp(bytime[-1].stat().st_mtime)})
|
|
||||||
by name : {byname[-1].name} ({datetime.datetime.fromtimestamp(byname[-1].stat().st_mtime)})
|
|
||||||
'''
|
|
||||||
print(warn)
|
|
||||||
warning.append(warn)
|
|
||||||
|
|
||||||
good_file = bytime[-1]
|
|
||||||
topack = good_file.path
|
|
||||||
topackname = good_file.name
|
|
||||||
dest = join(packzone, topackname)
|
|
||||||
|
|
||||||
# run checks and copy if needed
|
|
||||||
if exists(dest):
|
|
||||||
dup = [basename(dest)]
|
|
||||||
else:
|
|
||||||
print(f"compare with {'_'.join(splitext(good_file.name)[0].split('_')[:3])}")
|
|
||||||
# ex : twu_00-008-01_lighting_v001.mp4 (split on third to)
|
|
||||||
dup = [i for i in listdir(packzone) if isfile(join(packzone, i)) and '_'.join(splitext(i)[0].split('_')[:3]) == '_'.join(splitext(good_file.name)[0].split('_')[:3])]
|
|
||||||
|
|
||||||
# check duplication against this file
|
|
||||||
if dup:
|
|
||||||
print(f'same shot already exists:{dup}')
|
|
||||||
newer = True
|
|
||||||
for i in dup:
|
|
||||||
dfp = join(packzone, i)
|
|
||||||
# print(f'{os.stat(dfp).st_mtime} VS file {good_file.stat().st_mtime}')
|
|
||||||
if os.stat(dfp).st_mtime >= good_file.stat().st_mtime:
|
|
||||||
# print(f'{i} is same or most recent')
|
|
||||||
newer = False
|
|
||||||
|
|
||||||
if not newer:
|
|
||||||
print(f'{good_file.name} is not newer, skip')
|
|
||||||
continue
|
|
||||||
|
|
||||||
#src is most recent, do the copy and erase/move older
|
|
||||||
for d in dup:
|
|
||||||
if not exists(old_folder):os.mkdir(old_folder)
|
|
||||||
old_src = join(packzone, d)
|
|
||||||
old_dest = join(old_folder, d)
|
|
||||||
if exists(old_dest):
|
|
||||||
print(f' - deleting {d} (already in _old)')
|
|
||||||
if not dryrun: os.remove(old_src)
|
|
||||||
else:
|
|
||||||
print(f' - moving {d} to _old')
|
|
||||||
if not dryrun: shutil.move(old_src, old_dest)
|
|
||||||
|
|
||||||
# if made it here, safely do the copy
|
|
||||||
print(f'- packing new file : {topack}')
|
|
||||||
if not dryrun: shutil.copy2(topack, dest)
|
|
||||||
new_list.append(f'{topackname} : {topack}')
|
|
||||||
|
|
||||||
|
|
||||||
print('DONE\n----')
|
|
||||||
|
|
||||||
if warning:
|
|
||||||
print('\nWarnings')
|
|
||||||
for w in warning: print(w)
|
|
||||||
|
|
||||||
if new_list:
|
|
||||||
print(f'\n{len(new_list)} New:')
|
|
||||||
for n in new_list: print(n)
|
|
|
@ -1,119 +0,0 @@
|
||||||
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'])
|
|
|
@ -1,215 +0,0 @@
|
||||||
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')
|
|
|
@ -1,30 +0,0 @@
|
||||||
# coding: utf-8
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
print('====')
|
|
||||||
|
|
||||||
'''
|
|
||||||
for i in range(0, 8):
|
|
||||||
ao = i * 0.25
|
|
||||||
scene.eevee.gtao_distance = ao
|
|
||||||
scene.render.filepath = join(dirname(D.filepath), f'{splitext(basename(D.filepath))[0]}-{scene.frame_current}_AO{i}-{ao}')
|
|
||||||
bpy.ops.render.render(animation=False, write_still=True)
|
|
||||||
'''
|
|
||||||
|
|
||||||
for i in range(0, 8):
|
|
||||||
fac = 1 - i * 0.1
|
|
||||||
#scene.eevee.gtao_distance = ao
|
|
||||||
scene.eevee.gtao_factor = fac
|
|
||||||
scene.render.filepath = join(dirname(D.filepath), f'{splitext(basename(D.filepath))[0]}-{scene.frame_current}_AOfac{i}-{fac}')
|
|
||||||
bpy.ops.render.render(animation=False, write_still=True)
|
|
||||||
|
|
||||||
print('done')
|
|
|
@ -1,37 +0,0 @@
|
||||||
# coding: utf-8
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
print('====')
|
|
||||||
def more_sss(val=0.04):
|
|
||||||
for mat in D.materials:
|
|
||||||
if not mat.use_nodes:continue
|
|
||||||
nodes = mat.node_tree
|
|
||||||
if not nodes: continue
|
|
||||||
nodes = nodes.nodes
|
|
||||||
|
|
||||||
for n in nodes:
|
|
||||||
if n.type == 'GROUP':
|
|
||||||
sss = n.inputs.get('Subsurface')
|
|
||||||
if not sss: continue
|
|
||||||
#print(f'{mat.name} : {sss.default_value}')
|
|
||||||
current = sss.default_value
|
|
||||||
new = current + val
|
|
||||||
print(f'{mat.name} : {current} >> {new}')
|
|
||||||
sss.default_value = new
|
|
||||||
|
|
||||||
|
|
||||||
value = 0.06
|
|
||||||
for i in range(0, 8):
|
|
||||||
scene.render.filepath = join(dirname(D.filepath), f'{splitext(basename(D.filepath))[0]}-{scene.frame_current}_sss_plus_0.{str(i*6).zfill(2)}')
|
|
||||||
bpy.ops.render.render(animation=False, write_still=True)
|
|
||||||
more_sss(value)
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
# coding: utf-8
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
print('====')
|
|
||||||
def print_sss():
|
|
||||||
for mat in D.materials:
|
|
||||||
if not mat.use_nodes:continue
|
|
||||||
nodes = mat.node_tree
|
|
||||||
if not nodes: continue
|
|
||||||
nodes = nodes.nodes
|
|
||||||
|
|
||||||
for n in nodes:
|
|
||||||
if n.type == 'GROUP':
|
|
||||||
sss = n.inputs.get('Subsurface')
|
|
||||||
if not sss: continue
|
|
||||||
print(f'{mat.name} : {sss.default_value}')
|
|
||||||
if n.type == 'BSDF_PRINCIPLED':
|
|
||||||
sss = n.inputs.get('Subsurface')
|
|
||||||
if not sss: continue
|
|
||||||
print(f'PRINCIPLED : {mat.name} : {sss.default_value}')
|
|
||||||
|
|
||||||
|
|
||||||
print_sss()
|
|
|
@ -1,58 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'LINENUMBERS_ON',
|
|
||||||
'description' : 'Note and render',
|
|
||||||
'render' : False,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
print('====')
|
|
||||||
|
|
||||||
scene.render.use_stamp_note = True
|
|
||||||
|
|
||||||
dist = scene.eevee.gtao_distance
|
|
||||||
fac = scene.eevee.gtao_factor
|
|
||||||
print('dist: ', dist)
|
|
||||||
print('fac: ', fac)
|
|
||||||
|
|
||||||
dist = round(dist, 2)
|
|
||||||
fac = round(fac, 2)
|
|
||||||
|
|
||||||
scene.render.stamp_note_text = f'AO dist {dist} fac {fac}'
|
|
||||||
|
|
||||||
if scene.view_settings.look != 'Filmic - Medium Contrast':
|
|
||||||
scene.render.stamp_note_text += f' - {scene.view_settings.look}'
|
|
||||||
|
|
||||||
|
|
||||||
org = scene.render.filepath
|
|
||||||
print(f'filepath was : {org}')
|
|
||||||
|
|
||||||
## full filename
|
|
||||||
# scene.render.filepath = join(dirname(D.filepath), f'{splitext(basename(D.filepath))[0]}-{scene.frame_current}_AO-dist{dist}-fac{fac}')
|
|
||||||
|
|
||||||
## custom filename
|
|
||||||
ep = int(re.search(r"(\d{3})", splitext(basename(D.filepath))[0]).group(1))
|
|
||||||
print('ep: ', ep)
|
|
||||||
scene.render.filepath = join(dirname(D.filepath), f'twu_{ep}-{scene.frame_current}_AO-dist{dist}-fac{fac}')
|
|
||||||
|
|
||||||
i = 2#increment if needed
|
|
||||||
while exists(scene.render.filepath + '.png'):
|
|
||||||
scene.render.filepath = join(dirname(D.filepath), f'twu_{ep}-{scene.frame_current}_AO-dist{dist}-fac{fac}_{i}')
|
|
||||||
|
|
||||||
if info['render']:
|
|
||||||
bpy.ops.render.render(animation=False, write_still=True)
|
|
||||||
# restore old sauce ?
|
|
||||||
scene.render.filepath = org
|
|
||||||
|
|
||||||
print('done')
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'FILE_TEXT',
|
|
||||||
'description' : 'explore API in console at datapath of the popup',
|
|
||||||
'data_path' : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy, mathutils
|
|
||||||
|
|
||||||
exclude = (
|
|
||||||
### add lines here to exclude specific attribute
|
|
||||||
'bl_rna', 'identifier','name_property','rna_type','properties',#basic
|
|
||||||
## To avoid recursion/crash on direct object call (comment for API check on deeper props)
|
|
||||||
'data', 'edges', 'faces', 'edge_keys', 'polygons', 'loops', 'face_maps', 'original',
|
|
||||||
## Avoid some specific properties
|
|
||||||
#'matrix_local', 'matrix_parent_inverse', 'matrix_basis','location','rotation_euler', 'rotation_quaternion', 'rotation_axis_angle', 'scale', 'translation',
|
|
||||||
)
|
|
||||||
|
|
||||||
def list_attr(path, ct=0):
|
|
||||||
for attr in dir(eval(path)):
|
|
||||||
if not attr.startswith('__') and not attr in exclude:
|
|
||||||
try:
|
|
||||||
value = getattr(eval(path),attr)
|
|
||||||
except AttributeError:
|
|
||||||
value = None
|
|
||||||
if value != None:
|
|
||||||
if not callable(value):
|
|
||||||
if type(value) in ( type(0),type(0.0),type(True),type('str'),type(mathutils.Vector()),type(mathutils.Color()), type(mathutils.Matrix()) ):
|
|
||||||
print(ct*' ' + attr, value)
|
|
||||||
else:
|
|
||||||
print(ct*' ' + attr,value,type(value))
|
|
||||||
ct+=1
|
|
||||||
# print (ct*' ' + '>')
|
|
||||||
list_attr('%s.%s'%(path,attr), ct)#Comment this line to kill recursion
|
|
||||||
|
|
||||||
|
|
||||||
print('---')
|
|
||||||
# write datapath as string. ex : "bpy.data.objects['Cube'].modifiers['Softbody']"
|
|
||||||
|
|
||||||
dt = info['data_path']
|
|
||||||
if dt:
|
|
||||||
list_attr(dt)
|
|
||||||
print ('Done')
|
|
||||||
else:
|
|
||||||
print('no data path given')
|
|
|
@ -1,56 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'EVENT_X',
|
|
||||||
'description' : 'Delete all blend backup version (.blend1 and next backups) in passed directory',
|
|
||||||
'folderpath' : '',
|
|
||||||
'recursive' : True,
|
|
||||||
'test' : False,
|
|
||||||
}
|
|
||||||
|
|
||||||
# coding: utf-8
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from pathlib import Path
|
|
||||||
import shutil
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
|
|
||||||
def kill_blend_backup_version(fp, recursive=True, test=False):
|
|
||||||
if not fp:
|
|
||||||
print('ERROR', 'no filepath given')
|
|
||||||
return
|
|
||||||
|
|
||||||
re_blendbackup = re.compile(r'\.blend\d+')
|
|
||||||
fpo = Path(fp)
|
|
||||||
|
|
||||||
if not fpo.exists():
|
|
||||||
print('ERROR', f'invalid path: {fp}')
|
|
||||||
return
|
|
||||||
|
|
||||||
ct = 0
|
|
||||||
print(f'Removing blend backup files in : {fpo}')
|
|
||||||
if recursive:
|
|
||||||
for root, dirs, files in os.walk(fp):
|
|
||||||
for name in files:
|
|
||||||
fo = Path(root) / name
|
|
||||||
if re_blendbackup.match(fo.suffix):
|
|
||||||
ct += 1
|
|
||||||
print(fo)
|
|
||||||
if not test:
|
|
||||||
fo.unlink()
|
|
||||||
|
|
||||||
else:
|
|
||||||
for f in os.listdir(fp):
|
|
||||||
fo = Path(fp) / f
|
|
||||||
if re_blendbackup.match(fo.suffix):
|
|
||||||
ct += 1
|
|
||||||
print(fo)
|
|
||||||
if not test:
|
|
||||||
fo.unlink()
|
|
||||||
|
|
||||||
if ct:
|
|
||||||
print('INFO', f'Deleted {ct} file(s)')
|
|
||||||
|
|
||||||
kill_blend_backup_version(info['folderpath'], recursive = info['recursive'], test = info['test'])
|
|
|
@ -1,71 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'LIBRARY_DATA_BROKEN',
|
|
||||||
'description' : 'Correct path (print in console, apply as option) when weirdly auto added unwanted parent directory (still break rotate order for armatures...)',
|
|
||||||
'apply' : False
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext, abspath
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
""" rel = D.libraries[0].filepath.replace('//','')
|
|
||||||
parent = rel.count('..')
|
|
||||||
print('parent: ', parent)
|
|
||||||
abspath(join(dirname(D.filepath), rel)) """
|
|
||||||
|
|
||||||
|
|
||||||
## relpath
|
|
||||||
|
|
||||||
def to_abs(rfp):
|
|
||||||
return abspath(bpy.path.abspath(rfp))
|
|
||||||
|
|
||||||
print('\n--- Cheking libraries filepath ---')
|
|
||||||
apply = False
|
|
||||||
apply = info['apply']#get it from info dic
|
|
||||||
|
|
||||||
folder = dirname(D.filepath)
|
|
||||||
for lib in D.libraries:
|
|
||||||
libfp = lib.filepath
|
|
||||||
if exists(to_abs(libfp)):
|
|
||||||
print('clean :', libfp)
|
|
||||||
else:
|
|
||||||
print('broken:', libfp)
|
|
||||||
pct = libfp.count('..')
|
|
||||||
for i in range(1, pct+1):
|
|
||||||
newrel = ('').join(libfp.split('../',i))
|
|
||||||
if exists(to_abs(newrel)):
|
|
||||||
print(f'found at -{i} parent folder')
|
|
||||||
print(f'-> {newrel}')
|
|
||||||
if apply:
|
|
||||||
lib.filepath = newrel
|
|
||||||
print()
|
|
||||||
break
|
|
||||||
if i == pct:
|
|
||||||
print(f'tested with {pct} folder up and nothing found')
|
|
||||||
print('Done.')
|
|
||||||
|
|
||||||
'''
|
|
||||||
## abspath technique
|
|
||||||
folder = dirname(D.filepath)
|
|
||||||
for lib in D.libraries:
|
|
||||||
curfp = abspath(bpy.path.abspath(lib.filepath))
|
|
||||||
if exists(curfp):
|
|
||||||
print('clean :', lib.filepath)
|
|
||||||
else:
|
|
||||||
print('broken:', lib.filepath)
|
|
||||||
pct = lib.filepath.count('..')
|
|
||||||
print('up folder: ', pct)
|
|
||||||
endlib = lib.filepath.lstrip(os.sep+'.')
|
|
||||||
for i in range(1, pct+1):
|
|
||||||
start = '/'.join(folder.split(os.sep)[:-i])
|
|
||||||
nfp = join(start, endlib)
|
|
||||||
if exists(nfp):
|
|
||||||
print(f'{i} parent folder VS {pct} in current')
|
|
||||||
'''
|
|
|
@ -1,60 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'ARMATURE_DATA',
|
|
||||||
'description' : 'run some check on proxys and armautre and print in console',
|
|
||||||
}
|
|
||||||
|
|
||||||
# coding: utf-8
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = bpy.context.scene
|
|
||||||
|
|
||||||
print('\nCollection instance check -- ')
|
|
||||||
problems = []
|
|
||||||
for o in bpy.context.scene.objects:
|
|
||||||
if o.instance_collection:
|
|
||||||
for instob in o.instance_collection.objects:
|
|
||||||
badname = withproxy = withcolproxy = alert = ''
|
|
||||||
|
|
||||||
if instob.type == 'ARMATURE':
|
|
||||||
mess = f'{o.name} -> rig: {instob.name}'
|
|
||||||
arm = instob.data
|
|
||||||
# print("arm", arm.name)#Dbg
|
|
||||||
if instob.name != arm.name:
|
|
||||||
badname = 1
|
|
||||||
mess += f' != arm data: {arm.name}'
|
|
||||||
rigname = arm.name.replace('_rig','_proxy') if 'rig' in arm.name else arm.name + '_proxy'
|
|
||||||
|
|
||||||
proxy = bpy.context.scene.objects.get(rigname)
|
|
||||||
|
|
||||||
if proxy:
|
|
||||||
withproxy = 1
|
|
||||||
mess += ' ->> Proxy in scene'
|
|
||||||
if not proxy:
|
|
||||||
collec_proxy = instob.name.replace('_rig','_proxy') if 'rig' in instob.name else instob.name + '_proxy'
|
|
||||||
proxy = bpy.context.scene.objects.get(collec_proxy)
|
|
||||||
if proxy :
|
|
||||||
withcolproxy = 1
|
|
||||||
mess += ' ->> Proxy from colname in scene'
|
|
||||||
|
|
||||||
if proxy and proxy.animation_data and proxy.animation_data.action and len(proxy.animation_data.action.fcurves) > 0:
|
|
||||||
mess += ' (animated)'
|
|
||||||
|
|
||||||
if badname and withcolproxy:
|
|
||||||
alert = '!!!'
|
|
||||||
elif badname and withproxy:
|
|
||||||
alert = '!!'
|
|
||||||
elif badname:
|
|
||||||
alert = '!'
|
|
||||||
mess = f'{alert} {mess}'
|
|
||||||
if badname or withproxy or withcolproxy:
|
|
||||||
problems.append(mess)
|
|
||||||
print(mess)
|
|
||||||
|
|
||||||
print('Done')
|
|
|
@ -1,140 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'DRIVER',
|
|
||||||
'description' : 'create visibility on driver objects or armature selection from a bone of a rig',
|
|
||||||
'prop_rig' : 'name_of_the_rig'
|
|
||||||
'prop_name' : 'hide_something'
|
|
||||||
'prop_bone' : 'root'
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
|
|
||||||
def add_driver(source, target, prop, dataPath, index = -1, negative = False, func = ''):
|
|
||||||
''' Add driver to source prop (at index), driven by target dataPath '''
|
|
||||||
|
|
||||||
source.driver_remove(prop, index)
|
|
||||||
if index != -1:
|
|
||||||
d = source.driver_add( prop, index ).driver
|
|
||||||
else:
|
|
||||||
d = source.driver_add( prop ).driver
|
|
||||||
|
|
||||||
v = d.variables.new()
|
|
||||||
v.targets[0].id = target
|
|
||||||
v.targets[0].data_path = dataPath
|
|
||||||
|
|
||||||
d.expression = func + "(" + v.name + ")" if func else v.name
|
|
||||||
d.expression = d.expression if not negative else "-1 * " + d.expression
|
|
||||||
|
|
||||||
def create_hide_custom_prop(src_object, prop_name, prop_bone = ''):
|
|
||||||
'''
|
|
||||||
add source propertie with boolean option
|
|
||||||
place the hide prop on src_object with name prop_name
|
|
||||||
'''
|
|
||||||
|
|
||||||
rig = bpy.data.objects.get(src_object)
|
|
||||||
if not rig:
|
|
||||||
print(f"No objects named {src_object}")
|
|
||||||
return 1
|
|
||||||
if rig.type != 'ARMATURE':
|
|
||||||
print(f"Not an armature : {src_object}")
|
|
||||||
return 1
|
|
||||||
|
|
||||||
#add target bone
|
|
||||||
if prop_bone:
|
|
||||||
holder = rig.pose.bones.get(prop_bone)
|
|
||||||
else:
|
|
||||||
holder = rig.pose.bones.get('root')
|
|
||||||
|
|
||||||
if not holder:
|
|
||||||
print(f'problem finding bone {prop_bone} (or root)')
|
|
||||||
return 1
|
|
||||||
|
|
||||||
# create
|
|
||||||
if not holder.get('_RNA_UI'):
|
|
||||||
holder['_RNA_UI'] = {}
|
|
||||||
|
|
||||||
if not prop_name in holder.keys() :
|
|
||||||
holder[prop_name] = 0
|
|
||||||
holder['_RNA_UI'][prop_name] = {"default": 0,"min":0,"max":1,"soft_min":0,"soft_max":1}
|
|
||||||
else:
|
|
||||||
print(f'{prop_name} : already exists on root key')
|
|
||||||
return
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def drive_selection_visibility(rig, prop_name, prop_bone = ''):
|
|
||||||
# add driver on selection
|
|
||||||
prefixs = ('MCH','DEF','ORG', 'WGT')
|
|
||||||
|
|
||||||
rig = bpy.data.objects.get(src_object)
|
|
||||||
if not rig:
|
|
||||||
print(f"No objects named {src_object}")
|
|
||||||
return 1
|
|
||||||
if rig.type != 'ARMATURE':
|
|
||||||
print(f"Not an armature : {src_object}")
|
|
||||||
return 1
|
|
||||||
|
|
||||||
#add target bone
|
|
||||||
|
|
||||||
if not prop_bone:
|
|
||||||
prop_bone = 'root'
|
|
||||||
if not rig.pose.bones.get(prop_bone):
|
|
||||||
print(f'no bones {prop_bone} on rig {rig.name}')
|
|
||||||
return 1
|
|
||||||
|
|
||||||
meshes = [i for i in bpy.context.selected_objects if i.type in ('MESH','CURVE','TEXT') and not i.name.startswith(('WGT', 'WDGT'))]
|
|
||||||
armatures = [i for i in bpy.context.selected_objects if i.type == 'ARMATURE']
|
|
||||||
|
|
||||||
if bpy.context.mode == 'POSE':
|
|
||||||
obarm = bpy.context.active_object
|
|
||||||
for bone in bpy.context.selected_pose_bones_from_active_object:
|
|
||||||
prop = 'bones["%s"].hide'%bone.name
|
|
||||||
index = -1
|
|
||||||
layer = bone.bone.layers
|
|
||||||
protect_layer = rig.data.layers_protected
|
|
||||||
### dont check for protected, strictly use selection.
|
|
||||||
# if bone.name.startswith(prefixs) or any([i==j==1 for i,j in zip(layer,protect_layer)]) :
|
|
||||||
# print(f'Skipped : Prefixed or protected bone : {bone.name}')
|
|
||||||
# rig.data.driver_remove(prop, index)
|
|
||||||
# continue
|
|
||||||
print(f'New : Driver on bone {bone.name}')
|
|
||||||
add_driver(obarm.data, rig, prop, f'pose.bones["{prop_bone}"]["{prop_name}"]', index)
|
|
||||||
return
|
|
||||||
|
|
||||||
for ob in meshes :
|
|
||||||
print('Object : ', obarm.name)
|
|
||||||
|
|
||||||
add_driver(ob, rig, 'hide_viewport', f'pose.bones["{prop_bone}"]["{prop_name}"]', -1)
|
|
||||||
add_driver(ob, rig, 'hide_render', f'pose.bones["{prop_bone}"]["{prop_name}"]', -1)
|
|
||||||
|
|
||||||
for obarm in armatures:
|
|
||||||
print('Armature : ', obarm.name)
|
|
||||||
## mask armature object
|
|
||||||
## add_driver(obarm, rig, 'hide_viewport', f'pose.bones["{prop_bone}"]["{prop_name}"]', -1)
|
|
||||||
## bette mask pose bones since its a proxy...
|
|
||||||
for bone in obarm.pose.bones :
|
|
||||||
prop = 'bones["%s"].hide'%bone.name
|
|
||||||
index = -1
|
|
||||||
layer = bone.bone.layers
|
|
||||||
protect_layer = rig.data.layers_protected
|
|
||||||
if bone.name.startswith(prefixs) or any([i==j==1 for i,j in zip(layer,protect_layer)]) :
|
|
||||||
print(f'Skipped : Prefixed or protected bone : {bone.name}')
|
|
||||||
rig.data.driver_remove(prop, index)
|
|
||||||
else :
|
|
||||||
print(f'New : Driver on bone {bone.name}')
|
|
||||||
add_driver(obarm.data, rig, prop, f'pose.bones["{prop_bone}"]["{prop_name}"]', index)
|
|
||||||
|
|
||||||
### ----
|
|
||||||
|
|
||||||
## write the name of the rig source (will put the propertie on the root of this armature)
|
|
||||||
|
|
||||||
prop_rig = info['prop_rig']# name_of_the_rig
|
|
||||||
|
|
||||||
## write the name of the propertie to attach
|
|
||||||
prop_name = info["prop_name"]#'hide_headband'# hide_something
|
|
||||||
|
|
||||||
## prop_bone (bone holding the propertie), 'root' if left string empty.
|
|
||||||
prop_bone = info["prop_bone"]
|
|
||||||
|
|
||||||
|
|
||||||
create_hide_custom_prop(prop_rig, prop_name, prop_bone = prop_bone)
|
|
||||||
drive_selection_visibility(prop_rig, prop_name, prop_bone = prop_bone)
|
|
|
@ -1,27 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'ACTION_TWEAK',
|
|
||||||
'description' : 'Rename selected armature actions (with name of the rig, replacing "_rig" with "_act")',
|
|
||||||
}
|
|
||||||
|
|
||||||
# coding: utf-8
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
for o in C.selected_objects:
|
|
||||||
if o.type == 'ARMATURE':
|
|
||||||
print(o.animation_data.action.name)
|
|
||||||
if '_rig' in o.name:
|
|
||||||
action = o.animation_data.action
|
|
||||||
if action.name.replace('_act','') != o.name.replace('_rig', ''):
|
|
||||||
newname = o.name.replace('_rig', '_act')
|
|
||||||
print(f'action rename {action.name} > {newname}')
|
|
||||||
action.name = newname
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'HIDE_OFF',
|
|
||||||
'description' : 'Force viewport visibility ON for objects with hide_viewport prop animated',
|
|
||||||
}
|
|
||||||
|
|
||||||
# coding: utf-8
|
|
||||||
import bpy
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
|
||||||
import re, fnmatch, glob
|
|
||||||
from mathutils import Vector, Matrix
|
|
||||||
from math import radians, degrees
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
for o in bpy.context.scene.objects:
|
|
||||||
if o.animation_data and o.animation_data.action and o.animation_data.action.fcurves.find('hide_viewport'):
|
|
||||||
o.hide_viewport = False
|
|
|
@ -1,22 +0,0 @@
|
||||||
info = {
|
|
||||||
'icon' : 'OUTLINER_OB_ARMATURE',
|
|
||||||
'description' : 'Hide/Unhide all rigs',
|
|
||||||
}
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
C = bpy.context
|
|
||||||
D = bpy.data
|
|
||||||
scene = C.scene
|
|
||||||
|
|
||||||
#hide armature
|
|
||||||
hide = True
|
|
||||||
|
|
||||||
arms = [o for o in C.scene.objects if o.type == 'ARMATURE']
|
|
||||||
if arms:
|
|
||||||
hide = not arms[0].hide_viewport
|
|
||||||
|
|
||||||
#invert of the state of the first armature found for all of them
|
|
||||||
for o in C.scene.objects:
|
|
||||||
if o.type == 'ARMATURE':
|
|
||||||
o.hide_viewport = hide
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
import bpy
|
|
||||||
from bpy import data as D
|
|
||||||
ob = D.objects['boom_hairs_group_ref']
|
|
||||||
|
|
||||||
ob.hide_viewport = not ob.hide_viewport
|
|
Loading…
Reference in New Issue