Skip to content

Commit

Permalink
Fixed build_ik...the start joint was actually never being respected f…
Browse files Browse the repository at this point in the history
…rom the start if you don't set the flag...

Fixed the duplicate condition for Foot building and hopefully fixed the build_ik_toe chain builds.

Removed the toeEnd joint so retargetted all the test builds to the toe.

Added a foot with leg test skeleton file to test integration with a preexisting leg setup.
  • Loading branch information
AndresMWeber committed Feb 8, 2018
1 parent 0c96a14 commit 9751758
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 200 deletions.
8 changes: 5 additions & 3 deletions anvil/sub_rig_templates/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ class SubRigTemplate(nt.SubRig):
BUILT_IN_ATTRIBUTES = nt.SubRig.BUILT_IN_ATTRIBUTES.merge({cfg.IKFK_BLEND: at.ZERO_TO_ONE_KWARGS}, new=True)
DEFAULT_FK_SHAPE = cfg.DEFAULT_FK_SHAPE

def build_ik(self, hierarchy, solver=cfg.IK_RP_SOLVER, parent=None, **kwargs):
kwargs.update({'endEffector': str(hierarchy.tail), 'solver': solver})
handle, effector = rt.dcc.rigging.ik_handle(str(hierarchy.head), **kwargs)
@classmethod
def build_ik(cls, hierarchy, solver=cfg.IK_RP_SOLVER, sticky=True, parent=None, **kwargs):
kwargs.update({'startJoint': str(hierarchy.head), 'endEffector': str(hierarchy.tail), 'solver': solver})
handle, effector = rt.dcc.rigging.ik_handle(**kwargs)
if parent:
rt.dcc.scene.parent(handle, parent)
handle.stickiness.set(sticky)
return {cfg.NODE_TYPE: [anvil.factory(handle, **kwargs), anvil.factory(effector, **kwargs)]}

def build_blend_chain(self, layout_joints, source_chains, duplicate=True, **kwargs):
Expand Down
35 changes: 23 additions & 12 deletions anvil/sub_rig_templates/biped_foot.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class BipedFoot(SubRigTemplate):
cfg.RIGHT: '_'.join([cfg.LEFT, cfg.RIGHT])},
}

def __init__(self, heel=None, outsole=None, insole=None, has_ik=False, leg_ik=None, *args, **kwargs):
def __init__(self, heel=None, outsole=None, insole=None, has_ik=True, leg_ik=None, *args, **kwargs):
super(BipedFoot, self).__init__(*args, **kwargs)
self.ankle, self.ball, self.toe = self.layout_joints
self.heel = heel
Expand All @@ -46,14 +46,16 @@ def get_control_shape(self, label):

def build(self, duplicate=True, **kwargs):
super(BipedFoot, self).build(**kwargs)
joints = self.layout_joints[0].duplicate(all_children=True)
if duplicate:
self.ankle, self.ball, self.toe = nt.HierarchyChain(self.layout_joints[0].duplicate(all_children=True))

last = self.build_node(nt.Control, '%s_%s' % (cfg.CONTROL_TYPE, self.ANKLE_TOKEN),
shape=self.get_control_shape(self.ANKLE_TOKEN),
reference_object=self.ankle,
parent=self.group_controls,
rotate=False,
name_tokens={cfg.PURPOSE: self.ANKLE_TOKEN})
ankle_control = self.build_node(nt.Control, '%s_%s' % (cfg.CONTROL_TYPE, self.ANKLE_TOKEN),
shape=self.get_control_shape(self.ANKLE_TOKEN),
reference_object=self.ankle,
parent=self.group_controls,
rotate=False,
name_tokens={cfg.PURPOSE: self.ANKLE_TOKEN})
last = ankle_control.connection_group

for reference_object, label in zip([self.heel, self.toe, self.ball],
[self.HEEL_TOKEN, self.TOE_TOKEN, self.BALL_TOKEN]):
Expand All @@ -75,13 +77,22 @@ def build(self, duplicate=True, **kwargs):
self.rename()

def build_ik_toe(self):
toe_ball_chain = nt.HierarchyChain(self.toe, node_filter=cfg.JOINT_TYPE)
result = self.build_ik(toe_ball_chain, solver=cfg.IK_SC_SOLVER, parent=self.group_nodes)
handle, effector = result[cfg.NODE_TYPE]
foot_ball_result = self.build_ik(nt.HierarchyChain(self.ankle, self.ball, node_filter=cfg.JOINT_TYPE),
solver=cfg.IK_SC_SOLVER, parent=self.control_ball.connection_group)
handle, effector = foot_ball_result[cfg.NODE_TYPE]
self.register_node('%s_%s' % (self.name_tokens.name, cfg.IK_HANDLE), handle,
name_tokens={cfg.NAME: self.ANKLE_TOKEN, cfg.TYPE: cfg.IK_HANDLE})
self.register_node('%s_%s' % (self.name_tokens.name, cfg.IK_EFFECTOR), effector,
name_tokens={cfg.NAME: self.ANKLE_TOKEN, cfg.TYPE: cfg.IK_EFFECTOR})

