Commit: e100a8598f4cab14aaaeab4f2dd9ac530687d93d
Author: Campbell Barton
Date:   Mon Mar 14 14:15:56 2016 +1100
Branches: blender-v2.77-release
https://developer.blender.org/rBe100a8598f4cab14aaaeab4f2dd9ac530687d93d

Fix T47788: Symmetrize flips multi-res data

Symmetrize was unusable with multi-res data,
add an option for the bmesh operator not to flip the multi-res depth.

===================================================================

M       source/blender/bmesh/intern/bmesh_core.c
M       source/blender/bmesh/intern/bmesh_core.h
M       source/blender/bmesh/intern/bmesh_mods.c
M       source/blender/bmesh/intern/bmesh_opdefines.c
M       source/blender/bmesh/intern/bmesh_polygon.c
M       source/blender/bmesh/intern/bmesh_polygon.h
M       source/blender/bmesh/operators/bmo_extrude.c
M       source/blender/bmesh/operators/bmo_symmetrize.c
M       source/blender/bmesh/operators/bmo_utils.c
M       source/blender/editors/mesh/editmesh_tools.c

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_core.c 
b/source/blender/bmesh/intern/bmesh_core.c
index 7b56d90..307ceef 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -1044,13 +1044,18 @@ static int UNUSED_FUNCTION(bm_loop_length)(BMLoop *l)
  *
  * BMESH_TODO: reinsert validation code.
  *
+ * \param cd_loop_mdisp_offset: Cached result of 
`CustomData_get_offset(&bm->ldata, CD_MDISPS)`.
+ * \param use_loop_mdisp_flip: When set, flip the Z-depth of the mdisp,
+ * (use when flipping normals, disable when mirroring, eg: symmetrize).
+ *
  * \return Success
  */
-static bool bm_loop_reverse_loop(BMesh *bm, BMFace *f
+static bool bm_loop_reverse_loop(
+        BMesh *bm, BMFace *f,
 #ifdef USE_BMESH_HOLES
-                                , BMLoopList *lst
+        BMLoopList *lst,
 #endif
-                                )
+        const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
 {
 
 #ifdef USE_BMESH_HOLES
@@ -1060,7 +1065,6 @@ static bool bm_loop_reverse_loop(BMesh *bm, BMFace *f
 #endif
 
        const int len = f->len;
-       const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, 
CD_MDISPS);
        BMLoop *l_iter, *oldprev, *oldnext;
        BMEdge **edar = BLI_array_alloca(edar, len);
        int i, j, edok;
@@ -1100,15 +1104,19 @@ static bool bm_loop_reverse_loop(BMesh *bm, BMFace *f
                                        SWAP(float, co_a[0], co_a[1]);
                                        SWAP(float, co_b[0], co_b[1]);
 
-                                       co_a[2] *= -1.0f;
-                                       co_b[2] *= -1.0f;
+                                       if (use_loop_mdisp_flip) {
+                                               co_a[2] *= -1.0f;
+                                               co_b[2] *= -1.0f;
+                                       }
                                }
 
                                co_a = co[x * sides + x];
 
                                SWAP(float, co_a[0], co_a[1]);
 
-                               co_a[2] *= -1.0f;
+                               if (use_loop_mdisp_flip) {
+                                       co_a[2] *= -1.0f;
+                               }
                        }
                }
        }
