merge from trunk - r17500 to HEAD
[blender.git] / source / blender / src / buttons_editing.c
index edf4660b71e3fadcb23b678e6e16f71fce1bfb30..65b992682de16134a624d6a0a84996524a33e615 100644 (file)
 
 static float editbutweight= 1.0;
 float editbutvweight= 1;
-static int actmcol= 0, acttface= 0, acttface_rnd = 0, actmcol_rnd = 0;
+static int actmcol= 0, acttface= 0, acttface_rnd = 0, acttface_clone = 0, acttface_mask = 0, actmcol_rnd = 0;
 
 extern ListBase editNurb;
 
@@ -722,10 +722,10 @@ static void delete_customdata_layer(void *data1, void *data2)
        Mesh *me= (Mesh*)data1;
        CustomData *data= (G.obedit)? &G.editMesh->fdata: &me->fdata;
        CustomDataLayer *layer= (CustomDataLayer*)data2;
-       void *actlayerdata, *rndlayerdata, *layerdata=layer->data;
+       void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->data;
        int type= layer->type;
        int index= CustomData_get_layer_index(data, type);
-       int i, actindex, rndindex;
+       int i, actindex, rndindex, cloneindex, maskindex;
        
        /*ok, deleting a non-active layer needs to preserve the active layer indices.
          to do this, we store a pointer to the .data member of both layer and the active layer,
@@ -736,6 +736,8 @@ static void delete_customdata_layer(void *data1, void *data2)
          layer. */
        actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
        rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
+       clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
+       masklayerdata = data->layers[CustomData_get_mask_layer_index(data, type)].data;
        CustomData_set_layer_active(data, type, layer - &data->layers[index]);
 
        /* Multires is handled seperately because the display data is separate
@@ -787,6 +789,33 @@ static void delete_customdata_layer(void *data1, void *data2)
                CustomData_set_layer_render(data, type, rndindex);
        }
        
+       if (clonelayerdata != layerdata) {
+               /*find index. . .*/
+               cloneindex = CustomData_get_layer_index(data, type);
+               for (i=cloneindex; i<data->totlayer; i++) {
+                       if (data->layers[i].data == clonelayerdata) {
+                               cloneindex = i - cloneindex;
+                               break;
+                       }
+               }
+               
+               /*set index. . .*/
+               CustomData_set_layer_clone(data, type, cloneindex);
+       }
+       
+       if (masklayerdata != layerdata) {
+               /*find index. . .*/
+               maskindex = CustomData_get_layer_index(data, type);
+               for (i=maskindex; i<data->totlayer; i++) {
+                       if (data->layers[i].data == masklayerdata) {
+                               maskindex = i - maskindex;
+                               break;
+                       }
+               }
+               
+               /*set index. . .*/
+               CustomData_set_layer_mask(data, type, maskindex);
+       }
        
        DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
        
