@2112-lab/central-plant 0.1.42 → 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);
4937
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);
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
@@ -18753,15 +18864,32 @@ var TransformOperationsManager = /*#__PURE__*/function () {
18753
18864
  }
18754
18865
  console.log("\uD83D\uDD04 translateSegment(): Translating segment ".concat(segmentId, " on ").concat(axis, " axis by ").concat(value));
18755
18866
 
18756
- // Check for collision with component connectors on any axis
18757
- var newPosition = segment.position[axis] + value;
18758
- var collision = this.checkComponentConnectorCollision(newPosition, axis);
18867
+ // Temporarily apply the translation to check for collisions
18868
+ var originalPosition = segment.position[axis];
18869
+ segment.position[axis] += value;
18870
+ segment.updateMatrix();
18871
+ segment.updateMatrixWorld(true);
18872
+
18873
+ // Check for collision with component connectors along the segment's path
18874
+ var collision = this.checkSegmentPathConnectorCollision(segment);
18759
18875
  if (collision) {
18760
- console.warn("\u26A0\uFE0F translateSegment(): Translation canceled - new ".concat(axis, "-position (").concat(newPosition.toFixed(3), ") would equal component connector ").concat(axis, "-position + 0.5 (").concat(collision.connectorPos.toFixed(3), " + 0.5 = ").concat((collision.connectorPos + 0.5).toFixed(3), ")"));
18876
+ // Revert the translation
18877
+ segment.position[axis] = originalPosition;
18878
+ segment.updateMatrix();
18879
+ segment.updateMatrixWorld(true);
18880
+ console.warn("\u26A0\uFE0F translateSegment(): Translation canceled - segment path comes within 0.5 radius of component connector");
18881
+ console.warn(" Distance to connector: ".concat(collision.distance.toFixed(3), " (max allowed: 0.5)"));
18882
+ console.warn(" Closest point on segment: [".concat(collision.collisionPoint.x.toFixed(3), ", ").concat(collision.collisionPoint.y.toFixed(3), ", ").concat(collision.collisionPoint.z.toFixed(3), "]"));
18883
+ console.warn(" Connector position: [".concat(collision.connectorPos.x.toFixed(3), ", ").concat(collision.connectorPos.y.toFixed(3), ", ").concat(collision.connectorPos.z.toFixed(3), "]"));
18761
18884
  console.warn(" Colliding connector: ".concat(collision.connectorId, " on component: ").concat(collision.componentId));
18762
18885
  return false;
18763
18886
  }
18764
18887
 
18888
+ // Revert the temporary translation before continuing with the normal flow
18889
+ segment.position[axis] = originalPosition;
18890
+ segment.updateMatrix();
18891
+ segment.updateMatrixWorld(true);
18892
+
18765
18893
  // Check if translationalOverrideForAutomaticSegments is enabled
18766
18894
  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');
18767
18895
 
@@ -18770,7 +18898,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
18770
18898
  console.log('🔍 Checking for intersections with computed segments (translationalOverrideForAutomaticSegments is disabled)');
18771
18899
 
18772
18900
  // Temporarily apply the translation to check for intersections
18773
- var originalPosition = segment.position[axis];
18901
+ var _originalPosition = segment.position[axis];
18774
18902
  segment.position[axis] += value;
18775
18903
  segment.updateMatrix();
18776
18904
  segment.updateMatrixWorld(true);
@@ -18780,7 +18908,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
18780
18908
  console.log("\uD83D\uDD04 translateSegment() hasIntersection:", hasIntersection);
