如何使用 Maya Python API 2.0 在网格中添加边缘

Posted

技术标签:

【中文标题】如何使用 Maya Python API 2.0 在网格中添加边缘【英文标题】:How to add edge in mesh using Maya Python API 2.0 【发布时间】:2017-04-26 11:49:18 【问题描述】:

我使用 maya.api.OpenMaya.MFnMesh.subdivideEdges() 函数。边被顶点分割,但相应的新边不会出现。如何在分割边缘上添加边缘?或者如何创建从一个顶点到另一个顶点的边。使用 Maya Python API 2.0 吗?

#这是我的 Maya Python API 2.0 代码

import maya.api.OpenMaya as om
verticePos      = [(-0.5, -0.5, 0.5, 1), (0.5, -0.5, 0.5, 1), (-0.5, 0.910894, 0.5, 1), (0.5, 0.910894, 0.5, 1), (-0.5, 0.910894, -0.383361, 1), (0.5, 0.910894, -0.383361, 1), (-0.5, -0.5, -0.383361, 1), (0.5, -0.5, -0.383361, 1), -0.5, -0.5, 1.06715, 1), (0.5, -0.5, 1.06715, 1), (0.5, 0.910894, 1.06715, 1), (-0.5, 0.910894, 1.06715, 1), (-0.5, -1.12433, -0.383361, 1), (0.5, -1.12433, -0.383361, 1), (0.5, -1.12433, 0.5, 1), (-0.5, -1.12433, 0.5, 1), (0, 0.910894, 1.06715, 1), (0, 0.910894, 0.5, 1), (0, 0.910894, -0.383361, 1), (0, -0.5, -0.383361, 1), (0, -1.12433, -0.383361, 1), (0, -1.12433, 0.5, 1), (0, -0.5, 0.5, 1), (0, -0.5, 1.06715, 1)]

polygonCounts   = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
polygonConnects = [8, 23, 16, 11, 2, 17, 18, 4, 4, 18, 19, 6, 12, 20, 21, 15, 1, 7, 5, 3, 6, 0, 2, 4, 0, 22, 23, 8, 1, 3, 10, 9, 17, 2, 11, 16, 2, 0, 8, 11, 6, 19, 20, 12, 7, 1, 14, 13, 22, 0, 15, 21, 0, 6, 12, 15, 3, 17, 16, 10, 18, 17, 3, 5, 19, 18, 5, 7, 20, 19, 7, 13, 21, 20, 13, 14, 1, 22, 21, 14, 23, 22, 1, 9, 16, 23, 9, 10]

uValues         = [0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625]
vValues         = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

#Convert to MPointArray
vertices        = om.MPointArray ()
for eachPos in verticePos :            
    mPoint      = om.MPoint ()            
    mPoint.x    = eachPos[0]      
    mPoint.y    = eachPos[1]      
    mPoint.z    = eachPos[2]              
    vertices.append (mPoint)

mfnMesh    = om.MFnMesh ()
mfnMesh.create(vertices, polygonCounts, polygonConnects, uValues, vValues)
mfnMesh.updateSurface ()
cmds.sets (mfnMesh.fullPathName(), e=1, fe='initialShadingGroup')
mfnMesh.updateSurface()

#Spliting Edges################################
edgeIDs     = [5,7,19,14,12,32,15,17]
mfnMesh.subdivideEdges (edgeIDs, 1)

【问题讨论】:

【参考方案1】:

使用 OpenMaya.MFnMesh.split()。 MFnMesh.split,需要的信息:

[in]    placements  array that contains elements of the SplitPlacement enumeration. They represent where to place the new vertices for the split.
[in]    edgeList    array of edge IDs to be split, in order of their appearance in the split. There must be as many elements in this array as there are SplitPlacement::kOnEdge elements in the placements array.
[in]    edgeFactors     array of factors in the range [0,1] that represent how far along each edge must the split be done. This array must have the same number of elements as the edgeList array.
[in]    internalPoints  array of positions for the vertices that will be added inside existing faces. There must be as many elements in this array as there are SplitPlacement::kInternalPoint elements in the placements array. This array can be empty. Internal points should be specified on the face between the previous edge id and the next edge id.

工作示例:在此处查看拆分方法:Github,用于属性收集和干净拆分的准确方法。

import maya.api.OpenMaya as om
verticePos      = [(-0.5, -0.5, 0.5, 1), (0.5, -0.5, 0.5, 1), (-0.5, 0.910894, 0.5, 1), (0.5, 0.910894, 0.5, 1), (-0.5, 0.910894, -0.383361, 1), (0.5, 0.910894, -0.383361, 1), (-0.5, -0.5, -0.383361, 1), (0.5, -0.5, -0.383361, 1), -0.5, -0.5, 1.06715, 1), (0.5, -0.5, 1.06715, 1), (0.5, 0.910894, 1.06715, 1), (-0.5, 0.910894, 1.06715, 1), (-0.5, -1.12433, -0.383361, 1), (0.5, -1.12433, -0.383361, 1), (0.5, -1.12433, 0.5, 1), (-0.5, -1.12433, 0.5, 1), (0, 0.910894, 1.06715, 1), (0, 0.910894, 0.5, 1), (0, 0.910894, -0.383361, 1), (0, -0.5, -0.383361, 1), (0, -1.12433, -0.383361, 1), (0, -1.12433, 0.5, 1), (0, -0.5, 0.5, 1), (0, -0.5, 1.06715, 1)]

