Blender  V3.3
obj_importer_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 "testing/testing.h"
7 
8 #include "BKE_curve.h"
9 #include "BKE_customdata.h"
10 #include "BKE_main.h"
11 #include "BKE_object.h"
12 #include "BKE_scene.h"
13 
14 #include "BLI_listbase.h"
15 #include "BLI_math_base.h"
16 #include "BLI_math_vec_types.hh"
17 
18 #include "BLO_readfile.h"
19 
20 #include "DEG_depsgraph.h"
21 #include "DEG_depsgraph_query.h"
22 
23 #include "DNA_curve_types.h"
24 #include "DNA_mesh_types.h"
25 #include "DNA_meshdata_types.h"
26 #include "DNA_scene_types.h"
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "obj_importer.hh"
31 
32 namespace blender::io::obj {
33 
34 struct Expectation {
35  std::string name;
36  short type; /* OB_MESH, ... */
42  float4 color_first = {-1, -1, -1, -1};
43 };
44 
46  public:
47  void import_and_check(const char *path,
48  const Expectation *expect,
49  size_t expect_count,
50  int expect_mat_count,
51  int expect_image_count = 0)
52  {
53  if (!blendfile_load("io_tests/blend_geometry/all_quads.blend")) {
54  ADD_FAILURE();
55  return;
56  }
57 
59  params.clamp_size = 0;
60  params.forward_axis = IO_AXIS_NEGATIVE_Z;
61  params.up_axis = IO_AXIS_Y;
62  params.validate_meshes = true;
63  params.import_vertex_groups = false;
64  params.relative_paths = true;
65  params.clear_selection = true;
66 
67  std::string obj_path = blender::tests::flags_test_asset_dir() + "/io_tests/obj/" + path;
68  strncpy(params.filepath, obj_path.c_str(), FILE_MAX - 1);
69  const size_t read_buffer_size = 650;
71 
73 
74  const int deg_objects_visibility_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
78  size_t object_index = 0;
79  DEG_OBJECT_ITER_BEGIN (depsgraph, object, deg_objects_visibility_flags) {
80  if (object_index >= expect_count) {
81  ADD_FAILURE();
82  break;
83  }
84  const Expectation &exp = expect[object_index];
85  ASSERT_STREQ(object->id.name, exp.name.c_str());
86  EXPECT_EQ(object->type, exp.type);
87  EXPECT_V3_NEAR(object->loc, float3(0, 0, 0), 0.0001f);
88  if (strcmp(object->id.name, "OBCube") != 0) {
89  EXPECT_V3_NEAR(object->rot, float3(M_PI_2, 0, 0), 0.0001f);
90  }
91  EXPECT_V3_NEAR(object->scale, float3(1, 1, 1), 0.0001f);
92  if (object->type == OB_MESH) {
94  EXPECT_EQ(mesh->totvert, exp.totvert);
95  EXPECT_EQ(mesh->totedge, exp.mesh_totedge_or_curve_endp);
96  EXPECT_EQ(mesh->totpoly, exp.mesh_totpoly_or_curve_order);
97  EXPECT_EQ(mesh->totloop, exp.mesh_totloop_or_curve_cyclic);
98  EXPECT_V3_NEAR(mesh->mvert[0].co, exp.vert_first, 0.0001f);
99  EXPECT_V3_NEAR(mesh->mvert[mesh->totvert - 1].co, exp.vert_last, 0.0001f);
100  const float3 *lnors = (const float3 *)(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
101  float3 normal_first = lnors != nullptr ? lnors[0] : float3(0, 0, 0);
102  EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f);
103  const MLoopUV *mloopuv = static_cast<const MLoopUV *>(
105  float2 uv_first = mloopuv ? float2(mloopuv->uv) : float2(0, 0);
106  EXPECT_V2_NEAR(uv_first, exp.uv_first, 0.0001f);
107  if (exp.color_first.x >= 0) {
108  const float4 *colors = (const float4 *)(CustomData_get_layer(&mesh->vdata,
109  CD_PROP_COLOR));
110  EXPECT_TRUE(colors != nullptr);
111  EXPECT_V4_NEAR(colors[0], exp.color_first, 0.0001f);
112  }
113  else {
114  EXPECT_FALSE(CustomData_has_layer(&mesh->vdata, CD_PROP_COLOR));
115  }
116  }
117  if (object->type == OB_CURVES_LEGACY) {
118  Curve *curve = static_cast<Curve *>(DEG_get_evaluated_object(depsgraph, object)->data);
119  int numVerts;
120  float(*vertexCos)[3] = BKE_curve_nurbs_vert_coords_alloc(&curve->nurb, &numVerts);
121  EXPECT_EQ(numVerts, exp.totvert);
122  EXPECT_V3_NEAR(vertexCos[0], exp.vert_first, 0.0001f);
123  EXPECT_V3_NEAR(vertexCos[numVerts - 1], exp.vert_last, 0.0001f);
124  MEM_freeN(vertexCos);
125  const Nurb *nurb = static_cast<const Nurb *>(BLI_findlink(&curve->nurb, 0));
126  int endpoint = (nurb->flagu & CU_NURB_ENDPOINT) ? 1 : 0;
127  EXPECT_EQ(nurb->orderu, exp.mesh_totpoly_or_curve_order);
128  EXPECT_EQ(endpoint, exp.mesh_totedge_or_curve_endp);
129  /* Cyclic flag is not set by the importer yet. */
130  // int cyclic = (nurb->flagu & CU_NURB_CYCLIC) ? 1 : 0;
131  // EXPECT_EQ(cyclic, exp.mesh_totloop_or_curve_cyclic);
132  }
133  ++object_index;
134  }
136  EXPECT_EQ(object_index, expect_count);
137 
138  /* Check number of materials & textures. */
139  const int mat_count = BLI_listbase_count(&bfile->main->materials);
140  EXPECT_EQ(mat_count, expect_mat_count);
141 
142  const int ima_count = BLI_listbase_count(&bfile->main->images);
143  EXPECT_EQ(ima_count, expect_image_count);
144  }
145 };
146 
148 {
149  Expectation expect[] = {
150  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
151  {"OBcube",
152  OB_MESH,
153  8,
154  12,
155  6,
156  24,
157  float3(-1, -1, 1),
158  float3(1, -1, -1),
159  float3(-0.57735f, 0.57735f, -0.57735f)},
160  };
161  import_and_check("cube.obj", expect, std::size(expect), 1);
162 }
163 
164 TEST_F(obj_importer_test, import_cube_o_after_verts)
165 {
166  Expectation expect[] = {
167  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
168  {
169  "OBActualCube",
170  OB_MESH,
171  8,
172  12,
173  6,
174  24,
175  float3(-1, -1, 1),
176  float3(1, -1, -1),
177  float3(0, 0, 1),
178  },
179  {
180  "OBSparseTri",
181  OB_MESH,
182  3,
183  3,
184  1,
185  3,
186  float3(1, -1, 1),
187  float3(-2, -2, 2),
188  float3(-0.2357f, 0.9428f, 0.2357f),
189  },
190  };
191  import_and_check("cube_o_after_verts.obj", expect, std::size(expect), 2);
192 }
193 
194 TEST_F(obj_importer_test, import_suzanne_all_data)
195 {
196  Expectation expect[] = {
197  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
198  {"OBMonkey",
199  OB_MESH,
200  505,
201  1005,
202  500,
203  1968,
204  float3(-0.4375f, 0.164062f, 0.765625f),
205  float3(0.4375f, 0.164062f, 0.765625f),
206  float3(-0.6040f, -0.5102f, 0.6122f),
207  float2(0.692094f, 0.40191f)},
208  };
209  import_and_check("suzanne_all_data.obj", expect, std::size(expect), 0);
210 }
211 
212 TEST_F(obj_importer_test, import_nurbs)
213 {
214  Expectation expect[] = {
215  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
216  {"OBnurbs",
218  12,
219  0,
220  4,
221  1,
222  float3(0.260472f, -1.477212f, -0.866025f),
223  float3(-1.5f, 2.598076f, 0)},
224  };
225  import_and_check("nurbs.obj", expect, std::size(expect), 0);
226 }
227 
228 TEST_F(obj_importer_test, import_nurbs_curves)
229 {
230  Expectation expect[] = {
231  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
232  {"OBCurveDeg3", OB_CURVES_LEGACY, 4, 0, 3, 0, float3(10, -2, 0), float3(6, -2, 0)},
233  {"OBnurbs_curves", OB_CURVES_LEGACY, 4, 0, 4, 0, float3(2, -2, 0), float3(-2, -2, 0)},
234  {"OBNurbsCurveCyclic", OB_CURVES_LEGACY, 7, 0, 4, 1, float3(-2, -2, 0), float3(-6, 2, 0)},
235  {"OBNurbsCurveDiffWeights",
237  4,
238  0,
239  4,
240  0,
241  float3(6, -2, 0),
242  float3(2, -2, 0)},
243  {"OBNurbsCurveEndpoint",
245  4,
246  1,
247  4,
248  0,
249  float3(-6, -2, 0),
250  float3(-10, -2, 0)},
251  };
252  import_and_check("nurbs_curves.obj", expect, std::size(expect), 0);
253 }
254 
255 TEST_F(obj_importer_test, import_nurbs_cyclic)
256 {
257  Expectation expect[] = {
258  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
259  {"OBnurbs_cyclic",
261  31,
262  0,
263  4,
264  1,
265  float3(2.591002f, 0, -0.794829f),
266  float3(3.280729f, 0, 3.043217f)},
267  };
268  import_and_check("nurbs_cyclic.obj", expect, std::size(expect), 0);
269 }
270 
271 TEST_F(obj_importer_test, import_nurbs_manual)
272 {
273  Expectation expect[] = {
274  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
275  {"OBCurve_Cyclic", OB_CURVES_LEGACY, 7, 0, 4, 1, float3(-2, 0, 2), float3(2, 0, -2)},
276  {"OBCurve_Endpoints", OB_CURVES_LEGACY, 5, 1, 4, 0, float3(-2, 0, 2), float3(-2, 0, 2)},
277  {"OBCurve_NonUniform_Parm",
279  5,
280  0,
281  4,
282  0,
283  float3(-2, 0, 2),
284  float3(-2, 0, 2)},
285  {"OBCurve_Uniform_Parm", OB_CURVES_LEGACY, 5, 0, 4, 0, float3(-2, 0, 2), float3(-2, 0, 2)},
286  };
287  import_and_check("nurbs_manual.obj", expect, std::size(expect), 0);
288 }
289 
290 TEST_F(obj_importer_test, import_nurbs_mesh)
291 {
292  Expectation expect[] = {
293  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
294  {"OBTorus_Knot",
295  OB_MESH,
296  108,
297  108,
298  0,
299  0,
300  float3(0.438725f, 1.070313f, 0.433013f),
301  float3(0.625557f, 1.040691f, 0.460328f)},
302  };
303  import_and_check("nurbs_mesh.obj", expect, std::size(expect), 0);
304 }
305 
306 TEST_F(obj_importer_test, import_materials)
307 {
308  Expectation expect[] = {
309  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
310  {"OBmaterials", OB_MESH, 8, 12, 6, 24, float3(-1, -1, 1), float3(1, -1, -1)},
311  };
312  import_and_check("materials.obj", expect, std::size(expect), 4, 8);
313 }
314 
315 TEST_F(obj_importer_test, import_cubes_with_textures_rel)
316 {
317  Expectation expect[] = {
318  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
319  {"OBCube4Tex",
320  OB_MESH,
321  8,
322  12,
323  6,
324  24,
325  float3(1, 1, -1),
326  float3(-1, -1, 1),
327  float3(0, 1, 0),
328  float2(0.9935f, 0.0020f)},
329  {"OBCubeTexMul",
330  OB_MESH,
331  8,
332  12,
333  6,
334  24,
335  float3(4, -2, -1),
336  float3(2, -4, 1),
337  float3(0, 1, 0),
338  float2(0.9935f, 0.0020f)},
339  {"OBCubeTiledTex",
340  OB_MESH,
341  8,
342  12,
343  6,
344  24,
345  float3(4, 1, -1),
346  float3(2, -1, 1),
347  float3(0, 1, 0),
348  float2(0.9935f, 0.0020f)},
349  {"OBCubeTiledTexFromAnotherFolder",
350  OB_MESH,
351  8,
352  12,
353  6,
354  24,
355  float3(7, 1, -1),
356  float3(5, -1, 1),
357  float3(0, 1, 0),
358  float2(0.9935f, 0.0020f)},
359  };
360  import_and_check("cubes_with_textures_rel.obj", expect, std::size(expect), 4, 4);
361 }
362 
363 TEST_F(obj_importer_test, import_faces_invalid_or_with_holes)
364 {
365  Expectation expect[] = {
366  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
367  {"OBFaceAllVerts_BecomesOneOverlappingFaceUsingAllVerts",
368  OB_MESH,
369  8,
370  8,
371  1,
372  8,
373  float3(8, 0, -2),
374  float3(11, 0, -1)},
375  {"OBFaceAllVertsDup_BecomesOneOverlappingFaceUsingAllVerts",
376  OB_MESH,
377  8,
378  8,
379  1,
380  8,
381  float3(3, 0, 3),
382  float3(6, 0, 4)},
383  {"OBFaceJustTwoVerts_IsSkipped", OB_MESH, 2, 0, 0, 0, float3(8, 0, 3), float3(8, 0, 7)},
384  {"OBFaceQuadDupSomeVerts_BecomesOneQuadUsing4Verts",
385  OB_MESH,
386  4,
387  4,
388  1,
389  4,
390  float3(3, 0, -2),
391  float3(7, 0, -2)},
392  {"OBFaceTriDupVert_Becomes1Tri", OB_MESH, 3, 3, 1, 3, float3(-2, 0, 3), float3(2, 0, 7)},
393  {"OBFaceWithHole_BecomesTwoFacesFormingAHole",
394  OB_MESH,
395  8,
396  10,
397  2,
398  12,
399  float3(-2, 0, -2),
400  float3(1, 0, -1)},
401  };
402  import_and_check("faces_invalid_or_with_holes.obj", expect, std::size(expect), 0);
403 }
404 
405 TEST_F(obj_importer_test, import_invalid_indices)
406 {
407  Expectation expect[] = {
408  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
409  {"OBQuad",
410  OB_MESH,
411  3,
412  3,
413  1,
414  3,
415  float3(-2, 0, -2),
416  float3(2, 0, 2),
417  float3(0, 1, 0),
418  float2(0.5f, 0.25f)},
419  };
420  import_and_check("invalid_indices.obj", expect, std::size(expect), 0);
421 }
422 
423 TEST_F(obj_importer_test, import_invalid_syntax)
424 {
425  Expectation expect[] = {
426  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
427  {"OBObjectWithAReallyLongNameToCheckHowImportHandlesNamesThatAreLon",
428  OB_MESH,
429  3,
430  3,
431  1,
432  3,
433  float3(1, 2, 3),
434  float3(7, 8, 9),
435  float3(0, 1, 0),
436  float2(0.5f, 0.25f)},
437  };
438  import_and_check("invalid_syntax.obj", expect, std::size(expect), 0);
439 }
440 
441 TEST_F(obj_importer_test, import_all_objects)
442 {
443  Expectation expect[] = {
444  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
445  /* .obj file has empty EmptyText and EmptyMesh objects; these are ignored and skipped */
446  {"OBBezierCurve", OB_MESH, 13, 12, 0, 0, float3(-1, -2, 0), float3(1, -2, 0)},
447  {"OBBlankCube", OB_MESH, 8, 13, 7, 26, float3(1, 1, -1), float3(-1, 1, 1), float3(0, 0, 1)},
448  {"OBMaterialCube",
449  OB_MESH,
450  8,
451  13,
452  7,
453  26,
454  float3(28, 1, -1),
455  float3(26, 1, 1),
456  float3(-1, 0, 0)},
457  {"OBNurbsCircle",
458  OB_MESH,
459  96,
460  96,
461  0,
462  0,
463  float3(3.292893f, -2.707107f, 0),
464  float3(3.369084f, -2.77607f, 0)},
465  {"OBNurbsCircle.001", OB_MESH, 4, 4, 0, 0, float3(2, -3, 0), float3(3, -2, 0)},
466  {"OBParticleCube",
467  OB_MESH,
468  8,
469  13,
470  7,
471  26,
472  float3(22, 1, -1),
473  float3(20, 1, 1),
474  float3(0, 0, 1)},
475  {"OBShapeKeyCube",
476  OB_MESH,
477  8,
478  13,
479  7,
480  26,
481  float3(19, 1, -1),
482  float3(17, 1, 1),
483  float3(-0.4082f, -0.4082f, 0.8165f)},
484  {"OBSmoothCube",
485  OB_MESH,
486  8,
487  13,
488  7,
489  26,
490  float3(4, 1, -1),
491  float3(2, 1, 1),
492  float3(0.5774f, 0.5773f, 0.5774f)},
493  {"OBSurface",
494  OB_MESH,
495  256,
496  480,
497  224,
498  896,
499  float3(7.292893f, -2.707107f, -1),
500  float3(7.525872f, -2.883338f, 1),
501  float3(-0.7071f, -0.7071f, 0),
502  float2(0, 0.142857f)},
503  {"OBSurfPatch",
504  OB_MESH,
505  256,
506  480,
507  225,
508  900,
509  float3(12.5f, -2.5f, 0.694444f),
510  float3(13.5f, -1.5f, 0.694444f),
511  float3(-0.3246f, -0.3531f, 0.8775f),
512  float2(0, 0.066667f)},
513  {"OBSurfSphere",
514  OB_MESH,
515  640,
516  1248,
517  608,
518  2432,
519  float3(11, -2, -1),
520  float3(11, -2, 1),
521  float3(-0.0541f, -0.0541f, -0.9971f),
522  float2(0, 1)},
523  {"OBSurfTorus.001",
524  OB_MESH,
525  1024,
526  2048,
527  1024,
528  4096,
529  float3(5.34467f, -2.65533f, -0.176777f),
530  float3(5.232792f, -2.411795f, -0.220835f),
531  float3(-0.5042f, -0.5042f, -0.7011f),
532  float2(0, 1)},
533  {"OBTaperCube",
534  OB_MESH,
535  106,
536  208,
537  104,
538  416,
539  float3(24.444445f, 0.502543f, -0.753814f),
540  float3(23.790743f, 0.460522f, -0.766546f),
541  float3(-0.0546f, 0.1716f, 0.9837f)},
542  {"OBText",
543  OB_MESH,
544  177,
545  345,
546  171,
547  513,
548  float3(1.75f, -9.458f, 0),
549  float3(0.587f, -9.406f, 0),
550  float3(0, 0, 1),
551  float2(0.017544f, 0)},
552  {"OBUVCube",
553  OB_MESH,
554  8,
555  13,
556  7,
557  26,
558  float3(7, 1, -1),
559  float3(5, 1, 1),
560  float3(0, 0, 1),
561  float2(0.654526f, 0.579873f)},
562  {"OBUVImageCube",
563  OB_MESH,
564  8,
565  13,
566  7,
567  26,
568  float3(10, 1, -1),
569  float3(8, 1, 1),
570  float3(0, 0, 1),
571  float2(0.654526f, 0.579873f)},
572  {"OBVColCube",
573  OB_MESH,
574  8,
575  13,
576  7,
577  26,
578  float3(13, 1, -1),
579  float3(11, 1, 1),
580  float3(0, 0, 1),
581  float2(0, 0),
582  float4(0.0f, 0.002125f, 1.0f, 1.0f)},
583  {"OBVGroupCube",
584  OB_MESH,
585  8,
586  13,
587  7,
588  26,
589  float3(16, 1, -1),
590  float3(14, 1, 1),
591  float3(0, 0, 1)},
592  };
593  import_and_check("all_objects.obj", expect, std::size(expect), 7);
594 }
595 
596 TEST_F(obj_importer_test, import_cubes_vertex_colors)
597 {
598  Expectation expect[] = {
599  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
600  {"OBCubeCornerByte",
601  OB_MESH,
602  8,
603  12,
604  6,
605  24,
606  float3(1.0f, 1.0f, -3.812445f),
607  float3(-1.0f, -1.0f, -1.812445f),
608  float3(0, 0, 0),
609  float2(0, 0),
610  float4(0.89627f, 0.036889f, 0.47932f, 1.0f)},
611  {"OBCubeCornerFloat",
612  OB_MESH,
613  8,
614  12,
615  6,
616  24,
617  float3(3.481967f, 1.0f, -3.812445f),
618  float3(1.481967f, -1.0f, -1.812445f),
619  float3(0, 0, 0),
620  float2(0, 0),
621  float4(1.564582f, 0.039217f, 0.664309f, 1.0f)},
622  {"OBCubeMultiColorAttribs",
623  OB_MESH,
624  8,
625  12,
626  6,
627  24,
628  float3(-4.725068f, -1.0f, 1.0f),
629  float3(-2.725068f, 1.0f, -1.0f),
630  float3(0, 0, 0),
631  float2(0, 0),
632  float4(0.270498f, 0.47932f, 0.262251f, 1.0f)},
633  {"OBCubeNoColors",
634  OB_MESH,
635  8,
636  12,
637  6,
638  24,
639  float3(-4.550208f, -1.0f, -1.918042f),
640  float3(-2.550208f, 1.0f, -3.918042f)},
641  {"OBCubeVertexByte",
642  OB_MESH,
643  8,
644  12,
645  6,
646  24,
647  float3(1.0f, 1.0f, -1.0f),
648  float3(-1.0f, -1.0f, 1.0f),
649  float3(0, 0, 0),
650  float2(0, 0),
651  float4(0.846873f, 0.027321f, 0.982123f, 1.0f)},
652  {"OBCubeVertexFloat",
653  OB_MESH,
654  8,
655  12,
656  6,
657  24,
658  float3(3.392028f, 1.0f, -1.0f),
659  float3(1.392028f, -1.0f, 1.0f),
660  float3(0, 0, 0),
661  float2(0, 0),
662  float4(49.99467f, 0.027321f, 0.982123f, 1.0f)},
663  };
664  import_and_check("cubes_vertex_colors.obj", expect, std::size(expect), 0);
665 }
666 
667 TEST_F(obj_importer_test, import_cubes_vertex_colors_mrgb)
668 {
669  Expectation expect[] = {
670  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
671  {"OBCubeMRGB",
672  OB_MESH,
673  8,
674  12,
675  6,
676  24,
677  float3(4, 1, -1),
678  float3(2, -1, 1),
679  float3(0, 0, 0),
680  float2(0, 0),
681  float4(0.8714f, 0.6308f, 0.5271f, 1.0f)},
682  {"OBCubeXYZRGB",
683  OB_MESH,
684  8,
685  12,
686  6,
687  24,
688  float3(1, 1, -1),
689  float3(-1, -1, 1),
690  float3(0, 0, 0),
691  float2(0, 0),
692  float4(0.6038f, 0.3185f, 0.1329f, 1.0f)},
693  {"OBTriMRGB",
694  OB_MESH,
695  3,
696  3,
697  1,
698  3,
699  float3(12, 1, -1),
700  float3(10, 0, -1),
701  float3(0, 0, 0),
702  float2(0, 0),
703  float4(1.0f, 0.0f, 0.0f, 1.0f)},
704  {
705  "OBTriNoColors",
706  OB_MESH,
707  3,
708  3,
709  1,
710  3,
711  float3(8, 1, -1),
712  float3(6, 0, -1),
713  },
714  };
715  import_and_check("cubes_vertex_colors_mrgb.obj", expect, std::size(expect), 0);
716 }
717 
718 TEST_F(obj_importer_test, import_vertices)
719 {
720  Expectation expect[] = {
721  {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
722  /* Loose vertices without faces or edges. */
723  {"OBCube.001", OB_MESH, 8, 0, 0, 0, float3(1, 1, -1), float3(-1, 1, 1)},
724  };
725  import_and_check("vertices.obj", expect, std::size(expect), 0);
726 }
727 
728 } // namespace blender::io::obj
typedef float(TangentPoint)[2]
float(* BKE_curve_nurbs_vert_coords_alloc(const struct ListBase *lb, int *r_vert_len))[3]
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_get_layer(const struct CustomData *data, int type)
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(const struct Object *object)
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define M_PI_2
Definition: BLI_math_base.h:23
#define FILE_MAX
external readfile function prototypes.
@ DAG_EVAL_VIEWPORT
Definition: DEG_depsgraph.h:45
#define DEG_OBJECT_ITER_END
#define DEG_OBJECT_ITER_BEGIN(graph_, instance_, flag_)
@ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY
@ DEG_ITER_OBJECT_FLAG_VISIBLE
@ DEG_ITER_OBJECT_FLAG_DUPLI
@ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ CU_NURB_ENDPOINT
@ CD_PROP_COLOR
@ CD_MLOOPUV
@ OB_MESH
@ OB_CURVES_LEGACY
@ IO_AXIS_Y
Definition: IO_orientation.h:9
@ IO_AXIS_NEGATIVE_Z
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
virtual void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode)
bool blendfile_load(const char *filepath)
void import_and_check(const char *path, const Expectation *expect, size_t expect_count, int expect_mat_count, int expect_image_count=0)
Curve curve
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
ccl_device_inline float3 exp(float3 v)
Definition: math_float3.h:392
TEST_F(obj_exporter_test, filter_objects_curves_as_mesh)
void importer_main(bContext *C, const OBJImportParams &import_params)
Definition: obj_importer.cc:94
vec_base< float, 3 > float3
vec_base< float, 4 > float4
vec_base< float, 2 > float2
struct Scene * curscene
Definition: BLO_readfile.h:64
struct ViewLayer * cur_view_layer
Definition: BLO_readfile.h:65
struct Main * main
Definition: BLO_readfile.h:56
ListBase nurb
float co[3]
ListBase materials
Definition: BKE_main.h:174
ListBase images
Definition: BKE_main.h:176
CustomData vdata
struct MVert * mvert
int totedge
int totvert
int totpoly
int totloop
CustomData ldata
short flagu
short orderu
void * data
float x