@meshioplusplus/wasm 10.9.0 → 10.14.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
|
@@ -404,6 +404,9 @@ export type ErrorMethod = 'zz';
|
|
|
404
404
|
/** `estimateError`'s marking policy. See doc/error.md. */
|
|
405
405
|
export type ErrorMarking = 'none' | 'absolute' | 'fraction' | 'dorfler';
|
|
406
406
|
|
|
407
|
+
/** `remesh`'s clustering objective. See doc/remesh.md. */
|
|
408
|
+
export type RemeshMetric = 'isotropic' | 'quadric' | 'anisotropic';
|
|
409
|
+
|
|
407
410
|
/** One data array's location: `point_data`, `cell_data`, or `field_data`. */
|
|
408
411
|
export type DataLocation = 'point' | 'cell' | 'field';
|
|
409
412
|
|
|
@@ -441,8 +444,11 @@ export type MergeDataPolicy = 'intersection' | 'fill';
|
|
|
441
444
|
/** Element-representation conversion performed by `convertCells`. */
|
|
442
445
|
export type ConvertCellsMode = 'linearize' | 'simplexify' | 'elevate';
|
|
443
446
|
|
|
444
|
-
/** Smoothing operator applied by `smooth`. `'taubin'` is shrink-free.
|
|
445
|
-
|
|
447
|
+
/** Smoothing operator applied by `smooth`. `'taubin'` is shrink-free.
|
|
448
|
+
* `'odt'` (optimal-Delaunay-triangulation smoothing) is tet-only and
|
|
449
|
+
* moves each free interior vertex toward the volume-weighted average of
|
|
450
|
+
* its incident tets' circumcenters. See doc/smooth.md. */
|
|
451
|
+
export type SmoothMethod = 'laplacian' | 'taubin' | 'odt';
|
|
446
452
|
|
|
447
453
|
/**
|
|
448
454
|
* How `refine` resolves the hanging nodes a partial refinement leaves behind.
|
|
@@ -1393,6 +1399,134 @@ export interface MeshioPlusPlusModule {
|
|
|
1393
1399
|
overwrite?: boolean,
|
|
1394
1400
|
): { mesh: Mesh; globalError: number; numSkipped: number; numMarked: number };
|
|
1395
1401
|
|
|
1402
|
+
/**
|
|
1403
|
+
* Remesh a surface by approximated centroidal Voronoi diagram (ACVD)
|
|
1404
|
+
* clustering: replace its triangulation with a new, near-uniformly-sized,
|
|
1405
|
+
* well-shaped one at `numClusters` vertices. Unlike every other
|
|
1406
|
+
* resolution-changing operation, the output has NEW points and NEW
|
|
1407
|
+
* connectivity with no correspondence to the input — `point_data`,
|
|
1408
|
+
* `cell_data` and named regions are dropped, `field_data` is carried.
|
|
1409
|
+
*
|
|
1410
|
+
* `metric` is `"isotropic"` (default; area-weighted centroidal distance,
|
|
1411
|
+
* fast, rounds sharp features), `"quadric"` (Garland-Heckbert quadric
|
|
1412
|
+
* error, preserves sharp edges/corners at extra cost per candidate move),
|
|
1413
|
+
* or `"anisotropic"` (clusters shaped by a local curvature tensor —
|
|
1414
|
+
* elongated along low-curvature directions, compact across sharp ones —
|
|
1415
|
+
* see `maxAnisotropy`). `subdivide` defaults to automatic (`-1`): the
|
|
1416
|
+
* smallest count of uniform `refine` passes reaching `subsampleRatio`
|
|
1417
|
+
* items per cluster, capped at `maxSubdivide`; `0` disables subdivision.
|
|
1418
|
+
* `gradation` is the curvature-gradation exponent `gamma` in the item
|
|
1419
|
+
* weight `area * kappa^gamma` (`0.0`, the default, disables gradation
|
|
1420
|
+
* entirely and reproduces plain area weighting). `preserveBoundary`
|
|
1421
|
+
* (default `true`) detects the input's open boundary (if any), seeds it
|
|
1422
|
+
* before the interior, and emits a `line` dual cell along boundary edges
|
|
1423
|
+
* whose endpoints land in different clusters — a no-op on a closed mesh.
|
|
1424
|
+
* `maxAnisotropy` (default `4.0`, a measured value) is, under
|
|
1425
|
+
* `metric = "anisotropic"`, the maximum ratio between the two in-plane
|
|
1426
|
+
* target edge lengths a curvature tensor may request; `1.0` recovers the
|
|
1427
|
+
* isotropic shape exactly. Must be at least `1.0`, and an error to set
|
|
1428
|
+
* away from the default under any other metric.
|
|
1429
|
+
* `numIsolatedClusters` and `numNonManifoldVertices` are two distinct
|
|
1430
|
+
* causes of non-manifold output (disconnected clusters vs. "bowtie"
|
|
1431
|
+
* vertices) that repair could not fully fix; check both rather than
|
|
1432
|
+
* assuming.
|
|
1433
|
+
* @throws {Error} on a cluster count below 4 or above the subdivided
|
|
1434
|
+
* input's vertex count, or on any block outside the surface scope (3D
|
|
1435
|
+
* volume cells, higher-order cells, ragged polygon/polyhedron blocks).
|
|
1436
|
+
*/
|
|
1437
|
+
remesh(
|
|
1438
|
+
mesh: Mesh,
|
|
1439
|
+
numClusters: number,
|
|
1440
|
+
subdivide?: number,
|
|
1441
|
+
subsampleRatio?: number,
|
|
1442
|
+
maxSubdivide?: number,
|
|
1443
|
+
maxIterations?: number,
|
|
1444
|
+
maxRepairPasses?: number,
|
|
1445
|
+
metric?: RemeshMetric,
|
|
1446
|
+
gradation?: number,
|
|
1447
|
+
preserveBoundary?: boolean,
|
|
1448
|
+
maxAnisotropy?: number,
|
|
1449
|
+
): {
|
|
1450
|
+
mesh: Mesh;
|
|
1451
|
+
numClusters: number;
|
|
1452
|
+
numIterations: number;
|
|
1453
|
+
subdivideApplied: number;
|
|
1454
|
+
numIsolatedClusters: number;
|
|
1455
|
+
numNonManifoldVertices: number;
|
|
1456
|
+
};
|
|
1457
|
+
|
|
1458
|
+
/**
|
|
1459
|
+
* Retetrahedralize a volume mesh (or a closed surface) at a caller-chosen
|
|
1460
|
+
* resolution by isosurface stuffing — the volumetric sibling of `remesh`.
|
|
1461
|
+
* Unlike `remesh`, this accepts a VOLUME mesh directly (its boundary is
|
|
1462
|
+
* extracted internally) as well as a closed surface. Same
|
|
1463
|
+
* no-correspondence-with-the-input output contract as `remesh`: new
|
|
1464
|
+
* points, new connectivity, `point_data`/`cell_data`/named regions
|
|
1465
|
+
* dropped, `field_data` carried.
|
|
1466
|
+
*
|
|
1467
|
+
* Exactly one of `resolution`/`cellSize` must be given, sizing a body-
|
|
1468
|
+
* centered cubic (BCC) lattice whose uncut tets have dihedral angles from
|
|
1469
|
+
* a fixed, mesh-size-independent set. `warpFraction` (default `0.35`)
|
|
1470
|
+
* moves lattice vertices near the surface onto it, trading a small,
|
|
1471
|
+
* measured chance of non-manifold boundary edges (reported as
|
|
1472
|
+
* `numNonManifoldEdges`) for substantially better boundary tet quality;
|
|
1473
|
+
* `0` disables warping and gives an exactly watertight but lower-quality
|
|
1474
|
+
* boundary. See doc/remesh_volume.md for the measured tradeoff.
|
|
1475
|
+
* @throws {Error} when neither or both of `resolution`/`cellSize` are
|
|
1476
|
+
* set, on a non-positive resolution/cell size, on a negative
|
|
1477
|
+
* `warpFraction`, when the root lattice would exceed `maxCells`, when
|
|
1478
|
+
* the cut output would exceed `maxTets`, and on any input the boundary
|
|
1479
|
+
* extraction itself refuses.
|
|
1480
|
+
*/
|
|
1481
|
+
remeshVolume(
|
|
1482
|
+
mesh: Mesh,
|
|
1483
|
+
resolution?: number[] | null,
|
|
1484
|
+
cellSize?: number,
|
|
1485
|
+
bounds?: number[] | null,
|
|
1486
|
+
padding?: number,
|
|
1487
|
+
paddingRelative?: number,
|
|
1488
|
+
maxCells?: number,
|
|
1489
|
+
maxTets?: number,
|
|
1490
|
+
warpFraction?: number,
|
|
1491
|
+
sign?: SdfSign,
|
|
1492
|
+
watertightCheck?: SdfWatertightCheck,
|
|
1493
|
+
): {
|
|
1494
|
+
mesh: Mesh;
|
|
1495
|
+
numTets: number;
|
|
1496
|
+
numVerticesWarped: number;
|
|
1497
|
+
numTetsRejected: number;
|
|
1498
|
+
numNonManifoldEdges: number;
|
|
1499
|
+
};
|
|
1500
|
+
|
|
1501
|
+
/**
|
|
1502
|
+
* ODT-remesh a tetrahedral mesh: raise its worst element quality by
|
|
1503
|
+
* relocating vertices AND flipping connectivity (2-3/3-2, predicate-free).
|
|
1504
|
+
* The genuine "ODT remeshing" sibling of `remeshVolume` (which generates a
|
|
1505
|
+
* fresh lattice mesh) and of `smooth` method `"odt"` (which only moves
|
|
1506
|
+
* points on fixed connectivity). Tet-only. The point set is invariant, so
|
|
1507
|
+
* point_data/field_data and Point regions carry; cell_data + Cell/Side
|
|
1508
|
+
* regions are dropped. With `preserveBoundary` the boundary surface is
|
|
1509
|
+
* exactly preserved. See doc/optimize_volume.md.
|
|
1510
|
+
* @throws {Error} when the mesh contains a non-`tetra` block or no tetra.
|
|
1511
|
+
*/
|
|
1512
|
+
optimizeVolume(
|
|
1513
|
+
mesh: Mesh,
|
|
1514
|
+
maxIterations?: number,
|
|
1515
|
+
relocate?: boolean,
|
|
1516
|
+
flip?: boolean,
|
|
1517
|
+
preserveBoundary?: boolean,
|
|
1518
|
+
minImprovement?: number,
|
|
1519
|
+
): {
|
|
1520
|
+
mesh: Mesh;
|
|
1521
|
+
numFlips: number;
|
|
1522
|
+
num23Flips: number;
|
|
1523
|
+
num32Flips: number;
|
|
1524
|
+
numVerticesMoved: number;
|
|
1525
|
+
numTets: number;
|
|
1526
|
+
minQualityBefore: number;
|
|
1527
|
+
minQualityAfter: number;
|
|
1528
|
+
};
|
|
1529
|
+
|
|
1396
1530
|
/** Partition a mesh into submeshes by type, connected component, or tag. */
|
|
1397
1531
|
split(mesh: Mesh, by: SplitBy, tagName?: string): { key: string; mesh: Mesh }[];
|
|
1398
1532
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meshioplusplus/wasm",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.14.0",
|
|
4
4
|
"description": "meshio++ mesh I/O compiled to WebAssembly: read/write 41 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
|
@@ -162,6 +162,9 @@ function resolveVariant(variant) {
|
|
|
162
162
|
* gradient: (mesh: Mesh, array: string, operator?: string, method?: string, location?: string, output?: string, component?: number, overwrite?: boolean) => {mesh: Mesh, numSkipped: number, numFallback: number},
|
|
163
163
|
* hessian: (mesh: Mesh, array: string, method?: string, location?: string, output?: string, overwrite?: boolean) => {mesh: Mesh, numSkipped: number, numFallback: number},
|
|
164
164
|
* estimateError: (mesh: Mesh, array: string, method?: string, marking?: string, markingValue?: number, output?: string, marked?: string, overwrite?: boolean) => {mesh: Mesh, globalError: number, numSkipped: number, numMarked: number},
|
|
165
|
+
* remesh: (mesh: Mesh, numClusters: number, subdivide?: number, subsampleRatio?: number, maxSubdivide?: number, maxIterations?: number, maxRepairPasses?: number, metric?: string, gradation?: number, preserveBoundary?: boolean, maxAnisotropy?: number) => {mesh: Mesh, numClusters: number, numIterations: number, subdivideApplied: number, numIsolatedClusters: number, numNonManifoldVertices: number},
|
|
166
|
+
* remeshVolume: (mesh: Mesh, resolution?: number[], cellSize?: number, bounds?: number[], padding?: number, paddingRelative?: number, maxCells?: number, maxTets?: number, warpFraction?: number, sign?: string, watertightCheck?: string) => {mesh: Mesh, numTets: number, numVerticesWarped: number, numTetsRejected: number, numNonManifoldEdges: number},
|
|
167
|
+
* optimizeVolume: (mesh: Mesh, maxIterations?: number, relocate?: boolean, flip?: boolean, preserveBoundary?: boolean, minImprovement?: number) => {mesh: Mesh, numFlips: number, num23Flips: number, num32Flips: number, numVerticesMoved: number, numTets: number, minQualityBefore: number, minQualityAfter: number},
|
|
165
168
|
* split: (mesh: Mesh, by: string, tagName?: string) => {key: string, mesh: Mesh}[],
|
|
166
169
|
* convertCells: (mesh: Mesh, mode?: string, recordParentIds?: boolean) => Mesh,
|
|
167
170
|
* subdivide: (mesh: Mesh, recordParentIds?: boolean) => Mesh,
|
|
@@ -484,6 +487,57 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
|
|
|
484
487
|
marked,
|
|
485
488
|
overwrite,
|
|
486
489
|
),
|
|
490
|
+
remesh: (
|
|
491
|
+
mesh,
|
|
492
|
+
numClusters,
|
|
493
|
+
subdivide = -1,
|
|
494
|
+
subsampleRatio = 10.0,
|
|
495
|
+
maxSubdivide = 4,
|
|
496
|
+
maxIterations = 100,
|
|
497
|
+
maxRepairPasses = 10,
|
|
498
|
+
metric = 'isotropic',
|
|
499
|
+
gradation = 0.0,
|
|
500
|
+
preserveBoundary = true,
|
|
501
|
+
maxAnisotropy = 4.0,
|
|
502
|
+
) =>
|
|
503
|
+
Module.remesh(
|
|
504
|
+
mesh,
|
|
505
|
+
numClusters,
|
|
506
|
+
subdivide,
|
|
507
|
+
subsampleRatio,
|
|
508
|
+
maxSubdivide,
|
|
509
|
+
maxIterations,
|
|
510
|
+
maxRepairPasses,
|
|
511
|
+
metric,
|
|
512
|
+
gradation,
|
|
513
|
+
preserveBoundary,
|
|
514
|
+
maxAnisotropy,
|
|
515
|
+
),
|
|
516
|
+
remeshVolume: (
|
|
517
|
+
mesh,
|
|
518
|
+
resolution = null,
|
|
519
|
+
cellSize = 0,
|
|
520
|
+
bounds = null,
|
|
521
|
+
padding = 0,
|
|
522
|
+
paddingRelative = 0.1,
|
|
523
|
+
maxCells = 20000000,
|
|
524
|
+
maxTets = 20000000,
|
|
525
|
+
warpFraction = 0.35,
|
|
526
|
+
sign = 'pseudonormal',
|
|
527
|
+
watertightCheck = 'warn',
|
|
528
|
+
) =>
|
|
529
|
+
Module.remeshVolume(mesh, resolution, cellSize, bounds, padding, paddingRelative,
|
|
530
|
+
maxCells, maxTets, warpFraction, sign, watertightCheck),
|
|
531
|
+
optimizeVolume: (
|
|
532
|
+
mesh,
|
|
533
|
+
maxIterations = 10,
|
|
534
|
+
relocate = true,
|
|
535
|
+
flip = true,
|
|
536
|
+
preserveBoundary = true,
|
|
537
|
+
minImprovement = 1e-6,
|
|
538
|
+
) =>
|
|
539
|
+
Module.optimizeVolume(mesh, maxIterations, relocate, flip, preserveBoundary,
|
|
540
|
+
minImprovement),
|
|
487
541
|
split: (mesh, by, tagName = '') => Module.split(mesh, by, tagName),
|
|
488
542
|
convertCells: (mesh, mode = 'linearize', recordParentIds = false) =>
|
|
489
543
|
Module.convertCells(mesh, mode, recordParentIds),
|