@loaders.gl/tile-converter 4.1.0-alpha.1 → 4.1.0-alpha.11

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 (51) hide show
  1. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
  2. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +8 -0
  3. package/dist/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  4. package/dist/constants.d.ts +1 -0
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/constants.js +1 -0
  7. package/dist/constants.js.map +1 -1
  8. package/dist/converter-cli.js +41 -4
  9. package/dist/converter-cli.js.map +1 -1
  10. package/dist/converter.min.cjs +131 -220
  11. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  12. package/dist/deps-installer/deps-installer.js +4 -3
  13. package/dist/deps-installer/deps-installer.js.map +1 -1
  14. package/dist/i3s-converter/i3s-converter.d.ts +14 -0
  15. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  16. package/dist/i3s-converter/i3s-converter.js +73 -19
  17. package/dist/i3s-converter/i3s-converter.js.map +1 -1
  18. package/dist/i3s-converter/types.d.ts +7 -0
  19. package/dist/i3s-converter/types.d.ts.map +1 -1
  20. package/dist/i3s-converter/types.js +8 -0
  21. package/dist/i3s-converter/types.js.map +1 -1
  22. package/dist/i3s-server/bin/i3s-server.min.cjs +80 -80
  23. package/dist/index.cjs +365 -93
  24. package/dist/lib/utils/compress-util.d.ts +0 -37
  25. package/dist/lib/utils/compress-util.d.ts.map +1 -1
  26. package/dist/lib/utils/compress-util.js +1 -149
  27. package/dist/lib/utils/compress-util.js.map +1 -1
  28. package/dist/lib/utils/conversion-dump.d.ts +81 -0
  29. package/dist/lib/utils/conversion-dump.d.ts.map +1 -0
  30. package/dist/lib/utils/conversion-dump.js +131 -0
  31. package/dist/lib/utils/conversion-dump.js.map +1 -0
  32. package/dist/lib/utils/statistic-utills.d.ts +23 -6
  33. package/dist/lib/utils/write-queue.d.ts +6 -1
  34. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  35. package/dist/lib/utils/write-queue.js +15 -3
  36. package/dist/lib/utils/write-queue.js.map +1 -1
  37. package/dist/pgm-loader.js +1 -1
  38. package/dist/pgm-loader.js.map +1 -1
  39. package/dist/slpk-extractor.min.cjs +46 -46
  40. package/package.json +16 -16
  41. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +19 -0
  42. package/src/constants.ts +1 -0
  43. package/src/converter-cli.ts +58 -4
  44. package/src/deps-installer/deps-installer.ts +3 -2
  45. package/src/i3s-converter/i3s-converter.ts +191 -51
  46. package/src/i3s-converter/types.ts +8 -0
  47. package/src/lib/utils/compress-util.ts +1 -264
  48. package/src/lib/utils/conversion-dump.ts +203 -0
  49. package/src/lib/utils/write-queue.ts +15 -2
  50. package/dist/lib/utils/statistic-utills.d.js +0 -2
  51. package/dist/lib/utils/statistic-utills.d.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -257,7 +257,7 @@ var import_json_map_transform8 = __toESM(require("json-map-transform"), 1);
257
257
  var import_md52 = __toESM(require("md5"), 1);
258
258
 
259
259
  // src/i3s-converter/helpers/node-pages.ts
260
- var import_path3 = require("path");
260
+ var import_path2 = require("path");
261
261
  var import_json_map_transform = __toESM(require("json-map-transform"), 1);
262
262
 
263
263
  // src/i3s-converter/json-templates/metadata.ts