@@ -1155,12 +1163,14 @@ static bool bm_loop_reverse_loop(BMesh *bm, BMFace *f
 /**
  * \brief Flip the faces direction
  */
-bool bmesh_loop_reverse(BMesh *bm, BMFace *f)
+bool bmesh_loop_reverse(
+        BMesh *bm, BMFace *f,
+        const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
 {
 #ifdef USE_BMESH_HOLES
-       return bm_loop_reverse_loop(bm, f, f->loops.first);
+       return bm_loop_reverse_loop(bm, f, f->loops.first, 
cd_loop_mdisp_offset, use_loop_mdisp_flip);
 #else
-       return bm_loop_reverse_loop(bm, f);
+       return bm_loop_reverse_loop(bm, f, cd_loop_mdisp_offset, 
use_loop_mdisp_flip);
 #endif
 }
 
diff --git a/source/blender/bmesh/intern/bmesh_core.h 
b/source/blender/bmesh/intern/bmesh_core.h
index 808967a..fb5702b 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -75,7 +75,9 @@ void    bmesh_vert_separate(
         BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
         const bool copy_select);
 
-bool    bmesh_loop_reverse(BMesh *bm, BMFace *f);
+bool    bmesh_loop_reverse(
+        BMesh *bm, BMFace *f,
+        const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip);
 
 BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool 
do_del);
 void    BM_vert_separate(
diff --git a/source/blender/bmesh/intern/bmesh_mods.c 
b/source/blender/bmesh/intern/bmesh_mods.c
index 273d5db..d3c847d 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -244,7 +244,8 @@ BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f_a, BMFace 
*f_b, BMEdge *e, const
        BLI_assert(l_a && l_b);
 
        if (l_a->v == l_b->v) {
-               bmesh_loop_reverse(bm, f_b);
+               const int cd_loop_mdisp_offset = 
CustomData_get_offset(&bm->ldata, CD_MDISPS);
+               bmesh_loop_reverse(bm, f_b, cd_loop_mdisp_offset, true);
        }
        
        return BM_faces_join(bm, faces, 2, do_del);
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c 
b/source/blender/bmesh/intern/bmesh_opdefines.c
index 72a8dac..7e4a135 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -243,6 +243,7 @@ static BMOpDefine bmo_reverse_faces_def = {
        "reverse_faces",
        /* slots_in */
        {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
+        {"flip_multires", BMO_OP_SLOT_BOOL},  /* maintain multi-res offset */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c 
b/source/blender/bmesh/intern/bmesh_polygon.c
index 40f6078..62b29e6 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -702,12 +702,20 @@ void BM_face_calc_center_mean_vcos(
  * Reverses the winding of a face.
  * \note This updates the calculated normal.
  */
-void BM_face_normal_flip(BMesh *bm, BMFace *f)
+void BM_face_normal_flip_ex(
+        BMesh *bm, BMFace *f,
+        const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
 {
-       bmesh_loop_reverse(bm, f);
+       bmesh_loop_reverse(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip);
        negate_v3(f->no);
 }
 
+void BM_face_normal_flip(BMesh *bm, BMFace *f)
+{
+       const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, 
CD_MDISPS);
+       BM_face_normal_flip_ex(bm, f, cd_loop_mdisp_offset, true);
+}
+
 /* detects if two line segments cross each other (intersects).
  * note, there could be more winding cases then there needs to be. */
 static bool line_crosses_v2f(const float v1[2], const float v2[2], const float 
v3[2], const float v4[2])
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h 
b/source/blender/bmesh/intern/bmesh_polygon.h
index a1d1710..8f0df81 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -62,6 +62,9 @@ bool  BM_vert_calc_normal(const BMVert *v, float r_no[3]);
 void  BM_vert_normal_update(BMVert *v) ATTR_NONNULL();
 void  BM_vert_normal_update_all(BMVert *v) ATTR_NONNULL();
 
+void  BM_face_normal_flip_ex(
+        BMesh *bm, BMFace *f,
+        const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip) 
ATTR_NONNULL();
 void  BM_face_normal_flip(BMesh *bm, BMFace *f) ATTR_NONNULL();
 bool  BM_face_point_inside_test(const BMFace *f, const float co[3]) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 
diff --git a/source/blender/bmesh/operators/bmo_extrude.c 
b/source/blender/bmesh/operators/bmo_extrude.c
index 3eae98b..a2da7af 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -772,6 +772,7 @@ void bmo_solidify_face_region_exec(BMesh *bm, BMOperator 
*op)
 
        /* Flip original faces (so the shell is extruded inward) */
        BMO_op_init(bm, &reverseop, op->flag, "reverse_faces");
+       BMO_slot_bool_set(reverseop.slots_in, "flip_multires", true);
        BMO_slot_copy(op,         slots_in, "geom",
                      &reverseop, slots_in, "faces");
        BMO_op_exec(bm, &reverseop);
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c 
b/source/blender/bmesh/operators/bmo_symmetrize.c
index 5c1b428..2afd2c5 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -79,6 +79,9 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op)
 
 
        BMO_op_callf(bm, op->flag, "scale verts=%S vec=%v", &op_dupe, 
"geom.out", scale);
+
+       /* important 'flip_multires' is disabled,
+        * otherwise multi-res data will be reversed, see: T47788 */
        BMO_op_callf(bm, op->flag, "reverse_faces faces=%S", &op_dupe, 
"geom.out");
 
 
diff --git a/source/blender/bmesh/operators/bmo_utils.c 
b/source/blender/bmesh/operators/bmo_utils.c
index 964d0b1..e596032 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -111,11 +111,13 @@ void bmo_rotate_exec(BMesh *bm, BMOperator *op)
 
 void bmo_reverse_faces_exec(BMesh *bm, BMOperator *op)
 {
+       const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, 
CD_MDISPS);
+       const bool use_loop_mdisp_flip = BMO_slot_bool_get(op->slots_in, 
"flip_multires");
        BMOIter siter;
        BMFace *f;
 
        BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
-               BM_face_normal_flip(bm, f);
+               BM_face_normal_flip_ex(bm, f, cd_loop_mdisp_offset, 
use_loop_mdisp_flip);
        }
 }
 
diff --git a/source/blender/editors/mesh/editmesh_tools.c 
b/source/blender/editors/mesh/editmesh_tools.c
index b240836..c78e053 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1468,8 +1468,12 @@ static int edbm_flip_normals_exec(bContext *C, 
wmOperator *op)
        Object *obedit = CTX_data_edit_object(C);
        BMEditMesh *em = BKE_editmesh_from_object(obedit);
        
-       if (!EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT))
+       if (!EDBM_op_callf(
+               em, op, "reverse_faces faces=%hf flip_multires=%b",
+               BM_ELEM_SELECT, true))
+       {
                return OPERATOR_CANCELLED;
+       }
        
        EDBM_update_generic(em, true, false);
 
@@ -1637,8 +1641,9 @@ static int edbm_normals_make_consistent_exec(bContext *C, 
wmOperator *op)
        if (!EDBM_op_callf(em, op, "recalc_face_normals faces=%hf", 
BM_ELEM_SELECT))
                return OPERATOR_CANCELLED;
 
-       if (RNA_boolean_get(op->ptr, "inside"))
-               EDBM_op_callf(em, op, "reverse_faces faces=%hf", 
BM_ELEM_SELECT);
+       if (RNA_boolean_get(op->ptr, "inside")) {
+               EDBM_op_callf(em, op, "reverse_faces faces=%hf 
flip_multires=%b", BM_ELEM_SELECT, true);
+       }
 
        EDBM_update_generic(em, true, false);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to