@loaders.gl/tile-converter 4.1.1 → 4.2.0-alpha.2

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 (55) hide show
  1. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +11 -0
  2. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  3. package/dist/3d-tiles-converter/3d-tiles-converter.js +77 -27
  4. package/dist/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  5. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts +22 -1
  6. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts.map +1 -1
  7. package/dist/3d-tiles-converter/helpers/load-i3s.js +49 -4
  8. package/dist/3d-tiles-converter/helpers/load-i3s.js.map +1 -1
  9. package/dist/converter-cli.js +2 -1
  10. package/dist/converter-cli.js.map +1 -1
  11. package/dist/converter.min.cjs +137 -130
  12. package/dist/deps-installer/deps-installer.js +1 -1
  13. package/dist/deps-installer/deps-installer.js.map +1 -1
  14. package/dist/i3s-converter/helpers/attribute-metadata-info.d.ts +10 -0
  15. package/dist/i3s-converter/helpers/attribute-metadata-info.d.ts.map +1 -1
  16. package/dist/i3s-converter/helpers/attribute-metadata-info.js +5 -0
  17. package/dist/i3s-converter/helpers/attribute-metadata-info.js.map +1 -1
  18. package/dist/i3s-converter/helpers/load-3d-tiles.d.ts.map +1 -1
  19. package/dist/i3s-converter/helpers/load-3d-tiles.js +22 -2
  20. package/dist/i3s-converter/helpers/load-3d-tiles.js.map +1 -1
  21. package/dist/i3s-converter/helpers/node-index-document.d.ts +2 -1
  22. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
  23. package/dist/i3s-converter/helpers/node-index-document.js +6 -8
  24. package/dist/i3s-converter/helpers/node-index-document.js.map +1 -1
  25. package/dist/i3s-converter/i3s-converter.d.ts +18 -0
  26. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  27. package/dist/i3s-converter/i3s-converter.js +121 -24
  28. package/dist/i3s-converter/i3s-converter.js.map +1 -1
  29. package/dist/i3s-server/bin/i3s-server.min.cjs +86 -86
  30. package/dist/index.cjs +792 -101
  31. package/dist/lib/json-schemas/conversion-dump-json-schema.d.ts +463 -0
  32. package/dist/lib/json-schemas/conversion-dump-json-schema.d.ts.map +1 -0
  33. package/dist/lib/json-schemas/conversion-dump-json-schema.js +463 -0
  34. package/dist/lib/json-schemas/conversion-dump-json-schema.js.map +1 -0
  35. package/dist/lib/utils/conversion-dump.d.ts +65 -8
  36. package/dist/lib/utils/conversion-dump.d.ts.map +1 -1
  37. package/dist/lib/utils/conversion-dump.js +98 -18
  38. package/dist/lib/utils/conversion-dump.js.map +1 -1
  39. package/dist/lib/utils/file-utils.d.ts +6 -0
  40. package/dist/lib/utils/file-utils.d.ts.map +1 -1
  41. package/dist/lib/utils/file-utils.js +7 -0
  42. package/dist/lib/utils/file-utils.js.map +1 -1
  43. package/dist/pgm-loader.js +1 -1
  44. package/dist/pgm-loader.js.map +1 -1
  45. package/package.json +15 -14
  46. package/src/3d-tiles-converter/3d-tiles-converter.ts +104 -31
  47. package/src/3d-tiles-converter/helpers/load-i3s.ts +86 -7
  48. package/src/converter-cli.ts +2 -1
  49. package/src/i3s-converter/helpers/attribute-metadata-info.ts +16 -0
  50. package/src/i3s-converter/helpers/load-3d-tiles.ts +52 -2
  51. package/src/i3s-converter/helpers/node-index-document.ts +18 -8
  52. package/src/i3s-converter/i3s-converter.ts +198 -41
  53. package/src/lib/json-schemas/conversion-dump-json-schema.ts +285 -0
  54. package/src/lib/utils/conversion-dump.ts +200 -26
  55. package/src/lib/utils/file-utils.ts +13 -0
@@ -1,6 +1,12 @@
1
+ import {isDeepStrictEqual} from 'util';
1
2
  import {DUMP_FILE_SUFFIX} from '../../constants';
2
- import {removeFile, writeFile} from './file-utils';
3
+ import {isFileExists, openJson, removeFile, renameFile, writeFile} from './file-utils';
3
4
  import {join} from 'path';
