Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2009 Janne Karhu. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <stdlib.h> 00032 00033 #include "MEM_guardedalloc.h" 00034 00035 #include "DNA_particle_types.h" 00036 #include "DNA_scene_types.h" 00037 00038 #include "BLI_listbase.h" 00039 #include "BLI_utildefines.h" 00040 00041 #include "BKE_boids.h" 00042 #include "BKE_context.h" 00043 #include "BKE_depsgraph.h" 00044 #include "BKE_main.h" 00045 #include "BKE_particle.h" 00046 00047 #include "RNA_access.h" 00048 #include "RNA_enum_types.h" 00049 #include "RNA_define.h" 00050 00051 #include "WM_api.h" 00052 #include "WM_types.h" 00053 00054 #include "physics_intern.h" 00055 00056 /************************ add/del boid rule operators *********************/ 00057 static int rule_add_exec(bContext *C, wmOperator *op) 00058 { 00059 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00060 ParticleSystem *psys= ptr.data; 00061 Object *ob= ptr.id.data; 00062 ParticleSettings *part; 00063 int type= RNA_enum_get(op->ptr, "type"); 00064 00065 BoidRule *rule; 00066 BoidState *state; 00067 00068 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00069 return OPERATOR_CANCELLED; 00070 00071 part = psys->part; 00072 00073 state = boid_get_current_state(part->boids); 00074 00075 00076 for(rule=state->rules.first; rule; rule=rule->next) 00077 rule->flag &= ~BOIDRULE_CURRENT; 00078 00079 rule = boid_new_rule(type); 00080 rule->flag |= BOIDRULE_CURRENT; 00081 00082 BLI_addtail(&state->rules, rule); 00083 00084 DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00085 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00086 00087 return OPERATOR_FINISHED; 00088 } 00089 00090 void BOID_OT_rule_add(wmOperatorType *ot) 00091 { 00092 /* identifiers */ 00093 ot->name= "Add Boid Rule"; 00094 ot->description = "Add a boid rule to the current boid state"; 00095 ot->idname= "BOID_OT_rule_add"; 00096 00097 /* api callbacks */ 00098 ot->invoke= WM_menu_invoke; 00099 ot->exec= rule_add_exec; 00100 00101 /* flags */ 00102 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00103 00104 ot->prop= RNA_def_enum(ot->srna, "type", boidrule_type_items, 0, "Type", ""); 00105 } 00106 static int rule_del_exec(bContext *C, wmOperator *UNUSED(op)) 00107 { 00108 Main *bmain = CTX_data_main(C); 00109 Scene *scene = CTX_data_scene(C); 00110 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00111 ParticleSystem *psys= ptr.data; 00112 Object *ob = ptr.id.data; 00113 BoidRule *rule; 00114 BoidState *state; 00115 00116 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00117 return OPERATOR_CANCELLED; 00118 00119 state = boid_get_current_state(psys->part->boids); 00120 00121 00122 for(rule=state->rules.first; rule; rule=rule->next) { 00123 if(rule->flag & BOIDRULE_CURRENT) { 00124 BLI_remlink(&state->rules, rule); 00125 MEM_freeN(rule); 00126 break; 00127 } 00128 00129 } 00130 rule = state->rules.first; 00131 00132 if(rule) 00133 rule->flag |= BOIDRULE_CURRENT; 00134 00135 DAG_scene_sort(bmain, scene); 00136 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00137 00138 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00139 00140 return OPERATOR_FINISHED; 00141 } 00142 00143 void BOID_OT_rule_del(wmOperatorType *ot) 00144 { 00145 /* identifiers */ 00146 ot->name= "Remove Boid Rule"; 00147 ot->idname= "BOID_OT_rule_del"; 00148 00149 /* api callbacks */ 00150 ot->exec= rule_del_exec; 00151 00152 /* flags */ 00153 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00154 } 00155 00156 /************************ move up/down boid rule operators *********************/ 00157 static int rule_move_up_exec(bContext *C, wmOperator *UNUSED(op)) 00158 { 00159 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00160 ParticleSystem *psys= ptr.data; 00161 Object *ob = ptr.id.data; 00162 BoidRule *rule; 00163 BoidState *state; 00164 00165 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00166 return OPERATOR_CANCELLED; 00167 00168 state = boid_get_current_state(psys->part->boids); 00169 for(rule = state->rules.first; rule; rule=rule->next) { 00170 if(rule->flag & BOIDRULE_CURRENT && rule->prev) { 00171 BLI_remlink(&state->rules, rule); 00172 BLI_insertlink(&state->rules, rule->prev->prev, rule); 00173 00174 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00175 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00176 break; 00177 } 00178 } 00179 00180 return OPERATOR_FINISHED; 00181 } 00182 00183 void BOID_OT_rule_move_up(wmOperatorType *ot) 00184 { 00185 ot->name= "Move Up Boid Rule"; 00186 ot->description= "Move boid rule up in the list"; 00187 ot->idname= "BOID_OT_rule_move_up"; 00188 00189 ot->exec= rule_move_up_exec; 00190 00191 /* flags */ 00192 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00193 } 00194 00195 static int rule_move_down_exec(bContext *C, wmOperator *UNUSED(op)) 00196 { 00197 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00198 ParticleSystem *psys= ptr.data; 00199 Object *ob = ptr.id.data; 00200 BoidRule *rule; 00201 BoidState *state; 00202 00203 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00204 return OPERATOR_CANCELLED; 00205 00206 state = boid_get_current_state(psys->part->boids); 00207 for(rule = state->rules.first; rule; rule=rule->next) { 00208 if(rule->flag & BOIDRULE_CURRENT && rule->next) { 00209 BLI_remlink(&state->rules, rule); 00210 BLI_insertlink(&state->rules, rule->next, rule); 00211 00212 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00213 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00214 break; 00215 } 00216 } 00217 00218 return OPERATOR_FINISHED; 00219 } 00220 00221 void BOID_OT_rule_move_down(wmOperatorType *ot) 00222 { 00223 ot->name= "Move Down Boid Rule"; 00224 ot->description= "Move boid rule down in the list"; 00225 ot->idname= "BOID_OT_rule_move_down"; 00226 00227 ot->exec= rule_move_down_exec; 00228 00229 /* flags */ 00230 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00231 } 00232 00233 00234 /************************ add/del boid state operators *********************/ 00235 static int state_add_exec(bContext *C, wmOperator *UNUSED(op)) 00236 { 00237 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00238 ParticleSystem *psys= ptr.data; 00239 Object *ob= ptr.id.data; 00240 ParticleSettings *part; 00241 BoidState *state; 00242 00243 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00244 return OPERATOR_CANCELLED; 00245 00246 part = psys->part; 00247 00248 for(state=part->boids->states.first; state; state=state->next) 00249 state->flag &= ~BOIDSTATE_CURRENT; 00250 00251 state = boid_new_state(part->boids); 00252 state->flag |= BOIDSTATE_CURRENT; 00253 00254 BLI_addtail(&part->boids->states, state); 00255 00256 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00257 00258 return OPERATOR_FINISHED; 00259 } 00260 00261 void BOID_OT_state_add(wmOperatorType *ot) 00262 { 00263 /* identifiers */ 00264 ot->name= "Add Boid State"; 00265 ot->description = "Add a boid state to the particle system"; 00266 ot->idname= "BOID_OT_state_add"; 00267 00268 /* api callbacks */ 00269 ot->exec= state_add_exec; 00270 00271 /* flags */ 00272 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00273 } 00274 static int state_del_exec(bContext *C, wmOperator *UNUSED(op)) 00275 { 00276 Main *bmain = CTX_data_main(C); 00277 Scene *scene = CTX_data_scene(C); 00278 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00279 ParticleSystem *psys= ptr.data; 00280 Object *ob = ptr.id.data; 00281 ParticleSettings *part; 00282 BoidState *state; 00283 00284 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00285 return OPERATOR_CANCELLED; 00286 00287 part = psys->part; 00288 00289 for(state=part->boids->states.first; state; state=state->next) { 00290 if(state->flag & BOIDSTATE_CURRENT) { 00291 BLI_remlink(&part->boids->states, state); 00292 MEM_freeN(state); 00293 break; 00294 } 00295 00296 } 00297 00298 /* there must be at least one state */ 00299 if(!part->boids->states.first) { 00300 state = boid_new_state(part->boids); 00301 BLI_addtail(&part->boids->states, state); 00302 } 00303 else 00304 state = part->boids->states.first; 00305 00306 state->flag |= BOIDSTATE_CURRENT; 00307 00308 DAG_scene_sort(bmain, scene); 00309 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00310 00311 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00312 00313 return OPERATOR_FINISHED; 00314 } 00315 00316 void BOID_OT_state_del(wmOperatorType *ot) 00317 { 00318 /* identifiers */ 00319 ot->name= "Remove Boid State"; 00320 ot->idname= "BOID_OT_state_del"; 00321 00322 /* api callbacks */ 00323 ot->exec= state_del_exec; 00324 00325 /* flags */ 00326 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00327 } 00328 00329 /************************ move up/down boid state operators *********************/ 00330 static int state_move_up_exec(bContext *C, wmOperator *UNUSED(op)) 00331 { 00332 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00333 ParticleSystem *psys= ptr.data; 00334 Object *ob = ptr.id.data; 00335 BoidSettings *boids; 00336 BoidState *state; 00337 00338 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00339 return OPERATOR_CANCELLED; 00340 00341 boids = psys->part->boids; 00342 00343 for(state = boids->states.first; state; state=state->next) { 00344 if(state->flag & BOIDSTATE_CURRENT && state->prev) { 00345 BLI_remlink(&boids->states, state); 00346 BLI_insertlink(&boids->states, state->prev->prev, state); 00347 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00348 break; 00349 } 00350 } 00351 00352 return OPERATOR_FINISHED; 00353 } 00354 00355 void BOID_OT_state_move_up(wmOperatorType *ot) 00356 { 00357 ot->name= "Move Up Boid State"; 00358 ot->description= "Move boid state up in the list"; 00359 ot->idname= "BOID_OT_state_move_up"; 00360 00361 ot->exec= state_move_up_exec; 00362 00363 /* flags */ 00364 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00365 } 00366 00367 static int state_move_down_exec(bContext *C, wmOperator *UNUSED(op)) 00368 { 00369 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00370 ParticleSystem *psys= ptr.data; 00371 BoidSettings *boids; 00372 BoidState *state; 00373 00374 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00375 return OPERATOR_CANCELLED; 00376 00377 boids = psys->part->boids; 00378 00379 for(state = boids->states.first; state; state=state->next) { 00380 if(state->flag & BOIDSTATE_CURRENT && state->next) { 00381 BLI_remlink(&boids->states, state); 00382 BLI_insertlink(&boids->states, state->next, state); 00383 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00384 break; 00385 } 00386 } 00387 00388 return OPERATOR_FINISHED; 00389 } 00390 00391 void BOID_OT_state_move_down(wmOperatorType *ot) 00392 { 00393 ot->name= "Move Down Boid State"; 00394 ot->description= "Move boid state down in the list"; 00395 ot->idname= "BOID_OT_state_move_down"; 00396 00397 ot->exec= state_move_down_exec; 00398 00399 /* flags */ 00400 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00401 } 00402