Two in one:
[blender.git] / source / blender / src / buttons_shading.c
1 /**
2  * $Id$ 
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: not all of this file anymore. :)
24  *
25  * Contributor(s):
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <time.h>
31 #include <math.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "IMB_imbuf_types.h"
40 #include "IMB_imbuf.h"
41
42 #include "MEM_guardedalloc.h"
43
44 #include "DNA_brush_types.h"
45 #include "DNA_curve_types.h"
46 #include "DNA_image_types.h"
47 #include "DNA_lamp_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_node_types.h"
52 #include "DNA_packedFile_types.h"
53 #include "DNA_radio_types.h"
54 #include "DNA_screen_types.h"
55 #include "DNA_space_types.h"
56 #include "DNA_scene_types.h"
57 #include "DNA_texture_types.h"
58 #include "DNA_userdef_types.h"
59 #include "DNA_view3d_types.h"
60 #include "DNA_world_types.h"
61
62 #include "BKE_displist.h"
63 #include "BKE_effect.h"
64 #include "BKE_global.h"
65 #include "BKE_library.h"
66 #include "BKE_main.h"
67 #include "BKE_node.h"
68 #include "BKE_material.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_texture.h"
71
72 #include "BKE_packedFile.h"
73 #include "BKE_plugin_types.h"
74 #include "BKE_image.h"
75
76 #include "BLI_blenlib.h"
77 #include "BMF_Api.h"
78
79 #include "BSE_filesel.h"
80 #include "BSE_headerbuttons.h"
81 #include "BSE_node.h"
82
83 #include "BDR_drawmesh.h"
84
85 #include "BIF_drawimage.h"
86 #include "BIF_gl.h"
87 #include "BIF_graphics.h"
88 #include "BIF_keyval.h"
89 #include "BIF_mainqueue.h"
90 #include "BIF_resources.h"
91 #include "BIF_screen.h"
92 #include "BIF_mywindow.h"
93 #include "BIF_space.h"
94 #include "BIF_glutil.h"
95 #include "BIF_interface.h"
96 #include "BIF_toolbox.h"
97 #include "BIF_space.h"
98 #include "BIF_previewrender.h"
99 #include "BIF_butspace.h"
100 #include "BIF_writeimage.h"
101 #include "BIF_toets.h"
102
103 #include "mydevice.h"
104 #include "blendef.h"
105 #include "radio.h"
106
107 #include "RE_pipeline.h"
108
109 /* -----includes for this file specific----- */
110
111 #include "butspace.h" // own module
112
113
114 static MTex emptytex;
115 static int packdummy = 0;
116
117 static char *mapto_blendtype_pup(void)
118 {
119         static char formatstr[] = "|%s %%x%d";
120         static char string[1024];
121         char *str = string;
122         
123         str += sprintf(str, formatstr, "Mix", MTEX_BLEND);
124
125         str += sprintf(str, formatstr, "Add", MTEX_ADD);
126         str += sprintf(str, formatstr, "Subtract", MTEX_SUB);
127
128         str += sprintf(str, formatstr, "Multiply", MTEX_MUL);
129         str += sprintf(str, formatstr, "Screen", MTEX_SCREEN);
130         str += sprintf(str, formatstr, "Overlay", MTEX_OVERLAY);
131         
132         str += sprintf(str, formatstr, "Difference", MTEX_DIFF);
133         str += sprintf(str, formatstr, "Divide", MTEX_DIV);
134         
135         str += sprintf(str, formatstr, "Darken", MTEX_DARK);
136         str += sprintf(str, formatstr, "Lighten", MTEX_LIGHT);
137
138         return string;
139 }
140
141 void shade_buttons_change_3d(void)
142 {
143         Object *ob= OBACT;
144         ScrArea *sa;
145         
146         if(ob==NULL) return;
147         
148         for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
149                 if(sa->spacetype==SPACE_VIEW3D) {
150                         View3D *v3d= sa->spacedata.first;
151                         
152                         if(v3d->drawtype >= OB_SOLID) addqueue(sa->win, REDRAW, 0);
153                         if(v3d->drawtype == OB_SHADED) {
154                                 if(ob->type==OB_LAMP) reshadeall_displist();
155                                 else {
156                                         /* all objects using material */
157                                         Base *base= FIRSTBASE;
158                                         Material *ma= give_current_material(ob, ob->actcol);    
159                                         int a;
160                                         
161                                         while(base) {
162                                                 if(base->lay & G.vd->lay) {
163                                                         for(a=1; a<=ob->totcol; a++) {
164                                                                 if(ma == give_current_material(base->object, a)) {
165                                                                         freedisplist(&(base->object->disp));
166                                                                         break;
167                                                                 }
168                                                         }
169                                                 }
170                                                 base= base->next;
171                                         }
172                                 }
173                         }
174                 }
175         }       
176 }
177
178 /* *************************** TEXTURE ******************************** */
179
180 static void load_image_cb(char *str, void *ima_pp_v, void *iuser_v)     /* called from fileselect or button */
181 {
182         Image **ima_pp= (Image **)ima_pp_v;
183         Image *ima= NULL;
184         
185         ima= BKE_add_image_file(str);
186         if(ima) {
187                 if(*ima_pp) {
188                         (*ima_pp)->id.us--;
189                 }
190                 *ima_pp= ima;
191
192                 BKE_image_signal(ima, iuser_v, IMA_SIGNAL_RELOAD);
193                 
194                 /* button event gets lost when it goes via filewindow */
195                 if(G.buts && G.buts->lockpoin) {
196                         Tex *tex= G.buts->lockpoin;
197                         if(GS(tex->id.name)==ID_TE) {
198                                 BIF_preview_changed(ID_TE);
199                                 allqueue(REDRAWBUTSSHADING, 0);
200                         }
201                 }
202         }
203
204         BIF_undo_push("Load image");
205 }
206
207 static void load_plugin_tex(char *str, void *tex_v, void *unused)       /* called from fileselect */
208 {
209         Tex *tex= tex_v;
210         
211         if(tex->type!=TEX_PLUGIN) return;
212         
213         if(tex->plugin) free_plugin_tex(tex->plugin);
214         
215         tex->stype= 0;
216         tex->plugin= add_plugin_tex(str);
217
218         allqueue(REDRAWBUTSSHADING, 0);
219         BIF_preview_changed(ID_TE);
220 }
221
222 static void save_env(char *name)
223 {
224         Tex *tex;
225         char str[FILE_MAX];
226         
227         strcpy(str, name);
228         BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
229         tex= G.buts->lockpoin;
230         
231         if(tex && GS(tex->id.name)==ID_TE) {
232                 if(tex->env && tex->env->ok && saveover(str)) {
233                         waitcursor(1);
234                         BIF_save_envmap(tex->env, str);
235                         strcpy(G.ima, name);
236                         waitcursor(0);
237                 }
238         }
239         
240 }
241
242 static int vergcband(const void *a1, const void *a2)
243 {
244         const CBData *x1=a1, *x2=a2;
245         
246         if( x1->pos > x2->pos ) return 1;
247         else if( x1->pos < x2->pos) return -1;
248         return 0;
249 }
250
251 void do_texbuts(unsigned short event)
252 {
253         Tex *tex;
254         ScrArea *sa;
255         char str[FILE_MAX];
256         
257         tex= G.buts->lockpoin;
258         
259         switch(event) {
260         case B_TEXPRV:
261                 BIF_preview_changed(ID_TE);
262                 allqueue(REDRAWBUTSSHADING, 0);
263                 
264                 if(tex && G.scene->nodetree) {
265                         NodeTagIDChanged(G.scene->nodetree, &tex->id);
266                         allqueue(RECALC_COMPOSITE, 0);
267                 }
268                 break;
269         case B_TEXCHANNEL:
270                 scrarea_queue_headredraw(curarea);
271                 BIF_preview_changed(ID_TE);
272                 allqueue(REDRAWBUTSSHADING, 0);
273                 break;
274         case B_TEXTYPE:
275                 if(tex==NULL) return;
276                 tex->stype= 0;
277                 allqueue(REDRAWBUTSSHADING, 0);
278                 BIF_preview_changed(ID_TE);
279                 
280                 if(tex && G.scene->nodetree) {
281                         NodeTagIDChanged(G.scene->nodetree, &tex->id);
282                         allqueue(RECALC_COMPOSITE, 0);
283                 }
284                 break;
285         case B_DEFTEXVAR:
286                 if(tex==NULL) return;
287                 default_tex(tex);
288                 BIF_undo_push("Default texture vars");
289                 allqueue(REDRAWBUTSSHADING, 0);
290                 BIF_preview_changed(ID_TE);
291                 break;
292                 
293         case B_IMAGECHANGED:
294                 BIF_preview_changed(ID_TE);
295                 allqueue(REDRAWBUTSSHADING, 0);
296                 
297                 if(tex) {
298                         if(G.scene->nodetree) {
299                                 NodeTagIDChanged(G.scene->nodetree, &tex->id);
300                                 allqueue(RECALC_COMPOSITE, 0);
301                         }
302                         if(tex->ima && (tex->imaflag & TEX_MIPMAP) && (tex->ima->flag & IMA_FIELDS)) {
303                                 error("Cannot combine fields and mipmap");
304                                 tex->imaflag -= TEX_MIPMAP;
305                         }
306                         if(tex->env)
307                                 BKE_free_envmapdata(tex->env);
308                 }
309                         
310                 break;
311                 
312         case B_TEXREDR_PRV:
313                 allqueue(REDRAWBUTSSHADING, 0);
314                 BIF_preview_changed(ID_TE);
315                 shade_buttons_change_3d();
316                 break;
317
318
319         case B_LOADPLUGIN:
320                 if(tex==NULL) return;
321                         
322                 sa= closest_bigger_area();
323                 areawinset(sa->win);
324                 if(tex->plugin) strcpy(str, tex->plugin->name);
325                 else {
326                         strcpy(str, U.plugtexdir);
327                 }
328                 activate_fileselect_args(FILE_SPECIAL, "SELECT PLUGIN", str, load_plugin_tex, tex, NULL);
329                 
330                 break;
331
332         case B_NAMEPLUGIN:
333                 if(tex==NULL || tex->plugin==NULL) return;
334                 strcpy(str, tex->plugin->name);
335                 free_plugin_tex(tex->plugin);
336                 tex->stype= 0;
337                 tex->plugin= add_plugin_tex(str);
338                 allqueue(REDRAWBUTSSHADING, 0);
339                 BIF_preview_changed(ID_TE);
340                 break;
341         
342         case B_COLORBAND:
343                 if(tex==NULL) return;
344                 if(tex->coba==NULL) tex->coba= add_colorband(0);
345                 allqueue(REDRAWBUTSSHADING, 0);
346                 BIF_preview_changed(ID_TE); // also ramps, so we do this
347                 break;
348         
349         case B_ENV_DELETE:
350                 if(tex->env) {
351                         BKE_free_envmap(tex->env);
352                         tex->env= 0;
353                         allqueue(REDRAWBUTSSHADING, 0);
354                         BIF_preview_changed(ID_TE);
355                 }
356                 break;
357         case B_ENV_FREE:
358                 if(tex->env) {
359                         BKE_free_envmapdata(tex->env);
360                         allqueue(REDRAWBUTSSHADING, 0);
361                         BIF_preview_changed(ID_TE);
362                 }
363                 break;
364         case B_ENV_FREE_ALL:
365                 tex= G.main->tex.first;
366                 while(tex) {
367                         if(tex->id.us && tex->type==TEX_ENVMAP) {
368                                 if(tex->env) {
369                                         if(tex->env->stype!=ENV_LOAD) BKE_free_envmapdata(tex->env);
370                                 }
371                         }
372                         tex= tex->id.next;
373                 }
374                 allqueue(REDRAWBUTSSHADING, 0);
375                 BIF_preview_changed(ID_TE);
376                 break;
377         case B_ENV_SAVE:
378                 if(tex->env && tex->env->ok) {
379                         if(tex->env->type==ENV_PLANE) {
380                                 notice("Sorry, not implemented yet");
381                         }
382                         else {
383                                 sa= closest_bigger_area();
384                                 areawinset(sa->win);
385                                 save_image_filesel_str(str);
386                                 activate_fileselect(FILE_SPECIAL, str, G.ima, save_env);
387                         }
388                 }
389                 break;  
390         case B_ENV_OB:
391                 if(tex->env && tex->env->object) {
392                         BIF_preview_changed(ID_TE);
393                         if ELEM(tex->env->object->type, OB_CAMERA, OB_LAMP) {
394                                 error("Camera or Lamp not allowed");
395                                 tex->env->object= NULL;
396                         }
397                 }
398                 break;
399                 
400         default:
401                 if(event>=B_PLUGBUT && event<=B_PLUGBUT+23) {
402                         PluginTex *pit= tex->plugin;
403                         if(pit && pit->callback) {
404                                 pit->callback(event - B_PLUGBUT);
405                                 BIF_preview_changed(ID_TE);
406                                 allqueue(REDRAWBUTSSHADING, 0);
407                         }
408                 }
409         }
410 }
411
412 static void texture_panel_plugin(Tex *tex)
413 {
414         uiBlock *block;
415         VarStruct *varstr;
416         PluginTex *pit;
417         short xco, yco, a;
418         
419         block= uiNewBlock(&curarea->uiblocks, "texture_panel_plugin", UI_EMBOSS, UI_HELV, curarea->win);
420         if(uiNewPanel(curarea, block, "Plugin", "Texture", 640, 0, 318, 204)==0) return;
421         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
422
423         if(tex->plugin && tex->plugin->doit) {
424                 
425                 pit= tex->plugin;
426                 
427                 for(a=0; a<pit->stypes; a++) {
428                         uiDefButS(block, ROW, B_TEXREDR_PRV, pit->stnames+16*a, (76*a), 152, 75, 20, &tex->stype, 2.0, (float)a, 0, 0, "");
429                 }
430                 
431                 varstr= pit->varstr;
432                 if(varstr) {
433                         for(a=0; a<pit->vars; a++, varstr++) {
434                                 xco= 140*(a/6)+1;
435                                 yco= 125 - 20*(a % 6)+1;
436                                 uiDefBut(block, varstr->type, B_PLUGBUT+a, varstr->name, xco,yco,137,19, &(pit->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip);
437                         }
438                 }
439                 uiDefBut(block, TEX, B_NAMEPLUGIN, "",          0,180,318,24, pit->name, 0.0, 159.0, 0, 0, "");
440         }
441
442         uiDefBut(block, BUT, B_LOADPLUGIN, "Load Plugin", 0,204,137,24, 0, 0, 0, 0, 0, "");
443                         
444 }
445
446
447 static void texture_panel_magic(Tex *tex)
448 {
449         uiBlock *block;
450         
451         block= uiNewBlock(&curarea->uiblocks, "texture_panel_magic", UI_EMBOSS, UI_HELV, curarea->win);
452         if(uiNewPanel(curarea, block, "Magic", "Texture", 640, 0, 318, 204)==0) return;
453         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
454
455         uiBlockBeginAlign(block);
456         uiDefButS(block, NUM, B_TEXPRV, "Depth:",               10, 90, 150, 19, &tex->noisedepth, 0.0, 10.0, 0, 0, "Sets the depth of the pattern");
457         uiDefButF(block, NUM, B_TEXPRV, "Turbulence:",  10, 70, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Sets the strength of the pattern");
458 }
459
460 static void texture_panel_blend(Tex *tex)
461 {
462         uiBlock *block;
463         
464         block= uiNewBlock(&curarea->uiblocks, "texture_panel_blend", UI_EMBOSS, UI_HELV, curarea->win);
465         if(uiNewPanel(curarea, block, "Blend", "Texture", 640, 0, 318, 204)==0) return;
466         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
467
468         uiBlockBeginAlign(block);
469         uiDefButS(block, ROW, B_TEXPRV, "Lin",          10, 180, 75, 19, &tex->stype, 2.0, 0.0, 0, 0, "Creates a linear progresion"); 
470         uiDefButS(block, ROW, B_TEXPRV, "Quad",         85, 180, 75, 19, &tex->stype, 2.0, 1.0, 0, 0, "Creates a quadratic progression"); 
471         uiDefButS(block, ROW, B_TEXPRV, "Ease",         160, 180, 75, 19, &tex->stype, 2.0, 2.0, 0, 0, "Creates a progression easing from one step to the next"); 
472         uiDefButBitS(block, TOG, TEX_FLIPBLEND, B_TEXPRV, "Flip XY",    235, 180, 75, 19, &tex->flag, 0, 0, 0, 0, "Flips the direction of the progression 90 degrees");
473
474         uiDefButS(block, ROW, B_TEXPRV, "Diag",         10, 160, 75, 19, &tex->stype, 2.0, 3.0, 0, 0, "Use a diagonal progression");
475         uiDefButS(block, ROW, B_TEXPRV, "Sphere",       85, 160, 75, 19, &tex->stype, 2.0, 4.0, 0, 0, "Use progression with the shape of a sphere");
476         uiDefButS(block, ROW, B_TEXPRV, "Halo",         160, 160, 75, 19, &tex->stype, 2.0, 5.0, 0, 0, "Use a quadratic progression with the shape of a sphere");
477         uiDefButS(block, ROW, B_TEXPRV, "Radial",       235, 160, 75, 19, &tex->stype, 2.0, 6.0, 0, 0, "Use a polar progression");
478         
479 }
480
481 /* newnoise: noisebasis menu string */
482 static char* noisebasis_menu()
483 {
484         static char nbmenu[256];
485         sprintf(nbmenu, "Noise Basis %%t|Blender Original %%x%d|Original Perlin %%x%d|Improved Perlin %%x%d|Voronoi F1 %%x%d|Voronoi F2 %%x%d|Voronoi F3 %%x%d|Voronoi F4 %%x%d|Voronoi F2-F1 %%x%d|Voronoi Crackle %%x%d|CellNoise %%x%d", TEX_BLENDER, TEX_STDPERLIN, TEX_NEWPERLIN, TEX_VORONOI_F1, TEX_VORONOI_F2, TEX_VORONOI_F3, TEX_VORONOI_F4, TEX_VORONOI_F2F1, TEX_VORONOI_CRACKLE, TEX_CELLNOISE);
486         return nbmenu;
487 }
488
489 static void texture_panel_wood(Tex *tex)
490 {
491         uiBlock *block;
492         
493         block= uiNewBlock(&curarea->uiblocks, "texture_panel_wood", UI_EMBOSS, UI_HELV, curarea->win);
494         if(uiNewPanel(curarea, block, "Wood", "Texture", 640, 0, 318, 204)==0) return;
495         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
496         
497         uiBlockBeginAlign(block);
498         uiDefButS(block, ROW, B_TEXPRV, "Bands",                10, 180, 75, 18, &tex->stype, 2.0, 0.0, 0, 0, "Uses standard wood texture in bands"); 
499         uiDefButS(block, ROW, B_TEXPRV, "Rings",                85, 180, 75, 18, &tex->stype, 2.0, 1.0, 0, 0, "Uses wood texture in rings"); 
500         uiDefButS(block, ROW, B_TEXPRV, "BandNoise",    160, 180, 75, 18, &tex->stype, 2.0, 2.0, 0, 0, "Adds noise to standard wood"); 
501         uiDefButS(block, ROW, B_TEXPRV, "RingNoise",    235, 180, 75, 18, &tex->stype, 2.0, 3.0, 0, 0, "Adds noise to rings");
502         
503         uiDefButS(block, ROW, B_TEXPRV, "Sin",                  10, 160, 50, 19, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands"); 
504         uiDefButS(block, ROW, B_TEXPRV, "Saw",                  60, 160, 50, 19, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands"); 
505         uiDefButS(block, ROW, B_TEXPRV, "Tri",                  110, 160, 50, 19, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands");
506         uiDefButS(block, ROW, B_TEXPRV, "Soft noise",   160, 160, 75, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Generates soft noise");
507         uiDefButS(block, ROW, B_TEXPRV, "Hard noise",   235, 160, 75, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Generates hard noise");
508         
509         uiBlockBeginAlign(block);
510         uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :",  10, 130, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
511         uiDefButF(block, NUM, B_TEXPRV, "Turbulence:",  160, 130, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Sets the turbulence of the bandnoise and ringnoise types");
512         uiBlockEndAlign(block);
513         
514         /* newnoise: noisebasis menu */
515         uiDefBut(block, LABEL, 0, "Noise Basis",                10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
516         uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(),     10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
517         uiDefButF(block, NUM, B_NOP, "Nabla: ",                 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");      
518         
519 }
520
521 static void texture_panel_stucci(Tex *tex)
522 {
523         uiBlock *block;
524         
525         block= uiNewBlock(&curarea->uiblocks, "texture_panel_stucci", UI_EMBOSS, UI_HELV, curarea->win);
526         if(uiNewPanel(curarea, block, "Stucci", "Texture", 640, 0, 318, 204)==0) return;
527         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
528
529         uiBlockBeginAlign(block);
530         uiDefButS(block, ROW, B_TEXPRV, "Plastic",              10, 180, 100, 19, &tex->stype, 2.0, 0.0, 0, 0, "Uses standard stucci");
531         uiDefButS(block, ROW, B_TEXPRV, "Wall In",              110, 180, 100, 19, &tex->stype, 2.0, 1.0, 0, 0, "Creates Dimples"); 
532         uiDefButS(block, ROW, B_TEXPRV, "Wall Out",             210, 180, 100, 19, &tex->stype, 2.0, 2.0, 0, 0, "Creates Ridges"); 
533         
534         uiDefButS(block, ROW, B_TEXPRV, "Soft noise",   10, 160, 150, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Generates soft noise");
535         uiDefButS(block, ROW, B_TEXPRV, "Hard noise",   160, 160, 150, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Generates hard noise");
536
537         uiBlockBeginAlign(block);
538         uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :",  10, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
539         uiDefButF(block, NUM, B_TEXPRV, "Turbulence:",  10, 90, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Sets the depth of the stucci");
540         uiBlockEndAlign(block);
541
542         /* newnoise: noisebasis menu */
543         uiDefBut(block, LABEL, 0, "Noise Basis",                10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
544         uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(),     10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
545         // note, nabla not supported here!
546 //      uiDefButF(block, NUM, B_NOP, "Nabla: ",                 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");      
547
548 }
549
550 static void texture_panel_marble(Tex *tex)
551 {
552         uiBlock *block;
553         
554         block= uiNewBlock(&curarea->uiblocks, "texture_panel_marble", UI_EMBOSS, UI_HELV, curarea->win);
555         if(uiNewPanel(curarea, block, "Marble", "Texture", 640, 0, 318, 204)==0) return;
556         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
557         
558         uiBlockBeginAlign(block);
559         uiDefButS(block, ROW, B_TEXPRV, "Soft",                 10, 180, 100, 18, &tex->stype, 2.0, 0.0, 0, 0, "Uses soft marble"); 
560         uiDefButS(block, ROW, B_TEXPRV, "Sharp",                110, 180, 100, 18, &tex->stype, 2.0, 1.0, 0, 0, "Uses more clearly defined marble"); 
561         uiDefButS(block, ROW, B_TEXPRV, "Sharper",              210, 180, 100, 18, &tex->stype, 2.0, 2.0, 0, 0, "Uses very clearly defined marble"); 
562         
563         uiDefButS(block, ROW, B_TEXPRV, "Soft noise",   10, 160, 150, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Generates soft noise");
564         uiDefButS(block, ROW, B_TEXPRV, "Hard noise",   160, 160, 150, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Generates hard noise");
565         
566         uiDefButS(block, ROW, B_TEXPRV, "Sin",                  10, 140, 100, 18, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands."); 
567         uiDefButS(block, ROW, B_TEXPRV, "Saw",                  110, 140, 100, 18, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands"); 
568         uiDefButS(block, ROW, B_TEXPRV, "Tri",                  210, 140, 100, 18, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands"); 
569         
570         uiBlockBeginAlign(block);
571         uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :",  10, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
572         uiDefButS(block, NUM, B_TEXPRV, "NoiseDepth:",  10, 90, 150, 19, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the marble calculation");
573         uiDefButF(block, NUM, B_TEXPRV, "Turbulence:",  10, 70, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Sets the turbulence of the sine bands");
574         uiBlockEndAlign(block);
575         
576         /* newnoise: noisebasis menu */
577         uiDefBut(block, LABEL, 0, "Noise Basis",                10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
578         uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(),     10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
579         uiDefButF(block, NUM, B_NOP, "Nabla: ",                 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");      
580         
581 }
582
583 static void texture_panel_clouds(Tex *tex)
584 {
585         uiBlock *block;
586         
587         block= uiNewBlock(&curarea->uiblocks, "texture_panel_clouds", UI_EMBOSS, UI_HELV, curarea->win);
588         if(uiNewPanel(curarea, block, "Clouds", "Texture", 640, 0, 318, 204)==0) return;
589         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
590
591         uiBlockBeginAlign(block);
592         uiDefButS(block, ROW, B_TEXPRV, "Default",              10, 180, 70, 18, &tex->stype, 2.0, 0.0, 0, 0, "Uses standard noise"); 
593         uiDefButS(block, ROW, B_TEXPRV, "Color",                80, 180, 70, 18, &tex->stype, 2.0, 1.0, 0, 0, "Lets Noise return RGB value"); 
594         uiDefButS(block, ROW, B_TEXPRV, "Soft noise",   155, 180, 75, 18, &tex->noisetype, 12.0, 0.0, 0, 0, "Generates soft noise");
595         uiDefButS(block, ROW, B_TEXPRV, "Hard noise",   230, 180, 80, 18, &tex->noisetype, 12.0, 1.0, 0, 0, "Generates hard noise");
596         uiBlockBeginAlign(block);
597         uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :",  10, 130, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
598         uiDefButS(block, NUM, B_TEXPRV, "NoiseDepth:",  160, 130, 150, 19, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the cloud calculation");
599         uiBlockEndAlign(block);
600         
601         /* newnoise: noisebasis menu */
602         uiDefBut(block, LABEL, 0, "Noise Basis",                10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
603         uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(),     10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
604         uiDefButF(block, NUM, B_NOP, "Nabla: ",                 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");      
605
606 }
607
608 /*****************************************/
609 /* newnoise: panel(s) for musgrave types */
610 /*****************************************/
611
612 static void texture_panel_musgrave(Tex *tex)
613 {
614         uiBlock *block;
615         char *str;
616         
617         block= uiNewBlock(&curarea->uiblocks, "texture_panel_musgrave", UI_EMBOSS, UI_HELV, curarea->win);
618         if(uiNewPanel(curarea, block, "Musgrave", "Texture", 640, 0, 318, 204)==0) return;
619         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
620
621         str= "Multifractal %x0|Ridged Multifractal %x1|Hybrid Multifractal %x2|Hetero Terrain %x4|fBm %x3";
622         uiDefButS(block, MENU, B_TEXREDR_PRV, str, 10, 160, 150, 19, &tex->stype, 0.0, 0.0, 0, 0, "Sets Musgrave type");
623         
624         uiBlockBeginAlign(block);
625         uiDefButF(block, NUMSLI, B_TEXPRV, "H: ", 10, 130, 150, 19, &tex->mg_H, 0.0001, 2.0, 10, 0, "Sets the highest fractal dimension");
626         uiDefButF(block, NUMSLI, B_TEXPRV, "Lacu: ", 160, 130, 150, 19, &tex->mg_lacunarity, 0.0, 6.0, 10, 0, "Sets the gap between succesive frequencies");
627         uiDefButF(block, NUMSLI, B_TEXPRV, "Octs: ", 10, 110, 150, 19, &tex->mg_octaves, 0.0, 8.0, 10, 0, "Sets the number of frequencies used");
628         if ((tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF) || (tex->stype==TEX_HTERRAIN)) {
629                 uiDefButF(block, NUMSLI, B_TEXPRV, "Ofst: ", 160, 110, 150, 19, &tex->mg_offset, 0.0, 6.0, 10, 0, "Sets the fractal offset");
630                 if ((tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF))
631                         uiDefButF(block, NUMSLI, B_TEXPRV, "Gain: ", 10, 90, 150, 19, &tex->mg_gain, 0.0, 6.0, 10, 0, "Sets the gain multiplier");
632         }
633
634         uiBlockBeginAlign(block);
635         /* noise output scale */
636         uiDefButF(block, NUM, B_TEXPRV, "iScale: ", 10, 60, 150, 19, &tex->ns_outscale, 0.0, 10.0, 10, 0, "Scales intensity output");   
637         /* frequency scale */
638         uiDefButF(block, NUM, B_TEXPRV, "NoiseSize: ",  160, 60, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
639         uiBlockEndAlign(block);
640
641         /* noisebasis menu */
642         uiDefBut(block, LABEL, 0, "Noise Basis", 10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
643         uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
644         uiDefButF(block, NUM, B_NOP, "Nabla: ", 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");      
645
646 }
647
648
649 static void texture_panel_distnoise(Tex *tex)
650 {
651         uiBlock *block;
652         block= uiNewBlock(&curarea->uiblocks, "texture_panel_distnoise", UI_EMBOSS, UI_HELV, curarea->win);
653         if(uiNewPanel(curarea, block, "Distorted Noise", "Texture", 640, 0, 318, 204)==0) return;
654         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
655
656         uiBlockBeginAlign(block);
657         /* distortion amount */
658         uiDefButF(block, NUM, B_TEXPRV, "DistAmnt: ", 10, 130, 150, 19, &tex->dist_amount, 0.0, 10.0, 10, 0, "Sets amount of distortion");      
659         /* frequency scale */
660         uiDefButF(block, NUM, B_TEXPRV, "NoiseSize: ",  160, 130, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
661         uiBlockEndAlign(block);
662         
663         uiDefBut(block, LABEL, 0, "Distortion Noise", 10, 100, 150, 19, 0, 0.0, 0.0, 0, 0, "");
664         uiDefBut(block, LABEL, 0, "Noise Basis",        160, 100, 150, 19, 0, 0.0, 0.0, 0, 0, "");
665
666         uiBlockBeginAlign(block);
667         /* noisebasis used for the distortion */        
668         uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 10, 80, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis which does the distortion");
669         /* noisebasis to distort */
670         uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 160, 80, 150, 19, &tex->noisebasis2, 0,0,0,0, "Sets the noise basis to distort");
671         uiBlockEndAlign(block);
672
673         uiDefButF(block, NUM, B_NOP, "Nabla: ", 10, 50, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");       
674 }
675
676
677 static void texture_panel_voronoi(Tex *tex)
678 {
679         char dm_menu[256];
680         uiBlock *block;
681         block= uiNewBlock(&curarea->uiblocks, "texture_panel_voronoi", UI_EMBOSS, UI_HELV, curarea->win);
682         if(uiNewPanel(curarea, block, "Voronoi", "Texture", 640, 0, 318, 204)==0) return;
683         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
684
685         /* color types */
686         uiBlockBeginAlign(block);
687         uiDefButS(block, ROW, B_TEXPRV, "Int", 10, 180, 75, 18, &tex->vn_coltype, 1.0, 0.0, 0, 0, "Only calculate intensity"); 
688         uiDefButS(block, ROW, B_TEXPRV, "Col1", 85, 180, 75, 18, &tex->vn_coltype, 1.0, 1.0, 0, 0, "Color cells by position"); 
689         uiDefButS(block, ROW, B_TEXPRV, "Col2", 160, 180, 75, 18, &tex->vn_coltype, 1.0, 2.0, 0, 0, "Same as Col1 + outline based on F2-F1"); 
690         uiDefButS(block, ROW, B_TEXPRV, "Col3", 235, 180, 75, 18, &tex->vn_coltype, 1.0, 3.0, 0, 0, "Same as Col2 * intensity"); 
691         uiBlockEndAlign(block);
692
693         /* distance metric */
694         sprintf(dm_menu, "Distance Metric %%t|Actual Distance %%x%d|Distance Squared %%x%d|Manhattan %%x%d|Chebychev %%x%d|Minkovsky 1/2 %%x%d|Minkovsky 4 %%x%d|Minkovsky %%x%d", TEX_DISTANCE, TEX_DISTANCE_SQUARED, TEX_MANHATTAN, TEX_CHEBYCHEV, TEX_MINKOVSKY_HALF, TEX_MINKOVSKY_FOUR, TEX_MINKOVSKY);
695         uiDefBut(block, LABEL, B_TEXPRV, "Distance Metric", 10, 160, 150, 19, 0, 0, 0, 0, 0, "");
696         uiDefButS(block, MENU, B_TEXPRV, dm_menu, 10, 140, 150, 19, &tex->vn_distm, 0,0,0,0, "Sets the distance metric to be used");
697
698         if (tex->vn_distm==TEX_MINKOVSKY)
699                 uiDefButF(block, NUMSLI, B_TEXPRV, "Exp: ", 10, 120, 150, 19, &tex->vn_mexp, 0.01, 10.0, 10, 0, "Sets minkovsky exponent");
700
701         uiBlockBeginAlign(block);
702         uiDefButF(block, NUM, B_TEXPRV, "iScale: ", 160, 140, 150, 19, &tex->ns_outscale, 0.01, 10.0, 10, 0, "Scales intensity output");
703         uiDefButF(block, NUM, B_TEXPRV, "Size: ",       160, 120, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
704         uiBlockBeginAlign(block);
705         uiDefButF(block, NUM, B_NOP, "Nabla: ",         160, 70, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");      
706
707         /* weights */
708         uiBlockBeginAlign(block);
709         uiDefButF(block, NUMSLI, B_TEXPRV, "W1: ", 10, 70, 150, 19, &tex->vn_w1, -2.0, 2.0, 10, 0, "Sets feature weight 1");
710         uiDefButF(block, NUMSLI, B_TEXPRV, "W2: ", 10, 50, 150, 19, &tex->vn_w2, -2.0, 2.0, 10, 0, "Sets feature weight 2");
711         uiDefButF(block, NUMSLI, B_TEXPRV, "W3: ", 10, 30, 150, 19, &tex->vn_w3, -2.0, 2.0, 10, 0, "Sets feature weight 3");
712         uiDefButF(block, NUMSLI, B_TEXPRV, "W4: ", 10, 10, 150, 19, &tex->vn_w4, -2.0, 2.0, 10, 0, "Sets feature weight 4");
713 }
714
715
716 static char *layer_menu(RenderResult *rr, short *curlay)
717 {
718         RenderLayer *rl;
719         int len= 64 + 32*BLI_countlist(&rr->layers);
720         short a, nr= 0;
721         char *str= MEM_callocN(len, "menu layers");
722         
723         strcpy(str, "Layer %t");
724         a= strlen(str);
725         
726         /* compo result */
727         if(rr->rectf) {
728                 a+= sprintf(str+a, "|Composite %%x0");
729                 nr= 1;
730         }
731         for(rl= rr->layers.first; rl; rl= rl->next, nr++) {
732                 a+= sprintf(str+a, "|%s %%x%d", rl->name, nr);
733         }
734         
735         if(*curlay >= nr)
736                 *curlay= 0;
737         
738         return str;
739 }
740
741 /* rl==NULL means composite result */
742 static char *pass_menu(RenderLayer *rl, short *curpass)
743 {
744         RenderPass *rpass;
745         int len= 64 + 32*(rl?BLI_countlist(&rl->passes):1);
746         short a, nr= 0;
747         char *str= MEM_callocN(len, "menu layers");
748         
749         strcpy(str, "Pass %t");
750         a= strlen(str);
751         
752         /* rendered results don't have a Combined pass */
753         if(rl==NULL || rl->rectf) {
754                 a+= sprintf(str+a, "|Combined %%x0");
755                 nr= 1;
756         }
757         
758         if(rl)
759                 for(rpass= rl->passes.first; rpass; rpass= rpass->next, nr++)
760                         a+= sprintf(str+a, "|%s %%x%d", rpass->name, nr);
761         
762         if(*curpass >= nr)
763                 *curpass= 0;
764         
765         return str;
766 }
767
768 static void set_frames_cb(void *ima_v, void *iuser_v)
769 {
770         Image *ima= ima_v;
771         ImageUser *iuser= iuser_v;
772         
773         if(ima->anim) {
774                 iuser->frames = IMB_anim_get_duration(ima->anim);
775                 BKE_image_user_calc_imanr(iuser, G.scene->r.cfra, 0);
776         }
777 }
778
779 static void image_src_change_cb(void *ima_v, void *iuser_v)
780 {
781         BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_SRC_CHANGE);
782 }
783
784 /* buttons have 2 arg callbacks, filewindow has 3 args... so thats why the wrapper below */
785 static void image_browse_cb1(char *unused, void *ima_pp_v, void *iuser_v)
786 {
787         Image **ima_pp= (Image **)ima_pp_v;
788         ImageUser *iuser= iuser_v;
789         
790         if(ima_pp) {
791                 Image *ima= *ima_pp;
792                 
793                 if(iuser->menunr== -2) {
794                         activate_databrowse_args(&ima->id, ID_IM, 0, &iuser->menunr, image_browse_cb1, ima_pp, iuser);
795                 } 
796                 else if (iuser->menunr>0) {
797                         Image *newima= (Image*) BLI_findlink(&G.main->image, iuser->menunr-1);
798                         
799                         if (newima && newima!=ima) {
800                                 *ima_pp= newima;
801                                 id_us_plus(&newima->id);
802                                 if(ima) ima->id.us--;
803                                 
804                                 BKE_image_signal(newima, iuser, IMA_SIGNAL_USER_NEW_IMAGE);
805                                 
806                                 BIF_undo_push("Browse image");
807                         }
808                 }
809         }
810 }
811
812 static void image_browse_cb(void *ima_pp_v, void *iuser_v)
813 {
814         image_browse_cb1(NULL, ima_pp_v, iuser_v);
815 }
816
817 static void image_reload_cb(void *ima_v, void *iuser_v)
818 {
819         if(ima_v) {
820                 BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_RELOAD);
821         }
822 }
823
824 static void image_field_test(void *ima_v, void *iuser_v)
825 {
826         Image *ima= ima_v;
827         
828         if(ima) {
829                 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
830                 if(ibuf) {
831                         short nr= 0;
832                         if( !(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1;
833                         if( (ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1;
834                         if(nr) {
835                                 BKE_image_signal(ima, iuser_v, IMA_SIGNAL_FREE);
836                         }
837                 }
838         }
839 }
840
841 static void image_unlink_cb(void *ima_pp_v, void *unused)
842 {
843         Image **ima_pp= (Image **)ima_pp_v;
844         
845         if(ima_pp && *ima_pp) {
846                 Image *ima= *ima_pp;
847                 ima->id.us--;
848                 *ima_pp= NULL;
849         }
850 }
851
852 static void image_load_fs_cb(void *ima_pp_v, void *iuser_v)
853 {
854         Image **ima_pp= (Image **)ima_pp_v;
855         ScrArea *sa;
856         char *name;
857         
858         if(ima_pp==NULL) return;
859         
860         sa= closest_bigger_area();
861         areawinset(sa->win);
862         if(*ima_pp) name= (*ima_pp)->name;
863 #ifdef _WIN32
864         else {
865                 if (strcmp (U.textudir, "/") == 0)
866                         name= G.sce;
867                 else
868                         name= U.textudir;
869         }
870 #else
871         else name = U.textudir;
872 #endif
873         activate_fileselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
874 }
875
876 /* 5 layer button callbacks... */
877 static void image_multi_cb(void *rr_v, void *iuser_v) 
878 {
879         BKE_image_multilayer_index(rr_v, iuser_v); 
880 }
881 static void image_multi_inclay_cb(void *rr_v, void *iuser_v) 
882 {
883         RenderResult *rr= rr_v;
884         ImageUser *iuser= iuser_v;
885         int tot= BLI_countlist(&rr->layers) + (rr->rectf?1:0);  /* fake compo result layer */
886         if(iuser->layer<tot-1)
887                 iuser->layer++;
888         BKE_image_multilayer_index(rr, iuser); 
889 }
890 static void image_multi_declay_cb(void *rr_v, void *iuser_v) 
891 {
892         ImageUser *iuser= iuser_v;
893         if(iuser->layer>0)
894                 iuser->layer--;
895         BKE_image_multilayer_index(rr_v, iuser); 
896 }
897 static void image_multi_incpass_cb(void *rr_v, void *iuser_v) 
898 {
899         RenderResult *rr= rr_v;
900         ImageUser *iuser= iuser_v;
901         RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer);
902         if(rl) {
903                 int tot= BLI_countlist(&rl->passes) + (rl->rectf?1:0);  /* builtin render result has no combined pass in list */
904                 if(iuser->pass<tot-1) {
905                         iuser->pass++;
906                         BKE_image_multilayer_index(rr, iuser); 
907                 }
908         }
909 }
910 static void image_multi_decpass_cb(void *rr_v, void *iuser_v) 
911 {
912         ImageUser *iuser= iuser_v;
913         if(iuser->pass>0) {
914                 iuser->pass--;
915                 BKE_image_multilayer_index(rr_v, iuser); 
916         }
917 }
918
919 static void image_pack_cb(void *ima_v, void *iuser_v) 
920 {
921         if(ima_v) {
922                 Image *ima= ima_v;
923                 if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) {
924                         if (ima->packedfile) {
925                                 if (G.fileflags & G_AUTOPACK) {
926                                         if (okee("Disable AutoPack ?")) {
927                                                 G.fileflags &= ~G_AUTOPACK;
928                                         }
929                                 }
930                                 
931                                 if ((G.fileflags & G_AUTOPACK) == 0) {
932                                         unpackImage(ima, PF_ASK);
933                                         BIF_undo_push("Unpack image");
934                                 }
935                         } 
936                         else {
937                                 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
938                                 if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
939                                         error("Can't pack painted image. Save image or use Repack as PNG.");
940                                 } else {
941                                         ima->packedfile = newPackedFile(ima->name);
942                                         BIF_undo_push("Pack image");
943                                 }
944                         }
945                 }
946         }
947 }
948
949 static void image_load_cb(void *ima_pp_v, void *iuser_v)
950 {
951         if(ima_pp_v) {
952                 Image *ima= *((Image **)ima_pp_v);
953                 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
954                 char str[FILE_MAX];
955         
956                 /* name in ima has been changed by button! */
957                 BLI_strncpy(str, ima->name, FILE_MAX);
958                 if(ibuf) BLI_strncpy(ima->name, ibuf->name, FILE_MAX);
959                 
960                 load_image_cb(str, ima_pp_v, iuser_v);
961         }
962 }
963
964 static void image_freecache_cb(void *ima_v, void *unused) 
965 {
966         BKE_image_free_anim_ibufs(ima_v, G.scene->r.cfra);
967         allqueue(REDRAWIMAGE, 0);
968 }
969
970 static void image_generated_change_cb(void *ima_v, void *iuser_v)
971 {
972         BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_FREE);
973 }
974
975 static void image_user_change(void *iuser_v, void *unused)
976 {
977         BKE_image_user_calc_imanr(iuser_v, G.scene->r.cfra, 0);
978 }
979
980 void uiblock_layer_pass_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int event, int x, int y, int w)
981 {
982         uiBut *but;
983         RenderLayer *rl= NULL;
984         int wmenu1, wmenu2;
985         char *strp;
986
987         /* layer menu is 1/3 larger than pass */
988         wmenu1= (3*w)/5;
989         wmenu2= (2*w)/5;
990         
991         /* menu buts */
992         strp= layer_menu(rr, &iuser->layer);
993         but= uiDefButS(block, MENU, event, strp,                                        x, y, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer");
994         uiButSetFunc(but, image_multi_cb, rr, iuser);
995         MEM_freeN(strp);
996         
997         rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */
998         strp= pass_menu(rl, &iuser->pass);
999         but= uiDefButS(block, MENU, event, strp,                                        x+wmenu1, y, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass");
1000         uiButSetFunc(but, image_multi_cb, rr, iuser);
1001         MEM_freeN(strp);        
1002 }
1003
1004 static void uiblock_layer_pass_arrow_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int imagechanged) 
1005 {
1006         uiBut *but;
1007         
1008         if(rr==NULL || iuser==NULL)
1009                 return;
1010         if(rr->layers.first==NULL) {
1011                 uiDefBut(block, LABEL, 0, "No Layers in Render Result,",        10, 107, 300, 20, NULL, 1, 0, 0, 0, "");
1012                 return;
1013         }
1014         
1015         uiBlockBeginAlign(block);
1016
1017         /* decrease, increase arrows */
1018         but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT,     10,107,17,20, NULL, 0, 0, 0, 0, "Previous Layer");
1019         uiButSetFunc(but, image_multi_declay_cb, rr, iuser);
1020         but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT,    27,107,18,20, NULL, 0, 0, 0, 0, "Next Layer");
1021         uiButSetFunc(but, image_multi_inclay_cb, rr, iuser);
1022
1023         uiblock_layer_pass_buttons(block, rr, iuser, imagechanged, 45, 107, 230);
1024
1025         /* decrease, increase arrows */
1026         but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT,     275,107,17,20, NULL, 0, 0, 0, 0, "Previous Pass");
1027         uiButSetFunc(but, image_multi_decpass_cb, rr, iuser);
1028         but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT,    292,107,18,20, NULL, 0, 0, 0, 0, "Next Pass");
1029         uiButSetFunc(but, image_multi_incpass_cb, rr, iuser);
1030
1031         uiBlockEndAlign(block);
1032                          
1033 }
1034
1035 /* The general Image panel with the loadsa callbacks! */
1036 void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser, 
1037                                                  short redraw, short imagechanged)
1038 {
1039         Image *ima= *ima_pp;
1040         uiBut *but;
1041         char str[128], *strp;
1042         
1043         /* different stuff when we show viewer */
1044         if(ima && ima->source==IMA_SRC_VIEWER) {
1045                 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser);
1046                 
1047                 image_info(ima, ibuf, str);
1048                 uiDefBut(block, LABEL, 0, ima->id.name+2,       10, 180, 300, 20, NULL, 1, 0, 0, 0, "");
1049                 uiDefBut(block, LABEL, 0, str,                          10, 160, 300, 20, NULL, 1, 0, 0, 0, "");
1050                 
1051                 if(ima->type==IMA_TYPE_COMPOSITE) {
1052                         iuser= ntree_get_active_iuser(G.scene->nodetree);
1053                         
1054                         uiBlockBeginAlign(block);
1055                         uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, "");
1056                         uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play",    110,120,100,20, 0, 0, 0, 0, 0, "");
1057                         but= uiDefBut(block, BUT, B_NOP, "Free Cache",  210,120,100,20, 0, 0, 0, 0, 0, "");
1058                         uiButSetFunc(but, image_freecache_cb, ima, NULL);
1059                         
1060                         if(iuser->frames)
1061                                 sprintf(str, "(%d) Frames:", iuser->framenr);
1062                         else strcpy(str, "Frames:");
1063                         uiBlockBeginAlign(block);
1064                         uiDefButI(block, NUM, imagechanged, str,                10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
1065                         uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
1066                 }
1067                 else if(ima->type==IMA_TYPE_R_RESULT) {
1068                         /* browse layer/passes */
1069                         uiblock_layer_pass_arrow_buttons(block, RE_GetResult(RE_GetRender(G.scene->id.name)), iuser, imagechanged);
1070                 }
1071                 return;
1072         }
1073         
1074         /* the main ima source types */
1075         if(ima) {
1076                 uiSetButLock(ima->id.lib!=NULL, "Can't edit library data");
1077                 uiBlockBeginAlign(block);
1078                 uiBlockSetFunc(block, image_src_change_cb, ima, iuser);
1079                 uiDefButS(block, ROW, imagechanged, "Still",            10, 180, 60, 20, &ima->source, 0.0, IMA_SRC_FILE, 0, 0, "Single Image file");
1080                 uiDefButS(block, ROW, imagechanged, "Movie",            70, 180, 60, 20, &ima->source, 0.0, IMA_SRC_MOVIE, 0, 0, "Movie file");
1081                 uiDefButS(block, ROW, imagechanged, "Sequence", 130, 180, 90, 20, &ima->source, 0.0, IMA_SRC_SEQUENCE, 0, 0, "Multiple Image files, as a sequence");
1082                 uiDefButS(block, ROW, imagechanged, "Generated",        220, 180, 90, 20, &ima->source, 0.0, IMA_SRC_GENERATED, 0, 0, "Generated Image");
1083                 uiBlockSetFunc(block, NULL, NULL, NULL);
1084         }
1085         else
1086                 uiDefBut(block, LABEL, 0, " ",                                  10, 180, 300, 20, 0, 0, 0, 0, 0, "");   /* for align in panel */
1087                                  
1088          /* Browse */
1089          IMAnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), NULL, &iuser->menunr);
1090          
1091          uiBlockBeginAlign(block);
1092          but= uiDefButS(block, MENU, imagechanged, strp,                10,155,23,20, &iuser->menunr, 0, 0, 0, 0, "Selects an existing Image or Movie");
1093          uiButSetFunc(but, image_browse_cb, ima_pp, iuser);
1094          
1095          MEM_freeN(strp);
1096          
1097          /* name + options, or only load */
1098          if(ima) {
1099                  int drawpack= (ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE && ima->ok);
1100
1101                  but= uiDefBut(block, TEX, B_IDNAME, "IM:",             33, 155, 177, 20, ima->id.name+2, 0.0, 19.0, 0, 0, "Current Image Datablock name.");
1102                  uiButSetFunc(but, test_idbutton_cb, ima->id.name, NULL);
1103                  but= uiDefBut(block, BUT, imagechanged, "Reload",              210, 155, 60, 20, NULL, 0, 0, 0, 0, "Reloads Image or Movie");
1104                  uiButSetFunc(but, image_reload_cb, ima, iuser);
1105                  
1106                  but= uiDefIconBut(block, BUT, imagechanged, ICON_X,    270,155,20,20, 0, 0, 0, 0, 0, "Unlink Image block");
1107                  uiButSetFunc(but, image_unlink_cb, ima_pp, NULL);
1108                  sprintf(str, "%d", ima->id.us);
1109                  uiDefBut(block, BUT, B_NOP, str,                                       290,155,20,20, 0, 0, 0, 0, 0, "Only displays number of users of Image block");
1110                  
1111                  but= uiDefIconBut(block, BUT, imagechanged, ICON_FILESEL,      10, 135, 23, 20, 0, 0, 0, 0, 0, "Open Fileselect to load new Image");
1112                  uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser);
1113                  but= uiDefBut(block, TEX, imagechanged, "",                            33,135,257+(drawpack?0:20),20, ima->name, 0.0, 239.0, 0, 0, "Image/Movie file name, change to load new");
1114                  uiButSetFunc(but, image_load_cb, ima_pp, iuser);
1115                  
1116                  if(drawpack) {
1117                          if (ima->packedfile) packdummy = 1;
1118                          else packdummy = 0;
1119                          but= uiDefIconButBitI(block, TOG, 1, redraw, ICON_PACKAGE, 290,135,20,20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this Image");
1120                          uiButSetFunc(but, image_pack_cb, ima, iuser);
1121                  }
1122                  
1123          }
1124          else {
1125                  but= uiDefBut(block, BUT, imagechanged, "Load",                33, 155, 100,20, NULL, 0, 0, 0, 0, "Load new Image of Movie");
1126                  uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser);
1127          }
1128          uiBlockEndAlign(block);
1129          
1130          if(ima) {
1131                  ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser);
1132                  
1133                  /* check for re-render, only buttons */
1134                  if(imagechanged==B_IMAGECHANGED) {
1135                          if(iuser->flag & IMA_ANIM_REFRESHED) {
1136                                  iuser->flag &= ~IMA_ANIM_REFRESHED;
1137                                  BIF_preview_changed(ID_TE);
1138                          }
1139                  }
1140                  
1141                  /* multilayer? */
1142                  if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
1143                          uiblock_layer_pass_arrow_buttons(block, ima->rr, iuser, imagechanged);
1144                  }
1145                  else {
1146                          image_info(ima, ibuf, str);
1147                          uiDefBut(block, LABEL, 0, str,         10, 107, 300, 20, NULL, 1, 0, 0, 0, "");
1148                  }
1149                  
1150                  /* left side default per-image options, right half the additional options */
1151                  
1152                  /* fields */
1153                  uiBlockBeginAlign(block);
1154                  but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields",      10, 70, 100, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
1155                  uiButSetFunc(but, image_field_test, ima, iuser);
1156                  uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd",                  10, 50, 100, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
1157                  uiBlockEndAlign(block);
1158                  
1159                  uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti",                   10, 10, 100, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
1160                  
1161                  if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
1162                          sprintf(str, "(%d) Frames:", iuser->framenr);
1163                          
1164                          uiBlockBeginAlign(block);
1165                          uiBlockSetFunc(block, image_user_change, iuser, NULL);
1166                          uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh",       120, 70, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes");
1167                          
1168                          if(ima->anim) {
1169                                  uiDefButI(block, NUM, imagechanged, str,               120, 50,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
1170                                  but= uiDefBut(block, BUT, redraw, "<",         290, 50, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
1171                                  uiButSetFunc(but, set_frames_cb, ima, iuser);
1172                          }
1173                          else 
1174                                  uiDefButI(block, NUM, imagechanged, str,               120, 50,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use");
1175                          
1176                          uiDefButI(block, NUM, imagechanged, "Offs:",   120,30,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
1177                          uiDefButS(block, NUM, imagechanged, "Fie/Ima:",        220,30,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)");
1178                          
1179                          uiDefButI(block, NUM, imagechanged, "StartFr:",        120,10,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
1180                          uiDefButS(block, TOG, imagechanged, "Cyclic",  220,10,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie");
1181                          
1182                          uiBlockSetFunc(block, NULL, iuser, NULL);
1183                  }
1184                  else if(ima->source==IMA_SRC_GENERATED) {
1185                          
1186                          uiBlockBeginAlign(block);
1187                          uiBlockSetFunc(block, image_generated_change_cb, ima, iuser);
1188                          uiDefButS(block, NUM, imagechanged, "SizeX:",  120,70,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x");
1189                          uiDefButS(block, NUM, imagechanged, "SizeY:",  220,70,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y");
1190                          uiDefButS(block, TOG, imagechanged, "UV Test grid",120,50,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, "");
1191                          uiBlockSetFunc(block, NULL, NULL, NULL);
1192                  }
1193          }
1194
1195 }       
1196
1197 static void texture_panel_image(Image **ima, ImageUser *iuser)
1198 {
1199         uiBlock *block;
1200         
1201         block= uiNewBlock(&curarea->uiblocks, "texture_panel_image", UI_EMBOSS, UI_HELV, curarea->win);
1202         if(uiNewPanel(curarea, block, "Image", "Texture", 960, 0, 318, 204)==0) return;
1203         
1204         uiblock_image_panel(block, ima, iuser, B_REDR, B_IMAGECHANGED);
1205 }       
1206
1207 static void texture_panel_image_map(Tex *tex)
1208 {
1209         uiBlock *block;
1210         
1211         block= uiNewBlock(&curarea->uiblocks, "texture_panel_image_map", UI_EMBOSS, UI_HELV, curarea->win);
1212         if(uiNewPanel(curarea, block, "Map Image", "Texture", 640, 0, 318, 204)==0) return;
1213         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
1214
1215         /* types */
1216         uiBlockBeginAlign(block);
1217         uiDefButBitS(block, TOG, TEX_MIPMAP, B_IMAGECHANGED, "MipMap",  10, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Generates and uses mipmaps");
1218         uiDefButBitS(block, TOG, TEX_GAUSS_MIP, 0, "Gauss",                     85, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Enable Gauss filter to sample down mipmaps");
1219         uiDefButBitS(block, TOG, TEX_INTERPOL, 0, "Interpol",           160, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Interpolates pixels using Area filter");
1220         uiDefButBitS(block, TOG, TEX_IMAROT, B_TEXPRV, "Rot90",         235, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Actually flips X and Y for rendering, rotates and mirrors");
1221         
1222         uiDefButBitS(block, TOG, TEX_USEALPHA, B_TEXPRV, "UseAlpha",    10, 160, 100, 20, &tex->imaflag, 0, 0, 0, 0, "Click to use Image's alpha channel");
1223         uiDefButBitS(block, TOG, TEX_CALCALPHA, B_TEXPRV, "CalcAlpha",  110, 160, 100, 20, &tex->imaflag, 0, 0, 0, 0, "Click to calculate an alpha channel based on Image RGB values");
1224         uiDefButBitS(block, TOG, TEX_NEGALPHA, B_TEXPRV, "NegAlpha",    210, 160, 100, 20, &tex->flag, 0, 0, 0, 0, "Click to invert the alpha values");
1225         uiBlockEndAlign(block);
1226
1227         uiDefButF(block, NUM, B_TEXPRV, "Filter :",                                             10,120,150,20, &tex->filtersize, 0.1, 25.0, 10, 3, "Sets the filter size used by mipmap and interpol");
1228         
1229         uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map",    160,120,150,20, &tex->imaflag,
1230                                         0, 0, 0, 0, "Use image RGB values for normal mapping");
1231
1232         /* crop extend clip */
1233         
1234         uiBlockBeginAlign(block);
1235         uiDefButS(block, ROW, B_TEXREDR_PRV, "Extend",                  10,90,63,19, &tex->extend, 4.0, 1.0, 0, 0, "Extends the colour of the edge pixels");
1236         uiDefButS(block, ROW, B_TEXREDR_PRV, "Clip",                    73,90,48,19, &tex->extend, 4.0, 2.0, 0, 0, "Sets alpha 0.0 outside Image edges");
1237         uiDefButS(block, ROW, B_TEXREDR_PRV, "ClipCube",                121,90,63,19, &tex->extend, 4.0, 4.0, 0, 0, "Sets alpha to 0.0 outside cubeshaped area around Image");
1238         uiDefButS(block, ROW, B_TEXREDR_PRV, "Repeat",                  184,90,63,19, &tex->extend, 4.0, 3.0, 0, 0, "Causes Image to repeat horizontally and vertically");
1239         uiDefButS(block, ROW, B_TEXREDR_PRV, "Checker",                 247,90,63,19, &tex->extend, 4.0, 5.0, 0, 0, "Causes Image to repeat in checker pattern");
1240
1241         if(tex->extend==TEX_REPEAT) {
1242                 uiBlockBeginAlign(block);
1243                 uiDefButBitS(block, TOG, TEX_REPEAT_XMIR, B_TEXPRV, "Mirr",     10,60,30,19, &tex->flag, 0.0, 0.0, 0, 0, "Mirrors X direction repeat");
1244                 uiDefButS(block, NUM, B_TEXPRV, "Xrepeat:",     40,60,120,19, &tex->xrepeat, 1.0, 512.0, 0, 0, "Sets a repetition multiplier in the X direction");
1245                 uiDefButBitS(block, TOG, TEX_REPEAT_YMIR, B_TEXPRV, "Mirr",     160,60,30,19, &tex->flag, 0.0, 0.0, 0, 0, "Mirrors Y direction repeat");
1246                 uiDefButS(block, NUM, B_TEXPRV, "Yrepeat:",     190,60,120,19, &tex->yrepeat, 1.0, 512.0, 0, 0, "Sets a repetition multiplier in the Y direction");
1247         }
1248         else if(tex->extend==TEX_CHECKER) {
1249                 uiBlockBeginAlign(block);
1250                 uiDefButBitS(block, TOG, TEX_CHECKER_ODD, B_TEXPRV, "Odd",      10,60,100,19, &tex->flag, 0.0, 0.0, 0, 0, "Sets odd checker tiles");
1251                 uiDefButBitS(block, TOG, TEX_CHECKER_EVEN, B_TEXPRV, "Even",    110,60,100,19, &tex->flag, 0.0, 0.0, 0, 0, "Sets even checker tiles");
1252                 uiDefButF(block, NUM, B_TEXPRV, "Mortar:",              210,60,100,19, &tex->checkerdist, 0.0, 0.99, 0, 0, "Set checkers distance (like mortar)");
1253         }
1254         uiBlockBeginAlign(block);
1255         uiDefButF(block, NUM, B_TEXPRV, "MinX ",                10,30,150,19, &tex->cropxmin, -10.0, 10.0, 10, 0, "Sets minimum X value to crop Image");
1256         uiDefButF(block, NUM, B_TEXPRV, "MinY ",                10,10,150,19, &tex->cropymin, -10.0, 10.0, 10, 0, "Sets minimum Y value to crop Image");
1257
1258         uiBlockBeginAlign(block);
1259         uiDefButF(block, NUM, B_TEXPRV, "MaxX ",                160,30,150,19, &tex->cropxmax, -10.0, 10.0, 10, 0, "Sets maximum X value to crop Image");
1260         uiDefButF(block, NUM, B_TEXPRV, "MaxY ",                160,10,150,19, &tex->cropymax, -10.0, 10.0, 10, 0, "Sets maximum Y value to crop Image");
1261         uiBlockEndAlign(block);
1262
1263 }
1264
1265 /***************************************/
1266
1267 static void texture_panel_envmap(Tex *tex)
1268 {
1269         uiBlock *block;
1270         uiBut *but;
1271         EnvMap *env;
1272         ID *id;
1273         short a, xco, yco, dx, dy;
1274         char *strp, str[32];
1275         
1276         block= uiNewBlock(&curarea->uiblocks, "texture_panel_envmap", UI_EMBOSS, UI_HELV, curarea->win);
1277         if(uiNewPanel(curarea, block, "Envmap", "Texture", 640, 0, 318, 204)==0) return;
1278         uiSetButLock(tex->id.lib!=0, "Can't edit library data");
1279         
1280         if(tex->env==NULL) {
1281                 tex->env= BKE_add_envmap();
1282                 tex->env->object= OBACT;
1283         }
1284         if(tex->env) {
1285                 env= tex->env;
1286                 
1287                 uiBlockBeginAlign(block);
1288                 uiDefButS(block, ROW, B_REDR,   "Static",       10, 180, 100, 19, &env->stype, 2.0, 0.0, 0, 0, "Calculates environment map only once");
1289                 uiDefButS(block, ROW, B_REDR,   "Anim",         110, 180, 100, 19, &env->stype, 2.0, 1.0, 0, 0, "Calculates environment map at each rendering");
1290                 uiDefButS(block, ROW, B_ENV_FREE, "Load",       210, 180, 100, 19, &env->stype, 2.0, 2.0, 0, 0, "Loads saved environment map from disk");
1291                 uiBlockEndAlign(block);
1292                 
1293                 if(env->stype==ENV_LOAD) {
1294                         /* file input */
1295                         id= (ID *)tex->ima;
1296                         IMAnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(G.buts->menunr));
1297                         if(strp[0]) {
1298                                 uiBlockBeginAlign(block);
1299                                 
1300                                 but= uiDefButS(block, MENU, B_TEXPRV, strp,             10,145,23,20, &tex->iuser.menunr, 0, 0, 0, 0, "Selects an existing environment map");
1301                                 uiButSetFunc(but, image_browse_cb, &tex->ima, &tex->iuser);
1302                                 
1303                                 if(tex->ima) {
1304                                         but= uiDefBut(block, TEX, B_NAMEIMA, "",                        35,145,255,20, tex->ima->name, 0.0, 79.0, 0, 0, "Displays environment map name: click to change");
1305                                         uiButSetFunc(but, image_load_cb, &tex->ima, &tex->iuser);
1306                                         
1307                                         sprintf(str, "%d", tex->ima->id.us);
1308                                         uiDefBut(block, BUT, 0, str,                            290,145,20,20, 0, 0, 0, 0, 0, "Displays number of users of environment map: click to make single user");
1309                                         uiBlockEndAlign(block);
1310                                         
1311                                         but= uiDefBut(block, BUT, B_IMAGECHANGED, "Reload",     230,125,80,20, 0, 0, 0, 0, 0, "Reloads saved environment map");
1312                                         uiButSetFunc(but, image_reload_cb, tex->ima, NULL);
1313                                         
1314                                         if (tex->ima->packedfile) packdummy = 1;
1315                                         else packdummy = 0;
1316                                         but= uiDefIconButBitI(block, TOG, 1, B_REDR, ICON_PACKAGE, 205,125,24,20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this environment map");
1317                                         uiButSetFunc(but, image_pack_cb, tex->ima, &tex->iuser);
1318                                 }
1319                                 else uiBlockEndAlign(block);
1320                         }
1321                         MEM_freeN(strp);
1322                         
1323                         but= uiDefBut(block, BUT, B_IMAGECHANGED, "Load Image", 10,125,150,20, 0, 0, 0, 0, 0, "Loads saved environment map - file select");
1324                         uiButSetFunc(but, image_load_fs_cb, &tex->ima, &tex->iuser);
1325                 }
1326                 else {
1327                         uiBlockBeginAlign(block);
1328                         uiDefBut(block, BUT, B_ENV_FREE, "Free Data",   10,145,100,20, 0, 0, 0, 0, 0, "Releases all images associated with this environment map");
1329                         uiDefBut(block, BUT, B_ENV_SAVE, "Save EnvMap", 110,145,100,20, 0, 0, 0, 0, 0, "Saves current environment map");
1330                         uiDefBut(block, BUT, B_ENV_FREE_ALL, "Free all EnvMaps", 210,145,100,20, 0, 0, 0, 0, 0, "Frees all rendered environment maps for all materials");
1331                         
1332                         uiBlockBeginAlign(block);
1333                         uiDefButS(block, ROW, B_NOP, "Cube",                    10,120,100,20, &env->type, 3.0f, 0.0f, 0, 0, "Use environment map with six cube sides");
1334                         uiDefButS(block, ROW, B_NOP, "Plane",                   110,120,100,20, &env->type, 3.0f, 1.0f, 0, 0, "Only one side is rendered, with Z axis pointing in direction of image");
1335                         uiDefButF(block, NUM, B_NOP, "Zoom: ",                  210,120,100,20, &env->viewscale, 0.5f, 5.0f, 100, 2, "Zoom factor for planar environment map");
1336                         uiBlockEndAlign(block);
1337                 }
1338                 
1339                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_ENV_OB, "Ob:",  10,90,150,20, &(env->object), "Displays object to use as viewpoint for environment map: click to change");
1340                 if(env->stype!=ENV_LOAD) 
1341                         uiDefButS(block, NUM, B_ENV_FREE,       "CubeRes",              160,90,150,20, &env->cuberes, 50, 4096.0, 0, 0, "Sets the pixel resolution of the rendered environment map");
1342                 
1343                 uiBlockBeginAlign(block);
1344                 uiDefButF(block, NUM, B_TEXPRV, "Filter :",                             10,65,150,20, &tex->filtersize, 0.1, 25.0, 0, 3, "Adjusts sharpness or blurriness of the reflection"),
1345                         uiDefButS(block, NUM, B_ENV_FREE, "Depth:",                             160,65,150,20, &env->depth, 0, 5.0, 0, 0, "Sets the number of times a map will be rendered recursively mirror effects"),
1346                         uiDefButF(block, NUM, REDRAWVIEW3D,     "ClipSta",              10,40,150,20, &env->clipsta, 0.01, 50.0, 100, 0, "Sets start value for clipping: objects nearer than this are not visible to map");
1347                 uiDefButF(block, NUM, B_NOP,    "ClipEnd",                                      160,40,150,20, &env->clipend, 0.1, 5000.0, 1000, 0, "Sets end value for clipping beyond which objects are not visible to map");
1348                 uiBlockEndAlign(block);
1349                 
1350                 uiDefBut(block, LABEL, 0, "Don't render layer:",                10,10,140,22, 0, 0.0, 0.0, 0, 0, "");   
1351                 xco= 160;
1352                 yco= 10;
1353                 dx= 28;
1354                 dy= 26;
1355                 
1356                 uiBlockBeginAlign(block);
1357                 for(a=0; a<5; a++) 
1358                         uiDefButBitI(block, TOG, 1<<a, 0, "",   (xco+a*(dx/2)), (yco+dy/2), (dx/2), (1+dy/2), &env->notlay, 0, 0, 0, 0, "Toggles layer visibility to environment map");
1359                 for(a=0; a<5; a++) 
1360                         uiDefButBitI(block, TOG, 1<<(a+10), 0, "",(xco+a*(dx/2)), yco, (dx/2), (dy/2), &env->notlay, 0, 0, 0, 0, "Toggles layer visibility to environment map");
1361                 
1362                 uiBlockBeginAlign(block);
1363                 xco+= 5;
1364                 for(a=5; a<10; a++) 
1365                         uiDefButBitI(block, TOG, 1<<a, 0, "",   (xco+a*(dx/2)), (yco+dy/2), (dx/2), (1+dy/2), &env->notlay, 0, 0, 0, 0, "Toggles layer visibility to environment map");
1366                 for(a=5; a<10; a++) 
1367                         uiDefButBitI(block, TOG, 1<<(a+10), 0, "",(xco+a*(dx/2)), yco, (dx/2), (dy/2), &env->notlay, 0, 0, 0, 0, "Toggles layer visibility to environment map");
1368                 
1369         }
1370 }
1371
1372 static void colorband_pos_cb(void *coba_v, void *unused_v)
1373 {
1374         ColorBand *coba= coba_v;
1375         int a;
1376         
1377         if(coba->tot<2) return;
1378         
1379         for(a=0; a<coba->tot; a++) coba->data[a].cur= a;
1380         qsort(coba->data, coba->tot, sizeof(CBData), vergcband);
1381         for(a=0; a<coba->tot; a++) {
1382                 if(coba->data[a].cur==coba->cur) {
1383                         if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0);     /* button cur */
1384                         coba->cur= a;
1385                         break;
1386                 }
1387         }
1388 }
1389
1390 static void colorband_add_cb(void *coba_v, void *unused_v)
1391 {
1392         ColorBand *coba= coba_v;
1393         
1394         if(coba->tot < MAXCOLORBAND-1) coba->tot++;
1395         coba->cur= coba->tot-1;
1396         
1397         colorband_pos_cb(coba, NULL);
1398         BIF_undo_push("Add colorband");
1399         
1400 }
1401
1402 static void colorband_del_cb(void *coba_v, void *unused_v)
1403 {
1404         ColorBand *coba= coba_v;
1405         int a;
1406         
1407         if(coba->tot<2) return;
1408         
1409         for(a=coba->cur; a<coba->tot; a++) {
1410                 coba->data[a]= coba->data[a+1];
1411         }
1412         if(coba->cur) coba->cur--;
1413         coba->tot--;
1414         
1415         BIF_undo_push("Delete colorband");
1416         BIF_preview_changed(ID_TE);
1417 }
1418
1419
1420 /* offset aligns from bottom, standard width 300, height 115 */
1421 static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, int redraw)
1422 {
1423         CBData *cbd;
1424         uiBut *bt;
1425         
1426         if(coba==NULL) return;
1427         
1428         bt= uiDefBut(block, BUT, redraw,        "Add",          80+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Adds a new colour position to the colorband");
1429         uiButSetFunc(bt, colorband_add_cb, coba, NULL);
1430         uiDefButS(block, NUM, redraw,           "Cur:",         117+xoffs,95+yoffs,81,20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Displays the active colour from the colorband");
1431         bt= uiDefBut(block, BUT, redraw,                "Del",          199+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Deletes the active position");
1432         uiButSetFunc(bt, colorband_del_cb, coba, NULL);
1433         uiDefButS(block, ROW, redraw,            "E",           236+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) ");
1434         uiDefButS(block, ROW, redraw,           "C",            252+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal");
1435         uiDefButS(block, ROW, redraw,           "L",            268+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear");
1436         uiDefButS(block, ROW, redraw,           "S",            284+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline");
1437
1438         uiDefBut(block, BUT_COLORBAND, redraw, "",      xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, "");
1439         
1440         cbd= coba->data + coba->cur;
1441         
1442         uiBlockBeginAlign(block);
1443         bt= uiDefButF(block, NUM, redraw, "Pos",                xoffs,40+yoffs,110,20, &cbd->pos, 0.0, 1.0, 10, 0, "Sets the position of the active colour");
1444         uiButSetFunc(bt, colorband_pos_cb, coba, NULL);
1445         uiDefButF(block, COL, redraw,           "",             xoffs,20+yoffs,110,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "");
1446         uiDefButF(block, NUMSLI, redraw,        "A ",   xoffs,yoffs,110,20, &cbd->a, 0.0, 1.0, 10, 0, "Sets the alpha value for this position");
1447
1448         uiBlockBeginAlign(block);
1449         uiDefButF(block, NUMSLI, redraw,        "R ",   115+xoffs,40+yoffs,185,20, &cbd->r, 0.0, 1.0, B_BANDCOL, 0, "Sets the red value for the active colour");
1450         uiDefButF(block, NUMSLI, redraw,        "G ",   115+xoffs,20+yoffs,185,20, &cbd->g, 0.0, 1.0, B_BANDCOL, 0, "Sets the green value for the active colour");
1451         uiDefButF(block, NUMSLI, redraw,        "B ",   115+xoffs,yoffs,185,20, &cbd->b, 0.0, 1.0, B_BANDCOL, 0, "Sets the blue value for the active colour");
1452         uiBlockEndAlign(block);
1453 }
1454
1455 void draw_colorband_buts_small(uiBlock *block, ColorBand *coba, rctf *butr, int event)
1456 {
1457         CBData *cbd;
1458         uiBut *bt;
1459         float unit= (butr->xmax-butr->xmin)/12.0f;
1460         float xs= butr->xmin;
1461         
1462         cbd= coba->data + coba->cur;
1463         
1464         uiBlockBeginAlign(block);
1465         uiDefButF(block, COL, event,            "",                     xs,butr->ymin+20.0f,2.0f*unit,20,                               &(cbd->r), 0, 0, 0, B_BANDCOL, "");
1466         uiDefButF(block, NUM, event,            "A:",           xs+2.0f*unit,butr->ymin+20.0f,4.0f*unit,20,     &(cbd->a), 0.0f, 1.0f, 10, 2, "");
1467         bt= uiDefBut(block, BUT, event, "Del",          xs+6.0f*unit,butr->ymin+20.0f,2.0f*unit,20,     NULL, 0, 0, 0, 0, "Deletes the active position");
1468         uiButSetFunc(bt, colorband_del_cb, coba, NULL);
1469         uiDefButS(block, ROW, event,            "E",            xs+8.0f*unit,butr->ymin+20.0f,unit,20,          &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) ");
1470         uiDefButS(block, ROW, event,            "C",            xs+9.0f*unit,butr->ymin+20.0f,unit,20,          &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal");
1471         uiDefButS(block, ROW, event,            "L",            xs+10.0f*unit,butr->ymin+20.0f,unit,20,         &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear");
1472         uiDefButS(block, ROW, event,            "S",            xs+11.0f*unit,butr->ymin+20.0f,unit,20,         &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline");
1473         
1474         uiDefBut(block, BUT_COLORBAND, event, "",               xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, "");
1475         uiBlockEndAlign(block);
1476         
1477 }
1478
1479 static void texture_panel_colors(Tex *tex)
1480 {
1481         uiBlock *block;
1482         
1483         block= uiNewBlock(&curarea->uiblocks, "texture_panel_colors", UI_EMBOSS, UI_HELV, curarea->win);
1484         uiNewPanelTabbed("Texture", "Texture");
1485         if(uiNewPanel(curarea, block, "Colors", "Texture", 1280, 0, 318, 204)==0) return;
1486
1487
1488         /* COLORBAND */
1489         uiBlockBeginAlign(block);
1490         uiDefButBitS(block, TOG, TEX_COLORBAND, B_COLORBAND, "Colorband",10,180,80,20, &tex->flag, 0, 0, 0, 0, "Toggles colorband operations");
1491
1492         if(tex->flag & TEX_COLORBAND) {
1493                 draw_colorband_buts(block, tex->coba, 10, 85, B_TEXREDR_PRV);
1494         }
1495         
1496         /* RGB-BRICON */
1497         if((tex->flag & TEX_COLORBAND)==0) {
1498                 uiBlockBeginAlign(block);
1499                 uiDefButF(block, NUMSLI, B_TEXPRV, "R ",                60,80,200,20, &tex->rfac, 0.0, 2.0, 0, 0, "Changes the red value of the texture");
1500                 uiDefButF(block, NUMSLI, B_TEXPRV, "G ",                60,60,200,20, &tex->gfac, 0.0, 2.0, 0, 0, "Changes the green value of the texture");
1501                 uiDefButF(block, NUMSLI, B_TEXPRV, "B ",                60,40,200,20, &tex->bfac, 0.0, 2.0, 0, 0, "Changes the blue value of the texture");
1502         }
1503
1504         uiBlockBeginAlign(block);
1505         uiDefButF(block, NUMSLI, B_TEXPRV, "Bright",            10,10,150,20, &tex->bright, 0.0, 2.0, 0, 0, "Changes the brightness of the colour or intensity of a texture");
1506         uiDefButF(block, NUMSLI, B_TEXPRV, "Contr",                     160,10,150,20, &tex->contrast, 0.01, 5.0, 0, 0, "Changes the contrast of the colour or intensity of a texture");
1507 }
1508
1509
1510 static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *la, bNode *node, Brush *br, SculptData *sd)
1511 {
1512         MTex *mt=NULL;
1513         uiBlock *block;
1514         ID *id=NULL, *idfrom;
1515         int a, yco, loos;
1516         char str[32];
1517         
1518
1519         block= uiNewBlock(&curarea->uiblocks, "texture_panel_texture", UI_EMBOSS, UI_HELV, curarea->win);
1520         if(uiNewPanel(curarea, block, "Texture", "Texture", 320, 0, 318, 204)==0) return;
1521
1522         /* first do the browse but */
1523         if(mtex)
1524                 id= (ID *)mtex->tex;
1525         else if(node)
1526                 id= node->id;
1527         
1528         if(ma) idfrom= &ma->id;
1529         else if(wrld) idfrom= &wrld->id;
1530         else if(la) idfrom= &la->id;
1531         else if(br) idfrom= &br->id;
1532         else if(sd) idfrom= NULL; /* Not sure what this does */
1533         else idfrom= NULL;
1534         
1535         uiBlockSetCol(block, TH_BUT_SETTING2);
1536         if(ma) {
1537                 std_libbuttons(block, 10, 180, 0, NULL, B_TEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA);
1538         }
1539         else if(wrld) {
1540                 std_libbuttons(block, 10, 180, 0, NULL, B_WTEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA);
1541         }
1542         else if(la) {
1543                 std_libbuttons(block, 10, 180, 0, NULL, B_LTEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA);
1544         }
1545         else if(br) {
1546                 std_libbuttons(block, 10, 180, 0, NULL, B_BTEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->menunr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA);
1547         }
1548         else if(sd) {
1549                 std_libbuttons(block, 10, 180, 0, NULL, B_SCULPT_TEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA);
1550         }
1551         else if(node) {
1552
1553         }
1554         uiBlockSetCol(block, TH_BUT_NEUTRAL);
1555
1556         /* From button: removed */
1557
1558         /* CHANNELS */
1559         if(node==NULL) {
1560                 uiBlockBeginAlign(block);
1561                 yco= 150;
1562                 for(a= 0; a<MAX_MTEX; a++) {
1563                         
1564                         if(ma) mt= ma->mtex[a];
1565                         else if(wrld) mt= wrld->mtex[a];
1566                         else if(la) mt= la->mtex[a];
1567                         else if(br) mt= br->mtex[a];
1568                         else if(sd) mt= sd->mtex[a];
1569                         
1570                         if(mt && mt->tex) splitIDname(mt->tex->id.name+2, str, &loos);
1571                         else strcpy(str, "");
1572                         str[14]= 0;
1573
1574                         if(ma) {
1575                                 uiDefButC(block, ROW, B_TEXCHANNEL, str,        10,yco,140,19, &(ma->texact), 0.0, (float)a, 0, 0, "Click to select texture channel");
1576                                 yco-= 20;
1577                         }
1578                         else if(wrld) {
1579                                 uiDefButS(block, ROW, B_TEXCHANNEL, str,        10,yco,140,19, &(wrld->texact), 0.0, (float)a, 0, 0, "");
1580                                 yco-= 20;
1581                         }
1582                         else if(la) {
1583                                 uiDefButS(block, ROW, B_TEXCHANNEL, str,        10,yco,140,19, &(la->texact), 0.0, (float)a, 0, 0, "");
1584                                 yco-= 20;
1585                         }
1586                         else if(br) {
1587                                 uiDefButS(block, ROW, B_TEXCHANNEL, str,        10,yco,140,19, &(br->texact), 0.0, (float)a, 0, 0, "");
1588                                 yco-= 20;
1589                         }
1590                         else if(sd) {
1591                                 uiDefButS(block, ROW, B_TEXCHANNEL, str,        10,yco,140,19, &(sd->texact), 0.0, (float)a, 0, 0, "");
1592                                 yco-= 20;
1593                         }
1594                 }
1595                 uiBlockEndAlign(block);
1596         }       
1597         uiBlockSetCol(block, TH_AUTO);
1598
1599         /* TYPES */
1600         if(id) {
1601                 char textypes[512];
1602                 Tex *tex= (Tex *)id;
1603
1604                 uiSetButLock(tex->id.lib!=0, "Can't edit library data");
1605                 
1606                 /* newnoise: all texture types as menu, not enough room for more buttons.
1607                  * Can widen panel, but looks ugly when other panels overlap it */
1608                 
1609                 sprintf(textypes, "Texture Type %%t|None %%x%d|Image %%x%d|EnvMap %%x%d|Clouds %%x%d|Marble %%x%d|Stucci %%x%d|Wood %%x%d|Magic %%x%d|Blend %%x%d|Noise %%x%d|Plugin %%x%d|Musgrave %%x%d|Voronoi %%x%d|DistortedNoise %%x%d", 0, TEX_IMAGE, TEX_ENVMAP, TEX_CLOUDS, TEX_MARBLE, TEX_STUCCI, TEX_WOOD, TEX_MAGIC, TEX_BLEND, TEX_NOISE, TEX_PLUGIN, TEX_MUSGRAVE, TEX_VORONOI, TEX_DISTNOISE);
1610                 uiDefBut(block, LABEL, 0, "Texture Type",               160, 150, 140, 20, 0, 0.0, 0.0, 0, 0, "");
1611                 uiDefButS(block, MENU, B_TEXTYPE, textypes,     160, 125, 140, 25, &tex->type, 0,0,0,0, "Select texture type");
1612
1613         }
1614         else {
1615                 // label to avoid centering
1616                 uiDefBut(block, LABEL, 0, " ",  160, 10, 140, 20, 0, 0, 0, 0, 0, "");
1617         }
1618 }
1619
1620 static void texture_panel_preview(MTex *mtex, int preview)
1621 {
1622         uiBlock *block;
1623         
1624         block= uiNewBlock(&curarea->uiblocks, "texture_panel_preview", UI_EMBOSS, UI_HELV, curarea->win);
1625         if(uiNewPanel(curarea, block, "Preview", "Texture", 0, 0, 318, 204)==0) return;
1626         
1627         if(preview) uiBlockSetDrawExtraFunc(block, BIF_previewdraw);
1628
1629         // label to force a boundbox for buttons not to be centered
1630         uiDefBut(block, LABEL, 0, " ",  20,20,10,10, 0, 0, 0, 0, 0, "");
1631
1632         uiBlockBeginAlign(block);
1633         uiDefButC(block, ROW, B_TEXREDR_PRV, "Mat",             200,175,80,25, &G.buts->texfrom, 3.0, 0.0, 0, 0, "Displays the textures of the active material");
1634         uiDefButC(block, ROW, B_TEXREDR_PRV, "World",   200,150,80,25, &G.buts->texfrom, 3.0, 1.0, 0, 0, "Displays the textures of the world block");
1635         uiDefButC(block, ROW, B_TEXREDR_PRV, "Lamp",    200,125,80,25, &G.buts->texfrom, 3.0, 2.0, 0, 0, "Displays the textures of the selected lamp");
1636         uiDefButC(block, ROW, B_TEXREDR_PRV, "Brush",   200,100,80,25, &G.buts->texfrom, 3.0, 3.0, 0, 0, "Displays the textures of the selected brush");
1637         uiBlockEndAlign(block);
1638         
1639         if(mtex && mtex->tex)
1640                 uiDefButBitS(block, TOG, TEX_PRV_ALPHA, B_TEXREDR_PRV, "Alpha", 200,60,80,20, &mtex->tex->flag, 0, 0, 0, 0, "Show alpha in preview");
1641         
1642         uiDefBut(block, BUT, B_DEFTEXVAR, "Default Vars",200,10,80,20, 0, 0, 0, 0, 0, "Sets all values to defaults");
1643
1644 }
1645
1646
1647
1648 /* *************************** RADIO ******************************** */
1649
1650 void do_radiobuts(unsigned short event)
1651 {
1652         Radio *rad;
1653         int phase;
1654         
1655         phase= rad_phase();
1656         rad= G.scene->radio;
1657         
1658         switch(event) {
1659         case B_RAD_ADD:
1660                 add_radio();
1661                 BIF_undo_push("Add radiosity");
1662                 allqueue(REDRAWBUTSSHADING, 0);
1663                 allqueue(REDRAWVIEW3D, 0);
1664                 break;
1665         case B_RAD_DELETE:
1666                 delete_radio();
1667                 BIF_undo_push("Delete radiosity");
1668                 allqueue(REDRAWBUTSSHADING, 0);
1669                 allqueue(REDRAWVIEW3D, 0);
1670                 break;
1671         case B_RAD_FREE:
1672                 freeAllRad();
1673                 allqueue(REDRAWBUTSSHADING, 0);
1674                 allqueue(REDRAWVIEW3D, 0);
1675                 break;
1676         case B_RAD_COLLECT:
1677                 rad_collect_meshes();
1678                 allqueue(REDRAWBUTSSHADING, 0);
1679                 allqueue(REDRAWVIEW3D, 0);
1680                 break;
1681         case B_RAD_INIT:
1682                 if(phase==RAD_PHASE_PATCHES) {
1683                         rad_limit_subdivide();
1684                         allqueue(REDRAWBUTSSHADING, 0);
1685                         allqueue(REDRAWVIEW3D, 0);
1686                 }
1687                 break;
1688         case B_RAD_SHOOTP:
1689                 if(phase==RAD_PHASE_PATCHES) {
1690                         waitcursor(1);
1691                         rad_subdivshootpatch();
1692                         allqueue(REDRAWBUTSSHADING, 0);
1693                         allqueue(REDRAWVIEW3D, 0);
1694                         waitcursor(0);
1695                 }
1696                 break;
1697         case B_RAD_SHOOTE:
1698                 if(phase==RAD_PHASE_PATCHES) {
1699                         waitcursor(1);
1700                         rad_subdivshootelem();
1701                         allqueue(REDRAWBUTSSHADING, 0);
1702                         allqueue(REDRAWVIEW3D, 0);
1703                         waitcursor(0);
1704                 }
1705                 break;
1706         case B_RAD_GO:
1707                 if(phase==RAD_PHASE_PATCHES) {
1708                         waitcursor(1);
1709                         rad_go();
1710                         waitcursor(0);
1711                         allqueue(REDRAWBUTSSHADING, 0);
1712                         allqueue(REDRAWVIEW3D, 0);
1713                 }
1714                 break;
1715         case B_RAD_LIMITS:
1716                 rad_setlimits();
1717                 allqueue(REDRAWVIEW3D, 0);
1718                 allqueue(REDRAWBUTSSHADING, 0);
1719                 break;
1720         case B_RAD_FAC:
1721                 set_radglobal();
1722                 if(phase & RAD_PHASE_FACES) make_face_tab();
1723                 else make_node_display();       /* radio solver also uses nodes, different ones :) */
1724                 allqueue(REDRAWVIEW3D, 0);
1725                 break;
1726         case B_RAD_NODELIM:
1727                 if(phase & RAD_PHASE_FACES) {
1728                         set_radglobal();
1729                         removeEqualNodes(rad->nodelim);
1730                         make_face_tab();
1731                         allqueue(REDRAWVIEW3D, 0);
1732                         allqueue(REDRAWBUTSSHADING, 0);
1733                 }
1734                 break;
1735         case B_RAD_NODEFILT:
1736                 if(phase & RAD_PHASE_FACES) {
1737                         set_radglobal();
1738                         filterNodes();
1739                         make_face_tab();
1740                         allqueue(REDRAWVIEW3D, 0);
1741                 }
1742                 break;
1743         case B_RAD_FACEFILT:
1744                 if(phase & RAD_PHASE_FACES) {
1745                         filterFaces();
1746                         allqueue(REDRAWVIEW3D, 0);
1747                 }
1748                 break;
1749         case B_RAD_DRAW:
1750                 set_radglobal();
1751                 allqueue(REDRAWVIEW3D, 0);
1752                 break;
1753         case B_RAD_ADDMESH:
1754                 if(phase & RAD_PHASE_FACES) rad_addmesh();
1755                 BIF_undo_push("Radiosity add mesh");
1756                 allqueue(REDRAWVIEW3D, 0);
1757                 break;
1758         case B_RAD_REPLACE:
1759                 if(phase & RAD_PHASE_FACES) rad_replacemesh();
1760                 BIF_undo_push("Radiosity replace mesh");
1761                 allqueue(REDRAWVIEW3D, 0);
1762                 break;
1763         }
1764
1765 }
1766
1767
1768 static void radio_panel_calculation(Radio *rad, int flag)
1769 {
1770         uiBlock *block;
1771         
1772         block= uiNewBlock(&curarea->uiblocks, "radio_panel_calculation", UI_EMBOSS, UI_HELV, curarea->win);
1773         if(uiNewPanel(curarea, block, "Calculation", "Radio", 640, 0, 318, 204)==0) return;
1774         uiAutoBlock(block, 10, 10, 300, 200, UI_BLOCK_ROWS);
1775
1776         if(flag != RAD_PHASE_PATCHES) uiBlockSetCol(block, TH_BUT_NEUTRAL);
1777         uiDefBut(block,  BUT, B_RAD_GO, "GO",                                   0, 0, 10, 15, NULL, 0, 0, 0, 0, "Starts the radiosity simulation");
1778
1779         uiBlockSetCol(block, TH_AUTO);
1780         uiDefButS(block,  NUM, B_NOP, "SubSh Patch:",                           1, 0, 10, 10, &rad->subshootp, 0.0, 10.0, 0, 0, "Sets the number of times the environment is tested to detect pathes");
1781         uiDefButS(block,  NUM, B_NOP, "SubSh Element:",                         1, 0, 10, 10, &rad->subshoote, 0.0, 10.0, 0, 0, "Sets the number of times the environment is tested to detect elements");
1782
1783         if(flag != RAD_PHASE_PATCHES) uiBlockSetCol(block, TH_BUT_NEUTRAL);
1784         uiDefBut(block,  BUT, B_RAD_SHOOTE, "Subdiv Shoot Element", 2, 0, 10, 10, NULL, 0, 0, 0, 0, "For pre-subdivision, Detects high energy changes and subdivide Elements");
1785         uiDefBut(block,  BUT, B_RAD_SHOOTP, "Subdiv Shoot Patch",       2, 0, 10, 10, NULL, 0, 0, 0, 0, "For pre-subdivision, Detects high energy changes and subdivide Patches");
1786
1787         uiBlockSetCol(block, TH_AUTO);
1788         uiDefButI(block,  NUM, B_NOP, "MaxEl:",                                         3, 0, 10, 10, &rad->maxnode, 1.0, 250000.0, 0, 0, "Sets the maximum allowed number of elements");
1789         uiDefButS(block,  NUM, B_NOP, "Max Subdiv Shoot:",                      3, 0, 10, 10, &rad->maxsublamp, 1.0, 250.0, 0, 0, "Sets the maximum number of initial shoot patches that are evaluated");
1790
1791         if(flag & RAD_PHASE_FACES);
1792         else uiBlockSetCol(block, TH_BUT_NEUTRAL);
1793         uiDefBut(block,  BUT, B_RAD_FACEFILT, "FaceFilter",             4, 0, 10, 10, NULL, 0, 0, 0, 0, "Forces an extra smoothing");
1794         uiDefBut(block,  BUT, B_RAD_NODEFILT, "Element Filter", 4, 0, 10, 10, NULL, 0, 0, 0, 0, "Filters elements to remove aliasing artefacts");
1795
1796         uiDefBut(block,  BUT, B_RAD_NODELIM, "RemoveDoubles",   5, 0, 30, 10, NULL, 0.0, 50.0, 0, 0, "Joins elements which differ less than 'Lim'");
1797         uiBlockSetCol(block, TH_AUTO);
1798         uiDefButS(block,  NUM, B_NOP, "Lim:",                                           5, 0, 10, 10, &rad->nodelim, 0.0, 50.0, 0, 0, "Sets the range for removing doubles");
1799
1800
1801 }
1802
1803 static void radio_panel_tool(Radio *rad, int flag)
1804 {
1805         uiBlock *block;
1806         
1807         block= uiNewBlock(&curarea->uiblocks, "radio_panel_tool", UI_EMBOSS, UI_HELV, curarea->win);
1808         if(uiNewPanel(curarea, block, "Radio Tool", "Radio", 320, 0, 318, 204)==0) return;
1809         uiAutoBlock(block, 10, 10, 300, 200, UI_BLOCK_ROWS);
1810
1811         if(flag & RAD_PHASE_PATCHES) uiBlockSetCol(block, TH_BUT_SETTING1);
1812         uiDefBut(block,  BUT, B_RAD_COLLECT, "Collect Meshes",  0, 0, 10, 15, NULL, 0, 0, 0, 0, "Converts selected visible meshes to patches");
1813
1814         if(flag & RAD_PHASE_PATCHES)uiBlockSetCol(block, TH_AUTO);
1815         else uiBlockSetCol(block, TH_BUT_NEUTRAL);
1816         uiDefBut(block,  BUT, B_RAD_FREE, "Free Radio Data",    0, 0, 10, 15, NULL, 0, 0, 0, 0, "Releases all memory used by Radiosity");       
1817
1818         if(flag & RAD_PHASE_FACES) uiBlockSetCol(block, TH_AUTO);
1819         else uiBlockSetCol(block, TH_BUT_NEUTRAL);
1820         uiDefBut(block,  BUT, B_RAD_REPLACE, "Replace Meshes",  1, 0, 10, 12, NULL, 0, 0, 0, 0, "Converts meshes to Mesh objects with vertex colours, changing input-meshes");
1821         uiDefBut(block,  BUT, B_RAD_ADDMESH, "Add new Meshes",  1, 0, 10, 12, NULL, 0, 0, 0, 0, "Converts meshes to Mesh objects with vertex colours, unchanging input-meshes");
1822
1823         uiBlockSetCol(block, TH_AUTO);
1824         uiDefButS(block,  ROW, B_RAD_DRAW, "Wire",                      2, 0, 10, 10, &rad->drawtype, 0.0, 0.0, 0, 0, "Enables wireframe drawmode");
1825         uiDefButS(block,  ROW, B_RAD_DRAW, "Solid",                     2, 0, 10, 10, &rad->drawtype, 0.0, 1.0, 0, 0, "Enables solid drawmode");
1826         uiDefButS(block,  ROW, B_RAD_DRAW, "Gour",                      2, 0, 10, 10, &rad->drawtype, 0.0, 2.0, 0, 0, "Enables Gourad drawmode");
1827         uiDefButBitS(block,  TOG, 1, B_RAD_DRAW, "ShowLim", 2, 0, 10, 10, &rad->flag, 0, 0, 0, 0, "Draws patch and element limits");
1828         uiDefButBitS(block,  TOG, 2, B_RAD_DRAW, "Z",           2, 0, 3, 10, &rad->flag, 0, 0, 0, 0, "Draws limits differently");
1829
1830         uiDefButS(block,  NUM, B_RAD_LIMITS, "ElMax:",          3, 0, 10, 10, &rad->elma, 1.0, 500.0, 0, 0, "Sets maximum size of an element");
1831         uiDefButS(block,  NUM, B_RAD_LIMITS, "ElMin:",          3, 0, 10, 10, &rad->elmi, 1.0, 100.0, 0, 0, "Sets minimum size of an element");
1832         uiDefButS(block,  NUM, B_RAD_LIMITS, "PaMax:",          3, 0, 10, 10, &rad->pama, 10.0, 1000.0, 0, 0, "Sets maximum size of a patch");
1833         uiDefButS(block,  NUM, B_RAD_LIMITS, "PaMin:",          3, 0, 10, 10, &rad->pami, 10.0, 1000.0, 0, 0, "Sets minimum size of a patch");
1834
1835         uiDefBut(block,  BUT, B_RAD_INIT, "Limit Subdivide", 5, 0, 10, 10, NULL, 0, 0, 0, 0, "Subdivides patches");
1836 }
1837
1838
1839 static void radio_panel_render(Radio *rad)
1840 {
1841         uiBlock *block;
1842         
1843         block= uiNewBlock(&curarea->uiblocks, "radio_panel_render", UI_EMBOSS, UI_HELV, curarea->win);
1844         if(uiNewPanel(curarea, block, "Radio Render", "Radio", 0, 0, 318, 204)==0) return;
1845         uiAutoBlock(block, 210, 30, 230, 150, UI_BLOCK_ROWS);
1846
1847         uiDefButS(block,  NUMSLI, B_RAD_LIMITS, "Hemires:", 0, 0, 10, 10, &rad->hemires, 100.0, 1000.0, 100, 0, "Sets the size of a hemicube");
1848         uiDefButS(block,  NUM, B_NOP, "Max Iterations:",                2, 0, 10, 15, &rad->maxiter, 0.0, 10000.0, 0, 0, "Limits the maximum number of radiosity rounds");
1849         uiDefButF(block,  NUM, B_RAD_FAC, "Mult:",                      3, 0, 10, 15, &rad->radfac, 0.001, 250.0, 100, 0, "Mulitplies the energy values");
1850         uiDefButF(block,  NUM, B_RAD_FAC, "Gamma:",                     3, 0, 10, 15, &rad->gamma, 0.2, 10.0, 10, 0, "Changes the contrast of the energy values");
1851         uiDefButF(block,  NUMSLI, B_NOP, "Convergence:",                5, 0, 10, 10, &rad->convergence, 0.0, 1.0, 10, 0, "Sets the lower threshold of unshot energy");
1852 }
1853
1854
1855 /* ***************************** WORLD ************************** */
1856
1857 void do_worldbuts(unsigned short event)
1858 {
1859         static short mtexcopied=0;
1860         static MTex mtexcopybuf;
1861         World *wrld;
1862         MTex *mtex;
1863         
1864         switch(event) {
1865         case B_TEXCLEARWORLD:
1866                 wrld= G.buts->lockpoin;
1867                 mtex= wrld->mtex[ wrld->texact ];
1868                 if(mtex) {
1869                         if(mtex->tex) mtex->tex->id.us--;
1870                         MEM_freeN(mtex);
1871                         wrld->mtex[ wrld->texact ]= 0;
1872                         allqueue(REDRAWBUTSSHADING, 0);
1873                         allqueue(REDRAWOOPS, 0);
1874                         BIF_undo_push("Unlink world texture");
1875                         BIF_preview_changed(ID_WO);
1876                 }
1877                 break;
1878         case B_WMTEXCOPY:
1879                 wrld= G.buts->lockpoin;
1880                 if(wrld && wrld->mtex[(int)wrld->texact] ) {
1881                         mtex= wrld->mtex[(int)wrld->texact];
1882                         if(mtex->tex==NULL) {
1883                                 error("No texture available");
1884                         }
1885                         else {
1886                                 memcpy(&mtexcopybuf, wrld->mtex[(int)wrld->texact], sizeof(MTex));
1887                                 mtexcopied= 1;
1888                         }
1889                 }
1890                 break;
1891         case B_WMTEXPASTE:
1892                 wrld= G.buts->lockpoin;
1893                 if(wrld && mtexcopied && mtexcopybuf.tex) {
1894                         if(wrld->mtex[(int)wrld->texact]==NULL ) 
1895                                 wrld->mtex[(int)wrld->texact]= MEM_mallocN(sizeof(MTex), "mtex"); 
1896                         else if(wrld->mtex[(int)wrld->texact]->tex)
1897                                 wrld->mtex[(int)wrld->texact]->tex->id.us--;
1898                         
1899                         memcpy(wrld->mtex[(int)wrld->texact], &mtexcopybuf, sizeof(MTex));
1900                         
1901                         id_us_plus((ID *)mtexcopybuf.tex);
1902                         BIF_undo_push("Paste mapping settings");
1903                         BIF_preview_changed(ID_WO);
1904                         scrarea_queue_winredraw(curarea);
1905                 }
1906                 break;
1907         case B_AO_DISTANCES:
1908                 /* distances option only supports plain */
1909                 wrld= G.buts->lockpoin;
1910                 if(wrld)
1911                         wrld->aocolor= WO_AOPLAIN;
1912                 scrarea_queue_winredraw(curarea);
1913                 break;
1914         }
1915 }
1916
1917 static void world_panel_mapto(World *wrld)
1918 {
1919         uiBlock *block;
1920         MTex *mtex;
1921         
1922         block= uiNewBlock(&curarea->uiblocks, "world_panel_mapto", UI_EMBOSS, UI_HELV, curarea->win);
1923         uiNewPanelTabbed("Texture and Input", "World");
1924         if(uiNewPanel(curarea, block, "Map To", "World", 1280, 0, 318, 204)==0) return;
1925
1926         uiSetButLock(wrld->id.lib!=0, "Can't edit library data");
1927
1928         mtex= wrld->mtex[ wrld->texact ];
1929         if(mtex==NULL) {
1930                 mtex= &emptytex;
1931                 default_mtex(mtex);
1932                 mtex->texco= TEXCO_VIEW;
1933         }
1934
1935         /* TEXTURE OUTPUT */
1936         uiBlockBeginAlign(block);
1937         uiDefButBitS(block, TOG, MTEX_STENCIL, B_WORLDPRV, "Stencil",   10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode");
1938         uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_WORLDPRV, "Neg",              55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect");
1939         uiDefButBitS(block, TOG, MTEX_RGBTOINT, B_WORLDPRV, "No RGB",           85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values");
1940         uiBlockEndAlign(block);
1941
1942         uiBlockBeginAlign(block);
1943         uiDefButF(block, COL, B_WORLDPRV, "",                   10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, "");
1944         uiDefButF(block, NUMSLI, B_WORLDPRV, "R ",                      10,80,135,19, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
1945         uiDefButF(block, NUMSLI, B_WORLDPRV, "G ",                      10,60,135,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
1946         uiDefButF(block, NUMSLI, B_WORLDPRV, "B ",                      10,40,135,19, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
1947         uiBlockEndAlign(block);
1948         uiDefButF(block, NUMSLI, B_WORLDPRV, "DVar ",           10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value for textures to mix with values (not RGB)");
1949         
1950         /* MAP TO */
1951         uiBlockBeginAlign(block);
1952         uiDefButBitS(block, TOG, WOMAP_BLEND, B_WORLDPRV, "Blend",      10,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour progression of the background");
1953         uiDefButBitS(block, TOG, WOMAP_HORIZ, B_WORLDPRV, "Hori",               85,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the horizon");
1954         uiDefButBitS(block, TOG, WOMAP_ZENUP, B_WORLDPRV, "ZenUp",      160,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith above");
1955         uiDefButBitS(block, TOG, WOMAP_ZENDOWN, B_WORLDPRV, "ZenDo",    235,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith below");
1956         uiBlockEndAlign(block);
1957
1958         uiBlockBeginAlign(block);
1959         uiDefButS(block, MENU, B_WORLDPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode");
1960         uiBlockEndAlign(block);
1961
1962         uiBlockBeginAlign(block);
1963         uiDefButF(block, NUMSLI, B_WORLDPRV, "Col  ",           155,100,155,19, &(mtex->colfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects colour values");
1964         uiDefButF(block, NUMSLI, B_WORLDPRV, "Nor  ",           155,80,155,19, &(mtex->norfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects normal values");
1965         uiDefButF(block, NUMSLI, B_WORLDPRV, "Var  ",           155,60,155,19, &(mtex->varfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects other values");
1966         
1967 }
1968
1969 static void world_panel_texture(World *wrld)
1970 {
1971         uiBlock *block;
1972         MTex *mtex;
1973         ID *id;
1974         int a, loos;
1975         char str[64], *strp;
1976         
1977         block= uiNewBlock(&curarea->uiblocks, "world_panel_texture", UI_EMBOSS, UI_HELV, curarea->win);
1978         if(uiNewPanel(curarea, block, "Texture and Input", "World", 960, 0, 318, 204)==0) return;
1979
1980         uiSetButLock(wrld->id.lib!=0, "Can't edit library data");
1981
1982         /* TEX CHANNELS */
1983         uiBlockSetCol(block, TH_BUT_NEUTRAL);
1984         uiBlockBeginAlign(block);
1985         for(a= 0; a<MAX_MTEX; a++) {
1986                 mtex= wrld->mtex[a];
1987                 if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos);
1988                 else strcpy(str, "");
1989                 str[10]= 0;
1990                 uiDefButS(block, ROW, REDRAWBUTSSHADING, str,10, 160-18*a, 80, 20, &(wrld->texact), 3.0, (float)a, 0, 0, "Texture channel");
1991         }
1992         uiBlockEndAlign(block);
1993
1994         mtex= wrld->mtex[ wrld->texact ];
1995         if(mtex==NULL) {
1996                 mtex= &emptytex;
1997                 default_mtex(mtex);
1998                 mtex->texco= TEXCO_VIEW;
1999         }
2000         
2001         /* TEXTUREBLOCK SELECT */
2002         uiBlockSetCol(block, TH_BUT_SETTING2);
2003         id= (ID *)mtex->tex;
2004         IDnames_to_pupstring(&strp, NULL, "ADD NEW %x 32767", &(G.main->tex), id, &(G.buts->texnr));
2005         uiDefButS(block, MENU, B_WTEXBROWSE, strp, 100,140,20,19, &(G.buts->texnr), 0, 0, 0, 0, "Selects an existing texture or creates new");
2006         MEM_freeN(strp);
2007         
2008         if(id) {
2009                 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");
2010                 sprintf(str, "%d", id->us);
2011                 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");
2012                 uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 220,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
2013                 if(id->lib) {
2014                         if(wrld->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB,      219,140,21,19, 0, 0, 0, 0, 0, "");
2015                         else uiDefIconBut(block, BUT, 0, ICON_PARLIB,   219,140,21,19, 0, 0, 0, 0, 0, "");      
2016                 }
2017                 uiBlockSetCol(block, TH_AUTO);
2018                 uiDefBut(block, BUT, B_TEXCLEARWORLD, "Clear", 122, 140, 72, 19, 0, 0, 0, 0, 0, "Erases link to texture");
2019         }
2020         else 
2021                 uiDefButS(block, TOG, B_WTEXBROWSE, "Add New" ,100, 160, 200, 19, &(G.buts->texnr), -1.0, 32767.0, 0, 0, "Adds a new texture datablock");
2022
2023         uiBlockSetCol(block, TH_AUTO);
2024         
2025         /* copy/paste */
2026         uiBlockBeginAlign(block);
2027         uiDefIconBut(block, BUT, B_WMTEXCOPY, ICON_COPYUP,      250,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
2028         uiDefIconBut(block, BUT, B_WMTEXPASTE, ICON_PASTEUP,275,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
2029                 
2030         /* TEXCO */
2031         uiBlockBeginAlign(block);
2032         uiDefButS(block, ROW, B_WORLDPRV, "View",               100,110,100,20, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Uses view vector for the texture coordinates");
2033         uiDefButS(block, ROW, B_WORLDPRV, "Global",     200,110,100,20, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates (interior mist)");
2034         
2035         uiDefButS(block, ROW, B_WORLDPRV, "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");
2036         uiDefButS(block, ROW, B_WORLDPRV, "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");
2037         uiDefButS(block, ROW, B_WORLDPRV, "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");
2038         
2039         uiDefButS(block, ROW, B_WORLDPRV, "Object",     100,70,70,20, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
2040         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_WORLDPRV, "", 170,70,130,20, &(mtex->object), "");
2041
2042         uiBlockBeginAlign(block);
2043         uiDefButF(block, NUM, B_WORLDPRV, "dX",         100,40,100,19, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate");
2044         uiDefButF(block, NUM, B_WORLDPRV, "dY",         100,20,100,19, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate");
2045         uiDefButF(block, NUM, B_WORLDPRV, "dZ",         100, 0,100,19, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Z coordinate");
2046         uiBlockBeginAlign(block);
2047         uiDefButF(block, NUM, B_WORLDPRV, "sizeX",      200,40,100,19, mtex->size, -10.0, 10.0, 10, 0, "Sets scaling for the texture's X size");
2048         uiDefButF(block, NUM, B_WORLDPRV, "sizeY",      200,20,100,19, mtex->size+1, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Y size");
2049         uiDefButF(block, NUM, B_WORLDPRV, "sizeZ",      200, 0,100,19, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size");
2050         
2051 }
2052
2053 static void world_panel_mistaph(World *wrld)
2054 {
2055         uiBlock *block;
2056         
2057         block= uiNewBlock(&curarea->uiblocks, "world_panel_mistaph", UI_EMBOSS, UI_HELV, curarea->win);
2058         if(uiNewPanel(curarea, block, "Mist / Stars / Physics", "World", 640, 0, 318, 204)==0) return;
2059
2060         uiSetButLock(wrld->id.lib!=0, "Can't edit library data");
2061
2062 #if GAMEBLENDER == 1
2063         uiDefButI(block, MENU, 1, 
2064 #ifdef USE_ODE
2065                           "Physics %t|None %x0|Sumo %x2|Ode %x4 |Bullet %x5",
2066 #else
2067                           //"Physics %t|None %x0|Sumo %x2|Bullet %x5", //disable Sumo, until too many people complain ;-)
2068                           "Physics %t|None %x0|Sumo (deprecated) %x2|Bullet %x5",
2069 #endif
2070                           10,180,140,19, &wrld->physicsEngine, 0, 0, 0, 0, 
2071                           "Physics Engine");
2072         
2073         /* Gravitation for the game worlds */
2074         uiDefButF(block, NUMSLI,0, "Grav ", 150,180,150,19,     &(wrld->gravity), 0.0, 25.0, 0, 0,  "Sets the gravitation constant of the game world");
2075 #endif
2076
2077         uiBlockSetCol(block, TH_BUT_SETTING1);
2078         uiDefButBitS(block, TOG, WO_MIST, REDRAWVIEW3D,"Mist",  10,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles mist simulation");
2079         uiBlockSetCol(block, TH_AUTO);
2080
2081         uiBlockBeginAlign(block);
2082         uiDefButS(block, ROW, B_DIFF, "Qua", 10, 90, 40, 19, &wrld->mistype, 1.0, 0.0, 0, 0, "Mist uses quadratic progression");
2083         uiDefButS(block, ROW, B_DIFF, "Lin", 50, 90, 50, 19, &wrld->mistype, 1.0, 1.0, 0, 0, "Mist uses linear progression");
2084         uiDefButS(block, ROW, B_DIFF, "Sqr", 100, 90, 50, 19, &wrld->mistype, 1.0, 2.0, 0, 0, "Mist uses inverse quadratic progression");
2085         uiBlockBeginAlign(block);
2086         uiDefButF(block, NUM,REDRAWVIEW3D, "Sta:",10,70,140,19, &wrld->miststa, 0.0, 1000.0, 10, 0, "Specifies the starting distance of the mist");
2087         uiDefButF(block, NUM,REDRAWVIEW3D, "Di:",10,50,140,19, &wrld->mistdist, 0.0,1000.0, 10, 00, "Specifies the depth of the mist");
2088         uiDefButF(block, NUM,B_DIFF,"Hi:",              10,30,140,19, &wrld->misthi,0.0,100.0, 10, 0, "Specifies the factor for a less dense mist with increasing height");
2089         uiDefButF(block, NUMSLI, B_DIFF, "Misi ",               10,10,140,19,   &(wrld->misi), 0., 1.0, 0, 0, "Sets the mist intensity");
2090         uiBlockEndAlign(block);
2091
2092         uiBlockSetCol(block, TH_BUT_SETTING1);
2093         uiDefButBitS(block, TOG, WO_STARS, REDRAWVIEW3D,        "Stars",160,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles starfield generation");
2094         uiBlockSetCol(block, TH_AUTO);
2095         
2096         uiBlockBeginAlign(block);
2097         uiDefButF(block, NUM,B_DIFF,"StarDist:",        160,70,140,19, &(wrld->stardist), 2.0, 1000.0, 100, 0, "Specifies the average distance between any two stars");
2098         uiDefButF(block, NUM,B_DIFF,"MinDist:",         160,50,140,19, &(wrld->starmindist), 0.0, 1000.0, 100, 0, "Specifies the minimum distance to the camera for stars");
2099         uiDefButF(block, NUMSLI,B_DIFF,"Size:",         160,30,140,19, &(wrld->starsize), 0.0, 10.0, 10, 0, "Specifies the average screen dimension of stars");
2100         uiDefButF(block, NUMSLI,B_DIFF,"Colnoise:",     160,10,140,19, &(wrld->starcolnoise), 0.0, 1.0, 100, 0, "Randomizes starcolour");
2101         uiBlockEndAlign(block);
2102
2103 }
2104
2105 static void world_panel_amb_occ(World *wrld)
2106 {
2107         uiBlock *block;
2108         
2109         block= uiNewBlock(&curarea->uiblocks, "world_panel_amb_oc", UI_EMBOSS, UI_HELV, curarea->win);
2110         uiNewPanelTabbed("Mist / Stars / Physics", "World");
2111         if(uiNewPanel(curarea, block, "Amb Occ", "World", 320, 0, 318, 204)==0) return;
2112
2113         uiBlockSetCol(block, TH_BUT_SETTING1);
2114         uiDefButBitS(block, TOG, WO_AMB_OCC, B_REDR,    "Ambient Occlusion",10,150,300,19, &wrld->mode, 0, 0, 0, 0, "Toggles ambient occlusion (soft shadows)");
2115         uiBlockSetCol(block, TH_AUTO);
2116
2117         if(wrld->mode & WO_AMB_OCC) {
2118
2119                 /* aolight: samples */
2120                 uiBlockBeginAlign(block);
2121                 uiDefButS(block, NUM, B_REDR, "Samples:", 10, 120, 150, 19, &wrld->aosamp, 1.0, 16.0, 100, 0, "Sets the number of samples used for AO  (actual number: squared)");
2122                 /* enable/disable total random sampling */
2123                 uiDefButBitS(block, TOG, WO_AORNDSMP, 0, "Random Sampling", 160, 120, 150, 19, &wrld->aomode, 0, 0, 0, 0, "When enabled, total random sampling will be used for an even noisier effect");
2124                 uiBlockEndAlign(block);
2125
2126                 uiDefButF(block, NUM, B_REDR, "Dist:", 10, 95, 150, 19, &wrld->aodist, 0.001, 5000.0, 100, 0, "Sets length of AO rays, defines how far away other faces give occlusion effect");
2127
2128                 uiBlockBeginAlign(block);
2129                 uiDefButBitS(block, TOG, WO_AODIST, B_AO_DISTANCES, "Use Distances", 10, 70, 150, 19, &wrld->aomode, 0, 0, 0, 0, "When enabled, distances to objects will be used to attenuate shadows. Only for Plain AO.");
2130                 /* distance attenuation factor */
2131                 if (wrld->aomode & WO_AODIST)
2132                         uiDefButF(block, NUM, B_REDR, "DistF:", 160, 70, 150, 19, &wrld->aodistfac, 0.00001, 10.0, 100, 0, "Distance factor, the higher, the 'shorter' the shadows");
2133
2134                 /* result mix modes */
2135                 uiBlockBeginAlign(block);
2136                 uiDefButS(block, ROW, B_REDR, "Add", 10, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOADD, 0, 0, "adds light/shadows");
2137                 uiDefButS(block, ROW, B_REDR, "Sub", 110, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOSUB, 0, 0, "subtracts light/shadows (needs at least one normal light to make anything visible)");
2138                 uiDefButS(block, ROW, B_REDR, "Both", 210, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOADDSUB, 0, 0, "both lightens & darkens");
2139
2140                 /* color treatment */
2141                 uiBlockBeginAlign(block);
2142                 uiDefButS(block, ROW, B_REDR, "Plain", 10, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOPLAIN, 0, 0, "Plain diffuse energy (white)");
2143                 uiDefButS(block, ROW, B_REDR, "Sky Color", 110, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOSKYCOL, 0, 0, "Use horizon and zenith color for diffuse energy");
2144                 uiDefButS(block, ROW, B_REDR, "Sky Texture", 210, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOSKYTEX, 0, 0, "Does full Sky texture render for diffuse energy");
2145                 
2146                 uiBlockBeginAlign(block);
2147                 uiDefButF(block, NUMSLI, B_REDR, "Energy:", 10, 0, 150, 19, &wrld->aoenergy, 0.01, 3.0, 100, 0, "Sets global energy scale for AO");
2148                 uiDefButF(block, NUMSLI, B_REDR, "Bias:", 160, 0, 150, 19, &wrld->aobias, 0.0, 0.5, 10, 0, "Sets bias to prevent smoothed faces to show banding (in radians)");
2149         }
2150
2151 }
2152
2153 static void world_panel_world(World *wrld)
2154 {
2155         uiBlock *block;
2156         
2157         block= uiNewBlock(&curarea->uiblocks, "world_panel_world", UI_EMBOSS, UI_HELV, curarea->win);
2158         if(uiNewPanel(curarea, block, "World", "World", 320, 0, 318, 204)==0) return;
2159
2160         uiBlockSetCol(block, TH_BUT_SETTING2);
2161         std_libbuttons(block, 10, 180, 0, NULL, B_WORLDBROWSE, ID_WO, 0, (ID *)wrld, (ID *)G.scene, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0, B_KEEPDATA);
2162
2163         if(wrld==NULL) return;
2164         
2165         uiSetButLock(wrld->id.lib!=0, "Can't edit library data");
2166         uiBlockSetCol(block, TH_AUTO);
2167
2168         uiDefButF(block, COL, B_WORLDPRV, "",                   10,150,145,19, &wrld->horr, 0, 0, 0, B_COLHOR, "");
2169         uiDefButF(block, COL, B_WORLDPRV, "",                   160,150,145,19, &wrld->zenr, 0, 0, 0, B_COLZEN, "");
2170
2171         uiBlockBeginAlign(block);
2172         uiDefButF(block, NUMSLI,B_WORLDPRV,"HoR ",      10,130,145,19,  &(wrld->horr), 0.0, 1.0, B_COLHOR,0, "Sets the amount of red colour at the horizon");
2173         uiDefButF(block, NUMSLI,B_WORLDPRV,"HoG ",      10,110,145,19,  &(wrld->horg), 0.0, 1.0, B_COLHOR,0, "Sets the amount of green colour at the horizon");
2174         uiDefButF(block, NUMSLI,B_WORLDPRV,"HoB ",      10,90,145,19,   &(wrld->horb), 0.0, 1.0, B_COLHOR,0, "Sets the amount of blue colour at the horizon");
2175         
2176         uiBlockBeginAlign(block);
2177         uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeR ",      160,130,145,19, &(wrld->zenr), 0.0, 1.0, B_COLZEN,0, "Sets the amount of red colour at the zenith");
2178         uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeG ",      160,110,145,19, &(wrld->zeng), 0.0, 1.0, B_COLZEN,0, "Sets the amount of green colour at the zenith");
2179         uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeB ",      160,90,145,19,  &(wrld->zenb), 0.0, 1.0, B_COLZEN,0, "Sets the amount of blue colour at the zenith");
2180
2181         uiBlockBeginAlign(block);
2182         uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbR ",     10,50,145,19,   &(wrld->ambr), 0.0, 1.0 ,0,0, "Sets the amount of red ambient colour");
2183         uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbG ",     10,30,145,19,   &(wrld->ambg), 0.0, 1.0 ,0,0, "Sets the amount of green ambient colour");
2184         uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbB ",     10,10,145,19,   &(wrld->ambb), 0.0, 1.0 ,0,0, "Sets the amount of blue ambient colour");
2185
2186         uiBlockBeginAlign(block);
2187         uiBlockSetCol(block, TH_BUT_SETTING1);
2188         uiDefButF(block, NUMSLI,B_WORLDPRV, "Exp ",                     160,30,145,19,  &(wrld->exp), 0.0, 1.0, 0, 2, "Sets amount of exponential color correction for light");
2189         uiDefButF(block, NUMSLI,B_WORLDPRV, "Range ",           160,10,145,19,  &(wrld->range), 0.2, 5.0, 0, 2, "Sets the color amount that will be mapped on color 1.0");
2190
2191
2192 }
2193
2194 static void world_panel_preview(World *wrld)
2195 {
2196         uiBlock *block;
2197         
2198         /* name "Preview" is abused to detect previewrender offset panel */
2199         block= uiNewBlock(&curarea->uiblocks, "world_panel_preview", UI_EMBOSS, UI_HELV, curarea->win);
2200         if(uiNewPanel(curarea, block, "Preview", "World", 0, 0, 318, 204)==0) return;
2201         
2202         if(wrld==NULL) return;
2203
2204         uiSetButLock(wrld->id.lib!=0, "Can't edit library data");
2205
2206         uiBlockSetDrawExtraFunc(block, BIF_previewdraw);
2207
2208         // label to force a boundbox for buttons not to be centered
2209         uiDefBut(block, LABEL, 0, " ",  20,20,10,10, 0, 0, 0, 0, 0, "");
2210
2211         uiBlockBeginAlign(block);
2212         uiDefButBitS(block, TOG, WO_SKYREAL, B_WORLDPRV,"Real", 200,175,80,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with a real horizon");
2213         uiDefButBitS(block, TOG, WO_SKYBLEND, B_WORLDPRV,"Blend",200,150,80,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with natural progression from horizon to zenith");
2214         uiDefButBitS(block, TOG,WO_SKYPAPER, B_WORLDPRV,"Paper",200,125,80,25, &wrld->skytype, 0, 0, 0, 0, "Flattens blend or texture coordinates");
2215         uiBlockEndAlign(block);
2216
2217 }
2218
2219 /* ************************ LAMP *************************** */
2220
2221 void do_lampbuts(unsigned short event)
2222 {
2223         static short mtexcopied=0;
2224         static MTex mtexcopybuf;
2225         Lamp *la;
2226         MTex *mtex;
2227
2228         switch(event) {
2229         case B_LAMPREDRAW:
2230                 BIF_preview_changed(ID_LA);
2231                 allqueue(REDRAWVIEW3D, 0);
2232                 allqueue(REDRAWBUTSSHADING, 0);
2233                 break;
2234         case B_TEXCLEARLAMP:
2235                 la= G.buts->lockpoin;
2236                 mtex= la->mtex[ la->texact ];
2237                 if(mtex) {
2238                         if(mtex->tex) mtex->tex->id.us--;
2239                         MEM_freeN(mtex);
2240                         la->mtex[ la->texact ]= 0;
2241                         BIF_undo_push("Unlink world texture");
2242                         allqueue(REDRAWBUTSSHADING, 0);
2243                         allqueue(REDRAWOOPS, 0);
2244                         BIF_preview_changed(ID_LA);
2245                 }
2246                 break;
2247         case B_SBUFF:
2248                 la= G.buts->lockpoin;
2249                 la->bufsize = la->bufsize&=(~15); 
2250                 allqueue(REDRAWBUTSSHADING, 0); 
2251                 allqueue(REDRAWOOPS, 0); 
2252                 break; 
2253         case B_SHADBUF:
2254                 la= G.buts->lockpoin; 
2255                 la->mode &= ~LA_SHAD_RAY;
2256                 allqueue(REDRAWBUTSSHADING, 0); 
2257                 allqueue(REDRAWVIEW3D, 0);              
2258                 break;
2259         case B_SHADRAY:
2260                 la= G.buts->lockpoin; 
2261                 la->mode &= ~LA_SHAD_BUF;
2262                 /* yafray: 'softlight' uses it's own shadbuf. flag.
2263                    Must be cleared here too when switching from ray shadow */
2264                 la->mode &= ~LA_YF_SOFT;
2265                 allqueue(REDRAWBUTSSHADING, 0);
2266                 allqueue(REDRAWVIEW3D, 0);      
2267                 break;
2268         case B_LMTEXCOPY:
2269                 la= G.buts->lockpoin;
2270                 if(la && la->mtex[(int)la->texact] ) {
2271                         mtex= la->mtex[(int)la->texact];
2272                         if(mtex->tex==NULL) {
2273                                 error("No texture available");
2274                         }
2275                         else {
2276                                 memcpy(&mtexcopybuf, la->mtex[(int)la->texact], sizeof(MTex));
2277                                 mtexcopied= 1;
2278                         }
2279                 }
2280                 break;
2281         case B_LMTEXPASTE:
2282                 la= G.buts->lockpoin;
2283                 if(la && mtexcopied && mtexcopybuf.tex) {
2284                         if(la->mtex[(int)la->texact]==NULL ) 
2285                                 la->mtex[(int)la->texact]= MEM_mallocN(sizeof(MTex), "mtex"); 
2286                         else if(la->mtex[(int)la->texact]->tex)
2287                                 la->mtex[(int)la->texact]->tex->id.us--;
2288
2289                         memcpy(la->mtex[(int)la->texact], &mtexcopybuf, sizeof(MTex));
2290                         
2291                         id_us_plus((ID *)mtexcopybuf.tex);
2292                         BIF_undo_push("Paste mapping settings");
2293                         BIF_preview_changed(ID_LA);
2294                         scrarea_queue_winredraw(curarea);
2295                 }
2296                 break;
2297                 
2298         }
2299 }
2300
2301
2302 static void lamp_panel_mapto(Object *ob, Lamp *la)
2303 {
2304         uiBlock *block;
2305         MTex *mtex;
2306         
2307         block= uiNewBlock(&curarea->uiblocks, "lamp_panel_mapto", UI_EMBOSS, UI_HELV, curarea->win);
2308         uiNewPanelTabbed("Texture and Input", "Lamp");
2309         if(uiNewPanel(curarea, block, "Map To", "Lamp", 1280, 0, 318, 204)==0) return;
2310
2311         uiSetButLock(la->id.lib!=0, "Can't edit library data");
2312
2313         mtex= la->mtex[ la->texact ];
2314         if(mtex==NULL) {
2315                 mtex= &emptytex;
2316                 default_mtex(mtex);
2317                 mtex->texco= TEXCO_VIEW;
2318         }
2319
2320         /* TEXTURE OUTPUT */
2321         uiBlockBeginAlign(block);
2322         uiDefButBitS(block, TOG, MTEX_STENCIL, B_LAMPPRV, "Stencil",    10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode");
2323         uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_LAMPPRV, "Neg",               55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect");
2324         uiDefButBitS(block, TOG, MTEX_RGBTOINT, B_LAMPPRV, "No RGB",            85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values");
2325         uiBlockEndAlign(block);
2326         
2327         uiBlockBeginAlign(block);
2328         uiDefButF(block, COL, B_LAMPPRV, "",                    10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, "");
2329         uiDefButF(block, NUMSLI, B_LAMPPRV, "R ",                       10,80,135,19, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
2330         uiDefButF(block, NUMSLI, B_LAMPPRV, "G ",                       10,60,135,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
2331         uiDefButF(block, NUMSLI, B_LAMPPRV, "B ",                       10,40,135,19, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
2332         uiBlockEndAlign(block);
2333         uiDefButF(block, NUMSLI, B_LAMPPRV, "DVar ",                    10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value the textures uses to mix with");
2334         
2335         /* MAP TO */
2336         uiDefButBitS(block, TOG, MAP_COL, B_LAMPPRV, "Col",             10,180,135,19, &(mtex->mapto), 0, 0, 0, 0, "Lets the texture affect the basic colour of the lamp");
2337         
2338         uiBlockBeginAlign(block);
2339         uiDefButS(block, MENU, B_LAMPPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode");
2340         uiBlockEndAlign(block);
2341
2342         uiDefButF(block, NUMSLI, B_LAMPPRV, "Col  ",                    155,100,155,19, &(mtex->colfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects colour values");
2343
2344 }
2345
2346
2347 static void lamp_panel_texture(Object *ob, Lamp *la)
2348 {
2349         uiBlock *block;
2350         MTex *mtex;
2351         ID *id;
2352         int a, loos;
2353         char *strp, str[64];
2354         
2355         block= uiNewBlock(&curarea->uiblocks, "lamp_panel_texture", UI_EMBOSS, UI_HELV, curarea->win);
2356         if(uiNewPanel(curarea, block, "Texture and Input", "Lamp", 960, 0, 318, 204)==0) return;
2357
2358         uiSetButLock(la->id.lib!=0, "Can't edit library data");
2359
2360         /* TEX CHANNELS */
2361         uiBlockSetCol(block, TH_BUT_NEUTRAL);
2362         uiBlockBeginAlign(block);
2363         for(a= 0; a<MAX_MTEX; a++) {
2364                 mtex= la->mtex[a];
2365                 if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos);
2366                 else strcpy(str, "");
2367                 str[10]= 0;
2368                 uiDefButS(block, ROW, B_REDR, str,      10, 160-18*a, 80, 20, &(la->texact), 3.0, (float)a, 0, 0, "");
2369         }
2370         uiBlockEndAlign(block);
2371         
2372         mtex= la->mtex[ la->texact ];
2373         if(mtex==NULL) {
2374                 mtex= &emptytex;
2375                 default_mtex(mtex);
2376                 mtex->texco= TEXCO_VIEW;
2377         }
2378
2379         /* TEXTUREBLOK SELECT */
2380         uiBlockSetCol(block, TH_BUT_SETTING2);
2381         id= (ID *)mtex->tex;
2382         IDnames_to_pupstring(&strp, NULL, "ADD NEW %x 32767", &(G.main->tex), id, &(G.buts->texnr));
2383         
2384         /* doesnt work, because lockpoin points to lamp, not to texture */
2385         uiDefButS(block, MENU, B_LTEXBROWSE, strp, 100,140,20,19, &(G.buts->texnr), 0, 0, 0, 0, "Selects an existing texture or creates new");  
2386         MEM_freeN(strp);
2387         
2388         if(id) {
2389                 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");
2390                 sprintf(str, "%d", id->us);
2391                 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");
2392                 uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 221,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
2393                 if(id->lib) {
2394                         if(la->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB,        219,140,21,19, 0, 0, 0, 0, 0, "");
2395                         else uiDefIconBut(block, BUT, 0, ICON_PARLIB,   219,140,21,19, 0, 0, 0, 0, 0, "");      
2396                 }
2397                 uiBlockSetCol(block, TH_AUTO);
2398                 uiDefBut(block, BUT, B_TEXCLEARLAMP, "Clear", 122, 140, 72, 19, 0, 0, 0, 0, 0, "Erases link to texture");
2399         }
2400         else 
2401                 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");
2402
2403         /* copy/paste */
2404         uiBlockBeginAlign(block);
2405         uiDefIconBut(block, BUT, B_LMTEXCOPY, ICON_COPYUP,      250,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
2406         uiDefIconBut(block, BUT, B_LMTEXPASTE, ICON_PASTEUP,    275,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
2407         
2408         /* TEXCO */
2409         uiBlockSetCol(block, TH_AUTO);
2410         uiBlockBeginAlign(block);
2411         uiDefButS(block, ROW, B_LAMPPRV, "Glob",                        100,110,60,20, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates");
2412         uiDefButS(block, ROW, B_LAMPPRV, "View",                        160,110,70,20, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Uses view coordinates for the texture coordinates");
2413         uiDefButS(block, ROW, B_LAMPPRV, "Object",              230,110,70,20, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
2414         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_LAMPPRV, "", 100,90,200,20, &(mtex->object), "");
2415         
2416         uiBlockBeginAlign(block);
2417         uiDefButF(block, NUM, B_LAMPPRV, "dX",          100,50,100,18, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate");
2418         uiDefButF(block, NUM, B_LAMPPRV, "dY",          100,30,100,18, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate");
2419         uiDefButF(block, NUM, B_LAMPPRV, "dZ",          100,10,100,18, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Z coordinate");
2420         uiBlockBeginAlign(block);
2421         uiDefButF(block, NUM, B_LAMPPRV, "sizeX",       200,50,100,18, mtex->size, -10.0, 10.0, 10, 0, "Sets scaling for the texture's X size");
2422         uiDefButF(block, NUM, B_LAMPPRV, "sizeY",       200,30,100,18, mtex->size+1, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Y size");
2423         uiDefButF(block, NUM, B_LAMPPRV, "sizeZ",       200,10,100,18, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size");
2424         uiBlockEndAlign(block);
2425 }
2426
2427 static void lamp_panel_spot(Object *ob, Lamp *la)
2428 {
2429         uiBlock *block;
2430         float grid=0.0;
2431         
2432         block= uiNewBlock(&curarea->uiblocks, "lamp_panel_spot", UI_EMBOSS, UI_HELV, curarea->win);
2433         if(uiNewPanel(curarea, block, "Shadow and Spot", "Lamp", 640, 0, 318, 204)==0) return;
2434
2435         /* hemis and ray shadow dont work at all... */
2436         /* yafray: ignore photonlight as well */
2437         if ((la->type==LA_HEMI) || (la->type==LA_YF_PHOTON)) return;
2438
2439         if(G.vd) grid= G.vd->grid; 
2440         if(grid<1.0) grid= 1.0;
2441
2442         uiSetButLock(la->id.lib!=0, "Can't edit library data");
2443
2444         uiBlockSetCol(block, TH_BUT_SETTING1);
2445         uiBlockBeginAlign(block);
2446         uiDefButBitS(block, TOG, LA_SHAD_RAY, B_SHADRAY,"Ray Shadow",10,180,80,19,&la->mode, 0, 0, 0, 0, "Use ray tracing for shadow");
2447         if(la->type==LA_SPOT) {
2448                 uiDefButBitS(block, TOG, LA_SHAD_BUF, B_SHADBUF, "Buf.Shadow",10,160,80,19,&la->mode, 0, 0, 0, 0, "Lets spotlight produce shadows using shadow buffer");
2449                 if(la->mode & LA_SHAD_BUF) {
2450                         char *tip= "Regular buffer type";
2451                         if(la->buftype==LA_SHADBUF_IRREGULAR)
2452                                 tip= "Irregular buffer produces sharp shadow always, but it doesn't show up for raytracing";
2453                         else if(la->buftype==LA_SHADBUF_HALFWAY)
2454                                 tip= "Regular buffer, averaging the closest and 2nd closest Z value for reducing biasing";
2455                         
2456                         uiDefButC(block, MENU, B_REDR, "Classical %x0|Classic-Halfway %x2|Irregular %x1", 10,140,80,19,&la->buftype, 0, 0, 0, 0, tip);
2457                 }
2458         }
2459         uiBlockEndAlign(block);
2460         
2461         uiDefButBitS(block, TOG, LA_ONLYSHADOW, B_NOP,"OnlyShadow",             10,110,80,19,&la->mode, 0, 0, 0, 0, "Causes light to cast shadows only without illuminating objects");
2462
2463         if(la->type==LA_SPOT) {
2464                 uiBlockBeginAlign(block);
2465                 uiDefButBitS(block, TOG, LA_SQUARE, B_LAMPREDRAW,"Square",      10,60,80,19,&la->mode, 0, 0, 0, 0, "Sets square spotbundles");
2466                 uiDefButBitS(block, TOG, LA_HALO, B_LAMPREDRAW,"Halo",          10,40,80,19,&la->mode, 0, 0, 0, 0, "Renders spotlight with a volumetric halo"); 
2467
2468                 uiBlockSetCol(block, TH_AUTO);
2469                 uiBlockBeginAlign(block);
2470                 uiDefButF(block, NUMSLI,B_LAMPREDRAW,"SpotSi ", 100,180,200,19,&la->spotsize, 1.0, 180.0, 0, 0, "Sets the angle of the spotlight beam in degrees");
2471                 uiDefButF(block, NUMSLI,B_LAMPREDRAW,"SpotBl ",         100,160,200,19,&la->spotblend, 0.0, 1.0, 0, 0, "Sets the softness of the spotlight edge");
2472                 uiBlockEndAlign(block);
2473         
2474                 uiDefButF(block, NUMSLI,B_LAMPREDRAW,"HaloInt ",                        100,135,200,19,&la->haint, 0.0, 5.0, 0, 0, "Sets the intensity of the spotlight halo");
2475                 
2476                 if(la->mode & LA_SHAD_BUF) {
2477                         if(ELEM(la->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY)) {
2478                                 uiBlockBeginAlign(block);
2479                                 uiDefButS(block, NUM,B_SBUFF,"ShadowBufferSize:", 100,110,200,19,       &la->bufsize,512,10240, 0, 0, "Sets the size of the shadow buffer to nearest multiple of 16");
2480                                 uiDefButS(block, ROW,B_NOP,     "Box",                          100,90,65,19, &la->filtertype, 0.0, LA_SHADBUF_BOX, 0, 0, "Apply Box filter for shadowbuffer samples");
2481                                 uiDefButS(block, ROW,B_NOP,     "Tent",                         165,90,65,19, &la->filtertype, 0.0, LA_SHADBUF_TENT, 0, 0, "Apply Tent filter for shadowbuffer samples");
2482                                 uiDefButS(block, ROW,B_NOP,     "Gauss",                        230,90,70,19, &la->filtertype, 0.0, LA_SHADBUF_GAUSS, 0, 0, "Apply Gauss filter for shadowbuffer samples");
2483                                 
2484         //                      uiDefButS(block, ROW,B_NOP,"SubSamples: 1",             100,90,140,19, &la->buffers, 1.0, 1.0, 0, 0, "Amount of lampbuffer subsamples, a value of larger than 1 halves the shadowbuffer size");
2485         //                      uiDefButS(block, ROW,B_NOP,"4",                                 240,90,30,19, &la->buffers, 1.0, 4.0, 0, 0, "Amount of lampbuffer subsamples, this halves the actual shadowbuffer size");
2486         //                      uiDefButS(block, ROW,B_NOP,"9",                                 270,90,30,19, &la->buffers, 1.0, 9.0, 0, 0, "Amount of lampbuffer subsamples, this halves the shadowbuffer size");
2487                         
2488                                 uiBlockBeginAlign(block);
2489                                 uiDefButS(block, NUM,B_LAMPREDRAW,"Samples:",   100,60,100,19,  &la->samp,1.0,16.0, 0, 0, "Sets the number of shadow map samples");
2490                                 uiDefButS(block, NUM,B_NOP,"Halo step:",                200,60,100,19,  &la->shadhalostep, 0.0, 12.0, 0, 0, "Sets the volumetric halo sampling frequency");
2491                                 uiDefButF(block, NUM,B_LAMPREDRAW,"Bias:",              100,40,100,19,  &la->bias, 0.001, 5.0, 1, 0, "Sets the shadow map sampling bias");
2492                                 uiDefButF(block, NUM,B_LAMPREDRAW,"Soft:",              200,40,100,19,  &la->soft,1.0,100.0, 100, 0, "Sets the size of the shadow sample area");
2493                         }
2494                         else {  /* LA_SHADBUF_IRREGULAR */
2495                                 uiDefButF(block, NUM,B_LAMPREDRAW,"Bias:",              100,40,100,19,  &la->bias, 0.01, 5.0, 1, 0, "Sets the shadow map sampling bias");
2496                         }
2497                         
2498                         uiBlockBeginAlign(block);
2499                         uiDefIconButBitC(block, TOG, LA_SHADBUF_AUTO_START, B_REDR, ICON_AUTO,  10, 10, 25, 19, &la->bufflag, 0.0, 0.0, 0, 0, "Automatic calculation of clipping-start, based on visible vertices");
2500                         if(la->bufflag & LA_SHADBUF_AUTO_START)
2501                                 uiDefBut(block, LABEL, B_NOP, "ClipSta: Auto",  35,10,115,19,   NULL, 0, 0, 0, 0, "");
2502                         else
2503                                 uiDefButF(block, NUM,REDRAWVIEW3D,"ClipSta:",   35,10,115,19,   &la->clipsta, 0.1*grid,1000.0*grid, 10, 0, "Sets the shadow map clip start: objects closer will not generate shadows");
2504                         uiDefIconButBitC(block, TOG, LA_SHADBUF_AUTO_END, B_REDR, ICON_AUTO,    160, 10, 25, 19, &la->bufflag, 0.0, 0.0, 0, 0, "Automatic calculation of clipping-end, based on visible vertices");
2505                         if(la->bufflag & LA_SHADBUF_AUTO_END)
2506                                 uiDefBut(block, LABEL,B_NOP, "ClipEnd: Auto",   185,10,115,19,  NULL, 0, 0, 0, 0, "");
2507                         else
2508                                 uiDefButF(block, NUM,REDRAWVIEW3D,"ClipEnd:",   185,10,115,19,&la->clipend, 1.0, 5000.0*grid, 100, 0, "Sets the shadow map clip end beyond which objects will not generate shadows");
2509                         uiBlockEndAlign(block);
2510                         
2511                 }
2512         }
2513         else if(la->type==LA_AREA && (la->mode & LA_SHAD_RAY)) {
2514                 uiBlockBeginAlign(block);
2515                 uiBlockSetCol(block, TH_AUTO);
2516                 if(la->area_shape==LA_AREA_SQUARE) 
2517                         uiDefButS(block, NUM,0,"Samples:",      100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
2518                 if(la->area_shape==LA_AREA_CUBE) 
2519                         uiDefButS(block, NUM,0,"Samples:",      100,160,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp x samp)");
2520
2521                 if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)) {
2522                         uiDefButS(block, NUM,0,"SamplesX:",     100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of X samples taken extra");
2523                         uiDefButS(block, NUM,0,"SamplesY:",     100,160,200,19, &la->ray_sampy, 1.0, 16.0, 100, 0, "Sets the amount of Y samples taken extra");
2524                         if(la->area_shape==LA_AREA_BOX)
2525                                 uiDefButS(block, NUM,0,"SamplesZ:",     100,140,200,19, &la->ray_sampz, 1.0, 8.0, 100, 0, "Sets the amount of Z samples taken extra");
2526                 }
2527                 
2528                 uiBlockBeginAlign(block);
2529                 uiDefButBitS(block, TOG, LA_SAMP_UMBRA, 0,"Umbra",                      100,110,200,19,&la->ray_samp_type, 0, 0, 0, 0, "Emphasis parts that are fully shadowed");
2530                 uiDefButBitS(block, TOG, LA_SAMP_DITHER, 0,"Dither",                    100,90,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use 2x2 dithering for sampling");
2531                 uiDefButBitS(block, TOG, LA_SAMP_JITTER, 0,"Noise",                     200,90,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use noise for sampling");
2532         }
2533         else uiDefBut(block, LABEL,0," ",       100,180,200,19,NULL, 0, 0, 0, 0, "");
2534
2535 }
2536
2537 /* yafray: adaptation of lamp_panel_spot above with yafray specific parameters */
2538 static void lamp_panel_yafray(Object *ob, Lamp *la)
2539 {
2540         uiBlock *block;
2541         
2542         block= uiNewBlock(&curarea->uiblocks, "lamp_panel_yafray", UI_EMBOSS, UI_HELV, curarea->win);
2543         if(uiNewPanel(curarea, block, "Yafray: Shadow and Photons", "Lamp", 640, 0, 318, 204)==0) return;
2544
2545         /* hemis not used in yafray */
2546         if(la->type==LA_HEMI) return;
2547         
2548         uiSetButLock(la->id.lib!=0, "Can't edit library data");
2549         
2550                 /* photonlight params */
2551         if (la->type==LA_YF_PHOTON) {
2552                 uiBlockSetCol(block, TH_BUT_SETTING1);
2553                 uiDefButBitS(block, TOG, 1, B_DIFF,"Use QMC",10,180,80,19,&la->YF_useqmc, 0, 0, 0, 0, "Use QMC sampling (sometimes visible patterns)");
2554                 uiBlockSetCol(block, TH_AUTO);
2555                 uiDefButF(block, NUMSLI,B_LAMPREDRAW,"Angle ",  100,180,200,19,&la->spotsize, 1.0, 180.0, 0, 0, "Sets the angle of the photonlight beam in degrees");
2556                 uiDefButI(block, NUM,B_DIFF,"photons:", 10,150,290,19,  &la->YF_numphotons, 10000, 100000000, 0, 0, "Maximum number of photons to shoot");
2557                 uiDefButI(block, NUM,B_DIFF,"search:", 10,130,290,19,   &la->YF_numsearch, 100, 1000, 0, 0, "Number of photons to mix (blur)");
2558                 uiDefButS(block, NUM,B_DIFF,"depth:", 10,100,290,19,    &la->YF_phdepth, 1, 100, 0, 0, "Maximum caustic bounce depth");
2559                 uiDefButF(block, NUM,B_DIFF,"Blur:", 10,70,290,19,      &la->YF_causticblur, 0.01, 1.0, 1, 0, "Amount of caustics blurring (also depends on search)");
2560                 return;
2561         }
2562
2563         uiBlockSetCol(block, TH_BUT_SETTING1);
2564         
2565         /* in yafray arealights always cast shadows, so ray shadow flag not needed */
2566         /* ray shadow also not used when halo for spot enabled */
2567         if ((la->type!=LA_AREA) && (!((la->type==LA_SPOT) && (la->mode & LA_HALO))))
2568                 uiDefButBitS(block, TOG, LA_SHAD_RAY, B_SHADRAY,"Ray Shadow",10,180,80,19,&la->mode, 0, 0, 0, 0, "Use ray tracing for shadow");
2569         
2570         /* in yafray the regular lamp can use shadowbuffers (softlight), used by spot with halo as well */
2571         /* to prevent clash with blender shadowbuf flag, a special flag is used for yafray */
2572         if (la->type==LA_LOCAL) {
2573                 uiDefButBitS(block, TOG, LA_YF_SOFT, B_SHADBUF, "Buf.Shadow",10,160,80,19,&la->mode, 0, 0, 0, 0, "Lets light produce shadows using shadow buffer");
2574                 uiDefButF(block, NUM, B_DIFF, "GloInt:", 100,155,200,19, &la->YF_glowint, 0.0, 1.0, 1, 0, "Sets light glow intensity, 0 is off");
2575                 uiDefButF(block, NUM, B_DIFF, "GloOfs:", 100,135,100,19, &la->YF_glowofs, 0.0, 2.0, 1, 0, "Sets light glow offset, the higher, the less 'peaked' the glow");
2576                 uiDefButS(block, NUM, B_DIFF, "GlowType:", 200,135,100,19, &la->YF_glowtype, 0, 1, 1, 0, "Sets light glow type");
2577         }
2578         
2579         /* shadowbuffers used only for 'softlight' & spotlight with halo */
2580         if (((la->type==LA_LOCAL) && (la->mode & LA_YF_SOFT)) || ((la->type==LA_SPOT) && (la->mode & LA_HALO))) {
2581                 /* Shadow buffer size can be anything in yafray, but reasonable minimum is 128 */
2582                 /* Maximum is 1024, since zbuf in yafray is float, no multiple of 16 restriction */
2583                 uiDefButS(block, NUM,B_DIFF,"ShadowBufferSize:", 100,110,200,19,        &la->YF_bufsize, 128, 1024, 0, 0, "Sets the size of the shadow buffer");
2584
2585                 /* samples & halostep params only used for spotlight with halo */
2586                 if ((la->type==LA_SPOT) && (la->mode & LA_HALO)) {
2587                         uiDefButS(block, NUM,B_DIFF,"Samples:",         100,30,100,19,  &la->samp,1.0,16.0, 0, 0, "Sets the number of shadow map samples");
2588                         uiDefButS(block, NUM,B_DIFF,"Halo step:",       200,30,100,19,  &la->shadhalostep, 0.0, 12.0, 0, 0, "Sets the volumetric halo sampling frequency");
2589                 }
2590                 uiDefButF(block, NUM,B_DIFF,"Bias:",                    100,10,100,19,  &la->bias, 0.01, 5.0, 1, 0, "Sets the shadow map sampling bias");
2591                 /* here can use the Blender soft param, since for yafray it has the same function as in Blender */
2592                 uiDefButF(block, NUM,B_DIFF,"Soft:",                    200,10,100,19,  &la->soft,1.0,100.0, 100, 0, "Sets the size of the shadow sample area");
2593         }
2594         else if ((la->type==LA_LOCAL) && (la->mode & LA_SHAD_RAY)) {
2595                 /* for spherelight, light radius */
2596                 uiDefButF(block, NUM,B_DIFF,"Radius:",                  200,10,100,19,  &la->YF_ltradius, 0.0,100.0, 100, 0, "Sets the radius of the lightsource, 0 is same as pointlight");
2597         }
2598         
2599         if (la->type==LA_SPOT) {
2600
2601                 uiDefButBitS(block, TOG, LA_HALO, B_LAMPREDRAW,"Halo",                          10,50,80,19,&la->mode, 0, 0, 0, 0, "Renders spotlight with a volumetric halo"); 
2602
2603                 uiBlockSetCol(block, TH_AUTO);
2604                 uiBlockBeginAlign(block);
2605                 uiDefButF(block, NUMSLI,B_LAMPREDRAW,"SpotSi ", 100,180,200,19,&la->spotsize, 1.0, 180.0, 0, 0, "Sets the angle of the spotlight beam in degrees");
2606                 uiDefButF(block, NUMSLI,B_LAMPREDRAW,"SpotBl ",         100,160,200,19,&la->spotblend, 0.0, 1.0, 0, 0, "Sets the softness of the spotlight edge");
2607                 uiBlockEndAlign(block);
2608         
2609                 if (la->mode & LA_HALO) uiDefButF(block, NUMSLI,0,"HaloInt ",                   100,135,200,19,&la->haint, 0.0, 5.0, 0, 0, "Sets the intensity of the spotlight halo");
2610         }
2611         else if ((la->type==LA_AREA) || ((la->type==LA_LOCAL) && (la->mode & LA_SHAD_RAY))) {
2612                 /* area samples param also used for 'spherelight' */
2613                 uiBlockBeginAlign(block);
2614                 uiBlockSetCol(block, TH_AUTO);
2615                 
2616                 uiDefButS(block, NUM,B_DIFF,"Samples:", 100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
2617
2618                 /* shadow sampling types not used in yafray, removed */
2619         }
2620         else uiDefBut(block, LABEL,0," ",       100,180,200,19,NULL, 0, 0, 0, 0, "");   
2621
2622 }
2623
2624 static void lamp_panel_lamp(Object *ob, Lamp *la)
2625 {
2626         uiBlock *block;
2627         float grid= 0.0;
2628         short xco;
2629         
2630         block= uiNewBlock(&curarea->uiblocks, "lamp_panel_lamp", UI_EMBOSS, UI_HELV, curarea->win);
2631         if(uiNewPanel(curarea, block, "Lamp", "Lamp", 320, 0, 318, 204)==0) return;
2632
2633         if(G.vd) grid= G.vd->grid; 
2634         if(grid<1.0) grid= 1.0;
2635
2636         uiSetButLock(la->id.lib!=0, "Can't edit library data");
2637
2638         uiBlockSetCol(block, TH_BUT_SETTING2);
2639         xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, ID_LA, 0, (ID *)la, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0, 0);  
2640
2641         uiBlockSetCol(block, TH_AUTO);
2642         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");
2643
2644         uiBlockBeginAlign(block);
2645         if(la->type==LA_AREA) {
2646                 //uiDefButS(block, MENU, B_LAMPREDRAW, "Shape %t|Square %x0|Rect %x1|Cube %x2|Box %x3",
2647                 uiDefButS(block, MENU, B_LAMPREDRAW, "Shape %t|Square %x0|Rect %x1",
2648                                 10, 150, 100, 19, &la->area_shape, 0,0,0,0, "Sets area light shape");   
2649                 if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)){
2650                         uiDefButF(block, NUM,B_LAMPREDRAW,"SizeX ",     10,130,100,19, &la->area_size, 0.01, 100.0, 10, 0, "Area light size X, doesn't affect energy amount");
2651                         uiDefButF(block, NUM,B_LAMPREDRAW,"SizeY ",     10,110,100,19, &la->area_sizey, 0.01, 100.0, 10, 0, "Area light size Y, doesn't affect energy amount");
2652                 }
2653                 if(la->area_shape==LA_AREA_BOX)
2654                         uiDefButF(block, NUM,B_LAMPREDRAW,"SizeZ ",     10,90,100,19, &la->area_sizez, 0.01, 100.0, 10, 0, "Area light size Z, doesn't affect energy amount");
2655                 if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_CUBE))
2656                         uiDefButF(block, NUM,B_LAMPREDRAW,"Size ",      10,130,100,19, &la->area_size, 0.01, 100.0, 10, 0, "Area light size, doesn't affect energy amount");
2657         }
2658         else if( ELEM(la->type, LA_LOCAL, LA_SPOT)) {
2659                 uiBlockSetCol(block, TH_BUT_SETTING1);
2660                 uiDefButBitS(block, TOG, LA_QUAD, B_LAMPPRV,"Quad",             10,150,100,19,&la->mode, 0, 0, 0, 0, "Uses inverse quadratic proportion for light attenuation");
2661                 uiDefButBitS(block, TOG, LA_SPHERE, REDRAWVIEW3D,"Sphere",      10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value");
2662         }
2663
2664         uiBlockBeginAlign(block);
2665         uiBlockSetCol(block, TH_BUT_SETTING1);
2666         uiDefButBitS(block, TOG, LA_LAYER, 0,"Layer",                           10,70,100,19,&la->mode, 0, 0, 0, 0, "Illuminates objects in the same layer as the lamp only");
2667         uiDefButBitS(block, TOG, LA_NEG, B_LAMPPRV,"Negative",  10,50,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light");
2668         uiDefButBitS(block, TOG, LA_NO_DIFF, 0,"No Diffuse",            10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp");
2669         uiDefButBitS(block, TOG, LA_NO_SPEC, 0,"No Specular",           10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp");
2670         uiBlockEndAlign(block);
2671
2672         uiBlockSetCol(block, TH_AUTO);
2673         uiDefButF(block, NUMSLI,B_LAMPPRV,"Energy ",    120,150,180,20, &(la->energy), 0.0, 10.0, 0, 0, "Sets the intensity of the light");
2674
2675         uiBlockBeginAlign(block);
2676         uiDefButF(block, NUMSLI,B_LAMPPRV,"R ",         120,120,180,20,&la->r, 0.0, 1.0, B_COLLAMP, 0, "Sets the red component of the light");
2677         uiDefButF(block, NUMSLI,B_LAMPPRV,"G ",         120,100,180,20,&la->g, 0.0, 1.0, B_COLLAMP, 0, "Sets the green component of the light");
2678         uiDefButF(block, NUMSLI,B_LAMPPRV,"B ",         120,80,180,20,&la->b, 0.0, 1.0, B_COLLAMP, 0, "Sets the blue component of the light");
2679         uiBlockEndAlign(block);
2680         
2681         uiDefButF(block, COL, B_LAMPPRV, "",            120,52,180,24, &la->r, 0, 0, 0, B_COLLAMP, "");
2682         
2683         uiBlockBeginAlign(block);
2684         if (ELEM(la->type, LA_LOCAL, LA_SPOT)) {
2685                 uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad1 ",     120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuatation for a quad lamp");
2686                 uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad2 ",  120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the quadratic distance attenuatation for a quad lamp");
2687         }
2688         else if(la->type==LA_AREA) {
2689                 if(la->k==0.0) la->k= 1.0;
2690                 uiDefButF(block, NUMSLI,0,"Gamma ",     120,10,180,19,&la->k, 0.001, 2.0, 100, 0, "Set the light gamma correction value");
2691         }
2692 }
2693
2694
2695 static void lamp_panel_preview(Object *ob, Lamp *la)
2696 {
2697         uiBlock *block;
2698         
2699         /* name "Preview" is abused to detect previewrender offset panel */
2700         block= uiNewBlock(&curarea->uiblocks, "lamp_panel_preview", UI_EMBOSS, UI_HELV, curarea->win);
2701         if(uiNewPanel(curarea, block, "Preview", "Lamp", 0, 0, 318, 204)==0) return;
2702         
2703         uiSetButLock(la->id.lib!=0, "Can't edit library data");
2704
2705         uiBlockSetDrawExtraFunc(block, BIF_previewdraw);
2706
2707         // label to force a boundbox for buttons not to be centered
2708         uiDefBut(block, LABEL, 0, " ",  20,20,10,10, 0, 0, 0, 0, 0, "");
2709         uiBlockBeginAlign(block);
2710         uiDefButS(block, ROW,B_LAMPREDRAW,"Lamp",       200,175,80,25,&la->type,1.0,(float)LA_LOCAL, 0, 0, "Creates an omnidirectional point light source");
2711         uiDefButS(block, ROW,B_LAMPREDRAW,"Area",       200,150,80,25,&la->type,1.0,(float)LA_AREA, 0, 0, "Creates a directional area light source");
2712         uiDefButS(block, ROW,B_LAMPREDRAW,"Spot",       200,125,80,25,&la->type,1.0,(float)LA_SPOT, 0, 0, "Creates a directional cone light source");
2713         uiDefButS(block, ROW,B_LAMPREDRAW,"Sun",        200,100,80,25,&la->type,1.0,(float)LA_SUN, 0, 0, "Creates a constant direction parallel ray light source");
2714         uiDefButS(block, ROW,B_LAMPREDRAW,"Hemi",       200,75,80,25,&la->type,1.0,(float)LA_HEMI, 0, 0, "Creates a 180 degree constant light source");
2715         /* yafray: extra type, photonlight */
2716         if (G.scene->r.renderer==R_YAFRAY)
2717                 uiDefButS(block, ROW,B_LAMPREDRAW,"Photon",     200,50,80,25,&la->type,1.0,(float)LA_YF_PHOTON, 0, 0, "Creates a special caustics photon 'light', not a real lightsource, use with other lights");
2718 }
2719
2720
2721 /* ****************** MATERIAL ***************** */
2722
2723
2724 void do_matbuts(unsigned short event)
2725 {
2726         static short mtexcopied=0;
2727         static MTex mtexcopybuf;
2728         Material *ma;
2729         MTex *mtex;
2730
2731         /* all operations default on active material layer here */
2732         /* but this also gets called for lamp and world... */
2733         ma= G.buts->lockpoin;
2734         if(ma && GS(ma->id.name)==ID_MA)
2735                 ma = editnode_get_active_material(ma);
2736         else
2737                 ma= NULL;
2738         
2739         switch(event) {
2740         case B_MAT_YF_PRESET: {
2741                 switch (ma->YF_preset) {
2742                         case 0:
2743                                 /* normal mode, no reflection/refraction */
2744                                 ma->alpha = 1;
2745                                 ma->mode &= ~(MA_RAYMIRROR+MA_RAYTRANSP+MA_ZTRA);
2746                                 break;
2747                         case 1: {
2748                                 /* clear glass */
2749                                 ma->alpha = 0.001;
2750                                 ma->ray_mirror = 1;
2751                                 ma->fresnel_mir_i = 5;
2752                                 ma->mode |= (MA_RAYMIRROR+MA_RAYTRANSP);
2753                                 ma->mode &= ~MA_ZTRA;
2754                                 ma->filter = 0;
2755                                 ma->ang = 1.5;
2756                                 break;
2757                         }
2758                         case 2: {
2759                                 /* color glass */
2760                                 ma->alpha = 0.001;
2761                                 ma->ray_mirror = 1;
2762                                 ma->fresnel_mir_i = 5;
2763                                 ma->mode |= (MA_RAYMIRROR+MA_RAYTRANSP);
2764                                 ma->mode &= ~MA_ZTRA;
2765                                 ma->filter = 1;
2766                                 ma->ang = 1.5;
2767                                 break;
2768                         }
2769                         case 3: {
2770                                 /* uniform reflect */
2771                                 ma->alpha = 1;
2772                                 ma->ray_mirror = 1;
2773                                 ma->fresnel_mir_i = 1;
2774                                 ma->mode |= MA_RAYMIRROR;
2775                                 ma->mode &= ~(MA_RAYTRANSP+MA_ZTRA);
2776                                 break;
2777                         }
2778                         case 4: {
2779                                 /* fresnel reflect */
2780                                 ma->alpha = 1;
2781                                 ma->ray_mirror = 1;
2782                                 ma->fresnel_mir_i = 5;
2783                                 ma->mode |= MA_RAYMIRROR;
2784                                 ma->mode &= ~(MA_RAYTRANSP+MA_ZTRA);
2785                                 ma->ang = 3;
2786                                 break;
2787                         }
2788                 }
2789                 BIF_preview_changed(ID_MA);
2790                 allqueue(REDRAWBUTSSHADING, 0);
2791                 shade_buttons_change_3d();
2792                 break;
2793         }
2794         case B_ACTCOL:
2795                 scrarea_queue_headredraw(curarea);
2796                 allqueue(REDRAWBUTSSHADING, 0);
2797                 allqueue(REDRAWIPO, 0);
2798                 allqueue(REDRAWOOPS, 0);
2799                 BIF_preview_changed(ID_MA);
2800                 break;
2801         case B_MATFROM:
2802                 scrarea_queue_headredraw(curarea);
2803                 allqueue(REDRAWBUTSSHADING, 0);
2804                 allqueue(REDRAWOOPS, 0);
2805                 // BIF_previewdraw();  push/pop!
2806                 break;
2807         case B_MATPRV:
2808                 if(ma) end_render_material(ma); /// temporal... 3d preview
2809                 BIF_preview_changed(ID_MA);
2810                 allqueue(REDRAWBUTSSHADING, 0);
2811                 shade_buttons_change_3d();
2812                 break;
2813         case B_LAMPPRV:
2814                 BIF_preview_changed(ID_LA);
2815                 allqueue(REDRAWBUTSSHADING, 0);
2816                 break;
2817         case B_WORLDPRV:
2818                 BIF_preview_changed(ID_WO);
2819                 allqueue(REDRAWBUTSSHADING, 0);
2820                 break;
2821         case B_MATHALO:
2822                 /* when halo is disabled, clear star flag, this is the same as MA_FACETEXTURE <blush> */
2823                 /* same for 'xtreme alpha' which is 'only shadow' */
2824                 if(ma) {
2825                         if((ma->mode & MA_HALO)==0) {
2826                                 ma->mode &= ~(MA_STAR|MA_HALO_XALPHA|MA_ZINV|MA_ENV);
2827                         }
2828                         BIF_preview_changed(ID_MA);
2829                         allqueue(REDRAWBUTSSHADING, 0);
2830                         shade_buttons_change_3d();
2831                 }
2832                 break;
2833         case B_TEXCLEAR:
2834                 mtex= ma->mtex[(int) ma->texact ];
2835                 if(mtex) {
2836                         if(mtex->tex) mtex->tex->id.us--;
2837                         MEM_freeN(mtex);
2838                         ma->mtex[ (int) ma->texact ]= 0;
2839                         BIF_undo_push("Unlink material texture");
2840                         if(ma) end_render_material(ma); /// temporal... 3d preview
2841                         allqueue(REDRAWBUTSSHADING, 0);
2842                         allqueue(REDRAWOOPS, 0);
2843                         BIF_preview_changed(ID_MA);
2844                 }
2845                 break;
2846         case B_MTEXCOPY:
2847                 if(ma && ma->mtex[(int)ma->texact] ) {
2848                         mtex= ma->mtex[(int)ma->texact];
2849                         if(mtex->tex==NULL) {
2850                                 error("No texture available");
2851                         }
2852                         else {
2853                                 memcpy(&mtexcopybuf, ma->mtex[(int)ma->texact], sizeof(MTex));
2854                                 mtexcopied= 1;
2855                         }
2856                 }
2857                 break;
2858         case B_MTEXPASTE:
2859                 if(ma && mtexcopied && mtexcopybuf.tex) {
2860                         if(ma->mtex[(int)ma->texact]==NULL ) 
2861                                 ma->mtex[(int)ma->texact]= MEM_mallocN(sizeof(MTex), "mtex"); 
2862                         else if(ma->mtex[(int)ma->texact]->tex)
2863                                 ma->mtex[(int)ma->texact]->tex->id.us--;
2864
2865                         memcpy(ma->mtex[(int)ma->texact], &mtexcopybuf, sizeof(MTex));
2866                         
2867                         id_us_plus((ID *)mtexcopybuf.tex);
2868                         BIF_undo_push("Paste mapping settings");
2869                         BIF_preview_changed(ID_MA);
2870                         scrarea_queue_winredraw(curarea);
2871                 }
2872                 break;
2873         case B_MATZTRANSP:
2874                 if(ma) {
2875                         ma->mode &= ~MA_RAYTRANSP;
2876                         //BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);       /// temporal... 3d preview
2877                         allqueue(REDRAWBUTSSHADING, 0);
2878                         BIF_preview_changed(ID_MA);
2879                 }
2880                 break;
2881         case B_MATRAYTRANSP:
2882                 if(ma) {
2883                         ma->mode &= ~MA_ZTRA;
2884                         if(ma) end_render_material(ma); /// temporal... 3d preview
2885                         allqueue(REDRAWBUTSSHADING, 0);
2886                         BIF_preview_changed(ID_MA);
2887                 }
2888                 break;
2889         case B_MATCOLORBAND:
2890                 if(ma) {
2891                         if(ma->mode & MA_RAMP_COL)
2892                                 if(ma->ramp_col==NULL) ma->ramp_col= add_colorband(0);
2893                         if(ma->mode & MA_RAMP_SPEC)
2894                                 if(ma->ramp_spec==NULL) ma->ramp_spec= add_colorband(0);
2895
2896                         if(ma) end_render_material(ma); /// temporal... 3d preview
2897                         allqueue(REDRAWBUTSSHADING, 0);
2898                         BIF_preview_changed(ID_MA);
2899                         shade_buttons_change_3d();
2900                 }
2901                 break;
2902         case B_MAT_USENODES:
2903                 ma= G.buts->lockpoin;   /* use base material instead */
2904                 if(ma) {
2905                         if(ma->use_nodes && ma->nodetree==NULL) {
2906                                 node_shader_default(ma);
2907                         }
2908                         if(ma) end_render_material(ma); /// temporal... 3d preview
2909                         BIF_preview_changed(ID_MA);
2910                         allqueue(REDRAWNODE, 0);
2911                         allqueue(REDRAWBUTSSHADING, 0);
2912                         allqueue(REDRAWIPO, 0);
2913                 }               
2914                 break;
2915         case B_MAT_VCOL_PAINT:
2916                 if(ma) {
2917                         ma->mode &= ~MA_VERTEXCOL;
2918                         BIF_preview_changed(ID_MA);
2919                         allqueue(REDRAWBUTSSHADING, 0);
2920                 }
2921                 break;
2922         case B_MAT_VCOL_LIGHT:
2923                 if(ma) {
2924                         ma->mode &= ~MA_VERTEXCOLP;
2925                         BIF_preview_changed(ID_MA);
2926                         allqueue(REDRAWBUTSSHADING, 0);
2927                 }
2928                 break;
2929                 
2930         }
2931 }
2932