Blender V4.5
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_library.hh"
51#include "BKE_lightprobe.h"
52#include "BKE_linestyle.h"
53#include "BKE_main.hh"
55#include "BKE_material.hh"
56#include "BKE_node.hh"
57#include "BKE_node_runtime.hh"
59#include "BKE_object.hh"
60#include "BKE_report.hh"
61#include "BKE_scene.hh"
62#include "BKE_texture.h"
63#include "BKE_vfont.hh"
64#include "BKE_workspace.hh"
65#include "BKE_world.h"
66
67#include "NOD_composite.hh"
68
69#include "DEG_depsgraph.hh"
72
73#ifdef WITH_FREESTYLE
74# include "BKE_freestyle.h"
75# include "FRS_freestyle.h"
76# include "RNA_enum_types.hh"
77#endif
78
79#include "RNA_access.hh"
80
81#include "WM_api.hh"
82#include "WM_types.hh"
83
84#include "ED_curve.hh"
85#include "ED_mesh.hh"
86#include "ED_node.hh"
87#include "ED_object.hh"
88#include "ED_paint.hh"
89#include "ED_render.hh"
90#include "ED_scene.hh"
91#include "ED_screen.hh"
92#include "ED_undo.hh"
93
94#include "RNA_define.hh"
95#include "RNA_prototypes.hh"
96
97#include "UI_interface.hh"
98
99#include "RE_engine.h"
100#include "RE_pipeline.h"
101
103
104#include "render_intern.hh" /* own include */
105
106using blender::Vector;
107
108static bool object_materials_supported_poll_ex(bContext *C, const Object *ob);
109
110/* -------------------------------------------------------------------- */
113
114static void material_copybuffer_filepath_get(char filepath[FILE_MAX], size_t filepath_maxncpy)
115{
116 BLI_path_join(filepath, filepath_maxncpy, BKE_tempdir_base(), "copybuffer_material.blend");
117}
118
119static bool object_array_for_shading_edit_mode_enabled_filter(const Object *ob, void *user_data)
120{
121 bContext *C = static_cast<bContext *>(user_data);
123 if (BKE_object_is_in_editmode(ob) == true) {
124 return true;
125 }
126 }
127 return false;
128}
129
135
136static bool object_array_for_shading_edit_mode_disabled_filter(const Object *ob, void *user_data)
137{
138 bContext *C = static_cast<bContext *>(user_data);
140 if (BKE_object_is_in_editmode(ob) == false) {
141 return true;
142 }
143 }
144 return false;
145}
146
152
154
155/* -------------------------------------------------------------------- */
158
160{
162 return false;
163 }
164 if (!OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
165 return false;
166 }
167
168 /* Material linked to object. */
169 if (ob->matbits && ob->actcol && ob->matbits[ob->actcol - 1]) {
170 return true;
171 }
172
173 /* Material linked to obdata. */
174 const ID *data = static_cast<ID *>(ob->data);
176}
177
183
185
186/* -------------------------------------------------------------------- */
189
191{
192 Main *bmain = CTX_data_main(C);
194
195 if (!ob) {
196 return OPERATOR_CANCELLED;
197 }
198
200
201 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
202 Scene *scene = CTX_data_scene(C);
203 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
205 }
206
210
211 return OPERATOR_FINISHED;
212}
213
215{
216 /* identifiers */
217 ot->name = "Add Material Slot";
218 ot->idname = "OBJECT_OT_material_slot_add";
219 ot->description = "Add a new material slot";
220
221 /* API callbacks. */
224
225 /* flags */
227}
228
230
231/* -------------------------------------------------------------------- */
234
236{
238
239 if (!ob) {
240 return OPERATOR_CANCELLED;
241 }
242
243 /* Removing material slots in edit mode screws things up, see bug #21822. */
245 BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
246 return OPERATOR_CANCELLED;
247 }
248
250
251 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
252 Scene *scene = CTX_data_scene(C);
253 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
255 }
256
261
262 return OPERATOR_FINISHED;
263}
264
266{
267 /* identifiers */
268 ot->name = "Remove Material Slot";
269 ot->idname = "OBJECT_OT_material_slot_remove";
270 ot->description = "Remove the selected material slot";
271
272 /* API callbacks. */
275
276 /* flags */
278}
279
281
282/* -------------------------------------------------------------------- */
285
287{
288 View3D *v3d = CTX_wm_view3d(C);
289 bool changed_multi = false;
290
292 const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : nullptr;
293
295 for (Object *ob : objects) {
296 short mat_nr_active = -1;
297
298 if (ob->totcol == 0) {
299 continue;
300 }
301 if (obact && (mat_active == BKE_object_material_get(ob, obact->actcol))) {
302 /* Avoid searching since there may be multiple slots with the same material.
303 * For the active object or duplicates: match the material slot index first. */
304 mat_nr_active = obact->actcol - 1;
305 }
306 else {
307 /* Find the first matching material.
308 * NOTE: there may be multiple but that's not a common use case. */
309 for (int i = 0; i < ob->totcol; i++) {
310 const Material *mat = BKE_object_material_get(ob, i + 1);
311 if (mat_active == mat) {
312 mat_nr_active = i;
313 break;
314 }
315 }
316 if (mat_nr_active == -1) {
317 continue;
318 }
319 }
320
321 bool changed = false;
322 if (ob->type == OB_MESH) {
324 BMFace *efa;
325 BMIter iter;
326
327 if (em) {
328 BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
330 changed = true;
331 efa->mat_nr = mat_nr_active;
332 }
333 }
334 }
335 }
336 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
337 ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
338
339 if (nurbs) {
340 LISTBASE_FOREACH (Nurb *, nu, nurbs) {
341 if (ED_curve_nurb_select_check(v3d, nu)) {
342 changed = true;
343 nu->mat_nr = mat_nr_active;
344 }
345 }
346 }
347 }
348 else if (ob->type == OB_FONT) {
349 const Curve *cu = static_cast<const Curve *>(ob->data);
350 EditFont *ef = cu->editfont;
351 int i, selstart, selend;
352
353 if (ef && BKE_vfont_select_get(cu, &selstart, &selend)) {
354 for (i = selstart; i <= selend; i++) {
355 changed = true;
356 ef->textbufinfo[i].mat_nr = mat_nr_active;
357 }
358 }
359 }
360
361 if (changed) {
362 changed_multi = true;
365 }
366 }
367
368 return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
369}
370
372{
373 /* identifiers */
374 ot->name = "Assign Material Slot";
375 ot->idname = "OBJECT_OT_material_slot_assign";
376 ot->description = "Assign active material slot to selection";
377
378 /* API callbacks. */
381
382 /* flags */
384}
385
387
388/* -------------------------------------------------------------------- */
391
393{
394 bool changed_multi = false;
396 const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : nullptr;
397
399 for (Object *ob : objects) {
400 if (ob->totcol == 0) {
401 continue;
402 }
403
404 const short mat_nr_active = BKE_object_material_index_get_with_hint(
405 ob, mat_active, obact ? obact->actcol - 1 : -1);
406
407 if (mat_nr_active == -1) {
408 continue;
409 }
410
411 bool changed = false;
412
413 if (ob->type == OB_MESH) {
415
416 if (em) {
417 changed = EDBM_deselect_by_material(em, mat_nr_active, select);
418 }
419 }
420 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
421 ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
422 BPoint *bp;
423 BezTriple *bezt;
424 int a;
425
426 if (nurbs) {
427 LISTBASE_FOREACH (Nurb *, nu, nurbs) {
428 if (nu->mat_nr == mat_nr_active) {
429 if (nu->bezt) {
430 a = nu->pntsu;
431 bezt = nu->bezt;
432 while (a--) {
433 if (bezt->hide == 0) {
434 changed = true;
435 if (select) {
436 bezt->f1 |= SELECT;
437 bezt->f2 |= SELECT;
438 bezt->f3 |= SELECT;
439 }
440 else {
441 bezt->f1 &= ~SELECT;
442 bezt->f2 &= ~SELECT;
443 bezt->f3 &= ~SELECT;
444 }
445 }
446 bezt++;
447 }
448 }
449 else if (nu->bp) {
450 a = nu->pntsu * nu->pntsv;
451 bp = nu->bp;
452 while (a--) {
453 if (bp->hide == 0) {
454 changed = true;
455 if (select) {
456 bp->f1 |= SELECT;
457 }
458 else {
459 bp->f1 &= ~SELECT;
460 }
461 }
462 bp++;
463 }
464 }
465 }
466 }
467 }
468 }
469
470 if (changed) {
471 changed_multi = true;
472 DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_SELECT);
474 }
475 }
476
477 return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
478}
479
484
486{
487 /* identifiers */
488 ot->name = "Select Material Slot";
489 ot->idname = "OBJECT_OT_material_slot_select";
490 ot->description = "Select by active material slot";
491
492 /* API callbacks. */
494
495 /* flags */
497}
498
503
505{
506 /* identifiers */
507 ot->name = "Deselect Material Slot";
508 ot->idname = "OBJECT_OT_material_slot_deselect";
509 ot->description = "Deselect by active material slot";
510
511 /* API callbacks. */
513
514 /* flags */
516}
517
519
520/* -------------------------------------------------------------------- */
523
525{
526 Main *bmain = CTX_data_main(C);
528 Material ***matar_obdata;
529
530 if (!ob || !(matar_obdata = BKE_object_material_array_p(ob))) {
531 return OPERATOR_CANCELLED;
532 }
533
535
536 Material ***matar_object = &ob->mat;
537
538 Material **matar = static_cast<Material **>(
539 MEM_callocN(sizeof(*matar) * size_t(ob->totcol), __func__));
540 for (int i = ob->totcol; i--;) {
541 matar[i] = ob->matbits[i] ? (*matar_object)[i] : (*matar_obdata)[i];
542 }
543
544 CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
545 if (ob != ob_iter && BKE_object_material_array_p(ob_iter)) {
546 /* If we are using the same obdata, we only assign slots in ob_iter that are using object
547 * materials, and not obdata ones. */
548 const bool is_same_obdata = ob->data == ob_iter->data;
549
550 /* If we are using the same obdata, make the target object inherit the matbits of the active
551 * object. Without this, object material slots are not copied unless the target object
552 * already had its material slot link set to object. */
553 if (is_same_obdata) {
554 for (int i = ob->totcol; i--;) {
555 if (ob->matbits[i]) {
556 ob_iter->matbits[i] = ob->matbits[i];
557 }
558 }
559 }
560
561 BKE_object_material_array_assign(bmain, ob_iter, &matar, ob->totcol, is_same_obdata);
562
563 if (ob_iter->totcol == ob->totcol) {
564 ob_iter->actcol = ob->actcol;
567 }
568 }
569 }
571
572 MEM_freeN(matar);
573
574 return OPERATOR_FINISHED;
575}
576
578{
579 /* identifiers */
580 ot->name = "Copy Material to Selected";
581 ot->idname = "OBJECT_OT_material_slot_copy";
582 ot->description = "Copy material to selected objects";
583
584 /* API callbacks. */
586
587 /* flags */
589}
590
592
593/* -------------------------------------------------------------------- */
596
598{
600
601 uint *slot_remap;
602 int index_pair[2];
603
604 int dir = RNA_enum_get(op->ptr, "direction");
605
606 if (!ob || ob->totcol < 2) {
607 return OPERATOR_CANCELLED;
608 }
609
610 /* up */
611 if (dir == 1 && ob->actcol > 1) {
612 index_pair[0] = ob->actcol - 2;
613 index_pair[1] = ob->actcol - 1;
614 ob->actcol--;
615 }
616 /* down */
617 else if (dir == -1 && ob->actcol < ob->totcol) {
618 index_pair[0] = ob->actcol - 1;
619 index_pair[1] = ob->actcol - 0;
620 ob->actcol++;
621 }
622 else {
623 return OPERATOR_CANCELLED;
624 }
625
626 slot_remap = MEM_malloc_arrayN<uint>(ob->totcol, __func__);
627
628 range_vn_u(slot_remap, ob->totcol, 0);
629
630 slot_remap[index_pair[0]] = index_pair[1];
631 slot_remap[index_pair[1]] = index_pair[0];
632
633 BKE_object_material_remap(ob, slot_remap);
634
635 MEM_freeN(slot_remap);
636
640
641 return OPERATOR_FINISHED;
642}
643
645{
646 static const EnumPropertyItem material_slot_move[] = {
647 {1, "UP", 0, "Up", ""},
648 {-1, "DOWN", 0, "Down", ""},
649 {0, nullptr, 0, nullptr, nullptr},
650 };
651
652 /* identifiers */
653 ot->name = "Move Material";
654 ot->idname = "OBJECT_OT_material_slot_move";
655 ot->description = "Move the active material up/down in the list";
656
657 /* API callbacks. */
660
661 /* flags */
663
664 RNA_def_enum(ot->srna,
665 "direction",
666 material_slot_move,
667 0,
668 "Direction",
669 "Direction to move the active material towards");
670}
671
673
674/* -------------------------------------------------------------------- */
677
679{
680 /* Removing material slots in edit mode screws things up, see bug #21822. */
681 Object *ob_active = CTX_data_active_object(C);
682 if (ob_active && BKE_object_is_in_editmode(ob_active)) {
683 BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
684 return OPERATOR_CANCELLED;
685 }
686
687 Main *bmain = CTX_data_main(C);
688 int removed = 0;
689
691 for (Object *ob : objects) {
692 int actcol = ob->actcol;
693 for (int slot = 1; slot <= ob->totcol; slot++) {
694 while (slot <= ob->totcol && !BKE_object_material_slot_used(ob, slot)) {
695 ob->actcol = slot;
697
698 if (actcol >= slot) {
699 actcol--;
700 }
701
702 removed++;
703 }
704 }
705 ob->actcol = actcol;
706
708 }
709
710 if (!removed) {
711 return OPERATOR_CANCELLED;
712 }
713
714 BKE_reportf(op->reports, RPT_INFO, "Removed %d slots", removed);
715
716 if (ob_active->mode & OB_MODE_TEXTURE_PAINT) {
717 Scene *scene = CTX_data_scene(C);
718 ED_paint_proj_mesh_data_check(*scene, *ob_active, nullptr, nullptr, nullptr, nullptr);
720 }
721
725
726 return OPERATOR_FINISHED;
727}
728
730{
731 /* identifiers */
732 ot->name = "Remove Unused Slots";
733 ot->idname = "OBJECT_OT_material_slot_remove_unused";
734 ot->description = "Remove unused material slots";
735
736 /* API callbacks. */
739
740 /* flags */
742}
743
745{
746 /* Removing material slots in edit mode screws things up, see bug #21822. */
747 Object *ob_active = CTX_data_active_object(C);
748 if (ob_active && BKE_object_is_in_editmode(ob_active)) {
749 BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
750 return OPERATOR_CANCELLED;
751 }
752 Main *bmain = CTX_data_main(C);
753 int removed = 0;
754
756 for (Object *ob : objects) {
757 int actcol = ob->actcol;
758 for (int slot = 1; slot <= ob->totcol; slot++) {
759 while (slot <= ob->totcol) {
760 ob->actcol = slot;
762
763 if (actcol >= slot) {
764 actcol--;
765 }
766
767 removed++;
768 }
769 }
770 ob->actcol = actcol;
771
773 }
774
775 if (!removed) {
776 return OPERATOR_CANCELLED;
777 }
778
779 BKE_reportf(op->reports, RPT_INFO, "Removed %d materials", removed);
780
781 if (ob_active->mode == OB_MODE_TEXTURE_PAINT) {
782 Scene *scene = CTX_data_scene(C);
783 ED_paint_proj_mesh_data_check(*scene, *ob_active, nullptr, nullptr, nullptr, nullptr);
785 }
786
790
791 return OPERATOR_FINISHED;
792}
793
795{
796 /* identifiers */
797 ot->name = "Remove All Materials";
798 ot->idname = "OBJECT_OT_material_slot_remove_all";
799 ot->description = "Remove all materials";
800
801 /* API callbacks. */
804
805 /* flags */
807}
808
810
811/* -------------------------------------------------------------------- */
814
816{
817 Material *ma = static_cast<Material *>(
818 CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
819 Main *bmain = CTX_data_main(C);
821 PropertyRNA *prop;
822
823 /* hook into UI */
825
826 Object *ob = static_cast<Object *>((prop && RNA_struct_is_a(ptr.type, &RNA_Object)) ? ptr.data :
827 nullptr);
828
829 /* add or copy material */
830 if (ma) {
831 Material *new_ma = (Material *)BKE_id_copy_ex(
832 bmain, &ma->id, nullptr, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
833 ma = new_ma;
834 }
835 else {
836 const char *name = DATA_("Material");
837 if (!(ob != nullptr && ob->type == OB_GREASE_PENCIL)) {
838 ma = BKE_material_add(bmain, name);
839 }
840 else {
841 ma = BKE_gpencil_material_add(bmain, name);
842 }
844 ma->use_nodes = true;
845 }
846
847 if (prop) {
848 if (ob != nullptr) {
849 /* Add slot follows user-preferences for creating new slots,
850 * RNA pointer assignment doesn't, see: #60014. */
851 if (BKE_object_material_get_p(ob, ob->actcol) == nullptr) {
853 }
854 }
855
856 /* when creating new ID blocks, use is already 1, but RNA
857 * pointer use also increases user, so this compensates it */
858 id_us_min(&ma->id);
859
860 if (ptr.owner_id) {
861 BKE_id_move_to_same_lib(*bmain, ma->id, *ptr.owner_id);
862 }
863
864 PointerRNA idptr = RNA_id_pointer_create(&ma->id);
865 RNA_property_pointer_set(&ptr, prop, idptr, nullptr);
866 RNA_property_update(C, &ptr, prop);
867 }
868
870
871 return OPERATOR_FINISHED;
872}
873
875{
876 /* identifiers */
877 ot->name = "New Material";
878 ot->idname = "MATERIAL_OT_new";
879 ot->description = "Add a new material";
880
881 /* API callbacks. */
882 ot->exec = new_material_exec;
884
885 /* flags */
887}
888
890
891/* -------------------------------------------------------------------- */
894
896{
897 Tex *tex = static_cast<Tex *>(CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data);
898 Main *bmain = CTX_data_main(C);
900 PropertyRNA *prop;
901
902 /* add or copy texture */
903 if (tex) {
904 tex = (Tex *)BKE_id_copy(bmain, &tex->id);
905 }
906 else {
907 tex = BKE_texture_add(bmain, DATA_("Texture"));
908 }
909
910 /* hook into UI */
912
913 bool linked_id_created = false;
914 if (prop) {
915 /* when creating new ID blocks, use is already 1, but RNA
916 * pointer use also increases user, so this compensates it */
917 id_us_min(&tex->id);
918
919 if (ptr.owner_id) {
920 BKE_id_move_to_same_lib(*bmain, tex->id, *ptr.owner_id);
921 linked_id_created = ID_IS_LINKED(&tex->id);
922 }
923
924 PointerRNA idptr = RNA_id_pointer_create(&tex->id);
925 RNA_property_pointer_set(&ptr, prop, idptr, nullptr);
926 RNA_property_update(C, &ptr, prop);
927 }
928
929 if (!linked_id_created) {
930 ED_undo_push_op(C, op);
931 }
932
934
935 return OPERATOR_FINISHED;
936}
937
939{
940 /* identifiers */
941 ot->name = "New Texture";
942 ot->idname = "TEXTURE_OT_new";
943 ot->description = "Add a new texture";
944
945 /* API callbacks. */
946 ot->exec = new_texture_exec;
947
948 /* flags */
950}
951
953
954/* -------------------------------------------------------------------- */
957
959{
960 World *wo = static_cast<World *>(CTX_data_pointer_get_type(C, "world", &RNA_World).data);
961 Main *bmain = CTX_data_main(C);
963 PropertyRNA *prop;
964
965 /* add or copy world */
966 if (wo) {
967 World *new_wo = (World *)BKE_id_copy_ex(
968 bmain, &wo->id, nullptr, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
969 wo = new_wo;
970 }
971 else {
972 wo = BKE_world_add(bmain, CTX_DATA_(BLT_I18NCONTEXT_ID_WORLD, "World"));
974 wo->use_nodes = true;
975 }
976
977 /* hook into UI */
979
980 if (prop) {
981 /* when creating new ID blocks, use is already 1, but RNA
982 * pointer use also increases user, so this compensates it */
983 id_us_min(&wo->id);
984
985 if (ptr.owner_id) {
986 BKE_id_move_to_same_lib(*bmain, wo->id, *ptr.owner_id);
987 }
988
989 PointerRNA idptr = RNA_id_pointer_create(&wo->id);
990 RNA_property_pointer_set(&ptr, prop, idptr, nullptr);
991 RNA_property_update(C, &ptr, prop);
992 }
993
995
996 return OPERATOR_FINISHED;
997}
998
1000{
1001 /* identifiers */
1002 ot->name = "New World";
1003 ot->idname = "WORLD_OT_new";
1004 ot->description = "Create a new world Data-Block";
1005
1006 /* API callbacks. */
1007 ot->exec = new_world_exec;
1008
1009 /* flags */
1011}
1012
1014
1015/* -------------------------------------------------------------------- */
1018
1020{
1021 wmWindow *win = CTX_wm_window(C);
1022 Scene *scene = CTX_data_scene(C);
1023
1024 ViewLayer *view_layer_current = win ? WM_window_get_active_view_layer(win) : nullptr;
1025 int type = RNA_enum_get(op->ptr, "type");
1026 /* Copy requires a source. */
1027 if (type == VIEWLAYER_ADD_COPY) {
1028 if (view_layer_current == nullptr) {
1029 type = VIEWLAYER_ADD_NEW;
1030 }
1031 }
1032 ViewLayer *view_layer_new = BKE_view_layer_add(
1033 scene, view_layer_current ? view_layer_current->name : nullptr, view_layer_current, type);
1034
1035 if (win) {
1036 WM_window_set_active_view_layer(win, view_layer_new);
1037 }
1038
1042
1043 return OPERATOR_FINISHED;
1044}
1045
1047{
1048 static EnumPropertyItem type_items[] = {
1049 {VIEWLAYER_ADD_NEW, "NEW", 0, "New", "Add a new view layer"},
1050 {VIEWLAYER_ADD_COPY, "COPY", 0, "Copy Settings", "Copy settings of current view layer"},
1052 "EMPTY",
1053 0,
1054 "Blank",
1055 "Add a new view layer with all collections disabled"},
1056 {0, nullptr, 0, nullptr, nullptr},
1057 };
1058
1059 /* identifiers */
1060 ot->name = "Add View Layer";
1061 ot->idname = "SCENE_OT_view_layer_add";
1062 ot->description = "Add a view layer";
1063
1064 /* API callbacks. */
1065 ot->exec = view_layer_add_exec;
1066 ot->invoke = WM_menu_invoke;
1067
1068 /* flags */
1070
1071 /* properties */
1072 ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
1073}
1074
1076
1077/* -------------------------------------------------------------------- */
1080
1082{
1083 Scene *scene = CTX_data_scene(C);
1084 return (scene->view_layers.first != scene->view_layers.last);
1085}
1086
1088{
1089 Main *bmain = CTX_data_main(C);
1090 Scene *scene = CTX_data_scene(C);
1091 ViewLayer *view_layer = CTX_data_view_layer(C);
1092
1093 if (!ED_scene_view_layer_delete(bmain, scene, view_layer, nullptr)) {
1094 return OPERATOR_CANCELLED;
1095 }
1096
1098
1099 return OPERATOR_FINISHED;
1100}
1101
1103{
1104 /* identifiers */
1105 ot->name = "Remove View Layer";
1106 ot->idname = "SCENE_OT_view_layer_remove";
1107 ot->description = "Remove the selected view layer";
1108
1109 /* API callbacks. */
1110 ot->exec = view_layer_remove_exec;
1111 ot->poll = view_layer_remove_poll;
1112
1113 /* flags */
1115}
1116
1118
1119/* -------------------------------------------------------------------- */
1122
1124{
1125 Scene *scene = CTX_data_scene(C);
1126 ViewLayer *view_layer = CTX_data_view_layer(C);
1127
1128 BKE_view_layer_add_aov(view_layer);
1129
1130 RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
1131 if (engine_type->update_render_passes) {
1132 RenderEngine *engine = RE_engine_create(engine_type);
1133 if (engine) {
1134 BKE_view_layer_verify_aov(engine, scene, view_layer);
1135 }
1136 RE_engine_free(engine);
1137 engine = nullptr;
1138 }
1139
1140 if (scene->nodetree) {
1142 }
1143
1147
1148 return OPERATOR_FINISHED;
1149}
1150
1152{
1153 /* identifiers */
1154 ot->name = "Add AOV";
1155 ot->idname = "SCENE_OT_view_layer_add_aov";
1156 ot->description = "Add a Shader AOV";
1157
1158 /* API callbacks. */
1160
1161 /* flags */
1163}
1164
1166
1167/* -------------------------------------------------------------------- */
1170
1172{
1173 Scene *scene = CTX_data_scene(C);
1174 ViewLayer *view_layer = CTX_data_view_layer(C);
1175
1176 if (view_layer->active_aov == nullptr) {
1177 return OPERATOR_FINISHED;
1178 }
1179
1180 BKE_view_layer_remove_aov(view_layer, view_layer->active_aov);
1181
1182 RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
1183 if (engine_type->update_render_passes) {
1184 RenderEngine *engine = RE_engine_create(engine_type);
1185 if (engine) {
1186 BKE_view_layer_verify_aov(engine, scene, view_layer);
1187 }
1188 RE_engine_free(engine);
1189 engine = nullptr;
1190 }
1191
1192 if (scene->nodetree) {
1194 }
1195
1199
1200 return OPERATOR_FINISHED;
1201}
1202
1204{
1205 /* identifiers */
1206 ot->name = "Remove AOV";
1207 ot->idname = "SCENE_OT_view_layer_remove_aov";
1208 ot->description = "Remove Active AOV";
1209
1210 /* API callbacks. */
1212
1213 /* flags */
1215}
1216
1218
1219/* -------------------------------------------------------------------- */
1222
1224{
1225 Scene *scene = CTX_data_scene(C);
1226 ViewLayer *view_layer = CTX_data_view_layer(C);
1227
1228 char name[MAX_NAME];
1229 name[0] = '\0';
1230 /* If a name is provided, ensure that it is unique. */
1231 if (RNA_struct_property_is_set(op->ptr, "name")) {
1232 RNA_string_get(op->ptr, "name", name);
1233 /* Ensure that there are no dots in the name. */
1234 BLI_string_replace_char(name, '.', '_');
1235 LISTBASE_FOREACH (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
1236 if (STREQ(lightgroup->name, name)) {
1237 return OPERATOR_CANCELLED;
1238 }
1239 }
1240 }
1241
1242 BKE_view_layer_add_lightgroup(view_layer, name);
1243
1244 if (scene->nodetree) {
1246 }
1247
1251
1252 return OPERATOR_FINISHED;
1253}
1254
1256{
1257 /* identifiers */
1258 ot->name = "Add Lightgroup";
1259 ot->idname = "SCENE_OT_view_layer_add_lightgroup";
1260 ot->description = "Add a Light Group";
1261
1262 /* API callbacks. */
1264
1265 /* flags */
1267
1268 /* properties */
1269 ot->prop = RNA_def_string(ot->srna,
1270 "name",
1271 nullptr,
1273 "Name",
1274 "Name of newly created lightgroup");
1275}
1276
1278
1279/* -------------------------------------------------------------------- */
1282
1284{
1285 Scene *scene = CTX_data_scene(C);
1286 ViewLayer *view_layer = CTX_data_view_layer(C);
1287
1288 if (view_layer->active_lightgroup == nullptr) {
1289 return OPERATOR_FINISHED;
1290 }
1291
1292 BKE_view_layer_remove_lightgroup(view_layer, view_layer->active_lightgroup);
1293
1294 if (scene->nodetree) {
1296 }
1297
1301
1302 return OPERATOR_FINISHED;
1303}
1304
1306{
1307 /* identifiers */
1308 ot->name = "Remove Lightgroup";
1309 ot->idname = "SCENE_OT_view_layer_remove_lightgroup";
1310 ot->description = "Remove Active Lightgroup";
1311
1312 /* API callbacks. */
1314
1315 /* flags */
1317}
1318
1320
1321/* -------------------------------------------------------------------- */
1324
1326{
1327 blender::Set<blender::StringRefNull> used_lightgroups;
1328
1329 FOREACH_SCENE_OBJECT_BEGIN (scene, ob) {
1330 if (ob->lightgroup && ob->lightgroup->name[0]) {
1331 used_lightgroups.add_as(ob->lightgroup->name);
1332 }
1333 }
1335
1336 if (scene->world && scene->world->lightgroup && scene->world->lightgroup->name[0]) {
1337 used_lightgroups.add_as(scene->world->lightgroup->name);
1338 }
1339
1340 return used_lightgroups;
1341}
1342
1344{
1345 Scene *scene = CTX_data_scene(C);
1346 ViewLayer *view_layer = CTX_data_view_layer(C);
1347
1349 for (const blender::StringRefNull used_lightgroup : used_lightgroups) {
1350 if (!BLI_findstring(&view_layer->lightgroups,
1351 used_lightgroup.c_str(),
1353 {
1354 BKE_view_layer_add_lightgroup(view_layer, used_lightgroup.c_str());
1355 }
1356 }
1357
1358 if (scene->nodetree) {
1360 }
1361
1365
1366 return OPERATOR_FINISHED;
1367}
1368
1370{
1371 /* identifiers */
1372 ot->name = "Add Used Lightgroups";
1373 ot->idname = "SCENE_OT_view_layer_add_used_lightgroups";
1374 ot->description = "Add all used Light Groups";
1375
1376 /* API callbacks. */
1378
1379 /* flags */
1381}
1382
1384
1385/* -------------------------------------------------------------------- */
1388
1390{
1391 Scene *scene = CTX_data_scene(C);
1392 ViewLayer *view_layer = CTX_data_view_layer(C);
1393
1395 LISTBASE_FOREACH_MUTABLE (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
1396 if (!used_lightgroups.contains_as(lightgroup->name)) {
1397 BKE_view_layer_remove_lightgroup(view_layer, lightgroup);
1398 }
1399 }
1400
1401 if (scene->nodetree) {
1403 }
1404
1408
1409 return OPERATOR_FINISHED;
1410}
1411
1413{
1414 /* identifiers */
1415 ot->name = "Remove Unused Lightgroups";
1416 ot->idname = "SCENE_OT_view_layer_remove_unused_lightgroups";
1417 ot->description = "Remove all unused Light Groups";
1418
1419 /* API callbacks. */
1421
1422 /* flags */
1424}
1425
1427
1428/* -------------------------------------------------------------------- */
1431
1432enum {
1436};
1437
1439 wmOperator *op)
1440{
1441 ViewLayer *view_layer = CTX_data_view_layer(C);
1442 Scene *scene = CTX_data_scene(C);
1443
1444 auto is_irradiance_volume = [](Object *ob) -> bool {
1445 return ob->type == OB_LIGHTPROBE &&
1446 static_cast<LightProbe *>(ob->data)->type == LIGHTPROBE_TYPE_VOLUME;
1447 };
1448
1450
1451 auto irradiance_volume_setup = [&](Object *ob) {
1455 probes.append(ob);
1456 };
1457
1458 int subset = RNA_enum_get(op->ptr, "subset");
1459 switch (subset) {
1460 case LIGHTCACHE_SUBSET_ALL: {
1461 FOREACH_OBJECT_BEGIN (scene, view_layer, ob) {
1462 if (is_irradiance_volume(ob)) {
1463 irradiance_volume_setup(ob);
1464 }
1465 }
1467 break;
1468 }
1470 ObjectsInViewLayerParams parameters;
1471 parameters.filter_fn = nullptr;
1472 parameters.no_dup_data = true;
1474 view_layer, nullptr, &parameters);
1475 for (Object *ob : objects) {
1476 if (is_irradiance_volume(ob)) {
1477 irradiance_volume_setup(ob);
1478 }
1479 }
1480 break;
1481 }
1483 Object *active_ob = CTX_data_active_object(C);
1484 if (is_irradiance_volume(active_ob)) {
1485 irradiance_volume_setup(active_ob);
1486 }
1487 break;
1488 }
1489 default:
1491 break;
1492 }
1493
1494 return probes;
1495}
1496
1498 /* Store actual owner of job, so modal operator could check for it,
1499 * the reason of this is that active scene could change when rendering
1500 * several layers from compositor #31800. */
1502
1503 std::string report;
1504};
1505
1507 wmOperator *op,
1508 const wmEvent * /*event*/)
1509{
1511 wmWindow *win = CTX_wm_window(C);
1512 ViewLayer *view_layer = CTX_data_view_layer(C);
1513 Main *bmain = CTX_data_main(C);
1514 Scene *scene = CTX_data_scene(C);
1515
1517
1518 if (probes.is_empty()) {
1519 return OPERATOR_CANCELLED;
1520 }
1521
1522 BakeOperatorData *data = MEM_new<BakeOperatorData>(__func__);
1523 data->scene = scene;
1524 data->report = "";
1525
1527 wm, win, bmain, view_layer, scene, probes, data->report, scene->r.cfra, 0);
1528 if (wm_job == nullptr) {
1529 MEM_delete(data);
1530 BKE_report(op->reports, RPT_WARNING, "Can't bake light probe while rendering");
1531 return OPERATOR_CANCELLED;
1532 }
1533
1535
1536 op->customdata = static_cast<void *>(data);
1537
1538 WM_jobs_start(wm, wm_job);
1539
1540 WM_cursor_wait(false);
1541
1543}
1544
1546 wmOperator *op,
1547 const wmEvent *event)
1548{
1549 BakeOperatorData *data = static_cast<BakeOperatorData *>(op->customdata);
1550 Scene *scene = data->scene;
1551
1552 /* No running bake, remove handler and pass through. */
1554 std::string report = data->report;
1555
1556 MEM_delete(data);
1557 op->customdata = nullptr;
1558
1559 if (!report.empty()) {
1560 BKE_report(op->reports, RPT_ERROR, report.c_str());
1561 return OPERATOR_CANCELLED;
1562 }
1564 }
1565
1566 /* Running bake. */
1567 switch (event->type) {
1568 case EVT_ESCKEY:
1570 default: {
1571 break;
1572 }
1573 }
1574 return OPERATOR_PASS_THROUGH;
1575}
1576
1578{
1580 Scene *scene = static_cast<BakeOperatorData *>(op->customdata)->scene;
1581
1582 /* Kill on cancel, because job is using op->reports. */
1584}
1585
1586/* Executes blocking bake. */
1588{
1589 ViewLayer *view_layer = CTX_data_view_layer(C);
1590 Main *bmain = CTX_data_main(C);
1591 Scene *scene = CTX_data_scene(C);
1592
1593 G.is_break = false;
1594
1596
1597 std::string report;
1599 bmain, view_layer, scene, probes, report, scene->r.cfra);
1600 /* Do the job. */
1601 wmJobWorkerStatus worker_status = {};
1602 EEVEE_lightbake_job(rj, &worker_status);
1603 /* Move baking data to original object and then free it. */
1606
1607 if (!report.empty()) {
1608 BKE_report(op->reports, RPT_ERROR, report.c_str());
1609 return OPERATOR_CANCELLED;
1610 }
1611
1612 return OPERATOR_FINISHED;
1613}
1614
1616{
1617 static const EnumPropertyItem light_cache_subset_items[] = {
1618 {LIGHTCACHE_SUBSET_ALL, "ALL", 0, "All Volumes", "Bake all light probe volumes"},
1620 "SELECTED",
1621 0,
1622 "Selected Only",
1623 "Only bake selected light probe volumes"},
1625 "ACTIVE",
1626 0,
1627 "Active Only",
1628 "Only bake the active light probe volume"},
1629 {0, nullptr, 0, nullptr, nullptr},
1630 };
1631
1632 /* identifiers */
1633 ot->name = "Bake Light Cache";
1634 ot->idname = "OBJECT_OT_lightprobe_cache_bake";
1635 ot->description = "Bake irradiance volume light cache";
1636
1637 /* API callbacks. */
1642
1643 ot->prop = RNA_def_enum(
1644 ot->srna, "subset", light_cache_subset_items, 0, "Subset", "Subset of probes to update");
1646}
1647
1649
1650/* -------------------------------------------------------------------- */
1653
1655{
1656 Scene *scene = CTX_data_scene(C);
1657
1658 /* Kill potential bake job first (see #57011). */
1661
1663
1664 for (Object *object : probes) {
1665 if (object->lightprobe_cache == nullptr) {
1666 continue;
1667 }
1670 }
1671
1673
1674 return OPERATOR_FINISHED;
1675}
1676
1678{
1679 static const EnumPropertyItem lightprobe_subset_items[] = {
1681 "ALL",
1682 0,
1683 "All Light Probes",
1684 "Delete all light probes' baked lighting data"},
1686 "SELECTED",
1687 0,
1688 "Selected Only",
1689 "Only delete selected light probes' baked lighting data"},
1691 "ACTIVE",
1692 0,
1693 "Active Only",
1694 "Only delete the active light probe's baked lighting data"},
1695 {0, nullptr, 0, nullptr, nullptr},
1696 };
1697
1698 /* identifiers */
1699 ot->name = "Delete Light Cache";
1700 ot->idname = "OBJECT_OT_lightprobe_cache_free";
1701 ot->description = "Delete cached indirect lighting";
1702 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1703
1704 /* API callbacks. */
1706
1707 ot->prop = RNA_def_enum(ot->srna,
1708 "subset",
1709 lightprobe_subset_items,
1711 "Subset",
1712 "Subset of probes to update");
1713}
1714
1716
1717/* -------------------------------------------------------------------- */
1720
1722{
1723 Scene *scene = CTX_data_scene(C);
1724
1725 /* don't allow user to remove "left" and "right" views */
1726 return scene->r.actview > 1;
1727}
1728
1730{
1731 Main *bmain = CTX_data_main(C);
1732 Scene *scene = CTX_data_scene(C);
1733
1734 BKE_scene_add_render_view(scene, nullptr);
1735 scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
1736
1738
1739 BKE_ntree_update_tag_id_changed(bmain, &scene->id);
1741
1742 return OPERATOR_FINISHED;
1743}
1744
1746{
1747 /* identifiers */
1748 ot->name = "Add Render View";
1749 ot->idname = "SCENE_OT_render_view_add";
1750 ot->description = "Add a render view";
1751
1752 /* API callbacks. */
1753 ot->exec = render_view_add_exec;
1754
1755 /* flags */
1756 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1757}
1758
1760
1761/* -------------------------------------------------------------------- */
1764
1766{
1767 Main *bmain = CTX_data_main(C);
1768 Scene *scene = CTX_data_scene(C);
1769 SceneRenderView *rv = static_cast<SceneRenderView *>(
1770 BLI_findlink(&scene->r.views, scene->r.actview));
1771
1772 if (!BKE_scene_remove_render_view(scene, rv)) {
1773 return OPERATOR_CANCELLED;
1774 }
1775
1777
1778 BKE_ntree_update_tag_id_changed(bmain, &scene->id);
1780
1781 return OPERATOR_FINISHED;
1782}
1783
1785{
1786 /* identifiers */
1787 ot->name = "Remove Render View";
1788 ot->idname = "SCENE_OT_render_view_remove";
1789 ot->description = "Remove the selected render view";
1790
1791 /* API callbacks. */
1794
1795 /* flags */
1796 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1797}
1798
1800
1801#ifdef WITH_FREESTYLE
1802
1803/* -------------------------------------------------------------------- */
1806
1807static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)
1808{
1809 if (!lineset) {
1811 RPT_ERROR,
1812 "No active lineset and associated line style to manipulate the modifier");
1813 return false;
1814 }
1815 if (!lineset->linestyle) {
1817 RPT_ERROR,
1818 "The active lineset does not have a line style (indicating data corruption)");
1819 return false;
1820 }
1821
1822 return true;
1823}
1824
1825static bool freestyle_active_module_poll(bContext *C)
1826{
1827 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1828 FreestyleModuleConfig *module = static_cast<FreestyleModuleConfig *>(ptr.data);
1829
1830 return module != nullptr;
1831}
1832
1833static wmOperatorStatus freestyle_module_add_exec(bContext *C, wmOperator * /*op*/)
1834{
1835 Scene *scene = CTX_data_scene(C);
1836 ViewLayer *view_layer = CTX_data_view_layer(C);
1837
1839
1841
1842 return OPERATOR_FINISHED;
1843}
1844
1845void SCENE_OT_freestyle_module_add(wmOperatorType *ot)
1846{
1847 /* identifiers */
1848 ot->name = "Add Freestyle Module";
1849 ot->idname = "SCENE_OT_freestyle_module_add";
1850 ot->description = "Add a style module into the list of modules";
1851
1852 /* API callbacks. */
1853 ot->exec = freestyle_module_add_exec;
1854
1855 /* flags */
1857}
1858
1860
1861/* -------------------------------------------------------------------- */
1864
1865static wmOperatorStatus freestyle_module_remove_exec(bContext *C, wmOperator * /*op*/)
1866{
1867 Scene *scene = CTX_data_scene(C);
1868 ViewLayer *view_layer = CTX_data_view_layer(C);
1869 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1870 FreestyleModuleConfig *module = static_cast<FreestyleModuleConfig *>(ptr.data);
1871
1873
1876
1877 return OPERATOR_FINISHED;
1878}
1879
1880void SCENE_OT_freestyle_module_remove(wmOperatorType *ot)
1881{
1882 /* identifiers */
1883 ot->name = "Remove Freestyle Module";
1884 ot->idname = "SCENE_OT_freestyle_module_remove";
1885 ot->description = "Remove the style module from the stack";
1886
1887 /* API callbacks. */
1888 ot->poll = freestyle_active_module_poll;
1889 ot->exec = freestyle_module_remove_exec;
1890
1891 /* flags */
1893}
1894
1895static wmOperatorStatus freestyle_module_move_exec(bContext *C, wmOperator *op)
1896{
1897 Scene *scene = CTX_data_scene(C);
1898 ViewLayer *view_layer = CTX_data_view_layer(C);
1899 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1900 FreestyleModuleConfig *module = static_cast<FreestyleModuleConfig *>(ptr.data);
1901 int dir = RNA_enum_get(op->ptr, "direction");
1902
1903 if (BKE_freestyle_module_move(&view_layer->freestyle_config, module, dir)) {
1906 }
1907
1908 return OPERATOR_FINISHED;
1909}
1910
1912
1913/* -------------------------------------------------------------------- */
1916
1917void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
1918{
1919 static const EnumPropertyItem direction_items[] = {
1920 {-1, "UP", 0, "Up", ""},
1921 {1, "DOWN", 0, "Down", ""},
1922 {0, nullptr, 0, nullptr, nullptr},
1923 };
1924
1925 /* identifiers */
1926 ot->name = "Move Freestyle Module";
1927 ot->idname = "SCENE_OT_freestyle_module_move";
1928 ot->description = "Change the position of the style module within in the list of style modules";
1929
1930 /* API callbacks. */
1931 ot->poll = freestyle_active_module_poll;
1932 ot->exec = freestyle_module_move_exec;
1933
1934 /* flags */
1936
1937 /* props */
1938 RNA_def_enum(ot->srna,
1939 "direction",
1940 direction_items,
1941 0,
1942 "Direction",
1943 "Direction to move the chosen style module towards");
1944}
1945
1947
1948/* -------------------------------------------------------------------- */
1951
1952static wmOperatorStatus freestyle_lineset_add_exec(bContext *C, wmOperator * /*op*/)
1953{
1954 Main *bmain = CTX_data_main(C);
1955 Scene *scene = CTX_data_scene(C);
1956 ViewLayer *view_layer = CTX_data_view_layer(C);
1957
1958 BKE_freestyle_lineset_add(bmain, &view_layer->freestyle_config, nullptr);
1959
1962
1963 return OPERATOR_FINISHED;
1964}
1965
1966void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot)
1967{
1968 /* identifiers */
1969 ot->name = "Add Line Set";
1970 ot->idname = "SCENE_OT_freestyle_lineset_add";
1971 ot->description = "Add a line set into the list of line sets";
1972
1973 /* API callbacks. */
1974 ot->exec = freestyle_lineset_add_exec;
1975
1976 /* flags */
1978}
1979
1981
1982/* -------------------------------------------------------------------- */
1985
1986static bool freestyle_active_lineset_poll(bContext *C)
1987{
1988 ViewLayer *view_layer = CTX_data_view_layer(C);
1989
1990 if (!view_layer) {
1991 return false;
1992 }
1993
1994 return BKE_freestyle_lineset_get_active(&view_layer->freestyle_config) != nullptr;
1995}
1996
1997static wmOperatorStatus freestyle_lineset_copy_exec(bContext *C, wmOperator * /*op*/)
1998{
1999 ViewLayer *view_layer = CTX_data_view_layer(C);
2000
2002
2003 return OPERATOR_FINISHED;
2004}
2005
2006void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot)
2007{
2008 /* identifiers */
2009 ot->name = "Copy Line Set";
2010 ot->idname = "SCENE_OT_freestyle_lineset_copy";
2011 ot->description = "Copy the active line set to the internal clipboard";
2012
2013 /* API callbacks. */
2014 ot->exec = freestyle_lineset_copy_exec;
2015 ot->poll = freestyle_active_lineset_poll;
2016
2017 /* flags */
2019}
2020
2022
2023/* -------------------------------------------------------------------- */
2026
2027static wmOperatorStatus freestyle_lineset_paste_exec(bContext *C, wmOperator * /*op*/)
2028{
2029 Scene *scene = CTX_data_scene(C);
2030 ViewLayer *view_layer = CTX_data_view_layer(C);
2031
2033
2036
2037 return OPERATOR_FINISHED;
2038}
2039
2040void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot)
2041{
2042 /* identifiers */
2043 ot->name = "Paste Line Set";
2044 ot->idname = "SCENE_OT_freestyle_lineset_paste";
2045 ot->description = "Paste the internal clipboard content to the active line set";
2046
2047 /* API callbacks. */
2048 ot->exec = freestyle_lineset_paste_exec;
2049 ot->poll = freestyle_active_lineset_poll;
2050
2051 /* flags */
2053}
2054
2056
2057/* -------------------------------------------------------------------- */
2060
2061static wmOperatorStatus freestyle_lineset_remove_exec(bContext *C, wmOperator * /*op*/)
2062{
2063 Scene *scene = CTX_data_scene(C);
2064 ViewLayer *view_layer = CTX_data_view_layer(C);
2065
2067
2070
2071 return OPERATOR_FINISHED;
2072}
2073
2074void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot)
2075{
2076 /* identifiers */
2077 ot->name = "Remove Line Set";
2078 ot->idname = "SCENE_OT_freestyle_lineset_remove";
2079 ot->description = "Remove the active line set from the list of line sets";
2080
2081 /* API callbacks. */
2082 ot->exec = freestyle_lineset_remove_exec;
2083 ot->poll = freestyle_active_lineset_poll;
2084
2085 /* flags */
2087}
2088
2090
2091/* -------------------------------------------------------------------- */
2094
2095static wmOperatorStatus freestyle_lineset_move_exec(bContext *C, wmOperator *op)
2096{
2097 Scene *scene = CTX_data_scene(C);
2098 ViewLayer *view_layer = CTX_data_view_layer(C);
2099 int dir = RNA_enum_get(op->ptr, "direction");
2100
2101 if (FRS_move_active_lineset(&view_layer->freestyle_config, dir)) {
2104 }
2105
2106 return OPERATOR_FINISHED;
2107}
2108
2109void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot)
2110{
2111 static const EnumPropertyItem direction_items[] = {
2112 {-1, "UP", 0, "Up", ""},
2113 {1, "DOWN", 0, "Down", ""},
2114 {0, nullptr, 0, nullptr, nullptr},
2115 };
2116
2117 /* identifiers */
2118 ot->name = "Move Line Set";
2119 ot->idname = "SCENE_OT_freestyle_lineset_move";
2120 ot->description = "Change the position of the active line set within the list of line sets";
2121
2122 /* API callbacks. */
2123 ot->exec = freestyle_lineset_move_exec;
2124 ot->poll = freestyle_active_lineset_poll;
2125
2126 /* flags */
2128
2129 /* props */
2130 RNA_def_enum(ot->srna,
2131 "direction",
2132 direction_items,
2133 0,
2134 "Direction",
2135 "Direction to move the active line set towards");
2136}
2137
2139
2140/* -------------------------------------------------------------------- */
2143
2144static wmOperatorStatus freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
2145{
2146 Main *bmain = CTX_data_main(C);
2147 ViewLayer *view_layer = CTX_data_view_layer(C);
2149
2150 if (!lineset) {
2151 BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
2152 return OPERATOR_CANCELLED;
2153 }
2154 if (lineset->linestyle) {
2155 id_us_min(&lineset->linestyle->id);
2156 lineset->linestyle = (FreestyleLineStyle *)BKE_id_copy(bmain, &lineset->linestyle->id);
2157 }
2158 else {
2159 lineset->linestyle = BKE_linestyle_new(bmain, DATA_("LineStyle"));
2160 }
2161 DEG_id_tag_update(&lineset->linestyle->id, 0);
2163
2164 return OPERATOR_FINISHED;
2165}
2166
2167void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot)
2168{
2169 /* identifiers */
2170 ot->name = "New Line Style";
2171 ot->idname = "SCENE_OT_freestyle_linestyle_new";
2172 ot->description = "Create a new line style, reusable by multiple line sets";
2173
2174 /* API callbacks. */
2175 ot->exec = freestyle_linestyle_new_exec;
2176 ot->poll = freestyle_active_lineset_poll;
2177
2178 /* flags */
2180}
2181
2183
2184/* -------------------------------------------------------------------- */
2187
2188static wmOperatorStatus freestyle_color_modifier_add_exec(bContext *C, wmOperator *op)
2189{
2190 ViewLayer *view_layer = CTX_data_view_layer(C);
2192 int type = RNA_enum_get(op->ptr, "type");
2193
2194 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2195 return OPERATOR_CANCELLED;
2196 }
2197
2198 if (BKE_linestyle_color_modifier_add(lineset->linestyle, nullptr, type) == nullptr) {
2199 BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type");
2200 return OPERATOR_CANCELLED;
2201 }
2202 DEG_id_tag_update(&lineset->linestyle->id, 0);
2204
2205 return OPERATOR_FINISHED;
2206}
2207
2208void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot)
2209{
2210 /* identifiers */
2211 ot->name = "Add Line Color Modifier";
2212 ot->idname = "SCENE_OT_freestyle_color_modifier_add";
2213 ot->description =
2214 "Add a line color modifier to the line style associated with the active lineset";
2215
2216 /* API callbacks. */
2217 ot->invoke = WM_menu_invoke;
2218 ot->exec = freestyle_color_modifier_add_exec;
2219 ot->poll = freestyle_active_lineset_poll;
2220
2221 /* flags */
2223
2224 /* properties */
2225 ot->prop = RNA_def_enum(
2226 ot->srna, "type", rna_enum_linestyle_color_modifier_type_items, 0, "Type", "");
2227}
2228
2230
2231/* -------------------------------------------------------------------- */
2234
2235static wmOperatorStatus freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op)
2236{
2237 ViewLayer *view_layer = CTX_data_view_layer(C);
2239 int type = RNA_enum_get(op->ptr, "type");
2240
2241 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2242 return OPERATOR_CANCELLED;
2243 }
2244
2245 if (BKE_linestyle_alpha_modifier_add(lineset->linestyle, nullptr, type) == nullptr) {
2246 BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
2247 return OPERATOR_CANCELLED;
2248 }
2249 DEG_id_tag_update(&lineset->linestyle->id, 0);
2251
2252 return OPERATOR_FINISHED;
2253}
2254
2255void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot)
2256{
2257 /* identifiers */
2258 ot->name = "Add Alpha Transparency Modifier";
2259 ot->idname = "SCENE_OT_freestyle_alpha_modifier_add";
2260 ot->description =
2261 "Add an alpha transparency modifier to the line style associated with the active lineset";
2262
2263 /* API callbacks. */
2264 ot->invoke = WM_menu_invoke;
2265 ot->exec = freestyle_alpha_modifier_add_exec;
2266 ot->poll = freestyle_active_lineset_poll;
2267
2268 /* flags */
2270
2271 /* properties */
2272 ot->prop = RNA_def_enum(
2273 ot->srna, "type", rna_enum_linestyle_alpha_modifier_type_items, 0, "Type", "");
2274}
2275
2277
2278/* -------------------------------------------------------------------- */
2281
2282static wmOperatorStatus freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op)
2283{
2284 ViewLayer *view_layer = CTX_data_view_layer(C);
2286 int type = RNA_enum_get(op->ptr, "type");
2287
2288 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2289 return OPERATOR_CANCELLED;
2290 }
2291
2292 if (BKE_linestyle_thickness_modifier_add(lineset->linestyle, nullptr, type) == nullptr) {
2293 BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
2294 return OPERATOR_CANCELLED;
2295 }
2296 DEG_id_tag_update(&lineset->linestyle->id, 0);
2298
2299 return OPERATOR_FINISHED;
2300}
2301
2302void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot)
2303{
2304 /* identifiers */
2305 ot->name = "Add Line Thickness Modifier";
2306 ot->idname = "SCENE_OT_freestyle_thickness_modifier_add";
2307 ot->description =
2308 "Add a line thickness modifier to the line style associated with the active lineset";
2309
2310 /* API callbacks. */
2311 ot->invoke = WM_menu_invoke;
2312 ot->exec = freestyle_thickness_modifier_add_exec;
2313 ot->poll = freestyle_active_lineset_poll;
2314
2315 /* flags */
2317
2318 /* properties */
2319 ot->prop = RNA_def_enum(
2320 ot->srna, "type", rna_enum_linestyle_thickness_modifier_type_items, 0, "Type", "");
2321}
2322
2324
2325/* -------------------------------------------------------------------- */
2328
2329static wmOperatorStatus freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op)
2330{
2331 ViewLayer *view_layer = CTX_data_view_layer(C);
2333 int type = RNA_enum_get(op->ptr, "type");
2334
2335 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2336 return OPERATOR_CANCELLED;
2337 }
2338
2339 if (BKE_linestyle_geometry_modifier_add(lineset->linestyle, nullptr, type) == nullptr) {
2340 BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
2341 return OPERATOR_CANCELLED;
2342 }
2343 DEG_id_tag_update(&lineset->linestyle->id, 0);
2345
2346 return OPERATOR_FINISHED;
2347}
2348
2349void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot)
2350{
2351 /* identifiers */
2352 ot->name = "Add Stroke Geometry Modifier";
2353 ot->idname = "SCENE_OT_freestyle_geometry_modifier_add";
2354 ot->description =
2355 "Add a stroke geometry modifier to the line style associated with the active lineset";
2356
2357 /* API callbacks. */
2358 ot->invoke = WM_menu_invoke;
2359 ot->exec = freestyle_geometry_modifier_add_exec;
2360 ot->poll = freestyle_active_lineset_poll;
2361
2362 /* flags */
2364
2365 /* properties */
2366 ot->prop = RNA_def_enum(
2367 ot->srna, "type", rna_enum_linestyle_geometry_modifier_type_items, 0, "Type", "");
2368}
2369
2371
2372/* -------------------------------------------------------------------- */
2375
2376static int freestyle_get_modifier_type(PointerRNA *ptr)
2377{
2378 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier)) {
2380 }
2381 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier)) {
2383 }
2384 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier)) {
2386 }
2387 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier)) {
2389 }
2390 return -1;
2391}
2392
2393static wmOperatorStatus freestyle_modifier_remove_exec(bContext *C, wmOperator *op)
2394{
2395 ViewLayer *view_layer = CTX_data_view_layer(C);
2397 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
2398 LineStyleModifier *modifier = static_cast<LineStyleModifier *>(ptr.data);
2399
2400 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2401 return OPERATOR_CANCELLED;
2402 }
2403
2404 switch (freestyle_get_modifier_type(&ptr)) {
2407 break;
2410 break;
2413 break;
2416 break;
2417 default:
2418 BKE_report(
2419 op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
2420 return OPERATOR_CANCELLED;
2421 }
2422 DEG_id_tag_update(&lineset->linestyle->id, 0);
2424
2425 return OPERATOR_FINISHED;
2426}
2427
2428void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot)
2429{
2430 /* identifiers */
2431 ot->name = "Remove Modifier";
2432 ot->idname = "SCENE_OT_freestyle_modifier_remove";
2433 ot->description = "Remove the modifier from the list of modifiers";
2434
2435 /* API callbacks. */
2436 ot->exec = freestyle_modifier_remove_exec;
2437 ot->poll = freestyle_active_lineset_poll;
2438
2439 /* flags */
2441}
2442
2444
2445/* -------------------------------------------------------------------- */
2448
2449static wmOperatorStatus freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
2450{
2451 ViewLayer *view_layer = CTX_data_view_layer(C);
2453 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
2454 LineStyleModifier *modifier = static_cast<LineStyleModifier *>(ptr.data);
2455
2456 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2457 return OPERATOR_CANCELLED;
2458 }
2459
2460 switch (freestyle_get_modifier_type(&ptr)) {
2462 BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
2463 break;
2465 BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
2466 break;
2468 BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
2469 break;
2471 BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
2472 break;
2473 default:
2474 BKE_report(
2475 op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
2476 return OPERATOR_CANCELLED;
2477 }
2478 DEG_id_tag_update(&lineset->linestyle->id, 0);
2480
2481 return OPERATOR_FINISHED;
2482}
2483
2484void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot)
2485{
2486 /* identifiers */
2487 ot->name = "Copy Modifier";
2488 ot->idname = "SCENE_OT_freestyle_modifier_copy";
2489 ot->description = "Duplicate the modifier within the list of modifiers";
2490
2491 /* API callbacks. */
2492 ot->exec = freestyle_modifier_copy_exec;
2493 ot->poll = freestyle_active_lineset_poll;
2494
2495 /* flags */
2497}
2498
2500
2501/* -------------------------------------------------------------------- */
2504
2505static wmOperatorStatus freestyle_modifier_move_exec(bContext *C, wmOperator *op)
2506{
2507 ViewLayer *view_layer = CTX_data_view_layer(C);
2509 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
2510 LineStyleModifier *modifier = static_cast<LineStyleModifier *>(ptr.data);
2511 int dir = RNA_enum_get(op->ptr, "direction");
2512 bool changed = false;
2513
2514 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
2515 return OPERATOR_CANCELLED;
2516 }
2517
2518 switch (freestyle_get_modifier_type(&ptr)) {
2520 changed = BKE_linestyle_color_modifier_move(lineset->linestyle, modifier, dir);
2521 break;
2523 changed = BKE_linestyle_alpha_modifier_move(lineset->linestyle, modifier, dir);
2524 break;
2526 changed = BKE_linestyle_thickness_modifier_move(lineset->linestyle, modifier, dir);
2527 break;
2529 changed = BKE_linestyle_geometry_modifier_move(lineset->linestyle, modifier, dir);
2530 break;
2531 default:
2532 BKE_report(
2533 op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
2534 return OPERATOR_CANCELLED;
2535 }
2536
2537 if (changed) {
2538 DEG_id_tag_update(&lineset->linestyle->id, 0);
2540 }
2541
2542 return OPERATOR_FINISHED;
2543}
2544
2545void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot)
2546{
2547 static const EnumPropertyItem direction_items[] = {
2548 {-1, "UP", 0, "Up", ""},
2549 {1, "DOWN", 0, "Down", ""},
2550 {0, nullptr, 0, nullptr, nullptr},
2551 };
2552
2553 /* identifiers */
2554 ot->name = "Move Modifier";
2555 ot->idname = "SCENE_OT_freestyle_modifier_move";
2556 ot->description = "Move the modifier within the list of modifiers";
2557
2558 /* API callbacks. */
2559 ot->exec = freestyle_modifier_move_exec;
2560 ot->poll = freestyle_active_lineset_poll;
2561
2562 /* flags */
2564
2565 /* props */
2566 RNA_def_enum(ot->srna,
2567 "direction",
2568 direction_items,
2569 0,
2570 "Direction",
2571 "Direction to move the chosen modifier towards");
2572}
2573
2575
2576/* -------------------------------------------------------------------- */
2579
2580static wmOperatorStatus freestyle_stroke_material_create_exec(bContext *C, wmOperator *op)
2581{
2582 Main *bmain = CTX_data_main(C);
2583 ViewLayer *view_layer = CTX_data_view_layer(C);
2585
2586 if (!linestyle) {
2587 BKE_report(op->reports, RPT_ERROR, "No active line style in the current scene");
2588 return OPERATOR_CANCELLED;
2589 }
2590
2591 FRS_create_stroke_material(bmain, linestyle);
2592
2593 return OPERATOR_FINISHED;
2594}
2595
2596void SCENE_OT_freestyle_stroke_material_create(wmOperatorType *ot)
2597{
2598 /* identifiers */
2599 ot->name = "Create Freestyle Stroke Material";
2600 ot->idname = "SCENE_OT_freestyle_stroke_material_create";
2601 ot->description = "Create Freestyle stroke material for testing";
2602
2603 /* API callbacks. */
2604 ot->exec = freestyle_stroke_material_create_exec;
2605
2606 /* flags */
2607 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2608}
2609
2611
2612#endif /* WITH_FREESTYLE */
2613
2614/* -------------------------------------------------------------------- */
2617
2619{
2620 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
2621
2622 if (id) {
2623 MTex **mtex_ar, *mtexswap;
2624 short act;
2625 int type = RNA_enum_get(op->ptr, "type");
2626 AnimData *adt = BKE_animdata_from_id(id);
2627
2628 give_active_mtex(id, &mtex_ar, &act);
2629
2630 if (type == -1) { /* Up */
2631 if (act > 0) {
2632 mtexswap = mtex_ar[act];
2633 mtex_ar[act] = mtex_ar[act - 1];
2634 mtex_ar[act - 1] = mtexswap;
2635
2637 id, adt, nullptr, "texture_slots", nullptr, nullptr, act - 1, -1, false);
2639 id, adt, nullptr, "texture_slots", nullptr, nullptr, act, act - 1, false);
2641 id, adt, nullptr, "texture_slots", nullptr, nullptr, -1, act, false);
2642
2643 set_active_mtex(id, act - 1);
2644 }
2645 }
2646 else { /* Down */
2647 if (act < MAX_MTEX - 1) {
2648 mtexswap = mtex_ar[act];
2649 mtex_ar[act] = mtex_ar[act + 1];
2650 mtex_ar[act + 1] = mtexswap;
2651
2653 id, adt, nullptr, "texture_slots", nullptr, nullptr, act + 1, -1, false);
2655 id, adt, nullptr, "texture_slots", nullptr, nullptr, act, act + 1, false);
2657 id, adt, nullptr, "texture_slots", nullptr, nullptr, -1, act, false);
2658
2659 set_active_mtex(id, act + 1);
2660 }
2661 }
2662
2663 DEG_id_tag_update(id, 0);
2665 }
2666
2667 return OPERATOR_FINISHED;
2668}
2669
2671{
2672 static const EnumPropertyItem slot_move[] = {
2673 {-1, "UP", 0, "Up", ""},
2674 {1, "DOWN", 0, "Down", ""},
2675 {0, nullptr, 0, nullptr, nullptr},
2676 };
2677
2678 /* identifiers */
2679 ot->name = "Move Texture Slot";
2680 ot->idname = "TEXTURE_OT_slot_move";
2681 ot->description = "Move texture slots up and down";
2682
2683 /* API callbacks. */
2684 ot->exec = texture_slot_move_exec;
2685
2686 /* flags */
2688
2689 RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
2690}
2691
2693
2694/* -------------------------------------------------------------------- */
2697
2699{
2700 using namespace blender::bke::blendfile;
2701
2702 Material *ma = static_cast<Material *>(
2703 CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
2704
2705 if (ma == nullptr) {
2706 return OPERATOR_CANCELLED;
2707 }
2708
2709 Main *bmain = CTX_data_main(C);
2711
2712 /* Add the material to the copybuffer (and all of its dependencies). */
2713 copybuffer.id_add(
2714 &ma->id,
2715 PartialWriteContext::IDAddOptions{(PartialWriteContext::IDAddOperations::SET_FAKE_USER |
2716 PartialWriteContext::IDAddOperations::SET_CLIPBOARD_MARK |
2717 PartialWriteContext::IDAddOperations::ADD_DEPENDENCIES)},
2718 nullptr);
2719
2720 char filepath[FILE_MAX];
2721 material_copybuffer_filepath_get(filepath, sizeof(filepath));
2722 copybuffer.write(filepath, *op->reports);
2723
2724 /* We are all done! */
2725 BKE_report(op->reports, RPT_INFO, "Copied material to internal clipboard");
2726
2727 return OPERATOR_FINISHED;
2728}
2729
2731{
2732 /* identifiers */
2733 ot->name = "Copy Material";
2734 ot->idname = "MATERIAL_OT_copy";
2735 ot->description = "Copy the material settings and nodes";
2736
2737 /* API callbacks. */
2738 ot->exec = copy_material_exec;
2739
2740 /* flags */
2741 /* no undo needed since no changes are made to the material */
2743}
2744
2746
2747/* -------------------------------------------------------------------- */
2750
2755{
2756 if (cb_data->cb_flag & IDWALK_CB_USER) {
2757 id_us_min(*cb_data->id_pointer);
2758 }
2759 *cb_data->id_pointer = nullptr;
2760 return IDWALK_RET_NOP;
2761}
2762
2767{
2768 Main *bmain = static_cast<Main *>(cb_data->user_data);
2769 ID **id_p = cb_data->id_pointer;
2770 if (*id_p) {
2771 if (cb_data->cb_flag & IDWALK_CB_USER) {
2772 id_us_min(*id_p);
2773 }
2774 ListBase *lb = which_libbase(bmain, GS((*id_p)->name));
2775 ID *id_local = static_cast<ID *>(
2776 BLI_findstring(lb, (*id_p)->name + 2, offsetof(ID, name) + 2));
2777 *id_p = id_local;
2778 if (cb_data->cb_flag & IDWALK_CB_USER) {
2779 id_us_plus(id_local);
2780 }
2781 else if (cb_data->cb_flag & IDWALK_CB_USER_ONE) {
2782 id_us_ensure_real(id_local);
2783 }
2784 id_lib_extern(id_local);
2785 }
2786 return IDWALK_RET_NOP;
2787}
2788
2790{
2791 Main *bmain = CTX_data_main(C);
2792 Material *ma = static_cast<Material *>(
2793 CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
2794
2795 if (ma == nullptr) {
2796 BKE_report(op->reports, RPT_WARNING, "Cannot paste without a material");
2797 return OPERATOR_CANCELLED;
2798 }
2799
2800 /* Read copy buffer .blend file. */
2801 char filepath[FILE_MAX];
2802 Main *temp_bmain = BKE_main_new();
2803
2805
2806 material_copybuffer_filepath_get(filepath, sizeof(filepath));
2807
2808 /* NOTE(@ideasman42) The node tree might reference different kinds of ID types.
2809 * It's not clear-cut which ID types should be included, although it's unlikely
2810 * users would want an entire scene & it's objects to be included.
2811 * Filter a subset of ID types with some reasons for including them. */
2812 const uint64_t ntree_filter = (
2813 /* Material is necessary for reading the clipboard. */
2814 FILTER_ID_MA |
2815 /* Node-groups. */
2816 FILTER_ID_NT |
2817 /* Image textures. */
2818 FILTER_ID_IM |
2819 /* Internal text (scripts). */
2821 /* Texture coordinates may reference objects.
2822 * Note that object data is *not* included. */
2823 FILTER_ID_OB);
2824
2825 if (!BKE_copybuffer_read(temp_bmain, filepath, op->reports, ntree_filter)) {
2826 BKE_report(op->reports, RPT_ERROR, "Internal clipboard is empty");
2827 BKE_main_free(temp_bmain);
2828 return OPERATOR_CANCELLED;
2829 }
2830
2831 /* There may be multiple materials,
2832 * check for a property that marks this as the active material. */
2833 Material *ma_from = nullptr;
2834 LISTBASE_FOREACH (Material *, ma_iter, &temp_bmain->materials) {
2835 if (ma_iter->id.flag & ID_FLAG_CLIPBOARD_MARK) {
2836 ma_from = ma_iter;
2837 break;
2838 }
2839 }
2840
2841 /* Make sure data from this file is usable for material paste. */
2842 if (ma_from == nullptr) {
2843 BKE_report(op->reports, RPT_ERROR, "Internal clipboard is not from a material");
2844 BKE_main_free(temp_bmain);
2845 return OPERATOR_CANCELLED;
2846 }
2847
2848 /* Keep animation by moving local animation to the paste node-tree. */
2849 if (ma->nodetree && ma_from->nodetree) {
2850 BLI_assert(ma_from->nodetree->adt == nullptr);
2851 std::swap(ma->nodetree->adt, ma_from->nodetree->adt);
2852 }
2853
2854 /* Needed to update #SpaceNode::nodetree else a stale pointer is used. */
2855 if (ma->nodetree) {
2856 bNodeTree *nodetree = ma->nodetree;
2858
2859 /* Free & clear data here, so user counts are handled, otherwise it's
2860 * freed as part of #BKE_main_free which doesn't handle user-counts. */
2861 /* Walk over all the embedded nodes ID's (non-recursively). */
2863 bmain, &nodetree->id, paste_material_nodetree_ids_decref, nullptr, IDWALK_NOP);
2864
2866 MEM_freeN(nodetree);
2867 ma->nodetree = nullptr;
2868 }
2869
2870/* Swap data-block content, while swapping isn't always needed,
2871 * it means memory is properly freed in the case of allocations.. */
2872#define SWAP_MEMBER(member) std::swap(ma->member, ma_from->member)
2873
2874 /* Intentionally skip:
2875 * - Texture painting slots.
2876 * - Preview render.
2877 * - Grease pencil styles (we could although they reference many ID's themselves).
2878 */
2880 SWAP_MEMBER(r);
2881 SWAP_MEMBER(g);
2882 SWAP_MEMBER(b);
2883 SWAP_MEMBER(a);
2884 SWAP_MEMBER(specr);
2885 SWAP_MEMBER(specg);
2886 SWAP_MEMBER(specb);
2887 SWAP_MEMBER(spec);
2888 SWAP_MEMBER(roughness);
2889 SWAP_MEMBER(metallic);
2890 SWAP_MEMBER(use_nodes);
2891 SWAP_MEMBER(index);
2892 SWAP_MEMBER(nodetree);
2893 SWAP_MEMBER(line_col);
2894 SWAP_MEMBER(line_priority);
2895 SWAP_MEMBER(vcol_alpha);
2896
2897 SWAP_MEMBER(alpha_threshold);
2898 SWAP_MEMBER(refract_depth);
2899 SWAP_MEMBER(blend_method);
2900 SWAP_MEMBER(blend_shadow);
2901 SWAP_MEMBER(blend_flag);
2902
2903 SWAP_MEMBER(lineart);
2904
2905#undef SWAP_MEMBER
2906
2907 /* The node-tree from the clipboard is now assigned to the local material,
2908 * however the ID's it references are still part of `temp_bmain`.
2909 * These data-blocks references must be cleared or replaces with references to `bmain`.
2910 * TODO(@ideasman42): support merging indirectly referenced data-blocks besides the material,
2911 * this would be useful for pasting materials with node-groups between files. */
2912 if (ma->nodetree) {
2913 /* This implicitly points to local data, assign after remapping. */
2914 ma->nodetree->owner_id = nullptr;
2915
2916 /* Map remote ID's to local ones. */
2919
2920 ma->nodetree->owner_id = &ma->id;
2921 }
2922 BKE_main_free(temp_bmain);
2923
2924 /* Important to run this when the embedded tree if freed,
2925 * otherwise the depsgraph holds a reference to the (now freed) `ma->nodetree`.
2926 * Also run this when a new node-tree is set to ensure it's accounted for.
2927 * This also applies to animation data which is likely to be stored in the depsgraph.
2928 * Always call instead of checking when it *might* be needed. */
2930
2931 /* There are some custom updates to the node tree above, better do a full update pass. */
2934
2937
2938 return OPERATOR_FINISHED;
2939}
2940
2942{
2943 /* identifiers */
2944 ot->name = "Paste Material";
2945 ot->idname = "MATERIAL_OT_paste";
2946 ot->description = "Paste the material settings and nodes";
2947
2948 /* API callbacks. */
2949 ot->exec = paste_material_exec;
2951
2952 /* flags */
2954}
2955
2957
2958/* -------------------------------------------------------------------- */
2961
2962static short mtexcopied = 0; /* must be reset on file load */
2964
2966{ /* use for file reload */
2967 mtexcopied = 0;
2968}
2969
2970static void copy_mtex_copybuf(ID *id)
2971{
2972 MTex **mtex = nullptr;
2973
2974 switch (GS(id->name)) {
2975 case ID_PA:
2976 mtex = &(((ParticleSettings *)id)->mtex[int(((ParticleSettings *)id)->texact)]);
2977 break;
2978 case ID_LS:
2979 mtex = &(((FreestyleLineStyle *)id)->mtex[int(((FreestyleLineStyle *)id)->texact)]);
2980 break;
2981 default:
2982 break;
2983 }
2984
2985 if (mtex && *mtex) {
2986 mtexcopybuf = blender::dna::shallow_copy(**mtex);
2987 mtexcopied = 1;
2988 }
2989 else {
2990 mtexcopied = 0;
2991 }
2992}
2993
2994static void paste_mtex_copybuf(ID *id)
2995{
2996 MTex **mtex = nullptr;
2997
2998 if (mtexcopied == 0 || mtexcopybuf.tex == nullptr) {
2999 return;
3000 }
3001
3002 switch (GS(id->name)) {
3003 case ID_PA:
3004 mtex = &(((ParticleSettings *)id)->mtex[int(((ParticleSettings *)id)->texact)]);
3005 break;
3006 case ID_LS:
3007 mtex = &(((FreestyleLineStyle *)id)->mtex[int(((FreestyleLineStyle *)id)->texact)]);
3008 break;
3009 default:
3010 BLI_assert_msg(0, "invalid id type");
3011 return;
3012 }
3013
3014 if (mtex) {
3015 if (*mtex == nullptr) {
3016 *mtex = MEM_callocN<MTex>("mtex copy");
3017 }
3018 else if ((*mtex)->tex) {
3019 id_us_min(&(*mtex)->tex->id);
3020 }
3021
3022 **mtex = blender::dna::shallow_copy(mtexcopybuf);
3023
3024 /* NOTE(@ideasman42): the simple memory copy has no special handling for ID data-blocks.
3025 * Ideally this would use `BKE_copybuffer_*` API's, however for common using
3026 * copy-pasting between slots, the case a users expects to copy between files
3027 * seems quite niche. So, do primitive ID validation. */
3028
3029 /* WARNING: This isn't a fool-proof solution as it's possible memory locations are reused,
3030 * or that the ID was relocated in memory since it was copied.
3031 * it does however guard against references to dangling pointers. */
3032 if ((*mtex)->tex && (BLI_findindex(&G_MAIN->textures, (*mtex)->tex) == -1)) {
3033 (*mtex)->tex = nullptr;
3034 }
3035 if ((*mtex)->object && (BLI_findindex(&G_MAIN->objects, (*mtex)->object) == -1)) {
3036 (*mtex)->object = nullptr;
3037 }
3038 id_us_plus((ID *)(*mtex)->tex);
3039 id_lib_extern((ID *)(*mtex)->object);
3040 }
3041}
3042
3044
3045/* -------------------------------------------------------------------- */
3048
3050{
3051 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
3052
3053 if (id == nullptr) {
3054 /* copying empty slot */
3056 return OPERATOR_CANCELLED;
3057 }
3058
3060
3061 return OPERATOR_FINISHED;
3062}
3063
3065{
3066 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
3067
3068 return (id != nullptr);
3069}
3070
3072{
3073 /* identifiers */
3074 ot->name = "Copy Texture Slot Settings";
3075 ot->idname = "TEXTURE_OT_slot_copy";
3076 ot->description = "Copy the material texture settings and nodes";
3077
3078 /* API callbacks. */
3079 ot->exec = copy_mtex_exec;
3080 ot->poll = copy_mtex_poll;
3081
3082 /* flags */
3083 /* no undo needed since no changes are made to the mtex */
3085}
3086
3088
3089/* -------------------------------------------------------------------- */
3092
3094{
3095 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id;
3096
3097 if (id == nullptr) {
3098 Material *ma = static_cast<Material *>(
3099 CTX_data_pointer_get_type(C, "material", &RNA_Material).data);
3100 Light *la = static_cast<Light *>(CTX_data_pointer_get_type(C, "light", &RNA_Light).data);
3101 World *wo = static_cast<World *>(CTX_data_pointer_get_type(C, "world", &RNA_World).data);
3102 ParticleSystem *psys = static_cast<ParticleSystem *>(
3103 CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data);
3104 FreestyleLineStyle *linestyle = static_cast<FreestyleLineStyle *>(
3105 CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data);
3106
3107 if (ma) {
3108 id = &ma->id;
3109 }
3110 else if (la) {
3111 id = &la->id;
3112 }
3113 else if (wo) {
3114 id = &wo->id;
3115 }
3116 else if (psys) {
3117 id = &psys->part->id;
3118 }
3119 else if (linestyle) {
3120 id = &linestyle->id;
3121 }
3122
3123 if (id == nullptr) {
3124 return OPERATOR_CANCELLED;
3125 }
3126 }
3127
3129
3131
3132 return OPERATOR_FINISHED;
3133}
3134
3136{
3137 /* identifiers */
3138 ot->name = "Paste Texture Slot Settings";
3139 ot->idname = "TEXTURE_OT_slot_paste";
3140 ot->description = "Copy the texture settings and nodes";
3141
3142 /* API callbacks. */
3143 ot->exec = paste_mtex_exec;
3144
3145 /* flags */
3147}
3148
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:82
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:1249
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)
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:423
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:61
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:285
void id_us_plus(ID *id)
Definition lib_id.cc:353
@ LIB_ID_COPY_ACTIONS
@ LIB_ID_COPY_DEFAULT
void BKE_id_move_to_same_lib(Main &bmain, ID &id, const ID &owner_id)
Definition lib_id.cc:869
void id_us_ensure_real(ID *id)
Definition lib_id.cc:308
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
Definition lib_id.cc:767
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:772
void id_us_min(ID *id)
Definition lib_id.cc:361
@ IDWALK_CB_USER_ONE
@ IDWALK_CB_USER
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, LibraryForeachIDFlag flag)
Definition lib_query.cc:431
@ IDWALK_RET_NOP
@ IDWALK_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:693
int BKE_linestyle_alpha_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier)
int BKE_linestyle_color_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier)
Definition linestyle.cc:920
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:990
FreestyleLineStyle * BKE_linestyle_active_from_view_layer(struct ViewLayer *view_layer)
Definition linestyle.cc:704
LineStyleModifier * BKE_linestyle_color_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type)
Definition linestyle.cc:770
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:828
#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:882
Main * BKE_main_new()
Definition main.cc:48
void BKE_main_free(Main *bmain)
Definition main.cc:175
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:872
const char * BKE_main_blendfile_path_from_global()
Definition main.cc:877
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
General operations, lookup, etc. for materials.
short * BKE_object_material_len_p(Object *ob)
Material ** BKE_object_material_get_p(Object *ob, short act)
void BKE_object_material_remap(Object *ob, const unsigned int *remap)
Material * BKE_gpencil_material_add(Main *bmain, const char *name)
bool BKE_object_material_slot_add(Main *bmain, Object *ob, bool set_active=true)
void BKE_object_material_array_assign(Main *bmain, Object *ob, Material ***matar, int totcol, bool to_object_only)
Material * BKE_material_add(Main *bmain, const char *name)
bool BKE_object_material_slot_used(Object *object, short actcol)
Material * BKE_object_material_get(Object *ob, short act)
int BKE_object_material_index_get_with_hint(Object *ob, const Material *ma, int hint_index)
Material *** BKE_object_material_array_p(Object *ob)
bool BKE_object_material_slot_remove(Main *bmain, Object *ob)
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:126
bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv)
Definition scene.cc:2728
SceneRenderView * BKE_scene_add_render_view(Scene *sce, const char *name)
Definition scene.cc:2709
bool give_active_mtex(struct ID *id, struct MTex ***mtex_ar, short *act)
Definition texture.cc:484
void set_active_mtex(struct ID *id, short act)
Definition texture.cc:510
struct Tex * BKE_texture_add(struct Main *bmain, const char *name)
Definition texture.cc:374
int BKE_vfont_select_get(const Curve *cu, int *r_start, int *r_end)
Definition vfont.cc:404
struct World * BKE_world_add(struct Main *bmain, const char *name)
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:608
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
void range_vn_u(unsigned int *array_tar, int size, unsigned int start)
#define FILE_MAX
#define BLI_path_join(...)
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
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.
@ ID_FLAG_CLIPBOARD_MARK
Definition DNA_ID.h:712
@ ID_RECALC_SHADING
Definition DNA_ID.h:1002
@ ID_RECALC_SELECT
Definition DNA_ID.h:1009
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:982
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1012
@ ID_LS
@ ID_PA
@ 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_LIGHTPROBE
#define OB_TYPE_SUPPORT_MATERIAL(_type)
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
bool EDBM_deselect_by_material(BMEditMesh *em, short index, bool select)
void ED_node_shader_default(const bContext *C, ID *id)
Definition node_edit.cc:574
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)
void ED_undo_push_op(bContext *C, wmOperator *op)
Definition ed_undo.cc:358
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.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:330
#define C
Definition RandGen.cpp:29
#define MAX_MTEX
Definition Stroke.h:31
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:1752
#define NC_WORLD
Definition WM_types.hh:384
#define NC_GEOM
Definition WM_types.hh:390
#define ND_DRAW
Definition WM_types.hh:458
#define ND_DATA
Definition WM_types.hh:506
#define NC_LINESTYLE
Definition WM_types.hh:397
#define ND_RENDER_OPTIONS
Definition WM_types.hh:432
@ OPTYPE_INTERNAL
Definition WM_types.hh:202
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define ND_SHADING_PREVIEW
Definition WM_types.hh:477
#define NC_SCENE
Definition WM_types.hh:375
#define NA_ADDED
Definition WM_types.hh:583
#define ND_TOOLSETTINGS
Definition WM_types.hh:446
ReportList * reports
Definition WM_types.hh:1025
#define NC_MATERIAL
Definition WM_types.hh:377
#define ND_SELECT
Definition WM_types.hh:505
#define NC_TEXTURE
Definition WM_types.hh:378
#define ND_LAYER
Definition WM_types.hh:447
#define ND_OB_SHADING
Definition WM_types.hh:454
#define NC_OBJECT
Definition WM_types.hh:376
#define ND_SHADING_LINKS
Definition WM_types.hh:476
@ BM_ELEM_SELECT
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
BMesh const char void * data
unsigned long long int uint64_t
bool add_as(ForwardKey &&key)
Definition BLI_set.hh:256
bool contains_as(const ForwardKey &key) const
Definition BLI_set.hh:314
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)
#define SELECT
#define offsetof(t, d)
bool ED_curve_nurb_select_check(const View3D *v3d, const Nurb *nu)
void * EEVEE_lightbake_job_data_alloc(Main *bmain, ViewLayer *view_layer, Scene *scene, blender::Vector< Object * > original_probes, std::string &report, int frame)
void EEVEE_lightbake_job(void *job_data, wmJobWorkerStatus *worker_status)
void EEVEE_lightbake_job_data_free(void *job_data)
wmJob * EEVEE_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_lightbake_update(void *job_data)
#define select(A, B, C)
#define FILTER_ID_OB
#define FILTER_ID_MA
#define ID_IS_LINKED(_id)
#define ID_IS_EDITABLE(_id)
#define MAX_NAME
#define ID_IS_OVERRIDE_LIBRARY(_id)
#define FILTER_ID_IM
#define GS(a)
#define FILTER_ID_NT
#define FILTER_ID_TXT
RenderEngineType * RE_engines_find(const char *idname)
RenderEngine * RE_engine_create(RenderEngineType *type)
void RE_engine_free(RenderEngine *engine)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
void node_tree_free_embedded_tree(bNodeTree *ntree)
Definition node.cc:4724
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:796
void ED_render_clear_mtex_copybuf()
static wmOperatorStatus material_slot_assign_exec(bContext *C, wmOperator *)
void OBJECT_OT_material_slot_remove_all(wmOperatorType *ot)
static wmOperatorStatus render_view_remove_exec(bContext *C, wmOperator *)
void OBJECT_OT_material_slot_add(wmOperatorType *ot)
static wmOperatorStatus paste_mtex_exec(bContext *C, wmOperator *)
void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
static wmOperatorStatus copy_material_exec(bContext *C, wmOperator *op)
static wmOperatorStatus material_slot_remove_all_exec(bContext *C, wmOperator *op)
static wmOperatorStatus lightprobe_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *)
static blender::Vector< Object * > lightprobe_cache_irradiance_volume_subset_get(bContext *C, wmOperator *op)
static wmOperatorStatus view_layer_remove_unused_lightgroups_exec(bContext *C, wmOperator *)
static wmOperatorStatus lightprobe_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *event)
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 wmOperatorStatus new_material_exec(bContext *C, wmOperator *)
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 wmOperatorStatus material_slot_remove_unused_exec(bContext *C, wmOperator *op)
static wmOperatorStatus material_slot_copy_exec(bContext *C, wmOperator *)
static void copy_mtex_copybuf(ID *id)
void OBJECT_OT_lightprobe_cache_bake(wmOperatorType *ot)
static wmOperatorStatus material_slot_select_exec(bContext *C, wmOperator *)
static wmOperatorStatus lightprobe_cache_free_exec(bContext *C, wmOperator *op)
static wmOperatorStatus 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)
void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
static bool object_array_for_shading_edit_mode_disabled_filter(const Object *ob, void *user_data)
static wmOperatorStatus lightprobe_cache_bake_exec(bContext *C, wmOperator *op)
void MATERIAL_OT_paste(wmOperatorType *ot)
static wmOperatorStatus material_slot_deselect_exec(bContext *C, wmOperator *)
static wmOperatorStatus view_layer_add_exec(bContext *C, wmOperator *op)
void MATERIAL_OT_new(wmOperatorType *ot)
void SCENE_OT_view_layer_add(wmOperatorType *ot)
static wmOperatorStatus view_layer_add_lightgroup_exec(bContext *C, wmOperator *op)
void OBJECT_OT_material_slot_move(wmOperatorType *ot)
static wmOperatorStatus view_layer_add_aov_exec(bContext *C, wmOperator *)
void SCENE_OT_view_layer_add_used_lightgroups(wmOperatorType *ot)
void TEXTURE_OT_new(wmOperatorType *ot)
static bool render_view_remove_poll(bContext *C)
static bool object_materials_supported_poll(bContext *C)
@ LIGHTCACHE_SUBSET_ACTIVE
@ LIGHTCACHE_SUBSET_SELECTED
@ LIGHTCACHE_SUBSET_ALL
void MATERIAL_OT_copy(wmOperatorType *ot)
static wmOperatorStatus material_slot_move_exec(bContext *C, wmOperator *op)
static wmOperatorStatus material_slot_remove_exec(bContext *C, wmOperator *op)
static wmOperatorStatus new_texture_exec(bContext *C, wmOperator *op)
void SCENE_OT_view_layer_remove_lightgroup(wmOperatorType *ot)
static int paste_material_nodetree_ids_decref(LibraryIDLinkCallbackData *cb_data)
static wmOperatorStatus render_view_add_exec(bContext *C, wmOperator *)
void TEXTURE_OT_slot_paste(wmOperatorType *ot)
static Vector< Object * > object_array_for_shading_edit_mode_enabled(bContext *C)
static wmOperatorStatus view_layer_remove_lightgroup_exec(bContext *C, wmOperator *)
void SCENE_OT_view_layer_add_aov(wmOperatorType *ot)
static wmOperatorStatus view_layer_remove_exec(bContext *C, wmOperator *)
void TEXTURE_OT_slot_copy(wmOperatorType *ot)
static int paste_material_nodetree_ids_relink_or_clear(LibraryIDLinkCallbackData *cb_data)
static wmOperatorStatus view_layer_remove_aov_exec(bContext *C, wmOperator *)
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 wmOperatorStatus paste_material_exec(bContext *C, wmOperator *op)
void SCENE_OT_view_layer_add_lightgroup(wmOperatorType *ot)
static wmOperatorStatus copy_mtex_exec(bContext *C, wmOperator *)
static wmOperatorStatus material_slot_add_exec(bContext *C, wmOperator *)
static blender::Set< blender::StringRefNull > get_used_lightgroups(Scene *scene)
static void material_copybuffer_filepath_get(char filepath[FILE_MAX], size_t filepath_maxncpy)
static wmOperatorStatus material_slot_de_select(bContext *C, bool select)
static void lightprobe_cache_bake_cancel(bContext *C, wmOperator *op)
void SCENE_OT_render_view_remove(wmOperatorType *ot)
#define SWAP_MEMBER(member)
static wmOperatorStatus view_layer_add_used_lightgroups_exec(bContext *C, wmOperator *)
static bool object_materials_supported_poll_ex(bContext *C, const Object *ob)
static bool copy_mtex_poll(bContext *C)
static wmOperatorStatus texture_slot_move_exec(bContext *C, wmOperator *op)
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[]
short mat_nr
uint8_t f1
struct EditFont * editfont
CharInfo * textbufinfo
Definition BKE_vfont.hh:42
struct FreestyleLineStyle * linestyle
Definition DNA_ID.h:404
LibraryForeachIDCallbackFlag cb_flag
void * last
void * first
char filepath[1024]
Definition BKE_main.hh:155
ListBase materials
Definition BKE_main.hh:251
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:51
void * data
Definition RNA_types.hh:53
char engine[32]
void(* update_render_passes)(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer)
Definition RE_engine.h:111
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
wmEventType type
Definition WM_types.hh:754
struct ReportList * reports
struct PointerRNA * ptr
i
Definition text_draw.cc:230
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:4226
wmOperatorType * ot
Definition wm_files.cc:4225
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition wm_jobs.cc:456
void WM_jobs_kill_type(wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:598
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:224
wmOperatorStatus 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:139