forked from bartvdbraak/blender
topo mirror and sync with minor edits made to bmesh, no functional changes
This commit is contained in:
parent
2d1de2e78d
commit
0e4f1ad43d
@ -253,7 +253,8 @@ typedef struct MirrTopoStore_t {
|
||||
} MirrTopoStore_t;
|
||||
|
||||
int ED_mesh_mirrtopo_recalc_check(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store);
|
||||
void ED_mesh_mirrtopo_init(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store);
|
||||
void ED_mesh_mirrtopo_init(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store,
|
||||
const short skip_em_vert_array_init);
|
||||
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -823,22 +823,22 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend)
|
||||
|
||||
typedef int MirrTopoHash_t;
|
||||
|
||||
typedef struct MirrTopoPair_t {
|
||||
typedef struct MirrTopoVert_t {
|
||||
MirrTopoHash_t hash;
|
||||
int v_index;
|
||||
} MirrTopoPair_t;
|
||||
} MirrTopoVert_t;
|
||||
|
||||
static int MirrTopo_long_sort(const void *l1, const void *l2)
|
||||
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_item_sort(const void *v1, const void *v2)
|
||||
static int mirrtopo_vert_sort(const void *v1, const void *v2)
|
||||
{
|
||||
if (((MirrTopoPair_t *)v1)->hash > ((MirrTopoPair_t *)v2)->hash ) return 1;
|
||||
else if (((MirrTopoPair_t *)v1)->hash < ((MirrTopoPair_t *)v2)->hash ) return -1;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -848,12 +848,12 @@ int ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t *
|
||||
int totedge;
|
||||
|
||||
if (me->edit_mesh) {
|
||||
totvert= me->edit_mesh->totvert;
|
||||
totedge= me->edit_mesh->totedge;
|
||||
totvert = me->edit_mesh->totvert;
|
||||
totedge = me->edit_mesh->totedge;
|
||||
}
|
||||
else {
|
||||
totvert= me->totvert;
|
||||
totedge= me->totedge;
|
||||
totvert = me->totvert;
|
||||
totedge = me->totedge;
|
||||
}
|
||||
|
||||
if( (mesh_topo_store->index_lookup==NULL) ||
|
||||
@ -869,33 +869,36 @@ int ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t *
|
||||
|
||||
}
|
||||
|
||||
void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store)
|
||||
void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store,
|
||||
const short skip_em_vert_array_init)
|
||||
{
|
||||
MEdge *medge;
|
||||
EditMesh *em= me->edit_mesh;
|
||||
void **eve_tmp_back= NULL; /* some of the callers are using eve->tmp so restore after */
|
||||
EditMesh *em = me->edit_mesh;
|
||||
void **eve_tmp_back = NULL; /* some of the callers are using eve->tmp so restore after */
|
||||
|
||||
/* editmode*/
|
||||
EditEdge *eed;
|
||||
|
||||
int a, last;
|
||||
int totvert, totedge;
|
||||
int totUnique= -1, totUniqueOld= -1;
|
||||
int tot_unique = -1, tot_unique_prev = -1;
|
||||
|
||||
MirrTopoHash_t *MirrTopoHash = NULL;
|
||||
MirrTopoHash_t *MirrTopoHash_Prev = NULL;
|
||||
MirrTopoPair_t *MirrTopoPairs;
|
||||
MirrTopoHash_t *topo_hash = NULL;
|
||||
MirrTopoHash_t *topo_hash_prev = NULL;
|
||||
MirrTopoVert_t *topo_pairs;
|
||||
|
||||
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;
|
||||
mesh_topo_store->prev_ob_mode = ob_mode;
|
||||
|
||||
if(em) {
|
||||
EditVert *eve;
|
||||
totvert= 0;
|
||||
eve_tmp_back= MEM_callocN( em->totvert * sizeof(void *), "TopoMirr" );
|
||||
for(eve= em->verts.first; eve; eve= eve->next) {
|
||||
totvert = 0;
|
||||
eve_tmp_back = MEM_mallocN(em->totvert * sizeof(void *), "TopoMirr");
|
||||
for(eve = em->verts.first; eve; eve = eve->next) {
|
||||
eve_tmp_back[totvert]= eve->tmp.p;
|
||||
eve->tmp.l = totvert++;
|
||||
}
|
||||
@ -904,130 +907,139 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
|
||||
totvert = me->totvert;
|
||||
}
|
||||
|
||||
MirrTopoHash = MEM_callocN( totvert * sizeof(MirrTopoHash_t), "TopoMirr" );
|
||||
topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr");
|
||||
|
||||
/* Initialize the vert-edge-user counts used to detect unique topology */
|
||||
if(em) {
|
||||
totedge= 0;
|
||||
totedge = 0;
|
||||
|
||||
for(eed=em->edges.first; eed; eed= eed->next, totedge++) {
|
||||
MirrTopoHash[eed->v1->tmp.l]++;
|
||||
MirrTopoHash[eed->v2->tmp.l]++;
|
||||
for(eed=em->edges.first; eed; eed = eed->next, totedge++) {
|
||||
topo_hash[eed->v1->tmp.l]++;
|
||||
topo_hash[eed->v2->tmp.l]++;
|
||||
}
|
||||
} else {
|
||||
totedge= me->totedge;
|
||||
}
|
||||
else {
|
||||
totedge = me->totedge;
|
||||
|
||||
for(a=0, medge=me->medge; a < me->totedge; a++, medge++) {
|
||||
MirrTopoHash[medge->v1]++;
|
||||
MirrTopoHash[medge->v2]++;
|
||||
topo_hash[medge->v1]++;
|
||||
topo_hash[medge->v2]++;
|
||||
}
|
||||
}
|
||||
|
||||
MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash );
|
||||
topo_hash_prev = MEM_dupallocN(topo_hash);
|
||||
|
||||
totUniqueOld = -1;
|
||||
tot_unique_prev = -1;
|
||||
while(1) {
|
||||
/* use the number of edges per vert to give verts unique topology IDs */
|
||||
|
||||
if(em) {
|
||||
for(eed=em->edges.first; eed; eed= eed->next) {
|
||||
MirrTopoHash[eed->v1->tmp.l] += MirrTopoHash_Prev[eed->v2->tmp.l];
|
||||
MirrTopoHash[eed->v2->tmp.l] += MirrTopoHash_Prev[eed->v1->tmp.l];
|
||||
for(eed=em->edges.first; eed; eed = eed->next) {
|
||||
topo_hash[eed->v1->tmp.l] += topo_hash_prev[eed->v2->tmp.l];
|
||||
topo_hash[eed->v2->tmp.l] += topo_hash_prev[eed->v1->tmp.l];
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
for(a=0, medge=me->medge; a<me->totedge; a++, medge++) {
|
||||
/* This can make really big numbers, wrapping around here is fine */
|
||||
MirrTopoHash[medge->v1] += MirrTopoHash_Prev[medge->v2];
|
||||
MirrTopoHash[medge->v2] += MirrTopoHash_Prev[medge->v1];
|
||||
topo_hash[medge->v1] += topo_hash_prev[medge->v2];
|
||||
topo_hash[medge->v2] += topo_hash_prev[medge->v1];
|
||||
}
|
||||
}
|
||||
memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert);
|
||||
memcpy(topo_hash_prev, topo_hash, sizeof(MirrTopoHash_t) * totvert);
|
||||
|
||||
/* sort so we can count unique values */
|
||||
qsort(MirrTopoHash_Prev, totvert, sizeof(MirrTopoHash_t), MirrTopo_long_sort);
|
||||
qsort(topo_hash_prev, totvert, sizeof(MirrTopoHash_t), mirrtopo_hash_sort);
|
||||
|
||||
totUnique = 1; /* account for skiping the first value */
|
||||
tot_unique = 1; /* account for skiping the first value */
|
||||
for(a=1; a<totvert; a++) {
|
||||
if (MirrTopoHash_Prev[a-1] != MirrTopoHash_Prev[a]) {
|
||||
totUnique++;
|
||||
if (topo_hash_prev[a-1] != topo_hash_prev[a]) {
|
||||
tot_unique++;
|
||||
}
|
||||
}
|
||||
|
||||
if (totUnique <= totUniqueOld) {
|
||||
if (tot_unique <= tot_unique_prev) {
|
||||
/* Finish searching for unique valus when 1 loop dosnt give a
|
||||
* higher number of unique values compared to the previous loop */
|
||||
break;
|
||||
} else {
|
||||
totUniqueOld = totUnique;
|
||||
}
|
||||
else {
|
||||
tot_unique_prev = tot_unique;
|
||||
}
|
||||
/* Copy the hash calculated this iter, so we can use them next time */
|
||||
memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert);
|
||||
memcpy(topo_hash_prev, topo_hash, sizeof(MirrTopoHash_t) * totvert);
|
||||
}
|
||||
|
||||
/* restore eve->tmp.* */
|
||||
if(eve_tmp_back) {
|
||||
EditVert *eve;
|
||||
totvert= 0;
|
||||
for(eve= em->verts.first; eve; eve= eve->next) {
|
||||
eve->tmp.p= eve_tmp_back[totvert++];
|
||||
totvert = 0;
|
||||
for(eve = em->verts.first; eve; eve = eve->next) {
|
||||
eve->tmp.p = eve_tmp_back[totvert++];
|
||||
}
|
||||
|
||||
MEM_freeN(eve_tmp_back);
|
||||
eve_tmp_back= NULL;
|
||||
eve_tmp_back = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Hash/Index pairs are needed for sorting to find index pairs */
|
||||
MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair_t) * totvert, "MirrTopoPairs");
|
||||
topo_pairs = MEM_callocN( sizeof(MirrTopoVert_t) * totvert, "MirrTopoPairs");
|
||||
|
||||
/* since we are looping through verts, initialize these values here too */
|
||||
mesh_topo_store->index_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" );
|
||||
index_lookup = MEM_mallocN(totvert * sizeof(*index_lookup), "mesh_topo_lookup");
|
||||
|
||||
if(em) {
|
||||
EM_init_index_arrays(em,1,0,0);
|
||||
if (skip_em_vert_array_init == FALSE) {
|
||||
EM_init_index_arrays(em, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(a=0; a<totvert; a++) {
|
||||
MirrTopoPairs[a].hash= MirrTopoHash[a];
|
||||
MirrTopoPairs[a].v_index = a;
|
||||
topo_pairs[a].hash = topo_hash[a];
|
||||
topo_pairs[a].v_index = a;
|
||||
|
||||
/* initialize lookup */
|
||||
mesh_topo_store->index_lookup[a] = -1;
|
||||
index_lookup[a] = -1;
|
||||
}
|
||||
|
||||
qsort(MirrTopoPairs, totvert, sizeof(MirrTopoPair_t), MirrTopo_item_sort);
|
||||
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) && (MirrTopoPairs[0].hash == MirrTopoPairs[1].hash)) ? 0 : 1;
|
||||
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 ].vIndex ); */
|
||||
if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) {
|
||||
if ((a==totvert) || (topo_pairs[a-1].hash != topo_pairs[a].hash)) {
|
||||
if (a-last==2) {
|
||||
if(em) {
|
||||
mesh_topo_store->index_lookup[MirrTopoPairs[a-1].v_index] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-2].v_index);
|
||||
mesh_topo_store->index_lookup[MirrTopoPairs[a-2].v_index] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-1].v_index);
|
||||
} else {
|
||||
mesh_topo_store->index_lookup[MirrTopoPairs[a-1].v_index] = MirrTopoPairs[a-2].v_index;
|
||||
mesh_topo_store->index_lookup[MirrTopoPairs[a-2].v_index] = MirrTopoPairs[a-1].v_index;
|
||||
index_lookup[topo_pairs[a-1].v_index] = (intptr_t)EM_get_vert_for_index(topo_pairs[a-2].v_index);
|
||||
index_lookup[topo_pairs[a-2].v_index] = (intptr_t)EM_get_vert_for_index(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;
|
||||
last = a;
|
||||
}
|
||||
}
|
||||
if(em) {
|
||||
EM_free_index_arrays();
|
||||
if (skip_em_vert_array_init == FALSE) {
|
||||
EM_free_index_arrays();
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN( MirrTopoPairs );
|
||||
MirrTopoPairs = NULL;
|
||||
MEM_freeN(topo_pairs);
|
||||
topo_pairs = NULL;
|
||||
|
||||
MEM_freeN( MirrTopoHash );
|
||||
MEM_freeN( MirrTopoHash_Prev );
|
||||
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;
|
||||
}
|
||||
|
@ -861,7 +861,7 @@ int mesh_mirrtopo_table(Object *ob, char mode)
|
||||
}
|
||||
}
|
||||
else if(mode=='s') { /* start table */
|
||||
ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store);
|
||||
ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store, FALSE);
|
||||
}
|
||||
else if(mode=='e') { /* end table */
|
||||
ED_mesh_mirrtopo_free(&mesh_topo_store);
|
||||
|
Loading…
Reference in New Issue
Block a user