@metamesh/modeling 0.10.0 → 0.11.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/CHANGELOG.md +40 -0
- package/README.md +56 -17
- package/dist/api/engine.d.ts +105 -8
- package/dist/api/index.d.ts +754 -771
- package/dist/engine/construction-operations.js +3 -1
- package/dist/engine/deferred-context.js +182 -0
- package/dist/engine/execution.js +38 -4
- package/dist/engine/finalization.js +65 -133
- package/dist/engine/geometry-recipes.js +12 -0
- package/dist/engine/immutable-generation-data.js +186 -0
- package/dist/engine/index.js +57 -35
- package/dist/engine/kernel/manifold.wasm +0 -0
- package/dist/engine/model-dependencies.js +46 -0
- package/dist/engine/model-summary.js +43 -0
- package/dist/engine/native/ownership.js +11 -5
- package/dist/engine/placement.js +24 -0
- package/dist/engine/recipe-realization.js +119 -0
- package/dist/engine/session-graph.js +442 -0
- package/dist/engine/session-native.js +90 -0
- package/dist/engine/session-snapshot.js +153 -0
- package/dist/engine/session.js +184 -0
- package/dist/engine/shape-anchors.js +5 -0
- package/dist/geometry/mesh-centroid.js +7 -6
- package/dist/geometry/mesh-planar.js +11 -10
- package/dist/geometry/mesh-quality.js +15 -14
- package/dist/geometry/mesh-signature.js +8 -7
- package/dist/geometry/mesh-solid.js +10 -4
- package/dist/geometry/mesh.js +36 -31
- package/dist/index.js +2 -0
- package/dist/model/execution-binding.js +5 -5
- package/dist/model/generation.js +27 -0
- package/dist/model/immutable-buffer.js +111 -0
- package/dist/model/modeling-context.js +1 -0
- package/dist/model/operations.js +521 -160
- package/dist/model/shape-handles.js +44 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @metamesh/modeling
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b5da778: Replace prepare/build with typed generation programs, optional computed values and authoritative
|
|
8
|
+
part placement. Add isolated session caches and deferred geometry with explicit snapshot ownership.
|
|
9
|
+
Expose immutable fluent Solid and Section methods for transforms, subtraction, finishing, and
|
|
10
|
+
Section-to-Solid construction, replacing the corresponding standalone operations and public
|
|
11
|
+
context facade. Generator packages require format 4 and runtime 4; previous executable contracts are unsupported.
|
|
12
|
+
- bfb7a63: Keep computed dependencies correct after conditional removal and re-registration, and prevent
|
|
13
|
+
caught evaluation failures from returning earlier cached values. Reduce immutable data copying,
|
|
14
|
+
centralize geometry finalization, and validate newly delivered resources once while preserving
|
|
15
|
+
per-revision part and aggregate resource checks.
|
|
16
|
+
|
|
17
|
+
Replace transparent cached typed arrays with explicit immutableBuffer and immutableMesh capture
|
|
18
|
+
helpers. Cached numeric data exposes length, at(), and copy(); uncaptured typed arrays in computed
|
|
19
|
+
results or bindings now reject. Snapshot and Worker output buffers remain ordinary typed arrays.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 88f5336: Correct immutable cache comparisons, recapture mutable mesh inputs on every run, and preserve
|
|
24
|
+
session ownership during concurrent Testkit operations. Reject unsupported hidden data fields
|
|
25
|
+
instead of silently dropping them, and reuse native operation contexts during recipe evaluation.
|
|
26
|
+
- 6c90e9d: Capture computed data in one validated traversal, reuse unchanged bindings and repeated dependency
|
|
27
|
+
analysis, and share recorded operation calls across result handles. Derive internal fluent dispatch
|
|
28
|
+
from the public shape contracts and skip cache retention work when caching is disabled.
|
|
29
|
+
|
|
30
|
+
Keep failed assertions attached to their revision even when author code catches them, preventing
|
|
31
|
+
invalid snapshots and cache commits.
|
|
32
|
+
|
|
33
|
+
- 60c458f: Validate placed manufacturing geometry under the requested solid policy after Float32 rounding.
|
|
34
|
+
Share world buffers between identical placed instances while still counting each instance toward
|
|
35
|
+
output limits, and include retained object storage and field names in optional cache estimates.
|
|
36
|
+
- a1f5aba: Reuse evaluated computed geometry as native operands across session runs without changing the public
|
|
37
|
+
API. Preserve anchor and profile metadata, bound optional retention, and release native allocations
|
|
38
|
+
on failed candidate generation, eviction, cache clearing, and session disposal.
|
|
39
|
+
- d4ffce7: Release obsolete computation callbacks and prior revision graphs when a revision closes, keeping
|
|
40
|
+
cached numerical recipes from retaining unrelated work. Consolidate recipe traversal and revision
|
|
41
|
+
cleanup without changing the public Modeling API.
|
|
42
|
+
|
|
3
43
|
## 0.10.0
|
|
4
44
|
|
|
5
45
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -15,33 +15,72 @@ pnpm add @metamesh/modeling
|
|
|
15
15
|
Initialize an engine, then build and export a plate with a hole:
|
|
16
16
|
|
|
17
17
|
```ts
|
|
18
|
-
import { box, cylinder,
|
|
18
|
+
import { box, cylinder, generate } from "@metamesh/modeling";
|
|
19
19
|
import { createModelEngine } from "@metamesh/modeling/engine";
|
|
20
20
|
|
|
21
21
|
const engine = await createModelEngine();
|
|
22
|
-
const
|
|
23
|
-
(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
);
|
|
22
|
+
const model = generate<Record<never, never>>(({ part }) => {
|
|
23
|
+
const body = box({ size: [30, 20, 6] });
|
|
24
|
+
const bore = cylinder({ height: 8, radius: 3, sizing: "face" });
|
|
25
|
+
return [part("plate", { geometry: body.subtract([bore]), color: "#67e8f9" })];
|
|
26
|
+
});
|
|
27
|
+
const session = engine.createSession(model, { resolution: { maxChordError: 0.025 } });
|
|
28
|
+
const snapshot = session.run({});
|
|
30
29
|
const bytes = await engine.export3mf(snapshot.parts, { name: "Plate" });
|
|
30
|
+
snapshot.dispose();
|
|
31
|
+
session.dispose();
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
Constructors and fluent shape methods declare immutable recipes inside synchronous generation.
|
|
35
|
+
Use shape methods for transforms, subtraction, and finishing; collection operations such as
|
|
36
|
+
`union`, patterns, and observations remain functions. Calls apply in written order about the origin.
|
|
37
|
+
A method preserves its input; no-op operations may reuse a handle. A session owns optional
|
|
38
|
+
computed caches; captured snapshots stay usable after the session is disposed. Keep the finalized
|
|
39
|
+
snapshot for rendering or export, then dispose it. For browser WASM setup and host lifecycle, follow
|
|
35
40
|
[Run Modeling in your application](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/docs/engine/hosting.mdx).
|
|
36
41
|
|
|
42
|
+
## Reuse unchanged work
|
|
43
|
+
|
|
44
|
+
Caching is optional. A named computation tracks parameter and other computation reads; part
|
|
45
|
+
placement and color stay separate from its geometry:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const model = generate<{ height: number; gap: number }>(({ params, computed, part }) => {
|
|
49
|
+
const body = computed("body", () => box({ size: [10, 10, params.height] }));
|
|
50
|
+
return [part("left", body), part("right", { geometry: body, position: [10 + params.gap, 0, 0] })];
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Changing `gap` reuses the body's validated geometry. Changing `height` recomputes it. Computations
|
|
55
|
+
are pure and synchronous: bind changing locals explicitly with `computed(id, { value }, inputs => ...)`.
|
|
56
|
+
|
|
57
|
+
Capture cached numeric arrays with `immutableBuffer(values)`: read `length` or `at(index)`, and
|
|
58
|
+
call `copy()` for an owned mutable typed array. Capture cached meshes with `immutableMesh(mesh)`
|
|
59
|
+
and pass their readers directly to `part`. Computed results and bindings reject raw typed arrays;
|
|
60
|
+
ordinary transient mesh inputs, snapshots, and Worker output still use normal typed arrays.
|
|
61
|
+
|
|
62
|
+
The optional session setting `verifyCache: true` reruns callbacks on cache hits and compares bounded
|
|
63
|
+
data and recipes to diagnose observable missing dependencies. It can reject unsupported or large
|
|
64
|
+
comparisons and cannot prove arbitrary JavaScript; production caching leaves this probe disabled.
|
|
65
|
+
|
|
66
|
+
For expensive geometry followed by adjustable cuts or Booleans, put the base and finishing stage
|
|
67
|
+
in separate computations. Sessions can retain the evaluated base privately, preserving native
|
|
68
|
+
precision when it becomes an operand in a later run. Retention is bounded and optional; eviction
|
|
69
|
+
rebuilds the original recipe. Clear or dispose the session to release retained native geometry.
|
|
70
|
+
|
|
71
|
+
Use `assert(condition, message)` for a constraint that stops the revision and `warn(message)` for
|
|
72
|
+
nonblocking guidance. Hosts bind prepared deterministic capabilities through session `services`.
|
|
73
|
+
`validateModel` checks declarations and reached assertions without initializing a kernel; checks
|
|
74
|
+
that observe geometry use an initialized session's `validate` method.
|
|
75
|
+
|
|
37
76
|
## API discovery and ownership
|
|
38
77
|
|
|
39
|
-
| Import | Use it for
|
|
40
|
-
| ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
-
| [`@metamesh/modeling`](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/reference/generated/model/index.mdx) |
|
|
42
|
-
| [`@metamesh/modeling/geometry`](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/reference/generated/geometry/index.mdx) | Pure paths, profiles, meshes, and calculations
|
|
43
|
-
| [`@metamesh/modeling/engine`](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/reference/generated/engine/index.mdx) |
|
|
44
|
-
| [`@metamesh/modeling/text`](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/reference/generated/text/index.mdx) | Optional font preparation and vector layouts
|
|
78
|
+
| Import | Use it for |
|
|
79
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
80
|
+
| [`@metamesh/modeling`](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/reference/generated/model/index.mdx) | Fluent solids and sections, constructors, and collection operations |
|
|
81
|
+
| [`@metamesh/modeling/geometry`](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/reference/generated/geometry/index.mdx) | Pure paths, profiles, meshes, and calculations |
|
|
82
|
+
| [`@metamesh/modeling/engine`](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/reference/generated/engine/index.mdx) | Sessions, snapshots, limits, and 3MF export |
|
|
83
|
+
| [`@metamesh/modeling/text`](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/reference/generated/text/index.mdx) | Optional font preparation and vector layouts |
|
|
45
84
|
|
|
46
85
|
## Documentation
|
|
47
86
|
|
package/dist/api/engine.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import type { TriangleMesh } from "@metamesh/modeling/geometry";
|
|
2
|
-
import type {
|
|
2
|
+
import type { FinalizedModel, FinalizedPart, GenerationDiagnostic, GeometryResolution, ModelingLimits, ModelProgram, Vec3 } from "@metamesh/modeling";
|
|
3
3
|
/** Default host resource ceilings for parts, vertices, triangles, and transferable bytes. */
|
|
4
4
|
declare const defaultModelingLimits: Readonly<ModelingLimits>;
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
/** Execution settings supplied by the host, independently of generator metadata. */
|
|
8
|
-
export interface
|
|
8
|
+
export interface GenerationOptions {
|
|
9
9
|
/** Optional bounded intersection and nested-shell checks; defaults to indexed topology validation. */
|
|
10
10
|
readonly meshValidation?: "topology" | "solid";
|
|
11
11
|
/** Per-build limits, no larger than the configured engine ceilings. */
|
|
12
12
|
readonly limits?: Partial<ModelingLimits>;
|
|
13
|
-
/** Physical sampling defaults;
|
|
13
|
+
/** Physical sampling defaults; operation options and exact counts override these. */
|
|
14
14
|
readonly resolution?: GeometryResolution;
|
|
15
15
|
/** Optional bounded planar cleanup; unsupported candidates preserve the original part. */
|
|
16
16
|
readonly meshTopologyMode?: "original" | "optimized";
|
|
@@ -21,11 +21,90 @@ export interface BuildOptions {
|
|
|
21
21
|
export interface ModelEngine {
|
|
22
22
|
/** Immutable resource ceilings selected when this engine was initialized. */
|
|
23
23
|
readonly limits: ModelingLimits;
|
|
24
|
-
/**
|
|
25
|
-
|
|
24
|
+
/** Creates isolated caches; prepared service capabilities remain fixed for its lifetime. */
|
|
25
|
+
createSession<P, S>(program: ModelProgram<P, S>, ...options: keyof S extends never ? [options?: SessionOptions<S>] : [options: SessionOptions<S> & {
|
|
26
|
+
readonly services: S;
|
|
27
|
+
}]): ModelSession<P>;
|
|
26
28
|
/** Serializes already finalized mesh parts; never prepares or builds a generator again. */
|
|
27
29
|
export3mf(parts: readonly ExportMeshPart[], options?: Export3mfOptions): Promise<ArrayBuffer>;
|
|
28
30
|
}
|
|
31
|
+
/** Fixed generation policy and deterministic host capabilities for one model session. */
|
|
32
|
+
export interface SessionOptions<S = Record<never, never>> extends GenerationOptions {
|
|
33
|
+
/** Host-owned synchronous capabilities, required when declared by the program. The original
|
|
34
|
+
* environment is retained; its behavior and assets must remain deterministic and fixed for
|
|
35
|
+
* this session. Equivalent function wrappers do not constitute an asset revision.
|
|
36
|
+
*/
|
|
37
|
+
readonly services?: S;
|
|
38
|
+
/** Enables reuse; defaults to true. Set false for uncached output equivalence checks. */
|
|
39
|
+
readonly cache?: boolean;
|
|
40
|
+
/** Development-only cache-hit probe: reruns pure callbacks and compares bounded data/recipes.
|
|
41
|
+
* Unsupported closures or large results fail explicitly; this cannot prove arbitrary JavaScript.
|
|
42
|
+
*/
|
|
43
|
+
readonly verifyCache?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** Validated local geometry resource; accessors return owned buffer copies. */
|
|
46
|
+
export interface GeometryResource extends TriangleMesh {
|
|
47
|
+
/** Session-scoped immutable resource identity, stable while geometry is reused. */
|
|
48
|
+
readonly id: string;
|
|
49
|
+
/** Immutable resource revision; a new resource receives a new identity. */
|
|
50
|
+
readonly revision: number;
|
|
51
|
+
/** Facts for the exact local manufacturing buffers. */
|
|
52
|
+
readonly measurements: FinalizedPart["measurements"];
|
|
53
|
+
}
|
|
54
|
+
/** A world-space manufacturing part plus its reusable local renderer resource. */
|
|
55
|
+
export interface SnapshotPart extends FinalizedPart {
|
|
56
|
+
/** Validated geometry in local coordinates, independent of placement and appearance. */
|
|
57
|
+
readonly geometry: GeometryResource;
|
|
58
|
+
/** XYZ translation in millimetres after rotation. */
|
|
59
|
+
readonly position: Vec3;
|
|
60
|
+
/** Fixed global X, then Y, then Z rotation in degrees. */
|
|
61
|
+
readonly rotation: Vec3;
|
|
62
|
+
}
|
|
63
|
+
/** Captured immutable revision; disposal never changes another snapshot or an in-flight export. */
|
|
64
|
+
export interface ModelSnapshot extends FinalizedModel {
|
|
65
|
+
/** Ordered world-space parts, each referring to reusable local geometry. */
|
|
66
|
+
readonly parts: readonly SnapshotPart[];
|
|
67
|
+
/** Nonblocking diagnostics emitted for this revision. */
|
|
68
|
+
readonly diagnostics: readonly GenerationDiagnostic[];
|
|
69
|
+
/** Known dependency graph; outer reads remain conservative model-wide dependencies. */
|
|
70
|
+
readonly dependencies: ModelDependencies;
|
|
71
|
+
/** Releases this snapshot's references; idempotent, further access is invalid. */
|
|
72
|
+
dispose(): void;
|
|
73
|
+
}
|
|
74
|
+
/** Known dependencies for inspection; plain JavaScript bindings do not reveal their parameter origin. */
|
|
75
|
+
export interface ModelDependencies {
|
|
76
|
+
/** Parameter keys read outside computed callbacks, affecting structure or ordinary code. */
|
|
77
|
+
readonly modelParameters: readonly string[];
|
|
78
|
+
/** Direct dependencies recorded by successfully evaluated computations. */
|
|
79
|
+
readonly computations: readonly {
|
|
80
|
+
/** Session-local computation identity. */
|
|
81
|
+
readonly id: string;
|
|
82
|
+
/** Direct top-level parameter reads. */
|
|
83
|
+
readonly parameters: readonly string[];
|
|
84
|
+
/** Direct computed-reader dependencies. */
|
|
85
|
+
readonly computations: readonly string[];
|
|
86
|
+
}[];
|
|
87
|
+
/** Part reader roots and known transitive parameter dependencies. */
|
|
88
|
+
readonly parts: readonly {
|
|
89
|
+
/** Stable semantic output part identity. */
|
|
90
|
+
readonly id: string;
|
|
91
|
+
/** Computed readers supplied as geometry or placement roots. */
|
|
92
|
+
readonly computations: readonly string[];
|
|
93
|
+
/** Known transitive parameter dependencies through these roots. */
|
|
94
|
+
readonly parameters: readonly string[];
|
|
95
|
+
}[];
|
|
96
|
+
}
|
|
97
|
+
/** Stateful execution owner; a failed revision cannot change previously returned snapshots. */
|
|
98
|
+
export interface ModelSession<P> {
|
|
99
|
+
/** Generates an atomic manufacturing snapshot or throws; parameters are copied and frozen. */
|
|
100
|
+
run(params: Readonly<P>): ModelSnapshot;
|
|
101
|
+
/** Runs declaration and reached assertions without realizing returned parts. */
|
|
102
|
+
validate(params: Readonly<P>): readonly GenerationDiagnostic[];
|
|
103
|
+
/** Clears optional caches without invalidating captured snapshots. */
|
|
104
|
+
clearCache(): void;
|
|
105
|
+
/** Releases session ownership; idempotent, captured snapshots remain usable. */
|
|
106
|
+
dispose(): void;
|
|
107
|
+
}
|
|
29
108
|
/**
|
|
30
109
|
* Manufacturing buffers accepted by the snapshot exporter.
|
|
31
110
|
*/
|
|
@@ -59,17 +138,35 @@ export { defaultModelingLimits };
|
|
|
59
138
|
/** URL of the package's pinned WASM asset; browser bundlers may replace it with their emitted URL. */
|
|
60
139
|
export declare const modelingWasmUrl: string;
|
|
61
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Runs declaration and immediate assertions without initializing a kernel or finalizing parts.
|
|
143
|
+
* Geometry observations require an initialized session's `validate` method instead.
|
|
144
|
+
*/
|
|
145
|
+
export declare function validateModel<P, S>(program: ModelProgram<P, S>, params: Readonly<P>, ...settings: keyof S extends never ? [options?: SessionOptions<S>] : [options: SessionOptions<S> & {
|
|
146
|
+
readonly services: S;
|
|
147
|
+
}]): readonly GenerationDiagnostic[];
|
|
62
148
|
/**
|
|
63
149
|
* Initializes one host kernel and returns a lifecycle-safe engine. No generator initializes WASM.
|
|
64
150
|
*
|
|
65
151
|
* @example Build a box in a host application
|
|
66
152
|
* ```ts
|
|
67
|
-
* import { box } from "@metamesh/modeling";
|
|
153
|
+
* import { box, generate } from "@metamesh/modeling";
|
|
68
154
|
* import { createModelEngine } from "@metamesh/modeling/engine";
|
|
69
155
|
*
|
|
70
156
|
* const engine = await createModelEngine();
|
|
71
|
-
* const
|
|
157
|
+
* const model = generate<Record<never, never>>(({ part }) => [part("body", box({ size: [30, 20, 8] }))]);
|
|
158
|
+
* const session = engine.createSession(model);
|
|
159
|
+
* try {
|
|
160
|
+
* const snapshot = session.run({});
|
|
161
|
+
* try {
|
|
162
|
+
* await engine.export3mf(snapshot.parts);
|
|
163
|
+
* } finally {
|
|
164
|
+
* snapshot.dispose();
|
|
165
|
+
* }
|
|
166
|
+
* } finally {
|
|
167
|
+
* session.dispose();
|
|
168
|
+
* }
|
|
72
169
|
* ```
|
|
73
170
|
*/
|
|
74
171
|
export declare function createModelEngine(options?: ModelEngineOptions): Promise<ModelEngine>;
|
|
75
|
-
export type {
|
|
172
|
+
export type { ModelingLimits };
|