Пример #1
0
    def apply(self):
        form = self.getSubForm()
        children_nodes = form.getChildrenNodes()
        parent_node = form.getParentNode()
        LOG.debug('children_nodes: %r', children_nodes)
        LOG.debug('parent_node: %r', parent_node)

        # Store transform nodes (to be restored after tool is run).
        children_tfm_nodes = [
            tfm_utils.TransformNode(node=n) for n in children_nodes
        ]
        if parent_node is not None:
            parent_tfm_node = tfm_utils.TransformNode(node=parent_node)

        # Ensure we have enough nodes.
        msg = ''
        if parent_node is None:
            msg = 'Not enough nodes, choose at least 1 node.'
        else:
            msg = ('Not enough children nodes, '
                   'choose at least 1 child node.')
        if len(children_nodes) == 0:
            LOG.error(msg)
            return
        tool.reparent(children_nodes, parent_node)

        # Update children and parent nodes after reparent
        # process. Updates the UI.
        children_nodes = [tn.get_node() for tn in children_tfm_nodes]
        form.setChildrenNodes(children_nodes)
        if parent_node is None:
            form.setParentNode([])
        else:
            form.setParentNode([parent_tfm_node.get_node()])
        return
Пример #2
0
    def create_scene_b(self):
        """
        Three transforms, 2 children under 1 parent.
        No keyframes.

        - A
          - B
          - C
        """
        tfm_a = maya.cmds.createNode('transform')
        maya.cmds.setAttr(tfm_a + '.translateX', 10.0)
        maya.cmds.setAttr(tfm_a + '.translateY', 20.0)
        maya.cmds.setAttr(tfm_a + '.translateZ', 30.0)
        tfm_node_a = tfm_utils.TransformNode(node=tfm_a)

        tfm_b = maya.cmds.createNode('transform', parent=tfm_a)
        maya.cmds.setAttr(tfm_b + '.translateX', -10.0)
        maya.cmds.setAttr(tfm_b + '.translateY', -20.0)
        maya.cmds.setAttr(tfm_b + '.translateZ', -30.0)
        tfm_node_b = tfm_utils.TransformNode(node=tfm_b)

        tfm_c = maya.cmds.createNode('transform', parent=tfm_a)
        maya.cmds.setAttr(tfm_b + '.translateX', -12.0)
        maya.cmds.setAttr(tfm_b + '.translateY', -22.0)
        maya.cmds.setAttr(tfm_b + '.translateZ', -32.0)
        tfm_node_c = tfm_utils.TransformNode(node=tfm_c)
        return tfm_node_a, tfm_node_b, tfm_node_c
Пример #3
0
def reparent_under_node():
    """
    Re-parent the selection under the last selected node.
    """
    frame = maya.cmds.currentTime(query=True)
    nodes = maya.cmds.ls(selection=True, long=True, type='transform') or []

    if len(nodes) < 2:
        msg = ('Not enough objects selected, '
               'select at least 1 child and 1 parent node.')
        LOG.warn(msg)
        return
    with tools_utils.tool_context(disable_viewport=True,
                                  use_undo_chunk=False,
                                  use_dg_evaluation_mode=False,
                                  restore_current_frame=False,
                                  pre_update_frame=False):
        children = nodes[:-1]
        parent = nodes[-1]
        children_tfm_nodes = [
            tfm_utils.TransformNode(node=n) for n in children
        ]
        parent_tfm_node = tfm_utils.TransformNode(node=parent)
        lib.reparent(children_tfm_nodes, parent_tfm_node, sparse=True)
        children = [tn.get_node() for tn in children_tfm_nodes]
        maya.cmds.select(children, replace=True)

    # Trigger Maya to refresh.
    maya.cmds.currentTime(frame, update=True)
    maya.cmds.refresh(currentView=True, force=False)
    return
Пример #4
0
def parent(src_nodes, dst_node, current_frame=None, eval_mode=None):
    """
    Parent nodes under a new parent node.

    :param src_nodes: List of nodes to reparent.
    :type src_nodes: [str, ..]

    :param dst_node: The new parent node for the given source nodes.
    :type dst_node: str

    :param current_frame: What frame number is considered to be
                          'current' when evaluating transforms without
                          any keyframes.
    :type current_frame: float or int

    :param eval_mode: What type of transform evaluation method to use?
    :type eval_mode: mmSolver.utils.constant.EVAL_MODE_*

    """
    assert len(src_nodes) > 0
    assert len(dst_node) > 0
    if current_frame is None:
        current_frame = maya.cmds.currentTime(query=True)
    assert current_frame is not None

    src_tfm_nodes = [tfm_utils.TransformNode(node=n) for n in src_nodes]
    tfm_dst_node = tfm_utils.TransformNode(node=dst_node)

    # Query keyframe times on each node attribute
    key_times_map = time_utils.get_keyframe_times_for_node_attrs(
        src_nodes, const.TFM_ATTRS)

    # Create Transform Cache, add and process cache.
    times = []
    cache = tfm_utils.TransformMatrixCache()
    for src_tfm_node in src_tfm_nodes:
        src_node = src_tfm_node.get_node()
        times = key_times_map.get(src_node, [current_frame])
        cache.add_node(src_tfm_node, times)
    cache.process(eval_mode=eval_mode)

    # Re-parent the nodes.
    dst_node = tfm_dst_node.get_node()
    src_nodes = [tfm_node.get_node() for tfm_node in src_tfm_nodes]
    maya.cmds.parent(src_nodes, dst_node, relative=True)

    # Set transforms for all source nodes.
    # anim_curves = []
    for src_tfm_node in src_tfm_nodes:
        src_node = src_tfm_node.get_node()
        src_times = key_times_map.get(src_node, [current_frame])
        assert len(src_times) > 0
        tfm_utils.set_transform_values(cache,
                                       src_times,
                                       src_tfm_node,
                                       src_tfm_node,
                                       delete_static_anim_curves=False)

    src_nodes = [tfm_node.get_node() for tfm_node in src_tfm_nodes]
    return src_nodes
Пример #5
0
def reparent_under_node():
    """
    Re-parent the selection under the last selected node.
    """
    frame = maya.cmds.currentTime(query=True)
    nodes = maya.cmds.ls(selection=True, long=True,
                         type='transform') or []
    if len(nodes) < 2:
        msg = ('Not enough objects selected, '
               'select at least 1 child and 1 parent node.')
        LOG.warn(msg)
        return
    try:
        viewport.viewport_turn_off()
        children = nodes[:-1]
        parent = nodes[-1]
        children_tfm_nodes = [tfm_utils.TransformNode(node=n) for n in children]
        parent_tfm_node = tfm_utils.TransformNode(node=parent)
        lib.reparent(children_tfm_nodes, parent_tfm_node, sparse=True)
        children = [tn.get_node() for tn in children_tfm_nodes]
        maya.cmds.select(children, replace=True)
    finally:
        viewport.viewport_turn_on()
    # Trigger Maya to refresh.
    maya.cmds.currentTime(frame, update=True)
    maya.cmds.refresh(currentView=True, force=False)
    return
Пример #6
0
    def test_set_transform_values(self):
        """
        """
        start_frame = 1001
        end_frame = 1101
        node = maya.cmds.createNode('transform')
        maya.cmds.setKeyframe(node, attribute='translateX', time=start_frame, value=-100.0)
        maya.cmds.setKeyframe(node, attribute='translateX', time=end_frame, value=100.0)
        maya.cmds.setKeyframe(node, attribute='translateY', time=start_frame, value=-10.0)
        maya.cmds.setKeyframe(node, attribute='translateY', time=end_frame, value=10.0)
        maya.cmds.setKeyframe(node, attribute='rotateY', time=start_frame, value=90.0)
        maya.cmds.setKeyframe(node, attribute='rotateY', time=end_frame, value=-90.0)
        frame_range = list(range(start_frame, end_frame + 1))

        tfm_node = mod.TransformNode(node=node)

        tfm_cache = mod.TransformMatrixCache()
        tfm_cache.add_node_attr(tfm_node, 'worldMatrix[0]', frame_range)
        tfm_cache.process()

        dst_node = maya.cmds.createNode('transform')
        dst_tfm_node = mod.TransformNode(node=dst_node)

        mod.set_transform_values(tfm_cache, frame_range,
            tfm_node, dst_tfm_node,
            delete_static_anim_curves=True,
        )

        # save the output scene file
        path = 'test_transform.ma'
        path = self.get_data_path(path)
        maya.cmds.file(rename=path)
        maya.cmds.file(save=True, type='mayaAscii', force=True)
        return
Пример #7
0
 def test_TransformNode_usage(self):
     start_frame = 1001
     end_frame = 1101
     times = list(range(start_frame, end_frame))
     maya_node = maya.cmds.createNode('transform', name='myNode')
     tfm_node = mod.TransformNode(node=maya_node)
     node = tfm_node.get_node()
     node_uuid = tfm_node.get_node_uuid()
     tfm_node_parents = tfm_node.get_parents()
     tfm_node_b = mod.TransformNode()
     tfm_node_b.set_node('myNode')
     return
