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