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