okgeometry-api 1.1.2 → 1.1.4
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/dist/Mesh.d.ts +4 -0
- package/dist/Mesh.d.ts.map +1 -1
- package/dist/Mesh.js +90 -25
- package/dist/Mesh.js.map +1 -1
- package/dist/wasm-base64.d.ts +1 -1
- package/dist/wasm-base64.js +1 -1
- package/package.json +1 -1
- package/src/Mesh.ts +153 -41
- package/src/wasm-base64.ts +1 -1
- package/wasm/okgeometrycore.js +1 -1
- package/wasm/okgeometrycore_bg.wasm +0 -0
- package/wasm/package.json +1 -1
package/package.json
CHANGED
package/src/Mesh.ts
CHANGED
|
@@ -278,77 +278,52 @@ export class Mesh {
|
|
|
278
278
|
}));
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
private static
|
|
281
|
+
private static buildDirectionalDebugProbes(
|
|
282
282
|
inputA: Mesh,
|
|
283
283
|
inputB: Mesh,
|
|
284
284
|
result: Mesh,
|
|
285
|
-
|
|
285
|
+
center: Point,
|
|
286
|
+
pad: number,
|
|
287
|
+
maxDistance: number,
|
|
288
|
+
maxHits: number,
|
|
289
|
+
probeIds: Array<"posX" | "negX" | "posY" | "negY" | "posZ" | "negZ">,
|
|
290
|
+
labelPrefix = "",
|
|
286
291
|
): MeshBooleanDebugProbe[] {
|
|
287
|
-
const
|
|
288
|
-
const boundsB = Mesh.toDebugBounds(inputB.getBounds());
|
|
289
|
-
const resultBounds = Mesh.toDebugBounds(result.getBounds());
|
|
290
|
-
const min = new Point(
|
|
291
|
-
Math.min(boundsA.min.x, boundsB.min.x, resultBounds.min.x),
|
|
292
|
-
Math.min(boundsA.min.y, boundsB.min.y, resultBounds.min.y),
|
|
293
|
-
Math.min(boundsA.min.z, boundsB.min.z, resultBounds.min.z),
|
|
294
|
-
);
|
|
295
|
-
const max = new Point(
|
|
296
|
-
Math.max(boundsA.max.x, boundsB.max.x, resultBounds.max.x),
|
|
297
|
-
Math.max(boundsA.max.y, boundsB.max.y, resultBounds.max.y),
|
|
298
|
-
Math.max(boundsA.max.z, boundsB.max.z, resultBounds.max.z),
|
|
299
|
-
);
|
|
300
|
-
const center = new Point(
|
|
301
|
-
(min.x + max.x) * 0.5,
|
|
302
|
-
(min.y + max.y) * 0.5,
|
|
303
|
-
(min.z + max.z) * 0.5,
|
|
304
|
-
);
|
|
305
|
-
const diag = Math.max(
|
|
306
|
-
1e-6,
|
|
307
|
-
Math.hypot(max.x - min.x, max.y - min.y, max.z - min.z),
|
|
308
|
-
);
|
|
309
|
-
const padScale = Number.isFinite(options?.rayPaddingScale)
|
|
310
|
-
? Math.max(0.01, options?.rayPaddingScale ?? 0.25)
|
|
311
|
-
: 0.25;
|
|
312
|
-
const pad = Math.max(1e-3, diag * padScale);
|
|
313
|
-
const maxHits = Mesh.clampDebugHitCount(options?.maxRayHits);
|
|
314
|
-
const probeIds = options?.probes?.length
|
|
315
|
-
? options.probes
|
|
316
|
-
: Mesh.DEFAULT_BOOLEAN_DEBUG_PROBES;
|
|
292
|
+
const prefixed = (id: string) => (labelPrefix ? `${labelPrefix}:${id}` : id);
|
|
317
293
|
const probeSpecs: Record<
|
|
318
294
|
"posX" | "negX" | "posY" | "negY" | "posZ" | "negZ",
|
|
319
295
|
{ origin: Point; direction: Vec3 }
|
|
320
296
|
> = {
|
|
321
297
|
posX: {
|
|
322
|
-
origin: new Point(
|
|
298
|
+
origin: new Point(center.x + pad, center.y, center.z),
|
|
323
299
|
direction: new Vec3(-1, 0, 0),
|
|
324
300
|
},
|
|
325
301
|
negX: {
|
|
326
|
-
origin: new Point(
|
|
302
|
+
origin: new Point(center.x - pad, center.y, center.z),
|
|
327
303
|
direction: new Vec3(1, 0, 0),
|
|
328
304
|
},
|
|
329
305
|
posY: {
|
|
330
|
-
origin: new Point(center.x,
|
|
306
|
+
origin: new Point(center.x, center.y + pad, center.z),
|
|
331
307
|
direction: new Vec3(0, -1, 0),
|
|
332
308
|
},
|
|
333
309
|
negY: {
|
|
334
|
-
origin: new Point(center.x,
|
|
310
|
+
origin: new Point(center.x, center.y - pad, center.z),
|
|
335
311
|
direction: new Vec3(0, 1, 0),
|
|
336
312
|
},
|
|
337
313
|
posZ: {
|
|
338
|
-
origin: new Point(center.x, center.y,
|
|
314
|
+
origin: new Point(center.x, center.y, center.z + pad),
|
|
339
315
|
direction: new Vec3(0, 0, -1),
|
|
340
316
|
},
|
|
341
317
|
negZ: {
|
|
342
|
-
origin: new Point(center.x, center.y,
|
|
318
|
+
origin: new Point(center.x, center.y, center.z - pad),
|
|
343
319
|
direction: new Vec3(0, 0, 1),
|
|
344
320
|
},
|
|
345
321
|
};
|
|
346
|
-
const maxDistance = diag + pad * 2;
|
|
347
322
|
|
|
348
323
|
return probeIds.map((id) => {
|
|
349
324
|
const spec = probeSpecs[id];
|
|
350
325
|
return {
|
|
351
|
-
label: id,
|
|
326
|
+
label: prefixed(id),
|
|
352
327
|
origin: spec.origin,
|
|
353
328
|
direction: spec.direction,
|
|
354
329
|
maxDistance,
|
|
@@ -359,6 +334,67 @@ export class Mesh {
|
|
|
359
334
|
});
|
|
360
335
|
}
|
|
361
336
|
|
|
337
|
+
private static buildBooleanDebugProbes(
|
|
338
|
+
inputA: Mesh,
|
|
339
|
+
inputB: Mesh,
|
|
340
|
+
result: Mesh,
|
|
341
|
+
options?: MeshBooleanDebugOptions,
|
|
342
|
+
): MeshBooleanDebugProbe[] {
|
|
343
|
+
const boundsA = Mesh.toDebugBounds(inputA.getBounds());
|
|
344
|
+
const boundsB = Mesh.toDebugBounds(inputB.getBounds());
|
|
345
|
+
const resultBounds = Mesh.toDebugBounds(result.getBounds());
|
|
346
|
+
const min = new Point(
|
|
347
|
+
Math.min(boundsA.min.x, boundsB.min.x, resultBounds.min.x),
|
|
348
|
+
Math.min(boundsA.min.y, boundsB.min.y, resultBounds.min.y),
|
|
349
|
+
Math.min(boundsA.min.z, boundsB.min.z, resultBounds.min.z),
|
|
350
|
+
);
|
|
351
|
+
const max = new Point(
|
|
352
|
+
Math.max(boundsA.max.x, boundsB.max.x, resultBounds.max.x),
|
|
353
|
+
Math.max(boundsA.max.y, boundsB.max.y, resultBounds.max.y),
|
|
354
|
+
Math.max(boundsA.max.z, boundsB.max.z, resultBounds.max.z),
|
|
355
|
+
);
|
|
356
|
+
const center = new Point(
|
|
357
|
+
(min.x + max.x) * 0.5,
|
|
358
|
+
(min.y + max.y) * 0.5,
|
|
359
|
+
(min.z + max.z) * 0.5,
|
|
360
|
+
);
|
|
361
|
+
const diag = Math.max(
|
|
362
|
+
1e-6,
|
|
363
|
+
Math.hypot(max.x - min.x, max.y - min.y, max.z - min.z),
|
|
364
|
+
);
|
|
365
|
+
const padScale = Number.isFinite(options?.rayPaddingScale)
|
|
366
|
+
? Math.max(0.01, options?.rayPaddingScale ?? 0.25)
|
|
367
|
+
: 0.25;
|
|
368
|
+
const pad = Math.max(1e-3, diag * padScale);
|
|
369
|
+
const maxHits = Mesh.clampDebugHitCount(options?.maxRayHits);
|
|
370
|
+
const probeIds = options?.probes?.length
|
|
371
|
+
? options.probes
|
|
372
|
+
: Mesh.DEFAULT_BOOLEAN_DEBUG_PROBES;
|
|
373
|
+
const maxDistance = diag + pad * 2;
|
|
374
|
+
const sceneCenterProbes = Mesh.buildDirectionalDebugProbes(
|
|
375
|
+
inputA,
|
|
376
|
+
inputB,
|
|
377
|
+
result,
|
|
378
|
+
center,
|
|
379
|
+
pad,
|
|
380
|
+
maxDistance,
|
|
381
|
+
maxHits,
|
|
382
|
+
probeIds,
|
|
383
|
+
);
|
|
384
|
+
const inputBCenterProbes = Mesh.buildDirectionalDebugProbes(
|
|
385
|
+
inputA,
|
|
386
|
+
inputB,
|
|
387
|
+
result,
|
|
388
|
+
boundsB.center,
|
|
389
|
+
pad,
|
|
390
|
+
maxDistance,
|
|
391
|
+
maxHits,
|
|
392
|
+
probeIds,
|
|
393
|
+
"inputB",
|
|
394
|
+
);
|
|
395
|
+
return sceneCenterProbes.concat(inputBCenterProbes);
|
|
396
|
+
}
|
|
397
|
+
|
|
362
398
|
private static createBooleanDebugReport(
|
|
363
399
|
inputA: Mesh,
|
|
364
400
|
inputB: Mesh,
|
|
@@ -376,6 +412,65 @@ export class Mesh {
|
|
|
376
412
|
};
|
|
377
413
|
}
|
|
378
414
|
|
|
415
|
+
private static roundDebugScalar(value: number): number {
|
|
416
|
+
return Number.isFinite(value) ? Number(value.toFixed(4)) : value;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
private static summarizeDebugHit(hit: MeshDebugRayHit | undefined): {
|
|
420
|
+
point: { x: number; y: number; z: number };
|
|
421
|
+
normal: { x: number; y: number; z: number };
|
|
422
|
+
faceIndex: number;
|
|
423
|
+
distance: number;
|
|
424
|
+
} | null {
|
|
425
|
+
if (!hit) return null;
|
|
426
|
+
return {
|
|
427
|
+
point: {
|
|
428
|
+
x: Mesh.roundDebugScalar(hit.point.x),
|
|
429
|
+
y: Mesh.roundDebugScalar(hit.point.y),
|
|
430
|
+
z: Mesh.roundDebugScalar(hit.point.z),
|
|
431
|
+
},
|
|
432
|
+
normal: {
|
|
433
|
+
x: Mesh.roundDebugScalar(hit.normal.x),
|
|
434
|
+
y: Mesh.roundDebugScalar(hit.normal.y),
|
|
435
|
+
z: Mesh.roundDebugScalar(hit.normal.z),
|
|
436
|
+
},
|
|
437
|
+
faceIndex: hit.faceIndex,
|
|
438
|
+
distance: Mesh.roundDebugScalar(hit.distance),
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private static summarizeDebugProbe(probe: MeshBooleanDebugProbe): {
|
|
443
|
+
label: string;
|
|
444
|
+
origin: { x: number; y: number; z: number };
|
|
445
|
+
direction: { x: number; y: number; z: number };
|
|
446
|
+
inputAFirst: ReturnType<typeof Mesh.summarizeDebugHit>;
|
|
447
|
+
inputBFirst: ReturnType<typeof Mesh.summarizeDebugHit>;
|
|
448
|
+
resultFirst: ReturnType<typeof Mesh.summarizeDebugHit>;
|
|
449
|
+
inputAHits: number;
|
|
450
|
+
inputBHits: number;
|
|
451
|
+
resultHits: number;
|
|
452
|
+
} {
|
|
453
|
+
return {
|
|
454
|
+
label: probe.label,
|
|
455
|
+
origin: {
|
|
456
|
+
x: Mesh.roundDebugScalar(probe.origin.x),
|
|
457
|
+
y: Mesh.roundDebugScalar(probe.origin.y),
|
|
458
|
+
z: Mesh.roundDebugScalar(probe.origin.z),
|
|
459
|
+
},
|
|
460
|
+
direction: {
|
|
461
|
+
x: Mesh.roundDebugScalar(probe.direction.x),
|
|
462
|
+
y: Mesh.roundDebugScalar(probe.direction.y),
|
|
463
|
+
z: Mesh.roundDebugScalar(probe.direction.z),
|
|
464
|
+
},
|
|
465
|
+
inputAFirst: Mesh.summarizeDebugHit(probe.inputAHits[0]),
|
|
466
|
+
inputBFirst: Mesh.summarizeDebugHit(probe.inputBHits[0]),
|
|
467
|
+
resultFirst: Mesh.summarizeDebugHit(probe.resultHits[0]),
|
|
468
|
+
inputAHits: probe.inputAHits.length,
|
|
469
|
+
inputBHits: probe.inputBHits.length,
|
|
470
|
+
resultHits: probe.resultHits.length,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
|
|
379
474
|
private static logSubtractDebugSuccess(
|
|
380
475
|
inputA: Mesh,
|
|
381
476
|
inputB: Mesh,
|
|
@@ -390,13 +485,30 @@ export class Mesh {
|
|
|
390
485
|
"subtraction",
|
|
391
486
|
{ maxRayHits: 2, probes: ["posX", "negX", "posY"] },
|
|
392
487
|
);
|
|
488
|
+
const probeSummary = report.probes.map((probe) => Mesh.summarizeDebugProbe(probe));
|
|
393
489
|
console.log("[okgeometry-api] Mesh.subtract debug", {
|
|
394
490
|
options: options ?? null,
|
|
395
491
|
inputA: report.inputA,
|
|
396
492
|
inputB: report.inputB,
|
|
397
493
|
result: report.resultSummary,
|
|
398
|
-
|
|
494
|
+
deltas: {
|
|
495
|
+
faceCount: report.resultSummary.faceCount - report.inputA.faceCount,
|
|
496
|
+
vertexCount: report.resultSummary.vertexCount - report.inputA.vertexCount,
|
|
497
|
+
},
|
|
498
|
+
probeSummary,
|
|
499
|
+
report,
|
|
500
|
+
});
|
|
501
|
+
console.log("[okgeometry-api] Mesh.subtract summary", {
|
|
502
|
+
inputAFaces: report.inputA.faceCount,
|
|
503
|
+
inputBFaces: report.inputB.faceCount,
|
|
504
|
+
resultFaces: report.resultSummary.faceCount,
|
|
505
|
+
inputAVerts: report.inputA.vertexCount,
|
|
506
|
+
inputBVerts: report.inputB.vertexCount,
|
|
507
|
+
resultVerts: report.resultSummary.vertexCount,
|
|
508
|
+
resultClosed: report.resultSummary.isClosedVolume,
|
|
509
|
+
resultTopology: report.resultSummary.topology,
|
|
399
510
|
});
|
|
511
|
+
console.log("[okgeometry-api] Mesh.subtract probeSummary", probeSummary);
|
|
400
512
|
} catch (debugError) {
|
|
401
513
|
console.error("[okgeometry-api] Mesh.subtract debug logging failed", debugError);
|
|
402
514
|
}
|