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:
parent
d6eac9d787
commit
c111eb0e99
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue