diff --git a/examples/triangle_error.obj b/examples/triangle_error.obj new file mode 100644 index 0000000..882a2a7 --- /dev/null +++ b/examples/triangle_error.obj @@ -0,0 +1,15 @@ +# Blender v2.91.0 OBJ File: '' +# www.blender.org +mtllib triangle.mtl +o Plane +v -1.000000 0.000000 0.000000 +v 1.000000 0.000000 1.000000 +v 1.000000 0.000000 -1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vn 0.0000 1.0000 0.0000 +usemtl None +s off +f 1/1/1 2/2/1 3/3/1 +invalid diff --git a/src/obj.zig b/src/obj.zig index 9f852cb..42c3249 100644 --- a/src/obj.zig +++ b/src/obj.zig @@ -141,6 +141,7 @@ pub fn parse(allocator: Allocator, data: []const u8) !ObjData { // current mesh material var current_material: ?MeshMaterial = null; + errdefer if (current_material) |mat| allocator.free(mat.material); var mesh_materials = ArrayList(MeshMaterial).init(allocator); errdefer mesh_materials.deinit(); var num_processed_verts: usize = 0; @@ -297,6 +298,7 @@ const test_allocator = std.testing.allocator; const expect = std.testing.expect; const expectError = std.testing.expectError; +const expectEqual = std.testing.expectEqual; const expectEqualSlices = std.testing.expectEqualSlices; const expectEqualStrings = std.testing.expectEqualStrings; @@ -308,60 +310,60 @@ test "comment" { var result = try parse(test_allocator, "# this is a comment"); defer result.deinit(test_allocator); - try expect(result.vertices.len == 0); - try expect(result.tex_coords.len == 0); - try expect(result.normals.len == 0); - try expect(result.meshes.len == 0); + try expectEqual(0, result.vertices.len); + try expectEqual(0, result.tex_coords.len); + try expectEqual(0, result.normals.len); + try expectEqual(0, result.meshes.len); } test "single vertex def xyz" { var result = try parse(test_allocator, "v 0.123 0.234 0.345"); defer result.deinit(test_allocator); - try expect(std.mem.eql(f32, result.vertices, &[_]f32{ 0.123, 0.234, 0.345 })); - try expect(result.tex_coords.len == 0); - try expect(result.normals.len == 0); - try expect(result.meshes.len == 0); + try expectEqualSlices(f32, &.{ 0.123, 0.234, 0.345 }, result.vertices); + try expectEqual(0, result.tex_coords.len); + try expectEqual(0, result.normals.len); + try expectEqual(0, result.meshes.len); } test "single vertex def xyzw" { var result = try parse(test_allocator, "v 0.123 0.234 0.345 0.456"); defer result.deinit(test_allocator); - try expect(std.mem.eql(f32, result.vertices, &[_]f32{ 0.123, 0.234, 0.345 })); - try expect(result.tex_coords.len == 0); - try expect(result.normals.len == 0); - try expect(result.meshes.len == 0); + try expectEqualSlices(f32, &.{ 0.123, 0.234, 0.345 }, result.vertices); + try expectEqual(0, result.tex_coords.len); + try expectEqual(0, result.normals.len); + try expectEqual(0, result.meshes.len); } test "single tex coord def uv" { var result = try parse(test_allocator, "vt 0.123 0.234"); defer result.deinit(test_allocator); - try expect(std.mem.eql(f32, result.tex_coords, &[_]f32{ 0.123, 0.234 })); - try expect(result.vertices.len == 0); - try expect(result.normals.len == 0); - try expect(result.meshes.len == 0); + try expectEqualSlices(f32, &.{ 0.123, 0.234 }, result.tex_coords); + try expectEqual(0, result.vertices.len); + try expectEqual(0, result.normals.len); + try expectEqual(0, result.meshes.len); } test "single tex coord def uvw" { var result = try parse(test_allocator, "vt 0.123 0.234 0.345"); defer result.deinit(test_allocator); - try expect(std.mem.eql(f32, result.tex_coords, &[_]f32{ 0.123, 0.234 })); - try expect(result.vertices.len == 0); - try expect(result.normals.len == 0); - try expect(result.meshes.len == 0); + try expectEqualSlices(f32, &.{ 0.123, 0.234 }, result.tex_coords); + try expectEqual(0, result.vertices.len); + try expectEqual(0, result.normals.len); + try expectEqual(0, result.meshes.len); } test "single normal def xyz" { var result = try parse(test_allocator, "vn 0.123 0.234 0.345"); defer result.deinit(test_allocator); - try expect(std.mem.eql(f32, result.normals, &[_]f32{ 0.123, 0.234, 0.345 })); - try expect(result.vertices.len == 0); - try expect(result.tex_coords.len == 0); - try expect(result.meshes.len == 0); + try expectEqualSlices(f32, &.{ 0.123, 0.234, 0.345 }, result.normals); + try expectEqual(0, result.vertices.len); + try expectEqual(0, result.tex_coords.len); + try expectEqual(0, result.meshes.len); } test "single face def vertex only" { @@ -378,7 +380,7 @@ test "single face def vertex only" { }, .materials = &[_]MeshMaterial{}, }; - try expect(result.meshes.len == 1); + try expectEqual(1, result.meshes.len); try expect(result.meshes[0].eq(mesh)); } @@ -396,7 +398,7 @@ test "single face def vertex + tex coord" { }, .materials = &[_]MeshMaterial{}, }; - try expect(result.meshes.len == 1); + try expectEqual(1, result.meshes.len); try expect(result.meshes[0].eq(mesh)); } @@ -414,7 +416,7 @@ test "single face def vertex + tex coord + normal" { }, .materials = &[_]MeshMaterial{}, }; - try expect(result.meshes.len == 1); + try expectEqual(1, result.meshes.len); try expect(result.meshes[0].eq(mesh)); } @@ -432,7 +434,7 @@ test "single face def vertex + normal" { }, .materials = &[_]MeshMaterial{}, }; - try expect(result.meshes.len == 1); + try expectEqual(1, result.meshes.len); try expect(result.meshes[0].eq(expected)); } @@ -462,7 +464,7 @@ test "multiple materials in one mesh" { }, }; - try expect(result.meshes.len == 1); + try expectEqual(1, result.meshes.len); try expect(result.meshes[0].eq(expected)); } @@ -500,14 +502,14 @@ test "triangle obj exported from blender" { }, }, }; - try expect(result.material_libs.len == 1); - try expectEqualStrings(result.material_libs[0], expected.material_libs[0]); + try expectEqual(1, result.material_libs.len); + try expectEqualStrings(expected.material_libs[0], result.material_libs[0]); - try expectEqualSlices(f32, result.vertices, expected.vertices); - try expectEqualSlices(f32, result.tex_coords, expected.tex_coords); - try expectEqualSlices(f32, result.normals, expected.normals); + try expectEqualSlices(f32, expected.vertices, result.vertices); + try expectEqualSlices(f32, expected.tex_coords, result.tex_coords); + try expectEqualSlices(f32, expected.normals, result.normals); - try expect(result.meshes.len == 1); + try expectEqual(1, result.meshes.len); try expect(result.meshes[0].eq(expected.meshes[0])); } @@ -545,17 +547,22 @@ test "triangle obj exported from blender (windows line endings)" { }, }, }; - try expect(result.material_libs.len == 1); - try expectEqualStrings(result.material_libs[0], expected.material_libs[0]); + try expectEqual(1, result.material_libs.len); + try expectEqualStrings(expected.material_libs[0], result.material_libs[0]); - try expectEqualSlices(f32, result.vertices, expected.vertices); - try expectEqualSlices(f32, result.tex_coords, expected.tex_coords); - try expectEqualSlices(f32, result.normals, expected.normals); + try expectEqualSlices(f32, expected.vertices, result.vertices); + try expectEqualSlices(f32, expected.tex_coords, result.tex_coords); + try expectEqualSlices(f32, expected.normals, result.normals); - try expect(result.meshes.len == 1); + try expectEqual(1, result.meshes.len); try expect(result.meshes[0].eq(expected.meshes[0])); } +test "triangle obj exported from blender (with error)" { + const data = @embedFile("../examples/triangle_error.obj"); + try expectError(error.UnknownDefType, parse(test_allocator, data)); +} + test "cube obj exported from blender" { const data = @embedFile("../examples/cube.obj"); @@ -633,14 +640,14 @@ test "cube obj exported from blender" { }, }; - try expect(result.material_libs.len == 1); - try expectEqualStrings(result.material_libs[0], expected.material_libs[0]); + try expectEqual(1, result.material_libs.len); + try expectEqualStrings(expected.material_libs[0], result.material_libs[0]); - try expectEqualSlices(f32, result.vertices, expected.vertices); - try expectEqualSlices(f32, result.tex_coords, expected.tex_coords); - try expectEqualSlices(f32, result.normals, expected.normals); + try expectEqualSlices(f32, expected.vertices, result.vertices); + try expectEqualSlices(f32, expected.tex_coords, result.tex_coords); + try expectEqualSlices(f32, expected.normals, result.normals); - try expect(result.meshes.len == 1); + try expectEqual(1, result.meshes.len); try expect(result.meshes[0].eq(expected.meshes[0])); }