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
@@ -0,0 +1,275 @@
info = {
'icon' : 'PHYSICS',
'description' : 'Copy dynamic physics object from selected instance_collection',
}
import bpy
from os.path import abspath, relpath, dirname, basename, join
from time import time
C = bpy.context
D = bpy.data
scene = C.scene
def set_collection(ob, collection, unlink=True) :
''' link an object in a collection and create it if necessary, if unlink object is removed from other collections'''
scn = bpy.context.scene
col = None
visible = False
linked = False
# check if collection exist or create it
for c in bpy.data.collections :
if c.name == collection : col = c
if not col : col = bpy.data.collections.new(name=collection)
# link the collection to the scene's collection if necessary
for c in scn.collection.children :
if c.name == col.name : visible = True
if not visible : scn.collection.children.link(col)
# check if the object is already in the collection and link it if necessary
for o in col.objects :
if o == ob : linked = True
if not linked : col.objects.link(ob)
# remove object from scene's collection
for o in scn.collection.objects :
if o == ob : scn.collection.objects.unlink(ob)
# if unlink flag we remove the object from other collections
if unlink :
for c in ob.users_collection :
if c.name != collection : c.objects.unlink(ob)
def append_stuff(blendfile, section, obj):
filepath = blendfile
directory = join(blendfile, section)#join(blendfile, section)
filename = obj
print('Append')
print('filepath: ', filepath)
print('directory: ', directory)
print('filename: ', filename)
print(f'''using:
bpy.ops.wm.append(
filepath='{filepath}',
filename='{filename}',
directory='{directory}',
active_collection=True,
)
''')
bpy.ops.wm.append(
filepath=filepath,
filename=filename,
directory=directory,
filter_blender=True, filter_backup=False, filter_image=False, filter_movie=False,
filter_python=False, filter_font=False, filter_sound=False, filter_text=False,
filter_archive=False, filter_btx=False, filter_collada=False, filter_alembic=False,
filter_folder=True, filter_blenlib=True, filemode=1, display_type='DEFAULT', sort_method='FILE_SORT_ALPHA',
link=False, autoselect=True, active_collection=True,#default -> active_collection=True
instance_collections=False, set_fake=False,
use_recursive=True
)
#return {'finished'}
## data way (not working as is...)
'''
with bpy.data.libraries.load(filepath, link=False) as (data_from, data_to):
data_to.objects = [o for o in data_from.objects if o == obj]
#link object to current scene
for obj in data_to.objects:
if obj is not None:
C.scene.collection.objects.link(obj)
'''
def set_soft_body(ob, mod, bake=False):
if bake:
print(f'baking {ob.name} > {mod.name}')
ptc = mod.point_cache
name = ptc.name
override = {'scene': bpy.context.scene,
'active_object': ob,#no sure of this line.. .
'point_cache': ptc}
if bake:
if name:#kill point cache related to point cache name
# delete_point_cache(name)
bpy.ops.ptcache.free_bake(override)
## bpy.ops.ptcache.free_bake_all(override)
#ptc.is_outdated = True # read-only
ptc.frame_start = scene.frame_start
ptc.frame_end = scene.frame_end
# ptc.filepath = join(dirname(D.filepath), splitext(basename)[0]+'_cache')
if not ptc.use_disk_cache:
ptc.use_disk_cache = True
print('enabling use disk cache')
if bake:
print('>>> baking')
start = time()
#bpy.ops.ptcache.bake(override, bake=False)# bake to current frame
bpy.ops.ptcache.bake(override, bake=True)
print(f'Done {time()-start:.3f}')
def set_particle_system(ob, mod, bake=False):
if bake:
print(f'baking {ob.name} > {mod.name}')
ptc = mod.particle_system.point_cache
ptc.frame_start = scene.frame_start
ptc.frame_end = scene.frame_end
# ptc.filepath = join(dirname(D.filepath), splitext(basename)[0]+'_cache')
if not ptc.use_disk_cache:
ptc.use_disk_cache = True
print('enabling use disk cache')
if bake:
override = {'scene': bpy.context.scene,
'active_object': ob,#no sure of this line.. .
'point_cache': ptc}
print('>>> baking')
start = time()
#bpy.ops.ptcache.bake(override, bake=False)# bake to current frame
bpy.ops.ptcache.bake(override, bake=True)
print(f'Done {time()-start:.3f}')
def bake_mods(ob, bake=False):
for mod in ob.modifiers:
if mod.type == 'SOFT_BODY':
set_soft_body(ob, mod, bake)
if mod.type == 'PARTICLE_SYSTEM':
set_particle_system(ob, mod, bake)
def clear_obj_driver(ob):
'''delete visibility driver if any'''
print('clearing driver', ob.name)
ob.driver_remove('hide_viewport')
ob.driver_remove('hide_render')
ob.hide_viewport = False
ob.hide_render = False
def append_physics_obj(selected=True, purge=False, bake=False):
'''On selection or all scene'''
current_active_col = C.view_layer.active_layer_collection
if selected:
obpool = C.selected_objects
else:
obpool = bpy.context.scene.objects
pool = [o for o in obpool if o.type == 'EMPTY' and o.instance_collection]#PARTICLE_SYSTEM
if selected:
for proxyarm in [o for o in obpool if o.type == 'ARMATURE' and o.name.endswith('_proxy')]:
inst = proxyarm.proxy_collection
if inst not in pool: pool.append(inst)
linked = []
#[m for m in o.modifiers if m.type == 'SOFT_BODY']
for instance in pool:
print("instance", instance.name)#Dbg
for ob in instance.instance_collection.all_objects:
# print("ob", ob.name)#Dbg
if ob.type in ('MESH', 'CURVE'):
for mod in ob.modifiers:
if mod.type in ('SOFT_BODY', 'PARTICLE_SYSTEM'):
print(f'{ob.name} > {mod.name} ({mod.type})')
## check if object already exists in object base.
dynob_name = ob.name + '_DYN'
phycol = D.collections.get('Physics_sim')#Dynamic_physics
theob = None
if phycol: theob = phycol.objects.get(dynob_name)
if theob:
print(f'{dynob_name} already as object in scene')
continue
'''
if purge:#delete whats in physics collection, crashy as hell..
print(f'--> purge: deleting {dynob_name}')
D.objects.remove(theob)
else:
continue
'''
## get library path
libpath = abspath(bpy.path.abspath(instance.instance_collection.library.filepath))
print('libpath: ', libpath)
#libpath = instance.instance_collection.library.filepath
#objpath = join(libpath, 'Object', ob.name)
if not phycol:
phycol = D.collections.new('Physics_sim')
C.scene.collection.children.link(phycol)
## make it active
C.view_layer.active_layer_collection = C.view_layer.layer_collection.children['Physics_sim']
## Append individual object, (physics object with a different name from the blend file, else it 'links' to the one withi instance_collection)
#append_stuff(libpath, 'Object', ob.name)
## test copy from existing object
newob = ob.copy()
#newob.make_local()
#newob.data.make_local()
set_collection(newob, 'Physics_sim')
linked.append(newob)
# newob.name = newob.name + '_DYN'
#clear_obj_driver(newob)##crash when clearing driver of the copied object immediately. Do it later
'''
## get the newly appended object
newob = phycol.objects.get(ob.name)#not rename currently
if not newob:
print(f'problem, did not found "{dynob_name}" in physics collection')
continue
linked.append(newob)
'''
# setup proxy visibility...
if instance.name == 'jenny':
proxy = C.scene.objects.get('jenny_proxy')
hairdyn = proxy.pose.bones['root']['_RNA_UI'].get('hair_dynamic')
if hairdyn:
if hairdyn['max'] < 2:
#setmax
proxy.pose.bones['root']['_RNA_UI']['hair_dynamic']['max'] = 2
proxy.pose.bones['root']['_RNA_UI']['hair_dynamic']['soft_max'] = 2
#set val
proxy.pose.bones['root']['hair_dynamic'] = 2
if instance.name == 'boom':
proxy = C.scene.objects.get('boom_proxy')
hairdyn = proxy.pose.bones['root']['_RNA_UI'].get('hair_placeholder')
if hairdyn:
if hairdyn['max'] < 3:
#setmax
proxy.pose.bones['root']['_RNA_UI']['hair_placeholder']['max'] = 3
proxy.pose.bones['root']['_RNA_UI']['hair_placeholder']['soft_max'] = 3
#set val
proxy.pose.bones['root']['hair_placeholder'] = 3
for o in linked:#linked
print(f'-- linked: {o.name}')
# o.make_local()#localize then modify, usually no need to make local if appended
o.name = o.name + '_DYN'
clear_obj_driver(o)
print(o.name)
#set_collection(o, 'Physics_sim')
bake_mods(o, bake=False)
#reset active collection
C.view_layer.active_layer_collection = current_active_col
print()
append_physics_obj(selected=True, purge=False, bake=False)#purge bugged
@@ -0,0 +1,143 @@
info = {
'icon' : 'ACTION_TWEAK',
'description' : 'Bake action of selected objects',
'selection' : True
}
import bpy
from os.path import abspath, relpath, dirname, basename, join
from time import time
C = bpy.context
D = bpy.data
scene = C.scene
def set_collection(ob, collection, unlink=True) :
''' link an object in a collection and create it if necessary, if unlink object is removed from other collections'''
scn = bpy.context.scene
col = None
visible = False
linked = False
# check if collection exist or create it
for c in bpy.data.collections :
if c.name == collection : col = c
if not col : col = bpy.data.collections.new(name=collection)
# link the collection to the scene's collection if necessary
for c in scn.collection.children :
if c.name == col.name : visible = True
if not visible : scn.collection.children.link(col)
# check if the object is already in the collection and link it if necessary
for o in col.objects :
if o == ob : linked = True
if not linked : col.objects.link(ob)
# remove object from scene's collection
for o in scn.collection.objects :
if o == ob : scn.collection.objects.unlink(ob)
# if unlink flag we remove the object from other collections
if unlink :
for c in ob.users_collection :
if c.name != collection : c.objects.unlink(ob)
def set_soft_body(ob, mod, bake=False):
if bake:
print(f'baking {ob.name} > {mod.name}')
ptc = mod.point_cache
name = ptc.name
override = {'scene': bpy.context.scene,
'active_object': ob,#no sure of this line.. .
'point_cache': ptc}
if bake:
if name:#kill point cache related to point cache name
bpy.ops.ptcache.free_bake(override)
## bpy.ops.ptcache.free_bake_all(override)
#ptc.is_outdated = True # read-only
ptc.frame_start = scene.frame_start
ptc.frame_end = scene.frame_end
if not ptc.use_disk_cache:
ptc.use_disk_cache = True
print('enabling use disk cache')
if bake:
print('>>> baking')
start = time()
#bpy.ops.ptcache.bake(override, bake=False)# bake to current frame
bpy.ops.ptcache.bake(override, bake=True)
print(f'Done {time()-start:.3f}')
def set_particle_system(ob, mod, bake=False):
if bake:
print(f'baking {ob.name} > {mod.name}')
ptc = mod.particle_system.point_cache
ptc.frame_start = scene.frame_start
ptc.frame_end = scene.frame_end
# ptc.filepath = join(dirname(D.filepath), splitext(basename)[0]+'_cache')
if not ptc.use_disk_cache:
ptc.use_disk_cache = True
print('enabling use disk cache')
if bake:
override = {'scene': bpy.context.scene,
'active_object': ob,#no sure of this line.. .
'point_cache': ptc}
print('>>> baking')
start = time()
#bpy.ops.ptcache.bake(override, bake=False)# bake to current frame
bpy.ops.ptcache.bake(override, bake=True)
print(f'Done {time()-start:.3f}')
def bake_mods(ob, bake=False):
for mod in ob.modifiers:
if mod.type == 'SOFT_BODY':
set_soft_body(ob, mod, bake)
if mod.type == 'PARTICLE_SYSTEM':
set_particle_system(ob, mod, bake)
def bake_action(selected=True):
if selected:
pool = []
for o in C.selected_objects:
if o.animation_data.action:
print(f'{o.name} already has an action')
o.select_set(False)
continue
else:
pool.append(o)
if not pool:
print('no object ready for action bake')
return
else:#go in physics ob collection
phycol = D.collections.get('Physics_sim')
if not phycol:
print('No physics collection')
return
pool = [o for o in phycol.all_objects if not o.hide_viewport and not o.animation_data.action]
#redefine selection
bpy.ops.object.select_all(action='DESELECT')
for o in pool:
o.select_set(True)
C.view_layer.objects.active = o
# get viewport override ? (no need if launched from custom shelf)
print('Baking action...')
# launch action baking
bpy.ops.nla.bake(frame_start=scene.frame_start, frame_end=scene.frame_end, only_selected=False, visual_keying=True, clear_constraints=True, clear_parents=True, bake_types={'OBJECT'})
bake_action(selected=info['selection'])
print('EOF')
@@ -0,0 +1,100 @@
info = {
'icon' : 'PHYSICS',
'description' : 'Bake modifier cache of selected objects',
'selection' : True
}
import bpy
from os.path import abspath, relpath, dirname, basename, join
from time import time
C = bpy.context
D = bpy.data
scene = C.scene
def set_soft_body(ob, mod, bake=False):
if bake:
print(f'baking {ob.name} > {mod.name}')
ptc = mod.point_cache
name = ptc.name
override = {'scene': bpy.context.scene,
'active_object': ob,#no sure of this line.. .
'point_cache': ptc}
if bake:
if name:#kill point cache related to point cache name
bpy.ops.ptcache.free_bake(override)
## bpy.ops.ptcache.free_bake_all(override)
#ptc.is_outdated = True # read-only
ptc.frame_start = scene.frame_start
ptc.frame_end = scene.frame_end
if not ptc.use_disk_cache:
ptc.use_disk_cache = True
print('enabling use disk cache')
if bake:
print('>>> baking')
start = time()
#bpy.ops.ptcache.bake(override, bake=False)# bake to current frame
bpy.ops.ptcache.bake(override, bake=True)
print(f'Done {time()-start:.3f}')
def set_particle_system(ob, mod, bake=False):
if bake:
print(f'baking {ob.name} > {mod.name}')
ptc = mod.particle_system.point_cache
ptc.frame_start = scene.frame_start
ptc.frame_end = scene.frame_end
# ptc.filepath = join(dirname(D.filepath), splitext(basename)[0]+'_cache')
if not ptc.use_disk_cache:
ptc.use_disk_cache = True
print('enabling use disk cache')
if bake:
override = {'scene': bpy.context.scene,
'active_object': ob,#no sure of this line.. .
'point_cache': ptc}
print('>>> baking')
start = time()
#bpy.ops.ptcache.bake(override, bake=False)# bake to current frame
bpy.ops.ptcache.bake(override, bake=True)
print(f'Done {time()-start:.3f}')
def bake_mods(ob, bake=False):
for mod in ob.modifiers:
if mod.type == 'SOFT_BODY':
set_soft_body(ob, mod, bake)
if mod.type == 'PARTICLE_SYSTEM':
set_particle_system(ob, mod, bake)
def bake_mod_cache(selected=True):
phycol = D.collections.get('Physics_sim')
if not phycol:
print('No physics collection')
return
if selected:
pool = []
for o in C.selected_objects:
if not phycol in o.users_collection:
print(f'{o.name} is not in Physics_sim collection' )
continue
pool.append(o)
if not pool:
print('no object ready for cache baking')
return
else:#go in physics ob collection
pool = [o for o in phycol.all_objects if not o.hide_viewport and not o.animation_data.action]
#automate preroll ?
for o in pool:
bake_mods(o, bake=True)
bake_mod_cache(selected=info['selection'])
print('EOF')
@@ -0,0 +1,19 @@
info = {
'icon' : 'X',
'description' : 'Delete everything in collection Physics_sim',
}
import bpy
from os.path import abspath, relpath, dirname, basename, join
from time import time
C = bpy.context
D = bpy.data
scene = C.scene
phycol = D.collections.get('Physics_sim')#Dynamic_physics
if phycol:
for ob in phycol.all_objects:
D.objects.remove(ob)
D.collections.remove(phycol)