Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

glTF extension validation #280

Merged
merged 37 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7238950
First draft of glTF extension validation
javagl Sep 16, 2023
751f584
Fix featureCount validation
javagl Sep 16, 2023
6de58b6
Fix typo in comment
javagl Sep 19, 2023
e2df7a5
First pass of validation of EXT_mesh_features - WIP
javagl Sep 20, 2023
fbf1e3e
Using glTF-Transform for accessor access
javagl Sep 25, 2023
29d7036
Fixes for specs (some of them preliminary)
javagl Sep 25, 2023
4f003f4
First pass of specs for EXT_mesh_features
javagl Sep 25, 2023
256bc9d
Actually return 'false' when schema is missing
javagl Sep 25, 2023
7cbacb5
Extract class for resolving schema. Fix return values.
javagl Sep 25, 2023
bdc6544
Minor restructuring for schema definition validation
javagl Sep 25, 2023
e427da1
Generalization of ValidationState
javagl Sep 26, 2023
00ee092
First pass for EXT_structural_metadata validation
javagl Sep 26, 2023
1fb14b8
Cleanups and more EXT_structural_metadata validation
javagl Sep 27, 2023
fb26da7
Minor comment fix
javagl Sep 28, 2023
27b18d5
Update for changes in 3d-tiles-tools
javagl Oct 2, 2023
5b50dcb
Property texture value validation
javagl Oct 2, 2023
5161977
Remove unnecessary part of import paths
javagl Oct 2, 2023
be2d3c8
Minor comment update
javagl Oct 3, 2023
2f4d63c
Proper handling of numeric vs. string enum values
javagl Oct 3, 2023
7daf2ba
Do not validate value ranges for min/max/offset/scale
javagl Oct 3, 2023
1537c4e
More property attribute validation. Minor cleanups.
javagl Oct 3, 2023
2214d85
Property attribute value validation
javagl Oct 4, 2023
b345b05
Minor cleanups, better validation messages
javagl Oct 7, 2023
586f3eb
Minor cleanups
javagl Oct 7, 2023
0b60652
First set of EXT_structural_metadata specs
javagl Oct 7, 2023
d3e0d47
Generalization and cleanup for values validation
javagl Oct 7, 2023
438a7de
Cleanups and generalizations for value validation
javagl Oct 7, 2023
db22c1f
Add validation for metadata entity value ranges
javagl Oct 7, 2023
32257a7
Add specs for metadata entity value range validation
javagl Oct 7, 2023
1b81dc1
Fixed typo in file name
javagl Oct 7, 2023
f719aaa
Add missing 'await' when tracking found extensions
javagl Oct 7, 2023
60f6f92
Validation of mesh features combined with property tables
javagl Oct 8, 2023
bbe0130
Proper validation of featureCount with nullFeatureId
javagl Oct 9, 2023
919847b
Update 3d-tiles-tools to 0.3.1
javagl Oct 10, 2023
14ea612
Cleanup TSDoc
javagl Oct 11, 2023
5af4fa4
Extract common code to method
javagl Oct 11, 2023
274560e
Cleanups...
javagl Oct 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@
"3d-tiles-validator": "./build/main"
},
"dependencies": {
"3d-tiles-tools": "^0.3.0",
"@gltf-transform/core": "^3.2.1",
"@gltf-transform/extensions": "^3.2.1",
"@gltf-transform/functions": "^3.2.1",
"3d-tiles-tools": "^0.3.1",
"cesium": "^1.97.0",
"gltf-validator": "^2.0.0-dev.3.9",
"minimatch": "^5.1.0",
"node-stream-zip": "^1.10.1",
"sharp": "^0.32.1",
"yargs": "^17.5.1"
},
"devDependencies": {
Expand Down
74 changes: 74 additions & 0 deletions specs/TilesetValidationSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,80 @@ describe("Tileset validation", function () {
expect(result.get(0).type).toEqual("VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetMetadataEntityPropertyEnumInvalidValue", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyEnumInvalidValue.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual(
"CLASS_PROPERTY_ENUM_VALUE_NAME_NOT_FOUND"
);
});

it("detects issues in tilesetMetadataEntityPropertyMaxNotInRange", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyMaxNotInRange.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetMetadataEntityPropertyMaxWithNormalizedNotInRange", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithNormalizedNotInRange.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetMetadataEntityPropertyMaxWithOffsetNotInRange", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithOffsetNotInRange.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetMetadataEntityPropertyMaxWithScaleNotInRange", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyMaxWithScaleNotInRange.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetMetadataEntityPropertyMinNotInRange", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyMinNotInRange.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetMetadataEntityPropertyMinWithNormalizedNotInRange", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyMinWithNormalizedNotInRange.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetMetadataEntityPropertyMinWithOffsetNotInRange", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyMinWithOffsetNotInRange.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetMetadataEntityPropertyMinWithScaleNotInRange", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetMetadataEntityPropertyMinWithScaleNotInRange.json"
);
expect(result.length).toEqual(1);
expect(result.get(0).type).toEqual("METADATA_VALUE_NOT_IN_RANGE");
});

