2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * Contributor(s): Esteban Tovagliari, Cedric Paille, Kevin Dietrich
20 * ***** END GPL LICENSE BLOCK *****
23 #include "../ABC_alembic.h"
24 #include <boost/foreach.hpp>
26 #include <Alembic/AbcMaterial/IMaterial.h>
28 #include "abc_archive.h"
29 #include "abc_camera.h"
30 #include "abc_curves.h"
33 #include "abc_nurbs.h"
34 #include "abc_points.h"
35 #include "abc_transform.h"
39 #include "MEM_guardedalloc.h"
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"
47 #include "BKE_cachefile.h"
48 #include "BKE_cdderivedmesh.h"
49 #include "BKE_context.h"
50 #include "BKE_curve.h"
51 #include "BKE_global.h"
52 #include "BKE_layer.h"
53 #include "BKE_library.h"
55 #include "BKE_scene.h"
57 #include "DEG_depsgraph.h"
58 #include "DEG_depsgraph_build.h"
60 /* SpaceType struct has a member called 'new' which obviously conflicts with C++
61 * so temporarily redefining the new keyword to make it compile. */
62 #define new extern_new
63 #include "BKE_screen.h"
66 #include "BLI_fileops.h"
67 #include "BLI_ghash.h"
68 #include "BLI_listbase.h"
70 #include "BLI_path_util.h"
71 #include "BLI_string.h"
77 using Alembic::Abc::Int32ArraySamplePtr;
78 using Alembic::Abc::ObjectHeader;
80 using Alembic::AbcGeom::MetaData;
81 using Alembic::AbcGeom::P3fArraySamplePtr;
82 using Alembic::AbcGeom::kWrapExisting;
84 using Alembic::AbcGeom::ICamera;
85 using Alembic::AbcGeom::ICurves;
86 using Alembic::AbcGeom::ICurvesSchema;
87 using Alembic::AbcGeom::IFaceSet;
88 using Alembic::AbcGeom::ILight;
89 using Alembic::AbcGeom::INuPatch;
90 using Alembic::AbcGeom::IObject;
91 using Alembic::AbcGeom::IPoints;
92 using Alembic::AbcGeom::IPointsSchema;
93 using Alembic::AbcGeom::IPolyMesh;
94 using Alembic::AbcGeom::IPolyMeshSchema;
95 using Alembic::AbcGeom::ISampleSelector;
96 using Alembic::AbcGeom::ISubD;
97 using Alembic::AbcGeom::IV2fGeomParam;
98 using Alembic::AbcGeom::IXform;
99 using Alembic::AbcGeom::IXformSchema;
100 using Alembic::AbcGeom::N3fArraySamplePtr;
101 using Alembic::AbcGeom::XformSample;
102 using Alembic::AbcGeom::ICompoundProperty;
103 using Alembic::AbcGeom::IN3fArrayProperty;
104 using Alembic::AbcGeom::IN3fGeomParam;
105 using Alembic::AbcGeom::V3fArraySamplePtr;
107 using Alembic::AbcMaterial::IMaterial;
109 struct AbcArchiveHandle {
113 ABC_INLINE ArchiveReader *archive_from_handle(AbcArchiveHandle *handle)
115 return reinterpret_cast<ArchiveReader *>(handle);
118 ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
120 return reinterpret_cast<AbcArchiveHandle *>(archive);
125 /* NOTE: this function is similar to visit_objects below, need to keep them in
127 static bool gather_objects_paths(const IObject &object, ListBase *object_paths)
129 if (!object.valid()) {
134 size_t children_claiming_this_object = 0;
135 size_t num_children = object.getNumChildren();
137 for (size_t i = 0; i < num_children; ++i) {
138 bool child_claims_this_object = gather_objects_paths(object.getChild(i), object_paths);
139 children_claiming_this_object += child_claims_this_object ? 1 : 0;
142 const MetaData &md = object.getMetaData();
143 bool get_path = false;
144 bool parent_is_part_of_this_object = false;
146 if (!object.getParent()) {
147 /* The root itself is not an object we should import. */
149 else if (IXform::matches(md)) {
150 if (has_property(object.getProperties(), "locator")) {
154 get_path = children_claiming_this_object == 0;
157 /* Transforms are never "data" for their parent. */
158 parent_is_part_of_this_object = false;
161 /* These types are "data" for their parent. */
163 IPolyMesh::matches(md) ||
164 ISubD::matches(md) ||
166 INuPatch::matches(md) ||
168 ICamera::matches(md) ||
169 IPoints::matches(md) ||
170 ICurves::matches(md);
171 parent_is_part_of_this_object = get_path;
175 void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
176 AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
178 BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
179 BLI_addtail(object_paths, abc_path);
182 return parent_is_part_of_this_object;
185 AbcArchiveHandle *ABC_create_handle(const char *filename, ListBase *object_paths)
187 ArchiveReader *archive = new ArchiveReader(filename);
189 if (!archive->valid()) {
195 gather_objects_paths(archive->getTop(), object_paths);
198 return handle_from_archive(archive);
201 void ABC_free_handle(AbcArchiveHandle *handle)
203 delete archive_from_handle(handle);
206 int ABC_get_version()
208 return ALEMBIC_LIBRARY_VERSION;
211 static void find_iobject(const IObject &object, IObject &ret,
212 const std::string &path)
214 if (!object.valid()) {
218 std::vector<std::string> tokens;
219 split(path, '/', tokens);
221 IObject tmp = object;
223 std::vector<std::string>::iterator iter;
224 for (iter = tokens.begin(); iter != tokens.end(); ++iter) {
225 IObject child = tmp.getChild(*iter);
232 struct ExportJobData {
237 ExportSettings settings;
247 static void export_startjob(void *customdata, short *stop, short *do_update, float *progress)
249 ExportJobData *data = static_cast<ExportJobData *>(customdata);
252 data->do_update = do_update;
253 data->progress = progress;
255 /* XXX annoying hack: needed to prevent data corruption when changing
256 * scene frame in separate threads
258 G.is_rendering = true;
259 BKE_spacedata_draw_locks(true);
264 Scene *scene = data->scene;
265 AbcExporter exporter(scene, data->filename, data->settings);
267 const int orig_frame = CFRA;
269 data->was_canceled = false;
270 exporter(data->bmain, *data->progress, data->was_canceled);
272 if (CFRA != orig_frame) {
275 BKE_scene_update_for_newframe(data->bmain->eval_ctx, data->bmain, scene);
278 data->export_ok = !data->was_canceled;
280 catch (const std::exception &e) {
281 ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
284 ABC_LOG(data->settings.logger) << "Abc Export: unknown error...\n";
288 static void export_endjob(void *customdata)
290 ExportJobData *data = static_cast<ExportJobData *>(customdata);
292 if (data->was_canceled && BLI_exists(data->filename)) {
293 BLI_delete(data->filename, false, false);
296 if (!data->settings.logger.empty()) {
297 std::cerr << data->settings.logger;
298 WM_report(RPT_ERROR, "Errors occured during the export, look in the console to know more...");
301 G.is_rendering = false;
302 BKE_spacedata_draw_locks(false);
308 const char *filepath,
309 const struct AlembicExportParams *params,
310 bool as_background_job)
312 ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
314 job->bmain = CTX_data_main(C);
315 job->export_ok = false;
316 BLI_strncpy(job->filename, filepath, 1024);
318 /* Alright, alright, alright....
320 * ExportJobData contains an ExportSettings containing a SimpleLogger.
322 * Since ExportJobData is a C-style struct dynamically allocated with
323 * MEM_mallocN (see above), its construtor is never called, therefore the
324 * ExportSettings constructor is not called which implies that the
325 * SimpleLogger one is not called either. SimpleLogger in turn does not call
326 * the constructor of its data members which ultimately means that its
327 * std::ostringstream member has a NULL pointer. To be able to properly use
328 * the stream's operator<<, the pointer needs to be set, therefore we have
329 * to properly construct everything. And this is done using the placement
330 * new operator as here below. It seems hackish, but I'm too lazy to
331 * do bigger refactor and maybe there is a better way which does not involve
332 * hardcore refactoring. */
333 new (&job->settings) ExportSettings();
334 job->settings.scene = job->scene;
336 /* Sybren: for now we only export the active scene layer.
337 * Later in the 2.8 development process this may be replaced by using
338 * a specific collection for Alembic I/O, which can then be toggled
339 * between "real" objects and cached Alembic files. */
340 job->settings.sl = CTX_data_scene_layer(C);
342 job->settings.frame_start = params->frame_start;
343 job->settings.frame_end = params->frame_end;
344 job->settings.frame_step_xform = params->frame_step_xform;
345 job->settings.frame_step_shape = params->frame_step_shape;
346 job->settings.shutter_open = params->shutter_open;
347 job->settings.shutter_close = params->shutter_close;
349 /* Sybren: For now this is ignored, until we can get selection
350 * detection working through Base pointers (instead of ob->flags). */
351 job->settings.selected_only = params->selected_only;
353 job->settings.export_face_sets = params->face_sets;
354 job->settings.export_normals = params->normals;
355 job->settings.export_uvs = params->uvs;
356 job->settings.export_vcols = params->vcolors;
357 job->settings.export_hair = params->export_hair;
358 job->settings.export_particles = params->export_particles;
359 job->settings.apply_subdiv = params->apply_subdiv;
360 job->settings.flatten_hierarchy = params->flatten_hierarchy;
362 /* Sybren: visible_layer & renderable only is ignored for now,
363 * to be replaced with collections later in the 2.8 dev process
364 * (also see note above). */
365 job->settings.visible_layers_only = params->visible_layers_only;
366 job->settings.renderable_only = params->renderable_only;
368 job->settings.use_subdiv_schema = params->use_subdiv_schema;
369 job->settings.export_ogawa = (params->compression_type == ABC_ARCHIVE_OGAWA);
370 job->settings.pack_uv = params->packuv;
371 job->settings.global_scale = params->global_scale;
372 job->settings.triangulate = params->triangulate;
373 job->settings.quad_method = params->quad_method;
374 job->settings.ngon_method = params->ngon_method;
376 if (job->settings.frame_start > job->settings.frame_end) {
377 std::swap(job->settings.frame_start, job->settings.frame_end);
380 bool export_ok = false;
381 if (as_background_job) {
382 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
387 WM_JOB_TYPE_ALEMBIC);
390 WM_jobs_customdata_set(wm_job, job, MEM_freeN);
391 WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
392 WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
394 WM_jobs_start(CTX_wm_manager(C), wm_job);
397 /* Fake a job context, so that we don't need NULL pointer checks while exporting. */
398 short stop = 0, do_update = 0;
399 float progress = 0.f;
401 export_startjob(job, &stop, &do_update, &progress);
403 export_ok = job->export_ok;
411 /* ********************** Import file ********************** */
414 * Generates an AbcObjectReader for this Alembic object and its children.
416 * \param object The Alembic IObject to visit.
417 * \param readers The created AbcObjectReader * will be appended to this vector.
418 * \param settings Import settings, not used directly but passed to the
419 * AbcObjectReader subclass constructors.
420 * \param r_assign_as_parent Return parameter, contains a list of reader
421 * pointers, whose parent pointer should still be set.
422 * This is filled when this call to visit_object() didn't create
423 * a reader that should be the parent.
424 * \return A pair of boolean and reader pointer. The boolean indicates whether
425 * this IObject claims its parent as part of the same object
426 * (for example an IPolyMesh object would claim its parent, as the mesh
427 * is interpreted as the object's data, and the parent IXform as its
428 * Blender object). The pointer is the AbcObjectReader that represents
429 * the IObject parameter.
431 * NOTE: this function is similar to gather_object_paths above, need to keep
433 static std::pair<bool, AbcObjectReader *> visit_object(
434 const IObject &object,
435 AbcObjectReader::ptr_vector &readers,
436 ImportSettings &settings,
437 AbcObjectReader::ptr_vector &r_assign_as_parent)
439 const std::string & full_name = object.getFullName();
441 if (!object.valid()) {
444 << ": object is invalid, skipping it and all its children.\n";
445 return std::make_pair(false, static_cast<AbcObjectReader *>(NULL));
448 /* The interpretation of data by the children determine the role of this
449 * object. This is especially important for Xform objects, as they can be
450 * either part of a Blender object or a Blender object (Empty) themselves.
452 size_t children_claiming_this_object = 0;
453 size_t num_children = object.getNumChildren();
454 AbcObjectReader::ptr_vector claiming_child_readers;
455 AbcObjectReader::ptr_vector nonclaiming_child_readers;
456 AbcObjectReader::ptr_vector assign_as_parent;
457 for (size_t i = 0; i < num_children; ++i) {
458 const IObject ichild = object.getChild(i);
460 /* TODO: When we only support C++11, use std::tie() instead. */
461 std::pair<bool, AbcObjectReader *> child_result;
462 child_result = visit_object(ichild, readers, settings, assign_as_parent);
464 bool child_claims_this_object = child_result.first;
465 AbcObjectReader *child_reader = child_result.second;
467 if (child_reader == NULL) {
468 BLI_assert(!child_claims_this_object);
471 if (child_claims_this_object) {
472 claiming_child_readers.push_back(child_reader);
474 nonclaiming_child_readers.push_back(child_reader);
478 children_claiming_this_object += child_claims_this_object ? 1 : 0;
480 BLI_assert(children_claiming_this_object == claiming_child_readers.size());
482 AbcObjectReader *reader = NULL;
483 const MetaData &md = object.getMetaData();
484 bool parent_is_part_of_this_object = false;
486 if (!object.getParent()) {
487 /* The root itself is not an object we should import. */
489 else if (IXform::matches(md)) {
492 /* An xform can either be a Blender Object (if it contains a mesh, for
493 * example), but it can also be an Empty. Its correct translation to
494 * Blender's data model depends on its children. */
496 /* Check whether or not this object is a Maya locator, which is
497 * similar to empties used as parent object in Blender. */
498 if (has_property(object.getProperties(), "locator")) {
502 create_empty = claiming_child_readers.empty();
506 reader = new AbcEmptyReader(object, settings);
509 else if (IPolyMesh::matches(md)) {
510 reader = new AbcMeshReader(object, settings);
511 parent_is_part_of_this_object = true;
513 else if (ISubD::matches(md)) {
514 reader = new AbcSubDReader(object, settings);
515 parent_is_part_of_this_object = true;
517 else if (INuPatch::matches(md)) {
519 /* TODO(kevin): importing cyclic NURBS from other software crashes
520 * at the moment. This is due to the fact that NURBS in other
521 * software have duplicated points which causes buffer overflows in
522 * Blender. Need to figure out exactly how these points are
523 * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
524 * Until this is fixed, disabling NURBS reading. */
525 reader = new AbcNurbsReader(object, settings);
526 parent_is_part_of_this_object = true;
529 else if (ICamera::matches(md)) {
530 reader = new AbcCameraReader(object, settings);
531 parent_is_part_of_this_object = true;
533 else if (IPoints::matches(md)) {
534 reader = new AbcPointsReader(object, settings);
535 parent_is_part_of_this_object = true;
537 else if (IMaterial::matches(md)) {
540 else if (ILight::matches(md)) {
543 else if (IFaceSet::matches(md)) {
544 /* Pass, those are handled in the mesh reader. */
546 else if (ICurves::matches(md)) {
547 reader = new AbcCurveReader(object, settings);
548 parent_is_part_of_this_object = true;
551 std::cerr << "Alembic object " << full_name
552 << " is of unsupported schema type '"
553 << object.getMetaData().get("schemaObjTitle") << "'"
558 /* We have created a reader, which should imply that this object is
559 * not claimed as part of any child Alembic object. */
560 BLI_assert(claiming_child_readers.empty());
562 readers.push_back(reader);
565 AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
566 MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
567 BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
568 BLI_addtail(&settings.cache_file->object_paths, abc_path);
570 /* We can now assign this reader as parent for our children. */
571 if (nonclaiming_child_readers.size() + assign_as_parent.size() > 0) {
572 /* TODO: When we only support C++11, use for (a: b) instead. */
573 BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
574 child_reader->parent_reader = reader;
576 BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
577 child_reader->parent_reader = reader;
581 else if (object.getParent()) {
582 if (claiming_child_readers.size() > 0) {
583 /* The first claiming child will serve just fine as parent to
584 * our non-claiming children. Since all claiming children share
585 * the same XForm, it doesn't really matter which one we pick. */
586 AbcObjectReader *claiming_child = claiming_child_readers[0];
587 BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
588 child_reader->parent_reader = claiming_child;
590 BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
591 child_reader->parent_reader = claiming_child;
593 /* Claiming children should have our parent set as their parent. */
594 BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
595 r_assign_as_parent.push_back(child_reader);
599 /* This object isn't claimed by any child, and didn't produce
600 * a reader. Odd situation, could be the top Alembic object, or
601 * an unsupported Alembic schema. Delegate to our parent. */
602 BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
603 r_assign_as_parent.push_back(child_reader);
605 BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
606 r_assign_as_parent.push_back(child_reader);
608 BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
609 r_assign_as_parent.push_back(child_reader);
614 return std::make_pair(parent_is_part_of_this_object, reader);
620 ABC_UNSUPPORTED_HDF5,
623 struct ImportJobData {
626 SceneLayer *scene_layer;
629 ImportSettings settings;
631 std::vector<AbcObjectReader *> readers;
642 ABC_INLINE bool is_mesh_and_strands(const IObject &object)
644 bool has_mesh = false;
645 bool has_curve = false;
647 for (int i = 0; i < object.getNumChildren(); ++i) {
648 const IObject &child = object.getChild(i);
650 if (!child.valid()) {
654 const MetaData &md = child.getMetaData();
656 if (IPolyMesh::matches(md)) {
659 else if (ISubD::matches(md)) {
662 else if (ICurves::matches(md)) {
665 else if (IPoints::matches(md)) {
670 return has_mesh && has_curve;
673 static void import_startjob(void *user_data, short *stop, short *do_update, float *progress)
675 SCOPE_TIMER("Alembic import, objects reading and creation");
677 ImportJobData *data = static_cast<ImportJobData *>(user_data);
680 data->do_update = do_update;
681 data->progress = progress;
683 ArchiveReader *archive = new ArchiveReader(data->filename);
685 if (!archive->valid()) {
686 #ifndef WITH_ALEMBIC_HDF5
687 data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
689 data->error_code = ABC_ARCHIVE_FAIL;
695 CacheFile *cache_file = static_cast<CacheFile *>(BKE_cachefile_add(data->bmain, BLI_path_basename(data->filename)));
697 /* Decrement the ID ref-count because it is going to be incremented for each
698 * modifier and constraint that it will be attached to, so since currently
699 * it is not used by anyone, its use count will off by one. */
700 id_us_min(&cache_file->id);
702 cache_file->is_sequence = data->settings.is_sequence;
703 cache_file->scale = data->settings.scale;
704 cache_file->handle = handle_from_archive(archive);
705 BLI_strncpy(cache_file->filepath, data->filename, 1024);
707 data->settings.cache_file = cache_file;
709 *data->do_update = true;
710 *data->progress = 0.05f;
712 /* Parse Alembic Archive. */
713 AbcObjectReader::ptr_vector assign_as_parent;
714 visit_object(archive->getTop(), data->readers, data->settings, assign_as_parent);
716 /* There shouldn't be any orphans. */
717 BLI_assert(assign_as_parent.size() == 0);
720 data->was_cancelled = true;
724 *data->do_update = true;
725 *data->progress = 0.1f;
727 /* Create objects and set scene frame range. */
729 const float size = static_cast<float>(data->readers.size());
732 chrono_t min_time = std::numeric_limits<chrono_t>::max();
733 chrono_t max_time = std::numeric_limits<chrono_t>::min();
735 ISampleSelector sample_sel(0.0f);
736 std::vector<AbcObjectReader *>::iterator iter;
737 for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
738 AbcObjectReader *reader = *iter;
740 if (reader->valid()) {
741 reader->readObjectData(data->bmain, sample_sel);
743 min_time = std::min(min_time, reader->minTime());
744 max_time = std::max(max_time, reader->maxTime());
747 std::cerr << "Object " << reader->name() << " in Alembic file "
748 << data->filename << " is invalid.\n";
751 *data->progress = 0.1f + 0.3f * (++i / size);
752 *data->do_update = true;
755 data->was_cancelled = true;
760 if (data->settings.set_frame_range) {
761 Scene *scene = data->scene;
763 if (data->settings.is_sequence) {
764 SFRA = data->settings.offset;
765 EFRA = SFRA + (data->settings.sequence_len - 1);
768 else if (min_time < max_time) {
769 SFRA = static_cast<int>(round(min_time * FPS));
770 EFRA = static_cast<int>(round(max_time * FPS));
775 /* Setup parenthood. */
776 for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
777 const AbcObjectReader *reader = *iter;
778 const AbcObjectReader *parent_reader = reader->parent_reader;
779 Object *ob = reader->object();
781 if (parent_reader == NULL) {
785 ob->parent = parent_reader->object();
789 /* Setup transformations and constraints. */
791 for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
792 AbcObjectReader *reader = *iter;
793 reader->setupObjectTransform(0.0f);
795 *data->progress = 0.7f + 0.3f * (++i / size);
796 *data->do_update = true;
799 data->was_cancelled = true;
805 static void import_endjob(void *user_data)
807 SCOPE_TIMER("Alembic import, cleanup");
809 ImportJobData *data = static_cast<ImportJobData *>(user_data);
811 std::vector<AbcObjectReader *>::iterator iter;
813 /* Delete objects on cancelation. */
814 if (data->was_cancelled) {
815 for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
816 Object *ob = (*iter)->object();
818 /* It's possible that cancellation occured between the creation of
819 * the reader and the creation of the Blender object. */
820 if (ob == NULL) continue;
822 BKE_libblock_free_us(data->bmain, ob);
826 /* Add object to scene. */
829 SceneLayer *sl = data->scene_layer;
831 BKE_scene_layer_base_deselect_all(sl);
833 lc = BKE_layer_collection_active(sl);
835 BLI_assert(BLI_listbase_count_ex(&sl->layer_collections, 1) == 0);
836 /* when there is no collection linked to this SceneLayer, create one */
837 SceneCollection *sc = BKE_collection_add(data->scene, NULL, NULL);
838 lc = BKE_collection_link(sl, sc);
841 for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
842 Object *ob = (*iter)->object();
843 ob->lay = data->scene->lay;
845 BKE_collection_object_add(data->scene, lc->scene_collection, ob);
847 base = BKE_scene_layer_base_find(sl, ob);
848 BKE_scene_layer_base_select(sl, base);
850 DEG_id_tag_update_ex(data->bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
853 DEG_relations_tag_update(data->bmain);
856 for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
857 AbcObjectReader *reader = *iter;
860 if (reader->refcount() == 0) {
865 switch (data->error_code) {
868 data->import_ok = !data->was_cancelled;
870 case ABC_ARCHIVE_FAIL:
871 WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
873 case ABC_UNSUPPORTED_HDF5:
874 WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
878 WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
881 static void import_freejob(void *user_data)
883 ImportJobData *data = static_cast<ImportJobData *>(user_data);
887 bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence,
888 bool set_frame_range, int sequence_len, int offset,
889 bool validate_meshes, bool as_background_job)
891 /* Using new here since MEM_* funcs do not call ctor to properly initialize
893 ImportJobData *job = new ImportJobData();
894 job->bmain = CTX_data_main(C);
895 job->scene = CTX_data_scene(C);
896 job->scene_layer = CTX_data_scene_layer(C);
897 job->import_ok = false;
898 BLI_strncpy(job->filename, filepath, 1024);
900 job->settings.scale = scale;
901 job->settings.is_sequence = is_sequence;
902 job->settings.set_frame_range = set_frame_range;
903 job->settings.sequence_len = sequence_len;
904 job->settings.offset = offset;
905 job->settings.validate_meshes = validate_meshes;
906 job->error_code = ABC_NO_ERROR;
907 job->was_cancelled = false;
911 bool import_ok = false;
912 if (as_background_job) {
913 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
918 WM_JOB_TYPE_ALEMBIC);
921 WM_jobs_customdata_set(wm_job, job, import_freejob);
922 WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
923 WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
925 WM_jobs_start(CTX_wm_manager(C), wm_job);
928 /* Fake a job context, so that we don't need NULL pointer checks while importing. */
929 short stop = 0, do_update = 0;
930 float progress = 0.f;
932 import_startjob(job, &stop, &do_update, &progress);
934 import_ok = job->import_ok;
942 /* ************************************************************************** */
944 void ABC_get_transform(CacheReader *reader, float r_mat[4][4], float time, float scale)
950 AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
952 bool is_constant = false;
953 abc_reader->read_matrix(r_mat, time, scale, is_constant);
956 /* ************************************************************************** */
958 DerivedMesh *ABC_read_mesh(CacheReader *reader,
962 const char **err_str,
965 AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
966 IObject iobject = abc_reader->iobject();
968 if (!iobject.valid()) {
969 *err_str = "Invalid object: verify object path";
973 const ObjectHeader &header = iobject.getHeader();
974 if (!abc_reader->accepts_object_type(header, ob, err_str)) {
975 /* err_str is set by acceptsObjectType() */
979 ISampleSelector sample_sel(time);
980 return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str);
983 /* ************************************************************************** */
985 void CacheReader_free(CacheReader *reader)
987 AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
988 abc_reader->decref();
990 if (abc_reader->refcount() == 0) {
995 void CacheReader_incref(CacheReader *reader)
997 AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
998 abc_reader->incref();
1001 CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, CacheReader *reader, Object *object, const char *object_path)
1003 if (object_path[0] == '\0') {
1007 ArchiveReader *archive = archive_from_handle(handle);
1009 if (!archive || !archive->valid()) {
1014 find_iobject(archive->getTop(), iobject, object_path);
1017 CacheReader_free(reader);
1020 ImportSettings settings;
1021 AbcObjectReader *abc_reader = create_reader(iobject, settings);
1022 abc_reader->object(object);
1023 abc_reader->incref();
1025 return reinterpret_cast<CacheReader *>(abc_reader);