@code3d/core 0.0.1-alpha.0 → 0.0.1-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +223 -786
- package/THIRD_PARTY.md +40 -0
- package/bld/THIRD_PARTY_NOTICES.txt +182 -0
- package/bld/chunks/chunk-BF55AIEQ.js +31 -0
- package/bld/chunks/chunk-BF55AIEQ.js.map +7 -0
- package/bld/chunks/chunk-P5VGKAEM.js +30 -0
- package/bld/chunks/chunk-P5VGKAEM.js.map +7 -0
- package/bld/chunks/chunk-RPY2WVCB.js +24834 -0
- package/bld/chunks/chunk-RPY2WVCB.js.map +7 -0
- package/bld/chunks/chunk-TJIN6S4R.js +1 -0
- package/bld/chunks/chunk-TJIN6S4R.js.map +7 -0
- package/bld/chunks/chunk-U5G2VU2I.js +19 -0
- package/bld/chunks/chunk-U5G2VU2I.js.map +7 -0
- package/bld/library/cached.d.ts +33 -0
- package/bld/library/cached.d.ts.map +1 -0
- package/bld/library/font.d.ts +39 -0
- package/bld/library/font.d.ts.map +1 -0
- package/bld/library/google-font.d.ts +14 -0
- package/bld/library/google-font.d.ts.map +1 -0
- package/bld/library/index.d.ts +8 -2
- package/bld/library/index.d.ts.map +1 -1
- package/bld/library/index.js +60 -3
- package/bld/library/index.js.map +7 -1
- package/bld/library/kernel-artifact-codec.d.ts.map +1 -1
- package/bld/library/kernel-cache.d.ts +24 -6
- package/bld/library/kernel-cache.d.ts.map +1 -1
- package/bld/library/material.d.ts +1 -1
- package/bld/library/material.d.ts.map +1 -1
- package/bld/library/open-cascade.d.ts +4 -0
- package/bld/library/open-cascade.d.ts.map +1 -0
- package/bld/library/replicad.d.ts +3 -2
- package/bld/library/replicad.d.ts.map +1 -1
- package/bld/library/replicad.js +10 -24
- package/bld/library/replicad.js.map +7 -1
- package/bld/library/retained-memory.d.ts.map +1 -1
- package/bld/library/runtime.d.ts +146 -80
- package/bld/library/runtime.d.ts.map +1 -1
- package/bld/library/sketch-solver.d.ts +1 -1
- package/bld/library/sketch-solver.d.ts.map +1 -1
- package/bld/library/sketch.d.ts +9 -1
- package/bld/library/sketch.d.ts.map +1 -1
- package/bld/library/text.d.ts +53 -0
- package/bld/library/text.d.ts.map +1 -0
- package/bld/library/three.js +3 -3
- package/bld/library/three.js.map +7 -1
- package/bld/library/topology.d.ts.map +1 -1
- package/bld/node/index.d.ts.map +1 -1
- package/bld/node/index.js +62 -14
- package/bld/node/index.js.map +7 -1
- package/bld/node/replicad.js +13 -3
- package/bld/node/replicad.js.map +7 -1
- package/bld/tooling/index.d.ts +17 -15
- package/bld/tooling/index.d.ts.map +1 -1
- package/bld/tooling/index.js +147 -19
- package/bld/tooling/index.js.map +7 -1
- package/package.json +18 -6
- package/src/library/cached.ts +132 -0
- package/src/library/font.ts +186 -0
- package/src/library/google-font.ts +97 -0
- package/src/library/index.ts +8 -3
- package/src/library/kernel-artifact-codec.ts +129 -20
- package/src/library/kernel-cache.ts +128 -34
- package/src/library/loft.ts +4 -0
- package/src/library/material.ts +3 -4
- package/src/library/open-cascade.ts +13 -0
- package/src/library/replicad.ts +5 -5
- package/src/library/retained-memory.ts +6 -1
- package/src/library/runtime.ts +2064 -1730
- package/src/library/sketch-solver.ts +3 -1
- package/src/library/sketch.ts +81 -13
- package/src/library/text.ts +477 -0
- package/src/library/topology.ts +24 -0
- package/src/library/tsconfig.json +2 -1
- package/src/node/index.ts +14 -3
- package/src/node/tsconfig.json +2 -1
- package/src/tooling/index.ts +48 -46
- package/src/tooling/tsconfig.json +2 -1
- package/bld/library/alignment-geometry.js +0 -322
- package/bld/library/alignment-geometry.js.map +0 -1
- package/bld/library/bound-solver.js +0 -252
- package/bld/library/bound-solver.js.map +0 -1
- package/bld/library/extrude.js +0 -28
- package/bld/library/extrude.js.map +0 -1
- package/bld/library/kernel-artifact-codec.js +0 -148
- package/bld/library/kernel-artifact-codec.js.map +0 -1
- package/bld/library/kernel-cache.js +0 -245
- package/bld/library/kernel-cache.js.map +0 -1
- package/bld/library/kernel-shapes.js +0 -108
- package/bld/library/kernel-shapes.js.map +0 -1
- package/bld/library/loft.js +0 -161
- package/bld/library/loft.js.map +0 -1
- package/bld/library/material.js +0 -176
- package/bld/library/material.js.map +0 -1
- package/bld/library/model-color.js +0 -36
- package/bld/library/model-color.js.map +0 -1
- package/bld/library/open-cascade-error.js +0 -22
- package/bld/library/open-cascade-error.js.map +0 -1
- package/bld/library/relation-solver.js +0 -258
- package/bld/library/relation-solver.js.map +0 -1
- package/bld/library/retained-memory.js +0 -27
- package/bld/library/retained-memory.js.map +0 -1
- package/bld/library/runtime.js +0 -2954
- package/bld/library/runtime.js.map +0 -1
- package/bld/library/shell.js +0 -221
- package/bld/library/shell.js.map +0 -1
- package/bld/library/sketch-curve-intersections.js +0 -117
- package/bld/library/sketch-curve-intersections.js.map +0 -1
- package/bld/library/sketch-curves.js +0 -89
- package/bld/library/sketch-curves.js.map +0 -1
- package/bld/library/sketch-drag-rules.js +0 -522
- package/bld/library/sketch-drag-rules.js.map +0 -1
- package/bld/library/sketch-face.js +0 -72
- package/bld/library/sketch-face.js.map +0 -1
- package/bld/library/sketch-incidence.js +0 -114
- package/bld/library/sketch-incidence.js.map +0 -1
- package/bld/library/sketch-precision.js +0 -55
- package/bld/library/sketch-precision.js.map +0 -1
- package/bld/library/sketch-regions.js +0 -193
- package/bld/library/sketch-regions.js.map +0 -1
- package/bld/library/sketch-solver.js +0 -578
- package/bld/library/sketch-solver.js.map +0 -1
- package/bld/library/sketch.js +0 -650
- package/bld/library/sketch.js.map +0 -1
- package/bld/library/spatial.js +0 -195
- package/bld/library/spatial.js.map +0 -1
- package/bld/library/topology-id.js +0 -67
- package/bld/library/topology-id.js.map +0 -1
- package/bld/library/topology-inspection.js +0 -267
- package/bld/library/topology-inspection.js.map +0 -1
- package/bld/library/topology.js +0 -455
- package/bld/library/topology.js.map +0 -1
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import type {OpenCascadeInstance} from '@code3d/opencascade';
|
|
2
|
-
import {getOC} from 'replicad';
|
|
3
|
-
import {estimateRetainedBytes} from './retained-memory.js';
|
|
4
1
|
import {
|
|
5
2
|
decodeKernelArtifact,
|
|
6
3
|
encodeKernelArtifact,
|
|
7
4
|
} from './kernel-artifact-codec.js';
|
|
5
|
+
import {estimateRetainedBytes} from './retained-memory.js';
|
|
8
6
|
|
|
9
7
|
/** The host opens storage before synchronous evaluation and owns its lifetime. */
|
|
10
8
|
export interface KernelArtifactStore {
|
|
9
|
+
/** Encoded writes retained by the host for the current working version. */
|
|
10
|
+
readonly pendingWriteBytes?: number;
|
|
11
11
|
get(id: string): Uint8Array | undefined;
|
|
12
|
+
getMany(ids: readonly string[]): readonly (Uint8Array | undefined)[];
|
|
12
13
|
set(id: string, bytes: Uint8Array): void;
|
|
13
14
|
touch(id: string): boolean;
|
|
15
|
+
/** Update access order together, returning existence in the same order. */
|
|
16
|
+
touchMany(ids: readonly string[]): readonly boolean[];
|
|
14
17
|
delete(id: string): void;
|
|
18
|
+
/** Schedule persistence; hosts may complete disk I/O in the background. */
|
|
15
19
|
flush(): void;
|
|
16
20
|
}
|
|
17
21
|
|
|
@@ -23,6 +27,11 @@ export type KernelArtifact<Value> = Readonly<{
|
|
|
23
27
|
value: Value;
|
|
24
28
|
}>;
|
|
25
29
|
|
|
30
|
+
export type CacheCodec<Value> = Readonly<{
|
|
31
|
+
encoder(value: Value): Uint8Array;
|
|
32
|
+
decoder(bytes: Uint8Array): Value;
|
|
33
|
+
}>;
|
|
34
|
+
|
|
26
35
|
export type KernelValueLifecycle<Value> = Readonly<{
|
|
27
36
|
estimateBytes(value: Value): number;
|
|
28
37
|
retain(value: Value): Value;
|
|
@@ -38,7 +47,7 @@ type CacheEntry<Value> = Readonly<{
|
|
|
38
47
|
release(value: Value): void;
|
|
39
48
|
}>;
|
|
40
49
|
|
|
41
|
-
export function
|
|
50
|
+
export function createComputationCache({
|
|
42
51
|
maximumBytes = 2 * 1024 ** 3,
|
|
43
52
|
nativeAllocatedBytes,
|
|
44
53
|
}: {
|
|
@@ -56,8 +65,10 @@ export function createKernelOperationCache({
|
|
|
56
65
|
let store: KernelArtifactStore | undefined;
|
|
57
66
|
let persistentHits = 0;
|
|
58
67
|
let persistentWrites = 0;
|
|
68
|
+
let persistenceEncodeMilliseconds = 0;
|
|
59
69
|
let persistenceErrors = 0;
|
|
60
70
|
const persisted = new Set<string>();
|
|
71
|
+
const pendingPersistence = new Map<string, () => Uint8Array>();
|
|
61
72
|
let externalBytes = 0;
|
|
62
73
|
|
|
63
74
|
/** The host accounts for in-flight inputs and all auxiliary native heaps. */
|
|
@@ -69,6 +80,7 @@ export function createKernelOperationCache({
|
|
|
69
80
|
function setKernelArtifactStore(next: KernelArtifactStore | undefined): void {
|
|
70
81
|
store = next;
|
|
71
82
|
persisted.clear();
|
|
83
|
+
pendingPersistence.clear();
|
|
72
84
|
}
|
|
73
85
|
|
|
74
86
|
function accessStore<Result>(
|
|
@@ -97,6 +109,7 @@ export function createKernelOperationCache({
|
|
|
97
109
|
const used = new Set<string>();
|
|
98
110
|
currentEvaluation = {used, checkCancelled};
|
|
99
111
|
return () => {
|
|
112
|
+
flushPendingPersistence();
|
|
100
113
|
for (const id of retainedEvaluation) {
|
|
101
114
|
if (!used.has(id)) historicalEntries.set(id, entries.get(id)!);
|
|
102
115
|
}
|
|
@@ -107,39 +120,65 @@ export function createKernelOperationCache({
|
|
|
107
120
|
};
|
|
108
121
|
}
|
|
109
122
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
* scalar semantics; inputs carry the content identities of prior operations.
|
|
113
|
-
* The lifecycle keeps the retained value independent from each disposable use.
|
|
114
|
-
*/
|
|
115
|
-
function evaluateKernelOperation<Value>(
|
|
116
|
-
operation: string,
|
|
117
|
-
arguments_: readonly KernelKeyPart[],
|
|
118
|
-
inputs: readonly KernelArtifact<unknown>[],
|
|
123
|
+
function evaluateCachedArtifact<Value>(
|
|
124
|
+
key: KernelOperationKey,
|
|
119
125
|
lifecycle: KernelValueLifecycle<Value>,
|
|
120
126
|
compute: () => Value,
|
|
127
|
+
codec?: CacheCodec<Value> | false,
|
|
121
128
|
): KernelArtifact<Value> {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
if (cached) return cached;
|
|
129
|
+
const hit = findKernelOperation(key, lifecycle, codec);
|
|
130
|
+
if (hit) return hit;
|
|
125
131
|
const value = compute();
|
|
126
|
-
acceptKernelOperation(key, lifecycle, value);
|
|
132
|
+
acceptKernelOperation(key, lifecycle, value, codec);
|
|
127
133
|
return {id: key.id, value};
|
|
128
134
|
}
|
|
129
135
|
|
|
130
136
|
function findKernelOperation<Value>(
|
|
131
137
|
key: KernelOperationKey,
|
|
132
138
|
lifecycle: KernelValueLifecycle<Value>,
|
|
139
|
+
codec?: CacheCodec<Value> | false,
|
|
140
|
+
): KernelArtifact<Value> | undefined {
|
|
141
|
+
return lookup(key, lifecycle, codec, () =>
|
|
142
|
+
accessStore(store => store.get(key.id)),
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function findKernelOperations<Value>(
|
|
147
|
+
keys: readonly KernelOperationKey[],
|
|
148
|
+
lifecycle: KernelValueLifecycle<Value>,
|
|
149
|
+
codec?: CacheCodec<Value> | false,
|
|
150
|
+
): readonly (KernelArtifact<Value> | undefined)[] {
|
|
151
|
+
currentEvaluation?.checkCancelled?.();
|
|
152
|
+
const missing =
|
|
153
|
+
codec === false ? [] : keys.filter(key => !entries.has(key.id));
|
|
154
|
+
const bytes = missing.length
|
|
155
|
+
? accessStore(store => store.getMany(missing.map(key => key.id)))
|
|
156
|
+
: undefined;
|
|
157
|
+
const restored = new Map(
|
|
158
|
+
missing.map((key, index) => [key.id, bytes?.[index]]),
|
|
159
|
+
);
|
|
160
|
+
return keys.map(key =>
|
|
161
|
+
lookup(key, lifecycle, codec, () => restored.get(key.id)),
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function lookup<Value>(
|
|
166
|
+
key: KernelOperationKey,
|
|
167
|
+
lifecycle: KernelValueLifecycle<Value>,
|
|
168
|
+
codec: CacheCodec<Value> | false | undefined,
|
|
169
|
+
read: () => Uint8Array | undefined,
|
|
133
170
|
): KernelArtifact<Value> | undefined {
|
|
134
171
|
currentEvaluation?.checkCancelled?.();
|
|
135
172
|
const {id, signature} = key;
|
|
136
173
|
let cached = entries.get(id) as CacheEntry<Value> | undefined;
|
|
137
|
-
if (!cached) {
|
|
138
|
-
const bytes =
|
|
174
|
+
if (!cached && codec !== false) {
|
|
175
|
+
const bytes = read();
|
|
139
176
|
if (bytes) {
|
|
140
177
|
let restored: Value;
|
|
141
178
|
try {
|
|
142
|
-
restored =
|
|
179
|
+
restored = codec
|
|
180
|
+
? codec.decoder(decodeKernelArtifact<Uint8Array>(bytes, signature))
|
|
181
|
+
: decodeKernelArtifact<Value>(bytes, signature);
|
|
143
182
|
} catch {
|
|
144
183
|
persistenceErrors += 1;
|
|
145
184
|
accessStore(store => store.delete(id));
|
|
@@ -159,7 +198,7 @@ export function createKernelOperationCache({
|
|
|
159
198
|
throw new Error(`Kernel operation cache identity collision: ${id}`);
|
|
160
199
|
hits += 1;
|
|
161
200
|
const value = cached.instantiate(cached.value);
|
|
162
|
-
persist(key, cached.value);
|
|
201
|
+
if (codec !== false) persist(key, cached.value, codec, true);
|
|
163
202
|
touchEntry(id, cached as CacheEntry<unknown>);
|
|
164
203
|
return {id, value};
|
|
165
204
|
}
|
|
@@ -169,6 +208,7 @@ export function createKernelOperationCache({
|
|
|
169
208
|
key: KernelOperationKey,
|
|
170
209
|
lifecycle: KernelValueLifecycle<Value>,
|
|
171
210
|
value: Value,
|
|
211
|
+
codec?: CacheCodec<Value> | false,
|
|
172
212
|
): void {
|
|
173
213
|
const existing = entries.get(key.id);
|
|
174
214
|
if (existing) {
|
|
@@ -185,21 +225,59 @@ export function createKernelOperationCache({
|
|
|
185
225
|
throw error;
|
|
186
226
|
}
|
|
187
227
|
const entry = retainEntry(key, lifecycle, retained);
|
|
188
|
-
persist(key, retained);
|
|
228
|
+
if (codec !== false) persist(key, retained, codec);
|
|
189
229
|
touchEntry(key.id, entry as CacheEntry<unknown>);
|
|
190
230
|
}
|
|
191
231
|
|
|
192
|
-
function persist(
|
|
232
|
+
function persist<Value>(
|
|
233
|
+
key: KernelOperationKey,
|
|
234
|
+
value: Value,
|
|
235
|
+
codec?: CacheCodec<Value>,
|
|
236
|
+
defer = false,
|
|
237
|
+
): void {
|
|
193
238
|
if (!store || persisted.has(key.id)) return;
|
|
239
|
+
const encode = () => {
|
|
240
|
+
const started = performance.now();
|
|
241
|
+
try {
|
|
242
|
+
return encodeKernelArtifact(
|
|
243
|
+
key.signature,
|
|
244
|
+
codec ? Uint8Array.from(codec.encoder(value)) : value,
|
|
245
|
+
);
|
|
246
|
+
} finally {
|
|
247
|
+
persistenceEncodeMilliseconds += performance.now() - started;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
if (defer && currentEvaluation) {
|
|
251
|
+
pendingPersistence.set(key.id, encode);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
194
254
|
accessStore(store => {
|
|
195
|
-
|
|
196
|
-
|
|
255
|
+
// A completed computation follows a miss; write it without another lookup.
|
|
256
|
+
if (!defer || !store.touch(key.id)) {
|
|
257
|
+
store.set(key.id, encode());
|
|
197
258
|
persistentWrites += 1;
|
|
198
259
|
}
|
|
199
260
|
persisted.add(key.id);
|
|
200
261
|
});
|
|
201
262
|
}
|
|
202
263
|
|
|
264
|
+
/** Memory hits need one transaction, while newly computed work is saved immediately. */
|
|
265
|
+
function flushPendingPersistence(): void {
|
|
266
|
+
if (!pendingPersistence.size) return;
|
|
267
|
+
accessStore(store => {
|
|
268
|
+
const ids = [...pendingPersistence.keys()];
|
|
269
|
+
const present = store.touchMany(ids);
|
|
270
|
+
ids.forEach((id, index) => {
|
|
271
|
+
if (!present[index]) {
|
|
272
|
+
store.set(id, pendingPersistence.get(id)!());
|
|
273
|
+
persistentWrites += 1;
|
|
274
|
+
}
|
|
275
|
+
persisted.add(id);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
pendingPersistence.clear();
|
|
279
|
+
}
|
|
280
|
+
|
|
203
281
|
function retainEntry<Value>(
|
|
204
282
|
key: KernelOperationKey,
|
|
205
283
|
lifecycle: KernelValueLifecycle<Value>,
|
|
@@ -244,8 +322,10 @@ export function createKernelOperationCache({
|
|
|
244
322
|
estimatedJavaScriptBytes = 0;
|
|
245
323
|
persistentHits = 0;
|
|
246
324
|
persistentWrites = 0;
|
|
325
|
+
persistenceEncodeMilliseconds = 0;
|
|
247
326
|
persistenceErrors = 0;
|
|
248
327
|
persisted.clear();
|
|
328
|
+
pendingPersistence.clear();
|
|
249
329
|
}
|
|
250
330
|
|
|
251
331
|
function kernelOperationCacheStats() {
|
|
@@ -258,8 +338,10 @@ export function createKernelOperationCache({
|
|
|
258
338
|
nativeAllocatedBytes: nativeAllocatedBytes(),
|
|
259
339
|
maximumBytes,
|
|
260
340
|
externalBytes,
|
|
341
|
+
pendingPersistenceBytes: store?.pendingWriteBytes ?? 0,
|
|
261
342
|
persistentHits,
|
|
262
343
|
persistentWrites,
|
|
344
|
+
persistenceEncodeMilliseconds,
|
|
263
345
|
persistenceErrors,
|
|
264
346
|
};
|
|
265
347
|
}
|
|
@@ -267,7 +349,10 @@ export function createKernelOperationCache({
|
|
|
267
349
|
function evictHistoricalEntries(): void {
|
|
268
350
|
while (
|
|
269
351
|
historicalEntries.size &&
|
|
270
|
-
nativeAllocatedBytes() +
|
|
352
|
+
nativeAllocatedBytes() +
|
|
353
|
+
estimatedJavaScriptBytes +
|
|
354
|
+
externalBytes +
|
|
355
|
+
(store?.pendingWriteBytes ?? 0) >
|
|
271
356
|
maximumBytes
|
|
272
357
|
) {
|
|
273
358
|
const [id, entry] = historicalEntries.entries().next().value!;
|
|
@@ -279,29 +364,37 @@ export function createKernelOperationCache({
|
|
|
279
364
|
}
|
|
280
365
|
|
|
281
366
|
return {
|
|
367
|
+
evaluateCachedArtifact,
|
|
282
368
|
beginKernelOperationEvaluation,
|
|
283
|
-
evaluateKernelOperation,
|
|
284
369
|
clearKernelOperationCache,
|
|
285
370
|
kernelOperationCacheStats,
|
|
286
371
|
setKernelArtifactStore,
|
|
287
372
|
findKernelOperation,
|
|
373
|
+
findKernelOperations,
|
|
288
374
|
acceptKernelOperation,
|
|
289
375
|
setKernelExternalBytes,
|
|
290
376
|
};
|
|
291
377
|
}
|
|
292
378
|
|
|
379
|
+
let nativeMemoryCounter = () => 0;
|
|
380
|
+
|
|
381
|
+
/** The installed backend supplies native accounting; pure caches need no kernel. */
|
|
382
|
+
export function setKernelNativeMemoryCounter(read: () => number): void {
|
|
383
|
+
nativeMemoryCounter = read;
|
|
384
|
+
}
|
|
385
|
+
|
|
293
386
|
export const {
|
|
387
|
+
evaluateCachedArtifact,
|
|
294
388
|
beginKernelOperationEvaluation,
|
|
295
|
-
evaluateKernelOperation,
|
|
296
389
|
clearKernelOperationCache,
|
|
297
390
|
kernelOperationCacheStats,
|
|
298
391
|
setKernelArtifactStore,
|
|
299
392
|
findKernelOperation,
|
|
393
|
+
findKernelOperations,
|
|
300
394
|
acceptKernelOperation,
|
|
301
395
|
setKernelExternalBytes,
|
|
302
|
-
} =
|
|
303
|
-
nativeAllocatedBytes: () =>
|
|
304
|
-
(getOC() as OpenCascadeInstance).Code3dMemory.AllocatedBytes(),
|
|
396
|
+
} = createComputationCache({
|
|
397
|
+
nativeAllocatedBytes: () => nativeMemoryCounter(),
|
|
305
398
|
});
|
|
306
399
|
|
|
307
400
|
export type KernelOperationKey = Readonly<{id: string; signature: string}>;
|
|
@@ -316,16 +409,17 @@ export function kernelOperationKey(
|
|
|
316
409
|
arguments_,
|
|
317
410
|
inputs.map(input => input.id),
|
|
318
411
|
]);
|
|
319
|
-
return {id:
|
|
412
|
+
return {id: kernelContentId(signature), signature};
|
|
320
413
|
}
|
|
321
414
|
|
|
322
|
-
function
|
|
415
|
+
export function kernelContentId(value: string | Uint8Array): string {
|
|
323
416
|
let first = 0x811c9dc5;
|
|
324
417
|
let second = 0x9e3779b9;
|
|
325
418
|
let third = 0x85ebca6b;
|
|
326
419
|
let fourth = 0xc2b2ae35;
|
|
327
420
|
for (let index = 0; index < value.length; index += 1) {
|
|
328
|
-
const code =
|
|
421
|
+
const code =
|
|
422
|
+
typeof value === 'string' ? value.charCodeAt(index) : value[index];
|
|
329
423
|
first = Math.imul(first ^ code, 0x01000193);
|
|
330
424
|
second = Math.imul(second ^ code, 0x27d4eb2d);
|
|
331
425
|
third = Math.imul(third ^ code, 0x165667b1);
|
package/src/library/loft.ts
CHANGED
|
@@ -104,6 +104,10 @@ function loftContoursWithTopology(
|
|
|
104
104
|
builder.SetMutableInput(false);
|
|
105
105
|
for (const wire of wires) builder.AddWire(wire.wrapped);
|
|
106
106
|
builder.Build();
|
|
107
|
+
if (!builder.IsDone())
|
|
108
|
+
throw new Error(
|
|
109
|
+
'Could not construct a solid loft through these sections. Adjust their positions, orientations, or profiles.',
|
|
110
|
+
);
|
|
107
111
|
}
|
|
108
112
|
result = castOwnedShape3D(builder.Shape());
|
|
109
113
|
caps[0] = castOwnedShape(builder.FirstShape()) as Face;
|
package/src/library/material.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type SerializedImage,
|
|
7
7
|
type Texture,
|
|
8
8
|
type TypedArray,
|
|
9
|
-
} from '
|
|
9
|
+
} from 'three';
|
|
10
10
|
import {parseModelColor} from './model-color.js';
|
|
11
11
|
|
|
12
12
|
/** A color selects the default material for each geometry kind. */
|
|
@@ -52,14 +52,13 @@ export function captureModelMaterial(
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
if ('isShaderMaterial' in input) {
|
|
55
|
-
const shader = input as import('
|
|
55
|
+
const shader = input as import('three').ShaderMaterial;
|
|
56
56
|
if (
|
|
57
57
|
shader.uniformsGroups.length ||
|
|
58
58
|
shader.index0AttributeName !== undefined ||
|
|
59
59
|
JSON.stringify(shader.defaultAttributeValues) !==
|
|
60
60
|
JSON.stringify(
|
|
61
|
-
(restored as import('
|
|
62
|
-
.defaultAttributeValues,
|
|
61
|
+
(restored as import('three').ShaderMaterial).defaultAttributeValues,
|
|
63
62
|
)
|
|
64
63
|
) {
|
|
65
64
|
throw new Error(
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type {OpenCascadeInstance} from '@code3d/opencascade';
|
|
2
|
+
import {setOC} from 'replicad';
|
|
3
|
+
import {
|
|
4
|
+
clearKernelOperationCache,
|
|
5
|
+
setKernelNativeMemoryCounter,
|
|
6
|
+
} from './kernel-cache.js';
|
|
7
|
+
|
|
8
|
+
/** Install the backend and its memory accounting for Node and hosted runtimes. */
|
|
9
|
+
export function installOpenCascade(openCascade: OpenCascadeInstance): void {
|
|
10
|
+
clearKernelOperationCache();
|
|
11
|
+
setOC(openCascade);
|
|
12
|
+
setKernelNativeMemoryCounter(() => openCascade.Code3dMemory.AllocatedBytes());
|
|
13
|
+
}
|
package/src/library/replicad.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as replicadModule from 'replicad';
|
|
2
|
-
import {
|
|
2
|
+
import {primitiveConstructor} from './runtime.js';
|
|
3
3
|
import {castOwnedShape} from './kernel-shapes.js';
|
|
4
4
|
import type {SolidModel} from './index.js';
|
|
5
5
|
import type {Shape3D} from 'replicad';
|
|
@@ -29,12 +29,12 @@ export const replicad: Replicad = Object.freeze({
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Defines a synchronous model constructor with the builder's parameters.
|
|
32
|
-
*
|
|
33
|
-
*
|
|
32
|
+
* Reuses deterministic geometry by arguments; pass changing captured state as
|
|
33
|
+
* explicit parameters. Each invocation creates a fresh model. The builder
|
|
34
|
+
* transfers its returned solid to code3d and owns its intermediate shapes.
|
|
34
35
|
*/
|
|
35
36
|
export function definePrimitive<
|
|
36
37
|
Builder extends (...arguments_: never[]) => Shape3D,
|
|
37
38
|
>(build: Builder): (...arguments_: Parameters<Builder>) => SolidModel {
|
|
38
|
-
return (
|
|
39
|
-
modelFromReplicadSolid(build(...arguments_));
|
|
39
|
+
return primitiveConstructor(build);
|
|
40
40
|
}
|
|
@@ -12,7 +12,12 @@ export function estimateRetainedBytes(value: unknown): number {
|
|
|
12
12
|
seen.add(value);
|
|
13
13
|
if (ArrayBuffer.isView(value)) return 64 + visit(value.buffer);
|
|
14
14
|
if (value instanceof ArrayBuffer) return 32 + value.byteLength;
|
|
15
|
-
const values =
|
|
15
|
+
const values =
|
|
16
|
+
value instanceof Map
|
|
17
|
+
? [...value].flat()
|
|
18
|
+
: value instanceof Set
|
|
19
|
+
? [...value]
|
|
20
|
+
: Object.values(value);
|
|
16
21
|
return (
|
|
17
22
|
32 +
|
|
18
23
|
values.length * 8 +
|