@loaders.gl/tile-converter 4.2.0-alpha.4 → 4.2.0-alpha.5

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 (144) hide show
  1. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +3 -3
  2. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  3. package/dist/3d-tiles-converter/3d-tiles-converter.js +329 -293
  4. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +257 -200
  5. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +14 -5
  6. package/dist/3d-tiles-converter/helpers/load-i3s.js +106 -75
  7. package/dist/3d-tiles-converter/helpers/texture-atlas.js +44 -21
  8. package/dist/3d-tiles-converter/json-templates/tileset.js +32 -33
  9. package/dist/constants.js +0 -1
  10. package/dist/converter-cli.js +255 -234
  11. package/dist/converter.min.cjs +80 -90
  12. package/dist/deps-installer/deps-installer.js +72 -58
  13. package/dist/i3s-converter/helpers/attribute-metadata-info.js +207 -153
  14. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +1 -1
  15. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
  16. package/dist/i3s-converter/helpers/batch-ids-extensions.js +145 -103
  17. package/dist/i3s-converter/helpers/coordinate-converter.js +100 -65
  18. package/dist/i3s-converter/helpers/create-scene-server-path.js +14 -9
  19. package/dist/i3s-converter/helpers/feature-attributes.js +168 -105
  20. package/dist/i3s-converter/helpers/geometry-attributes.d.ts +1 -1
  21. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
  22. package/dist/i3s-converter/helpers/geometry-attributes.js +204 -212
  23. package/dist/i3s-converter/helpers/geometry-converter.d.ts +2 -2
  24. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  25. package/dist/i3s-converter/helpers/geometry-converter.js +1148 -829
  26. package/dist/i3s-converter/helpers/gltf-attributes.d.ts +1 -1
  27. package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
  28. package/dist/i3s-converter/helpers/gltf-attributes.js +111 -97
  29. package/dist/i3s-converter/helpers/load-3d-tiles.js +103 -66
  30. package/dist/i3s-converter/helpers/node-debug.js +98 -54
  31. package/dist/i3s-converter/helpers/node-index-document.d.ts +3 -3
  32. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
  33. package/dist/i3s-converter/helpers/node-index-document.js +248 -177
  34. package/dist/i3s-converter/helpers/node-pages.d.ts +1 -1
  35. package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
  36. package/dist/i3s-converter/helpers/node-pages.js +299 -194
  37. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts +1 -1
  38. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts.map +1 -1
  39. package/dist/i3s-converter/helpers/preprocess-3d-tiles.js +92 -60
  40. package/dist/i3s-converter/helpers/progress.js +134 -83
  41. package/dist/i3s-converter/helpers/tileset-traversal.d.ts +1 -1
  42. package/dist/i3s-converter/helpers/tileset-traversal.d.ts.map +1 -1
  43. package/dist/i3s-converter/helpers/tileset-traversal.js +24 -13
  44. package/dist/i3s-converter/i3s-converter.d.ts +7 -7
  45. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  46. package/dist/i3s-converter/i3s-converter.js +1044 -898
  47. package/dist/i3s-converter/json-templates/geometry-definitions.js +70 -79
  48. package/dist/i3s-converter/json-templates/layers.js +120 -121
  49. package/dist/i3s-converter/json-templates/metadata.js +19 -20
  50. package/dist/i3s-converter/json-templates/node.js +73 -71
  51. package/dist/i3s-converter/json-templates/scene-server.js +25 -26
  52. package/dist/i3s-converter/json-templates/shared-resources.js +107 -108
  53. package/dist/i3s-converter/json-templates/store.js +96 -94
  54. package/dist/i3s-converter/types.js +35 -23
  55. package/dist/i3s-server/app.js +15 -12
  56. package/dist/i3s-server/bin/www.js +14 -7
  57. package/dist/i3s-server/controllers/index-controller.js +18 -15
  58. package/dist/i3s-server/controllers/slpk-controller.js +22 -11
  59. package/dist/i3s-server/routes/index.js +9 -8
  60. package/dist/i3s-server/routes/slpk-router.js +18 -17
  61. package/dist/i3s-server/utils/create-scene-server.js +15 -10
  62. package/dist/i3s-server/utils/server-utils.js +49 -32
  63. package/dist/index.cjs +292 -851
  64. package/dist/index.cjs.map +7 -0
  65. package/dist/index.d.ts +2 -2
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +0 -1
  68. package/dist/lib/json-schemas/conversion-dump-json-schema.js +243 -421
  69. package/dist/lib/utils/cli-utils.js +63 -36
  70. package/dist/lib/utils/compress-util.js +20 -15
  71. package/dist/lib/utils/conversion-dump.d.ts +1 -1
  72. package/dist/lib/utils/conversion-dump.d.ts.map +1 -1
  73. package/dist/lib/utils/conversion-dump.js +209 -187
  74. package/dist/lib/utils/file-utils.js +122 -74
  75. package/dist/lib/utils/geometry-utils.js +13 -7
  76. package/dist/lib/utils/lod-conversion-utils.js +65 -33
  77. package/dist/lib/utils/queue.js +12 -13
  78. package/dist/lib/utils/statistic-utills.d.ts +6 -23
  79. package/dist/lib/utils/statistic-utills.js +64 -59
  80. package/dist/lib/utils/write-queue.d.ts +2 -2
  81. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  82. package/dist/lib/utils/write-queue.js +68 -86
  83. package/dist/pgm-loader.js +16 -12
  84. package/dist/slpk-extractor/slpk-extractor.js +59 -50
  85. package/dist/slpk-extractor-cli.js +82 -59
  86. package/package.json +18 -18
  87. package/dist/3d-tiles-converter/3d-tiles-converter.js.map +0 -1
  88. package/dist/3d-tiles-converter/helpers/b3dm-converter.js.map +0 -1
  89. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js.map +0 -1
  90. package/dist/3d-tiles-converter/helpers/load-i3s.js.map +0 -1
  91. package/dist/3d-tiles-converter/helpers/texture-atlas.js.map +0 -1
  92. package/dist/3d-tiles-converter/json-templates/tileset.js.map +0 -1
  93. package/dist/constants.js.map +0 -1
  94. package/dist/converter-cli.js.map +0 -1
  95. package/dist/deps-installer/deps-installer.js.map +0 -1
  96. package/dist/i3s-converter/helpers/attribute-metadata-info.js.map +0 -1
  97. package/dist/i3s-converter/helpers/batch-ids-extensions.js.map +0 -1
  98. package/dist/i3s-converter/helpers/coordinate-converter.js.map +0 -1
  99. package/dist/i3s-converter/helpers/create-scene-server-path.js.map +0 -1
  100. package/dist/i3s-converter/helpers/feature-attributes.js.map +0 -1
  101. package/dist/i3s-converter/helpers/geometry-attributes.js.map +0 -1
  102. package/dist/i3s-converter/helpers/geometry-converter.js.map +0 -1
  103. package/dist/i3s-converter/helpers/gltf-attributes.js.map +0 -1
  104. package/dist/i3s-converter/helpers/load-3d-tiles.js.map +0 -1
  105. package/dist/i3s-converter/helpers/node-debug.js.map +0 -1
  106. package/dist/i3s-converter/helpers/node-index-document.js.map +0 -1
  107. package/dist/i3s-converter/helpers/node-pages.js.map +0 -1
  108. package/dist/i3s-converter/helpers/preprocess-3d-tiles.js.map +0 -1
  109. package/dist/i3s-converter/helpers/progress.js.map +0 -1
  110. package/dist/i3s-converter/helpers/tileset-traversal.js.map +0 -1
  111. package/dist/i3s-converter/i3s-converter.js.map +0 -1
  112. package/dist/i3s-converter/json-templates/geometry-definitions.js.map +0 -1
  113. package/dist/i3s-converter/json-templates/layers.js.map +0 -1
  114. package/dist/i3s-converter/json-templates/metadata.js.map +0 -1
  115. package/dist/i3s-converter/json-templates/node.js.map +0 -1
  116. package/dist/i3s-converter/json-templates/scene-server.js.map +0 -1
  117. package/dist/i3s-converter/json-templates/shared-resources.js.map +0 -1
  118. package/dist/i3s-converter/json-templates/store.js.map +0 -1
  119. package/dist/i3s-converter/types.js.map +0 -1
  120. package/dist/i3s-server/README.md +0 -63
  121. package/dist/i3s-server/app.js.map +0 -1
  122. package/dist/i3s-server/bin/www.js.map +0 -1
  123. package/dist/i3s-server/certs/cert.pem +0 -19
  124. package/dist/i3s-server/certs/key.pem +0 -27
  125. package/dist/i3s-server/controllers/index-controller.js.map +0 -1
  126. package/dist/i3s-server/controllers/slpk-controller.js.map +0 -1
  127. package/dist/i3s-server/routes/index.js.map +0 -1
  128. package/dist/i3s-server/routes/slpk-router.js.map +0 -1
  129. package/dist/i3s-server/utils/create-scene-server.js.map +0 -1
  130. package/dist/i3s-server/utils/server-utils.js.map +0 -1
  131. package/dist/index.js.map +0 -1
  132. package/dist/lib/json-schemas/conversion-dump-json-schema.js.map +0 -1
  133. package/dist/lib/utils/cli-utils.js.map +0 -1
  134. package/dist/lib/utils/compress-util.js.map +0 -1
  135. package/dist/lib/utils/conversion-dump.js.map +0 -1
  136. package/dist/lib/utils/file-utils.js.map +0 -1
  137. package/dist/lib/utils/geometry-utils.js.map +0 -1
  138. package/dist/lib/utils/lod-conversion-utils.js.map +0 -1
  139. package/dist/lib/utils/queue.js.map +0 -1
  140. package/dist/lib/utils/statistic-utills.js.map +0 -1
  141. package/dist/lib/utils/write-queue.js.map +0 -1
  142. package/dist/pgm-loader.js.map +0 -1
  143. package/dist/slpk-extractor/slpk-extractor.js.map +0 -1
  144. package/dist/slpk-extractor-cli.js.map +0 -1
