PluginBench
Skill
Review
Audit score 70

implicit-cad

earthtojake/text-to-cad

Create browser-native implicit CAD models using GLSL signed-distance fields and raymarching.

What is implicit-cad?

Build `.implicit.js` and `.implicit.mjs` files that render directly in CAD Viewer using GLSL-based signed-distance fields, shader primitives, smooth booleans, and TPMS lattices. Use this for procedural geometry that benefits from real-time raymarching visualization; prefer conventional STEP-first workflows otherwise.

  • Define 3D geometry via GLSL signed-distance functions (SDFs) with built-in primitives like sphere, box, torus, and cylinder
  • Compose shapes using smooth booleans, chamfers, and exponential blends for organic transitions
  • Apply procedural color via local normal and position-based shaders
  • Add interactive parameters (numbers, booleans, enums, colors) that map directly to GLSL uniforms
  • Animate models with time-based parameter updates and keyframe-driven exploration
  • Export to GLB, STL, or 3MF with custom render settings and parameter snapshots

How to install implicit-cad

npx skills add https://github.com/earthtojake/text-to-cad --skill implicit-cad
Prerequisites
  • Node.js and npm installed
  • CAD Viewer skill installed (for live preview and export)
  • Python 3 (for snapshot verification tool)
Claude Code
Cursor
Windsurf
Cline

How to use implicit-cad

  1. 1.Write a `.implicit.js` or `.implicit.mjs` ES module exporting an object with schema `implicit.js/0.1.0`, a `name`, and a `glsl` string containing `float sdf(vec3 p)` and optionally `vec3 color(vec3 p, vec3 normal)`
  2. 2.Use built-in GLSL helpers like `implicit_sphere()`, `implicit_box_centered()`, and `implicit_union_round()` to compose shapes
  3. 3.Add optional `params` object to define interactive controls (number, boolean, enum, color); param names become GLSL uniforms automatically
  4. 4.Add optional `animations` object with duration and update functions to drive parameter changes over time
  5. 5.Run `python scripts/snapshot --input <model>.implicit.js --output /tmp/review.png` to verify geometry, color, and framing
  6. 6.Run `python scripts/gen <model>.implicit.js` to build the render package, or `node scripts/export.mjs --input <model>.implicit.js --glb` to export mesh
  7. 7.Hand the file path to `$cad-viewer` to open it in the live viewer and generate shareable links

Use cases

Good for
  • Design lattice structures and TPMS (triply periodic minimal surface) infills for lightweight parts
  • Create parametric organic shapes with real-time visual feedback as dimensions change
  • Build procedurally-colored models where surface appearance depends on local geometry
  • Prototype complex Boolean compositions before committing to traditional CAD
  • Generate animated exploded views or breathing/morphing geometry for visualization
Who it's for
  • 3D designers and engineers exploring procedural geometry workflows
  • Developers building parametric design tools or generative art
  • Anyone needing fast visual iteration on complex implicit surfaces
  • Teams preferring browser-native, code-first CAD over traditional UI-based tools

implicit-cad FAQ

When should I use implicit CAD instead of traditional STEP/IGES workflows?

Use implicit CAD when you need procedural geometry, real-time parameter exploration, lattice/TPMS structures, or organic shapes defined by mathematical functions. For conventional mechanical parts, prefer STEP-first CAD.

Can I export implicit CAD models to standard formats?

Yes. Use `python scripts/gen` to build a render package, or `node scripts/export.mjs --glb` to export to GLB, STL, or 3MF. You can also specify custom parameters and render settings during export.

How do I add interactive controls to my model?

Define a `params` object with entries for `number`, `boolean`, `enum`, or `color` types. Each param name becomes a GLSL uniform automatically; reference it directly in your `glsl` code.

What if my snapshot appears clipped or misframed?

