Blender  V3.3
material.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <math.h>
9 #include <stddef.h>
10 #include <string.h>
11 
12 #include "CLG_log.h"
13 
14 #include "MEM_guardedalloc.h"
15 
16 /* Allow using deprecated functionality for .blend file I/O. */
17 #define DNA_DEPRECATED_ALLOW
18 
19 #include "DNA_ID.h"
20 #include "DNA_anim_types.h"
21 #include "DNA_collection_types.h"
22 #include "DNA_curve_types.h"
23 #include "DNA_curves_types.h"
24 #include "DNA_customdata_types.h"
25 #include "DNA_defaults.h"
26 #include "DNA_gpencil_types.h"
27 #include "DNA_material_types.h"
28 #include "DNA_mesh_types.h"
29 #include "DNA_meshdata_types.h"
30 #include "DNA_meta_types.h"
31 #include "DNA_node_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_particle_types.h"
34 #include "DNA_pointcloud_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_volume_types.h"
37 
38 #include "BLI_array_utils.h"
39 #include "BLI_listbase.h"
40 #include "BLI_math.h"
41 #include "BLI_utildefines.h"
42 
43 #include "BLT_translation.h"
44 
45 #include "BKE_anim_data.h"
46 #include "BKE_attribute.h"
47 #include "BKE_brush.h"
48 #include "BKE_curve.h"
49 #include "BKE_displist.h"
50 #include "BKE_editmesh.h"
51 #include "BKE_gpencil.h"
52 #include "BKE_icons.h"
53 #include "BKE_idtype.h"
54 #include "BKE_image.h"
55 #include "BKE_lib_id.h"
56 #include "BKE_lib_query.h"
57 #include "BKE_main.h"
58 #include "BKE_material.h"
59 #include "BKE_mesh.h"
60 #include "BKE_node.h"
61 #include "BKE_object.h"
62 #include "BKE_scene.h"
63 #include "BKE_vfont.h"
64 
65 #include "DEG_depsgraph.h"
66 #include "DEG_depsgraph_build.h"
67 #include "DEG_depsgraph_query.h"
68 
69 #include "GPU_material.h"
70 
71 #include "NOD_shader.h"
72 
73 #include "BLO_read_write.h"
74 
75 static CLG_LogRef LOG = {"bke.material"};
76 
77 static void material_init_data(ID *id)
78 {
79  Material *material = (Material *)id;
80 
82 
84 }
85 
86 static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
87 {
88  Material *material_dst = (Material *)id_dst;
89  const Material *material_src = (const Material *)id_src;
90 
91  const bool is_localized = (flag & LIB_ID_CREATE_LOCAL) != 0;
92  /* We always need allocation of our private ID data. */
93  const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
94 
95  if (material_src->nodetree != NULL) {
96  if (is_localized) {
97  material_dst->nodetree = ntreeLocalize(material_src->nodetree);
98  }
99  else {
100  BKE_id_copy_ex(bmain,
101  (ID *)material_src->nodetree,
102  (ID **)&material_dst->nodetree,
103  flag_private_id_data);
104  }
105  }
106 
107  if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
108  BKE_previewimg_id_copy(&material_dst->id, &material_src->id);
109  }
110  else {
111  material_dst->preview = NULL;
112  }
113 
114  if (material_src->texpaintslot != NULL) {
115  /* TODO: Think we can also skip copying this data in the more generic `NO_MAIN` case? */
116  material_dst->texpaintslot = is_localized ? NULL : MEM_dupallocN(material_src->texpaintslot);
117  }
118 
119  if (material_src->gp_style != NULL) {
120  material_dst->gp_style = MEM_dupallocN(material_src->gp_style);
121  }
122 
123  BLI_listbase_clear(&material_dst->gpumaterial);
124 
125  /* TODO: Duplicate Engine Settings and set runtime to NULL. */
126 }
127 
128 static void material_free_data(ID *id)
129 {
130  Material *material = (Material *)id;
131 
132  /* Free gpu material before the ntree */
134 
135  /* is no lib link block, but material extension */
136  if (material->nodetree) {
140  }
141 
143 
145 
148 }
149 
151 {
152  Material *material = (Material *)id;
153  /* Nodetrees **are owned by IDs**, treat them as mere sub-data and not real ID! */
156  if (material->texpaintslot != NULL) {
158  }
159  if (material->gp_style != NULL) {
162  }
163 }
164 
165 static void material_blend_write(BlendWriter *writer, ID *id, const void *id_address)
166 {
167  Material *ma = (Material *)id;
168 
169  /* Clean up, important in undo case to reduce false detection of changed datablocks. */
170  ma->texpaintslot = NULL;
172 
173  /* write LibData */
174  BLO_write_id_struct(writer, Material, id_address, &ma->id);
175  BKE_id_blend_write(writer, &ma->id);
176 
177  if (ma->adt) {
178  BKE_animdata_blend_write(writer, ma->adt);
179  }
180 
181  /* nodetree is integral part of material, no libdata */
182  if (ma->nodetree) {
183  BLO_write_struct(writer, bNodeTree, ma->nodetree);
184  ntreeBlendWrite(writer, ma->nodetree);
185  }
186 
187  BKE_previewimg_blend_write(writer, ma->preview);
188 
189  /* grease pencil settings */
190  if (ma->gp_style) {
192  }
193 }
194 
195 static void material_blend_read_data(BlendDataReader *reader, ID *id)
196 {
197  Material *ma = (Material *)id;
198  BLO_read_data_address(reader, &ma->adt);
199  BKE_animdata_blend_read_data(reader, ma->adt);
200 
201  ma->texpaintslot = NULL;
202 
203  BLO_read_data_address(reader, &ma->preview);
204  BKE_previewimg_blend_read(reader, ma->preview);
205 
207 
208  BLO_read_data_address(reader, &ma->gp_style);
209 }
210 
211 static void material_blend_read_lib(BlendLibReader *reader, ID *id)
212 {
213  Material *ma = (Material *)id;
214  BLO_read_id_address(reader, ma->id.lib, &ma->ipo); /* XXX deprecated - old animation system */
215 
216  /* relink grease pencil settings */
217  if (ma->gp_style != NULL) {
218  MaterialGPencilStyle *gp_style = ma->gp_style;
219  if (gp_style->sima != NULL) {
220  BLO_read_id_address(reader, ma->id.lib, &gp_style->sima);
221  }
222  if (gp_style->ima != NULL) {
223  BLO_read_id_address(reader, ma->id.lib, &gp_style->ima);
224  }
225  }
226 }
227 
228 static void material_blend_read_expand(BlendExpander *expander, ID *id)
229 {
230  Material *ma = (Material *)id;
231  BLO_expand(expander, ma->ipo); /* XXX deprecated - old animation system */
232 
233  if (ma->gp_style) {
234  MaterialGPencilStyle *gp_style = ma->gp_style;
235  BLO_expand(expander, gp_style->sima);
236  BLO_expand(expander, gp_style->ima);
237  }
238 }
239 
241  .id_code = ID_MA,
242  .id_filter = FILTER_ID_MA,
243  .main_listbase_index = INDEX_ID_MA,
244  .struct_size = sizeof(Material),
245  .name = "Material",
246  .name_plural = "materials",
247  .translation_context = BLT_I18NCONTEXT_ID_MATERIAL,
249  .asset_type_info = NULL,
250 
252  .copy_data = material_copy_data,
253  .free_data = material_free_data,
254  .make_local = NULL,
255  .foreach_id = material_foreach_id,
256  .foreach_cache = NULL,
257  .foreach_path = NULL,
258  .owner_get = NULL,
259 
260  .blend_write = material_blend_write,
261  .blend_read_data = material_blend_read_data,
262  .blend_read_lib = material_blend_read_lib,
263  .blend_read_expand = material_blend_read_expand,
264 
265  .blend_read_undo_preserve = NULL,
266 
267  .lib_override_apply_post = NULL,
268 };
269 
271 {
272  if ((ma) && (ma->gp_style == NULL)) {
273  ma->gp_style = MEM_callocN(sizeof(MaterialGPencilStyle), "Grease Pencil Material Settings");
274 
275  MaterialGPencilStyle *gp_style = ma->gp_style;
276  /* set basic settings */
277  gp_style->stroke_rgba[3] = 1.0f;
278  gp_style->fill_rgba[3] = 1.0f;
279  ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 1.0f);
280  ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f);
281  gp_style->texture_offset[0] = -0.5f;
282  gp_style->texture_pixsize = 100.0f;
283  gp_style->mix_factor = 0.5f;
284 
285  gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
286  }
287 }
288 
289 Material *BKE_material_add(Main *bmain, const char *name)
290 {
291  Material *ma;
292 
293  ma = BKE_id_new(bmain, ID_MA, name);
294 
295  return ma;
296 }
297 
298 Material *BKE_gpencil_material_add(Main *bmain, const char *name)
299 {
300  Material *ma;
301 
302  ma = BKE_material_add(bmain, name);
303 
304  /* grease pencil settings */
305  if (ma != NULL) {
307  }
308  return ma;
309 }
310 
312 {
313  if (ob->type == OB_MESH) {
314  Mesh *me = ob->data;
315  return &(me->mat);
316  }
317  if (ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
318  Curve *cu = ob->data;
319  return &(cu->mat);
320  }
321  if (ob->type == OB_MBALL) {
322  MetaBall *mb = ob->data;
323  return &(mb->mat);
324  }
325  if (ob->type == OB_GPENCIL) {
326  bGPdata *gpd = ob->data;
327  return &(gpd->mat);
328  }
329  if (ob->type == OB_CURVES) {
330  Curves *curves = ob->data;
331  return &(curves->mat);
332  }
333  if (ob->type == OB_POINTCLOUD) {
334  PointCloud *pointcloud = ob->data;
335  return &(pointcloud->mat);
336  }
337  if (ob->type == OB_VOLUME) {
338  Volume *volume = ob->data;
339  return &(volume->mat);
340  }
341  return NULL;
342 }
343 
345 {
346  if (ob->type == OB_MESH) {
347  Mesh *me = ob->data;
348  return &(me->totcol);
349  }
350  if (ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
351  Curve *cu = ob->data;
352  return &(cu->totcol);
353  }
354  if (ob->type == OB_MBALL) {
355  MetaBall *mb = ob->data;
356  return &(mb->totcol);
357  }
358  if (ob->type == OB_GPENCIL) {
359  bGPdata *gpd = ob->data;
360  return &(gpd->totcol);
361  }
362  if (ob->type == OB_CURVES) {
363  Curves *curves = ob->data;
364  return &(curves->totcol);
365  }
366  if (ob->type == OB_POINTCLOUD) {
367  PointCloud *pointcloud = ob->data;
368  return &(pointcloud->totcol);
369  }
370  if (ob->type == OB_VOLUME) {
371  Volume *volume = ob->data;
372  return &(volume->totcol);
373  }
374  return NULL;
375 }
376 
378 {
379  /* ensure we don't try get materials from non-obdata */
381 
382  switch (GS(id->name)) {
383  case ID_ME:
384  return &(((Mesh *)id)->mat);
385  case ID_CU_LEGACY:
386  return &(((Curve *)id)->mat);
387  case ID_MB:
388  return &(((MetaBall *)id)->mat);
389  case ID_GD:
390  return &(((bGPdata *)id)->mat);
391  case ID_CV:
392  return &(((Curves *)id)->mat);
393  case ID_PT:
394  return &(((PointCloud *)id)->mat);
395  case ID_VO:
396  return &(((Volume *)id)->mat);
397  default:
398  break;
399  }
400  return NULL;
401 }
402 
404 {
405  /* ensure we don't try get materials from non-obdata */
407 
408  switch (GS(id->name)) {
409  case ID_ME:
410  return &(((Mesh *)id)->totcol);
411  case ID_CU_LEGACY:
412  return &(((Curve *)id)->totcol);
413  case ID_MB:
414  return &(((MetaBall *)id)->totcol);
415  case ID_GD:
416  return &(((bGPdata *)id)->totcol);
417  case ID_CV:
418  return &(((Curves *)id)->totcol);
419  case ID_PT:
420  return &(((PointCloud *)id)->totcol);
421  case ID_VO:
422  return &(((Volume *)id)->totcol);
423  default:
424  break;
425  }
426  return NULL;
427 }
428 
429 static void material_data_index_remove_id(ID *id, short index)
430 {
431  /* ensure we don't try get materials from non-obdata */
433 
434  switch (GS(id->name)) {
435  case ID_ME:
436  BKE_mesh_material_index_remove((Mesh *)id, index);
437  break;
438  case ID_CU_LEGACY:
440  break;
441  case ID_MB:
442  case ID_CV:
443  case ID_PT:
444  case ID_VO:
445  /* No material indices for these object data types. */
446  break;
447  default:
448  break;
449  }
450 }
451 
452 bool BKE_object_material_slot_used(Object *object, short actcol)
453 {
454  if (!BKE_object_supports_material_slots(object)) {
455  return false;
456  }
457 
458  LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
459  if (psys->part->omat == actcol) {
460  return true;
461  }
462  }
463 
464  ID *ob_data = object->data;
465  if (ob_data == NULL || !OB_DATA_SUPPORT_ID(GS(ob_data->name))) {
466  return false;
467  }
468 
469  switch (GS(ob_data->name)) {
470  case ID_ME:
471  return BKE_mesh_material_index_used((Mesh *)ob_data, actcol - 1);
472  case ID_CU_LEGACY:
473  return BKE_curve_material_index_used((Curve *)ob_data, actcol - 1);
474  case ID_MB:
475  /* Meta-elements don't support materials at the moment. */
476  return false;
477  case ID_GD:
478  return BKE_gpencil_material_index_used((bGPdata *)ob_data, actcol - 1);
479  default:
480  return false;
481  }
482 }
483 
485 {
486  /* ensure we don't try get materials from non-obdata */
488 
489  switch (GS(id->name)) {
490  case ID_ME:
492  break;
493  case ID_CU_LEGACY:
495  break;
496  case ID_MB:
497  case ID_CV:
498  case ID_PT:
499  case ID_VO:
500  /* No material indices for these object data types. */
501  break;
502  default:
503  break;
504  }
505 }
506 
507 void BKE_id_materials_copy(Main *bmain, ID *id_src, ID *id_dst)
508 {
509  Material ***matar_src = BKE_id_material_array_p(id_src);
510  const short *materials_len_p_src = BKE_id_material_len_p(id_src);
511 
512  Material ***matar_dst = BKE_id_material_array_p(id_dst);
513  short *materials_len_p_dst = BKE_id_material_len_p(id_dst);
514 
515  *materials_len_p_dst = *materials_len_p_src;
516  if (*materials_len_p_src != 0) {
517  (*matar_dst) = MEM_dupallocN(*matar_src);
518 
519  for (int a = 0; a < *materials_len_p_src; a++) {
520  id_us_plus((ID *)(*matar_dst)[a]);
521  }
522 
525  }
526 }
527 
528 void BKE_id_material_resize(Main *bmain, ID *id, short totcol, bool do_id_user)
529 {
530  Material ***matar = BKE_id_material_array_p(id);
531  short *totcolp = BKE_id_material_len_p(id);
532 
533  if (matar == NULL) {
534  return;
535  }
536 
537  if (do_id_user && totcol < (*totcolp)) {
538  short i;
539  for (i = totcol; i < (*totcolp); i++) {
540  id_us_min((ID *)(*matar)[i]);
541  }
542  }
543 
544  if (totcol == 0) {
545  if (*totcolp) {
546  MEM_freeN(*matar);
547  *matar = NULL;
548  }
549  }
550  else {
551  *matar = MEM_recallocN(*matar, sizeof(void *) * totcol);
552  }
553  *totcolp = totcol;
554 
557 }
558 
559 void BKE_id_material_append(Main *bmain, ID *id, Material *ma)
560 {
561  Material ***matar;
562  if ((matar = BKE_id_material_array_p(id))) {
563  short *totcol = BKE_id_material_len_p(id);
564  Material **mat = MEM_callocN(sizeof(void *) * ((*totcol) + 1), "newmatar");
565  if (*totcol) {
566  memcpy(mat, *matar, sizeof(void *) * (*totcol));
567  }
568  if (*matar) {
569  MEM_freeN(*matar);
570  }
571 
572  *matar = mat;
573  (*matar)[(*totcol)++] = ma;
574 
575  id_us_plus((ID *)ma);
577 
580  }
581 }
582 
583 Material *BKE_id_material_pop(Main *bmain, ID *id, int index_i)
584 {
585  short index = (short)index_i;
586  Material *ret = NULL;
587  Material ***matar;
588  if ((matar = BKE_id_material_array_p(id))) {
589  short *totcol = BKE_id_material_len_p(id);
590  if (index >= 0 && index < (*totcol)) {
591  ret = (*matar)[index];
592  id_us_min((ID *)ret);
593 
594  if (*totcol <= 1) {
595  *totcol = 0;
596  MEM_freeN(*matar);
597  *matar = NULL;
598  }
599  else {
600  if (index + 1 != (*totcol)) {
601  memmove((*matar) + index,
602  (*matar) + (index + 1),
603  sizeof(void *) * ((*totcol) - (index + 1)));
604  }
605 
606  (*totcol)--;
607  *matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol));
609  }
610 
612 
615  }
616  }
617 
618  return ret;
619 }
620 
621 void BKE_id_material_clear(Main *bmain, ID *id)
622 {
623  Material ***matar;
624  if ((matar = BKE_id_material_array_p(id))) {
625  short *totcol = BKE_id_material_len_p(id);
626 
627  while ((*totcol)--) {
628  id_us_min((ID *)((*matar)[*totcol]));
629  }
630  *totcol = 0;
631  if (*matar) {
632  MEM_freeN(*matar);
633  *matar = NULL;
634  }
635 
638 
641  }
642 }
643 
645 {
646  Material ***matarar, **ma_p;
647  const short *totcolp;
648 
649  if (ob == NULL) {
650  return NULL;
651  }
652 
653  /* if object cannot have material, (totcolp == NULL) */
654  totcolp = BKE_object_material_len_p(ob);
655  if (totcolp == NULL || *totcolp == 0) {
656  return NULL;
657  }
658 
659  /* Clamp to number of slots if index is out of range, same convention as used for rendering. */
660  const int slot_index = clamp_i(act - 1, 0, *totcolp - 1);
661 
662  /* Fix inconsistency which may happen when library linked data reduces the number of
663  * slots but object was not updated. Ideally should be fixed elsewhere. */
664  if (*totcolp < ob->totcol) {
665  ob->totcol = *totcolp;
666  }
667 
668  if (slot_index < ob->totcol && ob->matbits && ob->matbits[slot_index]) {
669  /* Use object material slot. */
670  ma_p = &ob->mat[slot_index];
671  }
672  else {
673  /* Use data material slot. */
674  matarar = BKE_object_material_array_p(ob);
675 
676  if (matarar && *matarar) {
677  ma_p = &(*matarar)[slot_index];
678  }
679  else {
680  ma_p = NULL;
681  }
682  }
683 
684  return ma_p;
685 }
686 
688 {
689  Material **ma_p = BKE_object_material_get_p(ob, act);
690  return ma_p ? *ma_p : NULL;
691 }
692 
694 {
695  ID *data = ob->data;
696  /* Meshes in edit mode need special handling. */
697  if (ob->type == OB_MESH && ob->mode == OB_MODE_EDIT) {
698  Mesh *mesh = ob->data;
699  Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
700  if (mesh->edit_mesh && editmesh_eval_final) {
701  data = &editmesh_eval_final->id;
702  }
703  }
704  return data;
705 }
706 
708 {
710 
712  const short *tot_slots_data_ptr = BKE_id_material_len_p(data);
713  const int tot_slots_data = tot_slots_data_ptr ? *tot_slots_data_ptr : 0;
714 
715  if (tot_slots_data == 0) {
716  return NULL;
717  }
718 
719  /* Clamp to number of slots if index is out of range, same convention as used for rendering. */
720  const int slot_index = clamp_i(act - 1, 0, tot_slots_data - 1);
721  const int tot_slots_object = ob->totcol;
722 
723  Material ***materials_data_ptr = BKE_id_material_array_p(data);
724  Material **materials_data = materials_data_ptr ? *materials_data_ptr : NULL;
725  Material **materials_object = ob->mat;
726 
727  /* Check if slot is overwritten by object. */
728  if (slot_index < tot_slots_object) {
729  if (ob->matbits) {
730  if (ob->matbits[slot_index]) {
731  Material *material = materials_object[slot_index];
732  if (material != NULL) {
733  return material;
734  }
735  }
736  }
737  }
738  /* Otherwise use data from object-data. */
739  if (slot_index < tot_slots_data) {
740  Material *material = materials_data[slot_index];
741  return material;
742  }
743  return NULL;
744 }
745 
747 {
749  if (ob->type == OB_EMPTY) {
750  return 0;
751  }
752  BLI_assert(ob->data != NULL);
754  const short *len_p = BKE_id_material_len_p(id);
755  return len_p ? *len_p : 0;
756 }
757 
759 {
760  BLI_assert(slot >= 1);
761  Material ***materials_ptr = BKE_id_material_array_p(id);
762  short *len_ptr = BKE_id_material_len_p(id);
763  if (ELEM(NULL, materials_ptr, len_ptr)) {
765  return;
766  }
767 
768  const int slot_index = slot - 1;
769  const int old_length = *len_ptr;
770 
771  if (slot_index >= old_length) {
772  /* Need to grow slots array. */
773  const int new_length = slot_index + 1;
774  *materials_ptr = MEM_reallocN(*materials_ptr, sizeof(void *) * new_length);
775  *len_ptr = new_length;
776  for (int i = old_length; i < new_length; i++) {
777  (*materials_ptr)[i] = NULL;
778  }
779  }
780 
781  (*materials_ptr)[slot_index] = material;
782 }
783 
785 {
786  short *len_ptr = BKE_id_material_len_p(id);
787  if (len_ptr == NULL) {
788  return;
789  }
790  if (*len_ptr == 0) {
792  }
793 }
794 
796 {
797  Material *ma = BKE_object_material_get(ob, act);
798  if (ma != NULL) {
799  return ma;
800  }
801 
803 }
804 
806 {
807  Material *ma = BKE_object_material_get(ob, act);
808  if (ma != NULL) {
809  if (ma->gp_style == NULL) {
811  }
812 
813  return ma->gp_style;
814  }
815 
817 }
818 
819 void BKE_object_material_resize(Main *bmain, Object *ob, const short totcol, bool do_id_user)
820 {
821  Material **newmatar;
822  char *newmatbits;
823 
824  if (do_id_user && totcol < ob->totcol) {
825  for (int i = totcol; i < ob->totcol; i++) {
826  id_us_min((ID *)ob->mat[i]);
827  }
828  }
829 
830  if (totcol == 0) {
831  if (ob->totcol) {
832  MEM_freeN(ob->mat);
833  MEM_freeN(ob->matbits);
834  ob->mat = NULL;
835  ob->matbits = NULL;
836  }
837  }
838  else if (ob->totcol < totcol) {
839  newmatar = MEM_callocN(sizeof(void *) * totcol, "newmatar");
840  newmatbits = MEM_callocN(sizeof(char) * totcol, "newmatbits");
841  if (ob->totcol) {
842  memcpy(newmatar, ob->mat, sizeof(void *) * ob->totcol);
843  memcpy(newmatbits, ob->matbits, sizeof(char) * ob->totcol);
844  MEM_freeN(ob->mat);
845  MEM_freeN(ob->matbits);
846  }
847  ob->mat = newmatar;
848  ob->matbits = newmatbits;
849  }
850  /* XXX(campbell): why not realloc on shrink? */
851 
852  ob->totcol = totcol;
853  if (ob->totcol && ob->actcol == 0) {
854  ob->actcol = 1;
855  }
856  if (ob->actcol > ob->totcol) {
857  ob->actcol = ob->totcol;
858  }
859 
862 }
863 
864 void BKE_object_materials_test(Main *bmain, Object *ob, ID *id)
865 {
866  /* make the ob mat-array same size as 'ob->data' mat-array */
867  const short *totcol;
868 
869  if (id == NULL || (totcol = BKE_id_material_len_p(id)) == NULL) {
870  return;
871  }
872 
873  if ((ob->id.tag & LIB_TAG_MISSING) == 0 && (id->tag & LIB_TAG_MISSING) != 0) {
874  /* Exception: In case the object is a valid data, but its obdata is an empty place-holder,
875  * use object's material slots amount as reference.
876  * This avoids losing materials in a local object when its linked obdata goes missing.
877  * See T92780. */
878  BKE_id_material_resize(bmain, id, (short)ob->totcol, false);
879  }
880  else {
881  /* Normal case: the use the obdata amount of materials slots to update the object's one. */
882  BKE_object_material_resize(bmain, ob, *totcol, false);
883  }
884 }
885 
887 {
888  /* make the ob mat-array same size as 'ob->data' mat-array */
889  Object *ob;
890  const short *totcol;
891 
892  if (id == NULL || (totcol = BKE_id_material_len_p(id)) == NULL) {
893  return;
894  }
895 
896  BKE_main_lock(bmain);
897  for (ob = bmain->objects.first; ob; ob = ob->id.next) {
898  if (ob->data == id) {
899  BKE_object_material_resize(bmain, ob, *totcol, false);
900  }
901  }
902  BKE_main_unlock(bmain);
903 }
904 
905 void BKE_id_material_assign(Main *bmain, ID *id, Material *ma, short act)
906 {
907  Material *mao, **matar, ***matarar;
908  short *totcolp;
909 
910  if (act > MAXMAT) {
911  return;
912  }
913  if (act < 1) {
914  act = 1;
915  }
916 
917  /* test arraylens */
918 
919  totcolp = BKE_id_material_len_p(id);
920  matarar = BKE_id_material_array_p(id);
921 
922  if (totcolp == NULL || matarar == NULL) {
923  return;
924  }
925 
926  if (act > *totcolp) {
927  matar = MEM_callocN(sizeof(void *) * act, "matarray1");
928 
929  if (*totcolp) {
930  memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
931  MEM_freeN(*matarar);
932  }
933 
934  *matarar = matar;
935  *totcolp = act;
936  }
937 
938  /* in data */
939  mao = (*matarar)[act - 1];
940  if (mao) {
941  id_us_min(&mao->id);
942  }
943  (*matarar)[act - 1] = ma;
944 
945  if (ma) {
946  id_us_plus(&ma->id);
947  }
948 
950 }
951 
953  Main *bmain, Object *ob, Material *ma, short act, int assign_type, bool do_test_all)
954 {
955  Material *mao, **matar, ***matarar;
956  short *totcolp;
957  char bit = 0;
958 
959  if (act > MAXMAT) {
960  return;
961  }
962  if (act < 1) {
963  act = 1;
964  }
965 
966  /* test arraylens */
967 
968  totcolp = BKE_object_material_len_p(ob);
969  matarar = BKE_object_material_array_p(ob);
970 
971  if (totcolp == NULL || matarar == NULL) {
972  return;
973  }
974 
975  if (act > *totcolp) {
976  matar = MEM_callocN(sizeof(void *) * act, "matarray1");
977 
978  if (*totcolp) {
979  memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
980  MEM_freeN(*matarar);
981  }
982 
983  *matarar = matar;
984  *totcolp = act;
985  }
986 
987  if (act > ob->totcol) {
988  /* Need more space in the material arrays */
989  ob->mat = MEM_recallocN_id(ob->mat, sizeof(void *) * act, "matarray2");
990  ob->matbits = MEM_recallocN_id(ob->matbits, sizeof(char) * act, "matbits1");
991  ob->totcol = act;
992  }
993 
994  /* Determine the object/mesh linking */
995  if (assign_type == BKE_MAT_ASSIGN_EXISTING) {
996  /* keep existing option (avoid confusion in scripts),
997  * intentionally ignore userpref (default to obdata). */
998  bit = ob->matbits[act - 1];
999  }
1000  else if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->totcol && ob->actcol) {
1001  /* copy from previous material */
1002  bit = ob->matbits[ob->actcol - 1];
1003  }
1004  else {
1005  switch (assign_type) {
1006  case BKE_MAT_ASSIGN_OBDATA:
1007  bit = 0;
1008  break;
1009  case BKE_MAT_ASSIGN_OBJECT:
1010  bit = 1;
1011  break;
1013  default:
1014  bit = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
1015  break;
1016  }
1017  }
1018 
1019  /* do it */
1020 
1021  ob->matbits[act - 1] = bit;
1022  if (bit == 1) { /* in object */
1023  mao = ob->mat[act - 1];
1024  if (mao) {
1025  id_us_min(&mao->id);
1026  }
1027  ob->mat[act - 1] = ma;
1028  BKE_object_materials_test(bmain, ob, ob->data);
1029  }
1030  else { /* in data */
1031  mao = (*matarar)[act - 1];
1032  if (mao) {
1033  id_us_min(&mao->id);
1034  }
1035  (*matarar)[act - 1] = ma;
1036  /* Data may be used by several objects. */
1037  if (do_test_all) {
1039  }
1040  }
1041 
1042  if (ma) {
1043  id_us_plus(&ma->id);
1044  }
1045 }
1046 
1047 void BKE_object_material_assign(Main *bmain, Object *ob, Material *ma, short act, int assign_type)
1048 {
1049  object_material_assign(bmain, ob, ma, act, assign_type, true);
1050 }
1051 
1053  struct Object *ob,
1054  struct Material *ma,
1055  short act)
1056 {
1057  object_material_assign(bmain, ob, ma, act, BKE_MAT_ASSIGN_OBDATA, false);
1058 }
1059 
1060 void BKE_object_material_remap(Object *ob, const unsigned int *remap)
1061 {
1062  Material ***matar = BKE_object_material_array_p(ob);
1063  const short *totcol_p = BKE_object_material_len_p(ob);
1064 
1065  BLI_array_permute(ob->mat, ob->totcol, remap);
1066 
1067  if (ob->matbits) {
1068  BLI_array_permute(ob->matbits, ob->totcol, remap);
1069  }
1070 
1071  if (matar) {
1072  BLI_array_permute(*matar, *totcol_p, remap);
1073  }
1074 
1075  if (ob->type == OB_MESH) {
1076  BKE_mesh_material_remap(ob->data, remap, ob->totcol);
1077  }
1078  else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
1079  BKE_curve_material_remap(ob->data, remap, ob->totcol);
1080  }
1081  else if (ob->type == OB_GPENCIL) {
1082  BKE_gpencil_material_remap(ob->data, remap, ob->totcol);
1083  }
1084  else {
1085  /* add support for this object data! */
1086  BLI_assert(matar == NULL);
1087  }
1088 }
1089 
1090 void BKE_object_material_remap_calc(Object *ob_dst, Object *ob_src, short *remap_src_to_dst)
1091 {
1092  if (ob_src->totcol == 0) {
1093  return;
1094  }
1095 
1096  GHash *gh_mat_map = BLI_ghash_ptr_new_ex(__func__, ob_src->totcol);
1097 
1098  for (int i = 0; i < ob_dst->totcol; i++) {
1099  Material *ma_src = BKE_object_material_get(ob_dst, i + 1);
1100  BLI_ghash_reinsert(gh_mat_map, ma_src, POINTER_FROM_INT(i), NULL, NULL);
1101  }
1102 
1103  /* setup default mapping (when materials don't match) */
1104  {
1105  int i = 0;
1106  if (ob_dst->totcol >= ob_src->totcol) {
1107  for (; i < ob_src->totcol; i++) {
1108  remap_src_to_dst[i] = i;
1109  }
1110  }
1111  else {
1112  for (; i < ob_dst->totcol; i++) {
1113  remap_src_to_dst[i] = i;
1114  }
1115  for (; i < ob_src->totcol; i++) {
1116  remap_src_to_dst[i] = 0;
1117  }
1118  }
1119  }
1120 
1121  for (int i = 0; i < ob_src->totcol; i++) {
1122  Material *ma_src = BKE_object_material_get(ob_src, i + 1);
1123 
1124  if ((i < ob_dst->totcol) && (ma_src == BKE_object_material_get(ob_dst, i + 1))) {
1125  /* when objects have exact matching materials - keep existing index */
1126  }
1127  else {
1128  void **index_src_p = BLI_ghash_lookup_p(gh_mat_map, ma_src);
1129  if (index_src_p) {
1130  remap_src_to_dst[i] = POINTER_AS_INT(*index_src_p);
1131  }
1132  }
1133  }
1134 
1135  BLI_ghash_free(gh_mat_map, NULL, NULL);
1136 }
1137 
1138 void BKE_object_material_from_eval_data(Main *bmain, Object *ob_orig, const ID *data_eval)
1139 {
1140  ID *data_orig = ob_orig->data;
1141 
1142  short *orig_totcol = BKE_id_material_len_p(data_orig);
1143  Material ***orig_mat = BKE_id_material_array_p(data_orig);
1144 
1145  /* Can cast away const, because the data is not changed. */
1146  const short *eval_totcol = BKE_id_material_len_p((ID *)data_eval);
1147  Material ***eval_mat = BKE_id_material_array_p((ID *)data_eval);
1148 
1149  if (ELEM(NULL, orig_totcol, orig_mat, eval_totcol, eval_mat)) {
1150  return;
1151  }
1152 
1153  /* Remove old materials from original geometry. */
1154  for (int i = 0; i < *orig_totcol; i++) {
1155  id_us_min(&(*orig_mat)[i]->id);
1156  }
1157  MEM_SAFE_FREE(*orig_mat);
1158 
1159  /* Create new material slots based on materials on evaluated geometry. */
1160  *orig_totcol = *eval_totcol;
1161  *orig_mat = MEM_callocN(sizeof(void *) * (*eval_totcol), __func__);
1162  for (int i = 0; i < *eval_totcol; i++) {
1163  Material *material_eval = (*eval_mat)[i];
1164  if (material_eval != NULL) {
1165  Material *material_orig = (Material *)DEG_get_original_id(&material_eval->id);
1166  (*orig_mat)[i] = material_orig;
1167  id_us_plus(&material_orig->id);
1168  }
1169  }
1170  BKE_object_materials_test(bmain, ob_orig, data_orig);
1171 }
1172 
1174  struct Object *ob,
1175  struct Material ***matar,
1176  int totcol,
1177  const bool to_object_only)
1178 {
1179  int actcol_orig = ob->actcol;
1180 
1181  while ((ob->totcol > totcol) && BKE_object_material_slot_remove(bmain, ob)) {
1182  /* pass */
1183  }
1184 
1185  /* now we have the right number of slots */
1186  for (int i = 0; i < totcol; i++) {
1187  if (to_object_only && ob->matbits && ob->matbits[i] == 0) {
1188  /* If we only assign to object, and that slot uses obdata material, do nothing. */
1189  continue;
1190  }
1192  ob,
1193  (*matar)[i],
1194  i + 1,
1195  to_object_only ? BKE_MAT_ASSIGN_OBJECT : BKE_MAT_ASSIGN_USERPREF);
1196  }
1197 
1198  if (actcol_orig > ob->totcol) {
1199  actcol_orig = ob->totcol;
1200  }
1201 
1202  ob->actcol = actcol_orig;
1203 }
1204 
1206 {
1207  Material ***matarar;
1208  short a, *totcolp;
1209 
1210  if (ma == NULL) {
1211  return 0;
1212  }
1213 
1214  totcolp = BKE_object_material_len_p(ob);
1215  matarar = BKE_object_material_array_p(ob);
1216 
1217  if (totcolp == NULL || matarar == NULL) {
1218  return 0;
1219  }
1220 
1221  for (a = 0; a < *totcolp; a++) {
1222  if ((*matarar)[a] == ma) {
1223  break;
1224  }
1225  }
1226  if (a < *totcolp) {
1227  return a + 1;
1228  }
1229  return 0;
1230 }
1231 
1233 {
1234  if (ob == NULL) {
1235  return false;
1236  }
1237  if (ob->totcol >= MAXMAT) {
1238  return false;
1239  }
1240 
1242  ob->actcol = ob->totcol;
1243  return true;
1244 }
1245 
1246 /* ****************** */
1247 
1249 {
1250  Material *mao, ***matarar;
1251  short *totcolp;
1252 
1253  if (ob == NULL || ob->totcol == 0) {
1254  return false;
1255  }
1256 
1257  /* this should never happen and used to crash */
1258  if (ob->actcol <= 0) {
1259  CLOG_ERROR(&LOG, "invalid material index %d, report a bug!", ob->actcol);
1260  return false;
1261  }
1262 
1263  /* take a mesh/curve/mball as starting point, remove 1 index,
1264  * AND with all objects that share the ob->data
1265  *
1266  * after that check indices in mesh/curve/mball!!!
1267  */
1268 
1269  totcolp = BKE_object_material_len_p(ob);
1270  matarar = BKE_object_material_array_p(ob);
1271 
1272  if (ELEM(NULL, matarar, *matarar)) {
1273  return false;
1274  }
1275 
1276  /* can happen on face selection in editmode */
1277  if (ob->actcol > ob->totcol) {
1278  ob->actcol = ob->totcol;
1279  }
1280 
1281  /* we delete the actcol */
1282  mao = (*matarar)[ob->actcol - 1];
1283  if (mao) {
1284  id_us_min(&mao->id);
1285  }
1286 
1287  for (int a = ob->actcol; a < ob->totcol; a++) {
1288  (*matarar)[a - 1] = (*matarar)[a];
1289  }
1290  (*totcolp)--;
1291 
1292  if (*totcolp == 0) {
1293  MEM_freeN(*matarar);
1294  *matarar = NULL;
1295  }
1296 
1297  const int actcol = ob->actcol;
1298 
1299  for (Object *obt = bmain->objects.first; obt; obt = obt->id.next) {
1300  if (obt->data == ob->data) {
1301  /* Can happen when object material lists are used, see: T52953 */
1302  if (actcol > obt->totcol) {
1303  continue;
1304  }
1305  /* WATCH IT: do not use actcol from ob or from obt (can become zero) */
1306  mao = obt->mat[actcol - 1];
1307  if (mao) {
1308  id_us_min(&mao->id);
1309  }
1310 
1311  for (int a = actcol; a < obt->totcol; a++) {
1312  obt->mat[a - 1] = obt->mat[a];
1313  obt->matbits[a - 1] = obt->matbits[a];
1314  }
1315  obt->totcol--;
1316  if (obt->actcol > obt->totcol) {
1317  obt->actcol = obt->totcol;
1318  }
1319 
1320  if (obt->totcol == 0) {
1321  MEM_freeN(obt->mat);
1322  MEM_freeN(obt->matbits);
1323  obt->mat = NULL;
1324  obt->matbits = NULL;
1325  }
1326  }
1327  }
1328 
1329  /* check indices from mesh */
1331  material_data_index_remove_id((ID *)ob->data, actcol - 1);
1332  if (ob->runtime.curve_cache) {
1334  }
1335  }
1336  /* check indices from gpencil */
1337  else if (ob->type == OB_GPENCIL) {
1338  BKE_gpencil_material_index_reassign((bGPdata *)ob->data, ob->totcol, actcol - 1);
1339  }
1340 
1341  return true;
1342 }
1343 
1345 {
1346  bNode *inode;
1347  bNodeSocket *sock;
1348 
1349  for (sock = node->inputs.first; sock; sock = sock->next) {
1350  if (sock->link) {
1351  inode = sock->link->fromnode;
1352  if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) {
1353  return inode;
1354  }
1355 
1356  return nodetree_uv_node_recursive(inode);
1357  }
1358  }
1359 
1360  return NULL;
1361 }
1362 
1364 typedef enum ePaintSlotFilter {
1368 
1369 typedef bool (*ForEachTexNodeCallback)(bNode *node, void *userdata);
1372  void *userdata,
1373  ePaintSlotFilter slot_filter)
1374 {
1375  const bool do_image_nodes = (slot_filter & PAINT_SLOT_IMAGE) != 0;
1376  const bool do_color_attributes = (slot_filter & PAINT_SLOT_COLOR_ATTRIBUTE) != 0;
1377  LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
1378  if (do_image_nodes && node->typeinfo->nclass == NODE_CLASS_TEXTURE &&
1379  node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
1380  if (!callback(node, userdata)) {
1381  return false;
1382  }
1383  }
1384  if (do_color_attributes && node->typeinfo->type == SH_NODE_ATTRIBUTE) {
1385  if (!callback(node, userdata)) {
1386  return false;
1387  }
1388  }
1389  else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
1390  /* recurse into the node group and see if it contains any textures */
1392  (bNodeTree *)node->id, callback, userdata, slot_filter)) {
1393  return false;
1394  }
1395  }
1396  }
1397  return true;
1398 }
1399 
1400 static bool count_texture_nodes_cb(bNode *UNUSED(node), void *userdata)
1401 {
1402  (*((int *)userdata))++;
1403  return true;
1404 }
1405 
1407 {
1408  int tex_nodes = 0;
1409  ntree_foreach_texnode_recursive(nodetree, count_texture_nodes_cb, &tex_nodes, slot_filter);
1410 
1411  return tex_nodes;
1412 }
1413 
1416  const Object *ob;
1418  int index;
1420 };
1421 
1422 static bool fill_texpaint_slots_cb(bNode *node, void *userdata)
1423 {
1424  struct FillTexPaintSlotsData *fill_data = userdata;
1425 
1426  Material *ma = fill_data->ma;
1427  int index = fill_data->index;
1428  fill_data->index++;
1429 
1430  if (fill_data->active_node == node) {
1432  }
1433 
1434  switch (node->type) {
1435  case SH_NODE_TEX_IMAGE: {
1436  TexPaintSlot *slot = &ma->texpaintslot[index];
1437  slot->ima = (Image *)node->id;
1438  NodeTexImage *storage = (NodeTexImage *)node->storage;
1439  slot->interp = storage->interpolation;
1440  slot->image_user = &storage->iuser;
1441  /* for new renderer, we need to traverse the treeback in search of a UV node */
1443 
1444  if (uvnode) {
1445  NodeShaderUVMap *uv_storage = (NodeShaderUVMap *)uvnode->storage;
1446  slot->uvname = uv_storage->uv_map;
1447  /* set a value to index so UI knows that we have a valid pointer for the mesh */
1448  slot->valid = true;
1449  }
1450  else {
1451  /* just invalidate the index here so UV map does not get displayed on the UI */
1452  slot->valid = false;
1453  }
1454  break;
1455  }
1456 
1457  case SH_NODE_ATTRIBUTE: {
1458  TexPaintSlot *slot = &ma->texpaintslot[index];
1459  NodeShaderAttribute *storage = node->storage;
1460  slot->attribute_name = storage->name;
1461  if (storage->type == SHD_ATTRIBUTE_GEOMETRY) {
1462  const Mesh *mesh = (const Mesh *)fill_data->ob->data;
1463  const CustomDataLayer *layer = BKE_id_attributes_color_find(&mesh->id, storage->name);
1464  slot->valid = layer != NULL;
1465  }
1466 
1467  /* Do not show unsupported attributes. */
1468  if (!slot->valid) {
1469  slot->attribute_name = NULL;
1470  fill_data->index--;
1471  }
1472 
1473  break;
1474  }
1475  }
1476 
1477  return fill_data->index != fill_data->slot_len;
1478 }
1479 
1481  bNode *active_node,
1482  const Object *ob,
1483  Material *ma,
1484  int slot_len,
1485  ePaintSlotFilter slot_filter)
1486 {
1487  struct FillTexPaintSlotsData fill_data = {active_node, ob, ma, 0, slot_len};
1488  ntree_foreach_texnode_recursive(nodetree, fill_texpaint_slots_cb, &fill_data, slot_filter);
1489 }
1490 
1493 {
1494  ePaintSlotFilter slot_filter = PAINT_SLOT_IMAGE;
1495  if (ob->mode == OB_MODE_SCULPT && U.experimental.use_sculpt_texture_paint) {
1496  slot_filter |= PAINT_SLOT_COLOR_ATTRIBUTE;
1497  }
1498  return slot_filter;
1499 }
1500 
1502 {
1503  if (!ma) {
1504  return;
1505  }
1506 
1507  const ePaintSlotFilter slot_filter = material_paint_slot_filter(ob);
1508 
1509  const TexPaintSlot *prev_texpaintslot = ma->texpaintslot;
1510  const int prev_paint_active_slot = ma->paint_active_slot;
1511  const int prev_paint_clone_slot = ma->paint_clone_slot;
1512  const int prev_tot_slots = ma->tot_slots;
1513 
1514  ma->texpaintslot = NULL;
1515  ma->tot_slots = 0;
1516 
1518  ma->paint_active_slot = 0;
1519  ma->paint_clone_slot = 0;
1520  }
1521  else if (!(ma->nodetree)) {
1522  ma->paint_active_slot = 0;
1523  ma->paint_clone_slot = 0;
1524  }
1525  else {
1526  int count = count_texture_nodes_recursive(ma->nodetree, slot_filter);
1527 
1528  if (count == 0) {
1529  ma->paint_active_slot = 0;
1530  ma->paint_clone_slot = 0;
1531  }
1532  else {
1533  ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
1534 
1536 
1538 
1539  ma->tot_slots = count;
1540 
1541  if (ma->paint_active_slot >= count) {
1542  ma->paint_active_slot = count - 1;
1543  }
1544 
1545  if (ma->paint_clone_slot >= count) {
1546  ma->paint_clone_slot = count - 1;
1547  }
1548  }
1549  }
1550 
1551  /* COW needed when adding texture slot on an object with no materials.
1552  * But do it only when slots actually change to avoid continuous depsgrap updates. */
1553  if (ma->tot_slots != prev_tot_slots || ma->paint_active_slot != prev_paint_active_slot ||
1554  ma->paint_clone_slot != prev_paint_clone_slot ||
1555  (ma->texpaintslot && prev_texpaintslot &&
1556  memcmp(ma->texpaintslot, prev_texpaintslot, sizeof(*ma->texpaintslot) * ma->tot_slots) !=
1557  0)) {
1559  }
1560 
1561  MEM_SAFE_FREE(prev_texpaintslot);
1562 }
1563 
1565 {
1566  for (int i = 1; i < ob->totcol + 1; i++) {
1569  }
1570 }
1571 
1575 };
1576 
1577 static bool texpaint_slot_node_find_cb(bNode *node, void *userdata)
1578 {
1579  struct FindTexPaintNodeData *find_data = userdata;
1580  if (find_data->slot->ima && node->type == SH_NODE_TEX_IMAGE) {
1581  Image *node_ima = (Image *)node->id;
1582  if (find_data->slot->ima == node_ima) {
1583  find_data->r_node = node;
1584  return false;
1585  }
1586  }
1587 
1588  if (find_data->slot->attribute_name && node->type == SH_NODE_ATTRIBUTE) {
1589  NodeShaderAttribute *storage = node->storage;
1590  if (STREQLEN(find_data->slot->attribute_name, storage->name, sizeof(storage->name))) {
1591  find_data->r_node = node;
1592  return false;
1593  }
1594  }
1595 
1596  return true;
1597 }
1598 
1600 {
1601  TexPaintSlot *slot = &ma->texpaintslot[texpaint_slot];
1602  struct FindTexPaintNodeData find_data = {slot, NULL};
1605  &find_data,
1607 
1608  return find_data.r_node;
1609 }
1610 
1611 void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
1612 {
1613  float tmp, facm = 1.0f - fac;
1614 
1615  switch (type) {
1616  case MA_RAMP_BLEND:
1617  r_col[0] = facm * (r_col[0]) + fac * col[0];
1618  r_col[1] = facm * (r_col[1]) + fac * col[1];
1619  r_col[2] = facm * (r_col[2]) + fac * col[2];
1620  break;
1621  case MA_RAMP_ADD:
1622  r_col[0] += fac * col[0];
1623  r_col[1] += fac * col[1];
1624  r_col[2] += fac * col[2];
1625  break;
1626  case MA_RAMP_MULT:
1627  r_col[0] *= (facm + fac * col[0]);
1628  r_col[1] *= (facm + fac * col[1]);
1629  r_col[2] *= (facm + fac * col[2]);
1630  break;
1631  case MA_RAMP_SCREEN:
1632  r_col[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1633  r_col[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1634  r_col[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1635  break;
1636  case MA_RAMP_OVERLAY:
1637  if (r_col[0] < 0.5f) {
1638  r_col[0] *= (facm + 2.0f * fac * col[0]);
1639  }
1640  else {
1641  r_col[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - r_col[0]);
1642  }
1643  if (r_col[1] < 0.5f) {
1644  r_col[1] *= (facm + 2.0f * fac * col[1]);
1645  }
1646  else {
1647  r_col[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - r_col[1]);
1648  }
1649  if (r_col[2] < 0.5f) {
1650  r_col[2] *= (facm + 2.0f * fac * col[2]);
1651  }
1652  else {
1653  r_col[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - r_col[2]);
1654  }
1655  break;
1656  case MA_RAMP_SUB:
1657  r_col[0] -= fac * col[0];
1658  r_col[1] -= fac * col[1];
1659  r_col[2] -= fac * col[2];
1660  break;
1661  case MA_RAMP_DIV:
1662  if (col[0] != 0.0f) {
1663  r_col[0] = facm * (r_col[0]) + fac * (r_col[0]) / col[0];
1664  }
1665  if (col[1] != 0.0f) {
1666  r_col[1] = facm * (r_col[1]) + fac * (r_col[1]) / col[1];
1667  }
1668  if (col[2] != 0.0f) {
1669  r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2];
1670  }
1671  break;
1672  case MA_RAMP_DIFF:
1673  r_col[0] = facm * (r_col[0]) + fac * fabsf(r_col[0] - col[0]);
1674  r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]);
1675  r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]);
1676  break;
1677  case MA_RAMP_DARK:
1678  r_col[0] = min_ff(r_col[0], col[0]) * fac + r_col[0] * facm;
1679  r_col[1] = min_ff(r_col[1], col[1]) * fac + r_col[1] * facm;
1680  r_col[2] = min_ff(r_col[2], col[2]) * fac + r_col[2] * facm;
1681  break;
1682  case MA_RAMP_LIGHT:
1683  tmp = fac * col[0];
1684  if (tmp > r_col[0]) {
1685  r_col[0] = tmp;
1686  }
1687  tmp = fac * col[1];
1688  if (tmp > r_col[1]) {
1689  r_col[1] = tmp;
1690  }
1691  tmp = fac * col[2];
1692  if (tmp > r_col[2]) {
1693  r_col[2] = tmp;
1694  }
1695  break;
1696  case MA_RAMP_DODGE:
1697  if (r_col[0] != 0.0f) {
1698  tmp = 1.0f - fac * col[0];
1699  if (tmp <= 0.0f) {
1700  r_col[0] = 1.0f;
1701  }
1702  else if ((tmp = (r_col[0]) / tmp) > 1.0f) {
1703  r_col[0] = 1.0f;
1704  }
1705  else {
1706  r_col[0] = tmp;
1707  }
1708  }
1709  if (r_col[1] != 0.0f) {
1710  tmp = 1.0f - fac * col[1];
1711  if (tmp <= 0.0f) {
1712  r_col[1] = 1.0f;
1713  }
1714  else if ((tmp = (r_col[1]) / tmp) > 1.0f) {
1715  r_col[1] = 1.0f;
1716  }
1717  else {
1718  r_col[1] = tmp;
1719  }
1720  }
1721  if (r_col[2] != 0.0f) {
1722  tmp = 1.0f - fac * col[2];
1723  if (tmp <= 0.0f) {
1724  r_col[2] = 1.0f;
1725  }
1726  else if ((tmp = (r_col[2]) / tmp) > 1.0f) {
1727  r_col[2] = 1.0f;
1728  }
1729  else {
1730  r_col[2] = tmp;
1731  }
1732  }
1733  break;
1734  case MA_RAMP_BURN:
1735  tmp = facm + fac * col[0];
1736 
1737  if (tmp <= 0.0f) {
1738  r_col[0] = 0.0f;
1739  }
1740  else if ((tmp = (1.0f - (1.0f - (r_col[0])) / tmp)) < 0.0f) {
1741  r_col[0] = 0.0f;
1742  }
1743  else if (tmp > 1.0f) {
1744  r_col[0] = 1.0f;
1745  }
1746  else {
1747  r_col[0] = tmp;
1748  }
1749 
1750  tmp = facm + fac * col[1];
1751  if (tmp <= 0.0f) {
1752  r_col[1] = 0.0f;
1753  }
1754  else if ((tmp = (1.0f - (1.0f - (r_col[1])) / tmp)) < 0.0f) {
1755  r_col[1] = 0.0f;
1756  }
1757  else if (tmp > 1.0f) {
1758  r_col[1] = 1.0f;
1759  }
1760  else {
1761  r_col[1] = tmp;
1762  }
1763 
1764  tmp = facm + fac * col[2];
1765  if (tmp <= 0.0f) {
1766  r_col[2] = 0.0f;
1767  }
1768  else if ((tmp = (1.0f - (1.0f - (r_col[2])) / tmp)) < 0.0f) {
1769  r_col[2] = 0.0f;
1770  }
1771  else if (tmp > 1.0f) {
1772  r_col[2] = 1.0f;
1773  }
1774  else {
1775  r_col[2] = tmp;
1776  }
1777  break;
1778  case MA_RAMP_HUE: {
1779  float rH, rS, rV;
1780  float colH, colS, colV;
1781  float tmpr, tmpg, tmpb;
1782  rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1783  if (colS != 0) {
1784  rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1785  hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb);
1786  r_col[0] = facm * (r_col[0]) + fac * tmpr;
1787  r_col[1] = facm * (r_col[1]) + fac * tmpg;
1788  r_col[2] = facm * (r_col[2]) + fac * tmpb;
1789  }
1790  break;
1791  }
1792  case MA_RAMP_SAT: {
1793  float rH, rS, rV;
1794  float colH, colS, colV;
1795  rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1796  if (rS != 0) {
1797  rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1798  hsv_to_rgb(rH, (facm * rS + fac * colS), rV, r_col + 0, r_col + 1, r_col + 2);
1799  }
1800  break;
1801  }
1802  case MA_RAMP_VAL: {
1803  float rH, rS, rV;
1804  float colH, colS, colV;
1805  rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1806  rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1807  hsv_to_rgb(rH, rS, (facm * rV + fac * colV), r_col + 0, r_col + 1, r_col + 2);
1808  break;
1809  }
1810  case MA_RAMP_COLOR: {
1811  float rH, rS, rV;
1812  float colH, colS, colV;
1813  float tmpr, tmpg, tmpb;
1814  rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
1815  if (colS != 0) {
1816  rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
1817  hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb);
1818  r_col[0] = facm * (r_col[0]) + fac * tmpr;
1819  r_col[1] = facm * (r_col[1]) + fac * tmpg;
1820  r_col[2] = facm * (r_col[2]) + fac * tmpb;
1821  }
1822  break;
1823  }
1824  case MA_RAMP_SOFT: {
1825  float scr, scg, scb;
1826 
1827  /* first calculate non-fac based Screen mix */
1828  scr = 1.0f - (1.0f - col[0]) * (1.0f - r_col[0]);
1829  scg = 1.0f - (1.0f - col[1]) * (1.0f - r_col[1]);
1830  scb = 1.0f - (1.0f - col[2]) * (1.0f - r_col[2]);
1831 
1832  r_col[0] = facm * (r_col[0]) +
1833  fac * (((1.0f - r_col[0]) * col[0] * (r_col[0])) + (r_col[0] * scr));
1834  r_col[1] = facm * (r_col[1]) +
1835  fac * (((1.0f - r_col[1]) * col[1] * (r_col[1])) + (r_col[1] * scg));
1836  r_col[2] = facm * (r_col[2]) +
1837  fac * (((1.0f - r_col[2]) * col[2] * (r_col[2])) + (r_col[2] * scb));
1838  break;
1839  }
1840  case MA_RAMP_LINEAR:
1841  if (col[0] > 0.5f) {
1842  r_col[0] = r_col[0] + fac * (2.0f * (col[0] - 0.5f));
1843  }
1844  else {
1845  r_col[0] = r_col[0] + fac * (2.0f * (col[0]) - 1.0f);
1846  }
1847  if (col[1] > 0.5f) {
1848  r_col[1] = r_col[1] + fac * (2.0f * (col[1] - 0.5f));
1849  }
1850  else {
1851  r_col[1] = r_col[1] + fac * (2.0f * (col[1]) - 1.0f);
1852  }
1853  if (col[2] > 0.5f) {
1854  r_col[2] = r_col[2] + fac * (2.0f * (col[2] - 0.5f));
1855  }
1856  else {
1857  r_col[2] = r_col[2] + fac * (2.0f * (col[2]) - 1.0f);
1858  }
1859  break;
1860  }
1861 }
1862 
1869 static short matcopied = 0;
1870 
1872 {
1873  memset(&matcopybuf, 0, sizeof(Material));
1874  matcopied = 0;
1875 }
1876 
1878 {
1879  if (matcopybuf.nodetree) {
1881  BLI_assert(!matcopybuf.nodetree->id.py_instance); /* Or call #BKE_libblock_free_data_py. */
1884  }
1885 
1886  matcopied = 0;
1887 }
1888 
1890 {
1891  if (matcopied) {
1893  }
1894 
1895  memcpy(&matcopybuf, ma, sizeof(Material));
1896 
1897  if (ma->nodetree != NULL) {
1898  matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, bmain, false);
1899  }
1900 
1903  /* TODO: Duplicate Engine Settings and set runtime to NULL. */
1904  matcopied = 1;
1905 }
1906 
1908 {
1909  ID id;
1910 
1911  if (matcopied == 0) {
1912  return;
1913  }
1914 
1915  /* Free gpu material before the ntree */
1917 
1918  if (ma->nodetree) {
1920  MEM_freeN(ma->nodetree);
1921  }
1922 
1923  id = (ma->id);
1924  memcpy(ma, &matcopybuf, sizeof(Material));
1925  (ma->id) = id;
1926 
1927  if (matcopybuf.nodetree != NULL) {
1928  ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, bmain, false);
1929  }
1930 }
1931 
1933 {
1936 }
1937 
1938 /* Default Materials
1939  *
1940  * Used for rendering when objects have no materials assigned, and initializing
1941  * default shader nodes. */
1942 
1948 
1954  NULL};
1955 
1957 {
1958  strcpy(ma->id.name, "MADefault GPencil");
1960  add_v3_fl(&ma->gp_style->stroke_rgba[0], 0.6f);
1961 }
1962 
1964 {
1965  strcpy(ma->id.name, "MADefault Surface");
1966 
1967  bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
1968  ma->nodetree = ntree;
1969  ma->use_nodes = true;
1970 
1972  bNodeSocket *base_color = nodeFindSocket(principled, SOCK_IN, "Base Color");
1973  copy_v3_v3(((bNodeSocketValueRGBA *)base_color->default_value)->value, &ma->r);
1974 
1976 
1978  principled,
1979  nodeFindSocket(principled, SOCK_OUT, "BSDF"),
1980  output,
1981  nodeFindSocket(output, SOCK_IN, "Surface"));
1982 
1983  principled->locx = 10.0f;
1984  principled->locy = 300.0f;
1985  output->locx = 300.0f;
1986  output->locy = 300.0f;
1987 
1989 }
1990 
1992 {
1993  strcpy(ma->id.name, "MADefault Volume");
1994 
1995  bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
1996  ma->nodetree = ntree;
1997  ma->use_nodes = true;
1998 
2001 
2003  principled,
2004  nodeFindSocket(principled, SOCK_OUT, "Volume"),
2005  output,
2006  nodeFindSocket(output, SOCK_IN, "Volume"));
2007 
2008  principled->locx = 10.0f;
2009  principled->locy = 300.0f;
2010  output->locx = 300.0f;
2011  output->locy = 300.0f;
2012 
2014 }
2015 
2017 {
2018  strcpy(ma->id.name, "MADefault Holdout");
2019 
2020  bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
2021  ma->nodetree = ntree;
2022  ma->use_nodes = true;
2023 
2026 
2028  holdout,
2029  nodeFindSocket(holdout, SOCK_OUT, "Holdout"),
2030  output,
2031  nodeFindSocket(output, SOCK_IN, "Surface"));
2032 
2033  holdout->locx = 10.0f;
2034  holdout->locy = 300.0f;
2035  output->locx = 300.0f;
2036  output->locy = 300.0f;
2037 
2039 }
2040 
2042 {
2043  return &default_material_empty;
2044 }
2045 
2047 {
2048  return &default_material_holdout;
2049 }
2050 
2052 {
2053  return &default_material_surface;
2054 }
2055 
2057 {
2058  return &default_material_volume;
2059 }
2060 
2062 {
2063  return &default_material_gpencil;
2064 }
2065 
2067 {
2068  for (int i = 0; default_materials[i]; i++) {
2069  Material *ma = default_materials[i];
2070  if (ma->gpumaterial.first) {
2072  }
2073  }
2074 }
2075 
2076 /* Module functions called on startup and exit. */
2077 
2079 {
2080  for (int i = 0; default_materials[i]; i++) {
2082  }
2083 
2088 }
2089 
2091 {
2092  for (int i = 0; default_materials[i]; i++) {
2094  }
2095 }
void BKE_animdata_blend_read_data(struct BlendDataReader *reader, struct AnimData *adt)
Definition: anim_data.c:1443
void BKE_animdata_blend_write(struct BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1421
Generic geometry attributes built on CustomData.
struct CustomDataLayer * BKE_id_attributes_color_find(const struct ID *id, const char *name)
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.cc:5393
void BKE_curve_material_index_clear(struct Curve *cu)
Definition: curve.cc:5343
void BKE_curve_material_index_remove(struct Curve *cu, int index)
Definition: curve.cc:5299
display list (or rather multi purpose list) stuff.
void BKE_displist_free(struct ListBase *lb)
Definition: displist.cc:69
bool BKE_gpencil_material_index_used(struct bGPdata *gpd, int index)
Definition: gpencil.c:1963
void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len)
Definition: gpencil.c:1978
void BKE_gpencil_material_index_reassign(struct bGPdata *gpd, int totcol, int index)
Definition: gpencil.c:1948
void BKE_icon_id_delete(struct ID *id)
Definition: icons.cc:870
void BKE_previewimg_free(struct PreviewImage **prv)
Definition: icons.cc:283
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:615
void BKE_previewimg_blend_write(struct BlendWriter *writer, const struct PreviewImage *prv)
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition: BKE_idtype.h:39
@ LIB_ID_CREATE_NO_ALLOCATE
Definition: BKE_lib_id.h:130
@ LIB_ID_COPY_NO_PREVIEW
Definition: BKE_lib_id.h:150
@ LIB_ID_CREATE_LOCAL
Definition: BKE_lib_id.h:139
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2008
void * BKE_id_new(struct Main *bmain, short type, const char *name)
Definition: lib_id.c:1159
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag)
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(_data, _func_call)
void BKE_library_foreach_ID_embedded(struct LibraryForeachIDData *data, struct ID **id_pp)
Definition: lib_query.c:147
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
void BKE_main_unlock(struct Main *bmain)
Definition: main.c:219
void BKE_main_lock(struct Main *bmain)
Definition: main.c:214
General operations, lookup, etc. for materials.
@ BKE_MAT_ASSIGN_OBDATA
Definition: BKE_material.h:81
@ BKE_MAT_ASSIGN_USERPREF
Definition: BKE_material.h:80
@ BKE_MAT_ASSIGN_OBJECT
Definition: BKE_material.h:82
@ BKE_MAT_ASSIGN_EXISTING
Definition: BKE_material.h:79
bool BKE_mesh_material_index_used(struct Mesh *me, short index)
Definition: mesh.cc:1420
void BKE_mesh_material_remap(struct Mesh *me, const unsigned int *remap, unsigned int remap_len)
Definition: mesh.cc:1456
void BKE_mesh_material_index_remove(struct Mesh *me, short index)
Definition: mesh.cc:1401
void BKE_mesh_material_index_clear(struct Mesh *me)
Definition: mesh.cc:1441
#define SH_NODE_HOLDOUT
Definition: BKE_node.h:1130
#define SH_NODE_UVMAP
Definition: BKE_node.h:1158
void ntreeBlendWrite(struct BlendWriter *writer, struct bNodeTree *ntree)
Definition: node.cc:519
#define NODE_CUSTOM_GROUP
Definition: BKE_node.h:989
#define SH_NODE_BSDF_PRINCIPLED
Definition: BKE_node.h:1164
struct bNodeTree * ntreeCopyTree_ex(const struct bNodeTree *ntree, struct Main *bmain, bool do_id_user)
struct bNode * nodeGetActivePaintCanvas(struct bNodeTree *ntree)
#define SH_NODE_OUTPUT_MATERIAL
Definition: BKE_node.h:1101
void ntreeFreeEmbeddedTree(struct bNodeTree *ntree)
Definition: node.cc:3112
struct bNodeLink * nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock)
Definition: node.cc:2296
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
#define NODE_CLASS_INPUT
Definition: BKE_node.h:345
struct bNodeTree * ntreeAddTree(struct Main *bmain, const char *name, const char *idname)
Definition: node.cc:2674
struct bNode * nodeAddStaticNode(const struct bContext *C, struct bNodeTree *ntree, int type)
Definition: node.cc:2151
#define SH_NODE_VOLUME_PRINCIPLED
Definition: BKE_node.h:1170
#define NODE_CLASS_TEXTURE
Definition: BKE_node.h:355
void nodeSetActive(struct bNodeTree *ntree, struct bNode *node)
Definition: node.cc:3644
#define SH_NODE_ATTRIBUTE
Definition: BKE_node.h:1106
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_editmesh_eval_final(const struct Object *object)
bool BKE_object_supports_material_slots(struct Object *ob)
Definition: object.cc:5070
Generic array manipulation API.
#define BLI_array_permute(arr, arr_len, order)
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
bool BLI_ghash_reinsert(GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:715
GHash * BLI_ghash_ptr_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:748
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
MINLINE float min_ff(float a, float b)
MINLINE int clamp_i(int value, int min, int max)
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
Definition: math_color.c:208
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:13
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 STREQLEN(a, b, n)
#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)
#define BLT_I18NCONTEXT_ID_MATERIAL
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
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)
bool DEG_is_evaluated_object(const struct Object *object)
struct ID * DEG_get_original_id(struct ID *id)
ID and Library types, which are fundamental for sdna.
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_SHADING
Definition: DNA_ID.h:811
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
#define FILTER_ID_MA
Definition: DNA_ID.h:910
@ INDEX_ID_MA
Definition: DNA_ID.h:1012
@ LIB_TAG_MISSING
Definition: DNA_ID.h:690
@ ID_VO
Definition: DNA_ID_enums.h:83
@ ID_GD
Definition: DNA_ID_enums.h:71
@ ID_CV
Definition: DNA_ID_enums.h:81
@ ID_MA
Definition: DNA_ID_enums.h:51
@ ID_CU_LEGACY
Definition: DNA_ID_enums.h:49
@ ID_ME
Definition: DNA_ID_enums.h:48
@ ID_MB
Definition: DNA_ID_enums.h:50
@ ID_PT
Definition: DNA_ID_enums.h:82
Object groups, one object can be in many groups at once.
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
#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
@ SHD_ATTRIBUTE_GEOMETRY
@ OB_MODE_EDIT
@ OB_MODE_SCULPT
Object is a sort of wrapper for general info.
#define OB_DATA_SUPPORT_ID(_id_type)
@ OB_MBALL
@ OB_EMPTY
@ OB_SURF
@ OB_FONT
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
@ OB_GPENCIL
#define 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:171
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
NODE_GROUP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block SH_NODE_TEX_IMAGE
unsigned int U
Definition: btGjkEpa3.h:78
OperationNode * node
Scene scene
Material material
const Depsgraph * depsgraph
DEGForeachIDComponentCallback callback
bNodeTree * ntree
uint col
int count
#define GS(x)
Definition: iris.c:225
ccl_global KernelShaderEvalInput ccl_global float * output
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_recallocN_id)(void *vmemh, size_t len, const char *str)
Definition: mallocn.c:30
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
bool(* ForEachTexNodeCallback)(bNode *node, void *userdata)
Definition: material.c:1369
static void material_default_surface_init(Material *ma)
Definition: material.c:1963
void BKE_materials_init(void)
Definition: material.c:2078
void BKE_materials_exit(void)
Definition: material.c:2090
static void material_default_holdout_init(Material *ma)
Definition: material.c:2016
static void material_data_index_clear_id(ID *id)
Definition: material.c:484
Material * BKE_object_material_get_eval(Object *ob, short act)
Definition: material.c:707
static void fill_texpaint_slots_recursive(bNodeTree *nodetree, bNode *active_node, const Object *ob, Material *ma, int slot_len, ePaintSlotFilter slot_filter)
Definition: material.c:1480
void BKE_id_material_eval_ensure_default_slot(ID *id)
Definition: material.c:784
static void material_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: material.c:211
void BKE_gpencil_material_attr_init(Material *ma)
Definition: material.c:270
void BKE_id_material_clear(Main *bmain, ID *id)
Definition: material.c:621
void BKE_object_material_array_assign(Main *bmain, struct Object *ob, struct Material ***matar, int totcol, const bool to_object_only)
Definition: material.c:1173
Material * BKE_material_default_empty(void)
Definition: material.c:2041
void BKE_material_copybuf_copy(Main *bmain, Material *ma)
Definition: material.c:1889
static Material matcopybuf
copy/paste buffer, if we had a proper py api that would be better
Definition: material.c:1868
Material ** BKE_object_material_get_p(Object *ob, short act)
Definition: material.c:644
void BKE_object_material_remap(Object *ob, const unsigned int *remap)
Definition: material.c:1060
void BKE_id_material_assign(Main *bmain, ID *id, Material *ma, short act)
Definition: material.c:905
static bool ntree_foreach_texnode_recursive(bNodeTree *nodetree, ForEachTexNodeCallback callback, void *userdata, ePaintSlotFilter slot_filter)
Definition: material.c:1370
static Material default_material_gpencil
Definition: material.c:1947
static void material_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: material.c:150
short BKE_object_material_slot_find_index(Object *ob, Material *ma)
Definition: material.c:1205
static bool count_texture_nodes_cb(bNode *UNUSED(node), void *userdata)
Definition: material.c:1400
Material * BKE_id_material_pop(Main *bmain, ID *id, int index_i)
Definition: material.c:583
void BKE_object_material_from_eval_data(Main *bmain, Object *ob_orig, const ID *data_eval)
Definition: material.c:1138
Material * BKE_gpencil_material_add(Main *bmain, const char *name)
Definition: material.c:298
static void material_data_index_remove_id(ID *id, short index)
Definition: material.c:429
Material *** BKE_object_material_array_p(Object *ob)
Definition: material.c:311
static Material default_material_surface
Definition: material.c:1945
Material * BKE_gpencil_material(Object *ob, short act)
Definition: material.c:795
Material * BKE_material_default_gpencil(void)
Definition: material.c:2061
static void material_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: material.c:165
short * BKE_object_material_len_p(Object *ob)
Definition: material.c:344
static bool texpaint_slot_node_find_cb(bNode *node, void *userdata)
Definition: material.c:1577
void BKE_material_copybuf_paste(Main *bmain, Material *ma)
Definition: material.c:1907
short * BKE_id_material_len_p(ID *id)
Definition: material.c:403
static Material default_material_empty
Definition: material.c:1943
void BKE_id_materials_copy(Main *bmain, ID *id_src, ID *id_dst)
Definition: material.c:507
void BKE_object_material_assign_single_obdata(struct Main *bmain, struct Object *ob, struct Material *ma, short act)
Definition: material.c:1052
int BKE_object_material_count_eval(Object *ob)
Definition: material.c:746
bool BKE_object_material_slot_add(Main *bmain, Object *ob)
Definition: material.c:1232
IDTypeInfo IDType_ID_MA
Definition: material.c:240
static void material_free_data(ID *id)
Definition: material.c:128
static ID * get_evaluated_object_data_with_materials(Object *ob)
Definition: material.c:693
bNode * BKE_texpaint_slot_material_find_node(Material *ma, short texpaint_slot)
Definition: material.c:1599
static Material * default_materials[]
Definition: material.c:1949
void BKE_id_material_resize(Main *bmain, ID *id, short totcol, bool do_id_user)
Definition: material.c:528
Material *** BKE_id_material_array_p(ID *id)
Definition: material.c:377
static short matcopied
Definition: material.c:1869
void BKE_material_copybuf_free(void)
Definition: material.c:1877
static void material_blend_read_expand(BlendExpander *expander, ID *id)
Definition: material.c:228
static Material default_material_holdout
Definition: material.c:1944
void BKE_id_material_eval_assign(ID *id, int slot, Material *material)
Definition: material.c:758
MaterialGPencilStyle * BKE_gpencil_material_settings(Object *ob, short act)
Definition: material.c:805
Material * BKE_material_default_volume(void)
Definition: material.c:2056
void BKE_object_materials_test(Main *bmain, Object *ob, ID *id)
Definition: material.c:864
void BKE_id_material_append(Main *bmain, ID *id, Material *ma)
Definition: material.c:559
bool BKE_object_material_slot_used(Object *object, short actcol)
Definition: material.c:452
static void object_material_assign(Main *bmain, Object *ob, Material *ma, short act, int assign_type, bool do_test_all)
Definition: material.c:952
void BKE_object_material_resize(Main *bmain, Object *ob, const short totcol, bool do_id_user)
Definition: material.c:819
void BKE_objects_materials_test_all(Main *bmain, ID *id)
Definition: material.c:886
static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
Definition: material.c:86
void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
Definition: material.c:1564
void BKE_object_material_remap_calc(Object *ob_dst, Object *ob_src, short *remap_src_to_dst)
Definition: material.c:1090
static void material_default_volume_init(Material *ma)
Definition: material.c:1991
void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma, const struct Object *ob)
Definition: material.c:1501
static void material_default_gpencil_init(Material *ma)
Definition: material.c:1956
static void material_blend_read_data(BlendDataReader *reader, ID *id)
Definition: material.c:195
static ePaintSlotFilter material_paint_slot_filter(const struct Object *ob)
Definition: material.c:1492
ePaintSlotFilter
Definition: material.c:1364
@ PAINT_SLOT_IMAGE
Definition: material.c:1365
@ PAINT_SLOT_COLOR_ATTRIBUTE
Definition: material.c:1366
Material * BKE_material_default_holdout(void)
Definition: material.c:2046
Material * BKE_object_material_get(Object *ob, short act)
Definition: material.c:687
static int count_texture_nodes_recursive(bNodeTree *nodetree, ePaintSlotFilter slot_filter)
Definition: material.c:1406
static void material_init_data(ID *id)
Definition: material.c:77
static CLG_LogRef LOG
Definition: material.c:75
Material * BKE_material_add(Main *bmain, const char *name)
Definition: material.c:289
void BKE_object_material_assign(Main *bmain, Object *ob, Material *ma, short act, int assign_type)
Definition: material.c:1047
void BKE_material_defaults_free_gpu(void)
Definition: material.c:2066
static Material default_material_volume
Definition: material.c:1946
static bool fill_texpaint_slots_cb(bNode *node, void *userdata)
Definition: material.c:1422
void BKE_material_copybuf_clear(void)
Definition: material.c:1871
void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
Definition: material.c:1932
Material * BKE_material_default_surface(void)
Definition: material.c:2051
bool BKE_object_material_slot_remove(Main *bmain, Object *ob)
Definition: material.c:1248
static bNode * nodetree_uv_node_recursive(bNode *node)
Definition: material.c:1344
void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
Definition: material.c:1611
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned a[3]
Definition: RandGen.cpp:78
return ret
ListBase disp
Definition: BKE_curve.h:33
struct Material ** mat
short totcol
const Object * ob
Definition: material.c:1416
TexPaintSlot * slot
Definition: material.c:1573
short id_code
Definition: BKE_idtype.h:114
Definition: DNA_ID.h:368
void * py_instance
Definition: DNA_ID.h:435
int tag
Definition: DNA_ID.h:387
struct Library * lib
Definition: DNA_ID.h:372
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase objects
Definition: BKE_main.h:170
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 BMEditMesh * edit_mesh
struct Material ** mat
short totcol
short totcol
struct Material ** mat
struct CurveCache * curve_cache
ListBase particlesystem
struct Material ** mat
char * matbits
Object_Runtime runtime
void * data
struct Material ** mat
struct ToolSettings * toolsettings
struct Image * ima
struct ImageUser * image_user
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:375
ListBase nodes
int type
Definition: BKE_node.h:228
short nclass
Definition: BKE_node.h:236
float locy
struct bNodeType * typeinfo
float locx
void * storage
smooth(Type::VEC3, "normal_interp") .smooth(Type materials_data[4096]