@meshioplusplus/wasm 10.21.1 → 12.0.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 +1 -1
- package/dist/meshioplusplus_wasm.mjs +1 -1
- package/dist/meshioplusplus_wasm.wasm +0 -0
- package/dist/meshioplusplus_wasm_mt.mjs +1 -1
- package/dist/meshioplusplus_wasm_mt.wasm +0 -0
- package/index.d.ts +631 -53
- package/package.json +2 -2
- package/src/index.mjs +391 -48
package/index.d.ts
CHANGED
|
@@ -7,6 +7,53 @@
|
|
|
7
7
|
* A rectangular (uniform node count) group of cells, all the same meshio++
|
|
8
8
|
* cell type.
|
|
9
9
|
*/
|
|
10
|
+
/**
|
|
11
|
+
* What is wrong with a surface, in numbers rather than a bare flag -- the four
|
|
12
|
+
* counts `surfaceWatertightCheck`, `computeCurvature`, `repair` and
|
|
13
|
+
* `shrinkwrap` all report.
|
|
14
|
+
*/
|
|
15
|
+
export interface SurfaceQualityInfo {
|
|
16
|
+
boundaryEdges: number;
|
|
17
|
+
nonManifoldEdges: number;
|
|
18
|
+
inconsistentPairs: number;
|
|
19
|
+
degenerateTriangles: number;
|
|
20
|
+
watertight: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A `point_data`/`cell_data`/`field_data` array's JS type: it carries its
|
|
25
|
+
* source dtype crossing the WASM boundary instead of always widening to
|
|
26
|
+
* `Float64Array` (roadmap §1 "WASM parity": dtype carry). `BigInt64Array`/
|
|
27
|
+
* `BigUint64Array` elements are JS `bigint`, not `number` -- see
|
|
28
|
+
* {@link XdmfTimeSeriesWriter.writeDataArrays} if you need to feed one to an
|
|
29
|
+
* API that still expects `number`s.
|
|
30
|
+
*/
|
|
31
|
+
export type DataArray =
|
|
32
|
+
| Float32Array
|
|
33
|
+
| Float64Array
|
|
34
|
+
| Int8Array
|
|
35
|
+
| Int16Array
|
|
36
|
+
| Int32Array
|
|
37
|
+
| BigInt64Array
|
|
38
|
+
| Uint8Array
|
|
39
|
+
| Uint16Array
|
|
40
|
+
| Uint32Array
|
|
41
|
+
| BigUint64Array;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The index maps an op that prunes/renumbers points and cells returns when
|
|
45
|
+
* called with `returnMaps: true`, alongside its `mesh`: `pointMap` is input
|
|
46
|
+
* point index -> output point index (-1 if pruned), `cellMaps` is one array
|
|
47
|
+
* per **input** cell block, input cell -> output index within the
|
|
48
|
+
* corresponding output block (-1 if dropped). See doc/wasm.md's "Index maps"
|
|
49
|
+
* section for the per-op semantics (e.g. what a collapsed/welded point's
|
|
50
|
+
* -1-or-survivor value means).
|
|
51
|
+
*/
|
|
52
|
+
export interface PointCellMaps {
|
|
53
|
+
pointMap: Int32Array;
|
|
54
|
+
cellMaps: Int32Array[];
|
|
55
|
+
}
|
|
56
|
+
|
|
10
57
|
export interface RectangularCellBlock {
|
|
11
58
|
/** meshio++ cell type name, e.g. "triangle", "tetra10", "hexahedron". */
|
|
12
59
|
type: string;
|
|
@@ -37,10 +84,11 @@ export interface PolygonCellBlock {
|
|
|
37
84
|
* start index into the face list (length numCells + 1, so cell `c`'s faces
|
|
38
85
|
* are `faceOffsets[cellOffsets[c]] .. faceOffsets[cellOffsets[c + 1]]`).
|
|
39
86
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
87
|
+
* `writeMesh` accepts a polyhedron block for the formats that can hold one
|
|
88
|
+
* (`vtu`, `ensight` nfaced, `cgns` NFACE_n, `med` POE, `openfoam`); a format
|
|
89
|
+
* that cannot (legacy `vtk`, `vtp`, ...) throws naming the format. The shape
|
|
90
|
+
* also crosses the JS boundary unchanged through operations such as
|
|
91
|
+
* {@link MeshioPlusPlusModule.clean}.
|
|
44
92
|
*/
|
|
45
93
|
export interface PolyhedronCellBlock {
|
|
46
94
|
type: string;
|
|
@@ -68,9 +116,10 @@ export interface Mesh {
|
|
|
68
116
|
/**
|
|
69
117
|
* name -> flat, row-major per-point data. A multi-component (vector/tensor)
|
|
70
118
|
* array is stored interleaved, `numPoints * components` long, with its width
|
|
71
|
-
* declared in {@link Mesh.point_data_components}.
|
|
119
|
+
* declared in {@link Mesh.point_data_components}. Each array's JS type is
|
|
120
|
+
* its source dtype (see {@link DataArray}), not always `Float64Array`.
|
|
72
121
|
*/
|
|
73
|
-
point_data?: Record<string,
|
|
122
|
+
point_data?: Record<string, DataArray>;
|
|
74
123
|
/**
|
|
75
124
|
* Per-entity width of any `point_data` array that is not a scalar, since a
|
|
76
125
|
* flat typed array carries no shape. A name absent here has one component.
|
|
@@ -78,8 +127,13 @@ export interface Mesh {
|
|
|
78
127
|
* scalar-only mesh gets an empty object.
|
|
79
128
|
*/
|
|
80
129
|
point_data_components?: Record<string, number>;
|
|
81
|
-
/**
|
|
82
|
-
|
|
130
|
+
/**
|
|
131
|
+
* name -> one flat array per cell block, same order as `cells`. Every
|
|
132
|
+
* block of one named array shares the same {@link DataArray} class --
|
|
133
|
+
* `writeMesh`/`convert`-side callers that mix classes across blocks of the
|
|
134
|
+
* same name get a thrown Error naming the array.
|
|
135
|
+
*/
|
|
136
|
+
cell_data?: Record<string, DataArray[]>;
|
|
83
137
|
/**
|
|
84
138
|
* Per-entity width of any `cell_data` array that is not a scalar. One value
|
|
85
139
|
* per *array*, not per block: every block of a named cell_data array must
|
|
@@ -87,11 +141,141 @@ export interface Mesh {
|
|
|
87
141
|
*/
|
|
88
142
|
cell_data_components?: Record<string, number>;
|
|
89
143
|
/** name -> scalar/small metadata arrays (e.g. material ids). */
|
|
90
|
-
field_data?: Record<string,
|
|
144
|
+
field_data?: Record<string, DataArray>;
|
|
91
145
|
/** Per-entity width of any `field_data` array that is not a scalar. */
|
|
92
146
|
field_data_components?: Record<string, number>;
|
|
93
147
|
/** Named groups of points / cells / cell facets (see {@link Region}). */
|
|
94
148
|
regions?: Region[];
|
|
149
|
+
/** `Begin Properties` blocks -- Kratos material data (currently MDPA only). See {@link PropertySet}. */
|
|
150
|
+
propertySets?: PropertySet[];
|
|
151
|
+
/**
|
|
152
|
+
* Format-specific side-channel metadata a generic `Mesh` cannot represent,
|
|
153
|
+
* attached by `readMeshSelective(path, {info: true})`. Present only for
|
|
154
|
+
* formats with one (openfoam/med/mdpa/ansysinp/unv/gmsh/exodus); absent
|
|
155
|
+
* otherwise, even when `info: true` was requested. Its own `format` field
|
|
156
|
+
* is what `writeMesh` checks before reusing it on a write with no explicit
|
|
157
|
+
* `options.info`. See doc/wasm.md's "Side channel (info)" section.
|
|
158
|
+
*/
|
|
159
|
+
info?: MeshInfo;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** The union of every format's side-channel `info` shape. Discriminate on `format`. */
|
|
163
|
+
export type MeshInfo =
|
|
164
|
+
| OpenFoamInfo
|
|
165
|
+
| MedInfo
|
|
166
|
+
| MdpaInfo
|
|
167
|
+
| AnsysInfo
|
|
168
|
+
| UnvInfo
|
|
169
|
+
| GmshInfo
|
|
170
|
+
| ExodusInfo;
|
|
171
|
+
|
|
172
|
+
/** OpenFOAM's side channel: `readMeshSelective`'s cell_tags/patch-type map, reshaped per patch. */
|
|
173
|
+
export interface OpenFoamInfo {
|
|
174
|
+
format: 'openfoam';
|
|
175
|
+
patches: Array<{
|
|
176
|
+
/** The negative, MED-style family id `cell_tags` uses for this patch. */
|
|
177
|
+
familyId: number;
|
|
178
|
+
/** Names this family id is known by (usually one; more than one on a collision). */
|
|
179
|
+
names: string[];
|
|
180
|
+
/** The patch `type` (`patch`/`wall`/`symmetry`/...), when known. */
|
|
181
|
+
type?: string;
|
|
182
|
+
}>;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** MED's side channel: family/group names, units, and per-field step/time metadata. */
|
|
186
|
+
export interface MedInfo {
|
|
187
|
+
format: 'med';
|
|
188
|
+
/** Point family id -> subset name(s), as `point_tags`/`cell_tags` key them. */
|
|
189
|
+
pointTags: Record<string, string[]>;
|
|
190
|
+
cellTags: Record<string, string[]>;
|
|
191
|
+
meshName: string;
|
|
192
|
+
description: string;
|
|
193
|
+
unitTime: string;
|
|
194
|
+
unitCoords: string;
|
|
195
|
+
/** Family id -> its `FAM_<id>...` group link name. */
|
|
196
|
+
pointTagGroups: Record<string, string>;
|
|
197
|
+
cellTagGroups: Record<string, string>;
|
|
198
|
+
/** Lenient-mode only: constructs this read could not represent, verbatim. */
|
|
199
|
+
skippedConstructs: string[];
|
|
200
|
+
/** Lenient-mode only: field name -> `[UNI, UNT]` unit strings. */
|
|
201
|
+
fieldUnits: Record<string, [string, string]>;
|
|
202
|
+
/** Lenient-mode only: field name -> `{ndt, nor, pdt}` (MED's own step/order/time triple). */
|
|
203
|
+
stepMeta: Record<string, { ndt: number; nor: number; pdt: number }>;
|
|
204
|
+
/** Field name -> every step's time value (always filled, not lenient-only). */
|
|
205
|
+
fieldTimeValues: Record<string, number[]>;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** MDPA's side channel: per-block entity names. Properties ride on `mesh.propertySets` instead (see {@link PropertySet}), not here. */
|
|
209
|
+
export interface MdpaInfo {
|
|
210
|
+
format: 'mdpa';
|
|
211
|
+
/** One entry per cell block, mesh block order. */
|
|
212
|
+
entityNames: Array<{ name: string; isCondition: boolean }>;
|
|
213
|
+
/** Lenient-mode only: constructs this read could not represent, verbatim. */
|
|
214
|
+
skippedConstructs: string[];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* The shared shape of Ansys (`.cdb`/`.inp`, MAPDL) and UNV's side channel:
|
|
219
|
+
* named point/cell sets the generic {@link Region} shape does not carry.
|
|
220
|
+
*/
|
|
221
|
+
export interface AnsysUnvInfoShape {
|
|
222
|
+
/** Set name -> 0-based point/node indices. */
|
|
223
|
+
pointSets: Record<string, number[]>;
|
|
224
|
+
/** Set name -> one array of 0-based local indices per cell block. */
|
|
225
|
+
cellSets: Record<string, number[][]>;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export interface AnsysInfo extends AnsysUnvInfoShape {
|
|
229
|
+
format: 'ansysinp';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export interface UnvInfo extends AnsysUnvInfoShape {
|
|
233
|
+
format: 'unv';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Gmsh's side channel: `$Entities` bounding-entity tags, one array per cell block. */
|
|
237
|
+
export interface GmshInfo {
|
|
238
|
+
format: 'gmsh';
|
|
239
|
+
boundingEntities: number[][];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** Exodus's side channel: info/QA records. Read-only -- there is no Info-bearing Exodus writer. */
|
|
243
|
+
export interface ExodusInfo {
|
|
244
|
+
format: 'exodus';
|
|
245
|
+
infoRecords: string[];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* One `Begin Properties <id>` block: an id plus its entries, in file order.
|
|
250
|
+
* Carried on the {@link Mesh} object itself (like {@link Region}), keyed by
|
|
251
|
+
* id rather than entity index, so operations that renumber cells/points
|
|
252
|
+
* cannot invalidate them. Shape-preserving operations (`clean`, `smooth`,
|
|
253
|
+
* `transform`, `attachQuality`, the `data*` ops) carry them through;
|
|
254
|
+
* restructuring and multi-input ones (`merge`, `cropBbox`/`cropPlane`/
|
|
255
|
+
* `cropPredicate`, `split`, `partition`, `diff`) do not.
|
|
256
|
+
*/
|
|
257
|
+
export interface PropertySet {
|
|
258
|
+
id: number;
|
|
259
|
+
values: PropertyValue[];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* One `KEY value` entry of a properties block. Exactly one of `values` and
|
|
264
|
+
* `text` carries the value: a plain number is a one-element `values`; an
|
|
265
|
+
* inline `Begin Table` is an `(n, k)` `values` (flat, row-major -- `k` given
|
|
266
|
+
* by `components` when `k > 1`) with `isTable` set and `key` holding the
|
|
267
|
+
* table header's arguments verbatim; anything else (a constitutive-law name,
|
|
268
|
+
* a bracketed vector/matrix) is kept verbatim in `text`, which is what makes
|
|
269
|
+
* an unrecognized value lossless.
|
|
270
|
+
*/
|
|
271
|
+
export interface PropertyValue {
|
|
272
|
+
key: string;
|
|
273
|
+
values: Float64Array;
|
|
274
|
+
/** Per-entity width of `values` when `isTable` and `k > 1`. Absent means 1. */
|
|
275
|
+
components?: number;
|
|
276
|
+
/** The value verbatim, when it is not numeric (`values` is then empty). */
|
|
277
|
+
text: string;
|
|
278
|
+
isTable: boolean;
|
|
95
279
|
}
|
|
96
280
|
|
|
97
281
|
/**
|
|
@@ -137,7 +321,34 @@ export interface RegionSummary {
|
|
|
137
321
|
numEntries: number;
|
|
138
322
|
}
|
|
139
323
|
|
|
140
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Parameterized-write options for `writeMesh`/`convert`, all optional --
|
|
326
|
+
* unset/empty reproduces the exact write from before v11.2.0. There is
|
|
327
|
+
* deliberately no gzip level or VTK 4.2/5.1 selector: neither exists as a
|
|
328
|
+
* `WriteOptions` field on the C++ side (gzip level 4 is a fixed registry
|
|
329
|
+
* default; `vtk42`/`vtk51` are separate format keys, not a `vtk` option).
|
|
330
|
+
*/
|
|
331
|
+
export interface MeshWriteOptions {
|
|
332
|
+
/** ASCII vs binary. Errors for a format with only one variant. */
|
|
333
|
+
encoding?: "ascii" | "binary";
|
|
334
|
+
/** Block-compression codec, for the VTK-XML formats (vtu/vtp) only. */
|
|
335
|
+
codec?: "none" | "zlib" | "lz4" | "zstd";
|
|
336
|
+
/** `printf`-style float format for ASCII writers that take one (e.g. `".16e"`, the default). */
|
|
337
|
+
floatFormat?: string;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* `writeMesh`'s own options: `MeshWriteOptions` plus `info`, a format's
|
|
342
|
+
* side-channel metadata to write (see {@link MeshInfo}) -- wins over a
|
|
343
|
+
* `mesh.info` whose own `format` matches this write's. Given for a format
|
|
344
|
+
* with no side-channel writer (openfoam/mdpa/ansysinp/unv/gmsh/med are the
|
|
345
|
+
* writable ones; exodus is read-only) throws naming it.
|
|
346
|
+
*/
|
|
347
|
+
export interface MeshWriteOptionsWithInfo extends MeshWriteOptions {
|
|
348
|
+
info?: MeshInfo;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export interface ConvertOptions extends MeshWriteOptions {
|
|
141
352
|
/** Explicit input format key, or omit to infer from inPath's extension. */
|
|
142
353
|
inFormat?: string;
|
|
143
354
|
/** Explicit output format key, or omit to infer from outPath's extension. */
|
|
@@ -667,13 +878,16 @@ export interface XdmfTimeSeriesWriter {
|
|
|
667
878
|
* Append one step from raw arrays instead of a mesh -- the granularity a
|
|
668
879
|
* solver has once `writePointsCells` has fixed the geometry. Arrays are
|
|
669
880
|
* emitted in key order; `components` gives the per-entity width of any array
|
|
670
|
-
* that is not a scalar, since a flat typed array carries no shape.
|
|
881
|
+
* that is not a scalar, since a flat typed array carries no shape. A
|
|
882
|
+
* `BigInt64Array`/`BigUint64Array` value (e.g. taken from a mesh's
|
|
883
|
+
* `cell_data` unchanged) is widened to `number`s internally -- the XDMF
|
|
884
|
+
* data path is double-precision regardless of the source dtype.
|
|
671
885
|
* @throws {Error} if an array's length does not match the static grid.
|
|
672
886
|
*/
|
|
673
887
|
writeDataArrays(
|
|
674
888
|
time: number,
|
|
675
|
-
pointData: Record<string,
|
|
676
|
-
cellData?: Record<string,
|
|
889
|
+
pointData: Record<string, DataArray | number[]>,
|
|
890
|
+
cellData?: Record<string, DataArray | number[]>,
|
|
677
891
|
components?: Record<string, number>
|
|
678
892
|
): void;
|
|
679
893
|
|
|
@@ -706,6 +920,41 @@ export interface XdmfTimeSeriesWriter {
|
|
|
706
920
|
close(): void;
|
|
707
921
|
}
|
|
708
922
|
|
|
923
|
+
/** One entry of a sequence plan: one step of one file. See {@link MeshioPlusPlusModule.sequenceEntries} and {@link SequenceReader}. */
|
|
924
|
+
export interface SequenceEntry {
|
|
925
|
+
path: string;
|
|
926
|
+
step: number;
|
|
927
|
+
time: number;
|
|
928
|
+
timeSource: 'explicit' | 'file' | 'filename' | 'index';
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* A stateful sequence reader, opened by {@link MeshioPlusPlusModule.openSequence}.
|
|
933
|
+
* Plans the sequence once (no heavy data read) and reads one step's mesh at a
|
|
934
|
+
* time -- at most one mesh alive, whatever the step count. See
|
|
935
|
+
* `doc/sequences.md`.
|
|
936
|
+
*/
|
|
937
|
+
export interface SequenceReader {
|
|
938
|
+
/** How many entries this sequence has. */
|
|
939
|
+
count: number;
|
|
940
|
+
path(i: number): string;
|
|
941
|
+
step(i: number): number;
|
|
942
|
+
time(i: number): number;
|
|
943
|
+
timeSource(i: number): 'explicit' | 'file' | 'filename' | 'index';
|
|
944
|
+
entry(i: number): SequenceEntry;
|
|
945
|
+
entries(): SequenceEntry[];
|
|
946
|
+
/**
|
|
947
|
+
* Read entry `i`'s mesh. `pointsOnly`/`arrays`/`lenient` are `readMeshSelective`'s.
|
|
948
|
+
* @throws {Error} if `i` is out of `[0, count)`.
|
|
949
|
+
*/
|
|
950
|
+
read(
|
|
951
|
+
i: number,
|
|
952
|
+
options?: { pointsOnly?: boolean; arrays?: string[] | null; lenient?: boolean },
|
|
953
|
+
): Mesh;
|
|
954
|
+
/** Release the handle. Safe to call twice; after this every other method throws. */
|
|
955
|
+
close(): void;
|
|
956
|
+
}
|
|
957
|
+
|
|
709
958
|
/**
|
|
710
959
|
* The instantiated module returned by `loadMeshioPlusPlus()`. `FS` is
|
|
711
960
|
* Emscripten's virtual filesystem (MEMFS by default) -- write the bytes of a
|
|
@@ -751,6 +1000,13 @@ export interface MeshioPlusPlusModule {
|
|
|
751
1000
|
* truncated block or a bad node reference still throws, because continuing
|
|
752
1001
|
* past those would return a mesh that is quietly wrong.
|
|
753
1002
|
*
|
|
1003
|
+
* `info: true` attaches the format's side channel as the result's `.info`
|
|
1004
|
+
* (see {@link MeshInfo}) for the formats that have one
|
|
1005
|
+
* (openfoam/med/mdpa/ansysinp/unv/gmsh/exodus); silently has no effect for
|
|
1006
|
+
* any other format, so a caller can always pass it and check `.info`
|
|
1007
|
+
* itself. `pointsOnly`/`arrays` reach the read only for the formats whose
|
|
1008
|
+
* info-bearing reader takes selective-read options (med/mdpa/gmsh/exodus).
|
|
1009
|
+
*
|
|
754
1010
|
* @throws {Error} on an out-of-range `timeStep`.
|
|
755
1011
|
*/
|
|
756
1012
|
readMeshSelective(
|
|
@@ -761,6 +1017,7 @@ export interface MeshioPlusPlusModule {
|
|
|
761
1017
|
arrays?: string[] | null;
|
|
762
1018
|
timeStep?: number;
|
|
763
1019
|
lenient?: boolean;
|
|
1020
|
+
info?: boolean;
|
|
764
1021
|
}
|
|
765
1022
|
): Mesh;
|
|
766
1023
|
|
|
@@ -778,18 +1035,26 @@ export interface MeshioPlusPlusModule {
|
|
|
778
1035
|
readerSupportsOptions(format: string): boolean;
|
|
779
1036
|
|
|
780
1037
|
/**
|
|
781
|
-
* Write a mesh to the virtual filesystem.
|
|
782
|
-
*
|
|
783
|
-
*
|
|
784
|
-
*
|
|
1038
|
+
* Write a mesh to the virtual filesystem. See {@link MeshWriteOptionsWithInfo.info}
|
|
1039
|
+
* for writing a format's side channel.
|
|
1040
|
+
* @returns every virtual-FS path this write touched (new or changed),
|
|
1041
|
+
* sorted -- more than one for a multi-file writer (`.xdmf` + its `.h5`
|
|
1042
|
+
* companion, an OpenFOAM `polyMesh` directory's files, ...).
|
|
1043
|
+
* @throws {Error} on an unknown/write-unsupported format, an `options`
|
|
1044
|
+
* field the format cannot honour, `info` given for a format with no
|
|
1045
|
+
* side-channel writer, or malformed input (e.g. a points/connectivity
|
|
1046
|
+
* array length not divisible by its declared dim/nodesPerCell).
|
|
785
1047
|
*/
|
|
786
|
-
writeMesh(
|
|
1048
|
+
writeMesh(
|
|
1049
|
+
path: string, mesh: Mesh, format?: string, options?: MeshWriteOptionsWithInfo
|
|
1050
|
+
): string[];
|
|
787
1051
|
|
|
788
1052
|
/**
|
|
789
1053
|
* Read `inPath` and write it to `outPath` directly (no intermediate JS
|
|
790
1054
|
* mesh object). Mirrors the CLI's `convert` subcommand.
|
|
1055
|
+
* @returns every virtual-FS path the write touched (new or changed), sorted.
|
|
791
1056
|
*/
|
|
792
|
-
convert(inPath: string, outPath: string, options?: ConvertOptions):
|
|
1057
|
+
convert(inPath: string, outPath: string, options?: ConvertOptions): string[];
|
|
793
1058
|
|
|
794
1059
|
/**
|
|
795
1060
|
* Like {@link convert}, but writes a *renderable surface*: a mesh with
|
|
@@ -885,12 +1150,24 @@ export interface MeshioPlusPlusModule {
|
|
|
885
1150
|
timeFrom?: 'auto' | 'file' | 'filename' | 'index';
|
|
886
1151
|
sort?: boolean;
|
|
887
1152
|
},
|
|
888
|
-
):
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
1153
|
+
): SequenceEntry[];
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Open a **stateful** sequence reader: plans the sequence once (`source`/
|
|
1157
|
+
* `options` exactly as {@link sequenceEntries}), then lets you read one
|
|
1158
|
+
* step's mesh at a time via {@link SequenceReader.read} without holding
|
|
1159
|
+
* more than one mesh alive -- the lazy-read counterpart to
|
|
1160
|
+
* `sequenceEntries` + `readMesh` in a loop.
|
|
1161
|
+
*/
|
|
1162
|
+
openSequence(
|
|
1163
|
+
source: string | string[],
|
|
1164
|
+
options?: {
|
|
1165
|
+
format?: string;
|
|
1166
|
+
times?: number[];
|
|
1167
|
+
timeFrom?: 'auto' | 'file' | 'filename' | 'index';
|
|
1168
|
+
sort?: boolean;
|
|
1169
|
+
},
|
|
1170
|
+
): SequenceReader;
|
|
894
1171
|
|
|
895
1172
|
/**
|
|
896
1173
|
* **Fan-in**: write every step of `source` into one multi-step file.
|
|
@@ -997,7 +1274,13 @@ export interface MeshioPlusPlusModule {
|
|
|
997
1274
|
/** Whether two meshes are equal within tolerance. */
|
|
998
1275
|
meshesEqual(a: Mesh, b: Mesh, atol?: number, rtol?: number, unordered?: boolean): boolean;
|
|
999
1276
|
|
|
1000
|
-
/**
|
|
1277
|
+
/**
|
|
1278
|
+
* Combine several meshes into one, optionally welding coincident points.
|
|
1279
|
+
* With `returnMaps: true`, also returns `pointMaps`/`cellMaps`: one array
|
|
1280
|
+
* per INPUT MESH (not per input block, unlike every other op's maps), each
|
|
1281
|
+
* input's local point/cell index -> the output index (cellMaps: -1 if
|
|
1282
|
+
* dropped as a duplicate).
|
|
1283
|
+
*/
|
|
1001
1284
|
merge(
|
|
1002
1285
|
meshes: Mesh[],
|
|
1003
1286
|
weld?: boolean,
|
|
@@ -1005,12 +1288,23 @@ export interface MeshioPlusPlusModule {
|
|
|
1005
1288
|
sourceTag?: boolean,
|
|
1006
1289
|
dataPolicy?: MergeDataPolicy,
|
|
1007
1290
|
dropDuplicateCells?: boolean,
|
|
1291
|
+
returnMaps?: false,
|
|
1008
1292
|
): Mesh;
|
|
1293
|
+
merge(
|
|
1294
|
+
meshes: Mesh[],
|
|
1295
|
+
weld?: boolean,
|
|
1296
|
+
atol?: number,
|
|
1297
|
+
sourceTag?: boolean,
|
|
1298
|
+
dataPolicy?: MergeDataPolicy,
|
|
1299
|
+
dropDuplicateCells?: boolean,
|
|
1300
|
+
returnMaps?: true,
|
|
1301
|
+
): { mesh: Mesh; pointMaps: Int32Array[]; cellMaps: Int32Array[] };
|
|
1009
1302
|
|
|
1010
1303
|
/** Apply a row-major 4x4 affine transform to the point coordinates. */
|
|
1011
1304
|
transform(mesh: Mesh, matrix: number[], rotateVectorData?: boolean): Mesh;
|
|
1012
1305
|
|
|
1013
|
-
/** Weld / prune / de-duplicate in one pass.
|
|
1306
|
+
/** Weld / prune / de-duplicate in one pass. With `returnMaps: true`, the
|
|
1307
|
+
* result also carries `pointMap`/`cellMaps` (see {@link PointCellMaps}). */
|
|
1014
1308
|
clean(
|
|
1015
1309
|
mesh: Mesh,
|
|
1016
1310
|
weld?: boolean,
|
|
@@ -1018,12 +1312,15 @@ export interface MeshioPlusPlusModule {
|
|
|
1018
1312
|
removeOrphans?: boolean,
|
|
1019
1313
|
dropDegenerate?: boolean,
|
|
1020
1314
|
dropDuplicateCells?: boolean,
|
|
1315
|
+
returnMaps?: boolean,
|
|
1021
1316
|
): {
|
|
1022
1317
|
mesh: Mesh;
|
|
1023
1318
|
pointsWelded: number;
|
|
1024
1319
|
pointsRemovedOrphan: number;
|
|
1025
1320
|
cellsDroppedDegenerate: number;
|
|
1026
1321
|
cellsDroppedDuplicate: number;
|
|
1322
|
+
pointMap?: Int32Array;
|
|
1323
|
+
cellMaps?: Int32Array[];
|
|
1027
1324
|
};
|
|
1028
1325
|
|
|
1029
1326
|
/**
|
|
@@ -1033,9 +1330,12 @@ export interface MeshioPlusPlusModule {
|
|
|
1033
1330
|
* `"laplacian"` is stronger per pass but contracts the mesh. A **negative**
|
|
1034
1331
|
* `lambda` means "this method's own default" (0.5 Laplacian, 0.33 Taubin).
|
|
1035
1332
|
* Boundary and feature nodes are pinned by default, and `guardInversion`
|
|
1036
|
-
* rejects any move that would flip an incident cell.
|
|
1333
|
+
* rejects any move that would flip an incident cell. `frozen` is an
|
|
1334
|
+
* optional array of 0-based point ids to pin outright, unioned with any
|
|
1335
|
+
* boundary/feature pins.
|
|
1037
1336
|
* @throws {Error} on an unknown `method`, a non-negative `lambda` outside
|
|
1038
|
-
* `(0, 1)`,
|
|
1337
|
+
* `(0, 1)`, a `"taubin"` `mu` that does not satisfy `mu < -lambda < 0`, or
|
|
1338
|
+
* a `frozen` id outside `[0, numPoints)`.
|
|
1039
1339
|
*/
|
|
1040
1340
|
smooth(
|
|
1041
1341
|
mesh: Mesh,
|
|
@@ -1047,6 +1347,7 @@ export interface MeshioPlusPlusModule {
|
|
|
1047
1347
|
preserveFeatures?: boolean,
|
|
1048
1348
|
featureAngle?: number,
|
|
1049
1349
|
guardInversion?: boolean,
|
|
1350
|
+
frozen?: number[] | Int32Array | null,
|
|
1050
1351
|
): { mesh: Mesh; numNodesMoved: number; maxDisplacement: number; numSkippedInversion: number };
|
|
1051
1352
|
|
|
1052
1353
|
/**
|
|
@@ -1114,17 +1415,37 @@ export interface MeshioPlusPlusModule {
|
|
|
1114
1415
|
fine: Mesh,
|
|
1115
1416
|
): { mesh: Mesh; numGroupsUndone: number; numCellsRemoved: number };
|
|
1116
1417
|
|
|
1117
|
-
/** Subset a mesh to an axis-aligned bounding box.
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1418
|
+
/** Subset a mesh to an axis-aligned bounding box. With `returnMaps: true`,
|
|
1419
|
+
* returns `{mesh, pointMap, cellMaps}` (see {@link PointCellMaps}) instead
|
|
1420
|
+
* of a bare mesh. */
|
|
1421
|
+
cropBbox(
|
|
1422
|
+
mesh: Mesh, lo: number[], hi: number[], mode?: CropMode, recordIds?: boolean,
|
|
1423
|
+
returnMaps?: false,
|
|
1424
|
+
): Mesh;
|
|
1425
|
+
cropBbox(
|
|
1426
|
+
mesh: Mesh, lo: number[], hi: number[], mode?: CropMode, recordIds?: boolean,
|
|
1427
|
+
returnMaps?: true,
|
|
1428
|
+
): { mesh: Mesh } & PointCellMaps;
|
|
1429
|
+
|
|
1430
|
+
/** Subset a mesh to the half-space `(p - point) . normal >= 0`. With
|
|
1431
|
+
* `returnMaps: true`, returns `{mesh, pointMap, cellMaps}` instead of a
|
|
1432
|
+
* bare mesh. */
|
|
1121
1433
|
cropPlane(
|
|
1122
1434
|
mesh: Mesh,
|
|
1123
1435
|
point: number[],
|
|
1124
1436
|
normal: number[],
|
|
1125
1437
|
mode?: CropMode,
|
|
1126
1438
|
recordIds?: boolean,
|
|
1439
|
+
returnMaps?: false,
|
|
1127
1440
|
): Mesh;
|
|
1441
|
+
cropPlane(
|
|
1442
|
+
mesh: Mesh,
|
|
1443
|
+
point: number[],
|
|
1444
|
+
normal: number[],
|
|
1445
|
+
mode?: CropMode,
|
|
1446
|
+
recordIds?: boolean,
|
|
1447
|
+
returnMaps?: true,
|
|
1448
|
+
): { mesh: Mesh } & PointCellMaps;
|
|
1128
1449
|
|
|
1129
1450
|
/**
|
|
1130
1451
|
* Subset a mesh to the cells whose value in a scalar `cell_data` array
|
|
@@ -1145,6 +1466,9 @@ export interface MeshioPlusPlusModule {
|
|
|
1145
1466
|
* @throws {Error} when `array` is not a scalar `cell_data` array covering
|
|
1146
1467
|
* every block, or the comparison is not one of `<`, `<=`, `>`, `>=`, `==`,
|
|
1147
1468
|
* `!=`.
|
|
1469
|
+
*
|
|
1470
|
+
* With `returnMaps: true`, returns `{mesh, pointMap, cellMaps}` instead of
|
|
1471
|
+
* a bare mesh.
|
|
1148
1472
|
*/
|
|
1149
1473
|
cropPredicate(
|
|
1150
1474
|
mesh: Mesh,
|
|
@@ -1152,7 +1476,16 @@ export interface MeshioPlusPlusModule {
|
|
|
1152
1476
|
compare?: CropCompare,
|
|
1153
1477
|
value?: number,
|
|
1154
1478
|
recordIds?: boolean,
|
|
1479
|
+
returnMaps?: false,
|
|
1155
1480
|
): Mesh;
|
|
1481
|
+
cropPredicate(
|
|
1482
|
+
mesh: Mesh,
|
|
1483
|
+
array: string,
|
|
1484
|
+
compare?: CropCompare,
|
|
1485
|
+
value?: number,
|
|
1486
|
+
recordIds?: boolean,
|
|
1487
|
+
returnMaps?: true,
|
|
1488
|
+
): { mesh: Mesh } & PointCellMaps;
|
|
1156
1489
|
|
|
1157
1490
|
/**
|
|
1158
1491
|
* Planar cross-section of a mesh (marching tetrahedra on a simplexified
|
|
@@ -1527,8 +1860,143 @@ export interface MeshioPlusPlusModule {
|
|
|
1527
1860
|
minQualityAfter: number;
|
|
1528
1861
|
};
|
|
1529
1862
|
|
|
1530
|
-
/**
|
|
1531
|
-
|
|
1863
|
+
/**
|
|
1864
|
+
* Per-vertex mean (H) and Gaussian (K) curvature of a surface mesh -- the
|
|
1865
|
+
* signed distance's natural companion as a node feature. K is the angle
|
|
1866
|
+
* defect, H the cotangent Laplace-Beltrami operator. Writes
|
|
1867
|
+
* `curvature:mean`/`curvature:gaussian` point data, optionally
|
|
1868
|
+
* `curvature:area` and `curvature:principal`. `totalAngleDefect` is the
|
|
1869
|
+
* Gauss-Bonnet oracle: `2*pi*chi` exactly for a CLOSED surface (`4*pi` for
|
|
1870
|
+
* anything sphere-like), whatever the tessellation and whichever
|
|
1871
|
+
* `dualArea`. H's sign is orientation-dependent and K's is not, so check
|
|
1872
|
+
* `quality.inconsistentPairs` before trusting a sign. Never repairs its
|
|
1873
|
+
* input. See doc/curvature.md.
|
|
1874
|
+
* @throws {Error} on a non-surface input or an unknown region.
|
|
1875
|
+
*/
|
|
1876
|
+
computeCurvature(
|
|
1877
|
+
mesh: Mesh,
|
|
1878
|
+
mean?: boolean,
|
|
1879
|
+
gaussian?: boolean,
|
|
1880
|
+
dualArea?: 'mixed-voronoi' | 'barycentric',
|
|
1881
|
+
includeBoundary?: boolean,
|
|
1882
|
+
recordArea?: boolean,
|
|
1883
|
+
recordPrincipal?: boolean,
|
|
1884
|
+
region?: string,
|
|
1885
|
+
): {
|
|
1886
|
+
mesh: Mesh;
|
|
1887
|
+
numBoundary: number;
|
|
1888
|
+
numIsolated: number;
|
|
1889
|
+
numDegenerate: number;
|
|
1890
|
+
totalAngleDefect: number;
|
|
1891
|
+
quality: {
|
|
1892
|
+
boundaryEdges: number;
|
|
1893
|
+
nonManifoldEdges: number;
|
|
1894
|
+
inconsistentPairs: number;
|
|
1895
|
+
degenerateTriangles: number;
|
|
1896
|
+
watertight: boolean;
|
|
1897
|
+
};
|
|
1898
|
+
};
|
|
1899
|
+
|
|
1900
|
+
/**
|
|
1901
|
+
* Surface repair beyond `clean`: weld (opt-in) -> triangulate -> split
|
|
1902
|
+
* bowties -> orient by the topological half-edge rule per connected
|
|
1903
|
+
* component -> fan-fill boundary loops of at most `maxHoleEdges` edges,
|
|
1904
|
+
* wound to agree with the surrounding surface -> orient closed components
|
|
1905
|
+
* outward. Lower-dimensional blocks ride along; fill triangles land in one
|
|
1906
|
+
* trailing `triangle` block. Non-manifold EDGES are counted, never split.
|
|
1907
|
+
* See doc/repair.md.
|
|
1908
|
+
* @throws {Error} on a volume or higher-order input (naming the fix).
|
|
1909
|
+
*/
|
|
1910
|
+
repair(
|
|
1911
|
+
mesh: Mesh,
|
|
1912
|
+
fixOrientation?: boolean,
|
|
1913
|
+
orientOutward?: boolean,
|
|
1914
|
+
fillHoles?: boolean,
|
|
1915
|
+
splitNonManifold?: boolean,
|
|
1916
|
+
maxHoleEdges?: number,
|
|
1917
|
+
weldTolerance?: number,
|
|
1918
|
+
recordProvenance?: boolean,
|
|
1919
|
+
): {
|
|
1920
|
+
mesh: Mesh;
|
|
1921
|
+
qualityBefore: SurfaceQualityInfo;
|
|
1922
|
+
qualityAfter: SurfaceQualityInfo;
|
|
1923
|
+
numFlipped: number;
|
|
1924
|
+
numComponents: number;
|
|
1925
|
+
largestComponent: number;
|
|
1926
|
+
numOrientedOutward: number;
|
|
1927
|
+
numUnorientable: number;
|
|
1928
|
+
numVerticesSplit: number;
|
|
1929
|
+
numHolesDetected: number;
|
|
1930
|
+
numHolesFilled: number;
|
|
1931
|
+
numHolesSkipped: number;
|
|
1932
|
+
numFacesAdded: number;
|
|
1933
|
+
numPointsAdded: number;
|
|
1934
|
+
pointsWelded: number;
|
|
1935
|
+
};
|
|
1936
|
+
|
|
1937
|
+
/**
|
|
1938
|
+
* Project every (selected) point of `mesh` onto the surface of `target`:
|
|
1939
|
+
* `x' = x + w (p + offset n - x)`, one projection, no iteration. Every
|
|
1940
|
+
* point of the source moves whatever cells it carries; only the target must
|
|
1941
|
+
* be a surface. The offset goes along the hit FEATURE's pseudonormal (the
|
|
1942
|
+
* bisector at a crease), not the selected triangle's normal. `weights`
|
|
1943
|
+
* names a point-data array on the source. See doc/shrinkwrap.md.
|
|
1944
|
+
* @throws {Error} on an unusable target, region or weights array.
|
|
1945
|
+
*/
|
|
1946
|
+
shrinkwrap(
|
|
1947
|
+
mesh: Mesh,
|
|
1948
|
+
target: Mesh,
|
|
1949
|
+
offset?: number,
|
|
1950
|
+
maxDistance?: number,
|
|
1951
|
+
weights?: string,
|
|
1952
|
+
targetRegion?: string,
|
|
1953
|
+
normalWeight?: 'angle' | 'area',
|
|
1954
|
+
recordDistance?: boolean,
|
|
1955
|
+
recordClosestCell?: boolean,
|
|
1956
|
+
): {
|
|
1957
|
+
mesh: Mesh;
|
|
1958
|
+
quality: SurfaceQualityInfo;
|
|
1959
|
+
numProjected: number;
|
|
1960
|
+
numMissed: number;
|
|
1961
|
+
numSkipped: number;
|
|
1962
|
+
maxDisplacement: number;
|
|
1963
|
+
};
|
|
1964
|
+
|
|
1965
|
+
/**
|
|
1966
|
+
* Sobolev (Helmholtz-filtered) deformation: solve `(M + l^2 K) u = M d`
|
|
1967
|
+
* over the mesh's own P1 operators and move the points by `u` -- a
|
|
1968
|
+
* screened-Poisson low-pass filter of the raw displacement whose cutoff
|
|
1969
|
+
* wavelength is `lengthScale`. Every top-dimensional block must be a linear
|
|
1970
|
+
* simplex; lower-dimensional blocks ride along. Nothing is pinned by
|
|
1971
|
+
* default. Non-convergence sets `converged` false and returns the last
|
|
1972
|
+
* iterate. See doc/sobolev_deform.md.
|
|
1973
|
+
* @throws {Error} on a missing array or a non-simplex block (naming the fix).
|
|
1974
|
+
*/
|
|
1975
|
+
sobolevDeform(
|
|
1976
|
+
mesh: Mesh,
|
|
1977
|
+
array: string,
|
|
1978
|
+
lengthScale: number,
|
|
1979
|
+
fixedPointsArray?: string,
|
|
1980
|
+
fixBoundary?: boolean,
|
|
1981
|
+
recordFiltered?: boolean,
|
|
1982
|
+
maxIterations?: number,
|
|
1983
|
+
tolerance?: number,
|
|
1984
|
+
): {
|
|
1985
|
+
mesh: Mesh;
|
|
1986
|
+
numIterations: number;
|
|
1987
|
+
residual: number;
|
|
1988
|
+
converged: boolean;
|
|
1989
|
+
numFixed: number;
|
|
1990
|
+
numIsolated: number;
|
|
1991
|
+
maxDisplacement: number;
|
|
1992
|
+
};
|
|
1993
|
+
|
|
1994
|
+
/** Partition a mesh into submeshes by type, connected component, or tag.
|
|
1995
|
+
* With `returnMaps: true`, each piece also carries `pointMap`/`cellMaps`
|
|
1996
|
+
* (see {@link PointCellMaps}). */
|
|
1997
|
+
split(
|
|
1998
|
+
mesh: Mesh, by: SplitBy, tagName?: string, returnMaps?: boolean,
|
|
1999
|
+
): ({ key: string; mesh: Mesh } & Partial<PointCellMaps>)[];
|
|
1532
2000
|
|
|
1533
2001
|
/**
|
|
1534
2002
|
* Convert the element representation: drop higher-order nodes
|
|
@@ -1536,8 +2004,16 @@ export interface MeshioPlusPlusModule {
|
|
|
1536
2004
|
* or promote linear cells to serendipity quadratic (`"elevate"`).
|
|
1537
2005
|
* @throws {Error} on a polyhedron block under `"simplexify"`, or a
|
|
1538
2006
|
* full-Lagrange target (quad9/hexahedron27) under `"elevate"`.
|
|
2007
|
+
*
|
|
2008
|
+
* With `returnMaps: true`, returns `{mesh, pointMap, cellMaps}` instead of
|
|
2009
|
+
* a bare mesh.
|
|
1539
2010
|
*/
|
|
1540
|
-
convertCells(
|
|
2011
|
+
convertCells(
|
|
2012
|
+
mesh: Mesh, mode?: ConvertCellsMode, recordParentIds?: boolean, returnMaps?: false,
|
|
2013
|
+
): Mesh;
|
|
2014
|
+
convertCells(
|
|
2015
|
+
mesh: Mesh, mode?: ConvertCellsMode, recordParentIds?: boolean, returnMaps?: true,
|
|
2016
|
+
): { mesh: Mesh } & PointCellMaps;
|
|
1541
2017
|
|
|
1542
2018
|
/**
|
|
1543
2019
|
* Polyhedrally refine a mesh: one polyhedral child per face of every
|
|
@@ -1549,8 +2025,11 @@ export interface MeshioPlusPlusModule {
|
|
|
1549
2025
|
* `convertCells`, there is no point map -- subdivide never prunes or
|
|
1550
2026
|
* renumbers an original point.
|
|
1551
2027
|
* @throws {Error} when a cell's faces are not a closed orientable surface.
|
|
2028
|
+
*
|
|
2029
|
+
* With `returnMaps: true`, returns `{mesh, cellMaps}` instead of a bare mesh.
|
|
1552
2030
|
*/
|
|
1553
|
-
subdivide(mesh: Mesh, recordParentIds?: boolean): Mesh;
|
|
2031
|
+
subdivide(mesh: Mesh, recordParentIds?: boolean, returnMaps?: false): Mesh;
|
|
2032
|
+
subdivide(mesh: Mesh, recordParentIds?: boolean, returnMaps?: true): { mesh: Mesh; cellMaps: Int32Array[] };
|
|
1554
2033
|
|
|
1555
2034
|
/**
|
|
1556
2035
|
* Polyhedrally coarsen a mesh: merge groups of cells into single larger
|
|
@@ -1563,8 +2042,13 @@ export interface MeshioPlusPlusModule {
|
|
|
1563
2042
|
* for a minimal point set).
|
|
1564
2043
|
* @throws {Error} when targetGroupSize is 0, or the mesh contains a face
|
|
1565
2044
|
* shared by three or more cells (non-manifold).
|
|
2045
|
+
*
|
|
2046
|
+
* With `returnMaps: true`, returns `{mesh, cellMap}` instead of a bare
|
|
2047
|
+
* mesh -- a single FLAT array (global input cell index -> global output
|
|
2048
|
+
* cell index), unlike the other ops' per-block `cellMaps`.
|
|
1566
2049
|
*/
|
|
1567
|
-
agglomerate(mesh: Mesh, targetGroupSize?: number): Mesh;
|
|
2050
|
+
agglomerate(mesh: Mesh, targetGroupSize?: number, returnMaps?: false): Mesh;
|
|
2051
|
+
agglomerate(mesh: Mesh, targetGroupSize?: number, returnMaps?: true): { mesh: Mesh; cellMap: Int32Array };
|
|
1568
2052
|
|
|
1569
2053
|
/**
|
|
1570
2054
|
* Refine a mesh, subdividing cells into same-type children (`line` → 2,
|
|
@@ -1579,13 +2063,24 @@ export interface MeshioPlusPlusModule {
|
|
|
1579
2063
|
* @throws {Error} on a higher-order cell, a `pyramid`, or a ragged
|
|
1580
2064
|
* polygon/polyhedron block — none has a same-type subdivision — and on more
|
|
1581
2065
|
* than one selector, an unknown region, or an unusable predicate array.
|
|
2066
|
+
*
|
|
2067
|
+
* With `returnMaps: true`, returns `{mesh, pointMap, cellMaps}` instead of
|
|
2068
|
+
* a bare mesh.
|
|
1582
2069
|
*/
|
|
1583
2070
|
refine(
|
|
1584
2071
|
mesh: Mesh,
|
|
1585
2072
|
levels?: number,
|
|
1586
2073
|
recordParentIds?: boolean,
|
|
1587
|
-
options?: RefineOptions
|
|
2074
|
+
options?: RefineOptions,
|
|
2075
|
+
returnMaps?: false,
|
|
1588
2076
|
): Mesh;
|
|
2077
|
+
refine(
|
|
2078
|
+
mesh: Mesh,
|
|
2079
|
+
levels?: number,
|
|
2080
|
+
recordParentIds?: boolean,
|
|
2081
|
+
options?: RefineOptions,
|
|
2082
|
+
returnMaps?: true,
|
|
2083
|
+
): { mesh: Mesh } & PointCellMaps;
|
|
1589
2084
|
|
|
1590
2085
|
/**
|
|
1591
2086
|
* Decimate a SURFACE mesh by quadric-error-metric (Garland-Heckbert) edge
|
|
@@ -1596,11 +2091,13 @@ export interface MeshioPlusPlusModule {
|
|
|
1596
2091
|
* (once-used-edge test) and feature vertices (face normals differing by
|
|
1597
2092
|
* more than `featureAngle` degrees) are pinned by default, and the link
|
|
1598
2093
|
* condition plus a normal-flip guard reject any collapse that would change
|
|
1599
|
-
* topology or fold the surface.
|
|
1600
|
-
*
|
|
2094
|
+
* topology or fold the surface. `frozen` is an optional array of 0-based
|
|
2095
|
+
* point ids to pin outright. With `returnMaps: true`, the result also
|
|
2096
|
+
* carries `pointMap`/`cellMaps`.
|
|
1601
2097
|
* @throws {Error} on a 3D volume mesh (extract the surface first),
|
|
1602
2098
|
* higher-order or ragged blocks, `line`/`vertex` blocks, an unknown
|
|
1603
|
-
* `placement`,
|
|
2099
|
+
* `placement`, a criterion count other than one, or a `frozen` id outside
|
|
2100
|
+
* `[0, numPoints)`.
|
|
1604
2101
|
*/
|
|
1605
2102
|
decimate(
|
|
1606
2103
|
mesh: Mesh,
|
|
@@ -1611,24 +2108,66 @@ export interface MeshioPlusPlusModule {
|
|
|
1611
2108
|
preserveBoundary?: boolean,
|
|
1612
2109
|
preserveFeatures?: boolean,
|
|
1613
2110
|
featureAngle?: number,
|
|
2111
|
+
frozen?: number[] | Int32Array | null,
|
|
2112
|
+
returnMaps?: boolean,
|
|
1614
2113
|
): {
|
|
1615
2114
|
mesh: Mesh;
|
|
1616
2115
|
facesRemoved: number;
|
|
1617
2116
|
pointsRemoved: number;
|
|
1618
2117
|
collapsesRejected: number;
|
|
1619
2118
|
maxErrorApplied: number;
|
|
2119
|
+
pointMap?: Int32Array;
|
|
2120
|
+
cellMaps?: Int32Array[];
|
|
2121
|
+
};
|
|
2122
|
+
|
|
2123
|
+
/**
|
|
2124
|
+
* Decimate a tetrahedral VOLUME mesh by quadric-error-metric tet-edge
|
|
2125
|
+
* collapse — `decimate`'s volume sibling. Exactly one of `ratio` (fraction
|
|
2126
|
+
* of tets to KEEP, in (0, 1]), `targetCells` and `maxError` must be
|
|
2127
|
+
* non-negative. The output is all-tetra with the block structure kept 1:1.
|
|
2128
|
+
* `preserveBoundary` defaults to `false` here (unlike `decimate`): the
|
|
2129
|
+
* mesh's outer surface is usually interior geometry a solver still wants
|
|
2130
|
+
* simplified, not a boundary to protect. `frozen` is an optional array of
|
|
2131
|
+
* 0-based point ids to pin outright, unioned with any boundary/feature
|
|
2132
|
+
* pins. With `returnMaps: true`, the result also carries
|
|
2133
|
+
* `pointMap`/`cellMaps`.
|
|
2134
|
+
* @throws {Error} on a non-manifold boundary face, a non-tetra 3D cell,
|
|
2135
|
+
* higher-order tets, ragged/polyhedron blocks, a non-3D block, an unknown
|
|
2136
|
+
* `placement`, a criterion count other than one, or a `frozen` id outside
|
|
2137
|
+
* `[0, numPoints)`.
|
|
2138
|
+
*/
|
|
2139
|
+
decimateVolume(
|
|
2140
|
+
mesh: Mesh,
|
|
2141
|
+
ratio?: number,
|
|
2142
|
+
targetCells?: number,
|
|
2143
|
+
maxError?: number,
|
|
2144
|
+
placement?: DecimatePlacement,
|
|
2145
|
+
preserveBoundary?: boolean,
|
|
2146
|
+
preserveFeatures?: boolean,
|
|
2147
|
+
featureAngle?: number,
|
|
2148
|
+
frozen?: number[] | Int32Array | null,
|
|
2149
|
+
returnMaps?: boolean,
|
|
2150
|
+
): {
|
|
2151
|
+
mesh: Mesh;
|
|
2152
|
+
tetsRemoved: number;
|
|
2153
|
+
pointsRemoved: number;
|
|
2154
|
+
collapsesRejected: number;
|
|
2155
|
+
maxErrorApplied: number;
|
|
2156
|
+
pointMap?: Int32Array;
|
|
2157
|
+
cellMaps?: Int32Array[];
|
|
1620
2158
|
};
|
|
1621
2159
|
|
|
1622
2160
|
/**
|
|
1623
2161
|
* Decompose a mesh into exactly `nparts` balanced pieces for domain
|
|
1624
2162
|
* decomposition (the count-driven complement to `split`). Pieces keep the
|
|
1625
2163
|
* input's cell-block structure 1:1 (empty blocks included, unlike `split`),
|
|
1626
|
-
* so concatenating them reproduces the input.
|
|
1627
|
-
* carried across the JS boundary — use `recordIds` for the
|
|
2164
|
+
* so concatenating them reproduces the input. Use `recordIds` for the
|
|
1628
2165
|
* `partition:original_*_id` arrays, or `partitionLabels` for the raw
|
|
1629
|
-
* assignment
|
|
1630
|
-
*
|
|
1631
|
-
*
|
|
2166
|
+
* assignment; with `returnMaps: true`, each piece also carries
|
|
2167
|
+
* `pointMap`/`cellMaps` (see {@link PointCellMaps}). `weightsKey` names a
|
|
2168
|
+
* scalar `cell_data` array of per-cell weights. `ghostLayers > 0` grows
|
|
2169
|
+
* each piece by that many shared-node BFS layers of other parts' cells (a
|
|
2170
|
+
* halo), tagged `partition:ghost`.
|
|
1632
2171
|
* @throws {Error} on `method: 'kahip'` (KaHIP is never part of the WASM
|
|
1633
2172
|
* build; the message names `MESHIOPLUSPLUS_WITH_KAHIP`), `nparts < 1`,
|
|
1634
2173
|
* `ghostLayers < 0`, or a bad weights array.
|
|
@@ -1643,7 +2182,8 @@ export interface MeshioPlusPlusModule {
|
|
|
1643
2182
|
recordIds?: boolean,
|
|
1644
2183
|
ghostLayers?: number,
|
|
1645
2184
|
weightsKey?: string,
|
|
1646
|
-
|
|
2185
|
+
returnMaps?: boolean,
|
|
2186
|
+
): ({ partId: number; mesh: Mesh } & Partial<PointCellMaps>)[];
|
|
1647
2187
|
|
|
1648
2188
|
/**
|
|
1649
2189
|
* The per-cell part assignment only: one array per cell block
|
|
@@ -1792,16 +2332,54 @@ export interface MeshioPlusPlusModule {
|
|
|
1792
2332
|
* instantiation otherwise. `variant: 'auto'` (default) picks the threaded build
|
|
1793
2333
|
* under Node and in a cross-origin-isolated browser, else the sequential one.
|
|
1794
2334
|
*
|
|
1795
|
-
* @param moduleOverrides forwarded
|
|
1796
|
-
*
|
|
1797
|
-
*
|
|
1798
|
-
*
|
|
2335
|
+
* @param moduleOverrides forwarded to the Emscripten module factory, with
|
|
2336
|
+
* `locateFile`/`onAbort` wrapped for diagnostics (your own overrides still
|
|
2337
|
+
* run first) -- see {@link MeshioPlusPlusLoadError}. `locateFile` receives
|
|
2338
|
+
* the requested filename, so return the URL matching the loaded variant
|
|
2339
|
+
* (`meshioplusplus_wasm.wasm` or `meshioplusplus_wasm_mt.wasm`).
|
|
1799
2340
|
* @param options.variant which native artifact to load: `'auto'` (default),
|
|
1800
2341
|
* `'mt'` (force threaded), or `'seq'` (force sequential).
|
|
2342
|
+
* @throws {MeshioPlusPlusLoadError} if the WASM module fails to instantiate.
|
|
1801
2343
|
*/
|
|
1802
2344
|
export function loadMeshioPlusPlus(
|
|
1803
|
-
moduleOverrides?:
|
|
2345
|
+
moduleOverrides?: ModuleOverrides,
|
|
1804
2346
|
options?: { variant?: 'auto' | 'mt' | 'seq' },
|
|
1805
2347
|
): Promise<MeshioPlusPlusModule>;
|
|
1806
2348
|
|
|
2349
|
+
/** Overrides forwarded to the underlying Emscripten module factory. */
|
|
2350
|
+
export interface ModuleOverrides {
|
|
2351
|
+
/**
|
|
2352
|
+
* Resolve the URL for a native artifact Emscripten wants to fetch (the
|
|
2353
|
+
* `.wasm` binary, and under a threaded build its worker script). Receives
|
|
2354
|
+
* the requested filename and Emscripten's own default prefix; return the
|
|
2355
|
+
* URL to actually load. Must return the file matching the loaded variant
|
|
2356
|
+
* (`meshioplusplus_wasm.wasm` vs `meshioplusplus_wasm_mt.wasm`) -- a
|
|
2357
|
+
* mismatch either fails instantiation or, in the case of the sequential
|
|
2358
|
+
* binary handed to the threaded glue, loads successfully but reports the
|
|
2359
|
+
* wrong {@link MeshioPlusPlusModule.parallelBackend}, which
|
|
2360
|
+
* `loadMeshioPlusPlus` detects and rejects with a {@link MeshioPlusPlusLoadError}.
|
|
2361
|
+
*/
|
|
2362
|
+
locateFile?(path: string, prefix: string): string;
|
|
2363
|
+
/** Called by Emscripten when the module aborts during instantiation. */
|
|
2364
|
+
onAbort?(reason: unknown): void;
|
|
2365
|
+
[key: string]: unknown;
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
/**
|
|
2369
|
+
* Thrown by `loadMeshioPlusPlus()` when a WASM module fails to instantiate.
|
|
2370
|
+
* `cause` is the underlying error (or abort reason) that triggered it.
|
|
2371
|
+
*/
|
|
2372
|
+
export interface MeshioPlusPlusLoadError extends Error {
|
|
2373
|
+
name: 'MeshioPlusPlusLoadError';
|
|
2374
|
+
/** Which native artifact was being loaded. */
|
|
2375
|
+
variant: 'mt' | 'seq';
|
|
2376
|
+
/** The glue module specifier (e.g. '../dist/meshioplusplus_wasm_mt.mjs'). */
|
|
2377
|
+
glue: string;
|
|
2378
|
+
/** The filename Emscripten asked `locateFile` to resolve, if it got that far. */
|
|
2379
|
+
requestedFile?: string;
|
|
2380
|
+
/** What `locateFile` returned for `requestedFile`. */
|
|
2381
|
+
resolvedUrl?: string;
|
|
2382
|
+
cause?: unknown;
|
|
2383
|
+
}
|
|
2384
|
+
|
|
1807
2385
|
export default loadMeshioPlusPlus;
|