Check the `bounds` property in your module—if omitted, bounds are auto-estimated. Add explicit bounds when the model is animated, periodic, or has thin features. Use `render.frameMargin` around 1.5 in snapshot jobs to add padding.

Can I use helper functions from the skill in my own code?

Yes, import `scripts/lib/implicit-cad.mjs` during authoring for primitives, booleans, modifiers, and TPMS fields. For the final module, emit standalone GLSL directly into the `.implicit.js` file rather than copying bundled helpers.

Full instructions (SKILL.md)

Source of truth, from earthtojake/text-to-cad.


name: implicit-cad description: Create, edit, render, and snapshot browser-native implicit CAD .implicit.js and .implicit.mjs files using GLSL signed-distance fields, shader primitives, smooth booleans, TPMS fields, and direct CAD Viewer raymarch rendering. Experimental.

Implicit CAD

Use this skill for implicit CAD models that should run directly in CAD Viewer as browser JS modules. The primary artifact is a .implicit.js or .implicit.mjs.

This skill is experimental. ALWAYS prefer conventional STEP-first CAD workflows unless the user explicitly asks for an implicit model.

File Format

An implicit CAD file is an ES module exporting an implicit.js/0.1.0 object. The schema source of truth lives in the bundled package at scripts/packages/implicitjs/src/lib/implicitCad/schema.js; scripts/lib/implicit-cad.mjs re-exports it as SCHEMA for helper-authored modules.

export default {
  schema: "implicit.js/0.1.0",
  name: "rounded capsule block",
  glsl: `
float sdf(vec3 p) {
  float sphere = implicit_sphere(p, vec3(0.0), 22.0);
  float block = implicit_box_centered(p, vec3(34.0, 18.0, 18.0), vec3(0.0));
  return implicit_union_round(sphere, block, 3.0);
}

vec3 color(vec3 p, vec3 normal) {
  return mix(vec3(0.20, 0.55, 0.95), vec3(0.95, 0.45, 0.20), smoothstep(-15.0, 20.0, p.z));
}
`,
};

Models may also declare params and animations. Parameter definitions use the implicitjs control schema: number, boolean, enum/select, color, string, and button. Number, boolean, color, and button params automatically become GLSL uniforms with the same name; do not add a separate uniforms object. bounds is optional and is estimated from the SDF when omitted; add explicit bounds only when the auto estimate is too broad, too slow, or misses an unusual field. bounds and render may be JavaScript functions that receive { ...params, params, animation, animationState, elapsedSec, progress, t }.

Built-in GLSL helpers use the implicit_* namespace, for example implicit_sphere, implicit_box_centered, and implicit_union_round.

export default {
  schema: "implicit.js/0.1.0",
  name: "breathing orb",
  params: {
    radius: {
      type: "number",
      label: "Radius",
      min: 12,
      max: 34,
      default: 22,
      unit: "mm",
    },
  },
  animations: {
    breathe: {
      label: "Breathe",
      duration: 3,
      update({ progress, set }) {
        set("radius", 18 + Math.sin(progress * Math.PI) * 10);
      },
    },
  },
  render: { steps: 224, epsilon: 0.004 },
  glsl: `
float sdf(vec3 p) {
  return length(p) - radius;
}

vec3 color(vec3 p, vec3 normal) {
  return mix(vec3(0.10, 0.58, 0.95), vec3(1.0, 0.34, 0.12), smoothstep(-18.0, 18.0, p.z));
}
`,
};

Do not copy bundled helper files out of this skill. If helper functions are useful, use scripts/lib/implicit-cad.mjs during authoring or emit standalone GLSL into the final .implicit.js/.implicit.mjs module.

