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