[Bf-blender-cvs] [bab2260b59c] master: Fix T71981: Alembic vertex interpolation can jumble mesh

Sybren A. Stüvel noreply at git.blender.org
Tue Sep 29 16:13:09 CEST 2020


Commit: bab2260b59c7bffe1e16b5e860ac36b5fdc31bf0
Author: Sybren A. Stüvel
Date:   Tue Sep 29 14:34:01 2020 +0200
Branches: master
https://developer.blender.org/rBbab2260b59c7bffe1e16b5e860ac36b5fdc31bf0

Fix T71981: Alembic vertex interpolation can jumble mesh

Add an option to disable Alembic vertex interpolation.
Bump subversion from 5 to 6.

Alembic stores mesh samples at specific time keys; when a frame in
Blender maps to a timecode between two samples, Blender will interpolate
the mesh vertex positions. This interpolation only happens when the mesh
has a constant topology, but sometimes this was not detected properly
when the vertices change order, but the number of mesh elements remains
the same. This would result in a mesh with jumbled up vertices (T71981).
With this patch, users have the ability to disable vertex interpolation.

An alternative would be to have better detection of topology changes,
but that that'll cause a considerable slowdown.

Maniphest Tasks: T71981

Differential Revision: https://developer.blender.org/D9041

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

M	source/blender/blenkernel/BKE_blender_version.h
M	source/blender/blenloader/intern/versioning_290.c
M	source/blender/io/alembic/intern/abc_customdata.h
M	source/blender/io/alembic/intern/abc_reader_mesh.cc
M	source/blender/io/alembic/intern/abc_reader_mesh.h
M	source/blender/io/alembic/intern/abc_reader_points.cc
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_meshsequencecache.c

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

diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 23efea81e57..e43043b034f 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -39,7 +39,7 @@ extern "C" {
 
 /* Blender file format version. */
 #define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 5
+#define BLENDER_FILE_SUBVERSION 6
 
 /* Minimum Blender version that supports reading file written with the current
  * version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 3c95a998d90..1b9e53ded63 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -724,18 +724,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
     }
   }
 
-  /**
-   * Versioning code until next subversion bump goes here.
-   *
-   * \note Be sure to check when bumping the version:
-   * - "versioning_userdef.c", #BLO_version_defaults_userpref_blend
-   * - "versioning_userdef.c", #do_versions_theme
-   *
-   * \note Keep this message at the bottom of the function.
-   */
-  {
-    /* Keep this block, even when empty. */
-
+  if (!MAIN_VERSION_ATLEAST(bmain, 291, 6)) {
     /* Darken Inactive Overlay. */
     if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "fade_alpha")) {
       for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
@@ -759,5 +748,30 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
         mesh->symmetry = mesh->editflag & (ME_SYMMETRY_X | ME_SYMMETRY_Y | ME_SYMMETRY_Z);
       }
     }
+
+    /* Alembic importer: allow vertex interpolation by default. */
+    for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
+      LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+        if (md->type != eModifierType_MeshSequenceCache) {
+          continue;
+        }
+
+        MeshSeqCacheModifierData *data = (MeshSeqCacheModifierData *)md;
+        data->read_flag |= MOD_MESHSEQ_INTERPOLATE_VERTICES;
+      }
+    }
+  }
+
+  /**
+   * Versioning code until next subversion bump goes here.
+   *
+   * \note Be sure to check when bumping the version:
+   * - "versioning_userdef.c", #BLO_version_defaults_userpref_blend
+   * - "versioning_userdef.c", #do_versions_theme
+   *
+   * \note Keep this message at the bottom of the function.
+   */
+  {
+    /* Keep this block, even when empty. */
   }
 }
diff --git a/source/blender/io/alembic/intern/abc_customdata.h b/source/blender/io/alembic/intern/abc_customdata.h
index e98ec271b9f..4eb515f132c 100644
--- a/source/blender/io/alembic/intern/abc_customdata.h
+++ b/source/blender/io/alembic/intern/abc_customdata.h
@@ -66,6 +66,7 @@ struct CDStreamConfig {
 
   float weight;
   float time;
+  bool use_vertex_interpolation;
   Alembic::AbcGeom::index_t index;
   Alembic::AbcGeom::index_t ceil_index;
 
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index ead908e87c2..e69c0edfec8 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -155,8 +155,8 @@ static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
   MVert *mverts = config.mvert;
   const P3fArraySamplePtr &positions = mesh_data.positions;
 
-  if (config.weight != 0.0f && mesh_data.ceil_positions != NULL &&
-      mesh_data.ceil_positions->size() == positions->size()) {
+  if (config.use_vertex_interpolation && config.weight != 0.0f &&
+      mesh_data.ceil_positions != NULL && mesh_data.ceil_positions->size() == positions->size()) {
     read_mverts_interp(mverts, positions, mesh_data.ceil_positions, config.weight);
     return;
   }
@@ -457,7 +457,7 @@ static void read_mesh_sample(const std::string &iobject_full_name,
   }
 }
 
-CDStreamConfig get_config(Mesh *mesh)
+CDStreamConfig get_config(Mesh *mesh, const bool use_vertex_interpolation)
 {
   CDStreamConfig config;
 
@@ -471,6 +471,7 @@ CDStreamConfig get_config(Mesh *mesh)
   config.totpoly = mesh->totpoly;
   config.loopdata = &mesh->ldata;
   config.add_customdata_cb = add_customdata_cb;
+  config.use_vertex_interpolation = use_vertex_interpolation;
 
   return config;
 }
@@ -646,7 +647,9 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
     }
   }
 
-  CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
+  Mesh *mesh_to_export = new_mesh ? new_mesh : existing_mesh;
+  const bool use_vertex_interpolation = read_flag & MOD_MESHSEQ_INTERPOLATE_VERTICES;
+  CDStreamConfig config = get_config(mesh_to_export, use_vertex_interpolation);
   config.time = sample_sel.getRequestedTime();
   config.modifier_error_message = err_str;
 
@@ -936,11 +939,13 @@ Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh,
   }
 
   /* Only read point data when streaming meshes, unless we need to create new ones. */
-  CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
+  Mesh *mesh_to_export = new_mesh ? new_mesh : existing_mesh;
+  const bool use_vertex_interpolation = read_flag & MOD_MESHSEQ_INTERPOLATE_VERTICES;
+  CDStreamConfig config = get_config(mesh_to_export, use_vertex_interpolation);
   config.time = sample_sel.getRequestedTime();
   read_subd_sample(m_iobject.getFullName(), &settings, m_schema, sample_sel, config);
 
-  return config.mesh;
+  return mesh_to_export;
 }
 
 }  // namespace blender::io::alembic
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.h b/source/blender/io/alembic/intern/abc_reader_mesh.h
index a29eeb71dff..3329b723b77 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.h
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.h
@@ -81,6 +81,6 @@ void read_mverts(MVert *mverts,
                  const Alembic::AbcGeom::P3fArraySamplePtr positions,
                  const Alembic::AbcGeom::N3fArraySamplePtr normals);
 
-CDStreamConfig get_config(struct Mesh *mesh);
+CDStreamConfig get_config(struct Mesh *mesh, bool use_vertex_interpolation);
 
 }  // namespace blender::io::alembic
diff --git a/source/blender/io/alembic/intern/abc_reader_points.cc b/source/blender/io/alembic/intern/abc_reader_points.cc
index f8cc6b0314a..88b5088805f 100644
--- a/source/blender/io/alembic/intern/abc_reader_points.cc
+++ b/source/blender/io/alembic/intern/abc_reader_points.cc
@@ -27,6 +27,7 @@
 #include "abc_util.h"
 
 #include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 
 #include "BKE_customdata.h"
@@ -125,7 +126,7 @@ void read_points_sample(const IPointsSchema &schema,
 
 struct Mesh *AbcPointsReader::read_mesh(struct Mesh *existing_mesh,
                                         const ISampleSelector &sample_sel,
-                                        int /*read_flag*/,
+                                        int read_flag,
                                         const char **err_str)
 {
   IPointsSchema::Sample sample;
@@ -150,10 +151,12 @@ struct Mesh *AbcPointsReader::read_mesh(struct Mesh *existing_mesh,
     new_mesh = BKE_mesh_new_nomain(positions->size(), 0, 0, 0, 0);
   }
 
-  CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
+  Mesh *mesh_to_export = new_mesh ? new_mesh : existing_mesh;
+  const bool use_vertex_interpolation = read_flag & MOD_MESHSEQ_INTERPOLATE_VERTICES;
+  CDStreamConfig config = get_config(mesh_to_export, use_vertex_interpolation);
   read_points_sample(m_schema, sample_sel, config);
 
-  return new_mesh ? new_mesh : existing_mesh;
+  return mesh_to_export;
 }
 
 }  // namespace blender::io::alembic
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 7218e75a404..035ac6cf7cb 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -2121,6 +2121,11 @@ enum {
   MOD_MESHSEQ_READ_POLY = (1 << 1),
   MOD_MESHSEQ_READ_UV = (1 << 2),
   MOD_MESHSEQ_READ_COLOR = (1 << 3),
+
+  /* Allow interpolation of mesh vertex positions. There is a heuristic to avoid interpolation when
+   * the mesh topology changes, but this heuristic sometimes fails. In these cases, users can
+   * disable interpolation with this flag. */
+  MOD_MESHSEQ_INTERPOLATE_VERTICES = (1 << 4),
 };
 
 typedef struct SDefBind {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index b433c938bd6..0e8903a2796 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -6134,7 +6134,12 @@ static void rna_def_modifier_meshseqcache(BlenderRNA *brna)
   RNA_def_property_enum_sdna(prop, NULL, "read_flag");
   RNA_def_property_enum_items(prop, read_flag_items);
   RNA_def_property_ui_text(prop, "Read Data", "Data to read from the cache");
+  RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
+  prop = RNA_def_property(srna, "use_vertex_interpolation", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "read_flag", MOD_MESHSEQ_INTERPOLATE_VERTICES);
+  RNA_def_property_ui_text(
+      prop, "Vertex Interpolation", "Allow interpolation of vertex positions.");
   RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
   prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index c9437605a01..eca20c088ce 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -66,7 +66,7 @@ static void initData(ModifierData *md)
 
   mcmd->cache_file = NULL;
   mcmd->object_path[0] = '\0';
-  mcmd->read_flag = MOD_MESHSEQ_READ_ALL;
+  mcmd->read_flag = MOD_MESHSEQ_READ_ALL | MOD_MESHSEQ_INTERPOLATE_VERTICES;
   mcmd->velocity_scale = 1.0f;
   mcmd->vertex_velocities = NULL;
   mcmd->num_vertices = 0;
@@ -238,6 +238,7 @@ static void panel_dra

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list