@loaders.gl/tile-converter 4.0.4 → 4.1.0-alpha.10

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/constants.d.ts +1 -0
  2. package/dist/constants.d.ts.map +1 -1
  3. package/dist/constants.js +1 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/converter-cli.js +41 -4
  6. package/dist/converter-cli.js.map +1 -1
  7. package/dist/converter.min.cjs +110 -110
  8. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  9. package/dist/deps-installer/deps-installer.js +4 -3
  10. package/dist/deps-installer/deps-installer.js.map +1 -1
  11. package/dist/i3s-converter/i3s-converter.d.ts +14 -0
  12. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  13. package/dist/i3s-converter/i3s-converter.js +71 -17
  14. package/dist/i3s-converter/i3s-converter.js.map +1 -1
  15. package/dist/i3s-converter/types.d.ts +7 -0
  16. package/dist/i3s-converter/types.d.ts.map +1 -1
  17. package/dist/i3s-converter/types.js +8 -0
  18. package/dist/i3s-converter/types.js.map +1 -1
  19. package/dist/i3s-server/bin/i3s-server.min.cjs +74 -74
  20. package/dist/i3s-server/routes/slpk-router.js +1 -1
  21. package/dist/i3s-server/routes/slpk-router.js.map +1 -1
  22. package/dist/index.cjs +347 -38
  23. package/dist/lib/utils/conversion-dump.d.ts +80 -0
  24. package/dist/lib/utils/conversion-dump.d.ts.map +1 -0
  25. package/dist/lib/utils/conversion-dump.js +127 -0
  26. package/dist/lib/utils/conversion-dump.js.map +1 -0
  27. package/dist/lib/utils/statistic-utills.d.ts +23 -6
  28. package/dist/lib/utils/write-queue.d.ts +6 -1
  29. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  30. package/dist/lib/utils/write-queue.js +15 -3
  31. package/dist/lib/utils/write-queue.js.map +1 -1
  32. package/dist/pgm-loader.js +1 -1
  33. package/dist/pgm-loader.js.map +1 -1
  34. package/dist/slpk-extractor.min.cjs +38 -38
  35. package/package.json +16 -16
  36. package/src/constants.ts +1 -0
  37. package/src/converter-cli.ts +58 -4
  38. package/src/deps-installer/deps-installer.ts +3 -2
  39. package/src/i3s-converter/i3s-converter.ts +189 -21
  40. package/src/i3s-converter/types.ts +8 -0
  41. package/src/i3s-server/routes/slpk-router.ts +1 -1
  42. package/src/lib/utils/conversion-dump.ts +198 -0
  43. package/src/lib/utils/write-queue.ts +15 -2
  44. package/dist/lib/utils/statistic-utills.d.js +0 -2
  45. package/dist/lib/utils/statistic-utills.d.js.map +0 -1
@@ -16,7 +16,7 @@ sceneServerRouter.get('*', async function (req, res, next) {
16
16
  });
17
17
  export const router = express.Router();
