[Bf-blender-cvs] [e62b3dd3f51] sybren-usd: USD: added gtest for abstract hierarchy iterator

Sybren A. Stüvel noreply at git.blender.org
Fri Nov 8 17:49:46 CET 2019


Commit: e62b3dd3f51af46453985db0aaa881c625fba955
Author: Sybren A. Stüvel
Date:   Fri Nov 8 16:27:00 2019 +0100
Branches: sybren-usd
https://developer.blender.org/rBe62b3dd3f51af46453985db0aaa881c625fba955

USD: added gtest for abstract hierarchy iterator

This test loads a blend file and asserts that the export paths are
reported correctly by the abstract hierarchy iterator.

===================================================================

M	source/blender/usd/intern/abstract_hierarchy_iterator.cc
M	source/blender/usd/intern/abstract_hierarchy_iterator.h
M	tests/gtests/CMakeLists.txt
M	tests/gtests/alembic/CMakeLists.txt
A	tests/gtests/usd/CMakeLists.txt
A	tests/gtests/usd/usd_export_hierarchy_iterator_test.cc

===================================================================

diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
index 9eb3c5d6ff2..d7f174396f5 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
@@ -51,6 +51,10 @@ void HierarchyContext::mark_as_not_instanced()
   original_export_path.clear();
 }
 
