diff options
Diffstat (limited to 'source/blender/editors/physics/particle_edit.c')
-rw-r--r-- | source/blender/editors/physics/particle_edit.c | 349 |
1 files changed, 218 insertions, 131 deletions
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 93bfd156707..e1dcec1d9ab 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -42,16 +42,17 @@ #include "DNA_view3d_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_workspace_types.h" #include "BLI_math.h" #include "BLI_lasso_2d.h" #include "BLI_listbase.h" +#include "BLI_string.h" #include "BLI_kdtree.h" #include "BLI_rand.h" #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_object.h" @@ -62,15 +63,20 @@ #include "BKE_bvhutils.h" #include "BKE_pointcache.h" +#include "DEG_depsgraph.h" + #include "BIF_gl.h" -#include "BIF_glutil.h" #include "ED_object.h" #include "ED_physics.h" #include "ED_mesh.h" #include "ED_particle.h" +#include "ED_screen.h" #include "ED_view3d.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" + #include "UI_resources.h" #include "WM_api.h" @@ -87,25 +93,29 @@ int PE_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); - if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) + if (!scene || !view_layer || !ob || !(workspace->object_mode & OB_MODE_PARTICLE_EDIT)) { return 0; - - return (PE_get_current(scene, ob) != NULL); + } + return (PE_get_current(scene, view_layer, ob) != NULL); } int PE_hair_poll(bContext *C) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); PTCacheEdit *edit; - if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) + if (!scene || !ob || !(workspace->object_mode & OB_MODE_PARTICLE_EDIT)) { return 0; - - edit= PE_get_current(scene, ob); + } + edit= PE_get_current(scene, view_layer, ob); return (edit && edit->psys); } @@ -190,7 +200,8 @@ static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *br * * note: this function runs on poll, therefor it can runs many times a second * keep it fast! */ -static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) +static PTCacheEdit *pe_get_current( + const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, Object *ob, int create) { ParticleEditSettings *pset= PE_settings(scene); PTCacheEdit *edit = NULL; @@ -201,6 +212,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) return NULL; pset->scene = scene; + pset->view_layer = view_layer; pset->object = ob; BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); @@ -229,18 +241,18 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) if (psys->part && psys->part->type == PART_HAIR) { if (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) { if (create && !psys->pointcache->edit) - PE_create_particle_edit(scene, ob, pid->cache, NULL); + PE_create_particle_edit(eval_ctx, scene, view_layer, ob, pid->cache, NULL); edit = pid->cache->edit; } else { if (create && !psys->edit && psys->flag & PSYS_HAIR_DONE) - PE_create_particle_edit(scene, ob, NULL, psys); + PE_create_particle_edit(eval_ctx, scene, view_layer, ob, NULL, psys); edit = psys->edit; } } else { if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) - PE_create_particle_edit(scene, ob, pid->cache, psys); + PE_create_particle_edit(eval_ctx, scene, view_layer, ob, pid->cache, psys); edit = pid->cache->edit; } @@ -251,7 +263,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) { pset->flag |= PE_FADE_TIME; // NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB; - PE_create_particle_edit(scene, ob, pid->cache, NULL); + PE_create_particle_edit(eval_ctx, scene, view_layer, ob, pid->cache, NULL); } edit = pid->cache->edit; break; @@ -260,7 +272,7 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) { pset->flag |= PE_FADE_TIME; // NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB; - PE_create_particle_edit(scene, ob, pid->cache, NULL); + PE_create_particle_edit(eval_ctx, scene, view_layer, ob, pid->cache, NULL); } edit = pid->cache->edit; break; @@ -275,20 +287,21 @@ static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) return edit; } -PTCacheEdit *PE_get_current(Scene *scene, Object *ob) +PTCacheEdit *PE_get_current(Scene *scene, ViewLayer *view_layer, Object *ob) { - return pe_get_current(scene, ob, 0); + return pe_get_current(NULL, scene, view_layer, ob, 0); } -PTCacheEdit *PE_create_current(Scene *scene, Object *ob) +PTCacheEdit *PE_create_current(const EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - return pe_get_current(scene, ob, 1); + return pe_get_current(eval_ctx, scene, eval_ctx->view_layer, ob, 1); } -void PE_current_changed(Scene *scene, Object *ob) +void PE_current_changed(const EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - if (ob->mode == OB_MODE_PARTICLE_EDIT) - PE_create_current(scene, ob); + if (eval_ctx->object_mode == OB_MODE_PARTICLE_EDIT) { + PE_create_current(eval_ctx, scene, ob); + } } void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra) @@ -330,9 +343,10 @@ static int pe_x_mirror(Object *ob) typedef struct PEData { ViewContext vc; - bglMats mats; + const bContext *context; Scene *scene; + ViewLayer *view_layer; Object *ob; DerivedMesh *dm; PTCacheEdit *edit; @@ -366,9 +380,10 @@ static void PE_set_data(bContext *C, PEData *data) { memset(data, 0, sizeof(*data)); - data->scene= CTX_data_scene(C); - data->ob= CTX_data_active_object(C); - data->edit= PE_get_current(data->scene, data->ob); + data->scene = CTX_data_scene(C); + data->view_layer = CTX_data_view_layer(C); + data->ob = CTX_data_active_object(C); + data->edit = PE_get_current(data->scene, data->view_layer, data->ob); } static void PE_set_view3d_data(bContext *C, PEData *data) @@ -376,15 +391,16 @@ static void PE_set_view3d_data(bContext *C, PEData *data) PE_set_data(C, data); ED_view3d_viewcontext_init(C, &data->vc); - /* note, the object argument means the modelview matrix does not account for the objects matrix, use viewmat rather than (obmat * viewmat) */ - view3d_get_transformation(data->vc.ar, data->vc.rv3d, NULL, &data->mats); if (V3D_IS_ZBUF(data->vc.v3d)) { if (data->vc.v3d->flag & V3D_INVALID_BACKBUF) { + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + /* needed or else the draw matrix can be incorrect */ view3d_operator_needs_opengl(C); - ED_view3d_backbuf_validate(&data->vc); + ED_view3d_backbuf_validate(&eval_ctx, &data->vc); /* we may need to force an update here by setting the rv3d as dirty * for now it seems ok, but take care!: * rv3d->depths->dirty = 1; */ @@ -417,7 +433,6 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[ { View3D *v3d= data->vc.v3d; ViewDepths *vd = data->vc.rv3d->depths; - double ux, uy, uz; float depth; /* nothing to do */ @@ -433,9 +448,6 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[ } #endif - gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection, - (GLint *)data->mats.viewport, &ux, &uy, &uz); - /* check if screen_co is within bounds because brush_cut uses out of screen coords */ if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) { BLI_assert(vd && vd->depths); @@ -445,7 +457,10 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[ else return 0; - if ((float)uz - 0.00001f > depth) + float win[3]; + ED_view3d_project(data->vc.ar, co, win); + + if (win[2] - 0.00001f > depth) return 0; else return 1; @@ -1130,12 +1145,15 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys) BLI_kdtree_balance(edit->emitter_field); } -static void PE_update_selection(Scene *scene, Object *ob, int useflag) +static void PE_update_selection(const bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, int useflag) { - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit = PE_get_current(scene, view_layer, ob); HairKey *hkey; + EvaluationContext eval_ctx; POINT_P; KEY_K; + CTX_data_eval_ctx(C, &eval_ctx); + /* flag all particles to be updated if not using flag */ if (!useflag) LOOP_POINTS @@ -1151,7 +1169,7 @@ static void PE_update_selection(Scene *scene, Object *ob, int useflag) } } - psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering); + psys_cache_edit_paths(&eval_ctx, scene, ob, edit, CFRA, G.is_rendering); /* disable update flag */ @@ -1237,12 +1255,12 @@ static void update_velocities(PTCacheEdit *edit) } } -void PE_update_object(Scene *scene, Object *ob, int useflag) +void PE_update_object(const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, Object *ob, int useflag) { /* use this to do partial particle updates, not usable when adding or * removing, then a full redo is necessary and calling this may crash */ ParticleEditSettings *pset= PE_settings(scene); - PTCacheEdit *edit = PE_get_current(scene, ob); + PTCacheEdit *edit = PE_get_current(scene, view_layer, ob); POINT_P; if (!edit) @@ -1267,7 +1285,7 @@ void PE_update_object(Scene *scene, Object *ob, int useflag) PE_hide_keys_time(scene, edit, CFRA); /* regenerate path caches */ - psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering); + psys_cache_edit_paths(eval_ctx, scene, ob, edit, CFRA, G.is_rendering); /* disable update flag */ LOOP_POINTS { @@ -1276,6 +1294,8 @@ void PE_update_object(Scene *scene, Object *ob, int useflag) if (edit->psys) edit->psys->flag &= ~PSYS_HAIR_UPDATED; + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } /************************************************/ @@ -1377,8 +1397,9 @@ static void select_action_apply(PTCacheEditPoint *point, PTCacheEditKey *key, in static int pe_select_all_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); POINT_P; KEY_K; int action = RNA_enum_get(op->ptr, "action"); @@ -1401,7 +1422,7 @@ static int pe_select_all_exec(bContext *C, wmOperator *op) } } - PE_update_selection(scene, ob, 1); + PE_update_selection(C, scene, view_layer, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1430,10 +1451,11 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec { PEData data; Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); POINT_P; KEY_K; - + if (!PE_start_edit(edit)) return OPERATOR_CANCELLED; @@ -1458,7 +1480,7 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec else for_mouse_hit_keys(&data, toggle_key_select, 1); - PE_update_selection(scene, ob, 1); + PE_update_selection(C, scene, view_layer, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1499,7 +1521,7 @@ static int select_roots_exec(bContext *C, wmOperator *op) data.select_action = action; foreach_point(&data, select_root); - PE_update_selection(data.scene, data.ob, 1); + PE_update_selection(C, data.scene, data.view_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1564,7 +1586,7 @@ static int select_tips_exec(bContext *C, wmOperator *op) data.select_action = action; foreach_point(&data, select_tip); - PE_update_selection(data.scene, data.ob, 1); + PE_update_selection(C, data.scene, data.view_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1603,6 +1625,7 @@ static int select_random_exec(bContext *C, wmOperator *op) PEData data; int type; Scene *scene; + ViewLayer *view_layer; Object *ob; /* used by LOOP_VISIBLE_POINTS, LOOP_VISIBLE_KEYS and LOOP_KEYS */ @@ -1622,8 +1645,9 @@ static int select_random_exec(bContext *C, wmOperator *op) PE_set_data(C, &data); data.select_action = SEL_SELECT; scene = CTX_data_scene(C); + view_layer = CTX_data_view_layer(C); ob = CTX_data_active_object(C); - edit = PE_get_current(scene, ob); + edit = PE_get_current(scene, view_layer, ob); rng = BLI_rng_new_srandom(seed); @@ -1648,7 +1672,7 @@ static int select_random_exec(bContext *C, wmOperator *op) BLI_rng_free(rng); - PE_update_selection(data.scene, data.ob, 1); + PE_update_selection(C, data.scene, data.view_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1692,7 +1716,7 @@ static int select_linked_exec(bContext *C, wmOperator *op) data.select= !RNA_boolean_get(op->ptr, "deselect"); for_mouse_hit_keys(&data, select_keys, 1); /* nearest only */ - PE_update_selection(data.scene, data.ob, 1); + PE_update_selection(C, data.scene, data.view_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1740,8 +1764,9 @@ void PE_deselect_all_visible(PTCacheEdit *edit) int PE_border_select(bContext *C, rcti *rect, bool select, bool extend) { Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); PEData data; if (!PE_start_edit(edit)) @@ -1756,7 +1781,7 @@ int PE_border_select(bContext *C, rcti *rect, bool select, bool extend) for_mouse_hit_keys(&data, select_key, 0); - PE_update_selection(scene, ob, 1); + PE_update_selection(C, scene, view_layer, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1767,8 +1792,9 @@ int PE_border_select(bContext *C, rcti *rect, bool select, bool extend) int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad) { Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); PEData data; if (!PE_start_edit(edit)) @@ -1781,7 +1807,7 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad) for_mouse_hit_keys(&data, select_key, 0); - PE_update_selection(scene, ob, 1); + PE_update_selection(C, scene, view_layer, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1792,10 +1818,11 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad) int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool extend, bool select) { Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); ARegion *ar= CTX_wm_region(C); ParticleEditSettings *pset= PE_settings(scene); - PTCacheEdit *edit = PE_get_current(scene, ob); + PTCacheEdit *edit = PE_get_current(scene, view_layer, ob); ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); POINT_P; KEY_K; @@ -1869,7 +1896,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool } } - PE_update_selection(scene, ob, 1); + PE_update_selection(C, scene, view_layer, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1881,7 +1908,8 @@ static int hide_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); Scene *scene= CTX_data_scene(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + ViewLayer *view_layer = CTX_data_view_layer(C); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); POINT_P; KEY_K; if (RNA_enum_get(op->ptr, "unselected")) { @@ -1903,7 +1931,7 @@ static int hide_exec(bContext *C, wmOperator *op) } } - PE_update_selection(scene, ob, 1); + PE_update_selection(C, scene, view_layer, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1933,7 +1961,8 @@ static int reveal_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); Scene *scene= CTX_data_scene(C); - PTCacheEdit *edit = PE_get_current(scene, ob); + ViewLayer *view_layer = CTX_data_view_layer(C); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); const bool select = RNA_boolean_get(op->ptr, "select"); POINT_P; KEY_K; @@ -1948,7 +1977,7 @@ static int reveal_exec(bContext *C, wmOperator *op) } } - PE_update_selection(scene, ob, 1); + PE_update_selection(C, scene, view_layer, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -2010,7 +2039,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op)) PE_set_data(C, &data); foreach_point(&data, select_less_keys); - PE_update_selection(data.scene, data.ob, 1); + PE_update_selection(C, data.scene, data.view_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -2072,7 +2101,7 @@ static int select_more_exec(bContext *C, wmOperator *UNUSED(op)) PE_set_data(C, &data); foreach_point(&data, select_more_keys); - PE_update_selection(data.scene, data.ob, 1); + PE_update_selection(C, data.scene, data.view_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -2105,12 +2134,15 @@ static void rekey_particle(PEData *data, int pa_index) ParticleKey state; HairKey *key, *new_keys, *okey; PTCacheEditKey *ekey; + EvaluationContext eval_ctx; float dval, sta, end; int k; - sim.scene= data->scene; - sim.ob= data->ob; - sim.psys= edit->psys; + CTX_data_eval_ctx(data->context, &eval_ctx); + sim.eval_ctx = &eval_ctx; + sim.scene = data->scene; + sim.ob = data->ob; + sim.psys = edit->psys; pa->flag |= PARS_REKEY; @@ -2161,6 +2193,9 @@ static int rekey_exec(bContext *C, wmOperator *op) { PEData data; + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + PE_set_data(C, &data); data.dval= 1.0f / (float)(data.totrekey-1); @@ -2169,7 +2204,7 @@ static int rekey_exec(bContext *C, wmOperator *op) foreach_selected_point(&data, rekey_particle); recalc_lengths(data.edit); - PE_update_object(data.scene, data.ob, 1); + PE_update_object(&eval_ctx, data.scene, data.view_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob); return OPERATOR_FINISHED; @@ -2194,24 +2229,28 @@ void PARTICLE_OT_rekey(wmOperatorType *ot) RNA_def_int(ot->srna, "keys_number", 2, 2, INT_MAX, "Number of Keys", "", 2, 100); } -static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float path_time) +static void rekey_particle_to_time(const bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, int pa_index, float path_time) { - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); ParticleSystem *psys; - ParticleSimulationData sim= {0}; + ParticleSimulationData sim = {0}; ParticleData *pa; ParticleKey state; HairKey *new_keys, *key; PTCacheEditKey *ekey; + EvaluationContext eval_ctx; int k; + CTX_data_eval_ctx(C, &eval_ctx); + if (!edit || !edit->psys) return; psys = edit->psys; - sim.scene= scene; - sim.ob= ob; - sim.psys= psys; + sim.eval_ctx = &eval_ctx; + sim.scene = scene; + sim.ob = ob; + sim.psys = psys; pa= psys->particles + pa_index; @@ -2421,14 +2460,17 @@ static void subdivide_particle(PEData *data, int pa_index) ParticleKey state; HairKey *key, *nkey, *new_keys; PTCacheEditKey *ekey, *nekey, *new_ekeys; + EvaluationContext eval_ctx; int k; short totnewkey=0; float endtime; - sim.scene= data->scene; - sim.ob= data->ob; - sim.psys= edit->psys; + CTX_data_eval_ctx(data->context, &eval_ctx); + sim.eval_ctx = &eval_ctx; + sim.scene = data->scene; + sim.ob = data->ob; + sim.psys = edit->psys; for (k=0, ekey=point->keys; k<pa->totkey-1; k++, ekey++) { if (ekey->flag&PEK_SELECT && (ekey+1)->flag&PEK_SELECT) @@ -2496,11 +2538,14 @@ static int subdivide_exec(bContext *C, wmOperator *UNUSED(op)) { PEData data; + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + PE_set_data(C, &data); foreach_point(&data, subdivide_particle); recalc_lengths(data.edit); - PE_update_object(data.scene, data.ob, 1); + PE_update_object(&eval_ctx, data.scene, data.view_layer, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob); return OPERATOR_FINISHED; @@ -2526,8 +2571,9 @@ void PARTICLE_OT_subdivide(wmOperatorType *ot) static int remove_doubles_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd; KDTree *tree; @@ -2589,7 +2635,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) BKE_reportf(op->reports, RPT_INFO, "Removed %d double particles", totremoved); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); return OPERATOR_FINISHED; @@ -2618,9 +2664,10 @@ void PARTICLE_OT_remove_doubles(wmOperatorType *ot) static int weight_set_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); ParticleEditSettings *pset= PE_settings(scene); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); ParticleSystem *psys = edit->psys; POINT_P; KEY_K; @@ -2641,7 +2688,7 @@ static int weight_set_exec(bContext *C, wmOperator *op) } } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); return OPERATOR_FINISHED; @@ -2673,24 +2720,27 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) ParticleEditSettings *pset= PE_settings(scene); ParticleBrushData *brush; - if (pset->brushtype < 0) + if (pset->brushtype < 0) { return; + } - brush= &pset->brush[pset->brushtype]; + brush = &pset->brush[pset->brushtype]; if (brush) { - glPushMatrix(); + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - glTranslatef((float)x, (float)y, 0.0f); + immUniformColor4ub(255, 255, 255, 128); - glColor4ub(255, 255, 255, 128); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glutil_draw_lined_arc(0.0, M_PI*2.0, pe_brush_size_get(scene, brush), 40); + + imm_draw_circle_wire_2d(pos, (float)x, (float)y, pe_brush_size_get(scene, brush), 40); + glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); - - glPopMatrix(); + + immUnbindProgram(); } } @@ -2747,7 +2797,7 @@ static int delete_exec(bContext *C, wmOperator *op) recalc_lengths(data.edit); } - DAG_id_tag_update(&data.ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&data.ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob); return OPERATOR_FINISHED; @@ -2774,11 +2824,12 @@ void PARTICLE_OT_delete(wmOperatorType *ot) /*************************** mirror operator **************************/ -static void PE_mirror_x(Scene *scene, Object *ob, int tagged) +static void PE_mirror_x( + Scene *scene, ViewLayer *view_layer, Object *ob, int tagged) { Mesh *me= (Mesh *)(ob->data); ParticleSystemModifierData *psmd; - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit = PE_get_current(scene, view_layer, ob); ParticleSystem *psys = edit->psys; ParticleData *pa, *newpa, *new_pars; PTCacheEditPoint *newpoint, *new_points; @@ -2925,14 +2976,15 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) static int mirror_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); - PE_mirror_x(scene, ob, 0); + PE_mirror_x(scene, view_layer, ob, 0); update_world_cos(ob, edit); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -3065,7 +3117,7 @@ static void brush_cut(PEData *data, int pa_index) edit->points[pa_index].flag |= PEP_TAG; } else { - rekey_particle_to_time(data->scene, ob, pa_index, cut_time); + rekey_particle_to_time(data->context, data->scene, data->view_layer, ob, pa_index, cut_time); edit->points[pa_index].flag |= PEP_EDIT_RECALC; } } @@ -3313,25 +3365,28 @@ static void intersect_dm_quad_weights(const float v1[3], const float v2[3], cons } /* check intersection with a derivedmesh */ -static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, +static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, DerivedMesh *dm, float *vert_cos, const float co1[3], const float co2[3], float *min_d, int *min_face, float *min_w, float *face_minmax, float *pa_minmax, float radius, float *ipoint) { + EvaluationContext eval_ctx; MFace *mface= NULL; MVert *mvert= NULL; int i, totface, intersect=0; float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3]; float cur_ipoint[3]; + CTX_data_eval_ctx(C, &eval_ctx); + if (dm == NULL) { psys_disable_all(ob); - dm=mesh_get_derived_final(scene, ob, 0); + dm = mesh_get_derived_final(&eval_ctx, scene, ob, 0); if (dm == NULL) - dm=mesh_get_derived_deform(scene, ob, 0); + dm = mesh_get_derived_deform(&eval_ctx, scene, ob, 0); psys_enable_all(ob); @@ -3444,8 +3499,10 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, return intersect; } -static int brush_add(PEData *data, short number) +static int brush_add(const bContext *C, PEData *data, short number) { + EvaluationContext eval_ctx; + const Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene= data->scene; Object *ob= data->ob; DerivedMesh *dm; @@ -3473,6 +3530,9 @@ static int brush_add(PEData *data, short number) rng = BLI_rng_new_srandom(psys->seed+data->mval[0]+data->mval[1]); + CTX_data_eval_ctx(C, &eval_ctx); + + sim.eval_ctx = &eval_ctx; sim.scene= scene; sim.ob= ob; sim.psys= psys; @@ -3506,14 +3566,14 @@ static int brush_add(PEData *data, short number) mco[0] = data->mval[0] + dmx; mco[1] = data->mval[1] + dmy; - ED_view3d_win_to_segment(data->vc.ar, data->vc.v3d, mco, co1, co2, true); + ED_view3d_win_to_segment(depsgraph, data->vc.ar, data->vc.v3d, mco, co1, co2, true); mul_m4_v3(imat, co1); mul_m4_v3(imat, co2); min_d=2.0; /* warning, returns the derived mesh face */ - if (particle_intersect_dm(scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) { + if (particle_intersect_dm(C, scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) { if (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly) { add_pars[n].num = add_pars[n].num_dmcache; add_pars[n].num_dmcache = DMCACHE_ISCHILD; @@ -3694,6 +3754,7 @@ static int brush_add(PEData *data, short number) typedef struct BrushEdit { Scene *scene; + ViewLayer *view_layer; Object *ob; PTCacheEdit *edit; @@ -3708,9 +3769,10 @@ typedef struct BrushEdit { static int brush_edit_init(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob= CTX_data_active_object(C); ParticleEditSettings *pset= PE_settings(scene); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); ARegion *ar= CTX_wm_region(C); BrushEdit *bedit; float min[3], max[3]; @@ -3720,7 +3782,7 @@ static int brush_edit_init(bContext *C, wmOperator *op) /* set the 'distance factor' for grabbing (used in comb etc) */ INIT_MINMAX(min, max); - PE_minmax(scene, min, max); + PE_minmax(scene, view_layer, min, max); mid_v3_v3v3(min, min, max); bedit= MEM_callocN(sizeof(BrushEdit), "BrushEdit"); @@ -3728,6 +3790,7 @@ static int brush_edit_init(bContext *C, wmOperator *op) op->customdata= bedit; bedit->scene= scene; + bedit->view_layer = view_layer; bedit->ob= ob; bedit->edit= edit; @@ -3743,6 +3806,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) { BrushEdit *bedit= op->customdata; Scene *scene= bedit->scene; + ViewLayer *view_layer = bedit->view_layer; Object *ob= bedit->ob; PTCacheEdit *edit= bedit->edit; ParticleEditSettings *pset= PE_settings(scene); @@ -3758,6 +3822,9 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (!PE_start_edit(edit)) return; + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + RNA_float_get_array(itemptr, "mouse", mousef); mouse[0] = mousef[0]; mouse[1] = mousef[1]; @@ -3783,6 +3850,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) (sqrtf(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first) { PEData data= bedit->data; + data.context = C; // TODO(mai): why isnt this set in bedit->data? view3d_operator_needs_opengl(C); selected= (short)count_selected_keys(scene, edit); @@ -3883,7 +3951,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (edit->psys && edit->psys->part->from==PART_FROM_FACE) { data.mval= mval; - added= brush_add(&data, brush->count); + added= brush_add(C, &data, brush->count); if (pset->flag & PE_KEEP_LENGTHS) recalc_lengths(edit); @@ -3933,21 +4001,22 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_CUT) && (added || removed)) { if (pset->brushtype == PE_BRUSH_ADD && pe_x_mirror(ob)) - PE_mirror_x(scene, ob, 1); + PE_mirror_x(scene, view_layer, ob, 1); update_world_cos(ob, edit); psys_free_path_cache(NULL, edit); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + } + else { + PE_update_object(&eval_ctx, scene, view_layer, ob, 1); } - else - PE_update_object(scene, ob, 1); } if (edit->psys) { WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); } else { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } @@ -4155,7 +4224,7 @@ static void shape_cut(PEData *data, int pa_index) edit->points[pa_index].flag |= PEP_TAG; } else { - rekey_particle_to_time(data->scene, ob, pa_index, cut_time); + rekey_particle_to_time(data->context, data->scene, data->view_layer, ob, pa_index, cut_time); edit->points[pa_index].flag |= PEP_EDIT_RECALC; } } @@ -4164,9 +4233,10 @@ static void shape_cut(PEData *data, int pa_index) static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = CTX_data_active_object(C); ParticleEditSettings *pset = PE_settings(scene); - PTCacheEdit *edit = PE_get_current(scene, ob); + PTCacheEdit *edit = PE_get_current(scene, view_layer, ob); Object *shapeob = pset->shape_object; int selected = count_selected_keys(scene, edit); int lock_root = pset->flag & PE_LOCK_FIRST; @@ -4174,6 +4244,9 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op)) if (!PE_start_edit(edit)) return OPERATOR_CANCELLED; + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + /* disable locking temporatily for disconnected hair */ if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) pset->flag &= ~PE_LOCK_FIRST; @@ -4199,16 +4272,17 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op)) if (removed) { update_world_cos(ob, edit); psys_free_path_cache(NULL, edit); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + } + else { + PE_update_object(&eval_ctx, scene, view_layer, ob, 1); } - else - PE_update_object(scene, ob, 1); if (edit->psys) { WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); } else { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } @@ -4237,10 +4311,10 @@ void PARTICLE_OT_shape_cut(wmOperatorType *ot) /************************ utilities ******************************/ -int PE_minmax(Scene *scene, float min[3], float max[3]) +int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3]) { - Object *ob= OBACT; - PTCacheEdit *edit= PE_get_current(scene, ob); + Object *ob= OBACT(view_layer); + PTCacheEdit *edit= PE_get_current(scene, view_layer, ob); ParticleSystem *psys; ParticleSystemModifierData *psmd = NULL; POINT_P; KEY_K; @@ -4277,7 +4351,8 @@ int PE_minmax(Scene *scene, float min[3], float max[3]) /************************ particle edit toggle operator ************************/ /* initialize needed data for bake edit */ -void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys) +void PE_create_particle_edit( + const EvaluationContext *eval_ctx, Scene *scene, ViewLayer *view_layer, Object *ob, PointCache *cache, ParticleSystem *psys) { PTCacheEdit *edit; ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL; @@ -4378,10 +4453,10 @@ void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, Partic recalc_lengths(edit); if (psys && !cache) recalc_emitter_field(ob, psys); - PE_update_object(scene, ob, 1); + PE_update_object(eval_ctx, scene, view_layer, ob, 1); PTCacheUndo_clear(edit); - PE_undo_push(scene, "Original"); + PE_undo_push(scene, view_layer, "Original"); } } @@ -4403,21 +4478,26 @@ static int particle_edit_toggle_poll(bContext *C) static int particle_edit_toggle_exec(bContext *C, wmOperator *op) { + wmWindowManager *wm = CTX_wm_manager(C); + struct WorkSpace *workspace = CTX_wm_workspace(C); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_PARTICLE_EDIT; - const bool is_mode_set = (ob->mode & mode_flag) != 0; + const bool is_mode_set = (eval_ctx.object_mode & mode_flag) != 0; if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } if (!is_mode_set) { PTCacheEdit *edit; - ob->mode |= mode_flag; - edit= PE_create_current(scene, ob); + + workspace->object_mode |= mode_flag; + edit= PE_create_current(&eval_ctx, scene, ob); /* mesh may have changed since last entering editmode. * note, this may have run before if the edit data was just created, so could avoid this and speed up a little */ @@ -4428,12 +4508,14 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL); } else { - ob->mode &= ~mode_flag; + workspace->object_mode &= ~mode_flag; toggle_particle_cursor(C, 0); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL); } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + ED_workspace_object_mode_sync_from_object(wm, workspace, ob); + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -4474,7 +4556,7 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op)) psys_reset(psys, PSYS_RESET_DEPSGRAPH); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } } else { /* some operation might have protected hair from editing so let's clear the flag */ @@ -4482,7 +4564,7 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op)) psys->flag &= ~PSYS_GLOBAL_HAIR; psys->flag &= ~PSYS_EDITED; WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } return OPERATOR_FINISHED; @@ -4585,19 +4667,24 @@ static int unify_length_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); - PTCacheEdit *edit = PE_get_current(scene, ob); + ViewLayer *view_layer = CTX_data_view_layer(C); + PTCacheEdit *edit = PE_get_current(scene, view_layer, ob); float average_length = calculate_average_length(edit); + if (average_length == 0.0f) { return OPERATOR_CANCELLED; } scale_points_to_length(edit, average_length); - PE_update_object(scene, ob, 1); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); + + PE_update_object(&eval_ctx, scene, view_layer, ob, 1); if (edit->psys) { WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); } else { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } |