@fmsim/machine 3.0.0-beta.3 → 3.0.0-beta.5

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 (94) hide show
  1. package/dist/agv-line.js +2 -2
  2. package/dist/agv-line.js.map +1 -1
  3. package/dist/agv.js +6 -2
  4. package/dist/agv.js.map +1 -1
  5. package/dist/buffer.js +2 -2
  6. package/dist/buffer.js.map +1 -1
  7. package/dist/conveyor-join.js +2 -2
  8. package/dist/conveyor-join.js.map +1 -1
  9. package/dist/conveyor.js +2 -2
  10. package/dist/conveyor.js.map +1 -1
  11. package/dist/crane.js +2 -2
  12. package/dist/crane.js.map +1 -1
  13. package/dist/equipment.js +2 -2
  14. package/dist/equipment.js.map +1 -1
  15. package/dist/factories/conveyor-3d.js +2 -2
  16. package/dist/factories/conveyor-3d.js.map +1 -1
  17. package/dist/factories/machine-3d.js +12 -12
  18. package/dist/factories/machine-3d.js.map +1 -1
  19. package/dist/factories/oht-3d.js +3 -4
  20. package/dist/factories/oht-3d.js.map +1 -1
  21. package/dist/features/legend-panel.js +29 -0
  22. package/dist/features/legend-panel.js.map +1 -0
  23. package/dist/features/legend-rows.js +88 -0
  24. package/dist/features/legend-rows.js.map +1 -0
  25. package/dist/features/lv-figures.js +137 -0
  26. package/dist/features/lv-figures.js.map +1 -0
  27. package/dist/features/lv-heights.js +20 -0
  28. package/dist/features/lv-heights.js.map +1 -0
  29. package/dist/features/mcs-status-default.js +3 -49
  30. package/dist/features/mcs-status-default.js.map +1 -1
  31. package/dist/features/oht-rail.js +32 -0
  32. package/dist/features/oht-rail.js.map +1 -0
  33. package/dist/features/vehicle-travel.js +90 -0
  34. package/dist/features/vehicle-travel.js.map +1 -0
  35. package/dist/index.js +4 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/mcs-carrier-holder.js +19 -25
  38. package/dist/mcs-carrier-holder.js.map +1 -1
  39. package/dist/mcs-machine.js +10 -1
  40. package/dist/mcs-machine.js.map +1 -1
  41. package/dist/mcs-unit.js +10 -1
  42. package/dist/mcs-unit.js.map +1 -1
  43. package/dist/mcs-vehicle.js +2 -60
  44. package/dist/mcs-vehicle.js.map +1 -1
  45. package/dist/oht-line.js +7 -3
  46. package/dist/oht-line.js.map +1 -1
  47. package/dist/oht.js +2 -2
  48. package/dist/oht.js.map +1 -1
  49. package/dist/port.js +2 -2
  50. package/dist/port.js.map +1 -1
  51. package/dist/scene/root-container-override.js +15 -210
  52. package/dist/scene/root-container-override.js.map +1 -1
  53. package/dist/shelf.js +2 -2
  54. package/dist/shelf.js.map +1 -1
  55. package/dist/shuttle.js +2 -2
  56. package/dist/shuttle.js.map +1 -1
  57. package/dist/stocker.js +2 -2
  58. package/dist/stocker.js.map +1 -1
  59. package/dist/tsconfig.tsbuildinfo +1 -1
  60. package/package.json +5 -4
  61. package/src/agv-line.ts +2 -2
  62. package/src/agv.ts +7 -2
  63. package/src/buffer.ts +2 -2
  64. package/src/conveyor-join.ts +2 -2
  65. package/src/conveyor.ts +2 -2
  66. package/src/crane.ts +2 -2
  67. package/src/equipment.ts +2 -2
  68. package/src/factories/conveyor-3d.ts +2 -2
  69. package/src/factories/machine-3d.ts +11 -12
  70. package/src/factories/oht-3d.ts +3 -5
  71. package/src/features/legend-panel.ts +31 -0
  72. package/src/features/legend-rows.ts +86 -0
  73. package/src/features/lv-figures.ts +144 -0
  74. package/src/features/lv-heights.ts +22 -0
  75. package/src/features/mcs-status-default.ts +3 -53
  76. package/src/features/oht-rail.ts +31 -0
  77. package/src/features/vehicle-travel.ts +97 -0
  78. package/src/index.ts +4 -0
  79. package/src/mcs-carrier-holder.ts +17 -26
  80. package/src/mcs-machine.ts +12 -1
  81. package/src/mcs-unit.ts +12 -1
  82. package/src/mcs-vehicle.ts +3 -71
  83. package/src/oht-line.ts +7 -3
  84. package/src/oht.ts +2 -2
  85. package/src/port.ts +2 -2
  86. package/src/scene/root-container-override.ts +15 -207
  87. package/src/shelf.ts +2 -2
  88. package/src/shuttle.ts +2 -2
  89. package/src/stocker.ts +2 -2
  90. package/translations/en.json +7 -1
  91. package/translations/ja.json +7 -1
  92. package/translations/ko.json +7 -1
  93. package/translations/ms.json +7 -1
  94. package/translations/zh.json +7 -1
@@ -12,14 +12,12 @@ import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUti
12
12
  import { RealObjectGroup, registerRealObjectFactory, disposeObject3D, MaterialBank } from '@hatiolab/things-scene';
13
13
  import { LEGEND_CAPACITY, legendColor, legendRangeEntryOf, resolveCarrierLegend } from '../features/mcs-status-default';
14
14
  import { fitGaugeScale } from '../utils/fit-gauge-scale';
15
+ import { railTopOf } from '../features/oht-rail';
16
+ import { MACHINE_HEIGHTS, MACHINE_OPACITY, TRANSPORT_SURFACE_HEIGHT } from '../features/lv-heights';
15
17
  import { carrierSegmentsFromData, abnormalSegmentsFromData, carrierColorsFromLegend, ABNORMAL_COLORS } from '../utils/stocker-gauge';
16
18
  import { Z_FMSIM } from './z-priority';
17
- /**
18
- * 포트 기본 높이 (절대값).
19
- * 모든 이송장치의 상단 높이 = 이 값.
20
- * 캐리어가 이송장치 간 높이 차 없이 이동할 수 있는 기준 높이.
21
- */
22
- export const TRANSPORT_SURFACE_HEIGHT = 30;
19
+ /* 포트 기본 높이와 설비 타입별 높이는 한 곳(features/lv-heights) — 피규어 fmsim.Machine 도 같은 표를 읽는다 */
20
+ export { TRANSPORT_SURFACE_HEIGHT } from '../features/lv-heights';
23
21
  const DEFAULTS = {
24
22
  depthRatio: 0.5,
25
23
  opacity: 1.0,
@@ -388,16 +386,16 @@ function register(type, overrides = {}) {
388
386
  // Machine (인프라 설비) — 높은 depth, 컨테이너는 반투명
389
387
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
390
388
  register('Equipment', {
391
- defaultDepth: 3 * TRANSPORT_SURFACE_HEIGHT,
392
- opacity: 0.75,
389
+ defaultDepth: MACHINE_HEIGHTS.equipment,
390
+ opacity: MACHINE_OPACITY.equipment,
393
391
  metalness: 0.4,
394
392
  roughness: 0.6,
395
393
  defaultColor: 0x8899aa,
396
394
  zPriority: Z_FMSIM.EQUIPMENT,
397
395
  });
398
396
  register('Buffer', {
399
- defaultDepth: TRANSPORT_SURFACE_HEIGHT,
400
- opacity: 1.0,
397
+ defaultDepth: MACHINE_HEIGHTS.buffer,
398
+ opacity: MACHINE_OPACITY.buffer,
401
399
  metalness: 0.3,
402
400
  roughness: 0.7,
403
401
  defaultColor: 0x99aa88,
@@ -416,11 +414,11 @@ register('AGVLine', {
416
414
  // OHTLine — 천장 I-beam 레일
417
415
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
418
416
  const OHT_LINE_RAIL_COLOR = 0xcccccc;
419
- const OHT_LINE_HEIGHT = 7 * TRANSPORT_SURFACE_HEIGHT; // OHT 상단과 일치
420
417
  class OHTLineRealObject3D extends RealObjectGroup {
421
418
  get zPriority() { return Z_FMSIM.OHT_LINE; }
422
419
  get effectiveDepth() { return 0; }
423
- get syncZPosOffset() { return OHT_LINE_HEIGHT; }
420
+ /** 레일 윗면 = 작업환경 천장 − 라인의 매달림 길이(railHang). OHT 상단이 여기에 매달린다 */
421
+ get syncZPosOffset() { return railTopOf(this.component); }
424
422
  build() {
425
423
  super.build();
426
424
  const { width = 10, height = 10 } = this.component.state;
@@ -484,6 +482,8 @@ class OHTLineRealObject3D extends RealObjectGroup {
484
482
  this.update();
485
483
  return;
486
484
  }
485
+ if ('railHang' in after)
486
+ this.updateTransform();
487
487
  super.onchange(after, before);
488
488
  }
489
489
  // updateAlpha override 제거 — 코어 RealObject.updateAlpha(=applyMaterialOpacity)로 수렴(faint).
@@ -1 +1 @@
1
- {"version":3,"file":"machine-3d.js","sourceRoot":"","sources":["../../src/factories/machine-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCS 설비 컴포넌트 3D 팩토리\n *\n * 10,000+ 인스턴스를 위한 최소 폴리곤 설계:\n * - 컴포넌트당 단일 Mesh (draw call 최소화)\n * - BoxGeometry / ExtrudeGeometry(hexagon) 만 사용\n * - Machine: 높은 depth, 컨테이너는 반투명\n * - Unit: 낮은 depth, 불투명\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup, registerRealObjectFactory, disposeObject3D, MaterialBank } from '@hatiolab/things-scene'\nimport type { Component } from '@hatiolab/things-scene'\nimport { LEGEND_CAPACITY, legendColor, legendRangeEntryOf, resolveCarrierLegend } from '../features/mcs-status-default'\nimport { fitGaugeScale } from '../utils/fit-gauge-scale'\nimport {\n carrierSegmentsFromData,\n abnormalSegmentsFromData,\n carrierColorsFromLegend,\n ABNORMAL_COLORS\n} from '../utils/stocker-gauge'\nimport { Z_FMSIM } from './z-priority'\n\n// ── 설정 타입 ────────────────────────────────────────────\n\ninterface MCS3DConfig {\n /** state.depth 미설정 시 기본 depth.\n * defaultDepth > 0이면 절대값, 아니면 min(w,h) * depthRatio */\n depthRatio: number\n defaultDepth?: number\n /** true이면 syncZPosOffset = TRANSPORT_SURFACE_HEIGHT */\n defaultZPosFromParent?: boolean\n /** 1.0 = 불투명, 0.35 = 반투명 컨테이너 */\n opacity: number\n metalness: number\n roughness: number\n /** statusColor 미사용 시 기본 색상 */\n defaultColor: number\n /** 'box' | 'hexagon' | 'plane' | 'triangle' */\n shape: 'box' | 'hexagon' | 'plane' | 'triangle'\n /** mesh 생성 전 가시성 판정 — false 반환 시 mesh 미생성 */\n isVisible?: (component: Component) => boolean\n /** 부모 대비 크기 비율 (기본 1.0). < 1이면 부모 중심에 배치. */\n sizeRatio?: number\n /** 상부 면 제거 (5면 개방 박스) */\n openTop?: boolean\n /** 상판 무반사 (MeshBasicMaterial) */\n matteTop?: boolean\n /** 상판에 2D 렌더링 텍스처 적용 */\n texturedTop?: boolean\n /** 자체 발광 강도 (0~1). 조명 약한 면에서도 색상 유지 */\n emissiveIntensity?: number\n /** 바닥면 유지 (기본 false — 바닥면 제거) */\n keepBottomFace?: boolean\n /** syncZPosOffset 고정값 (설정 시 다른 로직 무시) */\n zPosOverride?: number\n /** z-priority — polygonOffset 으로 z-fight 완화. 기본 0 (OBJECTS). */\n zPriority?: number\n}\n\n/**\n * 포트 기본 높이 (절대값).\n * 모든 이송장치의 상단 높이 = 이 값.\n * 캐리어가 이송장치 간 높이 차 없이 이동할 수 있는 기준 높이.\n */\nexport const TRANSPORT_SURFACE_HEIGHT = 30\n\nconst DEFAULTS: MCS3DConfig = {\n depthRatio: 0.5,\n opacity: 1.0,\n metalness: 0.3,\n roughness: 0.7,\n defaultColor: 0xaabbcc,\n shape: 'box',\n}\n\n// ── 3D 오브젝트 ──────────────────────────────────────────\n\nclass MCSRealObject3D extends RealObjectGroup {\n private _config: MCS3DConfig\n\n constructor(component: Component, config: MCS3DConfig) {\n super(component)\n this._config = config\n }\n\n get zPriority(): number {\n return this._config.zPriority ?? 0\n }\n\n // width, height 절대값 (음수 값은 양수로 취급).\n // `resizable:false` 컴포넌트(예: Scanner)는 state.width/height 가 없고\n // bounds 만 있을 수 있으므로 bounds 를 fallback 으로 사용.\n //\n // `??` only catches null/undefined — a property-panel input that produced\n // NaN would slip through and corrupt every downstream Math.* call. Use a\n // finite check so NaN falls through to bounds → 10 like missing values do.\n protected get absSize(): { w: number; h: number } {\n const state = (this.component.state || {}) as any\n const bounds = (this.component.bounds || {}) as any\n const width = pickFinite(state.width, bounds.width, 10)\n const height = pickFinite(state.height, bounds.height, 10)\n return { w: Math.abs(width), h: Math.abs(height) }\n }\n\n get effectiveDepth(): number {\n const { depth } = this.component.state\n // Truthy `if (depth)` already rejected NaN/0/undefined, but be explicit\n // so the intent (and the resolution chain) reads cleanly: only an\n // explicit positive finite number wins; everything else → defaults.\n if (typeof depth === 'number' && Number.isFinite(depth) && depth > 0) {\n return depth\n }\n if (this._config.defaultDepth) return this._config.defaultDepth\n const { w, h } = this.absSize\n return Math.min(w, h) * this._config.depthRatio\n }\n\n protected get syncZPosOffset(): number {\n // syncZPosOffset = placement + geometric (center origin = effectiveDepth/2)\n // 중첩 보정(parent shift 상쇄)은 base RealObject.cz가 parent.geometricOffsetY를\n // 빼는 방식으로 처리하므로 여기선 placement + 본인 geometric만 반환\n const halfD = this.effectiveDepth / 2\n // zPosOverride: 고정 높이 (OHTLine 등)\n if (this._config.zPosOverride != null) {\n return this._config.zPosOverride + halfD\n }\n // Port: 이송 표면 높이에 배치\n if (this._config.defaultZPosFromParent) {\n return TRANSPORT_SURFACE_HEIGHT + halfD\n }\n return halfD\n }\n\n\n // geometric 부분(center origin: depth/2)은 base 기본값 사용 — override 불필요\n\n // 컴포넌트의 상태 색상(statusColor) 또는 fillStyle → Three.js 색상 변환\n protected resolveColor(): number {\n const comp = this.component as any\n\n // 1) MCSStatusMixin.statusColor (legend 기반 상태 색상)\n // '#F0F0F0'은 상태 미설정 시 기본 fallback — 무시하고 defaultColor 사용\n try {\n const sc = comp.statusColor\n if (typeof sc === 'string' && sc && sc.toUpperCase() !== '#F0F0F0' && sc !== 'transparent') return new THREE.Color(sc).getHex()\n } catch {\n /* statusColor 미구현 시 무시 */\n }\n\n // 2) state.fillStyle fallback\n const { fillStyle } = this.component.state\n if (fillStyle && typeof fillStyle === 'string' && fillStyle !== 'transparent') {\n try {\n return new THREE.Color(fillStyle).getHex()\n } catch {\n /* 파싱 실패 시 무시 */\n }\n }\n\n return this._config.defaultColor\n }\n\n // ── Geometry helpers ──\n\n /**\n * 바닥면(-Y 방향) 삼각형 제거: z-fighting 근본 해결.\n * 바닥면이 없으면 floor grid와 겹칠 면 자체가 없어진다.\n */\n private removeBottomFace(geometry: THREE.BufferGeometry): THREE.BufferGeometry {\n const posAttr = geometry.getAttribute('position')\n const normAttr = geometry.getAttribute('normal')\n const index = geometry.getIndex()\n\n if (!posAttr || !normAttr || !index) return geometry\n\n const newIndices: number[] = []\n const normalY = new THREE.Vector3()\n\n for (let i = 0; i < index.count; i += 3) {\n const a = index.getX(i)\n const b = index.getX(i + 1)\n const c = index.getX(i + 2)\n\n // 세 꼭짓점 노말의 Y 성분 평균으로 방향 판단\n const avgY = (normAttr.getY(a) + normAttr.getY(b) + normAttr.getY(c)) / 3\n\n // -Y 방향 삼각형 제거 (threshold -0.9: 거의 아래를 향하는 면만)\n if (avgY > -0.9) {\n newIndices.push(a, b, c)\n }\n }\n\n geometry.setIndex(newIndices)\n return geometry\n }\n\n // ── Geometry builders ──\n\n private buildBoxGeometry(w: number, d: number, h: number): THREE.BufferGeometry {\n const geo = new THREE.BoxGeometry(w, d, h)\n return this._config.keepBottomFace ? geo : this.removeBottomFace(geo)\n }\n\n private buildHexagonGeometry(w: number, d: number, h: number): THREE.BufferGeometry {\n // Buffer의 2D 형태: 좌우 끝이 꺾인 육각형\n const offset = Math.min(w, h) * 0.2\n const hw = w / 2\n const hh = h / 2\n\n const shape = new THREE.Shape()\n shape.moveTo(-hw + offset, -hh)\n shape.lineTo(hw - offset, -hh)\n shape.lineTo(hw, 0)\n shape.lineTo(hw - offset, hh)\n shape.lineTo(-hw + offset, hh)\n shape.lineTo(-hw, 0)\n shape.closePath()\n\n const geo = new THREE.ExtrudeGeometry(shape, {\n steps: 1,\n depth: d,\n bevelEnabled: false,\n })\n\n // 중심 정렬 후 Y-up 좌표계 회전 (extrude 축: +Z → +Y)\n geo.translate(0, 0, -d / 2)\n geo.rotateX(Math.PI / 2)\n\n return this.removeBottomFace(geo)\n }\n\n private buildPlaneGeometry(w: number, h: number): THREE.BufferGeometry {\n const geo = new THREE.PlaneGeometry(w, h)\n geo.rotateX(-Math.PI / 2)\n return geo\n }\n\n /**\n * 삼각형 prism — 2D Triangle 의 꼭짓점(state.x1/y1, x2/y2, x3/y3) 을 그대로 사용.\n * things-scene 의 TriangleExtrude 와 동일한 방식 — 각 Scanner 인스턴스의\n * 실제 정점 배치(방향, 비대칭 등) 가 3D 에 반영된다.\n *\n * `geometry.center()` 로 로컬 원점을 bounding-box 중심으로 맞추므로\n * 후속 placement 와 정합.\n */\n private buildTriangleGeometry(d: number): THREE.BufferGeometry {\n const state = (this.component.state || {}) as any\n const { x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0 } = state\n\n const shape = new THREE.Shape()\n shape.moveTo(x1, y1)\n shape.lineTo(x2, y2)\n shape.lineTo(x3, y3)\n shape.closePath()\n\n const geo = new THREE.ExtrudeGeometry(shape, {\n steps: 1,\n depth: d,\n bevelEnabled: false,\n })\n\n // bounding box 중심으로 원점 정렬 후 Y-up 좌표계로 회전\n geo.center()\n geo.rotateX(Math.PI / 2)\n\n return this.removeBottomFace(geo)\n }\n\n // ── Build ──\n\n protected _ownMesh?: THREE.Mesh\n\n build() {\n super.build()\n\n // 가시성 판정 — e.g., Carrier는 데이터 없으면 mesh 미생성\n if (this._config.isVisible && !this._config.isVisible(this.component)) return\n\n const { w: rawW, h: rawH } = this.absSize\n const rawDepth = this.effectiveDepth\n if (!rawW || !rawH) return\n\n const ratio = this._config.sizeRatio ?? 1.0\n const w = rawW * ratio\n const h = rawH * ratio\n const depth = rawDepth * ratio\n\n const color = this.resolveColor()\n const { opacity, metalness, roughness, shape } = this._config\n\n const geometry =\n shape === 'plane'\n ? this.buildPlaneGeometry(w, h)\n : shape === 'hexagon'\n ? this.buildHexagonGeometry(w, depth, h)\n : shape === 'triangle'\n ? this.buildTriangleGeometry(depth)\n : this.buildBoxGeometry(w, depth, h)\n\n const isPlane = shape === 'plane'\n // Standard body 는 MaterialBank 공유(색 변형) — 인스턴스 dedup + faint 안전(코어가 공유 base 의\n // 변형만 스왑, 원본 base 불변). plane 은 unlit MeshBasicMaterial 이라 bank(Standard 전용) 비대상 → raw.\n const material: THREE.Material = isPlane\n ? new THREE.MeshBasicMaterial({\n color,\n opacity,\n transparent: opacity < 1,\n side: THREE.DoubleSide,\n })\n : MaterialBank.material(\n 'mcs|body',\n {\n metalness,\n roughness,\n opacity,\n side: opacity < 1 ? THREE.DoubleSide : THREE.FrontSide,\n ...(this._config.emissiveIntensity\n ? { emissive: color, emissiveIntensity: this._config.emissiveIntensity }\n : {}),\n },\n color,\n )\n // z-fighting 방지: 바닥면(floor grid)보다 앞. bank body 는 공유 base 라 polygonOffset 은 모든 mcs\n // body 공통 상수 — 반환 material 에 세팅(같은 값이라 멱등, 인스턴스별 발산 없음).\n material.polygonOffset = true\n material.polygonOffsetFactor = -1\n material.polygonOffsetUnit = -1\n\n // BoxGeometry material groups: +x(0), -x(1), +y(2), -y(3), +z(4), -z(5)\n let meshMaterial: THREE.Material | THREE.Material[] = material\n if (shape === 'box') {\n if (this._config.openTop) {\n // 상단면 제거 → 5면 개방 박스\n const invisible = new THREE.MeshBasicMaterial({ visible: false })\n meshMaterial = [material, material, invisible, material, material, material]\n } else if (this._config.texturedTop) {\n // 상판에 2D 렌더링 텍스처\n const topMat = this.buildTopTexture(w, h)\n meshMaterial = [material, material, topMat, material, material, material]\n } else if (this._config.matteTop) {\n // 상판만 무반사\n const matte = new THREE.MeshBasicMaterial({ color, opacity, transparent: opacity < 1 })\n meshMaterial = [material, material, matte, material, material, material]\n }\n }\n\n this._ownMesh = new THREE.Mesh(geometry, meshMaterial)\n // ownGroup 기준(bottom-up): mesh 바닥을 y=0에 맞추고 ownGroup이 -d/2로 shift해\n // center-origin object3d에 정렬됨.\n // box/hexagon (center-local geometry): y=rawDepth/2 (바닥을 0에 맞춤)\n // plane: y=1 (바닥 살짝 띄움)\n this._ownMesh.position.y = isPlane ? 1 : rawDepth / 2\n this._ownMesh.castShadow = !isPlane\n this._ownMesh.receiveShadow = true\n this.components3D.add(this._ownMesh)\n\n // mesh 는 super.build() *이후* 생성되므로, 코어의 build-시점 faint 적용이 이 mesh 에 못 닿는다.\n // mesh 생성 직후 명시 적용 — 코어 applyMaterialOpacity 가 content-alpha × faint 를 일괄 처리.\n // view 모드에선 factor=1(=state.alpha 없음) → canonical(config.opacity) 그대로, 고객 화면 불변.\n this.updateAlpha()\n }\n\n // ── Change handling ──\n\n private _updatePending = false\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if (\n 'width' in after ||\n 'height' in after ||\n 'depth' in after ||\n 'fillStyle' in after ||\n 'strokeStyle' in after ||\n 'id' in after ||\n 'EMPTYTYPE' in after ||\n 'CARRIERSTATUS' in after ||\n 'showText' in after\n ) {\n // 연속 setState에 의한 다중 rebuild 방지: 한 프레임에 한 번만 실행\n if (!this._updatePending) {\n this._updatePending = true\n queueMicrotask(() => {\n this._updatePending = false\n this.update()\n })\n }\n return\n }\n\n super.onchange(after, before)\n }\n\n /**\n * 상판 텍스처: 컴포넌트의 2D render()를 캔버스에 그려서 텍스처로 사용\n */\n protected buildTopTexture(w: number, h: number): THREE.MeshBasicMaterial {\n const scale = 4\n const cw = this.nextPow2(w * scale)\n const ch = this.nextPow2(h * scale)\n const canvas = document.createElement('canvas')\n canvas.width = cw\n canvas.height = ch\n const ctx = canvas.getContext('2d')!\n\n const statusColor = '#' + this.resolveColor().toString(16).padStart(6, '0')\n const emptyType = (this.component.state as any)?.EMPTYTYPE || ''\n const text = emptyType === 'FULL' ? 'F' : emptyType === 'EMPTY' ? 'E' : emptyType === 'EMPTYEMPTY' ? 'X' : ''\n\n // 실제 사용 영역 (nextPow2 이전 크기)\n const usedW = w * scale\n const usedH = h * scale\n\n // 바탕: 캐리어 상태 색상 (사용 영역만)\n ctx.fillStyle = statusColor\n ctx.fillRect(0, 0, usedW, usedH)\n\n // 텍스트 (사용 영역 중앙) — showText(= 현재 홀더의 showCarrierText) off 면 미표시. 2D 와 동일.\n const showText = !!(this.component.state as any)?.showText\n if (text && showText) {\n const fontSize = Math.round(Math.min(usedW, usedH) * 0.7)\n ctx.font = `bold ${fontSize}px Arial`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = '#000000'\n ctx.fillText(text, usedW / 2, usedH / 2)\n }\n\n const texture = new THREE.CanvasTexture(canvas)\n texture.offset.set(0, 1 - usedH / ch)\n texture.repeat.set(usedW / cw, usedH / ch)\n texture.colorSpace = THREE.SRGBColorSpace\n\n return new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n side: THREE.DoubleSide,\n })\n }\n\n private nextPow2(n: number): number {\n if (!(n > 0)) return 1\n let v = Math.ceil(n)\n v--\n v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16\n return v + 1\n }\n\n /**\n * 자신의 mesh만 제거 후 rebuild.\n * 기본 update()는 clear()로 object3d의 모든 children을 제거하는데,\n * 컨테이너(Port 등)의 경우 자식 컴포넌트(Carrier 등)의 3D 오브젝트도 함께 제거됨.\n * 이를 방지하기 위해 자신이 생성한 mesh만 제거한다.\n */\n update() {\n // 자신의 mesh만 제거 (자식 컴포넌트 3D 오브젝트 보존)\n if (this._ownMesh) {\n this.components3D.remove(this._ownMesh)\n disposeObject3D(this._ownMesh)\n this._ownMesh = undefined\n }\n\n this.build()\n this.updateTransform()\n this.updateAlpha()\n this.updateHidden()\n }\n\n // RealObjectGroup 기본 동작 비활성화\n updateDimension() {}\n\n // updateAlpha override 제거 — 코어 RealObject.updateAlpha(=applyMaterialOpacity)로 수렴.\n // 코어가 canonical(=build 시 config.opacity 로 만든 material) 위에 factor = state.alpha × faint 를\n // 공유 변형 스왑으로 일괄 적용한다(원본 base 불변). 기존 in-place 변이는 (1) faint 미적용,\n // (2) 코어 applyFocusDim 과 이중 적용 소지가 있어 방언이었다. config.opacity 는 canonical 로 보존.\n}\n\n// ── 헬퍼 ────────────────────────────────────────────────\n\n/**\n * Returns the first argument that is a finite number. NaN slips past `??`\n * (which only catches null/undefined), so without this a property-panel\n * input producing NaN would corrupt absSize and cascade through Math.*.\n */\nfunction pickFinite(...candidates: unknown[]): number {\n for (const c of candidates) {\n if (typeof c === 'number' && Number.isFinite(c)) return c\n }\n return 0\n}\n\n// ── 팩토리 등록 헬퍼 ─────────────────────────────────────\n\nfunction register(type: string, overrides: Partial<MCS3DConfig> = {}) {\n const config: MCS3DConfig = { ...DEFAULTS, ...overrides }\n registerRealObjectFactory(type, (component: Component) => new MCSRealObject3D(component, config))\n}\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Machine (인프라 설비) — 높은 depth, 컨테이너는 반투명\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nregister('Equipment', {\n defaultDepth: 3 * TRANSPORT_SURFACE_HEIGHT,\n opacity: 0.75,\n metalness: 0.4,\n roughness: 0.6,\n defaultColor: 0x8899aa,\n zPriority: Z_FMSIM.EQUIPMENT,\n})\n\nregister('Buffer', {\n defaultDepth: TRANSPORT_SURFACE_HEIGHT,\n opacity: 1.0,\n metalness: 0.3,\n roughness: 0.7,\n defaultColor: 0x99aa88,\n shape: 'hexagon',\n zPriority: Z_FMSIM.BUFFER,\n})\n\nregister('AGVLine', {\n depthRatio: 0,\n defaultDepth: 0.1,\n metalness: 0.6,\n roughness: 0.3,\n defaultColor: 0x888899,\n zPriority: Z_FMSIM.AGV_LINE,\n})\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// OHTLine — 천장 I-beam 레일\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nconst OHT_LINE_RAIL_COLOR = 0xcccccc\nconst OHT_LINE_HEIGHT = 7 * TRANSPORT_SURFACE_HEIGHT // OHT 상단과 일치\n\nclass OHTLineRealObject3D extends RealObjectGroup {\n private _mesh?: THREE.Mesh\n\n get zPriority(): number { return Z_FMSIM.OHT_LINE }\n get effectiveDepth(): number { return 0 }\n protected get syncZPosOffset(): number { return OHT_LINE_HEIGHT }\n\n build() {\n super.build()\n\n const { width = 10, height = 10 } = this.component.state\n const w = Math.abs(width)\n const h = Math.abs(height)\n if (!w || !h) return\n\n // I-beam 치수: 이송 방향 = 긴 변, 폭은 2D의 1/2\n const isVertical = w < h\n const shortSide = isVertical ? w : h // 2D 원본 짧은 쪽 폭\n const beltW = shortSide * 0.25 // I-beam 폭: 원본의 1/4\n const beamH = Math.max(beltW * 0.5, 3) // I-beam 전체 높이\n const inset = shortSide * 0.5 // 양끝 여백: 원본 폭의 1/2\n const railLen = (isVertical ? h : w) - inset * 2\n const flangeH = beamH * 0.2 // 플랜지 두께\n const flangeW = beltW * 0.8 // 플랜지 폭\n const webH = beamH - flangeH * 2 // 웹 높이\n const webW = Math.max(flangeW * 0.25, 1) // 웹 두께\n\n // 공유 base(MaterialBank) — OHTLine rail 은 정적 색이라 전 인스턴스 dedup. faint 는 코어가\n // 공유 base 의 변형을 스왑(원본 불변). dispose 는 bank-safe(update 에서 material.dispose 안 함).\n const mat = MaterialBank.material('oht-line|rail', { metalness: 0.5, roughness: 0.4 }, OHT_LINE_RAIL_COLOR)\n\n const geoms: THREE.BufferGeometry[] = []\n\n // 상부 플랜지\n const topFlange = isVertical\n ? new THREE.BoxGeometry(flangeW, flangeH, railLen)\n : new THREE.BoxGeometry(railLen, flangeH, flangeW)\n topFlange.translate(0, -flangeH / 2, 0)\n geoms.push(topFlange)\n\n // 웹 (수직판)\n const web = isVertical\n ? new THREE.BoxGeometry(webW, webH, railLen)\n : new THREE.BoxGeometry(railLen, webH, webW)\n web.translate(0, -flangeH - webH / 2, 0)\n geoms.push(web)\n\n // 하부 플랜지\n const botFlange = isVertical\n ? new THREE.BoxGeometry(flangeW, flangeH, railLen)\n : new THREE.BoxGeometry(railLen, flangeH, flangeW)\n botFlange.translate(0, -flangeH - webH - flangeH / 2, 0)\n geoms.push(botFlange)\n\n this._mesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(geoms), mat)\n this._mesh.castShadow = true\n this.object3d.add(this._mesh)\n\n // mesh 가 super.build() 이후 생성 → 코어 faint 를 명시 적용(편집 흐림이 mesh 에 닿게).\n this.updateAlpha()\n }\n\n update() {\n if (this._mesh) {\n this.object3d.remove(this._mesh)\n this._mesh.geometry.dispose()\n // material 은 MaterialBank 공유(앱 수명) — 여기서 dispose 하면 다른 인스턴스가 깨진다.\n this._mesh = undefined\n }\n this.build()\n this.updateTransform()\n this.updateHidden()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('width' in after || 'height' in after || 'depth' in after ||\n 'fillStyle' in after || 'strokeStyle' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n // updateAlpha override 제거 — 코어 RealObject.updateAlpha(=applyMaterialOpacity)로 수렴(faint).\n updateDimension() {}\n}\n\nregisterRealObjectFactory('OHTLine', (component: Component) => new OHTLineRealObject3D(component))\n\n// STOCKER: 벽면에 용량 게이지 바를 포함하는 커스텀 3D 오브젝트\nconst STOCKER_CONFIG: MCS3DConfig = {\n ...DEFAULTS,\n defaultDepth: 5 * TRANSPORT_SURFACE_HEIGHT,\n opacity: 0.75,\n metalness: 0.3,\n roughness: 0.6,\n defaultColor: 0x8899bb,\n zPriority: Z_FMSIM.STOCKER,\n}\n\nclass StockerRealObject3D extends MCSRealObject3D {\n private gaugeMesh?: THREE.Mesh\n\n constructor(component: Component) {\n super(component, STOCKER_CONFIG)\n }\n\n build() {\n super.build()\n this.buildGauge()\n }\n\n private buildGauge() {\n const comp = this.component as any\n const data = comp.data || {}\n const gaugeMode = comp.root?.stockerGaugeMode || 'capacity'\n\n const gauge = this.resolveGauge(data, gaugeMode)\n\n // 테두리는 스토커의 상태 색상 (machine status)\n const statusColor = comp.statusColor\n if (statusColor && statusColor.toUpperCase() !== '#F0F0F0') {\n gauge.borderColor = statusColor\n }\n\n const { w, h } = this.absSize\n const depth = this.effectiveDepth\n const isWidthLonger = w >= h\n\n // 게이지 최대 크기 (스토커가 충분히 크면 이 크기 그대로 사용).\n const MAX_BAR_W = 130\n const MAX_BAR_H = 26\n\n // 스토커 지붕 footprint 에 맞춰 비례 축소 (확대는 안 함 — 현재 크기가 상한).\n const fit = fitGaugeScale(w, h, MAX_BAR_W, MAX_BAR_H)\n\n // PlaneGeometry 의 월드 크기는 clamp, 텍스처 캔버스 해상도는 최대 크기 기준 고정\n // (축소되어도 선명도 유지).\n const barW = MAX_BAR_W * fit\n const barH = MAX_BAR_H * fit\n const scale = 4\n const canvasW = MAX_BAR_W * scale\n const canvasH = MAX_BAR_H * scale\n const canvas = document.createElement('canvas')\n canvas.width = canvasW\n canvas.height = canvasH\n const ctx = canvas.getContext('2d')!\n\n const pad = 12\n\n // 배경 + 테두리\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0, 0, canvasW, canvasH)\n ctx.strokeStyle = gauge.borderColor\n ctx.lineWidth = 12\n ctx.strokeRect(6, 6, canvasW - 12, canvasH - 12)\n\n // 세그먼트 채움 (왼→오) + carrier/abnormal 은 세그먼트별 숫자(%) 표기 (2D 와 동일)\n const innerW = canvasW - pad * 2\n const innerH = canvasH - pad * 2\n // 컴포넌트 폰트 설정(fontFamily/bold/italic) 을 그대로, 크기만 텍스처 scale 배 (2D 와 상대 크기 일치).\n const fontSize = (Number((this.component as any).state?.fontSize) || 15) * scale\n const font = this.gaugeFont(fontSize)\n let x = pad\n for (const seg of gauge.segments) {\n const segW = Math.max(innerW * seg.ratio, seg.ratio > 0 ? 1 : 0)\n if (segW <= 0) continue\n ctx.fillStyle = seg.color\n ctx.fillRect(x, pad, segW, innerH)\n if (gauge.perSegment) {\n this.drawGaugeSegmentNumber(ctx, seg.ratio, x, pad, segW, innerH, font, fontSize)\n }\n x += segW\n }\n\n // capacity: 전체 중앙에 usage% 한 개 (2D 와 동일). carrier/abnormal 은 위 세그먼트별 숫자 사용.\n if (gauge.label) {\n ctx.font = font\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = '#333333'\n ctx.fillText(gauge.label, canvasW / 2, canvasH / 2)\n }\n\n // 텍스처 → Plane\n const texture = new THREE.CanvasTexture(canvas)\n texture.colorSpace = THREE.SRGBColorSpace\n\n const geo = new THREE.PlaneGeometry(barW, barH)\n geo.rotateX(-Math.PI / 2) // 수평 (지붕 위)\n if (!isWidthLonger) geo.rotateY(Math.PI / 2)\n\n const mat = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n side: THREE.DoubleSide,\n })\n mat.polygonOffset = true\n mat.polygonOffsetFactor = -2\n mat.polygonOffsetUnit = -2\n\n this.gaugeMesh = new THREE.Mesh(geo, mat)\n // ownGroup 기준(bottom-up): 볼륨 상단 = +depth. 그 위로 0.5 띄움.\n this.gaugeMesh.position.set(0, depth + 0.5, 0)\n this.components3D.add(this.gaugeMesh)\n }\n\n private resolveGauge(\n data: any,\n mode: string\n ): { segments: { ratio: number; color: string }[]; borderColor: string; label: string | null; perSegment: boolean } {\n switch (mode) {\n case 'carrier': {\n // 세그먼트 비율/색상은 2D 와 공유되는 단일 소스에서 계산 (필드/색상 drift 방지).\n // 색상은 carrier 컴포넌트와 동일한 legend(테마)에서 취득.\n const colors = carrierColorsFromLegend(resolveCarrierLegend(this.component))\n const [f, e, ee] = carrierSegmentsFromData(data, colors)\n const total = f.count + e.count + ee.count\n // 접두사 없는 세그먼트별 숫자(%)로 표기 (capacity·2D 와 동일). label(중앙 한 개) 미사용.\n return total > 0\n ? {\n segments: [f, e, ee].map(s => ({ ratio: s.ratio, color: s.color })),\n borderColor: colors.full,\n label: null,\n perSegment: true,\n }\n : { segments: [{ ratio: 1, color: '#dddddd' }], borderColor: colors.full, label: null, perSegment: false }\n }\n case 'abnormal': {\n const [n, a] = abnormalSegmentsFromData(data)\n const total = n.count + a.count\n return total > 0\n ? {\n segments: [n, a].map(s => ({ ratio: s.ratio, color: s.color })),\n borderColor: a.count > 0 ? ABNORMAL_COLORS.abnormal : ABNORMAL_COLORS.normal,\n label: null,\n perSegment: true,\n }\n : {\n segments: [{ ratio: 1, color: '#dddddd' }],\n borderColor: ABNORMAL_COLORS.normal,\n label: null,\n perSegment: false,\n }\n }\n default: { // capacity — 전체 중앙에 usage% 한 개\n const cur = Number(data.CURRENTCAPACITY) || 0\n const max = Number(data.MAXCAPACITY) || 100\n const fullup = data.FULLUP === 'T'\n const usage = Math.round((cur / max) * 100)\n const legend = (this.component as any).root?.stockerCapacityLegendTheme || LEGEND_CAPACITY\n const color = fullup ? 'red' : (legendColor(legendRangeEntryOf(usage, legend)) || '#44aa44')\n return {\n segments: [{ ratio: usage / 100, color }],\n borderColor: color,\n label: `${usage}%`,\n perSegment: false,\n }\n }\n }\n }\n\n /** 컴포넌트 폰트 설정(fontFamily/bold/italic)으로 CSS font 문자열 조합. size 는 텍스처 스케일 반영값. */\n private gaugeFont(sizePx: number): string {\n const st = (this.component as any).state || {}\n const parts: string[] = []\n if (st.bold) parts.push('bold')\n if (st.italic) parts.push('italic')\n parts.push(`${sizePx}px`)\n parts.push(st.fontFamily || 'sans-serif')\n return parts.join(' ')\n }\n\n /** 세그먼트 영역 중심에 숫자(%)만 표기. 좁으면 값% → 값 → 생략 (2D _drawSegmentLabel 과 동일 정책). */\n private drawGaugeSegmentNumber(\n ctx: CanvasRenderingContext2D,\n ratio: number,\n x: number,\n y: number,\n w: number,\n h: number,\n font: string,\n fontSize: number\n ) {\n ctx.font = font\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = '#333333'\n const value = `${Math.round(ratio * 100)}`\n const cx = x + w / 2\n const cy = y + h / 2\n if (fontSize <= h && ctx.measureText(`${value}%`).width <= w) {\n ctx.fillText(`${value}%`, cx, cy)\n } else if (fontSize <= h && ctx.measureText(value).width <= w) {\n ctx.fillText(value, cx, cy)\n }\n }\n\n update() {\n this.clearGauge()\n super.update()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('data' in after) {\n this.clearGauge()\n this.buildGauge()\n }\n super.onchange(after, before)\n }\n\n clear() {\n this.clearGauge()\n return super.clear()\n }\n\n private clearGauge() {\n if (this.gaugeMesh) {\n this.components3D.remove(this.gaugeMesh)\n this.gaugeMesh.geometry?.dispose()\n const mat = this.gaugeMesh.material as THREE.MeshBasicMaterial\n mat?.map?.dispose()\n mat?.dispose()\n this.gaugeMesh = undefined\n }\n }\n}\n\nregisterRealObjectFactory('STOCKER', (component: Component) => new StockerRealObject3D(component))\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Unit (이동체 · 홀더) — 낮은 depth, 불투명\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n// Port: 바닥판 (PlaneGeometry)\nconst PORT_CONFIG: MCS3DConfig = {\n ...DEFAULTS,\n depthRatio: 0.01,\n defaultZPosFromParent: true,\n opacity: 0.1,\n metalness: 0.3,\n roughness: 0.8,\n defaultColor: 0xb0a090,\n shape: 'plane',\n zPriority: Z_FMSIM.PORT,\n}\nregisterRealObjectFactory('Port', (component: Component) => new MCSRealObject3D(component, PORT_CONFIG))\n\nregister('Shelf', {\n depthRatio: 0.25,\n metalness: 0.3,\n roughness: 0.7,\n defaultColor: 0xaabbcc,\n zPriority: Z_FMSIM.SHELF,\n})\n\n// Carrier: CARRIERSTATUS에 따른 3D 애니메이션 지원\nconst CARRIER_CONFIG: MCS3DConfig = {\n ...DEFAULTS,\n depthRatio: 0.5,\n metalness: 0,\n roughness: 1,\n defaultColor: 0xf0f0f0,\n isVisible: (c: Component) => !!(c.state as any).id,\n sizeRatio: 0.8,\n texturedTop: true,\n // Carrier 는 이동 entity — default OBJECTS(0). zPriority 미설정.\n}\n\n/**\n * Carrier 의 3D. 홀더가 자리에 앉힌다 (공통 아이템 계약 3.4): 위치·회전은 홀더의 Anchor 노드 위 안착이고, 크기는 홀더가\n * 보이는 치수(타입의 선언 치수, 모르면 자리의 표시용 상자)다. 자리 안에 들도록 줄이는 배율도 홀더가 준다.\n */\nclass CarrierRealObject3D extends MCSRealObject3D {\n constructor(component: Component) {\n super(component, CARRIER_CONFIG)\n }\n\n /** 홀더가 보이는 치수 (도면 단위): 폭(X)·깊이(도면 Z)·높이. 모르면 null */\n private get shown(): { w: number; d: number; h: number } | null {\n const holder = this.component.parent as any\n const dims = holder?.carrierShownDimsOf?.(this.component)\n const k = holder?.mmPerSceneUnit\n if (!dims || !(k > 0)) return null\n return { w: dims.width / k, d: dims.depth / k, h: dims.height / k }\n }\n\n /** build 가 sizeRatio 를 곱하므로 미리 나눈다 */\n protected override get absSize(): { w: number; h: number } {\n const shown = this.shown\n if (!shown) return super.absSize\n const ratio = CARRIER_CONFIG.sizeRatio ?? 1\n return { w: shown.w / ratio, h: shown.d / ratio }\n }\n\n override get effectiveDepth(): number {\n const shown = this.shown\n if (!shown) return super.effectiveDepth\n return shown.h / (CARRIER_CONFIG.sizeRatio ?? 1)\n }\n}\n\nregisterRealObjectFactory('Carrier', (component: Component) => new CarrierRealObject3D(component))\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Gauge (용량 게이지) — 얇은 바\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Gauge (용량 게이지) — 2D 렌더링을 Plane 텍스처로 3D 표시\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n// Gauge 컴포넌트는 3D에서 표시하지 않음 (부모 STOCKER의 3D 모델에서 직접 게이지 렌더링)\n// null 반환으로 3D 오브젝트 생성을 억제하고, default factory fallback도 방지\nregisterRealObjectFactory('StockerCapacityBar', () => undefined as any)\nregisterRealObjectFactory('MCSGaugeCapacityBar', () => undefined as any)\nregisterRealObjectFactory('ZoneCapacityBar', () => undefined as any)\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// PortFlow — 2D render를 Plane 텍스처로 3D 표시\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nclass PortFlowRealObject3D extends RealObjectGroup {\n private _mesh?: THREE.Mesh\n private _texture?: THREE.CanvasTexture\n\n get zPriority(): number { return Z_FMSIM.PORT_FLOW }\n get effectiveDepth(): number { return 0 }\n protected get syncZPosOffset(): number {\n // 부모 Port/Conveyor의 zPos와 동일하게\n const parent = (this.component as any).parentObject\n if (parent?.state?.zPos != null) return parent.state.zPos\n return TRANSPORT_SURFACE_HEIGHT\n }\n\n build() {\n super.build()\n\n const { width = 10, height = 10 } = this.component.state\n const w = Math.abs(width)\n const h = Math.abs(height)\n if (!w || !h) return\n\n // 2D render를 캔버스에 캡처\n // 화살표 날개 + 텍스트 영역이 bounds 밖으로 나가므로 전체 영역 계산\n const { left, top } = this.component.bounds\n const { fontSize = 24, labelPosition = 'top' } = this.component.state\n const arrowPad = Math.min(w, h) * 0.4\n\n // 텍스트 영역 확장\n let padLeft = arrowPad, padRight = arrowPad, padTop = arrowPad, padBottom = arrowPad\n if ((this.component as any).hasTextProperty) {\n switch (labelPosition) {\n case 'top': padTop = Math.max(padTop, fontSize + 4); break\n case 'bottom': padBottom = Math.max(padBottom, fontSize + 4); break\n case 'left': padLeft = Math.max(padLeft, fontSize * 4 + 4); break\n case 'right': padRight = Math.max(padRight, fontSize * 4 + 4); break\n }\n }\n\n const totalW = w + padLeft + padRight\n const totalH = h + padTop + padBottom\n const scale = 2\n const canvas = document.createElement('canvas')\n canvas.width = totalW * scale\n canvas.height = totalH * scale\n const ctx = canvas.getContext('2d')!\n\n ctx.save()\n ctx.scale(scale, scale)\n ctx.translate(-left + padLeft, -top + padTop)\n try {\n // 화살표 렌더\n this.component.render(ctx)\n ctx.fillStyle = this.component.state.strokeStyle || '#666666'\n ctx.fill()\n // 텍스트 렌더\n if ((this.component as any).hasTextProperty && (this.component as any).drawText) {\n ;(this.component as any).drawText(ctx)\n }\n } catch { /* render 실패 시 빈 텍스처 */ }\n ctx.restore()\n\n this._texture = new THREE.CanvasTexture(canvas)\n this._texture.colorSpace = THREE.SRGBColorSpace\n\n const geo = new THREE.PlaneGeometry(totalW, totalH)\n geo.rotateX(-Math.PI / 2)\n\n const mat = new THREE.MeshBasicMaterial({\n map: this._texture,\n alphaTest: 0.1,\n side: THREE.DoubleSide,\n })\n\n this._mesh = new THREE.Mesh(geo, mat)\n // 비대칭 패딩 보정: 플레인 센터를 컴포넌트 bounds 센터에 맞춤\n this._mesh.position.x = (padRight - padLeft) / 2\n this._mesh.position.y = 1\n this._mesh.position.z = (padBottom - padTop) / 2\n this.object3d.add(this._mesh)\n }\n\n update() {\n if (this._mesh) {\n this.object3d.remove(this._mesh)\n this._mesh.geometry.dispose()\n ;(this._mesh.material as THREE.Material).dispose()\n this._texture?.dispose()\n this._mesh = undefined\n this._texture = undefined\n }\n this.build()\n this.updateTransform()\n this.updateHidden()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('width' in after || 'height' in after || 'orientation' in after ||\n 'direction' in after || 'strokeStyle' in after || 'INOUTTYPE' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateDimension() {}\n updateAlpha() {}\n}\n\nregisterRealObjectFactory('PortFlow', (component: Component) => new PortFlowRealObject3D(component))\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Node — 2D render를 바닥 Plane 텍스처로 3D 표시\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nclass NodeRealObject3D extends RealObjectGroup {\n private _mesh?: THREE.Mesh\n private _texture?: THREE.CanvasTexture\n\n get zPriority(): number { return Z_FMSIM.NODE }\n get effectiveDepth(): number { return 0 }\n protected get syncZPosOffset(): number { return 0 }\n\n build() {\n super.build()\n\n const { cx, cy } = this.component.state\n const radius = 8\n const size = radius * 2\n const scale = 2\n const pad = 2\n\n const canvas = document.createElement('canvas')\n canvas.width = (size + pad * 2) * scale\n canvas.height = (size + pad * 2) * scale\n const ctx = canvas.getContext('2d')!\n\n ctx.save()\n ctx.scale(scale, scale)\n ctx.translate(-cx + radius + pad, -cy + radius + pad)\n try {\n this.component.render(ctx)\n const { fillStyle = '#888888' } = this.component.state\n ctx.fillStyle = typeof fillStyle === 'string' ? fillStyle : '#888888'\n ctx.fill()\n const { strokeStyle } = this.component.state\n if (strokeStyle && typeof strokeStyle === 'string') {\n ctx.strokeStyle = strokeStyle\n ctx.lineWidth = 1\n ctx.stroke()\n }\n } catch { /* render 실패 시 빈 텍스처 */ }\n ctx.restore()\n\n this._texture = new THREE.CanvasTexture(canvas)\n this._texture.colorSpace = THREE.SRGBColorSpace\n\n const geo = new THREE.PlaneGeometry(size + pad * 2, size + pad * 2)\n geo.rotateX(-Math.PI / 2)\n\n const mat = new THREE.MeshBasicMaterial({\n map: this._texture,\n alphaTest: 0.1,\n side: THREE.DoubleSide,\n })\n\n this._mesh = new THREE.Mesh(geo, mat)\n this._mesh.position.y = 1\n this.object3d.add(this._mesh)\n }\n\n update() {\n if (this._mesh) {\n this.object3d.remove(this._mesh)\n this._mesh.geometry.dispose()\n ;(this._mesh.material as THREE.Material).dispose()\n this._texture?.dispose()\n this._mesh = undefined\n this._texture = undefined\n }\n this.build()\n this.updateTransform()\n this.updateHidden()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('fillStyle' in after || 'strokeStyle' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateDimension() {}\n updateAlpha() {}\n}\n\nregisterRealObjectFactory('Node', (component: Component) => new NodeRealObject3D(component))\n\n// Scanner — 2D Triangle 실루엣과 정합되는 삼각형 prism.\n// 이송 표면 높이의 0.2배(=6) 얇은 기둥 — 원래 값 유지, shape 만 'box' → 'triangle'.\nconst SCANNER_CONFIG: MCS3DConfig = {\n ...DEFAULTS,\n defaultDepth: TRANSPORT_SURFACE_HEIGHT * 0.2,\n defaultZPosFromParent: true,\n opacity: 1,\n metalness: 0.3,\n roughness: 0.7,\n defaultColor: 0x888888,\n shape: 'triangle',\n zPriority: Z_FMSIM.SCANNER,\n}\nregisterRealObjectFactory('Scanner', (component: Component) => new MCSRealObject3D(component, SCANNER_CONFIG))\n"]}
1
+ {"version":3,"file":"machine-3d.js","sourceRoot":"","sources":["../../src/factories/machine-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCS 설비 컴포넌트 3D 팩토리\n *\n * 10,000+ 인스턴스를 위한 최소 폴리곤 설계:\n * - 컴포넌트당 단일 Mesh (draw call 최소화)\n * - BoxGeometry / ExtrudeGeometry(hexagon) 만 사용\n * - Machine: 높은 depth, 컨테이너는 반투명\n * - Unit: 낮은 depth, 불투명\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup, registerRealObjectFactory, disposeObject3D, MaterialBank } from '@hatiolab/things-scene'\nimport type { Component } from '@hatiolab/things-scene'\nimport { LEGEND_CAPACITY, legendColor, legendRangeEntryOf, resolveCarrierLegend } from '../features/mcs-status-default'\nimport { fitGaugeScale } from '../utils/fit-gauge-scale'\nimport { railTopOf } from '../features/oht-rail'\nimport { MACHINE_HEIGHTS, MACHINE_OPACITY, TRANSPORT_SURFACE_HEIGHT } from '../features/lv-heights'\nimport {\n carrierSegmentsFromData,\n abnormalSegmentsFromData,\n carrierColorsFromLegend,\n ABNORMAL_COLORS\n} from '../utils/stocker-gauge'\nimport { Z_FMSIM } from './z-priority'\n\n// ── 설정 타입 ────────────────────────────────────────────\n\ninterface MCS3DConfig {\n /** state.depth 미설정 시 기본 depth.\n * defaultDepth > 0이면 절대값, 아니면 min(w,h) * depthRatio */\n depthRatio: number\n defaultDepth?: number\n /** true이면 syncZPosOffset = TRANSPORT_SURFACE_HEIGHT */\n defaultZPosFromParent?: boolean\n /** 1.0 = 불투명, 0.35 = 반투명 컨테이너 */\n opacity: number\n metalness: number\n roughness: number\n /** statusColor 미사용 시 기본 색상 */\n defaultColor: number\n /** 'box' | 'hexagon' | 'plane' | 'triangle' */\n shape: 'box' | 'hexagon' | 'plane' | 'triangle'\n /** mesh 생성 전 가시성 판정 — false 반환 시 mesh 미생성 */\n isVisible?: (component: Component) => boolean\n /** 부모 대비 크기 비율 (기본 1.0). < 1이면 부모 중심에 배치. */\n sizeRatio?: number\n /** 상부 면 제거 (5면 개방 박스) */\n openTop?: boolean\n /** 상판 무반사 (MeshBasicMaterial) */\n matteTop?: boolean\n /** 상판에 2D 렌더링 텍스처 적용 */\n texturedTop?: boolean\n /** 자체 발광 강도 (0~1). 조명 약한 면에서도 색상 유지 */\n emissiveIntensity?: number\n /** 바닥면 유지 (기본 false — 바닥면 제거) */\n keepBottomFace?: boolean\n /** syncZPosOffset 고정값 (설정 시 다른 로직 무시) */\n zPosOverride?: number\n /** z-priority — polygonOffset 으로 z-fight 완화. 기본 0 (OBJECTS). */\n zPriority?: number\n}\n\n/* 포트 기본 높이와 설비 타입별 높이는 한 곳(features/lv-heights) — 피규어 fmsim.Machine 도 같은 표를 읽는다 */\nexport { TRANSPORT_SURFACE_HEIGHT } from '../features/lv-heights'\n\nconst DEFAULTS: MCS3DConfig = {\n depthRatio: 0.5,\n opacity: 1.0,\n metalness: 0.3,\n roughness: 0.7,\n defaultColor: 0xaabbcc,\n shape: 'box',\n}\n\n// ── 3D 오브젝트 ──────────────────────────────────────────\n\nclass MCSRealObject3D extends RealObjectGroup {\n private _config: MCS3DConfig\n\n constructor(component: Component, config: MCS3DConfig) {\n super(component)\n this._config = config\n }\n\n get zPriority(): number {\n return this._config.zPriority ?? 0\n }\n\n // width, height 절대값 (음수 값은 양수로 취급).\n // `resizable:false` 컴포넌트(예: Scanner)는 state.width/height 가 없고\n // bounds 만 있을 수 있으므로 bounds 를 fallback 으로 사용.\n //\n // `??` only catches null/undefined — a property-panel input that produced\n // NaN would slip through and corrupt every downstream Math.* call. Use a\n // finite check so NaN falls through to bounds → 10 like missing values do.\n protected get absSize(): { w: number; h: number } {\n const state = (this.component.state || {}) as any\n const bounds = (this.component.bounds || {}) as any\n const width = pickFinite(state.width, bounds.width, 10)\n const height = pickFinite(state.height, bounds.height, 10)\n return { w: Math.abs(width), h: Math.abs(height) }\n }\n\n get effectiveDepth(): number {\n const { depth } = this.component.state\n // Truthy `if (depth)` already rejected NaN/0/undefined, but be explicit\n // so the intent (and the resolution chain) reads cleanly: only an\n // explicit positive finite number wins; everything else → defaults.\n if (typeof depth === 'number' && Number.isFinite(depth) && depth > 0) {\n return depth\n }\n if (this._config.defaultDepth) return this._config.defaultDepth\n const { w, h } = this.absSize\n return Math.min(w, h) * this._config.depthRatio\n }\n\n protected get syncZPosOffset(): number {\n // syncZPosOffset = placement + geometric (center origin = effectiveDepth/2)\n // 중첩 보정(parent shift 상쇄)은 base RealObject.cz가 parent.geometricOffsetY를\n // 빼는 방식으로 처리하므로 여기선 placement + 본인 geometric만 반환\n const halfD = this.effectiveDepth / 2\n // zPosOverride: 고정 높이 (OHTLine 등)\n if (this._config.zPosOverride != null) {\n return this._config.zPosOverride + halfD\n }\n // Port: 이송 표면 높이에 배치\n if (this._config.defaultZPosFromParent) {\n return TRANSPORT_SURFACE_HEIGHT + halfD\n }\n return halfD\n }\n\n\n // geometric 부분(center origin: depth/2)은 base 기본값 사용 — override 불필요\n\n // 컴포넌트의 상태 색상(statusColor) 또는 fillStyle → Three.js 색상 변환\n protected resolveColor(): number {\n const comp = this.component as any\n\n // 1) MCSStatusMixin.statusColor (legend 기반 상태 색상)\n // '#F0F0F0'은 상태 미설정 시 기본 fallback — 무시하고 defaultColor 사용\n try {\n const sc = comp.statusColor\n if (typeof sc === 'string' && sc && sc.toUpperCase() !== '#F0F0F0' && sc !== 'transparent') return new THREE.Color(sc).getHex()\n } catch {\n /* statusColor 미구현 시 무시 */\n }\n\n // 2) state.fillStyle fallback\n const { fillStyle } = this.component.state\n if (fillStyle && typeof fillStyle === 'string' && fillStyle !== 'transparent') {\n try {\n return new THREE.Color(fillStyle).getHex()\n } catch {\n /* 파싱 실패 시 무시 */\n }\n }\n\n return this._config.defaultColor\n }\n\n // ── Geometry helpers ──\n\n /**\n * 바닥면(-Y 방향) 삼각형 제거: z-fighting 근본 해결.\n * 바닥면이 없으면 floor grid와 겹칠 면 자체가 없어진다.\n */\n private removeBottomFace(geometry: THREE.BufferGeometry): THREE.BufferGeometry {\n const posAttr = geometry.getAttribute('position')\n const normAttr = geometry.getAttribute('normal')\n const index = geometry.getIndex()\n\n if (!posAttr || !normAttr || !index) return geometry\n\n const newIndices: number[] = []\n const normalY = new THREE.Vector3()\n\n for (let i = 0; i < index.count; i += 3) {\n const a = index.getX(i)\n const b = index.getX(i + 1)\n const c = index.getX(i + 2)\n\n // 세 꼭짓점 노말의 Y 성분 평균으로 방향 판단\n const avgY = (normAttr.getY(a) + normAttr.getY(b) + normAttr.getY(c)) / 3\n\n // -Y 방향 삼각형 제거 (threshold -0.9: 거의 아래를 향하는 면만)\n if (avgY > -0.9) {\n newIndices.push(a, b, c)\n }\n }\n\n geometry.setIndex(newIndices)\n return geometry\n }\n\n // ── Geometry builders ──\n\n private buildBoxGeometry(w: number, d: number, h: number): THREE.BufferGeometry {\n const geo = new THREE.BoxGeometry(w, d, h)\n return this._config.keepBottomFace ? geo : this.removeBottomFace(geo)\n }\n\n private buildHexagonGeometry(w: number, d: number, h: number): THREE.BufferGeometry {\n // Buffer의 2D 형태: 좌우 끝이 꺾인 육각형\n const offset = Math.min(w, h) * 0.2\n const hw = w / 2\n const hh = h / 2\n\n const shape = new THREE.Shape()\n shape.moveTo(-hw + offset, -hh)\n shape.lineTo(hw - offset, -hh)\n shape.lineTo(hw, 0)\n shape.lineTo(hw - offset, hh)\n shape.lineTo(-hw + offset, hh)\n shape.lineTo(-hw, 0)\n shape.closePath()\n\n const geo = new THREE.ExtrudeGeometry(shape, {\n steps: 1,\n depth: d,\n bevelEnabled: false,\n })\n\n // 중심 정렬 후 Y-up 좌표계 회전 (extrude 축: +Z → +Y)\n geo.translate(0, 0, -d / 2)\n geo.rotateX(Math.PI / 2)\n\n return this.removeBottomFace(geo)\n }\n\n private buildPlaneGeometry(w: number, h: number): THREE.BufferGeometry {\n const geo = new THREE.PlaneGeometry(w, h)\n geo.rotateX(-Math.PI / 2)\n return geo\n }\n\n /**\n * 삼각형 prism — 2D Triangle 의 꼭짓점(state.x1/y1, x2/y2, x3/y3) 을 그대로 사용.\n * things-scene 의 TriangleExtrude 와 동일한 방식 — 각 Scanner 인스턴스의\n * 실제 정점 배치(방향, 비대칭 등) 가 3D 에 반영된다.\n *\n * `geometry.center()` 로 로컬 원점을 bounding-box 중심으로 맞추므로\n * 후속 placement 와 정합.\n */\n private buildTriangleGeometry(d: number): THREE.BufferGeometry {\n const state = (this.component.state || {}) as any\n const { x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0 } = state\n\n const shape = new THREE.Shape()\n shape.moveTo(x1, y1)\n shape.lineTo(x2, y2)\n shape.lineTo(x3, y3)\n shape.closePath()\n\n const geo = new THREE.ExtrudeGeometry(shape, {\n steps: 1,\n depth: d,\n bevelEnabled: false,\n })\n\n // bounding box 중심으로 원점 정렬 후 Y-up 좌표계로 회전\n geo.center()\n geo.rotateX(Math.PI / 2)\n\n return this.removeBottomFace(geo)\n }\n\n // ── Build ──\n\n protected _ownMesh?: THREE.Mesh\n\n build() {\n super.build()\n\n // 가시성 판정 — e.g., Carrier는 데이터 없으면 mesh 미생성\n if (this._config.isVisible && !this._config.isVisible(this.component)) return\n\n const { w: rawW, h: rawH } = this.absSize\n const rawDepth = this.effectiveDepth\n if (!rawW || !rawH) return\n\n const ratio = this._config.sizeRatio ?? 1.0\n const w = rawW * ratio\n const h = rawH * ratio\n const depth = rawDepth * ratio\n\n const color = this.resolveColor()\n const { opacity, metalness, roughness, shape } = this._config\n\n const geometry =\n shape === 'plane'\n ? this.buildPlaneGeometry(w, h)\n : shape === 'hexagon'\n ? this.buildHexagonGeometry(w, depth, h)\n : shape === 'triangle'\n ? this.buildTriangleGeometry(depth)\n : this.buildBoxGeometry(w, depth, h)\n\n const isPlane = shape === 'plane'\n // Standard body 는 MaterialBank 공유(색 변형) — 인스턴스 dedup + faint 안전(코어가 공유 base 의\n // 변형만 스왑, 원본 base 불변). plane 은 unlit MeshBasicMaterial 이라 bank(Standard 전용) 비대상 → raw.\n const material: THREE.Material = isPlane\n ? new THREE.MeshBasicMaterial({\n color,\n opacity,\n transparent: opacity < 1,\n side: THREE.DoubleSide,\n })\n : MaterialBank.material(\n 'mcs|body',\n {\n metalness,\n roughness,\n opacity,\n side: opacity < 1 ? THREE.DoubleSide : THREE.FrontSide,\n ...(this._config.emissiveIntensity\n ? { emissive: color, emissiveIntensity: this._config.emissiveIntensity }\n : {}),\n },\n color,\n )\n // z-fighting 방지: 바닥면(floor grid)보다 앞. bank body 는 공유 base 라 polygonOffset 은 모든 mcs\n // body 공통 상수 — 반환 material 에 세팅(같은 값이라 멱등, 인스턴스별 발산 없음).\n material.polygonOffset = true\n material.polygonOffsetFactor = -1\n material.polygonOffsetUnit = -1\n\n // BoxGeometry material groups: +x(0), -x(1), +y(2), -y(3), +z(4), -z(5)\n let meshMaterial: THREE.Material | THREE.Material[] = material\n if (shape === 'box') {\n if (this._config.openTop) {\n // 상단면 제거 → 5면 개방 박스\n const invisible = new THREE.MeshBasicMaterial({ visible: false })\n meshMaterial = [material, material, invisible, material, material, material]\n } else if (this._config.texturedTop) {\n // 상판에 2D 렌더링 텍스처\n const topMat = this.buildTopTexture(w, h)\n meshMaterial = [material, material, topMat, material, material, material]\n } else if (this._config.matteTop) {\n // 상판만 무반사\n const matte = new THREE.MeshBasicMaterial({ color, opacity, transparent: opacity < 1 })\n meshMaterial = [material, material, matte, material, material, material]\n }\n }\n\n this._ownMesh = new THREE.Mesh(geometry, meshMaterial)\n // ownGroup 기준(bottom-up): mesh 바닥을 y=0에 맞추고 ownGroup이 -d/2로 shift해\n // center-origin object3d에 정렬됨.\n // box/hexagon (center-local geometry): y=rawDepth/2 (바닥을 0에 맞춤)\n // plane: y=1 (바닥 살짝 띄움)\n this._ownMesh.position.y = isPlane ? 1 : rawDepth / 2\n this._ownMesh.castShadow = !isPlane\n this._ownMesh.receiveShadow = true\n this.components3D.add(this._ownMesh)\n\n // mesh 는 super.build() *이후* 생성되므로, 코어의 build-시점 faint 적용이 이 mesh 에 못 닿는다.\n // mesh 생성 직후 명시 적용 — 코어 applyMaterialOpacity 가 content-alpha × faint 를 일괄 처리.\n // view 모드에선 factor=1(=state.alpha 없음) → canonical(config.opacity) 그대로, 고객 화면 불변.\n this.updateAlpha()\n }\n\n // ── Change handling ──\n\n private _updatePending = false\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if (\n 'width' in after ||\n 'height' in after ||\n 'depth' in after ||\n 'fillStyle' in after ||\n 'strokeStyle' in after ||\n 'id' in after ||\n 'EMPTYTYPE' in after ||\n 'CARRIERSTATUS' in after ||\n 'showText' in after\n ) {\n // 연속 setState에 의한 다중 rebuild 방지: 한 프레임에 한 번만 실행\n if (!this._updatePending) {\n this._updatePending = true\n queueMicrotask(() => {\n this._updatePending = false\n this.update()\n })\n }\n return\n }\n\n super.onchange(after, before)\n }\n\n /**\n * 상판 텍스처: 컴포넌트의 2D render()를 캔버스에 그려서 텍스처로 사용\n */\n protected buildTopTexture(w: number, h: number): THREE.MeshBasicMaterial {\n const scale = 4\n const cw = this.nextPow2(w * scale)\n const ch = this.nextPow2(h * scale)\n const canvas = document.createElement('canvas')\n canvas.width = cw\n canvas.height = ch\n const ctx = canvas.getContext('2d')!\n\n const statusColor = '#' + this.resolveColor().toString(16).padStart(6, '0')\n const emptyType = (this.component.state as any)?.EMPTYTYPE || ''\n const text = emptyType === 'FULL' ? 'F' : emptyType === 'EMPTY' ? 'E' : emptyType === 'EMPTYEMPTY' ? 'X' : ''\n\n // 실제 사용 영역 (nextPow2 이전 크기)\n const usedW = w * scale\n const usedH = h * scale\n\n // 바탕: 캐리어 상태 색상 (사용 영역만)\n ctx.fillStyle = statusColor\n ctx.fillRect(0, 0, usedW, usedH)\n\n // 텍스트 (사용 영역 중앙) — showText(= 현재 홀더의 showCarrierText) off 면 미표시. 2D 와 동일.\n const showText = !!(this.component.state as any)?.showText\n if (text && showText) {\n const fontSize = Math.round(Math.min(usedW, usedH) * 0.7)\n ctx.font = `bold ${fontSize}px Arial`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = '#000000'\n ctx.fillText(text, usedW / 2, usedH / 2)\n }\n\n const texture = new THREE.CanvasTexture(canvas)\n texture.offset.set(0, 1 - usedH / ch)\n texture.repeat.set(usedW / cw, usedH / ch)\n texture.colorSpace = THREE.SRGBColorSpace\n\n return new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n side: THREE.DoubleSide,\n })\n }\n\n private nextPow2(n: number): number {\n if (!(n > 0)) return 1\n let v = Math.ceil(n)\n v--\n v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16\n return v + 1\n }\n\n /**\n * 자신의 mesh만 제거 후 rebuild.\n * 기본 update()는 clear()로 object3d의 모든 children을 제거하는데,\n * 컨테이너(Port 등)의 경우 자식 컴포넌트(Carrier 등)의 3D 오브젝트도 함께 제거됨.\n * 이를 방지하기 위해 자신이 생성한 mesh만 제거한다.\n */\n update() {\n // 자신의 mesh만 제거 (자식 컴포넌트 3D 오브젝트 보존)\n if (this._ownMesh) {\n this.components3D.remove(this._ownMesh)\n disposeObject3D(this._ownMesh)\n this._ownMesh = undefined\n }\n\n this.build()\n this.updateTransform()\n this.updateAlpha()\n this.updateHidden()\n }\n\n // RealObjectGroup 기본 동작 비활성화\n updateDimension() {}\n\n // updateAlpha override 제거 — 코어 RealObject.updateAlpha(=applyMaterialOpacity)로 수렴.\n // 코어가 canonical(=build 시 config.opacity 로 만든 material) 위에 factor = state.alpha × faint 를\n // 공유 변형 스왑으로 일괄 적용한다(원본 base 불변). 기존 in-place 변이는 (1) faint 미적용,\n // (2) 코어 applyFocusDim 과 이중 적용 소지가 있어 방언이었다. config.opacity 는 canonical 로 보존.\n}\n\n// ── 헬퍼 ────────────────────────────────────────────────\n\n/**\n * Returns the first argument that is a finite number. NaN slips past `??`\n * (which only catches null/undefined), so without this a property-panel\n * input producing NaN would corrupt absSize and cascade through Math.*.\n */\nfunction pickFinite(...candidates: unknown[]): number {\n for (const c of candidates) {\n if (typeof c === 'number' && Number.isFinite(c)) return c\n }\n return 0\n}\n\n// ── 팩토리 등록 헬퍼 ─────────────────────────────────────\n\nfunction register(type: string, overrides: Partial<MCS3DConfig> = {}) {\n const config: MCS3DConfig = { ...DEFAULTS, ...overrides }\n registerRealObjectFactory(type, (component: Component) => new MCSRealObject3D(component, config))\n}\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Machine (인프라 설비) — 높은 depth, 컨테이너는 반투명\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nregister('Equipment', {\n defaultDepth: MACHINE_HEIGHTS.equipment,\n opacity: MACHINE_OPACITY.equipment,\n metalness: 0.4,\n roughness: 0.6,\n defaultColor: 0x8899aa,\n zPriority: Z_FMSIM.EQUIPMENT,\n})\n\nregister('Buffer', {\n defaultDepth: MACHINE_HEIGHTS.buffer,\n opacity: MACHINE_OPACITY.buffer,\n metalness: 0.3,\n roughness: 0.7,\n defaultColor: 0x99aa88,\n shape: 'hexagon',\n zPriority: Z_FMSIM.BUFFER,\n})\n\nregister('AGVLine', {\n depthRatio: 0,\n defaultDepth: 0.1,\n metalness: 0.6,\n roughness: 0.3,\n defaultColor: 0x888899,\n zPriority: Z_FMSIM.AGV_LINE,\n})\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// OHTLine — 천장 I-beam 레일\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nconst OHT_LINE_RAIL_COLOR = 0xcccccc\n\nclass OHTLineRealObject3D extends RealObjectGroup {\n private _mesh?: THREE.Mesh\n\n get zPriority(): number { return Z_FMSIM.OHT_LINE }\n get effectiveDepth(): number { return 0 }\n /** 레일 윗면 = 작업환경 천장 − 라인의 매달림 길이(railHang). OHT 상단이 여기에 매달린다 */\n protected get syncZPosOffset(): number { return railTopOf(this.component) }\n\n build() {\n super.build()\n\n const { width = 10, height = 10 } = this.component.state\n const w = Math.abs(width)\n const h = Math.abs(height)\n if (!w || !h) return\n\n // I-beam 치수: 이송 방향 = 긴 변, 폭은 2D의 1/2\n const isVertical = w < h\n const shortSide = isVertical ? w : h // 2D 원본 짧은 쪽 폭\n const beltW = shortSide * 0.25 // I-beam 폭: 원본의 1/4\n const beamH = Math.max(beltW * 0.5, 3) // I-beam 전체 높이\n const inset = shortSide * 0.5 // 양끝 여백: 원본 폭의 1/2\n const railLen = (isVertical ? h : w) - inset * 2\n const flangeH = beamH * 0.2 // 플랜지 두께\n const flangeW = beltW * 0.8 // 플랜지 폭\n const webH = beamH - flangeH * 2 // 웹 높이\n const webW = Math.max(flangeW * 0.25, 1) // 웹 두께\n\n // 공유 base(MaterialBank) — OHTLine rail 은 정적 색이라 전 인스턴스 dedup. faint 는 코어가\n // 공유 base 의 변형을 스왑(원본 불변). dispose 는 bank-safe(update 에서 material.dispose 안 함).\n const mat = MaterialBank.material('oht-line|rail', { metalness: 0.5, roughness: 0.4 }, OHT_LINE_RAIL_COLOR)\n\n const geoms: THREE.BufferGeometry[] = []\n\n // 상부 플랜지\n const topFlange = isVertical\n ? new THREE.BoxGeometry(flangeW, flangeH, railLen)\n : new THREE.BoxGeometry(railLen, flangeH, flangeW)\n topFlange.translate(0, -flangeH / 2, 0)\n geoms.push(topFlange)\n\n // 웹 (수직판)\n const web = isVertical\n ? new THREE.BoxGeometry(webW, webH, railLen)\n : new THREE.BoxGeometry(railLen, webH, webW)\n web.translate(0, -flangeH - webH / 2, 0)\n geoms.push(web)\n\n // 하부 플랜지\n const botFlange = isVertical\n ? new THREE.BoxGeometry(flangeW, flangeH, railLen)\n : new THREE.BoxGeometry(railLen, flangeH, flangeW)\n botFlange.translate(0, -flangeH - webH - flangeH / 2, 0)\n geoms.push(botFlange)\n\n this._mesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(geoms), mat)\n this._mesh.castShadow = true\n this.object3d.add(this._mesh)\n\n // mesh 가 super.build() 이후 생성 → 코어 faint 를 명시 적용(편집 흐림이 mesh 에 닿게).\n this.updateAlpha()\n }\n\n update() {\n if (this._mesh) {\n this.object3d.remove(this._mesh)\n this._mesh.geometry.dispose()\n // material 은 MaterialBank 공유(앱 수명) — 여기서 dispose 하면 다른 인스턴스가 깨진다.\n this._mesh = undefined\n }\n this.build()\n this.updateTransform()\n this.updateHidden()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('width' in after || 'height' in after || 'depth' in after ||\n 'fillStyle' in after || 'strokeStyle' in after) {\n this.update()\n return\n }\n if ('railHang' in after) this.updateTransform()\n super.onchange(after, before)\n }\n\n // updateAlpha override 제거 — 코어 RealObject.updateAlpha(=applyMaterialOpacity)로 수렴(faint).\n updateDimension() {}\n}\n\nregisterRealObjectFactory('OHTLine', (component: Component) => new OHTLineRealObject3D(component))\n\n// STOCKER: 벽면에 용량 게이지 바를 포함하는 커스텀 3D 오브젝트\nconst STOCKER_CONFIG: MCS3DConfig = {\n ...DEFAULTS,\n defaultDepth: 5 * TRANSPORT_SURFACE_HEIGHT,\n opacity: 0.75,\n metalness: 0.3,\n roughness: 0.6,\n defaultColor: 0x8899bb,\n zPriority: Z_FMSIM.STOCKER,\n}\n\nclass StockerRealObject3D extends MCSRealObject3D {\n private gaugeMesh?: THREE.Mesh\n\n constructor(component: Component) {\n super(component, STOCKER_CONFIG)\n }\n\n build() {\n super.build()\n this.buildGauge()\n }\n\n private buildGauge() {\n const comp = this.component as any\n const data = comp.data || {}\n const gaugeMode = comp.root?.stockerGaugeMode || 'capacity'\n\n const gauge = this.resolveGauge(data, gaugeMode)\n\n // 테두리는 스토커의 상태 색상 (machine status)\n const statusColor = comp.statusColor\n if (statusColor && statusColor.toUpperCase() !== '#F0F0F0') {\n gauge.borderColor = statusColor\n }\n\n const { w, h } = this.absSize\n const depth = this.effectiveDepth\n const isWidthLonger = w >= h\n\n // 게이지 최대 크기 (스토커가 충분히 크면 이 크기 그대로 사용).\n const MAX_BAR_W = 130\n const MAX_BAR_H = 26\n\n // 스토커 지붕 footprint 에 맞춰 비례 축소 (확대는 안 함 — 현재 크기가 상한).\n const fit = fitGaugeScale(w, h, MAX_BAR_W, MAX_BAR_H)\n\n // PlaneGeometry 의 월드 크기는 clamp, 텍스처 캔버스 해상도는 최대 크기 기준 고정\n // (축소되어도 선명도 유지).\n const barW = MAX_BAR_W * fit\n const barH = MAX_BAR_H * fit\n const scale = 4\n const canvasW = MAX_BAR_W * scale\n const canvasH = MAX_BAR_H * scale\n const canvas = document.createElement('canvas')\n canvas.width = canvasW\n canvas.height = canvasH\n const ctx = canvas.getContext('2d')!\n\n const pad = 12\n\n // 배경 + 테두리\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0, 0, canvasW, canvasH)\n ctx.strokeStyle = gauge.borderColor\n ctx.lineWidth = 12\n ctx.strokeRect(6, 6, canvasW - 12, canvasH - 12)\n\n // 세그먼트 채움 (왼→오) + carrier/abnormal 은 세그먼트별 숫자(%) 표기 (2D 와 동일)\n const innerW = canvasW - pad * 2\n const innerH = canvasH - pad * 2\n // 컴포넌트 폰트 설정(fontFamily/bold/italic) 을 그대로, 크기만 텍스처 scale 배 (2D 와 상대 크기 일치).\n const fontSize = (Number((this.component as any).state?.fontSize) || 15) * scale\n const font = this.gaugeFont(fontSize)\n let x = pad\n for (const seg of gauge.segments) {\n const segW = Math.max(innerW * seg.ratio, seg.ratio > 0 ? 1 : 0)\n if (segW <= 0) continue\n ctx.fillStyle = seg.color\n ctx.fillRect(x, pad, segW, innerH)\n if (gauge.perSegment) {\n this.drawGaugeSegmentNumber(ctx, seg.ratio, x, pad, segW, innerH, font, fontSize)\n }\n x += segW\n }\n\n // capacity: 전체 중앙에 usage% 한 개 (2D 와 동일). carrier/abnormal 은 위 세그먼트별 숫자 사용.\n if (gauge.label) {\n ctx.font = font\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = '#333333'\n ctx.fillText(gauge.label, canvasW / 2, canvasH / 2)\n }\n\n // 텍스처 → Plane\n const texture = new THREE.CanvasTexture(canvas)\n texture.colorSpace = THREE.SRGBColorSpace\n\n const geo = new THREE.PlaneGeometry(barW, barH)\n geo.rotateX(-Math.PI / 2) // 수평 (지붕 위)\n if (!isWidthLonger) geo.rotateY(Math.PI / 2)\n\n const mat = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n side: THREE.DoubleSide,\n })\n mat.polygonOffset = true\n mat.polygonOffsetFactor = -2\n mat.polygonOffsetUnit = -2\n\n this.gaugeMesh = new THREE.Mesh(geo, mat)\n // ownGroup 기준(bottom-up): 볼륨 상단 = +depth. 그 위로 0.5 띄움.\n this.gaugeMesh.position.set(0, depth + 0.5, 0)\n this.components3D.add(this.gaugeMesh)\n }\n\n private resolveGauge(\n data: any,\n mode: string\n ): { segments: { ratio: number; color: string }[]; borderColor: string; label: string | null; perSegment: boolean } {\n switch (mode) {\n case 'carrier': {\n // 세그먼트 비율/색상은 2D 와 공유되는 단일 소스에서 계산 (필드/색상 drift 방지).\n // 색상은 carrier 컴포넌트와 동일한 legend(테마)에서 취득.\n const colors = carrierColorsFromLegend(resolveCarrierLegend(this.component))\n const [f, e, ee] = carrierSegmentsFromData(data, colors)\n const total = f.count + e.count + ee.count\n // 접두사 없는 세그먼트별 숫자(%)로 표기 (capacity·2D 와 동일). label(중앙 한 개) 미사용.\n return total > 0\n ? {\n segments: [f, e, ee].map(s => ({ ratio: s.ratio, color: s.color })),\n borderColor: colors.full,\n label: null,\n perSegment: true,\n }\n : { segments: [{ ratio: 1, color: '#dddddd' }], borderColor: colors.full, label: null, perSegment: false }\n }\n case 'abnormal': {\n const [n, a] = abnormalSegmentsFromData(data)\n const total = n.count + a.count\n return total > 0\n ? {\n segments: [n, a].map(s => ({ ratio: s.ratio, color: s.color })),\n borderColor: a.count > 0 ? ABNORMAL_COLORS.abnormal : ABNORMAL_COLORS.normal,\n label: null,\n perSegment: true,\n }\n : {\n segments: [{ ratio: 1, color: '#dddddd' }],\n borderColor: ABNORMAL_COLORS.normal,\n label: null,\n perSegment: false,\n }\n }\n default: { // capacity — 전체 중앙에 usage% 한 개\n const cur = Number(data.CURRENTCAPACITY) || 0\n const max = Number(data.MAXCAPACITY) || 100\n const fullup = data.FULLUP === 'T'\n const usage = Math.round((cur / max) * 100)\n const legend = (this.component as any).root?.stockerCapacityLegendTheme || LEGEND_CAPACITY\n const color = fullup ? 'red' : (legendColor(legendRangeEntryOf(usage, legend)) || '#44aa44')\n return {\n segments: [{ ratio: usage / 100, color }],\n borderColor: color,\n label: `${usage}%`,\n perSegment: false,\n }\n }\n }\n }\n\n /** 컴포넌트 폰트 설정(fontFamily/bold/italic)으로 CSS font 문자열 조합. size 는 텍스처 스케일 반영값. */\n private gaugeFont(sizePx: number): string {\n const st = (this.component as any).state || {}\n const parts: string[] = []\n if (st.bold) parts.push('bold')\n if (st.italic) parts.push('italic')\n parts.push(`${sizePx}px`)\n parts.push(st.fontFamily || 'sans-serif')\n return parts.join(' ')\n }\n\n /** 세그먼트 영역 중심에 숫자(%)만 표기. 좁으면 값% → 값 → 생략 (2D _drawSegmentLabel 과 동일 정책). */\n private drawGaugeSegmentNumber(\n ctx: CanvasRenderingContext2D,\n ratio: number,\n x: number,\n y: number,\n w: number,\n h: number,\n font: string,\n fontSize: number\n ) {\n ctx.font = font\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = '#333333'\n const value = `${Math.round(ratio * 100)}`\n const cx = x + w / 2\n const cy = y + h / 2\n if (fontSize <= h && ctx.measureText(`${value}%`).width <= w) {\n ctx.fillText(`${value}%`, cx, cy)\n } else if (fontSize <= h && ctx.measureText(value).width <= w) {\n ctx.fillText(value, cx, cy)\n }\n }\n\n update() {\n this.clearGauge()\n super.update()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('data' in after) {\n this.clearGauge()\n this.buildGauge()\n }\n super.onchange(after, before)\n }\n\n clear() {\n this.clearGauge()\n return super.clear()\n }\n\n private clearGauge() {\n if (this.gaugeMesh) {\n this.components3D.remove(this.gaugeMesh)\n this.gaugeMesh.geometry?.dispose()\n const mat = this.gaugeMesh.material as THREE.MeshBasicMaterial\n mat?.map?.dispose()\n mat?.dispose()\n this.gaugeMesh = undefined\n }\n }\n}\n\nregisterRealObjectFactory('STOCKER', (component: Component) => new StockerRealObject3D(component))\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Unit (이동체 · 홀더) — 낮은 depth, 불투명\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n// Port: 바닥판 (PlaneGeometry)\nconst PORT_CONFIG: MCS3DConfig = {\n ...DEFAULTS,\n depthRatio: 0.01,\n defaultZPosFromParent: true,\n opacity: 0.1,\n metalness: 0.3,\n roughness: 0.8,\n defaultColor: 0xb0a090,\n shape: 'plane',\n zPriority: Z_FMSIM.PORT,\n}\nregisterRealObjectFactory('Port', (component: Component) => new MCSRealObject3D(component, PORT_CONFIG))\n\nregister('Shelf', {\n depthRatio: 0.25,\n metalness: 0.3,\n roughness: 0.7,\n defaultColor: 0xaabbcc,\n zPriority: Z_FMSIM.SHELF,\n})\n\n// Carrier: CARRIERSTATUS에 따른 3D 애니메이션 지원\nconst CARRIER_CONFIG: MCS3DConfig = {\n ...DEFAULTS,\n depthRatio: 0.5,\n metalness: 0,\n roughness: 1,\n defaultColor: 0xf0f0f0,\n isVisible: (c: Component) => !!(c.state as any).id,\n sizeRatio: 0.8,\n texturedTop: true,\n // Carrier 는 이동 entity — default OBJECTS(0). zPriority 미설정.\n}\n\n/**\n * Carrier 의 3D. 홀더가 자리에 앉힌다 (공통 아이템 계약 3.4): 위치·회전은 홀더의 Anchor 노드 위 안착이고, 크기는 홀더가\n * 보이는 치수(타입의 선언 치수, 모르면 자리의 표시용 상자)다. 자리 안에 들도록 줄이는 배율도 홀더가 준다.\n */\nclass CarrierRealObject3D extends MCSRealObject3D {\n constructor(component: Component) {\n super(component, CARRIER_CONFIG)\n }\n\n /** 홀더가 보이는 치수 (도면 단위): 폭(X)·깊이(도면 Z)·높이. 모르면 null */\n private get shown(): { w: number; d: number; h: number } | null {\n const holder = this.component.parent as any\n const dims = holder?.carrierShownDimsOf?.(this.component)\n const k = holder?.mmPerSceneUnit\n if (!dims || !(k > 0)) return null\n return { w: dims.width / k, d: dims.depth / k, h: dims.height / k }\n }\n\n /** build 가 sizeRatio 를 곱하므로 미리 나눈다 */\n protected override get absSize(): { w: number; h: number } {\n const shown = this.shown\n if (!shown) return super.absSize\n const ratio = CARRIER_CONFIG.sizeRatio ?? 1\n return { w: shown.w / ratio, h: shown.d / ratio }\n }\n\n override get effectiveDepth(): number {\n const shown = this.shown\n if (!shown) return super.effectiveDepth\n return shown.h / (CARRIER_CONFIG.sizeRatio ?? 1)\n }\n}\n\nregisterRealObjectFactory('Carrier', (component: Component) => new CarrierRealObject3D(component))\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Gauge (용량 게이지) — 얇은 바\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Gauge (용량 게이지) — 2D 렌더링을 Plane 텍스처로 3D 표시\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n// Gauge 컴포넌트는 3D에서 표시하지 않음 (부모 STOCKER의 3D 모델에서 직접 게이지 렌더링)\n// null 반환으로 3D 오브젝트 생성을 억제하고, default factory fallback도 방지\nregisterRealObjectFactory('StockerCapacityBar', () => undefined as any)\nregisterRealObjectFactory('MCSGaugeCapacityBar', () => undefined as any)\nregisterRealObjectFactory('ZoneCapacityBar', () => undefined as any)\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// PortFlow — 2D render를 Plane 텍스처로 3D 표시\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nclass PortFlowRealObject3D extends RealObjectGroup {\n private _mesh?: THREE.Mesh\n private _texture?: THREE.CanvasTexture\n\n get zPriority(): number { return Z_FMSIM.PORT_FLOW }\n get effectiveDepth(): number { return 0 }\n protected get syncZPosOffset(): number {\n // 부모 Port/Conveyor의 zPos와 동일하게\n const parent = (this.component as any).parentObject\n if (parent?.state?.zPos != null) return parent.state.zPos\n return TRANSPORT_SURFACE_HEIGHT\n }\n\n build() {\n super.build()\n\n const { width = 10, height = 10 } = this.component.state\n const w = Math.abs(width)\n const h = Math.abs(height)\n if (!w || !h) return\n\n // 2D render를 캔버스에 캡처\n // 화살표 날개 + 텍스트 영역이 bounds 밖으로 나가므로 전체 영역 계산\n const { left, top } = this.component.bounds\n const { fontSize = 24, labelPosition = 'top' } = this.component.state\n const arrowPad = Math.min(w, h) * 0.4\n\n // 텍스트 영역 확장\n let padLeft = arrowPad, padRight = arrowPad, padTop = arrowPad, padBottom = arrowPad\n if ((this.component as any).hasTextProperty) {\n switch (labelPosition) {\n case 'top': padTop = Math.max(padTop, fontSize + 4); break\n case 'bottom': padBottom = Math.max(padBottom, fontSize + 4); break\n case 'left': padLeft = Math.max(padLeft, fontSize * 4 + 4); break\n case 'right': padRight = Math.max(padRight, fontSize * 4 + 4); break\n }\n }\n\n const totalW = w + padLeft + padRight\n const totalH = h + padTop + padBottom\n const scale = 2\n const canvas = document.createElement('canvas')\n canvas.width = totalW * scale\n canvas.height = totalH * scale\n const ctx = canvas.getContext('2d')!\n\n ctx.save()\n ctx.scale(scale, scale)\n ctx.translate(-left + padLeft, -top + padTop)\n try {\n // 화살표 렌더\n this.component.render(ctx)\n ctx.fillStyle = this.component.state.strokeStyle || '#666666'\n ctx.fill()\n // 텍스트 렌더\n if ((this.component as any).hasTextProperty && (this.component as any).drawText) {\n ;(this.component as any).drawText(ctx)\n }\n } catch { /* render 실패 시 빈 텍스처 */ }\n ctx.restore()\n\n this._texture = new THREE.CanvasTexture(canvas)\n this._texture.colorSpace = THREE.SRGBColorSpace\n\n const geo = new THREE.PlaneGeometry(totalW, totalH)\n geo.rotateX(-Math.PI / 2)\n\n const mat = new THREE.MeshBasicMaterial({\n map: this._texture,\n alphaTest: 0.1,\n side: THREE.DoubleSide,\n })\n\n this._mesh = new THREE.Mesh(geo, mat)\n // 비대칭 패딩 보정: 플레인 센터를 컴포넌트 bounds 센터에 맞춤\n this._mesh.position.x = (padRight - padLeft) / 2\n this._mesh.position.y = 1\n this._mesh.position.z = (padBottom - padTop) / 2\n this.object3d.add(this._mesh)\n }\n\n update() {\n if (this._mesh) {\n this.object3d.remove(this._mesh)\n this._mesh.geometry.dispose()\n ;(this._mesh.material as THREE.Material).dispose()\n this._texture?.dispose()\n this._mesh = undefined\n this._texture = undefined\n }\n this.build()\n this.updateTransform()\n this.updateHidden()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('width' in after || 'height' in after || 'orientation' in after ||\n 'direction' in after || 'strokeStyle' in after || 'INOUTTYPE' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateDimension() {}\n updateAlpha() {}\n}\n\nregisterRealObjectFactory('PortFlow', (component: Component) => new PortFlowRealObject3D(component))\n\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// Node — 2D render를 바닥 Plane 텍스처로 3D 표시\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nclass NodeRealObject3D extends RealObjectGroup {\n private _mesh?: THREE.Mesh\n private _texture?: THREE.CanvasTexture\n\n get zPriority(): number { return Z_FMSIM.NODE }\n get effectiveDepth(): number { return 0 }\n protected get syncZPosOffset(): number { return 0 }\n\n build() {\n super.build()\n\n const { cx, cy } = this.component.state\n const radius = 8\n const size = radius * 2\n const scale = 2\n const pad = 2\n\n const canvas = document.createElement('canvas')\n canvas.width = (size + pad * 2) * scale\n canvas.height = (size + pad * 2) * scale\n const ctx = canvas.getContext('2d')!\n\n ctx.save()\n ctx.scale(scale, scale)\n ctx.translate(-cx + radius + pad, -cy + radius + pad)\n try {\n this.component.render(ctx)\n const { fillStyle = '#888888' } = this.component.state\n ctx.fillStyle = typeof fillStyle === 'string' ? fillStyle : '#888888'\n ctx.fill()\n const { strokeStyle } = this.component.state\n if (strokeStyle && typeof strokeStyle === 'string') {\n ctx.strokeStyle = strokeStyle\n ctx.lineWidth = 1\n ctx.stroke()\n }\n } catch { /* render 실패 시 빈 텍스처 */ }\n ctx.restore()\n\n this._texture = new THREE.CanvasTexture(canvas)\n this._texture.colorSpace = THREE.SRGBColorSpace\n\n const geo = new THREE.PlaneGeometry(size + pad * 2, size + pad * 2)\n geo.rotateX(-Math.PI / 2)\n\n const mat = new THREE.MeshBasicMaterial({\n map: this._texture,\n alphaTest: 0.1,\n side: THREE.DoubleSide,\n })\n\n this._mesh = new THREE.Mesh(geo, mat)\n this._mesh.position.y = 1\n this.object3d.add(this._mesh)\n }\n\n update() {\n if (this._mesh) {\n this.object3d.remove(this._mesh)\n this._mesh.geometry.dispose()\n ;(this._mesh.material as THREE.Material).dispose()\n this._texture?.dispose()\n this._mesh = undefined\n this._texture = undefined\n }\n this.build()\n this.updateTransform()\n this.updateHidden()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('fillStyle' in after || 'strokeStyle' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateDimension() {}\n updateAlpha() {}\n}\n\nregisterRealObjectFactory('Node', (component: Component) => new NodeRealObject3D(component))\n\n// Scanner — 2D Triangle 실루엣과 정합되는 삼각형 prism.\n// 이송 표면 높이의 0.2배(=6) 얇은 기둥 — 원래 값 유지, shape 만 'box' → 'triangle'.\nconst SCANNER_CONFIG: MCS3DConfig = {\n ...DEFAULTS,\n defaultDepth: TRANSPORT_SURFACE_HEIGHT * 0.2,\n defaultZPosFromParent: true,\n opacity: 1,\n metalness: 0.3,\n roughness: 0.7,\n defaultColor: 0x888888,\n shape: 'triangle',\n zPriority: Z_FMSIM.SCANNER,\n}\nregisterRealObjectFactory('Scanner', (component: Component) => new MCSRealObject3D(component, SCANNER_CONFIG))\n"]}
@@ -13,11 +13,10 @@ import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUti
13
13
  import { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry.js';
14
14
  import { RealObjectGroup, registerRealObjectFactory, disposeObject3D, MaterialBank } from '@hatiolab/things-scene';
15
15
  import { TRANSPORT_SURFACE_HEIGHT } from './machine-3d.js';
16
+ import { ohtRailTop } from '../features/oht-rail.js';
16
17
  const TROLLEY_COLOR = 0x222222;
17
18
  const FRAME_COLOR = 0x444444;
18
19
  const DEFAULT_BODY_COLOR = 0x6688cc;
19
- /** OHT 레일 높이: 스토커(5x) 위 */
20
- const OHT_RAIL_HEIGHT = 6 * TRANSPORT_SURFACE_HEIGHT;
21
20
  export class OHT3D extends RealObjectGroup {
22
21
  constructor() {
23
22
  super(...arguments);
@@ -27,9 +26,9 @@ export class OHT3D extends RealObjectGroup {
27
26
  const { depth } = this.component.state;
28
27
  return depth || TRANSPORT_SURFACE_HEIGHT;
29
28
  }
30
- /** 천장 레일 높이에 배치 (center origin 기준: 레일 높이 + 볼륨 중심 반깊이) */
29
+ /** 자기 라인의 레일에 상단을 매단다 (center origin 기준: 레일 윗면 − 볼륨 중심 반깊이) */
31
30
  get syncZPosOffset() {
32
- return OHT_RAIL_HEIGHT + this.effectiveDepth / 2;
31
+ return ohtRailTop(this.component) - this.effectiveDepth / 2;
33
32
  }
34
33
  resolveColor() {
35
34
  const comp = this.component;
@@ -1 +1 @@
1
- {"version":3,"file":"oht-3d.js","sourceRoot":"","sources":["../../src/factories/oht-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OHT (Overhead Hoist Transport) 3D Factory\n *\n * 천장 레일에 매달려 이동하는 반송 차량. 캐리어를 호이스트로 운반.\n * 구조 (바닥 원점, y=0~depth):\n * - 하단 그리퍼 바 (캐리어 집는 가로 바)\n * - 호이스트 암 (좌우 수직 기둥)\n * - 본체 하우징 (statusColor 적용)\n * - 상단 트롤리 (납작+넓은 레일 클램프 + 좌우 바퀴)\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry.js'\nimport { RealObjectGroup, registerRealObjectFactory, disposeObject3D, MaterialBank } from '@hatiolab/things-scene'\nimport type { Component } from '@hatiolab/things-scene'\nimport { TRANSPORT_SURFACE_HEIGHT } from './machine-3d.js'\n\nconst TROLLEY_COLOR = 0x222222\nconst FRAME_COLOR = 0x444444\nconst DEFAULT_BODY_COLOR = 0x6688cc\n\n/** OHT 레일 높이: 스토커(5x) 위 */\nconst OHT_RAIL_HEIGHT = 6 * TRANSPORT_SURFACE_HEIGHT\n\nexport class OHT3D extends RealObjectGroup {\n private _ownMeshes: THREE.Mesh[] = []\n get effectiveDepth(): number {\n const { depth } = this.component.state\n return depth || TRANSPORT_SURFACE_HEIGHT\n }\n\n /** 천장 레일 높이에 배치 (center origin 기준: 레일 높이 + 볼륨 중심 반깊이) */\n protected get syncZPosOffset(): number {\n return OHT_RAIL_HEIGHT + this.effectiveDepth / 2\n }\n\n private resolveColor(): number {\n const comp = this.component as any\n\n try {\n const sc = comp.statusColor\n if (typeof sc === 'string' && sc && sc.toUpperCase() !== '#F0F0F0') return new THREE.Color(sc).getHex()\n } catch {\n /* statusColor 미구현 시 무시 */\n }\n\n const { fillStyle } = this.component.state\n if (fillStyle && typeof fillStyle === 'string') {\n try {\n return new THREE.Color(fillStyle).getHex()\n } catch {\n /* 파싱 실패 시 무시 */\n }\n }\n\n return DEFAULT_BODY_COLOR\n }\n\n build() {\n super.build()\n\n const { width = 10, height = 10 } = this.component.state\n const w = Math.abs(width)\n const h = Math.abs(height)\n const d = this.effectiveDepth\n if (!w || !h) return\n\n // 높이 배분: 그리퍼 8%, 호이스트암 22%, 본체 45%, 간격 5%, 트롤리 12%, 바퀴 8%\n const gripperBarH = d * 0.08\n const armH = d * 0.22\n const bodyH = d * 0.45\n const gap = d * 0.05\n const trolleyH = d * 0.12\n const wheelH = d * 0.08\n\n const armThickness = Math.min(w, h) * 0.12\n const bodyCornerR = Math.min(w, h, bodyH) * 0.1\n\n // MaterialBank 공유 — dedup + faint 안전(코어 변형 스왑, disposeObject3D 가 __bankOwned 스킵).\n const frameMat = MaterialBank.material('oht|frame', { roughness: 0.5, metalness: 0.4 }, FRAME_COLOR)\n\n // ── 1. 하단 그리퍼 바 (캐리어를 집는 가로 바 — 이동 방향과 직교) ──\n const gripperBarW = w * 0.7\n const gripperBarD = h * 0.15\n const gripperGeo = new THREE.BoxGeometry(gripperBarW, gripperBarH, gripperBarD)\n const gripperMesh = new THREE.Mesh(gripperGeo, frameMat)\n gripperMesh.position.y = gripperBarH / 2\n gripperMesh.castShadow = true\n\n // ── 2. 호이스트 암 (전후 수직 기둥 + 하단 연결 바) ──\n const armBaseY = gripperBarH\n const armGeometries: THREE.BufferGeometry[] = []\n\n // 전후 수직 기둥 (레일 방향 = Z축)\n for (const zSign of [-1, 1]) {\n const pillar = new THREE.BoxGeometry(armThickness, armH, armThickness)\n pillar.translate(0, armBaseY + armH / 2, zSign * (h * 0.3))\n armGeometries.push(pillar)\n }\n\n // 하단 연결 바 (레일 방향으로 연결)\n const crossBarD = h * 0.6 + armThickness\n const crossBarH = armThickness * 0.6\n const crossBar = new THREE.BoxGeometry(armThickness, crossBarH, crossBarD)\n crossBar.translate(0, armBaseY + crossBarH / 2, 0)\n armGeometries.push(crossBar)\n\n const armMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(armGeometries), frameMat)\n armMesh.castShadow = true\n\n // ── 3. 본체 하우징 (statusColor 적용) ──\n const bodyBaseY = armBaseY + armH\n const bodyColor = this.resolveColor()\n const bodyGeo = new RoundedBoxGeometry(w, bodyH, h, 4, bodyCornerR)\n const bodyMat = MaterialBank.material('oht|body', { roughness: 0.3, metalness: 0.5 }, bodyColor)\n const bodyMesh = new THREE.Mesh(bodyGeo, bodyMat)\n bodyMesh.position.y = bodyBaseY + bodyH / 2\n bodyMesh.castShadow = true\n bodyMesh.receiveShadow = true\n\n // ── 4. 상단 트롤리 플레이트 (레일 방향으로 길게 — Z축) ──\n const trolleyBaseY = bodyBaseY + bodyH + gap\n const trolleyW = w * 0.6\n const trolleyD = h * 1.15\n const trolleyGeo = new THREE.BoxGeometry(trolleyW, trolleyH, trolleyD)\n const trolleyMat = MaterialBank.material('oht|trolley', { roughness: 0.6, metalness: 0.3 }, TROLLEY_COLOR)\n const trolleyMesh = new THREE.Mesh(trolleyGeo, trolleyMat)\n trolleyMesh.position.y = trolleyBaseY + trolleyH / 2\n trolleyMesh.castShadow = true\n\n // ── 5. 전후 바퀴 (트롤리 위, 레일 방향 = Z축) ──\n const wheelBaseY = trolleyBaseY + trolleyH\n const wheelRadius = wheelH / 2\n const wheelDepth = w * 0.2\n const wheelMeshes: THREE.Mesh[] = []\n for (const zSign of [-1, 1]) {\n const wheelGeo = new THREE.CylinderGeometry(wheelRadius, wheelRadius, wheelDepth, 12)\n wheelGeo.rotateZ(Math.PI / 2)\n const wheelMesh = new THREE.Mesh(wheelGeo, trolleyMat)\n wheelMesh.position.set(0, wheelBaseY + wheelRadius, zSign * (trolleyD * 0.35))\n wheelMesh.castShadow = true\n wheelMeshes.push(wheelMesh)\n }\n\n this._ownMeshes = [gripperMesh, armMesh, bodyMesh, trolleyMesh, ...wheelMeshes]\n for (const m of this._ownMeshes) this.components3D.add(m)\n\n // mesh 는 super.build() 이후 생성 → 코어 faint 를 명시 적용(편집 흐림이 mesh 에 닿게).\n this.updateAlpha()\n }\n\n updateDimension() {}\n\n update() {\n for (const m of this._ownMeshes) {\n this.components3D.remove(m)\n disposeObject3D(m)\n }\n this._ownMeshes = []\n this.build()\n this.updateTransform()\n this.updateAlpha()\n this.updateHidden()\n }\n\n // updateAlpha override 제거 — 코어 RealObject.updateAlpha(=applyMaterialOpacity)로 수렴.\n // canonical(bank base opacity 1) × state.alpha × faint. view 모드 불변, 편집 모드 faint 추가.\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('width' in after || 'height' in after || 'depth' in after ||\n 'fillStyle' in after || 'strokeStyle' in after || 'id' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n}\n\nregisterRealObjectFactory('OHT', (component: Component) => new OHT3D(component))\n"]}
1
+ {"version":3,"file":"oht-3d.js","sourceRoot":"","sources":["../../src/factories/oht-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OHT (Overhead Hoist Transport) 3D Factory\n *\n * 천장 레일에 매달려 이동하는 반송 차량. 캐리어를 호이스트로 운반.\n * 구조 (바닥 원점, y=0~depth):\n * - 하단 그리퍼 바 (캐리어 집는 가로 바)\n * - 호이스트 암 (좌우 수직 기둥)\n * - 본체 하우징 (statusColor 적용)\n * - 상단 트롤리 (납작+넓은 레일 클램프 + 좌우 바퀴)\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry.js'\nimport { RealObjectGroup, registerRealObjectFactory, disposeObject3D, MaterialBank } from '@hatiolab/things-scene'\nimport type { Component } from '@hatiolab/things-scene'\nimport { TRANSPORT_SURFACE_HEIGHT } from './machine-3d.js'\nimport { ohtRailTop } from '../features/oht-rail.js'\n\nconst TROLLEY_COLOR = 0x222222\nconst FRAME_COLOR = 0x444444\nconst DEFAULT_BODY_COLOR = 0x6688cc\n\nexport class OHT3D extends RealObjectGroup {\n private _ownMeshes: THREE.Mesh[] = []\n get effectiveDepth(): number {\n const { depth } = this.component.state\n return depth || TRANSPORT_SURFACE_HEIGHT\n }\n\n /** 자기 라인의 레일에 상단을 매단다 (center origin 기준: 레일 윗면 − 볼륨 중심 반깊이) */\n protected get syncZPosOffset(): number {\n return ohtRailTop(this.component) - this.effectiveDepth / 2\n }\n\n private resolveColor(): number {\n const comp = this.component as any\n\n try {\n const sc = comp.statusColor\n if (typeof sc === 'string' && sc && sc.toUpperCase() !== '#F0F0F0') return new THREE.Color(sc).getHex()\n } catch {\n /* statusColor 미구현 시 무시 */\n }\n\n const { fillStyle } = this.component.state\n if (fillStyle && typeof fillStyle === 'string') {\n try {\n return new THREE.Color(fillStyle).getHex()\n } catch {\n /* 파싱 실패 시 무시 */\n }\n }\n\n return DEFAULT_BODY_COLOR\n }\n\n build() {\n super.build()\n\n const { width = 10, height = 10 } = this.component.state\n const w = Math.abs(width)\n const h = Math.abs(height)\n const d = this.effectiveDepth\n if (!w || !h) return\n\n // 높이 배분: 그리퍼 8%, 호이스트암 22%, 본체 45%, 간격 5%, 트롤리 12%, 바퀴 8%\n const gripperBarH = d * 0.08\n const armH = d * 0.22\n const bodyH = d * 0.45\n const gap = d * 0.05\n const trolleyH = d * 0.12\n const wheelH = d * 0.08\n\n const armThickness = Math.min(w, h) * 0.12\n const bodyCornerR = Math.min(w, h, bodyH) * 0.1\n\n // MaterialBank 공유 — dedup + faint 안전(코어 변형 스왑, disposeObject3D 가 __bankOwned 스킵).\n const frameMat = MaterialBank.material('oht|frame', { roughness: 0.5, metalness: 0.4 }, FRAME_COLOR)\n\n // ── 1. 하단 그리퍼 바 (캐리어를 집는 가로 바 — 이동 방향과 직교) ──\n const gripperBarW = w * 0.7\n const gripperBarD = h * 0.15\n const gripperGeo = new THREE.BoxGeometry(gripperBarW, gripperBarH, gripperBarD)\n const gripperMesh = new THREE.Mesh(gripperGeo, frameMat)\n gripperMesh.position.y = gripperBarH / 2\n gripperMesh.castShadow = true\n\n // ── 2. 호이스트 암 (전후 수직 기둥 + 하단 연결 바) ──\n const armBaseY = gripperBarH\n const armGeometries: THREE.BufferGeometry[] = []\n\n // 전후 수직 기둥 (레일 방향 = Z축)\n for (const zSign of [-1, 1]) {\n const pillar = new THREE.BoxGeometry(armThickness, armH, armThickness)\n pillar.translate(0, armBaseY + armH / 2, zSign * (h * 0.3))\n armGeometries.push(pillar)\n }\n\n // 하단 연결 바 (레일 방향으로 연결)\n const crossBarD = h * 0.6 + armThickness\n const crossBarH = armThickness * 0.6\n const crossBar = new THREE.BoxGeometry(armThickness, crossBarH, crossBarD)\n crossBar.translate(0, armBaseY + crossBarH / 2, 0)\n armGeometries.push(crossBar)\n\n const armMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(armGeometries), frameMat)\n armMesh.castShadow = true\n\n // ── 3. 본체 하우징 (statusColor 적용) ──\n const bodyBaseY = armBaseY + armH\n const bodyColor = this.resolveColor()\n const bodyGeo = new RoundedBoxGeometry(w, bodyH, h, 4, bodyCornerR)\n const bodyMat = MaterialBank.material('oht|body', { roughness: 0.3, metalness: 0.5 }, bodyColor)\n const bodyMesh = new THREE.Mesh(bodyGeo, bodyMat)\n bodyMesh.position.y = bodyBaseY + bodyH / 2\n bodyMesh.castShadow = true\n bodyMesh.receiveShadow = true\n\n // ── 4. 상단 트롤리 플레이트 (레일 방향으로 길게 — Z축) ──\n const trolleyBaseY = bodyBaseY + bodyH + gap\n const trolleyW = w * 0.6\n const trolleyD = h * 1.15\n const trolleyGeo = new THREE.BoxGeometry(trolleyW, trolleyH, trolleyD)\n const trolleyMat = MaterialBank.material('oht|trolley', { roughness: 0.6, metalness: 0.3 }, TROLLEY_COLOR)\n const trolleyMesh = new THREE.Mesh(trolleyGeo, trolleyMat)\n trolleyMesh.position.y = trolleyBaseY + trolleyH / 2\n trolleyMesh.castShadow = true\n\n // ── 5. 전후 바퀴 (트롤리 위, 레일 방향 = Z축) ──\n const wheelBaseY = trolleyBaseY + trolleyH\n const wheelRadius = wheelH / 2\n const wheelDepth = w * 0.2\n const wheelMeshes: THREE.Mesh[] = []\n for (const zSign of [-1, 1]) {\n const wheelGeo = new THREE.CylinderGeometry(wheelRadius, wheelRadius, wheelDepth, 12)\n wheelGeo.rotateZ(Math.PI / 2)\n const wheelMesh = new THREE.Mesh(wheelGeo, trolleyMat)\n wheelMesh.position.set(0, wheelBaseY + wheelRadius, zSign * (trolleyD * 0.35))\n wheelMesh.castShadow = true\n wheelMeshes.push(wheelMesh)\n }\n\n this._ownMeshes = [gripperMesh, armMesh, bodyMesh, trolleyMesh, ...wheelMeshes]\n for (const m of this._ownMeshes) this.components3D.add(m)\n\n // mesh 는 super.build() 이후 생성 → 코어 faint 를 명시 적용(편집 흐림이 mesh 에 닿게).\n this.updateAlpha()\n }\n\n updateDimension() {}\n\n update() {\n for (const m of this._ownMeshes) {\n this.components3D.remove(m)\n disposeObject3D(m)\n }\n this._ownMeshes = []\n this.build()\n this.updateTransform()\n this.updateAlpha()\n this.updateHidden()\n }\n\n // updateAlpha override 제거 — 코어 RealObject.updateAlpha(=applyMaterialOpacity)로 수렴.\n // canonical(bank base opacity 1) × state.alpha × faint. view 모드 불변, 편집 모드 faint 추가.\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('width' in after || 'height' in after || 'depth' in after ||\n 'fillStyle' in after || 'strokeStyle' in after || 'id' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n}\n\nregisterRealObjectFactory('OHT', (component: Component) => new OHT3D(component))\n"]}
@@ -0,0 +1,29 @@
1
+ import { themesColorMap, themesColorRange, themesAnimationMap } from '@fmsim/api';
2
+ import { legendRows } from '@fmsim/figure-capabilities';
3
+ import { legendRowsOnBoard } from './legend-rows';
4
+ /** The options a row's legend select offers: the board's legends of its kind. */
5
+ const LEGEND_OPTIONS = {
6
+ 'color-map': themesColorMap,
7
+ 'color-ranges': themesColorRange,
8
+ 'animation-map': themesAnimationMap
9
+ };
10
+ const legendSelect = (row) => ({ type: 'select', label: row.label, name: row.property, property: { options: LEGEND_OPTIONS[row.kind] } });
11
+ const legendHeader = (name, label) => ({ type: 'legend', label: '', name, property: { label } });
12
+ /**
13
+ * The board's LEGENDS panel, drawn from the registered rows (ADR-0167 decision 20): the rows the board's components
14
+ * follow first, then the others; the stocker's rows apart, as they were.
15
+ */
16
+ export function legendPanel(board) {
17
+ const used = legendRowsOnBoard(board);
18
+ const rows = legendRows().filter(row => row.section !== 'stocker');
19
+ const here = rows.filter(row => used.has(row.name));
20
+ const others = rows.filter(row => !used.has(row.name));
21
+ const stocker = legendRows().filter(row => row.section === 'stocker');
22
+ return [
23
+ legendHeader('LEGENDS', 'LEGENDS'),
24
+ ...here.map(legendSelect),
25
+ ...(others.length ? [legendHeader('LEGENDS-OTHERS', 'LEGENDS · NOT ON THIS BOARD'), ...others.map(legendSelect)] : []),
26
+ ...(stocker.length ? [legendHeader('LEGENDS-STOCKER', 'LEGENDS · STOCKER'), ...stocker.map(legendSelect)] : [])
27
+ ];
28
+ }
29
+ //# sourceMappingURL=legend-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legend-panel.js","sourceRoot":"","sources":["../../src/features/legend-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AACjF,OAAO,EAAE,UAAU,EAAkB,MAAM,4BAA4B,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEjD,iFAAiF;AACjF,MAAM,cAAc,GAAuC;IACzD,WAAW,EAAE,cAAc;IAC3B,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,kBAAkB;CACpC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,GAAc,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;AACpJ,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;AAEhH;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAU;IACpC,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;IACrC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAA;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IACtD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAA;IACrE,OAAO;QACL,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC;QAClC,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;QACzB,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,gBAAgB,EAAE,6BAA6B,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtH,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAChH,CAAA;AACH,CAAC","sourcesContent":["import { themesColorMap, themesColorRange, themesAnimationMap } from '@fmsim/api'\nimport { legendRows, type LegendRow } from '@fmsim/figure-capabilities'\nimport { legendRowsOnBoard } from './legend-rows'\n\n/** The options a row's legend select offers: the board's legends of its kind. */\nconst LEGEND_OPTIONS: Record<LegendRow['kind'], unknown> = {\n 'color-map': themesColorMap,\n 'color-ranges': themesColorRange,\n 'animation-map': themesAnimationMap\n}\n\nconst legendSelect = (row: LegendRow) => ({ type: 'select', label: row.label, name: row.property, property: { options: LEGEND_OPTIONS[row.kind] } })\nconst legendHeader = (name: string, label: string) => ({ type: 'legend', label: '', name, property: { label } })\n\n/**\n * The board's LEGENDS panel, drawn from the registered rows (ADR-0167 decision 20): the rows the board's components\n * follow first, then the others; the stocker's rows apart, as they were.\n */\nexport function legendPanel(board: any): any[] {\n const used = legendRowsOnBoard(board)\n const rows = legendRows().filter(row => row.section !== 'stocker')\n const here = rows.filter(row => used.has(row.name))\n const others = rows.filter(row => !used.has(row.name))\n const stocker = legendRows().filter(row => row.section === 'stocker')\n return [\n legendHeader('LEGENDS', 'LEGENDS'),\n ...here.map(legendSelect),\n ...(others.length ? [legendHeader('LEGENDS-OTHERS', 'LEGENDS · NOT ON THIS BOARD'), ...others.map(legendSelect)] : []),\n ...(stocker.length ? [legendHeader('LEGENDS-STOCKER', 'LEGENDS · STOCKER'), ...stocker.map(legendSelect)] : [])\n ]\n}\n"]}