@meshioplusplus/wasm 16.25.0 → 16.29.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/index.d.ts CHANGED
@@ -239,13 +239,42 @@ export interface MedInfo {
239
239
  fieldTimeValues: Record<string, number[]>;
240
240
  }
241
241
 
242
- /** MDPA's side channel: per-block entity names. Properties ride on `mesh.propertySets` instead (see {@link PropertySet}), not here. */
242
+ /**
243
+ * MDPA's side channel: per-block entity names and every block the mesh cannot
244
+ * hold. Properties ride on `mesh.propertySets` instead (see {@link PropertySet}),
245
+ * not here. Point references (`geometries[].conn`, `meshBlocks[].nodes`) are
246
+ * 0-based point rows; entity and table ids are the file's own.
247
+ */
243
248
  export interface MdpaInfo {
244
249
  format: 'mdpa';
245
250
  /** One entry per cell block, mesh block order. */
246
251
  entityNames: Array<{ name: string; isCondition: boolean }>;
247
252
  /** Lenient-mode only: constructs this read could not represent, verbatim. */
248
253
  skippedConstructs: string[];
254
+ /** The non-numeric `ModelPartData` entries (`text` set); numeric ones are `fieldData`. */
255
+ modelPartData?: PropertyValue[];
256
+ /** Top-level `Begin Table` blocks: `key` holds the header arguments (`"1 TIME VALUE"`). */
257
+ tables?: PropertyValue[];
258
+ /** `Begin Geometries` runs: `conn` is flat row-major `(n, nodes per geometry)`. */
259
+ geometries?: Array<{ name: string; type: string; conn: Float64Array; ids: number[] }>;
260
+ /** `Begin Mesh <id>` blocks. */
261
+ meshBlocks?: Array<{
262
+ id: number;
263
+ data: PropertyValue[];
264
+ nodes: number[];
265
+ elementIds: number[];
266
+ conditionIds: number[];
267
+ }>;
268
+ /** Data and membership, by hierarchical part name; ids stay raw and are not remapped by operations. */
269
+ subModelParts?: Array<{
270
+ name: string;
271
+ data: PropertyValue[];
272
+ tables: number[];
273
+ geometryIds?: number[];
274
+ constraintIds?: number[];
275
+ }>;
276
+ /** Every other top-level block (`Constraints`, ...), kept verbatim. */
277
+ rawBlocks?: Array<{ header: string; body: string; end: string }>;
249
278
  }
250
279
 
251
280
  /**
@@ -271,6 +300,9 @@ export interface UnvInfo extends AnsysUnvInfoShape {
271
300
  export interface GmshInfo {
272
301
  format: 'gmsh';
273
302
  boundingEntities: number[][];
303
+ /** Entity tags are raw ids; nodePairs is flattened (N,2), 0-based point rows.
304
+ * Ordering/duplicates survive I/O; mesh operations do not remap these rows. */
305
+ periodic?: { entity: number[]; affine: number[]; nodePairs: BigInt64Array | number[] }[];
274
306
  }
275
307
 
276
308
  /** Exodus's side channel: info/QA records. Read-only -- there is no Info-bearing Exodus writer. */
