Saturday, June 9, 2018

doodle

Hi,

I'm very new to blender but i thought these code snippets on making a blendshape/shapekey symmetric i wrote might be helpful.



cheers,
Nate


"""need imp to reload script
import sys
sys.path.append('/Users/Nathaniel/Documents/src_blender/python/naBlendShape')
import naMakeBlendshapeSymmetric as mod
import imp
imp.reload(mod)

mod.naMakeBlendshapeSymmetric(defaultMeshName = 'defaultFace', posedMeshName = 'posedFace', mirrorAxis = 1)  
"""

import bpy

def naMakeBlendshapeSymmetric(defaultMeshName = '', posedMeshName = '', mirrorAxis = 1):
    """
    this should be able to make both sides of blendshape/shape key symmetric on the posed mesh.
    TODO: edit duplicate of posed mesh
    mirrorAxis: 0 for x,1 for y,2 for z
    """
    #todo validate input
    
    ###first figure out correspondence between source and destination
    #ex {2: 0, 3: 1, 6: 4, 7: 5} says source vertex index 2's mirror index is 0 etc
    blendshapeInfo = {}
    defaultObj = bpy.data.objects[defaultMeshName]
    for v in defaultObj.data.vertices:
        #store key only if vertex world position in source side
        sourcePosition = v.co
        if sourcePosition[mirrorAxis] > 0: #0,1,2 : x,y,z
            sourceVertex = v.index
            #print('source vertex: '+str(sourceVertex))
            print('source vertex: %d pos: %d %d %d' %(sourceVertex, sourcePosition[0], sourcePosition[1], sourcePosition[2]) )
            #loop all vertices of mesh to find vertex on destination side
            for v1 in defaultObj.data.vertices:
                #if all positions same and negative value for destination side, its a mirror save it
                xx = [0,1,2] #will hold all but source side index
                xx.remove(mirrorAxis)
                pos = v1.co
                if pos[mirrorAxis] == -sourcePosition[mirrorAxis]:
                    if pos[xx[0]] == sourcePosition[xx[0]] and pos[xx[1]] == sourcePosition[xx[1]]:
                        #found a mirror, mirror side is negative source side and all other positions are same
                        destinationVertex = v1.index
                        print('destination vertex: %d pos: %d %d %d' %(destinationVertex, pos[0], pos[1], pos[2]) )
                        blendshapeInfo[sourceVertex] =  destinationVertex
    print("blendshapeInfo")
    print(blendshapeInfo)
    #########
    
    
    
    ###now actual do vertex movement
    posedObj = bpy.data.objects[posedMeshName]
    
    #assuming posedObj.data.vertices[i].index = i #not sure whether this is always true
    
    for sourceVertexIndex in blendshapeInfo:
        #we want to edit mirror side by making it the source position with one axis negated
        sourcePosition = posedObj.data.vertices[sourceVertexIndex].co
        m = [1,1,1]
        m[mirrorAxis] = -1
        mirrorPosition = [ sourcePosition[0]*m[0], sourcePosition[1]*m[1], sourcePosition[2]*m[2] ]
        destinationVertexIndex = blendshapeInfo[sourceVertexIndex]
        #actually move mirror side
        posedObj.data.vertices[destinationVertexIndex].co = mirrorPosition
    #########