Blender V4.3
render_shading.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "DNA_ID.h"
15#include "DNA_curve_types.h"
16#include "DNA_light_types.h"
18#include "DNA_material_types.h"
19#include "DNA_node_types.h"
20#include "DNA_object_types.h"
21#include "DNA_particle_types.h"
22#include "DNA_scene_types.h"
23#include "DNA_space_types.h"
24#include "DNA_world_types.h"
25
26#include "BLI_listbase.h"
27#include "BLI_math_vector.h"
28#include "BLI_path_utils.hh"
29#include "BLI_string.h"
30#include "BLI_string_utils.hh"
31#include "BLI_utildefines.h"
32
33#include "BLT_translation.hh"
34
35#include "BKE_anim_data.hh"
36#include "BKE_animsys.h"
37#include "BKE_appdir.hh"
39#include "BKE_blendfile.hh"
40#include "BKE_brush.hh"
41#include "BKE_context.hh"
42#include "BKE_curve.hh"
43#include "BKE_editmesh.hh"
44#include "BKE_global.hh"
45#include "BKE_image.hh"
46#include "BKE_layer.hh"
47#include "BKE_lib_id.hh"
48#include "BKE_lib_query.hh"
49#include "BKE_lib_remap.hh"
50#include "BKE_lightprobe.h"
51#include "BKE_linestyle.h"
52#include "BKE_main.hh"
53#include "BKE_material.h"
54#include "BKE_node.hh"
55#include "BKE_node_runtime.hh"
57#include "BKE_object.hh"
58#include "BKE_report.hh"
59#include "BKE_scene.hh"
60#include "BKE_texture.h"
61#include "BKE_vfont.hh"
62#include "BKE_workspace.hh"
63#include "BKE_world.h"
64
65#include "NOD_composite.hh"
66
67#include "DEG_depsgraph.hh"
70
71#ifdef WITH_FREESTYLE
72# include "BKE_freestyle.h"
73# include "FRS_freestyle.h"
74# include "RNA_enum_types.hh"
75#endif
76
77#include "RNA_access.hh"
78
79#include "WM_api.hh"
80#include "WM_types.hh"
81
82#include "ED_curve.hh"
83#include "ED_mesh.hh"
84#include "ED_node.hh"
85#include "ED_object.hh"
86#include "ED_paint.hh"
87#include "ED_render.hh"
88#include "ED_scene.hh"
89#include "ED_screen.hh"
90
91#include "RNA_define.hh"
92#include "RNA_prototypes.hh"
93
94#include "UI_interface.hh"
95
96#include "RE_engine.h"
97#include "RE_pipeline.h"
98
100
101#include "render_intern.hh" /* own include */
102
103using blender::Vector;
104
105static bool object_materials_supported_poll_ex(bContext *C, const Object *ob);
106
107/* -------------------------------------------------------------------- */
110
111static void material_copybuffer_filepath_get(char filepath[FILE_MAX], size_t filepath_maxncpy)
112{
113 BLI_path_join(filepath, filepath_maxncpy, BKE_tempdir_base(), "copybuffer_material.blend");
114}
115
116static bool object_array_for_shading_edit_mode_enabled_filter(const Object *ob, void *user_data)
117{
118 bContext *C = static_cast<bContext *>(user_data);
120 if (BKE_object_is_in_editmode(ob) == true) {
121 return true;
122 }
123 }
124 return false;
125}
126
132
133static bool object_array_for_shading_edit_mode_disabled_filter(const Object *ob, void *user_data)
134{
135 bContext *C = static_cast<bContext *>(user_data);
137 if (BKE_object_is_in_editmode(ob) == false) {
138 return true;
139 }
140 }
141 return false;
142}
143
149
151
152/* -------------------------------------------------------------------- */
155
157{
159 return false;
160 }
161 if (!OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
162 return false;
163 }
164
165 /* Material linked to object. */
166 if (ob->matbits && ob->actcol && ob->matbits[ob->actcol - 1]) {
167 return true;
168 }
169
170 /* Material linked to obdata. */
171 const ID *data = static_cast<ID *>(ob->data);
173}
174
180
182
183/* -------------------------------------------------------------------- */
186
188{
189 Main *bmain = CTX_data_main(C);
191
192 if (!ob) {
193 return OPERATOR_CANCELLED;
194 }
195
197
198 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
199 Scene *scene = CTX_data_scene(C);
200 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
202 }
203
207
208 return OPERATOR_FINISHED;
209}
210
212{
213 /* identifiers */
214 ot->name = "Add Material Slot";
215 ot->idname = "OBJECT_OT_material_slot_add";
216 ot->description = "Add a new material slot";
217
218 /* api callbacks */
221
222 /* flags */
224}
225
227
228/* -------------------------------------------------------------------- */
231
233{
235
236 if (!ob) {
237 return OPERATOR_CANCELLED;
238 }
239
240 /* Removing material slots in edit mode screws things up, see bug #21822. */
241 if (ob == CTX_data_edit_object(C)) {
242 BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
243 return OPERATOR_CANCELLED;
244 }
245
247
248 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
249 Scene *scene = CTX_data_scene(C);
250 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
252 }
253
258
259 return OPERATOR_FINISHED;
260}
261
263{
264 /* identifiers */
265 ot->name = "Remove Material Slot";
266 ot->idname = "OBJECT_OT_material_slot_remove";
267 ot->description = "Remove the selected material slot";
268
269 /* api callbacks */
272
273 /* flags */
275}
276
278
279/* -------------------------------------------------------------------- */
282
284{
285 View3D *v3d = CTX_wm_view3d(C);
286 bool changed_multi = false;
287
289 const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : nullptr;
290
292 for (Object *ob : objects) {
293 short mat_nr_active = -1;
294
295 if (ob->totcol == 0) {
296 continue;
297 }
298 if (obact && (mat_active == BKE_object_material_get(ob, obact->actcol))) {
299 /* Avoid searching since there may be multiple slots with the same material.
300 * For the active object or duplicates: match the material slot index first. */
301 mat_nr_active = obact->actcol - 1;
302 }
303 else {
304 /* Find the first matching material.
305 * NOTE: there may be multiple but that's not a common use case. */
306 for (int i = 0; i < ob->totcol; i++) {
307 const Material *mat = BKE_object_material_get(ob, i + 1);
308 if (mat_active == mat) {
309 mat_nr_active = i;
310 break;
311 }
312 }
313 if (mat_nr_active == -1) {
314 continue;
315 }
316 }
317
318 bool changed = false;
319 if (ob->type == OB_MESH) {
321 BMFace *efa;
322 BMIter iter;
323
324 if (em) {
325 BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
327 changed = true;
328 efa->mat_nr = mat_nr_active;
329 }
330 }
331 }
332 }
333 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
334 ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
335
336 if (nurbs) {
337 LISTBASE_FOREACH (Nurb *, nu, nurbs) {
338 if (ED_curve_nurb_select_check(v3d, nu)) {
339 changed = true;
340 nu->mat_nr = mat_nr_active;
341 }
342 }
343 }
344 }
345 else if (ob->type == OB_FONT) {
346 EditFont *ef = ((Curve *)ob->data)->editfont;
347 int i, selstart, selend;
348
349 if (ef && BKE_vfont_select_get(ob, &selstart, &selend)) {
350 for (i = selstart; i <= selend; i++) {
351 changed = true;
352 ef->textbufinfo[i].mat_nr = mat_nr_active;
353 }
354 }
355 }
356
357 if (changed) {
358 changed_multi = true;
361 }
362 }
363
364 return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
365}
366
368{
369 /* identifiers */
370 ot->name = "Assign Material Slot";
371 ot->idname = "OBJECT_OT_material_slot_assign";
372 ot->description = "Assign active material slot to selection";
373
374 /* api callbacks */
377
378 /* flags */
380}
381
383
384/* -------------------------------------------------------------------- */
387
389{
390 bool changed_multi = false;
392 const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : nullptr;
393
395 for (Object *ob : objects) {
396 if (ob->totcol == 0) {
397 continue;
398 }
399
400 const short mat_nr_active = BKE_object_material_index_get_with_hint(
401 ob, mat_active, obact ? obact->actcol - 1 : -1);
402
403 if (mat_nr_active == -1) {
404 continue;
405 }
406
407 bool changed = false;
408
409 if (ob->type == OB_MESH) {
411
412 if (em) {
413 changed = EDBM_deselect_by_material(em, mat_nr_active, select);
414 }
415 }
416 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
417 ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
418 BPoint *bp;
419 BezTriple *bezt;
420 int a;
421
422 if (nurbs) {
423 LISTBASE_FOREACH (Nurb *, nu, nurbs) {
424 if (nu->mat_nr == mat_nr_active) {
425 if (nu->bezt) {
426 a = nu->pntsu;
427 bezt = nu->bezt;
428 while (a--) {
429 if (bezt->hide == 0) {
430 changed = true;
431 if (select) {
432 bezt->f1 |= SELECT;
433 bezt->f2 |= SELECT;
434 bezt->f3 |= SELECT;
435 }
436 else {
437 bezt->f1 &= ~SELECT;
438 bezt->f2 &= ~SELECT;
439 bezt->f3 &= ~SELECT;
440 }
441 }
442 bezt++;
443 }
444 }
445 else if (nu->bp) {
446 a = nu->pntsu * nu->pntsv;
447 bp = nu->bp;
448 while (a--) {
449 if (bp->hide == 0) {
450 changed = true;
451 if (select) {
452 bp->f1 |= SELECT;
453 }
454 else {
455 bp->f1 &= ~SELECT;
456 }
457 }
458 bp++;
459 }
460 }
461 }
462 }
463 }
464 }
465
466 if (changed) {
467 changed_multi = true;
468 DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_SELECT);
470 }
471 }
472
473 return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
474}
475
477{
478 return material_slot_de_select(C, true);
479}
480
482{
483 /* identifiers */
484 ot->name = "Select Material Slot";
485 ot->idname = "OBJECT_OT_material_slot_select";
486 ot->description = "Select by active material slot";
487
488 /* api callbacks */
490
491 /* flags */
493}
494
496{
497 return material_slot_de_select(C, false);
498}
499
501{
502 /* identifiers */
503 ot->name = "Deselect Material Slot";
504 ot->idname = "OBJECT_OT_material_slot_deselect";
505 ot->description = "Deselect by active material slot";
506
507 /* api callbacks */
509
510 /* flags */
512}
513
515
516/* -------------------------------------------------------------------- */
519
521{
522 Main *bmain = CTX_data_main(C);
524 Material ***matar_obdata;
525
526 if (!ob || !(matar_obdata = BKE_object_material_array_p(ob))) {
527 return OPERATOR_CANCELLED;
528 }
529
531
532 Material ***matar_object = &ob->mat;
533
534 Material **matar = static_cast<Material **>(
535 MEM_callocN(sizeof(*matar) * size_t(ob->totcol), __func__));
536 for (int i = ob->totcol; i--;) {
537 matar[i] = ob->matbits[i] ? (*matar_object)[i] : (*matar_obdata)[i];
538 }
539
540 CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
541 if (ob != ob_iter && BKE_object_material_array_p(ob_iter)) {
542 /* If we are using the same obdata, we only assign slots in ob_iter that are using object
543 * materials, and not obdata ones. */
544 const bool is_same_obdata = ob->data == ob_iter->data;
545
546 /* If we are using the same obdata, make the target object inherit the matbits of the active
547 * object. Without this, object material slots are not copied unless the target object
548 * already had its material slot link set to object. */
549 if (is_same_obdata) {
550 for (int i = ob->totcol; i--;) {
551 if (ob->matbits[i]) {
552 ob_iter->matbits[i] = ob->matbits[i];
553 }
554 }
555 }
556
557 BKE_object_material_array_assign(bmain, ob_iter, &matar, ob->totcol, is_same_obdata);
558
559 if (ob_iter->totcol == ob->totcol) {
560 ob_iter->actcol = ob->actcol;
563 }
564 }
565 }
567
568 MEM_freeN(matar);
569
570 return OPERATOR_FINISHED;
571}
572
574{
575 /* identifiers */
576 ot->name = "Copy Material to Selected";
577 ot->idname = "OBJECT_OT_material_slot_copy";
578 ot->description = "Copy material to selected objects";
579
580 /* api callbacks */
582
583 /* flags */
585}
586
588
589/* -------------------------------------------------------------------- */
592
594{
596
597 uint *slot_remap;
598 int index_pair[2];
599
600 int dir = RNA_enum_get(op->ptr, "direction");
601
602 if (!ob || ob->totcol < 2) {
603 return OPERATOR_CANCELLED;
604 }
605
606 /* up */
607 if (dir == 1 && ob->actcol > 1) {
608 index_pair[0] = ob->actcol - 2;
609 index_pair[1] = ob->actcol - 1;
610 ob->actcol--;
611 }
612 /* down */
613 else if (dir == -1 && ob->actcol < ob->totcol) {
614 index_pair[0] = ob->actcol - 1;
615 index_pair[1] = ob->actcol - 0;
616 ob->actcol++;
617 }
618 else {
619 return OPERATOR_CANCELLED;
620 }
621
622 slot_remap = static_cast<uint *>(MEM_mallocN(sizeof(uint) * ob->totcol, __func__));
623
624 range_vn_u(slot_remap, ob->totcol, 0);
625
626 slot_remap[index_pair[0]] = index_pair[1];
627 slot_remap[index_pair[1]] = index_pair[0];
628
629 BKE_object_material_remap(ob, slot_remap);
630
631 MEM_freeN(slot_remap);
632
636
637 return OPERATOR_FINISHED;
638}
639
641{
642 static const EnumPropertyItem material_slot_move[] = {
643 {1, "UP", 0, "Up", ""},
644 {-1, "DOWN", 0, "Down", ""},
645 {0, nullptr, 0, nullptr, nullptr},
646 };
647
648 /* identifiers */
649 ot->name = "Move Material";
650 ot->idname = "OBJECT_OT_material_slot_move";
651 ot->description = "Move the active material up/down in the list";
652
653 /* api callbacks */
656
657 /* flags */
659
660 RNA_def_enum(ot->srna,
661 "direction",
662 material_slot_move,
663 0,
664 "Direction",
665 "Direction to move the active material towards");
666}
667
669
670/* -------------------------------------------------------------------- */
673
675{
676 /* Removing material slots in edit mode screws things up, see bug #21822. */
677 Object *ob_active = CTX_data_active_object(C);
678 if (ob_active && BKE_object_is_in_editmode(ob_active)) {
679 BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
680 return OPERATOR_CANCELLED;
681 }
682
683 Main *bmain = CTX_data_main(C);
684 int removed = 0;
685
687 for (Object *ob : objects) {
688 int actcol = ob->actcol;
689 for (int slot = 1; slot <= ob->totcol; slot++) {
690 while (slot <= ob->totcol && !BKE_object_material_slot_used(ob, slot)) {
691 ob->actcol = slot;
693
694 if (actcol >= slot) {
695 actcol--;
696 }
697
698 removed++;
699 }
700 }
701 ob->actcol = actcol;
702
704 }
705
706 if (!removed) {
707 return OPERATOR_CANCELLED;
708 }
709
710 BKE_reportf(op->reports, RPT_INFO, "Removed %d slots", removed);
711
712 if (ob_active->mode & OB_MODE_TEXTURE_PAINT) {
713 Scene *scene = CTX_data_scene(C);
714 ED_paint_proj_mesh_data_check(*scene, *ob_active, nullptr, nullptr, nullptr, nullptr);
716 }
717
721
722 return OPERATOR_FINISHED;
723}
724
726{
727 /* identifiers */
728 ot->name = "Remove Unused Slots";
729 ot->idname = "OBJECT_OT_material_slot_remove_unused";
730 ot->description = "Remove unused material slots";
731
732 /* api callbacks */
735
736 /* flags */
738}
739
741
742/* -------------------------------------------------------------------- */
745
747{
748 Material *ma = static_cast<Material *>(
749 CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
750 Main *bmain = CTX_data_main(C);
752 PropertyRNA *prop;
753
754 /* hook into UI */
756
757 Object *ob = static_cast<Object *>((prop && RNA_struct_is_a(ptr.type, &RNA_Object)) ? ptr.data :
758 nullptr);
759
760 /* add or copy material */
761 if (ma) {
762 Material *new_ma = (Material *)BKE_id_copy_ex(
763 bmain, &ma->id, nullptr, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
764 ma = new_ma;
765 }
766 else {
767 const char *name = DATA_("Material");
768 if (!(ob != nullptr && ELEM(ob->type, OB_GPENCIL_LEGACY, OB_GREASE_PENCIL))) {
769 ma = BKE_material_add(bmain, name);
770 }
771 else {
772 ma = BKE_gpencil_material_add(bmain, name);
773 }
775 ma->use_nodes = true;
776 }
777
778 if (prop) {
779 if (ob != nullptr) {
780 /* Add slot follows user-preferences for creating new slots,
781 * RNA pointer assignment doesn't, see: #60014. */
782 if (BKE_object_material_get_p(ob, ob->actcol) == nullptr) {
784 }
785 }
786
787 /* when creating new ID blocks, use is already 1, but RNA
788 * pointer use also increases user, so this compensates it */
789 id_us_min(&ma->id);
790
791 if (ptr.owner_id) {
792 BKE_id_move_to_same_lib(*bmain, ma->id, *ptr.owner_id);
793 }
794
795 PointerRNA idptr = RNA_id_pointer_create(&ma->id);
796 RNA_property_pointer_set(&ptr, prop, idptr, nullptr);
797 RNA_property_update(C, &ptr, prop);
798 }
799
801
802 return OPERATOR_FINISHED;
803}
804
806{
807 /* identifiers */
808 ot->name = "New Material";
809 ot->idname = "MATERIAL_OT_new";
810 ot->description = "Add a new material";
811
812 /* api callbacks */
813 ot->exec = new_material_exec;
815
816 /* flags */
818}
819
821
822/* -------------------------------------------------------------------- */
825
826static int new_texture_exec(bContext *C, wmOperator * /*op*/)
827{
828 Tex *tex = static_cast<Tex *>(CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data);
829 Main *bmain = CTX_data_main(C);
831 PropertyRNA *prop;
832
833 /* add or copy texture */
834 if (tex) {
835 tex = (Tex *)BKE_id_copy(bmain, &tex->id);
836 }
837 else {
838 tex = BKE_texture_add(bmain, DATA_("Texture"));
839 }
840
841 /* hook into UI */
843
844 if (prop) {
845 /* when creating new ID blocks, use is already 1, but RNA
846 * pointer use also increases user, so this compensates it */
847 id_us_min(&tex->id);
848
849 if (ptr.owner_id) {
850 BKE_id_move_to_same_lib(*bmain, tex->id, *ptr.owner_id);
851 }
852
853 PointerRNA idptr = RNA_id_pointer_create(&tex->id);
854 RNA_property_pointer_set(&ptr, prop, idptr, nullptr);
855 RNA_property_update(C, &ptr, prop);
856 }
857
859
860 return OPERATOR_FINISHED;
861}
862
864{
865 /* identifiers */
866 ot->name = "New Texture";
867 ot->idname = "TEXTURE_OT_new";
868 ot->description = "Add a new texture";
869
870 /* api callbacks */
871 ot->exec = new_texture_exec;
872
873 /* flags */
875}
876
878
879/* -------------------------------------------------------------------- */
882
883static int new_world_exec(bContext *C, wmOperator * /*op*/)
884{
885 World *wo = static_cast<World *>(CTX_data_pointer_get_type(C, "world", &RNA_World).data);
886 Main *bmain = CTX_data_main(C);
888 PropertyRNA *prop;
889
890 /* add or copy world */
891 if (wo) {
892 World *new_wo = (World *)BKE_id_copy_ex(
893 bmain, &wo->id, nullptr, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
894 wo = new_wo;
895 }
896 else {
897 wo = BKE_world_add(bmain, CTX_DATA_(BLT_I18NCONTEXT_ID_WORLD, "World"));
899 wo->use_nodes = true;
900 }
901
902 /* hook into UI */
904
905 if (prop) {
906 /* when creating new ID blocks, use is already 1, but RNA
907 * pointer use also increases user, so this compensates it */
908 id_us_min(&wo->id);
909
910 if (ptr.owner_id) {
911 BKE_id_move_to_same_lib(*bmain, wo->id, *ptr.owner_id);
912 }
913
914 PointerRNA idptr = RNA_id_pointer_create(&wo->id);
915 RNA_property_pointer_set(&ptr, prop, idptr, nullptr);
916 RNA_property_update(C, &ptr, prop);
917 }
918
920
921 return OPERATOR_FINISHED;
922}
923
925{
926 /* identifiers */
927 ot->name = "New World";
928 ot->idname = "WORLD_OT_new";
929 ot->description = "Create a new world Data-Block";
930
931 /* api callbacks */
932 ot->exec = new_world_exec;
933
934 /* flags */
936}
937
939
940/* -------------------------------------------------------------------- */
943
945{
946 wmWindow *win = CTX_wm_window(C);
947 Scene *scene = CTX_data_scene(C);
948 ViewLayer *view_layer_current = WM_window_get_active_view_layer(win);
949 ViewLayer *view_layer_new = BKE_view_layer_add(
950 scene, view_layer_current->name, view_layer_current, RNA_enum_get(op->ptr, "type"));
951
952 if (win) {
953 WM_window_set_active_view_layer(win, view_layer_new);
954 }
955
959
960 return OPERATOR_FINISHED;
961}
962
964{
965 static EnumPropertyItem type_items[] = {
966 {VIEWLAYER_ADD_NEW, "NEW", 0, "New", "Add a new view layer"},
967 {VIEWLAYER_ADD_COPY, "COPY", 0, "Copy Settings", "Copy settings of current view layer"},
969 "EMPTY",
970 0,
971 "Blank",
972 "Add a new view layer with all collections disabled"},
973 {0, nullptr, 0, nullptr, nullptr},
974 };
975
976 /* identifiers */
977 ot->name = "Add View Layer";
978 ot->idname = "SCENE_OT_view_layer_add";
979 ot->description = "Add a view layer";
980
981 /* api callbacks */
982 ot->exec = view_layer_add_exec;
983 ot->invoke = WM_menu_invoke;
984
985 /* flags */
987
988 /* properties */
989 ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
990}
991
993
994/* -------------------------------------------------------------------- */
997
999{
1000 Scene *scene = CTX_data_scene(C);
1001 return (scene->view_layers.first != scene->view_layers.last);
1002}
1003
1005{
1006 Main *bmain = CTX_data_main(C);
1007 Scene *scene = CTX_data_scene(C);
1008 ViewLayer *view_layer = CTX_data_view_layer(C);
1009
1010 if (!ED_scene_view_layer_delete(bmain, scene, view_layer, nullptr)) {
1011 return OPERATOR_CANCELLED;
1012 }
1013
1015
1016 return OPERATOR_FINISHED;
1017}
1018
1020{
1021 /* identifiers */
1022 ot->name = "Remove View Layer";
1023 ot->idname = "SCENE_OT_view_layer_remove";
1024 ot->description = "Remove the selected view layer";
1025
1026 /* api callbacks */
1027 ot->exec = view_layer_remove_exec;
1028 ot->poll = view_layer_remove_poll;
1029
1030 /* flags */
1032}
1033
1035
1036/* -------------------------------------------------------------------- */
1039
1041{
1042 Scene *scene = CTX_data_scene(C);
1043 ViewLayer *view_layer = CTX_data_view_layer(C);
1044
1045 BKE_view_layer_add_aov(view_layer);
1046
1047 RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
1048 if (engine_type->update_render_passes) {
1049 RenderEngine *engine = RE_engine_create(engine_type);
1050 if (engine) {
1051 BKE_view_layer_verify_aov(engine, scene, view_layer);
1052 }
1053 RE_engine_free(engine);
1054 engine = nullptr;
1055 }
1056
1057 if (scene->nodetree) {
1059 }
1060
1064
1065 return OPERATOR_FINISHED;
1066}
1067
1069{
1070 /* identifiers */
1071 ot->name = "Add AOV";
1072 ot->idname = "SCENE_OT_view_layer_add_aov";
1073 ot->description = "Add a Shader AOV";
1074
1075 /* api callbacks */
1077
1078 /* flags */
1080}
1081
1083
1084/* -------------------------------------------------------------------- */
1087
1089{
1090 Scene *scene = CTX_data_scene(C);
1091 ViewLayer *view_layer = CTX_data_view_layer(C);
1092
1093 if (view_layer->active_aov == nullptr) {
1094 return OPERATOR_FINISHED;
1095 }
1096
1097 BKE_view_layer_remove_aov(view_layer, view_layer->active_aov);
1098
1099 RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
1100 if (engine_type->update_render_passes) {
1101 RenderEngine *engine = RE_engine_create(engine_type);
1102 if (engine) {
1103 BKE_view_layer_verify_aov(engine, scene, view_layer);
1104 }
1105 RE_engine_free(engine);
1106 engine = nullptr;
1107 }
1108
1109 if (scene->nodetree) {
1111 }
1112
1116
1117 return OPERATOR_FINISHED;
1118}
1119
1121{
1122 /* identifiers */
1123 ot->name = "Remove AOV";
1124 ot->idname = "SCENE_OT_view_layer_remove_aov";
1125 ot->description = "Remove Active AOV";
1126
1127 /* api callbacks */
1129
1130 /* flags */
1132}
1133
1135
1136/* -------------------------------------------------------------------- */
1139
1141{
1142 Scene *scene = CTX_data_scene(C);
1143 ViewLayer *view_layer = CTX_data_view_layer(C);
1144
1145 char name[MAX_NAME];
1146 name[0] = '\0';
1147 /* If a name is provided, ensure that it is unique. */
1148 if (RNA_struct_property_is_set(op->ptr, "name")) {
1149 RNA_string_get(op->ptr, "name", name);
1150 /* Ensure that there are no dots in the name. */
1151 BLI_string_replace_char(name, '.', '_');
1152 LISTBASE_FOREACH (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
1153 if (STREQ(lightgroup->name, name)) {
1154 return OPERATOR_CANCELLED;
1155 }
1156 }
1157 }
1158
1159 BKE_view_layer_add_lightgroup(view_layer, name);
1160
1161 if (scene->nodetree) {
1163 }
1164
1168
1169 return OPERATOR_FINISHED;
1170}
1171
1173{
1174 /* identifiers */
1175 ot->name = "Add Lightgroup";
1176 ot->idname = "SCENE_OT_view_layer_add_lightgroup";
1177 ot->description = "Add a Light Group";
1178
1179 /* api callbacks */
1181
1182 /* flags */
1184
1185 /* properties */
1186 ot->prop = RNA_def_string(ot->srna,
1187 "name",
1188 nullptr,
1190 "Name",
1191 "Name of newly created lightgroup");
1192}
1193
1195
1196/* -------------------------------------------------------------------- */
1199
1201{
1202 Scene *scene = CTX_data_scene(C);
1203 ViewLayer *view_layer = CTX_data_view_layer(C);
1204
1205 if (view_layer->active_lightgroup == nullptr) {
1206 return OPERATOR_FINISHED;
1207 }
1208
1209 BKE_view_layer_remove_lightgroup(view_layer, view_layer->active_lightgroup);
1210
1211 if (scene->nodetree) {
1213 }
1214
1218
1219 return OPERATOR_FINISHED;
1220}
1221
1223{
1224 /* identifiers */
1225 ot->name = "Remove Lightgroup";
1226 ot->idname = "SCENE_OT_view_layer_remove_lightgroup";
1227 ot->description = "Remove Active Lightgroup";
1228
1229 /* api callbacks */
1231
1232 /* flags */
1234}
1235
1237
1238/* -------------------------------------------------------------------- */
1241
1243{
1244 GSet *used_lightgroups = BLI_gset_str_new(__func__);
1245
1246 FOREACH_SCENE_OBJECT_BEGIN (scene, ob) {
1247 if (ob->lightgroup && ob->lightgroup->name[0]) {
1248 BLI_gset_add(used_lightgroups, ob->lightgroup->name);
1249 }
1250 }
1252
1253 if (scene->world && scene->world->lightgroup && scene->world->lightgroup->name[0]) {
1254 BLI_gset_add(used_lightgroups, scene->world->lightgroup->name);
1255 }
1256
1257 return used_lightgroups;
1258}
1259
1261{
1262 Scene *scene = CTX_data_scene(C);
1263 ViewLayer *view_layer = CTX_data_view_layer(C);
1264
1265 GSet *used_lightgroups = get_used_lightgroups(scene);
1266 GSET_FOREACH_BEGIN (const char *, used_lightgroup, used_lightgroups) {
1267 if (!BLI_findstring(
1268 &view_layer->lightgroups, used_lightgroup, offsetof(ViewLayerLightgroup, name)))
1269 {
1270 BKE_view_layer_add_lightgroup(view_layer, used_lightgroup);
1271 }
1272 }
1274 BLI_gset_free(used_lightgroups, nullptr);
1275
1276 if (scene->nodetree) {
1278 }
1279
1283
1284 return OPERATOR_FINISHED;
1285}
1286
1288{
1289 /* identifiers */
1290 ot->name = "Add Used Lightgroups";
1291 ot->idname = "SCENE_OT_view_layer_add_used_lightgroups";
1292 ot->description = "Add all used Light Groups";
1293
1294 /* api callbacks */
1296
1297 /* flags */
1299}
1300
1302
1303/* -------------------------------------------------------------------- */
1306
1308{
1309 Scene *scene = CTX_data_scene(C);
1310 ViewLayer *view_layer = CTX_data_view_layer(C);
1311
1312 GSet *used_lightgroups = get_used_lightgroups(scene);
1313 LISTBASE_FOREACH_MUTABLE (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
1314 if (!BLI_gset_haskey(used_lightgroups, lightgroup->name)) {
1315 BKE_view_layer_remove_lightgroup(view_layer, lightgroup);
1316 }
1317 }
1318 BLI_gset_free(used_lightgroups, nullptr);
1319
1320 if (scene->nodetree) {
1322 }
1323
1327
1328 return OPERATOR_FINISHED;
1329}
1330
1332{
1333 /* identifiers */
1334 ot->name = "Remove Unused Lightgroups";
1335 ot->idname = "SCENE_OT_view_layer_remove_unused_lightgroups";
1336 ot->description = "Remove all unused Light Groups";
1337
1338 /* api callbacks */
1340
1341 /* flags */
1343}
1344
1346
1347/* -------------------------------------------------------------------- */
1350
1351enum {
1355};
1356
1358 wmOperator *op)
1359{
1360 ViewLayer *view_layer = CTX_data_view_layer(C);
1361 Scene *scene = CTX_data_scene(C);
1362
1363 auto is_irradiance_volume = [](Object *ob) -> bool {
1364 return ob->type == OB_LIGHTPROBE &&
1365 static_cast<LightProbe *>(ob->data)->type == LIGHTPROBE_TYPE_VOLUME;
1366 };
1367
1369
1370 auto irradiance_volume_setup = [&](Object *ob) {
1374 probes.append(ob);
1375 };
1376
1377 int subset = RNA_enum_get(op->ptr, "subset");
1378 switch (subset) {
1379 case LIGHTCACHE_SUBSET_ALL: {
1380 FOREACH_OBJECT_BEGIN (scene, view_layer, ob) {
1381 if (is_irradiance_volume(ob)) {
1382 irradiance_volume_setup(ob);
1383 }
1384 }
1386 break;
1387 }
1389 ObjectsInViewLayerParams parameters;
1390 parameters.filter_fn = nullptr;
1391 parameters.no_dup_data = true;
1393 view_layer, nullptr, &parameters);
1394 for (Object *ob : objects) {
1395 if (is_irradiance_volume(ob)) {
1396 irradiance_volume_setup(ob);
1397 }
1398 }
1399 break;
1400 }
1402 Object *active_ob = CTX_data_active_object(C);
1403 if (is_irradiance_volume(active_ob)) {
1404 irradiance_volume_setup(active_ob);
1405 }
1406 break;
1407 }
1408 default:
1410 break;
1411 }
1412
1413 return probes;
1414}
1415
1417 /* Store actual owner of job, so modal operator could check for it,
1418 * the reason of this is that active scene could change when rendering
1419 * several layers from compositor #31800. */
1421
1422 std::string report;
1423};
1424
1425static int lightprobe_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
1426{
1428 wmWindow *win = CTX_wm_window(C);
1429 ViewLayer *view_layer = CTX_data_view_layer(C);
1430 Main *bmain = CTX_data_main(C);
1431 Scene *scene = CTX_data_scene(C);
1432
1434
1435 if (probes.is_empty()) {
1436 return OPERATOR_CANCELLED;
1437 }
1438
1439 BakeOperatorData *data = MEM_new<BakeOperatorData>(__func__);
1440 data->scene = scene;
1441 data->report = "";
1442
1444 wm, win, bmain, view_layer, scene, probes, data->report, scene->r.cfra, 0);
1445
1447
1448 op->customdata = static_cast<void *>(data);
1449
1450 WM_jobs_start(wm, wm_job);
1451
1452 WM_cursor_wait(false);
1453
1455}
1456
1458{
1459 BakeOperatorData *data = static_cast<BakeOperatorData *>(op->customdata);
1460 Scene *scene = data->scene;
1461
1462 /* No running bake, remove handler and pass through. */
1464 std::string report = data->report;
1465
1466 MEM_delete(data);
1467 op->customdata = nullptr;
1468
1469 if (!report.empty()) {
1470 BKE_report(op->reports, RPT_ERROR, report.c_str());
1471 return OPERATOR_CANCELLED;
1472 }
1474 }
1475
1476 /* Running bake. */
1477 switch (event->type) {
1478 case EVT_ESCKEY:
1480 }
1481 return OPERATOR_PASS_THROUGH;
1482}
1483
1485{
1487 Scene *scene = static_cast<BakeOperatorData *>(op->customdata)->scene;
1488
1489 /* Kill on cancel, because job is using op->reports. */
1491}
1492
1493/* Executes blocking bake. */
1495{
1496 ViewLayer *view_layer = CTX_data_view_layer(C);
1497 Main *bmain = CTX_data_main(C);
1498 Scene *scene = CTX_data_scene(C);
1499
1500 G.is_break = false;
1501
1503
1504 std::string report;
1506 bmain, view_layer, scene, probes, report, scene->r.cfra);
1507 /* Do the job. */
1508 wmJobWorkerStatus worker_status = {};
1509 EEVEE_NEXT_lightbake_job(rj, &worker_status);
1510 /* Move baking data to original object and then free it. */
1513
1514 if (!report.empty()) {
1515 BKE_report(op->reports, RPT_ERROR, report.c_str());
1516 return OPERATOR_CANCELLED;
1517 }
1518
1519 return OPERATOR_FINISHED;
1520}
1521
1523{
1524 static const EnumPropertyItem light_cache_subset_items[] = {
1525 {LIGHTCACHE_SUBSET_ALL, "ALL", 0, "All Volumes", "Bake all light probe volumes"},
1527 "SELECTED",
1528 0,
1529 "Selected Only",
1530 "Only bake selected light probe volumes"},
1532 "ACTIVE",
1533 0,
1534 "Active Only",
1535 "Only bake the active light probe volume"},
1536 {0, nullptr, 0, nullptr, nullptr},
1537 };
1538
1539 /* identifiers */
1540 ot->name = "Bake Light Cache";
1541 ot->idname = "OBJECT_OT_lightprobe_cache_bake";
1542 ot->description = "Bake irradiance volume light cache";
1543
1544 /* api callbacks */
1549
1550 ot->prop = RNA_def_enum(
1551 ot->srna, "subset", light_cache_subset_items, 0, "Subset", "Subset of probes to update");
1553}
1554
1556
1557/* -------------------------------------------------------------------- */
1560
1562{
1563 Scene *scene = CTX_data_scene(C);
1564
1565 /* Kill potential bake job first (see #57011). */
1568
1570
1571 for (Object *object : probes) {
1572 if (object->lightprobe_cache == nullptr) {
1573 continue;
1574 }
1577 }
1578
1580
1581 return OPERATOR_FINISHED;
1582}
1583
1585{
1586 static const EnumPropertyItem lightprobe_subset_items[] = {
1588 "ALL",
1589 0,
1590 "All Light Probes",
1591 "Delete all light probes' baked lighting data"},
1593 "SELECTED",
1594 0,
1595 "Selected Only",
1596 "Only delete selected light probes' baked lighting data"},
1598 "ACTIVE",
1599 0,
1600 "Active Only",
1601 "Only delete the active light probe's baked lighting data"},
1602 {0, nullptr, 0, nullptr, nullptr},
1603 };
1604
1605 /* identifiers */
1606 ot->name = "Delete Light Cache";
1607 ot->idname = "OBJECT_OT_lightprobe_cache_free";
1608 ot->description = "Delete cached indirect lighting";
1609 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1610
1611 /* api callbacks */
1613
1614 ot->prop = RNA_def_enum(ot->srna,
1615 "subset",
1616 lightprobe_subset_items,
1618 "Subset",
1619 "Subset of probes to update");
1620}
1621
1623
1624/* -------------------------------------------------------------------- */
1627
1629{
1630 Scene *scene = CTX_data_scene(C);
1631
1632 /* don't allow user to remove "left" and "right" views */
1633 return scene->r.actview > 1;
1634}
1635
1637{
1638 Main *bmain = CTX_data_main(C);
1639 Scene *scene = CTX_data_scene(C);
1640
1641 BKE_scene_add_render_view(scene, nullptr);
1642 scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
1643
1645
1646 BKE_ntree_update_tag_id_changed(bmain, &scene->id);
1647 ED_node_tree_propagate_change(C, bmain, nullptr);
1648
1649 return OPERATOR_FINISHED;
1650}
1651
1653{
1654 /* identifiers */
1655 ot->name = "Add Render View";
1656 ot->idname = "SCENE_OT_render_view_add";
1657 ot->description = "Add a render view";
1658
1659 /* api callbacks */
1660 ot->exec = render_view_add_exec;
1661
1662 /* flags */
1663 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1664}
1665
1667
1668/* -------------------------------------------------------------------- */
1671
1673{
1674 Main *bmain = CTX_data_main(C);
1675 Scene *scene = CTX_data_scene(C);
1676 SceneRenderView *rv = static_cast<SceneRenderView *>(
1677 BLI_findlink(&scene->r.views, scene->r.actview));
1678
1679 if (!BKE_scene_remove_render_view(scene, rv)) {
1680 return OPERATOR_CANCELLED;
1681 }
1682
1684
1685 BKE_ntree_update_tag_id_changed(bmain, &scene->id);
1686 ED_node_tree_propagate_change(C, bmain, nullptr);
1687
1688 return OPERATOR_FINISHED;
1689}
1690
1692{
1693 /* identifiers */
1694 ot->name = "Remove Render View";
1695 ot->idname = "SCENE_OT_render_view_remove";
1696 ot->description = "Remove the selected render view";
1697
1698 /* api callbacks */
1701
1702 /* flags */
1703 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1704}
1705
1707
1708#ifdef WITH_FREESTYLE
1709
1710/* -------------------------------------------------------------------- */
1713
1714static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)
1715{
1716 if (!lineset) {
1717 BKE_report(reports,
1718 RPT_ERROR,
1719 "No active lineset and associated line style to manipulate the modifier");
1720 return false;
1721 }
1722 if (!lineset->linestyle) {
1723 BKE_report(reports,
1724 RPT_ERROR,
1725 "The active lineset does not have a line style (indicating data corruption)");
1726 return false;
1727 }
1728
1729 return true;
1730}
1731
1732static bool freestyle_active_module_poll(bContext *C)
1733{
1734 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1735 FreestyleModuleConfig *module = static_cast<FreestyleModuleConfig *>(ptr.data);
1736
1737 return module != nullptr;
1738}
1739
1740static int freestyle_module_add_exec(bContext *C, wmOperator * /*op*/)
1741{
1742 Scene *scene = CTX_data_scene(C);
1743 ViewLayer *view_layer = CTX_data_view_layer(C);
1744
1746
1748
1749 return OPERATOR_FINISHED;
1750}
1751
1752void SCENE_OT_freestyle_module_add(wmOperatorType *ot)
1753{
1754 /* identifiers */
1755 ot->name = "Add Freestyle Module";
1756 ot->idname = "SCENE_OT_freestyle_module_add";
1757 ot->description = "Add a style module into the list of modules";
1758
1759 /* api callbacks */
1760 ot->exec = freestyle_module_add_exec;
1761
1762 /* flags */
1764}
1765
1767
1768/* -------------------------------------------------------------------- */
1771
1772static int freestyle_module_remove_exec(bContext *C, wmOperator * /*op*/)
1773{
1774 Scene *scene = CTX_data_scene(C);
1775 ViewLayer *view_layer = CTX_data_view_layer(C);
1776 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1777 FreestyleModuleConfig *module = static_cast<FreestyleModuleConfig *>(ptr.data);
1778
1780
1783
1784 return OPERATOR_FINISHED;
1785}
1786
1787void SCENE_OT_freestyle_module_remove(wmOperatorType *ot)
1788{
1789 /* identifiers */
1790 ot->name = "Remove Freestyle Module";
1791 ot->idname = "SCENE_OT_freestyle_module_remove";
1792 ot->description = "Remove the style module from the stack";
1793
1794 /* api callbacks */
1795 ot->poll = freestyle_active_module_poll;
1796 ot->exec = freestyle_module_remove_exec;
1797
1798 /* flags */
1800}
1801
1802static int freestyle_module_move_exec(bContext *C, wmOperator *op)
1803{
1804 Scene *scene = CTX_data_scene(C);
1805 ViewLayer *view_layer = CTX_data_view_layer(C);
1806 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1807 FreestyleModuleConfig *module = static_cast<FreestyleModuleConfig *>(ptr.data);
1808 int dir = RNA_enum_get(op->ptr, "direction");
1809
1810 if (BKE_freestyle_module_move(&view_layer->freestyle_config, module, dir)) {
1813 }
1814
1815 return OPERATOR_FINISHED;
1816}
1817
1819
1820/* -------------------------------------------------------------------- */
1823
1824void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
1825{
1826 static const EnumPropertyItem direction_items[] = {
1827 {-1, "UP", 0, "Up", ""},
1828 {1, "DOWN", 0, "Down", ""},
1829 {0, nullptr, 0, nullptr, nullptr},
1830 };
1831
1832 /* identifiers */
1833 ot->name = "Move Freestyle Module";
1834 ot->idname = "SCENE_OT_freestyle_module_move";
1835 ot->description = "Change the position of the style module within in the list of style modules";
1836
1837 /* api callbacks */
1838 ot->poll = freestyle_active_module_poll;
1839 ot->exec = freestyle_module_move_exec;
1840
1841 /* flags */
1843
1844 /* props */
1845 RNA_def_enum(ot->srna,
1846 "direction",
1847 direction_items,
1848 0,
1849 "Direction",
1850 "Direction to move the chosen style module towards");
1851}
1852
1854
1855/* -------------------------------------------------------------------- */
1858
1859static int freestyle_lineset_add_exec(bContext *C, wmOperator * /*op*/)
1860{
1861 Main *bmain = CTX_data_main(C);
1862 Scene *scene = CTX_data_scene(C);
1863 ViewLayer *view_layer = CTX_data_view_layer(C);
1864
1865 BKE_freestyle_lineset_add(bmain, &view_layer->freestyle_config, nullptr);
1866
1869
1870 return OPERATOR_FINISHED;
1871}
1872
1873void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot)
1874{
1875 /* identifiers */
1876 ot->name = "Add Line Set";
1877 ot->idname = "SCENE_OT_freestyle_lineset_add";
1878 ot->description = "Add a line set into the list of line sets";
1879
1880 /* api callbacks */
1881 ot->exec = freestyle_lineset_add_exec;
1882
1883 /* flags */
1885}
1886
1888
1889/* -------------------------------------------------------------------- */
1892
1893static bool freestyle_active_lineset_poll(bContext *C)
1894{
1895 ViewLayer *view_layer = CTX_data_view_layer(C);
1896
1897 if (!view_layer) {
1898 return false;
1899 }
1900
1901 return BKE_freestyle_lineset_get_active(&view_layer->freestyle_config) != nullptr;
1902}
1903
1904static int freestyle_lineset_copy_exec(bContext *C, wmOperator * /*op*/)
1905{
1906 ViewLayer *view_layer = CTX_data_view_layer(C);
1907
1909
1910 return OPERATOR_FINISHED;
1911}
1912
1913void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot)
1914{
1915 /* identifiers */
1916 ot->name = "Copy Line Set";
1917 ot->idname = "SCENE_OT_freestyle_lineset_copy";
1918 ot->description = "Copy the active line set to the internal clipboard";
1919
1920 /* api callbacks */
1921 ot->exec = freestyle_lineset_copy_exec;
1922 ot->poll = freestyle_active_lineset_poll;
1923
1924 /* flags */
1926}
1927
1929
1930/* -------------------------------------------------------------------- */
1933
1934static int freestyle_lineset_paste_exec(bContext *C, wmOperator * /*op*/)
1935{
1936 Scene *scene = CTX_data_scene(C);
1937 ViewLayer *view_layer = CTX_data_view_layer(C);
1938
1940
1943
1944 return OPERATOR_FINISHED;
1945}
1946
1947void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot)
1948{
1949 /* identifiers */
1950 ot->name = "Paste Line Set";
1951 ot->idname = "SCENE_OT_freestyle_lineset_paste";
1952 ot->description = "Paste the internal clipboard content to the active line set";
1953
1954 /* api callbacks */
1955 ot->exec = freestyle_lineset_paste_exec;
1956 ot->poll = freestyle_active_lineset_poll;
1957
1958 /* flags */
1960}
1961
1963
1964/* -------------------------------------------------------------------- */
1967
1968static int freestyle_lineset_remove_exec(bContext *C, wmOperator * /*op*/)
1969{
1970 Scene *scene = CTX_data_scene(C);
1971 ViewLayer *view_layer = CTX_data_view_layer(C);
1972
1974
1977
1978 return OPERATOR_FINISHED;
1979}
1980
1981void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot)
1982{
1983 /* identifiers */
1984 ot->name = "Remove Line Set";
1985 ot->idname = "SCENE_OT_freestyle_lineset_remove";
1986 ot->description = "Remove the active line set from the list of line sets";
1987
1988 /* api callbacks */
1989 ot->exec = freestyle_lineset_remove_exec;
1990 ot->poll = freestyle_active_lineset_poll;
1991
1992 /* flags */
1994}
1995
1997
1998/* -------------------------------------------------------------------- */
2001
2002static int freestyle_lineset_move_exec(bContext *C, wmOperator *op)
2003{
2004 Scene *scene = CTX_data_scene(C);
2005 ViewLayer *view_layer = CTX_data_view_layer(C);
2006 int dir = RNA_enum_get(op->ptr, "direction");
2007
2008 if (FRS_move_active_lineset(&view_layer->freestyle_config, dir)) {
2011 }
2012
2013 return OPERATOR_FINISHED;
2014}
2015
2016void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot)
2017{
2018 static const EnumPropertyItem direction_items[] = {
2019 {-1, "UP", 0, "Up", ""},
2020 {1, "DOWN", 0, "Down", ""},
2021 {0, nullptr, 0, nullptr, nullptr},
2022 };
2023
2024 /* identifiers */
2025 ot->name = "Move Line Set";
2026 ot->idname = "SCENE_OT_freestyle_lineset_move";
2027 ot->description = "Change the position of the active line set within the list of line sets";
2028
2029 /* api callbacks */
2030 ot->exec = freestyle_lineset_move_exec;
2031 ot->poll = freestyle_active_lineset_poll;
2032
2033 /* flags */
2035
2036 /* props */
2037 RNA_def_enum(ot->srna,
2038 "direction",
2039 direction_items,
2040 0,
2041 "Direction",
2042 "Direction to move the active line set towards");
2043}
2044
2046
2047/* -------------------------------------------------------------------- */
2050
2051static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
2052{
2053 Main *bmain = CTX_data_main(C);
2054 ViewLayer *view_layer = CTX_data_view_layer(C);
2056
2057 if (!lineset) {
2058 BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
2059 return OPERATOR_CANCELLED;
2060 }
2061 if (lineset->linestyle) {
2062 id_us_min(&lineset->linestyle->id);
2063 lineset->linestyle = (FreestyleLineStyle *)BKE_id_copy(bmain, &lineset->linestyle->id);
2064 }
2065 else {
2066 lineset->linestyle = BKE_linestyle_new(bmain, DATA_("LineStyle"));
2067 }
2068 DEG_id_tag_update(&lineset->linestyle->id, 0);
2070
2071 return OPERATOR_FINISHED;
2072}
2073
2074void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot)
2075{
2076 /* identifiers */
2077 ot->name = "New Line Style";
2078 ot->idname = "SCENE_OT_freestyle_linestyle_new";
2079 ot->description = "Create a new line style, reusable by multiple line sets";
2080
2081 /* api callbacks */
2082 ot->exec = freestyle_linestyle_new_exec;
2083 ot->poll = freestyle_active_lineset_poll;
2084
2085 /* flags */
2087}
2088
2090
2091/* -------------------------------------------------------------------- */
2094
2095static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op)
2096{
2097 ViewLayer *view_layer = CTX_data_view_layer(C);
2099 int type = RNA_enum_get(op->ptr, "type");
2100
2101 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2102 return OPERATOR_CANCELLED;
2103 }
2104
2105 if (BKE_linestyle_color_modifier_add(lineset->linestyle, nullptr, type) == nullptr) {
2106 BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type");
2107 return OPERATOR_CANCELLED;
2108 }
2109 DEG_id_tag_update(&lineset->linestyle->id, 0);
2111
2112 return OPERATOR_FINISHED;
2113}
2114
2115void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot)
2116{
2117 /* identifiers */
2118 ot->name = "Add Line Color Modifier";
2119 ot->idname = "SCENE_OT_freestyle_color_modifier_add";
2120 ot->description =
2121 "Add a line color modifier to the line style associated with the active lineset";
2122
2123 /* api callbacks */
2124 ot->invoke = WM_menu_invoke;
2125 ot->exec = freestyle_color_modifier_add_exec;
2126 ot->poll = freestyle_active_lineset_poll;
2127
2128 /* flags */
2130
2131 /* properties */
2132 ot->prop = RNA_def_enum(
2133 ot->srna, "type", rna_enum_linestyle_color_modifier_type_items, 0, "Type", "");
2134}
2135
2137
2138/* -------------------------------------------------------------------- */
2141
2142static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op)
2143{
2144 ViewLayer *view_layer = CTX_data_view_layer(C);
2146 int type = RNA_enum_get(op->ptr, "type");
2147
2148 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2149 return OPERATOR_CANCELLED;
2150 }
2151
2152 if (BKE_linestyle_alpha_modifier_add(lineset->linestyle, nullptr, type) == nullptr) {
2153 BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
2154 return OPERATOR_CANCELLED;
2155 }
2156 DEG_id_tag_update(&lineset->linestyle->id, 0);
2158
2159 return OPERATOR_FINISHED;
2160}
2161
2162void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot)
2163{
2164 /* identifiers */
2165 ot->name = "Add Alpha Transparency Modifier";
2166 ot->idname = "SCENE_OT_freestyle_alpha_modifier_add";
2167 ot->description =
2168 "Add an alpha transparency modifier to the line style associated with the active lineset";
2169
2170 /* api callbacks */
2171 ot->invoke = WM_menu_invoke;
2172 ot->exec = freestyle_alpha_modifier_add_exec;
2173 ot->poll = freestyle_active_lineset_poll;
2174
2175 /* flags */
2177
2178 /* properties */
2179 ot->prop = RNA_def_enum(
2180 ot->srna, "type", rna_enum_linestyle_alpha_modifier_type_items, 0, "Type", "");
2181}
2182
2184
2185/* -------------------------------------------------------------------- */
2188
2189static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op)
2190{
2191 ViewLayer *view_layer = CTX_data_view_layer(C);
2193 int type = RNA_enum_get(op->ptr, "type");
2194
2195 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2196 return OPERATOR_CANCELLED;
2197 }
2198
2199 if (BKE_linestyle_thickness_modifier_add(lineset->linestyle, nullptr, type) == nullptr) {
2200 BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
2201 return OPERATOR_CANCELLED;
2202 }
2203 DEG_id_tag_update(&lineset->linestyle->id, 0);
2205
2206 return OPERATOR_FINISHED;
2207}
2208
2209void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot)
2210{
2211 /* identifiers */
2212 ot->name = "Add Line Thickness Modifier";
2213 ot->idname = "SCENE_OT_freestyle_thickness_modifier_add";
2214 ot->description =
2215 "Add a line thickness modifier to the line style associated with the active lineset";
2216
2217 /* api callbacks */
2218 ot->invoke = WM_menu_invoke;
2219 ot->exec = freestyle_thickness_modifier_add_exec;
2220 ot->poll = freestyle_active_lineset_poll;
2221
2222 /* flags */
2224
2225 /* properties */
2226 ot->prop = RNA_def_enum(
2227 ot->srna, "type", rna_enum_linestyle_thickness_modifier_type_items, 0, "Type", "");
2228}
2229
2231
2232/* -------------------------------------------------------------------- */
2235
2236static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op)
2237{
2238 ViewLayer *view_layer = CTX_data_view_layer(C);
2240 int type = RNA_enum_get(op->ptr, "type");
2241
2242 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2243 return OPERATOR_CANCELLED;
2244 }
2245
2246 if (BKE_linestyle_geometry_modifier_add(lineset->linestyle, nullptr, type) == nullptr) {
2247 BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
2248 return OPERATOR_CANCELLED;
2249 }
2250 DEG_id_tag_update(&lineset->linestyle->id, 0);
2252
2253 return OPERATOR_FINISHED;
2254}
2255
2256void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot)
2257{
2258 /* identifiers */
2259 ot->name = "Add Stroke Geometry Modifier";
2260 ot->idname = "SCENE_OT_freestyle_geometry_modifier_add";
2261 ot->description =
2262 "Add a stroke geometry modifier to the line style associated with the active lineset";
2263
2264 /* api callbacks */
2265 ot->invoke = WM_menu_invoke;
2266 ot->exec = freestyle_geometry_modifier_add_exec;
2267 ot->poll = freestyle_active_lineset_poll;
2268
2269 /* flags */
2271
2272 /* properties */
2273 ot->prop = RNA_def_enum(
2274 ot->srna, "type", rna_enum_linestyle_geometry_modifier_type_items, 0, "Type", "");
2275}
2276
2278
2279/* -------------------------------------------------------------------- */
2282
2283static int freestyle_get_modifier_type(PointerRNA *ptr)
2284{
2285 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier)) {
2287 }
2288 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier)) {
2290 }
2291 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier)) {
2293 }
2294 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier)) {
2296 }
2297 return -1;
2298}
2299
2300static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op)
2301{
2302 ViewLayer *view_layer = CTX_data_view_layer(C);
2304 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
2305 LineStyleModifier *modifier = static_cast<LineStyleModifier *>(ptr.data);
2306
2307 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2308 return OPERATOR_CANCELLED;
2309 }
2310
2311 switch (freestyle_get_modifier_type(&ptr)) {
2314 break;
2317 break;
2320 break;
2323 break;
2324 default:
2325 BKE_report(
2326 op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
2327 return OPERATOR_CANCELLED;
2328 }
2329 DEG_id_tag_update(&lineset->linestyle->id, 0);
2331
2332 return OPERATOR_FINISHED;
2333}
2334
2335void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot)
2336{
2337 /* identifiers */
2338 ot->name = "Remove Modifier";
2339 ot->idname = "SCENE_OT_freestyle_modifier_remove";
2340 ot->description = "Remove the modifier from the list of modifiers";
2341
2342 /* api callbacks */
2343 ot->exec = freestyle_modifier_remove_exec;
2344 ot->poll = freestyle_active_lineset_poll;
2345
2346 /* flags */
2348}
2349
2351
2352/* -------------------------------------------------------------------- */
2355
2356static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
2357{
2358 ViewLayer *view_layer = CTX_data_view_layer(C);
2360 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
2361 LineStyleModifier *modifier = static_cast<LineStyleModifier *>(ptr.data);
2362
2363 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2364 return OPERATOR_CANCELLED;
2365 }
2366
2367 switch (freestyle_get_modifier_type(&ptr)) {
2369 BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
2370 break;
2372 BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
2373 break;
2375 BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
2376 break;
2378 BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
2379 break;
2380 default:
2381 BKE_report(
2382 op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
2383 return OPERATOR_CANCELLED;
2384 }
2385 DEG_id_tag_update(&lineset->linestyle->id, 0);
2387
2388 return OPERATOR_FINISHED;
2389}
2390
2391void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot)
2392{
2393 /* identifiers */
2394 ot->name = "Copy Modifier";
2395 ot->idname = "SCENE_OT_freestyle_modifier_copy";
2396 ot->description = "Duplicate the modifier within the list of modifiers";
2397
2398 /* api callbacks */
2399 ot->exec = freestyle_modifier_copy_exec;
2400 ot->poll = freestyle_active_lineset_poll;
2401
2402 /* flags */
2404}
2405
2407
2408/* -------------------------------------------------------------------- */
2411
2412static int freestyle_modifier_move_exec(bContext *C, wmOperator *op)
2413{
2414 ViewLayer *view_layer = CTX_data_view_layer(C);
2416 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
2417 LineStyleModifier *modifier = static_cast<LineStyleModifier *>(ptr.data);
2418 int dir = RNA_enum_get(op->ptr, "direction");
2419 bool changed = false;
2420
2421 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2422 return OPERATOR_CANCELLED;
2423 }
2424
2425 switch (freestyle_get_modifier_type(&ptr)) {
2427 changed = BKE_linestyle_color_modifier_move(lineset->linestyle, modifier, dir);
2428 break;
2430 changed = BKE_linestyle_alpha_modifier_move(lineset->linestyle, modifier, dir);
2431 break;
2433 changed = BKE_linestyle_thickness_modifier_move(lineset->linestyle, modifier, dir);
2434 break;
2436 changed = BKE_linestyle_geometry_modifier_move(lineset->linestyle, modifier, dir);
2437 break;
2438 default:
2439 BKE_report(
2440 op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
2441 return OPERATOR_CANCELLED;
2442 }
2443
2444 if (changed) {
2445 DEG_id_tag_update(&lineset->linestyle->id, 0);
2447 }
2448
2449 return OPERATOR_FINISHED;
2450}
2451
2452void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot)
2453{
2454 static const EnumPropertyItem direction_items[] = {
2455 {-1, "UP", 0, "Up", ""},
2456 {1, "DOWN", 0, "Down", ""},
2457 {0, nullptr, 0, nullptr, nullptr},
2458 };
2459
2460 /* identifiers */
2461 ot->name = "Move Modifier";
2462 ot->idname = "SCENE_OT_freestyle_modifier_move";
2463 ot->description = "Move the modifier within the list of modifiers";
2464
2465 /* api callbacks */
2466 ot->exec = freestyle_modifier_move_exec;
2467 ot->poll = freestyle_active_lineset_poll;
2468
2469 /* flags */
2471
2472 /* props */
2473 RNA_def_enum(ot->srna,
2474 "direction",
2475 direction_items,
2476 0,
2477 "Direction",
2478 "Direction to move the chosen modifier towards");
2479}
2480
2482
2483/* -------------------------------------------------------------------- */
2486
2487static int freestyle_stroke_material_create_exec(bContext *C, wmOperator *op)
2488{
2489 Main *bmain = CTX_data_main(C);
2490 ViewLayer *view_layer = CTX_data_view_layer(C);
2492
2493 if (!linestyle) {
2494 BKE_report(op->reports, RPT_ERROR, "No active line style in the current scene");
2495 return OPERATOR_CANCELLED;
2496 }
2497
2498 FRS_create_stroke_material(bmain, linestyle);
2499
2500 return OPERATOR_FINISHED;
2501}
2502
2503void SCENE_OT_freestyle_stroke_material_create(wmOperatorType *ot)
2504{
2505 /* identifiers */
2506 ot->name = "Create Freestyle Stroke Material";
2507 ot->idname = "SCENE_OT_freestyle_stroke_material_create";
2508 ot->description = "Create Freestyle stroke material for testing";
2509
2510 /* api callbacks */
2511 ot->exec = freestyle_stroke_material_create_exec;
2512
2513 /* flags */
2514 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2515}
2516
2518
2519#endif /* WITH_FREESTYLE */
2520
2521/* -------------------------------------------------------------------- */
2524
2526{
2527 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
2528
2529 if (id) {
2530 MTex **mtex_ar, *mtexswap;
2531 short act;
2532 int type = RNA_enum_get(op->ptr, "type");
2533 AnimData *adt = BKE_animdata_from_id(id);
2534
2535 give_active_mtex(id, &mtex_ar, &act);
2536
2537 if (type == -1) { /* Up */
2538 if (act > 0) {
2539 mtexswap = mtex_ar[act];
2540 mtex_ar[act] = mtex_ar[act - 1];
2541 mtex_ar[act - 1] = mtexswap;
2542
2544 id, adt, nullptr, "texture_slots", nullptr, nullptr, act - 1, -1, false);
2546 id, adt, nullptr, "texture_slots", nullptr, nullptr, act, act - 1, false);
2548 id, adt, nullptr, "texture_slots", nullptr, nullptr, -1, act, false);
2549
2550 set_active_mtex(id, act - 1);
2551 }
2552 }
2553 else { /* Down */
2554 if (act < MAX_MTEX - 1) {
2555 mtexswap = mtex_ar[act];
2556 mtex_ar[act] = mtex_ar[act + 1];
2557 mtex_ar[act + 1] = mtexswap;
2558
2560 id, adt, nullptr, "texture_slots", nullptr, nullptr, act + 1, -1, false);
2562 id, adt, nullptr, "texture_slots", nullptr, nullptr, act, act + 1, false);
2564 id, adt, nullptr, "texture_slots", nullptr, nullptr, -1, act, false);
2565
2566 set_active_mtex(id, act + 1);
2567 }
2568 }
2569
2570 DEG_id_tag_update(id, 0);
2572 }
2573
2574 return OPERATOR_FINISHED;
2575}
2576
2578{
2579 static const EnumPropertyItem slot_move[] = {
2580 {-1, "UP", 0, "Up", ""},
2581 {1, "DOWN", 0, "Down", ""},
2582 {0, nullptr, 0, nullptr, nullptr},
2583 };
2584
2585 /* identifiers */
2586 ot->name = "Move Texture Slot";
2587 ot->idname = "TEXTURE_OT_slot_move";
2588 ot->description = "Move texture slots up and down";
2589
2590 /* api callbacks */
2591 ot->exec = texture_slot_move_exec;
2592
2593 /* flags */
2595
2596 RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
2597}
2598
2600
2601/* -------------------------------------------------------------------- */
2604
2606{
2607 using namespace blender::bke::blendfile;
2608
2609 Material *ma = static_cast<Material *>(
2610 CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
2611
2612 if (ma == nullptr) {
2613 return OPERATOR_CANCELLED;
2614 }
2615
2616 Main *bmain = CTX_data_main(C);
2618
2619 /* Add the material to the copybuffer (and all of its dependencies). */
2620 copybuffer.id_add(&ma->id,
2621 PartialWriteContext::IDAddOptions{PartialWriteContext::IDAddOperations(
2622 PartialWriteContext::IDAddOperations::SET_FAKE_USER |
2623 PartialWriteContext::IDAddOperations::SET_CLIPBOARD_MARK |
2624 PartialWriteContext::IDAddOperations::ADD_DEPENDENCIES)},
2625 nullptr);
2626
2627 char filepath[FILE_MAX];
2628 material_copybuffer_filepath_get(filepath, sizeof(filepath));
2629 copybuffer.write(filepath, *op->reports);
2630
2631 /* We are all done! */
2632 BKE_report(op->reports, RPT_INFO, "Copied material to internal clipboard");
2633
2634 return OPERATOR_FINISHED;
2635}
2636
2638{
2639 /* identifiers */
2640 ot->name = "Copy Material";
2641 ot->idname = "MATERIAL_OT_copy";
2642 ot->description = "Copy the material settings and nodes";
2643
2644 /* api callbacks */
2645 ot->exec = copy_material_exec;
2646
2647 /* flags */
2648 /* no undo needed since no changes are made to the material */
2650}
2651
2653
2654/* -------------------------------------------------------------------- */
2657
2662{
2663 if (cb_data->cb_flag & IDWALK_CB_USER) {
2664 id_us_min(*cb_data->id_pointer);
2665 }
2666 *cb_data->id_pointer = nullptr;
2667 return IDWALK_RET_NOP;
2668}
2669
2674{
2675 Main *bmain = static_cast<Main *>(cb_data->user_data);
2676 ID **id_p = cb_data->id_pointer;
2677 if (*id_p) {
2678 if (cb_data->cb_flag & IDWALK_CB_USER) {
2679 id_us_min(*id_p);
2680 }
2681 ListBase *lb = which_libbase(bmain, GS((*id_p)->name));
2682 ID *id_local = static_cast<ID *>(
2683 BLI_findstring(lb, (*id_p)->name + 2, offsetof(ID, name) + 2));
2684 *id_p = id_local;
2685 if (cb_data->cb_flag & IDWALK_CB_USER) {
2686 id_us_plus(id_local);
2687 }
2688 else if (cb_data->cb_flag & IDWALK_CB_USER_ONE) {
2689 id_us_ensure_real(id_local);
2690 }
2691 id_lib_extern(id_local);
2692 }
2693 return IDWALK_RET_NOP;
2694}
2695
2697{
2698 Main *bmain = CTX_data_main(C);
2699 Material *ma = static_cast<Material *>(
2700 CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
2701
2702 if (ma == nullptr) {
2703 BKE_report(op->reports, RPT_WARNING, "Cannot paste without a material");
2704 return OPERATOR_CANCELLED;
2705 }
2706
2707 /* Read copy buffer .blend file. */
2708 char filepath[FILE_MAX];
2709 Main *temp_bmain = BKE_main_new();
2710
2712
2713 material_copybuffer_filepath_get(filepath, sizeof(filepath));
2714
2715 /* NOTE(@ideasman42) The node tree might reference different kinds of ID types.
2716 * It's not clear-cut which ID types should be included, although it's unlikely
2717 * users would want an entire scene & it's objects to be included.
2718 * Filter a subset of ID types with some reasons for including them. */
2719 const uint64_t ntree_filter = (
2720 /* Material is necessary for reading the clipboard. */
2721 FILTER_ID_MA |
2722 /* Node-groups. */
2723 FILTER_ID_NT |
2724 /* Image textures. */
2725 FILTER_ID_IM |
2726 /* Internal text (scripts). */
2728 /* Texture coordinates may reference objects.
2729 * Note that object data is *not* included. */
2730 FILTER_ID_OB);
2731
2732 if (!BKE_copybuffer_read(temp_bmain, filepath, op->reports, ntree_filter)) {
2733 BKE_report(op->reports, RPT_ERROR, "Internal clipboard is empty");
2734 BKE_main_free(temp_bmain);
2735 return OPERATOR_CANCELLED;
2736 }
2737
2738 /* There may be multiple materials,
2739 * check for a property that marks this as the active material. */
2740 Material *ma_from = nullptr;
2741 LISTBASE_FOREACH (Material *, ma_iter, &temp_bmain->materials) {
2742 if (ma_iter->id.flag & ID_FLAG_CLIPBOARD_MARK) {
2743 ma_from = ma_iter;
2744 break;
2745 }
2746 }
2747
2748 /* Make sure data from this file is usable for material paste. */
2749 if (ma_from == nullptr) {
2750 BKE_report(op->reports, RPT_ERROR, "Internal clipboard is not from a material");
2751 BKE_main_free(temp_bmain);
2752 return OPERATOR_CANCELLED;
2753 }
2754
2755 /* Keep animation by moving local animation to the paste node-tree. */
2756 if (ma->nodetree && ma_from->nodetree) {
2757 BLI_assert(ma_from->nodetree->adt == nullptr);
2758 std::swap(ma->nodetree->adt, ma_from->nodetree->adt);
2759 }
2760
2761 /* Needed to update #SpaceNode::nodetree else a stale pointer is used. */
2762 if (ma->nodetree) {
2763 bNodeTree *nodetree = ma->nodetree;
2765
2766 /* Free & clear data here, so user counts are handled, otherwise it's
2767 * freed as part of #BKE_main_free which doesn't handle user-counts. */
2768 /* Walk over all the embedded nodes ID's (non-recursively). */
2770 bmain, &nodetree->id, paste_material_nodetree_ids_decref, nullptr, IDWALK_NOP);
2771
2773 MEM_freeN(nodetree);
2774 ma->nodetree = nullptr;
2775 }
2776
2777/* Swap data-block content, while swapping isn't always needed,
2778 * it means memory is properly freed in the case of allocations.. */
2779#define SWAP_MEMBER(member) std::swap(ma->member, ma_from->member)
2780
2781 /* Intentionally skip:
2782 * - Texture painting slots.
2783 * - Preview render.
2784 * - Grease pencil styles (we could although they reference many ID's themselves).
2785 */
2787 SWAP_MEMBER(r);
2788 SWAP_MEMBER(g);
2789 SWAP_MEMBER(b);
2790 SWAP_MEMBER(a);
2791 SWAP_MEMBER(specr);
2792 SWAP_MEMBER(specg);
2793 SWAP_MEMBER(specb);
2794 SWAP_MEMBER(spec);
2795 SWAP_MEMBER(roughness);
2797 SWAP_MEMBER(use_nodes);
2798 SWAP_MEMBER(index);
2799 SWAP_MEMBER(nodetree);
2800 SWAP_MEMBER(line_col);
2801 SWAP_MEMBER(line_priority);
2802 SWAP_MEMBER(vcol_alpha);
2803
2804 SWAP_MEMBER(alpha_threshold);
2805 SWAP_MEMBER(refract_depth);
2806 SWAP_MEMBER(blend_method);
2807 SWAP_MEMBER(blend_shadow);
2808 SWAP_MEMBER(blend_flag);
2809
2810 SWAP_MEMBER(lineart);
2811
2812#undef SWAP_MEMBER
2813
2814 /* The node-tree from the clipboard is now assigned to the local material,
2815 * however the ID's it references are still part of `temp_bmain`.
2816 * These data-blocks references must be cleared or replaces with references to `bmain`.
2817 * TODO(@ideasman42): support merging indirectly referenced data-blocks besides the material,
2818 * this would be useful for pasting materials with node-groups between files. */
2819 if (ma->nodetree) {
2820 /* This implicitly points to local data, assign after remapping. */
2821 ma->nodetree->owner_id = nullptr;
2822
2823 /* Map remote ID's to local ones. */
2826
2827 ma->nodetree->owner_id = &ma->id;
2828 }
2829 BKE_main_free(temp_bmain);
2830
2831 /* Important to run this when the embedded tree if freed,
2832 * otherwise the depsgraph holds a reference to the (now freed) `ma->nodetree`.
2833 * Also run this when a new node-tree is set to ensure it's accounted for.
2834 * This also applies to animation data which is likely to be stored in the depsgraph.
2835 * Always call instead of checking when it *might* be needed. */
2837
2838 /* There are some custom updates to the node tree above, better do a full update pass. */
2840 ED_node_tree_propagate_change(C, bmain, nullptr);
2841
2844
2845 return OPERATOR_FINISHED;
2846}
2847
2849{
2850 /* identifiers */
2851 ot->name = "Paste Material";
2852 ot->idname = "MATERIAL_OT_paste";
2853 ot->description = "Paste the material settings and nodes";
2854
2855 /* api callbacks */
2856 ot->exec = paste_material_exec;
2858
2859 /* flags */
2861}
2862
2864
2865/* -------------------------------------------------------------------- */
2868
2869static short mtexcopied = 0; /* must be reset on file load */
2871
2873{ /* use for file reload */
2874 mtexcopied = 0;
2875}
2876
2877static void copy_mtex_copybuf(ID *id)
2878{
2879 MTex **mtex = nullptr;
2880
2881 switch (GS(id->name)) {
2882 case ID_PA:
2883 mtex = &(((ParticleSettings *)id)->mtex[int(((ParticleSettings *)id)->texact)]);
2884 break;
2885 case ID_LS:
2886 mtex = &(((FreestyleLineStyle *)id)->mtex[int(((FreestyleLineStyle *)id)->texact)]);
2887 break;
2888 default:
2889 break;
2890 }
2891
2892 if (mtex && *mtex) {
2893 mtexcopybuf = blender::dna::shallow_copy(**mtex);
2894 mtexcopied = 1;
2895 }
2896 else {
2897 mtexcopied = 0;
2898 }
2899}
2900
2901static void paste_mtex_copybuf(ID *id)
2902{
2903 MTex **mtex = nullptr;
2904
2905 if (mtexcopied == 0 || mtexcopybuf.tex == nullptr) {
2906 return;
2907 }
2908
2909 switch (GS(id->name)) {
2910 case ID_PA:
2911 mtex = &(((ParticleSettings *)id)->mtex[int(((ParticleSettings *)id)->texact)]);
2912 break;
2913 case ID_LS:
2914 mtex = &(((FreestyleLineStyle *)id)->mtex[int(((FreestyleLineStyle *)id)->texact)]);
2915 break;
2916 default:
2917 BLI_assert_msg(0, "invalid id type");
2918 return;
2919 }
2920
2921 if (mtex) {
2922 if (*mtex == nullptr) {
2923 *mtex = static_cast<MTex *>(MEM_callocN(sizeof(MTex), "mtex copy"));
2924 }
2925 else if ((*mtex)->tex) {
2926 id_us_min(&(*mtex)->tex->id);
2927 }
2928
2929 **mtex = blender::dna::shallow_copy(mtexcopybuf);
2930
2931 /* NOTE(@ideasman42): the simple memory copy has no special handling for ID data-blocks.
2932 * Ideally this would use `BKE_copybuffer_*` API's, however for common using
2933 * copy-pasting between slots, the case a users expects to copy between files
2934 * seems quite niche. So, do primitive ID validation. */
2935
2936 /* WARNING: This isn't a fool-proof solution as it's possible memory locations are reused,
2937 * or that the ID was relocated in memory since it was copied.
2938 * it does however guard against references to dangling pointers. */
2939 if ((*mtex)->tex && (BLI_findindex(&G_MAIN->textures, (*mtex)->tex) == -1)) {
2940 (*mtex)->tex = nullptr;
2941 }
2942 if ((*mtex)->object && (BLI_findindex(&G_MAIN->objects, (*mtex)->object) == -1)) {
2943 (*mtex)->object = nullptr;
2944 }
2945 id_us_plus((ID *)(*mtex)->tex);
2946 id_lib_extern((ID *)(*mtex)->object);
2947 }
2948}
2949
2951
2952/* -------------------------------------------------------------------- */
2955
2956static int copy_mtex_exec(bContext *C, wmOperator * /*op*/)
2957{
2958 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
2959
2960 if (id == nullptr) {
2961 /* copying empty slot */
2963 return OPERATOR_CANCELLED;
2964 }
2965
2967
2968 return OPERATOR_FINISHED;
2969}
2970
2972{
2973 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
2974
2975 return (id != nullptr);
2976}
2977
2979{
2980 /* identifiers */
2981 ot->name = "Copy Texture Slot Settings";
2982 ot->idname = "TEXTURE_OT_slot_copy";
2983 ot->description = "Copy the material texture settings and nodes";
2984
2985 /* api callbacks */
2986 ot->exec = copy_mtex_exec;
2987 ot->poll = copy_mtex_poll;
2988
2989 /* flags */
2990 /* no undo needed since no changes are made to the mtex */
2992}
2993
2995
2996/* -------------------------------------------------------------------- */
2999
3000static int paste_mtex_exec(bContext *C, wmOperator * /*op*/)
3001{
3002 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
3003
3004 if (id == nullptr) {
3005 Material *ma = static_cast<Material *>(
3006 CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
3007 Light *la = static_cast<Light *>(CTX_data_pointer_get_type(C, "light", &RNA_Light).data);
3008 World *wo = static_cast<World *>(CTX_data_pointer_get_type(C, "world", &RNA_World).data);
3009 ParticleSystem *psys = static_cast<ParticleSystem *>(
3010 CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data);
3011 FreestyleLineStyle *linestyle = static_cast<FreestyleLineStyle *>(
3012 CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data);
3013
3014 if (ma) {
3015 id = &ma->id;
3016 }
3017 else if (la) {
3018 id = &la->id;
3019 }
3020 else if (wo) {
3021 id = &wo->id;
3022 }
3023 else if (psys) {
3024 id = &psys->part->id;
3025 }
3026 else if (linestyle) {
3027 id = &linestyle->id;
3028 }
3029
3030 if (id == nullptr) {
3031 return OPERATOR_CANCELLED;
3032 }
3033 }
3034
3036
3038
3039 return OPERATOR_FINISHED;
3040}
3041
3043{
3044 /* identifiers */
3045 ot->name = "Paste Texture Slot Settings";
3046 ot->idname = "TEXTURE_OT_slot_paste";
3047 ot->description = "Copy the texture settings and nodes";
3048
3049 /* api callbacks */
3050 ot->exec = paste_mtex_exec;
3051
3052 /* flags */
3054}
3055
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:89
void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, struct ID *ref_id, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
const char * BKE_tempdir_base() ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
Definition appdir.cc:1211
bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *reports, uint64_t id_types_mask)
#define FOREACH_SCENE_OBJECT_END
#define FOREACH_SCENE_OBJECT_BEGIN(scene, _instance)
#define CTX_DATA_BEGIN(C, Type, instance, member)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
wmWindow * CTX_wm_window(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
#define CTX_DATA_END
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
ListBase * BKE_curve_editNurbs_get(Curve *cu)
Definition curve.cc:398
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:63
struct FreestyleModuleConfig * BKE_freestyle_module_add(struct FreestyleConfig *config)
Definition freestyle.cc:116
struct FreestyleLineSet * BKE_freestyle_lineset_add(struct Main *bmain, struct FreestyleConfig *config, const char *name)
Definition freestyle.cc:163
struct FreestyleLineSet * BKE_freestyle_lineset_get_active(struct FreestyleConfig *config)
Definition freestyle.cc:212
bool BKE_freestyle_module_move(struct FreestyleConfig *config, struct FreestyleModuleConfig *module_conf, int direction)
Definition freestyle.cc:140
bool BKE_freestyle_module_delete(struct FreestyleConfig *config, struct FreestyleModuleConfig *module_conf)
Definition freestyle.cc:131
#define G_MAIN
ViewLayerLightgroup * BKE_view_layer_add_lightgroup(ViewLayer *view_layer, const char *name)
void BKE_view_layer_remove_aov(ViewLayer *view_layer, ViewLayerAOV *aov)
void BKE_view_layer_remove_lightgroup(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup)
#define FOREACH_OBJECT_END
Definition BKE_layer.hh:432
#define FOREACH_OBJECT_BEGIN(scene, view_layer, _instance)
Definition BKE_layer.hh:422
@ VIEWLAYER_ADD_NEW
Definition BKE_layer.hh:34
@ VIEWLAYER_ADD_EMPTY
Definition BKE_layer.hh:35
@ VIEWLAYER_ADD_COPY
Definition BKE_layer.hh:36
void BKE_view_layer_verify_aov(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
blender::Vector< Object * > BKE_view_layer_array_selected_objects_params(ViewLayer *view_layer, const View3D *v3d, const ObjectsInViewLayerParams *params)
ViewLayer * BKE_view_layer_add(Scene *scene, const char *name, ViewLayer *view_layer_source, int type)
ViewLayerAOV * BKE_view_layer_add_aov(ViewLayer *view_layer)
void id_lib_extern(ID *id)
Definition lib_id.cc:283
void id_us_plus(ID *id)
Definition lib_id.cc:351
void BKE_id_move_to_same_lib(Main &bmain, ID &id, const ID &owner_id)
Definition lib_id.cc:862
void id_us_ensure_real(ID *id)
Definition lib_id.cc:306
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
Definition lib_id.cc:760
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:765
void id_us_min(ID *id)
Definition lib_id.cc:359
@ LIB_ID_COPY_ACTIONS
@ LIB_ID_COPY_DEFAULT
@ IDWALK_NOP
@ IDWALK_CB_USER_ONE
@ IDWALK_CB_USER
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, int flag)
Definition lib_query.cc:416
@ IDWALK_RET_NOP
@ ID_REMAP_FORCE_UI_POINTERS
void void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, int remap_flags) ATTR_NONNULL(1
General operations for probes.
void BKE_lightprobe_cache_free(struct Object *object)
void BKE_lightprobe_cache_create(struct Object *object)
Blender kernel freestyle line style functionality.
FreestyleLineStyle * BKE_linestyle_new(struct Main *bmain, const char *name)
Definition linestyle.cc:694
int BKE_linestyle_alpha_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier)
int BKE_linestyle_color_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier)
Definition linestyle.cc:921
LineStyleModifier * BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m, int flag)
LineStyleModifier * BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m, int flag)
bool BKE_linestyle_thickness_modifier_move(FreestyleLineStyle *linestyle, LineStyleModifier *modifier, int direction)
LineStyleModifier * BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type)
#define LS_MODIFIER_TYPE_COLOR
#define LS_MODIFIER_TYPE_ALPHA
bool BKE_linestyle_color_modifier_move(FreestyleLineStyle *linestyle, LineStyleModifier *modifier, int direction)
LineStyleModifier * BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type)
Definition linestyle.cc:991
FreestyleLineStyle * BKE_linestyle_active_from_view_layer(struct ViewLayer *view_layer)
Definition linestyle.cc:705
LineStyleModifier * BKE_linestyle_color_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type)
Definition linestyle.cc:771
int BKE_linestyle_thickness_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier)
#define LS_MODIFIER_TYPE_GEOMETRY
bool BKE_linestyle_alpha_modifier_move(FreestyleLineStyle *linestyle, LineStyleModifier *modifier, int direction)
bool BKE_linestyle_geometry_modifier_move(FreestyleLineStyle *linestyle, LineStyleModifier *modifier, int direction)
LineStyleModifier * BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m, int flag)
Definition linestyle.cc:829
#define LS_MODIFIER_TYPE_THICKNESS
LineStyleModifier * BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type)
LineStyleModifier * BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m, int flag)
int BKE_linestyle_geometry_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier)
ListBase * which_libbase(Main *bmain, short type)
Definition main.cc:842
Main * BKE_main_new(void)
Definition main.cc:45
void BKE_main_free(Main *bmain)
Definition main.cc:175
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:832
const char * BKE_main_blendfile_path_from_global()
Definition main.cc:837
General operations, lookup, etc. for materials.
bool BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob)
struct Material * BKE_gpencil_material_add(struct Main *bmain, const char *name)
struct Material * BKE_object_material_get(struct Object *ob, short act)
bool BKE_object_material_slot_used(struct Object *object, short actcol)
short * BKE_object_material_len_p(struct Object *ob)
struct Material *** BKE_object_material_array_p(struct Object *ob)
void BKE_object_material_array_assign(struct Main *bmain, struct Object *ob, struct Material ***matar, int totcol, bool to_object_only)
struct Material * BKE_material_add(struct Main *bmain, const char *name)
void BKE_object_material_remap(struct Object *ob, const unsigned int *remap)
bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob)
struct Material ** BKE_object_material_get_p(struct Object *ob, short act)
int BKE_object_material_index_get_with_hint(Object *ob, const Material *ma, int hint_index)
void BKE_ntree_update_tag_all(bNodeTree *ntree)
void BKE_ntree_update_tag_id_changed(Main *bmain, ID *id)
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const Object *ob)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv)
Definition scene.cc:2678
SceneRenderView * BKE_scene_add_render_view(Scene *sce, const char *name)
Definition scene.cc:2659
bool give_active_mtex(struct ID *id, struct MTex ***mtex_ar, short *act)
Definition texture.cc:493
void set_active_mtex(struct ID *id, short act)
Definition texture.cc:519
struct Tex * BKE_texture_add(struct Main *bmain, const char *name)
Definition texture.cc:383
int BKE_vfont_select_get(Object *ob, int *r_start, int *r_end)
Definition vfont.cc:630
struct World * BKE_world_add(struct Main *bmain, const char *name)
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
struct GSet GSet
Definition BLI_ghash.h:341
#define GSET_FOREACH_END()
Definition BLI_ghash.h:541
bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:1004
GSet * BLI_gset_str_new(const char *info)
#define GSET_FOREACH_BEGIN(type, var, what)
Definition BLI_ghash.h:535
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition BLI_ghash.c:1034
bool BLI_gset_add(GSet *gs, void *key)
Definition BLI_ghash.c:966
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void range_vn_u(unsigned int *array_tar, int size, unsigned int start)
#define FILE_MAX
#define BLI_path_join(...)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
void BLI_string_replace_char(char *str, char src, char dst) ATTR_NONNULL(1)
unsigned int uint
#define ELEM(...)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_WORLD
#define CTX_DATA_(context, msgid)
#define DATA_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
ID and Library types, which are fundamental for SDNA.
#define FILTER_ID_OB
Definition DNA_ID.h:1181
@ ID_RECALC_SHADING
Definition DNA_ID.h:1061
@ ID_RECALC_SELECT
Definition DNA_ID.h:1068
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1071
#define FILTER_ID_MA
Definition DNA_ID.h:1175
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:658
@ ID_FLAG_CLIPBOARD_MARK
Definition DNA_ID.h:750
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:683
#define FILTER_ID_IM
Definition DNA_ID.h:1171
#define FILTER_ID_NT
Definition DNA_ID.h:1180
#define FILTER_ID_TXT
Definition DNA_ID.h:1188
@ ID_LS
@ ID_PA
#define MAX_NAME
Definition DNA_defs.h:50
@ LIGHTPROBE_TYPE_VOLUME
@ OB_MODE_TEXTURE_PAINT
Object is a sort of wrapper for general info.
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_CURVES_LEGACY
@ OB_GPENCIL_LEGACY
@ OB_LIGHTPROBE
#define OB_TYPE_SUPPORT_MATERIAL(_type)
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
bool EDBM_deselect_by_material(BMEditMesh *em, short index, bool select)
void ED_node_tree_propagate_change(const bContext *C, Main *bmain, bNodeTree *ntree)
Definition node_edit.cc:492
void ED_node_shader_default(const bContext *C, ID *id)
Definition node_edit.cc:549
bool ED_paint_proj_mesh_data_check(Scene &scene, Object &ob, bool *r_has_uvs, bool *r_has_mat, bool *r_has_tex, bool *r_has_stencil)
bool ED_scene_view_layer_delete(Main *bmain, Scene *scene, ViewLayer *layer, ReportList *reports) ATTR_NONNULL(1
bool ED_operator_object_active_local_editable_ex(bContext *C, const Object *ob)
bool FRS_move_active_lineset(struct FreestyleConfig *config, int direction)
void FRS_paste_active_lineset(struct FreestyleConfig *config)
struct Material * FRS_create_stroke_material(struct Main *bmain, struct FreestyleLineStyle *linestyle)
void FRS_copy_active_lineset(struct FreestyleConfig *config)
void FRS_delete_active_lineset(struct FreestyleConfig *config)
Read Guarded memory(de)allocation.
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 Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue Hue Saturation Apply a color transformation in the HSV color model Specular Similar to the Principled BSDF node but uses the specular workflow instead of metallic
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
#define C
Definition RandGen.cpp:29
#define MAX_MTEX
Definition Stroke.h:33
void UI_context_active_but_prop_get_templateID(const bContext *C, PointerRNA *r_ptr, PropertyRNA **r_prop)
@ WM_JOB_TYPE_LIGHT_BAKE
Definition WM_api.hh:1602
#define NC_WORLD
Definition WM_types.hh:354
#define NC_GEOM
Definition WM_types.hh:360
#define ND_DRAW
Definition WM_types.hh:428
#define ND_DATA
Definition WM_types.hh:475
@ OPTYPE_INTERNAL
Definition WM_types.hh:182
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NC_LINESTYLE
Definition WM_types.hh:367
#define ND_RENDER_OPTIONS
Definition WM_types.hh:402
#define ND_SHADING_PREVIEW
Definition WM_types.hh:447
#define NC_SCENE
Definition WM_types.hh:345
#define NA_ADDED
Definition WM_types.hh:552
#define ND_TOOLSETTINGS
Definition WM_types.hh:416
#define NC_MATERIAL
Definition WM_types.hh:347
#define ND_SELECT
Definition WM_types.hh:474
#define NC_TEXTURE
Definition WM_types.hh:348
#define ND_LAYER
Definition WM_types.hh:417
#define ND_OB_SHADING
Definition WM_types.hh:424
#define NC_OBJECT
Definition WM_types.hh:346
#define ND_SHADING_LINKS
Definition WM_types.hh:446
@ BM_ELEM_SELECT
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
void append(const T &value)
bool is_empty() const
ID * id_add(const ID *id, IDAddOptions options, blender::FunctionRef< IDAddOperations(LibraryIDLinkCallbackData *cb_data, IDAddOptions options)> dependencies_filter_cb=nullptr)
bool write(const char *write_filepath, int write_flags, int remap_mode, ReportList &reports)
local_group_size(16, 16) .push_constant(Type b
#define SELECT
#define offsetof(t, d)
bool ED_curve_nurb_select_check(const View3D *v3d, const Nurb *nu)
void EEVEE_NEXT_lightbake_job(void *job_data, wmJobWorkerStatus *worker_status)
void EEVEE_NEXT_lightbake_update(void *job_data)
void EEVEE_NEXT_lightbake_job_data_free(void *job_data)
wmJob * EEVEE_NEXT_lightbake_job_create(wmWindowManager *wm, wmWindow *win, Main *bmain, ViewLayer *view_layer, Scene *scene, blender::Vector< Object * > original_probes, std::string &report, int delay_ms, int frame)
void * EEVEE_NEXT_lightbake_job_data_alloc(Main *bmain, ViewLayer *view_layer, Scene *scene, blender::Vector< Object * > original_probes, std::string &report, int frame)
RenderEngineType * RE_engines_find(const char *idname)
RenderEngine * RE_engine_create(RenderEngineType *type)
void RE_engine_free(RenderEngine *engine)
#define GS(x)
Definition iris.cc:202
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
#define G(x, y, z)
void node_tree_free_embedded_tree(bNodeTree *ntree)
Definition node.cc:3632
Object * context_object(const bContext *C)
blender::Vector< Object * > objects_in_mode_or_selected(bContext *C, bool(*filter_fn)(const Object *ob, void *user_data), void *filter_user_data)
void ntreeCompositUpdateRLayers(bNodeTree *ntree)
static struct PyModuleDef module
Definition python.cpp:991
static int material_slot_copy_exec(bContext *C, wmOperator *)
void ED_render_clear_mtex_copybuf()
static GSet * get_used_lightgroups(Scene *scene)
void OBJECT_OT_material_slot_add(wmOperatorType *ot)
void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
static int material_slot_assign_exec(bContext *C, wmOperator *)
static int lightprobe_cache_free_exec(bContext *C, wmOperator *op)
static int view_layer_add_exec(bContext *C, wmOperator *op)
static int copy_mtex_exec(bContext *C, wmOperator *)
static int lightprobe_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *)
static int paste_mtex_exec(bContext *C, wmOperator *)
static int view_layer_remove_aov_exec(bContext *C, wmOperator *)
static int material_slot_select_exec(bContext *C, wmOperator *)
static blender::Vector< Object * > lightprobe_cache_irradiance_volume_subset_get(bContext *C, wmOperator *op)
void OBJECT_OT_lightprobe_cache_free(wmOperatorType *ot)
void OBJECT_OT_material_slot_copy(wmOperatorType *ot)
static bool object_array_for_shading_edit_mode_enabled_filter(const Object *ob, void *user_data)
static MTex mtexcopybuf
void SCENE_OT_view_layer_remove_unused_lightgroups(wmOperatorType *ot)
static bool view_layer_remove_poll(bContext *C)
static void paste_mtex_copybuf(ID *id)
static int material_slot_add_exec(bContext *C, wmOperator *)
static int paste_material_exec(bContext *C, wmOperator *op)
static void copy_mtex_copybuf(ID *id)
static int material_slot_de_select(bContext *C, bool select)
void OBJECT_OT_lightprobe_cache_bake(wmOperatorType *ot)
static int new_world_exec(bContext *C, wmOperator *)
void OBJECT_OT_material_slot_select(wmOperatorType *ot)
void WORLD_OT_new(wmOperatorType *ot)
void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot)
static int render_view_remove_exec(bContext *C, wmOperator *)
static int material_slot_remove_unused_exec(bContext *C, wmOperator *op)
void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
static int material_slot_deselect_exec(bContext *C, wmOperator *)
static bool object_array_for_shading_edit_mode_disabled_filter(const Object *ob, void *user_data)
void MATERIAL_OT_paste(wmOperatorType *ot)
void MATERIAL_OT_new(wmOperatorType *ot)
static int material_slot_remove_exec(bContext *C, wmOperator *op)
void SCENE_OT_view_layer_add(wmOperatorType *ot)
static int render_view_add_exec(bContext *C, wmOperator *)
static int copy_material_exec(bContext *C, wmOperator *op)
void OBJECT_OT_material_slot_move(wmOperatorType *ot)
void SCENE_OT_view_layer_add_used_lightgroups(wmOperatorType *ot)
static int new_texture_exec(bContext *C, wmOperator *)
void TEXTURE_OT_new(wmOperatorType *ot)
static bool render_view_remove_poll(bContext *C)
static int view_layer_add_used_lightgroups_exec(bContext *C, wmOperator *)
static bool object_materials_supported_poll(bContext *C)
static int lightprobe_cache_bake_exec(bContext *C, wmOperator *op)
static int material_slot_move_exec(bContext *C, wmOperator *op)
void MATERIAL_OT_copy(wmOperatorType *ot)
void SCENE_OT_view_layer_remove_lightgroup(wmOperatorType *ot)
static int paste_material_nodetree_ids_decref(LibraryIDLinkCallbackData *cb_data)
static int view_layer_remove_unused_lightgroups_exec(bContext *C, wmOperator *)
static int texture_slot_move_exec(bContext *C, wmOperator *op)
static int view_layer_remove_exec(bContext *C, wmOperator *)
void TEXTURE_OT_slot_paste(wmOperatorType *ot)
static Vector< Object * > object_array_for_shading_edit_mode_enabled(bContext *C)
static int view_layer_remove_lightgroup_exec(bContext *C, wmOperator *)
void SCENE_OT_view_layer_add_aov(wmOperatorType *ot)
void TEXTURE_OT_slot_copy(wmOperatorType *ot)
@ LIGHTCACHE_SUBSET_ACTIVE
@ LIGHTCACHE_SUBSET_SELECTED
@ LIGHTCACHE_SUBSET_ALL
static int paste_material_nodetree_ids_relink_or_clear(LibraryIDLinkCallbackData *cb_data)
void SCENE_OT_render_view_add(wmOperatorType *ot)
void SCENE_OT_view_layer_remove_aov(wmOperatorType *ot)
void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
void TEXTURE_OT_slot_move(wmOperatorType *ot)
void SCENE_OT_view_layer_remove(wmOperatorType *ot)
static int new_material_exec(bContext *C, wmOperator *)
void SCENE_OT_view_layer_add_lightgroup(wmOperatorType *ot)
static int lightprobe_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void material_copybuffer_filepath_get(char filepath[FILE_MAX], size_t filepath_maxncpy)
static void lightprobe_cache_bake_cancel(bContext *C, wmOperator *op)
static int view_layer_add_lightgroup_exec(bContext *C, wmOperator *op)
void SCENE_OT_render_view_remove(wmOperatorType *ot)
#define SWAP_MEMBER(member)
static int view_layer_add_aov_exec(bContext *C, wmOperator *)
static bool object_materials_supported_poll_ex(bContext *C, const Object *ob)
static bool copy_mtex_poll(bContext *C)
static short mtexcopied
static Vector< Object * > object_array_for_shading_edit_mode_disabled(bContext *C)
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_id_pointer_create(ID *id)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
const EnumPropertyItem rna_enum_linestyle_thickness_modifier_type_items[]
const EnumPropertyItem rna_enum_linestyle_geometry_modifier_type_items[]
const EnumPropertyItem rna_enum_linestyle_color_modifier_type_items[]
const EnumPropertyItem rna_enum_linestyle_alpha_modifier_type_items[]
unsigned __int64 uint64_t
Definition stdint.h:90
short mat_nr
uint8_t f1
CharInfo * textbufinfo
Definition BKE_vfont.hh:37
struct FreestyleLineStyle * linestyle
Definition DNA_ID.h:413
void * last
void * first
char filepath[1024]
Definition BKE_main.hh:136
ListBase materials
Definition BKE_main.hh:216
struct bNodeTree * nodetree
struct Material ** mat
char * matbits
bool(* filter_fn)(const Object *ob, void *user_data)
Definition BKE_layer.hh:487
ParticleSettings * part
ID * owner_id
Definition RNA_types.hh:40
void * data
Definition RNA_types.hh:42
char engine[32]
void(* update_render_passes)(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer)
Definition RE_engine.h:115
struct bNodeTree * nodetree
struct RenderData r
ListBase view_layers
struct World * world
struct FreestyleConfig freestyle_config
ListBase lightgroups
ViewLayerLightgroup * active_lightgroup
ViewLayerAOV * active_aov
char name[64]
struct LightgroupMembership * lightgroup
short use_nodes
struct AnimData * adt
short type
Definition WM_types.hh:722
struct ReportList * reports
struct PointerRNA * ptr
void WM_cursor_wait(bool val)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ EVT_ESCKEY
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition wm_jobs.cc:455
void WM_jobs_kill_type(wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:597
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:223
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)
void WM_window_set_active_view_layer(wmWindow *win, ViewLayer *view_layer)
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)
uint8_t flag
Definition wm_window.cc:138