Discard faces that don't have the same attributes

This commit is contained in:
Sean Lilley 2018-08-30 23:36:28 -04:00
parent 0c897a6847
commit 30bf9095fa
4 changed files with 83 additions and 5 deletions

View File

@ -112,17 +112,17 @@ function loadObj(objPath, options) {
mesh.name = getName(name); mesh.name = getName(name);
node.meshes.push(mesh); node.meshes.push(mesh);
addPrimitive(); addPrimitive();
// Clear the vertex cache for each new mesh
vertexCache = {};
vertexCacheCount = 0;
vertexCount = 0;
} }
function addPrimitive() { function addPrimitive() {
primitive = new Primitive(); primitive = new Primitive();
primitive.material = activeMaterial; primitive.material = activeMaterial;
mesh.primitives.push(primitive); mesh.primitives.push(primitive);
// Clear the vertex cache for each new primitive
vertexCache = {};
vertexCacheCount = 0;
vertexCount = 0;
} }
function useMaterial(name) { function useMaterial(name) {
@ -373,6 +373,17 @@ function loadObj(objPath, options) {
var isWindingCorrect = true; var isWindingCorrect = true;
var faceNormal; var faceNormal;
var firstFace = primitive.indices.length === 0;
var faceHasUvs = uvs[0].length > 0;
var faceHasNormals = normals[0].length > 0;
var primitiveHasUvs = primitive.uvs.length > 0;
var primitiveHasNormals = primitive.normals.length > 0;
if (!firstFace && (faceHasUvs !== primitiveHasUvs || faceHasNormals !== primitiveHasNormals)) {
// Discard faces that don't use the same attributes
return;
}
// If normals are defined, find a face normal to use in winding order sanitization. // If normals are defined, find a face normal to use in winding order sanitization.
// If no face normal, we have to assume the winding is correct. // If no face normal, we have to assume the winding is correct.
if (normals[0].length > 0) { if (normals[0].length > 0) {

View File

@ -0,0 +1,12 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 0.100000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.100000
Ni 1.000000
d 1.000000
illum 2

View File

@ -0,0 +1,46 @@
# Blender v2.78 (sub 0) OBJ File: ''
# www.blender.org
mtllib box-mixed-attributes.mtl
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 -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
usemtl Material
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3 4 8 7
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 7//5 5//5 1//5
f 8/19 4/6 2/15 6/20

View File

@ -38,6 +38,7 @@ var objWindowsPaths = 'specs/data/box-windows-paths/box-windows-paths.obj';
var objInvalidContentsPath = 'specs/data/box/box.mtl'; var objInvalidContentsPath = 'specs/data/box/box.mtl';
var objConcavePath = 'specs/data/concave/concave.obj'; var objConcavePath = 'specs/data/concave/concave.obj';
var objUnnormalizedPath = 'specs/data/box-unnormalized/box-unnormalized.obj'; var objUnnormalizedPath = 'specs/data/box-unnormalized/box-unnormalized.obj';
var objMixedAttributesPath = 'specs/data/box-mixed-attributes/box-mixed-attributes.obj';
var objInvalidPath = 'invalid.obj'; var objInvalidPath = 'invalid.obj';
function getMeshes(data) { function getMeshes(data) {
@ -486,6 +487,14 @@ describe('loadObj', function() {
}), done).toResolve(); }), done).toResolve();
}); });
it('discards faces that don\'t use the same attributes as other faces in the primitive', function(done) {
expect(loadObj(objMixedAttributesPath, options)
.then(function(data) {
var primitive = getPrimitives(data)[0];
expect(primitive.indices.length).toBe(18); // 3 faces removed
}), done).toResolve();
});
it('throws when file has invalid contents', function(done) { it('throws when file has invalid contents', function(done) {
expect(loadObj(objInvalidContentsPath, options), done).toRejectWith(RuntimeError); expect(loadObj(objInvalidContentsPath, options), done).toRejectWith(RuntimeError);
}); });