@2112-lab/central-plant 0.1.48 → 0.1.50
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 +172 -151
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/components/transformOperationsManager.js +45 -40
- package/dist/cjs/src/managers/controls/transformControlsManager.js +31 -16
- package/dist/cjs/src/managers/pathfinding/PathRenderingManager.js +23 -1
- package/dist/cjs/src/managers/pathfinding/pathfindingManager.js +72 -93
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/components/transformOperationsManager.js +45 -40
- package/dist/esm/src/managers/controls/transformControlsManager.js +31 -16
- package/dist/esm/src/managers/pathfinding/PathRenderingManager.js +23 -1
- package/dist/esm/src/managers/pathfinding/pathfindingManager.js +73 -94
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -5014,11 +5014,15 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
5014
5014
|
_this9.selectedObjects[selectedIndex] = segment;
|
|
5015
5015
|
console.log("\u2705 Updated selectedObjects[".concat(selectedIndex, "] with refreshed segment reference"));
|
|
5016
5016
|
}
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5017
|
+
if (segment) {
|
|
5018
|
+
console.log("\uD83D\uDCE6 Segment ".concat(segment.name, " translated (").concat(i + 1, "/").concat(segments.length, "):"), {
|
|
5019
|
+
deltaX: deltaX,
|
|
5020
|
+
deltaY: deltaY,
|
|
5021
|
+
deltaZ: deltaZ
|
|
5022
|
+
});
|
|
5023
|
+
} else {
|
|
5024
|
+
console.warn("\u26A0\uFE0F Segment reference became null after translation (".concat(i + 1, "/").concat(segments.length, ")"));
|
|
5025
|
+
}
|
|
5022
5026
|
|
|
5023
5027
|
// Delay between segments to ensure all updates propagate
|
|
5024
5028
|
if (!(i < segments.length - 1)) {
|
|
@@ -5145,11 +5149,15 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
5145
5149
|
_this9.selectedObjects[selectedIndex] = segment;
|
|
5146
5150
|
console.log("\u2705 Updated selectedObjects[".concat(selectedIndex, "] with refreshed segment reference"));
|
|
5147
5151
|
}
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5152
|
+
if (segment) {
|
|
5153
|
+
console.log("\uD83D\uDCE6 Segment ".concat(segment.name, " translated (").concat(_i + 1, "/").concat(segments.length, "):"), {
|
|
5154
|
+
deltaX: deltaX,
|
|
5155
|
+
deltaY: deltaY,
|
|
5156
|
+
deltaZ: deltaZ
|
|
5157
|
+
});
|
|
5158
|
+
} else {
|
|
5159
|
+
console.warn("\u26A0\uFE0F Segment reference became null after translation (".concat(_i + 1, "/").concat(segments.length, ")"));
|
|
5160
|
+
}
|
|
5153
5161
|
|
|
5154
5162
|
// Delay between segments
|
|
5155
5163
|
if (!(_i < segments.length - 1)) {
|
|
@@ -5291,17 +5299,24 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
5291
5299
|
deltaZ: deltaZ
|
|
5292
5300
|
});
|
|
5293
5301
|
case 21:
|
|
5294
|
-
// Reset the multi-selection group transform
|
|
5295
|
-
|
|
5296
|
-
this.multiSelectionGroup
|
|
5297
|
-
|
|
5302
|
+
// Reset the multi-selection group transform (if it still exists)
|
|
5303
|
+
// Note: The group might have been cleared during async operations
|
|
5304
|
+
if (this.multiSelectionGroup) {
|
|
5305
|
+
this.multiSelectionGroup.position.set(0, 0, 0);
|
|
5306
|
+
this.multiSelectionGroup.rotation.set(0, 0, 0);
|
|
5307
|
+
this.multiSelectionGroup.scale.set(1, 1, 1);
|
|
5308
|
+
} else {
|
|
5309
|
+
console.warn('⚠️ Multi-selection group was cleared during transformation');
|
|
5310
|
+
}
|
|
5298
5311
|
|
|
5299
5312
|
// CRITICAL: Clear bounding box cache after manualization
|
|
5300
5313
|
// Manualization changes object references, making cached boxes invalid
|
|
5301
5314
|
this.clearBoundingBoxCache();
|
|
5302
5315
|
|
|
5303
|
-
// Update the multi-selection display with new positions
|
|
5304
|
-
this.
|
|
5316
|
+
// Update the multi-selection display with new positions (only if we still have selected objects)
|
|
5317
|
+
if (this.selectedObjects.length > 0) {
|
|
5318
|
+
this.updateMultiSelection();
|
|
5319
|
+
}
|
|
5305
5320
|
console.log("\u2705 Multi-selection transform applied");
|
|
5306
5321
|
case 22:
|
|
5307
5322
|
return _context3.a(2);
|
|
@@ -19070,15 +19085,31 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19070
19085
|
}
|
|
19071
19086
|
|
|
19072
19087
|
// Check segment orientation and cancel invalid translations
|
|
19073
|
-
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19088
|
+
// Get the segment's direction vector to determine which axis it runs along
|
|
19089
|
+
var direction = new THREE__namespace.Vector3(0, 1, 0);
|
|
19090
|
+
direction.applyQuaternion(segment.quaternion);
|
|
19091
|
+
direction.normalize();
|
|
19092
|
+
|
|
19093
|
+
// Determine which axis the segment primarily runs along
|
|
19094
|
+
var absX = Math.abs(direction.x);
|
|
19095
|
+
var absY = Math.abs(direction.y);
|
|
19096
|
+
var absZ = Math.abs(direction.z);
|
|
19097
|
+
var tolerance = 0.9; // Direction component must be > 0.9 to be considered aligned with axis
|
|
19098
|
+
|
|
19099
|
+
// Block translation along the axis that the segment runs parallel to
|
|
19100
|
+
if (absX > tolerance && axis === 'x') {
|
|
19101
|
+
console.warn("\u26A0\uFE0F translateSegment(): Cannot translate segment along ".concat(axis.toUpperCase(), " axis - segment runs along this axis"));
|
|
19102
|
+
console.warn(" Segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
19103
|
+
return false;
|
|
19104
|
+
}
|
|
19105
|
+
if (absY > tolerance && axis === 'y') {
|
|
19106
|
+
console.warn("\u26A0\uFE0F translateSegment(): Cannot translate segment along ".concat(axis.toUpperCase(), " axis - segment runs along this axis"));
|
|
19107
|
+
console.warn(" Segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
19077
19108
|
return false;
|
|
19078
19109
|
}
|
|
19079
|
-
if (
|
|
19080
|
-
console.warn("\u26A0\uFE0F translateSegment(): Cannot translate
|
|
19081
|
-
console.warn("
|
|
19110
|
+
if (absZ > tolerance && axis === 'z') {
|
|
19111
|
+
console.warn("\u26A0\uFE0F translateSegment(): Cannot translate segment along ".concat(axis.toUpperCase(), " axis - segment runs along this axis"));
|
|
19112
|
+
console.warn(" Segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
19082
19113
|
return false;
|
|
19083
19114
|
}
|
|
19084
19115
|
console.log('[translateSegment] segment:', segment);
|
|
@@ -19243,17 +19274,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19243
19274
|
|
|
19244
19275
|
// ALWAYS update connector positions after segment movement (first or subsequent moves)
|
|
19245
19276
|
this.updateSegmentConnectorPositions(segment);
|
|
19246
|
-
|
|
19247
|
-
// NEW: Update adjacent manual segments to follow this segment's new position
|
|
19248
|
-
var maintainedConnections = this.snapSegmentConnectorsToNearbyEndpoints(segment);
|
|
19249
|
-
|
|
19250
|
-
// NOTE: We do NOT remove connections from scene data
|
|
19251
|
-
// The connections remain valid - the manual segments are maintaining those connections
|
|
19252
|
-
// The pathfinding algorithm should detect that connectors are at the same position
|
|
19253
|
-
// and skip creating computed segments for them
|
|
19254
|
-
if (maintainedConnections.length > 0) {
|
|
19255
|
-
console.log("\u2139\uFE0F ".concat(maintainedConnections.length, " connection(s) maintained by manual segments"));
|
|
19256
|
-
}
|
|
19277
|
+
this.snapSegmentConnectorsToNearbyEndpoints(segment);
|
|
19257
19278
|
|
|
19258
19279
|
// Store transform parameters using the OperationHistoryManager BEFORE updatePaths
|
|
19259
19280
|
// This is critical so that intersection detection can undo the operation
|
|
@@ -19270,9 +19291,6 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19270
19291
|
// UNLESS skipPathUpdate is true (for batch operations)
|
|
19271
19292
|
if (!skipPathUpdate) {
|
|
19272
19293
|
console.log('🔄 Regenerating paths to create connecting pipe segments...');
|
|
19273
|
-
if (maintainedConnections.length > 0) {
|
|
19274
|
-
console.log("\u2139\uFE0F Manual segments are maintaining connections - pathfinding should skip connectors at same position");
|
|
19275
|
-
}
|
|
19276
19294
|
try {
|
|
19277
19295
|
if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
|
|
19278
19296
|
this.sceneViewer.updatePaths();
|
|
@@ -20317,8 +20335,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20317
20335
|
}
|
|
20318
20336
|
|
|
20319
20337
|
/**
|
|
20320
|
-
*
|
|
20321
|
-
* @param {THREE.Object3D} segment - The segment to
|
|
20338
|
+
* Adjust segment geometry and transform to match new endpoint positions
|
|
20339
|
+
* @param {THREE.Object3D} segment - The segment to adjust
|
|
20322
20340
|
* @param {Array<THREE.Object3D>} connectors - The segment's connectors
|
|
20323
20341
|
* @param {THREE.Vector3} endPoint1 - Explicit world position for first endpoint (optional)
|
|
20324
20342
|
* @param {THREE.Vector3} endPoint2 - Explicit world position for second endpoint (optional)
|
|
@@ -20332,7 +20350,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20332
20350
|
var endPoint2 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
20333
20351
|
var activeSegment = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
20334
20352
|
if (!segment || connectors.length !== 2) {
|
|
20335
|
-
console.warn('⚠️ Cannot
|
|
20353
|
+
console.warn('⚠️ Cannot adjust segment: invalid segment or connectors');
|
|
20336
20354
|
return;
|
|
20337
20355
|
}
|
|
20338
20356
|
var _connectors = _slicedToArray(connectors, 2),
|
|
@@ -20375,21 +20393,28 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20375
20393
|
this._removeZeroLengthSegment(segment, connectors, activeSegment);
|
|
20376
20394
|
return;
|
|
20377
20395
|
}
|
|
20378
|
-
|
|
20396
|
+
var oldLength = segment.geometry.parameters.height;
|
|
20397
|
+
console.log("\uD83D\uDD27 Adjusting segment geometry: ".concat(oldLength.toFixed(3), " \u2192 ").concat(newLength.toFixed(3)));
|
|
20379
20398
|
|
|
20380
|
-
//
|
|
20381
|
-
|
|
20382
|
-
|
|
20383
|
-
|
|
20399
|
+
// Only recreate geometry if length has changed significantly
|
|
20400
|
+
if (Math.abs(newLength - oldLength) > 1e-6) {
|
|
20401
|
+
var oldGeometry = segment.geometry;
|
|
20402
|
+
var pipeRadius = oldGeometry.parameters.radiusTop || 0.1;
|
|
20384
20403
|
|
|
20385
|
-
|
|
20386
|
-
|
|
20404
|
+
// Create new cylinder geometry with updated length
|
|
20405
|
+
var newGeometry = new THREE__namespace.CylinderGeometry(pipeRadius, pipeRadius, newLength, 16, 1, false);
|
|
20387
20406
|
|
|
20388
|
-
|
|
20389
|
-
|
|
20407
|
+
// Replace geometry
|
|
20408
|
+
segment.geometry = newGeometry;
|
|
20409
|
+
|
|
20410
|
+
// Dispose old geometry
|
|
20411
|
+
oldGeometry.dispose();
|
|
20412
|
+
}
|
|
20413
|
+
|
|
20414
|
+
// Update segment position to new center
|
|
20390
20415
|
segment.position.copy(newCenter);
|
|
20391
20416
|
|
|
20392
|
-
// Calculate and apply rotation
|
|
20417
|
+
// Calculate and apply rotation to align with new direction
|
|
20393
20418
|
var quaternion = new THREE__namespace.Quaternion();
|
|
20394
20419
|
var up = new THREE__namespace.Vector3(0, 1, 0);
|
|
20395
20420
|
quaternion.setFromUnitVectors(up, direction.clone().normalize());
|
|
@@ -20398,12 +20423,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20398
20423
|
// Update matrices
|
|
20399
20424
|
segment.updateMatrix();
|
|
20400
20425
|
segment.updateMatrixWorld(true);
|
|
20401
|
-
|
|
20402
|
-
// Dispose old geometry
|
|
20403
|
-
if (oldGeometry && oldGeometry !== newGeometry) {
|
|
20404
|
-
oldGeometry.dispose();
|
|
20405
|
-
}
|
|
20406
|
-
console.log("\u2705 Segment mesh recreated: new length = ".concat(newLength.toFixed(3), ", center = [").concat(newCenter.x.toFixed(2), ", ").concat(newCenter.y.toFixed(2), ", ").concat(newCenter.z.toFixed(2), "]"));
|
|
20426
|
+
console.log("\u2705 Segment adjusted: length = ".concat(newLength.toFixed(3), ", center = [").concat(newCenter.x.toFixed(2), ", ").concat(newCenter.y.toFixed(2), ", ").concat(newCenter.z.toFixed(2), "]"));
|
|
20407
20427
|
}
|
|
20408
20428
|
|
|
20409
20429
|
/**
|
|
@@ -25201,8 +25221,30 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
25201
25221
|
value: function createPipePaths(paths, crosscubeTextureSet) {
|
|
25202
25222
|
var _this3 = this;
|
|
25203
25223
|
var sceneViewer = this.sceneViewer;
|
|
25204
|
-
var globalSegmentIndex = 0; // Counter for globally unique segment indices
|
|
25205
25224
|
|
|
25225
|
+
// Find the highest segment index currently in use (both computed SEGMENT-X and manual Segment-X)
|
|
25226
|
+
var maxExistingIndex = -1;
|
|
25227
|
+
sceneViewer.scene.traverse(function (obj) {
|
|
25228
|
+
if (obj.uuid) {
|
|
25229
|
+
// Check for computed segments: SEGMENT-123
|
|
25230
|
+
var computedMatch = obj.uuid.match(/^SEGMENT-(\d+)$/);
|
|
25231
|
+
if (computedMatch) {
|
|
25232
|
+
var index = parseInt(computedMatch[1], 10);
|
|
25233
|
+
maxExistingIndex = Math.max(maxExistingIndex, index);
|
|
25234
|
+
}
|
|
25235
|
+
|
|
25236
|
+
// Check for manual segments: Segment-123
|
|
25237
|
+
var manualMatch = obj.uuid.match(/^Segment-(\d+)$/);
|
|
25238
|
+
if (manualMatch) {
|
|
25239
|
+
var _index = parseInt(manualMatch[1], 10);
|
|
25240
|
+
maxExistingIndex = Math.max(maxExistingIndex, _index);
|
|
25241
|
+
}
|
|
25242
|
+
}
|
|
25243
|
+
});
|
|
25244
|
+
|
|
25245
|
+
// Start counter after the highest existing index to prevent UUID conflicts
|
|
25246
|
+
var globalSegmentIndex = maxExistingIndex + 1;
|
|
25247
|
+
console.log("\uD83D\uDD22 Starting segment index at ".concat(globalSegmentIndex, " (max existing: ").concat(maxExistingIndex, ")"));
|
|
25206
25248
|
var pipeRadius = 0.1;
|
|
25207
25249
|
var pipeMaterial = this.createPipeMaterial(crosscubeTextureSet);
|
|
25208
25250
|
paths.forEach(function (pathData, index) {
|
|
@@ -26548,13 +26590,6 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
26548
26590
|
connectionsCopy,
|
|
26549
26591
|
simplifiedSceneData,
|
|
26550
26592
|
pathfindingResult,
|
|
26551
|
-
intersectionCheck,
|
|
26552
|
-
_this$sceneViewer,
|
|
26553
|
-
operationHistoryManager,
|
|
26554
|
-
lastOp,
|
|
26555
|
-
undoSuccess,
|
|
26556
|
-
correctedResult,
|
|
26557
|
-
_this$sceneViewer2,
|
|
26558
26593
|
_args = arguments;
|
|
26559
26594
|
return _regenerator().w(function (_context) {
|
|
26560
26595
|
while (1) switch (_context.n) {
|
|
@@ -26589,93 +26624,79 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
26589
26624
|
console.log('Rewired connections:', JSON.parse(JSON.stringify(pathfindingResult.rewiredConnections)));
|
|
26590
26625
|
console.log("intersectionCheck input:", pathfindingResult.paths);
|
|
26591
26626
|
|
|
26592
|
-
// Check for path intersections (including manual segments)
|
|
26593
|
-
intersectionCheck = this.checkPathIntersections(pathfindingResult.paths, 0.2, true);
|
|
26594
|
-
pathfindingResult.intersections = intersectionCheck;
|
|
26595
|
-
|
|
26596
|
-
console.log("intersectionCheck
|
|
26597
|
-
|
|
26598
|
-
|
|
26599
|
-
//
|
|
26600
|
-
|
|
26601
|
-
|
|
26602
|
-
|
|
26603
|
-
|
|
26604
|
-
|
|
26605
|
-
|
|
26606
|
-
|
|
26607
|
-
|
|
26608
|
-
|
|
26609
|
-
|
|
26610
|
-
|
|
26611
|
-
|
|
26612
|
-
|
|
26613
|
-
|
|
26614
|
-
}
|
|
26615
|
-
|
|
26616
|
-
|
|
26617
|
-
|
|
26618
|
-
|
|
26619
|
-
|
|
26620
|
-
|
|
26621
|
-
|
|
26622
|
-
|
|
26623
|
-
//
|
|
26624
|
-
|
|
26625
|
-
|
|
26626
|
-
|
|
26627
|
-
|
|
26628
|
-
|
|
26629
|
-
|
|
26630
|
-
|
|
26631
|
-
//
|
|
26632
|
-
|
|
26633
|
-
|
|
26634
|
-
|
|
26635
|
-
//
|
|
26636
|
-
|
|
26627
|
+
// // Check for path intersections (including manual segments)
|
|
26628
|
+
// const intersectionCheck = this.checkPathIntersections(pathfindingResult.paths, 0.2, true);
|
|
26629
|
+
// pathfindingResult.intersections = intersectionCheck;
|
|
26630
|
+
|
|
26631
|
+
// console.log("intersectionCheck:", intersectionCheck);
|
|
26632
|
+
// console.log("intersectionCheck.hasIntersections:", intersectionCheck.hasIntersections);
|
|
26633
|
+
|
|
26634
|
+
// // Handle intersection detection - undo last operation if intersections found
|
|
26635
|
+
// // Skip this if we're already in the middle of an undo operation
|
|
26636
|
+
// if (intersectionCheck.hasIntersections && !this.isUndoInProgress) {
|
|
26637
|
+
// console.warn('⚠️ Path intersections detected! Attempting to undo last operation...');
|
|
26638
|
+
|
|
26639
|
+
// // Set flag to prevent recursive undo attempts
|
|
26640
|
+
// this.isUndoInProgress = true;
|
|
26641
|
+
|
|
26642
|
+
// // Access operationHistoryManager through sceneViewer.managers.operationHistory
|
|
26643
|
+
// const operationHistoryManager = this.sceneViewer?.managers?.operationHistory;
|
|
26644
|
+
|
|
26645
|
+
// if (operationHistoryManager) {
|
|
26646
|
+
// const lastOp = operationHistoryManager.getLastOperation();
|
|
26647
|
+
|
|
26648
|
+
// if (lastOp) {
|
|
26649
|
+
// console.warn(`⚠️ Intersection caused by operation: ${lastOp.operationName}`, lastOp.params);
|
|
26650
|
+
|
|
26651
|
+
// // Attempt to undo the operation FIRST (before removing computed objects)
|
|
26652
|
+
// // This is important because undo needs to find the segment that was moved
|
|
26653
|
+
// const undoSuccess = operationHistoryManager.undoLastOperation();
|
|
26654
|
+
|
|
26655
|
+
// if (undoSuccess) {
|
|
26656
|
+
// console.log('✅ Successfully undid operation that caused intersection');
|
|
26657
|
+
|
|
26658
|
+
// // Now remove the buggy computed objects that were created with the invalid state
|
|
26659
|
+
// console.log('🗑️ Removing buggy computed objects after undo...');
|
|
26660
|
+
// this.removeComputedObjects();
|
|
26661
|
+
|
|
26662
|
+
// // Re-run pathfinding after undo to restore valid state
|
|
26663
|
+
// console.log('🔄 Re-running pathfinding after undo to restore clean state...');
|
|
26664
|
+
|
|
26665
|
+
// // Recursively call _executePathfinding with the corrected scene state
|
|
26666
|
+
// // This is safe because we've undone the operation, so we won't get into an infinite loop
|
|
26667
|
+
// const correctedResult = await this._executePathfinding(
|
|
26668
|
+
// sceneData,
|
|
26669
|
+
// connections,
|
|
26670
|
+
// { ...options, context: `${context} (After Undo)` }
|
|
26671
|
+
// );
|
|
26672
|
+
|
|
26673
|
+
// // Mark that we performed an undo and return the corrected result
|
|
26674
|
+
// correctedResult.undoPerformed = true;
|
|
26675
|
+
// correctedResult.undoneOperation = lastOp;
|
|
26676
|
+
|
|
26677
|
+
// // Clear the undo flag before returning
|
|
26678
|
+
// this.isUndoInProgress = false;
|
|
26679
|
+
|
|
26680
|
+
// return correctedResult;
|
|
26681
|
+
// } else {
|
|
26682
|
+
// console.error('❌ Failed to undo operation that caused intersection');
|
|
26683
|
+
// pathfindingResult.undoFailed = true;
|
|
26684
|
+
// // Clear the undo flag even on failure
|
|
26685
|
+
// this.isUndoInProgress = false;
|
|
26686
|
+
// }
|
|
26687
|
+
// } else {
|
|
26688
|
+
// console.warn('⚠️ No operation in history to undo');
|
|
26689
|
+
// this.isUndoInProgress = false;
|
|
26690
|
+
// }
|
|
26691
|
+
// } else {
|
|
26692
|
+
// console.error('❌ OperationHistoryManager not available for undo');
|
|
26693
|
+
// console.error(' Available managers:', Object.keys(this.sceneViewer?.managers || {}));
|
|
26694
|
+
// this.isUndoInProgress = false;
|
|
26695
|
+
// }
|
|
26696
|
+
// } else if (intersectionCheck.hasIntersections && this.isUndoInProgress) {
|
|
26697
|
+
// console.log('⏭️ Skipping intersection handling - undo already in progress');
|
|
26698
|
+
// }
|
|
26637
26699
|
|
|
26638
|
-
// Recursively call _executePathfinding with the corrected scene state
|
|
26639
|
-
// This is safe because we've undone the operation, so we won't get into an infinite loop
|
|
26640
|
-
_context.n = 1;
|
|
26641
|
-
return this._executePathfinding(sceneData, connections, _objectSpread2(_objectSpread2({}, options), {}, {
|
|
26642
|
-
context: "".concat(context, " (After Undo)")
|
|
26643
|
-
}));
|
|
26644
|
-
case 1:
|
|
26645
|
-
correctedResult = _context.v;
|
|
26646
|
-
// Mark that we performed an undo and return the corrected result
|
|
26647
|
-
correctedResult.undoPerformed = true;
|
|
26648
|
-
correctedResult.undoneOperation = lastOp;
|
|
26649
|
-
|
|
26650
|
-
// Clear the undo flag before returning
|
|
26651
|
-
this.isUndoInProgress = false;
|
|
26652
|
-
return _context.a(2, correctedResult);
|
|
26653
|
-
case 2:
|
|
26654
|
-
console.error('❌ Failed to undo operation that caused intersection');
|
|
26655
|
-
pathfindingResult.undoFailed = true;
|
|
26656
|
-
// Clear the undo flag even on failure
|
|
26657
|
-
this.isUndoInProgress = false;
|
|
26658
|
-
case 3:
|
|
26659
|
-
_context.n = 5;
|
|
26660
|
-
break;
|
|
26661
|
-
case 4:
|
|
26662
|
-
console.warn('⚠️ No operation in history to undo');
|
|
26663
|
-
this.isUndoInProgress = false;
|
|
26664
|
-
case 5:
|
|
26665
|
-
_context.n = 7;
|
|
26666
|
-
break;
|
|
26667
|
-
case 6:
|
|
26668
|
-
console.error('❌ OperationHistoryManager not available for undo');
|
|
26669
|
-
console.error(' Available managers:', Object.keys(((_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.managers) || {}));
|
|
26670
|
-
this.isUndoInProgress = false;
|
|
26671
|
-
case 7:
|
|
26672
|
-
_context.n = 9;
|
|
26673
|
-
break;
|
|
26674
|
-
case 8:
|
|
26675
|
-
if (intersectionCheck.hasIntersections && this.isUndoInProgress) {
|
|
26676
|
-
console.log('⏭️ Skipping intersection handling - undo already in progress');
|
|
26677
|
-
}
|
|
26678
|
-
case 9:
|
|
26679
26700
|
// Create gateways in the scene if requested
|
|
26680
26701
|
if (options.createGateways && pathfindingResult.gateways) {
|
|
26681
26702
|
this.renderingManager.createGateways(pathfindingResult);
|
|
@@ -33740,7 +33761,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
33740
33761
|
* Initialize the CentralPlant manager
|
|
33741
33762
|
*
|
|
33742
33763
|
* @constructor
|
|
33743
|
-
* @version 0.1.
|
|
33764
|
+
* @version 0.1.50
|
|
33744
33765
|
* @updated 2025-10-22
|
|
33745
33766
|
*
|
|
33746
33767
|
* @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.
|
|
22
|
+
* @version 0.1.50
|
|
23
23
|
* @updated 2025-10-22
|
|
24
24
|
*
|
|
25
25
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -168,15 +168,31 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// Check segment orientation and cancel invalid translations
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
// Get the segment's direction vector to determine which axis it runs along
|
|
172
|
+
var direction = new THREE__namespace.Vector3(0, 1, 0);
|
|
173
|
+
direction.applyQuaternion(segment.quaternion);
|
|
174
|
+
direction.normalize();
|
|
175
|
+
|
|
176
|
+
// Determine which axis the segment primarily runs along
|
|
177
|
+
var absX = Math.abs(direction.x);
|
|
178
|
+
var absY = Math.abs(direction.y);
|
|
179
|
+
var absZ = Math.abs(direction.z);
|
|
180
|
+
var tolerance = 0.9; // Direction component must be > 0.9 to be considered aligned with axis
|
|
181
|
+
|
|
182
|
+
// Block translation along the axis that the segment runs parallel to
|
|
183
|
+
if (absX > tolerance && axis === 'x') {
|
|
184
|
+
console.warn("\u26A0\uFE0F translateSegment(): Cannot translate segment along ".concat(axis.toUpperCase(), " axis - segment runs along this axis"));
|
|
185
|
+
console.warn(" Segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
175
186
|
return false;
|
|
176
187
|
}
|
|
177
|
-
if (
|
|
178
|
-
console.warn("\u26A0\uFE0F translateSegment(): Cannot translate
|
|
179
|
-
console.warn("
|
|
188
|
+
if (absY > tolerance && axis === 'y') {
|
|
189
|
+
console.warn("\u26A0\uFE0F translateSegment(): Cannot translate segment along ".concat(axis.toUpperCase(), " axis - segment runs along this axis"));
|
|
190
|
+
console.warn(" Segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
if (absZ > tolerance && axis === 'z') {
|
|
194
|
+
console.warn("\u26A0\uFE0F translateSegment(): Cannot translate segment along ".concat(axis.toUpperCase(), " axis - segment runs along this axis"));
|
|
195
|
+
console.warn(" Segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
180
196
|
return false;
|
|
181
197
|
}
|
|
182
198
|
console.log('[translateSegment] segment:', segment);
|
|
@@ -341,17 +357,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
341
357
|
|
|
342
358
|
// ALWAYS update connector positions after segment movement (first or subsequent moves)
|
|
343
359
|
this.updateSegmentConnectorPositions(segment);
|
|
344
|
-
|
|
345
|
-
// NEW: Update adjacent manual segments to follow this segment's new position
|
|
346
|
-
var maintainedConnections = this.snapSegmentConnectorsToNearbyEndpoints(segment);
|
|
347
|
-
|
|
348
|
-
// NOTE: We do NOT remove connections from scene data
|
|
349
|
-
// The connections remain valid - the manual segments are maintaining those connections
|
|
350
|
-
// The pathfinding algorithm should detect that connectors are at the same position
|
|
351
|
-
// and skip creating computed segments for them
|
|
352
|
-
if (maintainedConnections.length > 0) {
|
|
353
|
-
console.log("\u2139\uFE0F ".concat(maintainedConnections.length, " connection(s) maintained by manual segments"));
|
|
354
|
-
}
|
|
360
|
+
this.snapSegmentConnectorsToNearbyEndpoints(segment);
|
|
355
361
|
|
|
356
362
|
// Store transform parameters using the OperationHistoryManager BEFORE updatePaths
|
|
357
363
|
// This is critical so that intersection detection can undo the operation
|
|
@@ -368,9 +374,6 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
368
374
|
// UNLESS skipPathUpdate is true (for batch operations)
|
|
369
375
|
if (!skipPathUpdate) {
|
|
370
376
|
console.log('🔄 Regenerating paths to create connecting pipe segments...');
|
|
371
|
-
if (maintainedConnections.length > 0) {
|
|
372
|
-
console.log("\u2139\uFE0F Manual segments are maintaining connections - pathfinding should skip connectors at same position");
|
|
373
|
-
}
|
|
374
377
|
try {
|
|
375
378
|
if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
|
|
376
379
|
this.sceneViewer.updatePaths();
|
|
@@ -1415,8 +1418,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
1415
1418
|
}
|
|
1416
1419
|
|
|
1417
1420
|
/**
|
|
1418
|
-
*
|
|
1419
|
-
* @param {THREE.Object3D} segment - The segment to
|
|
1421
|
+
* Adjust segment geometry and transform to match new endpoint positions
|
|
1422
|
+
* @param {THREE.Object3D} segment - The segment to adjust
|
|
1420
1423
|
* @param {Array<THREE.Object3D>} connectors - The segment's connectors
|
|
1421
1424
|
* @param {THREE.Vector3} endPoint1 - Explicit world position for first endpoint (optional)
|
|
1422
1425
|
* @param {THREE.Vector3} endPoint2 - Explicit world position for second endpoint (optional)
|
|
@@ -1430,7 +1433,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
1430
1433
|
var endPoint2 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1431
1434
|
var activeSegment = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
1432
1435
|
if (!segment || connectors.length !== 2) {
|
|
1433
|
-
console.warn('⚠️ Cannot
|
|
1436
|
+
console.warn('⚠️ Cannot adjust segment: invalid segment or connectors');
|
|
1434
1437
|
return;
|
|
1435
1438
|
}
|
|
1436
1439
|
var _connectors = _rollupPluginBabelHelpers.slicedToArray(connectors, 2),
|
|
@@ -1473,21 +1476,28 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
1473
1476
|
this._removeZeroLengthSegment(segment, connectors, activeSegment);
|
|
1474
1477
|
return;
|
|
1475
1478
|
}
|
|
1476
|
-
|
|
1479
|
+
var oldLength = segment.geometry.parameters.height;
|
|
1480
|
+
console.log("\uD83D\uDD27 Adjusting segment geometry: ".concat(oldLength.toFixed(3), " \u2192 ").concat(newLength.toFixed(3)));
|
|
1481
|
+
|
|
1482
|
+
// Only recreate geometry if length has changed significantly
|
|
1483
|
+
if (Math.abs(newLength - oldLength) > 1e-6) {
|
|
1484
|
+
var oldGeometry = segment.geometry;
|
|
1485
|
+
var pipeRadius = oldGeometry.parameters.radiusTop || 0.1;
|
|
1477
1486
|
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
segment.material;
|
|
1481
|
-
var pipeRadius = oldGeometry.parameters.radiusTop || 0.1;
|
|
1487
|
+
// Create new cylinder geometry with updated length
|
|
1488
|
+
var newGeometry = new THREE__namespace.CylinderGeometry(pipeRadius, pipeRadius, newLength, 16, 1, false);
|
|
1482
1489
|
|
|
1483
|
-
|
|
1484
|
-
|
|
1490
|
+
// Replace geometry
|
|
1491
|
+
segment.geometry = newGeometry;
|
|
1485
1492
|
|
|
1486
|
-
|
|
1487
|
-
|
|
1493
|
+
// Dispose old geometry
|
|
1494
|
+
oldGeometry.dispose();
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
// Update segment position to new center
|
|
1488
1498
|
segment.position.copy(newCenter);
|
|
1489
1499
|
|
|
1490
|
-
// Calculate and apply rotation
|
|
1500
|
+
// Calculate and apply rotation to align with new direction
|
|
1491
1501
|
var quaternion = new THREE__namespace.Quaternion();
|
|
1492
1502
|
var up = new THREE__namespace.Vector3(0, 1, 0);
|
|
1493
1503
|
quaternion.setFromUnitVectors(up, direction.clone().normalize());
|
|
@@ -1496,12 +1506,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
1496
1506
|
// Update matrices
|
|
1497
1507
|
segment.updateMatrix();
|
|
1498
1508
|
segment.updateMatrixWorld(true);
|
|
1499
|
-
|
|
1500
|
-
// Dispose old geometry
|
|
1501
|
-
if (oldGeometry && oldGeometry !== newGeometry) {
|
|
1502
|
-
oldGeometry.dispose();
|
|
1503
|
-
}
|
|
1504
|
-
console.log("\u2705 Segment mesh recreated: new length = ".concat(newLength.toFixed(3), ", center = [").concat(newCenter.x.toFixed(2), ", ").concat(newCenter.y.toFixed(2), ", ").concat(newCenter.z.toFixed(2), "]"));
|
|
1509
|
+
console.log("\u2705 Segment adjusted: length = ".concat(newLength.toFixed(3), ", center = [").concat(newCenter.x.toFixed(2), ", ").concat(newCenter.y.toFixed(2), ", ").concat(newCenter.z.toFixed(2), "]"));
|
|
1505
1510
|
}
|
|
1506
1511
|
|
|
1507
1512
|
/**
|