示例#1
0
def main():
    """
    Averages marker position from selected markers.
    """
    selection = maya.cmds.ls(selection=True, long=True) or []
    selected_markers = mmapi.filter_marker_nodes(selection)
    if len(selected_markers) < 2:
        LOG.warning('Please select more than 1 marker')
        return

    mkr_selection = selected_markers[0]
    mkr = mmapi.Marker(node=mkr_selection)
    # getting camera from the selected marker
    cam_from_mkr = mkr.get_camera()
    mkr_name = mmapi.get_new_marker_name('avgMarker1')
    new_mkr = mmapi.Marker().create_node(cam=cam_from_mkr, name=mkr_name)

    new_mkr_node = new_mkr.get_node()
    bnd_name = mmapi.get_new_bundle_name('avgBundle1')
    new_bnd = mmapi.Bundle().create_node(name=bnd_name)
    # connecting bundle to the marker
    new_mkr.set_bundle(new_bnd)

    # getting first frame and last frame from the selected markers
    start_frame, end_frame = mmapi.get_markers_start_end_frames(
        selected_markers)

    # Running average from selected markers for giving frame range
    lib.__set_average_marker_position(selected_markers, start_frame, end_frame,
                                      new_mkr_node)

    maya.cmds.select(new_mkr_node)
    # dgdirty for Channel box value update
    maya.cmds.dgdirty(new_mkr_node)
    return None
示例#2
0
def _create_line(cam, mkr_grp, base_name):
    name = '{base}_{num}_MKR'
    mkr_name1 = name.format(base=base_name, num=1)
    mkr_name2 = name.format(base=base_name, num=2)

    mkr1 = mmapi.Marker().create_node(mkr_grp=mkr_grp, name=mkr_name1)
    mkr2 = mmapi.Marker().create_node(mkr_grp=mkr_grp, name=mkr_name2)
    return mkr1, mkr2
示例#3
0
    def test_get_root_frames_from_markers_2(self):
        # Time Range
        start = 1001
        end = 1101
        maya.cmds.playbackOptions(animationStartTime=start,
                                  minTime=start,
                                  animationEndTime=end,
                                  maxTime=end)

        # Create Camera and Marker Group
        cam_tfm = maya.cmds.createNode('transform', name='cam_tfm')
        cam_shp = maya.cmds.createNode('camera',
                                       name='cam_shp',
                                       parent=cam_tfm)
        cam = mmapi.Camera(shape=cam_shp)
        mkr_grp = mmapi.MarkerGroup().create_node(cam=cam)

        # Marker A
        mkr_a = mmapi.Marker().create_node()
        mkr_a_node = mkr_a.get_node()
        times = [1000, 1001, 1101, 1102]
        values = [0, 1, 1, 0]
        anim_utils.create_anim_curve_node_apione(times, values,
                                                 mkr_a_node + '.enable')

        # Marker B
        mkr_b = mmapi.Marker().create_node()
        mkr_b_node = mkr_b.get_node()
        times = [1000, 1001, 1051, 1052]
        values = [0, 1, 1, 0]
        anim_utils.create_anim_curve_node_apione(times, values,
                                                 mkr_b_node + '.enable')

        # Marker C
        mkr_c = mmapi.Marker().create_node()
        mkr_c_node = mkr_c.get_node()
        times = [1050, 1051, 1101, 1102]
        values = [0, 1, 1, 0]
        anim_utils.create_anim_curve_node_apione(times, values,
                                                 mkr_c_node + '.enable')

        # Calculate Root Frames
        min_frames_per_marker = 2
        mkr_list = [mkr_a, mkr_b, mkr_c]
        start_frame, end_frame = time_utils.get_maya_timeline_range_inner()
        frame_nums = mod.get_root_frames_from_markers(mkr_list,
                                                      min_frames_per_marker,
                                                      start_frame, end_frame)
        print 'frames:', frame_nums
        return
示例#4
0
def _find_camera_from_selection(sel):
    cam = None
    filtered_nodes = mmapi.filter_nodes_into_categories(sel)
    cam_nodes = filtered_nodes['camera']
    mkr_grp_nodes = filtered_nodes['markergroup']
    mkr_nodes = filtered_nodes['marker']

    # Check selected camera.
    if len(cam_nodes) > 0:
        cam_node = cam_nodes[0]
        cam_tfm, cam_shp = camera_utils.get_camera(cam_node)
        if cam_tfm is not None and cam_shp is not None:
            cam = mmapi.Camera(transform=cam_tfm, shape=cam_shp)
    if cam is not None and cam.is_valid():
        return cam

    # Check selected marker group.
    if len(mkr_grp_nodes) > 0:
        mkr_grp_node = mkr_grp_nodes[0]
        mkr_grp = mmapi.MarkerGroup(node=mkr_grp_node)
        cam = mkr_grp.get_camera()
    if cam is not None and cam.is_valid():
        return cam

    # Check selected marker.
    if len(mkr_nodes) > 0:
        mkr_node = mkr_nodes[0]
        mkr = mmapi.Marker(node=mkr_node)
        cam = mkr.get_camera()
    if cam is not None and cam.is_valid():
        return cam
    return None
示例#5
0
def _get_markers(mkr_node_list, bnd_node_list, active_cam_shp):
    use_camera = False
    mkr_list = []
    mkr_uid_list = set()

    if len(mkr_node_list) > 0:
        for mkr_node in mkr_node_list:
            mkr = mmapi.Marker(node=mkr_node)
            _add_unique_markers_to_list(mkr, mkr_list, mkr_uid_list)

    if len(bnd_node_list) > 0:
        for bnd_node in bnd_node_list:
            bnd = mmapi.Bundle(node=bnd_node)
            bnd_mkr_list = bnd.get_marker_list()
            if len(bnd_mkr_list) == 1:
                # There can only be one possible marker to project from
                mkr = bnd_mkr_list[0]
                cam = mkr.get_camera()
                if cam is None:
                    continue
                _add_unique_markers_to_list(mkr, mkr_list, mkr_uid_list)
            else:
                for mkr in bnd_mkr_list:
                    cam = mkr.get_camera()
                    if cam is None:
                        continue
                    mkr_cam_shp = cam.get_shape_node()
                    if active_cam_shp != mkr_cam_shp:
                        continue
                    use_camera = True
                    _add_unique_markers_to_list(mkr, mkr_list, mkr_uid_list)
    return mkr_list, use_camera