Пример #8
0
def unparent_to_world():
    """
    Un-parent the selected nodes into world space.
    """
    frame = maya.cmds.currentTime(query=True)
    nodes = maya.cmds.ls(selection=True, long=True, type='transform') or []

    if len(nodes) == 0:
        msg = ('Not enough objects selected, '
               'select at least 1 transform node.')
        LOG.warn(msg)
        return
    with tools_utils.tool_context(disable_viewport=True,
                                  use_undo_chunk=True,
                                  use_dg_evaluation_mode=False,
                                  restore_current_frame=False,
                                  pre_update_frame=False):
        tfm_nodes = [tfm_utils.TransformNode(node=n) for n in nodes]
        lib.reparent(tfm_nodes, None, sparse=True)
        nodes = [tn.get_node() for tn in tfm_nodes]
        maya.cmds.select(nodes, replace=True)

    # Trigger Maya to refresh.
    maya.cmds.currentTime(frame, update=True)
    maya.cmds.refresh(currentView=True, force=False)
    return
Пример #9
0
    def test_reparent_unparent_with_sparse_keyframes(self):
        name = 'reparent_sparse_keyframes.ma'
        path = self.get_data_path('scenes', name)
        maya.cmds.file(path, open=True, force=True)

        tfm_a = 'pSphere1'
        tfm_b = 'pCube1'
        tfm_node_a = tfm_utils.TransformNode(node=tfm_a)
        tfm_node_b = tfm_utils.TransformNode(node=tfm_b)

        # Parent sphere under cube.
        tfm_nodes = lib.reparent([tfm_node_a],
                                 tfm_node_b,
                                 sparse=True,
                                 delete_static_anim_curves=True)
        tfm_node_c = tfm_nodes[0]

        node = tfm_node_c.get_node()
        plug = node + '.translateX'
        times = maya.cmds.keyframe(plug, query=True, timeChange=True)
        self.assertEqual(len(times), 5)
        self.assertEqual(sorted(times), sorted([1, 16, 61, 98, 120]))
        self.assertEqual(len(tfm_nodes), 1)
        new_parent = tfm_node_a.get_parent()
        self.assertEqual(new_parent, tfm_node_b)

        # Unparent sphere to world
        tfm_nodes = lib.reparent([tfm_node_c],
                                 None,
                                 sparse=True,
                                 delete_static_anim_curves=True)
        tfm_node_d = tfm_nodes[0]

        # save the output
        name = 'reparent_unparent_sparse_with_keyframes_after.ma'
        path = self.get_data_path(name)
        maya.cmds.file(rename=path)
        maya.cmds.file(save=True, type='mayaAscii', force=True)

        node = tfm_node_d.get_node()
        plug = node + '.translateX'
        times = maya.cmds.keyframe(plug, query=True, timeChange=True)
        self.assertEqual(len(times), 5)
        self.assertEqual(sorted(times), sorted([1, 16, 61, 98, 120]))
        self.assertEqual(len(tfm_nodes), 1)
        new_parent = tfm_node_a.get_parent()
        self.assertIs(new_parent, None)
Пример #10
0
 def test_TransformMatrixCache_init(self):
     start_frame = 1001
     end_frame = 1101
     times = list(range(start_frame, end_frame))
     node = maya.cmds.createNode('transform')
     tfm_node = mod.TransformNode(node=node)
     tfm_matrix_cache = mod.TransformMatrixCache()
     return
Пример #11
0
    def create_scene_a(self):
        """
        Simple scene, two transforms, both without any keyframes.

        - A
        - B
        """
        tfm_a = maya.cmds.createNode('transform')
        maya.cmds.setAttr(tfm_a + '.translateX', 10.0)
        maya.cmds.setAttr(tfm_a + '.translateY', 20.0)
        maya.cmds.setAttr(tfm_a + '.translateZ', 30.0)
        tfm_node_a = tfm_utils.TransformNode(node=tfm_a)

        tfm_b = maya.cmds.createNode('transform')
        maya.cmds.setAttr(tfm_b + '.translateX', -10.0)
        maya.cmds.setAttr(tfm_b + '.translateY', -20.0)
        maya.cmds.setAttr(tfm_b + '.translateZ', -30.0)
        tfm_node_b = tfm_utils.TransformNode(node=tfm_b)
        return tfm_node_a, tfm_node_b
Пример #12
0
def reparent_under_node():
    """
    Re-parent the selection under the last selected node.
    """
    nodes = maya.cmds.ls(selection=True, long=True, type='transform') or []
    if len(nodes) < 2:
        msg = ('Not enough objects selected, '
               'select at least 1 child and 1 parent node.')
        LOG.warn(msg)
        return
    children = nodes[:-1]
    parent = nodes[-1]
    children_tfm_nodes = [tfm_utils.TransformNode(node=n) for n in children]
    parent_tfm_node = tfm_utils.TransformNode(node=parent)
    lib.reparent(children_tfm_nodes, parent_tfm_node, sparse=True)
    children = [tn.get_node() for tn in children_tfm_nodes]
    maya.cmds.select(children, replace=True)
    __refresh_maya()
    return
Пример #13
0
 def test_TransformMatrixCache_usage(self):
     start_frame = 1001
     end_frame = 1101
     times = list(range(start_frame, end_frame))
     node = maya.cmds.createNode('transform')
     tfm_node = mod.TransformNode(node=node)
     tfm_matrix_cache = mod.TransformMatrixCache()
     tfm_matrix_cache.add_node(tfm_node, times)
     tfm_matrix_cache.process()
     attr_name = 'translateX'
     tfm_matrix_cache.get_node_attr_matrix(tfm_node, attr_name, times)
     return
    def test_detect_rotate_pivot_non_zero(self):
        start_frame = 1001
        end_frame = 1101
        tfm_node = maya.cmds.createNode('transform')
        tfm = mod.TransformNode(tfm_node)
        self.assertFalse(mod.detect_rotate_pivot_non_zero(tfm))

        path = self.get_data_path('scenes', 'bookHierarchy.ma')
        maya.cmds.file(path, open=True, force=True)

        book_node = 'book_GRP'
        spine_node = 'spine_GRP'
        cover_node = 'front_cover_GRP'
        book_tfm = mod.TransformNode(book_node)
        spine_tfm = mod.TransformNode(spine_node)
        cover_tfm = mod.TransformNode(cover_node)

        self.assertFalse(mod.detect_rotate_pivot_non_zero(book_tfm))
        self.assertTrue(mod.detect_rotate_pivot_non_zero(spine_tfm))
        self.assertTrue(mod.detect_rotate_pivot_non_zero(cover_tfm))
        return
Пример #15
0
def unparent_to_world():
    """
    Un-parent the selected nodes into world space.
    """
    nodes = maya.cmds.ls(selection=True, long=True, type='transform') or []
    if len(nodes) == 0:
        msg = ('Not enough objects selected, '
               'select at least 1 transform node.')
        LOG.warn(msg)
        return
    tfm_nodes = [tfm_utils.TransformNode(node=n) for n in nodes]
    lib.reparent(tfm_nodes, None, sparse=True)
    nodes = [tn.get_node() for tn in tfm_nodes]
    maya.cmds.select(nodes, replace=True)
    __refresh_maya()
    return
Пример #16
0
def unparent_to_world():
    """
    Un-parent the selected nodes into world space.
    """
    frame = maya.cmds.currentTime(query=True)
    nodes = maya.cmds.ls(selection=True, long=True,
                         type='transform') or []
    if len(nodes) == 0:
        msg = ('Not enough objects selected, '
               'select at least 1 transform node.')
        LOG.warn(msg)
        return
    try:
        viewport.viewport_turn_off()
        tfm_nodes = [tfm_utils.TransformNode(node=n) for n in nodes]
        lib.reparent(tfm_nodes, None, sparse=True)
        nodes = [tn.get_node() for tn in tfm_nodes]
        maya.cmds.select(nodes, replace=True)
    finally:
        viewport.viewport_turn_on()
    # Trigger Maya to refresh.
    maya.cmds.currentTime(frame, update=True)
    maya.cmds.refresh(currentView=True, force=False)
    return
