写这个东西的缘由是一个同事给我说了一个他以前碰到的一个问题:一个文件里有上万条动画曲线,要删除某一帧前面的帧,也要删掉某一帧后面的帧,相当于是掐头去尾,但从功能上来说这个mel完全可以胜任,但是执行起来效率就特别的低,于是他找另一个同事帮他写了个command,这样就将一个6G的含有上万条动画曲线的文件,只用了40多分钟就删完了,最后只剩下1G,而用mel删了一个小时还不到10%,可见二者效率相差。于是自己也想试着写一些,真正写起来没啥难点,主要是两个类,MFnAnimCurve和MAnimCurveChange,同时也实现了redo和undo,实现这个主要是用一个指针在堆中创建一个内存空间,然后将removekey都缓存到这块内存空间里,最后用它自身方法就可以实现redo和undo,自己测试,我这个command效率上没有他的那个夸张,应该是有些地方还不够优化,后面再继续完善吧。想想自己和他们的距离,不,那是天堑,自己还得多加努力啊。具体代码如下:

#include<maya/MPxCommand.h>
#include <maya/MFnPlugin.h>
#include <maya/MSyntax.h>
#include <maya/MDistance.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MDGModifier.h>
#include <maya/MArgDatabase.h>
#include <maya/MFnAnimCurve.h>
#include <maya/MAnimCurveChange.h>class DeleteKeysCmd : public MPxCommand
{
public:DeleteKeysCmd();~DeleteKeysCmd();virtual MStatus doIt( const MArgList& );virtual MStatus redoIt();virtual MStatus undoIt();virtual bool isUndoable() const { return true; };static void *creator(){ return new DeleteKeysCmd; }static MSyntax newSyntax();private:MTime startFrame;MTime endFrame;MAnimCurveChange* pAnimCache;};const char *startFrameFlag = "-sf", *startFrameLongFlag = "-startFrame";
const char *newendFrameFlag = "-ef", *newendFrameLongFlag = "-endFrame";DeleteKeysCmd::DeleteKeysCmd()
{startFrame.setValue( 0 );endFrame.setValue( 100 );
}DeleteKeysCmd::~DeleteKeysCmd()
{delete pAnimCache;
}MSyntax DeleteKeysCmd::newSyntax()
{MSyntax syntax;syntax.addFlag( startFrameFlag, startFrameLongFlag, MSyntax::kLong );syntax.addFlag( newendFrameFlag, newendFrameLongFlag, MSyntax::kLong );return syntax;
}MStatus DeleteKeysCmd::doIt( const MArgList &args )
{MStatus stat;pAnimCache = NULL;pAnimCache = new MAnimCurveChange();MArgDatabase argData( syntax(), args, &stat );if( !stat )return stat;if( argData.isFlagSet( startFrameFlag ) )argData.getFlagArgument( startFrameFlag, 0,  startFrame);if( argData.isFlagSet( newendFrameLongFlag ) )argData.getFlagArgument( newendFrameLongFlag, 0,  endFrame);MDGModifier modifier;MItDependencyNodes animCurves(MFn::kAnimCurve);for (; !animCurves.isDone(); animCurves.next()){MObject currentItem = animCurves.item();if ( currentItem.isNull() ){continue;}MFnAnimCurve fnCurve (currentItem);unsigned int numKeys = fnCurve.numKeys();if (numKeys == 0){modifier.deleteNode(currentItem);}else{unsigned int startFrameIndex = fnCurve.findClosest(startFrame);for(unsigned int i = 0; i < startFrameIndex; i++){fnCurve.remove(0, pAnimCache);}unsigned int endFrameIndex = fnCurve.findClosest(endFrame);unsigned int numKeysToRemoves = numKeys -1 - endFrameIndex;for(unsigned int i = 0; i < numKeysToRemoves; i++){fnCurve.remove(endFrameIndex + 1, pAnimCache);}}}return stat;
}MStatus DeleteKeysCmd::undoIt()
{if( pAnimCache != NULL )pAnimCache -> undoIt();return MS::kSuccess;
}MStatus DeleteKeysCmd::redoIt()
{if( pAnimCache != NULL )pAnimCache -> redoIt();return MS::kSuccess;
}MStatus initializePlugin( MObject obj )
{MFnPlugin plugin( obj, "Lulongfei", "1.0" );MStatus stat;stat = plugin.registerCommand( "deleteKeys", DeleteKeysCmd::creator, DeleteKeysCmd::newSyntax );if ( !stat )stat.perror( "registerCommand failed" );return stat;
}MStatus uninitializePlugin( MObject obj )
{MFnPlugin plugin( obj );MStatus stat;stat = plugin.deregisterCommand( "deleteKeys" );if ( !stat )stat.perror( "deregisterCommand failed" );return stat;
}

下面的是对应的python的api实现方式,相比于mel效率应该也很高,但是相对于C++ Api可能逊色点,也一并放上:

def removeInvalidKeys(start, end):animCurves = om.MItDependencyNodes(om.MFn.kAnimCurve)while not animCurves.isDone():modifier = om.MDGModifier()fnCurveCache = oma.MAnimCurveChange()currentItem = animCurves.item()fnCurve = oma.MFnAnimCurve(currentItem)if fnCurve.numKeys():# remove all frame before the start keyframestartFrameIndex = fnCurve.findClosest(om.MTime(start))for i in xrange(startFrameIndex):fnCurve.remove(0, fnCurveCache)# remove all frame after the end keyframeendFrameIndex = fnCurve.findClosest(om.MTime(end))for i in xrange(endFrameIndex, fnCurve.numKeys() - 1):fnCurve.remove(endFrameIndex + 1, fnCurveCache)#fnCurveCache.undoIt()else:modifier.deleteNode(currentItem)animCurves.next()

