@loaders.gl/tile-converter 4.0.0-alpha.23 → 4.0.0-alpha.25

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 (118) hide show
  1. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +4 -4
  2. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts.map +1 -1
  3. package/dist/converter.min.js +105 -105
  4. package/dist/dist.min.js +725 -652
  5. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +18 -18
  6. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  7. package/dist/es5/3d-tiles-converter/helpers/load-i3s.js.map +1 -1
  8. package/dist/es5/deps-installer/deps-installer.js +1 -1
  9. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +16 -14
  10. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  11. package/dist/es5/i3s-converter/helpers/feature-attributes.js +6 -18
  12. package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -1
  13. package/dist/es5/i3s-converter/helpers/geometry-attributes.js +83 -44
  14. package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  15. package/dist/es5/i3s-converter/helpers/geometry-converter.js +13 -83
  16. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  17. package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js +15 -8
  18. package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
  19. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  20. package/dist/es5/i3s-converter/types.js.map +1 -1
  21. package/dist/es5/pgm-loader.js +11 -3
  22. package/dist/es5/pgm-loader.js.map +1 -1
  23. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +8 -8
  24. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  25. package/dist/esm/3d-tiles-converter/helpers/load-i3s.js.map +1 -1
  26. package/dist/esm/deps-installer/deps-installer.js +1 -1
  27. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +5 -15
  28. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  29. package/dist/esm/i3s-converter/helpers/feature-attributes.js +5 -5
  30. package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -1
  31. package/dist/esm/i3s-converter/helpers/geometry-attributes.js +76 -34
  32. package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  33. package/dist/esm/i3s-converter/helpers/geometry-converter.js +10 -80
  34. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  35. package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js +15 -9
  36. package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
  37. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  38. package/dist/esm/i3s-converter/types.js.map +1 -1
  39. package/dist/esm/i3s-server/bin/i3s-server.min.js +75 -75
  40. package/dist/esm/pgm-loader.js +7 -4
  41. package/dist/esm/pgm-loader.js.map +1 -1
  42. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +4 -1
  43. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
  44. package/dist/i3s-converter/helpers/feature-attributes.d.ts +6 -6
  45. package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -1
  46. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
  47. package/dist/i3s-converter/helpers/geometry-converter.d.ts +1 -1
  48. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  49. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts.map +1 -1
  50. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  51. package/dist/i3s-converter/types.d.ts +13 -5
  52. package/dist/i3s-converter/types.d.ts.map +1 -1
  53. package/dist/pgm-loader.d.ts +9 -2
  54. package/dist/pgm-loader.d.ts.map +1 -1
  55. package/dist/slpk-extractor.min.js +42 -42
  56. package/package.json +14 -14
  57. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +8 -8
  58. package/src/3d-tiles-converter/helpers/load-i3s.ts +1 -0
  59. package/src/i3s-converter/helpers/batch-ids-extensions.ts +14 -35
  60. package/src/i3s-converter/helpers/feature-attributes.ts +14 -11
  61. package/src/i3s-converter/helpers/geometry-attributes.ts +80 -50
  62. package/src/i3s-converter/helpers/geometry-converter.ts +41 -177
  63. package/src/i3s-converter/helpers/preprocess-3d-tiles.ts +30 -9
  64. package/src/i3s-converter/i3s-converter.ts +0 -2
  65. package/src/i3s-converter/types.ts +14 -5
  66. package/src/pgm-loader.ts +15 -7
  67. package/dist/3d-tiles-converter/3d-tiles-converter.js +0 -279
  68. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +0 -271
  69. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +0 -23
  70. package/dist/3d-tiles-converter/helpers/load-i3s.js +0 -42
  71. package/dist/3d-tiles-converter/helpers/texture-atlas.js +0 -54
  72. package/dist/3d-tiles-converter/json-templates/tileset.js +0 -43
  73. package/dist/bundle.js +0 -5
  74. package/dist/constants.js +0 -4
  75. package/dist/converter-cli.js +0 -222
  76. package/dist/deps-installer/deps-installer.js +0 -89
  77. package/dist/i3s-converter/helpers/batch-ids-extensions.js +0 -179
  78. package/dist/i3s-converter/helpers/coordinate-converter.js +0 -122
  79. package/dist/i3s-converter/helpers/create-scene-server-path.js +0 -28
  80. package/dist/i3s-converter/helpers/feature-attributes.js +0 -218
  81. package/dist/i3s-converter/helpers/geometry-attributes.js +0 -203
  82. package/dist/i3s-converter/helpers/geometry-converter.js +0 -1321
  83. package/dist/i3s-converter/helpers/gltf-attributes.js +0 -129
  84. package/dist/i3s-converter/helpers/load-3d-tiles.js +0 -99
  85. package/dist/i3s-converter/helpers/node-debug.js +0 -120
  86. package/dist/i3s-converter/helpers/node-index-document.js +0 -271
  87. package/dist/i3s-converter/helpers/node-pages.js +0 -316
  88. package/dist/i3s-converter/helpers/preprocess-3d-tiles.js +0 -100
  89. package/dist/i3s-converter/helpers/tileset-traversal.js +0 -29
  90. package/dist/i3s-converter/i3s-converter.js +0 -964
  91. package/dist/i3s-converter/json-templates/geometry-definitions.js +0 -87
  92. package/dist/i3s-converter/json-templates/layers.js +0 -139
  93. package/dist/i3s-converter/json-templates/metadata.js +0 -25
  94. package/dist/i3s-converter/json-templates/node.js +0 -89
  95. package/dist/i3s-converter/json-templates/scene-server.js +0 -31
  96. package/dist/i3s-converter/json-templates/shared-resources.js +0 -129
  97. package/dist/i3s-converter/json-templates/store.js +0 -103
  98. package/dist/i3s-converter/types.js +0 -17
  99. package/dist/i3s-server/app.js +0 -29
  100. package/dist/i3s-server/bin/www.js +0 -37
  101. package/dist/i3s-server/controllers/index-controller.js +0 -31
  102. package/dist/i3s-server/controllers/slpk-controller.js +0 -33
  103. package/dist/i3s-server/routes/index.js +0 -20
  104. package/dist/i3s-server/routes/slpk-router.js +0 -34
  105. package/dist/i3s-server/utils/create-scene-server.js +0 -22
  106. package/dist/i3s-server/utils/server-utils.js +0 -66
  107. package/dist/index.js +0 -10
  108. package/dist/lib/utils/cli-utils.js +0 -82
  109. package/dist/lib/utils/compress-util.js +0 -257
  110. package/dist/lib/utils/file-utils.js +0 -139
  111. package/dist/lib/utils/geometry-utils.js +0 -18
  112. package/dist/lib/utils/lod-conversion-utils.js +0 -76
  113. package/dist/lib/utils/queue.js +0 -18
  114. package/dist/lib/utils/statistic-utills.js +0 -64
  115. package/dist/lib/utils/write-queue.js +0 -80
  116. package/dist/pgm-loader.js +0 -24
  117. package/dist/slpk-extractor/slpk-extractor.js +0 -75
  118. package/dist/slpk-extractor-cli.js +0 -102
