@2112-lab/central-plant 0.1.39 → 0.1.41

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.
Files changed (45) hide show
  1. package/dist/bundle/index.js +7991 -7054
  2. package/dist/cjs/src/core/centralPlant.js +48 -3
  3. package/dist/cjs/src/core/centralPlantInternals.js +75 -566
  4. package/dist/cjs/src/core/sceneViewer.js +38 -13
  5. package/dist/cjs/src/index.js +6 -4
  6. package/dist/cjs/src/managers/components/pathfindingManager.js +75 -60
  7. package/dist/cjs/src/managers/components/transformOperationsManager.js +929 -0
  8. package/dist/cjs/src/managers/controls/keyboardControlsManager.js +57 -1
  9. package/dist/cjs/src/managers/controls/transformControls.js +11 -3
  10. package/dist/cjs/src/managers/controls/transformControlsManager.js +563 -263
  11. package/dist/cjs/src/managers/pathfinding/ConnectorManager.js +385 -0
  12. package/dist/cjs/src/managers/pathfinding/PathIntersectionDetector.js +387 -0
  13. package/dist/cjs/src/managers/pathfinding/PathRenderingManager.js +401 -0
  14. package/dist/cjs/src/managers/pathfinding/pathfindingManager.js +378 -0
  15. package/dist/cjs/src/managers/pathfinding/sceneDataManager.js +256 -0
  16. package/dist/cjs/src/managers/scene/animationManager.js +145 -0
  17. package/dist/cjs/src/managers/scene/sceneExportManager.js +14 -13
  18. package/dist/cjs/src/managers/scene/sceneOperationsManager.js +516 -21
  19. package/dist/cjs/src/managers/scene/sceneTooltipsManager.js +1 -8
  20. package/dist/cjs/src/managers/system/operationHistoryManager.js +414 -0
  21. package/dist/cjs/src/managers/system/settingsManager.js +2 -1
  22. package/dist/cjs/src/utils/objectTypes.js +5 -7
  23. package/dist/esm/src/core/centralPlant.js +48 -3
  24. package/dist/esm/src/core/centralPlantInternals.js +76 -567
  25. package/dist/esm/src/core/sceneViewer.js +38 -13
  26. package/dist/esm/src/index.js +4 -3
  27. package/dist/esm/src/managers/components/pathfindingManager.js +75 -60
  28. package/dist/esm/src/managers/components/transformOperationsManager.js +904 -0
  29. package/dist/esm/src/managers/controls/keyboardControlsManager.js +57 -1
  30. package/dist/esm/src/managers/controls/transformControls.js +11 -3
  31. package/dist/esm/src/managers/controls/transformControlsManager.js +564 -264
  32. package/dist/esm/src/managers/pathfinding/ConnectorManager.js +361 -0
  33. package/dist/esm/src/managers/pathfinding/PathIntersectionDetector.js +363 -0
  34. package/dist/esm/src/managers/pathfinding/PathRenderingManager.js +377 -0
  35. package/dist/esm/src/managers/pathfinding/pathfindingManager.js +374 -0
  36. package/dist/esm/src/managers/pathfinding/sceneDataManager.js +232 -0
  37. package/dist/esm/src/managers/scene/animationManager.js +141 -0
  38. package/dist/esm/src/managers/scene/sceneExportManager.js +14 -13
  39. package/dist/esm/src/managers/scene/sceneOperationsManager.js +516 -21
  40. package/dist/esm/src/managers/scene/sceneTooltipsManager.js +1 -8
  41. package/dist/esm/src/managers/system/operationHistoryManager.js +409 -0
  42. package/dist/esm/src/managers/system/settingsManager.js +2 -1
  43. package/dist/esm/src/utils/objectTypes.js +5 -7
  44. package/dist/index.d.ts +2 -2
  45. package/package.json +1 -1
