# implicitjs

`implicitjs` is a standalone JavaScript runtime for browser-native implicit CAD
models. It defines the `.implicit.js` model schema, builds GLSL raymarch
shaders, renders models with Three.js, evaluates SDFs on the CPU, produces
headless PNG/GIF snapshots, samples meshes, checks mesh quality, and exports
STL, 3MF, and GLB artifacts.

The package is UI-framework agnostic. Applications provide their own editor,
catalog, sidebar, persistence, and product workflow; `implicitjs` provides the
model, rendering, snapshot, and export logic.

## Install

```bash
npm install implicitjs
```

Peer usage expects a modern ESM JavaScript environment. Rendering APIs require
Three.js-compatible WebGL support. The headless snapshot CLI uses Playwright.

## Model Format

An implicit model is an ES module that exports an `implicit.js/0.1.0` object.
The `glsl` string must provide `float sdf(vec3 p)`. It may also provide
`vec3 color(vec3 p, vec3 normal)` for procedural color.

```js
const GLSL = `
float sdf(vec3 p) {
  return implicit_sphere(p, vec3(0.0), radius);
}

vec3 color(vec3 p, vec3 normal) {
  return mix(vec3(0.0, 0.65, 1.0), vec3(1.0, 0.3, 0.8), normal.z * 0.5 + 0.5);
}
`;

export default {
  schema: "implicit.js/0.1.0",
  name: "parametric sphere",
  units: "mm",
  params: {
    radius: { type: "number", label: "Radius", min: 5, max: 50, default: 22, unit: "mm" }
  },
  bounds: ({ params }) => {
    const r = params.radius + 2;
    return [[-r, -r, -r], [r, r, r]];
  },
  render: { steps: 192 },
  glsl: GLSL
};
```

Number, boolean, color, and button params automatically become GLSL uniforms
with matching names. Use param names directly in GLSL; a separate `uniforms`
object is not needed.

`bounds` is optional and can be estimated from the SDF, but explicit bounds are
recommended for unusual fields, thin features, periodic models, animated size
changes, or export-heavy workflows.

Authored GLSL can use built-in helpers in the `implicit_*` namespace, such as
`implicit_sphere`, `implicit_box_centered`, `implicit_cylinder_capped`,
`implicit_line_segment2`, `implicit_union_round`, and
`implicit_intersect_round`.

## Public APIs

Common imports:

```js
import {
  loadImplicitModuleFromSource,
  normalizeImplicitModel,
  renderImplicitToDataUrl,
  snapshotImplicitCadModel,
  exportImplicitModel,
  exportImplicitAnimatedGlb
} from "implicitjs";
```

Useful subpath exports:

- `implicitjs/model`: schema normalization and parameterized runtime models.
- `implicitjs/loader`: loading `.implicit.js` modules or source strings.
- `implicitjs/render`: Three.js shader and camera helpers.
- `implicitjs/snapshot`: browser PNG snapshot helpers.
- `implicitjs/mesh`: SDF mesh sampling.
- `implicitjs/meshQuality`: mesh quality checks.
- `implicitjs/export`: STL/3MF/GLB export APIs.
- `implicitjs/sdfEvaluator`: CPU SDF evaluator for compatible GLSL.

## Rendering

```js
import * as THREE from "three";
import { loadImplicitModuleFromSource, renderImplicitToDataUrl } from "implicitjs";

const model = await loadImplicitModuleFromSource(source);
const pngDataUrl = await renderImplicitToDataUrl(THREE, model, {
  width: 1200,
  height: 900,
  camera: "iso",
  render: { frameMargin: 1.45 },
  graphics: { modelColors: true, detail: 1.2 }
});
```

Camera presets include `iso`, `front`, `back`, `left`, `right`, `top`, and
`bottom`. Cameras can also be JSON objects with `position`, `target`, `up`,
`direction`, `preset`, and `zoom`.

## Snapshots

From a package checkout:

```bash
npm run snapshot -- --input examples/model.implicit.js --output /tmp/model.png
npm run snapshot -- --input examples/model.implicit.js --output /tmp/model.gif --mode orbit
```

Orbit GIF jobs default to 6 fps over 12 seconds for a calmer review spin
without increasing default render frame count.
Override with `orbit.fps` and `orbit.durationSeconds` in JSON jobs when needed.

The snapshot CLI also accepts JSON jobs. A single job can include multiple
outputs, and `--job` can load one job, an array of jobs, or `{ "jobs": [...] }`.
Prefer one multi-output job when rendering review packets because the browser,
module, and runtime model can be reused.

```bash
npm run snapshot -- --job - <<'JSON'
{
  "input": "examples/model.implicit.js",
  "render": { "frameMargin": 1.55 },
  "outputs": [
    { "path": "/tmp/model-iso.png", "camera": "iso" },
    { "path": "/tmp/model-front.png", "camera": "front" },
    { "path": "/tmp/model-top.png", "camera": "top" }
  ]
}
JSON
```

Each output path receives a UTC timestamp before its extension.

## Exports

```js
import { exportImplicitModel, exportImplicitAnimatedGlb } from "implicitjs/browser";

const glb = await exportImplicitModel(model, {
  format: "glb",
  resolution: 96,
  params: { radius: 24 }
});

const animated = await exportImplicitAnimatedGlb(model, {
  animationId: "breathe",
  params: { radius: 24 },
  frames: 24,
  resolution: 72
});
```

From a package checkout:

```bash
npm run export -- --input examples/model.implicit.js --format glb --output /tmp/model.glb
npm run export -- --input examples/model.implicit.js --format stl --resolution 96
npm run export -- --input examples/model.implicit.js --format 3mf --params '{"radius":24}'
```

Exports sample the model's SDF inside its bounds. Higher resolutions produce
denser meshes and take longer.

## Package Layout

- `src/index.js`: public package entrypoint.
- `src/browser.js`: browser-oriented entrypoint.
- `src/common/`: shared camera, parameter, theme, render-option, and headless
  snapshot helpers.
- `src/lib/implicitCad/`: schema, model normalization, loading, shader
  rendering, CPU evaluation, mesh sampling, mesh quality, and exporters.
- `src/lib/viewer/`: internal render presentation defaults used by shaders.
- `scripts/`: snapshot, export, export-verification, and test CLIs.

Tests live beside the modules they cover as `*.test.js`.

## Development

```bash
npm test
npm run verify:exports -- --input examples/model.implicit.js
```

Keep the package reusable and UI-independent. Runtime behavior that applies to
model normalization, rendering, snapshots, CPU sampling, mesh export, graphics
settings, parameters, and animations belongs here. Product-specific UI state,
catalogs, editors, file sheets, routing, and persistence should live in the
consuming application.
