Cleanup: split ED_mesh_mirror_*_table into multiple functions

Spatial & topology mirror table each used a single function
taking a char as an identifier.

Split these into begin/end/lookup functions.
This commit is contained in:
Campbell Barton 2020-04-03 21:47:56 +11:00
parent b5253159b6
commit 7ec59cc7b7
10 changed files with 129 additions and 111 deletions

View File

@ -459,7 +459,7 @@ static void add_verts_to_dgroups(ReportList *reports,
}
/* only generated in some cases but can call anyway */
ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 'e');
ED_mesh_mirror_spatial_table_end(ob);
/* free the memory allocated */
MEM_freeN(bonelist);

View File

@ -450,9 +450,19 @@ int join_mesh_exec(struct bContext *C, struct wmOperator *op);
int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
/* mirror lookup api */
int ED_mesh_mirror_spatial_table(
struct Object *ob, struct BMEditMesh *em, struct Mesh *me_eval, const float co[3], char mode);
int ED_mesh_mirror_topo_table(struct Object *ob, struct Mesh *me_eval, char mode);
/* Spatial Mirror */
void ED_mesh_mirror_spatial_table_begin(struct Object *ob,
struct BMEditMesh *em,
struct Mesh *me_eval);
void ED_mesh_mirror_spatial_table_end(struct Object *ob);
int ED_mesh_mirror_spatial_table_lookup(struct Object *ob,
struct BMEditMesh *em,
struct Mesh *me_eval,
const float co[3]);
/* Topology Mirror */
void ED_mesh_mirror_topo_table_begin(struct Object *ob, struct Mesh *me_eval);
void ED_mesh_mirror_topo_table_end(struct Object *ob);
/* retrieves mirrored cache vert, or NULL if there isn't one.
* note: calling this without ensuring the mirror cache state

View File

@ -406,10 +406,10 @@ void EDBM_mesh_load(Main *bmain, Object *ob)
void EDBM_mesh_free(BMEditMesh *em)
{
/* These tables aren't used yet, so it's not strictly necessary
* to 'end' them (with 'e' param) but if someone tries to start
* using them, having these in place will save a lot of pain */
ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
ED_mesh_mirror_topo_table(NULL, NULL, 'e');
* to 'end' them but if someone tries to start using them,
* having these in place will save a lot of pain. */
ED_mesh_mirror_spatial_table_end(NULL);
ED_mesh_mirror_topo_table_end(NULL);
BKE_editmesh_free(em);
}

View File

@ -44,73 +44,71 @@ static struct {
void *tree;
} MirrKdStore = {NULL};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
int ED_mesh_mirror_spatial_table(
Object *ob, BMEditMesh *em, Mesh *me_eval, const float co[3], char mode)
void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *me_eval)
{
if (mode == 'u') { /* use table */
if (MirrKdStore.tree == NULL) {
ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 's');
}
Mesh *me = ob->data;
const bool use_em = (!me_eval && em && me->edit_mesh == em);
const int totvert = use_em ? em->bm->totvert : me_eval ? me_eval->totvert : me->totvert;
if (MirrKdStore.tree) {
KDTreeNearest_3d nearest;
const int i = BLI_kdtree_3d_find_nearest(MirrKdStore.tree, co, &nearest);
if (i != -1) {
if (nearest.dist < KD_THRESH) {
return i;
}
}
}
return -1;
if (MirrKdStore.tree) { /* happens when entering this call without ending it */
ED_mesh_mirror_spatial_table_end(ob);
}
else if (mode == 's') { /* start table */
Mesh *me = ob->data;
const bool use_em = (!me_eval && em && me->edit_mesh == em);
const int totvert = use_em ? em->bm->totvert : me_eval ? me_eval->totvert : me->totvert;
if (MirrKdStore.tree) { /* happens when entering this call without ending it */
ED_mesh_mirror_spatial_table(ob, em, me_eval, co, 'e');
}
MirrKdStore.tree = BLI_kdtree_3d_new(totvert);
MirrKdStore.tree = BLI_kdtree_3d_new(totvert);
if (use_em) {
BMVert *eve;
BMIter iter;
int i;
if (use_em) {
BMVert *eve;
BMIter iter;
int i;
/* this needs to be valid for index lookups later (callers need) */
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
/* this needs to be valid for index lookups later (callers need) */
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
BLI_kdtree_3d_insert(MirrKdStore.tree, i, eve->co);
}
}
else {
MVert *mvert = me_eval ? me_eval->mvert : me->mvert;
int i;
for (i = 0; i < totvert; i++, mvert++) {
BLI_kdtree_3d_insert(MirrKdStore.tree, i, mvert->co);
}
}
BLI_kdtree_3d_balance(MirrKdStore.tree);
}
else if (mode == 'e') { /* end table */
if (MirrKdStore.tree) {
BLI_kdtree_3d_free(MirrKdStore.tree);
MirrKdStore.tree = NULL;
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
BLI_kdtree_3d_insert(MirrKdStore.tree, i, eve->co);
}
}
else {
BLI_assert(0);
MVert *mvert = me_eval ? me_eval->mvert : me->mvert;
int i;
for (i = 0; i < totvert; i++, mvert++) {
BLI_kdtree_3d_insert(MirrKdStore.tree, i, mvert->co);
}
}
return 0;
BLI_kdtree_3d_balance(MirrKdStore.tree);
}
int ED_mesh_mirror_spatial_table_lookup(Object *ob,
BMEditMesh *em,
Mesh *me_eval,
const float co[3])
{
if (MirrKdStore.tree == NULL) {
ED_mesh_mirror_spatial_table_begin(ob, em, me_eval);
}
if (MirrKdStore.tree) {
KDTreeNearest_3d nearest;
const int i = BLI_kdtree_3d_find_nearest(MirrKdStore.tree, co, &nearest);
if (i != -1) {
if (nearest.dist < KD_THRESH) {
return i;
}
}
}
return -1;
}
void ED_mesh_mirror_spatial_table_end(Object *UNUSED(ob))
{
/* TODO: store this in object/object-data (keep unused argument for now). */
if (MirrKdStore.tree) {
BLI_kdtree_3d_free(MirrKdStore.tree);
MirrKdStore.tree = NULL;
}
}
/** \} */