@@ -287,17 +287,11 @@ var METADATA = () => ({
287
287
  var import_core = require("@loaders.gl/core");
288
288
  var import_loader_utils = require("@loaders.gl/loader-utils");
289
289
  var import_fs2 = require("fs");
290
- var import_path2 = require("path");
290
+ var import_path = require("path");
291
291
 
292
292
  // src/lib/utils/compress-util.ts
293
293
  var import_zlib = require("zlib");
294
- var import_path = require("path");
295
294
  var import_fs = require("fs");
296
- var import_archiver = __toESM(require("archiver"), 1);
297
- var import_worker_utils = require("@loaders.gl/worker-utils");
298
- var import_jszip = __toESM(require("jszip"), 1);
299
- var import_crypto = require("@loaders.gl/crypto");
300
- var import_crypt = __toESM(require("crypt"), 1);
301
295
  function compressFileWithGzip(pathFile) {
302
296
  const compressedPathFile = `${pathFile}.gz`;
303
297
  const gzip = (0, import_zlib.createGzip)();
@@ -315,42 +309,6 @@ function compressFileWithGzip(pathFile) {
315
309
  input.pipe(gzip).pipe(output);
316
310
  });
317
311
  }
318
- async function compressWithChildProcess(inputFolder, outputFile, level, inputFiles, sevenZipExe) {
319
- if (process.platform === "win32") {
320
- await compressWithChildProcessWindows(inputFolder, outputFile, level, inputFiles, sevenZipExe);
321
- } else {
322
- await compressWithChildProcessUnix(inputFolder, outputFile, level, inputFiles);
323
- }
324
- }
325
- async function compressWithChildProcessUnix(inputFolder, outputFile, level = 0, inputFiles = ".") {
326
- const fullOutputFile = getAbsoluteFilePath(outputFile);
327
- const args = [`-${level}`, "-r", fullOutputFile, inputFiles];
328
- const childProcess = new import_worker_utils.ChildProcessProxy();
329
- await childProcess.start({
330
- command: "zip",
331
- arguments: args,
332
- spawn: {
333
- cwd: inputFolder
334
- },
335
- wait: 0
336
- });
337
- }
338
- async function compressWithChildProcessWindows(inputFolder, outputFile, level = 0, inputFiles = (0, import_path.join)(".", "*"), sevenZipExe) {
339
- if (inputFiles[0] === "@") {
340
- inputFiles = `*${inputFiles.substr(1)}`;
341
- }
342
- const fullOutputFile = getAbsoluteFilePath(outputFile);
343
- const args = ["a", "-tzip", `-mx=${level}`, fullOutputFile, inputFiles];
344
- const childProcess = new import_worker_utils.ChildProcessProxy();
345
- await childProcess.start({
346
- command: sevenZipExe,
347
- arguments: args,
348
- spawn: {
349
- cwd: `${inputFolder}`
350
- },
351
- wait: 0
352
- });
353
- }
354
312
 
355
313
  // src/lib/utils/file-utils.ts
356
314
  async function writeFile(path, data, fileName = "index.json") {
@@ -363,7 +321,7 @@ async function writeFile(path, data, fileName = "index.json") {
363
321
  toWriteData = data;
364
322
  }
365
323
  await import_fs2.promises.mkdir(path, { recursive: true });
366
- const pathFile = (0, import_path2.join)(path, fileName);
324
+ const pathFile = (0, import_path.join)(path, fileName);
367
325
  try {
368
326
  await import_fs2.promises.writeFile(pathFile, toWriteData);
369
327
  } catch (err) {
@@ -395,7 +353,7 @@ async function openJson(path, fileName) {
395
353
  let count = 0;
396
354
  console.log(`load ${path}/${fileName}.`);
397
355
  const intervalId = setInterval(() => {
398
- const pathFile = (0, import_path2.join)(path, fileName);
356
+ const pathFile = (0, import_path.join)(path, fileName);
399
357
  (0, import_core.load)(pathFile, import_loader_utils.JSONLoader).then((result) => {
400
358
  clearInterval(intervalId);
401
359
  resolve(result);
@@ -424,7 +382,7 @@ function removeFile(path) {
424
382
  return import_fs2.promises.unlink(path);
425
383
  }
426
384
  function getAbsoluteFilePath(filePath) {
427
- return (0, import_path2.isAbsolute)(filePath) ? filePath : (0, import_path2.join)(process.cwd(), filePath);
385
+ return (0, import_path.isAbsolute)(filePath) ? filePath : (0, import_path.join)(process.cwd(), filePath);
428
386
  }
429
387
 
430
388
  // src/i3s-converter/helpers/node-pages.ts
@@ -461,10 +419,10 @@ var NodePages = class {
461
419
  let filePath;
462
420
  let fileName;
463
421
  if (this.converter.options.slpk) {
464
- filePath = (0, import_path3.join)(this.converter.layers0Path, "nodepages");
422
+ filePath = (0, import_path2.join)(this.converter.layers0Path, "nodepages");
465
423
  fileName = `${nodePageId.toString()}.json`;
466
424
  } else {
467
- filePath = (0, import_path3.join)(this.converter.layers0Path, "nodepages", nodePageId.toString());
425
+ filePath = (0, import_path2.join)(this.converter.layers0Path, "nodepages", nodePageId.toString());
468
426
  fileName = "index.json";
469
427
  }
470
428
  return { filePath, fileName };
@@ -476,7 +434,7 @@ var NodePages = class {
476
434
  */
477
435
  async loadNodePage(nodePageId) {
478
436
  const { filePath, fileName } = this.getNodePageFileName(nodePageId);
479
- const fullName = (0, import_path3.join)(filePath, fileName);
437
+ const fullName = (0, import_path2.join)(filePath, fileName);
480
438
  if (await isFileExists(fullName)) {
481
439
  console.log(`load ${fullName}.`);
482
440
  return await openJson(filePath, fileName);
@@ -613,7 +571,7 @@ var NodePages = class {
613
571
  if (this.converter.options.slpk) {
614
572
  for (const [index, nodePage] of this.nodePages.entries()) {
615
573
  const nodePageStr = JSON.stringify(nodePage);
616
- const slpkPath = (0, import_path3.join)(this.converter.layers0Path, "nodepages");
574
+ const slpkPath = (0, import_path2.join)(this.converter.layers0Path, "nodepages");
617
575
  await this.converter.writeQueue.enqueue({
618
576
  archiveKey: `nodePages/${index.toString()}.json.gz`,
619
577
  writePromise: () => this.writeFile(slpkPath, nodePageStr, `${index.toString()}.json`)
@@ -623,7 +581,7 @@ var NodePages = class {
623
581
  } else {
624
582
  for (const [index, nodePage] of this.nodePages.entries()) {
625
583
  const nodePageStr = JSON.stringify(nodePage);
626
- const nodePagePath = (0, import_path3.join)(this.converter.layers0Path, "nodepages", index.toString());
584
+ const nodePagePath = (0, import_path2.join)(this.converter.layers0Path, "nodepages", index.toString());
627
585
  await this.converter.writeQueue.enqueue({
628
586
  writePromise: () => this.writeFile(nodePagePath, nodePageStr)
629
587
  });
@@ -709,7 +667,7 @@ var NodePages = class {
709
667
  };
710
668
 
711
669
  // src/lib/utils/statistic-utills.ts
712
- var import_path4 = require("path");
670
+ var import_path3 = require("path");
713
671
  var import_fs3 = require("fs");
714
672
  function timeConverter(time) {
715
673
  if (typeof time === "number") {
@@ -750,11 +708,11 @@ async function calculateFilesSize(params) {
750
708
  const fullOutputPath = getAbsoluteFilePath(outputPath);
751
709
  try {
752
710
  if (slpk) {
753
- const slpkPath = (0, import_path4.join)(fullOutputPath, `${tilesetName}.slpk`);
711
+ const slpkPath = (0, import_path3.join)(fullOutputPath, `${tilesetName}.slpk`);
754
712
  const stat = await import_fs3.promises.stat(slpkPath);
755
713
  return stat.size;
756
714
  }
757
- const directoryPath = (0, import_path4.join)(fullOutputPath, tilesetName);
715
+ const directoryPath = (0, import_path3.join)(fullOutputPath, tilesetName);
758
716
  const totalSize = await getTotalFilesSize(directoryPath);
759
717
  return totalSize;
760
718
  } catch (error) {
@@ -766,9 +724,9 @@ async function getTotalFilesSize(dirPath) {
766
724
  let totalFileSize = 0;
767
725
  const files = await import_fs3.promises.readdir(dirPath);
768
726
  for (const file of files) {
769
- const fileStat = await import_fs3.promises.stat((0, import_path4.join)(dirPath, file));
727
+ const fileStat = await import_fs3.promises.stat((0, import_path3.join)(dirPath, file));
770
728
  if (fileStat.isDirectory()) {
771
- totalFileSize += await getTotalFilesSize((0, import_path4.join)(dirPath, file));
729
+ totalFileSize += await getTotalFilesSize((0, import_path3.join)(dirPath, file));
772
730
  } else {
773
731
  totalFileSize += fileStat.size;
774
732
  }
@@ -2436,7 +2394,7 @@ function getPropertyTableExtension(tileContent) {
2436
2394
  // src/i3s-converter/helpers/create-scene-server-path.ts
2437
2395
  var import_uuid2 = require("uuid");
2438
2396
  var import_json_map_transform2 = __toESM(require("json-map-transform"), 1);
2439
- var import_path5 = require("path");
2397
+ var import_path4 = require("path");
2440
2398
 
2441
2399
  // src/i3s-converter/json-templates/scene-server.ts
2442
2400
  var SCENE_SERVER = () => ({
@@ -2475,7 +2433,7 @@ async function createSceneServerPath(layerName, layers0, rootPath) {
2475
2433
  layers0
2476
2434
  };
2477
2435
  const sceneServer = (0, import_json_map_transform2.default)(sceneServerData, SCENE_SERVER());
2478
- const nodePagePath = (0, import_path5.join)(rootPath, "SceneServer");
2436
+ const nodePagePath = (0, import_path4.join)(rootPath, "SceneServer");
2479
2437
  await writeFile(nodePagePath, JSON.stringify(sceneServer));
2480
2438
  }
2481
2439
 
@@ -3135,7 +3093,7 @@ function isAllVerticesInsideBoundingVolume(boundingVolume, positions) {
3135
3093
  // src/i3s-converter/i3s-converter.ts
3136
3094
  var import_textures = require("@loaders.gl/textures");
3137
3095
  var import_images = require("@loaders.gl/images");
3138
- var import_worker_utils2 = require("@loaders.gl/worker-utils");
3096
+ var import_worker_utils = require("@loaders.gl/worker-utils");
3139
3097
 
3140
3098
  // src/lib/utils/queue.ts
3141
3099
  var Queue = class extends Array {
@@ -3157,10 +3115,11 @@ var Queue = class extends Array {
3157
3115
  var import_process = __toESM(require("process"), 1);
3158
3116
  var MEMORY_LIMIT = 4 * 1024 * 1024 * 1024;
3159
3117
  var WriteQueue = class extends Queue {
3160
- constructor(listeningInterval = 2e3, writeConcurrency = 400) {
3118
+ constructor(conversionDump, listeningInterval = 2e3, writeConcurrency = 400) {
3161
3119
  super();
3162
3120
  this.writePromise = null;
3163
3121
  this.fileMap = {};
3122
+ this.conversionDump = conversionDump;
3164
3123
  this.listeningInterval = listeningInterval;
3165
3124
  this.writeConcurrency = writeConcurrency;
3166
3125
  }
@@ -3201,18 +3160,21 @@ var WriteQueue = class extends Queue {
3201
3160
  while (this.length) {
3202
3161
  const promises = [];
3203
3162
  const archiveKeys = [];
3163
+ const changedRecords = [];
3204
3164
  for (let i = 0; i < this.writeConcurrency; i++) {
3205
3165
  const item = this.dequeue();
3206
3166
  if (!item) {
3207
3167
  break;
3208
3168
  }
3209
- const { archiveKey, writePromise } = item;
3169
+ const { archiveKey, sourceId, outputId, resourceType, writePromise } = item;
3210
3170
  archiveKeys.push(archiveKey);
3171
+ changedRecords.push({ sourceId, outputId, resourceType });
3211
3172
  const promise = writePromise();
3212
3173
  promises.push(promise);
3213
3174
  }
3214
3175
  const writeResults = await Promise.allSettled(promises);
3215
3176
  this.updateFileMap(archiveKeys, writeResults);
3177
+ await this.conversionDump.updateConvertedTilesDump(changedRecords, writeResults);
3216
3178
  }
3217
3179
  }
3218
3180
  updateFileMap(archiveKeys, writeResults) {
@@ -3227,9 +3189,10 @@ var WriteQueue = class extends Queue {
3227
3189
 
3228
3190
  // src/constants.ts
3229
3191
  var BROWSER_ERROR_MESSAGE = "Tile converter does not work in browser, only in node js environment";
3192
+ var DUMP_FILE_SUFFIX = ".dump.json";
3230
3193
 
3231
3194
  // src/i3s-converter/helpers/node-index-document.ts
3232
- var import_path6 = require("path");
3195
+ var import_path5 = require("path");
3233
3196
  var import_json_map_transform7 = __toESM(require("json-map-transform"), 1);
3234
3197
  var import_uuid3 = require("uuid");
3235
3198
 
@@ -3432,7 +3395,7 @@ var NodeIndexDocument = class {
3432
3395
  * @param node - Node3DIndexDocument object
3433
3396
  */
3434
3397
  async write(node) {
3435
- const path = (0, import_path6.join)(this.converter.layers0Path, "nodes", this.id);
3398
+ const path = (0, import_path5.join)(this.converter.layers0Path, "nodes", this.id);
3436
3399
  if (this.converter.options.slpk) {
3437
3400
  await this.converter.writeQueue.enqueue(
3438
3401
  {
@@ -3463,7 +3426,7 @@ var NodeIndexDocument = class {
3463
3426
  return this.data;
3464
3427
  }
3465
3428
  const path = this.id;
3466
- const parentNodePath = (0, import_path6.join)(this.converter.layers0Path, "nodes", path);
3429
+ const parentNodePath = (0, import_path5.join)(this.converter.layers0Path, "nodes", path);
3467
3430
  let parentNodeFileName = "index.json";
3468
3431
  if (this.converter.options.slpk) {
3469
3432
  parentNodeFileName = "3dNodeIndexDocument.json";
@@ -3902,6 +3865,172 @@ var Progress = class {
3902
3865
  }
3903
3866
  };
3904
3867
 
3868
+ // src/i3s-converter/i3s-converter.ts
3869
+ var import_zip = require("@loaders.gl/zip");
3870
+
3871
+ // src/lib/utils/conversion-dump.ts
3872
+ var import_path6 = require("path");
3873
+ var ConversionDump = class {
3874
+ constructor() {
3875
+ this.tilesConverted = {};
3876
+ }
3877
+ /**
3878
+ * Create a dump file with convertion options
3879
+ * @param options - converter options
3880
+ */
3881
+ async createDumpFile(options) {
3882
+ const {
3883
+ tilesetName,
3884
+ slpk,
3885
+ egmFilePath,
3886
+ inputUrl,
3887
+ outputPath,
3888
+ draco = true,
3889
+ maxDepth,
3890
+ token,
3891
+ generateTextures,
3892
+ generateBoundingVolumes,
3893
+ mergeMaterials: mergeMaterials2 = true,
3894
+ metadataClass,
3895
+ analyze = false
3896
+ } = options;
3897
+ this.options = {
3898
+ tilesetName,
3899
+ slpk,
3900
+ egmFilePath,
3901
+ inputUrl,
3902
+ outputPath,
3903
+ draco,
3904
+ maxDepth,
3905
+ token,
3906
+ generateTextures,
3907
+ generateBoundingVolumes,
3908
+ mergeMaterials: mergeMaterials2,
3909
+ metadataClass,
3910
+ analyze
3911
+ };
3912
+ try {
3913
+ await writeFile(
3914
+ options.outputPath,
3915
+ JSON.stringify({ options: this.options }),
3916
+ `${options.tilesetName}${DUMP_FILE_SUFFIX}`
3917
+ );
3918
+ } catch (error) {
3919
+ console.log("Can't create dump file", error);
3920
+ }
3921
+ }
3922
+ /**
3923
+ * Update conversion status in the dump file
3924
+ */
3925
+ async updateDumpFile() {
3926
+ var _a2;
3927
+ if (((_a2 = this.options) == null ? void 0 : _a2.outputPath) && this.options.tilesetName) {
3928
+ try {
3929
+ await writeFile(
3930
+ this.options.outputPath,
3931
+ JSON.stringify({
3932
+ options: this.options,
3933
+ tilesConverted: this.tilesConverted
3934
+ }),
3935
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
3936
+ );
3937
+ } catch (error) {
3938
+ console.log("Can't update dump file", error);
3939
+ }
3940
+ }
3941
+ }
3942
+ /**
3943
+ * Delete a dump file
3944
+ */
3945
+ async deleteDumpFile() {
3946
+ var _a2;
3947
+ if (((_a2 = this.options) == null ? void 0 : _a2.outputPath) && this.options.tilesetName) {
3948
+ await removeFile(
3949
+ (0, import_path6.join)(this.options.outputPath, `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`)
3950
+ );
3951
+ }
3952
+ }
3953
+ /**
3954
+ * Get record from the tilesConverted Map
3955
+ * @param fileName - source filename
3956
+ * @returns existing object from the tilesConverted Map
3957
+ */
3958
+ getRecord(fileName) {
3959
+ return this.tilesConverted[fileName];
3960
+ }
3961
+ /**
3962
+ * Set a record for the dump file
3963
+ * @param fileName - key - source filename
3964
+ * @param object - value
3965
+ */
3966
+ setRecord(fileName, object) {
3967
+ this.tilesConverted[fileName] = object;
3968
+ }
3969
+ /**
3970
+ * Add a node into the dump file for the source file record
3971
+ * @param fileName - source filename
3972
+ * @param nodeId - nodeId of the node
3973
+ */
3974
+ async addNode(filename, nodeId) {
3975
+ const { nodes } = this.getRecord(filename) || { nodes: [] };
3976
+ nodes.push({ nodeId, done: false, progress: {} });
3977
+ if (nodes.length === 1) {
3978
+ this.setRecord(filename, { nodes });
3979
+ }
3980
+ await this.updateDumpFile();
3981
+ }
3982
+ /**
3983
+ * Update done status object for the writing resources
3984
+ * @param fileName - key - source filename
3985
+ * @param nodeId - nodeId for the source filename
3986
+ * @param resourceType - resource type to update status
3987
+ * @param value - value
3988
+ */
3989
+ updateDoneStatus(filename, nodeId, resourceType, value) {
3990
+ var _a2;
3991
+ const nodeDump = (_a2 = this.tilesConverted[filename]) == null ? void 0 : _a2.nodes.find(
3992
+ (element) => element.nodeId === nodeId
3993
+ );
3994
+ if (nodeDump) {
3995
+ nodeDump.progress[resourceType] = value;
3996
+ if (!value) {
3997
+ nodeDump.done = false;
3998
+ }
3999
+ }
4000
+ }
4001
+ /**
4002
+ * Update dump file according to writing results
4003
+ * @param changedRecords - array of parameters ids for the written resources
4004
+ * @param writeResults - array of writing resource files results
4005
+ */
4006
+ async updateConvertedTilesDump(changedRecords, writeResults) {
4007
+ for (let i = 0; i < changedRecords.length; i++) {
4008
+ if (changedRecords[i] && "value" in writeResults[i]) {
4009
+ const { sourceId, resourceType, outputId } = changedRecords[i];
4010
+ if (!sourceId || !resourceType || !outputId)
4011
+ continue;
4012
+ for (const node of this.tilesConverted[sourceId].nodes) {
4013
+ if (node.nodeId === outputId) {
4014
+ node.progress[resourceType] = true;
4015
+ let done = false;
4016
+ for (const key in node.progress) {
4017
+ done = node.progress[key];
4018
+ if (!done)
4019
+ break;
4020
+ }
4021
+ node.done = done;
4022
+ if (node.done) {
4023
+ node.progress = {};
4024
+ }
4025
+ break;
4026
+ }
4027
+ }
4028
+ }
4029
+ }
4030
+ await this.updateDumpFile();
4031
+ }
4032
+ };
4033
+
3905
4034
  // src/i3s-converter/i3s-converter.ts
3906
4035
  var _a;
3907
4036
  var ION_DEFAULT_TOKEN = (_a = import_process3.default.env) == null ? void 0 : _a.IonToken;
@@ -3934,7 +4063,7 @@ var I3SConverter = class {
3934
4063
  this.geoidHeightModel = null;
3935
4064
  this.Loader = import_d_tiles2.Tiles3DLoader;
3936
4065
  this.workerSource = {};
3937
- this.writeQueue = new WriteQueue();
4066
+ this.writeQueue = new WriteQueue(new ConversionDump());
3938
4067
  this.compressList = null;
3939
4068
  this.preprocessData = {
3940
4069
  meshTopologyTypes: /* @__PURE__ */ new Set(),
@@ -3961,6 +4090,7 @@ var I3SConverter = class {
3961
4090
  this.generateBoundingVolumes = false;
3962
4091
  this.layersHasTexture = false;
3963
4092
  this.compressList = null;
4093
+ this.conversionDump = new ConversionDump();
3964
4094
  }
3965
4095
  /**
3966
4096
  * Convert a 3d tileset
@@ -4005,6 +4135,8 @@ var I3SConverter = class {
4005
4135
  analyze = false
4006
4136
  } = options;
4007
4137
  this.options = {
4138
+ outputPath,
4139
+ tilesetName,
4008
4140
  maxDepth,
4009
4141
  slpk,
4010
4142
  sevenZipExe,
@@ -4023,7 +4155,7 @@ var I3SConverter = class {
4023
4155
  this.Loader = inputUrl.indexOf(CESIUM_DATASET_PREFIX) !== -1 ? import_d_tiles2.CesiumIonLoader : import_d_tiles2.Tiles3DLoader;
4024
4156
  this.generateTextures = Boolean(generateTextures);
4025
4157
  this.generateBoundingVolumes = Boolean(generateBoundingVolumes);
4026
- this.writeQueue = new WriteQueue();
4158
+ this.writeQueue = new WriteQueue(this.conversionDump);
4027
4159
  this.writeQueue.startListening();
4028
4160
  console.log("Loading egm file...");
4029
4161
  this.geoidHeightModel = await (0, import_core9.load)(egmFilePath, PGMLoader);
@@ -4031,6 +4163,7 @@ var I3SConverter = class {
4031
4163
  if (slpk) {
4032
4164
  this.nodePages.useWriteFunction(writeFileForSlpk);
4033
4165
  }
4166
+ await this.conversionDump.createDumpFile(options);
4034
4167
  try {
4035
4168
  const preloadOptions = await this._fetchPreloadOptions();
4036
4169
  let tilesetUrl = inputUrl;
@@ -4053,7 +4186,7 @@ var I3SConverter = class {
4053
4186
  throw error;
4054
4187
  } finally {
4055
4188
  await this.writeQueue.finalize();
4056
- const workerFarm = import_worker_utils2.WorkerFarm.getWorkerFarm({});
4189
+ const workerFarm = import_worker_utils.WorkerFarm.getWorkerFarm({});
4057
4190
  workerFarm.destroy();
4058
4191
  }
4059
4192
  return "success";
@@ -4286,16 +4419,14 @@ var I3SConverter = class {
4286
4419
  * @param tilesetPath - Path to save file
4287
4420
  */
4288
4421
  async _createSlpk(tilesetPath) {
4422
+ await this.conversionDump.deleteDumpFile();
4289
4423
  if (this.options.slpk) {
4290
4424
  const slpkTilesetPath = (0, import_path7.join)(tilesetPath, "SceneServer", "layers", "0");
4291
4425
  const slpkFileName = `${tilesetPath}.slpk`;
4292
- await compressWithChildProcess(
4293
- slpkTilesetPath,
4294
- slpkFileName,
4295
- 0,
4296
- ".",
4297
- this.options.sevenZipExe
4298
- );
4426
+ await (0, import_zip.createZip)(slpkTilesetPath, slpkFileName, async (fileList) => ({
4427
+ path: "@specialIndexFileHASH128@",
4428
+ file: await (0, import_zip.composeHashFile)(fileList)
4429
+ }));
4299
4430
  try {
4300
4431
  await removeDir(tilesetPath);
4301
4432
  } catch (e) {
@@ -4436,7 +4567,10 @@ var I3SConverter = class {
4436
4567
  const node = await new NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
4437
4568
  nodes.push(node);
4438
4569
  if (nodeInPage.mesh) {
4439
- await this._writeResources(resources, node.id);
4570
+ if (sourceTile.id) {
4571
+ await this.conversionDump.addNode(sourceTile.id, nodeInPage.index);
4572
+ }
4573
+ await this._writeResources(resources, node.id, sourceTile);
4440
4574
  }
4441
4575
  if (this.validate) {
4442
4576
  this.boundingVolumeWarnings = validateNodeBoundingVolumes(nodeData);
@@ -4560,9 +4694,11 @@ var I3SConverter = class {
4560
4694
  * @param resources.texture - texture image
4561
4695
  * @param resources.sharedResources - shared resource data object
4562
4696
  * @param resources.attributes - feature attributes
4697
+ * @param nodePath - node path
4698
+ * @param sourceTile - source tile (3DTile)
4563
4699
  * @return {Promise<void>}
4564
4700
  */
4565
- async _writeResources(resources, nodePath) {
4701
+ async _writeResources(resources, nodePath, sourceTile) {
4566
4702
  const {
4567
4703
  geometry: geometryBuffer,
4568
4704
  compressedGeometry,
@@ -4572,10 +4708,36 @@ var I3SConverter = class {
4572
4708
  } = resources;
4573
4709
  const childPath = (0, import_path7.join)(this.layers0Path, "nodes", nodePath);
4574
4710
  const slpkChildPath = (0, import_path7.join)("nodes", nodePath);
4575
- await this._writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath);
4576
- await this._writeShared(sharedResources, childPath, slpkChildPath, nodePath);
4577
- await this._writeTexture(texture, childPath, slpkChildPath);
4578
- await this._writeAttributes(attributes, childPath, slpkChildPath);
4711
+ await this._writeGeometries(
4712
+ geometryBuffer,
4713
+ compressedGeometry,
4714
+ childPath,
4715
+ slpkChildPath,
4716
+ sourceTile.id || "",
4717
+ parseInt(nodePath)
4718
+ );
4719
+ await this._writeShared(
4720
+ sharedResources,
4721
+ childPath,
4722
+ slpkChildPath,
4723
+ nodePath,
4724
+ sourceTile.id || "",
4725
+ parseInt(nodePath)
4726
+ );
4727
+ await this._writeTexture(
4728
+ texture,
4729
+ childPath,
4730
+ slpkChildPath,
4731
+ sourceTile.id || "",
4732
+ parseInt(nodePath)
4733
+ );
4734
+ await this._writeAttributes(
4735
+ attributes,
4736
+ childPath,
4737
+ slpkChildPath,
4738
+ sourceTile.id || "",
4739
+ parseInt(nodePath)
4740
+ );
4579
4741
  }
4580
4742
  /**
4581
4743
  * Write non-compressed and compressed geometries in files
@@ -4583,30 +4745,46 @@ var I3SConverter = class {
4583
4745
  * @param compressedGeometry - Uint8Array with compressed (draco) geometry
4584
4746
  * @param childPath - a child path to write resources
4585
4747
  * @param slpkChildPath - resource path inside *slpk file
4748
+ * @param sourceId - source filename
4749
+ * @param nodeId - nodeId of a converted node for the writing
4586
4750
  */
4587
- async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath) {
4751
+ async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath, sourceId, nodeId) {
4752
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, "GEOMETRY" /* GEOMETRY */, false);
4588
4753
  if (this.options.slpk) {
4589
4754
  const slpkGeometryPath = (0, import_path7.join)(childPath, "geometries");
4590
4755
  await this.writeQueue.enqueue({
4591
4756
  archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
4757
+ sourceId,
4758
+ outputId: nodeId,
4759
+ resourceType: "GEOMETRY" /* GEOMETRY */,
4592
4760
  writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, "0.bin")
4593
4761
  });
4594
4762
  } else {
4595
4763
  const geometryPath = (0, import_path7.join)(childPath, "geometries/0/");
4596
4764
  await this.writeQueue.enqueue({
4765
+ sourceId,
4766
+ outputId: nodeId,
4767
+ resourceType: "GEOMETRY" /* GEOMETRY */,
4597
4768
  writePromise: () => writeFile(geometryPath, geometryBuffer, "index.bin")
4598
4769
  });
4599
4770
  }
4600
4771
  if (this.options.draco) {
4772
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, "DRACO_GEOMETRY" /* DRACO_GEOMETRY */, false);
4601
4773
  if (this.options.slpk) {
4602
4774
  const slpkCompressedGeometryPath = (0, import_path7.join)(childPath, "geometries");
4603
4775
  await this.writeQueue.enqueue({
4604
4776
  archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
4777
+ sourceId,
4778
+ outputId: nodeId,
4779
+ resourceType: "DRACO_GEOMETRY" /* DRACO_GEOMETRY */,
4605
4780
  writePromise: () => writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, "1.bin")
4606
4781
  });
4607
4782
  } else {
4608
4783
  const compressedGeometryPath = (0, import_path7.join)(childPath, "geometries/1/");
4609
4784
  await this.writeQueue.enqueue({
4785
+ sourceId,
4786
+ outputId: nodeId,
4787
+ resourceType: "DRACO_GEOMETRY" /* DRACO_GEOMETRY */,
4610
4788
  writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, "index.bin")
4611
4789
  });
4612
4790
  }
@@ -4618,23 +4796,34 @@ var I3SConverter = class {
4618
4796
  * @param childPath - a child path to write resources
4619
4797
  * @param slpkChildPath - resource path inside *slpk file
4620
4798
  * @param nodePath - a node path
4799
+ * @param sourceId - source filename
4800
+ * @param nodeId - nodeId of a converted node for the writing
4621
4801
  */
4622
- async _writeShared(sharedResources, childPath, slpkChildPath, nodePath) {
4802
+ async _writeShared(sharedResources, childPath, slpkChildPath, nodePath, sourceId, nodeId) {
4623
4803
  if (!sharedResources) {
4624
4804
  return;
4625
4805
  }
4626
4806
  sharedResources.nodePath = nodePath;
4627
4807
  const sharedData = (0, import_json_map_transform8.default)(sharedResources, SHARED_RESOURCES());
4628
4808
  const sharedDataStr = JSON.stringify(sharedData);
4809
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, "SHARED" /* SHARED */, false);
4629
4810
  if (this.options.slpk) {
4630
4811
  const slpkSharedPath = (0, import_path7.join)(childPath, "shared");
4631
4812
  await this.writeQueue.enqueue({
4632
4813
  archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
4814
+ sourceId,
4815
+ outputId: nodeId,
4816
+ resourceType: "SHARED" /* SHARED */,
4633
4817
  writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, "sharedResource.json")
4634
4818
  });
4635
4819
  } else {
4636
4820
  const sharedPath = (0, import_path7.join)(childPath, "shared/");
4637
- await this.writeQueue.enqueue({ writePromise: () => writeFile(sharedPath, sharedDataStr) });
4821
+ await this.writeQueue.enqueue({
4822
+ sourceId,
4823
+ outputId: nodeId,
4824
+ resourceType: "SHARED" /* SHARED */,
4825
+ writePromise: () => writeFile(sharedPath, sharedDataStr)
4826
+ });
4638
4827
  }
4639
4828
  }
4640
4829
  /**
@@ -4642,8 +4831,10 @@ var I3SConverter = class {
4642
4831
  * @param texture - the texture image
4643
4832
  * @param childPath - a child path to write resources
4644
4833
  * @param slpkChildPath - the resource path inside *slpk file
4834
+ * @param sourceId - source filename
4835
+ * @param nodeId - nodeId of a converted node for the writing
4645
4836
  */
4646
- async _writeTexture(texture, childPath, slpkChildPath) {
4837
+ async _writeTexture(texture, childPath, slpkChildPath, sourceId, nodeId) {
4647
4838
  if (texture) {
4648
4839
  const format = this._getFormatByMimeType(texture == null ? void 0 : texture.mimeType);
4649
4840
  const formats = [];
@@ -4652,13 +4843,28 @@ var I3SConverter = class {
4652
4843
  case "jpg":
4653
4844
  case "png": {
4654
4845
  formats.push({ name: "0", format });
4655
- await this.writeTextureFile(textureData, "0", format, childPath, slpkChildPath);
4846
+ this.conversionDump.updateDoneStatus(
4847
+ sourceId,
4848
+ nodeId,
4849
+ `${"TEXTURE" /* TEXTURE */}/${format}`,
4850
+ false
4851
+ );
4852
+ await this.writeTextureFile(
4853
+ textureData,
4854
+ "0",
4855
+ format,
4856
+ childPath,
4857
+ slpkChildPath,
4858
+ sourceId,
4859
+ nodeId
4860
+ );
4656
4861
  if (this.generateTextures) {
4657
4862
  formats.push({ name: "1", format: "ktx2" });
4658
4863
  const copyArrayBuffer = texture.image.data.subarray();
4659
4864
  const arrayToEncode = new Uint8Array(copyArrayBuffer);
4660
4865
  const ktx2TextureData = (0, import_core9.encode)(
4661
4866
  { ...texture.image, data: arrayToEncode },
4867
+ // @ts-expect-error - Worker encoder typing is still WIP
4662
4868
  import_textures.KTX2BasisWriterWorker,
4663
4869
  {
4664
4870
  ...import_textures.KTX2BasisWriterWorker.options,
@@ -4671,22 +4877,58 @@ var I3SConverter = class {
4671
4877
  useLocalLibraries: true
4672
4878
  }
4673
4879
  );
4674
- await this.writeTextureFile(ktx2TextureData, "1", "ktx2", childPath, slpkChildPath);
4880
+ this.conversionDump.updateDoneStatus(
4881
+ sourceId,
4882
+ nodeId,
4883
+ `${"TEXTURE" /* TEXTURE */}/ktx2`,
4884
+ false
4885
+ );
4886
+ await this.writeTextureFile(
4887
+ ktx2TextureData,
4888
+ "1",
4889
+ "ktx2",
4890
+ childPath,
4891
+ slpkChildPath,
4892
+ sourceId,
4893
+ nodeId
4894
+ );
4675
4895
  }
4676
4896
  break;
4677
4897
  }
4678
4898
  case "ktx2": {
4679
4899
  formats.push({ name: "1", format });
4680
- await this.writeTextureFile(textureData, "1", format, childPath, slpkChildPath);
4900
+ this.conversionDump.updateDoneStatus(
4901
+ sourceId,
4902
+ nodeId,
4903
+ `${"TEXTURE" /* TEXTURE */}/${format}`,
4904
+ false
4905
+ );
4906
+ await this.writeTextureFile(
4907
+ textureData,
4908
+ "1",
4909
+ format,
4910
+ childPath,
4911
+ slpkChildPath,
4912
+ sourceId,
4913
+ nodeId
4914
+ );
4681
4915
  if (this.generateTextures) {
4682
4916
  formats.push({ name: "0", format: "jpg" });
4683
4917
  const decodedFromKTX2TextureData = (0, import_core9.encode)(texture.image.data[0], import_images.ImageWriter);
4918
+ this.conversionDump.updateDoneStatus(
4919
+ sourceId,
4920
+ nodeId,
4921
+ `${"TEXTURE" /* TEXTURE */}/jpg`,
4922
+ false
4923
+ );
4684
4924
  await this.writeTextureFile(
4685
4925
  decodedFromKTX2TextureData,
4686
4926
  "0",
4687
4927
  "jpg",
4688
4928
  childPath,
4689
- slpkChildPath
4929
+ slpkChildPath,
4930
+ sourceId,
4931
+ nodeId
4690
4932
  );
4691
4933
  }
4692
4934
  }
@@ -4704,18 +4946,26 @@ var I3SConverter = class {
4704
4946
  * @param format
4705
4947
  * @param childPath
4706
4948
  * @param slpkChildPath
4949
+ * @param sourceId
4950
+ * @param nodeId
4707
4951
  */
4708
- async writeTextureFile(textureData, name, format, childPath, slpkChildPath) {
4952
+ async writeTextureFile(textureData, name, format, childPath, slpkChildPath, sourceId, nodeId) {
4709
4953
  if (this.options.slpk) {
4710
4954
  const slpkTexturePath = (0, import_path7.join)(childPath, "textures");
4711
4955
  const compress = false;
4712
4956
  await this.writeQueue.enqueue({
4713
4957
  archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
4958
+ sourceId,
4959
+ outputId: nodeId,
4960
+ resourceType: `${"TEXTURE" /* TEXTURE */}/${format}`,
4714
4961
  writePromise: () => writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
4715
4962
  });
4716
4963
  } else {
4717
4964
  const texturePath = (0, import_path7.join)(childPath, `textures/${name}/`);
4718
4965
  await this.writeQueue.enqueue({
4966
+ sourceId,
4967
+ outputId: nodeId,
4968
+ resourceType: `${"TEXTURE" /* TEXTURE */}/${format}`,
4719
4969
  writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
4720
4970
  });
4721
4971
  }
@@ -4725,22 +4975,36 @@ var I3SConverter = class {
4725
4975
  * @param attributes - feature attributes
4726
4976
  * @param childPath - a child path to write resources
4727
4977
  * @param slpkChildPath - the resource path inside *slpk file
4978
+ * @param sourceId - source filename
4979
+ * @param nodeId - nodeId of a converted node for the writing
4728
4980
  */
4729
- async _writeAttributes(attributes = [], childPath, slpkChildPath) {
4981
+ async _writeAttributes(attributes = [], childPath, slpkChildPath, sourceId, nodeId) {
4730
4982
  if ((attributes == null ? void 0 : attributes.length) && this.attributeMetadataInfo.attributeStorageInfo.length) {
4731
4983
  const minimumLength = attributes.length < this.attributeMetadataInfo.attributeStorageInfo.length ? attributes.length : this.attributeMetadataInfo.attributeStorageInfo.length;
4732
4984
  for (let index = 0; index < minimumLength; index++) {
4733
4985
  const folderName = this.attributeMetadataInfo.attributeStorageInfo[index].key;
4734
4986
  const fileBuffer = new Uint8Array(attributes[index]);
4987
+ this.conversionDump.updateDoneStatus(
4988
+ sourceId,
4989
+ nodeId,
4990
+ `${"ATTRIBUTES" /* ATTRIBUTES */}/${folderName}`,
4991
+ false
4992
+ );
4735
4993
  if (this.options.slpk) {
4736
4994
  const slpkAttributesPath = (0, import_path7.join)(childPath, "attributes", folderName);
4737
4995
  await this.writeQueue.enqueue({
4738
4996
  archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
4997
+ sourceId,
4998
+ outputId: nodeId,
4999
+ resourceType: `${"ATTRIBUTES" /* ATTRIBUTES */}/${folderName}`,
4739
5000
  writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, "0.bin")
4740
5001
  });
4741
5002
  } else {
4742
5003
  const attributesPath = (0, import_path7.join)(childPath, `attributes/${folderName}/0`);
4743
5004
  await this.writeQueue.enqueue({
5005
+ sourceId,
5006
+ outputId: nodeId,
5007
+ resourceType: `${"ATTRIBUTES" /* ATTRIBUTES */}/${folderName}`,
4744
5008
  writePromise: () => writeFile(attributesPath, fileBuffer, "index.bin")
4745
5009
  });
4746
5010
  }
@@ -4951,7 +5215,7 @@ var TILESET = () => ({
4951
5215
  });
4952
5216
 
4953
5217
  // src/3d-tiles-converter/3d-tiles-converter.ts
4954
- var import_worker_utils3 = require("@loaders.gl/worker-utils");
5218
+ var import_worker_utils2 = require("@loaders.gl/worker-utils");
4955
5219
 
4956
5220
  // src/3d-tiles-converter/helpers/b3dm-converter.ts
4957
5221
  var import_core12 = require("@loaders.gl/core");
@@ -4994,6 +5258,9 @@ function normalizeRegions(regions) {
4994
5258
  // src/3d-tiles-converter/helpers/b3dm-converter.ts
4995
5259
  var Z_UP_TO_Y_UP_MATRIX = new import_core13.Matrix4([1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1]);
4996
5260
  var scratchVector2 = new import_core13.Vector3();
5261
+ var KHR_MATERIALS_UNLIT = "KHR_materials_unlit";
5262
+ var METALLIC_FACTOR_DEFAULT = 1;
5263
+ var ROUGHNESS_FACTOR_DEFAULT = 1;
4997
5264
  var B3dmConverter = class {
4998
5265
  /**
4999
5266
  * The starter of content conversion
@@ -5023,6 +5290,11 @@ var B3dmConverter = class {
5023
5290
  const { material, attributes, indices: originalIndices, modelMatrix } = tileContent;
5024
5291
  const gltfBuilder = new import_gltf6.GLTFScenegraph();
5025
5292
  const textureIndex = await this._addI3sTextureToGLTF(tileContent, textureFormat, gltfBuilder);
5293
+ const pbrMetallicRoughness = material == null ? void 0 : material.pbrMetallicRoughness;
5294
+ if (pbrMetallicRoughness && (pbrMetallicRoughness.metallicFactor === void 0 || pbrMetallicRoughness.metallicFactor === METALLIC_FACTOR_DEFAULT) && (pbrMetallicRoughness.roughnessFactor === void 0 || pbrMetallicRoughness.roughnessFactor === ROUGHNESS_FACTOR_DEFAULT)) {
5295
+ gltfBuilder.addObjectExtension(material, KHR_MATERIALS_UNLIT, {});
5296
+ gltfBuilder.addExtension(KHR_MATERIALS_UNLIT);
5297
+ }
5026
5298
  const pbrMaterialInfo = this._convertI3sMaterialToGLTFMaterial(material, textureIndex);
5027
5299
  const materialIndex = gltfBuilder.addMaterial(pbrMaterialInfo);
5028
5300
  const positions = attributes.positions;
@@ -5352,7 +5624,7 @@ var Tiles3DConverter = class {
5352
5624
  const tileset = (0, import_json_map_transform10.default)({ root: rootTile }, TILESET());
5353
5625
  await writeFile(this.tilesetPath, JSON.stringify(tileset), "tileset.json");
5354
5626
  this._finishConversion({ slpk: false, outputPath, tilesetName });
5355
- const workerFarm = import_worker_utils3.WorkerFarm.getWorkerFarm({});
5627
+ const workerFarm = import_worker_utils2.WorkerFarm.getWorkerFarm({});
5356
5628
  workerFarm.destroy();
5357
5629
  }
5358
5630
  /**