@2112-lab/central-plant 0.1.43 → 0.1.44

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.
@@ -4867,6 +4867,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
4867
4867
  // Only process if there's a meaningful translation
4868
4868
  var threshold = 0.001;
4869
4869
  if (this.currentMode === 'translate' && positionDelta.length() > threshold) {
4870
+ var _this$sceneViewer;
4870
4871
  // FIRST: Reset all objects to their original positions
4871
4872
  // This undoes the visual transform applied during drag
4872
4873
  this.selectedObjects.forEach(function (obj) {
@@ -4878,63 +4879,160 @@ var TransformControlsManager = /*#__PURE__*/function () {
4878
4879
  });
4879
4880
  console.log('🔄 Reset objects to original positions before API calls');
4880
4881
 
4881
- // THEN: Apply the delta to each object using the appropriate API
4882
- this.selectedObjects.forEach(function (obj) {
4883
- var _obj$userData;
4884
- if (!_this9.centralPlant) {
4885
- console.warn('⚠️ CentralPlant API not available');
4886
- return;
4887
- }
4888
- var componentId = obj.uuid || ((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.originalUuid);
4889
- if (isSegment(obj)) {
4890
- // Use translateSegment API
4882
+ // Separate segments from other objects
4883
+ var segments = this.selectedObjects.filter(function (obj) {
4884
+ return isSegment(obj);
4885
+ });
4886
+ var gateways = this.selectedObjects.filter(function (obj) {
4887
+ return isGateway(obj);
4888
+ });
4889
+ var components = this.selectedObjects.filter(function (obj) {
4890
+ return !isSegment(obj) && !isGateway(obj);
4891
+ });
4892
+
4893
+ // BATCH SEGMENT TRANSLATIONS: Use direct manager access to skip updatePaths()
4894
+ if (segments.length > 0 && (_this$sceneViewer = this.sceneViewer) !== null && _this$sceneViewer !== void 0 && (_this$sceneViewer = _this$sceneViewer.managers) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.transformOperations) {
4895
+ var _this$sceneViewer$man;
4896
+ console.log("\uD83D\uDD27 Batch translating ".concat(segments.length, " segments..."));
4897
+ var transformOpsManager = this.sceneViewer.managers.transformOperations;
4898
+ var operationHistory = (_this$sceneViewer$man = this.sceneViewer.managers) === null || _this$sceneViewer$man === void 0 ? void 0 : _this$sceneViewer$man.operationHistory;
4899
+ segments.forEach(function (segment) {
4900
+ var _segment$userData;
4901
+ var segmentId = segment.uuid || ((_segment$userData = segment.userData) === null || _segment$userData === void 0 ? void 0 : _segment$userData.originalUuid);
4902
+
4903
+ // Apply translation directly to the segment object
4891
4904
  if (Math.abs(deltaX) > threshold) {
4892
- _this9.centralPlant.translateSegment(componentId, 'x', deltaX);
4905
+ segment.position.x += deltaX;
4906
+ // Add to operation history
4907
+ if (operationHistory) {
4908
+ operationHistory.addToOperationHistory('translateSegment', {
4909
+ segmentId: segmentId,
4910
+ axis: 'x',
4911
+ value: deltaX
4912
+ });
4913
+ }
4893
4914
  }
4894
4915
  if (Math.abs(deltaY) > threshold) {
4895
- _this9.centralPlant.translateSegment(componentId, 'y', deltaY);
4916
+ segment.position.y += deltaY;
4917
+ // Add to operation history
4918
+ if (operationHistory) {
4919
+ operationHistory.addToOperationHistory('translateSegment', {
4920
+ segmentId: segmentId,
4921
+ axis: 'y',
4922
+ value: deltaY
4923
+ });
4924
+ }
4896
4925
  }
4897
4926
  if (Math.abs(deltaZ) > threshold) {
4898
- _this9.centralPlant.translateSegment(componentId, 'z', deltaZ);
4927
+ segment.position.z += deltaZ;
4928
+ // Add to operation history
4929
+ if (operationHistory) {
4930
+ operationHistory.addToOperationHistory('translateSegment', {
4931
+ segmentId: segmentId,
4932
+ axis: 'z',
4933
+ value: deltaZ
4934
+ });
4935
+ }
4899
4936
  }
4900
- console.log("\uD83D\uDCE6 Segment ".concat(obj.name, " translated:"), {
4901
- deltaX: deltaX,
4902
- deltaY: deltaY,
4903
- deltaZ: deltaZ
4904
- });
4905
- } else if (isGateway(obj)) {
4906
- // Use translateGateway API
4907
- if (Math.abs(deltaX) > threshold) {
4908
- _this9.centralPlant.translateGateway(componentId, 'x', deltaX);
4937
+ segment.updateMatrix();
4938
+ segment.updateMatrixWorld(true);
4939
+
4940
+ // Update connector positions for this segment
4941
+ if (typeof transformOpsManager.updateSegmentConnectorPositions === 'function') {
4942
+ transformOpsManager.updateSegmentConnectorPositions(segment);
4909
4943
  }
4910
- if (Math.abs(deltaY) > threshold) {
4911
- _this9.centralPlant.translateGateway(componentId, 'y', deltaY);
4944
+
4945
+ // Snap segment connectors to nearby endpoints
4946
+ if (typeof transformOpsManager.snapSegmentConnectorsToNearbyEndpoints === 'function') {
4947
+ transformOpsManager.snapSegmentConnectorsToNearbyEndpoints(segment);
4912
4948
  }
4913
- if (Math.abs(deltaZ) > threshold) {
4914
- _this9.centralPlant.translateGateway(componentId, 'z', deltaZ);
4949
+
4950
+ // Mark as declared if not already
4951
+ if (segment.userData.isDeclared !== true) {
4952
+ var _this9$sceneViewer$ma;
4953
+ var sceneOpsManager = (_this9$sceneViewer$ma = _this9.sceneViewer.managers) === null || _this9$sceneViewer$ma === void 0 ? void 0 : _this9$sceneViewer$ma.sceneOperations;
4954
+ if (sceneOpsManager && typeof sceneOpsManager.manualizeSegment === 'function') {
4955
+ try {
4956
+ sceneOpsManager.manualizeSegment(segment, _this9.sceneViewer.currentSceneData);
4957
+ } catch (error) {
4958
+ console.error('❌ Error manualizing segment:', error);
4959
+ }
4960
+ }
4915
4961
  }
4916
- console.log("\uD83D\uDEAA Gateway ".concat(obj.name, " translated:"), {
4962
+ console.log("\uD83D\uDCE6 Segment ".concat(segment.name, " translated (batched):"), {
4917
4963
  deltaX: deltaX,
4918
4964
  deltaY: deltaY,
4919
4965
  deltaZ: deltaZ
4920
4966
  });
4921
- } else {
4922
- // Use standard translate API for components
4967
+ });
4968
+
4969
+ // Only call updatePaths ONCE after all segments are translated
4970
+ console.log('🔄 Calling updatePaths once for all segments...');
4971
+ if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
4972
+ this.sceneViewer.updatePaths();
4973
+ console.log('✅ Paths regenerated successfully for all segments');
4974
+ }
4975
+ } else if (segments.length > 0) {
4976
+ // Fallback to individual API calls if manager not available
4977
+ console.warn('⚠️ TransformOperationsManager not available, using individual API calls');
4978
+ segments.forEach(function (segment) {
4979
+ var _segment$userData2;
4980
+ var segmentId = segment.uuid || ((_segment$userData2 = segment.userData) === null || _segment$userData2 === void 0 ? void 0 : _segment$userData2.originalUuid);
4923
4981
  if (Math.abs(deltaX) > threshold) {
4924
- _this9.centralPlant.translate(componentId, 'x', deltaX);
4982
+ _this9.centralPlant.translateSegment(segmentId, 'x', deltaX);
4925
4983
  }
4926
4984
  if (Math.abs(deltaY) > threshold) {
4927
- _this9.centralPlant.translate(componentId, 'y', deltaY);
4985
+ _this9.centralPlant.translateSegment(segmentId, 'y', deltaY);
4928
4986
  }
4929
4987
  if (Math.abs(deltaZ) > threshold) {
4930
- _this9.centralPlant.translate(componentId, 'z', deltaZ);
4988
+ _this9.centralPlant.translateSegment(segmentId, 'z', deltaZ);
4931
4989
  }
4932
- console.log("\uD83D\uDD27 Component ".concat(obj.name, " translated:"), {
4990
+ console.log("\uD83D\uDCE6 Segment ".concat(segment.name, " translated:"), {
4933
4991
  deltaX: deltaX,
4934
4992
  deltaY: deltaY,
4935
4993
  deltaZ: deltaZ
4936
4994
  });
4995
+ });
4996
+ }
4997
+
4998
+ // Translate gateways (these don't conflict with each other)
4999
+ gateways.forEach(function (gateway) {
5000
+ var _gateway$userData;
5001
+ var gatewayId = gateway.uuid || ((_gateway$userData = gateway.userData) === null || _gateway$userData === void 0 ? void 0 : _gateway$userData.originalUuid);
5002
+ if (Math.abs(deltaX) > threshold) {
5003
+ _this9.centralPlant.translateGateway(gatewayId, 'x', deltaX);
5004
+ }
5005
+ if (Math.abs(deltaY) > threshold) {
5006
+ _this9.centralPlant.translateGateway(gatewayId, 'y', deltaY);
5007
+ }
5008
+ if (Math.abs(deltaZ) > threshold) {
5009
+ _this9.centralPlant.translateGateway(gatewayId, 'z', deltaZ);
4937
5010
  }
5011
+ console.log("\uD83D\uDEAA Gateway ".concat(gateway.name, " translated:"), {
5012
+ deltaX: deltaX,
5013
+ deltaY: deltaY,
5014
+ deltaZ: deltaZ
5015
+ });
5016
+ });
5017
+
5018
+ // Translate components (these don't conflict with each other)
5019
+ components.forEach(function (component) {
5020
+ var _component$userData;
5021
+ var componentId = component.uuid || ((_component$userData = component.userData) === null || _component$userData === void 0 ? void 0 : _component$userData.originalUuid);
5022
+ if (Math.abs(deltaX) > threshold) {
5023
+ _this9.centralPlant.translate(componentId, 'x', deltaX);
5024
+ }
5025
+ if (Math.abs(deltaY) > threshold) {
5026
+ _this9.centralPlant.translate(componentId, 'y', deltaY);
5027
+ }
5028
+ if (Math.abs(deltaZ) > threshold) {
5029
+ _this9.centralPlant.translate(componentId, 'z', deltaZ);
5030
+ }
5031
+ console.log("\uD83D\uDD27 Component ".concat(component.name, " translated:"), {
5032
+ deltaX: deltaX,
5033
+ deltaY: deltaY,
5034
+ deltaZ: deltaZ
5035
+ });
4938
5036
  });
4939
5037
  console.log("\u2705 All ".concat(this.selectedObjects.length, " objects translated with delta:"), {
4940
5038
  deltaX: deltaX,
@@ -4965,7 +5063,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
4965
5063
  }, {
4966
5064
  key: "handlePipeSegmentTransform",
4967
5065
  value: function handlePipeSegmentTransform(segment) {
4968
- var _this$transformState, _this$transformState2, _segment$userData;
5066
+ var _this$transformState, _this$transformState2, _segment$userData3;
4969
5067
  console.log('🔧 Pipe segment transformed:', segment.name);
4970
5068
 
4971
5069
  // Safety checks
@@ -5002,7 +5100,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
5002
5100
  });
5003
5101
 
5004
5102
  // Get the segment ID (try both uuid and originalUuid)
5005
- var segmentId = segment.uuid || ((_segment$userData = segment.userData) === null || _segment$userData === void 0 ? void 0 : _segment$userData.originalUuid);
5103
+ var segmentId = segment.uuid || ((_segment$userData3 = segment.userData) === null || _segment$userData3 === void 0 ? void 0 : _segment$userData3.originalUuid);
5006
5104
  if (!segmentId) {
5007
5105
  console.error('❌ Cannot find segment ID for translateSegment API call');
5008
5106
  return;
@@ -5048,7 +5146,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
5048
5146
  }, {
5049
5147
  key: "handleGatewayTransform",
5050
5148
  value: function handleGatewayTransform(gateway) {
5051
- var _this$transformState3, _this$transformState4, _gateway$userData;
5149
+ var _this$transformState3, _this$transformState4, _gateway$userData2;
5052
5150
  console.log('🔧 Gateway transformed:', gateway.name);
5053
5151
 
5054
5152
  // Safety checks
@@ -5085,7 +5183,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
5085
5183
  });
5086
5184
 
5087
5185
  // Get the gateway ID (try both uuid and originalUuid)
5088
- var gatewayId = gateway.uuid || ((_gateway$userData = gateway.userData) === null || _gateway$userData === void 0 ? void 0 : _gateway$userData.originalUuid);
5186
+ var gatewayId = gateway.uuid || ((_gateway$userData2 = gateway.userData) === null || _gateway$userData2 === void 0 ? void 0 : _gateway$userData2.originalUuid);
5089
5187
  if (!gatewayId) {
5090
5188
  console.error('❌ Cannot find gateway ID for translateGateway API call');
5091
5189
  return;
@@ -18706,6 +18804,19 @@ var TransformOperationsManager = /*#__PURE__*/function () {
18706
18804
  console.warn("\u26A0\uFE0F translateSegment(): Segment '".concat(segmentId, "' is marked as non-transformable (stub segment)"));
18707
18805
  return false;
18708
18806
  }
18807
+
18808
+ // Check segment orientation and cancel invalid translations
18809
+ var isHorizontal = this.isSegmentHorizontal(segment);
18810
+ if (isHorizontal && (axis === 'x' || axis === 'y')) {
18811
+ console.warn("\u26A0\uFE0F translateSegment(): Cannot translate horizontal segment along ".concat(axis.toUpperCase(), " axis"));
18812
+ console.warn(" Horizontal segments can only be translated along the Z axis");
18813
+ return false;
18814
+ }
18815
+ if (!isHorizontal && axis === 'z') {
18816
+ console.warn("\u26A0\uFE0F translateSegment(): Cannot translate vertical segment along Z axis");
18817
+ console.warn(" Vertical segments can only be translated along X or Y axes");
18818
+ return false;
18819
+ }
18709
18820
  console.log('[translateSegment] segment:', segment);
18710
18821
 
18711
18822
  // Calculate segment endpoints to check for nearby connectors
@@ -32377,7 +32488,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
32377
32488
  * Initialize the CentralPlant manager
32378
32489
  *
32379
32490
  * @constructor
32380
- * @version 0.1.43
32491
+ * @version 0.1.44
32381
32492
  * @updated 2025-10-22
32382
32493
  *
32383
32494
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -19,7 +19,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
19
19
  * Initialize the CentralPlant manager
20
20
  *
21
21
  * @constructor
22
- * @version 0.1.43
22
+ * @version 0.1.44
23
23
  * @updated 2025-10-22
24
24
  *
25
25
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -165,6 +165,19 @@ var TransformOperationsManager = /*#__PURE__*/function () {
165
165
  console.warn("\u26A0\uFE0F translateSegment(): Segment '".concat(segmentId, "' is marked as non-transformable (stub segment)"));
166
166
  return false;
167
167
  }
168
+
169
+ // Check segment orientation and cancel invalid translations
170
+ var isHorizontal = this.isSegmentHorizontal(segment);
171
+ if (isHorizontal && (axis === 'x' || axis === 'y')) {
172
+ console.warn("\u26A0\uFE0F translateSegment(): Cannot translate horizontal segment along ".concat(axis.toUpperCase(), " axis"));
173
+ console.warn(" Horizontal segments can only be translated along the Z axis");
174
+ return false;
175
+ }
176
+ if (!isHorizontal && axis === 'z') {
177
+ console.warn("\u26A0\uFE0F translateSegment(): Cannot translate vertical segment along Z axis");
178
+ console.warn(" Vertical segments can only be translated along X or Y axes");
179
+ return false;
180
+ }
168
181
  console.log('[translateSegment] segment:', segment);
169
182
 
170
183
  // Calculate segment endpoints to check for nearby connectors
@@ -1511,6 +1511,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1511
1511
  // Only process if there's a meaningful translation
1512
1512
  var threshold = 0.001;
1513
1513
  if (this.currentMode === 'translate' && positionDelta.length() > threshold) {
1514
+ var _this$sceneViewer;
1514
1515
  // FIRST: Reset all objects to their original positions
1515
1516
  // This undoes the visual transform applied during drag
1516
1517
  this.selectedObjects.forEach(function (obj) {
@@ -1522,63 +1523,160 @@ var TransformControlsManager = /*#__PURE__*/function () {
1522
1523
  });
1523
1524
  console.log('🔄 Reset objects to original positions before API calls');
1524
1525
 
1525
- // THEN: Apply the delta to each object using the appropriate API
1526
- this.selectedObjects.forEach(function (obj) {
1527
- var _obj$userData;
1528
- if (!_this9.centralPlant) {
1529
- console.warn('⚠️ CentralPlant API not available');
1530
- return;
1531
- }
1532
- var componentId = obj.uuid || ((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.originalUuid);
1533
- if (objectTypes.isSegment(obj)) {
1534
- // Use translateSegment API
1526
+ // Separate segments from other objects
1527
+ var segments = this.selectedObjects.filter(function (obj) {
1528
+ return objectTypes.isSegment(obj);
1529
+ });
1530
+ var gateways = this.selectedObjects.filter(function (obj) {
1531
+ return objectTypes.isGateway(obj);
1532
+ });
1533
+ var components = this.selectedObjects.filter(function (obj) {
1534
+ return !objectTypes.isSegment(obj) && !objectTypes.isGateway(obj);
1535
+ });
1536
+
1537
+ // BATCH SEGMENT TRANSLATIONS: Use direct manager access to skip updatePaths()
1538
+ if (segments.length > 0 && (_this$sceneViewer = this.sceneViewer) !== null && _this$sceneViewer !== void 0 && (_this$sceneViewer = _this$sceneViewer.managers) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.transformOperations) {
1539
+ var _this$sceneViewer$man;
1540
+ console.log("\uD83D\uDD27 Batch translating ".concat(segments.length, " segments..."));
1541
+ var transformOpsManager = this.sceneViewer.managers.transformOperations;
1542
+ var operationHistory = (_this$sceneViewer$man = this.sceneViewer.managers) === null || _this$sceneViewer$man === void 0 ? void 0 : _this$sceneViewer$man.operationHistory;
1543
+ segments.forEach(function (segment) {
1544
+ var _segment$userData;
1545
+ var segmentId = segment.uuid || ((_segment$userData = segment.userData) === null || _segment$userData === void 0 ? void 0 : _segment$userData.originalUuid);
1546
+
1547
+ // Apply translation directly to the segment object
1535
1548
  if (Math.abs(deltaX) > threshold) {
1536
- _this9.centralPlant.translateSegment(componentId, 'x', deltaX);
1549
+ segment.position.x += deltaX;
1550
+ // Add to operation history
1551
+ if (operationHistory) {
1552
+ operationHistory.addToOperationHistory('translateSegment', {
1553
+ segmentId: segmentId,
1554
+ axis: 'x',
1555
+ value: deltaX
1556
+ });
1557
+ }
1537
1558
  }
1538
1559
  if (Math.abs(deltaY) > threshold) {
1539
- _this9.centralPlant.translateSegment(componentId, 'y', deltaY);
1560
+ segment.position.y += deltaY;
1561
+ // Add to operation history
1562
+ if (operationHistory) {
1563
+ operationHistory.addToOperationHistory('translateSegment', {
1564
+ segmentId: segmentId,
1565
+ axis: 'y',
1566
+ value: deltaY
1567
+ });
1568
+ }
1540
1569
  }
1541
1570
  if (Math.abs(deltaZ) > threshold) {
1542
- _this9.centralPlant.translateSegment(componentId, 'z', deltaZ);
1571
+ segment.position.z += deltaZ;
1572
+ // Add to operation history
1573
+ if (operationHistory) {
1574
+ operationHistory.addToOperationHistory('translateSegment', {
1575
+ segmentId: segmentId,
1576
+ axis: 'z',
1577
+ value: deltaZ
1578
+ });
1579
+ }
1543
1580
  }
1544
- console.log("\uD83D\uDCE6 Segment ".concat(obj.name, " translated:"), {
1545
- deltaX: deltaX,
1546
- deltaY: deltaY,
1547
- deltaZ: deltaZ
1548
- });
1549
- } else if (objectTypes.isGateway(obj)) {
1550
- // Use translateGateway API
1551
- if (Math.abs(deltaX) > threshold) {
1552
- _this9.centralPlant.translateGateway(componentId, 'x', deltaX);
1581
+ segment.updateMatrix();
1582
+ segment.updateMatrixWorld(true);
1583
+
1584
+ // Update connector positions for this segment
1585
+ if (typeof transformOpsManager.updateSegmentConnectorPositions === 'function') {
1586
+ transformOpsManager.updateSegmentConnectorPositions(segment);
1553
1587
  }
1554
- if (Math.abs(deltaY) > threshold) {
1555
- _this9.centralPlant.translateGateway(componentId, 'y', deltaY);
1588
+
1589
+ // Snap segment connectors to nearby endpoints
1590
+ if (typeof transformOpsManager.snapSegmentConnectorsToNearbyEndpoints === 'function') {
1591
+ transformOpsManager.snapSegmentConnectorsToNearbyEndpoints(segment);
1556
1592
  }
1557
- if (Math.abs(deltaZ) > threshold) {
1558
- _this9.centralPlant.translateGateway(componentId, 'z', deltaZ);
1593
+
1594
+ // Mark as declared if not already
1595
+ if (segment.userData.isDeclared !== true) {
1596
+ var _this9$sceneViewer$ma;
1597
+ var sceneOpsManager = (_this9$sceneViewer$ma = _this9.sceneViewer.managers) === null || _this9$sceneViewer$ma === void 0 ? void 0 : _this9$sceneViewer$ma.sceneOperations;
1598
+ if (sceneOpsManager && typeof sceneOpsManager.manualizeSegment === 'function') {
1599
+ try {
1600
+ sceneOpsManager.manualizeSegment(segment, _this9.sceneViewer.currentSceneData);
1601
+ } catch (error) {
1602
+ console.error('❌ Error manualizing segment:', error);
1603
+ }
1604
+ }
1559
1605
  }
1560
- console.log("\uD83D\uDEAA Gateway ".concat(obj.name, " translated:"), {
1606
+ console.log("\uD83D\uDCE6 Segment ".concat(segment.name, " translated (batched):"), {
1561
1607
  deltaX: deltaX,
1562
1608
  deltaY: deltaY,
1563
1609
  deltaZ: deltaZ
1564
1610
  });
1565
- } else {
1566
- // Use standard translate API for components
1611
+ });
1612
+
1613
+ // Only call updatePaths ONCE after all segments are translated
1614
+ console.log('🔄 Calling updatePaths once for all segments...');
1615
+ if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
1616
+ this.sceneViewer.updatePaths();
1617
+ console.log('✅ Paths regenerated successfully for all segments');
1618
+ }
1619
+ } else if (segments.length > 0) {
1620
+ // Fallback to individual API calls if manager not available
1621
+ console.warn('⚠️ TransformOperationsManager not available, using individual API calls');
1622
+ segments.forEach(function (segment) {
1623
+ var _segment$userData2;
1624
+ var segmentId = segment.uuid || ((_segment$userData2 = segment.userData) === null || _segment$userData2 === void 0 ? void 0 : _segment$userData2.originalUuid);
1567
1625
  if (Math.abs(deltaX) > threshold) {
1568
- _this9.centralPlant.translate(componentId, 'x', deltaX);
1626
+ _this9.centralPlant.translateSegment(segmentId, 'x', deltaX);
1569
1627
  }
1570
1628
  if (Math.abs(deltaY) > threshold) {
1571
- _this9.centralPlant.translate(componentId, 'y', deltaY);
1629
+ _this9.centralPlant.translateSegment(segmentId, 'y', deltaY);
1572
1630
  }
1573
1631
  if (Math.abs(deltaZ) > threshold) {
1574
- _this9.centralPlant.translate(componentId, 'z', deltaZ);
1632
+ _this9.centralPlant.translateSegment(segmentId, 'z', deltaZ);
1575
1633
  }
1576
- console.log("\uD83D\uDD27 Component ".concat(obj.name, " translated:"), {
1634
+ console.log("\uD83D\uDCE6 Segment ".concat(segment.name, " translated:"), {
1577
1635
  deltaX: deltaX,
1578
1636
  deltaY: deltaY,
1579
1637
  deltaZ: deltaZ
1580
1638
  });
1639
+ });
1640
+ }
1641
+
1642
+ // Translate gateways (these don't conflict with each other)
1643
+ gateways.forEach(function (gateway) {
1644
+ var _gateway$userData;
1645
+ var gatewayId = gateway.uuid || ((_gateway$userData = gateway.userData) === null || _gateway$userData === void 0 ? void 0 : _gateway$userData.originalUuid);
1646
+ if (Math.abs(deltaX) > threshold) {
1647
+ _this9.centralPlant.translateGateway(gatewayId, 'x', deltaX);
1581
1648
  }
1649
+ if (Math.abs(deltaY) > threshold) {
1650
+ _this9.centralPlant.translateGateway(gatewayId, 'y', deltaY);
1651
+ }
1652
+ if (Math.abs(deltaZ) > threshold) {
1653
+ _this9.centralPlant.translateGateway(gatewayId, 'z', deltaZ);
1654
+ }
1655
+ console.log("\uD83D\uDEAA Gateway ".concat(gateway.name, " translated:"), {
1656
+ deltaX: deltaX,
1657
+ deltaY: deltaY,
1658
+ deltaZ: deltaZ
1659
+ });
1660
+ });
1661
+
1662
+ // Translate components (these don't conflict with each other)
1663
+ components.forEach(function (component) {
1664
+ var _component$userData;
1665
+ var componentId = component.uuid || ((_component$userData = component.userData) === null || _component$userData === void 0 ? void 0 : _component$userData.originalUuid);
1666
+ if (Math.abs(deltaX) > threshold) {
1667
+ _this9.centralPlant.translate(componentId, 'x', deltaX);
1668
+ }
1669
+ if (Math.abs(deltaY) > threshold) {
1670
+ _this9.centralPlant.translate(componentId, 'y', deltaY);
1671
+ }
1672
+ if (Math.abs(deltaZ) > threshold) {
1673
+ _this9.centralPlant.translate(componentId, 'z', deltaZ);
1674
+ }
1675
+ console.log("\uD83D\uDD27 Component ".concat(component.name, " translated:"), {
1676
+ deltaX: deltaX,
1677
+ deltaY: deltaY,
1678
+ deltaZ: deltaZ
1679
+ });
1582
1680
  });
1583
1681
  console.log("\u2705 All ".concat(this.selectedObjects.length, " objects translated with delta:"), {
1584
1682
  deltaX: deltaX,
@@ -1609,7 +1707,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1609
1707
  }, {
1610
1708
  key: "handlePipeSegmentTransform",
1611
1709
  value: function handlePipeSegmentTransform(segment) {
1612
- var _this$transformState, _this$transformState2, _segment$userData;
1710
+ var _this$transformState, _this$transformState2, _segment$userData3;
1613
1711
  console.log('🔧 Pipe segment transformed:', segment.name);
1614
1712
 
1615
1713
  // Safety checks
@@ -1646,7 +1744,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1646
1744
  });
1647
1745
 
1648
1746
  // Get the segment ID (try both uuid and originalUuid)
1649
- var segmentId = segment.uuid || ((_segment$userData = segment.userData) === null || _segment$userData === void 0 ? void 0 : _segment$userData.originalUuid);
1747
+ var segmentId = segment.uuid || ((_segment$userData3 = segment.userData) === null || _segment$userData3 === void 0 ? void 0 : _segment$userData3.originalUuid);
1650
1748
  if (!segmentId) {
1651
1749
  console.error('❌ Cannot find segment ID for translateSegment API call');
1652
1750
  return;
@@ -1692,7 +1790,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1692
1790
  }, {
1693
1791
  key: "handleGatewayTransform",
1694
1792
  value: function handleGatewayTransform(gateway) {
1695
- var _this$transformState3, _this$transformState4, _gateway$userData;
1793
+ var _this$transformState3, _this$transformState4, _gateway$userData2;
1696
1794
  console.log('🔧 Gateway transformed:', gateway.name);
1697
1795
 
1698
1796
  // Safety checks
@@ -1729,7 +1827,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1729
1827
  });
1730
1828
 
1731
1829
  // Get the gateway ID (try both uuid and originalUuid)
1732
- var gatewayId = gateway.uuid || ((_gateway$userData = gateway.userData) === null || _gateway$userData === void 0 ? void 0 : _gateway$userData.originalUuid);
1830
+ var gatewayId = gateway.uuid || ((_gateway$userData2 = gateway.userData) === null || _gateway$userData2 === void 0 ? void 0 : _gateway$userData2.originalUuid);
1733
1831
  if (!gatewayId) {
1734
1832
  console.error('❌ Cannot find gateway ID for translateGateway API call');
1735
1833
  return;
@@ -15,7 +15,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
15
15
  * Initialize the CentralPlant manager
16
16
  *
17
17
  * @constructor
18
- * @version 0.1.43
18
+ * @version 0.1.44
19
19
  * @updated 2025-10-22
20
20
  *
21
21
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -141,6 +141,19 @@ var TransformOperationsManager = /*#__PURE__*/function () {
141
141
  console.warn("\u26A0\uFE0F translateSegment(): Segment '".concat(segmentId, "' is marked as non-transformable (stub segment)"));
142
142
  return false;
143
143
  }
144
+
145
+ // Check segment orientation and cancel invalid translations
146
+ var isHorizontal = this.isSegmentHorizontal(segment);
147
+ if (isHorizontal && (axis === 'x' || axis === 'y')) {
148
+ console.warn("\u26A0\uFE0F translateSegment(): Cannot translate horizontal segment along ".concat(axis.toUpperCase(), " axis"));
149
+ console.warn(" Horizontal segments can only be translated along the Z axis");
150
+ return false;
151
+ }
152
+ if (!isHorizontal && axis === 'z') {
153
+ console.warn("\u26A0\uFE0F translateSegment(): Cannot translate vertical segment along Z axis");
154
+ console.warn(" Vertical segments can only be translated along X or Y axes");
155
+ return false;
156
+ }
144
157
  console.log('[translateSegment] segment:', segment);
145
158
 
146
159
  // Calculate segment endpoints to check for nearby connectors
@@ -1487,6 +1487,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1487
1487
  // Only process if there's a meaningful translation
1488
1488
  var threshold = 0.001;
1489
1489
  if (this.currentMode === 'translate' && positionDelta.length() > threshold) {
1490
+ var _this$sceneViewer;
1490
1491
  // FIRST: Reset all objects to their original positions
1491
1492
  // This undoes the visual transform applied during drag
1492
1493
  this.selectedObjects.forEach(function (obj) {
@@ -1498,63 +1499,160 @@ var TransformControlsManager = /*#__PURE__*/function () {
1498
1499
  });
1499
1500
  console.log('🔄 Reset objects to original positions before API calls');
1500
1501
 
1501
- // THEN: Apply the delta to each object using the appropriate API
1502
- this.selectedObjects.forEach(function (obj) {
1503
- var _obj$userData;
1504
- if (!_this9.centralPlant) {
1505
- console.warn('⚠️ CentralPlant API not available');
1506
- return;
1507
- }
1508
- var componentId = obj.uuid || ((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.originalUuid);
1509
- if (isSegment(obj)) {
1510
- // Use translateSegment API
1502
+ // Separate segments from other objects
1503
+ var segments = this.selectedObjects.filter(function (obj) {
1504
+ return isSegment(obj);
1505
+ });
1506
+ var gateways = this.selectedObjects.filter(function (obj) {
1507
+ return isGateway(obj);
1508
+ });
1509
+ var components = this.selectedObjects.filter(function (obj) {
1510
+ return !isSegment(obj) && !isGateway(obj);
1511
+ });
1512
+
1513
+ // BATCH SEGMENT TRANSLATIONS: Use direct manager access to skip updatePaths()
1514
+ if (segments.length > 0 && (_this$sceneViewer = this.sceneViewer) !== null && _this$sceneViewer !== void 0 && (_this$sceneViewer = _this$sceneViewer.managers) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.transformOperations) {
1515
+ var _this$sceneViewer$man;
1516
+ console.log("\uD83D\uDD27 Batch translating ".concat(segments.length, " segments..."));
1517
+ var transformOpsManager = this.sceneViewer.managers.transformOperations;
1518
+ var operationHistory = (_this$sceneViewer$man = this.sceneViewer.managers) === null || _this$sceneViewer$man === void 0 ? void 0 : _this$sceneViewer$man.operationHistory;
1519
+ segments.forEach(function (segment) {
1520
+ var _segment$userData;
1521
+ var segmentId = segment.uuid || ((_segment$userData = segment.userData) === null || _segment$userData === void 0 ? void 0 : _segment$userData.originalUuid);
1522
+
1523
+ // Apply translation directly to the segment object
1511
1524
  if (Math.abs(deltaX) > threshold) {
1512
- _this9.centralPlant.translateSegment(componentId, 'x', deltaX);
1525
+ segment.position.x += deltaX;
1526
+ // Add to operation history
1527
+ if (operationHistory) {
1528
+ operationHistory.addToOperationHistory('translateSegment', {
1529
+ segmentId: segmentId,
1530
+ axis: 'x',
1531
+ value: deltaX
1532
+ });
1533
+ }
1513
1534
  }
1514
1535
  if (Math.abs(deltaY) > threshold) {
1515
- _this9.centralPlant.translateSegment(componentId, 'y', deltaY);
1536
+ segment.position.y += deltaY;
1537
+ // Add to operation history
1538
+ if (operationHistory) {
1539
+ operationHistory.addToOperationHistory('translateSegment', {
1540
+ segmentId: segmentId,
1541
+ axis: 'y',
1542
+ value: deltaY
1543
+ });
1544
+ }
1516
1545
  }
1517
1546
  if (Math.abs(deltaZ) > threshold) {
1518
- _this9.centralPlant.translateSegment(componentId, 'z', deltaZ);
1547
+ segment.position.z += deltaZ;
1548
+ // Add to operation history
1549
+ if (operationHistory) {
1550
+ operationHistory.addToOperationHistory('translateSegment', {
1551
+ segmentId: segmentId,
1552
+ axis: 'z',
1553
+ value: deltaZ
1554
+ });
1555
+ }
1519
1556
  }
1520
- console.log("\uD83D\uDCE6 Segment ".concat(obj.name, " translated:"), {
1521
- deltaX: deltaX,
1522
- deltaY: deltaY,
1523
- deltaZ: deltaZ
1524
- });
1525
- } else if (isGateway(obj)) {
1526
- // Use translateGateway API
1527
- if (Math.abs(deltaX) > threshold) {
1528
- _this9.centralPlant.translateGateway(componentId, 'x', deltaX);
1557
+ segment.updateMatrix();
1558
+ segment.updateMatrixWorld(true);
1559
+
1560
+ // Update connector positions for this segment
1561
+ if (typeof transformOpsManager.updateSegmentConnectorPositions === 'function') {
1562
+ transformOpsManager.updateSegmentConnectorPositions(segment);
1529
1563
  }
1530
- if (Math.abs(deltaY) > threshold) {
1531
- _this9.centralPlant.translateGateway(componentId, 'y', deltaY);
1564
+
1565
+ // Snap segment connectors to nearby endpoints
1566
+ if (typeof transformOpsManager.snapSegmentConnectorsToNearbyEndpoints === 'function') {
1567
+ transformOpsManager.snapSegmentConnectorsToNearbyEndpoints(segment);
1532
1568
  }
1533
- if (Math.abs(deltaZ) > threshold) {
1534
- _this9.centralPlant.translateGateway(componentId, 'z', deltaZ);
1569
+
1570
+ // Mark as declared if not already
1571
+ if (segment.userData.isDeclared !== true) {
1572
+ var _this9$sceneViewer$ma;
1573
+ var sceneOpsManager = (_this9$sceneViewer$ma = _this9.sceneViewer.managers) === null || _this9$sceneViewer$ma === void 0 ? void 0 : _this9$sceneViewer$ma.sceneOperations;
1574
+ if (sceneOpsManager && typeof sceneOpsManager.manualizeSegment === 'function') {
1575
+ try {
1576
+ sceneOpsManager.manualizeSegment(segment, _this9.sceneViewer.currentSceneData);
1577
+ } catch (error) {
1578
+ console.error('❌ Error manualizing segment:', error);
1579
+ }
1580
+ }
1535
1581
  }
1536
- console.log("\uD83D\uDEAA Gateway ".concat(obj.name, " translated:"), {
1582
+ console.log("\uD83D\uDCE6 Segment ".concat(segment.name, " translated (batched):"), {
1537
1583
  deltaX: deltaX,
1538
1584
  deltaY: deltaY,
1539
1585
  deltaZ: deltaZ
1540
1586
  });
1541
- } else {
1542
- // Use standard translate API for components
1587
+ });
1588
+
1589
+ // Only call updatePaths ONCE after all segments are translated
1590
+ console.log('🔄 Calling updatePaths once for all segments...');
1591
+ if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
1592
+ this.sceneViewer.updatePaths();
1593
+ console.log('✅ Paths regenerated successfully for all segments');
1594
+ }
1595
+ } else if (segments.length > 0) {
1596
+ // Fallback to individual API calls if manager not available
1597
+ console.warn('⚠️ TransformOperationsManager not available, using individual API calls');
1598
+ segments.forEach(function (segment) {
1599
+ var _segment$userData2;
1600
+ var segmentId = segment.uuid || ((_segment$userData2 = segment.userData) === null || _segment$userData2 === void 0 ? void 0 : _segment$userData2.originalUuid);
1543
1601
  if (Math.abs(deltaX) > threshold) {
1544
- _this9.centralPlant.translate(componentId, 'x', deltaX);
1602
+ _this9.centralPlant.translateSegment(segmentId, 'x', deltaX);
1545
1603
  }
1546
1604
  if (Math.abs(deltaY) > threshold) {
1547
- _this9.centralPlant.translate(componentId, 'y', deltaY);
1605
+ _this9.centralPlant.translateSegment(segmentId, 'y', deltaY);
1548
1606
  }
1549
1607
  if (Math.abs(deltaZ) > threshold) {
1550
- _this9.centralPlant.translate(componentId, 'z', deltaZ);
1608
+ _this9.centralPlant.translateSegment(segmentId, 'z', deltaZ);
1551
1609
  }
1552
- console.log("\uD83D\uDD27 Component ".concat(obj.name, " translated:"), {
1610
+ console.log("\uD83D\uDCE6 Segment ".concat(segment.name, " translated:"), {
1553
1611
  deltaX: deltaX,
1554
1612
  deltaY: deltaY,
1555
1613
  deltaZ: deltaZ
1556
1614
  });
1615
+ });
1616
+ }
1617
+
1618
+ // Translate gateways (these don't conflict with each other)
1619
+ gateways.forEach(function (gateway) {
1620
+ var _gateway$userData;
1621
+ var gatewayId = gateway.uuid || ((_gateway$userData = gateway.userData) === null || _gateway$userData === void 0 ? void 0 : _gateway$userData.originalUuid);
1622
+ if (Math.abs(deltaX) > threshold) {
1623
+ _this9.centralPlant.translateGateway(gatewayId, 'x', deltaX);
1557
1624
  }
1625
+ if (Math.abs(deltaY) > threshold) {
1626
+ _this9.centralPlant.translateGateway(gatewayId, 'y', deltaY);
1627
+ }
1628
+ if (Math.abs(deltaZ) > threshold) {
1629
+ _this9.centralPlant.translateGateway(gatewayId, 'z', deltaZ);
1630
+ }
1631
+ console.log("\uD83D\uDEAA Gateway ".concat(gateway.name, " translated:"), {
1632
+ deltaX: deltaX,
1633
+ deltaY: deltaY,
1634
+ deltaZ: deltaZ
1635
+ });
1636
+ });
1637
+
1638
+ // Translate components (these don't conflict with each other)
1639
+ components.forEach(function (component) {
1640
+ var _component$userData;
1641
+ var componentId = component.uuid || ((_component$userData = component.userData) === null || _component$userData === void 0 ? void 0 : _component$userData.originalUuid);
1642
+ if (Math.abs(deltaX) > threshold) {
1643
+ _this9.centralPlant.translate(componentId, 'x', deltaX);
1644
+ }
1645
+ if (Math.abs(deltaY) > threshold) {
1646
+ _this9.centralPlant.translate(componentId, 'y', deltaY);
1647
+ }
1648
+ if (Math.abs(deltaZ) > threshold) {
1649
+ _this9.centralPlant.translate(componentId, 'z', deltaZ);
1650
+ }
1651
+ console.log("\uD83D\uDD27 Component ".concat(component.name, " translated:"), {
1652
+ deltaX: deltaX,
1653
+ deltaY: deltaY,
1654
+ deltaZ: deltaZ
1655
+ });
1558
1656
  });
1559
1657
  console.log("\u2705 All ".concat(this.selectedObjects.length, " objects translated with delta:"), {
1560
1658
  deltaX: deltaX,
@@ -1585,7 +1683,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1585
1683
  }, {
1586
1684
  key: "handlePipeSegmentTransform",
1587
1685
  value: function handlePipeSegmentTransform(segment) {
1588
- var _this$transformState, _this$transformState2, _segment$userData;
1686
+ var _this$transformState, _this$transformState2, _segment$userData3;
1589
1687
  console.log('🔧 Pipe segment transformed:', segment.name);
1590
1688
 
1591
1689
  // Safety checks
@@ -1622,7 +1720,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1622
1720
  });
1623
1721
 
1624
1722
  // Get the segment ID (try both uuid and originalUuid)
1625
- var segmentId = segment.uuid || ((_segment$userData = segment.userData) === null || _segment$userData === void 0 ? void 0 : _segment$userData.originalUuid);
1723
+ var segmentId = segment.uuid || ((_segment$userData3 = segment.userData) === null || _segment$userData3 === void 0 ? void 0 : _segment$userData3.originalUuid);
1626
1724
  if (!segmentId) {
1627
1725
  console.error('❌ Cannot find segment ID for translateSegment API call');
1628
1726
  return;
@@ -1668,7 +1766,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1668
1766
  }, {
1669
1767
  key: "handleGatewayTransform",
1670
1768
  value: function handleGatewayTransform(gateway) {
1671
- var _this$transformState3, _this$transformState4, _gateway$userData;
1769
+ var _this$transformState3, _this$transformState4, _gateway$userData2;
1672
1770
  console.log('🔧 Gateway transformed:', gateway.name);
1673
1771
 
1674
1772
  // Safety checks
@@ -1705,7 +1803,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
1705
1803
  });
1706
1804
 
1707
1805
  // Get the gateway ID (try both uuid and originalUuid)
1708
- var gatewayId = gateway.uuid || ((_gateway$userData = gateway.userData) === null || _gateway$userData === void 0 ? void 0 : _gateway$userData.originalUuid);
1806
+ var gatewayId = gateway.uuid || ((_gateway$userData2 = gateway.userData) === null || _gateway$userData2 === void 0 ? void 0 : _gateway$userData2.originalUuid);
1709
1807
  if (!gatewayId) {
1710
1808
  console.error('❌ Cannot find gateway ID for translateGateway API call');
1711
1809
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2112-lab/central-plant",
3
- "version": "0.1.43",
3
+ "version": "0.1.44",
4
4
  "description": "Utility modules for the Central Plant Application",
5
5
  "main": "dist/bundle/index.js",
6
6
  "module": "dist/esm/index.js",