Authoring Workflow

  1. Write a natural-language modeling brief with dimensions, coordinate assumptions, procedural color intent, and visual checks.
  2. Create or edit the user-specified .implicit.js/.implicit.mjs module.
  3. Use scripts/lib/implicit-cad.mjs helpers for primitives and field composition when useful:
    • primitives: sphere, circle, boxCentered, plane, lineSegment, torus, axis, cylinder, cylinderCapped, capsule, cone, coneCapped, coneCapsule
    • booleans/blends: unionSharp, intersectSharp, unionRound, intersectRound, unionChamfer, intersectChamfer, unionExp, intersectExp, unionLpNorm, intersectLpNorm, unionRvachev, intersectRvachev, difference
    • modifiers/lattices: shell, rotateAxis, repeatCentered, remapCylindrical, cubicGrid, squareHoneycomb, squareHoneycombReinforced, squareDiagonalHoneycomb, octetHoneycomb, hexagonalHoneycomb, triangularHoneycomb
    • TPMS fields: tpmsGyroid, tpmsSchwarz, tpmsDiamond, tpmsLidinoid, tpmsNeovius, tpmsSplitP, tpmsIwp
    • shader wrappers: distanceFunction emits float sdf(vec3 p), colorFunction emits vec3 color(vec3 p, vec3 normal)
  4. Add optional params and animations for dimensions, toggles, palettes, mode switches, and animated exploration. Use param names directly in GLSL; the runtime declares matching uniforms.
  5. Add optional procedural color with vec3 color(vec3 p, vec3 normal) when the model benefits from local material variation. Keep color values in 0..1 RGB.
  6. Rely on automatic SDF bounds first. Add explicit bounds when an animated, periodic, translated, or very thin model needs tighter or more reliable framing/export sampling.
  7. Run the lightweight visual verification flow below after visible geometry, color, params, animation, bounds, render, or export-affecting changes.
  8. Run python scripts/gen <model.implicit.js> to build (or refresh) the render package the CAD Viewer opens. Add --write when a sibling <name>.glb is also wanted, or use node scripts/export.mjs --input <model.implicit.js> --glb for STL/3MF, non-default parameters, or an animation.

Visual Verification

Use this skill's snapshot tool as a fast visual check, not as a substitute for deterministic import/export validation. Keep the packet small and purposeful.

For simple static edits, one image is enough:

python scripts/snapshot --input models/implicit-cad/<model>.implicit.js --output /tmp/implicit-review/<model>.png

For topology, periodicity, thin features, Boolean blends, object identity, color, or suspected framing issues, render a small packet in one CLI call so the browser, module, and runtime model are reused:

python scripts/snapshot --job - <<'JSON'
{
  "input": "models/implicit-cad/<model>.implicit.js",
  "mode": "view",
  "render": { "sizeProfile": "simple", "frameMargin": 1.55 },
  "graphics": { "modelColors": true, "detail": 1.2, "shadows": true, "ambientOcclusion": true },
  "outputs": [
    { "path": "/tmp/implicit-review/<model>-iso.png", "camera": "iso" },
    { "path": "/tmp/implicit-review/<model>-front.png", "camera": "front" },
    { "path": "/tmp/implicit-review/<model>-top.png", "camera": "top" },
    { "path": "/tmp/implicit-review/<model>-right.png", "camera": "right" }
  ]
}
JSON

Add implicitParameters at the job level for one parameter state, or on individual outputs when the point of the review is comparing parameter variants. Use render.frameMargin around 1.5 when a model is close to the edge; if a snapshot still appears clipped, first check whether the source bounds is cutting the raymarch itself.

For animations, create a short GIF only when motion is part of the request:

python scripts/snapshot --job - <<'JSON'
{
  "input": "models/implicit-cad/<model>.implicit.js",
  "mode": "animate",
  "outputs": [{ "path": "/tmp/implicit-review/<model>-animation.gif" }],
  "implicitAnimation": { "activeId": "<animation-id>", "durationSeconds": 3, "fps": 12 }
}
JSON

Review the resulting PNG/GIF for centered framing, no top/bottom/side clipping, expected silhouette and topology, visible parameter differences, GLSL-defined colors, no unexpected holes/gaps, and smooth enough edges for the requested graphics settings. If the snapshot reveals a mismatch, fix the implicit source or bounds and rerun only the relevant packet.