def get_bundles_from_markers(nodes):
    """
    Convert Marker nodes into Bundle nodes.

    :param nodes: Maya nodes to convert into Bundles (expected to be
                  Marker nodes, but other node types will not cause
                  errors).
    :type nodes: list of str

    :returns: All Maya nodes connected to Marker nodes as Bundles.
    :rtype: list of str
    """
    mkr_nodes = filternodes.get_marker_nodes(nodes)
    bnd_nodes = []
    for mkr_node in mkr_nodes:
        mkr = mmapi.Marker(mkr_node)
        bnd = mkr.get_bundle()
        if bnd is None:
            continue
        bnd_node = bnd.get_node()
        if bnd_node is None:
            continue
        if bnd_node not in bnd_nodes:
            bnd_nodes.append(bnd_node)
    return bnd_nodes
示例#7
0
def link_marker_bundle(mkr_node, bnd_node):
    """
    Try to connect the two marker and bundle nodes.
    """
    mkr = mmapi.Marker(node=mkr_node)
    bnd = mmapi.Bundle(node=bnd_node)
    cam_from_mkr = mkr.get_camera()
    cam_from_mkr_uid = cam_from_mkr.get_shape_uid()

    # Check the bundle doesn't already have a marker attached to the
    # same camera as 'mkr'
    bad_mkr = None
    connected_mkr_list = bnd.get_marker_list()
    for conn_mkr in connected_mkr_list:
        conn_cam = conn_mkr.get_camera()
        conn_cam_uid = conn_cam.get_shape_uid()
        if conn_cam_uid == cam_from_mkr_uid:
            bad_mkr = conn_mkr
            break

    valid = bad_mkr is None
    if valid:
        # No problem, set the bundle.
        mkr.set_bundle(bnd)
    else:
        msg = 'Cannot link {mkr} to {bnd}; '
        msg += 'bundle is already connected to Marker {mkr2} under camera {cam}.'
        msg = msg.format(
            mkr=repr(mkr_node),
            bnd=repr(bnd_node),
            mkr2=repr(bad_mkr.get_node()),
            cam=repr(cam_from_mkr.get_shape_node()),
        )
        LOG.warning(msg)
    return valid
示例#8
0
def get_markers_from_selection():
    """
    Given a selection of nodes, find the associated markers.

    :return: list of Marker objects.
    """
    nodes = maya.cmds.ls(long=True, selection=True) or []
    node_categories = filter_nodes.get_nodes(nodes)
    marker_nodes = node_categories.get('marker', [])

    camera_nodes = node_categories.get('camera', [])
    for node in camera_nodes:
        node_type = maya.cmds.nodeType(node)
        cam = None
        if node_type == 'transform':
            cam = mmapi.Camera(transform=node)
        if node_type == 'camera':
            cam = mmapi.Camera(shape=node)
        tfm_node = cam.get_transform_node()
        below_nodes = maya.cmds.ls(tfm_node, dag=True, long=True)
        marker_nodes += filter_nodes.get_marker_nodes(below_nodes)

    marker_group_nodes = list(node_categories['markergroup'])
    for node in marker_group_nodes:
        below_nodes = maya.cmds.ls(node, dag=True, long=True)
        marker_nodes += filter_nodes.get_marker_nodes(below_nodes)

    # Convert nodes into Marker objects.
    marker_nodes = list(set(marker_nodes))
    marker_list = []
    for node in marker_nodes:
        mkr = mmapi.Marker(node=node)
        marker_list.append(mkr)
    return marker_list
示例#9
0
def remove_layer_override():
    """
    Removed markers layer override.

    :return: None
    """
    selection = maya.cmds.ls(selection=True, long=True) or []
    selected_markers = mmapi.filter_marker_nodes(selection)
    if len(selected_markers) == 0:
        text = 'Please select a marker to remove anim layer override'
        LOG.warning(text)
        return None

    marker_nodes = []
    for marker in selected_markers:
        marker = mmapi.Marker(node=marker)
        marker_node = marker.get_node()
        marker_nodes.append(marker_node)

    if not marker_nodes:
        text = 'Please select a marker to remove anim layer override'
        LOG.warning(text)
        return

    attrs = lib.get_attrs_for_offset(marker_nodes)
    anim_layer = const.ANIM_LAYER
    for attr in attrs:
        maya.cmds.animLayer(anim_layer, removeAttribute=attr, edit=True)

    if maya.cmds.animLayer(anim_layer, attribute=True, query=True) is None:
        maya.cmds.delete(anim_layer)
    return
示例#10
0
def __create_node(mkr_data, cam, mkr_grp, with_bundles):
    """
    Create a Marker object from a MarkerData object.
    """
    if isinstance(mkr_data, interface.MarkerData) is False:
        msg = 'mkr_data must be of type: %r'
        raise TypeError(msg % interface.MarkerData.__name__)
    if isinstance(with_bundles, bool) is False:
        msg = 'with_bundles must be of type: %r'
        raise TypeError(msg % bool.__name__)

    name = mkr_data.get_name()
    mkr_name = mmapi.get_new_marker_name(name)
    bnd_name = mmapi.get_new_bundle_name(name)
    bnd = None
    mmapi.load_plugin()
    if with_bundles is True:
        bnd = mmapi.Bundle().create_node(bnd_name)
    if cam and mkr_grp:
        cam = None
    mkr = mmapi.Marker().create_node(name=mkr_name,
                                     cam=cam,
                                     mkr_grp=mkr_grp,
                                     bnd=bnd)
    return mkr, bnd
示例#11
0
def create_example_solve_scene():
    """
    Very basic single frame solver set up.

    This function does not execute the solve, execution must be done manually.

    :return: API Collection object.
    """
    # Camera
    cam_tfm = maya.cmds.createNode('transform',
                                   name='cam_tfm')
    cam_shp = maya.cmds.createNode('camera',
                                   name='cam_shp',
                                   parent=cam_tfm)
    maya.cmds.setAttr(cam_tfm + '.tx', -1.0)
    maya.cmds.setAttr(cam_tfm + '.ty',  1.0)
    maya.cmds.setAttr(cam_tfm + '.tz', -5.0)
    cam = mmapi.Camera(shape=cam_shp)

    # Bundle
    bnd = mmapi.Bundle().create_node()
    bundle_tfm = bnd.get_node()
    maya.cmds.setAttr(bundle_tfm + '.tx', 5.5)
    maya.cmds.setAttr(bundle_tfm + '.ty', 6.4)
    maya.cmds.setAttr(bundle_tfm + '.tz', -25.0)
    assert mmapi.get_object_type(bundle_tfm) == 'bundle'

    # Marker
    mkr = mmapi.Marker().create_node(cam=cam, bnd=bnd)
    marker_tfm = mkr.get_node()
    assert mmapi.get_object_type(marker_tfm) == 'marker'
    maya.cmds.setAttr(marker_tfm + '.tx', 0.0)
    maya.cmds.setAttr(marker_tfm + '.ty', 0.0)

    # Attributes
    attr_tx = mmapi.Attribute(bundle_tfm + '.tx')
    attr_ty = mmapi.Attribute(bundle_tfm + '.ty')

    # Frames
    frm_list = [
        mmapi.Frame(1, primary=True)
    ]

    # Solver
    sol = mmapi.Solver()
    sol.set_max_iterations(10)
    sol.set_verbose(True)
    sol.set_frame_list(frm_list)

    # Collection
    col = mmapi.Collection()
    col.create_node('mySolveCollection')
    col.add_solver(sol)
    col.add_marker(mkr)
    col.add_attribute(attr_tx)
    col.add_attribute(attr_ty)
    return col
