three-slicer 0.1.0 โ†’ 0.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.
Files changed (58) hide show
  1. package/README.md +342 -24
  2. package/components/README.md +1 -1
  3. package/components/dist/SettingsPanel.js +3 -4
  4. package/engine/index.d.ts +3 -1
  5. package/engine/src/data.js +12 -0
  6. package/engine/src/settings.js +1 -1
  7. package/engine/src/slicer.worker.js +2 -1
  8. package/engine/src/slicer_core.js +0 -0
  9. package/engine/src/slicer_core.mt.js +0 -0
  10. package/engine/src/toggle_eval.js +1 -2
  11. package/package.json +54 -26
  12. package/types/components.d.ts +19 -0
  13. package/types/data/config-schema.json.d.ts +55 -0
  14. package/types/data/invalidation-map.json.d.ts +15 -0
  15. package/types/data/toggle-rules.json.d.ts +20 -0
  16. package/types/data/ui-tree.json.d.ts +19 -0
  17. package/types/data.d.ts +17 -0
  18. package/types/gen_settings_types.mjs +70 -0
  19. package/types/settings-keys.d.ts +1704 -0
  20. package/types/settings.d.ts +19 -0
  21. package/types/toggle.d.ts +22 -0
  22. package/types/viewer-loaders.d.ts +33 -0
  23. package/types/viewer-toolpath.d.ts +105 -0
  24. package/types/viewer.d.ts +15 -0
  25. package/types/wasm.d.ts +5 -0
  26. package/types/worker.d.ts +3 -0
  27. package/viewer/README.md +1 -1
  28. package/viewer/dist/Viewport.js +674 -617
  29. package/viewer/dist/model_loaders.js +220 -108
  30. package/viewer/styles.css +2 -0
  31. package/data/config-schema-builddump.json +0 -12921
  32. package/viewer/src/Viewport.jsx +0 -1353
  33. package/viewer/src/assets/add.svg +0 -1
  34. package/viewer/src/assets/arrange.svg +0 -1
  35. package/viewer/src/assets/boolean.svg +0 -1
  36. package/viewer/src/assets/cut.svg +0 -1
  37. package/viewer/src/assets/delete.svg +0 -1
  38. package/viewer/src/assets/deleteall.svg +0 -1
  39. package/viewer/src/assets/duplicate.svg +0 -1
  40. package/viewer/src/assets/measure.svg +0 -1
  41. package/viewer/src/assets/mmu.svg +0 -1
  42. package/viewer/src/assets/move.svg +0 -1
  43. package/viewer/src/assets/negative.svg +0 -1
  44. package/viewer/src/assets/onbed.svg +0 -1
  45. package/viewer/src/assets/open.svg +0 -1
  46. package/viewer/src/assets/orient.svg +0 -1
  47. package/viewer/src/assets/paint.svg +0 -1
  48. package/viewer/src/assets/rotate.svg +0 -1
  49. package/viewer/src/assets/scale.svg +0 -1
  50. package/viewer/src/assets/seam.svg +0 -1
  51. package/viewer/src/assets/split.svg +0 -1
  52. package/viewer/src/assets/textmark.svg +0 -1
  53. package/viewer/src/assets/varlayer.svg +0 -1
  54. package/viewer/src/icons.js +0 -23
  55. package/viewer/src/make_worker.js +0 -9
  56. package/viewer/src/model_loaders.js +0 -178
  57. package/viewer/src/shadow_host.jsx +0 -30
  58. package/viewer/src/toolpath_gpu.js +0 -430
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Zm3-6h3m2,0h3m-4-4v8" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path d="M33.5,35H5.5A1.5,1.5,0,0,1,4,33.5V5.5A1.5,1.5,0,0,1,5.5,4h28A1.5,1.5,0,0,1,35,5.5v28A1.5,1.5,0,0,1,33.5,35ZM5.5,5a.5.5,0,0,0-.5.5v28a.5.5,0,0,0,.5.5h28a.5.5,0,0,0,.5-.5V5.5a.5.5,0,0,0-.5-.5Z" style="fill:#b6b6b6"/><path d="M30.5,32H8.5A1.5,1.5,0,0,1,7,30.5v-6A1.5,1.5,0,0,1,8.5,23h22A1.5,1.5,0,0,1,32,24.5v6A1.5,1.5,0,0,1,30.5,32Zm-22-8a.5.5,0,0,0-.5.5v6a.5.5,0,0,0,.5.5h22a.5.5,0,0,0,.5-.5v-6a.5.5,0,0,0-.5-.5Zm22-2h-6A1.5,1.5,0,0,1,23,20.5V8.5A1.5,1.5,0,0,1,24.5,7h6A1.5,1.5,0,0,1,32,8.5v12A1.5,1.5,0,0,1,30.5,22Zm-6-14a.5.5,0,0,0-.5.5v12a.5.5,0,0,0,.5.5h6a.5.5,0,0,0,.5-.5V8.5a.5.5,0,0,0-.5-.5Zm-6,6h-8a3.5,3.5,0,0,1,0-7h8a3.5,3.5,0,0,1,0,7Zm-8-6a2.5,2.5,0,0,0,0,5h8a2.5,2.5,0,0,0,0-5Zm8,14A3.5,3.5,0,1,1,22,18.5,3.5,3.5,0,0,1,18.5,22Zm0-6A2.5,2.5,0,1,0,21,18.5,2.5,2.5,0,0,0,18.5,16Zm-8,6A3.5,3.5,0,1,1,14,18.5,3.5,3.5,0,0,1,10.5,22Zm0-6A2.5,2.5,0,1,0,13,18.5,2.5,2.5,0,0,0,10.5,16Z" style="fill:#009688"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M6.2,8a2.6,2.6,0,1,0,5.2,0a2.6,2.6,0,1,0,-5.2,0" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M4.6,8a2.6,2.6,0,1,0,5.2,0a2.6,2.6,0,1,0,-5.2,0" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M3.5,9h2m2,0h2m2,0h2" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M8,3.5l1.8,3h-3.6z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Zm3-6h8" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M5,5l6,6" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M11,5l-6,6" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M4,4h5v5H4z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M7,7h5v5H7z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M2.5,8h11" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M2.5,6v4" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M13.5,6v4" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M6,7v2" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M10,7v2" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M4,8a4,4,0,1,0,8,0a4,4,0,1,0,-8,0" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M8,4a4,4,0,0,1,0,8z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1;fill:#949494;stroke:none"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path d="M34.854,19.146l-4-4a.5.5,0,0,0-.708.708L33.293,19H28.5a.5.5,0,0,0,0,1h4.793l-3.147,3.146a.5.5,0,0,0,.708.708l4-4A.5.5,0,0,0,34.854,19.146Z" style="fill:#009688"/><path d="M19.854,4.146a.5.5,0,0,0-.708,0l-4,4a.5.5,0,0,0,.708.708L19,5.707V10.5a.5.5,0,0,0,1,0V5.707l3.146,3.147a.5.5,0,0,0,.708-.708Z" style="fill:#009688"/><path d="M23.146,30.146,20,33.293V28.5a.5.5,0,0,0-1,0v4.793l-3.146-3.147a.5.5,0,0,0-.708.708l4,4a.5.5,0,0,0,.708,0l4-4a.5.5,0,0,0-.708-.708Z" style="fill:#009688"/><path d="M10.5,19H5.707l3.147-3.146a.5.5,0,0,0-.708-.708l-4,4a.5.5,0,0,0,0,.708l4,4a.5.5,0,0,0,.708-.708L5.707,20H10.5a.5.5,0,0,0,0-1Z" style="fill:#009688"/><path d="M24.5,26h-10A1.5,1.5,0,0,1,13,24.5v-10A1.5,1.5,0,0,1,14.5,13h10A1.5,1.5,0,0,1,26,14.5v10A1.5,1.5,0,0,1,24.5,26Zm-10-12a.5.5,0,0,0-.5.5v10a.5.5,0,0,0,.5.5h10a.5.5,0,0,0,.5-.5v-10a.5.5,0,0,0-.5-.5Z" style="fill:#b6b6b6"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M5,5h6v6H5z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1;stroke-dasharray:2 1.5"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M8,3.5v5m-2-2 2,2 2-2" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M4,11.5h8" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path d="M34.923,10.25a.392.392,0,0,0-.033-.05.5.5,0,0,0-.2-.162l0,0-15-6a.5.5,0,0,0-.372,0l-15,6,0,0a.5.5,0,0,0-.2.162.392.392,0,0,0-.033.05A.478.478,0,0,0,4,10.5v18a.464.464,0,0,0,.028.138.429.429,0,0,0,.011.054l.01.015a.51.51,0,0,0,.1.144l.008,0a.5.5,0,0,0,.156.1l0,0,14.989,6,0,0,.006,0a.5.5,0,0,0,.372,0l.006,0,0,0,1.989-.8a.5.5,0,0,0-.372-.928L20,33.762V16.839l14-5.6V21.5a.5.5,0,0,0,1,0v-11A.481.481,0,0,0,34.923,10.25ZM19,33.762l-14-5.6V11.239l14,5.6Zm.5-17.8L5.846,10.5,19.5,5.039,33.153,10.5Z" style="fill:#b6b6b6"/><path d="M33.5,24h-8A1.5,1.5,0,0,0,24,25.5v8A1.5,1.5,0,0,0,25.5,35h8A1.5,1.5,0,0,0,35,33.5v-8A1.5,1.5,0,0,0,33.5,24Zm.5,9.5a.5.5,0,0,1-.5.5h-8a.5.5,0,0,1-.5-.5v-8a.5.5,0,0,1,.5-.5h8a.5.5,0,0,1,.5.5Z" style="fill:#009688"/><path d="M32.5,29H30V26.5a.5.5,0,0,0-1,0V29H26.5a.5.5,0,0,0,0,1H29v2.5a.5.5,0,0,0,1,0V30h2.5a.5.5,0,0,0,0-1Z" style="fill:#009688"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path d="M25.5,22a.5.5,0,0,1-.5-.5V18H18v3.5a.5.5,0,0,1-1,0v-6a.5.5,0,0,1,.084-.277l2-3A.5.5,0,0,1,19.5,12h4a.5.5,0,0,1,.416.223l2,3A.5.5,0,0,1,26,15.5v6A.5.5,0,0,1,25.5,22ZM18,17h7V15.651L23.232,13H19.768L18,15.651Z" style="fill:#009688"/><path d="M11.964,29.314a.5.5,0,0,0-.65-.278L7.152,30.7a17.321,17.321,0,0,1,3.739-6.888.5.5,0,1,0-.782-.624A19.312,19.312,0,0,0,6.359,29.8L4.964,26.314a.5.5,0,1,0-.928.372l2,5c0,.01.016.015.021.025a.475.475,0,0,0,.15.185c.009.007.016.017.025.023a.5.5,0,0,0,.2.076A.367.367,0,0,0,6.5,32h0a.475.475,0,0,0,.181-.036h0l5-2A.5.5,0,0,0,11.964,29.314Z" style="fill:#009688"/><rect x="4" y="34" width="31" height="1" style="fill:#009688"/><path d="M34.854,17.146l-13-13a.5.5,0,0,0-.708,0l-13,13a.5.5,0,0,0,.708.708L21.5,5.207,33.793,17.5,21.146,30.146a.5.5,0,0,0,.708.708l13-13A.5.5,0,0,0,34.854,17.146Z" style="fill:#b6b6b6"/><path d="M21.5,31a.5.5,0,0,1-.354-.146l-13-13a.5.5,0,0,1,.708-.708l13,13A.5.5,0,0,1,21.5,31Z" style="fill:#009688"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path d="M27.878,34.926h-4.4c-.509,0-.845,0-.955-.394a.593.593,0,0,1,.36-.67,2.3,2.3,0,0,0,1.2-2.189,3.253,3.253,0,1,1,3.8,3.206Zm-3.538-1h2.988a2.253,2.253,0,1,0-2.253-2.253A3.445,3.445,0,0,1,24.34,33.926Z" style="fill:#009688"/><path d="M30.5,30.289l-.846-.535,4.364-6.9a.222.222,0,0,0-.36-.258l-5.4,6.644-.776-.631,5.4-6.644a1.222,1.222,0,0,1,1.982,1.423Z" style="fill:#009688"/><path d="M33.5,35h-1a.5.5,0,0,1,0-1h1a.5.5,0,0,0,.5-.5v-5a.5.5,0,0,1,1,0v5A1.5,1.5,0,0,1,33.5,35Z" style="fill:#b6b6b6"/><path d="M7.5,35a.5.5,0,0,1-.5-.5v-20a.5.5,0,0,1,1,0v20A.5.5,0,0,1,7.5,35Z" style="fill:#009688"/><path d="M10.5,35a.5.5,0,0,1-.5-.5v-20a.5.5,0,0,1,1,0v20A.5.5,0,0,1,10.5,35Z" style="fill:#009688"/><path d="M13.5,35h-9a.5.5,0,0,1-.5-.5v-20a.5.5,0,0,1,.5-.5h9a.5.5,0,0,1,.5.5v20A.5.5,0,0,1,13.5,35ZM5,34h8V15H5Z" style="fill:#009688"/><path d="M22.5,29a.5.5,0,0,1-.5-.5V15H4.5a.5.5,0,0,1-.5-.5v-9A1.5,1.5,0,0,1,5.5,4h28A1.5,1.5,0,0,1,35,5.5v13a.5.5,0,0,1-1,0V5.5a.5.5,0,0,0-.5-.5H5.5a.5.5,0,0,0-.5.5V14H22.5a.5.5,0,0,1,.5.5v14A.5.5,0,0,1,22.5,29Z" style="fill:#b6b6b6"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path d="M24.5,26h-10A1.5,1.5,0,0,1,13,24.5v-10A1.5,1.5,0,0,1,14.5,13h10A1.5,1.5,0,0,1,26,14.5v10A1.5,1.5,0,0,1,24.5,26Zm-10-12a.5.5,0,0,0-.5.5v10a.5.5,0,0,0,.5.5h10a.5.5,0,0,0,.5-.5v-10a.5.5,0,0,0-.5-.5Z" style="fill:#b6b6b6"/><path d="M35,19.5A15.517,15.517,0,0,1,19.5,35a15.767,15.767,0,0,1-2.063-.136.5.5,0,0,1-.43-.562.507.507,0,0,1,.562-.43A14.5,14.5,0,1,0,19.5,5,14.43,14.43,0,0,0,7.751,11H11.5a.5.5,0,0,1,0,1h-5a.5.5,0,0,1-.5-.5v-5a.5.5,0,0,1,1,0v3.836A15.5,15.5,0,0,1,35,19.5ZM5.943,24.66a.5.5,0,1,0-.933.356A15.426,15.426,0,0,0,7.354,29.13a.5.5,0,0,0,.783-.621A14.533,14.533,0,0,1,5.943,24.66Zm8.4,8.4a14.523,14.523,0,0,1-3.85-2.194.5.5,0,0,0-.621.784,15.455,15.455,0,0,0,4.115,2.343.487.487,0,0,0,.178.033.5.5,0,0,0,.178-.966ZM5.128,21.431A14.621,14.621,0,0,1,5,19.5a.5.5,0,0,0-1,0,15.729,15.729,0,0,0,.136,2.062.5.5,0,0,0,.992-.131Z" style="fill:#009688"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><path d="M25.5,5h-2a.5.5,0,0,1,0-1h2a.5.5,0,0,1,0,1ZM21,4.5a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,21,4.5Zm-5,0a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,16,4.5Zm10,30a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,26,34.5Zm-5,0a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,21,34.5Zm-5,0a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,16,34.5ZM5,15.5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm0,5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm0,5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm30-10v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm0,5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm0,5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm-9-1v-10A1.5,1.5,0,0,0,24.5,13h-10A1.5,1.5,0,0,0,13,14.5v10A1.5,1.5,0,0,0,14.5,26h10A1.5,1.5,0,0,0,26,24.5ZM24.5,14a.5.5,0,0,1,.5.5v10a.5.5,0,0,1-.5.5h-10a.5.5,0,0,1-.5-.5v-10a.5.5,0,0,1,.5-.5Z" style="fill:#b6b6b6"/><path d="M34.962,4.309A.5.5,0,0,0,34.5,4h-5a.5.5,0,0,0,0,1h3.793l-6.147,6.146a.5.5,0,0,0,.708.708L34,5.707V9.5a.5.5,0,0,0,1,0v-5A.5.5,0,0,0,34.962,4.309Z" style="fill:#009688"/><path d="M5.707,5H9.5a.5.5,0,0,0,0-1h-5a.5.5,0,0,0-.5.5v5a.5.5,0,0,0,1,0V5.707l6.146,6.147a.5.5,0,0,0,.708-.708Z" style="fill:#009688"/><path d="M34.5,29a.5.5,0,0,0-.5.5v3.793l-6.146-6.147a.5.5,0,0,0-.708.708L33.293,34H29.5a.5.5,0,0,0,0,1h5a.5.5,0,0,0,.5-.5v-5A.5.5,0,0,0,34.5,29Z" style="fill:#009688"/><path d="M11.146,27.146,5,33.293V29.5a.5.5,0,0,0-1,0v5a.5.5,0,0,0,.5.5h5a.5.5,0,0,0,0-1H5.707l6.147-6.146a.5.5,0,0,0-.708-.708Z" style="fill:#009688"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M8,3.5v2m0,2v2m0,2v2" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M8,3.5v9" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M6,6.5,4,8l2,1.5" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M10,6.5,12,8l-2,1.5" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M4.5,5h7" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M8,5v6.5" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M3,4.5h10" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M3,7h10" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M3,9h10" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M3,10.5h10" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/><path d="M3,11.6h10" style="fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1"/></svg>
@@ -1,23 +0,0 @@
1
- // ์•„์ด์ฝ˜ ๋ฐ์ดํ„ฐ URI โ€” assets/*.svg ๋ฅผ ์ธ๋ผ์ธ(๋ฒˆ๋“ค๋Ÿฌ svg ๋กœ๋” ์˜์กด ์ œ๊ฑฐ).
2
- // ์žฌ์ƒ์„ฑ: node -e ๋กœ assets ๋ฅผ ์ˆœํšŒํ•ด ์ด ํŒŒ์ผ์„ ๋‹ค์‹œ ์“ด๋‹ค(์ˆ˜๋™ ํŽธ์ง‘ ๊ธˆ์ง€).
3
- export const addIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Zm3-6h3m2,0h3m-4-4v8\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
4
- export const arrangeIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\"><path d=\"M33.5,35H5.5A1.5,1.5,0,0,1,4,33.5V5.5A1.5,1.5,0,0,1,5.5,4h28A1.5,1.5,0,0,1,35,5.5v28A1.5,1.5,0,0,1,33.5,35ZM5.5,5a.5.5,0,0,0-.5.5v28a.5.5,0,0,0,.5.5h28a.5.5,0,0,0,.5-.5V5.5a.5.5,0,0,0-.5-.5Z\" style=\"fill:#b6b6b6\"/><path d=\"M30.5,32H8.5A1.5,1.5,0,0,1,7,30.5v-6A1.5,1.5,0,0,1,8.5,23h22A1.5,1.5,0,0,1,32,24.5v6A1.5,1.5,0,0,1,30.5,32Zm-22-8a.5.5,0,0,0-.5.5v6a.5.5,0,0,0,.5.5h22a.5.5,0,0,0,.5-.5v-6a.5.5,0,0,0-.5-.5Zm22-2h-6A1.5,1.5,0,0,1,23,20.5V8.5A1.5,1.5,0,0,1,24.5,7h6A1.5,1.5,0,0,1,32,8.5v12A1.5,1.5,0,0,1,30.5,22Zm-6-14a.5.5,0,0,0-.5.5v12a.5.5,0,0,0,.5.5h6a.5.5,0,0,0,.5-.5V8.5a.5.5,0,0,0-.5-.5Zm-6,6h-8a3.5,3.5,0,0,1,0-7h8a3.5,3.5,0,0,1,0,7Zm-8-6a2.5,2.5,0,0,0,0,5h8a2.5,2.5,0,0,0,0-5Zm8,14A3.5,3.5,0,1,1,22,18.5,3.5,3.5,0,0,1,18.5,22Zm0-6A2.5,2.5,0,1,0,21,18.5,2.5,2.5,0,0,0,18.5,16Zm-8,6A3.5,3.5,0,1,1,14,18.5,3.5,3.5,0,0,1,10.5,22Zm0-6A2.5,2.5,0,1,0,13,18.5,2.5,2.5,0,0,0,10.5,16Z\" style=\"fill:#009688\"/></svg>")
5
- export const booleanIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M6.2,8a2.6,2.6,0,1,0,5.2,0a2.6,2.6,0,1,0,-5.2,0\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M4.6,8a2.6,2.6,0,1,0,5.2,0a2.6,2.6,0,1,0,-5.2,0\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
6
- export const cutIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M3.5,9h2m2,0h2m2,0h2\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M8,3.5l1.8,3h-3.6z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
7
- export const deleteIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Zm3-6h8\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
8
- export const deleteallIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M5,5l6,6\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M11,5l-6,6\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
9
- export const duplicateIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M4,4h5v5H4z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M7,7h5v5H7z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
10
- export const measureIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2.5,8h11\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M2.5,6v4\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M13.5,6v4\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M6,7v2\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M10,7v2\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
11
- export const mmuIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M4,8a4,4,0,1,0,8,0a4,4,0,1,0,-8,0\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M8,4a4,4,0,0,1,0,8z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1;fill:#949494;stroke:none\"/></svg>")
12
- export const moveIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\"><path d=\"M34.854,19.146l-4-4a.5.5,0,0,0-.708.708L33.293,19H28.5a.5.5,0,0,0,0,1h4.793l-3.147,3.146a.5.5,0,0,0,.708.708l4-4A.5.5,0,0,0,34.854,19.146Z\" style=\"fill:#009688\"/><path d=\"M19.854,4.146a.5.5,0,0,0-.708,0l-4,4a.5.5,0,0,0,.708.708L19,5.707V10.5a.5.5,0,0,0,1,0V5.707l3.146,3.147a.5.5,0,0,0,.708-.708Z\" style=\"fill:#009688\"/><path d=\"M23.146,30.146,20,33.293V28.5a.5.5,0,0,0-1,0v4.793l-3.146-3.147a.5.5,0,0,0-.708.708l4,4a.5.5,0,0,0,.708,0l4-4a.5.5,0,0,0-.708-.708Z\" style=\"fill:#009688\"/><path d=\"M10.5,19H5.707l3.147-3.146a.5.5,0,0,0-.708-.708l-4,4a.5.5,0,0,0,0,.708l4,4a.5.5,0,0,0,.708-.708L5.707,20H10.5a.5.5,0,0,0,0-1Z\" style=\"fill:#009688\"/><path d=\"M24.5,26h-10A1.5,1.5,0,0,1,13,24.5v-10A1.5,1.5,0,0,1,14.5,13h10A1.5,1.5,0,0,1,26,14.5v10A1.5,1.5,0,0,1,24.5,26Zm-10-12a.5.5,0,0,0-.5.5v10a.5.5,0,0,0,.5.5h10a.5.5,0,0,0,.5-.5v-10a.5.5,0,0,0-.5-.5Z\" style=\"fill:#b6b6b6\"/></svg>")
13
- export const negativeIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M5,5h6v6H5z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1;stroke-dasharray:2 1.5\"/></svg>")
14
- export const onbedIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M8,3.5v5m-2-2 2,2 2-2\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M4,11.5h8\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
15
- export const openIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\"><path d=\"M34.923,10.25a.392.392,0,0,0-.033-.05.5.5,0,0,0-.2-.162l0,0-15-6a.5.5,0,0,0-.372,0l-15,6,0,0a.5.5,0,0,0-.2.162.392.392,0,0,0-.033.05A.478.478,0,0,0,4,10.5v18a.464.464,0,0,0,.028.138.429.429,0,0,0,.011.054l.01.015a.51.51,0,0,0,.1.144l.008,0a.5.5,0,0,0,.156.1l0,0,14.989,6,0,0,.006,0a.5.5,0,0,0,.372,0l.006,0,0,0,1.989-.8a.5.5,0,0,0-.372-.928L20,33.762V16.839l14-5.6V21.5a.5.5,0,0,0,1,0v-11A.481.481,0,0,0,34.923,10.25ZM19,33.762l-14-5.6V11.239l14,5.6Zm.5-17.8L5.846,10.5,19.5,5.039,33.153,10.5Z\" style=\"fill:#b6b6b6\"/><path d=\"M33.5,24h-8A1.5,1.5,0,0,0,24,25.5v8A1.5,1.5,0,0,0,25.5,35h8A1.5,1.5,0,0,0,35,33.5v-8A1.5,1.5,0,0,0,33.5,24Zm.5,9.5a.5.5,0,0,1-.5.5h-8a.5.5,0,0,1-.5-.5v-8a.5.5,0,0,1,.5-.5h8a.5.5,0,0,1,.5.5Z\" style=\"fill:#009688\"/><path d=\"M32.5,29H30V26.5a.5.5,0,0,0-1,0V29H26.5a.5.5,0,0,0,0,1H29v2.5a.5.5,0,0,0,1,0V30h2.5a.5.5,0,0,0,0-1Z\" style=\"fill:#009688\"/></svg>")
16
- export const orientIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\"><path d=\"M25.5,22a.5.5,0,0,1-.5-.5V18H18v3.5a.5.5,0,0,1-1,0v-6a.5.5,0,0,1,.084-.277l2-3A.5.5,0,0,1,19.5,12h4a.5.5,0,0,1,.416.223l2,3A.5.5,0,0,1,26,15.5v6A.5.5,0,0,1,25.5,22ZM18,17h7V15.651L23.232,13H19.768L18,15.651Z\" style=\"fill:#009688\"/><path d=\"M11.964,29.314a.5.5,0,0,0-.65-.278L7.152,30.7a17.321,17.321,0,0,1,3.739-6.888.5.5,0,1,0-.782-.624A19.312,19.312,0,0,0,6.359,29.8L4.964,26.314a.5.5,0,1,0-.928.372l2,5c0,.01.016.015.021.025a.475.475,0,0,0,.15.185c.009.007.016.017.025.023a.5.5,0,0,0,.2.076A.367.367,0,0,0,6.5,32h0a.475.475,0,0,0,.181-.036h0l5-2A.5.5,0,0,0,11.964,29.314Z\" style=\"fill:#009688\"/><rect x=\"4\" y=\"34\" width=\"31\" height=\"1\" style=\"fill:#009688\"/><path d=\"M34.854,17.146l-13-13a.5.5,0,0,0-.708,0l-13,13a.5.5,0,0,0,.708.708L21.5,5.207,33.793,17.5,21.146,30.146a.5.5,0,0,0,.708.708l13-13A.5.5,0,0,0,34.854,17.146Z\" style=\"fill:#b6b6b6\"/><path d=\"M21.5,31a.5.5,0,0,1-.354-.146l-13-13a.5.5,0,0,1,.708-.708l13,13A.5.5,0,0,1,21.5,31Z\" style=\"fill:#009688\"/></svg>")
17
- export const paintIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\"><path d=\"M27.878,34.926h-4.4c-.509,0-.845,0-.955-.394a.593.593,0,0,1,.36-.67,2.3,2.3,0,0,0,1.2-2.189,3.253,3.253,0,1,1,3.8,3.206Zm-3.538-1h2.988a2.253,2.253,0,1,0-2.253-2.253A3.445,3.445,0,0,1,24.34,33.926Z\" style=\"fill:#009688\"/><path d=\"M30.5,30.289l-.846-.535,4.364-6.9a.222.222,0,0,0-.36-.258l-5.4,6.644-.776-.631,5.4-6.644a1.222,1.222,0,0,1,1.982,1.423Z\" style=\"fill:#009688\"/><path d=\"M33.5,35h-1a.5.5,0,0,1,0-1h1a.5.5,0,0,0,.5-.5v-5a.5.5,0,0,1,1,0v5A1.5,1.5,0,0,1,33.5,35Z\" style=\"fill:#b6b6b6\"/><path d=\"M7.5,35a.5.5,0,0,1-.5-.5v-20a.5.5,0,0,1,1,0v20A.5.5,0,0,1,7.5,35Z\" style=\"fill:#009688\"/><path d=\"M10.5,35a.5.5,0,0,1-.5-.5v-20a.5.5,0,0,1,1,0v20A.5.5,0,0,1,10.5,35Z\" style=\"fill:#009688\"/><path d=\"M13.5,35h-9a.5.5,0,0,1-.5-.5v-20a.5.5,0,0,1,.5-.5h9a.5.5,0,0,1,.5.5v20A.5.5,0,0,1,13.5,35ZM5,34h8V15H5Z\" style=\"fill:#009688\"/><path d=\"M22.5,29a.5.5,0,0,1-.5-.5V15H4.5a.5.5,0,0,1-.5-.5v-9A1.5,1.5,0,0,1,5.5,4h28A1.5,1.5,0,0,1,35,5.5v13a.5.5,0,0,1-1,0V5.5a.5.5,0,0,0-.5-.5H5.5a.5.5,0,0,0-.5.5V14H22.5a.5.5,0,0,1,.5.5v14A.5.5,0,0,1,22.5,29Z\" style=\"fill:#b6b6b6\"/></svg>")
18
- export const rotateIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\"><path d=\"M24.5,26h-10A1.5,1.5,0,0,1,13,24.5v-10A1.5,1.5,0,0,1,14.5,13h10A1.5,1.5,0,0,1,26,14.5v10A1.5,1.5,0,0,1,24.5,26Zm-10-12a.5.5,0,0,0-.5.5v10a.5.5,0,0,0,.5.5h10a.5.5,0,0,0,.5-.5v-10a.5.5,0,0,0-.5-.5Z\" style=\"fill:#b6b6b6\"/><path d=\"M35,19.5A15.517,15.517,0,0,1,19.5,35a15.767,15.767,0,0,1-2.063-.136.5.5,0,0,1-.43-.562.507.507,0,0,1,.562-.43A14.5,14.5,0,1,0,19.5,5,14.43,14.43,0,0,0,7.751,11H11.5a.5.5,0,0,1,0,1h-5a.5.5,0,0,1-.5-.5v-5a.5.5,0,0,1,1,0v3.836A15.5,15.5,0,0,1,35,19.5ZM5.943,24.66a.5.5,0,1,0-.933.356A15.426,15.426,0,0,0,7.354,29.13a.5.5,0,0,0,.783-.621A14.533,14.533,0,0,1,5.943,24.66Zm8.4,8.4a14.523,14.523,0,0,1-3.85-2.194.5.5,0,0,0-.621.784,15.455,15.455,0,0,0,4.115,2.343.487.487,0,0,0,.178.033.5.5,0,0,0,.178-.966ZM5.128,21.431A14.621,14.621,0,0,1,5,19.5a.5.5,0,0,0-1,0,15.729,15.729,0,0,0,.136,2.062.5.5,0,0,0,.992-.131Z\" style=\"fill:#009688\"/></svg>")
19
- export const scaleIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\"><path d=\"M25.5,5h-2a.5.5,0,0,1,0-1h2a.5.5,0,0,1,0,1ZM21,4.5a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,21,4.5Zm-5,0a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,16,4.5Zm10,30a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,26,34.5Zm-5,0a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,21,34.5Zm-5,0a.5.5,0,0,0-.5-.5h-2a.5.5,0,0,0,0,1h2A.5.5,0,0,0,16,34.5ZM5,15.5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm0,5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm0,5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm30-10v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm0,5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm0,5v-2a.5.5,0,0,0-1,0v2a.5.5,0,0,0,1,0Zm-9-1v-10A1.5,1.5,0,0,0,24.5,13h-10A1.5,1.5,0,0,0,13,14.5v10A1.5,1.5,0,0,0,14.5,26h10A1.5,1.5,0,0,0,26,24.5ZM24.5,14a.5.5,0,0,1,.5.5v10a.5.5,0,0,1-.5.5h-10a.5.5,0,0,1-.5-.5v-10a.5.5,0,0,1,.5-.5Z\" style=\"fill:#b6b6b6\"/><path d=\"M34.962,4.309A.5.5,0,0,0,34.5,4h-5a.5.5,0,0,0,0,1h3.793l-6.147,6.146a.5.5,0,0,0,.708.708L34,5.707V9.5a.5.5,0,0,0,1,0v-5A.5.5,0,0,0,34.962,4.309Z\" style=\"fill:#009688\"/><path d=\"M5.707,5H9.5a.5.5,0,0,0,0-1h-5a.5.5,0,0,0-.5.5v5a.5.5,0,0,0,1,0V5.707l6.146,6.147a.5.5,0,0,0,.708-.708Z\" style=\"fill:#009688\"/><path d=\"M34.5,29a.5.5,0,0,0-.5.5v3.793l-6.146-6.147a.5.5,0,0,0-.708.708L33.293,34H29.5a.5.5,0,0,0,0,1h5a.5.5,0,0,0,.5-.5v-5A.5.5,0,0,0,34.5,29Z\" style=\"fill:#009688\"/><path d=\"M11.146,27.146,5,33.293V29.5a.5.5,0,0,0-1,0v5a.5.5,0,0,0,.5.5h5a.5.5,0,0,0,0-1H5.707l6.147-6.146a.5.5,0,0,0-.708-.708Z\" style=\"fill:#009688\"/></svg>")
20
- export const seamIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M8,3.5v2m0,2v2m0,2v2\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
21
- export const splitIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M8,3.5v9\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M6,6.5,4,8l2,1.5\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M10,6.5,12,8l-2,1.5\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
22
- export const textmarkIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M.5,13.5V1.5a1,1,0,0,1,1-1h12a1,1,0,0,1,1,1v12a1,1,0,0,1-1,1H1.5A1,1,0,0,1,.5,13.5Z\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M4.5,5h7\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M8,5v6.5\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
23
- export const varlayerIcon = 'data:image/svg+xml;utf8,' + encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M3,4.5h10\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M3,7h10\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M3,9h10\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M3,10.5h10\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/><path d=\"M3,11.6h10\" style=\"fill:none;stroke:#949494;stroke-linecap:square;stroke-linejoin:round;opacity:1\"/></svg>")
@@ -1,9 +0,0 @@
1
- // ์Šฌ๋ผ์ด์„œ ์›Œ์ปค ์ƒ์„ฑ โ€” ์ด ํŒŒ์ผ์€ ๋ฒˆ๋“ค๋˜์ง€ ์•Š๊ณ  dist/ ์— ์›ํ˜• ๋ณต์‚ฌ๋œ๋‹ค (build ์Šคํฌ๋ฆฝํŠธ).
2
- // ์ด์œ : ์†Œ๋น„์ž ๋ฒˆ๋“ค๋Ÿฌ(Vite/webpack)๊ฐ€ ์›Œ์ปค๋ฅผ ์ฒญํฌ๋กœ ์ธ์‹ํ•˜๋ ค๋ฉด `new Worker(new URL('๋ฆฌํ„ฐ๋Ÿด', import.meta.url))`
3
- // ์ •์  ํŒจํ„ด์ด ์†Œ๋น„์ž์—๊ฒŒ ๋ณด์ด๋Š” ํŒŒ์ผ์— ๊ทธ๋Œ€๋กœ ๋‚จ์•„ ์žˆ์–ด์•ผ ํ•œ๋‹ค. viewer ์ž์ฒด lib ๋นŒ๋“œ๊ฐ€ ์ด๊ฑธ ์ฒ˜๋ฆฌํ•˜๋ฉด
4
- // ์‚ฌ์ดํŠธ ๋ฃจํŠธ ๊ธฐ์ค€ ์ ˆ๋Œ€๊ฒฝ๋กœ ์ž์‚ฐ์œผ๋กœ ๊ตณ์–ด์ ธ ์†Œ๋น„์ž ์•ฑ์—์„œ 404 ๊ฐ€ ๋‚œ๋‹ค.
5
- // ๊ฒฝ๋กœ '../../engine/โ€ฆ' ์€ dist/ ๊ธฐ์ค€: ๋ชจ๋…ธ๋ ˆํฌ(packages/viewer/distโ†’packages/engine)์™€
6
- // npm ์„ค์น˜(@three-slicer/ ์Šค์ฝ”ํ”„ ํ˜•์ œ ๋””๋ ‰ํ† ๋ฆฌ) ์–‘์ชฝ์—์„œ engine ํŒจํ‚ค์ง€๋กœ ํ•ด์„๋œ๋‹ค.
7
- export function makeSlicerWorker() {
8
- return new Worker(new URL('../../engine/src/slicer.worker.js', import.meta.url), { type: 'module' })
9
- }
@@ -1,178 +0,0 @@
1
- // 26๋‹จ๊ณ„: ํ†ต์ผ ๋ชจ๋ธ ์ž„ํฌํŠธ ํŒŒ์ดํ”„๋ผ์ธ โ€” STL/OBJ/3MF/AMF/PLY.
2
- // three/examples/jsm ๋กœ๋” ์žฌ์‚ฌ์šฉ(์‹ ๊ทœ npm ์˜์กด์„ฑ ์—†์Œ). ๊ฐ ๋กœ๋” ๊ฒฐ๊ณผ(BufferGeometry|Group) โ†’
3
- // ์›”๋“œํ–‰๋ ฌ ๋ฒ ์ดํฌ โ†’ ๋น„์ธ๋ฑ์Šค ์‚ผ๊ฐํ˜• โ†’ **model z-up** flat ๋ฐฐ์—ด(N*9). ์Šฌ๋ผ์ด์Šค ๊ฒฝ๋กœ(addObjectโ†’buildMergedSTLโ†’์ปค๋„) ์žฌ์‚ฌ์šฉ.
4
- // ์ขŒํ‘œ๊ณ„(์‹ค์ธก): 3D ํ”„๋ฆฐํŒ… ํฌ๋งท์€ ๋ชจ๋‘ z-up mm. three ๋กœ๋”๋Š” ์ถ• ๋ณ€ํ™˜์„ ํ•˜์ง€ ์•Š๊ณ  ํŒŒ์ผ ์›์ขŒํ‘œ๋ฅผ ๊ทธ๋Œ€๋กœ ๋กœ๋“œํ•˜๋ฏ€๋กœ,
5
- // STL/3MF/AMF/PLY ๋Š” z-up ๊ทธ๋Œ€๋กœ model ์ขŒํ‘œ๋กœ ์‚ฌ์šฉ. OBJ ๋Š” ๊ด€๋ก€์ƒ y-up(๊ทธ๋ž˜ํ”ฝ) ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋‚˜ ํ”„๋ฆฐํŒ… OBJ ๋Š” z-up ์ด
6
- // ์ผ๋ฐ˜์  โ†’ z-up ๊ธฐ๋ณธ(๋ถ€์ ์ ˆ ์‹œ ๊ธฐ์ฆˆ๋ชจ ํšŒ์ „). ์ด ํŒ๋‹จ์€ ํ”„๋ฆฐํŒ… ์›Œํฌํ”Œ๋กœ ๊ธฐ์ค€(๊ทผ๊ฑฐ ์ฃผ์„).
7
- import * as THREE from 'three'
8
- import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'
9
- import { PLYLoader } from 'three/examples/jsm/loaders/PLYLoader.js'
10
- import { ThreeMFLoader } from 'three/examples/jsm/loaders/3MFLoader.js'
11
- import { AMFLoader } from 'three/examples/jsm/loaders/AMFLoader.js'
12
-
13
- export const SUPPORTED_EXT = ['stl', 'obj', '3mf', 'amf', 'ply']
14
-
15
- export function fileExt(name) { const i = name.lastIndexOf('.'); return i < 0 ? '' : name.slice(i + 1).toLowerCase() }
16
-
17
- // --- STL ํŒŒ์„œ (๋ฐ”์ด๋„ˆ๋ฆฌ + ASCII) โ†’ model ์ขŒํ‘œ position (N*9) --- (๊ธฐ์กด Viewport ๋กœ์ง ์ด๊ด€)
18
- function parseSTL(buffer) {
19
- const dv = new DataView(buffer)
20
- if (buffer.byteLength >= 84) {
21
- const n = dv.getUint32(80, true)
22
- if (buffer.byteLength === 84 + n * 50) {
23
- const pos = new Float32Array(n * 9)
24
- let off = 84, p = 0
25
- for (let i = 0; i < n; i++) {
26
- off += 12
27
- for (let v = 0; v < 3; v++) { pos[p++] = dv.getFloat32(off, true); pos[p++] = dv.getFloat32(off + 4, true); pos[p++] = dv.getFloat32(off + 8, true); off += 12 }
28
- off += 2
29
- }
30
- return pos
31
- }
32
- }
33
- const text = new TextDecoder().decode(buffer)
34
- const re = /vertex\s+([-\d.eE+]+)\s+([-\d.eE+]+)\s+([-\d.eE+]+)/g
35
- const nums = []; let m
36
- while ((m = re.exec(text))) nums.push(+m[1], +m[2], +m[3])
37
- if (nums.length < 9) return null
38
- return new Float32Array(nums)
39
- }
40
-
41
- // BufferGeometry(+์›”๋“œํ–‰๋ ฌ) โ†’ ๋น„์ธ๋ฑ์Šค ์‚ผ๊ฐํ˜• model z-up flat ๋ฐฐ์—ด(N*9). ๋กœ๋” ์ขŒํ‘œ=z-up ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ.
42
- function geoToModelTris(geometry, matrix) {
43
- const pos = geometry?.attributes?.position
44
- if (!pos || pos.count < 3) return null
45
- const idx = geometry.index
46
- const v = new THREE.Vector3()
47
- const nTri = Math.floor((idx ? idx.count : pos.count) / 3)
48
- const out = new Float32Array(nTri * 9)
49
- let o = 0
50
- const emit = (i) => { v.fromBufferAttribute(pos, i); if (matrix) v.applyMatrix4(matrix); out[o++] = v.x; out[o++] = v.y; out[o++] = v.z }
51
- if (idx) { for (let i = 0; i < nTri * 3; i++) emit(idx.getX(i)) }
52
- else { for (let i = 0; i < nTri * 3; i++) emit(i) }
53
- return out
54
- }
55
-
56
- // Group/Object3D ์žฌ๊ท€ โ†’ [{geometry, matrixWorld}] (์›”๋“œํ–‰๋ ฌ ๋ฒ ์ดํฌ์šฉ).
57
- function collectMeshes(root) {
58
- root.updateMatrixWorld(true)
59
- const meshes = []
60
- root.traverse(o => { if (o.isMesh && o.geometry) meshes.push({ geometry: o.geometry, matrix: o.matrixWorld }) })
61
- return meshes
62
- }
63
-
64
- // ๋กœ๋” ๊ฒฐ๊ณผ โ†’ ์˜ค๋ธŒ์ ํŠธ ๋ชฉ๋ก. multi=true(3mf/amf) ๋ฉด ๋ฉ”์‹œ๋ณ„ ๊ฐœ๋ณ„ ์˜ค๋ธŒ์ ํŠธ, ์•„๋‹ˆ๋ฉด ํ•˜๋‚˜๋กœ ๋ณ‘ํ•ฉ.
65
- function meshesToObjects(baseName, meshes, multi) {
66
- const parts = meshes.map(m => geoToModelTris(m.geometry, m.matrix)).filter(Boolean)
67
- if (!parts.length) return []
68
- if (multi && parts.length > 1) {
69
- return parts.map((p, i) => ({ name: `${baseName}#${i + 1}`, modelPos: p }))
70
- }
71
- if (parts.length === 1) return [{ name: baseName, modelPos: parts[0] }]
72
- // ๋ณ‘ํ•ฉ
73
- let total = 0; for (const p of parts) total += p.length
74
- const merged = new Float32Array(total); let o = 0
75
- for (const p of parts) { merged.set(p, o); o += p.length }
76
- return [{ name: baseName, modelPos: merged }]
77
- }
78
-
79
- // ๊ณต๊ฐœ API: (ํŒŒ์ผ๋ช…, ArrayBuffer) โ†’ Promise<[{name, modelPos(N*9, model z-up)}]>. ์ปค๋„ ๋ฌด๊ด€ ์ˆœ์ˆ˜.
80
- export async function loadModel(name, buffer) {
81
- const ext = fileExt(name)
82
- switch (ext) {
83
- case 'stl': {
84
- const pos = parseSTL(buffer)
85
- if (!pos) throw new Error('STL ํŒŒ์‹ฑ ์‹คํŒจ')
86
- return [{ name, modelPos: pos }]
87
- }
88
- case 'obj': {
89
- const g = new OBJLoader().parse(new TextDecoder().decode(buffer)) // Group
90
- return meshesToObjects(name, collectMeshes(g), false)
91
- }
92
- case 'ply': {
93
- const geo = new PLYLoader().parse(buffer) // BufferGeometry
94
- const tris = geoToModelTris(geo, null)
95
- if (!tris) throw new Error('PLY ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ ์—†์Œ')
96
- return [{ name, modelPos: tris }]
97
- }
98
- case '3mf': {
99
- const g = new ThreeMFLoader().parse(buffer) // Group (fflate ๋กœ unzip, three ๋‚ด๋ถ€)
100
- const objs = meshesToObjects(name, collectMeshes(g), true) // ๋ณต์ˆ˜ ์˜ค๋ธŒ์ ํŠธ ๊ฐœ๋ณ„ ๋“ฑ๋ก
101
- if (!objs.length) throw new Error('3MF ๋ฉ”์‹œ ์—†์Œ')
102
- return objs
103
- }
104
- case 'amf': {
105
- const g = new AMFLoader().parse(buffer) // Group (DOMParser ์‚ฌ์šฉ โ€” ๋ธŒ๋ผ์šฐ์ €)
106
- const objs = meshesToObjects(name, collectMeshes(g), true)
107
- if (!objs.length) throw new Error('AMF ๋ฉ”์‹œ ์—†์Œ')
108
- return objs
109
- }
110
- default:
111
- throw new Error(`์ง€์›ํ•˜์ง€ ์•Š๋Š” ํฌ๋งท: .${ext} (STEP ์€ ๋ฒ”์œ„ ์™ธ โ€” OCCT ํ•„์š”)`)
112
- }
113
- }
114
-
115
- // ---- 33๋‹จ๊ณ„: ๊ฐ์ฒด ๋ถ„๋ฆฌ (์›๋ณธ Split to objects / TriangleMesh::its_split) ----
116
- // ์›๋ณธ ์ •์˜: "๋ฉด์€ **์—์ง€๋ฅผ ๊ณต์œ ํ•˜๋ฉด** ์—ฐ๊ฒฐ๋œ ๊ฒƒ์œผ๋กœ ๋ณธ๋‹ค(๊ณต์œ  ์—์ง€ = ์ •์  ์ธ๋ฑ์Šค 2๊ฐœ ๊ณต์œ )"
117
- // (TriangleMesh.cpp:1505). ๊ทธ ์—ฐ๊ฒฐ ์„ฑ๋ถ„(patch)๋งˆ๋‹ค ๋…๋ฆฝ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋œ๋‹ค.
118
- // ์šฐ๋ฆฌ localPos ๋Š” ๋น„์ธ๋ฑ์Šค ์‚ผ๊ฐํ˜• ์ŠคํŠธ๋ฆผ(์ •์  9๊ฐœ/์‚ผ๊ฐํ˜•)์ด๋ผ, ๋จผ์ € ์ขŒํ‘œ๋ฅผ ์–‘์žํ™”ํ•ด ์ •์ ์„ ์šฉ์ ‘ํ•˜๊ณ 
119
- // ์—์ง€๋ฅผ ๋งŒ๋“  ๋’ค union-find ๋กœ ์„ฑ๋ถ„์„ ๋ชจ์€๋‹ค. ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์•„ ๋ฉ”๋ชจ๋ฆฌ/์‹œ๊ฐ„์ด ์„ ํ˜•์— ๊ฐ€๊น๋‹ค.
120
- //
121
- // ๋ฐ˜ํ™˜: ์„ฑ๋ถ„์ด 2๊ฐœ ์ด์ƒ์ด๋ฉด Float32Array[] (๊ฐ ์„ฑ๋ถ„์˜ localPos, ์ขŒํ‘œ๊ณ„๋Š” ์ž…๋ ฅ ๊ทธ๋Œ€๋กœ),
122
- // 1๊ฐœ๋ฉด null (๋ถ„๋ฆฌ ๋ถˆ๊ฐ€).
123
- export function splitConnectedComponents(localPos) {
124
- const nTri = Math.floor(localPos.length / 9)
125
- if (nTri < 2) return null
126
-
127
- // ์ •์  ์šฉ์ ‘: ๋ถ€๋™์†Œ์ˆ˜ ์˜ค์ฐจ๋กœ ๊ฐ™์€ ์ ์ด ๊ฐˆ๋ผ์ง€์ง€ ์•Š๋„๋ก 1e-4mm ๊ฒฉ์ž๋กœ ์–‘์žํ™”
128
- const Q = 1e4
129
- const vmap = new Map()
130
- const vidx = new Int32Array(nTri * 3)
131
- for (let t = 0; t < nTri; t++) {
132
- for (let k = 0; k < 3; k++) {
133
- const o = t * 9 + k * 3
134
- const key = `${Math.round(localPos[o] * Q)},${Math.round(localPos[o + 1] * Q)},${Math.round(localPos[o + 2] * Q)}`
135
- let id = vmap.get(key)
136
- if (id === undefined) { id = vmap.size; vmap.set(key, id) }
137
- vidx[t * 3 + k] = id
138
- }
139
- }
140
-
141
- // union-find
142
- const parent = new Int32Array(nTri)
143
- for (let i = 0; i < nTri; i++) parent[i] = i
144
- const find = (x) => { while (parent[x] !== x) { parent[x] = parent[parent[x]]; x = parent[x] } return x }
145
- const union = (a, b) => { a = find(a); b = find(b); if (a !== b) parent[b] = a }
146
-
147
- // ์—์ง€(์ •์ ์Œ) โ†’ ์ฒ˜์Œ ๋ณธ ๋ฉด. ๊ฐ™์€ ์—์ง€๋ฅผ ๋‹ค์‹œ ๋งŒ๋‚˜๋ฉด ๋‘ ๋ฉด์„ ํ•ฉ์นœ๋‹ค.
148
- // ์—์ง€๋‹น ๋ฉด์ด 3๊ฐœ ์ด์ƒ์ธ ๋น„-๋งค๋‹ˆํด๋“œ๋„ ์ฒซ ๋ฉด ๊ธฐ์ค€์œผ๋กœ ์ „๋ถ€ ์ด์–ด์ ธ ๋ฌธ์ œ์—†๋‹ค.
149
- const edge = new Map()
150
- for (let t = 0; t < nTri; t++) {
151
- for (let e = 0; e < 3; e++) {
152
- const a = vidx[t * 3 + e], b = vidx[t * 3 + (e + 1) % 3]
153
- const key = a < b ? a * 4294967296 + b : b * 4294967296 + a // ์ •์  ์ธ๋ฑ์Šค 2๊ฐœ๋ฅผ ํ•˜๋‚˜์˜ ์ˆ˜๋กœ
154
- const prev = edge.get(key)
155
- if (prev === undefined) edge.set(key, t)
156
- else union(t, prev)
157
- }
158
- }
159
-
160
- // ์„ฑ๋ถ„๋ณ„ ๋ฉด ์ˆ˜์ง‘
161
- const groups = new Map()
162
- for (let t = 0; t < nTri; t++) {
163
- const r = find(t)
164
- let g = groups.get(r)
165
- if (!g) { g = []; groups.set(r, g) }
166
- g.push(t)
167
- }
168
- if (groups.size < 2) return null
169
-
170
- // ํฐ ์„ฑ๋ถ„๋ถ€ํ„ฐ (์›๋ณธ๋„ ๋ถ€ํ”ผ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•ด ์ฒซ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋ณธ์ฒด๊ฐ€ ๋˜๊ฒŒ ํ•œ๋‹ค)
171
- const parts = [...groups.values()].sort((a, b) => b.length - a.length)
172
- return parts.map(faces => {
173
- const out = new Float32Array(faces.length * 9)
174
- let w = 0
175
- for (const t of faces) { const o = t * 9; for (let k = 0; k < 9; k++) out[w++] = localPos[o + k] }
176
- return out
177
- })
178
- }
@@ -1,30 +0,0 @@
1
- import React, { useLayoutEffect, useRef, useState } from 'react'
2
- import { createPortal } from 'react-dom'
3
-
4
- // Shadow DOM ๊ฒฉ๋ฆฌ ํ˜ธ์ŠคํŠธ โ€” ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ์„ shadow root ์— ์ฃผ์ž…ํ•ด ํ˜ธ์ŠคํŠธ ์•ฑ CSS ์™€
5
- // ์–‘๋ฐฉํ–ฅ ์™„์ „ ์ฐจ๋‹จํ•œ๋‹ค (ํด๋ž˜์Šค๋ช… ์ถฉ๋Œ ๋ถˆ๊ฐ€). React 17+ ๋Š” ํฌํ„ธ ์ปจํ…Œ์ด๋„ˆ์—๋„ ์ด๋ฒคํŠธ
6
- // ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ง์ ‘ ๋ถ™์ด๋ฏ€๋กœ(preparePortalMount) shadow ์•ˆ์—์„œ๋„ ํ•ฉ์„ฑ ์ด๋ฒคํŠธ๊ฐ€ ์ •์ƒ ๋™์ž‘.
7
- // ํ˜ธ์ŠคํŠธ div/์ปจํ…Œ์ด๋„ˆ๋Š” display:contents ๋กœ ๋ ˆ์ด์•„์›ƒ ํˆฌ๋ช… โ€” ์ž์‹์ด ์ข…์ „์ฒ˜๋Ÿผ ๋ฐฐ์น˜๋œ๋‹ค.
8
- //
9
- // ํฌํ„ธ ์ปจํ…Œ์ด๋„ˆ๋Š” ๋ Œ๋” ์ „์— ๋ฏธ๋ฆฌ ๋งŒ๋“ ๋‹ค. shadow root ์ƒ์„ฑ์„ ๊ธฐ๋‹ค๋ ธ๋‹ค ์กฐ๊ฑด๋ถ€๋กœ ํฌํ„ธ์„
10
- // ์—ด๋ฉด ์ž์‹ ref ๊ฐ€ ๋ถ™๊ธฐ ์ „์— ์ž์‹์˜ mount useEffect ๊ฐ€ ref=null ๋กœ ์†Œ์ง„๋œ๋‹ค
11
- // (three.js ์ดˆ๊ธฐํ™” ์˜๊ตฌ ๋ถˆ๋ฐœ). ์ฒซ ์ปค๋ฐ‹๋ถ€ํ„ฐ detached ์ปจํ…Œ์ด๋„ˆ์— ์ž์‹์„ ๋งˆ์šดํŠธํ•˜๊ณ ,
12
- // layout effect ์—์„œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ shadow root ๋กœ ์˜ฎ๊ธด๋‹ค โ€” paint ์ „์ด๋ผ ๊นœ๋นก์ž„ ์—†์Œ.
13
- // (document ๋ฅผ ๋ Œ๋” ์ค‘ ๋งŒ์ง€๋ฏ€๋กœ SSR ๋ถˆ๊ฐ€ โ€” Next ๋“ฑ์—์„œ๋Š” ssr:false ๋กœ ๋กœ๋“œํ•  ๊ฒƒ.)
14
- export default function ShadowHost({ css, className, children }) {
15
- const hostRef = useRef(null)
16
- const [container] = useState(() => {
17
- const el = document.createElement('div')
18
- el.style.display = 'contents'
19
- return el
20
- })
21
- useLayoutEffect(() => {
22
- const host = hostRef.current
23
- const shadow = host.shadowRoot || host.attachShadow({ mode: 'open' })
24
- let style = shadow.querySelector('style[data-ts-css]')
25
- if (!style) { style = document.createElement('style'); style.setAttribute('data-ts-css', ''); shadow.append(style) }
26
- style.textContent = css
27
- if (!shadow.contains(container)) shadow.append(container)
28
- }, [css, container])
29
- return <div ref={hostRef} className={className}>{createPortal(children, container)}</div>
30
- }