maya崩溃自动保存路径_maya 使用swig将插件编译成pyd,无缝使用内置数据实现加速计算模块...

前言:

原本目的是想寻求一种方式来对cpu计算密集型代码部分进行加速替代,但是maya中mll插件的插件套路在传递参数上会占用大量的io,对于数据比较大的部分也会有相当消耗。如果全部写在c++部分又感觉缺乏灵活性,所以琢磨的一种可以在python中实现逻辑,pyd中实现算法的方式。

问题:

纯python api来编译pyd的计算模块会有大量的数据转换,比如获取模型所有的顶点会得到MFloatPointArray,获取所有SkinMesh的蒙皮权重会得到MDoubleArray,这些数据直接获取都很快,但是要把他们转换成python api所支持的数据格式就很麻烦,计算完成后还要转换回来,一旦模型面熟很高很耗费时间。作为一个懒人不能忍~

思路:

maya api 1.0使用swig做封装,借助swig解封PyObject指针的功能自动将python指针对象转换成maya内置的M数据类型。

流程:

  1. 下载swig,解压到本地,路径添加到添加到环境变量中
  2. 创建一个空的vs工程

7b53977c68dda1f80fac0c241cef777b.png

3. 添加一个文件compute.h,我们所有的代码都放这个头文件里面

223554b437a47c54775bad48767467c7.png

4. 针对所有平台,设置一下vs工程,方便代码提示

输出格式

596ad312ada78b45c854fec063f82063.png

包含目录,库目录

571f434a3cf9e2395580d07afef3ad49.png

依赖库,只用基本的数据类型

1039c30a0e91dfc42e4113c0b14e77d0.png

输出文件(带下划线,下面有解释)

44ed9e81b2e1150c8b7a743cf7c653ff.png

随便写一个累加的测试函数

// compute.h

#pragma once
#include <maya/MIntArray.h>

int testMIntArray(MIntArray input)
{
	int sum = 0;
	for (int i = 0; i < input.length(); i++)
	{
		sum += input[i];
	}
	return sum;
}

编写swig的compute.i

%module TestMayaApi

%{
#include "compute.h"
%}

%include "compute.h"

添加到工程,设置一下生成事件,每次编译之前先生成包裹函数

8645381bc4e39155dd3587bed14ba68d.png

接下来编译就可以了

391ab26868d1abbb468ecff215e4476a.png

maya中测试:

import sys
sys.path.append('F:/swig_maya_test/swig_maya_test')
import TestMayaApi

import maya.OpenMaya as om
iList=om.MIntArray()
for i in range(100):
    iList.append(i)
    
print TestMayaApi.testMIntArray(iList)

2202efb0e3fd3b8b1a9f0cf5c133168e.png

优化:

swig会生成两个文件py和pyd的,py是模块名,pyd是_模块名,要不然导入python模块会失败,要把pyd模块名的修改成TestMayaApi,只修改工程设置里面的输出文件是不行的,导入会报错,需要修改源码,这样我们只需要pyd就可以了。

  1. 先将输出文件修改

09bee8fb7dc7acccf5bfb17b6cbfe70a.png

2. 禁用生成事件,改为手动运行cmd

8dc18dc46711de301dceb0e5cbf72816.png

3. 将swig生成的compute_wrap.cxx添加进来,搜索替换模块名

每次运行swig都要重新生成替换。

e6f01a4e07e30819f00f77c935b7451a.png

重新生成后我们就不需要.py文件了,直接删掉,只保留TestMayaApi.pyd

返回值的坑:

c++函数不能直接返回maya内置类型,如果函数定义成这样,python中接受到的返回值是swig object指针,传递给其它python api时会出错

MIntArray testMIntArray(MIntArray input)

解决办法:

将参数传递改成引用类型,这样就可以直接修改数据,不用返回,和api 1.0大多数做法一致

void testMIntArrayMul(MIntArray input,int mul, MIntArray& output)
{
	output.setLength(input.length());
	for (int i = 0; i < input.length(); i++)
	{
		output[i] = input[i] * mul;
	}
}

maya测试代码

import sys
sys.path.append('F:/swig_maya_test/swig_maya_test')
import TestMayaApi

import maya.OpenMaya as om
iList=om.MIntArray()
for i in range(100):
    iList.append(i)

outList=om.MIntArray()
TestMayaApi.testMIntArrayMul(iList,2,outList)
print outList

f40d82e874c4b100e4e23936227a68b5.png

总结:

算是maya plugin和python api的之外的一种计算模块的方式,编译之后maya 2016以下版本可以共用一个pyd,其它版本可能要单独编译,没测试很全。好处就是用起来更舒服,不用转换数据,和python api无缝衔接,可以直接用MxxxArray,并且支持OpenMP多线程计算。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值