示例#12
0
def get_selected_markers():
    """
    Get selected Marker object.

    :rtype: list of mmSolver.api.Marker
    """
    nodes = maya.cmds.ls(selection=True, type='transform', long=True) or []
    mkr_nodes = mmapi.filter_marker_nodes(nodes)
    mkr_list = [mmapi.Marker(node=n) for n in mkr_nodes]
    return mkr_list
示例#13
0
def _runAndSetUsedSolveObjects(col_name, *args, **kwargs):
    """
    Call mmSolver, find (un)used objects, then set values for UIs to look up.

    :param col_name:
    :param args:
    :param kwargs:
    :return:
    """
    # Generate mmSolver command.
    import maya.cmds
    solver_args = args
    solver_kwargs = kwargs.copy()
    del solver_kwargs['mode']
    solver_kwargs['frame'] = [1]  # 'mmSolver' must have a frame value
    solver_kwargs['printStatistics'] = ['usedSolveObjects']
    data = maya.cmds.mmSolver(*solver_args, **solver_kwargs)

    markers_used = _parse_usage_list('markers_used=', data)
    markers_unused = _parse_usage_list('markers_unused=', data)
    attributes_used = _parse_usage_list('attributes_used=', data)
    attributes_unused = _parse_usage_list('attributes_unused=', data)

    # Set usage value attributes on Markers and Attributes.
    import mmSolver.api as mmapi
    for mkr_node in markers_used:
        mkr = mmapi.Marker(node=mkr_node)
        mkr.set_used_hint(const.MARKER_USED_HINT_USED_VALUE)
    for mkr_node in markers_unused:
        mkr = mmapi.Marker(node=mkr_node)
        mkr.set_used_hint(const.MARKER_USED_HINT_NOT_USED_VALUE)

    col = mmapi.Collection(col_name)
    for node_attr in attributes_used:
        attr = mmapi.Attribute(name=node_attr)
        col.set_attribute_used_hint(attr, const.ATTRIBUTE_USED_HINT_USED_VALUE)
    for node_attr in attributes_unused:
        attr = mmapi.Attribute(name=node_attr)
        col.set_attribute_used_hint(attr,
                                    const.ATTRIBUTE_USED_HINT_NOT_USED_VALUE)
    return
示例#14
0
def main():
    """
    Renames selected markers and connected bundles.
    :return: None
    """
    selection = maya.cmds.ls(selection=True, long=True) or []

    selected_markers = filternodes.get_marker_nodes(selection)
    selected_markers.reverse()
    if not selected_markers:
        LOG.warning('Please select markers')
        return

    total_mkrs = len(selected_markers)
    title = const.TITLE
    message = const.MESSAGE
    text = const.MARKER_NAME

    marker_name = lib.prompt_for_new_node_name(title, message, text)

    # if user click cancel on prompt window it returns "None"
    if not marker_name:
        return

    mkr_suffix = const.MARKER_SUFFIX
    bnd_suffix = const.BUNDLE_SUFFIX

    if marker_name == text:
        bundle_name = const.BUNDLE_NAME
    else:
        bundle_name = marker_name

    for number, marker in enumerate(selected_markers):
        new_mkr_name = '%s%02d' % (marker_name,
                                   total_mkrs - number) + "_" + mkr_suffix
        mkr = mmapi.Marker(node=marker)
        mkr_node = mkr.get_node()
        maya.cmds.rename(mkr_node, new_mkr_name)

        bnd = mkr.get_bundle()
        # checking if marker is connected to bundle
        if not bnd:
            LOG.warning('Cannot find bundle connected to %s' % new_mkr_name)
            continue

        new_bnd_name = '%s%02d' % (bundle_name,
                                   total_mkrs - number) + "_" + bnd_suffix
        bnd_node = bnd.get_node()
        maya.cmds.rename(bnd_node, new_bnd_name)
    return
示例#15
0
def get_cameras_from_markers(nodes):
    mkr_nodes = filternodes.get_marker_nodes(nodes)
    cam_nodes = []
    cam_nodes_tmp = {}
    for mkr_node in mkr_nodes:
        mkr = mmapi.Marker(mkr_node)
        cam = mkr.get_camera()
        cam_tfm_node = cam.get_transform_node()
        cam_shp_node = cam.get_shape_node()
        if cam_shp_node not in cam_nodes_tmp:
            cam_nodes_tmp[cam_shp_node] = (cam_tfm_node, cam_shp_node)
    for key, value in cam_nodes_tmp.iteritems():
        cam_nodes.append(value)
    return cam_nodes
示例#16
0
def main():
    """
    Renames selected markers and connected bundles.
    """
    selection = maya.cmds.ls(selection=True, long=True) or []

    selected_markers = filternodes.get_marker_nodes(selection)
    if not selected_markers:
        LOG.warning('Please select markers')
        return

    title = const.TITLE
    message = const.MESSAGE
    text = const.MARKER_NAME
    marker_name = lib.prompt_for_new_node_name(title, message, text)
    # if user clicks cancel on prompt window it returns "None"
    if not marker_name:
        return

    mkr_suffix = const.MARKER_SUFFIX
    bnd_suffix = const.BUNDLE_SUFFIX
    if marker_name == text:
        bundle_name = const.BUNDLE_NAME
    else:
        bundle_name = marker_name

    total_mkrs = len(selected_markers)
    for number, marker in enumerate(reversed(selected_markers)):
        num_str = '%02d' % (total_mkrs - number)
        new_mkr_name = mmapi.get_marker_name(num_str,
                                             prefix=marker_name,
                                             suffix=mkr_suffix)

        mkr = mmapi.Marker(node=marker)
        mkr_node = mkr.get_node()
        maya.cmds.rename(mkr_node, new_mkr_name)

        bnd = mkr.get_bundle()
        # checking if marker is connected to bundle
        if not bnd:
            msg = 'Cannot find bundle connected to Marker; mkr_node=%r'
            LOG.warning(msg, mkr_node)
            continue

        new_bnd_name = mmapi.get_bundle_name(num_str,
                                             prefix=bundle_name,
                                             suffix=bnd_suffix)
        bnd_node = bnd.get_node()
        maya.cmds.rename(bnd_node, new_bnd_name)
    return
