@2112-lab/central-plant 0.3.5 → 0.3.6
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 +162 -176
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/modelManager.js +7 -0
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +62 -132
- package/dist/cjs/src/managers/scene/viewport2DManager.js +88 -40
- package/dist/cjs/src/utils/sceneClearingUtility.js +2 -2
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/scene/modelManager.js +7 -0
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +63 -133
- package/dist/esm/src/managers/scene/viewport2DManager.js +88 -40
- package/dist/esm/src/utils/sceneClearingUtility.js +2 -2
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -29828,6 +29828,13 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
29828
29828
|
// Update both the JSON data object AND the live scene object
|
|
29829
29829
|
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
29830
29830
|
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
29831
|
+
// Snapshot the object's local position so viewport2DManager can compute
|
|
29832
|
+
// world-bbox updates via a fast O(1) position delta instead of re-traversing geometry
|
|
29833
|
+
glbModel.userData._wbbBasePosition = {
|
|
29834
|
+
x: glbModel.position.x,
|
|
29835
|
+
y: glbModel.position.y,
|
|
29836
|
+
z: glbModel.position.z
|
|
29837
|
+
};
|
|
29831
29838
|
});
|
|
29832
29839
|
|
|
29833
29840
|
// Dispatch completion event
|
|
@@ -30127,10 +30134,10 @@ var SceneClearingUtility = /*#__PURE__*/function () {
|
|
|
30127
30134
|
throw new Error('Scene not available for clearing');
|
|
30128
30135
|
case 1:
|
|
30129
30136
|
componentsToRemove = [];
|
|
30130
|
-
scene = this.sceneViewer.scene; // Collect
|
|
30137
|
+
scene = this.sceneViewer.scene; // Collect component, segment, and gateway objects
|
|
30131
30138
|
scene.traverse(function (child) {
|
|
30132
30139
|
if (child === scene) return;
|
|
30133
|
-
var isComponent = child.userData && (child.userData.objectType === 'component' || child.userData.objectType === '
|
|
30140
|
+
var isComponent = child.userData && (child.userData.objectType === 'component' || child.userData.objectType === 'segment' || child.userData.objectType === 'gateway' || child.userData.objectType === 'connector');
|
|
30134
30141
|
var isDirectChild = child.parent === scene;
|
|
30135
30142
|
if (isComponent && isDirectChild) {
|
|
30136
30143
|
componentsToRemove.push(child);
|
|
@@ -31123,123 +31130,52 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31123
31130
|
}
|
|
31124
31131
|
|
|
31125
31132
|
/**
|
|
31126
|
-
*
|
|
31127
|
-
*
|
|
31128
|
-
*
|
|
31129
|
-
|
|
31130
|
-
|
|
31131
|
-
|
|
31132
|
-
|
|
31133
|
-
|
|
31134
|
-
|
|
31135
|
-
|
|
31136
|
-
|
|
31137
|
-
|
|
31138
|
-
|
|
31139
|
-
|
|
31140
|
-
|
|
31141
|
-
|
|
31142
|
-
|
|
31143
|
-
|
|
31144
|
-
|
|
31145
|
-
|
|
31146
|
-
|
|
31147
|
-
|
|
31148
|
-
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
|
|
31154
|
-
|
|
31155
|
-
|
|
31156
|
-
|
|
31157
|
-
|
|
31158
|
-
|
|
31159
|
-
|
|
31160
|
-
|
|
31161
|
-
|
|
31162
|
-
|
|
31163
|
-
|
|
31164
|
-
|
|
31165
|
-
|
|
31166
|
-
|
|
31167
|
-
|
|
31168
|
-
if (
|
|
31169
|
-
|
|
31170
|
-
// For components: compute filtered bounding box (excludes io-device and connector subtrees)
|
|
31171
|
-
var filteredBBox = computeFilteredBoundingBox(object, ['io-device', 'connector']);
|
|
31172
|
-
jsonObject.userData.worldBoundingBox = {
|
|
31173
|
-
min: filteredBBox.min.toArray(),
|
|
31174
|
-
max: filteredBBox.max.toArray()
|
|
31175
|
-
};
|
|
31176
|
-
console.log("Added filtered world bounding box for component:", jsonObject.userData.worldBoundingBox);
|
|
31177
|
-
|
|
31178
|
-
// Compute and inject separate io-device bounding boxes as children
|
|
31179
|
-
var ioDeviceBBoxes = computeIODeviceBoundingBoxes(object);
|
|
31180
|
-
if (ioDeviceBBoxes.length > 0) {
|
|
31181
|
-
if (!jsonObject.children) jsonObject.children = [];
|
|
31182
|
-
ioDeviceBBoxes.forEach(function (deviceBBox) {
|
|
31183
|
-
var existingIndex = jsonObject.children.findIndex(function (c) {
|
|
31184
|
-
return c.uuid === deviceBBox.uuid;
|
|
31185
|
-
});
|
|
31186
|
-
if (existingIndex >= 0) {
|
|
31187
|
-
// Update existing entry
|
|
31188
|
-
if (!jsonObject.children[existingIndex].userData) jsonObject.children[existingIndex].userData = {};
|
|
31189
|
-
jsonObject.children[existingIndex].userData.objectType = 'io-device';
|
|
31190
|
-
jsonObject.children[existingIndex].userData.worldBoundingBox = deviceBBox.worldBoundingBox;
|
|
31191
|
-
} else {
|
|
31192
|
-
// Create new entry
|
|
31193
|
-
jsonObject.children.push({
|
|
31194
|
-
uuid: deviceBBox.uuid,
|
|
31195
|
-
userData: _objectSpread2(_objectSpread2({}, deviceBBox.userData), {}, {
|
|
31196
|
-
worldBoundingBox: deviceBBox.worldBoundingBox
|
|
31197
|
-
}),
|
|
31198
|
-
children: []
|
|
31199
|
-
});
|
|
31200
|
-
}
|
|
31201
|
-
});
|
|
31202
|
-
console.log("\uD83D\uDCE6 Injected ".concat(ioDeviceBBoxes.length, " io-device bbox(es) for component ").concat(jsonObject.uuid));
|
|
31203
|
-
}
|
|
31204
|
-
} else if (jsonObject.userData.objectType !== 'gateway') {
|
|
31205
|
-
// For non-component, non-gateway objects: standard bounding box
|
|
31206
|
-
var boundingBox = new THREE__namespace.Box3().setFromObject(object);
|
|
31207
|
-
jsonObject.userData.worldBoundingBox = {
|
|
31208
|
-
min: boundingBox.min.toArray(),
|
|
31209
|
-
max: boundingBox.max.toArray()
|
|
31210
|
-
};
|
|
31211
|
-
console.log("Added world bounding box:", jsonObject.userData.worldBoundingBox);
|
|
31212
|
-
}
|
|
31213
|
-
|
|
31214
|
-
// For gateways and connectors, ensure userData.position exists in scene data
|
|
31215
|
-
// This is REQUIRED for pathfinder compatibility
|
|
31216
|
-
if (jsonObject.userData.objectType === 'gateway' || jsonObject.userData.objectType === 'connector') {
|
|
31217
|
-
// Use the object's world position (from Three.js mesh)
|
|
31218
|
-
var worldPos = new THREE__namespace.Vector3();
|
|
31219
|
-
object.getWorldPosition(worldPos);
|
|
31220
|
-
|
|
31221
|
-
// ALWAYS update userData.position with world position
|
|
31222
|
-
// This is critical for manual segment connectors which start with local positions
|
|
31223
|
-
jsonObject.userData.position = [worldPos.x, worldPos.y, worldPos.z];
|
|
31224
|
-
console.log("\u2705 Set userData.position for ".concat(jsonObject.userData.objectType, " ").concat(jsonObject.uuid, ": [").concat(worldPos.x.toFixed(2), ", ").concat(worldPos.y.toFixed(2), ", ").concat(worldPos.z.toFixed(2), "]"));
|
|
31225
|
-
|
|
31226
|
-
// For gateways, ensure isDeclared flag is in scene data
|
|
31227
|
-
if (jsonObject.userData.objectType === 'gateway') {
|
|
31228
|
-
if (jsonObject.userData.isDeclared === undefined) {
|
|
31229
|
-
jsonObject.userData.isDeclared = true;
|
|
31230
|
-
}
|
|
31231
|
-
}
|
|
31232
|
-
|
|
31233
|
-
// For manual segment connectors, ensure isDeclared is set in scene data
|
|
31234
|
-
if (jsonObject.userData.objectType === 'segment-connector' && jsonObject.userData.isDeclared === undefined) {
|
|
31235
|
-
jsonObject.userData.isDeclared = true;
|
|
31236
|
-
console.log("\u2705 Set isDeclared=true for manual segment connector in scene data: ".concat(jsonObject.uuid));
|
|
31237
|
-
}
|
|
31238
|
-
|
|
31239
|
-
// Also sync the mesh's userData.position (belt and suspenders approach)
|
|
31240
|
-
object.userData.position = [worldPos.x, worldPos.y, worldPos.z];
|
|
31133
|
+
* Sync world-space positions and isDeclared flags for gateways and connectors
|
|
31134
|
+
* into the scene JSON data so the pathfinder can read them.
|
|
31135
|
+
*
|
|
31136
|
+
* Bounding boxes for components and segments are intentionally NOT computed here.
|
|
31137
|
+
* They are computed (with matrix-hash caching) by
|
|
31138
|
+
* PathfindingManager._enrichSceneDataWithBoundingBoxes(), which runs after GLB
|
|
31139
|
+
* models are fully loaded and therefore produces correct values.
|
|
31140
|
+
*/
|
|
31141
|
+
}, {
|
|
31142
|
+
key: "_syncPositionsForPathfinding",
|
|
31143
|
+
value: function _syncPositionsForPathfinding(data) {
|
|
31144
|
+
var scene = this.sceneViewer.scene;
|
|
31145
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
31146
|
+
var syncPosition = function syncPosition(jsonObject) {
|
|
31147
|
+
var _jsonObject$userData;
|
|
31148
|
+
var object = scene.getObjectByProperty('uuid', jsonObject.uuid) || scene.getObjectByProperty('uuid', (_jsonObject$userData = jsonObject.userData) === null || _jsonObject$userData === void 0 ? void 0 : _jsonObject$userData.originalUuid);
|
|
31149
|
+
if (!object) return;
|
|
31150
|
+
object.getWorldPosition(worldPos);
|
|
31151
|
+
var pos = [worldPos.x, worldPos.y, worldPos.z];
|
|
31152
|
+
jsonObject.userData.position = pos;
|
|
31153
|
+
object.userData.position = pos;
|
|
31154
|
+
};
|
|
31155
|
+
data.scene.children.forEach(function (jsonObject) {
|
|
31156
|
+
var _jsonObject$userData2;
|
|
31157
|
+
var type = (_jsonObject$userData2 = jsonObject.userData) === null || _jsonObject$userData2 === void 0 ? void 0 : _jsonObject$userData2.objectType;
|
|
31158
|
+
if (type === 'gateway') {
|
|
31159
|
+
syncPosition(jsonObject);
|
|
31160
|
+
if (jsonObject.userData.isDeclared === undefined) {
|
|
31161
|
+
jsonObject.userData.isDeclared = true;
|
|
31162
|
+
}
|
|
31163
|
+
} else if (type === 'connector') {
|
|
31164
|
+
syncPosition(jsonObject);
|
|
31165
|
+
} else if (type === 'segment-connector') {
|
|
31166
|
+
syncPosition(jsonObject);
|
|
31167
|
+
if (jsonObject.userData.isDeclared === undefined) {
|
|
31168
|
+
jsonObject.userData.isDeclared = true;
|
|
31169
|
+
}
|
|
31170
|
+
} else if (type === 'component' && Array.isArray(jsonObject.children)) {
|
|
31171
|
+
// Connectors are injected as JSON children by _injectConnectorChildrenFromDictionary
|
|
31172
|
+
// and their Three.js objects exist in the scene, created recursively by createSceneObject
|
|
31173
|
+
jsonObject.children.forEach(function (childJson) {
|
|
31174
|
+
var _childJson$userData;
|
|
31175
|
+
if (((_childJson$userData = childJson.userData) === null || _childJson$userData === void 0 ? void 0 : _childJson$userData.objectType) === 'connector') {
|
|
31176
|
+
syncPosition(childJson);
|
|
31241
31177
|
}
|
|
31242
|
-
}
|
|
31178
|
+
});
|
|
31243
31179
|
}
|
|
31244
31180
|
});
|
|
31245
31181
|
}
|
|
@@ -31404,10 +31340,10 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31404
31340
|
var componentsProcessed = 0;
|
|
31405
31341
|
var connectorsInjected = 0;
|
|
31406
31342
|
data.scene.children.forEach(function (child) {
|
|
31407
|
-
var _child$
|
|
31408
|
-
var childType = ((_child$
|
|
31343
|
+
var _child$userData4, _child$userData5, _child$userData6;
|
|
31344
|
+
var childType = ((_child$userData4 = child.userData) === null || _child$userData4 === void 0 ? void 0 : _child$userData4.objectType) || ((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType);
|
|
31409
31345
|
// Only process components with libraryId
|
|
31410
|
-
if (childType === 'component' && (_child$
|
|
31346
|
+
if (childType === 'component' && (_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.libraryId) {
|
|
31411
31347
|
var libraryId = child.userData.libraryId;
|
|
31412
31348
|
var dictEntry = componentDictionary[libraryId];
|
|
31413
31349
|
|
|
@@ -31564,23 +31500,25 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31564
31500
|
geometries = this.createSceneGeometries(data, componentDictionary); // Create basic objects and track GLB replacements
|
|
31565
31501
|
libraryObjectsToReplace = [];
|
|
31566
31502
|
data.scene.children.forEach(function (child, index) {
|
|
31567
|
-
var _child$
|
|
31503
|
+
var _child$userData7, _child$userData8;
|
|
31568
31504
|
var createdObject = _this4.createSceneObject(child, geometries, materials, componentDictionary);
|
|
31569
31505
|
_this4.sceneViewer.scene.add(createdObject);
|
|
31570
31506
|
|
|
31571
31507
|
// Track objects that need GLB model replacement
|
|
31572
|
-
if ((_child$
|
|
31573
|
-
var _child$
|
|
31508
|
+
if ((_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.libraryId && componentDictionary[(_child$userData8 = child.userData) === null || _child$userData8 === void 0 ? void 0 : _child$userData8.libraryId]) {
|
|
31509
|
+
var _child$userData9;
|
|
31574
31510
|
libraryObjectsToReplace.push({
|
|
31575
31511
|
basicObject: createdObject,
|
|
31576
31512
|
jsonData: child,
|
|
31577
|
-
componentData: componentDictionary[(_child$
|
|
31513
|
+
componentData: componentDictionary[(_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.libraryId]
|
|
31578
31514
|
});
|
|
31579
31515
|
}
|
|
31580
31516
|
});
|
|
31581
31517
|
|
|
31582
|
-
//
|
|
31583
|
-
|
|
31518
|
+
// Sync gateway/connector world positions into JSON before pathfinding.
|
|
31519
|
+
// Bounding boxes are computed later by PathfindingManager._enrichSceneDataWithBoundingBoxes
|
|
31520
|
+
// (after GLB models are loaded), so no bbox work is done here.
|
|
31521
|
+
this._syncPositionsForPathfinding(data);
|
|
31584
31522
|
this._saveOriginalWorldMatrices(this.sceneViewer.scene);
|
|
31585
31523
|
return _context6.a(2, {
|
|
31586
31524
|
componentDictionary: componentDictionary,
|
|
@@ -31726,8 +31664,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31726
31664
|
var instanceBehaviors = [];
|
|
31727
31665
|
if (Array.isArray(data === null || data === void 0 || (_data$scene3 = data.scene) === null || _data$scene3 === void 0 ? void 0 : _data$scene3.children)) {
|
|
31728
31666
|
data.scene.children.forEach(function (child) {
|
|
31729
|
-
var _child$
|
|
31730
|
-
var libraryId = (_child$
|
|
31667
|
+
var _child$userData0, _compData$defaultBeha;
|
|
31668
|
+
var libraryId = (_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.libraryId;
|
|
31731
31669
|
if (!libraryId) return;
|
|
31732
31670
|
var instanceUuid = child.uuid;
|
|
31733
31671
|
// Skip instances whose defaults were already resolved by Step A
|
|
@@ -31923,8 +31861,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31923
31861
|
key: "_saveOriginalWorldMatrices",
|
|
31924
31862
|
value: function _saveOriginalWorldMatrices(scene) {
|
|
31925
31863
|
scene.traverse(function (object) {
|
|
31926
|
-
var _object$
|
|
31927
|
-
if ((_object$
|
|
31864
|
+
var _object$userData;
|
|
31865
|
+
if ((_object$userData = object.userData) !== null && _object$userData !== void 0 && _object$userData.direction) {
|
|
31928
31866
|
var originalMatrix = new THREE__namespace.Matrix4();
|
|
31929
31867
|
originalMatrix.copy(object.matrixWorld);
|
|
31930
31868
|
}
|
|
@@ -32128,8 +32066,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32128
32066
|
// Process children (connectors, etc.) if they exist
|
|
32129
32067
|
if (componentModel.children && componentModel.children.length > 0) {
|
|
32130
32068
|
componentModel.children.forEach(function (child) {
|
|
32131
|
-
var _child$
|
|
32132
|
-
var childType = ((_child$
|
|
32069
|
+
var _child$userData1, _child$userData10;
|
|
32070
|
+
var childType = ((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType) || ((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType);
|
|
32133
32071
|
if (childType === 'connector') {
|
|
32134
32072
|
var _child$geometry;
|
|
32135
32073
|
var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
|
|
@@ -32214,8 +32152,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32214
32152
|
if (segment.children && segment.children.length > 0) {
|
|
32215
32153
|
var childrenToRemove = _toConsumableArray(segment.children);
|
|
32216
32154
|
childrenToRemove.forEach(function (child) {
|
|
32217
|
-
var _child$
|
|
32218
|
-
if ((_child$
|
|
32155
|
+
var _child$userData11;
|
|
32156
|
+
if ((_child$userData11 = child.userData) !== null && _child$userData11 !== void 0 && _child$userData11.isPipeElbow) {
|
|
32219
32157
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
32220
32158
|
segment.remove(child);
|
|
32221
32159
|
if (child.geometry) child.geometry.dispose();
|
|
@@ -35485,6 +35423,18 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35485
35423
|
// Map of viewport instances by viewType or custom key
|
|
35486
35424
|
_this2.viewports = new Map();
|
|
35487
35425
|
|
|
35426
|
+
// Per-refresh-cycle bbox cache: keyed by object.uuid, cleared each refresh()
|
|
35427
|
+
// so each component bbox is computed once per cycle regardless of viewport count
|
|
35428
|
+
_this2._bboxCache = new Map();
|
|
35429
|
+
|
|
35430
|
+
// Per-refresh-cycle component list cache: eliminates redundant scene traversals
|
|
35431
|
+
// when all 3 viewports render in the same cycle
|
|
35432
|
+
_this2._componentListCache = null;
|
|
35433
|
+
|
|
35434
|
+
// rAF debounce flag — prevents multiple same-frame refresh() calls from
|
|
35435
|
+
// stacking up independent renderComponents() runs
|
|
35436
|
+
_this2._refreshPending = false;
|
|
35437
|
+
|
|
35488
35438
|
// Event listener reference for cleanup
|
|
35489
35439
|
_this2._objectTransformedListener = null;
|
|
35490
35440
|
console.log('🔲 Viewport2DManager initialized (multi-instance support)');
|
|
@@ -35506,7 +35456,6 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35506
35456
|
|
|
35507
35457
|
// Listen for object transformations to refresh all viewports
|
|
35508
35458
|
this._objectTransformedListener = function (eventData) {
|
|
35509
|
-
console.log('🔲 Viewport2DManager detected object transformation, refreshing all viewports');
|
|
35510
35459
|
_this3.refresh(); // Refresh all viewports
|
|
35511
35460
|
};
|
|
35512
35461
|
|
|
@@ -35572,6 +35521,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35572
35521
|
case 3:
|
|
35573
35522
|
// Create new viewport instance
|
|
35574
35523
|
viewport = new Viewport2DInstance(this.sceneViewer, this.Konva, viewType, container);
|
|
35524
|
+
viewport._instanceKey = key;
|
|
35575
35525
|
this.viewports.set(key, viewport);
|
|
35576
35526
|
|
|
35577
35527
|
// Initialize the stage for this viewport
|
|
@@ -35749,9 +35699,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35749
35699
|
viewport.stage.width(width);
|
|
35750
35700
|
viewport.stage.height(height);
|
|
35751
35701
|
|
|
35752
|
-
// Redraw
|
|
35702
|
+
// Redraw grid immediately; schedule debounced component render
|
|
35753
35703
|
this.drawGrid(viewport);
|
|
35754
|
-
this.
|
|
35704
|
+
this.refresh(viewport._instanceKey);
|
|
35755
35705
|
}
|
|
35756
35706
|
}
|
|
35757
35707
|
|
|
@@ -35934,7 +35884,6 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35934
35884
|
worldDepth = _this$getComponentDim.worldDepth,
|
|
35935
35885
|
worldHeight = _this$getComponentDim.worldHeight,
|
|
35936
35886
|
bboxCenter = _this$getComponentDim.bboxCenter;
|
|
35937
|
-
console.log("[2D] ".concat(component.name, " | w=").concat(worldWidth.toFixed(3), " d=").concat(worldDepth.toFixed(3), " h=").concat(worldHeight.toFixed(3), " | center=(").concat(bboxCenter.x.toFixed(2), ",").concat(bboxCenter.y.toFixed(2), ",").concat(bboxCenter.z.toFixed(2), ")"));
|
|
35938
35887
|
|
|
35939
35888
|
// Project 3D bbox center to 2D based on view type
|
|
35940
35889
|
var _this$project3DTo2D = this.project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight),
|
|
@@ -36001,21 +35950,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36001
35950
|
}, {
|
|
36002
35951
|
key: "_getOrComputeWorldBoundingBox",
|
|
36003
35952
|
value: function _getOrComputeWorldBoundingBox(object) {
|
|
36004
|
-
|
|
35953
|
+
var _object$userData, _object$userData2;
|
|
35954
|
+
// Fast path: offset the stored world bbox by the position delta since load time.
|
|
35955
|
+
// Translation only shifts the bbox center — extents stay identical — so this is O(1)
|
|
35956
|
+
// instead of O(meshes × vertices) from a full geometry traversal.
|
|
35957
|
+
var stored = (_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.worldBoundingBox;
|
|
35958
|
+
var basePos = (_object$userData2 = object.userData) === null || _object$userData2 === void 0 ? void 0 : _object$userData2._wbbBasePosition;
|
|
35959
|
+
if (stored && basePos) {
|
|
35960
|
+
var dx = object.position.x - basePos.x;
|
|
35961
|
+
var dy = object.position.y - basePos.y;
|
|
35962
|
+
var dz = object.position.z - basePos.z;
|
|
35963
|
+
if (dx === 0 && dy === 0 && dz === 0) return stored;
|
|
35964
|
+
return {
|
|
35965
|
+
min: [stored.min[0] + dx, stored.min[1] + dy, stored.min[2] + dz],
|
|
35966
|
+
max: [stored.max[0] + dx, stored.max[1] + dy, stored.max[2] + dz]
|
|
35967
|
+
};
|
|
35968
|
+
}
|
|
35969
|
+
|
|
35970
|
+
// Slow path: full vertex-accurate traversal (fallback when userData not populated)
|
|
35971
|
+
if (this._bboxCache.has(object.uuid)) {
|
|
35972
|
+
return this._bboxCache.get(object.uuid);
|
|
35973
|
+
}
|
|
36005
35974
|
var box = computeFilteredBoundingBox(object, []);
|
|
35975
|
+
var result;
|
|
36006
35976
|
if (box.isEmpty()) {
|
|
36007
35977
|
// Object has no geometry; fall back to a point at world position
|
|
36008
35978
|
var wp = new THREE__namespace.Vector3();
|
|
36009
35979
|
object.getWorldPosition(wp);
|
|
36010
|
-
|
|
35980
|
+
result = {
|
|
36011
35981
|
min: [wp.x, wp.y, wp.z],
|
|
36012
35982
|
max: [wp.x, wp.y, wp.z]
|
|
36013
35983
|
};
|
|
35984
|
+
} else {
|
|
35985
|
+
result = {
|
|
35986
|
+
min: [box.min.x, box.min.y, box.min.z],
|
|
35987
|
+
max: [box.max.x, box.max.y, box.max.z]
|
|
35988
|
+
};
|
|
36014
35989
|
}
|
|
36015
|
-
|
|
36016
|
-
|
|
36017
|
-
max: [box.max.x, box.max.y, box.max.z]
|
|
36018
|
-
};
|
|
35990
|
+
this._bboxCache.set(object.uuid, result);
|
|
35991
|
+
return result;
|
|
36019
35992
|
}
|
|
36020
35993
|
|
|
36021
35994
|
/**
|
|
@@ -36024,11 +35997,12 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36024
35997
|
}, {
|
|
36025
35998
|
key: "getComponentDimensions",
|
|
36026
35999
|
value: function getComponentDimensions(component) {
|
|
36027
|
-
var _component$
|
|
36028
|
-
//
|
|
36029
|
-
//
|
|
36030
|
-
//
|
|
36031
|
-
|
|
36000
|
+
var _component$getWorldPo;
|
|
36001
|
+
// Always recompute from the live Three.js object so that the rect reflects
|
|
36002
|
+
// the current world position after translate/drag operations.
|
|
36003
|
+
// userData.worldBoundingBox is a load-time snapshot and goes stale whenever
|
|
36004
|
+
// the object moves, so we cannot rely on it here.
|
|
36005
|
+
var wbb = this._getOrComputeWorldBoundingBox(component);
|
|
36032
36006
|
if (wbb !== null && wbb !== void 0 && wbb.min && wbb !== null && wbb !== void 0 && wbb.max) {
|
|
36033
36007
|
var _wbb$min = _slicedToArray(wbb.min, 3),
|
|
36034
36008
|
minX = _wbb$min[0],
|
|
@@ -36139,7 +36113,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36139
36113
|
rect.stroke('#007bff');
|
|
36140
36114
|
rect.strokeWidth(3);
|
|
36141
36115
|
viewport.stage.container().style.cursor = 'grab';
|
|
36142
|
-
viewport.componentLayer.
|
|
36116
|
+
viewport.componentLayer.batchDraw();
|
|
36143
36117
|
}
|
|
36144
36118
|
});
|
|
36145
36119
|
rect.on('mouseleave', function () {
|
|
@@ -36148,7 +36122,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36148
36122
|
rect.stroke(colors.stroke);
|
|
36149
36123
|
rect.strokeWidth(2);
|
|
36150
36124
|
viewport.stage.container().style.cursor = 'default';
|
|
36151
|
-
viewport.componentLayer.
|
|
36125
|
+
viewport.componentLayer.batchDraw();
|
|
36152
36126
|
}
|
|
36153
36127
|
});
|
|
36154
36128
|
|
|
@@ -36192,7 +36166,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36192
36166
|
// Snap to grid
|
|
36193
36167
|
var snappedPos = _this6.snapScreenToGrid(viewport, currentPos.x, currentPos.y, scale, worldOriginX, worldOriginY);
|
|
36194
36168
|
componentGroup.position(snappedPos);
|
|
36195
|
-
viewport.componentLayer.
|
|
36169
|
+
viewport.componentLayer.batchDraw();
|
|
36196
36170
|
});
|
|
36197
36171
|
|
|
36198
36172
|
// DRAG END
|
|
@@ -36365,18 +36339,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36365
36339
|
}, {
|
|
36366
36340
|
key: "getSceneComponents",
|
|
36367
36341
|
value: function getSceneComponents() {
|
|
36342
|
+
if (this._componentListCache) return this._componentListCache;
|
|
36368
36343
|
if (!this.sceneViewer || !this.sceneViewer.scene) {
|
|
36369
36344
|
return [];
|
|
36370
36345
|
}
|
|
36371
36346
|
var components = [];
|
|
36372
36347
|
this.sceneViewer.scene.traverse(function (object) {
|
|
36373
|
-
var _object$
|
|
36348
|
+
var _object$userData3, _object$userData4;
|
|
36374
36349
|
// Only match the ROOT component object — must have both objectType:'component'
|
|
36375
36350
|
// AND libraryId (inner GLB mesh nodes don't have libraryId)
|
|
36376
|
-
if (((_object$
|
|
36351
|
+
if (((_object$userData3 = object.userData) === null || _object$userData3 === void 0 ? void 0 : _object$userData3.objectType) === 'component' && (_object$userData4 = object.userData) !== null && _object$userData4 !== void 0 && _object$userData4.libraryId) {
|
|
36377
36352
|
components.push(object);
|
|
36378
36353
|
}
|
|
36379
36354
|
});
|
|
36355
|
+
this._componentListCache = components;
|
|
36380
36356
|
return components;
|
|
36381
36357
|
}
|
|
36382
36358
|
|
|
@@ -36482,35 +36458,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36482
36458
|
}
|
|
36483
36459
|
|
|
36484
36460
|
/**
|
|
36485
|
-
* Refresh a specific viewport or all viewports
|
|
36461
|
+
* Refresh a specific viewport or all viewports.
|
|
36462
|
+
* Debounced via requestAnimationFrame so multiple calls within the same
|
|
36463
|
+
* frame (e.g. from Viewport2D mount + refreshAll2DViews) collapse into one.
|
|
36486
36464
|
* @param {string} key - Optional viewport key. If not provided, refreshes all viewports
|
|
36487
36465
|
*/
|
|
36488
36466
|
}, {
|
|
36489
36467
|
key: "refresh",
|
|
36490
36468
|
value: function refresh() {
|
|
36469
|
+
var _this7 = this;
|
|
36491
36470
|
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
36492
|
-
if (
|
|
36493
|
-
|
|
36494
|
-
|
|
36495
|
-
|
|
36496
|
-
|
|
36497
|
-
|
|
36498
|
-
|
|
36499
|
-
|
|
36500
|
-
|
|
36501
|
-
|
|
36502
|
-
|
|
36503
|
-
|
|
36504
|
-
|
|
36505
|
-
|
|
36471
|
+
if (this._refreshPending) return;
|
|
36472
|
+
this._refreshPending = true;
|
|
36473
|
+
requestAnimationFrame(function () {
|
|
36474
|
+
_this7._refreshPending = false;
|
|
36475
|
+
// Clear per-cycle caches so each component is measured/traversed once per paint
|
|
36476
|
+
_this7._bboxCache.clear();
|
|
36477
|
+
_this7._componentListCache = null;
|
|
36478
|
+
if (key) {
|
|
36479
|
+
var viewport = _this7.viewports.get(key);
|
|
36480
|
+
if (viewport && viewport.isReady) {
|
|
36481
|
+
_this7.renderComponents(viewport);
|
|
36482
|
+
}
|
|
36483
|
+
} else {
|
|
36484
|
+
var _iterator = _createForOfIteratorHelper(_this7.viewports.values()),
|
|
36485
|
+
_step;
|
|
36486
|
+
try {
|
|
36487
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
36488
|
+
var _viewport = _step.value;
|
|
36489
|
+
if (_viewport.isReady) {
|
|
36490
|
+
_this7.renderComponents(_viewport);
|
|
36491
|
+
}
|
|
36506
36492
|
}
|
|
36493
|
+
} catch (err) {
|
|
36494
|
+
_iterator.e(err);
|
|
36495
|
+
} finally {
|
|
36496
|
+
_iterator.f();
|
|
36507
36497
|
}
|
|
36508
|
-
} catch (err) {
|
|
36509
|
-
_iterator.e(err);
|
|
36510
|
-
} finally {
|
|
36511
|
-
_iterator.f();
|
|
36512
36498
|
}
|
|
36513
|
-
}
|
|
36499
|
+
});
|
|
36514
36500
|
}
|
|
36515
36501
|
|
|
36516
36502
|
/**
|
|
@@ -37830,7 +37816,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37830
37816
|
* Initialize the CentralPlant manager
|
|
37831
37817
|
*
|
|
37832
37818
|
* @constructor
|
|
37833
|
-
* @version 0.3.
|
|
37819
|
+
* @version 0.3.6
|
|
37834
37820
|
* @updated 2025-10-22
|
|
37835
37821
|
*
|
|
37836
37822
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -35,7 +35,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
35
35
|
* Initialize the CentralPlant manager
|
|
36
36
|
*
|
|
37
37
|
* @constructor
|
|
38
|
-
* @version 0.3.
|
|
38
|
+
* @version 0.3.6
|
|
39
39
|
* @updated 2025-10-22
|
|
40
40
|
*
|
|
41
41
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -595,6 +595,13 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
595
595
|
// Update both the JSON data object AND the live scene object
|
|
596
596
|
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
597
597
|
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
598
|
+
// Snapshot the object's local position so viewport2DManager can compute
|
|
599
|
+
// world-bbox updates via a fast O(1) position delta instead of re-traversing geometry
|
|
600
|
+
glbModel.userData._wbbBasePosition = {
|
|
601
|
+
x: glbModel.position.x,
|
|
602
|
+
y: glbModel.position.y,
|
|
603
|
+
z: glbModel.position.z
|
|
604
|
+
};
|
|
598
605
|
});
|
|
599
606
|
|
|
600
607
|
// Dispatch completion event
|