@metamesh/modeling 0.6.0 → 0.8.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 +30 -0
- package/README.md +157 -22
- package/dist/api/engine.d.ts +25 -4
- package/dist/api/geometry.d.ts +391 -82
- package/dist/api/index.d.ts +732 -108
- package/dist/api/text.d.ts +40 -10
- package/dist/engine/construction-operations.js +52 -10
- package/dist/engine/execution.js +55 -2
- package/dist/engine/export-3mf.js +17 -1
- package/dist/engine/finalization.js +27 -18
- package/dist/engine/index.js +12 -1
- package/dist/engine/inspection-operations.js +26 -22
- package/dist/engine/loft-operations.js +1 -1
- package/dist/engine/mechanical-operations.js +5 -8
- package/dist/engine/mesh-view-cache.js +23 -0
- package/dist/engine/native/adapter.js +2 -4
- package/dist/engine/native/distance.js +42 -0
- package/dist/engine/native/status.js +16 -0
- package/dist/engine/operation-environment.js +2 -1
- package/dist/engine/section-operations.js +3 -3
- package/dist/geometry/curves/sampling.js +2 -1
- package/dist/geometry/heightfield.js +109 -42
- package/dist/geometry/index.js +2 -0
- package/dist/geometry/loft-simple-mesh.js +2 -3
- package/dist/geometry/loft-triangulation.js +12 -9
- package/dist/geometry/loft.js +18 -7
- package/dist/geometry/math/vector3.js +35 -5
- package/dist/geometry/mechanical/standards.js +2 -3
- package/dist/geometry/mechanical/thread-profiles.js +5 -0
- package/dist/geometry/mechanical/threads.js +2 -3
- package/dist/geometry/mesh-centroid.js +36 -0
- package/dist/geometry/mesh-edge-table.js +126 -0
- package/dist/geometry/mesh-solid-intersections.js +123 -0
- package/dist/geometry/mesh-solid.js +284 -0
- package/dist/geometry/mesh.js +8 -25
- package/dist/geometry/paths/path.js +3 -1
- package/dist/geometry/paths/resampling.js +2 -1
- package/dist/geometry/profiles/matched.js +8 -0
- package/dist/geometry/profiles/profiles.js +24 -3
- package/dist/geometry/profiles/rectangle.js +16 -2
- package/dist/geometry/profiles/shapes.js +8 -1
- package/dist/geometry/revolve/revolve-mesh.js +6 -0
- package/dist/geometry/sweeps/sweep-closed.js +4 -4
- package/dist/geometry/sweeps/sweep-mesh.js +13 -7
- package/dist/geometry/sweeps/sweep-open.js +4 -4
- package/dist/geometry/sweeps/validation.js +1 -2
- package/dist/model/operations.js +13 -4
- package/dist/text/index.js +11 -1
- package/dist/text/vector-text-layout.js +46 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @metamesh/modeling
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bf1abe4: Add circular baselines to prepared vector text and Generator text services. Shaped glyphs and attached marks rotate rigidly around a millimetre radius, preserving kerning, ligatures, exact curve bounds and logical advances. Circular text is limited to one line, baseline vertical alignment, less than one revolution, and outlines that stay clear of the circle's center axis.
|
|
8
|
+
- bf1abe4: Complete solid splitting, plane clipping, Section hull/component/simplification operations, minimum-distance
|
|
9
|
+
queries and inspection facts. Add optional bounded geometric solid
|
|
10
|
+
validation at build/export boundaries and a pure uniform-density volume centroid helper.
|
|
11
|
+
Reuse immutable native inspection facts within a build and fresh owned topology analysis during
|
|
12
|
+
solid validation; share checks for identical buffer ranges without trusting mutable external facts.
|
|
13
|
+
|
|
14
|
+
Unify SVG default/preset limits and strict preset metadata checks. Preserve structured validation
|
|
15
|
+
codes and nested paths, add physical mesh assertions, and require runtime 2.1 for the current host
|
|
16
|
+
surface and issue metadata.
|
|
17
|
+
|
|
18
|
+
- bf1abe4: Add explicit uneven XY coordinates and optional shorter-edge or centre-error diagonal selection to heightfield and heightfieldMesh. Preserve uniform-grid sampling and fixed triangulation by default, with unchanged mesh allocation counts and strict Float32 coordinate checks.
|
|
19
|
+
|
|
20
|
+
Reject out-of-range section miter limits and inherited names in mechanical standards and thread-fit lookups. Avoid copying section polygons when only their count is needed.
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- bf1abe4: Reject cap triangulation workloads that cannot fit the comparison budget before ear clipping, preserving the existing work ceiling and input vertices.
|
|
25
|
+
- bf1abe4: Detect triangle crossings when an edge endpoint lies within the solid-validation tolerance, and avoid redundant topology analysis during solid validation.
|
|
26
|
+
|
|
27
|
+
## 0.7.0
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- b1b97b9: Reduce large-mesh finalization time and topology-analysis allocations without changing geometry, validation, or export output.
|
|
32
|
+
|
|
3
33
|
## 0.6.0
|
|
4
34
|
|
|
5
35
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@ Standalone geometry foundations and a modeling engine for Node applications, bro
|
|
|
4
4
|
|
|
5
5
|
> **Preview:** `0.x` minor releases may break compatibility. Patches remain compatible within the same minor line. Stable support requires an explicit `1.0.0` review.
|
|
6
6
|
|
|
7
|
-
Applications initialize one engine and build models with imported functions. Generator hosts
|
|
7
|
+
Applications initialize one engine and build models with imported functions. Generator hosts supply
|
|
8
|
+
the same execution scope and own WASM initialization and native cleanup. Modeling requires no SDK
|
|
9
|
+
or Testkit.
|
|
8
10
|
|
|
9
11
|
## API discovery and ownership
|
|
10
12
|
|
|
@@ -15,7 +17,10 @@ Applications initialize one engine and build models with imported functions. Gen
|
|
|
15
17
|
| `@metamesh/modeling/engine` | Host initialization, scoped modeling, finalization, resource limits, and snapshot export |
|
|
16
18
|
| `@metamesh/modeling/text` | Optional font-byte preparation and synchronous vector layout |
|
|
17
19
|
|
|
18
|
-
These four
|
|
20
|
+
These four entry points are the complete workspace and published API. Pure helpers cannot import
|
|
21
|
+
the engine, native kernel, browser APIs, Studio, or Generators. Fontkit and WOFF2 decoding are optional
|
|
22
|
+
peers used only by `/text`. Hosts own acquisition, worker lifecycle, and loading. API reports define
|
|
23
|
+
supported symbols; consumer fixtures verify published use.
|
|
19
24
|
|
|
20
25
|
## Modeling and lifecycle
|
|
21
26
|
|
|
@@ -51,11 +56,36 @@ const engine = await createModelEngine({ locateFile: () => modelingWasmUrl });
|
|
|
51
56
|
const snapshot = engine.build(() => box({ size: [10, 20, 30] }));
|
|
52
57
|
```
|
|
53
58
|
|
|
54
|
-
Imported functions and
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Builds
|
|
59
|
+
Imported functions and `ModelingContext` methods execute the same operations. Imports do not
|
|
60
|
+
initialize the kernel. The host binds the active context through a versioned symbol shared across
|
|
61
|
+
bundles, then clears it in `finally`. Calls outside `build` throw.
|
|
62
|
+
|
|
63
|
+
Builds are synchronous and cannot nest, including across engines in one JavaScript realm.
|
|
64
|
+
Hosts finish asynchronous loading and service preparation before `build`; separate Workers have
|
|
65
|
+
independent execution scopes.
|
|
66
|
+
An engine rejects builds or exports while its asynchronous exporter is busy.
|
|
67
|
+
|
|
68
|
+
`Solid` and `Section` are opaque immutable handles belonging to one synchronous build. Sections are
|
|
69
|
+
native filled XY shapes, including holes and disconnected components. `union`, `subtract`, and
|
|
70
|
+
`intersect` accept either Solid or Section operands and reject mixed dimensions. Offsets and Booleans
|
|
71
|
+
retain native sections; `fromRegion` and `toRegion` are explicit conversion boundaries. Repeated
|
|
72
|
+
sweeps and loft stations extract each Section once per execution; `toRegion` returns fresh immutable
|
|
73
|
+
snapshots.
|
|
74
|
+
|
|
75
|
+
Handles cannot cross builds or survive disposal. All native values dispose in reverse construction
|
|
76
|
+
order from `finally`, including on failure. Installed bundles call host-owned methods, avoiding
|
|
77
|
+
package-local native class or module identity.
|
|
78
|
+
|
|
79
|
+
Builds return a bare solid (part ID `model`) or named `{ id, solid, color? }` / `{ id, mesh, color? }`
|
|
80
|
+
descriptors. IDs are unique lowercase kebab-case strings of at most 64 characters; colors are
|
|
81
|
+
six-digit hex RGB. Direct meshes are copied and checked for finite, nondegenerate, oriented closed
|
|
82
|
+
topology and kernel reconstructability without copying them back from the kernel. Native extraction
|
|
83
|
+
allows one bounded retry for collapsed Float32 stitches.
|
|
84
|
+
|
|
85
|
+
Descriptors for the same Solid share one extraction, copied manufacturing buffers, and immutable
|
|
86
|
+
facts. `toTriangleMesh` inspection returns independent copies; mutable mesh inputs are captured and
|
|
87
|
+
validated afresh for every build. Finalized parts retain shared bounds, counts, signed volume, area,
|
|
88
|
+
and topology facts. Render normals remain outside manufacturing data.
|
|
59
89
|
|
|
60
90
|
Default limits are 64 parts, 1,000,000 vertices, 2,000,000 triangles, and 96 MiB of unique backing storage. Trusted applications may configure higher or lower ceilings through `createModelEngine({ limits })`. Per-build limits may only lower those configured ceilings, and snapshot export uses them too. Generator hosts own ceilings; generators receive no engine. Predictable allocations preflight safe-integer counts. Algorithm-specific numeric limits remain documented by their operations. Complexity fails explicitly instead of reducing fidelity.
|
|
61
91
|
|
|
@@ -72,9 +102,19 @@ work limits remain fixed operation safeguards.
|
|
|
72
102
|
|
|
73
103
|
`engine.export3mf` consumes selected finalized buffers without preparation or generation. Its lazy ZIP/XML serializer preserves exact selected vertices, triangle indices, semantic part names, and optional RGB display colors without a native or glTF conversion. Hosts own revisions, appearance overrides, filenames, delivery, and persistence.
|
|
74
104
|
|
|
105
|
+
Build and 3MF export accept `meshValidation: "solid"` for bounded geometric validation in addition
|
|
106
|
+
to their default indexed topology checks. This rejects intersecting/touching separate shells and
|
|
107
|
+
incorrectly oriented nested boundaries while preserving inward cavity shells. Checks apply to each
|
|
108
|
+
part independently; separate semantic parts may intentionally overlap. It uses the same pure
|
|
109
|
+
`validateSolidMesh` capability described below. Finalization reuses fresh topology facts for its
|
|
110
|
+
privately owned selected buffers; export captures mutable input before fresh analysis. Within one
|
|
111
|
+
operation, identical buffer ranges share checks. No caller-supplied or cross-operation facts are
|
|
112
|
+
trusted. Its additional work and failure ceilings are explicit;
|
|
113
|
+
the default `"topology"` mode retains the existing large-model workflow.
|
|
114
|
+
|
|
75
115
|
## Resolution and conventions
|
|
76
116
|
|
|
77
|
-
Primitive and pure loop factories share named options
|
|
117
|
+
Primitive and pure loop factories share named options and these conventions:
|
|
78
118
|
|
|
79
119
|
| Concept | Convention |
|
|
80
120
|
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -143,26 +183,48 @@ Boolean and other geometry construction results require deliberate definitions r
|
|
|
143
183
|
inheriting anchors that may no longer describe their surfaces. Custom rigid frames remain useful;
|
|
144
184
|
pure `boxAnchor3` and `cylinderAnchor3` calculate dimension-based frames without a native shape.
|
|
145
185
|
|
|
146
|
-
`GeometryResolution` defaults to 0.05 mm maximum chord error and 16–512 segments per complete circle.
|
|
186
|
+
`GeometryResolution` defaults to 0.05 mm maximum chord error and 16–512 segments per complete circle.
|
|
187
|
+
Precedence is exact local segments, operation resolution, context-derived resolution, then engine
|
|
188
|
+
defaults. Exact counts express deliberate faceting or fixed correspondence; adaptive curves retain
|
|
189
|
+
physical deviation and edge-length constraints.
|
|
190
|
+
|
|
191
|
+
`model.withResolution(policy)` and imported `modelingFunctions(policy)` return a local method set
|
|
192
|
+
for the same build. Destructure those methods to apply the local policy; other imports retain the
|
|
193
|
+
original build policy. There is no global resolution or font state.
|
|
147
194
|
|
|
148
195
|
Revolution `segments` describes a complete circle; partial revolutions scale that count to the
|
|
149
196
|
angular span and round up. Native filled revolutions need at least three intervals: adaptive
|
|
150
197
|
sampling refines to that minimum, while exact counts below it fail explicitly. Pure `revolveMesh`
|
|
151
198
|
supports one interval.
|
|
152
199
|
|
|
153
|
-
`resamplePolyline2` and `resamplePolyline3` share physical sampling options and return immutable
|
|
200
|
+
`resamplePolyline2` and `resamplePolyline3` share physical sampling options and return immutable
|
|
201
|
+
points with directed unit tangents. Open paths retain both endpoints; `closed: true` includes the
|
|
202
|
+
closing edge and omits a repeated seam vertex. Exact closed counts require at least three segments.
|
|
203
|
+
|
|
204
|
+
`regularPolygonLoop({ radius, sides, rotationDegrees, sizing })` creates a centered CCW point loop
|
|
205
|
+
with an implicit seam. `RadialSizing` defaults to `"vertex"`; `"face"` compensates polygon faceting
|
|
206
|
+
so the requested radius reaches the faces. `CylinderOptions` uses the same sizing option.
|
|
154
207
|
|
|
155
208
|
`normalizeLoop2`, `normalizePolygon2`, and `normalizeRegion2` return immutable geometry and may reuse internally validated results. External objects are validated even when frozen. Mutable mesh buffers are analyzed freshly at external boundaries; engine facts are reused inside their owner.
|
|
156
209
|
|
|
157
210
|
## Profiles and mechanical construction
|
|
158
211
|
|
|
159
|
-
`sampleOpenProfile` samples upward radius/height line and cubic chains. Consumers own closure and
|
|
212
|
+
`sampleOpenProfile` samples upward radius/height line and cubic chains. Consumers own closure and
|
|
213
|
+
product constraints. `circleLoop`, `rectangleLoop`, and other point factories return ordered loops.
|
|
214
|
+
`Profile` owns identified components, contours, and landmarks; `CorrespondingProfile` retains their
|
|
215
|
+
shared sampled slots.
|
|
216
|
+
|
|
217
|
+
`rectangle`, `rectangleLoop`, and `rectangleProfile` share `size`, `center`, and `treatment` options.
|
|
218
|
+
Use root primitives for ordinary modeling and pure loops/profiles for custom data and explicit
|
|
219
|
+
correspondence. Native filled sections do not promise stable vertex ordering.
|
|
160
220
|
|
|
161
221
|
For a closed planar XYZ path, map the canonical loop with
|
|
162
222
|
`rectangleLoop(options).map(([x, y]) => [x, y, 0] as const)`. Before sampling, cap its
|
|
163
223
|
`limits.maxProfilePoints` at the smaller selected profile and path point ceilings. This keeps
|
|
164
224
|
path allocation bounded and preserves all corner tangent endpoints and the implicit seam.
|
|
165
225
|
|
|
226
|
+
### Extrusion and sweep
|
|
227
|
+
|
|
166
228
|
`extrude(shape, { height, ... })`, `revolve(shape, options)` and `sweep(shape, path, options)` accept a filled Section or CorrespondingProfile, including holes and disconnected components. Open sweeps have watertight end caps; `closed: true` joins the path back to its beginning. Sweep options share degree twist, positive uniform or XY scale, and an XY scale pair per normalized path station. Closed scales interpolate along the implicit closing edge. A rotational symmetry seam uses `seamProfileOffset`, a counterclockwise logical point advance that reverses for clockwise hole contours; every contour must geometrically match the total twist. Incompatible seams fail explicitly.
|
|
167
229
|
|
|
168
230
|
Adaptive extrusion sampling bounds the entire side triangles, including the interaction between
|
|
@@ -194,6 +256,8 @@ policies. For a planar closed path whose profile X should stay vertical, request
|
|
|
194
256
|
`orientation: { kind: "transport", initialNormal: [0, 0, 1] }`. Closed policies use cyclic tangents
|
|
195
257
|
and the same first frame on their closing gap.
|
|
196
258
|
|
|
259
|
+
### Loft correspondence
|
|
260
|
+
|
|
197
261
|
`loft(stations, options)` accepts a `profile` and exactly one horizontal `z` height or explicit
|
|
198
262
|
right-handed `frame` per station. Stations stay in input order. Ordinary primitives keep the
|
|
199
263
|
simple case at the root entry point:
|
|
@@ -213,7 +277,7 @@ With omitted `correspondence`, compatible rectangle stations, circle/ellipse rin
|
|
|
213
277
|
regular polygons and equal-pointed stars use their retained authored landmarks. Rectangle corners
|
|
214
278
|
can change among square, round and chamfer treatments, including collapsed or saturated rounds.
|
|
215
279
|
Circle/ellipse and rectangle stations also share those quadrant/corner landmarks: a circular
|
|
216
|
-
inlet
|
|
280
|
+
inlet can become a rounded rectangle directly.
|
|
217
281
|
Exact circular counts for this mixed family must divide by four; other deliberately faceted counts
|
|
218
282
|
need an explicit geometric method. Adaptive counts align upward within the selected ceilings.
|
|
219
283
|
XY affine transforms preserve these identities; this semantic path requires consistent handedness.
|
|
@@ -250,6 +314,13 @@ then next-only advances. Its objective sums connection lengths with the closing
|
|
|
250
314
|
No tangent/supporting-plane association is exposed: general concave and spatial stations do not
|
|
251
315
|
provide the convexity contract that such a method needs.
|
|
252
316
|
|
|
317
|
+
Identified `ProfileSpan2` supports lines, arcs, and cubic Béziers with `start`, `control1`, `control2`,
|
|
318
|
+
and `end`. Cubics reuse the curve evaluator and physical subdivision policy, selecting one uniform
|
|
319
|
+
parameter grid for corresponding spans. Fully collapsed spans retain logical slots without moving
|
|
320
|
+
endpoints. Sampled contours and components use `CorrespondingContour` and `CorrespondingComponent`.
|
|
321
|
+
Pass the complete family to `matchProfiles` with optional `limits.maxProfilePoints`; its default is
|
|
322
|
+
100,000 points per profile, while a separate one-million-slot family work bound remains in force.
|
|
323
|
+
|
|
253
324
|
For precise custom correspondence, prepare `matchProfiles` over explicit `Profile` specifications.
|
|
254
325
|
It chooses the maximum physical interval count for each paired span across the family, including
|
|
255
326
|
span-local `resolution`; identified line, arc and cubic kinds may change while IDs, order and
|
|
@@ -262,8 +333,12 @@ All loft routes share `LoftOptions`. Pure `loftMesh` requires an explicit method
|
|
|
262
333
|
closed simple-loop mesh without an engine. Selected sampling/output budgets apply before expanded
|
|
263
334
|
grids and mesh buffers; fixed aggregate safeguards bound correspondence at eight million comparisons
|
|
264
335
|
and the complete grid at one million logical slots. Simple-loop cap triangulation also has an
|
|
265
|
-
eight-million-comparison work ceiling.
|
|
266
|
-
|
|
336
|
+
eight-million-comparison work ceiling. Caps whose minimum comparison count exceeds that ceiling
|
|
337
|
+
reject before ear clipping; other caps retain the running work check. Complexity rejects instead of
|
|
338
|
+
reducing fidelity or substituting another method. Pure counterparts also include `sweepMesh`,
|
|
339
|
+
`extrudeMesh` and `revolveMesh`.
|
|
340
|
+
|
|
341
|
+
### Patterns and bounded surfaces
|
|
267
342
|
|
|
268
343
|
`linearPattern(shape, { count, length })` determines equal intervals from exactly two of `count`,
|
|
269
344
|
signed `spacing`, and signed total `length`; its direction defaults to +X. Length and spacing must
|
|
@@ -279,23 +354,64 @@ algorithm ceiling and selected output budgets reject before predictable native c
|
|
|
279
354
|
varying factories are checked cumulatively before each transform. Path input and placement counts
|
|
280
355
|
also obey `maxPathPoints`. Copies use the shared transform and lifetime checks.
|
|
281
356
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
357
|
+
`heightfield` returns a Solid for transforms and booleans; `heightfieldMesh` returns the same
|
|
358
|
+
closed construction as pure indexed data. Supply `size`, `segments`, and optional `origin` for a
|
|
359
|
+
uniform grid, or `coordinates: { x, y }` for absolute, unevenly spaced XY samples. Explicit axes
|
|
360
|
+
must increase strictly and remain distinct in Float32. This lets callers refine narrow borders
|
|
361
|
+
without remapping mesh vertices. Heights remain absolute Z values strictly above `baseZ` (default
|
|
362
|
+
zero); sampling never rescales the field.
|
|
363
|
+
|
|
364
|
+
`triangulation` defaults to `"fixed"`, preserving the lower-left to upper-right diagonal.
|
|
365
|
+
`"min-edge"` chooses the shorter 3D diagonal without extra sampling. `"center-error"` samples the
|
|
366
|
+
physical cell centre once and chooses the diagonal whose interpolated height is closer there.
|
|
367
|
+
Ties retain the fixed diagonal. Every policy uses two top triangles per cell and the same closed
|
|
368
|
+
walls and flat base; centre agreement does not guarantee accuracy elsewhere. Allocation and
|
|
369
|
+
coordinate precision are checked before height callbacks. Each grid point is sampled once, with
|
|
370
|
+
one additional callback per cell for `"center-error"`.
|
|
288
371
|
|
|
289
|
-
|
|
372
|
+
```ts
|
|
373
|
+
heightfield({
|
|
374
|
+
coordinates: { x: [-15, -14.5, 0, 14.5, 15], y: [-10, -9.5, 0, 9.5, 10] },
|
|
375
|
+
triangulation: "min-edge",
|
|
376
|
+
height: ([x, y]) => 3 + Math.cos(x / 5) * Math.cos(y / 5),
|
|
377
|
+
});
|
|
378
|
+
```
|
|
290
379
|
|
|
291
380
|
Pure mechanical modules own thread profiles, sampling, printable fit, meshes, and allocation-free `preflightThreadedRod`, `preflightInternalThreadCutter`, and `preflightThreadedNut`. Engine methods own native construction. `pitch` is adjacent axial spacing; `lead = pitch × starts` is advance per turn. Internal cutters extend beyond requested faces and compensate faceting while preserving end treatments. Printable modeling forms are not certified thread classes or structural ratings.
|
|
292
381
|
|
|
382
|
+
`split(solid, cutter)` returns intersection followed by subtraction as two same-build handles.
|
|
383
|
+
`splitByPlane(solid, { normal, offset })` returns the positive-normal side followed by the negative
|
|
384
|
+
side. Destructure `[positive]` or `[, negative]` to retain just one side. The nonzero normal is
|
|
385
|
+
normalized and `offset` is the signed distance from the world origin in millimetres (default zero).
|
|
386
|
+
Empty results are valid handles
|
|
387
|
+
for `isEmpty`, inspection and further operations, but cannot be finalized as manufacturing parts.
|
|
388
|
+
|
|
389
|
+
`hull` accepts Solid inputs/XYZ points or Section inputs/XY points. `components` and `simplify`
|
|
390
|
+
also preserve either dimension. Solid components are disconnected surface shells: inward cavity
|
|
391
|
+
shells count separately in `inspectSolid().parts` and cannot be finalized alone. Section components
|
|
392
|
+
are filled islands that retain their holes. `inspectSolid` includes surface area, native tolerance and emptiness;
|
|
393
|
+
`inspectSection` includes emptiness. Both return immutable native facts shared by repeated
|
|
394
|
+
inspections of the same shape within one build, including aliases and derived resolution contexts.
|
|
395
|
+
Transforms, Booleans and tolerance changes have their own facts. The execution clears these caches
|
|
396
|
+
on disposal; retained facts contain no live native values.
|
|
397
|
+
|
|
398
|
+
`distance(a, b)` measures the minimum separation between two nonempty solids in millimetres.
|
|
399
|
+
It returns zero for contact or overlapping material. The kernel's search range is managed internally;
|
|
400
|
+
there is no caller-supplied distance cutoff. Queries use native geometry and precision without
|
|
401
|
+
extracting a triangle mesh; empty, expired and foreign-build handles reject.
|
|
402
|
+
|
|
403
|
+
Installed Generators using these added host operations or Section overloads declare minimum runtime
|
|
404
|
+
2.1.0. Imported operations require the current host context; package metadata declares the runtime
|
|
405
|
+
capabilities the Generator uses.
|
|
406
|
+
|
|
293
407
|
`implicit` samples a finite positive-inside field within explicit bounds and grid spacing. Grid allocations and field evaluations are bounded. `components` returns same-build handles. `simplify` requires explicit millimetre tolerance and preserves native original-surface cleanup semantics.
|
|
294
408
|
|
|
295
409
|
## Prepared text and SVG
|
|
296
410
|
|
|
297
411
|
Preparation shapes text once with the host's exact font service and retains immutable `VectorTextLayout`. Imported `textSection(layout, options)` consumes vector paths directly, without font shaping, fetching, or ambient providers. Paths and metrics use Y-up millimetres and a baseline origin. Empty layouts are measurable but cannot create sections. Font preparation remains optional and outside synchronous builds.
|
|
298
412
|
|
|
413
|
+
`baseline: { kind: "arc", radius }` places one line on a circle centered at the XY origin, in millimetres. Alignment defaults to `"center"` at `centerAngleDegrees` (90° from +X by default); `"left"` and `"right"` place the logical start and end at that datum. Direction defaults to `"clockwise"`, giving upright top lettering at 90°; `"counterclockwise"` at 270° gives upright bottom lettering. Shaped glyphs and attached zero-advance marks rotate rigidly, preserving their proportions, kerning and ligatures. Exact ink bounds describe the placed curves; `logicalWidth` and `advance[0]` retain the unwrapped arc length including spaces. Radius must be positive and at most 10000 mm. Arcs require baseline vertical alignment and reject multiline text, logical spans of a full revolution, and glyph outlines crossing the circle's center axis. Adjacent glyph collision and fit within a particular face remain consumer policy.
|
|
414
|
+
|
|
299
415
|
Install `fontkit` to use `prepareVectorFont` from `/text`, and `woff2-encoder` when decoding WOFF2. These optional peers are loaded only when preparing fonts. `sampleTextContours` from `/geometry` and `textSection` share bounded path sampling and need no font dependencies for an already prepared layout.
|
|
300
416
|
|
|
301
417
|
`svgSection` imports bounded painted SVG documents; `svgPathSection` imports filled path data. Y-down coordinates convert to Y-up; nonzero/even-odd filling preserves counters. Sampling applies after transforms and unit conversion. Basic shapes, groups, affine transforms, physical units, viewBox, fills, and strokes are supported. Text must be outlined. External resources, scripts, clipping, masks, filters, and unsupported content fail contextually. Pure parsers are shared with validation and the vector editor.
|
|
@@ -304,7 +420,26 @@ Install `fontkit` to use `prepareVectorFont` from `/text`, and `woff2-encoder` w
|
|
|
304
420
|
|
|
305
421
|
`analyzeTriangleMesh` validates and supplies bounds, counts, area, and signed volume in one traversal, with optional edge/component facts. Measurements, bounds, and signatures are independent immutable snapshots; external mutable buffers are inspected freshly on each call. Closed-edge checks require two oppositely wound faces per edge; they do not detect every geometric self-intersection. `createTriangleMeshSignature` adds quantized bounds, volume, topology, and a regression fingerprint, not a cryptographic digest.
|
|
306
422
|
|
|
307
|
-
|
|
423
|
+
Pure `validateSolidMesh(mesh, options)` adds spatial triangle tests, a single closed incident fan at
|
|
424
|
+
every vertex, and shell containment/orientation checks, including cavity boundaries and islands.
|
|
425
|
+
It never repairs or changes input buffers.
|
|
426
|
+
Floating-point contacts within the selected `tolerance` reject conservatively; this is not an exact
|
|
427
|
+
predicate or a manufacturing certification. Its fixed ceilings are 200,000 triangles and 2,000,000
|
|
428
|
+
spatial/containment tests. `maximumTests` may lower the work ceiling. Exhaustion throws
|
|
429
|
+
`COMPLEXITY_LIMIT` and never returns an unchecked result. All position vertices must be referenced.
|
|
430
|
+
|
|
431
|
+
`computeTriangleMeshCentroid(mesh)` returns an immutable uniform-density volume centroid in
|
|
432
|
+
millimetres for consistently oriented closed geometry, accounting for inward cavity shells.
|
|
433
|
+
It checks indexed closure and positive aggregate volume; use solid validation first for untrusted
|
|
434
|
+
geometric shell arrangements.
|
|
435
|
+
|
|
436
|
+
The optional `meshTopologyMode: "optimized"` build setting runs bounded planar edge flips for either
|
|
437
|
+
execution lane. It preserves vertices, boundaries, winding, closure, reconstructability, area, and
|
|
438
|
+
volume. This is local connectivity cleanup, not general remeshing; source buffers never change in place.
|
|
439
|
+
|
|
440
|
+
Models above 200,000 triangles skip optimization. Unsupported or failed candidates retain their
|
|
441
|
+
original part, as do models whose optimized buffers would exceed an execution ceiling. Equal shared
|
|
442
|
+
mesh views reuse one optimized candidate.
|
|
308
443
|
|
|
309
444
|
## Quality gates
|
|
310
445
|
|
package/dist/api/engine.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ declare const defaultModelingLimits: Readonly<ModelingLimits>;
|
|
|
6
6
|
|
|
7
7
|
/** Execution settings supplied by the host, independently of generator metadata. */
|
|
8
8
|
export interface BuildOptions {
|
|
9
|
+
/** Optional bounded intersection and nested-shell checks; defaults to indexed topology validation. */
|
|
10
|
+
readonly meshValidation?: "topology" | "solid";
|
|
9
11
|
/** Per-build limits, no larger than the configured engine ceilings. */
|
|
10
12
|
readonly limits?: Partial<ModelingLimits>;
|
|
11
13
|
/** Physical sampling defaults; model-derived contexts and exact counts override these. */
|
|
@@ -13,7 +15,9 @@ export interface BuildOptions {
|
|
|
13
15
|
/** Optional bounded planar cleanup; unsupported candidates preserve the original part. */
|
|
14
16
|
readonly meshTopologyMode?: "original" | "optimized";
|
|
15
17
|
}
|
|
16
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Host engine. No native values or manually disposable handles are exposed.
|
|
20
|
+
*/
|
|
17
21
|
export interface ModelEngine {
|
|
18
22
|
/** Immutable resource ceilings selected when this engine was initialized. */
|
|
19
23
|
readonly limits: ModelingLimits;
|
|
@@ -22,15 +26,21 @@ export interface ModelEngine {
|
|
|
22
26
|
/** Serializes already finalized mesh parts; never prepares or builds a generator again. */
|
|
23
27
|
export3mf(parts: readonly ExportMeshPart[], options?: Export3mfOptions): Promise<ArrayBuffer>;
|
|
24
28
|
}
|
|
25
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Manufacturing buffers accepted by the snapshot exporter.
|
|
31
|
+
*/
|
|
26
32
|
export interface ExportMeshPart extends TriangleMesh {
|
|
27
33
|
/** Stable canonical lowercase identity; unique within the containing topology or output. */
|
|
28
34
|
readonly id: string;
|
|
29
35
|
/** Optional six-digit hex RGB display color. */
|
|
30
36
|
readonly color?: string;
|
|
31
37
|
}
|
|
32
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Completed-snapshot serialization settings; filename selection belongs to the host.
|
|
40
|
+
*/
|
|
33
41
|
export interface Export3mfOptions {
|
|
42
|
+
/** Optional bounded geometric solid checks on captured buffers; defaults to indexed topology validation. */
|
|
43
|
+
readonly meshValidation?: "topology" | "solid";
|
|
34
44
|
/** Document display name; defaults to MetaMesh model. */
|
|
35
45
|
readonly name?: string;
|
|
36
46
|
}
|
|
@@ -49,6 +59,17 @@ export { defaultModelingLimits };
|
|
|
49
59
|
/** URL of the package's pinned WASM asset; browser bundlers may replace it with their emitted URL. */
|
|
50
60
|
export declare const modelingWasmUrl: string;
|
|
51
61
|
|
|
52
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Initializes one host kernel and returns a lifecycle-safe engine. No generator initializes WASM.
|
|
64
|
+
*
|
|
65
|
+
* @example Build a box in a host application
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { box } from "@metamesh/modeling";
|
|
68
|
+
* import { createModelEngine } from "@metamesh/modeling/engine";
|
|
69
|
+
*
|
|
70
|
+
* const engine = await createModelEngine();
|
|
71
|
+
* const snapshot = engine.build(() => box({ size: [30, 20, 8] }));
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
53
74
|
export declare function createModelEngine(options?: ModelEngineOptions): Promise<ModelEngine>;
|
|
54
75
|
export type { BuildOutput, FinalizedModel, FinalizedPart, ModelingContext, ModelingLimits, GeometryResolution, GeometrySamplingLimits, };
|