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