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:
authorBastien Montagne <montagne29@wanadoo.fr>2014-05-28 20:37:30 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2014-05-28 20:55:46 +0400
commit74cc3974fea0422343b09bdd61e4d3924c62940a (patch)
tree3530aa55027f7f8dc95ec202f049097aae4eae02 /source/blender/bmesh/intern/bmesh_mesh.c
parent9913da2b7f0a17112aa50d834d93d5f7961add06 (diff)
Fix T40405: Blender crashes on FBX export instantly.
Better fix than rBbef5cb3aa2e5a: consider edges between faces with opposed normals as sharp. In fact, previous code was broken more deeply in this case (inconsistent normals across a 'smooth fan') - some loop normals would even never be computed! Fixing this is possible (even wrote it, actually), but this adds more complexity to a piece of code that is already awfully complicated, *and* normals in that kind of smooth fan do not make much sense anyway. So simpler and nicer results with assuming sharp edges between such 'opposed' faces! Note that there is some face (loop) ordering black magic at work here, added more comments to try to explain how and why all this works. As a bonus, we do not need to check for already computed loop normals anymore, since we know each 'smooth fan' will be walked once, and only once.
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_mesh.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index e9d3c36eb1a..7df3f0e8367 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -477,11 +477,18 @@ static void bm_mesh_edges_sharp_tag(BMesh *bm, const float (*vnos)[3], const flo
is_angle_smooth = (dot_v3v3(no_a, no_b) >= split_angle);
}
- /* We only tag edges that are *really* smooth... */
+ /* We only tag edges that are *really* smooth:
+ * If the angle between both its polys' normals is below split_angle value,
+ * and it is tagged as such,
+ * and both its faces are smooth,
+ * and both its faces have compatible (non-flipped) normals, i.e. both loops on the same edge do not share
+ * the same vertex.
+ */
if (is_angle_smooth &&
BM_elem_flag_test_bool(e, BM_ELEM_SMOOTH) &&
BM_elem_flag_test_bool(l_a->f, BM_ELEM_SMOOTH) &&
- BM_elem_flag_test_bool(l_b->f, BM_ELEM_SMOOTH))
+ BM_elem_flag_test_bool(l_b->f, BM_ELEM_SMOOTH) &&
+ l_a->v != l_b->v)
{
const float *no;
BM_elem_flag_enable(e, BM_ELEM_TAG);
@@ -542,6 +549,14 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
const float *no = fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no;
copy_v3_v3(r_lnos[BM_elem_index_get(l_curr)], no);
}
+ /* We *do not need* to check/tag loops as already computed!
+ * Due to the fact a loop only links to one of its two edges, a same fan *will never be walked more than
+ * once!*
+ * Since we consider edges having neighbor faces with inverted (flipped) normals as sharp, we are sure that
+ * no fan will be skipped, even only considering the case (sharp curr_edge, smooth prev_edge), and not the
+ * alternative (smooth curr_edge, sharp prev_edge).
+ * All this due/thanks to link between normals and loop ordering.
+ */
else {
/* We have to fan around current vertex, until we find the other non-smooth edge,
* and accumulate face normals into the vertex!