Fix broken Mesh 'calc_smooth_groups' logic.
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 10 Jul 2019 09:21:43 +0000 (11:21 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Wed, 10 Jul 2019 09:24:37 +0000 (11:24 +0200)
We need to check both polygons of a manifold edge to be sure it is
actually smooth...

Reported by Hugo Sales (@someonewithpc) on blender.chat, thanks.

source/blender/blenkernel/intern/mesh_mapping.c

index 7f64b1567472ea8a1f5561c73eff057b7177bbc5..78c0fa184f49ccae3bfff3a2f23da29ee6b6bb87 100644 (file)
@@ -631,6 +631,8 @@ typedef bool (*MeshRemap_CheckIslandBoundary)(const struct MPoly *mpoly,
                                               const struct MLoop *mloop,
                                               const struct MEdge *medge,
                                               const int nbr_egde_users,
+                                              const struct MPoly *mpoly_array,
+                                              const struct MeshElemMap *edge_poly_map,
                                               void *user_data);
 
 static void poly_edge_loop_islands_calc(const MEdge *medge,
@@ -730,7 +732,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
         const MeshElemMap *map_ele = &edge_poly_map[me_idx];
         const int *p = map_ele->indices;
         int i = map_ele->count;
-        if (!edge_boundary_check(mp, ml, me, i, edge_boundary_check_data)) {
+        if (!edge_boundary_check(mp, ml, me, i, mpoly, map_ele, edge_boundary_check_data)) {
           for (; i--; p++) {
             /* if we meet other non initialized its a bug */
             BLI_assert(ELEM(poly_groups[*p], 0, poly_group_id));
@@ -832,11 +834,20 @@ static bool poly_is_island_boundary_smooth_cb(const MPoly *mp,
                                               const MLoop *UNUSED(ml),
                                               const MEdge *me,
                                               const int nbr_egde_users,
+                                              const MPoly *mpoly_array,
+                                              const MeshElemMap *edge_poly_map,
                                               void *UNUSED(user_data))
 {
-  /* Edge is sharp if its poly is sharp, or edge itself is sharp,
+  /* Edge is sharp if one of its polys is flat, or edge itself is sharp,
    * or edge is not used by exactly two polygons. */
-  return (!(mp->flag & ME_SMOOTH) || (me->flag & ME_SHARP) || (nbr_egde_users != 2));
+  if ((mp->flag & ME_SMOOTH) && !(me->flag & ME_SHARP) && (nbr_egde_users == 2)) {
+    /* In that case, edge appears to be smooth, but we need to check its other poly too. */
+    const MPoly *mp_other = (mp == &mpoly_array[edge_poly_map->indices[0]]) ?
+                                &mpoly_array[edge_poly_map->indices[1]] :
+                                &mpoly_array[edge_poly_map->indices[0]];
+    return (mp_other->flag & ME_SMOOTH) != 0;
+  }
+  return true;
 }
 
 /**
@@ -1002,6 +1013,8 @@ static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp),
                                           const MLoop *ml,
                                           const MEdge *me,
                                           const int UNUSED(nbr_egde_users),
+                                          const MPoly *UNUSED(mpoly_array),
+                                          const MeshElemMap *UNUSED(edge_poly_map),
                                           void *user_data)
 {
   if (user_data) {