@operato/scene-storage 10.0.0-beta.48 → 10.0.0-beta.53

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 (78) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/box.js +2 -2
  3. package/dist/box.js.map +1 -1
  4. package/dist/index.d.ts +9 -0
  5. package/dist/index.js +6 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/pallet.js +2 -2
  8. package/dist/pallet.js.map +1 -1
  9. package/dist/parcel.js +2 -2
  10. package/dist/parcel.js.map +1 -1
  11. package/dist/picking-station-3d.d.ts +20 -0
  12. package/dist/picking-station-3d.js +162 -0
  13. package/dist/picking-station-3d.js.map +1 -0
  14. package/dist/picking-station.d.ts +50 -0
  15. package/dist/picking-station.js +186 -0
  16. package/dist/picking-station.js.map +1 -0
  17. package/dist/rack-capability.d.ts +11 -0
  18. package/dist/rack-capability.js +25 -0
  19. package/dist/rack-capability.js.map +1 -0
  20. package/dist/rack-grid.d.ts +4 -22
  21. package/dist/rack-grid.js +23 -115
  22. package/dist/rack-grid.js.map +1 -1
  23. package/dist/spot.d.ts +1 -0
  24. package/dist/spot.js +6 -2
  25. package/dist/spot.js.map +1 -1
  26. package/dist/stockpile-3d.d.ts +55 -0
  27. package/dist/stockpile-3d.js +387 -0
  28. package/dist/stockpile-3d.js.map +1 -0
  29. package/dist/stockpile-grid-3d.d.ts +30 -0
  30. package/dist/stockpile-grid-3d.js +301 -0
  31. package/dist/stockpile-grid-3d.js.map +1 -0
  32. package/dist/stockpile-grid.d.ts +85 -0
  33. package/dist/stockpile-grid.js +361 -0
  34. package/dist/stockpile-grid.js.map +1 -0
  35. package/dist/stockpile.d.ts +116 -0
  36. package/dist/stockpile.js +345 -0
  37. package/dist/stockpile.js.map +1 -0
  38. package/dist/storage-rack.d.ts +39 -44
  39. package/dist/storage-rack.js +71 -146
  40. package/dist/storage-rack.js.map +1 -1
  41. package/dist/templates/index.d.ts +80 -0
  42. package/dist/templates/index.js +7 -1
  43. package/dist/templates/index.js.map +1 -1
  44. package/dist/templates/picking-station.d.ts +20 -0
  45. package/dist/templates/picking-station.js +22 -0
  46. package/dist/templates/picking-station.js.map +1 -0
  47. package/dist/templates/stockpile-grid.d.ts +37 -0
  48. package/dist/templates/stockpile-grid.js +38 -0
  49. package/dist/templates/stockpile-grid.js.map +1 -0
  50. package/dist/templates/stockpile.d.ts +29 -0
  51. package/dist/templates/stockpile.js +31 -0
  52. package/dist/templates/stockpile.js.map +1 -0
  53. package/package.json +3 -3
  54. package/src/box.ts +2 -1
  55. package/src/index.ts +14 -0
  56. package/src/pallet.ts +2 -1
  57. package/src/parcel.ts +2 -1
  58. package/src/picking-station-3d.ts +164 -0
  59. package/src/picking-station.ts +220 -0
  60. package/src/rack-capability.ts +26 -0
  61. package/src/rack-grid.ts +24 -108
  62. package/src/spot.ts +15 -1
  63. package/src/stockpile-3d.ts +412 -0
  64. package/src/stockpile-grid-3d.ts +327 -0
  65. package/src/stockpile-grid.ts +408 -0
  66. package/src/stockpile.ts +427 -0
  67. package/src/storage-rack.ts +82 -137
  68. package/src/templates/index.ts +7 -1
  69. package/src/templates/picking-station.ts +23 -0
  70. package/src/templates/stockpile-grid.ts +39 -0
  71. package/src/templates/stockpile.ts +32 -0
  72. package/test/test-rack-capability.ts +51 -0
  73. package/translations/en.json +23 -6
  74. package/translations/ja.json +23 -6
  75. package/translations/ko.json +22 -5
  76. package/translations/ms.json +23 -6
  77. package/translations/zh.json +22 -5
  78. package/tsconfig.tsbuildinfo +1 -1
