Check for incomplete attributes

This commit is contained in:
Sean Lilley 2019-10-27 15:00:35 -04:00
parent 2a7f0e5c7b
commit e7bd6d6461
6 changed files with 144 additions and 1 deletions

View File

@ -196,6 +196,9 @@ function loadObj(objPath, options) {
function createVertex(p, u, n) {
// Positions
if (defined(p) && (globalPositions.length > 0)) {
if (p * 3 >= globalPositions.length) {
throw new RuntimeError(`Position index ${p} is out of bounds`);
}
const px = globalPositions.get(p * 3);
const py = globalPositions.get(p * 3 + 1);
const pz = globalPositions.get(p * 3 + 2);
@ -206,6 +209,9 @@ function loadObj(objPath, options) {
// Normals
if (defined(n) && (globalNormals.length > 0)) {
if (n * 3 >= globalNormals.length) {
throw new RuntimeError(`Normal index ${n} is out of bounds`);
}
const nx = globalNormals.get(n * 3);
const ny = globalNormals.get(n * 3 + 1);
const nz = globalNormals.get(n * 3 + 2);
@ -216,6 +222,9 @@ function loadObj(objPath, options) {
// UVs
if (defined(u) && (globalUvs.length > 0)) {
if (u * 2 >= globalUvs.length) {
throw new RuntimeError(`UV index ${u} is out of bounds`);
}
const ux = globalUvs.get(u * 2);
const uy = globalUvs.get(u * 2 + 1);
primitive.uvs.push(ux);

View File

@ -23,6 +23,15 @@ function readLines(path, callback) {
const lineReader = readline.createInterface({
input : stream
});
lineReader.on('line', callback);
const callbackWrapper = function(line) {
try {
callback(line);
} catch (error) {
reject(error);
}
};
lineReader.on('line', callbackWrapper);
});
}

View File

@ -0,0 +1,36 @@
o Cube
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 0.0000
vt 0.0000 1.0000
vn 0.000000 0.000000 1.000000
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/5/2 4/6/2 8/7/2 7/8/2
f 7/9/3 8/10/3 6/11/3 5/12/3
f 5/13/4 6/14/4 2/15/4 1/16/4
f 3/5/5 7/17/5 5/18/5 1/16/5
f 8/19/6 4/6/6 2/15/6 6/20/6

View File

@ -0,0 +1,34 @@
o Cube
v -1.000000 -1.000000 1.000000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 0.0000
vt 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/5/2 4/6/2 8/7/2 7/8/2
f 7/9/3 8/10/3 6/11/3 5/12/3
f 5/13/4 6/14/4 2/15/4 1/16/4
f 3/5/5 7/17/5 5/18/5 1/16/5
f 8/19/6 4/6/6 2/15/6 6/20/6

View File

@ -0,0 +1,22 @@
o Cube
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vt 0.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/5/2 4/6/2 8/7/2 7/8/2
f 7/9/3 8/10/3 6/11/3 5/12/3
f 5/13/4 6/14/4 2/15/4 1/16/4
f 3/5/5 7/17/5 5/18/5 1/16/5
f 8/19/6 4/6/6 2/15/6 6/20/6

View File

@ -42,6 +42,9 @@ const objConcavePath = 'specs/data/concave/concave.obj';
const objUnnormalizedPath = 'specs/data/box-unnormalized/box-unnormalized.obj';
const objMixedAttributesPath = 'specs/data/box-mixed-attributes/box-mixed-attributes.obj';
const objMissingAttributesPath = 'specs/data/box-missing-attributes/box-missing-attributes.obj';
const objIncompletePositionsPath = 'specs/data/box-incomplete-attributes/box-incomplete-positions.obj'
const objIncompleteNormalsPath = 'specs/data/box-incomplete-attributes/box-incomplete-normals.obj'
const objIncompleteUvsPath = 'specs/data/box-incomplete-attributes/box-incomplete-uvs.obj'
const objInvalidPath = 'invalid.obj';
function getMeshes(data) {
@ -505,6 +508,36 @@ describe('loadObj', () => {
expect(primitive.uvs.length).toBe(0);
});
it('throws when position index is out of bounds', async () => {
let thrownError;
try {
await loadObj(objIncompletePositionsPath, options);
} catch (e) {
thrownError = e;
}
expect(thrownError).toEqual(new RuntimeError('Position index 1 is out of bounds'));
});
it('throws when normal index is out of bounds', async () => {
let thrownError;
try {
await loadObj(objIncompleteNormalsPath, options);
} catch (e) {
thrownError = e;
}
expect(thrownError).toEqual(new RuntimeError('Normal index 1 is out of bounds'));
});
it('throws when uv index is out of bounds', async () => {
let thrownError;
try {
await loadObj(objIncompleteUvsPath, options);
} catch (e) {
thrownError = e;
}
expect(thrownError).toEqual(new RuntimeError('UV index 1 is out of bounds'));
});
it('throws when file has invalid contents', async () => {
let thrownError;
try {