rig_picker/core/bl_utils.py

142 lines
3.6 KiB
Python

import bpy
def get_collection_parents(col, root=None, cols=None):
"""Return all direct collection parents
Args:
col (bpy.types.Collection): collection to get parents from
root (bpy.types.Collection, optional): collection to search in (recursive) instead of the scene collection.
Defaults to None.
cols (_type_, optional): for recursivity, store the parent collections.
Defaults to None.
Returns:
list[bpy.types.Collection]: a list of direct parents
"""
if cols is None:
cols = []
if root is None:
root = bpy.context.scene.collection
for sub in root.children:
if sub == col:
cols.append(root)
if len(sub.children):
cols = get_collection_parents(col, root=sub, cols=cols)
return cols
def get_view_3d_override():
windows = bpy.context.window_manager.windows
areas = [a for w in windows for a in w.screen.areas if a.type == 'VIEW_3D']
if not areas:
print('No view 3d found')
return
view_3d = None
for area in areas:
if area.spaces.active.camera:
view_3d = area
if not view_3d:
view_3d = max(areas, key=lambda x :x.width)
return {'area': view_3d, 'region': view_3d.regions[-1]}
def get_mat(ob):
for sl in ob.material_slots:
if sl.material:
return sl.material
def link_mat_to_object(ob):
for sl in ob.material_slots:
m = sl.material
sl.link = 'OBJECT'
sl.material = m
def eval_attr(ob, name):
resolved = ob
for o in name.split("."):
resolved = getattr(resolved, o)
return resolved
def flip_name(name):
if not name:
return
if name.startswith('[') and name.endswith(']'): #It's a custom property
flipped_name = bpy.utils.flip_name(name[:-2][2:])
return f'["{flipped_name}"]'
else:
return bpy.utils.flip_name(name)
def split_path(path) :
try :
bone_name = path.split('["')[1].split('"]')[0]
except Exception:
bone_name = None
try :
prop_name = path.split('["')[2].split('"]')[0]
except Exception:
prop_name = None
return bone_name, prop_name
def hide_layers(args):
""" """
ob = bpy.context.object
layers = []
for bone in [b for b in ob.pose.bones if b.bone.select]:
for i,l in enumerate(bone.bone.layers):
if l and i not in layers:
layers.append(i)
for i in layers:
ob.data.layers[i] = not ob.data.layers[i]
def select_layer(args):
ob = bpy.context.object
layers =[]
for bone in [b for b in ob.pose.bones if b.bone.select]:
bone_layers = [i for i,l in enumerate(bone.bone.layers) if l]
for l in bone_layers:
if l not in layers:
layers.append(l)
for bone in ob.pose.bones:
bone_layers = [i for i,l in enumerate(bone.bone.layers) if l]
if len(set(bone_layers).intersection(layers)):
bone.bone.select = True
def hide_bones(args):
ob = bpy.context.object
selected_bone = [b for b in ob.pose.bones if b.bone.select]
hide = [b.bone.hide for b in selected_bone if not b.bone.hide]
visibility = True if len(hide) else False
for bone in selected_bone:
bone.bone.hide = visibility
def select_all(args):
ob = bpy.context.object
shapes = ob.data.rig_picker['shapes']
bones = [s['bone'] for s in shapes if s['shape_type']=='BONE']
for bone_name in bones:
bone = ob.pose.bones.get(bone_name)
if bone:
bone.bone.select = True