@gridspace/raster-path 1.0.2 → 1.0.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/build/index.html CHANGED
@@ -8,7 +8,45 @@
8
8
  </head>
9
9
  <body>
10
10
  <div id="container">
11
- <!-- Controls Panel -->
11
+ <!-- Left Panel - Model Manipulation -->
12
+ <div class="model-controls">
13
+ <div class="section">
14
+ <h3>Model Rotation</h3>
15
+ <div class="rotation-controls">
16
+ <div class="rotation-row">
17
+ <span class="rotation-label">X:</span>
18
+ <button class="rotate-btn" data-axis="x" data-dir="-1">-90°</button>
19
+ <button class="rotate-btn" data-axis="x" data-dir="1">+90°</button>
20
+ </div>
21
+ <div class="rotation-row">
22
+ <span class="rotation-label">Y:</span>
23
+ <button class="rotate-btn" data-axis="y" data-dir="-1">-90°</button>
24
+ <button class="rotate-btn" data-axis="y" data-dir="1">+90°</button>
25
+ </div>
26
+ <div class="rotation-row">
27
+ <span class="rotation-label">Z:</span>
28
+ <button class="rotate-btn" data-axis="z" data-dir="-1">-90°</button>
29
+ <button class="rotate-btn" data-axis="z" data-dir="1">+90°</button>
30
+ </div>
31
+ <button id="reset-rotation" class="btn btn-small">Reset</button>
32
+ </div>
33
+ </div>
34
+
35
+ <div class="section">
36
+ <h3>Tool Size</h3>
37
+ <select id="tool-size">
38
+ <option value="1.0">1.0mm</option>
39
+ <option value="2.0">2.0mm</option>
40
+ <option value="2.5" selected>2.5mm</option>
41
+ <option value="3.0">3.0mm</option>
42
+ <option value="4.0">4.0mm</option>
43
+ <option value="5.0">5.0mm</option>
44
+ </select>
45
+ <div id="tool-size-status" class="status">No tool loaded</div>
46
+ </div>
47
+ </div>
48
+
49
+ <!-- Right Panel - Controls -->
12
50
  <div class="controls">
13
51
  <div class="section">
14
52
  <h3>Mode</h3>
@@ -55,6 +55,7 @@
55
55
  * @property {number} resolution - Grid step size in mm (required)
56
56
  * @property {number} rotationStep - Radial mode only: degrees between rays (e.g., 1.0 = 360 rays)
57
57
  * @property {number} trianglesPerTile - Target triangles per tile for radial rasterization (default: calculated)
58
+ * @property {number} batchDivisor - Testing parameter to artificially divide batch size (default: 1)
58
59
  * @property {boolean} debug - Enable debug logging (default: false)
59
60
  * @property {boolean} quiet - Suppress log output (default: false)
60
61
  */