具体使用时cmd可以用:cmds.deleteKeys(sf = 20, ef = 90); mel用deleteKeys -sf 20 -ef 90

而python则直接可以调用function了,removeInvalidKeys(20, 90)

用maya API删除动画曲线多余的关键帧——掐头去尾删帧相关推荐

  1. iPh oto的删除动画

    iPhoto 中想删除某张照片时,点击删除键,就能看到照片被回收到垃圾箱的动画. 今天就来模拟一下这个动画(据说有个私有API可以实现,不过私有的嘛,忽略之). 首先仔细观察下这个动画,包含了位置,大 ...

  2. Maya人物角色行走动画制作视频教程

    Maya人物角色行走动画制作视频教程 Maya人物角色行走动画制作视频教程 持续时间2h 57m 包含项目文件 1920X1080 MP4 大小解压后:2.27G 标题:技能分享–在Maya制作专业行 ...

  3. [Maya API] 一、基本类型介绍

    1.Maya API基本结构 1.1 API语言支持 C++ API(Application Programmer Interface) 比MEL和Python有更好的性能,你可以使用API创建你自己 ...

  4. 咸鱼Maya笔记—路径动画

    咸鱼Maya笔记-路径动画 创建路径动画 动画的创建方式有很多种,路径动画是其中的一种,Key关键帧的方式并不适用于所有的情况,有些特定的情况下我们就需要用到路径动画,它的创建方法如下 创建路径动画 ...

  5. Maya角色面部表情动画制作视频教程 Maya: Facial Rigging

    Maya角色面部表情动画制作视频教程 Maya: Facial Rigging Maya角色面部表情动画制作视频教程 Maya: Facial Rigging Maya角色面部表情动画制作视频教程 M ...

  6. Android动画曲线库AndroidEasingFunctions

    Android动画曲线库AndroidEasingFunctions AndroidEasingFunction是基于Easing Function(缓动函数)的Android动画曲线库.它提供了九大 ...

  7. 删除Kali Linux多余的系统架构

    删除Kali Linux多余的系统架构 现在大家通常安装的都是Kali Linux 64位操作系统,其架构为amd64.如果要安装运行32位的程序(如wine32),则必须添加32位架构i386.添加 ...

  8. 删除字符串中多余的空白字符和空行(C语言实现)

    要求:处理一个字符串,删除字符串中多余的空格.水平制表符和空行,并满足下列要求: (1)对原字符串只能进行一次扫描. (2)不允许申请新的空间. (3)处理后的字符串的首尾不能有空格.制表符和空行. ...

  9. 使用EditPlus 删除文本文件中多余的空行 和 EditPlus 选择列

    使用EditPlus 删除文本文件中多余的空行 可以直接调出查找,然后给在Find what中输入正则表达式 ^[ \t]*\n  ,注意\t前有空格符. EditPlus 选择列 注意:在自动换行的 ...

最新文章

  1. 除了Java,为什么我们要学Python?
  2. 绘制测试集、训练集的每一个病人或者样本的raidomics signiture图(绘制raidomics signature图),以及ROC曲线图
  3. C++笔记-shared_ptr与weak_ptr需要注意的地方
  4. 一文解析Apache Avro数据
  5. Java集合源码剖析-Java集合框架
  6. php中文字怎么上下居中,word文档表格文字怎么上下居中对齐
  7. 如何用Python计算周数
  8. 华硕AC56(8812)Linux网卡驱动安装教程
  9. 微信小程序wepy框架+minui踩坑之路
  10. python输入中文教程_如何用Python从头开始实现一个中文拼音输入法?
  11. ui界面颜色设计_界面设计ui的颜色基础
  12. 使用HiPrint批量打印条码,二维码
  13. linux vi命令的查询,关于Linux vi命令 vi命令一览表
  14. html5悬浮圆圈背景动画特效,html5圆圈浮动背景动画特效
  15. SpringBoot 集成 MongoDB 磁盘分页查询导致的坑,allowDiskUse 基本配置
  16. C语言实现一个走迷宫小游戏(深度优先算法)
  17. 二级日语语法总汇(2)
  18. emc存储设备型号_emc VNX系列存储技术参数表
  19. SSM中的拦截器机制
  20. PH10全彩 LED屏 64*16 点阵显示4个汉字调试心得

热门文章

  1. vnc远程控制软件,linux系统如何使用vnc远程控制软件,vnc客户端使用教程
  2. Android App 可以定时启动! 并且完成短信自动发送获取内容功能 (以获取闪讯密码为例 大学宿舍宽带)
  3. html5 画布绘制时钟
  4. MCE公司:RIP1 激酶抑制剂可应用于自身免疫性脑脊髓炎的治疗
  5. 南开大学2019年高等代数考研试题讲解
  6. 毕业论文写作中数据获取与查询
  7. fatal: detected dubious ownership in repository git报错解决
  8. 【经济学视频课程】科斯定理的本质…
  9. Python生成自动化测试报告的两种方法
  10. c# Excel 添加组合Range区域,方便选择Select()删除 Delete()