Revision: 15214
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15214
Author:   campbellbarton
Date:     2008-06-13 14:33:35 +0200 (Fri, 13 Jun 2008)

Log Message:
-----------
Topology Mirror. Find mirror verts based on topology, ignoring vertex location, 
Currently works with transform and weight painting.
Tested with 5 peach characters and Suzanne (without eyes), rely's on both verts 
being uniquely positioned in relation to the surrounding edge topology. useful 
when weight painting asymmetric characters.

Modified Paths:
--------------
    branches/apricot/source/blender/include/BIF_meshtools.h
    branches/apricot/source/blender/include/blendef.h
    branches/apricot/source/blender/src/buttons_editing.c
    branches/apricot/source/blender/src/editmesh.c
    branches/apricot/source/blender/src/editmesh_mods.c
    branches/apricot/source/blender/src/meshtools.c
    branches/apricot/source/blender/src/transform_conversions.c
    branches/apricot/source/blender/src/vpaint.c

Modified: branches/apricot/source/blender/include/BIF_meshtools.h
===================================================================
--- branches/apricot/source/blender/include/BIF_meshtools.h     2008-06-13 
02:20:09 UTC (rev 15213)
+++ branches/apricot/source/blender/include/BIF_meshtools.h     2008-06-13 
12:33:35 UTC (rev 15214)
@@ -41,8 +41,9 @@
 extern void objects_bake_render(short event, char **error_msg);
 
 extern long mesh_octree_table(struct Object *ob, float *co, char mode);
+extern long mesh_mirrtopo_table(struct Object *ob, char mode);
 extern int mesh_get_x_mirror_vert(struct Object *ob, int index);
-extern struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, float 
*co);
+extern struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, struct 
EditVert *eve);
 extern float *editmesh_get_mirror_uv(int axis, float *co, float *mirrCent, 
float *face_cent);
 extern int *mesh_get_x_mirror_faces(struct Object *ob);
 

Modified: branches/apricot/source/blender/include/blendef.h
===================================================================
--- branches/apricot/source/blender/include/blendef.h   2008-06-13 02:20:09 UTC 
(rev 15213)
+++ branches/apricot/source/blender/include/blendef.h   2008-06-13 12:33:35 UTC 
(rev 15214)
@@ -446,7 +446,9 @@
 #define B_JOINTRIA_VCOL                0X400
 #define B_JOINTRIA_SHARP       0X800
 #define B_JOINTRIA_MAT         0X1000
+#define B_MIRROR_TOPO          0X2000 /* Topology Mirroring, disabled by 
default */
 
+
 /* DISPLAYMODE */
 #define R_DISPLAYIMAGE 0
 #define R_DISPLAYWIN   1

