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