diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2019-10-01 09:59:51 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2019-10-01 14:29:30 +0300 |
commit | 50c493fb22869e0e08936c4b7a44624887b1de58 (patch) | |
tree | 59c571688b6e09f9d41cf6053924f7a3dfdb377d | |
parent | e57714f3a2805b5ca71d68f967961950e707e191 (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.py | 11 | ||||
-rw-r--r-- | rigify/rigs/limbs/super_palm.py | 15 | ||||
-rw-r--r-- | rigify/rigs/spines/spine_rigs.py | 19 | ||||
-rw-r--r-- | rigify/rigs/spines/super_head.py | 10 | ||||
-rw-r--r-- | rigify/utils/switch_parent.py | 8 | ||||
-rw-r--r-- | rigify/utils/widgets.py | 29 |
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) |