forked from bartvdbraak/blender
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.
This commit is contained in:
parent
0024768f88
commit
66043cc6c1
@ -1044,13 +1044,18 @@ static int UNUSED_FUNCTION(bm_loop_length)(BMLoop *l)
|
|||||||
*
|
*
|
||||||
* BMESH_TODO: reinsert validation code.
|
* 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
|
* \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
|
#ifdef USE_BMESH_HOLES
|
||||||
, BMLoopList *lst
|
BMLoopList *lst,
|
||||||
#endif
|
#endif
|
||||||
)
|
const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef USE_BMESH_HOLES
|
#ifdef USE_BMESH_HOLES
|
||||||
@ -1060,7 +1065,6 @@ static bool bm_loop_reverse_loop(BMesh *bm, BMFace *f
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
const int len = f->len;
|
const int len = f->len;
|
||||||
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
|
|
||||||
BMLoop *l_iter, *oldprev, *oldnext;
|
BMLoop *l_iter, *oldprev, *oldnext;
|
||||||
BMEdge **edar = BLI_array_alloca(edar, len);
|
BMEdge **edar = BLI_array_alloca(edar, len);
|
||||||
int i, j, edok;
|
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_a[0], co_a[1]);
|
||||||
SWAP(float, co_b[0], co_b[1]);
|
SWAP(float, co_b[0], co_b[1]);
|
||||||
|
|
||||||
co_a[2] *= -1.0f;
|
if (use_loop_mdisp_flip) {
|
||||||
co_b[2] *= -1.0f;
|
co_a[2] *= -1.0f;
|
||||||
|
co_b[2] *= -1.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
co_a = co[x * sides + x];
|
co_a = co[x * sides + x];
|
||||||
|
|
||||||
SWAP(float, co_a[0], co_a[1]);
|
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
|
* \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
|
#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
|
#else
|
||||||
return bm_loop_reverse_loop(bm, f);
|
return bm_loop_reverse_loop(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,9 @@ void bmesh_vert_separate(
|
|||||||
BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
|
BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
|
||||||
const bool copy_select);
|
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);
|
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del);
|
||||||
void BM_vert_separate(
|
void BM_vert_separate(
|
||||||
|
@ -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);
|
BLI_assert(l_a && l_b);
|
||||||
|
|
||||||
if (l_a->v == l_b->v) {
|
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);
|
return BM_faces_join(bm, faces, 2, do_del);
|
||||||
|
@ -243,6 +243,7 @@ static BMOpDefine bmo_reverse_faces_def = {
|
|||||||
"reverse_faces",
|
"reverse_faces",
|
||||||
/* slots_in */
|
/* slots_in */
|
||||||
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
|
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
|
||||||
|
{"flip_multires", BMO_OP_SLOT_BOOL}, /* maintain multi-res offset */
|
||||||
{{'\0'}},
|
{{'\0'}},
|
||||||
},
|
},
|
||||||
{{{'\0'}}}, /* no output */
|
{{{'\0'}}}, /* no output */
|
||||||
|
@ -702,10 +702,18 @@ void BM_face_calc_center_mean_vcos(
|
|||||||
* Reverses the winding of a face.
|
* Reverses the winding of a face.
|
||||||
* \note This updates the calculated normal.
|
* \note This updates the calculated normal.
|
||||||
*/
|
*/
|
||||||
|
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, cd_loop_mdisp_offset, use_loop_mdisp_flip);
|
||||||
|
negate_v3(f->no);
|
||||||
|
}
|
||||||
|
|
||||||
void BM_face_normal_flip(BMesh *bm, BMFace *f)
|
void BM_face_normal_flip(BMesh *bm, BMFace *f)
|
||||||
{
|
{
|
||||||
bmesh_loop_reverse(bm, f);
|
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
|
||||||
negate_v3(f->no);
|
BM_face_normal_flip_ex(bm, f, cd_loop_mdisp_offset, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* detects if two line segments cross each other (intersects).
|
/* detects if two line segments cross each other (intersects).
|
||||||
|
@ -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(BMVert *v) ATTR_NONNULL();
|
||||||
void BM_vert_normal_update_all(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();
|
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();
|
bool BM_face_point_inside_test(const BMFace *f, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
|
||||||
|
|
||||||
|
@ -773,6 +773,7 @@ void bmo_solidify_face_region_exec(BMesh *bm, BMOperator *op)
|
|||||||
|
|
||||||
/* Flip original faces (so the shell is extruded inward) */
|
/* Flip original faces (so the shell is extruded inward) */
|
||||||
BMO_op_init(bm, &reverseop, op->flag, "reverse_faces");
|
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",
|
BMO_slot_copy(op, slots_in, "geom",
|
||||||
&reverseop, slots_in, "faces");
|
&reverseop, slots_in, "faces");
|
||||||
BMO_op_exec(bm, &reverseop);
|
BMO_op_exec(bm, &reverseop);
|
||||||
|
@ -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);
|
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");
|
BMO_op_callf(bm, op->flag, "reverse_faces faces=%S", &op_dupe, "geom.out");
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,11 +111,13 @@ void bmo_rotate_exec(BMesh *bm, BMOperator *op)
|
|||||||
|
|
||||||
void bmo_reverse_faces_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;
|
BMOIter siter;
|
||||||
BMFace *f;
|
BMFace *f;
|
||||||
|
|
||||||
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,8 +1470,12 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
|
|||||||
Object *obedit = CTX_data_edit_object(C);
|
Object *obedit = CTX_data_edit_object(C);
|
||||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
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;
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
EDBM_update_generic(em, true, false);
|
EDBM_update_generic(em, true, false);
|
||||||
|
|
||||||
@ -1639,8 +1643,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))
|
if (!EDBM_op_callf(em, op, "recalc_face_normals faces=%hf", BM_ELEM_SELECT))
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
|
|
||||||
if (RNA_boolean_get(op->ptr, "inside"))
|
if (RNA_boolean_get(op->ptr, "inside")) {
|
||||||
EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT);
|
EDBM_op_callf(em, op, "reverse_faces faces=%hf flip_multires=%b", BM_ELEM_SELECT, true);
|
||||||
|
}
|
||||||
|
|
||||||
EDBM_update_generic(em, true, false);
|
EDBM_update_generic(em, true, false);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user