示例#17
0
def bake_offset():
    """
    Bakes offset for the selected markers.

    :return: None
    """
    selection = maya.cmds.ls(selection=True, long=True) or []
    selected_markers = mmapi.filter_marker_nodes(selection)
    if len(selected_markers) == 0:
        LOG.warning('Please select a marker to bake offset')
        return None

    marker_nodes = []
    for marker in selected_markers:
        marker = mmapi.Marker(node=marker)
        marker_node = marker.get_node()
        marker_nodes.append(marker_node)
    if not marker_nodes:
        LOG.warning('Please select a marker to bake offset')
        return None

    attrs = lib.get_attrs_for_offset(marker_nodes)
    anim_layer = const.ANIM_LAYER
    for attr in attrs:
        if not lib.is_in_layer(attr, anim_layer):
            text = 'Selected marker is not having a layer override'
            LOG.warning(text)
            return None
    if not lib.is_key_framed(attrs):
        maya.cmds.setKeyframe(attrs)

    for attr in attrs:
        first_frame, last_frame = lib.__get_first_last_frame(attr, anim_layer)
        input_a, input_b = lib.get_attr_blend_plugs(attr, anim_layer)
        input_a_value = lib.__get_attr_value_array(input_a, first_frame,
                                                   last_frame)
        input_b_value = lib.__get_attr_value_array(input_b, first_frame,
                                                   last_frame)
        new_array = list(map(operator.add, input_a_value, input_b_value))

        maya.cmds.animLayer(anim_layer, removeAttribute=attr, edit=True)
        lib.set_attr_value_array(attr, new_array, first_frame, last_frame)

    if maya.cmds.animLayer(anim_layer, attribute=True, query=True) is None:
        maya.cmds.delete(anim_layer)

    maya.cmds.select(selected_markers)
    maya.cmds.dgdirty(selected_markers)
    return
示例#18
0
def unlink_marker_bundle():
    """
    All selected markers are disconnected from their respective bundle.
    """
    sel = maya.cmds.ls(selection=True, long=True) or []
    mkr_nodes = filternodes.get_marker_nodes(sel)

    if len(mkr_nodes) == 0:
        msg = 'Please select one or more Markers.'
        LOG.warning(msg)
        return

    for mkr_node in mkr_nodes:
        mkr = mmapi.Marker(node=mkr_node)
        mkr.set_bundle(None)
    return
示例#19
0
def get_selected_cameras():
    """
    Return the (associated) Camera objects from the selection.

    :returns: Camera objects.
    :rtype: mmSolver.api.Camera
    """
    cams = []
    nodes = maya.cmds.ls(sl=True, long=True) or []

    added_cameras = []
    objects = mmapi.filter_nodes_into_categories(nodes)
    for node in objects['camera']:
        cam = None
        if maya.cmds.nodeType(node) == 'camera':
            cam = mmapi.Camera(shape=node)
        else:
            cam = mmapi.Camera(transform=node)
        if cam is None:
            continue
        shp_node = cam.get_shape_node()
        if shp_node not in added_cameras:
            cams.append(cam)
            added_cameras.append(shp_node)

    for node in objects['marker']:
        mkr = mmapi.Marker(node=node)
        cam = mkr.get_camera()
        if cam is None:
            continue
        shp_node = cam.get_shape_node()
        if shp_node not in added_cameras:
            cams.append(cam)
            added_cameras.append(shp_node)

    for node in objects['markergroup']:
        mkr_grp = mmapi.MarkerGroup(node=node)
        cam = mkr_grp.get_camera()
        if cam is None:
            continue
        shp_node = cam.get_shape_node()
        if shp_node not in added_cameras:
            cams.append(cam)
            added_cameras.append(shp_node)

    return cams
示例#20
0
def main():
    """
    Triangulate Bundle using camera and Marker.

    Usage:

    1) Select markers or bundles (or both).

    2) Run tool.

    3) Bundle is triangulated in TX, TY and TZ.
    """
    # Get Markers and Bundles
    sel = maya.cmds.ls(selection=True, long=True) or []
    filter_nodes = mmapi.filter_nodes_into_categories(sel)
    mkr_nodes = filter_nodes.get('marker', [])
    bnd_nodes = filter_nodes.get('bundle', [])
    if len(mkr_nodes) == 0 and len(bnd_nodes) == 0:
        msg = 'Please select at least one marker / bundle!'
        LOG.warning(msg)
        return

    # Get Bundles from Markers
    for mkr_node in mkr_nodes:
        mkr = mmapi.Marker(node=mkr_node)
        bnd = mkr.get_bundle()
        bnd_node = bnd.get_node()
        if bnd_node not in bnd_nodes:
            bnd_nodes.append(bnd_node)
    bnd_list = [mmapi.Bundle(node=node) for node in bnd_nodes]

    # Triangulate
    adjusted_bnd_node_list = []
    for bnd in bnd_list:
        lib.triangulate_bundle(bnd)
        adjusted_bnd_node_list.append(bnd.get_node())

    # Select all bundle nodes.
    if len(adjusted_bnd_node_list) > 0:
        maya.cmds.select(adjusted_bnd_node_list, replace=True)
    else:
        msg = 'No Bundle nodes found, see Script Editor for details.'
        LOG.warning(msg)
    return
示例#21
0
def __create_node(mkr_data, cam, mkr_grp, with_bundles):
    """
    Create a Marker object from a MarkerData object.

    :param mkr_data: The data to create the Marker with.
    :type mkr_data: MarkerData

    :param cam: Camera to create marker node underneath.
    :type cam: Camera

    :param mkr_grp: MarkerGroup to create marker underneath
    :type mkr_grp: MarkerGroup

    :param with_bundles: Create the Marker with Bundle attached?
    :type with_bundles: bool

    :returns: Created Marker and Bundle objects. If with_bundles is
              False, the Bundle object will be None.
    :rtype: (Marker, Bundle or None)
    """
    if isinstance(mkr_data, interface.MarkerData) is False:
        msg = 'mkr_data must be of type: %r'
        raise TypeError(msg % interface.MarkerData.__name__)
    if isinstance(with_bundles, bool) is False:
        msg = 'with_bundles must be of type: %r'
        raise TypeError(msg % bool.__name__)

    name = mkr_data.get_name()
    mkr_name = mmapi.get_new_marker_name(name)
    bnd_name = mmapi.get_new_bundle_name(name)
    bnd = None
    mmapi.load_plugin()
    if with_bundles is True:
        bnd = mmapi.Bundle().create_node(bnd_name)
    if cam and mkr_grp:
        cam = None
    mkr = mmapi.Marker().create_node(
        name=mkr_name,
        cam=cam,
        mkr_grp=mkr_grp,
        bnd=bnd)
    return mkr, bnd
