@gridspace/raster-path 1.0.9 → 1.1.1
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/build/raster-path.js +25 -6
- package/build/raster-worker.js +11 -5
- package/package.json +1 -1
- package/src/core/path-tracing.js +13 -3
- package/src/core/raster-path.js +25 -6
package/build/raster-path.js
CHANGED
|
@@ -464,7 +464,12 @@ export class RasterPath {
|
|
|
464
464
|
// Set up progress handler if callback provided
|
|
465
465
|
if (onProgress) {
|
|
466
466
|
const progressHandler = (data) => {
|
|
467
|
-
onProgress(data.percent, {
|
|
467
|
+
onProgress(data.percent, {
|
|
468
|
+
current: data.current,
|
|
469
|
+
total: data.total,
|
|
470
|
+
chunkIndex: data.chunkIndex,
|
|
471
|
+
totalChunks: data.totalChunks
|
|
472
|
+
});
|
|
468
473
|
};
|
|
469
474
|
this.messageHandlers.set('tracing-progress', progressHandler);
|
|
470
475
|
}
|
|
@@ -570,7 +575,7 @@ export class RasterPath {
|
|
|
570
575
|
const { type, success, data } = e.data;
|
|
571
576
|
|
|
572
577
|
// Handle progress messages (don't delete handler)
|
|
573
|
-
if (type === 'rasterize-progress' || type === 'toolpath-progress') {
|
|
578
|
+
if (type === 'rasterize-progress' || type === 'toolpath-progress' || type === 'tracing-progress') {
|
|
574
579
|
const handler = this.messageHandlers.get(type);
|
|
575
580
|
if (handler) {
|
|
576
581
|
handler(data);
|
|
@@ -676,18 +681,32 @@ export class RasterPath {
|
|
|
676
681
|
}
|
|
677
682
|
|
|
678
683
|
// Flatten triangle indices for GPU
|
|
679
|
-
|
|
684
|
+
// Pre-calculate total size for optimal performance
|
|
685
|
+
let totalIndices = 0;
|
|
686
|
+
for (let i = 0; i < buckets.length; i++) {
|
|
687
|
+
totalIndices += buckets[i].triangleIndices.length;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Pre-allocate array to avoid resizing overhead
|
|
691
|
+
const triangleIndices = new Array(totalIndices);
|
|
680
692
|
const bucketInfo = [];
|
|
693
|
+
let offset = 0;
|
|
681
694
|
|
|
682
695
|
for (let i = 0; i < buckets.length; i++) {
|
|
683
696
|
const bucket = buckets[i];
|
|
697
|
+
const indices = bucket.triangleIndices;
|
|
698
|
+
|
|
684
699
|
bucketInfo.push({
|
|
685
700
|
minX: bucket.minX,
|
|
686
701
|
maxX: bucket.maxX,
|
|
687
|
-
startIndex:
|
|
688
|
-
count:
|
|
702
|
+
startIndex: offset,
|
|
703
|
+
count: indices.length
|
|
689
704
|
});
|
|
690
|
-
|
|
705
|
+
|
|
706
|
+
// Copy indices using fast indexed access
|
|
707
|
+
for (let j = 0; j < indices.length; j++) {
|
|
708
|
+
triangleIndices[offset++] = indices[j];
|
|
709
|
+
}
|
|
691
710
|
}
|
|
692
711
|
|
|
693
712
|
return {
|
package/build/raster-worker.js
CHANGED
|
@@ -2387,7 +2387,7 @@ async function generateRadialToolpaths({
|
|
|
2387
2387
|
if (!strip.positions || strip.positions.length === 0)
|
|
2388
2388
|
continue;
|
|
2389
2389
|
if (diagnostic && (globalStripIdx === 0 || globalStripIdx === 360)) {
|
|
2390
|
-
debug.log(`
|
|
2390
|
+
debug.log(`ES2VU471 | Strip ${globalStripIdx} (${strip.angle.toFixed(1)}\xB0) INPUT terrain first 5 Z values: ${strip.positions.slice(0, 5).map((v) => v.toFixed(3)).join(",")}`);
|
|
2391
2391
|
}
|
|
2392
2392
|
const stripToolpathResult = await runToolpathComputeWithBuffers(
|
|
2393
2393
|
strip.positions,
|
|
@@ -2400,7 +2400,7 @@ async function generateRadialToolpaths({
|
|
|
2400
2400
|
pipelineStartTime
|
|
2401
2401
|
);
|
|
2402
2402
|
if (diagnostic && (globalStripIdx === 0 || globalStripIdx === 360)) {
|
|
2403
|
-
debug.log(`
|
|
2403
|
+
debug.log(`ES2VU471 | Strip ${globalStripIdx} (${strip.angle.toFixed(1)}\xB0) OUTPUT toolpath first 5 Z values: ${stripToolpathResult.pathData.slice(0, 5).map((v) => v.toFixed(3)).join(",")}`);
|
|
2404
2404
|
}
|
|
2405
2405
|
allStripToolpaths.push({
|
|
2406
2406
|
angle: strip.angle,
|
|
@@ -2896,7 +2896,7 @@ async function generateTracingToolpaths({
|
|
|
2896
2896
|
debug.log(`First point: world(${firstX.toFixed(2)}, ${firstY.toFixed(2)}) -> grid(${gridX.toFixed(2)}, ${gridY.toFixed(2)})`);
|
|
2897
2897
|
}
|
|
2898
2898
|
debug.log("PHASE 2: Calculating memory budget and chunking...");
|
|
2899
|
-
const bytesPerPoint = 8 + 4;
|
|
2899
|
+
const bytesPerPoint = 8 + 4 + 4;
|
|
2900
2900
|
const configuredLimit = config.maxGPUMemoryMB * 1024 * 1024;
|
|
2901
2901
|
const deviceLimit = deviceCapabilities.maxStorageBufferBindingSize;
|
|
2902
2902
|
const maxSafeSize = Math.min(configuredLimit, deviceLimit) * config.gpuMemorySafetyMargin;
|
|
@@ -2911,9 +2911,15 @@ async function generateTracingToolpaths({
|
|
|
2911
2911
|
);
|
|
2912
2912
|
}
|
|
2913
2913
|
const availableForPaths = maxSafeSize - fixedOverhead;
|
|
2914
|
-
const
|
|
2914
|
+
const maxPointsPerChunkMemory = Math.floor(availableForPaths / bytesPerPoint);
|
|
2915
|
+
const maxWorkgroupsPerDimension = deviceCapabilities.maxComputeWorkgroupsPerDimension || 65535;
|
|
2916
|
+
const threadsPerWorkgroup = 64;
|
|
2917
|
+
const maxPointsPerChunkGPU = maxWorkgroupsPerDimension * threadsPerWorkgroup;
|
|
2918
|
+
const maxPointsPerChunk = Math.min(maxPointsPerChunkMemory, maxPointsPerChunkGPU);
|
|
2915
2919
|
debug.log(`Memory budget: ${(maxSafeSize / 1024 / 1024).toFixed(1)}MB safe, ${(availableForPaths / 1024 / 1024).toFixed(1)}MB available for paths`);
|
|
2916
|
-
debug.log(`
|
|
2920
|
+
debug.log(`Memory-based max: ${maxPointsPerChunkMemory.toLocaleString()} points`);
|
|
2921
|
+
debug.log(`GPU dispatch max: ${maxPointsPerChunkGPU.toLocaleString()} points (${maxWorkgroupsPerDimension.toLocaleString()} workgroups)`);
|
|
2922
|
+
debug.log(`Max points per chunk: ${maxPointsPerChunk.toLocaleString()} (limited by ${maxPointsPerChunk === maxPointsPerChunkGPU ? "GPU" : "memory"})`);
|
|
2917
2923
|
const chunks = [];
|
|
2918
2924
|
let currentStart = 0;
|
|
2919
2925
|
while (currentStart < totalSampledPoints) {
|
package/package.json
CHANGED
package/src/core/path-tracing.js
CHANGED
|
@@ -325,7 +325,7 @@ export async function generateTracingToolpaths({
|
|
|
325
325
|
// PHASE 2: Calculate memory budget and create chunks
|
|
326
326
|
// ═══════════════════════════════════════════════════════════════════════
|
|
327
327
|
debug.log('PHASE 2: Calculating memory budget and chunking...');
|
|
328
|
-
const bytesPerPoint = 8 + 4; // XY input (
|
|
328
|
+
const bytesPerPoint = 8 + 4 + 4; // XY input (8) + Z output (4) + Z staging (4)
|
|
329
329
|
const configuredLimit = config.maxGPUMemoryMB * 1024 * 1024;
|
|
330
330
|
const deviceLimit = deviceCapabilities.maxStorageBufferBindingSize;
|
|
331
331
|
const maxSafeSize = Math.min(configuredLimit, deviceLimit) * config.gpuMemorySafetyMargin;
|
|
@@ -350,10 +350,20 @@ export async function generateTracingToolpaths({
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
const availableForPaths = maxSafeSize - fixedOverhead;
|
|
353
|
-
const
|
|
353
|
+
const maxPointsPerChunkMemory = Math.floor(availableForPaths / bytesPerPoint);
|
|
354
|
+
|
|
355
|
+
// GPU dispatch limit: 65535 workgroups per dimension, 64 threads per workgroup
|
|
356
|
+
const maxWorkgroupsPerDimension = deviceCapabilities.maxComputeWorkgroupsPerDimension || 65535;
|
|
357
|
+
const threadsPerWorkgroup = 64;
|
|
358
|
+
const maxPointsPerChunkGPU = maxWorkgroupsPerDimension * threadsPerWorkgroup;
|
|
359
|
+
|
|
360
|
+
// Use the smaller of memory limit and GPU dispatch limit
|
|
361
|
+
const maxPointsPerChunk = Math.min(maxPointsPerChunkMemory, maxPointsPerChunkGPU);
|
|
354
362
|
|
|
355
363
|
debug.log(`Memory budget: ${(maxSafeSize / 1024 / 1024).toFixed(1)}MB safe, ${(availableForPaths / 1024 / 1024).toFixed(1)}MB available for paths`);
|
|
356
|
-
debug.log(`
|
|
364
|
+
debug.log(`Memory-based max: ${maxPointsPerChunkMemory.toLocaleString()} points`);
|
|
365
|
+
debug.log(`GPU dispatch max: ${maxPointsPerChunkGPU.toLocaleString()} points (${maxWorkgroupsPerDimension.toLocaleString()} workgroups)`);
|
|
366
|
+
debug.log(`Max points per chunk: ${maxPointsPerChunk.toLocaleString()} (limited by ${maxPointsPerChunk === maxPointsPerChunkGPU ? 'GPU' : 'memory'})`);
|
|
357
367
|
|
|
358
368
|
// Create chunks
|
|
359
369
|
const chunks = [];
|
package/src/core/raster-path.js
CHANGED
|
@@ -464,7 +464,12 @@ export class RasterPath {
|
|
|
464
464
|
// Set up progress handler if callback provided
|
|
465
465
|
if (onProgress) {
|
|
466
466
|
const progressHandler = (data) => {
|
|
467
|
-
onProgress(data.percent, {
|
|
467
|
+
onProgress(data.percent, {
|
|
468
|
+
current: data.current,
|
|
469
|
+
total: data.total,
|
|
470
|
+
chunkIndex: data.chunkIndex,
|
|
471
|
+
totalChunks: data.totalChunks
|
|
472
|
+
});
|
|
468
473
|
};
|
|
469
474
|
this.messageHandlers.set('tracing-progress', progressHandler);
|
|
470
475
|
}
|
|
@@ -570,7 +575,7 @@ export class RasterPath {
|
|
|
570
575
|
const { type, success, data } = e.data;
|
|
571
576
|
|
|
572
577
|
// Handle progress messages (don't delete handler)
|
|
573
|
-
if (type === 'rasterize-progress' || type === 'toolpath-progress') {
|
|
578
|
+
if (type === 'rasterize-progress' || type === 'toolpath-progress' || type === 'tracing-progress') {
|
|
574
579
|
const handler = this.messageHandlers.get(type);
|
|
575
580
|
if (handler) {
|
|
576
581
|
handler(data);
|
|
@@ -676,18 +681,32 @@ export class RasterPath {
|
|
|
676
681
|
}
|
|
677
682
|
|
|
678
683
|
// Flatten triangle indices for GPU
|
|
679
|
-
|
|
684
|
+
// Pre-calculate total size for optimal performance
|
|
685
|
+
let totalIndices = 0;
|
|
686
|
+
for (let i = 0; i < buckets.length; i++) {
|
|
687
|
+
totalIndices += buckets[i].triangleIndices.length;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Pre-allocate array to avoid resizing overhead
|
|
691
|
+
const triangleIndices = new Array(totalIndices);
|
|
680
692
|
const bucketInfo = [];
|
|
693
|
+
let offset = 0;
|
|
681
694
|
|
|
682
695
|
for (let i = 0; i < buckets.length; i++) {
|
|
683
696
|
const bucket = buckets[i];
|
|
697
|
+
const indices = bucket.triangleIndices;
|
|
698
|
+
|
|
684
699
|
bucketInfo.push({
|
|
685
700
|
minX: bucket.minX,
|
|
686
701
|
maxX: bucket.maxX,
|
|
687
|
-
startIndex:
|
|
688
|
-
count:
|
|
702
|
+
startIndex: offset,
|
|
703
|
+
count: indices.length
|
|
689
704
|
});
|
|
690
|
-
|
|
705
|
+
|
|
706
|
+
// Copy indices using fast indexed access
|
|
707
|
+
for (let j = 0; j < indices.length; j++) {
|
|
708
|
+
triangleIndices[offset++] = indices[j];
|
|
709
|
+
}
|
|
691
710
|
}
|
|
692
711
|
|
|
693
712
|
return {
|