diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-10-24 13:19:48 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-10-24 13:19:48 +0300 |
commit | 7ea7fd45d0fffed5cc67769a9fe050ae6a574554 (patch) | |
tree | 032b450cf6ee9d9a40c8f307305df1eff350266e /source/blender | |
parent | f5456df095291c6cb2d0223a179746c8e514cd15 (diff) | |
parent | e03df90bf36f907a99ebd8cba6cf03cf05ca71a3 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/bmesh/bmesh_class.h | 6 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 38 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_edgeloop.c | 74 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_interp.c | 11 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon_edgenet.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 9 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_split_edges.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_select.c | 9 | ||||
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_types.c | 10 |
9 files changed, 120 insertions, 41 deletions
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 64a5cad812a..bec2c7a1f45 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -341,9 +341,9 @@ enum { /* spare tag, assumed dirty, use define in each function to name based on use */ // _BM_ELEM_TAG_ALT = (1 << 6), // UNUSED /** - * for low level internal API tagging, - * since tools may want to tag verts and - * not have functions clobber them */ + * For low level internal API tagging, + * since tools may want to tag verts and not have functions clobber them. + * Leave cleared! */ BM_ELEM_INTERNAL_TAG = (1 << 7), }; diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index c7ff93cf504..36b2f9cadf7 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -2090,25 +2090,33 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd } /* validate no internal join */ - for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) { - BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG); - } - for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) { - BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG); - } + { + bool is_dupe = false; - for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) { - if (l_iter != l_f1) { - BM_elem_flag_enable(l_iter->v, BM_ELEM_INTERNAL_TAG); + /* TODO: skip clearing once this is ensured. */ + for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) { + BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG); } - } - for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) { - if (l_iter != l_f2) { - /* as soon as a duplicate is found, bail out */ - if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) { - return NULL; + + for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) { + BM_elem_flag_set(l_iter->v, BM_ELEM_INTERNAL_TAG, l_iter != l_f1); + } + for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) { + if (l_iter != l_f2) { + /* as soon as a duplicate is found, bail out */ + if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) { + is_dupe = true; + break; + } } } + /* Cleanup tags. */ + for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) { + BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG); + } + if (is_dupe) { + return NULL; + } } /* join the two loop */ diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c index b3b23933d2f..9d51b59825d 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.c +++ b/source/blender/bmesh/intern/bmesh_edgeloop.c @@ -33,6 +33,7 @@ #include "BLI_listbase.h" #include "BLI_mempool.h" #include "BLI_utildefines_iter.h" +#include "BLI_stack.h" #include "bmesh.h" @@ -141,28 +142,36 @@ int BM_mesh_edgeloops_find( } /* first flush edges to tags, and tag verts */ + BLI_Stack *edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__); BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BLI_assert(!BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)); if (test_fn(e, user_data)) { BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG); BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG); + BLI_stack_push(edge_stack, (void *)&e); } else { BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); } } - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + const uint edges_len = BLI_stack_count(edge_stack); + BMEdge **edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__); + BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack)); + BLI_stack_free(edge_stack); + + for (uint i = 0; i < edges_len; i += 1) { + e = edges[i]; if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) { BMEdgeLoopStore *el_store = MEM_callocN(sizeof(BMEdgeLoopStore), __func__); /* add both directions */ if (bm_loop_build(el_store, e->v1, e->v2, 1) && - bm_loop_build(el_store, e->v2, e->v1, -1) && - el_store->len > 1) + bm_loop_build(el_store, e->v2, e->v1, -1) && + el_store->len > 1) { BLI_addtail(r_eloops, el_store); - BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); count++; } else { @@ -170,6 +179,15 @@ int BM_mesh_edgeloops_find( } } } + + for (uint i = 0; i < edges_len; i += 1) { + e = edges[i]; + BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); + BM_elem_flag_disable(e->v1, BM_ELEM_INTERNAL_TAG); + BM_elem_flag_disable(e->v2, BM_ELEM_INTERNAL_TAG); + } + + MEM_freeN(edges); return count; } @@ -267,6 +285,7 @@ bool BM_mesh_edgeloops_find_path( { BMIter iter; BMEdge *e; + bool found = false; BLI_assert(v_src != v_dst); @@ -274,28 +293,43 @@ bool BM_mesh_edgeloops_find_path( BMVert *v; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { BM_elem_index_set(v, 0); + BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG); } } bm->elem_index_dirty |= BM_VERT; /* first flush edges to tags, and tag verts */ + int edges_len; + BMEdge **edges; + if (test_fn) { + BLI_Stack *edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__); BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (test_fn(e, user_data)) { BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG); BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG); + BLI_stack_push(edge_stack, (void *)&e); } else { BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); } } + edges_len = BLI_stack_count(edge_stack); + edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__); + BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack)); + BLI_stack_free(edge_stack); } else { - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + int i = 0; + edges_len = bm->totedge; + edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__); + + BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) { BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG); BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG); + edges[i] = e; } } @@ -354,11 +388,19 @@ bool BM_mesh_edgeloops_find_path( BLI_addtail(r_eloops, el_store); - return true; + found = true; } } - return false; + for (uint i = 0; i < edges_len; i += 1) { + e = edges[i]; + BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); + BM_elem_flag_disable(e->v1, BM_ELEM_INTERNAL_TAG); + BM_elem_flag_disable(e->v2, BM_ELEM_INTERNAL_TAG); + } + MEM_freeN(edges); + + return found; } @@ -753,19 +795,29 @@ bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a, struct BMEdge { LinkData *node; + /* A little more efficient if 'a' as smaller. */ + if (el_store_a->len > el_store_b->len) { + SWAP(BMEdgeLoopStore *, el_store_a, el_store_b); + } + /* init */ for (node = el_store_a->verts.first; node; node = node->next) { - BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG); + BM_elem_flag_enable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG); } for (node = el_store_b->verts.first; node; node = node->next) { - BM_elem_flag_enable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG); + BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG); } - /* check 'a' */ + /* Check 'a' (clear as we go). */ for (node = el_store_a->verts.first; node; node = node->next) { - if (BM_elem_flag_test((BMVert *)node->data, BM_ELEM_INTERNAL_TAG)) { + if (!BM_elem_flag_test((BMVert *)node->data, BM_ELEM_INTERNAL_TAG)) { + /* Finish clearing 'a', leave tag clean. */ + while ((node = node->next)) { + BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG); + } return true; } + BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG); } return false; } diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 20ee31251e8..00f8eb6df40 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -957,7 +957,7 @@ static void bm_loop_walk_add(struct LoopWalkCtx *lwc, BMLoop *l) { const int i = BM_elem_index_get(l); const float w = lwc->loop_weights[i]; - BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG); + BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG); lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, lwc->cd_layer_offset); lwc->data_index_array[lwc->data_len] = i; lwc->weight_array[lwc->data_len] = w; @@ -976,7 +976,7 @@ static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk) int i; BLI_assert(CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset))); - BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG) == false); + BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG)); bm_loop_walk_add(lwc, l_walk); @@ -988,7 +988,7 @@ static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk) l_other = l_other->next; } BLI_assert(l_other->v == l_walk->v); - if (!BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) { + if (BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) { if (CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset))) { bm_loop_walk_data(lwc, l_other); } @@ -1012,9 +1012,10 @@ LinkNode *BM_vert_loop_groups_data_layer_create( lwc.loop_weights = loop_weights; lwc.arena = arena; + /* Enable 'BM_ELEM_INTERNAL_TAG', leaving the flag clean on completion. */ loop_num = 0; BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG); + BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG); BM_elem_index_set(l, loop_num); /* set_dirty! */ loop_num++; } @@ -1026,7 +1027,7 @@ LinkNode *BM_vert_loop_groups_data_layer_create( lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num); BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - if (!BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) { + if (BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) { struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf)); int len_prev = lwc.data_len; diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c index 8a3cb329610..41775bdf2d0 100644 --- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c +++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c @@ -1236,6 +1236,8 @@ bool BM_face_split_edgenet_connect_islands( BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { + BLI_assert(!BM_elem_flag_test(l_iter->v, VERT_NOT_IN_STACK)); + BLI_assert(!BM_elem_flag_test(l_iter->e, EDGE_NOT_IN_STACK)); edge_arr[i++] = l_iter->e; } while ((l_iter = l_iter->next) != l_first); BLI_assert(i == edge_arr_len); diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 5bdc3927e16..1f944238999 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -2108,7 +2108,8 @@ bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len) if (tot_tag == 0) { /* no faces use only boundary verts, quit early */ - return false; + ok = false; + goto finally; } /* 2) loop over non-boundary edges that use boundary verts, @@ -2143,6 +2144,12 @@ bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len) } } +finally: + /* Cleanup */ + for (i = 0; i < len; i++) { + BM_elem_flag_disable(varr[i], BM_ELEM_INTERNAL_TAG); + BM_elem_flag_disable(earr[i], BM_ELEM_INTERNAL_TAG); + } return ok; } diff --git a/source/blender/bmesh/operators/bmo_split_edges.c b/source/blender/bmesh/operators/bmo_split_edges.c index eb7946caff0..f67a9e38fcc 100644 --- a/source/blender/bmesh/operators/bmo_split_edges.c +++ b/source/blender/bmesh/operators/bmo_split_edges.c @@ -50,5 +50,5 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) /* this is where everything happens */ BM_mesh_edgesplit(bm, use_verts, true, false); - BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG); + BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); } diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 68982275c79..1683fbdbdb9 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -1085,6 +1085,8 @@ typedef struct tNearestVertInfo { int dist; /* distance from mouse to vert */ eAnim_ChannelType ctype; /* type of animation channel this FCurve comes from */ + + float frame; /* frame that point was on when it matched (global time) */ } tNearestVertInfo; /* Tags for the type of graph vert that we have */ @@ -1151,6 +1153,8 @@ static void nearest_fcurve_vert_store( nvi->hpoint = hpoint; nvi->dist = dist; + nvi->frame = bezt->vec[1][0]; /* currently in global time... */ + nvi->sel = BEZT_ISSEL_ANY(bezt); // XXX... should this use the individual verts instead? /* add to list of matches if appropriate... */ @@ -1435,10 +1439,7 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short /* get frame number on which elements should be selected */ // TODO: should we restrict to integer frames only? - if (nvi->bezt) - selx = nvi->bezt->vec[1][0]; - else if (nvi->fpt) - selx = nvi->fpt->vec[0]; + selx = nvi->frame; /* if select mode is replace, deselect all keyframes first */ if (select_mode == SELECT_REPLACE) { diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 8ab46240eed..629c3a3c7a3 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -3872,7 +3872,7 @@ void *BPy_BMElem_PySeq_As_Array_FAST( BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL; PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast); const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast); - Py_ssize_t i; + Py_ssize_t i, i_last_dirty = PY_SSIZE_T_MAX; BPy_BMElem *item; BMElem **alloc; @@ -3921,6 +3921,7 @@ void *BPy_BMElem_PySeq_As_Array_FAST( if (do_unique_check) { BM_elem_flag_enable(item->ele, BM_ELEM_INTERNAL_TAG); + i_last_dirty = i; } } @@ -3937,6 +3938,8 @@ void *BPy_BMElem_PySeq_As_Array_FAST( } if (ok == false) { + /* Cleared above. */ + i_last_dirty = PY_SSIZE_T_MAX; PyErr_Format(PyExc_ValueError, "%s: found the same %.200s used multiple times", error_prefix, BPy_BMElem_StringFromHType(htype)); @@ -3949,6 +3952,11 @@ void *BPy_BMElem_PySeq_As_Array_FAST( return alloc; err_cleanup: + if (do_unique_check && (i_last_dirty != PY_SSIZE_T_MAX)) { + for (i = 0; i <= i_last_dirty; i++) { + BM_elem_flag_disable(alloc[i], BM_ELEM_INTERNAL_TAG); + } + } PyMem_FREE(alloc); return NULL; |