@@ -362,11 +394,31 @@ export interface RegionSummary {
362
394
  * `WriteOptions` field on the C++ side (gzip level 4 is a fixed registry
363
395
  * default; `vtk42`/`vtk51` are separate format keys, not a `vtk` option).
364
396
  */
397
+ /** glTF writer parameters. Components are 0-based; omitted selects magnitude. */
398
+ export interface GltfWriteOptions {
399
+ colorBy?: string;
400
+ cmap?: "viridis" | "coolwarm" | "turbo";
401
+ component?: number;
402
+ vmin?: number;
403
+ vmax?: number;
404
+ splitAngle?: number;
405
+ upAxis?: "auto" | "x" | "y" | "z";
406
+ scale?: number;
407
+ container?: "auto" | "glb" | "gltf";
408
+ normalWeight?: "angle" | "area";
409
+ normals?: boolean;
410
+ fields?: boolean;
411
+ recenter?: boolean;
412
+ byRegion?: boolean;
413
+ unlit?: boolean;
414
+ nanColor?: string;
415
+ }
416
+
365
417
  export interface MeshWriteOptions {
366
418
  /** ASCII vs binary. Errors for a format with only one variant. */
367
419
  encoding?: "ascii" | "binary";
368
- /** Block-compression codec, for the VTK-XML formats (vtu/vtp) only. */
369
- codec?: "none" | "zlib" | "lz4" | "zstd";
420
+ /** VTK block codec, or `lzf` for PCD binary_compressed (not ASCII). */
421
+ codec?: "none" | "zlib" | "lz4" | "zstd" | "lzf";
370
422
  /** `printf`-style float format for ASCII writers that take one (e.g. `".16e"`, the default). */
371
423
  floatFormat?: string;
372
424
  }
@@ -890,9 +942,21 @@ export type XdmfDataFormat = 'HDF' | 'XML' | 'Binary';
890
942
  * `'XML'` writes one self-contained file and needs no companion; `'Binary'`
891
943
  * writes the `.xdmf` plus one `<path minus extension><n>.bin` per array.
892
944
  */
945
+ /** Fixed Exodus geometry, sets and attributes; step fields have a stable schema.
946
+ * Available in netCDF-enabled builds, including the shipped WASM artifacts. */
947
+ export interface ExodusTimeSeriesWriter {
948
+ writePointsCells(mesh: Mesh): void;
949
+ writeData(time: number, mesh: Mesh): void;
950
+ flush(): void;
951
+ finalize(): void;
952
+ numSteps(): number;
953
+ finalized(): boolean;
954
+ close(): void;
955
+ }
956
+
893
957
  export interface XdmfTimeSeriesWriter {
894
958
  /**
895
- * Write the static grid -- the points and cell blocks every step shares.
959
+ * Write the static grid -- points, cell blocks and fixed regions shared by every step.
896
960
  * Only geometry and connectivity are used; any data on `mesh` is ignored,
897
961
  * because in a series data belongs to a step. Call exactly once, before the
898
962
  * first `writeData`.
@@ -1016,6 +1080,10 @@ export interface MeshioPlusPlusModule {
1016
1080
  * @throws {Error} on an unknown/unsupported format or a malformed file.
1017
1081
  */
1018
1082
  readMesh(path: string, format?: string): Mesh;
1083
+ /** MED named meshes require an HDF5-enabled build. Profiles expand with NaN fill. */
1084
+ medMeshNames(path: string): string[];
1085
+ readMedNamed(path: string, name: string, options?: { timeStep?: number; lenient?: boolean }): Mesh;
1086
+ writeMedMulti(path: string, meshes: Mesh[], names: string[], options?: { version?: string }): void;
1019
1087
 
1020
1088
  /**
1021
1089
  * Read only part of a file: geometry alone, or a named subset of data arrays.
@@ -1095,6 +1163,8 @@ export interface MeshioPlusPlusModule {
1095
1163
  writeMesh(
1096
1164
  path: string, mesh: Mesh, format?: string, options?: MeshWriteOptionsWithInfo
1097
1165
  ): string[];
1166
+ /** Export a parameterized glTF surface and return every written MEMFS path. */
1167
+ writeGltf(path: string, mesh: Mesh, options?: GltfWriteOptions): string[];
1098
1168
 
1099
1169
  /**
1100
1170
  * Read `inPath` and write it to `outPath` directly (no intermediate JS
@@ -1158,6 +1228,11 @@ export interface MeshioPlusPlusModule {
1158
1228
  * {@link convertSurfaceOps}' pre-existing camelCase op specs — the two
1159
1229
  * dispatch through the same core engine, differing only in spelling. The
1160
1230
  * returned report's counter keys are PascalCase too.
1231
+ * Version 2 adds per-step `Inputs` for Merge/Interpolate/UndoGreen and
1232
+ * terminal Split/Partition with `Output.Pattern` (`{key}`/`{part}`).
1233
+ * Auxiliary inputs and generated outputs are MEMFS paths. Version 1 and
1234
+ * label-only Partition remain unchanged; spatial v2 steps are not a
1235
+ * transient sequence schema.
1161
1236
  *
1162
1237
  * Unlike {@link convertSurfaceOps} there is no surface-extraction tail:
1163
1238
  * what the pipeline produces is what is written.
@@ -2100,6 +2175,60 @@ export interface MeshioPlusPlusModule {
2100
2175
  */
2101
2176
  editRegions(mesh: Mesh, edits: RegionEdit | RegionEdit[]): Mesh;
2102
2177
 
2178
+ /** Return conforming facets shared by Cell regions (or cell blocks when needed). */
2179
+ regionAdjacency(mesh: Mesh, regions?: Array<string | RegionSelector>): Mesh;
2180
+
2181
+ /** Find conforming or proximity-matched facets; side entries are (cell, local facet). */
2182
+ findInterface(
2183
+ meshA: Mesh,
2184
+ regionA: string | RegionSelector,
2185
+ regionB: string | RegionSelector,
2186
+ options?: {
2187
+ meshB?: Mesh;
2188
+ mode?: "conforming" | "proximity";
2189
+ master?: "a" | "b";
2190
+ gapTolerance?: number;
2191
+ angleTolerance?: number;
2192
+ overlapTolerance?: number;
2193
+ },
2194
+ ): {
2195
+ mesh: Mesh;
2196
+ report: {
2197
+ numPairs: number;
2198
+ area: number;
2199
+ maxGap: number;
2200
+ unmatchedA: number;
2201
+ unmatchedB: number;
2202
+ sideA: Array<[number, number]>;
2203
+ sideB: Array<[number, number]>;
2204
+ };
2205
+ };
2206
+
2207
+ /** Project a Point region onto Cell-region facets. */
2208
+ contactPairs(
2209
+ slaveMesh: Mesh,
2210
+ slavePoints: string | RegionSelector,
2211
+ masterCells: string | RegionSelector,
2212
+ options?: { masterMesh?: Mesh; tolerance?: number; requireComplete?: boolean },
2213
+ ): {
2214
+ slavePoint: Int32Array;
2215
+ masterCell: Int32Array;
2216
+ masterFacet: Int32Array;
2217
+ masterSubfacet: Int32Array;
2218
+ localCoordinates: Float64Array;
2219
+ closestPoint: Float64Array;
2220
+ gap: Float64Array;
2221
+ normal: Float64Array;
2222
+ unmatched: Int32Array;
2223
+ };
2224
+
2225
+ /** Split a mesh along a Side region, optionally inserting cohesive cells. */
2226
+ splitInterface(
2227
+ mesh: Mesh,
2228
+ side: string | RegionSelector,
2229
+ options?: { addCohesive?: boolean },
2230
+ ): { mesh: Mesh; report: { numDuplicatedPoints: number; numCohesiveCells: number } };
2231
+
2103
2232
  /**
2104
2233
  * The master node each node of the `slave` region maps onto under the
2105
2234
  * row-major 4x4 affine `matrix` (16 numbers), within `atol`. `slave` is
@@ -2487,6 +2616,13 @@ export interface MeshioPlusPlusModule {
2487
2616
 
2488
2617
  /** Rename one array, preserving its values and dtype. */
2489
2618
  dataRename(mesh: Mesh, location: DataLocation, from: string, to: string): Mesh;
2619
+ /** Convert region-backed sets to zero-based labels; overlaps use the later
2620
+ * set and uncovered entities use -1. Removes converted regions. */
2621
+ setsToData(mesh: Mesh, location: 'point' | 'cell', options?: {
2622
+ dataName?: string | null; joinChar?: string; order?: string[];
2623
+ }): Mesh;
2624
+ /** Convert a scalar integer field to sets and remove that field. */
2625
+ dataToSets(mesh: Mesh, location: 'point' | 'cell', key: string): Mesh;
2490
2626
 
2491
2627
  /** Average point_data onto the cells (mean over each cell's own nodes). */
2492
2628
  dataPointToCell(mesh: Mesh, names?: string[], suffix?: string): Mesh;
@@ -2578,6 +2714,8 @@ export interface MeshioPlusPlusModule {
2578
2714
  autoFlush?: boolean;
2579
2715
  },
2580
2716
  ): XdmfTimeSeriesWriter;
2717
+ /** Requires netCDF; custom builds without it throw naming the dependency. */
2718
+ createExodusTimeSeriesWriter(path: string): ExodusTimeSeriesWriter;
2581
2719
  }
2582
2720
 
2583
2721
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshioplusplus/wasm",
3
- "version": "16.25.0",
3
+ "version": "16.29.0",
4
4
  "description": "meshio++ mesh I/O compiled to WebAssembly: read 76 and write 68 mesh formats (incl. MED, CGNS, Exodus) in the browser or Node.js",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",
package/src/index.mjs CHANGED
@@ -256,6 +256,10 @@ export class MeshioPlusPlusLoadError extends Error {
256
256
  * featureEdges: (mesh: Mesh, featureAngle?: number, feature?: boolean, boundary?: boolean, nonManifold?: boolean, inconsistent?: boolean, region?: string) => {mesh: Mesh, numFeature: number, numBoundary: number, numNonManifold: number, numInconsistent: number},
257
257
  * hausdorffDistance: (a: Mesh, b: Mesh, faceSamples?: number, regionA?: string, regionB?: string) => {distance: number, aToB: number, bToA: number, meanAToB: number, rmsAToB: number, meanBToA: number, rmsBToA: number, numSamplesA: number, numSamplesB: number, worstPointA: Float64Array, worstPointB: Float64Array},
258
258
  * editRegions: (mesh: Mesh, edits: Array<{op: string, inputs: Array<string | {name: string, kind?: string, dim?: number, tag?: number}>, output?: string, dim?: number, tag?: number, keepInputs?: boolean}>) => Mesh,
259
+ * regionAdjacency: (mesh: Mesh, regions?: Array<string | {name: string, kind?: string, dim?: number, tag?: number}>) => Mesh,
260
+ * findInterface: (meshA: Mesh, regionA: string | object, regionB: string | object, options?: {meshB?: Mesh, mode?: 'conforming'|'proximity', master?: 'a'|'b', gapTolerance?: number, angleTolerance?: number, overlapTolerance?: number}) => {mesh: Mesh, report: object},
261
+ * contactPairs: (slaveMesh: Mesh, slavePoints: string | object, masterCells: string | object, options?: {masterMesh?: Mesh, tolerance?: number, requireComplete?: boolean}) => object,
262
+ * splitInterface: (mesh: Mesh, side: string | object, options?: {addCohesive?: boolean}) => {mesh: Mesh, report: object},
259
263
  * matchPeriodicNodes: (mesh: Mesh, slave: string | {name: string, kind?: string, dim?: number, tag?: number}, master: string | {name: string, kind?: string, dim?: number, tag?: number}, matrix: ArrayLike<number>, atol?: number, requireComplete?: boolean) => {slave: Int32Array, master: Int32Array, unmatched: Int32Array, numFixed: number, maxResidual: number},
260
264
  * repair: (mesh: Mesh, fixOrientation?: boolean, orientOutward?: boolean, fillHoles?: boolean, splitNonManifold?: boolean, maxHoleEdges?: number, weldTolerance?: number, recordProvenance?: boolean) => {mesh: Mesh, qualityBefore: object, qualityAfter: object, numFlipped: number, numComponents: number, largestComponent: number, numOrientedOutward: number, numUnorientable: number, numVerticesSplit: number, numHolesDetected: number, numHolesFilled: number, numHolesSkipped: number, numFacesAdded: number, numPointsAdded: number, pointsWelded: number},
261
265
  * shrinkwrap: (mesh: Mesh, target: Mesh, offset?: number, maxDistance?: number, weights?: string, targetRegion?: string, normalWeight?: string, recordDistance?: boolean, recordClosestCell?: boolean) => {mesh: Mesh, quality: object, numProjected: number, numMissed: number, numSkipped: number, maxDisplacement: number},
@@ -281,6 +285,8 @@ export class MeshioPlusPlusLoadError extends Error {
281
285
  * dataDrop: (mesh: Mesh, location: string, names?: string[], ignoreMissing?: boolean) => Mesh,
282
286
  * dataKeep: (mesh: Mesh, location: string, names?: string[], ignoreMissing?: boolean) => Mesh,
283
287
  * dataRename: (mesh: Mesh, location: string, from: string, to: string) => Mesh,
288
+ * setsToData: (mesh: Mesh, location: string, options?: object) => Mesh,
289
+ * dataToSets: (mesh: Mesh, location: string, key: string) => Mesh,
284
290
  * dataPointToCell: (mesh: Mesh, names?: string[], suffix?: string) => Mesh,
285
291
  * dataCellToPoint: (mesh: Mesh, names?: string[], weight?: string, suffix?: string) => Mesh,
286
292
  * dataCalc: (mesh: Mesh, expression: string, location: string, outputName: string, overwrite?: boolean) => Mesh,
@@ -289,6 +295,11 @@ export class MeshioPlusPlusLoadError extends Error {
289
295
  * dataInfo: (mesh: Mesh) => object[],
290
296
  * dataIntegrate: (mesh: Mesh, arrays?: string[]) => object[],
291
297
  * createXdmfTimeSeriesWriter: (path: string, options?: {dataFormat?: string, gzipLevel?: number, mode?: 'truncate'|'append', autoFlush?: boolean}) => XdmfTimeSeriesWriter,
298
+ * createExodusTimeSeriesWriter: (path: string) => ExodusTimeSeriesWriter,
299
+ * medMeshNames: (path: string) => string[],
300
+ * readMedNamed: (path: string, name: string, options?: object) => Mesh,
301
+ * writeMedMulti: (path: string, meshes: Mesh[], names: string[], options?: object) => void,
302
+ * writeGltf: (path: string, mesh: Mesh, options?: object) => string[],
292
303
  * openSequence: (source: string|string[], options?: object) => SequenceReader,
293
304
  * }>}
294
305
  * @throws {MeshioPlusPlusLoadError} if the WASM module fails to instantiate.
@@ -361,6 +372,11 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
361
372
  return {
362
373
  FS: Module.FS,
363
374
  readMesh: (path, format = '') => Module.readMesh(path, format),
375
+ medMeshNames: (path) => Module.medMeshNames(path),
376
+ readMedNamed: (path, name, { timeStep = 0, lenient = false } = {}) =>
377
+ Module.readMedNamed(path, name, timeStep, lenient),
378
+ writeMedMulti: (path, meshes, names, { version = '4.1.0' } = {}) =>
379
+ Module.writeMedMulti(path, meshes, names, version),
364
380
  // Selective reads (see doc/selective_read.md). `arrays: null` reads
365
381
  // every data array, `arrays: []` reads none -- the distinction is
366
382
  // deliberate. Formats without a native selective path are read whole
@@ -415,6 +431,7 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
415
431
  // an OpenFOAM `polyMesh` directory's files, ...).
416
432
  writeMesh: (path, mesh, format = '', options = undefined) =>
417
433
  Module.writeMesh(path, mesh, format, options),
434
+ writeGltf: (path, mesh, options = undefined) => Module.writeGltf(path, mesh, options),
418
435
  // `options` adds `encoding`/`codec`/`floatFormat` to `inFormat`/
419
436
  // `outFormat` (see `writeMesh`). Returns the written paths, as
420
437
  // `writeMesh` does.
@@ -805,6 +822,12 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
805
822
  Module.hausdorffDistance(a, b, faceSamples, regionA, regionB),
806
823
  editRegions: (mesh, edits) =>
807
824
  Module.editRegions(mesh, Array.isArray(edits) ? edits : [edits]),
825
+ regionAdjacency: (mesh, regions = []) => Module.regionAdjacency(mesh, regions),
826
+ findInterface: (meshA, regionA, regionB, options = {}) =>
827
+ Module.findInterface(meshA, regionA, regionB, options),
828
+ contactPairs: (slaveMesh, slavePoints, masterCells, options = {}) =>
829
+ Module.contactPairs(slaveMesh, slavePoints, masterCells, options),
830
+ splitInterface: (mesh, side, options = {}) => Module.splitInterface(mesh, side, options),
808
831
  matchPeriodicNodes: (mesh, slave, master, matrix, atol = 1e-8, requireComplete = true) =>
809
832
  Module.matchPeriodicNodes(mesh, slave, master, Array.from(matrix), atol,
810
833
  requireComplete),
@@ -992,6 +1015,9 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
992
1015
  dataKeep: (mesh, location, names = [], ignoreMissing = false) =>
993
1016
  Module.dataKeep(mesh, location, names, ignoreMissing),
994
1017
  dataRename: (mesh, location, from, to) => Module.dataRename(mesh, location, from, to),
1018
+ setsToData: (mesh, location, {dataName = null, joinChar = '-', order = []} = {}) =>
1019
+ Module.setsToData(mesh, location, dataName, joinChar, order),
1020
+ dataToSets: (mesh, location, key) => Module.dataToSets(mesh, location, key),
995
1021
  dataPointToCell: (mesh, names = [], suffix = '') =>
996
1022
  Module.dataPointToCell(mesh, names, suffix),
997
1023
  dataCellToPoint: (mesh, names = [], weight = 'uniform', suffix = '') =>
@@ -1035,6 +1061,24 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
1035
1061
  // dataFormat 'HDF' the series is TWO files in the virtual FS: `<path>`
1036
1062
  // and its sibling `<path minus extension>.h5`. Copy BOTH out of
1037
1063
  // Module.FS. `mode: 'append'` continues a series already at `path`.
1064
+ createExodusTimeSeriesWriter: (path) => {
1065
+ const handle = Module.exodusSeriesCreate(path);
1066
+ let open = true;
1067
+ const action = (name, time = 0, mesh = null) => Module.exodusSeriesAction(handle, name, time, mesh);
1068
+ return {
1069
+ writePointsCells: (mesh) => action('grid', 0, mesh),
1070
+ writeData: (time, mesh) => action('data', time, mesh),
1071
+ flush: () => action('flush'),
1072
+ finalize: () => action('finalize'),
1073
+ numSteps: () => action('steps'),
1074
+ finalized: () => action('finalized'),
1075
+ close: () => {
1076
+ if (!open) return;
1077
+ open = false;
1078
+ try { action('finalize'); } finally { action('free'); }
1079
+ },
1080
+ };
1081
+ },
1038
1082
  createXdmfTimeSeriesWriter: (
1039
1083
  path,
1040
1084
  { dataFormat = 'HDF', gzipLevel = -1, mode = 'truncate', autoFlush = false } = {},