View File

@ -786,53 +786,64 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
}
/* -------------------------------------------------------------------- */
/* Mesh Mirror (Topology) */
/** \name Mesh Topology Mirror API
* \{ */
static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1};
BLI_INLINE void mesh_mirror_topo_table_get_meshes(Object *ob,
Mesh *me_eval,
Mesh **r_me_mirror,
BMEditMesh **r_em_mirror)
{
Mesh *me_mirror = NULL;
BMEditMesh *em_mirror = NULL;
Mesh *me = ob->data;
if (me_eval != NULL) {
me_mirror = me_eval;
}
else if (me->edit_mesh != NULL) {
em_mirror = me->edit_mesh;
}
else {
me_mirror = me;
}
*r_me_mirror = me_mirror;
*r_em_mirror = em_mirror;
}
/**
* Mode is 's' start, or 'e' end, or 'u' use
* if end, ob can be NULL.
* \note This is supposed return -1 on error,
* which callers are currently checking for, but is not used so far.
*/
int ED_mesh_mirror_topo_table(Object *ob, Mesh *me_eval, char mode)
void ED_mesh_mirror_topo_table_begin(Object *ob, Mesh *me_eval)
{
Mesh *me_mirror;
BMEditMesh *em_mirror;
mesh_mirror_topo_table_get_meshes(ob, me_eval, &me_mirror, &em_mirror);
Mesh *me_mirror = NULL;
BMEditMesh *em_mirror = NULL;
ED_mesh_mirrtopo_init(em_mirror, me_mirror, &mesh_topo_store, false);
}
if (mode != 'e') {
Mesh *me = ob->data;
if (me_eval != NULL) {
me_mirror = me_eval;
}
else if (me->edit_mesh != NULL) {
em_mirror = me->edit_mesh;
}
else {
me_mirror = me;
}
}
void ED_mesh_mirror_topo_table_end(Object *UNUSED(ob))
{
/* TODO: store this in object/object-data (keep unused argument for now). */
ED_mesh_mirrtopo_free(&mesh_topo_store);
}
if (mode == 'u') { /* use table */
if (ED_mesh_mirrtopo_recalc_check(em_mirror, me_mirror, &mesh_topo_store)) {
ED_mesh_mirror_topo_table(ob, me_eval, 's');
}
}
else if (mode == 's') { /* start table */
ED_mesh_mirrtopo_init(em_mirror, me_mirror, &mesh_topo_store, false);
}
else if (mode == 'e') { /* end table */
ED_mesh_mirrtopo_free(&mesh_topo_store);
}
else {
BLI_assert(0);
}
static int ed_mesh_mirror_topo_table_update(Object *ob, Mesh *me_eval)
{
Mesh *me_mirror;
BMEditMesh *em_mirror;
mesh_mirror_topo_table_get_meshes(ob, me_eval, &me_mirror, &em_mirror);
if (ED_mesh_mirrtopo_recalc_check(em_mirror, me_mirror, &mesh_topo_store)) {
ED_mesh_mirror_topo_table_begin(ob, me_eval);
}
return 0;
}
@ -849,12 +860,12 @@ static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *mesh, int index)
vec[1] = mvert->co[1];
vec[2] = mvert->co[2];
return ED_mesh_mirror_spatial_table(ob, NULL, mesh, vec, 'u');
return ED_mesh_mirror_spatial_table_lookup(ob, NULL, mesh, vec);
}
static int mesh_get_x_mirror_vert_topo(Object *ob, Mesh *mesh, int index)
{
if (ED_mesh_mirror_topo_table(ob, mesh, 'u') == -1) {
if (ed_mesh_mirror_topo_table_update(ob, mesh) == -1) {
return -1;
}
@ -885,7 +896,7 @@ static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, c
vec[1] = co[1];
vec[2] = co[2];
i = ED_mesh_mirror_spatial_table(ob, em, NULL, vec, 'u');
i = ED_mesh_mirror_spatial_table_lookup(ob, em, NULL, vec);
if (i != -1) {
return BM_vert_at_index(em->bm, i);
}
@ -898,7 +909,7 @@ static BMVert *editbmesh_get_x_mirror_vert_topo(Object *ob,
int index)
{
intptr_t poinval;
if (ED_mesh_mirror_topo_table(ob, NULL, 'u') == -1) {
if (ed_mesh_mirror_topo_table_update(ob, NULL) == -1) {
return NULL;
}
@ -1098,13 +1109,13 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
mvert = me_eval ? me_eval->mvert : me->mvert;
mface = me_eval ? me_eval->mface : me->mface;
ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 's');
ED_mesh_mirror_spatial_table_begin(ob, em, me_eval);
for (a = 0, mv = mvert; a < totvert; a++, mv++) {
mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology);
}
ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 'e');
ED_mesh_mirror_spatial_table_end(ob);
fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
for (a = 0, mf = mface; a < totface; a++, mf++) {

View File

@ -454,8 +454,8 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
}
/* will be recalculated as needed. */
{
ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
ED_mesh_mirror_topo_table(NULL, NULL, 'e');
ED_mesh_mirror_spatial_table_end(obedit);
ED_mesh_mirror_topo_table_end(obedit);
}
}
else if (obedit->type == OB_ARMATURE) {

View File

@ -126,7 +126,7 @@ static bool object_shape_key_mirror(
float *fp1, *fp2;
float tvec[3];
ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
ED_mesh_mirror_spatial_table_begin(ob, NULL, NULL);
for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) {
i2 = mesh_get_x_mirror_vert(ob, NULL, i1, use_topology);
@ -157,7 +157,7 @@ static bool object_shape_key_mirror(
}
}
ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 'e');
ED_mesh_mirror_spatial_table_end(ob);
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;

