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.
This commit is contained in:
parent
ac4d45dbf1
commit
00f218602d
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue