Merge branch 'master' into blender2.8
[blender.git] / source / blender / alembic / intern / abc_transform.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Esteban Tovagliari, Cedric Paille, Kevin Dietrich
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 #include "abc_transform.h"
24
25 #include <OpenEXR/ImathBoxAlgo.h>
26
27 #include "abc_util.h"
28
29 extern "C" {
30 #include "DNA_object_types.h"
31
32 #include "BLI_math.h"
33
34 #include "BKE_object.h"
35
36 #include "DEG_depsgraph_query.h"
37 }
38
39 using Alembic::AbcGeom::OObject;
40 using Alembic::AbcGeom::OXform;
41 using Alembic::Abc::ISampleSelector;
42
43 /* ************************************************************************** */
44
45 static bool has_parent_camera(Object *ob)
46 {
47         if (!ob->parent) {
48                 return false;
49         }
50
51         Object *parent = ob->parent;
52
53         if (parent->type == OB_CAMERA) {
54                 return true;
55         }
56
57         return has_parent_camera(parent);
58 }
59
60 /* ************************************************************************** */
61
62 AbcTransformWriter::AbcTransformWriter(Object *ob,
63                                        const OObject &abc_parent,
64                                        AbcTransformWriter *parent,
65                                        unsigned int time_sampling,
66                                        ExportSettings &settings)
67     : AbcObjectWriter(ob, time_sampling, settings, parent)
68     , m_proxy_from(NULL)
69 {
70         m_is_animated = hasAnimation(m_object);
71
72         if (!m_is_animated) {
73                 time_sampling = 0;
74         }
75
76         m_xform = OXform(abc_parent, get_id_name(m_object), time_sampling);
77         m_schema = m_xform.getSchema();
78
79         /* Blender objects can't have a parent without inheriting the transform. */
80         m_inherits_xform = parent != NULL;
81 }
82
83 void AbcTransformWriter::do_write()
84 {
85         Object *ob_eval = DEG_get_evaluated_object(m_settings.depsgraph, m_object);
86
87         if (m_first_frame) {
88                 m_visibility = Alembic::AbcGeom::CreateVisibilityProperty(m_xform, m_xform.getSchema().getTimeSampling());
89         }
90
91         m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_VIEW));
92
93         if (!m_first_frame && !m_is_animated) {
94                 return;
95         }
96
97         float yup_mat[4][4];
98         create_transform_matrix(ob_eval, yup_mat,
99                                 m_inherits_xform ? ABC_MATRIX_LOCAL : ABC_MATRIX_WORLD,
100                                 m_proxy_from);
101
102         /* Only apply rotation to root camera, parenting will propagate it. */
103         if (ob_eval->type == OB_CAMERA && (!m_inherits_xform || !has_parent_camera(ob_eval))) {
104                 float rot_mat[4][4];
105                 axis_angle_to_mat4_single(rot_mat, 'X', -M_PI_2);
106                 mul_m4_m4m4(yup_mat, yup_mat, rot_mat);
107         }
108
109         if (!ob_eval->parent || !m_inherits_xform) {
110                 /* Only apply scaling to root objects, parenting will propagate it. */
111                 float scale_mat[4][4];
112                 scale_m4_fl(scale_mat, m_settings.global_scale);
113                 scale_mat[3][3] = m_settings.global_scale;  /* also scale translation */
114                 mul_m4_m4m4(yup_mat, yup_mat, scale_mat);
115                 yup_mat[3][3] /= m_settings.global_scale;  /* normalise the homogeneous component */
116         }
117
118         m_matrix = convert_matrix(yup_mat);
119         m_sample.setMatrix(m_matrix);
120         m_sample.setInheritsXforms(m_inherits_xform);
121         m_schema.set(m_sample);
122 }
123
124 Imath::Box3d AbcTransformWriter::bounds()
125 {
126         Imath::Box3d bounds;
127
128         for (int i = 0; i < m_children.size(); ++i) {
129                 Imath::Box3d box(m_children[i]->bounds());
130                 bounds.extendBy(box);
131         }
132
133         return Imath::transform(bounds, m_matrix);
134 }
135
136 bool AbcTransformWriter::hasAnimation(Object * /*ob*/) const
137 {
138         /* TODO(kevin): implement this. */
139         return true;
140 }
141
142 /* ************************************************************************** */
143
144 AbcEmptyReader::AbcEmptyReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
145     : AbcObjectReader(object, settings)
146 {
147         /* Empties have no data. It makes the import of Alembic files easier to
148          * understand when we name the empty after its name in Alembic. */
149         m_object_name = object.getName();
150
151         Alembic::AbcGeom::IXform xform(object, Alembic::AbcGeom::kWrapExisting);
152         m_schema = xform.getSchema();
153
154         get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
155 }
156
157 bool AbcEmptyReader::valid() const
158 {
159         return m_schema.valid();
160 }
161
162 bool AbcEmptyReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
163                                          const Object *const ob,
164                                          const char **err_str) const
165 {
166         if (!Alembic::AbcGeom::IXform::matches(alembic_header)) {
167                 *err_str = "Object type mismatch, Alembic object path pointed to XForm when importing, but not any more.";
168                 return false;
169         }
170
171         if (ob->type != OB_EMPTY) {
172                 *err_str = "Object type mismatch, Alembic object path points to XForm.";
173                 return false;
174         }
175
176         return true;
177 }
178
179 void AbcEmptyReader::readObjectData(Main *bmain, const ISampleSelector &UNUSED(sample_sel))
180 {
181         m_object = BKE_object_add_only_object(bmain, OB_EMPTY,
182                                               m_object_name.c_str());
183         m_object->data = NULL;
184 }