Rigify: add option to parent all deform bones according to metarig #104644

Open
Leslie-Leigh wants to merge 1 commits from Leslie-Leigh/blender-addons:rigify_parent into blender-v3.4-release

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
7 changed files with 64 additions and 2 deletions

View File

@ -567,6 +567,11 @@ def register():
bpy.types.Armature.rigify_finalize_script = PointerProperty(type=bpy.types.Text,
name="Finalize Script",
description="Run this script after generation to apply user-specific changes")
bpy.types.Armature.rigify_parent_all_deform_bones = BoolProperty(name="(EXPERIMENTAL)Force Parent All Deform Bones",
description="Force parent all deform bones according to metarig\'s bone hierarchy.",
default=False)
IDStore.rigify_transfer_only_selected = BoolProperty(
name="Transfer Only Selected",
description="Transfer selected bones only", default=True)
@ -611,6 +616,7 @@ def unregister():
del ArmStore.rigify_force_widget_update
del ArmStore.rigify_target_rig
del ArmStore.rigify_rig_ui
del ArmStore.rigify_parent_all_deform_bones
IDStore = bpy.types.WindowManager
del IDStore.rigify_collection

View File

@ -205,6 +205,38 @@ class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, Mechanism
"""
return [pose_bone.name]
def filter_derived_deform_bones(self, org_bone):
"""
Returns a filter containing all deforming bones derived from specified org bone.
"""
if not org_bone in self.rigify_derived_bones:
return None
derived_bones = self.rigify_derived_bones[org_bone]
pred = (lambda b: b == self.bones.deform) if type(self.bones.deform) == str else (lambda b: b in self.bones.deform)
return filter(pred, derived_bones)
def find_most_relevant_parent_deform_bone(self, rig_parent):
"""
Finds a most relevant deform bone derived from specified org bone in parent rig, returns its name,
or returns None if this rig does not have a parent.
This method raises error if such a bone can not be found(but having a parent rig).
If there're multiple derived deform bones, the first one is returned.
"""
if not self.rigify_parent:
return None
filtered = self.rigify_parent.filter_derived_deform_bones(rig_parent)
if not filtered:
return None
derived_deform_bones_of_parent = list(filtered)
if len(derived_deform_bones_of_parent) == 0:
self.raise_error("Can not decide parent deform bone of %s" % rig_parent)
if not len(derived_deform_bones_of_parent) == 1:
print('Warn: there\' re multiple deform bones derived from parent: %s. The first one would be used.' % derived_deform_bones_of_parent)
parent_deform_bone = derived_deform_bones_of_parent[0]
return parent_deform_bone
###########################################################
# Parameters and UI

View File

@ -451,6 +451,7 @@ class Generator(base_generate.BaseGenerator):
obj.data["rig_id"] = self.rig_id
self.script = rig_ui_template.ScriptGenerator(self)
self.rigify_parent_all_deform_bones = metarig.data.rigify_parent_all_deform_bones
#------------------------------------------
bpy.ops.object.mode_set(mode='OBJECT')

View File

@ -47,7 +47,14 @@ class Rig(BaseRig, RelinkConstraintsMixin):
bones = self.bones
if self.make_deform:
self.set_bone_parent(bones.deform, bones.org, use_connect=False)
parent_deform_bone = None
if self.generator.rigify_parent_all_deform_bones:
parent_deform_bone = self.find_most_relevant_parent_deform_bone(self.get_bone_parent(bones.org))
if parent_deform_bone:
self.set_bone_parent(bones.deform, parent_deform_bone, use_connect=False)
else:
self.set_bone_parent(bones.deform, bones.org, use_connect=False)
new_parent = self.relink_bone_parent(bones.org)

View File

@ -102,6 +102,12 @@ class SimpleChainRig(BaseRig):
@stage.parent_bones
def parent_deform_chain(self):
parent_deform_bone = None
if self.generator.rigify_parent_all_deform_bones:
parent_deform_bone = self.find_most_relevant_parent_deform_bone(self.rig_parent_bone)
if parent_deform_bone:
self.set_bone_parent(self.bones.deform[0], parent_deform_bone)
self.parent_bone_chain(self.bones.deform, use_connect=True)
@stage.rig_bones

View File

@ -863,7 +863,14 @@ class BaseLimbRig(BaseRig):
@stage.parent_bones
def parent_deform_chain(self):
self.set_bone_parent(self.bones.deform[0], self.rig_parent_bone)
parent_deform_bone = None
if self.generator.rigify_parent_all_deform_bones:
parent_deform_bone = self.find_most_relevant_parent_deform_bone(self.rig_parent_bone)
if parent_deform_bone:
self.set_bone_parent(self.bones.deform[0], parent_deform_bone)
else:
self.set_bone_parent(self.bones.deform[0], self.rig_parent_bone)
self.parent_bone_chain(self.bones.deform, use_connect=True)
@stage.rig_bones

View File

@ -156,6 +156,9 @@ class DATA_PT_rigify_advanced(bpy.types.Panel):
col.separator()
col.row().prop(armature_id_store, "rigify_finalize_script", text="Run Script")
col.separator()
col.row().prop(armature_id_store, "rigify_parent_all_deform_bones")
class DATA_PT_rigify_samples(bpy.types.Panel):
bl_label = "Samples"