@2112-lab/central-plant 0.1.19 → 0.1.21
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 +724 -6
- package/dist/cjs/src/core/centralPlant.js +630 -0
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +115 -6
- package/dist/esm/src/core/centralPlant.js +610 -0
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +115 -6
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -21447,7 +21447,7 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
21447
21447
|
case 0:
|
|
21448
21448
|
component = this.sceneViewer;
|
|
21449
21449
|
_context6.p = 1;
|
|
21450
|
-
defaultCentralPlantUrl =
|
|
21450
|
+
defaultCentralPlantUrl = process.env.DEFAULT_CENTRAL_PLANT_URL;
|
|
21451
21451
|
_context6.n = 2;
|
|
21452
21452
|
return fetch(defaultCentralPlantUrl);
|
|
21453
21453
|
case 2:
|
|
@@ -21600,6 +21600,115 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
21600
21600
|
});
|
|
21601
21601
|
}
|
|
21602
21602
|
|
|
21603
|
+
/**
|
|
21604
|
+
* Add a new component to the scene data
|
|
21605
|
+
* @param {Object} componentModel - The Three.js component model that was added to the scene
|
|
21606
|
+
* @param {Object} currentSceneData - The current scene data structure
|
|
21607
|
+
* @returns {boolean} True if the component was successfully added to scene data
|
|
21608
|
+
*/
|
|
21609
|
+
}, {
|
|
21610
|
+
key: "addComponentToSceneData",
|
|
21611
|
+
value: function addComponentToSceneData(componentModel, currentSceneData) {
|
|
21612
|
+
if (!componentModel || !currentSceneData) {
|
|
21613
|
+
console.error('❌ addComponentToSceneData: Missing componentModel or currentSceneData');
|
|
21614
|
+
return false;
|
|
21615
|
+
}
|
|
21616
|
+
if (!currentSceneData.scene || !currentSceneData.scene.object) {
|
|
21617
|
+
console.error('❌ addComponentToSceneData: Invalid scene data structure');
|
|
21618
|
+
return false;
|
|
21619
|
+
}
|
|
21620
|
+
try {
|
|
21621
|
+
var _componentModel$userD;
|
|
21622
|
+
// Calculate world bounding box for the component
|
|
21623
|
+
var boundingBox = new THREE__namespace.Box3().setFromObject(componentModel);
|
|
21624
|
+
|
|
21625
|
+
// Create scene data entry for the new component
|
|
21626
|
+
var componentSceneData = {
|
|
21627
|
+
uuid: componentModel.uuid,
|
|
21628
|
+
name: componentModel.name,
|
|
21629
|
+
type: 'Group',
|
|
21630
|
+
matrix: componentModel.matrix.elements,
|
|
21631
|
+
position: {
|
|
21632
|
+
x: componentModel.position.x,
|
|
21633
|
+
y: componentModel.position.y,
|
|
21634
|
+
z: componentModel.position.z
|
|
21635
|
+
},
|
|
21636
|
+
rotation: {
|
|
21637
|
+
x: componentModel.rotation.x,
|
|
21638
|
+
y: componentModel.rotation.y,
|
|
21639
|
+
z: componentModel.rotation.z
|
|
21640
|
+
},
|
|
21641
|
+
scale: {
|
|
21642
|
+
x: componentModel.scale.x,
|
|
21643
|
+
y: componentModel.scale.y,
|
|
21644
|
+
z: componentModel.scale.z
|
|
21645
|
+
},
|
|
21646
|
+
userData: _objectSpread2(_objectSpread2({}, componentModel.userData), {}, {
|
|
21647
|
+
worldBoundingBox: {
|
|
21648
|
+
min: boundingBox.min.toArray(),
|
|
21649
|
+
max: boundingBox.max.toArray()
|
|
21650
|
+
}
|
|
21651
|
+
}),
|
|
21652
|
+
children: []
|
|
21653
|
+
};
|
|
21654
|
+
|
|
21655
|
+
// Process children (connectors, etc.) if they exist
|
|
21656
|
+
if (componentModel.children && componentModel.children.length > 0) {
|
|
21657
|
+
componentModel.children.forEach(function (child) {
|
|
21658
|
+
var _child$userData17;
|
|
21659
|
+
if (((_child$userData17 = child.userData) === null || _child$userData17 === void 0 ? void 0 : _child$userData17.componentType) === 'connector') {
|
|
21660
|
+
var _child$geometry5;
|
|
21661
|
+
var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
|
|
21662
|
+
var childSceneData = {
|
|
21663
|
+
uuid: child.uuid,
|
|
21664
|
+
name: child.name,
|
|
21665
|
+
type: child.type,
|
|
21666
|
+
position: {
|
|
21667
|
+
x: child.position.x,
|
|
21668
|
+
y: child.position.y,
|
|
21669
|
+
z: child.position.z
|
|
21670
|
+
},
|
|
21671
|
+
rotation: {
|
|
21672
|
+
x: child.rotation.x,
|
|
21673
|
+
y: child.rotation.y,
|
|
21674
|
+
z: child.rotation.z
|
|
21675
|
+
},
|
|
21676
|
+
scale: {
|
|
21677
|
+
x: child.scale.x,
|
|
21678
|
+
y: child.scale.y,
|
|
21679
|
+
z: child.scale.z
|
|
21680
|
+
},
|
|
21681
|
+
userData: _objectSpread2(_objectSpread2({}, child.userData), {}, {
|
|
21682
|
+
worldBoundingBox: {
|
|
21683
|
+
min: childBoundingBox.min.toArray(),
|
|
21684
|
+
max: childBoundingBox.max.toArray()
|
|
21685
|
+
}
|
|
21686
|
+
}),
|
|
21687
|
+
geometry: ((_child$geometry5 = child.geometry) === null || _child$geometry5 === void 0 ? void 0 : _child$geometry5.uuid) || 'CONNECTOR-GEO'
|
|
21688
|
+
};
|
|
21689
|
+
componentSceneData.children.push(childSceneData);
|
|
21690
|
+
}
|
|
21691
|
+
});
|
|
21692
|
+
}
|
|
21693
|
+
|
|
21694
|
+
// Add the component to the scene data
|
|
21695
|
+
if (!currentSceneData.scene.object.children) {
|
|
21696
|
+
currentSceneData.scene.object.children = [];
|
|
21697
|
+
}
|
|
21698
|
+
currentSceneData.scene.object.children.push(componentSceneData);
|
|
21699
|
+
console.log('✅ addComponentToSceneData: Component added to scene data successfully', {
|
|
21700
|
+
componentId: componentModel.uuid,
|
|
21701
|
+
libraryId: (_componentModel$userD = componentModel.userData) === null || _componentModel$userD === void 0 ? void 0 : _componentModel$userD.libraryId,
|
|
21702
|
+
childrenCount: componentSceneData.children.length,
|
|
21703
|
+
totalSceneChildren: currentSceneData.scene.object.children.length
|
|
21704
|
+
});
|
|
21705
|
+
return true;
|
|
21706
|
+
} catch (error) {
|
|
21707
|
+
console.error('❌ addComponentToSceneData: Error adding component to scene data:', error);
|
|
21708
|
+
return false;
|
|
21709
|
+
}
|
|
21710
|
+
}
|
|
21711
|
+
|
|
21603
21712
|
/**
|
|
21604
21713
|
* Update scene data after object transform
|
|
21605
21714
|
*/
|
|
@@ -21621,9 +21730,9 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
21621
21730
|
|
|
21622
21731
|
// Also update the corresponding scene data object
|
|
21623
21732
|
for (var i = 0; i < currentSceneData.scene.object.children.length; i++) {
|
|
21624
|
-
var _object$userData4, _child$
|
|
21733
|
+
var _object$userData4, _child$userData18;
|
|
21625
21734
|
var child = currentSceneData.scene.object.children[i];
|
|
21626
|
-
if (child.uuid === object.uuid || child.uuid === ((_object$userData4 = object.userData) === null || _object$userData4 === void 0 ? void 0 : _object$userData4.originalUuid) || object.uuid === ((_child$
|
|
21735
|
+
if (child.uuid === object.uuid || child.uuid === ((_object$userData4 = object.userData) === null || _object$userData4 === void 0 ? void 0 : _object$userData4.originalUuid) || object.uuid === ((_child$userData18 = child.userData) === null || _child$userData18 === void 0 ? void 0 : _child$userData18.originalUuid)) {
|
|
21627
21736
|
if (!child.userData) child.userData = {};
|
|
21628
21737
|
child.userData.origin = 'declared';
|
|
21629
21738
|
break;
|
|
@@ -21672,20 +21781,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
21672
21781
|
|
|
21673
21782
|
// Update the corresponding child in currentSceneData with the transformed object
|
|
21674
21783
|
var _loop = function _loop() {
|
|
21675
|
-
var _object$userData6, _child$
|
|
21784
|
+
var _object$userData6, _child$userData19, _object$userData7, _child$userData20;
|
|
21676
21785
|
var child = currentSceneData.scene.object.children[_i2];
|
|
21677
21786
|
console.log("onTransformEnd child.uuid:", child.uuid);
|
|
21678
21787
|
// Enhanced matching logic with hardcoded UUID priority
|
|
21679
21788
|
var isMatch = false;
|
|
21680
21789
|
|
|
21681
21790
|
// Strategy 1: Direct hardcoded UUID match (HIGHEST PRIORITY)
|
|
21682
|
-
if (child.uuid === object.uuid || child.uuid === ((_object$userData6 = object.userData) === null || _object$userData6 === void 0 ? void 0 : _object$userData6.originalUuid) || object.uuid === ((_child$
|
|
21791
|
+
if (child.uuid === object.uuid || child.uuid === ((_object$userData6 = object.userData) === null || _object$userData6 === void 0 ? void 0 : _object$userData6.originalUuid) || object.uuid === ((_child$userData19 = child.userData) === null || _child$userData19 === void 0 ? void 0 : _child$userData19.originalUuid)) {
|
|
21683
21792
|
isMatch = true;
|
|
21684
21793
|
console.log('🎯 Matched by hardcoded UUID');
|
|
21685
21794
|
}
|
|
21686
21795
|
|
|
21687
21796
|
// Strategy 4: Component type and library ID match
|
|
21688
|
-
if (!isMatch && (_object$userData7 = object.userData) !== null && _object$userData7 !== void 0 && _object$userData7.libraryId && (_child$
|
|
21797
|
+
if (!isMatch && (_object$userData7 = object.userData) !== null && _object$userData7 !== void 0 && _object$userData7.libraryId && (_child$userData20 = child.userData) !== null && _child$userData20 !== void 0 && _child$userData20.libraryId && object.userData.libraryId === child.userData.libraryId) {
|
|
21689
21798
|
// For library components, also check position similarity
|
|
21690
21799
|
var positionTolerance = 1.0; // Larger tolerance for main components
|
|
21691
21800
|
if (child.position && object.position) {
|
|
@@ -26482,6 +26591,615 @@ var CentralPlant = /*#__PURE__*/function () {
|
|
|
26482
26591
|
value: function getUtility(utilityName) {
|
|
26483
26592
|
return this.utilities[utilityName] || null;
|
|
26484
26593
|
}
|
|
26594
|
+
|
|
26595
|
+
/**
|
|
26596
|
+
* Translate a component by a specified value along a given axis
|
|
26597
|
+
* @param {string} componentId - The UUID or identifier of the component to translate
|
|
26598
|
+
* @param {string} axis - The axis to translate along ('x', 'y', or 'z')
|
|
26599
|
+
* @param {number} value - The value to translate by (can be positive or negative)
|
|
26600
|
+
* @returns {Object|false} The component object if translation was successful, false otherwise
|
|
26601
|
+
*/
|
|
26602
|
+
}, {
|
|
26603
|
+
key: "translate",
|
|
26604
|
+
value: function translate(componentId, axis, value) {
|
|
26605
|
+
// Validate input parameters
|
|
26606
|
+
if (!componentId || typeof componentId !== 'string') {
|
|
26607
|
+
console.error('❌ translate(): Invalid componentId provided:', componentId);
|
|
26608
|
+
return false;
|
|
26609
|
+
}
|
|
26610
|
+
if (!['x', 'y', 'z'].includes(axis.toLowerCase())) {
|
|
26611
|
+
console.error('❌ translate(): Invalid axis provided. Must be "x", "y", or "z":', axis);
|
|
26612
|
+
return false;
|
|
26613
|
+
}
|
|
26614
|
+
if (typeof value !== 'number' || isNaN(value)) {
|
|
26615
|
+
console.error('❌ translate(): Invalid value provided. Must be a number:', value);
|
|
26616
|
+
return false;
|
|
26617
|
+
}
|
|
26618
|
+
|
|
26619
|
+
// Check if scene viewer is available
|
|
26620
|
+
if (!this.sceneViewer || !this.sceneViewer.scene) {
|
|
26621
|
+
console.error('❌ translate(): Scene viewer or scene not available');
|
|
26622
|
+
return false;
|
|
26623
|
+
}
|
|
26624
|
+
|
|
26625
|
+
// Find the component in the scene
|
|
26626
|
+
var component = this.utilities.findObjectByHardcodedUuid(this.sceneViewer.scene, componentId);
|
|
26627
|
+
if (!component) {
|
|
26628
|
+
console.error("\u274C translate(): Component not found with ID: ".concat(componentId));
|
|
26629
|
+
return false;
|
|
26630
|
+
}
|
|
26631
|
+
|
|
26632
|
+
// Verify this is a valid component that can be translated
|
|
26633
|
+
if (!component.userData || !component.userData.componentType) {
|
|
26634
|
+
console.warn("\u26A0\uFE0F translate(): Object found but may not be a valid component: ".concat(componentId));
|
|
26635
|
+
}
|
|
26636
|
+
|
|
26637
|
+
// Store previous transform values for undo functionality
|
|
26638
|
+
var previousValues = {
|
|
26639
|
+
position: component.position.clone(),
|
|
26640
|
+
rotation: component.rotation.clone(),
|
|
26641
|
+
scale: component.scale.clone()
|
|
26642
|
+
};
|
|
26643
|
+
|
|
26644
|
+
// Perform the translation
|
|
26645
|
+
var normalizedAxis = axis.toLowerCase();
|
|
26646
|
+
var previousPosition = component.position[normalizedAxis];
|
|
26647
|
+
try {
|
|
26648
|
+
// Apply the translation
|
|
26649
|
+
component.position[normalizedAxis] += value;
|
|
26650
|
+
|
|
26651
|
+
// Force update the component's matrices
|
|
26652
|
+
component.updateMatrix();
|
|
26653
|
+
component.updateMatrixWorld(true);
|
|
26654
|
+
|
|
26655
|
+
// Update world bounding box if the component has an associated JSON object
|
|
26656
|
+
if (component.userData.associatedJsonObject) {
|
|
26657
|
+
var worldBoundingBox = new THREE__namespace.Box3().setFromObject(component);
|
|
26658
|
+
component.userData.associatedJsonObject.userData.worldBoundingBox = {
|
|
26659
|
+
min: worldBoundingBox.min.toArray(),
|
|
26660
|
+
max: worldBoundingBox.max.toArray()
|
|
26661
|
+
};
|
|
26662
|
+
}
|
|
26663
|
+
|
|
26664
|
+
// Record this transform operation in history
|
|
26665
|
+
this.recordTransform({
|
|
26666
|
+
type: 'translate',
|
|
26667
|
+
object: component,
|
|
26668
|
+
values: {
|
|
26669
|
+
position: component.position.clone(),
|
|
26670
|
+
rotation: component.rotation.clone(),
|
|
26671
|
+
scale: component.scale.clone()
|
|
26672
|
+
},
|
|
26673
|
+
previousValues: previousValues,
|
|
26674
|
+
axis: normalizedAxis,
|
|
26675
|
+
translationValue: value
|
|
26676
|
+
});
|
|
26677
|
+
|
|
26678
|
+
// Emit transform event if the scene viewer supports it
|
|
26679
|
+
if (this.sceneViewer.emit && typeof this.sceneViewer.emit === 'function') {
|
|
26680
|
+
this.sceneViewer.emit('transform-update', {
|
|
26681
|
+
componentId: componentId,
|
|
26682
|
+
component: component,
|
|
26683
|
+
type: 'translate',
|
|
26684
|
+
axis: normalizedAxis,
|
|
26685
|
+
value: value,
|
|
26686
|
+
newPosition: {
|
|
26687
|
+
x: component.position.x,
|
|
26688
|
+
y: component.position.y,
|
|
26689
|
+
z: component.position.z
|
|
26690
|
+
}
|
|
26691
|
+
});
|
|
26692
|
+
this.sceneViewer.emit('scene-changed', {
|
|
26693
|
+
action: 'translate',
|
|
26694
|
+
componentId: componentId,
|
|
26695
|
+
axis: normalizedAxis,
|
|
26696
|
+
value: value
|
|
26697
|
+
});
|
|
26698
|
+
}
|
|
26699
|
+
|
|
26700
|
+
// If there's a scene operations manager, update scene data
|
|
26701
|
+
if (this.sceneViewer.sceneOperationsManager && this.sceneViewer.currentSceneData) {
|
|
26702
|
+
this.sceneViewer.sceneOperationsManager.updateSceneDataAfterTransform(component, this.sceneViewer.currentSceneData);
|
|
26703
|
+
}
|
|
26704
|
+
|
|
26705
|
+
// if (this.sceneViewer.shouldUpdatePaths && this.sceneViewer.updatePaths) {
|
|
26706
|
+
// this.sceneViewer.updatePaths()
|
|
26707
|
+
// }
|
|
26708
|
+
|
|
26709
|
+
// // Update scene data and paths after successful translation
|
|
26710
|
+
// this.updatePaths(component)
|
|
26711
|
+
|
|
26712
|
+
// Log successful translation
|
|
26713
|
+
console.log("\u2705 translate(): Component ".concat(componentId, " translated ").concat(value, " units along ").concat(normalizedAxis.toUpperCase(), "-axis"), {
|
|
26714
|
+
componentId: componentId,
|
|
26715
|
+
axis: normalizedAxis,
|
|
26716
|
+
value: value,
|
|
26717
|
+
previousPosition: previousPosition,
|
|
26718
|
+
newPosition: component.position[normalizedAxis],
|
|
26719
|
+
totalPosition: {
|
|
26720
|
+
x: component.position.x.toFixed(3),
|
|
26721
|
+
y: component.position.y.toFixed(3),
|
|
26722
|
+
z: component.position.z.toFixed(3)
|
|
26723
|
+
}
|
|
26724
|
+
});
|
|
26725
|
+
return component;
|
|
26726
|
+
} catch (error) {
|
|
26727
|
+
console.error("\u274C translate(): Error translating component ".concat(componentId, ":"), error);
|
|
26728
|
+
|
|
26729
|
+
// Attempt to restore previous position on error
|
|
26730
|
+
try {
|
|
26731
|
+
component.position.copy(previousValues.position);
|
|
26732
|
+
component.updateMatrix();
|
|
26733
|
+
component.updateMatrixWorld(true);
|
|
26734
|
+
console.log('🔄 translate(): Restored previous position after error');
|
|
26735
|
+
} catch (restoreError) {
|
|
26736
|
+
console.error('❌ translate(): Failed to restore previous position:', restoreError);
|
|
26737
|
+
}
|
|
26738
|
+
return false;
|
|
26739
|
+
}
|
|
26740
|
+
}
|
|
26741
|
+
|
|
26742
|
+
/**
|
|
26743
|
+
* Add a new component to the scene using its library ID
|
|
26744
|
+
* @param {string} libraryId - The library identifier for the component type (e.g., 'PUMP', 'CHILLER', 'COOLING-TOWER')
|
|
26745
|
+
* @param {Object} options - Optional configuration for the new component
|
|
26746
|
+
* @param {Object} options.position - Initial position for the component (default: random position within scene bounds)
|
|
26747
|
+
* @param {Object} options.rotation - Initial rotation for the component (default: no rotation)
|
|
26748
|
+
* @param {Object} options.scale - Initial scale for the component (default: 1.0 on all axes)
|
|
26749
|
+
* @param {string} options.customId - Custom identifier for the component (default: auto-generated UUID)
|
|
26750
|
+
* @returns {Object|false} The added component object if successful, false otherwise
|
|
26751
|
+
*/
|
|
26752
|
+
}, {
|
|
26753
|
+
key: "addComponent",
|
|
26754
|
+
value: function addComponent(libraryId) {
|
|
26755
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
26756
|
+
// Validate input parameters
|
|
26757
|
+
if (!libraryId || typeof libraryId !== 'string') {
|
|
26758
|
+
console.error('❌ addComponent(): Invalid library ID provided. Must be a non-empty string.');
|
|
26759
|
+
return false;
|
|
26760
|
+
}
|
|
26761
|
+
|
|
26762
|
+
// Check if scene viewer is available
|
|
26763
|
+
if (!this.sceneViewer || !this.sceneViewer.scene) {
|
|
26764
|
+
console.error('❌ addComponent(): Scene viewer or scene not available');
|
|
26765
|
+
return false;
|
|
26766
|
+
}
|
|
26767
|
+
|
|
26768
|
+
// Check if component manager is available
|
|
26769
|
+
var componentManager = this.sceneViewer.componentManager;
|
|
26770
|
+
if (!componentManager) {
|
|
26771
|
+
console.error('❌ addComponent(): Component manager not available');
|
|
26772
|
+
return false;
|
|
26773
|
+
}
|
|
26774
|
+
|
|
26775
|
+
// Check if model preloader is available
|
|
26776
|
+
var modelPreloader = this.utilities.modelPreloader;
|
|
26777
|
+
if (!modelPreloader) {
|
|
26778
|
+
console.error('❌ addComponent(): Model preloader not available');
|
|
26779
|
+
return false;
|
|
26780
|
+
}
|
|
26781
|
+
try {
|
|
26782
|
+
// Generate a unique component ID if not provided
|
|
26783
|
+
var componentId = options.customId || this.utilities.generateUuidFromName(libraryId + '_' + Date.now());
|
|
26784
|
+
|
|
26785
|
+
// Set default position within scene boundaries if not provided
|
|
26786
|
+
var position = options.position || {
|
|
26787
|
+
x: 0,
|
|
26788
|
+
y: 0,
|
|
26789
|
+
z: 0
|
|
26790
|
+
};
|
|
26791
|
+
|
|
26792
|
+
// Set default rotation if not provided
|
|
26793
|
+
var rotation = options.rotation || {
|
|
26794
|
+
x: 0,
|
|
26795
|
+
y: 0,
|
|
26796
|
+
z: 0
|
|
26797
|
+
};
|
|
26798
|
+
console.log("\uD83D\uDD04 addComponent(): Adding component ".concat(libraryId, " at position:"), position);
|
|
26799
|
+
|
|
26800
|
+
// Get the component data from the preloader's component dictionary
|
|
26801
|
+
if (!modelPreloader.componentDictionary) {
|
|
26802
|
+
console.error("\u274C addComponent(): Component dictionary not available in model preloader");
|
|
26803
|
+
return false;
|
|
26804
|
+
}
|
|
26805
|
+
var componentData = modelPreloader.componentDictionary[libraryId];
|
|
26806
|
+
if (!componentData || !componentData.modelKey) {
|
|
26807
|
+
console.error("\u274C addComponent(): Component data not found for library ID '".concat(libraryId, "'. Available components:"), Object.keys(modelPreloader.componentDictionary));
|
|
26808
|
+
return false;
|
|
26809
|
+
}
|
|
26810
|
+
|
|
26811
|
+
// Get the cached model using the modelKey
|
|
26812
|
+
var cachedModel = modelPreloader.getCachedModelWithDimensions(componentData.modelKey, libraryId);
|
|
26813
|
+
if (!cachedModel) {
|
|
26814
|
+
var status = modelPreloader.getStatus();
|
|
26815
|
+
console.error("\u274C addComponent(): Model for library ID '".concat(libraryId, "' (modelKey: '").concat(componentData.modelKey, "') not found in cache. Cache status:"), {
|
|
26816
|
+
cachedModels: status.cachedModels,
|
|
26817
|
+
totalCached: status.totalCached,
|
|
26818
|
+
isPreloading: status.isPreloading,
|
|
26819
|
+
currentlyLoading: status.currentlyLoading
|
|
26820
|
+
});
|
|
26821
|
+
return false;
|
|
26822
|
+
}
|
|
26823
|
+
|
|
26824
|
+
// Clone the cached model to create a new instance
|
|
26825
|
+
var componentModel = cachedModel;
|
|
26826
|
+
|
|
26827
|
+
// Set the component properties
|
|
26828
|
+
componentModel.uuid = componentId;
|
|
26829
|
+
componentModel.name = libraryId + '_' + componentId.substring(0, 8);
|
|
26830
|
+
|
|
26831
|
+
// Set position and rotation
|
|
26832
|
+
componentModel.position.set(position.x, position.y, position.z);
|
|
26833
|
+
componentModel.rotation.set(rotation.x, rotation.y, rotation.z);
|
|
26834
|
+
|
|
26835
|
+
// Set up component metadata
|
|
26836
|
+
componentModel.userData = {
|
|
26837
|
+
componentType: 'component',
|
|
26838
|
+
libraryId: libraryId,
|
|
26839
|
+
originalUuid: componentId,
|
|
26840
|
+
hardcodedUuid: componentId,
|
|
26841
|
+
addedTimestamp: new Date().toISOString(),
|
|
26842
|
+
addedBy: 'centralPlant.addComponent()',
|
|
26843
|
+
isUserAdded: true,
|
|
26844
|
+
initialPosition: _objectSpread2({}, position),
|
|
26845
|
+
initialRotation: _objectSpread2({}, rotation)
|
|
26846
|
+
};
|
|
26847
|
+
|
|
26848
|
+
// Add the component to the scene
|
|
26849
|
+
this.sceneViewer.scene.add(componentModel);
|
|
26850
|
+
|
|
26851
|
+
// Update matrices to ensure proper positioning
|
|
26852
|
+
componentModel.updateMatrix();
|
|
26853
|
+
componentModel.updateMatrixWorld(true);
|
|
26854
|
+
|
|
26855
|
+
// Add children connectors from component dictionary
|
|
26856
|
+
if (componentData.children && Array.isArray(componentData.children)) {
|
|
26857
|
+
console.log("\uD83D\uDD0C addComponent(): Adding ".concat(componentData.children.length, " connectors for ").concat(libraryId));
|
|
26858
|
+
componentData.children.forEach(function (childData, index) {
|
|
26859
|
+
try {
|
|
26860
|
+
var _childData$userData, _childData$userData2, _childData$userData3;
|
|
26861
|
+
// Create connector geometry (simple sphere for now)
|
|
26862
|
+
var connectorGeometry = new THREE__namespace.SphereGeometry(0.1, 8, 6);
|
|
26863
|
+
var connectorMaterial = new THREE__namespace.MeshPhysicalMaterial({
|
|
26864
|
+
color: 0xC0C0C0,
|
|
26865
|
+
roughness: 0.15,
|
|
26866
|
+
metalness: 0.9,
|
|
26867
|
+
emissive: 0x000000,
|
|
26868
|
+
envMapIntensity: 1.5,
|
|
26869
|
+
transparent: true,
|
|
26870
|
+
opacity: 0.8
|
|
26871
|
+
});
|
|
26872
|
+
|
|
26873
|
+
// Create connector mesh
|
|
26874
|
+
var connectorMesh = new THREE__namespace.Mesh(connectorGeometry, connectorMaterial);
|
|
26875
|
+
|
|
26876
|
+
// Set connector properties from child data
|
|
26877
|
+
if (childData.uuid) {
|
|
26878
|
+
connectorMesh.uuid = "".concat(componentId, "_").concat(childData.uuid);
|
|
26879
|
+
}
|
|
26880
|
+
connectorMesh.name = "".concat(libraryId, "_connector_").concat(index);
|
|
26881
|
+
|
|
26882
|
+
// Set connector position relative to component
|
|
26883
|
+
if (childData.position) {
|
|
26884
|
+
connectorMesh.position.set(childData.position.x || 0, childData.position.y || 0, childData.position.z || 0);
|
|
26885
|
+
}
|
|
26886
|
+
|
|
26887
|
+
// Set connector user data
|
|
26888
|
+
connectorMesh.userData = {
|
|
26889
|
+
componentType: 'connector',
|
|
26890
|
+
parentComponentId: componentId,
|
|
26891
|
+
connectorIndex: index,
|
|
26892
|
+
direction: ((_childData$userData = childData.userData) === null || _childData$userData === void 0 ? void 0 : _childData$userData.direction) || [0, 1, 0],
|
|
26893
|
+
group: ((_childData$userData2 = childData.userData) === null || _childData$userData2 === void 0 ? void 0 : _childData$userData2.group) || null,
|
|
26894
|
+
forExport: ((_childData$userData3 = childData.userData) === null || _childData$userData3 === void 0 ? void 0 : _childData$userData3.forExport) || false,
|
|
26895
|
+
originalChildData: childData
|
|
26896
|
+
};
|
|
26897
|
+
|
|
26898
|
+
// Add connector as child of the component
|
|
26899
|
+
componentModel.add(connectorMesh);
|
|
26900
|
+
console.log("\u2705 Added connector ".concat(index, " to component ").concat(libraryId, ":"), {
|
|
26901
|
+
uuid: connectorMesh.uuid,
|
|
26902
|
+
position: connectorMesh.position,
|
|
26903
|
+
direction: connectorMesh.userData.direction,
|
|
26904
|
+
group: connectorMesh.userData.group
|
|
26905
|
+
});
|
|
26906
|
+
} catch (connectorError) {
|
|
26907
|
+
console.error("\u274C Error creating connector ".concat(index, " for ").concat(libraryId, ":"), connectorError);
|
|
26908
|
+
}
|
|
26909
|
+
});
|
|
26910
|
+
}
|
|
26911
|
+
|
|
26912
|
+
// Notify the component manager about the new component
|
|
26913
|
+
if (componentManager.registerComponent) {
|
|
26914
|
+
componentManager.registerComponent(componentModel);
|
|
26915
|
+
}
|
|
26916
|
+
|
|
26917
|
+
// Update scene data if available
|
|
26918
|
+
if (this.sceneViewer.sceneOperationsManager && this.sceneViewer.currentSceneData) {
|
|
26919
|
+
var success = this.sceneViewer.sceneOperationsManager.addComponentToSceneData(componentModel, this.sceneViewer.currentSceneData);
|
|
26920
|
+
if (success) {
|
|
26921
|
+
console.log('✅ Component successfully added to scene data');
|
|
26922
|
+
} else {
|
|
26923
|
+
console.warn('⚠️ Failed to add component to scene data');
|
|
26924
|
+
}
|
|
26925
|
+
}
|
|
26926
|
+
|
|
26927
|
+
// Record the add operation in metadata
|
|
26928
|
+
this.recordComponentAddition(componentModel, libraryId, options);
|
|
26929
|
+
|
|
26930
|
+
// Log successful addition
|
|
26931
|
+
console.log("\u2705 addComponent(): Component ".concat(libraryId, " added successfully"), componentModel);
|
|
26932
|
+
return componentModel;
|
|
26933
|
+
} catch (error) {
|
|
26934
|
+
console.error("\u274C addComponent(): Error adding component ".concat(libraryId, ":"), error);
|
|
26935
|
+
return false;
|
|
26936
|
+
}
|
|
26937
|
+
}
|
|
26938
|
+
|
|
26939
|
+
/**
|
|
26940
|
+
* Record component addition in metadata for tracking and potential undo
|
|
26941
|
+
* @param {Object} component - The added component
|
|
26942
|
+
* @param {string} libraryId - The library ID used
|
|
26943
|
+
* @param {Object} options - The options used for addition
|
|
26944
|
+
*/
|
|
26945
|
+
}, {
|
|
26946
|
+
key: "recordComponentAddition",
|
|
26947
|
+
value: function recordComponentAddition(component, libraryId, options) {
|
|
26948
|
+
// Get existing addition history or create new array
|
|
26949
|
+
var additionHistory = this.getMetadata('componentAdditionHistory') || [];
|
|
26950
|
+
var additionRecord = {
|
|
26951
|
+
componentId: component.uuid,
|
|
26952
|
+
libraryId: libraryId,
|
|
26953
|
+
position: {
|
|
26954
|
+
x: component.position.x,
|
|
26955
|
+
y: component.position.y,
|
|
26956
|
+
z: component.position.z
|
|
26957
|
+
},
|
|
26958
|
+
rotation: {
|
|
26959
|
+
x: component.rotation.x,
|
|
26960
|
+
y: component.rotation.y,
|
|
26961
|
+
z: component.rotation.z
|
|
26962
|
+
},
|
|
26963
|
+
scale: {
|
|
26964
|
+
x: component.scale.x,
|
|
26965
|
+
y: component.scale.y,
|
|
26966
|
+
z: component.scale.z
|
|
26967
|
+
},
|
|
26968
|
+
options: options,
|
|
26969
|
+
timestamp: new Date().toISOString(),
|
|
26970
|
+
sessionId: this.getMetadata('sessionId') || 'unknown'
|
|
26971
|
+
};
|
|
26972
|
+
|
|
26973
|
+
// Add to history (keep only last 50 additions to prevent memory issues)
|
|
26974
|
+
additionHistory.push(additionRecord);
|
|
26975
|
+
if (additionHistory.length > 50) {
|
|
26976
|
+
additionHistory.shift(); // Remove oldest entry
|
|
26977
|
+
}
|
|
26978
|
+
|
|
26979
|
+
// Update metadata
|
|
26980
|
+
this.setMetadata('componentAdditionHistory', additionHistory);
|
|
26981
|
+
this.setMetadata('lastComponentAddition', additionRecord);
|
|
26982
|
+
console.log('📝 Component addition recorded in metadata:', {
|
|
26983
|
+
componentId: component.uuid,
|
|
26984
|
+
libraryId: libraryId,
|
|
26985
|
+
totalAdditions: additionHistory.length
|
|
26986
|
+
});
|
|
26987
|
+
}
|
|
26988
|
+
|
|
26989
|
+
/**
|
|
26990
|
+
* Add a connection between two connector IDs to the connections list
|
|
26991
|
+
* This method adds a new connection to the currentSceneData.connections array
|
|
26992
|
+
* @param {string} fromConnectorId - The ID of the source connector
|
|
26993
|
+
* @param {string} toConnectorId - The ID of the destination connector
|
|
26994
|
+
* @returns {Object|false} The added connection object if successful, false otherwise
|
|
26995
|
+
*/
|
|
26996
|
+
}, {
|
|
26997
|
+
key: "addConnection",
|
|
26998
|
+
value: function addConnection(fromConnectorId, toConnectorId) {
|
|
26999
|
+
// Validate input parameters
|
|
27000
|
+
if (!fromConnectorId || typeof fromConnectorId !== 'string') {
|
|
27001
|
+
console.error('❌ addConnection(): Invalid fromConnectorId provided. Must be a non-empty string:', fromConnectorId);
|
|
27002
|
+
return false;
|
|
27003
|
+
}
|
|
27004
|
+
if (!toConnectorId || typeof toConnectorId !== 'string') {
|
|
27005
|
+
console.error('❌ addConnection(): Invalid toConnectorId provided. Must be a non-empty string:', toConnectorId);
|
|
27006
|
+
return false;
|
|
27007
|
+
}
|
|
27008
|
+
|
|
27009
|
+
// Check if the same connector IDs (avoid self-connection)
|
|
27010
|
+
if (fromConnectorId === toConnectorId) {
|
|
27011
|
+
console.error('❌ addConnection(): Cannot connect a connector to itself:', fromConnectorId);
|
|
27012
|
+
return false;
|
|
27013
|
+
}
|
|
27014
|
+
|
|
27015
|
+
// Check if scene viewer and currentSceneData are available
|
|
27016
|
+
if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
|
|
27017
|
+
console.error('❌ addConnection(): Scene viewer or current scene data not available');
|
|
27018
|
+
return false;
|
|
27019
|
+
}
|
|
27020
|
+
try {
|
|
27021
|
+
// Initialize connections array if it doesn't exist
|
|
27022
|
+
if (!this.sceneViewer.currentSceneData.connections) {
|
|
27023
|
+
this.sceneViewer.currentSceneData.connections = [];
|
|
27024
|
+
console.log('🔄 addConnection(): Initialized connections array in currentSceneData');
|
|
27025
|
+
}
|
|
27026
|
+
|
|
27027
|
+
// Check if connection already exists
|
|
27028
|
+
var existingConnection = this.sceneViewer.currentSceneData.connections.find(function (connection) {
|
|
27029
|
+
return connection.from === fromConnectorId && connection.to === toConnectorId || connection.from === toConnectorId && connection.to === fromConnectorId;
|
|
27030
|
+
});
|
|
27031
|
+
if (existingConnection) {
|
|
27032
|
+
console.warn("\u26A0\uFE0F addConnection(): Connection already exists between ".concat(fromConnectorId, " and ").concat(toConnectorId));
|
|
27033
|
+
return existingConnection;
|
|
27034
|
+
}
|
|
27035
|
+
|
|
27036
|
+
// Create the new connection object
|
|
27037
|
+
var newConnection = {
|
|
27038
|
+
from: fromConnectorId,
|
|
27039
|
+
to: toConnectorId
|
|
27040
|
+
};
|
|
27041
|
+
|
|
27042
|
+
// Add the connection to the connections array
|
|
27043
|
+
this.sceneViewer.currentSceneData.connections.push(newConnection);
|
|
27044
|
+
|
|
27045
|
+
// Log successful addition
|
|
27046
|
+
console.log("\u2705 addConnection(): Connection added successfully", {
|
|
27047
|
+
from: fromConnectorId,
|
|
27048
|
+
to: toConnectorId,
|
|
27049
|
+
totalConnections: this.sceneViewer.currentSceneData.connections.length
|
|
27050
|
+
});
|
|
27051
|
+
|
|
27052
|
+
// Record the connection addition in metadata for tracking
|
|
27053
|
+
this.recordConnectionAddition(newConnection);
|
|
27054
|
+
return newConnection;
|
|
27055
|
+
} catch (error) {
|
|
27056
|
+
console.error("\u274C addConnection(): Error adding connection from ".concat(fromConnectorId, " to ").concat(toConnectorId, ":"), error);
|
|
27057
|
+
return false;
|
|
27058
|
+
}
|
|
27059
|
+
}
|
|
27060
|
+
|
|
27061
|
+
/**
|
|
27062
|
+
* Record connection addition in metadata for tracking and potential undo
|
|
27063
|
+
* @param {Object} connection - The added connection object
|
|
27064
|
+
*/
|
|
27065
|
+
}, {
|
|
27066
|
+
key: "recordConnectionAddition",
|
|
27067
|
+
value: function recordConnectionAddition(connection) {
|
|
27068
|
+
try {
|
|
27069
|
+
// Get existing connection history or create new array
|
|
27070
|
+
var connectionHistory = this.getMetadata('connectionAdditionHistory') || [];
|
|
27071
|
+
var connectionRecord = {
|
|
27072
|
+
from: connection.from,
|
|
27073
|
+
to: connection.to,
|
|
27074
|
+
timestamp: new Date().toISOString(),
|
|
27075
|
+
addedBy: 'centralPlant.addConnection()'
|
|
27076
|
+
};
|
|
27077
|
+
|
|
27078
|
+
// Add to history
|
|
27079
|
+
connectionHistory.push(connectionRecord);
|
|
27080
|
+
|
|
27081
|
+
// Store updated history (keep last 100 entries to prevent memory issues)
|
|
27082
|
+
this.setMetadata('connectionAdditionHistory', connectionHistory.slice(-100));
|
|
27083
|
+
|
|
27084
|
+
// Update connection statistics
|
|
27085
|
+
var stats = this.getMetadata('connectionStats') || {
|
|
27086
|
+
totalAdded: 0
|
|
27087
|
+
};
|
|
27088
|
+
stats.totalAdded = (stats.totalAdded || 0) + 1;
|
|
27089
|
+
stats.lastAddedTimestamp = new Date().toISOString();
|
|
27090
|
+
this.setMetadata('connectionStats', stats);
|
|
27091
|
+
} catch (error) {
|
|
27092
|
+
console.warn('⚠️ Failed to record connection addition in metadata:', error);
|
|
27093
|
+
}
|
|
27094
|
+
}
|
|
27095
|
+
|
|
27096
|
+
/**
|
|
27097
|
+
* Get all current connections from the scene data
|
|
27098
|
+
* @returns {Array} Array of connection objects or empty array if none exist
|
|
27099
|
+
*/
|
|
27100
|
+
}, {
|
|
27101
|
+
key: "getConnections",
|
|
27102
|
+
value: function getConnections() {
|
|
27103
|
+
if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
|
|
27104
|
+
console.warn('⚠️ getConnections(): Scene viewer or current scene data not available');
|
|
27105
|
+
return [];
|
|
27106
|
+
}
|
|
27107
|
+
return this.sceneViewer.currentSceneData.connections || [];
|
|
27108
|
+
}
|
|
27109
|
+
|
|
27110
|
+
/**
|
|
27111
|
+
* Remove a connection between two connector IDs from the connections list
|
|
27112
|
+
* @param {string} fromConnectorId - The ID of the source connector
|
|
27113
|
+
* @param {string} toConnectorId - The ID of the destination connector
|
|
27114
|
+
* @returns {boolean} True if connection was removed, false otherwise
|
|
27115
|
+
*/
|
|
27116
|
+
}, {
|
|
27117
|
+
key: "removeConnection",
|
|
27118
|
+
value: function removeConnection(fromConnectorId, toConnectorId) {
|
|
27119
|
+
// Validate input parameters
|
|
27120
|
+
if (!fromConnectorId || typeof fromConnectorId !== 'string') {
|
|
27121
|
+
console.error('❌ removeConnection(): Invalid fromConnectorId provided. Must be a non-empty string:', fromConnectorId);
|
|
27122
|
+
return false;
|
|
27123
|
+
}
|
|
27124
|
+
if (!toConnectorId || typeof toConnectorId !== 'string') {
|
|
27125
|
+
console.error('❌ removeConnection(): Invalid toConnectorId provided. Must be a non-empty string:', toConnectorId);
|
|
27126
|
+
return false;
|
|
27127
|
+
}
|
|
27128
|
+
|
|
27129
|
+
// Check if scene viewer and currentSceneData are available
|
|
27130
|
+
if (!this.sceneViewer || !this.sceneViewer.currentSceneData || !this.sceneViewer.currentSceneData.connections) {
|
|
27131
|
+
console.error('❌ removeConnection(): Scene viewer, current scene data, or connections array not available');
|
|
27132
|
+
return false;
|
|
27133
|
+
}
|
|
27134
|
+
try {
|
|
27135
|
+
// Find the connection to remove (check both directions)
|
|
27136
|
+
var connectionIndex = this.sceneViewer.currentSceneData.connections.findIndex(function (connection) {
|
|
27137
|
+
return connection.from === fromConnectorId && connection.to === toConnectorId || connection.from === toConnectorId && connection.to === fromConnectorId;
|
|
27138
|
+
});
|
|
27139
|
+
if (connectionIndex === -1) {
|
|
27140
|
+
console.warn("\u26A0\uFE0F removeConnection(): Connection not found between ".concat(fromConnectorId, " and ").concat(toConnectorId));
|
|
27141
|
+
return false;
|
|
27142
|
+
}
|
|
27143
|
+
|
|
27144
|
+
// Remove the connection
|
|
27145
|
+
var removedConnection = this.sceneViewer.currentSceneData.connections.splice(connectionIndex, 1)[0];
|
|
27146
|
+
|
|
27147
|
+
// Log successful removal
|
|
27148
|
+
console.log("\u2705 removeConnection(): Connection removed successfully", {
|
|
27149
|
+
from: removedConnection.from,
|
|
27150
|
+
to: removedConnection.to,
|
|
27151
|
+
remainingConnections: this.sceneViewer.currentSceneData.connections.length
|
|
27152
|
+
});
|
|
27153
|
+
|
|
27154
|
+
// Record the connection removal in metadata
|
|
27155
|
+
this.recordConnectionRemoval(removedConnection);
|
|
27156
|
+
return true;
|
|
27157
|
+
} catch (error) {
|
|
27158
|
+
console.error("\u274C removeConnection(): Error removing connection from ".concat(fromConnectorId, " to ").concat(toConnectorId, ":"), error);
|
|
27159
|
+
return false;
|
|
27160
|
+
}
|
|
27161
|
+
}
|
|
27162
|
+
|
|
27163
|
+
/**
|
|
27164
|
+
* Record connection removal in metadata for tracking
|
|
27165
|
+
* @param {Object} connection - The removed connection object
|
|
27166
|
+
*/
|
|
27167
|
+
}, {
|
|
27168
|
+
key: "recordConnectionRemoval",
|
|
27169
|
+
value: function recordConnectionRemoval(connection) {
|
|
27170
|
+
try {
|
|
27171
|
+
// Get existing removal history or create new array
|
|
27172
|
+
var removalHistory = this.getMetadata('connectionRemovalHistory') || [];
|
|
27173
|
+
var removalRecord = {
|
|
27174
|
+
from: connection.from,
|
|
27175
|
+
to: connection.to,
|
|
27176
|
+
timestamp: new Date().toISOString(),
|
|
27177
|
+
removedBy: 'centralPlant.removeConnection()'
|
|
27178
|
+
};
|
|
27179
|
+
|
|
27180
|
+
// Add to history
|
|
27181
|
+
removalHistory.push(removalRecord);
|
|
27182
|
+
|
|
27183
|
+
// Store updated history (keep last 100 entries to prevent memory issues)
|
|
27184
|
+
this.setMetadata('connectionRemovalHistory', removalHistory.slice(-100));
|
|
27185
|
+
|
|
27186
|
+
// Update connection statistics
|
|
27187
|
+
var stats = this.getMetadata('connectionStats') || {
|
|
27188
|
+
totalAdded: 0,
|
|
27189
|
+
totalRemoved: 0
|
|
27190
|
+
};
|
|
27191
|
+
stats.totalRemoved = (stats.totalRemoved || 0) + 1;
|
|
27192
|
+
stats.lastRemovedTimestamp = new Date().toISOString();
|
|
27193
|
+
this.setMetadata('connectionStats', stats);
|
|
27194
|
+
} catch (error) {
|
|
27195
|
+
console.warn('⚠️ Failed to record connection removal in metadata:', error);
|
|
27196
|
+
}
|
|
27197
|
+
}
|
|
27198
|
+
}, {
|
|
27199
|
+
key: "updatePaths",
|
|
27200
|
+
value: function updatePaths() {
|
|
27201
|
+
this.sceneViewer.updatePaths();
|
|
27202
|
+
}
|
|
26485
27203
|
}]);
|
|
26486
27204
|
}();
|
|
26487
27205
|
|