diff options
Diffstat (limited to 'source/blender/editors/physics')
-rw-r--r-- | source/blender/editors/physics/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/physics/dynamicpaint_ops.c | 18 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_boids.c | 20 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_edit.c | 1241 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_edit_undo.c | 22 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_object.c | 203 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_fluid.c | 35 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_intern.h | 10 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_ops.c | 20 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_pointcache.c | 71 | ||||
-rw-r--r-- | source/blender/editors/physics/rigidbody_constraint.c | 37 | ||||
-rw-r--r-- | source/blender/editors/physics/rigidbody_object.c | 30 | ||||
-rw-r--r-- | source/blender/editors/physics/rigidbody_world.c | 7 |
13 files changed, 1063 insertions, 652 deletions
diff --git a/source/blender/editors/physics/CMakeLists.txt b/source/blender/editors/physics/CMakeLists.txt index a04ebb24d2c..3705ff9d41a 100644 --- a/source/blender/editors/physics/CMakeLists.txt +++ b/source/blender/editors/physics/CMakeLists.txt @@ -23,6 +23,7 @@ set(INC ../../blenkernel ../../blenlib ../../blentranslation + ../../depsgraph ../../gpu ../../makesdna ../../makesrna diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 480d17bbf85..7f74dd4666a 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -42,7 +42,6 @@ #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_object_deform.h" -#include "BKE_depsgraph.h" #include "BKE_dynamicpaint.h" #include "BKE_global.h" #include "BKE_main.h" @@ -50,6 +49,9 @@ #include "BKE_report.h" #include "BKE_screen.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "ED_mesh.h" #include "ED_screen.h" #include "ED_object.h" @@ -135,7 +137,7 @@ static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) } dynamicPaint_resetPreview(canvas); - DAG_id_tag_update(&obj_ctx->id, OB_RECALC_DATA); + DEG_id_tag_update(&obj_ctx->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obj_ctx); return OPERATOR_FINISHED; @@ -181,8 +183,8 @@ static int type_toggle_exec(bContext *C, wmOperator *op) } /* update dependency */ - DAG_id_tag_update(&cObject->id, OB_RECALC_DATA); - DAG_relations_tag_update(CTX_data_main(C)); + DEG_id_tag_update(&cObject->id, OB_RECALC_DATA); + DEG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, cObject); return OPERATOR_FINISHED; @@ -286,6 +288,7 @@ typedef struct DynamicPaintBakeJob { struct Main *bmain; Scene *scene; + Depsgraph *depsgraph; Object *ob; DynamicPaintSurface *surface; @@ -357,7 +360,7 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job) frame = surface->start_frame; orig_frame = scene->r.cfra; scene->r.cfra = (int)frame; - ED_update_for_newframe(job->bmain, scene, 1); + ED_update_for_newframe(job->bmain, job->depsgraph); /* Init surface */ if (!dynamicPaint_createUVSurface(scene, surface, job->progress, job->do_update)) { @@ -383,8 +386,8 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job) /* calculate a frame */ scene->r.cfra = (int)frame; - ED_update_for_newframe(job->bmain, scene, 1); - if (!dynamicPaint_calculateFrame(job->bmain, job->bmain->eval_ctx, surface, scene, cObject, frame)) { + ED_update_for_newframe(job->bmain, job->depsgraph); + if (!dynamicPaint_calculateFrame(surface, job->depsgraph, scene, cObject, frame)) { job->success = 0; return; } @@ -479,6 +482,7 @@ static int dynamicpaint_bake_exec(struct bContext *C, struct wmOperator *op) DynamicPaintBakeJob *job = MEM_mallocN(sizeof(DynamicPaintBakeJob), "DynamicPaintBakeJob"); job->bmain = CTX_data_main(C); job->scene = scene; + job->depsgraph = CTX_data_depsgraph(C); job->ob = ob; job->canvas = canvas; job->surface = surface; diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c index b6fc0fcad80..ac031079434 100644 --- a/source/blender/editors/physics/particle_boids.c +++ b/source/blender/editors/physics/particle_boids.c @@ -39,10 +39,12 @@ #include "BKE_boids.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_main.h" #include "BKE_particle.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "RNA_access.h" #include "RNA_enum_types.h" #include "RNA_define.h" @@ -75,7 +77,7 @@ static int rule_add_exec(bContext *C, wmOperator *op) BLI_addtail(&state->rules, rule); - DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); + DEG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); return OPERATOR_FINISHED; } @@ -121,8 +123,8 @@ static int rule_del_exec(bContext *C, wmOperator *UNUSED(op)) if (rule) rule->flag |= BOIDRULE_CURRENT; - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); return OPERATOR_FINISHED; } @@ -158,7 +160,7 @@ static int rule_move_up_exec(bContext *C, wmOperator *UNUSED(op)) BLI_remlink(&state->rules, rule); BLI_insertlinkbefore(&state->rules, rule->prev, rule); - DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); + DEG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } @@ -194,7 +196,7 @@ static int rule_move_down_exec(bContext *C, wmOperator *UNUSED(op)) BLI_remlink(&state->rules, rule); BLI_insertlinkafter(&state->rules, rule->next, rule); - DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); + DEG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } @@ -277,8 +279,8 @@ static int state_del_exec(bContext *C, wmOperator *UNUSED(op)) state->flag |= BOIDSTATE_CURRENT; - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); return OPERATOR_FINISHED; } @@ -349,7 +351,7 @@ static int state_move_down_exec(bContext *C, wmOperator *UNUSED(op)) if (state->flag & BOIDSTATE_CURRENT && state->next) { BLI_remlink(&boids->states, state); BLI_insertlinkafter(&boids->states, state->next, state); - DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); + DEG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 73ed8b016ef..e637a58e8c6 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -46,40 +46,55 @@ #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_task.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" +#include "BKE_library.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_report.h" +#include "BKE_scene.h" #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 "GPU_state.h" + #include "UI_resources.h" #include "WM_api.h" #include "WM_types.h" +#include "WM_message.h" +#include "WM_toolsystem.h" #include "RNA_access.h" #include "RNA_define.h" +#include "DEG_depsgraph_query.h" + +#include "PIL_time_utildefines.h" + #include "physics_intern.h" #include "particle_edit_utildefines.h" @@ -88,27 +103,25 @@ bool PE_poll(bContext *C) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) + if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) { return 0; - - return (PE_get_current(bmain, scene, ob) != NULL); + } + return (PE_get_current(scene, ob) != NULL); } bool PE_hair_poll(bContext *C) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); PTCacheEdit *edit; - if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) + if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) { return 0; - - edit= PE_get_current(bmain, scene, ob); + } + edit = PE_get_current(scene, ob); return (edit && edit->psys); } @@ -186,12 +199,55 @@ static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *br return brush->size * U.pixelsize; } +PTCacheEdit *PE_get_current_from_psys(ParticleSystem *psys) +{ + if (psys->part && psys->part->type == PART_HAIR) { + if ((psys->flag & PSYS_HAIR_DYNAMICS) != 0 && + (psys->pointcache->flag & PTCACHE_BAKED) != 0) + { + return psys->pointcache->edit; + } + else { + return psys->edit; + } + } + else if (psys->pointcache->flag & PTCACHE_BAKED) { + return psys->pointcache->edit; + } + return NULL; +} + +/* NOTE: Similar to creation of edit, but only updates pointers in the + * existing struct. + */ +static void pe_update_hair_particle_edit_pointers(PTCacheEdit *edit) +{ + ParticleSystem *psys = edit->psys; + ParticleData *pa = psys->particles; + for (int p = 0; p < edit->totpoint; p++) { + PTCacheEditPoint *point = &edit->points[p]; + HairKey *hair_key = pa->hair; + for (int k = 0; k < point->totkey; k++) { + PTCacheEditKey *key = &point->keys[k]; + key->co = hair_key->co; + key->time = &hair_key->time; + key->flag = hair_key->editflag; + if (!(psys->flag & PSYS_GLOBAL_HAIR)) { + key->flag |= PEK_USE_WCO; + hair_key->editflag |= PEK_USE_WCO; + } + hair_key++; + } + pa++; + } +} /* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set * * note: this function runs on poll, therefor it can runs many times a second * keep it fast! */ -static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int create) +static PTCacheEdit *pe_get_current( + Depsgraph *depsgraph, Scene *scene, Object *ob, int create) { ParticleEditSettings *pset= PE_settings(scene); PTCacheEdit *edit = NULL; @@ -204,7 +260,7 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr pset->scene = scene; pset->object = ob; - BKE_ptcache_ids_from_object(bmain, &pidlist, ob, NULL, 0); + BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); /* in the case of only one editable thing, set pset->edittype accordingly */ if (BLI_listbase_is_single(&pidlist)) { @@ -230,18 +286,21 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr 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(bmain, scene, ob, pid->cache, NULL); + PE_create_particle_edit(depsgraph, scene, ob, pid->cache, NULL); edit = pid->cache->edit; } else { - if (create && !psys->edit && psys->flag & PSYS_HAIR_DONE) - PE_create_particle_edit(bmain, scene, ob, NULL, psys); + if (create && !psys->edit) { + if (psys->flag & PSYS_HAIR_DONE) { + PE_create_particle_edit(depsgraph, scene, ob, NULL, psys); + } + } edit = psys->edit; } } else { if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) - PE_create_particle_edit(bmain, scene, ob, pid->cache, psys); + PE_create_particle_edit(depsgraph, scene, ob, pid->cache, psys); edit = pid->cache->edit; } @@ -252,7 +311,7 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr 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(bmain, scene, ob, pid->cache, NULL); + PE_create_particle_edit(depsgraph, scene, ob, pid->cache, NULL); } edit = pid->cache->edit; break; @@ -261,35 +320,44 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr 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(bmain, scene, ob, pid->cache, NULL); + PE_create_particle_edit(depsgraph, scene, ob, pid->cache, NULL); } edit = pid->cache->edit; break; } } - if (edit) + if (edit) { edit->pid = *pid; + if (edit->flags & PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL) { + if (edit->psys != NULL) { + psys_copy_particles(edit->psys, edit->psys_eval); + pe_update_hair_particle_edit_pointers(edit); + } + edit->flags &= ~PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL; + } + } BLI_freelistN(&pidlist); return edit; } -PTCacheEdit *PE_get_current(Main *bmain, Scene *scene, Object *ob) +PTCacheEdit *PE_get_current(Scene *scene, Object *ob) { - return pe_get_current(bmain, scene, ob, 0); + return pe_get_current(NULL, scene, ob, 0); } -PTCacheEdit *PE_create_current(Main *bmain, Scene *scene, Object *ob) +PTCacheEdit *PE_create_current(Depsgraph *depsgraph, Scene *scene, Object *ob) { - return pe_get_current(bmain, scene, ob, 1); + return pe_get_current(depsgraph, scene, ob, 1); } -void PE_current_changed(Main *bmain, Scene *scene, Object *ob) +void PE_current_changed(Depsgraph *depsgraph, Scene *scene, Object *ob) { - if (ob->mode == OB_MODE_PARTICLE_EDIT) - PE_create_current(bmain, scene, ob); + if (ob->mode == OB_MODE_PARTICLE_EDIT) { + PE_create_current(depsgraph, scene, ob); + } } void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra) @@ -331,14 +399,18 @@ static int pe_x_mirror(Object *ob) typedef struct PEData { ViewContext vc; - bglMats mats; + const bContext *context; Main *bmain; Scene *scene; + ViewLayer *view_layer; Object *ob; - DerivedMesh *dm; + Mesh *mesh; PTCacheEdit *edit; BVHTreeFromMesh shape_bvh; + Depsgraph *depsgraph; + + RNG *rng; const int *mval; rcti *rect; @@ -369,9 +441,11 @@ static void PE_set_data(bContext *C, PEData *data) memset(data, 0, sizeof(*data)); data->bmain = CTX_data_main(C); - data->scene= CTX_data_scene(C); - data->ob= CTX_data_active_object(C); - data->edit= PE_get_current(data->bmain, 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->depsgraph = CTX_data_depsgraph(C); + data->edit = PE_get_current(data->scene, data->ob); } static void PE_set_view3d_data(bContext *C, PEData *data) @@ -379,8 +453,6 @@ 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) { @@ -398,15 +470,15 @@ static void PE_set_view3d_data(bContext *C, PEData *data) static bool PE_create_shape_tree(PEData *data, Object *shapeob) { - DerivedMesh *dm = shapeob->derivedFinal; + Mesh *mesh = BKE_object_get_evaluated_mesh(data->depsgraph, shapeob); memset(&data->shape_bvh, 0, sizeof(data->shape_bvh)); - if (!dm) { + if (!mesh) { return false; } - return (bvhtree_from_mesh_get(&data->shape_bvh, dm, BVHTREE_FROM_LOOPTRI, 4) != NULL); + return (BKE_bvhtree_from_mesh_get(&data->shape_bvh, mesh, BVHTREE_FROM_LOOPTRI, 4) != NULL); } static void PE_free_shape_tree(PEData *data) @@ -414,13 +486,28 @@ static void PE_free_shape_tree(PEData *data) free_bvhtree_from_mesh(&data->shape_bvh); } +static void PE_create_random_generator(PEData *data) +{ + uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); + rng_seed ^= GET_UINT_FROM_POINTER(data->ob); + rng_seed ^= GET_UINT_FROM_POINTER(data->edit); + data->rng = BLI_rng_new(rng_seed); +} + +static void PE_free_random_generator(PEData *data) +{ + if (data->rng != NULL) { + BLI_rng_free(data->rng); + data->rng = NULL; + } +} + /*************************** selection utilities *******************************/ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[2]) { View3D *v3d= data->vc.v3d; ViewDepths *vd = data->vc.rv3d->depths; - double ux, uy, uz; float depth; /* nothing to do */ @@ -436,9 +523,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); @@ -448,7 +532,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; @@ -612,61 +699,87 @@ static void foreach_mouse_hit_point(PEData *data, ForPointFunc func, int selecte } } -static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected) +typedef struct KeyIterData { + PEData *data; + PTCacheEdit *edit; + int selected; + ForKeyMatFunc func; +} KeyIterData; + +static void foreach_mouse_hit_key_iter( + void *__restrict iter_data_v, + const int iter, + const ParallelRangeTLS *__restrict UNUSED(tls)) { + KeyIterData *iter_data = (KeyIterData *)iter_data_v; + PEData *data = iter_data->data; PTCacheEdit *edit = data->edit; + PTCacheEditPoint *point = &edit->points[iter]; + if (point->flag & PEP_HIDE) { + return; + } ParticleSystem *psys = edit->psys; - ParticleSystemModifierData *psmd = NULL; - ParticleEditSettings *pset= PE_settings(data->scene); - POINT_P; KEY_K; + ParticleSystemModifierData *psmd_eval = iter_data->edit->psmd_eval; + ParticleEditSettings *pset = PE_settings(data->scene); + const int selected = iter_data->selected; float mat[4][4], imat[4][4]; - unit_m4(mat); unit_m4(imat); - - if (edit->psys) - psmd= psys_get_modifier(data->ob, edit->psys); - - /* all is selected in path mode */ - if (pset->selectmode==SCE_SELECT_PATH) - selected= 0; - - LOOP_VISIBLE_POINTS { - if (pset->selectmode==SCE_SELECT_END) { - if (point->totkey) { - /* only do end keys */ - key= point->keys + point->totkey-1; - - if (selected==0 || key->flag & PEK_SELECT) { - if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { - if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); - invert_m4_m4(imat, mat); - } - - func(data, mat, imat, p, point->totkey-1, key); + if (pset->selectmode==SCE_SELECT_END) { + if (point->totkey) { + /* only do end keys */ + PTCacheEditKey *key = point->keys + point->totkey-1; + + if (selected==0 || key->flag & PEK_SELECT) { + if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { + if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { + psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); + invert_m4_m4(imat, mat); } + iter_data->func(data, mat, imat, iter, point->totkey-1, key); } } } - else { - /* do all keys */ - LOOP_VISIBLE_KEYS { - if (selected==0 || key->flag & PEK_SELECT) { - if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { - if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); - invert_m4_m4(imat, mat); - } - - func(data, mat, imat, p, k, key); + } + else { + /* do all keys */ + PTCacheEditKey *key; + int k; + LOOP_VISIBLE_KEYS { + if (selected==0 || key->flag & PEK_SELECT) { + if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { + if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { + psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); + invert_m4_m4(imat, mat); } + iter_data->func(data, mat, imat, iter, k, key); } } } } } +static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected) +{ + PTCacheEdit *edit = data->edit; + ParticleEditSettings *pset = PE_settings(data->scene); + /* all is selected in path mode */ + if (pset->selectmode == SCE_SELECT_PATH) { + selected = 0; + } + + KeyIterData iter_data; + iter_data.data = data; + iter_data.edit = edit; + iter_data.selected = selected; + iter_data.func = func; + + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC; + BLI_task_parallel_range(0, edit->totpoint, &iter_data, foreach_mouse_hit_key_iter, &settings); +} + static void foreach_selected_point(PEData *data, ForPointFunc func) { PTCacheEdit *edit = data->edit; @@ -730,7 +843,7 @@ static int count_selected_keys(Scene *scene, PTCacheEdit *edit) static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) { PTCacheEdit *edit; - ParticleSystemModifierData *psmd; + ParticleSystemModifierData *psmd_eval; KDTree *tree; KDTreeNearest nearest; HairKey *key; @@ -739,10 +852,10 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) int index, totpart; edit= psys->edit; - psmd= psys_get_modifier(ob, psys); + psmd_eval = edit->psmd_eval; totpart= psys->totpart; - if (!psmd->dm_final) + if (!psmd_eval->mesh_final) return; tree= BLI_kdtree_new(totpart); @@ -750,7 +863,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) /* insert particles into kd tree */ LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); BLI_kdtree_insert(tree, p, co); @@ -764,7 +877,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); co[0] = -co[0]; @@ -790,7 +903,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) BLI_kdtree_free(tree); } -static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa) +static void PE_mirror_particle(Object *ob, Mesh *mesh, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa) { HairKey *hkey, *mhkey; PTCacheEditPoint *point, *mpoint; @@ -841,8 +954,8 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys } /* mirror positions and tags */ - psys_mat_hair_to_orco(ob, dm, psys->part->from, pa, mat); - psys_mat_hair_to_orco(ob, dm, psys->part->from, mpa, mmat); + psys_mat_hair_to_orco(ob, mesh, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, mesh, psys->part->from, mpa, mmat); invert_m4_m4(immat, mmat); hkey=pa->hair; @@ -870,16 +983,16 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys static void PE_apply_mirror(Object *ob, ParticleSystem *psys) { PTCacheEdit *edit; - ParticleSystemModifierData *psmd; + ParticleSystemModifierData *psmd_eval; POINT_P; if (!psys) return; edit= psys->edit; - psmd= psys_get_modifier(ob, psys); + psmd_eval= edit->psmd_eval; - if (!psmd->dm_final) + if (!psmd_eval->mesh_final) return; if (!edit->mirror_cache) @@ -892,7 +1005,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) * to avoid doing mirror twice */ LOOP_POINTS { if (point->flag & PEP_EDIT_RECALC) { - PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); if (edit->mirror_cache[p] != -1) edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC; @@ -909,110 +1022,152 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) /************************************************/ /* Edit Calculation */ /************************************************/ -/* tries to stop edited particles from going through the emitter's surface */ -static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) -{ - ParticleEditSettings *pset= PE_settings(scene); + +typedef struct DeflectEmitterIter { + Object *object; ParticleSystem *psys; - ParticleSystemModifierData *psmd; - POINT_P; KEY_K; + PTCacheEdit *edit; + float dist; + float emitterdist; +} DeflectEmitterIter; + +static void deflect_emitter_iter( + void *__restrict iter_data_v, + const int iter, + const ParallelRangeTLS *__restrict UNUSED(tls)) + { + DeflectEmitterIter *iter_data = (DeflectEmitterIter *)iter_data_v; + PTCacheEdit *edit = iter_data->edit; + PTCacheEditPoint *point = &edit->points[iter]; + if ((point->flag & PEP_EDIT_RECALC) == 0) { + return; + } + Object *object = iter_data->object; + ParticleSystem *psys = iter_data->psys; + ParticleSystemModifierData *psmd_eval = iter_data->edit->psmd_eval; + PTCacheEditKey *key; + int k; + float hairimat[4][4], hairmat[4][4]; int index; float *vec, *nor, dvec[3], dot, dist_1st=0.0f; - float hairimat[4][4], hairmat[4][4]; - const float dist = ED_view3d_select_dist_px() * 0.01f; - - if (edit==NULL || edit->psys==NULL || (pset->flag & PE_DEFLECT_EMITTER)==0 || (edit->psys->flag & PSYS_GLOBAL_HAIR)) - return; - - psys = edit->psys; - psmd = psys_get_modifier(ob, psys); - - if (!psmd->dm_final) - return; + const float dist = iter_data->dist; + const float emitterdist = iter_data->emitterdist; + psys_mat_hair_to_object(object, + psmd_eval->mesh_final, + psys->part->from, + psys->particles + iter, + hairmat); - LOOP_EDITED_POINTS { - psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles + p, hairmat); + LOOP_KEYS { + mul_m4_v3(hairmat, key->co); + } - LOOP_KEYS { - mul_m4_v3(hairmat, key->co); + LOOP_KEYS { + if (k == 0) { + dist_1st = len_v3v3((key + 1)->co, key->co); + dist_1st *= dist * emitterdist; } + else { + index = BLI_kdtree_find_nearest(edit->emitter_field, key->co, NULL); - LOOP_KEYS { - if (k==0) { - dist_1st = len_v3v3((key+1)->co, key->co); - dist_1st *= dist * pset->emitterdist; - } - else { - index= BLI_kdtree_find_nearest(edit->emitter_field, key->co, NULL); - - vec=edit->emitter_cosnos +index*6; - nor=vec+3; + vec = edit->emitter_cosnos + index * 6; + nor = vec + 3; - sub_v3_v3v3(dvec, key->co, vec); + sub_v3_v3v3(dvec, key->co, vec); - dot=dot_v3v3(dvec, nor); - copy_v3_v3(dvec, nor); + dot = dot_v3v3(dvec, nor); + copy_v3_v3(dvec, nor); - if (dot>0.0f) { - if (dot<dist_1st) { - normalize_v3(dvec); - mul_v3_fl(dvec, dist_1st-dot); - add_v3_v3(key->co, dvec); - } - } - else { + if (dot > 0.0f) { + if (dot < dist_1st) { normalize_v3(dvec); - mul_v3_fl(dvec, dist_1st-dot); + mul_v3_fl(dvec, dist_1st - dot); add_v3_v3(key->co, dvec); } - if (k==1) - dist_1st*=1.3333f; + } + else { + normalize_v3(dvec); + mul_v3_fl(dvec, dist_1st - dot); + add_v3_v3(key->co, dvec); + } + if (k == 1) { + dist_1st *= 1.3333f; } } + } - invert_m4_m4(hairimat, hairmat); + invert_m4_m4(hairimat, hairmat); - LOOP_KEYS { - mul_m4_v3(hairimat, key->co); - } + LOOP_KEYS { + mul_m4_v3(hairimat, key->co); } } -/* force set distances between neighboring keys */ -static void PE_apply_lengths(Scene *scene, PTCacheEdit *edit) -{ - ParticleEditSettings *pset=PE_settings(scene); - POINT_P; KEY_K; - float dv1[3]; +/* tries to stop edited particles from going through the emitter's surface */ +static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) +{ + ParticleEditSettings *pset = PE_settings(scene); + ParticleSystem *psys; + const float dist = ED_view3d_select_dist_px() * 0.01f; - if (edit==0 || (pset->flag & PE_KEEP_LENGTHS)==0) + if (edit == NULL || edit->psys == NULL || + (pset->flag & PE_DEFLECT_EMITTER) == 0 || + (edit->psys->flag & PSYS_GLOBAL_HAIR)) + { return; + } - if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) + psys = edit->psys; + + if (!edit->psmd_eval->mesh_final) { return; + } - LOOP_EDITED_POINTS { - LOOP_KEYS { - if (k) { - sub_v3_v3v3(dv1, key->co, (key - 1)->co); - normalize_v3(dv1); - mul_v3_fl(dv1, (key - 1)->length); - add_v3_v3v3(key->co, (key - 1)->co, dv1); - } + DeflectEmitterIter iter_data; + iter_data.object = ob; + iter_data.psys = psys; + iter_data.edit = edit; + iter_data.dist = dist; + iter_data.emitterdist = pset->emitterdist; + + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC; + BLI_task_parallel_range(0, edit->totpoint, &iter_data, deflect_emitter_iter, &settings); +} + +typedef struct ApplyLengthsIterData { + PTCacheEdit *edit; +} ApplyLengthsIterData; + +static void apply_lengths_iter( + void *__restrict iter_data_v, + const int iter, + const ParallelRangeTLS *__restrict UNUSED(tls)) + { + ApplyLengthsIterData *iter_data = (ApplyLengthsIterData *)iter_data_v; + PTCacheEdit *edit = iter_data->edit; + PTCacheEditPoint *point = &edit->points[iter]; + if ((point->flag & PEP_EDIT_RECALC) == 0) { + return; + } + PTCacheEditKey *key; + int k; + LOOP_KEYS { + if (k) { + float dv1[3]; + sub_v3_v3v3(dv1, key->co, (key - 1)->co); + normalize_v3(dv1); + mul_v3_fl(dv1, (key - 1)->length); + add_v3_v3v3(key->co, (key - 1)->co, dv1); } } } -/* try to find a nice solution to keep distances between neighboring keys */ -static void pe_iterate_lengths(Scene *scene, PTCacheEdit *edit) + +/* force set distances between neighboring keys */ +static void PE_apply_lengths(Scene *scene, PTCacheEdit *edit) { ParticleEditSettings *pset=PE_settings(scene); - POINT_P; - PTCacheEditKey *key; - int j, k; - float tlen; - float dv0[3] = {0.0f, 0.0f, 0.0f}; - float dv1[3] = {0.0f, 0.0f, 0.0f}; - float dv2[3] = {0.0f, 0.0f, 0.0f}; if (edit==0 || (pset->flag & PE_KEEP_LENGTHS)==0) return; @@ -1020,43 +1175,91 @@ static void pe_iterate_lengths(Scene *scene, PTCacheEdit *edit) if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) return; - LOOP_EDITED_POINTS { - for (j=1; j<point->totkey; j++) { - float mul= 1.0f / (float)point->totkey; - - if (pset->flag & PE_LOCK_FIRST) { - key= point->keys + 1; - k= 1; - dv1[0] = dv1[1] = dv1[2] = 0.0; - } - else { - key= point->keys; - k= 0; - dv0[0] = dv0[1] = dv0[2] = 0.0; - } - - for (; k<point->totkey; k++, key++) { - if (k) { - sub_v3_v3v3(dv0, (key - 1)->co, key->co); - tlen= normalize_v3(dv0); - mul_v3_fl(dv0, (mul * (tlen - (key - 1)->length))); - } + ApplyLengthsIterData iter_data; + iter_data.edit = edit; - if (k < point->totkey - 1) { - sub_v3_v3v3(dv2, (key + 1)->co, key->co); - tlen= normalize_v3(dv2); - mul_v3_fl(dv2, mul * (tlen - key->length)); - } + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC; + BLI_task_parallel_range(0, edit->totpoint, &iter_data, apply_lengths_iter, &settings); +} - if (k) { - add_v3_v3((key-1)->co, dv1); - } +typedef struct IterateLengthsIterData { + PTCacheEdit *edit; + ParticleEditSettings *pset; +} IterateLengthsIterData; + +static void iterate_lengths_iter( + void *__restrict iter_data_v, + const int iter, + const ParallelRangeTLS *__restrict UNUSED(tls)) +{ + IterateLengthsIterData *iter_data = (IterateLengthsIterData *)iter_data_v; + PTCacheEdit *edit = iter_data->edit; + PTCacheEditPoint *point = &edit->points[iter]; + if ((point->flag & PEP_EDIT_RECALC) == 0) { + return; + } + ParticleEditSettings *pset = iter_data->pset; + float tlen; + float dv0[3] = {0.0f, 0.0f, 0.0f}; + float dv1[3] = {0.0f, 0.0f, 0.0f}; + float dv2[3] = {0.0f, 0.0f, 0.0f}; + for (int j = 1; j < point->totkey; j++) { + PTCacheEditKey *key; + int k; + float mul = 1.0f / (float)point->totkey; + if (pset->flag & PE_LOCK_FIRST) { + key = point->keys + 1; + k = 1; + dv1[0] = dv1[1] = dv1[2] = 0.0; + } + else { + key = point->keys; + k = 0; + dv0[0] = dv0[1] = dv0[2] = 0.0; + } - add_v3_v3v3(dv1, dv0, dv2); + for (; k < point->totkey; k++, key++) { + if (k) { + sub_v3_v3v3(dv0, (key - 1)->co, key->co); + tlen = normalize_v3(dv0); + mul_v3_fl(dv0, (mul * (tlen - (key - 1)->length))); + } + if (k < point->totkey - 1) { + sub_v3_v3v3(dv2, (key + 1)->co, key->co); + tlen = normalize_v3(dv2); + mul_v3_fl(dv2, mul * (tlen - key->length)); } + if (k) { + add_v3_v3((key-1)->co, dv1); + } + add_v3_v3v3(dv1, dv0, dv2); } } } + +/* try to find a nice solution to keep distances between neighboring keys */ +static void pe_iterate_lengths(Scene *scene, PTCacheEdit *edit) +{ + ParticleEditSettings *pset = PE_settings(scene); + if (edit==0 || (pset->flag & PE_KEEP_LENGTHS)==0) { + return; + } + if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) { + return; + } + + IterateLengthsIterData iter_data; + iter_data.edit = edit; + iter_data.pset = pset; + + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC; + BLI_task_parallel_range(0, edit->totpoint, &iter_data, iterate_lengths_iter, &settings); +} + /* set current distances to be kept between neighbouting keys */ void recalc_lengths(PTCacheEdit *edit) { @@ -1074,14 +1277,14 @@ void recalc_lengths(PTCacheEdit *edit) } /* calculate a tree for finding nearest emitter's vertice */ -void recalc_emitter_field(Object *ob, ParticleSystem *psys) +void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), ParticleSystem *psys) { - DerivedMesh *dm=psys_get_modifier(ob, psys)->dm_final; - PTCacheEdit *edit= psys->edit; + PTCacheEdit *edit = psys->edit; + Mesh *mesh = edit->psmd_eval->mesh_final; float *vec, *nor; int i, totface /*, totvert*/; - if (!dm) + if (!mesh) return; if (edit->emitter_cosnos) @@ -1089,7 +1292,7 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys) BLI_kdtree_free(edit->emitter_field); - totface=dm->getNumTessFaces(dm); + totface = mesh->totface; /*totvert=dm->getNumVerts(dm);*/ /*UNSUED*/ edit->emitter_cosnos=MEM_callocN(totface*6*sizeof(float), "emitter cosnos"); @@ -1100,23 +1303,23 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys) nor=vec+3; for (i=0; i<totface; i++, vec+=6, nor+=6) { - MFace *mface=dm->getTessFaceData(dm, i, CD_MFACE); + MFace *mface = &mesh->mface[i]; MVert *mvert; - mvert=dm->getVertData(dm, mface->v1, CD_MVERT); + mvert = &mesh->mvert[mface->v1]; copy_v3_v3(vec, mvert->co); VECCOPY(nor, mvert->no); - mvert=dm->getVertData(dm, mface->v2, CD_MVERT); + mvert = &mesh->mvert[mface->v2]; add_v3_v3v3(vec, vec, mvert->co); VECADD(nor, nor, mvert->no); - mvert=dm->getVertData(dm, mface->v3, CD_MVERT); + mvert = &mesh->mvert[mface->v3]; add_v3_v3v3(vec, vec, mvert->co); VECADD(nor, nor, mvert->no); if (mface->v4) { - mvert=dm->getVertData(dm, mface->v4, CD_MVERT); + mvert = &mesh->mvert[mface->v4]; add_v3_v3v3(vec, vec, mvert->co); VECADD(nor, nor, mvert->no); @@ -1133,9 +1336,9 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys) BLI_kdtree_balance(edit->emitter_field); } -static void PE_update_selection(Main *bmain, Scene *scene, Object *ob, int useflag) +static void PE_update_selection(Depsgraph *depsgraph, Scene *scene, Object *ob, int useflag) { - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit = PE_get_current(scene, ob); HairKey *hkey; POINT_P; KEY_K; @@ -1154,27 +1357,29 @@ static void PE_update_selection(Main *bmain, Scene *scene, Object *ob, int usefl } } - psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering); + psys_cache_edit_paths(depsgraph, scene, ob, edit, CFRA, G.is_rendering); /* disable update flag */ LOOP_POINTS point->flag &= ~PEP_EDIT_RECALC; + + DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE); } -void update_world_cos(Object *ob, PTCacheEdit *edit) +void update_world_cos(Depsgraph *UNUSED(depsgraph), Object *ob, PTCacheEdit *edit) { ParticleSystem *psys = edit->psys; - ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys); + ParticleSystemModifierData *psmd_eval = edit->psmd_eval; POINT_P; KEY_K; float hairmat[4][4]; - if (psys==0 || psys->edit==0 || psmd->dm_final==NULL) + if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL) return; LOOP_POINTS { if (!(psys->flag & PSYS_GLOBAL_HAIR)) - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, hairmat); + psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, psys->particles+p, hairmat); LOOP_KEYS { copy_v3_v3(key->world_co, key->co); @@ -1240,12 +1445,12 @@ static void update_velocities(PTCacheEdit *edit) } } -void PE_update_object(Main *bmain, Scene *scene, Object *ob, int useflag) +void PE_update_object(Depsgraph *depsgraph, Scene *scene, 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(bmain, scene, ob); + PTCacheEdit *edit = PE_get_current(scene, ob); POINT_P; if (!edit) @@ -1264,13 +1469,13 @@ void PE_update_object(Main *bmain, Scene *scene, Object *ob, int useflag) if (pe_x_mirror(ob)) PE_apply_mirror(ob, edit->psys); if (edit->psys) - update_world_cos(ob, edit); + update_world_cos(depsgraph, ob, edit); if (pset->flag & PE_AUTO_VELOCITY) update_velocities(edit); 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(depsgraph, scene, ob, edit, CFRA, G.is_rendering); /* disable update flag */ LOOP_POINTS { @@ -1379,10 +1584,10 @@ static void select_action_apply(PTCacheEditPoint *point, PTCacheEditKey *key, in static int pe_select_all_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); POINT_P; KEY_K; int action = RNA_enum_get(op->ptr, "action"); @@ -1405,7 +1610,7 @@ static int pe_select_all_exec(bContext *C, wmOperator *op) } } - PE_update_selection(bmain, scene, ob, 1); + PE_update_selection(depsgraph, scene, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1432,11 +1637,10 @@ void PARTICLE_OT_select_all(wmOperatorType *ot) int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) { - Main *bmain = CTX_data_main(C); PEData data; Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); POINT_P; KEY_K; if (!PE_start_edit(edit)) @@ -1463,7 +1667,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(bmain, scene, ob, 1); + PE_update_selection(data.depsgraph, scene, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1504,7 +1708,7 @@ static int select_roots_exec(bContext *C, wmOperator *op) data.select_action = action; foreach_point(&data, select_root); - PE_update_selection(data.bmain, data.scene, data.ob, 1); + PE_update_selection(data.depsgraph, data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1569,7 +1773,7 @@ static int select_tips_exec(bContext *C, wmOperator *op) data.select_action = action; foreach_point(&data, select_tip); - PE_update_selection(data.bmain, data.scene, data.ob, 1); + PE_update_selection(data.depsgraph, data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1624,7 +1828,7 @@ static int select_random_exec(bContext *C, wmOperator *op) PE_set_data(C, &data); data.select_action = SEL_SELECT; - edit = PE_get_current(data.bmain, data.scene, data.ob); + edit = PE_get_current(data.scene, data.ob); rng = BLI_rng_new_srandom(seed); @@ -1649,7 +1853,7 @@ static int select_random_exec(bContext *C, wmOperator *op) BLI_rng_free(rng); - PE_update_selection(data.bmain, data.scene, data.ob, 1); + PE_update_selection(data.depsgraph, data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1693,7 +1897,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.bmain, data.scene, data.ob, 1); + PE_update_selection(data.depsgraph, data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -1740,10 +1944,9 @@ void PE_deselect_all_visible(PTCacheEdit *edit) int PE_border_select(bContext *C, rcti *rect, bool select, bool extend) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); PEData data; if (!PE_start_edit(edit)) @@ -1758,7 +1961,7 @@ int PE_border_select(bContext *C, rcti *rect, bool select, bool extend) for_mouse_hit_keys(&data, select_key, 0); - PE_update_selection(bmain, scene, ob, 1); + PE_update_selection(data.depsgraph, scene, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1768,10 +1971,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) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); PEData data; if (!PE_start_edit(edit)) @@ -1784,7 +1986,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(bmain, scene, ob, 1); + PE_update_selection(data.depsgraph, scene, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1794,14 +1996,13 @@ 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) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); ARegion *ar= CTX_wm_region(C); ParticleEditSettings *pset= PE_settings(scene); - PTCacheEdit *edit = PE_get_current(bmain, scene, ob); + PTCacheEdit *edit = PE_get_current(scene, ob); ParticleSystem *psys = edit->psys; - ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); + ParticleSystemModifierData *psmd_eval = edit->psmd_eval; POINT_P; KEY_K; float co[3], mat[4][4]; int screen_co[2]; @@ -1821,7 +2022,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool LOOP_VISIBLE_POINTS { if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR)) - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); if (pset->selectmode==SCE_SELECT_POINT) { LOOP_KEYS { @@ -1873,7 +2074,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool } } - PE_update_selection(bmain, scene, ob, 1); + PE_update_selection(data.depsgraph, scene, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1883,12 +2084,14 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool static int hide_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Object *ob= CTX_data_active_object(C); Scene *scene= CTX_data_scene(C); - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + + PTCacheEdit *edit= PE_get_current(scene, ob); POINT_P; KEY_K; + if (RNA_enum_get(op->ptr, "unselected")) { LOOP_UNSELECTED_POINTS { point->flag |= PEP_HIDE; @@ -1908,7 +2111,7 @@ static int hide_exec(bContext *C, wmOperator *op) } } - PE_update_selection(bmain, scene, ob, 1); + PE_update_selection(depsgraph, scene, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -1936,10 +2139,10 @@ void PARTICLE_OT_hide(wmOperatorType *ot) static int reveal_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Object *ob= CTX_data_active_object(C); Scene *scene= CTX_data_scene(C); - PTCacheEdit *edit = PE_get_current(bmain, scene, ob); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + PTCacheEdit *edit= PE_get_current(scene, ob); const bool select = RNA_boolean_get(op->ptr, "select"); POINT_P; KEY_K; @@ -1954,7 +2157,7 @@ static int reveal_exec(bContext *C, wmOperator *op) } } - PE_update_selection(bmain, scene, ob, 1); + PE_update_selection(depsgraph, scene, ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob); return OPERATOR_FINISHED; @@ -2016,7 +2219,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.bmain, data.scene, data.ob, 1); + PE_update_selection(data.depsgraph, data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -2078,7 +2281,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.bmain, data.scene, data.ob, 1); + PE_update_selection(data.depsgraph, data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); return OPERATOR_FINISHED; @@ -2114,9 +2317,10 @@ static void rekey_particle(PEData *data, int pa_index) float dval, sta, end; int k; - sim.scene= data->scene; - sim.ob= data->ob; - sim.psys= edit->psys; + sim.depsgraph = data->depsgraph; + sim.scene = data->scene; + sim.ob = data->ob; + sim.psys = edit->psys; pa->flag |= PARS_REKEY; @@ -2175,7 +2379,7 @@ static int rekey_exec(bContext *C, wmOperator *op) foreach_selected_point(&data, rekey_particle); recalc_lengths(data.edit); - PE_update_object(data.bmain, data.scene, data.ob, 1); + PE_update_object(data.depsgraph, data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob); return OPERATOR_FINISHED; @@ -2200,11 +2404,11 @@ 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(Main *bmain, Scene *scene, Object *ob, int pa_index, float path_time) +static void rekey_particle_to_time(const bContext *C, Scene *scene, Object *ob, int pa_index, float path_time) { - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); ParticleSystem *psys; - ParticleSimulationData sim= {0}; + ParticleSimulationData sim = {0}; ParticleData *pa; ParticleKey state; HairKey *new_keys, *key; @@ -2215,9 +2419,10 @@ static void rekey_particle_to_time(Main *bmain, Scene *scene, Object *ob, int pa psys = edit->psys; - sim.scene= scene; - sim.ob= ob; - sim.psys= psys; + sim.depsgraph = CTX_data_depsgraph(C); + sim.scene = scene; + sim.ob = ob; + sim.psys = psys; pa= psys->particles + pa_index; @@ -2254,15 +2459,15 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror) ParticleData *pa, *npa=0, *new_pars=0; POINT_P; PTCacheEditPoint *npoint=0, *new_points=0; - ParticleSystemModifierData *psmd; + ParticleSystemModifierData *psmd_eval; int i, new_totpart= psys->totpart, removed= 0; if (mirror) { /* mirror tags */ - psmd= psys_get_modifier(ob, psys); + psmd_eval = edit->psmd_eval; LOOP_TAGGED_POINTS { - PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); } } @@ -2333,16 +2538,16 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys) HairKey *hkey, *nhkey, *new_hkeys=0; POINT_P; KEY_K; PTCacheEditKey *nkey, *new_keys; - ParticleSystemModifierData *psmd; + ParticleSystemModifierData *psmd_eval; short new_totkey; if (pe_x_mirror(ob)) { /* mirror key tags */ - psmd= psys_get_modifier(ob, psys); + psmd_eval = psys_get_modifier(ob, psys); LOOP_POINTS { LOOP_TAGGED_KEYS { - PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); break; } } @@ -2432,9 +2637,10 @@ static void subdivide_particle(PEData *data, int pa_index) short totnewkey=0; float endtime; - sim.scene= data->scene; - sim.ob= data->ob; - sim.psys= edit->psys; + sim.depsgraph = data->depsgraph; + 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) @@ -2506,7 +2712,7 @@ static int subdivide_exec(bContext *C, wmOperator *UNUSED(op)) foreach_point(&data, subdivide_particle); recalc_lengths(data.edit); - PE_update_object(data.bmain, data.scene, data.ob, 1); + PE_update_object(data.depsgraph, data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob); return OPERATOR_FINISHED; @@ -2531,12 +2737,11 @@ void PARTICLE_OT_subdivide(wmOperatorType *ot) static int remove_doubles_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); ParticleSystem *psys = edit->psys; - ParticleSystemModifierData *psmd; + ParticleSystemModifierData *psmd_eval; KDTree *tree; KDTreeNearest nearest[10]; POINT_P; @@ -2547,7 +2752,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; edit= psys->edit; - psmd= psys_get_modifier(ob, psys); + psmd_eval = edit->psmd_eval; totremoved= 0; do { @@ -2557,7 +2762,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* insert particles into kd tree */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_object(ob, psmd_eval->mesh_final, psys->part->from, psys->particles+p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); BLI_kdtree_insert(tree, p, co); @@ -2567,7 +2772,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* tag particles to be removed */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_object(ob, psmd_eval->mesh_final, psys->part->from, psys->particles+p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); @@ -2596,7 +2801,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; @@ -2624,11 +2829,10 @@ void PARTICLE_OT_remove_doubles(wmOperatorType *ot) static int weight_set_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); ParticleEditSettings *pset= PE_settings(scene); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); ParticleSystem *psys = edit->psys; POINT_P; KEY_K; @@ -2649,7 +2853,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; @@ -2681,24 +2885,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); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + GPU_line_smooth(true); + GPU_blend(true); - glPopMatrix(); + imm_draw_circle_wire_2d(pos, (float)x, (float)y, pe_brush_size_get(scene, brush), 40); + + GPU_blend(false); + GPU_line_smooth(false); + + immUnbindProgram(); } } @@ -2755,7 +2962,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; @@ -2782,11 +2989,12 @@ void PARTICLE_OT_delete(wmOperatorType *ot) /*************************** mirror operator **************************/ -static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged) +static void PE_mirror_x( + Scene *scene, Object *ob, int tagged) { Mesh *me= (Mesh *)(ob->data); - ParticleSystemModifierData *psmd; - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + ParticleSystemModifierData *psmd_eval; + PTCacheEdit *edit = PE_get_current(scene, ob); ParticleSystem *psys = edit->psys; ParticleData *pa, *newpa, *new_pars; PTCacheEditPoint *newpoint, *new_points; @@ -2798,18 +3006,18 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged) if (psys->flag & PSYS_GLOBAL_HAIR) return; - psmd= psys_get_modifier(ob, psys); - if (!psmd->dm_final) + psmd_eval = edit->psmd_eval; + if (!psmd_eval->mesh_final) return; - const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly); + const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd_eval->mesh_final->runtime.deformed_only); /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */ BKE_mesh_tessface_ensure(me); - /* Note: In case psys uses DM tessface indices, we mirror final DM itself, not orig mesh. Avoids an (impossible) - * dm -> orig -> dm tessface indices conversion... */ - mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? psmd->dm_final : NULL); + /* Note: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. Avoids an (impossible) + * mesh -> orig -> mesh tessface indices conversion... */ + mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL); if (!edit->mirror_cache) PE_update_mirror_cache(ob, psys); @@ -2823,7 +3031,7 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged) if (point_is_selected(point)) { if (edit->mirror_cache[p] != -1) { /* already has a mirror, don't need to duplicate */ - PE_mirror_particle(ob, psmd->dm_final, psys, pa, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, NULL); continue; } else @@ -2836,7 +3044,7 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged) } if (newtotpart != psys->totpart) { - MFace *mtessface = use_dm_final_indices ? psmd->dm_final->getTessFaceArray(psmd->dm_final) : me->mface; + MFace *mtessface = use_dm_final_indices ? psmd_eval->mesh_final->mface : me->mface; /* allocate new arrays and copy existing */ new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new"); @@ -2905,7 +3113,7 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged) } else { newpa->num_dmcache = psys_particle_dm_face_lookup( - psmd->dm_final, psmd->dm_deformed, newpa->num, newpa->fuv, NULL); + psmd_eval->mesh_final, psmd_eval->mesh_original, newpa->num, newpa->fuv, NULL); } /* update edit key pointers */ @@ -2916,7 +3124,7 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged) } /* map key positions as mirror over x axis */ - PE_mirror_particle(ob, psmd->dm_final, psys, pa, newpa); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, newpa); newpa++; newpoint++; @@ -2932,16 +3140,15 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged) static int mirror_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); - PE_mirror_x(bmain, scene, ob, 0); + PE_mirror_x(scene, ob, 0); - update_world_cos(ob, edit); + update_world_cos(CTX_data_depsgraph(C), 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; } @@ -2992,8 +3199,11 @@ static void brush_cut(PEData *data, int pa_index) int k, cut, keys= (int)pow(2.0, (double)pset->draw_step); int screen_co[2]; + BLI_assert(data->rng != NULL); /* blunt scissors */ - if (BLI_frand() > data->cutfac) return; + if (BLI_rng_get_float(data->rng) > data->cutfac) { + return; + } /* don't cut hidden */ if (edit->points[pa_index].flag & PEP_HIDE) @@ -3074,7 +3284,7 @@ static void brush_cut(PEData *data, int pa_index) edit->points[pa_index].flag |= PEP_TAG; } else { - rekey_particle_to_time(data->bmain, data->scene, ob, pa_index, cut_time); + rekey_particle_to_time(data->context, data->scene, ob, pa_index, cut_time); edit->points[pa_index].flag |= PEP_EDIT_RECALC; } } @@ -3127,7 +3337,7 @@ static void brush_puff(PEData *data, int point_index) } if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, psys->particles + point_index, mat); + psys_mat_hair_to_global(data->ob, data->mesh, psys->part->from, psys->particles + point_index, mat); invert_m4_m4(imat, mat); } else { @@ -3321,13 +3531,13 @@ static void intersect_dm_quad_weights(const float v1[3], const float v2[3], cons interp_weights_poly_v3(w, vert, 4, co); } -/* check intersection with a derivedmesh */ -static int particle_intersect_dm(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) +/** Check intersection with an evaluated mesh. */ +static int particle_intersect_mesh(Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh, + 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) { MFace *mface= NULL; MVert *mvert= NULL; @@ -3335,21 +3545,23 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, 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]; - if (dm == NULL) { + if (mesh == NULL) { psys_disable_all(ob); - dm=mesh_get_derived_final(scene, ob, 0); - if (dm == NULL) - dm=mesh_get_derived_deform(scene, ob, 0); + mesh = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH); + if (mesh == NULL) { + mesh = mesh_get_eval_deform(depsgraph, scene, ob, CD_MASK_BAREMESH); + } psys_enable_all(ob); - if (dm == NULL) + if (mesh == NULL) { return 0; + } } /* BMESH_ONLY, deform dm may not have tessface */ - DM_ensure_tessface(dm); + BKE_mesh_tessface_ensure(mesh); if (pa_minmax==0) { @@ -3362,9 +3574,9 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, copy_v3_v3(p_max, pa_minmax+3); } - totface=dm->getNumTessFaces(dm); - mface=dm->getTessFaceDataArray(dm, CD_MFACE); - mvert=dm->getVertDataArray(dm, CD_MVERT); + totface = mesh->totface; + mface = mesh->mface; + mvert = mesh->mvert; /* lets intersect the faces */ for (i=0; i<totface; i++, mface++) { @@ -3453,24 +3665,125 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, return intersect; } -static int brush_add(PEData *data, short number) +typedef struct BrushAddCountIterData { + Depsgraph *depsgraph; + Scene *scene; + Object *object; + Mesh *mesh; + PEData *data; + int number; + short size; + float imat[4][4]; + ParticleData *add_pars; + int num_added; +} BrushAddCountIterData; + +typedef struct BrushAddCountIterTLSData { + RNG *rng; + int num_added; +} BrushAddCountIterTLSData; + +static void brush_add_count_iter( + void *__restrict iter_data_v, + const int iter, + const ParallelRangeTLS *__restrict tls_v) { + BrushAddCountIterData *iter_data = (BrushAddCountIterData *)iter_data_v; + Depsgraph *depsgraph = iter_data->depsgraph; + PEData *data = iter_data->data; + PTCacheEdit *edit = data->edit; + ParticleSystem *psys = edit->psys; + ParticleSystemModifierData *psmd_eval = edit->psmd_eval; + ParticleData *add_pars = iter_data->add_pars; + BrushAddCountIterTLSData *tls = tls_v->userdata_chunk; + const int number = iter_data->number; + const short size = iter_data->size; + const short size2 = size*size; + float dmx, dmy; + if (number > 1) { + dmx = size; + dmy = size; + if (tls->rng == NULL) { + tls->rng = BLI_rng_new_srandom( + psys->seed + data->mval[0] + data->mval[1] + tls_v->thread_id); + } + /* rejection sampling to get points in circle */ + while (dmx*dmx + dmy*dmy > size2) { + dmx = (2.0f*BLI_rng_get_float(tls->rng) - 1.0f)*size; + dmy = (2.0f*BLI_rng_get_float(tls->rng) - 1.0f)*size; + } + } + else { + dmx = 0.0f; + dmy = 0.0f; + } + + float mco[2]; + mco[0] = data->mval[0] + dmx; + mco[1] = data->mval[1] + dmy; + + float co1[3], co2[3]; + ED_view3d_win_to_segment(depsgraph, data->vc.ar, data->vc.v3d, mco, co1, co2, true); + + mul_m4_v3(iter_data->imat, co1); + mul_m4_v3(iter_data->imat, co2); + float min_d = 2.0; + + /* warning, returns the derived mesh face */ + BLI_assert(iter_data->mesh != NULL); + if (particle_intersect_mesh(depsgraph, iter_data->scene, iter_data->object, iter_data->mesh, + 0, co1, co2, + &min_d, + &add_pars[iter].num_dmcache, + add_pars[iter].fuv, + 0, 0, 0, 0)) { + if (psys->part->use_modifier_stack && !psmd_eval->mesh_final->runtime.deformed_only) { + add_pars[iter].num = add_pars[iter].num_dmcache; + add_pars[iter].num_dmcache = DMCACHE_ISCHILD; + } + else if (iter_data->mesh == psmd_eval->mesh_original) { + /* Final DM is not same topology as orig mesh, we have to map num_dmcache to real final dm. */ + add_pars[iter].num = add_pars[iter].num_dmcache; + add_pars[iter].num_dmcache = psys_particle_dm_face_lookup( + psmd_eval->mesh_final, psmd_eval->mesh_original, + add_pars[iter].num, add_pars[iter].fuv, NULL); + } + else { + add_pars[iter].num = add_pars[iter].num_dmcache; + } + if (add_pars[iter].num != DMCACHE_NOTFOUND) { + tls->num_added++; + } + } +} + +static void brush_add_count_iter_finalize(void *__restrict userdata_v, + void *__restrict userdata_chunk_v) +{ + BrushAddCountIterData *iter_data = (BrushAddCountIterData *)userdata_v; + BrushAddCountIterTLSData *tls = (BrushAddCountIterTLSData *)userdata_chunk_v; + iter_data->num_added += tls->num_added; + if (tls->rng != NULL) { + BLI_rng_free(tls->rng); + } +} + +static int brush_add(const bContext *C, PEData *data, short number) +{ + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene= data->scene; Object *ob= data->ob; - DerivedMesh *dm; + Mesh *mesh; PTCacheEdit *edit = data->edit; ParticleSystem *psys= edit->psys; ParticleData *add_pars; - ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys); + ParticleSystemModifierData *psmd_eval = edit->psmd_eval; ParticleSimulationData sim= {0}; ParticleEditSettings *pset= PE_settings(scene); int i, k, n= 0, totpart= psys->totpart; - float mco[2]; - float dmx, dmy; - float co1[3], co2[3], min_d, imat[4][4]; + float co1[3], imat[4][4]; float framestep, timestep; short size= pset->brush[PE_BRUSH_ADD].size; - short size2= size*size; RNG *rng; invert_m4_m4(imat, ob->obmat); @@ -3482,67 +3795,66 @@ static int brush_add(PEData *data, short number) rng = BLI_rng_new_srandom(psys->seed+data->mval[0]+data->mval[1]); - sim.scene= scene; - sim.ob= ob; - sim.psys= psys; - sim.psmd= psmd; + sim.depsgraph = depsgraph; + sim.scene = scene; + sim.ob = ob; + sim.psys = psys; + sim.psmd = psmd_eval; - timestep= psys_get_timestep(&sim); + timestep = psys_get_timestep(&sim); - if (psys->part->use_modifier_stack || psmd->dm_final->deformedOnly) { - dm = psmd->dm_final; + if (psys->part->use_modifier_stack || psmd_eval->mesh_final->runtime.deformed_only) { + mesh = psmd_eval->mesh_final; } else { - dm = psmd->dm_deformed; + mesh = psmd_eval->mesh_original; } - BLI_assert(dm); - - for (i=0; i<number; i++) { - if (number>1) { - dmx = size; - dmy = size; - - /* rejection sampling to get points in circle */ - while (dmx*dmx + dmy*dmy > size2) { - dmx= (2.0f*BLI_rng_get_float(rng) - 1.0f)*size; - dmy= (2.0f*BLI_rng_get_float(rng) - 1.0f)*size; - } + BLI_assert(mesh); + + /* Calculate positions of new particles to add, based on brush interseciton + * with object. New particle data is assigned to a correponding to check + * index element of add_pars array. This means, that add_pars is a sparse + * array. + */ + BrushAddCountIterData iter_data; + iter_data.depsgraph = depsgraph; + iter_data.scene = scene; + iter_data.object = ob; + iter_data.mesh = mesh; + iter_data.data = data; + iter_data.number = number; + iter_data.size = size; + iter_data.add_pars = add_pars; + iter_data.num_added = 0; + copy_m4_m4(iter_data.imat, imat); + + BrushAddCountIterTLSData tls = {NULL}; + + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.scheduling_mode = TASK_SCHEDULING_DYNAMIC; + settings.userdata_chunk = &tls; + settings.userdata_chunk_size = sizeof(BrushAddCountIterTLSData); + settings.func_finalize = brush_add_count_iter_finalize; + BLI_task_parallel_range(0, number, &iter_data, brush_add_count_iter, &settings); + + /* Convert add_parse to a dense array, where all new particles are in the + * beginnign of the array. + */ + n = iter_data.num_added; + for (int current_iter = 0, new_index = 0; current_iter < number; current_iter++) { + if (add_pars[current_iter].num == DMCACHE_NOTFOUND) { + continue; } - else { - dmx = 0.0f; - dmy = 0.0f; - } - - 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); - - 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 (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; - } - else if (dm == psmd->dm_deformed) { - /* Final DM is not same topology as orig mesh, we have to map num_dmcache to real final dm. */ - add_pars[n].num = add_pars[n].num_dmcache; - add_pars[n].num_dmcache = psys_particle_dm_face_lookup( - psmd->dm_final, psmd->dm_deformed, - add_pars[n].num, add_pars[n].fuv, NULL); - } - else { - add_pars[n].num = add_pars[n].num_dmcache; - } - - if (add_pars[n].num != DMCACHE_NOTFOUND) { - n++; - } + if (new_index != current_iter) { + new_index++; + continue; } + memcpy(add_pars + new_index, add_pars + current_iter, sizeof(ParticleData)); + new_index++; } + + /* TODO(sergey): Consider multi-threading this part as well. */ if (n) { int newtotpart=totpart+n; float hairmat[4][4], cur_co[3]; @@ -3573,7 +3885,7 @@ static int brush_add(PEData *data, short number) tree=BLI_kdtree_new(psys->totpart); for (i=0, pa=psys->particles; i<totpart; i++, pa++) { - psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0, 0); + psys_particle_on_dm(psmd_eval->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0); BLI_kdtree_insert(tree, i, cur_co); } @@ -3617,7 +3929,7 @@ static int brush_add(PEData *data, short number) int w, maxw; float maxd, totw=0.0, weight[3]; - psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0, 0); + psys_particle_on_dm(psmd_eval->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0); maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3); maxd= ptn[maxw-1].dist; @@ -3682,7 +3994,7 @@ static int brush_add(PEData *data, short number) } } for (k=0, hkey=pa->hair; k<pset->totaddkey; k++, hkey++) { - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); mul_m4_v3(imat, hkey->co); } @@ -3703,6 +4015,7 @@ static int brush_add(PEData *data, short number) typedef struct BrushEdit { Scene *scene; + ViewLayer *view_layer; Object *ob; PTCacheEdit *edit; @@ -3716,11 +4029,11 @@ typedef struct BrushEdit { static int brush_edit_init(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); 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(bmain, scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); ARegion *ar= CTX_wm_region(C); BrushEdit *bedit; float min[3], max[3]; @@ -3730,7 +4043,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(bmain, scene, min, max); + PE_minmax(scene, view_layer, min, max); mid_v3_v3v3(min, min, max); bedit= MEM_callocN(sizeof(BrushEdit), "BrushEdit"); @@ -3738,6 +4051,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; @@ -3745,19 +4059,20 @@ static int brush_edit_init(bContext *C, wmOperator *op) /* cache view depths and settings for re-use */ PE_set_view3d_data(C, &bedit->data); + PE_create_random_generator(&bedit->data); return 1; } static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) { - Main *bmain = CTX_data_main(C); BrushEdit *bedit= op->customdata; + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene= bedit->scene; Object *ob= bedit->ob; PTCacheEdit *edit= bedit->edit; ParticleEditSettings *pset= PE_settings(scene); - ParticleSystemModifierData *psmd= edit->psys ? psys_get_modifier(ob, edit->psys) : NULL; + ParticleSystemModifierData *psmd_eval = edit->psmd_eval; ParticleBrushData *brush= &pset->brush[pset->brushtype]; ARegion *ar= CTX_wm_region(C); float vec[3], mousef[2]; @@ -3793,7 +4108,8 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (((pset->brushtype == PE_BRUSH_ADD) ? (sqrtf(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first) { - PEData data= bedit->data; + 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); @@ -3871,7 +4187,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_PUFF: { if (edit->psys) { - data.dm= psmd->dm_final; + data.mesh = psmd_eval->mesh_final; data.mval= mval; data.rad= pe_brush_size_get(scene, brush); data.select= selected; @@ -3894,7 +4210,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); @@ -3927,7 +4243,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_WEIGHT: { if (edit->psys) { - data.dm= psmd->dm_final; + data.mesh = psmd_eval->mesh_final; data.mval= mval; data.rad= pe_brush_size_get(scene, brush); @@ -3944,21 +4260,24 @@ 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(bmain, scene, ob, 1); + PE_mirror_x(scene, ob, 1); - update_world_cos(ob, edit); + update_world_cos(depsgraph, 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(depsgraph, scene, ob, 1); } - else - PE_update_object(bmain, scene, ob, 1); } if (edit->psys) { WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); + BKE_particle_batch_cache_dirty(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL); + DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE); } 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); } @@ -3974,6 +4293,7 @@ static void brush_edit_exit(wmOperator *op) { BrushEdit *bedit= op->customdata; + PE_free_random_generator(&bedit->data); MEM_freeN(bedit); } @@ -4169,7 +4489,7 @@ static void shape_cut(PEData *data, int pa_index) edit->points[pa_index].flag |= PEP_TAG; } else { - rekey_particle_to_time(data->bmain, data->scene, ob, pa_index, cut_time); + rekey_particle_to_time(data->context, data->scene, ob, pa_index, cut_time); edit->points[pa_index].flag |= PEP_EDIT_RECALC; } } @@ -4177,11 +4497,11 @@ static void shape_cut(PEData *data, int pa_index) static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); ParticleEditSettings *pset = PE_settings(scene); - PTCacheEdit *edit = PE_get_current(bmain, scene, ob); + PTCacheEdit *edit = PE_get_current(scene, ob); Object *shapeob = pset->shape_object; int selected = count_selected_keys(scene, edit); int lock_root = pset->flag & PE_LOCK_FIRST; @@ -4212,18 +4532,21 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op)) recalc_lengths(edit); if (removed) { - update_world_cos(ob, edit); + update_world_cos(depsgraph, 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(data.depsgraph, scene, ob, 1); } - else - PE_update_object(bmain, scene, ob, 1); if (edit->psys) { WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); + BKE_particle_batch_cache_dirty(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL); + DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE); } 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); } @@ -4252,12 +4575,12 @@ void PARTICLE_OT_shape_cut(wmOperatorType *ot) /************************ utilities ******************************/ -int PE_minmax(Main *bmain, 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(bmain, scene, ob); + Object *ob= OBACT(view_layer); + PTCacheEdit *edit= PE_get_current(scene, ob); ParticleSystem *psys; - ParticleSystemModifierData *psmd = NULL; + ParticleSystemModifierData *psmd_eval = NULL; POINT_P; KEY_K; float co[3], mat[4][4]; int ok= 0; @@ -4265,13 +4588,13 @@ int PE_minmax(Main *bmain, Scene *scene, float min[3], float max[3]) if (!edit) return ok; if ((psys = edit->psys)) - psmd= psys_get_modifier(ob, psys); + psmd_eval = edit->psmd_eval; else unit_m4(mat); LOOP_VISIBLE_POINTS { if (psys) - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, psys->particles+p, mat); LOOP_SELECTED_KEYS { copy_v3_v3(co, key->co); @@ -4291,18 +4614,43 @@ int PE_minmax(Main *bmain, Scene *scene, float min[3], float max[3]) /************************ particle edit toggle operator ************************/ +static struct ParticleSystem *psys_eval_get(Depsgraph *depsgraph, + Object *object, + ParticleSystem *psys) +{ + Object *object_eval = DEG_get_evaluated_object(depsgraph, object); + if (object_eval == object) { + return psys; + } + ParticleSystem *psys_eval = object_eval->particlesystem.first; + while (psys_eval != NULL) { + if (psys_eval->orig_psys == psys) { + return psys_eval; + } + psys_eval = psys_eval->next; + } + return psys_eval; +} + /* initialize needed data for bake edit */ -void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys) +void PE_create_particle_edit( + Depsgraph *depsgraph, Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys) { + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); PTCacheEdit *edit; ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL; + ParticleSystemModifierData *psmd_eval = NULL; POINT_P; KEY_K; ParticleData *pa = NULL; HairKey *hkey; int totpoint; + if (psmd != NULL) { + psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name); + } + /* no psmd->dm happens in case particle system modifier is not enabled */ - if (!(psys && psmd && psmd->dm_final) && !cache) + if (!(psys && psmd && psmd_eval->mesh_final) && !cache) return; if (cache && cache->flag & PTCACHE_DISK_CACHE) @@ -4314,6 +4662,9 @@ void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache * edit = (psys) ? psys->edit : cache->edit; if (!edit) { + ParticleSystem *psys_eval = psys_eval_get(depsgraph, ob, psys); + psys_copy_particles(psys, psys_eval); + totpoint = psys ? psys->totpart : (int)((PTCacheMem *)cache->mem_cache.first)->totpoint; edit= MEM_callocN(sizeof(PTCacheEdit), "PE_create_particle_edit"); @@ -4321,8 +4672,11 @@ void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache * edit->totpoint = totpoint; if (psys && !cache) { - psys->edit= edit; + edit->psmd = psmd; + edit->psmd_eval = psmd_eval; + psys->edit = edit; edit->psys = psys; + edit->psys_eval = psys_eval; psys->free_edit= PE_free_ptcache_edit; @@ -4349,7 +4703,7 @@ void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache * } pa++; } - update_world_cos(ob, edit); + update_world_cos(depsgraph, ob, edit); } else { PTCacheMem *pm; @@ -4387,13 +4741,19 @@ void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache * psys = NULL; } + /* Causes assert on startup. */ +#if 0 UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col); UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col); - +#else + memset(edit->sel_col, 0xff, sizeof(edit->sel_col)); + memset(edit->nosel_col, 0x00, sizeof(edit->nosel_col)); +#endif recalc_lengths(edit); if (psys && !cache) - recalc_emitter_field(ob, psys); - PE_update_object(bmain, scene, ob, 1); + recalc_emitter_field(depsgraph, ob, psys); + + PE_update_object(depsgraph, scene, ob, 1); } } @@ -4415,7 +4775,8 @@ static bool particle_edit_toggle_poll(bContext *C) static int particle_edit_toggle_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); + struct wmMsgBus *mbus = CTX_wm_message_bus(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_PARTICLE_EDIT; @@ -4429,13 +4790,15 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op) if (!is_mode_set) { PTCacheEdit *edit; + ob->mode |= mode_flag; - edit= PE_create_current(bmain, scene, ob); + + edit= PE_create_current(depsgraph, 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 */ if (edit && edit->psys) - recalc_emitter_field(ob, edit->psys); + recalc_emitter_field(depsgraph, ob, edit->psys); toggle_particle_cursor(C, 1); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL); @@ -4446,7 +4809,13 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op) 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 | DEG_TAG_COPY_ON_WRITE); + + WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode); + + WM_toolsystem_update_from_context_view3d(C); return OPERATOR_FINISHED; } @@ -4487,7 +4856,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 */ @@ -4495,7 +4864,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; @@ -4596,22 +4965,24 @@ static void scale_points_to_length(PTCacheEdit *edit, float length) static int unify_length_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); - PTCacheEdit *edit = PE_get_current(bmain, scene, ob); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + + PTCacheEdit *edit = PE_get_current(scene, 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(bmain, scene, ob, 1); + PE_update_object(depsgraph, 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); } diff --git a/source/blender/editors/physics/particle_edit_undo.c b/source/blender/editors/physics/particle_edit_undo.c index 3d17b1a20c1..fdf765e4557 100644 --- a/source/blender/editors/physics/particle_edit_undo.c +++ b/source/blender/editors/physics/particle_edit_undo.c @@ -45,12 +45,12 @@ #include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_main.h" #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_undo_system.h" +#include "DEG_depsgraph.h" + #include "ED_object.h" #include "ED_particle.h" #include "ED_physics.h" @@ -229,27 +229,27 @@ typedef struct ParticleUndoStep { static bool particle_undosys_poll(struct bContext *C) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Object *ob = OBACT; - PTCacheEdit *edit = PE_get_current(bmain, scene, ob); + ViewLayer *view_layer = CTX_data_view_layer(C); + Object *ob = OBACT(view_layer); + PTCacheEdit *edit = PE_get_current(scene, ob); + return (edit != NULL); } static bool particle_undosys_step_encode(struct bContext *C, UndoStep *us_p) { - Main *bmain = CTX_data_main(C); ParticleUndoStep *us = (ParticleUndoStep *)us_p; + ViewLayer *view_layer = CTX_data_view_layer(C); us->scene_ref.ptr = CTX_data_scene(C); - us->object_ref.ptr = us->scene_ref.ptr->basact->object; - PTCacheEdit *edit = PE_get_current(bmain, us->scene_ref.ptr, us->object_ref.ptr); + us->object_ref.ptr = OBACT(view_layer); + PTCacheEdit *edit = PE_get_current(us->scene_ref.ptr, us->object_ref.ptr); undoptcache_from_editcache(&us->data, edit); return true; } static void particle_undosys_step_decode(struct bContext *C, UndoStep *us_p, int UNUSED(dir)) { - Main *bmain = CTX_data_main(C); /* TODO(campbell): undo_system: use low-level API to set mode. */ ED_object_mode_set(C, OB_MODE_PARTICLE_EDIT); BLI_assert(particle_undosys_poll(C)); @@ -257,10 +257,10 @@ static void particle_undosys_step_decode(struct bContext *C, UndoStep *us_p, int ParticleUndoStep *us = (ParticleUndoStep *)us_p; Scene *scene = us->scene_ref.ptr; Object *ob = us->object_ref.ptr; - PTCacheEdit *edit = PE_get_current(bmain, scene, ob); + PTCacheEdit *edit = PE_get_current(scene, ob); if (edit) { undoptcache_to_editcache(&us->data, edit); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { BLI_assert(0); diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 087d3182d8c..4431e4f4a54 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -33,6 +33,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_scene_types.h" @@ -42,19 +43,22 @@ #include "BLI_utildefines.h" #include "BLI_string.h" +#include "BKE_bvhutils.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_DerivedMesh.h" -#include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_report.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "RNA_access.h" #include "RNA_define.h" @@ -112,6 +116,7 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op)) Main *bmain = CTX_data_main(C); Object *ob = ED_object_context(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); int mode_orig; if (!scene || !ob) @@ -125,7 +130,7 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op)) */ if (mode_orig & OB_MODE_PARTICLE_EDIT) { if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) { - if (scene->basact && scene->basact->object == ob) { + if (view_layer->basact && view_layer->basact->object == ob) { WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL); } } @@ -187,8 +192,8 @@ static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op)) psys_check_boid_data(psys); - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); @@ -235,8 +240,8 @@ static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op)) BLI_addtail(&psys->targets, pt); - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); @@ -283,8 +288,8 @@ static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op)) if (pt) pt->flag |= PTARGET_CURRENT; - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); @@ -323,7 +328,7 @@ static int target_move_up_exec(bContext *C, wmOperator *UNUSED(op)) BLI_remlink(&psys->targets, pt); BLI_insertlinkbefore(&psys->targets, pt->prev, pt); - 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, ob); break; } @@ -361,7 +366,7 @@ static int target_move_down_exec(bContext *C, wmOperator *UNUSED(op)) BLI_remlink(&psys->targets, pt); BLI_insertlinkafter(&psys->targets, pt->next, pt); - 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, ob); break; } @@ -382,6 +387,35 @@ void PARTICLE_OT_target_move_down(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } +/************************ refresh dupli objects *********************/ + +static int dupliob_refresh_exec(bContext *C, wmOperator *UNUSED(op)) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + + if (!psys) + return OPERATOR_CANCELLED; + + psys_check_group_weights(psys->part); + DEG_id_tag_update(&psys->part->id, OB_RECALC_DATA | PSYS_RECALC_REDO); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_dupliob_refresh(wmOperatorType *ot) +{ + ot->name = "Refresh Dupli Objects"; + ot->idname = "PARTICLE_OT_dupliob_refresh"; + ot->description = "Refresh list of dupli objects and their weights"; + + ot->exec = dupliob_refresh_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + /************************ move up particle dupliweight operator *********************/ static int dupliob_move_up_exec(bContext *C, wmOperator *UNUSED(op)) @@ -400,6 +434,7 @@ static int dupliob_move_up_exec(bContext *C, wmOperator *UNUSED(op)) BLI_remlink(&part->dupliweights, dw); BLI_insertlinkbefore(&part->dupliweights, dw->prev, dw); + DEG_id_tag_update(&part->id, OB_RECALC_DATA | PSYS_RECALC_REDO); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL); break; } @@ -439,6 +474,7 @@ static int copy_particle_dupliob_exec(bContext *C, wmOperator *UNUSED(op)) dw->flag |= PART_DUPLIW_CURRENT; BLI_addhead(&part->dupliweights, dw); + DEG_id_tag_update(&part->id, OB_RECALC_DATA | PSYS_RECALC_REDO); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL); break; } @@ -485,6 +521,7 @@ static int remove_particle_dupliob_exec(bContext *C, wmOperator *UNUSED(op)) if (dw) dw->flag |= PART_DUPLIW_CURRENT; + DEG_id_tag_update(&part->id, OB_RECALC_DATA | PSYS_RECALC_REDO); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL); return OPERATOR_FINISHED; @@ -522,6 +559,7 @@ static int dupliob_move_down_exec(bContext *C, wmOperator *UNUSED(op)) BLI_remlink(&part->dupliweights, dw); BLI_insertlinkafter(&part->dupliweights, dw->next, dw); + DEG_id_tag_update(&part->id, OB_RECALC_DATA | PSYS_RECALC_REDO); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL); break; } @@ -544,7 +582,9 @@ void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot) /************************ connect/disconnect hair operators *********************/ -static void disconnect_hair(Main *bmain, Scene *scene, Object *ob, ParticleSystem *psys) +static void disconnect_hair( + Depsgraph *depsgraph, Scene *scene, + Object *ob, ParticleSystem *psys) { ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); ParticleEditSettings *pset= PE_settings(scene); @@ -571,7 +611,7 @@ static void disconnect_hair(Main *bmain, Scene *scene, Object *ob, ParticleSyste point++; } - psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat); for (k=0, key=pa->hair; k<pa->totkey; k++, key++) { mul_m4_v3(hairmat, key->co); @@ -590,12 +630,12 @@ static void disconnect_hair(Main *bmain, Scene *scene, Object *ob, ParticleSyste if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_PUFF)) pset->brushtype = PE_BRUSH_NONE; - PE_update_object(bmain, scene, ob, 0); + PE_update_object(depsgraph, scene, ob, 0); } static int disconnect_hair_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene= CTX_data_scene(C); Object *ob= ED_object_context(C); ParticleSystem *psys= NULL; @@ -606,15 +646,15 @@ static int disconnect_hair_exec(bContext *C, wmOperator *op) if (all) { for (psys=ob->particlesystem.first; psys; psys=psys->next) { - disconnect_hair(bmain, scene, ob, psys); + disconnect_hair(depsgraph, scene, ob, psys); } } else { psys = psys_get_current(ob); - disconnect_hair(bmain, scene, ob, psys); + disconnect_hair(depsgraph, scene, ob, psys); } - 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, ob); return OPERATOR_FINISHED; @@ -637,9 +677,10 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) /* from/to_world_space : whether from/to particles are in world or hair space * from/to_mat : additional transform for from/to particles (e.g. for using object space copying) */ -static bool remap_hair_emitter(Main *bmain, Scene *scene, Object *ob, ParticleSystem *psys, - Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit, - float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global) +static bool remap_hair_emitter( + Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, + Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit, + float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global) { ParticleSystemModifierData *target_psmd = psys_get_modifier(target_ob, target_psys); ParticleData *pa, *tpa; @@ -649,13 +690,13 @@ static bool remap_hair_emitter(Main *bmain, Scene *scene, Object *ob, ParticleSy MFace *mface = NULL, *mf; MEdge *medge = NULL, *me; MVert *mvert; - DerivedMesh *dm, *target_dm; + Mesh *mesh, *target_mesh; int numverts; int i, k; float from_ob_imat[4][4], to_ob_imat[4][4]; float from_imat[4][4], to_imat[4][4]; - if (!target_psmd->dm_final) + if (!target_psmd->mesh_final) return false; if (!psys->part || psys->part->type != PART_HAIR) return false; @@ -669,40 +710,46 @@ static bool remap_hair_emitter(Main *bmain, Scene *scene, Object *ob, ParticleSy invert_m4_m4(from_imat, from_mat); invert_m4_m4(to_imat, to_mat); - if (target_psmd->dm_final->deformedOnly) { + if (target_psmd->mesh_final->runtime.deformed_only) { /* we don't want to mess up target_psmd->dm when converting to global coordinates below */ - dm = target_psmd->dm_final; + mesh = target_psmd->mesh_final; } else { - dm = target_psmd->dm_deformed; + mesh = target_psmd->mesh_original; } - target_dm = target_psmd->dm_final; - if (dm == NULL) { + target_mesh = target_psmd->mesh_final; + if (mesh == NULL) { return false; } /* don't modify the original vertices */ - dm = CDDM_copy(dm); + BKE_id_copy_ex( + NULL, &mesh->id, (ID **)&mesh, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); /* BMESH_ONLY, deform dm may not have tessface */ - DM_ensure_tessface(dm); + BKE_mesh_tessface_ensure(mesh); - numverts = dm->getNumVerts(dm); - mvert = dm->getVertArray(dm); + numverts = mesh->totvert; + mvert = mesh->mvert; /* convert to global coordinates */ for (i=0; i<numverts; i++) mul_m4_v3(to_mat, mvert[i].co); - if (dm->getNumTessFaces(dm) != 0) { - mface = dm->getTessFaceArray(dm); - bvhtree_from_mesh_get(&bvhtree, dm, BVHTREE_FROM_FACES, 2); + if (mesh->totface != 0) { + mface = mesh->mface; + BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_FACES, 2); } - else if (dm->getNumEdges(dm) != 0) { - medge = dm->getEdgeArray(dm); - bvhtree_from_mesh_get(&bvhtree, dm, BVHTREE_FROM_EDGES, 2); + else if (mesh->totedge != 0) { + medge = mesh->medge; + BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_EDGES, 2); } else { - dm->release(dm); + BKE_id_free(NULL, mesh); return false; } @@ -747,7 +794,7 @@ static bool remap_hair_emitter(Main *bmain, Scene *scene, Object *ob, ParticleSy tpa->foffset = 0.0f; tpa->num = nearest.index; - tpa->num_dmcache = psys_particle_dm_face_lookup(target_dm, dm, tpa->num, tpa->fuv, NULL); + tpa->num_dmcache = psys_particle_dm_face_lookup(target_mesh, mesh, tpa->num, tpa->fuv, NULL); } else { me = &medge[nearest.index]; @@ -773,7 +820,7 @@ static bool remap_hair_emitter(Main *bmain, Scene *scene, Object *ob, ParticleSy copy_m4_m4(imat, target_ob->obmat); else { /* note: using target_dm here, which is in target_ob object space and has full modifiers */ - psys_mat_hair_to_object(target_ob, target_dm, target_psys->part->from, tpa, hairmat); + psys_mat_hair_to_object(target_ob, target_mesh, target_psys->part->from, tpa, hairmat); invert_m4_m4(imat, hairmat); } mul_m4_m4m4(imat, imat, to_imat); @@ -819,24 +866,27 @@ static bool remap_hair_emitter(Main *bmain, Scene *scene, Object *ob, ParticleSy } free_bvhtree_from_mesh(&bvhtree); - dm->release(dm); + BKE_id_free(NULL, mesh); psys_free_path_cache(target_psys, target_edit); - PE_update_object(bmain, scene, target_ob, 0); + PE_update_object(depsgraph, scene, target_ob, 0); return true; } -static bool connect_hair(Main *bmain, Scene *scene, Object *ob, ParticleSystem *psys) +static bool connect_hair( + Depsgraph *depsgraph, Scene *scene, + Object *ob, ParticleSystem *psys) { bool ok; if (!psys) return false; - ok = remap_hair_emitter(bmain, scene, ob, psys, ob, psys, psys->edit, - ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false); + ok = remap_hair_emitter( + depsgraph, scene, ob, psys, ob, psys, psys->edit, + ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false); psys->flag &= ~PSYS_GLOBAL_HAIR; return ok; @@ -844,7 +894,7 @@ static bool connect_hair(Main *bmain, Scene *scene, Object *ob, ParticleSystem * static int connect_hair_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene= CTX_data_scene(C); Object *ob= ED_object_context(C); ParticleSystem *psys= NULL; @@ -856,12 +906,12 @@ static int connect_hair_exec(bContext *C, wmOperator *op) if (all) { for (psys=ob->particlesystem.first; psys; psys=psys->next) { - any_connected |= connect_hair(bmain, scene, ob, psys); + any_connected |= connect_hair(depsgraph, scene, ob, psys); } } else { psys = psys_get_current(ob); - any_connected |= connect_hair(bmain, scene, ob, psys); + any_connected |= connect_hair(depsgraph, scene, ob, psys); } if (!any_connected) { @@ -870,7 +920,7 @@ static int connect_hair_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - 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, ob); return OPERATOR_FINISHED; @@ -897,7 +947,9 @@ typedef enum eCopyParticlesSpace { PAR_COPY_SPACE_WORLD = 1, } eCopyParticlesSpace; -static void copy_particle_edit(Main *bmain, Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from) +static void copy_particle_edit( + Depsgraph *depsgraph, Scene *scene, + Object *ob, ParticleSystem *psys, ParticleSystem *psys_from) { PTCacheEdit *edit_from = psys_from->edit, *edit; ParticleData *pa; @@ -937,14 +989,14 @@ static void copy_particle_edit(Main *bmain, Scene *scene, Object *ob, ParticleSy pa++; } - update_world_cos(ob, edit); + update_world_cos(depsgraph, ob, edit); UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col); UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col); recalc_lengths(edit); - recalc_emitter_field(ob, psys); - PE_update_object(bmain, scene, ob, true); + recalc_emitter_field(depsgraph, ob, psys); + PE_update_object(depsgraph, scene, ob, true); } static void remove_particle_systems_from_object(Object *ob_to) @@ -972,7 +1024,7 @@ static void remove_particle_systems_from_object(Object *ob_to) } /* single_psys_from is optional, if NULL all psys of ob_from are copied */ -static bool copy_particle_systems_to_object(Main *bmain, +static bool copy_particle_systems_to_object(const bContext *C, Scene *scene, Object *ob_from, ParticleSystem *single_psys_from, @@ -980,10 +1032,12 @@ static bool copy_particle_systems_to_object(Main *bmain, int space, bool duplicate_settings) { + Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); ModifierData *md; ParticleSystem *psys_start = NULL, *psys, *psys_from; ParticleSystem **tmp_psys; - DerivedMesh *final_dm; + Mesh *final_mesh; CustomDataMask cdmask; int i, totpsys; @@ -1024,8 +1078,8 @@ static bool copy_particle_systems_to_object(Main *bmain, */ psys_start = totpsys > 0 ? tmp_psys[0] : NULL; - /* get the DM (psys and their modifiers have not been appended yet) */ - final_dm = mesh_get_derived_final(scene, ob_to, cdmask); + /* Get the evaluated mesh (psys and their modifiers have not been appended yet) */ + final_mesh = mesh_get_eval_final(depsgraph, scene, ob_to, cdmask); /* now append psys to the object and make modifiers */ for (i = 0, psys_from = PSYS_FROM_FIRST; @@ -1049,12 +1103,20 @@ static bool copy_particle_systems_to_object(Main *bmain, modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd); psmd->psys = psys; - psmd->dm_final = CDDM_copy(final_dm); - CDDM_calc_normals(psmd->dm_final); - DM_ensure_tessface(psmd->dm_final); - - if (psys_from->edit) - copy_particle_edit(bmain, scene, ob_to, psys, psys_from); + BKE_id_copy_ex( + NULL, &final_mesh->id, (ID **)&psmd->mesh_final, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); + + BKE_mesh_calc_normals(psmd->mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); + + if (psys_from->edit) { + copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from); + } if (duplicate_settings) { id_us_min(&psys->part->id); @@ -1089,8 +1151,8 @@ static bool copy_particle_systems_to_object(Main *bmain, } if (ob_from != ob_to) { remap_hair_emitter( - bmain, scene, ob_from, psys_from, ob_to, psys, psys->edit, - from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR); + depsgraph, scene, ob_from, psys_from, ob_to, psys, psys->edit, + from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR); } /* tag for recalc */ @@ -1100,7 +1162,7 @@ static bool copy_particle_systems_to_object(Main *bmain, #undef PSYS_FROM_FIRST #undef PSYS_FROM_NEXT - DAG_id_tag_update(&ob_to->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob_to->id, OB_RECALC_DATA); WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to); return true; } @@ -1123,7 +1185,6 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op) const int space = RNA_enum_get(op->ptr, "space"); const bool remove_target_particles = RNA_boolean_get(op->ptr, "remove_target_particles"); const bool use_active = RNA_boolean_get(op->ptr, "use_active"); - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob_from = ED_object_active_context(C); ParticleSystem *psys_from = use_active ? CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data : NULL; @@ -1139,7 +1200,7 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op) remove_particle_systems_from_object(ob_to); changed = true; } - if (copy_particle_systems_to_object(bmain, scene, ob_from, psys_from, ob_to, space, false)) + if (copy_particle_systems_to_object(C, scene, ob_from, psys_from, ob_to, space, false)) changed = true; else fail++; @@ -1200,7 +1261,7 @@ static int duplicate_particle_systems_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data; - copy_particle_systems_to_object(CTX_data_main(C), scene, ob, psys, ob, + copy_particle_systems_to_object(C, scene, ob, psys, ob, PAR_COPY_SPACE_OBJECT, duplicate_settings); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index c76c04c1e99..6cc9b9b8e4d 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -54,6 +54,8 @@ #include "BKE_report.h" #include "BKE_scene.h" +#include "DEG_depsgraph.h" + #include "LBM_fluidsim.h" #include "ED_screen.h" @@ -245,7 +247,7 @@ static void set_channel(float *channel, float time, float *value, int i, int siz } } -static void set_vertex_channel(float *channel, float time, struct Scene *scene, struct FluidObject *fobj, int i) +static void set_vertex_channel(Depsgraph *depsgraph, float *channel, float time, struct Scene *scene, struct FluidObject *fobj, int i) { Object *ob = fobj->object; FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); @@ -258,7 +260,7 @@ static void set_vertex_channel(float *channel, float time, struct Scene *scene, if (channel == NULL) return; - initElbeemMesh(scene, ob, &numVerts, &verts, &numTris, &tris, 1, modifierIndex); + initElbeemMesh(depsgraph, scene, ob, &numVerts, &verts, &numTris, &tris, 1, modifierIndex); /* don't allow mesh to change number of verts in anim sequence */ if (numVerts != fobj->numVerts) { @@ -330,6 +332,8 @@ static void free_all_fluidobject_channels(ListBase *fobjects) static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), FluidsimSettings *domainSettings, FluidAnimChannels *channels, ListBase *fobjects) { Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Base *base; int i; int length = channels->length; @@ -344,7 +348,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid channels->DomainTime = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime"); /* allocate fluid objects */ - for (base=scene->base.first; base; base= base->next) { + for (base = FIRSTBASE(view_layer); base; base = base->next) { Object *ob = base->object; FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); @@ -374,7 +378,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid float *verts=NULL; int *tris=NULL, modifierIndex = BLI_findindex(&ob->modifiers, (ModifierData *)fluidmd); - initElbeemMesh(scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex); + initElbeemMesh(depsgraph, scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex); fobj->VertexCache = MEM_callocN(length *((fobj->numVerts*CHANNEL_VEC)+1) * sizeof(float), "fluidobject VertexCache"); MEM_freeN(verts); @@ -403,7 +407,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid /* Modifying the global scene isn't nice, but we can do it in * this part of the process before a threaded job is created */ scene->r.cfra = (int)eval_time; - ED_update_for_newframe(CTX_data_main(C), scene, 1); + ED_update_for_newframe(CTX_data_main(C), depsgraph); /* now scene data should be current according to animation system, so we fill the channels */ @@ -462,14 +466,15 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid } if (fluid_is_animated_mesh(fluidmd->fss)) { - set_vertex_channel(fobj->VertexCache, timeAtFrame, scene, fobj, i); + set_vertex_channel(depsgraph, fobj->VertexCache, timeAtFrame, scene, fobj, i); } } } } -static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length) +static void export_fluid_objects(const bContext *C, ListBase *fobjects, Scene *scene, int length) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); FluidObject *fobj; for (fobj=fobjects->first; fobj; fobj=fobj->next) { @@ -492,7 +497,7 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length) fsmesh.type = fluidmd->fss->type; fsmesh.name = ob->id.name; - initElbeemMesh(scene, ob, &numVerts, &verts, &numTris, &tris, 0, modifierIndex); + initElbeemMesh(depsgraph, scene, ob, &numVerts, &verts, &numTris, &tris, 0, modifierIndex); fsmesh.numVertices = numVerts; fsmesh.numTriangles = numTris; @@ -571,14 +576,14 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length) } } -static int fluid_validate_scene(ReportList *reports, Scene *scene, Object *fsDomain) +static int fluid_validate_scene(ReportList *reports, ViewLayer *view_layer, Object *fsDomain) { Base *base; Object *newdomain = NULL; int channelObjCount = 0; int fluidInputCount = 0; - for (base=scene->base.first; base; base= base->next) { + for (base = FIRSTBASE(view_layer); base; base = base->next) { Object *ob = base->object; FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); @@ -837,7 +842,9 @@ static void fluidsim_delete_until_lastframe(FluidsimSettings *fss, const char *r static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, short do_job) { Main *bmain = CTX_data_main(C); - Scene *scene= CTX_data_scene(C); + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); int i; FluidsimSettings *domainSettings; @@ -884,7 +891,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor } /* check scene for sane object/modifier settings */ - if (!fluid_validate_scene(reports, scene, fsDomain)) { + if (!fluid_validate_scene(reports, view_layer, fsDomain)) { fluidbake_free_data(channels, fobjects, fsset, fb); return 0; } @@ -949,7 +956,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor /* reset to original current frame */ scene->r.cfra = origFrame; - ED_update_for_newframe(CTX_data_main(C), scene, 1); + ED_update_for_newframe(CTX_data_main(C), depsgraph); /* ******** init domain object's matrix ******** */ copy_m4_m4(domainMat, fsDomain->obmat); @@ -1036,7 +1043,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor elbeemAddDomain(fsset); /* ******** export all fluid objects to elbeem ******** */ - export_fluid_objects(fobjects, scene, channels->length); + export_fluid_objects(C, fobjects, scene, channels->length); /* custom data for fluid bake job */ fb->settings = fsset; diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h index 3f958f363b6..df688d90e44 100644 --- a/source/blender/editors/physics/physics_intern.h +++ b/source/blender/editors/physics/physics_intern.h @@ -33,11 +33,13 @@ #ifndef __PHYSICS_INTERN_H__ #define __PHYSICS_INTERN_H__ +struct Depsgraph; struct Object; struct PTCacheEdit; struct ParticleSystem; struct PointCache; struct Scene; +struct ViewLayer; struct wmOperatorType; /* particle_edit.c */ @@ -69,10 +71,11 @@ void PARTICLE_OT_edited_clear(struct wmOperatorType *ot); void PARTICLE_OT_unify_length(struct wmOperatorType *ot); void PE_create_particle_edit( - struct Main *bmain, struct Scene *scene, struct Object *ob, struct PointCache *cache, struct ParticleSystem *psys); + struct Depsgraph *depsgraph, struct Scene *scene, + struct Object *ob, struct PointCache *cache, struct ParticleSystem *psys); void recalc_lengths(struct PTCacheEdit *edit); -void recalc_emitter_field(struct Object *ob, struct ParticleSystem *psys); -void update_world_cos(struct Object *ob, struct PTCacheEdit *edit); +void recalc_emitter_field(struct Depsgraph *depsgraph, struct Object *ob, struct ParticleSystem *psys); +void update_world_cos(struct Depsgraph *depsgraph, struct Object *ob, struct PTCacheEdit *edit); /* particle_object.c */ void OBJECT_OT_particle_system_add(struct wmOperatorType *ot); @@ -92,6 +95,7 @@ void PARTICLE_OT_dupliob_copy(struct wmOperatorType *ot); void PARTICLE_OT_dupliob_remove(struct wmOperatorType *ot); void PARTICLE_OT_dupliob_move_up(struct wmOperatorType *ot); void PARTICLE_OT_dupliob_move_down(struct wmOperatorType *ot); +void PARTICLE_OT_dupliob_refresh(struct wmOperatorType *ot); /* particle_boids.c */ void BOID_OT_rule_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c index de2ee73ab26..db64aa8811c 100644 --- a/source/blender/editors/physics/physics_ops.c +++ b/source/blender/editors/physics/physics_ops.c @@ -85,6 +85,7 @@ static void operatortypes_particle(void) WM_operatortype_append(PARTICLE_OT_copy_particle_systems); WM_operatortype_append(PARTICLE_OT_duplicate_particle_system); + WM_operatortype_append(PARTICLE_OT_dupliob_refresh); WM_operatortype_append(PARTICLE_OT_dupliob_copy); WM_operatortype_append(PARTICLE_OT_dupliob_remove); WM_operatortype_append(PARTICLE_OT_dupliob_move_up); @@ -128,7 +129,9 @@ static void keymap_particle(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "deselect", true); +#ifdef USE_WM_KEYMAP_27X WM_keymap_add_item(keymap, "PARTICLE_OT_delete", XKEY, KM_PRESS, 0, 0); +#endif 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); @@ -137,23 +140,6 @@ static void keymap_particle(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "unselected", true); - /* Shift+LMB behavior first, so it has priority over KM_ANY item below. */ - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "release_confirm", true); - RNA_boolean_set(kmi->ptr, "use_planar_constraint", true); - RNA_boolean_set(kmi->ptr, "use_accurate", false); - - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "release_confirm", true); - RNA_boolean_set(kmi->ptr, "use_planar_constraint", false); - RNA_boolean_set(kmi->ptr, "use_accurate", true); - - /* Using KM_ANY here to allow holding modifiers before starting to transform. */ - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0); - RNA_boolean_set(kmi->ptr, "release_confirm", true); - RNA_boolean_set(kmi->ptr, "use_planar_constraint", false); - RNA_boolean_set(kmi->ptr, "use_accurate", false); - WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index 51c5955d507..7fc3dc2e1b8 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -42,6 +42,7 @@ #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_global.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -165,6 +166,8 @@ static PTCacheBaker *ptcache_baker_create(bContext *C, wmOperator *op, bool all) baker->bmain = CTX_data_main(C); baker->scene = CTX_data_scene(C); + baker->view_layer = CTX_data_view_layer(C); + baker->depsgraph = CTX_data_depsgraph(C); baker->bake = RNA_boolean_get(op->ptr, "bake"); baker->render = 0; baker->anim_init = 0; @@ -174,18 +177,7 @@ static PTCacheBaker *ptcache_baker_create(bContext *C, wmOperator *op, bool all) PointerRNA ptr = CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Object *ob = ptr.id.data; PointCache *cache = ptr.data; - - ListBase pidlist; - BKE_ptcache_ids_from_object(baker->bmain, &pidlist, ob, baker->scene, MAX_DUPLI_RECUR); - - for (PTCacheID *pid = pidlist.first; pid; pid = pid->next) { - if (pid->cache == cache) { - baker->pid = *pid; - break; - } - } - - BLI_freelistN(&pidlist); + baker->pid = BKE_ptcache_id_find(ob, baker->scene, cache); } return baker; @@ -253,23 +245,23 @@ static void ptcache_bake_cancel(bContext *C, wmOperator *op) static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Base *base; PTCacheID *pid; ListBase pidlist; - for (base = scene->base.first; base; base = base->next) { - BKE_ptcache_ids_from_object(bmain, &pidlist, base->object, scene, MAX_DUPLI_RECUR); + FOREACH_SCENE_OBJECT_BEGIN(scene, ob) + { + BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); - for (pid=pidlist.first; pid; pid=pid->next) { + for (pid = pidlist.first; pid; pid = pid->next) { ptcache_free_bake(pid->cache); } BLI_freelistN(&pidlist); - WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, base->object); + WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); } + FOREACH_SCENE_OBJECT_END; WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); @@ -384,27 +376,18 @@ void PTCACHE_OT_bake_from_cache(wmOperatorType *ot) static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Object *ob= ptr.id.data; PointCache *cache= ptr.data; - PTCacheID *pid; - ListBase pidlist; + PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache); - BKE_ptcache_ids_from_object(bmain, &pidlist, ob, scene, MAX_DUPLI_RECUR); - - for (pid=pidlist.first; pid; pid=pid->next) { - if (pid->cache == cache) { - PointCache *cache_new = BKE_ptcache_add(pid->ptcaches); - cache_new->step = pid->default_step; - *(pid->cache_ptr) = cache_new; - break; - } + if (pid.cache) { + PointCache *cache_new = BKE_ptcache_add(pid.ptcaches); + cache_new->step = pid.default_step; + *(pid.cache_ptr) = cache_new; } - BLI_freelistN(&pidlist); - WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); @@ -412,31 +395,19 @@ static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op)) } static int ptcache_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Scene *scene= CTX_data_scene(C); Object *ob= ptr.id.data; PointCache *cache= ptr.data; - PTCacheID *pid; - ListBase pidlist; - - BKE_ptcache_ids_from_object(bmain, &pidlist, ob, scene, MAX_DUPLI_RECUR); + PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache); - for (pid=pidlist.first; pid; pid=pid->next) { - if (pid->cache == cache) { - if (pid->ptcaches->first == pid->ptcaches->last) - continue; /* don't delete last cache */ - - BLI_remlink(pid->ptcaches, pid->cache); - BKE_ptcache_free(pid->cache); - *(pid->cache_ptr) = pid->ptcaches->first; - - break; - } + /* don't delete last cache */ + if (pid.cache && pid.ptcaches->first != pid.ptcaches->last) { + BLI_remlink(pid.ptcaches, pid.cache); + BKE_ptcache_free(pid.cache); + *(pid.cache_ptr) = pid.ptcaches->first; } - BLI_freelistN(&pidlist); - WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); return OPERATOR_FINISHED; diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c index 0c612cc5855..7ec814bc142 100644 --- a/source/blender/editors/physics/rigidbody_constraint.c +++ b/source/blender/editors/physics/rigidbody_constraint.c @@ -37,13 +37,15 @@ #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" +#include "BKE_collection.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_group.h" #include "BKE_main.h" #include "BKE_report.h" #include "BKE_rigidbody.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -81,17 +83,20 @@ bool ED_rigidbody_constraint_add(Main *bmain, Scene *scene, Object *ob, int type } /* create constraint group if it doesn't already exits */ if (rbw->constraints == NULL) { - rbw->constraints = BKE_group_add(bmain, "RigidBodyConstraints"); + rbw->constraints = BKE_collection_add(bmain, NULL, "RigidBodyConstraints"); + id_fake_user_set(&rbw->constraints->id); } /* make rigidbody constraint settings */ ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, type); ob->rigidbody_constraint->flag |= RBC_FLAG_NEEDS_VALIDATE; /* add constraint to rigid body constraint group */ - BKE_group_object_add(rbw->constraints, ob, scene, NULL); + BKE_collection_object_add(bmain, rbw->constraints, ob); + + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&rbw->constraints->id, DEG_TAG_COPY_ON_WRITE); - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&ob->id, OB_RECALC_OB); return true; } @@ -100,11 +105,13 @@ void ED_rigidbody_constraint_remove(Main *bmain, Scene *scene, Object *ob) RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); BKE_rigidbody_remove_constraint(scene, ob); - if (rbw) - BKE_group_object_unlink(bmain, rbw->constraints, ob, scene, NULL); + if (rbw) { + BKE_collection_object_remove(bmain, rbw->constraints, ob, false); + DEG_id_tag_update(&rbw->constraints->id, DEG_TAG_COPY_ON_WRITE); + } - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } /* ********************************************** */ @@ -116,8 +123,9 @@ static int rigidbody_con_add_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); - Object *ob = (scene) ? OBACT : NULL; + Object *ob = OBACT(view_layer); int type = RNA_enum_get(op->ptr, "type"); bool changed; @@ -165,11 +173,8 @@ static int rigidbody_con_remove_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Object *ob = (scene) ? OBACT : NULL; - - /* sanity checks */ - if (scene == NULL) - return OPERATOR_CANCELLED; + ViewLayer *view_layer = CTX_data_view_layer(C); + Object *ob = OBACT(view_layer); /* apply to active object */ if (ELEM(NULL, ob, ob->rigidbody_constraint)) { diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c index ec6de52ebc1..56d80e232c0 100644 --- a/source/blender/editors/physics/rigidbody_object.c +++ b/source/blender/editors/physics/rigidbody_object.c @@ -42,13 +42,15 @@ #include "BLT_translation.h" +#include "BKE_collection.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_group.h" #include "BKE_main.h" #include "BKE_report.h" #include "BKE_rigidbody.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -107,7 +109,8 @@ bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, Re scene->rigidbody_world = rbw; } if (rbw->group == NULL) { - rbw->group = BKE_group_add(bmain, "RigidBodyWorld"); + rbw->group = BKE_collection_add(bmain, NULL, "RigidBodyWorld"); + id_fake_user_set(&rbw->group->id); } /* make rigidbody object settings */ @@ -118,24 +121,21 @@ bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, Re ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE; /* add object to rigid body group */ - BKE_group_object_add(rbw->group, ob, scene, NULL); + BKE_collection_object_add(bmain, rbw->group, ob); - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&rbw->group->id, DEG_TAG_COPY_ON_WRITE); return true; } void ED_rigidbody_object_remove(Main *bmain, Scene *scene, Object *ob) { - RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); - - BKE_rigidbody_remove_object(scene, ob); - if (rbw) - BKE_group_object_unlink(bmain, rbw->group, ob, scene, NULL); + BKE_rigidbody_remove_object(bmain, scene, ob); - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } /* ********************************************** */ @@ -344,7 +344,7 @@ static int rigidbody_objects_shape_change_exec(bContext *C, wmOperator *op) RNA_pointer_create(&ob->id, &RNA_RigidBodyObject, ob->rigidbody_object, &ptr); RNA_enum_set(&ptr, "collision_shape", shape); - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); changed = true; } @@ -526,7 +526,7 @@ static int rigidbody_objects_calc_mass_exec(bContext *C, wmOperator *op) RNA_pointer_create(&ob->id, &RNA_RigidBodyObject, ob->rigidbody_object, &ptr); RNA_float_set(&ptr, "mass", mass); - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); changed = true; } diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c index fe2be86dd98..da0099ba469 100644 --- a/source/blender/editors/physics/rigidbody_world.c +++ b/source/blender/editors/physics/rigidbody_world.c @@ -114,8 +114,7 @@ static int rigidbody_world_remove_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BKE_rigidbody_free_world(rbw); - scene->rigidbody_world = NULL; + BKE_rigidbody_free_world(scene); /* done */ return OPERATOR_FINISHED; @@ -152,14 +151,14 @@ static int rigidbody_world_export_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to export"); return OPERATOR_CANCELLED; } - if (rbw->physics_world == NULL) { + if (rbw->shared->physics_world == NULL) { BKE_report(op->reports, RPT_ERROR, "Rigid Body World has no associated physics data to export"); return OPERATOR_CANCELLED; } RNA_string_get(op->ptr, "filepath", path); #ifdef WITH_BULLET - RB_dworld_export(rbw->physics_world, path); + RB_dworld_export(rbw->shared->physics_world, path); #endif return OPERATOR_FINISHED; } |