Beispiel #1
0
 def setFrame(fi):
     QGLViewer.timeline.frameStep = 1
     drawing_skel2 = True
     global animDict
     dofs = animDict['dofData'][(fi - animDict['frameNumbers'][0]) %
                                len(animDict['frameNumbers'])].copy()
     #dofs[[2,5]] = dofData[0,[2,5]]
     Character.pose_skeleton(skelDict['Gs'], skelDict, dofs)
     QGLViewer.skel.setPose(skelDict['Gs'])
     if drawing_skel2:
         dofs = skelDict2['dofData'][(fi - skelDict2['frameNumbers'][0]) %
                                     len(skelDict2['frameNumbers'])].copy()
         Character.pose_skeleton(skelDict2['Gs'], skelDict2, dofs)
         QGLViewer.skel2.setPose(skelDict['Gs'])
     QGLViewer.view.updateGL()
Beispiel #2
0
def scoreIK(skelDict, chanValues, effectorData, effectorTargets, rootMat=None):
    """
	Args:
		skelDict (GskelDict): The Skeleton to process

	Returns:
		?

	Requires:
		Character.pose_skeleton
		ISCV.score_effectors
	"""
    Character.pose_skeleton(skelDict['Gs'], skelDict, chanValues, rootMat)
    return (
        ISCV.score_effectors(skelDict['Gs'], effectorData[0], effectorData[1],
                             effectorData[2], effectorTargets) /
        np.sum(effectorData[1]))**0.5
Beispiel #3
0
def skeleton_marker_positions(skelDict,
                              rootMat,
                              chanValues,
                              effectorLabels,
                              effectorData,
                              markerWeights=None):
    """
	Based on the pose implied by the chanValues and rootMat, compute the 3D world-space
	positions of the markers.
	
	Multiple effectors may determine the position of the marker. effectorLabels provides this mapping.
	
	The weights for the markers, if any, are set by markerWeights.
	
	Args:
		skelDict (GskelDict): the skeleton
		rootMat (float[3][4]): reference frame of the Skeleton.
		chanValues (float[]) List of channel values to pose the skeleton
		effectorLabels : the marker that each effector determines
		effectorData : (effectorJoints, effectorOffsets, ...)
		markerWeights : the weight that each effector has on its marker
		
	Returns:
		int[]: Labels for the 3D positions of the markers.
		float[][3]: 3D positions of where the target would be in the pose.
		
	Requires:
		Character.pose_skeleton
		ISCV.marker_positions
		
	"""
    Character.pose_skeleton(skelDict['Gs'], skelDict, chanValues, rootMat)
    labels = np.unique(effectorLabels)
    els2 = np.int32([list(labels).index(x) for x in effectorLabels])
    x3ds = ISCV.marker_positions(skelDict['Gs'], effectorData[0],
                                 effectorData[1], els2, markerWeights)
    return x3ds, labels