示例#22
0
def create_offset_layer():
    """
    Creates anim layer for the selected markers.

    :return: None
    """
    selection = maya.cmds.ls(selection=True, long=True) or []
    selected_markers = mmapi.filter_marker_nodes(selection)
    if len(selected_markers) == 0:
        LOG.warning('Please select a marker to create offset')
        return None

    marker_nodes = []
    for marker in selected_markers:
        marker = mmapi.Marker(node=marker)
        marker_node = marker.get_node()
        marker_nodes.append(marker_node)

    if not marker_nodes:
        LOG.warning('Please select a marker to create offset')
        return None

    attrs = lib.get_attrs_for_offset(marker_nodes)
    if attrs is None:
        LOG.warning('Please select marker to create override')
        return None

    anim_layer_name = const.ANIM_LAYER
    anim_layer = lib.find_animlayer(anim_layer_name)

    for attr in attrs:
        if lib.is_in_layer(attr, anim_layer):
            LOG.warning('Selected marker is already having a override')
            return None

    maya.cmds.animLayer(anim_layer, attribute=attrs, edit=True)
    return None
示例#23
0
def place_marker():
    """
    Called each time the user left-clicks in the viewport.
    """
    nodes = maya.cmds.ls(
        selection=True,
        long=True,
        type='transform'
    ) or []
    if len(nodes) == 0:
        msg = 'No nodes selected! Please select Marker nodes to place.'
        LOG.warning(msg)
        return
    mkr_nodes = mmapi.filter_marker_nodes(nodes)
    if len(mkr_nodes) == 0:
        msg = 'No Marker nodes selected!'
        LOG.warning(msg)
        return
    mkr_list = [mmapi.Marker(node=n) for n in mkr_nodes]
    if len(mkr_list) == 0:
        msg = 'No Marker nodes!'
        LOG.warning(msg)
        return

    # Get viewport coordinate. Viewport coordinate is relative to the
    # viewport resolution in pixels.
    vpX, vpY, vpZ = maya.cmds.draggerContext(
        const.CTX,
        query=True,
        dragPoint=True)

    view = OpenMayaUI.M3dView().active3dView()

    # Get the camera nodes from 3D viewport.
    camDag = view.getCamera()
    camShp = camDag.fullPathName()
    camDag.pop()
    camTfm = camDag.fullPathName()

    # 'Image resolution' is used to make sure the film back aspect
    # ratio is respected.
    imageWidth = maya.cmds.getAttr(camShp + '.horizontalFilmAperture') * 100.0
    imageHeight = maya.cmds.getAttr(camShp + '.verticalFilmAperture') * 100.0

    # Get the world-space location for the clicked point.
    position = OpenMaya.MPoint()
    direction = OpenMaya.MVector()
    view.viewToWorld(
        int(vpX),
        int(vpY),
        position,
        direction)

    # Compute the Marker coordinates for the given camera.
    frame = maya.cmds.currentTime(query=True)
    coord = maya.cmds.mmReprojection(
        worldPoint=(position.x, position.y, position.z),
        camera=(camTfm, camShp),
        asMarkerCoordinate=True,
        imageResolution=(imageWidth, imageHeight),
        time=frame
    )
    if coord is None:
        msg = 'Could not get Marker coordinate.'
        LOG.warning(msg)
        return
    assert len(coord) == 3

    # Set the marker position
    for mkr in mkr_list:
        mkr_grp = mkr.get_marker_group()
        mkr_grp_node = mkr_grp.get_node()
        plug_overscan_x = mkr_grp_node + '.overscanX'
        plug_overscan_y = mkr_grp_node + '.overscanY'
        overscan_x = maya.cmds.getAttr(plug_overscan_x)
        overscan_y = maya.cmds.getAttr(plug_overscan_y)
        node = mkr.get_node()
        plug_tx = node + '.translateX'
        plug_ty = node + '.translateY'
        value_tx = coord[0] * overscan_x
        value_ty = coord[1] * overscan_y
        lock_tx = maya.cmds.getAttr(plug_tx, lock=True)
        lock_ty = maya.cmds.getAttr(plug_tx, lock=True)
        if lock_tx is False and lock_ty is False:
            maya.cmds.setAttr(plug_tx, value_tx)
            maya.cmds.setAttr(plug_ty, value_ty)
        else:
            msg = 'Did not set Marker position, node is locked; node=%r'
            LOG.warning(msg, node)

    maya.cmds.select(nodes, replace=True)
    maya.cmds.refresh()
    return
