partforge 0.144.0 → 0.145.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/package.json +1 -1
- package/src/framework/core/bvh-core.js +118 -0
- package/src/framework/core/core-wasm.js +6 -0
- package/src/framework/core/core.js +127 -0
- package/src/framework/core/creased-normals-core.js +143 -0
- package/src/framework/geometry/blend-surfaces.js +32 -2
- package/src/framework/geometry/creased-normals.js +26 -5
- package/src/framework/geometry/js-math.js +14 -0
- package/src/framework/geometry/manifold-backend.js +53 -11
- package/src/framework/geometry/mesh-roundall.js +116 -0
- package/src/framework/oracle/bvh.js +41 -2
- package/src/framework/oracle/gaps.js +14 -9
- package/src/framework/oracle/measure.js +7 -2
- package/src/framework/oracle/min-wall.js +11 -2
- package/src/oracle.js +3 -0
- package/types/oracle.d.ts +2 -0
- package/types/testing.d.ts +10 -0
package/package.json
CHANGED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// The oracle's triangle BVH and min-wall pass on the native core
|
|
2
|
+
// (native/bvh.cpp) — the same queries and results as oracle/bvh.js and
|
|
3
|
+
// oracle/min-wall.js, bit for bit.
|
|
4
|
+
//
|
|
5
|
+
// A core BVH lives in WebAssembly memory, so unlike the JS one it must be FREED:
|
|
6
|
+
// `dispose()`. The oracle's own callers do that — measure() for the Map it owns,
|
|
7
|
+
// meshGaps() for BVHs it built without one — and a FinalizationRegistry is the
|
|
8
|
+
// backstop for anything else. Only partforge's own call paths get these (see
|
|
9
|
+
// cachedBVH); the public buildBVH() and a caller-supplied bvhCache stay JS.
|
|
10
|
+
//
|
|
11
|
+
// Every query has a JS twin to fall back on — `jsIndex()`, the JS BVH of the
|
|
12
|
+
// same mesh, built on first need. A fault inside the module poisons the instance
|
|
13
|
+
// (core.js) and the query is answered by that twin instead, as is a distanceTo
|
|
14
|
+
// whose other side is not a core BVH of the same instance.
|
|
15
|
+
import { poisonCore, releaseIfIdle } from "./core.js";
|
|
16
|
+
|
|
17
|
+
const registry = typeof FinalizationRegistry === "function"
|
|
18
|
+
? new FinalizationRegistry(({ c, handle }) => {
|
|
19
|
+
c.live--;
|
|
20
|
+
if (!c.poisoned) c.x.bvh_destroy(handle);
|
|
21
|
+
releaseIfIdle(c);
|
|
22
|
+
})
|
|
23
|
+
: null;
|
|
24
|
+
|
|
25
|
+
const pt = (a, i) => (Number.isNaN(a[i]) ? null : [a[i], a[i + 1], a[i + 2]]);
|
|
26
|
+
|
|
27
|
+
// `verts`: bvh.js's triangleVertices(mesh) — 9 coords per triangle, mesh order.
|
|
28
|
+
// `makeJsIndex`: builds the JS BVH of the same mesh (the fallback), on demand.
|
|
29
|
+
// Throws if the module faults while building; the caller falls back.
|
|
30
|
+
export function buildCoreBVH(c, verts, makeJsIndex) {
|
|
31
|
+
const { x } = c;
|
|
32
|
+
const ptr = c.alloc(verts.byteLength);
|
|
33
|
+
new Uint8Array(x.memory.buffer, ptr, verts.byteLength).set(new Uint8Array(verts.buffer, verts.byteOffset, verts.byteLength));
|
|
34
|
+
// adopt = 1: the C++ index owns the vertex buffer from here (no second copy)
|
|
35
|
+
const handle = x.bvh_build(ptr, verts.length / 9, verts instanceof Float64Array ? 1 : 0, 1);
|
|
36
|
+
x.bvh_root_bounds(handle, c.scratch + 64);
|
|
37
|
+
const rb = c.f64().slice(8, 14);
|
|
38
|
+
c.live++;
|
|
39
|
+
let live = true, js = null;
|
|
40
|
+
const token = {};
|
|
41
|
+
registry?.register(token, { c, handle }, token);
|
|
42
|
+
const jsIndex = () => (js ??= makeJsIndex());
|
|
43
|
+
// Run `fn` on the core, or answer with `fallback` if the instance is (or
|
|
44
|
+
// becomes) unusable.
|
|
45
|
+
const guarded = (fn, fallback) => {
|
|
46
|
+
if (!live) throw new Error("core BVH used after dispose()");
|
|
47
|
+
if (c.poisoned) return fallback();
|
|
48
|
+
try {
|
|
49
|
+
return fn();
|
|
50
|
+
} catch {
|
|
51
|
+
poisonCore(c);
|
|
52
|
+
return fallback();
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const self = {
|
|
56
|
+
core: c,
|
|
57
|
+
triangleCount: verts.length / 9,
|
|
58
|
+
rootBounds: [rb[0], rb[1], rb[2], rb[3], rb[4], rb[5]],
|
|
59
|
+
get handle() { return handle; },
|
|
60
|
+
jsIndex,
|
|
61
|
+
raycast(origin, dir, opts = {}) {
|
|
62
|
+
const { tMin = 1e-6, tMax = Infinity, skipTri = -1 } = opts;
|
|
63
|
+
return guarded(() => {
|
|
64
|
+
const s = c.f64();
|
|
65
|
+
s[0] = origin[0]; s[1] = origin[1]; s[2] = origin[2]; s[3] = dir[0]; s[4] = dir[1]; s[5] = dir[2];
|
|
66
|
+
const tri = x.bvh_raycast(handle, c.scratch, c.scratch + 24, tMin, tMax, skipTri, c.scratch + 64);
|
|
67
|
+
return tri === -1 ? null : { t: c.f64()[8], tri };
|
|
68
|
+
}, () => jsIndex().raycast(origin, dir, opts));
|
|
69
|
+
},
|
|
70
|
+
closestPoint(p) {
|
|
71
|
+
return guarded(() => {
|
|
72
|
+
const s = c.f64();
|
|
73
|
+
s[0] = p[0]; s[1] = p[1]; s[2] = p[2];
|
|
74
|
+
const tri = x.bvh_closest_point(handle, c.scratch, c.scratch + 64);
|
|
75
|
+
const o = c.f64();
|
|
76
|
+
return { point: tri === -1 ? null : [o[8], o[9], o[10]], dist: o[11], tri };
|
|
77
|
+
}, () => jsIndex().closestPoint(p));
|
|
78
|
+
},
|
|
79
|
+
// Exact minimum surface-to-surface distance. Two core BVHs of the same live
|
|
80
|
+
// instance meet in C++; anything else (a JS index, another instance) meets
|
|
81
|
+
// through the JS twins.
|
|
82
|
+
distanceTo(other) {
|
|
83
|
+
const viaJs = () => jsIndex().distanceTo(other?.jsIndex ? other.jsIndex() : other);
|
|
84
|
+
if (other?.core !== c || other.core.poisoned) return viaJs();
|
|
85
|
+
return guarded(() => {
|
|
86
|
+
const ok = x.bvh_distance_to(handle, other.handle, c.scratch + 64);
|
|
87
|
+
if (!ok) return { distance: Infinity, at: null, pointA: null, pointB: null };
|
|
88
|
+
const r = c.f64();
|
|
89
|
+
return { distance: r[8], at: [r[9], r[10], r[11]], pointA: [r[12], r[13], r[14]], pointB: [r[15], r[16], r[17]] };
|
|
90
|
+
}, viaJs);
|
|
91
|
+
},
|
|
92
|
+
// minWall over this index, min-wall.js's result shape exactly. min-wall.js
|
|
93
|
+
// dispatches here with its own resolved options; `undefined` means "the core
|
|
94
|
+
// could not answer — run the JS pass" (null is a real answer: empty mesh).
|
|
95
|
+
minWall({ maxThickness, maxSamples, band = null }) {
|
|
96
|
+
return guarded(() => {
|
|
97
|
+
const ok = x.bvh_min_wall(handle, maxThickness == null ? 0 : 1, maxThickness == null ? 0 : maxThickness,
|
|
98
|
+
maxSamples, band ? 1 : 0, band ? band.min : 0, band ? band.max : 0, c.scratch + 64);
|
|
99
|
+
if (!ok) return null;
|
|
100
|
+
const r = c.f64().slice(8, 20);
|
|
101
|
+
return {
|
|
102
|
+
value: Number.isNaN(r[0]) ? null : r[0], location: pt(r, 1), sampled: r[4] === 1,
|
|
103
|
+
sampledTriangles: r[5], totalTriangles: r[6],
|
|
104
|
+
band: band ? { value: Number.isNaN(r[7]) ? null : r[7], location: pt(r, 8), members: r[11] } : null,
|
|
105
|
+
};
|
|
106
|
+
}, () => undefined);
|
|
107
|
+
},
|
|
108
|
+
dispose() {
|
|
109
|
+
if (!live) return;
|
|
110
|
+
live = false;
|
|
111
|
+
registry?.unregister(token);
|
|
112
|
+
c.live--;
|
|
113
|
+
if (!c.poisoned) x.bvh_destroy(handle);
|
|
114
|
+
releaseIfIdle(c);
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
return self;
|
|
118
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// GENERATED by scripts/build-core-wasm.mjs from native/ — do not edit by hand.
|
|
2
|
+
// emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 6.0.10-git
|
|
3
|
+
// 64176 bytes of WebAssembly. test/core-wasm.test.js checks the hash below
|
|
4
|
+
// against native/ so a C++ change without a rebuild fails.
|
|
5
|
+
export const CORE_SOURCE_HASH = "1192dae0d7f327873d13d953ff8011be87313260719c05f5a5ba9a569f7eb867";
|
|
6
|
+
export const CORE_WASM_BASE64 = "AGFzbQEAAAABwgEYYAF/AX9gAX8AYAN/f38Bf2ACf38AYAR/f39/AX9gAABgA39/fwBgAn9/AX9gBX9/f39/AGAEf39/fwBgB39/f3x8f38Bf2AEf35/fwF/YAZ/f39/f38AYAV/f39/fwF8YAh/f3x8f3x8fwF/YAh/f39/f39/fwBgC39/f39/f39/f39/AX9gDX9/f39/f3x8f39/f38AYAN/fn8BfmACfH8BfGAFf39/f38Bf2ACfn8Bf2AHf3x/f39/fwF/YAABfwKMAQQDZW52H2Vtc2NyaXB0ZW5fbm90aWZ5X21lbW9yeV9ncm93dGgAARZ3YXNpX3NuYXBzaG90X3ByZXZpZXcxCGZkX2Nsb3NlAAAWd2FzaV9zbmFwc2hvdF9wcmV2aWV3MQhmZF93cml0ZQAEFndhc2lfc25hcHNob3RfcHJldmlldzEHZmRfc2VlawALA0dGBQMFBQQJBgABAQEDBAMHAQwIAAMKCgECDQIJDgEIDxARBAAAAAAAAAABAAEAAAACBwAAAAISAAcTFAYABhUIFgMBAwEXAwQFAXABDAwFBwEBgAKAgAIGCAF/AUGwlwQLB6MDGgZtZW1vcnkCABlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQAJYnZoX2J1aWxkABAGbWFsbG9jAC4SYnZoX3RyaWFuZ2xlX2NvdW50ABYPYnZoX3Jvb3RfYm91bmRzABcLYnZoX3JheWNhc3QAGBFidmhfY2xvc2VzdF9wb2ludAAbD2J2aF9kaXN0YW5jZV90bwAdDGJ2aF9taW5fd2FsbAAfC2J2aF9kZXN0cm95ACAEZnJlZQAvCWNuX2NyZWF0ZQAjCWNuX2ZpbmlzaAAkDGNuX3Bvc2l0aW9ucwAmCmNuX25vcm1hbHMAJwhjbl9lZGdlcwAoDmNuX2VkZ2VfZmxvYXRzACkOY25fZmVhdHVyZV9pZHMAKhBjbl9mZWF0dXJlX2NvdW50ACsRY25fZmVhdHVyZV9sYWJlbHMALApjbl9kZXN0cm95AC0LX2luaXRpYWxpemUABAhzZXRUaHJldwBJGV9lbXNjcmlwdGVuX3N0YWNrX3Jlc3RvcmUARxxlbXNjcmlwdGVuX3N0YWNrX2dldF9jdXJyZW50AEgJEQEAQQELCwsMDTQOBDc4OUNEDAEWCsbmA0YqAEGQ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ABAPCyAJKAIEIgggCEEBayIAcUUEQCAAIARxIQAMAQsgBCAISQRAIAQhAAwBCyAEIAhwIQALAkAgCSgCACIEIABBAnRqIgUoAgAiAEUEQCANIAkoAgg2AgAgCSANNgIIIAUgCUEIajYCACANKAIAIgBFDQEgACgCBCEFAkAgCCAIQQFrIgBxRQRAIAAgBXEhBQwBCyAFIAhJDQAgBSAIcCEFCyAEIAVBAnRqIA02AgAMAQsgDSAAKAIANgIAIAAgDTYCAAsgCSAJKAIMQQFqNgIMQQELOgAcIA4gDTYCGCAKDAELIA1BDGoLLwEAOwEACyASIAFBAWoiAUcNAAsgDigCiAIhDQsCQCANKAKoASANKAKsAUYEQCALIQUMAQsgDSACNgKgASANKAKcASEFIA0gCzYCnAEgDSgCpAEaIA0gAzYCpAELIAUEQCAFEC8LIA4oAjgiDQRAA0AgDSgCACEAIA0QLyAAIg0NAAsLIA4oAjAhACAOQQA2AjAgAARAIA4oAjQaIAAQLwsgDigCUCINBEADQCANKAIAIQAgDRAvIAAiDQ0ACwsgDigCSCEAIA5BADYCSCAABEAgDigCTBogABAvCyAOKALUASIABEAgDiAANgLYASAOKALcARogABAvCyAZBEAgEyAZRwRAA0ACQCATQegBayITKALkASIARQ0AIAAgACgCBCIBQQFrNgIEIAENACAAIAAoAgAoAggRAQACQCAAKAIIIgEEQCAAIAFBAWs2AgggAQ0BCyAAIAAoAgAoAhARAQALCyATKALIASIABEAgEyAANgLMASATKALQARogABAvCyATKAK8ASIABEAgEyAANgLAASATKALEARogABAvCyATKAKwASIABEAgEyAANgK0ASATKAK4ARogABAvCyATKAKkASIABEAgEyAANgKoASATKAKsARogABAvCyATIBlHDQALCyAZEC8LIBUEQCAVEC8LIBQEQCAUEC8LIA4oAugBIg0EQANAIA0oAgAhACANEC8gACINDQALCyAOKALgASEAIA5BADYC4AEgAARAIA4oAuQBGiAAEC8LIA5BkAJqJAAPCxAGAAuFHAQMfxN8AX4CfSMAQUBqIgokAAJAIAAoAgQoAgAgACgCACgCACgCPCABQQJ0aigCACIFQfAAbGoiCy0AaEEBRw0AIAKtIAAoAgg1AgAgBa1+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ACAKIA4QPiAAQSAgASAHIAVBgMAAcxBCDAELCwtBACELDAMLQT0hCAtB7BEgCDYCAAtBfyELCyAGQUBrJAAgCwvHAQEDfyAALQAAQSBxRQRAAkAgACgCECIDBH8gAwUgABA6DQEgACgCEAsgACgCFCIEayACSQRAIAAgASACIAAoAiQRAgAaDAELAkACQCAAKAJQQQBIDQAgAkUNACACIQMDQCABIANqIgVBAWstAABBCkcEQCADQQFrIgMNAQwCCwsgACABIAMgACgCJBECACADSQ0CIAIgA2shAiAAKAIUIQQMAQsgASEFCyACBEAgBCAFIAL8CgAACyAAIAAoAhQgAmo2AhQLCwtzAQV/IAAoAgAiAywAAEEwayIBQQlLBEBBAA8LA0BBfyEEIAJBzJmz5gBNBEBBfyABIAJBCmwiBWogASAFQf////8Hc0sbIQQLIAAgA0EBaiIFNgIAIAMsAAEhASAEIQIgBSEDIAFBMGsiAUEKSQ0ACyACC7kCAAJAAkACQAJAAkACQAJAAkACQAJAAkAgAUEJaw4SAAgJCggJAQIDBAoJCgoICQUGBwsgAiACKAIAIgFBBGo2AgAgACABKAIANgIADwsgAiACKAIAIgFBBGo2AgAgACABMgEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMwEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMAAANwMADwsgAiACKAIAIgFBBGo2AgAgACABMQAANwMADwsgAiACKAIAQQdqQXhxIgFBCGo2AgAgACABKwMAOQMADwsgACACEEQLDwsgAiACKAIAIgFBBGo2AgAgACABNAIANwMADwsgAiACKAIAIgFBBGo2AgAgACABNQIANwMADwsgAiACKAIAQQdqQXhxIgFBCGo2AgAgACABKQMANwMAC4gBAgJ/AX4gAEKAgICAEFoEQANAIAFBAWsiASAAIgQgAEIKgCIAQgp+fadBMHI6AAAgBEL/////nwFWDQALCyAApyECIABCCloEQANAIAFBAWsiASACIgMgAkEKbiICQQpsa0EwcjoAACADQeMASw0ACwsgAgRAIAFBAWsiASACQTByOgAACyABC3IBAX8jAEGAAmsiBSQAAkAgAiADTA0AIARBgMAEcQ0AIAIgA2siA0GAAiADQYACSSICGyIEBEAgBSABIAT8CwAL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ACAFIAitIgeGIARBwAAgCGutiIQhBSAEIAeGIQQLIAAgBDcDECAAIAU3AxggACkDECAAKQMYhEIAUiEJCwJAIAFBwABxBEAgAyABQUBqrYghAkIAIQMMAQsgAUUNACADQcAAIAFrrYYgAiABrSIEiIQhAiADIASIIQMLIAAgAjcDACAAIAM3AwggACkDCEIEhiAAKQMAIgNCPIiEIQICQCAJrSADQv//////////D4OEIgNCgYCAgICAgIAIWgRAIAJCAXwhAgwBCyADQoCAgICAgICACFINACACQgGDIAJ8IQILIAJCgICAgICAgAiFIAIgAkL/////////B1YiARshAiABrQshAyAAQSBqJAAgBkKAgICAgICAgIB/gyADQjSGhCAChL85AwALfAECfyMAQRBrIgEkACABQQo6AA8CQAJAIAAoAhAiAgR/IAIFIAAQOg0CIAAoAhALIAAoAhQiAkYNACAAKAJQQQpGDQAgACACQQFqNgIUIAJBCjoAAAwBCyAAIAFBD2pBASAAKAIkEQIAQQFHDQAgAS0ADxoLIAFBEGokAAvdBAEEfyMAQRBrIgIkACACIAE2AgxB5AwoAgAhAiMAQdABayIDJAAgAyABNgLMASADQaABaiIBQQBBKPwLACADIAMoAswBNgLIAUEAIAAgA0HIAWogA0HQAGogARA9QQBIBH9BfwUgAiACKAIAIgFBX3E2AgACfwJAAkAgAigCMEUEQCACQdAANgIwIAJBADYCHCACQgA3AxAgAigCLCEEIAIgAzYCLAwBCyACKAIQDQELQX8gAhA6DQEaCyACIAAgA0HIAWogA0HQAGogA0GgAWoQPQshBSAEBH8gAkEAQQAgAigCJBECABogAkEANgIwIAIgBDYCLCACQQA2AhwgAigCFBogAkIANwMQQQAFIAULGiACIAIoAgAgAUEgcXI2AgBBAAsaIANB0AFqJAACQCAAIgNBA3EEQANAIAAtAABFDQIgAEEBaiIAQQNxDQALCwNAIAAiAUEEaiEAQYCChAggASgCACIEayAEckGAgYKEeHFBgIGChHhGDQALA0AgASIAQQFqIQEgAC0AAA0ACwsgAyAAIANrakEBay0AAEEKRwRAAkACQCACKAJMIgBBAE4EQCAARQ0BQfgVKAIAIABB/////wNxRw0BCwJAIAIoAlBBCkYNACACKAIUIgAgAigCEEYNACACIABBAWo2AhQgAEEKOgAADAILIAIQRQwBCyACIAIoAkwiAEH/////AyAAGzYCTAJAAkAgAigCUEEKRg0AIAIoAhQiACACKAIQRg0AIAIgAEEBajYCFCAAQQo6AAAMAQsgAhBFCyACKAJMGiACQQA2AkwLCwALBgAgACQACwQAIwALHABBnBcoAgBFBEBBoBcgATYCAEGcFyAANgIACwsL6AcWAEGACAu2AS0rICAgMFgweAAtMFgrMFggMFgtMHgrMHggMHgAdmVjdG9yAG5hbgBpbmYAYmFkX2FycmF5X25ld19sZW5ndGggd2FzIHRocm93biBpbiAtZm5vLWV4Y2VwdGlvbnMgbW9kZQBOQU4ASU5GAC4AKG51bGwpAGxlbmd0aF9lcnJvciB3YXMgdGhyb3duIGluIC1mbm8tZXhjZXB0aW9ucyBtb2RlIHdpdGggbWVzc2FnZSAiJXMiAEHACQsRAQAAAAIAAAADAAAABAAAAAUAQeQJC4IDAgAAAAMAAAAFAAAABwAAAAsAAAANAAAAEQAAABMAAAAXAAAAHQAAAB8AAAAlAAAAKQAAACsAAAAvAAAANQAAADsAAAA9AAAAQwAAAEcAAABJAAAATwAAAFMAAABZAAAAYQAAAGUAAABnAAAAawAAAG0AAABxAAAAfwAAAIMAAACJAAAAiwAAAJUAAACXAAAAnQAAAKMAAACnAAAArQAAALMAAAC1AAAAvwAAAMEAAADFAAAAxwAAANMAAAABAAAACwAAAA0AAAARAAAAEwAAABcAAAAdAAAAHwAAACUAAAApAAAAKwAAAC8AAAA1AAAAOwAAAD0AAABDAAAARwAAAEkAAABPAAAAUwAAAFkAAABhAAAAZQAAAGcAAABrAAAAbQAAAHEAAAB5AAAAfwAAAIMAAACJAAAAiwAAAI8AAACVAAAAlwAAAJ0AAACjAAAApwAAAKkAAACtAAAAswAAALUAAAC7AAAAvwAAAMEAAADFAAAAxwAAANEAAAAAAAAAWAgAQfAMC0EZAAsAGRkZAAAAAAUAAAAAAAAJAAAAAAsAAAAAAAAAABkACgoZGRkDCgcAAQAJCxgAAAkGCwAACwAGGQAAABkZGQBBwQ0LIQ4AAAAAAAAAABkACw0ZGRkADQAAAgAJDgAAAAkADgAADgBB+w0LAQwAQYcOCxUTAAAAABMAAAAACQwAAAAAAAwAAAwAQbUOCwEQAEHBDgsVDwAAAAQPAAAAAAkQAAAAAAAQAAAQAEHvDgsBEgBB+w4LHhEAAAAAEQAAAAAJEgAAAAAAEgAAEgAAGgAAABoaGgBBsg8LDhoAAAAaGhoAAAAAAAAJAEHjDwsBFABB7w8LFRcAAAAAFwAAAAAJFAAAAAAAFAAAFABBnRALARYAQakQCycVAAAAABUAAAAACRYAAAAAABYAABYAADAxMjM0NTY3ODlBQkNERUYAQdAQCwmwCwEAACAAAAUAQeQQCwEHAEH8EAsKCAAAAAkAAABgCwBBlBELAQIAQaQRCwj//////////wBB6BELAoAL";
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// The native core: native/*.cpp compiled to one WebAssembly module
|
|
2
|
+
// (core-wasm.js, built by scripts/build-core-wasm.mjs), loaded lazily and
|
|
3
|
+
// synchronously the first time a pass asks for it.
|
|
4
|
+
//
|
|
5
|
+
// What it runs — each a bit-exact port of a JS pass, which stays as the
|
|
6
|
+
// fallback:
|
|
7
|
+
// creasedNormals geometry/creased-normals.js (+ blend-surfaces.js)
|
|
8
|
+
// the oracle's BVH oracle/bvh.js, via cachedBVH (+ min-wall.js)
|
|
9
|
+
//
|
|
10
|
+
// Bit-exact is the contract, not an aspiration: test/core-parity.test.js builds
|
|
11
|
+
// the reference parts both ways and requires identical output, so turning the
|
|
12
|
+
// core on or off changes no mesh, normal, edge, reading or verdict — only how
|
|
13
|
+
// long they take (several times faster with a JIT; far more on a host whose JS
|
|
14
|
+
// is interpreted).
|
|
15
|
+
//
|
|
16
|
+
// The switch: on by default wherever WebAssembly exists. `setCoreEnabled(false)`
|
|
17
|
+
// (exported from partforge/oracle and partforge/testing), or
|
|
18
|
+
// `globalThis.PARTFORGE_CORE = false` (read on every use, so it can be set any
|
|
19
|
+
// time), turns it off for that realm — a worker is its own realm, so a host sets
|
|
20
|
+
// it there. If the module cannot be instantiated the passes keep their JS.
|
|
21
|
+
//
|
|
22
|
+
// Failure is contained, never fatal: a failed allocation or a trap inside the
|
|
23
|
+
// module POISONS that instance (poisonCore) — nothing touches it again — and
|
|
24
|
+
// the pass that hit it, and every pass after, runs its JS instead. And because
|
|
25
|
+
// WebAssembly memory only ever grows, an instance whose memory passed
|
|
26
|
+
// RECYCLE_BYTES is dropped once nothing holds it (releaseIfIdle); the next pass
|
|
27
|
+
// boots a fresh one in a few milliseconds and the old memory goes to the GC.
|
|
28
|
+
import { CORE_WASM_BASE64 } from "./core-wasm.js";
|
|
29
|
+
|
|
30
|
+
// What the core may keep holding between passes. Ordinary forges never grow it
|
|
31
|
+
// past its 16 MB start; a preview mesh needs ~145 bytes/triangle at the peak
|
|
32
|
+
// (screw, 210k triangles: 29 MB; a 1M-triangle mesh: 138 MB). Re-booting costs a
|
|
33
|
+
// few milliseconds — the module is 64 KB — so cap the retained memory low.
|
|
34
|
+
export const RECYCLE_BYTES = 64 * 1024 * 1024;
|
|
35
|
+
|
|
36
|
+
let enabled = true;
|
|
37
|
+
let booted; // undefined: not tried yet (or recycled); null: unavailable or poisoned
|
|
38
|
+
|
|
39
|
+
export function setCoreEnabled(on) { enabled = !!on; }
|
|
40
|
+
|
|
41
|
+
const flagOff = () => globalThis.PARTFORGE_CORE === false || globalThis.PARTFORGE_CORE === "off";
|
|
42
|
+
|
|
43
|
+
// The live core, or null when disabled, unavailable or poisoned.
|
|
44
|
+
export function core() {
|
|
45
|
+
if (!enabled || flagOff()) return null;
|
|
46
|
+
if (booted === undefined) booted = boot();
|
|
47
|
+
return booted;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// The instance `c` faulted (a trap, or an allocation that failed): never use it
|
|
51
|
+
// again in this realm. Objects still holding it check `c.poisoned` and fall back.
|
|
52
|
+
export function poisonCore(c) {
|
|
53
|
+
if (c) c.poisoned = true;
|
|
54
|
+
if (booted === c || c == null) booted = null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Drop `c` if its memory grew past RECYCLE_BYTES and nothing holds it (no live
|
|
58
|
+
// BVH); the next core() boots a fresh, small instance.
|
|
59
|
+
export function releaseIfIdle(c) {
|
|
60
|
+
if (booted === c && c.live === 0 && c.x.memory.buffer.byteLength > RECYCLE_BYTES) booted = undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Tests only: install a stand-in instance (or undefined to re-boot).
|
|
64
|
+
export function setCoreForTesting(c) { booted = c; }
|
|
65
|
+
|
|
66
|
+
const B64 = (() => {
|
|
67
|
+
const t = new Uint8Array(128);
|
|
68
|
+
const a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
69
|
+
for (let i = 0; i < a.length; i++) t[a.charCodeAt(i)] = i;
|
|
70
|
+
return t;
|
|
71
|
+
})();
|
|
72
|
+
// Not atob: some JS hosts (an app's own JavaScriptCore context) have none.
|
|
73
|
+
function decodeBase64(s) {
|
|
74
|
+
let n = s.length;
|
|
75
|
+
while (n > 0 && s[n - 1] === "=") n--;
|
|
76
|
+
const out = new Uint8Array((n * 3) >> 2);
|
|
77
|
+
let o = 0;
|
|
78
|
+
for (let i = 0; i < n; i += 4) {
|
|
79
|
+
const v = (B64[s.charCodeAt(i)] << 18) | (B64[s.charCodeAt(i + 1)] << 12)
|
|
80
|
+
| (i + 2 < n ? B64[s.charCodeAt(i + 2)] << 6 : 0) | (i + 3 < n ? B64[s.charCodeAt(i + 3)] : 0);
|
|
81
|
+
out[o++] = v >> 16;
|
|
82
|
+
if (i + 2 < n) out[o++] = (v >> 8) & 255;
|
|
83
|
+
if (i + 3 < n) out[o++] = v & 255;
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function boot() {
|
|
89
|
+
if (typeof WebAssembly !== "object") return null;
|
|
90
|
+
try {
|
|
91
|
+
const stub = () => 0;
|
|
92
|
+
// Synchronous on purpose: a pass asks mid-build and must get an answer now.
|
|
93
|
+
// The module is small (well under every engine's synchronous-compile limit).
|
|
94
|
+
const instance = new WebAssembly.Instance(new WebAssembly.Module(decodeBase64(CORE_WASM_BASE64)), {
|
|
95
|
+
env: { emscripten_notify_memory_growth: () => {} },
|
|
96
|
+
wasi_snapshot_preview1: { fd_close: stub, fd_write: stub, fd_seek: stub },
|
|
97
|
+
});
|
|
98
|
+
const x = instance.exports;
|
|
99
|
+
x._initialize?.();
|
|
100
|
+
// One 32-double scratch block for small inputs and outputs.
|
|
101
|
+
const scratch = x.malloc(32 * 8);
|
|
102
|
+
return {
|
|
103
|
+
x,
|
|
104
|
+
scratch,
|
|
105
|
+
live: 0, // core BVHs not yet disposed (they pin this instance)
|
|
106
|
+
poisoned: false,
|
|
107
|
+
// Never hands out 0: a failed malloc (memory exhausted) throws instead, so
|
|
108
|
+
// nothing is ever written over the module's low memory.
|
|
109
|
+
alloc(bytes) {
|
|
110
|
+
const ptr = x.malloc(bytes || 1);
|
|
111
|
+
if (!ptr) throw new Error("partforge core: out of WebAssembly memory");
|
|
112
|
+
return ptr;
|
|
113
|
+
},
|
|
114
|
+
// Views are rebuilt per use: any call that grows memory detaches the old buffer.
|
|
115
|
+
f64: () => new Float64Array(x.memory.buffer, scratch, 32),
|
|
116
|
+
copyIn(arr) {
|
|
117
|
+
if (!arr || arr.length === 0) return 0;
|
|
118
|
+
const ptr = this.alloc(arr.byteLength);
|
|
119
|
+
new Uint8Array(x.memory.buffer, ptr, arr.byteLength).set(new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength));
|
|
120
|
+
return ptr;
|
|
121
|
+
},
|
|
122
|
+
copyOut: (Ctor, ptr, len) => (ptr && len ? new Ctor(x.memory.buffer, ptr, len).slice() : new Ctor(0)),
|
|
123
|
+
};
|
|
124
|
+
} catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// creasedNormals(g, opts) on the native core (native/creased_normals.cpp) —
|
|
2
|
+
// same arguments, same result object, same bits as the JS in
|
|
3
|
+
// geometry/creased-normals.js, which dispatches here when the core is on.
|
|
4
|
+
//
|
|
5
|
+
// JS keeps only per-SURFACE work: the shading-policy table (Map lookups and
|
|
6
|
+
// Math.cos, so no second libm decides a cosine), the feature label strings, and
|
|
7
|
+
// flattening each fillet descriptor (blend-surfaces.js) into numbers once.
|
|
8
|
+
// Everything per vertex or per triangle runs in C++.
|
|
9
|
+
import { SMOOTH, COPLANAR_ANGLE, cosDeg } from "../geometry/shading-policy.js";
|
|
10
|
+
import { releaseIfIdle } from "./core.js";
|
|
11
|
+
|
|
12
|
+
const COPLANAR_COS = cosDeg(COPLANAR_ANGLE);
|
|
13
|
+
const ANALYTIC_COS = cosDeg(25); // creased-normals.js's ANALYTIC_COS
|
|
14
|
+
const EMPTY = new Uint32Array(0);
|
|
15
|
+
const KIND = { line: 1, point: 2, circle: 3, path: 4, spine: 5, planes: 6 };
|
|
16
|
+
|
|
17
|
+
// native/blend_surfaces.h's flat layout: [kind, closed, n, ...kind fields].
|
|
18
|
+
// An unknown kind flattens to 0, which evaluates to "no normal" — exactly what
|
|
19
|
+
// surfaceNormal does with one.
|
|
20
|
+
function flattenDescriptor(desc, out) {
|
|
21
|
+
const kind = KIND[desc.kind] ?? 0;
|
|
22
|
+
const pts = desc.pts ?? [];
|
|
23
|
+
const v = (p) => out.push(p[0], p[1], p[2]);
|
|
24
|
+
if (kind === 6) {
|
|
25
|
+
out.push(kind, 0, desc.planes.length, desc.tol);
|
|
26
|
+
for (const pl of desc.planes) { v(pl.n); out.push(pl.d); }
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
out.push(kind, desc.closed ? 1 : 0, pts.length);
|
|
30
|
+
switch (kind) {
|
|
31
|
+
case 1: v(desc.p); v(desc.d); break;
|
|
32
|
+
case 2: v(desc.c); break;
|
|
33
|
+
case 3: v(desc.c); v(desc.a); out.push(desc.R); break;
|
|
34
|
+
case 4: out.push(desc.kf, desc.kd); v(desc.f); pts.forEach(v); desc.dirs.forEach(v); break;
|
|
35
|
+
case 5: out.push(desc.r); pts.forEach(v); break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Can the core take this mesh? The C++ reads the arrays' raw bytes and trusts
|
|
40
|
+
// their indices, where the JS tolerated (or simply read undefined from) a
|
|
41
|
+
// malformed mesh — so anything but Manifold's own MeshGL shape, typed exactly
|
|
42
|
+
// and with every index in range, goes to the JS pass instead. Cheap: O(runs +
|
|
43
|
+
// merges), never O(triangles).
|
|
44
|
+
export function coreAccepts(g) {
|
|
45
|
+
const vp = g?.vertProperties, tris = g?.triVerts, ri = g?.runIndex, roid = g?.runOriginalID;
|
|
46
|
+
if (!(vp instanceof Float32Array) || !(tris instanceof Uint32Array)) return false;
|
|
47
|
+
if (!(ri instanceof Uint32Array) || !(roid instanceof Uint32Array) || ri.length !== roid.length + 1) return false;
|
|
48
|
+
if (!(g.numProp >= 3) || tris.length % 3 !== 0) return false;
|
|
49
|
+
const nVert = (vp.length / g.numProp) | 0;
|
|
50
|
+
for (let r = 0; r < roid.length; r++) if (ri[r] > ri[r + 1] || ri[r + 1] > tris.length) return false;
|
|
51
|
+
const mf = g.mergeFromVert, mt = g.mergeToVert;
|
|
52
|
+
if (mf != null || mt != null) {
|
|
53
|
+
if (!(mf instanceof Uint32Array) || !(mt instanceof Uint32Array) || mf.length !== mt.length) return false;
|
|
54
|
+
for (let i = 0; i < mf.length; i++) if (mf[i] >= nVert || mt[i] >= nVert) return false;
|
|
55
|
+
}
|
|
56
|
+
// Triangle indices are range-checked in C++ (one pass it already makes);
|
|
57
|
+
// see cn_create. Here: the cheap structural facts.
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Returns null when the core refuses the mesh (see cn_create); the caller then
|
|
62
|
+
// runs the JS pass.
|
|
63
|
+
export function creasedNormalsCore(c, g, { policies = null, featureLabels = null, surfaces = null } = {}) {
|
|
64
|
+
const { x } = c;
|
|
65
|
+
const np = g.numProp, vp = g.vertProperties, tris = g.triVerts;
|
|
66
|
+
const nTri = (tris.length / 3) | 0, nVert = (vp.length / np) | 0;
|
|
67
|
+
const roid = g.runOriginalID, ri = g.runIndex;
|
|
68
|
+
const mf = g.mergeFromVert ?? EMPTY, mt = g.mergeToVert ?? EMPTY;
|
|
69
|
+
|
|
70
|
+
// Policy table: every surface id in this mesh, then the SMOOTH default row.
|
|
71
|
+
const oidList = [...new Set(roid)];
|
|
72
|
+
const n = oidList.length + 1;
|
|
73
|
+
const oids = new Uint32Array(n), creaseCos = new Float64Array(n), flags = new Uint8Array(n), labelIds = new Int32Array(n);
|
|
74
|
+
const labelOf = new Map(), labels = [];
|
|
75
|
+
const row = (i, pol, label) => {
|
|
76
|
+
creaseCos[i] = cosDeg(pol.creaseAngle);
|
|
77
|
+
flags[i] = (pol.boundaryLines ? 1 : 0) | (pol.sameSurfaceLines ? 2 : 0);
|
|
78
|
+
if (label === undefined) { labelIds[i] = -1; return; }
|
|
79
|
+
let id = labelOf.get(label);
|
|
80
|
+
if (id === undefined) { id = labels.length; labels.push(label); labelOf.set(label, id); }
|
|
81
|
+
labelIds[i] = id;
|
|
82
|
+
};
|
|
83
|
+
oidList.forEach((oid, i) => {
|
|
84
|
+
oids[i] = oid;
|
|
85
|
+
row(i, (policies && policies.get(oid)) || SMOOTH, featureLabels?.size ? featureLabels.get(oid) : undefined);
|
|
86
|
+
});
|
|
87
|
+
row(n - 1, SMOOTH, undefined);
|
|
88
|
+
|
|
89
|
+
// Fillet surfaces: one flattened copy per distinct descriptor, run → descriptor
|
|
90
|
+
// index, and each run's transform (IDENTITY when the mesh carries none for it).
|
|
91
|
+
let runDesc = null, runXf = null, descData = null, descOffsets = null;
|
|
92
|
+
if (surfaces?.size) {
|
|
93
|
+
const index = new Map(), flat = [], offsets = [0];
|
|
94
|
+
runDesc = new Int32Array(roid.length).fill(-1);
|
|
95
|
+
for (let r = 0; r < roid.length; r++) {
|
|
96
|
+
const desc = surfaces.get(roid[r]);
|
|
97
|
+
if (!desc) continue;
|
|
98
|
+
let di = index.get(desc);
|
|
99
|
+
if (di === undefined) { di = index.size; index.set(desc, di); flattenDescriptor(desc, flat); offsets.push(flat.length); }
|
|
100
|
+
runDesc[r] = di;
|
|
101
|
+
}
|
|
102
|
+
if (index.size) {
|
|
103
|
+
const rt = g.runTransform;
|
|
104
|
+
runXf = new Float64Array(roid.length * 12);
|
|
105
|
+
for (let r = 0; r < roid.length; r++) {
|
|
106
|
+
if (rt && rt.length >= (r + 1) * 12) for (let k = 0; k < 12; k++) runXf[r * 12 + k] = rt[r * 12 + k];
|
|
107
|
+
else runXf.set([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], r * 12);
|
|
108
|
+
}
|
|
109
|
+
descData = Float64Array.from(flat);
|
|
110
|
+
descOffsets = Uint32Array.from(offsets);
|
|
111
|
+
} else runDesc = null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Inputs are borrowed by the state until destroy; free them after.
|
|
115
|
+
const inputs = [c.copyIn(vp), c.copyIn(tris), c.copyIn(mf), c.copyIn(mt), c.copyIn(ri), c.copyIn(roid)];
|
|
116
|
+
const state = x.cn_create(inputs[0], np, nVert, inputs[1], nTri, inputs[2], inputs[3], mf.length, inputs[4], inputs[5], roid.length);
|
|
117
|
+
if (!state) { // a triangle index out of range: not a mesh the core takes
|
|
118
|
+
for (const p of inputs) if (p) x.free(p);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const args = [c.copyIn(oids), c.copyIn(creaseCos), c.copyIn(flags), c.copyIn(labelIds),
|
|
122
|
+
c.copyIn(runDesc), c.copyIn(runXf), c.copyIn(descData), c.copyIn(descOffsets)];
|
|
123
|
+
try {
|
|
124
|
+
x.cn_finish(state, args[0], args[1], args[2], args[3], n, COPLANAR_COS, ANALYTIC_COS,
|
|
125
|
+
args[4], args[5], args[6], args[7], descOffsets ? descOffsets.length - 1 : 0);
|
|
126
|
+
const nf = x.cn_feature_count(state);
|
|
127
|
+
const out = {
|
|
128
|
+
positions: c.copyOut(Float32Array, x.cn_positions(state), nTri * 9),
|
|
129
|
+
normals: c.copyOut(Float32Array, x.cn_normals(state), nTri * 9),
|
|
130
|
+
triangles: nTri,
|
|
131
|
+
edges: c.copyOut(Float32Array, x.cn_edges(state), x.cn_edge_floats(state)),
|
|
132
|
+
};
|
|
133
|
+
if (nf) {
|
|
134
|
+
out.featureIds = c.copyOut(Uint16Array, x.cn_feature_ids(state), nTri);
|
|
135
|
+
out.features = [...c.copyOut(Int32Array, x.cn_feature_labels(state), nf)].map((id) => labels[id]);
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
} finally {
|
|
139
|
+
x.cn_destroy(state);
|
|
140
|
+
for (const p of [...inputs, ...args]) if (p) x.free(p);
|
|
141
|
+
releaseIfIdle(c);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
// { kind: "spine", pts, closed, r }
|
|
23
23
|
// general chain (mesh-fillet generalTool): the
|
|
24
24
|
// ball-centre polyline itself; r is the radius
|
|
25
|
+
// { kind: "planes", planes: [{ n, d }], tol }
|
|
26
|
+
// roundAll's flat faces (mesh-roundall.js
|
|
27
|
+
// flatFacePlanes): a point within tol of one plane
|
|
28
|
+
// (n·x = d) takes its normal; anywhere else — the
|
|
29
|
+
// rounded band off its seams — there is none, and
|
|
30
|
+
// creased-normals keeps the facet average
|
|
25
31
|
//
|
|
26
32
|
// A path's polyline usually STANDS FOR a smooth curve (a circle's rim, an outline's
|
|
27
33
|
// rounded corner): its per-segment cylinders would shade faceted around the curve,
|
|
@@ -40,6 +46,7 @@
|
|
|
40
46
|
// boolean and re-stamp that carries runTransform along (Manifold does, verified).
|
|
41
47
|
// Pure module: no DOM, no node:, no three.
|
|
42
48
|
|
|
49
|
+
import { hypot3 } from "./js-math.js";
|
|
43
50
|
const EPS = 1e-12;
|
|
44
51
|
|
|
45
52
|
// --- 3x4 column-major affine helpers (Manifold's runTransform layout) -------------
|
|
@@ -77,7 +84,7 @@ export function invertAffine(M) {
|
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
const norm = (v) => {
|
|
80
|
-
const l =
|
|
87
|
+
const l = hypot3(v[0], v[1], v[2]);
|
|
81
88
|
return l > EPS ? [v[0] / l, v[1] / l, v[2] / l] : null;
|
|
82
89
|
};
|
|
83
90
|
|
|
@@ -105,10 +112,32 @@ export function mapSurface(desc, M) {
|
|
|
105
112
|
M[0] * (M[4] * M[8] - M[5] * M[7]) - M[3] * (M[1] * M[8] - M[2] * M[7]) + M[6] * (M[1] * M[5] - M[2] * M[4])));
|
|
106
113
|
return { kind: "spine", closed: desc.closed, pts: desc.pts.map((p) => applyPt(M, p)), r: desc.r * s };
|
|
107
114
|
}
|
|
115
|
+
case "planes": {
|
|
116
|
+
const s = Math.cbrt(Math.abs(
|
|
117
|
+
M[0] * (M[4] * M[8] - M[5] * M[7]) - M[3] * (M[1] * M[8] - M[2] * M[7]) + M[6] * (M[1] * M[5] - M[2] * M[4])));
|
|
118
|
+
return { kind: "planes", tol: desc.tol * s, planes: desc.planes.map(({ n, d }) => {
|
|
119
|
+
const n2 = norm(applyDir(M, n)) ?? n;
|
|
120
|
+
const p = applyPt(M, [n[0] * d, n[1] * d, n[2] * d]);
|
|
121
|
+
return { n: n2, d: n2[0] * p[0] + n2[1] * p[1] + n2[2] * p[2] };
|
|
122
|
+
}) };
|
|
123
|
+
}
|
|
108
124
|
default: throw new Error(`blend surface: unknown kind ${desc.kind}`);
|
|
109
125
|
}
|
|
110
126
|
}
|
|
111
127
|
|
|
128
|
+
// The plane x lies on, or null — off every plane, or on two at once (where two
|
|
129
|
+
// flat faces would meet, which a rounded result never shows, so no answer is right).
|
|
130
|
+
function planeNormal(desc, x) {
|
|
131
|
+
let hit = null;
|
|
132
|
+
for (const pl of desc.planes) {
|
|
133
|
+
const n = pl.n;
|
|
134
|
+
if (Math.abs(n[0] * x[0] + n[1] * x[1] + n[2] * x[2] - pl.d) > desc.tol) continue;
|
|
135
|
+
if (hit) return null;
|
|
136
|
+
hit = n;
|
|
137
|
+
}
|
|
138
|
+
return hit;
|
|
139
|
+
}
|
|
140
|
+
|
|
112
141
|
// Nearest spine point to x, in the descriptor's own frame.
|
|
113
142
|
function spinePoint(desc, x) {
|
|
114
143
|
switch (desc.kind) {
|
|
@@ -175,7 +204,7 @@ function segmentGrid(desc) {
|
|
|
175
204
|
if (g) return g;
|
|
176
205
|
const { pts, closed } = desc, n = pts.length, nSeg = closed ? n : n - 1;
|
|
177
206
|
let total = 0;
|
|
178
|
-
for (let i = 0; i < nSeg; i++) { const p = pts[i], q = pts[(i + 1) % n]; total +=
|
|
207
|
+
for (let i = 0; i < nSeg; i++) { const p = pts[i], q = pts[(i + 1) % n]; total += hypot3(q[0] - p[0], q[1] - p[1], q[2] - p[2]); }
|
|
179
208
|
const h = Math.max(total / Math.max(1, nSeg), Math.abs(desc.kf ?? 0) + Math.abs(desc.kd ?? 0) + (desc.r ?? 0), 1e-6);
|
|
180
209
|
const cells = new Map();
|
|
181
210
|
// numeric hashed cell keys: a collision only adds candidates, each distance-checked
|
|
@@ -240,6 +269,7 @@ function nearestSegment(desc, x) {
|
|
|
240
269
|
// Unit spine→point direction at x in the descriptor's frame, or null where undefined.
|
|
241
270
|
export function surfaceNormal(desc, x) {
|
|
242
271
|
if (desc.kind === "path") return pathNormal(desc, x);
|
|
272
|
+
if (desc.kind === "planes") return planeNormal(desc, x);
|
|
243
273
|
if (desc.kind === "spine") {
|
|
244
274
|
const { bi, bt } = nearestSegment(desc, x);
|
|
245
275
|
if (bi < 0) return null;
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
// side, and any band vertex riding a face edge as a T-junction all agree.
|
|
19
19
|
import { SMOOTH, COPLANAR_ANGLE, MIN_EDGE, MIN_FACE, cosDeg } from "./shading-policy.js";
|
|
20
20
|
import { affineAt, IDENTITY, runEvaluator } from "./blend-surfaces.js";
|
|
21
|
+
import { hypot3 } from "./js-math.js";
|
|
22
|
+
import { core, poisonCore } from "../core/core.js";
|
|
23
|
+
import { coreAccepts, creasedNormalsCore } from "../core/creased-normals-core.js";
|
|
21
24
|
|
|
22
25
|
const COPLANAR_COS = cosDeg(COPLANAR_ANGLE);
|
|
23
26
|
const MIN_EDGE2 = MIN_EDGE * MIN_EDGE;
|
|
@@ -33,7 +36,25 @@ const SHADE_CELL = 1e-3; // its hash-grid cell
|
|
|
33
36
|
// Vertex-normal sliver cutoff (mm of triangle height): see the smooth loop below.
|
|
34
37
|
const SHADE_SLIVER = 1e-3;
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
// The pass every Manifold mesh goes through: on the native core when it is on
|
|
40
|
+
// (core/creased-normals-core.js — same bits, several times faster), else the JS
|
|
41
|
+
// below. test/core-parity.test.js holds the two to identical output. The core
|
|
42
|
+
// takes only well-formed MeshGL (coreAccepts / cn_create); a fault inside it
|
|
43
|
+
// poisons that instance and this mesh, and every one after, runs the JS.
|
|
44
|
+
export function creasedNormals(g, opts) {
|
|
45
|
+
const c = core();
|
|
46
|
+
if (c && coreAccepts(g)) {
|
|
47
|
+
try {
|
|
48
|
+
const out = creasedNormalsCore(c, g, opts);
|
|
49
|
+
if (out) return out;
|
|
50
|
+
} catch {
|
|
51
|
+
poisonCore(c);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return creasedNormalsJS(g, opts);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function creasedNormalsJS(g, { policies = null, featureLabels = null, surfaces = null } = {}) {
|
|
37
58
|
const np = g.numProp, vp = g.vertProperties, tris = g.triVerts;
|
|
38
59
|
const nTri = (tris.length / 3) | 0, nVert = (vp.length / np) | 0;
|
|
39
60
|
|
|
@@ -105,7 +126,7 @@ export function creasedNormals(g, { policies = null, featureLabels = null, surfa
|
|
|
105
126
|
const vx = vp[c] - vp[a], vy = vp[c + 1] - vp[a + 1], vz = vp[c + 2] - vp[a + 2];
|
|
106
127
|
const wx = vp[c] - vp[b], wy = vp[c + 1] - vp[b + 1], wz = vp[c + 2] - vp[b + 2];
|
|
107
128
|
const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx;
|
|
108
|
-
const L0 =
|
|
129
|
+
const L0 = hypot3(nx, ny, nz), L = L0 || 1; // the || 1 is for the normal divide ONLY
|
|
109
130
|
fn[t * 3] = nx / L; fn[t * 3 + 1] = ny / L; fn[t * 3 + 2] = nz / L;
|
|
110
131
|
const longest = Math.max(ux * ux + uy * uy + uz * uz, vx * vx + vy * vy + vz * vz, wx * wx + wy * wy + wz * wz);
|
|
111
132
|
// |cross| / maxEdge = min height — from the RAW cross magnitude, never the
|
|
@@ -188,7 +209,7 @@ export function creasedNormals(g, { policies = null, featureLabels = null, surfa
|
|
|
188
209
|
const an = analyticAt(t2, weld[v]);
|
|
189
210
|
if (an) { ax += an[0]; ay += an[1]; az += an[2]; any = true; }
|
|
190
211
|
}
|
|
191
|
-
const L =
|
|
212
|
+
const L = hypot3(ax, ay, az);
|
|
192
213
|
return any && L > 1e-9 ? [ax / L, ay / L, az / L] : null;
|
|
193
214
|
};
|
|
194
215
|
|
|
@@ -248,8 +269,8 @@ export function creasedNormals(g, { policies = null, featureLabels = null, surfa
|
|
|
248
269
|
}
|
|
249
270
|
}
|
|
250
271
|
if (!solid) { nx = sx; ny = sy; nz = sz; }
|
|
251
|
-
if (analytic &&
|
|
252
|
-
const L =
|
|
272
|
+
if (analytic && hypot3(ax, ay, az) > 1e-9) { nx = ax; ny = ay; nz = az; }
|
|
273
|
+
const L = hypot3(nx, ny, nz) || 1;
|
|
253
274
|
const o = (t * 3 + k) * 3, vv = v * np;
|
|
254
275
|
positions[o] = vp[vv]; positions[o + 1] = vp[vv + 1]; positions[o + 2] = vp[vv + 2];
|
|
255
276
|
normals[o] = nx / L; normals[o + 1] = ny / L; normals[o + 2] = nz / L;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// partforge's own hypot, for the passes the native core (src/framework/core/)
|
|
2
|
+
// mirrors in C++ — creased-normals.js, blend-surfaces.js and min-wall.js.
|
|
3
|
+
//
|
|
4
|
+
// Math.hypot is not one function: JavaScriptCore computes it as libc++'s fused
|
|
5
|
+
// std::hypot(x, y, z) and V8 as a Kahan-summed sum of scaled squares, and the
|
|
6
|
+
// two disagree in the last bit on about a third of inputs — so the same part
|
|
7
|
+
// shaded, measured and hashed slightly differently in Safari and in Chrome, and
|
|
8
|
+
// no C++ could match "the JS" in both. This is three multiplies, two adds and a
|
|
9
|
+
// correctly rounded square root, each rounded in order: the same on every
|
|
10
|
+
// engine (JS never fuses), and reproduced exactly by native/js_math.h.
|
|
11
|
+
//
|
|
12
|
+
// No overflow scaling: inputs are millimetre coordinates and their
|
|
13
|
+
// differences, nowhere near 1e154. Keep this file and native/js_math.h in step.
|
|
14
|
+
export const hypot3 = (x, y, z) => Math.sqrt(x * x + y * y + z * z);
|
|
@@ -18,8 +18,8 @@ import { meshToStl } from "./mesh-stl.js";
|
|
|
18
18
|
import { creasedNormals } from "./creased-normals.js";
|
|
19
19
|
import { loftShadingPolicy, SMOOTH, BLEND } from "./shading-policy.js";
|
|
20
20
|
import { meshFillet, meshChamfer, UnsupportedEdgeError } from "./mesh-fillet.js";
|
|
21
|
-
import { affineAt, invertAffine, mapSurface } from "./blend-surfaces.js";
|
|
22
|
-
import { meshRoundAll, prismSection, roundAllSegs } from "./mesh-roundall.js";
|
|
21
|
+
import { affineAt, IDENTITY, invertAffine, mapSurface } from "./blend-surfaces.js";
|
|
22
|
+
import { flatFacePlanes, meshRoundAll, prismSection, roundAllSegs } from "./mesh-roundall.js";
|
|
23
23
|
import { SEGS, circleSegs, doubleCurvatureSegs } from "./circle-segs.js";
|
|
24
24
|
import { checkBooleanResult } from "./boolean-gate.js";
|
|
25
25
|
import { KernelCapabilityError } from "./errors.js";
|
|
@@ -294,12 +294,20 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
|
|
|
294
294
|
// round-trip, so the descriptor's original frame stays valid). Folding the band
|
|
295
295
|
// into a single blend id, as this used to, lost every descriptor with it: a labeled
|
|
296
296
|
// fillet shaded with facet normals again.
|
|
297
|
+
//
|
|
298
|
+
// "Blend" here is any surface that must keep an id of its own: a fillet band (the
|
|
299
|
+
// boundaryLines policy) or a surface carrying an analytic descriptor at all —
|
|
300
|
+
// roundAll's flat-face planes ride on a SMOOTH surface, and folding that into the
|
|
301
|
+
// base id would drop them and bring the flat-face shading gradient back on every
|
|
302
|
+
// labeled roundAll. Each keeps the policy it had (none, for the roundAll surface).
|
|
303
|
+
const keepsOwnId = (oid) => !!oidPolicies.get(oid)?.boundaryLines || blendSurfaces.has(oid);
|
|
297
304
|
const reserveBlendRestamp = (oids) => {
|
|
298
|
-
const blends = [...oids].filter(
|
|
305
|
+
const blends = [...oids].filter(keepsOwnId);
|
|
299
306
|
const baseId = Manifold.reserveIDs(1 + blends.length);
|
|
300
307
|
const blendIdFor = new Map(blends.map((oid, i) => [oid, baseId + 1 + i]));
|
|
301
308
|
for (const [oid, id2] of blendIdFor) {
|
|
302
|
-
oidPolicies.
|
|
309
|
+
const pol = oidPolicies.get(oid);
|
|
310
|
+
if (pol !== undefined) oidPolicies.set(id2, pol);
|
|
303
311
|
const surf = blendSurfaces.get(oid);
|
|
304
312
|
if (surf) blendSurfaces.set(id2, surf);
|
|
305
313
|
}
|
|
@@ -405,7 +413,7 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
|
|
|
405
413
|
const isBlend = (oid) => !!oidPolicies.get(oid)?.boundaryLines;
|
|
406
414
|
if (![...new Set(g0.runOriginalID)].some(isBlend)) return T(filleted._m.asOriginal());
|
|
407
415
|
const { baseId, blendIdFor } = reserveBlendRestamp(new Set(g0.runOriginalID));
|
|
408
|
-
g0.runOriginalID = Uint32Array.from(g0.runOriginalID, (o) =>
|
|
416
|
+
g0.runOriginalID = Uint32Array.from(g0.runOriginalID, (o) => blendIdFor.get(o) ?? baseId);
|
|
409
417
|
// The constructor re-welds, and that can pinch a latent sliver off a
|
|
410
418
|
// component as fresh femto-debris (the same rebirth dropDebris's own
|
|
411
419
|
// compose() loop guards against) — sweep the reconstruction too.
|
|
@@ -423,6 +431,39 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
|
|
|
423
431
|
}
|
|
424
432
|
};
|
|
425
433
|
|
|
434
|
+
// The reference roundAll's flat faces (mesh-roundall.js flatFacePlanes): the
|
|
435
|
+
// input's flat faces, which the chain returns exactly to their planes, become a
|
|
436
|
+
// "planes" descriptor on the result's surface so creased-normals shades them —
|
|
437
|
+
// and the band's seams beside them — with the plane's own normal. The tolerance
|
|
438
|
+
// sits well under the first ring of band vertices off each face (the same ring
|
|
439
|
+
// meshRoundAll's simplify tolerance protects), so only the face and its seam
|
|
440
|
+
// vertices are on a plane. Keyed on geometry like every descriptor (see
|
|
441
|
+
// blendSurfaces above), so it is never removed with the cache entry.
|
|
442
|
+
const markFlatFaces = (input, out, r) => {
|
|
443
|
+
const gi = input.getMesh();
|
|
444
|
+
let planes;
|
|
445
|
+
try {
|
|
446
|
+
planes = flatFacePlanes(gi, { policyFor: (oid) => oidPolicies.get(oid) });
|
|
447
|
+
} finally {
|
|
448
|
+
gi.delete?.();
|
|
449
|
+
}
|
|
450
|
+
if (!planes.length) return out;
|
|
451
|
+
const segs = roundAllSegs(2 * r, quality);
|
|
452
|
+
const tol = Math.min(1e-3, 0.25 * r * (1 - Math.cos((2 * Math.PI) / segs)));
|
|
453
|
+
const go = out.getMesh();
|
|
454
|
+
try {
|
|
455
|
+
const roid = go.runOriginalID, rt = go.runTransform;
|
|
456
|
+
for (let i = 0; i < roid.length; i++) {
|
|
457
|
+
// a fresh original carries no runTransform at all — identity, as creased-normals reads it
|
|
458
|
+
const inv = rt && rt.length >= (i + 1) * 12 ? invertAffine(affineAt(rt, i)) : IDENTITY;
|
|
459
|
+
if (inv) blendSurfaces.set(roid[i], mapSurface({ kind: "planes", planes, tol }, inv));
|
|
460
|
+
}
|
|
461
|
+
} finally {
|
|
462
|
+
go.delete?.();
|
|
463
|
+
}
|
|
464
|
+
return out;
|
|
465
|
+
};
|
|
466
|
+
|
|
426
467
|
// Replay a recorded transform chain onto a solid. Each record maps back to the op
|
|
427
468
|
// that produced it, so the replayed solid rebuilds the same chain on its own canon.
|
|
428
469
|
const replay = (solid, chain) => chain.reduce(
|
|
@@ -503,7 +544,7 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
|
|
|
503
544
|
// key omits it for the same reason); it just spells out that the ball
|
|
504
545
|
// tessellation, and so the result, is tier-dependent.
|
|
505
546
|
return cached(h("roundAll", hash, r, quality), () =>
|
|
506
|
-
prismRoundAllFast(m, hash, r) ?? T(meshRoundAll(wasm, m, r, quality)));
|
|
547
|
+
prismRoundAllFast(m, hash, r) ?? markFlatFaces(m, T(meshRoundAll(wasm, m, r, quality)), r));
|
|
507
548
|
},
|
|
508
549
|
// batch difference: first minus the union of the rest, evaluated as one boolean
|
|
509
550
|
// tree — no materialized intermediate union (the unionRaw memory note applies)
|
|
@@ -538,7 +579,6 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
|
|
|
538
579
|
// fresh so cached-solid reuse under another label cannot collide — the same
|
|
539
580
|
// guarantee asOriginal() gives the plain path below.
|
|
540
581
|
const g0 = m.getMesh();
|
|
541
|
-
const isBlend = (oid) => !!oidPolicies.get(oid)?.boundaryLines;
|
|
542
582
|
const oids0 = new Set(g0.runOriginalID);
|
|
543
583
|
// Sector-aware re-stamp: a provenance-sectored loft (the `sector` policy
|
|
544
584
|
// marker) must keep every run's identity — folding them (either the plain
|
|
@@ -561,14 +601,16 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
|
|
|
561
601
|
featureLabels.set(newId, name);
|
|
562
602
|
const pol = oidPolicies.get(oldId);
|
|
563
603
|
if (pol !== undefined) oidPolicies.set(newId, pol);
|
|
604
|
+
const surf = blendSurfaces.get(oldId); // analytic normals ride the 1:1 stamp too
|
|
605
|
+
if (surf) blendSurfaces.set(newId, surf);
|
|
564
606
|
setIds.push(newId);
|
|
565
607
|
}
|
|
566
608
|
return { value: wrap(o, lh), pin: o, dispose: () => {
|
|
567
|
-
for (const id2 of setIds) { featureLabels.delete(id2); oidPolicies.delete(id2); }
|
|
609
|
+
for (const id2 of setIds) { featureLabels.delete(id2); oidPolicies.delete(id2); blendSurfaces.delete(id2); }
|
|
568
610
|
o.delete?.();
|
|
569
611
|
} };
|
|
570
612
|
}
|
|
571
|
-
if ([...oids0].some(
|
|
613
|
+
if ([...oids0].some(keepsOwnId)) {
|
|
572
614
|
const { baseId, blendIdFor, blendIds } = reserveBlendRestamp(oids0);
|
|
573
615
|
// base-group policy: the same triangle-weighted majority vote as the plain
|
|
574
616
|
// path, but over the NON-blend runs only — blend runs would elect BLEND for
|
|
@@ -578,7 +620,7 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
|
|
|
578
620
|
const weightByKey = new Map();
|
|
579
621
|
let bestWeight = -1, basePol;
|
|
580
622
|
for (let r = 0; r < roid.length; r++) {
|
|
581
|
-
if (
|
|
623
|
+
if (blendIdFor.has(roid[r])) continue;
|
|
582
624
|
const pol = oidPolicies.get(roid[r]) ?? SMOOTH;
|
|
583
625
|
const key = `${pol.creaseAngle}/${pol.sameSurfaceLines}/${!!pol.boundaryLines}`;
|
|
584
626
|
const weight = (weightByKey.get(key) || 0) + (ri[r + 1] / 3 - ri[r] / 3);
|
|
@@ -586,7 +628,7 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
|
|
|
586
628
|
const better = weight > bestWeight || (weight === bestWeight && !pol.sameSurfaceLines && basePol?.sameSurfaceLines);
|
|
587
629
|
if (better) { bestWeight = weight; basePol = pol; }
|
|
588
630
|
}
|
|
589
|
-
g0.runOriginalID = Uint32Array.from(roid, (o2) =>
|
|
631
|
+
g0.runOriginalID = Uint32Array.from(roid, (o2) => blendIdFor.get(o2) ?? baseId);
|
|
590
632
|
const o = T(new Manifold(g0));
|
|
591
633
|
g0.delete?.();
|
|
592
634
|
featureLabels.set(baseId, name);
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
// the two facetings still meets the tier's sagitta tolerance.
|
|
30
30
|
|
|
31
31
|
import { segsForSagitta } from "./circle-segs.js";
|
|
32
|
+
import { SMOOTH, cosDeg } from "./shading-policy.js";
|
|
32
33
|
|
|
33
34
|
// Sphere tessellation from the facet sagitta r·(1 − cos(π/segs)): pick the
|
|
34
35
|
// fewest segments that keep it under the quality tier's tolerance — its own
|
|
@@ -83,6 +84,121 @@ export function meshRoundAll(wasm, m, r, quality) {
|
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Flat-face shading. The reference path's result is one fresh surface, shaded
|
|
89
|
+
// SMOOTH (35° crease), and the rounding ball's facets bend far less than that, so
|
|
90
|
+
// a flat face used to share its corner normals with the band facets around it.
|
|
91
|
+
// The vertex sum is unweighted, so a large face split into two triangles — a
|
|
92
|
+
// sloped palm plate's top — took a several-degree tilt at each corner and showed
|
|
93
|
+
// it as a shading gradient across the whole face (cloud feedback #167).
|
|
94
|
+
//
|
|
95
|
+
// The cure rests on the invariant above: the chain returns every planar face of
|
|
96
|
+
// the input to its own plane. So the input's flat faces, found here, say exactly
|
|
97
|
+
// where the result is flat; the backend registers them as an analytic "planes"
|
|
98
|
+
// descriptor (blend-surfaces.js), and creased-normals then shades every vertex on
|
|
99
|
+
// one of those planes — the band's seam vertices too, since the band is tangent
|
|
100
|
+
// there — with the plane's normal, the same way a fillet band's seam agrees with
|
|
101
|
+
// its face.
|
|
102
|
+
//
|
|
103
|
+
// "Flat" means flat the way the INPUT shades it: a coplanar group counts only if
|
|
104
|
+
// every edge bounding it is one creased-normals would shade hard (a bend past the
|
|
105
|
+
// surface's crease angle, or a cut seam). A rod's wall facets, or a slot's sides
|
|
106
|
+
// running tangentially into its round ends, meet their neighbours softly — the
|
|
107
|
+
// input already shades them as part of a curved surface, and pinning them to
|
|
108
|
+
// their own planes would facet the rounded result.
|
|
109
|
+
//
|
|
110
|
+
// `g` is a MeshGL (or the same fields on plain arrays); `policyFor(oid)` returns
|
|
111
|
+
// that surface's shading policy. Returns [{ n, d }] with n·x = d on the plane.
|
|
112
|
+
const PLANE_COS = cosDeg(0.05); // coplanar neighbours: a boolean split, not a bend
|
|
113
|
+
export function flatFacePlanes(g, { policyFor = () => SMOOTH } = {}) {
|
|
114
|
+
const np = g.numProp, vp = g.vertProperties, tris = g.triVerts;
|
|
115
|
+
const nTri = (tris.length / 3) | 0, nVert = (vp.length / np) | 0;
|
|
116
|
+
const remap = new Uint32Array(nVert);
|
|
117
|
+
for (let i = 0; i < nVert; i++) remap[i] = i;
|
|
118
|
+
const mf = g.mergeFromVert, mt = g.mergeToVert;
|
|
119
|
+
if (mf && mt) for (let i = 0; i < mf.length; i++) remap[mf[i]] = mt[i];
|
|
120
|
+
const triOID = new Uint32Array(nTri);
|
|
121
|
+
const ri = g.runIndex, roid = g.runOriginalID;
|
|
122
|
+
if (ri && roid) for (let r = 0; r < roid.length; r++)
|
|
123
|
+
for (let t = ri[r] / 3; t < ri[r + 1] / 3; t++) triOID[t] = roid[r];
|
|
124
|
+
|
|
125
|
+
// facet normals, areas and centroids; a degenerate triangle has no normal and
|
|
126
|
+
// takes no part — it neither joins a face nor disqualifies one
|
|
127
|
+
const fn = new Float64Array(nTri * 3), area = new Float64Array(nTri), cen = new Float64Array(nTri * 3);
|
|
128
|
+
let span = 0;
|
|
129
|
+
for (let t = 0; t < nTri; t++) {
|
|
130
|
+
const a = tris[t * 3] * np, b = tris[t * 3 + 1] * np, c = tris[t * 3 + 2] * np;
|
|
131
|
+
const ux = vp[b] - vp[a], uy = vp[b + 1] - vp[a + 1], uz = vp[b + 2] - vp[a + 2];
|
|
132
|
+
const vx = vp[c] - vp[a], vy = vp[c + 1] - vp[a + 1], vz = vp[c + 2] - vp[a + 2];
|
|
133
|
+
const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx;
|
|
134
|
+
const L = Math.hypot(nx, ny, nz);
|
|
135
|
+
area[t] = L / 2;
|
|
136
|
+
if (L > 0) { fn[t * 3] = nx / L; fn[t * 3 + 1] = ny / L; fn[t * 3 + 2] = nz / L; }
|
|
137
|
+
for (let k = 0; k < 3; k++) cen[t * 3 + k] = (vp[a + k] + vp[b + k] + vp[c + k]) / 3;
|
|
138
|
+
span = Math.max(span, Math.abs(vp[a]), Math.abs(vp[a + 1]), Math.abs(vp[a + 2]));
|
|
139
|
+
}
|
|
140
|
+
const live = (t) => area[t] > 1e-9;
|
|
141
|
+
const dot = (t, u) => fn[t * 3] * fn[u * 3] + fn[t * 3 + 1] * fn[u * 3 + 1] + fn[t * 3 + 2] * fn[u * 3 + 2];
|
|
142
|
+
|
|
143
|
+
// edge → incident triangles, on welded vertex ids
|
|
144
|
+
const edges = new Map();
|
|
145
|
+
for (let t = 0; t < nTri; t++) for (let k = 0; k < 3; k++) {
|
|
146
|
+
const p = remap[tris[t * 3 + k]], q = remap[tris[t * 3 + ((k + 1) % 3)]];
|
|
147
|
+
const key = p < q ? p * nVert + q : q * nVert + p;
|
|
148
|
+
const list = edges.get(key);
|
|
149
|
+
if (list) list.push(t); else edges.set(key, [t]);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// coplanar groups (union-find over shared edges)
|
|
153
|
+
const parent = new Int32Array(nTri);
|
|
154
|
+
for (let t = 0; t < nTri; t++) parent[t] = t;
|
|
155
|
+
const find = (t) => { while (parent[t] !== t) { parent[t] = parent[parent[t]]; t = parent[t]; } return t; };
|
|
156
|
+
for (const list of edges.values()) {
|
|
157
|
+
if (list.length !== 2) continue;
|
|
158
|
+
const [t, u] = list;
|
|
159
|
+
if (live(t) && live(u) && dot(t, u) > PLANE_COS) parent[find(t)] = find(u);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// a group is a flat face only if every edge leaving it would shade hard
|
|
163
|
+
const soft = new Uint8Array(nTri); // indexed by group root
|
|
164
|
+
const hard = (t, u) => {
|
|
165
|
+
const pt = policyFor(triOID[t]) ?? SMOOTH, pu = policyFor(triOID[u]) ?? SMOOTH;
|
|
166
|
+
if (triOID[t] !== triOID[u] && !(pt.boundaryLines || pu.boundaryLines)) return true;
|
|
167
|
+
return dot(t, u) < cosDeg(pt.creaseAngle);
|
|
168
|
+
};
|
|
169
|
+
for (const list of edges.values()) {
|
|
170
|
+
if (list.length !== 2) continue; // non-manifold: no smooth neighbour to share with
|
|
171
|
+
const [t, u] = list;
|
|
172
|
+
if (!live(t) || !live(u) || find(t) === find(u)) continue;
|
|
173
|
+
if (!hard(t, u)) soft[find(t)] = 1;
|
|
174
|
+
if (!hard(u, t)) soft[find(u)] = 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// one area-weighted plane per surviving group, merged where two groups share a
|
|
178
|
+
// plane (a degenerate triangle can split one face into two)
|
|
179
|
+
const acc = new Map();
|
|
180
|
+
for (let t = 0; t < nTri; t++) {
|
|
181
|
+
if (!live(t)) continue;
|
|
182
|
+
const root = find(t);
|
|
183
|
+
if (soft[root]) continue;
|
|
184
|
+
let e = acc.get(root);
|
|
185
|
+
if (!e) acc.set(root, (e = { n: [0, 0, 0], c: [0, 0, 0], a: 0 }));
|
|
186
|
+
for (let k = 0; k < 3; k++) { e.n[k] += fn[t * 3 + k] * area[t]; e.c[k] += cen[t * 3 + k] * area[t]; }
|
|
187
|
+
e.a += area[t];
|
|
188
|
+
}
|
|
189
|
+
const dTol = Math.max(1e-6, span * 1e-7);
|
|
190
|
+
const planes = [];
|
|
191
|
+
for (const e of acc.values()) {
|
|
192
|
+
const L = Math.hypot(...e.n);
|
|
193
|
+
if (!(L > 0)) continue;
|
|
194
|
+
const n = e.n.map((x) => x / L);
|
|
195
|
+
const d = (n[0] * e.c[0] + n[1] * e.c[1] + n[2] * e.c[2]) / e.a;
|
|
196
|
+
const dup = planes.find((p) => p.n[0] * n[0] + p.n[1] * n[1] + p.n[2] * n[2] > PLANE_COS && Math.abs(p.d - d) < dTol);
|
|
197
|
+
if (!dup) planes.push({ n, d });
|
|
198
|
+
}
|
|
199
|
+
return planes;
|
|
200
|
+
}
|
|
201
|
+
|
|
86
202
|
// ---------------------------------------------------------------------------
|
|
87
203
|
// Prism detection for the fast path (manifold-backend.js). The Minkowski chain
|
|
88
204
|
// above is seconds-per-thousand-triangles, but roundAll's expensive real-world
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
// pointing at itself. Nodes are laid out in pre-order, so an internal
|
|
38
38
|
// node's left child is always the next node.
|
|
39
39
|
|
|
40
|
+
import { core, poisonCore } from "../core/core.js";
|
|
41
|
+
import { buildCoreBVH } from "../core/bvh-core.js";
|
|
42
|
+
|
|
40
43
|
const LEAF = 4; // max triangles per leaf
|
|
41
44
|
|
|
42
45
|
// Coords per triangle in a `vertices` store: v0,v1,v2 interleaved. The ONE place
|
|
@@ -285,13 +288,47 @@ function rayTri(ox, oy, oz, dx, dy, dz, V, base, tMin) {
|
|
|
285
288
|
// meshes would keep an index alive for as long as anything held its mesh, which
|
|
286
289
|
// is the quiet retention this pass exists to remove. Here the index's lifetime is
|
|
287
290
|
// visibly the caller's scope.
|
|
291
|
+
//
|
|
292
|
+
// The native core (core/core.js) is used only where partforge OWNS the index's
|
|
293
|
+
// lifetime: with no Map (the caller — meshGaps — frees it), or with a Map made
|
|
294
|
+
// by coreBVHCache() (measure()'s, freed by measure()). Those get the core's
|
|
295
|
+
// index (core/bvh-core.js): same queries, same bits, living in WebAssembly
|
|
296
|
+
// memory until disposeBVHs(). A caller's own plain Map — meshGaps' public
|
|
297
|
+
// `bvhCache` option — and buildBVH() itself keep getting the JS index, exactly
|
|
298
|
+
// as before: code outside partforge is never handed something it must free.
|
|
288
299
|
export function cachedBVH(mesh, cache) {
|
|
289
|
-
if (!cache) return
|
|
300
|
+
if (!cache) return indexFor(mesh, true);
|
|
290
301
|
let bvh = cache.get(mesh);
|
|
291
|
-
if (!bvh) cache.set(mesh, (bvh =
|
|
302
|
+
if (!bvh) cache.set(mesh, (bvh = indexFor(mesh, cache[CORE_CACHE] === true)));
|
|
292
303
|
return bvh;
|
|
293
304
|
}
|
|
294
305
|
|
|
306
|
+
const CORE_CACHE = Symbol("coreBVHCache");
|
|
307
|
+
// A Map for cachedBVH that may hold core indexes — its owner must disposeBVHs().
|
|
308
|
+
export function coreBVHCache() {
|
|
309
|
+
const m = new Map();
|
|
310
|
+
m[CORE_CACHE] = true;
|
|
311
|
+
return m;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function indexFor(mesh, allowCore) {
|
|
315
|
+
const c = allowCore ? core() : null;
|
|
316
|
+
if (c) {
|
|
317
|
+
try {
|
|
318
|
+
return buildCoreBVH(c, triangleVertices(mesh), () => buildBVH(mesh));
|
|
319
|
+
} catch {
|
|
320
|
+
poisonCore(c); // a fault while building: this realm's core is done; JS from here
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return buildBVH(mesh);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Free every core index among `bvhs` (a Map's values, or any iterable); JS
|
|
327
|
+
// indexes need nothing. Safe to call twice.
|
|
328
|
+
export function disposeBVHs(bvhs) {
|
|
329
|
+
for (const b of bvhs) b?.dispose?.();
|
|
330
|
+
}
|
|
331
|
+
|
|
295
332
|
export function buildBVH(mesh) {
|
|
296
333
|
const verts = triangleVertices(mesh);
|
|
297
334
|
const count = verts.length / 9;
|
|
@@ -407,6 +444,8 @@ export function buildBVH(mesh) {
|
|
|
407
444
|
// distance at leaf pairs; early-exits at 0 (touching/intersecting). The stack
|
|
408
445
|
// holds node-index PAIRS, pushed and popped two entries at a time.
|
|
409
446
|
function distanceTo(other) {
|
|
447
|
+
// A core index on the other side (bvh-core.js) meets this one through its JS twin.
|
|
448
|
+
if (other?.jsIndex) other = other.jsIndex();
|
|
410
449
|
const oV = other.vertices, oB = other._bounds, oM = other._meta, oO = other._order;
|
|
411
450
|
let best = { d2: Infinity, a: null, b: null };
|
|
412
451
|
const stack = [0, 0];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildView } from "./build.js";
|
|
2
|
-
import { cachedBVH } from "./bvh.js";
|
|
2
|
+
import { cachedBVH, disposeBVHs } from "./bvh.js";
|
|
3
3
|
|
|
4
4
|
// A measured pair distance at or below this (mm) counts as touching — absorbs
|
|
5
5
|
// posing float error while staying far below any real print clearance.
|
|
@@ -36,15 +36,20 @@ export function meshGaps(built, { bvhCache, prior, onPair } = {}) {
|
|
|
36
36
|
return bvhOf.get(it.name);
|
|
37
37
|
};
|
|
38
38
|
const out = [];
|
|
39
|
-
|
|
40
|
-
for (let
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
try {
|
|
40
|
+
for (let i = 0; i < items.length; i++) {
|
|
41
|
+
for (let j = i + 1; j < items.length; j++) {
|
|
42
|
+
const a = items[i].name, b = items[j].name;
|
|
43
|
+
const reused = prior?.(a, b);
|
|
44
|
+
const { distance, at } = reused ?? bvh(items[i]).distanceTo(bvh(items[j]));
|
|
45
|
+
const g = { a, b, distance, at };
|
|
46
|
+
onPair?.(a, b, { distance, at });
|
|
47
|
+
out.push(g);
|
|
48
|
+
}
|
|
47
49
|
}
|
|
50
|
+
} finally {
|
|
51
|
+
// With no caller Map these indexes are ours; with one, its owner frees them.
|
|
52
|
+
if (!bvhCache) disposeBVHs(bvhOf.values());
|
|
48
53
|
}
|
|
49
54
|
return out;
|
|
50
55
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildView } from "./build.js";
|
|
2
|
-
import { cachedBVH } from "./bvh.js";
|
|
2
|
+
import { cachedBVH, coreBVHCache, disposeBVHs } from "./bvh.js";
|
|
3
3
|
import { assemblyOverlaps } from "../assembly.js";
|
|
4
4
|
import { resolveParams, buildPosed } from "../part-model.js";
|
|
5
5
|
import { newReadSink, expandReads } from "../read-recorder.js";
|
|
@@ -257,7 +257,7 @@ export function measure(kernel, part, view = Object.keys(part.views)[0], params
|
|
|
257
257
|
// memory is unchanged (meshGaps already held every sub-part's index at once);
|
|
258
258
|
// the cache just fills it earlier. min-wall indexes exactly one mesh, so it is
|
|
259
259
|
// handed the resolved BVH rather than the Map.
|
|
260
|
-
const bvhCache =
|
|
260
|
+
const bvhCache = coreBVHCache();
|
|
261
261
|
// Sample budget for the min-wall pass. A part that declares a min-wall gate (a
|
|
262
262
|
// process profile or an `expect` mentioning it) gets the full resolution, because
|
|
263
263
|
// a gate's verdict rides on the reading. Everything else gets the diagnostic
|
|
@@ -440,6 +440,11 @@ export function measure(kernel, part, view = Object.keys(part.views)[0], params
|
|
|
440
440
|
})
|
|
441
441
|
: [])
|
|
442
442
|
: undefined;
|
|
443
|
+
// Both BVH passes (min-wall above, gaps here) are done: free the indexes this
|
|
444
|
+
// call owns. A native-core index lives in WebAssembly memory until freed; a JS
|
|
445
|
+
// one needs nothing. (A throw before this point leaves them to the core's
|
|
446
|
+
// FinalizationRegistry backstop.)
|
|
447
|
+
disposeBVHs(bvhCache.values());
|
|
443
448
|
|
|
444
449
|
// Rebuilds with the same kernel and cleans up at its end — every solid fact
|
|
445
450
|
// above is already read, so this is safe.
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
// 400k triangles and found no wall" is a very different statement from "nobody
|
|
25
25
|
// measured", and the two used to be indistinguishable downstream.
|
|
26
26
|
import { buildBVH, readTriangleInto } from "./bvh.js";
|
|
27
|
+
import { hypot3 } from "../geometry/js-math.js";
|
|
27
28
|
|
|
28
29
|
// Triangle budget above which minWall samples. Chosen so the parts people actually
|
|
29
30
|
// author stay exact: everything in src/parts/ is 200–10,000 triangles, and a
|
|
@@ -78,6 +79,14 @@ export const BAND_CEIL = 1.5;
|
|
|
78
79
|
// one is built. It does not interact with sampling — sampling picks WHICH rays to
|
|
79
80
|
// cast, not how the index is built, so a shared BVH is equally valid sampled or exact.
|
|
80
81
|
export function minWall(mesh, { maxThickness, maxSamples = MAX_SAMPLES, bvh = buildBVH(mesh), band = null } = {}) {
|
|
82
|
+
// A core BVH (cachedBVH's, when the native core is on) runs the whole pass in
|
|
83
|
+
// C++ — one call instead of a JS loop crossing into WebAssembly per ray. If
|
|
84
|
+
// the core cannot answer (undefined) the JS below runs on the index's JS twin.
|
|
85
|
+
if (bvh.core) {
|
|
86
|
+
const r = bvh.minWall({ maxThickness, maxSamples, band });
|
|
87
|
+
if (r !== undefined) return r;
|
|
88
|
+
bvh = bvh.jsIndex();
|
|
89
|
+
}
|
|
81
90
|
const n = bvh.triangleCount;
|
|
82
91
|
if (n === 0) return null;
|
|
83
92
|
const V = bvh.vertices;
|
|
@@ -89,7 +98,7 @@ export function minWall(mesh, { maxThickness, maxSamples = MAX_SAMPLES, bvh = bu
|
|
|
89
98
|
// are not in the tree; that only shrinks a ray cap, never a reading.)
|
|
90
99
|
if (maxThickness == null) {
|
|
91
100
|
const rb = bvh.rootBounds;
|
|
92
|
-
maxThickness =
|
|
101
|
+
maxThickness = hypot3(rb[3] - rb[0], rb[4] - rb[1], rb[5] - rb[2]) + 1;
|
|
93
102
|
}
|
|
94
103
|
|
|
95
104
|
// `maxSamples: 0` (or any non-positive) is the explicit "no cap, cast everything"
|
|
@@ -119,7 +128,7 @@ export function minWall(mesh, { maxThickness, maxSamples = MAX_SAMPLES, bvh = bu
|
|
|
119
128
|
const e1x = tri[3] - v0x, e1y = tri[4] - v0y, e1z = tri[5] - v0z;
|
|
120
129
|
const e2x = tri[6] - v0x, e2y = tri[7] - v0y, e2z = tri[8] - v0z;
|
|
121
130
|
let nx = e1y * e2z - e1z * e2y, ny = e1z * e2x - e1x * e2z, nz = e1x * e2y - e1y * e2x;
|
|
122
|
-
const len =
|
|
131
|
+
const len = hypot3(nx, ny, nz);
|
|
123
132
|
if (len < 1e-9) continue; // degenerate triangle: no normal, no ray
|
|
124
133
|
nx /= len; ny /= len; nz /= len; // outward normal (manifold winding)
|
|
125
134
|
const c = [(v0x + tri[3] + tri[6]) / 3, (v0y + tri[4] + tri[7]) / 3, (v0z + tri[5] + tri[8]) / 3];
|
package/src/oracle.js
CHANGED
|
@@ -25,6 +25,9 @@ export { verify } from "./framework/oracle/verify.js";
|
|
|
25
25
|
export { createChangeTracker } from "./framework/oracle/changes.js";
|
|
26
26
|
export { buildBVH, meshTriangles } from "./framework/oracle/bvh.js";
|
|
27
27
|
export { minWall } from "./framework/oracle/min-wall.js";
|
|
28
|
+
// The native core's switch (framework/core/core.js): bit-identical either way, so
|
|
29
|
+
// this is a performance and kill switch, never a behaviour choice.
|
|
30
|
+
export { setCoreEnabled } from "./framework/core/core.js";
|
|
28
31
|
export { overhang } from "./framework/oracle/overhang.js";
|
|
29
32
|
// Mesh file parsers — the import pipeline's own readers, browser-safe pure
|
|
30
33
|
// functions; the oracle package's corpus tests read real files through them.
|
package/types/oracle.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export {
|
|
|
16
16
|
type ChangeTracker, type ChangesReport, type SubPartChange, type ChangeRegion, type ChangeOpRef,
|
|
17
17
|
// mesh facts, gaps, BVH, min wall
|
|
18
18
|
meshVolume, bboxSize, bounds, meshArea, assemblyGaps, meshGaps, buildBVH, meshTriangles, minWall, overhang,
|
|
19
|
+
// the native core's switch
|
|
20
|
+
setCoreEnabled,
|
|
19
21
|
type Gap, type BVH,
|
|
20
22
|
// mesh file parsers (the import pipeline's own readers)
|
|
21
23
|
parseStl, parse3MF,
|
package/types/testing.d.ts
CHANGED
|
@@ -264,6 +264,16 @@ export function minWall(
|
|
|
264
264
|
totalTriangles: number;
|
|
265
265
|
} | null;
|
|
266
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Turn partforge's native core (src/framework/core/ — creasedNormals and the
|
|
269
|
+
* oracle's BVH + min-wall compiled to WebAssembly) on or off for this realm. On
|
|
270
|
+
* by default wherever WebAssembly exists. Output is bit-identical either way, so
|
|
271
|
+
* this is a performance and kill switch, never a behaviour choice. A worker is
|
|
272
|
+
* its own realm: set it there (or `globalThis.PARTFORGE_CORE = false`, which is
|
|
273
|
+
* read on every use).
|
|
274
|
+
*/
|
|
275
|
+
export function setCoreEnabled(on: boolean): void;
|
|
276
|
+
|
|
267
277
|
/**
|
|
268
278
|
* Unsupported downward-facing surface (oracle/overhang.js): the mm² of faces
|
|
269
279
|
* steeper than `maxAngle` from vertical, excluding the footprint on the bed
|