diff options
Diffstat (limited to 'source/blender/io/wavefront_obj/tests')
5 files changed, 537 insertions, 267 deletions
diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc index 6aec848573f..dcba78ac99e 100644 --- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc @@ -60,7 +60,7 @@ TEST_F(obj_exporter_test, filter_objects_curves_as_mesh) return; } auto [objmeshes, objcurves]{filter_supported_objects(depsgraph, _export.params)}; - EXPECT_EQ(objmeshes.size(), 20); + EXPECT_EQ(objmeshes.size(), 21); EXPECT_EQ(objcurves.size(), 0); } @@ -185,17 +185,17 @@ TEST(obj_exporter_writer, mtllib) TEST(obj_exporter_writer, format_handler_buffer_chunking) { /* Use a tiny buffer chunk size, so that the test below ends up creating several blocks. */ - FormatHandler<eFileType::OBJ, 16> h; - h.write<eOBJSyntaxElement::object_name>("abc"); - h.write<eOBJSyntaxElement::object_name>("abcd"); - h.write<eOBJSyntaxElement::object_name>("abcde"); - h.write<eOBJSyntaxElement::object_name>("abcdef"); - h.write<eOBJSyntaxElement::object_name>("012345678901234567890123456789abcd"); - h.write<eOBJSyntaxElement::object_name>("123"); - h.write<eOBJSyntaxElement::curve_element_begin>(); - h.write<eOBJSyntaxElement::new_line>(); - h.write<eOBJSyntaxElement::nurbs_parameter_begin>(); - h.write<eOBJSyntaxElement::new_line>(); + FormatHandler h(16); + h.write_obj_object("abc"); + h.write_obj_object("abcd"); + h.write_obj_object("abcde"); + h.write_obj_object("abcdef"); + h.write_obj_object("012345678901234567890123456789abcd"); + h.write_obj_object("123"); + h.write_obj_curve_begin(); + h.write_obj_newline(); + h.write_obj_nurbs_parm_begin(); + h.write_obj_newline(); size_t got_blocks = h.get_block_count(); ASSERT_EQ(got_blocks, 7); @@ -527,4 +527,27 @@ TEST_F(obj_exporter_regression_test, all_objects_mat_groups) _export.params); } +TEST_F(obj_exporter_regression_test, materials_without_pbr) +{ + OBJExportParamsDefault _export; + _export.params.export_normals = false; + _export.params.path_mode = PATH_REFERENCE_RELATIVE; + compare_obj_export_to_golden("io_tests/blend_geometry/materials_pbr.blend", + "io_tests/obj/materials_without_pbr.obj", + "io_tests/obj/materials_without_pbr.mtl", + _export.params); +} + +TEST_F(obj_exporter_regression_test, materials_pbr) +{ + OBJExportParamsDefault _export; + _export.params.export_normals = false; + _export.params.path_mode = PATH_REFERENCE_RELATIVE; + _export.params.export_pbr_extensions = true; + compare_obj_export_to_golden("io_tests/blend_geometry/materials_pbr.blend", + "io_tests/obj/materials_pbr.obj", + "io_tests/obj/materials_pbr.mtl", + _export.params); +} + } // namespace blender::io::obj diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh index 7d3b41ed527..006d86312b6 100644 --- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh +++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh @@ -31,6 +31,7 @@ struct OBJExportParamsDefault { params.path_mode = PATH_REFERENCE_AUTO; params.export_triangulated_mesh = false; params.export_curves_as_nurbs = false; + params.export_pbr_extensions = false; params.export_object_groups = false; params.export_material_groups = false; diff --git a/source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc b/source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc index 46e093bb8a7..dc1cfd2b449 100644 --- a/source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc @@ -10,17 +10,34 @@ namespace blender::io::obj { TEST(obj_import_string_utils, read_next_line) { - std::string str = "abc\n \n\nline with \\\ncontinuation\nCRLF ending:\r\na"; + std::string str = "abc\n \n\nline with \t spaces\nCRLF ending:\r\na"; StringRef s = str; EXPECT_STRREF_EQ("abc", read_next_line(s)); EXPECT_STRREF_EQ(" ", read_next_line(s)); EXPECT_STRREF_EQ("", read_next_line(s)); - EXPECT_STRREF_EQ("line with \\\ncontinuation", read_next_line(s)); + EXPECT_STRREF_EQ("line with \t spaces", read_next_line(s)); EXPECT_STRREF_EQ("CRLF ending:\r", read_next_line(s)); EXPECT_STRREF_EQ("a", read_next_line(s)); EXPECT_TRUE(s.is_empty()); } +TEST(obj_import_string_utils, fixup_line_continuations) +{ + const char *str = + "backslash \\\n eol\n" + "backslash spaces \\ \n eol\n" + "without eol \\ is \\\\ \\ left intact\n" + "\\"; + const char *exp = + "backslash eol\n" + "backslash spaces eol\n" + "without eol \\ is \\\\ \\ left intact\n" + "\\"; + std::string buf(str); + fixup_line_continuations(buf.data(), buf.data() + buf.size()); + EXPECT_STRREF_EQ(exp, buf); +} + static StringRef drop_whitespace(StringRef s) { return StringRef(drop_whitespace(s.begin(), s.end()), s.end()); @@ -29,9 +46,14 @@ static StringRef parse_int(StringRef s, int fallback, int &dst, bool skip_space { return StringRef(parse_int(s.begin(), s.end(), fallback, dst, skip_space), s.end()); } -static StringRef parse_float(StringRef s, float fallback, float &dst, bool skip_space = true) +static StringRef parse_float(StringRef s, + float fallback, + float &dst, + bool skip_space = true, + bool require_trailing_space = false) { - return StringRef(parse_float(s.begin(), s.end(), fallback, dst, skip_space), s.end()); + return StringRef( + parse_float(s.begin(), s.end(), fallback, dst, skip_space, require_trailing_space), s.end()); } TEST(obj_import_string_utils, drop_whitespace) @@ -49,7 +71,7 @@ TEST(obj_import_string_utils, drop_whitespace) /* No leading whitespace */ EXPECT_STRREF_EQ("c", drop_whitespace("c")); /* Case with backslash, should be treated as whitespace */ - EXPECT_STRREF_EQ("d", drop_whitespace(" \\ d")); + EXPECT_STRREF_EQ("d", drop_whitespace(" \t d")); } TEST(obj_import_string_utils, parse_int_valid) @@ -126,6 +148,9 @@ TEST(obj_import_string_utils, parse_float_invalid) /* Has leading white-space when we don't expect it */ EXPECT_STRREF_EQ(" 1", parse_float(" 1", -4.0f, val, false)); EXPECT_EQ(val, -4.0f); + /* Has trailing non-number characters when we don't want them */ + EXPECT_STRREF_EQ("123.5.png", parse_float(" 123.5.png", -5.0f, val, true, true)); + EXPECT_EQ(val, -5.0f); } } // namespace blender::io::obj diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc index b67adbc9753..99e12aed99c 100644 --- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc @@ -8,11 +8,12 @@ #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_scene.h" #include "BLI_listbase.h" -#include "BLI_math_base.h" +#include "BLI_math_base.hh" #include "BLI_math_vec_types.hh" #include "BLO_readfile.h" @@ -47,7 +48,8 @@ class obj_importer_test : public BlendfileLoadingBaseTest { void import_and_check(const char *path, const Expectation *expect, size_t expect_count, - int expect_mat_count) + int expect_mat_count, + int expect_image_count = 0) { if (!blendfile_load("io_tests/blend_geometry/all_quads.blend")) { ADD_FAILURE(); @@ -58,6 +60,10 @@ class obj_importer_test : public BlendfileLoadingBaseTest { params.clamp_size = 0; params.forward_axis = IO_AXIS_NEGATIVE_Z; params.up_axis = IO_AXIS_Y; + params.validate_meshes = true; + params.import_vertex_groups = false; + params.relative_paths = true; + params.clear_selection = true; std::string obj_path = blender::tests::flags_test_asset_dir() + "/io_tests/obj/" + path; strncpy(params.filepath, obj_path.c_str(), FILE_MAX - 1); @@ -90,8 +96,9 @@ class obj_importer_test : public BlendfileLoadingBaseTest { EXPECT_EQ(mesh->totedge, exp.mesh_totedge_or_curve_endp); EXPECT_EQ(mesh->totpoly, exp.mesh_totpoly_or_curve_order); EXPECT_EQ(mesh->totloop, exp.mesh_totloop_or_curve_cyclic); - EXPECT_V3_NEAR(mesh->mvert[0].co, exp.vert_first, 0.0001f); - EXPECT_V3_NEAR(mesh->mvert[mesh->totvert - 1].co, exp.vert_last, 0.0001f); + const Span<MVert> verts = mesh->verts(); + EXPECT_V3_NEAR(verts.first().co, exp.vert_first, 0.0001f); + EXPECT_V3_NEAR(verts.last().co, exp.vert_last, 0.0001f); const float3 *lnors = (const float3 *)(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); float3 normal_first = lnors != nullptr ? lnors[0] : float3(0, 0, 0); EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f); @@ -130,12 +137,12 @@ class obj_importer_test : public BlendfileLoadingBaseTest { DEG_OBJECT_ITER_END; EXPECT_EQ(object_index, expect_count); - /* Count number of materials. */ - int mat_count = 0; - LISTBASE_FOREACH (ID *, id, &bfile->main->materials) { - ++mat_count; - } + /* Check number of materials & textures. */ + const int mat_count = BLI_listbase_count(&bfile->main->materials); EXPECT_EQ(mat_count, expect_mat_count); + + const int ima_count = BLI_listbase_count(&bfile->main->images); + EXPECT_EQ(ima_count, expect_image_count); } }; @@ -156,6 +163,36 @@ TEST_F(obj_importer_test, import_cube) import_and_check("cube.obj", expect, std::size(expect), 1); } +TEST_F(obj_importer_test, import_cube_o_after_verts) +{ + Expectation expect[] = { + {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + { + "OBActualCube", + OB_MESH, + 8, + 12, + 6, + 24, + float3(-1, -1, 1), + float3(1, -1, -1), + float3(0, 0, 1), + }, + { + "OBSparseTri", + OB_MESH, + 3, + 3, + 1, + 3, + float3(1, -1, 1), + float3(-2, -2, 2), + float3(-0.2357f, 0.9428f, 0.2357f), + }, + }; + import_and_check("cube_o_after_verts.obj", expect, std::size(expect), 2); +} + TEST_F(obj_importer_test, import_suzanne_all_data) { Expectation expect[] = { @@ -194,7 +231,9 @@ TEST_F(obj_importer_test, import_nurbs_curves) { Expectation expect[] = { {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + {"OBCurveDeg3", OB_CURVES_LEGACY, 4, 0, 3, 0, float3(10, -2, 0), float3(6, -2, 0)}, {"OBnurbs_curves", OB_CURVES_LEGACY, 4, 0, 4, 0, float3(2, -2, 0), float3(-2, -2, 0)}, + {"OBNurbsCurveCyclic", OB_CURVES_LEGACY, 7, 0, 4, 1, float3(-2, -2, 0), float3(-6, 2, 0)}, {"OBNurbsCurveDiffWeights", OB_CURVES_LEGACY, 4, @@ -203,7 +242,6 @@ TEST_F(obj_importer_test, import_nurbs_curves) 0, float3(6, -2, 0), float3(2, -2, 0)}, - {"OBNurbsCurveCyclic", OB_CURVES_LEGACY, 7, 0, 4, 1, float3(-2, -2, 0), float3(-6, 2, 0)}, {"OBNurbsCurveEndpoint", OB_CURVES_LEGACY, 4, @@ -212,7 +250,6 @@ TEST_F(obj_importer_test, import_nurbs_curves) 0, float3(-6, -2, 0), float3(-10, -2, 0)}, - {"OBCurveDeg3", OB_CURVES_LEGACY, 4, 0, 3, 0, float3(10, -2, 0), float3(6, -2, 0)}, }; import_and_check("nurbs_curves.obj", expect, std::size(expect), 0); } @@ -237,7 +274,8 @@ TEST_F(obj_importer_test, import_nurbs_manual) { Expectation expect[] = { {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, - {"OBCurve_Uniform_Parm", OB_CURVES_LEGACY, 5, 0, 4, 0, float3(-2, 0, 2), float3(-2, 0, 2)}, + {"OBCurve_Cyclic", OB_CURVES_LEGACY, 7, 0, 4, 1, float3(-2, 0, 2), float3(2, 0, -2)}, + {"OBCurve_Endpoints", OB_CURVES_LEGACY, 5, 1, 4, 0, float3(-2, 0, 2), float3(-2, 0, 2)}, {"OBCurve_NonUniform_Parm", OB_CURVES_LEGACY, 5, @@ -246,8 +284,7 @@ TEST_F(obj_importer_test, import_nurbs_manual) 0, float3(-2, 0, 2), float3(-2, 0, 2)}, - {"OBCurve_Endpoints", OB_CURVES_LEGACY, 5, 1, 4, 0, float3(-2, 0, 2), float3(-2, 0, 2)}, - {"OBCurve_Cyclic", OB_CURVES_LEGACY, 7, 0, 4, 1, float3(-2, 0, 2), float3(2, 0, -2)}, + {"OBCurve_Uniform_Parm", OB_CURVES_LEGACY, 5, 0, 4, 0, float3(-2, 0, 2), float3(-2, 0, 2)}, }; import_and_check("nurbs_manual.obj", expect, std::size(expect), 0); } @@ -256,7 +293,7 @@ TEST_F(obj_importer_test, import_nurbs_mesh) { Expectation expect[] = { {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, - {"OBTorus Knot", + {"OBTorus_Knot", OB_MESH, 108, 108, @@ -274,30 +311,69 @@ TEST_F(obj_importer_test, import_materials) {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, {"OBmaterials", OB_MESH, 8, 12, 6, 24, float3(-1, -1, 1), float3(1, -1, -1)}, }; - import_and_check("materials.obj", expect, std::size(expect), 4); + import_and_check("materials.obj", expect, std::size(expect), 4, 8); } -TEST_F(obj_importer_test, import_faces_invalid_or_with_holes) +TEST_F(obj_importer_test, import_cubes_with_textures_rel) { Expectation expect[] = { {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, - {"OBFaceWithHole_BecomesTwoFacesFormingAHole", + {"OBCube4Tex", OB_MESH, 8, - 10, - 2, 12, - float3(-2, 0, -2), - float3(1, 0, -1)}, - {"OBFaceQuadDupSomeVerts_BecomesOneQuadUsing4Verts", + 6, + 24, + float3(1, 1, -1), + float3(-1, -1, 1), + float3(0, 1, 0), + float2(0.9935f, 0.0020f)}, + {"OBCubeTexMul", OB_MESH, 8, - 4, + 12, + 6, + 24, + float3(4, -2, -1), + float3(2, -4, 1), + float3(0, 1, 0), + float2(0.9935f, 0.0020f)}, + {"OBCubeTiledTex", + OB_MESH, + 8, + 12, + 6, + 24, + float3(4, 1, -1), + float3(2, -1, 1), + float3(0, 1, 0), + float2(0.9935f, 0.0020f)}, + {"OBCubeTiledTexFromAnotherFolder", + OB_MESH, + 8, + 12, + 6, + 24, + float3(7, 1, -1), + float3(5, -1, 1), + float3(0, 1, 0), + float2(0.9935f, 0.0020f)}, + }; + import_and_check("cubes_with_textures_rel.obj", expect, std::size(expect), 4, 4); +} + +TEST_F(obj_importer_test, import_faces_invalid_or_with_holes) +{ + Expectation expect[] = { + {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + {"OBFaceAllVerts_BecomesOneOverlappingFaceUsingAllVerts", + OB_MESH, + 8, + 8, 1, - 4, - float3(3, 0, -2), - float3(6, 0, -1)}, - {"OBFaceTriDupVert_Becomes1Tri", OB_MESH, 8, 3, 1, 3, float3(-2, 0, 3), float3(1, 0, 4)}, + 8, + float3(8, 0, -2), + float3(11, 0, -1)}, {"OBFaceAllVertsDup_BecomesOneOverlappingFaceUsingAllVerts", OB_MESH, 8, @@ -306,15 +382,24 @@ TEST_F(obj_importer_test, import_faces_invalid_or_with_holes) 8, float3(3, 0, 3), float3(6, 0, 4)}, - {"OBFaceAllVerts_BecomesOneOverlappingFaceUsingAllVerts", + {"OBFaceJustTwoVerts_IsSkipped", OB_MESH, 2, 0, 0, 0, float3(8, 0, 3), float3(8, 0, 7)}, + {"OBFaceQuadDupSomeVerts_BecomesOneQuadUsing4Verts", OB_MESH, - 8, - 8, + 4, + 4, 1, + 4, + float3(3, 0, -2), + float3(7, 0, -2)}, + {"OBFaceTriDupVert_Becomes1Tri", OB_MESH, 3, 3, 1, 3, float3(-2, 0, 3), float3(2, 0, 7)}, + {"OBFaceWithHole_BecomesTwoFacesFormingAHole", + OB_MESH, 8, - float3(8, 0, -2), - float3(11, 0, -1)}, - {"OBFaceJustTwoVerts_IsSkipped", OB_MESH, 8, 0, 0, 0, float3(8, 0, 3), float3(11, 0, 4)}, + 10, + 2, + 12, + float3(-2, 0, -2), + float3(1, 0, -1)}, }; import_and_check("faces_invalid_or_with_holes.obj", expect, std::size(expect), 0); } @@ -325,12 +410,12 @@ TEST_F(obj_importer_test, import_invalid_indices) {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, {"OBQuad", OB_MESH, - 4, + 3, 3, 1, 3, float3(-2, 0, -2), - float3(2, 0, -2), + float3(2, 0, 2), float3(0, 1, 0), float2(0.5f, 0.25f)}, }; @@ -343,12 +428,12 @@ TEST_F(obj_importer_test, import_invalid_syntax) {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, {"OBObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLon", OB_MESH, - 10, /* NOTE: right now parses some invalid obj syntax as valid vertices. */ + 3, 3, 1, 3, float3(1, 2, 3), - float3(10, 11, 12), + float3(7, 8, 9), float3(0, 1, 0), float2(0.5f, 0.25f)}, }; @@ -360,6 +445,63 @@ TEST_F(obj_importer_test, import_all_objects) Expectation expect[] = { {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, /* .obj file has empty EmptyText and EmptyMesh objects; these are ignored and skipped */ + {"OBBezierCurve", OB_MESH, 13, 12, 0, 0, float3(-1, -2, 0), float3(1, -2, 0)}, + {"OBBlankCube", OB_MESH, 8, 13, 7, 26, float3(1, 1, -1), float3(-1, 1, 1), float3(0, 0, 1)}, + {"OBMaterialCube", + OB_MESH, + 8, + 13, + 7, + 26, + float3(28, 1, -1), + float3(26, 1, 1), + float3(-1, 0, 0)}, + {"OBNurbsCircle", + OB_MESH, + 96, + 96, + 0, + 0, + float3(3.292893f, -2.707107f, 0), + float3(3.369084f, -2.77607f, 0)}, + {"OBNurbsCircle.001", OB_MESH, 4, 4, 0, 0, float3(2, -3, 0), float3(3, -2, 0)}, + {"OBParticleCube", + OB_MESH, + 8, + 13, + 7, + 26, + float3(22, 1, -1), + float3(20, 1, 1), + float3(0, 0, 1)}, + {"OBShapeKeyCube", + OB_MESH, + 8, + 13, + 7, + 26, + float3(19, 1, -1), + float3(17, 1, 1), + float3(-0.4082f, -0.4082f, 0.8165f)}, + {"OBSmoothCube", + OB_MESH, + 8, + 13, + 7, + 26, + float3(4, 1, -1), + float3(2, 1, 1), + float3(0.5774f, 0.5773f, 0.5774f)}, + {"OBSurface", + OB_MESH, + 256, + 480, + 224, + 896, + float3(7.292893f, -2.707107f, -1), + float3(7.525872f, -2.883338f, 1), + float3(-0.7071f, -0.7071f, 0), + float2(0, 0.142857f)}, {"OBSurfPatch", OB_MESH, 256, @@ -380,24 +522,16 @@ TEST_F(obj_importer_test, import_all_objects) float3(11, -2, 1), float3(-0.0541f, -0.0541f, -0.9971f), float2(0, 1)}, - {"OBSmoothCube", - OB_MESH, - 8, - 13, - 7, - 26, - float3(4, 1, -1), - float3(2, 1, 1), - float3(0.5774f, 0.5773f, 0.5774f)}, - {"OBMaterialCube", + {"OBSurfTorus.001", OB_MESH, - 8, - 13, - 7, - 26, - float3(28, 1, -1), - float3(26, 1, 1), - float3(-1, 0, 0)}, + 1024, + 2048, + 1024, + 4096, + float3(5.34467f, -2.65533f, -0.176777f), + float3(5.232792f, -2.411795f, -0.220835f), + float3(-0.5042f, -0.5042f, -0.7011f), + float2(0, 1)}, {"OBTaperCube", OB_MESH, 106, @@ -407,24 +541,26 @@ TEST_F(obj_importer_test, import_all_objects) float3(24.444445f, 0.502543f, -0.753814f), float3(23.790743f, 0.460522f, -0.766546f), float3(-0.0546f, 0.1716f, 0.9837f)}, - {"OBParticleCube", + {"OBText", OB_MESH, - 8, - 13, - 7, - 26, - float3(22, 1, -1), - float3(20, 1, 1), - float3(0, 0, 1)}, - {"OBShapeKeyCube", + 177, + 345, + 171, + 513, + float3(1.75f, -9.458f, 0), + float3(0.587f, -9.406f, 0), + float3(0, 0, 1), + float2(0.017544f, 0)}, + {"OBUVCube", OB_MESH, 8, 13, 7, 26, - float3(19, 1, -1), - float3(17, 1, 1), - float3(-0.4082f, -0.4082f, 0.8165f)}, + float3(7, 1, -1), + float3(5, 1, 1), + float3(0, 0, 1), + float2(0.654526f, 0.579873f)}, {"OBUVImageCube", OB_MESH, 8, @@ -435,15 +571,6 @@ TEST_F(obj_importer_test, import_all_objects) float3(8, 1, 1), float3(0, 0, 1), float2(0.654526f, 0.579873f)}, - {"OBVGroupCube", - OB_MESH, - 8, - 13, - 7, - 26, - float3(16, 1, -1), - float3(14, 1, 1), - float3(0, 0, 1)}, {"OBVColCube", OB_MESH, 8, @@ -455,57 +582,15 @@ TEST_F(obj_importer_test, import_all_objects) float3(0, 0, 1), float2(0, 0), float4(0.0f, 0.002125f, 1.0f, 1.0f)}, - {"OBUVCube", + {"OBVGroupCube", OB_MESH, 8, 13, 7, 26, - float3(7, 1, -1), - float3(5, 1, 1), - float3(0, 0, 1), - float2(0.654526f, 0.579873f)}, - {"OBNurbsCircle.001", OB_MESH, 4, 4, 0, 0, float3(2, -3, 0), float3(3, -2, 0)}, - {"OBSurface", - OB_MESH, - 256, - 480, - 224, - 896, - float3(7.292893f, -2.707107f, -1), - float3(7.525872f, -2.883338f, 1), - float3(-0.7071f, -0.7071f, 0), - float2(0, 0.142857f)}, - {"OBText", - OB_MESH, - 177, - 345, - 171, - 513, - float3(1.75f, -9.458f, 0), - float3(0.587f, -9.406f, 0), - float3(0, 0, 1), - float2(0.017544f, 0)}, - {"OBSurfTorus.001", - OB_MESH, - 1024, - 2048, - 1024, - 4096, - float3(5.34467f, -2.65533f, -0.176777f), - float3(5.232792f, -2.411795f, -0.220835f), - float3(-0.5042f, -0.5042f, -0.7011f), - float2(0, 1)}, - {"OBNurbsCircle", - OB_MESH, - 96, - 96, - 0, - 0, - float3(3.292893f, -2.707107f, 0), - float3(3.369084f, -2.77607f, 0)}, - {"OBBezierCurve", OB_MESH, 13, 12, 0, 0, float3(-1, -2, 0), float3(1, -2, 0)}, - {"OBBlankCube", OB_MESH, 8, 13, 7, 26, float3(1, 1, -1), float3(-1, 1, 1), float3(0, 0, 1)}, + float3(16, 1, -1), + float3(14, 1, 1), + float3(0, 0, 1)}, }; import_and_check("all_objects.obj", expect, std::size(expect), 7); } @@ -514,28 +599,6 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors) { Expectation expect[] = { {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, - {"OBCubeVertexByte", - OB_MESH, - 8, - 12, - 6, - 24, - float3(1.0f, 1.0f, -1.0f), - float3(-1.0f, -1.0f, 1.0f), - float3(0, 0, 0), - float2(0, 0), - float4(0.846873f, 0.027321f, 0.982123f, 1.0f)}, - {"OBCubeVertexFloat", - OB_MESH, - 8, - 12, - 6, - 24, - float3(3.392028f, 1.0f, -1.0f), - float3(1.392028f, -1.0f, 1.0f), - float3(0, 0, 0), - float2(0, 0), - float4(49.99467f, 0.027321f, 0.982123f, 1.0f)}, {"OBCubeCornerByte", OB_MESH, 8, @@ -577,36 +640,91 @@ TEST_F(obj_importer_test, import_cubes_vertex_colors) 24, float3(-4.550208f, -1.0f, -1.918042f), float3(-2.550208f, 1.0f, -3.918042f)}, + {"OBCubeVertexByte", + OB_MESH, + 8, + 12, + 6, + 24, + float3(1.0f, 1.0f, -1.0f), + float3(-1.0f, -1.0f, 1.0f), + float3(0, 0, 0), + float2(0, 0), + float4(0.846873f, 0.027321f, 0.982123f, 1.0f)}, + {"OBCubeVertexFloat", + OB_MESH, + 8, + 12, + 6, + 24, + float3(3.392028f, 1.0f, -1.0f), + float3(1.392028f, -1.0f, 1.0f), + float3(0, 0, 0), + float2(0, 0), + float4(49.99467f, 0.027321f, 0.982123f, 1.0f)}, }; import_and_check("cubes_vertex_colors.obj", expect, std::size(expect), 0); } TEST_F(obj_importer_test, import_cubes_vertex_colors_mrgb) { - Expectation expect[] = {{"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, - {"OBCubeXYZRGB", - OB_MESH, - 8, - 12, - 6, - 24, - float3(1, 1, -1), - float3(-1, -1, 1), - float3(0, 0, 0), - float2(0, 0), - float4(0.6038f, 0.3185f, 0.1329f, 1.0f)}, - {"OBCubeMRGB", - OB_MESH, - 8, - 12, - 6, - 24, - float3(4, 1, -1), - float3(2, -1, 1), - float3(0, 0, 0), - float2(0, 0), - float4(0.8714f, 0.6308f, 0.5271f, 1.0f)}}; + Expectation expect[] = { + {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + {"OBCubeMRGB", + OB_MESH, + 8, + 12, + 6, + 24, + float3(4, 1, -1), + float3(2, -1, 1), + float3(0, 0, 0), + float2(0, 0), + float4(0.8714f, 0.6308f, 0.5271f, 1.0f)}, + {"OBCubeXYZRGB", + OB_MESH, + 8, + 12, + 6, + 24, + float3(1, 1, -1), + float3(-1, -1, 1), + float3(0, 0, 0), + float2(0, 0), + float4(0.6038f, 0.3185f, 0.1329f, 1.0f)}, + {"OBTriMRGB", + OB_MESH, + 3, + 3, + 1, + 3, + float3(12, 1, -1), + float3(10, 0, -1), + float3(0, 0, 0), + float2(0, 0), + float4(1.0f, 0.0f, 0.0f, 1.0f)}, + { + "OBTriNoColors", + OB_MESH, + 3, + 3, + 1, + 3, + float3(8, 1, -1), + float3(6, 0, -1), + }, + }; import_and_check("cubes_vertex_colors_mrgb.obj", expect, std::size(expect), 0); } +TEST_F(obj_importer_test, import_vertices) +{ + Expectation expect[] = { + {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + /* Loose vertices without faces or edges. */ + {"OBCube.001", OB_MESH, 8, 0, 0, 0, float3(1, 1, -1), float3(-1, 1, 1)}, + }; + import_and_check("vertices.obj", expect, std::size(expect), 0); +} + } // namespace blender::io::obj diff --git a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc index 068cdc0bf3a..e473d629673 100644 --- a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc @@ -6,6 +6,7 @@ #include "testing/testing.h" +#include "obj_export_mtl.hh" #include "obj_import_file_reader.hh" namespace blender::io::obj { @@ -49,18 +50,26 @@ class obj_mtl_parser_test : public testing::Test { } const MTLMaterial &got = *materials.lookup(exp.name); const float tol = 0.0001f; - EXPECT_V3_NEAR(exp.Ka, got.Ka, tol); - EXPECT_V3_NEAR(exp.Kd, got.Kd, tol); - EXPECT_V3_NEAR(exp.Ks, got.Ks, tol); - EXPECT_V3_NEAR(exp.Ke, got.Ke, tol); - EXPECT_NEAR(exp.Ns, got.Ns, tol); - EXPECT_NEAR(exp.Ni, got.Ni, tol); - EXPECT_NEAR(exp.d, got.d, tol); - EXPECT_NEAR(exp.map_Bump_strength, got.map_Bump_strength, tol); - EXPECT_EQ(exp.illum, got.illum); - for (const auto &it : exp.texture_maps.items()) { - const tex_map_XX &exp_tex = it.value; - const tex_map_XX &got_tex = got.texture_maps.lookup(it.key); + EXPECT_V3_NEAR(exp.ambient_color, got.ambient_color, tol); + EXPECT_V3_NEAR(exp.color, got.color, tol); + EXPECT_V3_NEAR(exp.spec_color, got.spec_color, tol); + EXPECT_V3_NEAR(exp.emission_color, got.emission_color, tol); + EXPECT_V3_NEAR(exp.transmit_color, got.transmit_color, tol); + EXPECT_NEAR(exp.spec_exponent, got.spec_exponent, tol); + EXPECT_NEAR(exp.ior, got.ior, tol); + EXPECT_NEAR(exp.alpha, got.alpha, tol); + EXPECT_NEAR(exp.normal_strength, got.normal_strength, tol); + EXPECT_EQ(exp.illum_mode, got.illum_mode); + EXPECT_NEAR(exp.roughness, got.roughness, tol); + EXPECT_NEAR(exp.metallic, got.metallic, tol); + EXPECT_NEAR(exp.sheen, got.sheen, tol); + EXPECT_NEAR(exp.cc_thickness, got.cc_thickness, tol); + EXPECT_NEAR(exp.cc_roughness, got.cc_roughness, tol); + EXPECT_NEAR(exp.aniso, got.aniso, tol); + EXPECT_NEAR(exp.aniso_rot, got.aniso_rot, tol); + for (int key = 0; key < (int)MTLTexMapType::Count; key++) { + const MTLTexMap &exp_tex = exp.texture_maps[key]; + const MTLTexMap &got_tex = got.texture_maps[key]; EXPECT_STREQ(exp_tex.image_path.c_str(), got_tex.image_path.c_str()); EXPECT_V3_NEAR(exp_tex.translation, got_tex.translation, tol); EXPECT_V3_NEAR(exp_tex.scale, got_tex.scale, tol); @@ -101,20 +110,20 @@ TEST_F(obj_mtl_parser_test, string_newlines_whitespace) "map_Ks sometex_s_spaces_after_name.png \t \r\n"; MTLMaterial mat[6]; mat[0].name = "simple"; - mat[0].Ka = {0.1f, 0.2f, 0.3f}; - mat[0].illum = 4; + mat[0].ambient_color = {0.1f, 0.2f, 0.3f}; + mat[0].illum_mode = 4; mat[1].name = "tab_indentation"; - mat[1].Kd = {0.2f, 0.3f, 0.4f}; + mat[1].color = {0.2f, 0.3f, 0.4f}; mat[2].name = "space_after_name"; - mat[2].Ks = {0.4f, 0.5f, 0.6f}; + mat[2].spec_color = {0.4f, 0.5f, 0.6f}; mat[3].name = "space_before_name"; mat[4].name = "indented_values"; - mat[4].Ka = {0.5f, 0.6f, 0.7f}; - mat[4].Kd = {0.6f, 0.7f, 0.8f}; + mat[4].ambient_color = {0.5f, 0.6f, 0.7f}; + mat[4].color = {0.6f, 0.7f, 0.8f}; mat[5].name = "crlf_ending"; - mat[5].Ns = 5.0f; - mat[5].tex_map_of_type(eMTLSyntaxElement::map_Kd).image_path = "sometex_d.png"; - mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ks).image_path = "sometex_s_spaces_after_name.png"; + mat[5].spec_exponent = 5.0f; + mat[5].tex_map_of_type(MTLTexMapType::Color).image_path = "sometex_d.png"; + mat[5].tex_map_of_type(MTLTexMapType::Specular).image_path = "sometex_s_spaces_after_name.png"; check_string(text, mat, ARRAY_SIZE(mat)); } @@ -122,8 +131,8 @@ TEST_F(obj_mtl_parser_test, cube) { MTLMaterial mat; mat.name = "red"; - mat.Ka = {0.2f, 0.2f, 0.2f}; - mat.Kd = {1, 0, 0}; + mat.ambient_color = {0.2f, 0.2f, 0.2f}; + mat.color = {1, 0, 0}; check("cube.mtl", &mat, 1); } @@ -131,112 +140,206 @@ TEST_F(obj_mtl_parser_test, all_objects) { MTLMaterial mat[7]; for (auto &m : mat) { - m.Ka = {1, 1, 1}; - m.Ks = {0.5f, 0.5f, 0.5f}; - m.Ke = {0, 0, 0}; - m.Ns = 250; - m.Ni = 1; - m.d = 1; - m.illum = 2; + m.ambient_color = {1, 1, 1}; + m.spec_color = {0.5f, 0.5f, 0.5f}; + m.emission_color = {0, 0, 0}; + m.spec_exponent = 250; + m.ior = 1; + m.alpha = 1; + m.illum_mode = 2; } mat[0].name = "Blue"; - mat[0].Kd = {0, 0, 1}; + mat[0].color = {0, 0, 1}; mat[1].name = "BlueDark"; - mat[1].Kd = {0, 0, 0.5f}; + mat[1].color = {0, 0, 0.5f}; mat[2].name = "Green"; - mat[2].Kd = {0, 1, 0}; + mat[2].color = {0, 1, 0}; mat[3].name = "GreenDark"; - mat[3].Kd = {0, 0.5f, 0}; + mat[3].color = {0, 0.5f, 0}; mat[4].name = "Material"; - mat[4].Kd = {0.8f, 0.8f, 0.8f}; + mat[4].color = {0.8f, 0.8f, 0.8f}; mat[5].name = "Red"; - mat[5].Kd = {1, 0, 0}; + mat[5].color = {1, 0, 0}; mat[6].name = "RedDark"; - mat[6].Kd = {0.5f, 0, 0}; + mat[6].color = {0.5f, 0, 0}; check("all_objects.mtl", mat, ARRAY_SIZE(mat)); } TEST_F(obj_mtl_parser_test, materials) { - MTLMaterial mat[5]; + MTLMaterial mat[6]; mat[0].name = "no_textures_red"; - mat[0].Ka = {0.3f, 0.3f, 0.3f}; - mat[0].Kd = {0.8f, 0.3f, 0.1f}; - mat[0].Ns = 5.624998f; + mat[0].ambient_color = {0.3f, 0.3f, 0.3f}; + mat[0].color = {0.8f, 0.3f, 0.1f}; + mat[0].spec_exponent = 5.624998f; mat[1].name = "four_maps"; - mat[1].Ka = {1, 1, 1}; - mat[1].Kd = {0.8f, 0.8f, 0.8f}; - mat[1].Ks = {0.5f, 0.5f, 0.5f}; - mat[1].Ke = {0, 0, 0}; - mat[1].Ns = 1000; - mat[1].Ni = 1.45f; - mat[1].d = 1; - mat[1].illum = 2; - mat[1].map_Bump_strength = 1; + mat[1].ambient_color = {1, 1, 1}; + mat[1].color = {0.8f, 0.8f, 0.8f}; + mat[1].spec_color = {0.5f, 0.5f, 0.5f}; + mat[1].emission_color = {0, 0, 0}; + mat[1].spec_exponent = 1000; + mat[1].ior = 1.45f; + mat[1].alpha = 1; + mat[1].illum_mode = 2; + mat[1].normal_strength = 1; { - tex_map_XX &kd = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Kd); + MTLTexMap &kd = mat[1].tex_map_of_type(MTLTexMapType::Color); kd.image_path = "texture.png"; - tex_map_XX &ns = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Ns); + MTLTexMap &ns = mat[1].tex_map_of_type(MTLTexMapType::SpecularExponent); ns.image_path = "sometexture_Roughness.png"; - tex_map_XX &refl = mat[1].tex_map_of_type(eMTLSyntaxElement::map_refl); + MTLTexMap &refl = mat[1].tex_map_of_type(MTLTexMapType::Reflection); refl.image_path = "sometexture_Metallic.png"; - tex_map_XX &bump = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Bump); + MTLTexMap &bump = mat[1].tex_map_of_type(MTLTexMapType::Normal); bump.image_path = "sometexture_Normal.png"; } mat[2].name = "Clay"; - mat[2].Ka = {1, 1, 1}; - mat[2].Kd = {0.8f, 0.682657f, 0.536371f}; - mat[2].Ks = {0.5f, 0.5f, 0.5f}; - mat[2].Ke = {0, 0, 0}; - mat[2].Ns = 440.924042f; - mat[2].Ni = 1.45f; - mat[2].d = 1; - mat[2].illum = 2; + mat[2].ambient_color = {1, 1, 1}; + mat[2].color = {0.8f, 0.682657f, 0.536371f}; + mat[2].spec_color = {0.5f, 0.5f, 0.5f}; + mat[2].emission_color = {0, 0, 0}; + mat[2].spec_exponent = 440.924042f; + mat[2].ior = 1.45f; + mat[2].alpha = 1; + mat[2].illum_mode = 2; mat[3].name = "Hat"; - mat[3].Ka = {1, 1, 1}; - mat[3].Kd = {0.8f, 0.8f, 0.8f}; - mat[3].Ks = {0.5f, 0.5f, 0.5f}; - mat[3].Ns = 800; - mat[3].map_Bump_strength = 0.5f; + mat[3].ambient_color = {1, 1, 1}; + mat[3].color = {0.8f, 0.8f, 0.8f}; + mat[3].spec_color = {0.5f, 0.5f, 0.5f}; + mat[3].spec_exponent = 800; + mat[3].normal_strength = 0.5f; { - tex_map_XX &kd = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Kd); + MTLTexMap &kd = mat[3].tex_map_of_type(MTLTexMapType::Color); kd.image_path = "someHatTexture_BaseColor.jpg"; - tex_map_XX &ns = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Ns); + MTLTexMap &ns = mat[3].tex_map_of_type(MTLTexMapType::SpecularExponent); ns.image_path = "someHatTexture_Roughness.jpg"; - tex_map_XX &refl = mat[3].tex_map_of_type(eMTLSyntaxElement::map_refl); + MTLTexMap &refl = mat[3].tex_map_of_type(MTLTexMapType::Reflection); refl.image_path = "someHatTexture_Metalness.jpg"; - tex_map_XX &bump = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Bump); + MTLTexMap &bump = mat[3].tex_map_of_type(MTLTexMapType::Normal); bump.image_path = "someHatTexture_Normal.jpg"; } mat[4].name = "Parser_Test"; - mat[4].Ka = {0.1f, 0.2f, 0.3f}; - mat[4].Kd = {0.4f, 0.5f, 0.6f}; - mat[4].Ks = {0.7f, 0.8f, 0.9f}; - mat[4].illum = 6; - mat[4].Ns = 15.5; - mat[4].Ni = 1.5; - mat[4].d = 0.5; - mat[4].map_Bump_strength = 0.1f; + mat[4].ambient_color = {0.1f, 0.2f, 0.3f}; + mat[4].color = {0.4f, 0.5f, 0.6f}; + mat[4].spec_color = {0.7f, 0.8f, 0.9f}; + mat[4].illum_mode = 6; + mat[4].spec_exponent = 15.5; + mat[4].ior = 1.5; + mat[4].alpha = 0.5; + mat[4].normal_strength = 0.1f; + mat[4].transmit_color = {0.1f, 0.3f, 0.5f}; + mat[4].normal_strength = 0.1f; + mat[4].roughness = 0.2f; + mat[4].metallic = 0.3f; + mat[4].sheen = 0.4f; + mat[4].cc_thickness = 0.5f; + mat[4].cc_roughness = 0.6f; + mat[4].aniso = 0.7f; + mat[4].aniso_rot = 0.8f; { - tex_map_XX &kd = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Kd); + MTLTexMap &kd = mat[4].tex_map_of_type(MTLTexMapType::Color); kd.image_path = "sometex_d.png"; - tex_map_XX &ns = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Ns); + MTLTexMap &ns = mat[4].tex_map_of_type(MTLTexMapType::SpecularExponent); ns.image_path = "sometex_ns.psd"; - tex_map_XX &refl = mat[4].tex_map_of_type(eMTLSyntaxElement::map_refl); + MTLTexMap &refl = mat[4].tex_map_of_type(MTLTexMapType::Reflection); refl.image_path = "clouds.tiff"; refl.scale = {1.5f, 2.5f, 3.5f}; refl.translation = {4.5f, 5.5f, 6.5f}; refl.projection_type = SHD_PROJ_SPHERE; - tex_map_XX &bump = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Bump); + MTLTexMap &bump = mat[4].tex_map_of_type(MTLTexMapType::Normal); bump.image_path = "somebump.tga"; bump.scale = {3, 4, 5}; } + mat[5].name = "Parser_ScaleOffset_Test"; + { + MTLTexMap &kd = mat[5].tex_map_of_type(MTLTexMapType::Color); + kd.translation = {2.5f, 0.0f, 0.0f}; + kd.image_path = "OffsetOneValue.png"; + MTLTexMap &ks = mat[5].tex_map_of_type(MTLTexMapType::Specular); + ks.scale = {1.5f, 2.5f, 1.0f}; + ks.translation = {3.5f, 4.5f, 0.0f}; + ks.image_path = "ScaleOffsetBothTwovalues.png"; + MTLTexMap &ns = mat[5].tex_map_of_type(MTLTexMapType::SpecularExponent); + ns.scale = {0.5f, 1.0f, 1.0f}; + ns.image_path = "1.Value.png"; + } + check("materials.mtl", mat, ARRAY_SIZE(mat)); } +TEST_F(obj_mtl_parser_test, materials_without_pbr) +{ + MTLMaterial mat[2]; + mat[0].name = "Mat1"; + mat[0].spec_exponent = 360.0f; + mat[0].ambient_color = {0.9f, 0.9f, 0.9f}; + mat[0].color = {0.8f, 0.276449f, 0.101911f}; + mat[0].spec_color = {0.25f, 0.25f, 0.25f}; + mat[0].emission_color = {0, 0, 0}; + mat[0].ior = 1.45f; + mat[0].alpha = 1; + mat[0].illum_mode = 3; + + mat[1].name = "Mat2"; + mat[1].ambient_color = {1, 1, 1}; + mat[1].color = {0.8f, 0.8f, 0.8f}; + mat[1].spec_color = {0.5f, 0.5f, 0.5f}; + mat[1].ior = 1.45f; + mat[1].alpha = 1; + mat[1].illum_mode = 2; + { + MTLTexMap &ns = mat[1].tex_map_of_type(MTLTexMapType::SpecularExponent); + ns.image_path = "../blend_geometry/texture_roughness.png"; + MTLTexMap &ke = mat[1].tex_map_of_type(MTLTexMapType::Emission); + ke.image_path = "../blend_geometry/texture_illum.png"; + } + + check("materials_without_pbr.mtl", mat, ARRAY_SIZE(mat)); +} + +TEST_F(obj_mtl_parser_test, materials_pbr) +{ + MTLMaterial mat[2]; + mat[0].name = "Mat1"; + mat[0].color = {0.8f, 0.276449f, 0.101911f}; + mat[0].spec_color = {0.25f, 0.25f, 0.25f}; + mat[0].emission_color = {0, 0, 0}; + mat[0].ior = 1.45f; + mat[0].alpha = 1; + mat[0].illum_mode = 3; + mat[0].roughness = 0.4f; + mat[0].metallic = 0.9f; + mat[0].sheen = 0.3f; + mat[0].cc_thickness = 0.393182f; + mat[0].cc_roughness = 0.05f; + mat[0].aniso = 0.2f; + mat[0].aniso_rot = 0.0f; + + mat[1].name = "Mat2"; + mat[1].color = {0.8f, 0.8f, 0.8f}; + mat[1].spec_color = {0.5f, 0.5f, 0.5f}; + mat[1].ior = 1.45f; + mat[1].alpha = 1; + mat[1].illum_mode = 2; + mat[1].metallic = 0.0f; + mat[1].cc_thickness = 0.3f; + mat[1].cc_roughness = 0.4f; + mat[1].aniso = 0.8f; + mat[1].aniso_rot = 0.7f; + { + MTLTexMap &pr = mat[1].tex_map_of_type(MTLTexMapType::Roughness); + pr.image_path = "../blend_geometry/texture_roughness.png"; + MTLTexMap &ps = mat[1].tex_map_of_type(MTLTexMapType::Sheen); + ps.image_path = "../blend_geometry/texture_checker.png"; + MTLTexMap &ke = mat[1].tex_map_of_type(MTLTexMapType::Emission); + ke.image_path = "../blend_geometry/texture_illum.png"; + } + + check("materials_pbr.mtl", mat, ARRAY_SIZE(mat)); +} + } // namespace blender::io::obj |