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:
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c60
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h3
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c11
-rw-r--r--source/blender/editors/transform/transform.c2
4 files changed, 53 insertions, 23 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index dc42d86d800..09a39c05565 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1395,32 +1395,49 @@ void BM_lnorspace_err(BMesh *bm)
static void bm_loop_normal_mark_indiv_do_loop(BMLoop *l,
BLI_bitmap *loops,
MLoopNorSpaceArray *lnor_spacearr,
- int *totloopsel)
+ int *totloopsel,
+ const bool do_all_loops_of_vert)
{
if (l != NULL) {
const int l_idx = BM_elem_index_get(l);
- if (!BLI_BITMAP_TEST(loops, BM_elem_index_get(l))) {
+ if (!BLI_BITMAP_TEST(loops, l_idx)) {
/* If vert and face selected share a loop, mark it for editing. */
BLI_BITMAP_ENABLE(loops, l_idx);
(*totloopsel)++;
- /* Mark all loops in same loop normal space (aka smooth fan). */
- if ((lnor_spacearr->lspacearr[l_idx]->flags & MLNOR_SPACE_IS_SINGLE) == 0) {
- for (LinkNode *node = lnor_spacearr->lspacearr[l_idx]->loops; node; node = node->next) {
- const int lfan_idx = BM_elem_index_get((BMLoop *)node->link);
+ if (do_all_loops_of_vert) {
+ /* If required, also mark all loops shared by that vertex.
+ * This is needed when loop spaces may change
+ * (i.e. when some faces or edges might change of smooth/sharp status). */
+ BMIter liter;
+ BMLoop *lfan;
+ BM_ITER_ELEM (lfan, &liter, l->v, BM_LOOPS_OF_VERT) {
+ const int lfan_idx = BM_elem_index_get(lfan);
if (!BLI_BITMAP_TEST(loops, lfan_idx)) {
BLI_BITMAP_ENABLE(loops, lfan_idx);
(*totloopsel)++;
}
}
}
+ else {
+ /* Mark all loops in same loop normal space (aka smooth fan). */
+ if ((lnor_spacearr->lspacearr[l_idx]->flags & MLNOR_SPACE_IS_SINGLE) == 0) {
+ for (LinkNode *node = lnor_spacearr->lspacearr[l_idx]->loops; node; node = node->next) {
+ const int lfan_idx = BM_elem_index_get((BMLoop *)node->link);
+ if (!BLI_BITMAP_TEST(loops, lfan_idx)) {
+ BLI_BITMAP_ENABLE(loops, lfan_idx);
+ (*totloopsel)++;
+ }
+ }
+ }
+ }
}
}
}
/* Mark the individual clnors to be edited, if multiple selection methods are used. */
-static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
+static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops, const bool do_all_loops_of_vert)
{
BMEditSelection *ese, *ese_prev;
int totloopsel = 0;
@@ -1451,19 +1468,22 @@ static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
BM_face_vert_share_loop((BMFace *)ese->ele, (BMVert *)ese_prev->ele),
loops,
bm->lnor_spacearr,
- &totloopsel);
+ &totloopsel,
+ do_all_loops_of_vert);
}
else if (ese_prev->htype == BM_EDGE) {
BMEdge *e = (BMEdge *)ese_prev->ele;
bm_loop_normal_mark_indiv_do_loop(BM_face_vert_share_loop((BMFace *)ese->ele, e->v1),
loops,
bm->lnor_spacearr,
- &totloopsel);
+ &totloopsel,
+ do_all_loops_of_vert);
bm_loop_normal_mark_indiv_do_loop(BM_face_vert_share_loop((BMFace *)ese->ele, e->v2),
loops,
bm->lnor_spacearr,
- &totloopsel);
+ &totloopsel,
+ do_all_loops_of_vert);
}
}
}
@@ -1478,7 +1498,8 @@ static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
+ bm_loop_normal_mark_indiv_do_loop(
+ l, loops, bm->lnor_spacearr, &totloopsel, do_all_loops_of_vert);
}
}
}
@@ -1491,15 +1512,18 @@ static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
- bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
+ bm_loop_normal_mark_indiv_do_loop(
+ l, loops, bm->lnor_spacearr, &totloopsel, do_all_loops_of_vert);
/* Loops actually 'have' two edges, or said otherwise, a selected edge actually selects
* *two* loops in each of its faces. We have to find the other one too. */
if (BM_vert_in_edge(e, l->next->v)) {
- bm_loop_normal_mark_indiv_do_loop(l->next, loops, bm->lnor_spacearr, &totloopsel);
+ bm_loop_normal_mark_indiv_do_loop(
+ l->next, loops, bm->lnor_spacearr, &totloopsel, do_all_loops_of_vert);
}
else {
BLI_assert(BM_vert_in_edge(e, l->prev->v));
- bm_loop_normal_mark_indiv_do_loop(l->prev, loops, bm->lnor_spacearr, &totloopsel);
+ bm_loop_normal_mark_indiv_do_loop(
+ l->prev, loops, bm->lnor_spacearr, &totloopsel, do_all_loops_of_vert);
}
}
}
@@ -1513,7 +1537,8 @@ static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
- bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
+ bm_loop_normal_mark_indiv_do_loop(
+ l, loops, bm->lnor_spacearr, &totloopsel, do_all_loops_of_vert);
}
}
}
@@ -1546,7 +1571,8 @@ static void loop_normal_editdata_init(
lnor_ed->loc = v->co;
}
-BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm)
+BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm,
+ const bool do_all_loops_of_vert)
{
BMLoop *l;
BMVert *v;
@@ -1570,7 +1596,7 @@ BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm)
BLI_bitmap *loops = BLI_BITMAP_NEW(bm->totloop, __func__);
/* This function define loop normals to edit, based on selection modes and history. */
- totloopsel = bm_loop_normal_mark_indiv(bm, loops);
+ totloopsel = bm_loop_normal_mark_indiv(bm, loops, do_all_loops_of_vert);
if (totloopsel) {
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata = MEM_mallocN(
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index d0cf50a7894..83575552acc 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -67,7 +67,8 @@ void BM_lnorspace_err(BMesh *bm);
#endif
/* Loop Generics */
-struct BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm);
+struct BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm,
+ const bool do_all_loops_of_vert);
void BM_loop_normal_editdata_array_free(struct BMLoopNorEditDataArray *lnors_ed_arr);
int BM_total_loop_select(BMesh *bm);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index c4216d81317..c196a66332d 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -7689,7 +7689,7 @@ static int point_normals_init(bContext *C, wmOperator *op, const wmEvent *UNUSED
BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
- BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
op->customdata = lnors_ed_arr;
@@ -8246,7 +8246,10 @@ static int normals_split_merge(bContext *C, const bool do_merge)
BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
- BMLoopNorEditDataArray *lnors_ed_arr = do_merge ? BM_loop_normal_editdata_array_init(bm) : NULL;
+ /* Note that we need temp lnor editing data for all loops of all affected vertices, since by
+ * setting some faces/edges as smooth we are going to change clnors spaces... See also T65809. */
+ BMLoopNorEditDataArray *lnors_ed_arr = do_merge ? BM_loop_normal_editdata_array_init(bm, true) :
+ NULL;
mesh_set_smooth_faces(em, do_merge);
@@ -8573,7 +8576,7 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op)
BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
- BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
float *normal_vector = scene->toolsettings->normal_vector;
@@ -8867,7 +8870,7 @@ static int edbm_smoothen_normals_exec(bContext *C, wmOperator *op)
BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
- BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
float(*smooth_normal)[3] = MEM_callocN(sizeof(*smooth_normal) * lnors_ed_arr->totloop, __func__);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 9019b21997f..5b3f7d85b43 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4784,7 +4784,7 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm)
{
- BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
+ BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm, false);
// BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
tc->custom.mode.data = lnors_ed_arr;