Fix (unreported) EditNormal modifier: broken 'flip poly' feature.
authorBastien Montagne <montagne29@wanadoo.fr>
Tue, 7 Jun 2016 11:04:05 +0000 (13:04 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Tue, 7 Jun 2016 11:07:01 +0000 (13:07 +0200)
Newly computed custom normals were forgotten during poly flipping, leading
to wrong custom normals being assigned to wrong loop...

Dead simple, but was tough to track down this one!

source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/mesh_evaluate.c
source/blender/modifiers/intern/MOD_normal_edit.c

index c7d5857b873d0bfd8c26528e516e087c3c6dfa44..d8d869015a3da6a238c46bcccc24a4dbd5a27b84 100644 (file)
@@ -323,7 +323,7 @@ void BKE_mesh_mdisp_flip(struct MDisps *md, const bool use_loop_mdisp_flip);
 
 void BKE_mesh_polygon_flip_ex(
         struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata,
-        struct MDisps *mdisp, const bool use_loop_mdisp_flip);
+        float (*lnors)[3], struct MDisps *mdisp, const bool use_loop_mdisp_flip);
 void BKE_mesh_polygon_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata);
 void BKE_mesh_polygons_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata, int totpoly);
 
index e7e6118813ebb1d248f6ef03df4530e76127a751..392a38773e7c956c95362db02c45d6485628498a 100644 (file)
@@ -2660,6 +2660,9 @@ void CDDM_calc_loop_normals(DerivedMesh *dm, const bool use_split_normals, const
 }
 
 /* #define DEBUG_CLNORS */
+#ifdef DEBUG_CLNORS
+#  include "BLI_linklist.h"
+#endif
 
 void CDDM_calc_loop_normals_spacearr(
         DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
index 577a21285f8b2f7e8893c13c6584d960f1f87763..1c86fbcfe8efcc9831726d2132c006ee3c6a5f8d 100644 (file)
@@ -677,7 +677,7 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS
         */
        copy_v3_v3(*lnor, polynors[mp_index]);
 
-       /* printf("BASIC: handling loop %d / edge %d / vert %d\n", ml_curr_index, ml_curr->e, ml_curr->v); */
+       /* printf("BASIC: handling loop %d / edge %d / vert %d / poly %d\n", ml_curr_index, ml_curr->e, ml_curr->v, mp_index); */
 
        /* If needed, generate this (simple!) lnor space. */
        if (lnors_spacearr) {
@@ -3262,14 +3262,14 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
  */
 void BKE_mesh_polygon_flip_ex(
         MPoly *mpoly, MLoop *mloop, CustomData *ldata,
-        MDisps *mdisp, const bool use_loop_mdisp_flip)
+        float (*lnors)[3], MDisps *mdisp, const bool use_loop_mdisp_flip)
 {
        int loopstart = mpoly->loopstart;
        int loopend = loopstart + mpoly->totloop - 1;
        const bool loops_in_ldata = (CustomData_get_layer(ldata, CD_MLOOP) == mloop);
 
        if (mdisp) {
-               for (int i = mpoly->loopstart; i <= loopend; i++) {
+               for (int i = loopstart; i <= loopend; i++) {
                        BKE_mesh_mdisp_flip(&mdisp[i], use_loop_mdisp_flip);
                }
        }
@@ -3288,6 +3288,9 @@ void BKE_mesh_polygon_flip_ex(
                if (!loops_in_ldata) {
                        SWAP(MLoop, mloop[loopstart], mloop[loopend]);
                }
+               if (lnors) {
+                       swap_v3_v3(lnors[loopstart], lnors[loopend]);
+               }
                CustomData_swap(ldata, loopstart, loopend);
        }
        /* Even if we did not swap the other 'pivot' loop, we need to set its swapped edge. */
@@ -3299,7 +3302,7 @@ void BKE_mesh_polygon_flip_ex(
 void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata)
 {
        MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS);
-       BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, mdisp, true);
+       BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, NULL, mdisp, true);
 }
 
 /**
@@ -3315,7 +3318,7 @@ void BKE_mesh_polygons_flip(
        int i;
 
        for (mp = mpoly, i = 0; i < totpoly; mp++, i++) {
-               BKE_mesh_polygon_flip_ex(mp, mloop, ldata, mdisp, true);
+               BKE_mesh_polygon_flip_ex(mp, mloop, ldata, NULL, mdisp, true);
        }
 }
 
index d386653d2c6132ba055c2fae817fc19449758d2f..2cfa746ab3ce92d19de941537812a46ac93e6ed9 100644 (file)
@@ -158,6 +158,7 @@ static bool polygons_check_flip(
         MPoly *mpoly, float (*polynors)[3], const int num_polys)
 {
        MPoly *mp;
+       MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS);
        int i;
        bool flipped = false;
 
@@ -176,7 +177,7 @@ static bool polygons_check_flip(
 
                /* If average of new loop normals is opposed to polygon normal, flip polygon. */
                if (dot_v3v3(polynors[i], norsum) < 0.0f) {
-                       BKE_mesh_polygon_flip(mp, mloop, ldata);
+                       BKE_mesh_polygon_flip_ex(mp, mloop, ldata, nos, mdisp, true);
                        negate_v3(polynors[i]);
                        flipped = true;
                }
@@ -272,6 +273,8 @@ static void normalEditModifier_do_radial(
 
        if (polygons_check_flip(mloop, nos, dm->getLoopDataLayout(dm), mpoly, polynors, num_polys)) {
                dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
+               /* We need to recompute vertex normals! */
+               dm->calcNormals(dm);
        }
 
        BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,