Exemplo n.º 1
0
def DelStaticFunction():
    cmds.commandEcho(ln=False)

    #define UI information
    channelCheck = getChannelCheck()
    channelBox_attrs = channelBoxList(channelCheck)
    appliedChannels = appliedChannelList(channelCheck)
    [start, end] = defineTimeRange()

    #create objLists
    objLists = cmds.ls(sl=True)

    #undo
    cmds.undoInfo(openChunk=True)

    for obj in objLists:
        #define channels
        [keyable_channels,
         channels] = common(obj, channelCheck, channelBox_attrs,
                            appliedChannels, start, end)

        if len(channels) != 0:
            for channel in channels:
                #get key information
                key_values = cmds.keyframe('{0}.{1}'.format(obj, channel),
                                           q=True,
                                           t=(start, end),
                                           valueChange=True)
                key_numbers = cmds.keyframe('{0}.{1}'.format(obj, channel),
                                            q=True,
                                            t=(start, end),
                                            iv=True)
                key_outTangents = cmds.keyTangent('{0}.{1}'.format(
                    obj, channel),
                                                  q=True,
                                                  t=(start, end),
                                                  outAngle=True)

                #define static_index list
                static_index = []

                if len(key_values) == 1:
                    static_index.append((0, ))
                else:
                    static_index = getstatic_index(key_outTangents, key_values,
                                                   key_numbers, static_index)

                if len(static_index) != 0:
                    cmds.cutKey(obj,
                                at=channel,
                                clear=True,
                                index=static_index)
                else:
                    continue
        else:
            continue

    cmds.undoInfo(closeChunk=True)
Exemplo n.º 2
0
 def context_menu():
     """
     Create context menu for output window.
     """
     # context menu
     output_win = cmds.cmdScrollFieldReporter(SCRIPT_OUTPUT_SCROLLFIELD, fst="")
     cmds.popupMenu(parent=output_win)
     cmds.menuItem(
         label="Clear Output", command=lambda c: cmds.cmdScrollFieldReporter(output_win, e=True, clear=True)
     )
     # Echo all commands toggle
     cmds.menuItem(
         label="Toggle Echo Commands",
         command=lambda c: cmds.commandEcho(state=not (cmds.commandEcho(q=True, state=True))),
     )
     # Go to python reference
     cmds.menuItem(label="Python Command Reference", command=lambda c: cmds.showHelp("DocsPythonCommands"))
Exemplo n.º 3
0
def script_output(direction):
    """
    Script output dock for layouts.
    """
    dock_control = config['WINDOW_SCRIPT_OUTPUT_DOCK']
    dock_window = config['WINDOW_SCRIPT_OUTPUT']
    if cmds.dockControl(dock_control, ex=True):
        return cmds.dockControl(dock_control, e=True, vis=True, fl=False)

    if cmds.window(dock_window, ex=True):
        main_win = dock_window
    else:
        main_win = cmds.window(dock_window, title='Output Window')

    cmds.paneLayout(parent=main_win)

    # context menu
    output_win = cmds.cmdScrollFieldReporter(fst="")
    cmds.popupMenu(parent=output_win)
    cmds.menuItem(
        label='Clear Output',
        command=lambda c: cmds.cmdScrollFieldReporter(
            output_win, e=True, clear=True),
    )
    # Echo all commands toggle
    cmds.menuItem(
        label='Toggle Echo Commands',
        command=lambda c: cmds.commandEcho(
            state=not(cmds.commandEcho(q=True, state=True))),
    )
    # Go to python reference
    cmds.menuItem(
        label='Python Command Reference',
        command=lambda c: cmds.showHelp('DocsPythonCommands'),
    )

    cmds.dockControl(
        dock_control,
        content=main_win,
        label='Output Window',
        area=direction,
        height=500,
        floating=False,
        allowedArea=['left', 'right']
    )
