skshapes.features package


skshapes.features.curvatures module

Curvature estimators for point clouds and triangular meshes.

class skshapes.features.curvatures.PrincipalCurvatures(kmax: Float32[Tensor, '_'], kmin: Float32[Tensor, '_'])

Bases: NamedTuple

Class to store the principal curvatures.

kmax: Float32[Tensor, '_']

Alias for field number 0

kmin: Float32[Tensor, '_']

Alias for field number 1

class skshapes.features.curvatures.QuadraticCoefficients(coefficients: Float32[Tensor, '_ _'], nuv: dict, r2: Float32[Tensor, '_'])

Bases: NamedTuple

Class to store the coefficients of a quadratic approximation.

coefficients: Float32[Tensor, '_ _']

Alias for field number 0

nuv: dict

Alias for field number 1

r2: Float32[Tensor, '_']

Alias for field number 2

skshapes.features.curvatures.smooth_curvatures(*, vertices, triangles=None, scales=None, batch=None, normals=None, reg=0.01)

Mean (H) and Gauss (K) curvatures at different scales.

points, faces, scales -> (H_1, K_1, …, H_S, K_S) (N, 3), (3, N), (S,) -> (N, S*2)

We rely on a very simple linear regression method, for all vertices:

  1. Estimate normals and surface areas.

  2. Compute a local tangent frame.

  3. In a pseudo-geodesic Gaussian neighborhood at scale s, compute the two (2, 2) covariance matrices PPt and PQt between the displacement vectors “P = x_i - x_j” and the normals “Q = n_i - n_j”, projected on the local tangent plane.

  4. Up to the sign, the shape operator S at scale s is then approximated as “S = (reg**2 * I_2 + PPt)^-1 @ PQt”.

  5. The mean and Gauss curvatures are the trace and determinant of this (2, 2) matrix.

As of today, this implementation does not weigh points by surface areas: this could make a sizeable difference if protein surfaces were not sub-sampled to ensure uniform sampling density.

For convergence analysis, see for instance “Efficient curvature estimation for oriented point clouds”, Cao, Li, Sun, Assadi, Zhang, 2019.

  • vertices (Float32[Tensor, '_ 2'] | Float32[Tensor, '_ 3']) – (N,3) coordinates of the points or mesh vertices.

  • triangles (Int64[Tensor, '_ 3'] | None) – (3,T) mesh connectivity.

  • scales – List of (S,) smoothing scales. Defaults to [1.].

  • batch – Batch vector, as in PyTorch_geometric

  • normals (Float32[Tensor, '_ 2'] | Float32[Tensor, '_ 3'] | None) – (N,3) field of “raw” unit normals.

  • reg (int | float) – Small amount of Tikhonov/ridge regularization in the estimation of the shape operator.


(N, S*2) tensor of mean and Gauss curvatures computed for every point at the required scales.

Return type:


skshapes.features.curvatures.smooth_curvatures_2(*, points, triangles=None, scale=1.0, batch=None, normals=None, reg=0.01)

Curvature as a dictionary of tensors for mean and Gauss.

Return type:


skshapes.features.implicit_quadrics module

Implicit quadrics.

skshapes.features.implicit_quadrics.implicit_quadrics(*, points, weights=None, scale=1.0, batch=None, reg=0.0001)

Fits an implicit quadric to each point of a point cloud.

points, weights -> F (N, 3), (N,) -> (N, 4, 4)

The main reference for this function is the following paper:

Gabriel Taubin, “Estimation of Planar Curves, Surfaces and Nonplanar Space Curves Defined by Implicit Equations, with Applications to Edge and Range Image Segmentation”, IEEE Trans. PAMI, Vol. 13, 1991, pp1115-1138.

See also this StackOverflow answer for a full discussion: # noqa E501

skshapes.features.implicit_quadrics.normalize_point_cloud(*, points, weights)

Point cloud normalization for numerical stability.

skshapes.features.moments module

Moments for point clouds.

skshapes.features.moments.symmetric_sum(a, b)

Symmetric terms that appear in the tensor expansion of (a+b)^n.

skshapes.features.normals module

Point normals and tangent vectors.

skshapes.features.normals.smooth_normals(*, vertices, triangles=None, scale=None, batch=None, normals=None)

Smooth field of normals, possibly at different scales.

points, triangles or normals, scale(s) -> normals (N, 3), (3, T) or (N,3), (S,) -> (N, 3) or (N, S, 3)

Simply put - if triangles are provided:

  • Normals are first computed for every triangle using simple 3D geometry and are weighted according to surface area.

  • The normal at any given vertex is then computed as the weighted average of the normals of all triangles in a neighborhood specified by Gaussian windows whose radii are given in the list of “scales”.

If normals are provided instead, we simply smooth the discrete vector field using Gaussian windows whose radii are given in the list of “scales”.

If more than one scale is provided, normal fields are computed in parallel and returned in a single 3D tensor.

  • vertices (Float32[Tensor, '_ 2'] | Float32[Tensor, '_ 3']) – (N,3) coordinates of mesh vertices or 3D points.

  • triangles (Int64[Tensor, '_ 3'] | None) – (3,T) mesh connectivity. Defaults to None.

  • scale – (S,) radii of the Gaussian smoothing windows.

  • batch – batch vector, as in PyTorch_geometric. Defaults to None.

  • normals (Float32[Tensor, '_ 2'] | Float32[Tensor, '_ 3'] | None) – (N,3) raw normals vectors on the vertices. Defaults to None.


(N,3) or (N,S,3) point normals.

Return type:



Compute tangent vectors to a normal vector field.

Returns a pair of vector fields u and v to complete the orthonormal basis [n,u,v].

normals -> uv (N, 3) or (N, S, 3) -> (N, 2, 3) or (N, S, 2, 3)

This routine assumes that the 3D “normal” vectors are normalized. It is based on the 2017 paper from Pixar, “Building an orthonormal basis, revisited”.


normals – (N,3) or (N,S,3) normals n_i, i.e. unit-norm 3D vectors.


(N,2,3) or (N,S,2,3) unit vectors u_i and v_i to complete the tangent coordinate systems [n_i,u_i,v_i].

Return type:


skshapes.features.structure_tensors module

Structure tensors of a point cloud.

skshapes.features.structure_tensors.structure_tensors(*, points, scale=1.0, ranges=None)

Compute the structure tensors of a point cloud.

  • points (Float32[Tensor, '_ 2'] | Float32[Tensor, '_ 3']) – Coordinates of the points or mesh vertices.

  • scale (int | float) – Smoothing scale.


Tensor of structure tensors.

Return type: