def from_template_file(cls, template_file): cls.import_template_files(template_file) l_arm = nt.LinearHierarchyNodeSet('l_armA_JNT') r_arm = nt.LinearHierarchyNodeSet('r_armA_JNT') l_sub_rig_instance = cls.runner(template_args=l_arm, template_flags={'meta_data': {'side': 'left'}}) r_sub_rig_instance = cls.runner(template_args=r_arm, template_flags={'meta_data': {'side': 'right'}}) return l_sub_rig_instance, r_sub_rig_instance
def test_with_filter(self): filter = [cfg.JOINT_TYPE, cfg.TRANSFORM_TYPE] chain = nt.LinearHierarchyNodeSet(self.joints_total[0], node_filter=filter) self.assertDictEqual( chain.get_level(8), nt.LinearHierarchyNodeSet(self.joints_total[8], node_filter=filter).get_hierarchy())
def from_template_file(cls, template_file, **kwargs): cls.import_template_files(template_file) sub_rig_dict = { cfg.LEFT + '_' + cfg.ARM: { cfg.LAYOUT: nt.LinearHierarchyNodeSet('l_armA_JNT', 'l_armC_JNT') }, cfg.RIGHT + '_' + cfg.ARM: { cfg.LAYOUT: nt.LinearHierarchyNodeSet('r_armA_JNT', 'r_armC_JNT') }, cfg.LEFT + '_' + cfg.LEG: { cfg.LAYOUT: nt.LinearHierarchyNodeSet('l_legA_JNT', 'l_legC_JNT') }, cfg.RIGHT + '_' + cfg.LEG: { cfg.LAYOUT: nt.LinearHierarchyNodeSet('r_legA_JNT', 'r_legC_JNT') }, cfg.LEFT + '_' + cfg.FOOT: { cfg.LAYOUT: nt.LinearHierarchyNodeSet('l_legC_JNT', 'l_foot_toe_JNT'), 'heel': 'l_foot_heel_JNT' }, cfg.RIGHT + '_' + cfg.FOOT: { cfg.LAYOUT: nt.LinearHierarchyNodeSet('r_legC_JNT', 'r_foot_toe_JNT'), 'heel': 'r_foot_heel_JNT' }, cfg.SPINE: nt.LinearHierarchyNodeSet('spineA_JNT', 'spineE_JNT'), cfg.NECK: nt.LinearHierarchyNodeSet('neckA_JNT', 'neckEnd_JNT'), cfg.HEAD: nt.LinearHierarchyNodeSet('headA_JNT', 'headEnd_JNT'), } finger_start = '%s_finger_%s_A_JNT' finger_end = '%s_finger_%s_D_JNT' for side in [cfg.LEFT, cfg.RIGHT]: fingers = [] for finger in ['thb', 'ind', 'mid', 'rng', 'pnk']: fingers.append( nt.LinearHierarchyNodeSet(finger_start % (side[0], finger), finger_end % (side[0], finger))) sub_rig_dict[side + '_' + cfg.HAND] = { 'finger_joints': fingers, 'scale': 0.3 } rig_instance = cls.CLASS(sub_rig_dict=sub_rig_dict, name_tokens={cfg.CHARACTER: 'hombre'}, **kwargs) rig_instance.build(**kwargs) return rig_instance
def test_pynode_input(self): import pymel.core as pm nodes = [pm.createNode('joint')] nodes.append(pm.createNode('joint', parent=nodes[0])) self.checkEqual( [str(f) for f in list(nt.LinearHierarchyNodeSet(nodes[0]))], [str(f) for f in list(nodes)])
def build_blend_chain(self, layout_joints, source_chains, blend_attr=None, parent=None, duplicate=True, **kwargs): """ :param layout_joints: list, list of joints to use as the main joints in the set. :param source_chains: list, list of chains to use as the source input rotation chains - length can only be up to 2 due to blend node limitations :param blend_attr: anvil.objects.attribute.Attribute, attribute to use as the blender for the ik/fk blend. :param parent: list or object: list of up to length 1, [blend chain parent] :param duplicate: bool, whether or not to duplicate the layout joints chain :return: (NonLinearHierarchyNodeSet(Control), LinearHierarchyNodeSet(Joint)) """ blend_chain = nt.LinearHierarchyNodeSet(layout_joints[0], duplicate=duplicate, parent=parent, **kwargs) blend_nodes = [] for blend_chain_joint, source_chain_joints in zip( blend_chain, zip(*to_list(source_chains))): blend_nodes.append(rt.dcc.create.create_node(cfg.BLEND_NODE)) blend_nodes[-1].output.connect(blend_chain_joint.rotate) if blend_attr: blend_attr.connect(blend_nodes[-1].blender) for index, source_chain_joint in enumerate(source_chain_joints): source_chain_joint.rotate.connect(blend_nodes[-1].attr( 'color%d' % (index + 1))) return blend_chain
def build_leg_ik(): foot_ball_result = TestBuildBipedFoot.TEMPLATE().build_ik( nt.LinearHierarchyNodeSet('hip', 'foot', node_filter=cfg.JOINT_TYPE), solver=cfg.IK_RP_SOLVER) return {'leg_ik': foot_ball_result[cfg.NODE_TYPE][cfg.DEFAULT]}
def test_duplicate(self): self.assertEqual( len( list( nt.LinearHierarchyNodeSet(self.joints_total[0], self.joints_total[-3], duplicate=True))), len(self.joints_total) - 2)
def test_duplicate_no_end_specified(self): self.assertEqual( len( nt.LinearHierarchyNodeSet( self.joints_total[0], duplicate=True, node_filter=[cfg.JOINT_TYPE, cfg.TRANSFORM_TYPE])), len(self.joints_total))
def build_ik_chain(self, layout_joints, ik_end_index=-1, solver=cfg.IK_RP_SOLVER, parent=None, duplicate=True, **kwargs): """ :param parent: list or object: list of up to length 4: [ik chain parent, handle parent, pv control parent, [3 pole vector control parents]] :return: (NonLinearHierarchyNodeSet(Control), LinearHierarchyNodeSet(Joint)) """ parent = list(reversed(to_size_list(parent, 3))) kwargs[cfg.SKIP_REGISTER] = True kwargs[cfg.SKIP_REPORT] = True ik_chain = nt.LinearHierarchyNodeSet(layout_joints, duplicate=duplicate, parent=parent.pop(), **kwargs) handle, effector = self.build_ik(ik_chain, chain_end=ik_chain[ik_end_index], parent=parent.pop(), name_tokens=MetaData( {cfg.NAME: cfg.IK}, kwargs.pop(cfg.NAME_TOKENS, {})), **kwargs) controls = nt.NonLinearHierarchyNodeSet() # build ik control controls.append( nt.Control.build(**MetaData( kwargs, { cfg.PARENT: parent.pop(), cfg.REFERENCE_OBJECT: ik_chain[-1], cfg.SHAPE: cfg.DEFAULT_IK_SHAPE, cfg.NAME_TOKENS: { cfg.PURPOSE: cfg.IK } }).to_dict())) # build pole vector control if using RP solver. if solver == cfg.IK_RP_SOLVER: pv_control = self.build_pole_vector_control( ik_chain, handle, **MetaData( kwargs, { cfg.SHAPE: cfg.DEFAULT_PV_SHAPE, cfg.NAME_TOKENS: { cfg.PURPOSE: cfg.POLE_VECTOR } })) controls.append(pv_control) rt.dcc.connections.translate(controls[0].connection_group, handle) return ik_chain, controls, handle, effector
def build_dependencies(cls): cls.sub_rig = base_sub_rig_template.SubRigTemplate() cls.sub_rig.build() b = nt.Joint.build() c = nt.Joint.build() d = nt.Joint.build() c.translate_node([0, 2.5, 0]) d.translate_node([0, 5, 0]) cls.joint_chain = nt.LinearHierarchyNodeSet(b, d) result = cls.sub_rig.build_ik(cls.joint_chain) cls.handle, cls.effector = result[cfg.NODE_TYPE][cfg.DEFAULT]
def from_template_file(cls, template_file, finger_start_joints=None, **kwargs): cls.import_template_files(template_file) finger_joints = [] for finger in finger_start_joints: finger_joints.append(list(nt.LinearHierarchyNodeSet(finger))) rig_instance = cls.TEMPLATE_CLASS(layout_joints=finger_joints, **kwargs) rig_instance.build(**kwargs) return rig_instance
def build_fk_chain(self, chain_start=None, chain_end=None, shape=None, duplicate=True, parent=None, name_tokens=None, meta_data=None, **kwargs): """ :param parent: list or object: list of up to length 2, [fk chain parent, control chain parent] :return: (NonLinearHierarchyNodeSet(Control), LinearHierarchyNodeSet(Joint)) """ parent = to_size_list(parent, 2) name_tokens = MetaData(self.name_tokens, name_tokens) if hasattr( self, cfg.NAME_TOKENS) else name_tokens meta_data = MetaData(self.meta_data, meta_data) if hasattr( self, cfg.META_DATA) else meta_data kwargs['skip_register'] = True kwargs['skip_report'] = True fk_chain = nt.LinearHierarchyNodeSet(chain_start, chain_end, duplicate=duplicate, parent=parent.pop()) fk_controls = nt.NonLinearHierarchyNodeSet() control_parent = parent.pop() for node, shape in zip( fk_chain, to_size_list(shape or self.DEFAULT_FK_SHAPE, len(fk_chain))): control = self.build_node(nt.Control, reference_object=node, shape=shape, parent=control_parent, name_tokens=name_tokens, meta_data=meta_data, **kwargs) control.parent(control_parent) control_parent = control.node.connection_group rt.dcc.connections.parent(control_parent, node, maintainOffset=True) fk_controls.append(control) return fk_chain, fk_controls
def test_first_member(self): chain = nt.LinearHierarchyNodeSet(self.joints[0]) self.assertEquals(chain[0], self.joints[0])
def test_str_input(self): import maya.cmds as mc nodes = [mc.createNode('joint')] nodes.append(mc.createNode('joint', parent=nodes[0])) self.checkEqual( [str(f) for f in list(nt.LinearHierarchyNodeSet(nodes[0]))], nodes)
def test_anvil_input(self): nodes = [nt.Joint.build()] nodes.append(nt.Joint.build(parent=nodes[0])) self.checkEqual( [str(f) for f in list(nt.LinearHierarchyNodeSet(str(nodes[0])))], [str(f) for f in list(nodes)])
def test_invalid_index(self): chain = nt.LinearHierarchyNodeSet(self.joints[0]) with self.assertRaises(IndexError) as exception_context_manager: f = chain[40] exception = exception_context_manager.exception
def test_negative_indexing(self): chain = nt.LinearHierarchyNodeSet(self.joints[0]) self.assertEquals(chain[-1], self.joints[-1])
def test_joints_only(self): chain = nt.LinearHierarchyNodeSet(self.joints[0]) self.assertEqual(chain.depth(), len(self.joints) - 1)
def test_all_members(self): chain = nt.LinearHierarchyNodeSet(self.joints[0]) self.checkEqual(chain, self.joints)
def test_full_list(self): nt.LinearHierarchyNodeSet(self.joints[0])
def test_only_joints(self): nt.LinearHierarchyNodeSet(self.joints[0])
def test_joints_mixed(self): chain = nt.LinearHierarchyNodeSet(self.joints_mixed[0]) self.assertDictEqual( chain.get_level(4), nt.LinearHierarchyNodeSet(self.joints_mixed[4]).get_hierarchy())
def test_specified_end_node(self): chain = nt.LinearHierarchyNodeSet(self.joints_total[0], self.joints_second[-1]) self.checkEqual(chain, self.joints_second)
def test_joints_only(self): chain = nt.LinearHierarchyNodeSet(self.joints[0]) self.assertEqual( chain.get_level(4), nt.LinearHierarchyNodeSet(self.joints[4]).get_hierarchy())
def test_specified_end_node_with_node_filter(self): chain = nt.LinearHierarchyNodeSet(self.joints_mixed[0], self.joints_total[-3], node_filter=cfg.JOINT_TYPE) self.checkEqual(chain, self.joints)
def test_joints_mixed(self): chain = nt.LinearHierarchyNodeSet(self.joints_mixed[0]) self.assertEqual(chain.depth(), len(self.joints_total) - 1)
def test_with_filter(self): chain = nt.LinearHierarchyNodeSet( self.joints_mixed[0], node_filter=[cfg.JOINT_TYPE, cfg.TRANSFORM_TYPE]) self.assertEqual(chain.get_hierarchy(as_list=True), self.joints_total)
def test_mixed_joints_and_transforms(self): nt.LinearHierarchyNodeSet(self.joints_mixed[0])
def test_with_filter(self): chain = nt.LinearHierarchyNodeSet( self.joints_mixed[0], node_filter=[cfg.JOINT_TYPE, cfg.TRANSFORM_TYPE]) self.assertEqual(chain.depth(), len(self.joints_total) - 1)
def test_specified_end_node_with_node_filter_all(self): chain = nt.LinearHierarchyNodeSet( self.joints_mixed[0], self.joints_total[-3], node_filter=[cfg.JOINT_TYPE, cfg.TRANSFORM_TYPE]) self.checkEqual(chain, self.joints_total[:-3])