@@ -20,6 +20,86 @@ declare const _default: ({
20
20
  fontFamily: string;
21
21
  bold: boolean;
22
22
  };
23
+ } | {
24
+ type: string;
25
+ description: string;
26
+ group: string;
27
+ icon: string;
28
+ model: {
29
+ type: string;
30
+ top: number;
31
+ left: number;
32
+ width: number;
33
+ height: number;
34
+ depth: number;
35
+ rotation: number;
36
+ fillStyle: string;
37
+ strokeStyle: string;
38
+ stackPattern: string;
39
+ carrierPreset: string;
40
+ carrierWidth: number;
41
+ carrierHeight: number;
42
+ carrierDepth: number;
43
+ carrierGap: number;
44
+ capacity: number;
45
+ pickPolicy: string;
46
+ data: {
47
+ id: string;
48
+ }[];
49
+ };
50
+ } | {
51
+ type: string;
52
+ description: string;
53
+ group: string;
54
+ icon: string;
55
+ model: {
56
+ type: string;
57
+ top: number;
58
+ left: number;
59
+ width: number;
60
+ height: number;
61
+ depth: number;
62
+ rotation: number;
63
+ fillStyle: string;
64
+ strokeStyle: string;
65
+ cols: number;
66
+ rows: number;
67
+ cellWidth: number;
68
+ cellHeight: number;
69
+ stackPattern: string;
70
+ carrierPreset: string;
71
+ carrierWidth: number;
72
+ carrierHeight: number;
73
+ carrierDepth: number;
74
+ carrierGap: number;
75
+ capacity: number;
76
+ pickPolicy: string;
77
+ data: {
78
+ col: number;
79
+ row: number;
80
+ data: {
81
+ id: string;
82
+ }[];
83
+ }[];
84
+ };
85
+ } | {
86
+ type: string;
87
+ description: string;
88
+ group: string;
89
+ icon: string;
90
+ model: {
91
+ type: string;
92
+ top: number;
93
+ left: number;
94
+ width: number;
95
+ height: number;
96
+ depth: number;
97
+ rotation: number;
98
+ fillStyle: string;
99
+ strokeStyle: string;
100
+ processingTimeMs: number;
101
+ status: string;
102
+ };
23
103
  } | {
24
104
  type: string;
25
105
  description: string;
@@ -10,6 +10,9 @@
10
10
  * - spot — virtual placement marker
11
11
  */
12
12
  import spot from './spot.js';
13
+ import stockpile from './stockpile.js';
14
+ import stockpileGrid from './stockpile-grid.js';
15
+ import pickingStation from './picking-station.js';
13
16
  const pallet = new URL('../../icons/pallet.png', import.meta.url).href;
14
17
  const box = new URL('../../icons/box.png', import.meta.url).href;
15
18
  const parcel = new URL('../../icons/parcel.png', import.meta.url).href;
@@ -195,6 +198,9 @@ export default [
195
198
  ]
196
199
  }
197
200
  },
198
- spot
201
+ spot,
202
+ stockpile,
203
+ stockpileGrid,
204
+ pickingStation
199
205
  ];
