Alembic import: fixed dupligroup export when the dupli-empty has a parent
This commit is contained in:
@@ -448,8 +448,13 @@ 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) {
|
||||
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) {
|
||||
parent_writer = createTransformWriter(parent, NULL, 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;
|
||||
}
|
||||
|
@@ -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))) {
|
||||
|
@@ -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,
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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])
|
||||
|
Reference in New Issue
Block a user