5
+ import {BoundingVolumes, I3SMaterialDefinition, TextureSetDefinitionFormats} from '@loaders.gl/i3s';
6
+ import {AttributeMetadataInfoObject} from '../../i3s-converter/helpers/attribute-metadata-info';
7
+ import process from 'process';
8
+ import Ajv from 'ajv';
9
+ import {dumpJsonSchema} from '../json-schemas/conversion-dump-json-schema';
4
10
 
5
11
  export type ConversionDumpOptions = {
6
12
  inputUrl: string;
@@ -19,30 +25,55 @@ export type ConversionDumpOptions = {
19
25
  };
20
26
 
21
27
  type NodeDoneStatus = {
22
- nodeId: number;
28
+ nodeId: number | string;
23
29
  done: boolean;
24
- progress: Record<string, boolean>;
30
+ progress?: Record<string, boolean>;
31
+ dumpMetadata?: DumpMetadata;
25
32
  };
26
33
 
27
34
  type TilesConverted = {
28
35
  nodes: NodeDoneStatus[];
29
36
  };
30
37
 
38
+ export type DumpMetadata = {
39
+ boundingVolumes: BoundingVolumes | null;
40
+ attributesCount?: number;
41
+ featureCount: number | null;
42
+ geometry: boolean;
43
+ hasUvRegions: boolean;
44
+ materialId: number | null;
45
+ texelCountHint?: number;
46
+ vertexCount: number | null;
47
+ };
48
+
49
+ export type TextureSetDefinition = {
50
+ formats: TextureSetDefinitionFormats;
51
+ atlas?: boolean;
52
+ };
53
+
31
54
  export class ConversionDump {
55
+ /**Restored/resumed dump indicator */
56
+ restored: boolean = false;
32
57
  /** Conversion options */
33
58
  private options?: ConversionDumpOptions;
34
59
  /** Tiles conversion progress status map */
35
60
  tilesConverted: Record<string, TilesConverted>;
61
+ /** Textures formats definitions */
62
+ textureSetDefinitions?: TextureSetDefinition[];
63
+ /** Attributes Metadata */
64
+ attributeMetadataInfo?: AttributeMetadataInfoObject;
65
+ /** Array of materials definitions */
66
+ materialDefinitions?: I3SMaterialDefinition[];
36
67
 
37
68
  constructor() {
38
69
  this.tilesConverted = {};
39
70
  }
40
71
 
41
72
  /**
42
- * Create a dump file with convertion options
43
- * @param options - converter options
73
+ * Create a dump with convertion options
74
+ * @param currentOptions - converter options
44
75
  */
45
- async createDumpFile(options: ConversionDumpOptions): Promise<void> {
76
+ async createDump(currentOptions: ConversionDumpOptions): Promise<void> {
46
77
  const {
47
78
  tilesetName,
48
79
  slpk,
@@ -57,7 +88,7 @@ export class ConversionDump {
57
88
  mergeMaterials = true,
58
89
  metadataClass,
59
90
  analyze = false
60
- } = options;
91
+ } = currentOptions;
61
92
  this.options = {
62
93
  tilesetName,
63
94
  slpk,
@@ -74,14 +105,59 @@ export class ConversionDump {
74
105
  analyze
75
106
  };
76
107
 
77
- try {
78
- await writeFile(
79
- options.outputPath,
80
- JSON.stringify({options: this.options}),
81
- `${options.tilesetName}${DUMP_FILE_SUFFIX}`
82
- );
83
- } catch (error) {
84
- console.log("Can't create dump file", error);
108
+ const dumpFilename = join(
109
+ this.options.outputPath,
110
+ this.options.tilesetName,
111
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
112
+ );
113
+ if (await isFileExists(dumpFilename)) {
114
+ try {
115
+ const dump = await openJson(
116
+ join(this.options.outputPath, this.options.tilesetName),
117
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
118
+ );
119
+
120
+ const {
121
+ options,
122
+ tilesConverted,
123
+ textureSetDefinitions,
124
+ attributeMetadataInfo,
125
+ materialDefinitions
126
+ } = dump;
127
+
128
+ const ajv = new Ajv();
129
+ const dumpJsonValidate = ajv.compile(dumpJsonSchema);
130
+ const isDumpValid = dumpJsonValidate(dump);
131
+
132
+ if (isDumpValid && isDeepStrictEqual(options, JSON.parse(JSON.stringify(this.options)))) {
133
+ this.tilesConverted = tilesConverted;
134
+ this.textureSetDefinitions = textureSetDefinitions;
135
+ this.attributeMetadataInfo = attributeMetadataInfo;
136
+ this.materialDefinitions = materialDefinitions;
137
+ this.restored = true;
138
+ return;
139
+ }
140
+ } catch (error) {
141
+ console.log("Can't open dump file", error);
142
+ }
143
+ }
144
+ await this.deleteDumpFile();
145
+ }
146
+
147
+ /**
148
+ * Reset a dump
149
+ */
150
+ reset(): void {
151
+ this.restored = false;
152
+ this.tilesConverted = {};
153
+ if (this.textureSetDefinitions) {
154
+ delete this.textureSetDefinitions;
155
+ }
156
+ if (this.attributeMetadataInfo) {
157
+ delete this.attributeMetadataInfo;
158
+ }
159
+ if (this.materialDefinitions) {
160
+ delete this.materialDefinitions;
85
161
  }
86
162
  }
87
163
 
@@ -91,13 +167,29 @@ export class ConversionDump {
91
167
  private async updateDumpFile(): Promise<void> {
92
168
  if (this.options?.outputPath && this.options.tilesetName) {
93
169
  try {
170
+ const time = process.hrtime();
94
171
  await writeFile(
95
- this.options.outputPath,
172
+ join(this.options.outputPath, this.options.tilesetName),
96
173
  JSON.stringify({
97
174
  options: this.options,
98
- tilesConverted: this.tilesConverted
175
+ tilesConverted: this.tilesConverted,
176
+ textureSetDefinitions: this.textureSetDefinitions,
177
+ attributeMetadataInfo: this.attributeMetadataInfo,
178
+ materialDefinitions: this.materialDefinitions
99
179
  }),
100
- `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
180
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}.${time[0]}.${time[1]}`
181
+ );
182
+ await renameFile(
183
+ join(
184
+ this.options.outputPath,
185
+ this.options.tilesetName,
186
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}.${time[0]}.${time[1]}`
187
+ ),
188
+ join(
189
+ this.options.outputPath,
190
+ this.options.tilesetName,
191
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
192
+ )
101
193
  );
102
194
  } catch (error) {
103
195
  console.log("Can't update dump file", error);
@@ -109,9 +201,23 @@ export class ConversionDump {
109
201
  * Delete a dump file
110
202
  */
111
203
  async deleteDumpFile(): Promise<void> {
112
- if (this.options?.outputPath && this.options.tilesetName) {
204
+ if (
205
+ this.options?.outputPath &&
206
+ this.options.tilesetName &&
207
+ (await isFileExists(
208
+ join(
209
+ this.options.outputPath,
210
+ this.options.tilesetName,
211
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
212
+ )
213
+ ))
214
+ ) {
113
215
  await removeFile(
114
- join(this.options.outputPath, `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`)
216
+ join(
217
+ this.options.outputPath,
218
+ this.options.tilesetName,
219
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
220
+ )
115
221
  );
116
222
  }
117
223
  }
@@ -139,15 +245,31 @@ export class ConversionDump {
139
245
  * @param fileName - source filename
140
246
  * @param nodeId - nodeId of the node
141
247
  */
142
- async addNode(filename: string, nodeId: number) {
248
+ async addNode(filename: string, nodeId: number | string, dumpMetadata?: DumpMetadata) {
143
249
  const {nodes} = this.getRecord(filename) || {nodes: []};
144
- nodes.push({nodeId, done: false, progress: {}});
250
+ nodes.push({nodeId, done: false, dumpMetadata});
145
251
  if (nodes.length === 1) {
146
252
  this.setRecord(filename, {nodes});
147
253
  }
148
254
  await this.updateDumpFile();
149
255
  }
150
256
 
257
+ /**
258
+ * Clear dump record got the source filename
259
+ * @param fileName - source filename
260
+ */
261
+ clearDumpRecord(filename: string) {
262
+ this.setRecord(filename, {nodes: []});
263
+ }
264
+
265
+ /**
266
+ * Add textures definitions into the dump file
267
+ * @param textureDefinitions - textures definitions array
268
+ */
269
+ addTexturesDefinitions(textureDefinitions: TextureSetDefinition[]) {
270
+ this.textureSetDefinitions = textureDefinitions;
271
+ }
272
+
151
273
  /**
152
274
  * Update done status object for the writing resources
153
275
  * @param fileName - key - source filename
@@ -155,11 +277,19 @@ export class ConversionDump {
155
277
  * @param resourceType - resource type to update status
156
278
  * @param value - value
157
279
  */
158
- updateDoneStatus(filename: string, nodeId: number, resourceType: string, value: boolean) {
280
+ updateDoneStatus(
281
+ filename: string,
282
+ nodeId: number | string,
283
+ resourceType: string,
284
+ value: boolean
285
+ ) {
159
286
  const nodeDump = this.tilesConverted[filename]?.nodes.find(
160
287
  (element) => element.nodeId === nodeId
161
288
  );
162
289
  if (nodeDump) {
290
+ if (!nodeDump.progress) {
291
+ nodeDump.progress = {};
292
+ }
163
293
  nodeDump.progress[resourceType] = value;
164
294
  if (!value) {
165
295
  nodeDump.done = false;
@@ -173,7 +303,7 @@ export class ConversionDump {
173
303
  * @param writeResults - array of writing resource files results
174
304
  */
175
305
  async updateConvertedTilesDump(
176
- changedRecords: {outputId?: number; sourceId?: string; resourceType?: string}[],
306
+ changedRecords: {outputId?: number | string; sourceId?: string; resourceType?: string}[],
177
307
  writeResults: PromiseSettledResult<string | null>[]
178
308
  ) {
179
309
  for (let i = 0; i < changedRecords.length; i++) {
@@ -181,7 +311,7 @@ export class ConversionDump {
181
311
  const {sourceId, resourceType, outputId} = changedRecords[i];
182
312
  if (!sourceId || !resourceType || !outputId) continue;
183
313
  for (const node of this.tilesConverted[sourceId].nodes) {
184
- if (node.nodeId === outputId) {
314
+ if (node.nodeId === outputId && node.progress) {
185
315
  node.progress[resourceType] = true;
186
316
 
187
317
  let done = false;
@@ -191,7 +321,7 @@ export class ConversionDump {
191
321
  }
192
322
  node.done = done;
193
323
  if (node.done) {
194
- node.progress = {};
324
+ delete node.progress;
195
325
  }
196
326
  break;
197
327
  }
@@ -200,4 +330,48 @@ export class ConversionDump {
200
330
  }
201
331
  await this.updateDumpFile();
202
332
  }
333
+
334
+ /**
335
+ * Update 3d-tiles-converter dump file
336
+ * @param filename - source filename
337
+ * @param nodeId - nodeId
338
+ * @param done - conversion status
339
+ */
340
+ async updateConvertedNodesDumpFile(
341
+ filename: string,
342
+ nodeId: number | string,
343
+ done: boolean
344
+ ): Promise<void> {
345
+ const nodeDump = this.tilesConverted[filename]?.nodes.find(
346
+ (element) => element.nodeId === nodeId
347
+ );
348
+ if (nodeDump) {
349
+ nodeDump.done = done;
350
+ await this.updateDumpFile();
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Check is source file conversion complete
356
+ * @param filename - source filename
357
+ * @returns true if source file conversion complete
358
+ */
359
+ isFileConversionComplete(filename: string): boolean {
360
+ let result = true;
361
+ for (const node of this.tilesConverted[filename]?.nodes || []) {
362
+ if (!node.done) {
363
+ result = false;
364
+ break;
365
+ }
366
+ }
367
+ return result && this.tilesConverted[filename]?.nodes?.length > 0;
368
+ }
369
+
370
+ /**
371
+ * Set materialDefinitions into a dump
372
+ * @param materialDefinitions - Array materialDefinitions
373
+ */
374
+ setMaterialsDefinitions(materialDefinitions: I3SMaterialDefinition[]): void {
375
+ this.materialDefinitions = materialDefinitions;
376
+ }
203
377
  }
@@ -138,3 +138,16 @@ export function removeFile(path: string) {
138
138
  export function getAbsoluteFilePath(filePath: string) {
139
139
  return isAbsolute(filePath) ? filePath : join(process.cwd(), filePath);
140
140
  }
141
+
142
+ /**
143
+ * Rename file with old path by new path
144
+ * @param oldPath
145
+ * @param newPath
146
+ */
147
+ export async function renameFile(oldPath: string, newPath: string): Promise<void> {
148
+ try {
149
+ await fs.rename(oldPath, newPath);
150
+ } catch (err) {
151
+ console.log("Can't rename file", err);
152
+ }
153
+ }