@2112-lab/central-plant 0.1.49 → 0.1.51

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.
@@ -19,7 +19,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
19
19
  * Initialize the CentralPlant manager
20
20
  *
21
21
  * @constructor
22
- * @version 0.1.49
22
+ * @version 0.1.51
23
23
  * @updated 2025-10-22
24
24
  *
25
25
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -324,51 +324,6 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
324
324
  return this.internals.translateGateway(gatewayId, axis, value);
325
325
  }
326
326
 
327
- /**
328
- * Split a pipe segment by shortening it by 0.5 units and manualizing it
329
- * @param {string} segmentId - The UUID of the segment to split
330
- * @returns {THREE.Object3D|null} The shortened manual segment or null on failure
331
- * @description Shortens a selected pipe segment by 0.5 units and converts it to
332
- * manual/declared status with connectors. The segment is shortened from the end that
333
- * has a component connector (or from the end if no connectors are present).
334
- * The segment becomes transformable after this operation. Paths are regenerated
335
- * to ensure proper connections.
336
- * @example
337
- * // Split/shorten a segment when selected via transform controls
338
- * const result = centralPlant.splitSegment('SEGMENT-12345');
339
- * if (result) {
340
- * console.log('Segment shortened and manualized:', result.uuid);
341
- * }
342
- *
343
- * @since 0.1.37
344
- */
345
- }, {
346
- key: "splitSegment",
347
- value: function splitSegment(segmentId) {
348
- var _this$sceneViewer$man;
349
- if (!this.sceneViewer || !((_this$sceneViewer$man = this.sceneViewer.managers) !== null && _this$sceneViewer$man !== void 0 && _this$sceneViewer$man.sceneOperationsManager)) {
350
- console.warn('⚠️ splitSegment(): Scene viewer or scene operations manager not available');
351
- return null;
352
- }
353
- if (!segmentId) {
354
- console.error('❌ splitSegment(): No segment ID provided');
355
- return null;
356
- }
357
- try {
358
- var result = this.sceneViewer.managers.sceneOperationsManager.splitSegment(segmentId, this.sceneViewer.currentSceneData);
359
- if (result) {
360
- console.log('✅ splitSegment(): Segment split successfully');
361
- return result;
362
- } else {
363
- console.warn('⚠️ splitSegment(): Split operation returned null');
364
- return null;
365
- }
366
- } catch (error) {
367
- console.error('❌ splitSegment(): Error splitting segment:', error);
368
- return null;
369
- }
370
- }
371
-
372
327
  /**
373
328
  * Rotate a component by componentId
374
329
  * @param {string} componentId - The UUID of the component to rotate
@@ -1650,8 +1605,8 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
1650
1605
  }, {
1651
1606
  key: "generatePath",
1652
1607
  value: function generatePath(fromConnectorId, toConnectorId) {
1653
- var _this$sceneViewer$man2;
1654
- if (!this.sceneViewer || !((_this$sceneViewer$man2 = this.sceneViewer.managers) !== null && _this$sceneViewer$man2 !== void 0 && _this$sceneViewer$man2.pathfinding)) {
1608
+ var _this$sceneViewer$man;
1609
+ if (!this.sceneViewer || !((_this$sceneViewer$man = this.sceneViewer.managers) !== null && _this$sceneViewer$man !== void 0 && _this$sceneViewer$man.pathfinding)) {
1655
1610
  return null;
1656
1611
  }
1657
1612
  try {
@@ -103,6 +103,20 @@ var TransformOperationsManager = /*#__PURE__*/function () {
103
103
  this.fixUndergroundComponent(component);
104
104
  }
105
105
 
106
+ // Auto-update paths if enabled (matches behavior of translateSegment and translateGateway)
107
+ if (this.sceneViewer.shouldUpdatePaths) {
108
+ try {
109
+ if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
110
+ this.sceneViewer.updatePaths();
111
+ console.log('🔄 Paths auto-updated after component translation');
112
+ } else {
113
+ console.warn('⚠️ updatePaths method not available on sceneViewer');
114
+ }
115
+ } catch (error) {
116
+ console.error('❌ Error auto-updating paths:', error);
117
+ }
118
+ }
119
+
106
120
  // Emit transform event if available
