Merge branch 'blender2.7'
[blender.git] / source / blender / editors / render / render_shading.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software Foundation,
13  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14  *
15  * The Original Code is Copyright (C) 2009 Blender Foundation.
16  * All rights reserved.
17  */
18
19 /** \file
20  * \ingroup edrend
21  */
22
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "MEM_guardedalloc.h"
27
28 #include "DNA_curve_types.h"
29 #include "DNA_light_types.h"
30 #include "DNA_lightprobe_types.h"
31 #include "DNA_material_types.h"
32 #include "DNA_node_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_particle_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_space_types.h"
37 #include "DNA_world_types.h"
38
39 #include "BLI_utildefines.h"
40 #include "BLI_listbase.h"
41 #include "BLI_math_vector.h"
42
43 #include "BLT_translation.h"
44
45 #include "BKE_animsys.h"
46 #include "BKE_brush.h"
47 #include "BKE_context.h"
48 #include "BKE_curve.h"
49 #include "BKE_editmesh.h"
50 #include "BKE_font.h"
51 #include "BKE_global.h"
52 #include "BKE_image.h"
53 #include "BKE_layer.h"
54 #include "BKE_library.h"
55 #include "BKE_linestyle.h"
56 #include "BKE_main.h"
57 #include "BKE_material.h"
58 #include "BKE_paint.h"
59 #include "BKE_report.h"
60 #include "BKE_scene.h"
61 #include "BKE_texture.h"
62 #include "BKE_workspace.h"
63 #include "BKE_world.h"
64
65 #include "DEG_depsgraph.h"
66 #include "DEG_depsgraph_build.h"
67
68 #ifdef WITH_FREESTYLE
69 #  include "BKE_freestyle.h"
70 #  include "FRS_freestyle.h"
71 #  include "RNA_enum_types.h"
72 #endif
73
74 #include "RNA_access.h"
75
76 #include "WM_api.h"
77 #include "WM_types.h"
78
79 #include "ED_object.h"
80 #include "ED_curve.h"
81 #include "ED_mesh.h"
82 #include "ED_node.h"
83 #include "ED_render.h"
84 #include "ED_scene.h"
85 #include "ED_screen.h"
86
87 #include "RNA_define.h"
88
89 #include "UI_interface.h"
90
91 #include "RE_pipeline.h"
92
93 #include "engines/eevee/eevee_lightcache.h"
94
95 #include "render_intern.h"  // own include
96
97 /**
98  * Object list for material operations.
99  * has exception for pinned object.
100  */
101 static Object **object_array_for_shading(bContext *C, uint *r_objects_len)
102 {
103   ScrArea *sa = CTX_wm_area(C);
104   SpaceProperties *sbuts = NULL;
105   View3D *v3d = NULL;
106   if (sa->spacetype == SPACE_PROPERTIES) {
107     sbuts = sa->spacedata.first;
108   }
109   else if (sa->spacetype == SPACE_VIEW3D) {
110     v3d = sa->spacedata.first;
111   }
112
113   Object **objects;
114   if (sbuts && sbuts->pinid && GS(sbuts->pinid->name) == ID_OB) {
115     objects = MEM_mallocN(sizeof(*objects), __func__);
116     objects[0] = (Object *)sbuts->pinid;
117     *r_objects_len = 1;
118   }
119   else {
120     ViewLayer *view_layer = CTX_data_view_layer(C);
121     objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
122         view_layer, v3d, r_objects_len);
123   }
124   return objects;
125 }
126
127 /********************** material slot operators *********************/
128
129 static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
130 {
131   Main *bmain = CTX_data_main(C);
132   Object *ob = ED_object_context(C);
133
134   if (!ob)
135     return OPERATOR_CANCELLED;
136
137   BKE_object_material_slot_add(bmain, ob);
138
139   if (ob->mode & OB_MODE_TEXTURE_PAINT) {
140     Scene *scene = CTX_data_scene(C);
141     BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
142     WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
143   }
144
145   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
146   WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
147   WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
148
149   return OPERATOR_FINISHED;
150 }
151
152 void OBJECT_OT_material_slot_add(wmOperatorType *ot)
153 {
154   /* identifiers */
155   ot->name = "Add Material Slot";
156   ot->idname = "OBJECT_OT_material_slot_add";
157   ot->description = "Add a new material slot";
158
159   /* api callbacks */
160   ot->exec = material_slot_add_exec;
161   ot->poll = ED_operator_object_active_editable;
162
163   /* flags */
164   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
165 }
166
167 static int material_slot_remove_exec(bContext *C, wmOperator *op)
168 {
169   Object *ob = ED_object_context(C);
170
171   if (!ob)
172     return OPERATOR_CANCELLED;
173
174   /* Removing material slots in edit mode screws things up, see bug #21822.*/
175   if (ob == CTX_data_edit_object(C)) {
176     BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
177     return OPERATOR_CANCELLED;
178   }
179
180   BKE_object_material_slot_remove(CTX_data_main(C), ob);
181
182   if (ob->mode & OB_MODE_TEXTURE_PAINT) {
183     Scene *scene = CTX_data_scene(C);
184     BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
185     WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
186   }
187
188   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
189   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
190   WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
191   WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
192
193   return OPERATOR_FINISHED;
194 }
195
196 void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
197 {
198   /* identifiers */
199   ot->name = "Remove Material Slot";
200   ot->idname = "OBJECT_OT_material_slot_remove";
201   ot->description = "Remove the selected material slot";
202
203   /* api callbacks */
204   ot->exec = material_slot_remove_exec;
205   ot->poll = ED_operator_object_active_editable;
206
207   /* flags */
208   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
209 }
210
211 static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
212 {
213   View3D *v3d = CTX_wm_view3d(C);
214   bool changed_multi = false;
215
216   uint objects_len = 0;
217   Object **objects = object_array_for_shading(C, &objects_len);
218   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
219     Object *ob = objects[ob_index];
220     if (ob->actcol <= 0) {
221       continue;
222     }
223     bool changed = false;
224     if (ob->type == OB_MESH) {
225       BMEditMesh *em = BKE_editmesh_from_object(ob);
226       BMFace *efa;
227       BMIter iter;
228
229       if (em) {
230         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
231           if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
232             changed = true;
233             efa->mat_nr = ob->actcol - 1;
234           }
235         }
236       }
237     }
238     else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
239       Nurb *nu;
240       ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
241
242       if (nurbs) {
243         for (nu = nurbs->first; nu; nu = nu->next) {
244           if (ED_curve_nurb_select_check(v3d, nu)) {
245             changed = true;
246             nu->mat_nr = ob->actcol - 1;
247           }
248         }
249       }
250     }
251     else if (ob->type == OB_FONT) {
252       EditFont *ef = ((Curve *)ob->data)->editfont;
253       int i, selstart, selend;
254
255       if (ef && BKE_vfont_select_get(ob, &selstart, &selend)) {
256         for (i = selstart; i <= selend; i++) {
257           changed = true;
258           ef->textbufinfo[i].mat_nr = ob->actcol;
259         }
260       }
261     }
262
263     if (changed) {
264       changed_multi = true;
265       DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
266       WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
267     }
268   }
269   MEM_freeN(objects);
270
271   return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
272 }
273
274 void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
275 {
276   /* identifiers */
277   ot->name = "Assign Material Slot";
278   ot->idname = "OBJECT_OT_material_slot_assign";
279   ot->description = "Assign active material slot to selection";
280
281   /* api callbacks */
282   ot->exec = material_slot_assign_exec;
283   ot->poll = ED_operator_object_active_editable;
284
285   /* flags */
286   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
287 }
288
289 static int material_slot_de_select(bContext *C, bool select)
290 {
291   bool changed_multi = false;
292   Object *obact = CTX_data_active_object(C);
293   const Material *mat_active = obact ? give_current_material(obact, obact->actcol) : NULL;
294
295   uint objects_len = 0;
296   Object **objects = object_array_for_shading(C, &objects_len);
297   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
298     Object *ob = objects[ob_index];
299     short mat_nr_active = -1;
300
301     if (ob->totcol == 0) {
302       continue;
303     }
304     if (obact && (mat_active == give_current_material(ob, obact->actcol))) {
305       /* Avoid searching since there may be multiple slots with the same material.
306        * For the active object or duplicates: match the material slot index first. */
307       mat_nr_active = obact->actcol - 1;
308     }
309     else {
310       /* Find the first matching material.
311        * Note: there may be multiple but thats not a common use case. */
312       for (short i = 0; i < ob->totcol; i++) {
313         const Material *mat = give_current_material(ob, i + 1);
314         if (mat_active == mat) {
315           mat_nr_active = i;
316           break;
317         }
318       }
319       if (mat_nr_active == -1) {
320         continue;
321       }
322     }
323
324     bool changed = false;
325
326     if (ob->type == OB_MESH) {
327       BMEditMesh *em = BKE_editmesh_from_object(ob);
328
329       if (em) {
330         changed = EDBM_deselect_by_material(em, mat_nr_active, select);
331       }
332     }
333     else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
334       ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
335       Nurb *nu;
336       BPoint *bp;
337       BezTriple *bezt;
338       int a;
339
340       if (nurbs) {
341         for (nu = nurbs->first; nu; nu = nu->next) {
342           if (nu->mat_nr == mat_nr_active) {
343             if (nu->bezt) {
344               a = nu->pntsu;
345               bezt = nu->bezt;
346               while (a--) {
347                 if (bezt->hide == 0) {
348                   changed = true;
349                   if (select) {
350                     bezt->f1 |= SELECT;
351                     bezt->f2 |= SELECT;
352                     bezt->f3 |= SELECT;
353                   }
354                   else {
355                     bezt->f1 &= ~SELECT;
356                     bezt->f2 &= ~SELECT;
357                     bezt->f3 &= ~SELECT;
358                   }
359                 }
360                 bezt++;
361               }
362             }
363             else if (nu->bp) {
364               a = nu->pntsu * nu->pntsv;
365               bp = nu->bp;
366               while (a--) {
367                 if (bp->hide == 0) {
368                   changed = true;
369                   if (select)
370                     bp->f1 |= SELECT;
371                   else
372                     bp->f1 &= ~SELECT;
373                 }
374                 bp++;
375               }
376             }
377           }
378         }
379       }
380     }
381
382     if (changed) {
383       changed_multi = true;
384       DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
385       WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
386     }
387   }
388
389   MEM_freeN(objects);
390
391   return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
392 }
393
394 static int material_slot_select_exec(bContext *C, wmOperator *UNUSED(op))
395 {
396   return material_slot_de_select(C, true);
397 }
398
399 void OBJECT_OT_material_slot_select(wmOperatorType *ot)
400 {
401   /* identifiers */
402   ot->name = "Select Material Slot";
403   ot->idname = "OBJECT_OT_material_slot_select";
404   ot->description = "Select by active material slot";
405
406   /* api callbacks */
407   ot->exec = material_slot_select_exec;
408
409   /* flags */
410   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
411 }
412
413 static int material_slot_deselect_exec(bContext *C, wmOperator *UNUSED(op))
414 {
415   return material_slot_de_select(C, false);
416 }
417
418 void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
419 {
420   /* identifiers */
421   ot->name = "Deselect Material Slot";
422   ot->idname = "OBJECT_OT_material_slot_deselect";
423   ot->description = "Deselect by active material slot";
424
425   /* api callbacks */
426   ot->exec = material_slot_deselect_exec;
427
428   /* flags */
429   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
430 }
431
432 static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
433 {
434   Main *bmain = CTX_data_main(C);
435   Object *ob = ED_object_context(C);
436   Material ***matar;
437
438   if (!ob || !(matar = give_matarar(ob)))
439     return OPERATOR_CANCELLED;
440
441   CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
442     if (ob != ob_iter && give_matarar(ob_iter)) {
443       if (ob->data != ob_iter->data)
444         assign_matarar(bmain, ob_iter, matar, ob->totcol);
445
446       if (ob_iter->totcol == ob->totcol) {
447         ob_iter->actcol = ob->actcol;
448         DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
449         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
450       }
451     }
452   }
453   CTX_DATA_END;
454
455   return OPERATOR_FINISHED;
456 }
457
458 void OBJECT_OT_material_slot_copy(wmOperatorType *ot)
459 {
460   /* identifiers */
461   ot->name = "Copy Material to Selected";
462   ot->idname = "OBJECT_OT_material_slot_copy";
463   ot->description = "Copy material to selected objects";
464
465   /* api callbacks */
466   ot->exec = material_slot_copy_exec;
467
468   /* flags */
469   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
470 }
471
472 static int material_slot_move_exec(bContext *C, wmOperator *op)
473 {
474   Object *ob = ED_object_context(C);
475
476   unsigned int *slot_remap;
477   int index_pair[2];
478
479   int dir = RNA_enum_get(op->ptr, "direction");
480
481   if (!ob || ob->totcol < 2) {
482     return OPERATOR_CANCELLED;
483   }
484
485   /* up */
486   if (dir == 1 && ob->actcol > 1) {
487     index_pair[0] = ob->actcol - 2;
488     index_pair[1] = ob->actcol - 1;
489     ob->actcol--;
490   }
491   /* down */
492   else if (dir == -1 && ob->actcol < ob->totcol) {
493     index_pair[0] = ob->actcol - 1;
494     index_pair[1] = ob->actcol - 0;
495     ob->actcol++;
496   }
497   else {
498     return OPERATOR_CANCELLED;
499   }
500
501   slot_remap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, __func__);
502
503   range_vn_u(slot_remap, ob->totcol, 0);
504
505   slot_remap[index_pair[0]] = index_pair[1];
506   slot_remap[index_pair[1]] = index_pair[0];
507
508   BKE_material_remap_object(ob, slot_remap);
509
510   MEM_freeN(slot_remap);
511
512   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
513   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
514   WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
515
516   return OPERATOR_FINISHED;
517 }
518
519 void OBJECT_OT_material_slot_move(wmOperatorType *ot)
520 {
521   static const EnumPropertyItem material_slot_move[] = {
522       {1, "UP", 0, "Up", ""},
523       {-1, "DOWN", 0, "Down", ""},
524       {0, NULL, 0, NULL, NULL},
525   };
526
527   /* identifiers */
528   ot->name = "Move Material";
529   ot->idname = "OBJECT_OT_material_slot_move";
530   ot->description = "Move the active material up/down in the list";
531
532   /* api callbacks */
533   ot->exec = material_slot_move_exec;
534
535   /* flags */
536   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
537
538   RNA_def_enum(ot->srna,
539                "direction",
540                material_slot_move,
541                0,
542                "Direction",
543                "Direction to move the active material towards");
544 }
545
546 /********************** new material operator *********************/
547
548 static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
549 {
550   Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
551   Main *bmain = CTX_data_main(C);
552   PointerRNA ptr, idptr;
553   PropertyRNA *prop;
554
555   /* hook into UI */
556   UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
557
558   Object *ob = (prop && RNA_struct_is_a(ptr.type, &RNA_Object)) ? ptr.data : NULL;
559
560   /* add or copy material */
561   if (ma) {
562     Material *new_ma = NULL;
563     BKE_id_copy_ex(bmain, &ma->id, (ID **)&new_ma, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
564     ma = new_ma;
565   }
566   else {
567     const char *name = DATA_("Material");
568     if (!(ob != NULL && ob->type == OB_GPENCIL)) {
569       ma = BKE_material_add(bmain, name);
570     }
571     else {
572       ma = BKE_material_add_gpencil(bmain, name);
573     }
574     ED_node_shader_default(C, &ma->id);
575     ma->use_nodes = true;
576   }
577
578   if (prop) {
579     if (ob != NULL) {
580       /* Add slot follows user-preferences for creating new slots,
581        * RNA pointer assignment doesn't, see: T60014. */
582       if (give_current_material_p(ob, ob->actcol) == NULL) {
583         BKE_object_material_slot_add(bmain, ob);
584       }
585     }
586
587     /* when creating new ID blocks, use is already 1, but RNA
588      * pointer use also increases user, so this compensates it */
589     id_us_min(&ma->id);
590
591     RNA_id_pointer_create(&ma->id, &idptr);
592     RNA_property_pointer_set(&ptr, prop, idptr);
593     RNA_property_update(C, &ptr, prop);
594   }
595
596   WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma);
597
598   return OPERATOR_FINISHED;
599 }
600
601 void MATERIAL_OT_new(wmOperatorType *ot)
602 {
603   /* identifiers */
604   ot->name = "New Material";
605   ot->idname = "MATERIAL_OT_new";
606   ot->description = "Add a new material";
607
608   /* api callbacks */
609   ot->exec = new_material_exec;
610
611   /* flags */
612   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
613 }
614
615 /********************** new texture operator *********************/
616
617 static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
618 {
619   Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
620   Main *bmain = CTX_data_main(C);
621   PointerRNA ptr, idptr;
622   PropertyRNA *prop;
623
624   /* add or copy texture */
625   if (tex) {
626     tex = BKE_texture_copy(bmain, tex);
627   }
628   else {
629     tex = BKE_texture_add(bmain, DATA_("Texture"));
630   }
631
632   /* hook into UI */
633   UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
634
635   if (prop) {
636     /* when creating new ID blocks, use is already 1, but RNA
637      * pointer use also increases user, so this compensates it */
638     id_us_min(&tex->id);
639
640     RNA_id_pointer_create(&tex->id, &idptr);
641     RNA_property_pointer_set(&ptr, prop, idptr);
642     RNA_property_update(C, &ptr, prop);
643   }
644
645   WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex);
646
647   return OPERATOR_FINISHED;
648 }
649
650 void TEXTURE_OT_new(wmOperatorType *ot)
651 {
652   /* identifiers */
653   ot->name = "New Texture";
654   ot->idname = "TEXTURE_OT_new";
655   ot->description = "Add a new texture";
656
657   /* api callbacks */
658   ot->exec = new_texture_exec;
659
660   /* flags */
661   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
662 }
663
664 /********************** new world operator *********************/
665
666 static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
667 {
668   World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
669   Main *bmain = CTX_data_main(C);
670   PointerRNA ptr, idptr;
671   PropertyRNA *prop;
672
673   /* add or copy world */
674   if (wo) {
675     wo = BKE_world_copy(bmain, wo);
676   }
677   else {
678     wo = BKE_world_add(bmain, DATA_("World"));
679     ED_node_shader_default(C, &wo->id);
680     wo->use_nodes = true;
681   }
682
683   /* hook into UI */
684   UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
685
686   if (prop) {
687     /* when creating new ID blocks, use is already 1, but RNA
688      * pointer use also increases user, so this compensates it */
689     id_us_min(&wo->id);
690
691     RNA_id_pointer_create(&wo->id, &idptr);
692     RNA_property_pointer_set(&ptr, prop, idptr);
693     RNA_property_update(C, &ptr, prop);
694   }
695
696   WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo);
697
698   return OPERATOR_FINISHED;
699 }
700
701 void WORLD_OT_new(wmOperatorType *ot)
702 {
703   /* identifiers */
704   ot->name = "New World";
705   ot->idname = "WORLD_OT_new";
706   ot->description = "Create a new world Data-Block";
707
708   /* api callbacks */
709   ot->exec = new_world_exec;
710
711   /* flags */
712   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
713 }
714
715 /********************** render layer operators *********************/
716
717 static int view_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
718 {
719   wmWindow *win = CTX_wm_window(C);
720   Scene *scene = CTX_data_scene(C);
721   ViewLayer *view_layer = BKE_view_layer_add(scene, NULL);
722
723   if (win) {
724     WM_window_set_active_view_layer(win, view_layer);
725   }
726
727   DEG_id_tag_update(&scene->id, 0);
728   DEG_relations_tag_update(CTX_data_main(C));
729   WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
730
731   return OPERATOR_FINISHED;
732 }
733
734 void SCENE_OT_view_layer_add(wmOperatorType *ot)
735 {
736   /* identifiers */
737   ot->name = "Add View Layer";
738   ot->idname = "SCENE_OT_view_layer_add";
739   ot->description = "Add a view layer";
740
741   /* api callbacks */
742   ot->exec = view_layer_add_exec;
743
744   /* flags */
745   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
746 }
747
748 static bool view_layer_remove_poll(bContext *C)
749 {
750   Scene *scene = CTX_data_scene(C);
751   return (scene->view_layers.first != scene->view_layers.last);
752 }
753
754 static int view_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
755 {
756   Main *bmain = CTX_data_main(C);
757   Scene *scene = CTX_data_scene(C);
758   ViewLayer *view_layer = CTX_data_view_layer(C);
759
760   if (!ED_scene_view_layer_delete(bmain, scene, view_layer, NULL)) {
761     return OPERATOR_CANCELLED;
762   }
763
764   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
765
766   return OPERATOR_FINISHED;
767 }
768
769 void SCENE_OT_view_layer_remove(wmOperatorType *ot)
770 {
771   /* identifiers */
772   ot->name = "Remove View Layer";
773   ot->idname = "SCENE_OT_view_layer_remove";
774   ot->description = "Remove the selected view layer";
775
776   /* api callbacks */
777   ot->exec = view_layer_remove_exec;
778   ot->poll = view_layer_remove_poll;
779
780   /* flags */
781   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
782 }
783
784 /********************** light cache operators *********************/
785 enum {
786   LIGHTCACHE_SUBSET_ALL = 0,
787   LIGHTCACHE_SUBSET_DIRTY,
788   LIGHTCACHE_SUBSET_CUBE,
789 };
790
791 static void light_cache_bake_tag_cache(Scene *scene, wmOperator *op)
792 {
793   if (scene->eevee.light_cache != NULL) {
794     int subset = RNA_enum_get(op->ptr, "subset");
795     switch (subset) {
796       case LIGHTCACHE_SUBSET_ALL:
797         scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID | LIGHTCACHE_UPDATE_CUBE;
798         break;
799       case LIGHTCACHE_SUBSET_CUBE:
800         scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
801         break;
802       case LIGHTCACHE_SUBSET_DIRTY:
803         /* Leave tag untouched. */
804         break;
805     }
806   }
807 }
808
809 /* catch esc */
810 static int light_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *event)
811 {
812   Scene *scene = (Scene *)op->customdata;
813
814   /* no running blender, remove handler and pass through */
815   if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
816     return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
817   }
818
819   /* running render */
820   switch (event->type) {
821     case ESCKEY:
822       return OPERATOR_RUNNING_MODAL;
823   }
824   return OPERATOR_PASS_THROUGH;
825 }
826
827 static void light_cache_bake_cancel(bContext *C, wmOperator *op)
828 {
829   wmWindowManager *wm = CTX_wm_manager(C);
830   Scene *scene = (Scene *)op->customdata;
831
832   /* kill on cancel, because job is using op->reports */
833   WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
834 }
835
836 /* executes blocking render */
837 static int light_cache_bake_exec(bContext *C, wmOperator *op)
838 {
839   ViewLayer *view_layer = CTX_data_view_layer(C);
840   Main *bmain = CTX_data_main(C);
841   Scene *scene = CTX_data_scene(C);
842
843   G.is_break = false;
844
845   /* TODO abort if selected engine is not eevee. */
846   void *rj = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, false, scene->r.cfra);
847
848   light_cache_bake_tag_cache(scene, op);
849
850   short stop = 0, do_update;
851   float progress; /* Not actually used. */
852   EEVEE_lightbake_job(rj, &stop, &do_update, &progress);
853   EEVEE_lightbake_job_data_free(rj);
854
855   // no redraw needed, we leave state as we entered it
856   ED_update_for_newframe(bmain, CTX_data_depsgraph(C));
857
858   WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
859
860   return OPERATOR_FINISHED;
861 }
862
863 static int light_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
864 {
865   wmWindowManager *wm = CTX_wm_manager(C);
866   wmWindow *win = CTX_wm_window(C);
867   ViewLayer *view_layer = CTX_data_view_layer(C);
868   Main *bmain = CTX_data_main(C);
869   Scene *scene = CTX_data_scene(C);
870   int delay = RNA_int_get(op->ptr, "delay");
871
872   wmJob *wm_job = EEVEE_lightbake_job_create(
873       wm, win, bmain, view_layer, scene, delay, scene->r.cfra);
874
875   if (!wm_job) {
876     return OPERATOR_CANCELLED;
877   }
878
879   /* add modal handler for ESC */
880   WM_event_add_modal_handler(C, op);
881
882   light_cache_bake_tag_cache(scene, op);
883
884   /* store actual owner of job, so modal operator could check for it,
885    * the reason of this is that active scene could change when rendering
886    * several layers from compositor [#31800]
887    */
888   op->customdata = scene;
889
890   WM_jobs_start(wm, wm_job);
891
892   WM_cursor_wait(0);
893
894   return OPERATOR_RUNNING_MODAL;
895 }
896
897 void SCENE_OT_light_cache_bake(wmOperatorType *ot)
898 {
899   static const EnumPropertyItem light_cache_subset_items[] = {
900       {LIGHTCACHE_SUBSET_ALL,
901        "ALL",
902        0,
903        "All LightProbes",
904        "Bake both irradiance grids and reflection cubemaps"},
905       {LIGHTCACHE_SUBSET_DIRTY,
906        "DIRTY",
907        0,
908        "Dirty Only",
909        "Only bake lightprobes that are marked as dirty"},
910       {LIGHTCACHE_SUBSET_CUBE,
911        "CUBEMAPS",
912        0,
913        "Cubemaps Only",
914        "Try to only bake reflection cubemaps if irradiance grids are up to date"},
915       {0, NULL, 0, NULL, NULL},
916   };
917
918   /* identifiers */
919   ot->name = "Bake Light Cache";
920   ot->idname = "SCENE_OT_light_cache_bake";
921   ot->description = "Bake the active view layer lighting";
922
923   /* api callbacks */
924   ot->invoke = light_cache_bake_invoke;
925   ot->modal = light_cache_bake_modal;
926   ot->cancel = light_cache_bake_cancel;
927   ot->exec = light_cache_bake_exec;
928
929   ot->prop = RNA_def_int(ot->srna,
930                          "delay",
931                          0,
932                          0,
933                          2000,
934                          "Delay",
935                          "Delay in millisecond before baking starts",
936                          0,
937                          2000);
938   RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
939
940   ot->prop = RNA_def_enum(
941       ot->srna, "subset", light_cache_subset_items, 0, "Subset", "Subset of probes to update");
942   RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
943 }
944
945 static bool light_cache_free_poll(bContext *C)
946 {
947   Scene *scene = CTX_data_scene(C);
948
949   return scene->eevee.light_cache;
950 }
951
952 static int light_cache_free_exec(bContext *C, wmOperator *UNUSED(op))
953 {
954   Scene *scene = CTX_data_scene(C);
955
956   /* kill potential bake job first (see T57011) */
957   wmWindowManager *wm = CTX_wm_manager(C);
958   WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_LIGHT_BAKE);
959
960   if (!scene->eevee.light_cache) {
961     return OPERATOR_CANCELLED;
962   }
963
964   EEVEE_lightcache_free(scene->eevee.light_cache);
965   scene->eevee.light_cache = NULL;
966
967   EEVEE_lightcache_info_update(&scene->eevee);
968
969   DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
970
971   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
972
973   return OPERATOR_FINISHED;
974 }
975
976 void SCENE_OT_light_cache_free(wmOperatorType *ot)
977 {
978   /* identifiers */
979   ot->name = "Delete Light Cache";
980   ot->idname = "SCENE_OT_light_cache_free";
981   ot->description = "Delete cached indirect lighting";
982
983   /* api callbacks */
984   ot->exec = light_cache_free_exec;
985   ot->poll = light_cache_free_poll;
986 }
987
988 /********************** render view operators *********************/
989
990 static bool render_view_remove_poll(bContext *C)
991 {
992   Scene *scene = CTX_data_scene(C);
993
994   /* don't allow user to remove "left" and "right" views */
995   return scene->r.actview > 1;
996 }
997
998 static int render_view_add_exec(bContext *C, wmOperator *UNUSED(op))
999 {
1000   Scene *scene = CTX_data_scene(C);
1001
1002   BKE_scene_add_render_view(scene, NULL);
1003   scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
1004
1005   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1006
1007   return OPERATOR_FINISHED;
1008 }
1009
1010 void SCENE_OT_render_view_add(wmOperatorType *ot)
1011 {
1012   /* identifiers */
1013   ot->name = "Add Render View";
1014   ot->idname = "SCENE_OT_render_view_add";
1015   ot->description = "Add a render view";
1016
1017   /* api callbacks */
1018   ot->exec = render_view_add_exec;
1019
1020   /* flags */
1021   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1022 }
1023
1024 static int render_view_remove_exec(bContext *C, wmOperator *UNUSED(op))
1025 {
1026   Scene *scene = CTX_data_scene(C);
1027   SceneRenderView *rv = BLI_findlink(&scene->r.views, scene->r.actview);
1028
1029   if (!BKE_scene_remove_render_view(scene, rv))
1030     return OPERATOR_CANCELLED;
1031
1032   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1033
1034   return OPERATOR_FINISHED;
1035 }
1036
1037 void SCENE_OT_render_view_remove(wmOperatorType *ot)
1038 {
1039   /* identifiers */
1040   ot->name = "Remove Render View";
1041   ot->idname = "SCENE_OT_render_view_remove";
1042   ot->description = "Remove the selected render view";
1043
1044   /* api callbacks */
1045   ot->exec = render_view_remove_exec;
1046   ot->poll = render_view_remove_poll;
1047
1048   /* flags */
1049   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1050 }
1051
1052 #ifdef WITH_FREESTYLE
1053
1054 static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)
1055 {
1056   if (!lineset) {
1057     BKE_report(reports,
1058                RPT_ERROR,
1059                "No active lineset and associated line style to manipulate the modifier");
1060     return false;
1061   }
1062   if (!lineset->linestyle) {
1063     BKE_report(reports,
1064                RPT_ERROR,
1065                "The active lineset does not have a line style (indicating data corruption)");
1066     return false;
1067   }
1068
1069   return true;
1070 }
1071
1072 static bool freestyle_active_module_poll(bContext *C)
1073 {
1074   PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1075   FreestyleModuleConfig *module = ptr.data;
1076
1077   return module != NULL;
1078 }
1079
1080 static int freestyle_module_add_exec(bContext *C, wmOperator *UNUSED(op))
1081 {
1082   Scene *scene = CTX_data_scene(C);
1083   ViewLayer *view_layer = CTX_data_view_layer(C);
1084
1085   BKE_freestyle_module_add(&view_layer->freestyle_config);
1086
1087   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1088
1089   return OPERATOR_FINISHED;
1090 }
1091
1092 void SCENE_OT_freestyle_module_add(wmOperatorType *ot)
1093 {
1094   /* identifiers */
1095   ot->name = "Add Freestyle Module";
1096   ot->idname = "SCENE_OT_freestyle_module_add";
1097   ot->description = "Add a style module into the list of modules";
1098
1099   /* api callbacks */
1100   ot->exec = freestyle_module_add_exec;
1101
1102   /* flags */
1103   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1104 }
1105
1106 static int freestyle_module_remove_exec(bContext *C, wmOperator *UNUSED(op))
1107 {
1108   Scene *scene = CTX_data_scene(C);
1109   ViewLayer *view_layer = CTX_data_view_layer(C);
1110   PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1111   FreestyleModuleConfig *module = ptr.data;
1112
1113   BKE_freestyle_module_delete(&view_layer->freestyle_config, module);
1114
1115   DEG_id_tag_update(&scene->id, 0);
1116   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1117
1118   return OPERATOR_FINISHED;
1119 }
1120
1121 void SCENE_OT_freestyle_module_remove(wmOperatorType *ot)
1122 {
1123   /* identifiers */
1124   ot->name = "Remove Freestyle Module";
1125   ot->idname = "SCENE_OT_freestyle_module_remove";
1126   ot->description = "Remove the style module from the stack";
1127
1128   /* api callbacks */
1129   ot->poll = freestyle_active_module_poll;
1130   ot->exec = freestyle_module_remove_exec;
1131
1132   /* flags */
1133   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1134 }
1135
1136 static int freestyle_module_move_exec(bContext *C, wmOperator *op)
1137 {
1138   Scene *scene = CTX_data_scene(C);
1139   ViewLayer *view_layer = CTX_data_view_layer(C);
1140   PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
1141   FreestyleModuleConfig *module = ptr.data;
1142   int dir = RNA_enum_get(op->ptr, "direction");
1143
1144   if (BKE_freestyle_module_move(&view_layer->freestyle_config, module, dir)) {
1145     DEG_id_tag_update(&scene->id, 0);
1146     WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1147   }
1148
1149   return OPERATOR_FINISHED;
1150 }
1151
1152 void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
1153 {
1154   static const EnumPropertyItem direction_items[] = {
1155       {-1, "UP", 0, "Up", ""},
1156       {1, "DOWN", 0, "Down", ""},
1157       {0, NULL, 0, NULL, NULL},
1158   };
1159
1160   /* identifiers */
1161   ot->name = "Move Freestyle Module";
1162   ot->idname = "SCENE_OT_freestyle_module_move";
1163   ot->description = "Change the position of the style module within in the list of style modules";
1164
1165   /* api callbacks */
1166   ot->poll = freestyle_active_module_poll;
1167   ot->exec = freestyle_module_move_exec;
1168
1169   /* flags */
1170   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1171
1172   /* props */
1173   RNA_def_enum(ot->srna,
1174                "direction",
1175                direction_items,
1176                0,
1177                "Direction",
1178                "Direction to move the chosen style module towards");
1179 }
1180
1181 static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op))
1182 {
1183   Main *bmain = CTX_data_main(C);
1184   Scene *scene = CTX_data_scene(C);
1185   ViewLayer *view_layer = CTX_data_view_layer(C);
1186
1187   BKE_freestyle_lineset_add(bmain, &view_layer->freestyle_config, NULL);
1188
1189   DEG_id_tag_update(&scene->id, 0);
1190   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1191
1192   return OPERATOR_FINISHED;
1193 }
1194
1195 void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot)
1196 {
1197   /* identifiers */
1198   ot->name = "Add Line Set";
1199   ot->idname = "SCENE_OT_freestyle_lineset_add";
1200   ot->description = "Add a line set into the list of line sets";
1201
1202   /* api callbacks */
1203   ot->exec = freestyle_lineset_add_exec;
1204
1205   /* flags */
1206   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1207 }
1208
1209 static bool freestyle_active_lineset_poll(bContext *C)
1210 {
1211   ViewLayer *view_layer = CTX_data_view_layer(C);
1212
1213   if (!view_layer) {
1214     return false;
1215   }
1216
1217   return BKE_freestyle_lineset_get_active(&view_layer->freestyle_config) != NULL;
1218 }
1219
1220 static int freestyle_lineset_copy_exec(bContext *C, wmOperator *UNUSED(op))
1221 {
1222   ViewLayer *view_layer = CTX_data_view_layer(C);
1223
1224   FRS_copy_active_lineset(&view_layer->freestyle_config);
1225
1226   return OPERATOR_FINISHED;
1227 }
1228
1229 void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot)
1230 {
1231   /* identifiers */
1232   ot->name = "Copy Line Set";
1233   ot->idname = "SCENE_OT_freestyle_lineset_copy";
1234   ot->description = "Copy the active line set to a buffer";
1235
1236   /* api callbacks */
1237   ot->exec = freestyle_lineset_copy_exec;
1238   ot->poll = freestyle_active_lineset_poll;
1239
1240   /* flags */
1241   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1242 }
1243
1244 static int freestyle_lineset_paste_exec(bContext *C, wmOperator *UNUSED(op))
1245 {
1246   Scene *scene = CTX_data_scene(C);
1247   ViewLayer *view_layer = CTX_data_view_layer(C);
1248
1249   FRS_paste_active_lineset(&view_layer->freestyle_config);
1250
1251   DEG_id_tag_update(&scene->id, 0);
1252   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1253
1254   return OPERATOR_FINISHED;
1255 }
1256
1257 void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot)
1258 {
1259   /* identifiers */
1260   ot->name = "Paste Line Set";
1261   ot->idname = "SCENE_OT_freestyle_lineset_paste";
1262   ot->description = "Paste the buffer content to the active line set";
1263
1264   /* api callbacks */
1265   ot->exec = freestyle_lineset_paste_exec;
1266   ot->poll = freestyle_active_lineset_poll;
1267
1268   /* flags */
1269   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1270 }
1271
1272 static int freestyle_lineset_remove_exec(bContext *C, wmOperator *UNUSED(op))
1273 {
1274   Scene *scene = CTX_data_scene(C);
1275   ViewLayer *view_layer = CTX_data_view_layer(C);
1276
1277   FRS_delete_active_lineset(&view_layer->freestyle_config);
1278
1279   DEG_id_tag_update(&scene->id, 0);
1280   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1281
1282   return OPERATOR_FINISHED;
1283 }
1284
1285 void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot)
1286 {
1287   /* identifiers */
1288   ot->name = "Remove Line Set";
1289   ot->idname = "SCENE_OT_freestyle_lineset_remove";
1290   ot->description = "Remove the active line set from the list of line sets";
1291
1292   /* api callbacks */
1293   ot->exec = freestyle_lineset_remove_exec;
1294   ot->poll = freestyle_active_lineset_poll;
1295
1296   /* flags */
1297   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1298 }
1299
1300 static int freestyle_lineset_move_exec(bContext *C, wmOperator *op)
1301 {
1302   Scene *scene = CTX_data_scene(C);
1303   ViewLayer *view_layer = CTX_data_view_layer(C);
1304   int dir = RNA_enum_get(op->ptr, "direction");
1305
1306   if (FRS_move_active_lineset(&view_layer->freestyle_config, dir)) {
1307     DEG_id_tag_update(&scene->id, 0);
1308     WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1309   }
1310
1311   return OPERATOR_FINISHED;
1312 }
1313
1314 void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot)
1315 {
1316   static const EnumPropertyItem direction_items[] = {
1317       {-1, "UP", 0, "Up", ""},
1318       {1, "DOWN", 0, "Down", ""},
1319       {0, NULL, 0, NULL, NULL},
1320   };
1321
1322   /* identifiers */
1323   ot->name = "Move Line Set";
1324   ot->idname = "SCENE_OT_freestyle_lineset_move";
1325   ot->description = "Change the position of the active line set within the list of line sets";
1326
1327   /* api callbacks */
1328   ot->exec = freestyle_lineset_move_exec;
1329   ot->poll = freestyle_active_lineset_poll;
1330
1331   /* flags */
1332   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1333
1334   /* props */
1335   RNA_def_enum(ot->srna,
1336                "direction",
1337                direction_items,
1338                0,
1339                "Direction",
1340                "Direction to move the active line set towards");
1341 }
1342
1343 static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
1344 {
1345   Main *bmain = CTX_data_main(C);
1346   ViewLayer *view_layer = CTX_data_view_layer(C);
1347   FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
1348
1349   if (!lineset) {
1350     BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
1351     return OPERATOR_CANCELLED;
1352   }
1353   if (lineset->linestyle) {
1354     id_us_min(&lineset->linestyle->id);
1355     lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
1356   }
1357   else {
1358     lineset->linestyle = BKE_linestyle_new(bmain, "LineStyle");
1359   }
1360   DEG_id_tag_update(&lineset->linestyle->id, 0);
1361   WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1362
1363   return OPERATOR_FINISHED;
1364 }
1365
1366 void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot)
1367 {
1368   /* identifiers */
1369   ot->name = "New Line Style";
1370   ot->idname = "SCENE_OT_freestyle_linestyle_new";
1371   ot->description = "Create a new line style, reusable by multiple line sets";
1372
1373   /* api callbacks */
1374   ot->exec = freestyle_linestyle_new_exec;
1375   ot->poll = freestyle_active_lineset_poll;
1376
1377   /* flags */
1378   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1379 }
1380
1381 static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op)
1382 {
1383   ViewLayer *view_layer = CTX_data_view_layer(C);
1384   FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
1385   int type = RNA_enum_get(op->ptr, "type");
1386
1387   if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1388     return OPERATOR_CANCELLED;
1389   }
1390
1391   if (BKE_linestyle_color_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1392     BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type");
1393     return OPERATOR_CANCELLED;
1394   }
1395   DEG_id_tag_update(&lineset->linestyle->id, 0);
1396   WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1397
1398   return OPERATOR_FINISHED;
1399 }
1400
1401 void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot)
1402 {
1403   /* identifiers */
1404   ot->name = "Add Line Color Modifier";
1405   ot->idname = "SCENE_OT_freestyle_color_modifier_add";
1406   ot->description =
1407       "Add a line color modifier to the line style associated with the active lineset";
1408
1409   /* api callbacks */
1410   ot->invoke = WM_menu_invoke;
1411   ot->exec = freestyle_color_modifier_add_exec;
1412   ot->poll = freestyle_active_lineset_poll;
1413
1414   /* flags */
1415   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1416
1417   /* properties */
1418   ot->prop = RNA_def_enum(
1419       ot->srna, "type", rna_enum_linestyle_color_modifier_type_items, 0, "Type", "");
1420 }
1421
1422 static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op)
1423 {
1424   ViewLayer *view_layer = CTX_data_view_layer(C);
1425   FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
1426   int type = RNA_enum_get(op->ptr, "type");
1427
1428   if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1429     return OPERATOR_CANCELLED;
1430   }
1431
1432   if (BKE_linestyle_alpha_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1433     BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
1434     return OPERATOR_CANCELLED;
1435   }
1436   DEG_id_tag_update(&lineset->linestyle->id, 0);
1437   WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1438
1439   return OPERATOR_FINISHED;
1440 }
1441
1442 void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot)
1443 {
1444   /* identifiers */
1445   ot->name = "Add Alpha Transparency Modifier";
1446   ot->idname = "SCENE_OT_freestyle_alpha_modifier_add";
1447   ot->description =
1448       "Add an alpha transparency modifier to the line style associated with the active lineset";
1449
1450   /* api callbacks */
1451   ot->invoke = WM_menu_invoke;
1452   ot->exec = freestyle_alpha_modifier_add_exec;
1453   ot->poll = freestyle_active_lineset_poll;
1454
1455   /* flags */
1456   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1457
1458   /* properties */
1459   ot->prop = RNA_def_enum(
1460       ot->srna, "type", rna_enum_linestyle_alpha_modifier_type_items, 0, "Type", "");
1461 }
1462
1463 static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op)
1464 {
1465   ViewLayer *view_layer = CTX_data_view_layer(C);
1466   FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
1467   int type = RNA_enum_get(op->ptr, "type");
1468
1469   if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1470     return OPERATOR_CANCELLED;
1471   }
1472
1473   if (BKE_linestyle_thickness_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1474     BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
1475     return OPERATOR_CANCELLED;
1476   }
1477   DEG_id_tag_update(&lineset->linestyle->id, 0);
1478   WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1479
1480   return OPERATOR_FINISHED;
1481 }
1482
1483 void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot)
1484 {
1485   /* identifiers */
1486   ot->name = "Add Line Thickness Modifier";
1487   ot->idname = "SCENE_OT_freestyle_thickness_modifier_add";
1488   ot->description =
1489       "Add a line thickness modifier to the line style associated with the active lineset";
1490
1491   /* api callbacks */
1492   ot->invoke = WM_menu_invoke;
1493   ot->exec = freestyle_thickness_modifier_add_exec;
1494   ot->poll = freestyle_active_lineset_poll;
1495
1496   /* flags */
1497   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1498
1499   /* properties */
1500   ot->prop = RNA_def_enum(
1501       ot->srna, "type", rna_enum_linestyle_thickness_modifier_type_items, 0, "Type", "");
1502 }
1503
1504 static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op)
1505 {
1506   ViewLayer *view_layer = CTX_data_view_layer(C);
1507   FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
1508   int type = RNA_enum_get(op->ptr, "type");
1509
1510   if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1511     return OPERATOR_CANCELLED;
1512   }
1513
1514   if (BKE_linestyle_geometry_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1515     BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
1516     return OPERATOR_CANCELLED;
1517   }
1518   DEG_id_tag_update(&lineset->linestyle->id, 0);
1519   WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1520
1521   return OPERATOR_FINISHED;
1522 }
1523
1524 void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot)
1525 {
1526   /* identifiers */
1527   ot->name = "Add Stroke Geometry Modifier";
1528   ot->idname = "SCENE_OT_freestyle_geometry_modifier_add";
1529   ot->description =
1530       "Add a stroke geometry modifier to the line style associated with the active lineset";
1531
1532   /* api callbacks */
1533   ot->invoke = WM_menu_invoke;
1534   ot->exec = freestyle_geometry_modifier_add_exec;
1535   ot->poll = freestyle_active_lineset_poll;
1536
1537   /* flags */
1538   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1539
1540   /* properties */
1541   ot->prop = RNA_def_enum(
1542       ot->srna, "type", rna_enum_linestyle_geometry_modifier_type_items, 0, "Type", "");
1543 }
1544
1545 static int freestyle_get_modifier_type(PointerRNA *ptr)
1546 {
1547   if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier))
1548     return LS_MODIFIER_TYPE_COLOR;
1549   else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier))
1550     return LS_MODIFIER_TYPE_ALPHA;
1551   else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier))
1552     return LS_MODIFIER_TYPE_THICKNESS;
1553   else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier))
1554     return LS_MODIFIER_TYPE_GEOMETRY;
1555   return -1;
1556 }
1557
1558 static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op)
1559 {
1560   ViewLayer *view_layer = CTX_data_view_layer(C);
1561   FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
1562   PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1563   LineStyleModifier *modifier = ptr.data;
1564
1565   if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1566     return OPERATOR_CANCELLED;
1567   }
1568
1569   switch (freestyle_get_modifier_type(&ptr)) {
1570     case LS_MODIFIER_TYPE_COLOR:
1571       BKE_linestyle_color_modifier_remove(lineset->linestyle, modifier);
1572       break;
1573     case LS_MODIFIER_TYPE_ALPHA:
1574       BKE_linestyle_alpha_modifier_remove(lineset->linestyle, modifier);
1575       break;
1576     case LS_MODIFIER_TYPE_THICKNESS:
1577       BKE_linestyle_thickness_modifier_remove(lineset->linestyle, modifier);
1578       break;
1579     case LS_MODIFIER_TYPE_GEOMETRY:
1580       BKE_linestyle_geometry_modifier_remove(lineset->linestyle, modifier);
1581       break;
1582     default:
1583       BKE_report(
1584           op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1585       return OPERATOR_CANCELLED;
1586   }
1587   DEG_id_tag_update(&lineset->linestyle->id, 0);
1588   WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1589
1590   return OPERATOR_FINISHED;
1591 }
1592
1593 void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot)
1594 {
1595   /* identifiers */
1596   ot->name = "Remove Modifier";
1597   ot->idname = "SCENE_OT_freestyle_modifier_remove";
1598   ot->description = "Remove the modifier from the list of modifiers";
1599
1600   /* api callbacks */
1601   ot->exec = freestyle_modifier_remove_exec;
1602   ot->poll = freestyle_active_lineset_poll;
1603
1604   /* flags */
1605   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1606 }
1607
1608 static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
1609 {
1610   ViewLayer *view_layer = CTX_data_view_layer(C);
1611   FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
1612   PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1613   LineStyleModifier *modifier = ptr.data;
1614
1615   if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1616     return OPERATOR_CANCELLED;
1617   }
1618
1619   switch (freestyle_get_modifier_type(&ptr)) {
1620     case LS_MODIFIER_TYPE_COLOR:
1621       BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
1622       break;
1623     case LS_MODIFIER_TYPE_ALPHA:
1624       BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
1625       break;
1626     case LS_MODIFIER_TYPE_THICKNESS:
1627       BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
1628       break;
1629     case LS_MODIFIER_TYPE_GEOMETRY:
1630       BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
1631       break;
1632     default:
1633       BKE_report(
1634           op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1635       return OPERATOR_CANCELLED;
1636   }
1637   DEG_id_tag_update(&lineset->linestyle->id, 0);
1638   WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1639
1640   return OPERATOR_FINISHED;
1641 }
1642
1643 void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot)
1644 {
1645   /* identifiers */
1646   ot->name = "Copy Modifier";
1647   ot->idname = "SCENE_OT_freestyle_modifier_copy";
1648   ot->description = "Duplicate the modifier within the list of modifiers";
1649
1650   /* api callbacks */
1651   ot->exec = freestyle_modifier_copy_exec;
1652   ot->poll = freestyle_active_lineset_poll;
1653
1654   /* flags */
1655   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1656 }
1657
1658 static int freestyle_modifier_move_exec(bContext *C, wmOperator *op)
1659 {
1660   ViewLayer *view_layer = CTX_data_view_layer(C);
1661   FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
1662   PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1663   LineStyleModifier *modifier = ptr.data;
1664   int dir = RNA_enum_get(op->ptr, "direction");
1665   bool changed = false;
1666
1667   if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1668     return OPERATOR_CANCELLED;
1669   }
1670
1671   switch (freestyle_get_modifier_type(&ptr)) {
1672     case LS_MODIFIER_TYPE_COLOR:
1673       changed = BKE_linestyle_color_modifier_move(lineset->linestyle, modifier, dir);
1674       break;
1675     case LS_MODIFIER_TYPE_ALPHA:
1676       changed = BKE_linestyle_alpha_modifier_move(lineset->linestyle, modifier, dir);
1677       break;
1678     case LS_MODIFIER_TYPE_THICKNESS:
1679       changed = BKE_linestyle_thickness_modifier_move(lineset->linestyle, modifier, dir);
1680       break;
1681     case LS_MODIFIER_TYPE_GEOMETRY:
1682       changed = BKE_linestyle_geometry_modifier_move(lineset->linestyle, modifier, dir);
1683       break;
1684     default:
1685       BKE_report(
1686           op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1687       return OPERATOR_CANCELLED;
1688   }
1689
1690   if (changed) {
1691     DEG_id_tag_update(&lineset->linestyle->id, 0);
1692     WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1693   }
1694
1695   return OPERATOR_FINISHED;
1696 }
1697
1698 void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot)
1699 {
1700   static const EnumPropertyItem direction_items[] = {
1701       {-1, "UP", 0, "Up", ""},
1702       {1, "DOWN", 0, "Down", ""},
1703       {0, NULL, 0, NULL, NULL},
1704   };
1705
1706   /* identifiers */
1707   ot->name = "Move Modifier";
1708   ot->idname = "SCENE_OT_freestyle_modifier_move";
1709   ot->description = "Move the modifier within the list of modifiers";
1710
1711   /* api callbacks */
1712   ot->exec = freestyle_modifier_move_exec;
1713   ot->poll = freestyle_active_lineset_poll;
1714
1715   /* flags */
1716   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1717
1718   /* props */
1719   RNA_def_enum(ot->srna,
1720                "direction",
1721                direction_items,
1722                0,
1723                "Direction",
1724                "Direction to move the chosen modifier towards");
1725 }
1726
1727 static int freestyle_stroke_material_create_exec(bContext *C, wmOperator *op)
1728 {
1729   Main *bmain = CTX_data_main(C);
1730   ViewLayer *view_layer = CTX_data_view_layer(C);
1731   FreestyleLineStyle *linestyle = BKE_linestyle_active_from_view_layer(view_layer);
1732
1733   if (!linestyle) {
1734     BKE_report(op->reports, RPT_ERROR, "No active line style in the current scene");
1735     return OPERATOR_CANCELLED;
1736   }
1737
1738   FRS_create_stroke_material(bmain, linestyle);
1739
1740   return OPERATOR_FINISHED;
1741 }
1742
1743 void SCENE_OT_freestyle_stroke_material_create(wmOperatorType *ot)
1744 {
1745   /* identifiers */
1746   ot->name = "Create Freestyle Stroke Material";
1747   ot->idname = "SCENE_OT_freestyle_stroke_material_create";
1748   ot->description = "Create Freestyle stroke material for testing";
1749
1750   /* api callbacks */
1751   ot->exec = freestyle_stroke_material_create_exec;
1752
1753   /* flags */
1754   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1755 }
1756
1757 #endif /* WITH_FREESTYLE */
1758
1759 static int texture_slot_move_exec(bContext *C, wmOperator *op)
1760 {
1761   ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1762
1763   if (id) {
1764     MTex **mtex_ar, *mtexswap;
1765     short act;
1766     int type = RNA_enum_get(op->ptr, "type");
1767     struct AnimData *adt = BKE_animdata_from_id(id);
1768
1769     give_active_mtex(id, &mtex_ar, &act);
1770
1771     if (type == -1) { /* Up */
1772       if (act > 0) {
1773         mtexswap = mtex_ar[act];
1774         mtex_ar[act] = mtex_ar[act - 1];
1775         mtex_ar[act - 1] = mtexswap;
1776
1777         BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act - 1, -1, 0);
1778         BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act - 1, 0);
1779         BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
1780
1781         set_active_mtex(id, act - 1);
1782       }
1783     }
1784     else { /* Down */
1785       if (act < MAX_MTEX - 1) {
1786         mtexswap = mtex_ar[act];
1787         mtex_ar[act] = mtex_ar[act + 1];
1788         mtex_ar[act + 1] = mtexswap;
1789
1790         BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act + 1, -1, 0);
1791         BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act + 1, 0);
1792         BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
1793
1794         set_active_mtex(id, act + 1);
1795       }
1796     }
1797
1798     DEG_id_tag_update(id, 0);
1799     WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C));
1800   }
1801
1802   return OPERATOR_FINISHED;
1803 }
1804
1805 void TEXTURE_OT_slot_move(wmOperatorType *ot)
1806 {
1807   static const EnumPropertyItem slot_move[] = {
1808       {-1, "UP", 0, "Up", ""},
1809       {1, "DOWN", 0, "Down", ""},
1810       {0, NULL, 0, NULL, NULL},
1811   };
1812
1813   /* identifiers */
1814   ot->name = "Move Texture Slot";
1815   ot->idname = "TEXTURE_OT_slot_move";
1816   ot->description = "Move texture slots up and down";
1817
1818   /* api callbacks */
1819   ot->exec = texture_slot_move_exec;
1820
1821   /* flags */
1822   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1823
1824   RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
1825 }
1826
1827 /********************** material operators *********************/
1828
1829 /* material copy/paste */
1830 static int copy_material_exec(bContext *C, wmOperator *UNUSED(op))
1831 {
1832   Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1833
1834   if (ma == NULL)
1835     return OPERATOR_CANCELLED;
1836
1837   copy_matcopybuf(CTX_data_main(C), ma);
1838
1839   return OPERATOR_FINISHED;
1840 }
1841
1842 void MATERIAL_OT_copy(wmOperatorType *ot)
1843 {
1844   /* identifiers */
1845   ot->name = "Copy Material";
1846   ot->idname = "MATERIAL_OT_copy";
1847   ot->description = "Copy the material settings and nodes";
1848
1849   /* api callbacks */
1850   ot->exec = copy_material_exec;
1851
1852   /* flags */
1853   /* no undo needed since no changes are made to the material */
1854   ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
1855 }
1856
1857 static int paste_material_exec(bContext *C, wmOperator *UNUSED(op))
1858 {
1859   Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1860
1861   if (ma == NULL)
1862     return OPERATOR_CANCELLED;
1863
1864   paste_matcopybuf(CTX_data_main(C), ma);
1865
1866   DEG_id_tag_update(&ma->id, ID_RECALC_COPY_ON_WRITE);
1867   WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
1868
1869   return OPERATOR_FINISHED;
1870 }
1871
1872 void MATERIAL_OT_paste(wmOperatorType *ot)
1873 {
1874   /* identifiers */
1875   ot->name = "Paste Material";
1876   ot->idname = "MATERIAL_OT_paste";
1877   ot->description = "Paste the material settings and nodes";
1878
1879   /* api callbacks */
1880   ot->exec = paste_material_exec;
1881
1882   /* flags */
1883   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1884 }
1885
1886 static short mtexcopied = 0; /* must be reset on file load */
1887 static MTex mtexcopybuf;
1888
1889 void ED_render_clear_mtex_copybuf(void)
1890 { /* use for file reload */
1891   mtexcopied = 0;
1892 }
1893
1894 static void copy_mtex_copybuf(ID *id)
1895 {
1896   MTex **mtex = NULL;
1897
1898   switch (GS(id->name)) {
1899     case ID_PA:
1900       mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
1901       break;
1902     case ID_LS:
1903       mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
1904       break;
1905     default:
1906       break;
1907   }
1908
1909   if (mtex && *mtex) {
1910     memcpy(&mtexcopybuf, *mtex, sizeof(MTex));
1911     mtexcopied = 1;
1912   }
1913   else {
1914     mtexcopied = 0;
1915   }
1916 }
1917
1918 static void paste_mtex_copybuf(ID *id)
1919 {
1920   MTex **mtex = NULL;
1921
1922   if (mtexcopied == 0 || mtexcopybuf.tex == NULL)
1923     return;
1924
1925   switch (GS(id->name)) {
1926     case ID_PA:
1927       mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
1928       break;
1929     case ID_LS:
1930       mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
1931       break;
1932     default:
1933       BLI_assert(!"invalid id type");
1934       return;
1935   }
1936
1937   if (mtex) {
1938     if (*mtex == NULL) {
1939       *mtex = MEM_mallocN(sizeof(MTex), "mtex copy");
1940     }
1941     else if ((*mtex)->tex) {
1942       id_us_min(&(*mtex)->tex->id);
1943     }
1944
1945     memcpy(*mtex, &mtexcopybuf, sizeof(MTex));
1946
1947     id_us_plus((ID *)mtexcopybuf.tex);
1948   }
1949 }
1950
1951 static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op))
1952 {
1953   ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1954
1955   if (id == NULL) {
1956     /* copying empty slot */
1957     ED_render_clear_mtex_copybuf();
1958     return OPERATOR_CANCELLED;
1959   }
1960
1961   copy_mtex_copybuf(id);
1962
1963   return OPERATOR_FINISHED;
1964 }
1965
1966 static bool copy_mtex_poll(bContext *C)
1967 {
1968   ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1969
1970   return (id != NULL);
1971 }
1972
1973 void TEXTURE_OT_slot_copy(wmOperatorType *ot)
1974 {
1975   /* identifiers */
1976   ot->name = "Copy Texture Slot Settings";
1977   ot->idname = "TEXTURE_OT_slot_copy";
1978   ot->description = "Copy the material texture settings and nodes";
1979
1980   /* api callbacks */
1981   ot->exec = copy_mtex_exec;
1982   ot->poll = copy_mtex_poll;
1983
1984   /* flags */
1985   /* no undo needed since no changes are made to the mtex */
1986   ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
1987 }
1988
1989 static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
1990 {
1991   ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1992
1993   if (id == NULL) {
1994     Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1995     Light *la = CTX_data_pointer_get_type(C, "light", &RNA_Light).data;
1996     World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
1997     ParticleSystem *psys =
1998         CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
1999     FreestyleLineStyle *linestyle =
2000         CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data;
2001
2002     if (ma)
2003       id = &ma->id;
2004     else if (la)
2005       id = &la->id;
2006     else if (wo)
2007       id = &wo->id;
2008     else if (psys)
2009       id = &psys->part->id;
2010     else if (linestyle)
2011       id = &linestyle->id;
2012
2013     if (id == NULL)
2014       return OPERATOR_CANCELLED;
2015   }
2016
2017   paste_mtex_copybuf(id);
2018
2019   WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_LINKS, NULL);
2020
2021   return OPERATOR_FINISHED;
2022 }
2023
2024 void TEXTURE_OT_slot_paste(wmOperatorType *ot)
2025 {
2026   /* identifiers */
2027   ot->name = "Paste Texture Slot Settings";
2028   ot->idname = "TEXTURE_OT_slot_paste";
2029   ot->description = "Copy the texture settings and nodes";
2030
2031   /* api callbacks */
2032   ot->exec = paste_mtex_exec;
2033
2034   /* flags */
2035   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
2036 }