Skip to content

fossil_curvature

Per-vertex Gaussian curvature via angle defect.

Source: src/third_party/FOSSIL/src/lib/fossil_curvature.f90

Dependencies

Contents

Variables

NameTypeAttributesDescription
CURV_STATUS_OKinteger(kind=I4P)parameter
CURV_STATUS_BAD_INPUTinteger(kind=I4P)parameterEmpty facet array or pool not initialized.
CURV_STATUS_DEGENERATE_TRIANGLEinteger(kind=I4P)parameterAt least one triangle has area below tolerance; affected vertices skip that triangle.
DEGENERATE_AREA_TOLreal(kind=R8P)parameter
PIreal(kind=R8P)parameter

Subroutines

build_gaussian_curvature

Compute per-vertex Gaussian curvature K(1:n_vertices) via the angle-defect formula.

Vertices whose accumulated barycentric area is zero (no incident triangle survived the degenerate filter) get K = 0 — defensible default since the angle defect is undefined for an isolated vertex.

Boundary vertices use the (pi - sum angles) numerator; interior vertices use (2*pi - sum angles). Boundary detection via facet%fcon_edge == 0 on either incident edge.

fortran
subroutine build_gaussian_curvature(facet, pool, K, status)

Arguments

NameTypeIntentAttributesDescription
facettype(facet_object)in
pooltype(vertex_pool_object)in
Kreal(kind=R8P)outallocatable
statusinteger(kind=I4P)outoptional

Call graph

build_mean_curvature

Compute per-vertex signed mean curvature H(1:n_vertices) via

H_i * n_i = (1/2) M^-1 (L V)_i

where L is the cotangent Laplacian, M is the diagonal barycentric mass, and V is the per-vertex coordinate field.

Sign convention: H > 0 at convex-outward vertices (sphere surface, cube corners), H < 0 at saddle / concave-outward vertices. Sign is set by projecting the mean-curvature normal vector onto the per-vertex angle-weighted pseudo-normal (facet%vertex_pnormal, populated by surface%analyze); the magnitude is (1/2) ||M^-1 L V||.

Important note retracting an earlier claim: the §2.4 commit message that shipped Gaussian curvature stated mean curvature needed a sparse linear solver. That was wrong. The mass matrix M is diagonal (barycentric per the §2.1 builder), so M^-1 is just per-row scalar division. Mean H is shippable today without any external solver.

Pre-conditions:

  • pool initialized.
  • analyze has run (pseudo-normals populated). All public surface construction paths ensure both.

Vertices with no surviving incident triangle (e.g. all triangles degenerate) get H = 0 — defensible default.

fortran
subroutine build_mean_curvature(facet, pool, H, status)

Arguments

NameTypeIntentAttributesDescription
facettype(facet_object)in
pooltype(vertex_pool_object)in
Hreal(kind=R8P)outallocatable
statusinteger(kind=I4P)outoptional

Call graph

Functions

angle_at

Angle between vectors u and v via atan2(|u x v|, u . v). Well- conditioned across the full [0, pi] range — beats acos(dot/norms) which loses precision near 0 and pi.

Attributes: pure

Returns: real(kind=R8P)

fortran
function angle_at(u, v) result(theta)

Arguments

NameTypeIntentAttributesDescription
utype(vector_R8P)in
vtype(vector_R8P)in

Call graph