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