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 component
  • source – One of three types: crop, image, or placeholder
  • slot – Normalized coordinates (x, y, w, h as 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), or contour_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:

  1. Loads the base image—either the composed SVG from Stage 1 or an original raster fallback
  2. Converts normalized anchor coordinates to absolute pixel positions via _point()
  3. 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →