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 <math.h>
25 #include <stddef.h>
26 #include <string.h>
27 
28 #include "CLG_log.h"
29 
30 #include "MEM_guardedalloc.h"
31 
32 /* Allow using deprecated functionality for .blend file I/O. */
33 #define DNA_DEPRECATED_ALLOW
34 
35 #include "DNA_ID.h"
36 #include "DNA_anim_types.h"
37 #include "DNA_collection_types.h"
38 #include "DNA_curve_types.h"
39 #include "DNA_customdata_types.h"
40 #include "DNA_defaults.h"
41 #include "DNA_gpencil_types.h"
42 #include "DNA_hair_types.h"
43 #include "DNA_material_types.h"
44 #include "DNA_mesh_types.h"
45 #include "DNA_meshdata_types.h"
46 #include "DNA_meta_types.h"
47 #include "DNA_node_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_pointcloud_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_volume_types.h"
52 
53 #include "BLI_array_utils.h"
54 #include "BLI_listbase.h"
55 #include "BLI_math.h"
56 #include "BLI_utildefines.h"
57 
58 #include "BLT_translation.h"
59 
60 #include "BKE_anim_data.h"
61 #include "BKE_brush.h"
62 #include "BKE_curve.h"
63 #include "BKE_displist.h"
64 #include "BKE_editmesh.h"
65 #include "BKE_font.h"
66 #include "BKE_gpencil.h"
67 #include "BKE_icons.h"
68 #include "BKE_idtype.h"
69 #include "BKE_image.h"
70 #include "BKE_lib_id.h"
71 #include "BKE_lib_query.h"
72 #include "BKE_main.h"
73 #include "BKE_material.h"
74 #include "BKE_mesh.h"
75 #include "BKE_node.h"
76 #include "BKE_scene.h"
77 
78 #include "DEG_depsgraph.h"
79 #include "DEG_depsgraph_build.h"
80 
81 #include "GPU_material.h"
82 
83 #include "NOD_shader.h"
84 
85 #include "BLO_read_write.h"
86 
87 static CLG_LogRef LOG = {"bke.material"};
88 
material_init_data(ID * id)89 static void material_init_data(ID *id)
90 {
91   Material *material = (Material *)id;
92 
93   BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(material, id));
94 
95   MEMCPY_STRUCT_AFTER(material, DNA_struct_default_get(Material), id);
96 }
97 
material_copy_data(Main * bmain,ID * id_dst,const ID * id_src,const int flag)98 static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
99 {
100   Material *material_dst = (Material *)id_dst;
101   const Material *material_src = (const Material *)id_src;
102 
103   const bool is_localized = (flag & LIB_ID_CREATE_LOCAL) != 0;
104   /* We always need allocation of our private ID data. */
105   const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
106 
107   if (material_src->nodetree != NULL) {
108     if (is_localized) {
109       material_dst->nodetree = ntreeLocalize(material_src->nodetree);
110     }
111     else {
112       BKE_id_copy_ex(bmain,
113                      (ID *)material_src->nodetree,
114                      (ID **)&material_dst->nodetree,
115                      flag_private_id_data);
116     }
117   }
118 
119   if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
120     BKE_previewimg_id_copy(&material_dst->id, &material_src->id);
121   }
122   else {
123     material_dst->preview = NULL;
124   }
125 
126   if (material_src->texpaintslot != NULL) {
127     /* TODO: Think we can also skip copying this data in the more generic `NO_MAIN` case? */
128     material_dst->texpaintslot = is_localized ? NULL : MEM_dupallocN(material_src->texpaintslot);
129   }
130 
131   if (material_src->gp_style != NULL) {
132     material_dst->gp_style = MEM_dupallocN(material_src->gp_style);
133   }
134 
135   BLI_listbase_clear(&material_dst->gpumaterial);
136 
137   /* TODO Duplicate Engine Settings and set runtime to NULL */
138 }
139 
material_free_data(ID * id)140 static void material_free_data(ID *id)
141 {
142   Material *material = (Material *)id;
143 
144   /* Free gpu material before the ntree */
145   GPU_material_free(&material->gpumaterial);
146 
147   /* is no lib link block, but material extension */
148   if (material->nodetree) {
149     ntreeFreeEmbeddedTree(material->nodetree);
150     MEM_freeN(material->nodetree);
151     material->nodetree = NULL;
152   }
153 
154   MEM_SAFE_FREE(material->texpaintslot);
155 
156   MEM_SAFE_FREE(material->gp_style);
157 
158   BKE_icon_id_delete((ID *)material);
159   BKE_previewimg_free(&material->preview);
160 }
161 
material_foreach_id(ID * id,LibraryForeachIDData * data)162 static void material_foreach_id(ID *id, LibraryForeachIDData *data)
163 {
164   Material *material = (Material *)id;
165   /* Nodetrees **are owned by IDs**, treat them as mere sub-data and not real ID! */
166   if (!BKE_library_foreach_ID_embedded(data, (ID **)&material->nodetree)) {
167     return;
168   }
169   if (material->texpaintslot != NULL) {
170     BKE_LIB_FOREACHID_PROCESS(data, material->texpaintslot->ima, IDWALK_CB_NOP);
171   }
172   if (material->gp_style != NULL) {
173     BKE_LIB_FOREACHID_PROCESS(data, material->gp_style->sima, IDWALK_CB_USER);
174     BKE_LIB_FOREACHID_PROCESS(data, material->gp_style->ima, IDWALK_CB_USER);
175   }
176 }
177 
material_blend_write(BlendWriter * writer,ID * id,const void * id_address)178 static void material_blend_write(BlendWriter *writer, ID *id, const void *id_address)
179 {
180   Material *ma = (Material *)id;
181   if (ma->id.us > 0 || BLO_write_is_undo(writer)) {
182     /* Clean up, important in undo case to reduce false detection of changed datablocks. */
183     ma->texpaintslot = NULL;
184     BLI_listbase_clear(&ma->gpumaterial);
185 
186     /* write LibData */
187     BLO_write_id_struct(writer, Material, id_address, &ma->id);
188     BKE_id_blend_write(writer, &ma->id);
189 
190     if (ma->adt) {
191       BKE_animdata_blend_write(writer, ma->adt);
192     }
193 
194     /* nodetree is integral part of material, no libdata */
195     if (ma->nodetree) {
196       BLO_write_struct(writer, bNodeTree, ma->nodetree);
197       ntreeBlendWrite(writer, ma->nodetree);
198     }
199 
200     BKE_previewimg_blend_write(writer, ma->preview);
201 
202     /* grease pencil settings */
203     if (ma->gp_style) {
204       BLO_write_struct(writer, MaterialGPencilStyle, ma->gp_style);
205     }
206   }
207 }
208 
material_blend_read_data(BlendDataReader * reader,ID * id)209 static void material_blend_read_data(BlendDataReader *reader, ID *id)
210 {
211   Material *ma = (Material *)id;
212   BLO_read_data_address(reader, &ma->adt);
213   BKE_animdata_blend_read_data(reader, ma->adt);
214 
215   ma->texpaintslot = NULL;
216 
217   BLO_read_data_address(reader, &ma->preview);
218   BKE_previewimg_blend_read(reader, ma->preview);
219 
220   BLI_listbase_clear(&ma->gpumaterial);
221 
222   BLO_read_data_address(reader, &ma->gp_style);
223 }
224 
material_blend_read_lib(BlendLibReader * reader,ID * id)225 static void material_blend_read_lib(BlendLibReader *reader, ID *id)
226 {
227   Material *ma = (Material *)id;
228   BLO_read_id_address(reader, ma->id.lib, &ma->ipo); /* XXX deprecated - old animation system */
229 
230   /* relink grease pencil settings */
231   if (ma->gp_style != NULL) {
232     MaterialGPencilStyle *gp_style = ma->gp_style;
233     if (gp_style->sima != NULL) {
234       BLO_read_id_address(reader, ma->id.lib, &gp_style->sima);
235     }
236     if (gp_style->ima != NULL) {
237       BLO_read_id_address(reader, ma->id.lib, &gp_style->ima);
238     }
239   }
240 }
241 
material_blend_read_expand(BlendExpander * expander,ID * id)242 static void material_blend_read_expand(BlendExpander *expander, ID *id)
243 {
244   Material *ma = (Material *)id;
245   BLO_expand(expander, ma->ipo); /* XXX deprecated - old animation system */
246 
247   if (ma->gp_style) {
248     MaterialGPencilStyle *gp_style = ma->gp_style;
249     BLO_expand(expander, gp_style->sima);
250     BLO_expand(expander, gp_style->ima);
251   }
252 }
253 
254 IDTypeInfo IDType_ID_MA = {
255     .id_code = ID_MA,
256     .id_filter = FILTER_ID_MA,
257     .main_listbase_index = INDEX_ID_MA,
258     .struct_size = sizeof(Material),
259     .name = "Material",
260     .name_plural = "materials",
261     .translation_context = BLT_I18NCONTEXT_ID_MATERIAL,
262     .flags = 0,
263 
264     .init_data = material_init_data,
265     .copy_data = material_copy_data,
266     .free_data = material_free_data,
267     .make_local = NULL,
268     .foreach_id = material_foreach_id,
269     .foreach_cache = NULL,
270 
271     .blend_write = material_blend_write,
272     .blend_read_data = material_blend_read_data,
273     .blend_read_lib = material_blend_read_lib,
274     .blend_read_expand = material_blend_read_expand,
275 };
276 
BKE_gpencil_material_attr_init(Material * ma)277 void BKE_gpencil_material_attr_init(Material *ma)
278 {
279   if ((ma) && (ma->gp_style == NULL)) {
280     ma->gp_style = MEM_callocN(sizeof(MaterialGPencilStyle), "Grease Pencil Material Settings");
281 
282     MaterialGPencilStyle *gp_style = ma->gp_style;
283     /* set basic settings */
284     gp_style->stroke_rgba[3] = 1.0f;
285     gp_style->fill_rgba[3] = 1.0f;
286     ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 1.0f);
287     ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f);
288     gp_style->texture_offset[0] = -0.5f;
289     gp_style->texture_pixsize = 100.0f;
290     gp_style->mix_factor = 0.5f;
291 
292     gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
293   }
294 }
295 
BKE_material_add(Main * bmain,const char * name)296 Material *BKE_material_add(Main *bmain, const char *name)
297 {
298   Material *ma;
299 
300   ma = BKE_id_new(bmain, ID_MA, name);
301 
302   return ma;
303 }
304 
BKE_gpencil_material_add(Main * bmain,const char * name)305 Material *BKE_gpencil_material_add(Main *bmain, const char *name)
306 {
307   Material *ma;
308 
309   ma = BKE_material_add(bmain, name);
310 
311   /* grease pencil settings */
312   if (ma != NULL) {
313     BKE_gpencil_material_attr_init(ma);
314   }
315   return ma;
316 }
317 
BKE_object_material_array_p(Object * ob)318 Material ***BKE_object_material_array_p(Object *ob)
319 {
320   if (ob->type == OB_MESH) {
321     Mesh *me = ob->data;
322     return &(me->mat);
323   }
324   if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
325     Curve *cu = ob->data;
326     return &(cu->mat);
327   }
328   if (ob->type == OB_MBALL) {
329     MetaBall *mb = ob->data;
330     return &(mb->mat);
331   }
332   if (ob->type == OB_GPENCIL) {
333     bGPdata *gpd = ob->data;
334     return &(gpd->mat);
335   }
336   if (ob->type == OB_HAIR) {
337     Hair *hair = ob->data;
338     return &(hair->mat);
339   }
340   if (ob->type == OB_POINTCLOUD) {
341     PointCloud *pointcloud = ob->data;
342     return &(pointcloud->mat);
343   }
344   if (ob->type == OB_VOLUME) {
345     Volume *volume = ob->data;
346     return &(volume->mat);
347   }
348   return NULL;
349 }
350 
BKE_object_material_len_p(Object * ob)351 short *BKE_object_material_len_p(Object *ob)
352 {
353   if (ob->type == OB_MESH) {
354     Mesh *me = ob->data;
355     return &(me->totcol);
356   }
357   if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
358     Curve *cu = ob->data;
359     return &(cu->totcol);
360   }
361   if (ob->type == OB_MBALL) {
362     MetaBall *mb = ob->data;
363     return &(mb->totcol);
364   }
365   if (ob->type == OB_GPENCIL) {
366     bGPdata *gpd = ob->data;
367     return &(gpd->totcol);
368   }
369   if (ob->type == OB_HAIR) {
370     Hair *hair = ob->data;
371     return &(hair->totcol);
372   }
373   if (ob->type == OB_POINTCLOUD) {
374     PointCloud *pointcloud = ob->data;
375     return &(pointcloud->totcol);
376   }
377   if (ob->type == OB_VOLUME) {
378     Volume *volume = ob->data;
379     return &(volume->totcol);
380   }
381   return NULL;
382 }
383 
384 /* same as above but for ID's */
BKE_id_material_array_p(ID * id)385 Material ***BKE_id_material_array_p(ID *id)
386 {
387   /* ensure we don't try get materials from non-obdata */
388   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
389 
390   switch (GS(id->name)) {
391     case ID_ME:
392       return &(((Mesh *)id)->mat);
393     case ID_CU:
394       return &(((Curve *)id)->mat);
395     case ID_MB:
396       return &(((MetaBall *)id)->mat);
397     case ID_GD:
398       return &(((bGPdata *)id)->mat);
399     case ID_HA:
400       return &(((Hair *)id)->mat);
401     case ID_PT:
402       return &(((PointCloud *)id)->mat);
403     case ID_VO:
404       return &(((Volume *)id)->mat);
405     default:
406       break;
407   }
408   return NULL;
409 }
410 
BKE_id_material_len_p(ID * id)411 short *BKE_id_material_len_p(ID *id)
412 {
413   /* ensure we don't try get materials from non-obdata */
414   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
415 
416   switch (GS(id->name)) {
417     case ID_ME:
418       return &(((Mesh *)id)->totcol);
419     case ID_CU:
420       return &(((Curve *)id)->totcol);
421     case ID_MB:
422       return &(((MetaBall *)id)->totcol);
423     case ID_GD:
424       return &(((bGPdata *)id)->totcol);
425     case ID_HA:
426       return &(((Hair *)id)->totcol);
427     case ID_PT:
428       return &(((PointCloud *)id)->totcol);
429     case ID_VO:
430       return &(((Volume *)id)->totcol);
431     default:
432       break;
433   }
434   return NULL;
435 }
436 
material_data_index_remove_id(ID * id,short index)437 static void material_data_index_remove_id(ID *id, short index)
438 {
439   /* ensure we don't try get materials from non-obdata */
440   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
441 
442   switch (GS(id->name)) {
443     case ID_ME:
444       BKE_mesh_material_index_remove((Mesh *)id, index);
445       break;
446     case ID_CU:
447       BKE_curve_material_index_remove((Curve *)id, index);
448       break;
449     case ID_MB:
450     case ID_HA:
451     case ID_PT:
452     case ID_VO:
453       /* No material indices for these object data types. */
454       break;
455     default:
456       break;
457   }
458 }
459 
BKE_object_material_slot_used(ID * id,short actcol)460 bool BKE_object_material_slot_used(ID *id, short actcol)
461 {
462   /* ensure we don't try get materials from non-obdata */
463   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
464 
465   switch (GS(id->name)) {
466     case ID_ME:
467       return BKE_mesh_material_index_used((Mesh *)id, actcol - 1);
468     case ID_CU:
469       return BKE_curve_material_index_used((Curve *)id, actcol - 1);
470     case ID_MB:
471       /* meta-elems don't have materials atm */
472       return false;
473     case ID_GD:
474       return BKE_gpencil_material_index_used((bGPdata *)id, actcol - 1);
475     default:
476       return false;
477   }
478 }
479 
material_data_index_clear_id(ID * id)480 static void material_data_index_clear_id(ID *id)
481 {
482   /* ensure we don't try get materials from non-obdata */
483   BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
484 
485   switch (GS(id->name)) {
486     case ID_ME:
487       BKE_mesh_material_index_clear((Mesh *)id);
488       break;
489     case ID_CU:
490       BKE_curve_material_index_clear((Curve *)id);
491       break;
492     case ID_MB:
493     case ID_HA:
494     case ID_PT:
495     case ID_VO:
496       /* No material indices for these object data types. */
497       break;
498     default:
499       break;
500   }
501 }
502 
BKE_id_materials_copy(Main * bmain,ID * id_src,ID * id_dst)503 void BKE_id_materials_copy(Main *bmain, ID *id_src, ID *id_dst)
504 {
505   Material ***matar_src = BKE_id_material_array_p(id_src);
506   const short *materials_len_p_src = BKE_id_material_len_p(id_src);
507 
508   Material ***matar_dst = BKE_id_material_array_p(id_dst);
509   short *materials_len_p_dst = BKE_id_material_len_p(id_dst);
510 
511   *materials_len_p_dst = *materials_len_p_src;
512   if (*materials_len_p_src != 0) {
513     (*matar_dst) = MEM_dupallocN(*matar_src);
514 
515     for (int a = 0; a < *materials_len_p_src; a++) {
516       id_us_plus((ID *)(*matar_dst)[a]);
517     }
518 
519     DEG_id_tag_update(id_dst, ID_RECALC_COPY_ON_WRITE);
520     DEG_relations_tag_update(bmain);
521   }
522 }
523 
BKE_id_material_resize(Main * bmain,ID * id,short totcol,bool do_id_user)524 void BKE_id_material_resize(Main *bmain, ID *id, short totcol, bool do_id_user)
525 {
526   Material ***matar = BKE_id_material_array_p(id);
527   short *totcolp = BKE_id_material_len_p(id);
528 
529   if (matar == NULL) {
530     return;
531   }
532 
533   if (do_id_user && totcol < (*totcolp)) {
534     short i;
535     for (i = totcol; i < (*totcolp); i++) {
536       id_us_min((ID *)(*matar)[i]);
537     }
538   }
539 
540   if (totcol == 0) {
541     if (*totcolp) {
542       MEM_freeN(*matar);
543       *matar = NULL;
544     }
545   }
546   else {
547     *matar = MEM_recallocN(*matar, sizeof(void *) * totcol);
548   }
549   *totcolp = totcol;
550 
551   DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
552   DEG_relations_tag_update(bmain);
553 }
554 
BKE_id_material_append(Main * bmain,ID * id,Material * ma)555 void BKE_id_material_append(Main *bmain, ID *id, Material *ma)
556 {
557   Material ***matar;
558   if ((matar = BKE_id_material_array_p(id))) {
559     short *totcol = BKE_id_material_len_p(id);
560     Material **mat = MEM_callocN(sizeof(void *) * ((*totcol) + 1), "newmatar");
561     if (*totcol) {
562       memcpy(mat, *matar, sizeof(void *) * (*totcol));
563     }
564     if (*matar) {
565       MEM_freeN(*matar);
566     }
567 
568     *matar = mat;
569     (*matar)[(*totcol)++] = ma;
570 
571     id_us_plus((ID *)ma);
572     BKE_objects_materials_test_all(bmain, id);
573 
574     DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
575     DEG_relations_tag_update(bmain);
576   }
577 }
578 
BKE_id_material_pop(Main * bmain,ID * id,int index_i)579 Material *BKE_id_material_pop(Main *bmain, ID *id, int index_i)
580 {
581   short index = (short)index_i;
582   Material *ret = NULL;
583   Material ***matar;
584   if ((matar = BKE_id_material_array_p(id))) {
585     short *totcol = BKE_id_material_len_p(id);
586     if (index >= 0 && index < (*totcol)) {
587       ret = (*matar)[index];
588       id_us_min((ID *)ret);
589 
590       if (*totcol <= 1) {
591         *totcol = 0;
592         MEM_freeN(*matar);
593         *matar = NULL;
594       }
595       else {
596         if (index + 1 != (*totcol)) {
597           memmove((*matar) + index,
598                   (*matar) + (index + 1),
599                   sizeof(void *) * ((*totcol) - (index + 1)));
600         }
601 
602         (*totcol)--;
603         *matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol));
604         BKE_objects_materials_test_all(bmain, id);
605       }
606 
607       material_data_index_remove_id(id, index);
608 
609       DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
610       DEG_relations_tag_update(bmain);
611     }
612   }
613 
614   return ret;
615 }
616 
BKE_id_material_clear(Main * bmain,ID * id)617 void BKE_id_material_clear(Main *bmain, ID *id)
618 {
619   Material ***matar;
620   if ((matar = BKE_id_material_array_p(id))) {
621     short *totcol = BKE_id_material_len_p(id);
622 
623     while ((*totcol)--) {
624       id_us_min((ID *)((*matar)[*totcol]));
625     }
626     *totcol = 0;
627     if (*matar) {
628       MEM_freeN(*matar);
629       *matar = NULL;
630     }
631 
632     BKE_objects_materials_test_all(bmain, id);
633     material_data_index_clear_id(id);
634 
635     DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
636     DEG_relations_tag_update(bmain);
637   }
638 }
639 
BKE_object_material_get_p(Object * ob,short act)640 Material **BKE_object_material_get_p(Object *ob, short act)
641 {
642   Material ***matarar, **ma_p;
643   const short *totcolp;
644 
645   if (ob == NULL) {
646     return NULL;
647   }
648 
649   /* if object cannot have material, (totcolp == NULL) */
650   totcolp = BKE_object_material_len_p(ob);
651   if (totcolp == NULL || ob->totcol == 0) {
652     return NULL;
653   }
654 
655   /* return NULL for invalid 'act', can happen for mesh face indices */
656   if (act > ob->totcol) {
657     return NULL;
658   }
659   if (act <= 0) {
660     if (act < 0) {
661       CLOG_ERROR(&LOG, "Negative material index!");
662     }
663     return NULL;
664   }
665 
666   if (ob->matbits && ob->matbits[act - 1]) { /* in object */
667     ma_p = &ob->mat[act - 1];
668   }
669   else { /* in data */
670 
671     /* check for inconsistency */
672     if (*totcolp < ob->totcol) {
673       ob->totcol = *totcolp;
674     }
675     if (act > ob->totcol) {
676       act = ob->totcol;
677     }
678 
679     matarar = BKE_object_material_array_p(ob);
680 
681     if (matarar && *matarar) {
682       ma_p = &(*matarar)[act - 1];
683     }
684     else {
685       ma_p = NULL;
686     }
687   }
688 
689   return ma_p;
690 }
691 
BKE_object_material_get(Object * ob,short act)692 Material *BKE_object_material_get(Object *ob, short act)
693 {
694   Material **ma_p = BKE_object_material_get_p(ob, act);
695   return ma_p ? *ma_p : NULL;
696 }
697 
BKE_gpencil_material(Object * ob,short act)698 Material *BKE_gpencil_material(Object *ob, short act)
699 {
700   Material *ma = BKE_object_material_get(ob, act);
701   if (ma != NULL) {
702     return ma;
703   }
704 
705   return BKE_material_default_gpencil();
706 }
707 
BKE_gpencil_material_settings(Object * ob,short act)708 MaterialGPencilStyle *BKE_gpencil_material_settings(Object *ob, short act)
709 {
710   Material *ma = BKE_object_material_get(ob, act);
711   if (ma != NULL) {
712     if (ma->gp_style == NULL) {
713       BKE_gpencil_material_attr_init(ma);
714     }
715 
716     return ma->gp_style;
717   }
718 
719   return BKE_material_default_gpencil()->gp_style;
720 }
721 
BKE_object_material_resize(Main * bmain,Object * ob,const short totcol,bool do_id_user)722 void BKE_object_material_resize(Main *bmain, Object *ob, const short totcol, bool do_id_user)
723 {
724   Material **newmatar;
725   char *newmatbits;
726 
727   if (do_id_user && totcol < ob->totcol) {
728     for (int i = totcol; i < ob->totcol; i++) {
729       id_us_min((ID *)ob->mat[i]);
730     }
731   }
732 
733   if (totcol == 0) {
734     if (ob->totcol) {
735       MEM_freeN(ob->mat);
736       MEM_freeN(ob->matbits);
737       ob->mat = NULL;
738       ob->matbits = NULL;
739     }
740   }
741   else if (ob->totcol < totcol) {
742     newmatar = MEM_callocN(sizeof(void *) * totcol, "newmatar");
743     newmatbits = MEM_callocN(sizeof(char) * totcol, "newmatbits");
744     if (ob->totcol) {
745       memcpy(newmatar, ob->mat, sizeof(void *) * ob->totcol);
746       memcpy(newmatbits, ob->matbits, sizeof(char) * ob->totcol);
747       MEM_freeN(ob->mat);
748       MEM_freeN(ob->matbits);
749     }
750     ob->mat = newmatar;
751     ob->matbits = newmatbits;
752   }
753   /* XXX, why not realloc on shrink? - campbell */
754 
755   ob->totcol = totcol;
756   if (ob->totcol && ob->actcol == 0) {
757     ob->actcol = 1;
758   }
759   if (ob->actcol > ob->totcol) {
760     ob->actcol = ob->totcol;
761   }
762 
763   DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_GEOMETRY);
764   DEG_relations_tag_update(bmain);
765 }
766 
BKE_object_materials_test(Main * bmain,Object * ob,ID * id)767 void BKE_object_materials_test(Main *bmain, Object *ob, ID *id)
768 {
769   /* make the ob mat-array same size as 'ob->data' mat-array */
770   const short *totcol;
771 
772   if (id == NULL || (totcol = BKE_id_material_len_p(id)) == NULL) {
773     return;
774   }
775 
776   BKE_object_material_resize(bmain, ob, *totcol, false);
777 }
778 
BKE_objects_materials_test_all(Main * bmain,ID * id)779 void BKE_objects_materials_test_all(Main *bmain, ID *id)
780 {
781   /* make the ob mat-array same size as 'ob->data' mat-array */
782   Object *ob;
783   const short *totcol;
784 
785   if (id == NULL || (totcol = BKE_id_material_len_p(id)) == NULL) {
786     return;
787   }
788 
789   BKE_main_lock(bmain);
790   for (ob = bmain->objects.first; ob; ob = ob->id.next) {
791     if (ob->data == id) {
792       BKE_object_material_resize(bmain, ob, *totcol, false);
793     }
794   }
795   BKE_main_unlock(bmain);
796 }
797 
BKE_id_material_assign(Main * bmain,ID * id,Material * ma,short act)798 void BKE_id_material_assign(Main *bmain, ID *id, Material *ma, short act)
799 {
800   Material *mao, **matar, ***matarar;
801   short *totcolp;
802 
803   if (act > MAXMAT) {
804     return;
805   }
806   if (act < 1) {
807     act = 1;
808   }
809 
810   /* test arraylens */
811 
812   totcolp = BKE_id_material_len_p(id);
813   matarar = BKE_id_material_array_p(id);
814 
815   if (totcolp == NULL || matarar == NULL) {
816     return;
817   }
818 
819   if (act > *totcolp) {
820     matar = MEM_callocN(sizeof(void *) * act, "matarray1");
821 
822     if (*totcolp) {
823       memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
824       MEM_freeN(*matarar);
825     }
826 
827     *matarar = matar;
828     *totcolp = act;
829   }
830 
831   /* in data */
832   mao = (*matarar)[act - 1];
833   if (mao) {
834     id_us_min(&mao->id);
835   }
836   (*matarar)[act - 1] = ma;
837 
838   if (ma) {
839     id_us_plus(&ma->id);
840   }
841 
842   BKE_objects_materials_test_all(bmain, id);
843 }
844 
BKE_object_material_assign(Main * bmain,Object * ob,Material * ma,short act,int assign_type)845 void BKE_object_material_assign(Main *bmain, Object *ob, Material *ma, short act, int assign_type)
846 {
847   Material *mao, **matar, ***matarar;
848   short *totcolp;
849   char bit = 0;
850 
851   if (act > MAXMAT) {
852     return;
853   }
854   if (act < 1) {
855     act = 1;
856   }
857 
858   /* prevent crashing when using accidentally */
859   BLI_assert(!ID_IS_LINKED(ob));
860   if (ID_IS_LINKED(ob)) {
861     return;
862   }
863 
864   /* test arraylens */
865 
866   totcolp = BKE_object_material_len_p(ob);
867   matarar = BKE_object_material_array_p(ob);
868 
869   if (totcolp == NULL || matarar == NULL) {
870     return;
871   }
872 
873   if (act > *totcolp) {
874     matar = MEM_callocN(sizeof(void *) * act, "matarray1");
875 
876     if (*totcolp) {
877       memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
878       MEM_freeN(*matarar);
879     }
880 
881     *matarar = matar;
882     *totcolp = act;
883   }
884 
885   if (act > ob->totcol) {
886     /* Need more space in the material arrays */
887     ob->mat = MEM_recallocN_id(ob->mat, sizeof(void *) * act, "matarray2");
888     ob->matbits = MEM_recallocN_id(ob->matbits, sizeof(char) * act, "matbits1");
889     ob->totcol = act;
890   }
891 
892   /* Determine the object/mesh linking */
893   if (assign_type == BKE_MAT_ASSIGN_EXISTING) {
894     /* keep existing option (avoid confusion in scripts),
895      * intentionally ignore userpref (default to obdata). */
896     bit = ob->matbits[act - 1];
897   }
898   else if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->totcol && ob->actcol) {
899     /* copy from previous material */
900     bit = ob->matbits[ob->actcol - 1];
901   }
902   else {
903     switch (assign_type) {
904       case BKE_MAT_ASSIGN_OBDATA:
905         bit = 0;
906         break;
907       case BKE_MAT_ASSIGN_OBJECT:
908         bit = 1;
909         break;
910       case BKE_MAT_ASSIGN_USERPREF:
911       default:
912         bit = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
913         break;
914     }
915   }
916 
917   /* do it */
918 
919   ob->matbits[act - 1] = bit;
920   if (bit == 1) { /* in object */
921     mao = ob->mat[act - 1];
922     if (mao) {
923       id_us_min(&mao->id);
924     }
925     ob->mat[act - 1] = ma;
926     BKE_object_materials_test(bmain, ob, ob->data);
927   }
928   else { /* in data */
929     mao = (*matarar)[act - 1];
930     if (mao) {
931       id_us_min(&mao->id);
932     }
933     (*matarar)[act - 1] = ma;
934     BKE_objects_materials_test_all(bmain, ob->data); /* Data may be used by several objects... */
935   }
936 
937   if (ma) {
938     id_us_plus(&ma->id);
939   }
940 }
941 
BKE_object_material_remap(Object * ob,const unsigned int * remap)942 void BKE_object_material_remap(Object *ob, const unsigned int *remap)
943 {
944   Material ***matar = BKE_object_material_array_p(ob);
945   const short *totcol_p = BKE_object_material_len_p(ob);
946 
947   BLI_array_permute(ob->mat, ob->totcol, remap);
948 
949   if (ob->matbits) {
950     BLI_array_permute(ob->matbits, ob->totcol, remap);
951   }
952 
953   if (matar) {
954     BLI_array_permute(*matar, *totcol_p, remap);
955   }
956 
957   if (ob->type == OB_MESH) {
958     BKE_mesh_material_remap(ob->data, remap, ob->totcol);
959   }
960   else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
961     BKE_curve_material_remap(ob->data, remap, ob->totcol);
962   }
963   else if (ob->type == OB_GPENCIL) {
964     BKE_gpencil_material_remap(ob->data, remap, ob->totcol);
965   }
966   else {
967     /* add support for this object data! */
968     BLI_assert(matar == NULL);
969   }
970 }
971 
972 /**
973  * Calculate a material remapping from \a ob_src to \a ob_dst.
974  *
975  * \param remap_src_to_dst: An array the size of `ob_src->totcol`
976  * where index values are filled in which map to \a ob_dst materials.
977  */
BKE_object_material_remap_calc(Object * ob_dst,Object * ob_src,short * remap_src_to_dst)978 void BKE_object_material_remap_calc(Object *ob_dst, Object *ob_src, short *remap_src_to_dst)
979 {
980   if (ob_src->totcol == 0) {
981     return;
982   }
983 
984   GHash *gh_mat_map = BLI_ghash_ptr_new_ex(__func__, ob_src->totcol);
985 
986   for (int i = 0; i < ob_dst->totcol; i++) {
987     Material *ma_src = BKE_object_material_get(ob_dst, i + 1);
988     BLI_ghash_reinsert(gh_mat_map, ma_src, POINTER_FROM_INT(i), NULL, NULL);
989   }
990 
991   /* setup default mapping (when materials don't match) */
992   {
993     int i = 0;
994     if (ob_dst->totcol >= ob_src->totcol) {
995       for (; i < ob_src->totcol; i++) {
996         remap_src_to_dst[i] = i;
997       }
998     }
999     else {
1000       for (; i < ob_dst->totcol; i++) {
1001         remap_src_to_dst[i] = i;
1002       }
1003       for (; i < ob_src->totcol; i++) {
1004         remap_src_to_dst[i] = 0;
1005       }
1006     }
1007   }
1008 
1009   for (int i = 0; i < ob_src->totcol; i++) {
1010     Material *ma_src = BKE_object_material_get(ob_src, i + 1);
1011 
1012     if ((i < ob_dst->totcol) && (ma_src == BKE_object_material_get(ob_dst, i + 1))) {
1013       /* when objects have exact matching materials - keep existing index */
1014     }
1015     else {
1016       void **index_src_p = BLI_ghash_lookup_p(gh_mat_map, ma_src);
1017       if (index_src_p) {
1018         remap_src_to_dst[i] = POINTER_AS_INT(*index_src_p);
1019       }
1020     }
1021   }
1022 
1023   BLI_ghash_free(gh_mat_map, NULL, NULL);
1024 }
1025 
1026 /* XXX - this calls many more update calls per object then are needed, could be optimized */
BKE_object_material_array_assign(Main * bmain,struct Object * ob,struct Material *** matar,int totcol,const bool to_object_only)1027 void BKE_object_material_array_assign(Main *bmain,
1028                                       struct Object *ob,
1029                                       struct Material ***matar,
1030                                       int totcol,
1031                                       const bool to_object_only)
1032 {
1033   int actcol_orig = ob->actcol;
1034 
1035   while ((ob->totcol > totcol) && BKE_object_material_slot_remove(bmain, ob)) {
1036     /* pass */
1037   }
1038 
1039   /* now we have the right number of slots */
1040   for (int i = 0; i < totcol; i++) {
1041     if (to_object_only && ob->matbits[i] == 0) {
1042       /* If we only assign to object, and that slot uses obdata material, do nothing. */
1043       continue;
1044     }
1045     BKE_object_material_assign(bmain,
1046                                ob,
1047                                (*matar)[i],
1048                                i + 1,
1049                                to_object_only ? BKE_MAT_ASSIGN_OBJECT : BKE_MAT_ASSIGN_USERPREF);
1050   }
1051 
1052   if (actcol_orig > ob->totcol) {
1053     actcol_orig = ob->totcol;
1054   }
1055 
1056   ob->actcol = actcol_orig;
1057 }
1058 
BKE_object_material_slot_find_index(Object * ob,Material * ma)1059 short BKE_object_material_slot_find_index(Object *ob, Material *ma)
1060 {
1061   Material ***matarar;
1062   short a, *totcolp;
1063 
1064   if (ma == NULL) {
1065     return 0;
1066   }
1067 
1068   totcolp = BKE_object_material_len_p(ob);
1069   matarar = BKE_object_material_array_p(ob);
1070 
1071   if (totcolp == NULL || matarar == NULL) {
1072     return 0;
1073   }
1074 
1075   for (a = 0; a < *totcolp; a++) {
1076     if ((*matarar)[a] == ma) {
1077       break;
1078     }
1079   }
1080   if (a < *totcolp) {
1081     return a + 1;
1082   }
1083   return 0;
1084 }
1085 
BKE_object_material_slot_add(Main * bmain,Object * ob)1086 bool BKE_object_material_slot_add(Main *bmain, Object *ob)
1087 {
1088   if (ob == NULL) {
1089     return false;
1090   }
1091   if (ob->totcol >= MAXMAT) {
1092     return false;
1093   }
1094 
1095   BKE_object_material_assign(bmain, ob, NULL, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
1096   ob->actcol = ob->totcol;
1097   return true;
1098 }
1099 
1100 /* ****************** */
1101 
BKE_object_material_slot_remove(Main * bmain,Object * ob)1102 bool BKE_object_material_slot_remove(Main *bmain, Object *ob)
1103 {
1104   Material *mao, ***matarar;
1105   short *totcolp;
1106 
1107   if (ob == NULL || ob->totcol == 0) {
1108     return false;
1109   }
1110 
1111   /* this should never happen and used to crash */
1112   if (ob->actcol <= 0) {
1113     CLOG_ERROR(&LOG, "invalid material index %d, report a bug!", ob->actcol);
1114     BLI_assert(0);
1115     return false;
1116   }
1117 
1118   /* take a mesh/curve/mball as starting point, remove 1 index,
1119    * AND with all objects that share the ob->data
1120    *
1121    * after that check indices in mesh/curve/mball!!!
1122    */
1123 
1124   totcolp = BKE_object_material_len_p(ob);
1125   matarar = BKE_object_material_array_p(ob);
1126 
1127   if (ELEM(NULL, matarar, *matarar)) {
1128     return false;
1129   }
1130 
1131   /* can happen on face selection in editmode */
1132   if (ob->actcol > ob->totcol) {
1133     ob->actcol = ob->totcol;
1134   }
1135 
1136   /* we delete the actcol */
1137   mao = (*matarar)[ob->actcol - 1];
1138   if (mao) {
1139     id_us_min(&mao->id);
1140   }
1141 
1142   for (int a = ob->actcol; a < ob->totcol; a++) {
1143     (*matarar)[a - 1] = (*matarar)[a];
1144   }
1145   (*totcolp)--;
1146 
1147   if (*totcolp == 0) {
1148     MEM_freeN(*matarar);
1149     *matarar = NULL;
1150   }
1151 
1152   const int actcol = ob->actcol;
1153 
1154   for (Object *obt = bmain->objects.first; obt; obt = obt->id.next) {
1155     if (obt->data == ob->data) {
1156       /* Can happen when object material lists are used, see: T52953 */
1157       if (actcol > obt->totcol) {
1158         continue;
1159       }
1160       /* WATCH IT: do not use actcol from ob or from obt (can become zero) */
1161       mao = obt->mat[actcol - 1];
1162       if (mao) {
1163         id_us_min(&mao->id);
1164       }
1165 
1166       for (int a = actcol; a < obt->totcol; a++) {
1167         obt->mat[a - 1] = obt->mat[a];
1168         obt->matbits[a - 1] = obt->matbits[a];
1169       }
1170       obt->totcol--;
1171       if (obt->actcol > obt->totcol) {
1172         obt->actcol = obt->totcol;
1173       }
1174 
1175       if (obt->totcol == 0) {
1176         MEM_freeN(obt->mat);
1177         MEM_freeN(obt->matbits);
1178         obt->mat = NULL;
1179         obt->matbits = NULL;
1180       }
1181     }
1182   }
1183 
1184   /* check indices from mesh */
1185   if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
1186     material_data_index_remove_id((ID *)ob->data, actcol - 1);
1187     if (ob->runtime.curve_cache) {
1188       BKE_displist_free(&ob->runtime.curve_cache->disp);
1189     }
1190   }
1191   /* check indices from gpencil */
1192   else if (ob->type == OB_GPENCIL) {
1193     BKE_gpencil_material_index_reassign((bGPdata *)ob->data, ob->totcol, actcol - 1);
1194   }
1195 
1196   return true;
1197 }
1198 
nodetree_uv_node_recursive(bNode * node)1199 static bNode *nodetree_uv_node_recursive(bNode *node)
1200 {
1201   bNode *inode;
1202   bNodeSocket *sock;
1203 
1204   for (sock = node->inputs.first; sock; sock = sock->next) {
1205     if (sock->link) {
1206       inode = sock->link->fromnode;
1207       if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) {
1208         return inode;
1209       }
1210 
1211       return nodetree_uv_node_recursive(inode);
1212     }
1213   }
1214 
1215   return NULL;
1216 }
1217 
1218 typedef bool (*ForEachTexNodeCallback)(bNode *node, void *userdata);
ntree_foreach_texnode_recursive(bNodeTree * nodetree,ForEachTexNodeCallback callback,void * userdata)1219 static bool ntree_foreach_texnode_recursive(bNodeTree *nodetree,
1220                                             ForEachTexNodeCallback callback,
1221                                             void *userdata)
1222 {
1223   LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
1224     if (node->typeinfo->nclass == NODE_CLASS_TEXTURE &&
1225         node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
1226       if (!callback(node, userdata)) {
1227         return false;
1228       }
1229     }
1230     else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
1231       /* recurse into the node group and see if it contains any textures */
1232       if (!ntree_foreach_texnode_recursive((bNodeTree *)node->id, callback, userdata)) {
1233         return false;
1234       }
1235     }
1236   }
1237   return true;
1238 }
1239 
count_texture_nodes_cb(bNode * UNUSED (node),void * userdata)1240 static bool count_texture_nodes_cb(bNode *UNUSED(node), void *userdata)
1241 {
1242   (*((int *)userdata))++;
1243   return true;
1244 }
1245 
count_texture_nodes_recursive(bNodeTree * nodetree)1246 static int count_texture_nodes_recursive(bNodeTree *nodetree)
1247 {
1248   int tex_nodes = 0;
1249   ntree_foreach_texnode_recursive(nodetree, count_texture_nodes_cb, &tex_nodes);
1250 
1251   return tex_nodes;
1252 }
1253 
1254 struct FillTexPaintSlotsData {
1255   bNode *active_node;
1256   Material *ma;
1257   int index;
1258   int slot_len;
1259 };
1260 
fill_texpaint_slots_cb(bNode * node,void * userdata)1261 static bool fill_texpaint_slots_cb(bNode *node, void *userdata)
1262 {
1263   struct FillTexPaintSlotsData *fill_data = userdata;
1264 
1265   Material *ma = fill_data->ma;
1266   int index = fill_data->index;
1267   fill_data->index++;
1268 
1269   if (fill_data->active_node == node) {
1270     ma->paint_active_slot = index;
1271   }
1272 
1273   ma->texpaintslot[index].ima = (Image *)node->id;
1274   ma->texpaintslot[index].interp = ((NodeTexImage *)node->storage)->interpolation;
1275 
1276   /* for new renderer, we need to traverse the treeback in search of a UV node */
1277   bNode *uvnode = nodetree_uv_node_recursive(node);
1278 
1279   if (uvnode) {
1280     NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
1281     ma->texpaintslot[index].uvname = storage->uv_map;
1282     /* set a value to index so UI knows that we have a valid pointer for the mesh */
1283     ma->texpaintslot[index].valid = true;
1284   }
1285   else {
1286     /* just invalidate the index here so UV map does not get displayed on the UI */
1287     ma->texpaintslot[index].valid = false;
1288   }
1289 
1290   return fill_data->index != fill_data->slot_len;
1291 }
1292 
fill_texpaint_slots_recursive(bNodeTree * nodetree,bNode * active_node,Material * ma,int slot_len)1293 static void fill_texpaint_slots_recursive(bNodeTree *nodetree,
1294                                           bNode *active_node,
1295                                           Material *ma,
1296                                           int slot_len)
1297 {
1298   struct FillTexPaintSlotsData fill_data = {active_node, ma, 0, slot_len};
1299   ntree_foreach_texnode_recursive(nodetree, fill_texpaint_slots_cb, &fill_data);
1300 }
1301 
BKE_texpaint_slot_refresh_cache(Scene * scene,Material * ma)1302 void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
1303 {
1304   int count = 0;
1305 
1306   if (!ma) {
1307     return;
1308   }
1309 
1310   /* COW needed when adding texture slot on an object with no materials. */
1311   DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
1312 
1313   if (ma->texpaintslot) {
1314     MEM_freeN(ma->texpaintslot);
1315     ma->tot_slots = 0;
1316     ma->texpaintslot = NULL;
1317   }
1318 
1319   if (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
1320     ma->paint_active_slot = 0;
1321     ma->paint_clone_slot = 0;
1322     return;
1323   }
1324 
1325   if (!(ma->nodetree)) {
1326     ma->paint_active_slot = 0;
1327     ma->paint_clone_slot = 0;
1328     return;
1329   }
1330 
1331   count = count_texture_nodes_recursive(ma->nodetree);
1332 
1333   if (count == 0) {
1334     ma->paint_active_slot = 0;
1335     ma->paint_clone_slot = 0;
1336     return;
1337   }
1338 
1339   ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
1340 
1341   bNode *active_node = nodeGetActiveTexture(ma->nodetree);
1342 
1343   fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, count);
1344 
1345   ma->tot_slots = count;
1346 
1347   if (ma->paint_active_slot >= count) {
1348     ma->paint_active_slot = count - 1;
1349   }
1350 
1351   if (ma->paint_clone_slot >= count) {
1352     ma->paint_clone_slot = count - 1;
1353   }
1354 }
1355 
BKE_texpaint_slots_refresh_object(Scene * scene,struct Object * ob)1356 void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
1357 {
1358   for (int i = 1; i < ob->totcol + 1; i++) {
1359     Material *ma = BKE_object_material_get(ob, i);
1360     BKE_texpaint_slot_refresh_cache(scene, ma);
1361   }
1362 }
1363 
1364 struct FindTexPaintNodeData {
1365   bNode *node;
1366   short iter_index;
1367   short index;
1368 };
1369 
texpaint_slot_node_find_cb(bNode * node,void * userdata)1370 static bool texpaint_slot_node_find_cb(bNode *node, void *userdata)
1371 {
1372   struct FindTexPaintNodeData *find_data = userdata;
1373   if (find_data->iter_index++ == find_data->index) {
1374     find_data->node = node;
1375     return false;
1376   }
1377 
1378   return true;
1379 }
1380 
BKE_texpaint_slot_material_find_node(Material * ma,short texpaint_slot)1381 bNode *BKE_texpaint_slot_material_find_node(Material *ma, short texpaint_slot)
1382 {
1383   struct FindTexPaintNodeData find_data = {NULL, 0, texpaint_slot};
1384   ntree_foreach_texnode_recursive(ma->nodetree, texpaint_slot_node_find_cb, &find_data);
1385 
1386   return find_data.node;
1387 }
1388 
1389 /* r_col = current value, col = new value, (fac == 0) is no change */
ramp_blend(int type,float r_col[3],const float fac,const float col[3])1390 void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
1391 {
1392   float tmp, facm = 1.0f - fac;
1393 
1394   switch (type) {
1395     case MA_RAMP_BLEND:
1396       r_col[0] = facm * (r_col[0]) + fac * col[0];
1397       r_col[1] = facm * (r_col[1]) + fac * col[1];
1398       r_col[2] = facm * (r_col[2]) + fac * col[2];
1399       break;
1400     case MA_RAMP_ADD:
1401       r_col[0] += fac * col[0];
1402       r_col[1] += fac * col[1];
1403       r_col[2] += fac * col[2];
1404       break;
1405     case MA_RAMP_MULT:
1406       r_col[0] *= (facm + fac * col[0]);
1407       r_col[1] *= (facm + fac * col[1]);
1408       r_col[2] *= (facm + fac * col[2]);
1409       break;
1410     case MA_RAMP_SCREEN:
1411       r_col[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1412       r_col[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1413       r_col[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1414       break;
1415     case MA_RAMP_OVERLAY:
1416       if (r_col[0] < 0.5f) {
1417         r_col[0] *= (facm + 2.0f * fac * col[0]);
1418       }
1419       else {
1420         r_col[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1421       }
1422       if (r_col[1] < 0.5f) {
1423         r_col[1] *= (facm + 2.0f * fac * col[1]);
1424       }
1425       else {
1426         r_col[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1427       }
1428       if (r_col[2] < 0.5f) {
1429         r_col[2] *= (facm + 2.0f * fac * col[2]);
1430       }
1431       else {
1432         r_col[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1433       }
1434       break;
1435     case MA_RAMP_SUB:
1436       r_col[0] -= fac * col[0];
1437       r_col[1] -= fac * col[1];
1438       r_col[2] -= fac * col[2];
1439       break;
1440     case MA_RAMP_DIV:
1441       if (col[0] != 0.0f) {
1442         r_col[0] = facm * (r_col[0]) + fac * (r_col[0]) / col[0];
1443       }
1444       if (col[1] != 0.0f) {
1445         r_col[1] = facm * (r_col[1]) + fac * (r_col[1]) / col[1];
1446       }
1447       if (col[2] != 0.0f) {
1448         r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2];
1449       }
1450       break;
1451     case MA_RAMP_DIFF:
1452       r_col[0] = facm * (r_col[0]) + fac * fabsf(r_col[0] - col[0]);
1453       r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]);
1454       r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]);
1455       break;
1456     case MA_RAMP_DARK:
1457       r_col[0] = min_ff(r_col[0], col[0]) * fac + r_col[0] * facm;
1458       r_col[1] = min_ff(r_col[1], col[1]) * fac + r_col[1] * facm;
1459       r_col[2] = min_ff(r_col[2], col[2]) * fac + r_col[2] * facm;
1460       break;
1461     case MA_RAMP_LIGHT:
1462       tmp = fac * col[0];
1463       if (tmp > r_col[0]) {
1464         r_col[0] = tmp;
1465       }
1466       tmp = fac * col[1];
1467       if (tmp > r_col[1]) {
1468         r_col[1] = tmp;
1469       }
1470       tmp = fac * col[2];
1471       if (tmp > r_col[2]) {
1472         r_col[2] = tmp;
1473       }
1474       break;
1475     case MA_RAMP_DODGE:
1476       if (r_col[0] != 0.0f) {
1477         tmp = 1.0f - fac * col[0];
1478         if (tmp <= 0.0f) {
1479           r_col[0] = 1.0f;
1480         }
1481         else if ((tmp = (r_col[0]) / tmp) > 1.0f) {
1482           r_col[0] = 1.0f;
1483         }
1484         else {
1485           r_col[0] = tmp;
1486         }
1487       }
1488       if (r_col[1] != 0.0f) {
1489         tmp = 1.0f - fac * col[1];
1490         if (tmp <= 0.0f) {
1491           r_col[1] = 1.0f;
1492         }
1493         else if ((tmp = (r_col[1]) / tmp) > 1.0f) {
1494           r_col[1] = 1.0f;
1495         }
1496         else {
1497           r_col[1] = tmp;
1498         }
1499       }
1500       if (r_col[2] != 0.0f) {
1501         tmp = 1.0f - fac * col[2];
1502         if (tmp <= 0.0f) {
1503           r_col[2] = 1.0f;
1504         }
1505         else if ((tmp = (r_col[2]) / tmp) > 1.0f) {
1506           r_col[2] = 1.0f;
1507         }
1508         else {
1509           r_col[2] = tmp;
1510         }
1511       }
1512       break;
1513     case MA_RAMP_BURN:
1514       tmp = facm + fac * col[0];
1515 
1516       if (tmp <= 0.0f) {
1517         r_col[0] = 0.0f;
1518       }
1519       else if ((tmp = (1.0f - (1.0f - (r_col[0])) / tmp)) < 0.0f) {
1520         r_col[0] = 0.0f;
1521       }
1522       else if (tmp > 1.0f) {
1523         r_col[0] = 1.0f;
1524       }
1525       else {
1526         r_col[0] = tmp;
1527       }
1528 
1529       tmp = facm + fac * col[1];
1530       if (tmp <= 0.0f) {
1531         r_col[1] = 0.0f;
1532       }
1533       else if ((tmp = (1.0f - (1.0f - (r_col[1])) / tmp)) < 0.0f) {
1534         r_col[1] = 0.0f;
1535       }
1536       else if (tmp > 1.0f) {
1537         r_col[1] = 1.0f;
1538       }
1539       else {
1540         r_col[1] = tmp;
1541       }
1542 
1543       tmp = facm + fac * col[2];
1544       if (tmp <= 0.0f) {
1545         r_col[2] = 0.0f;
1546       }
1547       else if ((tmp = (1.0f - (1.0f - (r_col[2])) / tmp)) < 0.0f) {
1548         r_col[2] = 0.0f;
1549       }
1550       else if (tmp > 1.0f) {
1551         r_col[2] = 1.0f;
1552       }
1553       else {
1554         r_col[2] = tmp;
1555       }
1556       break;
1557     case MA_RAMP_HUE: {
1558       float rH, rS, rV;
1559       float colH, colS, colV;
1560       float tmpr, tmpg, tmpb;
1561       rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1562       if (colS != 0) {
1563         rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1564         hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb);
1565         r_col[0] = facm * (r_col[0]) + fac * tmpr;
1566         r_col[1] = facm * (r_col[1]) + fac * tmpg;
1567         r_col[2] = facm * (r_col[2]) + fac * tmpb;
1568       }
1569       break;
1570     }
1571     case MA_RAMP_SAT: {
1572       float rH, rS, rV;
1573       float colH, colS, colV;
1574       rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1575       if (rS != 0) {
1576         rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1577         hsv_to_rgb(rH, (facm * rS + fac * colS), rV, r_col + 0, r_col + 1, r_col + 2);
1578       }
1579       break;
1580     }
1581     case MA_RAMP_VAL: {
1582       float rH, rS, rV;
1583       float colH, colS, colV;
1584       rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1585       rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1586       hsv_to_rgb(rH, rS, (facm * rV + fac * colV), r_col + 0, r_col + 1, r_col + 2);
1587       break;
1588     }
1589     case MA_RAMP_COLOR: {
1590       float rH, rS, rV;
1591       float colH, colS, colV;
1592       float tmpr, tmpg, tmpb;
1593       rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1594       if (colS != 0) {
1595         rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1596         hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb);
1597         r_col[0] = facm * (r_col[0]) + fac * tmpr;
1598         r_col[1] = facm * (r_col[1]) + fac * tmpg;
1599         r_col[2] = facm * (r_col[2]) + fac * tmpb;
1600       }
1601       break;
1602     }
1603     case MA_RAMP_SOFT: {
1604       float scr, scg, scb;
1605 
1606       /* first calculate non-fac based Screen mix */
1607       scr = 1.0f - (1.0f - col[0]) * (1.0f - r_col[0]);
1608       scg = 1.0f - (1.0f - col[1]) * (1.0f - r_col[1]);
1609       scb = 1.0f - (1.0f - col[2]) * (1.0f - r_col[2]);
1610 
1611       r_col[0] = facm * (r_col[0]) +
1612                  fac * (((1.0f - r_col[0]) * col[0] * (r_col[0])) + (r_col[0] * scr));
1613       r_col[1] = facm * (r_col[1]) +
1614                  fac * (((1.0f - r_col[1]) * col[1] * (r_col[1])) + (r_col[1] * scg));
1615       r_col[2] = facm * (r_col[2]) +
1616                  fac * (((1.0f - r_col[2]) * col[2] * (r_col[2])) + (r_col[2] * scb));
1617       break;
1618     }
1619     case MA_RAMP_LINEAR:
1620       if (col[0] > 0.5f) {
1621         r_col[0] = r_col[0] + fac * (2.0f * (col[0] - 0.5f));
1622       }
1623       else {
1624         r_col[0] = r_col[0] + fac * (2.0f * (col[0]) - 1.0f);
1625       }
1626       if (col[1] > 0.5f) {
1627         r_col[1] = r_col[1] + fac * (2.0f * (col[1] - 0.5f));
1628       }
1629       else {
1630         r_col[1] = r_col[1] + fac * (2.0f * (col[1]) - 1.0f);
1631       }
1632       if (col[2] > 0.5f) {
1633         r_col[2] = r_col[2] + fac * (2.0f * (col[2] - 0.5f));
1634       }
1635       else {
1636         r_col[2] = r_col[2] + fac * (2.0f * (col[2]) - 1.0f);
1637       }
1638       break;
1639   }
1640 }
1641 
1642 /**
1643  * \brief copy/paste buffer, if we had a proper py api that would be better
1644  * \note matcopybuf.nodetree does _NOT_ use ID's
1645  * \todo matcopybuf.nodetree's  node->id's are NOT validated, this will crash!
1646  */
1647 static Material matcopybuf;
1648 static short matcopied = 0;
1649 
BKE_material_copybuf_clear(void)1650 void BKE_material_copybuf_clear(void)
1651 {
1652   memset(&matcopybuf, 0, sizeof(Material));
1653   matcopied = 0;
1654 }
1655 
BKE_material_copybuf_free(void)1656 void BKE_material_copybuf_free(void)
1657 {
1658   if (matcopybuf.nodetree) {
1659     ntreeFreeLocalTree(matcopybuf.nodetree);
1660     MEM_freeN(matcopybuf.nodetree);
1661     matcopybuf.nodetree = NULL;
1662   }
1663 
1664   matcopied = 0;
1665 }
1666 
BKE_material_copybuf_copy(Main * bmain,Material * ma)1667 void BKE_material_copybuf_copy(Main *bmain, Material *ma)
1668 {
1669   if (matcopied) {
1670     BKE_material_copybuf_free();
1671   }
1672 
1673   memcpy(&matcopybuf, ma, sizeof(Material));
1674 
1675   if (ma->nodetree != NULL) {
1676     matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, bmain, false);
1677   }
1678 
1679   matcopybuf.preview = NULL;
1680   BLI_listbase_clear(&matcopybuf.gpumaterial);
1681   /* TODO Duplicate Engine Settings and set runtime to NULL */
1682   matcopied = 1;
1683 }
1684 
BKE_material_copybuf_paste(Main * bmain,Material * ma)1685 void BKE_material_copybuf_paste(Main *bmain, Material *ma)
1686 {
1687   ID id;
1688 
1689   if (matcopied == 0) {
1690     return;
1691   }
1692 
1693   /* Free gpu material before the ntree */
1694   GPU_material_free(&ma->gpumaterial);
1695 
1696   if (ma->nodetree) {
1697     ntreeFreeEmbeddedTree(ma->nodetree);
1698     MEM_freeN(ma->nodetree);
1699   }
1700 
1701   id = (ma->id);
1702   memcpy(ma, &matcopybuf, sizeof(Material));
1703   (ma->id) = id;
1704 
1705   if (matcopybuf.nodetree != NULL) {
1706     ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, bmain, false);
1707   }
1708 }
1709 
BKE_material_eval(struct Depsgraph * depsgraph,Material * material)1710 void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
1711 {
1712   DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
1713   GPU_material_free(&material->gpumaterial);
1714 }
1715 
1716 /* Default Materials
1717  *
1718  * Used for rendering when objects have no materials assigned, and initializing
1719  * default shader nodes. */
1720 
1721 static Material default_material_empty;
1722 static Material default_material_holdout;
1723 static Material default_material_surface;
1724 static Material default_material_volume;
1725 static Material default_material_gpencil;
1726 
1727 static Material *default_materials[] = {&default_material_empty,
1728                                         &default_material_holdout,
1729                                         &default_material_surface,
1730                                         &default_material_volume,
1731                                         &default_material_gpencil,
1732                                         NULL};
1733 
material_default_gpencil_init(Material * ma)1734 static void material_default_gpencil_init(Material *ma)
1735 {
1736   strcpy(ma->id.name, "MADefault GPencil");
1737   BKE_gpencil_material_attr_init(ma);
1738   add_v3_fl(&ma->gp_style->stroke_rgba[0], 0.6f);
1739 }
1740 
material_default_surface_init(Material * ma)1741 static void material_default_surface_init(Material *ma)
1742 {
1743   bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
1744   ma->nodetree = ntree;
1745   ma->use_nodes = true;
1746 
1747   bNode *principled = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_PRINCIPLED);
1748   bNodeSocket *base_color = nodeFindSocket(principled, SOCK_IN, "Base Color");
1749   copy_v3_v3(((bNodeSocketValueRGBA *)base_color->default_value)->value, &ma->r);
1750 
1751   bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
1752 
1753   nodeAddLink(ntree,
1754               principled,
1755               nodeFindSocket(principled, SOCK_OUT, "BSDF"),
1756               output,
1757               nodeFindSocket(output, SOCK_IN, "Surface"));
1758 
1759   principled->locx = 10.0f;
1760   principled->locy = 300.0f;
1761   output->locx = 300.0f;
1762   output->locy = 300.0f;
1763 
1764   nodeSetActive(ntree, output);
1765 }
1766 
material_default_volume_init(Material * ma)1767 static void material_default_volume_init(Material *ma)
1768 {
1769   bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
1770   ma->nodetree = ntree;
1771   ma->use_nodes = true;
1772 
1773   bNode *principled = nodeAddStaticNode(NULL, ntree, SH_NODE_VOLUME_PRINCIPLED);
1774   bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
1775 
1776   nodeAddLink(ntree,
1777               principled,
1778               nodeFindSocket(principled, SOCK_OUT, "Volume"),
1779               output,
1780               nodeFindSocket(output, SOCK_IN, "Volume"));
1781 
1782   principled->locx = 10.0f;
1783   principled->locy = 300.0f;
1784   output->locx = 300.0f;
1785   output->locy = 300.0f;
1786 
1787   nodeSetActive(ntree, output);
1788 }
1789 
material_default_holdout_init(Material * ma)1790 static void material_default_holdout_init(Material *ma)
1791 {
1792   bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
1793   ma->nodetree = ntree;
1794   ma->use_nodes = true;
1795 
1796   bNode *holdout = nodeAddStaticNode(NULL, ntree, SH_NODE_HOLDOUT);
1797   bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
1798 
1799   nodeAddLink(ntree,
1800               holdout,
1801               nodeFindSocket(holdout, SOCK_OUT, "Holdout"),
1802               output,
1803               nodeFindSocket(output, SOCK_IN, "Surface"));
1804 
1805   holdout->locx = 10.0f;
1806   holdout->locy = 300.0f;
1807   output->locx = 300.0f;
1808   output->locy = 300.0f;
1809 
1810   nodeSetActive(ntree, output);
1811 }
1812 
BKE_material_default_empty(void)1813 Material *BKE_material_default_empty(void)
1814 {
1815   return &default_material_empty;
1816 }
1817 
BKE_material_default_holdout(void)1818 Material *BKE_material_default_holdout(void)
1819 {
1820   return &default_material_holdout;
1821 }
1822 
BKE_material_default_surface(void)1823 Material *BKE_material_default_surface(void)
1824 {
1825   return &default_material_surface;
1826 }
1827 
BKE_material_default_volume(void)1828 Material *BKE_material_default_volume(void)
1829 {
1830   return &default_material_volume;
1831 }
1832 
BKE_material_default_gpencil(void)1833 Material *BKE_material_default_gpencil(void)
1834 {
1835   return &default_material_gpencil;
1836 }
1837 
BKE_material_defaults_free_gpu(void)1838 void BKE_material_defaults_free_gpu(void)
1839 {
1840   for (int i = 0; default_materials[i]; i++) {
1841     Material *ma = default_materials[i];
1842     if (ma->gpumaterial.first) {
1843       GPU_material_free(&ma->gpumaterial);
1844     }
1845   }
1846 }
1847 
1848 /* Module functions called on startup and exit. */
1849 
BKE_materials_init(void)1850 void BKE_materials_init(void)
1851 {
1852   for (int i = 0; default_materials[i]; i++) {
1853     material_init_data(&default_materials[i]->id);
1854   }
1855 
1856   material_default_surface_init(&default_material_surface);
1857   material_default_volume_init(&default_material_volume);
1858   material_default_holdout_init(&default_material_holdout);
1859   material_default_gpencil_init(&default_material_gpencil);
1860 }
1861 
BKE_materials_exit(void)1862 void BKE_materials_exit(void)
1863 {
1864   for (int i = 0; default_materials[i]; i++) {
1865     material_free_data(&default_materials[i]->id);
1866   }
1867 }
1868