merge 17206:17211
[blender-staging.git] / source / blender / blenkernel / intern / material.c
1
2 /*  material.c
3  *
4  * 
5  * $Id$
6  *
7  * ***** BEGIN GPL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL LICENSE BLOCK *****
31  */
32
33 #include <string.h>
34 #include <math.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "DNA_curve_types.h"
39 #include "DNA_material_types.h"
40 #include "DNA_mesh_types.h"
41 #include "DNA_meta_types.h"
42 #include "DNA_node_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_texture_types.h"
46
47 #include "BLI_blenlib.h"
48 #include "BLI_arithb.h"         
49
50 #include "BKE_bad_level_calls.h"
51 #include "BKE_blender.h"
52 #include "BKE_displist.h"
53 #include "BKE_global.h"
54 #include "BKE_icons.h"
55 #include "BKE_library.h"
56 #include "BKE_main.h"
57 #include "BKE_material.h"
58 #include "BKE_mesh.h"
59 #include "BKE_node.h"
60 #include "BKE_utildefines.h"
61
62 #ifndef DISABLE_PYTHON
63 #include "BPY_extern.h"
64 #endif
65
66 #include "GPU_material.h"
67
68 /* used in UI and render */
69 Material defmaterial;
70
71 /* called on startup, creator.c */
72 void init_def_material(void)
73 {
74         init_material(&defmaterial);
75 }
76
77 /* not material itself */
78 void free_material(Material *ma)
79 {
80         MTex *mtex;
81         int a;
82
83 #ifndef DISABLE_PYTHON
84         BPY_free_scriptlink(&ma->scriptlink);
85 #endif
86         
87         for(a=0; a<MAX_MTEX; a++) {
88                 mtex= ma->mtex[a];
89                 if(mtex && mtex->tex) mtex->tex->id.us--;
90                 if(mtex) MEM_freeN(mtex);
91         }
92         
93         if(ma->ramp_col) MEM_freeN(ma->ramp_col);
94         if(ma->ramp_spec) MEM_freeN(ma->ramp_spec);
95         
96         BKE_previewimg_free(&ma->preview);
97         BKE_icon_delete((struct ID*)ma);
98         ma->id.icon_id = 0;
99         
100         /* is no lib link block, but material extension */
101         if(ma->nodetree) {
102                 ntreeFreeTree(ma->nodetree);
103                 MEM_freeN(ma->nodetree);
104         }
105
106         if(ma->gpumaterial.first)
107                 GPU_material_free(ma);
108 }
109
110 void init_material(Material *ma)
111 {
112         ma->r= ma->g= ma->b= ma->ref= 0.8;
113         ma->specr= ma->specg= ma->specb= 1.0;
114         ma->mirr= ma->mirg= ma->mirb= 1.0;
115         ma->spectra= 1.0;
116         ma->amb= 0.5;
117         ma->alpha= 1.0;
118         ma->spec= ma->hasize= 0.5;
119         ma->har= 50;
120         ma->starc= ma->ringc= 4;
121         ma->linec= 12;
122         ma->flarec= 1;
123         ma->flaresize= ma->subsize= 1.0;
124         ma->flareboost= 1;
125         ma->seed2= 6;
126         ma->friction= 0.5;
127         ma->refrac= 4.0;
128         ma->roughness= 0.5;
129         ma->param[0]= 0.5;
130         ma->param[1]= 0.1;
131         ma->param[2]= 0.5;
132         ma->param[3]= 0.1;
133         ma->rms= 0.1;
134         ma->darkness= 1.0;      
135         
136         ma->strand_sta= ma->strand_end= 1.0f;
137         
138         ma->ang= 1.0;
139         ma->ray_depth= 2;
140         ma->ray_depth_tra= 2;
141         ma->fresnel_mir= 0.0;
142         ma->fresnel_tra= 0.0;
143         ma->fresnel_tra_i= 1.25;
144         ma->fresnel_mir_i= 1.25;
145         ma->tx_limit= 0.0;
146         ma->tx_falloff= 1.0;
147         ma->shad_alpha= 1.0f;
148         
149         ma->gloss_mir = ma->gloss_tra= 1.0;
150         ma->samp_gloss_mir = ma->samp_gloss_tra= 18;
151         ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005;
152         ma->dist_mir = 0.0;
153         ma->fadeto_mir = MA_RAYMIR_FADETOSKY;
154         
155         ma->rampfac_col= 1.0;
156         ma->rampfac_spec= 1.0;
157         ma->pr_lamp= 3;                 /* two lamps, is bits */
158         ma->pr_type= MA_SPHERE;
159
160         ma->sss_radius[0]= 1.0f;
161         ma->sss_radius[1]= 1.0f;
162         ma->sss_radius[2]= 1.0f;
163         ma->sss_col[0]= 0.8f;
164         ma->sss_col[1]= 0.8f;
165         ma->sss_col[2]= 0.8f;
166         ma->sss_error= 0.05f;
167         ma->sss_scale= 0.1f;
168         ma->sss_ior= 1.3f;
169         ma->sss_colfac= 1.0f;
170         ma->sss_texfac= 0.0f;
171         ma->sss_front= 1.0f;
172         ma->sss_back= 1.0f;
173
174         ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_RAYBIAS|MA_TANGENT_STR;
175
176         ma->preview = NULL;
177 }
178
179 Material *add_material(char *name)
180 {
181         Material *ma;
182
183         ma= alloc_libblock(&G.main->mat, ID_MA, name);
184         
185         init_material(ma);
186         
187         return ma;      
188 }
189
190 Material *copy_material(Material *ma)
191 {
192         Material *man;
193         int a;
194         
195         man= copy_libblock(ma);
196         
197         id_us_plus((ID *)man->ipo);
198         id_us_plus((ID *)man->group);
199         
200         
201         for(a=0; a<MAX_MTEX; a++) {
202                 if(ma->mtex[a]) {
203                         man->mtex[a]= MEM_mallocN(sizeof(MTex), "copymaterial");
204                         memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex));
205                         id_us_plus((ID *)man->mtex[a]->tex);
206                 }
207         }
208
209 #ifndef DISABLE_PYTHON  
210         BPY_copy_scriptlink(&ma->scriptlink);
211 #endif
212         
213         if(ma->ramp_col) man->ramp_col= MEM_dupallocN(ma->ramp_col);
214         if(ma->ramp_spec) man->ramp_spec= MEM_dupallocN(ma->ramp_spec);
215         
216         if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview);
217
218         if(ma->nodetree) {
219                 man->nodetree= ntreeCopyTree(ma->nodetree, 0);  /* 0 == full new tree */
220         }
221
222         man->gpumaterial.first= man->gpumaterial.last= NULL;
223         
224         return man;
225 }
226
227 void make_local_material(Material *ma)
228 {
229         Object *ob;
230         Mesh *me;
231         Curve *cu;
232         MetaBall *mb;
233         Material *man;
234         int a, local=0, lib=0;
235
236         /* - only lib users: do nothing
237             * - only local users: set flag
238             * - mixed: make copy
239             */
240         
241         if(ma->id.lib==0) return;
242         if(ma->id.us==1) {
243                 ma->id.lib= 0;
244                 ma->id.flag= LIB_LOCAL;
245                 new_id(0, (ID *)ma, 0);
246                 for(a=0; a<MAX_MTEX; a++) {
247                         if(ma->mtex[a]) id_lib_extern((ID *)ma->mtex[a]->tex);
248                 }
249                 
250                 return;
251         }
252         
253         /* test objects */
254         ob= G.main->object.first;
255         while(ob) {
256                 if(ob->mat) {
257                         for(a=0; a<ob->totcol; a++) {
258                                 if(ob->mat[a]==ma) {
259                                         if(ob->id.lib) lib= 1;
260                                         else local= 1;
261                                 }
262                         }
263                 }
264                 ob= ob->id.next;
265         }
266         /* test meshes */
267         me= G.main->mesh.first;
268         while(me) {
269                 if(me->mat) {
270                         for(a=0; a<me->totcol; a++) {
271                                 if(me->mat[a]==ma) {
272                                         if(me->id.lib) lib= 1;
273                                         else local= 1;
274                                 }
275                         }
276                 }
277                 me= me->id.next;
278         }
279         /* test curves */
280         cu= G.main->curve.first;
281         while(cu) {
282                 if(cu->mat) {
283                         for(a=0; a<cu->totcol; a++) {
284                                 if(cu->mat[a]==ma) {
285                                         if(cu->id.lib) lib= 1;
286                                         else local= 1;
287                                 }
288                         }
289                 }
290                 cu= cu->id.next;
291         }
292         /* test mballs */
293         mb= G.main->mball.first;
294         while(mb) {
295                 if(mb->mat) {
296                         for(a=0; a<mb->totcol; a++) {
297                                 if(mb->mat[a]==ma) {
298                                         if(mb->id.lib) lib= 1;
299                                         else local= 1;
300                                 }
301                         }
302                 }
303                 mb= mb->id.next;
304         }
305         
306         if(local && lib==0) {
307                 ma->id.lib= 0;
308                 ma->id.flag= LIB_LOCAL;
309                 
310                 for(a=0; a<MAX_MTEX; a++) {
311                         if(ma->mtex[a]) id_lib_extern((ID *)ma->mtex[a]->tex);
312                 }
313                 
314                 new_id(0, (ID *)ma, 0);
315         }
316         else if(local && lib) {
317                 
318                 man= copy_material(ma);
319                 man->id.us= 0;
320                 
321                 /* do objects */
322                 ob= G.main->object.first;
323                 while(ob) {
324                         if(ob->mat) {
325                                 for(a=0; a<ob->totcol; a++) {
326                                         if(ob->mat[a]==ma) {
327                                                 if(ob->id.lib==0) {
328                                                         ob->mat[a]= man;
329                                                         man->id.us++;
330                                                         ma->id.us--;
331                                                 }
332                                         }
333                                 }
334                         }
335                         ob= ob->id.next;
336                 }
337                 /* do meshes */
338                 me= G.main->mesh.first;
339                 while(me) {
340                         if(me->mat) {
341                                 for(a=0; a<me->totcol; a++) {
342                                         if(me->mat[a]==ma) {
343                                                 if(me->id.lib==0) {
344                                                         me->mat[a]= man;
345                                                         man->id.us++;
346                                                         ma->id.us--;
347                                                 }
348                                         }
349                                 }
350                         }
351                         me= me->id.next;
352                 }
353                 /* do curves */
354                 cu= G.main->curve.first;
355                 while(cu) {
356                         if(cu->mat) {
357                                 for(a=0; a<cu->totcol; a++) {
358                                         if(cu->mat[a]==ma) {
359                                                 if(cu->id.lib==0) {
360                                                         cu->mat[a]= man;
361                                                         man->id.us++;
362                                                         ma->id.us--;
363                                                 }
364                                         }
365                                 }
366                         }
367                         cu= cu->id.next;
368                 }
369                 /* do mballs */
370                 mb= G.main->mball.first;
371                 while(mb) {
372                         if(mb->mat) {
373                                 for(a=0; a<mb->totcol; a++) {
374                                         if(mb->mat[a]==ma) {
375                                                 if(mb->id.lib==0) {
376                                                         mb->mat[a]= man;
377                                                         man->id.us++;
378                                                         ma->id.us--;
379                                                 }
380                                         }
381                                 }
382                         }
383                         mb= mb->id.next;
384                 }
385         }
386 }
387
388 Material ***give_matarar(Object *ob)
389 {
390         Mesh *me;
391         Curve *cu;
392         MetaBall *mb;
393         
394         if(ob->type==OB_MESH) {
395                 me= ob->data;
396                 return &(me->mat);
397         }
398         else if ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF) {
399                 cu= ob->data;
400                 return &(cu->mat);
401         }
402         else if(ob->type==OB_MBALL) {
403                 mb= ob->data;
404                 return &(mb->mat);
405         }
406         return NULL;
407 }
408
409 short *give_totcolp(Object *ob)
410 {
411         Mesh *me;
412         Curve *cu;
413         MetaBall *mb;
414         
415         if(ob->type==OB_MESH) {
416                 me= ob->data;
417                 return &(me->totcol);
418         }
419         else if ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF) {
420                 cu= ob->data;
421                 return &(cu->totcol);
422         }
423         else if(ob->type==OB_MBALL) {
424                 mb= ob->data;
425                 return &(mb->totcol);
426         }
427         return NULL;
428 }
429
430 Material *give_current_material(Object *ob, int act)
431 {
432         Material ***matarar, *ma;
433         short *totcolp;
434         
435         if(ob==NULL) return NULL;
436         
437         /* if object cannot have material, totcolp==NULL */
438         totcolp= give_totcolp(ob);
439         if(totcolp==NULL || ob->totcol==0) return NULL;
440         
441         if(act>ob->totcol) act= ob->totcol;
442         else if(act<=0) act= 1;
443
444         if( BTST(ob->colbits, act-1) ) {        /* in object */
445                 ma= ob->mat[act-1];
446         }
447         else {                                                          /* in data */
448
449                 /* check for inconsistancy */
450                 if(*totcolp < ob->totcol)
451                         ob->totcol= *totcolp;
452                 if(act>ob->totcol) act= ob->totcol;
453
454                 matarar= give_matarar(ob);
455                 
456                 if(matarar && *matarar) ma= (*matarar)[act-1];
457                 else ma= 0;
458                 
459         }
460         
461         return ma;
462 }
463
464 ID *material_from(Object *ob, int act)
465 {
466
467         if(ob==0) return 0;
468
469         if(ob->totcol==0) return ob->data;
470         if(act==0) act= 1;
471
472         if( BTST(ob->colbits, act-1) ) return (ID *)ob;
473         else return ob->data;
474 }
475
476 /* GS reads the memory pointed at in a specific ordering. There are,
477  * however two definitions for it. I have jotted them down here, both,
478  * but I think the first one is actually used. The thing is that
479  * big-endian systems might read this the wrong way round. OTOH, we
480  * constructed the IDs that are read out with this macro explicitly as
481  * well. I expect we'll sort it out soon... */
482
483 /* from blendef: */
484 #define GS(a)   (*((short *)(a)))
485
486 /* from misc_util: flip the bytes from x  */
487 /*  #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
488
489 void test_object_materials(ID *id)
490 {
491         /* make the ob mat-array same size as 'ob->data' mat-array */
492         Object *ob;
493         Mesh *me;
494         Curve *cu;
495         MetaBall *mb;
496         Material **newmatar;
497         int totcol=0;
498
499         if(id==0) return;
500
501         if( GS(id->name)==ID_ME ) {
502                 me= (Mesh *)id;
503                 totcol= me->totcol;
504         }
505         else if( GS(id->name)==ID_CU ) {
506                 cu= (Curve *)id;
507                 totcol= cu->totcol;
508         }
509         else if( GS(id->name)==ID_MB ) {
510                 mb= (MetaBall *)id;
511                 totcol= mb->totcol;
512         }
513         else return;
514
515         ob= G.main->object.first;
516         while(ob) {
517                 
518                 if(ob->data==id) {
519                 
520                         if(totcol==0) {
521                                 if(ob->totcol) {
522                                         MEM_freeN(ob->mat);
523                                         ob->mat= 0;
524                                 }
525                         }
526                         else if(ob->totcol<totcol) {
527                                 newmatar= MEM_callocN(sizeof(void *)*totcol, "newmatar");
528                                 if(ob->totcol) {
529                                         memcpy(newmatar, ob->mat, sizeof(void *)*ob->totcol);
530                                         MEM_freeN(ob->mat);
531                                 }
532                                 ob->mat= newmatar;
533                         }
534                         ob->totcol= totcol;
535                         if(ob->totcol && ob->actcol==0) ob->actcol= 1;
536                         if(ob->actcol>ob->totcol) ob->actcol= ob->totcol;
537                 }
538                 ob= ob->id.next;
539         }
540 }
541
542
543 void assign_material(Object *ob, Material *ma, int act)
544 {
545         Material *mao, **matar, ***matarar;
546         short *totcolp;
547
548         if(act>MAXMAT) return;
549         if(act<1) act= 1;
550         
551         /* test arraylens */
552         
553         totcolp= give_totcolp(ob);
554         matarar= give_matarar(ob);
555         
556         if(totcolp==0 || matarar==0) return;
557         
558         if( act > *totcolp) {
559                 matar= MEM_callocN(sizeof(void *)*act, "matarray1");
560                 if( *totcolp) {
561                         memcpy(matar, *matarar, sizeof(void *)*( *totcolp ));
562                         MEM_freeN(*matarar);
563                 }
564                 *matarar= matar;
565                 *totcolp= act;
566         }
567         
568         if(act > ob->totcol) {
569                 matar= MEM_callocN(sizeof(void *)*act, "matarray2");
570                 if( ob->totcol) {
571                         memcpy(matar, ob->mat, sizeof(void *)*( ob->totcol ));
572                         MEM_freeN(ob->mat);
573                 }
574                 ob->mat= matar;
575                 ob->totcol= act;
576         }
577         
578         /* do it */
579
580         if( BTST(ob->colbits, act-1) ) {        /* in object */
581                 mao= ob->mat[act-1];
582                 if(mao) mao->id.us--;
583                 ob->mat[act-1]= ma;
584         }
585         else {  /* in data */
586                 mao= (*matarar)[act-1];
587                 if(mao) mao->id.us--;
588                 (*matarar)[act-1]= ma;
589         }
590         id_us_plus((ID *)ma);
591         test_object_materials(ob->data);
592 }
593
594 int find_material_index(Object *ob, Material *ma)
595 {
596         Material ***matarar;
597         short a, *totcolp;
598         
599         if(ma==NULL) return 0;
600         
601         totcolp= give_totcolp(ob);
602         matarar= give_matarar(ob);
603         
604         if(totcolp==NULL || matarar==NULL) return 0;
605         
606         for(a=0; a<*totcolp; a++)
607                 if((*matarar)[a]==ma)
608                    break;
609         if(a<*totcolp)
610                 return a+1;
611         return 0;          
612 }
613
614 void new_material_to_objectdata(Object *ob)
615 {
616         Material *ma;
617         
618         if(ob==0) return;
619         if(ob->totcol>=MAXMAT) return;
620         
621         ma= give_current_material(ob, ob->actcol);
622         if(ma==NULL)
623                 ma= add_material("Material");
624         else
625                 ma= copy_material(ma);
626         
627         ma->id.us= 0; /* eeh... */
628         
629         if(ob->actcol) {
630                 if( BTST(ob->colbits, ob->actcol-1) ) {
631                         ob->colbits= BSET(ob->colbits, ob->totcol);
632                 }
633         }
634         
635         assign_material(ob, ma, ob->totcol+1);
636         ob->actcol= ob->totcol;
637 }
638
639 static void do_init_render_material(Material *ma, int r_mode, float *amb)
640 {
641         MTex *mtex;
642         int a, needuv=0, needtang=0;
643         
644         if(ma->flarec==0) ma->flarec= 1;
645
646         /* add all texcoflags from mtex, texco and mapto were cleared in advance */
647         for(a=0; a<MAX_MTEX; a++) {
648                 
649                 /* separate tex switching */
650                 if(ma->septex & (1<<a)) continue;
651
652                 mtex= ma->mtex[a];
653                 if(mtex && mtex->tex && mtex->tex->type) {
654                         
655                         ma->texco |= mtex->texco;
656                         ma->mapto |= mtex->mapto;
657                         if(r_mode & R_OSA) {
658                                 if ELEM3(mtex->tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) ma->texco |= TEXCO_OSA;
659                         }
660                         
661                         if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1;
662                         else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT|TEXCO_SPEED)) needuv= 1;
663                         else if(ma->texco & (TEXCO_LAVECTOR|TEXCO_VIEW|TEXCO_STICKY)) needuv= 1;
664
665                         if((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT))
666                                 needtang= 1;
667                 }
668         }
669
670         if(needtang) ma->mode |= MA_NORMAP_TANG;
671         else ma->mode &= ~MA_NORMAP_TANG;
672         
673         if(r_mode & R_RADIO)
674                 if(ma->mode & MA_RADIO) needuv= 1;
675         
676         if(ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
677                 needuv= 1;
678                 if(r_mode & R_OSA) ma->texco |= TEXCO_OSA;              /* for texfaces */
679         }
680         if(needuv) ma->texco |= NEED_UV;
681         
682         /* since the raytracer doesnt recalc O structs for each ray, we have to preset them all */
683         if(r_mode & R_RAYTRACE) {
684                 if(ma->mode & (MA_RAYMIRROR|MA_RAYTRANSP|MA_SHADOW_TRA)) { 
685                         ma->texco |= NEED_UV|TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM;
686                         if(r_mode & R_OSA) ma->texco |= TEXCO_OSA;
687                 }
688         }
689         
690         if(amb) {
691                 ma->ambr= ma->amb*amb[0];
692                 ma->ambg= ma->amb*amb[1];
693                 ma->ambb= ma->amb*amb[2];
694         }       
695         /* will become or-ed result of all node modes */
696         ma->mode_l= ma->mode;
697         ma->mode_l &= ~MA_SHLESS;
698
699         if(ma->strand_surfnor > 0.0f)
700                 ma->mode_l |= MA_STR_SURFDIFF;
701 }
702
703 static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb)
704 {
705         bNode *node;
706         
707         for(node=ntree->nodes.first; node; node= node->next) {
708                 if(node->id) {
709                         if(GS(node->id->name)==ID_MA) {
710                                 Material *ma= (Material *)node->id;
711                                 if(ma!=basemat) {
712                                         do_init_render_material(ma, r_mode, amb);
713                                         basemat->texco |= ma->texco;
714                                         basemat->mode_l |= ma->mode_l;
715                                 }
716                         }
717                         else if(node->type==NODE_GROUP)
718                                 init_render_nodetree((bNodeTree *)node->id, basemat, r_mode, amb);
719                 }
720         }
721         /* parses the geom+tex nodes */
722         ntreeShaderGetTexcoMode(ntree, r_mode, &basemat->texco, &basemat->mode_l);
723 }
724
725 void init_render_material(Material *mat, int r_mode, float *amb)
726 {
727         
728         do_init_render_material(mat, r_mode, amb);
729         
730         if(mat->nodetree && mat->use_nodes) {
731                 init_render_nodetree(mat->nodetree, mat, r_mode, amb);
732                 
733                 ntreeBeginExecTree(mat->nodetree); /* has internal flag to detect it only does it once */
734         }
735 }
736
737 void init_render_materials(int r_mode, float *amb)
738 {
739         Material *ma;
740         
741         /* clear these flags before going over materials, to make sure they
742          * are cleared only once, otherwise node materials contained in other
743          * node materials can go wrong */
744         for(ma= G.main->mat.first; ma; ma= ma->id.next) {
745                 if(ma->id.us) {
746                         ma->texco= 0;
747                         ma->mapto= 0;
748                 }
749         }
750
751         /* two steps, first initialize, then or the flags for layers */
752         for(ma= G.main->mat.first; ma; ma= ma->id.next) {
753                 /* is_used flag comes back in convertblender.c */
754                 ma->flag &= ~MA_IS_USED;
755                 if(ma->id.us) 
756                         init_render_material(ma, r_mode, amb);
757         }
758         
759         do_init_render_material(&defmaterial, r_mode, amb);
760 }
761
762 /* only needed for nodes now */
763 void end_render_material(Material *mat)
764 {
765         if(mat && mat->nodetree && mat->use_nodes)
766                 ntreeEndExecTree(mat->nodetree); /* has internal flag to detect it only does it once */
767 }
768
769 void end_render_materials(void)
770 {
771         Material *ma;
772         for(ma= G.main->mat.first; ma; ma= ma->id.next)
773                 if(ma->id.us) 
774                         end_render_material(ma);
775 }
776
777 static int material_in_nodetree(bNodeTree *ntree, Material *mat)
778 {
779         bNode *node;
780
781         for(node=ntree->nodes.first; node; node= node->next) {
782                 if(node->id && GS(node->id->name)==ID_MA) {
783                         if(node->id==(ID*)mat)
784                                 return 1;
785                 }
786                 else if(node->type==NODE_GROUP)
787                         if(material_in_nodetree((bNodeTree*)node->id, mat))
788                                 return 1;
789         }
790
791         return 0;
792 }
793
794 int material_in_material(Material *parmat, Material *mat)
795 {
796         if(parmat==mat)
797                 return 1;
798         else if(parmat->nodetree && parmat->use_nodes)
799                 return material_in_nodetree(parmat->nodetree, mat);
800         else
801                 return 0;
802 }
803         
804 /* ****************** */
805
806 char colname_array[125][20]= {
807 "Black","DarkRed","HalfRed","Red","Red",
808 "DarkGreen","DarkOlive","Brown","Chocolate","OrangeRed",
809 "HalfGreen","GreenOlive","DryOlive","Goldenrod","DarkOrange",
810 "LightGreen","Chartreuse","YellowGreen","Yellow","Gold",
811 "Green","LawnGreen","GreenYellow","LightOlive","Yellow",
812 "DarkBlue","DarkPurple","HotPink","VioletPink","RedPink",
813 "SlateGray","DarkGrey","PalePurple","IndianRed","Tomato",
814 "SeaGreen","PaleGreen","GreenKhaki","LightBrown","LightSalmon",
815 "SpringGreen","PaleGreen","MediumOlive","YellowBrown","LightGold",
816 "LightGreen","LightGreen","LightGreen","GreenYellow","PaleYellow",
817 "HalfBlue","DarkSky","HalfMagenta","VioletRed","DeepPink",
818 "SteelBlue","SkyBlue","Orchid","LightHotPink","HotPink",
819 "SeaGreen","SlateGray","MediumGrey","Burlywood","LightPink",
820 "SpringGreen","Aquamarine","PaleGreen","Khaki","PaleOrange",
821 "SpringGreen","SeaGreen","PaleGreen","PaleWhite","YellowWhite",
822 "LightBlue","Purple","MediumOrchid","Magenta","Magenta",
823 "RoyalBlue","SlateBlue","MediumOrchid","Orchid","Magenta",
824 "DeepSkyBlue","LightSteelBlue","LightSkyBlue","Violet","LightPink",
825 "Cyan","DarkTurquoise","SkyBlue","Grey","Snow",
826 "Mint","Mint","Aquamarine","MintCream","Ivory",
827 "Blue","Blue","DarkMagenta","DarkOrchid","Magenta",
828 "SkyBlue","RoyalBlue","LightSlateBlue","MediumOrchid","Magenta",
829 "DodgerBlue","SteelBlue","MediumPurple","PalePurple","Plum",
830 "DeepSkyBlue","PaleBlue","LightSkyBlue","PalePurple","Thistle",
831 "Cyan","ColdBlue","PaleTurquoise","GhostWhite","White"
832 };
833
834 void automatname(Material *ma)
835 {
836         int nr, r, g, b;
837         float ref;
838         
839         if(ma==0) return;
840         if(ma->mode & MA_SHLESS) ref= 1.0;
841         else ref= ma->ref;
842         
843         r= (int)(4.99*(ref*ma->r));
844         g= (int)(4.99*(ref*ma->g));
845         b= (int)(4.99*(ref*ma->b));
846         nr= r + 5*g + 25*b;
847         if(nr>124) nr= 124;
848         new_id(&G.main->mat, (ID *)ma, colname_array[nr]);
849         
850 }
851
852
853 void delete_material_index()
854 {
855         Material *mao, ***matarar;
856         Object *ob, *obt;
857         Curve *cu;
858         Nurb *nu;
859         short *totcolp;
860         int a, actcol;
861         
862         if(G.obedit) {
863                 error("Unable to perform function in EditMode");
864                 return;
865         }
866         ob= ((G.scene->basact)? (G.scene->basact->object) : 0) ;
867         if(ob==0 || ob->totcol==0) return;
868         
869         /* take a mesh/curve/mball as starting point, remove 1 index,
870          * AND with all objects that share the ob->data
871          * 
872          * after that check indices in mesh/curve/mball!!!
873          */
874         
875         totcolp= give_totcolp(ob);
876         matarar= give_matarar(ob);
877
878         /* we delete the actcol */
879         if(ob->totcol) {
880                 mao= (*matarar)[ob->actcol-1];
881                 if(mao) mao->id.us--;
882         }
883         
884         for(a=ob->actcol; a<ob->totcol; a++) {
885                 (*matarar)[a-1]= (*matarar)[a];
886         }
887         (*totcolp)--;
888         
889         if(*totcolp==0) {
890                 MEM_freeN(*matarar);
891                 *matarar= 0;
892         }
893         
894         actcol= ob->actcol;
895         obt= G.main->object.first;
896         while(obt) {
897         
898                 if(obt->data==ob->data) {
899                         
900                         /* WATCH IT: do not use actcol from ob or from obt (can become zero) */
901                         mao= obt->mat[actcol-1];
902                         if(mao) mao->id.us--;
903                 
904                         for(a=actcol; a<obt->totcol; a++) obt->mat[a-1]= obt->mat[a];
905                         obt->totcol--;
906                         if(obt->actcol > obt->totcol) obt->actcol= obt->totcol;
907                         
908                         if(obt->totcol==0) {
909                                 MEM_freeN(obt->mat);
910                                 obt->mat= 0;
911                         }
912                 }
913                 obt= obt->id.next;
914         }
915
916         /* check indices from mesh */
917
918         if(ob->type==OB_MESH) {
919                 Mesh *me= get_mesh(ob);
920                 mesh_delete_material_index(me, actcol-1);
921                 freedisplist(&ob->disp);
922         }
923         else if ELEM(ob->type, OB_CURVE, OB_SURF) {
924                 cu= ob->data;
925                 nu= cu->nurb.first;
926                 
927                 while(nu) {
928                         if(nu->mat_nr && nu->mat_nr>=actcol-1) {
929                                 nu->mat_nr--;
930                                 if (ob->type == OB_CURVE) nu->charidx--;
931                         }
932                         nu= nu->next;
933                 }
934                 freedisplist(&ob->disp);
935         }
936 }
937
938
939 /* r g b = current value, col = new value, fac==0 is no change */
940 /* if g==NULL, it only does r channel */
941 void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
942 {
943         float tmp, facm= 1.0-fac;
944         
945         switch (type) {
946                 case MA_RAMP_BLEND:
947                         *r = facm*(*r) + fac*col[0];
948                         if(g) {
949                                 *g = facm*(*g) + fac*col[1];
950                                 *b = facm*(*b) + fac*col[2];
951                         }
952                                 break;
953                 case MA_RAMP_ADD:
954                         *r += fac*col[0];
955                         if(g) {
956                                 *g += fac*col[1];
957                                 *b += fac*col[2];
958                         }
959                                 break;
960                 case MA_RAMP_MULT:
961                         *r *= (facm + fac*col[0]);
962                         if(g) {
963                                 *g *= (facm + fac*col[1]);
964                                 *b *= (facm + fac*col[2]);
965                         }
966                                 break;
967                 case MA_RAMP_SCREEN:
968                         *r = 1.0 - (facm + fac*(1.0 - col[0])) * (1.0 - *r);
969                         if(g) {
970                                 *g = 1.0 - (facm + fac*(1.0 - col[1])) * (1.0 - *g);
971                                 *b = 1.0 - (facm + fac*(1.0 - col[2])) * (1.0 - *b);
972                         }
973                                 break;
974                 case MA_RAMP_OVERLAY:
975                         if(*r < 0.5f)
976                                 *r *= (facm + 2.0f*fac*col[0]);
977                         else
978                                 *r = 1.0 - (facm + 2.0f*fac*(1.0 - col[0])) * (1.0 - *r);
979                         if(g) {
980                                 if(*g < 0.5f)
981                                         *g *= (facm + 2.0f*fac*col[1]);
982                                 else
983                                         *g = 1.0 - (facm + 2.0f*fac*(1.0 - col[1])) * (1.0 - *g);
984                                 if(*b < 0.5f)
985                                         *b *= (facm + 2.0f*fac*col[2]);
986                                 else
987                                         *b = 1.0 - (facm + 2.0f*fac*(1.0 - col[2])) * (1.0 - *b);
988                         }
989                                 break;
990                 case MA_RAMP_SUB:
991                         *r -= fac*col[0];
992                         if(g) {
993                                 *g -= fac*col[1];
994                                 *b -= fac*col[2];
995                         }
996                                 break;
997                 case MA_RAMP_DIV:
998                         if(col[0]!=0.0)
999                                 *r = facm*(*r) + fac*(*r)/col[0];
1000                         if(g) {
1001                                 if(col[1]!=0.0)
1002                                         *g = facm*(*g) + fac*(*g)/col[1];
1003                                 if(col[2]!=0.0)
1004                                         *b = facm*(*b) + fac*(*b)/col[2];
1005                         }
1006                                 break;
1007                 case MA_RAMP_DIFF:
1008                         *r = facm*(*r) + fac*fabs(*r-col[0]);
1009                         if(g) {
1010                                 *g = facm*(*g) + fac*fabs(*g-col[1]);
1011                                 *b = facm*(*b) + fac*fabs(*b-col[2]);
1012                         }
1013                                 break;
1014                 case MA_RAMP_DARK:
1015                         tmp= fac*col[0];
1016                         if(tmp < *r) *r= tmp; 
1017                                 if(g) {
1018                                         tmp= fac*col[1];
1019                                         if(tmp < *g) *g= tmp; 
1020                                         tmp= fac*col[2];
1021                                         if(tmp < *b) *b= tmp; 
1022                                 }
1023                                         break;
1024                 case MA_RAMP_LIGHT:
1025                         tmp= fac*col[0];
1026                         if(tmp > *r) *r= tmp; 
1027                                 if(g) {
1028                                         tmp= fac*col[1];
1029                                         if(tmp > *g) *g= tmp; 
1030                                         tmp= fac*col[2];
1031                                         if(tmp > *b) *b= tmp; 
1032                                 }
1033                                         break;  
1034                 case MA_RAMP_DODGE:                     
1035                         
1036                                 
1037                         if(*r !=0.0){
1038                                 tmp = 1.0 - fac*col[0];
1039                                 if(tmp <= 0.0)
1040                                         *r = 1.0;
1041                                 else if ((tmp = (*r) / tmp)> 1.0)
1042                                         *r = 1.0;
1043                                 else 
1044                                         *r = tmp;
1045                         }
1046                         if(g) {
1047                                 if(*g !=0.0){
1048                                         tmp = 1.0 - fac*col[1];
1049                                         if(tmp <= 0.0 )
1050                                                 *g = 1.0;
1051                                         else if ((tmp = (*g) / tmp) > 1.0 )
1052                                                 *g = 1.0;
1053                                         else
1054                                                 *g = tmp;
1055                                 }
1056                                 if(*b !=0.0){
1057                                         tmp = 1.0 - fac*col[2];
1058                                         if(tmp <= 0.0)
1059                                                 *b = 1.0;
1060                                         else if ((tmp = (*b) / tmp) > 1.0 )
1061                                                 *b = 1.0;
1062                                         else
1063                                                 *b = tmp;
1064                                 }
1065
1066                         }
1067                                 break;  
1068                 case MA_RAMP_BURN:
1069                         
1070                         tmp = facm + fac*col[0];
1071                         
1072                         if(tmp <= 0.0)
1073                                 *r = 0.0;
1074                         else if (( tmp = (1.0 - (1.0 - (*r)) / tmp )) < 0.0)
1075                                 *r = 0.0;
1076                         else if (tmp > 1.0)
1077                                 *r=1.0;
1078                         else 
1079                                 *r = tmp; 
1080
1081                         if(g) {
1082                                 tmp = facm + fac*col[1];
1083                                 if(tmp <= 0.0)
1084                                         *g = 0.0;
1085                                 else if (( tmp = (1.0 - (1.0 - (*g)) / tmp )) < 0.0 )
1086                                         *g = 0.0;
1087                                 else if(tmp >1.0)
1088                                         *g=1.0;
1089                                 else
1090                                         *g = tmp;
1091                                         
1092                                 tmp = facm + fac*col[2];
1093                                 if(tmp <= 0.0)
1094                                         *b = 0.0;
1095                                 else if (( tmp = (1.0 - (1.0 - (*b)) / tmp )) < 0.0  )
1096                                         *b = 0.0;
1097                                 else if(tmp >1.0)
1098                                         *b= 1.0;
1099                                 else
1100                                         *b = tmp;
1101                         }
1102                                 break;
1103                 case MA_RAMP_HUE:               
1104                         if(g){
1105                                 float rH,rS,rV;
1106                                 float colH,colS,colV; 
1107                                 float tmpr,tmpg,tmpb;
1108                                 rgb_to_hsv(col[0],col[1],col[2],&colH,&colS,&colV);
1109                                 if(colS!=0 ){
1110                                         rgb_to_hsv(*r,*g,*b,&rH,&rS,&rV);
1111                                         hsv_to_rgb( colH , rS, rV, &tmpr, &tmpg, &tmpb);
1112                                         *r = facm*(*r) + fac*tmpr;  
1113                                         *g = facm*(*g) + fac*tmpg; 
1114                                         *b = facm*(*b) + fac*tmpb;
1115                                 }
1116                         }
1117                                 break;
1118                 case MA_RAMP_SAT:               
1119                         if(g){
1120                                 float rH,rS,rV;
1121                                 float colH,colS,colV;
1122                                 rgb_to_hsv(*r,*g,*b,&rH,&rS,&rV);
1123                                 if(rS!=0){
1124                                         rgb_to_hsv(col[0],col[1],col[2],&colH,&colS,&colV);
1125                                         hsv_to_rgb( rH, (facm*rS +fac*colS), rV, r, g, b);
1126                                 }
1127                         }
1128                                 break;
1129                 case MA_RAMP_VAL:               
1130                         if(g){
1131                                 float rH,rS,rV;
1132                                 float colH,colS,colV;
1133                                 rgb_to_hsv(*r,*g,*b,&rH,&rS,&rV);
1134                                 rgb_to_hsv(col[0],col[1],col[2],&colH,&colS,&colV);
1135                                 hsv_to_rgb( rH, rS, (facm*rV +fac*colV), r, g, b);
1136                         }
1137                                 break;
1138                 case MA_RAMP_COLOR:             
1139                         if(g){
1140                                 float rH,rS,rV;
1141                                 float colH,colS,colV;
1142                                 float tmpr,tmpg,tmpb;
1143                                 rgb_to_hsv(col[0],col[1],col[2],&colH,&colS,&colV);
1144                                 if(colS!=0){
1145                                         rgb_to_hsv(*r,*g,*b,&rH,&rS,&rV);
1146                                         hsv_to_rgb( colH, colS, rV, &tmpr, &tmpg, &tmpb);
1147                                         *r = facm*(*r) + fac*tmpr;
1148                                         *g = facm*(*g) + fac*tmpg;
1149                                         *b = facm*(*b) + fac*tmpb;
1150                                 }
1151                         }
1152                                 break;
1153         }
1154         
1155 }
1156
1157