first commit
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user