Two in one:
[blender.git] / source / blender / src / editmesh_mods.c
index bd20e68830dfd248574aa482adda4d4ebda37520..5944c77e045fe2aab415ac3ac2b226b7dad560d9 100644 (file)
@@ -102,6 +102,7 @@ editmesh_mods.c, UI level access, no geometry changes
 
 #include "RE_render_ext.h"  /* externtex */
 
+#include "multires.h"
 #include "mydevice.h"
 #include "blendef.h"
 
@@ -331,7 +332,7 @@ int EM_init_backbuf_circle(short xs, short ys, short rads)
 
 static void findnearestvert__doClosest(void *userData, EditVert *eve, int x, int y, int index)
 {
-       struct { short mval[2], pass, select; int dist, lastIndex, closestIndex; EditVert *closest; } *data = userData;
+       struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; EditVert *closest; } *data = userData;
 
        if (data->pass==0) {
                if (index<=data->lastIndex)
@@ -343,7 +344,12 @@ static void findnearestvert__doClosest(void *userData, EditVert *eve, int x, int
 
        if (data->dist>3) {
                int temp = abs(data->mval[0] - x) + abs(data->mval[1]- y);
-               if ((eve->f&1)==data->select) temp += 5;
+               if ((eve->f&1) == data->select) {
+                       if (data->strict == 1)
+                               return;
+                       else
+                               temp += 5;
+               }
 
                if (temp<data->dist) {
                        data->dist = temp;
@@ -352,26 +358,49 @@ static void findnearestvert__doClosest(void *userData, EditVert *eve, int x, int
                }
        }
 }
-EditVert *findnearestvert(int *dist, short sel)
+
+
+
+
+static unsigned int findnearestvert__backbufIndextest(unsigned int index){
+               EditVert *eve = BLI_findlink(&G.editMesh->verts, index-1);
+               if(eve && (eve->f & SELECT)) return 0;
+               return 1; 
+}
+/**
+ * findnearestvert
+ * 
+ * dist (in/out): minimal distance to the nearest and at the end, actual distance
+ * sel: selection bias
+ *             if SELECT, selected vertice are given a 5 pixel bias to make them farter than unselect verts
+ *             if 0, unselected vertice are given the bias
+ * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased 
+ */
+EditVert *findnearestvert(int *dist, short sel, short strict)
 {
        short mval[2];
 
        getmouseco_areawin(mval);
-               
-       if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
+       if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)){
                int distance;
-               unsigned int index = sample_backbuf_rect(mval, 50, em_wireoffs, 0xFFFFFF, &distance);
-               EditVert *eve = BLI_findlink(&G.editMesh->verts, index-1);
-
-               if (eve && distance < *dist) {
+               unsigned int index;
+               EditVert *eve;
+               
+               if(strict) index = sample_backbuf_rect(mval, 50, em_wireoffs, 0xFFFFFF, &distance, strict, findnearestvert__backbufIndextest); 
+               else index = sample_backbuf_rect(mval, 50, em_wireoffs, 0xFFFFFF, &distance, 0, NULL); 
+               
+               eve = BLI_findlink(&G.editMesh->verts, index-1);
+               
+               if(eve && distance < *dist) {
                        *dist = distance;
                        return eve;
                } else {
                        return NULL;
                }
+                       
        }
        else {
-               struct { short mval[2], pass, select; int dist, lastIndex, closestIndex; EditVert *closest; } data;
+               struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; EditVert *closest; } data;
                static int lastSelectedIndex=0;
                static EditVert *lastSelected=NULL;
 
@@ -385,6 +414,7 @@ EditVert *findnearestvert(int *dist, short sel)
                data.mval[1] = mval[1];
                data.select = sel;
                data.dist = *dist;
+               data.strict = strict;
                data.closest = NULL;
                data.closestIndex = 0;
 
@@ -462,7 +492,7 @@ EditEdge *findnearestedge(int *dist)
 
        if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
                int distance;
-               unsigned int index = sample_backbuf_rect(mval, 50, em_solidoffs, em_wireoffs, &distance);
+               unsigned int index = sample_backbuf_rect(mval, 50, em_solidoffs, em_wireoffs, &distance,0, NULL);
                EditEdge *eed = BLI_findlink(&G.editMesh->edges, index-1);
 
                if (eed && distance<*dist) {
@@ -731,7 +761,7 @@ static int unified_findnearest(EditVert **eve, EditEdge **eed, EditFace **efa)
        *efa= NULL;
        
        if(G.scene->selectmode & SCE_SELECT_VERTEX)
-               *eve= findnearestvert(&dist, SELECT);
+               *eve= findnearestvert(&dist, SELECT, 0);
        if(G.scene->selectmode & SCE_SELECT_FACE)
                *efa= findnearestface(&dist);
 
@@ -1205,26 +1235,47 @@ int vertgroup_select(short mode)
 handles face/edge vert context and
 facegroup_select/edgegroup_select/vertgroup_select do all the work
 */
+
 void select_mesh_group_menu()
 {
        short ret;
-       int selcount;
+       int selcount, first_item=1;
+       char str[512] = "Select Grouped%t"; /* total max length is 404 at the moment */
+
+       if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+               first_item=0;
+               strcat(str, "|Verts...%x-1|    Similar Normal %x1|    Same Face Users %x2|    Shared Vertex Groups%x3");
+       }
+
+       if(G.scene->selectmode & SCE_SELECT_EDGE) {
+               if (!first_item)        strcat(str, "|%l");
+               else                            first_item=1;
+               
+               strcat(str, "|Edges...%x-1|    Similar Length %x10|    Similar Direction %x20|    Same Face Users%x30|    Similar Face Angle%x40|    Similar Crease%x50");
+       }
        
        if(G.scene->selectmode & SCE_SELECT_FACE) {
-               ret= pupmenu("Select Grouped Faces %t|Same Material %x1|Same Image %x2|Similar Area %x3|Similar Perimeter %x4|Similar Normal %x5|Similar Co-Planer %x6");
-               if (ret<1) return;
-               selcount= facegroup_select(ret);
-               
+               if (!first_item)        strcat(str, "|%l");
+               strcat(str, "|Faces...%x-1|    Same Material %x100|    Same Image %x200|    Similar Area %x300|    Similar Perimeter %x400|    Similar Normal %x500|    Similar Co-Planer %x600");
+       
+       }
+       
+       ret= pupmenu(str);
+       if (ret<1) return;
+       
+       if (ret<10) {
+               selcount= vertgroup_select(ret);
                if (selcount) { /* update if data was selected */
-                       G.totfacesel+=selcount;
+                       EM_select_flush(); /* so that selected verts, go onto select faces */
+                       G.totvertsel += selcount;
                        allqueue(REDRAWVIEW3D, 0);
-                       BIF_undo_push("Select Grouped Faces");
+                       BIF_undo_push("Select Grouped Verts");
                }
-               
-       } else if(G.scene->selectmode & SCE_SELECT_EDGE) {
-               ret= pupmenu("Select Grouped Edges%t|Similar Length %x1|Similar Direction %x2|Same Face Users%x3|Similar Adjacent Face Angle%x4|Similar Crease%x5");
-               if (ret<1) return;
-               selcount= edgegroup_select(ret);
+               return;
+       }
+       
+       if (ret<100) {
+               selcount= edgegroup_select(ret/10);
                
                if (selcount) { /* update if data was selected */
                        /*EM_select_flush();*/ /* dont use because it can end up selecting more edges and is not usefull*/
@@ -1232,20 +1283,18 @@ void select_mesh_group_menu()
                        allqueue(REDRAWVIEW3D, 0);
                        BIF_undo_push("Select Grouped Edges");
                }
-               
-       } else if(G.scene->selectmode & SCE_SELECT_VERTEX) {
-               ret= pupmenu("Select Grouped Verts%t|Similar Normal %x1|Same Face Users %x2|Shared Vertex Groups%x3");
-               if (ret<1) return;
-               selcount= vertgroup_select(ret);
-               
+               return;
+       }
+       
+       if (ret<1000) {
+               selcount= facegroup_select(ret/100);
                if (selcount) { /* update if data was selected */
-                       EM_select_flush(); /* so that selected verts, go onto select faces */
-                       G.totedgesel+=selcount;
+                       G.totfacesel+=selcount;
                        allqueue(REDRAWVIEW3D, 0);
-                       BIF_undo_push("Select Grouped Verts");
+                       BIF_undo_push("Select Grouped Faces");
                }
+               return;
        }
-       
 }
 
 
@@ -1531,7 +1580,7 @@ void loop_multiselect(int looptype)
 static void mouse_mesh_loop(void)
 {
        EditEdge *eed;
-       int select;
+       int select= 1;
        int dist= 50;
        
        eed= findnearestedge(&dist);
@@ -2536,6 +2585,8 @@ void editmesh_mark_seam(int clear)
 {
        EditMesh *em= G.editMesh;
        EditEdge *eed;
+       
+       if(multires_level1_test()) return;
 
        /* auto-enable seams drawing */
        if(clear==0) {
@@ -2601,6 +2652,18 @@ void editmesh_mark_sharp(int set)
        allqueue(REDRAWVIEW3D, 0);
 }
 
+void BME_Menu()        {
+       short ret;
+       ret= pupmenu("BME modeller%t|Select Edges of Vert%x1");
+       
+       switch(ret)
+       {
+               case 1:
+               //BME_edges_of_vert();
+               break;
+       }
+}
+
 void Edge_Menu() {
        short ret;