How the Utility‑Model Structure‑Line‑Art Pipeline Combines SVG Parts and Overlays Callout Numbers
The utility‑model structure‑line‑art pipeline builds an editable SVG assembly from individual part SVGs, then overlays numbered callouts using persisted vision‑model anchors.
The handsomestWei/patent-disclosure-skill repository implements a two‑stage pipeline for generating patent‑style technical illustrations. This article explains how the structure line art pipeline composes modular SVG parts and layers callout numbers on top—preserving full editability for utility model disclosures.
Stage 1: Preparing and Composing Per‑Part SVGs
The first stage transforms source images into discrete, reusable SVG components. The entry point is structure_lineart_compose.py, which orchestrates this decomposition.
The Compose Schema
The pipeline reads a YAML configuration (structure_lineart_compose.yaml) that defines the assembly structure. Each part entry specifies:
id– A unique token identifying the componentsource– One of three types:crop,image, orplaceholderslot– Normalized coordinates (x,y,w,has percentages) for placement
Three Source Types for Part Generation
The _write_part_svg() function handles each source type differently:
| Source Type | Behavior | Use Case |
|---|---|---|
| Crop | Extracts a rectangular region from a source PNG/JPEG and converts it to SVG | Selecting regions from photographs or scans |
| Image | Embeds a pre‑generated PNG that scales to fit the slot | Reusing externally rendered part images |
| Placeholder | Draws a dashed rectangle when no visual source exists | Reserving space for unillustrated components |
Building the Layered Assembly
The render_view() function in structure_lineart_compose.py iterates over resolved parts and computes absolute placement coordinates from slot percentages. Key implementation details:
- Child SVGs are stored under
…/parts/and referenced via relative<image>elements - Each part wraps in
<g id="part‑{token}" …>groups, preserving original IDs for downstream identification - No base‑64 embedding—keeping files lightweight and human‑editable
- Canvas dimensions derive from
_canvas_size(), using either explicit settings or source image dimensions
The output is a single SVG where each part remains a separate, addressable layer.
Stage 2: Generating Callout Metadata
Before overlaying numbers, the pipeline validates callout requirements and produces anchor data. This intermediary stage lives in structure_lineart_gate.py.
The Brief Schema Validation
structure_lineart_gate.py validates structure_lineart_brief.yaml against its schema. This brief specifies:
- Visible part IDs – Which components appear in each view
- Callout mode –
overlay(numbers on image),in_prompt(numbers in generation prompt), orcontour_only(silhouette without labels) - LLM prompt – Instructions for rendering the raw line‑art "contour" pass
Persisting Anchor Positions
After the contour pass completes, a vision model analyzes the output and writes normalized anchor coordinates to structure_callout_anchors.yaml. These anchors define where each callout number should appear—separating positioning logic from the final rendering stage.
Stage 3: Overlaying Callout Numbers
The final stage injects numbered leader lines into the composed SVG. structure_callout_overlay.py performs this merge.
Loading and Positioning Anchors
For each view, the script:
- Loads the base image—either the composed SVG from Stage 1 or an original raster fallback
- Converts normalized anchor coordinates to absolute pixel positions via
_point() - Computes both anchor (where the line touches the part) and label (where the number appears) positions
Generating Callout Markup
The callouts_markup() function produces SVG elements for:
- Leader lines connecting parts to their labels
- Numeric labels with configurable styling (font size, line width)
- Optional circular backgrounds behind numbers
Style options are read from the pipeline configuration, allowing consistent patent‑office formatting.
Injecting into the Document
The inject_callouts() function inserts generated markup between XML comment markers:
<!-- structure-callouts -->
[generated leader lines and numbers]
<!-- /structure-callouts -->
This insertion pattern enables:
- Idempotent re‑runs – Old callouts are replaced, not duplicated
- Manual editing – Human reviewers can adjust positions between comments
- Tool interoperability – Other processors can locate and modify callout regions
Complete Pipeline Walkthrough
from pathlib import Path
from tools.shared.structure_lineart_compose import load_data, render_view as compose_view
from tools.shared.structure_callout_overlay import load_data as load_manifest, render_view as overlay_view
# Stage 1: Compose parts into unified SVG
compose = load_data(Path("case/structure_lineart_compose.yaml"))
view = compose["views"][0]
composed_svg = compose_view(compose, view, Path("case"))
print(f"Composed SVG: {composed_svg}")
# Stage 3: Overlay callout numbers
manifest = load_data(Path("case/structure_callout_anchors.yaml"))
for view in manifest["views"]:
final_svg = overlay_view(view, Path("case"))
print(f"Final SVG with callouts: {final_svg}")
Key Implementation Files
| File | Purpose |
|---|---|
tools/shared/structure_lineart_compose.py |
Decomposes source images into per‑part SVGs and assembles the layered composition |
tools/shared/structure_lineart_gate.py |
Validates briefs, generates contour jobs, and persists anchor metadata |
tools/shared/structure_callout_overlay.py |
Reads anchors and injects numbered leader lines into the final SVG |
references/schemas/structure_lineart_compose.schema.yaml |
Schema for part definitions and slot configurations |
references/schemas/structure_lineart_brief.schema.yaml |
Schema for callout modes and view specifications |
references/schemas/structure_callout_anchors.schema.yaml |
Schema for vision‑model anchor coordinates |
Summary
- The structure line art pipeline separates composition from annotation—parts assemble first, callouts apply second
- SVG layering preserves editability—relative
<image>references keep files small and hand‑modifiable - Three source types (
crop,image,placeholder) handle diverse input conditions - Anchor persistence decouples vision processing from rendering—enabling human review of AI‑generated positions
- Comment‑delimited injection makes callout updates safe and repeatable
Frequently Asked Questions
How does the pipeline handle missing part images?
When no visual source exists, structure_lineart_compose.py generates a placeholder—a dashed rectangle drawn by _write_part_svg(). This reserves slot space and maintains consistent part numbering without breaking the composition.
Can I manually adjust callout positions after automated overlay?
Yes. The inject_callouts() function places all markup between <!-- structure-callouts --> and <!-- /structure-callouts --> comments. You can edit SVG coordinates within these boundaries; subsequent pipeline runs will replace only this delimited region.
Why are child SVGs referenced rather than embedded?
The pipeline uses relative <image> elements pointing to …/parts/ files instead of base‑64 encoding. This keeps the top‑level SVG editable in standard vector tools, enables part‑level version control, and reduces file sizes for complex assemblies.
What callout modes are available for different patent requirements?
Three modes control annotation behavior: overlay draws numbers on the final image; in_prompt includes numbers during LLM generation (for integrated labels); contour_only produces silhouette illustrations without any numbering. Mode selection happens in structure_lineart_brief.yaml.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →