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!
This commit is contained in:
parent
8d297394ba
commit
a217db0d63
Notes:
blender-bot
2023-02-14 10:36:38 +01:00
Referenced by issue #40297, Crash while ripping an edge when autosmooth is activated.
|
@ -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);
|
||||
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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++;
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue