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:
-rw-r--r--rigify/rigs/limbs/arm.py67
-rw-r--r--rigify/rigs/limbs/limb_rigs.py4
-rw-r--r--rigify/rigs/spines/spine_rigs.py3
-rw-r--r--rigify/utils/switch_parent.py45
4 files changed, 106 insertions, 13 deletions
diff --git a/rigify/rigs/limbs/arm.py b/rigify/rigs/limbs/arm.py
index 1ac979d0..0eced859 100644
--- a/rigify/rigs/limbs/arm.py
+++ b/rigify/rigs/limbs/arm.py
@@ -21,12 +21,15 @@
import bpy
from itertools import count
+from mathutils import Matrix
-from ...utils.bones import BoneDict, compute_chain_x_axis, align_bone_x_axis, align_bone_z_axis
+from ...utils.bones import put_bone, compute_chain_x_axis, align_bone_x_axis, align_bone_z_axis
from ...utils.naming import make_derived_name
from ...utils.misc import map_list
+from ...utils.widgets import adjust_widget_transform_mesh
from ..widgets import create_hand_widget
+from ...utils.widgets_basic import create_circle_widget
from ...base_rig import stage
@@ -42,6 +45,8 @@ class Rig(BaseLimbRig):
super().initialize()
+ self.make_palm_pivot = self.params.make_ik_palm_pivot
+
def prepare_bones(self):
orgs = self.bones.org.main
@@ -68,10 +73,70 @@ class Rig(BaseLimbRig):
create_hand_widget(self.obj, ctrl)
####################################################
+ # Palm Pivot
+
+ def get_ik_input_bone(self):
+ if self.make_palm_pivot:
+ return self.bones.mch.ik_palm
+ else:
+ return self.get_ik_control_output()
+
+ def get_extra_ik_controls(self):
+ controls = super().get_extra_ik_controls()
+ if self.make_palm_pivot:
+ controls += [self.bones.ctrl.ik_palm]
+ return controls
+
+ @stage.generate_bones
+ def make_palm_pivot_control(self):
+ if self.make_palm_pivot:
+ org = self.bones.org.main[2]
+ self.bones.ctrl.ik_palm = self.make_palm_pivot_bone(org)
+ self.bones.mch.ik_palm = self.copy_bone(org, make_derived_name(org, 'mch'), scale=0.25)
+
+ def make_palm_pivot_bone(self, org):
+ name = self.copy_bone(org, make_derived_name(org, 'ctrl', '_ik_palm'), scale=0.5)
+ put_bone(self.obj, name, self.get_bone(org).tail)
+ return name
+
+ @stage.parent_bones
+ def parent_palm_pivot_control(self):
+ if self.make_palm_pivot:
+ ctrl = self.bones.ctrl.ik_palm
+ self.set_bone_parent(ctrl, self.get_ik_control_output())
+ self.set_bone_parent(self.bones.mch.ik_palm, ctrl)
+
+ @stage.generate_widgets
+ def make_palm_pivot_widget(self):
+ if self.make_palm_pivot:
+ ctrl = self.bones.ctrl.ik_palm
+
+ if self.main_axis == 'x':
+ obj = create_circle_widget(self.obj, ctrl, head_tail=-0.3, head_tail_x=0.5)
+ else:
+ obj = create_circle_widget(self.obj, ctrl, head_tail=0.5, head_tail_x=-0.3)
+
+ if obj:
+ org_bone = self.get_bone(self.bones.org.main[2])
+ offset = org_bone.head - self.get_bone(ctrl).head
+ adjust_widget_transform_mesh(obj, Matrix.Translation(offset))
+
+ ####################################################
# Settings
@classmethod
+ def add_parameters(self, params):
+ super().add_parameters(params)
+
+ params.make_ik_palm_pivot = bpy.props.BoolProperty(
+ name="IK Palm Pivot", default=False,
+ description="Make an extra IK hand control pivoting around the tip of the hand"
+ )
+
+ @classmethod
def parameters_ui(self, layout, params):
+ layout.prop(params, "make_ik_palm_pivot")
+
super().parameters_ui(layout, params, 'Hand')
diff --git a/rigify/rigs/limbs/limb_rigs.py b/rigify/rigs/limbs/limb_rigs.py
index e09dfb7b..b68fbdd0 100644
--- a/rigify/rigs/limbs/limb_rigs.py
+++ b/rigify/rigs/limbs/limb_rigs.py
@@ -376,8 +376,8 @@ class BaseLimbRig(BaseRig):
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'},
+ 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):
diff --git a/rigify/rigs/spines/spine_rigs.py b/rigify/rigs/spines/spine_rigs.py
index 25450717..070a6bd3 100644
--- a/rigify/rigs/spines/spine_rigs.py
+++ b/rigify/rigs/spines/spine_rigs.py
@@ -99,7 +99,8 @@ class BaseSpineRig(TweakChainRig):
org_parent = self.get_bone_parent(self.bones.org[0])
parents = [org_parent] if org_parent else []
- pbuilder.register_parent(self, self.get_master_control_output, name='Torso', tags={'torso'})
+ pbuilder.register_parent(self, self.get_master_control_output, name='Torso', tags={'torso', 'child'})
+
pbuilder.build_child(
self, master_name, exclude_self=True,
extra_parents=parents, select_parent=org_parent,
diff --git a/rigify/utils/switch_parent.py b/rigify/utils/switch_parent.py
index bb2d9045..8247a7c8 100644
--- a/rigify/utils/switch_parent.py
+++ b/rigify/utils/switch_parent.py
@@ -96,6 +96,8 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
ignore_global Ignore the is_global flag of potential parents.
exclude_self Ignore parents registered by the rig itself.
context_rig Rig to use for selecting parents.
+ no_implicit Only use parents listed as extra_parents.
+ only_selected Like no_implicit, but allow the 'default' selected parent.
prop_bone Name of the bone to add the property to.
prop_id Actual name of the control property.
@@ -159,6 +161,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
'prop_bone': None, 'prop_id': None, 'prop_name': None, 'controls': None,
'select_parent': None, 'ignore_global': False, 'exclude_self': False,
'context_rig': None, 'select_tags': None,
+ 'no_implicit': False, 'only_selected': False,
'ctrl_bone': None,
'no_fix_location': False, 'no_fix_rotation': False, 'no_fix_scale': False,
'copy_location': None, 'copy_rotation': None, 'copy_scale': None,
@@ -255,33 +258,57 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
parent_tags[parent['bone']] |= parent['tags']
last_main_parent_bone = child['parents'][-1]['bone']
- num_main_parents = len(parent_map.items())
+ extra_parents = set()
for parent in force_lazy(child['extra_parents'] or []):
if not isinstance(parent, tuple):
parent = (parent, None)
+ extra_parents.add(parent[0])
if parent[0] not in parent_map:
parent_map[parent[0]] = parent[1]
+ for parent in parent_map:
+ if parent in self.child_map:
+ parent_tags[parent] |= {'child'}
+
parent_bones = list(parent_map.items())
- child['parent_bones'] = parent_bones
# Find which bone to select
select_bone = force_lazy(child['select_parent']) or last_main_parent_bone
select_tags = force_lazy(child['select_tags']) or []
- select_index = num_main_parents
- try:
- select_index = 1 + next(i for i, (bone, _) in enumerate(parent_bones) if bone == select_bone)
- except StopIteration:
- print("RIGIFY ERROR: Can't find bone '%s' to select as default parent of '%s'\n" % (select_bone, bone))
+ if child['no_implicit']:
+ assert len(extra_parents) > 0
+ parent_bones = [ item for item in parent_bones if item[0] in extra_parents ]
+ if last_main_parent_bone not in extra_parents:
+ last_main_parent_bone = parent_bones[-1][0]
for tag in select_tags:
- matching = [ i for i, (bone, _) in enumerate(parent_bones) if tag in parent_tags[bone] ]
+ tag_set = tag if isinstance(tag, set) else {tag}
+ matching = [
+ bone for (bone, _) in parent_bones
+ if not tag_set.isdisjoint(parent_tags[bone])
+ ]
if len(matching) > 0:
- select_index = 1 + matching[-1]
+ select_bone = matching[-1]
break
+ if select_bone not in parent_map:
+ print("RIGIFY ERROR: Can't find bone '%s' to select as default parent of '%s'\n" % (select_bone, bone))
+ select_bone = last_main_parent_bone
+
+ if child['only_selected']:
+ filter_set = { select_bone, *extra_parents }
+ parent_bones = [ item for item in parent_bones if item[0] in filter_set ]
+
+ try:
+ select_index = 1 + next(i for i, (bone, _) in enumerate(parent_bones) if bone == select_bone)
+ except StopIteration:
+ select_index = len(parent_bones)
+ print("RIGIFY ERROR: Invalid default parent '%s' of '%s'\n" % (select_bone, bone))
+
+ child['parent_bones'] = parent_bones
+
# Create the controlling property
prop_bone = child['prop_bone'] = force_lazy(child['prop_bone']) or bone
prop_name = child['prop_name'] or child['prop_id'] or 'Parent Switch'