@@ -1,14 +1,13 @@
1
1
  import type {FeatureTableJson, Tiles3DTileContent} from '@loaders.gl/3d-tiles';
2
2
  import type {
3
- GLTF_EXT_mesh_features,
4
- GLTF_EXT_structural_metadata,
5
3
  GLTFAccessorPostprocessed,
6
4
  GLTFMaterialPostprocessed,
7
5
  GLTFNodePostprocessed,
8
6
  GLTFMeshPrimitivePostprocessed,
9
7
  GLTFMeshPostprocessed,
10
8
  GLTFTexturePostprocessed,
11
- GLTF_EXT_feature_metadata_GLTF
9
+ GLTF_EXT_feature_metadata_GLTF,
10
+ GLTF_EXT_structural_metadata_GLTF
12
11
  } from '@loaders.gl/gltf';
13
12
 
14
13
  import {Vector3, Matrix4, Vector4} from '@math.gl/core';
@@ -50,7 +49,12 @@ import type {GLTFAttributesData, TextureImageProperties, TypedArrayConstructor}
50
49
  import {generateSyntheticIndices} from '../../lib/utils/geometry-utils';
51
50
  import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
52
51
 
53
- import {EXT_MESH_FEATURES, EXT_FEATURE_METADATA, EXT_STRUCTURAL_METADATA} from '@loaders.gl/gltf';
52
+ import {
53
+ EXT_FEATURE_METADATA,
54
+ EXT_STRUCTURAL_METADATA,
55
+ getPropertyTableFromExtFeatureMetadata,
56
+ getPropertyTableFromExtStructuralMetadata
57
+ } from '@loaders.gl/gltf';
54
58
 