200
206
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * things-scene catalog templates for the storage domain.\n *\n * Components:\n * - pallet / box / parcel — carriers\n * - rack — multi-level storage shelf (bays × levels)\n * - rack-table — bulk layout (rows × columns × shelves) helper\n * - crane — stacker picker (Mover + CarrierHolder + ContainerCapacity)\n * - mobile-rack — Mover(Rack), an AGV-mounted / cart-mounted moving rack\n * - spot — virtual placement marker\n */\nimport spot from './spot.js'\nconst pallet = new URL('../../icons/pallet.png', import.meta.url).href\nconst box = new URL('../../icons/box.png', import.meta.url).href\nconst parcel = new URL('../../icons/parcel.png', import.meta.url).href\nconst rack = new URL('../../icons/storage-rack.png', import.meta.url).href\nconst crane = new URL('../../icons/crane.png', import.meta.url).href\n\nexport default [\n {\n type: 'wood pallet',\n description: 'wood pallet (EUR / EPAL)',\n group: 'storage',\n icon: pallet,\n model: {\n type: 'pallet',\n top: 100,\n left: 100,\n width: 80,\n height: 80,\n material: 'wood'\n }\n },\n {\n type: 'plastic pallet',\n description: 'plastic pallet',\n group: 'storage',\n icon: pallet,\n model: {\n type: 'pallet',\n top: 100,\n left: 250,\n width: 80,\n height: 80,\n depth: 4,\n material: 'plastic'\n }\n },\n {\n type: 'wood box',\n description: 'wood crate',\n group: 'storage',\n icon: box,\n model: {\n type: 'box',\n top: 100,\n left: 400,\n width: 80,\n height: 80,\n material: 'wood'\n }\n },\n {\n type: 'plastic box',\n description: 'plastic tote',\n group: 'storage',\n icon: box,\n model: {\n type: 'box',\n top: 100,\n left: 520,\n width: 80,\n height: 80,\n depth: 60,\n material: 'plastic'\n }\n },\n {\n type: 'parcel',\n description: 'cardboard parcel',\n group: 'storage',\n icon: parcel,\n model: {\n type: 'parcel',\n top: 100,\n left: 640,\n width: 10,\n height: 10,\n depth: 10\n }\n },\n {\n type: 'storage-rack',\n description: 'storage rack — multi-level shelves',\n group: 'storage',\n icon: rack,\n model: {\n type: 'storage-rack',\n top: 300,\n left: 100,\n width: 800,\n height: 200,\n levels: 4,\n bays: 5\n }\n },\n {\n type: 'rack-grid',\n description: 'rack table — N×M rack layout + auto location IDs',\n group: 'storage',\n icon: rack,\n model: {\n type: 'rack-grid',\n top: 100,\n left: 100,\n width: 1200,\n height: 600,\n rows: 2,\n columns: 4,\n shelves: 4,\n zone: 'A',\n locPattern: '{z}{s}-{u}-{sh}',\n sectionDigits: 2,\n unitDigits: 2\n }\n },\n {\n type: 'crane',\n description: 'stacker crane — picker actor',\n group: 'storage',\n icon: crane,\n model: {\n type: 'crane',\n top: 550,\n left: 400,\n width: 100,\n height: 200,\n status: 'idle',\n carriageHeight: 100\n }\n },\n {\n type: 'mobile-storage-rack',\n description: 'mobile rack — Mover(Rack), AGV/cart-mounted',\n group: 'storage',\n icon: rack,\n model: {\n type: 'mobile-storage-rack',\n top: 300,\n left: 100,\n width: 400,\n height: 200,\n levels: 3,\n bays: 3\n }\n },\n {\n type: 'group',\n description: 'storage aisle — rack pair + crane',\n group: 'storage',\n icon: rack,\n model: {\n type: 'group',\n top: 100,\n left: 100,\n width: 840,\n height: 220,\n components: [\n {\n type: 'storage-rack',\n top: 100,\n left: 100,\n width: 800,\n height: 80,\n levels: 4,\n bays: 8\n },\n {\n type: 'crane',\n top: 140,\n left: 420,\n width: 60,\n height: 60,\n status: 'idle',\n carriageHeight: 0\n },\n {\n type: 'storage-rack',\n top: 320,\n left: 100,\n width: 800,\n height: 80,\n levels: 4,\n bays: 8\n }\n ]\n }\n },\n spot\n]\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * things-scene catalog templates for the storage domain.\n *\n * Components:\n * - pallet / box / parcel — carriers\n * - rack — multi-level storage shelf (bays × levels)\n * - rack-table — bulk layout (rows × columns × shelves) helper\n * - crane — stacker picker (Mover + CarrierHolder + ContainerCapacity)\n * - mobile-rack — Mover(Rack), an AGV-mounted / cart-mounted moving rack\n * - spot — virtual placement marker\n */\nimport spot from './spot.js'\nimport stockpile from './stockpile.js'\nimport stockpileGrid from './stockpile-grid.js'\nimport pickingStation from './picking-station.js'\nconst pallet = new URL('../../icons/pallet.png', import.meta.url).href\nconst box = new URL('../../icons/box.png', import.meta.url).href\nconst parcel = new URL('../../icons/parcel.png', import.meta.url).href\nconst rack = new URL('../../icons/storage-rack.png', import.meta.url).href\nconst crane = new URL('../../icons/crane.png', import.meta.url).href\n\nexport default [\n {\n type: 'wood pallet',\n description: 'wood pallet (EUR / EPAL)',\n group: 'storage',\n icon: pallet,\n model: {\n type: 'pallet',\n top: 100,\n left: 100,\n width: 80,\n height: 80,\n material: 'wood'\n }\n },\n {\n type: 'plastic pallet',\n description: 'plastic pallet',\n group: 'storage',\n icon: pallet,\n model: {\n type: 'pallet',\n top: 100,\n left: 250,\n width: 80,\n height: 80,\n depth: 4,\n material: 'plastic'\n }\n },\n {\n type: 'wood box',\n description: 'wood crate',\n group: 'storage',\n icon: box,\n model: {\n type: 'box',\n top: 100,\n left: 400,\n width: 80,\n height: 80,\n material: 'wood'\n }\n },\n {\n type: 'plastic box',\n description: 'plastic tote',\n group: 'storage',\n icon: box,\n model: {\n type: 'box',\n top: 100,\n left: 520,\n width: 80,\n height: 80,\n depth: 60,\n material: 'plastic'\n }\n },\n {\n type: 'parcel',\n description: 'cardboard parcel',\n group: 'storage',\n icon: parcel,\n model: {\n type: 'parcel',\n top: 100,\n left: 640,\n width: 10,\n height: 10,\n depth: 10\n }\n },\n {\n type: 'storage-rack',\n description: 'storage rack — multi-level shelves',\n group: 'storage',\n icon: rack,\n model: {\n type: 'storage-rack',\n top: 300,\n left: 100,\n width: 800,\n height: 200,\n levels: 4,\n bays: 5\n }\n },\n {\n type: 'rack-grid',\n description: 'rack table — N×M rack layout + auto location IDs',\n group: 'storage',\n icon: rack,\n model: {\n type: 'rack-grid',\n top: 100,\n left: 100,\n width: 1200,\n height: 600,\n rows: 2,\n columns: 4,\n shelves: 4,\n zone: 'A',\n locPattern: '{z}{s}-{u}-{sh}',\n sectionDigits: 2,\n unitDigits: 2\n }\n },\n {\n type: 'crane',\n description: 'stacker crane — picker actor',\n group: 'storage',\n icon: crane,\n model: {\n type: 'crane',\n top: 550,\n left: 400,\n width: 100,\n height: 200,\n status: 'idle',\n carriageHeight: 100\n }\n },\n {\n type: 'mobile-storage-rack',\n description: 'mobile rack — Mover(Rack), AGV/cart-mounted',\n group: 'storage',\n icon: rack,\n model: {\n type: 'mobile-storage-rack',\n top: 300,\n left: 100,\n width: 400,\n height: 200,\n levels: 3,\n bays: 3\n }\n },\n {\n type: 'group',\n description: 'storage aisle — rack pair + crane',\n group: 'storage',\n icon: rack,\n model: {\n type: 'group',\n top: 100,\n left: 100,\n width: 840,\n height: 220,\n components: [\n {\n type: 'storage-rack',\n top: 100,\n left: 100,\n width: 800,\n height: 80,\n levels: 4,\n bays: 8\n },\n {\n type: 'crane',\n top: 140,\n left: 420,\n width: 60,\n height: 60,\n status: 'idle',\n carriageHeight: 0\n },\n {\n type: 'storage-rack',\n top: 320,\n left: 100,\n width: 800,\n height: 80,\n levels: 4,\n bays: 8\n }\n ]\n }\n },\n spot,\n stockpile,\n stockpileGrid,\n pickingStation\n]\n"]}
@@ -0,0 +1,20 @@
1
+ declare const _default: {
2
+ type: string;
3
+ description: string;
4
+ group: string;
5
+ icon: string;
6
+ model: {
7
+ type: string;
8
+ top: number;
9
+ left: number;
10
+ width: number;
11
+ height: number;
12
+ depth: number;
13
+ rotation: number;
14
+ fillStyle: string;
15
+ strokeStyle: string;
16
+ processingTimeMs: number;
17
+ status: string;
18
+ };
19
+ };
20
+ export default _default;
@@ -0,0 +1,22 @@
1
+ // Reuse parcel.png as a placeholder icon until a dedicated picking-station icon is drawn.
2
+ const icon = new URL('../../icons/parcel.png', import.meta.url).href;
3
+ export default {
4
+ type: 'picking-station',
5
+ description: 'work station — carrier stays for processingTimeMs then becomes idle. anchors AMR↔human handoff',
6
+ group: 'storage',
7
+ icon,
8
+ model: {
9
+ type: 'picking-station',
10
+ top: 200,
11
+ left: 400,
12
+ width: 120,
13
+ height: 100,
14
+ depth: 60,
15
+ rotation: 0,
16
+ fillStyle: '#5a8ab8',
17
+ strokeStyle: '#3d6a8f',
18
+ processingTimeMs: 3000,
19
+ status: 'idle'
20
+ }
21
+ };
22
+ //# sourceMappingURL=picking-station.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picking-station.js","sourceRoot":"","sources":["../../src/templates/picking-station.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAEpE,eAAe;IACb,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT,gGAAgG;IAClG,KAAK,EAAE,SAAS;IAChB,IAAI;IACJ,KAAK,EAAE;QACL,IAAI,EAAE,iBAAiB;QACvB,GAAG,EAAE,GAAG;QACR,IAAI,EAAE,GAAG;QACT,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;QACX,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,CAAC;QACX,SAAS,EAAE,SAAS;QACpB,WAAW,EAAE,SAAS;QACtB,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE,MAAM;KACf;CACF,CAAA","sourcesContent":["// Reuse parcel.png as a placeholder icon until a dedicated picking-station icon is drawn.\nconst icon = new URL('../../icons/parcel.png', import.meta.url).href\n\nexport default {\n type: 'picking-station',\n description:\n 'work station — carrier stays for processingTimeMs then becomes idle. anchors AMR↔human handoff',\n group: 'storage',\n icon,\n model: {\n type: 'picking-station',\n top: 200,\n left: 400,\n width: 120,\n height: 100,\n depth: 60,\n rotation: 0,\n fillStyle: '#5a8ab8',\n strokeStyle: '#3d6a8f',\n processingTimeMs: 3000,\n status: 'idle'\n }\n}\n"]}
@@ -0,0 +1,37 @@
1
+ declare const _default: {
2
+ type: string;
3
+ description: string;
4
+ group: string;
5
+ icon: string;
6
+ model: {
7
+ type: string;
8
+ top: number;
9
+ left: number;
10
+ width: number;
11
+ height: number;
12
+ depth: number;
13
+ rotation: number;
14
+ fillStyle: string;
15
+ strokeStyle: string;
16
+ cols: number;
17
+ rows: number;
18
+ cellWidth: number;
19
+ cellHeight: number;
20
+ stackPattern: string;
21
+ carrierPreset: string;
22
+ carrierWidth: number;
23
+ carrierHeight: number;
24
+ carrierDepth: number;
25
+ carrierGap: number;
26
+ capacity: number;
27
+ pickPolicy: string;
28
+ data: {
29
+ col: number;
30
+ row: number;
31
+ data: {
32
+ id: string;
33
+ }[];
34
+ }[];
35
+ };
36
+ };
37
+ export default _default;
@@ -0,0 +1,38 @@
1
+ // Reuse parcel.png as a placeholder icon until a dedicated stockpile-grid icon is drawn.
2
+ const icon = new URL('../../icons/parcel.png', import.meta.url).href;
3
+ export default {
4
+ type: 'stockpile-grid',
5
+ description: 'grid of block/floor storage cells — each cell is a stockpile with its own records, capacity, and preset override',
6
+ group: 'storage',
7
+ icon,
8
+ model: {
9
+ type: 'stockpile-grid',
10
+ top: 200,
11
+ left: 400,
12
+ width: 300,
13
+ height: 200,
14
+ depth: 5,
15
+ rotation: 0,
16
+ fillStyle: '#c89c5c',
17
+ strokeStyle: '#7a5a2e',
18
+ cols: 3,
19
+ rows: 2,
20
+ cellWidth: 100,
21
+ cellHeight: 100,
22
+ stackPattern: 'row',
23
+ carrierPreset: 'box',
24
+ carrierWidth: 30,
25
+ carrierHeight: 30,
26
+ carrierDepth: 22,
27
+ carrierGap: 10,
28
+ capacity: 20,
29
+ pickPolicy: 'lifo',
30
+ // 데모 — 일부 cell 에 records 미리 채워서 끌어 놓자 마자 적치 보이게.
31
+ data: [
32
+ { col: 0, row: 0, data: [{ id: 'a1' }, { id: 'a2' }] },
33
+ { col: 1, row: 0, data: [{ id: 'b1' }, { id: 'b2' }, { id: 'b3' }] },
34
+ { col: 2, row: 1, data: [{ id: 'c1' }] }
35
+ ]
36
+ }
37
+ };
38
+ //# sourceMappingURL=stockpile-grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stockpile-grid.js","sourceRoot":"","sources":["../../src/templates/stockpile-grid.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAEpE,eAAe;IACb,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,kHAAkH;IACpH,KAAK,EAAE,SAAS;IAChB,IAAI;IACJ,KAAK,EAAE;QACL,IAAI,EAAE,gBAAgB;QACtB,GAAG,EAAE,GAAG;QACR,IAAI,EAAE,GAAG;QACT,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;QACX,KAAK,EAAE,CAAC;QACR,QAAQ,EAAE,CAAC;QACX,SAAS,EAAE,SAAS;QACpB,WAAW,EAAE,SAAS;QACtB,IAAI,EAAE,CAAC;QACP,IAAI,EAAE,CAAC;QACP,SAAS,EAAE,GAAG;QACd,UAAU,EAAE,GAAG;QACf,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,EAAE;QAChB,aAAa,EAAE,EAAE;QACjB,YAAY,EAAE,EAAE;QAChB,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,MAAM;QAClB,iDAAiD;QACjD,IAAI,EAAE;YACJ,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;YACtD,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;YACpE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;SACzC;KACF;CACF,CAAA","sourcesContent":["// Reuse parcel.png as a placeholder icon until a dedicated stockpile-grid icon is drawn.\nconst icon = new URL('../../icons/parcel.png', import.meta.url).href\n\nexport default {\n type: 'stockpile-grid',\n description:\n 'grid of block/floor storage cells — each cell is a stockpile with its own records, capacity, and preset override',\n group: 'storage',\n icon,\n model: {\n type: 'stockpile-grid',\n top: 200,\n left: 400,\n width: 300,\n height: 200,\n depth: 5,\n rotation: 0,\n fillStyle: '#c89c5c',\n strokeStyle: '#7a5a2e',\n cols: 3,\n rows: 2,\n cellWidth: 100,\n cellHeight: 100,\n stackPattern: 'row',\n carrierPreset: 'box',\n carrierWidth: 30,\n carrierHeight: 30,\n carrierDepth: 22,\n carrierGap: 10,\n capacity: 20,\n pickPolicy: 'lifo',\n // 데모 — 일부 cell 에 records 미리 채워서 끌어 놓자 마자 적치 보이게.\n data: [\n { col: 0, row: 0, data: [{ id: 'a1' }, { id: 'a2' }] },\n { col: 1, row: 0, data: [{ id: 'b1' }, { id: 'b2' }, { id: 'b3' }] },\n { col: 2, row: 1, data: [{ id: 'c1' }] }\n ]\n }\n}\n"]}
@@ -0,0 +1,29 @@
1
+ declare const _default: {
2
+ type: string;
3
+ description: string;
4
+ group: string;
5
+ icon: string;
6
+ model: {
7
+ type: string;
8
+ top: number;
9
+ left: number;
10
+ width: number;
11
+ height: number;
12
+ depth: number;
13
+ rotation: number;
14
+ fillStyle: string;
15
+ strokeStyle: string;
16
+ stackPattern: string;
17
+ carrierPreset: string;
18
+ carrierWidth: number;
19
+ carrierHeight: number;
20
+ carrierDepth: number;
21
+ carrierGap: number;
22
+ capacity: number;
23
+ pickPolicy: string;
24
+ data: {
25
+ id: string;
26
+ }[];
27
+ };
28
+ };
29
+ export default _default;
@@ -0,0 +1,31 @@
1
+ // Reuse parcel.png as a placeholder icon until a dedicated stockpile icon is drawn.
2
+ const icon = new URL('../../icons/parcel.png', import.meta.url).href;
3
+ export default {
4
+ type: 'stockpile',
5
+ description: 'block/floor storage — rectangular footprint with auto-stacked virtual carriers (stackPattern × carrierPreset) driven by state.data records',
6
+ group: 'storage' /* line|shape|textAndMedia|chartAndGauge|table|container|dataSource|3D|facility|storage|conveyance|transport|manufacturing|form|etc */,
7
+ icon,
8
+ model: {
9
+ type: 'stockpile',
10
+ top: 200,
11
+ left: 400,
12
+ width: 200,
13
+ height: 150,
14
+ depth: 5,
15
+ rotation: 0,
16
+ fillStyle: '#c89c5c',
17
+ // 바닥 페인트 라인 의도 — fillStyle 보다 진한 색으로 영역 마킹이 눈에 띄게.
18
+ strokeStyle: '#7a5a2e',
19
+ stackPattern: 'row',
20
+ carrierPreset: 'box',
21
+ carrierWidth: 30,
22
+ carrierHeight: 30,
23
+ carrierDepth: 22,
24
+ carrierGap: 10,
25
+ capacity: 30,
26
+ pickPolicy: 'lifo',
27
+ // 데모용 — 새로 끌어다 놓았을 때 적치된 모습이 즉시 보이도록 record 몇 개.
28
+ data: [{ id: 'p-1' }, { id: 'p-2' }, { id: 'p-3' }]
29
+ }
30
+ };
31
+ //# sourceMappingURL=stockpile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stockpile.js","sourceRoot":"","sources":["../../src/templates/stockpile.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAEpE,eAAe;IACb,IAAI,EAAE,WAAW;IACjB,WAAW,EACT,4IAA4I;IAC9I,KAAK,EAAE,SAAS,CAAC,sIAAsI;IACvJ,IAAI;IACJ,KAAK,EAAE;QACL,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,GAAG;QACR,IAAI,EAAE,GAAG;QACT,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;QACX,KAAK,EAAE,CAAC;QACR,QAAQ,EAAE,CAAC;QACX,SAAS,EAAE,SAAS;QACpB,mDAAmD;QACnD,WAAW,EAAE,SAAS;QACtB,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,EAAE;QAChB,aAAa,EAAE,EAAE;QACjB,YAAY,EAAE,EAAE;QAChB,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,MAAM;QAClB,iDAAiD;QACjD,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;KACpD;CACF,CAAA","sourcesContent":["// Reuse parcel.png as a placeholder icon until a dedicated stockpile icon is drawn.\nconst icon = new URL('../../icons/parcel.png', import.meta.url).href\n\nexport default {\n type: 'stockpile',\n description:\n 'block/floor storage — rectangular footprint with auto-stacked virtual carriers (stackPattern × carrierPreset) driven by state.data records',\n group: 'storage' /* line|shape|textAndMedia|chartAndGauge|table|container|dataSource|3D|facility|storage|conveyance|transport|manufacturing|form|etc */,\n icon,\n model: {\n type: 'stockpile',\n top: 200,\n left: 400,\n width: 200,\n height: 150,\n depth: 5,\n rotation: 0,\n fillStyle: '#c89c5c',\n // 바닥 페인트 라인 의도 — fillStyle 보다 진한 색으로 영역 마킹이 눈에 띄게.\n strokeStyle: '#7a5a2e',\n stackPattern: 'row',\n carrierPreset: 'box',\n carrierWidth: 30,\n carrierHeight: 30,\n carrierDepth: 22,\n carrierGap: 10,\n capacity: 30,\n pickPolicy: 'lifo',\n // 데모용 — 새로 끌어다 놓았을 때 적치된 모습이 즉시 보이도록 record 몇 개.\n data: [{ id: 'p-1' }, { id: 'p-2' }, { id: 'p-3' }]\n }\n}\n"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/scene-storage",
3
3
  "description": "Storage-domain components for things-scene (smart factory / logistics) — pallet, box, parcel; AS/RS and shelves planned.",
