diff options
-rw-r--r-- | source/blender/io/common/IO_dupli_persistent_id.hh | 7 | ||||
-rw-r--r-- | source/blender/io/common/intern/abstract_hierarchy_iterator.cc | 8 | ||||
-rw-r--r-- | source/blender/io/common/intern/dupli_persistent_id.cc | 22 | ||||
-rw-r--r-- | tests/gtests/usd/object_identifier_test.cc | 37 | ||||
-rw-r--r-- | tests/python/alembic_tests.py | 20 |
5 files changed, 78 insertions, 16 deletions
diff --git a/source/blender/io/common/IO_dupli_persistent_id.hh b/source/blender/io/common/IO_dupli_persistent_id.hh index dc70c1cdf31..5dc54164684 100644 --- a/source/blender/io/common/IO_dupli_persistent_id.hh +++ b/source/blender/io/common/IO_dupli_persistent_id.hh @@ -48,6 +48,13 @@ class PersistentID { /* Construct the persistent ID of this instance's instancer. */ PersistentID instancer_pid() const; + /* Construct a string representation by reversing the persistent ID. + * In case of a duplicator that is duplicated itself as well, this + * results in strings like: + * "3" for the duplicated duplicator, and + * "3-0", "3-1", etc. for its duplis. */ + std::string as_object_name_suffix() const; + friend bool operator==(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b); friend bool operator<(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b); friend std::ostream &operator<<(std::ostream &os, const PersistentID &persistent_id); diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc index c8d916c0950..3622c1eb7cd 100644 --- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc +++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc @@ -427,10 +427,10 @@ void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object, copy_m4_m4(context->matrix_world, dupli_object->mat); // Construct export name for the dupli-instance. - std::stringstream suffix_stream; - suffix_stream << std::hex; - suffix_stream << "-" << context->persistent_id; - context->export_name = make_valid_name(get_object_name(context->object) + suffix_stream.str()); + std::stringstream export_name_stream; + export_name_stream << get_object_name(context->object) << "-" + << context->persistent_id.as_object_name_suffix(); + context->export_name = make_valid_name(export_name_stream.str()); ExportGraph::key_type graph_index = determine_graph_index_dupli( context, dupli_object, dupli_parent_finder); diff --git a/source/blender/io/common/intern/dupli_persistent_id.cc b/source/blender/io/common/intern/dupli_persistent_id.cc index 8563fd5cea6..f0f3079a75c 100644 --- a/source/blender/io/common/intern/dupli_persistent_id.cc +++ b/source/blender/io/common/intern/dupli_persistent_id.cc @@ -22,6 +22,7 @@ #include <climits> #include <cstring> #include <ostream> +#include <sstream> namespace blender::io { @@ -84,6 +85,27 @@ PersistentID PersistentID::instancer_pid() const return PersistentID(new_pid_values); } +std::string PersistentID::as_object_name_suffix() const +{ + std::stringstream stream; + + /* Find one past the last index. */ + int index; + for (index = 0; index < array_length_ && persistent_id_[index] < INT_MAX; ++index) + ; + + /* Iterate backward to construct the string. */ + --index; + for (; index >= 0; --index) { + stream << persistent_id_[index]; + if (index > 0) { + stream << "-"; + } + } + + return stream.str(); +} + bool operator<(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b) { const PersistentID::PIDArray &pid_a = persistent_id_a.persistent_id_; diff --git a/tests/gtests/usd/object_identifier_test.cc b/tests/gtests/usd/object_identifier_test.cc index a914ec7e89d..810d4470260 100644 --- a/tests/gtests/usd/object_identifier_test.cc +++ b/tests/gtests/usd/object_identifier_test.cc @@ -39,11 +39,30 @@ Object *fake_pointer(int value) /* PersistentID subclass for use in tests, making it easier to construct test values. */ class TestPersistentID : public PersistentID { public: - TestPersistentID(int value0, int value1) + TestPersistentID(int value0, + int value1, + int value2, + int value3, + int value4, + int value5, + int value6, + int value7) { persistent_id_[0] = value0; persistent_id_[1] = value1; - persistent_id_[2] = INT_MAX; + persistent_id_[2] = value2; + persistent_id_[3] = value3; + persistent_id_[4] = value4; + persistent_id_[5] = value5; + persistent_id_[6] = value6; + persistent_id_[7] = value7; + } + TestPersistentID(int value0, int value1, int value2) + : TestPersistentID(value0, value1, value2, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX) + { + } + TestPersistentID(int value0, int value1) : TestPersistentID(value0, value1, INT_MAX) + { } explicit TestPersistentID(int value0) : TestPersistentID(value0, INT_MAX) { @@ -199,5 +218,19 @@ TEST_F(PersistentIDTest, instancer_id) EXPECT_LT(expect_instancer_id, empty_id); } +TEST_F(PersistentIDTest, as_object_name_suffix) +{ + EXPECT_EQ("", PersistentID().as_object_name_suffix()); + EXPECT_EQ("47", TestPersistentID(47).as_object_name_suffix()); + EXPECT_EQ("327-47", TestPersistentID(47, 327).as_object_name_suffix()); + EXPECT_EQ("42-327-47", TestPersistentID(47, 327, 42).as_object_name_suffix()); + + EXPECT_EQ("7-6-5-4-3-2-1-0", TestPersistentID(0, 1, 2, 3, 4, 5, 6, 7).as_object_name_suffix()); + + EXPECT_EQ("0-0-0", TestPersistentID(0, 0, 0).as_object_name_suffix()); + EXPECT_EQ("0-0", TestPersistentID(0, 0).as_object_name_suffix()); + EXPECT_EQ("-3--2--1", TestPersistentID(-1, -2, -3).as_object_name_suffix()); +} + } // namespace io } // namespace blender diff --git a/tests/python/alembic_tests.py b/tests/python/alembic_tests.py index 4d7ae97b327..66545dc85c7 100644 --- a/tests/python/alembic_tests.py +++ b/tests/python/alembic_tests.py @@ -254,7 +254,7 @@ class DupliGroupExportTest(AbstractAlembicTest): # `--Triangle # |--Triangle # |--Empty-1 - # | `--Pole-0-1 + # | `--Pole-1-0 # | |--Pole # | `--Block-1-1 # | `--Block @@ -264,18 +264,18 @@ class DupliGroupExportTest(AbstractAlembicTest): # | `--Block-1 # | `--Block # |--Empty-2 - # | `--Pole-0-2 + # | `--Pole-2-0 # | |--Pole - # | `--Block-1-2 + # | `--Block-2-1 # | `--Block # `--Empty-0 # `--Pole-0-0 # |--Pole - # `--Block-1-0 + # `--Block-0-1 # `--Block # Now check the resulting Alembic file. - xform = self.abcprop(abc, '/Triangle/Empty-1/Pole-0-1/Block-1-1/.xform') + xform = self.abcprop(abc, '/Triangle/Empty-1/Pole-1-0/Block-1-1/.xform') self.assertEqual(1, xform['.inherits']) self.assertAlmostEqualFloatArray( xform['.vals'], @@ -288,17 +288,17 @@ class DupliGroupExportTest(AbstractAlembicTest): # If the property can be gotten, the hierarchy is okay. No need to actually check each xform. self.abcprop(abc, '/Triangle/.xform') self.abcprop(abc, '/Triangle/Empty-1/.xform') - self.abcprop(abc, '/Triangle/Empty-1/Pole-0-1/.xform') - self.abcprop(abc, '/Triangle/Empty-1/Pole-0-1/Block-1-1/.xform') + self.abcprop(abc, '/Triangle/Empty-1/Pole-1-0/.xform') + self.abcprop(abc, '/Triangle/Empty-1/Pole-1-0/Block-1-1/.xform') self.abcprop(abc, '/Triangle/Empty/.xform') self.abcprop(abc, '/Triangle/Empty/Pole-0/.xform') self.abcprop(abc, '/Triangle/Empty/Pole-0/Block-1/.xform') self.abcprop(abc, '/Triangle/Empty-2/.xform') - self.abcprop(abc, '/Triangle/Empty-2/Pole-0-2/.xform') - self.abcprop(abc, '/Triangle/Empty-2/Pole-0-2/Block-1-2/.xform') + self.abcprop(abc, '/Triangle/Empty-2/Pole-2-0/.xform') + self.abcprop(abc, '/Triangle/Empty-2/Pole-2-0/Block-2-1/.xform') self.abcprop(abc, '/Triangle/Empty-0/.xform') self.abcprop(abc, '/Triangle/Empty-0/Pole-0-0/.xform') - self.abcprop(abc, '/Triangle/Empty-0/Pole-0-0/Block-1-0/.xform') + self.abcprop(abc, '/Triangle/Empty-0/Pole-0-0/Block-0-1/.xform') class CurveExportTest(AbstractAlembicTest): |