用maya API删除动画曲线多余的关键帧——掐头去尾删帧
来源:互联网 发布:启示录2优化补丁 编辑:程序博客网 时间:2024/05/22 06:55
写这个东西的缘由是一个同事给我说了一个他以前碰到的一个问题:一个文件里有上万条动画曲线,要删除某一帧前面的帧,也要删掉某一帧后面的帧,相当于是掐头去尾,但从功能上来说这个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;}
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 keyframe startFrameIndex = fnCurve.findClosest(om.MTime(start)) for i in xrange(startFrameIndex): fnCurve.remove(0, fnCurveCache) # remove all frame after the end keyframe endFrameIndex = 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)
0 0
- 用maya API删除动画曲线多余的关键帧——掐头去尾删帧
- CAKeyframeAnimation—关键帧动画
- 《核心动画——关键帧动画》
- 关键帧动画的停止
- Silverlight开发历程—关键帧动画
- 用六种算法实现maya动画曲线光滑
- iOS开发UI篇—核心动画(关键帧动画)
- iOS开发UI篇—核心动画(关键帧动画)
- iOS开发UI篇—核心动画(关键帧动画)
- iOS开发UI篇—核心动画(关键帧动画)
- iOS开发UI篇—核心动画(关键帧动画)
- iOS开发UI篇—核心动画(关键帧动画)
- 动画—Core Animation初步学习三:关键帧动画
- iOS开发UI篇—核心动画(关键帧动画)
- iOS UI篇7—核心动画(关键帧动画)
- iOS开发UI篇—核心动画(关键帧动画)
- iOS开发UI篇—核心动画(关键帧动画)
- Maya API转换curve为螺旋曲线
- 阿里云服务器调用微信支付接口慢的解决方案 (api.mch.weixin.qq.com)
- javascript 反序列化json字符串
- 获取Listview所有Item高度总和
- Centos 7.2 PHP 7.0 安装
- 在Unity3d中使用GZip来压缩网络传输数据
- 用maya API删除动画曲线多余的关键帧——掐头去尾删帧
- cordova 移动跨平台开发(二) ---- 使用ionic界面开发
- 如果你来投票决定百度的生死,你会如何抉择?
- OpenStack一键安装for CentOS
- jquery ajax,ashx,json的用法总结
- hdu_1495_非常可乐(bfs模拟)
- 后台数据控制前端checkbox(是否选中)
- Android studio 如何修改工程的包名
- 图像基本变换---图像二值化(包含OSTU/迭代法/统计法/双峰法/P分位法/最大熵法)