[Bf-blender-cvs] [5fa4f397c20] master: Alembic import: fixed dupligroup export when the dupli-empty has a parent

Sybren A. Stüvel noreply at git.blender.org
Fri Apr 14 18:25:48 CEST 2017


Commit: 5fa4f397c2050fa15e28855acae1520377a4a517
Author: Sybren A. Stüvel
Date:   Fri Apr 14 18:20:24 2017 +0200
Branches: master
https://developer.blender.org/rB5fa4f397c2050fa15e28855acae1520377a4a517

Alembic import: fixed dupligroup export when the dupli-empty has a parent

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

M	source/blender/alembic/intern/abc_exporter.cc
M	source/blender/alembic/intern/abc_transform.cc
M	source/blender/alembic/intern/abc_transform.h
M	source/blender/alembic/intern/abc_util.cc
M	source/blender/alembic/intern/abc_util.h
M	tests/python/alembic_tests.py

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

diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index d949df1b20a..ef3196cb15d 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -448,7 +448,12 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare
 		 * parent by name. We'll just call createTransformWriter(), which will
 		 * return the parent's AbcTransformWriter pointer. */
 		if (parent->parent) {
-			parent_writer = createTransformWriter(parent, parent->parent, dupliObParent);
+			if (parent == dupliObParent) {
+				parent_writer = createTransformWriter(parent, parent->parent, NULL);
+			}
+			else {
+				parent_writer = createTransformWriter(parent, parent->parent, dupliObParent);
+			}
 		}
 		else if (parent == dupliObParent) {
 			if (dupliObParent->parent == NULL) {
@@ -468,6 +473,12 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare
 
 	my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer,
 	                                   m_trans_sampling_index, m_settings);
+
+	/* When flattening, the matrix of the dupliobject has to be added. */
+	if (m_settings.flatten_hierarchy && dupliObParent) {
+		my_writer->m_proxy_from = dupliObParent;
+	}
+
 	m_xforms[name] = my_writer;
 	return my_writer;
 }
diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc
index 2e626edeb8b..6e218cac429 100644
--- a/source/blender/alembic/intern/abc_transform.cc
+++ b/source/blender/alembic/intern/abc_transform.cc
@@ -62,6 +62,7 @@ AbcTransformWriter::AbcTransformWriter(Object *ob,
                                        unsigned int time_sampling,
                                        ExportSettings &settings)
     : AbcObjectWriter(NULL, ob, time_sampling, settings, parent)
