Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    def build_pole_vector_control(self,
                                  joints,
                                  ik_handle,
                                  parent=None,
                                  up_vector=None,
                                  aim_vector=None,
                                  up_object=None,
                                  move_by=None,
                                  meta_data=None,
                                  name_tokens=None,
                                  **kwargs):
        """ Builds a pole vector control based on positions of joints and existing ik handle.
            Runs as follows:
                - Point constraint to the two base positions, aim constrain to the other objects
                - Delete constraints then move the control outside of the reference transforms in the aim direction.

        :param parent: list or object: list of up to length 3, [control parent, clusters parent, pv line parent]
        :param joints: LinearHierarchyNodeSet(Joint), linear hierarchy set of joints.
        :param ik_handle: DagNode, ik handle node
        :param kwargs: dict, build kwargs for the control build call
        :return: (Control, DagNode, NonLinearHierarchyNodeSet(DagNode))
        """
        parent = list(reversed(to_size_list(parent, 3)))

        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.update({
            cfg.NAME_TOKENS: name_tokens,
            cfg.META_DATA: meta_data,
            'move_by': move_by,
            'parent': parent.pop(),
            'up_vector': up_vector,
            'aim_vector': aim_vector,
            'up_object': up_object
        })

        control = nt.Control.build_pole_vector(joints, ik_handle, **kwargs)
        pv_line, clusters = nt.Curve.build_line_indicator(
            joints[len(joints) // 2], control.controller, **kwargs)

        cluster_parent = parent.pop()
        for cluster in clusters:
            cluster.visibility.set(False)
            cluster.parent(cluster_parent)

        pv_line.parent(parent.pop())

        return control, pv_line, nt.NonLinearHierarchyNodeSet(clusters)
Ejemplo n.º 5
0
    def wrapper(abstract_grouping, *args, **kwargs):
        """ Creates a dictionary of created nodes that will be digested later by the node registration function.

        :param args: object, node to sort into the hierarchy, SHOULD be an Anvil node.
        :param kwargs: dict, use kwargs if you want to override the types.
                             By default accepts any key from abstract_grouping.BUILD_REPORT_KEYS
        :return:

        A build report looks like this:

        {'control': {'default': [anvil_controls_or_set_of_controls, ...]},
         'node': {'default': [anvil_nodes_or_set_of_nodes, ...],
                  'user custom hierarchy id': node}},
         'set': {'default': None},
         'joint': {'default': None},

        A top level key will not be present if the result nodes from the wrapped function are not of that type.
        The top level key possibilities are: ['control', 'joint', 'node', 'set']
        """
        skip_report = kwargs.pop('skip_report', False)
        custom_hierarchy_ids = kwargs.pop(cfg.ID_TYPE, None)
        nodes_built = f(abstract_grouping, *args, **kwargs)

        if skip_report:
            return nodes_built

        result = {}
        nodes_built = to_list(nodes_built)
        for node, hierarchy_id in zip(nodes_built, to_size_list(custom_hierarchy_ids, len(nodes_built))):
            tag = getattr(node, cfg.ANVIL_TYPE, cfg.NODE_TYPE)
            if hierarchy_id:
                # We are assuming the extra tag is unique and we can just do a plain update instead of checking.
                result.update({tag: {hierarchy_id: node}})
            else:
                result[tag] = result.get(tag, {cfg.DEFAULT: []})
                result[tag][cfg.DEFAULT].append(node)
        return result
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    def build_pole_vector_control(self, joints, ik_handle, parent=None, up_vector=None, aim_vector=None,
                                  up_object=None, move_by=None, meta_data=None, name_tokens=None, **kwargs):
        """ Builds a pole vector control based on positions of joints and existing ik handle.
            Runs as follows:
                - Point constraint to the two base positions, aim constrain to the other objects
                - Delete constraints then move the control outside of the reference transforms in the aim direction.

        :param parent: list or object: list of up to length 3, [control parent, clusters parent, pv line parent]
        :param joints: LinearHierarchyNodeSet(Joint), linear hierarchy set of joints.
        :param ik_handle: DagNode, ik handle node
        :param kwargs: dict, build kwargs for the control build call
        :return: (Control, DagNode, NonLinearHierarchyNodeSet(DagNode))
        """
        parent = list(reversed(to_size_list(parent, 3)))

        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.update({cfg.NAME_TOKENS: name_tokens,
                       cfg.META_DATA: meta_data,
                       'move_by': move_by,
                       'parent': parent.pop(),
                       'up_vector': up_vector,
                       'aim_vector': aim_vector,
                       'up_object': up_object})

        control = nt.Control.build_pole_vector(joints, ik_handle, **kwargs)
        pv_line, clusters = nt.Curve.build_line_indicator(joints[len(joints) // 2], control.controller, **kwargs)

        cluster_parent = parent.pop()
        for cluster in clusters:
            cluster.visibility.set(False)
            cluster.parent(cluster_parent)

        pv_line.parent(parent.pop())

        return control, pv_line, nt.NonLinearHierarchyNodeSet(clusters)
Ejemplo n.º 8
0
 def __init__(self, heel=None, outsole=None, insole=None, *args, **kwargs):
     super(BipedFoot, self).__init__(*args, **kwargs)
     self.ankle, self.ball, self.toe = to_size_list(self.layout_joints, 3)
     self.heel = heel
     self.outsole = outsole
     self.insole = insole
Ejemplo n.º 9
0
 def test_kwarg_shape_input(self):
     self.assertEqual(generic.to_size_list('pyramid', 6), ['pyramid'] * 6)
Ejemplo n.º 10
0
 def test_over_length_shape_list(self):
     input = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
     self.assertEqual(generic.to_size_list(input, 5), input[:5])
Ejemplo n.º 11
0
 def test_short_shape_list_by_one(self):
     input = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
     self.assertEqual(generic.to_size_list(input, 9),
                      ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'h'])
Ejemplo n.º 12
0
 def test_short_shape_list(self):
     input = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
     self.assertEqual(generic.to_size_list(input, 14),
                      ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] + ['h'] * 6)
Ejemplo n.º 13
0
 def test_input_shape_list(self):
     input = ['f', 'g', 'h', 'i']
     self.assertEqual(generic.to_size_list(input, 4), input)