I was working on merging a separate eye lid to existing face mesh and thought these tools would be handy so I wrote them.
use at your own risk.
first i wanted a way for the outer border of the eyelids to automatically snap to existing edges of the face. So here is the snap script at work:
i wanted a way to quickly join the split eyelid mesh with existing face:
it should also work with joining multiple meshes:
finally wanted a way to split areas off of separate eyelid mesh i didn't need by edgeloop:
here is the personal script i wrote:
"""useful for merging split eyelids/or lips onto existing mesh
@author Nathaniel Anozie
Modify at your own risk
last updated: 10/28/2017 -- initial release
application:
facial modeling
body modeling
for maya
wip for blender
description naSnapToMesh:
snaps given vertices to closest vertex on mesh, will use selection if no vertices specified. should support a selected edgeloop.
usage:
import naSeam
naSeam.naSnapToMesh('polySurface1')
"""
import maya.cmds as cmds
def naSnapToMesh(mesh, vertices=[]):
"""snaps given vertices to closest vertex on mesh, will use selection if no vertices specified.
should support a selected edgeloop.
#mesh = 'polySurface2' #this would be the entire face mesh, place want to merge to
#vertices = ['polySurface1.vtx[0]', 'polySurface1.vtx[2]'] #these would be eyelid boundary vertices
"""
if not vertices:
selection = cmds.filterExpand(cmds.polyListComponentConversion(toVertex=True),sm=31)
vertices = selection
if not vertices:
print 'could not find vertices to snap'
return
cpmNode = cmds.createNode('closestPointOnMesh')
cmds.connectAttr(mesh+'.worldMesh[0]', cpmNode+'.inMesh')
indexExternal = 2
for vtxExternal in vertices:
cmds.select(cpmNode,replace=True)
cmds.select(vtxExternal,replace=True)
posExternal = cmds.xform( vtxExternal, translation=True, query=True, ws=True)
cmds.setAttr( cpmNode+'.inPositionX', posExternal[0] )
cmds.setAttr( cpmNode+'.inPositionY', posExternal[1] )
cmds.setAttr( cpmNode+'.inPositionZ', posExternal[2] )
vtxIndex = cmds.getAttr( cpmNode+'.result.closestVertexIndex' )
vtx = mesh+'.vtx[%s]'%(vtxIndex)
vtxPos = cmds.xform( vtx, translation=True, query=True, ws=True)
#actual moving of external mesh to meet mesh
cmds.xform( vtxExternal, translation=vtxPos, ws=True)
cmds.delete(cpmNode)
def naJoin(meshes=[]):
"""
merges given or selected meshes
"""
if not meshes:
meshes = cmds.ls(selection=True) #should check all selected are meshes
if not meshes:
print 'no meshes to combine'
return
def _join(meshA,meshB):
#meshA = 'polySurface2'
#meshB = 'polySurface1'
meshCombine = cmds.polyUnite(meshA,meshB) #combine meshes
vertices = cmds.polyListComponentConversion(meshCombine,toVertex=True)
cmds.polyMergeVertex(vertices)#merge all vertices
meshC = [x for x in meshCombine if cmds.objectType(x) != 'polyUnite']
cmds.delete(meshCombine, ch=True)#clean mesh
return meshC[0]
meshA = meshes[0]
for meshB in meshes[1:]:
meshA = _join(meshA,meshB)
def naSplit():
"""
split by selected edge loop. note select loop one inside then where want split to accomodate face conversion from selection.
result meshes get parented to world. i think works on one mesh at a time.
"""
edges = cmds.ls(selection=True)
faces = cmds.polyListComponentConversion(edges, toFace=True)
cmds.polyChipOff(faces,dup=False)
meshParent = faces[0].split('.')[0]
mesh = cmds.listRelatives(meshParent,children=True,type='mesh')[0]
sepResult = cmds.polySeparate(mesh)
for x in sepResult:
if not cmds.objExists(x):
continue
if cmds.objectType(x) != 'polySeparate':
cmds.delete(x,ch=True)
cmds.parent(x,world=True)
cmds.delete(meshParent)
hope you find it helpful.
Happy Scripting!
Nate