+    , m_proxy_from(NULL)
 {
 	m_is_animated = hasAnimation(m_object);
 
@@ -90,7 +91,8 @@ void AbcTransformWriter::do_write()
 
 	float yup_mat[4][4];
 	create_transform_matrix(m_object, yup_mat,
-	                        m_inherits_xform ? ABC_MATRIX_LOCAL : ABC_MATRIX_WORLD);
+	                        m_inherits_xform ? ABC_MATRIX_LOCAL : ABC_MATRIX_WORLD,
+	                        m_proxy_from);
 
 	/* Only apply rotation to root camera, parenting will propagate it. */
 	if (m_object->type == OB_CAMERA && (!m_inherits_xform || !has_parent_camera(m_object))) {
diff --git a/source/blender/alembic/intern/abc_transform.h b/source/blender/alembic/intern/abc_transform.h
index 714adc299c1..59388e155dc 100644
--- a/source/blender/alembic/intern/abc_transform.h
+++ b/source/blender/alembic/intern/abc_transform.h
@@ -41,6 +41,9 @@ class AbcTransformWriter : public AbcObjectWriter {
 	bool m_inherits_xform;
 
 public:
+	Object *m_proxy_from;
+
+public:
 	AbcTransformWriter(Object *ob,
 	                   const Alembic::AbcGeom::OObject &abc_parent,
 	                   AbcTransformWriter *parent,
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index 248ca4e64ae..67d2d3b1eb2 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -257,7 +257,8 @@ void convert_matrix(const Imath::M44d &xform, Object *ob, float r_mat[4][4])
 
 /* Recompute transform matrix of object in new coordinate system
  * (from Z-Up to Y-Up). */
-void create_transform_matrix(Object *obj, float r_yup_mat[4][4], AbcMatrixMode mode)
+void create_transform_matrix(Object *obj, float r_yup_mat[4][4], AbcMatrixMode mode,
+                             Object *proxy_from)
 {
 	float zup_mat[4][4];
 
@@ -267,11 +268,16 @@ void create_transform_matrix(Object *obj, float r_yup_mat[4][4], AbcMatrixMode m
 		 * constraints and modifiers as well as the obj->parentinv matrix. */
 		invert_m4_m4(obj->parent->imat, obj->parent->obmat);
 		mul_m4_m4m4(zup_mat, obj->parent->imat, obj->obmat);
-		copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
 	}
 	else {
-		copy_m44_axis_swap(r_yup_mat, obj->obmat, ABC_YUP_FROM_ZUP);
+		copy_m4_m4(zup_mat, obj->obmat);
 	}
+
+	if (proxy_from) {
+		mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat);
+	}
+
+	copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
 }
 
 bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name)
diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h
index 7bde9ac6e15..74d0faf97d3 100644
--- a/source/blender/alembic/intern/abc_util.h
+++ b/source/blender/alembic/intern/abc_util.h
@@ -62,7 +62,8 @@ typedef enum {
 	ABC_MATRIX_WORLD = 1,
 	ABC_MATRIX_LOCAL = 2,
 } AbcMatrixMode;
-void create_transform_matrix(Object *obj, float r_transform_mat[4][4], AbcMatrixMode mode);
+void create_transform_matrix(Object *obj, float r_transform_mat[4][4],
+                             AbcMatrixMode mode, Object *proxy_from);
 
 void split(const std::string &s, const char delim, std::vector<std::string> &tokens);
 
diff --git a/tests/python/alembic_tests.py b/tests/python/alembic_tests.py
index 1af2a157b64..209b34a8634 100755
--- a/tests/python/alembic_tests.py
+++ b/tests/python/alembic_tests.py
@@ -221,5 +221,46 @@ class HierarchicalAndFlatExportTest(AbstractAlembicTest):
         )
 
 
+class DupliGroupExportTest(AbstractAlembicTest):
+    @with_tempdir
+    def test_hierarchical_export(self, tempdir: pathlib.Path):
+        abc = tempdir / 'dupligroup_hierarchical.abc'
+        script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
+                 "renderable_only=True, visible_layers_only=True, flatten=False)" % abc
+        self.run_blender('dupligroup-scene.blend', script)
+
+        # Now check the resulting Alembic file.
+        xform = self.abcprop(abc, '/Real_Cube/Linked_Suzanne/Cylinder/Suzanne/.xform')
+        self.assertEqual(1, xform['.inherits'])
+        self.assertAlmostEqualFloatArray(
+            xform['.vals'],
+            [1.0, 0.0, 0.0, 0.0,
+             0.0, 1.0, 0.0, 0.0,
+             0.0, 0.0, 1.0, 0.0,
+             0.0, 2.0, 0.0, 1.0]
+        )
+
+    @with_tempdir
+    def test_flat_export(self, tempdir: pathlib.Path):
+        abc = tempdir / 'dupligroup_hierarchical.abc'
+        script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
+                 "renderable_only=True, visible_layers_only=True, flatten=True)" % abc
+        self.run_blender('dupligroup-scene.blend', script)
+
+        # Now check the resulting Alembic file.
+        xform = self.abcprop(abc, '/Suzanne/.xform')
+        self.assertEqual(0, xform['.inherits'])
+
+        self.assertAlmostEqualFloatArray(
+            xform['.vals'],
+            [1.5, 0.0, 0.0, 0.0,
+             0.0, 1.5, 0.0, 0.0,
+             0.0, 0.0, 1.5, 0.0,
+             2.0, 3.0, 0.0, 1.0]
+        )
+
+
+
+
 if __name__ == '__main__':
     unittest.main(argv=sys.argv[0:1])




More information about the Bf-blender-cvs mailing list