Cleanup: get rid of dual DM/Mesh versions of mirror topology code.

Easy to switch to only use (evaluated) mesh instead!
This commit is contained in:
Bastien Montagne 2018-06-21 19:05:10 +02:00
parent d6eac9d787
commit c111eb0e99
5 changed files with 45 additions and 289 deletions

View File

@ -225,14 +225,9 @@ typedef struct MirrTopoStore_t {
} MirrTopoStore_t;
bool ED_mesh_mirrtopo_recalc_check(
struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store);
bool ED_mesh_mirrtopo_recalc_check__real_mesh(
struct Mesh *me, struct Mesh *dm, MirrTopoStore_t *mesh_topo_store);
struct Mesh *me, struct Mesh *me_eval, MirrTopoStore_t *mesh_topo_store);
void ED_mesh_mirrtopo_init(
struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store,
const bool skip_em_vert_array_init);
void ED_mesh_mirrtopo_init__real_mesh(
struct Mesh *me, struct Mesh *dm, MirrTopoStore_t *mesh_topo_store,
struct Mesh *me, struct Mesh *me_eval, MirrTopoStore_t *mesh_topo_store,
const bool skip_em_vert_array_init);
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
@ -322,22 +317,17 @@ 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 DerivedMesh *dm, const float co[3], char mode);
int ED_mesh_mirror_spatial_table__real_mesh(
struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh, const float co[3], char mode);
int ED_mesh_mirror_topo_table(struct Object *ob, struct DerivedMesh *dm, char mode);
int ED_mesh_mirror_topo_table__real_mesh(struct Object *ob, struct Mesh *mesh, char mode);
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);
/* retrieves mirrored cache vert, or NULL if there isn't one.
* note: calling this without ensuring the mirror cache state
* is bad.*/
int mesh_get_x_mirror_vert(struct Object *ob, struct DerivedMesh *dm, int index, const bool use_topology);
int mesh_get_x_mirror_vert__real_mesh(struct Object *ob, struct Mesh *mesh, int index, const bool use_topology);
int mesh_get_x_mirror_vert(struct Object *ob, struct Mesh *me_eval, int index, const bool use_topology);
struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em,
struct BMVert *eve, const float co[3],
int index, const bool use_topology);
int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm);
int *mesh_get_x_mirror_faces__real_mesh(struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh);
int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em, struct Mesh *me_eval);
int ED_mesh_mirror_get_vert(struct Object *ob, int index);

View File

