sdf.primitives.ExtrudedPolygon

sdf.primitives.ExtrudedPolygon(
    vertices,
    depth,
    material=None,
    draft=0.0,
    twist=0.0,
)

Solid formed by extruding a polygon profile along the local Z axis.

The profile lies in the local XY plane; the solid spans ±depth/2 in Z (centered on the sketch plane). Use Translate/Rotate — or the construction-layer :func:cadjoint.construction.extrude — for placement.

Parameters

Name Type Description Default
vertices list[Vector2] Ordered profile vertices — Vector2 parameters (or raw (2,) arrays). Parameter references are preserved, so sketch constraints keep acting on the generated solid. required
depth float | Scalar Total extrusion depth (Scalar parameter or float). required
material Optional render material. None
draft float | Scalar Draft angle in degrees. Positive values taper the walls inward as z increases: the profile is exact at z = -depth/2 and the 2D distance is offset by tan(draft)·(z + depth/2) above it. A non-zero draft makes the field a bound (gradient norm up to sec(draft)), not an exact SDF. 0.0
twist float | Scalar Total twist in degrees over the full depth, applied by rotating the query’s XY coordinates by an angle proportional to z (zero at mid-depth, ±twist/2 at the caps). A non-zero twist makes the field non-1-Lipschitz — distances can be overestimated, so sphere-tracing style consumers must shorten their steps. 0.0

Both draft and twist default to 0.0 and are only added to params when non-zero (or given as Parameters), so plain extrusions keep their exact parameter layout and bit-identical field values.

Methods

Name Description
patch_fields Per-edge wall planes plus the two caps — tilted when drafted.
sdf Pure SDF: exact extrusion of the exact polygon distance.

patch_fields

sdf.primitives.ExtrudedPolygon.patch_fields()

Per-edge wall planes plus the two caps — tilted when drafted.

Order: patch k (for k < N) is the wall extruded from profile edge (v_k, v_{k+1}); patch N is the bottom cap (z = -depth/2), patch N+1 the top cap.

A draft keeps every wall a plane. :meth:sdf offsets the 2D profile distance by tan(δ)·(z + depth/2), so wall k’s field is edge_k(x, y) + tan(δ)·(z + depth/2) — linear in x, y and z, just tilted out of vertical by δ about its own profile edge. What the draft does cost is the gradient norm: that expression has |∇| = sec(δ), which is the class docstring’s “the field is a bound, not an exact SDF”. Ownership here is argmin_i |f_i|, and a field that reads sec(δ) times the true distance would claim surface that belongs to its neighbours, so each wall is scaled by cos(δ):

``cos(δ)·edge_k(x, y) + sin(δ)·(z + depth/2)``

Same zero set, unit gradient, honest distances. The caps are untouched — a draft tapers the walls and leaves z = ±depth/2 where they were.

A twist is where this stops: it rotates the profile by an angle proportional to z, so each wall sweeps a helicoid, which is none of the analytic surfaces a consumer can fit. Twisted extrusions therefore report None, drafted ones do not.

sdf

sdf.primitives.ExtrudedPolygon.sdf(p, depth, draft=0.0, twist=0.0, **vertices)

Pure SDF: exact extrusion of the exact polygon distance.

With the default draft=0/twist=0 this is bit-identical to the plain extrusion — the extra terms are skipped for concrete zeros.

Parameters

Name Type Description Default
p Array Query point(s), shape (…, 3). Profile plane is local XY. required
depth Array Total extrusion depth. required
draft Array Draft angle in degrees; offsets the 2D distance by tan(draft)·(z + depth/2) so walls taper inward with +z. 0.0
twist Array Total twist in degrees over the full depth; rotates the query XY by twist·z/depth (non-1-Lipschitz when non-zero). 0.0
**vertices Array v0..v{N-1} profile vertices, each shape (2,). {}

Returns

Name Type Description
Signed distance, shape (…).