Modified: branches/apricot/source/blender/src/buttons_editing.c
===================================================================
--- branches/apricot/source/blender/src/buttons_editing.c       2008-06-13 
02:20:09 UTC (rev 15213)
+++ branches/apricot/source/blender/src/buttons_editing.c       2008-06-13 
12:33:35 UTC (rev 15214)
@@ -5086,7 +5086,8 @@
        
        uiBlockBeginAlign(block);
        uiDefButBitI(block, TOG, G_ALLEDGES, 0, "All Edges",                    
1125, 22,150,19, &G.f, 0, 0, 0, 0, "Displays all edges in object mode without 
optimization");
-       uiDefButBitS(block, TOG, B_MESH_X_MIRROR, B_DIFF, "X-axis 
mirror",1125,0,150,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "While 
using transforms, mirrors the transformation");
+       uiDefButBitS(block, TOG, B_MESH_X_MIRROR, B_DIFF, "X-Axis 
Mirror",1125,0,80,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "While 
using transforms, mirrors the transformation");
+       uiDefButBitS(block, TOG, B_MIRROR_TOPO, B_DIFF, 
"Topology",1125+80,0,70,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, 
"Calculate mirror from mesh topology");    
        uiBlockEndAlign(block);
 }
 
@@ -6077,7 +6078,8 @@
        if(ob) {
                uiBlockBeginAlign(block);
                uiDefButBitS(block, TOG, VP_ONLYVGROUP, REDRAWVIEW3D, "Vgroup", 
        10,0,100,19, &Gwp.flag, 0, 0, 0, 0, "Only paint on vertices in the 
selected vertex group.");
-               uiDefButBitS(block, TOG, VP_MIRROR_X, REDRAWVIEW3D, "X-Mirror", 
110,0,100,19, &Gwp.flag, 0, 0, 0, 0, "Mirrored Paint, applying on mirrored 
Weight Group name");
+               uiDefButBitS(block, TOG, VP_MIRROR_X, REDRAWVIEW3D, "X-Mirror", 
110,0,80,19, &Gwp.flag, 0, 0, 0, 0, "Mirrored Paint, applying on mirrored 
Weight Group name");
+               uiDefButBitS(block, TOG, B_MIRROR_TOPO, B_DIFF, 
"T",110+80,0,20,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "Calculate 
mirror from mesh topology"); /* TODO - Put this in a nicer place */
                uiDefBut(block, BUT, B_CLR_WPAINT, "Clear",                     
                210,0,100,19, NULL, 0, 0, 0, 0, "Removes reference to this 
deform group from all vertices");
                uiBlockEndAlign(block);
        }

Modified: branches/apricot/source/blender/src/editmesh.c
===================================================================
--- branches/apricot/source/blender/src/editmesh.c      2008-06-13 02:20:09 UTC 
(rev 15213)
+++ branches/apricot/source/blender/src/editmesh.c      2008-06-13 12:33:35 UTC 
(rev 15214)
@@ -627,6 +627,7 @@
        em->allfaces= em->curface= NULL;
        
        mesh_octree_table(NULL, NULL, 'e');
+       mesh_mirrtopo_table(NULL, 'e');
        
        G.totvert= G.totface= 0;
 

Modified: branches/apricot/source/blender/src/editmesh_mods.c
===================================================================
--- branches/apricot/source/blender/src/editmesh_mods.c 2008-06-13 02:20:09 UTC 
(rev 15213)
+++ branches/apricot/source/blender/src/editmesh_mods.c 2008-06-13 12:33:35 UTC 
(rev 15214)
@@ -120,7 +120,7 @@
                
                for(eve= em->verts.first; eve; eve= eve->next) {
                        if(eve->f & SELECT) {
-                               v1= editmesh_get_x_mirror_vert(G.obedit, 
eve->co);
+                               v1= editmesh_get_x_mirror_vert(G.obedit, eve);
                                if(v1) {
                                        eve->f &= ~SELECT;
                                        v1->f |= SELECT;
@@ -4249,7 +4249,7 @@
                        if(eve->f1) {
                                
                                if (G.scene->toolsettings->editbutflag & 
B_MESH_X_MIRROR) {
-                                       eve_mir= 
editmesh_get_x_mirror_vert(G.obedit, eve->co);
+                                       eve_mir= 
editmesh_get_x_mirror_vert(G.obedit, eve);
                                }
                                
                                adr = eve->tmp.p;

Modified: branches/apricot/source/blender/src/meshtools.c
===================================================================
--- branches/apricot/source/blender/src/meshtools.c     2008-06-13 02:20:09 UTC 
(rev 15213)
+++ branches/apricot/source/blender/src/meshtools.c     2008-06-13 12:33:35 UTC 
(rev 15214)
@@ -837,8 +837,192 @@
        return 0;
 }
 
-int mesh_get_x_mirror_vert(Object *ob, int index)
+
+/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */
+
+#define MIRRHASH_TYPE int
+
+typedef struct MirrTopoPair {
+       long hash;
+       int vIndex;
+} MirrTopoPair;
+
+/* sort faces on view axis */
+static int MirrTopo_long_sort(const void *l1, const void *l2)
+{      
+       if(                     (MIRRHASH_TYPE)l1 > (MIRRHASH_TYPE)l2 ) return  
1;
+       else if(        (MIRRHASH_TYPE)l1 < (MIRRHASH_TYPE)l2 ) return -1;
+       return 0;
+}
+
+static int MirrTopo_item_sort(const void *v1, const void *v2)
 {
+       if(                     ((MirrTopoPair *)v1)->hash > ((MirrTopoPair 
*)v2)->hash ) return  1;
+       else if(        ((MirrTopoPair *)v1)->hash < ((MirrTopoPair *)v2)->hash 
) return -1;
+       return 0;
+}
+
+static long *mesh_topo_lookup = NULL;
+static int  mesh_topo_lookup_tot = -1;
+
+/* mode is 's' start, or 'e' end, or 'u' use */
+/* if end, ob can be NULL */
+long mesh_mirrtopo_table(Object *ob, char mode)
+{
+       if(mode=='u') {         /* use table */
+               Mesh *me= ob->data;
+               if (!mesh_topo_lookup || (me->totvert != mesh_topo_lookup_tot)) 
{
+                       mesh_mirrtopo_table(ob, 's');
+               }
+       } else if(mode=='s') { /* start table */
+               Mesh *me= ob->data;
+               MEdge *medge;
+               
+               /* editmode*/
+               EditEdge *eed;
+               
+               int a, last, totvert;
+               int totUnique= -1, totUniqueOld= -1;
+
+
+               MIRRHASH_TYPE *MirrTopoHash = NULL;
+               MIRRHASH_TYPE *MirrTopoHash_Prev = NULL;
+               MirrTopoPair *MirrTopoPairs;
+               
+               /* reallocate if needed */
+               if (mesh_topo_lookup) {
+                       MEM_freeN(mesh_topo_lookup);
+                       mesh_topo_lookup = NULL;
+               }
+
+               if(ob==G.obedit) {
+                       EditVert *eve;
+                       totvert= 0;
+                       for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
+                               eve->tmp.l = totvert++;
+                       }
+               } else {
+                       totvert = me->totvert;
+               }
+               
+               MirrTopoHash = MEM_callocN( totvert * sizeof(MIRRHASH_TYPE), 
"TopoMirr" );
+               
+               /* Initialize the vert-edge-user counts used to detect unique 
topology */
+               if(ob==G.obedit) {
+                       for(eed=G.editMesh->edges.first; eed; eed= eed->next) {
+                               MirrTopoHash[eed->v1->tmp.l]++;
+                               MirrTopoHash[eed->v2->tmp.l]++;
+                       }
+               } else {
+                       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(ob==G.obedit) {
+                               for(eed=G.editMesh->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 realy 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(MIRRHASH_TYPE) * totvert);
+               
+                       /* sort so we can count unique values */
+                       qsort(MirrTopoHash_Prev, totvert, 
sizeof(MIRRHASH_TYPE), 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(MIRRHASH_TYPE) * totvert);
+               }
+               
+               /* Hash/Index pairs are needed for sorting to find index pairs 
*/
+               MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair) * 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(ob==G.obedit) {
+                       EM_init_index_arrays(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), 
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(ob==G.obedit) {
+                                               
mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] =   
(long)EM_get_vert_for_index(MirrTopoPairs[a-2].vIndex);
+                                               
mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] =   
(long)EM_get_vert_for_index(MirrTopoPairs[a-1].vIndex);
+                                       } else {
+                                               
mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] =   MirrTopoPairs[a-2].vIndex;

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to