Exemplo n.º 4
0
def script_output(direction):
    """
    Script output dock for layouts.
    """
    dock_control = config['WINDOW_SCRIPT_OUTPUT_DOCK']
    dock_window = config['WINDOW_SCRIPT_OUTPUT']
    if cmds.dockControl(dock_control, ex=True):
        return cmds.dockControl(dock_control, e=True, vis=True, fl=False)

    if cmds.window(dock_window, ex=True):
        main_win = dock_window
    else:
        main_win = cmds.window(dock_window, title='Output Window')

    cmds.paneLayout(parent=main_win)

    # context menu
    output_win = cmds.cmdScrollFieldReporter(fst="")
    cmds.popupMenu(parent=output_win)
    cmds.menuItem(
        label='Clear Output',
        command=lambda c: cmds.cmdScrollFieldReporter(
            output_win, e=True, clear=True),
    )
    # Echo all commands toggle
    cmds.menuItem(
        label='Toggle Echo Commands',
        command=lambda c: cmds.commandEcho(state=not (cmds.commandEcho(
            q=True, state=True))),
    )
    # Go to python reference
    cmds.menuItem(
        label='Python Command Reference',
        command=lambda c: cmds.showHelp('DocsPythonCommands'),
    )

    cmds.dockControl(dock_control,
                     content=main_win,
                     label='Output Window',
                     area=direction,
                     height=500,
                     floating=False,
                     allowedArea=['left', 'right'])
Exemplo n.º 5
0
    def eval(cls, cmd):
        """
        evaluate a string as a mel command and return the result.

        Behaves like maya.mel.eval, with several improvements:
            - returns pymel `Vector` and `Matrix` classes
            - when an error is encountered a `MelError` exception is raised, along with the line number (if enabled) and exact mel error.

        >>> mel.eval( 'attributeExists("persp", "translate")' )
        0
        >>> mel.eval( 'interToUI( "fooBarSpangle" )' )
        u'Foo Bar Spangle'

        """
        # should return a value, like _mm.eval
        #return _mm.eval( cmd )
        # get this before installing the callback
        undoState = _mc.undoInfo(q=1, state=1)
        lineNumbers = _mc.commandEcho(q=1, lineNumbers=1)
        _mc.commandEcho(lineNumbers=1)
        global errors
        errors = []  # a list to store each error line

        def errorCallback(nativeMsg, messageType, data):
            global errors
            if messageType == _api.MCommandMessage.kError:
                if nativeMsg:
                    errors += [nativeMsg]

        # setup the callback:
        # assigning ids to a list avoids the swig memory leak warning, which would scare a lot of people even though
        # it is harmless.  hoping we get a real solution to this so that we don't have to needlessly accumulate this data
        id = _api.MCommandMessage.addCommandOutputCallback(errorCallback, None)

        try:
            res = _api.MCommandResult()
            _api.MGlobal.executeCommand(cmd, res, False, undoState)
        except Exception:
            # these two lines would go in a finally block, but we have to maintain python 2.4 compatibility for maya 8.5
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()

            msg = '\n'.join(errors)

            if 'Cannot find procedure' in msg:
                e = MelUnknownProcedureError
            elif 'Wrong number of arguments' in msg:
                e = MelArgumentError
                if cls.proc:
                    # remove the calling proc, it will be added below
                    msg = msg.split('\n', 1)[1].lstrip()
            elif 'Cannot convert data' in msg or 'Cannot cast data' in msg:
                e = MelConversionError
            elif 'Syntax error' in msg:
                e = MelSyntaxError
            else:
                e = MelError
            message = "Error during execution of MEL script: %s" % (msg)
            fmtCmd = '\n'.join(['  ' + x for x in cmd.split('\n')])

            if cls.proc:
                if e is not MelUnknownProcedureError:
                    file = _mm.eval('whatIs "%s"' % cls.proc)
                    if file.startswith('Mel procedure found in: '):
                        file = 'file "%s"' % os.path.realpath(
                            file.split(':')[1].lstrip())
                    message += '\nCalling Procedure: %s, in %s' % (cls.proc,
                                                                   file)
                    message += '\n' + fmtCmd
            else:
                message += '\nScript:\n%s' % fmtCmd
            raise e, message
        else:
            # these two lines would go in a finally block, but we have to maintain python 2.4 compatibility for maya 8.5
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()
            resType = res.resultType()

            if resType == _api.MCommandResult.kInvalid:
                return
            elif resType == _api.MCommandResult.kInt:
                result = _api.SafeApiPtr('int')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kIntArray:
                result = _api.MIntArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kDouble:
                result = _api.SafeApiPtr('double')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kDoubleArray:
                result = _api.MDoubleArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kString:
                return res.stringResult()
            elif resType == _api.MCommandResult.kStringArray:
                result = []
                res.getResult(result)
                return result
            elif resType == _api.MCommandResult.kVector:
                result = _api.MVector()
                res.getResult(result)
                return datatypes.Vector(result)
            elif resType == _api.MCommandResult.kVectorArray:
                result = _api.MVectorArray()
                res.getResult(result)
                return [
                    datatypes.Vector(result[i]) for i in range(result.length())
                ]
            elif resType == _api.MCommandResult.kMatrix:
                result = _api.MMatrix()
                res.getResult(result)
                return datatypes.Matrix(result)
            elif resType == _api.MCommandResult.kMatrixArray:
                result = _api.MMatrixArray()
                res.getResult(result)
                return [
                    datatypes.Matrix(result[i]) for i in range(result.length())
                ]
