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>2019-10-01 09:59:51 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-10-01 14:29:30 +0300
commit50c493fb22869e0e08936c4b7a44624887b1de58 (patch)
tree59c571688b6e09f9d41cf6053924f7a3dfdb377d
parente57714f3a2805b5ca71d68f967961950e707e191 (diff)
Rigify: add more parent switching and 2.81 inherit scale features.
- Add a parent switch to the main spine control, to allow using the key baking operator to convert between moving and fixed root bone. - Add hips, chest and head as parents for children of the spine. - Use 'Fix Shear' Inherit Scale and 'Make Uniform' Copy Scale in limbs. - Switch code to use the new inherit_scale parameter of set_bone_parent. - Allow local matrices in adjust_widget_transform_mesh.
-rw-r--r--rigify/rigs/limbs/limb_rigs.py11
-rw-r--r--rigify/rigs/limbs/super_palm.py15
-rw-r--r--rigify/rigs/spines/spine_rigs.py19
-rw-r--r--rigify/rigs/spines/super_head.py10
-rw-r--r--rigify/utils/switch_parent.py8
-rw-r--r--rigify/utils/widgets.py29
6 files changed, 60 insertions, 32 deletions
diff --git a/rigify/rigs/limbs/limb_rigs.py b/rigify/rigs/limbs/limb_rigs.py
index 30d475bb..81079c05 100644
--- a/rigify/rigs/limbs/limb_rigs.py
+++ b/rigify/rigs/limbs/limb_rigs.py
@@ -218,7 +218,7 @@ class BaseLimbRig(BaseRig):
def parent_mch_follow_bone(self):
mch = self.bones.mch.follow
align_bone_orientation(self.obj, mch, 'root')
- self.set_bone_parent(mch, self.rig_parent_bone)
+ self.set_bone_parent(mch, self.rig_parent_bone, inherit_scale='FIX_SHEAR')
@stage.configure_bones
def configure_mch_follow_bone(self):
@@ -232,8 +232,9 @@ class BaseLimbRig(BaseRig):
def rig_mch_follow_bone(self):
mch = self.bones.mch.follow
+ self.make_constraint(mch, 'COPY_SCALE', 'root', use_make_uniform=True)
+
con = self.make_constraint(mch, 'COPY_ROTATION', 'root')
- self.make_constraint(mch, 'COPY_SCALE', 'root')
self.make_driver(con, 'influence', variables=[(self.prop_bone, 'FK_limb_follow')])
@@ -311,7 +312,7 @@ class BaseLimbRig(BaseRig):
def parent_fk_parent_bone(self, i, parent_mch, prev_ctrl, org, prev_org):
if i == 2:
- self.set_bone_parent(parent_mch, prev_ctrl, use_connect=True)
+ self.set_bone_parent(parent_mch, prev_ctrl, use_connect=True, inherit_scale='NONE')
@stage.rig_bones
def rig_fk_parent_chain(self):
@@ -320,7 +321,7 @@ class BaseLimbRig(BaseRig):
def rig_fk_parent_bone(self, i, parent_mch, org):
if i == 2:
- self.make_constraint(parent_mch, 'COPY_SCALE', 'root')
+ self.make_constraint(parent_mch, 'COPY_SCALE', 'root', use_make_uniform=True)
####################################################
@@ -691,7 +692,7 @@ class BaseLimbRig(BaseRig):
self.make_constraint(tweak, 'DAMPED_TRACK', next_tweak)
elif entry.seg_idx is not None:
- self.make_constraint(tweak, 'COPY_SCALE', 'root')
+ self.make_constraint(tweak, 'COPY_SCALE', 'root', use_make_uniform=True)
####################################################
diff --git a/rigify/rigs/limbs/super_palm.py b/rigify/rigs/limbs/super_palm.py
index a7b322aa..8bcbabf8 100644
--- a/rigify/rigs/limbs/super_palm.py
+++ b/rigify/rigs/limbs/super_palm.py
@@ -115,17 +115,21 @@ class Rig(BaseRig):
@stage.parent_bones
def parent_master_control(self):
- self.set_bone_parent(self.bones.ctrl.master, self.rig_parent_bone)
+ self.set_bone_parent(self.bones.ctrl.master, self.rig_parent_bone, inherit_scale='AVERAGE')
if self.make_secondary:
- self.set_bone_parent(self.bones.ctrl.secondary, self.rig_parent_bone)
+ self.set_bone_parent(self.bones.ctrl.secondary, self.rig_parent_bone, inherit_scale='AVERAGE')
@stage.configure_bones
def configure_master_control(self):
- self.copy_bone_properties(self.bones.org[-1], self.bones.ctrl.master)
+ self.configure_control_bone(self.bones.ctrl.master, self.bones.org[-1])
if self.make_secondary:
- self.copy_bone_properties(self.bones.org[0], self.bones.ctrl.secondary)
+ self.configure_control_bone(self.bones.ctrl.secondary, self.bones.org[0])
+
+ def configure_control_bone(self, ctrl, org):
+ self.copy_bone_properties(org, ctrl)
+ self.get_bone(ctrl).lock_scale = (True, True, True)
@stage.generate_widgets
def make_master_control_widgets(self):
@@ -179,8 +183,7 @@ class Rig(BaseRig):
@stage.parent_bones
def parent_org_chain(self):
for org in self.bones.org:
- self.set_bone_parent(org, self.rig_parent_bone)
- self.get_bone(org).inherit_scale = 'NONE'
+ self.set_bone_parent(org, self.rig_parent_bone, inherit_scale='NONE')
@stage.rig_bones
def rig_org_chain(self):
diff --git a/rigify/rigs/spines/spine_rigs.py b/rigify/rigs/spines/spine_rigs.py
index 34eefbf5..6628289f 100644
--- a/rigify/rigs/spines/spine_rigs.py
+++ b/rigify/rigs/spines/spine_rigs.py
@@ -64,11 +64,26 @@ class BaseSpineRig(TweakChainRig):
align_bone_to_axis(self.obj, name, 'y', length=self.length * 0.6)
- SwitchParentBuilder(self.generator).register_parent(self, name)
+ self.build_parent_switch(name)
+
+ def build_parent_switch(self, master_name):
+ pbuilder = SwitchParentBuilder(self.generator)
+ pbuilder.register_parent(self, master_name, name='Torso')
+ pbuilder.build_child(
+ self, master_name, exclude_self=True,
+ prop_id='torso_parent', prop_name='Torso Parent',
+ controls=lambda: self.bones.flatten('ctrl'),
+ )
+
+ self.register_parent_bones(pbuilder)
+
+ def register_parent_bones(self, pbuilder):
+ pbuilder.register_parent(self, self.bones.org[0], name='Hips', exclude_self=True)
+ pbuilder.register_parent(self, self.bones.org[-1], name='Chest', exclude_self=True)
@stage.parent_bones
def parent_master_control(self):
- self.set_bone_parent(self.bones.ctrl.master, self.rig_parent_bone)
+ pass
@stage.configure_bones
def configure_master_control(self):
diff --git a/rigify/rigs/spines/super_head.py b/rigify/rigs/spines/super_head.py
index 422f3ad0..9b85e5b5 100644
--- a/rigify/rigs/spines/super_head.py
+++ b/rigify/rigs/spines/super_head.py
@@ -26,6 +26,7 @@ from ...utils.naming import make_derived_name
from ...utils.bones import align_bone_orientation
from ...utils.widgets_basic import create_circle_widget, create_cube_widget
from ...utils.widgets_special import create_neck_bend_widget, create_neck_tweak_widget
+from ...utils.switch_parent import SwitchParentBuilder
from ...utils.misc import map_list
from ...base_rig import stage
@@ -253,8 +254,7 @@ class Rig(BaseHeadTailRig):
def parent_mch_chain(self):
mch = self.bones.mch
for bone in mch.chain:
- self.set_bone_parent(bone, mch.stretch)
- self.get_bone(bone).inherit_scale = 'NONE'
+ self.set_bone_parent(bone, mch.stretch, inherit_scale='NONE')
@stage.rig_bones
def rig_mch_chain(self):
@@ -318,6 +318,12 @@ class Rig(BaseHeadTailRig):
####################################################
# ORG and DEF bones
+ @stage.generate_bones
+ def register_parent_bones(self):
+ rig = self.rigify_parent or self
+ builder = SwitchParentBuilder(self.generator)
+ builder.register_parent(rig, self.bones.org[-1], name='Head', exclude_self=True)
+
@stage.configure_bones
def configure_bbone_chain(self):
self.get_bone(self.bones.deform[-1]).bone.bbone_segments = 1
diff --git a/rigify/utils/switch_parent.py b/rigify/utils/switch_parent.py
index 85e6e130..463398fc 100644
--- a/rigify/utils/switch_parent.py
+++ b/rigify/utils/switch_parent.py
@@ -96,6 +96,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
use_parent_mch Create an intermediate MCH bone for the constraints and parent the child to it.
select_parent Select the specified bone instead of the last one.
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.
prop_bone Name of the bone to add the property to.
@@ -158,7 +159,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
child_option_table = {
'extra_parents': None,
'prop_bone': None, 'prop_id': None, 'prop_name': None, 'controls': None,
- 'select_parent': None, 'ignore_global': False, 'context_rig': None,
+ 'select_parent': None, 'ignore_global': False, 'exclude_self': False, 'context_rig': None,
'ctrl_bone': None,
'no_fix_location': False, 'no_fix_rotation': False, 'no_fix_scale': False,
'copy_location': None, 'copy_rotation': None, 'copy_scale': None,
@@ -186,7 +187,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
for parent in self.parent_list:
if parent['rig'] is child_rig:
- if parent['exclude_self']:
+ if parent['exclude_self'] or child['exclude_self']:
continue
elif parent['is_global'] and not child['ignore_global']:
# Can't use parents from own children, even if global (cycle risk)
@@ -218,8 +219,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
# Parent child to the MCH proxy
if mch != child['bone']:
- rig.set_bone_parent(child['bone'], mch)
- rig.get_bone(child['bone']).inherit_scale = child['inherit_scale']
+ rig.set_bone_parent(child['bone'], mch, inherit_scale=child['inherit_scale'])
def configure_bones(self):
for child in self.child_list:
diff --git a/rigify/utils/widgets.py b/rigify/utils/widgets.py
index f7e796b6..f4713372 100644
--- a/rigify/utils/widgets.py
+++ b/rigify/utils/widgets.py
@@ -50,16 +50,8 @@ def obj_to_bone(obj, rig, bone_name, bone_transform_name=None):
elif bone.custom_shape_transform:
bone = bone.custom_shape_transform
- mat = rig.matrix_world @ bone.bone.matrix_local
-
- obj.location = mat.to_translation()
-
obj.rotation_mode = 'XYZ'
- obj.rotation_euler = mat.to_euler()
-
- scl = mat.to_scale()
- scl_avg = (scl[0] + scl[1] + scl[2]) / 3
- obj.scale = (scale * scl_avg), (scale * scl_avg), (scale * scl_avg)
+ obj.matrix_basis = rig.matrix_world @ bone.bone.matrix_local @ Matrix.Scale(scale, 4)
def create_widget(rig, bone_name, bone_transform_name=None):
@@ -159,11 +151,22 @@ def adjust_widget_axis(obj, axis='y', offset=0.0):
vert.co = matrix @ vert.co
-def adjust_widget_transform(obj, matrix):
- """Adjust the generated widget by applying a world space correction matrix to the mesh."""
+def adjust_widget_transform_mesh(obj, matrix, local=None):
+ """Adjust the generated widget by applying a correction matrix to the mesh.
+ If local is false, the matrix is in world space.
+ If local is True, it's in the local space of the widget.
+ If local is a bone, it's in the local space of the bone.
+ """
if obj:
- obmat = obj.matrix_basis
- matrix = obmat.inverted() @ matrix @ obmat
+ if local is not True:
+ if local:
+ assert isinstance(local, bpy.types.PoseBone)
+ bonemat = local.id_data.matrix_world @ local.bone.matrix_local
+ matrix = bonemat @ matrix @ bonemat.inverted()
+
+ obmat = obj.matrix_basis
+ matrix = obmat.inverted() @ matrix @ obmat
+
obj.data.transform(matrix)