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