Exemplo n.º 6
0
    def eval(cls, cmd):
        """
        evaluate a string as a mel command and return the result.

        Behaves like `maya.mel.eval`, with several improvements:
            - returns `pymel.datatype.Vector` and `pymel.datatype.Matrix`
              classes
            - when an error is encountered a `MelError` exception is raised,
              along with the line number (if enabled) and exact mel error.

        >>> mel.eval( 'attributeExists("persp", "translate")' )
        0
        >>> mel.eval( 'interToUI( "fooBarSpangle" )' )
        u'Foo Bar Spangle'

        """
        # should return a value, like _mm.eval
        # return _mm.eval( cmd )
        # get this before installing the callback
        undoState = _mc.undoInfo(q=1, state=1)
        lineNumbers = _mc.commandEcho(q=1, lineNumbers=1)
        _mc.commandEcho(lineNumbers=1)
        global errors
        errors = []  # a list to store each error line

        def errorCallback(nativeMsg, messageType, data):
            global errors
            if messageType == _api.MCommandMessage.kError:
                if nativeMsg:
                    errors += [nativeMsg]

        # setup the callback:
        # assigning ids to a list avoids the swig memory leak warning, which would scare a lot of people even though
        # it is harmless.  hoping we get a real solution to this so that we don't have to needlessly accumulate this data
        id = _api.MCommandMessage.addCommandOutputCallback(errorCallback, None)

        try:
            res = _api.MCommandResult()
            _api.MGlobal.executeCommand(cmd, res, False, undoState)
        except Exception:
            # these two lines would go in a finally block, but we have to maintain python 2.4 compatibility for maya 8.5
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()

            msg = '\n'.join(errors)

            if 'Cannot find procedure' in msg:
                e = MelUnknownProcedureError
            elif 'Wrong number of arguments' in msg:
                e = MelArgumentError
                if cls.proc:
                    # remove the calling proc, it will be added below
                    msg = msg.split('\n', 1)[1].lstrip()
            elif 'Cannot convert data' in msg or 'Cannot cast data' in msg:
                e = MelConversionError
            elif 'Syntax error' in msg:
                e = MelSyntaxError
            else:
                e = MelError
            message = "Error during execution of MEL script: %s" % (msg)
            fmtCmd = '\n'.join(['  ' + x for x in cmd.split('\n')])

            if cls.proc:
                if e is not MelUnknownProcedureError:
                    file = _mm.eval('whatIs "%s"' % cls.proc)
                    if file.startswith('Mel procedure found in: '):
                        file = 'file "%s"' % os.path.realpath(file.split(':')[1].lstrip())
                    message += '\nCalling Procedure: %s, in %s' % (cls.proc, file)
                    message += '\n' + fmtCmd
            else:
                message += '\nScript:\n%s' % fmtCmd
            raise e, message
        else:
            # these two lines would go in a finally block, but we have to maintain python 2.4 compatibility for maya 8.5
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()
            resType = res.resultType()

            if resType == _api.MCommandResult.kInvalid:
                return
            elif resType == _api.MCommandResult.kInt:
                result = _api.SafeApiPtr('int')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kIntArray:
                result = _api.MIntArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kDouble:
                result = _api.SafeApiPtr('double')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kDoubleArray:
                result = _api.MDoubleArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kString:
                return res.stringResult()
            elif resType == _api.MCommandResult.kStringArray:
                result = []
                res.getResult(result)
                return result
            elif resType == _api.MCommandResult.kVector:
                result = _api.MVector()
                res.getResult(result)
                return datatypes.Vector(result)
            elif resType == _api.MCommandResult.kVectorArray:
                result = _api.MVectorArray()
                res.getResult(result)
                return [datatypes.Vector(result[i]) for i in range(result.length())]
            elif resType == _api.MCommandResult.kMatrix:
                result = _api.MMatrix()
                res.getResult(result)
                return datatypes.Matrix(result)
            elif resType == _api.MCommandResult.kMatrixArray:
                result = _api.MMatrixArray()
                res.getResult(result)
                return [datatypes.Matrix(result[i]) for i in range(result.length())]
