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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/physics')
-rw-r--r--source/blender/editors/physics/CMakeLists.txt1
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c18
-rw-r--r--source/blender/editors/physics/particle_boids.c20
-rw-r--r--source/blender/editors/physics/particle_edit.c1241
-rw-r--r--source/blender/editors/physics/particle_edit_undo.c22
-rw-r--r--source/blender/editors/physics/particle_object.c203
-rw-r--r--source/blender/editors/physics/physics_fluid.c35
-rw-r--r--source/blender/editors/physics/physics_intern.h10
-rw-r--r--source/blender/editors/physics/physics_ops.c20
-rw-r--r--source/blender/editors/physics/physics_pointcache.c71
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c37
-rw-r--r--source/blender/editors/physics/rigidbody_object.c30
-rw-r--r--source/blender/editors/physics/rigidbody_world.c7
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;
}