@taulabs/openrscad-engine 0.11.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +21 -0
- package/README.md +194 -0
- package/dist/browser.d.ts +16 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +33 -0
- package/dist/browser.js.map +1 -0
- package/dist/core.d.ts +158 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +133 -0
- package/dist/core.js.map +1 -0
- package/dist/node.d.ts +14 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +30 -0
- package/dist/node.js.map +1 -0
- package/examples/node-render.mjs +19 -0
- package/examples/worker.js +18 -0
- package/package.json +87 -0
- package/pkg/node/openrscad.d.ts +174 -0
- package/pkg/node/openrscad.js +914 -0
- package/pkg/node/openrscad_bg.wasm +0 -0
- package/pkg/node/openrscad_bg.wasm.d.ts +56 -0
- package/pkg/node/package.json +16 -0
- package/pkg/web/openrscad.d.ts +255 -0
- package/pkg/web/openrscad.js +997 -0
- package/pkg/web/openrscad_bg.wasm +0 -0
- package/pkg/web/openrscad_bg.wasm.d.ts +56 -0
- package/pkg/web/package.json +20 -0
package/dist/core.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Environment-agnostic facade over the raw wasm-bindgen exports.
|
|
2
|
+
//
|
|
3
|
+
// The generated `render*` functions return a wasm-owned `RenderResult` whose
|
|
4
|
+
// getters COPY their data into fresh JS values (each getter clones), then the
|
|
5
|
+
// object must be `.free()`d or it leaks wasm linear memory on every render. This
|
|
6
|
+
// wrapper reads the fields callers actually want and always frees in a
|
|
7
|
+
// `finally`, so consumers never touch `.free()` and never leak. The browser and
|
|
8
|
+
// node entry points supply the concrete bindings and an `ensureReady` hook.
|
|
9
|
+
const consumeExportResult = (result) => {
|
|
10
|
+
try {
|
|
11
|
+
return {
|
|
12
|
+
ok: result.ok,
|
|
13
|
+
error: result.error,
|
|
14
|
+
bytes: result.take_bytes(),
|
|
15
|
+
format: result.format,
|
|
16
|
+
is2d: result.is_2d,
|
|
17
|
+
triangleCount: result.triangle_count,
|
|
18
|
+
vertexCount: result.vertex_count,
|
|
19
|
+
volume: result.volume,
|
|
20
|
+
area: result.area,
|
|
21
|
+
echo: result.echo,
|
|
22
|
+
warnings: result.warnings,
|
|
23
|
+
geomErrors: result.geom_errors,
|
|
24
|
+
diagnostics: JSON.parse(result.diagnostics || "[]"),
|
|
25
|
+
viewport: result.viewport,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
result.free();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
function toLiteral(v) {
|
|
33
|
+
return typeof v === "string" ? v : String(v);
|
|
34
|
+
}
|
|
35
|
+
function toBase64(bytes) {
|
|
36
|
+
const chunks = [];
|
|
37
|
+
for (let offset = 0; offset < bytes.length; offset += 0x8000) {
|
|
38
|
+
chunks.push(String.fromCharCode(...bytes.subarray(offset, offset + 0x8000)));
|
|
39
|
+
}
|
|
40
|
+
return btoa(chunks.join(""));
|
|
41
|
+
}
|
|
42
|
+
/** Build the public API from the raw engine bindings and an init hook. */
|
|
43
|
+
export function makeApi(engine, ensureReady) {
|
|
44
|
+
function split(opts) {
|
|
45
|
+
const paramEntries = Object.entries(opts.params ?? {});
|
|
46
|
+
const fileEntries = Object.entries(opts.files ?? {});
|
|
47
|
+
const binaryEntries = Object.entries(opts.binaryFiles ?? {});
|
|
48
|
+
return {
|
|
49
|
+
names: paramEntries.map(([k]) => k),
|
|
50
|
+
values: paramEntries.map(([, v]) => toLiteral(v)),
|
|
51
|
+
fileNames: fileEntries.map(([k]) => k),
|
|
52
|
+
fileContents: fileEntries.map(([, v]) => v),
|
|
53
|
+
binNames: binaryEntries.map(([k]) => k),
|
|
54
|
+
binData: binaryEntries.map(([, v]) => toBase64(v)),
|
|
55
|
+
fontBlobs: (opts.fontFiles ?? []).map(toBase64),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Parse `.scad` source and render it to mesh + diagnostics. */
|
|
59
|
+
async function render(source, opts = {}) {
|
|
60
|
+
await ensureReady();
|
|
61
|
+
const { names, values, fileNames, fileContents, binNames, binData, fontBlobs } = split(opts);
|
|
62
|
+
const r = engine.render_with_files(source, names, values, fileNames, fileContents, binNames, binData, fontBlobs);
|
|
63
|
+
try {
|
|
64
|
+
return {
|
|
65
|
+
ok: r.ok,
|
|
66
|
+
error: r.error,
|
|
67
|
+
positions: r.positions,
|
|
68
|
+
normals: r.normals,
|
|
69
|
+
is2d: r.is_2d,
|
|
70
|
+
triangleCount: r.triangle_count,
|
|
71
|
+
vertexCount: r.vertex_count,
|
|
72
|
+
volume: r.volume,
|
|
73
|
+
area: r.area,
|
|
74
|
+
echo: r.echo,
|
|
75
|
+
warnings: r.warnings,
|
|
76
|
+
geomErrors: r.geom_errors,
|
|
77
|
+
diagnostics: JSON.parse(r.diagnostics || "[]"),
|
|
78
|
+
preview: {
|
|
79
|
+
positions: r.preview_positions,
|
|
80
|
+
normals: r.preview_normals,
|
|
81
|
+
groups: r.groups,
|
|
82
|
+
},
|
|
83
|
+
provenance: {
|
|
84
|
+
positions: r.provenance_positions,
|
|
85
|
+
normals: r.provenance_normals,
|
|
86
|
+
groups: r.provenance,
|
|
87
|
+
},
|
|
88
|
+
viewport: r.viewport,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
r.free();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** Render a 2D model to DXF or SVG text (empty if the model isn't 2D). */
|
|
96
|
+
async function exportShape2D(source, format, opts = {}) {
|
|
97
|
+
await ensureReady();
|
|
98
|
+
const { names, values, fileNames, fileContents, binNames, binData, fontBlobs } = split(opts);
|
|
99
|
+
return engine.export_2d(source, names, values, fileNames, fileContents, binNames, binData, fontBlobs, format);
|
|
100
|
+
}
|
|
101
|
+
async function exportShape3D(source, format, opts = {}) {
|
|
102
|
+
await ensureReady();
|
|
103
|
+
const { names, values, fileNames, fileContents, binNames, binData, fontBlobs } = split(opts);
|
|
104
|
+
const glb = format === "glb" ? opts : {};
|
|
105
|
+
const result = engine.export_3d(source, names, values, fileNames, fileContents, binNames, binData, fontBlobs, format, glb.includeEdges ?? false, glb.sourceUnitToMeters ?? 0.001, glb.coordinateSystem ?? "y-up");
|
|
106
|
+
return consumeExportResult(result);
|
|
107
|
+
}
|
|
108
|
+
/** Render preview-semantics geometry directly to GLB for an interactive viewer. */
|
|
109
|
+
async function renderToGlb(source, opts = {}) {
|
|
110
|
+
await ensureReady();
|
|
111
|
+
const { names, values, fileNames, fileContents, binNames, binData, fontBlobs } = split(opts);
|
|
112
|
+
const result = engine.render_to_glb(source, names, values, fileNames, fileContents, binNames, binData, fontBlobs, opts.includeEdges ?? false);
|
|
113
|
+
return consumeExportResult(result);
|
|
114
|
+
}
|
|
115
|
+
/** The customizer parameter schema for a source string, as JSON
|
|
116
|
+
* (`{"params":[…]}`). */
|
|
117
|
+
async function parameters(source) {
|
|
118
|
+
await ensureReady();
|
|
119
|
+
return engine.parameters(source);
|
|
120
|
+
}
|
|
121
|
+
/** The engine version string (matches the npm package version). */
|
|
122
|
+
async function version() {
|
|
123
|
+
await ensureReady();
|
|
124
|
+
return engine.version();
|
|
125
|
+
}
|
|
126
|
+
/** Drop the persistent geometry cache (e.g. when loading a new document). */
|
|
127
|
+
async function clearCache() {
|
|
128
|
+
await ensureReady();
|
|
129
|
+
engine.clear_cache();
|
|
130
|
+
}
|
|
131
|
+
return { render, renderToGlb, exportShape2D, exportShape3D, parameters, version, clearCache };
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Resolves immediately — the wasm is already instantiated on import in Node. */
|
|
2
|
+
export declare function ensureReady(): Promise<void>;
|
|
3
|
+
export declare const render: (source: string, opts?: import("./core.js").RenderOptions) => Promise<import("./core.js").RenderOutput>;
|
|
4
|
+
export declare const renderToGlb: (source: string, opts?: import("./core.js").RenderToGlbOptions) => Promise<import("./core.js").ExportShape3DOutput>;
|
|
5
|
+
export declare const exportShape2D: (source: string, format: "dxf" | "svg", opts?: import("./core.js").RenderOptions) => Promise<string>;
|
|
6
|
+
export declare const exportShape3D: {
|
|
7
|
+
(source: string, format: "glb", opts?: import("./core.js").ExportGlbOptions): Promise<import("./core.js").ExportShape3DOutput>;
|
|
8
|
+
(source: string, format: Exclude<import("./core.js").ExportShape3DFormat, "glb">, opts?: import("./core.js").RenderOptions): Promise<import("./core.js").ExportShape3DOutput>;
|
|
9
|
+
};
|
|
10
|
+
export declare const parameters: (source: string) => Promise<string>;
|
|
11
|
+
export declare const version: () => Promise<string>;
|
|
12
|
+
export declare const clearCache: () => Promise<void>;
|
|
13
|
+
export type { Diagnostic, ExportGlbOptions, ExportShape3DFormat, ExportShape3DOutput, RenderOptions, RenderOutput, RenderToGlbOptions, } from "./core.js";
|
|
14
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAiBA,iFAAiF;AACjF,wBAAgB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3C;AAcD,eAAO,MAAM,MAAM,yGAAa,CAAC;AACjC,eAAO,MAAM,WAAW,qHAAkB,CAAC;AAC3C,eAAO,MAAM,aAAa,sGAAoB,CAAC;AAC/C,eAAO,MAAM,aAAa;;;CAAoB,CAAC;AAC/C,eAAO,MAAM,UAAU,qCAAiB,CAAC;AACzC,eAAO,MAAM,OAAO,uBAAc,CAAC;AACnC,eAAO,MAAM,UAAU,qBAAiB,CAAC;AAEzC,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,kBAAkB,GACnB,MAAM,WAAW,CAAC"}
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Node entry (the `node` + `import` export condition).
|
|
2
|
+
//
|
|
3
|
+
// The nodejs-target glue instantiates the wasm synchronously on import, so there
|
|
4
|
+
// is no async init step: `ensureReady()` resolves immediately and exists only
|
|
5
|
+
// for API parity with the browser entry. (CommonJS `require()` consumers resolve
|
|
6
|
+
// to the raw `pkg/node/openrscad.js` glue directly — see the package `exports` map.)
|
|
7
|
+
import { render_with_files as rawRenderWithFiles, export_2d as rawExport2d, export_3d as rawExport3d, render_to_glb as rawRenderToGlb, parameters as rawParameters, version as rawVersion, clear_cache as rawClearCache, } from "../pkg/node/openrscad.js";
|
|
8
|
+
import { makeApi } from "./core.js";
|
|
9
|
+
/** Resolves immediately — the wasm is already instantiated on import in Node. */
|
|
10
|
+
export function ensureReady() {
|
|
11
|
+
return Promise.resolve();
|
|
12
|
+
}
|
|
13
|
+
const engine = {
|
|
14
|
+
render_with_files: rawRenderWithFiles,
|
|
15
|
+
export_2d: rawExport2d,
|
|
16
|
+
export_3d: rawExport3d,
|
|
17
|
+
render_to_glb: rawRenderToGlb,
|
|
18
|
+
parameters: rawParameters,
|
|
19
|
+
version: rawVersion,
|
|
20
|
+
clear_cache: rawClearCache,
|
|
21
|
+
};
|
|
22
|
+
const api = makeApi(engine, ensureReady);
|
|
23
|
+
export const render = api.render;
|
|
24
|
+
export const renderToGlb = api.renderToGlb;
|
|
25
|
+
export const exportShape2D = api.exportShape2D;
|
|
26
|
+
export const exportShape3D = api.exportShape3D;
|
|
27
|
+
export const parameters = api.parameters;
|
|
28
|
+
export const version = api.version;
|
|
29
|
+
export const clearCache = api.clearCache;
|
|
30
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,iFAAiF;AACjF,8EAA8E;AAC9E,iFAAiF;AACjF,qFAAqF;AACrF,OAAO,EACL,iBAAiB,IAAI,kBAAkB,EACvC,SAAS,IAAI,WAAW,EACxB,SAAS,IAAI,WAAW,EACxB,aAAa,IAAI,cAAc,EAC/B,UAAU,IAAI,aAAa,EAC3B,OAAO,IAAI,UAAU,EACrB,WAAW,IAAI,aAAa,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAkB,MAAM,WAAW,CAAC;AAEpD,iFAAiF;AACjF,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,MAAM,GAAG;IACb,iBAAiB,EAAE,kBAAkB;IACrC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,aAAa,EAAE,cAAc;IAC7B,UAAU,EAAE,aAAa;IACzB,OAAO,EAAE,UAAU;IACnB,WAAW,EAAE,aAAa;CACH,CAAC;AAE1B,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAEzC,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;AACjC,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;AAC3C,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,CAAC;AAC/C,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,CAAC;AAC/C,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;AACzC,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;AACnC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Headless render in Node (ESM). Run with: node node-render.mjs
|
|
2
|
+
//
|
|
3
|
+
// The Node build instantiates the wasm on import, so `render()` works with no
|
|
4
|
+
// init step. Mesh data comes back as a non-indexed triangle soup (9 f32 per
|
|
5
|
+
// triangle in both `positions` and `normals`).
|
|
6
|
+
import { render, version } from "@taulabs/openrscad-engine";
|
|
7
|
+
|
|
8
|
+
console.log("@taulabs/openrscad-engine", await version());
|
|
9
|
+
|
|
10
|
+
const r = await render("difference() { cube(20, center=true); sphere(12); }");
|
|
11
|
+
if (!r.ok) {
|
|
12
|
+
console.error(r.error);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
console.log(
|
|
17
|
+
`${r.triangleCount} triangles, ${r.vertexCount} verts, ` +
|
|
18
|
+
`volume ${r.volume.toFixed(2)}, area ${r.area.toFixed(2)}`,
|
|
19
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// A module Web Worker that runs the OpenRSCAD engine off the main thread — the
|
|
2
|
+
// recommended way to use it in a browser app (rendering a large model can take
|
|
3
|
+
// tens of milliseconds and shouldn't block the UI).
|
|
4
|
+
//
|
|
5
|
+
// Spawn it from your app with a bundler that supports module workers, e.g. Vite:
|
|
6
|
+
//
|
|
7
|
+
// const worker = new Worker(new URL("./worker.js", import.meta.url), { type: "module" });
|
|
8
|
+
// worker.onmessage = (e) => { /* e.data.result is a RenderOutput */ };
|
|
9
|
+
// worker.postMessage({ seq: 1, source: "cube(10);" });
|
|
10
|
+
//
|
|
11
|
+
import { render } from "@taulabs/openrscad-engine";
|
|
12
|
+
|
|
13
|
+
self.onmessage = async (e) => {
|
|
14
|
+
const { seq, source, params, files } = e.data;
|
|
15
|
+
const result = await render(source, { params, files });
|
|
16
|
+
// Transfer the (largest) mesh buffers to hand them over without a copy.
|
|
17
|
+
self.postMessage({ seq, result }, [result.positions.buffer, result.normals.buffer]);
|
|
18
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@taulabs/openrscad-engine",
|
|
3
|
+
"version": "0.11.0-beta.0",
|
|
4
|
+
"description": "Tau's fork of the OpenRSCAD geometry engine, compiled to WebAssembly \u2014 parse .scad source and render solid 3D meshes in the browser or Node. Adds an authored-scene GLB/3MF export path with source-derived feature edges; tracks upstream.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "Apache-2.0 OR MIT",
|
|
7
|
+
"author": "Matt Hova",
|
|
8
|
+
"homepage": "https://github.com/taucad/openrscad",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/taucad/openrscad.git",
|
|
12
|
+
"directory": "packages/npm"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/taucad/openrscad/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"openscad",
|
|
19
|
+
"scad",
|
|
20
|
+
"cad",
|
|
21
|
+
"wasm",
|
|
22
|
+
"webassembly",
|
|
23
|
+
"geometry",
|
|
24
|
+
"csg",
|
|
25
|
+
"3d",
|
|
26
|
+
"mesh",
|
|
27
|
+
"openrscad",
|
|
28
|
+
"fork"
|
|
29
|
+
],
|
|
30
|
+
"types": "./dist/browser.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"browser": {
|
|
34
|
+
"types": "./dist/browser.d.ts",
|
|
35
|
+
"default": "./dist/browser.js"
|
|
36
|
+
},
|
|
37
|
+
"node": {
|
|
38
|
+
"types": "./dist/node.d.ts",
|
|
39
|
+
"import": "./dist/node.js",
|
|
40
|
+
"require": "./pkg/node/openrscad.js"
|
|
41
|
+
},
|
|
42
|
+
"default": {
|
|
43
|
+
"types": "./dist/browser.d.ts",
|
|
44
|
+
"default": "./dist/browser.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"./web": {
|
|
48
|
+
"types": "./pkg/web/openrscad.d.ts",
|
|
49
|
+
"default": "./pkg/web/openrscad.js"
|
|
50
|
+
},
|
|
51
|
+
"./node": {
|
|
52
|
+
"types": "./pkg/node/openrscad.d.ts",
|
|
53
|
+
"default": "./pkg/node/openrscad.js"
|
|
54
|
+
},
|
|
55
|
+
"./openrscad_bg.wasm": "./pkg/web/openrscad_bg.wasm",
|
|
56
|
+
"./package.json": "./package.json"
|
|
57
|
+
},
|
|
58
|
+
"sideEffects": [
|
|
59
|
+
"./pkg/*/openrscad.js",
|
|
60
|
+
"./dist/*.js"
|
|
61
|
+
],
|
|
62
|
+
"files": [
|
|
63
|
+
"dist",
|
|
64
|
+
"pkg/web",
|
|
65
|
+
"pkg/node",
|
|
66
|
+
"examples",
|
|
67
|
+
"README.md",
|
|
68
|
+
"LICENSE-APACHE",
|
|
69
|
+
"LICENSE-MIT"
|
|
70
|
+
],
|
|
71
|
+
"publishConfig": {
|
|
72
|
+
"access": "public"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "npm run build:wasm && npm run build:facade",
|
|
76
|
+
"build:wasm": "wasm-pack build ../../crates/openrscad-wasm --release --target web --out-dir \"$PWD/pkg/web\" --out-name openrscad && wasm-pack build ../../crates/openrscad-wasm --release --target nodejs --out-dir \"$PWD/pkg/node\" --out-name openrscad && rm -f pkg/web/.gitignore pkg/node/.gitignore",
|
|
77
|
+
"build:wasm:profile": "wasm-pack build ../../crates/openrscad-wasm --release --target web --out-dir \"$PWD/pkg/web\" --out-name openrscad -- --features benchmark-profile && wasm-pack build ../../crates/openrscad-wasm --release --target nodejs --out-dir \"$PWD/pkg/node\" --out-name openrscad -- --features benchmark-profile && rm -f pkg/web/.gitignore pkg/node/.gitignore",
|
|
78
|
+
"build:facade": "tsc -p tsconfig.json",
|
|
79
|
+
"test": "npm run build:facade && node --test test/*.test.mjs"
|
|
80
|
+
},
|
|
81
|
+
"devDependencies": {
|
|
82
|
+
"typescript": "^5.5.3"
|
|
83
|
+
},
|
|
84
|
+
"contributors": [
|
|
85
|
+
"Richard Fontein (Tau)"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* One owned native 3D artifact plus the operational metadata needed by hosts.
|
|
6
|
+
*/
|
|
7
|
+
export class ExportShape3DResult {
|
|
8
|
+
private constructor();
|
|
9
|
+
free(): void;
|
|
10
|
+
[Symbol.dispose](): void;
|
|
11
|
+
/**
|
|
12
|
+
* Transfer artifact ownership to JavaScript. A second call returns empty.
|
|
13
|
+
*/
|
|
14
|
+
take_bytes(): Uint8Array;
|
|
15
|
+
readonly area: number;
|
|
16
|
+
readonly diagnostics: string;
|
|
17
|
+
readonly echo: string;
|
|
18
|
+
readonly error: string;
|
|
19
|
+
readonly format: string;
|
|
20
|
+
readonly geom_errors: string;
|
|
21
|
+
readonly is_2d: boolean;
|
|
22
|
+
readonly ok: boolean;
|
|
23
|
+
readonly triangle_count: number;
|
|
24
|
+
readonly vertex_count: number;
|
|
25
|
+
readonly viewport: string;
|
|
26
|
+
readonly volume: number;
|
|
27
|
+
readonly warnings: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The result of rendering a `.scad` source string.
|
|
32
|
+
*
|
|
33
|
+
* Mesh data is a non-indexed triangle soup with flat (per-face) normals:
|
|
34
|
+
* `positions` and `normals` both hold 9 floats per triangle.
|
|
35
|
+
*/
|
|
36
|
+
export class RenderResult {
|
|
37
|
+
private constructor();
|
|
38
|
+
free(): void;
|
|
39
|
+
[Symbol.dispose](): void;
|
|
40
|
+
readonly area: number;
|
|
41
|
+
/**
|
|
42
|
+
* Structured diagnostics as a JSON array (`[{severity,message,start,end}]`),
|
|
43
|
+
* where start/end are byte offsets into the source, or -1 when unknown.
|
|
44
|
+
*/
|
|
45
|
+
readonly diagnostics: string;
|
|
46
|
+
/**
|
|
47
|
+
* Newline-joined `ECHO:` output.
|
|
48
|
+
*/
|
|
49
|
+
readonly echo: string;
|
|
50
|
+
/**
|
|
51
|
+
* Error message, or empty string if the render succeeded.
|
|
52
|
+
*/
|
|
53
|
+
readonly error: string;
|
|
54
|
+
/**
|
|
55
|
+
* Newline-joined recoverable geometry errors (degraded render), or empty
|
|
56
|
+
* when the geometry is exact. See the field docs on `geom_errors`.
|
|
57
|
+
*/
|
|
58
|
+
readonly geom_errors: string;
|
|
59
|
+
/**
|
|
60
|
+
* Per-group ranges/colors as JSON (`[{start,count,color,mode}]`); empty `[]`
|
|
61
|
+
* when the model uses no display attributes.
|
|
62
|
+
*/
|
|
63
|
+
readonly groups: string;
|
|
64
|
+
/**
|
|
65
|
+
* Whether the model is a 2D object (exportable to DXF/SVG) vs a 3D solid.
|
|
66
|
+
*/
|
|
67
|
+
readonly is_2d: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Per-face normals (9 f32 per triangle) as a `Float32Array`.
|
|
70
|
+
*/
|
|
71
|
+
readonly normals: Float32Array;
|
|
72
|
+
/**
|
|
73
|
+
* Whether the render succeeded (no error).
|
|
74
|
+
*/
|
|
75
|
+
readonly ok: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Triangle-soup vertex positions (9 f32 per triangle) as a `Float32Array`.
|
|
78
|
+
*/
|
|
79
|
+
readonly positions: Float32Array;
|
|
80
|
+
readonly preview_normals: Float32Array;
|
|
81
|
+
/**
|
|
82
|
+
* Preview triangle soup (concatenated colored groups); empty when the model
|
|
83
|
+
* uses no color/`#`/`%` (the viewer then uses `positions`).
|
|
84
|
+
*/
|
|
85
|
+
readonly preview_positions: Float32Array;
|
|
86
|
+
/**
|
|
87
|
+
* Per-group provenance ranges/span-stacks as JSON (`[{start,count,spans}]`);
|
|
88
|
+
* empty when the model has no pickable geometry.
|
|
89
|
+
*/
|
|
90
|
+
readonly provenance: string;
|
|
91
|
+
readonly provenance_normals: Float32Array;
|
|
92
|
+
/**
|
|
93
|
+
* Provenance triangle soup (concatenated per-statement groups); empty only
|
|
94
|
+
* for models with no geometry.
|
|
95
|
+
*/
|
|
96
|
+
readonly provenance_positions: Float32Array;
|
|
97
|
+
readonly triangle_count: number;
|
|
98
|
+
readonly vertex_count: number;
|
|
99
|
+
/**
|
|
100
|
+
* `$vp*` viewport variables as JSON, or empty when the source has no `$vp`.
|
|
101
|
+
*/
|
|
102
|
+
readonly viewport: string;
|
|
103
|
+
readonly volume: number;
|
|
104
|
+
/**
|
|
105
|
+
* Newline-joined warnings.
|
|
106
|
+
*/
|
|
107
|
+
readonly warnings: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Drop the persistent geometry cache (e.g. when loading a new document).
|
|
112
|
+
*/
|
|
113
|
+
export function clear_cache(): void;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Render a 2D model and serialize it to DXF or SVG text. Returns an empty
|
|
117
|
+
* string if the model isn't 2D or fails to evaluate (the caller checks
|
|
118
|
+
* `RenderResult.is_2d` first). `format` is "dxf" or "svg".
|
|
119
|
+
*/
|
|
120
|
+
export function export_2d(source: string, names: string[], values: string[], file_names: string[], file_contents: string[], bin_names: string[], bin_data: string[], font_blobs: string[], format: string): string;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Evaluate a 3D source and serialize it natively to one owned artifact.
|
|
124
|
+
*/
|
|
125
|
+
export function export_3d(source: string, names: string[], values: string[], file_names: string[], file_contents: string[], bin_names: string[], bin_data: string[], font_blobs: string[], format: string, include_edges: boolean, source_unit_to_meters: number, coordinate_system: string): ExportShape3DResult;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The customizer parameter schema for a source string, as a JSON string
|
|
129
|
+
* (`{"params":[…]}`). The playground renders a control panel from this.
|
|
130
|
+
*/
|
|
131
|
+
export function parameters(source: string): string;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Run the full pipeline on a source string.
|
|
135
|
+
*/
|
|
136
|
+
export function render(source: string): RenderResult;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Like [`render_with_files`], but renders the fast, **non-watertight** preview
|
|
140
|
+
* (see `openrscad_geom::render_preview_cached_diag`): unions are concatenated rather
|
|
141
|
+
* than run through the CSG kernel. Suitable for opaque on-screen display only —
|
|
142
|
+
* stats and export still use the exact path. Differences/intersections/hulls
|
|
143
|
+
* still resolve exactly, so holes and clips look correct.
|
|
144
|
+
*/
|
|
145
|
+
export function render_preview_with_files(source: string, names: string[], values: string[], file_names: string[], file_contents: string[], bin_names: string[], bin_data: string[], font_blobs: string[]): RenderResult;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Render a preview-semantics GLB for interactive viewers.
|
|
149
|
+
*/
|
|
150
|
+
export function render_to_glb(source: string, names: string[], values: string[], file_names: string[], file_contents: string[], bin_names: string[], bin_data: string[], font_blobs: string[], include_edges: boolean): ExportShape3DResult;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Like [`render_with_params`], but `include`/`use` resolve against an in-memory
|
|
154
|
+
* set of files (`file_names[i]` → `file_contents[i]`) — the playground's other
|
|
155
|
+
* files and/or a bundled library.
|
|
156
|
+
*/
|
|
157
|
+
export function render_with_files(source: string, names: string[], values: string[], file_names: string[], file_contents: string[], bin_names: string[], bin_data: string[], font_blobs: string[]): RenderResult;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Like [`render`], but with customizer overrides supplied as parallel arrays:
|
|
161
|
+
* `names[i]` is a top-level parameter and `values[i]` its new value as a
|
|
162
|
+
* literal string (`"30"`, `"true"`, `"\"hi\""`, `"[1,2,3]"`).
|
|
163
|
+
*/
|
|
164
|
+
export function render_with_params(source: string, names: string[], values: string[]): RenderResult;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Initialize panic hook for readable errors in the browser console.
|
|
168
|
+
*/
|
|
169
|
+
export function start(): void;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Engine version string.
|
|
173
|
+
*/
|
|
174
|
+
export function version(): string;
|