示例#24
0
def reset_marker_used_hints(mkr_nodes):
    import mmSolver.api as mmapi
    for mkr_node in mkr_nodes:
        mkr = mmapi.Marker(node=mkr_node)
        mkr.set_used_hint(const.MARKER_USED_HINT_UNKNOWN_VALUE)
    return
    def test_init(self):
        """
        Single Frame solve.
        """
        # Camera
        cam_tfm = maya.cmds.createNode('transform',
                                       name='cam_tfm')
        cam_shp = maya.cmds.createNode('camera',
                                       name='cam_shp',
                                       parent=cam_tfm)
        maya.cmds.setAttr(cam_tfm + '.tx', -1.0)
        maya.cmds.setAttr(cam_tfm + '.ty',  1.0)
        maya.cmds.setAttr(cam_tfm + '.tz', -5.0)
        cam = mmapi.Camera(shape=cam_shp)

        # Bundle
        bnd = mmapi.Bundle().create_node()
        bundle_tfm = bnd.get_node()
        maya.cmds.setAttr(bundle_tfm + '.tx', 5.5)
        maya.cmds.setAttr(bundle_tfm + '.ty', 6.4)
        maya.cmds.setAttr(bundle_tfm + '.tz', -25.0)
        assert mmapi.get_object_type(bundle_tfm) == 'bundle'

        # Marker
        mkr = mmapi.Marker().create_node(cam=cam, bnd=bnd)
        marker_tfm = mkr.get_node()
        assert mmapi.get_object_type(marker_tfm) == 'marker'
        maya.cmds.setAttr(marker_tfm + '.tx', 0.0)
        maya.cmds.setAttr(marker_tfm + '.ty', 0.0)

        # Attributes
        attr_tx = mmapi.Attribute(bundle_tfm + '.tx')
        attr_ty = mmapi.Attribute(bundle_tfm + '.ty')

        # Frames
        frm_list = [
            mmapi.Frame(1, primary=True)
        ]

        # Solver
        sol = mmapi.Solver()
        sol.set_max_iterations(10)
        sol.set_solver_type(mmapi.SOLVER_TYPE_DEFAULT)
        sol.set_verbose(True)
        sol.set_frame_list(frm_list)

        # Collection
        col = mmapi.Collection()
        col.create_node('mySolveCollection')
        col.add_solver(sol)
        col.add_marker(mkr)
        col.add_attribute(attr_tx)
        col.add_attribute(attr_ty)

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

        # Run solver!
        results = col.execute()

        # Set Deviation
        mmapi.update_deviation_on_markers([mkr], results)
        mmapi.update_deviation_on_collection(col, results)

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

        # Ensure the values are correct
        self.checkSolveResults(results)
        # assert self.approx_equal(maya.cmds.getAttr(bundle_tfm+'.tx'), -6.0)
        # assert self.approx_equal(maya.cmds.getAttr(bundle_tfm+'.ty'), 3.6)
        return
    def test_stA_refine_good_solve(self):
        """
        Test file based on 3DEqualizer 'stA' image sequence.

        The Maya file loaded contains a good 3DEqualizer solve.  This
        test tests the solver to ensure it produces good results,
        given an already good solution.

        The 'stA' image sequence has a frame range of 0 to 94.
        """
        start_frame = 0
        end_frame = 94

        path = self.get_data_path('scenes', 'stA', 'stA.ma')
        ok = maya.cmds.file(path, open=True, ignoreVersion=True, force=True)
        assert isinstance(ok, (str, unicode))

        # Camera
        cam_name = 'stA_1_1Shape1'
        cam = mmapi.Camera(shape=cam_name)
        cam_tfm_node = cam.get_transform_node()
        cam_shp_node = cam.get_shape_node()

        # Marker Group
        mkr_grp_name = 'markerGroup1'
        mkr_grp = mmapi.MarkerGroup(node=mkr_grp_name)
        mkr_grp_node = mkr_grp.get_node()

        # Markers
        mkr_list = []
        bnd_list = []
        mkr_nodes = maya.cmds.listRelatives(
            mkr_grp_node,
            children=True,
            shapes=False) or []
        for node in mkr_nodes:
            if node.endswith('_MKR') is False:
                continue
            assert mmapi.get_object_type(node) == 'marker'
            mkr = mmapi.Marker(node=node)
            bnd = mkr.get_bundle()
            mkr_list.append(mkr)
            bnd_list.append(bnd)
        assert len(mkr_list) > 0
        assert len(bnd_list) > 0

        # Attributes
        attr_list = []
        for bnd in bnd_list:
            bnd_node = bnd.get_node()
            attr_tx = mmapi.Attribute(node=bnd_node, attr='tx')
            attr_ty = mmapi.Attribute(node=bnd_node, attr='ty')
            attr_tz = mmapi.Attribute(node=bnd_node, attr='tz')
            attr_list.append(attr_tx)
            attr_list.append(attr_ty)
            attr_list.append(attr_tz)
        attr_tx = mmapi.Attribute(node=cam_tfm_node, attr='tx')
        attr_ty = mmapi.Attribute(node=cam_tfm_node, attr='ty')
        attr_tz = mmapi.Attribute(node=cam_tfm_node, attr='tz')
        attr_rx = mmapi.Attribute(node=cam_tfm_node, attr='rx')
        attr_ry = mmapi.Attribute(node=cam_tfm_node, attr='ry')
        attr_rz = mmapi.Attribute(node=cam_tfm_node, attr='rz')
        attr_fl = mmapi.Attribute(node=cam_shp_node, attr='focalLength')
        attr_list.append(attr_tx)
        attr_list.append(attr_ty)
        attr_list.append(attr_tz)
        attr_list.append(attr_rx)
        attr_list.append(attr_ry)
        attr_list.append(attr_rz)
        attr_list.append(attr_fl)

        # Frames
        frm_list = []
        root_frm_list = []
        not_root_frm_list = []
        all_frames = range(start_frame, end_frame + 1, 1)
        for f in all_frames:
            prim = ((float(f) % 20.0) == 0) \
                   or (f == start_frame) \
                   or (f == end_frame)
            sec = prim is not True
            frm = mmapi.Frame(f, primary=prim, secondary=sec)
            if prim is True:
                root_frm_list.append(frm)
            else:
                not_root_frm_list.append(frm)
            frm_list.append(frm)

        # Solvers
        sol_list = []
        print_stats = False
        use_solver_steps = False
        if print_stats is True:
            # Print statistics
            stats_sol = mmapi.SolverStep()
            stats_sol.set_verbose(False)
            stats_sol.set_frame_list(frm_list)
            stats_sol.set_print_statistics_inputs(True)
            stats_sol.set_print_statistics_affects(True)
            stats_sol.set_print_statistics_deviation(True)
            sol_list.append(stats_sol)
        if use_solver_steps is True:
            # Global solve with every 10th frame (and start/end frames)
            sol = mmapi.SolverStep()
            sol.set_verbose(False)
            sol.set_max_iterations(10)
            sol.set_frames_use_tags(['primary'])
            sol.set_attributes_use_static(True)
            sol.set_attributes_use_animated(True)
            sol.set_frame_list(frm_list)
            sol_list.append(sol)

            # Per-frame solvers
            for frm in frm_list:
                sol = mmapi.SolverStep()
                sol.set_verbose(False)
                sol.set_max_iterations(10)
                sol.set_frames_use_tags(['primary', 'secondary'])
                sol.set_attributes_use_static(False)
                sol.set_attributes_use_animated(True)
                sol.set_frame_list([frm])
                sol_list.append(sol)
        else:
            # Solver
            sol = mmapi.SolverStandard()
            sol.set_root_frame_list(root_frm_list)
            sol.set_frame_list(not_root_frm_list)
            sol.set_only_root_frames(False)
            sol.set_global_solve(False)
            sol._triangulate_bundles = False
            sol._auto_attr_blocks = False
            sol.set_use_single_frame(False)
            sol_list.append(sol)

        # Collection
        col = mmapi.Collection()
        col.create_node('mySolveCollection')
        col.set_solver_list(sol_list)
        col.add_marker_list(mkr_list)
        col.add_attribute_list(attr_list)

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

        # Run solver!
        LOG.warning('Running Solver Test... (it may take some time to finish).')
        results = col.execute()

        # Set Deviation
        mmapi.update_deviation_on_markers(mkr_list, results)
        mmapi.update_deviation_on_collection(col, results)

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

        self.checkSolveResults(results)
        return
