@meshioplusplus/wasm 17.0.0 → 17.2.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/README.md +28 -2
- package/THIRD_PARTY_NOTICES.md +32 -0
- package/dist/meshioplusplus_wasm.mjs +1 -1
- package/dist/meshioplusplus_wasm.wasm +0 -0
- package/dist/meshioplusplus_wasm_full.mjs +2 -0
- package/dist/meshioplusplus_wasm_full.wasm +0 -0
- package/dist/meshioplusplus_wasm_full_mt.mjs +2 -0
- package/dist/meshioplusplus_wasm_full_mt.wasm +0 -0
- package/dist/meshioplusplus_wasm_mt.mjs +1 -1
- package/dist/meshioplusplus_wasm_mt.wasm +0 -0
- package/index.d.ts +137 -5
- package/package.json +12 -4
- package/src/index.mjs +104 -18
package/index.d.ts
CHANGED
|
@@ -367,6 +367,13 @@ export interface IgaOptions {
|
|
|
367
367
|
trim?: boolean;
|
|
368
368
|
}
|
|
369
369
|
|
|
370
|
+
/**
|
|
371
|
+
* A B-rep in CAD JSON's shape: what a `cad_json` file holds, what `fitCad`
|
|
372
|
+
* returns as `info`, and -- in the full artifact -- what reading a `step` or
|
|
373
|
+
* `iges` file with `{info: true}` returns (still `format: 'cad_json'`, so
|
|
374
|
+
* `writeMesh(path, mesh, 'cad_json', {info})` and the `iga*` operations take
|
|
375
|
+
* it unchanged).
|
|
376
|
+
*/
|
|
370
377
|
export interface CadJsonInfo {
|
|
371
378
|
format: 'cad_json';
|
|
372
379
|
/** The face surfaces: two degrees, two full knot vectors, (points, 3) control net (u fastest). */
|
|
@@ -1695,14 +1702,37 @@ export interface MeshioPlusPlusModule {
|
|
|
1695
1702
|
*/
|
|
1696
1703
|
hasCgnslib(): boolean;
|
|
1697
1704
|
|
|
1705
|
+
/**
|
|
1706
|
+
* Whether OpenCASCADE is linked in, so `step` and `iges` read and `fitCad`
|
|
1707
|
+
* runs: true in the full artifact (`{full: true}`), false in the lean one.
|
|
1708
|
+
*/
|
|
1709
|
+
hasOcct(): boolean;
|
|
1710
|
+
|
|
1711
|
+
/** Whether the VTK XML zstd block codec is linked in (the full artifact). */
|
|
1712
|
+
hasZstd(): boolean;
|
|
1713
|
+
|
|
1714
|
+
/** Whether the VTK XML lz4 block codec is linked in (the full artifact). */
|
|
1715
|
+
hasLz4(): boolean;
|
|
1716
|
+
|
|
1717
|
+
/** Whether bzip2 is linked in, for libMesh `.xda.bz2`/`.xdr.bz2` (the full artifact). */
|
|
1718
|
+
hasBzip2(): boolean;
|
|
1719
|
+
|
|
1720
|
+
/**
|
|
1721
|
+
* Which artifact loaded: `'lean'` (`meshioplusplus_wasm[_mt]`, MIT) or
|
|
1722
|
+
* `'full'` (`meshioplusplus_wasm_full[_mt]`, with OpenCASCADE, zstd, lz4 and
|
|
1723
|
+
* bzip2; mixed licence, see the package's THIRD_PARTY_NOTICES.md).
|
|
1724
|
+
*/
|
|
1725
|
+
buildFlavour(): 'lean' | 'full';
|
|
1726
|
+
|
|
1698
1727
|
/**
|
|
1699
1728
|
* The format names this build can actually read and write, both sorted.
|
|
1700
1729
|
*
|
|
1701
1730
|
* Prefer this over a hardcoded table when building a file-picker filter or a
|
|
1702
|
-
* "convert to" menu: the two lists genuinely differ (`
|
|
1703
|
-
*
|
|
1731
|
+
* "convert to" menu: the two lists genuinely differ (`gmsh22` is
|
|
1732
|
+
* write-only), and the set depends on how
|
|
1704
1733
|
* the artifact was built -- an official build carries the HDF5/netCDF-backed
|
|
1705
|
-
* formats, one built with `--without-hdf5` does not
|
|
1734
|
+
* formats, one built with `--without-hdf5` does not, and `step` and `iges`
|
|
1735
|
+
* are readers only in the full artifact.
|
|
1706
1736
|
*/
|
|
1707
1737
|
availableFormats(): { readers: string[]; writers: string[] };
|
|
1708
1738
|
|
|
@@ -2516,6 +2546,18 @@ export interface MeshioPlusPlusModule {
|
|
|
2516
2546
|
numUnfitted: number;
|
|
2517
2547
|
};
|
|
2518
2548
|
|
|
2549
|
+
/**
|
|
2550
|
+
* Build a CAD solid from the fitted patches of a closed skin (normally the
|
|
2551
|
+
* output of `segment` then `fitPrimitives`): planes, spheres, cylinders,
|
|
2552
|
+
* cones and tori, fillets and blends, threads and freeform B-spline faces,
|
|
2553
|
+
* sewn and checked by OpenCASCADE, optionally written as STEP to
|
|
2554
|
+
* `stepPath` on the virtual FS. Needs OpenCASCADE: the full artifact only.
|
|
2555
|
+
* See doc/fit_cad.md.
|
|
2556
|
+
* @throws {Error} in the lean artifact (naming `{full: true}`), on a bad
|
|
2557
|
+
* option, or on a skin that is not closed.
|
|
2558
|
+
*/
|
|
2559
|
+
fitCad(mesh: Mesh, options?: FitCadOptions): FitCadResult;
|
|
2560
|
+
|
|
2519
2561
|
/**
|
|
2520
2562
|
* Refine every patch (every face surface of a B-rep) of a NURBS model
|
|
2521
2563
|
* exactly: degree elevation by `elevate`, then knot insertion splitting each
|
|
@@ -3197,16 +3239,104 @@ export interface MeshioPlusPlusModule {
|
|
|
3197
3239
|
* `locateFile`/`onAbort` wrapped for diagnostics (your own overrides still
|
|
3198
3240
|
* run first) -- see {@link MeshioPlusPlusLoadError}. `locateFile` receives
|
|
3199
3241
|
* the requested filename, so return the URL matching the loaded variant
|
|
3200
|
-
* (`meshioplusplus_wasm.wasm` or `meshioplusplus_wasm_mt.wasm
|
|
3242
|
+
* (`meshioplusplus_wasm.wasm` or `meshioplusplus_wasm_mt.wasm`, and their
|
|
3243
|
+
* `_full` counterparts with `full`).
|
|
3201
3244
|
* @param options.variant which native artifact to load: `'auto'` (default),
|
|
3202
3245
|
* `'mt'` (force threaded), or `'seq'` (force sequential).
|
|
3246
|
+
* @param options.full load the full artifact (OpenCASCADE, zstd, lz4, bzip2;
|
|
3247
|
+
* mixed licence) rather than the lean, MIT one. Only the chosen artifact's
|
|
3248
|
+
* bytes are fetched.
|
|
3249
|
+
* @param options.fullGlue where the full artifact's glue module lives, for a
|
|
3250
|
+
* bundled app that copied `dist/meshioplusplus_wasm_full*.{mjs,wasm}`
|
|
3251
|
+
* itself; the loader never names the full glue literally, so a bundler
|
|
3252
|
+
* does not pull it into a lean bundle.
|
|
3203
3253
|
* @throws {MeshioPlusPlusLoadError} if the WASM module fails to instantiate.
|
|
3204
3254
|
*/
|
|
3205
3255
|
export function loadMeshioPlusPlus(
|
|
3206
3256
|
moduleOverrides?: ModuleOverrides,
|
|
3207
|
-
options?:
|
|
3257
|
+
options?: LoadOptions,
|
|
3208
3258
|
): Promise<MeshioPlusPlusModule>;
|
|
3209
3259
|
|
|
3260
|
+
/** The second argument of {@link loadMeshioPlusPlus}. */
|
|
3261
|
+
export interface LoadOptions {
|
|
3262
|
+
variant?: 'auto' | 'mt' | 'seq';
|
|
3263
|
+
full?: boolean;
|
|
3264
|
+
fullGlue?: string | URL;
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3267
|
+
/** The options of {@link MeshioPlusPlusModule.fitCad}; every key is optional. */
|
|
3268
|
+
export interface FitCadOptions {
|
|
3269
|
+
/** Write the solid as AP214 STEP here (virtual FS); omitted writes nothing. */
|
|
3270
|
+
stepPath?: string;
|
|
3271
|
+
/** The largest distance a face may lie from the skin; <= 0 is automatic. */
|
|
3272
|
+
tolerance?: number;
|
|
3273
|
+
/** Try the exact intersection of two analytic surfaces first (default true). */
|
|
3274
|
+
exactEdges?: boolean;
|
|
3275
|
+
/** The accepted primitive types that become analytic faces (default: all five). */
|
|
3276
|
+
types?: Array<'plane' | 'sphere' | 'cylinder' | 'cone' | 'torus'>;
|
|
3277
|
+
/** The re-meshed solid's chordal deflection; <= 0 takes tolerance / 4. */
|
|
3278
|
+
meshDeflection?: number;
|
|
3279
|
+
/** Rounds of demoting failed faces before every patch is faceted (default 8). */
|
|
3280
|
+
maxDemotionRounds?: number;
|
|
3281
|
+
/** Try a freeform B-spline face where no primitive fits (default true). */
|
|
3282
|
+
freeform?: boolean;
|
|
3283
|
+
/** The freeform B-spline's highest degree, 3 to 8 (default 3). */
|
|
3284
|
+
freeformDegree?: number;
|
|
3285
|
+
/** The most grid points per direction a freeform fit samples (default 64). */
|
|
3286
|
+
freeformMaxControl?: number;
|
|
3287
|
+
/** Split a freeform patch that folds over every flattening (default true). */
|
|
3288
|
+
freeformSplit?: boolean;
|
|
3289
|
+
/** Try fillets, blends, chamfers and vertex blends (default true). */
|
|
3290
|
+
fillets?: boolean;
|
|
3291
|
+
/** Try thread faces, tapered and of varying pitch included (default true). */
|
|
3292
|
+
threads?: boolean;
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3295
|
+
/** What {@link MeshioPlusPlusModule.fitCad} built. */
|
|
3296
|
+
export interface FitCadResult {
|
|
3297
|
+
/** The solid re-meshed, with `fit_cad:face`, `fit_cad:type` and `fit_cad:patch` cell data. */
|
|
3298
|
+
mesh: Mesh;
|
|
3299
|
+
/** Whether the solid passed OpenCASCADE's B-rep check. */
|
|
3300
|
+
valid: boolean;
|
|
3301
|
+
tolerance: number;
|
|
3302
|
+
volume: number;
|
|
3303
|
+
skinVolume: number;
|
|
3304
|
+
volumeRatio: number;
|
|
3305
|
+
/** Symmetric Hausdorff distance, skin to re-meshed solid. */
|
|
3306
|
+
maxDeviation: number;
|
|
3307
|
+
numFaces: number;
|
|
3308
|
+
numPlane: number;
|
|
3309
|
+
numSphere: number;
|
|
3310
|
+
numCylinder: number;
|
|
3311
|
+
numCone: number;
|
|
3312
|
+
numTorus: number;
|
|
3313
|
+
numFacetedFaces: number;
|
|
3314
|
+
numPatches: number;
|
|
3315
|
+
numDemoted: number;
|
|
3316
|
+
numExactEdges: number;
|
|
3317
|
+
numApproxEdges: number;
|
|
3318
|
+
numSolids: number;
|
|
3319
|
+
numBspline: number;
|
|
3320
|
+
numSplitPatches: number;
|
|
3321
|
+
numFillet: number;
|
|
3322
|
+
numHelical: number;
|
|
3323
|
+
numVariableFillet: number;
|
|
3324
|
+
numBlend: number;
|
|
3325
|
+
numRoundedThread: number;
|
|
3326
|
+
/** Vertex blends (setback corners), type 9. */
|
|
3327
|
+
numVertexBlend: number;
|
|
3328
|
+
/** Chamfers (straight-section blends), type 10. */
|
|
3329
|
+
numChamfer: number;
|
|
3330
|
+
/** Fillet faces whose section is a conic rather than a circle. */
|
|
3331
|
+
numConicBlend: number;
|
|
3332
|
+
/** Thread flanks on a tapered (conical) thread. */
|
|
3333
|
+
numTaperedThread: number;
|
|
3334
|
+
/** Thread flanks whose pitch varies along the axis. */
|
|
3335
|
+
numVariablePitchThread: number;
|
|
3336
|
+
/** The solid's B-rep, for `writeMesh(path, mesh, 'cad_json', {info})`. */
|
|
3337
|
+
info: CadJsonInfo;
|
|
3338
|
+
}
|
|
3339
|
+
|
|
3210
3340
|
/** Overrides forwarded to the underlying Emscripten module factory. */
|
|
3211
3341
|
export interface ModuleOverrides {
|
|
3212
3342
|
/**
|
|
@@ -3234,6 +3364,8 @@ export interface MeshioPlusPlusLoadError extends Error {
|
|
|
3234
3364
|
name: 'MeshioPlusPlusLoadError';
|
|
3235
3365
|
/** Which native artifact was being loaded. */
|
|
3236
3366
|
variant: 'mt' | 'seq';
|
|
3367
|
+
/** Whether it was the full artifact. */
|
|
3368
|
+
full: boolean;
|
|
3237
3369
|
/** The glue module specifier (e.g. '../dist/meshioplusplus_wasm_mt.mjs'). */
|
|
3238
3370
|
glue: string;
|
|
3239
3371
|
/** The filename Emscripten asked `locateFile` to resolve, if it got that far. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meshioplusplus/wasm",
|
|
3
|
-
"version": "17.
|
|
4
|
-
"description": "meshio++ mesh I/O compiled to WebAssembly: read
|
|
3
|
+
"version": "17.2.0",
|
|
4
|
+
"description": "meshio++ mesh I/O compiled to WebAssembly: read 80 and write 75 mesh formats (incl. MED, CGNS, Exodus; STEP and IGES in the full build) in the browser or Node.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.mjs",
|
|
7
7
|
"module": "./src/index.mjs",
|
|
@@ -12,8 +12,13 @@
|
|
|
12
12
|
"dist/meshioplusplus_wasm.wasm",
|
|
13
13
|
"dist/meshioplusplus_wasm_mt.mjs",
|
|
14
14
|
"dist/meshioplusplus_wasm_mt.wasm",
|
|
15
|
+
"dist/meshioplusplus_wasm_full.mjs",
|
|
16
|
+
"dist/meshioplusplus_wasm_full.wasm",
|
|
17
|
+
"dist/meshioplusplus_wasm_full_mt.mjs",
|
|
18
|
+
"dist/meshioplusplus_wasm_full_mt.wasm",
|
|
15
19
|
"index.d.ts",
|
|
16
|
-
"README.md"
|
|
20
|
+
"README.md",
|
|
21
|
+
"THIRD_PARTY_NOTICES.md"
|
|
17
22
|
],
|
|
18
23
|
"engines": {
|
|
19
24
|
"node": ">=18"
|
|
@@ -29,9 +34,12 @@
|
|
|
29
34
|
"obj",
|
|
30
35
|
"finite-elements",
|
|
31
36
|
"fem",
|
|
37
|
+
"step",
|
|
38
|
+
"iges",
|
|
39
|
+
"cad",
|
|
32
40
|
"scientific-computing"
|
|
33
41
|
],
|
|
34
|
-
"license": "MIT",
|
|
42
|
+
"license": "MIT AND (LGPL-2.1-only WITH OCCT-exception-1.0)",
|
|
35
43
|
"author": "Vicente Mataix Ferrandiz",
|
|
36
44
|
"homepage": "https://github.com/loumalouomega/meshioplusplus",
|
|
37
45
|
"repository": {
|
package/src/index.mjs
CHANGED
|
@@ -29,6 +29,16 @@
|
|
|
29
29
|
// context, else the sequential one. The dynamic import()s are literal so
|
|
30
30
|
// bundlers (Vite) emit both chunks. Callers can force a build with the
|
|
31
31
|
// `{ variant }` option.
|
|
32
|
+
//
|
|
33
|
+
// Beside that lean pair the package ships the FULL pair (roadmap 6.2),
|
|
34
|
+
// meshioplusplus_wasm_full and meshioplusplus_wasm_full_mt: the same API, with
|
|
35
|
+
// OpenCASCADE (STEP/IGES reading, fitCad), zstd, lz4 and bzip2 linked in, and
|
|
36
|
+
// a mixed licence (OpenCASCADE is LGPL-2.1 with its exception; see
|
|
37
|
+
// THIRD_PARTY_NOTICES.md). `{ full: true }` loads it, with the same variant
|
|
38
|
+
// choice. Its import() is deliberately NOT literal: a bundler that saw it would
|
|
39
|
+
// pull the full bytes into every lean consumer's bundle. Node and native
|
|
40
|
+
// browser ESM resolve it next to this file; a bundled app copies the full
|
|
41
|
+
// glue and .wasm itself and passes `fullGlue` (and `locateFile`).
|
|
32
42
|
|
|
33
43
|
// The raw xdmfSeriesWriteDataArrays embind call still converts every value
|
|
34
44
|
// with emscripten::convertJSArrayToNumberVector<double>, which throws on a
|
|
@@ -61,6 +71,17 @@ function resolveVariant(variant) {
|
|
|
61
71
|
return crossOriginIsolated ? 'mt' : 'seq';
|
|
62
72
|
}
|
|
63
73
|
|
|
74
|
+
/**
|
|
75
|
+
* The glue module of the full artifact for a variant, relative to this file.
|
|
76
|
+
* @param {'mt'|'seq'} chosen
|
|
77
|
+
* @returns {string}
|
|
78
|
+
*/
|
|
79
|
+
function fullGlueFor(chosen) {
|
|
80
|
+
return chosen === 'mt'
|
|
81
|
+
? '../dist/meshioplusplus_wasm_full_mt.mjs'
|
|
82
|
+
: '../dist/meshioplusplus_wasm_full.mjs';
|
|
83
|
+
}
|
|
84
|
+
|
|
64
85
|
/**
|
|
65
86
|
* Thrown by `loadMeshioPlusPlus()` when a WASM module fails to instantiate,
|
|
66
87
|
* so a caller can tell a wrong `.wasm` URL from an environment that cannot
|
|
@@ -72,6 +93,7 @@ export class MeshioPlusPlusLoadError extends Error {
|
|
|
72
93
|
* @param {string} message
|
|
73
94
|
* @param {object} details
|
|
74
95
|
* @param {'mt'|'seq'} details.variant - which artifact was being loaded.
|
|
96
|
+
* @param {boolean} [details.full] - whether it was the full artifact.
|
|
75
97
|
* @param {string} details.glue - the glue module specifier (e.g.
|
|
76
98
|
* '../dist/meshioplusplus_wasm_mt.mjs').
|
|
77
99
|
* @param {string} [details.requestedFile] - the filename Emscripten asked
|
|
@@ -79,10 +101,11 @@ export class MeshioPlusPlusLoadError extends Error {
|
|
|
79
101
|
* @param {string} [details.resolvedUrl] - what `locateFile` returned for it.
|
|
80
102
|
* @param {unknown} [details.cause] - the underlying error/abort reason.
|
|
81
103
|
*/
|
|
82
|
-
constructor(message, { variant, glue, requestedFile, resolvedUrl, cause }) {
|
|
104
|
+
constructor(message, { variant, full = false, glue, requestedFile, resolvedUrl, cause }) {
|
|
83
105
|
super(message, cause === undefined ? undefined : { cause });
|
|
84
106
|
this.name = 'MeshioPlusPlusLoadError';
|
|
85
107
|
this.variant = variant;
|
|
108
|
+
this.full = full;
|
|
86
109
|
this.glue = glue;
|
|
87
110
|
this.requestedFile = requestedFile;
|
|
88
111
|
this.resolvedUrl = resolvedUrl;
|
|
@@ -190,12 +213,19 @@ export class MeshioPlusPlusLoadError extends Error {
|
|
|
190
213
|
* `{ locateFile: (p) => new URL(p, import.meta.url) }` relocates the
|
|
191
214
|
* `.wasm` binary for a bundler/CDN setup; `locateFile` receives the
|
|
192
215
|
* requested filename, so return the URL matching the loaded variant
|
|
193
|
-
* (`meshioplusplus_wasm.wasm` or `_wasm_mt.wasm`
|
|
216
|
+
* (`meshioplusplus_wasm.wasm` or `_wasm_mt.wasm`, and `_wasm_full.wasm` or
|
|
217
|
+
* `_wasm_full_mt.wasm` with `full`).
|
|
194
218
|
* @param {object} [options]
|
|
195
219
|
* @param {'auto'|'mt'|'seq'} [options.variant='auto'] - which native artifact to
|
|
196
220
|
* load. `auto` picks the threaded (`mt`) build under Node and in a
|
|
197
221
|
* cross-origin-isolated browser, else the sequential (`seq`) build; `mt`/`seq`
|
|
198
222
|
* force one (`mt` aborts if the environment cannot host Wasm threads).
|
|
223
|
+
* @param {boolean} [options.full=false] - load the full artifact (OpenCASCADE,
|
|
224
|
+
* zstd, lz4, bzip2; mixed licence) instead of the lean, MIT one. The lean
|
|
225
|
+
* bytes are never fetched then, nor the full ones without it.
|
|
226
|
+
* @param {string|URL} [options.fullGlue] - where the full artifact's glue module
|
|
227
|
+
* lives, for a bundled app that copied it (default: `../dist/` beside this
|
|
228
|
+
* file). Pair it with a `locateFile` that finds the matching `.wasm`.
|
|
199
229
|
* @returns {Promise<{
|
|
200
230
|
* FS: object,
|
|
201
231
|
* readMesh: (path: string, format?: string) => Mesh,
|
|
@@ -218,6 +248,11 @@ export class MeshioPlusPlusLoadError extends Error {
|
|
|
218
248
|
* meshBackend: () => string,
|
|
219
249
|
* parallelBackend: () => string,
|
|
220
250
|
* hasCgnslib: () => boolean,
|
|
251
|
+
* hasOcct: () => boolean,
|
|
252
|
+
* hasZstd: () => boolean,
|
|
253
|
+
* hasLz4: () => boolean,
|
|
254
|
+
* hasBzip2: () => boolean,
|
|
255
|
+
* buildFlavour: () => 'lean' | 'full',
|
|
221
256
|
* availableFormats: () => {readers: string[], writers: string[]},
|
|
222
257
|
* extractSurface: (mesh: Mesh, recordParentIds?: boolean) => Mesh,
|
|
223
258
|
* extractSkin: (mesh: Mesh, linearize?: boolean) => Mesh,
|
|
@@ -260,6 +295,7 @@ export class MeshioPlusPlusLoadError extends Error {
|
|
|
260
295
|
* igaSample: (info: object, options?: {sampleSubdivisions?: number, trimSamples?: number, edges?: boolean, trim?: boolean}) => {mesh: Mesh, info: object},
|
|
261
296
|
* igaEvaluate: (info: object, patch: number, params: ArrayLike<number>, options?: {derivatives?: 0 | 1, trimSamples?: number}) => object,
|
|
262
297
|
* fitPrimitives: (mesh: Mesh, patchData?: string, tolerance?: number, relative?: boolean, minInlierFraction?: number, types?: string[], maxIterations?: number) => {mesh: Mesh, numPatches: number, numPlane: number, numSphere: number, numCylinder: number, numCone: number, numTorus: number, numUnfitted: number},
|
|
298
|
+
* fitCad: (mesh: Mesh, options?: {stepPath?: string, tolerance?: number, exactEdges?: boolean, types?: string[], meshDeflection?: number, maxDemotionRounds?: number, freeform?: boolean, freeformDegree?: number, freeformMaxControl?: number, freeformSplit?: boolean, fillets?: boolean, threads?: boolean}) => object,
|
|
263
299
|
* tessellate: (mesh: Mesh, levels?: number, curved?: boolean, fields?: boolean, recordStencil?: boolean) => {mesh: Mesh, numSourcePoints: number, numSourceCells: number, numCurvedSourceCells: number, numPassThroughSourceCells: number, numPoints: number, numCells: number, numBoundaryFacets: number, numInteriorFacets: number, numFacetsWithBadCount: number},
|
|
264
300
|
* render: (mesh: Mesh, options?: RenderOptions) => RenderedFrame,
|
|
265
301
|
* renderText: (mesh: Mesh, options?: RenderOptions, text?: RenderTextOptions) => string,
|
|
@@ -314,16 +350,43 @@ export class MeshioPlusPlusLoadError extends Error {
|
|
|
314
350
|
* }>}
|
|
315
351
|
* @throws {MeshioPlusPlusLoadError} if the WASM module fails to instantiate.
|
|
316
352
|
*/
|
|
317
|
-
export async function loadMeshioPlusPlus(
|
|
353
|
+
export async function loadMeshioPlusPlus(
|
|
354
|
+
moduleOverrides = {},
|
|
355
|
+
{ variant = 'auto', full = false, fullGlue } = {},
|
|
356
|
+
) {
|
|
318
357
|
const chosen = resolveVariant(variant);
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
358
|
+
const flavour = full ? 'full' : 'lean';
|
|
359
|
+
const label = full ? `full ${chosen}` : chosen;
|
|
360
|
+
let glue;
|
|
361
|
+
let createRawModule;
|
|
362
|
+
if (full) {
|
|
363
|
+
glue = String(fullGlue ?? fullGlueFor(chosen));
|
|
364
|
+
// A computed specifier on purpose (see the header): bundlers leave it
|
|
365
|
+
// alone, so a lean bundle never carries the full artifact.
|
|
366
|
+
try {
|
|
367
|
+
({ default: createRawModule } = await import(
|
|
368
|
+
/* @vite-ignore */ /* webpackIgnore: true */ fullGlue === undefined
|
|
369
|
+
? new URL(glue, import.meta.url).href
|
|
370
|
+
: glue
|
|
371
|
+
));
|
|
372
|
+
} catch (cause) {
|
|
373
|
+
throw new MeshioPlusPlusLoadError(
|
|
374
|
+
`meshio++ (wasm): cannot import the full artifact's glue (${glue}): ` +
|
|
375
|
+
`${cause.message ?? cause}. A bundled app copies ` +
|
|
376
|
+
"dist/meshioplusplus_wasm_full*.{mjs,wasm} and passes `fullGlue`.",
|
|
377
|
+
{ variant: chosen, full, glue, cause },
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
} else {
|
|
381
|
+
glue =
|
|
382
|
+
chosen === 'mt' ? '../dist/meshioplusplus_wasm_mt.mjs' : '../dist/meshioplusplus_wasm.mjs';
|
|
383
|
+
// Literal specifiers so bundlers emit both chunks; the sequential one
|
|
384
|
+
// is the fallback whenever threads are unavailable.
|
|
385
|
+
({ default: createRawModule } =
|
|
386
|
+
chosen === 'mt'
|
|
387
|
+
? await import('../dist/meshioplusplus_wasm_mt.mjs')
|
|
388
|
+
: await import('../dist/meshioplusplus_wasm.mjs'));
|
|
389
|
+
}
|
|
327
390
|
|
|
328
391
|
// Wrap locateFile/onAbort (rather than passing moduleOverrides through
|
|
329
392
|
// untouched) so a failed instantiation can be reported with which file
|
|
@@ -355,10 +418,10 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
|
|
|
355
418
|
Module = await createRawModule(wrappedOverrides);
|
|
356
419
|
} catch (cause) {
|
|
357
420
|
throw new MeshioPlusPlusLoadError(
|
|
358
|
-
`meshio++ (wasm): failed to instantiate the '${
|
|
421
|
+
`meshio++ (wasm): failed to instantiate the '${label}' variant (${glue}): ` +
|
|
359
422
|
`${abortReason ?? cause.message ?? cause}. Emscripten requested ` +
|
|
360
423
|
`'${requestedFile}' and locateFile returned '${resolvedUrl}'.`,
|
|
361
|
-
{ variant: chosen, glue, requestedFile, resolvedUrl, cause },
|
|
424
|
+
{ variant: chosen, full, glue, requestedFile, resolvedUrl, cause },
|
|
362
425
|
);
|
|
363
426
|
}
|
|
364
427
|
|
|
@@ -371,11 +434,25 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
|
|
|
371
434
|
const actualBackend = Module.parallelBackend();
|
|
372
435
|
if (actualBackend !== expectedBackend) {
|
|
373
436
|
throw new MeshioPlusPlusLoadError(
|
|
374
|
-
`meshio++ (wasm): failed to instantiate the '${
|
|
437
|
+
`meshio++ (wasm): failed to instantiate the '${label}' variant (${glue}): ` +
|
|
375
438
|
`loaded, but reports parallel backend '${actualBackend}' (expected ` +
|
|
376
439
|
`'${expectedBackend}') -- locateFile likely returned the wrong .wasm binary. ` +
|
|
377
440
|
`Emscripten requested '${requestedFile}' and locateFile returned '${resolvedUrl}'.`,
|
|
378
|
-
{ variant: chosen, glue, requestedFile, resolvedUrl },
|
|
441
|
+
{ variant: chosen, full, glue, requestedFile, resolvedUrl },
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
// The same tell for the lean/full split: the two share the whole export
|
|
445
|
+
// surface, so a lean .wasm behind the full glue (or the reverse) can link.
|
|
446
|
+
// A binary from before buildFlavour existed is a lean one.
|
|
447
|
+
const actualFlavour =
|
|
448
|
+
typeof Module.buildFlavour === 'function' ? Module.buildFlavour() : 'lean';
|
|
449
|
+
if (actualFlavour !== flavour) {
|
|
450
|
+
throw new MeshioPlusPlusLoadError(
|
|
451
|
+
`meshio++ (wasm): failed to instantiate the '${label}' variant (${glue}): ` +
|
|
452
|
+
`loaded, but reports the '${actualFlavour}' artifact (expected '${flavour}') -- ` +
|
|
453
|
+
`locateFile likely returned the wrong .wasm binary. Emscripten requested ` +
|
|
454
|
+
`'${requestedFile}' and locateFile returned '${resolvedUrl}'.`,
|
|
455
|
+
{ variant: chosen, full, glue, requestedFile, resolvedUrl },
|
|
379
456
|
);
|
|
380
457
|
}
|
|
381
458
|
|
|
@@ -523,10 +600,17 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
|
|
|
523
600
|
// meshioplusplus_wasm_mt one -- which of the two this instance loaded.
|
|
524
601
|
parallelBackend: () => Module.parallelBackend(),
|
|
525
602
|
hasCgnslib: () => Module.hasCgnslib(),
|
|
603
|
+
// The full artifact's libraries (roadmap 6.2): all four are true there
|
|
604
|
+
// and false in the lean one. buildFlavour() names which loaded.
|
|
605
|
+
hasOcct: () => Module.hasOcct(),
|
|
606
|
+
hasZstd: () => Module.hasZstd(),
|
|
607
|
+
hasLz4: () => Module.hasLz4(),
|
|
608
|
+
hasBzip2: () => Module.hasBzip2(),
|
|
609
|
+
buildFlavour: () => Module.buildFlavour(),
|
|
526
610
|
// What this build can actually read/write, both sorted. Prefer this
|
|
527
|
-
// over a hardcoded table: a few formats are
|
|
528
|
-
//
|
|
529
|
-
//
|
|
611
|
+
// over a hardcoded table: a few formats are write-only (gmsh22), and the
|
|
612
|
+
// HDF5/netCDF-backed ones are present only in a build that linked them
|
|
613
|
+
// (the official artifact does).
|
|
530
614
|
availableFormats: () => Module.availableFormats(),
|
|
531
615
|
// Mesh operations (see doc/*.md per operation): computations ON a mesh,
|
|
532
616
|
// not file formats. Index maps (crop/split/convertCells) are not carried
|
|
@@ -862,6 +946,8 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
|
|
|
862
946
|
) =>
|
|
863
947
|
Module.fitPrimitives(mesh, patchData, tolerance, relative, minInlierFraction,
|
|
864
948
|
Array.isArray(types) ? types : [types], maxIterations),
|
|
949
|
+
// OpenCASCADE: the full artifact only; the lean one throws by name.
|
|
950
|
+
fitCad: (mesh, options = {}) => Module.fitCad(mesh, options),
|
|
865
951
|
igaRefine: (info, options = {}) => Module.igaRefine(info, options),
|
|
866
952
|
igaSample: (info, options = {}) => Module.igaSample(info, options),
|
|
867
953
|
igaEvaluate: (info, patch, params, options = {}) =>
|