diff options
Diffstat (limited to 'source/blender/editors/physics')
-rw-r--r-- | source/blender/editors/physics/SConscript | 7 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_boids.c (renamed from source/blender/editors/physics/physics_boids.c) | 116 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_edit.c (renamed from source/blender/editors/physics/editparticle.c) | 160 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_object.c | 651 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_fluid.c (renamed from source/blender/editors/physics/ed_fluidsim.c) | 7 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_intern.h | 69 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_ops.c | 176 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_pointcache.c (renamed from source/blender/editors/physics/ed_pointcache.c) | 24 |
8 files changed, 1019 insertions, 191 deletions
diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript index 5718ae0c217..60b992d2e07 100644 --- a/source/blender/editors/physics/SConscript +++ b/source/blender/editors/physics/SConscript @@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' #/intern/guardedalloc ../../gpu' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_physics', sources, Split(incs), [], libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/physics/physics_boids.c b/source/blender/editors/physics/particle_boids.c index 148359068ad..b7a97d1131a 100644 --- a/source/blender/editors/physics/physics_boids.c +++ b/source/blender/editors/physics/particle_boids.c @@ -25,35 +25,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -//#include <stdlib.h> -//#include <string.h> -// +#include <stdlib.h> + #include "MEM_guardedalloc.h" #include "DNA_boid_types.h" #include "DNA_particle_types.h" -//#include "DNA_curve_types.h" #include "DNA_object_types.h" -//#include "DNA_material_types.h" -//#include "DNA_texture_types.h" #include "DNA_scene_types.h" -//#include "DNA_world_types.h" #include "BKE_boids.h" #include "BKE_context.h" #include "BKE_depsgraph.h" -//#include "BKE_font.h" -//#include "BKE_library.h" -//#include "BKE_main.h" -//#include "BKE_material.h" #include "BKE_particle.h" -//#include "BKE_texture.h" -//#include "BKE_utildefines.h" -//#include "BKE_world.h" -//#include "BLI_editVert.h" #include "BLI_listbase.h" -// #include "RNA_access.h" #include "RNA_enum_types.h" #include "RNA_define.h" @@ -61,15 +47,11 @@ #include "WM_api.h" #include "WM_types.h" -//#include "ED_curve.h" -//#include "ED_mesh.h" -// -//#include "buttons_intern.h" // own include +#include "physics_intern.h" /************************ add/del boid rule operators *********************/ -static int boidrule_add_exec(bContext *C, wmOperator *op) +static int rule_add_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob= ptr.id.data; @@ -95,29 +77,29 @@ static int boidrule_add_exec(bContext *C, wmOperator *op) BLI_addtail(&state->rules, rule); - psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET); + DAG_id_flush_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; } -void BOID_OT_boidrule_add(wmOperatorType *ot) +void BOID_OT_rule_add(wmOperatorType *ot) { /* identifiers */ ot->name= "Add Boid Rule"; ot->description = "Add a boid rule to the current boid state."; - ot->idname= "BOID_OT_boidrule_add"; + ot->idname= "BOID_OT_rule_add"; /* api callbacks */ ot->invoke= WM_menu_invoke; - ot->exec= boidrule_add_exec; + ot->exec= rule_add_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; RNA_def_enum(ot->srna, "type", boidrule_type_items, 0, "Type", ""); } -static int boidrule_del_exec(bContext *C, wmOperator *op) +static int rule_del_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); @@ -146,30 +128,29 @@ static int boidrule_del_exec(bContext *C, wmOperator *op) rule->flag |= BOIDRULE_CURRENT; DAG_scene_sort(scene); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; } -void BOID_OT_boidrule_del(wmOperatorType *ot) +void BOID_OT_rule_del(wmOperatorType *ot) { /* identifiers */ ot->name= "Remove Boid Rule"; - ot->idname= "BOID_OT_boidrule_del"; + ot->idname= "BOID_OT_rule_del"; /* api callbacks */ - ot->exec= boidrule_del_exec; + ot->exec= rule_del_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } /************************ move up/down boid rule operators *********************/ -static int boidrule_move_up_exec(bContext *C, wmOperator *op) +static int rule_move_up_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob = ptr.id.data; @@ -185,7 +166,7 @@ static int boidrule_move_up_exec(bContext *C, wmOperator *op) BLI_remlink(&state->rules, rule); BLI_insertlink(&state->rules, rule->prev->prev, rule); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); break; } @@ -194,21 +175,20 @@ static int boidrule_move_up_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void BOID_OT_boidrule_move_up(wmOperatorType *ot) +void BOID_OT_rule_move_up(wmOperatorType *ot) { ot->name= "Move Up Boid Rule"; ot->description= "Move boid rule up in the list."; - ot->idname= "BOID_OT_boidrule_move_up"; + ot->idname= "BOID_OT_rule_move_up"; - ot->exec= boidrule_move_up_exec; + ot->exec= rule_move_up_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int boidrule_move_down_exec(bContext *C, wmOperator *op) +static int rule_move_down_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob = ptr.id.data; @@ -224,7 +204,7 @@ static int boidrule_move_down_exec(bContext *C, wmOperator *op) BLI_remlink(&state->rules, rule); BLI_insertlink(&state->rules, rule->next, rule); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); break; } @@ -233,13 +213,13 @@ static int boidrule_move_down_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void BOID_OT_boidrule_move_down(wmOperatorType *ot) +void BOID_OT_rule_move_down(wmOperatorType *ot) { ot->name= "Move Down Boid Rule"; ot->description= "Move boid rule down in the list."; - ot->idname= "BOID_OT_boidrule_move_down"; + ot->idname= "BOID_OT_rule_move_down"; - ot->exec= boidrule_move_down_exec; + ot->exec= rule_move_down_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -247,7 +227,7 @@ void BOID_OT_boidrule_move_down(wmOperatorType *ot) /************************ add/del boid state operators *********************/ -static int boidstate_add_exec(bContext *C, wmOperator *op) +static int state_add_exec(bContext *C, wmOperator *op) { PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; @@ -273,20 +253,20 @@ static int boidstate_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void BOID_OT_boidstate_add(wmOperatorType *ot) +void BOID_OT_state_add(wmOperatorType *ot) { /* identifiers */ ot->name= "Add Boid State"; ot->description = "Add a boid state to the particle system."; - ot->idname= "BOID_OT_boidstate_add"; + ot->idname= "BOID_OT_state_add"; /* api callbacks */ - ot->exec= boidstate_add_exec; + ot->exec= state_add_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int boidstate_del_exec(bContext *C, wmOperator *op) +static int state_del_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); @@ -320,28 +300,28 @@ static int boidstate_del_exec(bContext *C, wmOperator *op) state->flag |= BOIDSTATE_CURRENT; DAG_scene_sort(scene); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; } -void BOID_OT_boidstate_del(wmOperatorType *ot) +void BOID_OT_state_del(wmOperatorType *ot) { /* identifiers */ ot->name= "Remove Boid State"; - ot->idname= "BOID_OT_boidstate_del"; + ot->idname= "BOID_OT_state_del"; /* api callbacks */ - ot->exec= boidstate_del_exec; + ot->exec= state_del_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } /************************ move up/down boid state operators *********************/ -static int boidstate_move_up_exec(bContext *C, wmOperator *op) +static int state_move_up_exec(bContext *C, wmOperator *op) { PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; @@ -366,21 +346,20 @@ static int boidstate_move_up_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void BOID_OT_boidstate_move_up(wmOperatorType *ot) +void BOID_OT_state_move_up(wmOperatorType *ot) { ot->name= "Move Up Boid State"; ot->description= "Move boid state up in the list."; - ot->idname= "BOID_OT_boidstate_move_up"; + ot->idname= "BOID_OT_state_move_up"; - ot->exec= boidstate_move_up_exec; + ot->exec= state_move_up_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int boidstate_move_down_exec(bContext *C, wmOperator *op) +static int state_move_down_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; BoidSettings *boids; @@ -395,7 +374,7 @@ static int boidstate_move_down_exec(bContext *C, wmOperator *op) if(state->flag & BOIDSTATE_CURRENT && state->next) { BLI_remlink(&boids->states, state); BLI_insertlink(&boids->states, state->next, state); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } @@ -403,28 +382,15 @@ static int boidstate_move_down_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void BOID_OT_boidstate_move_down(wmOperatorType *ot) +void BOID_OT_state_move_down(wmOperatorType *ot) { ot->name= "Move Down Boid State"; ot->description= "Move boid state down in the list."; - ot->idname= "BOID_OT_boidstate_move_down"; + ot->idname= "BOID_OT_state_move_down"; - ot->exec= boidstate_move_down_exec; + ot->exec= state_move_down_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/*******************************************************************************/ -void ED_operatortypes_boids(void) -{ - WM_operatortype_append(BOID_OT_boidrule_add); - WM_operatortype_append(BOID_OT_boidrule_del); - WM_operatortype_append(BOID_OT_boidrule_move_up); - WM_operatortype_append(BOID_OT_boidrule_move_down); - - WM_operatortype_append(BOID_OT_boidstate_add); - WM_operatortype_append(BOID_OT_boidstate_del); - WM_operatortype_append(BOID_OT_boidstate_move_up); - WM_operatortype_append(BOID_OT_boidstate_move_down); -} diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/particle_edit.c index 212d2047872..a1570810e94 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/particle_edit.c @@ -106,35 +106,32 @@ static void PTCacheUndo_clear(PTCacheEdit *edit); /**************************** utilities *******************************/ -static int PE_poll(bContext *C) +int PE_poll(bContext *C) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit; - if(!scene || !ob) + if(!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) return 0; - edit= PE_get_current(scene, ob); - - return (edit && (ob->mode & OB_MODE_PARTICLE_EDIT)); + return (PE_get_current(scene, ob) != NULL); } -static int PE_hair_poll(bContext *C) +int PE_hair_poll(bContext *C) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); PTCacheEdit *edit; - if(!scene || !ob) + if(!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) return 0; edit= PE_get_current(scene, ob); - return (edit && edit->psys && (ob->mode & OB_MODE_PARTICLE_EDIT)); + return (edit && edit->psys); } -static int PE_poll_3dview(bContext *C) +int PE_poll_3dview(bContext *C) { return PE_poll(C) && CTX_wm_area(C)->spacetype == SPACE_VIEW3D && CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW; @@ -197,7 +194,7 @@ ParticleEditSettings *PE_settings(Scene *scene) } /* always gets atleast the first particlesystem even if PSYS_CURRENT flag is not set */ -PTCacheEdit *PE_get_current(Scene *scene, Object *ob) +static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) { ParticleEditSettings *pset= PE_settings(scene); PTCacheEdit *edit = NULL; @@ -235,18 +232,18 @@ PTCacheEdit *PE_get_current(Scene *scene, Object *ob) if(psys->flag & PSYS_CURRENT) { if(psys->part && psys->part->type == PART_HAIR) { if(psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) { - if(!psys->pointcache->edit) + if(create && !psys->pointcache->edit) PE_create_particle_edit(scene, ob, pid->cache, NULL); edit = pid->cache->edit; } else { - if(!psys->edit && psys->flag & PSYS_HAIR_DONE) + if(create && !psys->edit && psys->flag & PSYS_HAIR_DONE) PE_create_particle_edit(scene, ob, NULL, psys); edit = psys->edit; } } else { - if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + if(create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) PE_create_particle_edit(scene, ob, pid->cache, psys); edit = pid->cache->edit; } @@ -255,13 +252,13 @@ PTCacheEdit *PE_get_current(Scene *scene, Object *ob) } } else if(pset->edittype == PE_TYPE_SOFTBODY && pid->type == PTCACHE_TYPE_SOFTBODY) { - if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + if(create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) PE_create_particle_edit(scene, ob, pid->cache, NULL); edit = pid->cache->edit; break; } else if(pset->edittype == PE_TYPE_CLOTH && pid->type == PTCACHE_TYPE_CLOTH) { - if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + if(create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) PE_create_particle_edit(scene, ob, pid->cache, NULL); edit = pid->cache->edit; break; @@ -276,6 +273,22 @@ PTCacheEdit *PE_get_current(Scene *scene, Object *ob) return edit; } +PTCacheEdit *PE_get_current(Scene *scene, Object *ob) +{ + return pe_get_current(scene, ob, 0); +} + +PTCacheEdit *PE_create_current(Scene *scene, Object *ob) +{ + return pe_get_current(scene, ob, 1); +} + +void PE_current_changed(Scene *scene, Object *ob) +{ + if(ob->mode == OB_MODE_PARTICLE_EDIT) + PE_create_current(scene, ob); +} + void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra) { ParticleEditSettings *pset=PE_settings(scene); @@ -675,6 +688,9 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) psmd= psys_get_modifier(ob, psys); totpart= psys->totpart; + if(!psmd->dm) + return; + tree= BLI_kdtree_new(totpart); /* insert particles into kd tree */ @@ -803,6 +819,9 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) edit= psys->edit; psmd= psys_get_modifier(ob, psys); + if(!edit->mirror_cache || !psmd->dm) + return; + /* we delay settings the PARS_EDIT_RECALC for mirrored particles * to avoid doing mirror twice */ LOOP_POINTS { @@ -841,6 +860,9 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) psys = edit->psys; psmd = psys_get_modifier(ob,psys); + if(!psmd->dm) + return; + LOOP_EDITED_POINTS { psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles + p, hairmat); @@ -994,12 +1016,15 @@ static void recalc_emitter_field(Object *ob, ParticleSystem *psys) float *vec, *nor; int i, totface, totvert; + if(!dm) + return; + if(edit->emitter_cosnos) MEM_freeN(edit->emitter_cosnos); BLI_kdtree_free(edit->emitter_field); - totface=dm->getNumFaces(dm); + totface=dm->getNumTessFaces(dm); totvert=dm->getNumVerts(dm); edit->emitter_cosnos=MEM_callocN(totface*6*sizeof(float),"emitter cosnos"); @@ -1079,7 +1104,7 @@ static void update_world_cos(Object *ob, PTCacheEdit *edit) POINT_P; KEY_K; float hairmat[4][4]; - if(psys==0 || psys->edit==0) + if(psys==0 || psys->edit==0 || psmd->dm==NULL) return; LOOP_POINTS { @@ -1184,7 +1209,8 @@ void PE_update_object(Scene *scene, Object *ob, int useflag) point->flag &= ~PEP_EDIT_RECALC; } - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + if(edit->psys) + edit->psys->flag &= ~PSYS_HAIR_UPDATED; } /************************************************/ @@ -1761,6 +1787,7 @@ static void rekey_particle(PEData *data, int pa_index) { PTCacheEdit *edit= data->edit; ParticleSystem *psys= edit->psys; + ParticleSimulationData sim = {data->scene, data->ob, edit->psys, NULL}; ParticleData *pa= psys->particles + pa_index; PTCacheEditPoint *point = edit->points + pa_index; ParticleKey state; @@ -1785,7 +1812,7 @@ static void rekey_particle(PEData *data, int pa_index) /* interpolate new keys from old ones */ for(k=1,key++; k<data->totrekey-1; k++,key++) { state.time= (float)k / (float)(data->totrekey-1); - psys_get_particle_on_path(data->scene, data->ob, psys, pa_index, &state, 0); + psys_get_particle_on_path(&sim, pa_index, &state, 0); VECCOPY(key->co, state.co); key->time= sta + k * dval; } @@ -1853,6 +1880,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float { PTCacheEdit *edit= PE_get_current(scene, ob); ParticleSystem *psys; + ParticleSimulationData sim = {scene, ob, edit ? edit->psys : NULL, NULL}; ParticleData *pa; ParticleKey state; HairKey *new_keys, *key; @@ -1872,7 +1900,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float /* interpolate new keys from old ones (roots stay the same) */ for(k=1, key++; k < pa->totkey; k++, key++) { state.time= path_time * (float)k / (float)(pa->totkey-1); - psys_get_particle_on_path(scene, ob, psys, pa_index, &state, 0); + psys_get_particle_on_path(&sim, pa_index, &state, 0); VECCOPY(key->co, state.co); } @@ -2044,6 +2072,7 @@ static void subdivide_particle(PEData *data, int pa_index) { PTCacheEdit *edit= data->edit; ParticleSystem *psys= edit->psys; + ParticleSimulationData sim = {data->scene, data->ob, edit->psys, NULL}; ParticleData *pa= psys->particles + pa_index; PTCacheEditPoint *point = edit->points + pa_index; ParticleKey state; @@ -2083,7 +2112,7 @@ static void subdivide_particle(PEData *data, int pa_index) if(ekey->flag & PEK_SELECT && (ekey+1)->flag & PEK_SELECT) { nkey->time= (key->time + (key+1)->time)*0.5f; state.time= (endtime != 0.0f)? nkey->time/endtime: 0.0f; - psys_get_particle_on_path(data->scene, data->ob, psys, pa_index, &state, 0); + psys_get_particle_on_path(&sim, pa_index, &state, 0); VECCOPY(nkey->co, state.co); nekey->co= nkey->co; @@ -2394,7 +2423,6 @@ static int delete_exec(bContext *C, wmOperator *op) } PE_update_object(data.scene, data.ob, 0); - DAG_id_flush_update(&data.ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, data.ob); @@ -2438,6 +2466,8 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) return; psmd= psys_get_modifier(ob, psys); + if(!psmd->dm) + return; mirrorfaces= mesh_get_x_mirror_faces(ob, NULL); @@ -2875,12 +2905,13 @@ static void brush_add(PEData *data, short number) ParticleSystem *psys= edit->psys; ParticleData *add_pars= MEM_callocN(number*sizeof(ParticleData),"ParticleData add"); ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys); + ParticleSimulationData sim = {scene, ob, psys, psmd}; ParticleEditSettings *pset= PE_settings(scene); int i, k, n= 0, totpart= psys->totpart; - short mco[2]; + float mco[2]; short dmx= 0, dmy= 0; float co1[3], co2[3], min_d, imat[4][4]; - float framestep, timestep= psys_get_timestep(psys->part); + float framestep, timestep= psys_get_timestep(&sim); short size= pset->brush[PE_BRUSH_ADD].size; short size2= size*size; DerivedMesh *dm=0; @@ -2972,11 +3003,14 @@ static void brush_add(PEData *data, short number) for(k=0, hkey=pa->hair; k<pa->totkey; k++, hkey++, key++) { key->co= hkey->co; key->time= &hkey->time; + + if(!(psys->flag & PSYS_GLOBAL_HAIR)) + key->flag |= PEK_USE_WCO; } pa->size= 1.0f; - initialize_particle(pa,i,ob,psys,psmd); - reset_particle(scene, pa,psys,psmd,ob,0.0,1.0,0,0,0); + initialize_particle(&sim, pa,i); + reset_particle(&sim, pa, 0.0, 1.0); point->flag |= PEP_EDIT_RECALC; if(pset->flag & PE_X_MIRROR) point->flag |= PEP_TAG; /* signal for duplicate */ @@ -3013,18 +3047,18 @@ static void brush_add(PEData *data, short number) hkey->time= pa->time + k * framestep; key[0].time= hkey->time/ 100.0f; - psys_get_particle_on_path(scene, ob, psys, ptn[0].index, key, 0); + psys_get_particle_on_path(&sim, ptn[0].index, key, 0); VecMulf(key[0].co, weight[0]); if(maxw>1) { key[1].time= key[0].time; - psys_get_particle_on_path(scene, ob, psys, ptn[1].index, key + 1, 0); + psys_get_particle_on_path(&sim, ptn[1].index, key + 1, 0); VecMulf(key[1].co, weight[1]); VECADD(key[0].co, key[0].co, key[1].co); if(maxw>2) { key[2].time= key[0].time; - psys_get_particle_on_path(scene, ob, psys, ptn[2].index, key + 2, 0); + psys_get_particle_on_path(&sim, ptn[2].index, key + 2, 0); VecMulf(key[2].co, weight[2]); VECADD(key[0].co, key[0].co, key[2].co); } @@ -3345,7 +3379,7 @@ static int brush_edit_invoke(bContext *C, wmOperator *op, wmEvent *event) brush_edit_apply_event(C, op, event); - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -3716,13 +3750,15 @@ int PE_minmax(Scene *scene, float *min, float *max) /* initialize needed data for bake edit */ static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys) { - PTCacheEdit *edit= psys ? psys->edit : cache->edit; + PTCacheEdit *edit= (psys)? psys->edit : cache->edit; + ParticleSystemModifierData *psmd= (psys)? psys_get_modifier(ob, psys): NULL; POINT_P; KEY_K; ParticleData *pa = NULL; HairKey *hkey; int totpoint; - if(!psys && !cache) + /* no psmd->dm happens in case particle system modifier is not enabled */ + if(!(psys && psmd && psmd->dm) && !cache) return; if(cache && cache->flag & PTCACHE_DISK_CACHE) @@ -3832,10 +3868,12 @@ static int particle_edit_toggle_poll(bContext *C) static int particle_edit_toggle_exec(bContext *C, wmOperator *op) { + Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); if(!(ob->mode & OB_MODE_PARTICLE_EDIT)) { ob->mode |= OB_MODE_PARTICLE_EDIT; + PE_create_current(scene, ob); toggle_particle_cursor(C, 1); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL); } @@ -3911,7 +3949,6 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) { Scene *scene= CTX_data_scene(C); ParticleEditSettings *pset=PE_settings(scene); - PTCacheEdit *edit = PE_get_current(scene, CTX_data_active_object(C)); uiPopupMenu *pup; uiLayout *layout; @@ -3942,58 +3979,3 @@ void PARTICLE_OT_specials_menu(wmOperatorType *ot) ot->poll= PE_hair_poll; } -/**************************** registration **********************************/ - -void ED_operatortypes_particle(void) -{ - WM_operatortype_append(PARTICLE_OT_select_all_toggle); - WM_operatortype_append(PARTICLE_OT_select_first); - WM_operatortype_append(PARTICLE_OT_select_last); - WM_operatortype_append(PARTICLE_OT_select_linked); - WM_operatortype_append(PARTICLE_OT_select_less); - WM_operatortype_append(PARTICLE_OT_select_more); - - WM_operatortype_append(PARTICLE_OT_hide); - WM_operatortype_append(PARTICLE_OT_reveal); - - WM_operatortype_append(PARTICLE_OT_rekey); - WM_operatortype_append(PARTICLE_OT_subdivide); - WM_operatortype_append(PARTICLE_OT_remove_doubles); - WM_operatortype_append(PARTICLE_OT_delete); - WM_operatortype_append(PARTICLE_OT_mirror); - - WM_operatortype_append(PARTICLE_OT_brush_set); - WM_operatortype_append(PARTICLE_OT_brush_edit); - WM_operatortype_append(PARTICLE_OT_brush_radial_control); - - WM_operatortype_append(PARTICLE_OT_specials_menu); - - WM_operatortype_append(PARTICLE_OT_particle_edit_toggle); - WM_operatortype_append(PARTICLE_OT_edited_clear); -} - -void ED_keymap_particle(wmWindowManager *wm) -{ - ListBase *keymap= WM_keymap_listbase(wm, "Particle", 0, 0); - - WM_keymap_add_item(keymap, "PARTICLE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PARTICLE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "PARTICLE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "deselect", 1); - - WM_keymap_add_item(keymap, "PARTICLE_OT_delete", XKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PARTICLE_OT_delete", DELKEY, KM_PRESS, 0, 0); - - WM_keymap_add_item(keymap, "PARTICLE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, 0, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); - - WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", ACTIONMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); - - WM_keymap_add_item(keymap, "PARTICLE_OT_specials_menu", WKEY, KM_PRESS, 0, 0); -} - diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c new file mode 100644 index 00000000000..fd81e828bea --- /dev/null +++ b/source/blender/editors/physics/particle_object.c @@ -0,0 +1,651 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_windowmanager_types.h" + +#include "BLI_arithb.h" +#include "BLI_listbase.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_main.h" +#include "BKE_particle.h" +#include "BKE_pointcache.h" +#include "BKE_utildefines.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_particle.h" + +#include "physics_intern.h" + +/********************** particle system slot operators *********************/ + +static int particle_system_add_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Scene *scene = CTX_data_scene(C); + + if(!scene || !ob) + return OPERATOR_CANCELLED; + + object_add_particle_system(scene, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_particle_system_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Particle System Slot"; + ot->idname= "OBJECT_OT_particle_system_add"; + ot->description="Add a particle system."; + + /* api callbacks */ + ot->exec= particle_system_add_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int particle_system_remove_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Scene *scene = CTX_data_scene(C); + + if(!scene || !ob) + return OPERATOR_CANCELLED; + + object_remove_particle_system(scene, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_particle_system_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Particle System Slot"; + ot->idname= "OBJECT_OT_particle_system_remove"; + ot->description="Remove the selected particle system."; + + /* api callbacks */ + ot->exec= particle_system_remove_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** new particle settings operator *********************/ + +static int psys_poll(bContext *C) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + return (ptr.data != NULL); +} + +static int new_particle_settings_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Main *bmain= CTX_data_main(C); + ParticleSystem *psys; + ParticleSettings *part = NULL; + Object *ob; + PointerRNA ptr; + + ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + + psys = ptr.data; + + /* add or copy particle setting */ + if(psys->part) + part= psys_copy_settings(psys->part); + else + part= psys_new_settings("ParticleSettings", bmain); + + ob= ptr.id.data; + + if(psys->part) + psys->part->id.us--; + + psys->part = part; + + psys_check_boid_data(psys); + + DAG_scene_sort(scene); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "New Particle Settings"; + ot->idname= "PARTICLE_OT_new"; + ot->description="Add new particle settings."; + + /* api callbacks */ + ot->exec= new_particle_settings_exec; + ot->poll= psys_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** keyed particle target operators *********************/ + +static int new_particle_target_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + Object *ob = ptr.id.data; + + ParticleTarget *pt; + + if(!psys) + return OPERATOR_CANCELLED; + + pt = psys->targets.first; + for(; pt; pt=pt->next) + pt->flag &= ~PTARGET_CURRENT; + + pt = MEM_callocN(sizeof(ParticleTarget), "keyed particle target"); + + pt->flag |= PTARGET_CURRENT; + pt->psys = 1; + + BLI_addtail(&psys->targets, pt); + + DAG_scene_sort(scene); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_new_target(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "New Particle Target"; + ot->idname= "PARTICLE_OT_new_target"; + ot->description="Add a new particle target."; + + /* api callbacks */ + ot->exec= new_particle_target_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int remove_particle_target_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + Object *ob = ptr.id.data; + + ParticleTarget *pt; + + if(!psys) + return OPERATOR_CANCELLED; + + pt = psys->targets.first; + for(; pt; pt=pt->next) { + if(pt->flag & PTARGET_CURRENT) { + BLI_remlink(&psys->targets, pt); + MEM_freeN(pt); + break; + } + + } + pt = psys->targets.last; + + if(pt) + pt->flag |= PTARGET_CURRENT; + + DAG_scene_sort(scene); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_remove_target(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Particle Target"; + ot->idname= "PARTICLE_OT_remove_target"; + ot->description="Remove the selected particle target."; + + /* api callbacks */ + ot->exec= remove_particle_target_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/************************ move up particle target operator *********************/ + +static int target_move_up_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + Object *ob = ptr.id.data; + ParticleTarget *pt; + + if(!psys) + return OPERATOR_CANCELLED; + + pt = psys->targets.first; + for(; pt; pt=pt->next) { + if(pt->flag & PTARGET_CURRENT && pt->prev) { + BLI_remlink(&psys->targets, pt); + BLI_insertlink(&psys->targets, pt->prev->prev, pt); + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + break; + } + } + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_target_move_up(wmOperatorType *ot) +{ + ot->name= "Move Up Target"; + ot->idname= "PARTICLE_OT_target_move_up"; + ot->description= "Move particle target up in the list."; + + ot->exec= target_move_up_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/************************ move down particle target operator *********************/ + +static int target_move_down_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + Object *ob = ptr.id.data; + ParticleTarget *pt; + + if(!psys) + return OPERATOR_CANCELLED; + pt = psys->targets.first; + for(; pt; pt=pt->next) { + if(pt->flag & PTARGET_CURRENT && pt->next) { + BLI_remlink(&psys->targets, pt); + BLI_insertlink(&psys->targets, pt->next, pt); + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + break; + } + } + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_target_move_down(wmOperatorType *ot) +{ + ot->name= "Move Down Target"; + ot->idname= "PARTICLE_OT_target_move_down"; + ot->description= "Move particle target down in the list."; + + ot->exec= target_move_down_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/************************ move up particle dupliweight operator *********************/ + +static int dupliob_move_up_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + ParticleSettings *part; + ParticleDupliWeight *dw; + + if(!psys) + return OPERATOR_CANCELLED; + + part = psys->part; + for(dw=part->dupliweights.first; dw; dw=dw->next) { + if(dw->flag & PART_DUPLIW_CURRENT && dw->prev) { + BLI_remlink(&part->dupliweights, dw); + BLI_insertlink(&part->dupliweights, dw->prev->prev, dw); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL); + break; + } + } + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot) +{ + ot->name= "Move Up Dupli Object"; + ot->idname= "PARTICLE_OT_dupliob_move_up"; + ot->description= "Move dupli object up in the list."; + + ot->exec= dupliob_move_up_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/************************ move down particle dupliweight operator *********************/ + +static int dupliob_move_down_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + ParticleSettings *part; + ParticleDupliWeight *dw; + + if(!psys) + return OPERATOR_CANCELLED; + + part = psys->part; + for(dw=part->dupliweights.first; dw; dw=dw->next) { + if(dw->flag & PART_DUPLIW_CURRENT && dw->next) { + BLI_remlink(&part->dupliweights, dw); + BLI_insertlink(&part->dupliweights, dw->next, dw); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL); + break; + } + } + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot) +{ + ot->name= "Move Down Dupli Object"; + ot->idname= "PARTICLE_OT_dupliob_move_down"; + ot->description= "Move dupli object down in the list."; + + ot->exec= dupliob_move_down_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/************************ connect/disconnect hair operators *********************/ + +static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) +{ + ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys); + ParticleData *pa; + PTCacheEdit *edit; + PTCacheEditPoint *point; + PTCacheEditKey *ekey = NULL; + HairKey *key; + int i, k; + float hairmat[4][4]; + + if(!ob || !psys || psys->flag & PSYS_GLOBAL_HAIR) + return; + + if(!psys->part || psys->part->type != PART_HAIR) + return; + + edit = psys->edit; + point= edit ? edit->points : NULL; + + for(i=0, pa=psys->particles; i<psys->totpart; i++,pa++) { + if(point) { + ekey = point->keys; + point++; + } + + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + + for(k=0,key=pa->hair; k<pa->totkey; k++,key++) { + Mat4MulVecfl(hairmat,key->co); + + if(ekey) { + ekey->flag &= ~PEK_USE_WCO; + ekey++; + } + } + } + + psys_free_path_cache(psys, psys->edit); + + psys->flag |= PSYS_GLOBAL_HAIR; + + PE_update_object(scene, ob, 0); +} + +static int disconnect_hair_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= NULL; + int all = RNA_boolean_get(op->ptr, "all"); + + if(!ob) + return OPERATOR_CANCELLED; + + if(all) { + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + disconnect_hair(scene, ob, psys); + } + } + else { + psys = ptr.data; + disconnect_hair(scene, ob, psys); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) +{ + ot->name= "Disconnect Hair"; + ot->description= "Disconnect hair from the emitter mesh."; + ot->idname= "PARTICLE_OT_disconnect_hair"; + + ot->exec= disconnect_hair_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh"); +} + +static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) +{ + ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys); + ParticleData *pa; + PTCacheEdit *edit; + PTCacheEditPoint *point; + PTCacheEditKey *ekey; + HairKey *key; + BVHTreeFromMesh bvhtree; + BVHTreeNearest nearest; + MFace *mface; + DerivedMesh *dm = NULL; + int numverts; + int i, k; + float hairmat[4][4], imat[4][4]; + float v[4][3], vec[3]; + + if(!psys || !psys->part || psys->part->type != PART_HAIR) + return; + + edit= psys->edit; + point= edit ? edit->points : NULL; + + if(psmd->dm->deformedOnly) + dm= psmd->dm; + else + dm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + + numverts = dm->getNumVerts (dm); + + memset( &bvhtree, 0, sizeof(bvhtree) ); + + /* convert to global coordinates */ + for (i=0; i<numverts; i++) + Mat4MulVecfl (ob->obmat, CDDM_get_vert(dm, i)->co); + + bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6); + + for(i=0, pa= psys->particles; i<psys->totpart; i++,pa++) { + key = pa->hair; + + nearest.index = -1; + nearest.dist = FLT_MAX; + + BLI_bvhtree_find_nearest(bvhtree.tree, key->co, &nearest, bvhtree.nearest_callback, &bvhtree); + + if(nearest.index == -1) { + printf("No nearest point found for hair root!"); + continue; + } + + mface = CDDM_get_tessface(dm,nearest.index); + + VecCopyf(v[0], CDDM_get_vert(dm,mface->v1)->co); + VecCopyf(v[1], CDDM_get_vert(dm,mface->v2)->co); + VecCopyf(v[2], CDDM_get_vert(dm,mface->v3)->co); + if(mface->v4) { + VecCopyf(v[3], CDDM_get_vert(dm,mface->v4)->co); + MeanValueWeights(v, 4, nearest.co, pa->fuv); + } + else + MeanValueWeights(v, 3, nearest.co, pa->fuv); + + pa->num = nearest.index; + pa->num_dmcache = psys_particle_dm_face_lookup(ob,psmd->dm,pa->num,pa->fuv,NULL); + + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + Mat4Invert(imat,hairmat); + + VECSUB(vec, nearest.co, key->co); + + if(point) { + ekey = point->keys; + point++; + } + + for(k=0,key=pa->hair; k<pa->totkey; k++,key++) { + VECADD(key->co, key->co, vec); + Mat4MulVecfl(imat,key->co); + + if(ekey) { + ekey->flag |= PEK_USE_WCO; + ekey++; + } + } + } + + free_bvhtree_from_mesh(&bvhtree); + if(!psmd->dm->deformedOnly) + dm->release(dm); + + psys_free_path_cache(psys, psys->edit); + + psys->flag &= ~PSYS_GLOBAL_HAIR; + + PE_update_object(scene, ob, 0); +} + +static int connect_hair_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= NULL; + int all = RNA_boolean_get(op->ptr, "all"); + + if(!ob) + return OPERATOR_CANCELLED; + + if(all) { + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + connect_hair(scene, ob, psys); + } + } + else { + psys = ptr.data; + connect_hair(scene, ob, psys); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_connect_hair(wmOperatorType *ot) +{ + ot->name= "Connect Hair"; + ot->description= "Connect hair to the emitter mesh."; + ot->idname= "PARTICLE_OT_connect_hair"; + + ot->exec= connect_hair_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh"); +} + diff --git a/source/blender/editors/physics/ed_fluidsim.c b/source/blender/editors/physics/physics_fluid.c index 093fa3f0a49..126c21a554b 100644 --- a/source/blender/editors/physics/ed_fluidsim.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -93,6 +93,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "physics_intern.h" // own include + /* enable/disable overall compilation */ #ifndef DISABLE_ELBEEM @@ -1200,8 +1202,3 @@ void FLUID_OT_bake(wmOperatorType *ot) ot->poll= ED_operator_object_active; } -void ED_operatortypes_fluid(void) -{ - WM_operatortype_append(FLUID_OT_bake); -} - diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h index e03649575cb..3847ec8032a 100644 --- a/source/blender/editors/physics/physics_intern.h +++ b/source/blender/editors/physics/physics_intern.h @@ -33,6 +33,75 @@ #ifndef ED_PHYSICS_INTERN_H #define ED_PHYSICS_INTERN_H +struct wmOperatorType; + +/* particle_edit.c */ +int PE_poll(struct bContext *C); +int PE_hair_poll(struct bContext *C); +int PE_poll_3dview(struct bContext *C); + +void PARTICLE_OT_select_all_toggle(struct wmOperatorType *ot); +void PARTICLE_OT_select_first(struct wmOperatorType *ot); +void PARTICLE_OT_select_last(struct wmOperatorType *ot); +void PARTICLE_OT_select_linked(struct wmOperatorType *ot); +void PARTICLE_OT_select_less(struct wmOperatorType *ot); +void PARTICLE_OT_select_more(struct wmOperatorType *ot); + +void PARTICLE_OT_hide(struct wmOperatorType *ot); +void PARTICLE_OT_reveal(struct wmOperatorType *ot); + +void PARTICLE_OT_rekey(struct wmOperatorType *ot); +void PARTICLE_OT_subdivide(struct wmOperatorType *ot); +void PARTICLE_OT_remove_doubles(struct wmOperatorType *ot); +void PARTICLE_OT_delete(struct wmOperatorType *ot); +void PARTICLE_OT_mirror(struct wmOperatorType *ot); + +void PARTICLE_OT_brush_set(struct wmOperatorType *ot); +void PARTICLE_OT_brush_edit(struct wmOperatorType *ot); +void PARTICLE_OT_brush_radial_control(struct wmOperatorType *ot); + +void PARTICLE_OT_specials_menu(struct wmOperatorType *ot); + +void PARTICLE_OT_particle_edit_toggle(struct wmOperatorType *ot); +void PARTICLE_OT_edited_clear(struct wmOperatorType *ot); + +/* particle_object.c */ +void OBJECT_OT_particle_system_add(struct wmOperatorType *ot); +void OBJECT_OT_particle_system_remove(struct wmOperatorType *ot); + +void PARTICLE_OT_new(struct wmOperatorType *ot); +void PARTICLE_OT_new_target(struct wmOperatorType *ot); +void PARTICLE_OT_remove_target(struct wmOperatorType *ot); +void PARTICLE_OT_target_move_up(struct wmOperatorType *ot); +void PARTICLE_OT_target_move_down(struct wmOperatorType *ot); +void PARTICLE_OT_connect_hair(struct wmOperatorType *ot); +void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot); + +void PARTICLE_OT_dupliob_move_up(struct wmOperatorType *ot); +void PARTICLE_OT_dupliob_move_down(struct wmOperatorType *ot); + +/* particle_boids.c */ +void BOID_OT_rule_add(struct wmOperatorType *ot); +void BOID_OT_rule_del(struct wmOperatorType *ot); +void BOID_OT_rule_move_up(struct wmOperatorType *ot); +void BOID_OT_rule_move_down(struct wmOperatorType *ot); + +void BOID_OT_state_add(struct wmOperatorType *ot); +void BOID_OT_state_del(struct wmOperatorType *ot); +void BOID_OT_state_move_up(struct wmOperatorType *ot); +void BOID_OT_state_move_down(struct wmOperatorType *ot); + +/* physics_fluid.c */ +void FLUID_OT_bake(struct wmOperatorType *ot); + +/* physics_pointcache.c */ +void PTCACHE_OT_bake_all(struct wmOperatorType *ot); +void PTCACHE_OT_free_bake_all(struct wmOperatorType *ot); +void PTCACHE_OT_bake(struct wmOperatorType *ot); +void PTCACHE_OT_free_bake(struct wmOperatorType *ot); +void PTCACHE_OT_bake_from_cache(struct wmOperatorType *ot); +void PTCACHE_OT_add_new(struct wmOperatorType *ot); +void PTCACHE_OT_remove(struct wmOperatorType *ot); #endif /* ED_PHYSICS_INTERN_H */ diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c new file mode 100644 index 00000000000..0ebbfa6b701 --- /dev/null +++ b/source/blender/editors/physics/physics_ops.c @@ -0,0 +1,176 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> + +#include "DNA_windowmanager_types.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_physics.h" + +#include "physics_intern.h" // own include + +/***************************** particles ***********************************/ + +static void operatortypes_particle(void) +{ + WM_operatortype_append(PARTICLE_OT_select_all_toggle); + WM_operatortype_append(PARTICLE_OT_select_first); + WM_operatortype_append(PARTICLE_OT_select_last); + WM_operatortype_append(PARTICLE_OT_select_linked); + WM_operatortype_append(PARTICLE_OT_select_less); + WM_operatortype_append(PARTICLE_OT_select_more); + + WM_operatortype_append(PARTICLE_OT_hide); + WM_operatortype_append(PARTICLE_OT_reveal); + + WM_operatortype_append(PARTICLE_OT_rekey); + WM_operatortype_append(PARTICLE_OT_subdivide); + WM_operatortype_append(PARTICLE_OT_remove_doubles); + WM_operatortype_append(PARTICLE_OT_delete); + WM_operatortype_append(PARTICLE_OT_mirror); + + WM_operatortype_append(PARTICLE_OT_brush_set); + WM_operatortype_append(PARTICLE_OT_brush_edit); + WM_operatortype_append(PARTICLE_OT_brush_radial_control); + + WM_operatortype_append(PARTICLE_OT_specials_menu); + + WM_operatortype_append(PARTICLE_OT_particle_edit_toggle); + WM_operatortype_append(PARTICLE_OT_edited_clear); + + + WM_operatortype_append(OBJECT_OT_particle_system_add); + WM_operatortype_append(OBJECT_OT_particle_system_remove); + + WM_operatortype_append(PARTICLE_OT_new); + WM_operatortype_append(PARTICLE_OT_new_target); + WM_operatortype_append(PARTICLE_OT_remove_target); + WM_operatortype_append(PARTICLE_OT_target_move_up); + WM_operatortype_append(PARTICLE_OT_target_move_down); + WM_operatortype_append(PARTICLE_OT_connect_hair); + WM_operatortype_append(PARTICLE_OT_disconnect_hair); + + WM_operatortype_append(PARTICLE_OT_dupliob_move_up); + WM_operatortype_append(PARTICLE_OT_dupliob_move_down); +} + +static void keymap_particle(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap; + + keymap= WM_keymap_find(keyconf, "Particle", 0, 0); + keymap->poll= PE_poll; + + WM_keymap_add_item(keymap, "PARTICLE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PARTICLE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "PARTICLE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "deselect", 1); + + WM_keymap_add_item(keymap, "PARTICLE_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PARTICLE_OT_delete", DELKEY, KM_PRESS, 0, 0); + + WM_keymap_add_item(keymap, "PARTICLE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + + WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", ACTIONMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); + RNA_enum_set(WM_keymap_add_item(keymap, "PARTICLE_OT_brush_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); + + WM_keymap_add_item(keymap, "PARTICLE_OT_specials_menu", WKEY, KM_PRESS, 0, 0); +} + +/******************************* boids *************************************/ + +static void operatortypes_boids(void) +{ + WM_operatortype_append(BOID_OT_rule_add); + WM_operatortype_append(BOID_OT_rule_del); + WM_operatortype_append(BOID_OT_rule_move_up); + WM_operatortype_append(BOID_OT_rule_move_down); + + WM_operatortype_append(BOID_OT_state_add); + WM_operatortype_append(BOID_OT_state_del); + WM_operatortype_append(BOID_OT_state_move_up); + WM_operatortype_append(BOID_OT_state_move_down); +} + +/********************************* fluid ***********************************/ + +static void operatortypes_fluid(void) +{ + WM_operatortype_append(FLUID_OT_bake); +} + +/**************************** point cache **********************************/ + +static void operatortypes_pointcache(void) +{ + WM_operatortype_append(PTCACHE_OT_bake_all); + WM_operatortype_append(PTCACHE_OT_free_bake_all); + WM_operatortype_append(PTCACHE_OT_bake); + WM_operatortype_append(PTCACHE_OT_free_bake); + WM_operatortype_append(PTCACHE_OT_bake_from_cache); + WM_operatortype_append(PTCACHE_OT_add_new); + WM_operatortype_append(PTCACHE_OT_remove); +} + +//static void keymap_pointcache(wmWindowManager *wm) +//{ +// wmKeyMap *keymap= WM_keymap_find(wm, "Pointcache", 0, 0); +// +// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0); +// WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); +// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_particle_system", PADMINUS, KM_PRESS, KM_CTRL, 0); +// WM_keymap_add_item(keymap, "PHYSICS_OT_free_particle_system", LKEY, KM_PRESS, 0, 0); +//} + +/****************************** general ************************************/ + +void ED_operatortypes_physics(void) +{ + operatortypes_particle(); + operatortypes_boids(); + operatortypes_fluid(); + operatortypes_pointcache(); +} + +void ED_keymap_physics(wmKeyConfig *keyconf) +{ + keymap_particle(keyconf); + //keymap_pointcache(keyconf); +} + + + diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index f2c7b64032f..26099a18966 100644 --- a/source/blender/editors/physics/ed_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -27,6 +27,8 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include <stdlib.h> + #include "MEM_guardedalloc.h" #include "DNA_scene_types.h" @@ -332,26 +334,4 @@ void PTCACHE_OT_remove(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/**************************** registration **********************************/ - -void ED_operatortypes_pointcache(void) -{ - WM_operatortype_append(PTCACHE_OT_bake_all); - WM_operatortype_append(PTCACHE_OT_free_bake_all); - WM_operatortype_append(PTCACHE_OT_bake); - WM_operatortype_append(PTCACHE_OT_free_bake); - WM_operatortype_append(PTCACHE_OT_bake_from_cache); - WM_operatortype_append(PTCACHE_OT_add_new); - WM_operatortype_append(PTCACHE_OT_remove); -} - -//void ED_keymap_pointcache(wmWindowManager *wm) -//{ -// ListBase *keymap= WM_keymap_listbase(wm, "Pointcache", 0, 0); -// -// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0); -// WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); -// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_particle_system", PADMINUS, KM_PRESS, KM_CTRL, 0); -// WM_keymap_add_item(keymap, "PHYSICS_OT_free_particle_system", LKEY, KM_PRESS, 0, 0); -//} |