Skip to content

Commit e57b521

Browse files
authored
Merge pull request #357 from CesiumGS/binary-property-value-validation
Binary property value validation in glTF
2 parents c97548f + 8366730 commit e57b521

24 files changed

+345
-60
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
{
2+
"extensions" : {
3+
"EXT_structural_metadata" : {
4+
"schema" : {
5+
"id": "FeatureIdAttributeAndPropertyTableSchema",
6+
"classes" : {
7+
"exampleMetadataClass" : {
8+
"name" : "Example metadata class",
9+
"description" : "An example metadata class",
10+
"properties" : {
11+
"example_VEC3_FLOAT32" : {
12+
"name" : "Example VEC3 FLOAT32 property",
13+
"description" : "An example property, with type VEC3, with component type FLOAT32",
14+
"type" : "VEC3",
15+
"componentType" : "FLOAT32",
16+
"max": [ 3.0, 3.0, 3.0 ]
17+
}
18+
}
19+
}
20+
}
21+
},
22+
"propertyTables" : [ {
23+
"name" : "Example property table",
24+
"class" : "exampleMetadataClass",
25+
"count" : 4,
26+
"properties" : {
27+
"example_VEC3_FLOAT32" : {
28+
"values" : 4
29+
}
30+
}
31+
} ]
32+
}
33+
},
34+
"extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ],
35+
"accessors" : [ {
36+
"bufferView" : 0,
37+
"byteOffset" : 0,
38+
"componentType" : 5123,
39+
"count" : 24,
40+
"type" : "SCALAR",
41+
"max" : [ 15 ],
42+
"min" : [ 0 ]
43+
}, {
44+
"bufferView" : 1,
45+
"byteOffset" : 0,
46+
"componentType" : 5126,
47+
"count" : 16,
48+
"type" : "VEC3",
49+
"max" : [ 1.0, 1.0, 0.0 ],
50+
"min" : [ 0.0, 0.0, 0.0 ]
51+
}, {
52+
"bufferView" : 2,
53+
"byteOffset" : 0,
54+
"componentType" : 5126,
55+
"count" : 16,
56+
"type" : "VEC3",
57+
"max" : [ 0.0, 0.0, 1.0 ],
58+
"min" : [ 0.0, 0.0, 1.0 ]
59+
}, {
60+
"bufferView" : 3,
61+
"byteOffset" : 0,
62+
"componentType" : 5121,
63+
"count" : 16,
64+
"type" : "SCALAR",
65+
"max" : [ 3 ],
66+
"min" : [ 0 ]
67+
} ],
68+
"asset" : {
69+
"generator" : "JglTF from https://github.com/javagl/JglTF",
70+
"version" : "2.0"
71+
},
72+
"buffers" : [ {
73+
"uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==",
74+
"byteLength" : 496
75+
}, {
76+
"uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA",
77+
"byteLength" : 48
78+
} ],
79+
"bufferViews" : [ {
80+
"buffer" : 0,
81+
"byteOffset" : 0,
82+
"byteLength" : 48,
83+
"target" : 34963
84+
}, {
85+
"buffer" : 0,
86+
"byteOffset" : 48,
87+
"byteLength" : 192,
88+
"target" : 34962
89+
}, {
90+
"buffer" : 0,
91+
"byteOffset" : 240,
92+
"byteLength" : 192,
93+
"target" : 34962
94+
}, {
95+
"buffer" : 0,
96+
"byteOffset" : 432,
97+
"byteLength" : 64,
98+
"byteStride" : 4,
99+
"target" : 34962
100+
}, {
101+
"buffer" : 1,
102+
"byteOffset" : 0,
103+
"byteLength" : 48
104+
} ],
105+
"materials" : [ {
106+
"pbrMetallicRoughness" : {
107+
"baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ],
108+
"metallicFactor" : 0.0,
109+
"roughnessFactor" : 1.0
110+
},
111+
"alphaMode" : "OPAQUE",
112+
"doubleSided" : true
113+
} ],
114+
"meshes" : [ {
115+
"primitives" : [ {
116+
"extensions" : {
117+
"EXT_mesh_features" : {
118+
"featureIds" : [ {
119+
"featureCount" : 4,
120+
"attribute" : 0,
121+
"propertyTable" : 0
122+
} ]
123+
}
124+
},
125+
"attributes" : {
126+
"POSITION" : 1,
127+
"NORMAL" : 2,
128+
"_FEATURE_ID_0" : 3
129+
},
130+
"indices" : 0,
131+
"material" : 0,
132+
"mode" : 4
133+
} ]
134+
} ],
135+
"nodes" : [ {
136+
"mesh" : 0
137+
} ],
138+
"scene" : 0,
139+
"scenes" : [ {
140+
"nodes" : [ 0 ]
141+
} ]
142+
}

