forked from TimoBolkart/voca
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlbs.py
executable file
·80 lines (60 loc) · 2.79 KB
/
lbs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
'''
Copyright 2015 Matthew Loper, Naureen Mahmood and the Max Planck Gesellschaft. All rights reserved.
This software is provided for research purposes only.
By using this software you agree to the terms of the SMPL Model license here http://smpl.is.tue.mpg.de/license
More information about SMPL is available here http://smpl.is.tue.mpg.
For comments or questions, please email us at: [email protected]
About this file:
================
This file defines linear blend skinning for the SMPL loader which
defines the effect of bones and blendshapes on the vertices of the template mesh.
Modules included:
- global_rigid_transformation:
computes global rotation & translation of the model
- verts_core: [overloaded function inherited from verts.verts_core]
computes the blending of joint-influences for each vertex based on type of skinning
'''
from smpl_webuser.posemapper import posemap
import chumpy
import numpy as np
def global_rigid_transformation(pose, J, kintree_table, xp):
results = {}
pose = pose.reshape((-1,3))
id_to_col = {kintree_table[1,i] : i for i in range(kintree_table.shape[1])}
parent = {i : id_to_col[kintree_table[0,i]] for i in range(1, kintree_table.shape[1])}
if xp == chumpy:
from smpl_webuser.posemapper import Rodrigues
rodrigues = lambda x : Rodrigues(x)
else:
import cv2
rodrigues = lambda x : cv2.Rodrigues(x)[0]
with_zeros = lambda x : xp.vstack((x, xp.array([[0.0, 0.0, 0.0, 1.0]])))
results[0] = with_zeros(xp.hstack((rodrigues(pose[0,:]), J[0,:].reshape((3,1)))))
for i in range(1, kintree_table.shape[1]):
results[i] = results[parent[i]].dot(with_zeros(xp.hstack((
rodrigues(pose[i,:]),
((J[i,:] - J[parent[i],:]).reshape((3,1)))
))))
pack = lambda x : xp.hstack([np.zeros((4, 3)), x.reshape((4,1))])
results = [results[i] for i in sorted(results.keys())]
results_global = results
if True:
results2 = [results[i] - (pack(
results[i].dot(xp.concatenate( ( (J[i,:]), 0 ) )))
) for i in range(len(results))]
results = results2
result = xp.dstack(results)
return result, results_global
def verts_core(pose, v, J, weights, kintree_table, want_Jtr=False, xp=chumpy):
A, A_global = global_rigid_transformation(pose, J, kintree_table, xp)
T = A.dot(weights.T)
rest_shape_h = xp.vstack((v.T, np.ones((1, v.shape[0]))))
v =(T[:,0,:] * rest_shape_h[0, :].reshape((1, -1)) +
T[:,1,:] * rest_shape_h[1, :].reshape((1, -1)) +
T[:,2,:] * rest_shape_h[2, :].reshape((1, -1)) +
T[:,3,:] * rest_shape_h[3, :].reshape((1, -1))).T
v = v[:,:3]
if not want_Jtr:
return v
Jtr = xp.vstack([g[:3,3] for g in A_global])
return (v, Jtr)