示例#27
0
def main():
    """
    Main function runs duplicate marker on all selected markers.
    """
    selection = maya.cmds.ls(selection=True, long=True) or []
    selected_markers = mmapi.filter_marker_nodes(selection)
    if not selected_markers:
        LOG.warning('Please select markers')
        return

    mkr_selection = selected_markers[0]
    mkr = mmapi.Marker(node=mkr_selection)
    # getting camera from the selected marker
    cam_from_mkr = mkr.get_camera()

    new_mkr_nodes = []
    for marker in selected_markers:
        # Get Marker's name
        mkr = mmapi.Marker(node=marker)
        # old_mkr_node is expected to be a long name.
        old_mkr_node = mkr.get_node()
        if old_mkr_node is None:
            LOG.warning('Invalid Marker, skipping duplicate.')
            continue
        mkr_name = old_mkr_node.rpartition('|')[-1]
        mkr_name = mkr_name[0].upper() + mkr_name[1:]
        mkr_name = 'dup' + mkr_name

        # Get Bundles's name
        bnd_name = 'dupBundle1'
        bnd = mkr.get_bundle()
        if bnd is None:
            pass
        else:
            bnd_node = bnd.get_node()
            bnd_name = bnd_node.rpartition('|')[-1]
            bnd_name = bnd_name[0].upper() + bnd_name[1:]
            bnd_name = 'dup' + bnd_name

        # get attrs lock state
        lock_value = lib.__get_lock_state(marker, const.MKR_ATTRS)

        mkr_name = mmapi.get_new_marker_name(mkr_name)
        new_mkr = mmapi.Marker().create_node(cam=cam_from_mkr, name=mkr_name)
        new_mkr_node = new_mkr.get_node()
        bnd_name = mmapi.get_new_bundle_name(bnd_name)
        new_bnd = mmapi.Bundle().create_node(name=bnd_name)
        # connecting bundle to the marker
        new_mkr.set_bundle(new_bnd)

        # running duplicate
        lib.__copy_key_frames(marker, new_mkr_node)

        # set lock state on newly created markers
        lib.__set_lock_state(marker, new_mkr_node, const.MKR_ATTRS, lock_value)
        new_mkr_nodes.append(new_mkr_node)

    if len(new_mkr_nodes) > 0:
        maya.cmds.select(new_mkr_nodes, replace=True)
    else:
        # Restore the original selection.
        maya.cmds.select(selection, replace=True)
    return
    def test_marker_enable(self):
        start = 1
        end = 5

        # Set Time Range
        maya.cmds.playbackOptions(
            animationStartTime=start,
            minTime=start,
            animationEndTime=end,
            maxTime=end
        )

        # Camera
        cam_tfm = maya.cmds.createNode('transform',
                                       name='cam_tfm')
        cam_shp = maya.cmds.createNode('camera',
                                       name='cam_shp',
                                       parent=cam_tfm)
        maya.cmds.setAttr(cam_tfm + '.tx', -1.0)
        maya.cmds.setAttr(cam_tfm + '.ty',  1.0)
        maya.cmds.setAttr(cam_tfm + '.tz', -5.0)
        cam = mmapi.Camera(shape=cam_shp)

        # Bundle
        bnd = mmapi.Bundle().create_node()
        bundle_tfm = bnd.get_node()
        maya.cmds.setAttr(bundle_tfm + '.tx', 5.5)
        maya.cmds.setAttr(bundle_tfm + '.ty', 6.4)
        maya.cmds.setAttr(bundle_tfm + '.tz', -25.0)
        assert mmapi.get_object_type(bundle_tfm) == 'bundle'

        # calculate angle of view (AOV)
        f = maya.cmds.getAttr(cam_shp + '.focalLength')
        fbw = maya.cmds.getAttr(cam_shp + '.horizontalFilmAperture') * 25.4
        fbh = maya.cmds.getAttr(cam_shp + '.verticalFilmAperture') * 25.4
        aov = math.degrees(2.0 * math.atan(fbw * (0.5 / f)))

        # Set Camera Anim
        maya.cmds.setKeyframe(cam_tfm, attribute='rotateY', time=start, value=-(aov/2),
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(cam_tfm, attribute='rotateY', time=end, value=(aov/2),
                              inTangentType='linear',
                              outTangentType='linear')

        # Marker
        mkr = mmapi.Marker().create_node(cam=cam, bnd=bnd)
        marker_tfm = mkr.get_node()
        assert mmapi.get_object_type(marker_tfm) == 'marker'
        mid_value = 0.23534346
        maya.cmds.setKeyframe(marker_tfm, attribute='translateX', time=start, value=-0.5,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm, attribute='translateX', time=start+1,
                              value=-mid_value,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm, attribute='translateX', time=end-1,
                              value=mid_value,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm, attribute='translateX', time=end, value=0.5,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setAttr(marker_tfm + '.ty', 0.0)

        maya.cmds.setKeyframe(marker_tfm, attribute='enable', time=1, value=1,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm, attribute='enable', time=2, value=1,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm, attribute='enable', time=3, value=0,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm, attribute='enable', time=4, value=1,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm, attribute='enable', time=5, value=1,
                              inTangentType='linear',
                              outTangentType='linear')

        # Create Sphere
        sph_tfm, shp_node = maya.cmds.polySphere()
        maya.cmds.setAttr(sph_tfm + '.tx', -1.0)
        maya.cmds.setAttr(sph_tfm + '.ty', 1.0)
        maya.cmds.setAttr(sph_tfm + '.tz', -25.0)

        # Attributes
        attr_tx = mmapi.Attribute(bundle_tfm + '.tx')
        attr_ty = mmapi.Attribute(bundle_tfm + '.ty')

        # Frames
        frm_list = [
            mmapi.Frame(1, primary=True),
            mmapi.Frame(2, primary=True),
            mmapi.Frame(3, primary=True),
            mmapi.Frame(4, primary=True),
            mmapi.Frame(5, primary=True)
        ]

        # Solver
        sol = mmapi.Solver()
        sol.set_max_iterations(1000)
        sol.set_solver_type(mmapi.SOLVER_TYPE_DEFAULT)
        sol.set_verbose(True)
        sol.set_frame_list(frm_list)

        # Collection
        col = mmapi.Collection()
        col.create_node('mySolveCollection')
        col.add_solver(sol)
        col.add_marker(mkr)
        col.add_attribute(attr_tx)
        col.add_attribute(attr_ty)

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

        # Run solver!
        results = col.execute()

        # Ensure the values are correct
        for res in results:
            success = res.get_success()
            err = res.get_final_error()
            print('error stats: ' + pprint.pformat(res.get_error_stats()))
            print('timer stats: ' + pprint.pformat(res.get_timer_stats()))
            print('solver stats: ' + pprint.pformat(res.get_solver_stats()))
            print('frame error list: ' + pprint.pformat(dict(res.get_frame_error_list())))
            print('marker error list: ' + pprint.pformat(dict(res.get_marker_error_list())))

            self.assertTrue(success)
            # self.assertGreater(0.001, err)
        # assert self.approx_equal(maya.cmds.getAttr(bundle_tfm+'.tx'), -6.0)
        # assert self.approx_equal(maya.cmds.getAttr(bundle_tfm+'.ty'), 3.6)

        # Set Deviation
        mmapi.update_deviation_on_markers([mkr], results)
        mmapi.update_deviation_on_collection(col, results)

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

        self.checkSolveResults(results)
        return
示例#29
0
def main():
    """
    Ray casts selected markers bundles on mesh from the associated camera.

    Select markers and mesh objects to ray cast on, if not mesh
    objects tool will ray cast on all visible mesh objects.

    If a bundle translate attribute is locked, it will be
    unlocked, then projected, and then the lock state will
    be reverted to the original value.

    Example::

        >>> import mmSolver.tools.raycastmarker.tool as tool
        >>> tool.main()
    """
    selection = maya.cmds.ls(selection=True) or []
    if not selection:
        LOG.warning('Please select a marker to rayCast.')
        return

    selected_markers = filternodes.get_marker_nodes(selection)
    if not selected_markers:
        LOG.warning('No markers found in the selection list.')
        return

    meshes = []
    selected_meshes = maya.cmds.ls(
        sl=True,
        type='mesh',
        dagObjects=True,
        noIntermediate=True) or []
    if len(selected_meshes) > 0:
        meshes = selected_meshes
    else:
        meshes = maya.cmds.ls(type='mesh', visible=True) or []

    max_dist = 9999999999.0
    bnd_nodes = []
    for node in selected_markers:
        mkr = mmapi.Marker(node=node)
        bnd = mkr.get_bundle()
        if bnd is None:
            continue
        mkr_node = mkr.get_node()
        camera = mkr.get_camera()
        camera = camera.get_transform_node()
        direction = __get_camera_direction_to_point(camera, mkr_node)
        origin_point = maya.cmds.xform(
            mkr_node, query=True,
            translation=True,
            worldSpace=True
        )

        hit_point = raytrace_utils.closest_intersect(
            origin_point,
            direction,
            meshes,
            test_both_directions=True,
            max_dist=max_dist,
        )
        if hit_point is None:
            LOG.warning('%s didn\'t hit the mesh.' % node)
            continue

        bnd_node = bnd.get_node()
        plugs = [
            '%s.translateX' % bnd_node,
            '%s.translateY' % bnd_node,
            '%s.translateZ' % bnd_node
        ]
        plug_lock_state = {}
        for plug_name in plugs:
            value = maya.cmds.getAttr(plug_name, lock=True)
            plug_lock_state[plug_name] = value
            maya.cmds.setAttr(plug_name, lock=False)
        hit_xyz = (hit_point.x, hit_point.y, hit_point.z)
        maya.cmds.xform(
            bnd_node,
            translation=hit_xyz,
            worldSpace=True,
        )
        for plug_name in plugs:
            value = plug_lock_state.get(plug_name)
            maya.cmds.setAttr(plug_name, lock=value)
        bnd_nodes.append(bnd_node)
        
    if len(bnd_nodes) > 0:
        maya.cmds.select(bnd_nodes)
    else:
        maya.cmds.select(selection)
    return
    def test_per_frame(self):
        """
        Solve animated values, per-frame.
        """
        # Camera
        cam_tfm = maya.cmds.createNode('transform',
                                       name='cam_tfm')
        cam_shp = maya.cmds.createNode('camera',
                                       name='cam_shp',
                                       parent=cam_tfm)
        maya.cmds.setAttr(cam_tfm + '.tx', -1.0)
        maya.cmds.setAttr(cam_tfm + '.ty',  1.0)
        maya.cmds.setAttr(cam_tfm + '.tz', -5.0)
        cam = mmapi.Camera(shape=cam_shp)

        # Bundle
        bnd = mmapi.Bundle().create_node()
        bundle_tfm = bnd.get_node()
        maya.cmds.setAttr(bundle_tfm + '.tx', 5.5)
        maya.cmds.setAttr(bundle_tfm + '.ty', 6.4)
        maya.cmds.setAttr(bundle_tfm + '.tz', -25.0)
        assert mmapi.get_object_type(bundle_tfm) == 'bundle'
        maya.cmds.setKeyframe(bundle_tfm,
                              attribute='translateX',
                              time=1, value=5.5,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(bundle_tfm,
                              attribute='translateY',
                              time=1, value=6.4,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(bundle_tfm,
                              attribute='translateZ',
                              time=1, value=-25.0,
                              inTangentType='linear',
                              outTangentType='linear')

        # Marker
        mkr = mmapi.Marker().create_node(cam=cam, bnd=bnd)
        marker_tfm = mkr.get_node()
        assert mmapi.get_object_type(marker_tfm) == 'marker'
        # maya.cmds.setAttr(marker_tfm + '.tx', 0.0)
        # maya.cmds.setAttr(marker_tfm + '.ty', 0.0)
        maya.cmds.setKeyframe(marker_tfm,
                              attribute='translateX',
                              time=1, value=-0.5,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm,
                              attribute='translateX',
                              time=5, value=0.5,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm,
                              attribute='translateY',
                              time=1, value=-0.5,
                              inTangentType='linear',
                              outTangentType='linear')
        maya.cmds.setKeyframe(marker_tfm,
                              attribute='translateY',
                              time=5, value=0.5,
                              inTangentType='linear',
                              outTangentType='linear')

        # Attributes
        attr_tx = mmapi.Attribute(bundle_tfm + '.tx')
        attr_ty = mmapi.Attribute(bundle_tfm + '.ty')

        # Frames
        frm_list = [
            mmapi.Frame(1),
            mmapi.Frame(2),
            mmapi.Frame(3),
            mmapi.Frame(4),
            mmapi.Frame(5),
        ]

        # Solver
        sol_list = []
        for frm in frm_list:
            sol = mmapi.Solver()
            sol.set_max_iterations(10)
            sol.set_verbose(True)
            sol.set_frame_list([frm])
            sol_list.append(sol)

        # Collection
        col = mmapi.Collection()
        col.create_node('mySolveCollection')
        col.add_solver_list(sol_list)
        col.add_marker(mkr)
        col.add_attribute(attr_tx)
        col.add_attribute(attr_ty)

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

        # Run solver!
        results = col.execute()

        # Set Deviation
        mmapi.update_deviation_on_markers([mkr], results)
        mmapi.update_deviation_on_collection(col, results)

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

        self.checkSolveResults(results)
        return