赞
踩
本文介绍的是Maya中blendShape的底层原理,并总结了一些通过Python代码编辑blendShape的方法。代码库为cmds和openMaya。注意,阅读本文需要一定的编程基础。
在“窗口>>节点编辑器”中打开节点编辑器,按下“Tab”并输入“blendshape”创建一个完全无数据的空blendShape;右键按住并移动到“显示所有属性”一栏再松开,可以看到节点的所有属性;可以点击名称处修改它的名字。
在节点编辑器中创建blendShape
可以看到BS节点中的属性有很多,但重点只有四个,我们使用上一节中“在形变编辑器中创建blendShape“的方法创建好BS后,右键点击“在节点编辑器中查看”选项,可以看到系统为您连好的BS节点。
原始几何体用来获取该BS的初始形状,与“pSphereShape1Orig”链接代表该BS从网格“pSphereShape1”的Orig节点中获取初始形状。(Orig节点是网格的原始节点,记录网格的最原始的数据,可能不与显示在窗口中的形状相同。)
BS将修改后的形状通过“输出几何体”属性输出,与“pSphereShape1”链接代表形变后的形状会赋予给“pSphereShape1”,使该网格显示在窗口中的形状发生改变。(不带后缀的节点是网格的显示节点,用来记录网格显示在窗口中的形状数据,即我们看到的形状。)
一个BS中可能包含多个目标形状,这些形状的权重值和名字就记录在权重当中,由于大部分时候我们不会改变权重的大小,所以我通常使用该属性方便的遍历BS的目标形状名称、获取BS的目标形状数量。
输入目标中包含的信息最多我们重点关注:输入目标[x],输入点目标,输入组件目标。每个输入目标[x]都代表一个目标网格;“输入点目标”中记录的是该目标网格会影响的点的ID;“输入组件目标”中记录的是该目标网格会影响的点的位移量。因此,我们可以通过改变这些数据实现快速批量控制BS。
图四:BS输入目标属性表
我尝试了cmds、mel、pymel、OpenMaya等库与语言后,选择了OpenMaya来实现BS的编辑,因为cmds、mel、pymel都是调用OpenMaya来实现BS的编辑,速度慢不说,可实现的功能也不多。因此,使用OpenMaya改写blendShape节点可以说是最优解,且AutoDesk官方给出了API,学习起来也很方便。
这里我将介绍,通过OpenMaya创建BS的目标网格的方法、通过OpenMaya修改BS的目标网格的方法。
首先要导入OpenMaya库,获取BS节点,在创建目标形状,最后给入形变数据。
- import maya.OpenMaya as OM
-
- # BS的名称
- BSName = "blendShape1"
-
-
- # 获取OpenMaya中的BS节点
- # OpenMaya中的BS节点为MFnDependencyNode
- BSNodeObj = OM.MObject()
- sel = OM.MSelectionList()
- sel.add(BSName, 0)
- sel.getDependNode(0, BSNodeObj)
- dgFn = OM.MFnDependencyNode(BSNodeObj)
-
-
- # 使用plug获取节点中的属性
- # findPlug('inputTarget')为图四中的输入目标接口
- # elementByLogicalIndex是Mplug的函数,用来返回plug的逻辑节点的元素,如果找不到,就创建它。此处的elementByLogicalIndex(0)代表输入目标[0]
- # child(0)返回的值为“输入目标[0]-输入目标组”
- plug = dgFn.findPlug('inputTarget').elementByLogicalIndex(0).child(0)
-
- # ------------------------------------------------------------------
- # 下面的函数用来创建一个新的目标形状,值得注意的是其中有个值为6000的逻辑地址,
- # 它根据该目标网格的权重值得到,6000=w*1000+5000
- tarId = 0
- tarName = "testTarName"
-
- # create target
- custPlug.elementByLogicalIndex(tarId).asMObject()
- custPlug.evaluateNumElements()
-
- # create LogicalIndex6000 on the target
- input_target_item_mPlug = custPlug.elementByLogicalIndex(tarId).child(0)
- input_target_item_mPlug.elementByLogicalIndex(6000)
- input_target_item_mPlug.evaluateNumElements()
-
- # create weight of the target
- weight_mPlug = custDgFn.findPlug("weight", False)
- weight_mPlug.elementByLogicalIndex(tarId).asFloat()
- weight_mPlug.evaluateNumElements()
-
- # assign the name to the new target
- cmds.aliasAttr(tarName, '{}.w[{}]'.format(BSName, tarId))
-
- # ------------------------------------------------------------------
- # 下面的函数用来给入BS形变数据
-
- # points记录顶点delta数据,可以完全自定义,形如:[ [0,0,0] , [1,1,1] , [0,0,1] ]
- # indices记录delta数据对应的顶点ID, 长度要与points一致,形如:[ 0,1,3 ]
- points = [ [1,0,0] , [1,1,1] , [0,0,1] ]
- indices = [ 0,1,3 ]
-
- # 将列表转换成MObject类型的数据
- point_list = OM.MPointArray()
- index_list = OM.MIntArray()
-
- # get point_list
- for pointDelta in points:
- point = OM.MPoint(pointDelta[0], pointDelta[1], pointDelta[2], 1.0)
- point_list.append(point)
- # writes the delta data in the inputPointsTarget plug
- dg_pointArray_fn = OM.MFnPointArrayData()
- dg_pointArray_data = dg_pointArray_fn.create(point_list)
- plug.elementByLogicalIndex(tarId).child(0).elementByLogicalIndex(6000).child(3).setMObject(dg_pointArray_data)
-
- # get index_list
- for index in indices:
- index_list.append(index)
- # initializes function sets, needed to create the MObjects and set their data
- dg_component_fn = OM.MFnComponentListData()
- dg_component_data = dg_component_fn.create()
- singleComponent_fn = OM.MFnSingleIndexedComponent()
- singleComponent_data = singleComponent_fn.create(OM.MFn.kMeshVertComponent)
- singleComponent_fn.addElements(index_list)
- dg_component_fn.add(singleComponent_data)
- plug.elementByLogicalIndex(tarId).child(0).elementByLogicalIndex(6000).child(4).setMObject(dg_component_data)
-
- # ------------------------------------------------------------------
- # 至此,一个完全自定义的目标形状就创建完了,提醒一下BS数据,可以直接从现有BS中获取,
- # 且不必转换来转换去的,还麻烦
参考链接:
1、OpenMaya API链接:
https://help.autodesk.com/view/MAYAUL/2023/CHS/?guid=MAYA_API_REF_py_ref_namespace_open_maya_html
2、外网参考
https://groups.google.com/g/python_inside_maya/c/_GiD2R89Dqg
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。