How to Create Snapshots for CAD Review and Validation in Text-to-CAD

The snapshot skill in earthtojake/text-to-cad converts STEP models into rendered images (PNG, GLB, 3MF) using a headless Chromium browser via Playwright, enabling automated design review and validation pipelines.

The text-to-cad repository provides a powerful snapshot skill that transforms STEP files into visual assets for documentation and quality assurance. Learning how to create snapshots for CAD review and validation allows you to automate design checks and generate consistent documentation across your engineering workflow. This guide covers the command-line interface and programmatic APIs based on the actual implementation in skills/cad/scripts/snapshot/__main__.py.

Understanding the Snapshot Architecture

The snapshot system consists of three tightly-coupled components defined in the source code.

CLI Parser and Options Builder

The parse_snapshot_args function in skills/cad/scripts/snapshot/__main__.py builds a SnapshotOptions object from command-line flags, validating inputs and merging per-job selection options. This component handles path resolution for STEP files and enforces mutually exclusive constraints, such as preventing simultaneous use of --focus and --hide selectors.

Headless Browser Renderer

The BatchSnapshotRenderer class launches a headless Chromium instance via Playwright and orchestrates the rendering pipeline. It manages viewport sizing through max_output_size, which inspects output dimensions in batch jobs and defaults to constants like SIMPLE_RENDER_WIDTH = 1200 defined at the module level. The renderer wraps each operation with with_snapshot_timeout, enforcing DEFAULT_TIMEOUT_SECONDS (300 seconds) before raising a SnapshotError.

Runtime JavaScript Assets

The browser loads skills/cad/scripts/snapshot/runtime/snapshot-render.js, which exposes window.__snapshotRender. This function loads the STEP model via the cadpy library, applies appearance and display settings, and captures the canvas as a data-URL or generates GLB/3MF payloads. The CLI then decodes this payload through write_output_payload and writes the final file.

Preparing a Render Job

A render job is a JSON object describing the input model, output format, view configuration, and optional selectors for focus or hiding parts.

Single Job Structure

Minimal jobs require an input path and output destination:

{
  "input": "models/gear.step",
  "output": "snapshots/gear.png",
  "mode": "rendered",
  "appearance": "workbench",
  "display": {
    "projection": "orthographic",
    "exploded": { "enabled": true, "axis": "z", "spacing": 1.5 }
  },
  "camera": "iso",
  "size_profile": "simple"
}

Batch Configuration

For multiple snapshots, wrap jobs in a jobs array or set "single": false. The CLI automatically detects single-job payloads when using top-level keys versus batch arrays.

Running the Snapshot CLI

The entry point is the Python script at skills/cad/scripts/snapshot/__main__.py, invoked as a module. It accepts either direct flags or a JSON job file.

Command-Line Execution

Generate a single PNG from a STEP file using appearance and display settings:

python skills/cad/scripts/snapshot \
  --input models/robot_arm.step \
  --output snapshots/robot_arm.png \
  --appearance workbench \
  --display rendered \
  --camera iso \
  --size-profile diagnostic

Essential CLI Flags

  • --input: Path to .step or .stp file (required unless using --job)
  • --output: Destination path (supports PNG, GLB, 3MF extensions)
  • --appearance: Theme name, JSON object, or path to JSON appearance file
  • --display: Display mode (solid, rendered, transparent) or JSON descriptor
  • --camera: Preset (iso, top, front) or JSON camera definition
  • --focus / --hide: Selector refs like #o1.2 to isolate or hide parts (mutually exclusive)
  • --size-profile: Predefined dimensions (simple, diagnostic, assembly, presentation, orbit, contact-sheet)
  • --view-labels: Burn camera labels into the output image

Batch Rendering

Process multiple jobs using a JSON file:

python skills/cad/scripts/snapshot --job batch.json

Example batch configuration:

