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