Exemplo n.º 7
0
    def _eval(cls, cmd, commandName):
        # commandName is just used for nicer formatting of error messages,
        # and is used by MelCallable

        # should return a value, like _mm.eval
        # return _mm.eval( cmd )
        # get this before installing the callback
        undoState = _mc.undoInfo(q=1, state=1)
        lineNumbers = _mc.commandEcho(q=1, lineNumbers=1)
        _mc.commandEcho(lineNumbers=1)
        global errors
        errors = []  # a list to store each error line

        def errorCallback(nativeMsg, messageType, data):
            global errors
            if messageType == _api.MCommandMessage.kError:
                if nativeMsg:
                    errors += [nativeMsg]

        # setup the callback:
        # assigning ids to a list avoids the swig memory leak warning, which would scare a lot of people even though
        # it is harmless.  hoping we get a real solution to this so that we don't have to needlessly accumulate this data
        id = _api.MCommandMessage.addCommandOutputCallback(errorCallback, None)

        try:
            res = _api.MCommandResult()
            _api.MGlobal.executeCommand(cmd, res, False, undoState)
        except Exception:
            msg = '\n'.join(errors)

            if 'Cannot find procedure' in msg:
                e = MelUnknownProcedureError
            elif 'Wrong number of arguments' in msg:
                e = MelArgumentError
                if commandName:
                    # remove the calling proc, it will be added below
                    msg = msg.split('\n', 1)[1].lstrip()
            elif 'Cannot convert data' in msg or 'Cannot cast data' in msg:
                e = MelConversionError
            elif 'Syntax error' in msg:
                e = MelSyntaxError
            else:
                e = MelError
            message = "Error during execution of MEL script: %s" % (msg)
            fmtCmd = '\n'.join(['  ' + x for x in cmd.split('\n')])

            if commandName:
                if e is not MelUnknownProcedureError:
                    file = _mm.eval('whatIs "%s"' % commandName)
                    if file.startswith('Mel procedure found in: '):
                        file = 'file "%s"' % os.path.realpath(file.split(':')[1].lstrip())
                    message += '\nCalling Procedure: %s, in %s' % (commandName, file)
                    message += '\n' + fmtCmd
            else:
                message += '\nScript:\n%s' % fmtCmd
            raise e, message
        else:
            resType = res.resultType()

            if resType == _api.MCommandResult.kInvalid:
                return
            elif resType == _api.MCommandResult.kInt:
                result = _api.SafeApiPtr('int')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kIntArray:
                result = _api.MIntArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kDouble:
                result = _api.SafeApiPtr('double')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kDoubleArray:
                result = _api.MDoubleArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kString:
                return res.stringResult()
            elif resType == _api.MCommandResult.kStringArray:
                result = []
                res.getResult(result)
                return result
            elif resType == _api.MCommandResult.kVector:
                result = _api.MVector()
                res.getResult(result)
                return datatypes.Vector(result)
            elif resType == _api.MCommandResult.kVectorArray:
                result = _api.MVectorArray()
                res.getResult(result)
                return [datatypes.Vector(result[i]) for i in range(result.length())]
            elif resType == _api.MCommandResult.kMatrix:
                result = _api.MMatrix()
                res.getResult(result)
                return datatypes.Matrix(result)
            elif resType == _api.MCommandResult.kMatrixArray:
                result = _api.MMatrixArray()
                res.getResult(result)
                return [datatypes.Matrix(result[i]) for i in range(result.length())]
        finally:
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()
Exemplo n.º 8
0
    def _eval(cls, cmd, commandName):
        # commandName is just used for nicer formatting of error messages,
        # and is used by MelCallable

        # should return a value, like _mm.eval
        # return _mm.eval( cmd )
        # get this before installing the callback
        undoState = _mc.undoInfo(q=1, state=1)
        lineNumbers = _mc.commandEcho(q=1, lineNumbers=1)
        _mc.commandEcho(lineNumbers=1)
        global errors
        errors = []  # a list to store each error line

        def errorCallback(nativeMsg, messageType, data):
            global errors
            if messageType == _api.MCommandMessage.kError:
                if nativeMsg:
                    errors += [nativeMsg]

        # setup the callback:
        # assigning ids to a list avoids the swig memory leak warning, which would scare a lot of people even though
        # it is harmless.  hoping we get a real solution to this so that we don't have to needlessly accumulate this data
        id = _api.MCommandMessage.addCommandOutputCallback(errorCallback, None)

        try:
            res = _api.MCommandResult()
            _api.MGlobal.executeCommand(cmd, res, False, undoState)
        except Exception:
            msg = '\n'.join(errors)

            if 'Cannot find procedure' in msg:
                e = MelUnknownProcedureError
            elif 'Wrong number of arguments' in msg:
                e = MelArgumentError
                if commandName:
                    # remove the calling proc, it will be added below
                    msg = msg.split('\n', 1)[1].lstrip()
            elif 'Cannot convert data' in msg or 'Cannot cast data' in msg:
                e = MelConversionError
            elif 'Syntax error' in msg:
                e = MelSyntaxError
            else:
                e = MelError
            message = "Error during execution of MEL script: %s" % (msg)
            fmtCmd = '\n'.join(['  ' + x for x in cmd.split('\n')])

            if commandName:
                if e is not MelUnknownProcedureError:
                    file = _mm.eval('whatIs "%s"' % commandName)
                    if file.startswith('Mel procedure found in: '):
                        file = 'file "%s"' % os.path.realpath(
                            file.split(':')[1].lstrip())
                    message += '\nCalling Procedure: %s, in %s' % (commandName,
                                                                   file)
                    message += '\n' + fmtCmd
            else:
                message += '\nScript:\n%s' % fmtCmd
            # PY2: once we switch to python-3 only, suppress the original
            # exception context, it's not useful
            #raise e(message) from None
            raise e(message)
        else:
            resType = res.resultType()

            if resType == _api.MCommandResult.kInvalid:
                return
            elif resType == _api.MCommandResult.kInt:
                result = _api.SafeApiPtr('int')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kIntArray:
                result = _api.MIntArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kDouble:
                result = _api.SafeApiPtr('double')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kDoubleArray:
                result = _api.MDoubleArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kString:
                return res.stringResult()
            elif resType == _api.MCommandResult.kStringArray:
                result = []
                res.getResult(result)
                return result
            elif resType == _api.MCommandResult.kVector:
                result = _api.MVector()
                res.getResult(result)
                return datatypes.Vector(result)
            elif resType == _api.MCommandResult.kVectorArray:
                result = _api.MVectorArray()
                res.getResult(result)
                return [
                    datatypes.Vector(result[i]) for i in range(result.length())
                ]
            elif resType == _api.MCommandResult.kMatrix:
                result = _api.MMatrix()
                res.getResult(result)
                return datatypes.Matrix(result)
            elif resType == _api.MCommandResult.kMatrixArray:
                result = _api.MMatrixArray()
                res.getResult(result)
                return [
                    datatypes.Matrix(result[i]) for i in range(result.length())
                ]
        finally:
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()
Exemplo n.º 9
0
def BakeFunction():
    cmds.commandEcho(ln=False)

    #define UI information
    channelCheck = getChannelCheck()
    channelBox_attrs = channelBoxList(channelCheck)
    appliedChannels = appliedChannelList(channelCheck)
    [start, end] = defineTimeRange()
    b_sample = cmds.floatField('bakeSample', q=True, value=True)

    #create objLists
    objLists = cmds.ls(sl=True)

    #undo
    cmds.undoInfo(openChunk=True)

    bake_channels = bake_channel(channelCheck, channelBox_attrs,
                                 appliedChannels)

    if cmds.checkBox('Euler', q=True, value=True) == True:
        if cmds.checkBox('Sim', q=True, value=True) == True:
            cmds.bakeResults(objLists,
                             at=bake_channels,
                             simulation=True,
                             t=(start, end),
                             sb=b_sample,
                             pok=True)
            cmds.setKeyframe(objLists, t=(-10000, -10000))
            cmds.setKeyframe(objLists, t=(-10001, -10001), value=0)
            cmds.filterCurve(objLists)
            cmds.cutKey(obj, at=bake_channels, t=(-10001, -10000))
        else:
            cmds.bakeResults(objLists,
                             at=bake_channels,
                             t=(start, end),
                             sb=b_sample,
                             pok=True)
            cmds.setKeyframe(objLists, t=(-10000, -10000))
            cmds.setKeyframe(objLists, t=(-10001, -10001), value=0)
            cmds.filterCurve(objLists)
            cmds.cutKey(objLists, at=bake_channels, t=(-10001, -10000))
    else:
        if cmds.checkBox('Sim', q=True, value=True) == True:
            cmds.bakeResults(objLists,
                             at=bake_channels,
                             simulation=True,
                             t=(start, end),
                             sb=b_sample,
                             pok=True)
        else:
            cmds.bakeResults(objLists,
                             at=bake_channels,
                             t=(start, end),
                             sb=b_sample,
                             pok=True)
    if cmds.checkBox('POK', q=True, value=True) == False:
        cmds.cutKey(objLists,
                    at=bake_channels,
                    clear=True,
                    t=(-100000, start - 1))
        cmds.cutKey(objLists,
                    at=bake_channels,
                    clear=True,
                    t=(end + 1, 100000))
    else:
        pass

    cmds.undoInfo(closeChunk=True)