{
  "jobs": [
    {
      "input": "models/gear.step",
      "output": "snapshots/gear.png",
      "mode": "rendered",
      "appearance": "workbench",
      "display": "rendered"
    },
    {
      "input": "models/gear.step",
      "output": "snapshots/gear.glb",
      "mode": "view",
      "appearance": "workbench",
      "display": { "mode": "wireframe" }
    }
  ]
}

Programmatic Rendering

Import the renderer directly for integration into Python applications without invoking the CLI:

import asyncio
import json
from skills.cad.scripts.snapshot.__main__ import (
    BatchSnapshotRenderer, 
    normalize_snapshot_job_packet,
    render_resolved_job_packet
)

async def programmatic_render():
    raw = '{"input":"models/part.step","output":"snapshots/part.png"}'
    single, jobs = normalize_snapshot_job_packet(json.loads(raw))
    packet = {"single": single, "jobs": jobs}
    result = await render_resolved_job_packet(packet)
    print(result)

asyncio.run(programmatic_render())

This approach uses render_resolved_job_packet to handle packet processing and print_render_result for status output, mirroring the CLI's internal workflow.

Configuring Advanced Visual Settings

Appearance and Display Modes

The appearance parameter controls materials and lighting themes, while display manages geometry representation (solid, wireframe, transparent). These settings map directly to the runtime JavaScript that configures the WebGL rendering context in snapshot-render.js.

Size Profiles and Viewport Control

Size profiles define canvas dimensions for different use cases:

  • simple: Standard documentation size (1200px width default)
  • diagnostic: Detail-oriented inspection views
  • assembly: Larger canvas for complex multi-part models
  • presentation: Publication-quality high resolution
  • orbit and contact-sheet: Specialized layouts for specific review workflows

The renderer automatically selects the largest required dimensions when processing batches via max_output_size.

Summary

  • The snapshot skill converts STEP models to PNG, GLB, or 3MF formats using a headless Chromium renderer via Playwright, as implemented in skills/cad/scripts/snapshot/__main__.py.
  • Configuration happens through SnapshotOptions parsed by parse_snapshot_args and executed by BatchSnapshotRenderer.
  • Jobs support both single-file and batch modes via JSON configuration, with automatic viewport sizing and 300-second timeout protection via DEFAULT_TIMEOUT_SECONDS.
  • Runtime assets in snapshot-render.js handle the actual WebGL rendering through window.__snapshotRender, utilizing the cadpy library for model conversion and write_output_payload for file serialization.

Frequently Asked Questions

What output formats does the snapshot tool support?

The snapshot tool generates PNG images for documentation, GLB files for web-based 3D viewing, and 3MF files for manufacturing workflows. The format is determined by the file extension specified in the --output flag or JSON job configuration. The runtime JavaScript in snapshot-render.js handles format-specific encoding before returning data to the CLI for writing.

Can I render multiple CAD models in a single command?

Yes. Create a JSON file with a jobs array containing multiple render configurations, then invoke python skills/cad/scripts/snapshot --job batch.json. The BatchSnapshotRenderer reuses the same Chromium instance across jobs, significantly improving performance when generating multiple views of the same assembly or processing multiple parts sequentially.

How do I troubleshoot timeout errors during rendering?

The default DEFAULT_TIMEOUT_SECONDS is set to 300 seconds (5 minutes) in __main__.py. If complex assemblies exceed this limit, the renderer raises a SnapshotError. Ensure Playwright is properly installed with python -m playwright install chromium, and consider simplifying display modes or reducing model complexity. For batch operations, verify that max_output_size calculations do not request excessively large viewports that slow down the browser renderer.

What is the difference between --focus and --hide selectors?

Both options use selector references like #o1.2 to manipulate visibility, but they are mutually exclusive. --focus isolates specific parts while hiding all others, while --hide removes specific parts from view while keeping the rest visible. The CLI parser in parse_snapshot_args aborts with a SnapshotError if you attempt to use both flags simultaneously, enforcing a single visibility strategy per job.

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 →