107
121
  if (this.sceneViewer.emit && typeof this.sceneViewer.emit === 'function') {
108
122
  this.sceneViewer.emit('objectTransformed', {
@@ -126,7 +140,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
126
140
  }, {
127
141
  key: "translateSegment",
128
142
  value: function translateSegment(segmentId, axis, value) {
129
- var _segment$userData, _segment$userData2, _this$sceneViewer3, _this$sceneViewer$man3, _this$sceneViewer$man4, _this$sceneViewer$man5;
143
+ var _segment$userData, _segment$userData2, _segment$userData3, _this$sceneViewer2, _this$sceneViewer$man2, _this$sceneViewer$man3, _this$sceneViewer$man4;
130
144
  var skipPathUpdate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
131
145
  // Validate parameters
132
146
  if (!segmentId || !axis || value === undefined || value === null) {
@@ -167,6 +181,12 @@ var TransformOperationsManager = /*#__PURE__*/function () {
167
181
  return false;
168
182
  }
169
183
 
184
+ // Check if segment is immutable (computed from pathfinder)
185
+ if (((_segment$userData3 = segment.userData) === null || _segment$userData3 === void 0 ? void 0 : _segment$userData3.immutable) === true) {
186
+ console.warn("\u26A0\uFE0F translateSegment(): Segment '".concat(segmentId, "' is immutable (computed from pathfinder)"));
187
+ return false;
188
+ }
189
+
170
190
  // Check segment orientation and cancel invalid translations
171
191
  // Get the segment's direction vector to determine which axis it runs along
172
192
  var direction = new THREE__namespace.Vector3(0, 1, 0);
@@ -212,66 +232,6 @@ var TransformOperationsManager = /*#__PURE__*/function () {
212
232
  parentType: (_c$parent2 = c.parent) === null || _c$parent2 === void 0 || (_c$parent2 = _c$parent2.userData) === null || _c$parent2 === void 0 ? void 0 : _c$parent2.objectType
213
233
  };
214
234
  }));
215
-
216
- // Filter out segment connectors - we only care about component connectors
217
- var componentConnectorsAtEndpoints = connectorsAtEndpoints.filter(function (connector) {
218
- var _connector$userData;
219
- return ((_connector$userData = connector.userData) === null || _connector$userData === void 0 ? void 0 : _connector$userData.objectType) !== 'segment-connector';
220
- });
221
- console.log("\uD83D\uDD0D After filtering, ".concat(componentConnectorsAtEndpoints.length, " component connectors at endpoints"));
222
- if (componentConnectorsAtEndpoints.length > 0) {
223
- var _this$sceneViewer2, _this$sceneViewer$man2;
224
- console.warn("\u26A0\uFE0F translateSegment(): Segment '".concat(segmentId, "' has component connectors at endpoints."));
225
- console.log(" Found ".concat(componentConnectorsAtEndpoints.length, " component connector(s):"), componentConnectorsAtEndpoints.map(function (c) {
226
- var _c$parent3;
227
- return {
228
- uuid: c.uuid,
229
- parent: (_c$parent3 = c.parent) === null || _c$parent3 === void 0 ? void 0 : _c$parent3.uuid
230
- };
231
- }));
232
-
233
- // Check if segment splitting is enabled in settings
234
- var splitSegmentsEnabled = (_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.managers) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.settingsManager) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.getSetting('scene', 'splitSegmentsWithComponentConnectors');
235
- if (splitSegmentsEnabled === false) {
236
- console.warn('⚠️ Segment splitting is disabled. Cannot translate segments with component connectors at endpoints.');
237
- return false;
238
- }
239
-
240
- // Split the segment and translate the free half
241
- console.log('✂️ Splitting segment to enable translation of the free half...');
242
-
243
- // Get sceneOperationsManager
244
- var _sceneOperationsManager = (_this$sceneViewer$man2 = this.sceneViewer.managers) === null || _this$sceneViewer$man2 === void 0 ? void 0 : _this$sceneViewer$man2.sceneOperationsManager;
245
- if (!_sceneOperationsManager) {
246
- console.error('❌ translateSegment(): SceneOperationsManager not available for splitting');
247
- return false;
248
- }
249
- try {
250
- var splitResult = _sceneOperationsManager.splitSegment(segment, this.sceneViewer.currentSceneData);
251
- if (splitResult) {
252
- console.log("\u2705 Segment split and shortened: ".concat(splitResult.uuid, " (new length: ").concat(splitResult.geometry.parameters.height, ")"));
253
-
254
- // The splitResult is now a shortened manual segment
255
- // Translate this shortened segment
256
- console.log("\uD83C\uDFAF Translating shortened manual segment: ".concat(splitResult.uuid));
257
-
258
- // Now translate the shortened manual segment (recursive call with the new segment)
259
- var translateSuccess = this.translateSegment(splitResult.uuid, axis, value);
260
- if (!translateSuccess) {
261
- console.error('❌ translateSegment(): Failed to translate shortened manual segment');
262
- return false;
263
- }
264
- console.log('✅ Split, shorten, and translate operation completed successfully');
265
- return true;
266
- } else {
267
- console.error('❌ translateSegment(): Split operation failed');
268
- return false;
269
- }
270
- } catch (error) {
271
- console.error('❌ translateSegment(): Error splitting segment:', error);
272
- return false;
273
- }
274
- }
275
235
  console.log("\uD83D\uDD04 translateSegment(): Translating segment ".concat(segmentId, " on ").concat(axis, " axis by ").concat(value));
276
236
 
277
237
  // Temporarily apply the translation to check for collisions
@@ -301,7 +261,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
301
261
  segment.updateMatrixWorld(true);
302
262
 
303
263
  // Check if translationalOverrideForAutomaticSegments is enabled
304
- var translationalOverride = (_this$sceneViewer3 = this.sceneViewer) === null || _this$sceneViewer3 === void 0 || (_this$sceneViewer3 = _this$sceneViewer3.managers) === null || _this$sceneViewer3 === void 0 || (_this$sceneViewer3 = _this$sceneViewer3.settingsManager) === null || _this$sceneViewer3 === void 0 ? void 0 : _this$sceneViewer3.getSetting('scene', 'translationalOverrideForAutomaticSegments');
264
+ var translationalOverride = (_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.managers) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.settingsManager) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.getSetting('scene', 'translationalOverrideForAutomaticSegments');
305
265
 
