Blender  V3.3
obj_mtl_parser_tests.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0 */
2 
3 #include <gtest/gtest.h>
4 
5 #include "BKE_appdir.h"
6 
7 #include "testing/testing.h"
8 
10 
11 namespace blender::io::obj {
12 
13 class obj_mtl_parser_test : public testing::Test {
14  public:
15  void check_string(const char *text, const MTLMaterial *expect, size_t expect_count)
16  {
17  BKE_tempdir_init(nullptr);
18  std::string tmp_dir = BKE_tempdir_base();
19  std::string tmp_file_name = "mtl_test.mtl";
20  std::string tmp_file_path = tmp_dir + "/" + tmp_file_name;
21  FILE *tmp_file = BLI_fopen(tmp_file_path.c_str(), "wb");
22  fputs(text, tmp_file);
23  fclose(tmp_file);
24 
25  check_impl(tmp_file_name, tmp_dir, expect, expect_count);
26 
27  BLI_delete(tmp_file_path.c_str(), false, false);
28  }
29  void check(const char *file, const MTLMaterial *expect, size_t expect_count)
30  {
31  std::string obj_dir = blender::tests::flags_test_asset_dir() + "/io_tests/obj/";
32  check_impl(file, obj_dir, expect, expect_count);
33  }
34  void check_impl(StringRefNull mtl_file_path,
35  StringRefNull file_dir,
36  const MTLMaterial *expect,
37  size_t expect_count)
38  {
39  MTLParser parser(mtl_file_path, file_dir + "dummy.obj");
41  parser.parse_and_store(materials);
42 
43  for (int i = 0; i < expect_count; ++i) {
44  const MTLMaterial &exp = expect[i];
45  if (!materials.contains(exp.name)) {
46  fprintf(stderr, "Material '%s' was expected in parsed result\n", exp.name.c_str());
47  ADD_FAILURE();
48  continue;
49  }
50  const MTLMaterial &got = *materials.lookup(exp.name);
51  const float tol = 0.0001f;
52  EXPECT_V3_NEAR(exp.Ka, got.Ka, tol);
53  EXPECT_V3_NEAR(exp.Kd, got.Kd, tol);
54  EXPECT_V3_NEAR(exp.Ks, got.Ks, tol);
55  EXPECT_V3_NEAR(exp.Ke, got.Ke, tol);
56  EXPECT_NEAR(exp.Ns, got.Ns, tol);
57  EXPECT_NEAR(exp.Ni, got.Ni, tol);
58  EXPECT_NEAR(exp.d, got.d, tol);
59  EXPECT_NEAR(exp.map_Bump_strength, got.map_Bump_strength, tol);
60  EXPECT_EQ(exp.illum, got.illum);
61  for (const auto &it : exp.texture_maps.items()) {
62  const tex_map_XX &exp_tex = it.value;
63  const tex_map_XX &got_tex = got.texture_maps.lookup(it.key);
64  EXPECT_STREQ(exp_tex.image_path.c_str(), got_tex.image_path.c_str());
65  EXPECT_V3_NEAR(exp_tex.translation, got_tex.translation, tol);
66  EXPECT_V3_NEAR(exp_tex.scale, got_tex.scale, tol);
67  EXPECT_EQ(exp_tex.projection_type, got_tex.projection_type);
68  }
69  }
70  EXPECT_EQ(materials.size(), expect_count);
71  }
72 };
73 
74 TEST_F(obj_mtl_parser_test, string_newlines_whitespace)
75 {
76  const char *text =
77  "# a comment\n"
78  " # indented comment\n"
79  "# comment with CRLF line ending\r\n"
80  "\r\n"
81 
82  "newmtl simple\n"
83  "Ka 0.1 0.2 0.3\n"
84  "illum 4\n"
85 
86  "newmtl\ttab_indentation\n"
87  "Kd\t \t0.2 0.3\t0.4 \t \n"
88 
89  "newmtl space_after_name \t \n"
90  "Ks 0.4 0.5 0.6\n"
91 
92  "newmtl space_before_name\n"
93 
94  "newmtl indented_values\n"
95  " Ka 0.5 0.6 0.7\n"
96  "\t\t\tKd 0.6 0.7 0.8\n"
97 
98  "newmtl crlf_ending\r\n"
99  "Ns 5.0\r\n"
100  "map_Kd sometex_d.png\r\n"
101  "map_Ks sometex_s_spaces_after_name.png \t \r\n";
102  MTLMaterial mat[6];
103  mat[0].name = "simple";
104  mat[0].Ka = {0.1f, 0.2f, 0.3f};
105  mat[0].illum = 4;
106  mat[1].name = "tab_indentation";
107  mat[1].Kd = {0.2f, 0.3f, 0.4f};
108  mat[2].name = "space_after_name";
109  mat[2].Ks = {0.4f, 0.5f, 0.6f};
110  mat[3].name = "space_before_name";
111  mat[4].name = "indented_values";
112  mat[4].Ka = {0.5f, 0.6f, 0.7f};
113  mat[4].Kd = {0.6f, 0.7f, 0.8f};
114  mat[5].name = "crlf_ending";
115  mat[5].Ns = 5.0f;
116  mat[5].tex_map_of_type(eMTLSyntaxElement::map_Kd).image_path = "sometex_d.png";
117  mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ks).image_path = "sometex_s_spaces_after_name.png";
118  check_string(text, mat, ARRAY_SIZE(mat));
119 }
120 
122 {
123  MTLMaterial mat;
124  mat.name = "red";
125  mat.Ka = {0.2f, 0.2f, 0.2f};
126  mat.Kd = {1, 0, 0};
127  check("cube.mtl", &mat, 1);
128 }
129 
131 {
132  MTLMaterial mat[7];
133  for (auto &m : mat) {
134  m.Ka = {1, 1, 1};
135  m.Ks = {0.5f, 0.5f, 0.5f};
136  m.Ke = {0, 0, 0};
137  m.Ns = 250;
138  m.Ni = 1;
139  m.d = 1;
140  m.illum = 2;
141  }
142  mat[0].name = "Blue";
143  mat[0].Kd = {0, 0, 1};
144  mat[1].name = "BlueDark";
145  mat[1].Kd = {0, 0, 0.5f};
146  mat[2].name = "Green";
147  mat[2].Kd = {0, 1, 0};
148  mat[3].name = "GreenDark";
149  mat[3].Kd = {0, 0.5f, 0};
150  mat[4].name = "Material";
151  mat[4].Kd = {0.8f, 0.8f, 0.8f};
152  mat[5].name = "Red";
153  mat[5].Kd = {1, 0, 0};
154  mat[6].name = "RedDark";
155  mat[6].Kd = {0.5f, 0, 0};
156  check("all_objects.mtl", mat, ARRAY_SIZE(mat));
157 }
158 
160 {
161  MTLMaterial mat[6];
162  mat[0].name = "no_textures_red";
163  mat[0].Ka = {0.3f, 0.3f, 0.3f};
164  mat[0].Kd = {0.8f, 0.3f, 0.1f};
165  mat[0].Ns = 5.624998f;
166 
167  mat[1].name = "four_maps";
168  mat[1].Ka = {1, 1, 1};
169  mat[1].Kd = {0.8f, 0.8f, 0.8f};
170  mat[1].Ks = {0.5f, 0.5f, 0.5f};
171  mat[1].Ke = {0, 0, 0};
172  mat[1].Ns = 1000;
173  mat[1].Ni = 1.45f;
174  mat[1].d = 1;
175  mat[1].illum = 2;
176  mat[1].map_Bump_strength = 1;
177  {
179  kd.image_path = "texture.png";
181  ns.image_path = "sometexture_Roughness.png";
183  refl.image_path = "sometexture_Metallic.png";
185  bump.image_path = "sometexture_Normal.png";
186  }
187 
188  mat[2].name = "Clay";
189  mat[2].Ka = {1, 1, 1};
190  mat[2].Kd = {0.8f, 0.682657f, 0.536371f};
191  mat[2].Ks = {0.5f, 0.5f, 0.5f};
192  mat[2].Ke = {0, 0, 0};
193  mat[2].Ns = 440.924042f;
194  mat[2].Ni = 1.45f;
195  mat[2].d = 1;
196  mat[2].illum = 2;
197 
198  mat[3].name = "Hat";
199  mat[3].Ka = {1, 1, 1};
200  mat[3].Kd = {0.8f, 0.8f, 0.8f};
201  mat[3].Ks = {0.5f, 0.5f, 0.5f};
202  mat[3].Ns = 800;
203  mat[3].map_Bump_strength = 0.5f;
204  {
206  kd.image_path = "someHatTexture_BaseColor.jpg";
208  ns.image_path = "someHatTexture_Roughness.jpg";
210  refl.image_path = "someHatTexture_Metalness.jpg";
212  bump.image_path = "someHatTexture_Normal.jpg";
213  }
214 
215  mat[4].name = "Parser_Test";
216  mat[4].Ka = {0.1f, 0.2f, 0.3f};
217  mat[4].Kd = {0.4f, 0.5f, 0.6f};
218  mat[4].Ks = {0.7f, 0.8f, 0.9f};
219  mat[4].illum = 6;
220  mat[4].Ns = 15.5;
221  mat[4].Ni = 1.5;
222  mat[4].d = 0.5;
223  mat[4].map_Bump_strength = 0.1f;
224  {
226  kd.image_path = "sometex_d.png";
228  ns.image_path = "sometex_ns.psd";
230  refl.image_path = "clouds.tiff";
231  refl.scale = {1.5f, 2.5f, 3.5f};
232  refl.translation = {4.5f, 5.5f, 6.5f};
235  bump.image_path = "somebump.tga";
236  bump.scale = {3, 4, 5};
237  }
238 
239  mat[5].name = "Parser_ScaleOffset_Test";
240  {
242  kd.translation = {2.5f, 0.0f, 0.0f};
243  kd.image_path = "OffsetOneValue.png";
245  ks.scale = {1.5f, 2.5f, 1.0f};
246  ks.translation = {3.5f, 4.5f, 0.0f};
247  ks.image_path = "ScaleOffsetBothTwovalues.png";
249  ns.scale = {0.5f, 1.0f, 1.0f};
250  ns.image_path = "1.Value.png";
251  }
252 
253  check("materials.mtl", mat, ARRAY_SIZE(mat));
254 }
255 
256 } // namespace blender::io::obj
void BKE_tempdir_init(const char *userdir)
Definition: appdir.c:1133
const char * BKE_tempdir_base(void)
Definition: appdir.c:1154
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:906
int BLI_delete(const char *file, bool dir, bool recursive) ATTR_NONNULL()
Definition: fileops.c:934
#define ARRAY_SIZE(arr)
#define SHD_PROJ_SPHERE
void parse_and_store(Map< std::string, std::unique_ptr< MTLMaterial >> &r_materials)
void check(const char *file, const MTLMaterial *expect, size_t expect_count)
void check_impl(StringRefNull mtl_file_path, StringRefNull file_dir, const MTLMaterial *expect, size_t expect_count)
void check_string(const char *text, const MTLMaterial *expect, size_t expect_count)
FILE * file
smooth(Type::VEC4, "color_mul") .smooth(Type gpFillTexture gpSceneDepthTexture materials[GPENCIL_MATERIAL_BUFFER_LEN]
Definition: gpencil_info.hh:29
ccl_device_inline float3 exp(float3 v)
Definition: math_float3.h:392
TEST_F(obj_exporter_test, filter_objects_curves_as_mesh)
Map< const eMTLSyntaxElement, tex_map_XX > texture_maps
const tex_map_XX & tex_map_of_type(const eMTLSyntaxElement key) const