Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/physics')
-rw-r--r--source/blender/editors/physics/SConscript7
-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.c651
-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.h69
-rw-r--r--source/blender/editors/physics/physics_ops.c176
-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);
-//}