Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-12-20 14:05:58 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-12-20 14:05:58 +0400
commitb70174cb9350868e9dd26139a8980406b18415b8 (patch)
tree0bed4fa3d079e1444d72343d4fdb82a342cabde8 /source/blender/editors/mesh
parent2bfad340ff479d43831b43000c94a5c72f53416c (diff)
move topology mirror out into its own functions - needed for bmesh branch so we can use then for bmeshes own internal mirror calculations.
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/editface.c226
-rw-r--r--source/blender/editors/mesh/meshtools.c222
2 files changed, 237 insertions, 211 deletions
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 02d20e64bc3..95c71488d26 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -815,3 +815,229 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend)
return OPERATOR_FINISHED;
}
+
+
+/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */
+/* note, this is not the best place for the function to be but moved
+ * here to for the purpose of syncing with bmesh */
+
+typedef int MirrTopoHash_t;
+
+typedef struct MirrTopoPair_t {
+ MirrTopoHash_t hash;
+ int v_index;
+} MirrTopoPair_t;
+
+static int MirrTopo_long_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)
+{
+ if (((MirrTopoPair_t *)v1)->hash > ((MirrTopoPair_t *)v2)->hash ) return 1;
+ else if (((MirrTopoPair_t *)v1)->hash < ((MirrTopoPair_t *)v2)->hash ) return -1;
+ return 0;
+}
+
+int ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store)
+{
+ int totvert;
+ int totedge;
+
+ if (me->edit_mesh) {
+ totvert= me->edit_mesh->totvert;
+ totedge= me->edit_mesh->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, const int ob_mode, MirrTopoStore_t *mesh_topo_store)
+{
+ MEdge *medge;
+ 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;
+
+ MirrTopoHash_t *MirrTopoHash = NULL;
+ MirrTopoHash_t *MirrTopoHash_Prev = NULL;
+ MirrTopoPair_t *MirrTopoPairs;
+
+ /* reallocate if needed */
+ ED_mesh_mirrtopo_free(mesh_topo_store);
+
+ 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) {
+ eve_tmp_back[totvert]= eve->tmp.p;
+ eve->tmp.l = totvert++;
+ }
+ }
+ else {
+ totvert = me->totvert;
+ }
+
+ MirrTopoHash = MEM_callocN( totvert * sizeof(MirrTopoHash_t), "TopoMirr" );
+
+ /* Initialize the vert-edge-user counts used to detect unique topology */
+ if(em) {
+ totedge= 0;
+
+ for(eed=em->edges.first; eed; eed= eed->next, totedge++) {
+ MirrTopoHash[eed->v1->tmp.l]++;
+ MirrTopoHash[eed->v2->tmp.l]++;
+ }
+ } else {
+ totedge= me->totedge;
+
+ for(a=0, medge=me->medge; a < me->totedge; a++, medge++) {
+ MirrTopoHash[medge->v1]++;
+ MirrTopoHash[medge->v2]++;
+ }
+ }
+
+ MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash );
+
+ totUniqueOld = -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];
+ }
+ } 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];
+ }
+ }
+ memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert);
+
+ /* sort so we can count unique values */
+ qsort(MirrTopoHash_Prev, totvert, sizeof(MirrTopoHash_t), MirrTopo_long_sort);
+
+ totUnique = 1; /* account for skiping the first value */
+ for(a=1; a<totvert; a++) {
+ if (MirrTopoHash_Prev[a-1] != MirrTopoHash_Prev[a]) {
+ totUnique++;
+ }
+ }
+
+ if (totUnique <= totUniqueOld) {
+ /* 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;
+ }
+ /* Copy the hash calculated this iter, so we can use them next time */
+ memcpy(MirrTopoHash_Prev, MirrTopoHash, 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++];
+ }
+
+ MEM_freeN(eve_tmp_back);
+ eve_tmp_back= NULL;
+ }
+
+
+ /* Hash/Index pairs are needed for sorting to find index pairs */
+ MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair_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" );
+
+ if(em) {
+ EM_init_index_arrays(em,1,0,0);
+ }
+
+
+ for(a=0; a<totvert; a++) {
+ MirrTopoPairs[a].hash= MirrTopoHash[a];
+ MirrTopoPairs[a].v_index = a;
+
+ /* initialize lookup */
+ mesh_topo_store->index_lookup[a] = -1;
+ }
+
+ qsort(MirrTopoPairs, totvert, sizeof(MirrTopoPair_t), MirrTopo_item_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;
+
+ /* 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-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;
+ }
+ }
+ last= a;
+ }
+ }
+ if(em) {
+ EM_free_index_arrays();
+ }
+
+ MEM_freeN( MirrTopoPairs );
+ MirrTopoPairs = NULL;
+
+ MEM_freeN( MirrTopoHash );
+ MEM_freeN( MirrTopoHash_Prev );
+
+ 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;
+}
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index dd82f055f14..77daf21affa 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -765,7 +765,7 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
if(mode=='u') { /* use table */
if(MeshOctree.table==NULL)
mesh_octree_table(ob, em, NULL, 's');
-
+
if(MeshOctree.table) {
Mesh *me= ob->data;
bt= MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div);
@@ -848,34 +848,7 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
return 0;
}
-
-/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */
-
-typedef int MirrTopoHash_t;
-
-typedef struct MirrTopoPair_t {
- MirrTopoHash_t hash;
- int vIndex;
-} MirrTopoPair_t;
-
-static int MirrTopo_long_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)
-{
- if (((MirrTopoPair_t *)v1)->hash > ((MirrTopoPair_t *)v2)->hash ) return 1;
- else if (((MirrTopoPair_t *)v1)->hash < ((MirrTopoPair_t *)v2)->hash ) return -1;
- return 0;
-}
-
-static intptr_t *mesh_topo_lookup = NULL;
-static int mesh_topo_lookup_vert_tot = -1;
-static int mesh_topo_lookup_edge_tot = -1;
-static int mesh_topo_lookup_mode = -1;
+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 */
@@ -883,188 +856,15 @@ static int mesh_topo_lookup_mode = -1;
int mesh_mirrtopo_table(Object *ob, char mode)
{
if(mode=='u') { /* use table */
- Mesh *me= ob->data;
- if( (mesh_topo_lookup==NULL) ||
- (mesh_topo_lookup_mode != ob->mode) ||
- (me->edit_mesh && (me->edit_mesh->totvert != mesh_topo_lookup_vert_tot)) ||
- (me->edit_mesh && (me->edit_mesh->totedge != mesh_topo_lookup_edge_tot)) ||
- (me->edit_mesh==NULL && me->totvert != mesh_topo_lookup_vert_tot) ||
- (me->edit_mesh==NULL && me->totedge != mesh_topo_lookup_edge_tot)
- ) {
+ if (ED_mesh_mirrtopo_recalc_check(ob->data, ob->mode, &mesh_topo_store)) {
mesh_mirrtopo_table(ob, 's');
}
- } else if(mode=='s') { /* start table */
- Mesh *me= ob->data;
- MEdge *medge;
- 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;
-
- MirrTopoHash_t *MirrTopoHash = NULL;
- MirrTopoHash_t *MirrTopoHash_Prev = NULL;
- MirrTopoPair_t *MirrTopoPairs;
- mesh_topo_lookup_mode= ob->mode;
-
- /* reallocate if needed */
- if (mesh_topo_lookup) {
- MEM_freeN(mesh_topo_lookup);
- mesh_topo_lookup = NULL;
- }
-
- 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) {
- eve_tmp_back[totvert]= eve->tmp.p;
- eve->tmp.l = totvert++;
- }
- }
- else {
- totvert = me->totvert;
- }
-
- MirrTopoHash = MEM_callocN( totvert * sizeof(MirrTopoHash_t), "TopoMirr" );
-
- /* Initialize the vert-edge-user counts used to detect unique topology */
- if(em) {
- totedge= 0;
-
- for(eed=em->edges.first; eed; eed= eed->next, totedge++) {
- MirrTopoHash[eed->v1->tmp.l]++;
- MirrTopoHash[eed->v2->tmp.l]++;
- }
- } else {
- totedge= me->totedge;
-
- for(a=0, medge=me->medge; a < me->totedge; a++, medge++) {
- MirrTopoHash[medge->v1]++;
- MirrTopoHash[medge->v2]++;
- }
- }
-
- MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash );
-
- totUniqueOld = -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];
- }
- } 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];
- }
- }
- memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert);
-
- /* sort so we can count unique values */
- qsort(MirrTopoHash_Prev, totvert, sizeof(MirrTopoHash_t), MirrTopo_long_sort);
-
- totUnique = 1; /* account for skiping the first value */
- for(a=1; a<totvert; a++) {
- if (MirrTopoHash_Prev[a-1] != MirrTopoHash_Prev[a]) {
- totUnique++;
- }
- }
-
- if (totUnique <= totUniqueOld) {
- /* 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;
- }
- /* Copy the hash calculated this iter, so we can use them next time */
- memcpy(MirrTopoHash_Prev, MirrTopoHash, 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++];
- }
-
- MEM_freeN(eve_tmp_back);
- eve_tmp_back= NULL;
- }
-
-
- /* Hash/Index pairs are needed for sorting to find index pairs */
- MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair_t) * totvert, "MirrTopoPairs");
-
- /* since we are looping through verts, initialize these values here too */
- mesh_topo_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" );
-
- if(em) {
- EM_init_index_arrays(em,1,0,0);
- }
-
-
- for(a=0; a<totvert; a++) {
- MirrTopoPairs[a].hash= MirrTopoHash[a];
- MirrTopoPairs[a].vIndex = a;
-
- /* initialize lookup */
- mesh_topo_lookup[a] = -1;
- }
-
- qsort(MirrTopoPairs, totvert, sizeof(MirrTopoPair_t), MirrTopo_item_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;
-
- /* 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+1; 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-last==2) {
- if(em) {
- mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-2].vIndex);
- mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-1].vIndex);
- } else {
- mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = MirrTopoPairs[a-2].vIndex;
- mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = MirrTopoPairs[a-1].vIndex;
- }
- }
- last= a;
- }
- }
- if(em) {
- EM_free_index_arrays();
- }
-
- MEM_freeN( MirrTopoPairs );
- MirrTopoPairs = NULL;
-
- MEM_freeN( MirrTopoHash );
- MEM_freeN( MirrTopoHash_Prev );
-
- mesh_topo_lookup_vert_tot = totvert;
- mesh_topo_lookup_edge_tot = totedge;
-
- } else if(mode=='e') { /* end table */
- if (mesh_topo_lookup) {
- MEM_freeN(mesh_topo_lookup);
- }
- mesh_topo_lookup = NULL;
- mesh_topo_lookup_vert_tot= -1;
- mesh_topo_lookup_edge_tot= -1;
+ }
+ else if(mode=='s') { /* start table */
+ ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store);
+ }
+ else if(mode=='e') { /* end table */
+ ED_mesh_mirrtopo_free(&mesh_topo_store);
}
return 0;
}
@@ -1088,7 +888,7 @@ static int mesh_get_x_mirror_vert_topo(Object *ob, int index)
if (mesh_mirrtopo_table(ob, 'u')==-1)
return -1;
- return mesh_topo_lookup[index];
+ return mesh_topo_store.index_lookup[index];
}
int mesh_get_x_mirror_vert(Object *ob, int index)
@@ -1136,7 +936,7 @@ static EditVert *editmesh_get_x_mirror_vert_topo(Object *ob, struct EditMesh *em
}
}
- poinval= mesh_topo_lookup[ index ];
+ poinval= mesh_topo_store.index_lookup[index];
if(poinval != -1)
return (EditVert *)(poinval);