Exemplo n.º 1
0
def create_screen_space_motion_trail(cam,
                                     tfm,
                                     name=None,
                                     use_frame_range=None,
                                     pre_frame=None,
                                     post_frame=None,
                                     start_frame=None,
                                     end_frame=None,
                                     increment=None):
    """
    Create a Screen-Space Maya Locator that may be solved in Screen XYZ.
    """
    assert isinstance(cam, pycompat.TEXT_TYPE)
    assert isinstance(tfm, pycompat.TEXT_TYPE)
    if name is None:
        name = tfm.rpartition('|')[-1]

    frame_range = time_utils.get_maya_timeline_range_inner()
    if use_frame_range is None:
        use_frame_range = const.USE_FRAME_RANGE_DEFAULT
    if pre_frame is None:
        pre_frame = const.PRE_FRAME_DEFAULT
    if post_frame is None:
        post_frame = const.POST_FRAME_DEFAULT
    if start_frame is None:
        start_frame = frame_range.start
    if end_frame is None:
        end_frame = frame_range.end
    if increment is None:
        if use_frame_range:
            increment = const.FRAME_RANGE_INCREMENT_DEFAULT
        else:
            increment = const.PER_FRAME_INCREMENT_DEFAULT

    tfm_attrs = [
        'translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY',
        'rotateZ', 'scaleX', 'scaleY', 'scaleZ'
    ]

    maya.cmds.loadPlugin('matrixNodes', quiet=True)
    cam_tfm, cam_shp = camera_utils.get_camera(cam)

    # Create temporary group
    temp_grp_name = const.TEMP_OBJECT_NAME
    temp_grp = temp_grp_name
    if not maya.cmds.objExists(temp_grp):
        temp_grp = maya.cmds.createNode('transform', name=temp_grp_name)
        maya.cmds.setAttr(temp_grp + '.visibility', False)

    # Create Temporary transform node to calculate motion path on.
    temp_tfm_name = name + '_TEMP_NULL'
    temp_tfm_name = mmapi.find_valid_maya_node_name(temp_tfm_name)
    temp_tfm = maya.cmds.createNode('transform',
                                    parent=temp_grp,
                                    name=temp_tfm_name)

    # Create trail group under the camera.
    trail_handle_grp_name = const.MOTION_PATH_GROUP_NAME
    trail_handle_grp = cam_tfm + '|' + trail_handle_grp_name
    if not maya.cmds.objExists(trail_handle_grp):
        trail_handle_grp = maya.cmds.createNode('transform',
                                                name=trail_handle_grp_name,
                                                parent=cam_tfm)
        # Trails are non-selectable by default.
        plug_name = trail_handle_grp + '.template'
        maya.cmds.setAttr(plug_name, True)

        # Lock transform attributes.
        for attr in tfm_attrs:
            plug_name = trail_handle_grp + '.' + attr
            maya.cmds.setAttr(plug_name, lock=True)

    # Matrix Multiply
    mult_mat = maya.cmds.createNode('multMatrix')
    src = tfm + '.worldMatrix[0]'
    dst = mult_mat + '.matrixIn[0]'
    maya.cmds.connectAttr(src, dst)

    src = cam_tfm + '.worldInverseMatrix[0]'
    dst = mult_mat + '.matrixIn[1]'
    maya.cmds.connectAttr(src, dst)

    # Decompose Matrix
    decompose = maya.cmds.createNode('decomposeMatrix')
    src = mult_mat + '.matrixSum'
    dst = decompose + '.inputMatrix'
    maya.cmds.connectAttr(src, dst)

    src = decompose + '.outputTranslate'
    dst = temp_tfm + '.translate'
    maya.cmds.connectAttr(src, dst)

    # Lock the temporary transform node.
    for attr in tfm_attrs:
        plug_name = temp_tfm + '.' + attr
        maya.cmds.setAttr(plug_name, lock=True)

    # Create Motion Trail
    update_mode = 'always'
    handle_tfm, handle_shp, trail_shp = create_motion_trail_setup(
        temp_tfm,
        trail_handle_grp,
        name,
        use_frame_range,
        start_frame,
        end_frame,
        pre_frame,
        post_frame,
        increment,
        update_mode,
    )
    return handle_tfm, handle_shp, trail_shp
Exemplo n.º 2
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
Exemplo n.º 3
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