Various fixes/improvements regarding BMesh's elem_index_dirty and BM_LOOP handling.
authorBastien Montagne <montagne29@wanadoo.fr>
Tue, 15 Apr 2014 14:18:27 +0000 (16:18 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Tue, 15 Apr 2014 14:20:07 +0000 (16:20 +0200)
Most notably, BM_LOOP and BM_FACE index recompute should now be fully decoupled.

source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/modifiers_bmesh.c
source/blender/bmesh/intern/bmesh_mesh.c
source/blender/bmesh/operators/bmo_removedoubles.c
source/blender/bmesh/tools/bmesh_decimate_collapse.c

index 176ef505a9a732e534bfa1358721393336aa24ca..b1bf1b4889fa9b91db6d3b2b08b65d16066763e9 100644 (file)
@@ -2162,6 +2162,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, const bool use_mdisps,
                        mloop->e = BM_elem_index_get(l_iter->e);
                        CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j);
 
+                       BM_elem_index_set(l_iter, j); /* set_inline */
+
                        j++;
                        mloop++;
                } while ((l_iter = l_iter->next) != l_first);
@@ -2170,7 +2172,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, const bool use_mdisps,
 
                if (add_orig) *index++ = i;
        }
-       bm->elem_index_dirty &= ~BM_FACE;
+       bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
 
        dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
 
index 13368be1acb3a2b0d40d670f71b0ad3e63893c15..3cb607730d4d25e10e3ac6df5e3722714028203e 100644 (file)
@@ -176,7 +176,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm, const bool calc_face_normal)
                l_iter = l_first = BM_FACE_FIRST_LOOP(f);
                do {
                        /* Save index of correspsonding MLoop */
-                       CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, j++, &l_iter->head.data, true);
+                       CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, j, &l_iter->head.data, true);
+                       BM_elem_index_set(l_iter, j++); /* set_inline */
                } while ((l_iter = l_iter->next) != l_first);
 
                CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true);
@@ -195,7 +196,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm, const bool calc_face_normal)
                        *orig_index = ORIGINDEX_NONE;
                }
        }
-       if (is_init) bm->elem_index_dirty &= ~BM_FACE;
+       if (is_init) bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
 
        MEM_freeN(vtable);
        MEM_freeN(etable);
index ee7dc8139d123cfcfd3b323bc6c0e66427707ee3..e7233535760c0e7f01c6af1920d0059420fe1c46 100644 (file)
@@ -451,10 +451,12 @@ static void bm_mesh_edges_sharp_tag(BMesh *bm, const float (*vnos)[3], const flo
 
        {
                char hflag = BM_LOOP;
-               if (vnos)
+               if (vnos) {
                        hflag |= BM_VERT;
-               if (fnos)
+               }
+               if (fnos) {
                        hflag |= BM_FACE;
+               }
                BM_mesh_elem_index_ensure(bm, hflag);
        }
 
@@ -508,10 +510,12 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
 
        {
                char hflag = BM_LOOP;
-               if (vcos)
+               if (vcos) {
                        hflag |= BM_VERT;
-               if (fnos)
+               }
+               if (fnos) {
                        hflag |= BM_FACE;
+               }
                BM_mesh_elem_index_ensure(bm, hflag);
        }
 
@@ -822,27 +826,31 @@ void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag)
                                        BMIter iter;
                                        BMElem *ele;
 
-                                       const bool hflag_loop = (hflag & BM_LOOP) && (bm->elem_index_dirty & BM_LOOP);
+                                       const bool update_face = (hflag & BM_FACE) && (bm->elem_index_dirty & BM_FACE);
+                                       const bool update_loop = (hflag & BM_LOOP) && (bm->elem_index_dirty & BM_LOOP);
 
                                        int index;
-                                       int index_loop_start = 0;
+                                       int index_loop = 0;
+
                                        BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, index) {
-                                               BM_elem_index_set(ele, index); /* set_ok */
+                                               if (update_face) {
+                                                       BM_elem_index_set(ele, index); /* set_ok */
+                                               }
 
-                                               if (hflag_loop) {
-                                                       BMIter liter;
-                                                       BMElem *lele;
+                                               if (update_loop) {
+                                                       BMLoop *l_iter, *l_first;
 
-                                                       int index_diff;
-                                                       BM_ITER_ELEM_INDEX (lele, &liter, ele, BM_LOOPS_OF_FACE, index_diff) {
-                                                               BM_elem_index_set(lele, index_loop_start + index_diff); /* set_ok */
-                                                       }
-                                                       index_loop_start += index_diff;
+                                                       l_iter = l_first = BM_FACE_FIRST_LOOP((BMFace *)ele);
+                                                       do {
+                                                               BM_elem_index_set(l_iter, index_loop++); /* set_ok */
+                                                       } while ((l_iter = l_iter->next) != l_first);
                                                }
                                        }
+
                                        BLI_assert(index == bm->totface);
-                                       if (hflag & BM_LOOP)
-                                               BLI_assert(index_loop_start == bm->totloop);
+                                       if (update_loop) {
+                                               BLI_assert(index_loop == bm->totloop);
+                                       }
                                }
                                else {
                                        // printf("%s: skipping face/loop index calc!\n", __func__);
index cef7c70d52031df6cdc5e5ebea0e87c148418018..216d3410de858573e3ce01735c2c7ec31a3026fc 100644 (file)
@@ -219,7 +219,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
                        }
                }
        }
-       bm->elem_index_dirty |= BM_FACE;
+       bm->elem_index_dirty |= BM_FACE | BM_LOOP;
 
        /* faces get "modified" by creating new faces here, then at the
         * end the old faces are deleted */
index ef628a1060775b2b51adbd839c6f06723bc7f779..1e9d8e9ee9d610dfd398477280a07b5a1d51f6af 100644 (file)
@@ -1006,7 +1006,7 @@ void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, c
        bm_decim_build_edge_cost(bm, vquadrics, vweights, eheap, eheap_table);
 
        face_tot_target = bm->totface * factor;
-       bm->elem_index_dirty |= BM_FACE | BM_LOOP | BM_EDGE | BM_VERT;
+       bm->elem_index_dirty |= BM_ALL;
 
 
 #ifdef USE_CUSTOMDATA