f97dd2f859dd412e1cd79862f0bdc122e7392653
[blender.git] / source / blender / blenkernel / intern / material.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/material.c
29  *  \ingroup bke
30  */
31
32
33 #include <string.h>
34 #include <math.h>
35 #include <stddef.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_anim_types.h"
40 #include "DNA_curve_types.h"
41 #include "DNA_material_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_customdata_types.h"
45 #include "DNA_ID.h"
46 #include "DNA_meta_types.h"
47 #include "DNA_node_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_scene_types.h"
50
51 #include "BLI_math.h"           
52 #include "BLI_listbase.h"               
53 #include "BLI_utildefines.h"
54 #include "BLI_bpath.h"
55 #include "BLI_string.h"
56
57 #include "BKE_animsys.h"
58 #include "BKE_displist.h"
59 #include "BKE_global.h"
60 #include "BKE_icons.h"
61 #include "BKE_image.h"
62 #include "BKE_library.h"
63 #include "BKE_main.h"
64 #include "BKE_material.h"
65 #include "BKE_mesh.h"
66 #include "BKE_node.h"
67 #include "BKE_curve.h"
68
69 #include "GPU_material.h"
70
71 /* used in UI and render */
72 Material defmaterial;
73
74 /* called on startup, creator.c */
75 void init_def_material(void)
76 {
77         init_material(&defmaterial);
78 }
79
80 /* not material itself */
81 void BKE_material_free(Material *ma)
82 {
83         MTex *mtex;
84         int a;
85         
86         for (a = 0; a < MAX_MTEX; a++) {
87                 mtex = ma->mtex[a];
88                 if (mtex && mtex->tex) mtex->tex->id.us--;
89                 if (mtex) MEM_freeN(mtex);
90         }
91         
92         if (ma->ramp_col) MEM_freeN(ma->ramp_col);
93         if (ma->ramp_spec) MEM_freeN(ma->ramp_spec);
94         
95         BKE_free_animdata((ID *)ma);
96         
97         if (ma->preview)
98                 BKE_previewimg_free(&ma->preview);
99         BKE_icon_delete((struct ID *)ma);
100         ma->id.icon_id = 0;
101         
102         /* is no lib link block, but material extension */
103         if (ma->nodetree) {
104                 ntreeFreeTree(ma->nodetree);
105                 MEM_freeN(ma->nodetree);
106         }
107
108         if (ma->gpumaterial.first)
109                 GPU_material_free(ma);
110 }
111
112 void init_material(Material *ma)
113 {
114         ma->r = ma->g = ma->b = ma->ref = 0.8;
115         ma->specr = ma->specg = ma->specb = 1.0;
116         ma->mirr = ma->mirg = ma->mirb = 1.0;
117         ma->spectra = 1.0;
118         ma->amb = 1.0;
119         ma->alpha = 1.0;
120         ma->spec = ma->hasize = 0.5;
121         ma->har = 50;
122         ma->starc = ma->ringc = 4;
123         ma->linec = 12;
124         ma->flarec = 1;
125         ma->flaresize = ma->subsize = 1.0;
126         ma->flareboost = 1;
127         ma->seed2 = 6;
128         ma->friction = 0.5;
129         ma->refrac = 4.0;
130         ma->roughness = 0.5;
131         ma->param[0] = 0.5;
132         ma->param[1] = 0.1;
133         ma->param[2] = 0.5;
134         ma->param[3] = 0.1;
135         ma->rms = 0.1;
136         ma->darkness = 1.0;
137
138         ma->strand_sta = ma->strand_end = 1.0f;
139
140         ma->ang = 1.0;
141         ma->ray_depth = 2;
142         ma->ray_depth_tra = 2;
143         ma->fresnel_mir = 0.0;
144         ma->fresnel_tra = 0.0;
145         ma->fresnel_tra_i = 1.25;
146         ma->fresnel_mir_i = 1.25;
147         ma->tx_limit = 0.0;
148         ma->tx_falloff = 1.0;
149         ma->shad_alpha = 1.0f;
150         
151         ma->gloss_mir = ma->gloss_tra = 1.0;
152         ma->samp_gloss_mir = ma->samp_gloss_tra = 18;
153         ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005;
154         ma->dist_mir = 0.0;
155         ma->fadeto_mir = MA_RAYMIR_FADETOSKY;
156         
157         ma->rampfac_col = 1.0;
158         ma->rampfac_spec = 1.0;
159         ma->pr_lamp = 3;         /* two lamps, is bits */
160         ma->pr_type = MA_SPHERE;
161
162         ma->sss_radius[0] = 1.0f;
163         ma->sss_radius[1] = 1.0f;
164         ma->sss_radius[2] = 1.0f;
165         ma->sss_col[0] = 1.0f;
166         ma->sss_col[1] = 1.0f;
167         ma->sss_col[2] = 1.0f;
168         ma->sss_error = 0.05f;
169         ma->sss_scale = 0.1f;
170         ma->sss_ior = 1.3f;
171         ma->sss_colfac = 1.0f;
172         ma->sss_texfac = 0.0f;
173         ma->sss_front = 1.0f;
174         ma->sss_back = 1.0f;
175
176         ma->vol.density = 1.0f;
177         ma->vol.emission = 0.0f;
178         ma->vol.scattering = 1.0f;
179         ma->vol.reflection = 1.0f;
180         ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
181         ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
182         ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
183         ma->vol.density_scale = 1.0f;
184         ma->vol.depth_cutoff = 0.01f;
185         ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
186         ma->vol.stepsize = 0.2f;
187         ma->vol.shade_type = MA_VOL_SHADE_SHADED;
188         ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
189         ma->vol.precache_resolution = 50;
190         ma->vol.ms_spread = 0.2f;
191         ma->vol.ms_diff = 1.f;
192         ma->vol.ms_intensity = 1.f;
193         
194         ma->game.flag = GEMAT_BACKCULL;
195         ma->game.alpha_blend = 0;
196         ma->game.face_orientation = 0;
197         
198         ma->mode = MA_TRACEBLE | MA_SHADBUF | MA_SHADOW | MA_RAYBIAS | MA_TANGENT_STR | MA_ZTRANSP;
199         ma->shade_flag = MA_APPROX_OCCLUSION;
200         ma->preview = NULL;
201 }
202
203 Material *BKE_material_add(const char *name)
204 {
205         Material *ma;
206
207         ma = BKE_libblock_alloc(&G.main->mat, ID_MA, name);
208         
209         init_material(ma);
210         
211         return ma;      
212 }
213
214 /* XXX keep synced with next function */
215 Material *BKE_material_copy(Material *ma)
216 {
217         Material *man;
218         int a;
219         
220         man = BKE_libblock_copy(&ma->id);
221         
222         id_lib_extern((ID *)man->group);
223         
224         for (a = 0; a < MAX_MTEX; a++) {
225                 if (ma->mtex[a]) {
226                         man->mtex[a] = MEM_mallocN(sizeof(MTex), "copymaterial");
227                         memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex));
228                         id_us_plus((ID *)man->mtex[a]->tex);
229                 }
230         }
231         
232         if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
233         if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
234         
235         if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview);
236
237         if (ma->nodetree) {
238                 man->nodetree = ntreeCopyTree(ma->nodetree); /* 0 == full new tree */
239         }
240
241         man->gpumaterial.first = man->gpumaterial.last = NULL;
242         
243         return man;
244 }
245
246 /* XXX (see above) material copy without adding to main dbase */
247 Material *localize_material(Material *ma)
248 {
249         Material *man;
250         int a;
251         
252         man = BKE_libblock_copy(&ma->id);
253         BLI_remlink(&G.main->mat, man);
254
255         /* no increment for texture ID users, in previewrender.c it prevents decrement */
256         for (a = 0; a < MAX_MTEX; a++) {
257                 if (ma->mtex[a]) {
258                         man->mtex[a] = MEM_mallocN(sizeof(MTex), "copymaterial");
259                         memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex));
260                 }
261         }
262         
263         if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
264         if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
265         
266         man->preview = NULL;
267         
268         if (ma->nodetree)
269                 man->nodetree = ntreeLocalize(ma->nodetree);
270         
271         man->gpumaterial.first = man->gpumaterial.last = NULL;
272         
273         return man;
274 }
275
276 static void extern_local_material(Material *ma)
277 {
278         int i;
279         for (i = 0; i < MAX_MTEX; i++) {
280                 if (ma->mtex[i]) id_lib_extern((ID *)ma->mtex[i]->tex);
281         }
282 }
283
284 void BKE_material_make_local(Material *ma)
285 {
286         Main *bmain = G.main;
287         Object *ob;
288         Mesh *me;
289         Curve *cu;
290         MetaBall *mb;
291         int a, is_local = FALSE, is_lib = FALSE;
292
293         /* - only lib users: do nothing
294          * - only local users: set flag
295          * - mixed: make copy
296          */
297         
298         if (ma->id.lib == NULL) return;
299
300         /* One local user; set flag and return. */
301         if (ma->id.us == 1) {
302                 id_clear_lib_data(bmain, &ma->id);
303                 extern_local_material(ma);
304                 return;
305         }
306
307         /* Check which other IDs reference this one to determine if it's used by
308          * lib or local */
309         /* test objects */
310         ob = bmain->object.first;
311         while (ob) {
312                 if (ob->mat) {
313                         for (a = 0; a < ob->totcol; a++) {
314                                 if (ob->mat[a] == ma) {
315                                         if (ob->id.lib) is_lib = TRUE;
316                                         else is_local = TRUE;
317                                 }
318                         }
319                 }
320                 ob = ob->id.next;
321         }
322         /* test meshes */
323         me = bmain->mesh.first;
324         while (me) {
325                 if (me->mat) {
326                         for (a = 0; a < me->totcol; a++) {
327                                 if (me->mat[a] == ma) {
328                                         if (me->id.lib) is_lib = TRUE;
329                                         else is_local = TRUE;
330                                 }
331                         }
332                 }
333                 me = me->id.next;
334         }
335         /* test curves */
336         cu = bmain->curve.first;
337         while (cu) {
338                 if (cu->mat) {
339                         for (a = 0; a < cu->totcol; a++) {
340                                 if (cu->mat[a] == ma) {
341                                         if (cu->id.lib) is_lib = TRUE;
342                                         else is_local = TRUE;
343                                 }
344                         }
345                 }
346                 cu = cu->id.next;
347         }
348         /* test mballs */
349         mb = bmain->mball.first;
350         while (mb) {
351                 if (mb->mat) {
352                         for (a = 0; a < mb->totcol; a++) {
353                                 if (mb->mat[a] == ma) {
354                                         if (mb->id.lib) is_lib = TRUE;
355                                         else is_local = TRUE;
356                                 }
357                         }
358                 }
359                 mb = mb->id.next;
360         }
361
362         /* Only local users. */
363         if (is_local && is_lib == FALSE) {
364                 id_clear_lib_data(bmain, &ma->id);
365                 extern_local_material(ma);
366         }
367         /* Both user and local, so copy. */
368         else if (is_local && is_lib) {
369                 Material *ma_new = BKE_material_copy(ma);
370
371                 ma_new->id.us = 0;
372
373                 /* Remap paths of new ID using old library as base. */
374                 BKE_id_lib_local_paths(bmain, ma->id.lib, &ma_new->id);
375
376                 /* do objects */
377                 ob = bmain->object.first;
378                 while (ob) {
379                         if (ob->mat) {
380                                 for (a = 0; a < ob->totcol; a++) {
381                                         if (ob->mat[a] == ma) {
382                                                 if (ob->id.lib == NULL) {
383                                                         ob->mat[a] = ma_new;
384                                                         ma_new->id.us++;
385                                                         ma->id.us--;
386                                                 }
387                                         }
388                                 }
389                         }
390                         ob = ob->id.next;
391                 }
392                 /* do meshes */
393                 me = bmain->mesh.first;
394                 while (me) {
395                         if (me->mat) {
396                                 for (a = 0; a < me->totcol; a++) {
397                                         if (me->mat[a] == ma) {
398                                                 if (me->id.lib == NULL) {
399                                                         me->mat[a] = ma_new;
400                                                         ma_new->id.us++;
401                                                         ma->id.us--;
402                                                 }
403                                         }
404                                 }
405                         }
406                         me = me->id.next;
407                 }
408                 /* do curves */
409                 cu = bmain->curve.first;
410                 while (cu) {
411                         if (cu->mat) {
412                                 for (a = 0; a < cu->totcol; a++) {
413                                         if (cu->mat[a] == ma) {
414                                                 if (cu->id.lib == NULL) {
415                                                         cu->mat[a] = ma_new;
416                                                         ma_new->id.us++;
417                                                         ma->id.us--;
418                                                 }
419                                         }
420                                 }
421                         }
422                         cu = cu->id.next;
423                 }
424                 /* do mballs */
425                 mb = bmain->mball.first;
426                 while (mb) {
427                         if (mb->mat) {
428                                 for (a = 0; a < mb->totcol; a++) {
429                                         if (mb->mat[a] == ma) {
430                                                 if (mb->id.lib == NULL) {
431                                                         mb->mat[a] = ma_new;
432                                                         ma_new->id.us++;
433                                                         ma->id.us--;
434                                                 }
435                                         }
436                                 }
437                         }
438                         mb = mb->id.next;
439                 }
440         }
441 }
442
443 /* for curve, mball, mesh types */
444 void extern_local_matarar(struct Material **matar, short totcol)
445 {
446         short i;
447         for (i = 0; i < totcol; i++) {
448                 id_lib_extern((ID *)matar[i]);
449         }
450 }
451
452 Material ***give_matarar(Object *ob)
453 {
454         Mesh *me;
455         Curve *cu;
456         MetaBall *mb;
457         
458         if (ob->type == OB_MESH) {
459                 me = ob->data;
460                 return &(me->mat);
461         }
462         else if (ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
463                 cu = ob->data;
464                 return &(cu->mat);
465         }
466         else if (ob->type == OB_MBALL) {
467                 mb = ob->data;
468                 return &(mb->mat);
469         }
470         return NULL;
471 }
472
473 short *give_totcolp(Object *ob)
474 {
475         Mesh *me;
476         Curve *cu;
477         MetaBall *mb;
478         
479         if (ob->type == OB_MESH) {
480                 me = ob->data;
481                 return &(me->totcol);
482         }
483         else if (ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
484                 cu = ob->data;
485                 return &(cu->totcol);
486         }
487         else if (ob->type == OB_MBALL) {
488                 mb = ob->data;
489                 return &(mb->totcol);
490         }
491         return NULL;
492 }
493
494 /* same as above but for ID's */
495 Material ***give_matarar_id(ID *id)
496 {
497         switch (GS(id->name)) {
498                 case ID_ME:
499                         return &(((Mesh *)id)->mat);
500                         break;
501                 case ID_CU:
502                         return &(((Curve *)id)->mat);
503                         break;
504                 case ID_MB:
505                         return &(((MetaBall *)id)->mat);
506                         break;
507         }
508         return NULL;
509 }
510
511 short *give_totcolp_id(ID *id)
512 {
513         switch (GS(id->name)) {
514                 case ID_ME:
515                         return &(((Mesh *)id)->totcol);
516                         break;
517                 case ID_CU:
518                         return &(((Curve *)id)->totcol);
519                         break;
520                 case ID_MB:
521                         return &(((MetaBall *)id)->totcol);
522                         break;
523         }
524         return NULL;
525 }
526
527 static void data_delete_material_index_id(ID *id, short index)
528 {
529         switch (GS(id->name)) {
530                 case ID_ME:
531                         BKE_mesh_delete_material_index((Mesh *)id, index);
532                         break;
533                 case ID_CU:
534                         BKE_curve_delete_material_index((Curve *)id, index);
535                         break;
536                 case ID_MB:
537                         /* meta-elems don't have materials atm */
538                         break;
539         }
540 }
541
542 void material_append_id(ID *id, Material *ma)
543 {
544         Material ***matar;
545         if ((matar = give_matarar_id(id))) {
546                 short *totcol = give_totcolp_id(id);
547                 Material **mat = MEM_callocN(sizeof(void *) * ((*totcol) + 1), "newmatar");
548                 if (*totcol) memcpy(mat, *matar, sizeof(void *) * (*totcol));
549                 if (*matar) MEM_freeN(*matar);
550
551                 *matar = mat;
552                 (*matar)[(*totcol)++] = ma;
553
554                 id_us_plus((ID *)ma);
555                 test_object_materials(id);
556         }
557 }
558
559 Material *material_pop_id(ID *id, int index_i, int remove_material_slot)
560 {
561         short index = (short)index_i;
562         Material *ret = NULL;
563         Material ***matar;
564         if ((matar = give_matarar_id(id))) {
565                 short *totcol = give_totcolp_id(id);
566                 if (index >= 0 && index < (*totcol)) {
567                         ret = (*matar)[index];
568                         id_us_min((ID *)ret);
569
570                         if (remove_material_slot) {
571                                 if (*totcol <= 1) {
572                                         *totcol = 0;
573                                         MEM_freeN(*matar);
574                                         *matar = NULL;
575                                 }
576                                 else {
577                                         Material **mat;
578                                         if (index + 1 != (*totcol))
579                                                 memmove((*matar) + index, (*matar) + (index + 1), sizeof(void *) * ((*totcol) - (index + 1)));
580
581                                         (*totcol)--;
582                                         
583                                         mat = MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
584                                         memcpy(mat, *matar, sizeof(void *) * (*totcol));
585                                         MEM_freeN(*matar);
586
587                                         *matar = mat;
588                                         test_object_materials(id);
589                                 }
590
591                                 /* decrease mat_nr index */
592                                 data_delete_material_index_id(id, index);
593                         }
594
595                         /* don't remove material slot, only clear it*/
596                         else
597                                 (*matar)[index] = NULL;
598                 }
599         }
600         
601         return ret;
602 }
603
604 Material *give_current_material(Object *ob, short act)
605 {
606         Material ***matarar, *ma;
607         short *totcolp;
608         
609         if (ob == NULL) return NULL;
610         
611         /* if object cannot have material, (totcolp == NULL) */
612         totcolp = give_totcolp(ob);
613         if (totcolp == NULL || ob->totcol == 0) return NULL;
614         
615         if (act < 0) {
616                 printf("no!\n");
617         }
618         
619         if (act > ob->totcol) act = ob->totcol;
620         else if (act <= 0) act = 1;
621
622         if (ob->matbits && ob->matbits[act - 1]) {    /* in object */
623                 ma = ob->mat[act - 1];
624         }
625         else {                              /* in data */
626
627                 /* check for inconsistency */
628                 if (*totcolp < ob->totcol)
629                         ob->totcol = *totcolp;
630                 if (act > ob->totcol) act = ob->totcol;
631
632                 matarar = give_matarar(ob);
633                 
634                 if (matarar && *matarar) ma = (*matarar)[act - 1];
635                 else ma = NULL;
636                 
637         }
638         
639         return ma;
640 }
641
642 ID *material_from(Object *ob, short act)
643 {
644
645         if (ob == NULL) return NULL;
646
647         if (ob->totcol == 0) return ob->data;
648         if (act == 0) act = 1;
649
650         if (ob->matbits[act - 1]) return (ID *)ob;
651         else return ob->data;
652 }
653
654 Material *give_node_material(Material *ma)
655 {
656         if (ma && ma->use_nodes && ma->nodetree) {
657                 bNode *node = nodeGetActiveID(ma->nodetree, ID_MA);
658
659                 if (node)
660                         return (Material *)node->id;
661         }
662
663         return NULL;
664 }
665
666 /* GS reads the memory pointed at in a specific ordering. There are,
667  * however two definitions for it. I have jotted them down here, both,
668  * but I think the first one is actually used. The thing is that
669  * big-endian systems might read this the wrong way round. OTOH, we
670  * constructed the IDs that are read out with this macro explicitly as
671  * well. I expect we'll sort it out soon... */
672
673 /* from blendef: */
674 #define GS(a)   (*((short *)(a)))
675
676 /* from misc_util: flip the bytes from x  */
677 /*  #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
678
679 void resize_object_material(Object *ob, const short totcol)
680 {
681         Material **newmatar;
682         char *newmatbits;
683
684         if (totcol == 0) {
685                 if (ob->totcol) {
686                         MEM_freeN(ob->mat);
687                         MEM_freeN(ob->matbits);
688                         ob->mat = NULL;
689                         ob->matbits = NULL;
690                 }
691         }
692         else if (ob->totcol < totcol) {
693                 newmatar = MEM_callocN(sizeof(void *) * totcol, "newmatar");
694                 newmatbits = MEM_callocN(sizeof(char) * totcol, "newmatbits");
695                 if (ob->totcol) {
696                         memcpy(newmatar, ob->mat, sizeof(void *) * ob->totcol);
697                         memcpy(newmatbits, ob->matbits, sizeof(char) * ob->totcol);
698                         MEM_freeN(ob->mat);
699                         MEM_freeN(ob->matbits);
700                 }
701                 ob->mat = newmatar;
702                 ob->matbits = newmatbits;
703         }
704         ob->totcol = totcol;
705         if (ob->totcol && ob->actcol == 0) ob->actcol = 1;
706         if (ob->actcol > ob->totcol) ob->actcol = ob->totcol;
707 }
708
709 void test_object_materials(ID *id)
710 {
711         /* make the ob mat-array same size as 'ob->data' mat-array */
712         Object *ob;
713         short *totcol;
714
715         if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
716                 return;
717         }
718
719         for (ob = G.main->object.first; ob; ob = ob->id.next) {
720                 if (ob->data == id) {
721                         resize_object_material(ob, *totcol);
722                 }
723         }
724 }
725
726 void assign_material_id(ID *id, Material *ma, short act)
727 {
728         Material *mao, **matar, ***matarar;
729         short *totcolp;
730
731         if (act > MAXMAT) return;
732         if (act < 1) act = 1;
733
734         /* prevent crashing when using accidentally */
735         BLI_assert(id->lib == NULL);
736         if (id->lib) return;
737
738         /* test arraylens */
739
740         totcolp = give_totcolp_id(id);
741         matarar = give_matarar_id(id);
742
743         if (totcolp == NULL || matarar == NULL) return;
744
745         if (act > *totcolp) {
746                 matar = MEM_callocN(sizeof(void *) * act, "matarray1");
747
748                 if (*totcolp) {
749                         memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
750                         MEM_freeN(*matarar);
751                 }
752
753                 *matarar = matar;
754                 *totcolp = act;
755         }
756
757         /* in data */
758         mao = (*matarar)[act - 1];
759         if (mao) mao->id.us--;
760         (*matarar)[act - 1] = ma;
761
762         if (ma)
763                 id_us_plus((ID *)ma);
764
765         test_object_materials(id);
766 }
767
768 void assign_material(Object *ob, Material *ma, short act)
769 {
770         Material *mao, **matar, ***matarar;
771         char *matbits;
772         short *totcolp;
773
774         if (act > MAXMAT) return;
775         if (act < 1) act = 1;
776         
777         /* prevent crashing when using accidentally */
778         BLI_assert(ob->id.lib == NULL);
779         if (ob->id.lib) return;
780         
781         /* test arraylens */
782         
783         totcolp = give_totcolp(ob);
784         matarar = give_matarar(ob);
785         
786         if (totcolp == NULL || matarar == NULL) return;
787         
788         if (act > *totcolp) {
789                 matar = MEM_callocN(sizeof(void *) * act, "matarray1");
790
791                 if (*totcolp) {
792                         memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
793                         MEM_freeN(*matarar);
794                 }
795
796                 *matarar = matar;
797                 *totcolp = act;
798         }
799         
800         if (act > ob->totcol) {
801                 matar = MEM_callocN(sizeof(void *) * act, "matarray2");
802                 matbits = MEM_callocN(sizeof(char) * act, "matbits1");
803                 if (ob->totcol) {
804                         memcpy(matar, ob->mat, sizeof(void *) * ob->totcol);
805                         memcpy(matbits, ob->matbits, sizeof(char) * (*totcolp));
806                         MEM_freeN(ob->mat);
807                         MEM_freeN(ob->matbits);
808                 }
809                 ob->mat = matar;
810                 ob->matbits = matbits;
811                 ob->totcol = act;
812
813                 /* copy object/mesh linking, or assign based on userpref */
814                 if (ob->actcol)
815                         ob->matbits[act - 1] = ob->matbits[ob->actcol - 1];
816                 else
817                         ob->matbits[act - 1] = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
818         }
819         
820         /* do it */
821
822         if (ob->matbits[act - 1]) {   /* in object */
823                 mao = ob->mat[act - 1];
824                 if (mao) mao->id.us--;
825                 ob->mat[act - 1] = ma;
826         }
827         else {  /* in data */
828                 mao = (*matarar)[act - 1];
829                 if (mao) mao->id.us--;
830                 (*matarar)[act - 1] = ma;
831         }
832
833         if (ma)
834                 id_us_plus((ID *)ma);
835         test_object_materials(ob->data);
836 }
837
838 /* XXX - this calls many more update calls per object then are needed, could be optimized */
839 void assign_matarar(struct Object *ob, struct Material ***matar, short totcol)
840 {
841         int actcol_orig = ob->actcol;
842         short i;
843
844         while (object_remove_material_slot(ob)) {}
845
846         /* now we have the right number of slots */
847         for (i = 0; i < totcol; i++)
848                 assign_material(ob, (*matar)[i], i + 1);
849
850         if (actcol_orig > ob->totcol)
851                 actcol_orig = ob->totcol;
852
853         ob->actcol = actcol_orig;
854 }
855
856
857 short find_material_index(Object *ob, Material *ma)
858 {
859         Material ***matarar;
860         short a, *totcolp;
861         
862         if (ma == NULL) return 0;
863         
864         totcolp = give_totcolp(ob);
865         matarar = give_matarar(ob);
866         
867         if (totcolp == NULL || matarar == NULL) return 0;
868         
869         for (a = 0; a < *totcolp; a++)
870                 if ((*matarar)[a] == ma)
871                         break;
872         if (a < *totcolp)
873                 return a + 1;
874         return 0;          
875 }
876
877 int object_add_material_slot(Object *ob)
878 {
879         if (ob == NULL) return FALSE;
880         if (ob->totcol >= MAXMAT) return FALSE;
881         
882         assign_material(ob, NULL, ob->totcol + 1);
883         ob->actcol = ob->totcol;
884         return TRUE;
885 }
886
887 static void do_init_render_material(Material *ma, int r_mode, float *amb)
888 {
889         MTex *mtex;
890         int a, needuv = 0, needtang = 0;
891         
892         if (ma->flarec == 0) ma->flarec = 1;
893
894         /* add all texcoflags from mtex, texco and mapto were cleared in advance */
895         for (a = 0; a < MAX_MTEX; a++) {
896                 
897                 /* separate tex switching */
898                 if (ma->septex & (1 << a)) continue;
899
900                 mtex = ma->mtex[a];
901                 if (mtex && mtex->tex && (mtex->tex->type | (mtex->tex->use_nodes && mtex->tex->nodetree) )) {
902                         
903                         ma->texco |= mtex->texco;
904                         ma->mapto |= mtex->mapto;
905
906                         /* always get derivatives for these textures */
907                         if (ELEM(mtex->tex->type, TEX_IMAGE, TEX_ENVMAP)) ma->texco |= TEXCO_OSA;
908                         else if (mtex->texflag & (MTEX_COMPAT_BUMP | MTEX_3TAP_BUMP | MTEX_5TAP_BUMP | MTEX_BICUBIC_BUMP)) ma->texco |= TEXCO_OSA;
909                         
910                         if (ma->texco & (TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM | TEXCO_STRAND | TEXCO_STRESS)) needuv = 1;
911                         else if (ma->texco & (TEXCO_GLOB | TEXCO_UV | TEXCO_OBJECT | TEXCO_SPEED)) needuv = 1;
912                         else if (ma->texco & (TEXCO_LAVECTOR | TEXCO_VIEW | TEXCO_STICKY)) needuv = 1;
913
914                         if ((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT))
915                                 needtang = 1;
916                 }
917         }
918
919         if (needtang) ma->mode |= MA_NORMAP_TANG;
920         else ma->mode &= ~MA_NORMAP_TANG;
921         
922         if (ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
923                 needuv = 1;
924                 if (r_mode & R_OSA) ma->texco |= TEXCO_OSA;     /* for texfaces */
925         }
926         if (needuv) ma->texco |= NEED_UV;
927         
928         /* since the raytracer doesnt recalc O structs for each ray, we have to preset them all */
929         if (r_mode & R_RAYTRACE) {
930                 if ((ma->mode & (MA_RAYMIRROR | MA_SHADOW_TRA)) || ((ma->mode & MA_TRANSP) && (ma->mode & MA_RAYTRANSP))) {
931                         ma->texco |= NEED_UV | TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM;
932                         if (r_mode & R_OSA) ma->texco |= TEXCO_OSA;
933                 }
934         }
935         
936         if (amb) {
937                 ma->ambr = ma->amb * amb[0];
938                 ma->ambg = ma->amb * amb[1];
939                 ma->ambb = ma->amb * amb[2];
940         }       
941         /* will become or-ed result of all node modes */
942         ma->mode_l = ma->mode;
943         ma->mode_l &= ~MA_SHLESS;
944
945         if (ma->strand_surfnor > 0.0f)
946                 ma->mode_l |= MA_STR_SURFDIFF;
947
948         /* parses the geom+tex nodes */
949         if (ma->nodetree && ma->use_nodes)
950                 ntreeShaderGetTexcoMode(ma->nodetree, r_mode, &ma->texco, &ma->mode_l);
951 }
952
953 static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb)
954 {
955         bNode *node;
956         
957         for (node = ntree->nodes.first; node; node = node->next) {
958                 if (node->id) {
959                         if (GS(node->id->name) == ID_MA) {
960                                 Material *ma = (Material *)node->id;
961                                 if (ma != basemat) {
962                                         do_init_render_material(ma, r_mode, amb);
963                                         basemat->texco |= ma->texco;
964                                         basemat->mode_l |= ma->mode_l & ~(MA_TRANSP | MA_ZTRANSP | MA_RAYTRANSP);
965                                 }
966                         }
967                         else if (node->type == NODE_GROUP)
968                                 init_render_nodetree((bNodeTree *)node->id, basemat, r_mode, amb);
969                 }
970         }
971 }
972
973 void init_render_material(Material *mat, int r_mode, float *amb)
974 {
975         
976         do_init_render_material(mat, r_mode, amb);
977         
978         if (mat->nodetree && mat->use_nodes) {
979                 init_render_nodetree(mat->nodetree, mat, r_mode, amb);
980                 
981                 if (!mat->nodetree->execdata)
982                         mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree, 1);
983         }
984 }
985
986 void init_render_materials(Main *bmain, int r_mode, float *amb)
987 {
988         Material *ma;
989         
990         /* clear these flags before going over materials, to make sure they
991          * are cleared only once, otherwise node materials contained in other
992          * node materials can go wrong */
993         for (ma = bmain->mat.first; ma; ma = ma->id.next) {
994                 if (ma->id.us) {
995                         ma->texco = 0;
996                         ma->mapto = 0;
997                 }
998         }
999
1000         /* two steps, first initialize, then or the flags for layers */
1001         for (ma = bmain->mat.first; ma; ma = ma->id.next) {
1002                 /* is_used flag comes back in convertblender.c */
1003                 ma->flag &= ~MA_IS_USED;
1004                 if (ma->id.us) 
1005                         init_render_material(ma, r_mode, amb);
1006         }
1007         
1008         do_init_render_material(&defmaterial, r_mode, amb);
1009 }
1010
1011 /* only needed for nodes now */
1012 void end_render_material(Material *mat)
1013 {
1014         if (mat && mat->nodetree && mat->use_nodes) {
1015                 if (mat->nodetree->execdata)
1016                         ntreeShaderEndExecTree(mat->nodetree->execdata, 1);
1017         }
1018 }
1019
1020 void end_render_materials(Main *bmain)
1021 {
1022         Material *ma;
1023         for (ma = bmain->mat.first; ma; ma = ma->id.next)
1024                 if (ma->id.us) 
1025                         end_render_material(ma);
1026 }
1027
1028 static int material_in_nodetree(bNodeTree *ntree, Material *mat)
1029 {
1030         bNode *node;
1031
1032         for (node = ntree->nodes.first; node; node = node->next) {
1033                 if (node->id) {
1034                         if (GS(node->id->name) == ID_MA) {
1035                                 if (node->id == (ID *)mat) {
1036                                         return 1;
1037                                 }
1038                         }
1039                         else if (node->type == NODE_GROUP) {
1040                                 if (material_in_nodetree((bNodeTree *)node->id, mat)) {
1041                                         return 1;
1042                                 }
1043                         }
1044                 }
1045         }
1046
1047         return 0;
1048 }
1049
1050 int material_in_material(Material *parmat, Material *mat)
1051 {
1052         if (parmat == mat)
1053                 return 1;
1054         else if (parmat->nodetree && parmat->use_nodes)
1055                 return material_in_nodetree(parmat->nodetree, mat);
1056         else
1057                 return 0;
1058 }
1059
1060
1061 /* ****************** */
1062
1063 /* Update drivers for materials in a nodetree */
1064 static void material_node_drivers_update(Scene *scene, bNodeTree *ntree, float ctime)
1065 {
1066         bNode *node;
1067
1068         /* nodetree itself */
1069         if (ntree->adt && ntree->adt->drivers.first) {
1070                 BKE_animsys_evaluate_animdata(scene, &ntree->id, ntree->adt, ctime, ADT_RECALC_DRIVERS);
1071         }
1072         
1073         /* nodes */
1074         for (node = ntree->nodes.first; node; node = node->next) {
1075                 if (node->id) {
1076                         if (GS(node->id->name) == ID_MA) {
1077                                 material_drivers_update(scene, (Material *)node->id, ctime);
1078                         }
1079                         else if (node->type == NODE_GROUP) {
1080                                 material_node_drivers_update(scene, (bNodeTree *)node->id, ctime);
1081                         }
1082                 }
1083         }
1084 }
1085
1086 /* Calculate all drivers for materials 
1087  * FIXME: this is really a terrible method which may result in some things being calculated
1088  * multiple times. However, without proper despgraph support for these things, we are forced
1089  * into this sort of thing...
1090  */
1091 void material_drivers_update(Scene *scene, Material *ma, float ctime)
1092 {
1093         //if (G.f & G_DEBUG)
1094         //      printf("material_drivers_update(%s, %s)\n", scene->id.name, ma->id.name);
1095         
1096         /* Prevent infinite recursion by checking (and tagging the material) as having been visited already
1097          * (see BKE_scene_update_tagged()). This assumes ma->id.flag & LIB_DOIT isn't set by anything else
1098          * in the meantime... [#32017]
1099          */
1100         if (ma->id.flag & LIB_DOIT)
1101                 return;
1102         else
1103                 ma->id.flag |= LIB_DOIT;
1104         
1105         /* material itself */
1106         if (ma->adt && ma->adt->drivers.first) {
1107                 BKE_animsys_evaluate_animdata(scene, &ma->id, ma->adt, ctime, ADT_RECALC_DRIVERS);
1108         }
1109         
1110         /* nodes */
1111         if (ma->nodetree) {
1112                 material_node_drivers_update(scene, ma->nodetree, ctime);
1113         }
1114 }
1115         
1116 /* ****************** */
1117 #if 0 /* UNUSED */
1118 static char colname_array[125][20]= {
1119 "Black", "DarkRed", "HalfRed", "Red", "Red",
1120 "DarkGreen", "DarkOlive", "Brown", "Chocolate", "OrangeRed",
1121 "HalfGreen", "GreenOlive", "DryOlive", "Goldenrod", "DarkOrange",
1122 "LightGreen", "Chartreuse", "YellowGreen", "Yellow", "Gold",
1123 "Green", "LawnGreen", "GreenYellow", "LightOlive", "Yellow",
1124 "DarkBlue", "DarkPurple", "HotPink", "VioletPink", "RedPink",
1125 "SlateGray", "DarkGray", "PalePurple", "IndianRed", "Tomato",
1126 "SeaGreen", "PaleGreen", "GreenKhaki", "LightBrown", "LightSalmon",
1127 "SpringGreen", "PaleGreen", "MediumOlive", "YellowBrown", "LightGold",
1128 "LightGreen", "LightGreen", "LightGreen", "GreenYellow", "PaleYellow",
1129 "HalfBlue", "DarkSky", "HalfMagenta", "VioletRed", "DeepPink",
1130 "SteelBlue", "SkyBlue", "Orchid", "LightHotPink", "HotPink",
1131 "SeaGreen", "SlateGray", "MediumGray", "Burlywood", "LightPink",
1132 "SpringGreen", "Aquamarine", "PaleGreen", "Khaki", "PaleOrange",
1133 "SpringGreen", "SeaGreen", "PaleGreen", "PaleWhite", "YellowWhite",
1134 "LightBlue", "Purple", "MediumOrchid", "Magenta", "Magenta",
1135 "RoyalBlue", "SlateBlue", "MediumOrchid", "Orchid", "Magenta",
1136 "DeepSkyBlue", "LightSteelBlue", "LightSkyBlue", "Violet", "LightPink",
1137 "Cyan", "DarkTurquoise", "SkyBlue", "Gray", "Snow",
1138 "Mint", "Mint", "Aquamarine", "MintCream", "Ivory",
1139 "Blue", "Blue", "DarkMagenta", "DarkOrchid", "Magenta",
1140 "SkyBlue", "RoyalBlue", "LightSlateBlue", "MediumOrchid", "Magenta",
1141 "DodgerBlue", "SteelBlue", "MediumPurple", "PalePurple", "Plum",
1142 "DeepSkyBlue", "PaleBlue", "LightSkyBlue", "PalePurple", "Thistle",
1143 "Cyan", "ColdBlue", "PaleTurquoise", "GhostWhite", "White"
1144 };
1145
1146 void automatname(Material *ma)
1147 {
1148         int nr, r, g, b;
1149         float ref;
1150         
1151         if (ma == NULL) return;
1152         if (ma->mode & MA_SHLESS) ref = 1.0;
1153         else ref = ma->ref;
1154
1155         r = (int)(4.99f * (ref * ma->r));
1156         g = (int)(4.99f * (ref * ma->g));
1157         b = (int)(4.99f * (ref * ma->b));
1158         nr = r + 5 * g + 25 * b;
1159         if (nr > 124) nr = 124;
1160         new_id(&G.main->mat, (ID *)ma, colname_array[nr]);
1161         
1162 }
1163 #endif
1164
1165 int object_remove_material_slot(Object *ob)
1166 {
1167         Material *mao, ***matarar;
1168         Object *obt;
1169         short *totcolp;
1170         short a, actcol;
1171         
1172         if (ob == NULL || ob->totcol == 0) {
1173                 return FALSE;
1174         }
1175
1176         /* this should never happen and used to crash */
1177         if (ob->actcol <= 0) {
1178                 printf("%s: invalid material index %d, report a bug!\n", __func__, ob->actcol);
1179                 BLI_assert(0);
1180                 return FALSE;
1181         }
1182
1183         /* take a mesh/curve/mball as starting point, remove 1 index,
1184          * AND with all objects that share the ob->data
1185          * 
1186          * after that check indices in mesh/curve/mball!!!
1187          */
1188         
1189         totcolp = give_totcolp(ob);
1190         matarar = give_matarar(ob);
1191
1192         if (*matarar == NULL) return FALSE;
1193
1194         /* we delete the actcol */
1195         mao = (*matarar)[ob->actcol - 1];
1196         if (mao) mao->id.us--;
1197         
1198         for (a = ob->actcol; a < ob->totcol; a++)
1199                 (*matarar)[a - 1] = (*matarar)[a];
1200         (*totcolp)--;
1201         
1202         if (*totcolp == 0) {
1203                 MEM_freeN(*matarar);
1204                 *matarar = NULL;
1205         }
1206         
1207         actcol = ob->actcol;
1208         obt = G.main->object.first;
1209         while (obt) {
1210         
1211                 if (obt->data == ob->data) {
1212                         
1213                         /* WATCH IT: do not use actcol from ob or from obt (can become zero) */
1214                         mao = obt->mat[actcol - 1];
1215                         if (mao) mao->id.us--;
1216                 
1217                         for (a = actcol; a < obt->totcol; a++) {
1218                                 obt->mat[a - 1] = obt->mat[a];
1219                                 obt->matbits[a - 1] = obt->matbits[a];
1220                         }
1221                         obt->totcol--;
1222                         if (obt->actcol > obt->totcol) obt->actcol = obt->totcol;
1223                         
1224                         if (obt->totcol == 0) {
1225                                 MEM_freeN(obt->mat);
1226                                 MEM_freeN(obt->matbits);
1227                                 obt->mat = NULL;
1228                                 obt->matbits = NULL;
1229                         }
1230                 }
1231                 obt = obt->id.next;
1232         }
1233
1234         /* check indices from mesh */
1235         if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
1236                 data_delete_material_index_id((ID *)ob->data, actcol - 1);
1237                 BKE_displist_free(&ob->disp);
1238         }
1239
1240         return TRUE;
1241 }
1242
1243
1244 /* r_col = current value, col = new value, (fac == 0) is no change */
1245 void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
1246 {
1247         float tmp, facm = 1.0f - fac;
1248         
1249         switch (type) {
1250                 case MA_RAMP_BLEND:
1251                         r_col[0] = facm * (r_col[0]) + fac * col[0];
1252                         r_col[1] = facm * (r_col[1]) + fac * col[1];
1253                         r_col[2] = facm * (r_col[2]) + fac * col[2];
1254                         break;
1255                 case MA_RAMP_ADD:
1256                         r_col[0] += fac * col[0];
1257                         r_col[1] += fac * col[1];
1258                         r_col[2] += fac * col[2];
1259                         break;
1260                 case MA_RAMP_MULT:
1261                         r_col[0] *= (facm + fac * col[0]);
1262                         r_col[1] *= (facm + fac * col[1]);
1263                         r_col[2] *= (facm + fac * col[2]);
1264                         break;
1265                 case MA_RAMP_SCREEN:
1266                         r_col[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1267                         r_col[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1268                         r_col[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1269                         break;
1270                 case MA_RAMP_OVERLAY:
1271                         if (r_col[0] < 0.5f)
1272                                 r_col[0] *= (facm + 2.0f * fac * col[0]);
1273                         else
1274                                 r_col[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1275                         if (r_col[1] < 0.5f)
1276                                 r_col[1] *= (facm + 2.0f * fac * col[1]);
1277                         else
1278                                 r_col[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1279                         if (r_col[2] < 0.5f)
1280                                 r_col[2] *= (facm + 2.0f * fac * col[2]);
1281                         else
1282                                 r_col[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1283                         break;
1284                 case MA_RAMP_SUB:
1285                         r_col[0] -= fac * col[0];
1286                         r_col[1] -= fac * col[1];
1287                         r_col[2] -= fac * col[2];
1288                         break;
1289                 case MA_RAMP_DIV:
1290                         if (col[0] != 0.0f)
1291                                 r_col[0] = facm * (r_col[0]) + fac * (r_col[0]) / col[0];
1292                         if (col[1] != 0.0f)
1293                                 r_col[1] = facm * (r_col[1]) + fac * (r_col[1]) / col[1];
1294                         if (col[2] != 0.0f)
1295                                 r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2];
1296                         break;
1297                 case MA_RAMP_DIFF:
1298                         r_col[0] = facm * (r_col[0]) + fac *fabsf(r_col[0] - col[0]);
1299                         r_col[1] = facm * (r_col[1]) + fac *fabsf(r_col[1] - col[1]);
1300                         r_col[2] = facm * (r_col[2]) + fac *fabsf(r_col[2] - col[2]);
1301                         break;
1302                 case MA_RAMP_DARK:
1303                         tmp = col[0] + ((1 - col[0]) * facm);
1304                         if (tmp < r_col[0]) r_col[0] = tmp;
1305                         tmp = col[1] + ((1 - col[1]) * facm);
1306                         if (tmp < r_col[1]) r_col[1] = tmp;
1307                         tmp = col[2] + ((1 - col[2]) * facm);
1308                         if (tmp < r_col[2]) r_col[2] = tmp;
1309                         break;
1310                 case MA_RAMP_LIGHT:
1311                         tmp = fac * col[0];
1312                         if (tmp > r_col[0]) r_col[0] = tmp;
1313                         tmp = fac * col[1];
1314                         if (tmp > r_col[1]) r_col[1] = tmp;
1315                         tmp = fac * col[2];
1316                         if (tmp > r_col[2]) r_col[2] = tmp;
1317                         break;
1318                 case MA_RAMP_DODGE:
1319                         if (r_col[0] != 0.0f) {
1320                                 tmp = 1.0f - fac * col[0];
1321                                 if (tmp <= 0.0f)
1322                                         r_col[0] = 1.0f;
1323                                 else if ((tmp = (r_col[0]) / tmp) > 1.0f)
1324                                         r_col[0] = 1.0f;
1325                                 else
1326                                         r_col[0] = tmp;
1327                         }
1328                         if (r_col[1] != 0.0f) {
1329                                 tmp = 1.0f - fac * col[1];
1330                                 if (tmp <= 0.0f)
1331                                         r_col[1] = 1.0f;
1332                                 else if ((tmp = (r_col[1]) / tmp) > 1.0f)
1333                                         r_col[1] = 1.0f;
1334                                 else
1335                                         r_col[1] = tmp;
1336                         }
1337                         if (r_col[2] != 0.0f) {
1338                                 tmp = 1.0f - fac * col[2];
1339                                 if (tmp <= 0.0f)
1340                                         r_col[2] = 1.0f;
1341                                 else if ((tmp = (r_col[2]) / tmp) > 1.0f)
1342                                         r_col[2] = 1.0f;
1343                                 else
1344                                         r_col[2] = tmp;
1345                         }
1346                         break;
1347                 case MA_RAMP_BURN:
1348                         tmp = facm + fac * col[0];
1349
1350                         if (tmp <= 0.0f)
1351                                 r_col[0] = 0.0f;
1352                         else if ((tmp = (1.0f - (1.0f - (r_col[0])) / tmp)) < 0.0f)
1353                                 r_col[0] = 0.0f;
1354                         else if (tmp > 1.0f)
1355                                 r_col[0] = 1.0f;
1356                         else
1357                                 r_col[0] = tmp;
1358
1359                         tmp = facm + fac * col[1];
1360                         if (tmp <= 0.0f)
1361                                 r_col[1] = 0.0f;
1362                         else if ((tmp = (1.0f - (1.0f - (r_col[1])) / tmp)) < 0.0f)
1363                                 r_col[1] = 0.0f;
1364                         else if (tmp > 1.0f)
1365                                 r_col[1] = 1.0f;
1366                         else
1367                                 r_col[1] = tmp;
1368
1369                         tmp = facm + fac * col[2];
1370                         if (tmp <= 0.0f)
1371                                 r_col[2] = 0.0f;
1372                         else if ((tmp = (1.0f - (1.0f - (r_col[2])) / tmp)) < 0.0f)
1373                                 r_col[2] = 0.0f;
1374                         else if (tmp > 1.0f)
1375                                 r_col[2] = 1.0f;
1376                         else
1377                                 r_col[2] = tmp;
1378                         break;
1379                 case MA_RAMP_HUE:
1380                 {
1381                         float rH, rS, rV;
1382                         float colH, colS, colV;
1383                         float tmpr, tmpg, tmpb;
1384                         rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1385                         if (colS != 0) {
1386                                 rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1387                                 hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb);
1388                                 r_col[0] = facm * (r_col[0]) + fac * tmpr;
1389                                 r_col[1] = facm * (r_col[1]) + fac * tmpg;
1390                                 r_col[2] = facm * (r_col[2]) + fac * tmpb;
1391                         }
1392                 }
1393                 break;
1394                 case MA_RAMP_SAT:
1395                 {
1396                         float rH, rS, rV;
1397                         float colH, colS, colV;
1398                         rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1399                         if (rS != 0) {
1400                                 rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1401                                 hsv_to_rgb(rH, (facm * rS + fac * colS), rV, r_col + 0, r_col + 1, r_col + 2);
1402                         }
1403                 }
1404                 break;
1405                 case MA_RAMP_VAL:
1406                 {
1407                         float rH, rS, rV;
1408                         float colH, colS, colV;
1409                         rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1410                         rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1411                         hsv_to_rgb(rH, rS, (facm * rV + fac * colV), r_col + 0, r_col + 1, r_col + 2);
1412                 }
1413                 break;
1414                 case MA_RAMP_COLOR:
1415                 {
1416                         float rH, rS, rV;
1417                         float colH, colS, colV;
1418                         float tmpr, tmpg, tmpb;
1419                         rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1420                         if (colS != 0) {
1421                                 rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1422                                 hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb);
1423                                 r_col[0] = facm * (r_col[0]) + fac * tmpr;
1424                                 r_col[1] = facm * (r_col[1]) + fac * tmpg;
1425                                 r_col[2] = facm * (r_col[2]) + fac * tmpb;
1426                         }
1427                 }
1428                 break;
1429                 case MA_RAMP_SOFT:
1430                 {
1431                         float scr, scg, scb;
1432
1433                         /* first calculate non-fac based Screen mix */
1434                         scr = 1.0f - (1.0f - col[0]) * (1.0f - r_col[0]);
1435                         scg = 1.0f - (1.0f - col[1]) * (1.0f - r_col[1]);
1436                         scb = 1.0f - (1.0f - col[2]) * (1.0f - r_col[2]);
1437
1438                         r_col[0] = facm * (r_col[0]) + fac * (((1.0f - r_col[0]) * col[0] * (r_col[0])) + (r_col[0] * scr));
1439                         r_col[1] = facm * (r_col[1]) + fac * (((1.0f - r_col[1]) * col[1] * (r_col[1])) + (r_col[1] * scg));
1440                         r_col[2] = facm * (r_col[2]) + fac * (((1.0f - r_col[2]) * col[2] * (r_col[2])) + (r_col[2] * scb));
1441                 }
1442                 break;
1443                 case MA_RAMP_LINEAR:
1444                         if (col[0] > 0.5f)
1445                                 r_col[0] = r_col[0] + fac * (2.0f * (col[0] - 0.5f));
1446                         else
1447                                 r_col[0] = r_col[0] + fac * (2.0f * (col[0]) - 1.0f);
1448                         if (col[1] > 0.5f)
1449                                 r_col[1] = r_col[1] + fac * (2.0f * (col[1] - 0.5f));
1450                         else
1451                                 r_col[1] = r_col[1] + fac * (2.0f * (col[1]) - 1.0f);
1452                         if (col[2] > 0.5f)
1453                                 r_col[2] = r_col[2] + fac * (2.0f * (col[2] - 0.5f));
1454                         else
1455                                 r_col[2] = r_col[2] + fac * (2.0f * (col[2]) - 1.0f);
1456                         break;
1457         }
1458 }
1459
1460 /* copy/paste buffer, if we had a propper py api that would be better */
1461 static Material matcopybuf;
1462 static short matcopied = 0;
1463
1464 void clear_matcopybuf(void)
1465 {
1466         memset(&matcopybuf, 0, sizeof(Material));
1467         matcopied = 0;
1468 }
1469
1470 void free_matcopybuf(void)
1471 {
1472         int a;
1473
1474         for (a = 0; a < MAX_MTEX; a++) {
1475                 if (matcopybuf.mtex[a]) {
1476                         MEM_freeN(matcopybuf.mtex[a]);
1477                         matcopybuf.mtex[a] = NULL;
1478                 }
1479         }
1480
1481         if (matcopybuf.ramp_col) MEM_freeN(matcopybuf.ramp_col);
1482         if (matcopybuf.ramp_spec) MEM_freeN(matcopybuf.ramp_spec);
1483
1484         matcopybuf.ramp_col = NULL;
1485         matcopybuf.ramp_spec = NULL;
1486
1487         if (matcopybuf.nodetree) {
1488                 ntreeFreeTree(matcopybuf.nodetree);
1489                 MEM_freeN(matcopybuf.nodetree);
1490                 matcopybuf.nodetree = NULL;
1491         }
1492
1493         matcopied = 0;
1494 }
1495
1496 void copy_matcopybuf(Material *ma)
1497 {
1498         int a;
1499         MTex *mtex;
1500
1501         if (matcopied)
1502                 free_matcopybuf();
1503
1504         memcpy(&matcopybuf, ma, sizeof(Material));
1505         if (matcopybuf.ramp_col) matcopybuf.ramp_col = MEM_dupallocN(matcopybuf.ramp_col);
1506         if (matcopybuf.ramp_spec) matcopybuf.ramp_spec = MEM_dupallocN(matcopybuf.ramp_spec);
1507
1508         for (a = 0; a < MAX_MTEX; a++) {
1509                 mtex = matcopybuf.mtex[a];
1510                 if (mtex) {
1511                         matcopybuf.mtex[a] = MEM_dupallocN(mtex);
1512                 }
1513         }
1514         matcopybuf.nodetree = ntreeCopyTree(ma->nodetree);
1515         matcopybuf.preview = NULL;
1516         matcopybuf.gpumaterial.first = matcopybuf.gpumaterial.last = NULL;
1517         matcopied = 1;
1518 }
1519
1520 void paste_matcopybuf(Material *ma)
1521 {
1522         int a;
1523         MTex *mtex;
1524         ID id;
1525
1526         if (matcopied == 0)
1527                 return;
1528         /* free current mat */
1529         if (ma->ramp_col) MEM_freeN(ma->ramp_col);
1530         if (ma->ramp_spec) MEM_freeN(ma->ramp_spec);
1531         for (a = 0; a < MAX_MTEX; a++) {
1532                 mtex = ma->mtex[a];
1533                 if (mtex && mtex->tex) mtex->tex->id.us--;
1534                 if (mtex) MEM_freeN(mtex);
1535         }
1536
1537         if (ma->nodetree) {
1538                 ntreeFreeTree(ma->nodetree);
1539                 MEM_freeN(ma->nodetree);
1540         }
1541
1542         GPU_material_free(ma);
1543
1544         id = (ma->id);
1545         memcpy(ma, &matcopybuf, sizeof(Material));
1546         (ma->id) = id;
1547
1548         if (matcopybuf.ramp_col) ma->ramp_col = MEM_dupallocN(matcopybuf.ramp_col);
1549         if (matcopybuf.ramp_spec) ma->ramp_spec = MEM_dupallocN(matcopybuf.ramp_spec);
1550
1551         for (a = 0; a < MAX_MTEX; a++) {
1552                 mtex = ma->mtex[a];
1553                 if (mtex) {
1554                         ma->mtex[a] = MEM_dupallocN(mtex);
1555                         if (mtex->tex) id_us_plus((ID *)mtex->tex);
1556                 }
1557         }
1558
1559         ma->nodetree = ntreeCopyTree(matcopybuf.nodetree);
1560 }
1561
1562
1563 /*********************** texface to material convert functions **********************/
1564 /* encode all the TF information into a single int */
1565 static int encode_tfaceflag(MTFace *tf, int convertall)
1566 {
1567         /* calculate the flag */
1568         int flag = tf->mode;
1569
1570         /* options that change the material offline render */   
1571         if (!convertall) {
1572                 flag &= ~TF_OBCOL;
1573         }
1574
1575         /* clean flags that are not being converted */
1576         flag &= ~TF_TEX;
1577         flag &= ~TF_SHAREDVERT;
1578         flag &= ~TF_SHAREDCOL;
1579         flag &= ~TF_CONVERTED;
1580
1581         /* light tface flag is ignored in GLSL mode */
1582         flag &= ~TF_LIGHT;
1583         
1584         /* 15 is how big the flag can be - hardcoded here and in decode_tfaceflag() */
1585         flag |= tf->transp << 15;
1586         
1587         /* increase 1 so flag 0 is different than no flag yet */
1588         return flag + 1;
1589 }
1590
1591 /* set the material options based in the tface flag */
1592 static void decode_tfaceflag(Material *ma, int flag, int convertall)
1593 {
1594         int alphablend; 
1595         GameSettings *game = &ma->game;
1596
1597         /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
1598         flag -= 1;
1599
1600         alphablend = flag >> 15; //encoded in the encode_tfaceflag function
1601         (*game).flag = 0;
1602         
1603         /* General Material Options */
1604         if ((flag & TF_DYNAMIC) == 0) (*game).flag    |= GEMAT_NOPHYSICS;
1605         
1606         /* Material Offline Rendering Properties */
1607         if (convertall) {
1608                 if (flag & TF_OBCOL) ma->shade_flag |= MA_OBCOLOR;
1609         }
1610         
1611         /* Special Face Properties */
1612         if ((flag & TF_TWOSIDE) == 0) (*game).flag |= GEMAT_BACKCULL;
1613         if (flag & TF_INVISIBLE) (*game).flag |= GEMAT_INVISIBLE;
1614         if (flag & TF_BMFONT) (*game).flag |= GEMAT_TEXT;
1615         
1616         /* Face Orientation */
1617         if (flag & TF_BILLBOARD) (*game).face_orientation |= GEMAT_HALO;
1618         else if (flag & TF_BILLBOARD2) (*game).face_orientation |= GEMAT_BILLBOARD;
1619         else if (flag & TF_SHADOW) (*game).face_orientation |= GEMAT_SHADOW;
1620         
1621         /* Alpha Blend */
1622         if (flag & TF_ALPHASORT && ELEM(alphablend, TF_ALPHA, TF_ADD)) (*game).alpha_blend = GEMAT_ALPHA_SORT;
1623         else if (alphablend & TF_ALPHA) (*game).alpha_blend = GEMAT_ALPHA;
1624         else if (alphablend & TF_ADD) (*game).alpha_blend = GEMAT_ADD;
1625         else if (alphablend & TF_CLIP) (*game).alpha_blend = GEMAT_CLIP;
1626 }
1627
1628 /* boolean check to see if the mesh needs a material */
1629 static int check_tfaceneedmaterial(int flag)
1630 {
1631         /* check if the flags we have are not deprecated != than default material options
1632          * also if only flags are visible and collision see if all objects using this mesh have this option in physics */
1633
1634         /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
1635         flag -= 1;
1636
1637         /* deprecated flags */
1638         flag &= ~TF_OBCOL;
1639         flag &= ~TF_SHAREDVERT;
1640         flag &= ~TF_SHAREDCOL;
1641
1642         /* light tface flag is ignored in GLSL mode */
1643         flag &= ~TF_LIGHT;
1644         
1645         /* automatic detected if tex image has alpha */
1646         flag &= ~(TF_ALPHA << 15);
1647         /* automatic detected if using texture */
1648         flag &= ~TF_TEX;
1649
1650         /* settings for the default NoMaterial */
1651         if (flag == TF_DYNAMIC)
1652                 return 0;
1653
1654         else
1655                 return 1;
1656 }
1657
1658 /* return number of digits of an integer */
1659 /* XXX to be optmized or replaced by an equivalent blender internal function */
1660 static int integer_getdigits(int number)
1661 {
1662         int i = 0;
1663         if (number == 0) return 1;
1664
1665         while (number != 0) {
1666                 number = (int)(number / 10);
1667                 i++;
1668         }
1669         return i;
1670 }
1671
1672 static void calculate_tface_materialname(char *matname, char *newname, int flag)
1673 {
1674         /* if flag has only light and collision and material matches those values
1675          * you can do strcpy(name, mat_name);
1676          * otherwise do: */
1677         int digits = integer_getdigits(flag);
1678         /* clamp the old name, remove the MA prefix and add the .TF.flag suffix
1679          * e.g. matname = "MALoooooooooooooongName"; newname = "Loooooooooooooon.TF.2" */
1680         BLI_snprintf(newname, MAX_ID_NAME, "%.*s.TF.%0*d", MAX_ID_NAME - (digits + 5), matname, digits, flag);
1681 }
1682
1683 /* returns -1 if no match */
1684 static short mesh_getmaterialnumber(Mesh *me, Material *ma)
1685 {
1686         short a;
1687
1688         for (a = 0; a < me->totcol; a++) {
1689                 if (me->mat[a] == ma) {
1690                         return a;
1691                 }
1692         }
1693
1694         return -1;
1695 }
1696
1697 /* append material */
1698 static short mesh_addmaterial(Mesh *me, Material *ma)
1699 {
1700         material_append_id(&me->id, NULL);
1701         me->mat[me->totcol - 1] = ma;
1702
1703         id_us_plus(&ma->id);
1704
1705         return me->totcol - 1;
1706 }
1707
1708 static void set_facetexture_flags(Material *ma, Image *image)
1709 {
1710         if (image) {
1711                 ma->mode |= MA_FACETEXTURE;
1712                 /* we could check if the texture has alpha, but then more meshes sharing the same
1713                  * material may need it. Let's make it simple. */
1714                 if (BKE_image_has_alpha(image))
1715                         ma->mode |= MA_FACETEXTURE_ALPHA;
1716         }
1717 }
1718
1719 /* returns material number */
1720 static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
1721 {
1722         Material *ma;
1723         char idname[MAX_ID_NAME];
1724         short mat_nr = -1;
1725         
1726         /* new material, the name uses the flag*/
1727         BLI_snprintf(idname, sizeof(idname), "MAMaterial.TF.%0*d", integer_getdigits(flag), flag);
1728
1729         if ((ma = BLI_findstring(&main->mat, idname + 2, offsetof(ID, name) + 2))) {
1730                 mat_nr = mesh_getmaterialnumber(me, ma);
1731                 /* assign the material to the mesh */
1732                 if (mat_nr == -1) mat_nr = mesh_addmaterial(me, ma);
1733
1734                 /* if needed set "Face Textures [Alpha]" Material options */
1735                 set_facetexture_flags(ma, tf->tpage);
1736         }
1737         /* create a new material */
1738         else {
1739                 ma = BKE_material_add(idname + 2);
1740
1741                 if (ma) {
1742                         printf("TexFace Convert: Material \"%s\" created.\n", idname + 2);
1743                         mat_nr = mesh_addmaterial(me, ma);
1744                         
1745                         /* if needed set "Face Textures [Alpha]" Material options */
1746                         set_facetexture_flags(ma, tf->tpage);
1747
1748                         decode_tfaceflag(ma, flag, 1);
1749                         /* the final decoding will happen after, outside the main loop
1750                          * for now store the flag into the material and change light/tex/collision
1751                          * store the flag as a negative number */
1752                         ma->game.flag = -flag;
1753                         id_us_min((ID *)ma);    
1754                 }
1755                 else printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
1756         }
1757
1758         /* set as converted, no need to go bad to this face */
1759         tf->mode |= TF_CONVERTED;       
1760         return mat_nr;
1761 }
1762
1763 /* Function to fully convert materials */
1764 static void convert_tfacematerial(Main *main, Material *ma)
1765 {
1766         Mesh *me;
1767         Material *mat_new;
1768         MFace *mf;
1769         MTFace *tf;
1770         int flag, index;
1771         int a;
1772         short mat_nr;
1773         CustomDataLayer *cdl;
1774         char idname[MAX_ID_NAME];
1775
1776         for (me = main->mesh.first; me; me = me->id.next) {
1777                 /* check if this mesh uses this material */
1778                 for (a = 0; a < me->totcol; a++)
1779                         if (me->mat[a] == ma) break;
1780                         
1781                 /* no material found */
1782                 if (a == me->totcol) continue;
1783
1784                 /* get the active tface layer */
1785                 index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
1786                 cdl = (index == -1) ? NULL : &me->fdata.layers[index];
1787                 if (!cdl) continue;
1788
1789                 /* loop over all the faces and stop at the ones that use the material*/
1790                 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
1791                         if (me->mat[mf->mat_nr] != ma) continue;
1792
1793                         /* texface data for this face */
1794                         tf = ((MTFace *)cdl->data) + a;
1795                         flag = encode_tfaceflag(tf, 1);
1796
1797                         /* the name of the new material */
1798                         calculate_tface_materialname(ma->id.name, (char *)&idname, flag);
1799
1800                         if ((mat_new = BLI_findstring(&main->mat, idname + 2, offsetof(ID, name) + 2))) {
1801                                 /* material already existent, see if the mesh has it */
1802                                 mat_nr = mesh_getmaterialnumber(me, mat_new);
1803                                 /* material is not in the mesh, add it */
1804                                 if (mat_nr == -1) mat_nr = mesh_addmaterial(me, mat_new);
1805                         }
1806                         /* create a new material */
1807                         else {
1808                                 mat_new = BKE_material_copy(ma);
1809                                 if (mat_new) {
1810                                         /* rename the material*/
1811                                         strcpy(mat_new->id.name, idname);
1812                                         id_us_min((ID *)mat_new);       
1813
1814                                         mat_nr = mesh_addmaterial(me, mat_new);
1815                                         decode_tfaceflag(mat_new, flag, 1);
1816                                 }
1817                                 else {
1818                                         printf("Error: Unable to create Material \"%s\" for Mesh \"%s.", idname + 2, me->id.name + 2);
1819                                         mat_nr = mf->mat_nr;
1820                                         continue;
1821                                 }
1822                         }
1823                         
1824                         /* if the material has a texture but no texture channel
1825                          * set "Face Textures [Alpha]" Material options 
1826                          * actually we need to run it always, because of old behavior
1827                          * of using face texture if any texture channel was present (multitex) */
1828                         //if ((!mat_new->mtex[0]) && (!mat_new->mtex[0]->tex))
1829                         set_facetexture_flags(mat_new, tf->tpage);
1830
1831                         /* set the material number to the face*/
1832                         mf->mat_nr = mat_nr;
1833                 }
1834                 /* remove material from mesh */
1835                 for (a = 0; a < me->totcol; )
1836                         if (me->mat[a] == ma) material_pop_id(&me->id, a, 1); else a++;
1837         }
1838 }
1839
1840
1841 #define MAT_BGE_DISPUTED -99999
1842
1843 int do_version_tface(Main *main, int fileload)
1844 {
1845         Mesh *me;
1846         Material *ma;
1847         MFace *mf;
1848         MTFace *tf;
1849         CustomDataLayer *cdl;
1850         int a;
1851         int flag;
1852         int index;
1853
1854         /* sometimes mesh has no materials but will need a new one. In those
1855          * cases we need to ignore the mf->mat_nr and only look at the face
1856          * mode because it can be zero as uninitialized or the 1st created material
1857          */
1858         int nomaterialslots;
1859
1860         /* alert to user to check the console */
1861         int nowarning = 1;
1862
1863         /* mark all the materials to conversion with a flag
1864          * if there is tface create a complete flag for that storing in flag
1865          * if there is tface and flag > 0: creates a new flag based on this face
1866          * if flags are different set flag to -1  
1867          */
1868         
1869         /* 1st part: marking mesh materials to update */
1870         for (me = main->mesh.first; me; me = me->id.next) {
1871                 if (me->id.lib) continue;
1872
1873                 /* get the active tface layer */
1874                 index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
1875                 cdl = (index == -1) ? NULL : &me->fdata.layers[index];
1876                 if (!cdl) continue;
1877
1878                 nomaterialslots = (me->totcol == 0 ? 1 : 0);
1879                 
1880                 /* loop over all the faces*/
1881                 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
1882                         /* texface data for this face */
1883                         tf = ((MTFace *)cdl->data) + a;
1884
1885                         /* conversion should happen only once */
1886                         if (fileload)
1887                                 tf->mode &= ~TF_CONVERTED;
1888                         else {
1889                                 if ((tf->mode & TF_CONVERTED)) continue;
1890                                 else tf->mode |= TF_CONVERTED;
1891                         }
1892                         
1893                         /* no material slots */
1894                         if (nomaterialslots) {
1895                                 flag = encode_tfaceflag(tf, 1);
1896                                 
1897                                 /* create/find a new material and assign to the face */
1898                                 if (check_tfaceneedmaterial(flag)) {
1899                                         mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
1900                                 }
1901                                 /* else mark them as no-material to be reverted to 0 later */
1902                                 else {
1903                                         mf->mat_nr = -1;
1904                                 }
1905                         }
1906                         else if (mf->mat_nr < me->totcol) {
1907                                 ma = me->mat[mf->mat_nr];
1908                                 
1909                                 /* no material create one if necessary */
1910                                 if (!ma) {
1911                                         /* find a new material and assign to the face */
1912                                         flag = encode_tfaceflag(tf, 1);
1913
1914                                         /* create/find a new material and assign to the face */
1915                                         if (check_tfaceneedmaterial(flag))
1916                                                 mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
1917
1918                                         continue;
1919                                 }
1920
1921                                 /* we can't read from this if it comes from a library,
1922                                  * at doversion time: direct_link might not have happened on it,
1923                                  * so ma->mtex is not pointing to valid memory yet.
1924                                  * later we could, but it's better not */
1925                                 else if (ma->id.lib)
1926                                         continue;
1927                                 
1928                                 /* material already marked as disputed */
1929                                 else if (ma->game.flag == MAT_BGE_DISPUTED)
1930                                         continue;
1931
1932                                 /* found a material */
1933                                 else {
1934                                         flag = encode_tfaceflag(tf, ((fileload) ? 0 : 1));
1935
1936                                         /* first time changing this material */
1937                                         if (ma->game.flag == 0)
1938                                                 ma->game.flag = -flag;
1939                         
1940                                         /* mark material as disputed */
1941                                         else if (ma->game.flag != -flag) {
1942                                                 ma->game.flag = MAT_BGE_DISPUTED;
1943                                                 continue;
1944                                         }
1945                         
1946                                         /* material ok so far */
1947                                         else {
1948                                                 ma->game.flag = -flag;
1949                                                 
1950                                                 /* some people uses multitexture with TexFace by creating a texture
1951                                                  * channel which not necessarily the tf->tpage image. But the game engine
1952                                                  * was enabling it. Now it's required to set "Face Texture [Alpha] in the
1953                                                  * material settings. */
1954                                                 if (!fileload)
1955                                                         set_facetexture_flags(ma, tf->tpage);
1956                                         }
1957                                 }
1958                         }
1959                         else {
1960                                 continue;
1961                         }
1962                 }
1963
1964                 /* if we didn't have material slot and now we do, we need to
1965                  * make sure the materials are correct */
1966                 if (nomaterialslots) {
1967                         if (me->totcol > 0) {
1968                                 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
1969                                         if (mf->mat_nr == -1) {
1970                                                 /* texface data for this face */
1971                                                 tf = ((MTFace *)cdl->data) + a;
1972                                                 mf->mat_nr = convert_tfacenomaterial(main, me, tf, encode_tfaceflag(tf, 1));
1973                                         }
1974                                 }
1975                         }
1976                         else {
1977                                 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
1978                                         mf->mat_nr = 0;
1979                                 }
1980                         }
1981                 }
1982
1983         }
1984         
1985         /* 2nd part - conversion */
1986         /* skip library files */
1987
1988         /* we shouldn't loop through the materials created in the loop. make the loop stop at its original length) */
1989         for (ma = main->mat.first, a = 0; ma; ma = ma->id.next, a++) {
1990                 if (ma->id.lib) continue;
1991
1992                 /* disputed material */
1993                 if (ma->game.flag == MAT_BGE_DISPUTED) {
1994                         ma->game.flag = 0;
1995                         if (fileload) {
1996                                 printf("Warning: material \"%s\" skipped - to convert old game texface to material go to the Help menu.\n", ma->id.name + 2);
1997                                 nowarning = 0;
1998                         }
1999                         else
2000                                 convert_tfacematerial(main, ma);
2001                         continue;       
2002                 }
2003         
2004                 /* no conflicts in this material - 90% of cases
2005                  * convert from tface system to material */
2006                 else if (ma->game.flag < 0) {
2007                         decode_tfaceflag(ma, -(ma->game.flag), 1);
2008
2009                         /* material is good make sure all faces using
2010                          * this material are set to converted */
2011                         if (fileload) {
2012                                 for (me = main->mesh.first; me; me = me->id.next) {
2013                                         /* check if this mesh uses this material */
2014                                         for (a = 0; a < me->totcol; a++)
2015                                                 if (me->mat[a] == ma) break;
2016                                                 
2017                                         /* no material found */
2018                                         if (a == me->totcol) continue;
2019                         
2020                                         /* get the active tface layer */
2021                                         index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
2022                                         cdl = (index == -1) ? NULL : &me->fdata.layers[index];
2023                                         if (!cdl) continue;
2024                         
2025                                         /* loop over all the faces and stop at the ones that use the material*/
2026                                         for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
2027                                                 if (me->mat[mf->mat_nr] == ma) {
2028                                                         /* texface data for this face */
2029                                                         tf = ((MTFace *)cdl->data) + a;
2030                                                         tf->mode |= TF_CONVERTED;
2031                                                 }
2032                                         }
2033                                 }
2034                         }
2035                 }
2036                 /* material is not used by faces with texface
2037                  * set the default flag - do it only once */
2038                 else {
2039                         if (fileload) {
2040                                 ma->game.flag = GEMAT_BACKCULL;
2041                         }
2042                 }
2043         }
2044
2045         return nowarning;
2046 }
2047