From 00f218602d52defee624e9853b03431d732649fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 7 Mar 2021 16:17:59 +0100 Subject: Alembic procedural: fix missing update when only the transforms change The missing update has two sources: The TimeSampling used for looking up transformations in the cache was uninitialized. To fix this, simply use the TimeSampling from the last transformation in the hierarchy (that is the object's parent), which should also contain the time information for all of its parents. The objects are not tagged for update when their trasformations change. --- intern/cycles/render/alembic.cpp | 47 +++++++++++++++++++++++++++++----------- intern/cycles/render/alembic.h | 8 ++++++- 2 files changed, 41 insertions(+), 14 deletions(-) (limited to 'intern') diff --git a/intern/cycles/render/alembic.cpp b/intern/cycles/render/alembic.cpp index 60e24e7b375..9c73fb05405 100644 --- a/intern/cycles/render/alembic.cpp +++ b/intern/cycles/render/alembic.cpp @@ -1017,6 +1017,10 @@ void AlembicObject::setup_transform_cache(float scale) cached_data.transforms.clear(); cached_data.transforms.invalidate_last_loaded_time(); + if (xform_time_sampling) { + cached_data.transforms.set_time_sampling(*xform_time_sampling); + } + if (xform_samples.size() == 0) { Transform tfm = transform_scale(make_float3(scale)); cached_data.transforms.add_data(tfm, 0.0); @@ -1476,7 +1480,7 @@ void AlembicProcedural::load_objects(Progress &progress) IObject root = archive.getTop(); for (size_t i = 0; i < root.getNumChildren(); ++i) { - walk_hierarchy(root, root.getChildHeader(i), nullptr, object_map, progress); + walk_hierarchy(root, root.getChildHeader(i), {}, object_map, progress); } /* Create nodes in the scene. */ @@ -1541,6 +1545,10 @@ void AlembicProcedural::read_mesh(Scene *scene, Object *object = abc_object->get_object(); cached_data.transforms.copy_to_socket(frame_time, object, object->get_tfm_socket()); + if (object->is_modified()) { + object->tag_update(scene_); + } + cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket()); cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_shader_socket()); @@ -1636,6 +1644,10 @@ void AlembicProcedural::read_subd(Scene *scene, Object *object = abc_object->get_object(); cached_data.transforms.copy_to_socket(frame_time, object, object->get_tfm_socket()); + if (object->is_modified()) { + object->tag_update(scene_); + } + cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket()); /* cached_data.shader is also used for subd_shader */ @@ -1716,6 +1728,10 @@ void AlembicProcedural::read_curves(Scene *scene, Object *object = abc_object->get_object(); cached_data.transforms.copy_to_socket(frame_time, object, object->get_tfm_socket()); + if (object->is_modified()) { + object->tag_update(scene_); + } + cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket()); cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket()); @@ -1746,7 +1762,7 @@ void AlembicProcedural::read_curves(Scene *scene, void AlembicProcedural::walk_hierarchy( IObject parent, const ObjectHeader &header, - MatrixSampleMap *xform_samples, + MatrixSamplesData matrix_samples_data, const unordered_map &object_map, Progress &progress) { @@ -1768,7 +1784,7 @@ void AlembicProcedural::walk_hierarchy( MatrixSampleMap local_xform_samples; MatrixSampleMap *temp_xform_samples = nullptr; - if (xform_samples == nullptr) { + if (matrix_samples_data.samples == nullptr) { /* If there is no parent transforms, fill the map directly. */ temp_xform_samples = &concatenated_xform_samples; } @@ -1783,11 +1799,13 @@ void AlembicProcedural::walk_hierarchy( temp_xform_samples->insert({sample_time, sample.getMatrix()}); } - if (xform_samples != nullptr) { - concatenate_xform_samples(*xform_samples, local_xform_samples, concatenated_xform_samples); + if (matrix_samples_data.samples != nullptr) { + concatenate_xform_samples( + *matrix_samples_data.samples, local_xform_samples, concatenated_xform_samples); } - xform_samples = &concatenated_xform_samples; + matrix_samples_data.samples = &concatenated_xform_samples; + matrix_samples_data.time_sampling = ts; } next_object = xform; @@ -1803,8 +1821,9 @@ void AlembicProcedural::walk_hierarchy( abc_object->iobject = subd; abc_object->schema_type = AlembicObject::SUBD; - if (xform_samples) { - abc_object->xform_samples = *xform_samples; + if (matrix_samples_data.samples) { + abc_object->xform_samples = *matrix_samples_data.samples; + abc_object->xform_time_sampling = matrix_samples_data.time_sampling; } } @@ -1821,8 +1840,9 @@ void AlembicProcedural::walk_hierarchy( abc_object->iobject = mesh; abc_object->schema_type = AlembicObject::POLY_MESH; - if (xform_samples) { - abc_object->xform_samples = *xform_samples; + if (matrix_samples_data.samples) { + abc_object->xform_samples = *matrix_samples_data.samples; + abc_object->xform_time_sampling = matrix_samples_data.time_sampling; } } @@ -1839,8 +1859,9 @@ void AlembicProcedural::walk_hierarchy( abc_object->iobject = curves; abc_object->schema_type = AlembicObject::CURVES; - if (xform_samples) { - abc_object->xform_samples = *xform_samples; + if (matrix_samples_data.samples) { + abc_object->xform_samples = *matrix_samples_data.samples; + abc_object->xform_time_sampling = matrix_samples_data.time_sampling; } } @@ -1857,7 +1878,7 @@ void AlembicProcedural::walk_hierarchy( if (next_object.valid()) { for (size_t i = 0; i < next_object.getNumChildren(); ++i) { walk_hierarchy( - next_object, next_object.getChildHeader(i), xform_samples, object_map, progress); + next_object, next_object.getChildHeader(i), matrix_samples_data, object_map, progress); } } } diff --git a/intern/cycles/render/alembic.h b/intern/cycles/render/alembic.h index b986f46bc8a..a00343c5225 100644 --- a/intern/cycles/render/alembic.h +++ b/intern/cycles/render/alembic.h @@ -38,6 +38,11 @@ class Shader; using MatrixSampleMap = std::map; +struct MatrixSamplesData { + MatrixSampleMap *samples = nullptr; + Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling; +}; + /* Helpers to detect if some type is a ccl::array. */ template struct is_array : public std::false_type { }; @@ -274,6 +279,7 @@ class AlembicObject : public Node { bool need_shader_update = true; + Alembic::AbcCoreAbstract::TimeSamplingPtr xform_time_sampling; MatrixSampleMap xform_samples; Alembic::AbcGeom::IObject iobject; @@ -384,7 +390,7 @@ class AlembicProcedural : public Procedural { * way for each IObject. */ void walk_hierarchy(Alembic::AbcGeom::IObject parent, const Alembic::AbcGeom::ObjectHeader &ohead, - MatrixSampleMap *xform_samples, + MatrixSamplesData matrix_samples_data, const unordered_map &object_map, Progress &progress); -- cgit v1.2.3