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