@2112-lab/central-plant 0.3.5 → 0.3.7
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 +167 -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 +7 -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 +7 -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);
|
|
@@ -30381,6 +30388,11 @@ var SceneClearingUtility = /*#__PURE__*/function () {
|
|
|
30381
30388
|
this.sceneViewer.currentSceneData.connections = [];
|
|
30382
30389
|
}
|
|
30383
30390
|
|
|
30391
|
+
// Clear the JSON data mirror so getAvailableConnections() returns nothing
|
|
30392
|
+
if (this.sceneViewer.currentSceneData && this.sceneViewer.currentSceneData.scene) {
|
|
30393
|
+
this.sceneViewer.currentSceneData.scene.children = [];
|
|
30394
|
+
}
|
|
30395
|
+
|
|
30384
30396
|
// Reset component counter for CentralPlant
|
|
30385
30397
|
if (this.sceneViewer.centralPlant && this.sceneViewer.centralPlant.componentCounter !== undefined) {
|
|
30386
30398
|
this.sceneViewer.centralPlant.componentCounter = 0;
|
|
@@ -31123,123 +31135,52 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31123
31135
|
}
|
|
31124
31136
|
|
|
31125
31137
|
/**
|
|
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];
|
|
31138
|
+
* Sync world-space positions and isDeclared flags for gateways and connectors
|
|
31139
|
+
* into the scene JSON data so the pathfinder can read them.
|
|
31140
|
+
*
|
|
31141
|
+
* Bounding boxes for components and segments are intentionally NOT computed here.
|
|
31142
|
+
* They are computed (with matrix-hash caching) by
|
|
31143
|
+
* PathfindingManager._enrichSceneDataWithBoundingBoxes(), which runs after GLB
|
|
31144
|
+
* models are fully loaded and therefore produces correct values.
|
|
31145
|
+
*/
|
|
31146
|
+
}, {
|
|
31147
|
+
key: "_syncPositionsForPathfinding",
|
|
31148
|
+
value: function _syncPositionsForPathfinding(data) {
|
|
31149
|
+
var scene = this.sceneViewer.scene;
|
|
31150
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
31151
|
+
var syncPosition = function syncPosition(jsonObject) {
|
|
31152
|
+
var _jsonObject$userData;
|
|
31153
|
+
var object = scene.getObjectByProperty('uuid', jsonObject.uuid) || scene.getObjectByProperty('uuid', (_jsonObject$userData = jsonObject.userData) === null || _jsonObject$userData === void 0 ? void 0 : _jsonObject$userData.originalUuid);
|
|
31154
|
+
if (!object) return;
|
|
31155
|
+
object.getWorldPosition(worldPos);
|
|
31156
|
+
var pos = [worldPos.x, worldPos.y, worldPos.z];
|
|
31157
|
+
jsonObject.userData.position = pos;
|
|
31158
|
+
object.userData.position = pos;
|
|
31159
|
+
};
|
|
31160
|
+
data.scene.children.forEach(function (jsonObject) {
|
|
31161
|
+
var _jsonObject$userData2;
|
|
31162
|
+
var type = (_jsonObject$userData2 = jsonObject.userData) === null || _jsonObject$userData2 === void 0 ? void 0 : _jsonObject$userData2.objectType;
|
|
31163
|
+
if (type === 'gateway') {
|
|
31164
|
+
syncPosition(jsonObject);
|
|
31165
|
+
if (jsonObject.userData.isDeclared === undefined) {
|
|
31166
|
+
jsonObject.userData.isDeclared = true;
|
|
31167
|
+
}
|
|
31168
|
+
} else if (type === 'connector') {
|
|
31169
|
+
syncPosition(jsonObject);
|
|
31170
|
+
} else if (type === 'segment-connector') {
|
|
31171
|
+
syncPosition(jsonObject);
|
|
31172
|
+
if (jsonObject.userData.isDeclared === undefined) {
|
|
31173
|
+
jsonObject.userData.isDeclared = true;
|
|
31174
|
+
}
|
|
31175
|
+
} else if (type === 'component' && Array.isArray(jsonObject.children)) {
|
|
31176
|
+
// Connectors are injected as JSON children by _injectConnectorChildrenFromDictionary
|
|
31177
|
+
// and their Three.js objects exist in the scene, created recursively by createSceneObject
|
|
31178
|
+
jsonObject.children.forEach(function (childJson) {
|
|
31179
|
+
var _childJson$userData;
|
|
31180
|
+
if (((_childJson$userData = childJson.userData) === null || _childJson$userData === void 0 ? void 0 : _childJson$userData.objectType) === 'connector') {
|
|
31181
|
+
syncPosition(childJson);
|
|
31241
31182
|
}
|
|
31242
|
-
}
|
|
31183
|
+
});
|
|
31243
31184
|
}
|
|
31244
31185
|
});
|
|
31245
31186
|
}
|
|
@@ -31404,10 +31345,10 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31404
31345
|
var componentsProcessed = 0;
|
|
31405
31346
|
var connectorsInjected = 0;
|
|
31406
31347
|
data.scene.children.forEach(function (child) {
|
|
31407
|
-
var _child$
|
|
31408
|
-
var childType = ((_child$
|
|
31348
|
+
var _child$userData4, _child$userData5, _child$userData6;
|
|
31349
|
+
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
31350
|
// Only process components with libraryId
|
|
31410
|
-
if (childType === 'component' && (_child$
|
|
31351
|
+
if (childType === 'component' && (_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.libraryId) {
|
|
31411
31352
|
var libraryId = child.userData.libraryId;
|
|
31412
31353
|
var dictEntry = componentDictionary[libraryId];
|
|
31413
31354
|
|
|
@@ -31564,23 +31505,25 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31564
31505
|
geometries = this.createSceneGeometries(data, componentDictionary); // Create basic objects and track GLB replacements
|
|
31565
31506
|
libraryObjectsToReplace = [];
|
|
31566
31507
|
data.scene.children.forEach(function (child, index) {
|
|
31567
|
-
var _child$
|
|
31508
|
+
var _child$userData7, _child$userData8;
|
|
31568
31509
|
var createdObject = _this4.createSceneObject(child, geometries, materials, componentDictionary);
|
|
31569
31510
|
_this4.sceneViewer.scene.add(createdObject);
|
|
31570
31511
|
|
|
31571
31512
|
// Track objects that need GLB model replacement
|
|
31572
|
-
if ((_child$
|
|
31573
|
-
var _child$
|
|
31513
|
+
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]) {
|
|
31514
|
+
var _child$userData9;
|
|
31574
31515
|
libraryObjectsToReplace.push({
|
|
31575
31516
|
basicObject: createdObject,
|
|
31576
31517
|
jsonData: child,
|
|
31577
|
-
componentData: componentDictionary[(_child$
|
|
31518
|
+
componentData: componentDictionary[(_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.libraryId]
|
|
31578
31519
|
});
|
|
31579
31520
|
}
|
|
31580
31521
|
});
|
|
31581
31522
|
|
|
31582
|
-
//
|
|
31583
|
-
|
|
31523
|
+
// Sync gateway/connector world positions into JSON before pathfinding.
|
|
31524
|
+
// Bounding boxes are computed later by PathfindingManager._enrichSceneDataWithBoundingBoxes
|
|
31525
|
+
// (after GLB models are loaded), so no bbox work is done here.
|
|
31526
|
+
this._syncPositionsForPathfinding(data);
|
|
31584
31527
|
this._saveOriginalWorldMatrices(this.sceneViewer.scene);
|
|
31585
31528
|
return _context6.a(2, {
|
|
31586
31529
|
componentDictionary: componentDictionary,
|
|
@@ -31726,8 +31669,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31726
31669
|
var instanceBehaviors = [];
|
|
31727
31670
|
if (Array.isArray(data === null || data === void 0 || (_data$scene3 = data.scene) === null || _data$scene3 === void 0 ? void 0 : _data$scene3.children)) {
|
|
31728
31671
|
data.scene.children.forEach(function (child) {
|
|
31729
|
-
var _child$
|
|
31730
|
-
var libraryId = (_child$
|
|
31672
|
+
var _child$userData0, _compData$defaultBeha;
|
|
31673
|
+
var libraryId = (_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.libraryId;
|
|
31731
31674
|
if (!libraryId) return;
|
|
31732
31675
|
var instanceUuid = child.uuid;
|
|
31733
31676
|
// Skip instances whose defaults were already resolved by Step A
|
|
@@ -31923,8 +31866,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31923
31866
|
key: "_saveOriginalWorldMatrices",
|
|
31924
31867
|
value: function _saveOriginalWorldMatrices(scene) {
|
|
31925
31868
|
scene.traverse(function (object) {
|
|
31926
|
-
var _object$
|
|
31927
|
-
if ((_object$
|
|
31869
|
+
var _object$userData;
|
|
31870
|
+
if ((_object$userData = object.userData) !== null && _object$userData !== void 0 && _object$userData.direction) {
|
|
31928
31871
|
var originalMatrix = new THREE__namespace.Matrix4();
|
|
31929
31872
|
originalMatrix.copy(object.matrixWorld);
|
|
31930
31873
|
}
|
|
@@ -32128,8 +32071,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32128
32071
|
// Process children (connectors, etc.) if they exist
|
|
32129
32072
|
if (componentModel.children && componentModel.children.length > 0) {
|
|
32130
32073
|
componentModel.children.forEach(function (child) {
|
|
32131
|
-
var _child$
|
|
32132
|
-
var childType = ((_child$
|
|
32074
|
+
var _child$userData1, _child$userData10;
|
|
32075
|
+
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
32076
|
if (childType === 'connector') {
|
|
32134
32077
|
var _child$geometry;
|
|
32135
32078
|
var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
|
|
@@ -32214,8 +32157,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32214
32157
|
if (segment.children && segment.children.length > 0) {
|
|
32215
32158
|
var childrenToRemove = _toConsumableArray(segment.children);
|
|
32216
32159
|
childrenToRemove.forEach(function (child) {
|
|
32217
|
-
var _child$
|
|
32218
|
-
if ((_child$
|
|
32160
|
+
var _child$userData11;
|
|
32161
|
+
if ((_child$userData11 = child.userData) !== null && _child$userData11 !== void 0 && _child$userData11.isPipeElbow) {
|
|
32219
32162
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
32220
32163
|
segment.remove(child);
|
|
32221
32164
|
if (child.geometry) child.geometry.dispose();
|
|
@@ -35485,6 +35428,18 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35485
35428
|
// Map of viewport instances by viewType or custom key
|
|
35486
35429
|
_this2.viewports = new Map();
|
|
35487
35430
|
|
|
35431
|
+
// Per-refresh-cycle bbox cache: keyed by object.uuid, cleared each refresh()
|
|
35432
|
+
// so each component bbox is computed once per cycle regardless of viewport count
|
|
35433
|
+
_this2._bboxCache = new Map();
|
|
35434
|
+
|
|
35435
|
+
// Per-refresh-cycle component list cache: eliminates redundant scene traversals
|
|
35436
|
+
// when all 3 viewports render in the same cycle
|
|
35437
|
+
_this2._componentListCache = null;
|
|
35438
|
+
|
|
35439
|
+
// rAF debounce flag — prevents multiple same-frame refresh() calls from
|
|
35440
|
+
// stacking up independent renderComponents() runs
|
|
35441
|
+
_this2._refreshPending = false;
|
|
35442
|
+
|
|
35488
35443
|
// Event listener reference for cleanup
|
|
35489
35444
|
_this2._objectTransformedListener = null;
|
|
35490
35445
|
console.log('🔲 Viewport2DManager initialized (multi-instance support)');
|
|
@@ -35506,7 +35461,6 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35506
35461
|
|
|
35507
35462
|
// Listen for object transformations to refresh all viewports
|
|
35508
35463
|
this._objectTransformedListener = function (eventData) {
|
|
35509
|
-
console.log('🔲 Viewport2DManager detected object transformation, refreshing all viewports');
|
|
35510
35464
|
_this3.refresh(); // Refresh all viewports
|
|
35511
35465
|
};
|
|
35512
35466
|
|
|
@@ -35572,6 +35526,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35572
35526
|
case 3:
|
|
35573
35527
|
// Create new viewport instance
|
|
35574
35528
|
viewport = new Viewport2DInstance(this.sceneViewer, this.Konva, viewType, container);
|
|
35529
|
+
viewport._instanceKey = key;
|
|
35575
35530
|
this.viewports.set(key, viewport);
|
|
35576
35531
|
|
|
35577
35532
|
// Initialize the stage for this viewport
|
|
@@ -35749,9 +35704,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35749
35704
|
viewport.stage.width(width);
|
|
35750
35705
|
viewport.stage.height(height);
|
|
35751
35706
|
|
|
35752
|
-
// Redraw
|
|
35707
|
+
// Redraw grid immediately; schedule debounced component render
|
|
35753
35708
|
this.drawGrid(viewport);
|
|
35754
|
-
this.
|
|
35709
|
+
this.refresh(viewport._instanceKey);
|
|
35755
35710
|
}
|
|
35756
35711
|
}
|
|
35757
35712
|
|
|
@@ -35934,7 +35889,6 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35934
35889
|
worldDepth = _this$getComponentDim.worldDepth,
|
|
35935
35890
|
worldHeight = _this$getComponentDim.worldHeight,
|
|
35936
35891
|
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
35892
|
|
|
35939
35893
|
// Project 3D bbox center to 2D based on view type
|
|
35940
35894
|
var _this$project3DTo2D = this.project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight),
|
|
@@ -36001,21 +35955,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36001
35955
|
}, {
|
|
36002
35956
|
key: "_getOrComputeWorldBoundingBox",
|
|
36003
35957
|
value: function _getOrComputeWorldBoundingBox(object) {
|
|
36004
|
-
|
|
35958
|
+
var _object$userData, _object$userData2;
|
|
35959
|
+
// Fast path: offset the stored world bbox by the position delta since load time.
|
|
35960
|
+
// Translation only shifts the bbox center — extents stay identical — so this is O(1)
|
|
35961
|
+
// instead of O(meshes × vertices) from a full geometry traversal.
|
|
35962
|
+
var stored = (_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.worldBoundingBox;
|
|
35963
|
+
var basePos = (_object$userData2 = object.userData) === null || _object$userData2 === void 0 ? void 0 : _object$userData2._wbbBasePosition;
|
|
35964
|
+
if (stored && basePos) {
|
|
35965
|
+
var dx = object.position.x - basePos.x;
|
|
35966
|
+
var dy = object.position.y - basePos.y;
|
|
35967
|
+
var dz = object.position.z - basePos.z;
|
|
35968
|
+
if (dx === 0 && dy === 0 && dz === 0) return stored;
|
|
35969
|
+
return {
|
|
35970
|
+
min: [stored.min[0] + dx, stored.min[1] + dy, stored.min[2] + dz],
|
|
35971
|
+
max: [stored.max[0] + dx, stored.max[1] + dy, stored.max[2] + dz]
|
|
35972
|
+
};
|
|
35973
|
+
}
|
|
35974
|
+
|
|
35975
|
+
// Slow path: full vertex-accurate traversal (fallback when userData not populated)
|
|
35976
|
+
if (this._bboxCache.has(object.uuid)) {
|
|
35977
|
+
return this._bboxCache.get(object.uuid);
|
|
35978
|
+
}
|
|
36005
35979
|
var box = computeFilteredBoundingBox(object, []);
|
|
35980
|
+
var result;
|
|
36006
35981
|
if (box.isEmpty()) {
|
|
36007
35982
|
// Object has no geometry; fall back to a point at world position
|
|
36008
35983
|
var wp = new THREE__namespace.Vector3();
|
|
36009
35984
|
object.getWorldPosition(wp);
|
|
36010
|
-
|
|
35985
|
+
result = {
|
|
36011
35986
|
min: [wp.x, wp.y, wp.z],
|
|
36012
35987
|
max: [wp.x, wp.y, wp.z]
|
|
36013
35988
|
};
|
|
35989
|
+
} else {
|
|
35990
|
+
result = {
|
|
35991
|
+
min: [box.min.x, box.min.y, box.min.z],
|
|
35992
|
+
max: [box.max.x, box.max.y, box.max.z]
|
|
35993
|
+
};
|
|
36014
35994
|
}
|
|
36015
|
-
|
|
36016
|
-
|
|
36017
|
-
max: [box.max.x, box.max.y, box.max.z]
|
|
36018
|
-
};
|
|
35995
|
+
this._bboxCache.set(object.uuid, result);
|
|
35996
|
+
return result;
|
|
36019
35997
|
}
|
|
36020
35998
|
|
|
36021
35999
|
/**
|
|
@@ -36024,11 +36002,12 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36024
36002
|
}, {
|
|
36025
36003
|
key: "getComponentDimensions",
|
|
36026
36004
|
value: function getComponentDimensions(component) {
|
|
36027
|
-
var _component$
|
|
36028
|
-
//
|
|
36029
|
-
//
|
|
36030
|
-
//
|
|
36031
|
-
|
|
36005
|
+
var _component$getWorldPo;
|
|
36006
|
+
// Always recompute from the live Three.js object so that the rect reflects
|
|
36007
|
+
// the current world position after translate/drag operations.
|
|
36008
|
+
// userData.worldBoundingBox is a load-time snapshot and goes stale whenever
|
|
36009
|
+
// the object moves, so we cannot rely on it here.
|
|
36010
|
+
var wbb = this._getOrComputeWorldBoundingBox(component);
|
|
36032
36011
|
if (wbb !== null && wbb !== void 0 && wbb.min && wbb !== null && wbb !== void 0 && wbb.max) {
|
|
36033
36012
|
var _wbb$min = _slicedToArray(wbb.min, 3),
|
|
36034
36013
|
minX = _wbb$min[0],
|
|
@@ -36139,7 +36118,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36139
36118
|
rect.stroke('#007bff');
|
|
36140
36119
|
rect.strokeWidth(3);
|
|
36141
36120
|
viewport.stage.container().style.cursor = 'grab';
|
|
36142
|
-
viewport.componentLayer.
|
|
36121
|
+
viewport.componentLayer.batchDraw();
|
|
36143
36122
|
}
|
|
36144
36123
|
});
|
|
36145
36124
|
rect.on('mouseleave', function () {
|
|
@@ -36148,7 +36127,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36148
36127
|
rect.stroke(colors.stroke);
|
|
36149
36128
|
rect.strokeWidth(2);
|
|
36150
36129
|
viewport.stage.container().style.cursor = 'default';
|
|
36151
|
-
viewport.componentLayer.
|
|
36130
|
+
viewport.componentLayer.batchDraw();
|
|
36152
36131
|
}
|
|
36153
36132
|
});
|
|
36154
36133
|
|
|
@@ -36192,7 +36171,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36192
36171
|
// Snap to grid
|
|
36193
36172
|
var snappedPos = _this6.snapScreenToGrid(viewport, currentPos.x, currentPos.y, scale, worldOriginX, worldOriginY);
|
|
36194
36173
|
componentGroup.position(snappedPos);
|
|
36195
|
-
viewport.componentLayer.
|
|
36174
|
+
viewport.componentLayer.batchDraw();
|
|
36196
36175
|
});
|
|
36197
36176
|
|
|
36198
36177
|
// DRAG END
|
|
@@ -36365,18 +36344,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36365
36344
|
}, {
|
|
36366
36345
|
key: "getSceneComponents",
|
|
36367
36346
|
value: function getSceneComponents() {
|
|
36347
|
+
if (this._componentListCache) return this._componentListCache;
|
|
36368
36348
|
if (!this.sceneViewer || !this.sceneViewer.scene) {
|
|
36369
36349
|
return [];
|
|
36370
36350
|
}
|
|
36371
36351
|
var components = [];
|
|
36372
36352
|
this.sceneViewer.scene.traverse(function (object) {
|
|
36373
|
-
var _object$
|
|
36353
|
+
var _object$userData3, _object$userData4;
|
|
36374
36354
|
// Only match the ROOT component object — must have both objectType:'component'
|
|
36375
36355
|
// AND libraryId (inner GLB mesh nodes don't have libraryId)
|
|
36376
|
-
if (((_object$
|
|
36356
|
+
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
36357
|
components.push(object);
|
|
36378
36358
|
}
|
|
36379
36359
|
});
|
|
36360
|
+
this._componentListCache = components;
|
|
36380
36361
|
return components;
|
|
36381
36362
|
}
|
|
36382
36363
|
|
|
@@ -36482,35 +36463,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36482
36463
|
}
|
|
36483
36464
|
|
|
36484
36465
|
/**
|
|
36485
|
-
* Refresh a specific viewport or all viewports
|
|
36466
|
+
* Refresh a specific viewport or all viewports.
|
|
36467
|
+
* Debounced via requestAnimationFrame so multiple calls within the same
|
|
36468
|
+
* frame (e.g. from Viewport2D mount + refreshAll2DViews) collapse into one.
|
|
36486
36469
|
* @param {string} key - Optional viewport key. If not provided, refreshes all viewports
|
|
36487
36470
|
*/
|
|
36488
36471
|
}, {
|
|
36489
36472
|
key: "refresh",
|
|
36490
36473
|
value: function refresh() {
|
|
36474
|
+
var _this7 = this;
|
|
36491
36475
|
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
|
-
|
|
36476
|
+
if (this._refreshPending) return;
|
|
36477
|
+
this._refreshPending = true;
|
|
36478
|
+
requestAnimationFrame(function () {
|
|
36479
|
+
_this7._refreshPending = false;
|
|
36480
|
+
// Clear per-cycle caches so each component is measured/traversed once per paint
|
|
36481
|
+
_this7._bboxCache.clear();
|
|
36482
|
+
_this7._componentListCache = null;
|
|
36483
|
+
if (key) {
|
|
36484
|
+
var viewport = _this7.viewports.get(key);
|
|
36485
|
+
if (viewport && viewport.isReady) {
|
|
36486
|
+
_this7.renderComponents(viewport);
|
|
36487
|
+
}
|
|
36488
|
+
} else {
|
|
36489
|
+
var _iterator = _createForOfIteratorHelper(_this7.viewports.values()),
|
|
36490
|
+
_step;
|
|
36491
|
+
try {
|
|
36492
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
36493
|
+
var _viewport = _step.value;
|
|
36494
|
+
if (_viewport.isReady) {
|
|
36495
|
+
_this7.renderComponents(_viewport);
|
|
36496
|
+
}
|
|
36506
36497
|
}
|
|
36498
|
+
} catch (err) {
|
|
36499
|
+
_iterator.e(err);
|
|
36500
|
+
} finally {
|
|
36501
|
+
_iterator.f();
|
|
36507
36502
|
}
|
|
36508
|
-
} catch (err) {
|
|
36509
|
-
_iterator.e(err);
|
|
36510
|
-
} finally {
|
|
36511
|
-
_iterator.f();
|
|
36512
36503
|
}
|
|
36513
|
-
}
|
|
36504
|
+
});
|
|
36514
36505
|
}
|
|
36515
36506
|
|
|
36516
36507
|
/**
|
|
@@ -37830,7 +37821,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37830
37821
|
* Initialize the CentralPlant manager
|
|
37831
37822
|
*
|
|
37832
37823
|
* @constructor
|
|
37833
|
-
* @version 0.3.
|
|
37824
|
+
* @version 0.3.7
|
|
37834
37825
|
* @updated 2025-10-22
|
|
37835
37826
|
*
|
|
37836
37827
|
* @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.7
|
|
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
|