Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2022-01-04 18:40:07 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2022-01-09 15:41:09 +0300
commit0391f865e12d432ad06050f654a04f259361f123 (patch)
tree62afb85b00a9bc6cac2b58f483795a271534709a /rigify/rigs/limbs/limb_rigs.py
parent6afec05c3286cdea58ab269fb8dd1f5de011de4e (diff)
Rigify: support separate IK and FK controls for the toe.
Currently the leg rig tries to share one control between IK and FK modes, which looks as a nice optimization at first, but makes it impossible to IK/FK snap correctly if the IK foot is rolled forward. This commit adds an option to generate separate toe controls.
Diffstat (limited to 'rigify/rigs/limbs/limb_rigs.py')
-rw-r--r--rigify/rigs/limbs/limb_rigs.py50
1 files changed, 37 insertions, 13 deletions
diff --git a/rigify/rigs/limbs/limb_rigs.py b/rigify/rigs/limbs/limb_rigs.py
index ae854638..2e6fe538 100644
--- a/rigify/rigs/limbs/limb_rigs.py
+++ b/rigify/rigs/limbs/limb_rigs.py
@@ -257,6 +257,7 @@ class BaseLimbRig(BaseRig):
self.bones.ctrl.fk = map_list(self.make_fk_control_bone, count(0), self.bones.org.main)
fk_name_suffix_cutoff = 2
+ fk_ik_layer_cutoff = 3
def get_fk_name(self, i, org, kind):
return make_derived_name(org, kind, '_fk' if i <= self.fk_name_suffix_cutoff else '')
@@ -283,8 +284,9 @@ class BaseLimbRig(BaseRig):
for args in zip(count(0), self.bones.ctrl.fk, self.bones.org.main):
self.configure_fk_control_bone(*args)
- ControlLayersOption.FK.assign_rig(self, self.bones.ctrl.fk[0:3])
- ControlLayersOption.FK.assign_rig(self, self.bones.ctrl.fk[3:], combine=True, priority=1)
+ cut = self.fk_ik_layer_cutoff
+ ControlLayersOption.FK.assign_rig(self, self.bones.ctrl.fk[0:cut])
+ ControlLayersOption.FK.assign_rig(self, self.bones.ctrl.fk[cut:], combine=True, priority=1)
def configure_fk_control_bone(self, i, ctrl, org):
self.copy_bone_properties(org, ctrl)
@@ -352,16 +354,24 @@ class BaseLimbRig(BaseRig):
def get_middle_ik_controls(self):
return []
+ def get_tail_ik_controls(self):
+ return []
+
def get_ik_fk_position_chains(self):
ik_chain = self.get_ik_output_chain()
- return ik_chain, self.bones.ctrl.fk[0:len(ik_chain)]
+ tail_chain = self.get_tail_ik_controls()
+ return ik_chain, tail_chain, self.bones.ctrl.fk[0:len(ik_chain)+len(tail_chain)]
def get_ik_control_chain(self):
ctrl = self.bones.ctrl
return [ctrl.ik_base, ctrl.ik_pole, *self.get_middle_ik_controls(), ctrl.ik]
def get_all_ik_controls(self):
- return self.get_ik_control_chain() + self.get_extra_ik_controls()
+ return [
+ *self.get_ik_control_chain(),
+ *self.get_tail_ik_controls(),
+ *self.get_extra_ik_controls(),
+ ]
@stage.generate_bones
def make_ik_controls(self):
@@ -596,22 +606,20 @@ class BaseLimbRig(BaseRig):
def add_global_buttons(self, panel, rig_name):
ctrl = self.bones.ctrl
- ik_chain = self.get_ik_output_chain()
- fk_chain = ctrl.fk[0:len(ik_chain)]
+ ik_chain, tail_chain, fk_chain = self.get_ik_fk_position_chains()
add_generic_snap_fk_to_ik(
panel,
- fk_bones=fk_chain, ik_bones=ik_chain,
+ fk_bones=fk_chain, ik_bones=ik_chain+tail_chain,
ik_ctrl_bones=self.get_all_ik_controls(),
rig_name=rig_name
)
- ik_chain, fk_chain = self.get_ik_fk_position_chains()
add_limb_snap_ik_to_fk(
panel,
master=ctrl.master,
- fk_bones=fk_chain, ik_bones=ik_chain,
+ fk_bones=fk_chain, ik_bones=ik_chain, tail_bones=tail_chain,
ik_ctrl_bones=self.get_ik_control_chain(),
ik_extra_ctrls=self.get_extra_ik_controls(),
rig_name=rig_name
@@ -619,7 +627,7 @@ class BaseLimbRig(BaseRig):
def add_ik_only_buttons(self, panel, rig_name):
ctrl = self.bones.ctrl
- ik_chain, fk_chain = self.get_ik_fk_position_chains()
+ ik_chain, tail_chain, fk_chain = self.get_ik_fk_position_chains()
add_limb_toggle_pole(
panel, master=ctrl.master,
@@ -688,7 +696,7 @@ class BaseLimbRig(BaseRig):
@stage.rig_bones
def rig_org_chain(self):
- ik = self.get_ik_output_chain()
+ ik = self.get_ik_output_chain() + self.get_tail_ik_controls()
for args in zip(count(0), self.bones.org.main, self.bones.ctrl.fk, padnone(ik)):
self.rig_org_bone(*args)
@@ -979,6 +987,7 @@ class RigifyLimbIk2FkBase:
fk_bones: StringProperty(name="FK Bone Chain")
ik_bones: StringProperty(name="IK Result Bone Chain")
ctrl_bones: StringProperty(name="IK Controls")
+ tail_bones: StringProperty(name="Tail IK Controls", default="[]")
extra_ctrls: StringProperty(name="Extra IK Controls")
def init_execute(self, context):
@@ -986,6 +995,7 @@ class RigifyLimbIk2FkBase:
self.fk_bone_list = json.loads(self.fk_bones)
self.ik_bone_list = json.loads(self.ik_bones)
self.ctrl_bone_list = json.loads(self.ctrl_bones)
+ self.tail_bone_list = json.loads(self.tail_bones)
self.extra_ctrl_list = json.loads(self.extra_ctrls)
def get_use_pole(self, obj):
@@ -1016,9 +1026,15 @@ class RigifyLimbIk2FkBase:
mat = convert_pose_matrix_via_rest_delta(mat, ik, ctrl)
set_transform_from_matrix(obj, ctrl.name, mat, keyflags=keyflags)
- def apply_frame_state(self, context, obj, matrices):
+ def apply_frame_state(self, context, obj, all_matrices):
ik_bones = [ obj.pose.bones[k] for k in self.ik_bone_list ]
ctrl_bones = [ obj.pose.bones[k] for k in self.ctrl_bone_list ]
+ tail_bones = [ obj.pose.bones[k] for k in self.tail_bone_list ]
+
+ assert len(all_matrices) == len(ik_bones) + len(tail_bones)
+
+ matrices = all_matrices[0:len(ik_bones)]
+ tail_matrices = all_matrices[len(ik_bones):]
use_pole = self.get_use_pole(obj)
@@ -1055,6 +1071,11 @@ class RigifyLimbIk2FkBase:
# Assign middle control transforms (final pass)
self.assign_middle_controls(context, obj, matrices, ik_bones, ctrl_bones, keyflags=self.keyflags)
+ # Assign tail control transforms
+ for mat, ctrl in zip(tail_matrices, tail_bones):
+ context.view_layer.update()
+ set_transform_from_matrix(obj, ctrl.name, mat, keyflags=self.keyflags)
+
# Keyframe controls
if self.keyflags is not None:
if use_pole:
@@ -1083,16 +1104,19 @@ class POSE_OT_rigify_limb_ik2fk_bake(RigifyLimbIk2FkBase, RigifyBakeKeyframesMix
return self.bake_get_all_bone_curves(self.ctrl_bone_list + self.extra_ctrl_list, TRANSFORM_PROPS_ALL)
''']
-def add_limb_snap_ik_to_fk(panel, *, master=None, fk_bones=[], ik_bones=[], ik_ctrl_bones=[], ik_extra_ctrls=[], rig_name=''):
+def add_limb_snap_ik_to_fk(panel, *, master=None, fk_bones=[], ik_bones=[], tail_bones=[], ik_ctrl_bones=[], ik_extra_ctrls=[], rig_name=''):
panel.use_bake_settings()
panel.script.add_utilities(SCRIPT_UTILITIES_OP_SNAP_IK_FK)
panel.script.register_classes(SCRIPT_REGISTER_OP_SNAP_IK_FK)
+ assert len(fk_bones) == len(ik_bones) + len(tail_bones)
+
op_props = {
'prop_bone': master,
'fk_bones': json.dumps(fk_bones),
'ik_bones': json.dumps(ik_bones),
'ctrl_bones': json.dumps(ik_ctrl_bones),
+ 'tail_bones': json.dumps(tail_bones),
'extra_ctrls': json.dumps(ik_extra_ctrls),
}