MCPcopy Create free account
hub / github.com/DeepGraphLearning/S3F / curvatures

Function curvatures

s3f/surface.py:415–489  ·  view source on GitHub ↗
(
    vertices, triangles=None, scales=[1.0], batch=None, normals=None, reg=1e-10
)

Source from the content-addressed store, hash-verified

413
414
415def curvatures(
416 vertices, triangles=None, scales=[1.0], batch=None, normals=None, reg=1e-10
417):
418 # Number of points, number of scales:
419 N, S = vertices.shape[0], len(scales)
420 #ranges = diagonal_ranges(batch)
421
422 # Compute the normals at different scales + vertice areas:
423 normals_s, _ = mesh_normals_areas(
424 vertices, triangles=triangles, normals=normals, scale=scales, batch=batch
425 ) # (N, S, 3), (N,)
426
427 # Local tangent bases:
428 uv_s = tangent_vectors(normals_s) # (N, S, 2, 3)
429
430 features = []
431
432 for s, scale in enumerate(scales):
433 # Extract the relevant descriptors at the current scale:
434 normals = normals_s[:, s, :].contiguous() # (N, 3)
435 uv = uv_s[:, s, :, :].contiguous() # (N, 2, 3)
436
437 # Encode as symbolic tensors:
438 # Points:
439 x_i = LazyTensor(vertices.view(N, 1, 3))
440 x_j = LazyTensor(vertices.view(1, N, 3))
441 # Normals:
442 n_i = LazyTensor(normals.view(N, 1, 3))
443 n_j = LazyTensor(normals.view(1, N, 3))
444 # Tangent bases:
445 uv_i = LazyTensor(uv.view(N, 1, 6))
446
447 # Pseudo-geodesic squared distance:
448 d2_ij = ((x_j - x_i) ** 2).sum(-1) * ((2 - (n_i | n_j)) ** 2) # (N, N, 1)
449 # Gaussian window:
450 window_ij = (-d2_ij / (2 * (scale ** 2))).exp() # (N, N, 1)
451
452 # Project on the tangent plane:
453 P_ij = uv_i.matvecmult(x_j - x_i) # (N, N, 2)
454 Q_ij = uv_i.matvecmult(n_j - n_i) # (N, N, 2)
455 # Concatenate:
456 PQ_ij = P_ij.concat(Q_ij) # (N, N, 2+2)
457
458 # Covariances, with a scale-dependent weight:
459 PPt_PQt_ij = P_ij.tensorprod(PQ_ij) # (N, N, 2*(2+2))
460 PPt_PQt_ij = window_ij * PPt_PQt_ij # (N, N, 2*(2+2))
461
462 # Reduction - with batch support:
463 #PPt_PQt_ij.ranges = ranges
464 PPt_PQt = PPt_PQt_ij.sum(1) # (N, 2*(2+2))
465
466 # Reshape to get the two covariance matrices:
467 PPt_PQt = PPt_PQt.view(N, 2, 2, 2)
468 PPt, PQt = PPt_PQt[:, :, 0, :], PPt_PQt[:, :, 1, :] # (N, 2, 2), (N, 2, 2)
469
470 # Add a small ridge regression:
471 PQt[:, 0, 0] += reg
472 PQt[:, 1, 1] += reg

Callers 1

compute_curvaturesFunction · 0.85

Calls 2

mesh_normals_areasFunction · 0.85
tangent_vectorsFunction · 0.85

Tested by

no test coverage detected