in contactopt/hand_object.py [0:0]
def generate_pointnet_features(self, obj_sampled_idx):
"""Calculates per-point features for pointnet. DeepContact uses these features"""
obj_mesh = Meshes(verts=[torch.Tensor(self.obj_verts)], faces=[torch.Tensor(self.obj_faces)])
hand_mesh = Meshes(verts=[torch.Tensor(self.hand_verts)], faces=[torch.Tensor(util.get_mano_closed_faces())])
obj_sampled_verts_tensor = obj_mesh.verts_padded()[:, obj_sampled_idx, :]
_, _, obj_nearest = pytorch3d.ops.knn_points(obj_sampled_verts_tensor, hand_mesh.verts_padded(), K=1, return_nn=True) # Calculate on object
_, _, hand_nearest = pytorch3d.ops.knn_points(hand_mesh.verts_padded(), obj_sampled_verts_tensor, K=1, return_nn=True) # Calculate on hand
obj_normals = obj_mesh.verts_normals_padded()
obj_normals = torch.nn.functional.normalize(obj_normals, dim=2, eps=1e-12) # Because buggy mistuned value in Pytorch3d, must re-normalize
norms = torch.sum(obj_normals * obj_normals, dim=2) # Dot product
obj_normals[norms < 0.8] = 0.6 # TODO hacky get-around when normal finding fails completely
self.obj_normals = obj_normals.detach().squeeze().numpy()
obj_sampled_verts = self.obj_verts[obj_sampled_idx, :]
obj_sampled_normals = obj_normals[0, obj_sampled_idx, :].detach().numpy()
hand_normals = hand_mesh.verts_normals_padded()[0, :, :].detach().numpy()
hand_centroid = np.mean(self.hand_verts, axis=0)
obj_centroid = np.mean(self.obj_verts, axis=0)
# Hand features
hand_one_hot = np.ones((self.hand_verts.shape[0], 1))
hand_vec_to_closest = hand_nearest.squeeze().numpy() - self.hand_verts
hand_dist_to_closest = np.expand_dims(np.linalg.norm(hand_vec_to_closest, 2, 1), axis=1)
hand_dist_along_normal = np.expand_dims(np.sum(hand_vec_to_closest * hand_normals, axis=1), axis=1)
hand_dist_to_joint = np.expand_dims(self.hand_verts, axis=1) - np.expand_dims(self.hand_joints, axis=0) # Expand for broadcasting
hand_dist_to_joint = np.linalg.norm(hand_dist_to_joint, 2, 2)
hand_dot_to_centroid = np.expand_dims(np.sum((self.hand_verts - obj_centroid) * hand_normals, axis=1), axis=1)
# Object features
obj_one_hot = np.zeros((obj_sampled_verts.shape[0], 1))
obj_vec_to_closest = obj_nearest.squeeze().numpy() - obj_sampled_verts
obj_dist_to_closest = np.expand_dims(np.linalg.norm(obj_vec_to_closest, 2, 1), axis=1)
obj_dist_along_normal = np.expand_dims(np.sum(obj_vec_to_closest * obj_sampled_normals, axis=1), axis=1)
obj_dist_to_joint = np.expand_dims(obj_sampled_verts, axis=1) - np.expand_dims(self.hand_joints, axis=0) # Expand for broadcasting
obj_dist_to_joint = np.linalg.norm(obj_dist_to_joint, 2, 2)
obj_dot_to_centroid = np.expand_dims(np.sum((obj_sampled_verts - hand_centroid) * obj_sampled_normals, axis=1), axis=1)
# hand_feats = np.concatenate((hand_one_hot, hand_normals, hand_vec_to_closest, hand_dist_to_closest, hand_dist_along_normal, hand_dist_to_joint), axis=1)
# obj_feats = np.concatenate((obj_one_hot, obj_sampled_normals, obj_vec_to_closest, obj_dist_to_closest, obj_dist_along_normal, obj_dist_to_joint), axis=1)
hand_feats = np.concatenate((hand_one_hot, hand_dot_to_centroid, hand_dist_to_closest, hand_dist_along_normal, hand_dist_to_joint), axis=1)
obj_feats = np.concatenate((obj_one_hot, obj_dot_to_centroid, obj_dist_to_closest, obj_dist_along_normal, obj_dist_to_joint), axis=1)
return hand_feats, obj_feats