2.5: warning fixes
[blender.git] / source / blender / editors / physics / physics_boids.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 Janne Karhu.
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_boid_types.h"
34 #include "DNA_particle_types.h"
35 //#include "DNA_curve_types.h"
36 #include "DNA_object_types.h"
37 //#include "DNA_material_types.h"
38 //#include "DNA_texture_types.h"
39 #include "DNA_scene_types.h"
40 //#include "DNA_world_types.h"
41
42 #include "BKE_boids.h"
43 #include "BKE_context.h"
44 #include "BKE_depsgraph.h"
45 //#include "BKE_font.h"
46 //#include "BKE_library.h"
47 //#include "BKE_main.h"
48 //#include "BKE_material.h"
49 #include "BKE_particle.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 #include "RNA_enum_types.h"
59 #include "RNA_define.h"
60
61 #include "WM_api.h"
62 #include "WM_types.h"
63
64 //#include "ED_curve.h"
65 //#include "ED_mesh.h"
66 //
67 //#include "buttons_intern.h"   // own include
68
69 /************************ add/del boid rule operators *********************/
70 static int boidrule_add_exec(bContext *C, wmOperator *op)
71 {
72         Scene *scene = CTX_data_scene(C);
73         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
74         ParticleSystem *psys= ptr.data;
75         Object *ob= ptr.id.data;
76         ParticleSettings *part;
77         int type= RNA_enum_get(op->ptr, "type");
78
79         BoidRule *rule;
80         BoidState *state;
81
82         if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS)
83                 return OPERATOR_CANCELLED;
84
85         part = psys->part;
86
87         state = boid_get_current_state(part->boids);
88
89
90         for(rule=state->rules.first; rule; rule=rule->next)
91                 rule->flag &= ~BOIDRULE_CURRENT;
92
93         rule = boid_new_rule(type);
94         rule->flag |= BOIDRULE_CURRENT;
95
96         BLI_addtail(&state->rules, rule);
97
98         psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET);
99         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
100         
101         return OPERATOR_FINISHED;
102 }
103
104 void BOID_OT_boidrule_add(wmOperatorType *ot)
105 {
106         /* identifiers */
107         ot->name= "Add Boid Rule";
108         ot->description = "Add a boid rule to the current boid state.";
109         ot->idname= "BOID_OT_boidrule_add";
110         
111         /* api callbacks */
112         ot->invoke= WM_menu_invoke;
113         ot->exec= boidrule_add_exec;
114         
115         /* flags */
116         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
117         
118         RNA_def_enum(ot->srna, "type", boidrule_type_items, 0, "Type", "");
119 }
120 static int boidrule_del_exec(bContext *C, wmOperator *op)
121 {
122         Scene *scene = CTX_data_scene(C);
123         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
124         ParticleSystem *psys= ptr.data;
125         Object *ob = ptr.id.data;
126         BoidRule *rule;
127         BoidState *state;
128
129         if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS)
130                 return OPERATOR_CANCELLED;
131
132         state = boid_get_current_state(psys->part->boids);
133
134         
135         for(rule=state->rules.first; rule; rule=rule->next) {
136                 if(rule->flag & BOIDRULE_CURRENT) {
137                         BLI_remlink(&state->rules, rule);
138                         MEM_freeN(rule);
139                         break;
140                 }
141
142         }
143         rule = state->rules.first;
144
145         if(rule)
146                 rule->flag |= BOIDRULE_CURRENT;
147
148         DAG_scene_sort(scene);
149         psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
150
151         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
152         
153         return OPERATOR_FINISHED;
154 }
155
156 void BOID_OT_boidrule_del(wmOperatorType *ot)
157 {
158         /* identifiers */
159         ot->name= "Remove Boid Rule";
160         ot->idname= "BOID_OT_boidrule_del";
161         
162         /* api callbacks */
163         ot->exec= boidrule_del_exec;
164
165         /* flags */
166         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
167 }
168
169 /************************ move up/down boid rule operators *********************/
170 static int boidrule_move_up_exec(bContext *C, wmOperator *op)
171 {
172         Scene *scene= CTX_data_scene(C);
173         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
174         ParticleSystem *psys= ptr.data;
175         Object *ob = ptr.id.data;
176         BoidRule *rule;
177         BoidState *state;
178
179         if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS)
180                 return OPERATOR_CANCELLED;
181         
182         state = boid_get_current_state(psys->part->boids);
183         for(rule = state->rules.first; rule; rule=rule->next) {
184                 if(rule->flag & BOIDRULE_CURRENT && rule->prev) {
185                         BLI_remlink(&state->rules, rule);
186                         BLI_insertlink(&state->rules, rule->prev->prev, rule);
187
188                         psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
189                         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
190                         break;
191                 }
192         }
193         
194         return OPERATOR_FINISHED;
195 }
196
197 void BOID_OT_boidrule_move_up(wmOperatorType *ot)
198 {
199         ot->name= "Move Up Boid Rule";
200         ot->description= "Move boid rule up in the list.";
201         ot->idname= "BOID_OT_boidrule_move_up";
202
203         ot->exec= boidrule_move_up_exec;
204         
205         /* flags */
206         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
207 }
208
209 static int boidrule_move_down_exec(bContext *C, wmOperator *op)
210 {
211         Scene *scene= CTX_data_scene(C);
212         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
213         ParticleSystem *psys= ptr.data;
214         Object *ob = ptr.id.data;
215         BoidRule *rule;
216         BoidState *state;
217
218         if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS)
219                 return OPERATOR_CANCELLED;
220         
221         state = boid_get_current_state(psys->part->boids);
222         for(rule = state->rules.first; rule; rule=rule->next) {
223                 if(rule->flag & BOIDRULE_CURRENT && rule->next) {
224                         BLI_remlink(&state->rules, rule);
225                         BLI_insertlink(&state->rules, rule->next, rule);
226
227                         psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
228                         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
229                         break;
230                 }
231         }
232         
233         return OPERATOR_FINISHED;
234 }
235
236 void BOID_OT_boidrule_move_down(wmOperatorType *ot)
237 {
238         ot->name= "Move Down Boid Rule";
239         ot->description= "Move boid rule down in the list.";
240         ot->idname= "BOID_OT_boidrule_move_down";
241
242         ot->exec= boidrule_move_down_exec;
243         
244         /* flags */
245         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
246 }
247
248
249 /************************ add/del boid state operators *********************/
250 static int boidstate_add_exec(bContext *C, wmOperator *op)
251 {
252         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
253         ParticleSystem *psys= ptr.data;
254         Object *ob= ptr.id.data;
255         ParticleSettings *part;
256         BoidState *state;
257
258         if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS)
259                 return OPERATOR_CANCELLED;
260
261         part = psys->part;
262
263         for(state=part->boids->states.first; state; state=state->next)
264                 state->flag &= ~BOIDSTATE_CURRENT;
265
266         state = boid_new_state(part->boids);
267         state->flag |= BOIDSTATE_CURRENT;
268
269         BLI_addtail(&part->boids->states, state);
270
271         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
272         
273         return OPERATOR_FINISHED;
274 }
275
276 void BOID_OT_boidstate_add(wmOperatorType *ot)
277 {
278         /* identifiers */
279         ot->name= "Add Boid State";
280         ot->description = "Add a boid state to the particle system.";
281         ot->idname= "BOID_OT_boidstate_add";
282         
283         /* api callbacks */
284         ot->exec= boidstate_add_exec;
285         
286         /* flags */
287         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
288 }
289 static int boidstate_del_exec(bContext *C, wmOperator *op)
290 {
291         Scene *scene = CTX_data_scene(C);
292         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
293         ParticleSystem *psys= ptr.data;
294         Object *ob = ptr.id.data;
295         ParticleSettings *part;
296         BoidState *state;
297
298         if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS)
299                 return OPERATOR_CANCELLED;
300
301         part = psys->part;
302         
303         for(state=part->boids->states.first; state; state=state->next) {
304                 if(state->flag & BOIDSTATE_CURRENT) {
305                         BLI_remlink(&part->boids->states, state);
306                         MEM_freeN(state);
307                         break;
308                 }
309
310         }
311
312         /* there must be at least one state */
313         if(!part->boids->states.first) {
314                 state = boid_new_state(part->boids);
315                 BLI_addtail(&part->boids->states, state);       
316         }
317         else
318                 state = part->boids->states.first;
319
320         state->flag |= BOIDSTATE_CURRENT;
321
322         DAG_scene_sort(scene);
323         psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
324
325         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
326         
327         return OPERATOR_FINISHED;
328 }
329
330 void BOID_OT_boidstate_del(wmOperatorType *ot)
331 {
332         /* identifiers */
333         ot->name= "Remove Boid State";
334         ot->idname= "BOID_OT_boidstate_del";
335         
336         /* api callbacks */
337         ot->exec= boidstate_del_exec;
338
339         /* flags */
340         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
341 }
342
343 /************************ move up/down boid state operators *********************/
344 static int boidstate_move_up_exec(bContext *C, wmOperator *op)
345 {
346         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
347         ParticleSystem *psys= ptr.data;
348         Object *ob = ptr.id.data;
349         BoidSettings *boids;
350         BoidState *state;
351
352         if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS)
353                 return OPERATOR_CANCELLED;
354
355         boids = psys->part->boids;
356         
357         for(state = boids->states.first; state; state=state->next) {
358                 if(state->flag & BOIDSTATE_CURRENT && state->prev) {
359                         BLI_remlink(&boids->states, state);
360                         BLI_insertlink(&boids->states, state->prev->prev, state);
361                         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
362                         break;
363                 }
364         }
365         
366         return OPERATOR_FINISHED;
367 }
368
369 void BOID_OT_boidstate_move_up(wmOperatorType *ot)
370 {
371         ot->name= "Move Up Boid State";
372         ot->description= "Move boid state up in the list.";
373         ot->idname= "BOID_OT_boidstate_move_up";
374
375         ot->exec= boidstate_move_up_exec;
376         
377         /* flags */
378         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
379 }
380
381 static int boidstate_move_down_exec(bContext *C, wmOperator *op)
382 {
383         Scene *scene= CTX_data_scene(C);
384         PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
385         ParticleSystem *psys= ptr.data;
386         BoidSettings *boids;
387         BoidState *state;
388
389         if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS)
390                 return OPERATOR_CANCELLED;
391
392         boids = psys->part->boids;
393         
394         for(state = boids->states.first; state; state=state->next) {
395                 if(state->flag & BOIDSTATE_CURRENT && state->next) {
396                         BLI_remlink(&boids->states, state);
397                         BLI_insertlink(&boids->states, state->next, state);
398                         psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET);
399                         break;
400                 }
401         }
402         
403         return OPERATOR_FINISHED;
404 }
405
406 void BOID_OT_boidstate_move_down(wmOperatorType *ot)
407 {
408         ot->name= "Move Down Boid State";
409         ot->description= "Move boid state down in the list.";
410         ot->idname= "BOID_OT_boidstate_move_down";
411
412         ot->exec= boidstate_move_down_exec;
413         
414         /* flags */
415         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
416 }
417
418 /*******************************************************************************/
419 void ED_operatortypes_boids(void)
420 {
421         WM_operatortype_append(BOID_OT_boidrule_add);
422         WM_operatortype_append(BOID_OT_boidrule_del);
423         WM_operatortype_append(BOID_OT_boidrule_move_up);
424         WM_operatortype_append(BOID_OT_boidrule_move_down);
425
426         WM_operatortype_append(BOID_OT_boidstate_add);
427         WM_operatortype_append(BOID_OT_boidstate_del);
428         WM_operatortype_append(BOID_OT_boidstate_move_up);
429         WM_operatortype_append(BOID_OT_boidstate_move_down);
430 }