@2112-lab/central-plant 0.3.47 → 0.3.49

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.
@@ -20,7 +20,7 @@ var ComponentManager = /*#__PURE__*/function () {
20
20
  key: "addComponentToScene",
21
21
  value: (function () {
22
22
  var _addComponentToScene = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(componentData) {
23
- var _gltfScene$userData, uuid, componentDictionary, libraryComponent, position, gltfScene, componentMesh, event, _t, _t2;
23
+ var _gltfScene$userData, uuid, componentDictionary, libraryComponent, position, gltfScene, componentMesh, connectorIndex, event, _t, _t2;
24
24
  return _regenerator().w(function (_context) {
25
25
  while (1) switch (_context.n) {
26
26
  case 0:
@@ -124,6 +124,7 @@ var ComponentManager = /*#__PURE__*/function () {
124
124
  }
125
125
 
126
126
  // Enable shadows for all meshes in the component
127
+ connectorIndex = 0;
127
128
  componentMesh.traverse(function (child) {
128
129
  if (child.isMesh) {
129
130
  child.castShadow = true;
@@ -133,12 +134,19 @@ var ComponentManager = /*#__PURE__*/function () {
133
134
  }
134
135
 
135
136
  // Set connector properties for connectors within the component
136
- if (child.name && child.name.toLowerCase().includes('connector')) {
137
+ if (child.name && child.name.toLowerCase().includes('connector') || child.userData && child.userData.objectType === 'connector') {
138
+ connectorIndex++;
137
139
  if (!child.userData) {
138
140
  child.userData = {};
139
141
  }
140
142
  child.userData.objectType = 'connector';
141
- console.log("\uD83D\uDD27 Set objectType='connector' for: ".concat(child.name));
143
+
144
+ // Assign a predictable, stable UUID to the connector
145
+ // This ensures connections made in the sandbox survive export/import
146
+ var connectorUuid = "".concat(uuid, "-CONNECTOR-").concat(connectorIndex);
147
+ child.uuid = connectorUuid;
148
+ child.userData.originalUuid = connectorUuid;
149
+ console.log("\uD83D\uDD27 Set predictable connector UUID: ".concat(connectorUuid, " for: ").concat(child.name));
142
150
  }
143
151
  }
144
152
  });
@@ -16,12 +16,14 @@ var TransformOperationsManager = /*#__PURE__*/function () {
16
16
  * @param {string} componentId - The UUID of the component to translate
17
17
  * @param {string} axis - The axis to translate on ('x', 'y', or 'z')
18
18
  * @param {number} value - The value to translate by
19
+ * @param {boolean} [skipPathUpdate=false] - Whether to skip triggering pathfinding after translation
19
20
  * @returns {boolean} True if translation was successful, false otherwise
20
21
  */
21
22
  return _createClass(TransformOperationsManager, [{
22
23
  key: "translateComponent",
23
24
  value: function translateComponent(componentId, axis, value) {
24
25
  var _this$sceneViewer$man, _this$sceneViewer;
26
+ var skipPathUpdate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
25
27
  // Store transform parameters using the OperationHistoryManager
26
28
  if ((_this$sceneViewer$man = this.sceneViewer.managers) !== null && _this$sceneViewer$man !== void 0 && _this$sceneViewer$man.operationHistoryManager) {
27
29
  this.sceneViewer.managers.operationHistoryManager.addToOperationHistory('translateComponent', {
@@ -89,7 +91,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
89
91
  }
90
92
 
91
93
  // Auto-update paths if enabled (matches behavior of translateSegment and translateGateway)
92
- if (this.sceneViewer.shouldUpdatePaths) {
94
+ if (!skipPathUpdate && this.sceneViewer.shouldUpdatePaths) {
93
95
  try {
94
96
  if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
95
97
  this.sceneViewer.updatePaths();
@@ -100,6 +102,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
100
102
  } catch (error) {
101
103
  console.error('❌ Error auto-updating paths:', error);
102
104
  }
105
+ } else if (skipPathUpdate) {
106
+ console.log('ℹ️ skipPathUpdate is true: skipping automatic path update');
103
107
  }
104
108
 
105
109
  // Emit transform event if available
@@ -1918,11 +1922,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1918
1922
  sceneDataComponent.children.forEach(function (child) {
1919
1923
  var _child$userData21;
1920
1924
  if (((_child$userData21 = child.userData) === null || _child$userData21 === void 0 ? void 0 : _child$userData21.objectType) === 'connector') {
1921
- // Find the actual connector object in the scene
1922
- var connectorObj = component.children.find(function (c) {
1923
- var _c$userData;
1924
- return c.uuid === child.uuid || ((_c$userData = c.userData) === null || _c$userData === void 0 ? void 0 : _c$userData.originalUuid) === child.uuid;
1925
- });
1925
+ // Find the actual connector object in the scene (recursive search for nested connectors)
1926
+ var connectorObj = component.getObjectByProperty('uuid', child.uuid) || component.getObjectByProperty('name', child.uuid);
1926
1927
  if (connectorObj) {
1927
1928
  // Get world position of connector
1928
1929
  var worldPos = new THREE.Vector3();
@@ -1981,11 +1982,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1981
1982
  sceneDataComponent.children.forEach(function (child) {
1982
1983
  var _child$userData22;
1983
1984
  if (((_child$userData22 = child.userData) === null || _child$userData22 === void 0 ? void 0 : _child$userData22.objectType) === 'connector') {
1984
- // Find the actual connector object in the scene
1985
- var connectorObj = component.children.find(function (c) {
1986
- var _c$userData2;
1987
- return c.uuid === child.uuid || ((_c$userData2 = c.userData) === null || _c$userData2 === void 0 ? void 0 : _c$userData2.originalUuid) === child.uuid;
1988
- });
1985
+ // Find the actual connector object in the scene (recursive search for nested connectors)
1986
+ var connectorObj = component.getObjectByProperty('uuid', child.uuid) || component.getObjectByProperty('name', child.uuid);
1989
1987
  if (connectorObj) {
1990
1988
  var _connectorObj$userDat;
1991
1989
  // Get world position of connector
@@ -40,7 +40,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
40
40
  this.forceInvisible = false;
41
41
 
42
42
  // SceneViewer reference for event listening
43
- this.sceneViewer = null;
43
+ this.sceneViewer = centralPlant ? centralPlant.sceneViewer : null;
44
44
  this._objectTransformedListener = null;
45
45
 
46
46
  // Event handlers storage
@@ -242,23 +242,28 @@ var TransformControlsManager = /*#__PURE__*/function () {
242
242
  _this2.transformState.isTransforming = true;
243
243
 
244
244
  // Store initial transforms for all selected objects
245
- if (_this2.selectedObjects.length > 0 && _this2.multiSelectionGroup) {
245
+ if (_this2.selectedObjects.length > 0) {
246
246
  _this2.selectedObjects.forEach(function (obj) {
247
- obj.userData._multiSelectOriginalPosition = obj.position.clone();
248
- obj.userData._multiSelectOriginalRotation = obj.rotation.clone();
249
- obj.userData._multiSelectOriginalScale = obj.scale.clone();
250
- });
251
-
252
- // Snapshot group position and helper geometry vertices so we can do
253
- // cheap per-frame bbox translation without re-traversing the mesh hierarchy.
254
- _this2._dragStartGroupPosition = _this2.multiSelectionGroup.position.clone();
255
- _this2.boundingBoxHelpers.forEach(function (helper) {
256
- var _helper$geometry;
257
- var posAttr = (_helper$geometry = helper.geometry) === null || _helper$geometry === void 0 || (_helper$geometry = _helper$geometry.attributes) === null || _helper$geometry === void 0 ? void 0 : _helper$geometry.position;
258
- if (posAttr) {
259
- helper.userData._dragStartPositions = new Float32Array(posAttr.array);
247
+ obj.userData._dragStartRotation = obj.rotation.clone();
248
+ obj.userData._dragStartPosition = obj.position.clone();
249
+ if (_this2.multiSelectionGroup) {
250
+ obj.userData._multiSelectOriginalPosition = obj.position.clone();
251
+ obj.userData._multiSelectOriginalRotation = obj.rotation.clone();
252
+ obj.userData._multiSelectOriginalScale = obj.scale.clone();
260
253
  }
261
254
  });
255
+ if (_this2.multiSelectionGroup) {
256
+ // Snapshot group position and helper geometry vertices so we can do
257
+ // cheap per-frame bbox translation without re-traversing the mesh hierarchy.
258
+ _this2._dragStartGroupPosition = _this2.multiSelectionGroup.position.clone();
259
+ _this2.boundingBoxHelpers.forEach(function (helper) {
260
+ var _helper$geometry;
261
+ var posAttr = (_helper$geometry = helper.geometry) === null || _helper$geometry === void 0 || (_helper$geometry = _helper$geometry.attributes) === null || _helper$geometry === void 0 ? void 0 : _helper$geometry.position;
262
+ if (posAttr) {
263
+ helper.userData._dragStartPositions = new Float32Array(posAttr.array);
264
+ }
265
+ });
266
+ }
262
267
  }
263
268
 
264
269
  // Disable orbit controls during transformation
@@ -275,7 +280,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
275
280
 
276
281
  // Transform end event
277
282
  this.eventHandlers.transformEnd = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
278
- var hasComponents, _this2$selectedObject, sceneCompleteEvent;
283
+ var isTranslate, isRotate, hasComponents, _this2$selectedObject, sceneCompleteEvent;
279
284
  return _regenerator().w(function (_context) {
280
285
  while (1) switch (_context.n) {
281
286
  case 0:
@@ -297,29 +302,52 @@ var TransformControlsManager = /*#__PURE__*/function () {
297
302
  console.error('❌ Error in applyMultiSelectionTransform:', error);
298
303
  });
299
304
  case 1:
300
- // applyMultiSelectionTransform() already calls updatePaths() once at the end
301
- // so we skip the additional updatePaths() call below
302
- console.log('✅ Multi-selection transform complete (updatePaths already called)');
305
+ console.log('✅ Multi-selection transform complete');
303
306
  _context.n = 3;
304
307
  break;
305
308
  case 2:
306
- if (_this2.currentMode === 'translate' && _this2.sceneViewer && typeof _this2.sceneViewer.updatePaths === 'function') {
307
- // Update paths after translation is complete
308
- // Only if we translated components (not segments/gateways - they handle paths internally)
309
- // This branch only executes when NOT in multi-selection mode
310
- hasComponents = _this2.selectedObjects.some(function (obj) {
311
- return !isSegment(obj) && !isGateway(obj);
312
- });
313
- if (hasComponents) {
314
- console.log('🔄 Updating paths after component translation...');
315
- try {
316
- _this2.sceneViewer.updatePaths();
317
- console.log('✅ Paths updated successfully after translation');
318
- } catch (error) {
319
- console.error('❌ Error updating paths after translation:', error);
309
+ if (_this2.sceneViewer && typeof _this2.sceneViewer.updatePaths === 'function') {
310
+ // Update paths after transformation is complete (translation or rotation)
311
+ isTranslate = _this2.currentMode === 'translate';
312
+ isRotate = _this2.currentMode === 'rotate';
313
+ if (isTranslate || isRotate) {
314
+ hasComponents = _this2.selectedObjects.some(function (obj) {
315
+ return !isSegment(obj) && !isGateway(obj);
316
+ });
317
+ if (hasComponents) {
318
+ console.log("\uD83D\uDD04 Updating paths after component ".concat(_this2.currentMode, "..."));
319
+ try {
320
+ // Ensure scene data is synced before updating paths
321
+ _this2.selectedObjects.forEach(function (obj) {
322
+ var _obj$userData;
323
+ if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) === 'component') {
324
+ var _this2$sceneViewer$ma;
325
+ var transformMgr = (_this2$sceneViewer$ma = _this2.sceneViewer.managers) === null || _this2$sceneViewer$ma === void 0 ? void 0 : _this2$sceneViewer$ma.transformOperationsManager;
326
+ if (transformMgr) {
327
+ if (isTranslate) {
328
+ transformMgr.updateComponentPositionInSceneData(obj);
329
+ }
330
+ if (isRotate) {
331
+ transformMgr.updateComponentRotationInSceneData(obj);
332
+
333
+ // Calculate rotation delta for direction vector patching
334
+ var startRot = obj.userData._dragStartRotation || obj.rotation;
335
+ var deltaRad = obj.rotation.z - startRot.z;
336
+ var deltaDeg = Math.round(THREE.MathUtils.radToDeg(deltaRad) / 90) * 90;
337
+ if (deltaDeg !== 0) {
338
+ console.log("\uD83E\uDDED Patching connector directions by ".concat(deltaDeg, " degrees after gizmo rotation"));
339
+ transformMgr.updateConnectorDirections(obj, 'z', deltaDeg);
340
+ }
341
+ }
342
+ }
343
+ }
344
+ });
345
+ _this2.sceneViewer.updatePaths();
346
+ console.log("\u2705 Paths updated successfully after ".concat(_this2.currentMode));
347
+ } catch (error) {
348
+ console.error("\u274C Error updating paths after ".concat(_this2.currentMode, ":"), error);
349
+ }
320
350
  }
321
- } else {
322
- console.log('ℹ️ Skipping updatePaths - segments/gateways handle their own path updates');
323
351
  }
324
352
  }
325
353
  case 3:
@@ -450,8 +478,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
450
478
  var hit = _step.value;
451
479
  var _obj = hit.object;
452
480
  while (_obj) {
453
- var _obj$userData2;
454
- if (((_obj$userData2 = _obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.objectType) === 'io-device') {
481
+ var _obj$userData3;
482
+ if (((_obj$userData3 = _obj.userData) === null || _obj$userData3 === void 0 ? void 0 : _obj$userData3.objectType) === 'io-device') {
455
483
  ioDeviceObject = _obj;
456
484
  break;
457
485
  }
@@ -474,8 +502,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
474
502
  var parentUuid = null;
475
503
  var obj = ioDeviceObject.parent;
476
504
  while (obj) {
477
- var _obj$userData;
478
- if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) === 'component') {
505
+ var _obj$userData2;
506
+ if (((_obj$userData2 = obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.objectType) === 'component') {
479
507
  parentUuid = obj.userData.originalUuid || obj.uuid;
480
508
  break;
481
509
  }
@@ -552,8 +580,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
552
580
  var hit = _step2.value;
553
581
  var obj = hit.object;
554
582
  while (obj) {
555
- var _obj$userData3;
556
- if (((_obj$userData3 = obj.userData) === null || _obj$userData3 === void 0 ? void 0 : _obj$userData3.objectType) === 'io-device') {
583
+ var _obj$userData4;
584
+ if (((_obj$userData4 = obj.userData) === null || _obj$userData4 === void 0 ? void 0 : _obj$userData4.objectType) === 'io-device') {
557
585
  _this4.callbacks.onIODeviceClick(obj);
558
586
  return;
559
587
  }
@@ -2214,8 +2242,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
2214
2242
  key: "_updateSegmentReference",
2215
2243
  value: function _updateSegmentReference(oldSegment, newSegment, index) {
2216
2244
  var selectedIndex = this.selectedObjects.findIndex(function (obj) {
2217
- var _obj$userData4;
2218
- return obj.uuid === oldSegment.uuid || ((_obj$userData4 = obj.userData) === null || _obj$userData4 === void 0 ? void 0 : _obj$userData4.originalUuid) === oldSegment.uuid;
2245
+ var _obj$userData5;
2246
+ return obj.uuid === oldSegment.uuid || ((_obj$userData5 = obj.userData) === null || _obj$userData5 === void 0 ? void 0 : _obj$userData5.originalUuid) === oldSegment.uuid;
2219
2247
  });
2220
2248
  if (selectedIndex !== -1 && newSegment) {
2221
2249
  // Clear bounding box cache
@@ -2323,7 +2351,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
2323
2351
  componentId = component.uuid || ((_component$userData = component.userData) === null || _component$userData === void 0 ? void 0 : _component$userData.originalUuid);
2324
2352
  _context6.n = 3;
2325
2353
  return this._translateObjectOnAxes(componentId, deltaX, deltaY, deltaZ, threshold, throttleDelay, AXIS_THROTTLE, function (id, axis, delta) {
2326
- return _this0.centralPlant.translate(id, axis, delta);
2354
+ return _this0.centralPlant.translate(id, axis, delta, true);
2327
2355
  });
2328
2356
  case 3:
2329
2357
  console.log("\uD83D\uDD27 Component ".concat(component.name, " translated (").concat(i + 1, "/").concat(components.length, ")"));
@@ -2422,6 +2450,17 @@ var TransformControlsManager = /*#__PURE__*/function () {
2422
2450
  if (this.selectedObjects.length > 0) {
2423
2451
  this.updateMultiSelection();
2424
2452
  }
2453
+
2454
+ // Trigger pathfinding update once after all objects in the batch are translated
2455
+ if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
2456
+ var hasComponentsOrSegments = this.selectedObjects.some(function (obj) {
2457
+ return !isGateway(obj);
2458
+ });
2459
+ if (hasComponentsOrSegments) {
2460
+ console.log('🔄 Triggering batched pathfinding update after multi-object translation...');
2461
+ this.sceneViewer.updatePaths();
2462
+ }
2463
+ }
2425
2464
  console.log("\u2705 Multi-selection transform applied");
2426
2465
  }
2427
2466