Beispiel #4
0
def loadVSS(fn):
	'''Decode a Vicon Skeleton file (VST format). VSK is labeling skeleton. VSS is solving skeleton.'''
	import xml.etree.cElementTree as ET
	import numpy as np
	dom = ET.parse(fn)
	parameters = dom.findall('Parameters')[0]
	params = dict([(p.get('NAME'),p.get('VALUE')) for p in parameters])
	sticks = dom.findall('MarkerSet')[0].find('Sticks')
	sticksPairs = [(x.get('MARKER1'),x.get('MARKER2')) for x in sticks]
	sticksColour= [np.fromstring(x.get('RGB1', '255 255 255'), dtype=np.uint8, sep=' ') for x in sticks]
	hasTargetSet = True
	try: markers = dom.findall('TargetSet')[0].find('Targets')
	except: markers = dom.findall('MarkerSet')[0].find('Markers'); hasTargetSet = False
	markerOffsets = [x.get('POSITION').split() for x in markers]
	def ev(x,params):
		for k,v in params.items(): x = x.replace(k,v)
		return float(x) # eval(x)
	markerOffsets = [[ev(x,params) for x in mp] for mp in markerOffsets]
	markerColour= [np.fromstring(col, dtype=np.uint8, sep=' ') for col in \
						[x.get('MARKER', x.get('RGB')) for x in dom.findall('MarkerSet')[0].find('Markers')]]
	colouredMarkers = [x.get('MARKER', x.get('NAME')) for x in dom.findall('MarkerSet')[0].find('Markers')]
	markerNames = [x.get('MARKER', x.get('NAME')) for x in markers]
	markerWeights = [float(x.get('WEIGHT')) if hasTargetSet else 1.0 for x in markers]
	markerParents = [x.get('SEGMENT') for x in markers]
	skeleton = dom.findall('Skeleton')[0]
	# skeleton is defined as a tree of Segments
	# Segment contains Joint and Segment
	# Joint is JointDummy(0)/JointHinge(1)/JointHardySpicer(2)/JointBall(3)/JointFree(6), containing JointTemplate
	def ap(skeleton, parent, skel):
		for seg in skeleton:
			if seg.tag == 'Segment':
				skel.append([seg.get('NAME'),parent,seg.attrib])
				ap(seg, len(skel)-1, skel)
			else:
				skel[parent].extend([seg.tag,seg.attrib,{} if len(seg) == 0 else seg[0].attrib])
		return skel
	# recursively parse the skeleton
	root = ap(skeleton, -1, [])
	assert(len(markerParents) == len(markerOffsets))
	def cqToR(rs, R):
		'''Given a compressed quaternion, form a 3x3 rotation matrix.'''
		angle = np.dot(rs,rs)**0.5
		scale = (np.sin(angle*0.5)/angle if angle > 1e-8 else 0.5)
		q = np.array([rs[0]*scale,rs[1]*scale,rs[2]*scale,np.cos(angle*0.5)], dtype=np.float32)
		q = np.outer(q, q)*2
		R[:3,:3] = [
			[1.0-q[1, 1]-q[2, 2],     q[0, 1]-q[2, 3],     q[0, 2]+q[1, 3]],
			[    q[0, 1]+q[2, 3], 1.0-q[0, 0]-q[2, 2],     q[1, 2]-q[0, 3]],
			[    q[0, 2]-q[1, 3],     q[1, 2]+q[0, 3], 1.0-q[0, 0]-q[1, 1]]]
	def float3(x): return np.array(map(lambda x:ev(x,params), x.split()),dtype=np.float32)
	def mats(x):
		preT = x.get('PRE-POSITION', '0 0 0')
		postT = x.get('POST-POSITION', '0 0 0')
		preR = x.get('PRE-ORIENTATION', '0 0 0')
		postR = x.get('POST-ORIENTATION', '0 0 0')
		pre = np.zeros((3,4),dtype=np.float32)
		post = np.zeros((3,4),dtype=np.float32)
		pre[:,3] = float3(preT)
		post[:,3] = float3(postT)
		cqToR(float3(preR), pre[:3,:3])
		cqToR(float3(postR), post[:3,:3])
		return pre,post
	name = fn.rpartition('/')[2].partition('.')[0]
	numBones = len(root)
	jointNames = [r[0] for r in root]
	markerParents = np.array([jointNames.index(mp) for mp in markerParents],dtype=np.int32)
	jointNames[0] = 'root' # !!!! WARNING !!!!
	jointParents = [r[1] for r in root]
	jointData = [mats(r[4]) for r in root]
	jointTypes = [r[3] for r in root] # JointDummy(0)/JointHinge(1)/JointHardySpicer(2)/JointBall(3)/JointFree(6)
	#jointTemplates = [mats(r[5]) for r in root] # JointTemplate ... contains the same data as jointTypes
	jointAxes = [r[4].get('AXIS',r[4].get('AXIS-PAIR',r[4].get('EULER-ORDER','XYZ'))) for r in root] # order
	jointTs = [r[4].get('T',None) for r in root]
	Gs = np.zeros((numBones,3,4),dtype=np.float32) # GLOBAL mats
	Ls = np.zeros((numBones,3,4),dtype=np.float32) # LOCAL mats
	Bs = np.zeros((numBones,3),dtype=np.float32) # BONES
	for ji,pi in enumerate(jointParents):
		if pi == -1: Ls[ji] = jointData[ji][0]
		else: np.dot(jointData[pi][1][:,:3],jointData[ji][0],out=Ls[ji]); Ls[ji,:,3] += jointData[pi][1][:,3]
	dofNames = []
	jointChans = [] # tx=0,ty,tz,rx,ry,rz
	jointChanSplits = [0]
	# TODO: locked channels
	for ji,(jt,T) in enumerate(zip(jointTypes,jointTs)):
		jointChanSplits.append(len(jointChans))
		if jt == 'JointDummy': assert(T is None)
		elif jt == 'JointHinge':
			assert(T == '* ')
			jointChans.append(jointAxes[ji].split().index('1')+3)
		elif jt == 'JointHardySpicer':
			assert(T == '* * ')
			ja = jointAxes[ji].split()
			jointChans.append(ja.index('1',3))
			jointChans.append(ja.index('1')+3)
		elif jt == 'JointBall':
			assert(T == '* * * ')
			ja = jointAxes[ji]
			jointChans.append(ord(ja[0])-ord('X')+3)
			jointChans.append(ord(ja[1])-ord('X')+3)
			jointChans.append(ord(ja[2])-ord('X')+3)
		elif jt == 'JointFree':
			assert(T == '* * * * * * ' or T is None) # version 1 of the file apparently doesn't fill this!
			ja = jointAxes[ji]
			jointChans.append(0)
			jointChans.append(1)
			jointChans.append(2)
			jointChanSplits[-1] = len(jointChans)
			jointChans.append(ord(ja[0])-ord('X')+3)
			jointChans.append(ord(ja[1])-ord('X')+3)
			jointChans.append(ord(ja[2])-ord('X')+3)
		for jc in jointChans[jointChanSplits[-2]:]:
			dofNames.append(jointNames[ji]+':'+'tx ty tz rx ry rz'.split()[jc])
		jointChanSplits.append(len(jointChans))
	numDofs = len(dofNames)
	# fill Gs
	chanValues = np.zeros(numDofs,dtype=np.float32)
	rootMat = np.eye(3, 4, dtype=np.float32)

	# fill Bs; TODO add dummy joints to store the extra bones (where multiple joints have the same parent)
	for ji,pi in enumerate(jointParents):
		if pi != -1: Bs[pi] = Ls[ji,:,3]
	Bs[np.where(Bs*Bs<0.01)] = 0 # zero out bones < 0.1mm

	# TODO: compare skeleton with ASF exported version
	skel_dict = {
			'markerOffsets'  : np.array(markerOffsets, dtype=np.float32),
			'markerParents'  : markerParents,
			'markerNames'    : markerNames,
			'markerNamesUnq' : colouredMarkers,
			'markerColour'   : markerColour,
			'markerWeights'  : np.array(markerWeights,dtype=np.float32),
			'numMarkers'     : len(markerNames),
			'sticks'         : sticksPairs,
			'sticksColour'   : sticksColour,
			'name'           : str(name),
			'numJoints'      : int(numBones),
			'jointNames'     : jointNames,  # list of strings
			'jointIndex'     : dict([(k,v) for v,k in enumerate(jointNames)]), # dict of string:int
			'jointParents'   : np.array(jointParents,dtype=np.int32),
			'jointChans'     : np.array(jointChans,dtype=np.int32), # 0 to 5 : tx,ty,tz,rx,ry,rz
			'jointChanSplits': np.array(jointChanSplits,dtype=np.int32),
			'chanNames'      : dofNames,   # list of strings
			'chanValues'     : np.zeros(numDofs,dtype=np.float32),
			'numChans'       : int(numDofs),
			'Bs'             : np.array(Bs, dtype=np.float32),
			'Ls'             : np.array(Ls, dtype=np.float32),
			'Gs'             : np.array(Gs, dtype=np.float32),
			'rootMat'        : rootMat,
			}
	Character.pose_skeleton(skel_dict['Gs'], skel_dict)
	return skel_dict
