Cura Engine powered by Web Assembly (WASM)
- Written in modern TypeScript
- Uses Rollup for JS/TS compilation
- Uses Docker for C++ compilation (Enhanced reproducibility)
- Ships with everything already compiled
- Works in the browser and on NodeJS
- Thoroughly commented
Cura WASM ships with both ES6 and CJS exports. The ES6 version is built with browsers in mind and likely won't work on NodeJS; the CJS version is built with NodeJS in mind and almost certainly won't work on browsers due to lacking standard modules.
- Basic Benchy + Ultimaker 2 example
import CuraWASM from 'cura-wasm';
const main = async () =>
{
//Create a new slicer
const slicer = new CuraWASM({
/*
* The 3D printer definition to slice for (See the src/definitions directory
* or https://github.com/Ultimaker/Cura/tree/master/resources/definitions
* for a list of built-in definitions)
*/
definition: 'ultimaker2',
/*
* Overrides for the current 3D printer definition (Passed to Cura Engine
* with the -s CLI argument)
*/
overrides: [
{
/*
* The scope of the setting. (Passed to Cura Engine with a leading
* hyphen before the corresponding -s argument)
*/
scope: 'e0',
//The override's key/name
key: 'mesh_position_x',
//The override's value
value: -10
}
],
/*
* Wether to enable verbose logging (Useful for debugging; allows Cura
* Engine to directly log to the console)
*/
verbose: true
});
//Load your STL as an ArrayBuffer
const res = await fetch('/demo/benchy.stl');
const stl = await res.arrayBuffer();
//Progress logger (Ranges from 0 to 100)
slicer.on('progress', percent =>
{
console.log(`Progress: ${percent}%`);
});
//Slice (This can take multiple minutes to resolve!)
const gcode = await slicer.slice(stl);
//Do something with the GCODE (ArrayBuffer)
//Dispose (Reccomended but not necessary to call/intended for SPAs)
slicer.dispose();
}
main();
- Multiple browser examples can be found in the
demo
andtests/web
directory (Which is used for browser tests). - Multiple NodeJS examples can be found in the
tests/node
directory.
The performance is decent but not great. If you're running NodeJS, consider using Native Cura Engine instead unless you want the isolation from the WASM VM.
Note: Cura Engine uses OpenMP for multithreading, however, Emscripten doesn't support OpenMP.
Name | Slice Time |
---|---|
NodeJS V14.4.0 |
6084ms |
Chrome 83.0.4103.116 |
5476ms |
Firefox 77.0.1 |
5035ms |
Native Cura Engine V4.6.1 |
1945ms |
Note: NodeJS, Chrome, and Firefox were ran 3 times then averaged; Native Cura Engine was ran 6 times then averaged due to more inconsistent times. The benchmarking computer ran Windows 10 Pro 2004 (19041.329) and had a Ryzen 7 3700X, 32GB DDR4-3600MHZ (CL16), NVMe Gen 4 SSD, and an RTX 2070 Super (Maybe the GPU matters ¯\(ツ)/¯ ).
If you want more finite control over Cura WASM, consider interacting with the worker (worker.ts
) and bypassing the normal CuraWASM
(index.ts
) class. This allows finite control over the command line arguments passed to Cura Engine, direct file I/O, and more; you'll need to re-implement some of the worker management found in the CuraWASM class though. If that's not low enough, consider directly importing CuraEngine.js
(Which is directly built by Emscripten); be warned: it will choke up the calling thread hence the need for Threads JS.
Cura WASM uses emscripten to compile Cura Engine to Web Assembly.
Emscripten provides a virtual filesystem with which Cura WASM loads your STL into as well as the 3D printer definitions. Cura WASM includes a very small modification to Cura Engine which makes it call 2 global functions (Unique to each instance of Cura WASM) alerting Cura WASM when the progress updates and when the part is done so Cura WASM can read the GCODE out of the virtual filesystem.
Yes, this is by no means the first time someone has compiled Cura Engine to run in the browser. Previous projects include gyf304/cura-emscripten, nelsonsilva/CuraEngine-em, Skeen/CuraJS-Engine, and possibly more. However, none of these are maintained and only one (CuraJS) is meant to be used as a library - not a stand-alone application.
Yes. If you're looking for something specific to help with, I'd greatly appreciate any help with making Cura Engine run faster, tightening the JS/TS <---> C++ coupling (eg: improved Cura Engine error reporting), and improving the JS/TS API (eg: allow users to only bundle the printer definitions they need).
Because this ships with Cura Engine already compiled which itself uses AGPL3+. So instead of separately licensing the new code under something like MIT (Which the rest of Cloud CNC uses), it's just simpler to use AGLP3+ for all of Cura WASM. If this is a problem, and you'd like to see everything except the compiled Cura Engine licensed under something like MIT, feel free to file an issue.