def _do_raycast(node_list, mesh_nodes, frame_range, max_dist, use_smooth_mesh):
    bnd_nodes = set()
    cur_frame = maya.cmds.currentTime(query=True)
    if frame_range is None:
        frame_range = time_utils.FrameRange(int(cur_frame), int(cur_frame))
    frames = range(frame_range.start, frame_range.end + 1)
    is_multi_frame = len(frames) > 1
    for frame in frames:
        maya.cmds.currentTime(frame, edit=True, update=True)
        for mkr_node, bnd_node, cam_tfm in node_list:
            assert bnd_node is not None
            assert cam_tfm is not None

            direction = reproject_utils.get_camera_direction_to_point(
                cam_tfm, mkr_node)
            origin_point = maya.cmds.xform(mkr_node,
                                           query=True,
                                           translation=True,
                                           worldSpace=True)
            hit_point = raytrace_utils.closest_intersect(
                origin_point,
                direction,
                mesh_nodes,
                test_both_directions=False,
                max_dist=max_dist,
                use_smooth_mesh=use_smooth_mesh)
            if hit_point is None:
                if is_multi_frame is False:
                    LOG.warn("%s didn't hit the mesh.", mkr_node)
                continue

            hit_xyz = (hit_point.x, hit_point.y, hit_point.z)
            maya.cmds.xform(
                bnd_node,
                translation=hit_xyz,
                worldSpace=True,
            )
            if is_multi_frame is True:
                maya.cmds.setKeyframe(bnd_node, attribute=BND_ATTRS)
            bnd_nodes.add(bnd_node)
    maya.cmds.currentTime(cur_frame, edit=True, update=True)
    return bnd_nodes
Exemple #2
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