18
18
  router.get('*', async function (req, res, next) {
19
- const file = await getFileByUrl(req.path);
19
+ const file = await getFileByUrl(req.path.replace(/\/+$/, ''));
20
20
  if (file) {
21
21
  res.send(Buffer.from(file));
22
22
  } else {
@@ -1 +1 @@
1
- {"version":3,"file":"slpk-router.js","names":["express","getFileByUrl","createSceneServer","textDecoder","TextDecoder","sceneServerRouter","Router","get","req","res","next","file","layer","JSON","parse","decode","sceneServerResponse","name","send","status","router","path","Buffer","from"],"sources":["../../../src/i3s-server/routes/slpk-router.ts"],"sourcesContent":["import express from 'express';\nimport {getFileByUrl} from '../controllers/slpk-controller';\nimport {createSceneServer} from '../utils/create-scene-server';\n\nconst textDecoder = new TextDecoder();\n\nexport const sceneServerRouter = express.Router();\nsceneServerRouter.get('*', async function (req, res, next) {\n const file = await getFileByUrl('/');\n if (file) {\n const layer = JSON.parse(textDecoder.decode(file));\n const sceneServerResponse = createSceneServer(layer.name, layer);\n res.send(sceneServerResponse);\n } else {\n res.status(404);\n res.send('File not found');\n }\n});\n\nexport const router = express.Router();\nrouter.get('*', async function (req, res, next) {\n const file = await getFileByUrl(req.path);\n if (file) {\n res.send(Buffer.from(file));\n } else {\n res.status(404);\n res.send('File not found');\n }\n});\n"],"mappings":"AAAA,OAAOA,OAAO,MAAM,SAAS;AAAC,SACtBC,YAAY;AAAA,SACZC,iBAAiB;AAEzB,MAAMC,WAAW,GAAG,IAAIC,WAAW,CAAC,CAAC;AAErC,OAAO,MAAMC,iBAAiB,GAAGL,OAAO,CAACM,MAAM,CAAC,CAAC;AACjDD,iBAAiB,CAACE,GAAG,CAAC,GAAG,EAAE,gBAAgBC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE;EACzD,MAAMC,IAAI,GAAG,MAAMV,YAAY,CAAC,GAAG,CAAC;EACpC,IAAIU,IAAI,EAAE;IACR,MAAMC,KAAK,GAAGC,IAAI,CAACC,KAAK,CAACX,WAAW,CAACY,MAAM,CAACJ,IAAI,CAAC,CAAC;IAClD,MAAMK,mBAAmB,GAAGd,iBAAiB,CAACU,KAAK,CAACK,IAAI,EAAEL,KAAK,CAAC;IAChEH,GAAG,CAACS,IAAI,CAACF,mBAAmB,CAAC;EAC/B,CAAC,MAAM;IACLP,GAAG,CAACU,MAAM,CAAC,GAAG,CAAC;IACfV,GAAG,CAACS,IAAI,CAAC,gBAAgB,CAAC;EAC5B;AACF,CAAC,CAAC;AAEF,OAAO,MAAME,MAAM,GAAGpB,OAAO,CAACM,MAAM,CAAC,CAAC;AACtCc,MAAM,CAACb,GAAG,CAAC,GAAG,EAAE,gBAAgBC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE;EAC9C,MAAMC,IAAI,GAAG,MAAMV,YAAY,CAACO,GAAG,CAACa,IAAI,CAAC;EACzC,IAAIV,IAAI,EAAE;IACRF,GAAG,CAACS,IAAI,CAACI,MAAM,CAACC,IAAI,CAACZ,IAAI,CAAC,CAAC;EAC7B,CAAC,MAAM;IACLF,GAAG,CAACU,MAAM,CAAC,GAAG,CAAC;IACfV,GAAG,CAACS,IAAI,CAAC,gBAAgB,CAAC;EAC5B;AACF,CAAC,CAAC"}
1
+ {"version":3,"file":"slpk-router.js","names":["express","getFileByUrl","createSceneServer","textDecoder","TextDecoder","sceneServerRouter","Router","get","req","res","next","file","layer","JSON","parse","decode","sceneServerResponse","name","send","status","router","path","replace","Buffer","from"],"sources":["../../../src/i3s-server/routes/slpk-router.ts"],"sourcesContent":["import express from 'express';\nimport {getFileByUrl} from '../controllers/slpk-controller';\nimport {createSceneServer} from '../utils/create-scene-server';\n\nconst textDecoder = new TextDecoder();\n\nexport const sceneServerRouter = express.Router();\nsceneServerRouter.get('*', async function (req, res, next) {\n const file = await getFileByUrl('/');\n if (file) {\n const layer = JSON.parse(textDecoder.decode(file));\n const sceneServerResponse = createSceneServer(layer.name, layer);\n res.send(sceneServerResponse);\n } else {\n res.status(404);\n res.send('File not found');\n }\n});\n\nexport const router = express.Router();\nrouter.get('*', async function (req, res, next) {\n const file = await getFileByUrl(req.path.replace(/\\/+$/, ''));\n if (file) {\n res.send(Buffer.from(file));\n } else {\n res.status(404);\n res.send('File not found');\n }\n});\n"],"mappings":"AAAA,OAAOA,OAAO,MAAM,SAAS;AAAC,SACtBC,YAAY;AAAA,SACZC,iBAAiB;AAEzB,MAAMC,WAAW,GAAG,IAAIC,WAAW,CAAC,CAAC;AAErC,OAAO,MAAMC,iBAAiB,GAAGL,OAAO,CAACM,MAAM,CAAC,CAAC;AACjDD,iBAAiB,CAACE,GAAG,CAAC,GAAG,EAAE,gBAAgBC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE;EACzD,MAAMC,IAAI,GAAG,MAAMV,YAAY,CAAC,GAAG,CAAC;EACpC,IAAIU,IAAI,EAAE;IACR,MAAMC,KAAK,GAAGC,IAAI,CAACC,KAAK,CAACX,WAAW,CAACY,MAAM,CAACJ,IAAI,CAAC,CAAC;IAClD,MAAMK,mBAAmB,GAAGd,iBAAiB,CAACU,KAAK,CAACK,IAAI,EAAEL,KAAK,CAAC;IAChEH,GAAG,CAACS,IAAI,CAACF,mBAAmB,CAAC;EAC/B,CAAC,MAAM;IACLP,GAAG,CAACU,MAAM,CAAC,GAAG,CAAC;IACfV,GAAG,CAACS,IAAI,CAAC,gBAAgB,CAAC;EAC5B;AACF,CAAC,CAAC;AAEF,OAAO,MAAME,MAAM,GAAGpB,OAAO,CAACM,MAAM,CAAC,CAAC;AACtCc,MAAM,CAACb,GAAG,CAAC,GAAG,EAAE,gBAAgBC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE;EAC9C,MAAMC,IAAI,GAAG,MAAMV,YAAY,CAACO,GAAG,CAACa,IAAI,CAACC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;EAC7D,IAAIX,IAAI,EAAE;IACRF,GAAG,CAACS,IAAI,CAACK,MAAM,CAACC,IAAI,CAACb,IAAI,CAAC,CAAC;EAC7B,CAAC,MAAM;IACLF,GAAG,CAACU,MAAM,CAAC,GAAG,CAAC;IACfV,GAAG,CAACS,IAAI,CAAC,gBAAgB,CAAC;EAC5B;AACF,CAAC,CAAC"}
package/dist/index.cjs CHANGED
@@ -250,7 +250,7 @@ var AttributeMetadataInfo = class {
250
250
  // src/i3s-converter/i3s-converter.ts
251
251
  var import_core9 = require("@loaders.gl/core");
252
252
  var import_d_tiles2 = require("@loaders.gl/3d-tiles");
253
- var import_path7 = require("path");
253
+ var import_path8 = require("path");
254
254
  var import_uuid4 = require("uuid");
255
255
  var import_process3 = __toESM(require("process"), 1);
256
256
  var import_json_map_transform8 = __toESM(require("json-map-transform"), 1);
@@ -3134,6 +3134,7 @@ function isAllVerticesInsideBoundingVolume(boundingVolume, positions) {
3134
3134
 
3135
3135
  // src/i3s-converter/i3s-converter.ts
3136
3136
  var import_textures = require("@loaders.gl/textures");
3137
+ var import_loader_utils4 = require("@loaders.gl/loader-utils");
3137
3138
  var import_images = require("@loaders.gl/images");
3138
3139
  var import_worker_utils2 = require("@loaders.gl/worker-utils");
3139
3140
 
@@ -3157,10 +3158,11 @@ var Queue = class extends Array {
3157
3158
  var import_process = __toESM(require("process"), 1);
3158
3159
  var MEMORY_LIMIT = 4 * 1024 * 1024 * 1024;
3159
3160
  var WriteQueue = class extends Queue {
3160
- constructor(listeningInterval = 2e3, writeConcurrency = 400) {
3161
+ constructor(conversionDump, listeningInterval = 2e3, writeConcurrency = 400) {
3161
3162
  super();
3162
3163
  this.writePromise = null;
3163
3164
  this.fileMap = {};
3165
+ this.conversionDump = conversionDump;
3164
3166
  this.listeningInterval = listeningInterval;
3165
3167
  this.writeConcurrency = writeConcurrency;
3166
3168
  }
@@ -3201,18 +3203,21 @@ var WriteQueue = class extends Queue {
3201
3203
  while (this.length) {
3202
3204
  const promises = [];
3203
3205
  const archiveKeys = [];
3206
+ const changedRecords = [];
3204
3207
  for (let i = 0; i < this.writeConcurrency; i++) {
3205
3208
  const item = this.dequeue();
3206
3209
  if (!item) {
3207
3210
  break;
3208
3211
  }
3209
- const { archiveKey, writePromise } = item;
3212
+ const { archiveKey, sourceId, outputId, resourceType, writePromise } = item;
3210
3213
  archiveKeys.push(archiveKey);
3214
+ changedRecords.push({ sourceId, outputId, resourceType });
3211
3215
  const promise = writePromise();
3212
3216
  promises.push(promise);
3213
3217
  }
3214
3218
  const writeResults = await Promise.allSettled(promises);
3215
3219
  this.updateFileMap(archiveKeys, writeResults);
3220
+ await this.conversionDump.updateConvertedTilesDump(changedRecords, writeResults);
3216
3221
  }
3217
3222
  }
3218
3223
  updateFileMap(archiveKeys, writeResults) {
@@ -3227,6 +3232,7 @@ var WriteQueue = class extends Queue {
3227
3232
 
3228
3233
  // src/constants.ts
3229
3234
  var BROWSER_ERROR_MESSAGE = "Tile converter does not work in browser, only in node js environment";
3235
+ var DUMP_FILE_SUFFIX = ".dump.json";
3230
3236
 
3231
3237
  // src/i3s-converter/helpers/node-index-document.ts
3232
3238
  var import_path6 = require("path");
@@ -3902,6 +3908,169 @@ var Progress = class {
3902
3908
  }
3903
3909
  };
3904
3910
 
3911
+ // src/i3s-converter/i3s-converter.ts
3912
+ var import_zip = require("@loaders.gl/zip");
3913
+
3914
+ // src/lib/utils/conversion-dump.ts
3915
+ var import_path7 = require("path");
3916
+ var ConversionDump = class {
3917
+ constructor() {
3918
+ this.tilesConverted = {};
3919
+ }
3920
+ /**
3921
+ * Create a dump file with convertion options
3922
+ * @param options - converter options
3923
+ */
3924
+ async createDumpFile(options) {
3925
+ const {
3926
+ tilesetName,
3927
+ slpk,
3928
+ egmFilePath,
3929
+ inputUrl,
3930
+ outputPath,
3931
+ draco = true,
3932
+ maxDepth,
3933
+ token,
3934
+ generateTextures,
3935
+ generateBoundingVolumes,
3936
+ mergeMaterials: mergeMaterials2 = true,
3937
+ metadataClass,
3938
+ analyze = false
3939
+ } = options;
3940
+ this.options = {
3941
+ tilesetName,
3942
+ slpk,
3943
+ egmFilePath,
3944
+ inputUrl,
3945
+ outputPath,
3946
+ draco,
3947
+ maxDepth,
3948
+ token,
3949
+ generateTextures,
3950
+ generateBoundingVolumes,
3951
+ mergeMaterials: mergeMaterials2,
3952
+ metadataClass,
3953
+ analyze
3954
+ };
3955
+ try {
3956
+ await writeFile(
3957
+ options.outputPath,
3958
+ JSON.stringify({ options: this.options }),
3959
+ `${options.tilesetName}${DUMP_FILE_SUFFIX}`
3960
+ );
3961
+ } catch (error) {
3962
+ console.log("Can't create dump file", error);
3963
+ }
3964
+ }
3965
+ /**
3966
+ * Update conversion status in the dump file
3967
+ */
3968
+ async updateDumpFile() {
3969
+ var _a2;
3970
+ if (((_a2 = this.options) == null ? void 0 : _a2.outputPath) && this.options.tilesetName) {
3971
+ try {
3972
+ await writeFile(
3973
+ this.options.outputPath,
3974
+ JSON.stringify({
3975
+ options: this.options,
3976
+ tilesConverted: this.tilesConverted
3977
+ }),
3978
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
3979
+ );
3980
+ } catch (error) {
3981
+ console.log("Can't update dump file", error);
3982
+ }
3983
+ }
3984
+ }
3985
+ /**
3986
+ * Delete a dump file
3987
+ */
3988
+ async deleteDumpFile() {
3989
+ var _a2;
3990
+ if (((_a2 = this.options) == null ? void 0 : _a2.outputPath) && this.options.tilesetName) {
3991
+ await removeFile(
3992
+ (0, import_path7.join)(this.options.outputPath, `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`)
3993
+ );
3994
+ }
3995
+ }
3996
+ /**
3997
+ * Get record from the tilesConverted Map
3998
+ * @param fileName - source filename
3999
+ * @returns existing object from the tilesConverted Map
4000
+ */
4001
+ getRecord(fileName) {
4002
+ return this.tilesConverted[fileName];
4003
+ }
4004
+ /**
4005
+ * Set a record for the dump file
4006
+ * @param fileName - key - source filename
4007
+ * @param object - value
4008
+ */
4009
+ setRecord(fileName, object) {
4010
+ this.tilesConverted[fileName] = object;
4011
+ }
4012
+ /**
4013
+ * Add a node into the dump file for the source file record
4014
+ * @param fileName - source filename
4015
+ * @param nodeId - nodeId of the node
4016
+ */
4017
+ async addNode(filename, nodeId) {
4018
+ const { nodes } = this.getRecord(filename) || { nodes: [] };
4019
+ nodes.push({ nodeId, done: {} });
4020
+ if (nodes.length === 1) {
4021
+ this.setRecord(filename, { nodes });
4022
+ }
4023
+ await this.updateDumpFile();
4024
+ }
4025
+ /**
4026
+ * Update done status object for the writing resources
4027
+ * @param fileName - key - source filename
4028
+ * @param nodeId - nodeId for the source filename
4029
+ * @param resourceType - resource type to update status
4030
+ * @param value - value
4031
+ */
4032
+ updateDoneStatus(filename, nodeId, resourceType, value) {
4033
+ var _a2;
4034
+ const nodeDump = (_a2 = this.tilesConverted[filename]) == null ? void 0 : _a2.nodes.find(
4035
+ (element) => element.nodeId === nodeId
4036
+ );
4037
+ if (nodeDump) {
4038
+ nodeDump.done[resourceType] = value;
4039
+ }
4040
+ }
4041
+ /**
4042
+ * Update dump file according to writing results
4043
+ * @param changedRecords - array of parameters ids for the written resources
4044
+ * @param writeResults - array of writing resource files results
4045
+ */
4046
+ async updateConvertedTilesDump(changedRecords, writeResults) {
4047
+ for (let i = 0; i < changedRecords.length; i++) {
4048
+ if (changedRecords[i] && "value" in writeResults[i]) {
4049
+ const { sourceId, resourceType, outputId } = changedRecords[i];
4050
+ if (!sourceId || !resourceType || !outputId)
4051
+ continue;
4052
+ for (const node of this.tilesConverted[sourceId].nodes) {
4053
+ if (typeof node.done !== "boolean" && node.nodeId === outputId) {
4054
+ node.done[resourceType] = true;
4055
+ }
4056
+ if (typeof node.done !== "boolean") {
4057
+ let done = false;
4058
+ for (const key in node.done) {
4059
+ done = node.done[key];
4060
+ if (!done)
4061
+ break;
4062
+ }
4063
+ if (done) {
4064
+ node.done = true;
4065
+ }
4066
+ }
4067
+ }
4068
+ }
4069
+ }
4070
+ await this.updateDumpFile();
4071
+ }
4072
+ };
4073
+
3905
4074
  // src/i3s-converter/i3s-converter.ts
3906
4075
  var _a;
3907
4076
  var ION_DEFAULT_TOKEN = (_a = import_process3.default.env) == null ? void 0 : _a.IonToken;
@@ -3934,7 +4103,7 @@ var I3SConverter = class {
3934
4103
  this.geoidHeightModel = null;
3935
4104
  this.Loader = import_d_tiles2.Tiles3DLoader;
3936
4105
  this.workerSource = {};
3937
- this.writeQueue = new WriteQueue();
4106
+ this.writeQueue = new WriteQueue(new ConversionDump());
3938
4107
  this.compressList = null;
3939
4108
  this.preprocessData = {
3940
4109
  meshTopologyTypes: /* @__PURE__ */ new Set(),
@@ -3961,6 +4130,7 @@ var I3SConverter = class {
3961
4130
  this.generateBoundingVolumes = false;
3962
4131
  this.layersHasTexture = false;
3963
4132
  this.compressList = null;
4133
+ this.conversionDump = new ConversionDump();
3964
4134
  }
3965
4135
  /**
3966
4136
  * Convert a 3d tileset
@@ -4005,6 +4175,8 @@ var I3SConverter = class {
4005
4175
  analyze = false
4006
4176
  } = options;
4007
4177
  this.options = {
4178
+ outputPath,
4179
+ tilesetName,
4008
4180
  maxDepth,
4009
4181
  slpk,
4010
4182
  sevenZipExe,
@@ -4023,7 +4195,7 @@ var I3SConverter = class {
4023
4195
  this.Loader = inputUrl.indexOf(CESIUM_DATASET_PREFIX) !== -1 ? import_d_tiles2.CesiumIonLoader : import_d_tiles2.Tiles3DLoader;
4024
4196
  this.generateTextures = Boolean(generateTextures);
4025
4197
  this.generateBoundingVolumes = Boolean(generateBoundingVolumes);
4026
- this.writeQueue = new WriteQueue();
4198
+ this.writeQueue = new WriteQueue(this.conversionDump);
4027
4199
  this.writeQueue.startListening();
4028
4200
  console.log("Loading egm file...");
4029
4201
  this.geoidHeightModel = await (0, import_core9.load)(egmFilePath, PGMLoader);
@@ -4031,6 +4203,7 @@ var I3SConverter = class {
4031
4203
  if (slpk) {
4032
4204
  this.nodePages.useWriteFunction(writeFileForSlpk);
4033
4205
  }
4206
+ await this.conversionDump.createDumpFile(options);
4034
4207
  try {
4035
4208
  const preloadOptions = await this._fetchPreloadOptions();
4036
4209
  let tilesetUrl = inputUrl;
@@ -4164,12 +4337,12 @@ var I3SConverter = class {
4164
4337
  */
4165
4338
  async _createAndSaveTileset(outputPath, tilesetName) {
4166
4339
  var _a2, _b, _c;
4167
- const tilesetPath = (0, import_path7.join)(`${outputPath}`, `${tilesetName}`);
4340
+ const tilesetPath = (0, import_path8.join)(`${outputPath}`, `${tilesetName}`);
4168
4341
  try {
4169
4342
  await removeDir(tilesetPath);
4170
4343
  } catch (e) {
4171
4344
  }
4172
- this.layers0Path = (0, import_path7.join)(tilesetPath, "SceneServer", "layers", "0");
4345
+ this.layers0Path = (0, import_path8.join)(tilesetPath, "SceneServer", "layers", "0");
4173
4346
  this.materialDefinitions = [];
4174
4347
  this.materialMap = /* @__PURE__ */ new Map();
4175
4348
  const sourceRootTile = this.sourceTileset.root;
@@ -4286,8 +4459,9 @@ var I3SConverter = class {
4286
4459
  * @param tilesetPath - Path to save file
4287
4460
  */
4288
4461
  async _createSlpk(tilesetPath) {
4462
+ await this.conversionDump.deleteDumpFile();
4289
4463
  if (this.options.slpk) {
4290
- const slpkTilesetPath = (0, import_path7.join)(tilesetPath, "SceneServer", "layers", "0");
4464
+ const slpkTilesetPath = (0, import_path8.join)(tilesetPath, "SceneServer", "layers", "0");
4291
4465
  const slpkFileName = `${tilesetPath}.slpk`;
4292
4466
  await compressWithChildProcess(
4293
4467
  slpkTilesetPath,
@@ -4296,6 +4470,8 @@ var I3SConverter = class {
4296
4470
  ".",
4297
4471
  this.options.sevenZipExe
4298
4472
  );
4473
+ const hashTable = await (0, import_zip.composeHashFile)(new import_loader_utils4.FileHandleFile(slpkFileName));
4474
+ await (0, import_zip.addOneFile)(slpkFileName, hashTable, "@specialIndexFileHASH128@");
4299
4475
  try {
4300
4476
  await removeDir(tilesetPath);
4301
4477
  } catch (e) {
@@ -4436,7 +4612,10 @@ var I3SConverter = class {
4436
4612
  const node = await new NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
4437
4613
  nodes.push(node);
4438
4614
  if (nodeInPage.mesh) {
4439
- await this._writeResources(resources, node.id);
4615
+ if (sourceTile.id) {
4616
+ await this.conversionDump.addNode(sourceTile.id, nodeInPage.index);
4617
+ }
4618
+ await this._writeResources(resources, node.id, sourceTile);
4440
4619
  }
4441
4620
  if (this.validate) {
4442
4621
  this.boundingVolumeWarnings = validateNodeBoundingVolumes(nodeData);
@@ -4560,9 +4739,11 @@ var I3SConverter = class {
4560
4739
  * @param resources.texture - texture image
4561
4740
  * @param resources.sharedResources - shared resource data object
4562
4741
  * @param resources.attributes - feature attributes
4742
+ * @param nodePath - node path
4743
+ * @param sourceTile - source tile (3DTile)
4563
4744
  * @return {Promise<void>}
4564
4745
  */
4565
- async _writeResources(resources, nodePath) {
4746
+ async _writeResources(resources, nodePath, sourceTile) {
4566
4747
  const {
4567
4748
  geometry: geometryBuffer,
4568
4749
  compressedGeometry,
@@ -4570,12 +4751,38 @@ var I3SConverter = class {
4570
4751
  sharedResources,
4571
4752
  attributes
4572
4753
  } = resources;
4573
- const childPath = (0, import_path7.join)(this.layers0Path, "nodes", nodePath);
4574
- 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);
4754
+ const childPath = (0, import_path8.join)(this.layers0Path, "nodes", nodePath);
4755
+ const slpkChildPath = (0, import_path8.join)("nodes", nodePath);
4756
+ await this._writeGeometries(
4757
+ geometryBuffer,
4758
+ compressedGeometry,
4759
+ childPath,
4760
+ slpkChildPath,
4761
+ sourceTile.id || "",
4762
+ parseInt(nodePath)
4763
+ );
4764
+ await this._writeShared(
4765
+ sharedResources,
4766
+ childPath,
4767
+ slpkChildPath,
4768
+ nodePath,
4769
+ sourceTile.id || "",
4770
+ parseInt(nodePath)
4771
+ );
4772
+ await this._writeTexture(
4773
+ texture,
4774
+ childPath,
4775
+ slpkChildPath,
4776
+ sourceTile.id || "",
4777
+ parseInt(nodePath)
4778
+ );
4779
+ await this._writeAttributes(
4780
+ attributes,
4781
+ childPath,
4782
+ slpkChildPath,
4783
+ sourceTile.id || "",
4784
+ parseInt(nodePath)
4785
+ );
4579
4786
  }
4580
4787
  /**
4581
4788
  * Write non-compressed and compressed geometries in files
@@ -4583,30 +4790,46 @@ var I3SConverter = class {
4583
4790
  * @param compressedGeometry - Uint8Array with compressed (draco) geometry
4584
4791
  * @param childPath - a child path to write resources
4585
4792
  * @param slpkChildPath - resource path inside *slpk file
4793
+ * @param sourceId - source filename
4794
+ * @param nodeId - nodeId of a converted node for the writing
4586
4795
  */
4587
- async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath) {
4796
+ async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath, sourceId, nodeId) {
4797
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, "GEOMETRY" /* GEOMETRY */, false);
4588
4798
  if (this.options.slpk) {
4589
- const slpkGeometryPath = (0, import_path7.join)(childPath, "geometries");
4799
+ const slpkGeometryPath = (0, import_path8.join)(childPath, "geometries");
4590
4800
  await this.writeQueue.enqueue({
4591
4801
  archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
4802
+ sourceId,
4803
+ outputId: nodeId,
4804
+ resourceType: "GEOMETRY" /* GEOMETRY */,
4592
4805
  writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, "0.bin")
4593
4806
  });
4594
4807
  } else {
4595
- const geometryPath = (0, import_path7.join)(childPath, "geometries/0/");
4808
+ const geometryPath = (0, import_path8.join)(childPath, "geometries/0/");
4596
4809
  await this.writeQueue.enqueue({
4810
+ sourceId,
4811
+ outputId: nodeId,
4812
+ resourceType: "GEOMETRY" /* GEOMETRY */,
4597
4813
  writePromise: () => writeFile(geometryPath, geometryBuffer, "index.bin")
4598
4814
  });
4599
4815
  }
4600
4816
  if (this.options.draco) {
4817
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, "DRACO_GEOMETRY" /* DRACO_GEOMETRY */, false);
4601
4818
  if (this.options.slpk) {
4602
- const slpkCompressedGeometryPath = (0, import_path7.join)(childPath, "geometries");
4819
+ const slpkCompressedGeometryPath = (0, import_path8.join)(childPath, "geometries");
4603
4820
  await this.writeQueue.enqueue({
4604
4821
  archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
4822
+ sourceId,
4823
+ outputId: nodeId,
4824
+ resourceType: "DRACO_GEOMETRY" /* DRACO_GEOMETRY */,
4605
4825
  writePromise: () => writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, "1.bin")
4606
4826
  });
4607
4827
  } else {
4608
- const compressedGeometryPath = (0, import_path7.join)(childPath, "geometries/1/");
4828
+ const compressedGeometryPath = (0, import_path8.join)(childPath, "geometries/1/");
4609
4829
  await this.writeQueue.enqueue({
4830
+ sourceId,
4831
+ outputId: nodeId,
4832
+ resourceType: "DRACO_GEOMETRY" /* DRACO_GEOMETRY */,
4610
4833
  writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, "index.bin")
4611
4834
  });
4612
4835
  }
@@ -4618,23 +4841,34 @@ var I3SConverter = class {
4618
4841
  * @param childPath - a child path to write resources
4619
4842
  * @param slpkChildPath - resource path inside *slpk file
4620
4843
  * @param nodePath - a node path
4844
+ * @param sourceId - source filename
4845
+ * @param nodeId - nodeId of a converted node for the writing
4621
4846
  */
4622
- async _writeShared(sharedResources, childPath, slpkChildPath, nodePath) {
4847
+ async _writeShared(sharedResources, childPath, slpkChildPath, nodePath, sourceId, nodeId) {
4623
4848
  if (!sharedResources) {
4624
4849
  return;
4625
4850
  }
4626
4851
  sharedResources.nodePath = nodePath;
4627
4852
  const sharedData = (0, import_json_map_transform8.default)(sharedResources, SHARED_RESOURCES());
4628
4853
  const sharedDataStr = JSON.stringify(sharedData);
4854
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, "SHARED" /* SHARED */, false);
4629
4855
  if (this.options.slpk) {
4630
- const slpkSharedPath = (0, import_path7.join)(childPath, "shared");
4856
+ const slpkSharedPath = (0, import_path8.join)(childPath, "shared");
4631
4857
  await this.writeQueue.enqueue({
4632
4858
  archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
4859
+ sourceId,
4860
+ outputId: nodeId,
4861
+ resourceType: "SHARED" /* SHARED */,
4633
4862
  writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, "sharedResource.json")
4634
4863
  });
4635
4864
  } else {
4636
- const sharedPath = (0, import_path7.join)(childPath, "shared/");
4637
- await this.writeQueue.enqueue({ writePromise: () => writeFile(sharedPath, sharedDataStr) });
4865
+ const sharedPath = (0, import_path8.join)(childPath, "shared/");
4866
+ await this.writeQueue.enqueue({
4867
+ sourceId,
4868
+ outputId: nodeId,
4869
+ resourceType: "SHARED" /* SHARED */,
4870
+ writePromise: () => writeFile(sharedPath, sharedDataStr)
4871
+ });
4638
4872
  }
4639
4873
  }
4640
4874
  /**
@@ -4642,8 +4876,10 @@ var I3SConverter = class {
4642
4876
  * @param texture - the texture image
4643
4877
  * @param childPath - a child path to write resources
4644
4878
  * @param slpkChildPath - the resource path inside *slpk file
4879
+ * @param sourceId - source filename
4880
+ * @param nodeId - nodeId of a converted node for the writing
4645
4881
  */
4646
- async _writeTexture(texture, childPath, slpkChildPath) {
4882
+ async _writeTexture(texture, childPath, slpkChildPath, sourceId, nodeId) {
4647
4883
  if (texture) {
4648
4884
  const format = this._getFormatByMimeType(texture == null ? void 0 : texture.mimeType);
4649
4885
  const formats = [];
@@ -4652,13 +4888,28 @@ var I3SConverter = class {
4652
4888
  case "jpg":
4653
4889
  case "png": {
4654
4890
  formats.push({ name: "0", format });
4655
- await this.writeTextureFile(textureData, "0", format, childPath, slpkChildPath);
4891
+ this.conversionDump.updateDoneStatus(
4892
+ sourceId,
4893
+ nodeId,
4894
+ `${"TEXTURE" /* TEXTURE */}/${format}`,
4895
+ false
4896
+ );
4897
+ await this.writeTextureFile(
4898
+ textureData,
4899
+ "0",
4900
+ format,
4901
+ childPath,
4902
+ slpkChildPath,
4903
+ sourceId,
4904
+ nodeId
4905
+ );
4656
4906
  if (this.generateTextures) {
4657
4907
  formats.push({ name: "1", format: "ktx2" });
4658
4908
  const copyArrayBuffer = texture.image.data.subarray();
4659
4909
  const arrayToEncode = new Uint8Array(copyArrayBuffer);
4660
4910
  const ktx2TextureData = (0, import_core9.encode)(
4661
4911
  { ...texture.image, data: arrayToEncode },
4912
+ // @ts-expect-error - Worker encoder typing is still WIP
4662
4913
  import_textures.KTX2BasisWriterWorker,
4663
4914
  {
4664
4915
  ...import_textures.KTX2BasisWriterWorker.options,
@@ -4671,22 +4922,58 @@ var I3SConverter = class {
4671
4922
  useLocalLibraries: true
4672
4923
  }
4673
4924
  );
4674
- await this.writeTextureFile(ktx2TextureData, "1", "ktx2", childPath, slpkChildPath);
4925
+ this.conversionDump.updateDoneStatus(
4926
+ sourceId,
4927
+ nodeId,
4928
+ `${"TEXTURE" /* TEXTURE */}/ktx2`,
4929
+ false
4930
+ );
4931
+ await this.writeTextureFile(
4932
+ ktx2TextureData,
4933
+ "1",
4934
+ "ktx2",
4935
+ childPath,
4936
+ slpkChildPath,
4937
+ sourceId,
4938
+ nodeId
4939
+ );
4675
4940
  }
4676
4941
  break;
4677
4942
  }
4678
4943
  case "ktx2": {
4679
4944
  formats.push({ name: "1", format });
4680
- await this.writeTextureFile(textureData, "1", format, childPath, slpkChildPath);
4945
+ this.conversionDump.updateDoneStatus(
4946
+ sourceId,
4947
+ nodeId,
4948
+ `${"TEXTURE" /* TEXTURE */}/${format}`,
4949
+ false
4950
+ );
4951
+ await this.writeTextureFile(
4952
+ textureData,
4953
+ "1",
4954
+ format,
4955
+ childPath,
4956
+ slpkChildPath,
4957
+ sourceId,
4958
+ nodeId
4959
+ );
4681
4960
  if (this.generateTextures) {
4682
4961
  formats.push({ name: "0", format: "jpg" });
4683
4962
  const decodedFromKTX2TextureData = (0, import_core9.encode)(texture.image.data[0], import_images.ImageWriter);
4963
+ this.conversionDump.updateDoneStatus(
4964
+ sourceId,
4965
+ nodeId,
4966
+ `${"TEXTURE" /* TEXTURE */}/jpg`,
4967
+ false
4968
+ );
4684
4969
  await this.writeTextureFile(
4685
4970
  decodedFromKTX2TextureData,
4686
4971
  "0",
4687
4972
  "jpg",
4688
4973
  childPath,
4689
- slpkChildPath
4974
+ slpkChildPath,
4975
+ sourceId,
4976
+ nodeId
4690
4977
  );
4691
4978
  }
4692
4979
  }
@@ -4704,18 +4991,26 @@ var I3SConverter = class {
4704
4991
  * @param format
4705
4992
  * @param childPath
4706
4993
  * @param slpkChildPath
4994
+ * @param sourceId
4995
+ * @param nodeId
4707
4996
  */
4708
- async writeTextureFile(textureData, name, format, childPath, slpkChildPath) {
4997
+ async writeTextureFile(textureData, name, format, childPath, slpkChildPath, sourceId, nodeId) {
4709
4998
  if (this.options.slpk) {
4710
- const slpkTexturePath = (0, import_path7.join)(childPath, "textures");
4999
+ const slpkTexturePath = (0, import_path8.join)(childPath, "textures");
4711
5000
  const compress = false;
4712
5001
  await this.writeQueue.enqueue({
4713
5002
  archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
5003
+ sourceId,
5004
+ outputId: nodeId,
5005
+ resourceType: `${"TEXTURE" /* TEXTURE */}/${format}`,
4714
5006
  writePromise: () => writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
4715
5007
  });
4716
5008
  } else {
4717
- const texturePath = (0, import_path7.join)(childPath, `textures/${name}/`);
5009
+ const texturePath = (0, import_path8.join)(childPath, `textures/${name}/`);
4718
5010
  await this.writeQueue.enqueue({
5011
+ sourceId,
5012
+ outputId: nodeId,
5013
+ resourceType: `${"TEXTURE" /* TEXTURE */}/${format}`,
4719
5014
  writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
4720
5015
  });
4721
5016
  }
@@ -4725,22 +5020,36 @@ var I3SConverter = class {
4725
5020
  * @param attributes - feature attributes
4726
5021
  * @param childPath - a child path to write resources
4727
5022
  * @param slpkChildPath - the resource path inside *slpk file
5023
+ * @param sourceId - source filename
5024
+ * @param nodeId - nodeId of a converted node for the writing
4728
5025
  */
4729
- async _writeAttributes(attributes = [], childPath, slpkChildPath) {
5026
+ async _writeAttributes(attributes = [], childPath, slpkChildPath, sourceId, nodeId) {
4730
5027
  if ((attributes == null ? void 0 : attributes.length) && this.attributeMetadataInfo.attributeStorageInfo.length) {
4731
5028
  const minimumLength = attributes.length < this.attributeMetadataInfo.attributeStorageInfo.length ? attributes.length : this.attributeMetadataInfo.attributeStorageInfo.length;
4732
5029
  for (let index = 0; index < minimumLength; index++) {
4733
5030
  const folderName = this.attributeMetadataInfo.attributeStorageInfo[index].key;
4734
5031
  const fileBuffer = new Uint8Array(attributes[index]);
5032
+ this.conversionDump.updateDoneStatus(
5033
+ sourceId,
5034
+ nodeId,
5035
+ `${"ATTRIBUTES" /* ATTRIBUTES */}/${folderName}`,
5036
+ false
5037
+ );
4735
5038
  if (this.options.slpk) {
4736
- const slpkAttributesPath = (0, import_path7.join)(childPath, "attributes", folderName);
5039
+ const slpkAttributesPath = (0, import_path8.join)(childPath, "attributes", folderName);
4737
5040
  await this.writeQueue.enqueue({
4738
5041
  archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
5042
+ sourceId,
5043
+ outputId: nodeId,
5044
+ resourceType: `${"ATTRIBUTES" /* ATTRIBUTES */}/${folderName}`,
4739
5045
  writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, "0.bin")
4740
5046
  });
4741
5047
  } else {
4742
- const attributesPath = (0, import_path7.join)(childPath, `attributes/${folderName}/0`);
5048
+ const attributesPath = (0, import_path8.join)(childPath, `attributes/${folderName}/0`);
4743
5049
  await this.writeQueue.enqueue({
5050
+ sourceId,
5051
+ outputId: nodeId,
5052
+ resourceType: `${"ATTRIBUTES" /* ATTRIBUTES */}/${folderName}`,
4744
5053
  writePromise: () => writeFile(attributesPath, fileBuffer, "index.bin")
4745
5054
  });
4746
5055
  }
@@ -4887,7 +5196,7 @@ var I3SConverter = class {
4887
5196
  };
4888
5197
 
4889
5198
  // src/3d-tiles-converter/3d-tiles-converter.ts
4890
- var import_path8 = require("path");
5199
+ var import_path9 = require("path");
4891
5200
  var import_process4 = __toESM(require("process"), 1);
4892
5201
  var import_json_map_transform10 = __toESM(require("json-map-transform"), 1);
4893
5202
  var import_core15 = require("@loaders.gl/core");
@@ -5335,7 +5644,7 @@ var Tiles3DConverter = class {
5335
5644
  if (!rootNode.obb) {
5336
5645
  rootNode.obb = createObbFromMbs(rootNode.mbs);
5337
5646
  }
5338
- this.tilesetPath = (0, import_path8.join)(`${outputPath}`, `${tilesetName}`);
5647
+ this.tilesetPath = (0, import_path9.join)(`${outputPath}`, `${tilesetName}`);
5339
5648
  this.attributeStorageInfo = this.sourceTileset.attributeStorageInfo;
5340
5649
  try {
5341
5650
  await removeDir(this.tilesetPath);