Saturday merger of bf-blender in orange branch.
[blender.git] / source / blender / src / buttons_shading.c
index 246e9daa390250b475e901588cfc131f05676aea..fcbe1a5d71c57ec1fb85feb5eadc79b75566ca38 100644 (file)
@@ -111,12 +111,9 @@ int vergcband(const void *, const void *);
 void save_env(char *);
 void drawcolorband(ColorBand *, float , float , float , float );
 
-
-static MTex mtexcopybuf;
 static MTex emptytex;
 static int packdummy = 0;
 
-
 static char *mapto_blendtype_pup(void)
 {
        static char string[1024];
@@ -379,17 +376,20 @@ static void drawcolorband_cb(void)
 {
        ID *id, *idfrom;
        
-       buttons_active_id(&id, &idfrom);
+       buttons_active_id(&id, &idfrom);        /* base material, not the matlayer! */
        if( GS(id->name)==ID_TE) {
                Tex *tex= (Tex *)id;
                drawcolorband(tex->coba, 10,145,300,30);
        }
        else if( GS(id->name)==ID_MA) {
                Material *ma= (Material *)id;
-               if(ma->ramp_show==0)
-                       drawcolorband(ma->ramp_col, 10,110,300,30);
-               else
-                       drawcolorband(ma->ramp_spec, 10,110,300,30);
+               ma= get_active_matlayer(ma);
+               if(ma) {
+                       if(ma->ramp_show==0)
+                               drawcolorband(ma->ramp_col, 10,110,300,30);
+                       else
+                               drawcolorband(ma->ramp_spec, 10,110,300,30);
+               }
        }
 }
 
@@ -763,7 +763,7 @@ void do_texbuts(unsigned short event)
                                do_colorbandbuts(tex->coba, event);
                        }
                        else {
-                               ma= (Material *)id;
+                               ma= get_active_matlayer((Material *)id);
                                if(ma->ramp_show==0) do_colorbandbuts(ma->ramp_col, event);
                                else do_colorbandbuts(ma->ramp_spec, event);
                        }
@@ -1420,7 +1420,7 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l
 {
        MTex *mt=NULL;
        uiBlock *block;
-       ID *id, *idfrom;
+       ID *id=NULL, *idfrom;
        int a, yco, loos;
        char str[32];
        
@@ -1429,7 +1429,12 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l
        if(uiNewPanel(curarea, block, "Texture", "Texture", 320, 0, 318, 204)==0) return;
 
        /* first do the browse but */
-       buttons_active_id(&id, &idfrom);
+       if(mtex)
+               id= (ID *)mtex->tex;
+       
+       if(ma) idfrom= &ma->id;
+       else if(wrld) idfrom= &wrld->id;
+       else idfrom= &la->id;
 
        uiBlockSetCol(block, TH_BUT_SETTING2);
        if(ma) {
@@ -1730,6 +1735,8 @@ static void radio_panel_render(Radio *rad)
 
 void do_worldbuts(unsigned short event)
 {
+       static short mtexcopied=0;
+       static MTex mtexcopybuf;
        World *wrld;
        MTex *mtex;
        
@@ -1747,6 +1754,35 @@ void do_worldbuts(unsigned short event)
                        BIF_preview_changed(G.buts);
                }
                break;
+       case B_WMTEXCOPY:
+               wrld= G.buts->lockpoin;
+               if(wrld && wrld->mtex[(int)wrld->texact] ) {
+                       mtex= wrld->mtex[(int)wrld->texact];
+                       if(mtex->tex==0) {
+                               error("No texture available");
+                       }
+                       else {
+                               memcpy(&mtexcopybuf, wrld->mtex[(int)wrld->texact], sizeof(MTex));
+                               mtexcopied= 1;
+                       }
+               }
+               break;
+       case B_WMTEXPASTE:
+               wrld= G.buts->lockpoin;
+               if(wrld && mtexcopied && mtexcopybuf.tex) {
+                       if(wrld->mtex[(int)wrld->texact]==0 ) 
+                               wrld->mtex[(int)wrld->texact]= MEM_mallocN(sizeof(MTex), "mtex"); 
+                       else if(wrld->mtex[(int)wrld->texact]->tex)
+                               wrld->mtex[(int)wrld->texact]->tex->id.us--;
+                       
+                       memcpy(wrld->mtex[(int)wrld->texact], &mtexcopybuf, sizeof(MTex));
+                       
+                       id_us_plus((ID *)mtexcopybuf.tex);
+                       BIF_undo_push("Paste mapping settings");
+                       BIF_preview_changed(G.buts);
+                       scrarea_queue_winredraw(curarea);
+               }
+               break;
        }
 }
 
@@ -1785,10 +1821,10 @@ static void world_panel_mapto(World *wrld)
        
        /* MAP TO */
        uiBlockBeginAlign(block);