55
59
  // Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
56
60
  const DEFAULT_ROUGHNESS_FACTOR = 1;
@@ -244,12 +248,18 @@ async function _makeNodeResources({
244
248
  const {faceRange, featureIds, positions, normals, colors, uvRegions, texCoords, featureCount} =
245
249
  generateAttributes(convertedAttributes);
246
250
 
247
- if (tileContent.batchTableJson) {
248
- makeFeatureIdsUnique(
251
+ let featureIdsMap: Record<string, number> = {};
252
+ if (propertyTable) {
253
+ /**
254
+ * 3DTiles has featureIndices unique only for one tile.
255
+ * In I3S featureIds are unique layer-wide. We create featureIds from all feature properties.
256
+ * If 3DTiles features has equal set of properties they are considered as same feature in I3S.
257
+ */
258
+ featureIdsMap = makeFeatureIdsUnique(
249
259
  featureIds,
250
260
  convertedAttributes.featureIndices,
251
261
  featuresHashArray,
252
- tileContent.batchTableJson
262
+ propertyTable
253
263
  );
254
264
  }
255
265
 
@@ -291,6 +301,7 @@ async function _makeNodeResources({
291
301
  if (attributeStorageInfo && propertyTable) {
292
302
  attributes = convertPropertyTableToAttributeBuffers(
293
303
  featureIds,
304
+ featureIdsMap,
294
305
  propertyTable,
295
306
  attributeStorageInfo
296
307
  );
@@ -378,7 +389,7 @@ export async function convertAttributes(
378
389
  }
379
390
 
380
391
  /**
381
- * Gltf has hierarchical structure of nodes. This function converts nodes starting from those which are in gltf scene object.
392
+ * glTF has hierarchical structure of nodes. This function converts nodes starting from those which are in gltf scene object.
382
393
  * The goal is applying tranformation matrix for all children. Functions "convertNodes" and "convertNode" work together recursively.
383
394
  * @param nodes - gltf nodes array
384
395
  * @param images - gltf images array
@@ -1046,7 +1057,7 @@ function convertMaterial(sourceMaterial: GLTFMaterialPostprocessed): I3SMaterial
1046
1057
 
1047
1058
  /**
1048
1059
  * Converts from `alphaMode` material property from GLTF to I3S format
1049
- * @param gltfAlphaMode Gltf material `alphaMode` property
1060
+ * @param gltfAlphaMode glTF material `alphaMode` property
1050
1061
  * @returns I3SMaterialDefinition.alphaMode property
1051
1062
  */
1052
1063
  function convertAlphaMode(
@@ -1252,17 +1263,18 @@ function generateImageId(texture: GLTFTexturePostprocessed, nodeId: number) {
1252
1263
  * @param featureIndices
1253
1264
  * @param featuresHashArray
1254
1265
  * @param batchTable
1255
- * @returns {void}
1266
+ * @returns propertyTable indices to map featureIds
1256
1267
  */
1257
1268
  function makeFeatureIdsUnique(
1258
1269
  featureIds: number[],
1259
1270
  featureIndices: number[],
1260
1271
  featuresHashArray: string[],
1261
1272
  batchTable: {[key: string]: any}
1262
- ) {
1273
+ ): Record<string, number> {
1263
1274
  const replaceMap = getFeaturesReplaceMap(featureIds, batchTable, featuresHashArray);
1264
1275
  replaceIndicesByUnique(featureIndices, replaceMap);
1265
1276
  replaceIndicesByUnique(featureIds, replaceMap);
1277
+ return replaceMap;
1266
1278
  }
1267
1279
 
1268
1280
  /**
@@ -1276,8 +1288,8 @@ function getFeaturesReplaceMap(
1276
1288
  featureIds: any[],
1277
1289
  batchTable: object,
1278
1290
  featuresHashArray: any[]
1279
- ): Record<string, any> {
1280
- const featureMap: Record<string, any> = {};
1291
+ ): Record<string, number> {
1292
+ const featureMap: Record<string, number> = {};
1281
1293
 
1282
1294
  for (let index = 0; index < featureIds.length; index++) {
1283
1295
  const oldFeatureId = featureIds[index];
@@ -1329,7 +1341,7 @@ function getOrCreateUniqueFeatureId(
1329
1341
  * @param featureMap
1330
1342
  * @returns
1331
1343
  */
1332
- function replaceIndicesByUnique(indicesArray: any[], featureMap: Record<string, []>) {
1344
+ function replaceIndicesByUnique(indicesArray: number[], featureMap: Record<string, number>) {
1333
1345
  for (let index = 0; index < indicesArray.length; index++) {
1334
1346
  indicesArray[index] = featureMap[indicesArray[index]];
1335
1347
  }
@@ -1344,6 +1356,7 @@ function replaceIndicesByUnique(indicesArray: any[], featureMap: Record<string,
1344
1356
  */
1345
1357
  function convertPropertyTableToAttributeBuffers(
1346
1358
  featureIds: number[],
1359
+ featureIdsMap: Record<string, number>,
1347
1360
  propertyTable: FeatureTableJson,
1348
1361
  attributeStorageInfo: AttributeStorageInfo[]
1349
1362
  ): any[] {
@@ -1351,7 +1364,7 @@ function convertPropertyTableToAttributeBuffers(
1351
1364
 
1352
1365
  const needFlattenPropertyTable = checkPropertiesLength(featureIds, propertyTable);
1353
1366
  const properties = needFlattenPropertyTable
1354
- ? flattenPropertyTableByFeatureIds(featureIds, propertyTable)
1367
+ ? flattenPropertyTableByFeatureIds(featureIdsMap, propertyTable)
1355
1368
  : propertyTable;
1356
1369
 
1357
1370
  const propertyTableWithObjectIds = {
@@ -1597,7 +1610,7 @@ function generateFeatureIndexAttribute(
1597
1610
  * For example it can be batchTable for b3dm files or property table in gLTF extension.
1598
1611
  * @param tileContent - 3DTiles tile content
1599
1612
  * @param metadataClass - user selected feature metadata class name
1600
- * @return batch table from b3dm / feature properties from EXT_FEATURE_METADATA, EXT_MESH_FEATURES or EXT_STRUCTURAL_METADATA
1613
+ * @return batch table from b3dm / feature properties from EXT_FEATURE_METADATA or EXT_STRUCTURAL_METADATA.
1601
1614
  */
1602
1615
  export function getPropertyTable(
1603
1616
  tileContent: Tiles3DTileContent | null,
@@ -1607,7 +1620,7 @@ export function getPropertyTable(
1607
1620
  return null;
1608
1621
  }
1609
1622
  let propertyTable: FeatureTableJson | null;
1610
- const batchTableJson = tileContent?.batchTableJson;
1623
+ const batchTableJson = tileContent.batchTableJson;
1611
1624
 
1612
1625
  if (batchTableJson) {
1613
1626
  return batchTableJson;
@@ -1616,16 +1629,9 @@ export function getPropertyTable(
1616
1629
  const {extensionName, extension} = getPropertyTableExtension(tileContent);
1617
1630
 
1618
1631
  switch (extensionName) {
1619
- case EXT_MESH_FEATURES: {
1620
- propertyTable = getPropertyTableFromExtMeshFeatures(
1621
- extension as GLTF_EXT_mesh_features,
1622
- metadataClass
1623
- );
1624
- return propertyTable;
1625
- }
1626
1632
  case EXT_STRUCTURAL_METADATA: {
1627
1633
  propertyTable = getPropertyTableFromExtStructuralMetadata(
1628
- extension as GLTF_EXT_structural_metadata,
1634
+ extension as GLTF_EXT_structural_metadata_GLTF,
1629
1635
  metadataClass
1630
1636
  );
1631
1637
  return propertyTable;
@@ -1648,18 +1654,9 @@ export function getPropertyTable(
1648
1654
  */
1649
1655
  function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
1650
1656
  extensionName: null | string;
1651
- extension:
1652
- | string
1653
- | GLTF_EXT_feature_metadata_GLTF
1654
- | GLTF_EXT_structural_metadata
1655
- | GLTF_EXT_mesh_features
1656
- | null;
1657
+ extension: string | GLTF_EXT_feature_metadata_GLTF | GLTF_EXT_structural_metadata_GLTF | null;
1657
1658
  } {
1658
- const extensionsWithPropertyTables = [
1659
- EXT_FEATURE_METADATA,
1660
- EXT_STRUCTURAL_METADATA,
1661
- EXT_MESH_FEATURES
1662
- ];
1659
+ const extensionsWithPropertyTables = [EXT_FEATURE_METADATA, EXT_STRUCTURAL_METADATA];
1663
1660
  const extensionsUsed = tileContent?.gltf?.extensionsUsed;
1664
1661
 
1665
1662
  if (!extensionsUsed) {
@@ -1670,6 +1667,12 @@ function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
1670
1667
  for (const extensionItem of tileContent?.gltf?.extensionsUsed || []) {
1671
1668
  if (extensionsWithPropertyTables.includes(extensionItem)) {
1672
1669
  extensionName = extensionItem;
1670
+ /*
1671
+ It returns the first extension containing the property table.
1672
+ We assume that there can be only one extension containing the property table:
1673
+ either EXT_FEATURE_METADATA, which is a depricated extension,
1674
+ or EXT_STRUCTURAL_METADATA.
1675
+ */
1673
1676
  break;
1674
1677
  }
1675
1678
  }
@@ -1680,147 +1683,8 @@ function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
1680
1683
 
1681
1684
  const extension = tileContent?.gltf?.extensions?.[extensionName] as
1682
1685
  | string // EXT_mesh_features doesn't have global metadata
1683
- | GLTF_EXT_feature_metadata_GLTF;
1686
+ | GLTF_EXT_feature_metadata_GLTF
1687
+ | GLTF_EXT_structural_metadata_GLTF;
1684
1688
 
1685
1689
  return {extensionName, extension};
1686
1690
  }
1687
-
1688
- /**
1689
- * Handle EXT_feature_metadata to get property table
1690
- * @param extension - global level of EXT_FEATURE_METADATA extension
1691
- * @param metadataClass - user selected feature metadata class name
1692
- * @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
1693
- */
1694
- function getPropertyTableFromExtFeatureMetadata(
1695
- extension: GLTF_EXT_feature_metadata_GLTF,
1696
- metadataClass?: string
1697
- ): FeatureTableJson | null {
1698
- if (extension?.featureTables) {
1699
- /**
1700
- * Take only first feature table to generate attributes storage info object.
1701
- * TODO: Think about getting data from all feature tables?
1702
- * It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
1703
- * In I3S we should decide which featureIds attribute will be passed to geometry data.
1704
- */
1705
- const firstFeatureTableName = Object.keys(extension.featureTables)?.[0];
1706
-
1707
- if (firstFeatureTableName) {
1708
- const featureTable = extension?.featureTables[firstFeatureTableName];
1709
- const propertyTable = {};
1710
-
1711
- for (const propertyName in featureTable.properties) {
1712
- propertyTable[propertyName] = featureTable.properties[propertyName].data;
1713
- }
1714
-
1715
- return propertyTable;
1716
- }
1717
- }
1718
-
1719
- if (extension?.featureTextures) {
1720
- let featureTexture: string | undefined;
1721
- for (const textureKey in extension.featureTextures) {
1722
- const texture = extension.featureTextures[textureKey];
1723
- if (texture.class === metadataClass) {
1724
- featureTexture = textureKey;
1725
- }
1726
- }
1727
-
1728
- if (typeof featureTexture === 'string') {
1729
- const featureTable = extension?.featureTextures[featureTexture];
1730
- const propertyTable = {};
1731
-
1732
- for (const propertyName in featureTable.properties) {
1733
- propertyTable[propertyName] = featureTable.properties[propertyName].data;
1734
- }
1735
-
1736
- return propertyTable;
1737
- }
1738
- }
1739
-
1740
- console.warn(
1741
- "The I3S converter couldn't handle EXT_feature_metadata extension: There is neither featureTables, no featureTextures in the extension."
1742
- );
1743
- return null;
1744
- }
1745
-
1746
- /**
1747
- * Handle EXT_structural_metadata to get property table
1748
- * @param extension - global level of EXT_STRUCTURAL_METADATA extension
1749
- * @param metadataClass - user selected feature metadata class name
1750
- * @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
1751
- */
1752
- function getPropertyTableFromExtStructuralMetadata(
1753
- extension: GLTF_EXT_structural_metadata,
1754
- metadataClass?: string
1755
- ): FeatureTableJson | null {
1756
- if (extension?.propertyTables) {
1757
- /**
1758
- * Take only first feature table to generate attributes storage info object.
1759
- * TODO: Think about getting data from all feature tables?
1760
- * It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
1761
- * In I3S we should decide which featureIds attribute will be passed to geometry data.
1762
- */
1763
- const firstPropertyTable = extension?.propertyTables[0];
1764
- const propertyTableWithData = {};
1765
-
1766
- for (const propertyName in firstPropertyTable.properties) {
1767
- propertyTableWithData[propertyName] = firstPropertyTable.properties[propertyName].data;
1768
- }
1769
-
1770
- return propertyTableWithData;
1771
- }
1772
-
1773
- if (extension?.propertyTextures) {
1774
- /**
1775
- * Take only first feature table to generate attributes storage info object.
1776
- * TODO: Think about getting data from all feature tables?
1777
- * It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
1778
- * In I3S we should decide which featureIds attribute will be passed to geometry data.
1779
- */
1780
- if (extension?.propertyTextures) {
1781
- const firstPropertyTexture = extension?.propertyTextures[0];
1782
- const propertyTableWithData = {};
1783
-
1784
- for (const propertyName in firstPropertyTexture.properties) {
1785
- propertyTableWithData[propertyName] = firstPropertyTexture.properties[propertyName].data;
1786
- }
1787
-
1788
- return propertyTableWithData;
1789
- }
1790
- }
1791
-
1792
- console.warn(
1793
- "The I3S converter couldn't handle EXT_structural_metadata extension: There is neither propertyTables, no propertyTextures in the extension."
1794
- );
1795
- return null;
1796
- }
1797
-
1798
- /**
1799
- * Handle EXT_mesh_features to get property table
1800
- * @param extension - global level of EXT_MESH_FEATURES extension
1801
- * @param metadataClass - user selected feature metadata class name
1802
- * @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
1803
- */
1804
- function getPropertyTableFromExtMeshFeatures(
1805
- extension: GLTF_EXT_mesh_features,
1806
- metadataClass?: string
1807
- ): FeatureTableJson | null {
1808
- if (extension?.featureIds) {
1809
- const firstFeatureId = extension?.featureIds[0];
1810
- const propertyTableWithData = {};
1811
-
1812
- // When firstFeatureId.propertyTable is defined, the property data will be taken from EXT_structural_metadata extension
1813
- if (!firstFeatureId.propertyTable) {
1814
- console.warn(
1815
- 'Should be implemented as we have the tileset with Ext_mesh_features not linked with EXT_structural_metadata extension'
1816
- );
1817
- }
1818
-
1819
- return propertyTableWithData;
1820
- }
1821
-
1822
- console.warn(
1823
- "The I3S converter couldn't handle EXT_mesh_features extension: There is no featureIds in the extension."
1824
- );
1825
- return null;
1826
- }
@@ -1,6 +1,12 @@
1
1
  import {Tiles3DTileContent} from '@loaders.gl/3d-tiles';
2
2
  import {GLTFPrimitiveModeString, PreprocessData} from '../types';
3
- import {GLTF, GLTFLoader, GLTF_EXT_feature_metadata_GLTF} from '@loaders.gl/gltf';
3
+ import {
4
+ EXT_STRUCTURAL_METADATA,
5
+ GLTF,
6
+ GLTFLoader,
7
+ GLTF_EXT_feature_metadata_GLTF,
8
+ GLTF_EXT_structural_metadata_GLTF
9
+ } from '@loaders.gl/gltf';
4
10
  import {parse} from '@loaders.gl/core';
5
11
  import {EXT_FEATURE_METADATA} from '@loaders.gl/gltf';
6
12
 
@@ -43,8 +49,8 @@ export const analyzeTileContent = async (
43
49
  if (!gltf) {
44
50
  return defaultResult;
45
51
  }
46
- const meshTopologyTypes = getMeshTypesFromGltf(gltf);
47
- const metadataClasses = getMetadataClassesFromGltf(gltf);
52
+ const meshTopologyTypes = getMeshTypesFromGLTF(gltf);
53
+ const metadataClasses = getMetadataClassesFromGLTF(gltf);
48
54
  return {
49
55
  meshTopologyTypes,
50
56
  metadataClasses
@@ -56,7 +62,7 @@ export const analyzeTileContent = async (
56
62
  * @param gltfJson - JSON part of GLB content
57
63
  * @returns array of mesh types found
58
64
  */
59
- const getMeshTypesFromGltf = (gltfJson: GLTF): Set<GLTFPrimitiveModeString> => {
65
+ const getMeshTypesFromGLTF = (gltfJson: GLTF): Set<GLTFPrimitiveModeString> => {
60
66
  const result: Set<GLTFPrimitiveModeString> = new Set();
61
67
  for (const mesh of gltfJson.meshes || []) {
62
68
  for (const primitive of mesh.primitives) {
@@ -72,17 +78,32 @@ const getMeshTypesFromGltf = (gltfJson: GLTF): Set<GLTFPrimitiveModeString> => {
72
78
 
73
79
  /**
74
80
  * Get feature metadata classes from glTF
81
+ * The tileset might contain multiple metadata classes provided by EXT_feature_metadata and EXT_structural_metadata extensions.
82
+ * Every class is a set of properties. But I3S can consume only one set of properties.
83
+ * 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.
75
84
  * @param gltfJson - JSON part of GLB content
76
85
  * @returns array of classes
77
86
  */
78
- const getMetadataClassesFromGltf = (gltfJson: GLTF): Set<string> => {
87
+ const getMetadataClassesFromGLTF = (gltfJson: GLTF): Set<string> => {
79
88
  const result: Set<string> = new Set();
80
89
 
81
- const classes = (gltfJson.extensions?.[EXT_FEATURE_METADATA] as GLTF_EXT_feature_metadata_GLTF)
82
- ?.schema?.classes;
90
+ // Try to parse from EXT_feature_metadata
91
+ const extFeatureMetadataClasses = (
92
+ gltfJson.extensions?.[EXT_FEATURE_METADATA] as GLTF_EXT_feature_metadata_GLTF
93
+ )?.schema?.classes;
83
94
 
84
- if (classes) {
85
- for (const classKey of Object.keys(classes)) {
95
+ if (extFeatureMetadataClasses) {
96
+ for (const classKey of Object.keys(extFeatureMetadataClasses)) {
97
+ result.add(classKey);
98
+ }
99
+ }
100
+
101
+ // Try to parse from EXT_structural_metadata
102
+ const extStructuralMetadataClasses = (
103
+ gltfJson.extensions?.[EXT_STRUCTURAL_METADATA] as GLTF_EXT_structural_metadata_GLTF
104
+ )?.schema?.classes;
105
+ if (extStructuralMetadataClasses) {
106
+ for (const classKey of Object.keys(extStructuralMetadataClasses)) {
86
107
  result.add(classKey);
87
108
  }
88
109
  }
@@ -656,7 +656,6 @@ export default class I3SConverter {
656
656
  We will append new attributes only in case the property table is updated.
657
657
  According to ver 1.9 (see https://github.com/Esri/i3s-spec/blob/master/docs/1.9/attributeStorageInfo.cmn.md):
658
658
  "The attributeStorageInfo object describes the structure of the binary attribute data resource of a layer, which is the same for every node in the layer."
659
- But the specification of ver 2.1 doesn't have such a requirement ("...the same for every node...")
660
659
  */
661
660
  this._convertPropertyTableToNodeAttributes(propertyTable);
662
661
  }
@@ -1167,7 +1166,6 @@ export default class I3SConverter {
1167
1166
  We will append new attributes only in case the property table is updated.
1168
1167
  According to ver 1.9 (see https://github.com/Esri/i3s-spec/blob/master/docs/1.9/attributeStorageInfo.cmn.md):
1169
1168
  "The attributeStorageInfo object describes the structure of the binary attribute data resource of a layer, which is the same for every node in the layer."
1170
- But the specification of ver 2.1 doesn't have such a requirement ("...the same for every node...")
1171
1169
  */
1172
1170
  const found = this.layers0!.attributeStorageInfo!.find((element) => element.name === key);
1173
1171
  if (!found) {
@@ -106,10 +106,8 @@ export type GeometryAttributes = {
106
106
  featureCount: number;
107
107
  };
108
108
 
109
- /** Geometry attributes specific for the particular feature */
110
- export type GroupedByFeatureIdAttributes = {
111
- /** Feature Id */
112
- featureId: number;
109
+ /** Geometry attributes applicable for reordering by featureId */
110
+ export type GroupedAttributes = {
113
111
  /** POSITION attribute value */
114
112
  positions: Float32Array;
115
113
  /** NORMAL attribute value */
@@ -122,6 +120,12 @@ export type GroupedByFeatureIdAttributes = {
122
120
  texCoords: Float32Array;
123
121
  };
124
122
 
123
+ /** Geometry attributes specific for the particular feature */
124
+ export type GroupedByFeatureIdAttributes = GroupedAttributes & {
125
+ /** Feature Id */
126
+ featureId: number;
127
+ };
128
+
125
129
  /** Shared resources made from GLTF material */
126
130
  export type SharedResourcesArrays = {
127
131
  /** material definitions list https://github.com/Esri/i3s-spec/blob/master/docs/1.8/materialDefinitionInfo.cmn.md */
@@ -183,7 +187,12 @@ export enum GLTFPrimitiveModeString {
183
187
  export type PreprocessData = {
184
188
  /** Mesh topology types used in gltf primitives of the tileset */
185
189
  meshTopologyTypes: Set<GLTFPrimitiveModeString>;
186
- /** Featrue metadata classes found in glTF extensions */
190
+ /**
191
+ * Featrue metadata classes found in glTF extensions
192
+ * The tileset might contain multiple metadata classes provided by EXT_feature_metadata and EXT_structural_metadata extensions.
193
+ * Every class is a set of properties. But I3S can consume only one set of properties.
194
+ * 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.
195
+ */
187
196
  metadataClasses: Set<string>;
188
197
  };
189
198
 
package/src/pgm-loader.ts CHANGED
@@ -1,24 +1,32 @@
1
- import type {LoaderWithParser} from '@loaders.gl/loader-utils';
2
- import {parsePGM} from '@math.gl/geoid';
1
+ import type {LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
2
+ import {Geoid, parsePGM} from '@math.gl/geoid';
3
3
 
4
4
  // __VERSION__ is injected by babel-plugin-version-inline
5
5
  // @ts-ignore TS2304: Cannot find name '__VERSION__'.
6
6
  const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
7
7
 
8
+ export {Geoid};
9
+
10
+ export type PGMLoaderOptions = LoaderOptions & {
11
+ pgm?: {
12
+ cubic?: boolean;
13
+ };
14
+ };
15
+
8
16
  /**
9
17
  * Loader for PGM - Netpbm grayscale image format
10
18
  */
11
- export const PGMLoader: LoaderWithParser = {
19
+ export const PGMLoader: LoaderWithParser<Geoid, never, PGMLoaderOptions> = {
12
20
  name: 'PGM - Netpbm grayscale image format',
13
21
  id: 'pgm',
14
22
  module: 'tile-converter',
15
23
  version: VERSION,
16
24
  mimeTypes: ['image/x-portable-graymap'],
17
- // @ts-expect-error LoaderOptions does not have cubic parameter
18
- parse: async (arrayBuffer, options) => parsePGM(new Uint8Array(arrayBuffer), options),
25
+ parse: async (arrayBuffer, options) => parsePGM(new Uint8Array(arrayBuffer), options?.pgm || {}),
19
26
  extensions: ['pgm'],
20
27
  options: {
21
- // TODO - use pgm namespace
22
- cubic: false
28
+ pgm: {
29
+ cubic: false
30
+ }
23
31
  }
24
32
  };