Still haven't made this into an addon yet.
But the code snippets might be helpful for learning.
Modify and use at your own risk.
The purpose is to be able to export skin weights of a model. And also ability to import skin weights to model.
It Assumes armature is the same for both import and export. It doesn't create an armature on import (it assumes armature is already bound to same bones as were exported).
There is a part where it writes weights to disc.
Tested in blender 2.79.
Happy Sketching!
Nate
#Usage:
#assumes your character mesh is selected
#assumes you enter in a weight file path
#little error checking. use at your own risk.
#exportWeightOnSelected(weightFile = '/Users/Nathaniel/Documents/src_blender/python/snippets/weights1.naSkin')
#importWeightOnSelected(weightFile = '/Users/Nathaniel/Documents/src_blender/python/snippets/weights1.naSkin')
import bpy
import json
import os
def exportWeightOnSelected(weightFile = '/Users/Nathaniel/Documents/src_blender/python/snippets/weights1.naSkin'):
"""
export skin weights on selected character
"""
#assumes your character is selected
#no error checking
outDir = os.path.dirname(weightFile)
if not os.path.exists(outDir):
print('Requires an out directory that exists to write weight file')
return
vertexIds = []
weightDict = {} #will hold weights info
bpy.ops.object.mode_set(mode="EDIT")
charObj = bpy.context.edit_object
vtxGroups = []
vtxGroups = [ (grp.name,grp.index) for grp in charObj.vertex_groups ]
mesh = charObj.data
vertexIds = [ v.index for v in mesh.vertices ]
bpy.ops.object.mode_set(mode="OBJECT")
for vtxId in vertexIds:
boneDict = {}
for bone, boneIndex in vtxGroups:
weight = charObj.data.vertices[vtxId].groups[boneIndex].weight
weight = round(weight,4)
print('export weights on vtx >>> %s for bone >>> %s weight >> %s' %(vtxId,bone,weight) )
boneDict[ bone ] = weight
weightDict[vtxId] = boneDict #update weight info
print(weightDict)
#export weights to file
with open( weightFile, 'w' ) as f:
f.write( json.dumps(weightDict) )
def importWeightOnSelected(weightFile = '/Users/Nathaniel/Documents/src_blender/python/snippets/weights1.naSkin'):
"""
import skin weights on selected character
"""
if not os.path.exists(weightFile):
print('Requires weightfile path to exist')
return
#assumes your character is selected
#no error checking
weightDict = {} #will hold weights info
with open( weightFile, 'r' ) as f:
weightDict = json.load(f)
bpy.ops.object.mode_set(mode="EDIT")
charObj = bpy.context.edit_object
bpy.ops.object.mode_set(mode="OBJECT")
for vtxId, bones in weightDict.items():
print( vtxId )
for boneName, boneWeight in bones.items():
print('import weights on vtx >>> %s for bone >>> %s weight >> %s' %(vtxId,boneName,boneWeight) )
#change weights here. No error checking. example wouldnt work if couldnt find bone in armature
charObj.vertex_groups[ boneName ].add( [int(vtxId)], float(boneWeight), 'REPLACE' )
#inspired by online post: https://blender.stackexchange.com/questions/39653/how-to-set-vertex-weights-using-blenders-python-api