Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/alembic/intern/alembic_capi.cc
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/alembic/intern/alembic_capi.cc')
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc1475
1 files changed, 738 insertions, 737 deletions
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 541db514bb0..0bc4eb2385b 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -74,15 +74,18 @@ extern "C" {
using Alembic::Abc::Int32ArraySamplePtr;
using Alembic::Abc::ObjectHeader;
+using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::MetaData;
using Alembic::AbcGeom::P3fArraySamplePtr;
-using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::ICamera;
+using Alembic::AbcGeom::ICompoundProperty;
using Alembic::AbcGeom::ICurves;
using Alembic::AbcGeom::ICurvesSchema;
using Alembic::AbcGeom::IFaceSet;
using Alembic::AbcGeom::ILight;
+using Alembic::AbcGeom::IN3fArrayProperty;
+using Alembic::AbcGeom::IN3fGeomParam;
using Alembic::AbcGeom::INuPatch;
using Alembic::AbcGeom::IObject;
using Alembic::AbcGeom::IPoints;
@@ -95,26 +98,23 @@ using Alembic::AbcGeom::IV2fGeomParam;
using Alembic::AbcGeom::IXform;
using Alembic::AbcGeom::IXformSchema;
using Alembic::AbcGeom::N3fArraySamplePtr;
-using Alembic::AbcGeom::XformSample;
-using Alembic::AbcGeom::ICompoundProperty;
-using Alembic::AbcGeom::IN3fArrayProperty;
-using Alembic::AbcGeom::IN3fGeomParam;
using Alembic::AbcGeom::V3fArraySamplePtr;
+using Alembic::AbcGeom::XformSample;
using Alembic::AbcMaterial::IMaterial;
struct AbcArchiveHandle {
- int unused;
+ int unused;
};
ABC_INLINE ArchiveReader *archive_from_handle(AbcArchiveHandle *handle)
{
- return reinterpret_cast<ArchiveReader *>(handle);
+ return reinterpret_cast<ArchiveReader *>(handle);
}
ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
{
- return reinterpret_cast<AbcArchiveHandle *>(archive);
+ return reinterpret_cast<AbcArchiveHandle *>(archive);
}
//#define USE_NURBS
@@ -123,297 +123,289 @@ ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
* sync. */
static bool gather_objects_paths(const IObject &object, ListBase *object_paths)
{
- if (!object.valid()) {
- return false;
- }
-
-
- size_t children_claiming_this_object = 0;
- size_t num_children = object.getNumChildren();
-
- for (size_t i = 0; i < num_children; ++i) {
- bool child_claims_this_object = gather_objects_paths(object.getChild(i), object_paths);
- children_claiming_this_object += child_claims_this_object ? 1 : 0;
- }
-
- const MetaData &md = object.getMetaData();
- bool get_path = false;
- bool parent_is_part_of_this_object = false;
-
- if (!object.getParent()) {
- /* The root itself is not an object we should import. */
- }
- else if (IXform::matches(md)) {
- if (has_property(object.getProperties(), "locator")) {
- get_path = true;
- }
- else {
- get_path = children_claiming_this_object == 0;
- }
-
- /* Transforms are never "data" for their parent. */
- parent_is_part_of_this_object = false;
- }
- else {
- /* These types are "data" for their parent. */
- get_path =
- IPolyMesh::matches(md) ||
- ISubD::matches(md) ||
+ if (!object.valid()) {
+ return false;
+ }
+
+ size_t children_claiming_this_object = 0;
+ size_t num_children = object.getNumChildren();
+
+ for (size_t i = 0; i < num_children; ++i) {
+ bool child_claims_this_object = gather_objects_paths(object.getChild(i), object_paths);
+ children_claiming_this_object += child_claims_this_object ? 1 : 0;
+ }
+
+ const MetaData &md = object.getMetaData();
+ bool get_path = false;
+ bool parent_is_part_of_this_object = false;
+
+ if (!object.getParent()) {
+ /* The root itself is not an object we should import. */
+ }
+ else if (IXform::matches(md)) {
+ if (has_property(object.getProperties(), "locator")) {
+ get_path = true;
+ }
+ else {
+ get_path = children_claiming_this_object == 0;
+ }
+
+ /* Transforms are never "data" for their parent. */
+ parent_is_part_of_this_object = false;
+ }
+ else {
+ /* These types are "data" for their parent. */
+ get_path = IPolyMesh::matches(md) || ISubD::matches(md) ||
#ifdef USE_NURBS
- INuPatch::matches(md) ||
+ INuPatch::matches(md) ||
#endif
- ICamera::matches(md) ||
- IPoints::matches(md) ||
- ICurves::matches(md);
- parent_is_part_of_this_object = get_path;
- }
+ ICamera::matches(md) || IPoints::matches(md) || ICurves::matches(md);
+ parent_is_part_of_this_object = get_path;
+ }
- if (get_path) {
- void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
- AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
+ if (get_path) {
+ void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
+ AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
- BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
- BLI_addtail(object_paths, abc_path);
- }
+ BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
+ BLI_addtail(object_paths, abc_path);
+ }
- return parent_is_part_of_this_object;
+ return parent_is_part_of_this_object;
}
AbcArchiveHandle *ABC_create_handle(const char *filename, ListBase *object_paths)
{
- ArchiveReader *archive = new ArchiveReader(filename);
+ ArchiveReader *archive = new ArchiveReader(filename);
- if (!archive->valid()) {
- delete archive;
- return NULL;
- }
+ if (!archive->valid()) {
+ delete archive;
+ return NULL;
+ }
- if (object_paths) {
- gather_objects_paths(archive->getTop(), object_paths);
- }
+ if (object_paths) {
+ gather_objects_paths(archive->getTop(), object_paths);
+ }
- return handle_from_archive(archive);
+ return handle_from_archive(archive);
}
void ABC_free_handle(AbcArchiveHandle *handle)
{
- delete archive_from_handle(handle);
+ delete archive_from_handle(handle);
}
int ABC_get_version()
{
- return ALEMBIC_LIBRARY_VERSION;
+ return ALEMBIC_LIBRARY_VERSION;
}
-static void find_iobject(const IObject &object, IObject &ret,
- const std::string &path)
+static void find_iobject(const IObject &object, IObject &ret, const std::string &path)
{
- if (!object.valid()) {
- return;
- }
+ if (!object.valid()) {
+ return;
+ }
- std::vector<std::string> tokens;
- split(path, '/', tokens);
+ std::vector<std::string> tokens;
+ split(path, '/', tokens);
- IObject tmp = object;
+ IObject tmp = object;
- std::vector<std::string>::iterator iter;
- for (iter = tokens.begin(); iter != tokens.end(); ++iter) {
- IObject child = tmp.getChild(*iter);
- tmp = child;
- }
+ std::vector<std::string>::iterator iter;
+ for (iter = tokens.begin(); iter != tokens.end(); ++iter) {
+ IObject child = tmp.getChild(*iter);
+ tmp = child;
+ }
- ret = tmp;
+ ret = tmp;
}
struct ExportJobData {
- ViewLayer *view_layer;
- Main *bmain;
+ ViewLayer *view_layer;
+ Main *bmain;
- char filename[1024];
- ExportSettings settings;
+ char filename[1024];
+ ExportSettings settings;
- short *stop;
- short *do_update;
- float *progress;
+ short *stop;
+ short *do_update;
+ float *progress;
- bool was_canceled;
- bool export_ok;
+ bool was_canceled;
+ bool export_ok;
};
static void export_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
- ExportJobData *data = static_cast<ExportJobData *>(customdata);
+ ExportJobData *data = static_cast<ExportJobData *>(customdata);
- data->stop = stop;
- data->do_update = do_update;
- data->progress = progress;
+ data->stop = stop;
+ data->do_update = do_update;
+ data->progress = progress;
- /* XXX annoying hack: needed to prevent data corruption when changing
- * scene frame in separate threads
- */
- G.is_rendering = true;
- BKE_spacedata_draw_locks(true);
+ /* XXX annoying hack: needed to prevent data corruption when changing
+ * scene frame in separate threads
+ */
+ G.is_rendering = true;
+ BKE_spacedata_draw_locks(true);
- G.is_break = false;
+ G.is_break = false;
- DEG_graph_build_from_view_layer(data->settings.depsgraph,
- data->bmain,
- data->settings.scene,
- data->view_layer);
- BKE_scene_graph_update_tagged(data->settings.depsgraph, data->bmain);
+ DEG_graph_build_from_view_layer(
+ data->settings.depsgraph, data->bmain, data->settings.scene, data->view_layer);
+ BKE_scene_graph_update_tagged(data->settings.depsgraph, data->bmain);
- try {
- AbcExporter exporter(data->bmain, data->filename, data->settings);
+ try {
+ AbcExporter exporter(data->bmain, data->filename, data->settings);
- Scene *scene = data->settings.scene; /* for the CFRA macro */
- const int orig_frame = CFRA;
+ Scene *scene = data->settings.scene; /* for the CFRA macro */
+ const int orig_frame = CFRA;
- data->was_canceled = false;
- exporter(*data->progress, data->was_canceled);
+ data->was_canceled = false;
+ exporter(*data->progress, data->was_canceled);
- if (CFRA != orig_frame) {
- CFRA = orig_frame;
+ if (CFRA != orig_frame) {
+ CFRA = orig_frame;
- BKE_scene_graph_update_for_newframe(data->settings.depsgraph, data->bmain);
- }
+ BKE_scene_graph_update_for_newframe(data->settings.depsgraph, data->bmain);
+ }
- data->export_ok = !data->was_canceled;
- }
- catch (const std::exception &e) {
- ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
- }
- catch (...) {
- ABC_LOG(data->settings.logger) << "Abc Export: unknown error...\n";
- }
+ data->export_ok = !data->was_canceled;
+ }
+ catch (const std::exception &e) {
+ ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
+ }
+ catch (...) {
+ ABC_LOG(data->settings.logger) << "Abc Export: unknown error...\n";
+ }
}
static void export_endjob(void *customdata)
{
- ExportJobData *data = static_cast<ExportJobData *>(customdata);
+ ExportJobData *data = static_cast<ExportJobData *>(customdata);
- DEG_graph_free(data->settings.depsgraph);
+ DEG_graph_free(data->settings.depsgraph);
- if (data->was_canceled && BLI_exists(data->filename)) {
- BLI_delete(data->filename, false, false);
- }
+ if (data->was_canceled && BLI_exists(data->filename)) {
+ BLI_delete(data->filename, false, false);
+ }
- if (!data->settings.logger.empty()) {
- std::cerr << data->settings.logger;
- WM_report(RPT_ERROR, "Errors occurred during the export, look in the console to know more...");
- }
+ if (!data->settings.logger.empty()) {
+ std::cerr << data->settings.logger;
+ WM_report(RPT_ERROR, "Errors occurred during the export, look in the console to know more...");
+ }
- G.is_rendering = false;
- BKE_spacedata_draw_locks(false);
+ G.is_rendering = false;
+ BKE_spacedata_draw_locks(false);
}
-bool ABC_export(
- Scene *scene,
- bContext *C,
- const char *filepath,
- const struct AlembicExportParams *params,
- bool as_background_job)
+bool ABC_export(Scene *scene,
+ bContext *C,
+ const char *filepath,
+ const struct AlembicExportParams *params,
+ bool as_background_job)
{
- ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
-
- job->view_layer = CTX_data_view_layer(C);
- job->bmain = CTX_data_main(C);
- job->export_ok = false;
- BLI_strncpy(job->filename, filepath, 1024);
-
- /* Alright, alright, alright....
- *
- * ExportJobData contains an ExportSettings containing a SimpleLogger.
- *
- * Since ExportJobData is a C-style struct dynamically allocated with
- * MEM_mallocN (see above), its constructor is never called, therefore the
- * ExportSettings constructor is not called which implies that the
- * SimpleLogger one is not called either. SimpleLogger in turn does not call
- * the constructor of its data members which ultimately means that its
- * std::ostringstream member has a NULL pointer. To be able to properly use
- * the stream's operator<<, the pointer needs to be set, therefore we have
- * to properly construct everything. And this is done using the placement
- * new operator as here below. It seems hackish, but I'm too lazy to
- * do bigger refactor and maybe there is a better way which does not involve
- * hardcore refactoring. */
- new (&job->settings) ExportSettings();
- job->settings.scene = scene;
- job->settings.depsgraph = DEG_graph_new(scene, job->view_layer, DAG_EVAL_RENDER);
-
- /* TODO(Sybren): for now we only export the active scene layer.
- * Later in the 2.8 development process this may be replaced by using
- * a specific collection for Alembic I/O, which can then be toggled
- * between "real" objects and cached Alembic files. */
- job->settings.view_layer = job->view_layer;
-
- job->settings.frame_start = params->frame_start;
- job->settings.frame_end = params->frame_end;
- job->settings.frame_samples_xform = params->frame_samples_xform;
- job->settings.frame_samples_shape = params->frame_samples_shape;
- job->settings.shutter_open = params->shutter_open;
- job->settings.shutter_close = params->shutter_close;
-
- /* TODO(Sybren): For now this is ignored, until we can get selection
- * detection working through Base pointers (instead of ob->flags). */
- job->settings.selected_only = params->selected_only;
-
- job->settings.export_face_sets = params->face_sets;
- job->settings.export_normals = params->normals;
- job->settings.export_uvs = params->uvs;
- job->settings.export_vcols = params->vcolors;
- job->settings.export_hair = params->export_hair;
- job->settings.export_particles = params->export_particles;
- job->settings.apply_subdiv = params->apply_subdiv;
- job->settings.curves_as_mesh = params->curves_as_mesh;
- job->settings.flatten_hierarchy = params->flatten_hierarchy;
-
- /* TODO(Sybren): visible_layer & renderable only is ignored for now,
- * to be replaced with collections later in the 2.8 dev process
- * (also see note above). */
- job->settings.visible_layers_only = params->visible_layers_only;
- job->settings.renderable_only = params->renderable_only;
-
- job->settings.use_subdiv_schema = params->use_subdiv_schema;
- job->settings.export_ogawa = (params->compression_type == ABC_ARCHIVE_OGAWA);
- job->settings.pack_uv = params->packuv;
- job->settings.global_scale = params->global_scale;
- job->settings.triangulate = params->triangulate;
- job->settings.quad_method = params->quad_method;
- job->settings.ngon_method = params->ngon_method;
-
- if (job->settings.frame_start > job->settings.frame_end) {
- std::swap(job->settings.frame_start, job->settings.frame_end);
- }
-
- bool export_ok = false;
- if (as_background_job) {
- wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
- CTX_wm_window(C),
- job->settings.scene,
- "Alembic Export",
- WM_JOB_PROGRESS,
- WM_JOB_TYPE_ALEMBIC);
-
- /* setup job */
- WM_jobs_customdata_set(wm_job, job, MEM_freeN);
- WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
- WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
-
- WM_jobs_start(CTX_wm_manager(C), wm_job);
- }
- else {
- /* Fake a job context, so that we don't need NULL pointer checks while exporting. */
- short stop = 0, do_update = 0;
- float progress = 0.f;
-
- export_startjob(job, &stop, &do_update, &progress);
- export_endjob(job);
- export_ok = job->export_ok;
-
- MEM_freeN(job);
- }
-
- return export_ok;
+ ExportJobData *job = static_cast<ExportJobData *>(
+ MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
+
+ job->view_layer = CTX_data_view_layer(C);
+ job->bmain = CTX_data_main(C);
+ job->export_ok = false;
+ BLI_strncpy(job->filename, filepath, 1024);
+
+ /* Alright, alright, alright....
+ *
+ * ExportJobData contains an ExportSettings containing a SimpleLogger.
+ *
+ * Since ExportJobData is a C-style struct dynamically allocated with
+ * MEM_mallocN (see above), its constructor is never called, therefore the
+ * ExportSettings constructor is not called which implies that the
+ * SimpleLogger one is not called either. SimpleLogger in turn does not call
+ * the constructor of its data members which ultimately means that its
+ * std::ostringstream member has a NULL pointer. To be able to properly use
+ * the stream's operator<<, the pointer needs to be set, therefore we have
+ * to properly construct everything. And this is done using the placement
+ * new operator as here below. It seems hackish, but I'm too lazy to
+ * do bigger refactor and maybe there is a better way which does not involve
+ * hardcore refactoring. */
+ new (&job->settings) ExportSettings();
+ job->settings.scene = scene;
+ job->settings.depsgraph = DEG_graph_new(scene, job->view_layer, DAG_EVAL_RENDER);
+
+ /* TODO(Sybren): for now we only export the active scene layer.
+ * Later in the 2.8 development process this may be replaced by using
+ * a specific collection for Alembic I/O, which can then be toggled
+ * between "real" objects and cached Alembic files. */
+ job->settings.view_layer = job->view_layer;
+
+ job->settings.frame_start = params->frame_start;
+ job->settings.frame_end = params->frame_end;
+ job->settings.frame_samples_xform = params->frame_samples_xform;
+ job->settings.frame_samples_shape = params->frame_samples_shape;
+ job->settings.shutter_open = params->shutter_open;
+ job->settings.shutter_close = params->shutter_close;
+
+ /* TODO(Sybren): For now this is ignored, until we can get selection
+ * detection working through Base pointers (instead of ob->flags). */
+ job->settings.selected_only = params->selected_only;
+
+ job->settings.export_face_sets = params->face_sets;
+ job->settings.export_normals = params->normals;
+ job->settings.export_uvs = params->uvs;
+ job->settings.export_vcols = params->vcolors;
+ job->settings.export_hair = params->export_hair;
+ job->settings.export_particles = params->export_particles;
+ job->settings.apply_subdiv = params->apply_subdiv;
+ job->settings.curves_as_mesh = params->curves_as_mesh;
+ job->settings.flatten_hierarchy = params->flatten_hierarchy;
+
+ /* TODO(Sybren): visible_layer & renderable only is ignored for now,
+ * to be replaced with collections later in the 2.8 dev process
+ * (also see note above). */
+ job->settings.visible_layers_only = params->visible_layers_only;
+ job->settings.renderable_only = params->renderable_only;
+
+ job->settings.use_subdiv_schema = params->use_subdiv_schema;
+ job->settings.export_ogawa = (params->compression_type == ABC_ARCHIVE_OGAWA);
+ job->settings.pack_uv = params->packuv;
+ job->settings.global_scale = params->global_scale;
+ job->settings.triangulate = params->triangulate;
+ job->settings.quad_method = params->quad_method;
+ job->settings.ngon_method = params->ngon_method;
+
+ if (job->settings.frame_start > job->settings.frame_end) {
+ std::swap(job->settings.frame_start, job->settings.frame_end);
+ }
+
+ bool export_ok = false;
+ if (as_background_job) {
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ job->settings.scene,
+ "Alembic Export",
+ WM_JOB_PROGRESS,
+ WM_JOB_TYPE_ALEMBIC);
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, job, MEM_freeN);
+ WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
+ WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
+ else {
+ /* Fake a job context, so that we don't need NULL pointer checks while exporting. */
+ short stop = 0, do_update = 0;
+ float progress = 0.f;
+
+ export_startjob(job, &stop, &do_update, &progress);
+ export_endjob(job);
+ export_ok = job->export_ok;
+
+ MEM_freeN(job);
+ }
+
+ return export_ok;
}
/* ********************** Import file ********************** */
@@ -439,499 +431,505 @@ bool ABC_export(
* NOTE: this function is similar to gather_object_paths above, need to keep
* them in sync. */
static std::pair<bool, AbcObjectReader *> visit_object(
- const IObject &object,
- AbcObjectReader::ptr_vector &readers,
- ImportSettings &settings,
- AbcObjectReader::ptr_vector &r_assign_as_parent)
+ const IObject &object,
+ AbcObjectReader::ptr_vector &readers,
+ ImportSettings &settings,
+ AbcObjectReader::ptr_vector &r_assign_as_parent)
{
- const std::string & full_name = object.getFullName();
-
- if (!object.valid()) {
- std::cerr << " - "
- << full_name
- << ": object is invalid, skipping it and all its children.\n";
- return std::make_pair(false, static_cast<AbcObjectReader *>(NULL));
- }
-
- /* The interpretation of data by the children determine the role of this
- * object. This is especially important for Xform objects, as they can be
- * either part of a Blender object or a Blender object (Empty) themselves.
- */
- size_t children_claiming_this_object = 0;
- size_t num_children = object.getNumChildren();
- AbcObjectReader::ptr_vector claiming_child_readers;
- AbcObjectReader::ptr_vector nonclaiming_child_readers;
- AbcObjectReader::ptr_vector assign_as_parent;
- for (size_t i = 0; i < num_children; ++i) {
- const IObject ichild = object.getChild(i);
-
- /* TODO: When we only support C++11, use std::tie() instead. */
- std::pair<bool, AbcObjectReader *> child_result;
- child_result = visit_object(ichild, readers, settings, assign_as_parent);
-
- bool child_claims_this_object = child_result.first;
- AbcObjectReader *child_reader = child_result.second;
-
- if (child_reader == NULL) {
- BLI_assert(!child_claims_this_object);
- }
- else {
- if (child_claims_this_object) {
- claiming_child_readers.push_back(child_reader);
- }
- else {
- nonclaiming_child_readers.push_back(child_reader);
- }
- }
-
- children_claiming_this_object += child_claims_this_object ? 1 : 0;
- }
- BLI_assert(children_claiming_this_object == claiming_child_readers.size());
-
- AbcObjectReader *reader = NULL;
- const MetaData &md = object.getMetaData();
- bool parent_is_part_of_this_object = false;
-
- if (!object.getParent()) {
- /* The root itself is not an object we should import. */
- }
- else if (IXform::matches(md)) {
- bool create_empty;
-
- /* An xform can either be a Blender Object (if it contains a mesh, for
- * example), but it can also be an Empty. Its correct translation to
- * Blender's data model depends on its children. */
-
- /* Check whether or not this object is a Maya locator, which is
- * similar to empties used as parent object in Blender. */
- if (has_property(object.getProperties(), "locator")) {
- create_empty = true;
- }
- else {
- create_empty = claiming_child_readers.empty();
- }
-
- if (create_empty) {
- reader = new AbcEmptyReader(object, settings);
- }
- }
- else if (IPolyMesh::matches(md)) {
- reader = new AbcMeshReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else if (ISubD::matches(md)) {
- reader = new AbcSubDReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else if (INuPatch::matches(md)) {
+ const std::string &full_name = object.getFullName();
+
+ if (!object.valid()) {
+ std::cerr << " - " << full_name << ": object is invalid, skipping it and all its children.\n";
+ return std::make_pair(false, static_cast<AbcObjectReader *>(NULL));
+ }
+
+ /* The interpretation of data by the children determine the role of this
+ * object. This is especially important for Xform objects, as they can be
+ * either part of a Blender object or a Blender object (Empty) themselves.
+ */
+ size_t children_claiming_this_object = 0;
+ size_t num_children = object.getNumChildren();
+ AbcObjectReader::ptr_vector claiming_child_readers;
+ AbcObjectReader::ptr_vector nonclaiming_child_readers;
+ AbcObjectReader::ptr_vector assign_as_parent;
+ for (size_t i = 0; i < num_children; ++i) {
+ const IObject ichild = object.getChild(i);
+
+ /* TODO: When we only support C++11, use std::tie() instead. */
+ std::pair<bool, AbcObjectReader *> child_result;
+ child_result = visit_object(ichild, readers, settings, assign_as_parent);
+
+ bool child_claims_this_object = child_result.first;
+ AbcObjectReader *child_reader = child_result.second;
+
+ if (child_reader == NULL) {
+ BLI_assert(!child_claims_this_object);
+ }
+ else {
+ if (child_claims_this_object) {
+ claiming_child_readers.push_back(child_reader);
+ }
+ else {
+ nonclaiming_child_readers.push_back(child_reader);
+ }
+ }
+
+ children_claiming_this_object += child_claims_this_object ? 1 : 0;
+ }
+ BLI_assert(children_claiming_this_object == claiming_child_readers.size());
+
+ AbcObjectReader *reader = NULL;
+ const MetaData &md = object.getMetaData();
+ bool parent_is_part_of_this_object = false;
+
+ if (!object.getParent()) {
+ /* The root itself is not an object we should import. */
+ }
+ else if (IXform::matches(md)) {
+ bool create_empty;
+
+ /* An xform can either be a Blender Object (if it contains a mesh, for
+ * example), but it can also be an Empty. Its correct translation to
+ * Blender's data model depends on its children. */
+
+ /* Check whether or not this object is a Maya locator, which is
+ * similar to empties used as parent object in Blender. */
+ if (has_property(object.getProperties(), "locator")) {
+ create_empty = true;
+ }
+ else {
+ create_empty = claiming_child_readers.empty();
+ }
+
+ if (create_empty) {
+ reader = new AbcEmptyReader(object, settings);
+ }
+ }
+ else if (IPolyMesh::matches(md)) {
+ reader = new AbcMeshReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else if (ISubD::matches(md)) {
+ reader = new AbcSubDReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else if (INuPatch::matches(md)) {
#ifdef USE_NURBS
- /* TODO(kevin): importing cyclic NURBS from other software crashes
- * at the moment. This is due to the fact that NURBS in other
- * software have duplicated points which causes buffer overflows in
- * Blender. Need to figure out exactly how these points are
- * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
- * Until this is fixed, disabling NURBS reading. */
- reader = new AbcNurbsReader(object, settings);
- parent_is_part_of_this_object = true;
+ /* TODO(kevin): importing cyclic NURBS from other software crashes
+ * at the moment. This is due to the fact that NURBS in other
+ * software have duplicated points which causes buffer overflows in
+ * Blender. Need to figure out exactly how these points are
+ * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
+ * Until this is fixed, disabling NURBS reading. */
+ reader = new AbcNurbsReader(object, settings);
+ parent_is_part_of_this_object = true;
#endif
- }
- else if (ICamera::matches(md)) {
- reader = new AbcCameraReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else if (IPoints::matches(md)) {
- reader = new AbcPointsReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else if (IMaterial::matches(md)) {
- /* Pass for now. */
- }
- else if (ILight::matches(md)) {
- /* Pass for now. */
- }
- else if (IFaceSet::matches(md)) {
- /* Pass, those are handled in the mesh reader. */
- }
- else if (ICurves::matches(md)) {
- reader = new AbcCurveReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else {
- std::cerr << "Alembic object " << full_name
- << " is of unsupported schema type '"
- << object.getMetaData().get("schemaObjTitle") << "'"
- << std::endl;
- }
-
- if (reader) {
- /* We have created a reader, which should imply that this object is
- * not claimed as part of any child Alembic object. */
- BLI_assert(claiming_child_readers.empty());
-
- readers.push_back(reader);
- reader->incref();
-
- AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
- MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
- BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
- BLI_addtail(&settings.cache_file->object_paths, abc_path);
-
- /* We can now assign this reader as parent for our children. */
- if (nonclaiming_child_readers.size() + assign_as_parent.size() > 0) {
- /* TODO: When we only support C++11, use for (a: b) instead. */
- BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
- child_reader->parent_reader = reader;
- }
- BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
- child_reader->parent_reader = reader;
- }
- }
- }
- else if (object.getParent()) {
- if (claiming_child_readers.size() > 0) {
- /* The first claiming child will serve just fine as parent to
- * our non-claiming children. Since all claiming children share
- * the same XForm, it doesn't really matter which one we pick. */
- AbcObjectReader *claiming_child = claiming_child_readers[0];
- BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
- child_reader->parent_reader = claiming_child;
- }
- BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
- child_reader->parent_reader = claiming_child;
- }
- /* Claiming children should have our parent set as their parent. */
- BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
- r_assign_as_parent.push_back(child_reader);
- }
- }
- else {
- /* This object isn't claimed by any child, and didn't produce
- * a reader. Odd situation, could be the top Alembic object, or
- * an unsupported Alembic schema. Delegate to our parent. */
- BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
- r_assign_as_parent.push_back(child_reader);
- }
- BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
- r_assign_as_parent.push_back(child_reader);
- }
- BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
- r_assign_as_parent.push_back(child_reader);
- }
- }
- }
-
- return std::make_pair(parent_is_part_of_this_object, reader);
+ }
+ else if (ICamera::matches(md)) {
+ reader = new AbcCameraReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else if (IPoints::matches(md)) {
+ reader = new AbcPointsReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else if (IMaterial::matches(md)) {
+ /* Pass for now. */
+ }
+ else if (ILight::matches(md)) {
+ /* Pass for now. */
+ }
+ else if (IFaceSet::matches(md)) {
+ /* Pass, those are handled in the mesh reader. */
+ }
+ else if (ICurves::matches(md)) {
+ reader = new AbcCurveReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else {
+ std::cerr << "Alembic object " << full_name << " is of unsupported schema type '"
+ << object.getMetaData().get("schemaObjTitle") << "'" << std::endl;
+ }
+
+ if (reader) {
+ /* We have created a reader, which should imply that this object is
+ * not claimed as part of any child Alembic object. */
+ BLI_assert(claiming_child_readers.empty());
+
+ readers.push_back(reader);
+ reader->incref();
+
+ AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
+ MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
+ BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
+ BLI_addtail(&settings.cache_file->object_paths, abc_path);
+
+ /* We can now assign this reader as parent for our children. */
+ if (nonclaiming_child_readers.size() + assign_as_parent.size() > 0) {
+ /* TODO: When we only support C++11, use for (a: b) instead. */
+ BOOST_FOREACH (AbcObjectReader *child_reader, nonclaiming_child_readers) {
+ child_reader->parent_reader = reader;
+ }
+ BOOST_FOREACH (AbcObjectReader *child_reader, assign_as_parent) {
+ child_reader->parent_reader = reader;
+ }
+ }
+ }
+ else if (object.getParent()) {
+ if (claiming_child_readers.size() > 0) {
+ /* The first claiming child will serve just fine as parent to
+ * our non-claiming children. Since all claiming children share
+ * the same XForm, it doesn't really matter which one we pick. */
+ AbcObjectReader *claiming_child = claiming_child_readers[0];
+ BOOST_FOREACH (AbcObjectReader *child_reader, nonclaiming_child_readers) {
+ child_reader->parent_reader = claiming_child;
+ }
+ BOOST_FOREACH (AbcObjectReader *child_reader, assign_as_parent) {
+ child_reader->parent_reader = claiming_child;
+ }
+ /* Claiming children should have our parent set as their parent. */
+ BOOST_FOREACH (AbcObjectReader *child_reader, claiming_child_readers) {
+ r_assign_as_parent.push_back(child_reader);
+ }
+ }
+ else {
+ /* This object isn't claimed by any child, and didn't produce
+ * a reader. Odd situation, could be the top Alembic object, or
+ * an unsupported Alembic schema. Delegate to our parent. */
+ BOOST_FOREACH (AbcObjectReader *child_reader, claiming_child_readers) {
+ r_assign_as_parent.push_back(child_reader);
+ }
+ BOOST_FOREACH (AbcObjectReader *child_reader, nonclaiming_child_readers) {
+ r_assign_as_parent.push_back(child_reader);
+ }
+ BOOST_FOREACH (AbcObjectReader *child_reader, assign_as_parent) {
+ r_assign_as_parent.push_back(child_reader);
+ }
+ }
+ }
+
+ return std::make_pair(parent_is_part_of_this_object, reader);
}
enum {
- ABC_NO_ERROR = 0,
- ABC_ARCHIVE_FAIL,
- ABC_UNSUPPORTED_HDF5,
+ ABC_NO_ERROR = 0,
+ ABC_ARCHIVE_FAIL,
+ ABC_UNSUPPORTED_HDF5,
};
struct ImportJobData {
- Main *bmain;
- Scene *scene;
- ViewLayer *view_layer;
- wmWindowManager *wm;
+ Main *bmain;
+ Scene *scene;
+ ViewLayer *view_layer;
+ wmWindowManager *wm;
- char filename[1024];
- ImportSettings settings;
+ char filename[1024];
+ ImportSettings settings;
- std::vector<AbcObjectReader *> readers;
+ std::vector<AbcObjectReader *> readers;
- short *stop;
- short *do_update;
- float *progress;
+ short *stop;
+ short *do_update;
+ float *progress;
- char error_code;
- bool was_cancelled;
- bool import_ok;
+ char error_code;
+ bool was_cancelled;
+ bool import_ok;
};
static void import_startjob(void *user_data, short *stop, short *do_update, float *progress)
{
- SCOPE_TIMER("Alembic import, objects reading and creation");
+ SCOPE_TIMER("Alembic import, objects reading and creation");
- ImportJobData *data = static_cast<ImportJobData *>(user_data);
+ ImportJobData *data = static_cast<ImportJobData *>(user_data);
- data->stop = stop;
- data->do_update = do_update;
- data->progress = progress;
+ data->stop = stop;
+ data->do_update = do_update;
+ data->progress = progress;
- WM_set_locked_interface(data->wm, true);
+ WM_set_locked_interface(data->wm, true);
- ArchiveReader *archive = new ArchiveReader(data->filename);
+ ArchiveReader *archive = new ArchiveReader(data->filename);
- if (!archive->valid()) {
+ if (!archive->valid()) {
#ifndef WITH_ALEMBIC_HDF5
- data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
+ data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
#else
- data->error_code = ABC_ARCHIVE_FAIL;
+ data->error_code = ABC_ARCHIVE_FAIL;
#endif
- delete archive;
- return;
- }
-
- CacheFile *cache_file = static_cast<CacheFile *>(BKE_cachefile_add(data->bmain, BLI_path_basename(data->filename)));
-
- /* Decrement the ID ref-count because it is going to be incremented for each
- * modifier and constraint that it will be attached to, so since currently
- * it is not used by anyone, its use count will off by one. */
- id_us_min(&cache_file->id);
-
- cache_file->is_sequence = data->settings.is_sequence;
- cache_file->scale = data->settings.scale;
- cache_file->handle = handle_from_archive(archive);
- BLI_strncpy(cache_file->filepath, data->filename, 1024);
-
- data->settings.cache_file = cache_file;
-
- *data->do_update = true;
- *data->progress = 0.05f;
-
- /* Parse Alembic Archive. */
- AbcObjectReader::ptr_vector assign_as_parent;
- visit_object(archive->getTop(), data->readers, data->settings, assign_as_parent);
-
- /* There shouldn't be any orphans. */
- BLI_assert(assign_as_parent.size() == 0);
-
- if (G.is_break) {
- data->was_cancelled = true;
- return;
- }
-
- *data->do_update = true;
- *data->progress = 0.1f;
-
- /* Create objects and set scene frame range. */
-
- const float size = static_cast<float>(data->readers.size());
- size_t i = 0;
-
- chrono_t min_time = std::numeric_limits<chrono_t>::max();
- chrono_t max_time = std::numeric_limits<chrono_t>::min();
-
- ISampleSelector sample_sel(0.0f);
- std::vector<AbcObjectReader *>::iterator iter;
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- AbcObjectReader *reader = *iter;
-
- if (reader->valid()) {
- reader->readObjectData(data->bmain, sample_sel);
-
- min_time = std::min(min_time, reader->minTime());
- max_time = std::max(max_time, reader->maxTime());
- }
- else {
- std::cerr << "Object " << reader->name() << " in Alembic file "
- << data->filename << " is invalid.\n";
- }
-
- *data->progress = 0.1f + 0.3f * (++i / size);
- *data->do_update = true;
-
- if (G.is_break) {
- data->was_cancelled = true;
- return;
- }
- }
-
- if (data->settings.set_frame_range) {
- Scene *scene = data->scene;
-
- if (data->settings.is_sequence) {
- SFRA = data->settings.sequence_offset;
- EFRA = SFRA + (data->settings.sequence_len - 1);
- CFRA = SFRA;
- }
- else if (min_time < max_time) {
- SFRA = static_cast<int>(round(min_time * FPS));
- EFRA = static_cast<int>(round(max_time * FPS));
- CFRA = SFRA;
- }
- }
-
- /* Setup parenthood. */
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- const AbcObjectReader *reader = *iter;
- const AbcObjectReader *parent_reader = reader->parent_reader;
- Object *ob = reader->object();
-
- if (parent_reader == NULL || !reader->inherits_xform()) {
- ob->parent = NULL;
- }
- else {
- ob->parent = parent_reader->object();
- }
- }
-
- /* Setup transformations and constraints. */
- i = 0;
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- AbcObjectReader *reader = *iter;
- reader->setupObjectTransform(0.0f);
-
- *data->progress = 0.7f + 0.3f * (++i / size);
- *data->do_update = true;
-
- if (G.is_break) {
- data->was_cancelled = true;
- return;
- }
- }
+ delete archive;
+ return;
+ }
+
+ CacheFile *cache_file = static_cast<CacheFile *>(
+ BKE_cachefile_add(data->bmain, BLI_path_basename(data->filename)));
+
+ /* Decrement the ID ref-count because it is going to be incremented for each
+ * modifier and constraint that it will be attached to, so since currently
+ * it is not used by anyone, its use count will off by one. */
+ id_us_min(&cache_file->id);
+
+ cache_file->is_sequence = data->settings.is_sequence;
+ cache_file->scale = data->settings.scale;
+ cache_file->handle = handle_from_archive(archive);
+ BLI_strncpy(cache_file->filepath, data->filename, 1024);
+
+ data->settings.cache_file = cache_file;
+
+ *data->do_update = true;
+ *data->progress = 0.05f;
+
+ /* Parse Alembic Archive. */
+ AbcObjectReader::ptr_vector assign_as_parent;
+ visit_object(archive->getTop(), data->readers, data->settings, assign_as_parent);
+
+ /* There shouldn't be any orphans. */
+ BLI_assert(assign_as_parent.size() == 0);
+
+ if (G.is_break) {
+ data->was_cancelled = true;
+ return;
+ }
+
+ *data->do_update = true;
+ *data->progress = 0.1f;
+
+ /* Create objects and set scene frame range. */
+
+ const float size = static_cast<float>(data->readers.size());
+ size_t i = 0;
+
+ chrono_t min_time = std::numeric_limits<chrono_t>::max();
+ chrono_t max_time = std::numeric_limits<chrono_t>::min();
+
+ ISampleSelector sample_sel(0.0f);
+ std::vector<AbcObjectReader *>::iterator iter;
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ AbcObjectReader *reader = *iter;
+
+ if (reader->valid()) {
+ reader->readObjectData(data->bmain, sample_sel);
+
+ min_time = std::min(min_time, reader->minTime());
+ max_time = std::max(max_time, reader->maxTime());
+ }
+ else {
+ std::cerr << "Object " << reader->name() << " in Alembic file " << data->filename
+ << " is invalid.\n";
+ }
+
+ *data->progress = 0.1f + 0.3f * (++i / size);
+ *data->do_update = true;
+
+ if (G.is_break) {
+ data->was_cancelled = true;
+ return;
+ }
+ }
+
+ if (data->settings.set_frame_range) {
+ Scene *scene = data->scene;
+
+ if (data->settings.is_sequence) {
+ SFRA = data->settings.sequence_offset;
+ EFRA = SFRA + (data->settings.sequence_len - 1);
+ CFRA = SFRA;
+ }
+ else if (min_time < max_time) {
+ SFRA = static_cast<int>(round(min_time * FPS));
+ EFRA = static_cast<int>(round(max_time * FPS));
+ CFRA = SFRA;
+ }
+ }
+
+ /* Setup parenthood. */
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ const AbcObjectReader *reader = *iter;
+ const AbcObjectReader *parent_reader = reader->parent_reader;
+ Object *ob = reader->object();
+
+ if (parent_reader == NULL || !reader->inherits_xform()) {
+ ob->parent = NULL;
+ }
+ else {
+ ob->parent = parent_reader->object();
+ }
+ }
+
+ /* Setup transformations and constraints. */
+ i = 0;
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ AbcObjectReader *reader = *iter;
+ reader->setupObjectTransform(0.0f);
+
+ *data->progress = 0.7f + 0.3f * (++i / size);
+ *data->do_update = true;
+
+ if (G.is_break) {
+ data->was_cancelled = true;
+ return;
+ }
+ }
}
static void import_endjob(void *user_data)
{
- SCOPE_TIMER("Alembic import, cleanup");
-
- ImportJobData *data = static_cast<ImportJobData *>(user_data);
-
- std::vector<AbcObjectReader *>::iterator iter;
-
- /* Delete objects on cancelation. */
- if (data->was_cancelled) {
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- Object *ob = (*iter)->object();
-
- /* It's possible that cancellation occurred between the creation of
- * the reader and the creation of the Blender object. */
- if (ob == NULL) continue;
-
- BKE_id_free_us(data->bmain, ob);
- }
- }
- else {
- /* Add object to scene. */
- Base *base;
- LayerCollection *lc;
- ViewLayer *view_layer = data->view_layer;
-
- BKE_view_layer_base_deselect_all(view_layer);
-
- lc = BKE_layer_collection_get_active(view_layer);
-
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- Object *ob = (*iter)->object();
-
- BKE_collection_object_add(data->bmain, lc->collection, ob);
-
- base = BKE_view_layer_base_find(view_layer, ob);
- /* TODO: is setting active needed? */
- BKE_view_layer_base_select_and_set_active(view_layer, base);
-
- DEG_id_tag_update(&lc->collection->id, ID_RECALC_COPY_ON_WRITE);
- DEG_id_tag_update_ex(data->bmain, &ob->id,
- ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION | ID_RECALC_BASE_FLAGS);
- }
-
- DEG_id_tag_update(&data->scene->id, ID_RECALC_BASE_FLAGS);
- DEG_relations_tag_update(data->bmain);
- }
-
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- AbcObjectReader *reader = *iter;
- reader->decref();
-
- if (reader->refcount() == 0) {
- delete reader;
- }
- }
-
- WM_set_locked_interface(data->wm, false);
-
- switch (data->error_code) {
- default:
- case ABC_NO_ERROR:
- data->import_ok = !data->was_cancelled;
- break;
- case ABC_ARCHIVE_FAIL:
- WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
- break;
- case ABC_UNSUPPORTED_HDF5:
- WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
- break;
- }
-
- WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
+ SCOPE_TIMER("Alembic import, cleanup");
+
+ ImportJobData *data = static_cast<ImportJobData *>(user_data);
+
+ std::vector<AbcObjectReader *>::iterator iter;
+
+ /* Delete objects on cancelation. */
+ if (data->was_cancelled) {
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ Object *ob = (*iter)->object();
+
+ /* It's possible that cancellation occurred between the creation of
+ * the reader and the creation of the Blender object. */
+ if (ob == NULL)
+ continue;
+
+ BKE_id_free_us(data->bmain, ob);
+ }
+ }
+ else {
+ /* Add object to scene. */
+ Base *base;
+ LayerCollection *lc;
+ ViewLayer *view_layer = data->view_layer;
+
+ BKE_view_layer_base_deselect_all(view_layer);
+
+ lc = BKE_layer_collection_get_active(view_layer);
+
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ Object *ob = (*iter)->object();
+
+ BKE_collection_object_add(data->bmain, lc->collection, ob);
+
+ base = BKE_view_layer_base_find(view_layer, ob);
+ /* TODO: is setting active needed? */
+ BKE_view_layer_base_select_and_set_active(view_layer, base);
+
+ DEG_id_tag_update(&lc->collection->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update_ex(data->bmain,
+ &ob->id,
+ ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION |
+ ID_RECALC_BASE_FLAGS);
+ }
+
+ DEG_id_tag_update(&data->scene->id, ID_RECALC_BASE_FLAGS);
+ DEG_relations_tag_update(data->bmain);
+ }
+
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ AbcObjectReader *reader = *iter;
+ reader->decref();
+
+ if (reader->refcount() == 0) {
+ delete reader;
+ }
+ }
+
+ WM_set_locked_interface(data->wm, false);
+
+ switch (data->error_code) {
+ default:
+ case ABC_NO_ERROR:
+ data->import_ok = !data->was_cancelled;
+ break;
+ case ABC_ARCHIVE_FAIL:
+ WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
+ break;
+ case ABC_UNSUPPORTED_HDF5:
+ WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
+ break;
+ }
+
+ WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
}
static void import_freejob(void *user_data)
{
- ImportJobData *data = static_cast<ImportJobData *>(user_data);
- delete data;
+ ImportJobData *data = static_cast<ImportJobData *>(user_data);
+ delete data;
}
-bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence,
- bool set_frame_range, int sequence_len, int offset,
- bool validate_meshes, bool as_background_job)
+bool ABC_import(bContext *C,
+ const char *filepath,
+ float scale,
+ bool is_sequence,
+ bool set_frame_range,
+ int sequence_len,
+ int offset,
+ bool validate_meshes,
+ bool as_background_job)
{
- /* Using new here since MEM_* funcs do not call ctor to properly initialize
- * data. */
- ImportJobData *job = new ImportJobData();
- job->bmain = CTX_data_main(C);
- job->scene = CTX_data_scene(C);
- job->view_layer = CTX_data_view_layer(C);
- job->wm = CTX_wm_manager(C);
- job->import_ok = false;
- BLI_strncpy(job->filename, filepath, 1024);
-
- job->settings.scale = scale;
- job->settings.is_sequence = is_sequence;
- job->settings.set_frame_range = set_frame_range;
- job->settings.sequence_len = sequence_len;
- job->settings.sequence_offset = offset;
- job->settings.validate_meshes = validate_meshes;
- job->error_code = ABC_NO_ERROR;
- job->was_cancelled = false;
-
- G.is_break = false;
-
- bool import_ok = false;
- if (as_background_job) {
- wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
- CTX_wm_window(C),
- job->scene,
- "Alembic Import",
- WM_JOB_PROGRESS,
- WM_JOB_TYPE_ALEMBIC);
-
- /* setup job */
- WM_jobs_customdata_set(wm_job, job, import_freejob);
- WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
- WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
-
- WM_jobs_start(CTX_wm_manager(C), wm_job);
- }
- else {
- /* Fake a job context, so that we don't need NULL pointer checks while importing. */
- short stop = 0, do_update = 0;
- float progress = 0.f;
-
- import_startjob(job, &stop, &do_update, &progress);
- import_endjob(job);
- import_ok = job->import_ok;
-
- import_freejob(job);
- }
-
- return import_ok;
+ /* Using new here since MEM_* funcs do not call ctor to properly initialize
+ * data. */
+ ImportJobData *job = new ImportJobData();
+ job->bmain = CTX_data_main(C);
+ job->scene = CTX_data_scene(C);
+ job->view_layer = CTX_data_view_layer(C);
+ job->wm = CTX_wm_manager(C);
+ job->import_ok = false;
+ BLI_strncpy(job->filename, filepath, 1024);
+
+ job->settings.scale = scale;
+ job->settings.is_sequence = is_sequence;
+ job->settings.set_frame_range = set_frame_range;
+ job->settings.sequence_len = sequence_len;
+ job->settings.sequence_offset = offset;
+ job->settings.validate_meshes = validate_meshes;
+ job->error_code = ABC_NO_ERROR;
+ job->was_cancelled = false;
+
+ G.is_break = false;
+
+ bool import_ok = false;
+ if (as_background_job) {
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ job->scene,
+ "Alembic Import",
+ WM_JOB_PROGRESS,
+ WM_JOB_TYPE_ALEMBIC);
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, job, import_freejob);
+ WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
+ WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
+ else {
+ /* Fake a job context, so that we don't need NULL pointer checks while importing. */
+ short stop = 0, do_update = 0;
+ float progress = 0.f;
+
+ import_startjob(job, &stop, &do_update, &progress);
+ import_endjob(job);
+ import_ok = job->import_ok;
+
+ import_freejob(job);
+ }
+
+ return import_ok;
}
/* ************************************************************************** */
void ABC_get_transform(CacheReader *reader, float r_mat[4][4], float time, float scale)
{
- if (!reader) {
- return;
- }
+ if (!reader) {
+ return;
+ }
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- bool is_constant = false;
- abc_reader->read_matrix(r_mat, time, scale, is_constant);
+ bool is_constant = false;
+ abc_reader->read_matrix(r_mat, time, scale, is_constant);
}
/* ************************************************************************** */
@@ -943,71 +941,74 @@ Mesh *ABC_read_mesh(CacheReader *reader,
const char **err_str,
int read_flag)
{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- IObject iobject = abc_reader->iobject();
-
- if (!iobject.valid()) {
- *err_str = "Invalid object: verify object path";
- return NULL;
- }
-
- const ObjectHeader &header = iobject.getHeader();
- if (!abc_reader->accepts_object_type(header, ob, err_str)) {
- /* err_str is set by acceptsObjectType() */
- return NULL;
- }
-
- /* kFloorIndex is used to be compatible with non-interpolating
- * properties; they use the floor. */
- ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
- return abc_reader->read_mesh(existing_mesh, sample_sel, read_flag, err_str);
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ IObject iobject = abc_reader->iobject();
+
+ if (!iobject.valid()) {
+ *err_str = "Invalid object: verify object path";
+ return NULL;
+ }
+
+ const ObjectHeader &header = iobject.getHeader();
+ if (!abc_reader->accepts_object_type(header, ob, err_str)) {
+ /* err_str is set by acceptsObjectType() */
+ return NULL;
+ }
+
+ /* kFloorIndex is used to be compatible with non-interpolating
+ * properties; they use the floor. */
+ ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
+ return abc_reader->read_mesh(existing_mesh, sample_sel, read_flag, err_str);
}
/* ************************************************************************** */
void CacheReader_free(CacheReader *reader)
{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- abc_reader->decref();
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ abc_reader->decref();
- if (abc_reader->refcount() == 0) {
- delete abc_reader;
- }
+ if (abc_reader->refcount() == 0) {
+ delete abc_reader;
+ }
}
void CacheReader_incref(CacheReader *reader)
{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- abc_reader->incref();
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ abc_reader->incref();
}
-CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, CacheReader *reader, Object *object, const char *object_path)
+CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle,
+ CacheReader *reader,
+ Object *object,
+ const char *object_path)
{
- if (object_path[0] == '\0') {
- return reader;
- }
+ if (object_path[0] == '\0') {
+ return reader;
+ }
- ArchiveReader *archive = archive_from_handle(handle);
+ ArchiveReader *archive = archive_from_handle(handle);
- if (!archive || !archive->valid()) {
- return reader;
- }
+ if (!archive || !archive->valid()) {
+ return reader;
+ }
- IObject iobject;
- find_iobject(archive->getTop(), iobject, object_path);
+ IObject iobject;
+ find_iobject(archive->getTop(), iobject, object_path);
- if (reader) {
- CacheReader_free(reader);
- }
+ if (reader) {
+ CacheReader_free(reader);
+ }
- ImportSettings settings;
- AbcObjectReader *abc_reader = create_reader(iobject, settings);
- if (abc_reader == NULL) {
- /* This object is not supported */
- return NULL;
- }
- abc_reader->object(object);
- abc_reader->incref();
+ ImportSettings settings;
+ AbcObjectReader *abc_reader = create_reader(iobject, settings);
+ if (abc_reader == NULL) {
+ /* This object is not supported */
+ return NULL;
+ }
+ abc_reader->object(object);
+ abc_reader->incref();
- return reinterpret_cast<CacheReader *>(abc_reader);
+ return reinterpret_cast<CacheReader *>(abc_reader);
}