-       uiDefButBitS(block, TOG, WOMAP_BLEND, B_MATPRV, "Blend",                10,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour progression of the background");
+       uiDefButBitS(block, TOG, WOMAP_BLEND, B_MATPRV, "Blend",        10,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour progression of the background");
        uiDefButBitS(block, TOG, WOMAP_HORIZ, B_MATPRV, "Hori",         85,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the horizon");
-       uiDefButBitS(block, TOG, WOMAP_ZENUP, B_MATPRV, "ZenUp",                160,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith above");
-       uiDefButBitS(block, TOG, WOMAP_ZENDOWN, B_MATPRV, "ZenDo",              235,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith below");
+       uiDefButBitS(block, TOG, WOMAP_ZENUP, B_MATPRV, "ZenUp",        160,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith above");
+       uiDefButBitS(block, TOG, WOMAP_ZENDOWN, B_MATPRV, "ZenDo",      235,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith below");
        uiBlockEndAlign(block);
 
        uiBlockBeginAlign(block);
@@ -1845,7 +1881,7 @@ static void world_panel_texture(World *wrld)
                uiDefBut(block, TEX, B_IDNAME, "TE:",   100,160,200,19, id->name+2, 0.0, 18.0, 0, 0, "Displays name of the texture block: click to change");
                sprintf(str, "%d", id->us);
                uiDefBut(block, BUT, 0, str,                    196,140,21,19, 0, 0, 0, 0, 0, "Displays number of users of texture: click to make single user");
-               uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 279,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
+               uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 220,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
                if(id->lib) {
                        if(wrld->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB,      219,140,21,19, 0, 0, 0, 0, 0, "");
                        else uiDefIconBut(block, BUT, 0, ICON_PARLIB,   219,140,21,19, 0, 0, 0, 0, 0, "");      
@@ -1858,24 +1894,31 @@ static void world_panel_texture(World *wrld)
 
        uiBlockSetCol(block, TH_AUTO);
        
-
+       /* copy/paste */
+       uiBlockBeginAlign(block);
+       uiDefIconBut(block, BUT, B_WMTEXCOPY, ICON_COPYUP,      250,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
+       uiDefIconBut(block, BUT, B_WMTEXPASTE, ICON_PASTEUP,275,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
+               
        /* TEXCO */
        uiBlockBeginAlign(block);
-       uiDefButS(block, ROW, B_MATPRV, "View",                 100,110,45,20, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Uses global coordinates for the texture coordinates");
-       uiDefButS(block, ROW, B_MATPRV, "AngMap",               145,110,55,20, &(mtex->texco), 4.0, (float)TEXCO_ANGMAP, 0, 0, "Uses 360 degree angular coordinates, e.g. for spherical light probes");
-       uiDefButS(block, ROW, B_MATPRV, "Sphere",               200,110,55,20, &(mtex->texco), 4.0, (float)TEXCO_H_SPHEREMAP, 0, 0, "For 360 degree panorama sky, spherical mapped, only top half");
-       uiDefButS(block, ROW, B_MATPRV, "Tube",                 255,110,45,20, &(mtex->texco), 4.0, (float)TEXCO_H_TUBEMAP, 0, 0, "For 360 degree panorama sky, cylindrical mapped, only top half");
-       uiDefButS(block, ROW, B_MATPRV, "Object",               100,90,70,20, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
-       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "", 170,90,130,20, &(mtex->object), "");
+       uiDefButS(block, ROW, B_MATPRV, "View",         100,110,100,20, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Uses view vector for the texture coordinates");
+       uiDefButS(block, ROW, B_MATPRV, "Global",       200,110,100,20, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates (interior mist)");
+       
+       uiDefButS(block, ROW, B_MATPRV, "AngMap",       100,90,70,20, &(mtex->texco), 4.0, (float)TEXCO_ANGMAP, 0, 0, "Uses 360 degree angular coordinates, e.g. for spherical light probes");
+       uiDefButS(block, ROW, B_MATPRV, "Sphere",       170,90,65,20, &(mtex->texco), 4.0, (float)TEXCO_H_SPHEREMAP, 0, 0, "For 360 degree panorama sky, spherical mapped, only top half");
+       uiDefButS(block, ROW, B_MATPRV, "Tube",         235,90,65,20, &(mtex->texco), 4.0, (float)TEXCO_H_TUBEMAP, 0, 0, "For 360 degree panorama sky, cylindrical mapped, only top half");
+       
+       uiDefButS(block, ROW, B_MATPRV, "Object",       100,70,70,20, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
+       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "", 170,70,130,20, &(mtex->object), "");
 
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUM, B_MATPRV, "dX",           100,50,100,19, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate");
-       uiDefButF(block, NUM, B_MATPRV, "dY",           100,30,100,19, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate");
-       uiDefButF(block, NUM, B_MATPRV, "dZ",           100,10,100,19, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Z coordinate");
+       uiDefButF(block, NUM, B_MATPRV, "dX",           100,40,100,19, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate");
+       uiDefButF(block, NUM, B_MATPRV, "dY",           100,20,100,19, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate");
+       uiDefButF(block, NUM, B_MATPRV, "dZ",           100, 0,100,19, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Z coordinate");
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUM, B_MATPRV, "sizeX",        200,50,100,19, mtex->size, -10.0, 10.0, 10, 0, "Sets scaling for the texture's X size");
-       uiDefButF(block, NUM, B_MATPRV, "sizeY",        200,30,100,19, mtex->size+1, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Y size");
-       uiDefButF(block, NUM, B_MATPRV, "sizeZ",        200,10,100,19, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size");
+       uiDefButF(block, NUM, B_MATPRV, "sizeX",        200,40,100,19, mtex->size, -10.0, 10.0, 10, 0, "Sets scaling for the texture's X size");
+       uiDefButF(block, NUM, B_MATPRV, "sizeY",        200,20,100,19, mtex->size+1, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Y size");
+       uiDefButF(block, NUM, B_MATPRV, "sizeZ",        200, 0,100,19, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size");
        
 }
 
@@ -1981,16 +2024,12 @@ static void world_panel_amb_occ(World *wrld)
 static void world_panel_world(World *wrld)
 {
        uiBlock *block;
-       ID *id, *idfrom;
        
        block= uiNewBlock(&curarea->uiblocks, "world_panel_world", UI_EMBOSS, UI_HELV, curarea->win);
        if(uiNewPanel(curarea, block, "World", "World", 320, 0, 318, 204)==0) return;
 
-       /* first do the browse but */
-       buttons_active_id(&id, &idfrom);
-
        uiBlockSetCol(block, TH_BUT_SETTING2);
-       std_libbuttons(block, 10, 180, 0, NULL, B_WORLDBROWSE, id, idfrom, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0, B_KEEPDATA);
+       std_libbuttons(block, 10, 180, 0, NULL, B_WORLDBROWSE, (ID *)wrld, (ID *)G.scene, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0, B_KEEPDATA);
 
        if(wrld==NULL) return;
        
@@ -2052,6 +2091,8 @@ static void world_panel_preview(World *wrld)
 
 void do_lampbuts(unsigned short event)
 {
+       static short mtexcopied=0;
+       static MTex mtexcopybuf;
        Lamp *la;
        MTex *mtex;
 
@@ -2095,6 +2136,36 @@ void do_lampbuts(unsigned short event)
                allqueue(REDRAWBUTSSHADING, 0);
                allqueue(REDRAWVIEW3D, 0);      
                break;
+       case B_LMTEXCOPY:
+               la= G.buts->lockpoin;
+               if(la && la->mtex[(int)la->texact] ) {
+                       mtex= la->mtex[(int)la->texact];
+                       if(mtex->tex==0) {
+                               error("No texture available");
+                       }
+                       else {
+                               memcpy(&mtexcopybuf, la->mtex[(int)la->texact], sizeof(MTex));
+                               mtexcopied= 1;
+                       }
+               }
+               break;
+       case B_LMTEXPASTE:
+               la= G.buts->lockpoin;
+               if(la && mtexcopied && mtexcopybuf.tex) {
+                       if(la->mtex[(int)la->texact]==0 ) 
+                               la->mtex[(int)la->texact]= MEM_mallocN(sizeof(MTex), "mtex"); 
+                       else if(la->mtex[(int)la->texact]->tex)
+                               la->mtex[(int)la->texact]->tex->id.us--;
+
+                       memcpy(la->mtex[(int)la->texact], &mtexcopybuf, sizeof(MTex));
+                       
+                       id_us_plus((ID *)mtexcopybuf.tex);
+                       BIF_undo_push("Paste mapping settings");
+                       BIF_preview_changed(G.buts);
+                       scrarea_queue_winredraw(curarea);
+               }
+               break;
+               
        }
        
        if(event) freefastshade();
@@ -2191,7 +2262,7 @@ static void lamp_panel_texture(Object *ob, Lamp *la)
                uiDefBut(block, TEX, B_IDNAME, "TE:",   100,160,200,19, id->name+2, 0.0, 18.0, 0, 0, "Displays name of the texture block: click to change");
                sprintf(str, "%d", id->us);
                uiDefBut(block, BUT, 0, str,                    196,140,21,19, 0, 0, 0, 0, 0, "Displays number of users of texture: click to make single user");
-               uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 241,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
+               uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 221,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
                if(id->lib) {
                        if(la->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB,        219,140,21,19, 0, 0, 0, 0, 0, "");
                        else uiDefIconBut(block, BUT, 0, ICON_PARLIB,   219,140,21,19, 0, 0, 0, 0, 0, "");      
@@ -2202,6 +2273,11 @@ static void lamp_panel_texture(Object *ob, Lamp *la)
        else 
                uiDefButS(block, TOG, B_LTEXBROWSE, "Add New" ,100, 160, 200, 19, &(G.buts->texnr), -1.0, 32767.0, 0, 0, "Adds a new texture datablock");
 
+       /* copy/paste */
+       uiBlockBeginAlign(block);
+       uiDefIconBut(block, BUT, B_LMTEXCOPY, ICON_COPYUP,      250,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
+       uiDefIconBut(block, BUT, B_LMTEXPASTE, ICON_PASTEUP,    275,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
+       
        /* TEXCO */
        uiBlockSetCol(block, TH_AUTO);
        uiBlockBeginAlign(block);
@@ -2387,7 +2463,6 @@ static void lamp_panel_yafray(Object *ob, Lamp *la)
 static void lamp_panel_lamp(Object *ob, Lamp *la)
 {
        uiBlock *block;
-       ID *id, *idfrom;
        float grid= 0.0;
        short xco;
        
@@ -2399,11 +2474,8 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
 
        uiSetButLock(la->id.lib!=0, "Can't edit library data");
 
-       /* first do the browse but */
-       buttons_active_id(&id, &idfrom);
-
        uiBlockSetCol(block, TH_BUT_SETTING2);
-       xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, id, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0, 0);  
+       xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, (ID *)la, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0, 0);    
 
        uiBlockSetCol(block, TH_AUTO);
        uiDefButF(block, NUM,B_LAMPREDRAW,"Dist:", xco,180,300-xco,20,&la->dist, 0.01, 5000.0*grid, 100, 0, "Sets the distance value at which light intensity is half");
@@ -2491,12 +2563,20 @@ static void lamp_panel_preview(Object *ob, Lamp *la)
 void do_matbuts(unsigned short event)
 {
        static short mtexcopied=0;
+       static MTex mtexcopybuf;
        Material *ma;
        MTex *mtex;
 
+       /* all operations default on active material layer here */
+       /* but this also gets called for lamp and world... */
+       ma= G.buts->lockpoin;
+       if(ma && GS(ma->id.name)==ID_MA)
+               ma = get_active_matlayer(ma);
+       else
+               ma= NULL;
+       
        switch(event) {
        case B_MAT_YF_PRESET: {
-               ma = G.buts->lockpoin;
                switch (ma->YF_preset) {
                        case 0:
                                /* normal mode, no reflection/refraction */
@@ -2576,7 +2656,6 @@ void do_matbuts(unsigned short event)
        case B_MATHALO:
                /* when halo is disabled, clear star flag, this is the same as MA_FACETEXTURE <blush> */
                /* same for 'xtreme alpha' which is 'only shadow' */
-               ma= G.buts->lockpoin;
                if((ma->mode & MA_HALO)==0) {
                        ma->mode &= ~(MA_STAR|MA_HALO_XALPHA|MA_ZINV);
                }
@@ -2585,7 +2664,6 @@ void do_matbuts(unsigned short event)
                shade_buttons_change_3d();
                break;
        case B_TEXCLEAR:
-               ma= G.buts->lockpoin;
                mtex= ma->mtex[(int) ma->texact ];
                if(mtex) {
                        if(mtex->tex) mtex->tex->id.us--;
@@ -2598,7 +2676,6 @@ void do_matbuts(unsigned short event)
                }
                break;
        case B_MTEXCOPY:
-               ma= G.buts->lockpoin;
                if(ma && ma->mtex[(int)ma->texact] ) {
                        mtex= ma->mtex[(int)ma->texact];
                        if(mtex->tex==0) {
@@ -2611,9 +2688,12 @@ void do_matbuts(unsigned short event)
                }
                break;
        case B_MTEXPASTE:
-               ma= G.buts->lockpoin;
                if(ma && mtexcopied && mtexcopybuf.tex) {
-                       if(ma->mtex[(int)ma->texact]==0 ) ma->mtex[(int)ma->texact]= MEM_mallocN(sizeof(MTex), "mtex"); 
+                       if(ma->mtex[(int)ma->texact]==0 ) 
+                               ma->mtex[(int)ma->texact]= MEM_mallocN(sizeof(MTex), "mtex"); 
+                       else if(ma->mtex[(int)ma->texact]->tex)
+                               ma->mtex[(int)ma->texact]->tex->id.us--;
+
                        memcpy(ma->mtex[(int)ma->texact], &mtexcopybuf, sizeof(MTex));
                        
                        id_us_plus((ID *)mtexcopybuf.tex);
@@ -2623,14 +2703,12 @@ void do_matbuts(unsigned short event)
                }
                break;
        case B_MATLAY:
-               ma= G.buts->lockpoin;
                if(ma && ma->lay==0) {
                        ma->lay= 1;
                        scrarea_queue_winredraw(curarea);
                }
                break;
        case B_MATZTRANSP:
-               ma= G.buts->lockpoin;
                if(ma) {
                        ma->mode &= ~MA_RAYTRANSP;
                        allqueue(REDRAWBUTSSHADING, 0);
@@ -2638,7 +2716,6 @@ void do_matbuts(unsigned short event)
                }
                break;
        case B_MATRAYTRANSP:
-               ma= G.buts->lockpoin;
                if(ma) {
                        ma->mode &= ~MA_ZTRA;
                        allqueue(REDRAWBUTSSHADING, 0);
@@ -2646,7 +2723,6 @@ void do_matbuts(unsigned short event)
                }
                break;
        case B_MATCOLORBAND:
-               ma= G.buts->lockpoin;
                if(ma) {
                        if(ma->mode & MA_RAMP_COL)
                                if(ma->ramp_col==NULL) ma->ramp_col= add_colorband();
@@ -2658,7 +2734,33 @@ void do_matbuts(unsigned short event)
                        shade_buttons_change_3d();
                }
                break;
-
+       case B_MAT_LAYERBROWSE:
+               ma= G.buts->lockpoin;   /* use base material instead */
+               if(ma) {
+                       MaterialLayer *ml;
+                       
+                       /* the one with a menu set is the browser */
+                       for(ml= ma->layers.first; ml; ml= ml->next) {
+                               if(ml->menunr) {
+                                       if(ml->menunr==32767) {
+                                               if(ml->mat) {
+                                                       ml->mat->id.us--;
+                                                       ml->mat= copy_material(ml->mat);
+                                               }
+                                               else ml->mat= add_material("Layer");
+                                       }
+                                       else {
+                                               ml->mat= BLI_findlink(&G.main->mat, ml->menunr-1);
+                                               ml->mat->id.us++;
+                                       }
+                                       allqueue(REDRAWBUTSSHADING, 0);
+                                       BIF_all_preview_changed();
+                                       
+                                       break;
+                               }
+                       }
+               }
+               break;
        }
 }
 
@@ -2719,7 +2821,7 @@ static void material_panel_map_to(Material *ma)
        uiDefButBitS(block, TOG3, MAP_RAYMIRR, B_MATPRV, "RayMir",      60,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value");
        uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Alpha",         110,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value");
        uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit",           160,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value");
-       uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "Translu",     205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the translucency value");
+       uiDefButBitS(block, TOG3, MAP_LAYER, B_MATPRV, "Layer",         205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the layer blending value");
        uiDefButBitS(block, TOG3, MAP_DISPLACE, B_MATPRV, "Disp",               265,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface");
        uiBlockEndAlign(block);
        
@@ -2758,26 +2860,29 @@ static void material_panel_map_input(Object *ob, Material *ma)
        
        /* TEXCO */
        uiBlockBeginAlign(block);
-       uiDefButS(block, ROW, B_MATPRV, "UV",                   630,166,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates");
-       uiDefButS(block, ROW, B_MATPRV, "Object",               670,166,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
-       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",745,166,163,18, &(mtex->object), "");
+       uiDefButS(block, ROW, B_MATPRV, "Glob",                 630,180,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates");
+       uiDefButS(block, ROW, B_MATPRV, "Object",               675,180,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
+       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",750,180,158,18, &(mtex->object), "");
        
-       uiDefButS(block, ROW, B_MATPRV, "Glob",                 630,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates");
-       uiDefButS(block, ROW, B_MATPRV, "Orco",                 675,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original coordinates of the mesh");
+       uiDefButS(block, ROW, B_MATPRV, "UV",                   630,160,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates");
+       uiDefButS(block, ROW, B_MATPRV, "Orco",                 670,160,55,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object");
        if( give_parteff(ob) )
-               uiDefButS(block, ROW, B_MATPRV, "Strand",       725,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)");
+               uiDefButS(block, ROW, B_MATPRV, "Strand",       725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)");
        else
-               uiDefButS(block, ROW, B_MATPRV, "Stick",                725,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates");
-       uiDefButS(block, ROW, B_MATPRV, "Win",                  775,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Uses screen coordinates as texture coordinates");
-       uiDefButS(block, ROW, B_MATPRV, "Nor",                  820,146,44,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Uses normal vector as texture coordinates");
-       uiDefButS(block, ROW, B_MATPRV, "Refl",                 864,146,44,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Uses reflection vector as texture coordinates");
+               uiDefButS(block, ROW, B_MATPRV, "Stick",        725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates");
+       uiDefButS(block, ROW, B_MATPRV, "Win",                  775,160,45,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Uses screen coordinates as texture coordinates");
+       uiDefButS(block, ROW, B_MATPRV, "Nor",                  820,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Uses normal vector as texture coordinates");
+       uiDefButS(block, ROW, B_MATPRV, "Refl",                 864,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Uses reflection vector as texture coordinates");
+       
+       uiDefButS(block, ROW, B_MATPRV, "Stress",               630,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh");
+       uiDefButS(block, ROW, B_MATPRV, "Tangent",              700,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_TANGENT, 0, 0, "Uses te optional tangent vector as texture coordinates");
 
        /* COORDS */
        uiBlockBeginAlign(block);
-       uiDefButC(block, ROW, B_MATPRV, "Flat",                 630,114,48,18, &(mtex->mapping), 5.0, (float)MTEX_FLAT, 0, 0, "Maps X and Y coordinates directly");
-       uiDefButC(block, ROW, B_MATPRV, "Cube",                 681,114,50,18, &(mtex->mapping), 5.0, (float)MTEX_CUBE, 0, 0, "Maps using the normal vector");
-       uiDefButC(block, ROW, B_MATPRV, "Tube",                 630,94,48,18, &(mtex->mapping), 5.0, (float)MTEX_TUBE, 0, 0, "Maps with Z as central axis (tube-like)");
-       uiDefButC(block, ROW, B_MATPRV, "Sphe",                 681,94,50,18, &(mtex->mapping), 5.0, (float)MTEX_SPHERE, 0, 0, "Maps with Z as central axis (sphere-like)");
+       uiDefButC(block, ROW, B_MATPRV, "Flat",                 630,115,48,19, &(mtex->mapping), 5.0, (float)MTEX_FLAT, 0, 0, "Maps X and Y coordinates directly");
+       uiDefButC(block, ROW, B_MATPRV, "Cube",                 681,115,50,19, &(mtex->mapping), 5.0, (float)MTEX_CUBE, 0, 0, "Maps using the normal vector");
+       uiDefButC(block, ROW, B_MATPRV, "Tube",                 630,95,48,19, &(mtex->mapping), 5.0, (float)MTEX_TUBE, 0, 0, "Maps with Z as central axis (tube-like)");
+       uiDefButC(block, ROW, B_MATPRV, "Sphe",                 681,95,50,19, &(mtex->mapping), 5.0, (float)MTEX_SPHERE, 0, 0, "Maps with Z as central axis (sphere-like)");
 
        uiBlockBeginAlign(block);
        for(b=0; b<3; b++) {
@@ -2793,13 +2898,13 @@ static void material_panel_map_input(Object *ob, Material *ma)
        }
        
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUM, B_MATPRV, "ofsX",         778,114,130,18, mtex->ofs, -10.0, 10.0, 10, 0, "Fine tunes texture mapping X coordinate");
-       uiDefButF(block, NUM, B_MATPRV, "ofsY",         778,94,130,18, mtex->ofs+1, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Y coordinate");
-       uiDefButF(block, NUM, B_MATPRV, "ofsZ",         778,74,130,18, mtex->ofs+2, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Z coordinate");
+       uiDefButF(block, NUM, B_MATPRV, "ofsX",         778,115,130,19, mtex->ofs, -10.0, 10.0, 10, 0, "Fine tunes texture mapping X coordinate");
+       uiDefButF(block, NUM, B_MATPRV, "ofsY",         778,95,130,19, mtex->ofs+1, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Y coordinate");
+       uiDefButF(block, NUM, B_MATPRV, "ofsZ",         778,75,130,19, mtex->ofs+2, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Z coordinate");
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUM, B_MATPRV, "sizeX",        778,50,130,18, mtex->size, -100.0, 100.0, 10, 0, "Sets scaling for the texture's X size");
-       uiDefButF(block, NUM, B_MATPRV, "sizeY",        778,30,130,18, mtex->size+1, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Y size");
-       uiDefButF(block, NUM, B_MATPRV, "sizeZ",        778,10,130,18, mtex->size+2, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Z size");
+       uiDefButF(block, NUM, B_MATPRV, "sizeX",        778,50,130,19, mtex->size, -100.0, 100.0, 10, 0, "Sets scaling for the texture's X size");
+       uiDefButF(block, NUM, B_MATPRV, "sizeY",        778,30,130,19, mtex->size+1, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Y size");
+       uiDefButF(block, NUM, B_MATPRV, "sizeZ",        778,10,130,19, mtex->size+2, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Z size");
        uiBlockEndAlign(block);
 
 }
@@ -3027,7 +3132,7 @@ static void material_panel_shading(Material *ma)
                uiBlockEndAlign(block);
        }
        else {
-               char *str1= "Diffuse Shader%t|Lambert %x0|Oren-Nayar %x1|Toon %x2|Minnaert %x3";
+               char *str1= "Diffuse Shader%t|Lambert %x0|Oren-Nayar %x1|Toon %x2|Minnaert %x3|Fresnel %x4";
                char *str2= "Specular Shader%t|CookTorr %x0|Phong %x1|Blinn %x2|Toon %x3|WardIso %x4";
                
                /* diff shader buttons */
@@ -3043,6 +3148,10 @@ static void material_panel_shading(Material *ma)
                }
                else if(ma->diff_shader==MA_DIFF_MINNAERT) 
                        uiDefButF(block, NUMSLI, B_MATPRV, "Dark:",90,160, 150,19, &(ma->darkness), 0.0, 2.0, 0, 0, "Sets Minnaert darkness");
+               else if(ma->diff_shader==MA_DIFF_FRESNEL) {
+                       uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel:",  90, 160,150,19, &(ma->param[1]), 0.0, 5.0, 0, 0, "Power of Fresnel");
+                       uiDefButF(block, NUMSLI, B_MATPRV, "Fac:",90,140,150,19, &(ma->param[0]), 1.0, 5.0, 0, 0, "Blending factor");
+               }
                uiBlockEndAlign(block);
                
                /* spec shader buttons */
@@ -3063,28 +3172,234 @@ static void material_panel_shading(Material *ma)
                        uiDefButF(block, NUMSLI, B_MATPRV, "rms:",     90, 100,150,19, &(ma->rms), 0.0, 0.4, 0, 0, "Sets the standard deviation of surface slope");             
                /* default shading variables */
                uiBlockBeginAlign(block);
-               uiDefButF(block, NUMSLI, B_DIFF, "Translucency ",       9,30,301,19, &(ma->translucency), 0.0, 1.0, 100, 2, "Amount of diffuse shading of the back side");
+               uiDefButF(block, NUMSLI, B_DIFF, "Tralu ",      9,30,150,19, &(ma->translucency), 0.0, 1.0, 100, 2, "Translucency, amount of diffuse shading of the back side");
+               uiDefButF(block, NUMSLI, B_DIFF, "SBias ",      159,30,151,19, &(ma->sbias), 0.0, 0.25, 10, 2, "Shadow bias, to prevent terminator problems on shadow boundary");
                uiDefButF(block, NUMSLI, B_MATPRV, "Amb ",              9,10,150,19, &(ma->amb), 0.0, 1.0, 0, 0, "Sets the amount of global ambient color the material receives");
-               uiDefButF(block, NUMSLI, B_MATPRV, "Emit ",             160,10,150,19, &(ma->emit), 0.0, 1.0, 0, 0, "Sets the amount of light the material emits");
+               uiDefButF(block, NUMSLI, B_MATPRV, "Emit ",             159,10,151,19, &(ma->emit), 0.0, 1.0, 0, 0, "Sets the amount of light the material emits");
                uiBlockEndAlign(block);
 
                uiBlockSetCol(block, TH_BUT_SETTING1);
                uiBlockBeginAlign(block);
-               uiDefButBitI(block, TOG, MA_TRACEBLE, 0,"Traceable",            245,160,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to being detected by ray tracing");
-               uiDefButBitI(block, TOG, MA_SHADBUF, 0, "Shadbuf",                      245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to cast shadows with shadow buffers");
+               uiDefButBitI(block, TOG, MA_TRACEBLE, B_NOP,"Traceable",                245,160,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to being detected by ray tracing");
+               uiDefButBitI(block, TOG, MA_SHADBUF, B_NOP,     "Shadbuf",                      245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to cast shadows with shadow buffers");
 
                uiBlockBeginAlign(block);
-               uiDefButBitI(block, TOG, MA_SHADOW, 0,  "Shadow",                       245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows");
-               uiDefButBitI(block, TOG, MA_SHADOW_TRA, 0, "TraShadow",         245,100,65,19, &(ma->mode), 0, 0, 0, 0, "Receives transparent shadows based at material color and alpha");
-               uiDefButBitI(block, TOG, MA_RAYBIAS, 0, "Bias",                         245,80,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)");
+               uiDefButBitI(block, TOG, MA_SHADOW, B_NOP,      "Shadow",                       245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows");
+               uiDefButBitI(block, TOG, MA_SHADOW_TRA, B_NOP, "TraShadow",             245,100,65,19, &(ma->mode), 0, 0, 0, 0, "Recieves transparent shadows based at material color and alpha");
+               uiDefButBitI(block, TOG, MA_RAYBIAS, B_NOP, "Bias",                             245,80,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)");
                uiBlockEndAlign(block);
 
-               uiDefButBitI(block, TOG, MA_RADIO, 0,   "Radio",                        245,55,65,19, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosity rendering");
+               uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_NOP, "GR:", 9, 55, 150, 19, &ma->group, "Limit Lighting to Lamps in this Group"); 
+               
+               uiDefButBitI(block, TOG, MA_TANGENT_V, B_MATPRV, "Tangent V",           170,55,65,19, &(ma->mode), 0, 0, 0, 0, "Use the tangent vector in V direction for shading");
+               uiDefButBitI(block, TOG, MA_RADIO, B_NOP,       "Radio",                        245,55,65,19, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosity rendering");
 
        }
+}
 
+static void matlayer_add(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml= ml_v, *mlnew;
+       
+       mlnew= MEM_callocN(sizeof(MaterialLayer), "mat layer");
+       
+       if(ml==NULL) 
+               BLI_addhead(&ma->layers, mlnew);
+       else
+               BLI_insertlink(&ma->layers, ml, mlnew);
+       
+       mlnew->blendfac= 0.5f;
+       mlnew->flag= ML_RENDER|ML_DIFFUSE|ML_SPECULAR;
+       
+       BIF_undo_push("Add Material Layer");
+       allqueue(REDRAWBUTSSHADING, 0);
+}
+
+static void matlayer_moveUp(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml= ml_v;
+
+       if (ml->prev) {
+               BLI_remlink(&ma->layers, ml);
+               BLI_insertlink(&ma->layers, ml->prev->prev, ml);
+       }
+       
+       BIF_undo_push("Move Material Layer");
+}
+
+static void matlayer_moveDown(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml= ml_v;
+       
+       if (ml->next) {
+               BLI_remlink(&ma->layers, ml);
+               BLI_insertlink(&ma->layers, ml->next, ml);
+       }
+       
+       BIF_undo_push("Move Material Layer");
 }
 
+static void matlayer_del(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml= ml_v;
+       
+       BLI_remlink(&ma->layers, ml);
+       if(ml->mat) ml->mat->id.us--;
+       MEM_freeN(ml);
+
+       BIF_undo_push("Delete Material Layer");
+}
+
+static void matlayer_active(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml;
+       
+       for(ml= ma->layers.first; ml; ml= ml->next) {
+               if(ml==ml_v)
+                       ml->flag |= ML_ACTIVE;
+               else
+                       ml->flag &= ~ML_ACTIVE;
+       }
+       BIF_undo_push("Activate Material Layer");
+}
+
+static void matlayer_alone(void *ml_v, void *unused)
+{
+       MaterialLayer *ml= ml_v;
+       
+       ml->mat= copy_material(ml->mat);
+
+       BIF_undo_push("Single user material");
+       allqueue(REDRAWBUTSSHADING, 0);
+       allqueue(REDRAWOOPS, 0);
+}
+
+
+static void material_panel_layers(Material *ma)
+{
+       uiBlock *block;
+       uiBut *but;
+       MaterialLayer *ml;
+       int yco= 155, rb_col;
+       char *strp;
+       
+       block= uiNewBlock(&curarea->uiblocks, "material_panel_layers", UI_EMBOSS, UI_HELV, curarea->win);
+       uiNewPanelTabbed("Preview", "Material");
+       if(uiNewPanel(curarea, block, "Layers", "Material", 0, 0, 318, 204)==0) return;
+       
+       uiNewPanelHeight(block, 204);
+       
+       /* Active button for current material */
+       uiBlockBeginAlign(block);
+       for(ml= ma->layers.first; ml; ml= ml->next)
+               if(ml->flag & ML_ACTIVE) break;
+       
+       if(ml==NULL)
+               but=uiDefIconBut(block, BUT, B_MATPRV_DRAW, ICON_MATERIAL,      10, 180, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate base Material");
+       else but=uiDefBut(block, BUT, B_MATPRV_DRAW, " ",               10, 180, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate base Material");
+       uiButSetFunc(but, matlayer_active, ma, NULL);
+       
+       /* Enable/disable for current material */
+       if(ma->ml_flag & ML_RENDER)
+               uiDefIconButBitS(block, TOG, ML_RENDER, B_MATPRV_DRAW, ICON_CHECKBOX_HLT,       30, 180, 20, 20, &ma->ml_flag, 0.0, 0.0, 0, 0, "Enable or disable base Material");
+       else uiDefButBitS(block, TOG, ML_RENDER, B_MATPRV, " ", 30, 180, 20, 20, &ma->ml_flag, 0.0, 0.0, 0, 0, "Enable or disable base Material");
+       
+       uiBlockEndAlign(block);
+       /* label */
+       uiDefBut(block, LABEL, B_NOP, ma->id.name+2,                    60, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
+       /* add layer */
+       but= uiDefBut(block, BUT, B_NOP, "Add Layer", 200, 180,110,20, NULL, 0, 0, 0, 0, "Add a new Material Layer");
+       uiButSetFunc(but, matlayer_add, ma, NULL);
+
+       
+       for(ml= ma->layers.first; ml; ml= ml->next) {
+               
+               /* rounded header */
+               rb_col= (ml->flag & ML_ACTIVE)?40:20;
+               uiDefBut(block, ROUNDBOX, B_DIFF, "", 8, yco-48, 304, 71, NULL, 5.0, 0.0, 3 , rb_col-20, ""); 
+               
+               /* Active button */
+               uiBlockBeginAlign(block);
+               if(ml->flag & ML_ACTIVE)
+                       but=uiDefIconBut(block, BUT, B_MATPRV_DRAW, ICON_MATERIAL,      10, yco, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate this layer");
+               else but=uiDefBut(block, BUT, B_MATPRV_DRAW, " ",               10, yco, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate this layer");
+               uiButSetFunc(but, matlayer_active, ma, ml);
+               
+               /* enable/disable button */
+               if(ml->flag & ML_RENDER)
+                       uiDefIconButBitS(block, TOG, ML_RENDER, B_MATPRV_DRAW, ICON_CHECKBOX_HLT,       30, yco, 20, 20, &ml->flag, 0.0, 0.0, 0, 0, "Enable or disable this layer");
+               else uiDefButBitS(block, TOG, ML_RENDER, B_MATPRV, " ", 30, yco, 20, 20, &ml->flag, 0.0, 0.0, 0, 0, "Enable or disable this layer");
+               
+               uiBlockBeginAlign(block);
+               
+               /* browse button */
+               IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->mat), (ID *)ma, NULL);
+               ml->menunr= 0;
+               uiDefButS(block, MENU, B_MAT_LAYERBROWSE, strp, 60,yco,20,20, &ml->menunr, 0, 0, 0, 0, "Browses existing choices or adds NEW");
+               if(strp) MEM_freeN(strp);
+                       
+               /* name and users */
+               if(ml->mat) {
+                       int width;
+                       
+                       if(ml->mat->id.us>1) width= 120;
+                       else width= 140;
+                       but= uiDefBut(block, TEX, B_IDNAME, "MA:",80, yco, width, 20, ml->mat->id.name+2, 0.0, 19.0, 0, 0, "Rename Material");
+                       uiButSetFunc(but, test_idbutton_cb, ml->mat->id.name, NULL);
+                       
+                       if(ml->mat->id.us>1) {
+                               char str1[32];
+                               sprintf(str1, "%d", ml->mat->id.us);
+                               but= uiDefBut(block, BUT, B_NOP, str1, 200,yco,20,20, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
+                               uiButSetFunc(but, matlayer_alone, ml, NULL);
+                       }
+               }
+               else
+                       uiDefBut(block, LABEL, B_NOP, "No Material",80, yco, 140, 20, NULL, 0.0, 0.0, 0, 0, "");
+                       
+               /* add new */
+               but= uiDefBut(block, BUT, B_NOP, "Add", 220, yco,30,20, NULL, 0, 0, 0, 0, "Add a new Material Layer");
+               uiButSetFunc(but, matlayer_add, ma, ml);
+               
+               /* move up/down/delete */
+               but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_MOVE_UP, 250, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move layer up");
+               uiButSetFunc(but, matlayer_moveUp, ma, ml);
+               
+               but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_MOVE_DOWN, 270, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move layer down");
+               uiButSetFunc(but, matlayer_moveDown, ma, ml);
+               
+               but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_X, 290, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Delete material layer");
+               uiButSetFunc(but, matlayer_del, ma, ml);
+               
+               /* blend slider and operation */
+               uiBlockBeginAlign(block);
+               yco-= 25;
+               uiDefButS(block, MENU, B_MATPRV, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Divide %x5|Difference %x6|Darken %x7|Lighten %x8",
+                                                                                                       35,yco,100,20, &ml->blendmethod, 0, 0, 0, 0, "Blending method for Ramp (uses alpha in Colorband)");
+               uiDefButF(block, NUMSLI, B_MATPRV, "Blend:",135,yco,175,20, &ml->blendfac, 0.0, 1.0, 100, 0, "Blending factor");
+               
+               /* output */
+               yco-=20;
+               uiDefButBitS(block, TOG, ML_DIFFUSE, B_MATPRV,  "Diff",         35,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Diffuse");
+               uiDefButBitS(block, TOG, ML_SPECULAR, B_MATPRV, "Spec", 85,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Specular");
+               uiDefButBitS(block, TOG, ML_ALPHA, B_MATPRV, "Alpha",           135,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Alpha");
+               uiDefButBitS(block, TOG, ML_NEG_NORMAL, B_MATPRV, "Negate Normal",      185,yco,125,20, &ml->flag, 0, 0, 0, 0, "Negate normal for this layer");
+               
+               yco-= 30;
+               
+               uiBlockEndAlign(block);
+       }
+       
+       if(yco < 0) uiNewPanelHeight(block, 204-yco);
+
+}
+
+
 static void material_panel_ramps(Material *ma)
 {
        uiBlock *block;
@@ -3167,7 +3482,7 @@ static void material_panel_material(Object *ob, Material *ma)
        if(uiNewPanel(curarea, block, "Material", "Material", 320, 0, 318, 204)==0) return;
 
        /* first do the browse but */
-       buttons_active_id(&id, &idfrom);
+       buttons_active_id(&id, &idfrom);        /* base material, not the matlayer! */
 
        uiBlockSetCol(block, TH_BUT_SETTING2);
        std_libbuttons(block, 8, 200, 0, NULL, B_MATBROWSE, id, idfrom, &(G.buts->menunr), B_MATALONE, B_MATLOCAL, B_MATDELETE, B_AUTOMATNAME, B_KEEPDATA);
@@ -3208,8 +3523,8 @@ static void material_panel_material(Object *ob, Material *ma)
        if(ob->totcol==0) return;
        uiSetButLock(id->lib!=0, "Can't edit library data");
 
-       ma= give_current_material(ob, ob->actcol);      
-       if(ma==0) return;       
+       ma= get_active_matlayer(ma);
+       if(ma==NULL) return;    
        
        if(ma->dynamode & MA_DRAW_DYNABUTS) {
                uiBlockBeginAlign(block);
@@ -3328,23 +3643,30 @@ void material_panels()
                material_panel_material(ob, ma);
                
                if(ma) {
-                       material_panel_ramps(ma);
-                       material_panel_shading(ma);
-                       if (G.scene->r.renderer==R_INTERN)
-                               material_panel_tramir(ma);
-                       else {
-                               if (ma->YF_ar==0.f) {
-                                       ma->YF_ar = ma->YF_ag = ma->YF_ab = 1;
-                                       ma->YF_dscale = 1;
-                               }
-                               material_panel_tramir_yafray(ma);
-                       }
-                       material_panel_texture(ma);
+                       material_panel_layers(ma);
                        
-                       mtex= ma->mtex[ ma->texact ];
-                       if(mtex && mtex->tex) {
-                               material_panel_map_input(ob, ma);
-                               material_panel_map_to(ma);
+                       ma= get_active_matlayer(ma);
+                       if(ma) {
+                               material_panel_ramps(ma);
+                               material_panel_shading(ma);
+                               
+                               if (G.scene->r.renderer==R_INTERN)
+                                       material_panel_tramir(ma);
+                               else {
+                                       if(ma->YF_ar==0.f) {
+                                               ma->YF_ar = ma->YF_ag = ma->YF_ab = 1;
+                                               ma->YF_dscale = 1;
+                                       }
+                                       material_panel_tramir_yafray(ma);
+                               }
+                               
+                               material_panel_texture(ma);
+                               
+                               mtex= ma->mtex[ ma->texact ];
+                               if(mtex && mtex->tex) {
+                                       material_panel_map_input(ob, ma);
+                                       material_panel_map_to(ma);
+                               }
                        }
                }
        }
@@ -3405,6 +3727,7 @@ void texture_panels()
        if(G.buts->texfrom==0) {
                if(ob) {
                        ma= give_current_material(ob, ob->actcol);
+                       ma= get_active_matlayer(ma);
                        if(ma) mtex= ma->mtex[ ma->texact ];
                }
        }
@@ -3528,8 +3851,8 @@ void clever_numbuts_buts()
                break;
        case TAB_SHADING_MAT:
 
-               ma= G.buts->lockpoin;
-
+               ma= get_active_matlayer(G.buts->lockpoin);
+               
                /* Build a hex value */
                if (ma){
                        sprintf(hexrgb, "%02X%02X%02X", (int)(ma->r*255), (int)(ma->g*255), (int)(ma->b*255));