4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: not all of this file anymore. :)
27 * ***** END GPL LICENSE BLOCK *****
39 #include "IMB_imbuf_types.h"
40 #include "IMB_imbuf.h"
42 #include "MEM_guardedalloc.h"
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"
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"
73 #include "BKE_material.h"
74 #include "BKE_particle.h"
75 #include "BKE_utildefines.h"
76 #include "BKE_texture.h"
78 #include "BKE_packedFile.h"
79 #include "BKE_plugin_types.h"
80 #include "BKE_image.h"
82 #include "BLI_blenlib.h"
85 #include "BSE_filesel.h"
86 #include "BSE_headerbuttons.h"
89 #include "BDR_drawmesh.h"
91 #include "BIF_drawimage.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"
110 #include "mydevice.h"
114 #include "RE_pipeline.h"
116 #include "GPU_material.h"
118 /* -----includes for this file specific----- */
120 #include "butspace.h" // own module
123 static MTex emptytex;
124 static int packdummy = 0;
126 static char *mapto_blendtype_pup(void)
128 static char formatstr[] = "|%s %%x%d";
129 static char string[1024];
132 str += sprintf(str, formatstr, "Mix", MTEX_BLEND);
134 str += sprintf(str, formatstr, "Add", MTEX_ADD);
135 str += sprintf(str, formatstr, "Subtract", MTEX_SUB);
137 str += sprintf(str, formatstr, "Multiply", MTEX_MUL);
138 str += sprintf(str, formatstr, "Screen", MTEX_SCREEN);
139 str += sprintf(str, formatstr, "Overlay", MTEX_OVERLAY);
141 str += sprintf(str, formatstr, "Difference", MTEX_DIFF);
142 str += sprintf(str, formatstr, "Divide", MTEX_DIV);
144 str += sprintf(str, formatstr, "Darken", MTEX_DARK);
145 str += sprintf(str, formatstr, "Lighten", MTEX_LIGHT);
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);
155 void shade_buttons_change_3d(void)
162 for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
163 if(sa->spacetype==SPACE_VIEW3D) {
164 View3D *v3d= sa->spacedata.first;
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();
170 /* all objects using material */
171 Base *base= FIRSTBASE;
172 Material *ma= give_current_material(ob, ob->actcol);
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));
192 /* *************************** TEXTURE ******************************** */
194 static void load_image_cb(char *str, void *ima_pp_v, void *iuser_v) /* called from fileselect or button */
196 Image **ima_pp= (Image **)ima_pp_v;
199 ima= BKE_add_image_file(str);
206 BKE_image_signal(ima, iuser_v, IMA_SIGNAL_RELOAD);
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);
220 BIF_undo_push("Load image");
223 static void load_plugin_tex(char *str, void *tex_v, void *unused) /* called from fileselect */
227 if(tex->type!=TEX_PLUGIN) return;
229 if(tex->plugin) free_plugin_tex(tex->plugin);
232 tex->plugin= add_plugin_tex(str);
234 allqueue(REDRAWBUTSSHADING, 0);
235 BIF_preview_changed(ID_TE);
238 static void save_env(char *name)
244 BLI_convertstringcode(str, G.sce);
245 tex= G.buts->lockpoin;
247 if(tex && GS(tex->id.name)==ID_TE) {
248 if(tex->env && tex->env->ok && saveover(str)) {
250 BIF_save_envmap(tex->env, str);
258 static int vergcband(const void *a1, const void *a2)
260 const CBData *x1=a1, *x2=a2;
262 if( x1->pos > x2->pos ) return 1;
263 else if( x1->pos < x2->pos) return -1;
267 void do_texbuts(unsigned short event)
273 tex= G.buts->lockpoin;
277 BIF_preview_changed(ID_TE);
278 allqueue(REDRAWBUTSSHADING, 0);
280 if(tex && G.scene->nodetree) {
281 NodeTagIDChanged(G.scene->nodetree, &tex->id);
282 allqueue(RECALC_COMPOSITE, 0);
286 scrarea_queue_headredraw(curarea);
287 BIF_preview_changed(ID_TE);
288 allqueue(REDRAWBUTSSHADING, 0);
289 if(G.buts->texfrom == 3) /* brush texture */
290 allqueue(REDRAWIMAGE, 0);
293 if(tex==NULL) return;
295 allqueue(REDRAWBUTSSHADING, 0);
296 BIF_preview_changed(ID_TE);
298 if(tex && G.scene->nodetree) {
299 NodeTagIDChanged(G.scene->nodetree, &tex->id);
300 allqueue(RECALC_COMPOSITE, 0);
304 if(tex==NULL) return;
306 BIF_undo_push("Default texture vars");
307 allqueue(REDRAWBUTSSHADING, 0);
308 BIF_preview_changed(ID_TE);
312 BIF_preview_changed(ID_TE);
313 allqueue(REDRAWBUTSSHADING, 0);
316 if(G.scene->nodetree) {
317 NodeTagIDChanged(G.scene->nodetree, &tex->id);
318 allqueue(RECALC_COMPOSITE, 0);
320 if(tex->ima && (tex->imaflag & TEX_MIPMAP) && (tex->ima->flag & IMA_FIELDS)) {
321 error("Cannot combine fields and mipmap");
322 tex->imaflag -= TEX_MIPMAP;
325 BKE_free_envmapdata(tex->env);
331 allqueue(REDRAWBUTSSHADING, 0);
332 BIF_preview_changed(ID_TE);
333 shade_buttons_change_3d();
338 if(tex==NULL) return;
340 sa= closest_bigger_area();
342 if(tex->plugin) strcpy(str, tex->plugin->name);
344 strcpy(str, U.plugtexdir);
346 activate_fileselect_args(FILE_SPECIAL, "SELECT PLUGIN", str, load_plugin_tex, tex, NULL);
351 if(tex==NULL || tex->plugin==NULL) return;
352 strcpy(str, tex->plugin->name);
353 free_plugin_tex(tex->plugin);
355 tex->plugin= add_plugin_tex(str);
356 allqueue(REDRAWBUTSSHADING, 0);
357 BIF_preview_changed(ID_TE);
361 if(tex==NULL) return;
362 if(tex->coba==NULL) tex->coba= add_colorband(0);
363 allqueue(REDRAWBUTSSHADING, 0);
364 BIF_preview_changed(ID_TE); // also ramps, so we do this
369 BKE_free_envmap(tex->env);
371 allqueue(REDRAWBUTSSHADING, 0);
372 BIF_preview_changed(ID_TE);
377 BKE_free_envmapdata(tex->env);
378 allqueue(REDRAWBUTSSHADING, 0);
379 BIF_preview_changed(ID_TE);
383 tex= G.main->tex.first;
385 if(tex->id.us && tex->type==TEX_ENVMAP) {
387 if(tex->env->stype!=ENV_LOAD) BKE_free_envmapdata(tex->env);
392 allqueue(REDRAWBUTSSHADING, 0);
393 BIF_preview_changed(ID_TE);
396 if(tex->env && tex->env->ok) {
397 if(tex->env->type==ENV_PLANE) {
398 notice("Sorry, not implemented yet");
401 sa= closest_bigger_area();
403 save_image_filesel_str(str);
404 activate_fileselect(FILE_SPECIAL, str, G.ima, save_env);
409 if(tex->env && tex->env->object) {
410 BIF_preview_changed(ID_TE);
411 if ELEM(tex->env->object->type, OB_CAMERA, OB_LAMP) {
412 error("Camera or Lamp not allowed");
413 tex->env->object= NULL;
419 if(event>=B_PLUGBUT && event<=B_PLUGBUT+23) {
420 PluginTex *pit= tex->plugin;
421 if(pit && pit->callback) {
422 pit->callback(event - B_PLUGBUT);
423 BIF_preview_changed(ID_TE);
424 allqueue(REDRAWBUTSSHADING, 0);
430 static void texture_panel_plugin(Tex *tex)
437 block= uiNewBlock(&curarea->uiblocks, "texture_panel_plugin", UI_EMBOSS, UI_HELV, curarea->win);
438 if(uiNewPanel(curarea, block, "Plugin", "Texture", 640, 0, 318, 204)==0) return;
439 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
441 if(tex->plugin && tex->plugin->doit) {
445 for(a=0; a<pit->stypes; a++) {
446 uiDefButS(block, ROW, B_TEXREDR_PRV, pit->stnames+16*a, (76*a), 152, 75, 20, &tex->stype, 2.0, (float)a, 0, 0, "");
451 for(a=0; a<pit->vars; a++, varstr++) {
453 yco= 125 - 20*(a % 6)+1;
454 uiDefBut(block, varstr->type, B_PLUGBUT+a, varstr->name, xco,yco,137,19, &(pit->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip);
457 uiDefBut(block, TEX, B_NAMEPLUGIN, "", 0,180,318,24, pit->name, 0.0, 159.0, 0, 0, "");
460 uiDefBut(block, BUT, B_LOADPLUGIN, "Load Plugin", 0,204,137,24, 0, 0, 0, 0, 0, "");
465 static void texture_panel_magic(Tex *tex)
469 block= uiNewBlock(&curarea->uiblocks, "texture_panel_magic", UI_EMBOSS, UI_HELV, curarea->win);
470 if(uiNewPanel(curarea, block, "Magic", "Texture", 640, 0, 318, 204)==0) return;
471 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
473 uiBlockBeginAlign(block);
474 uiDefButS(block, NUM, B_TEXPRV, "Depth:", 10, 90, 150, 19, &tex->noisedepth, 0.0, 10.0, 0, 0, "Sets the depth of the pattern");
475 uiDefButF(block, NUM, B_TEXPRV, "Turbulence:", 10, 70, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Sets the strength of the pattern");
478 static void texture_panel_blend(Tex *tex)
482 block= uiNewBlock(&curarea->uiblocks, "texture_panel_blend", UI_EMBOSS, UI_HELV, curarea->win);
483 if(uiNewPanel(curarea, block, "Blend", "Texture", 640, 0, 318, 204)==0) return;
484 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
486 uiBlockBeginAlign(block);
487 uiDefButS(block, ROW, B_TEXPRV, "Lin", 10, 180, 75, 19, &tex->stype, 2.0, (float)TEX_LIN, 0, 0, "Creates a linear progresion");
488 uiDefButS(block, ROW, B_TEXPRV, "Quad", 85, 180, 75, 19, &tex->stype, 2.0, (float)TEX_QUAD, 0, 0, "Creates a quadratic progression");
489 uiDefButS(block, ROW, B_TEXPRV, "Ease", 160, 180, 75, 19, &tex->stype, 2.0, (float)TEX_EASE, 0, 0, "Creates a progression easing from one step to the next");
490 uiDefButBitS(block, TOG, TEX_FLIPBLEND, B_TEXPRV, "Flip XY", 235, 180, 75, 19, &tex->flag, 0, 0, 0, 0, "Flips the direction of the progression 90 degrees");
492 uiDefButS(block, ROW, B_TEXPRV, "Diag", 10, 160, 75, 19, &tex->stype, 2.0, (float)TEX_DIAG, 0, 0, "Use a diagonal progression");
493 uiDefButS(block, ROW, B_TEXPRV, "Sphere", 85, 160, 75, 19, &tex->stype, 2.0, (float)TEX_SPHERE, 0, 0, "Use progression with the shape of a sphere");
494 uiDefButS(block, ROW, B_TEXPRV, "Halo", 160, 160, 75, 19, &tex->stype, 2.0, (float)TEX_HALO, 0, 0, "Use a quadratic progression with the shape of a sphere");
495 uiDefButS(block, ROW, B_TEXPRV, "Radial", 235, 160, 75, 19, &tex->stype, 2.0, (float)TEX_RAD, 0, 0, "Use a polar progression");
499 /* newnoise: noisebasis menu string */
500 static char* noisebasis_menu()
502 static char nbmenu[256];
503 sprintf(nbmenu, "Noise Basis %%t|Blender Original %%x%d|Original Perlin %%x%d|Improved Perlin %%x%d|Voronoi F1 %%x%d|Voronoi F2 %%x%d|Voronoi F3 %%x%d|Voronoi F4 %%x%d|Voronoi F2-F1 %%x%d|Voronoi Crackle %%x%d|CellNoise %%x%d", TEX_BLENDER, TEX_STDPERLIN, TEX_NEWPERLIN, TEX_VORONOI_F1, TEX_VORONOI_F2, TEX_VORONOI_F3, TEX_VORONOI_F4, TEX_VORONOI_F2F1, TEX_VORONOI_CRACKLE, TEX_CELLNOISE);
507 static void texture_panel_wood(Tex *tex)
511 block= uiNewBlock(&curarea->uiblocks, "texture_panel_wood", UI_EMBOSS, UI_HELV, curarea->win);
512 if(uiNewPanel(curarea, block, "Wood", "Texture", 640, 0, 318, 204)==0) return;
513 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
515 uiBlockBeginAlign(block);
516 uiDefButS(block, ROW, B_TEXPRV, "Bands", 10, 180, 75, 18, &tex->stype, 2.0, (float)TEX_BAND, 0, 0, "Uses standard wood texture in bands");
517 uiDefButS(block, ROW, B_TEXPRV, "Rings", 85, 180, 75, 18, &tex->stype, 2.0, (float)TEX_RING, 0, 0, "Uses wood texture in rings");
518 uiDefButS(block, ROW, B_TEXPRV, "BandNoise", 160, 180, 75, 18, &tex->stype, 2.0, (float)TEX_BANDNOISE, 0, 0, "Adds noise to standard wood");
519 uiDefButS(block, ROW, B_TEXPRV, "RingNoise", 235, 180, 75, 18, &tex->stype, 2.0, (float)TEX_RINGNOISE, 0, 0, "Adds noise to rings");
521 uiDefButS(block, ROW, B_TEXPRV, "Sin", 10, 160, 50, 19, &tex->noisebasis2, 8.0, (float)TEX_SIN, 0, 0, "Uses a sine wave to produce bands");
522 uiDefButS(block, ROW, B_TEXPRV, "Saw", 60, 160, 50, 19, &tex->noisebasis2, 8.0, (float)TEX_SAW, 0, 0, "Uses a saw wave to produce bands");
523 uiDefButS(block, ROW, B_TEXPRV, "Tri", 110, 160, 50, 19, &tex->noisebasis2, 8.0, (float)TEX_TRI, 0, 0, "Uses a triangle wave to produce bands");
524 uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 160, 160, 75, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
525 uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 235, 160, 75, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
527 uiBlockBeginAlign(block);
528 uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :", 10, 130, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
529 uiDefButF(block, NUM, B_TEXPRV, "Turbulence:", 160, 130, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Sets the turbulence of the bandnoise and ringnoise types");
530 uiBlockEndAlign(block);
532 /* newnoise: noisebasis menu */
533 uiDefBut(block, LABEL, 0, "Noise Basis", 10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
534 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
535 uiDefButF(block, NUM, B_NOP, "Nabla: ", 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");
539 static void texture_panel_stucci(Tex *tex)
543 block= uiNewBlock(&curarea->uiblocks, "texture_panel_stucci", UI_EMBOSS, UI_HELV, curarea->win);
544 if(uiNewPanel(curarea, block, "Stucci", "Texture", 640, 0, 318, 204)==0) return;
545 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
547 uiBlockBeginAlign(block);
548 uiDefButS(block, ROW, B_TEXPRV, "Plastic", 10, 180, 100, 19, &tex->stype, 2.0, (float)TEX_PLASTIC, 0, 0, "Uses standard stucci");
549 uiDefButS(block, ROW, B_TEXPRV, "Wall In", 110, 180, 100, 19, &tex->stype, 2.0, (float)TEX_WALLIN, 0, 0, "Creates Dimples");
550 uiDefButS(block, ROW, B_TEXPRV, "Wall Out", 210, 180, 100, 19, &tex->stype, 2.0, (float)TEX_WALLOUT, 0, 0, "Creates Ridges");
552 uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 10, 160, 150, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
553 uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 160, 160, 150, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
555 uiBlockBeginAlign(block);
556 uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :", 10, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
557 uiDefButF(block, NUM, B_TEXPRV, "Turbulence:", 10, 90, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Sets the depth of the stucci");
558 uiBlockEndAlign(block);
560 /* newnoise: noisebasis menu */
561 uiDefBut(block, LABEL, 0, "Noise Basis", 10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
562 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
563 // note, nabla not supported here!
564 // uiDefButF(block, NUM, B_NOP, "Nabla: ", 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");
568 static void texture_panel_marble(Tex *tex)
572 block= uiNewBlock(&curarea->uiblocks, "texture_panel_marble", UI_EMBOSS, UI_HELV, curarea->win);
573 if(uiNewPanel(curarea, block, "Marble", "Texture", 640, 0, 318, 204)==0) return;
574 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
576 uiBlockBeginAlign(block);
577 uiDefButS(block, ROW, B_TEXPRV, "Soft", 10, 180, 100, 18, &tex->stype, 2.0, (float)TEX_SOFT, 0, 0, "Uses soft marble");
578 uiDefButS(block, ROW, B_TEXPRV, "Sharp", 110, 180, 100, 18, &tex->stype, 2.0, (float)TEX_SHARP, 0, 0, "Uses more clearly defined marble");
579 uiDefButS(block, ROW, B_TEXPRV, "Sharper", 210, 180, 100, 18, &tex->stype, 2.0, (float)TEX_SHARPER, 0, 0, "Uses very clearly defined marble");
581 uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 10, 160, 150, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
582 uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 160, 160, 150, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
584 uiDefButS(block, ROW, B_TEXPRV, "Sin", 10, 140, 100, 18, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands.");
585 uiDefButS(block, ROW, B_TEXPRV, "Saw", 110, 140, 100, 18, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands");
586 uiDefButS(block, ROW, B_TEXPRV, "Tri", 210, 140, 100, 18, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands");
588 uiBlockBeginAlign(block);
589 uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :", 10, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
590 uiDefButS(block, NUM, B_TEXPRV, "NoiseDepth:", 10, 90, 150, 19, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the marble calculation");
591 uiDefButF(block, NUM, B_TEXPRV, "Turbulence:", 10, 70, 150, 19, &tex->turbul, 0.0, 200.0, 10, 0, "Sets the turbulence of the sine bands");
592 uiBlockEndAlign(block);
594 /* newnoise: noisebasis menu */
595 uiDefBut(block, LABEL, 0, "Noise Basis", 10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
596 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
597 uiDefButF(block, NUM, B_NOP, "Nabla: ", 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");
601 static void texture_panel_clouds(Tex *tex)
605 block= uiNewBlock(&curarea->uiblocks, "texture_panel_clouds", UI_EMBOSS, UI_HELV, curarea->win);
606 if(uiNewPanel(curarea, block, "Clouds", "Texture", 640, 0, 318, 204)==0) return;
607 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
609 uiBlockBeginAlign(block);
610 uiDefButS(block, ROW, B_TEXPRV, "Default", 10, 180, 70, 18, &tex->stype, 2.0, (float)TEX_DEFAULT, 0, 0, "Uses standard noise");
611 uiDefButS(block, ROW, B_TEXPRV, "Color", 80, 180, 70, 18, &tex->stype, 2.0, (float)TEX_COLOR, 0, 0, "Lets Noise return RGB value");
612 uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 155, 180, 75, 18, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
613 uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 230, 180, 80, 18, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
614 uiBlockBeginAlign(block);
615 uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :", 10, 130, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
616 uiDefButS(block, NUM, B_TEXPRV, "NoiseDepth:", 160, 130, 150, 19, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the cloud calculation");
617 uiBlockEndAlign(block);
619 /* newnoise: noisebasis menu */
620 uiDefBut(block, LABEL, 0, "Noise Basis", 10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
621 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
622 uiDefButF(block, NUM, B_NOP, "Nabla: ", 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");
626 /*****************************************/
627 /* newnoise: panel(s) for musgrave types */
628 /*****************************************/
630 static void texture_panel_musgrave(Tex *tex)
635 block= uiNewBlock(&curarea->uiblocks, "texture_panel_musgrave", UI_EMBOSS, UI_HELV, curarea->win);
636 if(uiNewPanel(curarea, block, "Musgrave", "Texture", 640, 0, 318, 204)==0) return;
637 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
639 /* TEX_MFRACTAL, TEX_RIDGEDMF, TEX_HYBRIDMF, TEX_FBM, TEX_HTERRAIN */
640 str= "Multifractal %x0|Ridged Multifractal %x1|Hybrid Multifractal %x2|Hetero Terrain %x4|fBm %x3";
641 uiDefButS(block, MENU, B_TEXREDR_PRV, str, 10, 160, 150, 19, &tex->stype, 0.0, 0.0, 0, 0, "Sets Musgrave type");
643 uiBlockBeginAlign(block);
644 uiDefButF(block, NUMSLI, B_TEXPRV, "H: ", 10, 130, 150, 19, &tex->mg_H, 0.0001, 2.0, 10, 0, "Sets the highest fractal dimension");
645 uiDefButF(block, NUMSLI, B_TEXPRV, "Lacu: ", 160, 130, 150, 19, &tex->mg_lacunarity, 0.0, 6.0, 10, 0, "Sets the gap between succesive frequencies");
646 uiDefButF(block, NUMSLI, B_TEXPRV, "Octs: ", 10, 110, 150, 19, &tex->mg_octaves, 0.0, 8.0, 10, 0, "Sets the number of frequencies used");
647 if ((tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF) || (tex->stype==TEX_HTERRAIN)) {
648 uiDefButF(block, NUMSLI, B_TEXPRV, "Ofst: ", 160, 110, 150, 19, &tex->mg_offset, 0.0, 6.0, 10, 0, "Sets the fractal offset");
649 if ((tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF))
650 uiDefButF(block, NUMSLI, B_TEXPRV, "Gain: ", 10, 90, 150, 19, &tex->mg_gain, 0.0, 6.0, 10, 0, "Sets the gain multiplier");
653 uiBlockBeginAlign(block);
654 /* noise output scale */
655 uiDefButF(block, NUM, B_TEXPRV, "iScale: ", 10, 60, 150, 19, &tex->ns_outscale, 0.0, 10.0, 10, 0, "Scales intensity output");
656 /* frequency scale */
657 uiDefButF(block, NUM, B_TEXPRV, "NoiseSize: ", 160, 60, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
658 uiBlockEndAlign(block);
660 /* noisebasis menu */
661 uiDefBut(block, LABEL, 0, "Noise Basis", 10, 30, 150, 19, 0, 0.0, 0.0, 0, 0, "");
662 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 10, 10, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence");
663 uiDefButF(block, NUM, B_NOP, "Nabla: ", 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");
668 static void texture_panel_distnoise(Tex *tex)
671 block= uiNewBlock(&curarea->uiblocks, "texture_panel_distnoise", UI_EMBOSS, UI_HELV, curarea->win);
672 if(uiNewPanel(curarea, block, "Distorted Noise", "Texture", 640, 0, 318, 204)==0) return;
673 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
675 uiBlockBeginAlign(block);
676 /* distortion amount */
677 uiDefButF(block, NUM, B_TEXPRV, "DistAmnt: ", 10, 130, 150, 19, &tex->dist_amount, 0.0, 10.0, 10, 0, "Sets amount of distortion");
678 /* frequency scale */
679 uiDefButF(block, NUM, B_TEXPRV, "NoiseSize: ", 160, 130, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
680 uiBlockEndAlign(block);
682 uiDefBut(block, LABEL, 0, "Distortion Noise", 10, 100, 150, 19, 0, 0.0, 0.0, 0, 0, "");
683 uiDefBut(block, LABEL, 0, "Noise Basis", 160, 100, 150, 19, 0, 0.0, 0.0, 0, 0, "");
685 uiBlockBeginAlign(block);
686 /* noisebasis used for the distortion */
687 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 10, 80, 150, 19, &tex->noisebasis, 0,0,0,0, "Sets the noise basis which does the distortion");
688 /* noisebasis to distort */
689 uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), 160, 80, 150, 19, &tex->noisebasis2, 0,0,0,0, "Sets the noise basis to distort");
690 uiBlockEndAlign(block);
692 uiDefButF(block, NUM, B_NOP, "Nabla: ", 10, 50, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");
696 static void texture_panel_voronoi(Tex *tex)
700 block= uiNewBlock(&curarea->uiblocks, "texture_panel_voronoi", UI_EMBOSS, UI_HELV, curarea->win);
701 if(uiNewPanel(curarea, block, "Voronoi", "Texture", 640, 0, 318, 204)==0) return;
702 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
705 uiBlockBeginAlign(block);
706 uiDefButS(block, ROW, B_TEXPRV, "Int", 10, 180, 75, 18, &tex->vn_coltype, 1.0, 0.0, 0, 0, "Only calculate intensity");
707 uiDefButS(block, ROW, B_TEXPRV, "Col1", 85, 180, 75, 18, &tex->vn_coltype, 1.0, 1.0, 0, 0, "Color cells by position");
708 uiDefButS(block, ROW, B_TEXPRV, "Col2", 160, 180, 75, 18, &tex->vn_coltype, 1.0, 2.0, 0, 0, "Same as Col1 + outline based on F2-F1");
709 uiDefButS(block, ROW, B_TEXPRV, "Col3", 235, 180, 75, 18, &tex->vn_coltype, 1.0, 3.0, 0, 0, "Same as Col2 * intensity");
710 uiBlockEndAlign(block);
712 /* distance metric */
713 sprintf(dm_menu, "Distance Metric %%t|Actual Distance %%x%d|Distance Squared %%x%d|Manhattan %%x%d|Chebychev %%x%d|Minkovsky 1/2 %%x%d|Minkovsky 4 %%x%d|Minkovsky %%x%d", TEX_DISTANCE, TEX_DISTANCE_SQUARED, TEX_MANHATTAN, TEX_CHEBYCHEV, TEX_MINKOVSKY_HALF, TEX_MINKOVSKY_FOUR, TEX_MINKOVSKY);
714 uiDefBut(block, LABEL, B_TEXPRV, "Distance Metric", 10, 160, 150, 19, 0, 0, 0, 0, 0, "");
715 uiDefButS(block, MENU, B_TEXPRV, dm_menu, 10, 140, 150, 19, &tex->vn_distm, 0,0,0,0, "Sets the distance metric to be used");
717 if (tex->vn_distm==TEX_MINKOVSKY)
718 uiDefButF(block, NUMSLI, B_TEXPRV, "Exp: ", 10, 120, 150, 19, &tex->vn_mexp, 0.01, 10.0, 10, 0, "Sets minkovsky exponent");
720 uiBlockBeginAlign(block);
721 uiDefButF(block, NUM, B_TEXPRV, "iScale: ", 160, 140, 150, 19, &tex->ns_outscale, 0.01, 10.0, 10, 0, "Scales intensity output");
722 uiDefButF(block, NUM, B_TEXPRV, "Size: ", 160, 120, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
723 uiBlockBeginAlign(block);
724 uiDefButF(block, NUM, B_NOP, "Nabla: ", 160, 70, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");
727 uiBlockBeginAlign(block);
728 uiDefButF(block, NUMSLI, B_TEXPRV, "W1: ", 10, 70, 150, 19, &tex->vn_w1, -2.0, 2.0, 10, 0, "Sets feature weight 1");
729 uiDefButF(block, NUMSLI, B_TEXPRV, "W2: ", 10, 50, 150, 19, &tex->vn_w2, -2.0, 2.0, 10, 0, "Sets feature weight 2");
730 uiDefButF(block, NUMSLI, B_TEXPRV, "W3: ", 10, 30, 150, 19, &tex->vn_w3, -2.0, 2.0, 10, 0, "Sets feature weight 3");
731 uiDefButF(block, NUMSLI, B_TEXPRV, "W4: ", 10, 10, 150, 19, &tex->vn_w4, -2.0, 2.0, 10, 0, "Sets feature weight 4");
735 static char *layer_menu(RenderResult *rr, short *curlay)
738 int len= 64 + 32*BLI_countlist(&rr->layers);
740 char *str= MEM_callocN(len, "menu layers");
742 strcpy(str, "Layer %t");
747 a+= sprintf(str+a, "|Composite %%x0");
750 for(rl= rr->layers.first; rl; rl= rl->next, nr++) {
751 a+= sprintf(str+a, "|%s %%x%d", rl->name, nr);
754 /* no curlay clip here, on render (redraws) the amount of layers can be 1 fir single-layer render */
759 /* rl==NULL means composite result */
760 static char *pass_menu(RenderLayer *rl, short *curpass)
763 int len= 64 + 32*(rl?BLI_countlist(&rl->passes):1);
765 char *str= MEM_callocN(len, "menu layers");
767 strcpy(str, "Pass %t");
770 /* rendered results don't have a Combined pass */
771 if(rl==NULL || rl->rectf) {
772 a+= sprintf(str+a, "|Combined %%x0");
777 for(rpass= rl->passes.first; rpass; rpass= rpass->next, nr++)
778 a+= sprintf(str+a, "|%s %%x%d", rpass->name, nr);
786 static void set_frames_cb(void *ima_v, void *iuser_v)
789 ImageUser *iuser= iuser_v;
792 iuser->frames = IMB_anim_get_duration(ima->anim);
793 BKE_image_user_calc_imanr(iuser, G.scene->r.cfra, 0);
797 static void image_src_change_cb(void *ima_v, void *iuser_v)
799 BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_SRC_CHANGE);
802 /* buttons have 2 arg callbacks, filewindow has 3 args... so thats why the wrapper below */
803 static void image_browse_cb1(char *unused, void *ima_pp_v, void *iuser_v)
805 Image **ima_pp= (Image **)ima_pp_v;
806 ImageUser *iuser= iuser_v;
811 if(iuser->menunr== -2) {
812 activate_databrowse_args(&ima->id, ID_IM, 0, &iuser->menunr, image_browse_cb1, ima_pp, iuser);
814 else if (iuser->menunr>0) {
815 Image *newima= (Image*) BLI_findlink(&G.main->image, iuser->menunr-1);
817 if (newima && newima!=ima) {
819 id_us_plus(&newima->id);
820 if(ima) ima->id.us--;
822 BKE_image_signal(newima, iuser, IMA_SIGNAL_USER_NEW_IMAGE);
824 BIF_undo_push("Browse image");
830 static void image_browse_cb(void *ima_pp_v, void *iuser_v)
832 image_browse_cb1(NULL, ima_pp_v, iuser_v);
835 static void image_reload_cb(void *ima_v, void *iuser_v)
838 BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_RELOAD);
842 static void image_field_test(void *ima_v, void *iuser_v)
847 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
850 if( !(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1;
851 if( (ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1;
853 BKE_image_signal(ima, iuser_v, IMA_SIGNAL_FREE);
859 static void image_unlink_cb(void *ima_pp_v, void *unused)
861 Image **ima_pp= (Image **)ima_pp_v;
863 if(ima_pp && *ima_pp) {
870 static void image_load_fs_cb(void *ima_pp_v, void *iuser_v)
872 Image **ima_pp= (Image **)ima_pp_v;
876 if(ima_pp==NULL) return;
878 sa= closest_bigger_area();
880 if(*ima_pp) name= (*ima_pp)->name;
883 if (strcmp (U.textudir, "/") == 0)
889 else name = U.textudir;
891 if (G.qual & LR_CTRLKEY) {
892 activate_imageselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
895 activate_fileselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
899 /* 5 layer button callbacks... */
900 static void image_multi_cb(void *rr_v, void *iuser_v)
902 BKE_image_multilayer_index(rr_v, iuser_v);
904 static void image_multi_inclay_cb(void *rr_v, void *iuser_v)
906 RenderResult *rr= rr_v;
907 ImageUser *iuser= iuser_v;
908 int tot= BLI_countlist(&rr->layers) + (rr->rectf?1:0); /* fake compo result layer */
909 if(iuser->layer<tot-1)
911 BKE_image_multilayer_index(rr, iuser);
913 static void image_multi_declay_cb(void *rr_v, void *iuser_v)
915 ImageUser *iuser= iuser_v;
918 BKE_image_multilayer_index(rr_v, iuser);
920 static void image_multi_incpass_cb(void *rr_v, void *iuser_v)
922 RenderResult *rr= rr_v;
923 ImageUser *iuser= iuser_v;
924 RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer);
926 int tot= BLI_countlist(&rl->passes) + (rl->rectf?1:0); /* builtin render result has no combined pass in list */
927 if(iuser->pass<tot-1) {
929 BKE_image_multilayer_index(rr, iuser);
933 static void image_multi_decpass_cb(void *rr_v, void *iuser_v)
935 ImageUser *iuser= iuser_v;
938 BKE_image_multilayer_index(rr_v, iuser);
942 static void image_pack_cb(void *ima_v, void *iuser_v)
946 if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) {
947 if (ima->packedfile) {
948 if (G.fileflags & G_AUTOPACK) {
949 if (okee("Disable AutoPack ?")) {
950 G.fileflags &= ~G_AUTOPACK;
954 if ((G.fileflags & G_AUTOPACK) == 0) {
955 unpackImage(ima, PF_ASK);
956 BIF_undo_push("Unpack image");
960 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
961 if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
962 error("Can't pack painted image. Save image or use Repack as PNG.");
964 ima->packedfile = newPackedFile(ima->name);
965 BIF_undo_push("Pack image");
972 static void image_load_cb(void *ima_pp_v, void *iuser_v)
975 Image *ima= *((Image **)ima_pp_v);
976 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v);
979 /* name in ima has been changed by button! */
980 BLI_strncpy(str, ima->name, FILE_MAX);
981 if(ibuf) BLI_strncpy(ima->name, ibuf->name, FILE_MAX);
983 load_image_cb(str, ima_pp_v, iuser_v);
987 static void image_freecache_cb(void *ima_v, void *unused)
989 BKE_image_free_anim_ibufs(ima_v, G.scene->r.cfra);
990 allqueue(REDRAWIMAGE, 0);
993 static void image_generated_change_cb(void *ima_v, void *iuser_v)
995 BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_FREE);
998 static void image_user_change(void *iuser_v, void *unused)
1000 BKE_image_user_calc_imanr(iuser_v, G.scene->r.cfra, 0);
1003 void uiblock_layer_pass_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int event, int x, int y, int w)
1006 RenderLayer *rl= NULL;
1010 /* layer menu is 1/3 larger than pass */
1015 strp= layer_menu(rr, &iuser->layer);
1016 but= uiDefButS(block, MENU, event, strp, x, y, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer");
1017 uiButSetFunc(but, image_multi_cb, rr, iuser);
1020 rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */
1021 strp= pass_menu(rl, &iuser->pass);
1022 but= uiDefButS(block, MENU, event, strp, x+wmenu1, y, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass");
1023 uiButSetFunc(but, image_multi_cb, rr, iuser);
1027 static void uiblock_layer_pass_arrow_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int imagechanged)
1031 if(rr==NULL || iuser==NULL)
1033 if(rr->layers.first==NULL) {
1034 uiDefBut(block, LABEL, 0, "No Layers in Render Result,", 10, 107, 300, 20, NULL, 1, 0, 0, 0, "");
1038 uiBlockBeginAlign(block);
1040 /* decrease, increase arrows */
1041 but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 10,107,17,20, NULL, 0, 0, 0, 0, "Previous Layer");
1042 uiButSetFunc(but, image_multi_declay_cb, rr, iuser);
1043 but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 27,107,18,20, NULL, 0, 0, 0, 0, "Next Layer");
1044 uiButSetFunc(but, image_multi_inclay_cb, rr, iuser);
1046 uiblock_layer_pass_buttons(block, rr, iuser, imagechanged, 45, 107, 230);
1048 /* decrease, increase arrows */
1049 but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 275,107,17,20, NULL, 0, 0, 0, 0, "Previous Pass");
1050 uiButSetFunc(but, image_multi_decpass_cb, rr, iuser);
1051 but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 292,107,18,20, NULL, 0, 0, 0, 0, "Next Pass");
1052 uiButSetFunc(but, image_multi_incpass_cb, rr, iuser);
1054 uiBlockEndAlign(block);
1058 /* The general Image panel with the loadsa callbacks! */
1059 void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
1060 short redraw, short imagechanged)
1062 Image *ima= *ima_pp;
1064 char str[128], *strp;
1066 /* different stuff when we show viewer */
1067 if(ima && ima->source==IMA_SRC_VIEWER) {
1068 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser);
1070 image_info(ima, ibuf, str);
1071 uiDefBut(block, LABEL, 0, ima->id.name+2, 10, 180, 300, 20, NULL, 1, 0, 0, 0, "");
1072 uiDefBut(block, LABEL, 0, str, 10, 160, 300, 20, NULL, 1, 0, 0, 0, "");
1074 if(ima->type==IMA_TYPE_COMPOSITE) {
1075 iuser= ntree_get_active_iuser(G.scene->nodetree);
1077 uiBlockBeginAlign(block);
1078 uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, "");
1079 uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, "");
1080 but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, "");
1081 uiButSetFunc(but, image_freecache_cb, ima, NULL);
1084 sprintf(str, "(%d) Frames:", iuser->framenr);
1085 else strcpy(str, "Frames:");
1086 uiBlockBeginAlign(block);
1087 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");
1088 uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
1091 else if(ima->type==IMA_TYPE_R_RESULT) {
1092 /* browse layer/passes */
1093 uiblock_layer_pass_arrow_buttons(block, RE_GetResult(RE_GetRender(G.scene->id.name)), iuser, imagechanged);
1098 /* the main ima source types */
1100 uiSetButLock(ima->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
1101 uiBlockBeginAlign(block);
1102 uiBlockSetFunc(block, image_src_change_cb, ima, iuser);
1103 uiDefButS(block, ROW, imagechanged, "Still", 10, 180, 60, 20, &ima->source, 0.0, IMA_SRC_FILE, 0, 0, "Single Image file");
1104 uiDefButS(block, ROW, imagechanged, "Movie", 70, 180, 60, 20, &ima->source, 0.0, IMA_SRC_MOVIE, 0, 0, "Movie file");
1105 uiDefButS(block, ROW, imagechanged, "Sequence", 130, 180, 90, 20, &ima->source, 0.0, IMA_SRC_SEQUENCE, 0, 0, "Multiple Image files, as a sequence");
1106 uiDefButS(block, ROW, imagechanged, "Generated", 220, 180, 90, 20, &ima->source, 0.0, IMA_SRC_GENERATED, 0, 0, "Generated Image");
1107 uiBlockSetFunc(block, NULL, NULL, NULL);
1110 uiDefBut(block, LABEL, 0, " ", 10, 180, 300, 20, 0, 0, 0, 0, 0, ""); /* for align in panel */
1113 IMAnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), NULL, &iuser->menunr);
1115 uiBlockBeginAlign(block);
1116 but= uiDefButS(block, MENU, imagechanged, strp, 10,155,23,20, &iuser->menunr, 0, 0, 0, 0, "Selects an existing Image or Movie");
1117 uiButSetFunc(but, image_browse_cb, ima_pp, iuser);
1121 /* name + options, or only load */
1123 int drawpack= (ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE && ima->ok);
1125 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.");
1126 uiButSetFunc(but, test_idbutton_cb, ima->id.name, NULL);
1127 but= uiDefBut(block, BUT, imagechanged, "Reload", 210, 155, 60, 20, NULL, 0, 0, 0, 0, "Reloads Image or Movie");
1128 uiButSetFunc(but, image_reload_cb, ima, iuser);
1130 but= uiDefIconBut(block, BUT, imagechanged, ICON_X, 270,155,20,20, 0, 0, 0, 0, 0, "Unlink Image block");
1131 uiButSetFunc(but, image_unlink_cb, ima_pp, NULL);
1132 sprintf(str, "%d", ima->id.us);
1133 uiDefBut(block, BUT, B_NOP, str, 290,155,20,20, 0, 0, 0, 0, 0, "Only displays number of users of Image block");
1135 but= uiDefIconBut(block, BUT, imagechanged, ICON_FILESEL, 10, 135, 23, 20, 0, 0, 0, 0, 0, "Open Fileselect to load new Image");
1136 uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser);
1137 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");
1138 uiButSetFunc(but, image_load_cb, ima_pp, iuser);
1141 if (ima->packedfile) packdummy = 1;
1143 but= uiDefIconButBitI(block, TOG, 1, redraw, ICON_PACKAGE, 290,135,20,20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this Image");
1144 uiButSetFunc(but, image_pack_cb, ima, iuser);
1149 but= uiDefBut(block, BUT, imagechanged, "Load", 33, 155, 100,20, NULL, 0, 0, 0, 0, "Load new Image of Movie");
1150 uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser);
1152 uiBlockEndAlign(block);
1155 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser);
1157 /* check for re-render, only buttons */
1158 if(imagechanged==B_IMAGECHANGED) {
1159 if(iuser->flag & IMA_ANIM_REFRESHED) {
1160 iuser->flag &= ~IMA_ANIM_REFRESHED;
1161 BIF_preview_changed(ID_TE);
1166 if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
1167 uiblock_layer_pass_arrow_buttons(block, ima->rr, iuser, imagechanged);
1170 image_info(ima, ibuf, str);
1171 uiDefBut(block, LABEL, 0, str, 10, 112, 300, 20, NULL, 1, 0, 0, 0, "");
1174 /* exception, let's do because we only use this panel 3 times in blender... but not real good code! */
1175 if( (FACESEL_PAINT_TEST) && G.sima && &G.sima->iuser==iuser)
1177 /* left side default per-image options, right half the additional options */
1180 uiBlockBeginAlign(block);
1181 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");
1182 uiButSetFunc(but, image_field_test, ima, iuser);
1183 uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 75, 70, 45, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
1185 uiBlockSetFunc(block, image_reload_cb, ima, iuser);
1186 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");
1187 uiDefButBitS(block, TOG, IMA_DO_PREMUL, imagechanged, "Premul", 55, 50, 65, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha");
1188 uiBlockEndAlign(block);
1190 if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
1191 sprintf(str, "(%d) Frames:", iuser->framenr);
1193 uiBlockBeginAlign(block);
1194 uiBlockSetFunc(block, image_user_change, iuser, NULL);
1195 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");
1198 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");
1199 but= uiDefBut(block, BUT, redraw, "<", 290, 50, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button");
1200 uiButSetFunc(but, set_frames_cb, ima, iuser);
1203 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");
1205 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");
1206 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)");
1208 uiDefButI(block, NUM, imagechanged, "StartFr:", 120,10,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie");
1209 uiDefButS(block, TOG, imagechanged, "Cyclic", 220,10,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie");
1211 uiBlockSetFunc(block, NULL, iuser, NULL);
1213 else if(ima->source==IMA_SRC_GENERATED) {
1215 uiBlockBeginAlign(block);
1216 uiBlockSetFunc(block, image_generated_change_cb, ima, iuser);
1217 uiDefButS(block, NUM, imagechanged, "SizeX:", 120,70,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x");
1218 uiDefButS(block, NUM, imagechanged, "SizeY:", 220,70,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y");
1219 uiDefButS(block, TOG, imagechanged, "UV Test grid",120,50,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, "");
1220 uiBlockSetFunc(block, NULL, NULL, NULL);
1223 uiBlockEndAlign(block);
1226 static void texture_panel_image(Image **ima, ImageUser *iuser)
1230 block= uiNewBlock(&curarea->uiblocks, "texture_panel_image", UI_EMBOSS, UI_HELV, curarea->win);
1231 if(uiNewPanel(curarea, block, "Image", "Texture", 960, 0, 318, 204)==0) return;
1233 uiblock_image_panel(block, ima, iuser, B_REDR, B_IMAGECHANGED);
1236 static void texture_panel_image_map(Tex *tex, MTex *mtex)
1240 block= uiNewBlock(&curarea->uiblocks, "texture_panel_image_map", UI_EMBOSS, UI_HELV, curarea->win);
1241 if(uiNewPanel(curarea, block, "Map Image", "Texture", 640, 0, 318, 204)==0) return;
1242 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
1245 uiBlockBeginAlign(block);
1246 uiDefButBitS(block, TOG, TEX_MIPMAP, B_IMAGECHANGED, "MipMap", 10, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Generates and uses mipmaps");
1247 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");
1248 uiDefButBitS(block, TOG, TEX_INTERPOL, 0, "Interpol", 160, 180, 75, 20, &tex->imaflag, 0, 0, 0, 0, "Interpolates pixels using Area filter");
1249 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");
1251 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");
1252 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");
1253 uiDefButBitS(block, TOG, TEX_NEGALPHA, B_TEXPRV, "NegAlpha", 210, 160, 100, 20, &tex->flag, 0, 0, 0, 0, "Click to invert the alpha values");
1255 uiBlockBeginAlign(block);
1256 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");
1257 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");
1259 uiBlockBeginAlign(block);
1260 uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map", 160,120,(mtex)? 75: 150,20, &tex->imaflag,
1261 0, 0, 0, 0, "Use image RGB values for normal mapping");
1263 uiDefButS(block, MENU, B_DIFF, "Normal Space %t|Camera %x0|World %x1|Object %x2|Tangent %x3",
1264 235,120,75,20, &mtex->normapspace, 0, 0, 0, 0, "Sets space of normal map image");
1265 uiBlockEndAlign(block);
1267 /* crop extend clip */
1269 uiBlockBeginAlign(block);
1270 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");
1271 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");
1272 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");
1273 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");
1274 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");
1276 if(tex->extend==TEX_REPEAT) {
1277 uiBlockBeginAlign(block);
1278 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");
1279 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");
1280 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");
1281 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");
1283 else if(tex->extend==TEX_CHECKER) {
1284 uiBlockBeginAlign(block);
1285 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");
1286 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");
1287 uiDefButF(block, NUM, B_TEXPRV, "Mortar:", 210,60,100,19, &tex->checkerdist, 0.0, 0.99, 0, 0, "Set checkers distance (like mortar)");
1289 uiBlockBeginAlign(block);
1290 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");
1291 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");
1293 uiBlockBeginAlign(block);
1294 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");
1295 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");
1296 uiBlockEndAlign(block);
1300 /***************************************/
1302 static void texture_panel_envmap(Tex *tex)
1308 short a, xco, yco, dx, dy;
1309 char *strp, str[32];
1311 block= uiNewBlock(&curarea->uiblocks, "texture_panel_envmap", UI_EMBOSS, UI_HELV, curarea->win);
1312 if(uiNewPanel(curarea, block, "Envmap", "Texture", 640, 0, 318, 204)==0) return;
1313 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
1315 if(tex->env==NULL) {
1316 tex->env= BKE_add_envmap();
1317 tex->env->object= OBACT;
1322 uiBlockBeginAlign(block);
1323 uiDefButS(block, ROW, B_REDR, "Static", 10, 180, 100, 19, &env->stype, 2.0, (float)ENV_STATIC, 0, 0, "Calculates environment map only once");
1324 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");
1325 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");
1326 uiBlockEndAlign(block);
1328 if(env->stype==ENV_LOAD) {
1331 IMAnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(G.buts->menunr));
1333 uiBlockBeginAlign(block);
1335 but= uiDefButS(block, MENU, B_TEXPRV, strp, 10,145,23,20, &tex->iuser.menunr, 0, 0, 0, 0, "Selects an existing environment map");
1336 uiButSetFunc(but, image_browse_cb, &tex->ima, &tex->iuser);
1339 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");
1340 uiButSetFunc(but, image_load_cb, &tex->ima, &tex->iuser);
1342 sprintf(str, "%d", tex->ima->id.us);
1343 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");
1344 uiBlockEndAlign(block);
1346 but= uiDefBut(block, BUT, B_IMAGECHANGED, "Reload", 230,125,80,20, 0, 0, 0, 0, 0, "Reloads saved environment map");
1347 uiButSetFunc(but, image_reload_cb, tex->ima, NULL);
1349 if (tex->ima->packedfile) packdummy = 1;
1351 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");
1352 uiButSetFunc(but, image_pack_cb, tex->ima, &tex->iuser);
1354 else uiBlockEndAlign(block);
1358 but= uiDefBut(block, BUT, B_IMAGECHANGED, "Load Image", 10,125,150,20, 0, 0, 0, 0, 0, "Loads saved environment map - file select");
1359 uiButSetFunc(but, image_load_fs_cb, &tex->ima, &tex->iuser);
1362 uiBlockBeginAlign(block);
1363 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");
1364 uiDefBut(block, BUT, B_ENV_SAVE, "Save EnvMap", 110,145,100,20, 0, 0, 0, 0, 0, "Saves current environment map");
1365 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");
1367 uiBlockBeginAlign(block);
1368 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");
1369 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");
1370 uiDefButF(block, NUM, B_NOP, "Zoom: ", 210,120,100,20, &env->viewscale, 0.5f, 5.0f, 100, 2, "Zoom factor for planar environment map");
1371 uiBlockEndAlign(block);
1374 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");
1375 if(env->stype!=ENV_LOAD)
1376 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");
1378 uiBlockBeginAlign(block);
1379 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");
1380 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"),
1381 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"),
1382 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");
1383 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");
1384 uiBlockEndAlign(block);
1386 uiDefBut(block, LABEL, 0, "Don't render layer:", 10,10,140,22, 0, 0.0, 0.0, 0, 0, "");
1392 uiBlockBeginAlign(block);
1394 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");
1396 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");
1398 uiBlockBeginAlign(block);
1401 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");
1403 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");
1408 static void colorband_pos_cb(void *coba_v, void *unused_v)
1410 ColorBand *coba= coba_v;
1413 if(coba->tot<2) return;
1415 for(a=0; a<coba->tot; a++) coba->data[a].cur= a;
1416 qsort(coba->data, coba->tot, sizeof(CBData), vergcband);
1417 for(a=0; a<coba->tot; a++) {
1418 if(coba->data[a].cur==coba->cur) {
1419 if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */
1426 static void colorband_add_cb(void *coba_v, void *unused_v)
1428 ColorBand *coba= coba_v;
1430 if(coba->tot < MAXCOLORBAND-1) coba->tot++;
1431 coba->cur= coba->tot-1;
1433 colorband_pos_cb(coba, NULL);
1434 BIF_undo_push("Add colorband");
1438 static void colorband_del_cb(void *coba_v, void *unused_v)
1440 ColorBand *coba= coba_v;
1443 if(coba->tot<2) return;
1445 for(a=coba->cur; a<coba->tot; a++) {
1446 coba->data[a]= coba->data[a+1];
1448 if(coba->cur) coba->cur--;
1451 BIF_undo_push("Delete colorband");
1452 BIF_preview_changed(ID_TE);
1456 /* offset aligns from bottom, standard width 300, height 115 */
1457 static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, int redraw)
1462 if(coba==NULL) return;
1464 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");
1465 uiButSetFunc(bt, colorband_add_cb, coba, NULL);
1466 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");
1467 bt= uiDefBut(block, BUT, redraw, "Del", 199+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Deletes the active position");
1468 uiButSetFunc(bt, colorband_del_cb, coba, NULL);
1469 uiDefButS(block, ROW, redraw, "E", 236+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) ");
1470 uiDefButS(block, ROW, redraw, "C", 252+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal");
1471 uiDefButS(block, ROW, redraw, "L", 268+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear");
1472 uiDefButS(block, ROW, redraw, "S", 284+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline");
1474 uiDefBut(block, BUT_COLORBAND, redraw, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, "");
1476 cbd= coba->data + coba->cur;
1478 uiBlockBeginAlign(block);
1479 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");
1480 uiButSetFunc(bt, colorband_pos_cb, coba, NULL);
1481 uiDefButF(block, COL, redraw, "", xoffs,20+yoffs,110,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "");
1482 uiDefButF(block, NUMSLI, redraw, "A ", xoffs,yoffs,110,20, &cbd->a, 0.0, 1.0, 10, 0, "Sets the alpha value for this position");
1484 uiBlockBeginAlign(block);
1485 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");
1486 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");
1487 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");
1488 uiBlockEndAlign(block);
1491 void draw_colorband_buts_small(uiBlock *block, ColorBand *coba, rctf *butr, int event)
1495 float unit= (butr->xmax-butr->xmin)/14.0f;
1496 float xs= butr->xmin;
1498 cbd= coba->data + coba->cur;
1500 uiBlockBeginAlign(block);
1501 uiDefButF(block, COL, event, "", xs,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "");
1502 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, "");
1503 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");
1504 uiButSetFunc(bt, colorband_add_cb, coba, NULL);
1505 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");
1506 uiButSetFunc(bt, colorband_del_cb, coba, NULL);
1507 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) ");
1508 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");
1509 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");
1510 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");
1512 uiDefBut(block, BUT_COLORBAND, event, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, "");
1513 uiBlockEndAlign(block);
1517 static void texture_panel_colors(Tex *tex)
1521 block= uiNewBlock(&curarea->uiblocks, "texture_panel_colors", UI_EMBOSS, UI_HELV, curarea->win);
1522 uiNewPanelTabbed("Texture", "Texture");
1523 if(uiNewPanel(curarea, block, "Colors", "Texture", 1280, 0, 318, 204)==0) return;
1525 uiSetButLock(tex->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
1528 uiBlockBeginAlign(block);
1529 uiDefButBitS(block, TOG, TEX_COLORBAND, B_COLORBAND, "Colorband",10,180,80,20, &tex->flag, 0, 0, 0, 0, "Toggles colorband operations");
1531 if(tex->flag & TEX_COLORBAND) {
1532 draw_colorband_buts(block, tex->coba, 10, 85, B_TEXREDR_PRV);
1536 if((tex->flag & TEX_COLORBAND)==0) {
1537 uiBlockBeginAlign(block);
1538 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");
1539 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");
1540 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");
1543 uiBlockBeginAlign(block);
1544 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");
1545 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");
1548 static int texture_channels_num_display(MTex **mtex)
1555 /* compute number of texture channels to draw, 1 more
1556 * than the last, used texture channel, and at least 10 */
1559 for(a=MAX_MTEX-1; a>=0; a--) {
1568 else if(num_mtex < MAX_MTEX)
1569 return num_mtex + 1;
1574 static void texture_panel_texture(MTex *actmtex, Material *ma, World *wrld, Lamp *la, bNode *node, Brush *br, SculptData *sd)
1578 ID *id=NULL, *idfrom;
1583 block= uiNewBlock(&curarea->uiblocks, "texture_panel_texture", UI_EMBOSS, UI_HELV, curarea->win);
1584 if(uiNewPanel(curarea, block, "Texture", "Texture", 320, 0, 318, 204)==0) return;
1586 /* first do the browse but */
1588 id= (ID *)actmtex->tex;
1609 idfrom= NULL; /* Not sure what this does */
1617 uiBlockSetCol(block, TH_BUT_SETTING2);
1619 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);
1622 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);
1625 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);
1628 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);
1631 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);
1636 uiBlockSetCol(block, TH_BUT_NEUTRAL);
1640 /* From button: removed */
1645 uiBlockBeginAlign(block);
1648 num_mtex= texture_channels_num_display(mtex);
1649 for(a=0; a<num_mtex; a++) {
1652 if(mt && mt->tex) splitIDname(mt->tex->id.name+2, str, &loos);
1653 else strcpy(str, "");
1657 uiDefButC(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(ma->texact), 0.0, (float)a, 0, 0, "Click to select texture channel");
1661 uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(wrld->texact), 0.0, (float)a, 0, 0, "");
1665 uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(la->texact), 0.0, (float)a, 0, 0, "");
1669 uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(br->texact), 0.0, (float)a, 0, 0, "");
1673 uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(sd->texact), 0.0, (float)a, 0, 0, "");
1677 uiBlockEndAlign(block);
1679 uiBlockSetCol(block, TH_AUTO);
1684 Tex *tex= (Tex *)id;
1686 uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
1688 /* newnoise: all texture types as menu, not enough room for more buttons.
1689 * Can widen panel, but looks ugly when other panels overlap it */
1691 sprintf(textypes, "Texture Type %%t|None %%x%d|Image %%x%d|EnvMap %%x%d|Clouds %%x%d|Marble %%x%d|Stucci %%x%d|Wood %%x%d|Magic %%x%d|Blend %%x%d|Noise %%x%d|Plugin %%x%d|Musgrave %%x%d|Voronoi %%x%d|DistortedNoise %%x%d", 0, TEX_IMAGE, TEX_ENVMAP, TEX_CLOUDS, TEX_MARBLE, TEX_STUCCI, TEX_WOOD, TEX_MAGIC, TEX_BLEND, TEX_NOISE, TEX_PLUGIN, TEX_MUSGRAVE, TEX_VORONOI, TEX_DISTNOISE);
1692 uiDefBut(block, LABEL, 0, "Texture Type", 160, 150, 140, 20, 0, 0.0, 0.0, 0, 0, "");
1693 uiDefButS(block, MENU, B_TEXTYPE, textypes, 160, 125, 140, 25, &tex->type, 0,0,0,0, "Select texture type");
1697 // label to avoid centering
1698 uiDefBut(block, LABEL, 0, " ", 160, 10, 140, 20, 0, 0, 0, 0, 0, "");
1702 static void texture_panel_preview(MTex *mtex, int preview)
1706 block= uiNewBlock(&curarea->uiblocks, "texture_panel_preview", UI_EMBOSS, UI_HELV, curarea->win);
1707 if(uiNewPanel(curarea, block, "Preview", "Texture", 0, 0, 318, 204)==0) return;
1709 if(preview) uiBlockSetDrawExtraFunc(block, BIF_previewdraw);
1711 // label to force a boundbox for buttons not to be centered
1712 uiDefBut(block, LABEL, 0, " ", 20,20,10,10, 0, 0, 0, 0, 0, "");
1714 uiBlockBeginAlign(block);
1715 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");
1716 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");
1717 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");
1718 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");
1719 uiBlockEndAlign(block);
1721 if(mtex && mtex->tex) {
1722 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");
1723 uiSetButLock(mtex->tex->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
1724 uiDefBut(block, BUT, B_DEFTEXVAR, "Default Vars",200,10,80,20, 0, 0, 0, 0, 0, "Sets all values to defaults");
1730 /* *************************** RADIO ******************************** */
1732 void do_radiobuts(unsigned short event)
1738 rad= G.scene->radio;
1743 BIF_undo_push("Add radiosity");
1744 allqueue(REDRAWBUTSSHADING, 0);
1745 allqueue(REDRAWVIEW3D, 0);
1749 BIF_undo_push("Delete radiosity");
1750 allqueue(REDRAWBUTSSHADING, 0);
1751 allqueue(REDRAWVIEW3D, 0);
1755 allqueue(REDRAWBUTSSHADING, 0);
1756 allqueue(REDRAWVIEW3D, 0);
1759 rad_collect_meshes();
1760 allqueue(REDRAWBUTSSHADING, 0);
1761 allqueue(REDRAWVIEW3D, 0);
1764 if(phase==RAD_PHASE_PATCHES) {
1765 rad_limit_subdivide();
1766 allqueue(REDRAWBUTSSHADING, 0);
1767 allqueue(REDRAWVIEW3D, 0);
1771 if(phase==RAD_PHASE_PATCHES) {
1773 rad_subdivshootpatch();
1774 allqueue(REDRAWBUTSSHADING, 0);
1775 allqueue(REDRAWVIEW3D, 0);
1780 if(phase==RAD_PHASE_PATCHES) {
1782 rad_subdivshootelem();
1783 allqueue(REDRAWBUTSSHADING, 0);
1784 allqueue(REDRAWVIEW3D, 0);
1789 if(phase==RAD_PHASE_PATCHES) {
1793 allqueue(REDRAWBUTSSHADING, 0);
1794 allqueue(REDRAWVIEW3D, 0);
1799 allqueue(REDRAWVIEW3D, 0);
1800 allqueue(REDRAWBUTSSHADING, 0);
1804 if(phase & RAD_PHASE_FACES) make_face_tab();
1805 else make_node_display(); /* radio solver also uses nodes, different ones :) */
1806 allqueue(REDRAWVIEW3D, 0);
1809 if(phase & RAD_PHASE_FACES) {
1811 removeEqualNodes(rad->nodelim);
1813 allqueue(REDRAWVIEW3D, 0);
1814 allqueue(REDRAWBUTSSHADING, 0);
1817 case B_RAD_NODEFILT:
1818 if(phase & RAD_PHASE_FACES) {
1822 allqueue(REDRAWVIEW3D, 0);
1825 case B_RAD_FACEFILT:
1826 if(phase & RAD_PHASE_FACES) {
1828 allqueue(REDRAWVIEW3D, 0);
1833 allqueue(REDRAWVIEW3D, 0);
1836 if(phase & RAD_PHASE_FACES) rad_addmesh();
1837 BIF_undo_push("Radiosity add mesh");
1838 allqueue(REDRAWVIEW3D, 0);
1841 if(phase & RAD_PHASE_FACES) rad_replacemesh();
1842 BIF_undo_push("Radiosity replace mesh");
1843 allqueue(REDRAWVIEW3D, 0);
1850 static void radio_panel_calculation(Radio *rad, int flag)
1854 block= uiNewBlock(&curarea->uiblocks, "radio_panel_calculation", UI_EMBOSS, UI_HELV, curarea->win);
1855 if(uiNewPanel(curarea, block, "Calculation", "Radio", 640, 0, 318, 204)==0) return;
1856 uiAutoBlock(block, 10, 10, 300, 200, UI_BLOCK_ROWS);
1858 if(flag != RAD_PHASE_PATCHES) uiBlockSetCol(block, TH_BUT_NEUTRAL);
1859 uiDefBut(block, BUT, B_RAD_GO, "GO", 0, 0, 10, 15, NULL, 0, 0, 0, 0, "Starts the radiosity simulation");
1861 uiBlockSetCol(block, TH_AUTO);
1862 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");
1863 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");
1865 if(flag != RAD_PHASE_PATCHES) uiBlockSetCol(block, TH_BUT_NEUTRAL);
1866 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");
1867 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");
1869 uiBlockSetCol(block, TH_AUTO);
1870 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");
1871 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");
1873 if(flag & RAD_PHASE_FACES);
1874 else uiBlockSetCol(block, TH_BUT_NEUTRAL);
1875 uiDefBut(block, BUT, B_RAD_FACEFILT, "FaceFilter", 4, 0, 10, 10, NULL, 0, 0, 0, 0, "Forces an extra smoothing");
1876 uiDefBut(block, BUT, B_RAD_NODEFILT, "Element Filter", 4, 0, 10, 10, NULL, 0, 0, 0, 0, "Filters elements to remove aliasing artefacts");
1878 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'");
1879 uiBlockSetCol(block, TH_AUTO);
1880 uiDefButS(block, NUM, B_NOP, "Lim:", 5, 0, 10, 10, &rad->nodelim, 0.0, 50.0, 0, 0, "Sets the range for removing doubles");
1885 static void radio_panel_tool(Radio *rad, int flag)
1889 block= uiNewBlock(&curarea->uiblocks, "radio_panel_tool", UI_EMBOSS, UI_HELV, curarea->win);
1890 if(uiNewPanel(curarea, block, "Radio Tool", "Radio", 320, 0, 318, 204)==0) return;
1891 uiAutoBlock(block, 10, 10, 300, 200, UI_BLOCK_ROWS);
1893 if(flag & RAD_PHASE_PATCHES) uiBlockSetCol(block, TH_BUT_SETTING1);
1894 uiDefBut(block, BUT, B_RAD_COLLECT, "Collect Meshes", 0, 0, 10, 15, NULL, 0, 0, 0, 0, "Converts selected visible meshes to patches");
1896 if(flag & RAD_PHASE_PATCHES)uiBlockSetCol(block, TH_AUTO);
1897 else uiBlockSetCol(block, TH_BUT_NEUTRAL);
1898 uiDefBut(block, BUT, B_RAD_FREE, "Free Radio Data", 0, 0, 10, 15, NULL, 0, 0, 0, 0, "Releases all memory used by Radiosity");
1900 if(flag & RAD_PHASE_FACES) uiBlockSetCol(block, TH_AUTO);
1901 else uiBlockSetCol(block, TH_BUT_NEUTRAL);
1902 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");
1903 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");
1905 uiBlockSetCol(block, TH_AUTO);
1906 uiDefButS(block, ROW, B_RAD_DRAW, "Wire", 2, 0, 10, 10, &rad->drawtype, 0.0, 0.0, 0, 0, "Enables wireframe drawmode");
1907 uiDefButS(block, ROW, B_RAD_DRAW, "Solid", 2, 0, 10, 10, &rad->drawtype, 0.0, 1.0, 0, 0, "Enables solid drawmode");
1908 uiDefButS(block, ROW, B_RAD_DRAW, "Gour", 2, 0, 10, 10, &rad->drawtype, 0.0, 2.0, 0, 0, "Enables Gourad drawmode");
1909 uiDefButBitS(block, TOG, 1, B_RAD_DRAW, "ShowLim", 2, 0, 10, 10, &rad->flag, 0, 0, 0, 0, "Draws patch and element limits");
1910 uiDefButBitS(block, TOG, 2, B_RAD_DRAW, "Z", 2, 0, 3, 10, &rad->flag, 0, 0, 0, 0, "Draws limits differently");
1912 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");
1913 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");
1914 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");
1915 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");
1917 uiDefBut(block, BUT, B_RAD_INIT, "Limit Subdivide", 5, 0, 10, 10, NULL, 0, 0, 0, 0, "Subdivides patches");
1921 static void radio_panel_render(Radio *rad)
1925 block= uiNewBlock(&curarea->uiblocks, "radio_panel_render", UI_EMBOSS, UI_HELV, curarea->win);
1926 if(uiNewPanel(curarea, block, "Radio Render", "Radio", 0, 0, 318, 204)==0) return;
1927 uiAutoBlock(block, 210, 30, 230, 150, UI_BLOCK_ROWS);
1929 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");
1930 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");
1931 uiDefButF(block, NUM, B_RAD_FAC, "Mult:", 3, 0, 10, 15, &rad->radfac, 0.001, 250.0, 100, 0, "Mulitplies the energy values");
1932 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");
1933 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");
1937 /* ***************************** WORLD ************************** */
1939 void do_worldbuts(unsigned short event)
1941 static short mtexcopied=0;
1942 static MTex mtexcopybuf;
1948 case B_TEXCLEARWORLD:
1949 wrld= G.buts->lockpoin;
1950 mtex= wrld->mtex[ wrld->texact ];
1952 if(mtex->tex) mtex->tex->id.us--;
1954 wrld->mtex[ wrld->texact ]= 0;
1955 allqueue(REDRAWBUTSSHADING, 0);
1956 allqueue(REDRAWOOPS, 0);
1957 BIF_undo_push("Unlink world texture");
1958 BIF_preview_changed(ID_WO);
1962 wrld= G.buts->lockpoin;
1963 if(wrld && wrld->mtex[(int)wrld->texact] ) {
1964 mtex= wrld->mtex[(int)wrld->texact];
1965 if(mtex->tex==NULL) {
1966 error("No texture available");
1969 memcpy(&mtexcopybuf, wrld->mtex[(int)wrld->texact], sizeof(MTex));
1975 wrld= G.buts->lockpoin;
1976 if(wrld && mtexcopied && mtexcopybuf.tex) {
1977 if(wrld->mtex[(int)wrld->texact]==NULL )
1978 wrld->mtex[(int)wrld->texact]= MEM_mallocN(sizeof(MTex), "mtex");
1979 else if(wrld->mtex[(int)wrld->texact]->tex)
1980 wrld->mtex[(int)wrld->texact]->tex->id.us--;
1982 memcpy(wrld->mtex[(int)wrld->texact], &mtexcopybuf, sizeof(MTex));
1984 id_us_plus((ID *)mtexcopybuf.tex);
1985 BIF_undo_push("Paste mapping settings");
1986 BIF_preview_changed(ID_WO);
1987 scrarea_queue_winredraw(curarea);
1991 wrld= G.buts->lockpoin;
1992 if(wrld && (int)wrld->texact > 0) {
1993 mtexswap = wrld->mtex[(int)wrld->texact];
1994 wrld->mtex[(int)wrld->texact] = wrld->mtex[((int)wrld->texact)-1];
1995 wrld->mtex[((int)wrld->texact)-1] = mtexswap;
1997 allqueue(REDRAWBUTSSHADING, 0);
2000 case B_WMTEXMOVEDOWN:
2001 wrld= G.buts->lockpoin;
2002 if(wrld && (int)wrld->texact < MAX_MTEX-1) {
2003 mtexswap = wrld->mtex[(int)wrld->texact];
2004 wrld->mtex[(int)wrld->texact] = wrld->mtex[((int)wrld->texact)+1];
2005 wrld->mtex[((int)wrld->texact)+1] = mtexswap;
2007 allqueue(REDRAWBUTSSHADING, 0);
2011 /* falloff distances option only supports plain */
2012 wrld= G.buts->lockpoin;
2014 wrld->aocolor= WO_AOPLAIN;
2015 scrarea_queue_winredraw(curarea);
2020 static void world_panel_mapto(World *wrld)
2025 block= uiNewBlock(&curarea->uiblocks, "world_panel_mapto", UI_EMBOSS, UI_HELV, curarea->win);
2026 uiNewPanelTabbed("Texture and Input", "World");
2027 if(uiNewPanel(curarea, block, "Map To", "World", 1280, 0, 318, 204)==0) return;
2029 uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2031 mtex= wrld->mtex[ wrld->texact ];
2035 mtex->texco= TEXCO_VIEW;
2038 /* TEXTURE OUTPUT */
2039 uiBlockBeginAlign(block);
2040 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");
2041 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");
2042 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");
2043 uiBlockEndAlign(block);
2045 uiBlockBeginAlign(block);
2046 uiDefButF(block, COL, B_WORLDPRV, "", 10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, "");
2047 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");
2048 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");
2049 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");
2050 uiBlockEndAlign(block);
2051 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");
2054 uiBlockBeginAlign(block);
2055 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");
2056 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");
2057 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");
2058 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");
2059 uiBlockEndAlign(block);
2061 uiBlockBeginAlign(block);
2062 uiDefButS(block, MENU, B_WORLDPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode");
2063 uiBlockEndAlign(block);
2065 uiBlockBeginAlign(block);
2066 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");
2067 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");
2068 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");
2072 static void world_panel_texture(World *wrld)
2077 int a, loos, num_mtex;
2078 char str[64], *strp;
2080 block= uiNewBlock(&curarea->uiblocks, "world_panel_texture", UI_EMBOSS, UI_HELV, curarea->win);
2081 if(uiNewPanel(curarea, block, "Texture and Input", "World", 960, 0, 318, 204)==0) return;
2083 uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2086 uiBlockSetCol(block, TH_BUT_NEUTRAL);
2087 uiBlockBeginAlign(block);
2088 num_mtex= texture_channels_num_display(wrld->mtex);
2089 for(a= 0; a<num_mtex; a++) {
2090 mtex= wrld->mtex[a];
2091 if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos);
2092 else strcpy(str, "");
2094 uiDefButS(block, ROW, REDRAWBUTSSHADING, str,10, 160-18*a, 80, 20, &(wrld->texact), 3.0, (float)a, 0, 0, "Texture channel");
2096 uiBlockEndAlign(block);
2098 mtex= wrld->mtex[ wrld->texact ];
2102 mtex->texco= TEXCO_VIEW;
2105 /* TEXTUREBLOCK SELECT */
2106 uiBlockSetCol(block, TH_BUT_SETTING2);
2107 id= (ID *)mtex->tex;
2108 IDnames_to_pupstring(&strp, NULL, "ADD NEW %x 32767", &(G.main->tex), id, &(G.buts->texnr));
2109 uiDefButS(block, MENU, B_WTEXBROWSE, strp, 100,140,20,19, &(G.buts->texnr), 0, 0, 0, 0, "Selects an existing texture or creates new");
2113 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");
2114 sprintf(str, "%d", id->us);
2115 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");
2116 uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 155,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
2118 if(wrld->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 219,140,21,19, 0, 0, 0, 0, 0, "");
2119 else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 219,140,21,19, 0, 0, 0, 0, 0, "");
2121 uiBlockSetCol(block, TH_AUTO);
2122 uiDefBut(block, BUT, B_TEXCLEARWORLD, "Clear", 122, 140, 32, 19, 0, 0, 0, 0, 0, "Erases link to texture");
2125 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");
2127 uiBlockSetCol(block, TH_AUTO);
2129 /* copy/paste/up/down */
2130 uiBlockBeginAlign(block);
2131 uiDefIconBut(block, BUT, B_WMTEXCOPY, ICON_COPYUP, 200,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
2132 uiDefIconBut(block, BUT, B_WMTEXPASTE, ICON_PASTEUP, 225,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
2133 uiDefIconBut(block, BUT, B_WMTEXMOVEUP, VICON_MOVE_UP, 250,140,25,19, 0, 0, 0, 0, 0, "Move texture channel up");
2134 uiDefIconBut(block, BUT, B_WMTEXMOVEDOWN, VICON_MOVE_DOWN, 275,140,25,19, 0, 0, 0, 0, 0, "Move texture channel down");
2137 uiBlockBeginAlign(block);
2138 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");
2139 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)");
2141 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");
2142 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");
2143 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");
2145 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");
2146 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_WORLDPRV, "OB:", 170,70,130,20, &(mtex->object), "Object name to use for mapping");
2148 uiBlockBeginAlign(block);
2149 uiDefButF(block, NUM, B_WORLDPRV, "dX", 100,40,100,19, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate");
2150 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");
2151 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");
2152 uiBlockBeginAlign(block);
2153 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");
2154 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");
2155 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");
2159 static void world_panel_mistaph(World *wrld)
2163 block= uiNewBlock(&curarea->uiblocks, "world_panel_mistaph", UI_EMBOSS, UI_HELV, curarea->win);
2164 if(uiNewPanel(curarea, block, "Mist / Stars / Physics", "World", 640, 0, 318, 204)==0) return;
2166 uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2168 #if GAMEBLENDER == 1
2169 uiDefButI(block, MENU, 1,
2171 "Physics %t|None %x0|Sumo %x2|Ode %x4 |Bullet %x5",
2173 //"Physics %t|None %x0|Sumo %x2|Bullet %x5", //disable Sumo, until too many people complain ;-)
2174 "Physics %t|None %x0|Sumo (deprecated) %x2|Bullet %x5",
2176 10,180,140,19, &wrld->physicsEngine, 0, 0, 0, 0,
2179 /* Gravitation for the game worlds */
2180 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");
2183 uiBlockSetCol(block, TH_BUT_SETTING1);
2184 uiDefButBitS(block, TOG, WO_MIST, B_WORLDPRV2,"Mist", 10,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles mist simulation");
2185 uiBlockSetCol(block, TH_AUTO);
2187 uiBlockBeginAlign(block);
2188 uiDefButS(block, ROW, B_WORLDPRV2, "Quad", 10, 90, 40, 19, &wrld->mistype, 1.0, 0.0, 0, 0, "Mist uses quadratic progression");
2189 uiDefButS(block, ROW, B_WORLDPRV2, "Lin", 50, 90, 50, 19, &wrld->mistype, 1.0, 1.0, 0, 0, "Mist uses linear progression");
2190 uiDefButS(block, ROW, B_WORLDPRV2, "Sqr", 100, 90, 50, 19, &wrld->mistype, 1.0, 2.0, 0, 0, "Mist uses inverse quadratic progression");
2191 uiBlockBeginAlign(block);
2192 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");
2193 uiDefButF(block, NUM,B_WORLDPRV2, "Dist:",10,50,140,19, &wrld->mistdist, 0.0,10000.0, 10, 00, "Specifies the depth of the mist");
2194 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");
2195 uiDefButF(block, NUMSLI, B_WORLDPRV2, "Misi ", 10,10,140,19, &(wrld->misi), 0., 1.0, 0, 0, "Sets the mist intensity");
2196 uiBlockEndAlign(block);
2198 uiBlockSetCol(block, TH_BUT_SETTING1);
2199 uiDefButBitS(block, TOG, WO_STARS, B_WORLDPRV2, "Stars",160,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles starfield generation");
2200 uiBlockSetCol(block, TH_AUTO);
2202 uiBlockBeginAlign(block);
2203 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");
2204 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");
2205 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");
2206 uiDefButF(block, NUMSLI,B_WORLDPRV2,"Colnoise:", 160,10,140,19, &(wrld->starcolnoise), 0.0, 1.0, 100, 0, "Randomizes star color");
2207 uiBlockEndAlign(block);
2211 static void world_panel_amb_occ(World *wrld)
2214 short yco=PANEL_YMAX;
2216 block= uiNewBlock(&curarea->uiblocks, "world_panel_amb_oc", UI_EMBOSS, UI_HELV, curarea->win);
2217 uiNewPanelTabbed("Mist / Stars / Physics", "World");
2218 if(uiNewPanel(curarea, block, "Amb Occ", "World", PANELX, PANELY, PANELW, PANELH)==0) return;
2219 uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2222 uiBlockSetCol(block, TH_BUT_SETTING1);
2223 uiDefButBitS(block, TOG, WO_AMB_OCC, B_REDR, "Ambient Occlusion",
2224 X2CLM1, yco-=BUTH, BUTW1, BUTH, &wrld->mode, 0, 0, 0, 0, "Toggles ambient occlusion (soft shadows)");
2225 uiBlockSetCol(block, TH_AUTO);
2227 if(!(wrld->mode & WO_AMB_OCC)) return;
2231 if(wrld->ao_gather_method == WO_AOGATHER_RAYTRACE) {
2232 uiDefButS(block, NUM, B_REDR, "Samples:",
2233 X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aosamp, 1.0, 32.0, 100, 0, "Sets the number of samples used for AO (actual number: squared)");
2237 uiDefButF(block, NUM, B_REDR, "Max Dist:",
2238 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");
2241 uiDefButS(block, NUM, B_REDR, "Passes:",
2242 X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->ao_approx_passes, 0.0, 10.0, 0, 0, "Sets the number of preprocessing passes to reduce overocclusion");
2246 uiDefButF(block, NUM, B_REDR, "Correction:",
2247 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.");
2250 uiBlockBeginAlign(block);
2251 uiDefButBitS(block, TOG, WO_AODIST, B_AO_FALLOFF, "Use Falloff",
2252 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.");
2253 if (wrld->aomode & WO_AODIST)
2254 uiDefButF(block, NUM, B_REDR, "Strength:",
2255 X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aodistfac, 0.00001, 10.0, 100, 0, "Distance attenuation factor, the higher, the 'shorter' the shadows");
2256 uiBlockEndAlign(block);
2259 yco = PANEL_YMAX - BUTH - YSPACE;
2261 uiDefButS(block, MENU, B_REDR, "Gather Method%t|Raytrace %x0|Approximate %x1",
2262 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");
2266 if(wrld->ao_gather_method == WO_AOGATHER_RAYTRACE) {
2267 uiDefButS(block, MENU, B_REDR, "Constant QMC %x2|Adaptive QMC %x1|Constant Jittered %x0",
2268 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");
2272 if (wrld->ao_samp_method == WO_AOSAMP_HALTON) {
2273 uiBlockBeginAlign(block);
2274 uiDefButF(block, NUM, B_REDR, "Threshold:",
2275 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");
2276 uiDefButF(block, NUMSLI, B_REDR, "Adapt Vec:",
2277 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.");
2278 uiBlockEndAlign(block);
2279 } else if (wrld->ao_samp_method == WO_AOSAMP_CONSTANT) {
2280 uiDefButF(block, NUMSLI, B_REDR, "Bias:",
2281 X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->aobias, 0.0, 0.5, 10, 0, "Sets bias to prevent smoothed faces to show banding (in radians)");
2285 uiBlockBeginAlign(block);
2286 uiDefButF(block, NUM, B_REDR, "Error:",
2287 X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_approx_error, 0.0001, 10.0, 0, 0, "Error tolerance (low values are slower and higher quality)");
2289 uiDefButBitS(block, TOG, WO_AOCACHE, B_REDR, "Pixel Cache",
2290 X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->aomode, 0, 0, 0, 0, "Cache AO results in pixels and interpolate over neighbouring pixels for speedup.");
2291 uiBlockEndAlign(block);
2294 yco = PANEL_YMAX - (5*BUTH+4*YSPACE);
2296 /* result mix modes */
2297 uiBlockBeginAlign(block);
2298 uiDefButS(block, ROW, B_REDR, "Add",
2299 X3CLM1, yco-=BUTH, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOADD, 0, 0, "adds light/shadows");
2300 uiDefButS(block, ROW, B_REDR, "Sub",
2301 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)");
2302 uiDefButS(block, ROW, B_REDR, "Both",
2303 X3CLM3, yco, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOADDSUB, 0, 0, "both lightens & darkens");
2304 uiBlockEndAlign(block);
2308 /* color treatment */
2309 uiBlockBeginAlign(block);
2310 uiDefButS(block, ROW, B_REDR, "Plain",
2311 X3CLM1, yco-=BUTH, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOPLAIN, 0, 0, "Plain diffuse energy (white)");
2312 uiDefButS(block, ROW, B_REDR, "Sky Color",
2313 X3CLM2, yco, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOSKYCOL, 0, 0, "Use horizon and zenith color for diffuse energy");
2314 if(wrld->ao_gather_method == WO_AOGATHER_RAYTRACE)
2315 uiDefButS(block, ROW, B_REDR, "Sky Texture",
2316 X3CLM3, yco, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOSKYTEX, 0, 0, "Does full Sky texture render for diffuse energy");
2317 uiBlockEndAlign(block);
2321 uiDefButF(block, NUMSLI, B_REDR, "Energy:",
2322 X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aoenergy, 0.01, 3.0, 100, 0, "Sets global energy scale for AO");
2325 static void world_panel_world(World *wrld)
2329 block= uiNewBlock(&curarea->uiblocks, "world_panel_world", UI_EMBOSS, UI_HELV, curarea->win);
2330 if(uiNewPanel(curarea, block, "World", "World", 320, 0, 318, 204)==0) return;
2332 uiBlockSetCol(block, TH_BUT_SETTING2);
2333 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);
2335 if(wrld==NULL) return;
2337 uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2338 uiBlockSetCol(block, TH_AUTO);
2340 uiBlockBeginAlign(block);
2341 uiDefButF(block, COL, B_WORLDPRV, "", 10,150,145,19, &wrld->horr, 0, 0, 0, B_COLHOR, "");
2342 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");
2343 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");
2344 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");
2346 uiBlockBeginAlign(block);
2347 uiDefButF(block, COL, B_WORLDPRV, "", 160,150,145,19, &wrld->zenr, 0, 0, 0, B_COLZEN, "");
2348 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");
2349 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");
2350 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");
2352 uiBlockBeginAlign(block);
2353 uiDefButF(block, COL, B_WORLDPRV, "", 10,70,145,19, &wrld->ambr, 0, 0, 0, 0, "");
2354 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");
2355 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");
2356 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");
2358 uiBlockBeginAlign(block);
2359 uiBlockSetCol(block, TH_BUT_SETTING1);
2360 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");
2361 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");
2366 static void world_panel_preview(World *wrld)
2370 /* name "Preview" is abused to detect previewrender offset panel */
2371 block= uiNewBlock(&curarea->uiblocks, "world_panel_preview", UI_EMBOSS, UI_HELV, curarea->win);
2372 if(uiNewPanel(curarea, block, "Preview", "World", 0, 0, 318, 204)==0) return;
2374 if(wrld==NULL) return;
2376 uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2378 uiBlockSetDrawExtraFunc(block, BIF_previewdraw);
2380 // label to force a boundbox for buttons not to be centered
2381 uiDefBut(block, LABEL, 0, " ", 20,20,10,10, 0, 0, 0, 0, 0, "");
2383 uiBlockBeginAlign(block);
2384 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");
2385 uiDefButBitS(block, TOG,WO_SKYPAPER, B_WORLDPRV,"Paper", 220,150,100,25, &wrld->skytype, 0, 0, 0, 0, "Flattens blend or texture coordinates");
2386 /*if (wrld->skytype & WO_SKYBLEND) {*/ /* In some (rare?) cases its possible to use this, leave this out for now */
2387 uiDefButBitS(block, TOG, WO_SKYREAL, B_WORLDPRV,"Real", 220,125,100,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with a real horizon");
2389 uiBlockEndAlign(block);
2393 /* ************************ LAMP *************************** */
2395 void do_lampbuts(unsigned short event)
2397 static short mtexcopied=0;
2398 static MTex mtexcopybuf;
2405 BIF_preview_changed(ID_LA);
2406 allqueue(REDRAWVIEW3D, 0);
2407 allqueue(REDRAWBUTSSHADING, 0);
2409 case B_TEXCLEARLAMP:
2410 la= G.buts->lockpoin;
2411 mtex= la->mtex[ la->texact ];
2413 if(mtex->tex) mtex->tex->id.us--;
2415 la->mtex[ la->texact ]= 0;
2416 BIF_undo_push("Unlink world texture");
2417 allqueue(REDRAWBUTSSHADING, 0);
2418 allqueue(REDRAWOOPS, 0);
2419 BIF_preview_changed(ID_LA);
2423 la= G.buts->lockpoin;
2424 la->bufsize = la->bufsize&=(~15);
2425 allqueue(REDRAWBUTSSHADING, 0);
2426 allqueue(REDRAWOOPS, 0);
2429 la= G.buts->lockpoin;
2430 la->mode &= ~LA_SHAD_RAY;
2431 allqueue(REDRAWBUTSSHADING, 0);
2432 allqueue(REDRAWVIEW3D, 0);
2435 la= G.buts->lockpoin;
2436 la->mode &= ~LA_SHAD_BUF;
2437 /* yafray: 'softlight' uses it's own shadbuf. flag.
2438 Must be cleared here too when switching from ray shadow */
2439 la->mode &= ~LA_YF_SOFT;
2440 allqueue(REDRAWBUTSSHADING, 0);
2441 allqueue(REDRAWVIEW3D, 0);
2444 la= G.buts->lockpoin;
2445 if(la && la->mtex[(int)la->texact] ) {
2446 mtex= la->mtex[(int)la->texact];
2447 if(mtex->tex==NULL) {
2448 error("No texture available");
2451 memcpy(&mtexcopybuf, la->mtex[(int)la->texact], sizeof(MTex));
2457 la= G.buts->lockpoin;
2458 if(la && mtexcopied && mtexcopybuf.tex) {
2459 if(la->mtex[(int)la->texact]==NULL )
2460 la->mtex[(int)la->texact]= MEM_mallocN(sizeof(MTex), "mtex");
2461 else if(la->mtex[(int)la->texact]->tex)
2462 la->mtex[(int)la->texact]->tex->id.us--;
2464 memcpy(la->mtex[(int)la->texact], &mtexcopybuf, sizeof(MTex));
2466 id_us_plus((ID *)mtexcopybuf.tex);
2467 BIF_undo_push("Paste mapping settings");
2468 BIF_preview_changed(ID_LA);
2469 scrarea_queue_winredraw(curarea);
2473 la= G.buts->lockpoin;
2474 if(la && (int)la->texact > 0) {
2475 mtexswap = la->mtex[(int)la->texact];
2476 la->mtex[(int)la->texact] = la->mtex[((int)la->texact)-1];
2477 la->mtex[((int)la->texact)-1] = mtexswap;
2479 allqueue(REDRAWBUTSSHADING, 0);
2482 case B_LMTEXMOVEDOWN:
2483 la= G.buts->lockpoin;
2484 if(la && (int)la->texact < MAX_MTEX-1) {
2485 mtexswap = la->mtex[(int)la->texact];
2486 la->mtex[(int)la->texact] = la->mtex[((int)la->texact)+1];
2487 la->mtex[((int)la->texact)+1] = mtexswap;
2489 allqueue(REDRAWBUTSSHADING, 0);
2492 case B_LFALLOFFCHANGED:
2493 la= G.buts->lockpoin;
2494 curvemapping_changed(la->curfalloff, 1);
2495 BIF_undo_push("Edit Lamp falloff curve");
2496 BIF_preview_changed(ID_LA);
2497 scrarea_queue_winredraw(curarea);
2504 static void lamp_panel_mapto(Object *ob, Lamp *la)
2509 block= uiNewBlock(&curarea->uiblocks, "lamp_panel_mapto", UI_EMBOSS, UI_HELV, curarea->win);
2510 uiNewPanelTabbed("Texture and Input", "Lamp");
2511 if(uiNewPanel(curarea, block, "Map To", "Lamp", 1280, 0, 318, 204)==0) return;
2513 uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2515 mtex= la->mtex[ la->texact ];
2519 mtex->texco= TEXCO_VIEW;
2522 /* TEXTURE OUTPUT */
2523 uiBlockBeginAlign(block);
2524 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");
2525 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");
2526 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");
2527 uiBlockEndAlign(block);
2529 uiBlockBeginAlign(block);
2530 uiDefButF(block, COL, B_LAMPPRV, "", 10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, "");
2531 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");
2532 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");
2533 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");
2534 uiBlockEndAlign(block);
2535 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");
2538 uiBlockBeginAlign(block);
2539 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");
2540 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");
2541 uiBlockEndAlign(block);
2543 uiBlockBeginAlign(block);
2544 uiDefButS(block, MENU, B_LAMPPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode");
2545 uiBlockEndAlign(block);
2547 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");
2552 static void lamp_panel_texture(Object *ob, Lamp *la)
2557 int a, loos, num_mtex;
2558 char *strp, str[64];
2560 block= uiNewBlock(&curarea->uiblocks, "lamp_panel_texture", UI_EMBOSS, UI_HELV, curarea->win);
2561 if(uiNewPanel(curarea, block, "Texture and Input", "Lamp", 960, 0, 318, 204)==0) return;
2563 uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2566 uiBlockSetCol(block, TH_BUT_NEUTRAL);
2567 uiBlockBeginAlign(block);
2568 num_mtex= texture_channels_num_display(la->mtex);
2569 for(a= 0; a<num_mtex; a++) {
2571 if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos);
2572 else strcpy(str, "");
2574 uiDefButS(block, ROW, B_REDR, str, 10, 160-18*a, 80, 20, &(la->texact), 3.0, (float)a, 0, 0, "");
2576 uiBlockEndAlign(block);
2578 mtex= la->mtex[ la->texact ];
2582 mtex->texco= TEXCO_VIEW;
2585 /* TEXTUREBLOK SELECT */
2586 uiBlockSetCol(block, TH_BUT_SETTING2);
2587 id= (ID *)mtex->tex;
2588 IDnames_to_pupstring(&strp, NULL, "ADD NEW %x 32767", &(G.main->tex), id, &(G.buts->texnr));
2590 /* doesnt work, because lockpoin points to lamp, not to texture */
2591 uiDefButS(block, MENU, B_LTEXBROWSE, strp, 100,140,20,19, &(G.buts->texnr), 0, 0, 0, 0, "Selects an existing texture or creates new");
2595 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");
2596 sprintf(str, "%d", id->us);
2597 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");
2598 uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 177,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
2600 if(la->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 219,140,21,19, 0, 0, 0, 0, 0, "");
2601 else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 219,140,21,19, 0, 0, 0, 0, 0, "");
2603 uiBlockSetCol(block, TH_AUTO);
2604 uiDefBut(block, BUT, B_TEXCLEARLAMP, "Clear", 122, 140, 32, 19, 0, 0, 0, 0, 0, "Erases link to texture");
2607 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");
2609 /* copy/paste/up/down */
2610 uiBlockBeginAlign(block);
2611 uiDefIconBut(block, BUT, B_LMTEXCOPY, ICON_COPYUP, 200,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
2612 uiDefIconBut(block, BUT, B_LMTEXPASTE, ICON_PASTEUP, 225,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
2613 uiDefIconBut(block, BUT, B_LMTEXMOVEUP, VICON_MOVE_UP, 250,140,25,19, 0, 0, 0, 0, 0, "Move texture channel up");
2614 uiDefIconBut(block, BUT, B_LMTEXMOVEDOWN, VICON_MOVE_DOWN, 275,140,25,19, 0, 0, 0, 0, 0, "Move texture channel down");
2618 uiBlockSetCol(block, TH_AUTO);
2619 uiBlockBeginAlign(block);
2620 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");
2621 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");
2622 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");
2623 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_LAMPPRV, "", 100,90,200,20, &(mtex->object), "");
2625 uiBlockBeginAlign(block);
2626 uiDefButF(block, NUM, B_LAMPPRV, "dX", 100,50,100,18, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate");
2627 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");
2628 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");
2629 uiBlockBeginAlign(block);
2630 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");
2631 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");
2632 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");
2633 uiBlockEndAlign(block);
2636 static void lamp_panel_spot(Object *ob, Lamp *la)
2641 block= uiNewBlock(&curarea->uiblocks, "lamp_panel_spot", UI_EMBOSS, UI_HELV, curarea->win);
2642 if(uiNewPanel(curarea, block, "Shadow and Spot", "Lamp", 640, 0, 318, 224)==0) return;
2644 /* hemis and ray shadow dont work at all... */
2645 /* yafray: ignore photonlight as well */
2646 if ((la->type==LA_HEMI) || (la->type==LA_YF_PHOTON)) return;
2648 if(G.vd) grid= G.vd->grid;
2649 if(grid<1.0) grid= 1.0;
2651 uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2653 uiBlockSetCol(block, TH_BUT_SETTING1);
2654 uiBlockBeginAlign(block);
2655 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");
2656 if(la->type==LA_SPOT) {
2657 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");
2658 if(la->mode & LA_SHAD_BUF) {
2659 char *tip= "Regular buffer type";
2660 if(la->buftype==LA_SHADBUF_IRREGULAR)
2661 tip= "Irregular buffer produces sharp shadow always, but it doesn't show up for raytracing";
2662 else if(la->buftype==LA_SHADBUF_HALFWAY)
2663 tip= "Regular buffer, averaging the closest and 2nd closest Z value for reducing biasing";
2665 uiDefButC(block, MENU, B_REDR, "Classical %x0|Classic-Halfway %x2|Irregular %x1", 10,140,80,19,&la->buftype, 0, 0, 0, 0, tip);
2668 uiBlockEndAlign(block);
2670 uiBlockBeginAlign(block);
2671 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");
2672 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");
2673 uiBlockEndAlign(block);
2675 if(la->type==LA_SPOT) {
2676 uiBlockBeginAlign(block);
2677 uiDefButBitI(block, TOG, LA_SQUARE, B_LAMPREDRAW,"Square", 10,60,80,19,&la->mode, 0, 0, 0, 0, "Sets square spotbundles");
2678 uiDefButBitI(block, TOG, LA_HALO, B_LAMPREDRAW,"Halo", 10,40,80,19,&la->mode, 0, 0, 0, 0, "Renders spotlight with a volumetric halo");
2680 uiBlockBeginAlign(block);
2681 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");
2682 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");
2683 uiBlockEndAlign(block);
2685 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");
2687 if(la->mode & LA_SHAD_BUF) {
2688 if(ELEM(la->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY)) {
2689 uiBlockBeginAlign(block);
2690 uiDefButS(block, NUM,B_SBUFF,"ShadowBufferSize:", 100,110,200,19, &la->bufsize,512,10240, 0, 0, "Sets the size of the shadow buffer to nearest multiple of 16");
2691 uiDefButS(block, ROW,B_NOP, "Box", 100,90,65,19, &la->filtertype, 0.0, LA_SHADBUF_BOX, 0, 0, "Apply Box filter for shadowbuffer samples");
2692 uiDefButS(block, ROW,B_NOP, "Tent", 165,90,65,19, &la->filtertype, 0.0, LA_SHADBUF_TENT, 0, 0, "Apply Tent filter for shadowbuffer samples");
2693 uiDefButS(block, ROW,B_NOP, "Gauss", 230,90,70,19, &la->filtertype, 0.0, LA_SHADBUF_GAUSS, 0, 0, "Apply Gauss filter for shadowbuffer samples");
2695 uiBlockBeginAlign(block);
2696 uiDefButS(block, ROW,B_NOP,"SampleBuffers: 1", 100,-15,140,19, &la->buffers, 1.0, 1.0, 0, 0, "Only one lampbuffer rendered");
2697 uiDefButS(block, ROW,B_NOP,"4", 240,-15,30,19, &la->buffers, 1.0, 4.0, 0, 0, "Renders 4 lampbuffers for better AA, this quadruples memory usage");
2698 uiDefButS(block, ROW,B_NOP,"9", 270,-15,30,19, &la->buffers, 1.0, 9.0, 0, 0, "Renders 9 lampbuffers for better AA, this uses nine times more memory");
2700 uiBlockBeginAlign(block);
2701 uiDefButS(block, NUM,B_LAMPREDRAW,"Samples:", 100,60,100,19, &la->samp,1.0,16.0, 0, 0, "Sets the number of shadow map samples");
2702 uiDefButS(block, NUM,B_NOP,"Halo step:", 200,60,100,19, &la->shadhalostep, 0.0, 12.0, 0, 0, "Sets the volumetric halo sampling frequency");
2703 uiDefButF(block, NUM,B_LAMPREDRAW,"Bias:", 100,40,100,19, &la->bias, 0.001, 5.0, 1, 0, "Sets the shadow map sampling bias");
2704 uiDefButF(block, NUM,B_LAMPREDRAW,"Soft:", 200,40,100,19, &la->soft,1.0,100.0, 100, 0, "Sets the size of the shadow sample area");
2706 else { /* LA_SHADBUF_IRREGULAR */
2707 uiDefButF(block, NUM,B_LAMPREDRAW,"Bias:", 100,40,100,19, &la->bias, 0.001, 5.0, 1, 0, "Sets the shadow map sampling bias");
2710 uiBlockBeginAlign(block);
2711 uiDefIconButBitC(block, TOG, LA_SHADBUF_AUTO_START, B_REDR, ICON_AUTO, 10, 10, 25, 19, &la->bufflag, 0.0, 0.0, 0, 0, "Automatic calculation of clipping-start, based on visible vertices");
2712 if(la->bufflag & LA_SHADBUF_AUTO_START)
2713 uiDefBut(block, LABEL, B_NOP, "ClipSta: Auto", 35,10,115,19, NULL, 0, 0, 0, 0, "");
2715 uiDefButF(block, NUM,REDRAWVIEW3D,"ClipSta:", 35,10,115,19, &la->clipsta, 0.1*grid,1000.0*grid, 10, 0, "Sets the shadow map clip start: objects closer will not generate shadows");
2716 uiDefIconButBitC(block, TOG, LA_SHADBUF_AUTO_END, B_REDR, ICON_AUTO, 160, 10, 25, 19, &la->bufflag, 0.0, 0.0, 0, 0, "Automatic calculation of clipping-end, based on visible vertices");
2717 if(la->bufflag & LA_SHADBUF_AUTO_END)
2718 uiDefBut(block, LABEL,B_NOP, "ClipEnd: Auto", 185,10,115,19, NULL, 0, 0, 0, 0, "");
2720 uiDefButF(block, NUM,REDRAWVIEW3D,"ClipEnd:", 185,10,115,19,&la->clipend, 1.0, 5000.0*grid, 100, 0, "Sets the shadow map clip end beyond which objects will not generate shadows");
2721 uiBlockEndAlign(block);
2725 if(ELEM4(la->type, LA_AREA, LA_SPOT, LA_SUN, LA_LOCAL) && (la->mode & LA_SHAD_RAY)) {
2727 if (ELEM3(la->type, LA_SPOT, LA_SUN, LA_LOCAL)) {
2728 if (la->ray_samp_method == LA_SAMP_CONSTANT) la->ray_samp_method = LA_SAMP_HALTON;
2730 uiDefButS(block, MENU, B_REDR, "Adaptive QMC %x1|Constant QMC %x2",
2731 100,110,200,19, &la->ray_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Adaptive QMC is fastest, Constant QMC is less noisy but slower");
2733 uiDefButF(block, NUM,B_LAMPREDRAW,"Soft Size", 100,80,200,19, &la->area_size, 0.01, 100.0, 10, 0, "Area light size, doesn't affect energy amount");
2735 uiDefButS(block, NUM,0,"Samples:", 100,60,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
2736 if (la->ray_samp_method == LA_SAMP_HALTON)
2737 uiDefButF(block, NUM,0,"Threshold:", 100,40,200,19, &la->adapt_thresh, 0.0, 1.0, 100, 0, "Threshold for adaptive sampling, to control what level is considered already in shadow");
2739 else if (la->type == LA_AREA) {
2740 uiDefButS(block, MENU, B_REDR, "Adaptive QMC %x1|Constant QMC %x2|Constant Jittered %x0",
2741 100,180,200,19, &la->ray_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Adaptive QMC is fastest");
2743 if(la->area_shape==LA_AREA_SQUARE)
2744 uiDefButS(block, NUM,0,"Samples:", 100,150,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
2745 else if(la->area_shape==LA_AREA_CUBE)
2746 uiDefButS(block, NUM,0,"Samples:", 100,130,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp x samp)");
2748 if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)) {
2749 uiDefButS(block, NUM,0,"SamplesX:", 100,150,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of X samples taken extra");
2750 uiDefButS(block, NUM,0,"SamplesY:", 100,130,200,19, &la->ray_sampy, 1.0, 16.0, 100, 0, "Sets the amount of Y samples taken extra");
2751 if(la->area_shape==LA_AREA_BOX)
2752 uiDefButS(block, NUM,0,"SamplesZ:", 100,110,200,19, &la->ray_sampz, 1.0, 8.0, 100, 0, "Sets the amount of Z samples taken extra");
2755 if (la->ray_samp_method == LA_SAMP_CONSTANT) {
2756 uiBlockBeginAlign(block);
2757 uiDefButBitS(block, TOG, LA_SAMP_UMBRA, 0,"Umbra", 100,90,200,19,&la->ray_samp_type, 0, 0, 0, 0, "Emphasis parts that are fully shadowed");
2758 uiDefButBitS(block, TOG, LA_SAMP_DITHER, 0,"Dither", 100,70,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use 2x2 dithering for sampling");
2759 uiDefButBitS(block, TOG, LA_SAMP_JITTER, 0,"Noise", 200,70,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use noise for sampling");
2760 } else if (la->ray_samp_method == LA_SAMP_HALTON) {
2761 uiDefButF(block, NUM,0,"Threshold:", 100,90,200,19, &la->adapt_thresh, 0.0, 1.0, 100, 0, "Threshold for adaptive sampling, to control what level is considered already in shadow");
2767 else uiDefBut(block, LABEL,0," ", 100,180,200,19,NULL, 0, 0, 0, 0, "");
2771 /* yafray: adaptation of lamp_panel_spot above with yafray specific parameters */
2772 static void lamp_panel_yafray(Object *ob, Lamp *la)
2776 block= uiNewBlock(&curarea->uiblocks, "lamp_panel_yafray", UI_EMBOSS, UI_HELV, curarea->win);
2777 if(uiNewPanel(curarea, block, "Yafray: Shadow and Photons", "Lamp", 640, 0, 318, 204)==0) return;
2779 /* hemis not used in yafray */
2780 if(la->type==LA_HEMI) return;
2782 uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2784 /* photonlight params */
2785 if (la->type==LA_YF_PHOTON) {
2786 uiBlockSetCol(block, TH_BUT_SETTING1);
2787 uiDefButBitS(block, TOG, 1, B_DIFF,"Use QMC",10,180,80,19,&la->YF_useqmc, 0, 0, 0, 0, "Use QMC sampling (sometimes visible patterns)");
2788 uiBlockSetCol(block, TH_AUTO);
2789 uiDefButF(block, NUMSLI,B_LAMPREDRAW,"Angle ", 100,180,200,19,&la->spotsize, 1.0, 180.0, 0, 0, "Sets the angle of the photonlight beam in degrees");
2790 uiDefButI(block, NUM,B_DIFF,"photons:", 10,150,290,19, &la->YF_numphotons, 10000, 100000000, 0, 0, "Maximum number of photons to shoot");
2791 uiDefButI(block, NUM,B_DIFF,"search:", 10,130,290,19, &la->YF_numsearch, 100, 1000, 0, 0, "Number of photons to mix (blur)");
2792 uiDefButS(block, NUM,B_DIFF,"depth:", 10,100,290,19, &la->YF_phdepth, 1, 100, 0, 0, "Maximum caustic bounce depth");
2793 uiDefButF(block, NUM,B_DIFF,"Blur:", 10,70,290,19, &la->YF_causticblur, 0.01, 1.0, 1, 0, "Amount of caustics blurring (also depends on search)");
2797 uiBlockSetCol(block, TH_BUT_SETTING1);
2799 /* in yafray arealights always cast shadows, so ray shadow flag not needed */
2800 /* ray shadow also not used when halo for spot enabled */
2801 if ((la->type!=LA_AREA) && (!((la->type==LA_SPOT) && (la->mode & LA_HALO))))
2802 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");
2804 /* in yafray the regular lamp can use shadowbuffers (softlight), used by spot with halo as well */
2805 /* to prevent clash with blender shadowbuf flag, a special flag is used for yafray */
2806 if (la->type==LA_LOCAL) {
2807 uiDefButBitI(block, TOG, LA_YF_SOFT, B_SHADBUF, "Buf.Shadow",10,160,80,19,&la->mode, 0, 0, 0, 0, "Lets light produce shadows using shadow buffer");
2808 uiDefButF(block, NUM, B_DIFF, "GloInt:", 100,155,200,19, &la->YF_glowint, 0.0, 1.0, 1, 0, "Sets light glow intensity, 0 is off");
2809 uiDefButF(block, NUM, B_DIFF, "GloOfs:", 100,135,100,19, &la->YF_glowofs, 0.0, 2.0, 1, 0, "Sets light glow offset, the higher, the less 'peaked' the glow");
2810 uiDefButS(block, NUM, B_DIFF, "GlowType:", 200,135,100,19, &la->YF_glowtype, 0, 1, 1, 0, "Sets light glow type");
2813 /* shadowbuffers used only for 'softlight' & spotlight with halo */
2814 if (((la->type==LA_LOCAL) && (la->mode & LA_YF_SOFT)) || ((la->type==LA_SPOT) && (la->mode & LA_HALO))) {
2815 /* Shadow buffer size can be anything in yafray, but reasonable minimum is 128 */
2816 /* Maximum is 1024, since zbuf in yafray is float, no multiple of 16 restriction */
2817 uiDefButS(block, NUM,B_DIFF,"ShadowBufferSize:", 100,110,200,19, &la->YF_bufsize, 128, 1024, 0, 0, "Sets the size of the shadow buffer");
2819 /* samples & halostep params only used for spotlight with halo */
2820 if ((la->type==LA_SPOT) && (la->mode & LA_HALO)) {
2821 uiDefButS(block, NUM,B_DIFF,"Samples:", 100,30,100,19, &la->samp,1.0,16.0, 0, 0, "Sets the number of shadow map samples");
2822 uiDefButS(block, NUM,B_DIFF,"Halo step:", 200,30,100,19, &la->shadhalostep, 0.0, 12.0, 0, 0, "Sets the volumetric halo sampling frequency");
2824 uiDefButF(block, NUM,B_DIFF,"Bias:", 100,10,100,19, &la->bias, 0.01, 5.0, 1, 0, "Sets the shadow map sampling bias");
2825 /* here can use the Blender soft param, since for yafray it has the same function as in Blender */
2826 uiDefButF(block, NUM,B_DIFF,"Soft:", 200,10,100,19, &la->soft,1.0,100.0, 100, 0, "Sets the size of the shadow sample area");
2828 else if ((la->type==LA_LOCAL) && (la->mode & LA_SHAD_RAY)) {
2829 /* for spherelight, light radius */
2830 uiDefButF(block, NUM,B_DIFF,"Radius:", 200,10,100,19, &la->YF_ltradius, 0.0,100.0, 100, 0, "Sets the radius of the lightsource, 0 is same as pointlight");
2833 if (la->type==LA_SPOT) {
2835 uiDefButBitI(block, TOG, LA_HALO, B_LAMPREDRAW,"Halo", 10,50,80,19,&la->mode, 0, 0, 0, 0, "Renders spotlight with a volumetric halo");
2837 uiBlockSetCol(block, TH_AUTO);
2838 uiBlockBeginAlign(block);
2839 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");
2840 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");
2841 uiBlockEndAlign(block);
2843 if (la->mode & LA_HALO) uiDefButF(block, NUMSLI,0,"HaloInt ", 100,135,200,19,&la->haint, 0.0, 5.0, 0, 0, "Sets the intensity of the spotlight halo");
2845 else if ((la->type==LA_AREA) || ((la->type==LA_LOCAL) && (la->mode & LA_SHAD_RAY))) {
2846 /* area samples param also used for 'spherelight' */
2847 uiBlockBeginAlign(block);
2848 uiBlockSetCol(block, TH_AUTO);
2850 uiDefButS(block, NUM,B_DIFF,"Samples:", 100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
2852 /* shadow sampling types not used in yafray, removed */
2854 else uiDefBut(block, LABEL,0," ", 100,180,200,19,NULL, 0, 0, 0, 0, "");
2858 static void lamp_panel_atmosphere(Object *ob, Lamp *la)
2862 block= uiNewBlock(&curarea->uiblocks, "lamp_panel_atm", UI_EMBOSS, UI_HELV, curarea->win);
2863 uiNewPanelTabbed("Shadow and Spot", "Lamp");
2864 if(uiNewPanel(curarea, block, "Sky/Atmosphere", "Lamp", 3*PANELX, PANELY, PANELW, PANELH)==0) return;
2866 uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2868 uiDefButBitS(block, TOG, LA_SUN_EFFECT_SKY, B_LAMPPRV, "Sky", 10,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on sky.");
2869 uiDefButBitS(block, TOG, LA_SUN_EFFECT_AP, REDRAWVIEW3D, "Atmosphere", 20+BUTW2,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on atmosphere.");
2871 if(la->sun_effect_type & (LA_SUN_EFFECT_SKY|LA_SUN_EFFECT_AP)){
2872 uiDefButF(block, NUM, B_LAMPREDRAW, "Turbidity:",10,180,BUTW1,19, &(la->atm_turbidity), 1.000f, 30.0f, 1, 0, "Sky Turbidity");
2876 if(la->sun_effect_type & LA_SUN_EFFECT_SKY)
2878 uiBlockBeginAlign(block);
2879 uiDefButS(block, MENU, B_LAMPPRV, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Overlay %x9|Divide %x5|Difference %x6|Darken %x7|Lighten %x8|Dodge %x10|Burn %x11|Color %x15|Value %x14|Saturation %x13|Hue %x12",
2881 &la->skyblendtype, 0.0f, 0.0f, 0, 0, "Blend type for how it gets combined with sky");
2882 uiDefButF(block, NUM, B_LAMPPRV, "",10+BUTW2/2,y-25,BUTW2/2,19, &(la->skyblendfac), 0.0f, 1.0f, 10, 0, "Sets blending factor with sky color");
2883 uiBlockEndAlign(block);
2886 uiDefButF(block, NUM, B_LAMPPRV, "Hor.Bright:",10,y-25,BUTW2,19, &(la->horizon_brightness), 0.00f, 20.00f, 10, 0, "Sets horizon brightness.");
2887 uiDefButF(block, NUM, B_LAMPPRV, "Hor.Spread:",10,y-50,BUTW2,19, &(la->spread), 0.00f, 10.00f, 10, 0, "Sets horizon spread.");
2888 uiDefButF(block, NUM, B_LAMPPRV, "Sun Bright:",10,y-75,BUTW2,19, &(la->sun_brightness), 0.00f, 10.0f, 10, 0, "Sets sun brightness.");
2889 uiDefButF(block, NUM, B_LAMPPRV, "Sun Size:",10,y-100,BUTW2,19, &(la->sun_size), 0.00f, 10.00f, 10, 0, "Sets sun size.");
2890 uiDefButF(block, NUM, B_LAMPPRV, "Back Light:",10,y-125,BUTW2,19, &(la->backscattered_light), -1.00f, 1.00f, 10, 0, "Sets backscatter light.");
2893 if(la->sun_effect_type & LA_SUN_EFFECT_AP)
2895 uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Intens.:",20+BUTW2,y-25,BUTW2,19, &(la->sun_intensity), 0.00f, 10.00f, 10, 0, "Sets sun intensity.");
2896 uiDefButF(block, NUM, B_LAMPREDRAW, "Inscattering:",20+BUTW2,y-50,BUTW2,19, &(la->atm_inscattering_factor), 0.00f, 1.00f, 10, 0, "In Scattering Contribution Factor.");
2897 uiDefButF(block, NUM, B_LAMPREDRAW, "Extinction:",20+BUTW2,y-75,BUTW2,19, &(la->atm_extinction_factor), 0.00f, 1.00f, 10, 0, "Extinction Scattering Contribution Factor.");
2898 uiDefButF(block, NUM, B_LAMPREDRAW, "Distance:",20+BUTW2,y-100,BUTW2,19, &(la->atm_distance_factor), 0.000f, 500.0f, 10, 0, "Scale blender distance to real distance.");
2902 static void lamp_panel_falloff(Object *ob, Lamp *la)
2906 short yco=PANEL_YMAX;
2909 /* name "Preview" is abused to detect previewrender offset panel */
2910 block= uiNewBlock(&curarea->uiblocks, "lamp_panel_falloff", UI_EMBOSS, UI_HELV, curarea->win);
2911 uiNewPanelTabbed("Lamp", "Lamp");
2912 if(uiNewPanel(curarea, block, "Falloff Curve", "Lamp", PANELX, PANELY, PANELW, PANELH)==0) return;
2914 if(G.vd) grid= G.vd->grid;
2915 if(grid<1.0) grid= 1.0;
2917 uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2919 BLI_init_rctf(&butr, 10.0, 310.0, 10.0, (float)yco);
2920 curvemap_buttons(block, la->curfalloff, 's', B_LFALLOFFCHANGED, B_LAMPREDRAW, &butr);
2924 static void lamp_panel_lamp(Object *ob, Lamp *la)
2930 block= uiNewBlock(&curarea->uiblocks, "lamp_panel_lamp", UI_EMBOSS, UI_HELV, curarea->win);
2931 if(uiNewPanel(curarea, block, "Lamp", "Lamp", 320, 0, 318, 204)==0) return;
2933 if(G.vd) grid= G.vd->grid;
2934 if(grid<1.0) grid= 1.0;
2936 uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
2938 uiBlockSetCol(block, TH_BUT_SETTING2);
2939 xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, ID_LA, 0, (ID *)la, (ID *)ob, &(G.buts->menunr),&