Beispiel #5
0
def solveIK1Ray(skelDict,
                effectorData,
                x3ds,
                effectorIndices_3d,
                E,
                effectorIndices_2d,
                outerIts=10,
                rootMat=None):
    """
	solveIK routine form Label.py - Has Single ray constraint equations enables

	Given effectors (joint, offset, weight) and constraints for those (3d and 2d), solve for the skeleton pose.
	Effector offsets, weights and targets are 3-vectors
		
	Args:
		skelDict (GskelDict): The Skeleton to process
		effectorData (big o'l structure!):
			effectorJoints, effectorOffsets, effectorWeights, usedChannels, usedChannelWeights, usedCAEs, usedCAEsSplits
		x3ds (float[][3]): 3D Reconstructions
		effectorIndices_3d (?): What's this?
		E (): Equations for 1-Ray constraints, or MDMA.
		effectorIndices_2d (?): What's this?
		outerIts (int): IK Iterations to solve the skeleton. Default = 10
		rootMat (float[3][4]): reference frame of the Skeleton. Default = None
		
	Returns:
		None: The result is an update of the skelDict to the solution - chanValues, channelMats, and Gs.
		
	Requires:
		Character.pose_skeleton_with_chan_mats
		ISCV.derror_dchannel_single_ray
		ISCV.JTJ_single_ray
	"""
    if rootMat is None: rootMat = np.eye(3, 4, dtype=np.float32)
    effectorJoints, effectorOffsets, effectorWeightsOld, usedChannels, usedChannelWeights, usedCAEs, usedCAEsSplits = effectorData
    chanValues = skelDict['chanValues']
    jointParents = skelDict['jointParents']
    Gs = skelDict['Gs']
    Ls = skelDict['Ls']
    jointChans = skelDict['jointChans']
    jointChanSplits = skelDict['jointChanSplits']
    numChannels = jointChanSplits[-1]
    numEffectors = len(effectorJoints)
    num3ds = len(effectorIndices_3d)
    num2ds = len(effectorIndices_2d)
    effectorOffsets = np.copy(effectorOffsets[:, :, 3])
    effectorWeights = np.zeros(numEffectors, dtype=np.float32)
    effectorWeights[
        effectorIndices_3d] = 1  # TODO Why does this fail? effectorWeightsOld[effectorIndices_3d,0,3]
    effectorWeights[
        effectorIndices_2d] = 1  # effectorWeightsOld[effectorIndices_2d,0,3]
    numUsedChannels = len(usedChannels)
    channelMats = np.zeros((numChannels, 3, 4), dtype=np.float32)
    effectors = np.zeros((numEffectors, 3), dtype=np.float32)
    residual = np.zeros((num3ds, 3), dtype=np.float32)
    residual2 = np.zeros((num2ds, 2), dtype=np.float32)
    derrors = np.zeros((numUsedChannels, numEffectors, 3), dtype=np.float32)
    delta = np.zeros((numUsedChannels), dtype=np.float32)
    JTJ = np.zeros((numUsedChannels, numUsedChannels), dtype=np.float32)
    JTB = np.zeros((numUsedChannels), dtype=np.float32)
    JT = derrors.reshape(numUsedChannels, -1)
    JTJdiag = np.diag_indices_from(JTJ)
    for it in xrange(outerIts):
        # TODO, only usedChannels are changing, only update the matrices that have changed after the first iteration.
        # updates the channelMats and Gs
        Character.pose_skeleton_with_chan_mats(channelMats, Gs, skelDict,
                                               chanValues, rootMat)
        bestScore = ISCV.pose_effectors_single_ray(
            effectors, residual, residual2, Gs, effectorJoints,
            effectorOffsets, effectorWeights, x3ds, effectorIndices_3d, E,
            effectorIndices_2d)
        if np.sum(residual * residual) + np.sum(
                residual2 * residual2) <= 1e-5 * (num3ds + num2ds):
            break  # early termination
        ISCV.derror_dchannel_single_ray(derrors, channelMats, usedChannels,
                                        usedChannelWeights, usedCAEs,
                                        usedCAEsSplits, jointChans, effectors,
                                        effectorWeights)
        # J = d_effectors/dc
        # err(c) = x3ds - effectors[effectorIndices_3d], e0 + E effectors[effectorIndices_2d]; err(c+delta) = x3ds - effectors[effectorIndices_3d] - J[effectorIndices_3d] delta, e0 + E effectors[effectorIndices_2d] + E J[effectorIndices_2d] delta  = 0
        # J dc = B; (J[effectorIndices_3d] ; E J[effectorIndices_2d]) dc = B ; e0
        # DLS method : solve (JTJ + k^2 I) delta = JTB
        ISCV.JTJ_single_ray(
            JTJ, JTB, JT, residual, effectorIndices_3d, E, effectorIndices_2d,
            residual2)  #np.dot(JT, B, out=JTB); np.dot(JT, JT.T, out=JTJ)
        JTJ[JTJdiag] += 1
        JTJ[JTJdiag] *= 1.1
        # delta[:] = np.linalg.solve(JTJ, JTB)
        _, delta[:], _ = LAPACK.dposv(JTJ, JTB)  # Use Positive Definite Solver
        chanValues[usedChannels] += delta
        # TODO: add channel limits

        # # J_transpose method, 3d only: scaling problems with translation
        #JT = derrors[:,effectorIndices_3d,:].reshape(numUsedChannels,-1)
        #np.dot(JT, B, out=delta)
        #np.dot(JT.T,delta,out=JJTB)
        #delta *= np.dot(B,JJTB)/(np.dot(JJTB,JJTB)+1)
        #delta[:3] *= 100000.
        #testScale = ISCV.Jtranspose_SR(delta, JJTB, JT, residual,effectorIndices_3d,residual2,effectorIndices_2d)
    Character.pose_skeleton(Gs, skelDict, chanValues, rootMat)
Beispiel #6
0
def solveIK(skelDict,
            chanValues,
            effectorData,
            effectorTargets,
            outerIts=10,
            rootMat=None):
    """
	Given an initial skeleton pose (chanValues), effectors (ie constraints: joint, offset, weight, target), solve for the skeleton pose.
	Effector weights and targets are 3x4 matrices.
		* Setting 1 in the weight's 4th column makes a position constraint.
		* Setting 100 in the weight's first 3 columns makes an orientation constraint.
		
	Args:
		skelDict (GskelDict): The Skeleton to process
		chanValues (float[]): Initial pose of the skeleton as Translation and many rotations applied to joints in the skelDict.
		effectorData (big o'l structure!):
			effectorJoints, effectorOffsets, effectorWeights, usedChannels, usedChannelWeights, usedCAEs, usedCAEsSplits
		effectorTargets (?): What's this?
		outerIts (int): IK Iterations to solve the skeleton. Default = 10
		rootMat (float[3][4]): reference frame of the Skeleton. Default = None
		
	Returns:
		None: The result is an update of the skelDict to the solution - chanValues, channelMats, and Gs.
		
	Requires:
		Character.pose_skeleton_with_chan_mats
		ISCV.pose_effectors
		ISCV.derror_dchannel
		ISCV.JTJ
	"""
    effectorJoints, effectorOffsets, effectorWeights, usedChannels, usedChannelWeights, usedCAEs, usedCAEsSplits = effectorData
    jointParents = skelDict['jointParents']
    Gs = skelDict['Gs']
    Ls = skelDict['Ls']
    jointChans = skelDict['jointChans']
    jointChanSplits = skelDict['jointChanSplits']
    numChannels = jointChanSplits[-1]
    numEffectors = len(effectorJoints)
    numUsedChannels = len(usedChannels)
    channelMats = np.zeros((numChannels, 3, 4), dtype=np.float32)
    #usedEffectors   = np.array(np.where(np.sum(effectorWeights,axis=(1,2)) != 0)[0], dtype=np.int32)
    usedEffectors = np.array(np.where(effectorWeights.reshape(-1) != 0)[0],
                             dtype=np.int32)
    # numUsedEffectors= len(usedEffectors)
    effectors = np.zeros((numEffectors, 3, 4), dtype=np.float32)
    residual = np.zeros((numEffectors, 3, 4), dtype=np.float32)
    derrors = np.zeros((numUsedChannels, numEffectors, 3, 4), dtype=np.float32)
    # steps           = np.ones((numUsedChannels),dtype=np.float32)*0.2
    # steps[np.where(jointChans[usedChannels] < 3)[0]] = 30.
    # steps = 1.0/steps
    delta = np.zeros((numUsedChannels), dtype=np.float32)
    # JJTB            = np.zeros((numEffectors*12),dtype=np.float32)
    JTJ = np.zeros((numUsedChannels, numUsedChannels), dtype=np.float32)
    JTB = np.zeros((numUsedChannels), dtype=np.float32)
    JT = derrors.reshape(numUsedChannels, -1)
    JTJdiag = np.diag_indices_from(JTJ)
    B = residual.reshape(-1)
    # TODO, calculate the exact requirements on the tolerance
    B_len = len(B)
    tolerance = 0.00001
    it_eps = (B_len**0.5) * tolerance
    for it in xrange(outerIts):
        # TODO, only usedChannels are changing, only update the matrices that have changed after the first iteration.
        # TODO Look into damping, possibly clip residuals?
        # updates the channelMats and Gs
        Character.pose_skeleton_with_chan_mats(channelMats, Gs, skelDict,
                                               chanValues, rootMat)
        bestScore = ISCV.pose_effectors(effectors, residual, Gs,
                                        effectorJoints, effectorOffsets,
                                        effectorWeights, effectorTargets)
        if np.linalg.norm(B) < it_eps: break  # early termination
        ISCV.derror_dchannel(derrors, channelMats, usedChannels,
                             usedChannelWeights, usedCAEs, usedCAEsSplits,
                             jointChans, effectors, effectorWeights)
        # if True: # DLS method : solve (JTJ + k^2 I) delta = JTB
        ISCV.JTJ(
            JTJ, JTB, JT, B,
            usedEffectors)  #np.dot(JT, B, out=JTB); np.dot(JT, JT.T, out=JTJ)
        JTJ[JTJdiag] += 1
        JTJ[JTJdiag] *= 1.1
        _, delta[:], _ = LAPACK.dposv(JTJ, JTB)  # Use Positive Definite Solver
        # Use General Solver
        # delta[:] = np.linalg.solve(JTJ, JTB)
        # elif it==0: # SVD method: solve J delta = B
        # 	delta[:] = np.linalg.lstsq(JT.T[usedEffectors], B[usedEffectors], rcond=0.0001)[0].reshape(-1)
        # else:     # J transpose method
        # 	testScale = ISCV.J_transpose(delta, JJTB, JT, B)
        # 	#np.dot(JT, B, out=delta); np.dot(JT.T,delta,out=JJTB); delta *= np.dot(B,JJTB)/(np.dot(JJTB,JJTB)+1.0)
        #scale = np.max(np.abs(delta*steps))
        #if scale > 1.0: delta *= 1.0/scale
        #np.clip(delta,-steps,steps,out=delta)
        chanValues[usedChannels] += delta
        # TODO: add channel limits
        #bestScore = ISCV.lineSearch(chanValues, usedChannels, delta, Gs, Ls, jointParents, jointChans, jointChanSplits,
        #							rootMat, effectorJoints, effectorOffsets, effectorWeights, effectorTargets, innerIts, bestScore)
    #print np.mean(B*B)
    Character.pose_skeleton(Gs, skelDict, chanValues, rootMat)
Beispiel #7
0
def animateHead(newFrame):
    global ted_geom, ted_geom2, ted_shape, tony_geom, tony_shape, tony_geom2, tony_obj, ted_obj, diff_geom, c3d_frames, extract
    global tony_shape_vector, tony_shape_mat, ted_lo_rest, ted_lo_mat, c3d_points
    global md, movies
    tony_geom.image, tony_geom.bindImage, tony_geom.bindId = ted_geom.image, ted_geom.bindImage, ted_geom.bindId  # reuse the texture!
    fo = 55
    MovieReader.readFrame(md, seekFrame=((newFrame + fo) / 2))
    view = QApp.view()
    for ci in range(0, 4):
        view.cameras[ci + 1].invalidateImageData()
    ci = view.cameras.index(view.camera) - 1
    if ci >= 0:
        MovieReader.readFrame(movies[ci],
                              seekFrame=(newFrame +
                                         fo))  # only update the visible camera
    frac = (newFrame % 200) / 100.
    if (frac > 1.0): frac = 2.0 - frac
    fi = newFrame % len(c3d_frames)

    if ted_skel:  # move the skeleton
        dofs = ted_anim['dofData'][fi * 2 - 120]
        Character.pose_skeleton(ted_skel['Gs'], ted_skel, dofs)
        ted_glskel.setPose(ted_skel['Gs'])
        offset = ted_skel['Gs'][13]  # ted_skel['jointNames'].index('VSS_Head')

        cams = QApp.app.getLayers()['cameras']
        tmp = np.eye(4, 4, dtype=np.float32)
        tmp[:3, :] = offset
        cams.setTransform(tmp)

        if ci >= 0:  # move the camera view to be correct
            camRT = mats[ci][1]
            RT = np.dot(camRT, np.linalg.inv(tmp))
            view.cameras[ci + 1].setRT(RT)

        # update the face geometries to fit the skeleton
        ted_geom.setPose(offset.reshape(1, 3, 4))
        tony_geom.setPose(offset.reshape(1, 3, 4))
        #TODO head_points,c3d_points,surface_points,ted_geom2

    frame = c3d_frames[fi][extract]
    which = np.where(frame[:, 3] == 0)[0]
    x3ds = frame[which, :3]
    #print which,x3ds.shape,ted_lo_rest.shape,ted_lo_mat.shape
    bnds = np.array([[0, 1]] * ted_lo_mat.shape[0], dtype=np.float32)
    tony_shape_vector[:] = OBJReader.fitLoResShapeMat(ted_lo_rest,
                                                      ted_lo_mat,
                                                      x3ds,
                                                      Aoffset=10.0,
                                                      Boffset=3.0,
                                                      x_0=tony_shape_vector,
                                                      indices=which,
                                                      bounds=bnds)
    #global tony_shape_vectors; tony_shape_vector[:] = tony_shape_vectors[newFrame%len(tony_shape_vectors)]

    #tony_shape_vector *= 0.
    #tony_shape_vector += (np.random.random(len(tony_shape_vector)) - 0.5)*0.2
    if 1:
        ted_shape_v = np.dot(ted_shape_mat_T, tony_shape_vector).reshape(-1, 3)
    else:
        ted_shape_v = np.zeros_like(ted_obj['v'])
        ISCV.dot(ted_shape_mat_T, tony_shape_vector, ted_shape_v.reshape(-1))
    tony_shape_v = ted_shape_v
    #tony_shape_v = tony_shape['v']*frac
    ted_geom.setVs(ted_obj['v'] + ted_shape_v)  #ted_shape['v'] * frac)
    tony_geom.setVs(tony_obj['v'] + tony_shape_v -
                    np.array([200, 0, 0], dtype=np.float32))
    ted_geom2.setVs(ted_obj['v'] * (1.0 - frac) +
                    tony_tedtopo_obj['v'] * frac +
                    np.array([200, 0, 0], dtype=np.float32))
    #if len(ted_shape_v) == len(tony_shape_v):
    #	tony_geom2.setVs(tony_obj['v'] + ted_shape_v - [400,0,0])
    #	diff_geom.setVs(ted_obj['v'] + tony_shape_v - ted_shape_v - [600,0,0])

    #print [c3d_labels[i] for i in which]
    surface_points.vertices = np.dot(ted_lo_mat.T,
                                     tony_shape_vector).T + ted_lo_rest
    surface_points.colour = [0, 1, 0, 1]  # green
    c3d_points.vertices = x3ds
    c3d_points.colour = [1, 0, 0, 1]  # red

    QApp.app.refreshImageData()
    QApp.app.updateGL()