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-02-11 23:27:26 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2022-02-11 23:40:22 +0300
commit7120e9c9e08720c20833a334fee197ed9a11dc64 (patch)
tree1900e8544142f3ac4bcc91059fb94a8fae9eb840
parent01c94f43a6ddc174c3f90aa9fa9c247ea79b4b76 (diff)
Rigify: allow aligning IK control location channels to world space.
For IK controls that move freely in space without being tied to a parent it makes sense to align the location channels to world (or root), while keeping rotation channels aligned to the limb end orientation. Blender already has a Local Location parenting option for this very use case, but Rigify wasn't using it. This adjusts the switchable parent mechanism so that the option works as intended, and provides a Rigify option that controls its value for IK controls. Note that now it is possible to enable the Local Location option directly on the control bones after generation and it will work correctly - it is not required to enable IK Local Location.
-rw-r--r--rigify/rigs/face/skin_eye.py2
-rw-r--r--rigify/rigs/limbs/limb_rigs.py13
-rw-r--r--rigify/rigs/limbs/super_finger.py15
-rw-r--r--rigify/utils/bones.py14
-rw-r--r--rigify/utils/switch_parent.py8
5 files changed, 51 insertions, 1 deletions
diff --git a/rigify/rigs/face/skin_eye.py b/rigify/rigs/face/skin_eye.py
index 2d1f6c2f..4955df6b 100644
--- a/rigify/rigs/face/skin_eye.py
+++ b/rigify/rigs/face/skin_eye.py
@@ -593,6 +593,8 @@ class EyeClusterControl(RigComponent):
def parent_bones(self):
if self.rig_count > 1:
+ self.get_bone(self.master_bone).use_local_location = False
+
for child in self.child_bones:
self.set_bone_parent(child, self.master_bone)
diff --git a/rigify/rigs/limbs/limb_rigs.py b/rigify/rigs/limbs/limb_rigs.py
index 2b4723a4..b72e9d40 100644
--- a/rigify/rigs/limbs/limb_rigs.py
+++ b/rigify/rigs/limbs/limb_rigs.py
@@ -432,6 +432,12 @@ class BaseLimbRig(BaseRig):
else:
self.set_bone_parent(self.bones.ctrl.ik_base, self.bones.mch.ik_swing)
+ self.set_ik_local_location(self.bones.ctrl.ik)
+ self.set_ik_local_location(self.bones.ctrl.ik_pole)
+
+ def set_ik_local_location(self, ctrl):
+ self.get_bone(ctrl).use_local_location = self.params.ik_local_location
+
@stage.configure_bones
def configure_ik_controls(self):
base = self.get_bone(self.bones.ctrl.ik_base)
@@ -927,6 +933,12 @@ class BaseLimbRig(BaseRig):
description = "Create a rotation pivot control that can be repositioned arbitrarily"
)
+ params.ik_local_location = bpy.props.BoolProperty(
+ name = "IK Local Location",
+ default = True,
+ description = "Specifies the value of the Local Location option for IK controls, which decides if the location channels are aligned to the local control orientation or world",
+ )
+
# Setting up extra layers for the FK and tweak
ControlLayersOption.FK.add_parameters(params)
ControlLayersOption.TWEAK.add_parameters(params)
@@ -949,6 +961,7 @@ class BaseLimbRig(BaseRig):
r.prop(params, "bbones")
layout.prop(params, 'make_custom_pivot', text="Custom IK Pivot")
+ layout.prop(params, 'ik_local_location')
ControlLayersOption.FK.parameters_ui(layout, params)
ControlLayersOption.TWEAK.parameters_ui(layout, params)
diff --git a/rigify/rigs/limbs/super_finger.py b/rigify/rigs/limbs/super_finger.py
index 9eed5415..2229c0c0 100644
--- a/rigify/rigs/limbs/super_finger.py
+++ b/rigify/rigs/limbs/super_finger.py
@@ -152,6 +152,12 @@ class Rig(SimpleChainRig):
no_fix_rotation=True, no_fix_scale=True,
)
+ @stage.parent_bones
+ def parent_ik_control(self):
+ if self.make_ik:
+ bone = self.get_bone(self.bones.ctrl.ik)
+ bone.use_local_location = self.params.ik_local_location
+
@stage.configure_bones
def configure_ik_control(self):
if self.make_ik:
@@ -366,6 +372,12 @@ class Rig(SimpleChainRig):
description = "Create an optional IK control"
)
+ params.ik_local_location = bpy.props.BoolProperty(
+ name = 'IK Local Location',
+ default = True,
+ description = "Specifies the value of the Local Location option for IK controls, which decides if the location channels are aligned to the local control orientation or world",
+ )
+
ControlLayersOption.TWEAK.add_parameters(params)
ControlLayersOption.EXTRA_IK.add_parameters(params)
@@ -380,6 +392,9 @@ class Rig(SimpleChainRig):
layout.prop(params, 'bbones')
layout.prop(params, 'make_extra_ik_control', text='IK Control')
+ if params.make_extra_ik_control:
+ layout.prop(params, 'ik_local_location')
+
ControlLayersOption.TWEAK.parameters_ui(layout, params)
if params.make_extra_ik_control:
diff --git a/rigify/utils/bones.py b/rigify/utils/bones.py
index 16cf62de..10a8926d 100644
--- a/rigify/utils/bones.py
+++ b/rigify/utils/bones.py
@@ -482,6 +482,20 @@ def align_bone_orientation(obj, bone_name, target_bone_name):
bone1_e.roll = bone2_e.roll
+def set_bone_orientation(obj, bone_name, orientation):
+ """ Aligns the orientation of bone to target bone or matrix. """
+ if isinstance(orientation, str):
+ align_bone_orientation(obj, bone_name, orientation)
+
+ else:
+ bone_e = obj.data.edit_bones[bone_name]
+
+ matrix = Matrix(orientation).to_4x4()
+ matrix.translation = bone_e.head
+
+ bone_e.matrix = matrix
+
+
def align_bone_roll(obj, bone1, bone2):
""" Aligns the roll of two bones.
"""
diff --git a/rigify/utils/switch_parent.py b/rigify/utils/switch_parent.py
index 405008b9..ff5217b4 100644
--- a/rigify/utils/switch_parent.py
+++ b/rigify/utils/switch_parent.py
@@ -7,6 +7,7 @@ import json
from .errors import MetarigError
from .naming import strip_prefix, make_derived_name
+from .bones import set_bone_orientation
from .mechanism import MechanismUtilityMixin
from .rig import rig_is_child
from .misc import map_list, map_apply, force_lazy
@@ -16,6 +17,7 @@ from ..base_generate import GeneratorPlugin
from collections import defaultdict
from itertools import count, repeat, chain
+from mathutils import Matrix
class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
@@ -80,7 +82,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
self.local_parents[id(rig)].append(entry)
- def build_child(self, rig, bone, *, use_parent_mch=True, **options):
+ def build_child(self, rig, bone, *, use_parent_mch=True, mch_orientation=None, **options):
"""
Build a switchable parent mechanism for the specified bone.
@@ -89,6 +91,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
bone Name of the child bone.
extra_parents List of bone names or (name, user_name) pairs to use as additional parents.
use_parent_mch Create an intermediate MCH bone for the constraints and parent the child to it.
+ mch_orientation Orientation matrix or bone name to align the MCH bone to; defaults to world.
select_parent Select the specified bone instead of the last one.
select_tags List of parent tags to try for default selection.
ignore_global Ignore the is_global flag of potential parents.
@@ -120,6 +123,9 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
# Create MCH proxy
if use_parent_mch:
mch_bone = rig.copy_bone(bone, make_derived_name(bone, 'mch', '.parent'), scale=1/3)
+
+ set_bone_orientation(rig.obj, mch_bone, mch_orientation or Matrix.Identity(4))
+
else:
mch_bone = bone