@2112-lab/central-plant 0.1.13 → 0.1.16
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 +1731 -89
- package/dist/cjs/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +462 -0
- package/dist/cjs/src/index.js +4 -0
- package/dist/cjs/src/rendering/modelPreloader.js +348 -83
- package/dist/cjs/src/rendering/objProcessor.js +703 -0
- package/dist/cjs/src/testing/objProcessingDemo.js +254 -0
- package/dist/esm/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +461 -2
- package/dist/esm/src/index.js +2 -0
- package/dist/esm/src/rendering/modelPreloader.js +348 -83
- package/dist/esm/src/rendering/objProcessor.js +678 -0
- package/dist/esm/src/testing/objProcessingDemo.js +249 -0
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelper
|
|
|
6
6
|
var THREE = require('three');
|
|
7
7
|
var GLTFLoader = require('../../node_modules/three/examples/jsm/loaders/GLTFLoader.js');
|
|
8
8
|
var OBJLoader = require('../../node_modules/three/examples/jsm/loaders/OBJLoader.js');
|
|
9
|
+
var objProcessor = require('./objProcessor.js');
|
|
9
10
|
|
|
10
11
|
function _interopNamespace(e) {
|
|
11
12
|
if (e && e.__esModule) return e;
|
|
@@ -34,10 +35,12 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
34
35
|
this.loadingPromises = new Map(); // Track ongoing loads to prevent duplicates
|
|
35
36
|
this.gltfLoader = new GLTFLoader.GLTFLoader();
|
|
36
37
|
this.objLoader = new OBJLoader.OBJLoader();
|
|
38
|
+
this.objProcessor = new objProcessor["default"](); // Initialize OBJ processor
|
|
37
39
|
this.isPreloading = false;
|
|
38
40
|
this.preloadingPromise = null;
|
|
39
41
|
this.componentDictionary = null;
|
|
40
42
|
console.log('🚀 ModelPreloader initialized with GLB and OBJ support');
|
|
43
|
+
console.log('🔧 OBJ Processor integrated for indexed BufferGeometry conversion');
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
/**
|
|
@@ -143,93 +146,137 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
143
146
|
}, {
|
|
144
147
|
key: "preloadSingleModel",
|
|
145
148
|
value: (function () {
|
|
146
|
-
var _preloadSingleModel = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function
|
|
149
|
+
var _preloadSingleModel = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee3(modelKey) {
|
|
147
150
|
var _this2 = this;
|
|
148
151
|
var modelType,
|
|
149
152
|
loadPromise,
|
|
150
|
-
|
|
151
|
-
return _rollupPluginBabelHelpers.regenerator().w(function (
|
|
152
|
-
while (1) switch (
|
|
153
|
+
_args3 = arguments;
|
|
154
|
+
return _rollupPluginBabelHelpers.regenerator().w(function (_context3) {
|
|
155
|
+
while (1) switch (_context3.n) {
|
|
153
156
|
case 0:
|
|
154
|
-
modelType =
|
|
157
|
+
modelType = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : 'glb';
|
|
155
158
|
if (!this.modelCache.has(modelKey)) {
|
|
156
|
-
|
|
159
|
+
_context3.n = 1;
|
|
157
160
|
break;
|
|
158
161
|
}
|
|
159
162
|
console.log("\uD83C\uDFAF Model ".concat(modelKey, " already cached, skipping"));
|
|
160
|
-
return
|
|
163
|
+
return _context3.a(2, this.modelCache.get(modelKey));
|
|
161
164
|
case 1:
|
|
162
165
|
if (!this.loadingPromises.has(modelKey)) {
|
|
163
|
-
|
|
166
|
+
_context3.n = 2;
|
|
164
167
|
break;
|
|
165
168
|
}
|
|
166
169
|
console.log("\u23F3 Model ".concat(modelKey, " already loading, waiting for completion"));
|
|
167
|
-
return
|
|
170
|
+
return _context3.a(2, this.loadingPromises.get(modelKey));
|
|
168
171
|
case 2:
|
|
169
172
|
console.log("\uD83D\uDD04 Starting preload of ".concat(modelType.toUpperCase(), " model: ").concat(modelKey));
|
|
170
173
|
loadPromise = new Promise(function (resolve, reject) {
|
|
171
174
|
var modelPath = "/library/models/".concat(modelKey);
|
|
172
175
|
if (modelType === 'obj') {
|
|
173
|
-
// Load OBJ model
|
|
174
|
-
_this2.objLoader.load(modelPath, function (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
176
|
+
// Load OBJ model with advanced processing
|
|
177
|
+
_this2.objLoader.load(modelPath, /*#__PURE__*/function () {
|
|
178
|
+
var _ref = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee2(object) {
|
|
179
|
+
var processedResult, modelData, _t;
|
|
180
|
+
return _rollupPluginBabelHelpers.regenerator().w(function (_context2) {
|
|
181
|
+
while (1) switch (_context2.n) {
|
|
182
|
+
case 0:
|
|
183
|
+
_context2.p = 0;
|
|
184
|
+
console.log("\u2705 Successfully loaded OBJ model: ".concat(modelKey));
|
|
185
|
+
|
|
186
|
+
// Process OBJ with the new processor for indexed BufferGeometry
|
|
187
|
+
_context2.n = 1;
|
|
188
|
+
return _this2.objProcessor.processObjObject(object, modelKey, true);
|
|
189
|
+
case 1:
|
|
190
|
+
processedResult = _context2.v;
|
|
191
|
+
if (!processedResult) {
|
|
192
|
+
_context2.n = 2;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
console.log("\uD83D\uDD27 OBJ processed to indexed BufferGeometry: ".concat(modelKey));
|
|
196
|
+
console.log("\uD83D\uDCCA Geometry stats:", processedResult.stats);
|
|
197
|
+
|
|
198
|
+
// Apply double-sided materials with solid + wireframe overlay
|
|
199
|
+
object.traverse(function (child) {
|
|
200
|
+
if (child.isMesh) {
|
|
201
|
+
// Create solid material
|
|
202
|
+
var solidMaterial = new THREE__namespace.MeshStandardMaterial({
|
|
203
|
+
color: child.material.color || 0x888888,
|
|
204
|
+
side: THREE__namespace.DoubleSide,
|
|
205
|
+
wireframe: false
|
|
206
|
+
// transparent: true,
|
|
207
|
+
// opacity: 0.8 // Slightly transparent to show wireframe better
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Create wireframe material
|
|
211
|
+
var wireframeMaterial = new THREE__namespace.MeshBasicMaterial({
|
|
212
|
+
color: 0x000000,
|
|
213
|
+
// Black wireframe
|
|
214
|
+
wireframe: true,
|
|
215
|
+
// transparent: true,
|
|
216
|
+
// opacity: 0.6,
|
|
217
|
+
side: THREE__namespace.DoubleSide
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Apply solid material to the original mesh
|
|
221
|
+
child.material = solidMaterial;
|
|
222
|
+
|
|
223
|
+
// Create a wireframe mesh clone and add it as a child
|
|
224
|
+
var wireframeMesh = new THREE__namespace.Mesh(child.geometry, wireframeMaterial);
|
|
225
|
+
wireframeMesh.position.copy(child.position);
|
|
226
|
+
wireframeMesh.rotation.copy(child.rotation);
|
|
227
|
+
wireframeMesh.scale.copy(child.scale);
|
|
228
|
+
wireframeMesh.name = child.name + '_wireframe';
|
|
229
|
+
wireframeMesh.userData.isWireframeOverlay = true;
|
|
230
|
+
|
|
231
|
+
// Add wireframe mesh to the same parent
|
|
232
|
+
if (child.parent) {
|
|
233
|
+
child.parent.add(wireframeMesh);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
// Store both the original object and processed data
|
|
238
|
+
modelData = {
|
|
239
|
+
originalObject: object,
|
|
240
|
+
processedGeometry: processedResult.geometry,
|
|
241
|
+
geometryStats: processedResult.stats,
|
|
242
|
+
materials: processedResult.materials,
|
|
243
|
+
isObjModel: true
|
|
244
|
+
}; // Cache the model data
|
|
245
|
+
_this2.modelCache.set(modelKey, modelData);
|
|
246
|
+
_this2.loadingPromises.delete(modelKey);
|
|
247
|
+
resolve(modelData);
|
|
248
|
+
_context2.n = 3;
|
|
249
|
+
break;
|
|
250
|
+
case 2:
|
|
251
|
+
throw new Error('Failed to process OBJ to indexed geometry');
|
|
252
|
+
case 3:
|
|
253
|
+
_context2.n = 5;
|
|
254
|
+
break;
|
|
255
|
+
case 4:
|
|
256
|
+
_context2.p = 4;
|
|
257
|
+
_t = _context2.v;
|
|
258
|
+
console.error("\u274C Error processing OBJ model ".concat(modelKey, ":"), _t);
|
|
259
|
+
// Fallback: cache the original object without processing
|
|
260
|
+
_this2.modelCache.set(modelKey, object);
|
|
261
|
+
_this2.loadingPromises.delete(modelKey);
|
|
262
|
+
resolve(object);
|
|
263
|
+
case 5:
|
|
264
|
+
return _context2.a(2);
|
|
212
265
|
}
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
_this2.loadingPromises.delete(modelKey);
|
|
220
|
-
resolve(object);
|
|
221
|
-
}, function (progress) {
|
|
222
|
-
// Optional: track loading progress
|
|
266
|
+
}, _callee2, null, [[0, 4]]);
|
|
267
|
+
}));
|
|
268
|
+
return function (_x3) {
|
|
269
|
+
return _ref.apply(this, arguments);
|
|
270
|
+
};
|
|
271
|
+
}(), function (progress) {
|
|
223
272
|
if (progress.lengthComputable) {
|
|
224
273
|
var percentage = progress.loaded / progress.total * 100;
|
|
225
274
|
if (percentage % 25 === 0) {
|
|
226
|
-
// Log every 25%
|
|
227
275
|
console.log("\uD83D\uDCCA Loading OBJ ".concat(modelKey, ": ").concat(percentage.toFixed(0), "%"));
|
|
228
276
|
}
|
|
229
277
|
}
|
|
230
278
|
}, function (error) {
|
|
231
279
|
console.error("\u274C Failed to preload OBJ model ".concat(modelKey, ":"), error);
|
|
232
|
-
// Remove from loading promises
|
|
233
280
|
_this2.loadingPromises.delete(modelKey);
|
|
234
281
|
reject(error);
|
|
235
282
|
});
|
|
@@ -260,9 +307,9 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
260
307
|
}
|
|
261
308
|
}); // Cache the loading promise
|
|
262
309
|
this.loadingPromises.set(modelKey, loadPromise);
|
|
263
|
-
return
|
|
310
|
+
return _context3.a(2, loadPromise);
|
|
264
311
|
}
|
|
265
|
-
},
|
|
312
|
+
}, _callee3, this);
|
|
266
313
|
}));
|
|
267
314
|
function preloadSingleModel(_x2) {
|
|
268
315
|
return _preloadSingleModel.apply(this, arguments);
|
|
@@ -272,18 +319,42 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
272
319
|
/**
|
|
273
320
|
* Get a cached model (cloned for use)
|
|
274
321
|
* @param {string} modelKey - The model key
|
|
322
|
+
* @param {boolean} useIndexedGeometry - Whether to use indexed geometry for OBJ models
|
|
275
323
|
* @returns {THREE.Object3D|null} Cloned model or null if not found
|
|
276
324
|
*/
|
|
277
325
|
)
|
|
278
326
|
}, {
|
|
279
327
|
key: "getCachedModel",
|
|
280
328
|
value: function getCachedModel(modelKey) {
|
|
329
|
+
var useIndexedGeometry = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
281
330
|
if (this.modelCache.has(modelKey)) {
|
|
282
331
|
console.log("\uD83C\uDFAF Returning cached model: ".concat(modelKey));
|
|
283
|
-
var
|
|
332
|
+
var cachedData = this.modelCache.get(modelKey);
|
|
333
|
+
|
|
334
|
+
// Handle OBJ models with processed geometry
|
|
335
|
+
if (cachedData && cachedData.isObjModel && useIndexedGeometry && cachedData.processedGeometry) {
|
|
336
|
+
console.log("\uD83D\uDD27 Using indexed BufferGeometry for OBJ: ".concat(modelKey));
|
|
284
337
|
|
|
285
|
-
|
|
286
|
-
|
|
338
|
+
// Create a mesh from the processed indexed geometry
|
|
339
|
+
var mesh = new THREE__namespace.Mesh(cachedData.processedGeometry.clone(), cachedData.materials.clone());
|
|
340
|
+
|
|
341
|
+
// Add metadata
|
|
342
|
+
mesh.userData.modelKey = modelKey;
|
|
343
|
+
mesh.userData.geometryStats = cachedData.geometryStats;
|
|
344
|
+
mesh.userData.isIndexedGeometry = true;
|
|
345
|
+
mesh.userData.originalSizeKB = cachedData.geometryStats.sizeKB;
|
|
346
|
+
return mesh;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Handle regular models or OBJ models without indexed geometry
|
|
350
|
+
var modelToClone = cachedData.isObjModel ? cachedData.originalObject : cachedData;
|
|
351
|
+
var clonedModel = modelToClone.clone();
|
|
352
|
+
|
|
353
|
+
// Add OBJ stats if available
|
|
354
|
+
if (cachedData.isObjModel && cachedData.geometryStats) {
|
|
355
|
+
clonedModel.userData.geometryStats = cachedData.geometryStats;
|
|
356
|
+
clonedModel.userData.isObjModel = true;
|
|
357
|
+
}
|
|
287
358
|
return clonedModel;
|
|
288
359
|
}
|
|
289
360
|
console.warn("\u26A0\uFE0F Model ".concat(modelKey, " not found in cache"));
|
|
@@ -302,7 +373,26 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
302
373
|
var libraryId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
303
374
|
if (this.modelCache.has(modelKey)) {
|
|
304
375
|
console.log("\uD83C\uDFAF Returning cached model with dimensions: ".concat(modelKey));
|
|
305
|
-
var
|
|
376
|
+
var cachedData = this.modelCache.get(modelKey);
|
|
377
|
+
|
|
378
|
+
// Handle OBJ models with processed geometry structure
|
|
379
|
+
var clonedModel;
|
|
380
|
+
if (cachedData && cachedData.isObjModel) {
|
|
381
|
+
// Clone the original OBJ object
|
|
382
|
+
clonedModel = cachedData.originalObject.clone();
|
|
383
|
+
|
|
384
|
+
// Add OBJ stats if available
|
|
385
|
+
if (cachedData.geometryStats) {
|
|
386
|
+
if (!clonedModel.userData) {
|
|
387
|
+
clonedModel.userData = {};
|
|
388
|
+
}
|
|
389
|
+
clonedModel.userData.geometryStats = cachedData.geometryStats;
|
|
390
|
+
clonedModel.userData.isObjModel = true;
|
|
391
|
+
}
|
|
392
|
+
} else {
|
|
393
|
+
// Handle regular GLB models
|
|
394
|
+
clonedModel = cachedData.clone();
|
|
395
|
+
}
|
|
306
396
|
|
|
307
397
|
// Add dimensions from component dictionary if available
|
|
308
398
|
if (libraryId && this.componentDictionary) {
|
|
@@ -391,41 +481,41 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
391
481
|
}, {
|
|
392
482
|
key: "reloadModel",
|
|
393
483
|
value: (function () {
|
|
394
|
-
var _reloadModel = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function
|
|
484
|
+
var _reloadModel = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee4(modelKey) {
|
|
395
485
|
var modelType,
|
|
396
486
|
_i,
|
|
397
487
|
_Object$keys,
|
|
398
488
|
componentType,
|
|
399
489
|
component,
|
|
400
|
-
|
|
401
|
-
return _rollupPluginBabelHelpers.regenerator().w(function (
|
|
402
|
-
while (1) switch (
|
|
490
|
+
_args4 = arguments;
|
|
491
|
+
return _rollupPluginBabelHelpers.regenerator().w(function (_context4) {
|
|
492
|
+
while (1) switch (_context4.n) {
|
|
403
493
|
case 0:
|
|
404
|
-
modelType =
|
|
494
|
+
modelType = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : null;
|
|
405
495
|
console.log("\uD83D\uDD04 Force reloading model: ".concat(modelKey));
|
|
406
496
|
|
|
407
497
|
// Try to determine model type from component dictionary if not provided
|
|
408
498
|
if (!(!modelType && this.componentDictionary)) {
|
|
409
|
-
|
|
499
|
+
_context4.n = 3;
|
|
410
500
|
break;
|
|
411
501
|
}
|
|
412
502
|
_i = 0, _Object$keys = Object.keys(this.componentDictionary);
|
|
413
503
|
case 1:
|
|
414
504
|
if (!(_i < _Object$keys.length)) {
|
|
415
|
-
|
|
505
|
+
_context4.n = 3;
|
|
416
506
|
break;
|
|
417
507
|
}
|
|
418
508
|
componentType = _Object$keys[_i];
|
|
419
509
|
component = this.componentDictionary[componentType];
|
|
420
510
|
if (!(component && component.modelKey === modelKey)) {
|
|
421
|
-
|
|
511
|
+
_context4.n = 2;
|
|
422
512
|
break;
|
|
423
513
|
}
|
|
424
514
|
modelType = component.modelType || 'glb';
|
|
425
|
-
return
|
|
515
|
+
return _context4.a(3, 3);
|
|
426
516
|
case 2:
|
|
427
517
|
_i++;
|
|
428
|
-
|
|
518
|
+
_context4.n = 1;
|
|
429
519
|
break;
|
|
430
520
|
case 3:
|
|
431
521
|
// Default to GLB if still not determined
|
|
@@ -436,11 +526,11 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
436
526
|
this.loadingPromises.delete(modelKey);
|
|
437
527
|
|
|
438
528
|
// Preload again
|
|
439
|
-
return
|
|
529
|
+
return _context4.a(2, this.preloadSingleModel(modelKey, modelType));
|
|
440
530
|
}
|
|
441
|
-
},
|
|
531
|
+
}, _callee4, this);
|
|
442
532
|
}));
|
|
443
|
-
function reloadModel(
|
|
533
|
+
function reloadModel(_x4) {
|
|
444
534
|
return _reloadModel.apply(this, arguments);
|
|
445
535
|
}
|
|
446
536
|
return reloadModel;
|
|
@@ -457,7 +547,42 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
457
547
|
// Dispose of all cached models
|
|
458
548
|
this.modelCache.forEach(function (model, modelKey) {
|
|
459
549
|
console.log("\uD83D\uDDD1\uFE0F Disposing cached model: ".concat(modelKey));
|
|
460
|
-
if (model && model.
|
|
550
|
+
if (model && model.isObjModel) {
|
|
551
|
+
// Handle OBJ model data structure
|
|
552
|
+
if (model.originalObject && model.originalObject.traverse) {
|
|
553
|
+
model.originalObject.traverse(function (child) {
|
|
554
|
+
if (child.geometry) {
|
|
555
|
+
child.geometry.dispose();
|
|
556
|
+
}
|
|
557
|
+
if (child.material) {
|
|
558
|
+
if (Array.isArray(child.material)) {
|
|
559
|
+
child.material.forEach(function (material) {
|
|
560
|
+
return material.dispose();
|
|
561
|
+
});
|
|
562
|
+
} else {
|
|
563
|
+
child.material.dispose();
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Dispose processed geometry
|
|
570
|
+
if (model.processedGeometry) {
|
|
571
|
+
model.processedGeometry.dispose();
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Dispose materials
|
|
575
|
+
if (model.materials) {
|
|
576
|
+
if (Array.isArray(model.materials)) {
|
|
577
|
+
model.materials.forEach(function (material) {
|
|
578
|
+
return material.dispose();
|
|
579
|
+
});
|
|
580
|
+
} else {
|
|
581
|
+
model.materials.dispose();
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
} else if (model && model.traverse) {
|
|
585
|
+
// Handle regular model
|
|
461
586
|
model.traverse(function (child) {
|
|
462
587
|
if (child.geometry) {
|
|
463
588
|
child.geometry.dispose();
|
|
@@ -478,6 +603,9 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
478
603
|
this.loadingPromises.clear();
|
|
479
604
|
this.isPreloading = false;
|
|
480
605
|
this.preloadingPromise = null;
|
|
606
|
+
|
|
607
|
+
// Clear OBJ processor caches
|
|
608
|
+
this.objProcessor.clearCaches();
|
|
481
609
|
console.log('✅ Model preloader cache cleared');
|
|
482
610
|
}
|
|
483
611
|
|
|
@@ -550,7 +678,24 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
550
678
|
console.log("\uD83D\uDD04 Loading model for library ID ".concat(libraryId, ": ").concat(modelKey, " (").concat(modelType.toUpperCase(), ")"));
|
|
551
679
|
this.preloadSingleModel(modelKey, modelType).then(function (model) {
|
|
552
680
|
if (model) {
|
|
553
|
-
|
|
681
|
+
// Handle OBJ models with processed geometry structure
|
|
682
|
+
var _clonedModel;
|
|
683
|
+
if (model && model.isObjModel) {
|
|
684
|
+
// Clone the original OBJ object
|
|
685
|
+
_clonedModel = model.originalObject.clone();
|
|
686
|
+
|
|
687
|
+
// Add OBJ stats if available
|
|
688
|
+
if (model.geometryStats) {
|
|
689
|
+
if (!_clonedModel.userData) {
|
|
690
|
+
_clonedModel.userData = {};
|
|
691
|
+
}
|
|
692
|
+
_clonedModel.userData.geometryStats = model.geometryStats;
|
|
693
|
+
_clonedModel.userData.isObjModel = true;
|
|
694
|
+
}
|
|
695
|
+
} else {
|
|
696
|
+
// Handle regular GLB models
|
|
697
|
+
_clonedModel = model.clone();
|
|
698
|
+
}
|
|
554
699
|
|
|
555
700
|
// Add dimensions if available
|
|
556
701
|
if (componentData.boundingBox) {
|
|
@@ -586,13 +731,15 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
586
731
|
totalModels: this.modelCache.size,
|
|
587
732
|
loadingModels: this.loadingPromises.size,
|
|
588
733
|
isPreloading: this.isPreloading,
|
|
589
|
-
memoryUsage: 0
|
|
734
|
+
memoryUsage: 0,
|
|
735
|
+
objProcessorStats: this.objProcessor.getStatus()
|
|
590
736
|
};
|
|
591
737
|
|
|
592
738
|
// Estimate memory usage (rough calculation)
|
|
593
739
|
this.modelCache.forEach(function (model) {
|
|
594
740
|
if (model && model.traverse) {
|
|
595
|
-
model.
|
|
741
|
+
var modelToAnalyze = model.isObjModel ? model.originalObject : model;
|
|
742
|
+
modelToAnalyze.traverse(function (child) {
|
|
596
743
|
if (child.geometry) {
|
|
597
744
|
var _child$geometry$attri;
|
|
598
745
|
stats.memoryUsage += (((_child$geometry$attri = child.geometry.attributes.position) === null || _child$geometry$attri === void 0 ? void 0 : _child$geometry$attri.count) || 0) * 12; // Rough estimate
|
|
@@ -602,6 +749,124 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
602
749
|
});
|
|
603
750
|
return stats;
|
|
604
751
|
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Get all OBJ geometry statistics
|
|
755
|
+
* @returns {Array} Array of OBJ geometry statistics
|
|
756
|
+
*/
|
|
757
|
+
}, {
|
|
758
|
+
key: "getObjGeometryStats",
|
|
759
|
+
value: function getObjGeometryStats() {
|
|
760
|
+
return this.objProcessor.getAllGeometryStats();
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/**
|
|
764
|
+
* Get OBJ processor memory usage
|
|
765
|
+
* @returns {Object} Memory usage statistics
|
|
766
|
+
*/
|
|
767
|
+
}, {
|
|
768
|
+
key: "getObjMemoryUsage",
|
|
769
|
+
value: function getObjMemoryUsage() {
|
|
770
|
+
return this.objProcessor.getMemoryUsage();
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* Create a custom mesh from indexed OBJ geometry
|
|
775
|
+
* @param {string} modelKey - The model key (must be an OBJ)
|
|
776
|
+
* @param {THREE.Material} material - Optional material to use
|
|
777
|
+
* @returns {THREE.Mesh|null} The created mesh or null if not found
|
|
778
|
+
*/
|
|
779
|
+
}, {
|
|
780
|
+
key: "createCustomObjMesh",
|
|
781
|
+
value: function createCustomObjMesh(modelKey) {
|
|
782
|
+
var material = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
783
|
+
return this.objProcessor.createCustomMesh(modelKey, material);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Get indexed geometry directly from processor
|
|
788
|
+
* @param {string} modelKey - The model key
|
|
789
|
+
* @returns {THREE.BufferGeometry|null} The indexed geometry or null
|
|
790
|
+
*/
|
|
791
|
+
}, {
|
|
792
|
+
key: "getIndexedGeometry",
|
|
793
|
+
value: function getIndexedGeometry(modelKey) {
|
|
794
|
+
var result = this.objProcessor.indexedGeometryCache.get(modelKey);
|
|
795
|
+
return result ? result.geometry.clone() : null;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Toggle wireframe visibility on an OBJ model
|
|
800
|
+
* @param {THREE.Object3D} model - The model to toggle wireframe on
|
|
801
|
+
* @param {boolean} visible - Whether wireframe should be visible
|
|
802
|
+
*/
|
|
803
|
+
}, {
|
|
804
|
+
key: "toggleWireframe",
|
|
805
|
+
value: function toggleWireframe(model) {
|
|
806
|
+
var visible = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
807
|
+
if (!model) return;
|
|
808
|
+
model.traverse(function (child) {
|
|
809
|
+
if (child.userData && child.userData.isWireframeOverlay) {
|
|
810
|
+
child.visible = visible;
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Update wireframe appearance on an OBJ model
|
|
817
|
+
* @param {THREE.Object3D} model - The model to update
|
|
818
|
+
* @param {Object} options - Wireframe options {color, opacity, visible}
|
|
819
|
+
*/
|
|
820
|
+
}, {
|
|
821
|
+
key: "updateWireframeAppearance",
|
|
822
|
+
value: function updateWireframeAppearance(model) {
|
|
823
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
824
|
+
if (!model) return;
|
|
825
|
+
var _options$color = options.color,
|
|
826
|
+
color = _options$color === void 0 ? 0x000000 : _options$color,
|
|
827
|
+
_options$opacity = options.opacity,
|
|
828
|
+
opacity = _options$opacity === void 0 ? 0.6 : _options$opacity,
|
|
829
|
+
_options$visible = options.visible,
|
|
830
|
+
visible = _options$visible === void 0 ? true : _options$visible;
|
|
831
|
+
model.traverse(function (child) {
|
|
832
|
+
if (child.userData && child.userData.isWireframeOverlay && child.material) {
|
|
833
|
+
child.material.color.setHex(color);
|
|
834
|
+
child.material.opacity = opacity;
|
|
835
|
+
child.visible = visible;
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Force reload and reprocess an OBJ model
|
|
842
|
+
* @param {string} modelKey - The model key to reload
|
|
843
|
+
* @returns {Promise} Promise that resolves with the reloaded model
|
|
844
|
+
*/
|
|
845
|
+
}, {
|
|
846
|
+
key: "reloadObjModel",
|
|
847
|
+
value: (function () {
|
|
848
|
+
var _reloadObjModel = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee5(modelKey) {
|
|
849
|
+
return _rollupPluginBabelHelpers.regenerator().w(function (_context5) {
|
|
850
|
+
while (1) switch (_context5.n) {
|
|
851
|
+
case 0:
|
|
852
|
+
console.log("\uD83D\uDD04 Force reloading OBJ model: ".concat(modelKey));
|
|
853
|
+
|
|
854
|
+
// Clear from both caches
|
|
855
|
+
this.modelCache.delete(modelKey);
|
|
856
|
+
this.loadingPromises.delete(modelKey);
|
|
857
|
+
this.objProcessor.indexedGeometryCache.delete(modelKey);
|
|
858
|
+
this.objProcessor.geometrySizeCache.delete(modelKey);
|
|
859
|
+
|
|
860
|
+
// Reload with OBJ processing
|
|
861
|
+
return _context5.a(2, this.preloadSingleModel(modelKey, 'obj'));
|
|
862
|
+
}
|
|
863
|
+
}, _callee5, this);
|
|
864
|
+
}));
|
|
865
|
+
function reloadObjModel(_x5) {
|
|
866
|
+
return _reloadObjModel.apply(this, arguments);
|
|
867
|
+
}
|
|
868
|
+
return reloadObjModel;
|
|
869
|
+
}())
|
|
605
870
|
}]);
|
|
606
871
|
}(); // Create singleton instance
|
|
607
872
|
var modelPreloader = new ModelPreloader();
|