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