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:
Diffstat (limited to 'rigify/rigs/limbs/limb_rigs.py')
-rw-r--r--rigify/rigs/limbs/limb_rigs.py97
1 files changed, 65 insertions, 32 deletions
diff --git a/rigify/rigs/limbs/limb_rigs.py b/rigify/rigs/limbs/limb_rigs.py
index 81079c05..f1eb8639 100644
--- a/rigify/rigs/limbs/limb_rigs.py
+++ b/rigify/rigs/limbs/limb_rigs.py
@@ -23,12 +23,12 @@ import json
from ...utils.animation import add_generic_snap_fk_to_ik, add_fk_ik_snap_buttons
from ...utils.rig import connected_children_names
-from ...utils.bones import BoneDict, put_bone, compute_chain_x_axis, align_bone_orientation
-from ...utils.bones import align_bone_x_axis, align_bone_y_axis, align_bone_z_axis
+from ...utils.bones import BoneDict, put_bone, compute_chain_x_axis, align_bone_orientation, set_bone_widget_transform
from ...utils.naming import strip_org, make_derived_name
from ...utils.layers import ControlLayersOption
from ...utils.misc import pairwise_nozip, padnone, map_list
from ...utils.switch_parent import SwitchParentBuilder
+from ...utils.components import CustomPivotControl
from ...base_rig import stage, BaseRig
@@ -64,6 +64,7 @@ class BaseLimbRig(BaseRig):
self.segments = self.params.segments
self.bbone_segments = self.params.bbones
+ self.use_ik_pivot = self.params.make_custom_pivot
rot_axis = self.params.rotation_axis
@@ -124,15 +125,6 @@ class BaseLimbRig(BaseRig):
bone = self.get_bone(org)
return bone.head + bone.vector * (seg / self.segments)
- def align_roll_bone(self, org, name, y_axis):
- if y_axis:
- align_bone_y_axis(self.obj, name, y_axis)
-
- if self.main_axis == 'x':
- align_bone_x_axis(self.obj, name, self.get_bone(org).x_axis)
- else:
- align_bone_z_axis(self.obj, name, self.get_bone(org).z_axis)
-
@staticmethod
def vector_without_z(vector):
return Vector((vector[0], vector[1], 0))
@@ -154,6 +146,8 @@ class BaseLimbRig(BaseRig):
# IK controls
# ik_vispole
# IK pole visualization.
+ # ik_pivot
+ # Custom IK pivot (optional).
# mch:
# master:
# Parent of the master control.
@@ -161,6 +155,8 @@ class BaseLimbRig(BaseRig):
# FK follow behavior.
# fk[]:
# FK chain parents (or None)
+ # ik_pivot
+ # Custom IK pivot result (optional).
# ik_stretch
# IK stretch switch implementation.
# ik_target
@@ -328,22 +324,30 @@ class BaseLimbRig(BaseRig):
# IK controls
def get_extra_ik_controls(self):
- return []
+ if self.component_ik_pivot:
+ return [self.component_ik_pivot.control]
+ else:
+ return []
def get_all_ik_controls(self):
ctrl = self.bones.ctrl
- return [ctrl.ik_base, ctrl.ik_pole, ctrl.ik] + self.get_extra_ik_controls()
+ controls = [ctrl.ik_base, ctrl.ik_pole, ctrl.ik]
+ return controls + self.get_extra_ik_controls()
@stage.generate_bones
def make_ik_controls(self):
orgs = self.bones.org.main
- self.bones.ctrl.ik_base = self.copy_bone(orgs[0], make_derived_name(orgs[0], 'ctrl', '_ik'))
+ self.bones.ctrl.ik_base = self.make_ik_base_bone(orgs)
self.bones.ctrl.ik_pole = self.make_ik_pole_bone(orgs)
- self.bones.ctrl.ik = self.make_ik_control_bone(orgs)
+ self.bones.ctrl.ik = ik_name = self.make_ik_control_bone(orgs)
+ self.component_ik_pivot = self.build_ik_pivot(ik_name)
self.build_ik_parent_switch(SwitchParentBuilder(self.generator))
+ def make_ik_base_bone(self, orgs):
+ return self.copy_bone(orgs[0], make_derived_name(orgs[0], 'ctrl', '_ik'))
+
def make_ik_pole_bone(self, orgs):
name = self.copy_bone(orgs[0], make_derived_name(orgs[0], 'ctrl', '_ik_target'))
@@ -357,10 +361,25 @@ class BaseLimbRig(BaseRig):
def make_ik_control_bone(self, orgs):
return self.copy_bone(orgs[2], make_derived_name(orgs[2], 'ctrl', '_ik'))
+ def build_ik_pivot(self, ik_name, **args):
+ if self.use_ik_pivot:
+ return CustomPivotControl(self, 'ik_pivot', ik_name, parent=ik_name, **args)
+
+ def get_ik_control_output(self):
+ if self.component_ik_pivot:
+ return self.component_ik_pivot.output
+ else:
+ return self.bones.ctrl.ik
+
def register_switch_parents(self, pbuilder):
if self.rig_parent_bone:
pbuilder.register_parent(self, self.rig_parent_bone)
+ pbuilder.register_parent(
+ self, self.get_ik_control_output, name=self.bones.ctrl.ik,
+ exclude_self=True, tags={'limb_ik', 'child'},
+ )
+
def build_ik_parent_switch(self, pbuilder):
ctrl = self.bones.ctrl
@@ -398,9 +417,13 @@ class BaseLimbRig(BaseRig):
@stage.generate_widgets
def make_ik_control_widgets(self):
- self.make_ik_base_widget(self.bones.ctrl.ik_base)
- self.make_ik_pole_widget(self.bones.ctrl.ik_pole)
- self.make_ik_ctrl_widget(self.bones.ctrl.ik)
+ ctrl = self.bones.ctrl
+
+ set_bone_widget_transform(self.obj, ctrl.ik, self.get_ik_control_output())
+
+ self.make_ik_base_widget(ctrl.ik_base)
+ self.make_ik_pole_widget(ctrl.ik_pole)
+ self.make_ik_ctrl_widget(ctrl.ik)
def make_ik_base_widget(self, ctrl):
if self.main_axis == 'x':
@@ -453,7 +476,7 @@ class BaseLimbRig(BaseRig):
ik_input_head_tail = 0.0
def get_ik_input_bone(self):
- return self.bones.ctrl.ik
+ return self.get_ik_control_output()
def get_ik_output_chain(self):
return [self.bones.ctrl.ik_base, self.bones.mch.ik_end, self.bones.mch.ik_target]
@@ -670,7 +693,13 @@ class BaseLimbRig(BaseRig):
@stage.parent_bones
def parent_tweak_mch_chain(self):
- for mch, entry in zip(self.bones.mch.tweak, self.segment_table_tweak):
+ for args in zip(count(0), self.bones.mch.tweak, self.segment_table_tweak):
+ self.parent_tweak_mch_bone(*args)
+
+ def parent_tweak_mch_bone(self, i, mch, entry):
+ if i == 0:
+ self.set_bone_parent(mch, self.rig_parent_bone, inherit_scale='FIX_SHEAR')
+ else:
self.set_bone_parent(mch, entry.org)
@stage.rig_bones
@@ -694,6 +723,10 @@ class BaseLimbRig(BaseRig):
elif entry.seg_idx is not None:
self.make_constraint(tweak, 'COPY_SCALE', 'root', use_make_uniform=True)
+ if i == 0:
+ self.make_constraint(tweak, 'COPY_LOCATION', entry.org)
+ self.make_constraint(tweak, 'DAMPED_TRACK', entry.org, head_tail=1)
+
####################################################
# Deform chain
@@ -786,17 +819,23 @@ class BaseLimbRig(BaseRig):
)
params.segments = bpy.props.IntProperty(
- name = 'limb segments',
+ name = 'Limb Segments',
default = 2,
min = 1,
- description = 'Number of segments'
+ description = 'Number of limb segments'
)
params.bbones = bpy.props.IntProperty(
- name = 'bbone segments',
+ name = 'B-Bone Segments',
default = 10,
min = 1,
- description = 'Number of segments'
+ description = 'Number of B-Bone segments'
+ )
+
+ params.make_custom_pivot = bpy.props.BoolProperty(
+ name = "Custom Pivot Control",
+ default = False,
+ description = "Create a rotation pivot control that can be repositioned arbitrarily"
)
# Setting up extra layers for the FK and tweak
@@ -820,6 +859,8 @@ class BaseLimbRig(BaseRig):
r = layout.row()
r.prop(params, "bbones")
+ layout.prop(params, 'make_custom_pivot', text="Custom IK Pivot")
+
ControlLayersOption.FK.parameters_ui(layout, params)
ControlLayersOption.TWEAK.parameters_ui(layout, params)
@@ -843,8 +884,6 @@ class RigifyLimbIk2FkBase:
ctrl_bones: StringProperty(name="IK Controls")
extra_ctrls: StringProperty(name="Extra IK Controls")
- keyflags = None
-
def init_execute(self, context):
if self.fk_bones:
self.fk_bone_list = json.loads(self.fk_bones)
@@ -921,13 +960,11 @@ class RigifyLimbIk2FkBase:
class POSE_OT_rigify_limb_ik2fk(RigifyLimbIk2FkBase, RigifySingleUpdateMixin, bpy.types.Operator):
bl_idname = "pose.rigify_limb_ik2fk_" + rig_id
bl_label = "Snap IK->FK"
- bl_options = {'UNDO', 'INTERNAL'}
bl_description = "Snap the IK chain to FK result"
class POSE_OT_rigify_limb_ik2fk_bake(RigifyLimbIk2FkBase, RigifyBakeKeyframesMixin, bpy.types.Operator):
bl_idname = "pose.rigify_limb_ik2fk_bake_" + rig_id
bl_label = "Apply Snap IK->FK To Keyframes"
- bl_options = {'UNDO', 'INTERNAL'}
bl_description = "Snap the IK chain keyframes to FK result"
def execute_scan_curves(self, context, obj):
@@ -968,8 +1005,6 @@ SCRIPT_UTILITIES_OP_TOGGLE_POLE = SCRIPT_UTILITIES_OP_SNAP_IK_FK + ['''
class RigifyLimbTogglePoleBase(RigifyLimbIk2FkBase):
use_pole: bpy.props.BoolProperty(name="Use Pole Vector")
- keyflags_switch = None
-
def save_frame_state(self, context, obj):
return get_chain_transform_matrices(obj, self.ik_bone_list)
@@ -1007,13 +1042,11 @@ class RigifyLimbTogglePoleBase(RigifyLimbIk2FkBase):
class POSE_OT_rigify_limb_toggle_pole(RigifyLimbTogglePoleBase, RigifySingleUpdateMixin, bpy.types.Operator):
bl_idname = "pose.rigify_limb_toggle_pole_" + rig_id
bl_label = "Toggle Pole"
- bl_options = {'UNDO', 'INTERNAL'}
bl_description = "Switch the IK chain between pole and rotation"
class POSE_OT_rigify_limb_toggle_pole_bake(RigifyLimbTogglePoleBase, RigifyBakeKeyframesMixin, bpy.types.Operator):
bl_idname = "pose.rigify_limb_toggle_pole_bake_" + rig_id
bl_label = "Apply Toggle Pole To Keyframes"
- bl_options = {'UNDO', 'INTERNAL'}
bl_description = "Switch the IK chain between pole and rotation over a frame range"
def execute_scan_curves(self, context, obj):