+AbstractHierarchyWriter::~AbstractHierarchyWriter()
+{
+}
+
 AbstractHierarchyIterator::AbstractHierarchyIterator(Depsgraph *depsgraph)
     : depsgraph(depsgraph), writers()
 {
diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.h b/source/blender/usd/intern/abstract_hierarchy_iterator.h
index ff5cfbcb05a..8e4039e54d6 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.h
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.h
@@ -89,6 +89,7 @@ struct HierarchyContext {
 
 class AbstractHierarchyWriter {
  public:
+  virtual ~AbstractHierarchyWriter();
   virtual void write(HierarchyContext &context) = 0;
   // TODO(Sybren): add function like unused_during_iteration() that's called when a writer was
   // previously created, but wasn't used this iteration.
diff --git a/tests/gtests/CMakeLists.txt b/tests/gtests/CMakeLists.txt
index 285b414e997..b2ff5830ad9 100644
--- a/tests/gtests/CMakeLists.txt
+++ b/tests/gtests/CMakeLists.txt
@@ -18,4 +18,7 @@ if(WITH_GTESTS)
   if(WITH_ALEMBIC)
     add_subdirectory(alembic)
   endif()
+  if(WITH_USD)
+    add_subdirectory(usd)
+  endif()
 endif()
diff --git a/tests/gtests/alembic/CMakeLists.txt b/tests/gtests/alembic/CMakeLists.txt
index 57b1fb52022..7da33a096e9 100644
--- a/tests/gtests/alembic/CMakeLists.txt
+++ b/tests/gtests/alembic/CMakeLists.txt
@@ -22,6 +22,7 @@ set(INC
   .
   ..
   ../../../source/blender/blenlib
+  ../../../source/blender/blenloader
   ../../../source/blender/blenkernel
   ../../../source/blender/alembic
   ../../../source/blender/makesdna
diff --git a/tests/gtests/alembic/CMakeLists.txt b/tests/gtests/usd/CMakeLists.txt
similarity index 85%
copy from tests/gtests/alembic/CMakeLists.txt
copy to tests/gtests/usd/CMakeLists.txt
index 57b1fb52022..8f5897d551f 100644
--- a/tests/gtests/alembic/CMakeLists.txt
+++ b/tests/gtests/usd/CMakeLists.txt
@@ -22,21 +22,24 @@ set(INC
   .
   ..
   ../../../source/blender/blenlib
+  ../../../source/blender/blenloader
   ../../../source/blender/blenkernel
-  ../../../source/blender/alembic
+  ../../../source/blender/usd
   ../../../source/blender/makesdna
+  ../../../source/blender/makesrna
   ../../../source/blender/depsgraph
-  ${ALEMBIC_INCLUDE_DIRS}
+  ../../../intern/guardedalloc
+  ${USD_INCLUDE_DIRS}
   ${BOOST_INCLUDE_DIR}
   ${HDF5_INCLUDE_DIRS}
   ${OPENEXR_INCLUDE_DIRS}
 )
 
 set(LIB
-  bf_blenloader  # Should not be needed but gives linking error without it.
+  bf_blenloader
   bf_intern_opencolorio # Should not be needed but gives windows linker errors if the ocio libs are linked before this
   bf_gpu # Should not be needed but gives windows linker errors if the ocio libs are linked before this
-  bf_alembic
+  bf_usd
 )
 
 include_directories(${INC})
@@ -51,8 +54,8 @@ else()
 endif()
 
 # For motivation on doubling BLENDER_SORTED_LIBS, see ../bmesh/CMakeLists.txt
-BLENDER_SRC_GTEST(alembic "abc_matrix_test.cc;abc_export_test.cc;${_buildinfo_src}" "${LIB}")
+BLENDER_SRC_GTEST(usd "usd_export_hierarchy_iterator_test.cc;${_buildinfo_src}" "${LIB}")
 
 unset(_buildinfo_src)
 
-setup_liblinks(alembic_test)
+setup_liblinks(usd_test)
diff --git a/tests/gtests/usd/usd_export_hierarchy_iterator_test.cc b/tests/gtests/usd/usd_export_hierarchy_iterator_test.cc
new file mode 100644
index 00000000000..c8f34c0fad9
--- /dev/null
+++ b/tests/gtests/usd/usd_export_hierarchy_iterator_test.cc
@@ -0,0 +1,258 @@
+#include "testing/testing.h"
+
+// Keep first since utildefines defines AT which conflicts with STL
+#include "intern/abstract_hierarchy_iterator.h"
+
+extern "C" {
+#include "BKE_blender.h"
+#include "BKE_main.h"
+#include "BKE_modifier.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "BLO_readfile.h"
+
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph.h"
+
+#include "DNA_genfile.h"
+#include "DNA_scene_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "RNA_define.h"
+
+#include "MEM_guardedalloc.h"
+}
+
+#include <map>
+#include <set>
+
+/* Mapping from ID.name to set of export hierarchy path. Duplicated objects can be exported
+ * multiple times, hence the set. */
+typedef std::map<std::string, std::set<std::string>> created_writers;
+
+class TestHierarchyWriter : public AbstractHierarchyWriter {
+ public:
+  created_writers &writers_map;
+
+  TestHierarchyWriter(created_writers &writers_map) : writers_map(writers_map)
+  {
+  }
+
+  void write(HierarchyContext &context) override
+  {
+    const char *id_name = context.object->id.name;
+    created_writers::mapped_type &writers = writers_map[id_name];
+
+    BLI_assert(writers.find(context.export_path) == writers.end());
+    writers.insert(context.export_path);
+  }
+};
+
+void debug_print_writers(const char *label, const created_writers &writers_map)
+{
+  printf("%s:\n", label);
+  for (auto idname_writers : writers_map) {
+    printf("    %s:\n", idname_writers.first.c_str());
+    for (const std::string &export_path : idname_writers.second) {
+      printf("      - %s\n", export_path.c_str());
+    }
+  }
+}
+
+class TestingHierarchyIterator : public AbstractHierarchyIterator {
+ public: /* Public so that the test cases can directly inspect the created writers. */
+  created_writers xform_writers;
+  created_writers data_writers;
+  created_writers hair_writers;
+  created_writers particle_writers;
+
+ public:
+  explicit TestingHierarchyIterator(Depsgraph *depsgraph) : AbstractHierarchyIterator(depsgraph)
+  {
+  }
+  virtual ~TestingHierarchyIterator()
+  {
+  }
+
+ protected:
+  AbstractHierarchyWriter *create_xform_writer(const HierarchyContext *context) override
+  {
+    return new TestHierarchyWriter(xform_writers);
+  }
+  AbstractHierarchyWriter *create_data_writer(const HierarchyContext *context) override
+  {
+    return new TestHierarchyWriter(data_writers);
+  }
+  AbstractHierarchyWriter *create_hair_writer(const HierarchyContext *context) override
+  {
+    return new TestHierarchyWriter(hair_writers);
+  }
+  AbstractHierarchyWriter *create_particle_writer(const HierarchyContext *context) override
+  {
+    return new TestHierarchyWriter(particle_writers);
+  }
+
+  void delete_object_writer(AbstractHierarchyWriter *writer) override
+  {
+    delete writer;
+  }
+};
+
+class USDHierarchyIteratorTest : public testing::Test {
+ protected:
+  BlendFileData *bfile;
+  Depsgraph *depsgraph;
+  TestingHierarchyIterator *iterator;
+
+  virtual void SetUp()
+  {
+    bfile = nullptr;
+    depsgraph = nullptr;
+    iterator = nullptr;
+
+    /* Minimal code to make the exporter not crash, copied from main() in creator.c. */
+    DNA_sdna_current_init();
+    DEG_register_node_types();
+    RNA_init();
+    init_nodesystem();
+  }
+
+  virtual void TearDown()
+  {
+    iterator_free();
+    depsgraph_free();
+    blendfile_free();
+  }
+
+  /* Load a blend file, return 'ok' (true=good, false=bad) and set bfile.
+   * Fails the test if the file cannot be loaded.
+   */
+  bool blendfile_load(const char *filepath)
+  {
+    bfile = BLO_read_from_file(filepath, BLO_READ_SKIP_NONE, NULL /* reports */);
+    if (bfile == nullptr) {
+      ADD_FAILURE();
+      return false;
+    }
+
+    /* Create a dummy window manager. Some code would SEGFAULT without it. */
+    bfile->main->wm.first = MEM_callocN(sizeof(wmWindowManager), "Dummy Window Manager");
+    return true;
+  }
+  /* Free bfile if it is not nullptr */
+  void blendfile_free()
+  {
+    if (bfile == nullptr) {
+      return;
+    }
+    BLO_blendfiledata_free(bfile);
+    bfile = nullptr;
+  }
+
+  /* Create a depsgraph. Assumes a blend file has been loaded. */
+  void depsgraph_create()
+  {
+    /* TODO(sergey): Pass scene layer somehow? */
+    depsgraph = DEG_graph_new(
+        bfile->main, bfile->curscene, bfile->cur_view_layer, DAG_EVAL_RENDER);
+
+    DEG_graph_build_from_view_layer(
+        depsgraph, bfile->main, bfile->curscene, bfile->cur_view_layer);
+    BKE_scene_graph_update_tagged(depsgraph, bfile->main);
+  }
+  /* Free the depsgraph if it's not nullptr. */
+  void depsgraph_free()
+  {
+    if (depsgraph == nullptr) {
+      return;
+    }
+    DEG_graph_free(depsgraph);
+    depsgraph = nullptr;
+  }
+
+  /* Create a test iterator. */
+  void iterator_create()
+  {
+    iterator = new TestingHierarchyIterator(depsgraph);
+  }
+  /* Free the test iterator if it is not nullptr. */
+  void iterator_free()
+  {
+    if (iterator == nullptr) {
+      return;
+    }
+    delete iterator;
+    iterator = nullptr;
+  }
+};
+
+TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest)
+{
+  /* Load the test blend file. */
+  if (!blendfile_load("../../lib/tests/usd/usd_hierarchy_export_test.blend")) {
+    return;
+  }
+  depsgraph_create();
+  iterator_create();
+
+  iterator->iterate();
+
+  // Mapping from object name to set of export paths.
+  created_writers expected_xforms = {
+      {"OBCamera", {"/Camera"}},
+      {"OBDupli1", {"/Dupli1"}},
+      {"OBDupli2", {"/ParentOfDupli2/Dupli2"}},
+      {"OBGEO_Ear_L",
+       {"/Dupli1/GEO_Head-0/GEO_Ear_L-1",
+        "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L",
+        "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1"}},
+      {"OBGEO_Ear_R",
+       {"/Dupli1/GEO_Head-0/GEO_Ear_R-2",
+        "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R",
+        "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2"}},
+      {"OBGEO_Head",
+       {"/Dupli1/GEO_Head-0",
+        "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head",
+        "/ParentOfDupli2/Dupli2/GEO_Head-0"}},
+      {"OBGEO_Nose",
+       {"/Dupli1/GEO_Head-0/GEO_Nose-3",
+        "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose",
+        "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3"}},
+      {"

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list