@@ -103,18 +104,13 @@ export class RasterPath {
103
104
  this.deviceCapabilities = null;
104
105
 
105
106
  // Configure debug output
106
- let urlOpt = [];
107
107
  if (config.quiet) {
108
108
  debug.log = function() {};
109
- urlOpt.push('quiet');
110
- }
111
- if (config.debug) {
112
- urlOpt.push('debug');
113
109
  }
114
110
 
115
111
  // Configuration with defaults
116
112
  this.config = {
117
- workerName: (config.workerName ?? "webgpu-worker.js") + (urlOpt.length ? "?"+urlOpt.join('&') : ""),
113
+ workerName: config.workerName ?? "webgpu-worker.js",
118
114
  maxGPUMemoryMB: config.maxGPUMemoryMB ?? 256,
119
115
  gpuMemorySafetyMargin: config.gpuMemorySafetyMargin ?? 0.8,
120
116
  autoTiling: config.autoTiling ?? true,
@@ -122,7 +118,12 @@ export class RasterPath {
122
118
  maxConcurrentTiles: config.maxConcurrentTiles ?? 10,
123
119
  trianglesPerTile: config.trianglesPerTile, // undefined = auto-calculate
124
120
  radialRotationOffset: config.radialRotationOffset ?? 0, // degrees
121
+ batchDivisor: config.batchDivisor ?? 1, // For testing batching overhead
122
+ debug: config.debug,
123
+ quiet: config.quiet
125
124
  };
125
+
126
+ debug.log('config', this.config);
126
127
  }
127
128
 
128
129
  /**
@@ -238,8 +239,8 @@ export class RasterPath {
238
239
  const originalBounds = boundsOverride || this.#calculateBounds(triangles);
239
240
 
240
241
  // Center model in YZ plane (required for radial rasterization)
241
- // Radial mode casts rays from origin, so terrain must be centered at (0,0) in YZ
242
- // to ensure rays intersect the geometry symmetrically around the rotation axis
242
+ // Radial mode casts rays from max_radius distance inward toward the X-axis,
243
+ // and centering ensures the geometry is symmetric around the rotation axis
243
244
  const centerY = (originalBounds.min.y + originalBounds.max.y) / 2;
244
245
  const centerZ = (originalBounds.min.z + originalBounds.max.z) / 2;
245
246
 
@@ -273,12 +274,10 @@ export class RasterPath {
273
274
  * @param {number} params.xStep - Sample every Nth point in X direction
274
275
  * @param {number} params.yStep - Sample every Nth point in Y direction
275
276
  * @param {number} params.zFloor - Z floor value for out-of-bounds areas
276
- * @param {number} params.radiusOffset - (Radial mode only) Distance from terrain surface to tool tip in mm.
277
- * Used to calculate radial collision offset. Default: 20mm
278
277
  * @param {function} params.onProgress - Optional progress callback (progress: number, info?: string) => void
279
278
  * @returns {Promise<object>} Planar: {pathData, width, height} | Radial: {strips[], numStrips, totalPoints}
280
279
  */
281
- async generateToolpaths({ xStep, yStep, zFloor, radiusOffset = 20, onProgress }) {
280
+ async generateToolpaths({ xStep, yStep, zFloor, onProgress }) {
282
281
  if (!this.isInitialized) {
283
282
  throw new Error('RasterPath not initialized. Call init() first.');
284
283
  }
@@ -287,6 +286,8 @@ export class RasterPath {
287
286
  throw new Error('Tool not loaded. Call loadTool() first.');
288
287
  }
289
288
 
289
+ debug.log('gen.paths', { xStep, yStep, zFloor });
290
+
290
291
  if (this.mode === 'planar') {
291
292
  if (!this.terrainData) {
292
293
  throw new Error('Terrain not loaded. Call loadTerrain() first.');
@@ -444,8 +445,7 @@ export class RasterPath {
444
445
  zFloor: zFloor,
445
446
  bounds,
446
447
  xStep,
447
- yStep,
448
- gridStep: this.resolution
448
+ yStep
449
449
  },
450
450
  'radial-toolpaths-complete',
451
451
  completionHandler
package/build/style.css CHANGED
@@ -23,10 +23,26 @@ body {
23
23
  height: 100%;
24
24
  }
25
25
 
26
+ .model-controls {
27
+ position: absolute;
28
+ top: 20px;
29
+ left: 20px;
30
+ background: rgba(0, 0, 0, 0.85);
31
+ backdrop-filter: blur(10px);
32
+ border: 1px solid #333;
33
+ border-radius: 8px;
34
+ padding: 20px;
35
+ min-width: 200px;
36
+ max-width: 240px;
37
+ z-index: 100;
38
+ }
39
+
26
40
  .controls {
27
41
  position: absolute;
28
42
  top: 20px;
29
43
  right: 20px;
44
+ bottom: 20px;
45
+ overflow-y: auto;
30
46
  background: rgba(0, 0, 0, 0.85);
31
47
  backdrop-filter: blur(10px);
32
48
  border: 1px solid #333;
@@ -156,3 +172,52 @@ input[type="checkbox"] {
156
172
  .hide {
157
173
  display: none;
158
174
  }
175
+
176
+ /* Rotation controls */
177
+ .rotation-controls {
178
+ display: flex;
179
+ flex-direction: column;
180
+ gap: 8px;
181
+ }
182
+
183
+ .rotation-row {
184
+ display: flex;
185
+ align-items: center;
186
+ gap: 6px;
187
+ }
188
+
189
+ .rotation-label {
190
+ font-size: 13px;
191
+ font-weight: 600;
192
+ min-width: 18px;
193
+ color: #00ffff;
194
+ }
195
+
196
+ .rotate-btn {
197
+ flex: 1;
198
+ padding: 6px 10px;
199
+ font-size: 11px;
200
+ font-weight: 600;
201
+ background: rgba(0, 255, 255, 0.08);
202
+ border: 1px solid #00ffff;
203
+ border-radius: 4px;
204
+ color: #00ffff;
205
+ cursor: pointer;
206
+ transition: all 0.2s ease;
207
+ }
208
+
209
+ .rotate-btn:hover {
210
+ background: rgba(0, 255, 255, 0.15);
211
+ box-shadow: 0 0 6px rgba(0, 255, 255, 0.2);
212
+ }
213
+
214
+ .rotate-btn:active {
215
+ background: rgba(0, 255, 255, 0.25);
216
+ transform: scale(0.98);
217
+ }
218
+
219
+ .btn-small {
220
+ padding: 6px 10px;
221
+ font-size: 11px;
222
+ margin-top: 4px;
223
+ }