2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/material.c
37 #include "MEM_guardedalloc.h"
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"
47 #include "DNA_meta_types.h"
48 #include "DNA_node_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_scene_types.h"
53 #include "BLI_listbase.h"
54 #include "BLI_utildefines.h"
55 #include "BLI_string.h"
57 #include "BKE_animsys.h"
58 #include "BKE_displist.h"
59 #include "BKE_global.h"
60 #include "BKE_icons.h"
61 #include "BKE_image.h"
62 #include "BKE_library.h"
64 #include "BKE_material.h"
66 #include "BKE_scene.h"
68 #include "BKE_curve.h"
70 #include "GPU_material.h"
72 /* used in UI and render */
75 /* called on startup, creator.c */
76 void init_def_material(void)
78 init_material(&defmaterial);
81 /* not material itself */
82 void BKE_material_free(Material *ma)
84 BKE_material_free_ex(ma, true);
87 /* not material itself */
88 void BKE_material_free_ex(Material *ma, bool do_id_user)
93 for (a = 0; a < MAX_MTEX; a++) {
95 if (do_id_user && mtex && mtex->tex) mtex->tex->id.us--;
96 if (mtex) MEM_freeN(mtex);
99 if (ma->ramp_col) MEM_freeN(ma->ramp_col);
100 if (ma->ramp_spec) MEM_freeN(ma->ramp_spec);
102 BKE_animdata_free((ID *)ma);
105 BKE_previewimg_free(&ma->preview);
106 BKE_icon_delete((struct ID *)ma);
109 /* is no lib link block, but material extension */
111 ntreeFreeTree_ex(ma->nodetree, do_id_user);
112 MEM_freeN(ma->nodetree);
115 if (ma->texpaintslot)
116 MEM_freeN(ma->texpaintslot);
118 if (ma->gpumaterial.first)
119 GPU_material_free(&ma->gpumaterial);
122 void init_material(Material *ma)
124 ma->r = ma->g = ma->b = ma->ref = 0.8;
125 ma->specr = ma->specg = ma->specb = 1.0;
126 ma->mirr = ma->mirg = ma->mirb = 1.0;
130 ma->spec = ma->hasize = 0.5;
132 ma->starc = ma->ringc = 4;
135 ma->flaresize = ma->subsize = 1.0;
148 ma->strand_sta = ma->strand_end = 1.0f;
152 ma->ray_depth_tra = 2;
153 ma->fresnel_mir = 0.0;
154 ma->fresnel_tra = 0.0;
155 ma->fresnel_tra_i = 1.25;
156 ma->fresnel_mir_i = 1.25;
158 ma->tx_falloff = 1.0;
159 ma->shad_alpha = 1.0f;
162 ma->gloss_mir = ma->gloss_tra = 1.0;
163 ma->samp_gloss_mir = ma->samp_gloss_tra = 18;
164 ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005;
166 ma->fadeto_mir = MA_RAYMIR_FADETOSKY;
168 ma->rampfac_col = 1.0;
169 ma->rampfac_spec = 1.0;
170 ma->pr_lamp = 3; /* two lamps, is bits */
171 ma->pr_type = MA_SPHERE;
173 ma->sss_radius[0] = 1.0f;
174 ma->sss_radius[1] = 1.0f;
175 ma->sss_radius[2] = 1.0f;
176 ma->sss_col[0] = 1.0f;
177 ma->sss_col[1] = 1.0f;
178 ma->sss_col[2] = 1.0f;
179 ma->sss_error = 0.05f;
180 ma->sss_scale = 0.1f;
182 ma->sss_colfac = 1.0f;
183 ma->sss_texfac = 0.0f;
184 ma->sss_front = 1.0f;
187 ma->vol.density = 1.0f;
188 ma->vol.emission = 0.0f;
189 ma->vol.scattering = 1.0f;
190 ma->vol.reflection = 1.0f;
191 ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
192 ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
193 ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
194 ma->vol.density_scale = 1.0f;
195 ma->vol.depth_cutoff = 0.01f;
196 ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
197 ma->vol.stepsize = 0.2f;
198 ma->vol.shade_type = MA_VOL_SHADE_SHADED;
199 ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
200 ma->vol.precache_resolution = 50;
201 ma->vol.ms_spread = 0.2f;
202 ma->vol.ms_diff = 1.f;
203 ma->vol.ms_intensity = 1.f;
205 ma->game.flag = GEMAT_BACKCULL;
206 ma->game.alpha_blend = 0;
207 ma->game.face_orientation = 0;
209 ma->mode = MA_TRACEBLE | MA_SHADBUF | MA_SHADOW | MA_RAYBIAS | MA_TANGENT_STR | MA_ZTRANSP;
210 ma->mode2 = MA_CASTSHADOW;
211 ma->shade_flag = MA_APPROX_OCCLUSION;
215 Material *BKE_material_add(Main *bmain, const char *name)
219 ma = BKE_libblock_alloc(bmain, ID_MA, name);
226 /* XXX keep synced with next function */
227 Material *BKE_material_copy(Material *ma)
232 man = BKE_libblock_copy(&ma->id);
234 id_lib_extern((ID *)man->group);
236 for (a = 0; a < MAX_MTEX; a++) {
238 man->mtex[a] = MEM_mallocN(sizeof(MTex), "copymaterial");
239 memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex));
240 id_us_plus((ID *)man->mtex[a]->tex);
244 if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
245 if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
247 if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview);
250 man->nodetree = ntreeCopyTree(ma->nodetree);
253 BLI_listbase_clear(&man->gpumaterial);
256 BKE_id_lib_local_paths(G.main, ma->id.lib, &man->id);
262 /* XXX (see above) material copy without adding to main dbase */
263 Material *localize_material(Material *ma)
268 man = BKE_libblock_copy_nolib(&ma->id, false);
270 /* no increment for texture ID users, in previewrender.c it prevents decrement */
271 for (a = 0; a < MAX_MTEX; a++) {
273 man->mtex[a] = MEM_mallocN(sizeof(MTex), "copymaterial");
274 memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex));
278 if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
279 if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
281 man->texpaintslot = NULL;
285 man->nodetree = ntreeLocalize(ma->nodetree);
287 BLI_listbase_clear(&man->gpumaterial);
292 static void extern_local_material(Material *ma)
295 for (i = 0; i < MAX_MTEX; i++) {
296 if (ma->mtex[i]) id_lib_extern((ID *)ma->mtex[i]->tex);
300 void BKE_material_make_local(Material *ma)
302 Main *bmain = G.main;
308 bool is_local = false, is_lib = false;
310 /* - only lib users: do nothing
311 * - only local users: set flag
315 if (ma->id.lib == NULL) return;
317 /* One local user; set flag and return. */
318 if (ma->id.us == 1) {
319 id_clear_lib_data(bmain, &ma->id);
320 extern_local_material(ma);
324 /* Check which other IDs reference this one to determine if it's used by
327 ob = bmain->object.first;
330 for (a = 0; a < ob->totcol; a++) {
331 if (ob->mat[a] == ma) {
332 if (ob->id.lib) is_lib = true;
333 else is_local = true;
340 me = bmain->mesh.first;
343 for (a = 0; a < me->totcol; a++) {
344 if (me->mat[a] == ma) {
345 if (me->id.lib) is_lib = true;
346 else is_local = true;
353 cu = bmain->curve.first;
356 for (a = 0; a < cu->totcol; a++) {
357 if (cu->mat[a] == ma) {
358 if (cu->id.lib) is_lib = true;
359 else is_local = true;
366 mb = bmain->mball.first;
369 for (a = 0; a < mb->totcol; a++) {
370 if (mb->mat[a] == ma) {
371 if (mb->id.lib) is_lib = true;
372 else is_local = true;
379 /* Only local users. */
380 if (is_local && is_lib == false) {
381 id_clear_lib_data(bmain, &ma->id);
382 extern_local_material(ma);
384 /* Both user and local, so copy. */
385 else if (is_local && is_lib) {
386 Material *ma_new = BKE_material_copy(ma);
390 /* Remap paths of new ID using old library as base. */
391 BKE_id_lib_local_paths(bmain, ma->id.lib, &ma_new->id);
394 ob = bmain->object.first;
397 for (a = 0; a < ob->totcol; a++) {
398 if (ob->mat[a] == ma) {
399 if (ob->id.lib == NULL) {
410 me = bmain->mesh.first;
413 for (a = 0; a < me->totcol; a++) {
414 if (me->mat[a] == ma) {
415 if (me->id.lib == NULL) {
426 cu = bmain->curve.first;
429 for (a = 0; a < cu->totcol; a++) {
430 if (cu->mat[a] == ma) {
431 if (cu->id.lib == NULL) {
442 mb = bmain->mball.first;
445 for (a = 0; a < mb->totcol; a++) {
446 if (mb->mat[a] == ma) {
447 if (mb->id.lib == NULL) {
460 /* for curve, mball, mesh types */
461 void extern_local_matarar(struct Material **matar, short totcol)
464 for (i = 0; i < totcol; i++) {
465 id_lib_extern((ID *)matar[i]);
469 Material ***give_matarar(Object *ob)
475 if (ob->type == OB_MESH) {
479 else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
483 else if (ob->type == OB_MBALL) {
490 short *give_totcolp(Object *ob)
496 if (ob->type == OB_MESH) {
498 return &(me->totcol);
500 else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
502 return &(cu->totcol);
504 else if (ob->type == OB_MBALL) {
506 return &(mb->totcol);
511 /* same as above but for ID's */
512 Material ***give_matarar_id(ID *id)
514 /* ensure we don't try get materials from non-obdata */
515 BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
517 switch (GS(id->name)) {
519 return &(((Mesh *)id)->mat);
521 return &(((Curve *)id)->mat);
523 return &(((MetaBall *)id)->mat);
528 short *give_totcolp_id(ID *id)
530 /* ensure we don't try get materials from non-obdata */
531 BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
533 switch (GS(id->name)) {
535 return &(((Mesh *)id)->totcol);
537 return &(((Curve *)id)->totcol);
539 return &(((MetaBall *)id)->totcol);
544 static void material_data_index_remove_id(ID *id, short index)
546 /* ensure we don't try get materials from non-obdata */
547 BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
549 switch (GS(id->name)) {
551 BKE_mesh_material_index_remove((Mesh *)id, index);
554 BKE_curve_material_index_remove((Curve *)id, index);
557 /* meta-elems don't have materials atm */
562 static void material_data_index_clear_id(ID *id)
564 /* ensure we don't try get materials from non-obdata */
565 BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
567 switch (GS(id->name)) {
569 BKE_mesh_material_index_clear((Mesh *)id);
572 BKE_curve_material_index_clear((Curve *)id);
575 /* meta-elems don't have materials atm */
580 void BKE_material_resize_id(struct ID *id, short totcol, bool do_id_user)
582 Material ***matar = give_matarar_id(id);
583 short *totcolp = give_totcolp_id(id);
589 if (do_id_user && totcol < (*totcolp)) {
591 for (i = totcol; i < (*totcolp); i++) {
592 id_us_min((ID *)(*matar)[i]);
603 *matar = MEM_recallocN(*matar, sizeof(void *) * totcol);
608 void BKE_material_append_id(ID *id, Material *ma)
611 if ((matar = give_matarar_id(id))) {
612 short *totcol = give_totcolp_id(id);
613 Material **mat = MEM_callocN(sizeof(void *) * ((*totcol) + 1), "newmatar");
614 if (*totcol) memcpy(mat, *matar, sizeof(void *) * (*totcol));
615 if (*matar) MEM_freeN(*matar);
618 (*matar)[(*totcol)++] = ma;
620 id_us_plus((ID *)ma);
621 test_object_materials(G.main, id);
625 Material *BKE_material_pop_id(ID *id, int index_i, bool update_data)
627 short index = (short)index_i;
628 Material *ret = NULL;
630 if ((matar = give_matarar_id(id))) {
631 short *totcol = give_totcolp_id(id);
632 if (index >= 0 && index < (*totcol)) {
633 ret = (*matar)[index];
634 id_us_min((ID *)ret);
642 if (index + 1 != (*totcol))
643 memmove((*matar) + index, (*matar) + (index + 1), sizeof(void *) * ((*totcol) - (index + 1)));
646 *matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol));
647 test_object_materials(G.main, id);
651 /* decrease mat_nr index */
652 material_data_index_remove_id(id, index);
660 void BKE_material_clear_id(struct ID *id, bool update_data)
663 if ((matar = give_matarar_id(id))) {
664 short *totcol = give_totcolp_id(id);
672 /* decrease mat_nr index */
673 material_data_index_clear_id(id);
678 Material *give_current_material(Object *ob, short act)
680 Material ***matarar, *ma;
681 const short *totcolp;
683 if (ob == NULL) return NULL;
685 /* if object cannot have material, (totcolp == NULL) */
686 totcolp = give_totcolp(ob);
687 if (totcolp == NULL || ob->totcol == 0) return NULL;
689 /* return NULL for invalid 'act', can happen for mesh face indices */
690 if (act > ob->totcol)
694 printf("Negative material index!\n");
699 if (ob->matbits && ob->matbits[act - 1]) { /* in object */
700 ma = ob->mat[act - 1];
704 /* check for inconsistency */
705 if (*totcolp < ob->totcol)
706 ob->totcol = *totcolp;
707 if (act > ob->totcol) act = ob->totcol;
709 matarar = give_matarar(ob);
711 if (matarar && *matarar) ma = (*matarar)[act - 1];
719 ID *material_from(Object *ob, short act)
722 if (ob == NULL) return NULL;
724 if (ob->totcol == 0) return ob->data;
725 if (act == 0) act = 1;
727 if (ob->matbits[act - 1]) return (ID *)ob;
728 else return ob->data;
731 Material *give_node_material(Material *ma)
733 if (ma && ma->use_nodes && ma->nodetree) {
734 bNode *node = nodeGetActiveID(ma->nodetree, ID_MA);
737 return (Material *)node->id;
743 void BKE_material_resize_object(Object *ob, const short totcol, bool do_id_user)
748 if (do_id_user && totcol < ob->totcol) {
750 for (i = totcol; i < ob->totcol; i++) {
751 id_us_min((ID *)ob->mat[i]);
758 MEM_freeN(ob->matbits);
763 else if (ob->totcol < totcol) {
764 newmatar = MEM_callocN(sizeof(void *) * totcol, "newmatar");
765 newmatbits = MEM_callocN(sizeof(char) * totcol, "newmatbits");
767 memcpy(newmatar, ob->mat, sizeof(void *) * ob->totcol);
768 memcpy(newmatbits, ob->matbits, sizeof(char) * ob->totcol);
770 MEM_freeN(ob->matbits);
773 ob->matbits = newmatbits;
775 /* XXX, why not realloc on shrink? - campbell */
778 if (ob->totcol && ob->actcol == 0) ob->actcol = 1;
779 if (ob->actcol > ob->totcol) ob->actcol = ob->totcol;
782 void test_object_materials(Main *bmain, ID *id)
784 /* make the ob mat-array same size as 'ob->data' mat-array */
788 if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
792 BKE_main_lock(bmain);
793 for (ob = bmain->object.first; ob; ob = ob->id.next) {
794 if (ob->data == id) {
795 BKE_material_resize_object(ob, *totcol, false);
798 BKE_main_unlock(bmain);
801 void assign_material_id(ID *id, Material *ma, short act)
803 Material *mao, **matar, ***matarar;
806 if (act > MAXMAT) return;
807 if (act < 1) act = 1;
809 /* this is needed for Python overrides,
810 * we just have to take care that the UI can't do this */
812 /* prevent crashing when using accidentally */
813 BLI_assert(id->lib == NULL);
819 totcolp = give_totcolp_id(id);
820 matarar = give_matarar_id(id);
822 if (totcolp == NULL || matarar == NULL) return;
824 if (act > *totcolp) {
825 matar = MEM_callocN(sizeof(void *) * act, "matarray1");
828 memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
837 mao = (*matarar)[act - 1];
838 if (mao) mao->id.us--;
839 (*matarar)[act - 1] = ma;
842 id_us_plus((ID *)ma);
844 test_object_materials(G.main, id);
847 void assign_material(Object *ob, Material *ma, short act, int assign_type)
849 Material *mao, **matar, ***matarar;
853 if (act > MAXMAT) return;
854 if (act < 1) act = 1;
856 /* prevent crashing when using accidentally */
857 BLI_assert(ob->id.lib == NULL);
858 if (ob->id.lib) return;
862 totcolp = give_totcolp(ob);
863 matarar = give_matarar(ob);
865 if (totcolp == NULL || matarar == NULL) return;
867 if (act > *totcolp) {
868 matar = MEM_callocN(sizeof(void *) * act, "matarray1");
871 memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
879 /* Determine the object/mesh linking */
880 if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->totcol && ob->actcol) {
881 /* copy from previous material */
882 bit = ob->matbits[ob->actcol - 1];
885 switch (assign_type) {
886 case BKE_MAT_ASSIGN_OBDATA:
889 case BKE_MAT_ASSIGN_OBJECT:
892 case BKE_MAT_ASSIGN_USERPREF:
894 bit = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
899 if (act > ob->totcol) {
900 /* Need more space in the material arrays */
901 ob->mat = MEM_recallocN_id(ob->mat, sizeof(void *) * act, "matarray2");
902 ob->matbits = MEM_recallocN_id(ob->matbits, sizeof(char) * act, "matbits1");
908 ob->matbits[act - 1] = bit;
909 if (bit == 1) { /* in object */
910 mao = ob->mat[act - 1];
911 if (mao) mao->id.us--;
912 ob->mat[act - 1] = ma;
915 mao = (*matarar)[act - 1];
916 if (mao) mao->id.us--;
917 (*matarar)[act - 1] = ma;
921 id_us_plus((ID *)ma);
922 test_object_materials(G.main, ob->data);
925 /* XXX - this calls many more update calls per object then are needed, could be optimized */
926 void assign_matarar(struct Object *ob, struct Material ***matar, short totcol)
928 int actcol_orig = ob->actcol;
931 while (object_remove_material_slot(ob)) {}
933 /* now we have the right number of slots */
934 for (i = 0; i < totcol; i++)
935 assign_material(ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
937 if (actcol_orig > ob->totcol)
938 actcol_orig = ob->totcol;
940 ob->actcol = actcol_orig;
944 short find_material_index(Object *ob, Material *ma)
949 if (ma == NULL) return 0;
951 totcolp = give_totcolp(ob);
952 matarar = give_matarar(ob);
954 if (totcolp == NULL || matarar == NULL) return 0;
956 for (a = 0; a < *totcolp; a++)
957 if ((*matarar)[a] == ma)
964 bool object_add_material_slot(Object *ob)
966 if (ob == NULL) return false;
967 if (ob->totcol >= MAXMAT) return false;
969 assign_material(ob, NULL, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
970 ob->actcol = ob->totcol;
974 static void do_init_render_material(Material *ma, int r_mode, float *amb)
977 int a, needuv = 0, needtang = 0;
979 if (ma->flarec == 0) ma->flarec = 1;
981 /* add all texcoflags from mtex, texco and mapto were cleared in advance */
982 for (a = 0; a < MAX_MTEX; a++) {
984 /* separate tex switching */
985 if (ma->septex & (1 << a)) continue;
988 if (mtex && mtex->tex && (mtex->tex->type | (mtex->tex->use_nodes && mtex->tex->nodetree) )) {
990 ma->texco |= mtex->texco;
991 ma->mapto |= mtex->mapto;
993 /* always get derivatives for these textures */
994 if (ELEM(mtex->tex->type, TEX_IMAGE, TEX_ENVMAP)) ma->texco |= TEXCO_OSA;
995 else if (mtex->texflag & (MTEX_COMPAT_BUMP | MTEX_3TAP_BUMP | MTEX_5TAP_BUMP | MTEX_BICUBIC_BUMP)) ma->texco |= TEXCO_OSA;
997 if (ma->texco & (TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM | TEXCO_STRAND | TEXCO_STRESS)) needuv = 1;
998 else if (ma->texco & (TEXCO_GLOB | TEXCO_UV | TEXCO_OBJECT | TEXCO_SPEED)) needuv = 1;
999 else if (ma->texco & (TEXCO_LAVECTOR | TEXCO_VIEW)) needuv = 1;
1001 if ((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT))
1006 if (needtang) ma->mode |= MA_NORMAP_TANG;
1007 else ma->mode &= ~MA_NORMAP_TANG;
1009 if (ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
1011 if (r_mode & R_OSA) ma->texco |= TEXCO_OSA; /* for texfaces */
1013 if (needuv) ma->texco |= NEED_UV;
1015 /* since the raytracer doesnt recalc O structs for each ray, we have to preset them all */
1016 if (r_mode & R_RAYTRACE) {
1017 if ((ma->mode & (MA_RAYMIRROR | MA_SHADOW_TRA)) || ((ma->mode & MA_TRANSP) && (ma->mode & MA_RAYTRANSP))) {
1018 ma->texco |= NEED_UV | TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM;
1019 if (r_mode & R_OSA) ma->texco |= TEXCO_OSA;
1024 ma->ambr = ma->amb * amb[0];
1025 ma->ambg = ma->amb * amb[1];
1026 ma->ambb = ma->amb * amb[2];
1029 /* local group override */
1030 if ((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) {
1033 for (group = G.main->group.first; group; group = group->id.next) {
1034 if (!group->id.lib && STREQ(group->id.name, ma->group->id.name)) {
1041 static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb)
1045 for (node = ntree->nodes.first; node; node = node->next) {
1047 if (GS(node->id->name) == ID_MA) {
1048 Material *ma = (Material *)node->id;
1049 if (ma != basemat) {
1050 do_init_render_material(ma, r_mode, amb);
1051 basemat->texco |= ma->texco;
1054 basemat->mode_l |= ma->mode & ~(MA_MODE_PIPELINE | MA_SHLESS);
1055 basemat->mode2_l |= ma->mode2 & ~MA_MODE2_PIPELINE;
1056 /* basemat only considered shadeless if all node materials are too */
1057 if (!(ma->mode & MA_SHLESS))
1058 basemat->mode_l &= ~MA_SHLESS;
1060 if (ma->strand_surfnor > 0.0f)
1061 basemat->mode_l |= MA_STR_SURFDIFF;
1063 else if (node->type == NODE_GROUP)
1064 init_render_nodetree((bNodeTree *)node->id, basemat, r_mode, amb);
1069 void init_render_material(Material *mat, int r_mode, float *amb)
1072 do_init_render_material(mat, r_mode, amb);
1074 if (mat->nodetree && mat->use_nodes) {
1075 /* mode_l will take the pipeline options from the main material, and the or-ed
1076 * result of non-pipeline options from the nodes. shadeless is an exception,
1077 * mode_l will have it set when all node materials are shadeless. */
1078 mat->mode_l = (mat->mode & MA_MODE_PIPELINE) | MA_SHLESS;
1079 mat->mode2_l = mat->mode2 & MA_MODE2_PIPELINE;
1081 /* parses the geom+tex nodes */
1082 ntreeShaderGetTexcoMode(mat->nodetree, r_mode, &mat->texco, &mat->mode_l);
1084 init_render_nodetree(mat->nodetree, mat, r_mode, amb);
1086 if (!mat->nodetree->execdata)
1087 mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree);
1090 mat->mode_l = mat->mode;
1091 mat->mode2_l = mat->mode2;
1093 if (mat->strand_surfnor > 0.0f)
1094 mat->mode_l |= MA_STR_SURFDIFF;
1098 void init_render_materials(Main *bmain, int r_mode, float *amb)
1102 /* clear these flags before going over materials, to make sure they
1103 * are cleared only once, otherwise node materials contained in other
1104 * node materials can go wrong */
1105 for (ma = bmain->mat.first; ma; ma = ma->id.next) {
1112 /* two steps, first initialize, then or the flags for layers */
1113 for (ma = bmain->mat.first; ma; ma = ma->id.next) {
1114 /* is_used flag comes back in convertblender.c */
1115 ma->flag &= ~MA_IS_USED;
1117 init_render_material(ma, r_mode, amb);
1120 init_render_material(&defmaterial, r_mode, amb);
1123 /* only needed for nodes now */
1124 void end_render_material(Material *mat)
1126 if (mat && mat->nodetree && mat->use_nodes) {
1127 if (mat->nodetree->execdata)
1128 ntreeShaderEndExecTree(mat->nodetree->execdata);
1132 void end_render_materials(Main *bmain)
1135 for (ma = bmain->mat.first; ma; ma = ma->id.next)
1137 end_render_material(ma);
1140 static bool material_in_nodetree(bNodeTree *ntree, Material *mat)
1144 for (node = ntree->nodes.first; node; node = node->next) {
1146 if (GS(node->id->name) == ID_MA) {
1147 if (node->id == (ID *)mat) {
1151 else if (node->type == NODE_GROUP) {
1152 if (material_in_nodetree((bNodeTree *)node->id, mat)) {
1162 bool material_in_material(Material *parmat, Material *mat)
1166 else if (parmat->nodetree && parmat->use_nodes)
1167 return material_in_nodetree(parmat->nodetree, mat);
1173 /* ****************** */
1175 /* Update drivers for materials in a nodetree */
1176 static void material_node_drivers_update(Scene *scene, bNodeTree *ntree, float ctime)
1180 /* nodetree itself */
1181 if (ntree->adt && ntree->adt->drivers.first) {
1182 BKE_animsys_evaluate_animdata(scene, &ntree->id, ntree->adt, ctime, ADT_RECALC_DRIVERS);
1186 for (node = ntree->nodes.first; node; node = node->next) {
1188 if (GS(node->id->name) == ID_MA) {
1189 material_drivers_update(scene, (Material *)node->id, ctime);
1191 else if (node->type == NODE_GROUP) {
1192 material_node_drivers_update(scene, (bNodeTree *)node->id, ctime);
1198 /* Calculate all drivers for materials
1199 * FIXME: this is really a terrible method which may result in some things being calculated
1200 * multiple times. However, without proper despgraph support for these things, we are forced
1201 * into this sort of thing...
1203 void material_drivers_update(Scene *scene, Material *ma, float ctime)
1205 //if (G.f & G_DEBUG)
1206 // printf("material_drivers_update(%s, %s)\n", scene->id.name, ma->id.name);
1208 /* Prevent infinite recursion by checking (and tagging the material) as having been visited already
1209 * (see BKE_scene_update_tagged()). This assumes ma->id.flag & LIB_DOIT isn't set by anything else
1210 * in the meantime... [#32017]
1212 if (ma->id.flag & LIB_DOIT)
1215 ma->id.flag |= LIB_DOIT;
1217 /* material itself */
1218 if (ma->adt && ma->adt->drivers.first) {
1219 BKE_animsys_evaluate_animdata(scene, &ma->id, ma->adt, ctime, ADT_RECALC_DRIVERS);
1224 material_node_drivers_update(scene, ma->nodetree, ctime);
1227 ma->id.flag &= ~LIB_DOIT;
1230 bool object_remove_material_slot(Object *ob)
1232 Material *mao, ***matarar;
1237 if (ob == NULL || ob->totcol == 0) {
1241 /* this should never happen and used to crash */
1242 if (ob->actcol <= 0) {
1243 printf("%s: invalid material index %d, report a bug!\n", __func__, ob->actcol);
1248 /* take a mesh/curve/mball as starting point, remove 1 index,
1249 * AND with all objects that share the ob->data
1251 * after that check indices in mesh/curve/mball!!!
1254 totcolp = give_totcolp(ob);
1255 matarar = give_matarar(ob);
1257 if (ELEM(NULL, matarar, *matarar)) {
1261 /* can happen on face selection in editmode */
1262 if (ob->actcol > ob->totcol) {
1263 ob->actcol = ob->totcol;
1266 /* we delete the actcol */
1267 mao = (*matarar)[ob->actcol - 1];
1268 if (mao) mao->id.us--;
1270 for (a = ob->actcol; a < ob->totcol; a++)
1271 (*matarar)[a - 1] = (*matarar)[a];
1274 if (*totcolp == 0) {
1275 MEM_freeN(*matarar);
1279 actcol = ob->actcol;
1280 obt = G.main->object.first;
1283 if (obt->data == ob->data) {
1285 /* WATCH IT: do not use actcol from ob or from obt (can become zero) */
1286 mao = obt->mat[actcol - 1];
1287 if (mao) mao->id.us--;
1289 for (a = actcol; a < obt->totcol; a++) {
1290 obt->mat[a - 1] = obt->mat[a];
1291 obt->matbits[a - 1] = obt->matbits[a];
1294 if (obt->actcol > obt->totcol) obt->actcol = obt->totcol;
1296 if (obt->totcol == 0) {
1297 MEM_freeN(obt->mat);
1298 MEM_freeN(obt->matbits);
1300 obt->matbits = NULL;
1306 /* check indices from mesh */
1307 if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
1308 material_data_index_remove_id((ID *)ob->data, actcol - 1);
1309 if (ob->curve_cache) {
1310 BKE_displist_free(&ob->curve_cache->disp);
1317 static bool get_mtex_slot_valid_texpaint(struct MTex *mtex)
1319 return (mtex && (mtex->texco == TEXCO_UV) &&
1320 mtex->tex && (mtex->tex->type == TEX_IMAGE) &&
1324 static bNode *nodetree_uv_node_recursive(bNode *node)
1329 for (sock = node->inputs.first; sock; sock = sock->next) {
1331 inode = sock->link->fromnode;
1332 if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) {
1336 return nodetree_uv_node_recursive(inode);
1344 void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
1350 bool use_nodes = BKE_scene_use_new_shading_nodes(scene);
1351 bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene);
1356 if (ma->texpaintslot) {
1357 MEM_freeN(ma->texpaintslot);
1359 ma->texpaintslot = NULL;
1362 if (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
1363 ma->paint_active_slot = 0;
1364 ma->paint_clone_slot = 0;
1368 if (use_nodes || ma->use_nodes) {
1369 bNode *node, *active_node;
1371 if (!(ma->nodetree)) {
1372 ma->paint_active_slot = 0;
1373 ma->paint_clone_slot = 0;
1377 for (node = ma->nodetree->nodes.first; node; node = node->next) {
1378 if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id)
1383 ma->paint_active_slot = 0;
1384 ma->paint_clone_slot = 0;
1387 ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
1389 active_node = nodeGetActiveTexture(ma->nodetree);
1391 for (node = ma->nodetree->nodes.first; node; node = node->next) {
1392 if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
1393 if (active_node == node)
1394 ma->paint_active_slot = index;
1395 ma->texpaintslot[index].ima = (Image *)node->id;
1397 /* for new renderer, we need to traverse the treeback in search of a UV node */
1399 bNode *uvnode = nodetree_uv_node_recursive(node);
1402 NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
1403 ma->texpaintslot[index].uvname = storage->uv_map;
1404 /* set a value to index so UI knows that we have a valid pointer for the mesh */
1405 ma->texpaintslot[index].index = 0;
1408 /* just invalidate the index here so UV map does not get displayed on the UI */
1409 ma->texpaintslot[index].index = -1;
1413 ma->texpaintslot[index].index = -1;
1420 for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) {
1421 if (get_mtex_slot_valid_texpaint(*mtex)) {
1427 ma->paint_active_slot = 0;
1428 ma->paint_clone_slot = 0;
1432 ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
1434 for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) {
1435 if (get_mtex_slot_valid_texpaint(*mtex)) {
1436 ma->texpaintslot[index].ima = (*mtex)->tex->ima;
1437 ma->texpaintslot[index].uvname = (*mtex)->uvname;
1438 ma->texpaintslot[index].index = i;
1445 ma->paint_active_slot = 0;
1446 ma->paint_clone_slot = 0;
1451 ma->tot_slots = count;
1454 if (ma->paint_active_slot >= count) {
1455 ma->paint_active_slot = count - 1;
1458 if (ma->paint_clone_slot >= count) {
1459 ma->paint_clone_slot = count - 1;
1465 void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
1469 for (i = 1; i < ob->totcol + 1; i++) {
1470 Material *ma = give_current_material(ob, i);
1471 BKE_texpaint_slot_refresh_cache(scene, ma);
1476 /* r_col = current value, col = new value, (fac == 0) is no change */
1477 void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
1479 float tmp, facm = 1.0f - fac;
1483 r_col[0] = facm * (r_col[0]) + fac * col[0];
1484 r_col[1] = facm * (r_col[1]) + fac * col[1];
1485 r_col[2] = facm * (r_col[2]) + fac * col[2];
1488 r_col[0] += fac * col[0];
1489 r_col[1] += fac * col[1];
1490 r_col[2] += fac * col[2];
1493 r_col[0] *= (facm + fac * col[0]);
1494 r_col[1] *= (facm + fac * col[1]);
1495 r_col[2] *= (facm + fac * col[2]);
1497 case MA_RAMP_SCREEN:
1498 r_col[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1499 r_col[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1500 r_col[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1502 case MA_RAMP_OVERLAY:
1503 if (r_col[0] < 0.5f)
1504 r_col[0] *= (facm + 2.0f * fac * col[0]);
1506 r_col[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1507 if (r_col[1] < 0.5f)
1508 r_col[1] *= (facm + 2.0f * fac * col[1]);
1510 r_col[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1511 if (r_col[2] < 0.5f)
1512 r_col[2] *= (facm + 2.0f * fac * col[2]);
1514 r_col[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1517 r_col[0] -= fac * col[0];
1518 r_col[1] -= fac * col[1];
1519 r_col[2] -= fac * col[2];
1523 r_col[0] = facm * (r_col[0]) + fac * (r_col[0]) / col[0];
1525 r_col[1] = facm * (r_col[1]) + fac * (r_col[1]) / col[1];
1527 r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2];
1530 r_col[0] = facm * (r_col[0]) + fac * fabsf(r_col[0] - col[0]);
1531 r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]);
1532 r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]);
1535 r_col[0] = min_ff(r_col[0], col[0]) * fac + r_col[0] * facm;
1536 r_col[1] = min_ff(r_col[1], col[1]) * fac + r_col[1] * facm;
1537 r_col[2] = min_ff(r_col[2], col[2]) * fac + r_col[2] * facm;
1541 if (tmp > r_col[0]) r_col[0] = tmp;
1543 if (tmp > r_col[1]) r_col[1] = tmp;
1545 if (tmp > r_col[2]) r_col[2] = tmp;
1548 if (r_col[0] != 0.0f) {
1549 tmp = 1.0f - fac * col[0];
1552 else if ((tmp = (r_col[0]) / tmp) > 1.0f)
1557 if (r_col[1] != 0.0f) {
1558 tmp = 1.0f - fac * col[1];
1561 else if ((tmp = (r_col[1]) / tmp) > 1.0f)
1566 if (r_col[2] != 0.0f) {
1567 tmp = 1.0f - fac * col[2];
1570 else if ((tmp = (r_col[2]) / tmp) > 1.0f)
1577 tmp = facm + fac * col[0];
1581 else if ((tmp = (1.0f - (1.0f - (r_col[0])) / tmp)) < 0.0f)
1583 else if (tmp > 1.0f)
1588 tmp = facm + fac * col[1];
1591 else if ((tmp = (1.0f - (1.0f - (r_col[1])) / tmp)) < 0.0f)
1593 else if (tmp > 1.0f)
1598 tmp = facm + fac * col[2];
1601 else if ((tmp = (1.0f - (1.0f - (r_col[2])) / tmp)) < 0.0f)
1603 else if (tmp > 1.0f)
1611 float colH, colS, colV;
1612 float tmpr, tmpg, tmpb;
1613 rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1615 rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1616 hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb);
1617 r_col[0] = facm * (r_col[0]) + fac * tmpr;
1618 r_col[1] = facm * (r_col[1]) + fac * tmpg;
1619 r_col[2] = facm * (r_col[2]) + fac * tmpb;
1626 float colH, colS, colV;
1627 rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1629 rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1630 hsv_to_rgb(rH, (facm * rS + fac * colS), rV, r_col + 0, r_col + 1, r_col + 2);
1637 float colH, colS, colV;
1638 rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1639 rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1640 hsv_to_rgb(rH, rS, (facm * rV + fac * colV), r_col + 0, r_col + 1, r_col + 2);
1646 float colH, colS, colV;
1647 float tmpr, tmpg, tmpb;
1648 rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1650 rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1651 hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb);
1652 r_col[0] = facm * (r_col[0]) + fac * tmpr;
1653 r_col[1] = facm * (r_col[1]) + fac * tmpg;
1654 r_col[2] = facm * (r_col[2]) + fac * tmpb;
1660 float scr, scg, scb;
1662 /* first calculate non-fac based Screen mix */
1663 scr = 1.0f - (1.0f - col[0]) * (1.0f - r_col[0]);
1664 scg = 1.0f - (1.0f - col[1]) * (1.0f - r_col[1]);
1665 scb = 1.0f - (1.0f - col[2]) * (1.0f - r_col[2]);
1667 r_col[0] = facm * (r_col[0]) + fac * (((1.0f - r_col[0]) * col[0] * (r_col[0])) + (r_col[0] * scr));
1668 r_col[1] = facm * (r_col[1]) + fac * (((1.0f - r_col[1]) * col[1] * (r_col[1])) + (r_col[1] * scg));
1669 r_col[2] = facm * (r_col[2]) + fac * (((1.0f - r_col[2]) * col[2] * (r_col[2])) + (r_col[2] * scb));
1672 case MA_RAMP_LINEAR:
1674 r_col[0] = r_col[0] + fac * (2.0f * (col[0] - 0.5f));
1676 r_col[0] = r_col[0] + fac * (2.0f * (col[0]) - 1.0f);
1678 r_col[1] = r_col[1] + fac * (2.0f * (col[1] - 0.5f));
1680 r_col[1] = r_col[1] + fac * (2.0f * (col[1]) - 1.0f);
1682 r_col[2] = r_col[2] + fac * (2.0f * (col[2] - 0.5f));
1684 r_col[2] = r_col[2] + fac * (2.0f * (col[2]) - 1.0f);
1690 * \brief copy/paste buffer, if we had a proper py api that would be better
1691 * \note matcopybuf.nodetree does _NOT_ use ID's
1692 * \todo matcopybuf.nodetree's node->id's are NOT validated, this will crash!
1694 static Material matcopybuf;
1695 static short matcopied = 0;
1697 void clear_matcopybuf(void)
1699 memset(&matcopybuf, 0, sizeof(Material));
1703 void free_matcopybuf(void)
1707 for (a = 0; a < MAX_MTEX; a++) {
1708 if (matcopybuf.mtex[a]) {
1709 MEM_freeN(matcopybuf.mtex[a]);
1710 matcopybuf.mtex[a] = NULL;
1714 if (matcopybuf.ramp_col) MEM_freeN(matcopybuf.ramp_col);
1715 if (matcopybuf.ramp_spec) MEM_freeN(matcopybuf.ramp_spec);
1717 matcopybuf.ramp_col = NULL;
1718 matcopybuf.ramp_spec = NULL;
1720 if (matcopybuf.nodetree) {
1721 ntreeFreeTree_ex(matcopybuf.nodetree, false);
1722 MEM_freeN(matcopybuf.nodetree);
1723 matcopybuf.nodetree = NULL;
1729 void copy_matcopybuf(Material *ma)
1737 memcpy(&matcopybuf, ma, sizeof(Material));
1738 if (matcopybuf.ramp_col) matcopybuf.ramp_col = MEM_dupallocN(matcopybuf.ramp_col);
1739 if (matcopybuf.ramp_spec) matcopybuf.ramp_spec = MEM_dupallocN(matcopybuf.ramp_spec);
1741 for (a = 0; a < MAX_MTEX; a++) {
1742 mtex = matcopybuf.mtex[a];
1744 matcopybuf.mtex[a] = MEM_dupallocN(mtex);
1747 matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, G.main, false);
1748 matcopybuf.preview = NULL;
1749 BLI_listbase_clear(&matcopybuf.gpumaterial);
1753 void paste_matcopybuf(Material *ma)
1761 /* free current mat */
1762 if (ma->ramp_col) MEM_freeN(ma->ramp_col);
1763 if (ma->ramp_spec) MEM_freeN(ma->ramp_spec);
1764 for (a = 0; a < MAX_MTEX; a++) {
1766 if (mtex && mtex->tex) mtex->tex->id.us--;
1767 if (mtex) MEM_freeN(mtex);
1771 ntreeFreeTree(ma->nodetree);
1772 MEM_freeN(ma->nodetree);
1775 GPU_material_free(&ma->gpumaterial);
1778 memcpy(ma, &matcopybuf, sizeof(Material));
1781 if (matcopybuf.ramp_col) ma->ramp_col = MEM_dupallocN(matcopybuf.ramp_col);
1782 if (matcopybuf.ramp_spec) ma->ramp_spec = MEM_dupallocN(matcopybuf.ramp_spec);
1784 for (a = 0; a < MAX_MTEX; a++) {
1787 ma->mtex[a] = MEM_dupallocN(mtex);
1789 /* first check this is in main (we may have loaded another file) [#35500] */
1790 if (BLI_findindex(&G.main->tex, mtex->tex) != -1) {
1791 id_us_plus((ID *)mtex->tex);
1794 ma->mtex[a]->tex = NULL;
1800 ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, G.main, false);
1804 /*********************** texface to material convert functions **********************/
1805 /* encode all the TF information into a single int */
1806 static int encode_tfaceflag(MTFace *tf, int convertall)
1808 /* calculate the flag */
1809 int flag = tf->mode;
1811 /* options that change the material offline render */
1816 /* clean flags that are not being converted */
1818 flag &= ~TF_SHAREDVERT;
1819 flag &= ~TF_SHAREDCOL;
1820 flag &= ~TF_CONVERTED;
1822 /* light tface flag is ignored in GLSL mode */
1825 /* 15 is how big the flag can be - hardcoded here and in decode_tfaceflag() */
1826 flag |= tf->transp << 15;
1828 /* increase 1 so flag 0 is different than no flag yet */
1832 /* set the material options based in the tface flag */
1833 static void decode_tfaceflag(Material *ma, int flag, int convertall)
1836 GameSettings *game = &ma->game;
1838 /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
1841 alphablend = flag >> 15; /* encoded in the encode_tfaceflag function */
1844 /* General Material Options */
1845 if ((flag & TF_DYNAMIC) == 0) (*game).flag |= GEMAT_NOPHYSICS;
1847 /* Material Offline Rendering Properties */
1849 if (flag & TF_OBCOL) ma->shade_flag |= MA_OBCOLOR;
1852 /* Special Face Properties */
1853 if ((flag & TF_TWOSIDE) == 0) (*game).flag |= GEMAT_BACKCULL;
1854 if (flag & TF_INVISIBLE) (*game).flag |= GEMAT_INVISIBLE;
1855 if (flag & TF_BMFONT) (*game).flag |= GEMAT_TEXT;
1857 /* Face Orientation */
1858 if (flag & TF_BILLBOARD) (*game).face_orientation |= GEMAT_HALO;
1859 else if (flag & TF_BILLBOARD2) (*game).face_orientation |= GEMAT_BILLBOARD;
1860 else if (flag & TF_SHADOW) (*game).face_orientation |= GEMAT_SHADOW;
1863 if (flag & TF_ALPHASORT && ELEM(alphablend, TF_ALPHA, TF_ADD)) (*game).alpha_blend = GEMAT_ALPHA_SORT;
1864 else if (alphablend & TF_ALPHA) (*game).alpha_blend = GEMAT_ALPHA;
1865 else if (alphablend & TF_ADD) (*game).alpha_blend = GEMAT_ADD;
1866 else if (alphablend & TF_CLIP) (*game).alpha_blend = GEMAT_CLIP;
1869 /* boolean check to see if the mesh needs a material */
1870 static int check_tfaceneedmaterial(int flag)
1872 /* check if the flags we have are not deprecated != than default material options
1873 * also if only flags are visible and collision see if all objects using this mesh have this option in physics */
1875 /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
1878 /* deprecated flags */
1880 flag &= ~TF_SHAREDVERT;
1881 flag &= ~TF_SHAREDCOL;
1883 /* light tface flag is ignored in GLSL mode */
1886 /* automatic detected if tex image has alpha */
1887 flag &= ~(TF_ALPHA << 15);
1888 /* automatic detected if using texture */
1891 /* settings for the default NoMaterial */
1892 if (flag == TF_DYNAMIC)
1899 /* return number of digits of an integer */
1900 /* XXX to be optmized or replaced by an equivalent blender internal function */
1901 static int integer_getdigits(int number)
1904 if (number == 0) return 1;
1906 while (number != 0) {
1907 number = (int)(number / 10);
1913 static void calculate_tface_materialname(char *matname, char *newname, int flag)
1915 /* if flag has only light and collision and material matches those values
1916 * you can do strcpy(name, mat_name);
1918 int digits = integer_getdigits(flag);
1919 /* clamp the old name, remove the MA prefix and add the .TF.flag suffix
1920 * e.g. matname = "MALoooooooooooooongName"; newname = "Loooooooooooooon.TF.2" */
1921 BLI_snprintf(newname, MAX_ID_NAME, "%.*s.TF.%0*d", MAX_ID_NAME - (digits + 5), matname, digits, flag);
1924 /* returns -1 if no match */
1925 static short mesh_getmaterialnumber(Mesh *me, Material *ma)
1929 for (a = 0; a < me->totcol; a++) {
1930 if (me->mat[a] == ma) {
1938 /* append material */
1939 static short mesh_addmaterial(Mesh *me, Material *ma)
1941 BKE_material_append_id(&me->id, NULL);
1942 me->mat[me->totcol - 1] = ma;
1944 id_us_plus(&ma->id);
1946 return me->totcol - 1;
1949 static void set_facetexture_flags(Material *ma, Image *image)
1952 ma->mode |= MA_FACETEXTURE;
1953 /* we could check if the texture has alpha, but then more meshes sharing the same
1954 * material may need it. Let's make it simple. */
1955 if (BKE_image_has_alpha(image))
1956 ma->mode |= MA_FACETEXTURE_ALPHA;
1960 /* returns material number */
1961 static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
1964 char idname[MAX_ID_NAME];
1967 /* new material, the name uses the flag*/
1968 BLI_snprintf(idname, sizeof(idname), "MAMaterial.TF.%0*d", integer_getdigits(flag), flag);
1970 if ((ma = BLI_findstring(&main->mat, idname + 2, offsetof(ID, name) + 2))) {
1971 mat_nr = mesh_getmaterialnumber(me, ma);
1972 /* assign the material to the mesh */
1973 if (mat_nr == -1) mat_nr = mesh_addmaterial(me, ma);
1975 /* if needed set "Face Textures [Alpha]" Material options */
1976 set_facetexture_flags(ma, tf->tpage);
1978 /* create a new material */
1980 ma = BKE_material_add(main, idname + 2);
1983 printf("TexFace Convert: Material \"%s\" created.\n", idname + 2);
1984 mat_nr = mesh_addmaterial(me, ma);
1986 /* if needed set "Face Textures [Alpha]" Material options */
1987 set_facetexture_flags(ma, tf->tpage);
1989 decode_tfaceflag(ma, flag, 1);
1990 /* the final decoding will happen after, outside the main loop
1991 * for now store the flag into the material and change light/tex/collision
1992 * store the flag as a negative number */
1993 ma->game.flag = -flag;
1994 id_us_min((ID *)ma);
1997 printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
2001 /* set as converted, no need to go bad to this face */
2002 tf->mode |= TF_CONVERTED;
2006 /* Function to fully convert materials */
2007 static void convert_tfacematerial(Main *main, Material *ma)
2016 CustomDataLayer *cdl;
2017 char idname[MAX_ID_NAME];
2019 for (me = main->mesh.first; me; me = me->id.next) {
2020 /* check if this mesh uses this material */
2021 for (a = 0; a < me->totcol; a++)
2022 if (me->mat[a] == ma) break;
2024 /* no material found */
2025 if (a == me->totcol) continue;
2027 /* get the active tface layer */
2028 index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
2029 cdl = (index == -1) ? NULL : &me->fdata.layers[index];
2032 /* loop over all the faces and stop at the ones that use the material*/
2033 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
2034 if (me->mat[mf->mat_nr] != ma) continue;
2036 /* texface data for this face */
2037 tf = ((MTFace *)cdl->data) + a;
2038 flag = encode_tfaceflag(tf, 1);
2040 /* the name of the new material */
2041 calculate_tface_materialname(ma->id.name, (char *)&idname, flag);
2043 if ((mat_new = BLI_findstring(&main->mat, idname + 2, offsetof(ID, name) + 2))) {
2044 /* material already existent, see if the mesh has it */
2045 mat_nr = mesh_getmaterialnumber(me, mat_new);
2046 /* material is not in the mesh, add it */
2047 if (mat_nr == -1) mat_nr = mesh_addmaterial(me, mat_new);
2049 /* create a new material */
2051 mat_new = BKE_material_copy(ma);
2053 /* rename the material*/
2054 BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name));
2055 id_us_min((ID *)mat_new);
2057 mat_nr = mesh_addmaterial(me, mat_new);
2058 decode_tfaceflag(mat_new, flag, 1);
2061 printf("Error: Unable to create Material \"%s\" for Mesh \"%s.", idname + 2, me->id.name + 2);
2062 mat_nr = mf->mat_nr;
2067 /* if the material has a texture but no texture channel
2068 * set "Face Textures [Alpha]" Material options
2069 * actually we need to run it always, because of old behavior
2070 * of using face texture if any texture channel was present (multitex) */
2071 //if ((!mat_new->mtex[0]) && (!mat_new->mtex[0]->tex))
2072 set_facetexture_flags(mat_new, tf->tpage);
2074 /* set the material number to the face*/
2075 mf->mat_nr = mat_nr;
2077 /* remove material from mesh */
2078 for (a = 0; a < me->totcol; ) {
2079 if (me->mat[a] == ma) {
2080 BKE_material_pop_id(&me->id, a, true);
2090 #define MAT_BGE_DISPUTED -99999
2092 int do_version_tface(Main *main)
2098 CustomDataLayer *cdl;
2103 /* Operator in help menu has been removed for 2.7x */
2106 /* sometimes mesh has no materials but will need a new one. In those
2107 * cases we need to ignore the mf->mat_nr and only look at the face
2108 * mode because it can be zero as uninitialized or the 1st created material
2110 int nomaterialslots;
2112 /* alert to user to check the console */
2115 /* mark all the materials to conversion with a flag
2116 * if there is tface create a complete flag for that storing in flag
2117 * if there is tface and flag > 0: creates a new flag based on this face
2118 * if flags are different set flag to -1
2121 /* 1st part: marking mesh materials to update */
2122 for (me = main->mesh.first; me; me = me->id.next) {
2123 if (me->id.lib) continue;
2125 /* get the active tface layer */
2126 index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
2127 cdl = (index == -1) ? NULL : &me->fdata.layers[index];
2130 nomaterialslots = (me->totcol == 0 ? 1 : 0);
2132 /* loop over all the faces*/
2133 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
2134 /* texface data for this face */
2135 tf = ((MTFace *)cdl->data) + a;
2137 /* conversion should happen only once */
2139 tf->mode &= ~TF_CONVERTED;
2141 if ((tf->mode & TF_CONVERTED)) continue;
2142 else tf->mode |= TF_CONVERTED;
2145 /* no material slots */
2146 if (nomaterialslots) {
2147 flag = encode_tfaceflag(tf, 1);
2149 /* create/find a new material and assign to the face */
2150 if (check_tfaceneedmaterial(flag)) {
2151 mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
2153 /* else mark them as no-material to be reverted to 0 later */
2158 else if (mf->mat_nr < me->totcol) {
2159 ma = me->mat[mf->mat_nr];
2161 /* no material create one if necessary */
2163 /* find a new material and assign to the face */
2164 flag = encode_tfaceflag(tf, 1);
2166 /* create/find a new material and assign to the face */
2167 if (check_tfaceneedmaterial(flag))
2168 mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
2173 /* we can't read from this if it comes from a library,
2174 * at doversion time: direct_link might not have happened on it,
2175 * so ma->mtex is not pointing to valid memory yet.
2176 * later we could, but it's better not */
2177 else if (ma->id.lib)
2180 /* material already marked as disputed */
2181 else if (ma->game.flag == MAT_BGE_DISPUTED)
2184 /* found a material */
2186 flag = encode_tfaceflag(tf, ((fileload) ? 0 : 1));
2188 /* first time changing this material */
2189 if (ma->game.flag == 0)
2190 ma->game.flag = -flag;
2192 /* mark material as disputed */
2193 else if (ma->game.flag != -flag) {
2194 ma->game.flag = MAT_BGE_DISPUTED;
2198 /* material ok so far */
2200 ma->game.flag = -flag;
2202 /* some people uses multitexture with TexFace by creating a texture
2203 * channel which not necessarily the tf->tpage image. But the game engine
2204 * was enabling it. Now it's required to set "Face Texture [Alpha] in the
2205 * material settings. */
2207 set_facetexture_flags(ma, tf->tpage);
2216 /* if we didn't have material slot and now we do, we need to
2217 * make sure the materials are correct */
2218 if (nomaterialslots) {
2219 if (me->totcol > 0) {
2220 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
2221 if (mf->mat_nr == -1) {
2222 /* texface data for this face */
2223 tf = ((MTFace *)cdl->data) + a;
2224 mf->mat_nr = convert_tfacenomaterial(main, me, tf, encode_tfaceflag(tf, 1));
2229 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
2237 /* 2nd part - conversion */
2238 /* skip library files */
2240 /* we shouldn't loop through the materials created in the loop. make the loop stop at its original length) */
2241 for (ma = main->mat.first, a = 0; ma; ma = ma->id.next, a++) {
2242 if (ma->id.lib) continue;
2244 /* disputed material */
2245 if (ma->game.flag == MAT_BGE_DISPUTED) {
2248 printf("Warning: material \"%s\" skipped.\n", ma->id.name + 2);
2252 convert_tfacematerial(main, ma);
2257 /* no conflicts in this material - 90% of cases
2258 * convert from tface system to material */
2259 else if (ma->game.flag < 0) {
2260 decode_tfaceflag(ma, -(ma->game.flag), 1);
2262 /* material is good make sure all faces using
2263 * this material are set to converted */
2265 for (me = main->mesh.first; me; me = me->id.next) {
2266 /* check if this mesh uses this material */
2267 for (a = 0; a < me->totcol; a++)
2268 if (me->mat[a] == ma) break;
2270 /* no material found */
2271 if (a == me->totcol) continue;
2273 /* get the active tface layer */
2274 index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
2275 cdl = (index == -1) ? NULL : &me->fdata.layers[index];
2278 /* loop over all the faces and stop at the ones that use the material*/
2279 for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
2280 if (me->mat[mf->mat_nr] == ma) {
2281 /* texface data for this face */
2282 tf = ((MTFace *)cdl->data) + a;
2283 tf->mode |= TF_CONVERTED;
2289 /* material is not used by faces with texface
2290 * set the default flag - do it only once */
2293 ma->game.flag = GEMAT_BACKCULL;