Skip to content

Instantly share code, notes, and snippets.

@paulwinex
Last active May 1, 2018 21:08
Show Gist options
  • Save paulwinex/da19004d7eb8af4849b41efec7f4936a to your computer and use it in GitHub Desktop.
Save paulwinex/da19004d7eb8af4849b41efec7f4936a to your computer and use it in GitHub Desktop.
"""
WARNING!!!
1. Select mesh with BlendShape
2. Select file with RIGHT weight map
3. Start script
"""
from pymel.core import *
from PySide2.QtGui import *
from PySide2.QtCore import *
import time
def copy_to(obj, name=None, parent=None):
new = duplicate(obj, ic=False)[0]
if parent:
new.setParent(parent)
if not name:
new.rename(obj.name().split('|')[-1])
if name:
new.rename(name)
for sh in new.getShapes():
if sh.intermediateObject.get():
delete(sh)
return new
def apply_map(map_array, blendshape, target_index):
for i in range(len(map_array)):
w = map_array[i]/255.0
setAttr(blendshape.it[0].itg[target_index].tw[i], w)
def invert_weight(blendshape, target_index):
mesh = (blendshape.outputGeometry.outputs() or [None])[0]
if not mesh:
return
for i in range(len(mesh.vtx)):
setAttr(blendshape.it[0].itg[target_index].tw[i], 1-getAttr(blendshape.it[0].itg[target_index].tw[i]))
def fill_target(blendshape, target_index, value):
mesh = (blendshape.outputGeometry.outputs() or [None])[0]
if not mesh:
return
for i in range(len(mesh.vtx)):
setAttr(blendshape.it[0].itg[target_index].tw[i], value)
def split_targets(bs, map_file, mesh):
st = time.time()
bs.envelope.set(1)
uvs = [x.getUV() for x in mesh.vtx]
if os.path.splitext(map_file)[-1] == '.png':
frm = QImage.Format_RGBA8888
else:
frm = QImage.Format_RGB888
print 'Read Map...'
map = QImage(map_file, format=frm)
armap = [map.pixelColor(x[0]*1024, (1-x[1])*1024).value() for x in uvs]
out_parent = createNode('transform', name=mesh.name()+'_split_L_R')
print 'Start Split...'
targets = bs.getTarget()
count = len(targets)
for ti, name in enumerate(targets):
out_name = name.rsplit('|')[-1]
print 'Split %s Right' % out_name
bs.setWeight(ti, 1)
# apply left map
apply_map(armap, bs, ti)
# save left
dup = copy_to(mesh, name=out_name+'_R', parent=out_parent)
dup.hide()
# apply right map
invert_weight(bs, ti)
# save right
dup = copy_to(mesh, name=out_name+'_L', parent=out_parent)
dup.hide()
# reset
fill_target(bs, ti, 1)
bs.setWeight(ti, 0)
print 'Complete in {} sec'.format(int(time.time()-st))
def start():
sel = selected(transforms=True)
if not sel:
system.displayWarning('Select Mesh Object')
return
mesh = sel[0]
if not mesh.getShape():
system.displayWarning('Shape not found')
return
bs = (mesh.getShape().inputs(type='blendShape') or [None])[0]
if not bs:
system.displayWarning('Blens Shape not found')
return
multipleFilters = "Images (*.jpg *.png)"
file = fileDialog2(fileFilter=multipleFilters, fileMode=1, caption="Import Right Side Map")
if not file:
return
file = file[0]
split_targets(bs, file, mesh)
start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment