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