4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20 * The Original Code is Copyright (C) 2009 Blender Foundation.
21 * All rights reserved.
23 * Contributor(s): Blender Foundation
25 * ***** END GPL LICENSE BLOCK *****
31 #include "MEM_guardedalloc.h"
33 #include "DNA_boid_types.h"
34 #include "DNA_curve_types.h"
35 #include "DNA_group_types.h"
36 #include "DNA_object_types.h"
37 #include "DNA_material_types.h"
38 #include "DNA_node_types.h"
39 #include "DNA_texture_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_world_types.h"
43 #include "BKE_context.h"
44 #include "BKE_depsgraph.h"
45 #include "BKE_group.h"
47 #include "BKE_library.h"
49 #include "BKE_material.h"
51 #include "BKE_particle.h"
52 #include "BKE_scene.h"
53 #include "BKE_texture.h"
54 #include "BKE_utildefines.h"
55 #include "BKE_world.h"
57 #include "BLI_editVert.h"
58 #include "BLI_listbase.h"
60 #include "RNA_access.h"
61 #include "RNA_enum_types.h"
69 #include "RNA_access.h"
70 #include "RNA_define.h"
72 #include "buttons_intern.h" // own include
75 /********************** group operators *********************/
77 static int group_add_exec(bContext *C, wmOperator *op)
79 Main *bmain= CTX_data_main(C);
80 Scene *scene= CTX_data_scene(C);
81 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
84 int value= RNA_enum_get(op->ptr, "group");
87 return OPERATOR_CANCELLED;
89 base= object_in_scene(ob, scene);
91 return OPERATOR_CANCELLED;
94 group= add_group( "Group" );
96 group= BLI_findlink(&bmain->group, value);
99 add_to_group(group, ob);
100 ob->flag |= OB_FROMGROUP;
101 base->flag |= OB_FROMGROUP;
104 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
106 return OPERATOR_FINISHED;
109 static EnumPropertyItem group_items[]= {
110 {-1, "ADD_NEW", 0, "Add New Group", ""},
111 {0, NULL, 0, NULL, NULL}};
113 static EnumPropertyItem *group_itemf(bContext *C, PointerRNA *ptr, int *free)
115 EnumPropertyItem tmp = {0, "", 0, "", ""};
116 EnumPropertyItem *item= NULL;
121 if(!C) /* needed for docs */
124 RNA_enum_items_add_value(&item, &totitem, group_items, -1);
126 bmain= CTX_data_main(C);
127 if(bmain->group.first)
128 RNA_enum_item_add_separator(&item, &totitem);
130 for(a=0, group=bmain->group.first; group; group=group->id.next, a++) {
132 tmp.identifier= group->id.name+2;
133 tmp.name= group->id.name+2;
134 RNA_enum_item_add(&item, &totitem, &tmp);
137 RNA_enum_item_end(&item, &totitem);
144 void OBJECT_OT_group_add(wmOperatorType *ot)
149 ot->name= "Add Group";
150 ot->idname= "OBJECT_OT_group_add";
153 ot->exec= group_add_exec;
156 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
159 prop= RNA_def_enum(ot->srna, "group", group_items, -1, "Group", "Group to add object to.");
160 RNA_def_enum_funcs(prop, group_itemf);
163 static int group_remove_exec(bContext *C, wmOperator *op)
165 Scene *scene= CTX_data_scene(C);
166 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
167 Group *group= CTX_data_pointer_get_type(C, "group", &RNA_Group).data;
171 return OPERATOR_CANCELLED;
173 base= object_in_scene(ob, scene);
175 return OPERATOR_CANCELLED;
177 rem_from_group(group, ob);
179 if(find_group(ob, NULL) == NULL) {
180 ob->flag &= ~OB_FROMGROUP;
181 base->flag &= ~OB_FROMGROUP;
184 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
186 return OPERATOR_FINISHED;
189 void OBJECT_OT_group_remove(wmOperatorType *ot)
192 ot->name= "Remove Group";
193 ot->idname= "OBJECT_OT_group_remove";
196 ot->exec= group_remove_exec;
199 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
202 /********************** material slot operators *********************/
204 static int material_slot_add_exec(bContext *C, wmOperator *op)
206 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
209 return OPERATOR_CANCELLED;
211 object_add_material_slot(ob);
212 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
214 return OPERATOR_FINISHED;
217 void OBJECT_OT_material_slot_add(wmOperatorType *ot)
220 ot->name= "Add Material Slot";
221 ot->idname= "OBJECT_OT_material_slot_add";
224 ot->exec= material_slot_add_exec;
227 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
230 static int material_slot_remove_exec(bContext *C, wmOperator *op)
232 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
235 return OPERATOR_CANCELLED;
237 object_remove_material_slot(ob);
238 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
240 return OPERATOR_FINISHED;
243 void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
246 ot->name= "Remove Material Slot";
247 ot->idname= "OBJECT_OT_material_slot_remove";
250 ot->exec= material_slot_remove_exec;
253 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
256 static int material_slot_assign_exec(bContext *C, wmOperator *op)
258 Scene *scene= CTX_data_scene(C);
259 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
262 return OPERATOR_CANCELLED;
264 if(ob && ob->actcol>0) {
265 if(ob->type == OB_MESH) {
266 EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
270 for(efa= em->faces.first; efa; efa=efa->next)
272 efa->mat_nr= ob->actcol-1;
275 else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
276 ListBase *editnurb= ((Curve*)ob->data)->editnurb;
280 for(nu= editnurb->first; nu; nu= nu->next)
282 nu->mat_nr= nu->charidx= ob->actcol-1;
285 else if(ob->type == OB_FONT) {
286 EditFont *ef= ((Curve*)ob->data)->editfont;
287 int i, selstart, selend;
289 if(ef && BKE_font_getselection(ob, &selstart, &selend)) {
290 for(i=selstart; i<=selend; i++)
291 ef->textbufinfo[i].mat_nr = ob->actcol-1;
296 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
297 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
299 return OPERATOR_FINISHED;
302 void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
305 ot->name= "Assign Material Slot";
306 ot->idname= "OBJECT_OT_material_slot_assign";
309 ot->exec= material_slot_assign_exec;
312 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
315 static int material_slot_de_select(bContext *C, int select)
317 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
320 return OPERATOR_CANCELLED;
322 if(ob->type == OB_MESH) {
323 EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
327 EM_select_by_material(em, ob->actcol-1);
329 EM_deselect_by_material(em, ob->actcol-1);
332 else if ELEM(ob->type, OB_CURVE, OB_SURF) {
333 ListBase *editnurb= ((Curve*)ob->data)->editnurb;
339 for(nu= editnurb->first; nu; nu=nu->next) {
340 if(nu->mat_nr==ob->actcol-1) {
361 a= nu->pntsu*nu->pntsv;
365 if(select) bp->f1 |= SELECT;
366 else bp->f1 &= ~SELECT;
375 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
377 return OPERATOR_FINISHED;
380 static int material_slot_select_exec(bContext *C, wmOperator *op)
382 return material_slot_de_select(C, 1);
385 void OBJECT_OT_material_slot_select(wmOperatorType *ot)
388 ot->name= "Select Material Slot";
389 ot->idname= "OBJECT_OT_material_slot_select";
392 ot->exec= material_slot_select_exec;
395 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
398 static int material_slot_deselect_exec(bContext *C, wmOperator *op)
400 return material_slot_de_select(C, 0);
403 void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
406 ot->name= "Deselect Material Slot";
407 ot->idname= "OBJECT_OT_material_slot_deselect";
410 ot->exec= material_slot_deselect_exec;
413 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
416 /********************** new material operator *********************/
418 static int new_material_exec(bContext *C, wmOperator *op)
420 Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
425 /* add or copy material */
427 ma= copy_material(ma);
429 ma= add_material("Material");
431 ma->id.us--; /* compensating for us++ in assign_material */
433 /* attempt to assign to material slot */
434 ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
438 index= (Material**)ptr.data - ob->mat;
440 assign_material(ob, ma, index+1);
442 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
445 WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma);
447 return OPERATOR_FINISHED;
450 void MATERIAL_OT_new(wmOperatorType *ot)
453 ot->name= "New Material";
454 ot->idname= "MATERIAL_OT_new";
457 ot->exec= new_material_exec;
460 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
463 /********************** new texture operator *********************/
465 static int new_texture_exec(bContext *C, wmOperator *op)
467 Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
472 /* add or copy texture */
474 tex= copy_texture(tex);
476 tex= add_texture("Texture");
480 /* attempt to assign to texture slot */
481 ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot);
489 id_us_min(&mtex->tex->id);
491 id_us_plus(&tex->id);
494 /* XXX nodes, notifier .. */
497 WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex);
499 return OPERATOR_FINISHED;
502 void TEXTURE_OT_new(wmOperatorType *ot)
505 ot->name= "New Texture";
506 ot->idname= "TEXTURE_OT_new";
509 ot->exec= new_texture_exec;
512 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
515 /********************** new world operator *********************/
517 static int new_world_exec(bContext *C, wmOperator *op)
519 Scene *scene= CTX_data_scene(C);
520 World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data;
522 /* add or copy world */
526 wo= add_world("World");
528 /* assign to scene */
530 id_us_min(&scene->world->id);
533 WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo);
535 return OPERATOR_FINISHED;
538 void WORLD_OT_new(wmOperatorType *ot)
541 ot->name= "New World";
542 ot->idname= "WORLD_OT_new";
545 ot->exec= new_world_exec;
548 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
553 /********************** particle system slot operators *********************/
555 static int particle_system_add_exec(bContext *C, wmOperator *op)
557 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
558 Scene *scene = CTX_data_scene(C);
561 return OPERATOR_CANCELLED;
563 object_add_particle_system(scene, ob);
564 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
566 return OPERATOR_FINISHED;
569 void OBJECT_OT_particle_system_add(wmOperatorType *ot)
572 ot->name= "Add Particle System Slot";
573 ot->idname= "OBJECT_OT_particle_system_add";
576 ot->exec= particle_system_add_exec;
579 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
582 static int particle_system_remove_exec(bContext *C, wmOperator *op)
584 Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
585 Scene *scene = CTX_data_scene(C);
588 return OPERATOR_CANCELLED;
590 object_remove_particle_system(scene, ob);
591 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
593 return OPERATOR_FINISHED;
596 void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
599 ot->name= "Remove Particle System Slot";
600 ot->idname= "OBJECT_OT_particle_system_remove";
603 ot->exec= particle_system_remove_exec;
606 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
609 /********************** new particle settings operator *********************/
611 static int new_particle_settings_exec(bContext *C, wmOperator *op)
613 Scene *scene = CTX_data_scene(C);
614 Main *bmain= CTX_data_main(C);
615 ParticleSystem *psys;
616 ParticleSettings *part = NULL;
620 ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
624 /* add or copy particle setting */
626 part= psys_copy_settings(psys->part);
628 part= psys_new_settings("ParticleSettings", bmain);
637 psys_check_boid_data(psys);
639 DAG_scene_sort(scene);
640 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
642 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
644 return OPERATOR_FINISHED;
647 void PARTICLE_OT_new(wmOperatorType *ot)
650 ot->name= "New Particle Settings";
651 ot->idname= "PARTICLE_OT_new";
654 ot->exec= new_particle_settings_exec;
657 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
660 /********************** keyed particle target operators *********************/
662 static int new_particle_target_exec(bContext *C, wmOperator *op)
664 Scene *scene = CTX_data_scene(C);
665 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
666 ParticleSystem *psys= ptr.data;
667 Object *ob = ptr.id.data;
672 return OPERATOR_CANCELLED;
674 pt = psys->targets.first;
675 for(; pt; pt=pt->next)
676 pt->flag &= ~PTARGET_CURRENT;
678 pt = MEM_callocN(sizeof(ParticleTarget), "keyed particle target");
680 pt->flag |= PTARGET_CURRENT;
683 BLI_addtail(&psys->targets, pt);
685 DAG_scene_sort(scene);
686 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
688 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
690 return OPERATOR_FINISHED;
693 void PARTICLE_OT_new_target(wmOperatorType *ot)
696 ot->name= "New Particle Target";
697 ot->idname= "PARTICLE_OT_new_target";
700 ot->exec= new_particle_target_exec;
703 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
706 static int remove_particle_target_exec(bContext *C, wmOperator *op)
708 Scene *scene = CTX_data_scene(C);
709 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
710 ParticleSystem *psys= ptr.data;
711 Object *ob = ptr.id.data;
716 return OPERATOR_CANCELLED;
718 pt = psys->targets.first;
719 for(; pt; pt=pt->next) {
720 if(pt->flag & PTARGET_CURRENT) {
721 BLI_remlink(&psys->targets, pt);
727 pt = psys->targets.last;
730 pt->flag |= PTARGET_CURRENT;
732 DAG_scene_sort(scene);
733 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
735 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
737 return OPERATOR_FINISHED;
740 void PARTICLE_OT_remove_target(wmOperatorType *ot)
743 ot->name= "Remove Particle Target";
744 ot->idname= "PARTICLE_OT_remove_target";
747 ot->exec= remove_particle_target_exec;
750 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
753 /************************ move up particle target operator *********************/
755 static int target_move_up_exec(bContext *C, wmOperator *op)
757 Scene *scene= CTX_data_scene(C);
758 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
759 ParticleSystem *psys= ptr.data;
760 Object *ob = ptr.id.data;
764 return OPERATOR_CANCELLED;
766 pt = psys->targets.first;
767 for(; pt; pt=pt->next) {
768 if(pt->flag & PTARGET_CURRENT && pt->prev) {
769 BLI_remlink(&psys->targets, pt);
770 BLI_insertlink(&psys->targets, pt->prev->prev, pt);
772 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
773 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
778 return OPERATOR_FINISHED;
781 void PARTICLE_OT_target_move_up(wmOperatorType *ot)
783 ot->name= "Move Up Target";
784 ot->description= "Move particle target up in the list.";
785 ot->idname= "PARTICLE_OT_target_move_up";
787 ot->exec= target_move_up_exec;
790 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
793 /************************ move down particle target operator *********************/
795 static int target_move_down_exec(bContext *C, wmOperator *op)
797 Scene *scene= CTX_data_scene(C);
798 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
799 ParticleSystem *psys= ptr.data;
800 Object *ob = ptr.id.data;
804 return OPERATOR_CANCELLED;
805 pt = psys->targets.first;
806 for(; pt; pt=pt->next) {
807 if(pt->flag & PTARGET_CURRENT && pt->next) {
808 BLI_remlink(&psys->targets, pt);
809 BLI_insertlink(&psys->targets, pt->next, pt);
811 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
812 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
817 return OPERATOR_FINISHED;
820 void PARTICLE_OT_target_move_down(wmOperatorType *ot)
822 ot->name= "Move Down Target";
823 ot->description= "Move particle target down in the list.";
824 ot->idname= "PARTICLE_OT_target_move_down";
826 ot->exec= target_move_down_exec;
829 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
832 /********************** render layer operators *********************/
834 static int render_layer_add_exec(bContext *C, wmOperator *op)
836 Scene *scene= CTX_data_scene(C);
838 scene_add_render_layer(scene);
839 scene->r.actlay= BLI_countlist(&scene->r.layers) - 1;
841 WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene);
843 return OPERATOR_FINISHED;
846 void SCENE_OT_render_layer_add(wmOperatorType *ot)
849 ot->name= "Add Render Layer";
850 ot->idname= "SCENE_OT_render_layer_add";
853 ot->exec= render_layer_add_exec;
856 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
859 static int render_layer_remove_exec(bContext *C, wmOperator *op)
861 Scene *scene= CTX_data_scene(C);
862 SceneRenderLayer *rl;
863 int act= scene->r.actlay;
865 if(BLI_countlist(&scene->r.layers) <= 1)
866 return OPERATOR_CANCELLED;
868 rl= BLI_findlink(&scene->r.layers, scene->r.actlay);
869 BLI_remlink(&scene->r.layers, rl);
874 if(scene->nodetree) {
876 for(node= scene->nodetree->nodes.first; node; node= node->next) {
877 if(node->type==CMP_NODE_R_LAYERS && node->id==NULL) {
878 if(node->custom1==act)
880 else if(node->custom1>act)
886 WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene);
888 return OPERATOR_FINISHED;
891 void SCENE_OT_render_layer_remove(wmOperatorType *ot)
894 ot->name= "Remove Render Layer";
895 ot->idname= "SCENE_OT_render_layer_remove";
898 ot->exec= render_layer_remove_exec;
901 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;