@2112-lab/central-plant 0.1.54 → 0.1.55
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.
- package/dist/bundle/index.js +295 -674
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/index.js +0 -2
- package/dist/cjs/src/managers/components/transformOperationsManager.js +218 -90
- package/dist/cjs/src/managers/pathfinding/PathRenderingManager.js +21 -2
- package/dist/cjs/src/managers/pathfinding/pathfindingManager.js +76 -117
- package/dist/cjs/src/managers/pathfinding/sceneDataManager.js +5 -131
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/index.js +0 -1
- package/dist/esm/src/managers/components/transformOperationsManager.js +218 -90
- package/dist/esm/src/managers/pathfinding/PathRenderingManager.js +21 -2
- package/dist/esm/src/managers/pathfinding/pathfindingManager.js +57 -118
- package/dist/esm/src/managers/pathfinding/sceneDataManager.js +5 -111
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -19070,6 +19070,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19070
19070
|
component.updateMatrix();
|
|
19071
19071
|
component.updateMatrixWorld(true);
|
|
19072
19072
|
|
|
19073
|
+
// Update component position in currentSceneData
|
|
19074
|
+
this.updateComponentPositionInSceneData(component);
|
|
19075
|
+
|
|
19073
19076
|
// Check if component is underground and fix if needed (based on settings)
|
|
19074
19077
|
var checkUnderground = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.settingsManager) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.getSetting('scene', 'checkUnderground');
|
|
19075
19078
|
if (checkUnderground) {
|
|
@@ -19214,7 +19217,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19214
19217
|
}, {
|
|
19215
19218
|
key: "validateTranslateSegmentCollisions",
|
|
19216
19219
|
value: function validateTranslateSegmentCollisions(segment, axis, value) {
|
|
19217
|
-
var
|
|
19220
|
+
var _segment$userData4, _segment$userData5;
|
|
19218
19221
|
// Store original position for reverting
|
|
19219
19222
|
var originalPosition = segment.position[axis];
|
|
19220
19223
|
|
|
@@ -19223,6 +19226,14 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19223
19226
|
segment.updateMatrix();
|
|
19224
19227
|
segment.updateMatrixWorld(true);
|
|
19225
19228
|
|
|
19229
|
+
// IMPORTANT: Update stored endpoints if they exist, since position changed
|
|
19230
|
+
// This ensures checkSegmentIntersection uses the correct translated endpoints
|
|
19231
|
+
if ((_segment$userData4 = segment.userData) !== null && _segment$userData4 !== void 0 && (_segment$userData4 = _segment$userData4.endpoints) !== null && _segment$userData4 !== void 0 && _segment$userData4.startOffset && (_segment$userData5 = segment.userData) !== null && _segment$userData5 !== void 0 && (_segment$userData5 = _segment$userData5.endpoints) !== null && _segment$userData5 !== void 0 && _segment$userData5.endOffset) {
|
|
19232
|
+
// Endpoints are stored as offsets from center, so they don't need updating
|
|
19233
|
+
// The getSegmentEndpoints method will automatically use the new position
|
|
19234
|
+
console.log("\uD83D\uDD0D Checking collisions with translated position: ".concat(axis, "=").concat(segment.position[axis].toFixed(3)));
|
|
19235
|
+
}
|
|
19236
|
+
|
|
19226
19237
|
// Check for collision with component connectors along the segment's path
|
|
19227
19238
|
var connectorCollision = this.checkSegmentPathConnectorCollision(segment);
|
|
19228
19239
|
if (connectorCollision) {
|
|
@@ -19252,26 +19263,21 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19252
19263
|
return false;
|
|
19253
19264
|
}
|
|
19254
19265
|
|
|
19255
|
-
//
|
|
19256
|
-
|
|
19257
|
-
|
|
19258
|
-
// If override is disabled (false), check for intersections with computed segments
|
|
19259
|
-
if (translationalOverride === false) {
|
|
19260
|
-
console.log('🔍 Checking for intersections with computed segments (translationalOverrideForAutomaticSegments is disabled)');
|
|
19266
|
+
// ALWAYS check for segment-to-segment intersections
|
|
19267
|
+
console.log('🔍 Checking for intersections with other segments...');
|
|
19261
19268
|
|
|
19262
|
-
|
|
19263
|
-
|
|
19264
|
-
|
|
19265
|
-
|
|
19266
|
-
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
|
|
19270
|
-
|
|
19271
|
-
|
|
19272
|
-
}
|
|
19273
|
-
console.log('✅ No intersections detected, proceeding with translation');
|
|
19269
|
+
// Check if the translated segment intersects with any other segments
|
|
19270
|
+
var hasIntersection = this.checkSegmentIntersection(segment);
|
|
19271
|
+
console.log("\uD83D\uDD04 translateSegment() hasIntersection:", hasIntersection);
|
|
19272
|
+
if (hasIntersection) {
|
|
19273
|
+
// Revert the translation
|
|
19274
|
+
segment.position[axis] = originalPosition;
|
|
19275
|
+
segment.updateMatrix();
|
|
19276
|
+
segment.updateMatrixWorld(true);
|
|
19277
|
+
console.warn("\u26A0\uFE0F translateSegment(): Translation canceled - segment would intersect with other segment(s)");
|
|
19278
|
+
return false;
|
|
19274
19279
|
}
|
|
19280
|
+
console.log('✅ No intersections detected, proceeding with translation');
|
|
19275
19281
|
|
|
19276
19282
|
// Revert the temporary translation
|
|
19277
19283
|
segment.position[axis] = originalPosition;
|
|
@@ -19733,9 +19739,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19733
19739
|
}, {
|
|
19734
19740
|
key: "findConnectorsAtPositions",
|
|
19735
19741
|
value: function findConnectorsAtPositions(positions) {
|
|
19736
|
-
var _this$
|
|
19742
|
+
var _this$sceneViewer2;
|
|
19737
19743
|
var tolerance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;
|
|
19738
|
-
if (!((_this$
|
|
19744
|
+
if (!((_this$sceneViewer2 = this.sceneViewer) !== null && _this$sceneViewer2 !== void 0 && _this$sceneViewer2.scene)) {
|
|
19739
19745
|
return [];
|
|
19740
19746
|
}
|
|
19741
19747
|
var foundConnectors = [];
|
|
@@ -19779,10 +19785,10 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19779
19785
|
}, {
|
|
19780
19786
|
key: "updateSegmentConnectorPositions",
|
|
19781
19787
|
value: function updateSegmentConnectorPositions(segment) {
|
|
19782
|
-
var _this$
|
|
19788
|
+
var _this$sceneViewer3,
|
|
19783
19789
|
_this = this;
|
|
19784
19790
|
console.log("updateSegmentConnectorPositions started:", segment);
|
|
19785
|
-
if (!segment || !((_this$
|
|
19791
|
+
if (!segment || !((_this$sceneViewer3 = this.sceneViewer) !== null && _this$sceneViewer3 !== void 0 && (_this$sceneViewer3 = _this$sceneViewer3.currentSceneData) !== null && _this$sceneViewer3 !== void 0 && _this$sceneViewer3.scene)) {
|
|
19786
19792
|
console.warn('⚠️ updateSegmentConnectorPositions(): Missing segment or scene data');
|
|
19787
19793
|
return;
|
|
19788
19794
|
}
|
|
@@ -19833,24 +19839,25 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19833
19839
|
}
|
|
19834
19840
|
|
|
19835
19841
|
/**
|
|
19836
|
-
* Check if a segment intersects with any
|
|
19837
|
-
*
|
|
19842
|
+
* Check if a segment intersects with any segments in the scene
|
|
19843
|
+
* For grid-based segments (0.5 grid), checks if segments cross or overlap
|
|
19844
|
+
* Uses only endpoint comparisons, no radius checks
|
|
19845
|
+
* Allows T-junctions (endpoint touching line) if segments are connected (same pathFrom/pathTo)
|
|
19838
19846
|
* @param {THREE.Object3D} segment - The segment to check for intersections
|
|
19839
|
-
* @returns {boolean} True if segment intersects with any
|
|
19847
|
+
* @returns {boolean} True if segment intersects with any segment
|
|
19840
19848
|
* @private
|
|
19841
19849
|
*/
|
|
19842
19850
|
}, {
|
|
19843
19851
|
key: "checkSegmentIntersection",
|
|
19844
19852
|
value: function checkSegmentIntersection(segment) {
|
|
19845
|
-
var _this$
|
|
19853
|
+
var _this$sceneViewer4,
|
|
19846
19854
|
_this2 = this;
|
|
19847
|
-
if (!((_this$
|
|
19855
|
+
if (!((_this$sceneViewer4 = this.sceneViewer) !== null && _this$sceneViewer4 !== void 0 && _this$sceneViewer4.scene)) {
|
|
19848
19856
|
return false;
|
|
19849
19857
|
}
|
|
19850
19858
|
|
|
19851
|
-
// Get endpoints of the segment being checked
|
|
19852
|
-
var segmentEndpoints = this.
|
|
19853
|
-
var segmentRadius = segment.geometry.parameters.radiusTop || 0.05;
|
|
19859
|
+
// Get endpoints of the segment being checked (use stored endpoints if available)
|
|
19860
|
+
var segmentEndpoints = this.getSegmentEndpoints(segment);
|
|
19854
19861
|
|
|
19855
19862
|
// Track if any intersection was found
|
|
19856
19863
|
var hasIntersection = false;
|
|
@@ -19863,41 +19870,74 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19863
19870
|
return;
|
|
19864
19871
|
}
|
|
19865
19872
|
|
|
19866
|
-
// Only check computed segments
|
|
19867
|
-
if (((_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.objectType) === 'segment' && (
|
|
19868
|
-
|
|
19869
|
-
|
|
19870
|
-
var
|
|
19873
|
+
// Only check computed segments in the scene
|
|
19874
|
+
if (((_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.objectType) === 'segment' && (_child$userData0 = child.userData) !== null && _child$userData0 !== void 0 && _child$userData0.isDeclared) {
|
|
19875
|
+
var _segment$userData6, _child$userData1, _segment$userData7, _child$userData10;
|
|
19876
|
+
// Check if segments are part of the same connection path
|
|
19877
|
+
var sameConnection = ((_segment$userData6 = segment.userData) === null || _segment$userData6 === void 0 ? void 0 : _segment$userData6.pathFrom) === ((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.pathFrom) && ((_segment$userData7 = segment.userData) === null || _segment$userData7 === void 0 ? void 0 : _segment$userData7.pathTo) === ((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.pathTo);
|
|
19871
19878
|
|
|
19872
|
-
//
|
|
19873
|
-
var
|
|
19879
|
+
// Get endpoints of the other segment (use stored endpoints if available)
|
|
19880
|
+
var otherEndpoints = _this2.getSegmentEndpoints(child);
|
|
19874
19881
|
|
|
19875
|
-
//
|
|
19876
|
-
|
|
19877
|
-
var endpointTolerance = 0.55; // Generous tolerance for endpoint connections
|
|
19882
|
+
// Grid tolerance for endpoint comparisons (0.5 grid system)
|
|
19883
|
+
var endpointTolerance = 0.01; // Very tight tolerance for grid-aligned segments
|
|
19878
19884
|
|
|
19879
|
-
var d1 = segmentEndpoints.start.distanceTo(
|
|
19880
|
-
var d2 = segmentEndpoints.start.distanceTo(
|
|
19881
|
-
var d3 = segmentEndpoints.end.distanceTo(
|
|
19882
|
-
var d4 = segmentEndpoints.end.distanceTo(
|
|
19885
|
+
var d1 = segmentEndpoints.start.distanceTo(otherEndpoints.start);
|
|
19886
|
+
var d2 = segmentEndpoints.start.distanceTo(otherEndpoints.end);
|
|
19887
|
+
var d3 = segmentEndpoints.end.distanceTo(otherEndpoints.start);
|
|
19888
|
+
var d4 = segmentEndpoints.end.distanceTo(otherEndpoints.end);
|
|
19883
19889
|
|
|
19884
|
-
//
|
|
19885
|
-
var
|
|
19890
|
+
// Count how many endpoints are shared/touching
|
|
19891
|
+
var sharedEndpointCount = 0;
|
|
19892
|
+
if (d1 < endpointTolerance) sharedEndpointCount++;
|
|
19893
|
+
if (d2 < endpointTolerance) sharedEndpointCount++;
|
|
19894
|
+
if (d3 < endpointTolerance) sharedEndpointCount++;
|
|
19895
|
+
if (d4 < endpointTolerance) sharedEndpointCount++;
|
|
19886
19896
|
|
|
19887
|
-
// If
|
|
19888
|
-
if (
|
|
19889
|
-
console.log("\
|
|
19897
|
+
// If segments share 2 or more endpoints, they're overlapping on the same line
|
|
19898
|
+
if (sharedEndpointCount >= 2) {
|
|
19899
|
+
console.log("\uD83D\uDD34 Overlapping segments detected - segments share ".concat(sharedEndpointCount, " endpoints"));
|
|
19900
|
+
console.log(" Segment 1: [".concat(segmentEndpoints.start.x.toFixed(2), ", ").concat(segmentEndpoints.start.y.toFixed(2), ", ").concat(segmentEndpoints.start.z.toFixed(2), "] to [").concat(segmentEndpoints.end.x.toFixed(2), ", ").concat(segmentEndpoints.end.y.toFixed(2), ", ").concat(segmentEndpoints.end.z.toFixed(2), "]"));
|
|
19901
|
+
console.log(" Segment 2: [".concat(otherEndpoints.start.x.toFixed(2), ", ").concat(otherEndpoints.start.y.toFixed(2), ", ").concat(otherEndpoints.start.z.toFixed(2), "] to [").concat(otherEndpoints.end.x.toFixed(2), ", ").concat(otherEndpoints.end.y.toFixed(2), ", ").concat(otherEndpoints.end.z.toFixed(2), "]"));
|
|
19902
|
+
hasIntersection = true;
|
|
19890
19903
|
return;
|
|
19891
19904
|
}
|
|
19892
19905
|
|
|
19893
|
-
//
|
|
19894
|
-
|
|
19906
|
+
// If exactly 1 endpoint is shared, check if they overlap along the same line
|
|
19907
|
+
if (sharedEndpointCount === 1) {
|
|
19908
|
+
// Check if segments are collinear (on the same line)
|
|
19909
|
+
var _distance = _this2.calculateSegmentToSegmentDistance(segmentEndpoints.start, segmentEndpoints.end, otherEndpoints.start, otherEndpoints.end);
|
|
19910
|
+
if (_distance < endpointTolerance) {
|
|
19911
|
+
// Segments are on the same line and share one endpoint
|
|
19912
|
+
// This means they overlap along part of their length
|
|
19913
|
+
console.log("\uD83D\uDD34 Overlapping collinear segments detected - share 1 endpoint and are on same line");
|
|
19914
|
+
console.log(" Segment 1: [".concat(segmentEndpoints.start.x.toFixed(2), ", ").concat(segmentEndpoints.start.y.toFixed(2), ", ").concat(segmentEndpoints.start.z.toFixed(2), "] to [").concat(segmentEndpoints.end.x.toFixed(2), ", ").concat(segmentEndpoints.end.y.toFixed(2), ", ").concat(segmentEndpoints.end.z.toFixed(2), "]"));
|
|
19915
|
+
console.log(" Segment 2: [".concat(otherEndpoints.start.x.toFixed(2), ", ").concat(otherEndpoints.start.y.toFixed(2), ", ").concat(otherEndpoints.start.z.toFixed(2), "] to [").concat(otherEndpoints.end.x.toFixed(2), ", ").concat(otherEndpoints.end.y.toFixed(2), ", ").concat(otherEndpoints.end.z.toFixed(2), "]"));
|
|
19916
|
+
console.log(" Distance: ".concat(_distance.toFixed(6)));
|
|
19917
|
+
hasIntersection = true;
|
|
19918
|
+
} else {
|
|
19919
|
+
// Valid end-to-end connection at different angles
|
|
19920
|
+
console.log("\u2705 Segments connected at one endpoint with different directions - valid connection");
|
|
19921
|
+
}
|
|
19922
|
+
return;
|
|
19923
|
+
}
|
|
19924
|
+
|
|
19925
|
+
// No shared endpoints - check if segments cross or overlap
|
|
19926
|
+
var distance = _this2.calculateSegmentToSegmentDistance(segmentEndpoints.start, segmentEndpoints.end, otherEndpoints.start, otherEndpoints.end);
|
|
19895
19927
|
|
|
19896
|
-
//
|
|
19897
|
-
if (distance <
|
|
19898
|
-
|
|
19899
|
-
|
|
19900
|
-
|
|
19928
|
+
// If distance is near zero, segments cross or overlap
|
|
19929
|
+
if (distance < endpointTolerance) {
|
|
19930
|
+
// Special case: T-junction (one segment's endpoint touches the other's line)
|
|
19931
|
+
// This is allowed if the segments are part of the same connection path
|
|
19932
|
+
if (sameConnection) {
|
|
19933
|
+
var _segment$userData8, _segment$userData9;
|
|
19934
|
+
console.log("\u2705 T-junction detected but allowed - segments are part of the same connection (".concat((_segment$userData8 = segment.userData) === null || _segment$userData8 === void 0 ? void 0 : _segment$userData8.pathFrom, " \u2192 ").concat((_segment$userData9 = segment.userData) === null || _segment$userData9 === void 0 ? void 0 : _segment$userData9.pathTo, ")"));
|
|
19935
|
+
return;
|
|
19936
|
+
}
|
|
19937
|
+
console.log("\uD83D\uDD34 Intersection detected - segments cross or overlap");
|
|
19938
|
+
console.log(" Segment 1: [".concat(segmentEndpoints.start.x.toFixed(2), ", ").concat(segmentEndpoints.start.y.toFixed(2), ", ").concat(segmentEndpoints.start.z.toFixed(2), "] to [").concat(segmentEndpoints.end.x.toFixed(2), ", ").concat(segmentEndpoints.end.y.toFixed(2), ", ").concat(segmentEndpoints.end.z.toFixed(2), "]"));
|
|
19939
|
+
console.log(" Segment 2: [".concat(otherEndpoints.start.x.toFixed(2), ", ").concat(otherEndpoints.start.y.toFixed(2), ", ").concat(otherEndpoints.start.z.toFixed(2), "] to [").concat(otherEndpoints.end.x.toFixed(2), ", ").concat(otherEndpoints.end.y.toFixed(2), ", ").concat(otherEndpoints.end.z.toFixed(2), "]"));
|
|
19940
|
+
console.log(" Distance: ".concat(distance.toFixed(6)));
|
|
19901
19941
|
hasIntersection = true;
|
|
19902
19942
|
}
|
|
19903
19943
|
}
|
|
@@ -19905,6 +19945,32 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19905
19945
|
return hasIntersection;
|
|
19906
19946
|
}
|
|
19907
19947
|
|
|
19948
|
+
/**
|
|
19949
|
+
* Get segment endpoints, using stored userData.endpoints if available, otherwise calculate
|
|
19950
|
+
* @param {THREE.Object3D} segment - The segment object
|
|
19951
|
+
* @returns {Object} Object with start and end Vector3 points
|
|
19952
|
+
* @private
|
|
19953
|
+
*/
|
|
19954
|
+
}, {
|
|
19955
|
+
key: "getSegmentEndpoints",
|
|
19956
|
+
value: function getSegmentEndpoints(segment) {
|
|
19957
|
+
var _segment$userData0, _segment$userData1;
|
|
19958
|
+
// Check if segment has stored endpoints in userData
|
|
19959
|
+
if ((_segment$userData0 = segment.userData) !== null && _segment$userData0 !== void 0 && (_segment$userData0 = _segment$userData0.endpoints) !== null && _segment$userData0 !== void 0 && _segment$userData0.startOffset && (_segment$userData1 = segment.userData) !== null && _segment$userData1 !== void 0 && (_segment$userData1 = _segment$userData1.endpoints) !== null && _segment$userData1 !== void 0 && _segment$userData1.endOffset) {
|
|
19960
|
+
// Reconstruct world positions from stored offsets
|
|
19961
|
+
var centerPoint = segment.position;
|
|
19962
|
+
var startOffset = segment.userData.endpoints.startOffset;
|
|
19963
|
+
var endOffset = segment.userData.endpoints.endOffset;
|
|
19964
|
+
return {
|
|
19965
|
+
start: new THREE__namespace.Vector3(centerPoint.x + startOffset.x, centerPoint.y + startOffset.y, centerPoint.z + startOffset.z),
|
|
19966
|
+
end: new THREE__namespace.Vector3(centerPoint.x + endOffset.x, centerPoint.y + endOffset.y, centerPoint.z + endOffset.z)
|
|
19967
|
+
};
|
|
19968
|
+
}
|
|
19969
|
+
|
|
19970
|
+
// Fallback to calculating endpoints from geometry
|
|
19971
|
+
return this.calculateSegmentEndpoints(segment);
|
|
19972
|
+
}
|
|
19973
|
+
|
|
19908
19974
|
/**
|
|
19909
19975
|
* Check if any point along a segment's path would collide with component connector within 0.5 radius
|
|
19910
19976
|
* @param {THREE.Object3D} segment - The segment to check
|
|
@@ -19914,8 +19980,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19914
19980
|
}, {
|
|
19915
19981
|
key: "checkSegmentPathConnectorCollision",
|
|
19916
19982
|
value: function checkSegmentPathConnectorCollision(segment) {
|
|
19917
|
-
var _this$
|
|
19918
|
-
if (!((_this$
|
|
19983
|
+
var _this$sceneViewer5;
|
|
19984
|
+
if (!((_this$sceneViewer5 = this.sceneViewer) !== null && _this$sceneViewer5 !== void 0 && _this$sceneViewer5.scene) || !segment) {
|
|
19919
19985
|
return null;
|
|
19920
19986
|
}
|
|
19921
19987
|
var collisionRadius = 0.5; // Radius around connector that triggers collision
|
|
@@ -19929,11 +19995,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19929
19995
|
|
|
19930
19996
|
// Traverse scene to find all component connectors
|
|
19931
19997
|
this.sceneViewer.scene.traverse(function (child) {
|
|
19932
|
-
var _child$
|
|
19998
|
+
var _child$userData11;
|
|
19933
19999
|
if (collision) return; // Stop if collision already found
|
|
19934
20000
|
|
|
19935
20001
|
// Check if this is a component connector (not a segment-connector)
|
|
19936
|
-
if (((_child$
|
|
20002
|
+
if (((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType) === 'connector') {
|
|
19937
20003
|
// Get world position of connector
|
|
19938
20004
|
var connectorWorldPos = new THREE__namespace.Vector3();
|
|
19939
20005
|
child.getWorldPosition(connectorWorldPos);
|
|
@@ -19954,8 +20020,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19954
20020
|
|
|
19955
20021
|
// Handle degenerate case (zero-length segment)
|
|
19956
20022
|
if (segmentLengthSquared < 1e-10) {
|
|
19957
|
-
var
|
|
19958
|
-
if (
|
|
20023
|
+
var _distance2 = startPoint.distanceTo(connectorWorldPos);
|
|
20024
|
+
if (_distance2 <= collisionRadius) {
|
|
19959
20025
|
// Find the parent component
|
|
19960
20026
|
var component = child.parent;
|
|
19961
20027
|
while (component && !((_component$userData2 = component.userData) !== null && _component$userData2 !== void 0 && _component$userData2.libraryId)) {
|
|
@@ -19975,7 +20041,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19975
20041
|
y: startPoint.y,
|
|
19976
20042
|
z: startPoint.z
|
|
19977
20043
|
},
|
|
19978
|
-
distance:
|
|
20044
|
+
distance: _distance2
|
|
19979
20045
|
};
|
|
19980
20046
|
}
|
|
19981
20047
|
return;
|
|
@@ -20029,8 +20095,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20029
20095
|
}, {
|
|
20030
20096
|
key: "checkComponentConnectorCollision",
|
|
20031
20097
|
value: function checkComponentConnectorCollision(newPosition) {
|
|
20032
|
-
var _this$
|
|
20033
|
-
if (!((_this$
|
|
20098
|
+
var _this$sceneViewer6;
|
|
20099
|
+
if (!((_this$sceneViewer6 = this.sceneViewer) !== null && _this$sceneViewer6 !== void 0 && _this$sceneViewer6.scene)) {
|
|
20034
20100
|
return null;
|
|
20035
20101
|
}
|
|
20036
20102
|
var tolerance = 0.01; // Small tolerance for floating-point comparison
|
|
@@ -20038,9 +20104,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20038
20104
|
|
|
20039
20105
|
// Traverse scene to find all component connectors
|
|
20040
20106
|
this.sceneViewer.scene.traverse(function (child) {
|
|
20041
|
-
var _child$
|
|
20107
|
+
var _child$userData12;
|
|
20042
20108
|
// Check if this is a component connector (not a segment-connector)
|
|
20043
|
-
if (((_child$
|
|
20109
|
+
if (((_child$userData12 = child.userData) === null || _child$userData12 === void 0 ? void 0 : _child$userData12.objectType) === 'connector') {
|
|
20044
20110
|
// Get world position of connector
|
|
20045
20111
|
var connectorWorldPos = new THREE__namespace.Vector3();
|
|
20046
20112
|
child.getWorldPosition(connectorWorldPos);
|
|
@@ -20086,8 +20152,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20086
20152
|
}, {
|
|
20087
20153
|
key: "checkSegmentComponentBoundingBoxCollision",
|
|
20088
20154
|
value: function checkSegmentComponentBoundingBoxCollision(segment) {
|
|
20089
|
-
var _this$
|
|
20090
|
-
if (!((_this$
|
|
20155
|
+
var _this$sceneViewer7;
|
|
20156
|
+
if (!((_this$sceneViewer7 = this.sceneViewer) !== null && _this$sceneViewer7 !== void 0 && _this$sceneViewer7.scene) || !segment) {
|
|
20091
20157
|
return null;
|
|
20092
20158
|
}
|
|
20093
20159
|
|
|
@@ -20097,11 +20163,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20097
20163
|
|
|
20098
20164
|
// Traverse scene to find all components
|
|
20099
20165
|
this.sceneViewer.scene.traverse(function (child) {
|
|
20100
|
-
var _child$
|
|
20166
|
+
var _child$userData13, _child$userData14;
|
|
20101
20167
|
if (collision) return; // Stop if collision already found
|
|
20102
20168
|
|
|
20103
20169
|
// Check if this is a component (equipment)
|
|
20104
|
-
if (((_child$
|
|
20170
|
+
if (((_child$userData13 = child.userData) === null || _child$userData13 === void 0 ? void 0 : _child$userData13.objectType) === 'component' && (_child$userData14 = child.userData) !== null && _child$userData14 !== void 0 && _child$userData14.libraryId) {
|
|
20105
20171
|
// Create bounding box for the component
|
|
20106
20172
|
var componentBBox = new THREE__namespace.Box3().setFromObject(child);
|
|
20107
20173
|
|
|
@@ -20228,10 +20294,10 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20228
20294
|
}, {
|
|
20229
20295
|
key: "snapSegmentConnectorsToNearbyEndpoints",
|
|
20230
20296
|
value: function snapSegmentConnectorsToNearbyEndpoints(movedSegment) {
|
|
20231
|
-
var _this$
|
|
20232
|
-
_this$
|
|
20297
|
+
var _this$sceneViewer8,
|
|
20298
|
+
_this$sceneViewer9,
|
|
20233
20299
|
_this3 = this;
|
|
20234
|
-
if (!movedSegment || !((_this$
|
|
20300
|
+
if (!movedSegment || !((_this$sceneViewer8 = this.sceneViewer) !== null && _this$sceneViewer8 !== void 0 && _this$sceneViewer8.scene)) {
|
|
20235
20301
|
return [];
|
|
20236
20302
|
}
|
|
20237
20303
|
console.log('🔗 Finding adjacent segments connected to moved segment...');
|
|
@@ -20239,8 +20305,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20239
20305
|
// Get the moved segment's connectors
|
|
20240
20306
|
var movedConnectors = [];
|
|
20241
20307
|
movedSegment.traverse(function (child) {
|
|
20242
|
-
var _child$
|
|
20243
|
-
if (((_child$
|
|
20308
|
+
var _child$userData15;
|
|
20309
|
+
if (((_child$userData15 = child.userData) === null || _child$userData15 === void 0 ? void 0 : _child$userData15.objectType) === 'segment-connector') {
|
|
20244
20310
|
movedConnectors.push(child);
|
|
20245
20311
|
}
|
|
20246
20312
|
});
|
|
@@ -20253,7 +20319,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20253
20319
|
var newEndpoints = this.calculateSegmentEndpoints(movedSegment);
|
|
20254
20320
|
|
|
20255
20321
|
// Check scene data for connections involving the moved segment's connectors
|
|
20256
|
-
var connections = ((_this$
|
|
20322
|
+
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) || [];
|
|
20257
20323
|
var movedConnectorIds = movedConnectors.map(function (c) {
|
|
20258
20324
|
return c.uuid;
|
|
20259
20325
|
});
|
|
@@ -20310,8 +20376,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20310
20376
|
// Get all connectors of the adjacent segment
|
|
20311
20377
|
var adjacentConnectors = [];
|
|
20312
20378
|
adjacentSegment.traverse(function (child) {
|
|
20313
|
-
var _child$
|
|
20314
|
-
if (((_child$
|
|
20379
|
+
var _child$userData16;
|
|
20380
|
+
if (((_child$userData16 = child.userData) === null || _child$userData16 === void 0 ? void 0 : _child$userData16.objectType) === 'segment-connector') {
|
|
20315
20381
|
adjacentConnectors.push(child);
|
|
20316
20382
|
}
|
|
20317
20383
|
});
|
|
@@ -20399,6 +20465,68 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20399
20465
|
this.updateConnectorPositionInSceneData(connector, worldPosition, parentSegment);
|
|
20400
20466
|
}
|
|
20401
20467
|
|
|
20468
|
+
/**
|
|
20469
|
+
* Update component position in currentSceneData after translation
|
|
20470
|
+
* @param {THREE.Object3D} component - The component that was translated
|
|
20471
|
+
* @private
|
|
20472
|
+
*/
|
|
20473
|
+
}, {
|
|
20474
|
+
key: "updateComponentPositionInSceneData",
|
|
20475
|
+
value: function updateComponentPositionInSceneData(component) {
|
|
20476
|
+
var _this$sceneViewer0;
|
|
20477
|
+
if (!((_this$sceneViewer0 = this.sceneViewer) !== null && _this$sceneViewer0 !== void 0 && (_this$sceneViewer0 = _this$sceneViewer0.currentSceneData) !== null && _this$sceneViewer0 !== void 0 && _this$sceneViewer0.scene)) {
|
|
20478
|
+
console.warn('⚠️ Cannot update component position: currentSceneData not available');
|
|
20479
|
+
return;
|
|
20480
|
+
}
|
|
20481
|
+
var cleanPosition = function cleanPosition(value) {
|
|
20482
|
+
return Math.abs(value) < 1e-10 ? 0 : value;
|
|
20483
|
+
};
|
|
20484
|
+
|
|
20485
|
+
// Find the component in scene data
|
|
20486
|
+
var sceneDataComponent = this.sceneViewer.currentSceneData.scene.children.find(function (child) {
|
|
20487
|
+
var _component$userData5;
|
|
20488
|
+
return child.uuid === component.uuid || child.uuid === ((_component$userData5 = component.userData) === null || _component$userData5 === void 0 ? void 0 : _component$userData5.originalUuid);
|
|
20489
|
+
});
|
|
20490
|
+
if (sceneDataComponent) {
|
|
20491
|
+
// Update position object for components (different from connectors which use array)
|
|
20492
|
+
if (!sceneDataComponent.position) {
|
|
20493
|
+
sceneDataComponent.position = {};
|
|
20494
|
+
}
|
|
20495
|
+
sceneDataComponent.position.x = cleanPosition(component.position.x);
|
|
20496
|
+
sceneDataComponent.position.y = cleanPosition(component.position.y);
|
|
20497
|
+
sceneDataComponent.position.z = cleanPosition(component.position.z);
|
|
20498
|
+
console.log("\u2705 Updated component ".concat(component.uuid, " position in scene data to [").concat(component.position.x, ", ").concat(component.position.y, ", ").concat(component.position.z, "]"));
|
|
20499
|
+
|
|
20500
|
+
// Also update child connectors' positions if they exist
|
|
20501
|
+
if (sceneDataComponent.children) {
|
|
20502
|
+
sceneDataComponent.children.forEach(function (child) {
|
|
20503
|
+
var _child$userData17;
|
|
20504
|
+
if (((_child$userData17 = child.userData) === null || _child$userData17 === void 0 ? void 0 : _child$userData17.objectType) === 'connector') {
|
|
20505
|
+
// Find the actual connector object in the scene
|
|
20506
|
+
var connectorObj = component.children.find(function (c) {
|
|
20507
|
+
var _c$userData;
|
|
20508
|
+
return c.uuid === child.uuid || ((_c$userData = c.userData) === null || _c$userData === void 0 ? void 0 : _c$userData.originalUuid) === child.uuid;
|
|
20509
|
+
});
|
|
20510
|
+
if (connectorObj) {
|
|
20511
|
+
// Get world position of connector
|
|
20512
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
20513
|
+
connectorObj.getWorldPosition(worldPos);
|
|
20514
|
+
|
|
20515
|
+
// Update connector's position in userData as array
|
|
20516
|
+
if (!child.userData) {
|
|
20517
|
+
child.userData = {};
|
|
20518
|
+
}
|
|
20519
|
+
child.userData.position = [cleanPosition(worldPos.x), cleanPosition(worldPos.y), cleanPosition(worldPos.z)];
|
|
20520
|
+
console.log(" \u21B3 Updated child connector ".concat(child.uuid, " position to [").concat(child.userData.position.join(', '), "]"));
|
|
20521
|
+
}
|
|
20522
|
+
}
|
|
20523
|
+
});
|
|
20524
|
+
}
|
|
20525
|
+
} else {
|
|
20526
|
+
console.warn("\u26A0\uFE0F Component ".concat(component.uuid, " not found in scene data"));
|
|
20527
|
+
}
|
|
20528
|
+
}
|
|
20529
|
+
|
|
20402
20530
|
/**
|
|
20403
20531
|
* Update a connector's position in scene data
|
|
20404
20532
|
* @param {THREE.Object3D} connector - The connector to update
|
|
@@ -20681,8 +20809,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20681
20809
|
// Remove segment from scene data
|
|
20682
20810
|
if (currentSceneData.scene && currentSceneData.scene.children) {
|
|
20683
20811
|
var segmentIndex = currentSceneData.scene.children.findIndex(function (child) {
|
|
20684
|
-
var _segment$
|
|
20685
|
-
return child.uuid === segment.uuid || child.uuid === ((_segment$
|
|
20812
|
+
var _segment$userData10;
|
|
20813
|
+
return child.uuid === segment.uuid || child.uuid === ((_segment$userData10 = segment.userData) === null || _segment$userData10 === void 0 ? void 0 : _segment$userData10.originalUuid);
|
|
20686
20814
|
});
|
|
20687
20815
|
if (segmentIndex !== -1) {
|
|
20688
20816
|
currentSceneData.scene.children.splice(segmentIndex, 1);
|
|
@@ -20702,8 +20830,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20702
20830
|
// Check if either external connector belongs to the active segment
|
|
20703
20831
|
var activeSegmentConnectors = [];
|
|
20704
20832
|
activeSegment.traverse(function (child) {
|
|
20705
|
-
var _child$
|
|
20706
|
-
if (((_child$
|
|
20833
|
+
var _child$userData18;
|
|
20834
|
+
if (((_child$userData18 = child.userData) === null || _child$userData18 === void 0 ? void 0 : _child$userData18.objectType) === 'segment-connector') {
|
|
20707
20835
|
activeSegmentConnectors.push(child.uuid);
|
|
20708
20836
|
}
|
|
20709
20837
|
});
|
|
@@ -20751,8 +20879,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20751
20879
|
// Get all connectors of the active segment
|
|
20752
20880
|
var activeConnectors = [];
|
|
20753
20881
|
activeSegment.traverse(function (child) {
|
|
20754
|
-
var _child$
|
|
20755
|
-
if (((_child$
|
|
20882
|
+
var _child$userData19;
|
|
20883
|
+
if (((_child$userData19 = child.userData) === null || _child$userData19 === void 0 ? void 0 : _child$userData19.objectType) === 'segment-connector') {
|
|
20756
20884
|
activeConnectors.push(child);
|
|
20757
20885
|
}
|
|
20758
20886
|
});
|
|
@@ -24564,365 +24692,6 @@ var PathData = /*#__PURE__*/function () {
|
|
|
24564
24692
|
}]);
|
|
24565
24693
|
}();
|
|
24566
24694
|
|
|
24567
|
-
/**
|
|
24568
|
-
* PathIntersectionDetector - Detects intersections between pipe paths
|
|
24569
|
-
*
|
|
24570
|
-
* This class handles all intersection detection logic for both computed paths
|
|
24571
|
-
* (from pathfinding) and manual segments (user-positioned pipes).
|
|
24572
|
-
*
|
|
24573
|
-
* @class PathIntersectionDetector
|
|
24574
|
-
*/
|
|
24575
|
-
var PathIntersectionDetector = /*#__PURE__*/function () {
|
|
24576
|
-
/**
|
|
24577
|
-
* Create a new PathIntersectionDetector
|
|
24578
|
-
* @param {Object} sceneViewer - Reference to the scene viewer
|
|
24579
|
-
*/
|
|
24580
|
-
function PathIntersectionDetector(sceneViewer) {
|
|
24581
|
-
_classCallCheck(this, PathIntersectionDetector);
|
|
24582
|
-
this.sceneViewer = sceneViewer;
|
|
24583
|
-
}
|
|
24584
|
-
|
|
24585
|
-
/**
|
|
24586
|
-
* Check for intersections between paths
|
|
24587
|
-
* @param {Array} paths - Array of path objects from pathfinder
|
|
24588
|
-
* @param {number} tolerance - Distance tolerance for considering pipes as intersecting (default: 0.2)
|
|
24589
|
-
* @param {boolean} includeManualSegments - Whether to include manual segments in the check (default: true)
|
|
24590
|
-
* @returns {Object} Intersection results
|
|
24591
|
-
* @property {boolean} hasIntersections - Whether any intersections were found
|
|
24592
|
-
* @property {Array<Object>} intersections - Array of intersection details
|
|
24593
|
-
* @property {number} count - Total number of intersections found
|
|
24594
|
-
*/
|
|
24595
|
-
return _createClass(PathIntersectionDetector, [{
|
|
24596
|
-
key: "checkPathIntersections",
|
|
24597
|
-
value: function checkPathIntersections(paths) {
|
|
24598
|
-
var tolerance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.2;
|
|
24599
|
-
var includeManualSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
24600
|
-
var intersections = [];
|
|
24601
|
-
|
|
24602
|
-
// Convert all paths to line segments for comparison
|
|
24603
|
-
var pathSegments = paths.map(function (pathData, pathIndex) {
|
|
24604
|
-
if (!pathData.path || pathData.path.length < 2) {
|
|
24605
|
-
return null;
|
|
24606
|
-
}
|
|
24607
|
-
var segments = [];
|
|
24608
|
-
var pathPoints = pathData.path.map(function (point) {
|
|
24609
|
-
if (point instanceof THREE__namespace.Vector3) {
|
|
24610
|
-
return point.clone();
|
|
24611
|
-
} else if (Array.isArray(point)) {
|
|
24612
|
-
return new THREE__namespace.Vector3().fromArray(point);
|
|
24613
|
-
} else if (point.x !== undefined && point.y !== undefined && point.z !== undefined) {
|
|
24614
|
-
return new THREE__namespace.Vector3(point.x, point.y, point.z);
|
|
24615
|
-
}
|
|
24616
|
-
return null;
|
|
24617
|
-
}).filter(function (p) {
|
|
24618
|
-
return p !== null;
|
|
24619
|
-
});
|
|
24620
|
-
for (var i = 0; i < pathPoints.length - 1; i++) {
|
|
24621
|
-
segments.push({
|
|
24622
|
-
start: pathPoints[i],
|
|
24623
|
-
end: pathPoints[i + 1],
|
|
24624
|
-
pathIndex: pathIndex,
|
|
24625
|
-
segmentIndex: i,
|
|
24626
|
-
pathFrom: pathData.from,
|
|
24627
|
-
pathTo: pathData.to,
|
|
24628
|
-
isFirstSegment: i === 0,
|
|
24629
|
-
isLastSegment: i === pathPoints.length - 2,
|
|
24630
|
-
isManual: false // Computed path segment
|
|
24631
|
-
});
|
|
24632
|
-
}
|
|
24633
|
-
return segments;
|
|
24634
|
-
}).filter(function (s) {
|
|
24635
|
-
return s !== null;
|
|
24636
|
-
}).flat();
|
|
24637
|
-
|
|
24638
|
-
// Add manual segments if requested
|
|
24639
|
-
if (includeManualSegments) {
|
|
24640
|
-
var manualSegments = this._collectManualSegments(pathSegments.length);
|
|
24641
|
-
pathSegments.push.apply(pathSegments, _toConsumableArray(manualSegments));
|
|
24642
|
-
console.log("\uD83D\uDCE6 Added ".concat(manualSegments.length, " manual segment(s) to intersection check"));
|
|
24643
|
-
}
|
|
24644
|
-
console.log("\uD83D\uDD0D Checking ".concat(pathSegments.length, " segments for intersections..."));
|
|
24645
|
-
|
|
24646
|
-
// Check each pair of segments
|
|
24647
|
-
for (var i = 0; i < pathSegments.length; i++) {
|
|
24648
|
-
for (var j = i + 1; j < pathSegments.length; j++) {
|
|
24649
|
-
var seg1 = pathSegments[i];
|
|
24650
|
-
var seg2 = pathSegments[j];
|
|
24651
|
-
|
|
24652
|
-
// Skip if segments are from the same path
|
|
24653
|
-
if (seg1.pathIndex === seg2.pathIndex) {
|
|
24654
|
-
continue;
|
|
24655
|
-
}
|
|
24656
|
-
|
|
24657
|
-
// Check if segments intersect
|
|
24658
|
-
var intersection = this._checkLineSegmentIntersection(seg1.start, seg1.end, seg2.start, seg2.end, tolerance);
|
|
24659
|
-
if (intersection) {
|
|
24660
|
-
// Check if this is a shared endpoint (connector/gateway)
|
|
24661
|
-
// Paths naturally touch at shared connectors - this is not an intersection
|
|
24662
|
-
var endpointTolerance = 0.01; // Very small tolerance for endpoint matching
|
|
24663
|
-
var touchingAtEndpoint = this._areSegmentsTouchingAtSharedEndpoint(seg1, seg2, endpointTolerance);
|
|
24664
|
-
if (touchingAtEndpoint) {
|
|
24665
|
-
console.log("\u2139\uFE0F Segments share endpoint (not an intersection): ".concat(seg1.pathFrom, " \u2194 ").concat(seg2.pathFrom));
|
|
24666
|
-
continue; // Skip this - it's a valid shared connection point
|
|
24667
|
-
}
|
|
24668
|
-
intersections.push({
|
|
24669
|
-
path1: {
|
|
24670
|
-
from: seg1.pathFrom,
|
|
24671
|
-
to: seg1.pathTo,
|
|
24672
|
-
segmentIndex: seg1.segmentIndex,
|
|
24673
|
-
isManual: seg1.isManual
|
|
24674
|
-
},
|
|
24675
|
-
path2: {
|
|
24676
|
-
from: seg2.pathFrom,
|
|
24677
|
-
to: seg2.pathTo,
|
|
24678
|
-
segmentIndex: seg2.segmentIndex,
|
|
24679
|
-
isManual: seg2.isManual
|
|
24680
|
-
},
|
|
24681
|
-
point: intersection.point,
|
|
24682
|
-
distance: intersection.distance,
|
|
24683
|
-
type: intersection.type
|
|
24684
|
-
});
|
|
24685
|
-
var seg1Type = seg1.isManual ? 'manual' : 'computed';
|
|
24686
|
-
var seg2Type = seg2.isManual ? 'manual' : 'computed';
|
|
24687
|
-
console.log("\u26A0\uFE0F Intersection found between paths:\n Path 1 (".concat(seg1Type, "): ").concat(seg1.pathFrom, " \u2192 ").concat(seg1.pathTo, " (segment ").concat(seg1.segmentIndex, ")\n Path 2 (").concat(seg2Type, "): ").concat(seg2.pathFrom, " \u2192 ").concat(seg2.pathTo, " (segment ").concat(seg2.segmentIndex, ")\n Distance: ").concat(intersection.distance.toFixed(4), "\n Type: ").concat(intersection.type));
|
|
24688
|
-
}
|
|
24689
|
-
}
|
|
24690
|
-
}
|
|
24691
|
-
var result = {
|
|
24692
|
-
hasIntersections: intersections.length > 0,
|
|
24693
|
-
intersections: intersections,
|
|
24694
|
-
count: intersections.length
|
|
24695
|
-
};
|
|
24696
|
-
if (result.hasIntersections) {
|
|
24697
|
-
console.log("\uD83D\uDEA8 Found ".concat(result.count, " intersection(s) between paths"));
|
|
24698
|
-
} else {
|
|
24699
|
-
console.log("\u2705 No path intersections detected");
|
|
24700
|
-
}
|
|
24701
|
-
return result;
|
|
24702
|
-
}
|
|
24703
|
-
|
|
24704
|
-
/**
|
|
24705
|
-
* Collect manual segments from the scene and convert them to path segments format
|
|
24706
|
-
* @private
|
|
24707
|
-
* @param {number} startingPathIndex - The starting index for manual segment paths
|
|
24708
|
-
* @returns {Array} Array of segment objects in the same format as computed paths
|
|
24709
|
-
*/
|
|
24710
|
-
}, {
|
|
24711
|
-
key: "_collectManualSegments",
|
|
24712
|
-
value: function _collectManualSegments(startingPathIndex) {
|
|
24713
|
-
var _this = this;
|
|
24714
|
-
var manualSegments = [];
|
|
24715
|
-
var sceneViewer = this.sceneViewer;
|
|
24716
|
-
var pathIndex = startingPathIndex;
|
|
24717
|
-
|
|
24718
|
-
// Traverse the scene to find manual segments (lowercase "Segment-")
|
|
24719
|
-
sceneViewer.scene.traverse(function (obj) {
|
|
24720
|
-
var _obj$userData, _obj$userData2;
|
|
24721
|
-
if (obj.uuid && obj.uuid.startsWith('Segment-') && ((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) === 'segment' && ((_obj$userData2 = obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.isDeclared) === true) {
|
|
24722
|
-
// Calculate segment endpoints from the cylinder geometry
|
|
24723
|
-
var endpoints = _this._calculateSegmentEndpoints(obj);
|
|
24724
|
-
|
|
24725
|
-
// Create segment object in the same format as computed paths
|
|
24726
|
-
manualSegments.push({
|
|
24727
|
-
start: endpoints.start,
|
|
24728
|
-
end: endpoints.end,
|
|
24729
|
-
pathIndex: pathIndex,
|
|
24730
|
-
segmentIndex: 0,
|
|
24731
|
-
// Manual segments are single-segment paths
|
|
24732
|
-
pathFrom: obj.userData.pathFrom || obj.uuid,
|
|
24733
|
-
pathTo: obj.userData.pathTo || obj.uuid,
|
|
24734
|
-
isFirstSegment: true,
|
|
24735
|
-
isLastSegment: true,
|
|
24736
|
-
isManual: true,
|
|
24737
|
-
// Flag to identify manual segments
|
|
24738
|
-
segmentUuid: obj.uuid
|
|
24739
|
-
});
|
|
24740
|
-
pathIndex++;
|
|
24741
|
-
console.log("\uD83D\uDCE6 Collected manual segment: ".concat(obj.uuid));
|
|
24742
|
-
}
|
|
24743
|
-
});
|
|
24744
|
-
return manualSegments;
|
|
24745
|
-
}
|
|
24746
|
-
|
|
24747
|
-
/**
|
|
24748
|
-
* Calculate the start and end points of a pipe segment in world coordinates
|
|
24749
|
-
* @private
|
|
24750
|
-
* @param {THREE.Object3D} segment - The pipe segment
|
|
24751
|
-
* @returns {Object} Object with start and end points
|
|
24752
|
-
*/
|
|
24753
|
-
}, {
|
|
24754
|
-
key: "_calculateSegmentEndpoints",
|
|
24755
|
-
value: function _calculateSegmentEndpoints(segment) {
|
|
24756
|
-
// Get the segment's geometry to determine its length and orientation
|
|
24757
|
-
var geometry = segment.geometry;
|
|
24758
|
-
var length = geometry.parameters.height || 1;
|
|
24759
|
-
|
|
24760
|
-
// Calculate start and end points based on segment position and orientation
|
|
24761
|
-
var startPoint = new THREE__namespace.Vector3();
|
|
24762
|
-
var endPoint = new THREE__namespace.Vector3();
|
|
24763
|
-
|
|
24764
|
-
// Get the segment's direction vector
|
|
24765
|
-
var direction = new THREE__namespace.Vector3(0, 1, 0);
|
|
24766
|
-
direction.applyQuaternion(segment.quaternion);
|
|
24767
|
-
|
|
24768
|
-
// Calculate start point (half length back from center)
|
|
24769
|
-
startPoint.copy(segment.position).sub(direction.clone().multiplyScalar(length / 2));
|
|
24770
|
-
|
|
24771
|
-
// Calculate end point (half length forward from center)
|
|
24772
|
-
endPoint.copy(segment.position).add(direction.clone().multiplyScalar(length / 2));
|
|
24773
|
-
return {
|
|
24774
|
-
start: startPoint,
|
|
24775
|
-
end: endPoint
|
|
24776
|
-
};
|
|
24777
|
-
}
|
|
24778
|
-
|
|
24779
|
-
/**
|
|
24780
|
-
* Check if two segments are touching at a shared endpoint (connector/gateway)
|
|
24781
|
-
* @private
|
|
24782
|
-
* @param {Object} seg1 - First segment
|
|
24783
|
-
* @param {Object} seg2 - Second segment
|
|
24784
|
-
* @param {number} tolerance - Distance tolerance for considering points as the same
|
|
24785
|
-
* @returns {boolean} True if segments share an endpoint
|
|
24786
|
-
*/
|
|
24787
|
-
}, {
|
|
24788
|
-
key: "_areSegmentsTouchingAtSharedEndpoint",
|
|
24789
|
-
value: function _areSegmentsTouchingAtSharedEndpoint(seg1, seg2, tolerance) {
|
|
24790
|
-
// Check all possible endpoint combinations
|
|
24791
|
-
var endpoints = [
|
|
24792
|
-
// seg1.start with seg2 endpoints
|
|
24793
|
-
{
|
|
24794
|
-
p1: seg1.start,
|
|
24795
|
-
p2: seg2.start,
|
|
24796
|
-
isSeg1Start: true,
|
|
24797
|
-
isSeg2Start: true
|
|
24798
|
-
}, {
|
|
24799
|
-
p1: seg1.start,
|
|
24800
|
-
p2: seg2.end,
|
|
24801
|
-
isSeg1Start: true,
|
|
24802
|
-
isSeg2Start: false
|
|
24803
|
-
},
|
|
24804
|
-
// seg1.end with seg2 endpoints
|
|
24805
|
-
{
|
|
24806
|
-
p1: seg1.end,
|
|
24807
|
-
p2: seg2.start,
|
|
24808
|
-
isSeg1Start: false,
|
|
24809
|
-
isSeg2Start: true
|
|
24810
|
-
}, {
|
|
24811
|
-
p1: seg1.end,
|
|
24812
|
-
p2: seg2.end,
|
|
24813
|
-
isSeg1Start: false,
|
|
24814
|
-
isSeg2Start: false
|
|
24815
|
-
}];
|
|
24816
|
-
for (var _i = 0, _endpoints = endpoints; _i < _endpoints.length; _i++) {
|
|
24817
|
-
var _endpoints$_i = _endpoints[_i],
|
|
24818
|
-
p1 = _endpoints$_i.p1,
|
|
24819
|
-
p2 = _endpoints$_i.p2,
|
|
24820
|
-
isSeg1Start = _endpoints$_i.isSeg1Start,
|
|
24821
|
-
isSeg2Start = _endpoints$_i.isSeg2Start;
|
|
24822
|
-
var distance = p1.distanceTo(p2);
|
|
24823
|
-
if (distance <= tolerance) {
|
|
24824
|
-
// Verify this is actually an endpoint of the path (not just any segment point)
|
|
24825
|
-
var isSeg1Endpoint = isSeg1Start && seg1.isFirstSegment || !isSeg1Start && seg1.isLastSegment;
|
|
24826
|
-
var isSeg2Endpoint = isSeg2Start && seg2.isFirstSegment || !isSeg2Start && seg2.isLastSegment;
|
|
24827
|
-
|
|
24828
|
-
// Only count as shared endpoint if at least one is a path endpoint
|
|
24829
|
-
// (This handles both connector-to-connector and connector-to-gateway cases)
|
|
24830
|
-
if (isSeg1Endpoint || isSeg2Endpoint) {
|
|
24831
|
-
return true;
|
|
24832
|
-
}
|
|
24833
|
-
}
|
|
24834
|
-
}
|
|
24835
|
-
return false;
|
|
24836
|
-
}
|
|
24837
|
-
|
|
24838
|
-
/**
|
|
24839
|
-
* Check if two line segments intersect or come within tolerance distance
|
|
24840
|
-
* @private
|
|
24841
|
-
* @param {THREE.Vector3} p1 - Start of first segment
|
|
24842
|
-
* @param {THREE.Vector3} p2 - End of first segment
|
|
24843
|
-
* @param {THREE.Vector3} p3 - Start of second segment
|
|
24844
|
-
* @param {THREE.Vector3} p4 - End of second segment
|
|
24845
|
-
* @param {number} tolerance - Distance tolerance
|
|
24846
|
-
* @returns {Object|null} Intersection details or null
|
|
24847
|
-
*/
|
|
24848
|
-
}, {
|
|
24849
|
-
key: "_checkLineSegmentIntersection",
|
|
24850
|
-
value: function _checkLineSegmentIntersection(p1, p2, p3, p4, tolerance) {
|
|
24851
|
-
// Calculate closest points on two line segments
|
|
24852
|
-
var d1 = new THREE__namespace.Vector3().subVectors(p2, p1); // Direction of segment 1
|
|
24853
|
-
var d2 = new THREE__namespace.Vector3().subVectors(p4, p3); // Direction of segment 2
|
|
24854
|
-
var r = new THREE__namespace.Vector3().subVectors(p1, p3);
|
|
24855
|
-
var a = d1.dot(d1);
|
|
24856
|
-
var b = d1.dot(d2);
|
|
24857
|
-
var c = d2.dot(d2);
|
|
24858
|
-
var d = d1.dot(r);
|
|
24859
|
-
var e = d2.dot(r);
|
|
24860
|
-
var denom = a * c - b * b;
|
|
24861
|
-
|
|
24862
|
-
// Check if lines are parallel
|
|
24863
|
-
if (Math.abs(denom) < 1e-10) {
|
|
24864
|
-
// Lines are parallel, check if they're close enough
|
|
24865
|
-
var distToLine = this._distancePointToLineSegment(p3, p1, p2);
|
|
24866
|
-
if (distToLine <= tolerance) {
|
|
24867
|
-
return {
|
|
24868
|
-
point: p3.clone(),
|
|
24869
|
-
distance: distToLine,
|
|
24870
|
-
type: 'parallel'
|
|
24871
|
-
};
|
|
24872
|
-
}
|
|
24873
|
-
return null;
|
|
24874
|
-
}
|
|
24875
|
-
|
|
24876
|
-
// Calculate parameters for closest points
|
|
24877
|
-
var s = (b * e - c * d) / denom;
|
|
24878
|
-
var t = (a * e - b * d) / denom;
|
|
24879
|
-
|
|
24880
|
-
// Clamp to segment bounds
|
|
24881
|
-
s = Math.max(0, Math.min(1, s));
|
|
24882
|
-
t = Math.max(0, Math.min(1, t));
|
|
24883
|
-
|
|
24884
|
-
// Calculate closest points
|
|
24885
|
-
var closestPoint1 = new THREE__namespace.Vector3().addVectors(p1, d1.clone().multiplyScalar(s));
|
|
24886
|
-
var closestPoint2 = new THREE__namespace.Vector3().addVectors(p3, d2.clone().multiplyScalar(t));
|
|
24887
|
-
|
|
24888
|
-
// Calculate distance between closest points
|
|
24889
|
-
var distance = closestPoint1.distanceTo(closestPoint2);
|
|
24890
|
-
|
|
24891
|
-
// Check if within tolerance
|
|
24892
|
-
if (distance <= tolerance) {
|
|
24893
|
-
var midPoint = new THREE__namespace.Vector3().addVectors(closestPoint1, closestPoint2).multiplyScalar(0.5);
|
|
24894
|
-
return {
|
|
24895
|
-
point: midPoint,
|
|
24896
|
-
distance: distance,
|
|
24897
|
-
type: distance < 0.01 ? 'crossing' : 'near'
|
|
24898
|
-
};
|
|
24899
|
-
}
|
|
24900
|
-
return null;
|
|
24901
|
-
}
|
|
24902
|
-
|
|
24903
|
-
/**
|
|
24904
|
-
* Calculate distance from a point to a line segment
|
|
24905
|
-
* @private
|
|
24906
|
-
* @param {THREE.Vector3} point - The point
|
|
24907
|
-
* @param {THREE.Vector3} lineStart - Start of line segment
|
|
24908
|
-
* @param {THREE.Vector3} lineEnd - End of line segment
|
|
24909
|
-
* @returns {number} Distance to line segment
|
|
24910
|
-
*/
|
|
24911
|
-
}, {
|
|
24912
|
-
key: "_distancePointToLineSegment",
|
|
24913
|
-
value: function _distancePointToLineSegment(point, lineStart, lineEnd) {
|
|
24914
|
-
var line = new THREE__namespace.Vector3().subVectors(lineEnd, lineStart);
|
|
24915
|
-
var lineLength = line.length();
|
|
24916
|
-
if (lineLength < 1e-10) {
|
|
24917
|
-
return point.distanceTo(lineStart);
|
|
24918
|
-
}
|
|
24919
|
-
var t = Math.max(0, Math.min(1, new THREE__namespace.Vector3().subVectors(point, lineStart).dot(line) / (lineLength * lineLength)));
|
|
24920
|
-
var projection = new THREE__namespace.Vector3().addVectors(lineStart, line.multiplyScalar(t));
|
|
24921
|
-
return point.distanceTo(projection);
|
|
24922
|
-
}
|
|
24923
|
-
}]);
|
|
24924
|
-
}();
|
|
24925
|
-
|
|
24926
24695
|
/**
|
|
24927
24696
|
* SceneDataManager
|
|
24928
24697
|
* Utility class for managing scene data transformations and queries
|
|
@@ -24935,118 +24704,12 @@ var SceneDataManager = /*#__PURE__*/function () {
|
|
|
24935
24704
|
}
|
|
24936
24705
|
|
|
24937
24706
|
/**
|
|
24938
|
-
*
|
|
24939
|
-
*
|
|
24940
|
-
*
|
|
24941
|
-
* @returns {Object}
|
|
24707
|
+
* Helper method to find an object in scene data by UUID
|
|
24708
|
+
* @param {Object} sceneData - Scene data to search
|
|
24709
|
+
* @param {string} uuid - UUID to find
|
|
24710
|
+
* @returns {Object|null} Found object or null
|
|
24942
24711
|
*/
|
|
24943
24712
|
return _createClass(SceneDataManager, [{
|
|
24944
|
-
key: "getSimplifiedSceneData",
|
|
24945
|
-
value: function getSimplifiedSceneData() {
|
|
24946
|
-
// Collect all objects with objectType (flattened list from scene traversal)
|
|
24947
|
-
// Filter out ALL computed objects - only include declared/source objects
|
|
24948
|
-
var sceneDataNew = [];
|
|
24949
|
-
this.sceneViewer.scene.traverse(function (obj) {
|
|
24950
|
-
if (obj.userData && obj.userData.objectType) {
|
|
24951
|
-
// Skip computed gateways (only include declared/manual gateways)
|
|
24952
|
-
if (obj.userData.objectType === 'gateway' && !obj.userData.isDeclared) {
|
|
24953
|
-
return;
|
|
24954
|
-
}
|
|
24955
|
-
sceneDataNew.push(obj);
|
|
24956
|
-
}
|
|
24957
|
-
});
|
|
24958
|
-
console.log('🔗 [SceneDataManager] sceneDataNew (flattened):', sceneDataNew);
|
|
24959
|
-
|
|
24960
|
-
// Calculate world bounding boxes for each object individually (after flattening)
|
|
24961
|
-
// This way we don't need to worry about children - each object is standalone
|
|
24962
|
-
var simplifiedSceneData = {};
|
|
24963
|
-
simplifiedSceneData.children = sceneDataNew.map(function (obj) {
|
|
24964
|
-
var _obj$children;
|
|
24965
|
-
var uuid = obj.uuid;
|
|
24966
|
-
|
|
24967
|
-
// Calculate world bounding box for this individual object
|
|
24968
|
-
var worldBoundingBox = null;
|
|
24969
|
-
|
|
24970
|
-
// For meshes, calculate bbox from geometry only (ignoring children)
|
|
24971
|
-
if (obj.isMesh && obj.geometry) {
|
|
24972
|
-
try {
|
|
24973
|
-
// Compute bounding box from geometry in world space
|
|
24974
|
-
var bbox = new THREE__namespace.Box3();
|
|
24975
|
-
obj.geometry.computeBoundingBox();
|
|
24976
|
-
if (obj.geometry.boundingBox) {
|
|
24977
|
-
// Transform local bbox to world space
|
|
24978
|
-
bbox.copy(obj.geometry.boundingBox);
|
|
24979
|
-
bbox.applyMatrix4(obj.matrixWorld);
|
|
24980
|
-
|
|
24981
|
-
// Only include valid bounding boxes
|
|
24982
|
-
// Check if all components of min and max are finite numbers
|
|
24983
|
-
var isValidBBox = !bbox.isEmpty() && isFinite(bbox.min.x) && isFinite(bbox.min.y) && isFinite(bbox.min.z) && isFinite(bbox.max.x) && isFinite(bbox.max.y) && isFinite(bbox.max.z);
|
|
24984
|
-
if (isValidBBox) {
|
|
24985
|
-
worldBoundingBox = {
|
|
24986
|
-
min: bbox.min.toArray(),
|
|
24987
|
-
max: bbox.max.toArray()
|
|
24988
|
-
};
|
|
24989
|
-
} else {
|
|
24990
|
-
console.warn("\u26A0\uFE0F Invalid bounding box for ".concat(uuid, ", skipping"));
|
|
24991
|
-
}
|
|
24992
|
-
}
|
|
24993
|
-
} catch (error) {
|
|
24994
|
-
console.warn("\u26A0\uFE0F Failed to calculate bounding box for ".concat(uuid, ":"), error);
|
|
24995
|
-
}
|
|
24996
|
-
}
|
|
24997
|
-
// For groups or objects with children, use setFromObject but only on this object
|
|
24998
|
-
else if (obj.isGroup || ((_obj$children = obj.children) === null || _obj$children === void 0 ? void 0 : _obj$children.length) > 0) {
|
|
24999
|
-
try {
|
|
25000
|
-
var _bbox = new THREE__namespace.Box3().setFromObject(obj);
|
|
25001
|
-
|
|
25002
|
-
// Check if all components of min and max are finite numbers
|
|
25003
|
-
var _isValidBBox = !_bbox.isEmpty() && isFinite(_bbox.min.x) && isFinite(_bbox.min.y) && isFinite(_bbox.min.z) && isFinite(_bbox.max.x) && isFinite(_bbox.max.y) && isFinite(_bbox.max.z);
|
|
25004
|
-
if (_isValidBBox) {
|
|
25005
|
-
worldBoundingBox = {
|
|
25006
|
-
min: _bbox.min.toArray(),
|
|
25007
|
-
max: _bbox.max.toArray()
|
|
25008
|
-
};
|
|
25009
|
-
}
|
|
25010
|
-
} catch (error) {
|
|
25011
|
-
console.warn("\u26A0\uFE0F Failed to calculate bounding box for ".concat(uuid, ":"), error);
|
|
25012
|
-
}
|
|
25013
|
-
}
|
|
25014
|
-
var results = {
|
|
25015
|
-
uuid: uuid,
|
|
25016
|
-
userData: _objectSpread2(_objectSpread2({}, obj.userData), worldBoundingBox && {
|
|
25017
|
-
worldBoundingBox: worldBoundingBox
|
|
25018
|
-
})
|
|
25019
|
-
};
|
|
25020
|
-
|
|
25021
|
-
// For connectors and gateways, add world position
|
|
25022
|
-
if (obj.userData.objectType.includes('connector') || obj.userData.objectType === 'gateway') {
|
|
25023
|
-
var worldPosition = new THREE__namespace.Vector3();
|
|
25024
|
-
obj.getWorldPosition(worldPosition);
|
|
25025
|
-
results.userData.position = [worldPosition.x, worldPosition.y, worldPosition.z];
|
|
25026
|
-
|
|
25027
|
-
// Differentiate component connectors from segment connectors for pathfinder
|
|
25028
|
-
// Component connectors are children of components
|
|
25029
|
-
if (obj.userData.objectType === 'connector') {
|
|
25030
|
-
var _parent$userData;
|
|
25031
|
-
// Check if parent is a component (not a segment)
|
|
25032
|
-
var parent = obj.parent;
|
|
25033
|
-
if (parent && ((_parent$userData = parent.userData) === null || _parent$userData === void 0 ? void 0 : _parent$userData.objectType) === 'component') {
|
|
25034
|
-
results.userData.objectType = 'component-connector';
|
|
25035
|
-
}
|
|
25036
|
-
}
|
|
25037
|
-
}
|
|
25038
|
-
return results;
|
|
25039
|
-
});
|
|
25040
|
-
return simplifiedSceneData;
|
|
25041
|
-
}
|
|
25042
|
-
|
|
25043
|
-
/**
|
|
25044
|
-
* Helper method to find an object in scene data by UUID
|
|
25045
|
-
* @param {Object} sceneData - Scene data to search
|
|
25046
|
-
* @param {string} uuid - UUID to find
|
|
25047
|
-
* @returns {Object|null} Found object or null
|
|
25048
|
-
*/
|
|
25049
|
-
}, {
|
|
25050
24713
|
key: "findObjectInSceneData",
|
|
25051
24714
|
value: function findObjectInSceneData(sceneData, uuid) {
|
|
25052
24715
|
var _searchChildren = function searchChildren(children) {
|
|
@@ -25384,7 +25047,8 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
25384
25047
|
}
|
|
25385
25048
|
var cylinderGeometry = new THREE__namespace.CylinderGeometry(pipeRadius, pipeRadius, length, 16, 1, false);
|
|
25386
25049
|
var cylinder = new THREE__namespace.Mesh(cylinderGeometry, pipeMaterial);
|
|
25387
|
-
|
|
25050
|
+
var centerPoint = new THREE__namespace.Vector3().copy(start).add(end).multiplyScalar(0.5);
|
|
25051
|
+
cylinder.position.copy(centerPoint);
|
|
25388
25052
|
var quaternion = new THREE__namespace.Quaternion();
|
|
25389
25053
|
var up = new THREE__namespace.Vector3(0, 1, 0);
|
|
25390
25054
|
quaternion.setFromUnitVectors(up, direction.clone().normalize());
|
|
@@ -25405,6 +25069,10 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
25405
25069
|
var isLastSegment = j === pathPoints.length - 2;
|
|
25406
25070
|
var isImmutable = fromHasDirection && isFirstSegment || toHasDirection && isLastSegment;
|
|
25407
25071
|
|
|
25072
|
+
// Calculate relative endpoint offsets from center point
|
|
25073
|
+
var startOffset = new THREE__namespace.Vector3().subVectors(start, centerPoint);
|
|
25074
|
+
var endOffset = new THREE__namespace.Vector3().subVectors(end, centerPoint);
|
|
25075
|
+
|
|
25408
25076
|
// Add userData to make pipe segments selectable and for tooltip display
|
|
25409
25077
|
cylinder.userData = {
|
|
25410
25078
|
objectType: 'segment',
|
|
@@ -25412,7 +25080,21 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
25412
25080
|
segmentIndex: globalSegmentIndex,
|
|
25413
25081
|
pathFrom: pathData.from,
|
|
25414
25082
|
pathTo: pathData.to,
|
|
25415
|
-
immutable: isImmutable
|
|
25083
|
+
immutable: isImmutable,
|
|
25084
|
+
// Mark segments connected to component connectors as immutable
|
|
25085
|
+
// Store endpoint offsets relative to center point for reconstruction
|
|
25086
|
+
endpoints: {
|
|
25087
|
+
startOffset: {
|
|
25088
|
+
x: startOffset.x,
|
|
25089
|
+
y: startOffset.y,
|
|
25090
|
+
z: startOffset.z
|
|
25091
|
+
},
|
|
25092
|
+
endOffset: {
|
|
25093
|
+
x: endOffset.x,
|
|
25094
|
+
y: endOffset.y,
|
|
25095
|
+
z: endOffset.z
|
|
25096
|
+
}
|
|
25097
|
+
}
|
|
25416
25098
|
};
|
|
25417
25099
|
|
|
25418
25100
|
// Increment global segment counter
|
|
@@ -26651,9 +26333,6 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
26651
26333
|
}
|
|
26652
26334
|
}
|
|
26653
26335
|
|
|
26654
|
-
// Initialize intersection detector
|
|
26655
|
-
_this.intersectionDetector = new PathIntersectionDetector(sceneViewer);
|
|
26656
|
-
|
|
26657
26336
|
// Initialize rendering manager
|
|
26658
26337
|
_this.renderingManager = new PathRenderingManager(sceneViewer);
|
|
26659
26338
|
_this.registerDisposable(_this.renderingManager);
|
|
@@ -26725,17 +26404,67 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
26725
26404
|
// END NEW ADAPTER METHODS
|
|
26726
26405
|
// ============================================================================
|
|
26727
26406
|
|
|
26407
|
+
/**
|
|
26408
|
+
* Enrich sceneData with worldBoundingBox for segments
|
|
26409
|
+
* Connectors remain with just position information
|
|
26410
|
+
* @param {Object} sceneData - Original scene data
|
|
26411
|
+
* @returns {Object} Enriched scene data (shallow copy with modifications)
|
|
26412
|
+
* @private
|
|
26413
|
+
*/
|
|
26414
|
+
}, {
|
|
26415
|
+
key: "_enrichSceneDataWithBoundingBoxes",
|
|
26416
|
+
value: function _enrichSceneDataWithBoundingBoxes(sceneData) {
|
|
26417
|
+
var _this3 = this;
|
|
26418
|
+
// Create a shallow copy of sceneData structure
|
|
26419
|
+
var enriched = _objectSpread2({}, sceneData);
|
|
26420
|
+
if (!sceneData.children || !Array.isArray(sceneData.children)) {
|
|
26421
|
+
console.warn('⚠️ sceneData has no children array');
|
|
26422
|
+
return enriched;
|
|
26423
|
+
}
|
|
26424
|
+
|
|
26425
|
+
// Process children to add worldBoundingBox to segments
|
|
26426
|
+
enriched.children = sceneData.children.map(function (child) {
|
|
26427
|
+
// Only enrich segments (check if objectType is 'segment' in userData)
|
|
26428
|
+
if (child.userData && child.userData.objectType === 'segment') {
|
|
26429
|
+
// Find the actual segment object in the scene
|
|
26430
|
+
var segmentObject = _this3.sceneViewer.scene.getObjectByProperty('uuid', child.uuid);
|
|
26431
|
+
if (segmentObject) {
|
|
26432
|
+
// Compute world bounding box
|
|
26433
|
+
var worldBBox = new THREE__namespace.Box3().setFromObject(segmentObject);
|
|
26434
|
+
|
|
26435
|
+
// Return enriched segment data with worldBoundingBox in userData
|
|
26436
|
+
// Note: pathfinder expects arrays [x, y, z] format for min/max
|
|
26437
|
+
return _objectSpread2(_objectSpread2({}, child), {}, {
|
|
26438
|
+
userData: _objectSpread2(_objectSpread2({}, child.userData), {}, {
|
|
26439
|
+
worldBoundingBox: {
|
|
26440
|
+
min: [worldBBox.min.x, worldBBox.min.y, worldBBox.min.z],
|
|
26441
|
+
max: [worldBBox.max.x, worldBBox.max.y, worldBBox.max.z]
|
|
26442
|
+
}
|
|
26443
|
+
})
|
|
26444
|
+
});
|
|
26445
|
+
} else {
|
|
26446
|
+
console.warn("\u26A0\uFE0F Could not find segment object in scene: ".concat(child.uuid));
|
|
26447
|
+
}
|
|
26448
|
+
}
|
|
26449
|
+
|
|
26450
|
+
// For non-segments (including connectors), return as-is
|
|
26451
|
+
return child;
|
|
26452
|
+
});
|
|
26453
|
+
return enriched;
|
|
26454
|
+
}
|
|
26455
|
+
|
|
26728
26456
|
/**
|
|
26729
26457
|
* Core pathfinding logic shared across initialization and updates
|
|
26730
26458
|
*/
|
|
26731
26459
|
}, {
|
|
26732
26460
|
key: "_executePathfinding",
|
|
26733
|
-
value: function () {
|
|
26461
|
+
value: (function () {
|
|
26734
26462
|
var _executePathfinding2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(sceneData, connections) {
|
|
26735
26463
|
var options,
|
|
26736
26464
|
_options$context,
|
|
26737
26465
|
context,
|
|
26738
26466
|
connectionsCopy,
|
|
26467
|
+
enrichedSceneData,
|
|
26739
26468
|
sceneDataCopy,
|
|
26740
26469
|
pathfindingResult,
|
|
26741
26470
|
_args = arguments;
|
|
@@ -26752,26 +26481,11 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
26752
26481
|
console.log("\uD83D\uDD04 Updated matrix world for ".concat(context, " pathfinding execution"));
|
|
26753
26482
|
|
|
26754
26483
|
// Deep copy connections to prevent pathfinder from mutating the original
|
|
26755
|
-
connectionsCopy = JSON.parse(JSON.stringify(connections));
|
|
26756
|
-
|
|
26484
|
+
connectionsCopy = JSON.parse(JSON.stringify(connections)); // Enrich sceneData with worldBoundingBox for segments before deep copy
|
|
26485
|
+
enrichedSceneData = this._enrichSceneDataWithBoundingBoxes(sceneData);
|
|
26486
|
+
sceneDataCopy = JSON.parse(JSON.stringify(enrichedSceneData));
|
|
26757
26487
|
console.log("[Pathfinder] sceneDataCopy:", sceneDataCopy);
|
|
26758
26488
|
|
|
26759
|
-
// const simplifiedSceneData = JSON.parse(JSON.stringify( this.getSimplifiedSceneData() ));
|
|
26760
|
-
|
|
26761
|
-
// // Take snapshot before pathfinding execution (capture Three.js scene)
|
|
26762
|
-
// this.snapshotManager.takeSnapshot(
|
|
26763
|
-
// this.sceneViewer.scene, // Pass the actual Three.js scene
|
|
26764
|
-
// connectionsCopy,
|
|
26765
|
-
// context
|
|
26766
|
-
// );
|
|
26767
|
-
|
|
26768
|
-
// console.log('[Pathfinder] simplifiedSceneData length at creation:', simplifiedSceneData.children?.length);
|
|
26769
|
-
// console.log('[Pathfinder] simplifiedSceneData (deep clone for inspection):', JSON.parse(JSON.stringify(simplifiedSceneData)));
|
|
26770
|
-
|
|
26771
|
-
// // Add debugging for pathfinder input
|
|
26772
|
-
// console.log('🔍 PATHFINDER DEBUGGING:');
|
|
26773
|
-
// console.log('🔗 [Pathfinder] Connections:', JSON.parse(JSON.stringify(connectionsCopy)));
|
|
26774
|
-
|
|
26775
26489
|
// Find paths using v1.0.17 API (sceneData and connections separately)
|
|
26776
26490
|
// Pass deep copy to ensure pathfinder cannot mutate original connections
|
|
26777
26491
|
pathfindingResult = this.pathfinder.findPaths(sceneDataCopy, connectionsCopy);
|
|
@@ -26780,79 +26494,6 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
26780
26494
|
console.log('Rewired connections:', JSON.parse(JSON.stringify(pathfindingResult.rewiredConnections)));
|
|
26781
26495
|
console.log("intersectionCheck input:", pathfindingResult.paths);
|
|
26782
26496
|
|
|
26783
|
-
// // Check for path intersections (including manual segments)
|
|
26784
|
-
// const intersectionCheck = this.checkPathIntersections(pathfindingResult.paths, 0.2, true);
|
|
26785
|
-
// pathfindingResult.intersections = intersectionCheck;
|
|
26786
|
-
|
|
26787
|
-
// console.log("intersectionCheck:", intersectionCheck);
|
|
26788
|
-
// console.log("intersectionCheck.hasIntersections:", intersectionCheck.hasIntersections);
|
|
26789
|
-
|
|
26790
|
-
// // Handle intersection detection - undo last operation if intersections found
|
|
26791
|
-
// // Skip this if we're already in the middle of an undo operation
|
|
26792
|
-
// if (intersectionCheck.hasIntersections && !this.isUndoInProgress) {
|
|
26793
|
-
// console.warn('⚠️ Path intersections detected! Attempting to undo last operation...');
|
|
26794
|
-
|
|
26795
|
-
// // Set flag to prevent recursive undo attempts
|
|
26796
|
-
// this.isUndoInProgress = true;
|
|
26797
|
-
|
|
26798
|
-
// // Access operationHistoryManager through sceneViewer.managers.operationHistory
|
|
26799
|
-
// const operationHistoryManager = this.sceneViewer?.managers?.operationHistory;
|
|
26800
|
-
|
|
26801
|
-
// if (operationHistoryManager) {
|
|
26802
|
-
// const lastOp = operationHistoryManager.getLastOperation();
|
|
26803
|
-
|
|
26804
|
-
// if (lastOp) {
|
|
26805
|
-
// console.warn(`⚠️ Intersection caused by operation: ${lastOp.operationName}`, lastOp.params);
|
|
26806
|
-
|
|
26807
|
-
// // Attempt to undo the operation FIRST (before removing computed objects)
|
|
26808
|
-
// // This is important because undo needs to find the segment that was moved
|
|
26809
|
-
// const undoSuccess = operationHistoryManager.undoLastOperation();
|
|
26810
|
-
|
|
26811
|
-
// if (undoSuccess) {
|
|
26812
|
-
// console.log('✅ Successfully undid operation that caused intersection');
|
|
26813
|
-
|
|
26814
|
-
// // Now remove the buggy computed objects that were created with the invalid state
|
|
26815
|
-
// console.log('🗑️ Removing buggy computed objects after undo...');
|
|
26816
|
-
// this.removeComputedObjects();
|
|
26817
|
-
|
|
26818
|
-
// // Re-run pathfinding after undo to restore valid state
|
|
26819
|
-
// console.log('🔄 Re-running pathfinding after undo to restore clean state...');
|
|
26820
|
-
|
|
26821
|
-
// // Recursively call _executePathfinding with the corrected scene state
|
|
26822
|
-
// // This is safe because we've undone the operation, so we won't get into an infinite loop
|
|
26823
|
-
// const correctedResult = await this._executePathfinding(
|
|
26824
|
-
// sceneData,
|
|
26825
|
-
// connections,
|
|
26826
|
-
// { ...options, context: `${context} (After Undo)` }
|
|
26827
|
-
// );
|
|
26828
|
-
|
|
26829
|
-
// // Mark that we performed an undo and return the corrected result
|
|
26830
|
-
// correctedResult.undoPerformed = true;
|
|
26831
|
-
// correctedResult.undoneOperation = lastOp;
|
|
26832
|
-
|
|
26833
|
-
// // Clear the undo flag before returning
|
|
26834
|
-
// this.isUndoInProgress = false;
|
|
26835
|
-
|
|
26836
|
-
// return correctedResult;
|
|
26837
|
-
// } else {
|
|
26838
|
-
// console.error('❌ Failed to undo operation that caused intersection');
|
|
26839
|
-
// pathfindingResult.undoFailed = true;
|
|
26840
|
-
// // Clear the undo flag even on failure
|
|
26841
|
-
// this.isUndoInProgress = false;
|
|
26842
|
-
// }
|
|
26843
|
-
// } else {
|
|
26844
|
-
// console.warn('⚠️ No operation in history to undo');
|
|
26845
|
-
// this.isUndoInProgress = false;
|
|
26846
|
-
// }
|
|
26847
|
-
// } else {
|
|
26848
|
-
// console.error('❌ OperationHistoryManager not available for undo');
|
|
26849
|
-
// console.error(' Available managers:', Object.keys(this.sceneViewer?.managers || {}));
|
|
26850
|
-
// this.isUndoInProgress = false;
|
|
26851
|
-
// }
|
|
26852
|
-
// } else if (intersectionCheck.hasIntersections && this.isUndoInProgress) {
|
|
26853
|
-
// console.log('⏭️ Skipping intersection handling - undo already in progress');
|
|
26854
|
-
// }
|
|
26855
|
-
|
|
26856
26497
|
// Create gateways in the scene if requested
|
|
26857
26498
|
if (options.createGateways && pathfindingResult.gateways) {
|
|
26858
26499
|
this.renderingManager.createGateways(pathfindingResult);
|
|
@@ -26869,7 +26510,7 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
26869
26510
|
return _executePathfinding2.apply(this, arguments);
|
|
26870
26511
|
}
|
|
26871
26512
|
return _executePathfinding;
|
|
26872
|
-
}()
|
|
26513
|
+
}())
|
|
26873
26514
|
}, {
|
|
26874
26515
|
key: "getSimplifiedSceneData",
|
|
26875
26516
|
value: function getSimplifiedSceneData() {
|
|
@@ -26960,25 +26601,6 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
26960
26601
|
console.log("\u2705 Removed ".concat(objectsToRemove.length, " computed objects from scene (segments, elbows, and gateways)"));
|
|
26961
26602
|
}
|
|
26962
26603
|
|
|
26963
|
-
/**
|
|
26964
|
-
* Check for intersections between paths
|
|
26965
|
-
* Delegates to PathIntersectionDetector for the actual detection logic
|
|
26966
|
-
* @param {Array} paths - Array of path objects from pathfinder
|
|
26967
|
-
* @param {number} tolerance - Distance tolerance for considering pipes as intersecting (default: 0.2)
|
|
26968
|
-
* @param {boolean} includeManualSegments - Whether to include manual segments in the check (default: true)
|
|
26969
|
-
* @returns {Object} Intersection results
|
|
26970
|
-
* @property {boolean} hasIntersections - Whether any intersections were found
|
|
26971
|
-
* @property {Array<Object>} intersections - Array of intersection details
|
|
26972
|
-
* @property {number} count - Total number of intersections found
|
|
26973
|
-
*/
|
|
26974
|
-
}, {
|
|
26975
|
-
key: "checkPathIntersections",
|
|
26976
|
-
value: function checkPathIntersections(paths) {
|
|
26977
|
-
var tolerance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.2;
|
|
26978
|
-
var includeManualSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
26979
|
-
return this.intersectionDetector.checkPathIntersections(paths, tolerance, includeManualSegments);
|
|
26980
|
-
}
|
|
26981
|
-
|
|
26982
26604
|
/**
|
|
26983
26605
|
* Update pathfinding after object transforms
|
|
26984
26606
|
*/
|
|
@@ -33805,7 +33427,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
33805
33427
|
* Initialize the CentralPlant manager
|
|
33806
33428
|
*
|
|
33807
33429
|
* @constructor
|
|
33808
|
-
* @version 0.1.
|
|
33430
|
+
* @version 0.1.55
|
|
33809
33431
|
* @updated 2025-10-22
|
|
33810
33432
|
*
|
|
33811
33433
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -38011,7 +37633,6 @@ exports.KeyboardControlsManager = KeyboardControlsManager;
|
|
|
38011
37633
|
exports.ModelManager = ModelManager;
|
|
38012
37634
|
exports.OperationHistoryManager = OperationHistoryManager;
|
|
38013
37635
|
exports.PathData = PathData;
|
|
38014
|
-
exports.PathIntersectionDetector = PathIntersectionDetector;
|
|
38015
37636
|
exports.PathfindingManager = PathfindingManager;
|
|
38016
37637
|
exports.PerformanceMonitorManager = PerformanceMonitorManager;
|
|
38017
37638
|
exports.Rendering2D = rendering2D;
|