Commit: 0053a9116553c516d7a3e5ccd16d8ffd6a27da3b
Author: Kévin Dietrich
Date:   Fri Sep 9 05:59:20 2016 +0200
Branches: master
https://developer.blender.org/rB0053a9116553c516d7a3e5ccd16d8ffd6a27da3b

Alembic streaming: initial support to interpolate data between frames.

Pretty self-explanatory, allows to get some slow motion type of playback
and animations.

===================================================================

M       source/blender/alembic/intern/abc_customdata.h
M       source/blender/alembic/intern/abc_mesh.cc
M       source/blender/alembic/intern/alembic_capi.cc

===================================================================

diff --git a/source/blender/alembic/intern/abc_customdata.h 
b/source/blender/alembic/intern/abc_customdata.h
index 3b16c0d..bc42e24 100644
--- a/source/blender/alembic/intern/abc_customdata.h
+++ b/source/blender/alembic/intern/abc_customdata.h
@@ -63,6 +63,11 @@ struct CDStreamConfig {
        void *user_data;
        void *(*add_customdata_cb)(void *user_data, const char *name, int 
data_type);
 
+       float weight;
+       float time;
+       int index;
+       int ceil_index;
+
        CDStreamConfig()
            : mloop(NULL)
            , totloop(0)
@@ -72,6 +77,10 @@ struct CDStreamConfig {
            , pack_uvs(false)
            , user_data(NULL)
            , add_customdata_cb(NULL)
+           , weight(0.0f)
+           , time(0.0f)
+           , index(0)
+           , ceil_index(0)
        {}
 };
 
diff --git a/source/blender/alembic/intern/abc_mesh.cc 
b/source/blender/alembic/intern/abc_mesh.cc
index 70af6af..18b5dd9 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -804,6 +804,7 @@ struct AbcMeshData {
        Int32ArraySamplePtr face_counts;
 
        P3fArraySamplePtr positions;
+       P3fArraySamplePtr ceil_positions;
 
        N3fArraySamplePtr vertex_normals;
        N3fArraySamplePtr face_normals;
@@ -851,12 +852,32 @@ CDStreamConfig create_config(Mesh *mesh)
        return config;
 }
 
+static void read_mverts_interp(MVert *mverts, const P3fArraySamplePtr 
&positions, const P3fArraySamplePtr &ceil_positions, const float weight)
+{
+       float tmp[3];
+       for (int i = 0; i < positions->size(); ++i) {
+               MVert &mvert = mverts[i];
+               const Imath::V3f &floor_pos = (*positions)[i];
+               const Imath::V3f &ceil_pos = (*ceil_positions)[i];
+
+               interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), 
weight);
+               copy_yup_zup(mvert.co, tmp);
+
+               mvert.bweight = 0;
+       }
+}
+
 static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
 {
        MVert *mverts = config.mvert;
        const P3fArraySamplePtr &positions = mesh_data.positions;
        const N3fArraySamplePtr &normals = mesh_data.vertex_normals;
 
+       if (config.weight != 0.0f && mesh_data.ceil_positions) {
+               read_mverts_interp(mverts, positions, mesh_data.ceil_positions, 
config.weight);
+               return;
+       }
+
        read_mverts(mverts, positions, normals);
 }
 
@@ -1083,6 +1104,46 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh 
*mesh, size_t poly_star
        utils::assign_materials(bmain, m_object, mat_map);
 }
 
+typedef std::pair<Alembic::AbcCoreAbstract::index_t, float> index_time_pair_t;
+
+static void get_weight_and_index(CDStreamConfig &config,
+                                 Alembic::AbcCoreAbstract::TimeSamplingPtr 
time_sampling,
+                                 size_t samples_number)
+{
+       if (samples_number == 0) {
+               samples_number = 1;
+       }
+
+       index_time_pair_t floor_index = 
time_sampling->getFloorIndex(config.time, samples_number);
+
+       config.index = floor_index.first;
+       config.ceil_index = config.index;
+
+       if (fabs(config.time - floor_index.second) < 0.0001f) {
+               config.weight = 0.0f;
+               return;
+       }
+
+       index_time_pair_t ceil_index = time_sampling->getCeilIndex(config.time, 
samples_number);
+
+       if (config.index == ceil_index.first) {
+               config.weight = 0.0f;
+               return;
+       }
+
+       config.ceil_index = ceil_index.first;
+
+       float alpha = (config.time - floor_index.second) / (ceil_index.second - 
floor_index.second);
+
+       /* Since we so closely match the ceiling, we'll just use it. */
+       if (fabs(1.0f - alpha) < 0.0001f) {
+               config.index = config.ceil_index;
+               alpha = 0.0f;
+       }
+
+       config.weight = alpha;
+}
+
 void read_mesh_sample(ImportSettings *settings,
                       const IPolyMeshSchema &schema,
                       const ISampleSelector &selector,
@@ -1100,6 +1161,14 @@ void read_mesh_sample(ImportSettings *settings,
 
        do_normals = (abc_mesh_data.face_normals != NULL);
 
+       get_weight_and_index(config, schema.getTimeSampling(), 
schema.getNumSamples());
+
+       if (config.weight != 0.0f) {
+               Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample;
+               schema.get(ceil_sample, 
Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index)));
+               abc_mesh_data.ceil_positions = ceil_sample.getPositions();
+       }
+
        if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
                read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), 
selector);
        }
@@ -1215,6 +1284,14 @@ void read_subd_sample(ImportSettings *settings,
        abc_mesh_data.face_normals = N3fArraySamplePtr();
        abc_mesh_data.positions = sample.getPositions();
 
+       get_weight_and_index(config, schema.getTimeSampling(), 
schema.getNumSamples());
+
+       if (config.weight != 0.0f) {
+               Alembic::AbcGeom::ISubDSchema::Sample ceil_sample;
+               schema.get(ceil_sample, 
Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index)));
+               abc_mesh_data.ceil_positions = ceil_sample.getPositions();
+       }
+
        if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
                read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), 
selector);
        }
diff --git a/source/blender/alembic/intern/alembic_capi.cc 
b/source/blender/alembic/intern/alembic_capi.cc
index 04ea8e8..3cc5493 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -898,6 +898,7 @@ static DerivedMesh *read_mesh_sample(DerivedMesh *dm, const 
IObject &iobject, co
        }
 
        CDStreamConfig config = get_config(new_dm ? new_dm : dm);
+       config.time = time;
 
        bool do_normals = false;
        read_mesh_sample(&settings, schema, sample_sel, config, do_normals);
@@ -952,6 +953,7 @@ static DerivedMesh *read_subd_sample(DerivedMesh *dm, const 
IObject &iobject, co
 
        /* Only read point data when streaming meshes, unless we need to create 
new ones. */
        CDStreamConfig config = get_config(new_dm ? new_dm : dm);
+       config.time = time;
        read_subd_sample(&settings, schema, sample_sel, config);
 
        if (new_dm) {

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to