@2112-lab/central-plant 0.1.25 → 0.1.26
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 +266 -3
- package/dist/cjs/src/core/centralPlant.js +266 -3
- package/dist/esm/src/core/centralPlant.js +267 -4
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -25865,8 +25865,8 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
25865
25865
|
* Update paths in the scene
|
|
25866
25866
|
* @returns {boolean} True if paths were updated successfully, false otherwise
|
|
25867
25867
|
* @description Triggers an update of all connection paths/pipes in the scene to reflect
|
|
25868
|
-
* current component positions and connections. This
|
|
25869
|
-
*
|
|
25868
|
+
* current component positions and connections. This method ensures all scene data is
|
|
25869
|
+
* synchronized before updating paths for guaranteed accuracy.
|
|
25870
25870
|
* @example
|
|
25871
25871
|
* // After moving components or changing connections
|
|
25872
25872
|
* const success = centralPlant.updatePaths();
|
|
@@ -25882,8 +25882,15 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
25882
25882
|
return false;
|
|
25883
25883
|
}
|
|
25884
25884
|
try {
|
|
25885
|
+
// Step 1: Ensure scene data is synchronized before updating paths
|
|
25886
|
+
console.log('🔄 updatePaths(): Synchronizing scene data before path update...');
|
|
25887
|
+
if (!this.syncSceneData()) {
|
|
25888
|
+
console.warn('⚠️ updatePaths(): Scene data synchronization failed, proceeding with caution');
|
|
25889
|
+
}
|
|
25890
|
+
|
|
25891
|
+
// Step 2: Update paths with synchronized data
|
|
25885
25892
|
this.sceneViewer.updatePaths();
|
|
25886
|
-
console.log('✅ updatePaths(): Paths updated successfully');
|
|
25893
|
+
console.log('✅ updatePaths(): Paths updated successfully with synchronized data');
|
|
25887
25894
|
return true;
|
|
25888
25895
|
} catch (error) {
|
|
25889
25896
|
console.error('❌ updatePaths(): Error updating paths:', error);
|
|
@@ -25891,6 +25898,262 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
25891
25898
|
}
|
|
25892
25899
|
}
|
|
25893
25900
|
|
|
25901
|
+
/**
|
|
25902
|
+
* Synchronize scene data to ensure all component positions and properties are up-to-date
|
|
25903
|
+
* @returns {boolean} True if synchronization was successful, false otherwise
|
|
25904
|
+
* @description Updates the currentSceneData to match the actual Three.js scene state.
|
|
25905
|
+
* This includes component positions, rotations, scales, and world bounding boxes.
|
|
25906
|
+
* Should be called before operations that depend on accurate scene data.
|
|
25907
|
+
* @example
|
|
25908
|
+
* // Ensure scene data is current before pathfinding
|
|
25909
|
+
* const success = centralPlant.syncSceneData();
|
|
25910
|
+
* if (success) {
|
|
25911
|
+
* console.log('Scene data synchronized with Three.js scene');
|
|
25912
|
+
* }
|
|
25913
|
+
*/
|
|
25914
|
+
}, {
|
|
25915
|
+
key: "syncSceneData",
|
|
25916
|
+
value: function syncSceneData() {
|
|
25917
|
+
var _this = this;
|
|
25918
|
+
// Check if scene viewer and currentSceneData are available
|
|
25919
|
+
if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
|
|
25920
|
+
console.warn('⚠️ syncSceneData(): Scene viewer or current scene data not available');
|
|
25921
|
+
return false;
|
|
25922
|
+
}
|
|
25923
|
+
if (!this.sceneViewer.scene) {
|
|
25924
|
+
console.warn('⚠️ syncSceneData(): Three.js scene not available');
|
|
25925
|
+
return false;
|
|
25926
|
+
}
|
|
25927
|
+
try {
|
|
25928
|
+
console.log('🔄 syncSceneData(): Starting scene data synchronization...');
|
|
25929
|
+
|
|
25930
|
+
// Get reference to currentSceneData
|
|
25931
|
+
var currentSceneData = this.sceneViewer.currentSceneData;
|
|
25932
|
+
if (!currentSceneData.scene || !currentSceneData.scene.object || !currentSceneData.scene.object.children) {
|
|
25933
|
+
console.warn('⚠️ syncSceneData(): Invalid currentSceneData structure');
|
|
25934
|
+
return false;
|
|
25935
|
+
}
|
|
25936
|
+
|
|
25937
|
+
// Update each component in scene data to match Three.js scene
|
|
25938
|
+
var updatedCount = 0;
|
|
25939
|
+
currentSceneData.scene.object.children.forEach(function (sceneDataChild, index) {
|
|
25940
|
+
// Find matching Three.js object
|
|
25941
|
+
var matchingThreeObject = null;
|
|
25942
|
+
_this.sceneViewer.scene.traverse(function (threeObject) {
|
|
25943
|
+
var _sceneDataChild$userD, _threeObject$userData, _threeObject$userData2;
|
|
25944
|
+
// Check various UUID matching strategies
|
|
25945
|
+
if (threeObject.uuid === sceneDataChild.uuid || threeObject.uuid === ((_sceneDataChild$userD = sceneDataChild.userData) === null || _sceneDataChild$userD === void 0 ? void 0 : _sceneDataChild$userD.originalUuid) || ((_threeObject$userData = threeObject.userData) === null || _threeObject$userData === void 0 ? void 0 : _threeObject$userData.originalUuid) === sceneDataChild.uuid || ((_threeObject$userData2 = threeObject.userData) === null || _threeObject$userData2 === void 0 ? void 0 : _threeObject$userData2.hardcodedUuid) === sceneDataChild.uuid) {
|
|
25946
|
+
matchingThreeObject = threeObject;
|
|
25947
|
+
}
|
|
25948
|
+
});
|
|
25949
|
+
if (matchingThreeObject) {
|
|
25950
|
+
// Update position, rotation, and scale
|
|
25951
|
+
sceneDataChild.position = {
|
|
25952
|
+
x: matchingThreeObject.position.x,
|
|
25953
|
+
y: matchingThreeObject.position.y,
|
|
25954
|
+
z: matchingThreeObject.position.z
|
|
25955
|
+
};
|
|
25956
|
+
sceneDataChild.rotation = {
|
|
25957
|
+
x: matchingThreeObject.rotation.x,
|
|
25958
|
+
y: matchingThreeObject.rotation.y,
|
|
25959
|
+
z: matchingThreeObject.rotation.z
|
|
25960
|
+
};
|
|
25961
|
+
sceneDataChild.scale = {
|
|
25962
|
+
x: matchingThreeObject.scale.x,
|
|
25963
|
+
y: matchingThreeObject.scale.y,
|
|
25964
|
+
z: matchingThreeObject.scale.z
|
|
25965
|
+
};
|
|
25966
|
+
|
|
25967
|
+
// Update matrix
|
|
25968
|
+
sceneDataChild.matrix = matchingThreeObject.matrix.elements;
|
|
25969
|
+
|
|
25970
|
+
// Update world bounding box
|
|
25971
|
+
if (matchingThreeObject.isMesh) {
|
|
25972
|
+
var boundingBox = new THREE__namespace.Box3().setFromObject(matchingThreeObject);
|
|
25973
|
+
if (!sceneDataChild.userData) sceneDataChild.userData = {};
|
|
25974
|
+
sceneDataChild.userData.worldBoundingBox = {
|
|
25975
|
+
min: boundingBox.min.toArray(),
|
|
25976
|
+
max: boundingBox.max.toArray()
|
|
25977
|
+
};
|
|
25978
|
+
}
|
|
25979
|
+
|
|
25980
|
+
// Sync children (connectors) if they exist
|
|
25981
|
+
if (sceneDataChild.children && matchingThreeObject.children) {
|
|
25982
|
+
sceneDataChild.children.forEach(function (sceneChild, childIndex) {
|
|
25983
|
+
var matchingChild = matchingThreeObject.children.find(function (threeChild) {
|
|
25984
|
+
var _sceneChild$userData, _threeChild$userData;
|
|
25985
|
+
return threeChild.uuid === sceneChild.uuid || threeChild.uuid === ((_sceneChild$userData = sceneChild.userData) === null || _sceneChild$userData === void 0 ? void 0 : _sceneChild$userData.originalUuid) || ((_threeChild$userData = threeChild.userData) === null || _threeChild$userData === void 0 ? void 0 : _threeChild$userData.originalUuid) === sceneChild.uuid;
|
|
25986
|
+
});
|
|
25987
|
+
if (matchingChild) {
|
|
25988
|
+
var _matchingChild$userDa;
|
|
25989
|
+
// Update child position, rotation, and scale
|
|
25990
|
+
sceneChild.position = {
|
|
25991
|
+
x: matchingChild.position.x,
|
|
25992
|
+
y: matchingChild.position.y,
|
|
25993
|
+
z: matchingChild.position.z
|
|
25994
|
+
};
|
|
25995
|
+
sceneChild.rotation = {
|
|
25996
|
+
x: matchingChild.rotation.x,
|
|
25997
|
+
y: matchingChild.rotation.y,
|
|
25998
|
+
z: matchingChild.rotation.z
|
|
25999
|
+
};
|
|
26000
|
+
sceneChild.scale = {
|
|
26001
|
+
x: matchingChild.scale.x,
|
|
26002
|
+
y: matchingChild.scale.y,
|
|
26003
|
+
z: matchingChild.scale.z
|
|
26004
|
+
};
|
|
26005
|
+
|
|
26006
|
+
// Update direction vector for connectors
|
|
26007
|
+
if ((_matchingChild$userDa = matchingChild.userData) !== null && _matchingChild$userDa !== void 0 && _matchingChild$userDa.direction) {
|
|
26008
|
+
if (!sceneChild.userData) sceneChild.userData = {};
|
|
26009
|
+
sceneChild.userData.direction = _toConsumableArray(matchingChild.userData.direction);
|
|
26010
|
+
}
|
|
26011
|
+
}
|
|
26012
|
+
});
|
|
26013
|
+
}
|
|
26014
|
+
updatedCount++;
|
|
26015
|
+
} else {
|
|
26016
|
+
console.warn("\u26A0\uFE0F syncSceneData(): No matching Three.js object found for scene data child: ".concat(sceneDataChild.uuid));
|
|
26017
|
+
}
|
|
26018
|
+
});
|
|
26019
|
+
|
|
26020
|
+
// Force recompute world bounding boxes for pathfinding accuracy
|
|
26021
|
+
if (this.sceneViewer.pathfindingManager && typeof this.sceneViewer.pathfindingManager.recomputeWorldBoundingBoxes === 'function') {
|
|
26022
|
+
this.sceneViewer.pathfindingManager.recomputeWorldBoundingBoxes(currentSceneData);
|
|
26023
|
+
console.log('🔄 syncSceneData(): Recomputed world bounding boxes for pathfinding');
|
|
26024
|
+
}
|
|
26025
|
+
console.log("\u2705 syncSceneData(): Synchronized ".concat(updatedCount, " components successfully"));
|
|
26026
|
+
return true;
|
|
26027
|
+
} catch (error) {
|
|
26028
|
+
console.error('❌ syncSceneData(): Error synchronizing scene data:', error);
|
|
26029
|
+
return false;
|
|
26030
|
+
}
|
|
26031
|
+
}
|
|
26032
|
+
|
|
26033
|
+
/**
|
|
26034
|
+
* Force complete scene data synchronization using SceneOperationsManager
|
|
26035
|
+
* @returns {boolean} True if forced synchronization was successful, false otherwise
|
|
26036
|
+
* @description Uses the SceneOperationsManager's updateSceneDataAfterTransform method
|
|
26037
|
+
* to update scene data for every component. This is more thorough than syncSceneData()
|
|
26038
|
+
* and should be used when maximum accuracy is required.
|
|
26039
|
+
* @example
|
|
26040
|
+
* // Force complete synchronization before critical operations
|
|
26041
|
+
* const success = centralPlant.forceSyncSceneData();
|
|
26042
|
+
* if (success) {
|
|
26043
|
+
* console.log('Complete scene data synchronization completed');
|
|
26044
|
+
* }
|
|
26045
|
+
*/
|
|
26046
|
+
}, {
|
|
26047
|
+
key: "forceSyncSceneData",
|
|
26048
|
+
value: function forceSyncSceneData() {
|
|
26049
|
+
var _this2 = this;
|
|
26050
|
+
// Check if scene viewer and sceneOperationsManager are available
|
|
26051
|
+
if (!this.sceneViewer || !this.sceneViewer.sceneOperationsManager) {
|
|
26052
|
+
console.warn('⚠️ forceSyncSceneData(): Scene viewer or scene operations manager not available');
|
|
26053
|
+
return false;
|
|
26054
|
+
}
|
|
26055
|
+
if (!this.sceneViewer.currentSceneData) {
|
|
26056
|
+
console.warn('⚠️ forceSyncSceneData(): Current scene data not available');
|
|
26057
|
+
return false;
|
|
26058
|
+
}
|
|
26059
|
+
if (!this.sceneViewer.scene) {
|
|
26060
|
+
console.warn('⚠️ forceSyncSceneData(): Three.js scene not available');
|
|
26061
|
+
return false;
|
|
26062
|
+
}
|
|
26063
|
+
try {
|
|
26064
|
+
console.log('🔄 forceSyncSceneData(): Starting forced scene data synchronization...');
|
|
26065
|
+
var syncedCount = 0;
|
|
26066
|
+
var currentSceneData = this.sceneViewer.currentSceneData;
|
|
26067
|
+
|
|
26068
|
+
// Traverse all objects in the Three.js scene and update their scene data
|
|
26069
|
+
this.sceneViewer.scene.traverse(function (threeObject) {
|
|
26070
|
+
// Only sync objects that have component-related userData
|
|
26071
|
+
if (threeObject.userData && (threeObject.userData.componentType === 'component' || threeObject.userData.componentType === 'gateway' || threeObject.userData.libraryId)) {
|
|
26072
|
+
console.log("\uD83D\uDD04 Syncing object: ".concat(threeObject.uuid, " (").concat(threeObject.userData.componentType || 'unknown', ")"));
|
|
26073
|
+
|
|
26074
|
+
// Use the existing updateSceneDataAfterTransform method
|
|
26075
|
+
var success = _this2.sceneViewer.sceneOperationsManager.updateSceneDataAfterTransform(threeObject, currentSceneData);
|
|
26076
|
+
if (success) {
|
|
26077
|
+
syncedCount++;
|
|
26078
|
+
} else {
|
|
26079
|
+
console.warn("\u26A0\uFE0F Failed to sync object: ".concat(threeObject.uuid));
|
|
26080
|
+
}
|
|
26081
|
+
}
|
|
26082
|
+
});
|
|
26083
|
+
console.log("\u2705 forceSyncSceneData(): Force synchronized ".concat(syncedCount, " objects successfully"));
|
|
26084
|
+
return true;
|
|
26085
|
+
} catch (error) {
|
|
26086
|
+
console.error('❌ forceSyncSceneData(): Error during forced scene data synchronization:', error);
|
|
26087
|
+
return false;
|
|
26088
|
+
}
|
|
26089
|
+
}
|
|
26090
|
+
|
|
26091
|
+
/**
|
|
26092
|
+
* Update paths with optional scene data synchronization level
|
|
26093
|
+
* @param {string} [syncLevel='auto'] - Level of synchronization: 'none', 'basic', 'complete', or 'auto'
|
|
26094
|
+
* @returns {boolean} True if paths were updated successfully, false otherwise
|
|
26095
|
+
* @description Enhanced updatePaths method that allows choosing the level of scene data
|
|
26096
|
+
* synchronization before updating paths. The 'auto' level intelligently chooses based
|
|
26097
|
+
* on scene complexity and recent changes.
|
|
26098
|
+
* @example
|
|
26099
|
+
* // Update paths with automatic synchronization (recommended)
|
|
26100
|
+
* centralPlant.updatePathsWithSync('auto');
|
|
26101
|
+
*
|
|
26102
|
+
* // Update paths with complete synchronization (most accurate)
|
|
26103
|
+
* centralPlant.updatePathsWithSync('complete');
|
|
26104
|
+
*
|
|
26105
|
+
* // Update paths without synchronization (fastest)
|
|
26106
|
+
* centralPlant.updatePathsWithSync('none');
|
|
26107
|
+
*/
|
|
26108
|
+
}, {
|
|
26109
|
+
key: "updatePathsWithSync",
|
|
26110
|
+
value: function updatePathsWithSync() {
|
|
26111
|
+
var syncLevel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'auto';
|
|
26112
|
+
if (!this.sceneViewer || !this.sceneViewer.updatePaths) {
|
|
26113
|
+
console.warn('⚠️ updatePathsWithSync(): Scene viewer or updatePaths method not available');
|
|
26114
|
+
return false;
|
|
26115
|
+
}
|
|
26116
|
+
try {
|
|
26117
|
+
// Determine sync level automatically if needed
|
|
26118
|
+
if (syncLevel === 'auto') {
|
|
26119
|
+
var _this$transformHistor;
|
|
26120
|
+
// Use basic sync by default, but upgrade to complete if recent transforms detected
|
|
26121
|
+
syncLevel = (_this$transformHistor = this.transformHistory) !== null && _this$transformHistor !== void 0 && _this$transformHistor.lastTransform && Date.now() - new Date(this.transformHistory.lastTransform.timestamp).getTime() < 5000 ? 'complete' : 'basic';
|
|
26122
|
+
console.log("\uD83E\uDD16 updatePathsWithSync(): Auto-selected sync level: ".concat(syncLevel));
|
|
26123
|
+
}
|
|
26124
|
+
|
|
26125
|
+
// Perform synchronization based on level
|
|
26126
|
+
var syncSuccess = true;
|
|
26127
|
+
switch (syncLevel) {
|
|
26128
|
+
case 'none':
|
|
26129
|
+
console.log('⚡ updatePathsWithSync(): Skipping synchronization for speed');
|
|
26130
|
+
break;
|
|
26131
|
+
case 'basic':
|
|
26132
|
+
console.log('🔄 updatePathsWithSync(): Performing basic scene data synchronization...');
|
|
26133
|
+
syncSuccess = this.syncSceneData();
|
|
26134
|
+
break;
|
|
26135
|
+
case 'complete':
|
|
26136
|
+
console.log('🔄 updatePathsWithSync(): Performing complete scene data synchronization...');
|
|
26137
|
+
syncSuccess = this.forceSyncSceneData();
|
|
26138
|
+
break;
|
|
26139
|
+
default:
|
|
26140
|
+
console.warn("\u26A0\uFE0F updatePathsWithSync(): Unknown sync level '".concat(syncLevel, "', defaulting to basic"));
|
|
26141
|
+
syncSuccess = this.syncSceneData();
|
|
26142
|
+
}
|
|
26143
|
+
if (!syncSuccess && syncLevel !== 'none') {
|
|
26144
|
+
console.warn('⚠️ updatePathsWithSync(): Scene data synchronization failed, proceeding with caution');
|
|
26145
|
+
}
|
|
26146
|
+
|
|
26147
|
+
// Update paths
|
|
26148
|
+
this.sceneViewer.updatePaths();
|
|
26149
|
+
console.log("\u2705 updatePathsWithSync(): Paths updated successfully with '".concat(syncLevel, "' synchronization"));
|
|
26150
|
+
return true;
|
|
26151
|
+
} catch (error) {
|
|
26152
|
+
console.error('❌ updatePathsWithSync(): Error updating paths with sync:', error);
|
|
26153
|
+
return false;
|
|
26154
|
+
}
|
|
26155
|
+
}
|
|
26156
|
+
|
|
25894
26157
|
/**
|
|
25895
26158
|
* Add a connection between two connector IDs to the connections list
|
|
25896
26159
|
* @param {string} fromConnectorId - The UUID of the source connector
|
|
@@ -569,8 +569,8 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
569
569
|
* Update paths in the scene
|
|
570
570
|
* @returns {boolean} True if paths were updated successfully, false otherwise
|
|
571
571
|
* @description Triggers an update of all connection paths/pipes in the scene to reflect
|
|
572
|
-
* current component positions and connections. This
|
|
573
|
-
*
|
|
572
|
+
* current component positions and connections. This method ensures all scene data is
|
|
573
|
+
* synchronized before updating paths for guaranteed accuracy.
|
|
574
574
|
* @example
|
|
575
575
|
* // After moving components or changing connections
|
|
576
576
|
* const success = centralPlant.updatePaths();
|
|
@@ -586,8 +586,15 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
586
586
|
return false;
|
|
587
587
|
}
|
|
588
588
|
try {
|
|
589
|
+
// Step 1: Ensure scene data is synchronized before updating paths
|
|
590
|
+
console.log('🔄 updatePaths(): Synchronizing scene data before path update...');
|
|
591
|
+
if (!this.syncSceneData()) {
|
|
592
|
+
console.warn('⚠️ updatePaths(): Scene data synchronization failed, proceeding with caution');
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Step 2: Update paths with synchronized data
|
|
589
596
|
this.sceneViewer.updatePaths();
|
|
590
|
-
console.log('✅ updatePaths(): Paths updated successfully');
|
|
597
|
+
console.log('✅ updatePaths(): Paths updated successfully with synchronized data');
|
|
591
598
|
return true;
|
|
592
599
|
} catch (error) {
|
|
593
600
|
console.error('❌ updatePaths(): Error updating paths:', error);
|
|
@@ -595,6 +602,262 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
595
602
|
}
|
|
596
603
|
}
|
|
597
604
|
|
|
605
|
+
/**
|
|
606
|
+
* Synchronize scene data to ensure all component positions and properties are up-to-date
|
|
607
|
+
* @returns {boolean} True if synchronization was successful, false otherwise
|
|
608
|
+
* @description Updates the currentSceneData to match the actual Three.js scene state.
|
|
609
|
+
* This includes component positions, rotations, scales, and world bounding boxes.
|
|
610
|
+
* Should be called before operations that depend on accurate scene data.
|
|
611
|
+
* @example
|
|
612
|
+
* // Ensure scene data is current before pathfinding
|
|
613
|
+
* const success = centralPlant.syncSceneData();
|
|
614
|
+
* if (success) {
|
|
615
|
+
* console.log('Scene data synchronized with Three.js scene');
|
|
616
|
+
* }
|
|
617
|
+
*/
|
|
618
|
+
}, {
|
|
619
|
+
key: "syncSceneData",
|
|
620
|
+
value: function syncSceneData() {
|
|
621
|
+
var _this = this;
|
|
622
|
+
// Check if scene viewer and currentSceneData are available
|
|
623
|
+
if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
|
|
624
|
+
console.warn('⚠️ syncSceneData(): Scene viewer or current scene data not available');
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
if (!this.sceneViewer.scene) {
|
|
628
|
+
console.warn('⚠️ syncSceneData(): Three.js scene not available');
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
try {
|
|
632
|
+
console.log('🔄 syncSceneData(): Starting scene data synchronization...');
|
|
633
|
+
|
|
634
|
+
// Get reference to currentSceneData
|
|
635
|
+
var currentSceneData = this.sceneViewer.currentSceneData;
|
|
636
|
+
if (!currentSceneData.scene || !currentSceneData.scene.object || !currentSceneData.scene.object.children) {
|
|
637
|
+
console.warn('⚠️ syncSceneData(): Invalid currentSceneData structure');
|
|
638
|
+
return false;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// Update each component in scene data to match Three.js scene
|
|
642
|
+
var updatedCount = 0;
|
|
643
|
+
currentSceneData.scene.object.children.forEach(function (sceneDataChild, index) {
|
|
644
|
+
// Find matching Three.js object
|
|
645
|
+
var matchingThreeObject = null;
|
|
646
|
+
_this.sceneViewer.scene.traverse(function (threeObject) {
|
|
647
|
+
var _sceneDataChild$userD, _threeObject$userData, _threeObject$userData2;
|
|
648
|
+
// Check various UUID matching strategies
|
|
649
|
+
if (threeObject.uuid === sceneDataChild.uuid || threeObject.uuid === ((_sceneDataChild$userD = sceneDataChild.userData) === null || _sceneDataChild$userD === void 0 ? void 0 : _sceneDataChild$userD.originalUuid) || ((_threeObject$userData = threeObject.userData) === null || _threeObject$userData === void 0 ? void 0 : _threeObject$userData.originalUuid) === sceneDataChild.uuid || ((_threeObject$userData2 = threeObject.userData) === null || _threeObject$userData2 === void 0 ? void 0 : _threeObject$userData2.hardcodedUuid) === sceneDataChild.uuid) {
|
|
650
|
+
matchingThreeObject = threeObject;
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
if (matchingThreeObject) {
|
|
654
|
+
// Update position, rotation, and scale
|
|
655
|
+
sceneDataChild.position = {
|
|
656
|
+
x: matchingThreeObject.position.x,
|
|
657
|
+
y: matchingThreeObject.position.y,
|
|
658
|
+
z: matchingThreeObject.position.z
|
|
659
|
+
};
|
|
660
|
+
sceneDataChild.rotation = {
|
|
661
|
+
x: matchingThreeObject.rotation.x,
|
|
662
|
+
y: matchingThreeObject.rotation.y,
|
|
663
|
+
z: matchingThreeObject.rotation.z
|
|
664
|
+
};
|
|
665
|
+
sceneDataChild.scale = {
|
|
666
|
+
x: matchingThreeObject.scale.x,
|
|
667
|
+
y: matchingThreeObject.scale.y,
|
|
668
|
+
z: matchingThreeObject.scale.z
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
// Update matrix
|
|
672
|
+
sceneDataChild.matrix = matchingThreeObject.matrix.elements;
|
|
673
|
+
|
|
674
|
+
// Update world bounding box
|
|
675
|
+
if (matchingThreeObject.isMesh) {
|
|
676
|
+
var boundingBox = new THREE__namespace.Box3().setFromObject(matchingThreeObject);
|
|
677
|
+
if (!sceneDataChild.userData) sceneDataChild.userData = {};
|
|
678
|
+
sceneDataChild.userData.worldBoundingBox = {
|
|
679
|
+
min: boundingBox.min.toArray(),
|
|
680
|
+
max: boundingBox.max.toArray()
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Sync children (connectors) if they exist
|
|
685
|
+
if (sceneDataChild.children && matchingThreeObject.children) {
|
|
686
|
+
sceneDataChild.children.forEach(function (sceneChild, childIndex) {
|
|
687
|
+
var matchingChild = matchingThreeObject.children.find(function (threeChild) {
|
|
688
|
+
var _sceneChild$userData, _threeChild$userData;
|
|
689
|
+
return threeChild.uuid === sceneChild.uuid || threeChild.uuid === ((_sceneChild$userData = sceneChild.userData) === null || _sceneChild$userData === void 0 ? void 0 : _sceneChild$userData.originalUuid) || ((_threeChild$userData = threeChild.userData) === null || _threeChild$userData === void 0 ? void 0 : _threeChild$userData.originalUuid) === sceneChild.uuid;
|
|
690
|
+
});
|
|
691
|
+
if (matchingChild) {
|
|
692
|
+
var _matchingChild$userDa;
|
|
693
|
+
// Update child position, rotation, and scale
|
|
694
|
+
sceneChild.position = {
|
|
695
|
+
x: matchingChild.position.x,
|
|
696
|
+
y: matchingChild.position.y,
|
|
697
|
+
z: matchingChild.position.z
|
|
698
|
+
};
|
|
699
|
+
sceneChild.rotation = {
|
|
700
|
+
x: matchingChild.rotation.x,
|
|
701
|
+
y: matchingChild.rotation.y,
|
|
702
|
+
z: matchingChild.rotation.z
|
|
703
|
+
};
|
|
704
|
+
sceneChild.scale = {
|
|
705
|
+
x: matchingChild.scale.x,
|
|
706
|
+
y: matchingChild.scale.y,
|
|
707
|
+
z: matchingChild.scale.z
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
// Update direction vector for connectors
|
|
711
|
+
if ((_matchingChild$userDa = matchingChild.userData) !== null && _matchingChild$userDa !== void 0 && _matchingChild$userDa.direction) {
|
|
712
|
+
if (!sceneChild.userData) sceneChild.userData = {};
|
|
713
|
+
sceneChild.userData.direction = _rollupPluginBabelHelpers.toConsumableArray(matchingChild.userData.direction);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
updatedCount++;
|
|
719
|
+
} else {
|
|
720
|
+
console.warn("\u26A0\uFE0F syncSceneData(): No matching Three.js object found for scene data child: ".concat(sceneDataChild.uuid));
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
// Force recompute world bounding boxes for pathfinding accuracy
|
|
725
|
+
if (this.sceneViewer.pathfindingManager && typeof this.sceneViewer.pathfindingManager.recomputeWorldBoundingBoxes === 'function') {
|
|
726
|
+
this.sceneViewer.pathfindingManager.recomputeWorldBoundingBoxes(currentSceneData);
|
|
727
|
+
console.log('🔄 syncSceneData(): Recomputed world bounding boxes for pathfinding');
|
|
728
|
+
}
|
|
729
|
+
console.log("\u2705 syncSceneData(): Synchronized ".concat(updatedCount, " components successfully"));
|
|
730
|
+
return true;
|
|
731
|
+
} catch (error) {
|
|
732
|
+
console.error('❌ syncSceneData(): Error synchronizing scene data:', error);
|
|
733
|
+
return false;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* Force complete scene data synchronization using SceneOperationsManager
|
|
739
|
+
* @returns {boolean} True if forced synchronization was successful, false otherwise
|
|
740
|
+
* @description Uses the SceneOperationsManager's updateSceneDataAfterTransform method
|
|
741
|
+
* to update scene data for every component. This is more thorough than syncSceneData()
|
|
742
|
+
* and should be used when maximum accuracy is required.
|
|
743
|
+
* @example
|
|
744
|
+
* // Force complete synchronization before critical operations
|
|
745
|
+
* const success = centralPlant.forceSyncSceneData();
|
|
746
|
+
* if (success) {
|
|
747
|
+
* console.log('Complete scene data synchronization completed');
|
|
748
|
+
* }
|
|
749
|
+
*/
|
|
750
|
+
}, {
|
|
751
|
+
key: "forceSyncSceneData",
|
|
752
|
+
value: function forceSyncSceneData() {
|
|
753
|
+
var _this2 = this;
|
|
754
|
+
// Check if scene viewer and sceneOperationsManager are available
|
|
755
|
+
if (!this.sceneViewer || !this.sceneViewer.sceneOperationsManager) {
|
|
756
|
+
console.warn('⚠️ forceSyncSceneData(): Scene viewer or scene operations manager not available');
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
if (!this.sceneViewer.currentSceneData) {
|
|
760
|
+
console.warn('⚠️ forceSyncSceneData(): Current scene data not available');
|
|
761
|
+
return false;
|
|
762
|
+
}
|
|
763
|
+
if (!this.sceneViewer.scene) {
|
|
764
|
+
console.warn('⚠️ forceSyncSceneData(): Three.js scene not available');
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
try {
|
|
768
|
+
console.log('🔄 forceSyncSceneData(): Starting forced scene data synchronization...');
|
|
769
|
+
var syncedCount = 0;
|
|
770
|
+
var currentSceneData = this.sceneViewer.currentSceneData;
|
|
771
|
+
|
|
772
|
+
// Traverse all objects in the Three.js scene and update their scene data
|
|
773
|
+
this.sceneViewer.scene.traverse(function (threeObject) {
|
|
774
|
+
// Only sync objects that have component-related userData
|
|
775
|
+
if (threeObject.userData && (threeObject.userData.componentType === 'component' || threeObject.userData.componentType === 'gateway' || threeObject.userData.libraryId)) {
|
|
776
|
+
console.log("\uD83D\uDD04 Syncing object: ".concat(threeObject.uuid, " (").concat(threeObject.userData.componentType || 'unknown', ")"));
|
|
777
|
+
|
|
778
|
+
// Use the existing updateSceneDataAfterTransform method
|
|
779
|
+
var success = _this2.sceneViewer.sceneOperationsManager.updateSceneDataAfterTransform(threeObject, currentSceneData);
|
|
780
|
+
if (success) {
|
|
781
|
+
syncedCount++;
|
|
782
|
+
} else {
|
|
783
|
+
console.warn("\u26A0\uFE0F Failed to sync object: ".concat(threeObject.uuid));
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
console.log("\u2705 forceSyncSceneData(): Force synchronized ".concat(syncedCount, " objects successfully"));
|
|
788
|
+
return true;
|
|
789
|
+
} catch (error) {
|
|
790
|
+
console.error('❌ forceSyncSceneData(): Error during forced scene data synchronization:', error);
|
|
791
|
+
return false;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Update paths with optional scene data synchronization level
|
|
797
|
+
* @param {string} [syncLevel='auto'] - Level of synchronization: 'none', 'basic', 'complete', or 'auto'
|
|
798
|
+
* @returns {boolean} True if paths were updated successfully, false otherwise
|
|
799
|
+
* @description Enhanced updatePaths method that allows choosing the level of scene data
|
|
800
|
+
* synchronization before updating paths. The 'auto' level intelligently chooses based
|
|
801
|
+
* on scene complexity and recent changes.
|
|
802
|
+
* @example
|
|
803
|
+
* // Update paths with automatic synchronization (recommended)
|
|
804
|
+
* centralPlant.updatePathsWithSync('auto');
|
|
805
|
+
*
|
|
806
|
+
* // Update paths with complete synchronization (most accurate)
|
|
807
|
+
* centralPlant.updatePathsWithSync('complete');
|
|
808
|
+
*
|
|
809
|
+
* // Update paths without synchronization (fastest)
|
|
810
|
+
* centralPlant.updatePathsWithSync('none');
|
|
811
|
+
*/
|
|
812
|
+
}, {
|
|
813
|
+
key: "updatePathsWithSync",
|
|
814
|
+
value: function updatePathsWithSync() {
|
|
815
|
+
var syncLevel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'auto';
|
|
816
|
+
if (!this.sceneViewer || !this.sceneViewer.updatePaths) {
|
|
817
|
+
console.warn('⚠️ updatePathsWithSync(): Scene viewer or updatePaths method not available');
|
|
818
|
+
return false;
|
|
819
|
+
}
|
|
820
|
+
try {
|
|
821
|
+
// Determine sync level automatically if needed
|
|
822
|
+
if (syncLevel === 'auto') {
|
|
823
|
+
var _this$transformHistor;
|
|
824
|
+
// Use basic sync by default, but upgrade to complete if recent transforms detected
|
|
825
|
+
syncLevel = (_this$transformHistor = this.transformHistory) !== null && _this$transformHistor !== void 0 && _this$transformHistor.lastTransform && Date.now() - new Date(this.transformHistory.lastTransform.timestamp).getTime() < 5000 ? 'complete' : 'basic';
|
|
826
|
+
console.log("\uD83E\uDD16 updatePathsWithSync(): Auto-selected sync level: ".concat(syncLevel));
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// Perform synchronization based on level
|
|
830
|
+
var syncSuccess = true;
|
|
831
|
+
switch (syncLevel) {
|
|
832
|
+
case 'none':
|
|
833
|
+
console.log('⚡ updatePathsWithSync(): Skipping synchronization for speed');
|
|
834
|
+
break;
|
|
835
|
+
case 'basic':
|
|
836
|
+
console.log('🔄 updatePathsWithSync(): Performing basic scene data synchronization...');
|
|
837
|
+
syncSuccess = this.syncSceneData();
|
|
838
|
+
break;
|
|
839
|
+
case 'complete':
|
|
840
|
+
console.log('🔄 updatePathsWithSync(): Performing complete scene data synchronization...');
|
|
841
|
+
syncSuccess = this.forceSyncSceneData();
|
|
842
|
+
break;
|
|
843
|
+
default:
|
|
844
|
+
console.warn("\u26A0\uFE0F updatePathsWithSync(): Unknown sync level '".concat(syncLevel, "', defaulting to basic"));
|
|
845
|
+
syncSuccess = this.syncSceneData();
|
|
846
|
+
}
|
|
847
|
+
if (!syncSuccess && syncLevel !== 'none') {
|
|
848
|
+
console.warn('⚠️ updatePathsWithSync(): Scene data synchronization failed, proceeding with caution');
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Update paths
|
|
852
|
+
this.sceneViewer.updatePaths();
|
|
853
|
+
console.log("\u2705 updatePathsWithSync(): Paths updated successfully with '".concat(syncLevel, "' synchronization"));
|
|
854
|
+
return true;
|
|
855
|
+
} catch (error) {
|
|
856
|
+
console.error('❌ updatePathsWithSync(): Error updating paths with sync:', error);
|
|
857
|
+
return false;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
598
861
|
/**
|
|
599
862
|
* Add a connection between two connector IDs to the connections list
|
|
600
863
|
* @param {string} fromConnectorId - The UUID of the source connector
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createClass as _createClass, objectSpread2 as _objectSpread2, classCallCheck as _classCallCheck } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
1
|
+
import { createClass as _createClass, objectSpread2 as _objectSpread2, toConsumableArray as _toConsumableArray, classCallCheck as _classCallCheck } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { CentralPlantInternals } from './centralPlantInternals.js';
|
|
4
4
|
import '../rendering/modelPreloader.js';
|
|
@@ -545,8 +545,8 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
545
545
|
* Update paths in the scene
|
|
546
546
|
* @returns {boolean} True if paths were updated successfully, false otherwise
|
|
547
547
|
* @description Triggers an update of all connection paths/pipes in the scene to reflect
|
|
548
|
-
* current component positions and connections. This
|
|
549
|
-
*
|
|
548
|
+
* current component positions and connections. This method ensures all scene data is
|
|
549
|
+
* synchronized before updating paths for guaranteed accuracy.
|
|
550
550
|
* @example
|
|
551
551
|
* // After moving components or changing connections
|
|
552
552
|
* const success = centralPlant.updatePaths();
|
|
@@ -562,8 +562,15 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
562
562
|
return false;
|
|
563
563
|
}
|
|
564
564
|
try {
|
|
565
|
+
// Step 1: Ensure scene data is synchronized before updating paths
|
|
566
|
+
console.log('🔄 updatePaths(): Synchronizing scene data before path update...');
|
|
567
|
+
if (!this.syncSceneData()) {
|
|
568
|
+
console.warn('⚠️ updatePaths(): Scene data synchronization failed, proceeding with caution');
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Step 2: Update paths with synchronized data
|
|
565
572
|
this.sceneViewer.updatePaths();
|
|
566
|
-
console.log('✅ updatePaths(): Paths updated successfully');
|
|
573
|
+
console.log('✅ updatePaths(): Paths updated successfully with synchronized data');
|
|
567
574
|
return true;
|
|
568
575
|
} catch (error) {
|
|
569
576
|
console.error('❌ updatePaths(): Error updating paths:', error);
|
|
@@ -571,6 +578,262 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
571
578
|
}
|
|
572
579
|
}
|
|
573
580
|
|
|
581
|
+
/**
|
|
582
|
+
* Synchronize scene data to ensure all component positions and properties are up-to-date
|
|
583
|
+
* @returns {boolean} True if synchronization was successful, false otherwise
|
|
584
|
+
* @description Updates the currentSceneData to match the actual Three.js scene state.
|
|
585
|
+
* This includes component positions, rotations, scales, and world bounding boxes.
|
|
586
|
+
* Should be called before operations that depend on accurate scene data.
|
|
587
|
+
* @example
|
|
588
|
+
* // Ensure scene data is current before pathfinding
|
|
589
|
+
* const success = centralPlant.syncSceneData();
|
|
590
|
+
* if (success) {
|
|
591
|
+
* console.log('Scene data synchronized with Three.js scene');
|
|
592
|
+
* }
|
|
593
|
+
*/
|
|
594
|
+
}, {
|
|
595
|
+
key: "syncSceneData",
|
|
596
|
+
value: function syncSceneData() {
|
|
597
|
+
var _this = this;
|
|
598
|
+
// Check if scene viewer and currentSceneData are available
|
|
599
|
+
if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
|
|
600
|
+
console.warn('⚠️ syncSceneData(): Scene viewer or current scene data not available');
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
if (!this.sceneViewer.scene) {
|
|
604
|
+
console.warn('⚠️ syncSceneData(): Three.js scene not available');
|
|
605
|
+
return false;
|
|
606
|
+
}
|
|
607
|
+
try {
|
|
608
|
+
console.log('🔄 syncSceneData(): Starting scene data synchronization...');
|
|
609
|
+
|
|
610
|
+
// Get reference to currentSceneData
|
|
611
|
+
var currentSceneData = this.sceneViewer.currentSceneData;
|
|
612
|
+
if (!currentSceneData.scene || !currentSceneData.scene.object || !currentSceneData.scene.object.children) {
|
|
613
|
+
console.warn('⚠️ syncSceneData(): Invalid currentSceneData structure');
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// Update each component in scene data to match Three.js scene
|
|
618
|
+
var updatedCount = 0;
|
|
619
|
+
currentSceneData.scene.object.children.forEach(function (sceneDataChild, index) {
|
|
620
|
+
// Find matching Three.js object
|
|
621
|
+
var matchingThreeObject = null;
|
|
622
|
+
_this.sceneViewer.scene.traverse(function (threeObject) {
|
|
623
|
+
var _sceneDataChild$userD, _threeObject$userData, _threeObject$userData2;
|
|
624
|
+
// Check various UUID matching strategies
|
|
625
|
+
if (threeObject.uuid === sceneDataChild.uuid || threeObject.uuid === ((_sceneDataChild$userD = sceneDataChild.userData) === null || _sceneDataChild$userD === void 0 ? void 0 : _sceneDataChild$userD.originalUuid) || ((_threeObject$userData = threeObject.userData) === null || _threeObject$userData === void 0 ? void 0 : _threeObject$userData.originalUuid) === sceneDataChild.uuid || ((_threeObject$userData2 = threeObject.userData) === null || _threeObject$userData2 === void 0 ? void 0 : _threeObject$userData2.hardcodedUuid) === sceneDataChild.uuid) {
|
|
626
|
+
matchingThreeObject = threeObject;
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
if (matchingThreeObject) {
|
|
630
|
+
// Update position, rotation, and scale
|
|
631
|
+
sceneDataChild.position = {
|
|
632
|
+
x: matchingThreeObject.position.x,
|
|
633
|
+
y: matchingThreeObject.position.y,
|
|
634
|
+
z: matchingThreeObject.position.z
|
|
635
|
+
};
|
|
636
|
+
sceneDataChild.rotation = {
|
|
637
|
+
x: matchingThreeObject.rotation.x,
|
|
638
|
+
y: matchingThreeObject.rotation.y,
|
|
639
|
+
z: matchingThreeObject.rotation.z
|
|
640
|
+
};
|
|
641
|
+
sceneDataChild.scale = {
|
|
642
|
+
x: matchingThreeObject.scale.x,
|
|
643
|
+
y: matchingThreeObject.scale.y,
|
|
644
|
+
z: matchingThreeObject.scale.z
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
// Update matrix
|
|
648
|
+
sceneDataChild.matrix = matchingThreeObject.matrix.elements;
|
|
649
|
+
|
|
650
|
+
// Update world bounding box
|
|
651
|
+
if (matchingThreeObject.isMesh) {
|
|
652
|
+
var boundingBox = new THREE.Box3().setFromObject(matchingThreeObject);
|
|
653
|
+
if (!sceneDataChild.userData) sceneDataChild.userData = {};
|
|
654
|
+
sceneDataChild.userData.worldBoundingBox = {
|
|
655
|
+
min: boundingBox.min.toArray(),
|
|
656
|
+
max: boundingBox.max.toArray()
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Sync children (connectors) if they exist
|
|
661
|
+
if (sceneDataChild.children && matchingThreeObject.children) {
|
|
662
|
+
sceneDataChild.children.forEach(function (sceneChild, childIndex) {
|
|
663
|
+
var matchingChild = matchingThreeObject.children.find(function (threeChild) {
|
|
664
|
+
var _sceneChild$userData, _threeChild$userData;
|
|
665
|
+
return threeChild.uuid === sceneChild.uuid || threeChild.uuid === ((_sceneChild$userData = sceneChild.userData) === null || _sceneChild$userData === void 0 ? void 0 : _sceneChild$userData.originalUuid) || ((_threeChild$userData = threeChild.userData) === null || _threeChild$userData === void 0 ? void 0 : _threeChild$userData.originalUuid) === sceneChild.uuid;
|
|
666
|
+
});
|
|
667
|
+
if (matchingChild) {
|
|
668
|
+
var _matchingChild$userDa;
|
|
669
|
+
// Update child position, rotation, and scale
|
|
670
|
+
sceneChild.position = {
|
|
671
|
+
x: matchingChild.position.x,
|
|
672
|
+
y: matchingChild.position.y,
|
|
673
|
+
z: matchingChild.position.z
|
|
674
|
+
};
|
|
675
|
+
sceneChild.rotation = {
|
|
676
|
+
x: matchingChild.rotation.x,
|
|
677
|
+
y: matchingChild.rotation.y,
|
|
678
|
+
z: matchingChild.rotation.z
|
|
679
|
+
};
|
|
680
|
+
sceneChild.scale = {
|
|
681
|
+
x: matchingChild.scale.x,
|
|
682
|
+
y: matchingChild.scale.y,
|
|
683
|
+
z: matchingChild.scale.z
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
// Update direction vector for connectors
|
|
687
|
+
if ((_matchingChild$userDa = matchingChild.userData) !== null && _matchingChild$userDa !== void 0 && _matchingChild$userDa.direction) {
|
|
688
|
+
if (!sceneChild.userData) sceneChild.userData = {};
|
|
689
|
+
sceneChild.userData.direction = _toConsumableArray(matchingChild.userData.direction);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
updatedCount++;
|
|
695
|
+
} else {
|
|
696
|
+
console.warn("\u26A0\uFE0F syncSceneData(): No matching Three.js object found for scene data child: ".concat(sceneDataChild.uuid));
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
// Force recompute world bounding boxes for pathfinding accuracy
|
|
701
|
+
if (this.sceneViewer.pathfindingManager && typeof this.sceneViewer.pathfindingManager.recomputeWorldBoundingBoxes === 'function') {
|
|
702
|
+
this.sceneViewer.pathfindingManager.recomputeWorldBoundingBoxes(currentSceneData);
|
|
703
|
+
console.log('🔄 syncSceneData(): Recomputed world bounding boxes for pathfinding');
|
|
704
|
+
}
|
|
705
|
+
console.log("\u2705 syncSceneData(): Synchronized ".concat(updatedCount, " components successfully"));
|
|
706
|
+
return true;
|
|
707
|
+
} catch (error) {
|
|
708
|
+
console.error('❌ syncSceneData(): Error synchronizing scene data:', error);
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Force complete scene data synchronization using SceneOperationsManager
|
|
715
|
+
* @returns {boolean} True if forced synchronization was successful, false otherwise
|
|
716
|
+
* @description Uses the SceneOperationsManager's updateSceneDataAfterTransform method
|
|
717
|
+
* to update scene data for every component. This is more thorough than syncSceneData()
|
|
718
|
+
* and should be used when maximum accuracy is required.
|
|
719
|
+
* @example
|
|
720
|
+
* // Force complete synchronization before critical operations
|
|
721
|
+
* const success = centralPlant.forceSyncSceneData();
|
|
722
|
+
* if (success) {
|
|
723
|
+
* console.log('Complete scene data synchronization completed');
|
|
724
|
+
* }
|
|
725
|
+
*/
|
|
726
|
+
}, {
|
|
727
|
+
key: "forceSyncSceneData",
|
|
728
|
+
value: function forceSyncSceneData() {
|
|
729
|
+
var _this2 = this;
|
|
730
|
+
// Check if scene viewer and sceneOperationsManager are available
|
|
731
|
+
if (!this.sceneViewer || !this.sceneViewer.sceneOperationsManager) {
|
|
732
|
+
console.warn('⚠️ forceSyncSceneData(): Scene viewer or scene operations manager not available');
|
|
733
|
+
return false;
|
|
734
|
+
}
|
|
735
|
+
if (!this.sceneViewer.currentSceneData) {
|
|
736
|
+
console.warn('⚠️ forceSyncSceneData(): Current scene data not available');
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
if (!this.sceneViewer.scene) {
|
|
740
|
+
console.warn('⚠️ forceSyncSceneData(): Three.js scene not available');
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
try {
|
|
744
|
+
console.log('🔄 forceSyncSceneData(): Starting forced scene data synchronization...');
|
|
745
|
+
var syncedCount = 0;
|
|
746
|
+
var currentSceneData = this.sceneViewer.currentSceneData;
|
|
747
|
+
|
|
748
|
+
// Traverse all objects in the Three.js scene and update their scene data
|
|
749
|
+
this.sceneViewer.scene.traverse(function (threeObject) {
|
|
750
|
+
// Only sync objects that have component-related userData
|
|
751
|
+
if (threeObject.userData && (threeObject.userData.componentType === 'component' || threeObject.userData.componentType === 'gateway' || threeObject.userData.libraryId)) {
|
|
752
|
+
console.log("\uD83D\uDD04 Syncing object: ".concat(threeObject.uuid, " (").concat(threeObject.userData.componentType || 'unknown', ")"));
|
|
753
|
+
|
|
754
|
+
// Use the existing updateSceneDataAfterTransform method
|
|
755
|
+
var success = _this2.sceneViewer.sceneOperationsManager.updateSceneDataAfterTransform(threeObject, currentSceneData);
|
|
756
|
+
if (success) {
|
|
757
|
+
syncedCount++;
|
|
758
|
+
} else {
|
|
759
|
+
console.warn("\u26A0\uFE0F Failed to sync object: ".concat(threeObject.uuid));
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
console.log("\u2705 forceSyncSceneData(): Force synchronized ".concat(syncedCount, " objects successfully"));
|
|
764
|
+
return true;
|
|
765
|
+
} catch (error) {
|
|
766
|
+
console.error('❌ forceSyncSceneData(): Error during forced scene data synchronization:', error);
|
|
767
|
+
return false;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Update paths with optional scene data synchronization level
|
|
773
|
+
* @param {string} [syncLevel='auto'] - Level of synchronization: 'none', 'basic', 'complete', or 'auto'
|
|
774
|
+
* @returns {boolean} True if paths were updated successfully, false otherwise
|
|
775
|
+
* @description Enhanced updatePaths method that allows choosing the level of scene data
|
|
776
|
+
* synchronization before updating paths. The 'auto' level intelligently chooses based
|
|
777
|
+
* on scene complexity and recent changes.
|
|
778
|
+
* @example
|
|
779
|
+
* // Update paths with automatic synchronization (recommended)
|
|
780
|
+
* centralPlant.updatePathsWithSync('auto');
|
|
781
|
+
*
|
|
782
|
+
* // Update paths with complete synchronization (most accurate)
|
|
783
|
+
* centralPlant.updatePathsWithSync('complete');
|
|
784
|
+
*
|
|
785
|
+
* // Update paths without synchronization (fastest)
|
|
786
|
+
* centralPlant.updatePathsWithSync('none');
|
|
787
|
+
*/
|
|
788
|
+
}, {
|
|
789
|
+
key: "updatePathsWithSync",
|
|
790
|
+
value: function updatePathsWithSync() {
|
|
791
|
+
var syncLevel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'auto';
|
|
792
|
+
if (!this.sceneViewer || !this.sceneViewer.updatePaths) {
|
|
793
|
+
console.warn('⚠️ updatePathsWithSync(): Scene viewer or updatePaths method not available');
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
try {
|
|
797
|
+
// Determine sync level automatically if needed
|
|
798
|
+
if (syncLevel === 'auto') {
|
|
799
|
+
var _this$transformHistor;
|
|
800
|
+
// Use basic sync by default, but upgrade to complete if recent transforms detected
|
|
801
|
+
syncLevel = (_this$transformHistor = this.transformHistory) !== null && _this$transformHistor !== void 0 && _this$transformHistor.lastTransform && Date.now() - new Date(this.transformHistory.lastTransform.timestamp).getTime() < 5000 ? 'complete' : 'basic';
|
|
802
|
+
console.log("\uD83E\uDD16 updatePathsWithSync(): Auto-selected sync level: ".concat(syncLevel));
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// Perform synchronization based on level
|
|
806
|
+
var syncSuccess = true;
|
|
807
|
+
switch (syncLevel) {
|
|
808
|
+
case 'none':
|
|
809
|
+
console.log('⚡ updatePathsWithSync(): Skipping synchronization for speed');
|
|
810
|
+
break;
|
|
811
|
+
case 'basic':
|
|
812
|
+
console.log('🔄 updatePathsWithSync(): Performing basic scene data synchronization...');
|
|
813
|
+
syncSuccess = this.syncSceneData();
|
|
814
|
+
break;
|
|
815
|
+
case 'complete':
|
|
816
|
+
console.log('🔄 updatePathsWithSync(): Performing complete scene data synchronization...');
|
|
817
|
+
syncSuccess = this.forceSyncSceneData();
|
|
818
|
+
break;
|
|
819
|
+
default:
|
|
820
|
+
console.warn("\u26A0\uFE0F updatePathsWithSync(): Unknown sync level '".concat(syncLevel, "', defaulting to basic"));
|
|
821
|
+
syncSuccess = this.syncSceneData();
|
|
822
|
+
}
|
|
823
|
+
if (!syncSuccess && syncLevel !== 'none') {
|
|
824
|
+
console.warn('⚠️ updatePathsWithSync(): Scene data synchronization failed, proceeding with caution');
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// Update paths
|
|
828
|
+
this.sceneViewer.updatePaths();
|
|
829
|
+
console.log("\u2705 updatePathsWithSync(): Paths updated successfully with '".concat(syncLevel, "' synchronization"));
|
|
830
|
+
return true;
|
|
831
|
+
} catch (error) {
|
|
832
|
+
console.error('❌ updatePathsWithSync(): Error updating paths with sync:', error);
|
|
833
|
+
return false;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
574
837
|
/**
|
|
575
838
|
* Add a connection between two connector IDs to the connections list
|
|
576
839
|
* @param {string} fromConnectorId - The UUID of the source connector
|