View File

@ -1226,7 +1226,7 @@ static void ed_vwpaintmode_enter_generic(Main *bmain,
BKE_paint_init(bmain, scene, paint_mode, PAINT_CURSOR_WEIGHT_PAINT);
/* weight paint specific */
ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
ED_mesh_mirror_spatial_table_end(ob);
ED_vgroup_sync_from_pose(ob);
}
else {
@ -1318,8 +1318,8 @@ static void ed_vwpaintmode_exit_generic(Object *ob, const eObjectMode mode_flag)
paint_cursor_delete_textures();
if (mode_flag == OB_MODE_WEIGHT_PAINT) {
ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
ED_mesh_mirror_topo_table(NULL, NULL, 'e');
ED_mesh_mirror_spatial_table_end(ob);
ED_mesh_mirror_topo_table_end(ob);
}
/* Never leave derived meshes behind. */

View File

@ -2248,9 +2248,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
else if (t->flag & T_EDIT) {
if (t->obedit_type == OB_MESH) {
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
/* table needs to be created for each edit command, since vertices can move etc */
ED_mesh_mirror_spatial_table(tc->obedit, em, NULL, NULL, 'e');
ED_mesh_mirror_spatial_table_end(tc->obedit);
/* TODO(campbell): xform: We need support for many mirror objects at once! */
break;
}

View File

@ -224,8 +224,8 @@ void ED_editors_exit(Main *bmain, bool do_undo_system)
}
/* global in meshtools... */
ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
ED_mesh_mirror_topo_table(NULL, NULL, 'e');
ED_mesh_mirror_spatial_table_end(NULL);
ED_mesh_mirror_topo_table_end(NULL);
}
bool ED_editors_flush_edits_for_object_ex(Main *bmain,