4
4
  "author": "heartyoh",
5
- "version": "10.0.0-beta.48",
5
+ "version": "10.0.0-beta.53",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@hatiolab/things-scene": "^10.0.0-beta.1",
29
- "@operato/scene-base": "^10.0.0-beta.48",
29
+ "@operato/scene-base": "^10.0.0-beta.53",
30
30
  "three": "^0.183.0"
31
31
  },
32
32
  "devDependencies": {
@@ -45,5 +45,5 @@
45
45
  "typescript": "^5.0.4"
46
46
  },
47
47
  "prettier": "@hatiolab/prettier-config",
48
- "gitHead": "ebda54409e9c089f6e7662ee6b447b5de9a9ecb3"
48
+ "gitHead": "ce61d4ad1beee04ac4078e478d88fe55820b600f"
49
49
  }
package/src/box.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  import type { State, Material3D, PickupFrame, PoseSerialized } from '@hatiolab/things-scene'
14
14
  import {
15
15
  Carriable,
16
+ Identifiable,
16
17
  Legendable,
17
18
  Placeable,
18
19
  type Alignment,
@@ -81,7 +82,7 @@ const NATURE: ComponentNature = {
81
82
  * scene-tree). If a future use case needs nested boxes, extend Container.
82
83
  */
83
84
  @sceneComponent('box')
84
- export default class Box extends Carriable(Legendable(Placeable(RectPath(Shape)))) {
85
+ export default class Box extends Identifiable(Carriable(Legendable(Placeable(RectPath(Shape))))) {
85
86
  declare state: BoxState
86
87
 
87
88
  static legends: Record<string, LegendBinding> = {
package/src/index.ts CHANGED
@@ -25,6 +25,20 @@ export { Crane3D } from './crane-3d.js'
25
25
  export { default as Spot } from './spot.js'
26
26
  export { Spot3D } from './spot-3d.js'
27
27
 
28
+ export { default as Stockpile } from './stockpile.js'
29
+ export type {
30
+ StockpileState, StockpileRecord, StackPattern, CarrierPreset, PickPolicy
31
+ } from './stockpile.js'
32
+ export { Stockpile3D } from './stockpile-3d.js'
33
+
34
+ export { default as StockpileGrid } from './stockpile-grid.js'
35
+ export type { StockpileGridState, StockpileGridCell } from './stockpile-grid.js'
36
+ export { StockpileGrid3D } from './stockpile-grid-3d.js'
37
+
38
+ export { default as PickingStation } from './picking-station.js'
39
+ export type { PickingStationState, PickingStationStatus } from './picking-station.js'
40
+ export { PickingStation3D } from './picking-station-3d.js'
41
+
28
42
  export { default as GenericContainer } from './generic-container.js'
29
43
  export type { ContainerStatus } from './generic-container.js'
30
44
  export { GenericContainer3D } from './generic-container-3d.js'
package/src/pallet.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  import type { State, Material3D, PickupFrame, PoseSerialized } from '@hatiolab/things-scene'
16
16
  import {
17
17
  Carriable,
18
+ Identifiable,
18
19
  Legendable,
19
20
  Placeable,
20
21
  type Alignment,
@@ -122,7 +123,7 @@ const NATURE: ComponentNature = {
122
123
  * detection.
123
124
  */
124
125
  @sceneComponent('pallet')
125
- export default class Pallet extends Carriable(Legendable(Placeable(ContainerAbstract))) {
126
+ export default class Pallet extends Identifiable(Carriable(Legendable(Placeable(ContainerAbstract)))) {
126
127
  declare state: PalletState
127
128
 
128
129
  static legends: Record<string, LegendBinding> = {
package/src/parcel.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  import type { State, Material3D, PickupFrame, PoseSerialized } from '@hatiolab/things-scene'
14
14
  import {
15
15
  Carriable,
16
+ Identifiable,
16
17
  Placeable,
17
18
  type Alignment,
18
19
  type PlacementArchetype
@@ -62,7 +63,7 @@ const NATURE: ComponentNature = {
62
63
  * inspected indicators would add a status legend then.
63
64
  */
64
65
  @sceneComponent('parcel')
65
- export default class Parcel extends Carriable(Placeable(RectPath(Shape))) {
66
+ export default class Parcel extends Identifiable(Carriable(Placeable(RectPath(Shape)))) {
66
67
  declare state: ParcelState
67
68
 
68
69
  static placement: PlacementArchetype = 'operation'
@@ -0,0 +1,164 @@
1
+ /*
2
+ * Copyright © HatioLab Inc. All rights reserved.
3
+ *
4
+ * PickingStation3D — 사람 작업 위치의 3D 시각화. pad(영역) + 작업대(가운데 box, top
5
+ * face 가 carrier 안착면). status 별 색 변화 (idle/processing/busy) 로 작업 진행
6
+ * 인지성.
7
+ */
8
+
9
+ import * as THREE from 'three'
10
+ import { RealObjectGroup } from '@hatiolab/things-scene'
11
+
12
+ import type PickingStation from './picking-station.js'
13
+ import type { PickingStationStatus } from './picking-station.js'
14
+
15
+ const PAD_DEPTH = 2
16
+
17
+ const STATUS_TINT: Record<PickingStationStatus, number> = {
18
+ idle: 0x4a7a9b, // 차분한 blue-grey
19
+ processing: 0xd9943a, // 작업 중 — 주황
20
+ busy: 0xc04040 // busy/blocked — 빨강
21
+ }
22
+
23
+ export class PickingStation3D extends RealObjectGroup {
24
+ private _padMesh?: THREE.Mesh
25
+ private _padOutline?: THREE.LineSegments
26
+ private _tableMesh?: THREE.Mesh
27
+
28
+ build() {
29
+ super.build()
30
+ const state = this.component.state as any
31
+ const w = state.width ?? 100
32
+ const h = state.height ?? 100
33
+ const depth = state.depth ?? 5
34
+
35
+ // ── pad (영역) ─────────────────────────────────────────────
36
+ const padGeom = new THREE.BoxGeometry(w, PAD_DEPTH, h)
37
+ const padMat = new THREE.MeshStandardMaterial({
38
+ color: this._padColor(), roughness: 0.85, transparent: true, opacity: 0.5
39
+ })
40
+ this._padMesh = new THREE.Mesh(padGeom, padMat)
41
+ this._padMesh.position.y = PAD_DEPTH / 2
42
+ this._padMesh.receiveShadow = true
43
+ this.object3d.add(this._padMesh)
44
+
45
+ // pad outline
46
+ const outline = new THREE.LineBasicMaterial({ color: this._strokeColor() })
47
+ this._padOutline = new THREE.LineSegments(new THREE.EdgesGeometry(padGeom), outline)
48
+ this._padOutline.position.y = PAD_DEPTH / 2
49
+ this.object3d.add(this._padOutline)
50
+
51
+ // ── 작업대 (table) — pad 위 가운데 box. top face = carrier 안착면. ──
52
+ const tableW = w * 0.55
53
+ const tableH = h * 0.45
54
+ const tableD = Math.max(8, depth) // 작업면 높이 — operation height 근사
55
+ const tableGeom = new THREE.BoxGeometry(tableW, tableD, tableH)
56
+ const tableMat = new THREE.MeshStandardMaterial({
57
+ color: this._statusColor(), roughness: 0.6, metalness: 0.1
58
+ })
59
+ this._tableMesh = new THREE.Mesh(tableGeom, tableMat)
60
+ this._tableMesh.position.y = PAD_DEPTH + tableD / 2
61
+ this._tableMesh.castShadow = true
62
+ this._tableMesh.receiveShadow = true
63
+ this.object3d.add(this._tableMesh)
64
+ }
65
+
66
+ /** carrier 안착 anchor — 작업대 top face. */
67
+ getAttachFrame(): THREE.Object3D | undefined {
68
+ return this._tableMesh ?? this._padMesh
69
+ }
70
+
71
+ private _padColor(): THREE.Color {
72
+ const raw = (this.component.state as any)?.fillStyle
73
+ if (typeof raw === 'string' && raw.length > 0) {
74
+ try { return new THREE.Color(raw) } catch { /* fallthrough */ }
75
+ }
76
+ return new THREE.Color(0x5a8ab8)
77
+ }
78
+
79
+ private _strokeColor(): THREE.Color {
80
+ const raw = (this.component.state as any)?.strokeStyle
81
+ if (typeof raw === 'string' && raw.length > 0) {
82
+ try { return new THREE.Color(raw) } catch { /* fallthrough */ }
83
+ }
84
+ return this._padColor().clone().multiplyScalar(0.6)
85
+ }
86
+
87
+ /** status 에 따른 작업대 색 — idle/processing/busy. */
88
+ private _statusColor(): THREE.Color {
89
+ const s = (this.component.state as any)?.status as PickingStationStatus | undefined
90
+ return new THREE.Color(STATUS_TINT[s ?? 'idle'] ?? STATUS_TINT.idle)
91
+ }
92
+
93
+ private _applyPadColor(): void {
94
+ if (this._padMesh) {
95
+ const m = this._padMesh.material as THREE.MeshStandardMaterial
96
+ m.color.copy(this._padColor())
97
+ m.needsUpdate = true
98
+ }
99
+ }
100
+ private _applyStrokeColor(): void {
101
+ if (this._padOutline) {
102
+ const m = this._padOutline.material as THREE.LineBasicMaterial
103
+ m.color.copy(this._strokeColor())
104
+ m.needsUpdate = true
105
+ }
106
+ }
107
+ private _applyStatusColor(): void {
108
+ if (this._tableMesh) {
109
+ const m = this._tableMesh.material as THREE.MeshStandardMaterial
110
+ m.color.copy(this._statusColor())
111
+ m.needsUpdate = true
112
+ }
113
+ }
114
+
115
+ updateAlpha(): void {
116
+ const alpha = typeof (this.component.state as any).alpha === 'number'
117
+ ? (this.component.state as any).alpha : 1
118
+ if (this._padMesh) {
119
+ const m = this._padMesh.material as THREE.MeshStandardMaterial
120
+ m.opacity = 0.5 * alpha
121
+ m.transparent = m.opacity < 1
122
+ m.needsUpdate = true
123
+ }
124
+ }
125
+
126
+ updateDimension(): void {
127
+ if (this._padMesh) {
128
+ const state = this.component.state as any
129
+ const w = state.width ?? 100
130
+ const h = state.height ?? 100
131
+ const depth = state.depth ?? 5
132
+ this._padMesh.geometry.dispose()
133
+ this._padMesh.geometry = new THREE.BoxGeometry(w, PAD_DEPTH, h)
134
+ if (this._padOutline) {
135
+ this._padOutline.geometry.dispose()
136
+ this._padOutline.geometry = new THREE.EdgesGeometry(this._padMesh.geometry)
137
+ }
138
+ if (this._tableMesh) {
139
+ const tableW = w * 0.55
140
+ const tableH = h * 0.45
141
+ const tableD = Math.max(8, depth)
142
+ this._tableMesh.geometry.dispose()
143
+ this._tableMesh.geometry = new THREE.BoxGeometry(tableW, tableD, tableH)
144
+ this._tableMesh.position.y = PAD_DEPTH + tableD / 2
145
+ }
146
+ }
147
+ }
148
+
149
+ onchange(after: Record<string, unknown>, before: Record<string, unknown>): void {
150
+ if ('width' in after || 'height' in after || 'depth' in after) {
151
+ this.updateDimension()
152
+ return
153
+ }
154
+ if ('alpha' in after) { this.updateAlpha(); return }
155
+ if ('fillStyle' in after) {
156
+ this._applyPadColor()
157
+ if ((this.component.state as any).strokeStyle == null) this._applyStrokeColor()
158
+ return
159
+ }
160
+ if ('strokeStyle' in after) { this._applyStrokeColor(); return }
161
+ if ('status' in after) { this._applyStatusColor(); return }
162
+ super.onchange?.(after, before)
163
+ }
164
+ }