@@ -2,204 +2,309 @@ import { join } from 'path';
2
2
  import transform from 'json-map-transform';
3
3
  import { METADATA as metadataTemplate } from "../json-templates/metadata.js";
4
4
  import { isFileExists, openJson } from "../../lib/utils/file-utils.js";
5
- export default class NodePages {
6
- constructor(writeFileFunc, nodesPerPage, converter) {
7
- this.nodesPerPage = void 0;
8
- this.nodesCounter = void 0;
9
- this.writeFile = void 0;
10
- this.converter = void 0;
11
- this.nodePages = void 0;
12
- this.length = 0;
13
- this.nodesPerPage = nodesPerPage;
14
- this.nodesCounter = 0;
15
- this.nodePages = [{}];
16
- this.nodePages[0].nodes = [];
17
- this.writeFile = writeFileFunc;
18
- this.converter = converter;
19
- this.length = 0;
20
- }
21
- useWriteFunction(func) {
22
- this.writeFile = func;
23
- }
24
- getNodePageFileName(nodePageId) {
25
- let filePath;
26
- let fileName;
27
- if (this.converter.options.slpk) {
28
- filePath = join(this.converter.layers0Path, 'nodepages');
29
- fileName = `${nodePageId.toString()}.json`;
30
- } else {
31
- filePath = join(this.converter.layers0Path, 'nodepages', nodePageId.toString());
32
- fileName = 'index.json';
33
- }
34
- return {
35
- filePath,
36
- fileName
37
- };
38
- }
39
- async loadNodePage(nodePageId) {
40
- const {
41
- filePath,
42
- fileName
43
- } = this.getNodePageFileName(nodePageId);
44
- const fullName = join(filePath, fileName);
45
- if (await isFileExists(fullName)) {
46
- console.log(`load ${fullName}.`);
47
- return await openJson(filePath, fileName);
48
- } else {
49
- return {
50
- nodes: []
51
- };
52
- }
53
- }
54
- getPageIndexByNodeId(id) {
55
- return Math.floor(id / this.nodesPerPage);
56
- }
57
- async getPageByNodeId(id) {
58
- const pageIndex = this.getPageIndexByNodeId(id);
59
- if (this.converter.options.instantNodeWriting) {
60
- return await this.loadNodePage(pageIndex);
61
- }
62
- return this.nodePages[pageIndex];
63
- }
64
- async getNodeById(id, nodePage) {
65
- const nodeIndex = id % this.nodesPerPage;
66
- nodePage = nodePage || (await this.getPageByNodeId(id));
67
- return nodePage.nodes[nodeIndex];
68
- }
69
- async addChildRelation(parentId, childId) {
70
- var _parentNode$children;
71
- if (parentId === null || parentId === undefined) {
72
- return;
73
- }
74
- const parentNode = await this.getNodeById(parentId);
75
- (_parentNode$children = parentNode.children) === null || _parentNode$children === void 0 ? void 0 : _parentNode$children.push(childId);
76
- await this.saveNode(parentNode);
77
- }
78
- async push(node, parentId) {
79
- node.index = this.nodesCounter++;
80
- if (!this.converter.options.instantNodeWriting) {
81
- let currentNodePage = this.nodePages[this.nodePages.length - 1];
82
- if (currentNodePage.nodes.length === this.nodesPerPage) {
83
- currentNodePage = {
84
- nodes: []
85
- };
86
- this.nodePages.push(currentNodePage);
87
- }
88
- currentNodePage.nodes.push(node);
89
- }
90
- await this.addChildRelation(parentId, node.index);
91
- NodePages.updateResourceInMesh(node);
92
- await this.saveNode(node);
93
- return node;
94
- }
95
- async saveNode(node) {
96
- if (!this.converter.options.instantNodeWriting) {
97
- return;
98
- } else {
99
- const nodePageIndex = this.getPageIndexByNodeId(node.index);
100
- const nodePage = await this.getPageByNodeId(node.index);
101
- const {
102
- filePath,
103
- fileName
104
- } = this.getNodePageFileName(nodePageIndex);
105
- const nodeToUpdate = await this.getNodeById(node.index, nodePage);
106
- if (nodeToUpdate) {
107
- NodePages.updateAll(nodeToUpdate, node);
108
- } else {
109
- nodePage.nodes.push(node);
110
- }
111
- const nodePageStr = JSON.stringify(nodePage);
112
- if (this.converter.options.slpk) {
113
- await this.converter.writeQueue.enqueue({
114
- archiveKey: `nodePages/${nodePageIndex.toString()}.json.gz`,
115
- writePromise: () => this.writeFile(filePath, nodePageStr, fileName, true, this.converter.compressList)
116
- }, true);
117
- } else {
118
- await this.converter.writeQueue.enqueue({
119
- writePromise: () => this.writeFile(filePath, nodePageStr)
120
- }, true);
121
- }
122
- }
123
- }
124
- async saveMetadata() {
125
- const metadata = transform({
126
- nodeCount: this.nodesCounter
127
- }, metadataTemplate());
128
- const compress = false;
129
- await this.converter.writeQueue.enqueue({
130
- archiveKey: 'metadata.json',
131
- writePromise: () => this.writeFile(this.converter.layers0Path, JSON.stringify(metadata), 'metadata.json', compress)
5
+ /**
6
+ * class NodePages - wrapper of nodePages array
7
+ *
8
+ * @example
9
+ * import {writeFile} from './helpers/write-file';
10
+ *
11
+ * // create an instance of the class
12
+ * const nodePages = new NodePages(writeFile, HARDCODED_NODES_PER_PAGE);
13
+ * ...
14
+ * // push root node
15
+ * const parent = await nodePages.push({
16
+ lodThreshold: HARDCODED_MAX_SCREEN_THRESHOLD_SQ,
17
+ obb: coordinates.obb,
18
+ children: []
132
19
  });
133
- }
134
- async save() {
135
- if (this.converter.options.instantNodeWriting) {
136
- await this.saveMetadata();
137
- return;
138
- }
139
- if (this.converter.options.slpk) {
140
- for (const [index, nodePage] of this.nodePages.entries()) {
141
- const nodePageStr = JSON.stringify(nodePage);
142
- const slpkPath = join(this.converter.layers0Path, 'nodepages');
143
- await this.converter.writeQueue.enqueue({
144
- archiveKey: `nodePages/${index.toString()}.json.gz`,
145
- writePromise: () => this.writeFile(slpkPath, nodePageStr, `${index.toString()}.json`)
146
- });
20
+ * ...
21
+ * // push node with parent relation
22
+ * const nodeInPage = {
23
+ lodThreshold: HARDCODED_MAX_SCREEN_THRESHOLD_SQ,
24
+ obb: coordinates.obb,
25
+ children: [],
26
+ mesh: {
27
+ geometry: {
28
+ definition: 0
29
+ }
147
30
  }
148
- await this.saveMetadata();
149
- } else {
150
- for (const [index, nodePage] of this.nodePages.entries()) {
151
- const nodePageStr = JSON.stringify(nodePage);
152
- const nodePagePath = join(this.converter.layers0Path, 'nodepages', index.toString());
31
+ };
32
+ * const node = await this.nodePages.push(nodeInPage, parent.index);
33
+ * ...
34
+ * // save all the nodePages in the end of pushing all the nodes
35
+ * await this.nodePages.save(layers0path);
36
+ */
37
+ export default class NodePages {
38
+ /**
39
+ * @constructs
40
+ * Create a nodePages instance.
41
+ * @param writeFileFunc - function to save one nodePage into a file
42
+ * @param nodesPerPage - length limit for one nodePage. An additional nodePage is created when this limit is met
43
+ */
44
+ constructor(writeFileFunc, nodesPerPage, converter) {
45
+ this.length = 0;
46
+ this.nodesPerPage = nodesPerPage;
47
+ this.nodesCounter = 0;
48
+ // @ts-expect-error
49
+ this.nodePages = [{}];
50
+ this.nodePages[0].nodes = [];
51
+ this.writeFile = writeFileFunc;
52
+ this.converter = converter;
53
+ this.length = 0;
54
+ }
55
+ /**
56
+ * Setup function to save node pages
57
+ * @param func - function which should be used to save node pages
58
+ */
59
+ useWriteFunction(func) {
60
+ this.writeFile = func;
61
+ }
62
+ /**
63
+ * Get file path and file name of the node page with the particular id
64
+ * @param nodePageId - node page id
65
+ * @returns file path and file name
66
+ */
67
+ getNodePageFileName(nodePageId) {
68
+ let filePath;
69
+ let fileName;
70
+ if (this.converter.options.slpk) {
71
+ filePath = join(this.converter.layers0Path, 'nodepages');
72
+ fileName = `${nodePageId.toString()}.json`;
73
+ }
74
+ else {
75
+ filePath = join(this.converter.layers0Path, 'nodepages', nodePageId.toString());
76
+ fileName = 'index.json';
77
+ }
78
+ return { filePath, fileName };
79
+ }
80
+ /**
81
+ * Load node page from a file on the disk
82
+ * @param nodePageId - node page id
83
+ * @returns - node page data
84
+ */
85
+ async loadNodePage(nodePageId) {
86
+ const { filePath, fileName } = this.getNodePageFileName(nodePageId);
87
+ const fullName = join(filePath, fileName);
88
+ if (await isFileExists(fullName)) {
89
+ console.log(`load ${fullName}.`); // eslint-disable-line
90
+ return (await openJson(filePath, fileName));
91
+ }
92
+ else {
93
+ return { nodes: [] };
94
+ }
95
+ }
96
+ /**
97
+ * Get nodepage id by node id
98
+ * @param id node id
99
+ * @returns node page id
100
+ */
101
+ getPageIndexByNodeId(id) {
102
+ return Math.floor(id / this.nodesPerPage);
103
+ }
104
+ /**
105
+ * Get node page data by node id
106
+ * @param id node id
107
+ * @returns node page data
108
+ */
109
+ async getPageByNodeId(id) {
110
+ const pageIndex = this.getPageIndexByNodeId(id);
111
+ if (this.converter.options.instantNodeWriting) {
112
+ return await this.loadNodePage(pageIndex);
113
+ }
114
+ return this.nodePages[pageIndex];
115
+ }
116
+ /**
117
+ * Get the node by its end-to-end index
118
+ * @param id - end-to-end index of the node
119
+ * @return the node object
120
+ */
121
+ async getNodeById(id, nodePage) {
122
+ const nodeIndex = id % this.nodesPerPage;
123
+ nodePage = nodePage || (await this.getPageByNodeId(id));
124
+ return nodePage.nodes[nodeIndex];
125
+ }
126
+ /**
127
+ * Add a child id into the parent node.children array
128
+ * @param parentId - end-to-end parent node index
129
+ * @param childId - end-to-end child node index
130
+ */
131
+ async addChildRelation(parentId, childId) {
132
+ if (parentId === null || parentId === undefined) {
133
+ return;
134
+ }
135
+ const parentNode = await this.getNodeById(parentId);
136
+ parentNode.children?.push(childId);
137
+ await this.saveNode(parentNode);
138
+ }
139
+ /**
140
+ * Put new node in nodePages array
141
+ * @param node - node object
142
+ * @param parentId - index of parent node
143
+ * @return
144
+ */
145
+ async push(node, parentId) {
146
+ node.index = this.nodesCounter++;
147
+ if (!this.converter.options.instantNodeWriting) {
148
+ let currentNodePage = this.nodePages[this.nodePages.length - 1];
149
+ if (currentNodePage.nodes.length === this.nodesPerPage) {
150
+ currentNodePage = { nodes: [] };
151
+ this.nodePages.push(currentNodePage);
152
+ }
153
+ currentNodePage.nodes.push(node);
154
+ }
155
+ await this.addChildRelation(parentId, node.index);
156
+ NodePages.updateResourceInMesh(node);
157
+ await this.saveNode(node);
158
+ return node;
159
+ }
160
+ /**
161
+ * Save node to the file on the disk
162
+ * @param node - node data
163
+ */
164
+ async saveNode(node) {
165
+ if (!this.converter.options.instantNodeWriting) {
166
+ return;
167
+ }
168
+ else {
169
+ const nodePageIndex = this.getPageIndexByNodeId(node.index);
170
+ const nodePage = await this.getPageByNodeId(node.index);
171
+ const { filePath, fileName } = this.getNodePageFileName(nodePageIndex);
172
+ const nodeToUpdate = await this.getNodeById(node.index, nodePage);
173
+ if (nodeToUpdate) {
174
+ NodePages.updateAll(nodeToUpdate, node);
175
+ }
176
+ else {
177
+ nodePage.nodes.push(node);
178
+ }
179
+ const nodePageStr = JSON.stringify(nodePage);
180
+ if (this.converter.options.slpk) {
181
+ await this.converter.writeQueue.enqueue({
182
+ archiveKey: `nodePages/${nodePageIndex.toString()}.json.gz`,
183
+ writePromise: () => this.writeFile(filePath, nodePageStr, fileName, true, this.converter.compressList)
184
+ }, true);
185
+ }
186
+ else {
187
+ await this.converter.writeQueue.enqueue({
188
+ writePromise: () => this.writeFile(filePath, nodePageStr)
189
+ }, true);
190
+ }
191
+ }
192
+ }
193
+ /**
194
+ * Save metadata file (for slpk only)
195
+ */
196
+ async saveMetadata() {
197
+ const metadata = transform({ nodeCount: this.nodesCounter }, metadataTemplate());
198
+ const compress = false;
153
199
  await this.converter.writeQueue.enqueue({
154
- writePromise: () => this.writeFile(nodePagePath, nodePageStr)
200
+ archiveKey: 'metadata.json',
201
+ writePromise: () => this.writeFile(this.converter.layers0Path, JSON.stringify(metadata), 'metadata.json', compress)
155
202
  });
156
- }
157
203
  }
158
- }
159
- static updateResourceInMesh(node) {
160
- if (node.mesh && isFinite(node.index)) {
161
- node.mesh.geometry.resource = node.index;
204
+ /**
205
+ * Save all the node pages
206
+ * Run this method when all nodes is pushed in nodePages
207
+ */
208
+ async save() {
209
+ if (this.converter.options.instantNodeWriting) {
210
+ await this.saveMetadata();
211
+ return;
212
+ }
213
+ if (this.converter.options.slpk) {
214
+ for (const [index, nodePage] of this.nodePages.entries()) {
215
+ const nodePageStr = JSON.stringify(nodePage);
216
+ const slpkPath = join(this.converter.layers0Path, 'nodepages');
217
+ await this.converter.writeQueue.enqueue({
218
+ archiveKey: `nodePages/${index.toString()}.json.gz`,
219
+ writePromise: () => this.writeFile(slpkPath, nodePageStr, `${index.toString()}.json`)
220
+ });
221
+ }
222
+ await this.saveMetadata();
223
+ }
224
+ else {
225
+ for (const [index, nodePage] of this.nodePages.entries()) {
226
+ const nodePageStr = JSON.stringify(nodePage);
227
+ const nodePagePath = join(this.converter.layers0Path, 'nodepages', index.toString());
228
+ await this.converter.writeQueue.enqueue({
229
+ writePromise: () => this.writeFile(nodePagePath, nodePageStr)
230
+ });
231
+ }
232
+ }
233
+ }
234
+ /**
235
+ * Update resource index in node.mesh object
236
+ * @param node - node object
237
+ */
238
+ static updateResourceInMesh(node) {
239
+ if (node.mesh && isFinite(node.index)) {
240
+ node.mesh.geometry.resource = node.index;
241
+ }
242
+ }
243
+ /**
244
+ * Update all fields in the node excluding id
245
+ * @param node - node object
246
+ * @param data - NodeInPage data to replace original data
247
+ */
248
+ static updateAll(node, data) {
249
+ Object.assign(node, data, { index: node.index });
250
+ NodePages.updateResourceInMesh(node);
251
+ return node;
252
+ }
253
+ /**
254
+ * Update material in node.mesh object by node id
255
+ * @param id - end-to-end index of the node
256
+ * @param materialId - id from scene layer materialDefinitions
257
+ */
258
+ static updateMaterialByNodeId(node, materialId) {
259
+ if (!node.mesh) {
260
+ return;
261
+ }
262
+ node.mesh.material = {
263
+ definition: materialId,
264
+ resource: node.index
265
+ };
266
+ }
267
+ /**
268
+ * Update vertexCount in node.mesh.geometry object by node id
269
+ * @param id - end-to-end index of the node
270
+ * @param vertexCount - vertex count for particular node
271
+ */
272
+ static updateVertexCountByNodeId(node, vertexCount) {
273
+ if (!node.mesh) {
274
+ return;
275
+ }
276
+ node.mesh.geometry.vertexCount = vertexCount;
277
+ }
278
+ /**
279
+ * Update resource in node.mesh.attribute object by node id
280
+ * @param node - node object
281
+ */
282
+ static updateNodeAttributeByNodeId(node) {
283
+ if (!node.mesh || !node.index) {
284
+ return;
285
+ }
286
+ node.mesh.attribute.resource = node.index;
287
+ }
288
+ /**
289
+ * Update featureCount in node.mesh.geometry object by node id
290
+ * @param node - node object
291
+ * @param featureCount - features count of the node
292
+ */
293
+ static updateFeatureCountByNodeId(node, featureCount) {
294
+ if (!node.mesh) {
295
+ return;
296
+ }
297
+ node.mesh.geometry.featureCount = featureCount;
298
+ }
299
+ /**
300
+ * Update texelCountHint in node.mesh.material object by node id
301
+ * @param node - node object
302
+ * @param texelCountHint - texelCountHint of particular node
303
+ */
304
+ static updateTexelCountHintByNodeId(node, texelCountHint) {
305
+ if (!node.mesh || !node.mesh.material) {
306
+ return;
307
+ }
308
+ node.mesh.material.texelCountHint = texelCountHint;
162
309
  }
163
- }
164
- static updateAll(node, data) {
165
- Object.assign(node, data, {
166
- index: node.index
167
- });
168
- NodePages.updateResourceInMesh(node);
169
- return node;
170
- }
171
- static updateMaterialByNodeId(node, materialId) {
172
- if (!node.mesh) {
173
- return;
174
- }
175
- node.mesh.material = {
176
- definition: materialId,
177
- resource: node.index
178
- };
179
- }
180
- static updateVertexCountByNodeId(node, vertexCount) {
181
- if (!node.mesh) {
182
- return;
183
- }
184
- node.mesh.geometry.vertexCount = vertexCount;
185
- }
186
- static updateNodeAttributeByNodeId(node) {
187
- if (!node.mesh || !node.index) {
188
- return;
189
- }
190
- node.mesh.attribute.resource = node.index;
191
- }
192
- static updateFeatureCountByNodeId(node, featureCount) {
193
- if (!node.mesh) {
194
- return;
195
- }
196
- node.mesh.geometry.featureCount = featureCount;
197
- }
198
- static updateTexelCountHintByNodeId(node, texelCountHint) {
199
- if (!node.mesh || !node.mesh.material) {
200
- return;
201
- }
202
- node.mesh.material.texelCountHint = texelCountHint;
203
- }
204
310
  }
205
- //# sourceMappingURL=node-pages.js.map
@@ -1,5 +1,5 @@
1
1
  import { Tiles3DTileContent } from '@loaders.gl/3d-tiles';
2
- import { GLTFPrimitiveModeString, PreprocessData } from '../types';
2
+ import { GLTFPrimitiveModeString, PreprocessData } from "../types.js";
3
3
  /**
4
4
  * glTF primitive modes
5
5
  * @see https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode
@@ -1 +1 @@
1
- {"version":3,"file":"preprocess-3d-tiles.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/preprocess-3d-tiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAC,uBAAuB,EAAE,cAAc,EAAC,MAAM,UAAU,CAAC;AAWjE;;;GAGG;AACH,eAAO,MAAM,oBAAoB,2BAQhC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,gBAChB,kBAAkB,GAAG,IAAI,KACrC,QAAQ,cAAc,CAuBxB,CAAC;AAwDF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,YAAa,cAAc,WAAW,cAAc,KAAG,IAUtF,CAAC"}
1
+ {"version":3,"file":"preprocess-3d-tiles.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/preprocess-3d-tiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAC,uBAAuB,EAAE,cAAc,EAAC,oBAAiB;AAWjE;;;GAGG;AACH,eAAO,MAAM,oBAAoB,2BAQhC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,gBAChB,kBAAkB,GAAG,IAAI,KACrC,QAAQ,cAAc,CAuBxB,CAAC;AAwDF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,YAAa,cAAc,WAAW,cAAc,KAAG,IAUtF,CAAC"}
@@ -2,72 +2,104 @@ import { GLTFPrimitiveModeString } from "../types.js";
2
2
  import { EXT_STRUCTURAL_METADATA, GLTFLoader } from '@loaders.gl/gltf';
3
3
  import { parse } from '@loaders.gl/core';
4
4
  import { EXT_FEATURE_METADATA } from '@loaders.gl/gltf';
5
- export const GLTF_PRIMITIVE_MODES = [GLTFPrimitiveModeString.POINTS, GLTFPrimitiveModeString.LINES, GLTFPrimitiveModeString.LINE_LOOP, GLTFPrimitiveModeString.LINE_STRIP, GLTFPrimitiveModeString.TRIANGLES, GLTFPrimitiveModeString.TRIANGLE_STRIP, GLTFPrimitiveModeString.TRIANGLE_FAN];
6
- export const analyzeTileContent = async tileContent => {
7
- const defaultResult = {
8
- meshTopologyTypes: new Set(),
9
- metadataClasses: new Set()
10
- };
11
- if (!(tileContent !== null && tileContent !== void 0 && tileContent.gltfArrayBuffer)) {
12
- return defaultResult;
13
- }
14
- const gltfData = await parse(tileContent.gltfArrayBuffer, GLTFLoader, {
15
- gltf: {
16
- normalize: false,
17
- loadBuffers: false,
18
- loadImages: false,
19
- decompressMeshes: false
5
+ /**
6
+ * glTF primitive modes
7
+ * @see https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode
8
+ */
9
+ export const GLTF_PRIMITIVE_MODES = [
10
+ GLTFPrimitiveModeString.POINTS, // 0
11
+ GLTFPrimitiveModeString.LINES, // 1
12
+ GLTFPrimitiveModeString.LINE_LOOP, // 2
13
+ GLTFPrimitiveModeString.LINE_STRIP, // 3
14
+ GLTFPrimitiveModeString.TRIANGLES, // 4
15
+ GLTFPrimitiveModeString.TRIANGLE_STRIP, // 5
16
+ GLTFPrimitiveModeString.TRIANGLE_FAN // 6
17
+ ];
18
+ /**
19
+ * Analyze tile content. This function is used during preprocess stage of
20
+ * conversion
21
+ * @param tileContent - 3DTiles tile content ArrayBuffer
22
+ * @returns
23
+ */
24
+ export const analyzeTileContent = async (tileContent) => {
25
+ const defaultResult = {
26
+ meshTopologyTypes: new Set(),
27
+ metadataClasses: new Set()
28
+ };
29
+ if (!tileContent?.gltfArrayBuffer) {
30
+ return defaultResult;
20
31
  }
21
- });
22
- const gltf = gltfData.json;
23
- if (!gltf) {
24
- return defaultResult;
25
- }
26
- const meshTopologyTypes = getMeshTypesFromGLTF(gltf);
27
- const metadataClasses = getMetadataClassesFromGLTF(gltf);
28
- return {
29
- meshTopologyTypes,
30
- metadataClasses
31
- };
32
+ const gltfData = await parse(tileContent.gltfArrayBuffer, GLTFLoader, {
33
+ gltf: { normalize: false, loadBuffers: false, loadImages: false, decompressMeshes: false }
34
+ });
35
+ const gltf = gltfData.json;
36
+ if (!gltf) {
37
+ return defaultResult;
38
+ }
39
+ const meshTopologyTypes = getMeshTypesFromGLTF(gltf);
40
+ const metadataClasses = getMetadataClassesFromGLTF(gltf);
41
+ return {
42
+ meshTopologyTypes,
43
+ metadataClasses
44
+ };
32
45
  };
33
- const getMeshTypesFromGLTF = gltfJson => {
34
- const result = new Set();
35
- for (const mesh of gltfJson.meshes || []) {
36
- for (const primitive of mesh.primitives) {
37
- let {
38
- mode
39
- } = primitive;
40
- if (typeof mode !== 'number') {
41
- mode = 4;
42
- }
43
- result.add(GLTF_PRIMITIVE_MODES[mode]);
46
+ /**
47
+ * Get mesh topology types that the glb content has
48
+ * @param gltfJson - JSON part of GLB content
49
+ * @returns array of mesh types found
50
+ */
51
+ const getMeshTypesFromGLTF = (gltfJson) => {
52
+ const result = new Set();
53
+ for (const mesh of gltfJson.meshes || []) {
54
+ for (const primitive of mesh.primitives) {
55
+ let { mode } = primitive;
56
+ if (typeof mode !== 'number') {
57
+ mode = 4; // Default is 4 - TRIANGLES
58
+ }
59
+ result.add(GLTF_PRIMITIVE_MODES[mode]);
60
+ }
44
61
  }
45
- }
46
- return result;
62
+ return result;
47
63
  };
48
- const getMetadataClassesFromGLTF = gltfJson => {
49
- var _gltfJson$extensions, _gltfJson$extensions$, _gltfJson$extensions$2, _gltfJson$extensions2, _gltfJson$extensions3, _gltfJson$extensions4;
50
- const result = new Set();
51
- const extFeatureMetadataClasses = (_gltfJson$extensions = gltfJson.extensions) === null || _gltfJson$extensions === void 0 ? void 0 : (_gltfJson$extensions$ = _gltfJson$extensions[EXT_FEATURE_METADATA]) === null || _gltfJson$extensions$ === void 0 ? void 0 : (_gltfJson$extensions$2 = _gltfJson$extensions$.schema) === null || _gltfJson$extensions$2 === void 0 ? void 0 : _gltfJson$extensions$2.classes;
52
- if (extFeatureMetadataClasses) {
53
- for (const classKey of Object.keys(extFeatureMetadataClasses)) {
54
- result.add(classKey);
64
+ /**
65
+ * Get feature metadata classes from glTF
66
+ * The tileset might contain multiple metadata classes provided by EXT_feature_metadata and EXT_structural_metadata extensions.
67
+ * Every class is a set of properties. But I3S can consume only one set of properties.
68
+ * On the pre-process we collect all classes from the tileset in order to show the prompt to select one class for conversion to I3S.
69
+ * @param gltfJson - JSON part of GLB content
70
+ * @returns array of classes
71
+ */
72
+ const getMetadataClassesFromGLTF = (gltfJson) => {
73
+ const result = new Set();
74
+ // Try to parse from EXT_feature_metadata
75
+ const extFeatureMetadataClasses = gltfJson.extensions?.[EXT_FEATURE_METADATA]?.schema?.classes;
76
+ if (extFeatureMetadataClasses) {
77
+ for (const classKey of Object.keys(extFeatureMetadataClasses)) {
78
+ result.add(classKey);
79
+ }
55
80
  }
56
- }
57
- const extStructuralMetadataClasses = (_gltfJson$extensions2 = gltfJson.extensions) === null || _gltfJson$extensions2 === void 0 ? void 0 : (_gltfJson$extensions3 = _gltfJson$extensions2[EXT_STRUCTURAL_METADATA]) === null || _gltfJson$extensions3 === void 0 ? void 0 : (_gltfJson$extensions4 = _gltfJson$extensions3.schema) === null || _gltfJson$extensions4 === void 0 ? void 0 : _gltfJson$extensions4.classes;
58
- if (extStructuralMetadataClasses) {
59
- for (const classKey of Object.keys(extStructuralMetadataClasses)) {
60
- result.add(classKey);
81
+ // Try to parse from EXT_structural_metadata
82
+ const extStructuralMetadataClasses = gltfJson.extensions?.[EXT_STRUCTURAL_METADATA]?.schema?.classes;
83
+ if (extStructuralMetadataClasses) {
84
+ for (const classKey of Object.keys(extStructuralMetadataClasses)) {
85
+ result.add(classKey);
86
+ }
61
87
  }
62
- }
63
- return result;
88
+ return result;
64
89
  };
90
+ /**
91
+ * Merge object2 into object1
92
+ * @param object1
93
+ * @param object2
94
+ * @returns nothing
95
+ */
65
96
  export const mergePreprocessData = (object1, object2) => {
66
- for (const type of object2.meshTopologyTypes) {
67
- object1.meshTopologyTypes.add(type);
68
- }
69
- for (const metadataClass of object2.metadataClasses) {
70
- object1.metadataClasses.add(metadataClass);
71
- }
97
+ // Merge topology mesh types info
98
+ for (const type of object2.meshTopologyTypes) {
99
+ object1.meshTopologyTypes.add(type);
100
+ }
101
+ // Merge feature metadata classes
102
+ for (const metadataClass of object2.metadataClasses) {
103
+ object1.metadataClasses.add(metadataClass);
104
+ }
72
105
  };
73
- //# sourceMappingURL=preprocess-3d-tiles.js.map