@ -1035,7 +1035,7 @@ void EDBM_verts_mirror_cache_begin_ex(
BM_mesh_elem_index_ensure(bm, BM_VERT);
if (use_topology) {
ED_mesh_mirrtopo_init__real_mesh(me, NULL, &mesh_topo_store, true);
ED_mesh_mirrtopo_init(me, NULL, &mesh_topo_store, true);
}
else {
tree = BLI_kdtree_new(bm->totvert);

View File

@ -32,9 +32,9 @@
#include "BLI_bitmap.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "BKE_DerivedMesh.h"
#include "BLI_kdtree.h"
#include "BKE_editmesh.h"
#include "BKE_library.h"
@ -52,11 +52,11 @@ 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, DerivedMesh *dm, const float co[3], char mode)
int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, Mesh *me_eval, const float co[3], char mode)
{
if (mode == 'u') { /* use table */
if (MirrKdStore.tree == NULL)
ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 's');
ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 's');
if (MirrKdStore.tree) {
KDTreeNearest nearest;
@ -72,11 +72,11 @@ int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, DerivedMesh *dm, co
}
else if (mode == 's') { /* start table */
Mesh *me = ob->data;
const bool use_em = (!dm && em && me->edit_btmesh == em);
const int totvert = use_em ? em->bm->totvert : dm ? dm->getNumVerts(dm) : me->totvert;
const bool use_em = (!me_eval && em && me->edit_btmesh == 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, dm, co, 'e');
ED_mesh_mirror_spatial_table(ob, em, me_eval, co, 'e');
MirrKdStore.tree = BLI_kdtree_new(totvert);
@ -93,73 +93,7 @@ int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, DerivedMesh *dm, co
}
}
else {
MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert;
int i;
for (i = 0; i < totvert; i++, mvert++) {
BLI_kdtree_insert(MirrKdStore.tree, i, mvert->co);
}
}
BLI_kdtree_balance(MirrKdStore.tree);
}
else if (mode == 'e') { /* end table */
if (MirrKdStore.tree) {
BLI_kdtree_free(MirrKdStore.tree);
MirrKdStore.tree = NULL;
}
}
else {
BLI_assert(0);
}
return 0;
}
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
int ED_mesh_mirror_spatial_table__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, const float co[3], char mode)
{
if (mode == 'u') { /* use table */
if (MirrKdStore.tree == NULL)
ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's');
if (MirrKdStore.tree) {
KDTreeNearest nearest;
const int i = BLI_kdtree_find_nearest(MirrKdStore.tree, co, &nearest);
if (i != -1) {
if (nearest.dist < KD_THRESH) {
return i;
}
}
}
return -1;
}
else if (mode == 's') { /* start table */
Mesh *me = ob->data;
const bool use_em = (!mesh && em && me->edit_btmesh == em);
const int totvert = use_em ? em->bm->totvert : mesh ? mesh->totvert : me->totvert;
if (MirrKdStore.tree) /* happens when entering this call without ending it */
ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, co, 'e');
MirrKdStore.tree = BLI_kdtree_new(totvert);
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);
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
BLI_kdtree_insert(MirrKdStore.tree, i, eve->co);
}
}
else {
MVert *mvert = mesh ? mesh->mvert : me->mvert;
MVert *mvert = me_eval ? me_eval->mvert : me->mvert;
int i;
for (i = 0; i < totvert; i++, mvert++) {
@ -209,15 +143,15 @@ static int mirrtopo_vert_sort(const void *v1, const void *v2)
return 0;
}
bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store)
bool ED_mesh_mirrtopo_recalc_check(Mesh *me, Mesh *me_eval, MirrTopoStore_t *mesh_topo_store)
{
const bool is_editmode = (me->edit_btmesh != NULL);
int totvert;
int totedge;
if (dm) {
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
if (me_eval) {
totvert = me_eval->totvert;
totedge = me_eval->totedge;
}
else if (me->edit_btmesh) {
totvert = me->edit_btmesh->bm->totvert;
@ -240,65 +174,14 @@ bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, MirrTopoStore_t *m
}
}
bool ED_mesh_mirrtopo_recalc_check__real_mesh(Mesh *me, Mesh *dm, MirrTopoStore_t *mesh_topo_store)
{
const bool is_editmode = (me->edit_btmesh != NULL);
int totvert;
int totedge;
if (dm) {
totvert = dm->totvert;
totedge = dm->totedge;
}
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_is_editmode != is_editmode) ||
(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, MirrTopoStore_t *mesh_topo_store,
const bool skip_em_vert_array_init)
{
Mesh *fake_mesh = NULL;
if (dm != NULL) {
/* ED_real_mesh_mirrtopo_init() only uses the counts, not the actual data */
fake_mesh = BKE_mesh_new_nomain(dm->getNumVerts(dm), dm->getNumEdges(dm), dm->getNumTessFaces(dm),
dm->getNumLoops(dm), dm->getNumPolys(dm));
}
ED_mesh_mirrtopo_init__real_mesh(me, fake_mesh, mesh_topo_store, skip_em_vert_array_init);
if (dm != NULL) {
BKE_id_free(NULL, fake_mesh);
}
}
void ED_mesh_mirrtopo_init__real_mesh(
Mesh *me, Mesh *dm, MirrTopoStore_t *mesh_topo_store,
Mesh *me, Mesh *me_eval, MirrTopoStore_t *mesh_topo_store,
const bool skip_em_vert_array_init)
{
const bool is_editmode = (me->edit_btmesh != NULL);
MEdge *medge = NULL, *med;
BMEditMesh *em = dm ? NULL : me->edit_btmesh;
BMEditMesh *em = me_eval ? NULL : me->edit_btmesh;
/* editmode*/
BMEdge *eed;
@ -327,7 +210,7 @@ void ED_mesh_mirrtopo_init__real_mesh(
totvert = em->bm->totvert;
}
else {
totvert = dm ? dm->totvert : me->totvert;
totvert = me_eval ? me_eval->totvert : me->totvert;
}
topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr");
@ -343,8 +226,8 @@ void ED_mesh_mirrtopo_init__real_mesh(
}
}
else {
totedge = dm ? dm->totedge : me->totedge;
medge = dm ? dm->medge : me->medge;
totedge = me_eval ? me_eval->totedge : me->totedge;
medge = me_eval ? me_eval->medge : me->medge;
for (a = 0, med = medge; a < totedge; a++, med++) {
const unsigned int i1 = med->v1, i2 = med->v2;

View File

@ -34,9 +34,10 @@
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@ -49,7 +50,6 @@
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
@ -691,40 +691,15 @@ static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
/* note, 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, DerivedMesh *dm, char mode)
int ED_mesh_mirror_topo_table(Object *ob, Mesh *me_eval, char mode)
{
if (mode == 'u') { /* use table */
if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, &mesh_topo_store)) {
ED_mesh_mirror_topo_table(ob, dm, 's');
if (ED_mesh_mirrtopo_recalc_check(ob->data, me_eval, &mesh_topo_store)) {
ED_mesh_mirror_topo_table(ob, me_eval, 's');
}
}
else if (mode == 's') { /* start table */
ED_mesh_mirrtopo_init(ob->data, dm, &mesh_topo_store, false);
}
else if (mode == 'e') { /* end table */
ED_mesh_mirrtopo_free(&mesh_topo_store);
}
else {
BLI_assert(0);
}
return 0;
}
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */
int ED_mesh_mirror_topo_table__real_mesh(
Object *ob, Mesh *mesh, char mode)
{
if (mode == 'u') { /* use table */
if (ED_mesh_mirrtopo_recalc_check__real_mesh(ob->data, mesh, &mesh_topo_store)) {
ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 's');
}
}
else if (mode == 's') { /* start table */
ED_mesh_mirrtopo_init__real_mesh(ob->data, mesh, &mesh_topo_store, false);
ED_mesh_mirrtopo_init(ob->data, me_eval, &mesh_topo_store, false);
}
else if (mode == 'e') { /* end table */
ED_mesh_mirrtopo_free(&mesh_topo_store);
@ -739,39 +714,7 @@ int ED_mesh_mirror_topo_table__real_mesh(
/** \} */
static int mesh_get_x_mirror_vert_spatial(Object *ob, DerivedMesh *dm, int index)
{
Mesh *me = ob->data;
MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert;
float vec[3];
mvert = &mvert[index];
vec[0] = -mvert->co[0];
vec[1] = mvert->co[1];
vec[2] = mvert->co[2];
return ED_mesh_mirror_spatial_table(ob, NULL, dm, vec, 'u');
}
static int mesh_get_x_mirror_vert_topo(Object *ob, DerivedMesh *dm, int index)
{
if (ED_mesh_mirror_topo_table(ob, dm, 'u') == -1)
return -1;
return mesh_topo_store.index_lookup[index];
}
int mesh_get_x_mirror_vert(Object *ob, DerivedMesh *dm, int index, const bool use_topology)
{
if (use_topology) {
return mesh_get_x_mirror_vert_topo(ob, dm, index);
}
else {
return mesh_get_x_mirror_vert_spatial(ob, dm, index);
}
}
static int mesh_get_x_mirror_vert_spatial__real_mesh(Object *ob, Mesh *mesh, int index)
static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *mesh, int index)
{
Mesh *me = ob->data;
MVert *mvert = mesh ? mesh->mvert : me->mvert;
@ -782,24 +725,24 @@ static int mesh_get_x_mirror_vert_spatial__real_mesh(Object *ob, Mesh *mesh, int
vec[1] = mvert->co[1];
vec[2] = mvert->co[2];
return ED_mesh_mirror_spatial_table__real_mesh(ob, NULL, mesh, vec, 'u');
return ED_mesh_mirror_spatial_table(ob, NULL, mesh, vec, 'u');
}
static int mesh_get_x_mirror_vert_topo__real_mesh(Object *ob, Mesh *mesh, int index)
static int mesh_get_x_mirror_vert_topo(Object *ob, Mesh *mesh, int index)
{
if (ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 'u') == -1)
if (ED_mesh_mirror_topo_table(ob, mesh, 'u') == -1)
return -1;
return mesh_topo_store.index_lookup[index];
}
int mesh_get_x_mirror_vert__real_mesh(Object *ob, Mesh *mesh, int index, const bool use_topology)
int mesh_get_x_mirror_vert(Object *ob, Mesh *me_eval, int index, const bool use_topology)
{
if (use_topology) {
return mesh_get_x_mirror_vert_topo__real_mesh(ob, mesh, index);
return mesh_get_x_mirror_vert_topo(ob, me_eval, index);
}
else {
return mesh_get_x_mirror_vert_spatial__real_mesh(ob, mesh, index);
return mesh_get_x_mirror_vert_spatial(ob, me_eval, index);
}
}
@ -996,68 +939,8 @@ static bool mirror_facecmp(const void *a, const void *b)
return (mirror_facerotation((MFace *)a, (MFace *)b) == -1);
}
/* BMESH_TODO, convert to MPoly (functions above also) */
int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm)
{
Mesh *me = ob->data;
MVert *mv, *mvert;
MFace mirrormf, *mf, *hashmf, *mface;
GHash *fhash;
int *mirrorverts, *mirrorfaces;
BLI_assert(em == NULL); /* Does not work otherwise, currently... */
const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
const int totvert = dm ? dm->getNumVerts(dm) : me->totvert;
const int totface = dm ? dm->getNumTessFaces(dm) : me->totface;
int a;
mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts");
mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces");
mvert = dm ? dm->getVertArray(dm) : me->mvert;
mface = dm ? dm->getTessFaceArray(dm) : me->mface;
ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 's');
for (a = 0, mv = mvert; a < totvert; a++, mv++)
mirrorverts[a] = mesh_get_x_mirror_vert(ob, dm, a, use_topology);
ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 'e');
fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
for (a = 0, mf = mface; a < totface; a++, mf++)
BLI_ghash_insert(fhash, mf, mf);
for (a = 0, mf = mface; a < totface; a++, mf++) {
mirrormf.v1 = mirrorverts[mf->v3];
mirrormf.v2 = mirrorverts[mf->v2];
mirrormf.v3 = mirrorverts[mf->v1];
mirrormf.v4 = (mf->v4) ? mirrorverts[mf->v4] : 0;
/* make sure v4 is not 0 if a quad */
if (mf->v4 && mirrormf.v4 == 0) {
SWAP(unsigned int, mirrormf.v1, mirrormf.v3);
SWAP(unsigned int, mirrormf.v2, mirrormf.v4);
}
hashmf = BLI_ghash_lookup(fhash, &mirrormf);
if (hashmf) {
mirrorfaces[a * 2] = hashmf - mface;
mirrorfaces[a * 2 + 1] = mirror_facerotation(&mirrormf, hashmf);
}
else
mirrorfaces[a * 2] = -1;
}
BLI_ghash_free(fhash, NULL, NULL);
MEM_freeN(mirrorverts);
return mirrorfaces;
}
/* This is a Mesh-based copy of mesh_get_x_mirror_faces() */
int *mesh_get_x_mirror_faces__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh)
int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
{
Mesh *me = ob->data;
MVert *mv, *mvert;
@ -1068,22 +951,22 @@ int *mesh_get_x_mirror_faces__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh)
BLI_assert(em == NULL); /* Does not work otherwise, currently... */
const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
const int totvert = mesh ? mesh->totvert : me->totvert;
const int totface = mesh ? mesh->totface : me->totface;
const int totvert = me_eval ? me_eval->totvert : me->totvert;
const int totface = me_eval ? me_eval->totface : me->totface;
int a;
mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts");
mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces");
mvert = mesh ? mesh->mvert : me->mvert;
mface = mesh ? mesh->mface : me->mface;
mvert = me_eval ? me_eval->mvert : me->mvert;
mface = me_eval ? me_eval->mface : me->mface;
ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's');
ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 's');
for (a = 0, mv = mvert; a < totvert; a++, mv++)
mirrorverts[a] = mesh_get_x_mirror_vert__real_mesh(ob, mesh, a, use_topology);
mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology);
ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 'e');
ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 'e');
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

@ -3017,7 +3017,7 @@ static void PE_mirror_x(
/* Note: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. Avoids an (impossible)
* mesh -> orig -> mesh tessface indices conversion... */
mirrorfaces = mesh_get_x_mirror_faces__real_mesh(ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL);
mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL);
if (!edit->mirror_cache)
PE_update_mirror_cache(ob, psys);