2.5: Render
[blender-staging.git] / source / blender / editors / space_buttons / buttons_ops.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "DNA_curve_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_material_types.h"
36 #include "DNA_node_types.h"
37 #include "DNA_texture_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_world_types.h"
40
41 #include "BKE_context.h"
42 #include "BKE_depsgraph.h"
43 #include "BKE_font.h"
44 #include "BKE_library.h"
45 #include "BKE_main.h"
46 #include "BKE_material.h"
47 #include "BKE_node.h"
48 #include "BKE_particle.h"
49 #include "BKE_scene.h"
50 #include "BKE_texture.h"
51 #include "BKE_utildefines.h"
52 #include "BKE_world.h"
53
54 #include "BLI_editVert.h"
55 #include "BLI_listbase.h"
56
57 #include "RNA_access.h"
58
59 #include "WM_api.h"
60 #include "WM_types.h"
61
62 #include "ED_curve.h"
63 #include "ED_mesh.h"
64
65 #include "buttons_intern.h"     // own include
66
67 /********************** material slot operators *********************/
68
69 static int material_slot_add_exec(bContext *C, wmOperator *op)
70 {
71         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
72
73         if(!ob)
74                 return OPERATOR_CANCELLED;
75
76         object_add_material_slot(ob);
77         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
78         
79         return OPERATOR_FINISHED;
80 }
81
82 void OBJECT_OT_material_slot_add(wmOperatorType *ot)
83 {
84         /* identifiers */
85         ot->name= "Add Material Slot";
86         ot->idname= "OBJECT_OT_material_slot_add";
87         
88         /* api callbacks */
89         ot->exec= material_slot_add_exec;
90
91         /* flags */
92         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
93 }
94
95 static int material_slot_remove_exec(bContext *C, wmOperator *op)
96 {
97         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
98
99         if(!ob)
100                 return OPERATOR_CANCELLED;
101
102         object_remove_material_slot(ob);
103         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
104         
105         return OPERATOR_FINISHED;
106 }
107
108 void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
109 {
110         /* identifiers */
111         ot->name= "Remove Material Slot";
112         ot->idname= "OBJECT_OT_material_slot_remove";
113         
114         /* api callbacks */
115         ot->exec= material_slot_remove_exec;
116
117         /* flags */
118         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
119 }
120
121 static int material_slot_assign_exec(bContext *C, wmOperator *op)
122 {
123         Scene *scene= CTX_data_scene(C);
124         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
125
126         if(!ob)
127                 return OPERATOR_CANCELLED;
128
129         if(ob && ob->actcol>0) {
130                 if(ob->type == OB_MESH) {
131                         EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
132                         EditFace *efa;
133
134                         if(em) {
135                                 for(efa= em->faces.first; efa; efa=efa->next)
136                                         if(efa->f & SELECT)
137                                                 efa->mat_nr= ob->actcol-1;
138                         }
139                 }
140                 else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
141                         ListBase *editnurb= ((Curve*)ob->data)->editnurb;
142                         Nurb *nu;
143
144                         if(editnurb) {
145                                 for(nu= editnurb->first; nu; nu= nu->next)
146                                         if(isNurbsel(nu))
147                                                 nu->mat_nr= nu->charidx= ob->actcol-1;
148                         }
149                 }
150                 else if(ob->type == OB_FONT) {
151                         EditFont *ef= ((Curve*)ob->data)->editfont;
152                 int i, selstart, selend;
153
154                         if(ef && BKE_font_getselection(ob, &selstart, &selend)) {
155                                 for(i=selstart; i<=selend; i++)
156                                         ef->textbufinfo[i].mat_nr = ob->actcol-1;
157                         }
158                 }
159         }
160
161     DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
162     WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
163         
164         return OPERATOR_FINISHED;
165 }
166
167 void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
168 {
169         /* identifiers */
170         ot->name= "Assign Material Slot";
171         ot->idname= "OBJECT_OT_material_slot_assign";
172         
173         /* api callbacks */
174         ot->exec= material_slot_assign_exec;
175
176         /* flags */
177         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
178 }
179
180 static int material_slot_de_select(bContext *C, int select)
181 {
182         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
183
184         if(!ob)
185                 return OPERATOR_CANCELLED;
186
187         if(ob->type == OB_MESH) {
188                 EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
189
190                 if(em) {
191                         if(select)
192                                 EM_select_by_material(em, ob->actcol-1);
193                         else
194                                 EM_deselect_by_material(em, ob->actcol-1);
195                 }
196         }
197         else if ELEM(ob->type, OB_CURVE, OB_SURF) {
198                 ListBase *editnurb= ((Curve*)ob->data)->editnurb;
199                 Nurb *nu;
200                 BPoint *bp;
201                 BezTriple *bezt;
202                 int a;
203
204                 for(nu= editnurb->first; nu; nu=nu->next) {
205                         if(nu->mat_nr==ob->actcol-1) {
206                                 if(nu->bezt) {
207                                         a= nu->pntsu;
208                                         bezt= nu->bezt;
209                                         while(a--) {
210                                                 if(bezt->hide==0) {
211                                                         if(select) {
212                                                                 bezt->f1 |= SELECT;
213                                                                 bezt->f2 |= SELECT;
214                                                                 bezt->f3 |= SELECT;
215                                                         }
216                                                         else {
217                                                                 bezt->f1 &= ~SELECT;
218                                                                 bezt->f2 &= ~SELECT;
219                                                                 bezt->f3 &= ~SELECT;
220                                                         }
221                                                 }
222                                                 bezt++;
223                                         }
224                                 }
225                                 else if(nu->bp) {
226                                         a= nu->pntsu*nu->pntsv;
227                                         bp= nu->bp;
228                                         while(a--) {
229                                                 if(bp->hide==0) {
230                                                         if(select) bp->f1 |= SELECT;
231                                                         else bp->f1 &= ~SELECT;
232                                                 }
233                                                 bp++;
234                                         }
235                                 }
236                         }
237                 }
238         }
239
240     WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
241
242         return OPERATOR_FINISHED;
243 }
244
245 static int material_slot_select_exec(bContext *C, wmOperator *op)
246 {
247         return material_slot_de_select(C, 1);
248 }
249
250 void OBJECT_OT_material_slot_select(wmOperatorType *ot)
251 {
252         /* identifiers */
253         ot->name= "Select Material Slot";
254         ot->idname= "OBJECT_OT_material_slot_select";
255         
256         /* api callbacks */
257         ot->exec= material_slot_select_exec;
258
259         /* flags */
260         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
261 }
262
263 static int material_slot_deselect_exec(bContext *C, wmOperator *op)
264 {
265         return material_slot_de_select(C, 0);
266 }
267
268 void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
269 {
270         /* identifiers */
271         ot->name= "Deselect Material Slot";
272         ot->idname= "OBJECT_OT_material_slot_deselect";
273         
274         /* api callbacks */
275         ot->exec= material_slot_deselect_exec;
276
277         /* flags */
278         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
279 }
280
281 /********************** new material operator *********************/
282
283 static int new_material_exec(bContext *C, wmOperator *op)
284 {
285         Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
286         Object *ob;
287         PointerRNA ptr;
288         int index;
289
290         /* add or copy material */
291         if(ma)
292                 ma= copy_material(ma);
293         else
294                 ma= add_material("Material");
295
296         ma->id.us--; /* compensating for us++ in assign_material */
297
298         /* attempt to assign to material slot */
299         ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
300
301         if(ptr.data) {
302                 ob= ptr.id.data;
303                 index= (Material**)ptr.data - ob->mat;
304
305                 assign_material(ob, ma, index+1);
306
307                 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
308         }
309
310         WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma);
311         
312         return OPERATOR_FINISHED;
313 }
314
315 void MATERIAL_OT_new(wmOperatorType *ot)
316 {
317         /* identifiers */
318         ot->name= "New Material";
319         ot->idname= "MATERIAL_OT_new";
320         
321         /* api callbacks */
322         ot->exec= new_material_exec;
323
324         /* flags */
325         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
326 }
327
328 /********************** new texture operator *********************/
329
330 static int new_texture_exec(bContext *C, wmOperator *op)
331 {
332         Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
333         ID *id;
334         MTex *mtex;
335         PointerRNA ptr;
336
337         /* add or copy texture */
338         if(tex)
339                 tex= copy_texture(tex);
340         else
341                 tex= add_texture("Texture");
342
343         id_us_min(&tex->id);
344
345         /* attempt to assign to texture slot */
346         ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot);
347
348         if(ptr.data) {
349                 id= ptr.id.data;
350                 mtex= ptr.data;
351
352                 if(mtex) {
353                         if(mtex->tex)
354                                 id_us_min(&mtex->tex->id);
355                         mtex->tex= tex;
356                         id_us_plus(&tex->id);
357                 }
358
359                 /* XXX nodes, notifier .. */
360         }
361
362         WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex);
363         
364         return OPERATOR_FINISHED;
365 }
366
367 void TEXTURE_OT_new(wmOperatorType *ot)
368 {
369         /* identifiers */
370         ot->name= "New Texture";
371         ot->idname= "TEXTURE_OT_new";
372         
373         /* api callbacks */
374         ot->exec= new_texture_exec;
375
376         /* flags */
377         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
378 }
379
380 /********************** new world operator *********************/
381
382 static int new_world_exec(bContext *C, wmOperator *op)
383 {
384         Scene *scene= CTX_data_scene(C);
385         World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data;
386
387         /* add or copy world */
388         if(wo)
389                 wo= copy_world(wo);
390         else
391                 wo= add_world("World");
392
393         /* assign to scene */
394         if(scene->world)
395                 id_us_min(&scene->world->id);
396         scene->world= wo;
397
398         WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo);
399         
400         return OPERATOR_FINISHED;
401 }
402
403 void WORLD_OT_new(wmOperatorType *ot)
404 {
405         /* identifiers */
406         ot->name= "New World";
407         ot->idname= "WORLD_OT_new";
408         
409         /* api callbacks */
410         ot->exec= new_world_exec;
411
412         /* flags */
413         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
414 }
415
416
417
418 /********************** particle system slot operators *********************/
419
420 static int particle_system_add_exec(bContext *C, wmOperator *op)
421 {
422         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
423         Scene *scene = CTX_data_scene(C);
424
425         if(!scene || !ob)
426                 return OPERATOR_CANCELLED;
427
428         object_add_particle_system(scene, ob);
429         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
430         
431         return OPERATOR_FINISHED;
432 }
433
434 void OBJECT_OT_particle_system_add(wmOperatorType *ot)
435 {
436         /* identifiers */
437         ot->name= "Add Particle System Slot";
438         ot->idname= "OBJECT_OT_particle_system_add";
439         
440         /* api callbacks */
441         ot->exec= particle_system_add_exec;
442
443         /* flags */
444         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
445 }
446
447 static int particle_system_remove_exec(bContext *C, wmOperator *op)
448 {
449         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
450         Scene *scene = CTX_data_scene(C);
451
452         if(!scene || !ob)
453                 return OPERATOR_CANCELLED;
454
455         object_remove_particle_system(scene, ob);
456         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
457         
458         return OPERATOR_FINISHED;
459 }
460
461 void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
462 {
463         /* identifiers */
464         ot->name= "Remove Particle System Slot";
465         ot->idname= "OBJECT_OT_particle_system_remove";
466         
467         /* api callbacks */
468         ot->exec= particle_system_remove_exec;
469
470         /* flags */
471         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
472 }
473
474 /********************** new particle settings operator *********************/
475
476 static int new_particle_settings_exec(bContext *C, wmOperator *op)
477 {
478         Scene *scene = CTX_data_scene(C);
479         Main *bmain= CTX_data_main(C);
480         ParticleSystem *psys;
481         ParticleSettings *part = NULL;
482         Object *ob;
483         PointerRNA ptr;
484
485         ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
486
487         psys = ptr.data;
488
489         /* add or copy particle setting */
490         if(psys->part)
491                 part= psys_copy_settings(psys->part);
492         else
493                 part= psys_new_settings("PSys", bmain);
494
495         ob= ptr.id.data;
496
497         if(psys->part)
498                 psys->part->id.us--;
499
500         psys->part = part;
501
502         DAG_scene_sort(scene);
503         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
504
505         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
506         
507         return OPERATOR_FINISHED;
508 }
509
510 void PARTICLE_OT_new(wmOperatorType *ot)
511 {
512         /* identifiers */
513         ot->name= "New Particle Settings";
514         ot->idname= "PARTICLE_OT_new";
515         
516         /* api callbacks */
517         ot->exec= new_particle_settings_exec;
518
519         /* flags */
520         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
521 }
522
523 /********************** keyed particle target operators *********************/
524
525 static int new_keyed_particle_target_exec(bContext *C, wmOperator *op)
526 {
527         Scene *scene = CTX_data_scene(C);
528         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
529         ParticleSystem *psys= ptr.data;
530         Object *ob = ptr.id.data;
531
532         KeyedParticleTarget *kpt;
533
534         if(!psys)
535                 return OPERATOR_CANCELLED;
536
537         kpt = psys->keyed_targets.first;
538         for(; kpt; kpt=kpt->next)
539                 kpt->flag &= ~KEYED_TARGET_CURRENT;
540
541         kpt = MEM_callocN(sizeof(KeyedParticleTarget), "keyed particle target");
542
543         kpt->flag |= KEYED_TARGET_CURRENT;
544         kpt->psys = 1;
545
546         BLI_addtail(&psys->keyed_targets, kpt);
547
548         DAG_scene_sort(scene);
549         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
550
551         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
552         
553         return OPERATOR_FINISHED;
554 }
555
556 void PARTICLE_OT_new_keyed_target(wmOperatorType *ot)
557 {
558         /* identifiers */
559         ot->name= "New Keyed Particle Target";
560         ot->idname= "PARTICLE_OT_new_keyed_target";
561         
562         /* api callbacks */
563         ot->exec= new_keyed_particle_target_exec;
564
565         /* flags */
566         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
567 }
568
569 static int remove_keyed_particle_target_exec(bContext *C, wmOperator *op)
570 {
571         Scene *scene = CTX_data_scene(C);
572         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
573         ParticleSystem *psys= ptr.data;
574         Object *ob = ptr.id.data;
575
576         KeyedParticleTarget *kpt;
577
578         if(!psys)
579                 return OPERATOR_CANCELLED;
580
581         kpt = psys->keyed_targets.first;
582         for(; kpt; kpt=kpt->next) {
583                 if(kpt->flag & KEYED_TARGET_CURRENT) {
584                         BLI_remlink(&psys->keyed_targets, kpt);
585                         MEM_freeN(kpt);
586                         break;
587                 }
588
589         }
590         kpt = psys->keyed_targets.last;
591
592         if(kpt)
593                 kpt->flag |= KEYED_TARGET_CURRENT;
594
595         DAG_scene_sort(scene);
596         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
597
598         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
599         
600         return OPERATOR_FINISHED;
601 }
602
603 void PARTICLE_OT_remove_keyed_target(wmOperatorType *ot)
604 {
605         /* identifiers */
606         ot->name= "Remove Keyed Particle Target";
607         ot->idname= "PARTICLE_OT_remove_keyed_target";
608         
609         /* api callbacks */
610         ot->exec= remove_keyed_particle_target_exec;
611
612         /* flags */
613         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
614 }
615
616 /************************ move up modifier operator *********************/
617
618 static int keyed_target_move_up_exec(bContext *C, wmOperator *op)
619 {
620         Scene *scene= CTX_data_scene(C);
621         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
622         ParticleSystem *psys= ptr.data;
623         Object *ob = ptr.id.data;
624         KeyedParticleTarget *kpt;
625
626         if(!psys)
627                 return OPERATOR_CANCELLED;
628         
629         kpt = psys->keyed_targets.first;
630         for(; kpt; kpt=kpt->next) {
631                 if(kpt->flag & KEYED_TARGET_CURRENT && kpt->prev) {
632                         BLI_remlink(&psys->keyed_targets, kpt);
633                         BLI_insertlink(&psys->keyed_targets, kpt->prev->prev, kpt);
634
635                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
636                         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
637                         break;
638                 }
639         }
640         
641         return OPERATOR_FINISHED;
642 }
643
644 void PARTICLE_OT_keyed_target_move_up(wmOperatorType *ot)
645 {
646         ot->name= "Move Up Keyed Target";
647         ot->description= "Move keyed particle target up in the list.";
648         ot->idname= "PARTICLE_OT_keyed_target_move_up";
649
650         ot->exec= keyed_target_move_up_exec;
651         
652         /* flags */
653         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
654 }
655
656 /************************ move down modifier operator *********************/
657
658 static int keyed_target_move_down_exec(bContext *C, wmOperator *op)
659 {
660         Scene *scene= CTX_data_scene(C);
661         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
662         ParticleSystem *psys= ptr.data;
663         Object *ob = ptr.id.data;
664         KeyedParticleTarget *kpt;
665
666         if(!psys)
667                 return OPERATOR_CANCELLED;
668         kpt = psys->keyed_targets.first;
669         for(; kpt; kpt=kpt->next) {
670                 if(kpt->flag & KEYED_TARGET_CURRENT && kpt->next) {
671                         BLI_remlink(&psys->keyed_targets, kpt);
672                         BLI_insertlink(&psys->keyed_targets, kpt->next, kpt);
673
674                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
675                         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
676                         break;
677                 }
678         }
679         
680         return OPERATOR_FINISHED;
681 }
682
683 void PARTICLE_OT_keyed_target_move_down(wmOperatorType *ot)
684 {
685         ot->name= "Move Down Keyed Target";
686         ot->description= "Move keyed particle target down in the list.";
687         ot->idname= "PARTICLE_OT_keyed_target_move_down";
688
689         ot->exec= keyed_target_move_down_exec;
690         
691         /* flags */
692         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
693 }
694
695 /********************** render layer operators *********************/
696
697 static int render_layer_add_exec(bContext *C, wmOperator *op)
698 {
699         Scene *scene= CTX_data_scene(C);
700
701         scene_add_render_layer(scene);
702         scene->r.actlay= BLI_countlist(&scene->r.layers) - 1;
703
704         WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene);
705         
706         return OPERATOR_FINISHED;
707 }
708
709 void SCENE_OT_render_layer_add(wmOperatorType *ot)
710 {
711         /* identifiers */
712         ot->name= "Add Render Layer";
713         ot->idname= "SCENE_OT_render_layer_add";
714         
715         /* api callbacks */
716         ot->exec= render_layer_add_exec;
717
718         /* flags */
719         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
720 }
721
722 static int render_layer_remove_exec(bContext *C, wmOperator *op)
723 {
724         Scene *scene= CTX_data_scene(C);
725         SceneRenderLayer *rl;
726         int act= scene->r.actlay;
727
728         if(BLI_countlist(&scene->r.layers) <= 1)
729                 return OPERATOR_CANCELLED;
730         
731         rl= BLI_findlink(&scene->r.layers, scene->r.actlay);
732         BLI_remlink(&scene->r.layers, rl);
733         MEM_freeN(rl);
734
735         scene->r.actlay= 0;
736         
737         if(scene->nodetree) {
738                 bNode *node;
739                 for(node= scene->nodetree->nodes.first; node; node= node->next) {
740                         if(node->type==CMP_NODE_R_LAYERS && node->id==NULL) {
741                                 if(node->custom1==act)
742                                         node->custom1= 0;
743                                 else if(node->custom1>act)
744                                         node->custom1--;
745                         }
746                 }
747         }
748
749         WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene);
750         
751         return OPERATOR_FINISHED;
752 }
753
754 void SCENE_OT_render_layer_remove(wmOperatorType *ot)
755 {
756         /* identifiers */
757         ot->name= "Remove Render Layer";
758         ot->idname= "SCENE_OT_render_layer_remove";
759         
760         /* api callbacks */
761         ot->exec= render_layer_remove_exec;
762
763         /* flags */
764         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
765 }