Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2020-05-12 14:21:17 +0300
committerSybren A. Stüvel <sybren@blender.org>2020-05-12 14:58:40 +0300
commit973ab436f07c652cb6aa13bedc351df06bce6561 (patch)
tree166b4cac5199e5379524fb46c21443715885baa4 /source/blender/io
parentfffcb6e48068d77de6bbaaf35ef30515d1078dac (diff)
Fix T76514: Invalid geometry in Alembic crashes Blender
Even though {T76514} is caused by invalid geometry, and thus technically constitutes a bug in the software that created the Alembic file, I would like Blender not to crash on importing such a file. The error in the Alembic file consists of invalid mesh loops, where consecutive loops refer to the same vertex. The `BKE_mesh_validate()` can actually correct these errors, so this commit focuses on two things: - Letting Blender survive the situation until the mesh is loaded, and - Detecting the error so that `BKE_mesh_validate()` can be called only when necessary. This ensures there is only a minimal impact on performance when loading actually valid data. Differential Revision: https://developer.blender.org/D7703 Reviewed By: JacquesLucke
Diffstat (limited to 'source/blender/io')
-rw-r--r--source/blender/io/alembic/intern/abc_customdata.h5
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc16
2 files changed, 20 insertions, 1 deletions
diff --git a/source/blender/io/alembic/intern/abc_customdata.h b/source/blender/io/alembic/intern/abc_customdata.h
index 6107e230627..11b005eb66a 100644
--- a/source/blender/io/alembic/intern/abc_customdata.h
+++ b/source/blender/io/alembic/intern/abc_customdata.h
@@ -68,6 +68,8 @@ struct CDStreamConfig {
Alembic::AbcGeom::index_t index;
Alembic::AbcGeom::index_t ceil_index;
+ const char **modifier_error_message;
+
CDStreamConfig()
: mloop(NULL),
totloop(0),
@@ -80,7 +82,8 @@ struct CDStreamConfig {
weight(0.0f),
time(0.0f),
index(0),
- ceil_index(0)
+ ceil_index(0),
+ modifier_error_message(NULL)
{
}
};
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index ec74fb2137e..b85bce3e10a 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -201,6 +201,7 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
unsigned int loop_index = 0;
unsigned int rev_loop_index = 0;
unsigned int uv_index = 0;
+ bool seen_invalid_geometry = false;
for (int i = 0; i < face_counts->size(); i++) {
const int face_size = (*face_counts)[i];
@@ -216,10 +217,18 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
/* NOTE: Alembic data is stored in the reverse order. */
rev_loop_index = loop_index + (face_size - 1);
+ uint last_vertex_index = 0;
for (int f = 0; f < face_size; f++, loop_index++, rev_loop_index--) {
MLoop &loop = mloops[rev_loop_index];
loop.v = (*face_indices)[loop_index];
+ if (f > 0 && loop.v == last_vertex_index) {
+ /* This face is invalid, as it has consecutive loops from the same vertex. This is caused
+ * by invalid geometry in the Alembic file, such as in T76514. */
+ seen_invalid_geometry = true;
+ }
+ last_vertex_index = loop.v;
+
if (do_uvs) {
MLoopUV &loopuv = mloopuvs[rev_loop_index];
@@ -237,6 +246,12 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
}
BKE_mesh_calc_edges(config.mesh, false, false);
+ if (seen_invalid_geometry) {
+ if (config.modifier_error_message) {
+ *config.modifier_error_message = "Mesh hash invalid geometry; more details on the console";
+ }
+ BKE_mesh_validate(config.mesh, true, true);
+ }
}
static void process_no_normals(CDStreamConfig &config)
@@ -609,6 +624,7 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
config.time = sample_sel.getRequestedTime();
+ config.modifier_error_message = err_str;
read_mesh_sample(m_iobject.getFullName(), &settings, m_schema, sample_sel, config);