def batch_sample()

in utils.py [0:0]


def batch_sample(verts, faces, num=10000):
	dist_uni = torch.distributions.Uniform(torch.tensor([0.0]).cuda(), torch.tensor([1.0]).cuda())
	batch_size = verts.shape[0]

	# calculate area of each face
	x1, x2, x3 = torch.split(torch.index_select(verts, 1, faces[:, 0]) - torch.index_select(verts, 1, faces[:, 1]), 1,
							 dim=-1)
	y1, y2, y3 = torch.split(torch.index_select(verts, 1, faces[:, 1]) - torch.index_select(verts, 1, faces[:, 2]), 1,
							 dim=-1)
	a = (x2 * y3 - x3 * y2) ** 2
	b = (x3 * y1 - x1 * y3) ** 2
	c = (x1 * y2 - x2 * y1) ** 2
	Areas = torch.sqrt(a + b + c) / 2
	Areas = Areas.squeeze(-1) / torch.sum(Areas, dim=1)  # percentage of each face w.r.t. full surface area

	# define distrubtions of relative face surface areas
	choices = None
	for A in Areas:
		if choices is None:
			choices = torch.multinomial(A, num, True)  # list of faces to be sampled from
		else:
			choices = torch.cat((choices, torch.multinomial(A, num, True)))

	# select the faces to be used
	select_faces = faces[choices].view(verts.shape[0], 3, num)
	face_arange = verts.shape[1] * torch.arange(0, batch_size).cuda().unsqueeze(-1).expand(batch_size, num)
	select_faces = select_faces + face_arange.unsqueeze(1)
	select_faces = select_faces.view(-1, 3)
	flat_verts = verts.view(-1, 3)

	# sample one point from each
	xs = torch.index_select(flat_verts, 0, select_faces[:, 0])
	ys = torch.index_select(flat_verts, 0, select_faces[:, 1])
	zs = torch.index_select(flat_verts, 0, select_faces[:, 2])
	u = torch.sqrt(dist_uni.sample_n(batch_size * num))
	v = dist_uni.sample_n(batch_size * num)
	points = (1 - u) * xs + (u * (1 - v)) * ys + u * v * zs
	points = points.view(batch_size, num, 3)

	return points