Пример #17
0
    def create_scene_d(self, start, end):
        """
        Three transforms, 2 transforms parented 1 parent.
        With keyframes.

        - A
          - B
          - C
        """
        tfm_a = maya.cmds.createNode('transform')
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateX',
                              value=10.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateY',
                              value=20.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateZ',
                              value=30.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateX',
                              value=-10.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateY',
                              value=-20.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateZ',
                              value=-30.0,
                              time=end)
        tfm_node_a = tfm_utils.TransformNode(node=tfm_a)

        tfm_b = maya.cmds.createNode('transform', parent=tfm_a)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateX',
                              value=30.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateY',
                              value=20.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateZ',
                              value=10.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateX',
                              value=-30.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateY',
                              value=-20.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateZ',
                              value=-10.0,
                              time=end)
        tfm_node_b = tfm_utils.TransformNode(node=tfm_b)

        tfm_c = maya.cmds.createNode('transform', parent=tfm_a)
        maya.cmds.setKeyframe(tfm_c,
                              attribute='translateX',
                              value=-32.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_c,
                              attribute='translateY',
                              value=-22.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_c,
                              attribute='translateZ',
                              value=-12.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_c,
                              attribute='translateX',
                              value=32.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_c,
                              attribute='translateY',
                              value=22.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_c,
                              attribute='translateZ',
                              value=12.0,
                              time=end)
        tfm_node_c = tfm_utils.TransformNode(node=tfm_c)
        return tfm_node_a, tfm_node_b, tfm_node_c
Пример #18
0
def create_camera_body_track_scale_rig(name,
                              camera,
                              scene,
                              body_track_controls,
                              scale_rig_type):
    """
    Create a camera track scale rig.
    
    :param name: Scale rig name.
    :type name: str   
    
    :param camera: Camera node.
    :type camera: Transform node
    
    :param scene: Scene node.
    :type scene: Transform node or None   
    
    :param body_track_controls: Body track controls transforms.
    :type body_track_controls: Transforms list or [] 
    
    :param scale_rig_type: Which type of scale rig to be created?
        mmSolver.tools.camerabodytrackscalerigbake.constant.SCALE_RIG_LIST.
    :type: str 
    
    :rtype: [str]       
    """
    
    # Create camera witness
    attrs = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz']
    controller_type = createcontroller2_const.CONTROLLER_TYPE_WORLD_SPACE
    if scale_rig_type == const.SCALE_RIG_TYPE_BODY_TRACK:     
        camera_witness = _create_scale_rig_main_grp(name+suffix+main_grp_suffix,
                                                    str(scene),
                                                    body_track_controls,
                                                    const.SCALE_RIG_TYPE_BODY_TRACK)
    if scale_rig_type == const.SCALE_RIG_TYPE_CAMERA_TRACK: 
        camera_witness = cmds.group(name=name+suffix, empty=True)    
    
    parent_con = cmds.parentConstraint(camera, camera_witness, maintainOffset=False)
    camera_witness = cmds.ls(camera_witness)
    fastbake_lib.bake_attributes(camera_witness, attrs, frame_start, frame_end,
                                                              smart_bake=False)
    cmds.delete(parent_con)
    
    # Create rig controls witness
    body_track_controls_witness = []
    for control in body_track_controls:
        control_witness = createcontroller2_lib.create_controller(name,
                                                control,
                                                control,
                                                cmds.spaceLocator(),
                                                frame_start,
                                                frame_end,
                                                controller_type,
                                                smart_bake=False,
                                                camera=None)
        body_track_controls_witness.append(control_witness[0])
        
    # Reparent
    children_nodes = [tfm_utils.TransformNode(node=n) for n in body_track_controls_witness]
    parent_node = tfm_utils.TransformNode(node=camera_witness[0])
    reparent2_lib.reparent(children_nodes, parent_node,
                           frame_range_mode='timeline_inner',
                           start_frame=frame_start,
                           end_frame=frame_end,
                           bake_mode='full_bake',
                           rotate_order_mode='use_existing',
                           delete_static_anim_curves=False)
    _break_scale_attributes(children_nodes)

    # Body track scale rig
    if scale_rig_type == const.SCALE_RIG_TYPE_BODY_TRACK:
        # Break body track controls witness scale attributes
        body_track_control_nodes = [tfm_utils.TransformNode(node=n) for n in body_track_controls]
        _break_scale_attributes(body_track_control_nodes)
        # Scale constraint to body track controls
        for node in body_track_control_nodes:
            cmds.scaleConstraint(parent_node.get_node(),
                                 node.get_node(), maintainOffset=True)
        cmds.select(parent_node.get_node(), replace=True)
            
    # Camera track scale rig
    if scale_rig_type == const.SCALE_RIG_TYPE_CAMERA_TRACK:
        grand_parent = _create_scale_rig_main_grp(name+suffix+main_grp_suffix,
                                                  str(scene),
                                                  body_track_controls,
                                                  const.SCALE_RIG_TYPE_CAMERA_TRACK)        
        con = cmds.parentConstraint(parent_node.get_node(), grand_parent,
                                                    maintainOffset=False)
        cmds.delete(con)        
        grand_parent_node = tfm_utils.TransformNode(node=grand_parent)
        reparent2_lib.reparent([parent_node], grand_parent_node,
                               frame_range_mode='timeline_inner',
                               start_frame=frame_start,
                               end_frame=frame_end,
                               bake_mode='full_bake',
                               rotate_order_mode='use_existing',
                               delete_static_anim_curves=False) 
        _break_scale_attributes([parent_node])
        
        # Break scene scale attributes
        node = cmds.ls(scene, long=True, type='transform')
        scene_node = tfm_utils.TransformNode(node=node[0])
        _break_scale_attributes([scene_node])        
        cmds.parentConstraint(grand_parent, scene, maintainOffset=True)        
        cmds.scaleConstraint(grand_parent, scene, maintainOffset=True)
        
        # Create scale expression
        attrs = ['sx', 'sy', 'sz']
        parent = parent_node.get_node()
        for attr in attrs:
            exp = str(str(parent)+'.'+attr)+'='+'1'+'/'+str(grand_parent)+'.'+attr
            cmds.expression(string=exp, object=str(parent), alwaysEvaluate=True,
                                                           unitConversion='all')
        cmds.select(grand_parent, replace=True)    
Пример #19
0
def create(nodes, sparse=True):
    tfm_nodes = [tfm_utils.TransformNode(node=n) for n in nodes]

    # Force into long-names.
    nodes = [n.get_node() for n in tfm_nodes]

    # Ensure node attributes are editable.
    keyable_attrs = set()
    for node in nodes:
        keyable_attrs |= _get_keyable_attrs(node, const.TFM_ATTRS)

    # Query keyframe times on each node attribute
    start_frame, end_frame = time_utils.get_maya_timeline_range_outer()
    keytime_obj = keytime_utils.KeyframeTimes()
    for node in nodes:
        keytime_obj.add_node_attrs(node, const.TFM_ATTRS, start_frame, end_frame)
    fallback_frame_range = keytime_obj.sum_frame_range_for_nodes(nodes)
    fallback_times = list(range(fallback_frame_range[0],
                                fallback_frame_range[1]+1))

    # Query the transform matrix for the nodes
    cache = tfm_utils.TransformMatrixCache()
    for tfm_node in tfm_nodes:
        node = tfm_node.get_node()
        times = keytime_obj.get_times(node, sparse) or fallback_times
        cache.add_node(tfm_node, times)
    cache.process()

    # Create new (locator) node for each input node
    ctrl_list = []
    for tfm_node in tfm_nodes:
        node = tfm_node.get_node()
        name = node.rpartition('|')[-1]
        assert '|' not in name
        name = name.replace(':', '_')
        name = name + '_CTRL'
        name = mmapi.find_valid_maya_node_name(name)
        # TODO: Allow maintaining relative hierarchy of nodes.
        tfm = maya.cmds.createNode('transform', name=name)
        maya.cmds.createNode('locator', parent=tfm)
        rot_order = maya.cmds.xform(node, query=True, rotateOrder=True)
        maya.cmds.xform(tfm, rotateOrder=rot_order, preserve=True)
        ctrl_list.append(tfm)
    ctrl_tfm_nodes = [tfm_utils.TransformNode(node=tfm)
                      for tfm in ctrl_list]

    # Set transform matrix on new node
    for src, dst in zip(tfm_nodes, ctrl_tfm_nodes):
        src_node = src.get_node()
        times = keytime_obj.get_times(src_node, sparse) or fallback_times
        tfm_utils.set_transform_values(
            cache, times, src, dst,
            delete_static_anim_curves=False
        )
        if sparse is True:
            # Remove keyframes
            src_times = keytime_obj.get_times(src_node, sparse) or []
            dst_node = dst.get_node()
            if len(src_times) == 0:
                time_range = keytime_obj.get_frame_range_for_node(src_node)
                assert time_range[0] is not None
                assert time_range[1] is not None
                maya.cmds.cutKey(
                    dst_node,
                    attribute=const.TFM_ATTRS,
                    time=time_range,
                    clear=True
                )

    # Delete all keyframes on controlled nodes
    anim_curves = anim_utils.get_anim_curves_from_nodes(
        list(keyable_attrs),
    )
    anim_curves = [n for n in anim_curves
                   if node_utils.node_is_referenced(n) is False]
    if len(anim_curves) > 0:
        maya.cmds.delete(anim_curves)

    # Create constraint(s) to previous nodes.
    for tfm_node, ctrl in zip(tfm_nodes, ctrl_tfm_nodes):
        src_node = tfm_node.get_node()
        dst_node = ctrl.get_node()
        _create_constraint(src_node, dst_node)
    return ctrl_list
