Skip to content

Commit e0298c4

Browse files
TMHSDigitalclaude
andauthored
fix(examples): redesign gp-lineart-contour as an inked lighthouse diorama (#279)
The gallery review judged the hero weak: a lone teal octahedron with a cyan outline on a small black stand, a primitive rather than a designed subject. The source is now one cel-shaded mesh (a banded lighthouse with gallery, railing, lantern room and roof, a keeper's cottage, a rowboat on the rocks and a diorama sea with wave crests), so the black Line Art ink is what turns it into an inked illustration. Clear source_object and the same render is a flat model with no lines at all, so the render witnesses the contract. The check and the still now share one camera (Line Art is view-dependent). The gates went from >= 1 stroke / >= 4 points to >= 240 / >= 1320 against a measured 255 / 1393 on 4.5.11, 5.1.2 and 5.2.1. That sits above the count left when any one of contour, crease, material-border or intersection edges is dropped, so every edge type is load-bearing. The flags-off probe now turns off every edge type, and the rebuild must recover the exact first-pass counts. The README documents the NPR stage deviation (cel-shaded emission materials on the default stage). Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 50bd728 commit e0298c4

9 files changed

Lines changed: 832 additions & 383 deletions

File tree

‎README.md‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -811,17 +811,18 @@ round-trips through the raw `POINT` buffer.
811811
</tr>
812812
<tr>
813813
<td width="46%" valign="middle">
814-
<a href="examples/gp-lineart-contour/"><img src="examples/gp-lineart-contour/preview.webp" alt="GP Line Art contour: a faceted teal crystal on a dark studio floor outlined in neon cyan Grease Pencil Line Art strokes, proving modifiers.new LINEART with source_object silhouette evaluation" /></a>
814+
<a href="examples/gp-lineart-contour/"><img src="examples/gp-lineart-contour/preview.webp" alt="GP Line Art contour: a cel-shaded red-and-white lighthouse on a rocky islet with a keeper's cottage and rowboat, inked in bold black Grease Pencil Line Art strokes, proving modifiers.new LINEART with source_object evaluation" /></a>
815815
</td>
816816
<td valign="middle">
817817

818818
### [gp-lineart-contour](examples/gp-lineart-contour/)
819819

820-
Grease Pencil `LINEART` modifier contours via the depsgraph — not Freestyle and
821-
not hand-drawn strokes. `source_object` is load-bearing (clear → 0 strokes);
822-
contour+crease off → 0; restore recovers **10** strokes / **34** points on both
823-
binaries. Stroke width: `thickness` exists on 4.5, `AttributeError` on 5.1 —
824-
portable path is `radius`.
820+
Grease Pencil `LINEART` modifier ink via the depsgraph on a cel-shaded
821+
lighthouse diorama — not Freestyle and not hand-drawn strokes. `source_object`
822+
is load-bearing (clear → 0 strokes); every edge type off → 0; the drawing is
823+
**255** strokes / **1393** points on all three binaries, gated so dropping any
824+
one edge type fails. Stroke width: `thickness` exists on 4.5, `AttributeError`
825+
on 5.1 — portable path is `radius`.
825826

826827
</td>
827828
</tr>
4.13 KB
Loading
-11.6 KB
Loading

‎docs/gallery/gp-lineart-contour/index.html‎

Lines changed: 400 additions & 182 deletions
Large diffs are not rendered by default.

‎docs/gallery/index.html‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,12 +728,12 @@ <h2><a href="sky-texture-sun-elevation/">sky-texture-sun-elevation</a></h2>
728728
</article>
729729
<article class="card" data-tags="grease-pencil line-art modifiers">
730730
<a class="card-media" href="gp-lineart-contour/" tabindex="-1" aria-hidden="true">
731-
<img src="assets/gp-lineart-contour-hero.webp" alt="A translucent teal crystal, a six-sided double pyramid set tip-down in a dark hex mount, its edges traced by cyan Line Art contour strokes." loading="lazy" decoding="async" />
731+
<img src="assets/gp-lineart-contour-hero.webp" alt="A red-and-white lighthouse on a rocky islet with a keeper&#x27;s cottage and a rowboat, on a round blue sea with white wave crests, drawn like a comic panel in bold black Line Art ink." loading="lazy" decoding="async" />
732732
</a>
733733
<div class="card-body">
734734
<h2><a href="gp-lineart-contour/">gp-lineart-contour</a></h2>
735-
<p class="teaches">Grease Pencil LINEART modifier contours via the depsgraph on a faceted crystal. source_object is load-bearing (clear yields 0 strokes); contour+crease off yields 0; restore recovers 2 strokes / 12 points on 4.5.11, 5.1.2 and 5.2.1. Stroke width: thickness exists on 4.5, AttributeError on 5.1 — portable path is radius.</p>
736-
<p class="witnesses"><span class="tag">witnesses</span> AI code still sets LINEART.thickness on 5.1 (AttributeError) or hand-draws strokes / enables Freestyle instead of modifiers.new(..., &#x27;LINEART&#x27;). Clearing source_object or leaving contour+crease off silently yields an empty drawing — the check proves both failure modes and recovery.</p>
735+
<p class="teaches">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.</p>
736+
<p class="witnesses"><span class="tag">witnesses</span> AI code still sets LINEART.thickness on 5.1 (AttributeError) or hand-draws strokes / enables Freestyle instead of modifiers.new(..., &#x27;LINEART&#x27;). Clearing source_object or leaving every edge type off silently yields an empty drawing — the check proves both failure modes and recovery.</p>
737737
<a class="card-link" href="gp-lineart-contour/">View example<span class="sr-only"> gp-lineart-contour</span> <span aria-hidden="true">&rarr;</span></a>
738738
</div>
739739
</article>

‎examples/gallery.json‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,9 @@
473473
{
474474
"name": "gp-lineart-contour",
475475
"dir": "examples/gp-lineart-contour",
476-
"teaches": "Grease Pencil LINEART modifier contours via the depsgraph on a faceted crystal. source_object is load-bearing (clear yields 0 strokes); contour+crease off yields 0; restore recovers 2 strokes / 12 points on 4.5.11, 5.1.2 and 5.2.1. Stroke width: thickness exists on 4.5, AttributeError on 5.1 — portable path is radius.",
477-
"alt": "A translucent teal crystal, a six-sided double pyramid set tip-down in a dark hex mount, its edges traced by cyan Line Art contour strokes.",
478-
"witnessesFix": "AI code still sets LINEART.thickness on 5.1 (AttributeError) or hand-draws strokes / enables Freestyle instead of modifiers.new(..., 'LINEART'). Clearing source_object or leaving contour+crease off silently yields an empty drawing — the check proves both failure modes and recovery.",
476+
"teaches": "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.",
477+
"alt": "A red-and-white lighthouse on a rocky islet with a keeper's cottage and a rowboat, on a round blue sea with white wave crests, drawn like a comic panel in bold black Line Art ink.",
478+
"witnessesFix": "AI code still sets LINEART.thickness on 5.1 (AttributeError) or hand-draws strokes / enables Freestyle instead of modifiers.new(..., 'LINEART'). Clearing source_object or leaving every edge type off silently yields an empty drawing — the check proves both failure modes and recovery.",
479479
"hero": "docs/gallery/assets/gp-lineart-contour-hero.webp",
480480
"preview": "examples/gp-lineart-contour/preview.webp",
481481
"tags": [

‎examples/gp-lineart-contour/README.md‎

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,56 @@
11
# GP Line Art Contour
22

3-
A runnable example that builds a faceted crystal, attaches a Grease Pencil
4-
`LINEART` modifier with `source_type='OBJECT'`, and proves the contour contract
5-
through the depsgraph — including the 4.5 → 5.1 stroke-width trap.
3+
A runnable example that builds a lighthouse on a rocky islet — tower, gallery,
4+
lantern room, keeper's cottage, a hauled-up rowboat and a diorama sea — as one
5+
cel-shaded mesh, attaches a Grease Pencil `LINEART` modifier with
6+
`source_type='OBJECT'`, and proves the contour contract through the depsgraph,
7+
including the 4.5 → 5.1 stroke-width trap.
68

79
**What it witnesses:** the Line Art modifier contract AI-generated NPR code most
810
often gets wrong.
911

1012
- **Contours are a modifier, not Freestyle and not hand-authored strokes.**
1113
`modifiers.new(..., 'LINEART')` on a GPv3 object, with `target_layer` /
12-
`target_material` set, evaluates silhouette edges into drawing strokes.
14+
`target_material` set, evaluates the source mesh's edges into drawing strokes.
1315
- **`source_object` is load-bearing.** Clearing it yields **0** evaluated
14-
strokes (proven in the same check pass). Restoring it recovers the contour.
15-
- **Edge-type flags matter.** A freshly added LINEART with `use_contour` and
16-
`use_crease` both off emits **0** strokes; turning contour (+ crease) back on
17-
recovers the silhouette (**2** strokes / **12** points on every binary for
18-
this crystal + camera; Line Art chains the bipyramid's edges into long
19-
strokes, so the count is low and the gates are lower bounds).
20-
- **Stroke width renamed.** 4.5 exposes both `thickness` (legacy px, set to 45
16+
strokes (proven in the same check pass). Restoring it recovers the drawing.
17+
- **Edge-type flags matter.** A freshly added LINEART with every edge type off
18+
(contour, crease, material borders, intersections, loose, edge marks) emits
19+
**0** strokes. The configured modifier draws **255** strokes / **1393**
20+
points on every binary, and the gates (**≥ 240** strokes, **≥ 1320** points)
21+
sit above the count left when any *one* edge type is dropped — contour 234
22+
strokes, crease 171 / 1099, material borders 247 / 1305, intersections
23+
179 / 921 — so each is load-bearing: the band borders on the tower are
24+
material-border ink, the waterline around each rock is intersection ink.
25+
Rebuilding the modifier must recover exactly the first pass's counts.
26+
- **Stroke width renamed.** 4.5 exposes both `thickness` (legacy px, set to 22
2127
here) and `radius`; 5.1 removes `thickness` (`AttributeError`) and keeps
22-
`radius` only (portable path: `mod.radius = 0.028`).
28+
`radius` only (portable path: `mod.radius = 0.021`).
2329
- **GPv3 address** matches `grease-pencil-rosette`: `grease_pencils_v3` on 4.5,
2430
`grease_pencils` on 5.x.
2531

2632
**What each check catches on failure:** wrong GPv3 collection (exit 2),
2733
`thickness` present/absent on the wrong side of 5.0 (exit 3), lost
28-
`source_object` assignment (exit 4), contour too thin (exit 5), source clear
29-
not zeroing strokes (exit 6), flags-off or restore failure (exit 7).
34+
`source_object` assignment or `use_contour` (exit 4), drawing below the gates
35+
(exit 5), source clear not zeroing strokes (exit 6), flags-off not zeroing
36+
strokes or a rebuild not recovering the same counts (exit 7).
3037

3138
**Version witness:** stroke counts match on 4.5.11 LTS, 5.1.2 and 5.2.1 LTS
32-
(2 strokes / 12 points). The divergence is `thickness` vs `radius`.
39+
(255 strokes / 1393 points). The divergence is `thickness` vs `radius`.
3340

34-
**The still:** the crystal is a hexagonal bipyramid (an equator ring and two
35-
apexes), set tip-down in a two-tier hex mount on the floor. The mount is
36-
render staging, derived from the crystal's lowest evaluated vertex; it is built
37-
after the check, so it never enters the Line Art counts. The still's camera
38-
drops its aim and dollies in along the check camera's bearing, so the crystal
39-
fills the frame with the mount's foot inside it.
41+
**The still:** the check and the still share one camera, because Line Art is
42+
view-dependent — the strokes the check counts are the strokes the still draws.
43+
The mesh is shaded flat (three cel tones), so the black ink is what makes it
44+
read as an inked illustration: clear `source_object` and the same render is a
45+
flat, lineless low-poly model — no band borders, no waterline, no outlines.
46+
47+
### Stage deviation
48+
49+
Line Art is a non-photoreal contract: the hero's materials are cel-shaded
50+
(Diffuse → Shader to RGB → constant ramp, emitted) instead of Principled, so
51+
the ink reads against flat tone fields. The stage itself — floor, wall, world,
52+
key, fill and warm wedge — is the default. The cel shading uses Shader to RGB,
53+
which is EEVEE-only, so `--engine cycles` does not render the look.
4054

4155
## Run
4256

@@ -63,9 +77,9 @@ against it. `10` is the shared framing helper.
6377
| 2 | argparse / usage; also GPv3 collection address contract |
6478
| 3 | LINEART `thickness` / `radius` trap for this Blender |
6579
| 4 | LINEART type, source, or `use_contour` (`--no-contour` lands here) |
66-
| 5 | Evaluated contour too thin |
80+
| 5 | Evaluated drawing below the stroke/point gates |
6781
| 6 | Cleared `source_object` still produced strokes |
68-
| 7 | Contour+crease off still produced strokes, or restore failed |
82+
| 7 | Every edge type off still produced strokes, or the rebuild did not recover the same counts |
6983
| 8 | `--output` produced no file |
7084
| 10 | Gallery framing violation |
7185

0 commit comments

Comments
 (0)