it("detects issues in tilesetSchemaUriInvalidType", async function () {
const result = await Validators.validateTilesetFile(
"specs/data/tilesets/tilesetSchemaUriInvalidType.json"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{
"extensions" : {
"EXT_structural_metadata" : {
"schema" : {
"id": "FeatureIdAttributeAndPropertyTableSchema",
"classes" : {
"exampleMetadataClass" : {
"name" : "Example metadata class",
"description" : "An example metadata class",
"properties" : {
"example_VEC3_FLOAT32" : {
"name" : "Example VEC3 FLOAT32 property",
"description" : "An example property, with type VEC3, with component type FLOAT32",
"type" : "VEC3",
"componentType" : "FLOAT32"
}
}
}
}
},
"propertyTables" : [ {
"name" : "Example property table",
"class" : "exampleMetadataClass",
"count" : 4,
"properties" : {
"example_VEC3_FLOAT32" : {
"values" : 4
}
}
} ]
}
},
"extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ],
"accessors" : [ {
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 24,
"type" : "SCALAR",
"max" : [ 15 ],
"min" : [ 0 ]
}, {
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 16,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
}, {
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 16,
"type" : "VEC3",
"max" : [ 0.0, 0.0, 1.0 ],
"min" : [ 0.0, 0.0, 1.0 ]
}, {
"bufferView" : 3,
"byteOffset" : 0,
"componentType" : 5120,
"count" : 16,
"type" : "SCALAR",
"max" : [ 123 ],
"min" : [ -123 ]
} ],
"asset" : {
"generator" : "JglTF from https://github.com/javagl/JglTF",
"version" : "2.0"
},
"buffers" : [ {
"uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/hQAAAIUAAACFAAAAhQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAewAAAHsAAAB7AAAAewAAAA==",
"byteLength" : 496
}, {
"uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA",
"byteLength" : 48
} ],
"bufferViews" : [ {
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 48,
"target" : 34963
}, {
"buffer" : 0,
"byteOffset" : 48,
"byteLength" : 192,
"target" : 34962
}, {
"buffer" : 0,
"byteOffset" : 240,
"byteLength" : 192,
"target" : 34962
}, {
"buffer" : 0,
"byteOffset" : 432,
"byteLength" : 64,
"byteStride" : 4,
"target" : 34962
}, {
"buffer" : 1,
"byteOffset" : 0,
"byteLength" : 48
} ],
"materials" : [ {
"pbrMetallicRoughness" : {
"baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ],
"metallicFactor" : 0.0,
"roughnessFactor" : 1.0
},
"alphaMode" : "OPAQUE",
"doubleSided" : true
} ],
"meshes" : [ {
"primitives" : [ {
"extensions" : {
"EXT_mesh_features" : {
"featureIds" : [ {
"featureCount" : 4,
"attribute" : 0,
"propertyTable" : 0
} ]
}
},
"attributes" : {
"POSITION" : 1,
"NORMAL" : 2,
"_FEATURE_ID_0" : 3
},
"indices" : 0,
"material" : 0,
"mode" : 4
} ]
} ],
"nodes" : [ {
"mesh" : 0
} ],
"scene" : 0,
"scenes" : [ {
"nodes" : [ 0 ]
} ]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{
"extensions" : {
"EXT_structural_metadata" : {
"schema" : {
"id": "FeatureIdAttributeAndPropertyTableSchema",
"classes" : {
"exampleMetadataClass" : {
"name" : "Example metadata class",
"description" : "An example metadata class",
"properties" : {
"example_VEC3_FLOAT32" : {
"name" : "Example VEC3 FLOAT32 property",
"description" : "An example property, with type VEC3, with component type FLOAT32",
"type" : "VEC3",
"componentType" : "FLOAT32"
}
}
}
}
},
"propertyTables" : [ {
"name" : "Example property table",
"class" : "exampleMetadataClass",
"count" : 4,
"properties" : {
"example_VEC3_FLOAT32" : {
"values" : 4
}
}
} ]
}
},
"extensionsUsed" : [ "EXT_mesh_features", "EXT_structural_metadata" ],
"accessors" : [ {
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 24,
"type" : "SCALAR",
"max" : [ 15 ],
"min" : [ 0 ]
}, {
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 16,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
}, {
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 16,
"type" : "VEC3",
"max" : [ 0.0, 0.0, 1.0 ],
"min" : [ 0.0, 0.0, 1.0 ]
}, {
"bufferView" : 3,
"byteOffset" : 0,
"componentType" : 5121,
"count" : 16,
"type" : "SCALAR",
"max" : [ 3 ],
"min" : [ 0 ]
} ],
"asset" : {
"generator" : "JglTF from https://github.com/javagl/JglTF",
"version" : "2.0"
},
"buffers" : [ {
"uri" : "data:application/gltf-buffer;base64,AAABAAIAAQADAAIABAAFAAYABQAHAAYACAAJAAoACQALAAoADAANAA4ADQAPAA4AAAAAAAAAAAAAAAAAZmbmPgAAAAAAAAAAAAAAAGZm5j4AAAAAZmbmPmZm5j4AAAAAzcwMPwAAAAAAAAAAAACAPwAAAAAAAAAAzcwMP2Zm5j4AAAAAAACAP2Zm5j4AAAAAAAAAAM3MDD8AAAAAZmbmPs3MDD8AAAAAAAAAAAAAgD8AAAAAZmbmPgAAgD8AAAAAzcwMP83MDD8AAAAAAACAP83MDD8AAAAAzcwMPwAAgD8AAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAA==",
"byteLength" : 496
}, {
"uri" : "data:application/gltf-buffer;base64,AAAAAM3MzD3NzEw+AACAP83MjD+amZk/AAAAQGZmBkDNzAxAAABAQGZmRkDNzExA",
"byteLength" : 48
} ],
"bufferViews" : [ {
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 48,
"target" : 34963
}, {
"buffer" : 0,
"byteOffset" : 48,
"byteLength" : 192,
"target" : 34962
}, {
"buffer" : 0,
"byteOffset" : 240,
"byteLength" : 192,
"target" : 34962
}, {
"buffer" : 0,
"byteOffset" : 432,
"byteLength" : 64,
"byteStride" : 4,
"target" : 34962
}, {
"buffer" : 1,
"byteOffset" : 0,
"byteLength" : 48
} ],
"materials" : [ {
"pbrMetallicRoughness" : {
"baseColorFactor" : [ 0.5, 1.0, 0.5, 1.0 ],
"metallicFactor" : 0.0,
"roughnessFactor" : 1.0
},
"alphaMode" : "OPAQUE",
"doubleSided" : true
} ],
"meshes" : [ {
"primitives" : [ {
"extensions" : {
"EXT_mesh_features" : {
"featureIds" : [ {
"featureCount" : 4,
"attribute" : 0,
"propertyTable" : 12345
} ]
}
},
"attributes" : {
"POSITION" : 1,
"NORMAL" : 2,
"_FEATURE_ID_0" : 3
},
"indices" : 0,
"material" : 0,
"mode" : 4
} ]
} ],
"nodes" : [ {
"mesh" : 0
} ],
"scene" : 0,
"scenes" : [ {
"nodes" : [ 0 ]
} ]
}
Loading
Loading