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