diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2014-05-22 00:35:08 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2014-05-22 00:37:50 +0400 |
commit | a217db0d6373a4050658049a9ded84f34b33f952 (patch) | |
tree | 18a2c2befaaf38f0d4ab40e1a8b96a45e71bf067 /source | |
parent | 8d297394ba51246f2db0d503df7f4cae19ca6e92 (diff) |
Fix T40297: Crash while ripping an edge when autosmooth is activated.
Turned out there was still quite a few cases were indices were set dirty,
but elem_index_dirty was not tagged accordingly (mostly for BM_LOOP,
but a few others as well). So probably this crash was not the only one
hidden here.
Hopefully all possible cases were catched this time!
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 10 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_edgeloop.c | 4 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_inline.h | 3 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 10 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.h | 2 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_connect.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_connect_nonplanar.c | 6 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_inset.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_subdivide.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_decimate_collapse.c | 8 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_wireframe.c | 3 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_rip.c | 7 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 1 |
14 files changed, 38 insertions, 25 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 1f81b59badc..6a13a99999c 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -198,7 +198,13 @@ static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, /* --- assign all members --- */ l->head.data = NULL; - BM_elem_index_set(l, 0); /* set_loop */ + +#ifdef USE_DEBUG_INDEX_MEMCHECK + DEBUG_MEMCHECK_INDEX_INVALIDATE(l) +#else + BM_elem_index_set(l, -1); /* set_ok_invalid */ +#endif + l->head.hflag = 0; l->head.htype = BM_LOOP; l->head.api_flag = 0; @@ -1927,7 +1933,7 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) BLI_mempool_free(bm->fpool, f2); bm->totface--; /* account for both above */ - bm->elem_index_dirty |= BM_EDGE | BM_FACE; + bm->elem_index_dirty |= BM_EDGE | BM_LOOP | BM_FACE; BM_CHECK_ELEMENT(f1); diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c index bbf4b661a1b..c8a954ab6a3 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.c +++ b/source/blender/bmesh/intern/bmesh_edgeloop.c @@ -189,7 +189,7 @@ static void vs_add(BLI_mempool *vs_pool, ListBase *lb, struct VertStep *vs_new = BLI_mempool_alloc(vs_pool); vs_new->v = v; - BM_elem_index_set(v, iter_tot); + BM_elem_index_set(v, iter_tot); /* set_dirty */ /* This edge stores a direct path back to the original vertex so we can * backtrack without having to store an array of previous verts. */ @@ -248,6 +248,7 @@ static bool bm_loop_path_build_step(BLI_mempool *vs_pool, ListBase *lb, const in BLI_mempool_free(vs_pool, vs); } + /* bm->elem_index_dirty |= BM_VERT; */ /* Commented because used in a loop, and this flag has already been set. */ /* lb is now full of free'd items, overwrite */ *lb = lb_tmp; @@ -303,6 +304,7 @@ bool BM_mesh_edgeloops_find_path(BMesh *bm, ListBase *r_eloops, /* edge args are dummy */ vs_add(vs_pool, &lb_src, v_src, v_src->e, 1); vs_add(vs_pool, &lb_dst, v_dst, v_dst->e, -1); + bm->elem_index_dirty |= BM_VERT; do { if ((bm_loop_path_build_step(vs_pool, &lb_src, 1, v_match) == false) || v_match[0]) { diff --git a/source/blender/bmesh/intern/bmesh_inline.h b/source/blender/bmesh/intern/bmesh_inline.h index 5ac6d7da61b..96b2cd396a2 100644 --- a/source/blender/bmesh/intern/bmesh_inline.h +++ b/source/blender/bmesh/intern/bmesh_inline.h @@ -106,9 +106,6 @@ BLI_INLINE void _bm_elem_flag_merge_into(BMHeader *head, const BMHeader *head_a, * adding new vert/edge/faces since they may be added at * the end of the array. * - * - 'set_loop' -- currently loop index values are not used used much so - * assume each case they are dirty. - * * - campbell */ #define BM_elem_index_get(ele) _bm_elem_index_get(&(ele)->head) diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index ed12c641014..4065ba33ee1 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -935,7 +935,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, #endif if (FACE_USED_TEST(f_a) == false) { - FACE_USED_SET(f_a); + FACE_USED_SET(f_a); /* set_dirty */ if (nf_i < edge_array_len) { r_faces_new[nf_i++] = f_a; @@ -947,7 +947,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, } if (FACE_USED_TEST(f_b) == false) { - FACE_USED_SET(f_b); + FACE_USED_SET(f_b); /* set_dirty */ if (nf_i < edge_array_len) { r_faces_new[nf_i++] = f_b; @@ -972,6 +972,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, } } } + bm->elem_index_dirty |= BM_FACE; if (r_faces_new_tot) { *r_faces_new_tot = nf_i; @@ -986,7 +987,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, * intersecting splits, only the first of the set of intersecting * splits survives */ -void BM_face_splits_check_legal(BMFace *f, BMLoop *(*loops)[2], int len) +void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) { const int len2 = len * 2; BMLoop *l; @@ -1003,9 +1004,10 @@ void BM_face_splits_check_legal(BMFace *f, BMLoop *(*loops)[2], int len) axis_dominant_v3_to_m3(axis_mat, f->no); for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) { - BM_elem_index_set(l, i); /* set_loop */ + BM_elem_index_set(l, i); /* set_dirty */ mul_v2_m3v3(projverts[i], axis_mat, l->v->co); } + bm->elem_index_dirty |= BM_LOOP; /* first test for completely convex face */ if (is_poly_convex_v2((const float (*)[2])projverts, f->len)) { diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index d903b77ecf8..bc0e7e832c8 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -62,7 +62,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, const int quad_method, const int ngon_method, const bool use_tag) ATTR_NONNULL(1, 2); -void BM_face_splits_check_legal(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL(); +void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL(); void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL(); void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3]) ATTR_NONNULL(); diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index c98777d87a8..5a00401b3c7 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -86,7 +86,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f, const bool check_degenera } if (check_degenerate) { - BM_face_splits_check_legal(f, loops_split, STACK_SIZE(loops_split)); + BM_face_splits_check_legal(bm, f, loops_split, STACK_SIZE(loops_split)); } else { BM_face_splits_check_optimal(f, loops_split, STACK_SIZE(loops_split)); diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c index be325fc9adc..6859ce2060c 100644 --- a/source/blender/bmesh/operators/bmo_connect_nonplanar.c +++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c @@ -63,7 +63,7 @@ static float bm_face_subset_calc_planar(BMLoop *l_first, BMLoop *l_last, const f return delta_z; } -static bool bm_face_split_find(BMFace *f, BMLoop *l_pair[2], float *r_angle) +static bool bm_face_split_find(BMesh *bm, BMFace *f, BMLoop *l_pair[2], float *r_angle) { BMLoop *l_iter, *l_first; BMLoop **l_arr = BLI_array_alloca(l_arr, f->len); @@ -102,7 +102,7 @@ static bool bm_face_split_find(BMFace *f, BMLoop *l_pair[2], float *r_angle) if (err_test < err_best) { /* check we're legal (we could batch this) */ BMLoop *l_split[2] = {l_a, l_b}; - BM_face_splits_check_legal(f, &l_split, 1); + BM_face_splits_check_legal(bm, f, &l_split, 1); if (l_split[0]) { err_best = err_test; l_pair[0] = l_a; @@ -129,7 +129,7 @@ static bool bm_face_split_by_angle(BMesh *bm, BMFace *f, BMFace *r_f_pair[2], co BMLoop *l_pair[2]; float angle; - if (bm_face_split_find(f, l_pair, &angle) && (angle > angle_limit)) { + if (bm_face_split_find(bm, f, l_pair, &angle) && (angle > angle_limit)) { BMFace *f_new; BMLoop *l_new; diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index cb4255d337e..0ca4ddf8d55 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -90,8 +90,9 @@ static void bm_interp_face_store(InterpFace *iface, BMesh *bm, BMFace *f, MemAre CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, l_iter->v->head.data, &blocks_v[i]); /* use later for index lookups */ - BM_elem_index_set(l_iter, i); /* set_ok */ + BM_elem_index_set(l_iter, i); /* set_dirty */ } while (i++, (l_iter = l_iter->next) != l_first); + bm->elem_index_dirty |= BM_LOOP; } static void bm_interp_face_free(InterpFace *iface, BMesh *bm) { diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index c9b35e895aa..0730c287eaa 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -1113,7 +1113,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) * - concave corner of an ngon. * - 2 edges being used in 2+ ngons. */ -// BM_face_splits_check_legal(face, loops_split, BLI_array_count(loops_split)); +// BM_face_splits_check_legal(bm, face, loops_split, BLI_array_count(loops_split)); for (j = 0; j < BLI_array_count(loops_split); j++) { if (loops_split[j][0]) { diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index f614c43193a..4b6209fc4eb 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -312,12 +312,14 @@ static bool bm_decim_triangulate_begin(BMesh *bm) l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - BM_elem_index_set(l_iter, -1); + BM_elem_index_set(l_iter, -1); /* set_dirty */ } while ((l_iter = l_iter->next) != l_first); // has_quad |= (f->len == 4) } + bm->elem_index_dirty |= BM_LOOP; + /* adding new faces as we loop over faces * is normally best avoided, however in this case its not so bad because any face touched twice * will already be triangulated*/ @@ -366,8 +368,8 @@ static bool bm_decim_triangulate_begin(BMesh *bm) /* since we just split theres only ever 2 loops */ BLI_assert(BM_edge_is_manifold(l_new->e)); - BM_elem_index_set(l_new, f_index); - BM_elem_index_set(l_new->radial_next, f_index); + BM_elem_index_set(l_new, f_index); /* set_dirty */ + BM_elem_index_set(l_new->radial_next, f_index); /* set_dirty */ BM_face_normal_update(f); BM_face_normal_update(f_new); diff --git a/source/blender/bmesh/tools/bmesh_wireframe.c b/source/blender/bmesh/tools/bmesh_wireframe.c index 0860dab0d66..e2ce31d15b9 100644 --- a/source/blender/bmesh/tools/bmesh_wireframe.c +++ b/source/blender/bmesh/tools/bmesh_wireframe.c @@ -334,7 +334,7 @@ void BM_mesh_wireframe( } BM_ITER_ELEM (l, &itersub, f_src, BM_LOOPS_OF_FACE) { - BM_elem_index_set(l, verts_loop_tot); /* set_loop */ + BM_elem_index_set(l, verts_loop_tot); /* set_dirty */ /* Because some faces might be skipped! */ BM_loop_calc_face_tangent(l, tvec); @@ -407,6 +407,7 @@ void BM_mesh_wireframe( verts_loop_tot++; } } + bm->elem_index_dirty |= BM_LOOP; BM_ITER_MESH (f_src, &iter, bm, BM_FACES_OF_MESH) { diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 84952297235..58701e776b7 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -217,8 +217,8 @@ static BMEdge *edbm_ripsel_edge_mark_step(BMVert *v, const int uid) BM_edge_loop_pair(e, &l_a, &l_b); /* no need to check, we know this will be true */ /* so (IS_VISIT_DONE == true) */ - BM_elem_index_set(l_a, uid); - BM_elem_index_set(l_b, uid); + BM_elem_index_set(l_a, uid); /* set_dirty */ + BM_elem_index_set(l_b, uid); /* set_dirty */ return e; } @@ -250,9 +250,10 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm) /* initialize loops with dummy invalid index values */ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BM_elem_index_set(l, INVALID_UID); + BM_elem_index_set(l, INVALID_UID); /* set_dirty */ } } + bm->elem_index_dirty |= BM_LOOP; /* set contiguous loops ordered 'uid' values for walking after split */ while (true) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 159eac4a275..8672a479ab5 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2460,7 +2460,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK) { copy_v2_fl(*sco, FLT_MAX); /* set error value */ } - BM_elem_index_set(bv, i); /* set_ok */ + BM_elem_index_set(bv, i); /* set_inline */ sco++; } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 7f6ea9b7982..ac52cf6b53f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1889,6 +1889,7 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float dists[i] = 0.0f; } } + bm->elem_index_dirty &= ~BM_VERT; } do { |