Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / material.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bke
22  */
23
24 #include <string.h>
25 #include <math.h>
26 #include <stddef.h>
27
28 #include "CLG_log.h"
29
30 #include "MEM_guardedalloc.h"
31
32 #include "DNA_anim_types.h"
33 #include "DNA_collection_types.h"
34 #include "DNA_curve_types.h"
35 #include "DNA_material_types.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_meshdata_types.h"
38 #include "DNA_customdata_types.h"
39 #include "DNA_gpencil_types.h"
40 #include "DNA_ID.h"
41 #include "DNA_meta_types.h"
42 #include "DNA_node_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_scene_types.h"
45
46 #include "BLI_math.h"
47 #include "BLI_listbase.h"
48 #include "BLI_utildefines.h"
49 #include "BLI_array_utils.h"
50
51 #include "BKE_animsys.h"
52 #include "BKE_brush.h"
53 #include "BKE_displist.h"
54 #include "BKE_gpencil.h"
55 #include "BKE_icons.h"
56 #include "BKE_image.h"
57 #include "BKE_library.h"
58 #include "BKE_main.h"
59 #include "BKE_material.h"
60 #include "BKE_mesh.h"
61 #include "BKE_scene.h"
62 #include "BKE_node.h"
63 #include "BKE_curve.h"
64 #include "BKE_editmesh.h"
65 #include "BKE_font.h"
66
67 #include "DEG_depsgraph.h"
68 #include "DEG_depsgraph_build.h"
69
70 #include "GPU_material.h"
71
72 /* used in UI and render */
73 Material defmaterial;
74
75 static CLG_LogRef LOG = {"bke.material"};
76
77 /* called on startup, creator.c */
78 void init_def_material(void)
79 {
80   BKE_material_init(&defmaterial);
81 }
82
83 /** Free (or release) any data used by this material (does not free the material itself). */
84 void BKE_material_free(Material *ma)
85 {
86   BKE_animdata_free((ID *)ma, false);
87
88   /* Free gpu material before the ntree */
89   GPU_material_free(&ma->gpumaterial);
90
91   /* is no lib link block, but material extension */
92   if (ma->nodetree) {
93     ntreeFreeNestedTree(ma->nodetree);
94     MEM_freeN(ma->nodetree);
95     ma->nodetree = NULL;
96   }
97
98   MEM_SAFE_FREE(ma->texpaintslot);
99
100   MEM_SAFE_FREE(ma->gp_style);
101
102   BKE_icon_id_delete((ID *)ma);
103   BKE_previewimg_free(&ma->preview);
104 }
105
106 void BKE_material_init_gpencil_settings(Material *ma)
107 {
108   if ((ma) && (ma->gp_style == NULL)) {
109     ma->gp_style = MEM_callocN(sizeof(MaterialGPencilStyle), "Grease Pencil Material Settings");
110
111     MaterialGPencilStyle *gp_style = ma->gp_style;
112     /* set basic settings */
113     gp_style->stroke_rgba[3] = 1.0f;
114     gp_style->fill_rgba[3] = 1.0f;
115     gp_style->pattern_gridsize = 0.1f;
116     gp_style->gradient_radius = 0.5f;
117     ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 0.2f);
118     ARRAY_SET_ITEMS(gp_style->gradient_scale, 1.0f, 1.0f);
119     ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f);
120     gp_style->texture_opacity = 1.0f;
121     gp_style->texture_pixsize = 100.0f;
122
123     gp_style->flag |= GP_STYLE_STROKE_SHOW;
124   }
125 }
126
127 void BKE_material_init(Material *ma)
128 {
129   BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(ma, id));
130
131   ma->r = ma->g = ma->b = 0.8;
132   ma->specr = ma->specg = ma->specb = 1.0;
133   ma->a = 1.0f;
134   ma->spec = 0.5;
135
136   ma->roughness = 0.25f;
137
138   ma->pr_type = MA_SPHERE;
139
140   ma->preview = NULL;
141
142   ma->alpha_threshold = 0.5f;
143
144   ma->blend_shadow = MA_BS_SOLID;
145 }
146
147 Material *BKE_material_add(Main *bmain, const char *name)
148 {
149   Material *ma;
150
151   ma = BKE_libblock_alloc(bmain, ID_MA, name, 0);
152
153   BKE_material_init(ma);
154
155   return ma;
156 }
157
158 Material *BKE_material_add_gpencil(Main *bmain, const char *name)
159 {
160   Material *ma;
161
162   ma = BKE_material_add(bmain, name);
163
164   /* grease pencil settings */
165   if (ma != NULL) {
166     BKE_material_init_gpencil_settings(ma);
167   }
168   return ma;
169 }
170
171 /**
172  * Only copy internal data of Material ID from source to already allocated/initialized destination.
173  * You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs.
174  *
175  * WARNING! This function will not handle ID user count!
176  *
177  * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
178  */
179 void BKE_material_copy_data(Main *bmain, Material *ma_dst, const Material *ma_src, const int flag)
180 {
181   if (ma_src->nodetree) {
182     /* Note: nodetree is *not* in bmain, however this specific case is handled at lower level
183      *       (see BKE_libblock_copy_ex()). */
184     BKE_id_copy_ex(bmain, (ID *)ma_src->nodetree, (ID **)&ma_dst->nodetree, flag);
185   }
186
187   if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
188     BKE_previewimg_id_copy(&ma_dst->id, &ma_src->id);
189   }
190   else {
191     ma_dst->preview = NULL;
192   }
193
194   if (ma_src->texpaintslot != NULL) {
195     ma_dst->texpaintslot = MEM_dupallocN(ma_src->texpaintslot);
196   }
197
198   if (ma_src->gp_style != NULL) {
199     ma_dst->gp_style = MEM_dupallocN(ma_src->gp_style);
200   }
201
202   BLI_listbase_clear(&ma_dst->gpumaterial);
203
204   /* TODO Duplicate Engine Settings and set runtime to NULL */
205 }
206
207 Material *BKE_material_copy(Main *bmain, const Material *ma)
208 {
209   Material *ma_copy;
210   BKE_id_copy(bmain, &ma->id, (ID **)&ma_copy);
211   return ma_copy;
212 }
213
214 /* XXX (see above) material copy without adding to main dbase */
215 Material *BKE_material_localize(Material *ma)
216 {
217   /* TODO(bastien): Replace with something like:
218    *
219    *   Material *ma_copy;
220    *   BKE_id_copy_ex(bmain, &ma->id, (ID **)&ma_copy,
221    *                  LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT,
222    *                  false);
223    *   return ma_copy;
224    *
225    * NOTE: Only possible once nested node trees are fully converted to that too. */
226
227   Material *man = BKE_libblock_copy_for_localize(&ma->id);
228
229   man->texpaintslot = NULL;
230   man->preview = NULL;
231
232   if (ma->nodetree != NULL) {
233     man->nodetree = ntreeLocalize(ma->nodetree);
234   }
235
236   if (ma->gp_style != NULL) {
237     man->gp_style = MEM_dupallocN(ma->gp_style);
238   }
239
240   BLI_listbase_clear(&man->gpumaterial);
241
242   /* TODO Duplicate Engine Settings and set runtime to NULL */
243
244   man->id.tag |= LIB_TAG_LOCALIZED;
245
246   return man;
247 }
248
249 void BKE_material_make_local(Main *bmain, Material *ma, const bool lib_local)
250 {
251   BKE_id_make_local_generic(bmain, &ma->id, true, lib_local);
252 }
253
254 Material ***give_matarar(Object *ob)
255 {
256   Mesh *me;
257   Curve *cu;
258   MetaBall *mb;
259   bGPdata *gpd;
260
261   if (ob->type == OB_MESH) {
262     me = ob->data;
263     return &(me->mat);
264   }
265   else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
266     cu = ob->data;
267     return &(cu->mat);
268   }
269   else if (ob->type == OB_MBALL) {
270     mb = ob->data;
271     return &(mb->mat);
272   }
273   else if (ob->type == OB_GPENCIL) {
274     gpd = ob->data;
275     return &(gpd->mat);
276   }
277   return NULL;
278 }
279
280 short *give_totcolp(Object *ob)
281 {
282   Mesh *me;
283   Curve *cu;
284   MetaBall *mb;
285   bGPdata *gpd;
286
287   if (ob->type == OB_MESH) {
288     me = ob->data;
289     return &(me->totcol);
290   }
291   else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
292     cu = ob->data;
293     return &(cu->totcol);
294   }
295   else if (ob->type == OB_MBALL) {
296     mb = ob->data;
297     return &(mb->totcol);
298   }
299   else if (ob->type == OB_GPENCIL) {
300     gpd = ob->data;
301     return &(gpd->totcol);
302   }
303   return NULL;
304 }
305
306 /* same as above but for ID's */
307 Material ***give_matarar_id(ID *id)
308 {
309   /* ensure we don't try get materials from non-obdata */
310   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
311
312   switch (GS(id->name)) {
313     case ID_ME:
314       return &(((Mesh *)id)->mat);
315     case ID_CU:
316       return &(((Curve *)id)->mat);
317     case ID_MB:
318       return &(((MetaBall *)id)->mat);
319     case ID_GD:
320       return &(((bGPdata *)id)->mat);
321     default:
322       break;
323   }
324   return NULL;
325 }
326
327 short *give_totcolp_id(ID *id)
328 {
329   /* ensure we don't try get materials from non-obdata */
330   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
331
332   switch (GS(id->name)) {
333     case ID_ME:
334       return &(((Mesh *)id)->totcol);
335     case ID_CU:
336       return &(((Curve *)id)->totcol);
337     case ID_MB:
338       return &(((MetaBall *)id)->totcol);
339     case ID_GD:
340       return &(((bGPdata *)id)->totcol);
341     default:
342       break;
343   }
344   return NULL;
345 }
346
347 static void material_data_index_remove_id(ID *id, short index)
348 {
349   /* ensure we don't try get materials from non-obdata */
350   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
351
352   switch (GS(id->name)) {
353     case ID_ME:
354       BKE_mesh_material_index_remove((Mesh *)id, index);
355       break;
356     case ID_CU:
357       BKE_curve_material_index_remove((Curve *)id, index);
358       break;
359     case ID_MB:
360       /* meta-elems don't have materials atm */
361       break;
362     case ID_GD:
363       BKE_gpencil_material_index_remove((bGPdata *)id, index);
364       break;
365     default:
366       break;
367   }
368 }
369
370 static void material_data_index_clear_id(ID *id)
371 {
372   /* ensure we don't try get materials from non-obdata */
373   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
374
375   switch (GS(id->name)) {
376     case ID_ME:
377       BKE_mesh_material_index_clear((Mesh *)id);
378       break;
379     case ID_CU:
380       BKE_curve_material_index_clear((Curve *)id);
381       break;
382     case ID_MB:
383       /* meta-elems don't have materials atm */
384       break;
385     default:
386       break;
387   }
388 }
389
390 void BKE_material_resize_id(Main *bmain, ID *id, short totcol, bool do_id_user)
391 {
392   Material ***matar = give_matarar_id(id);
393   short *totcolp = give_totcolp_id(id);
394
395   if (matar == NULL) {
396     return;
397   }
398
399   if (do_id_user && totcol < (*totcolp)) {
400     short i;
401     for (i = totcol; i < (*totcolp); i++) {
402       id_us_min((ID *)(*matar)[i]);
403     }
404   }
405
406   if (totcol == 0) {
407     if (*totcolp) {
408       MEM_freeN(*matar);
409       *matar = NULL;
410     }
411   }
412   else {
413     *matar = MEM_recallocN(*matar, sizeof(void *) * totcol);
414   }
415   *totcolp = totcol;
416
417   DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
418   DEG_relations_tag_update(bmain);
419 }
420
421 void BKE_material_append_id(Main *bmain, ID *id, Material *ma)
422 {
423   Material ***matar;
424   if ((matar = give_matarar_id(id))) {
425     short *totcol = give_totcolp_id(id);
426     Material **mat = MEM_callocN(sizeof(void *) * ((*totcol) + 1), "newmatar");
427     if (*totcol) {
428       memcpy(mat, *matar, sizeof(void *) * (*totcol));
429     }
430     if (*matar) {
431       MEM_freeN(*matar);
432     }
433
434     *matar = mat;
435     (*matar)[(*totcol)++] = ma;
436
437     id_us_plus((ID *)ma);
438     test_all_objects_materials(bmain, id);
439
440     DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
441     DEG_relations_tag_update(bmain);
442   }
443 }
444
445 Material *BKE_material_pop_id(Main *bmain, ID *id, int index_i, bool update_data)
446 {
447   short index = (short)index_i;
448   Material *ret = NULL;
449   Material ***matar;
450   if ((matar = give_matarar_id(id))) {
451     short *totcol = give_totcolp_id(id);
452     if (index >= 0 && index < (*totcol)) {
453       ret = (*matar)[index];
454       id_us_min((ID *)ret);
455
456       if (*totcol <= 1) {
457         *totcol = 0;
458         MEM_freeN(*matar);
459         *matar = NULL;
460       }
461       else {
462         if (index + 1 != (*totcol)) {
463           memmove((*matar) + index,
464                   (*matar) + (index + 1),
465                   sizeof(void *) * ((*totcol) - (index + 1)));
466         }
467
468         (*totcol)--;
469         *matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol));
470         test_all_objects_materials(bmain, id);
471       }
472
473       if (update_data) {
474         /* decrease mat_nr index */
475         material_data_index_remove_id(id, index);
476       }
477
478       DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
479       DEG_relations_tag_update(bmain);
480     }
481   }
482
483   return ret;
484 }
485
486 void BKE_material_clear_id(Main *bmain, ID *id, bool update_data)
487 {
488   Material ***matar;
489   if ((matar = give_matarar_id(id))) {
490     short *totcol = give_totcolp_id(id);
491
492     while ((*totcol)--) {
493       id_us_min((ID *)((*matar)[*totcol]));
494     }
495     *totcol = 0;
496     if (*matar) {
497       MEM_freeN(*matar);
498       *matar = NULL;
499     }
500
501     if (update_data) {
502       /* decrease mat_nr index */
503       material_data_index_clear_id(id);
504     }
505
506     DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
507     DEG_relations_tag_update(bmain);
508   }
509 }
510
511 Material **give_current_material_p(Object *ob, short act)
512 {
513   Material ***matarar, **ma_p;
514   const short *totcolp;
515
516   if (ob == NULL) {
517     return NULL;
518   }
519
520   /* if object cannot have material, (totcolp == NULL) */
521   totcolp = give_totcolp(ob);
522   if (totcolp == NULL || ob->totcol == 0) {
523     return NULL;
524   }
525
526   /* return NULL for invalid 'act', can happen for mesh face indices */
527   if (act > ob->totcol) {
528     return NULL;
529   }
530   else if (act <= 0) {
531     if (act < 0) {
532       CLOG_ERROR(&LOG, "Negative material index!");
533     }
534     return NULL;
535   }
536
537   if (ob->matbits && ob->matbits[act - 1]) { /* in object */
538     ma_p = &ob->mat[act - 1];
539   }
540   else { /* in data */
541
542     /* check for inconsistency */
543     if (*totcolp < ob->totcol) {
544       ob->totcol = *totcolp;
545     }
546     if (act > ob->totcol) {
547       act = ob->totcol;
548     }
549
550     matarar = give_matarar(ob);
551
552     if (matarar && *matarar) {
553       ma_p = &(*matarar)[act - 1];
554     }
555     else {
556       ma_p = NULL;
557     }
558   }
559
560   return ma_p;
561 }
562
563 Material *give_current_material(Object *ob, short act)
564 {
565   Material **ma_p = give_current_material_p(ob, act);
566   return ma_p ? *ma_p : NULL;
567 }
568
569 MaterialGPencilStyle *BKE_material_gpencil_settings_get(Object *ob, short act)
570 {
571   Material *ma = give_current_material(ob, act);
572   if (ma != NULL) {
573     if (ma->gp_style == NULL) {
574       BKE_material_init_gpencil_settings(ma);
575     }
576
577     return ma->gp_style;
578   }
579   else {
580     return NULL;
581   }
582 }
583
584 Material *give_node_material(Material *ma)
585 {
586   if (ma && ma->use_nodes && ma->nodetree) {
587     bNode *node = nodeGetActiveID(ma->nodetree, ID_MA);
588
589     if (node) {
590       return (Material *)node->id;
591     }
592   }
593
594   return NULL;
595 }
596
597 void BKE_material_resize_object(Main *bmain, Object *ob, const short totcol, bool do_id_user)
598 {
599   Material **newmatar;
600   char *newmatbits;
601
602   if (do_id_user && totcol < ob->totcol) {
603     short i;
604     for (i = totcol; i < ob->totcol; i++) {
605       id_us_min((ID *)ob->mat[i]);
606     }
607   }
608
609   if (totcol == 0) {
610     if (ob->totcol) {
611       MEM_freeN(ob->mat);
612       MEM_freeN(ob->matbits);
613       ob->mat = NULL;
614       ob->matbits = NULL;
615     }
616   }
617   else if (ob->totcol < totcol) {
618     newmatar = MEM_callocN(sizeof(void *) * totcol, "newmatar");
619     newmatbits = MEM_callocN(sizeof(char) * totcol, "newmatbits");
620     if (ob->totcol) {
621       memcpy(newmatar, ob->mat, sizeof(void *) * ob->totcol);
622       memcpy(newmatbits, ob->matbits, sizeof(char) * ob->totcol);
623       MEM_freeN(ob->mat);
624       MEM_freeN(ob->matbits);
625     }
626     ob->mat = newmatar;
627     ob->matbits = newmatbits;
628   }
629   /* XXX, why not realloc on shrink? - campbell */
630
631   ob->totcol = totcol;
632   if (ob->totcol && ob->actcol == 0) {
633     ob->actcol = 1;
634   }
635   if (ob->actcol > ob->totcol) {
636     ob->actcol = ob->totcol;
637   }
638
639   DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_GEOMETRY);
640   DEG_relations_tag_update(bmain);
641 }
642
643 void test_object_materials(Main *bmain, Object *ob, ID *id)
644 {
645   /* make the ob mat-array same size as 'ob->data' mat-array */
646   const short *totcol;
647
648   if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
649     return;
650   }
651
652   BKE_material_resize_object(bmain, ob, *totcol, false);
653 }
654
655 void test_all_objects_materials(Main *bmain, ID *id)
656 {
657   /* make the ob mat-array same size as 'ob->data' mat-array */
658   Object *ob;
659   const short *totcol;
660
661   if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
662     return;
663   }
664
665   BKE_main_lock(bmain);
666   for (ob = bmain->objects.first; ob; ob = ob->id.next) {
667     if (ob->data == id) {
668       BKE_material_resize_object(bmain, ob, *totcol, false);
669     }
670   }
671   BKE_main_unlock(bmain);
672 }
673
674 void assign_material_id(Main *bmain, ID *id, Material *ma, short act)
675 {
676   Material *mao, **matar, ***matarar;
677   short *totcolp;
678
679   if (act > MAXMAT) {
680     return;
681   }
682   if (act < 1) {
683     act = 1;
684   }
685
686   /* test arraylens */
687
688   totcolp = give_totcolp_id(id);
689   matarar = give_matarar_id(id);
690
691   if (totcolp == NULL || matarar == NULL) {
692     return;
693   }
694
695   if (act > *totcolp) {
696     matar = MEM_callocN(sizeof(void *) * act, "matarray1");
697
698     if (*totcolp) {
699       memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
700       MEM_freeN(*matarar);
701     }
702
703     *matarar = matar;
704     *totcolp = act;
705   }
706
707   /* in data */
708   mao = (*matarar)[act - 1];
709   if (mao) {
710     id_us_min(&mao->id);
711   }
712   (*matarar)[act - 1] = ma;
713
714   if (ma) {
715     id_us_plus(&ma->id);
716   }
717
718   test_all_objects_materials(bmain, id);
719 }
720
721 void assign_material(Main *bmain, Object *ob, Material *ma, short act, int assign_type)
722 {
723   Material *mao, **matar, ***matarar;
724   short *totcolp;
725   char bit = 0;
726
727   if (act > MAXMAT) {
728     return;
729   }
730   if (act < 1) {
731     act = 1;
732   }
733
734   /* prevent crashing when using accidentally */
735   BLI_assert(!ID_IS_LINKED(ob));
736   if (ID_IS_LINKED(ob)) {
737     return;
738   }
739
740   /* test arraylens */
741
742   totcolp = give_totcolp(ob);
743   matarar = give_matarar(ob);
744
745   if (totcolp == NULL || matarar == NULL) {
746     return;
747   }
748
749   if (act > *totcolp) {
750     matar = MEM_callocN(sizeof(void *) * act, "matarray1");
751
752     if (*totcolp) {
753       memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
754       MEM_freeN(*matarar);
755     }
756
757     *matarar = matar;
758     *totcolp = act;
759   }
760
761   if (act > ob->totcol) {
762     /* Need more space in the material arrays */
763     ob->mat = MEM_recallocN_id(ob->mat, sizeof(void *) * act, "matarray2");
764     ob->matbits = MEM_recallocN_id(ob->matbits, sizeof(char) * act, "matbits1");
765     ob->totcol = act;
766   }
767
768   /* Determine the object/mesh linking */
769   if (assign_type == BKE_MAT_ASSIGN_EXISTING) {
770     /* keep existing option (avoid confusion in scripts),
771      * intentionally ignore userpref (default to obdata). */
772     bit = ob->matbits[act - 1];
773   }
774   else if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->totcol && ob->actcol) {
775     /* copy from previous material */
776     bit = ob->matbits[ob->actcol - 1];
777   }
778   else {
779     switch (assign_type) {
780       case BKE_MAT_ASSIGN_OBDATA:
781         bit = 0;
782         break;
783       case BKE_MAT_ASSIGN_OBJECT:
784         bit = 1;
785         break;
786       case BKE_MAT_ASSIGN_USERPREF:
787       default:
788         bit = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
789         break;
790     }
791   }
792
793   /* do it */
794
795   ob->matbits[act - 1] = bit;
796   if (bit == 1) { /* in object */
797     mao = ob->mat[act - 1];
798     if (mao) {
799       id_us_min(&mao->id);
800     }
801     ob->mat[act - 1] = ma;
802     test_object_materials(bmain, ob, ob->data);
803   }
804   else { /* in data */
805     mao = (*matarar)[act - 1];
806     if (mao) {
807       id_us_min(&mao->id);
808     }
809     (*matarar)[act - 1] = ma;
810     test_all_objects_materials(bmain, ob->data); /* Data may be used by several objects... */
811   }
812
813   if (ma) {
814     id_us_plus(&ma->id);
815   }
816 }
817
818 void BKE_material_remap_object(Object *ob, const unsigned int *remap)
819 {
820   Material ***matar = give_matarar(ob);
821   const short *totcol_p = give_totcolp(ob);
822
823   BLI_array_permute(ob->mat, ob->totcol, remap);
824
825   if (ob->matbits) {
826     BLI_array_permute(ob->matbits, ob->totcol, remap);
827   }
828
829   if (matar) {
830     BLI_array_permute(*matar, *totcol_p, remap);
831   }
832
833   if (ob->type == OB_MESH) {
834     BKE_mesh_material_remap(ob->data, remap, ob->totcol);
835   }
836   else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
837     BKE_curve_material_remap(ob->data, remap, ob->totcol);
838   }
839   else if (ob->type == OB_GPENCIL) {
840     BKE_gpencil_material_remap(ob->data, remap, ob->totcol);
841   }
842   else {
843     /* add support for this object data! */
844     BLI_assert(matar == NULL);
845   }
846 }
847
848 /**
849  * Calculate a material remapping from \a ob_src to \a ob_dst.
850  *
851  * \param remap_src_to_dst: An array the size of `ob_src->totcol`
852  * where index values are filled in which map to \a ob_dst materials.
853  */
854 void BKE_material_remap_object_calc(Object *ob_dst, Object *ob_src, short *remap_src_to_dst)
855 {
856   if (ob_src->totcol == 0) {
857     return;
858   }
859
860   GHash *gh_mat_map = BLI_ghash_ptr_new_ex(__func__, ob_src->totcol);
861
862   for (int i = 0; i < ob_dst->totcol; i++) {
863     Material *ma_src = give_current_material(ob_dst, i + 1);
864     BLI_ghash_reinsert(gh_mat_map, ma_src, POINTER_FROM_INT(i), NULL, NULL);
865   }
866
867   /* setup default mapping (when materials don't match) */
868   {
869     int i = 0;
870     if (ob_dst->totcol >= ob_src->totcol) {
871       for (; i < ob_src->totcol; i++) {
872         remap_src_to_dst[i] = i;
873       }
874     }
875     else {
876       for (; i < ob_dst->totcol; i++) {
877         remap_src_to_dst[i] = i;
878       }
879       for (; i < ob_src->totcol; i++) {
880         remap_src_to_dst[i] = 0;
881       }
882     }
883   }
884
885   for (int i = 0; i < ob_src->totcol; i++) {
886     Material *ma_src = give_current_material(ob_src, i + 1);
887
888     if ((i < ob_dst->totcol) && (ma_src == give_current_material(ob_dst, i + 1))) {
889       /* when objects have exact matching materials - keep existing index */
890     }
891     else {
892       void **index_src_p = BLI_ghash_lookup_p(gh_mat_map, ma_src);
893       if (index_src_p) {
894         remap_src_to_dst[i] = POINTER_AS_INT(*index_src_p);
895       }
896     }
897   }
898
899   BLI_ghash_free(gh_mat_map, NULL, NULL);
900 }
901
902 /* XXX - this calls many more update calls per object then are needed, could be optimized */
903 void assign_matarar(Main *bmain, struct Object *ob, struct Material ***matar, short totcol)
904 {
905   int actcol_orig = ob->actcol;
906   short i;
907
908   while ((ob->totcol > totcol) && BKE_object_material_slot_remove(bmain, ob)) {
909     /* pass */
910   }
911
912   /* now we have the right number of slots */
913   for (i = 0; i < totcol; i++) {
914     assign_material(bmain, ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
915   }
916
917   if (actcol_orig > ob->totcol) {
918     actcol_orig = ob->totcol;
919   }
920
921   ob->actcol = actcol_orig;
922 }
923
924 short BKE_object_material_slot_find_index(Object *ob, Material *ma)
925 {
926   Material ***matarar;
927   short a, *totcolp;
928
929   if (ma == NULL) {
930     return 0;
931   }
932
933   totcolp = give_totcolp(ob);
934   matarar = give_matarar(ob);
935
936   if (totcolp == NULL || matarar == NULL) {
937     return 0;
938   }
939
940   for (a = 0; a < *totcolp; a++) {
941     if ((*matarar)[a] == ma) {
942       break;
943     }
944   }
945   if (a < *totcolp) {
946     return a + 1;
947   }
948   return 0;
949 }
950
951 bool BKE_object_material_slot_add(Main *bmain, Object *ob)
952 {
953   if (ob == NULL) {
954     return false;
955   }
956   if (ob->totcol >= MAXMAT) {
957     return false;
958   }
959
960   assign_material(bmain, ob, NULL, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
961   ob->actcol = ob->totcol;
962   return true;
963 }
964
965 /* ****************** */
966
967 bool BKE_object_material_slot_remove(Main *bmain, Object *ob)
968 {
969   Material *mao, ***matarar;
970   short *totcolp;
971   short a, actcol;
972
973   if (ob == NULL || ob->totcol == 0) {
974     return false;
975   }
976
977   /* this should never happen and used to crash */
978   if (ob->actcol <= 0) {
979     CLOG_ERROR(&LOG, "invalid material index %d, report a bug!", ob->actcol);
980     BLI_assert(0);
981     return false;
982   }
983
984   /* take a mesh/curve/mball as starting point, remove 1 index,
985    * AND with all objects that share the ob->data
986    *
987    * after that check indices in mesh/curve/mball!!!
988    */
989
990   totcolp = give_totcolp(ob);
991   matarar = give_matarar(ob);
992
993   if (ELEM(NULL, matarar, *matarar)) {
994     return false;
995   }
996
997   /* can happen on face selection in editmode */
998   if (ob->actcol > ob->totcol) {
999     ob->actcol = ob->totcol;
1000   }
1001
1002   /* we delete the actcol */
1003   mao = (*matarar)[ob->actcol - 1];
1004   if (mao) {
1005     id_us_min(&mao->id);
1006   }
1007
1008   for (a = ob->actcol; a < ob->totcol; a++) {
1009     (*matarar)[a - 1] = (*matarar)[a];
1010   }
1011   (*totcolp)--;
1012
1013   if (*totcolp == 0) {
1014     MEM_freeN(*matarar);
1015     *matarar = NULL;
1016   }
1017
1018   actcol = ob->actcol;
1019
1020   for (Object *obt = bmain->objects.first; obt; obt = obt->id.next) {
1021     if (obt->data == ob->data) {
1022       /* Can happen when object material lists are used, see: T52953 */
1023       if (actcol > obt->totcol) {
1024         continue;
1025       }
1026       /* WATCH IT: do not use actcol from ob or from obt (can become zero) */
1027       mao = obt->mat[actcol - 1];
1028       if (mao) {
1029         id_us_min(&mao->id);
1030       }
1031
1032       for (a = actcol; a < obt->totcol; a++) {
1033         obt->mat[a - 1] = obt->mat[a];
1034         obt->matbits[a - 1] = obt->matbits[a];
1035       }
1036       obt->totcol--;
1037       if (obt->actcol > obt->totcol) {
1038         obt->actcol = obt->totcol;
1039       }
1040
1041       if (obt->totcol == 0) {
1042         MEM_freeN(obt->mat);
1043         MEM_freeN(obt->matbits);
1044         obt->mat = NULL;
1045         obt->matbits = NULL;
1046       }
1047     }
1048   }
1049
1050   /* check indices from mesh */
1051   if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_GPENCIL)) {
1052     material_data_index_remove_id((ID *)ob->data, actcol - 1);
1053     if (ob->runtime.curve_cache) {
1054       BKE_displist_free(&ob->runtime.curve_cache->disp);
1055     }
1056   }
1057
1058   return true;
1059 }
1060
1061 static bNode *nodetree_uv_node_recursive(bNode *node)
1062 {
1063   bNode *inode;
1064   bNodeSocket *sock;
1065
1066   for (sock = node->inputs.first; sock; sock = sock->next) {
1067     if (sock->link) {
1068       inode = sock->link->fromnode;
1069       if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) {
1070         return inode;
1071       }
1072       else {
1073         return nodetree_uv_node_recursive(inode);
1074       }
1075     }
1076   }
1077
1078   return NULL;
1079 }
1080
1081 static int count_texture_nodes_recursive(bNodeTree *nodetree)
1082 {
1083   int tex_nodes = 0;
1084
1085   for (bNode *node = nodetree->nodes.first; node; node = node->next) {
1086     if (node->typeinfo->nclass == NODE_CLASS_TEXTURE &&
1087         node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
1088       tex_nodes++;
1089     }
1090     else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
1091       /* recurse into the node group and see if it contains any textures */
1092       tex_nodes += count_texture_nodes_recursive((bNodeTree *)node->id);
1093     }
1094   }
1095
1096   return tex_nodes;
1097 }
1098
1099 static void fill_texpaint_slots_recursive(bNodeTree *nodetree,
1100                                           bNode *active_node,
1101                                           Material *ma,
1102                                           int *index)
1103 {
1104   for (bNode *node = nodetree->nodes.first; node; node = node->next) {
1105     if (node->typeinfo->nclass == NODE_CLASS_TEXTURE &&
1106         node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
1107       if (active_node == node) {
1108         ma->paint_active_slot = *index;
1109       }
1110
1111       ma->texpaintslot[*index].ima = (Image *)node->id;
1112       ma->texpaintslot[*index].interp = ((NodeTexImage *)node->storage)->interpolation;
1113
1114       /* for new renderer, we need to traverse the treeback in search of a UV node */
1115       bNode *uvnode = nodetree_uv_node_recursive(node);
1116
1117       if (uvnode) {
1118         NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
1119         ma->texpaintslot[*index].uvname = storage->uv_map;
1120         /* set a value to index so UI knows that we have a valid pointer for the mesh */
1121         ma->texpaintslot[*index].valid = true;
1122       }
1123       else {
1124         /* just invalidate the index here so UV map does not get displayed on the UI */
1125         ma->texpaintslot[*index].valid = false;
1126       }
1127       (*index)++;
1128     }
1129     else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
1130       /* recurse into the node group and see if it contains any textures */
1131       fill_texpaint_slots_recursive((bNodeTree *)node->id, active_node, ma, index);
1132     }
1133   }
1134 }
1135
1136 void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
1137 {
1138   int count = 0;
1139   int index = 0;
1140
1141   if (!ma) {
1142     return;
1143   }
1144
1145   /* COW needed when adding texture slot on an object with no materials. */
1146   DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
1147
1148   if (ma->texpaintslot) {
1149     MEM_freeN(ma->texpaintslot);
1150     ma->tot_slots = 0;
1151     ma->texpaintslot = NULL;
1152   }
1153
1154   if (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
1155     ma->paint_active_slot = 0;
1156     ma->paint_clone_slot = 0;
1157     return;
1158   }
1159
1160   if (!(ma->nodetree)) {
1161     ma->paint_active_slot = 0;
1162     ma->paint_clone_slot = 0;
1163     return;
1164   }
1165
1166   count = count_texture_nodes_recursive(ma->nodetree);
1167
1168   if (count == 0) {
1169     ma->paint_active_slot = 0;
1170     ma->paint_clone_slot = 0;
1171     return;
1172   }
1173
1174   ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
1175
1176   bNode *active_node = nodeGetActiveTexture(ma->nodetree);
1177
1178   fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, &index);
1179
1180   ma->tot_slots = count;
1181
1182   if (ma->paint_active_slot >= count) {
1183     ma->paint_active_slot = count - 1;
1184   }
1185
1186   if (ma->paint_clone_slot >= count) {
1187     ma->paint_clone_slot = count - 1;
1188   }
1189
1190   return;
1191 }
1192
1193 void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
1194 {
1195   int i;
1196
1197   for (i = 1; i < ob->totcol + 1; i++) {
1198     Material *ma = give_current_material(ob, i);
1199     BKE_texpaint_slot_refresh_cache(scene, ma);
1200   }
1201 }
1202
1203 /* r_col = current value, col = new value, (fac == 0) is no change */
1204 void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
1205 {
1206   float tmp, facm = 1.0f - fac;
1207
1208   switch (type) {
1209     case MA_RAMP_BLEND:
1210       r_col[0] = facm * (r_col[0]) + fac * col[0];
1211       r_col[1] = facm * (r_col[1]) + fac * col[1];
1212       r_col[2] = facm * (r_col[2]) + fac * col[2];
1213       break;
1214     case MA_RAMP_ADD:
1215       r_col[0] += fac * col[0];
1216       r_col[1] += fac * col[1];
1217       r_col[2] += fac * col[2];
1218       break;
1219     case MA_RAMP_MULT:
1220       r_col[0] *= (facm + fac * col[0]);
1221       r_col[1] *= (facm + fac * col[1]);
1222       r_col[2] *= (facm + fac * col[2]);
1223       break;
1224     case MA_RAMP_SCREEN:
1225       r_col[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1226       r_col[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1227       r_col[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1228       break;
1229     case MA_RAMP_OVERLAY:
1230       if (r_col[0] < 0.5f) {
1231         r_col[0] *= (facm + 2.0f * fac * col[0]);
1232       }
1233       else {
1234         r_col[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1235       }
1236       if (r_col[1] < 0.5f) {
1237         r_col[1] *= (facm + 2.0f * fac * col[1]);
1238       }
1239       else {
1240         r_col[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1241       }
1242       if (r_col[2] < 0.5f) {
1243         r_col[2] *= (facm + 2.0f * fac * col[2]);
1244       }
1245       else {
1246         r_col[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1247       }
1248       break;
1249     case MA_RAMP_SUB:
1250       r_col[0] -= fac * col[0];
1251       r_col[1] -= fac * col[1];
1252       r_col[2] -= fac * col[2];
1253       break;
1254     case MA_RAMP_DIV:
1255       if (col[0] != 0.0f) {
1256         r_col[0] = facm * (r_col[0]) + fac * (r_col[0]) / col[0];
1257       }
1258       if (col[1] != 0.0f) {
1259         r_col[1] = facm * (r_col[1]) + fac * (r_col[1]) / col[1];
1260       }
1261       if (col[2] != 0.0f) {
1262         r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2];
1263       }
1264       break;
1265     case MA_RAMP_DIFF:
1266       r_col[0] = facm * (r_col[0]) + fac * fabsf(r_col[0] - col[0]);
1267       r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]);
1268       r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]);
1269       break;
1270     case MA_RAMP_DARK:
1271       r_col[0] = min_ff(r_col[0], col[0]) * fac + r_col[0] * facm;
1272       r_col[1] = min_ff(r_col[1], col[1]) * fac + r_col[1] * facm;
1273       r_col[2] = min_ff(r_col[2], col[2]) * fac + r_col[2] * facm;
1274       break;
1275     case MA_RAMP_LIGHT:
1276       tmp = fac * col[0];
1277       if (tmp > r_col[0]) {
1278         r_col[0] = tmp;
1279       }
1280       tmp = fac * col[1];
1281       if (tmp > r_col[1]) {
1282         r_col[1] = tmp;
1283       }
1284       tmp = fac * col[2];
1285       if (tmp > r_col[2]) {
1286         r_col[2] = tmp;
1287       }
1288       break;
1289     case MA_RAMP_DODGE:
1290       if (r_col[0] != 0.0f) {
1291         tmp = 1.0f - fac * col[0];
1292         if (tmp <= 0.0f) {
1293           r_col[0] = 1.0f;
1294         }
1295         else if ((tmp = (r_col[0]) / tmp) > 1.0f) {
1296           r_col[0] = 1.0f;
1297         }
1298         else {
1299           r_col[0] = tmp;
1300         }
1301       }
1302       if (r_col[1] != 0.0f) {
1303         tmp = 1.0f - fac * col[1];
1304         if (tmp <= 0.0f) {
1305           r_col[1] = 1.0f;
1306         }
1307         else if ((tmp = (r_col[1]) / tmp) > 1.0f) {
1308           r_col[1] = 1.0f;
1309         }
1310         else {
1311           r_col[1] = tmp;
1312         }
1313       }
1314       if (r_col[2] != 0.0f) {
1315         tmp = 1.0f - fac * col[2];
1316         if (tmp <= 0.0f) {
1317           r_col[2] = 1.0f;
1318         }
1319         else if ((tmp = (r_col[2]) / tmp) > 1.0f) {
1320           r_col[2] = 1.0f;
1321         }
1322         else {
1323           r_col[2] = tmp;
1324         }
1325       }
1326       break;
1327     case MA_RAMP_BURN:
1328       tmp = facm + fac * col[0];
1329
1330       if (tmp <= 0.0f) {
1331         r_col[0] = 0.0f;
1332       }
1333       else if ((tmp = (1.0f - (1.0f - (r_col[0])) / tmp)) < 0.0f) {
1334         r_col[0] = 0.0f;
1335       }
1336       else if (tmp > 1.0f) {
1337         r_col[0] = 1.0f;
1338       }
1339       else {
1340         r_col[0] = tmp;
1341       }
1342
1343       tmp = facm + fac * col[1];
1344       if (tmp <= 0.0f) {
1345         r_col[1] = 0.0f;
1346       }
1347       else if ((tmp = (1.0f - (1.0f - (r_col[1])) / tmp)) < 0.0f) {
1348         r_col[1] = 0.0f;
1349       }
1350       else if (tmp > 1.0f) {
1351         r_col[1] = 1.0f;
1352       }
1353       else {
1354         r_col[1] = tmp;
1355       }
1356
1357       tmp = facm + fac * col[2];
1358       if (tmp <= 0.0f) {
1359         r_col[2] = 0.0f;
1360       }
1361       else if ((tmp = (1.0f - (1.0f - (r_col[2])) / tmp)) < 0.0f) {
1362         r_col[2] = 0.0f;
1363       }
1364       else if (tmp > 1.0f) {
1365         r_col[2] = 1.0f;
1366       }
1367       else {
1368         r_col[2] = tmp;
1369       }
1370       break;
1371     case MA_RAMP_HUE: {
1372       float rH, rS, rV;
1373       float colH, colS, colV;
1374       float tmpr, tmpg, tmpb;
1375       rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1376       if (colS != 0) {
1377         rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1378         hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb);
1379         r_col[0] = facm * (r_col[0]) + fac * tmpr;
1380         r_col[1] = facm * (r_col[1]) + fac * tmpg;
1381         r_col[2] = facm * (r_col[2]) + fac * tmpb;
1382       }
1383       break;
1384     }
1385     case MA_RAMP_SAT: {
1386       float rH, rS, rV;
1387       float colH, colS, colV;
1388       rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1389       if (rS != 0) {
1390         rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1391         hsv_to_rgb(rH, (facm * rS + fac * colS), rV, r_col + 0, r_col + 1, r_col + 2);
1392       }
1393       break;
1394     }
1395     case MA_RAMP_VAL: {
1396       float rH, rS, rV;
1397       float colH, colS, colV;
1398       rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1399       rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1400       hsv_to_rgb(rH, rS, (facm * rV + fac * colV), r_col + 0, r_col + 1, r_col + 2);
1401       break;
1402     }
1403     case MA_RAMP_COLOR: {
1404       float rH, rS, rV;
1405       float colH, colS, colV;
1406       float tmpr, tmpg, tmpb;
1407       rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1408       if (colS != 0) {
1409         rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1410         hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb);
1411         r_col[0] = facm * (r_col[0]) + fac * tmpr;
1412         r_col[1] = facm * (r_col[1]) + fac * tmpg;
1413         r_col[2] = facm * (r_col[2]) + fac * tmpb;
1414       }
1415       break;
1416     }
1417     case MA_RAMP_SOFT: {
1418       float scr, scg, scb;
1419
1420       /* first calculate non-fac based Screen mix */
1421       scr = 1.0f - (1.0f - col[0]) * (1.0f - r_col[0]);
1422       scg = 1.0f - (1.0f - col[1]) * (1.0f - r_col[1]);
1423       scb = 1.0f - (1.0f - col[2]) * (1.0f - r_col[2]);
1424
1425       r_col[0] = facm * (r_col[0]) +
1426                  fac * (((1.0f - r_col[0]) * col[0] * (r_col[0])) + (r_col[0] * scr));
1427       r_col[1] = facm * (r_col[1]) +
1428                  fac * (((1.0f - r_col[1]) * col[1] * (r_col[1])) + (r_col[1] * scg));
1429       r_col[2] = facm * (r_col[2]) +
1430                  fac * (((1.0f - r_col[2]) * col[2] * (r_col[2])) + (r_col[2] * scb));
1431       break;
1432     }
1433     case MA_RAMP_LINEAR:
1434       if (col[0] > 0.5f) {
1435         r_col[0] = r_col[0] + fac * (2.0f * (col[0] - 0.5f));
1436       }
1437       else {
1438         r_col[0] = r_col[0] + fac * (2.0f * (col[0]) - 1.0f);
1439       }
1440       if (col[1] > 0.5f) {
1441         r_col[1] = r_col[1] + fac * (2.0f * (col[1] - 0.5f));
1442       }
1443       else {
1444         r_col[1] = r_col[1] + fac * (2.0f * (col[1]) - 1.0f);
1445       }
1446       if (col[2] > 0.5f) {
1447         r_col[2] = r_col[2] + fac * (2.0f * (col[2] - 0.5f));
1448       }
1449       else {
1450         r_col[2] = r_col[2] + fac * (2.0f * (col[2]) - 1.0f);
1451       }
1452       break;
1453   }
1454 }
1455
1456 /**
1457  * \brief copy/paste buffer, if we had a proper py api that would be better
1458  * \note matcopybuf.nodetree does _NOT_ use ID's
1459  * \todo matcopybuf.nodetree's  node->id's are NOT validated, this will crash!
1460  */
1461 static Material matcopybuf;
1462 static short matcopied = 0;
1463
1464 void clear_matcopybuf(void)
1465 {
1466   memset(&matcopybuf, 0, sizeof(Material));
1467   matcopied = 0;
1468 }
1469
1470 void free_matcopybuf(void)
1471 {
1472   if (matcopybuf.nodetree) {
1473     ntreeFreeLocalTree(matcopybuf.nodetree);
1474     MEM_freeN(matcopybuf.nodetree);
1475     matcopybuf.nodetree = NULL;
1476   }
1477
1478   matcopied = 0;
1479 }
1480
1481 void copy_matcopybuf(Main *bmain, Material *ma)
1482 {
1483   if (matcopied) {
1484     free_matcopybuf();
1485   }
1486
1487   memcpy(&matcopybuf, ma, sizeof(Material));
1488
1489   if (ma->nodetree != NULL) {
1490     matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, bmain, false);
1491   }
1492
1493   matcopybuf.preview = NULL;
1494   BLI_listbase_clear(&matcopybuf.gpumaterial);
1495   /* TODO Duplicate Engine Settings and set runtime to NULL */
1496   matcopied = 1;
1497 }
1498
1499 void paste_matcopybuf(Main *bmain, Material *ma)
1500 {
1501   ID id;
1502
1503   if (matcopied == 0) {
1504     return;
1505   }
1506
1507   /* Free gpu material before the ntree */
1508   GPU_material_free(&ma->gpumaterial);
1509
1510   if (ma->nodetree) {
1511     ntreeFreeNestedTree(ma->nodetree);
1512     MEM_freeN(ma->nodetree);
1513   }
1514
1515   id = (ma->id);
1516   memcpy(ma, &matcopybuf, sizeof(Material));
1517   (ma->id) = id;
1518
1519   if (matcopybuf.nodetree != NULL) {
1520     ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, bmain, false);
1521   }
1522 }
1523
1524 void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
1525 {
1526   DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
1527   GPU_material_free(&material->gpumaterial);
1528 }