.nornir/assets/map3d-clip-pipeline.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1320 560" font-family="'DejaVu Sans', 'Segoe UI', sans-serif">
<defs>
<linearGradient id="board" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#0b1c2e"/><stop offset="1" stop-color="#06111d"/>
</linearGradient>
<linearGradient id="chip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#14384f"/><stop offset="1" stop-color="#0e2a3e"/>
</linearGradient>
<linearGradient id="newchip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#1d6f4f"/><stop offset="1" stop-color="#10402f"/>
</linearGradient>
<linearGradient id="bug" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#6f2330"/><stop offset="1" stop-color="#401018"/>
</linearGradient>
<marker id="arrow" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto">
<path d="M0,0 L7,3 L0,6 Z" fill="#6fd3f5"/>
</marker>
</defs>
<rect x="0" y="0" width="1320" height="560" fill="url(#board)"/>
<g stroke="#143a52" stroke-width="1"><line x1="0" y1="92" x2="1320" y2="92"/><line x1="0" y1="470" x2="1320" y2="470"/></g>
<g fill="#16415c"><circle cx="40" cy="40" r="2"/><circle cx="1280" cy="40" r="2"/><circle cx="40" cy="520" r="2"/><circle cx="1280" cy="520" r="2"/></g>
<!-- title -->
<text x="40" y="42" fill="#eaf6ff" font-size="22" font-weight="700">facett-map3d · clip → pixel</text>
<text x="372" y="42" fill="#9fc9e0" font-size="14">extruded mesh → <tspan fill="#bfe6ff" font-weight="700">8 composable part-steps</tspan>, <tspan fill="#7be3ad" font-weight="700">each emit-tapped + benched</tspan></text>
<g font-size="12">
<rect x="40" y="62" width="26" height="13" rx="3" fill="url(#newchip)"/><text x="72" y="73" fill="#cfe6f5">NEW (the fix)</text>
<rect x="200" y="62" width="26" height="13" rx="3" fill="url(#bug)"/><text x="232" y="73" fill="#cfe6f5">bug oracle</text>
<rect x="360" y="62" width="26" height="13" rx="3" fill="url(#chip)"/><text x="392" y="73" fill="#cfe6f5">existing step</text>
<line x1="520" y1="69" x2="556" y2="69" stroke="#6fd3f5" stroke-width="3" marker-end="url(#arrow)"/><text x="564" y="73" fill="#cfe6f5">data flow (shape on edge)</text>
</g>
<!-- step chips: 8 across two rows -->
<!-- row 1 -->
<g text-anchor="middle">
<!-- 1 near-clip NEW -->
<rect x="44" y="140" width="150" height="86" rx="10" fill="url(#newchip)" stroke="#27a36f" stroke-width="2"/>
<text x="119" y="168" fill="#eaf6ff" font-size="13" font-weight="700">1 near-plane clip</text>
<text x="119" y="186" fill="#bfe7d4" font-size="10">Sutherland–Hodgman</text>
<text x="119" y="200" fill="#bfe7d4" font-size="10">view-space, z=near</text>
<text x="119" y="217" fill="#7be3ad" font-size="9.5">bench: near_clip</text>
<!-- 2 project -->
<rect x="234" y="140" width="150" height="86" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="309" y="168" fill="#eaf6ff" font-size="13" font-weight="700">2 project</text>
<text x="309" y="186" fill="#9fc9e0" font-size="10">cam.project(), once</text>
<text x="309" y="203" fill="#6fd3f5" font-size="9.5">emit: coords_in==out</text>
<text x="309" y="217" fill="#7be3ad" font-size="9.5">bench: project</text>
<!-- 3 frustum cull -->
<rect x="424" y="140" width="150" height="86" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="499" y="168" fill="#eaf6ff" font-size="13" font-weight="700">3 frustum cull</text>
<text x="499" y="186" fill="#9fc9e0" font-size="10">near / far drop</text>
<text x="499" y="203" fill="#6fd3f5" font-size="9.5">emit: in≥out</text>
<text x="499" y="217" fill="#7be3ad" font-size="9.5">bench: cull</text>
<!-- 4 back-face -->
<rect x="614" y="140" width="150" height="86" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="689" y="168" fill="#eaf6ff" font-size="13" font-weight="700">4 back-face cull</text>
<text x="689" y="186" fill="#9fc9e0" font-size="10">CCW screen-space</text>
<text x="689" y="203" fill="#6fd3f5" font-size="9.5">emit: backface_dropped</text>
<text x="689" y="217" fill="#7be3ad" font-size="9.5">(folded into cull)</text>
</g>
<!-- arrows row 1 -->
<g stroke="#6fd3f5" stroke-width="2.5" fill="none">
<line x1="194" y1="183" x2="230" y2="183" marker-end="url(#arrow)"/>
<line x1="384" y1="183" x2="420" y2="183" marker-end="url(#arrow)"/>
<line x1="574" y1="183" x2="610" y2="183" marker-end="url(#arrow)"/>
</g>
<g fill="#7fb0cc" font-size="9" text-anchor="middle">
<text x="212" y="178">tris</text><text x="402" y="178">px</text><text x="592" y="178">tris</text>
</g>
<!-- elbow 4 -> 5 -->
<path d="M764,183 L794,183 L794,330 L74,330 L74,358" stroke="#6fd3f5" stroke-width="2.5" fill="none" marker-end="url(#arrow)"/>
<!-- row 2 -->
<g text-anchor="middle">
<!-- 5 shade -->
<rect x="44" y="358" width="150" height="86" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="119" y="386" fill="#eaf6ff" font-size="13" font-weight="700">5 shade</text>
<text x="119" y="404" fill="#9fc9e0" font-size="10">fog + dir light</text>
<text x="119" y="421" fill="#6fd3f5" font-size="9.5">emit: lit_fraction</text>
<text x="119" y="435" fill="#7be3ad" font-size="9.5">bench: shade</text>
<!-- 6 depth-sort -->
<rect x="234" y="358" width="150" height="86" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="309" y="386" fill="#eaf6ff" font-size="13" font-weight="700">6 depth-sort</text>
<text x="309" y="404" fill="#9fc9e0" font-size="10">painter far→near</text>
<text x="309" y="421" fill="#6fd3f5" font-size="9.5">emit: is_monotone</text>
<text x="309" y="435" fill="#7be3ad" font-size="9.5">bench: depth_sort</text>
<!-- 7 scissor BUG -->
<rect x="424" y="358" width="150" height="86" rx="10" fill="url(#bug)" stroke="#e0667a" stroke-width="2.2"/>
<text x="499" y="384" fill="#ffe7ec" font-size="13" font-weight="700">7 rect scissor</text>
<text x="499" y="401" fill="#f3c2cd" font-size="10">clip_poly_to_rect</text>
<text x="499" y="416" fill="#ffd0db" font-size="9.5" font-weight="700">ink_outside_rect==0</text>
<text x="499" y="435" fill="#7be3ad" font-size="9.5">bench: scissor</text>
<!-- 8 composite -->
<rect x="614" y="358" width="150" height="86" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="689" y="384" fill="#eaf6ff" font-size="13" font-weight="700">8 rasterize</text>
<text x="689" y="401" fill="#9fc9e0" font-size="10">CPU painter / GPU</text>
<text x="689" y="416" fill="#6fd3f5" font-size="9.5">emit: PNG blob</text>
<text x="689" y="435" fill="#7be3ad" font-size="9.5">bench: composite</text>
</g>
<!-- arrows row 2 -->
<g stroke="#6fd3f5" stroke-width="2.5" fill="none">
<line x1="194" y1="401" x2="230" y2="401" marker-end="url(#arrow)"/>
<line x1="384" y1="401" x2="420" y2="401" marker-end="url(#arrow)"/>
<line x1="574" y1="401" x2="610" y2="401" marker-end="url(#arrow)"/>
</g>
<g fill="#7fb0cc" font-size="9" text-anchor="middle">
<text x="212" y="396">tris</text><text x="402" y="396">ordered</text><text x="592" y="396">3..7-gon</text>
</g>
<!-- final picture out -->
<rect x="820" y="358" width="220" height="86" rx="10" fill="url(#chip)" stroke="#6fd3f5" stroke-width="2.2"/>
<text x="930" y="388" fill="#eaf6ff" font-size="13" font-weight="700">FINAL PICTURE</text>
<text x="930" y="406" fill="#9fc9e0" font-size="10" text-anchor="middle">emitted as PNG blob → warehouse</text>
<text x="930" y="423" fill="#7be3ad" font-size="10" text-anchor="middle">agent Reads it — no human asked</text>
<line x1="764" y1="401" x2="816" y2="401" stroke="#6fd3f5" stroke-width="2.5" marker-end="url(#arrow)"/>
<!-- footnote -->
<text x="40" y="502" fill="#5f93b0" font-size="11">Replaces the brittle <tspan fill="#cfe6f5">near-singularity spoke reject</tspan> + <tspan fill="#cfe6f5">screen-extent guard</tspan> with the geometric step-1 clip. Every step: inject input → assert emit → part-bench. testmatrix-gated; stripped in release.</text>
</svg>