@@ -802,9 +831,9 @@ static void delete_customdata_layer(void *data1, void *data2)
 
 static int customdata_buttons(
        uiBlock *block, Mesh *me, CustomData *data,
-       int type, int *activep, int *renderp,
-       int setevt, int setevt_rnd, int newevt,
-       char *label, char *shortlabel, char *browsetip, char *browsetip_rnd,
+       int type, int *activep, int *renderp, int *clonep, int *maskp,
+       int setevt, int setevt_rnd, int setevt_clone, int setevt_mask, int newevt,
+       char *label, char *shortlabel, char *browsetip, char *browsetip_rnd, char *browsetip_clone, char *browsetip_mask,
        char *newtip, char *deltip, int x, int y)
 {
        CustomDataLayer *layer;
@@ -828,12 +857,27 @@ static int customdata_buttons(
                layer= &data->layers[i];
 
                if(layer->type == type) {
+                       int xi = 0;
                        *activep= layer->active + 1;
                        *renderp= layer->active_rnd + 1;
+                       if (clonep) *clonep= layer->active_clone + 1;
+                       if (maskp) *maskp= layer->active_mask + 1;
+                       
                        
                        uiDefIconButI(block, ROW, setevt, ICON_VIEW3D, x,y,25,19, activep, 1.0, count, 0, 0, browsetip);
                        uiDefIconButI(block, ROW, setevt_rnd, ICON_SCENE, x+25,y,25,19, renderp, 1.0, count, 0, 0, browsetip_rnd);
-                       but=uiDefBut(block, TEX, setevt, "", x+50,y,145,19, layer->name, 0.0, 31.0, 0, 0, label);
+                       
+                       if (clonep) {
+                               uiDefIconButI(block, ROW, setevt_clone, ICON_TEXTURE, x+50,y,25,19, clonep, 1.0, count, 0, 0, browsetip_clone);
+                               xi += 25;
+                       }
+                       
+                       if (maskp) {
+                               uiDefIconButI(block, ROW, setevt_mask, ICON_PAINT, x+50+xi,y,25,19, maskp, 1.0, count, 0, 0, browsetip_mask);
+                               xi += 25;
+                       }
+                       
+                       but=uiDefBut(block, TEX, setevt, "", x+50+xi,y,145-xi,19, layer->name, 0.0, 31.0, 0, 0, label);
                        uiButSetFunc(but, verify_customdata_name_func, data, layer);
                        but= uiDefIconBut(block, BUT, B_NOP, VICON_X, x+195,y,25,19, NULL, 0.0, 0.0, 0.0, 0.0, deltip);
                        uiButSetFunc(but, delete_customdata_layer, me, layer);
@@ -902,14 +946,14 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
        uiBlockEndAlign(block);
 
        fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata;
-       yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd,
-               B_SETTFACE, B_SETTFACE_RND, B_NEWTFACE, "UV Texture", "UV Texture:",
-               "Set active UV texture", "Set rendering UV texture", "Creates a new UV texture layer",
+       yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd, (G.f & G_TEXTUREPAINT ? &acttface_clone : NULL), (G.f & G_TEXTUREPAINT ? &acttface_mask : NULL),
+               B_SETTFACE, B_SETTFACE_RND, B_SETTFACE_CLONE, B_SETTFACE_MASK, B_NEWTFACE, "UV Texture", "UV Texture:",
+               "Set active UV texture", "Set rendering UV texture", "Set the layer used for texturepaint cloning", "Set the texture paint stencil layer", "Creates a new UV texture layer",
                "Removes the current UV texture layer", 190, 130);
 
-       yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd,
-               B_SETMCOL, B_SETMCOL_RND, B_NEWMCOL, "Vertex Color", "Vertex Color:",
-               "Sets active vertex color layer", "Sets rendering vertex color layer", "Creates a new vertex color layer",
+       yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd, NULL, NULL,
+               B_SETMCOL, B_SETMCOL_RND, B_NOP, B_NOP, B_NEWMCOL, "Vertex Color", "Vertex Color:",
+               "Sets active vertex color layer", "Sets rendering vertex color layer", "", "", "Creates a new vertex color layer",
                "Removes the current vertex color layer", 190, yco-5);
 
        if(yco < 0)
@@ -4964,7 +5008,22 @@ void do_meshbuts(unsigned short event)
                                allqueue(REDRAWBUTSEDIT, 0);
                        }
                        break;
