From 0fd3321283b9202a93295ee9ddded42ce38bcfca Mon Sep 17 00:00:00 2001 From: Viktor Belomestnov Date: Tue, 19 Sep 2023 09:20:24 +0200 Subject: [PATCH] feat(tile-converter): select metadata class from EXT_structural_metadata (#2647) --- modules/gltf/src/index.ts | 2 +- .../src/lib/extensions/EXT_mesh_features.ts | 2 + .../lib/extensions/EXT_structural_metadata.ts | 12 ++--- .../gltf-ext-structural-metadata-schema.ts | 2 +- .../helpers/batch-ids-extensions.ts | 28 +----------- .../helpers/geometry-converter.ts | 45 ++----------------- .../helpers/preprocess-3d-tiles.ts | 28 +++++++++--- 7 files changed, 40 insertions(+), 79 deletions(-) diff --git a/modules/gltf/src/index.ts b/modules/gltf/src/index.ts index 3f400ecc65..b1b0a9ebf2 100644 --- a/modules/gltf/src/index.ts +++ b/modules/gltf/src/index.ts @@ -44,7 +44,7 @@ export type { GLTF_EXT_feature_metadata_FeatureIdTextureAccessor } from './lib/types/gltf-json-schema'; -export type {GLTF_EXT_structural_metadata} from './lib/types/gltf-ext-structural-metadata-schema'; +export type {GLTF_EXT_structural_metadata_GLTF} from './lib/types/gltf-ext-structural-metadata-schema'; export type { GLTF_EXT_mesh_features, diff --git a/modules/gltf/src/lib/extensions/EXT_mesh_features.ts b/modules/gltf/src/lib/extensions/EXT_mesh_features.ts index 1b2d5fbc39..39af8f9fa7 100644 --- a/modules/gltf/src/lib/extensions/EXT_mesh_features.ts +++ b/modules/gltf/src/lib/extensions/EXT_mesh_features.ts @@ -1,3 +1,5 @@ +// GLTF EXTENSION: EXT_mesh_features +// https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_mesh_features /* eslint-disable camelcase */ import type {GLTF, GLTFMeshPrimitive} from '../types/gltf-json-schema'; import {GLTFLoaderOptions} from '../../gltf-loader'; diff --git a/modules/gltf/src/lib/extensions/EXT_structural_metadata.ts b/modules/gltf/src/lib/extensions/EXT_structural_metadata.ts index 039d0a47d3..fa307bf96a 100644 --- a/modules/gltf/src/lib/extensions/EXT_structural_metadata.ts +++ b/modules/gltf/src/lib/extensions/EXT_structural_metadata.ts @@ -1,3 +1,5 @@ +// GLTF EXTENSION: EXT_structural_metadata +// https://github.com/CesiumGS/glTF/blob/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata /* eslint-disable camelcase */ import type {BigTypedArray, TypedArray} from '@loaders.gl/schema'; import type {GLTF, GLTFTextureInfoMetadata, GLTFMeshPrimitive} from '../types/gltf-json-schema'; @@ -7,7 +9,7 @@ import type { GLTF_EXT_structural_metadata_Enum, GLTF_EXT_structural_metadata_EnumValue, GLTF_EXT_structural_metadata_PropertyTable, - GLTF_EXT_structural_metadata, + GLTF_EXT_structural_metadata_GLTF, GLTF_EXT_structural_metadata_PropertyTexture, GLTF_EXT_structural_metadata_PropertyTable_Property, GLTF_EXT_structural_metadata_Primitive @@ -100,7 +102,7 @@ export function getPropertyTablePopulated( scenegraph: GLTFScenegraph, propertyTableIndex: number ): GLTF_EXT_structural_metadata_PropertyTable { - const extension: GLTF_EXT_structural_metadata | null = scenegraph.getExtension( + const extension: GLTF_EXT_structural_metadata_GLTF | null = scenegraph.getExtension( EXT_STRUCTURAL_METADATA_NAME ); const propertyTable = extension?.propertyTables?.[propertyTableIndex]; @@ -119,7 +121,7 @@ export function getPropertyTablePopulated( * @param options - loader options. */ function decodeExtStructuralMetadata(scenegraph: GLTFScenegraph, options: GLTFLoaderOptions): void { - const extension: GLTF_EXT_structural_metadata | null = scenegraph.getExtension( + const extension: GLTF_EXT_structural_metadata_GLTF | null = scenegraph.getExtension( EXT_STRUCTURAL_METADATA_NAME ); if (!extension?.schema) { @@ -180,7 +182,7 @@ function processPrimitivePropertyTextures( scenegraph: GLTFScenegraph, propertyTextures: GLTF_EXT_structural_metadata_PropertyTexture[], primitive: GLTFMeshPrimitive, - extension: GLTF_EXT_structural_metadata + extension: GLTF_EXT_structural_metadata_GLTF ): void { if (!propertyTextures) { return; @@ -210,7 +212,7 @@ function processPrimitivePropertyTexture( scenegraph: GLTFScenegraph, propertyTexture: GLTF_EXT_structural_metadata_PropertyTexture, primitive: GLTFMeshPrimitive, - extension: GLTF_EXT_structural_metadata + extension: GLTF_EXT_structural_metadata_GLTF ): void { if (!propertyTexture.properties) { return; diff --git a/modules/gltf/src/lib/types/gltf-ext-structural-metadata-schema.ts b/modules/gltf/src/lib/types/gltf-ext-structural-metadata-schema.ts index ab54314c45..f6f373841b 100644 --- a/modules/gltf/src/lib/types/gltf-ext-structural-metadata-schema.ts +++ b/modules/gltf/src/lib/types/gltf-ext-structural-metadata-schema.ts @@ -5,7 +5,7 @@ import {GLTFTextureInfoMetadata} from './gltf-json-schema'; /** * @see https://github.com/CesiumGS/glTF/blob/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata/schema/glTF.EXT_structural_metadata.schema.json */ -export type GLTF_EXT_structural_metadata = { +export type GLTF_EXT_structural_metadata_GLTF = { /** An object defining classes and enums. */ schema?: GLTF_EXT_structural_metadata_Schema; /** A uri to an external schema file. */ diff --git a/modules/tile-converter/src/i3s-converter/helpers/batch-ids-extensions.ts b/modules/tile-converter/src/i3s-converter/helpers/batch-ids-extensions.ts index f4ae09a787..2199b105fe 100644 --- a/modules/tile-converter/src/i3s-converter/helpers/batch-ids-extensions.ts +++ b/modules/tile-converter/src/i3s-converter/helpers/batch-ids-extensions.ts @@ -3,8 +3,7 @@ import type {NumericArray} from '@loaders.gl/loader-utils'; import type { GLTF_EXT_feature_metadata_FeatureIdTexture, GLTF_EXT_feature_metadata_GLTF, - GLTF_EXT_feature_metadata_Primitive, - GLTF_EXT_structural_metadata + GLTF_EXT_feature_metadata_Primitive } from '@loaders.gl/gltf'; import type {GLTF_EXT_mesh_features} from '@loaders.gl/gltf'; @@ -12,7 +11,7 @@ import type {GLTF_EXT_mesh_features} from '@loaders.gl/gltf'; import {TypedArray} from '@math.gl/core'; import {TextureImageProperties} from '../types'; import {emod} from '@loaders.gl/math'; -import {EXT_STRUCTURAL_METADATA, EXT_MESH_FEATURES, EXT_FEATURE_METADATA} from '@loaders.gl/gltf'; +import {EXT_MESH_FEATURES, EXT_FEATURE_METADATA} from '@loaders.gl/gltf'; import {Tiles3DTileContent} from '@loaders.gl/3d-tiles'; /** @@ -75,12 +74,6 @@ export function handleBatchIdsExtensions( ); case EXT_MESH_FEATURES: return handleExtMeshFeaturesExtension(attributes, extensionData as GLTF_EXT_mesh_features); - case EXT_STRUCTURAL_METADATA: - return handleExtStructuralMetadataExtension( - attributes, - extensionData as GLTF_EXT_structural_metadata - ); - default: return []; } @@ -89,23 +82,6 @@ export function handleBatchIdsExtensions( return []; } -function handleExtStructuralMetadataExtension( - attributes: { - [key: string]: GLTFAccessorPostprocessed; - }, - extStructuralMetadata: GLTF_EXT_structural_metadata -): NumericArray { - // Take only first extension object to get batchIds attribute name. - const dataAttributeNames = extStructuralMetadata?.dataAttributeNames; - if (dataAttributeNames?.length) { - // Let's use the first element of the array - // TODO: What to do with others if any? - const batchIdsAttribute = attributes[dataAttributeNames[0]]; - return batchIdsAttribute.value; - } - return []; -} - /** * Getting batchIds from EXT_mesh_features extensions. * @param attributes - gltf accessors diff --git a/modules/tile-converter/src/i3s-converter/helpers/geometry-converter.ts b/modules/tile-converter/src/i3s-converter/helpers/geometry-converter.ts index d81f029407..42f49e6722 100644 --- a/modules/tile-converter/src/i3s-converter/helpers/geometry-converter.ts +++ b/modules/tile-converter/src/i3s-converter/helpers/geometry-converter.ts @@ -1,7 +1,7 @@ import type {FeatureTableJson, Tiles3DTileContent} from '@loaders.gl/3d-tiles'; import type { GLTF_EXT_mesh_features, - GLTF_EXT_structural_metadata, + GLTF_EXT_structural_metadata_GLTF, GLTFAccessorPostprocessed, GLTFMaterialPostprocessed, GLTFNodePostprocessed, @@ -1625,16 +1625,9 @@ export function getPropertyTable( const {extensionName, extension} = getPropertyTableExtension(tileContent); switch (extensionName) { - case EXT_MESH_FEATURES: { - propertyTable = getPropertyTableFromExtMeshFeatures( - extension as GLTF_EXT_mesh_features, - metadataClass - ); - return propertyTable; - } case EXT_STRUCTURAL_METADATA: { propertyTable = getPropertyTableFromExtStructuralMetadata( - extension as GLTF_EXT_structural_metadata, + extension as GLTF_EXT_structural_metadata_GLTF, metadataClass ); return propertyTable; @@ -1660,7 +1653,7 @@ function getPropertyTableExtension(tileContent: Tiles3DTileContent): { extension: | string | GLTF_EXT_feature_metadata_GLTF - | GLTF_EXT_structural_metadata + | GLTF_EXT_structural_metadata_GLTF | GLTF_EXT_mesh_features | null; } { @@ -1759,7 +1752,7 @@ function getPropertyTableFromExtFeatureMetadata( * @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly. */ function getPropertyTableFromExtStructuralMetadata( - extension: GLTF_EXT_structural_metadata, + extension: GLTF_EXT_structural_metadata_GLTF, metadataClass?: string ): FeatureTableJson | null { if (extension?.propertyTables) { @@ -1803,33 +1796,3 @@ function getPropertyTableFromExtStructuralMetadata( ); return null; } - -/** - * Handle EXT_mesh_features to get property table - * @param extension - global level of EXT_MESH_FEATURES extension - * @param metadataClass - user selected feature metadata class name - * @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly. - */ -function getPropertyTableFromExtMeshFeatures( - extension: GLTF_EXT_mesh_features, - metadataClass?: string -): FeatureTableJson | null { - if (extension?.featureIds) { - const firstFeatureId = extension?.featureIds[0]; - const propertyTableWithData = {}; - - // When firstFeatureId.propertyTable is defined, the property data will be taken from EXT_structural_metadata extension - if (!firstFeatureId.propertyTable) { - console.warn( - 'Should be implemented as we have the tileset with Ext_mesh_features not linked with EXT_structural_metadata extension' - ); - } - - return propertyTableWithData; - } - - console.warn( - "The I3S converter couldn't handle EXT_mesh_features extension: There is no featureIds in the extension." - ); - return null; -} diff --git a/modules/tile-converter/src/i3s-converter/helpers/preprocess-3d-tiles.ts b/modules/tile-converter/src/i3s-converter/helpers/preprocess-3d-tiles.ts index 0b677a2e45..bc4f96216a 100644 --- a/modules/tile-converter/src/i3s-converter/helpers/preprocess-3d-tiles.ts +++ b/modules/tile-converter/src/i3s-converter/helpers/preprocess-3d-tiles.ts @@ -1,6 +1,12 @@ import {Tiles3DTileContent} from '@loaders.gl/3d-tiles'; import {GLTFPrimitiveModeString, PreprocessData} from '../types'; -import {GLTF, GLTFLoader, GLTF_EXT_feature_metadata_GLTF} from '@loaders.gl/gltf'; +import { + EXT_STRUCTURAL_METADATA, + GLTF, + GLTFLoader, + GLTF_EXT_feature_metadata_GLTF, + GLTF_EXT_structural_metadata_GLTF +} from '@loaders.gl/gltf'; import {parse} from '@loaders.gl/core'; import {EXT_FEATURE_METADATA} from '@loaders.gl/gltf'; @@ -81,11 +87,23 @@ const getMeshTypesFromGLTF = (gltfJson: GLTF): Set => { const getMetadataClassesFromGLTF = (gltfJson: GLTF): Set => { const result: Set = new Set(); - const classes = (gltfJson.extensions?.[EXT_FEATURE_METADATA] as GLTF_EXT_feature_metadata_GLTF) - ?.schema?.classes; + // Try to parse from EXT_feature_metadata + const extFeatureMetadataClasses = ( + gltfJson.extensions?.[EXT_FEATURE_METADATA] as GLTF_EXT_feature_metadata_GLTF + )?.schema?.classes; - if (classes) { - for (const classKey of Object.keys(classes)) { + if (extFeatureMetadataClasses) { + for (const classKey of Object.keys(extFeatureMetadataClasses)) { + result.add(classKey); + } + } + + // Try to parse from EXT_structural_metadata + const extStructuralMetadataClasses = ( + gltfJson.extensions?.[EXT_STRUCTURAL_METADATA] as GLTF_EXT_structural_metadata_GLTF + )?.schema?.classes; + if (extStructuralMetadataClasses) { + for (const classKey of Object.keys(extStructuralMetadataClasses)) { result.add(classKey); } }