18781
18909
  if (hasIntersection) {
18782
18910
  // Revert the translation
18783
- segment.position[axis] = originalPosition;
18911
+ segment.position[axis] = _originalPosition;
18784
18912
  segment.updateMatrix();
18785
18913
  segment.updateMatrixWorld(true);
18786
18914
  console.warn("\u26A0\uFE0F translateSegment(): Translation canceled - segment would intersect with computed segment(s)");
@@ -19402,21 +19530,123 @@ var TransformOperationsManager = /*#__PURE__*/function () {
19402
19530
  }
19403
19531
 
19404
19532
  /**
19405
- * Check if a position on a given axis would collide with any component connector position + 0.5
19406
- * @param {number} newPosition - The proposed new position on the specified axis
19407
- * @param {string} axis - The axis to check ('x', 'y', or 'z')
19408
- * @returns {Object|null} Collision info {connectorId, componentId, connectorPos} if collision detected, null otherwise
19533
+ * Check if any point along a segment's path would collide with component connector within 0.5 radius
19534
+ * @param {THREE.Object3D} segment - The segment to check
19535
+ * @returns {Object|null} Collision info {connectorId, componentId, connectorPos, collisionPoint, distance} if collision detected, null otherwise
19409
19536
  * @private
19410
19537
  */
19411
19538
  }, {
19412
- key: "checkComponentConnectorCollision",
19413
- value: function checkComponentConnectorCollision(newPosition, axis) {
19539
+ key: "checkSegmentPathConnectorCollision",
19540
+ value: function checkSegmentPathConnectorCollision(segment) {
19414
19541
  var _this$sceneViewer7;
19415
- if (!((_this$sceneViewer7 = this.sceneViewer) !== null && _this$sceneViewer7 !== void 0 && _this$sceneViewer7.scene)) {
19542
+ if (!((_this$sceneViewer7 = this.sceneViewer) !== null && _this$sceneViewer7 !== void 0 && _this$sceneViewer7.scene) || !segment) {
19416
19543
  return null;
19417
19544
  }
19418
- if (!['x', 'y', 'z'].includes(axis)) {
19419
- console.warn("\u26A0\uFE0F checkComponentConnectorCollision(): Invalid axis '".concat(axis, "'"));
19545
+ var collisionRadius = 0.5; // Radius around connector that triggers collision
19546
+
19547
+ // Get segment endpoints in world coordinates
19548
+ var endpoints = this.calculateSegmentEndpoints(segment);
19549
+ var startPoint = endpoints.start;
19550
+ var endPoint = endpoints.end;
19551
+ var collision = null;
19552
+
19553
+ // Traverse scene to find all component connectors
19554
+ this.sceneViewer.scene.traverse(function (child) {
19555
+ var _child$userData1;
19556
+ if (collision) return; // Stop if collision already found
19557
+
19558
+ // Check if this is a component connector (not a segment-connector)
19559
+ if (((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType) === 'connector') {
19560
+ // Get world position of connector
19561
+ var connectorWorldPos = new THREE__namespace.Vector3();
19562
+ child.getWorldPosition(connectorWorldPos);
19563
+
19564
+ // Find the closest point on the segment to the connector
19565
+ var segmentVector = new THREE__namespace.Vector3().subVectors(endPoint, startPoint);
19566
+ var pointVector = new THREE__namespace.Vector3().subVectors(connectorWorldPos, startPoint);
19567
+
19568
+ // Project connector position onto the segment line
19569
+ var segmentLengthSquared = segmentVector.dot(segmentVector);
19570
+
19571
+ // Handle degenerate case (zero-length segment)
19572
+ if (segmentLengthSquared < 1e-10) {
19573
+ var _distance = startPoint.distanceTo(connectorWorldPos);
19574
+ if (_distance <= collisionRadius) {
19575
+ // Find the parent component
19576
+ var component = child.parent;
19577
+ while (component && !((_component$userData2 = component.userData) !== null && _component$userData2 !== void 0 && _component$userData2.libraryId)) {
19578
+ var _component$userData2;
19579
+ component = component.parent;
19580
+ }
19581
+ collision = {
19582
+ connectorId: child.uuid,
19583
+ componentId: component ? component.uuid : 'unknown',
19584
+ connectorPos: {
19585
+ x: connectorWorldPos.x,
19586
+ y: connectorWorldPos.y,
19587
+ z: connectorWorldPos.z
19588
+ },
19589
+ collisionPoint: {
19590
+ x: startPoint.x,
19591
+ y: startPoint.y,
19592
+ z: startPoint.z
19593
+ },
19594
+ distance: _distance
19595
+ };
19596
+ }
19597
+ return;
19598
+ }
19599
+ var t = pointVector.dot(segmentVector) / segmentLengthSquared;
19600
+
19601
+ // Clamp t to [0, 1] to stay within segment bounds
19602
+ var tClamped = Math.max(0, Math.min(1, t));
19603
+
19604
+ // Calculate the closest point on the segment
19605
+ var closestPoint = new THREE__namespace.Vector3().addVectors(startPoint, segmentVector.clone().multiplyScalar(tClamped));
19606
+
19607
+ // Calculate distance from connector to closest point on segment
19608
+ var distance = closestPoint.distanceTo(connectorWorldPos);
19609
+
19610
+ // Check if distance is within collision radius
19611
+ if (distance <= collisionRadius) {
19612
+ // Find the parent component
19613
+ var _component = child.parent;
19614
+ while (_component && !((_component$userData3 = _component.userData) !== null && _component$userData3 !== void 0 && _component$userData3.libraryId)) {
19615
+ var _component$userData3;
19616
+ _component = _component.parent;
19617
+ }
19618
+ collision = {
19619
+ connectorId: child.uuid,
19620
+ componentId: _component ? _component.uuid : 'unknown',
19621
+ connectorPos: {
19622
+ x: connectorWorldPos.x,
19623
+ y: connectorWorldPos.y,
19624
+ z: connectorWorldPos.z
19625
+ },
19626
+ collisionPoint: {
19627
+ x: closestPoint.x,
19628
+ y: closestPoint.y,
19629
+ z: closestPoint.z
19630
+ },
19631
+ distance: distance
19632
+ };
19633
+ }
19634
+ }
19635
+ });
19636
+ return collision;
19637
+ }
19638
+
19639
+ /**
19640
+ * Check if a position would collide with any component connector position + 0.5 on all axes (X AND Y AND Z)
19641
+ * @param {Object} newPosition - The proposed new position {x, y, z}
19642
+ * @returns {Object|null} Collision info {connectorId, componentId, connectorPos} if collision detected, null otherwise
19643
+ * @private
19644
+ */
19645
+ }, {
19646
+ key: "checkComponentConnectorCollision",
19647
+ value: function checkComponentConnectorCollision(newPosition) {
19648
+ var _this$sceneViewer8;
19649
+ if (!((_this$sceneViewer8 = this.sceneViewer) !== null && _this$sceneViewer8 !== void 0 && _this$sceneViewer8.scene)) {
19420
19650
  return null;
19421
19651
  }
19422
19652
  var tolerance = 0.01; // Small tolerance for floating-point comparison
@@ -19424,27 +19654,35 @@ var TransformOperationsManager = /*#__PURE__*/function () {
19424
19654
 
19425
19655
  // Traverse scene to find all component connectors
19426
19656
  this.sceneViewer.scene.traverse(function (child) {
19427
- var _child$userData1;
19657
+ var _child$userData10;
19428
19658
  // Check if this is a component connector (not a segment-connector)
19429
- if (((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType) === 'connector') {
19659
+ if (((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType) === 'connector') {
19430
19660
  // Get world position of connector
19431
19661
  var connectorWorldPos = new THREE__namespace.Vector3();
19432
19662
  child.getWorldPosition(connectorWorldPos);
19433
19663
 
19434
- // Check if newPosition equals connector position on specified axis + 0.5 (within tolerance)
19435
- var connectorAxisPos = connectorWorldPos[axis];
19436
- var targetPos = connectorAxisPos + 0.5;
19437
- if (Math.abs(newPosition - targetPos) < tolerance) {
19664
+ // Check if newPosition equals connector position + 0.5 on ALL three axes simultaneously
19665
+ var targetX = connectorWorldPos.x + 0.5;
19666
+ var targetY = connectorWorldPos.y + 0.5;
19667
+ var targetZ = connectorWorldPos.z + 0.5;
19668
+ var matchesX = Math.abs(newPosition.x - targetX) < tolerance;
19669
+ var matchesY = Math.abs(newPosition.y - targetY) < tolerance;
19670
+ var matchesZ = Math.abs(newPosition.z - targetZ) < tolerance;
19671
+ if (matchesX && matchesY && matchesZ) {
19438
19672
  // Find the parent component
19439
19673
  var component = child.parent;
19440
- while (component && !((_component$userData2 = component.userData) !== null && _component$userData2 !== void 0 && _component$userData2.libraryId)) {
19441
- var _component$userData2;
19674
+ while (component && !((_component$userData4 = component.userData) !== null && _component$userData4 !== void 0 && _component$userData4.libraryId)) {
19675
+ var _component$userData4;
19442
19676
  component = component.parent;
19443
19677
  }
19444
19678
  collision = {
19445
19679
  connectorId: child.uuid,
19446
19680
  componentId: component ? component.uuid : 'unknown',
19447
- connectorPos: connectorAxisPos
19681
+ connectorPos: {
19682
+ x: connectorWorldPos.x,
19683
+ y: connectorWorldPos.y,
19684
+ z: connectorWorldPos.z
19685
+ }
19448
19686
  };
19449
19687
 
19450
19688
  // Stop traversal once collision is found
@@ -19533,10 +19771,10 @@ var TransformOperationsManager = /*#__PURE__*/function () {
19533
19771
  }, {
19534
19772
  key: "snapSegmentConnectorsToNearbyEndpoints",
19535
19773
  value: function snapSegmentConnectorsToNearbyEndpoints(movedSegment) {
19536
- var _this$sceneViewer8,
19537
- _this$sceneViewer9,
19774
+ var _this$sceneViewer9,
19775
+ _this$sceneViewer0,
19538
19776
  _this2 = this;
19539
- if (!movedSegment || !((_this$sceneViewer8 = this.sceneViewer) !== null && _this$sceneViewer8 !== void 0 && _this$sceneViewer8.scene)) {
19777
+ if (!movedSegment || !((_this$sceneViewer9 = this.sceneViewer) !== null && _this$sceneViewer9 !== void 0 && _this$sceneViewer9.scene)) {
19540
19778
  return [];
19541
19779
  }
19542
19780
  console.log('🔗 Finding adjacent segments connected to moved segment...');
@@ -19544,8 +19782,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
19544
19782
  // Get the moved segment's connectors
19545
19783
  var movedConnectors = [];
19546
19784
  movedSegment.traverse(function (child) {
19547
- var _child$userData10;
19548
- if (((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType) === 'segment-connector') {
19785
+ var _child$userData11;
19786
+ if (((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType) === 'segment-connector') {
19549
19787
  movedConnectors.push(child);
19550
19788
  }
19551
19789
  });
@@ -19558,7 +19796,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
19558
19796
  var newEndpoints = this.calculateSegmentEndpoints(movedSegment);
19559
19797
 
19560
19798
  // Check scene data for connections involving the moved segment's connectors
19561
- 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) || [];
19799
+ 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) || [];
19562
19800
  var movedConnectorIds = movedConnectors.map(function (c) {
19563
19801
  return c.uuid;
19564
19802
  });
@@ -19615,8 +19853,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
19615
19853
  // Get all connectors of the adjacent segment
19616
19854
  var adjacentConnectors = [];
19617
19855
  adjacentSegment.traverse(function (child) {
19618
- var _child$userData11;
19619
- if (((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType) === 'segment-connector') {
19856
+ var _child$userData12;
19857
+ if (((_child$userData12 = child.userData) === null || _child$userData12 === void 0 ? void 0 : _child$userData12.objectType) === 'segment-connector') {
19620
19858
  adjacentConnectors.push(child);
19621
19859
  }
19622
19860
  });
@@ -19708,9 +19946,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
19708
19946
  }, {
19709
19947
  key: "updateConnectorPositionInSceneData",
19710
19948
  value: function updateConnectorPositionInSceneData(connector, worldPosition, parentSegment) {
19711
- var _this$sceneViewer0;
19949
+ var _this$sceneViewer1;
19712
19950
  // Update scene data if available
19713
- if (!((_this$sceneViewer0 = this.sceneViewer) !== null && _this$sceneViewer0 !== void 0 && _this$sceneViewer0.currentSceneData)) {
19951
+ if (!((_this$sceneViewer1 = this.sceneViewer) !== null && _this$sceneViewer1 !== void 0 && _this$sceneViewer1.currentSceneData)) {
19714
19952
  return;
19715
19953
  }
19716
19954
  var cleanPosition = function cleanPosition(value) {
@@ -32250,7 +32488,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
32250
32488
  * Initialize the CentralPlant manager
32251
32489
  *
32252
32490
  * @constructor
32253
- * @version 0.1.42
32491
+ * @version 0.1.44
32254
32492
  * @updated 2025-10-22
32255
32493
  *
32256
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.42
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.