Пример #20
0
def remove(nodes, sparse=True):
    """
    Remove a controller and push the animation back to the controlled
    object.

    .. todo:: What should we do with any transforms parented under the
    controller? Should these objects be re-parented under the
    controlled object? Probably yes.

    """
    # Find controlled nodes from controller nodes
    ctrl_to_ctrlled_map = {}
    for ctrl_node in nodes:
        constraints = _get_constraints_from_ctrls(ctrl_node)
        dests = _get_destination_nodes_from_ctrls(constraints)
        if len(dests) == 0:
            continue
        ctrl_to_ctrlled_map[ctrl_node] = (constraints, dests)

    # Query keyframe times on controller nodes.
    start_frame, end_frame = time_utils.get_maya_timeline_range_outer()
    keytime_obj = keytime_utils.KeyframeTimes()
    for node in nodes:
        keytime_obj.add_node_attrs(node, const.TFM_ATTRS, start_frame, end_frame)
    fallback_frame_range = keytime_obj.sum_frame_range_for_nodes(nodes)
    fallback_times = list(range(fallback_frame_range[0],
                                fallback_frame_range[1]+1))

    # Query transform matrix on controlled nodes.
    cache = tfm_utils.TransformMatrixCache()
    for ctrl_node, (constraints, dest_nodes) in ctrl_to_ctrlled_map.items():
        times = keytime_obj.get_times(ctrl_node, sparse) or fallback_times
        ctrl = tfm_utils.TransformNode(node=ctrl_node)
        cache.add_node(ctrl, times)
        for dest_node in dest_nodes:
            dest = tfm_utils.TransformNode(node=dest_node)
            cache.add_node(dest, times)
    cache.process()

    # Get Controlled nodes
    ctrlled_nodes = set()
    for ctrl_node, (_, dest_nodes) in ctrl_to_ctrlled_map.items():
        for dest_node in dest_nodes:
            ctrlled_nodes.add(dest_node)

    # Delete constraints on controlled nodes.
    const_nodes = set()
    for ctrl_node, (constraints, _) in ctrl_to_ctrlled_map.items():
        const_nodes |= constraints
    if len(const_nodes) > 0:
        maya.cmds.delete(list(const_nodes))

    # Set keyframes (per-frame) on controlled nodes
    for ctrl_node, (_, ctrlled_nodes) in ctrl_to_ctrlled_map.items():
        times = keytime_obj.get_times(ctrl_node, sparse) or fallback_times
        ctrl = tfm_utils.TransformNode(node=ctrl_node)
        for ctrlled_node in ctrlled_nodes:
            ctrlled = tfm_utils.TransformNode(node=ctrlled_node)
            tfm_utils.set_transform_values(cache, times, ctrl, ctrlled,
                                           delete_static_anim_curves=False)

            # Re-parent controller child nodes under controlled node.
            ctrl_children = maya.cmds.listRelatives(
                ctrl_node,
                children=True,
                shapes=False,
                fullPath=True,
                type='transform',
            ) or []
            for child_node in ctrl_children:
                maya.cmds.parent(child_node, ctrlled_node, absolute=True)

    # Delete controller nodes
    ctrl_nodes = ctrl_to_ctrlled_map.keys()
    if len(ctrl_nodes) > 0:
        maya.cmds.delete(ctrl_nodes)
    return list(ctrlled_nodes)