specs/gltfExtensions/ExtValidationSpec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ describe("combined EXT_structural_metadata and EXT_mesh_features extension valid
99
expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE");
1010
});
1111

12+
it("detects issues in FeatureIdAttributeAndPropertyTableWithValueNotInRange", async function () {
13+
const result = await validateGltf(
14+
"./specs/data/gltfExtensions/FeatureIdAttributeAndPropertyTableWithValueNotInRange.gltf"
15+
);
16+
expect(result.length).toEqual(1);
17+
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
18+
});
19+
1220
it("detects issues in FeatureIdAttributePropertyTableInvalidValue", async function () {
1321
const result = await validateGltf(
1422
"./specs/data/gltfExtensions/FeatureIdAttributePropertyTableInvalidValue.gltf"

src/issues/GltfExtensionValidationIssues.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class GltfExtensionValidationIssues {
2323

2424
/**
2525
* Indicates that the extension referred to an element in the
26-
* glTF assset that did not match the requirements of the
26+
* glTF asset that did not match the requirements of the
2727
* extension specification. (For example, a 'texCoord' that
2828
* referred to a VEC3 accessor). Further details should be
2929
* encoded in the 'message'.

src/tileFormats/I3dmValidator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ export class I3dmValidator implements Validator<Buffer> {
254254
result = false;
255255
}
256256

257-
// If the GLB data was embdedded, validate it directly
257+
// If the GLB data was embedded, validate it directly
258258
if (hasEmbeddedGlb) {
259259
const gltfValidator = new GltfValidator();
260260
const gltfResult = await gltfValidator.validateObject(
@@ -268,7 +268,7 @@ export class I3dmValidator implements Validator<Buffer> {
268268
} else {
269269
// The GLB data was a URI, as indicated by `gltfFormat === 0`.
270270
// The padding bytes in this case should be 0x20 (space) bytes,
271-
// so issue a warning if the buffer contais 0x00 (zero) bytes.
271+
// so issue a warning if the buffer contains 0x00 (zero) bytes.
272272
if (glbData.includes("\0")) {
273273
const message =
274274
`The field containing the URI of the glTF asset contained ` +

src/validation/PropertiesValidator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Properties } from "3d-tiles-tools";
88
import { SemanticValidationIssues } from "../issues/SemanticValidationIssues";
99

1010
/**
11-
* A class for validations related to `tileset.properties` objects. Aplogies
11+
* A class for validations related to `tileset.properties` objects. Apologies
1212
* for the confusing name...
1313
*
1414
* @internal

src/validation/StatisticsClassValidator.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,15 @@ export class StatisticsClassValidator {
117117
) {
118118
result = false;
119119
} else {
120-
for (const statisticsClassPropetyName of Object.keys(
120+
for (const statisticsClassPropertyName of Object.keys(
121121
statisticsClassProperties
122122
)) {
123123
if (
124-
!metadataClassPropertyNames.includes(statisticsClassPropetyName)
124+
!metadataClassPropertyNames.includes(statisticsClassPropertyName)
125125
) {
126126
const message =
127127
`Statistics class '${className}' contains a property name ` +
128-
`'${statisticsClassPropetyName}', but the schema class does ` +
128+
`'${statisticsClassPropertyName}', but the schema class does ` +
129129
`not define this property`;
130130
const issue = StructureValidationIssues.IDENTIFIER_NOT_FOUND(
131131
classPath,

src/validation/SubtreeConsistencyValidator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class SubtreeConsistencyValidator {
4545
* is not given, then the validation of the availability information
4646
* (that requires information about the subtree structure) will be
4747
* skipped
48-
* @param context - The `ValidationCondext`
48+
* @param context - The `ValidationContext`
4949
* @returns Whether the data was consistent
5050
*/
5151
static validateSubtreeConsistency(
@@ -111,7 +111,7 @@ export class SubtreeConsistencyValidator {
111111
let result = true;
112112

113113
// The implicitTiling has already been validated to have a valid
114-
// subvisionScheme. Therefore, the methods from `ImplicitTilings`
114+
// subdivisionScheme. Therefore, the methods from `ImplicitTilings`
115115
// should never throw an `ImplicitTilingError` here.
116116

117117
// Validate the consistency of the tileAvailability

src/validation/SubtreeInfoValidator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class SubtreeInfoValidator {
106106
result = false;
107107
}
108108

109-
// TOOD The validation of whether the child subtrees that are
109+
// TODO The validation of whether the child subtrees that are
110110
// marked as available are actually available is not done yet
111111
// (Should this really try to resolve the resource?)
112112

src/validation/ValidationIssueFilters.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ export class ValidationIssueFilters {
2727
* `ValidationIssue` instances where the `ValidationIssue#severity`
2828
* is one of the given severities.
2929
*
30-
* @param includedServerities - The included severities
30+
* @param includedSeverities - The included severities
3131
* @returns The `ValidationIssueFilter`
3232
*/
3333
static byIncludedSeverities(
34-
...includedServerities: ValidationIssueSeverity[]
34+
...includedSeverities: ValidationIssueSeverity[]
3535
): ValidationIssueFilter {
3636
const predicate = (issues: ValidationIssue[]) =>
37-
includedServerities.includes(issues[issues.length - 1].severity);
37+
includedSeverities.includes(issues[issues.length - 1].severity);
3838
return predicate;
3939
}
4040
}

src/validation/gltf/meshFeatures/FeatureIdAccessorValidator.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,16 @@ export class FeatureIdAccessorValidator {
7373
// Only if the structures have been valid until now,
7474
// validate the actual data of the accessor
7575
if (result && gltfData.gltfDocument) {
76-
const dataValid = FeatureIdAccessorValidator.validateFeatureIdAcessorData(
77-
path,
78-
accessorIndex,
79-
featureCount,
80-
gltfData,
81-
propertyTableState,
82-
nullFeatureId,
83-
context
84-
);
76+
const dataValid =
77+
FeatureIdAccessorValidator.validateFeatureIdAccessorData(
78+
path,
79+
accessorIndex,
80+
featureCount,
81+
gltfData,
82+
propertyTableState,
83+
nullFeatureId,
84+
context
85+
);
8586
if (!dataValid) {
8687
result = false;
8788
}
@@ -90,7 +91,7 @@ export class FeatureIdAccessorValidator {
9091
}
9192

9293
/**
93-
* Validate the data of the given feature ID atribute.
94+
* Validate the data of the given feature ID attribute.
9495
*
9596
* This assumes that the glTF data is valid as determined by the
9697
* glTF Validator, **AND** as determined by the validation of
@@ -110,7 +111,7 @@ export class FeatureIdAccessorValidator {
110111
* @param context - The `ValidationContext` that any issues will be added to
111112
* @returns Whether the object was valid
112113
*/
113-
private static validateFeatureIdAcessorData(
114+
private static validateFeatureIdAccessorData(
114115
path: string,
115116
accessorIndex: number,
116117
featureCount: number,
@@ -126,7 +127,7 @@ export class FeatureIdAccessorValidator {
126127
if (!accessorValues) {
127128
// This should only happen for invalid glTF assets (e.g. ones that
128129
// use wrong accessor component types), or when the gltfDocument
129-
// could not be read due to another structual error that should
130+
// could not be read due to another structural error that should
130131
// be detected by the extension validation.
131132
const message = `Could not read data for feature ID attribute accessor`;
132133
const issue = ValidationIssues.INTERNAL_ERROR(path, message);

0 commit comments

Comments
 (0)