diff options
Diffstat (limited to 'source/blender/editors/mesh/editface.c')
-rw-r--r-- | source/blender/editors/mesh/editface.c | 263 |
1 files changed, 13 insertions, 250 deletions
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index c4e87614732..c453284a617 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -24,7 +24,6 @@ * \ingroup edmesh */ - #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" @@ -41,8 +40,6 @@ #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_context.h" -#include "BKE_editmesh.h" -#include "BKE_utildefines.h" #include "BIF_gl.h" @@ -139,7 +136,7 @@ void paintface_hide(Object *ob, const bool unselected) } -void paintface_reveal(Object *ob) +void paintface_reveal(Object *ob, const bool select) { Mesh *me; MPoly *mpoly; @@ -152,8 +149,8 @@ void paintface_reveal(Object *ob) a = me->totpoly; while (a--) { if (mpoly->flag & ME_HIDE) { - mpoly->flag |= ME_FACE_SEL; - mpoly->flag -= ME_HIDE; + SET_FLAG_FROM_TEST(mpoly->flag, select, ME_FACE_SEL); + mpoly->flag &= ~ME_HIDE; } mpoly++; } @@ -231,7 +228,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const unsigned int index, for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) { if (BLI_BITMAP_TEST(poly_tag, a)) { - BKE_BIT_TEST_SET(mp->flag, select, ME_FACE_SEL); + SET_FLAG_FROM_TEST(mp->flag, select, ME_FACE_SEL); } } @@ -306,31 +303,30 @@ void paintface_deselect_all_visible(Object *ob, int action, bool flush_flags) bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) { - Mesh *me; - MPoly *mp; - MTexPoly *tf; - MLoop *ml; - MVert *mvert; + const Mesh *me; + const MPoly *mp; + const MLoop *ml; + const MVert *mvert; int a, b; bool ok = false; float vec[3], bmat[3][3]; me = BKE_mesh_from_object(ob); - if (!me || !me->mtpoly) return ok; + if (!me || !me->mloopuv) { + return ok; + } copy_m3_m4(bmat, ob->obmat); mvert = me->mvert; mp = me->mpoly; - tf = me->mtpoly; - for (a = me->totpoly; a > 0; a--, mp++, tf++) { + for (a = me->totpoly; a > 0; a--, mp++) { if (mp->flag & ME_HIDE || !(mp->flag & ME_FACE_SEL)) continue; ml = me->mloop + mp->totloop; for (b = 0; b < mp->totloop; b++, ml++) { - copy_v3_v3(vec, (mvert[ml->v].co)); - mul_m3_v3(bmat, vec); + mul_v3_m3v3(vec, bmat, mvert[ml->v].co); add_v3_v3v3(vec, vec, ob->obmat[3]); minmax_v3v3_v3(r_min, r_max, vec); } @@ -607,236 +603,3 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags) paintvert_flush_flags(ob); } } - -/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */ -/* note, this is not the best place for the function to be but moved - * here for the purpose of syncing with bmesh */ - -typedef unsigned int MirrTopoHash_t; - -typedef struct MirrTopoVert_t { - MirrTopoHash_t hash; - int v_index; -} MirrTopoVert_t; - -static int mirrtopo_hash_sort(const void *l1, const void *l2) -{ - if ((MirrTopoHash_t)(intptr_t)l1 > (MirrTopoHash_t)(intptr_t)l2) return 1; - else if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2) return -1; - return 0; -} - -static int mirrtopo_vert_sort(const void *v1, const void *v2) -{ - if (((MirrTopoVert_t *)v1)->hash > ((MirrTopoVert_t *)v2)->hash) return 1; - else if (((MirrTopoVert_t *)v1)->hash < ((MirrTopoVert_t *)v2)->hash) return -1; - return 0; -} - -bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store) -{ - int totvert; - int totedge; - - if (dm) { - totvert = dm->getNumVerts(dm); - totedge = dm->getNumEdges(dm); - } - else if (me->edit_btmesh) { - totvert = me->edit_btmesh->bm->totvert; - totedge = me->edit_btmesh->bm->totedge; - } - else { - totvert = me->totvert; - totedge = me->totedge; - } - - if ((mesh_topo_store->index_lookup == NULL) || - (mesh_topo_store->prev_ob_mode != ob_mode) || - (totvert != mesh_topo_store->prev_vert_tot) || - (totedge != mesh_topo_store->prev_edge_tot)) - { - return true; - } - else { - return false; - } - -} - -void ED_mesh_mirrtopo_init(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store, - const bool skip_em_vert_array_init) -{ - MEdge *medge = NULL, *med; - BMEditMesh *em = dm ? NULL : me->edit_btmesh; - - /* editmode*/ - BMEdge *eed; - BMIter iter; - - int a, last; - int totvert, totedge; - int tot_unique = -1, tot_unique_prev = -1; - int tot_unique_edges = 0, tot_unique_edges_prev; - - MirrTopoHash_t *topo_hash = NULL; - MirrTopoHash_t *topo_hash_prev = NULL; - MirrTopoVert_t *topo_pairs; - MirrTopoHash_t topo_pass = 1; - - intptr_t *index_lookup; /* direct access to mesh_topo_store->index_lookup */ - - /* reallocate if needed */ - ED_mesh_mirrtopo_free(mesh_topo_store); - - mesh_topo_store->prev_ob_mode = ob_mode; - - if (em) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT); - - totvert = em->bm->totvert; - } - else { - totvert = dm ? dm->getNumVerts(dm) : me->totvert; - } - - topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr"); - - /* Initialize the vert-edge-user counts used to detect unique topology */ - if (em) { - totedge = me->edit_btmesh->bm->totedge; - - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - const int i1 = BM_elem_index_get(eed->v1), i2 = BM_elem_index_get(eed->v2); - topo_hash[i1]++; - topo_hash[i2]++; - } - } - else { - totedge = dm ? dm->getNumEdges(dm) : me->totedge; - medge = dm ? dm->getEdgeArray(dm) : me->medge; - - for (a = 0, med = medge; a < totedge; a++, med++) { - const unsigned int i1 = med->v1, i2 = med->v2; - topo_hash[i1]++; - topo_hash[i2]++; - } - } - - topo_hash_prev = MEM_dupallocN(topo_hash); - - tot_unique_prev = -1; - tot_unique_edges_prev = -1; - while (1) { - /* use the number of edges per vert to give verts unique topology IDs */ - - tot_unique_edges = 0; - - /* This can make really big numbers, wrapping around here is fine */ - if (em) { - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - const int i1 = BM_elem_index_get(eed->v1), i2 = BM_elem_index_get(eed->v2); - topo_hash[i1] += topo_hash_prev[i2] * topo_pass; - topo_hash[i2] += topo_hash_prev[i1] * topo_pass; - tot_unique_edges += (topo_hash[i1] != topo_hash[i2]); - } - } - else { - for (a = 0, med = medge; a < totedge; a++, med++) { - const unsigned int i1 = med->v1, i2 = med->v2; - topo_hash[i1] += topo_hash_prev[i2] * topo_pass; - topo_hash[i2] += topo_hash_prev[i1] * topo_pass; - tot_unique_edges += (topo_hash[i1] != topo_hash[i2]); - } - } - memcpy(topo_hash_prev, topo_hash, sizeof(MirrTopoHash_t) * totvert); - - /* sort so we can count unique values */ - qsort(topo_hash_prev, totvert, sizeof(MirrTopoHash_t), mirrtopo_hash_sort); - - tot_unique = 1; /* account for skiping the first value */ - for (a = 1; a < totvert; a++) { - if (topo_hash_prev[a - 1] != topo_hash_prev[a]) { - tot_unique++; - } - } - - if ((tot_unique <= tot_unique_prev) && (tot_unique_edges <= tot_unique_edges_prev)) { - /* Finish searching for unique values when 1 loop dosnt give a - * higher number of unique values compared to the previous loop */ - break; - } - else { - tot_unique_prev = tot_unique; - tot_unique_edges_prev = tot_unique_edges; - } - /* Copy the hash calculated this iter, so we can use them next time */ - memcpy(topo_hash_prev, topo_hash, sizeof(MirrTopoHash_t) * totvert); - - topo_pass++; - } - - /* Hash/Index pairs are needed for sorting to find index pairs */ - topo_pairs = MEM_callocN(sizeof(MirrTopoVert_t) * totvert, "MirrTopoPairs"); - - /* since we are looping through verts, initialize these values here too */ - index_lookup = MEM_mallocN(totvert * sizeof(*index_lookup), "mesh_topo_lookup"); - - if (em) { - if (skip_em_vert_array_init == false) { - BM_mesh_elem_table_ensure(em->bm, BM_VERT); - } - } - - for (a = 0; a < totvert; a++) { - topo_pairs[a].hash = topo_hash[a]; - topo_pairs[a].v_index = a; - - /* initialize lookup */ - index_lookup[a] = -1; - } - - qsort(topo_pairs, totvert, sizeof(MirrTopoVert_t), mirrtopo_vert_sort); - - /* Since the loop starts at 2, we must define the last index where the hash's differ */ - last = ((totvert >= 2) && (topo_pairs[0].hash == topo_pairs[1].hash)) ? 0 : 1; - - /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2, - * but you cant ever access the last 'a' index of MirrTopoPairs */ - for (a = 2; a <= totvert; a++) { - /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].v_index ); */ - if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) { - if (a - last == 2) { - if (em) { - index_lookup[topo_pairs[a - 1].v_index] = (intptr_t)BM_vert_at_index(em->bm, topo_pairs[a - 2].v_index); - index_lookup[topo_pairs[a - 2].v_index] = (intptr_t)BM_vert_at_index(em->bm, topo_pairs[a - 1].v_index); - } - else { - index_lookup[topo_pairs[a - 1].v_index] = topo_pairs[a - 2].v_index; - index_lookup[topo_pairs[a - 2].v_index] = topo_pairs[a - 1].v_index; - } - } - last = a; - } - } - - MEM_freeN(topo_pairs); - topo_pairs = NULL; - - MEM_freeN(topo_hash); - MEM_freeN(topo_hash_prev); - - mesh_topo_store->index_lookup = index_lookup; - mesh_topo_store->prev_vert_tot = totvert; - mesh_topo_store->prev_edge_tot = totedge; -} - -void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store) -{ - if (mesh_topo_store->index_lookup) { - MEM_freeN(mesh_topo_store->index_lookup); - } - mesh_topo_store->index_lookup = NULL; - mesh_topo_store->prev_vert_tot = -1; - mesh_topo_store->prev_edge_tot = -1; -} |