svn merge ^/trunk/blender -r42759:42761
authorCampbell Barton <ideasman42@gmail.com>
Tue, 20 Dec 2011 21:28:57 +0000 (21:28 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 20 Dec 2011 21:28:57 +0000 (21:28 +0000)
1  2 
source/blender/editors/include/ED_mesh.h
source/blender/editors/mesh/editface.c
source/blender/editors/mesh/meshtools.c
source/blender/modifiers/intern/MOD_uvproject.c

index 6415a440f901485335b0b8e924e86fbd7a9e424a,3a69db013c0b93819e0984d05b3d73b476e4d570..9a2bce910fc58819edba41760abea32eae1a75cf
@@@ -298,11 -243,19 +298,24 @@@ int ED_mesh_color_add(struct bContext *
  int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct Mesh *me);
  int ED_mesh_color_remove_named(struct bContext *C, struct Object *ob, struct Mesh *me, const char *name);
  
 +void EDBM_selectmode_to_scene(struct bContext *C);
 +void EDBM_ClearMesh(struct BMEditMesh *em);
 +
 +#include "../mesh/editbmesh_bvh.h"
 +
+ /* mirrtopo */
+ typedef struct MirrTopoStore_t {
+       intptr_t *index_lookup;
+       int       prev_vert_tot;
+       int       prev_edge_tot;
+       int       prev_ob_mode;
+ } 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_free(MirrTopoStore_t *mesh_topo_store);
  #ifdef __cplusplus
  }
  #endif
index 36e9f2db58f2825712e9b55c928850709cc573e4,95c71488d26621dde5ffea3dd497480259fca017..5fed77c6f5d1cbc88d6434f259f7f3bdae9b4105
@@@ -670,99 -817,227 +670,304 @@@ int do_paintface_box_select(ViewContex
  }
  
  
 -      if (me->edit_mesh) {
 -              totvert= me->edit_mesh->totvert;
 -              totedge= me->edit_mesh->totedge;
 +/*  (similar to void paintface_flush_flags(Object *ob))
 + * copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
 + * use in object mode when selecting vertices (while painting) */
 +void paintvert_flush_flags(Object *ob)
 +{
 +      Mesh *me= get_mesh(ob);
 +      DerivedMesh *dm= ob->derivedFinal;
 +      MVert *dm_mvert, *dm_mv;
 +      int *index_array = NULL;
 +      int totvert;
 +      int i;
 +
 +      if(me==NULL || dm==NULL)
 +              return;
 +
 +      index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
 +
 +      dm_mvert = dm->getVertArray(dm);
 +      totvert = dm->getNumVerts(dm);
 +
 +      dm_mv= dm_mvert;
 +
 +      if(index_array) {
 +              int orig_index;
 +              for (i= 0; i<totvert; i++, dm_mv++) {
 +                      orig_index= index_array[i];
 +                      if(orig_index != ORIGINDEX_NONE) {
 +                              dm_mv->flag= me->mvert[index_array[i]].flag;
 +                      }
 +              }
 +      }
 +      else {
 +              for (i= 0; i<totvert; i++, dm_mv++) {
 +                      dm_mv->flag= me->mvert[i].flag;
 +              }
 +      }
 +}
 +/*  note: if the caller passes FALSE to flush_flags, then they will need to run paintvert_flush_flags(ob) themselves */
 +void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags)
 +{
 +      Mesh *me;
 +      MVert *mvert;
 +      int a;
 +
 +      me= get_mesh(ob);
 +      if(me==NULL) return;
 +      
 +      if(action == SEL_INVERT) {
 +              mvert= me->mvert;
 +              a= me->totvert;
 +              while(a--) {
 +                      if((mvert->flag & ME_HIDE) == 0) {
 +                              mvert->flag ^= SELECT;
 +                      }
 +                      mvert++;
 +              }
 +      }
 +      else {
 +              if (action == SEL_TOGGLE) {
 +                      action = SEL_SELECT;
 +
 +                      mvert= me->mvert;
 +                      a= me->totvert;
 +                      while(a--) {
 +                              if((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
 +                                      action = SEL_DESELECT;
 +                                      break;
 +                              }
 +                              mvert++;
 +                      }
 +              }
 +
 +              mvert= me->mvert;
 +              a= me->totvert;
 +              while(a--) {
 +                      if((mvert->flag & ME_HIDE) == 0) {
 +                              switch (action) {
 +                              case SEL_SELECT:
 +                                      mvert->flag |= SELECT;
 +                                      break;
 +                              case SEL_DESELECT:
 +                                      mvert->flag &= ~SELECT;
 +                                      break;
 +                              case SEL_INVERT:
 +                                      mvert->flag ^= SELECT;
 +                                      break;
 +                              }
 +                      }
 +                      mvert++;
 +              }
 +      }
 +
 +      if(flush_flags) {
 +              paintvert_flush_flags(ob);
 +      }
 +}
++
++
+ /* ********************* 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;
 -      EditMesh *em= me->edit_mesh;
 -      void **eve_tmp_back= NULL; /* some of the callers are using eve->tmp so restore after */
 -
 -      /* editmode*/
 -      EditEdge *eed;
 -
++      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_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;
 -              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++;
 -              }
++      BMEditMesh *em= me->edit_btmesh;
++      BMEdge *eed;
++      BMIter iter;
+       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) {
 -              totedge= 0;
 -
 -              for(eed=em->edges.first; eed; eed= eed->next, totedge++) {
 -                      MirrTopoHash[eed->v1->tmp.l]++;
 -                      MirrTopoHash[eed->v2->tmp.l]++;
++              BM_ElemIndex_Ensure(em->bm, BM_VERT);
++
++              totvert= em->bm->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) {
 -                      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];
++              totedge= me->edit_btmesh->bm->totedge;
++              BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
++                      MirrTopoHash[BM_GetIndex(eed->v1)]++;
++                      MirrTopoHash[BM_GetIndex(eed->v2)]++;
+               }
+       } 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) {
 -      /* 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;
 -      }
 -
 -
++                      BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
++                              MirrTopoHash[BM_GetIndex(eed->v1)] += MirrTopoHash_Prev[BM_GetIndex(eed->v2)];
++                              MirrTopoHash[BM_GetIndex(eed->v2)] += MirrTopoHash_Prev[BM_GetIndex(eed->v1)];
+                       }
+               } 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);
+       }
 -              EM_init_index_arrays(em,1,0,0);
+       /* 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) {
 -              /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a  ].hash, MirrTopoPairs[a  ].vIndex ); */
++              EDBM_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++) {
 -                                      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);
++              /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a  ].hash, MirrTopoPairs[a  ].v_index ); */
+               if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) {
+                       if (a-last==2) {
+                               if(em) {
 -              EM_free_index_arrays();
++                                      mesh_topo_store->index_lookup[MirrTopoPairs[a-1].v_index] =     (intptr_t)EDBM_get_vert_for_index(em, MirrTopoPairs[a-2].v_index);
++                                      mesh_topo_store->index_lookup[MirrTopoPairs[a-2].v_index] =     (intptr_t)EDBM_get_vert_for_index(em, 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) {
++              EDBM_free_index_arrays(em);
+       }
+       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;
+ }
index cea0e3739f76acfe83fee022835dc2fc7962ded3,77daf21affa3740c6b080183ae398bb4f64ef624..25648b265263a90895393bd200b0b201c444ffd4
@@@ -1177,10 -936,10 +998,10 @@@ static BMVert *editbmesh_get_x_mirror_v
                }
        }
  
-       poinval= mesh_topo_lookup[ index ];
+       poinval= mesh_topo_store.index_lookup[index];
  
        if(poinval != -1)
 -              return (EditVert *)(poinval);
 +              return (BMVert *)(poinval);
        return NULL;
  }