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