@2112-lab/central-plant 0.3.47 → 0.3.49
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 +591 -476
- package/dist/cjs/src/core/centralPlant.js +44 -43
- package/dist/cjs/src/core/centralPlantInternals.js +4 -2
- package/dist/cjs/src/core/sceneViewer.js +1 -1
- package/dist/cjs/src/managers/components/componentManager.js +11 -3
- package/dist/cjs/src/managers/components/transformOperationsManager.js +9 -11
- package/dist/cjs/src/managers/controls/transformControlsManager.js +83 -44
- package/dist/cjs/src/managers/pathfinding/pathfindingManager.js +272 -244
- package/dist/cjs/src/managers/scene/modelManager.js +33 -10
- package/dist/cjs/src/managers/scene/sceneExportManager.js +23 -30
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +48 -21
- package/dist/cjs/src/utils/boundingBoxUtils.js +62 -65
- package/dist/esm/src/core/centralPlant.js +44 -43
- package/dist/esm/src/core/centralPlantInternals.js +4 -2
- package/dist/esm/src/core/sceneViewer.js +1 -1
- package/dist/esm/src/managers/components/componentManager.js +11 -3
- package/dist/esm/src/managers/components/transformOperationsManager.js +9 -11
- package/dist/esm/src/managers/controls/transformControlsManager.js +83 -44
- package/dist/esm/src/managers/pathfinding/pathfindingManager.js +274 -246
- package/dist/esm/src/managers/scene/modelManager.js +33 -10
- package/dist/esm/src/managers/scene/sceneExportManager.js +24 -31
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +48 -21
- package/dist/esm/src/utils/boundingBoxUtils.js +62 -65
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -3720,41 +3720,36 @@ function computeFilteredBoundingBox(object) {
|
|
|
3720
3720
|
*/
|
|
3721
3721
|
function computeIODeviceBoundingBoxes(componentObject) {
|
|
3722
3722
|
var results = [];
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
}
|
|
3723
|
+
componentObject.traverse(function (child) {
|
|
3724
|
+
var _child$userData;
|
|
3725
|
+
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) !== 'io-device') return;
|
|
3726
|
+
var bbox = new THREE__namespace.Box3().setFromObject(child);
|
|
3727
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
3728
|
+
child.getWorldPosition(worldPos);
|
|
3729
|
+
if (!bbox.isEmpty()) {
|
|
3730
|
+
results.push({
|
|
3731
|
+
uuid: child.uuid,
|
|
3732
|
+
userData: {
|
|
3733
|
+
objectType: 'io-device',
|
|
3734
|
+
deviceId: child.userData.deviceId || null,
|
|
3735
|
+
attachmentId: child.userData.attachmentId || null,
|
|
3736
|
+
parentComponentId: child.userData.parentComponentId || componentObject.uuid,
|
|
3737
|
+
// Sync position for pathfinder
|
|
3738
|
+
position: [worldPos.x, worldPos.y, worldPos.z]
|
|
3739
|
+
},
|
|
3740
|
+
worldBoundingBox: {
|
|
3741
|
+
min: [bbox.min.x, bbox.min.y, bbox.min.z],
|
|
3742
|
+
max: [bbox.max.x, bbox.max.y, bbox.max.z]
|
|
3743
|
+
}
|
|
3744
|
+
});
|
|
3746
3745
|
}
|
|
3747
|
-
}
|
|
3748
|
-
_iterator.e(err);
|
|
3749
|
-
} finally {
|
|
3750
|
-
_iterator.f();
|
|
3751
|
-
}
|
|
3746
|
+
});
|
|
3752
3747
|
return results;
|
|
3753
3748
|
}
|
|
3754
3749
|
|
|
3755
3750
|
/**
|
|
3756
3751
|
* Computes individual world-space bounding boxes for each connector child
|
|
3757
|
-
* of a component.
|
|
3752
|
+
* of a component. Supports deep children (e.g. within GLB model hierarchy).
|
|
3758
3753
|
*
|
|
3759
3754
|
* @param {THREE.Object3D} componentObject - The component's Three.js object
|
|
3760
3755
|
* @returns {Array<{uuid: string, userData: Object, worldBoundingBox: {min: number[], max: number[]}}>}
|
|
@@ -3762,38 +3757,40 @@ function computeIODeviceBoundingBoxes(componentObject) {
|
|
|
3762
3757
|
*/
|
|
3763
3758
|
function computeConnectorBoundingBoxes(componentObject) {
|
|
3764
3759
|
var results = [];
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3760
|
+
componentObject.traverse(function (child) {
|
|
3761
|
+
var _child$userData2;
|
|
3762
|
+
if (((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType) !== 'connector') return;
|
|
3763
|
+
var bbox = new THREE__namespace.Box3().setFromObject(child);
|
|
3764
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
3765
|
+
child.getWorldPosition(worldPos);
|
|
3766
|
+
|
|
3767
|
+
// Compute world-space direction vector (Crucial for rotation-aware pathfinding)
|
|
3768
|
+
// Default to [0, 0, 1] if not specified (Standard for our coordinate system)
|
|
3769
|
+
var localDirData = child.userData && Array.isArray(child.userData.direction) ? child.userData.direction : [0, 0, 1];
|
|
3770
|
+
var localDir = new THREE__namespace.Vector3(localDirData[0], localDirData[1], localDirData[2]);
|
|
3771
|
+
var worldQuat = new THREE__namespace.Quaternion();
|
|
3772
|
+
child.getWorldQuaternion(worldQuat);
|
|
3773
|
+
var worldDir = localDir.clone().applyQuaternion(worldQuat).normalize();
|
|
3774
|
+
|
|
3775
|
+
// Fallback if mesh is too small or empty (sometimes connectors are just points)
|
|
3776
|
+
if (bbox.isEmpty() || bbox.getSize(new THREE__namespace.Vector3()).length() < 0.01) {
|
|
3777
|
+
var size = 0.1;
|
|
3778
|
+
bbox.setFromCenterAndSize(worldPos, new THREE__namespace.Vector3(size, size, size));
|
|
3779
|
+
}
|
|
3780
|
+
results.push({
|
|
3781
|
+
uuid: child.uuid,
|
|
3782
|
+
userData: _objectSpread2(_objectSpread2({}, child.userData), {}, {
|
|
3783
|
+
objectType: 'connector',
|
|
3784
|
+
// Update both position AND direction for pathfinder
|
|
3785
|
+
position: [worldPos.x, worldPos.y, worldPos.z],
|
|
3786
|
+
direction: [worldDir.x, worldDir.y, worldDir.z]
|
|
3787
|
+
}),
|
|
3788
|
+
worldBoundingBox: {
|
|
3789
|
+
min: [bbox.min.x, bbox.min.y, bbox.min.z],
|
|
3790
|
+
max: [bbox.max.x, bbox.max.y, bbox.max.z]
|
|
3780
3791
|
}
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
userData: _objectSpread2(_objectSpread2({}, child.userData), {}, {
|
|
3784
|
-
objectType: 'connector'
|
|
3785
|
-
}),
|
|
3786
|
-
worldBoundingBox: {
|
|
3787
|
-
min: [bbox.min.x, bbox.min.y, bbox.min.z],
|
|
3788
|
-
max: [bbox.max.x, bbox.max.y, bbox.max.z]
|
|
3789
|
-
}
|
|
3790
|
-
});
|
|
3791
|
-
}
|
|
3792
|
-
} catch (err) {
|
|
3793
|
-
_iterator2.e(err);
|
|
3794
|
-
} finally {
|
|
3795
|
-
_iterator2.f();
|
|
3796
|
-
}
|
|
3792
|
+
});
|
|
3793
|
+
});
|
|
3797
3794
|
return results;
|
|
3798
3795
|
}
|
|
3799
3796
|
|
|
@@ -3893,11 +3890,11 @@ function createSelectionBoxHelpers(object) {
|
|
|
3893
3890
|
* @param {THREE.Scene} scene - The scene (for finding objects by uuid)
|
|
3894
3891
|
*/
|
|
3895
3892
|
function updateSelectionBoxHelpers(helpers, selectedObjects, scene) {
|
|
3896
|
-
var
|
|
3897
|
-
|
|
3893
|
+
var _iterator = _createForOfIteratorHelper(helpers),
|
|
3894
|
+
_step;
|
|
3898
3895
|
try {
|
|
3899
3896
|
var _loop = function _loop() {
|
|
3900
|
-
var helper =
|
|
3897
|
+
var helper = _step.value;
|
|
3901
3898
|
var _helper$userData = helper.userData,
|
|
3902
3899
|
sourceObjectUuid = _helper$userData.sourceObjectUuid,
|
|
3903
3900
|
isFiltered = _helper$userData.isFiltered,
|
|
@@ -3928,13 +3925,13 @@ function updateSelectionBoxHelpers(helpers, selectedObjects, scene) {
|
|
|
3928
3925
|
helper.update();
|
|
3929
3926
|
}
|
|
3930
3927
|
};
|
|
3931
|
-
for (
|
|
3928
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
3932
3929
|
if (_loop()) continue;
|
|
3933
3930
|
}
|
|
3934
3931
|
} catch (err) {
|
|
3935
|
-
|
|
3932
|
+
_iterator.e(err);
|
|
3936
3933
|
} finally {
|
|
3937
|
-
|
|
3934
|
+
_iterator.f();
|
|
3938
3935
|
}
|
|
3939
3936
|
}
|
|
3940
3937
|
|
|
@@ -3974,7 +3971,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
3974
3971
|
this.forceInvisible = false;
|
|
3975
3972
|
|
|
3976
3973
|
// SceneViewer reference for event listening
|
|
3977
|
-
this.sceneViewer = null;
|
|
3974
|
+
this.sceneViewer = centralPlant ? centralPlant.sceneViewer : null;
|
|
3978
3975
|
this._objectTransformedListener = null;
|
|
3979
3976
|
|
|
3980
3977
|
// Event handlers storage
|
|
@@ -4176,23 +4173,28 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
4176
4173
|
_this2.transformState.isTransforming = true;
|
|
4177
4174
|
|
|
4178
4175
|
// Store initial transforms for all selected objects
|
|
4179
|
-
if (_this2.selectedObjects.length > 0
|
|
4176
|
+
if (_this2.selectedObjects.length > 0) {
|
|
4180
4177
|
_this2.selectedObjects.forEach(function (obj) {
|
|
4181
|
-
obj.userData.
|
|
4182
|
-
obj.userData.
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
// cheap per-frame bbox translation without re-traversing the mesh hierarchy.
|
|
4188
|
-
_this2._dragStartGroupPosition = _this2.multiSelectionGroup.position.clone();
|
|
4189
|
-
_this2.boundingBoxHelpers.forEach(function (helper) {
|
|
4190
|
-
var _helper$geometry;
|
|
4191
|
-
var posAttr = (_helper$geometry = helper.geometry) === null || _helper$geometry === void 0 || (_helper$geometry = _helper$geometry.attributes) === null || _helper$geometry === void 0 ? void 0 : _helper$geometry.position;
|
|
4192
|
-
if (posAttr) {
|
|
4193
|
-
helper.userData._dragStartPositions = new Float32Array(posAttr.array);
|
|
4178
|
+
obj.userData._dragStartRotation = obj.rotation.clone();
|
|
4179
|
+
obj.userData._dragStartPosition = obj.position.clone();
|
|
4180
|
+
if (_this2.multiSelectionGroup) {
|
|
4181
|
+
obj.userData._multiSelectOriginalPosition = obj.position.clone();
|
|
4182
|
+
obj.userData._multiSelectOriginalRotation = obj.rotation.clone();
|
|
4183
|
+
obj.userData._multiSelectOriginalScale = obj.scale.clone();
|
|
4194
4184
|
}
|
|
4195
4185
|
});
|
|
4186
|
+
if (_this2.multiSelectionGroup) {
|
|
4187
|
+
// Snapshot group position and helper geometry vertices so we can do
|
|
4188
|
+
// cheap per-frame bbox translation without re-traversing the mesh hierarchy.
|
|
4189
|
+
_this2._dragStartGroupPosition = _this2.multiSelectionGroup.position.clone();
|
|
4190
|
+
_this2.boundingBoxHelpers.forEach(function (helper) {
|
|
4191
|
+
var _helper$geometry;
|
|
4192
|
+
var posAttr = (_helper$geometry = helper.geometry) === null || _helper$geometry === void 0 || (_helper$geometry = _helper$geometry.attributes) === null || _helper$geometry === void 0 ? void 0 : _helper$geometry.position;
|
|
4193
|
+
if (posAttr) {
|
|
4194
|
+
helper.userData._dragStartPositions = new Float32Array(posAttr.array);
|
|
4195
|
+
}
|
|
4196
|
+
});
|
|
4197
|
+
}
|
|
4196
4198
|
}
|
|
4197
4199
|
|
|
4198
4200
|
// Disable orbit controls during transformation
|
|
@@ -4209,7 +4211,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
4209
4211
|
|
|
4210
4212
|
// Transform end event
|
|
4211
4213
|
this.eventHandlers.transformEnd = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
4212
|
-
var hasComponents, _this2$selectedObject, sceneCompleteEvent;
|
|
4214
|
+
var isTranslate, isRotate, hasComponents, _this2$selectedObject, sceneCompleteEvent;
|
|
4213
4215
|
return _regenerator().w(function (_context) {
|
|
4214
4216
|
while (1) switch (_context.n) {
|
|
4215
4217
|
case 0:
|
|
@@ -4231,29 +4233,52 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
4231
4233
|
console.error('❌ Error in applyMultiSelectionTransform:', error);
|
|
4232
4234
|
});
|
|
4233
4235
|
case 1:
|
|
4234
|
-
|
|
4235
|
-
// so we skip the additional updatePaths() call below
|
|
4236
|
-
console.log('✅ Multi-selection transform complete (updatePaths already called)');
|
|
4236
|
+
console.log('✅ Multi-selection transform complete');
|
|
4237
4237
|
_context.n = 3;
|
|
4238
4238
|
break;
|
|
4239
4239
|
case 2:
|
|
4240
|
-
if (_this2.
|
|
4241
|
-
// Update paths after
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4240
|
+
if (_this2.sceneViewer && typeof _this2.sceneViewer.updatePaths === 'function') {
|
|
4241
|
+
// Update paths after transformation is complete (translation or rotation)
|
|
4242
|
+
isTranslate = _this2.currentMode === 'translate';
|
|
4243
|
+
isRotate = _this2.currentMode === 'rotate';
|
|
4244
|
+
if (isTranslate || isRotate) {
|
|
4245
|
+
hasComponents = _this2.selectedObjects.some(function (obj) {
|
|
4246
|
+
return !isSegment(obj) && !isGateway(obj);
|
|
4247
|
+
});
|
|
4248
|
+
if (hasComponents) {
|
|
4249
|
+
console.log("\uD83D\uDD04 Updating paths after component ".concat(_this2.currentMode, "..."));
|
|
4250
|
+
try {
|
|
4251
|
+
// Ensure scene data is synced before updating paths
|
|
4252
|
+
_this2.selectedObjects.forEach(function (obj) {
|
|
4253
|
+
var _obj$userData;
|
|
4254
|
+
if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) === 'component') {
|
|
4255
|
+
var _this2$sceneViewer$ma;
|
|
4256
|
+
var transformMgr = (_this2$sceneViewer$ma = _this2.sceneViewer.managers) === null || _this2$sceneViewer$ma === void 0 ? void 0 : _this2$sceneViewer$ma.transformOperationsManager;
|
|
4257
|
+
if (transformMgr) {
|
|
4258
|
+
if (isTranslate) {
|
|
4259
|
+
transformMgr.updateComponentPositionInSceneData(obj);
|
|
4260
|
+
}
|
|
4261
|
+
if (isRotate) {
|
|
4262
|
+
transformMgr.updateComponentRotationInSceneData(obj);
|
|
4263
|
+
|
|
4264
|
+
// Calculate rotation delta for direction vector patching
|
|
4265
|
+
var startRot = obj.userData._dragStartRotation || obj.rotation;
|
|
4266
|
+
var deltaRad = obj.rotation.z - startRot.z;
|
|
4267
|
+
var deltaDeg = Math.round(THREE__namespace.MathUtils.radToDeg(deltaRad) / 90) * 90;
|
|
4268
|
+
if (deltaDeg !== 0) {
|
|
4269
|
+
console.log("\uD83E\uDDED Patching connector directions by ".concat(deltaDeg, " degrees after gizmo rotation"));
|
|
4270
|
+
transformMgr.updateConnectorDirections(obj, 'z', deltaDeg);
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
}
|
|
4274
|
+
}
|
|
4275
|
+
});
|
|
4276
|
+
_this2.sceneViewer.updatePaths();
|
|
4277
|
+
console.log("\u2705 Paths updated successfully after ".concat(_this2.currentMode));
|
|
4278
|
+
} catch (error) {
|
|
4279
|
+
console.error("\u274C Error updating paths after ".concat(_this2.currentMode, ":"), error);
|
|
4280
|
+
}
|
|
4254
4281
|
}
|
|
4255
|
-
} else {
|
|
4256
|
-
console.log('ℹ️ Skipping updatePaths - segments/gateways handle their own path updates');
|
|
4257
4282
|
}
|
|
4258
4283
|
}
|
|
4259
4284
|
case 3:
|
|
@@ -4384,8 +4409,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
4384
4409
|
var hit = _step.value;
|
|
4385
4410
|
var _obj = hit.object;
|
|
4386
4411
|
while (_obj) {
|
|
4387
|
-
var _obj$
|
|
4388
|
-
if (((_obj$
|
|
4412
|
+
var _obj$userData3;
|
|
4413
|
+
if (((_obj$userData3 = _obj.userData) === null || _obj$userData3 === void 0 ? void 0 : _obj$userData3.objectType) === 'io-device') {
|
|
4389
4414
|
ioDeviceObject = _obj;
|
|
4390
4415
|
break;
|
|
4391
4416
|
}
|
|
@@ -4408,8 +4433,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
4408
4433
|
var parentUuid = null;
|
|
4409
4434
|
var obj = ioDeviceObject.parent;
|
|
4410
4435
|
while (obj) {
|
|
4411
|
-
var _obj$
|
|
4412
|
-
if (((_obj$
|
|
4436
|
+
var _obj$userData2;
|
|
4437
|
+
if (((_obj$userData2 = obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.objectType) === 'component') {
|
|
4413
4438
|
parentUuid = obj.userData.originalUuid || obj.uuid;
|
|
4414
4439
|
break;
|
|
4415
4440
|
}
|
|
@@ -4486,8 +4511,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
4486
4511
|
var hit = _step2.value;
|
|
4487
4512
|
var obj = hit.object;
|
|
4488
4513
|
while (obj) {
|
|
4489
|
-
var _obj$
|
|
4490
|
-
if (((_obj$
|
|
4514
|
+
var _obj$userData4;
|
|
4515
|
+
if (((_obj$userData4 = obj.userData) === null || _obj$userData4 === void 0 ? void 0 : _obj$userData4.objectType) === 'io-device') {
|
|
4491
4516
|
_this4.callbacks.onIODeviceClick(obj);
|
|
4492
4517
|
return;
|
|
4493
4518
|
}
|
|
@@ -6148,8 +6173,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
6148
6173
|
key: "_updateSegmentReference",
|
|
6149
6174
|
value: function _updateSegmentReference(oldSegment, newSegment, index) {
|
|
6150
6175
|
var selectedIndex = this.selectedObjects.findIndex(function (obj) {
|
|
6151
|
-
var _obj$
|
|
6152
|
-
return obj.uuid === oldSegment.uuid || ((_obj$
|
|
6176
|
+
var _obj$userData5;
|
|
6177
|
+
return obj.uuid === oldSegment.uuid || ((_obj$userData5 = obj.userData) === null || _obj$userData5 === void 0 ? void 0 : _obj$userData5.originalUuid) === oldSegment.uuid;
|
|
6153
6178
|
});
|
|
6154
6179
|
if (selectedIndex !== -1 && newSegment) {
|
|
6155
6180
|
// Clear bounding box cache
|
|
@@ -6257,7 +6282,7 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
6257
6282
|
componentId = component.uuid || ((_component$userData = component.userData) === null || _component$userData === void 0 ? void 0 : _component$userData.originalUuid);
|
|
6258
6283
|
_context6.n = 3;
|
|
6259
6284
|
return this._translateObjectOnAxes(componentId, deltaX, deltaY, deltaZ, threshold, throttleDelay, AXIS_THROTTLE, function (id, axis, delta) {
|
|
6260
|
-
return _this0.centralPlant.translate(id, axis, delta);
|
|
6285
|
+
return _this0.centralPlant.translate(id, axis, delta, true);
|
|
6261
6286
|
});
|
|
6262
6287
|
case 3:
|
|
6263
6288
|
console.log("\uD83D\uDD27 Component ".concat(component.name, " translated (").concat(i + 1, "/").concat(components.length, ")"));
|
|
@@ -6356,6 +6381,17 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
6356
6381
|
if (this.selectedObjects.length > 0) {
|
|
6357
6382
|
this.updateMultiSelection();
|
|
6358
6383
|
}
|
|
6384
|
+
|
|
6385
|
+
// Trigger pathfinding update once after all objects in the batch are translated
|
|
6386
|
+
if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
|
|
6387
|
+
var hasComponentsOrSegments = this.selectedObjects.some(function (obj) {
|
|
6388
|
+
return !isGateway(obj);
|
|
6389
|
+
});
|
|
6390
|
+
if (hasComponentsOrSegments) {
|
|
6391
|
+
console.log('🔄 Triggering batched pathfinding update after multi-object translation...');
|
|
6392
|
+
this.sceneViewer.updatePaths();
|
|
6393
|
+
}
|
|
6394
|
+
}
|
|
6359
6395
|
console.log("\u2705 Multi-selection transform applied");
|
|
6360
6396
|
}
|
|
6361
6397
|
|
|
@@ -11881,6 +11917,11 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
11881
11917
|
// Helper function to convert Three.js object to minimal JSON format
|
|
11882
11918
|
var convertObjectToJson = function convertObjectToJson(threeObject) {
|
|
11883
11919
|
var _threeObject$name, _threeObject$userData, _threeObject$userData2, _threeObject$userData3, _threeObject$userData4, _threeObject$userData5, _threeObject$userData6, _threeObject$userData7, _threeObject$userData8, _threeObject$userData9, _threeObject$userData0, _threeObject$userData1, _threeObject$userData10;
|
|
11920
|
+
// Ensure world matrices are updated for this subtree before exporting
|
|
11921
|
+
if (threeObject.updateMatrixWorld) {
|
|
11922
|
+
threeObject.updateMatrixWorld(true);
|
|
11923
|
+
}
|
|
11924
|
+
|
|
11884
11925
|
// Skip certain objects that shouldn't be exported
|
|
11885
11926
|
if (!threeObject || (_threeObject$name = threeObject.name) !== null && _threeObject$name !== void 0 && _threeObject$name.includes('Polyline') ||
|
|
11886
11927
|
// Skip pipe paths
|
|
@@ -12019,11 +12060,10 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
12019
12060
|
};
|
|
12020
12061
|
}
|
|
12021
12062
|
|
|
12022
|
-
//
|
|
12023
|
-
//
|
|
12024
|
-
//
|
|
12063
|
+
// Only manual segments persist their connector children here.
|
|
12064
|
+
// Component connectors are NOT exported — they are regenerated from the
|
|
12065
|
+
// component dictionary on load (see note below), keeping the scene JSON minimal.
|
|
12025
12066
|
if (threeObject.children && threeObject.children.length > 0) {
|
|
12026
|
-
var _threeObject$userData11;
|
|
12027
12067
|
var exportableChildren = [];
|
|
12028
12068
|
if (isManualSegment) {
|
|
12029
12069
|
// For manual segments, export their connector children
|
|
@@ -12037,26 +12077,15 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
12037
12077
|
}
|
|
12038
12078
|
}
|
|
12039
12079
|
});
|
|
12040
|
-
} else if (((_threeObject$userData11 = threeObject.userData) === null || _threeObject$userData11 === void 0 ? void 0 : _threeObject$userData11.objectType) === 'component') {
|
|
12041
|
-
// For components, only export connectors that have objectType='connector'
|
|
12042
|
-
// Standard dictionary-injected connectors should be exported so connections work on re-import
|
|
12043
|
-
threeObject.children.forEach(function (child) {
|
|
12044
|
-
var _child$userData2;
|
|
12045
|
-
if (((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType) === 'connector') {
|
|
12046
|
-
exportableChildren.push({
|
|
12047
|
-
uuid: child.uuid,
|
|
12048
|
-
name: child.name,
|
|
12049
|
-
type: 'Mesh',
|
|
12050
|
-
position: {
|
|
12051
|
-
x: roundIfClose(child.position.x),
|
|
12052
|
-
y: roundIfClose(child.position.y),
|
|
12053
|
-
z: roundIfClose(child.position.z)
|
|
12054
|
-
},
|
|
12055
|
-
userData: _objectSpread2({}, child.userData)
|
|
12056
|
-
});
|
|
12057
|
-
}
|
|
12058
|
-
});
|
|
12059
12080
|
}
|
|
12081
|
+
// NOTE: Component connectors are intentionally NOT exported.
|
|
12082
|
+
// They are defined in the component dictionary and regenerated on load by
|
|
12083
|
+
// sceneOperationsManager._injectConnectorChildrenFromDictionary using the
|
|
12084
|
+
// matching uuid scheme (`${componentUuid}_${dictConnectorUuid}`), and the
|
|
12085
|
+
// pathfinder rebuilds their world positions/bounding boxes on every run
|
|
12086
|
+
// (computeConnectorBoundingBoxes). Connections still resolve because the
|
|
12087
|
+
// regenerated connector uuids match the connection endpoints.
|
|
12088
|
+
|
|
12060
12089
|
if (exportableChildren.length > 0) {
|
|
12061
12090
|
jsonObject.children = exportableChildren;
|
|
12062
12091
|
}
|
|
@@ -12070,9 +12099,9 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
12070
12099
|
// Extract main scene objects (components and standalone connectors)
|
|
12071
12100
|
var sceneChildren = [];
|
|
12072
12101
|
this.sceneViewer.scene.children.forEach(function (child) {
|
|
12073
|
-
var _child$
|
|
12102
|
+
var _child$userData2;
|
|
12074
12103
|
// Only export components and connectors; skip segments, gateways, polylines, etc.
|
|
12075
|
-
var objectType = (_child$
|
|
12104
|
+
var objectType = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType;
|
|
12076
12105
|
if (objectType !== 'component' && objectType !== 'connector') {
|
|
12077
12106
|
return;
|
|
12078
12107
|
}
|
|
@@ -12236,14 +12265,14 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
12236
12265
|
BufferGeometryUtils$1 = BufferGeometryUtilsModule.BufferGeometryUtils || BufferGeometryUtilsModule.default || BufferGeometryUtilsModule; // Create a new scene for export instead of cloning
|
|
12237
12266
|
exportScene = new _THREE.Scene(); // Helper function to check if an object should be exported
|
|
12238
12267
|
shouldExport = function shouldExport(child) {
|
|
12239
|
-
var _child$name, _child$
|
|
12268
|
+
var _child$name, _child$userData3, _child$userData4, _child$userData5, _child$userData6;
|
|
12240
12269
|
if ((_child$name = child.name) !== null && _child$name !== void 0 && _child$name.includes('Polyline')) return false; // Will handle separately
|
|
12241
12270
|
if (child.name === 'fogPlane') return false; // Skip fog plane
|
|
12242
|
-
if ((_child$
|
|
12243
|
-
if ((_child$
|
|
12244
|
-
if ((_child$
|
|
12271
|
+
if ((_child$userData3 = child.userData) !== null && _child$userData3 !== void 0 && _child$userData3.isBrickWall) return false; // Skip environment
|
|
12272
|
+
if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBaseGround) return false; // Skip environment
|
|
12273
|
+
if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGrid) return false; // Skip environment
|
|
12245
12274
|
if (child.isLight) return false; // Skip lights
|
|
12246
|
-
if ((_child$
|
|
12275
|
+
if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isTransformControls) return false; // Skip transform controls
|
|
12247
12276
|
if (child.isTransformControls) return false; // Skip transform controls
|
|
12248
12277
|
if (child.type && child.type.includes('TransformControls')) return false;
|
|
12249
12278
|
if (child.type && child.type.includes('Helper')) return false; // Skip helpers
|
|
@@ -19901,7 +19930,7 @@ var ComponentManager = /*#__PURE__*/function () {
|
|
|
19901
19930
|
key: "addComponentToScene",
|
|
19902
19931
|
value: (function () {
|
|
19903
19932
|
var _addComponentToScene = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(componentData) {
|
|
19904
|
-
var _gltfScene$userData, uuid, componentDictionary, libraryComponent, position, gltfScene, componentMesh, event, _t, _t2;
|
|
19933
|
+
var _gltfScene$userData, uuid, componentDictionary, libraryComponent, position, gltfScene, componentMesh, connectorIndex, event, _t, _t2;
|
|
19905
19934
|
return _regenerator().w(function (_context) {
|
|
19906
19935
|
while (1) switch (_context.n) {
|
|
19907
19936
|
case 0:
|
|
@@ -20005,6 +20034,7 @@ var ComponentManager = /*#__PURE__*/function () {
|
|
|
20005
20034
|
}
|
|
20006
20035
|
|
|
20007
20036
|
// Enable shadows for all meshes in the component
|
|
20037
|
+
connectorIndex = 0;
|
|
20008
20038
|
componentMesh.traverse(function (child) {
|
|
20009
20039
|
if (child.isMesh) {
|
|
20010
20040
|
child.castShadow = true;
|
|
@@ -20014,12 +20044,19 @@ var ComponentManager = /*#__PURE__*/function () {
|
|
|
20014
20044
|
}
|
|
20015
20045
|
|
|
20016
20046
|
// Set connector properties for connectors within the component
|
|
20017
|
-
if (child.name && child.name.toLowerCase().includes('connector')) {
|
|
20047
|
+
if (child.name && child.name.toLowerCase().includes('connector') || child.userData && child.userData.objectType === 'connector') {
|
|
20048
|
+
connectorIndex++;
|
|
20018
20049
|
if (!child.userData) {
|
|
20019
20050
|
child.userData = {};
|
|
20020
20051
|
}
|
|
20021
20052
|
child.userData.objectType = 'connector';
|
|
20022
|
-
|
|
20053
|
+
|
|
20054
|
+
// Assign a predictable, stable UUID to the connector
|
|
20055
|
+
// This ensures connections made in the sandbox survive export/import
|
|
20056
|
+
var connectorUuid = "".concat(uuid, "-CONNECTOR-").concat(connectorIndex);
|
|
20057
|
+
child.uuid = connectorUuid;
|
|
20058
|
+
child.userData.originalUuid = connectorUuid;
|
|
20059
|
+
console.log("\uD83D\uDD27 Set predictable connector UUID: ".concat(connectorUuid, " for: ").concat(child.name));
|
|
20023
20060
|
}
|
|
20024
20061
|
}
|
|
20025
20062
|
});
|
|
@@ -21214,12 +21251,14 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21214
21251
|
* @param {string} componentId - The UUID of the component to translate
|
|
21215
21252
|
* @param {string} axis - The axis to translate on ('x', 'y', or 'z')
|
|
21216
21253
|
* @param {number} value - The value to translate by
|
|
21254
|
+
* @param {boolean} [skipPathUpdate=false] - Whether to skip triggering pathfinding after translation
|
|
21217
21255
|
* @returns {boolean} True if translation was successful, false otherwise
|
|
21218
21256
|
*/
|
|
21219
21257
|
return _createClass(TransformOperationsManager, [{
|
|
21220
21258
|
key: "translateComponent",
|
|
21221
21259
|
value: function translateComponent(componentId, axis, value) {
|
|
21222
21260
|
var _this$sceneViewer$man, _this$sceneViewer;
|
|
21261
|
+
var skipPathUpdate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
21223
21262
|
// Store transform parameters using the OperationHistoryManager
|
|
21224
21263
|
if ((_this$sceneViewer$man = this.sceneViewer.managers) !== null && _this$sceneViewer$man !== void 0 && _this$sceneViewer$man.operationHistoryManager) {
|
|
21225
21264
|
this.sceneViewer.managers.operationHistoryManager.addToOperationHistory('translateComponent', {
|
|
@@ -21287,7 +21326,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21287
21326
|
}
|
|
21288
21327
|
|
|
21289
21328
|
// Auto-update paths if enabled (matches behavior of translateSegment and translateGateway)
|
|
21290
|
-
if (this.sceneViewer.shouldUpdatePaths) {
|
|
21329
|
+
if (!skipPathUpdate && this.sceneViewer.shouldUpdatePaths) {
|
|
21291
21330
|
try {
|
|
21292
21331
|
if (this.sceneViewer && typeof this.sceneViewer.updatePaths === 'function') {
|
|
21293
21332
|
this.sceneViewer.updatePaths();
|
|
@@ -21298,6 +21337,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21298
21337
|
} catch (error) {
|
|
21299
21338
|
console.error('❌ Error auto-updating paths:', error);
|
|
21300
21339
|
}
|
|
21340
|
+
} else if (skipPathUpdate) {
|
|
21341
|
+
console.log('ℹ️ skipPathUpdate is true: skipping automatic path update');
|
|
21301
21342
|
}
|
|
21302
21343
|
|
|
21303
21344
|
// Emit transform event if available
|
|
@@ -23116,11 +23157,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
23116
23157
|
sceneDataComponent.children.forEach(function (child) {
|
|
23117
23158
|
var _child$userData21;
|
|
23118
23159
|
if (((_child$userData21 = child.userData) === null || _child$userData21 === void 0 ? void 0 : _child$userData21.objectType) === 'connector') {
|
|
23119
|
-
// Find the actual connector object in the scene
|
|
23120
|
-
var connectorObj = component.
|
|
23121
|
-
var _c$userData;
|
|
23122
|
-
return c.uuid === child.uuid || ((_c$userData = c.userData) === null || _c$userData === void 0 ? void 0 : _c$userData.originalUuid) === child.uuid;
|
|
23123
|
-
});
|
|
23160
|
+
// Find the actual connector object in the scene (recursive search for nested connectors)
|
|
23161
|
+
var connectorObj = component.getObjectByProperty('uuid', child.uuid) || component.getObjectByProperty('name', child.uuid);
|
|
23124
23162
|
if (connectorObj) {
|
|
23125
23163
|
// Get world position of connector
|
|
23126
23164
|
var worldPos = new THREE__namespace.Vector3();
|
|
@@ -23179,11 +23217,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
23179
23217
|
sceneDataComponent.children.forEach(function (child) {
|
|
23180
23218
|
var _child$userData22;
|
|
23181
23219
|
if (((_child$userData22 = child.userData) === null || _child$userData22 === void 0 ? void 0 : _child$userData22.objectType) === 'connector') {
|
|
23182
|
-
// Find the actual connector object in the scene
|
|
23183
|
-
var connectorObj = component.
|
|
23184
|
-
var _c$userData2;
|
|
23185
|
-
return c.uuid === child.uuid || ((_c$userData2 = c.userData) === null || _c$userData2 === void 0 ? void 0 : _c$userData2.originalUuid) === child.uuid;
|
|
23186
|
-
});
|
|
23220
|
+
// Find the actual connector object in the scene (recursive search for nested connectors)
|
|
23221
|
+
var connectorObj = component.getObjectByProperty('uuid', child.uuid) || component.getObjectByProperty('name', child.uuid);
|
|
23187
23222
|
if (connectorObj) {
|
|
23188
23223
|
var _connectorObj$userDat;
|
|
23189
23224
|
// Get world position of connector
|
|
@@ -29109,10 +29144,11 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29109
29144
|
}, {
|
|
29110
29145
|
key: "_matrixHash",
|
|
29111
29146
|
value: function _matrixHash(obj) {
|
|
29147
|
+
// Force matrix update to ensure we're looking at the latest data
|
|
29148
|
+
obj.updateMatrixWorld(true);
|
|
29112
29149
|
var e = obj.matrixWorld.elements;
|
|
29113
|
-
//
|
|
29114
|
-
|
|
29115
|
-
return "".concat(e[0].toFixed(5), ",").concat(e[5].toFixed(5), ",").concat(e[10].toFixed(5), ",").concat(e[12].toFixed(5), ",").concat(e[13].toFixed(5), ",").concat(e[14].toFixed(5));
|
|
29150
|
+
// Just hash the position/rotation/scale part of the matrix (12 elements)
|
|
29151
|
+
return "".concat(e[0].toFixed(3), ",").concat(e[1].toFixed(3), ",").concat(e[2].toFixed(3), ",").concat(e[4].toFixed(3), ",").concat(e[5].toFixed(3), ",").concat(e[6].toFixed(3), ",").concat(e[8].toFixed(3), ",").concat(e[9].toFixed(3), ",").concat(e[10].toFixed(3), ",").concat(e[12].toFixed(3), ",").concat(e[13].toFixed(3), ",").concat(e[14].toFixed(3));
|
|
29116
29152
|
}
|
|
29117
29153
|
|
|
29118
29154
|
/**
|
|
@@ -29130,11 +29166,7 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29130
29166
|
* Compute a lightweight fingerprint of the pathfinding inputs so that
|
|
29131
29167
|
* consecutive identical runs can be skipped entirely.
|
|
29132
29168
|
*
|
|
29133
|
-
*
|
|
29134
|
-
* • The connections list (from / to pairs)
|
|
29135
|
-
* • The world transform of every top-level child in sceneData
|
|
29136
|
-
*
|
|
29137
|
-
* @param {Object} sceneData - scene data object with .children
|
|
29169
|
+
* @param {Object} sceneData - scene object or manifest
|
|
29138
29170
|
* @param {Array} connections - array of {from, to}
|
|
29139
29171
|
* @returns {string}
|
|
29140
29172
|
* @private
|
|
@@ -29142,277 +29174,241 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29142
29174
|
}, {
|
|
29143
29175
|
key: "_computePathfindingFingerprint",
|
|
29144
29176
|
value: function _computePathfindingFingerprint(sceneData, connections) {
|
|
29177
|
+
var _this3 = this;
|
|
29145
29178
|
var parts = [];
|
|
29146
29179
|
|
|
29147
29180
|
// 1. Connections (sorted so order doesn't matter)
|
|
29148
|
-
parts.push(connections.map(function (c) {
|
|
29181
|
+
parts.push((connections || []).map(function (c) {
|
|
29149
29182
|
return "".concat(c.from, "->").concat(c.to);
|
|
29150
29183
|
}).sort().join(','));
|
|
29151
29184
|
|
|
29152
|
-
// 2. World transforms of every referenced scene object
|
|
29153
|
-
|
|
29154
|
-
|
|
29155
|
-
|
|
29156
|
-
|
|
29157
|
-
|
|
29158
|
-
|
|
29159
|
-
var
|
|
29160
|
-
|
|
29161
|
-
|
|
29162
|
-
|
|
29163
|
-
var _p$x, _p$y, _p$z;
|
|
29164
|
-
// Object only in data, not in scene — include its serialised position
|
|
29165
|
-
var p = child.position || {};
|
|
29166
|
-
parts.push("".concat(child.uuid, ":").concat(((_p$x = p.x) !== null && _p$x !== void 0 ? _p$x : 0).toFixed(5), ",").concat(((_p$y = p.y) !== null && _p$y !== void 0 ? _p$y : 0).toFixed(5), ",").concat(((_p$z = p.z) !== null && _p$z !== void 0 ? _p$z : 0).toFixed(5)));
|
|
29167
|
-
}
|
|
29185
|
+
// 2. World transforms of every referenced scene object (recursive)
|
|
29186
|
+
var _addTransformsRecursive = function addTransformsRecursive(node) {
|
|
29187
|
+
if (node.uuid) {
|
|
29188
|
+
var obj = _this3.sceneViewer.scene.getObjectByProperty('uuid', node.uuid);
|
|
29189
|
+
if (obj) {
|
|
29190
|
+
parts.push("".concat(node.uuid, ":").concat(_this3._matrixHash(obj)));
|
|
29191
|
+
} else {
|
|
29192
|
+
var _p$x, _p$y, _p$z;
|
|
29193
|
+
// Object only in data, not in scene — include its serialised position
|
|
29194
|
+
var p = node.position || {};
|
|
29195
|
+
parts.push("".concat(node.uuid, ":").concat(((_p$x = p.x) !== null && _p$x !== void 0 ? _p$x : 0).toFixed(5), ",").concat(((_p$y = p.y) !== null && _p$y !== void 0 ? _p$y : 0).toFixed(5), ",").concat(((_p$z = p.z) !== null && _p$z !== void 0 ? _p$z : 0).toFixed(5)));
|
|
29168
29196
|
}
|
|
29169
|
-
} catch (err) {
|
|
29170
|
-
_iterator.e(err);
|
|
29171
|
-
} finally {
|
|
29172
|
-
_iterator.f();
|
|
29173
29197
|
}
|
|
29198
|
+
|
|
29199
|
+
// Handle both flattened array and nested Three.js JSON structures
|
|
29200
|
+
var children = node.children || node.object && node.object.children;
|
|
29201
|
+
if (children && Array.isArray(children)) {
|
|
29202
|
+
children.forEach(_addTransformsRecursive);
|
|
29203
|
+
}
|
|
29204
|
+
};
|
|
29205
|
+
if (sceneData) {
|
|
29206
|
+
_addTransformsRecursive(sceneData);
|
|
29174
29207
|
}
|
|
29175
29208
|
return parts.join('|');
|
|
29176
29209
|
}
|
|
29177
29210
|
|
|
29178
29211
|
/**
|
|
29179
|
-
* Enrich
|
|
29180
|
-
*
|
|
29181
|
-
*
|
|
29182
|
-
* Uses _bboxCache to avoid recomputing filtered / io-device bboxes
|
|
29183
|
-
* when the underlying object's world matrix has not changed.
|
|
29184
|
-
*
|
|
29185
|
-
* @param {Object} sceneData - Original scene data
|
|
29186
|
-
* @returns {Object} Enriched scene data (shallow copy with modifications)
|
|
29212
|
+
* Enrich scene data with world-space bounding boxes and positions for collision avoidance
|
|
29213
|
+
* @param {Object|Array} sceneData - Original scene data or array of children
|
|
29214
|
+
* @returns {Object|Array} Enriched scene data (shallow copy with modifications)
|
|
29187
29215
|
* @private
|
|
29188
29216
|
*/
|
|
29189
29217
|
}, {
|
|
29190
29218
|
key: "_enrichSceneDataWithBoundingBoxes",
|
|
29191
29219
|
value: function _enrichSceneDataWithBoundingBoxes(sceneData) {
|
|
29192
|
-
var
|
|
29193
|
-
|
|
29194
|
-
|
|
29195
|
-
|
|
29196
|
-
|
|
29197
|
-
return
|
|
29198
|
-
|
|
29199
|
-
|
|
29200
|
-
|
|
29201
|
-
|
|
29202
|
-
|
|
29203
|
-
|
|
29204
|
-
|
|
29205
|
-
|
|
29220
|
+
var _this4 = this;
|
|
29221
|
+
if (!sceneData) return sceneData;
|
|
29222
|
+
|
|
29223
|
+
// Recursive helper to enrich a node and its children
|
|
29224
|
+
var _enrichNode = function enrichNode(node) {
|
|
29225
|
+
if (!node) return node;
|
|
29226
|
+
var enrichedNode = _objectSpread2({}, node);
|
|
29227
|
+
|
|
29228
|
+
// Skip computed objects ( elbows etc )
|
|
29229
|
+
if (node.userData && (node.userData.isComputed === true || node.userData.objectType === 'elbow')) {
|
|
29230
|
+
return node;
|
|
29231
|
+
}
|
|
29232
|
+
|
|
29233
|
+
// ── Enrich Segments ──
|
|
29234
|
+
if (node.userData && node.userData.objectType === 'segment') {
|
|
29235
|
+
var segmentObject = _this4.sceneViewer.scene.getObjectByProperty('uuid', node.uuid);
|
|
29206
29236
|
if (segmentObject) {
|
|
29207
|
-
|
|
29208
|
-
var
|
|
29209
|
-
var cached = _this3._bboxCache.get(child.uuid);
|
|
29237
|
+
var hash = _this4._matrixHash(segmentObject);
|
|
29238
|
+
var cached = _this4._bboxCache.get(node.uuid);
|
|
29210
29239
|
if (cached && cached.matrixHash === hash && cached.segmentBBox) {
|
|
29211
|
-
|
|
29212
|
-
|
|
29213
|
-
worldBoundingBox: cached.segmentBBox
|
|
29214
|
-
})
|
|
29240
|
+
enrichedNode.userData = _objectSpread2(_objectSpread2({}, node.userData), {}, {
|
|
29241
|
+
worldBoundingBox: cached.segmentBBox
|
|
29215
29242
|
});
|
|
29216
|
-
}
|
|
29217
|
-
|
|
29218
|
-
|
|
29219
|
-
|
|
29220
|
-
|
|
29221
|
-
|
|
29222
|
-
|
|
29223
|
-
|
|
29224
|
-
|
|
29225
|
-
|
|
29226
|
-
|
|
29227
|
-
matrixHash: hash,
|
|
29228
|
-
segmentBBox: bboxData
|
|
29229
|
-
});
|
|
29230
|
-
return _objectSpread2(_objectSpread2({}, child), {}, {
|
|
29231
|
-
userData: _objectSpread2(_objectSpread2({}, child.userData), {}, {
|
|
29243
|
+
} else {
|
|
29244
|
+
var worldBBox = new THREE__namespace.Box3().setFromObject(segmentObject);
|
|
29245
|
+
var bboxData = {
|
|
29246
|
+
min: [worldBBox.min.x, worldBBox.min.y, worldBBox.min.z],
|
|
29247
|
+
max: [worldBBox.max.x, worldBBox.max.y, worldBBox.max.z]
|
|
29248
|
+
};
|
|
29249
|
+
_this4._bboxCache.set(node.uuid, {
|
|
29250
|
+
matrixHash: hash,
|
|
29251
|
+
segmentBBox: bboxData
|
|
29252
|
+
});
|
|
29253
|
+
enrichedNode.userData = _objectSpread2(_objectSpread2({}, node.userData), {}, {
|
|
29232
29254
|
worldBoundingBox: bboxData
|
|
29233
|
-
})
|
|
29234
|
-
}
|
|
29235
|
-
} else {
|
|
29236
|
-
console.warn("\u26A0\uFE0F Could not find segment object in scene: ".concat(child.uuid));
|
|
29255
|
+
});
|
|
29256
|
+
}
|
|
29237
29257
|
}
|
|
29238
29258
|
}
|
|
29239
29259
|
|
|
29240
|
-
// Enrich
|
|
29241
|
-
if (
|
|
29242
|
-
|
|
29243
|
-
var componentObject = _this3.sceneViewer.scene.getObjectByProperty('uuid', child.uuid);
|
|
29260
|
+
// ── Enrich Components ──
|
|
29261
|
+
else if (node.userData && node.userData.objectType === 'component') {
|
|
29262
|
+
var componentObject = _this4.sceneViewer.scene.getObjectByProperty('uuid', node.uuid);
|
|
29244
29263
|
if (componentObject) {
|
|
29245
|
-
|
|
29246
|
-
var _hash =
|
|
29247
|
-
var _cached =
|
|
29264
|
+
componentObject.updateMatrixWorld(true);
|
|
29265
|
+
var _hash = _this4._matrixHash(componentObject);
|
|
29266
|
+
var _cached = _this4._bboxCache.get(node.uuid);
|
|
29248
29267
|
if (_cached && _cached.matrixHash === _hash && _cached.filteredBBox) {
|
|
29249
|
-
|
|
29250
|
-
|
|
29251
|
-
|
|
29252
|
-
|
|
29253
|
-
|
|
29268
|
+
enrichedNode.position = {
|
|
29269
|
+
x: componentObject.position.x,
|
|
29270
|
+
y: componentObject.position.y,
|
|
29271
|
+
z: componentObject.position.z
|
|
29272
|
+
};
|
|
29273
|
+
enrichedNode.rotation = {
|
|
29274
|
+
x: THREE__namespace.MathUtils.radToDeg(componentObject.rotation.x),
|
|
29275
|
+
y: THREE__namespace.MathUtils.radToDeg(componentObject.rotation.y),
|
|
29276
|
+
z: THREE__namespace.MathUtils.radToDeg(componentObject.rotation.z)
|
|
29277
|
+
};
|
|
29278
|
+
enrichedNode.userData = _objectSpread2(_objectSpread2({}, node.userData), {}, {
|
|
29279
|
+
worldBoundingBox: _cached.filteredBBox,
|
|
29280
|
+
position: [componentObject.position.x, componentObject.position.y, componentObject.position.z]
|
|
29254
29281
|
});
|
|
29255
|
-
|
|
29256
|
-
|
|
29257
|
-
|
|
29258
|
-
|
|
29259
|
-
|
|
29260
|
-
|
|
29261
|
-
if (existingIndex >= 0) {
|
|
29262
|
-
_enrichedChild.children[existingIndex] = _objectSpread2(_objectSpread2({}, _enrichedChild.children[existingIndex]), {}, {
|
|
29263
|
-
userData: _objectSpread2(_objectSpread2({}, _enrichedChild.children[existingIndex].userData), {}, {
|
|
29264
|
-
objectType: 'io-device',
|
|
29265
|
-
worldBoundingBox: deviceBBox.worldBoundingBox
|
|
29266
|
-
})
|
|
29267
|
-
});
|
|
29268
|
-
} else {
|
|
29269
|
-
_enrichedChild.children.push({
|
|
29270
|
-
uuid: deviceBBox.uuid,
|
|
29271
|
-
userData: _objectSpread2(_objectSpread2({}, deviceBBox.userData), {}, {
|
|
29272
|
-
worldBoundingBox: deviceBBox.worldBoundingBox
|
|
29273
|
-
}),
|
|
29274
|
-
children: []
|
|
29275
|
-
});
|
|
29276
|
-
}
|
|
29282
|
+
|
|
29283
|
+
// Re-merge cached connectors and devices if they exist
|
|
29284
|
+
if (!enrichedNode.children) enrichedNode.children = [];
|
|
29285
|
+
if (_cached.connectorBBoxes) {
|
|
29286
|
+
_cached.connectorBBoxes.forEach(function (conn) {
|
|
29287
|
+
return _this4._mergeEnrichedChild(enrichedNode.children, conn);
|
|
29277
29288
|
});
|
|
29278
29289
|
}
|
|
29279
|
-
|
|
29280
|
-
|
|
29281
|
-
|
|
29282
|
-
if (!_enrichedChild.children) _enrichedChild.children = [];
|
|
29283
|
-
_cached.connectorBBoxes.forEach(function (connBBox) {
|
|
29284
|
-
var existingIndex = _enrichedChild.children.findIndex(function (c) {
|
|
29285
|
-
return c.uuid === connBBox.uuid;
|
|
29286
|
-
});
|
|
29287
|
-
if (existingIndex >= 0) {
|
|
29288
|
-
_enrichedChild.children[existingIndex] = _objectSpread2(_objectSpread2({}, _enrichedChild.children[existingIndex]), {}, {
|
|
29289
|
-
userData: _objectSpread2(_objectSpread2({}, _enrichedChild.children[existingIndex].userData), {}, {
|
|
29290
|
-
worldBoundingBox: connBBox.worldBoundingBox
|
|
29291
|
-
})
|
|
29292
|
-
});
|
|
29293
|
-
} else {
|
|
29294
|
-
_enrichedChild.children.push({
|
|
29295
|
-
uuid: connBBox.uuid,
|
|
29296
|
-
userData: _objectSpread2(_objectSpread2({}, connBBox.userData), {}, {
|
|
29297
|
-
worldBoundingBox: connBBox.worldBoundingBox
|
|
29298
|
-
}),
|
|
29299
|
-
children: []
|
|
29300
|
-
});
|
|
29301
|
-
}
|
|
29290
|
+
if (_cached.ioDeviceBBoxes) {
|
|
29291
|
+
_cached.ioDeviceBBoxes.forEach(function (dev) {
|
|
29292
|
+
return _this4._mergeEnrichedChild(enrichedNode.children, dev);
|
|
29302
29293
|
});
|
|
29303
29294
|
}
|
|
29304
|
-
|
|
29295
|
+
} else {
|
|
29296
|
+
var filteredBBox = computeFilteredBoundingBox(componentObject, ['io-device', 'connector']);
|
|
29297
|
+
var _bboxData = {
|
|
29298
|
+
min: [filteredBBox.min.x, filteredBBox.min.y, filteredBBox.min.z],
|
|
29299
|
+
max: [filteredBBox.max.x, filteredBBox.max.y, filteredBBox.max.z]
|
|
29300
|
+
};
|
|
29301
|
+
enrichedNode.position = {
|
|
29302
|
+
x: componentObject.position.x,
|
|
29303
|
+
y: componentObject.position.y,
|
|
29304
|
+
z: componentObject.position.z
|
|
29305
|
+
};
|
|
29306
|
+
enrichedNode.rotation = {
|
|
29307
|
+
x: THREE__namespace.MathUtils.radToDeg(componentObject.rotation.x),
|
|
29308
|
+
y: THREE__namespace.MathUtils.radToDeg(componentObject.rotation.y),
|
|
29309
|
+
z: THREE__namespace.MathUtils.radToDeg(componentObject.rotation.z)
|
|
29310
|
+
};
|
|
29311
|
+
enrichedNode.userData = _objectSpread2(_objectSpread2({}, node.userData), {}, {
|
|
29312
|
+
worldBoundingBox: _bboxData,
|
|
29313
|
+
position: [componentObject.position.x, componentObject.position.y, componentObject.position.z]
|
|
29314
|
+
});
|
|
29315
|
+
var connectorBBoxes = computeConnectorBoundingBoxes(componentObject);
|
|
29316
|
+
var ioDeviceBBoxes = computeIODeviceBoundingBoxes(componentObject);
|
|
29317
|
+
if (!enrichedNode.children) enrichedNode.children = [];
|
|
29318
|
+
connectorBBoxes.forEach(function (conn) {
|
|
29319
|
+
return _this4._mergeEnrichedChild(enrichedNode.children, conn);
|
|
29320
|
+
});
|
|
29321
|
+
ioDeviceBBoxes.forEach(function (dev) {
|
|
29322
|
+
return _this4._mergeEnrichedChild(enrichedNode.children, dev);
|
|
29323
|
+
});
|
|
29324
|
+
_this4._bboxCache.set(node.uuid, {
|
|
29325
|
+
matrixHash: _hash,
|
|
29326
|
+
filteredBBox: _bboxData,
|
|
29327
|
+
ioDeviceBBoxes: ioDeviceBBoxes,
|
|
29328
|
+
connectorBBoxes: connectorBBoxes
|
|
29329
|
+
});
|
|
29305
29330
|
}
|
|
29331
|
+
}
|
|
29332
|
+
}
|
|
29306
29333
|
|
|
29307
|
-
|
|
29308
|
-
|
|
29309
|
-
|
|
29310
|
-
|
|
29311
|
-
|
|
29312
|
-
|
|
29313
|
-
|
|
29334
|
+
// ── Enrich Standalone Objects (Gateways/Connectors) ──
|
|
29335
|
+
else if (node.userData && (node.userData.objectType === 'gateway' || node.userData.objectType === 'connector')) {
|
|
29336
|
+
var _node$userData;
|
|
29337
|
+
var object = _this4.sceneViewer.scene.getObjectByProperty('uuid', node.uuid) || _this4.sceneViewer.scene.getObjectByProperty('uuid', (_node$userData = node.userData) === null || _node$userData === void 0 ? void 0 : _node$userData.originalUuid);
|
|
29338
|
+
if (object) {
|
|
29339
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
29340
|
+
object.getWorldPosition(worldPos);
|
|
29341
|
+
enrichedNode.position = {
|
|
29342
|
+
x: worldPos.x,
|
|
29343
|
+
y: worldPos.y,
|
|
29344
|
+
z: worldPos.z
|
|
29314
29345
|
};
|
|
29315
|
-
|
|
29316
|
-
|
|
29317
|
-
var enrichedChild = _objectSpread2(_objectSpread2({}, child), {}, {
|
|
29318
|
-
userData: _objectSpread2(_objectSpread2({}, child.userData), {}, {
|
|
29319
|
-
worldBoundingBox: _bboxData
|
|
29320
|
-
})
|
|
29346
|
+
enrichedNode.userData = _objectSpread2(_objectSpread2({}, node.userData), {}, {
|
|
29347
|
+
position: [worldPos.x, worldPos.y, worldPos.z]
|
|
29321
29348
|
});
|
|
29322
29349
|
|
|
29323
|
-
//
|
|
29324
|
-
|
|
29325
|
-
|
|
29326
|
-
|
|
29327
|
-
|
|
29328
|
-
|
|
29329
|
-
}
|
|
29330
|
-
|
|
29331
|
-
// Inject io-device entries with their own worldBoundingBox
|
|
29332
|
-
ioDeviceBBoxes.forEach(function (deviceBBox) {
|
|
29333
|
-
var existingIndex = enrichedChild.children.findIndex(function (c) {
|
|
29334
|
-
return c.uuid === deviceBBox.uuid;
|
|
29335
|
-
});
|
|
29336
|
-
if (existingIndex >= 0) {
|
|
29337
|
-
enrichedChild.children[existingIndex] = _objectSpread2(_objectSpread2({}, enrichedChild.children[existingIndex]), {}, {
|
|
29338
|
-
userData: _objectSpread2(_objectSpread2({}, enrichedChild.children[existingIndex].userData), {}, {
|
|
29339
|
-
objectType: 'io-device',
|
|
29340
|
-
worldBoundingBox: deviceBBox.worldBoundingBox
|
|
29341
|
-
})
|
|
29342
|
-
});
|
|
29343
|
-
} else {
|
|
29344
|
-
enrichedChild.children.push({
|
|
29345
|
-
uuid: deviceBBox.uuid,
|
|
29346
|
-
userData: _objectSpread2(_objectSpread2({}, deviceBBox.userData), {}, {
|
|
29347
|
-
worldBoundingBox: deviceBBox.worldBoundingBox
|
|
29348
|
-
}),
|
|
29349
|
-
children: []
|
|
29350
|
-
});
|
|
29351
|
-
}
|
|
29352
|
-
console.log("\uD83D\uDCE6 Injected io-device bbox for ".concat(deviceBBox.uuid, ": min=[").concat(deviceBBox.worldBoundingBox.min.map(function (v) {
|
|
29353
|
-
return v.toFixed(2);
|
|
29354
|
-
}).join(', '), "], max=[").concat(deviceBBox.worldBoundingBox.max.map(function (v) {
|
|
29355
|
-
return v.toFixed(2);
|
|
29356
|
-
}).join(', '), "]"));
|
|
29357
|
-
});
|
|
29358
|
-
console.log("\uD83D\uDCE6 Injected ".concat(ioDeviceBBoxes.length, " io-device bounding box(es) for component ").concat(child.uuid));
|
|
29350
|
+
// If it's a connector, also sync direction
|
|
29351
|
+
if (node.userData.objectType === 'connector') {
|
|
29352
|
+
var worldDir = new THREE__namespace.Vector3(0, 0, 1);
|
|
29353
|
+
if (node.userData.direction) worldDir.set(node.userData.direction[0], node.userData.direction[1], node.userData.direction[2]);
|
|
29354
|
+
worldDir.applyQuaternion(object.getWorldQuaternion(new THREE__namespace.Quaternion())).normalize();
|
|
29355
|
+
enrichedNode.userData.direction = [worldDir.x, worldDir.y, worldDir.z];
|
|
29359
29356
|
}
|
|
29360
|
-
|
|
29361
|
-
// PHASE 2: Enrich Connectors (CRITICAL for pathfinding API)
|
|
29362
|
-
// Also compute world bounding boxes for connectors and inject into children.
|
|
29363
|
-
// This ensures endpoints have world coordinates in sceneDataCopy.
|
|
29364
|
-
var connectorBBoxes = computeConnectorBoundingBoxes(componentObject);
|
|
29365
|
-
if (connectorBBoxes.length > 0) {
|
|
29366
|
-
if (!enrichedChild.children) enrichedChild.children = [];
|
|
29367
|
-
connectorBBoxes.forEach(function (connBBox) {
|
|
29368
|
-
var existingIndex = enrichedChild.children.findIndex(function (c) {
|
|
29369
|
-
return c.uuid === connBBox.uuid;
|
|
29370
|
-
});
|
|
29371
|
-
if (existingIndex >= 0) {
|
|
29372
|
-
enrichedChild.children[existingIndex] = _objectSpread2(_objectSpread2({}, enrichedChild.children[existingIndex]), {}, {
|
|
29373
|
-
userData: _objectSpread2(_objectSpread2({}, enrichedChild.children[existingIndex].userData), {}, {
|
|
29374
|
-
worldBoundingBox: connBBox.worldBoundingBox
|
|
29375
|
-
})
|
|
29376
|
-
});
|
|
29377
|
-
} else {
|
|
29378
|
-
enrichedChild.children.push({
|
|
29379
|
-
uuid: connBBox.uuid,
|
|
29380
|
-
userData: _objectSpread2(_objectSpread2({}, connBBox.userData), {}, {
|
|
29381
|
-
worldBoundingBox: connBBox.worldBoundingBox
|
|
29382
|
-
}),
|
|
29383
|
-
children: []
|
|
29384
|
-
});
|
|
29385
|
-
}
|
|
29386
|
-
});
|
|
29387
|
-
}
|
|
29388
|
-
|
|
29389
|
-
// Store in cache
|
|
29390
|
-
_this3._bboxCache.set(child.uuid, {
|
|
29391
|
-
matrixHash: _hash,
|
|
29392
|
-
filteredBBox: _bboxData,
|
|
29393
|
-
ioDeviceBBoxes: ioDeviceBBoxes,
|
|
29394
|
-
connectorBBoxes: connectorBBoxes
|
|
29395
|
-
});
|
|
29396
|
-
return enrichedChild;
|
|
29397
|
-
} else {
|
|
29398
|
-
console.warn("\u26A0\uFE0F Could not find component object in scene: ".concat(child.uuid));
|
|
29399
29357
|
}
|
|
29400
29358
|
}
|
|
29401
29359
|
|
|
29402
|
-
//
|
|
29403
|
-
|
|
29404
|
-
|
|
29405
|
-
|
|
29360
|
+
// Recurse into children
|
|
29361
|
+
if (node.children && Array.isArray(node.children)) {
|
|
29362
|
+
enrichedNode.children = node.children.map(_enrichNode);
|
|
29363
|
+
}
|
|
29364
|
+
return enrichedNode;
|
|
29365
|
+
};
|
|
29366
|
+
|
|
29367
|
+
// Handle root being an array or object
|
|
29368
|
+
if (Array.isArray(sceneData)) {
|
|
29369
|
+
return sceneData.map(_enrichNode);
|
|
29370
|
+
} else if (sceneData.children && Array.isArray(sceneData.children)) {
|
|
29371
|
+
var enrichedRoot = _objectSpread2({}, sceneData);
|
|
29372
|
+
enrichedRoot.children = sceneData.children.map(_enrichNode);
|
|
29373
|
+
return enrichedRoot;
|
|
29374
|
+
} else {
|
|
29375
|
+
return _enrichNode(sceneData);
|
|
29376
|
+
}
|
|
29406
29377
|
}
|
|
29407
29378
|
|
|
29408
29379
|
/**
|
|
29409
|
-
*
|
|
29380
|
+
* Helper to merge an enriched child (connector/device) into a children array
|
|
29381
|
+
* @private
|
|
29410
29382
|
*/
|
|
29383
|
+
}, {
|
|
29384
|
+
key: "_mergeEnrichedChild",
|
|
29385
|
+
value: function _mergeEnrichedChild(childrenArray, enrichedData) {
|
|
29386
|
+
var existingIndex = childrenArray.findIndex(function (c) {
|
|
29387
|
+
return c.uuid === enrichedData.uuid;
|
|
29388
|
+
});
|
|
29389
|
+
var nodeToMerge = {
|
|
29390
|
+
uuid: enrichedData.uuid,
|
|
29391
|
+
position: {
|
|
29392
|
+
x: enrichedData.userData.position[0],
|
|
29393
|
+
y: enrichedData.userData.position[1],
|
|
29394
|
+
z: enrichedData.userData.position[2]
|
|
29395
|
+
},
|
|
29396
|
+
userData: _objectSpread2(_objectSpread2({}, enrichedData.userData), {}, {
|
|
29397
|
+
worldBoundingBox: enrichedData.worldBoundingBox
|
|
29398
|
+
}),
|
|
29399
|
+
children: []
|
|
29400
|
+
};
|
|
29401
|
+
if (existingIndex >= 0) {
|
|
29402
|
+
childrenArray[existingIndex] = _objectSpread2(_objectSpread2({}, childrenArray[existingIndex]), nodeToMerge);
|
|
29403
|
+
} else {
|
|
29404
|
+
childrenArray.push(nodeToMerge);
|
|
29405
|
+
}
|
|
29406
|
+
}
|
|
29411
29407
|
}, {
|
|
29412
29408
|
key: "_executePathfinding",
|
|
29413
|
-
value:
|
|
29409
|
+
value: function () {
|
|
29414
29410
|
var _executePathfinding2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(sceneData, connections) {
|
|
29415
|
-
var
|
|
29411
|
+
var _this5 = this,
|
|
29416
29412
|
_sceneDataCopy$childr,
|
|
29417
29413
|
_sceneDataCopy$childr2,
|
|
29418
29414
|
_pathfindingResult$pa,
|
|
@@ -29424,6 +29420,12 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29424
29420
|
totalStart,
|
|
29425
29421
|
inputGenStart,
|
|
29426
29422
|
enrichedSceneData,
|
|
29423
|
+
_from$userData,
|
|
29424
|
+
_to$userData,
|
|
29425
|
+
firstConn,
|
|
29426
|
+
findEndpoint,
|
|
29427
|
+
from,
|
|
29428
|
+
to,
|
|
29427
29429
|
connectionsCopy,
|
|
29428
29430
|
sceneDataCopy,
|
|
29429
29431
|
algoStart,
|
|
@@ -29440,6 +29442,10 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29440
29442
|
while (1) switch (_context.n) {
|
|
29441
29443
|
case 0:
|
|
29442
29444
|
options = _args.length > 2 && _args[2] !== undefined ? _args[2] : {};
|
|
29445
|
+
// Fallback to sceneData connections if not explicitly provided (e.g. during transform updates)
|
|
29446
|
+
if (!connections && sceneData && sceneData.connections) {
|
|
29447
|
+
connections = sceneData.connections;
|
|
29448
|
+
}
|
|
29443
29449
|
options.createGateways, _options$context = options.context, context = _options$context === void 0 ? 'Pathfinding' : _options$context;
|
|
29444
29450
|
timers = {};
|
|
29445
29451
|
totalStart = performance.now(); // Create pathfinder instance with configuration only
|
|
@@ -29468,7 +29474,50 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29468
29474
|
console.log("\uD83D\uDD04 Updated matrix world for ".concat(context, " pathfinding execution"));
|
|
29469
29475
|
|
|
29470
29476
|
// Enrich sceneData with worldBoundingBox for segments before deep copy
|
|
29471
|
-
enrichedSceneData = this._enrichSceneDataWithBoundingBoxes(sceneData); //
|
|
29477
|
+
enrichedSceneData = this._enrichSceneDataWithBoundingBoxes(sceneData); // DEBUG: Log first connection endpoints in enriched data
|
|
29478
|
+
if (connections && connections.length > 0 && enrichedSceneData.children) {
|
|
29479
|
+
firstConn = connections[0];
|
|
29480
|
+
findEndpoint = function findEndpoint(uuid) {
|
|
29481
|
+
var _iterator = _createForOfIteratorHelper(enrichedSceneData.children),
|
|
29482
|
+
_step;
|
|
29483
|
+
try {
|
|
29484
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
29485
|
+
var child = _step.value;
|
|
29486
|
+
if (child.uuid === uuid) return child;
|
|
29487
|
+
if (child.children) {
|
|
29488
|
+
var _iterator2 = _createForOfIteratorHelper(child.children),
|
|
29489
|
+
_step2;
|
|
29490
|
+
try {
|
|
29491
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
29492
|
+
var nested = _step2.value;
|
|
29493
|
+
if (nested.uuid === uuid) return nested;
|
|
29494
|
+
}
|
|
29495
|
+
} catch (err) {
|
|
29496
|
+
_iterator2.e(err);
|
|
29497
|
+
} finally {
|
|
29498
|
+
_iterator2.f();
|
|
29499
|
+
}
|
|
29500
|
+
}
|
|
29501
|
+
}
|
|
29502
|
+
} catch (err) {
|
|
29503
|
+
_iterator.e(err);
|
|
29504
|
+
} finally {
|
|
29505
|
+
_iterator.f();
|
|
29506
|
+
}
|
|
29507
|
+
return null;
|
|
29508
|
+
};
|
|
29509
|
+
from = findEndpoint(firstConn.from);
|
|
29510
|
+
to = findEndpoint(firstConn.to);
|
|
29511
|
+
console.log("\uD83D\uDCE1 [DEBUG] Pathfinding from ".concat(firstConn.from, " to ").concat(firstConn.to));
|
|
29512
|
+
if (from) console.log(" From BBox: min=[".concat((_from$userData = from.userData) === null || _from$userData === void 0 || (_from$userData = _from$userData.worldBoundingBox) === null || _from$userData === void 0 || (_from$userData = _from$userData.min) === null || _from$userData === void 0 ? void 0 : _from$userData.map(function (v) {
|
|
29513
|
+
return v.toFixed(2);
|
|
29514
|
+
}), "]"));
|
|
29515
|
+
if (to) console.log(" To BBox: min=[".concat((_to$userData = to.userData) === null || _to$userData === void 0 || (_to$userData = _to$userData.worldBoundingBox) === null || _to$userData === void 0 || (_to$userData = _to$userData.min) === null || _to$userData === void 0 ? void 0 : _to$userData.map(function (v) {
|
|
29516
|
+
return v.toFixed(2);
|
|
29517
|
+
}), "]"));
|
|
29518
|
+
}
|
|
29519
|
+
|
|
29520
|
+
// Deep copy connections and sceneData to prevent pathfinder from mutating the original
|
|
29472
29521
|
connectionsCopy = structuredClone(connections);
|
|
29473
29522
|
sceneDataCopy = structuredClone(enrichedSceneData);
|
|
29474
29523
|
timers.inputGeneration = performance.now() - inputGenStart;
|
|
@@ -29499,7 +29548,7 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29499
29548
|
if (pathfindingResult.paths) {
|
|
29500
29549
|
pathfindingResult.paths.forEach(function (path) {
|
|
29501
29550
|
var pathId = "".concat(path.from, "-->").concat(path.to);
|
|
29502
|
-
|
|
29551
|
+
_this5._getOrCreatePathData(pathId, path.from, path.to);
|
|
29503
29552
|
});
|
|
29504
29553
|
}
|
|
29505
29554
|
timers.pathRendering = performance.now() - renderStart;
|
|
@@ -29532,7 +29581,7 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29532
29581
|
return _executePathfinding2.apply(this, arguments);
|
|
29533
29582
|
}
|
|
29534
29583
|
return _executePathfinding;
|
|
29535
|
-
}()
|
|
29584
|
+
}()
|
|
29536
29585
|
}, {
|
|
29537
29586
|
key: "getSimplifiedSceneData",
|
|
29538
29587
|
value: function getSimplifiedSceneData() {
|
|
@@ -29571,7 +29620,7 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29571
29620
|
}, {
|
|
29572
29621
|
key: "_propagateFlowAttributesAndApplyVisualizations",
|
|
29573
29622
|
value: function _propagateFlowAttributesAndApplyVisualizations(connections, pathfindingResult) {
|
|
29574
|
-
var
|
|
29623
|
+
var _this6 = this,
|
|
29575
29624
|
_this$sceneViewer;
|
|
29576
29625
|
if (!Array.isArray(connections) || !pathfindingResult) return;
|
|
29577
29626
|
|
|
@@ -29599,7 +29648,7 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29599
29648
|
var subPathIds = new Set(originalToSubPaths.get(origId) || []);
|
|
29600
29649
|
subPathIds.add(origId);
|
|
29601
29650
|
subPathIds.forEach(function (subPathId) {
|
|
29602
|
-
var pd =
|
|
29651
|
+
var pd = _this6.pathDataStore.get(subPathId);
|
|
29603
29652
|
if (pd && Object.keys(pd.flowAttributes).length === 0) {
|
|
29604
29653
|
Object.entries(conn.flowAttributes).forEach(function (_ref2) {
|
|
29605
29654
|
var _ref3 = _slicedToArray(_ref2, 2),
|
|
@@ -29663,7 +29712,7 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29663
29712
|
key: "initializePathfinder",
|
|
29664
29713
|
value: (function () {
|
|
29665
29714
|
var _initializePathfinder = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(data, crosscubeTextureSet) {
|
|
29666
|
-
var
|
|
29715
|
+
var _this7 = this;
|
|
29667
29716
|
var pathfindingResult;
|
|
29668
29717
|
return _regenerator().w(function (_context2) {
|
|
29669
29718
|
while (1) switch (_context2.n) {
|
|
@@ -29677,7 +29726,7 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29677
29726
|
data.connections.forEach(function (conn) {
|
|
29678
29727
|
if (conn.flowAttributes && _typeof(conn.flowAttributes) === 'object') {
|
|
29679
29728
|
var pathId = "".concat(conn.from, "-->").concat(conn.to);
|
|
29680
|
-
var pd =
|
|
29729
|
+
var pd = _this7._getOrCreatePathData(pathId, conn.from, conn.to);
|
|
29681
29730
|
Object.entries(conn.flowAttributes).forEach(function (_ref6) {
|
|
29682
29731
|
var _ref7 = _slicedToArray(_ref6, 2),
|
|
29683
29732
|
key = _ref7[0],
|
|
@@ -29795,33 +29844,47 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
29795
29844
|
key: "updatePathfindingAfterTransform",
|
|
29796
29845
|
value: (function () {
|
|
29797
29846
|
var _updatePathfindingAfterTransform = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(currentSceneData) {
|
|
29798
|
-
var
|
|
29847
|
+
var _currentSceneData$sce;
|
|
29848
|
+
var fingerprint, dataRoot, connections, result;
|
|
29799
29849
|
return _regenerator().w(function (_context3) {
|
|
29800
29850
|
while (1) switch (_context3.n) {
|
|
29801
29851
|
case 0:
|
|
29852
|
+
if (!(!currentSceneData || !currentSceneData.scene)) {
|
|
29853
|
+
_context3.n = 1;
|
|
29854
|
+
break;
|
|
29855
|
+
}
|
|
29856
|
+
console.warn('⚠️ updatePathfindingAfterTransform: Invalid scene data');
|
|
29857
|
+
return _context3.a(2, null);
|
|
29858
|
+
case 1:
|
|
29802
29859
|
// ── Skip-unchanged-paths check ──────────────────────────────────
|
|
29803
29860
|
// Ensure matrices are fresh so the fingerprint is accurate.
|
|
29804
29861
|
this.sceneViewer.scene.updateMatrixWorld(true);
|
|
29805
29862
|
fingerprint = this._computePathfindingFingerprint(currentSceneData.scene, currentSceneData.connections);
|
|
29863
|
+
console.log("\uD83D\uDD0D Pathfinding update check. Fingerprint: ".concat(fingerprint.substring(0, 50), "..."));
|
|
29806
29864
|
if (!(fingerprint === this._lastPathfindingFingerprint && this._lastPathfindingResult)) {
|
|
29807
|
-
_context3.n =
|
|
29865
|
+
_context3.n = 2;
|
|
29808
29866
|
break;
|
|
29809
29867
|
}
|
|
29810
29868
|
console.log('⏭️ Pathfinding skipped — inputs unchanged since last run');
|
|
29811
29869
|
return _context3.a(2, this._lastPathfindingResult);
|
|
29812
|
-
case
|
|
29870
|
+
case 2:
|
|
29871
|
+
// Clear the cache for the specific fingerprint mismatch to ensure fresh enrichment
|
|
29872
|
+
this.invalidateBBoxCache();
|
|
29873
|
+
|
|
29813
29874
|
// Remove all existing paths from the scene
|
|
29814
29875
|
this.removeComputedObjects();
|
|
29815
29876
|
console.log('🔄 Starting pathfinding with updated scene data...');
|
|
29816
29877
|
|
|
29817
|
-
//
|
|
29878
|
+
// Robust root discovery for different manifest structures
|
|
29879
|
+
dataRoot = ((_currentSceneData$sce = currentSceneData.scene) === null || _currentSceneData$sce === void 0 ? void 0 : _currentSceneData$sce.object) || currentSceneData.scene || currentSceneData;
|
|
29880
|
+
connections = currentSceneData.connections || []; // Note: Matrix updates and bounding box recomputation now handled in _executePathfinding
|
|
29818
29881
|
// Use shared pathfinding logic (no gateways needed for transform updates)
|
|
29819
|
-
_context3.n =
|
|
29820
|
-
return this._executePathfinding(
|
|
29882
|
+
_context3.n = 3;
|
|
29883
|
+
return this._executePathfinding(dataRoot, connections, {
|
|
29821
29884
|
createGateways: true,
|
|
29822
29885
|
context: 'Transform Update'
|
|
29823
29886
|
});
|
|
29824
|
-
case
|
|
29887
|
+
case 3:
|
|
29825
29888
|
result = _context3.v;
|
|
29826
29889
|
// Re-apply flow attribute colors (new materials are created on each execution)
|
|
29827
29890
|
this._propagateFlowAttributesAndApplyVisualizations(currentSceneData.connections, result);
|
|
@@ -31727,36 +31790,58 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
31727
31790
|
* @param {THREE.Object3D} targetMesh - The mesh whose connectors to preserve
|
|
31728
31791
|
* @param {string} parentUuid - The UUID of the parent component
|
|
31729
31792
|
*/
|
|
31793
|
+
/**
|
|
31794
|
+
* Identifies all connector objects within a model hierarchy and prepares them
|
|
31795
|
+
* to be preserved when the model is replaced or modified.
|
|
31796
|
+
* Uses traverse() to find connectors at any depth in the hierarchy.
|
|
31797
|
+
* @param {THREE.Object3D} targetMesh - The root of the model to search
|
|
31798
|
+
* @param {string} parentUuid - The UUID of the parent component
|
|
31799
|
+
* @returns {Array<THREE.Object3D>} Array of cloned and prepared connector objects
|
|
31800
|
+
*/
|
|
31730
31801
|
}, {
|
|
31731
31802
|
key: "_preserveConnectorChildren",
|
|
31732
31803
|
value: function _preserveConnectorChildren(targetMesh, parentUuid) {
|
|
31733
31804
|
var _this = this;
|
|
31734
31805
|
var connectorChildren = [];
|
|
31735
|
-
|
|
31806
|
+
var connectorIndex = 0;
|
|
31807
|
+
|
|
31808
|
+
// Use traverse to find connectors at ANY depth in the hierarchy
|
|
31809
|
+
targetMesh.traverse(function (child) {
|
|
31736
31810
|
var _child$userData;
|
|
31737
31811
|
var isConnectorGeometry = child.geometry && (child.geometry.uuid === 'CONNECTOR-GEO' || child.geometry.type === 'SphereGeometry' && child.geometry.parameters);
|
|
31738
31812
|
var isConnectorByName = child.name && child.name.toLowerCase().includes('connector');
|
|
31739
|
-
// Also recognise connectors declared via userData (e.g. inline connectors from SAMPLE_1.json
|
|
31740
|
-
// whose geometry may be a fallback BufferGeometry rather than a SphereGeometry).
|
|
31741
31813
|
var isConnectorByUserData = ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'connector';
|
|
31742
31814
|
if (isConnectorGeometry && isConnectorByName || isConnectorByUserData) {
|
|
31815
|
+
connectorIndex++;
|
|
31816
|
+
|
|
31743
31817
|
// Ensure userData exists and has worldBoundingBox
|
|
31744
31818
|
if (!child.userData) child.userData = {};
|
|
31745
31819
|
if (!child.userData.worldBoundingBox) {
|
|
31746
31820
|
child.userData.worldBoundingBox = _this._calculateWorldBoundingBox(child);
|
|
31747
31821
|
}
|
|
31748
31822
|
|
|
31749
|
-
// Clone
|
|
31823
|
+
// Clone the connector
|
|
31750
31824
|
var clonedConnector = child.clone();
|
|
31751
31825
|
|
|
31752
|
-
//
|
|
31753
|
-
//
|
|
31754
|
-
var
|
|
31826
|
+
// CRITICAL: Convert nested world position to root-relative position
|
|
31827
|
+
// This ensures the connector stays in the same place when re-added as a direct child of targetMesh
|
|
31828
|
+
var targetInverse = targetMesh.matrixWorld.clone().invert();
|
|
31829
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
31830
|
+
child.getWorldPosition(worldPos);
|
|
31831
|
+
clonedConnector.position.copy(worldPos.applyMatrix4(targetInverse));
|
|
31832
|
+
|
|
31833
|
+
// Get hardcoded UUID if it exists (e.g. from JSON mesh placeholder)
|
|
31834
|
+
// This ensures compatibility with existing scene JSON naming conventions
|
|
31835
|
+
var existingUuid = getHardcodedUuid(child);
|
|
31836
|
+
|
|
31837
|
+
// Generate fallback UUID only if existing one isn't already parent-prefixed
|
|
31838
|
+
// Format: COMPONENT-UUID-CONNECTOR-INDEX (stable fallback)
|
|
31839
|
+
var connectorUuid = existingUuid && existingUuid.includes(parentUuid) ? existingUuid : "".concat(parentUuid, "-CONNECTOR-").concat(connectorIndex);
|
|
31755
31840
|
clonedConnector.uuid = connectorUuid;
|
|
31756
31841
|
if (child.userData) {
|
|
31757
31842
|
clonedConnector.userData = _objectSpread2({}, child.userData);
|
|
31758
31843
|
|
|
31759
|
-
// Deep copy critical data
|
|
31844
|
+
// Deep copy critical data
|
|
31760
31845
|
if (child.userData.worldBoundingBox) {
|
|
31761
31846
|
var wbb = child.userData.worldBoundingBox;
|
|
31762
31847
|
clonedConnector.userData.worldBoundingBox = {
|
|
@@ -31765,7 +31850,6 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
31765
31850
|
};
|
|
31766
31851
|
}
|
|
31767
31852
|
if (child.userData.direction) {
|
|
31768
|
-
// Handle both array [x,y,z] and object {x,y,z} formats
|
|
31769
31853
|
if (Array.isArray(child.userData.direction)) {
|
|
31770
31854
|
clonedConnector.userData.direction = _toConsumableArray(child.userData.direction);
|
|
31771
31855
|
} else if (_typeof(child.userData.direction) === 'object') {
|
|
@@ -31777,11 +31861,12 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
31777
31861
|
|
|
31778
31862
|
// Set originalUuid to match the actual uuid (maintains consistency)
|
|
31779
31863
|
clonedConnector.userData.originalUuid = connectorUuid;
|
|
31780
|
-
clonedConnector.userData.objectType = child.userData.objectType ||
|
|
31864
|
+
clonedConnector.userData.objectType = child.userData.objectType || 'connector';
|
|
31781
31865
|
}
|
|
31782
31866
|
connectorChildren.push(clonedConnector);
|
|
31783
31867
|
}
|
|
31784
31868
|
});
|
|
31869
|
+
console.log("\uD83D\uDEE1\uFE0F Preserved ".concat(connectorChildren.length, " connector(s) for component ").concat(parentUuid));
|
|
31785
31870
|
return connectorChildren;
|
|
31786
31871
|
}
|
|
31787
31872
|
|
|
@@ -33754,6 +33839,19 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
33754
33839
|
if (!(data !== null && data !== void 0 && (_data$scene2 = data.scene) !== null && _data$scene2 !== void 0 && _data$scene2.children) || !componentDictionary) {
|
|
33755
33840
|
return;
|
|
33756
33841
|
}
|
|
33842
|
+
|
|
33843
|
+
// Collect every connector uuid referenced by the scene's connections so we
|
|
33844
|
+
// can inject connectors under the SAME uuid scheme the scene actually uses.
|
|
33845
|
+
// Two schemes exist in the wild:
|
|
33846
|
+
// - Preferred (runtime add path + minimal export): `${componentUuid}_${dictConnectorUuid}`
|
|
33847
|
+
// - Legacy (older hand-authored scenes): `${componentUuid}-CONNECTOR-${index+1}`
|
|
33848
|
+
var connectionEndpoints = new Set();
|
|
33849
|
+
if (Array.isArray(data.connections)) {
|
|
33850
|
+
data.connections.forEach(function (conn) {
|
|
33851
|
+
if (conn !== null && conn !== void 0 && conn.from) connectionEndpoints.add(conn.from);
|
|
33852
|
+
if (conn !== null && conn !== void 0 && conn.to) connectionEndpoints.add(conn.to);
|
|
33853
|
+
});
|
|
33854
|
+
}
|
|
33757
33855
|
var componentsProcessed = 0;
|
|
33758
33856
|
var connectorsInjected = 0;
|
|
33759
33857
|
data.scene.children.forEach(function (child) {
|
|
@@ -33776,9 +33874,18 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
33776
33874
|
|
|
33777
33875
|
// Deep clone the connector children from the dictionary
|
|
33778
33876
|
child.children = dictEntry.children.map(function (connector, index) {
|
|
33779
|
-
//
|
|
33780
|
-
//
|
|
33781
|
-
|
|
33877
|
+
// Choose the connector uuid that matches the scheme the scene's
|
|
33878
|
+
// connections reference. Prefer `${componentUuid}_${dictConnectorUuid}`
|
|
33879
|
+
// (sandbox add path + minimal export); fall back to the legacy
|
|
33880
|
+
// index-based scheme `${componentUuid}-CONNECTOR-${index+1}` when the
|
|
33881
|
+
// connections reference that form. If neither is referenced (e.g. an
|
|
33882
|
+
// unconnected connector), default to the preferred scheme.
|
|
33883
|
+
var legacyUuid = "".concat(child.uuid, "-CONNECTOR-").concat(index + 1);
|
|
33884
|
+
var preferredUuid = connector.uuid ? "".concat(child.uuid, "_").concat(connector.uuid) : legacyUuid;
|
|
33885
|
+
var connectorUuid = preferredUuid;
|
|
33886
|
+
if (!connectionEndpoints.has(preferredUuid) && connectionEndpoints.has(legacyUuid)) {
|
|
33887
|
+
connectorUuid = legacyUuid;
|
|
33888
|
+
}
|
|
33782
33889
|
|
|
33783
33890
|
// Clone connector with deep copy of userData
|
|
33784
33891
|
var clonedConnector = _objectSpread2(_objectSpread2({}, connector), {}, {
|
|
@@ -34212,24 +34319,29 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
34212
34319
|
children: [] // Initialize children array
|
|
34213
34320
|
};
|
|
34214
34321
|
|
|
34215
|
-
// Collect children that are connectors
|
|
34216
|
-
|
|
34217
|
-
|
|
34218
|
-
|
|
34219
|
-
|
|
34220
|
-
|
|
34221
|
-
|
|
34222
|
-
|
|
34223
|
-
|
|
34224
|
-
|
|
34225
|
-
|
|
34226
|
-
|
|
34227
|
-
|
|
34228
|
-
|
|
34229
|
-
|
|
34230
|
-
|
|
34231
|
-
|
|
34232
|
-
|
|
34322
|
+
// Collect children that are connectors (using traverse to find deep children in models)
|
|
34323
|
+
componentModel.traverse(function (child) {
|
|
34324
|
+
if (child.userData && child.userData.objectType === 'connector') {
|
|
34325
|
+
// Calculate position relative to component root
|
|
34326
|
+
// This ensures that when we re-add it as a direct child of the component,
|
|
34327
|
+
// it maintains the same world position relative to the component.
|
|
34328
|
+
var componentMatrixWorldInverse = componentModel.matrixWorld.clone().invert();
|
|
34329
|
+
var childWorldPos = new THREE__namespace.Vector3();
|
|
34330
|
+
child.getWorldPosition(childWorldPos);
|
|
34331
|
+
var relativePos = childWorldPos.applyMatrix4(componentMatrixWorldInverse);
|
|
34332
|
+
componentSceneData.children.push({
|
|
34333
|
+
uuid: child.uuid,
|
|
34334
|
+
name: child.name,
|
|
34335
|
+
type: 'Mesh',
|
|
34336
|
+
position: {
|
|
34337
|
+
x: relativePos.x,
|
|
34338
|
+
y: relativePos.y,
|
|
34339
|
+
z: relativePos.z
|
|
34340
|
+
},
|
|
34341
|
+
userData: _objectSpread2({}, child.userData)
|
|
34342
|
+
});
|
|
34343
|
+
}
|
|
34344
|
+
});
|
|
34233
34345
|
|
|
34234
34346
|
// Add the component to the scene data
|
|
34235
34347
|
if (!currentSceneData.scene.children) {
|
|
@@ -39876,17 +39988,19 @@ var CentralPlantInternals = /*#__PURE__*/function () {
|
|
|
39876
39988
|
* @param {string} componentId - The UUID of the component to translate
|
|
39877
39989
|
* @param {string} axis - The axis to translate on ('x', 'y', or 'z')
|
|
39878
39990
|
* @param {number} value - The value to translate by
|
|
39991
|
+
* @param {boolean} [skipPathUpdate=false] - Whether to skip triggering pathfinding
|
|
39879
39992
|
* @returns {boolean} True if translation was successful, false otherwise
|
|
39880
39993
|
*/
|
|
39881
39994
|
}, {
|
|
39882
39995
|
key: "translateComponent",
|
|
39883
39996
|
value: function translateComponent(componentId, axis, value) {
|
|
39884
39997
|
var _this$centralPlant$ma;
|
|
39998
|
+
var skipPathUpdate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
39885
39999
|
if (!((_this$centralPlant$ma = this.centralPlant.managers) !== null && _this$centralPlant$ma !== void 0 && _this$centralPlant$ma.transformOperationsManager)) {
|
|
39886
40000
|
console.error('❌ translateComponent(): TransformOperationsManager not available');
|
|
39887
40001
|
return false;
|
|
39888
40002
|
}
|
|
39889
|
-
return this.centralPlant.managers.transformOperationsManager.translateComponent(componentId, axis, value);
|
|
40003
|
+
return this.centralPlant.managers.transformOperationsManager.translateComponent(componentId, axis, value, skipPathUpdate);
|
|
39890
40004
|
}
|
|
39891
40005
|
|
|
39892
40006
|
/**
|
|
@@ -39978,7 +40092,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
|
|
|
39978
40092
|
} else if (objectType === 'gateway') {
|
|
39979
40093
|
success = this.translateGateway(objectId, axis, value);
|
|
39980
40094
|
} else if (objectType === 'component') {
|
|
39981
|
-
success = this.translateComponent(objectId, axis, value);
|
|
40095
|
+
success = this.translateComponent(objectId, axis, value, skipPathUpdate);
|
|
39982
40096
|
} else {
|
|
39983
40097
|
result.errors.push("Unknown object type: ".concat(objectType, " (").concat(objectId, ")"));
|
|
39984
40098
|
console.warn("\u26A0\uFE0F Unknown object type: ".concat(objectType, " for ").concat(objectId));
|
|
@@ -41011,7 +41125,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
41011
41125
|
* Initialize the CentralPlant manager
|
|
41012
41126
|
*
|
|
41013
41127
|
* @constructor
|
|
41014
|
-
* @version 0.3.
|
|
41128
|
+
* @version 0.3.49
|
|
41015
41129
|
* @updated 2025-10-22
|
|
41016
41130
|
*
|
|
41017
41131
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -41341,7 +41455,8 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
41341
41455
|
}, {
|
|
41342
41456
|
key: "translate",
|
|
41343
41457
|
value: function translate(componentId, axis, value) {
|
|
41344
|
-
|
|
41458
|
+
var skipPathUpdate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
41459
|
+
return this.internals.translateComponent(componentId, axis, value, skipPathUpdate);
|
|
41345
41460
|
}
|
|
41346
41461
|
|
|
41347
41462
|
/**
|
|
@@ -42039,18 +42154,19 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
42039
42154
|
return [];
|
|
42040
42155
|
}
|
|
42041
42156
|
|
|
42042
|
-
//
|
|
42043
|
-
|
|
42044
|
-
|
|
42045
|
-
|
|
42046
|
-
|
|
42047
|
-
|
|
42048
|
-
|
|
42049
|
-
|
|
42050
|
-
|
|
42051
|
-
}
|
|
42052
|
-
}
|
|
42053
|
-
}
|
|
42157
|
+
// Recursive search for connector IDs
|
|
42158
|
+
var _findConnectorIds = function findConnectorIds(nodes) {
|
|
42159
|
+
if (!nodes || !Array.isArray(nodes)) return;
|
|
42160
|
+
nodes.forEach(function (node) {
|
|
42161
|
+
if (node.userData && node.userData.objectType === 'connector' && node.uuid) {
|
|
42162
|
+
allConnectorIds.push(node.uuid);
|
|
42163
|
+
}
|
|
42164
|
+
if (node.children && Array.isArray(node.children)) {
|
|
42165
|
+
_findConnectorIds(node.children);
|
|
42166
|
+
}
|
|
42167
|
+
});
|
|
42168
|
+
};
|
|
42169
|
+
_findConnectorIds(sceneData.scene.children);
|
|
42054
42170
|
|
|
42055
42171
|
// Get existing connections
|
|
42056
42172
|
var existingConnections = this.getConnections();
|
|
@@ -42080,28 +42196,28 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
42080
42196
|
* const infos = centralPlant.getAvailableConnectionsInfo()
|
|
42081
42197
|
* // [{ id: 'PUMP-1-CONNECTOR-1', flow: 'out' }, ...]
|
|
42082
42198
|
*/
|
|
42199
|
+
/**
|
|
42200
|
+
* Get all connectors in the scene that are currently available (not used in a connection).
|
|
42201
|
+
* Searches the active Three.js scene directly for the most accurate results.
|
|
42202
|
+
* @returns {Array<{id: string, flow: string}>} Array of connector info objects
|
|
42203
|
+
* @since 0.1.72 (Updated to search Three.js scene directly)
|
|
42204
|
+
*/
|
|
42083
42205
|
}, {
|
|
42084
42206
|
key: "getAvailableConnectionsInfo",
|
|
42085
42207
|
value: function getAvailableConnectionsInfo() {
|
|
42086
|
-
if (!this.sceneViewer || !this.sceneViewer.
|
|
42087
|
-
console.warn('⚠️ getAvailableConnectionsInfo(): Scene viewer or
|
|
42088
|
-
return [];
|
|
42089
|
-
}
|
|
42090
|
-
var sceneData = this.sceneViewer.currentSceneData;
|
|
42091
|
-
if (!sceneData.scene || !sceneData.scene.children) {
|
|
42092
|
-
console.warn('⚠️ getAvailableConnectionsInfo(): Invalid scene data structure');
|
|
42208
|
+
if (!this.sceneViewer || !this.sceneViewer.scene) {
|
|
42209
|
+
console.warn('⚠️ getAvailableConnectionsInfo(): Scene viewer or scene not available');
|
|
42093
42210
|
return [];
|
|
42094
42211
|
}
|
|
42095
42212
|
var allConnectorInfos = [];
|
|
42096
|
-
|
|
42097
|
-
|
|
42098
|
-
|
|
42099
|
-
|
|
42100
|
-
|
|
42101
|
-
|
|
42102
|
-
|
|
42103
|
-
|
|
42104
|
-
}
|
|
42213
|
+
|
|
42214
|
+
// Search the Three.js scene directly for connectors
|
|
42215
|
+
// This is more reliable than searching currentSceneData which might be stale
|
|
42216
|
+
this.sceneViewer.scene.traverse(function (node) {
|
|
42217
|
+
if (node.userData && node.userData.objectType === 'connector' && node.uuid) {
|
|
42218
|
+
allConnectorInfos.push({
|
|
42219
|
+
id: node.uuid,
|
|
42220
|
+
flow: node.userData.flow || 'bi'
|
|
42105
42221
|
});
|
|
42106
42222
|
}
|
|
42107
42223
|
});
|
|
@@ -42123,30 +42239,29 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
42123
42239
|
* const result = centralPlant.validateConnections()
|
|
42124
42240
|
* result.invalid.forEach(({ connection, reason }) => console.warn(reason, connection))
|
|
42125
42241
|
*/
|
|
42242
|
+
/**
|
|
42243
|
+
* Validate all connections in the current scene for flow direction compatibility.
|
|
42244
|
+
* Searches the active Three.js scene for connector flow markers.
|
|
42245
|
+
* @returns {{ valid: Array<Object>, invalid: Array<{connection: Object, reason: string}> }}
|
|
42246
|
+
* @since 0.1.72 (Updated to search Three.js scene directly)
|
|
42247
|
+
*/
|
|
42126
42248
|
}, {
|
|
42127
42249
|
key: "validateConnections",
|
|
42128
42250
|
value: function validateConnections() {
|
|
42129
|
-
if (!this.sceneViewer || !this.sceneViewer.
|
|
42130
|
-
console.warn('⚠️ validateConnections(): Scene viewer or
|
|
42251
|
+
if (!this.sceneViewer || !this.sceneViewer.scene) {
|
|
42252
|
+
console.warn('⚠️ validateConnections(): Scene viewer or scene not available');
|
|
42131
42253
|
return {
|
|
42132
42254
|
valid: [],
|
|
42133
42255
|
invalid: []
|
|
42134
42256
|
};
|
|
42135
42257
|
}
|
|
42136
42258
|
var connections = this.getConnections();
|
|
42137
|
-
var sceneData = this.sceneViewer.currentSceneData;
|
|
42138
42259
|
|
|
42139
|
-
// Build lookup map: connectorId → flow
|
|
42260
|
+
// Build lookup map: connectorId → flow from the Three.js scene
|
|
42140
42261
|
var flowMap = {};
|
|
42141
|
-
|
|
42142
|
-
|
|
42143
|
-
|
|
42144
|
-
if (component.children && Array.isArray(component.children)) {
|
|
42145
|
-
component.children.forEach(function (child) {
|
|
42146
|
-
if (child.userData && child.userData.objectType === 'connector' && child.uuid) {
|
|
42147
|
-
flowMap[child.uuid] = child.userData.flow || 'bi';
|
|
42148
|
-
}
|
|
42149
|
-
});
|
|
42262
|
+
this.sceneViewer.scene.traverse(function (node) {
|
|
42263
|
+
if (node.userData && node.userData.objectType === 'connector' && node.uuid) {
|
|
42264
|
+
flowMap[node.uuid] = node.userData.flow || 'bi';
|
|
42150
42265
|
}
|
|
42151
42266
|
});
|
|
42152
42267
|
var valid = [];
|
|
@@ -44114,7 +44229,7 @@ var sceneViewer = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
44114
44229
|
this.centralPlant.attachToComponent();
|
|
44115
44230
|
|
|
44116
44231
|
// Sync our managers tracking object after attachment
|
|
44117
|
-
managerKeys = ['threeJSResourceManager', 'performanceMonitorManager', 'settingsManager', 'sceneExportManager', 'componentManager', 'sceneInitializationManager', 'environmentManager', 'keyboardControlsManager', 'pathfindingManager', 'pathFlowManager', 'ioBehaviorManager', 'ioOutlineManager', 'sceneOperationsManager', 'animationManager', 'cameraControlsManager', 'componentDragManager', 'tooltipsManager', 'componentTooltipManager']; // Populate our managers tracking object
|
|
44232
|
+
managerKeys = ['threeJSResourceManager', 'performanceMonitorManager', 'settingsManager', 'sceneExportManager', 'componentManager', 'transformOperationsManager', 'sceneInitializationManager', 'environmentManager', 'keyboardControlsManager', 'pathfindingManager', 'pathFlowManager', 'ioBehaviorManager', 'ioOutlineManager', 'sceneOperationsManager', 'animationManager', 'cameraControlsManager', 'componentDragManager', 'tooltipsManager', 'componentTooltipManager']; // Populate our managers tracking object
|
|
44118
44233
|
managerKeys.forEach(function (key) {
|
|
44119
44234
|
if (_this2[key]) {
|
|
44120
44235
|
_this2.managers[key] = _this2[key];
|