GN Modifier Inputs
Per-modifier Geometry Nodes Float inputs on a shared tree — 4.5/5.1 write mod[identifier], 5.2 writes mod.properties.inputs.Socket_1.value.
examples/gp-lineart-contour/
Grease Pencil LINEART modifier ink via the depsgraph on a cel-shaded lighthouse diorama. source_object is load-bearing (clear yields 0 strokes); every edge type off yields 0; the drawing is 255 strokes / 1393 points on 4.5.11, 5.1.2 and 5.2.1, gated above the count left when any one of contour, crease, material-border or intersection edges is dropped. Stroke width: thickness exists on 4.5, AttributeError on 5.1 — portable path is radius.
Rendered headless by the example itself. Select it to enlarge.
tags grease-pencil line-art modifiers
runs on 4.5 LTS · 5.1 · 5.2 LTS
blender --background --python examples/gp-lineart-contour/gp_lineart_contour.py --
falsify it Breaks the contract on purpose and must exit 5
blender --background --python examples/gp-lineart-contour/gp_lineart_contour.py -- --no-contour
A runnable example that builds a lighthouse on a rocky islet — tower, gallery, lantern room, keeper's cottage, a hauled-up rowboat and a diorama sea — as one cel-shaded mesh, attaches a Grease Pencil LINEART modifier with source_type='OBJECT', and proves the contour contract through the depsgraph, including the 4.5 → 5.1 stroke-width trap.
What it witnesses: the Line Art modifier contract AI-generated NPR code most often gets wrong.
modifiers.new(..., 'LINEART') on a GPv3 object, with target_layer / target_material set, evaluates the source mesh's edges into drawing strokes.source_object is load-bearing. Clearing it yields 0 evaluated strokes (proven in the same check pass). Restoring it recovers the drawing.thickness (legacy px, set to 22 here) and radius; 5.1 removes thickness (AttributeError) and keeps radius only (portable path: mod.radius = 0.021).grease-pencil-rosette: grease_pencils_v3 on 4.5, grease_pencils on 5.x.What each check catches on failure: wrong GPv3 collection (exit 9), thickness present/absent on the wrong side of 5.0 (exit 3), lost source_object assignment (exit 4), drawing below the gates (exit 5; use_contour off lands here), source clear not zeroing strokes (exit 6), flags-off not zeroing strokes or a rebuild not recovering the same counts (exit 7).
Version witness: stroke counts match on 4.5.11 LTS, 5.1.2 and 5.2.1 LTS (255 strokes / 1393 points). The divergence is thickness vs radius.
The still: the check and the still share one camera, because Line Art is view-dependent — the strokes the check counts are the strokes the still draws. The mesh is shaded flat (three cel tones), so the black ink is what makes it read as an inked illustration: clear source_object and the same render is a flat, lineless low-poly model — no band borders, no waterline, no outlines.
Line Art is a non-photoreal contract: the hero's materials are cel-shaded (Diffuse → Shader to RGB → constant ramp, emitted) instead of Principled, so the ink reads against flat tone fields. The stage itself — floor, wall, world, key, fill and warm wedge — is the default. The cel shading uses Shader to RGB, which is EEVEE-only, so --engine cycles does not render the look.
# Depsgraph contour check — the CI check:
blender --background --python gp_lineart_contour.py --
# Falsifier: use_contour off. Must exit non-zero (evaluated strokes below the gates, exit 5).
blender --background --python gp_lineart_contour.py -- --no-contour
# Also render the gallery still:
blender --background --python gp_lineart_contour.py -- --output lineart.png
Per-script sequential checks. 9 is a valid check code; there is no rule against it. 10 is the shared framing helper.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Uncaught exception (FATAL wrapper) |
| 2 | argparse / usage |
| 3 | LINEART thickness / radius trap for this Blender |
| 4 | LINEART type or source |
| 5 | Evaluated drawing below the stroke/point gates (--no-contour lands here) |
| 6 | Cleared source_object still produced strokes |
| 7 | Every edge type off still produced strokes, or the rebuild did not recover the same counts |
| 8 | --output produced no file |
| 9 | GPv3 collection address contract (checked first) |
| 10 | Gallery framing violation |
The blender-smoke workflow runs the check on Blender 5.2 LTS and 4.5 LTS (5.1 on the weekly cron, the needs-5.1 PR label, or manual dispatch). Smoke does not pass --output. Its catalog falsifier is --no-contour (expects exit 5).