diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-06-23 06:48:33 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-06-23 06:57:23 +0300 |
commit | 61b22d27c8b9b64f04a7dd585eac11134184a235 (patch) | |
tree | 279f8622b10c1b57ec96b6dfc58da60302977663 | |
parent | 5cc8e7ab53cb20a64b8c14268fe2dba2396b4247 (diff) |
Fix T89249: incorrect mesh validate error with zeroed vertex normals
It's not an error for centered vertices to have a zero normal.
-rw-r--r-- | source/blender/blenkernel/intern/mesh_validate.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 3570b1dd933..df84cf6607f 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -217,6 +217,16 @@ static int search_polyloop_cmp(const void *v1, const void *v2) * Validate the mesh, \a do_fixes requires \a mesh to be non-null. * * \return false if no changes needed to be made. + * + * Vertex Normals + * ============== + * + * While zeroed normals are checked, these checks aren't comprehensive. + * Technically, to detect errors here a normal recalculation and comparison is necessary. + * However this function is mainly to prevent severe errors in geometry + * (invalid data that will crash Blender, or cause some features to behave incorrectly), + * not to detect subtle differences in the resulting normals which could be caused + * by importers that load normals (for example). */ /* NOLINTNEXTLINE: readability-function-size */ bool BKE_mesh_validate_arrays(Mesh *mesh, @@ -328,10 +338,21 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, } if (fix_normal) { - PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal", i); - if (do_fixes) { - mv->no[2] = SHRT_MAX; - fix_flag.verts = true; + /* If the vertex normal accumulates to zero or isn't part of a face, the location is used. + * When the location is also zero, a zero normal warning should not be raised. + * since this is the expected behavior of normal calculation. + * + * This avoids false positives but isn't foolproof as it's possible the vertex + * is part of a polygon that has a normal which this vertex should be using, + * although it's also possible degenerate/opposite faces accumulate to a zero vector. + * To detect this a full normal recalculation would be needed, which is out of scope + * for a basic validity check (see "Vertex Normal" in the doc-string). */ + if (!is_zero_v3(mv->co)) { + PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal", i); + if (do_fixes) { + mv->no[2] = SHRT_MAX; + fix_flag.verts = true; + } } } } |