| 353 | console.error('THREE.OrbitControls is not available!'); |
| 354 | } |
| 355 | |
| 356 | // Handle window resize |
| 357 | window.addEventListener('resize', onPreviewResize); |
| 358 | |
| 359 | // Start animation loop |
| 360 | animatePreview(); |
| 361 | } |
| 362 | |
| 363 | function getEncodedFilePath(filePath) { |
| 364 | try { |
| 365 | const normalizedPath = filePath.replace(/\\/g, '/'); |
| 366 | const prefix = normalizedPath.startsWith('/') ? 'file://' : 'file:///'; |
| 367 | return `${prefix}${normalizedPath}` |
| 368 | .replace(/#/g, '%23') |
| 369 | .replace(/\?/g, '%3F') |
| 370 | .replace(/\s/g, '%20') |
| 371 | .replace(/\(/g, '%28') |
| 372 | .replace(/\)/g, '%29') |
| 373 | .replace(/'/g, '%27') |
| 374 | .replace(/\[/g, '%5B') |
| 375 | .replace(/\]/g, '%5D'); |
| 376 | } catch (error) { |
| 377 | console.error('Error encoding file path:', error); |
| 378 | return `file://${filePath.replace(/\\/g, '/').replace(/#/g, '%23').replace(/\s/g, '%20')}`; |
| 379 | } |
| 380 | } |
| 381 | |
| 382 | const MAX_STL_TRIANGLES = 10000000; |