Exemplo n.º 10
0
def ReductKeyFunction():
    cmds.commandEcho(ln=False)

    #define UI information
    channelCheck = getChannelCheck()
    channelBox_attrs = channelBoxList(channelCheck)
    appliedChannels = appliedChannelList(channelCheck)
    [start, end] = defineTimeRange()

    #create objLists
    objLists = cmds.ls(sl=True)

    if cmds.checkBox('LockSelectedKey', q=True, value=True) == True:
        #create L_KeyNameLists
        L_KeyNameLists = cmds.keyframe(q=True, n=True)
        [L_Name, L_keyTimes, L_keyValues, L_keyOutTangents,
         L_keyTangentTypes] = lockedKeyframe(L_KeyNameLists)
    else:
        L_Name = []
        L_keyTimes = []
        L_keyValues = []
        L_keyOutTangents = []
        L_keyTangentTypes = []

    #undo
    cmds.undoInfo(openChunk=True)

    for obj in objLists:
        #define channels
        [keyable_channels,
         channels] = common(obj, channelCheck, channelBox_attrs,
                            appliedChannels, start, end)

        if len(channels) != 0:
            for channel in channels:
                #get key information
                key_times = cmds.keyframe('{0}.{1}'.format(obj, channel),
                                          q=True,
                                          t=(start, end),
                                          timeChange=True)
                key_values = cmds.keyframe('{0}.{1}'.format(obj, channel),
                                           q=True,
                                           t=(start, end),
                                           valueChange=True)
                key_numbers = cmds.keyframe('{0}.{1}'.format(obj, channel),
                                            q=True,
                                            t=(start, end),
                                            iv=True)
                key_outTangents = cmds.keyTangent('{0}.{1}'.format(
                    obj, channel),
                                                  q=True,
                                                  t=(start, end),
                                                  outAngle=True)
                key_tangentTypes = cmds.keyTangent('{0}.{1}'.format(
                    obj, channel),
                                                   q=True,
                                                   t=(start, end),
                                                   ott=True)

                #fixed keyTangent
                fixed_index = fixedKey(key_tangentTypes, key_numbers)
                if len(fixed_index) != 0:
                    cmds.keyTangent('{0}.{1}'.format(obj, channel),
                                    e=True,
                                    index=fixed_index,
                                    itt='fixed',
                                    ott='fixed')
                else:
                    continue

                if len(key_outTangents) == 1:
                    continue
                else:
                    reduct_index = getReduct_index(key_outTangents, key_values,
                                                   key_numbers, key_times)

                if len(reduct_index) != 0:
                    cmds.cutKey(obj,
                                at=channel,
                                clear=True,
                                index=reduct_index)
                else:
                    continue
        else:
            continue

    if cmds.checkBox('LockSelectedKey', q=True, value=True) == True:
        if len(L_Name) != 0:
            for (i, L_name) in enumerate(L_Name):
                L_Times = L_keyTimes[i]
                L_values = L_keyValues[i]
                L_OutTangents = L_keyOutTangents[i]
                L_TangentTypes = L_keyTangentTypes[i]

                for (j, L_Time) in enumerate(L_Times):
                    cmds.setKeyframe(L_name,
                                     t=(L_Time, L_Time),
                                     value=L_values[j])
                    cmds.keyTangent(L_name,
                                    e=True,
                                    time=(L_Time, L_Time),
                                    ia=L_OutTangents[j],
                                    oa=L_OutTangents[j],
                                    itt=L_TangentTypes[j],
                                    ott=L_TangentTypes[j])

    cmds.undoInfo(closeChunk=True)