Пример #21
0
def reparent(children_nodes,
             parent_node,
             frame_range_mode=None,
             start_frame=None,
             end_frame=None,
             bake_mode=None,
             rotate_order_mode=None,
             delete_static_anim_curves=None):
    """
    Reparent the children under the given parent.

    :param children_nodes: List of child nodes to be modified.
    :type children_nodes: [TransformNode, ..]

    :param parent_node: The new parent node for children, or None means
        un-parent.
    :type parent_node: TransformNode or None

    :param frame_range_mode: What frame range to use for baking.
    :type frame_range_mode: FRAME_RANGE_MODE_VALUES

    :param start_frame: First frame of custom frame range.
    :type start_frame: int or None

    :param end_frame: Last frame of custom frame range.
    :type end_frame: int or None

    :param bake_mode: How to bake the object? Where to place keyframes.
    :type bake_mode: BAKE_MODE_VALUES

    :param rotate_order_mode:
    :type rotate_order_mode: ROTATE_ORDER_MODE_VALUES

    :param delete_static_anim_curves:
        Delete any animCurves that all have the same values.
    :type delete_static_anim_curves: bool

    :returns: List of 'children' TransformNodes modified, will not
              contain child nodes if the child is already parented
              under 'parent'.
    :rtype: [TransformNode, ..]
    """
    assert len(children_nodes) > 0
    assert isinstance(children_nodes[0], tfm_utils.TransformNode)
    assert parent_node is None or isinstance(parent_node,
                                             tfm_utils.TransformNode)
    if isinstance(parent_node, tfm_utils.TransformNode):
        assert maya.cmds.objExists(parent_node.get_node())
    if frame_range_mode is None:
        frame_range_mode = const.FRAME_RANGE_MODE_TIMELINE_INNER_VALUE
    if bake_mode is None:
        bake_mode = const.BAKE_MODE_FULL_BAKE_VALUE
    if rotate_order_mode is None:
        rotate_order_mode = const.ROTATE_ORDER_MODE_USE_EXISTING_VALUE
    assert frame_range_mode in const.FRAME_RANGE_MODE_VALUES
    assert bake_mode in const.BAKE_MODE_VALUES
    assert rotate_order_mode in const.ROTATE_ORDER_MODE_VALUES
    assert isinstance(delete_static_anim_curves, bool)

    # Get frame range
    frame_range = time_utils.get_frame_range(frame_range_mode)

    # Get bake mode.
    sparse = None
    if bake_mode == const.BAKE_MODE_FULL_BAKE_VALUE:
        sparse = False
    elif bake_mode == const.BAKE_MODE_SMART_BAKE_VALUE:
        sparse = True
    else:
        assert False
    smart_bake = sparse is True

    # Get rotate order mode.
    rotate_order = None
    if rotate_order_mode == const.ROTATE_ORDER_MODE_USE_EXISTING_VALUE:
        rotate_order = None
    else:
        order_str = str(rotate_order_mode)
        rotate_order = const_utils.ROTATE_ORDER_STR_TO_INDEX[order_str]

    # Filter out invalid nodes.
    #
    # There is no need to un-parent to the world, if the node is
    # already parented to the world.
    msg = 'Skipping Re-Parent! Node is already parented to world: node=%r'
    if parent_node is None:
        tmp_children_nodes = children_nodes
        children_nodes = []
        for child_node in tmp_children_nodes:
            node = child_node.get_node()
            current_parent = maya.cmds.listRelatives(node, parent=True)
            if not current_parent:
                LOG.warn(msg, node)
            else:
                children_nodes.append(child_node)
    if len(children_nodes) == 0:
        return

    # Sort nodes by depth, deeper nodes first, so we do do not remove
    # parents before children.
    children = [tn.get_node() for tn in children_nodes]
    children = node_utils.sort_nodes_by_depth(children, reverse=True)
    children_nodes = [tfm_utils.TransformNode(node=n) for n in children]

    loc_tfms = []
    for i, child in enumerate(children):
        tfm_name = 'dummy' + str(i + 1)
        shp_name = 'dummy' + str(i + 1) + 'Shape'
        loc_tfm = maya.cmds.createNode('transform', name=tfm_name)
        maya.cmds.createNode('locator', name=shp_name, parent=loc_tfm)

        # Constrain the locator to the child, in translate, rotate and
        # scale.
        maya.cmds.pointConstraint(child, loc_tfm)
        maya.cmds.orientConstraint(child, loc_tfm)
        maya.cmds.scaleConstraint(child, loc_tfm)

        loc_tfms.append(loc_tfm)

    # Bake the locator results
    _bake_nodes(loc_tfms, frame_range, smart_bake=True)
    maya.cmds.delete(loc_tfms, constraints=True)

    for child, child_node, loc_tfm in zip(children, children_nodes, loc_tfms):
        # Find which attributes are partially locked, so we can avoid
        # modifying the attributes.
        translate_skip = _get_node_attr_skip(child, 'translate')
        rotate_skip = _get_node_attr_skip(child, 'rotate')
        scale_skip = _get_node_attr_skip(child, 'scale')

        # Warn if the child transform is completely locked.
        if (translate_skip == SKIP_ALL and rotate_skip == SKIP_ALL
                and scale_skip == SKIP_ALL):
            msg = 'Skipping Re-Parent! Cannot modify any attributes: node=%r'
            LOG.warn(msg, child)
            continue

        # Warn the user if some values cannot be modified.
        msg_base = 'Cannot modify attributes: node=%r attrs={} skip=%r'
        if translate_skip != 'none':
            msg = msg_base.format('translate')
            LOG.warn(msg, child, translate_skip)
        if rotate_skip != 'none':
            msg = msg_base.format('rotate')
            LOG.warn(msg, child, rotate_skip)
        if scale_skip != 'none':
            msg = msg_base.format('scale')
            LOG.warn(msg, child, scale_skip)

        # Remove keyframes from child transform.
        maya.cmds.cutKey(child, time=frame_range, attribute='translateX')
        maya.cmds.cutKey(child, time=frame_range, attribute='translateY')
        maya.cmds.cutKey(child, time=frame_range, attribute='translateZ')
        maya.cmds.cutKey(child, time=frame_range, attribute='rotateX')
        maya.cmds.cutKey(child, time=frame_range, attribute='rotateY')
        maya.cmds.cutKey(child, time=frame_range, attribute='rotateZ')
        maya.cmds.cutKey(child, time=frame_range, attribute='scaleX')
        maya.cmds.cutKey(child, time=frame_range, attribute='scaleY')
        maya.cmds.cutKey(child, time=frame_range, attribute='scaleZ')
        maya.cmds.cutKey(child, time=frame_range, attribute='rotateOrder')

        # If the parent is empty, parent to the world...
        if parent_node is None:
            maya.cmds.parent(child, world=True)
        else:
            # Else, constrain the child to the parent,
            # delete the history, and parent the child under
            # the parent.
            parent = parent_node.get_node()
            if translate_skip != SKIP_ALL:
                maya.cmds.pointConstraint(parent, child, skip=translate_skip)
            if rotate_skip != SKIP_ALL:
                maya.cmds.orientConstraint(parent, child, skip=rotate_skip)
            if scale_skip != SKIP_ALL:
                maya.cmds.scaleConstraint(parent, child, skip=scale_skip)
            maya.cmds.delete(child, constraints=True)

            maya.cmds.parent(child, parent)
        child = child_node.get_node()

        # Change Rotate order.
        if rotate_order is not None:
            node_attr = child + '.rotateOrder'
            settable = maya.cmds.getAttr(node_attr, settable=True)
            if settable:
                maya.cmds.setAttr(node_attr, rotate_order)
            else:
                LOG.warn('Cannot change rotate order: %r', child)

        # Constrain the child to match the locator.
        if translate_skip != SKIP_ALL:
            maya.cmds.pointConstraint(loc_tfm, child, skip=translate_skip)
        if rotate_skip != SKIP_ALL:
            maya.cmds.orientConstraint(loc_tfm, child, skip=rotate_skip)
        if scale_skip != SKIP_ALL:
            maya.cmds.scaleConstraint(loc_tfm, child, skip=scale_skip)

    # Bake the children's results.
    children = [tn.get_node() for tn in children_nodes]
    _bake_nodes(children, frame_range, smart_bake=smart_bake)
    maya.cmds.delete(children, constraints=True)
    maya.cmds.filterCurve(children)
    if delete_static_anim_curves is True:
        maya.cmds.delete(children, staticChannels=True)

    # Clean up redundant nodes.
    maya.cmds.delete(loc_tfms)
    return
    def test_get_transform_matrix_list_90degrees(self):
        path = self.get_data_path('scenes', 'bookHierarchy.ma')
        maya.cmds.file(path, open=True, force=True)

        book_node = 'book_GRP'
        spine_node = 'spine_GRP'
        cover_node = 'front_cover_GRP'
        latch_node = 'latch_GRP'

        maya.cmds.setAttr(book_node + '.ty', 10.0)
        maya.cmds.setAttr(book_node + '.rz', 90.0)  # <<< 90 degrees
        maya.cmds.setAttr(spine_node + '.rz', 90.0)
        maya.cmds.setAttr(cover_node + '.rz', 90.0)

        book_tfm = mod.TransformNode(book_node)
        spine_tfm = mod.TransformNode(spine_node)
        cover_tfm = mod.TransformNode(cover_node)
        latch_tfm = mod.TransformNode(latch_node)
        tfm_nodes = [book_tfm, spine_tfm, cover_tfm, latch_tfm]

        current_frame = maya.cmds.currentTime(query=True)
        frame_range = [current_frame]

        # Query the transform matrix for the nodes
        cache = mod.TransformMatrixCache()
        for tfm_node in tfm_nodes:
            cache.add_node(tfm_node, frame_range)
        cache.process()

        book_world_matrix_list = mod.get_transform_matrix_list(
            cache, frame_range, book_tfm)
        self.assertEqual(len(book_world_matrix_list), 1)
        book_world_matrix = list(book_world_matrix_list[0].asMatrix())

        spine_world_matrix_list = mod.get_transform_matrix_list(
            cache, frame_range, spine_tfm)
        self.assertEqual(len(spine_world_matrix_list), 1)
        spine_world_matrix = list(spine_world_matrix_list[0].asMatrix())

        cover_world_matrix_list = mod.get_transform_matrix_list(
            cache, frame_range, cover_tfm)
        self.assertEqual(len(cover_world_matrix_list), 1)
        cover_world_matrix = list(cover_world_matrix_list[0].asMatrix())

        latch_world_matrix_list = mod.get_transform_matrix_list(
            cache, frame_range, latch_tfm)
        self.assertEqual(len(latch_world_matrix_list), 1)
        latch_world_matrix = list(latch_world_matrix_list[0].asMatrix())

        # Expected Matrices
        expected_book_matrix = [
            0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
            10.0, 0.0, 1.0
        ]
        expected_spine_matrix = [
            -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            0.3518918752670288, 8.476484298706055, 0.0029969215393066406, 1.0
        ]
        expected_cover_matrix = [
            0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            0.3488234877586365, 7.9185943603515625, 0.0029969215393066406, 1.0
        ]
        expected_latch_matrix = [
            0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            0.3430972993373871, 11.661497116088867, 0.0001980811357498169, 1.0
        ]

        # Confirm matrix values in the cache are correct
        self.assertGreater(
            closeness.compare_floats(book_world_matrix, expected_book_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        self.assertGreater(
            closeness.compare_floats(spine_world_matrix,
                                     expected_spine_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        self.assertGreater(
            closeness.compare_floats(cover_world_matrix,
                                     expected_cover_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        self.assertGreater(
            closeness.compare_floats(latch_world_matrix,
                                     expected_latch_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)
        return
Пример #23
0
def remove(nodes, current_frame=None, eval_mode=None):
    """
    Remove a controller and push the animation back to the controlled
    object.

    Order the nodes to remove by hierarchy depth. This means that
    children will be removed first, then parents, this ensures we
    don't delete a controller accidentally when a parent controller is
    deleted first.

    :param nodes: The nodes to delete.
    :type nodes: [str, ..]

    :param current_frame: What frame number is considered to be
                          'current' when evaluating transforms without
                          any keyframes.
    :type current_frame: float or int

    :param eval_mode: What type of transform evaluation method to use?
    :type eval_mode: mmSolver.utils.constant.EVAL_MODE_*

    :returns: List of once controlled transform nodes, that are no
              longer controlled.
    :rtype: [str, ..]
    """
    if current_frame is None:
        current_frame = maya.cmds.currentTime(query=True)
    assert current_frame is not None
    sparse = False

    nodes = _sort_by_hierarchy(nodes, children_first=True)
    tfm_nodes = [tfm_utils.TransformNode(node=n) for n in nodes]

    # Find controlled nodes from controller nodes
    ctrl_to_ctrlled_map = {}
    for tfm_node in tfm_nodes:
        node = tfm_node.get_node()
        constraints = _get_constraints_from_ctrls(node)
        dests = _get_destination_nodes_from_ctrls(constraints)
        if len(dests) == 0:
            continue
        dests = _sort_by_hierarchy(dests, children_first=True)
        ctrl_to_ctrlled_map[node] = (constraints, dests)

    # Query keyframe times on controller nodes.
    start_frame, end_frame = time_utils.get_maya_timeline_range_outer()
    keytime_obj = keytime_utils.KeyframeTimes()
    for node in nodes:
        keytime_obj.add_node_attrs(node, const.TFM_ATTRS, start_frame,
                                   end_frame)
    fallback_frame_range = keytime_obj.sum_frame_range_for_nodes(nodes)
    fallback_times = list(
        range(fallback_frame_range[0], fallback_frame_range[1] + 1))

    # Query keyframe times on each node attribute
    key_times_map = time_utils.get_keyframe_times_for_node_attrs(
        nodes, const.TFM_ATTRS)

    # Query transform matrix on controlled nodes.
    cache = tfm_utils.TransformMatrixCache()
    for src_node, (constraints, dst_nodes) in ctrl_to_ctrlled_map.items():
        times = key_times_map.get(src_node, [current_frame])
        assert len(times) > 0
        ctrl = tfm_utils.TransformNode(node=src_node)
        cache.add_node(ctrl, times)
        for dst_node in dst_nodes:
            dst = tfm_utils.TransformNode(node=dst_node)
            cache.add_node(dst, times)
    cache.process(eval_mode=eval_mode)

    # Get Controlled nodes
    ctrlled_nodes = set()
    for src_node, (_, dst_nodes) in ctrl_to_ctrlled_map.items():
        for dst_node in dst_nodes:
            ctrlled_nodes.add(dst_node)

    # Delete constraints on controlled nodes.
    const_nodes = set()
    for src_node, (constraints, _) in ctrl_to_ctrlled_map.items():
        assert src_node not in constraints
        const_nodes |= constraints
    if len(const_nodes) > 0:
        maya.cmds.delete(list(const_nodes))

    # Set keyframes (per-frame) on controlled nodes
    for ctrl_node, (_, ctrlled_nodes) in ctrl_to_ctrlled_map.items():
        times = key_times_map.get(ctrl_node, [current_frame])
        ctrl = tfm_utils.TransformNode(node=ctrl_node)
        for ctrlled_node in ctrlled_nodes:
            ctrlled = tfm_utils.TransformNode(node=ctrlled_node)
            tfm_utils.set_transform_values(cache,
                                           times,
                                           ctrl,
                                           ctrlled,
                                           delete_static_anim_curves=False)

    parent_nodes = []
    anim_curves = []
    for src_node, (_, dst_nodes) in ctrl_to_ctrlled_map.items():
        src_times = key_times_map.get(src_node, [current_frame])
        assert len(src_times) > 0
        ctrl = tfm_utils.TransformNode(node=src_node)
        for dst_node in dst_nodes:
            dst = tfm_utils.TransformNode(node=dst_node)
            tfm_utils.set_transform_values(cache,
                                           src_times,
                                           ctrl,
                                           dst,
                                           delete_static_anim_curves=False)

            # Re-parent controller child nodes under controlled node.
            ctrl_children = maya.cmds.listRelatives(
                src_node,
                children=True,
                shapes=False,
                fullPath=True,
                type='transform',
            ) or []
            for child_node in ctrl_children:
                if child_node in nodes:
                    continue
                child = tfm_utils.TransformNode(node=child_node)
                parent_nodes.append((child, dst))

            src_had_keys = key_times_map.get(src_node) is not None
            if src_had_keys is True:
                continue
            # Maintain that destination node will not have keyframes now, the
            # same as the source node.
            dst_node = dst.get_node()
            keyable_attrs = _get_keyable_attrs(dst_node, const.TFM_ATTRS)
            anim_curves += anim_utils.get_anim_curves_from_nodes(
                list(keyable_attrs), )

    # Reparent children back to under the controlled.
    for src, dst in parent_nodes:
        src_node = src.get_node()
        dst_node = dst.get_node()
        maya.cmds.parent(src_node, dst_node, absolute=True)

    # Remove animation curves.
    anim_curves = [
        n for n in anim_curves if node_utils.node_is_referenced(n) is False
    ]
    if len(anim_curves) > 0:
        maya.cmds.delete(anim_curves)

    # Delete controller nodes
    ctrl_nodes = [n.get_node() for n in tfm_nodes]
    if len(ctrl_nodes) > 0:
        maya.cmds.delete(ctrl_nodes)
    return list(ctrlled_nodes)
Пример #24
0
def query_camera_data(cam_tfm, cam_shp, frames, rotate_order, test_disk):
    """
    Get the camera information from the given cameras
    """
    assert isinstance(cam_tfm, (str, unicode, basestring))
    assert isinstance(cam_shp, (str, unicode, basestring))
    assert len(cam_tfm) > 0
    assert len(cam_shp) > 0
    assert maya.cmds.objExists(cam_tfm)
    assert maya.cmds.objExists(cam_shp)
    assert isinstance(frames, (list, tuple))

    cam_data = {}
    attr_data = {}

    # Get the camera name, by parsing node name.
    name = cam_tfm.rpartition('|')[-1]
    cam_data['name'] = name

    # Add 'translate' and 'rotate' attributes to list to evaluate.
    tfm_node = tfm_utils.TransformNode(cam_tfm)
    tfm_cache = tfm_utils.TransformMatrixCache()
    tfm_cache.add_node(tfm_node, frames)
    tfm_cache.process()
    tfm_mat_list = tfm_utils.get_transform_matrix_list(
        tfm_cache, frames, tfm_node, rotate_order=rotate_order)
    assert len(tfm_mat_list) == len(frames)
    tx_values = []
    ty_values = []
    tz_values = []
    rx_values = []
    ry_values = []
    rz_values = []
    prv_rot = None
    for f, mat in zip(frames, tfm_mat_list):
        tx, ty, tz, rx, ry, rz, _, _, _ = tfm_utils.decompose_matrix(
            mat, prv_rot)
        tx_values.append((f, tx))
        ty_values.append((f, ty))
        tz_values.append((f, tz))
        rx_values.append((f, rx))
        ry_values.append((f, ry))
        rz_values.append((f, rz))
    attr_data['translateX'] = tx_values
    attr_data['translateY'] = ty_values
    attr_data['translateZ'] = tz_values
    attr_data['rotateX'] = rx_values
    attr_data['rotateY'] = ry_values
    attr_data['rotateZ'] = rz_values

    # Get the camera shape node attributes:
    # - focal length
    # - film back
    # - film back offset
    #
    # The values are stored in millimetres (mm).
    attrs = [
        ('focalLength', 'focalLength', lambda x: x),
        ('horizontalFilmAperture', 'filmBackWidth', lambda x: x * 25.4),
        ('verticalFilmAperture', 'filmBackHeight', lambda x: x * 25.4),
        ('horizontalFilmOffset', 'filmBackOffsetX', lambda x: x * 25.4),
        ('verticalFilmOffset', 'filmBackOffsetY', lambda x: x * 25.4),
    ]
    for attr, attr_name, convert_func in attrs:
        plug = '{0}.{1}'.format(cam_tfm, attr)
        attr_values = []
        for f in frames:
            v = maya.cmds.getAttr(plug, time=f)
            v = convert_func(v)
            attr_values.append((f, v))
        attr_data[attr_name] = attr_values

    cam_data['attr'] = attr_data
    return cam_data
Пример #25
0
def create(nodes, current_frame=None, eval_mode=None):
    """
    Create a Controller for the given nodes.

    :param nodes: The nodes to create Controller for.
    :type nodes: [str, ..]

    :param current_frame: What frame number is considered to be
                          'current' when evaluating transforms without
                          any keyframes.
    :type current_frame: float or int

    :param eval_mode: What type of transform evaluation method to use?
    :type eval_mode: mmSolver.utils.constant.EVAL_MODE_*

    :returns: List of controller transform nodes.
    :rtype: [str, ..]
    """
    if current_frame is None:
        current_frame = maya.cmds.currentTime(query=True)
    assert current_frame is not None
    sparse = False

    tfm_nodes = [tfm_utils.TransformNode(node=n) for n in nodes]

    # Force into long-names.
    nodes = [n.get_node() for n in tfm_nodes]

    # Ensure node attributes are editable.
    keyable_attrs = set()
    for node in nodes:
        keyable_attrs |= _get_keyable_attrs(node, const.TFM_ATTRS)

    # Query keyframe times on each node attribute
    start_frame, end_frame = time_utils.get_maya_timeline_range_outer()
    keytime_obj = keytime_utils.KeyframeTimes()
    for node in nodes:
        keytime_obj.add_node_attrs(node, const.TFM_ATTRS, start_frame,
                                   end_frame)
    fallback_frame_range = keytime_obj.sum_frame_range_for_nodes(nodes)
    fallback_times = list(
        range(fallback_frame_range[0], fallback_frame_range[1] + 1))
    key_times_map = time_utils.get_keyframe_times_for_node_attrs(
        nodes, const.TFM_ATTRS)

    # Query the transform matrix for the nodes
    cache = tfm_utils.TransformMatrixCache()
    for tfm_node in tfm_nodes:
        node = tfm_node.get_node()
        times = key_times_map.get(node, [current_frame])
        cache.add_node(tfm_node, times)
    cache.process(eval_mode=eval_mode)

    depth_to_tfm_node_map = _sort_hierarchy_depth_to_tfm_nodes(tfm_nodes)
    nodes_parent = _get_node_parent_map(nodes)

    # Create new (locator) node for each input node
    ctrl_list = []
    node_to_ctrl_map = {}
    node_to_ctrl_tfm_map = {}
    depths = sorted(depth_to_tfm_node_map.keys())
    for depth in depths:
        depth_tfm_nodes = depth_to_tfm_node_map.get(depth)
        assert depth_tfm_nodes is not None
        sorted_tfm_nodes = sorted(depth_tfm_nodes, key=lambda x: x.get_node())
        for tfm_node in sorted_tfm_nodes:
            node = tfm_node.get_node()
            node_parent = nodes_parent.get(node)
            if node_parent is not None:
                node_parent = node_to_ctrl_map.get(node_parent)
            name = node.rpartition('|')[-1]
            assert '|' not in name
            name = name.replace(':', '_')
            name = name + '_CTRL'
            name = mmapi.find_valid_maya_node_name(name)
            tfm = maya.cmds.createNode('transform',
                                       name=name,
                                       parent=node_parent)
            tfm = node_utils.get_long_name(tfm)
            shape_name = name + 'Shape'
            maya.cmds.createNode('locator', name=shape_name, parent=tfm)
            rot_order = maya.cmds.xform(node, query=True, rotateOrder=True)
            maya.cmds.xform(tfm, rotateOrder=rot_order, preserve=True)
            ctrl_tfm = tfm_utils.TransformNode(node=tfm)
            ctrl_list.append(tfm)
            node_to_ctrl_map[node] = tfm
            node_to_ctrl_tfm_map[node] = ctrl_tfm

    # Set transform matrix on new node
    anim_curves = []
    for src in tfm_nodes:
        src_node = src.get_node()
        src_times = key_times_map.get(src_node, [current_frame])
        dst = node_to_ctrl_tfm_map.get(src_node)
        assert len(src_times) > 0
        tfm_utils.set_transform_values(cache,
                                       src_times,
                                       src,
                                       dst,
                                       delete_static_anim_curves=False,
                                       eval_mode=eval_mode)
        src_had_keys = key_times_map.get(src_node) is not None
        if src_had_keys is True:
            continue
        # Maintain that destination node will not have keyframes now, the
        # same as the source node.
        dst_node = dst.get_node()
        keyable_attrs = _get_keyable_attrs(dst_node, const.TFM_ATTRS)
        anim_curves += anim_utils.get_anim_curves_from_nodes(
            list(keyable_attrs), )
    anim_curves = [
        n for n in anim_curves if node_utils.node_is_referenced(n) is False
    ]
    if len(anim_curves) > 0:
        maya.cmds.delete(anim_curves)

    # Delete all keyframes on controlled nodes
    keyable_attrs = set()
    for tfm_node in tfm_nodes:
        node = tfm_node.get_node()
        keyable_attrs |= _get_keyable_attrs(node, const.TFM_ATTRS)
    anim_curves = anim_utils.get_anim_curves_from_nodes(list(keyable_attrs), )
    anim_curves = [
        n for n in anim_curves if node_utils.node_is_referenced(n) is False
    ]
    if len(anim_curves) > 0:
        maya.cmds.delete(anim_curves)

    # Create constraint(s) to previous nodes.
    for tfm_node in tfm_nodes:
        src_node = tfm_node.get_node()
        ctrl = node_to_ctrl_tfm_map.get(src_node)
        dst_node = ctrl.get_node()
        _create_constraint(src_node, dst_node)
    return ctrl_list
Пример #26
0
def reparent(children, parent):
    """
    Reparent 'children' nodes under 'parent' node.

    If 'parent' is None, the children are unparented to world.

    All settings are taken from the UI's defaults. To change these,
    please use the UI (or 'configmaya' module)
    """
    children_nodes = [tfm_utils.TransformNode(node=n) for n in children]
    parent_node = None
    if parent is not None:
        parent_node = tfm_utils.TransformNode(node=parent)

    # Get all saved re-parent options.
    frame_range_mode = configmaya.get_scene_option(
        const.CONFIG_FRAME_RANGE_MODE_KEY,
        default=const.DEFAULT_FRAME_RANGE_MODE)
    start_frame = configmaya.get_scene_option(
        const.CONFIG_FRAME_START_KEY,
        default=const.DEFAULT_FRAME_START)
    end_frame = configmaya.get_scene_option(
        const.CONFIG_FRAME_END_KEY,
        default=const.DEFAULT_FRAME_END)
    bake_mode = configmaya.get_scene_option(
        const.CONFIG_BAKE_MODE_KEY,
        default=const.DEFAULT_BAKE_MODE)
    rotate_order = configmaya.get_scene_option(
        const.CONFIG_ROTATE_ORDER_MODE_KEY,
        default=const.DEFAULT_ROTATE_ORDER_MODE)
    delete_static_anim_curves = configmaya.get_scene_option(
        const.CONFIG_DELETE_STATIC_ANIM_CURVES_KEY,
        default=const.DEFAULT_DELETE_STATIC_ANIM_CURVES)
    viewport_mode = const_utils.DISABLE_VIEWPORT_MODE_VP1_VALUE

    # Check the children nodes and prompt the user what to do
    prompt_user, settable_map, full_msg, confirm_msg = \
        __check_modify_nodes(children)
    if prompt_user is True:
        LOG.warn(full_msg)
        cancel_button = 'Cancel'
        continue_button = 'Continue'
        button = maya.cmds.confirmDialog(
            title='Warning: Cannot Modify Nodes.',
            message=confirm_msg,
            button=[continue_button, cancel_button],
            defaultButton=continue_button,
            cancelButton=cancel_button,
            dismissString=cancel_button)
        if button == cancel_button:
            LOG.warn('User canceled Re-parent.')
            return

    with tools_utils.tool_context(disable_viewport=True,
                                  use_undo_chunk=True,
                                  use_dg_evaluation_mode=False,
                                  restore_current_frame=True,
                                  pre_update_frame=False,
                                  disable_viewport_mode=viewport_mode):
        lib.reparent(
            children_nodes, parent_node,
            frame_range_mode=frame_range_mode,
            start_frame=start_frame,
            end_frame=end_frame,
            bake_mode=bake_mode,
            rotate_order_mode=rotate_order,
            delete_static_anim_curves=bool(delete_static_anim_curves),
        )
        nodes = [tn.get_node() for tn in children_nodes]
        maya.cmds.select(nodes, replace=True)

    # Trigger Maya to refresh.
    maya.cmds.refresh(currentView=True, force=False)
    return
Пример #27
0
    def create_scene_c(self, start, end):
        """
        Simple scene, two transforms, both with keyframes.

        - A
        - B
        """
        maya.cmds.playbackOptions(edit=True, minTime=start)
        maya.cmds.playbackOptions(edit=True, animationStartTime=start)
        maya.cmds.playbackOptions(edit=True, animationEndTime=end)
        maya.cmds.playbackOptions(edit=True, maxTime=end)

        tfm_a = maya.cmds.createNode('transform')
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateX',
                              value=10.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateY',
                              value=20.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateZ',
                              value=30.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateX',
                              value=-10.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateY',
                              value=-20.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_a,
                              attribute='translateZ',
                              value=-30.0,
                              time=end)
        tfm_node_a = tfm_utils.TransformNode(node=tfm_a)

        tfm_b = maya.cmds.createNode('transform')
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateX',
                              value=-10.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateY',
                              value=-20.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateZ',
                              value=-30.0,
                              time=start)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateX',
                              value=10.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateY',
                              value=20.0,
                              time=end)
        maya.cmds.setKeyframe(tfm_b,
                              attribute='translateZ',
                              value=30.0,
                              time=end)
        tfm_node_b = tfm_utils.TransformNode(node=tfm_b)
        return tfm_node_a, tfm_node_b
    def test_set_transform_values_with_rotate_pivot(self):
        path = self.get_data_path('scenes', 'bookHierarchy.ma')
        maya.cmds.file(path, open=True, force=True)

        book_node = 'book_GRP'
        spine_node = 'spine_GRP'
        cover_node = 'front_cover_GRP'

        maya.cmds.setAttr(book_node + '.ty', 10.0)
        maya.cmds.setAttr(book_node + '.rz', 90.0)
        maya.cmds.setAttr(spine_node + '.rz', 90.0)
        maya.cmds.setAttr(cover_node + '.rz', 90.0)

        book_tfm = mod.TransformNode(book_node)
        spine_tfm = mod.TransformNode(spine_node)
        cover_tfm = mod.TransformNode(cover_node)
        tfm_nodes = [book_tfm, spine_tfm, cover_tfm]

        current_frame = maya.cmds.currentTime(query=True)
        frame_range = [current_frame]

        # Query the transform matrix for the nodes
        cache = mod.TransformMatrixCache()
        for tfm_node in tfm_nodes:
            cache.add_node(tfm_node, frame_range)
        cache.process()

        book_dst_node = maya.cmds.createNode('transform', name='book_CTRL')
        book_dst_tfm_node = mod.TransformNode(node=book_dst_node)
        mod.set_transform_values(cache,
                                 frame_range,
                                 book_tfm,
                                 book_dst_tfm_node,
                                 delete_static_anim_curves=False)

        spine_dst_node = maya.cmds.createNode('transform', name='spine_CTRL')
        spine_dst_tfm_node = mod.TransformNode(node=spine_dst_node)
        mod.set_transform_values(cache,
                                 frame_range,
                                 spine_tfm,
                                 spine_dst_tfm_node,
                                 delete_static_anim_curves=False)

        cover_dst_node = maya.cmds.createNode('transform', name='cover_CTRL')
        cover_dst_tfm_node = mod.TransformNode(node=cover_dst_node)
        mod.set_transform_values(cache,
                                 frame_range,
                                 cover_tfm,
                                 cover_dst_tfm_node,
                                 delete_static_anim_curves=False)

        # save the output scene file
        path = 'test_transform_set_transforms_with_rotate_pivot.ma'
        path = self.get_data_path(path)
        maya.cmds.file(rename=path)
        maya.cmds.file(save=True, type='mayaAscii', force=True)

        # Expected Matrices
        expected_book_matrix = [
            0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
            10.0, 0.0, 1.0
        ]
        expected_spine_matrix = [
            -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            0.3518918752670288, 8.476484298706055, 0.0029969215393066406, 1.0
        ]
        expected_cover_matrix = [
            0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            0.3488234877586365, 7.9185943603515625, 0.0029969215393066406, 1.0
        ]
        expected_spine_par_inv_matrix = [
            0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -10.0,
            0.0, 0.0, 1.0
        ]
        expected_front_cover_par_inv_matrix = [
            -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            -1.1716232898755894, 8.124592860140336, 0.0, 1.0
        ]

        # Confirm attributes in the cache are correct
        book_attrs = cache.get_attrs_for_node(book_tfm)
        self.assertItemsEqual(book_attrs, ["worldMatrix[0]"])

        attr_names_with_pivot = [
            "worldMatrix[0]",
            "matrix",
            "parentInverseMatrix[0]",
            "rotatePivotX",
            "rotatePivotY",
            "rotatePivotZ",
        ]
        spine_attrs = cache.get_attrs_for_node(spine_tfm)
        self.assertItemsEqual(spine_attrs, attr_names_with_pivot)

        cover_attrs = cache.get_attrs_for_node(cover_tfm)
        self.assertItemsEqual(cover_attrs, attr_names_with_pivot)

        # Confirm matrix values in the cache are correct
        book_world_matrix = list(
            cache.get_node_attr(book_tfm, "worldMatrix[0]", frame_range)[0])
        self.assertGreater(
            closeness.compare_floats(book_world_matrix, expected_book_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        spine_par_inv_matrix = list(
            cache.get_node_attr(spine_tfm, "parentInverseMatrix[0]",
                                frame_range)[0])
        self.assertGreater(
            closeness.compare_floats(spine_par_inv_matrix,
                                     expected_spine_par_inv_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        cover_par_inv_matrix = list(
            cache.get_node_attr(cover_tfm, "parentInverseMatrix[0]",
                                frame_range)[0])
        self.assertGreater(
            closeness.compare_floats(cover_par_inv_matrix,
                                     expected_front_cover_par_inv_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        # Compare destination node matrices with the original
        book_matrix = maya.cmds.xform(book_dst_node,
                                      query=True,
                                      matrix=True,
                                      worldSpace=True)
        self.assertGreater(
            closeness.compare_floats(book_matrix, expected_book_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        spine_matrix = maya.cmds.xform(spine_dst_node,
                                       query=True,
                                       matrix=True,
                                       worldSpace=True)
        self.assertGreater(
            closeness.compare_floats(spine_matrix, expected_spine_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        cover_matrix = maya.cmds.xform(cover_dst_node,
                                       query=True,
                                       matrix=True,
                                       worldSpace=True)
        self.assertGreater(
            closeness.compare_floats(cover_matrix, expected_cover_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)
        return
    def test_get_transform_matrix_list_45degrees(self):
        path = self.get_data_path('scenes', 'bookHierarchy.ma')
        maya.cmds.file(path, open=True, force=True)

        book_node = 'book_GRP'
        spine_node = 'spine_GRP'
        cover_node = 'front_cover_GRP'
        latch_node = 'latch_GRP'

        maya.cmds.setAttr(book_node + '.ty', 10.0)
        maya.cmds.setAttr(book_node + '.rz', 45.0)  # <<< 45 degrees
        maya.cmds.setAttr(spine_node + '.rz', 90.0)
        maya.cmds.setAttr(cover_node + '.rz', 90.0)

        book_tfm = mod.TransformNode(book_node)
        spine_tfm = mod.TransformNode(spine_node)
        cover_tfm = mod.TransformNode(cover_node)
        latch_tfm = mod.TransformNode(latch_node)
        tfm_nodes = [book_tfm, spine_tfm, cover_tfm, latch_tfm]

        current_frame = maya.cmds.currentTime(query=True)
        frame_range = [current_frame]

        # Query the transform matrix for the nodes
        cache = mod.TransformMatrixCache()
        for tfm_node in tfm_nodes:
            cache.add_node(tfm_node, frame_range)
        cache.process()

        book_world_matrix_list = mod.get_transform_matrix_list(
            cache, frame_range, book_tfm)
        self.assertEqual(len(book_world_matrix_list), 1)
        book_world_matrix = list(book_world_matrix_list[0].asMatrix())

        spine_world_matrix_list = mod.get_transform_matrix_list(
            cache, frame_range, spine_tfm)
        self.assertEqual(len(spine_world_matrix_list), 1)
        spine_world_matrix = list(spine_world_matrix_list[0].asMatrix())

        cover_world_matrix_list = mod.get_transform_matrix_list(
            cache, frame_range, cover_tfm)
        self.assertEqual(len(cover_world_matrix_list), 1)
        cover_world_matrix = list(cover_world_matrix_list[0].asMatrix())

        latch_world_matrix_list = mod.get_transform_matrix_list(
            cache, frame_range, latch_tfm)
        self.assertEqual(len(latch_world_matrix_list), 1)
        latch_world_matrix = list(latch_world_matrix_list[0].asMatrix())

        # Expected Matrices
        expected_book_matrix = [
            0.7071067811865475, 0.7071067811865476, 0.0, 0.0,
            -0.7071067811865476, 0.7071067811865475, 0.0, 0.0, 0.0, 0.0, 1.0,
            0.0, 0.0, 10.0, 0.0, 1.0
        ]
        expected_spine_matrix = [
            -0.7071067811865475, 0.7071067811865477, 0.0, 0.0,
            -0.7071067811865477, -0.7071067811865475, 0.0, 0.0, 0.0, 0.0, 1.0,
            0.0, -0.8284631523833599, 8.673886585125107, 0.0029969215393066406,
            1.0
        ]
        expected_cover_matrix = [
            -0.7071067811865479, -0.7071067811865474, 0.0, 0.0,
            0.7071067811865474, -0.7071067811865479, 0.0, 0.0, 0.0, 0.0, 1.0,
            0.0, -1.2251205885640575, 8.281568504173393, 0.0029969215393066406,
            1.0
        ]
        expected_latch_matrix = [
            0.7071067811865475, 0.7071067811865476, 0.0, 0.0,
            -0.7071067811865476, 0.7071067811865475, 0.0, 0.0, 0.0, 0.0, 1.0,
            0.0, 1.417462229728698, 10.932249069213867, 0.0001980811357498169,
            1.0
        ]

        # Confirm matrix values in the cache are correct
        self.assertGreater(
            closeness.compare_floats(book_world_matrix, expected_book_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)

        tol = 0.000001
        mat_a = OpenMaya2.MMatrix(book_world_matrix)
        mat_b = OpenMaya2.MMatrix(expected_book_matrix)
        self.assertTrue(mat_a.isEquivalent(mat_b, tol))

        self.assertGreater(
            closeness.compare_floats(spine_world_matrix,
                                     expected_spine_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)
        mat_a = OpenMaya2.MMatrix(spine_world_matrix)
        mat_b = OpenMaya2.MMatrix(expected_spine_matrix)
        self.assertTrue(mat_a.isEquivalent(mat_b, tol))

        self.assertGreater(
            closeness.compare_floats(cover_world_matrix,
                                     expected_cover_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)
        mat_a = OpenMaya2.MMatrix(cover_world_matrix)
        mat_b = OpenMaya2.MMatrix(expected_cover_matrix)
        self.assertTrue(mat_a.isEquivalent(mat_b, tol))

        self.assertGreater(
            closeness.compare_floats(latch_world_matrix,
                                     expected_latch_matrix),
            closeness.DEFAULT_SIGNIFICANT_DIGITS)
        mat_a = OpenMaya2.MMatrix(latch_world_matrix)
        mat_b = OpenMaya2.MMatrix(expected_latch_matrix)
        self.assertTrue(mat_a.isEquivalent(mat_b, tol))
        return