Merge branch 'master' into blender2.8
[blender.git] / source / blender / alembic / intern / abc_object.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_object.h"
24
25 #include "abc_util.h"
26
27 extern "C" {
28 #include "DNA_cachefile_types.h"
29 #include "DNA_constraint_types.h"
30 #include "DNA_modifier_types.h"
31 #include "DNA_object_types.h"
32 #include "DNA_space_types.h"  /* for FILE_MAX */
33
34 #include "BKE_constraint.h"
35 #include "BKE_idprop.h"
36 #include "BKE_library.h"
37 #include "BKE_modifier.h"
38 #include "BKE_object.h"
39
40 #include "BLI_listbase.h"
41 #include "BLI_math.h"
42 #include "BLI_string.h"
43 }
44
45 using Alembic::AbcGeom::IObject;
46 using Alembic::AbcGeom::IXform;
47 using Alembic::AbcGeom::IXformSchema;
48
49 using Alembic::AbcGeom::OCompoundProperty;
50 using Alembic::AbcGeom::ODoubleArrayProperty;
51 using Alembic::AbcGeom::ODoubleProperty;
52 using Alembic::AbcGeom::OFloatArrayProperty;
53 using Alembic::AbcGeom::OFloatProperty;
54 using Alembic::AbcGeom::OInt32ArrayProperty;
55 using Alembic::AbcGeom::OInt32Property;
56 using Alembic::AbcGeom::OStringArrayProperty;
57 using Alembic::AbcGeom::OStringProperty;
58
59 /* ************************************************************************** */
60
61 AbcObjectWriter::AbcObjectWriter(EvaluationContext *eval_ctx,
62                                  Scene *scene,
63                                  Object *ob,
64                                  uint32_t time_sampling,
65                                  ExportSettings &settings,
66                                  AbcObjectWriter *parent)
67     : m_object(ob)
68     , m_settings(settings)
69     , m_eval_ctx(eval_ctx)
70     , m_scene(scene)
71     , m_time_sampling(time_sampling)
72     , m_first_frame(true)
73 {
74         m_name = get_id_name(m_object) + "Shape";
75
76         if (parent) {
77                 parent->addChild(this);
78         }
79 }
80
81 AbcObjectWriter::~AbcObjectWriter()
82 {}
83
84 void AbcObjectWriter::addChild(AbcObjectWriter *child)
85 {
86         m_children.push_back(child);
87 }
88
89 Imath::Box3d AbcObjectWriter::bounds()
90 {
91         BoundBox *bb = BKE_object_boundbox_get(this->m_object);
92
93         if (!bb) {
94                 if (this->m_object->type != OB_CAMERA) {
95                         ABC_LOG(m_settings.logger) << "Bounding box is null!\n";
96                 }
97
98                 return Imath::Box3d();
99         }
100
101         /* Convert Z-up to Y-up. This also changes which vector goes into which min/max property. */
102         this->m_bounds.min.x = bb->vec[0][0];
103         this->m_bounds.min.y = bb->vec[0][2];
104         this->m_bounds.min.z = -bb->vec[6][1];
105
106         this->m_bounds.max.x = bb->vec[6][0];
107         this->m_bounds.max.y = bb->vec[6][2];
108         this->m_bounds.max.z = -bb->vec[0][1];
109
110         return this->m_bounds;
111 }
112
113 void AbcObjectWriter::write()
114 {
115         do_write();
116         m_first_frame = false;
117 }
118
119 /* ************************************************************************** */
120
121 AbcObjectReader::AbcObjectReader(const IObject &object, ImportSettings &settings)
122     : m_name("")
123     , m_object_name("")
124     , m_data_name("")
125     , m_object(NULL)
126     , m_iobject(object)
127     , m_settings(&settings)
128     , m_min_time(std::numeric_limits<chrono_t>::max())
129     , m_max_time(std::numeric_limits<chrono_t>::min())
130     , m_refcount(0)
131     , parent_reader(NULL)
132 {
133         m_name = object.getFullName();
134         std::vector<std::string> parts;
135         split(m_name, '/', parts);
136
137         if (parts.size() >= 2) {
138                 m_object_name = parts[parts.size() - 2];
139                 m_data_name = parts[parts.size() - 1];
140         }
141         else {
142                 m_object_name = m_data_name = parts[parts.size() - 1];
143         }
144
145         determine_inherits_xform();
146 }
147
148 /* Determine whether we can inherit our parent's XForm */
149 void AbcObjectReader::determine_inherits_xform()
150 {
151         m_inherits_xform = false;
152
153         IXform ixform = xform();
154         if (!ixform) {
155                 return;
156         }
157
158         const IXformSchema & schema(ixform.getSchema());
159         if (!schema.valid()) {
160                 std::cerr << "Alembic object " << ixform.getFullName()
161                           << " has an invalid schema." << std::endl;
162                 return;
163         }
164
165         m_inherits_xform = schema.getInheritsXforms();
166
167         IObject ixform_parent = ixform.getParent();
168         if (!ixform_parent.getParent()) {
169                 /* The archive top object certainly is not a transform itself, so handle
170                  * it as "no parent". */
171                 m_inherits_xform = false;
172         }
173         else {
174                 m_inherits_xform = ixform_parent && m_inherits_xform;
175         }
176 }
177
178 AbcObjectReader::~AbcObjectReader()
179 {}
180
181 const IObject &AbcObjectReader::iobject() const
182 {
183         return m_iobject;
184 }
185
186 Object *AbcObjectReader::object() const
187 {
188         return m_object;
189 }
190
191 void AbcObjectReader::object(Object *ob)
192 {
193         m_object = ob;
194 }
195
196 static Imath::M44d blend_matrices(const Imath::M44d &m0, const Imath::M44d &m1, const float weight)
197 {
198         float mat0[4][4], mat1[4][4], ret[4][4];
199
200         /* Cannot use Imath::M44d::getValue() since this returns a pointer to
201          * doubles and interp_m4_m4m4 expects pointers to floats. So need to convert
202          * the matrices manually.
203          */
204
205         for (int i = 0; i < 4; ++i) {
206                 for (int j = 0; j < 4; ++j) {
207                         mat0[i][j] = static_cast<float>(m0[i][j]);
208                 }
209         }
210
211         for (int i = 0; i < 4; ++i) {
212                 for (int j = 0; j < 4; ++j) {
213                         mat1[i][j] = static_cast<float>(m1[i][j]);
214                 }
215         }
216
217         interp_m4_m4m4(ret, mat0, mat1, weight);
218
219         Imath::M44d m;
220
221         for (int i = 0; i < 4; ++i) {
222                 for (int j = 0; j < 4; ++j) {
223                         m[i][j] = ret[i][j];
224                 }
225         }
226
227         return m;
228 }
229
230 Imath::M44d get_matrix(const IXformSchema &schema, const float time)
231 {
232         Alembic::AbcGeom::index_t i0, i1;
233         Alembic::AbcGeom::XformSample s0, s1;
234
235         const float weight = get_weight_and_index(time,
236                                                   schema.getTimeSampling(),
237                                                   schema.getNumSamples(),
238                                                   i0,
239                                                   i1);
240
241         schema.get(s0, Alembic::AbcGeom::ISampleSelector(i0));
242
243         if (i0 != i1) {
244                 schema.get(s1, Alembic::AbcGeom::ISampleSelector(i1));
245                 return blend_matrices(s0.getMatrix(), s1.getMatrix(), weight);
246         }
247
248         return s0.getMatrix();
249 }
250
251 DerivedMesh *AbcObjectReader::read_derivedmesh(DerivedMesh *dm,
252                                                const Alembic::Abc::ISampleSelector &UNUSED(sample_sel),
253                                                int UNUSED(read_flag),
254                                                const char **UNUSED(err_str))
255 {
256         return dm;
257 }
258
259 void AbcObjectReader::setupObjectTransform(const float time)
260 {
261         bool is_constant = false;
262
263         this->read_matrix(m_object->obmat, time, m_settings->scale, is_constant);
264         invert_m4_m4(m_object->imat, m_object->obmat);
265
266         BKE_object_apply_mat4(m_object, m_object->obmat, false,  false);
267
268         if (!is_constant) {
269                 bConstraint *con = BKE_constraint_add_for_object(m_object, NULL, CONSTRAINT_TYPE_TRANSFORM_CACHE);
270                 bTransformCacheConstraint *data = static_cast<bTransformCacheConstraint *>(con->data);
271                 BLI_strncpy(data->object_path, m_iobject.getFullName().c_str(), FILE_MAX);
272
273                 data->cache_file = m_settings->cache_file;
274                 id_us_plus(&data->cache_file->id);
275
276                 data->reader = reinterpret_cast<CacheReader *>(this);
277                 this->incref();
278         }
279 }
280
281 Alembic::AbcGeom::IXform AbcObjectReader::xform()
282 {
283         /* Check that we have an empty object (locator, bone head/tail...).  */
284         if (IXform::matches(m_iobject.getMetaData())) {
285                 return IXform(m_iobject, Alembic::AbcGeom::kWrapExisting);
286         }
287
288         /* Check that we have an object with actual data, in which case the
289          * parent Alembic object should contain the transform. */
290         IObject abc_parent = m_iobject.getParent();
291
292         /* The archive's top object can be recognised by not having a parent. */
293         if (abc_parent.getParent()
294                 && IXform::matches(abc_parent.getMetaData())) {
295                 return IXform(abc_parent, Alembic::AbcGeom::kWrapExisting);
296         }
297
298         /* Should not happen. */
299         std::cerr << "AbcObjectReader::xform(): "
300                   << "unable to find IXform for Alembic object '"
301                   << m_iobject.getFullName() << "'\n";
302         BLI_assert(false);
303
304         return IXform();
305 }
306
307 void AbcObjectReader::read_matrix(float r_mat[4][4], const float time,
308                                   const float scale, bool &is_constant)
309 {
310         IXform ixform = xform();
311         if (!ixform) {
312                 return;
313         }
314
315         const IXformSchema & schema(ixform.getSchema());
316         if (!schema.valid()) {
317                 std::cerr << "Alembic object " << ixform.getFullName()
318                           << " has an invalid schema." << std::endl;
319                 return;
320         }
321
322         const Imath::M44d matrix = get_matrix(schema, time);
323         convert_matrix(matrix, m_object, r_mat);
324
325         if (m_inherits_xform) {
326                 /* In this case, the matrix in Alembic is in local coordinates, so
327                  * convert to world matrix. To prevent us from reading and accumulating
328                  * all parent matrices in the Alembic file, we assume that the Blender
329                  * parent object is already updated for the current timekey, and use its
330                  * world matrix. */
331                 BLI_assert(m_object->parent);
332                 mul_m4_m4m4(r_mat, m_object->parent->obmat, r_mat);
333         }
334         else {
335                 /* Only apply scaling to root objects, parenting will propagate it. */
336                 float scale_mat[4][4];
337                 scale_m4_fl(scale_mat, scale);
338                 scale_mat[3][3] = scale; /* scale translations too */
339                 mul_m4_m4m4(r_mat, r_mat, scale_mat);
340         }
341
342         is_constant = schema.isConstant();
343 }
344
345 void AbcObjectReader::addCacheModifier()
346 {
347         ModifierData *md = modifier_new(eModifierType_MeshSequenceCache);
348         BLI_addtail(&m_object->modifiers, md);
349
350         MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
351
352         mcmd->cache_file = m_settings->cache_file;
353         id_us_plus(&mcmd->cache_file->id);
354
355         BLI_strncpy(mcmd->object_path, m_iobject.getFullName().c_str(), FILE_MAX);
356
357         mcmd->reader = reinterpret_cast<CacheReader *>(this);
358         this->incref();
359 }
360
361 chrono_t AbcObjectReader::minTime() const
362 {
363         return m_min_time;
364 }
365
366 chrono_t AbcObjectReader::maxTime() const
367 {
368         return m_max_time;
369 }
370
371 int AbcObjectReader::refcount() const
372 {
373         return m_refcount;
374 }
375
376 void AbcObjectReader::incref()
377 {
378         ++m_refcount;
379 }
380
381 void AbcObjectReader::decref()
382 {
383         --m_refcount;
384         BLI_assert(m_refcount >= 0);
385 }