@@ -0,0 +1,374 @@
1
+ import { inherits as _inherits, createClass as _createClass, superPropGet as _superPropGet, classCallCheck as _classCallCheck, callSuper as _callSuper, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../../../_virtual/_rollupPluginBabelHelpers.js';
2
+ import 'three';
3
+ import { Pathfinder } from '@2112-lab/pathfinder';
4
+ import { BaseDisposable } from '../../core/baseDisposable.js';
5
+ import { PathData } from '../../core/pathfindingData.js';
6
+ import { PathIntersectionDetector } from './PathIntersectionDetector.js';
7
+ import { SceneDataManager } from './sceneDataManager.js';
8
+ import { PathRenderingManager } from './PathRenderingManager.js';
9
+ import { ConnectorManager } from './ConnectorManager.js';
10
+
11
+ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
12
+ function PathfindingManager(sceneViewer) {
13
+ var _this;
14
+ _classCallCheck(this, PathfindingManager);
15
+ _this = _callSuper(this, PathfindingManager);
16
+ _this.sceneViewer = sceneViewer;
17
+ _this.pathfinder = null;
18
+ _this.crosscubeTextureSet = null;
19
+ _this.pathfinderVersionInfo = null;
20
+
21
+ // Initialize scene data manager
22
+ _this.sceneDataManager = new SceneDataManager(sceneViewer);
23
+
24
+ // Initialize intersection detector
25
+ _this.intersectionDetector = new PathIntersectionDetector(sceneViewer);
26
+
27
+ // Initialize rendering manager
28
+ _this.renderingManager = new PathRenderingManager(sceneViewer);
29
+ _this.registerDisposable(_this.renderingManager);
30
+
31
+ // Initialize connector manager
32
+ _this.connectorManager = new ConnectorManager(sceneViewer);
33
+ _this.registerDisposable(_this.connectorManager);
34
+
35
+ // NEW: PathData store for business logic layer
36
+ _this.pathDataStore = new Map(); // pathId -> PathData
37
+
38
+ // Configuration for pathfinder grid
39
+ _this.pathfinderConfig = {
40
+ grid: {
41
+ size: 0.5,
42
+ safetyMargin: 0,
43
+ minSegmentLength: 0.5,
44
+ timeout: 1000
45
+ },
46
+ connectorBBoxSize: 0.1 // Default size for position-based connectors (Phase 2 Refactoring)
47
+ };
48
+ return _this;
49
+ }
50
+
51
+ /**
52
+ * Export path data as JSON
53
+ * @returns {Array<Object>} Array of serialized PathData objects
54
+ */
55
+ _inherits(PathfindingManager, _BaseDisposable);
56
+ return _createClass(PathfindingManager, [{
57
+ key: "exportData",
58
+ value: function exportData() {
59
+ var exportData = Array.from(this.pathDataStore.values()).map(function (pathData) {
60
+ return pathData.toJSON();
61
+ });
62
+ console.log("\uD83D\uDCE4 Exported ".concat(exportData.length, " path data objects"));
63
+ return exportData;
64
+ }
65
+
66
+ /**
67
+ * Import path data from JSON
68
+ * @param {Array<Object>} jsonArray - Array of serialized PathData objects
69
+ */
70
+ }, {
71
+ key: "importData",
72
+ value: function importData(jsonArray) {
73
+ var _this2 = this;
74
+ if (!Array.isArray(jsonArray)) {
75
+ console.error('❌ importData expects an array');
76
+ return;
77
+ }
78
+ this.pathDataStore.clear();
79
+ jsonArray.forEach(function (json) {
80
+ try {
81
+ var pathData = PathData.fromJSON(json);
82
+ _this2.pathDataStore.set(pathData.pathId, pathData);
83
+ console.log("\uD83D\uDCE5 Imported PathData: ".concat(pathData.pathId));
84
+ } catch (error) {
85
+ console.error('❌ Error importing PathData:', error);
86
+ }
87
+ });
88
+ console.log("\u2705 Imported ".concat(this.pathDataStore.size, " path data objects"));
89
+ }
90
+
91
+ // ============================================================================
92
+ // END NEW ADAPTER METHODS
93
+ // ============================================================================
94
+
95
+ /**
96
+ * Core pathfinding logic shared across initialization and updates
97
+ */
98
+ }, {
99
+ key: "_executePathfinding",
100
+ value: function () {
101
+ var _executePathfinding2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(sceneData, connections) {
102
+ var _simplifiedSceneData$;
103
+ var options,
104
+ _options$context,
105
+ context,
106
+ connectionsCopy,
107
+ simplifiedSceneData,
108
+ pathfindingResult,
109
+ intersectionCheck,
110
+ _args = arguments;
111
+ return _regenerator().w(function (_context) {
112
+ while (1) switch (_context.n) {
113
+ case 0:
114
+ options = _args.length > 2 && _args[2] !== undefined ? _args[2] : {};
115
+ options.createGateways, _options$context = options.context, context = _options$context === void 0 ? 'Pathfinding' : _options$context; // Create pathfinder instance with configuration only
116
+ this.pathfinder = new Pathfinder(this.pathfinderConfig);
117
+ this.sceneViewer.pathfinder = this.pathfinder;
118
+
119
+ // Ensure all matrices are up to date before bounding box calculations (for all pathfinding executions)
120
+ this.sceneViewer.scene.updateMatrixWorld(true);
121
+ console.log("\uD83D\uDD04 Updated matrix world for ".concat(context, " pathfinding execution"));
122
+
123
+ // Deep copy connections to prevent pathfinder from mutating the original
124
+ connectionsCopy = JSON.parse(JSON.stringify(connections));
125
+ simplifiedSceneData = JSON.parse(JSON.stringify(this.getSimplifiedSceneData()));
126
+ console.log('[Pathfinder] simplifiedSceneData length at creation:', (_simplifiedSceneData$ = simplifiedSceneData.children) === null || _simplifiedSceneData$ === void 0 ? void 0 : _simplifiedSceneData$.length);
127
+ console.log('[Pathfinder] simplifiedSceneData (deep clone for inspection):', JSON.parse(JSON.stringify(simplifiedSceneData)));
128
+
129
+ // Add debugging for pathfinder input
130
+ console.log('🔍 PATHFINDER DEBUGGING:');
131
+ console.log('🔗 [Pathfinder] Connections:', JSON.parse(JSON.stringify(connectionsCopy)));
132
+
133
+ // Find paths using v1.0.17 API (sceneData and connections separately)
134
+ // Pass deep copy to ensure pathfinder cannot mutate original connections
135
+ pathfindingResult = this.pathfinder.findPaths(simplifiedSceneData, connectionsCopy);
136
+ console.log('[Pathfinder] Found paths:', JSON.parse(JSON.stringify(pathfindingResult.paths)));
137
+ console.log('Generated gateways:', JSON.parse(JSON.stringify(pathfindingResult.gateways)));
138
+ console.log('Rewired connections:', JSON.parse(JSON.stringify(pathfindingResult.rewiredConnections)));
139
+ console.log("intersectionCheck input:", pathfindingResult.paths);
140
+
141
+ // Check for path intersections (including manual segments)
142
+ intersectionCheck = this.checkPathIntersections(pathfindingResult.paths, 0.2, true);
143
+ pathfindingResult.intersections = intersectionCheck;
144
+ console.log("intersectionCheck:", intersectionCheck);
145
+ console.log("intersectionCheck.hasIntersections:", intersectionCheck.hasIntersections);
146
+
147
+ // // Handle intersection detection - undo last operation if intersections found
148
+ // if (intersectionCheck.hasIntersections) {
149
+ // console.warn('⚠️ Path intersections detected! Attempting to undo last operation...');
150
+
151
+ // // Access operationHistoryManager through sceneViewer.managers.operationHistory
152
+ // const operationHistoryManager = this.sceneViewer?.managers?.operationHistory;
153
+
154
+ // if (operationHistoryManager) {
155
+ // const lastOp = operationHistoryManager.getLastOperation();
156
+
157
+ // if (lastOp) {
158
+ // console.warn(`⚠️ Intersection caused by operation: ${lastOp.operationName}`, lastOp.params);
159
+
160
+ // // Attempt to undo the operation
161
+ // const undoSuccess = operationHistoryManager.undoLastOperation();
162
+
163
+ // if (undoSuccess) {
164
+ // console.log('✅ Successfully undid operation that caused intersection');
165
+
166
+ // // Re-run pathfinding after undo to restore valid state
167
+ // console.log('🔄 Re-running pathfinding after undo...');
168
+
169
+ // // Note: We don't recursively call _executePathfinding here to avoid potential infinite loops
170
+ // // Instead, the calling code (updatePathfindingAfterTransform) will handle re-execution
171
+ // pathfindingResult.undoPerformed = true;
172
+ // pathfindingResult.undoneOperation = lastOp;
173
+ // } else {
174
+ // console.error('❌ Failed to undo operation that caused intersection');
175
+ // pathfindingResult.undoFailed = true;
176
+ // }
177
+ // } else {
178
+ // console.warn('⚠️ No operation in history to undo');
179
+ // }
180
+ // } else {
181
+ // console.error('❌ OperationHistoryManager not available for undo');
182
+ // console.error(' Available managers:', Object.keys(this.sceneViewer?.managers || {}));
183
+ // }
184
+ // }
185
+
186
+ // Create gateways in the scene if requested
187
+ if (options.createGateways && pathfindingResult.gateways) {
188
+ this.renderingManager.createGateways(pathfindingResult);
189
+ }
190
+ console.log("pathfindingResult.paths:", pathfindingResult.paths);
191
+
192
+ // Create pipe paths with materials using the paths from pathfinder
193
+ this.renderingManager.createPipePaths(pathfindingResult.paths, this.crosscubeTextureSet);
194
+ return _context.a(2, pathfindingResult);
195
+ }
196
+ }, _callee, this);
197
+ }));
198
+ function _executePathfinding(_x, _x2) {
199
+ return _executePathfinding2.apply(this, arguments);
200
+ }
201
+ return _executePathfinding;
202
+ }()
203
+ }, {
204
+ key: "getSimplifiedSceneData",
205
+ value: function getSimplifiedSceneData() {
206
+ return this.sceneDataManager.getSimplifiedSceneData();
207
+ }
208
+
209
+ /**
210
+ * Initialize pathfinder and create paths
211
+ */
212
+ }, {
213
+ key: "initializePathfinder",
214
+ value: (function () {
215
+ var _initializePathfinder = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(data, crosscubeTextureSet) {
216
+ var pathfindingResult;
217
+ return _regenerator().w(function (_context2) {
218
+ while (1) switch (_context2.n) {
219
+ case 0:
220
+ this.crosscubeTextureSet = crosscubeTextureSet;
221
+
222
+ // Use shared pathfinding logic with gateway creation enabled
223
+ _context2.n = 1;
224
+ return this._executePathfinding(data.scene, data.connections, {
225
+ createGateways: true,
226
+ context: 'Scene Loading'
227
+ });
228
+ case 1:
229
+ pathfindingResult = _context2.v;
230
+ // Update connections with rewired connections
231
+ if (pathfindingResult.rewiredConnections) {
232
+ // data.connections = pathfindingResult.rewiredConnections;
233
+ console.log('🔄 Updated connections with rewired connections:', data.connections);
234
+ }
235
+
236
+ // Return full result for potential additional processing
237
+ return _context2.a(2, pathfindingResult);
238
+ }
239
+ }, _callee2, this);
240
+ }));
241
+ function initializePathfinder(_x3, _x4) {
242
+ return _initializePathfinder.apply(this, arguments);
243
+ }
244
+ return initializePathfinder;
245
+ }()
246
+ /**
247
+ * Remove all computed objects from the scene (segments, elbows, and gateways)
248
+ */
249
+ )
250
+ }, {
251
+ key: "removeComputedObjects",
252
+ value: function removeComputedObjects() {
253
+ var sceneViewer = this.sceneViewer;
254
+ console.log("removeComputedObjects started");
255
+ var objectsToRemove = [];
256
+ sceneViewer.scene.traverse(function (obj) {
257
+ // Remove computed Segments (uppercase SEGMENT-)
258
+ if (obj.uuid && obj.uuid.startsWith("SEGMENT-")) {
259
+ console.log("[removeComputedObjects] to be removed: ".concat(obj.uuid, ")"));
260
+ objectsToRemove.push(obj);
261
+ }
262
+ // Remove computed Elbows
263
+ if (obj.userData && obj.userData.isPipeElbow && obj.userData.isDeclared !== true) {
264
+ console.log("[removeComputedObjects] to be removed: ".concat(obj.uuid, ")"));
265
+ objectsToRemove.push(obj);
266
+ }
267
+ // Also remove computed Gateways
268
+ if (obj.uuid && obj.uuid.includes("Gateway") && obj.userData && obj.userData.isDeclared !== true) {
269
+ console.log("[removeComputedObjects] to be removed: ".concat(obj.uuid));
270
+ objectsToRemove.push(obj);
271
+ }
272
+ });
273
+
274
+ // console.log(`[removeComputedObjects] objectsToRemove:`, objectsToRemove);
275
+
276
+ for (var _i = 0, _objectsToRemove = objectsToRemove; _i < _objectsToRemove.length; _i++) {
277
+ var obj = _objectsToRemove[_i];
278
+ sceneViewer.scene.remove(obj);
279
+ if (obj.geometry) obj.geometry.dispose();
280
+ if (obj.material) {
281
+ if (Array.isArray(obj.material)) {
282
+ obj.material.forEach(function (mat) {
283
+ return mat.dispose();
284
+ });
285
+ } else {
286
+ obj.material.dispose();
287
+ }
288
+ }
289
+ }
290
+ console.log("\u2705 Removed ".concat(objectsToRemove.length, " computed objects from scene (segments, elbows, and gateways)"));
291
+ }
292
+
293
+ /**
294
+ * Check for intersections between paths
295
+ * Delegates to PathIntersectionDetector for the actual detection logic
296
+ * @param {Array} paths - Array of path objects from pathfinder
297
+ * @param {number} tolerance - Distance tolerance for considering pipes as intersecting (default: 0.2)
298
+ * @param {boolean} includeManualSegments - Whether to include manual segments in the check (default: true)
299
+ * @returns {Object} Intersection results
300
+ * @property {boolean} hasIntersections - Whether any intersections were found
301
+ * @property {Array<Object>} intersections - Array of intersection details
302
+ * @property {number} count - Total number of intersections found
303
+ */
304
+ }, {
305
+ key: "checkPathIntersections",
306
+ value: function checkPathIntersections(paths) {
307
+ var tolerance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.2;
308
+ var includeManualSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
309
+ return this.intersectionDetector.checkPathIntersections(paths, tolerance, includeManualSegments);
310
+ }
311
+
312
+ /**
313
+ * Update pathfinding after object transforms
314
+ */
315
+ }, {
316
+ key: "updatePathfindingAfterTransform",
317
+ value: (function () {
318
+ var _updatePathfindingAfterTransform = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(currentSceneData) {
319
+ return _regenerator().w(function (_context3) {
320
+ while (1) switch (_context3.n) {
321
+ case 0:
322
+ // Remove all existing paths from the scene
323
+ this.removeComputedObjects();
324
+ console.log('🔄 Starting pathfinding with updated scene data...');
325
+
326
+ // Note: Matrix updates and bounding box recomputation now handled in _executePathfinding
327
+ // Use shared pathfinding logic (no gateways needed for transform updates)
328
+ _context3.n = 1;
329
+ return this._executePathfinding(currentSceneData.scene, currentSceneData.connections, {
330
+ createGateways: true,
331
+ context: 'Transform Update'
332
+ });
333
+ case 1:
334
+ return _context3.a(2);
335
+ }
336
+ }, _callee3, this);
337
+ }));
338
+ function updatePathfindingAfterTransform(_x5) {
339
+ return _updatePathfindingAfterTransform.apply(this, arguments);
340
+ }
341
+ return updatePathfindingAfterTransform;
342
+ }()
343
+ /**
344
+ * Dispose of pathfinding resources
345
+ */
346
+ )
347
+ }, {
348
+ key: "dispose",
349
+ value: function dispose() {
350
+ console.log('🗑️ Disposing PathfindingManager...');
351
+
352
+ // Clear path data store
353
+ if (this.pathDataStore) {
354
+ this.pathDataStore.clear();
355
+ console.log('✅ Cleared pathDataStore');
356
+ }
357
+
358
+ // Remove computed objects
359
+ this.removeComputedObjects();
360
+
361
+ // Call parent dispose to clean up registered resources
362
+ _superPropGet(PathfindingManager, "dispose", this, 3)([]);
363
+
364
+ // Nullify properties
365
+ this.pathfinder = null;
366
+ this.crosscubeTextureSet = null;
367
+ this.pathfinderVersionInfo = null;
368
+ this.sceneViewer = null;
369
+ console.log('✅ PathfindingManager disposed');
370
+ }
371
+ }]);
372
+ }(BaseDisposable);
373
+
374
+ export { PathfindingManager };
@@ -0,0 +1,232 @@
1
+ import { createClass as _createClass, objectSpread2 as _objectSpread2, classCallCheck as _classCallCheck, createForOfIteratorHelper as _createForOfIteratorHelper } from '../../../_virtual/_rollupPluginBabelHelpers.js';
2
+ import * as THREE from 'three';
3
+
4
+ /**
5
+ * SceneDataManager
6
+ * Utility class for managing scene data transformations and queries
7
+ * Handles scene structure flattening, simplification, and object lookups
8
+ */
9
+ var SceneDataManager = /*#__PURE__*/function () {
10
+ function SceneDataManager(sceneViewer) {
11
+ _classCallCheck(this, SceneDataManager);
12
+ this.sceneViewer = sceneViewer;
13
+ }
14
+
15
+ /**
16
+ * Get simplified scene data for pathfinding
17
+ * Collects all objects with objectType, filters out computed objects,
18
+ * and calculates world bounding boxes
19
+ * @returns {Object} Simplified scene data with children array
20
+ */
21
+ return _createClass(SceneDataManager, [{
22
+ key: "getSimplifiedSceneData",
23
+ value: function getSimplifiedSceneData() {
24
+ // Collect all objects with objectType (flattened list from scene traversal)
25
+ // Filter out ALL computed objects - only include declared/source objects
26
+ var sceneDataNew = [];
27
+ this.sceneViewer.scene.traverse(function (obj) {
28
+ if (obj.userData && obj.userData.objectType) {
29
+ // Skip computed gateways (only include declared/manual gateways)
30
+ if (obj.userData.objectType === 'gateway' && !obj.userData.isDeclared) {
31
+ return;
32
+ }
33
+ sceneDataNew.push(obj);
34
+ }
35
+ });
36
+ console.log('🔗 [SceneDataManager] sceneDataNew (flattened):', sceneDataNew);
37
+
38
+ // Calculate world bounding boxes for each object individually (after flattening)
39
+ // This way we don't need to worry about children - each object is standalone
40
+ var simplifiedSceneData = {};
41
+ simplifiedSceneData.children = sceneDataNew.map(function (obj) {
42
+ var _obj$children;
43
+ var uuid = obj.uuid;
44
+
45
+ // Calculate world bounding box for this individual object
46
+ var worldBoundingBox = null;
47
+
48
+ // For meshes, calculate bbox from geometry only (ignoring children)
49
+ if (obj.isMesh && obj.geometry) {
50
+ try {
51
+ // Compute bounding box from geometry in world space
52
+ var bbox = new THREE.Box3();
53
+ obj.geometry.computeBoundingBox();
54
+ if (obj.geometry.boundingBox) {
55
+ // Transform local bbox to world space
56
+ bbox.copy(obj.geometry.boundingBox);
57
+ bbox.applyMatrix4(obj.matrixWorld);
58
+
59
+ // Only include valid bounding boxes
60
+ // Check if all components of min and max are finite numbers
61
+ var isValidBBox = !bbox.isEmpty() && isFinite(bbox.min.x) && isFinite(bbox.min.y) && isFinite(bbox.min.z) && isFinite(bbox.max.x) && isFinite(bbox.max.y) && isFinite(bbox.max.z);
62
+ if (isValidBBox) {
63
+ worldBoundingBox = {
64
+ min: bbox.min.toArray(),
65
+ max: bbox.max.toArray()
66
+ };
67
+ } else {
68
+ console.warn("\u26A0\uFE0F Invalid bounding box for ".concat(uuid, ", skipping"));
69
+ }
70
+ }
71
+ } catch (error) {
72
+ console.warn("\u26A0\uFE0F Failed to calculate bounding box for ".concat(uuid, ":"), error);
73
+ }
74
+ }
75
+ // For groups or objects with children, use setFromObject but only on this object
76
+ else if (obj.isGroup || ((_obj$children = obj.children) === null || _obj$children === void 0 ? void 0 : _obj$children.length) > 0) {
77
+ try {
78
+ var _bbox = new THREE.Box3().setFromObject(obj);
79
+
80
+ // Check if all components of min and max are finite numbers
81
+ var _isValidBBox = !_bbox.isEmpty() && isFinite(_bbox.min.x) && isFinite(_bbox.min.y) && isFinite(_bbox.min.z) && isFinite(_bbox.max.x) && isFinite(_bbox.max.y) && isFinite(_bbox.max.z);
82
+ if (_isValidBBox) {
83
+ worldBoundingBox = {
84
+ min: _bbox.min.toArray(),
85
+ max: _bbox.max.toArray()
86
+ };
87
+ }
88
+ } catch (error) {
89
+ console.warn("\u26A0\uFE0F Failed to calculate bounding box for ".concat(uuid, ":"), error);
90
+ }
91
+ }
92
+ var results = {
93
+ uuid: uuid,
94
+ userData: _objectSpread2(_objectSpread2({}, obj.userData), worldBoundingBox && {
95
+ worldBoundingBox: worldBoundingBox
96
+ })
97
+ };
98
+ if (obj.userData.objectType.includes('connector') || obj.userData.objectType === 'gateway') {
99
+ var worldPosition = new THREE.Vector3();
100
+ obj.getWorldPosition(worldPosition);
101
+ results.userData.position = [worldPosition.x, worldPosition.y, worldPosition.z];
102
+ }
103
+ return results;
104
+ });
105
+ return simplifiedSceneData;
106
+ }
107
+
108
+ /**
109
+ * Helper method to find an object in scene data by UUID
110
+ * @param {Object} sceneData - Scene data to search
111
+ * @param {string} uuid - UUID to find
112
+ * @returns {Object|null} Found object or null
113
+ */
114
+ }, {
115
+ key: "findObjectInSceneData",
116
+ value: function findObjectInSceneData(sceneData, uuid) {
117
+ var _searchChildren = function searchChildren(children) {
118
+ var _iterator = _createForOfIteratorHelper(children),
119
+ _step;
120
+ try {
121
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
122
+ var child = _step.value;
123
+ if (child.uuid === uuid) {
124
+ return child;
125
+ }
126
+ if (child.children) {
127
+ var found = _searchChildren(child.children);
128
+ if (found) return found;
129
+ }
130
+ }
131
+ } catch (err) {
132
+ _iterator.e(err);
133
+ } finally {
134
+ _iterator.f();
135
+ }
136
+ return null;
137
+ };
138
+ if (sceneData.children) {
139
+ return _searchChildren(sceneData.children);
140
+ }
141
+ return null;
142
+ }
143
+
144
+ /**
145
+ * Mark an object as declared (manual) in both the scene object and scene data
146
+ * @param {THREE.Object3D} object - The object to mark as declared
147
+ * @param {Object} currentSceneData - Current scene data
148
+ * @param {Object} additionalSceneDataProps - Additional properties to add to scene data (optional)
149
+ */
150
+ }, {
151
+ key: "markObjectAsDeclared",
152
+ value: function markObjectAsDeclared(object, currentSceneData) {
153
+ var additionalSceneDataProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
154
+ // Mark in the scene object
155
+ object.userData.isDeclared = true;
156
+
157
+ // Find and update in scene data
158
+ var foundInSceneData = false;
159
+ for (var i = 0; i < currentSceneData.scene.children.length; i++) {
160
+ var _object$userData, _child$userData;
161
+ var child = currentSceneData.scene.children[i];
162
+ if (child.uuid === object.uuid || child.uuid === ((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.originalUuid) || object.uuid === ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.originalUuid)) {
163
+ var _object$userData2, _object$userData3;
164
+ if (!child.userData) child.userData = {};
165
+ child.userData.isDeclared = true;
166
+
167
+ // Update position in scene data
168
+ if (!child.position) {
169
+ child.position = {};
170
+ }
171
+ child.position.x = object.position.x;
172
+ child.position.y = object.position.y;
173
+ child.position.z = object.position.z;
174
+
175
+ // For gateways and connectors, also update userData.position array for pathfinder compatibility
176
+ if (((_object$userData2 = object.userData) === null || _object$userData2 === void 0 ? void 0 : _object$userData2.objectType) === 'gateway' || ((_object$userData3 = object.userData) === null || _object$userData3 === void 0 ? void 0 : _object$userData3.objectType) === 'connector') {
177
+ child.userData.position = [object.position.x, object.position.y, object.position.z];
178
+ }
179
+ console.log("\u2705 Marked object as declared and updated position in scene data: ".concat(child.uuid));
180
+ foundInSceneData = true;
181
+ break;
182
+ }
183
+ }
184
+
185
+ // If not found in scene data, add it
186
+ if (!foundInSceneData) {
187
+ var _object$userData4, _object$userData5, _object$userData6;
188
+ console.log("\u26A0\uFE0F Object ".concat(object.uuid, " not found in scene data, adding it now"));
189
+ var sceneDataObject = _objectSpread2({
190
+ uuid: object.uuid,
191
+ userData: _objectSpread2({
192
+ objectType: object.userData.objectType,
193
+ isDeclared: true
194
+ }, object.userData),
195
+ position: {
196
+ x: object.position.x,
197
+ y: object.position.y,
198
+ z: object.position.z
199
+ }
200
+ }, additionalSceneDataProps);
201
+
202
+ // For gateways and connectors, also add position array to userData for pathfinder compatibility
203
+ if (((_object$userData4 = object.userData) === null || _object$userData4 === void 0 ? void 0 : _object$userData4.objectType) === 'gateway' || ((_object$userData5 = object.userData) === null || _object$userData5 === void 0 ? void 0 : _object$userData5.objectType) === 'connector') {
204
+ sceneDataObject.userData.position = [object.position.x, object.position.y, object.position.z];
205
+ }
206
+
207
+ // For segments, initialize children array to hold connectors
208
+ if (((_object$userData6 = object.userData) === null || _object$userData6 === void 0 ? void 0 : _object$userData6.objectType) === 'segment') {
209
+ sceneDataObject.children = [];
210
+ console.log("\uD83D\uDCE6 Initialized children array for segment: ".concat(object.uuid));
211
+ }
212
+ currentSceneData.scene.children.push(sceneDataObject);
213
+ console.log("\u2705 Added object to scene data as declared: ".concat(object.uuid));
214
+ } else {
215
+ var _object$userData8;
216
+ // If segment was found in scene data, ensure it has a children array
217
+ var _child = currentSceneData.scene.children.find(function (c) {
218
+ var _object$userData7, _c$userData;
219
+ return c.uuid === object.uuid || c.uuid === ((_object$userData7 = object.userData) === null || _object$userData7 === void 0 ? void 0 : _object$userData7.originalUuid) || object.uuid === ((_c$userData = c.userData) === null || _c$userData === void 0 ? void 0 : _c$userData.originalUuid);
220
+ });
221
+ if (_child && ((_object$userData8 = object.userData) === null || _object$userData8 === void 0 ? void 0 : _object$userData8.objectType) === 'segment') {
222
+ if (!_child.children) {
223
+ _child.children = [];
224
+ console.log("\uD83D\uDCE6 Initialized children array for existing segment: ".concat(_child.uuid));
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }]);
230
+ }();
231
+
232
+ export { SceneDataManager };