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:
authorCampbell Barton <ideasman42@gmail.com>2016-03-14 06:15:56 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-03-18 13:44:24 +0300
commite100a8598f4cab14aaaeab4f2dd9ac530687d93d (patch)
tree0561f1f774feecde55fb7c4a7883b20c8f24e62d
parentf0e52274adb8544832cbca58b543a8bc94b83ec6 (diff)
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.
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c30
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c3
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c1
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c12
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h3
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c1
-rw-r--r--source/blender/bmesh/operators/bmo_symmetrize.c3
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c4
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c11
10 files changed, 54 insertions, 18 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 7b56d90e39f..307ceef4a2d 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 808967a39ca..fb5702bc574 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 273d5dba94d..d3c847de64e 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 72a8dac534a..7e4a1358a9b 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 40f6078dc0b..62b29e61d08 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 a1d17101ece..8f0df81af73 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 3eae98b3c46..a2da7af6362 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 5c1b4287c2f..2afd2c574f9 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 964d0b1dfc6..e596032663e 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 b240836b153..c78e05391e3 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);