diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-03-07 18:17:59 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-03-07 19:16:16 +0300 |
commit | 00f218602d52defee624e9853b03431d732649fa (patch) | |
tree | 24d74d16005f68f7c75bd8de319adf6d6938585b | |
parent | ac4d45dbf156f538d2591b5323a042b4a59692e1 (diff) |
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.
-rw-r--r-- | intern/cycles/render/alembic.cpp | 47 | ||||
-rw-r--r-- | intern/cycles/render/alembic.h | 8 |
2 files changed, 41 insertions, 14 deletions
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<std::string, AlembicObject *> &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<Alembic::Abc::chrono_t, Alembic::Abc::M44d>; +struct MatrixSamplesData { + MatrixSampleMap *samples = nullptr; + Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling; +}; + /* Helpers to detect if some type is a ccl::array. */ template<typename> 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<string, AlembicObject *> &object_map, Progress &progress); |