306
266
  // If override is disabled (false), check for intersections with computed segments
307
267
  if (translationalOverride === false) {
@@ -335,8 +295,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
335
295
  }
336
296
 
337
297
  // Validate PathfindingManager and SceneOperationsManager availability
338
- var pathfindingManager = (_this$sceneViewer$man3 = this.sceneViewer.managers) === null || _this$sceneViewer$man3 === void 0 ? void 0 : _this$sceneViewer$man3.pathfindingManager;
339
- var sceneOperationsManager = (_this$sceneViewer$man4 = this.sceneViewer.managers) === null || _this$sceneViewer$man4 === void 0 ? void 0 : _this$sceneViewer$man4.sceneOperationsManager;
298
+ var pathfindingManager = (_this$sceneViewer$man2 = this.sceneViewer.managers) === null || _this$sceneViewer$man2 === void 0 ? void 0 : _this$sceneViewer$man2.pathfindingManager;
299
+ var sceneOperationsManager = (_this$sceneViewer$man3 = this.sceneViewer.managers) === null || _this$sceneViewer$man3 === void 0 ? void 0 : _this$sceneViewer$man3.sceneOperationsManager;
340
300
  if (!pathfindingManager || !sceneOperationsManager) {
341
301
  console.error('❌ translateSegment(): PathfindingManager or SceneOperationsManager not available');
342
302
  return false;
@@ -357,21 +317,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
357
317
 
358
318
  // ALWAYS update connector positions after segment movement (first or subsequent moves)
359
319
  this.updateSegmentConnectorPositions(segment);
360
-
361
- // NEW: Update adjacent manual segments to follow this segment's new position
362
- var maintainedConnections = this.snapSegmentConnectorsToNearbyEndpoints(segment);
363
-
364
- // NOTE: We do NOT remove connections from scene data
365
- // The connections remain valid - the manual segments are maintaining those connections
366
- // The pathfinding algorithm should detect that connectors are at the same position
367
- // and skip creating computed segments for them
368
- if (maintainedConnections.length > 0) {
369
- console.log("\u2139\uFE0F ".concat(maintainedConnections.length, " connection(s) maintained by manual segments"));
370
- }
320
+ this.snapSegmentConnectorsToNearbyEndpoints(segment);
371
321
 
372
322
  // Store transform parameters using the OperationHistoryManager BEFORE updatePaths
373
323
  // This is critical so that intersection detection can undo the operation
374
- if ((_this$sceneViewer$man5 = this.sceneViewer.managers) !== null && _this$sceneViewer$man5 !== void 0 && _this$sceneViewer$man5.operationHistory) {
324
+ if ((_this$sceneViewer$man4 = this.sceneViewer.managers) !== null && _this$sceneViewer$man4 !== void 0 && _this$sceneViewer$man4.operationHistory) {
375
325
  this.sceneViewer.managers.operationHistory.addToOperationHistory('translateSegment', {
376
326
  segmentId: segmentId,
377
327
  axis: axis,
@@ -384,9 +334,6 @@ var TransformOperationsManager = /*#__PURE__*/function () {
384
334
  // UNLESS skipPathUpdate is true (for batch operations)
385
335
  if (!skipPathUpdate) {
386
336
  console.log('🔄 Regenerating paths to create connecting pipe segments...');
387
- if (maintainedConnections.length > 0) {
388
- console.log("\u2139\uFE0F Manual segments are maintaining connections - pathfinding should skip connectors at same position");
389
- }
390
337
  try {
391
338
  if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
392
339
  this.sceneViewer.updatePaths();
@@ -424,11 +371,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
424
371
  }, {
425
372
  key: "translateGateway",
426
373
  value: function translateGateway(gatewayId, axis, value) {
427
- var _this$sceneViewer$man6, _this$sceneViewer$man7;
374
+ var _this$sceneViewer$man5, _this$sceneViewer$man6;
428
375
  console.log("[Pathfinder] translateGateway started");
429
376
 
430
377
  // Store transform parameters using the OperationHistoryManager
431
- if ((_this$sceneViewer$man6 = this.sceneViewer.managers) !== null && _this$sceneViewer$man6 !== void 0 && _this$sceneViewer$man6.operationHistoryManager) {
378
+ if ((_this$sceneViewer$man5 = this.sceneViewer.managers) !== null && _this$sceneViewer$man5 !== void 0 && _this$sceneViewer$man5.operationHistoryManager) {
432
379
  this.sceneViewer.managers.operationHistoryManager.addToOperationHistory('translateGateway', {
433
380
  gatewayId: gatewayId,
434
381
  axis: axis,
@@ -479,7 +426,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
479
426
 
480
427
  // Handle manual gateway transformation (convert to declared and process connections)
481
428
  console.log('🔧 Handling manual gateway transformation via SceneOperationsManager');
482
- var sceneOperationsManager = (_this$sceneViewer$man7 = this.sceneViewer.managers) === null || _this$sceneViewer$man7 === void 0 ? void 0 : _this$sceneViewer$man7.sceneOperationsManager;
429
+ var sceneOperationsManager = (_this$sceneViewer$man6 = this.sceneViewer.managers) === null || _this$sceneViewer$man6 === void 0 ? void 0 : _this$sceneViewer$man6.sceneOperationsManager;
483
430
  if (!sceneOperationsManager) {
484
431
  console.error('❌ translateGateway(): SceneOperationsManager not available');
485
432
  return false;
@@ -581,6 +528,20 @@ var TransformOperationsManager = /*#__PURE__*/function () {
581
528
  component.updateMatrix();
582
529
  component.updateMatrixWorld(true);
583
530
 
531
+ // Auto-update paths if enabled (matches behavior of translateComponent)
532
+ if (this.sceneViewer.shouldUpdatePaths) {
533
+ try {
534
+ if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
535
+ this.sceneViewer.updatePaths();
536
+ console.log('🔄 Paths auto-updated after component rotation');
537
+ } else {
538
+ console.warn('⚠️ updatePaths method not available on sceneViewer');
539
+ }
540
+ } catch (error) {
541
+ console.error('❌ Error auto-updating paths:', error);
542
+ }
543
+ }
544
+
584
545
  // Emit transform event if available
585
546
  if (this.sceneViewer.emit && typeof this.sceneViewer.emit === 'function') {
586
547
  this.sceneViewer.emit('objectTransformed', {
@@ -763,9 +724,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
763
724
  }, {
764
725
  key: "findConnectorsAtPositions",
765
726
  value: function findConnectorsAtPositions(positions) {
766
- var _this$sceneViewer4;
727
+ var _this$sceneViewer3;
767
728
  var tolerance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;
768
- if (!((_this$sceneViewer4 = this.sceneViewer) !== null && _this$sceneViewer4 !== void 0 && _this$sceneViewer4.scene)) {
729
+ if (!((_this$sceneViewer3 = this.sceneViewer) !== null && _this$sceneViewer3 !== void 0 && _this$sceneViewer3.scene)) {
769
730
  return [];
770
731
  }
771
732
  var foundConnectors = [];
@@ -809,9 +770,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
809
770
  }, {
810
771
  key: "updateSegmentConnectorPositions",
811
772
  value: function updateSegmentConnectorPositions(segment) {
812
- var _this$sceneViewer5;
773
+ var _this$sceneViewer4;
813
774
  console.log("updateSegmentConnectorPositions started:", segment);
814
- if (!segment || !((_this$sceneViewer5 = this.sceneViewer) !== null && _this$sceneViewer5 !== void 0 && (_this$sceneViewer5 = _this$sceneViewer5.currentSceneData) !== null && _this$sceneViewer5 !== void 0 && _this$sceneViewer5.scene)) {
775
+ if (!segment || !((_this$sceneViewer4 = this.sceneViewer) !== null && _this$sceneViewer4 !== void 0 && (_this$sceneViewer4 = _this$sceneViewer4.currentSceneData) !== null && _this$sceneViewer4 !== void 0 && _this$sceneViewer4.scene)) {
815
776
  console.warn('⚠️ updateSegmentConnectorPositions(): Missing segment or scene data');
816
777
  return;
817
778
  }
@@ -837,8 +798,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
837
798
 
838
799
  // First, find the segment in scene data
839
800
  var sceneDataSegment = this.sceneViewer.currentSceneData.scene.children.find(function (child) {
840
- var _segment$userData3;
841
- return child.uuid === segment.uuid || child.uuid === ((_segment$userData3 = segment.userData) === null || _segment$userData3 === void 0 ? void 0 : _segment$userData3.originalUuid);
801
+ var _segment$userData4;
802
+ return child.uuid === segment.uuid || child.uuid === ((_segment$userData4 = segment.userData) === null || _segment$userData4 === void 0 ? void 0 : _segment$userData4.originalUuid);
842
803
  });
843
804
  if (!sceneDataSegment) {
844
805
  console.warn("\u26A0\uFE0F Segment ".concat(segment.uuid, " not found in scene data"));
@@ -858,8 +819,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
858
819
 
859
820
  // Find the connector in the segment's children array (not root scene.children)
860
821
  var sceneDataConnector = sceneDataSegment.children.find(function (child) {
861
- var _connector$userData2;
862
- return child.uuid === connector.uuid || child.uuid === ((_connector$userData2 = connector.userData) === null || _connector$userData2 === void 0 ? void 0 : _connector$userData2.originalUuid);
822
+ var _connector$userData;
823
+ return child.uuid === connector.uuid || child.uuid === ((_connector$userData = connector.userData) === null || _connector$userData === void 0 ? void 0 : _connector$userData.originalUuid);
863
824
  });
864
825
  if (sceneDataConnector && sceneDataConnector.userData) {
865
826
  // Update position as array [x, y, z] for pathfinder compatibility
@@ -881,9 +842,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
881
842
  }, {
882
843
  key: "checkSegmentIntersection",
883
844
  value: function checkSegmentIntersection(segment) {
884
- var _this$sceneViewer6,
845
+ var _this$sceneViewer5,
885
846
  _this = this;
886
- if (!((_this$sceneViewer6 = this.sceneViewer) !== null && _this$sceneViewer6 !== void 0 && _this$sceneViewer6.scene)) {
847
+ if (!((_this$sceneViewer5 = this.sceneViewer) !== null && _this$sceneViewer5 !== void 0 && _this$sceneViewer5.scene)) {
887
848
  return false;
888
849
  }
889
850
 
@@ -953,8 +914,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
953
914
  }, {
954
915
  key: "checkSegmentPathConnectorCollision",
955
916
  value: function checkSegmentPathConnectorCollision(segment) {
956
- var _this$sceneViewer7;
957
- if (!((_this$sceneViewer7 = this.sceneViewer) !== null && _this$sceneViewer7 !== void 0 && _this$sceneViewer7.scene) || !segment) {
917
+ var _this$sceneViewer6;
918
+ if (!((_this$sceneViewer6 = this.sceneViewer) !== null && _this$sceneViewer6 !== void 0 && _this$sceneViewer6.scene) || !segment) {
958
919
  return null;
959
920
  }
960
921
  var collisionRadius = 0.5; // Radius around connector that triggers collision
@@ -1068,8 +1029,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1068
1029
  }, {
1069
1030
  key: "checkComponentConnectorCollision",
1070
1031
  value: function checkComponentConnectorCollision(newPosition) {
1071
- var _this$sceneViewer8;
1072
- if (!((_this$sceneViewer8 = this.sceneViewer) !== null && _this$sceneViewer8 !== void 0 && _this$sceneViewer8.scene)) {
1032
+ var _this$sceneViewer7;
1033
+ if (!((_this$sceneViewer7 = this.sceneViewer) !== null && _this$sceneViewer7 !== void 0 && _this$sceneViewer7.scene)) {
1073
1034
  return null;
1074
1035
  }
1075
1036
  var tolerance = 0.01; // Small tolerance for floating-point comparison
@@ -1225,10 +1186,10 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1225
1186
  }, {
1226
1187
  key: "snapSegmentConnectorsToNearbyEndpoints",
1227
1188
  value: function snapSegmentConnectorsToNearbyEndpoints(movedSegment) {
1228
- var _this$sceneViewer9,
1229
- _this$sceneViewer0,
1189
+ var _this$sceneViewer8,
1190
+ _this$sceneViewer9,
1230
1191
  _this2 = this;
1231
- if (!movedSegment || !((_this$sceneViewer9 = this.sceneViewer) !== null && _this$sceneViewer9 !== void 0 && _this$sceneViewer9.scene)) {
1192
+ if (!movedSegment || !((_this$sceneViewer8 = this.sceneViewer) !== null && _this$sceneViewer8 !== void 0 && _this$sceneViewer8.scene)) {
1232
1193
  return [];
1233
1194
  }
1234
1195
  console.log('🔗 Finding adjacent segments connected to moved segment...');
@@ -1250,7 +1211,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1250
1211
  var newEndpoints = this.calculateSegmentEndpoints(movedSegment);
1251
1212
 
1252
1213
  // Check scene data for connections involving the moved segment's connectors
1253
- var connections = ((_this$sceneViewer0 = this.sceneViewer) === null || _this$sceneViewer0 === void 0 || (_this$sceneViewer0 = _this$sceneViewer0.currentSceneData) === null || _this$sceneViewer0 === void 0 ? void 0 : _this$sceneViewer0.connections) || [];
1214
+ var connections = ((_this$sceneViewer9 = this.sceneViewer) === null || _this$sceneViewer9 === void 0 || (_this$sceneViewer9 = _this$sceneViewer9.currentSceneData) === null || _this$sceneViewer9 === void 0 ? void 0 : _this$sceneViewer9.connections) || [];
1254
1215
  var movedConnectorIds = movedConnectors.map(function (c) {
1255
1216
  return c.uuid;
1256
1217
  });
@@ -1406,9 +1367,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1406
1367
  }, {
1407
1368
  key: "updateConnectorPositionInSceneData",
1408
1369
  value: function updateConnectorPositionInSceneData(connector, worldPosition, parentSegment) {
1409
- var _this$sceneViewer1;
1370
+ var _this$sceneViewer0;
1410
1371
  // Update scene data if available
1411
- if (!((_this$sceneViewer1 = this.sceneViewer) !== null && _this$sceneViewer1 !== void 0 && _this$sceneViewer1.currentSceneData)) {
1372
+ if (!((_this$sceneViewer0 = this.sceneViewer) !== null && _this$sceneViewer0 !== void 0 && _this$sceneViewer0.currentSceneData)) {
1412
1373
  return;
1413
1374
  }
1414
1375
  var cleanPosition = function cleanPosition(value) {
@@ -1431,8 +1392,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1431
1392
  }
1432
1393
 
1433
1394
  /**
1434
- * Recreate segment mesh with new length based on connector positions
1435
- * @param {THREE.Object3D} segment - The segment to recreate
1395
+ * Adjust segment geometry and transform to match new endpoint positions
1396
+ * @param {THREE.Object3D} segment - The segment to adjust
1436
1397
  * @param {Array<THREE.Object3D>} connectors - The segment's connectors
1437
1398
  * @param {THREE.Vector3} endPoint1 - Explicit world position for first endpoint (optional)
1438
1399
  * @param {THREE.Vector3} endPoint2 - Explicit world position for second endpoint (optional)
@@ -1446,7 +1407,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1446
1407
  var endPoint2 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
1447
1408
  var activeSegment = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
1448
1409
  if (!segment || connectors.length !== 2) {
1449
- console.warn('⚠️ Cannot recreate segment: invalid segment or connectors');
1410
+ console.warn('⚠️ Cannot adjust segment: invalid segment or connectors');
1450
1411
  return;
1451
1412
  }
1452
1413
  var _connectors = _rollupPluginBabelHelpers.slicedToArray(connectors, 2),
@@ -1489,21 +1450,28 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1489
1450
  this._removeZeroLengthSegment(segment, connectors, activeSegment);
1490
1451
  return;
1491
1452
  }
1492
- console.log("\uD83D\uDD27 Recreating segment with new length: ".concat(newLength.toFixed(3), " (was ").concat(segment.geometry.parameters.height.toFixed(3), ")"));
1453
+ var oldLength = segment.geometry.parameters.height;
1454
+ console.log("\uD83D\uDD27 Adjusting segment geometry: ".concat(oldLength.toFixed(3), " \u2192 ").concat(newLength.toFixed(3)));
1455
+
1456
+ // Only recreate geometry if length has changed significantly
1457
+ if (Math.abs(newLength - oldLength) > 1e-6) {
1458
+ var oldGeometry = segment.geometry;
1459
+ var pipeRadius = oldGeometry.parameters.radiusTop || 0.1;
1493
1460
 
1494
- // Store old geometry and material references
1495
- var oldGeometry = segment.geometry;
1496
- segment.material;
1497
- var pipeRadius = oldGeometry.parameters.radiusTop || 0.1;
1461
+ // Create new cylinder geometry with updated length
1462
+ var newGeometry = new THREE__namespace.CylinderGeometry(pipeRadius, pipeRadius, newLength, 16, 1, false);
1498
1463
 
1499
- // Create new cylinder geometry with updated length
1500
- var newGeometry = new THREE__namespace.CylinderGeometry(pipeRadius, pipeRadius, newLength, 16, 1, false);
1464
+ // Replace geometry
1465
+ segment.geometry = newGeometry;
1501
1466
 
1502
- // Update segment mesh
1503
- segment.geometry = newGeometry;
1467
+ // Dispose old geometry
1468
+ oldGeometry.dispose();
1469
+ }
1470
+
1471
+ // Update segment position to new center
1504
1472
  segment.position.copy(newCenter);
1505
1473
 
1506
- // Calculate and apply rotation
1474
+ // Calculate and apply rotation to align with new direction
1507
1475
  var quaternion = new THREE__namespace.Quaternion();
1508
1476
  var up = new THREE__namespace.Vector3(0, 1, 0);
1509
1477
  quaternion.setFromUnitVectors(up, direction.clone().normalize());
@@ -1512,12 +1480,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1512
1480
  // Update matrices
1513
1481
  segment.updateMatrix();
1514
1482
  segment.updateMatrixWorld(true);
1515
-
1516
- // Dispose old geometry
1517
- if (oldGeometry && oldGeometry !== newGeometry) {
1518
- oldGeometry.dispose();
1519
- }
1520
- console.log("\u2705 Segment mesh recreated: new length = ".concat(newLength.toFixed(3), ", center = [").concat(newCenter.x.toFixed(2), ", ").concat(newCenter.y.toFixed(2), ", ").concat(newCenter.z.toFixed(2), "]"));
1483
+ console.log("\u2705 Segment adjusted: length = ".concat(newLength.toFixed(3), ", center = [").concat(newCenter.x.toFixed(2), ", ").concat(newCenter.y.toFixed(2), ", ").concat(newCenter.z.toFixed(2), "]"));
1521
1484
  }
1522
1485
 
1523
1486
  /**
@@ -1634,8 +1597,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1634
1597
  // Remove segment from scene data
1635
1598
  if (currentSceneData.scene && currentSceneData.scene.children) {
1636
1599
  var segmentIndex = currentSceneData.scene.children.findIndex(function (child) {
1637
- var _segment$userData4;
1638
- return child.uuid === segment.uuid || child.uuid === ((_segment$userData4 = segment.userData) === null || _segment$userData4 === void 0 ? void 0 : _segment$userData4.originalUuid);
1600
+ var _segment$userData5;
1601
+ return child.uuid === segment.uuid || child.uuid === ((_segment$userData5 = segment.userData) === null || _segment$userData5 === void 0 ? void 0 : _segment$userData5.originalUuid);
1639
1602
  });
1640
1603
  if (segmentIndex !== -1) {
1641
1604
  currentSceneData.scene.children.splice(segmentIndex, 1);
@@ -18,21 +18,12 @@ var KeyboardControlsManager = /*#__PURE__*/function () {
18
18
  return _rollupPluginBabelHelpers.createClass(KeyboardControlsManager, [{
19
19
  key: "setupKeyboardControls",
20
20
  value: function setupKeyboardControls() {
21
- var _this = this;
22
21
  this.handleKeyDown = function (event) {
23
22
  // Sample Ctrl+Z example
24
23
  if (event.ctrlKey && (event.key.toLowerCase() === 'z' || event.code === 'KeyZ')) {
25
24
  // method call here
26
25
  return;
27
26
  }
28
-
29
- // Shift+D to split selected segment
30
- if (event.shiftKey && (event.key.toLowerCase() === 'd' || event.code === 'KeyD')) {
31
- _this.handleSegmentSplit();
32
- event.preventDefault();
33
- event.stopPropagation();
34
- return;
35
- }
36
27
  switch (event.key.toLowerCase()) {
37
28
  }
38
29
  };
@@ -46,53 +37,6 @@ var KeyboardControlsManager = /*#__PURE__*/function () {
46
37
  console.log('Keyboard controls initialized with Ctrl+Z undo override and Shift+D segment split');
47
38
  }
48
39
 
49
- /**
50
- * Handle segment split operation (Shift+D)
51
- * Splits the currently selected segment in half if it's a pipe segment
52
- */
53
- }, {
54
- key: "handleSegmentSplit",
55
- value: function handleSegmentSplit() {
56
- var sceneViewer = this.sceneViewer;
57
-
58
- // Check if transform controls are active with a selected object
59
- if (!sceneViewer.transformManager || !sceneViewer.transformManager.selectedObjects || sceneViewer.transformManager.selectedObjects.length === 0) {
60
- console.log('ℹ️ No object selected for segment split');
61
- return;
62
- }
63
- var selectedObject = sceneViewer.transformManager.selectedObjects[0];
64
-
65
- // Verify it's a segment
66
- if (!selectedObject.userData || selectedObject.userData.objectType !== 'segment') {
67
- console.log('ℹ️ Selected object is not a segment, cannot split');
68
- return;
69
- }
70
- console.log('✂️ Shift+D pressed - splitting segment:', selectedObject.uuid);
71
-
72
- // Access CentralPlant through sceneViewer
73
- var centralPlant = sceneViewer.centralPlant;
74
- if (!centralPlant || typeof centralPlant.splitSegment !== 'function') {
75
- console.error('❌ CentralPlant or splitSegment method not available');
76
- return;
77
- }
78
-
79
- // Call the public API to split the segment
80
- var result = centralPlant.splitSegment(selectedObject.uuid);
81
- if (result) {
82
- console.log('✅ Segment split successful:', result);
83
-
84
- // Deselect the original segment (now removed) and optionally select one of the new segments
85
- sceneViewer.transformManager.deselectObject();
86
-
87
- // Optionally select the first new segment
88
- if (result.segment1) {
89
- sceneViewer.transformManager.selectObject(result.segment1);
90
- }
91
- } else {
92
- console.error('❌ Segment split failed');
93
- }
94
- }
95
-
96
40
  /**
97
41
  * Toggle auto-rotation of the camera
98
42
  */