ball_toe_result = self.build_ik(nt.HierarchyChain(self.ball, self.toe, node_filter=cfg.JOINT_TYPE),
solver=cfg.IK_SC_SOLVER, parent=self.control_toe.connection_group)
handle, effector = ball_toe_result[cfg.NODE_TYPE]
self.register_node('%s_%s' % (self.name_tokens.name, cfg.IK_HANDLE), handle,
name_tokens={cfg.NAME: self.BALL_TOKEN, cfg.TYPE: cfg.IK_HANDLE})
self.register_node('%s_%s' % (self.name_tokens.name, cfg.IK_EFFECTOR), effector,
name_tokens={cfg.NAME: self.BALL_TOKEN, cfg.TYPE: cfg.IK_EFFECTOR})

if self.leg_ik:
self.leg_ik.parent(self.ball)

Expand All @@ -91,4 +102,4 @@ def build_fk_toe(self):
name_tokens={cfg.PURPOSE: 'cancel',
cfg.TYPE: cfg.MULT_DIV_TYPE,
'protected': cfg.TYPE})
#md.input1D.connect()
# md.input1D.connect()
4 changes: 2 additions & 2 deletions tests/acceptance/test_biped.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ def from_template_file(cls, template_file, **kwargs):
cfg.RIGHT + '_' + cfg.ARM: {cfg.LAYOUT: nt.HierarchyChain('r_armA_JNT', 'r_armC_JNT')},
cfg.LEFT + '_' + cfg.LEG: {cfg.LAYOUT: nt.HierarchyChain('l_legA_JNT', 'l_legC_JNT')},
cfg.RIGHT + '_' + cfg.LEG: {cfg.LAYOUT: nt.HierarchyChain('r_legA_JNT', 'r_legC_JNT')},
cfg.LEFT + '_' + cfg.FOOT: {cfg.LAYOUT: nt.HierarchyChain('l_legC_JNT', 'l_foot_toeEnd_JNT'),
cfg.LEFT + '_' + cfg.FOOT: {cfg.LAYOUT: nt.HierarchyChain('l_legC_JNT', 'l_foot_toe_JNT'),
'heel': 'l_foot_heel_JNT'},
cfg.RIGHT + '_' + cfg.FOOT: {cfg.LAYOUT: nt.HierarchyChain('r_legC_JNT', 'r_foot_toeEnd_JNT'),
cfg.RIGHT + '_' + cfg.FOOT: {cfg.LAYOUT: nt.HierarchyChain('r_legC_JNT', 'r_foot_toe_JNT'),
'heel': 'r_foot_heel_JNT'},
cfg.SPINE: nt.HierarchyChain('spineA_JNT', 'spineE_JNT'),
cfg.NECK: nt.HierarchyChain('neckA_JNT', 'neckEnd_JNT'),
Expand Down
28 changes: 22 additions & 6 deletions tests/acceptance/test_biped_foot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@
import anvil.node_types as nt
from anvil.sub_rig_templates import BipedFoot
from tests.base_test import TestBase, cleanup_nodes
import anvil.config as cfg


class TestBaseTemplateRigs(TestBase):
name_tokens = {'name': 'eye', 'purpose': 'mvp'}
test_rig = None
TEMPLATE_CLASS = None
TEMPLATE_CLASS = BipedFoot


class TestBuildBipedFoot(TestBaseTemplateRigs):
@classmethod
def from_template_file(cls, template_file, **kwargs):
cls.import_template_files(template_file)
rig_instance = BipedFoot(layout_joints=[nt.Transform(n) for n in ['foot', 'ball', 'toe', 'end']],
heel=nt.Transform('heel'))
def from_template_file(cls, template_file, skip_import=False, **kwargs):
if not skip_import:
cls.import_template_files(template_file)
rig_instance = cls.TEMPLATE_CLASS(layout_joints=[nt.Transform(n) for n in ['foot', 'ball', 'toe']],
heel=nt.Transform('heel'))
rig_instance.build(**kwargs)
return rig_instance

Expand All @@ -29,6 +31,17 @@ def test_build_with_parent(self):
rig_instance = self.from_template_file(self.FOOT, parent=parent)
self.assertEqual(str(rig_instance.root.get_parent()), str(parent))

def test_build_with_leg_ik(self):
with cleanup_nodes():
parent = nt.Transform.build(name='test')
self.import_template_files(self.FOOT_WITH_LEG)
foot_ball_result = self.TEMPLATE_CLASS.build_ik(
nt.HierarchyChain('hip', 'foot', node_filter=cfg.JOINT_TYPE),
solver=cfg.IK_RP_SOLVER)
handle, effector = foot_ball_result[cfg.NODE_TYPE]
rig_instance = self.from_template_file(None, leg_ik=handle, skip_import=True, parent=parent)
self.assertEqual(str(rig_instance.root.get_parent()), str(parent))


class TestBuildBipedFootHierarchy(TestBaseTemplateRigs):
@classmethod
Expand All @@ -40,7 +53,10 @@ def test_number_of_controls(self):
len(list([node for key, node in iteritems(self.rig.hierarchy) if isinstance(node, nt.Control)])), 4)

def test_control_positions_match(self):
components = [BipedFoot.TOE_TOKEN, BipedFoot.BALL_TOKEN, BipedFoot.ANKLE_TOKEN, BipedFoot.HEEL_TOKEN]
components = [self.TEMPLATE_CLASS.TOE_TOKEN,
self.TEMPLATE_CLASS.BALL_TOKEN,
self.TEMPLATE_CLASS.ANKLE_TOKEN,
self.TEMPLATE_CLASS.HEEL_TOKEN]
for component in components:
control = getattr(self.rig, 'control_%s' % component)
joint = getattr(self.rig, component)
Expand Down
Loading

0 comments on commit 9751758

Please sign in to comment.