-                       
+               case B_SETTFACE_CLONE:
+                       if (G.obedit || me) {
+                               CustomData *fdata= (G.obedit)? &em->fdata: &me->fdata;
+                               CustomData_set_layer_clone(fdata, CD_MTFACE, acttface_clone-1);
+                               BIF_undo_push("Set Clone UV Texture");
+                               allqueue(REDRAWBUTSEDIT, 0);
+                       }
+                       break;
+               case B_SETTFACE_MASK:
+                       if (G.obedit || me) {
+                               CustomData *fdata= (G.obedit)? &em->fdata: &me->fdata;
+                               CustomData_set_layer_mask(fdata, CD_MTFACE, acttface_mask-1);
+                               BIF_undo_push("Set Mask UV Texture");
+                               allqueue(REDRAWBUTSEDIT, 0);
+                       }
+                       break;
                case B_FLIPNORM:
                        if(G.obedit) {
                                flip_editnormals();
@@ -6279,20 +6338,23 @@ void brush_buttons(uiBlock *block, short sima,
        ToolSettings *settings= G.scene->toolsettings;
        Brush *brush= settings->imapaint.brush;
        ID *id;
-       int yco, xco, butw;
+       int yco, xco, butw, but_idx;
 
        short *menupoin = sima ? &(G.sima->menunr) : &(G.buts->menunr);
+       short do_project = settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE ? 0:1;
        
        yco= 160;
 
        butw = sima ? 80 : 106;
        
        uiBlockBeginAlign(block);
-       uiDefButS(block, ROW, evt_change, "Draw",               0,              yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_DRAW, 0, 0, "Draw brush");
-       uiDefButS(block, ROW, evt_change, "Soften",             butw,   yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SOFTEN, 0, 0, "Soften brush");
-       uiDefButS(block, ROW, evt_change, "Smear",              butw*2, yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SMEAR, 0, 0, "Smear brush");
-       if (sima)
-               uiDefButS(block, ROW, evt_change, "Clone",      butw*3, yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_CLONE, 0, 0, "Clone brush, use RMB to drag source image");
+       but_idx = 0;
+       uiDefButS(block, ROW, evt_change, "Draw",               butw*(but_idx++),yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_DRAW, 0, 0, "Draw brush");
+       if (sima || do_project==0)
+               uiDefButS(block, ROW, evt_change, "Soften",     butw*(but_idx++),       yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SOFTEN, 0, 0, "Soften brush");
+       uiDefButS(block, ROW, evt_change, "Smear",              butw*(but_idx++),       yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SMEAR, 0, 0, "Smear brush");
+       if (sima || do_project)
+               uiDefButS(block, ROW, evt_change, "Clone",      butw*(but_idx++),       yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_CLONE, 0, 0, "Clone brush, use RMB to drag source image");
        
        uiBlockEndAlign(block);
        yco -= 30;
@@ -6307,16 +6369,44 @@ void brush_buttons(uiBlock *block, short sima,
                butw= 320-(xco+10);
 
                uiDefButS(block, MENU, evt_nop, "Mix %x0|Add %x1|Subtract %x2|Multiply %x3|Lighten %x4|Darken %x5|Erase Alpha %x6|Add Alpha %x7", xco+10,yco,butw,19, &brush->blend, 0, 0, 0, 0, "Blending method for applying brushes");
-
-               uiDefButBitS(block, TOG|BIT, BRUSH_TORUS, evt_change, "Wrap",   xco+10,yco-25,butw,19, &brush->flag, 0, 0, 0, 0, "Enables torus wrapping");
-
+       
                uiBlockBeginAlign(block);
-               uiDefButBitS(block, TOG|BIT, BRUSH_AIRBRUSH, evt_change, "Airbrush",    xco+10,yco-50,butw,19, &brush->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse (spray)");
-               uiDefButF(block, NUM, evt_nop, "Rate ", xco+10,yco-70,butw,19, &brush->rate, 0.01, 1.0, 0, 0, "Number of paints per second for Airbrush");
+               uiDefButBitS(block, TOG|BIT, BRUSH_AIRBRUSH, evt_change, "Airbrush",    xco+10,yco-25,butw/2,19, &brush->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse (spray)");
+               uiDefButF(block, NUM, evt_nop, "", xco+10 + butw/2,yco-25,butw/2,19, &brush->rate, 0.01, 1.0, 0, 0, "Number of paints per second for Airbrush");
                uiBlockEndAlign(block);
-
-               yco -= 25;
-
+               
+               if (sima) {
+                       uiDefButBitS(block, TOG|BIT, BRUSH_TORUS, evt_change, "Wrap",   xco+10,yco-45,butw,19, &brush->flag, 0, 0, 0, 0, "Enables torus wrapping");
+                       yco -= 25;
+               }
+               else {
+                       yco -= 25;
+                       uiBlockBeginAlign(block);
+                       uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_DISABLE, B_REDR, "Project Paint",      xco+10,yco-25,butw,19, &settings->imapaint.flag, 0, 0, 0, 0, "Use projection painting for improved consistency in the brush strokes");
+                       
+                       if ((settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0) {
+                               
+                               
+                               /* Projection Painting */
+                               
+                               uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_XRAY, B_NOP, "Occlude",        xco+10,yco-45,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Only paint onto the faces directly under the brush (slower)");
+                               uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_BACKFACE, B_NOP, "Cull",       xco+10+butw/2,yco-45,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)");
+                               
+                               uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_FLAT, B_NOP, "Normal", xco+10,yco-65,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Paint most on faces pointing towards the view");
+                               uiDefButS(block, NUM, B_NOP, "", xco+10 +(butw/2),yco-65,butw/2,19, &settings->imapaint.normal_angle, 10.0, 90.0, 0, 0, "Paint most on faces pointing towards the view acording to this angle)");
+                               
+                               uiDefButS(block, NUM, B_NOP, "Bleed: ", xco+10,yco-85,butw,19, &settings->imapaint.seam_bleed, 0.0, 8.0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)");
+                               uiBlockEndAlign(block);
+                               
+                               uiBlockBeginAlign(block);
+                               uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_MASK, B_NOP, "Stencil Layer",     xco+10,yco-110,butw-30,19, &settings->imapaint.flag, 0, 0, 0, 0, "Set the mask layer from the UV layer buttons");
+                               uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_MASK_INV, B_NOP, "Inv",   xco+10 + butw-30,yco-110,30,19, &settings->imapaint.flag, 0, 0, 0, 0, "Invert the mask");
+                               uiBlockEndAlign(block);
+                               
+                       }
+                       uiBlockEndAlign(block);
+               }
+               
                uiBlockBeginAlign(block);
                uiDefButF(block, COL, B_VPCOLSLI, "",                                   0,yco,200,19, brush->rgb, 0, 0, 0, 0, "");
                uiDefButF(block, NUMSLI, evt_nop, "Opacity ",           0,yco-20,180,19, &brush->alpha, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");