前言
  这次的问题是之前一起实习的朋友发来问我的,我上个月就帮他解决了问题,拖到现在才来记录一下填坑记录(:з」∠)
  说实话我是没想到有 Houdini 不用,居然会用 Maya MASH 插件来做效果的。
  朋友说那是因为那边的模型管理可以用 MASH 解决简单的效果,就不用劳烦特效部门了。
  不过 MASH 也是不争气,虽然有 Python API ,但是 Python API 居然也会有 BUG (:з」∠)
  我让他做了个小型可复现的 Demo 方便我去研究,大概的效果如下↓↓↓

测试文件下载地址
MASH API 的问题
  网上搜索一下 MASH Python 就可以找到 API 文档了 链接
  MASH 的 API 也不复杂,比起 Pymel 来说简单多了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | import MASH.api as mapi import pymel.core as pm mashNetwork = mapi.Network("MASH1")
  min_time = pm.playbackOptions(q=1,min=1) max_time = pm.playbackOptions(q=1,max=1) for i in range(int(min_time),int(max_time)+1):     pm.currentTime(i,update=1)     mashNetwork.getCurrentFrameData()     loc_list = []     for pt in mashNetwork.position:         loc = pm.spaceLocator()         loc.t.set((pt[0],pt[1],pt[2]))         loc_list.append(loc)     pm.group(loc_list,n="frame_%s" % i)
   | 
 
  按照文档的用法,应该可以用 getCurrentFrameData 的方式更新对象内部的 position 数据。
  我使用 locator 进行位置可视化,可以看到生成的 locator 都是固定在原始位置上的。

  位置信息没有根据动态进行更新。
  后面我只好去查 MASH.api 的代码看看是怎么实现。
  一查发现原来也是用 OpenMaya 获取对应节点信息的。

  于是我用节点视图查看了一下节点连接获取的信息。

  network 存储的 waiter 名称就是我们获取的 MASH1 节点。
  在节点视图下获取它的信息可能不是正确的,因为 BulletSolver 在 MASH1 后面。
  所以我打算获取 Repro 的信息,应该就是最终的数据。
  经过 pymel 的一番折腾,可以通过下面的代码获取 MASH 点的位置信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
   | import MASH.api as mapi from maya import OpenMaya import pymel.core as pm
 
  pm.delete([grp for grp in pm.ls(assemblies=1) if grp.startswith("frame")])
  data = {} min_time = pm.playbackOptions(q=1,min=1) max_time = pm.playbackOptions(q=1,max=1) for i in range(int(min_time),int(max_time)+1):     pm.currentTime(i,update=1)          mashNetwork = mapi.Network("MASH1")          node = pm.PyNode(mashNetwork.instancer)          obj = node.inputPoints.__apiobject__().asMObject()     inputPointsData = OpenMaya.MFnArrayAttrsData(obj)     positions = inputPointsData.getVectorData("position")          loc_list = []          for i in range(positions.length()):         pt = positions[i]         loc = pm.spaceLocator()         loc.t.set((pt.x,pt.y,pt.z))         loc_list.append(loc)     pm.group(loc_list,n="frame_%s" % i)     data[i] = mashNetwork.position print (data)
 
   | 
 

  这里通过 pymel 的方式获取到 OpenMaya1.0 的对象, pymel 的操作比较便捷,省去我很多前期的获取操作。
  得到 MASH1_Repro 下面就是获取节点内部的点信息。

  inputPoints 是个复合属性,为了获取出 position 的数据还是折腾了好一会。
  后面是参照了 MASH API 的一些写法获取到了。
  最后获取到的顶点数据 positions 不能直接进行 for 循环遍历,会导致 Maya 崩溃。
  以上就是这次 MASH 获取顶点信息的踩坑过程。
总结
  垃圾Maya , 换上 Houdini 吧~