polygonCounts   = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
polygonConnects = [8, 23, 16, 11, 2, 17, 18, 4, 4, 18, 19, 6, 12, 20, 21, 15, 1, 7, 5, 3, 6, 0, 2, 4, 0, 22, 23, 8, 1, 3, 10, 9, 17, 2, 11, 16, 2, 0, 8, 11, 6, 19, 20, 12, 7, 1, 14, 13, 22, 0, 15, 21, 0, 6, 12, 15, 3, 17, 16, 10, 18, 17, 3, 5, 19, 18, 5, 7, 20, 19, 7, 13, 21, 20, 13, 14, 1, 22, 21, 14, 23, 22, 1, 9, 16, 23, 9, 10]

uValues         = [0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625]
vValues         = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

#Convert to MPointArray
vertices        = om.MPointArray ()
for eachPos in verticePos :            
    mPoint      = om.MPoint ()            
    mPoint.x    = eachPos[0]      
    mPoint.y    = eachPos[1]      
    mPoint.z    = eachPos[2]              
    vertices.append (mPoint)

mfnMesh    = om.MFnMesh ()
mfnMesh.create(vertices, polygonCounts, polygonConnects, uValues, vValues)
mfnMesh.updateSurface ()
cmds.sets (mfnMesh.fullPathName(), e=1, fe='initialShadingGroup')
mfnMesh.updateSurface()

# OpenMaya.MFnMesh.subdivideEdges() dividing the selected 
# edges(we will get new Vertices/Edges)
# The real challenge is connect the new vertices with each other, in order....
# my solution is hacking the right info and connect the Vertices,
# its based on the correct edge flow/selection...

#find all connected edges per Vertex
def ver_coll(rr):
  dict = 
  for vertexid in range(rr):
    vIdArray = om1.MIntArray()
    vIdArray.append(vertexid)
    vtxCom = om1.MFnSingleIndexedComponent()
    vtxCom.create(om1.MFn.kMeshVertComponent)
    vtxCom.addElements(vIdArray)
    sel = om1.MSelectionList()
    sel.clear()
    sel.add(mfnMesh.fullPathName())
    meshdag = om1.MDagPath()
    sel.getDagPath(0,meshdag)
    vtxIter = om1.MItMeshVertex(meshdag,vtxCom.object())
    vtxIter.getConnectedEdges(vIdArray)
    util = om1.MScriptUtil(vIdArray)
    data = util.asIntPtr()
    numCE = vIdArray.length()
    dict[vertexid] = [util.getIntArrayItem(data, i) for i in range(numCE)]
  return dict

pre = ver_coll(cmds.polyEvaluate(mfnMesh.fullPathName(), v=True))
edgeIDs = [0, 21, 13, 11, 9, 6, 4, 2] # or [5,7,19,14,12,32,15,17] 
mfnMesh.subdivideEdges(edgeIDs, 1)
post = ver_coll(cmds.polyEvaluate(mfnMesh.fullPathName(), v=True))

object_id = mfnMesh.fullPathName().split("|")[1]

for e in range(0,len(edgeIDs),1):
  con = edgeIDs[e:e+2]
  vtx_ids = []
  for c in con:
    for v in set(post.keys())-set(pre.keys()):
      if c in post[v]:
        vtx_ids.append(v)
  if len(vtx_ids) == 2:
    print vtx_ids 
    cmds.polyConnectComponents("0.vtx[1]".format(object_id, vtx_ids[0]), "0.vtx[1]".format(object_id, vtx_ids[1]), adjustEdgeFlow=True, ch=True)
  else:
    vtx = []
    for i in [edgeIDs[0], con[0]]:
      for v in set(post.keys())-set(pre.keys()):
        if i in post[v]:
          vtx.append(v)
    cmds.polyConnectComponents("0.vtx[1]".format(object_id, vtx[0]), "0.vtx[1]".format(object_id, vtx[1]), adjustEdgeFlow=True, ch=True)

【讨论】:

嗨,Ari Gold。谢谢您的帮助。我会试试这个。感谢您与我分享您的知识!

以上是关于如何使用 Maya Python API 2.0 在网格中添加边缘的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 python 在 Maya 中设置目录?目前使用 PyQt4,但愿意接受任何建议

MailChimp API 2.0 python 新订阅者到分组

ansible python api 2.0使用

如何在 Python 脚本中为 Autodesk Maya 2016 中的对象添加颜色?

Maya Plugin 编译Maya插件

如何解决 Twitter 搜索 API 2.0 上的操作员错误