Rigify: add option to parent all deform bones according to metarig #104644
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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')
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user