Edit Mesh: skip flipping custom normals for meshes with no selection
Also split out normal calculation into functions.
This commit is contained in:
@@ -2183,6 +2183,61 @@ static bool flip_custom_normals(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr)
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Flip Normals Operator
|
||||
* \{ */
|
||||
|
||||
static void edbm_flip_normals_custom_loop_normals(Object *obedit, BMEditMesh *em)
|
||||
{
|
||||
if (!CustomData_has_layer(&em->bm->ldata, CD_CUSTOMLOOPNORMAL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The mesh has custom normal data, flip them. */
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
BM_lnorspace_update(bm);
|
||||
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
|
||||
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
|
||||
|
||||
for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
|
||||
negate_v3(lnor_ed->nloc);
|
||||
|
||||
BKE_lnor_space_custom_normal_to_data(
|
||||
bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data);
|
||||
}
|
||||
BM_loop_normal_editdata_array_free(lnors_ed_arr);
|
||||
EDBM_update(obedit->data,
|
||||
&(const struct EDBMUpdate_Params){
|
||||
.calc_looptri = true,
|
||||
.calc_normals = false,
|
||||
.is_destructive = false,
|
||||
});
|
||||
}
|
||||
|
||||
static void edbm_flip_normals_face_winding(wmOperator *op, Object *obedit, BMEditMesh *em)
|
||||
{
|
||||
|
||||
bool has_flipped_faces = false;
|
||||
|
||||
/* See if we have any custom normals to flip. */
|
||||
BMLoopNorEditDataArray *lnors_ed_arr = flip_custom_normals_init_data(em->bm);
|
||||
|
||||
if (EDBM_op_callf(em, op, "reverse_faces faces=%hf flip_multires=%b", BM_ELEM_SELECT, true)) {
|
||||
has_flipped_faces = true;
|
||||
}
|
||||
|
||||
if (flip_custom_normals(em->bm, lnors_ed_arr) || has_flipped_faces) {
|
||||
EDBM_update(obedit->data,
|
||||
&(const struct EDBMUpdate_Params){
|
||||
.calc_looptri = true,
|
||||
.calc_normals = false,
|
||||
.is_destructive = false,
|
||||
});
|
||||
}
|
||||
|
||||
if (lnors_ed_arr != NULL) {
|
||||
BM_loop_normal_editdata_array_free(lnors_ed_arr);
|
||||
}
|
||||
}
|
||||
|
||||
static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool only_clnors = RNA_boolean_get(op->ptr, "only_clnors");
|
||||
@@ -2197,56 +2252,16 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
if (only_clnors) {
|
||||
if (CustomData_has_layer(&em->bm->ldata, CD_CUSTOMLOOPNORMAL)) {
|
||||
/* The mesh has custom normal data, flip them. */
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
BM_lnorspace_update(bm);
|
||||
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
|
||||
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
|
||||
|
||||
for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
|
||||
negate_v3(lnor_ed->nloc);
|
||||
|
||||
BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[lnor_ed->loop_index],
|
||||
lnor_ed->nloc,
|
||||
lnor_ed->clnors_data);
|
||||
}
|
||||
BM_loop_normal_editdata_array_free(lnors_ed_arr);
|
||||
EDBM_update(obedit->data,
|
||||
&(const struct EDBMUpdate_Params){
|
||||
.calc_looptri = true,
|
||||
.calc_normals = false,
|
||||
.is_destructive = false,
|
||||
});
|
||||
if ((em->bm->totvertsel == 0) && (em->bm->totedgesel == 0) && (em->bm->totfacesel == 0)) {
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
edbm_flip_normals_custom_loop_normals(obedit, em);
|
||||
}
|
||||
|
||||
if (em->bm->totfacesel == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool has_flipped_faces = false;
|
||||
|
||||
/* See if we have any custom normals to flip. */
|
||||
BMLoopNorEditDataArray *lnors_ed_arr = flip_custom_normals_init_data(em->bm);
|
||||
|
||||
if (EDBM_op_callf(em, op, "reverse_faces faces=%hf flip_multires=%b", BM_ELEM_SELECT, true)) {
|
||||
has_flipped_faces = true;
|
||||
}
|
||||
|
||||
if (flip_custom_normals(em->bm, lnors_ed_arr) || has_flipped_faces) {
|
||||
EDBM_update(obedit->data,
|
||||
&(const struct EDBMUpdate_Params){
|
||||
.calc_looptri = true,
|
||||
.calc_normals = false,
|
||||
.is_destructive = false,
|
||||
});
|
||||
}
|
||||
|
||||
if (lnors_ed_arr != NULL) {
|
||||
BM_loop_normal_editdata_array_free(lnors_ed_arr);
|
||||
else {
|
||||
if (em->bm->totfacesel == 0) {
|
||||
continue;
|
||||
}
|
||||
edbm_flip_normals_face_winding(op, obedit, em);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user