Handoff

After completing implicit CAD work that creates or modifies .implicit.js, .implicit.mjs, .glb, .stl, or .3mf artifacts, you must ALWAYS hand the explicit file path(s) to $cad-viewer when that skill is installed. $cad-viewer must start CAD Viewer if it is not already running and return link(s) to the relevant created or updated file(s); include those live viewer link(s) in the final response. If $cad-viewer is unavailable or startup fails, report that instead of silently omitting the handoff.

When verification snapshots are generated, also include the saved PNG/GIF snapshot(s) in the final response. If no snapshot applies, or if snapshot generation fails, say why and report the deterministic validation that still ran.

Snapshot Tool

From this skill directory:

python scripts/snapshot --input <model.implicit.js> --output <snapshot.png>
python scripts/snapshot --input <model.implicit.js> --output <orbit.gif> --mode orbit
python scripts/snapshot --job <render-job.json>
python scripts/snapshot --job - --json
python scripts/snapshot --help

Use python scripts/snapshot --help for the complete current command interface. The snapshot CLI is shared with every other rendering skill (cadgen.snapshot_cli) and driven by the same browser runtime the CAD Viewer uses, so geometry, materials and lighting render identically — the default snapshot theme deliberately differs from the viewport only by dropping the grid, origin axis and shadows; this skill enables .implicit.js only. Theme settings live under one --theme and implicit raymarch quality under --graphics, mirroring the viewer's Theme and Graphics tabs. There is no --display: display settings are CAD topology settings and an implicit model carries none. The default theme is snapshot — Workbench Light without the ground grid, origin axis or shadows; raymarched shadows are off by default here too, so an implicit snapshot matches the shadowless mesh path (pass --graphics '{"shadows":true}' to restore them). The tool appends a UTC timestamp before the output extension. JSON jobs may be a single job, one job with multiple outputs, a raw array of jobs, or { "jobs": [...] }; prefer a multi-output job for review packets because it avoids rebuilding the same artifact for each camera.

Generate Tool

From this skill directory:

python scripts/gen <model.implicit.js>
python scripts/gen <model.implicit.js> --write
python scripts/gen models/implicits/*.implicit.js --force
python scripts/gen <model.implicit.js> --resolution 128 --threads 4
python scripts/gen --help

scripts/gen builds the model's render package — the baked mesh the CAD Viewer opens, under the model folder's __cadgen__/models/<name>.implicit.js/ (implicit.json + model.glb). The package is baked at the model's parameter DEFAULTS: it carries no live parameters and no animation. It is also what the viewer builds on demand, through the same producer, so a package built here and one built by opening the model are the same artifact.

A model whose package is current is skipped; --force rebuilds anyway. --write also leaves the sibling <name>.glb beside the source, from the same mesh pass — that file is an ordinary export-preset GLB (the package's own model.glb is compressed for the viewer and is not a substitute). Use scripts/export when you want STL or 3MF, non-default parameters, or an animation.

Export Tool

From this skill directory:

node scripts/export.mjs --input <model.implicit.js> --glb
node scripts/export.mjs --input <model.implicit.js> --stl <mesh.stl> --resolution <resolution>
node scripts/export.mjs --input <model.implicit.js> --stl --3mf --glb
node scripts/export.mjs --input <model.implicit.js> --3mf --params '<parameter-json>' --json
node scripts/export.mjs --help

One flag per format — --stl, --3mf, --glb — and several are allowed in one run, matching the CAD skill's export CLI. At least one is required; without any, the command exits 2. The model is meshed once per run, so every requested format comes from identical geometry. A format flag with no path writes next to the source file using the same stem, such as <model>.glb for <model>.implicit.js; a supplied path resolves against the current directory. Use node scripts/export.mjs --help for the complete current command interface.