Alembic: Construct ISampleSelector once and pass along
[blender.git] / source / blender / alembic / intern / alembic_capi.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_alembic.h"
24 #include <boost/foreach.hpp>
25
26 #include <Alembic/AbcMaterial/IMaterial.h>
27
28 #include "abc_archive.h"
29 #include "abc_camera.h"
30 #include "abc_curves.h"
31 #include "abc_hair.h"
32 #include "abc_mesh.h"
33 #include "abc_nurbs.h"
34 #include "abc_points.h"
35 #include "abc_transform.h"
36 #include "abc_util.h"
37
38 extern "C" {
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_cachefile_types.h"
42 #include "DNA_curve_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46
47 #include "BKE_cachefile.h"
48 #include "BKE_cdderivedmesh.h"
49 #include "BKE_context.h"
50 #include "BKE_curve.h"
51 #include "BKE_depsgraph.h"
52 #include "BKE_global.h"
53 #include "BKE_library.h"
54 #include "BKE_main.h"
55 #include "BKE_scene.h"
56
57 /* SpaceType struct has a member called 'new' which obviously conflicts with C++
58  * so temporarily redefining the new keyword to make it compile. */
59 #define new extern_new
60 #include "BKE_screen.h"
61 #undef new
62
63 #include "BLI_fileops.h"
64 #include "BLI_ghash.h"
65 #include "BLI_listbase.h"
66 #include "BLI_math.h"
67 #include "BLI_path_util.h"
68 #include "BLI_string.h"
69
70 #include "WM_api.h"
71 #include "WM_types.h"
72 }
73
74 using Alembic::Abc::Int32ArraySamplePtr;
75 using Alembic::Abc::ObjectHeader;
76
77 using Alembic::AbcGeom::MetaData;
78 using Alembic::AbcGeom::P3fArraySamplePtr;
79 using Alembic::AbcGeom::kWrapExisting;
80
81 using Alembic::AbcGeom::ICamera;
82 using Alembic::AbcGeom::ICurves;
83 using Alembic::AbcGeom::ICurvesSchema;
84 using Alembic::AbcGeom::IFaceSet;
85 using Alembic::AbcGeom::ILight;
86 using Alembic::AbcGeom::INuPatch;
87 using Alembic::AbcGeom::IObject;
88 using Alembic::AbcGeom::IPoints;
89 using Alembic::AbcGeom::IPointsSchema;
90 using Alembic::AbcGeom::IPolyMesh;
91 using Alembic::AbcGeom::IPolyMeshSchema;
92 using Alembic::AbcGeom::ISampleSelector;
93 using Alembic::AbcGeom::ISubD;
94 using Alembic::AbcGeom::IV2fGeomParam;
95 using Alembic::AbcGeom::IXform;
96 using Alembic::AbcGeom::IXformSchema;
97 using Alembic::AbcGeom::N3fArraySamplePtr;
98 using Alembic::AbcGeom::XformSample;
99 using Alembic::AbcGeom::ICompoundProperty;
100 using Alembic::AbcGeom::IN3fArrayProperty;
101 using Alembic::AbcGeom::IN3fGeomParam;
102 using Alembic::AbcGeom::V3fArraySamplePtr;
103
104 using Alembic::AbcMaterial::IMaterial;
105
106 struct AbcArchiveHandle {
107         int unused;
108 };
109
110 ABC_INLINE ArchiveReader *archive_from_handle(AbcArchiveHandle *handle)
111 {
112         return reinterpret_cast<ArchiveReader *>(handle);
113 }
114
115 ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
116 {
117         return reinterpret_cast<AbcArchiveHandle *>(archive);
118 }
119
120 //#define USE_NURBS
121
122 /* NOTE: this function is similar to visit_objects below, need to keep them in
123  * sync. */
124 static bool gather_objects_paths(const IObject &object, ListBase *object_paths)
125 {
126         if (!object.valid()) {
127                 return false;
128         }
129
130
131         size_t children_claiming_this_object = 0;
132         size_t num_children = object.getNumChildren();
133
134         for (size_t i = 0; i < num_children; ++i) {
135                 bool child_claims_this_object = gather_objects_paths(object.getChild(i), object_paths);
136                 children_claiming_this_object += child_claims_this_object ? 1 : 0;
137         }
138
139         const MetaData &md = object.getMetaData();
140         bool get_path = false;
141         bool parent_is_part_of_this_object = false;
142
143         if (!object.getParent()) {
144                 /* The root itself is not an object we should import. */
145         }
146         else if (IXform::matches(md)) {
147                 if (has_property(object.getProperties(), "locator")) {
148                         get_path = true;
149                 }
150                 else {
151                         get_path = children_claiming_this_object == 0;
152                 }
153
154                 /* Transforms are never "data" for their parent. */
155                 parent_is_part_of_this_object = false;
156         }
157         else {
158                 /* These types are "data" for their parent. */
159                 get_path =
160                         IPolyMesh::matches(md) ||
161                         ISubD::matches(md) ||
162 #ifdef USE_NURBS
163                         INuPatch::matches(md) ||
164 #endif
165                         ICamera::matches(md) ||
166                         IPoints::matches(md) ||
167                         ICurves::matches(md);
168                 parent_is_part_of_this_object = get_path;
169         }
170
171         if (get_path) {
172                 void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
173                 AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
174
175                 BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
176                 BLI_addtail(object_paths, abc_path);
177         }
178
179         return parent_is_part_of_this_object;
180 }
181
182 AbcArchiveHandle *ABC_create_handle(const char *filename, ListBase *object_paths)
183 {
184         ArchiveReader *archive = new ArchiveReader(filename);
185
186         if (!archive->valid()) {
187                 delete archive;
188                 return NULL;
189         }
190
191         if (object_paths) {
192                 gather_objects_paths(archive->getTop(), object_paths);
193         }
194
195         return handle_from_archive(archive);
196 }
197
198 void ABC_free_handle(AbcArchiveHandle *handle)
199 {
200         delete archive_from_handle(handle);
201 }
202
203 int ABC_get_version()
204 {
205         return ALEMBIC_LIBRARY_VERSION;
206 }
207
208 static void find_iobject(const IObject &object, IObject &ret,
209                          const std::string &path)
210 {
211         if (!object.valid()) {
212                 return;
213         }
214
215         std::vector<std::string> tokens;
216         split(path, '/', tokens);
217
218         IObject tmp = object;
219
220         std::vector<std::string>::iterator iter;
221         for (iter = tokens.begin(); iter != tokens.end(); ++iter) {
222                 IObject child = tmp.getChild(*iter);
223                 tmp = child;
224         }
225
226         ret = tmp;
227 }
228
229 struct ExportJobData {
230         Scene *scene;
231         Main *bmain;
232
233         char filename[1024];
234         ExportSettings settings;
235
236         short *stop;
237         short *do_update;
238         float *progress;
239
240         bool was_canceled;
241         bool export_ok;
242 };
243
244 static void export_startjob(void *customdata, short *stop, short *do_update, float *progress)
245 {
246         ExportJobData *data = static_cast<ExportJobData *>(customdata);
247
248         data->stop = stop;
249         data->do_update = do_update;
250         data->progress = progress;
251
252         /* XXX annoying hack: needed to prevent data corruption when changing
253          * scene frame in separate threads
254          */
255         G.is_rendering = true;
256         BKE_spacedata_draw_locks(true);
257
258         G.is_break = false;
259
260         try {
261                 Scene *scene = data->scene;
262                 AbcExporter exporter(scene, data->filename, data->settings);
263
264                 const int orig_frame = CFRA;
265
266                 data->was_canceled = false;
267                 exporter(data->bmain, *data->progress, data->was_canceled);
268
269                 if (CFRA != orig_frame) {
270                         CFRA = orig_frame;
271
272                         BKE_scene_update_for_newframe(data->bmain->eval_ctx, data->bmain,
273                                                       scene, scene->lay);
274                 }
275
276                 data->export_ok = !data->was_canceled;
277         }
278         catch (const std::exception &e) {
279                 ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
280         }
281         catch (...) {
282                 ABC_LOG(data->settings.logger) << "Abc Export: unknown error...\n";
283         }
284 }
285
286 static void export_endjob(void *customdata)
287 {
288         ExportJobData *data = static_cast<ExportJobData *>(customdata);
289
290         if (data->was_canceled && BLI_exists(data->filename)) {
291                 BLI_delete(data->filename, false, false);
292         }
293
294         if (!data->settings.logger.empty()) {
295                 std::cerr << data->settings.logger;
296                 WM_report(RPT_ERROR, "Errors occured during the export, look in the console to know more...");
297         }
298
299         G.is_rendering = false;
300         BKE_spacedata_draw_locks(false);
301 }
302
303 bool ABC_export(
304         Scene *scene,
305         bContext *C,
306         const char *filepath,
307         const struct AlembicExportParams *params,
308         bool as_background_job)
309 {
310         ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
311         job->scene = scene;
312         job->bmain = CTX_data_main(C);
313         job->export_ok = false;
314         BLI_strncpy(job->filename, filepath, 1024);
315
316         /* Alright, alright, alright....
317          *
318          * ExportJobData contains an ExportSettings containing a SimpleLogger.
319          *
320          * Since ExportJobData is a C-style struct dynamically allocated with
321          * MEM_mallocN (see above), its construtor is never called, therefore the
322          * ExportSettings constructor is not called which implies that the
323          * SimpleLogger one is not called either. SimpleLogger in turn does not call
324          * the constructor of its data members which ultimately means that its
325          * std::ostringstream member has a NULL pointer. To be able to properly use
326          * the stream's operator<<, the pointer needs to be set, therefore we have
327          * to properly construct everything. And this is done using the placement
328          * new operator as here below. It seems hackish, but I'm too lazy to
329          * do bigger refactor and maybe there is a better way which does not involve
330          * hardcore refactoring. */
331         new (&job->settings) ExportSettings();
332         job->settings.scene = job->scene;
333         job->settings.frame_start = params->frame_start;
334         job->settings.frame_end = params->frame_end;
335         job->settings.frame_step_xform = params->frame_step_xform;
336         job->settings.frame_step_shape = params->frame_step_shape;
337         job->settings.shutter_open = params->shutter_open;
338         job->settings.shutter_close = params->shutter_close;
339         job->settings.selected_only = params->selected_only;
340         job->settings.export_face_sets = params->face_sets;
341         job->settings.export_normals = params->normals;
342         job->settings.export_uvs = params->uvs;
343         job->settings.export_vcols = params->vcolors;
344         job->settings.export_hair = params->export_hair;
345         job->settings.export_particles = params->export_particles;
346         job->settings.apply_subdiv = params->apply_subdiv;
347         job->settings.flatten_hierarchy = params->flatten_hierarchy;
348         job->settings.visible_layers_only = params->visible_layers_only;
349         job->settings.renderable_only = params->renderable_only;
350         job->settings.use_subdiv_schema = params->use_subdiv_schema;
351         job->settings.export_ogawa = (params->compression_type == ABC_ARCHIVE_OGAWA);
352         job->settings.pack_uv = params->packuv;
353         job->settings.global_scale = params->global_scale;
354         job->settings.triangulate = params->triangulate;
355         job->settings.quad_method = params->quad_method;
356         job->settings.ngon_method = params->ngon_method;
357
358         if (job->settings.frame_start > job->settings.frame_end) {
359                 std::swap(job->settings.frame_start, job->settings.frame_end);
360         }
361
362         bool export_ok = false;
363         if (as_background_job) {
364                 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
365                                             CTX_wm_window(C),
366                                             job->scene,
367                                             "Alembic Export",
368                                             WM_JOB_PROGRESS,
369                                             WM_JOB_TYPE_ALEMBIC);
370
371                 /* setup job */
372                 WM_jobs_customdata_set(wm_job, job, MEM_freeN);
373                 WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
374                 WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
375
376                 WM_jobs_start(CTX_wm_manager(C), wm_job);
377         }
378         else {
379                 /* Fake a job context, so that we don't need NULL pointer checks while exporting. */
380                 short stop = 0, do_update = 0;
381                 float progress = 0.f;
382
383                 export_startjob(job, &stop, &do_update, &progress);
384                 export_endjob(job);
385                 export_ok = job->export_ok;
386
387                 MEM_freeN(job);
388         }
389
390         return export_ok;
391 }
392
393 /* ********************** Import file ********************** */
394
395 /**
396  * Generates an AbcObjectReader for this Alembic object and its children.
397  *
398  * \param object The Alembic IObject to visit.
399  * \param readers The created AbcObjectReader * will be appended to this vector.
400  * \param settings Import settings, not used directly but passed to the
401  *                 AbcObjectReader subclass constructors.
402  * \param r_assign_as_parent Return parameter, contains a list of reader
403  *                 pointers, whose parent pointer should still be set.
404  *                 This is filled when this call to visit_object() didn't create
405  *                 a reader that should be the parent.
406  * \return A pair of boolean and reader pointer. The boolean indicates whether
407  *         this IObject claims its parent as part of the same object
408  *         (for example an IPolyMesh object would claim its parent, as the mesh
409  *         is interpreted as the object's data, and the parent IXform as its
410  *         Blender object). The pointer is the AbcObjectReader that represents
411  *         the IObject parameter.
412  *
413  * NOTE: this function is similar to gather_object_paths above, need to keep
414  * them in sync. */
415 static std::pair<bool, AbcObjectReader *> visit_object(
416         const IObject &object,
417         AbcObjectReader::ptr_vector &readers,
418         ImportSettings &settings,
419         AbcObjectReader::ptr_vector &r_assign_as_parent)
420 {
421         const std::string & full_name = object.getFullName();
422
423         if (!object.valid()) {
424                 std::cerr << "  - "
425                           << full_name
426                           << ": object is invalid, skipping it and all its children.\n";
427                 return std::make_pair(false, static_cast<AbcObjectReader *>(NULL));
428         }
429
430         /* The interpretation of data by the children determine the role of this
431          * object. This is especially important for Xform objects, as they can be
432          * either part of a Blender object or a Blender object (Empty) themselves.
433          */
434         size_t children_claiming_this_object = 0;
435         size_t num_children = object.getNumChildren();
436         AbcObjectReader::ptr_vector claiming_child_readers;
437         AbcObjectReader::ptr_vector nonclaiming_child_readers;
438         AbcObjectReader::ptr_vector assign_as_parent;
439         for (size_t i = 0; i < num_children; ++i) {
440                 const IObject ichild = object.getChild(i);
441
442                 /* TODO: When we only support C++11, use std::tie() instead. */
443                 std::pair<bool, AbcObjectReader *> child_result;
444                 child_result = visit_object(ichild, readers, settings, assign_as_parent);
445
446                 bool child_claims_this_object = child_result.first;
447                 AbcObjectReader *child_reader = child_result.second;
448
449                 if (child_reader == NULL) {
450                         BLI_assert(!child_claims_this_object);
451                 }
452                 else {
453                         if (child_claims_this_object) {
454                                 claiming_child_readers.push_back(child_reader);
455                         } else {
456                                 nonclaiming_child_readers.push_back(child_reader);
457                         }
458                 }
459
460                 children_claiming_this_object += child_claims_this_object ? 1 : 0;
461         }
462         BLI_assert(children_claiming_this_object == claiming_child_readers.size());
463
464         AbcObjectReader *reader = NULL;
465         const MetaData &md = object.getMetaData();
466         bool parent_is_part_of_this_object = false;
467
468         if (!object.getParent()) {
469                 /* The root itself is not an object we should import. */
470         }
471         else if (IXform::matches(md)) {
472                 bool create_empty;
473
474                 /* An xform can either be a Blender Object (if it contains a mesh, for
475                  * example), but it can also be an Empty. Its correct translation to
476                  * Blender's data model depends on its children. */
477
478                 /* Check whether or not this object is a Maya locator, which is
479                  * similar to empties used as parent object in Blender. */
480                 if (has_property(object.getProperties(), "locator")) {
481                         create_empty = true;
482                 }
483                 else {
484                         create_empty = claiming_child_readers.empty();
485                 }
486
487                 if (create_empty) {
488                         reader = new AbcEmptyReader(object, settings);
489                 }
490         }
491         else if (IPolyMesh::matches(md)) {
492                 reader = new AbcMeshReader(object, settings);
493                 parent_is_part_of_this_object = true;
494         }
495         else if (ISubD::matches(md)) {
496                 reader = new AbcSubDReader(object, settings);
497                 parent_is_part_of_this_object = true;
498         }
499         else if (INuPatch::matches(md)) {
500 #ifdef USE_NURBS
501                 /* TODO(kevin): importing cyclic NURBS from other software crashes
502                  * at the moment. This is due to the fact that NURBS in other
503                  * software have duplicated points which causes buffer overflows in
504                  * Blender. Need to figure out exactly how these points are
505                  * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
506                  * Until this is fixed, disabling NURBS reading. */
507                 reader = new AbcNurbsReader(object, settings);
508                 parent_is_part_of_this_object = true;
509 #endif
510         }
511         else if (ICamera::matches(md)) {
512                 reader = new AbcCameraReader(object, settings);
513                 parent_is_part_of_this_object = true;
514         }
515         else if (IPoints::matches(md)) {
516                 reader = new AbcPointsReader(object, settings);
517                 parent_is_part_of_this_object = true;
518         }
519         else if (IMaterial::matches(md)) {
520                 /* Pass for now. */
521         }
522         else if (ILight::matches(md)) {
523                 /* Pass for now. */
524         }
525         else if (IFaceSet::matches(md)) {
526                 /* Pass, those are handled in the mesh reader. */
527         }
528         else if (ICurves::matches(md)) {
529                 reader = new AbcCurveReader(object, settings);
530                 parent_is_part_of_this_object = true;
531         }
532         else {
533                 std::cerr << "Alembic object " << full_name
534                           << " is of unsupported schema type '"
535                           << object.getMetaData().get("schemaObjTitle") << "'"
536                           << std::endl;
537         }
538
539         if (reader) {
540                 /* We have created a reader, which should imply that this object is
541                  * not claimed as part of any child Alembic object. */
542                 BLI_assert(claiming_child_readers.empty());
543
544                 readers.push_back(reader);
545                 reader->incref();
546
547                 AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
548                                                   MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
549                 BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
550                 BLI_addtail(&settings.cache_file->object_paths, abc_path);
551
552                 /* We can now assign this reader as parent for our children. */
553                 if (nonclaiming_child_readers.size() + assign_as_parent.size() > 0) {
554                         /* TODO: When we only support C++11, use for (a: b) instead. */
555                         BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
556                                 child_reader->parent_reader = reader;
557                         }
558                         BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
559                                 child_reader->parent_reader = reader;
560                         }
561                 }
562         }
563         else if (object.getParent()) {
564                 if (claiming_child_readers.size() > 0) {
565                         /* The first claiming child will serve just fine as parent to
566                          * our non-claiming children. Since all claiming children share
567                          * the same XForm, it doesn't really matter which one we pick. */
568                         AbcObjectReader *claiming_child = claiming_child_readers[0];
569                         BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
570                                 child_reader->parent_reader = claiming_child;
571                         }
572                         BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
573                                 child_reader->parent_reader = claiming_child;
574                         }
575                         /* Claiming children should have our parent set as their parent. */
576                         BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
577                                 r_assign_as_parent.push_back(child_reader);
578                         }
579                 }
580                 else {
581                         /* This object isn't claimed by any child, and didn't produce
582                          * a reader. Odd situation, could be the top Alembic object, or
583                          * an unsupported Alembic schema. Delegate to our parent. */
584                         BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
585                                 r_assign_as_parent.push_back(child_reader);
586                         }
587                         BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
588                                 r_assign_as_parent.push_back(child_reader);
589                         }
590                         BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
591                                 r_assign_as_parent.push_back(child_reader);
592                         }
593                 }
594         }
595
596         return std::make_pair(parent_is_part_of_this_object, reader);
597 }
598
599 enum {
600         ABC_NO_ERROR = 0,
601         ABC_ARCHIVE_FAIL,
602         ABC_UNSUPPORTED_HDF5,
603 };
604
605 struct ImportJobData {
606         Main *bmain;
607         Scene *scene;
608
609         char filename[1024];
610         ImportSettings settings;
611
612         std::vector<AbcObjectReader *> readers;
613
614         short *stop;
615         short *do_update;
616         float *progress;
617
618         char error_code;
619         bool was_cancelled;
620         bool import_ok;
621 };
622
623 ABC_INLINE bool is_mesh_and_strands(const IObject &object)
624 {
625         bool has_mesh = false;
626         bool has_curve = false;
627
628         for (int i = 0; i < object.getNumChildren(); ++i) {
629                 const IObject &child = object.getChild(i);
630
631                 if (!child.valid()) {
632                         continue;
633                 }
634
635                 const MetaData &md = child.getMetaData();
636
637                 if (IPolyMesh::matches(md)) {
638                         has_mesh = true;
639                 }
640                 else if (ISubD::matches(md)) {
641                         has_mesh = true;
642                 }
643                 else if (ICurves::matches(md)) {
644                         has_curve = true;
645                 }
646                 else if (IPoints::matches(md)) {
647                         has_curve = true;
648                 }
649         }
650
651         return has_mesh && has_curve;
652 }
653
654 static void import_startjob(void *user_data, short *stop, short *do_update, float *progress)
655 {
656         SCOPE_TIMER("Alembic import, objects reading and creation");
657
658         ImportJobData *data = static_cast<ImportJobData *>(user_data);
659
660         data->stop = stop;
661         data->do_update = do_update;
662         data->progress = progress;
663
664         ArchiveReader *archive = new ArchiveReader(data->filename);
665
666         if (!archive->valid()) {
667 #ifndef WITH_ALEMBIC_HDF5
668                 data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
669 #else
670                 data->error_code = ABC_ARCHIVE_FAIL;
671 #endif
672                 delete archive;
673                 return;
674         }
675
676         CacheFile *cache_file = static_cast<CacheFile *>(BKE_cachefile_add(data->bmain, BLI_path_basename(data->filename)));
677
678         /* Decrement the ID ref-count because it is going to be incremented for each
679          * modifier and constraint that it will be attached to, so since currently
680          * it is not used by anyone, its use count will off by one. */
681         id_us_min(&cache_file->id);
682
683         cache_file->is_sequence = data->settings.is_sequence;
684         cache_file->scale = data->settings.scale;
685         cache_file->handle = handle_from_archive(archive);
686         BLI_strncpy(cache_file->filepath, data->filename, 1024);
687
688         data->settings.cache_file = cache_file;
689
690         *data->do_update = true;
691         *data->progress = 0.05f;
692
693         /* Parse Alembic Archive. */
694         AbcObjectReader::ptr_vector assign_as_parent;
695         visit_object(archive->getTop(), data->readers, data->settings, assign_as_parent);
696
697         /* There shouldn't be any orphans. */
698         BLI_assert(assign_as_parent.size() == 0);
699
700         if (G.is_break) {
701                 data->was_cancelled = true;
702                 return;
703         }
704
705         *data->do_update = true;
706         *data->progress = 0.1f;
707
708         /* Create objects and set scene frame range. */
709
710         const float size = static_cast<float>(data->readers.size());
711         size_t i = 0;
712
713         chrono_t min_time = std::numeric_limits<chrono_t>::max();
714         chrono_t max_time = std::numeric_limits<chrono_t>::min();
715
716         ISampleSelector sample_sel(0.0f);
717         std::vector<AbcObjectReader *>::iterator iter;
718         for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
719                 AbcObjectReader *reader = *iter;
720
721                 if (reader->valid()) {
722                         reader->readObjectData(data->bmain, sample_sel);
723
724                         min_time = std::min(min_time, reader->minTime());
725                         max_time = std::max(max_time, reader->maxTime());
726                 }
727                 else {
728                         std::cerr << "Object " << reader->name() << " in Alembic file "
729                                   << data->filename << " is invalid.\n";
730                 }
731
732                 *data->progress = 0.1f + 0.3f * (++i / size);
733                 *data->do_update = true;
734
735                 if (G.is_break) {
736                         data->was_cancelled = true;
737                         return;
738                 }
739         }
740
741         if (data->settings.set_frame_range) {
742                 Scene *scene = data->scene;
743
744                 if (data->settings.is_sequence) {
745                         SFRA = data->settings.offset;
746                         EFRA = SFRA + (data->settings.sequence_len - 1);
747                         CFRA = SFRA;
748                 }
749                 else if (min_time < max_time) {
750                         SFRA = static_cast<int>(round(min_time * FPS));
751                         EFRA = static_cast<int>(round(max_time * FPS));
752                         CFRA = SFRA;
753                 }
754         }
755
756         /* Setup parenthood. */
757         for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
758                 const AbcObjectReader *reader = *iter;
759                 const AbcObjectReader *parent_reader = reader->parent_reader;
760                 Object *ob = reader->object();
761
762                 if (parent_reader == NULL) {
763                         ob->parent = NULL;
764                 }
765                 else {
766                         ob->parent = parent_reader->object();
767                 }
768         }
769
770         /* Setup transformations and constraints. */
771         i = 0;
772         for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
773                 AbcObjectReader *reader = *iter;
774                 reader->setupObjectTransform(0.0f);
775
776                 *data->progress = 0.7f + 0.3f * (++i / size);
777                 *data->do_update = true;
778
779                 if (G.is_break) {
780                         data->was_cancelled = true;
781                         return;
782                 }
783         }
784 }
785
786 static void import_endjob(void *user_data)
787 {
788         SCOPE_TIMER("Alembic import, cleanup");
789
790         ImportJobData *data = static_cast<ImportJobData *>(user_data);
791
792         std::vector<AbcObjectReader *>::iterator iter;
793
794         /* Delete objects on cancelation. */
795         if (data->was_cancelled) {
796                 for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
797                         Object *ob = (*iter)->object();
798
799                         /* It's possible that cancellation occured between the creation of
800                          * the reader and the creation of the Blender object. */
801                         if (ob == NULL) continue;
802
803                         BKE_libblock_free_us(data->bmain, ob);
804                 }
805         }
806         else {
807                 /* Add object to scene. */
808                 Base *base;
809
810                 BKE_scene_base_deselect_all(data->scene);
811
812                 for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
813                         Object *ob = (*iter)->object();
814                         ob->lay = data->scene->lay;
815
816                         base = BKE_scene_base_add(data->scene, ob);
817                         BKE_scene_base_select(data->scene, base);
818
819                         DAG_id_tag_update_ex(data->bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
820                 }
821
822                 DAG_relations_tag_update(data->bmain);
823         }
824
825         for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
826                 AbcObjectReader *reader = *iter;
827                 reader->decref();
828
829                 if (reader->refcount() == 0) {
830                         delete reader;
831                 }
832         }
833
834         switch (data->error_code) {
835                 default:
836                 case ABC_NO_ERROR:
837                         data->import_ok = !data->was_cancelled;
838                         break;
839                 case ABC_ARCHIVE_FAIL:
840                         WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
841                         break;
842                 case ABC_UNSUPPORTED_HDF5:
843                         WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
844                         break;
845         }
846
847         WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
848 }
849
850 static void import_freejob(void *user_data)
851 {
852         ImportJobData *data = static_cast<ImportJobData *>(user_data);
853         delete data;
854 }
855
856 bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence,
857                 bool set_frame_range, int sequence_len, int offset,
858                 bool validate_meshes, bool as_background_job)
859 {
860         /* Using new here since MEM_* funcs do not call ctor to properly initialize
861          * data. */
862         ImportJobData *job = new ImportJobData();
863         job->bmain = CTX_data_main(C);
864         job->scene = CTX_data_scene(C);
865         job->import_ok = false;
866         BLI_strncpy(job->filename, filepath, 1024);
867
868         job->settings.scale = scale;
869         job->settings.is_sequence = is_sequence;
870         job->settings.set_frame_range = set_frame_range;
871         job->settings.sequence_len = sequence_len;
872         job->settings.offset = offset;
873         job->settings.validate_meshes = validate_meshes;
874         job->error_code = ABC_NO_ERROR;
875         job->was_cancelled = false;
876
877         G.is_break = false;
878
879         bool import_ok = false;
880         if (as_background_job) {
881                 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
882                                             CTX_wm_window(C),
883                                             job->scene,
884                                             "Alembic Import",
885                                             WM_JOB_PROGRESS,
886                                             WM_JOB_TYPE_ALEMBIC);
887
888                 /* setup job */
889                 WM_jobs_customdata_set(wm_job, job, import_freejob);
890                 WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
891                 WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
892
893                 WM_jobs_start(CTX_wm_manager(C), wm_job);
894         }
895         else {
896                 /* Fake a job context, so that we don't need NULL pointer checks while importing. */
897                 short stop = 0, do_update = 0;
898                 float progress = 0.f;
899
900                 import_startjob(job, &stop, &do_update, &progress);
901                 import_endjob(job);
902                 import_ok = job->import_ok;
903
904                 import_freejob(job);
905         }
906
907         return import_ok;
908 }
909
910 /* ************************************************************************** */
911
912 void ABC_get_transform(CacheReader *reader, float r_mat[4][4], float time, float scale)
913 {
914         if (!reader) {
915                 return;
916         }
917
918         AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
919
920         bool is_constant = false;
921         abc_reader->read_matrix(r_mat, time, scale, is_constant);
922 }
923
924 /* ************************************************************************** */
925
926 DerivedMesh *ABC_read_mesh(CacheReader *reader,
927                            Object *ob,
928                            DerivedMesh *dm,
929                            const float time,
930                            const char **err_str,
931                            int read_flag)
932 {
933         AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
934         IObject iobject = abc_reader->iobject();
935
936         if (!iobject.valid()) {
937                 *err_str = "Invalid object: verify object path";
938                 return NULL;
939         }
940
941         const ObjectHeader &header = iobject.getHeader();
942         ISampleSelector sample_sel(time);
943
944         if (IPolyMesh::matches(header)) {
945                 if (ob->type != OB_MESH) {
946                         *err_str = "Object type mismatch: object path points to a mesh!";
947                         return NULL;
948                 }
949
950                 return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str);
951         }
952         else if (ISubD::matches(header)) {
953                 if (ob->type != OB_MESH) {
954                         *err_str = "Object type mismatch: object path points to a subdivision mesh!";
955                         return NULL;
956                 }
957
958                 return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str);
959         }
960         else if (IPoints::matches(header)) {
961                 if (ob->type != OB_MESH) {
962                         *err_str = "Object type mismatch: object path points to a point cloud (requires a mesh object)!";
963                         return NULL;
964                 }
965
966                 return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str);
967         }
968         else if (ICurves::matches(header)) {
969                 if (ob->type != OB_CURVE) {
970                         *err_str = "Object type mismatch: object path points to a curve!";
971                         return NULL;
972                 }
973
974                 return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str);
975         }
976
977         *err_str = "Unsupported object type: verify object path"; // or poke developer
978         return NULL;
979 }
980
981 /* ************************************************************************** */
982
983 void CacheReader_free(CacheReader *reader)
984 {
985         AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
986         abc_reader->decref();
987
988         if (abc_reader->refcount() == 0) {
989                 delete abc_reader;
990         }
991 }
992
993 void CacheReader_incref(CacheReader *reader)
994 {
995         AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
996         abc_reader->incref();
997 }
998
999 CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, CacheReader *reader, Object *object, const char *object_path)
1000 {
1001         if (object_path[0] == '\0') {
1002                 return reader;
1003         }
1004
1005         ArchiveReader *archive = archive_from_handle(handle);
1006
1007         if (!archive || !archive->valid()) {
1008                 return reader;
1009         }
1010
1011         IObject iobject;
1012         find_iobject(archive->getTop(), iobject, object_path);
1013
1014         if (reader) {
1015                 CacheReader_free(reader);
1016         }
1017
1018         ImportSettings settings;
1019         AbcObjectReader *abc_reader = create_reader(iobject, settings);
1020         abc_reader->object(object);
1021         abc_reader->incref();
1022
1023         return reinterpret_cast<CacheReader *>(abc_reader);
1024 }