WIP: Rigify - modifier keys on Rig Layers buttons #104998
@ -6,7 +6,8 @@ import bpy
|
|||||||
|
|
||||||
from typing import Tuple, Optional, Sequence, Any
|
from typing import Tuple, Optional, Sequence, Any
|
||||||
|
|
||||||
from bpy.types import PropertyGroup, Action, UIList, UILayout, Context, Panel, Operator, Armature, PoseBone
|
from bpy.types import (PropertyGroup, Action, UIList, UILayout, Context, Panel, Operator, Armature,
|
||||||
|
PoseBone, Bone, BoneCollection)
|
||||||
from bpy.props import (EnumProperty, IntProperty, BoolProperty, StringProperty, FloatProperty,
|
from bpy.props import (EnumProperty, IntProperty, BoolProperty, StringProperty, FloatProperty,
|
||||||
PointerProperty, CollectionProperty)
|
PointerProperty, CollectionProperty)
|
||||||
|
|
||||||
@ -190,15 +191,13 @@ def is_pose_bone_all_locked(pose_bone: PoseBone) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def should_skip_bone(bone, pose_bones):
|
def should_skip_bone(bone: Bone):
|
||||||
"""Return True if the bone should not be used (hidden, locked, etc..)"""
|
"""Return True if the bone should not be displayed (hidden, VIS_*)"""
|
||||||
if bone.hide:
|
if bone.hide:
|
||||||
return True
|
return True
|
||||||
if bone.name.startswith('VIS_'):
|
if bone.name.startswith('VIS_'):
|
||||||
# "VIS_*" bones are used for drawing lines, e.g. line connecting knee to IK pole
|
# "VIS_*" bones are used for drawing lines, e.g. line connecting knee to IK pole
|
||||||
return True
|
return True
|
||||||
if is_pose_bone_all_locked(pose_bones[bone.name]):
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -249,7 +248,7 @@ class RIGIFY_OT_jump_to_action_slot(Operator):
|
|||||||
# noinspection PyPep8Naming
|
# noinspection PyPep8Naming
|
||||||
class RIGIFY_OT_display_select_group(bpy.types.Operator):
|
class RIGIFY_OT_display_select_group(bpy.types.Operator):
|
||||||
"""Toggle bone layer visibility. Shift + click to toggle selection, Ctrl + click to remove from selection.
|
"""Toggle bone layer visibility. Shift + click to toggle selection, Ctrl + click to remove from selection.
|
||||||
Alt + click displays a menu"""
|
Alt + click displays a panel"""
|
||||||
bl_idname = "object.rigify_display_select_bone_group"
|
bl_idname = "object.rigify_display_select_bone_group"
|
||||||
bl_label = "Display or Select the bones that belong to a selection"
|
bl_label = "Display or Select the bones that belong to a selection"
|
||||||
|
|
||||||
@ -285,7 +284,9 @@ class RIGIFY_OT_display_select_group(bpy.types.Operator):
|
|||||||
if self.action == 'TOGGLE_SELECT':
|
if self.action == 'TOGGLE_SELECT':
|
||||||
pose_bones = context.object.pose.bones
|
pose_bones = context.object.pose.bones
|
||||||
for bone in coll.bones:
|
for bone in coll.bones:
|
||||||
if should_skip_bone(bone, pose_bones):
|
if should_skip_bone(bone):
|
||||||
|
continue
|
||||||
|
if is_pose_bone_all_locked(pose_bones[bone.name]):
|
||||||
continue
|
continue
|
||||||
bone.select = not bone.select
|
bone.select = not bone.select
|
||||||
elif self.action == 'UNSELECT':
|
elif self.action == 'UNSELECT':
|
||||||
@ -341,6 +342,7 @@ class RIGIFY_OT_select_prefix_bones(bpy.types.Operator):
|
|||||||
# =============================================
|
# =============================================
|
||||||
# UI Panel
|
# UI Panel
|
||||||
|
|
||||||
|
# noinspection PyPep8Naming
|
||||||
class RIGIFY_PT_select_active_group_bones(bpy.types.Panel):
|
class RIGIFY_PT_select_active_group_bones(bpy.types.Panel):
|
||||||
"""Display Panel"""
|
"""Display Panel"""
|
||||||
bl_idname = "object.rigify_active_group_select_bones"
|
bl_idname = "object.rigify_active_group_select_bones"
|
||||||
@ -355,20 +357,22 @@ class RIGIFY_PT_select_active_group_bones(bpy.types.Panel):
|
|||||||
return context.mode == 'POSE'
|
return context.mode == 'POSE'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def collect_bone_sides(collection, pose_bones):
|
def collect_bone_sides(collection: BoneCollection):
|
||||||
left_bones = []
|
left_bones = []
|
||||||
mid_bones = []
|
mid_bones = []
|
||||||
right_bones = []
|
right_bones = []
|
||||||
prefix_bones = set()
|
prefix_bones = set()
|
||||||
|
|
||||||
digits = ".0123456789" # used for stripping dot and number from bone names
|
digits = ".0123456789" # used for stripping dot and number from bone names
|
||||||
|
armature = collection.id_data
|
||||||
for bone in collection.bones:
|
for bone in collection.bones:
|
||||||
if should_skip_bone(bone, pose_bones):
|
if should_skip_bone(bone):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if bone.name[-1].isdigit():
|
if bone.name[-1].isdigit():
|
||||||
|
# Looking for bones like "*.L.015", "*.R.023", "*.001"
|
||||||
base_name = bone.name.rstrip(digits)
|
base_name = bone.name.rstrip(digits)
|
||||||
if base_name in pose_bones: # e.g. "*.L", "*.L.015", "*.R.023"
|
if base_name in armature.bones:
|
||||||
prefix_bones.add(base_name)
|
prefix_bones.add(base_name)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -385,13 +389,17 @@ class RIGIFY_PT_select_active_group_bones(bpy.types.Panel):
|
|||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
collection = context.object.data.collections.active
|
collection = context.object.data.collections.active
|
||||||
bone_lists, prefix_bones = self.collect_bone_sides(collection, context.object.pose.bones)
|
bone_lists, prefix_bones = self.collect_bone_sides(collection)
|
||||||
|
|
||||||
# display Left and Right bones
|
# display Left and Right bones
|
||||||
row = self.layout.row()
|
row = self.layout.row()
|
||||||
columns = row.column(), row.column()
|
columns = row.column(), row.column()
|
||||||
|
pose_bones = context.object.pose.bones
|
||||||
for col, bone_list in zip(columns, bone_lists[:2]):
|
for col, bone_list in zip(columns, bone_lists[:2]):
|
||||||
for bone in bone_list:
|
for bone in bone_list:
|
||||||
|
if is_pose_bone_all_locked(pose_bones[bone.name]):
|
||||||
|
continue
|
||||||
|
|
||||||
if bone.name in prefix_bones:
|
if bone.name in prefix_bones:
|
||||||
col.operator(RIGIFY_OT_select_prefix_bones.bl_idname, text=bone.name, icon='TRIA_RIGHT').prefix = bone.name
|
col.operator(RIGIFY_OT_select_prefix_bones.bl_idname, text=bone.name, icon='TRIA_RIGHT').prefix = bone.name
|
||||||
else:
|
else:
|
||||||
@ -401,6 +409,8 @@ class RIGIFY_PT_select_active_group_bones(bpy.types.Panel):
|
|||||||
|
|
||||||
# display Mid bones
|
# display Mid bones
|
||||||
for bone in bone_lists[2]:
|
for bone in bone_lists[2]:
|
||||||
|
if is_pose_bone_all_locked(pose_bones[bone.name]):
|
||||||
|
continue
|
||||||
if bone.name in prefix_bones:
|
if bone.name in prefix_bones:
|
||||||
col.operator(RIGIFY_OT_select_prefix_bones.bl_idname, text=bone.name, icon='TRIA_RIGHT').prefix = bone.name
|
col.operator(RIGIFY_OT_select_prefix_bones.bl_idname, text=bone.name, icon='TRIA_RIGHT').prefix = bone.name
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user