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

This commit is contained in:
Sybren A. Stüvel
2017-04-14 18:20:24 +02:00
parent 4d117f2fd2
commit 5fa4f397c2
6 changed files with 70 additions and 6 deletions

View File

@@ -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;
}

View File

@@ -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))) {

View File

@@ -40,6 +40,9 @@ class AbcTransformWriter : public AbcObjectWriter {
bool m_visible;
bool m_inherits_xform;
public:
Object *m_proxy_from;
public:
AbcTransformWriter(Object *ob,
const Alembic::AbcGeom::OObject &abc_parent,

View File

@@ -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)

View File

@@ -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);

View File

@@ -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])