diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2016-04-20 17:45:29 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2016-04-20 17:45:29 +0300 |
commit | aae0598aa233d43d0ffc81a070b2ce20d6871c1d (patch) | |
tree | 378100f45cf1db972c671a6886496a5604f7ab29 /source/blender/editors/physics | |
parent | 95d7d3c2a6aa91f1dcb33ff0cdfc751e2886d8cd (diff) | |
parent | d7e4f920fd93a4ae5679e0eb6b228a349ab3b082 (diff) |
Merge branch 'master' into temp_depsgraph_split_ubereval
Diffstat (limited to 'source/blender/editors/physics')
-rw-r--r-- | source/blender/editors/physics/SConscript | 58 | ||||
-rw-r--r-- | source/blender/editors/physics/dynamicpaint_ops.c | 184 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_boids.c | 2 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_edit.c | 152 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_object.c | 37 | ||||
-rw-r--r-- | source/blender/editors/physics/physics_pointcache.c | 270 | ||||
-rw-r--r-- | source/blender/editors/physics/rigidbody_constraint.c | 2 | ||||
-rw-r--r-- | source/blender/editors/physics/rigidbody_object.c | 6 | ||||
-rw-r--r-- | source/blender/editors/physics/rigidbody_world.c | 4 |
9 files changed, 410 insertions, 305 deletions
diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript deleted file mode 100644 index be399a58732..00000000000 --- a/source/blender/editors/physics/SConscript +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Nathan Letwory. -# -# ***** END GPL LICENSE BLOCK ***** - -Import ('env') - -sources = env.Glob('*.c') - -incs = [ - '#/intern/guardedalloc', - env['BF_GLEW_INC'], - '#/intern/glew-mx', - '#/intern/rigidbody', - '#/intern/elbeem/extern', - '../include', - '../../blenkernel', - '../../blenlib', - '../../blentranslation', - '../../gpu', - '../../makesdna', - '../../makesrna', - '../../windowmanager', - ] -incs = ' '.join(incs) - -defs = [] -defs += env['BF_GL_DEFINITIONS'] - -if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): - incs += ' ' + env['BF_PTHREADS_INC'] - -if env['WITH_BF_INTERNATIONAL']: - defs.append('WITH_INTERNATIONAL') - -env.BlenderLib ( 'bf_editors_physics', sources, Split(incs), defs, libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 93daa15e608..7cc17e4bfea 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -26,6 +26,8 @@ #include <stdio.h> #include <string.h> +#include "MEM_guardedalloc.h" + #include "BLI_blenlib.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -44,8 +46,10 @@ #include "BKE_depsgraph.h" #include "BKE_dynamicpaint.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_report.h" +#include "BKE_screen.h" #include "ED_mesh.h" #include "ED_screen.h" @@ -202,7 +206,7 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop = RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", ""); + prop = RNA_def_enum(ot->srna, "type", rna_enum_prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", ""); ot->prop = prop; } @@ -275,49 +279,112 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot) /***************************** Image Sequence Baking ******************************/ +typedef struct DynamicPaintBakeJob { + /* from wmJob */ + void *owner; + short *stop, *do_update; + float *progress; + + struct Main *bmain; + Scene *scene; + Object *ob; + + DynamicPaintSurface *surface; + DynamicPaintCanvasSettings *canvas; + + int success; + double start; +} DynamicPaintBakeJob; + +static void dpaint_bake_free(void *customdata) +{ + DynamicPaintBakeJob *job = customdata; + MEM_freeN(job); +} + +static void dpaint_bake_endjob(void *customdata) +{ + DynamicPaintBakeJob *job = customdata; + DynamicPaintCanvasSettings *canvas = job->canvas; + + canvas->flags &= ~MOD_DPAINT_BAKING; + + dynamicPaint_freeSurfaceData(job->surface); + + G.is_rendering = false; + BKE_spacedata_draw_locks(false); + + WM_set_locked_interface(G.main->wm.first, false); + + /* Bake was successful: + * Report for ended bake and how long it took */ + if (job->success) { + /* Show bake info */ + WM_reportf(RPT_INFO, "DynamicPaint: Bake complete! (%.2f)", PIL_check_seconds_timer() - job->start); + } + else { + if (strlen(canvas->error)) { /* If an error occurred */ + WM_reportf(RPT_ERROR, "DynamicPaint: Bake failed: %s", canvas->error); + } + else { /* User canceled the bake */ + WM_report(RPT_WARNING, "Baking canceled!"); + } + } +} + /* * Do actual bake operation. Loop through to-be-baked frames. * Returns 0 on failure. */ -static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surface, Object *cObject) +static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job) { + DynamicPaintSurface *surface = job->surface; + Object *cObject = job->ob; DynamicPaintCanvasSettings *canvas = surface->canvas; - Scene *scene = CTX_data_scene(C); - wmWindow *win = CTX_wm_window(C); - int frame = 1; + Scene *scene = job->scene; + int frame = 1, orig_frame; int frames; frames = surface->end_frame - surface->start_frame + 1; if (frames <= 0) { BLI_strncpy(canvas->error, N_("No frames to bake"), sizeof(canvas->error)); - return 0; + return; } /* Set frame to start point (also inits modifier data) */ frame = surface->start_frame; + orig_frame = scene->r.cfra; scene->r.cfra = (int)frame; - ED_update_for_newframe(CTX_data_main(C), scene, 1); + ED_update_for_newframe(job->bmain, scene, 1); /* Init surface */ - if (!dynamicPaint_createUVSurface(scene, surface)) return 0; + if (!dynamicPaint_createUVSurface(scene, surface)) { + job->success = 0; + return; + } /* Loop through selected frames */ for (frame = surface->start_frame; frame <= surface->end_frame; frame++) { - float progress = (frame - surface->start_frame) / (float)frames * 100; + float progress = (frame - surface->start_frame) / (float)frames; surface->current_frame = frame; - /* If user requested stop (esc), quit baking */ - if (blender_test_break()) return 0; - - /* Update progress bar cursor */ - if (!G.background) { - WM_cursor_time(win, (int)progress); + /* If user requested stop, quit baking */ + if (G.is_break) { + job->success = 0; + return; } + /* Update progress bar */ + *(job->do_update) = true; + *(job->progress) = progress; + /* calculate a frame */ scene->r.cfra = (int)frame; - ED_update_for_newframe(CTX_data_main(C), scene, 1); - if (!dynamicPaint_calculateFrame(surface, scene, cObject, frame)) return 0; + ED_update_for_newframe(job->bmain, scene, 1); + if (!dynamicPaint_calculateFrame(surface, scene, cObject, frame)) { + job->success = 0; + return; + } /* * Save output images @@ -345,21 +412,44 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf } } } - return 1; + + scene->r.cfra = orig_frame; } +static void dpaint_bake_startjob(void *customdata, short *stop, short *do_update, float *progress) +{ + DynamicPaintBakeJob *job = customdata; + + job->stop = stop; + job->do_update = do_update; + job->progress = progress; + job->start = PIL_check_seconds_timer(); + job->success = 1; + + G.is_break = false; /* reset blender_test_break*/ + + /* XXX annoying hack: needed to prevent data corruption when changing + * scene frame in separate threads + */ + G.is_rendering = true; + BKE_spacedata_draw_locks(true); + + dynamicPaint_bakeImageSequence(job); + + *do_update = true; + *stop = 0; +} /* * Bake Dynamic Paint image sequence surface */ -static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) +static int dynamicpaint_bake_exec(struct bContext *C, struct wmOperator *op) { - wmWindow *win = CTX_wm_window(C); DynamicPaintModifierData *pmd = NULL; DynamicPaintCanvasSettings *canvas; Object *ob = ED_object_context(C); - int status = 0; - double timer = PIL_check_seconds_timer(); + Scene *scene = CTX_data_scene(C); + DynamicPaintSurface *surface; /* @@ -368,54 +458,40 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); if (!pmd) { BKE_report(op->reports, RPT_ERROR, "Bake failed: no Dynamic Paint modifier found"); - return 0; + return OPERATOR_CANCELLED; } /* Make sure we're dealing with a canvas */ canvas = pmd->canvas; if (!canvas) { BKE_report(op->reports, RPT_ERROR, "Bake failed: invalid canvas"); - return 0; + return OPERATOR_CANCELLED; } surface = get_activeSurface(canvas); /* Set state to baking and init surface */ canvas->error[0] = '\0'; canvas->flags |= MOD_DPAINT_BAKING; - G.is_break = false; /* reset blender_test_break*/ - /* Bake Dynamic Paint */ - status = dynamicPaint_bakeImageSequence(C, surface, ob); - /* Clear bake */ - canvas->flags &= ~MOD_DPAINT_BAKING; - if (!G.background) { - WM_cursor_modal_restore(win); - } - dynamicPaint_freeSurfaceData(surface); + DynamicPaintBakeJob *job = MEM_mallocN(sizeof(DynamicPaintBakeJob), "DynamicPaintBakeJob"); + job->bmain = CTX_data_main(C); + job->scene = scene; + job->ob = ob; + job->canvas = canvas; + job->surface = surface; - /* Bake was successful: - * Report for ended bake and how long it took */ - if (status) { - /* Show bake info */ - BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%.2f)", PIL_check_seconds_timer() - timer); - } - else { - if (strlen(canvas->error)) { /* If an error occurred */ - BKE_reportf(op->reports, RPT_ERROR, "Bake failed: %s", canvas->error); - } - else { /* User canceled the bake */ - BKE_report(op->reports, RPT_WARNING, "Baking canceled!"); - } - } + wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, + "Dynamic Paint Bake", WM_JOB_PROGRESS, + WM_JOB_TYPE_DPAINT_BAKE); - return status; -} + WM_jobs_customdata_set(wm_job, job, dpaint_bake_free); + WM_jobs_timer(wm_job, 0.1, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER); + WM_jobs_callbacks(wm_job, dpaint_bake_startjob, NULL, NULL, dpaint_bake_endjob); -static int dynamicpaint_bake_exec(bContext *C, wmOperator *op) -{ - /* Bake dynamic paint */ - if (!dynamicPaint_initBake(C, op)) { - return OPERATOR_CANCELLED;} + WM_set_locked_interface(CTX_wm_manager(C), true); + + /* Bake Dynamic Paint */ + WM_jobs_start(CTX_wm_manager(C), wm_job); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c index ef1e661c580..14b12497c4a 100644 --- a/source/blender/editors/physics/particle_boids.c +++ b/source/blender/editors/physics/particle_boids.c @@ -94,7 +94,7 @@ void BOID_OT_rule_add(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; - ot->prop = RNA_def_enum(ot->srna, "type", boidrule_type_items, 0, "Type", ""); + ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_boidrule_type_items, 0, "Type", ""); } static int rule_del_exec(bContext *C, wmOperator *UNUSED(op)) { diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 892545a8efd..29824a348f5 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -659,7 +659,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected 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, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); invert_m4_m4(imat, mat); } @@ -674,7 +674,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected 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, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); invert_m4_m4(imat, mat); } @@ -761,7 +761,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) psmd= psys_get_modifier(ob, psys); totpart= psys->totpart; - if (!psmd->dm) + if (!psmd->dm_final) return; tree= BLI_kdtree_new(totpart); @@ -769,7 +769,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, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); BLI_kdtree_insert(tree, p, co); @@ -783,7 +783,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); co[0] = -co[0]; @@ -898,7 +898,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) edit= psys->edit; psmd= psys_get_modifier(ob, psys); - if (!psmd->dm) + if (!psmd->dm_final) return; if (!edit->mirror_cache) @@ -911,7 +911,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, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); if (edit->mirror_cache[p] != -1) edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC; @@ -946,11 +946,11 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) psys = edit->psys; psmd = psys_get_modifier(ob, psys); - if (!psmd->dm) + if (!psmd->dm_final) return; LOOP_EDITED_POINTS { - psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles + p, hairmat); + psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles + p, hairmat); LOOP_KEYS { mul_m4_v3(hairmat, key->co); @@ -1095,7 +1095,7 @@ void recalc_lengths(PTCacheEdit *edit) /* calculate a tree for finding nearest emitter's vertice */ void recalc_emitter_field(Object *ob, ParticleSystem *psys) { - DerivedMesh *dm=psys_get_modifier(ob, psys)->dm; + DerivedMesh *dm=psys_get_modifier(ob, psys)->dm_final; PTCacheEdit *edit= psys->edit; float *vec, *nor; int i, totface /*, totvert*/; @@ -1188,12 +1188,12 @@ void update_world_cos(Object *ob, PTCacheEdit *edit) POINT_P; KEY_K; float hairmat[4][4]; - if (psys==0 || psys->edit==0 || psmd->dm==NULL) + if (psys==0 || psys->edit==0 || psmd->dm_final==NULL) return; LOOP_POINTS { if (!(psys->flag & PSYS_GLOBAL_HAIR)) - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, hairmat); + psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, hairmat); LOOP_KEYS { copy_v3_v3(key->world_co, key->co); @@ -1634,7 +1634,10 @@ static int select_random_exec(bContext *C, wmOperator *op) int p; int k; - const float randf = RNA_float_get (op->ptr, "percent") / 100.0f; + const float randfac = RNA_float_get (op->ptr, "percent") / 100.0f; + const int seed = WM_operator_properties_select_random_seed_increment_get(op); + const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT); + RNG *rng; type = RNA_enum_get(op->ptr, "type"); @@ -1644,10 +1647,12 @@ static int select_random_exec(bContext *C, wmOperator *op) ob = CTX_data_active_object(C); edit = PE_get_current(scene, ob); + rng = BLI_rng_new_srandom(seed); + switch (type) { case RAN_HAIR: LOOP_VISIBLE_POINTS { - int flag = (BLI_frand() < randf) ? SEL_SELECT : SEL_DESELECT; + int flag = ((BLI_rng_get_float(rng) < randfac) == select) ? SEL_SELECT : SEL_DESELECT; LOOP_KEYS { select_action_apply (point, key, flag); } @@ -1656,13 +1661,15 @@ static int select_random_exec(bContext *C, wmOperator *op) case RAN_POINTS: LOOP_VISIBLE_POINTS { LOOP_VISIBLE_KEYS { - int flag = (BLI_frand() < randf) ? SEL_SELECT : SEL_DESELECT; + int flag = ((BLI_rng_get_float(rng) < randfac) == select) ? SEL_SELECT : SEL_DESELECT; select_action_apply (point, key, flag); } } break; } + BLI_rng_free(rng); + PE_update_selection(data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob); @@ -1684,9 +1691,7 @@ void PARTICLE_OT_select_random(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_float_percentage (ot->srna, "percent", 50.0f, 0.0f, 100.0f, "Percent", - "Percentage (mean) of elements in randomly selected set", - 0.0f, 100.0f); + WM_operator_properties_select_random(ot); ot->prop = RNA_def_enum (ot->srna, "type", select_random_type_items, RAN_HAIR, "Type", "Select either hair or points"); } @@ -1834,7 +1839,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, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + p, mat); if (pset->selectmode==SCE_SELECT_POINT) { LOOP_KEYS { @@ -2268,7 +2273,7 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror) psmd= psys_get_modifier(ob, psys); LOOP_TAGGED_POINTS { - PE_mirror_particle(ob, psmd->dm, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); } } @@ -2348,7 +2353,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys) LOOP_POINTS { LOOP_TAGGED_KEYS { - PE_mirror_particle(ob, psmd->dm, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL); break; } } @@ -2562,7 +2567,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, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_object(ob, psmd->dm_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); @@ -2572,7 +2577,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, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); @@ -2803,13 +2808,17 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) return; psmd= psys_get_modifier(ob, psys); - if (!psmd->dm) + if (!psmd->dm_final) return; + const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly); + /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */ BKE_mesh_tessface_ensure(me); - mirrorfaces= mesh_get_x_mirror_faces(ob, NULL); + /* 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); if (!edit->mirror_cache) PE_update_mirror_cache(ob, psys); @@ -2818,11 +2827,12 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) newtotpart= psys->totpart; LOOP_VISIBLE_POINTS { pa = psys->particles + p; + if (!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, psys, pa, NULL); + PE_mirror_particle(ob, psmd->dm_final, psys, pa, NULL); continue; } else @@ -2835,6 +2845,8 @@ static void PE_mirror_x(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; + /* allocate new arrays and copy existing */ new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new"); new_points= MEM_callocN(newtotpart*sizeof(PTCacheEditPoint), "PTCacheEditPoint new"); @@ -2864,10 +2876,12 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) for (p=0, point=edit->points; p<totpart; p++, point++) { pa = psys->particles + p; + const int pa_num = pa->num; if (point->flag & PEP_HIDE) continue; - if (!(point->flag & PEP_TAG) || mirrorfaces[pa->num*2] == -1) + + if (!(point->flag & PEP_TAG) || mirrorfaces[pa_num * 2] == -1) continue; /* duplicate */ @@ -2877,27 +2891,31 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) if (point->keys) newpoint->keys= MEM_dupallocN(point->keys); /* rotate weights according to vertex index rotation */ - rotation= mirrorfaces[pa->num*2+1]; + rotation= mirrorfaces[pa_num * 2 + 1]; newpa->fuv[0] = pa->fuv[2]; newpa->fuv[1] = pa->fuv[1]; newpa->fuv[2] = pa->fuv[0]; newpa->fuv[3] = pa->fuv[3]; - while (rotation-- > 0) - if (me->mface[pa->num].v4) { + while (rotation--) { + if (mtessface[pa_num].v4) { SHIFT4(float, newpa->fuv[0], newpa->fuv[1], newpa->fuv[2], newpa->fuv[3]); } else { SHIFT3(float, newpa->fuv[0], newpa->fuv[1], newpa->fuv[2]); } + } - /* assign face inddex */ - newpa->num= mirrorfaces[pa->num*2]; - newpa->num_dmcache= psys_particle_dm_face_lookup(ob, psmd->dm, newpa->num, newpa->fuv, NULL); + /* assign face index */ + /* NOTE: mesh_get_x_mirror_faces generates -1 for non-found mirror, same as DMCACHE_NOTFOUND... */ + newpa->num = mirrorfaces[pa_num * 2]; - if ((newpa->num_dmcache != DMCACHE_NOTFOUND) && psys->part->use_modifier_stack && !psmd->dm->deformedOnly) { - newpa->num = newpa->num_dmcache; + if (use_dm_final_indices) { newpa->num_dmcache = DMCACHE_ISCHILD; } + else { + newpa->num_dmcache = psys_particle_dm_face_lookup( + psmd->dm_final, psmd->dm_deformed, newpa->num, newpa->fuv, NULL); + } /* update edit key pointers */ key= newpoint->keys; @@ -2907,7 +2925,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } /* map key positions as mirror over x axis */ - PE_mirror_particle(ob, psmd->dm, psys, pa, newpa); + PE_mirror_particle(ob, psmd->dm_final, psys, pa, newpa); newpa++; newpoint++; @@ -3355,7 +3373,7 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, totface=dm->getNumTessFaces(dm); mface=dm->getTessFaceDataArray(dm, CD_MFACE); mvert=dm->getVertDataArray(dm, CD_MVERT); - + /* lets intersect the faces */ for (i=0; i<totface; i++, mface++) { if (vert_cos) { @@ -3411,7 +3429,7 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, } } else { - if (isect_line_tri_v3(co1, co2, v1, v2, v3, &cur_d, cur_uv)) { + if (isect_line_segment_tri_v3(co1, co2, v1, v2, v3, &cur_d, cur_uv)) { if (cur_d<*min_d) { *min_d=cur_d; min_w[0] = 1.0f - cur_uv[0] - cur_uv[1]; @@ -3425,7 +3443,7 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, } } if (mface->v4) { - if (isect_line_tri_v3(co1, co2, v1, v3, v4, &cur_d, cur_uv)) { + if (isect_line_segment_tri_v3(co1, co2, v1, v3, v4, &cur_d, cur_uv)) { if (cur_d<*min_d) { *min_d=cur_d; min_w[0] = 1.0f - cur_uv[0] - cur_uv[1]; @@ -3447,6 +3465,7 @@ static int brush_add(PEData *data, short number) { Scene *scene= data->scene; Object *ob= data->ob; + DerivedMesh *dm; PTCacheEdit *edit = data->edit; ParticleSystem *psys= edit->psys; ParticleData *add_pars; @@ -3460,11 +3479,7 @@ static int brush_add(PEData *data, short number) float framestep, timestep; short size= pset->brush[PE_BRUSH_ADD].size; short size2= size*size; - DerivedMesh *dm=0; RNG *rng; - const int *index_mf_to_mpoly; - const int *index_mp_to_orig; - bool release_dm = false; invert_m4_m4(imat, ob->obmat); @@ -3482,15 +3497,13 @@ static int brush_add(PEData *data, short number) timestep= psys_get_timestep(&sim); - if (psmd->dm->deformedOnly || psys->part->use_modifier_stack) - dm = psmd->dm; + if (psys->part->use_modifier_stack || psmd->dm_final->deformedOnly) { + dm = psmd->dm_final; + } else { - dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH | CD_MASK_MFACE); - release_dm = true; + dm = psmd->dm_deformed; } - - index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + BLI_assert(dm); for (i=0; i<number; i++) { if (number>1) { @@ -3518,16 +3531,22 @@ static int brush_add(PEData *data, short number) /* 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 (index_mf_to_mpoly && index_mp_to_orig) - add_pars[n].num = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, add_pars[n].num_dmcache); - else + 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 (psys_particle_dm_face_lookup(ob, psmd->dm, add_pars[n].num_dmcache, add_pars[n].fuv, NULL) != DMCACHE_NOTFOUND) { - if (psys->part->use_modifier_stack && !psmd->dm->deformedOnly) { - add_pars[n].num = add_pars[n].num_dmcache; - add_pars[n].num_dmcache = DMCACHE_ISCHILD; - } + if (add_pars[n].num != DMCACHE_NOTFOUND) { n++; } } @@ -3562,7 +3581,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, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0, 0); + 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); BLI_kdtree_insert(tree, i, cur_co); } @@ -3606,7 +3625,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, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0, 0); + 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); maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3); maxd= ptn[maxw-1].dist; @@ -3671,7 +3690,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, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); mul_m4_v3(imat, hkey->co); } @@ -3683,9 +3702,6 @@ static int brush_add(PEData *data, short number) MEM_freeN(add_pars); - if (release_dm) - dm->release(dm); - BLI_rng_free(rng); return n; @@ -3861,7 +3877,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_PUFF: { if (edit->psys) { - data.dm= psmd->dm; + data.dm= psmd->dm_final; data.mval= mval; data.rad= pe_brush_size_get(scene, brush); data.select= selected; @@ -3917,7 +3933,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_WEIGHT: { if (edit->psys) { - data.dm= psmd->dm; + data.dm= psmd->dm_final; data.mval= mval; data.rad= pe_brush_size_get(scene, brush); @@ -4540,7 +4556,7 @@ int PE_minmax(Scene *scene, float min[3], float max[3]) LOOP_VISIBLE_POINTS { if (psys) - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, mat); + psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat); LOOP_SELECTED_KEYS { copy_v3_v3(co, key->co); @@ -4571,7 +4587,7 @@ void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, Partic int totpoint; /* no psmd->dm happens in case particle system modifier is not enabled */ - if (!(psys && psmd && psmd->dm) && !cache) + if (!(psys && psmd && psmd->dm_final) && !cache) return; if (cache && cache->flag & PTCACHE_DISK_CACHE) diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 327ce060df9..1297133e1a2 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -202,7 +202,7 @@ static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op)) ob= ptr.id.data; if (psys->part) - psys->part->id.us--; + id_us_min(&psys->part->id); psys->part = part; @@ -592,7 +592,7 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) point++; } - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat); for (k=0, key=pa->hair; k<pa->totkey; k++, key++) { mul_m4_v3(hairmat, key->co); @@ -618,7 +618,6 @@ static int disconnect_hair_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= ED_object_context(C); - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= NULL; const bool all = RNA_boolean_get(op->ptr, "all"); @@ -631,7 +630,7 @@ static int disconnect_hair_exec(bContext *C, wmOperator *op) } } else { - psys = ptr.data; + psys = psys_get_current(ob); disconnect_hair(scene, ob, psys); } @@ -650,7 +649,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) ot->exec = disconnect_hair_exec; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO; /* No REGISTER, redo does not work due to missing update, see T47750. */ RNA_def_boolean(ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh"); } @@ -676,7 +675,7 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys, float from_ob_imat[4][4], to_ob_imat[4][4]; float from_imat[4][4], to_imat[4][4]; - if (!target_psmd->dm) + if (!target_psmd->dm_final) return false; if (!psys->part || psys->part->type != PART_HAIR) return false; @@ -690,15 +689,14 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys, invert_m4_m4(from_imat, from_mat); invert_m4_m4(to_imat, to_mat); - if (target_psmd->dm->deformedOnly) { + if (target_psmd->dm_final->deformedOnly) { /* we don't want to mess up target_psmd->dm when converting to global coordinates below */ - dm = target_psmd->dm; + dm = target_psmd->dm_final; } else { - /* warning: this rebuilds target_psmd->dm! */ - dm = mesh_get_derived_deform(scene, target_ob, CD_MASK_BAREMESH | CD_MASK_MFACE); + dm = target_psmd->dm_deformed; } - target_dm = target_psmd->dm; + target_dm = target_psmd->dm_final; /* don't modify the original vertices */ dm = CDDM_copy(dm); @@ -766,7 +764,7 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys, tpa->foffset = 0.0f; tpa->num = nearest.index; - tpa->num_dmcache = psys_particle_dm_face_lookup(target_ob, target_dm, tpa->num, tpa->fuv, NULL); + tpa->num_dmcache = psys_particle_dm_face_lookup(target_dm, dm, tpa->num, tpa->fuv, NULL); } else { me = &medge[nearest.index]; @@ -864,7 +862,6 @@ static int connect_hair_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= ED_object_context(C); - PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= NULL; const bool all = RNA_boolean_get(op->ptr, "all"); bool any_connected = false; @@ -878,12 +875,13 @@ static int connect_hair_exec(bContext *C, wmOperator *op) } } else { - psys = ptr.data; + psys = psys_get_current(ob); any_connected |= connect_hair(scene, ob, psys); } if (!any_connected) { - BKE_report(op->reports, RPT_ERROR, "Can't disconnect hair if particle system modifier is disabled"); + BKE_report(op->reports, RPT_WARNING, + "No hair connected (can't connect hair if particle system modifier is disabled)"); return OPERATOR_CANCELLED; } @@ -902,7 +900,7 @@ void PARTICLE_OT_connect_hair(wmOperatorType *ot) ot->exec = connect_hair_exec; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO; /* No REGISTER, redo does not work due to missing update, see T47750. */ RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh"); } @@ -1066,9 +1064,9 @@ static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, Parti modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd); psmd->psys = psys; - psmd->dm = CDDM_copy(final_dm); - CDDM_calc_normals(psmd->dm); - DM_ensure_tessface(psmd->dm); + 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(scene, ob_to, psys, psys_from); @@ -1095,6 +1093,7 @@ static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, Parti break; default: /* should not happen */ + from_mat = to_mat = NULL; BLI_assert(false); break; } diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index 71e5e23b5f1..e81aa584586 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -30,6 +30,9 @@ */ #include <stdlib.h> +#include <string.h> + +#include "MEM_guardedalloc.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" @@ -37,6 +40,7 @@ #include "DNA_scene_types.h" #include "BKE_context.h" +#include "BKE_screen.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_particle.h" @@ -52,18 +56,9 @@ #include "physics_intern.h" -static int cache_break_test(void *UNUSED(cbd)) -{ - return (G.is_break == true); -} static int ptcache_bake_all_poll(bContext *C) { - Scene *scene= CTX_data_scene(C); - - if (!scene) - return 0; - - return 1; + return CTX_data_scene(C) != NULL; } static int ptcache_poll(bContext *C) @@ -72,15 +67,82 @@ static int ptcache_poll(bContext *C) return (ptr.data && ptr.id.data); } -static void bake_console_progress(void *UNUSED(arg), int nr) +typedef struct PointCacheJob { + void *owner; + short *stop, *do_update; + float *progress; + + PTCacheBaker *baker; +} PointCacheJob; + +static void ptcache_job_free(void *customdata) +{ + PointCacheJob *job = customdata; + MEM_freeN(job->baker); + MEM_freeN(job); +} + +static int ptcache_job_break(void *customdata) +{ + PointCacheJob *job = customdata; + + if (G.is_break) { + return 1; + } + + if (job->stop && *(job->stop)) { + return 1; + } + + return 0; +} + +static void ptcache_job_update(void *customdata, float progress, int *cancel) +{ + PointCacheJob *job = customdata; + + if (ptcache_job_break(job)) { + *cancel = 1; + } + + *(job->do_update) = true; + *(job->progress) = progress; +} + +static void ptcache_job_startjob(void *customdata, short *stop, short *do_update, float *progress) { - printf("\rbake: %3i%%", nr); - fflush(stdout); + PointCacheJob *job = customdata; + + job->stop = stop; + job->do_update = do_update; + job->progress = progress; + + G.is_break = false; + + /* XXX annoying hack: needed to prevent data corruption when changing + * scene frame in separate threads + */ + G.is_rendering = true; + BKE_spacedata_draw_locks(true); + + BKE_ptcache_bake(job->baker); + + *do_update = true; + *stop = 0; } -static void bake_console_progress_end(void *UNUSED(arg)) +static void ptcache_job_endjob(void *customdata) { - printf("\rbake: done!\n"); + PointCacheJob *job = customdata; + Scene *scene = job->baker->scene; + + G.is_rendering = false; + BKE_spacedata_draw_locks(false); + + WM_set_locked_interface(G.main->wm.first, false); + + WM_main_add_notifier(NC_SCENE | ND_FRAME, scene); + WM_main_add_notifier(NC_OBJECT | ND_POINTCACHE, job->baker->pid.ob); } static void ptcache_free_bake(PointCache *cache) @@ -97,44 +159,98 @@ static void ptcache_free_bake(PointCache *cache) } } -static int ptcache_bake_all_exec(bContext *C, wmOperator *op) +static PTCacheBaker *ptcache_baker_create(bContext *C, wmOperator *op, bool all) { - Main *bmain = CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - wmWindow *win = G.background ? NULL : CTX_wm_window(C); - PTCacheBaker baker; - - baker.main = bmain; - baker.scene = scene; - baker.pid = NULL; - baker.bake = RNA_boolean_get(op->ptr, "bake"); - baker.render = 0; - baker.anim_init = 0; - baker.quick_step = 1; - baker.break_test = cache_break_test; - baker.break_data = NULL; - - /* Disabled for now as this doesn't work properly, - * and pointcache baking will be reimplemented with - * the job system soon anyways. */ - if (win) { - baker.progressbar = (void (*)(void *, int))WM_cursor_time; - baker.progressend = (void (*)(void *))WM_cursor_modal_restore; - baker.progresscontext = win; - } - else { - baker.progressbar = bake_console_progress; - baker.progressend = bake_console_progress_end; - baker.progresscontext = NULL; + PTCacheBaker *baker = MEM_callocN(sizeof(PTCacheBaker), "PTCacheBaker"); + + baker->main = CTX_data_main(C); + baker->scene = CTX_data_scene(C); + baker->bake = RNA_boolean_get(op->ptr, "bake"); + baker->render = 0; + baker->anim_init = 0; + baker->quick_step = 1; + + if (!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(&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); } - BKE_ptcache_bake(&baker); + return baker; +} - WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); - WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, NULL); +static int ptcache_bake_exec(bContext *C, wmOperator *op) +{ + bool all = STREQ(op->type->idname, "PTCACHE_OT_bake_all"); + + PTCacheBaker *baker = ptcache_baker_create(C, op, all); + BKE_ptcache_bake(baker); + MEM_freeN(baker); return OPERATOR_FINISHED; } + +static int ptcache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + bool all = STREQ(op->type->idname, "PTCACHE_OT_bake_all"); + + PointCacheJob *job = MEM_mallocN(sizeof(PointCacheJob), "PointCacheJob"); + job->baker = ptcache_baker_create(C, op, all); + job->baker->bake_job = job; + job->baker->update_progress = ptcache_job_update; + + wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_data_scene(C), + "Point Cache", WM_JOB_PROGRESS, WM_JOB_TYPE_POINTCACHE); + + WM_jobs_customdata_set(wm_job, job, ptcache_job_free); + WM_jobs_timer(wm_job, 0.1, NC_OBJECT | ND_POINTCACHE, NC_OBJECT | ND_POINTCACHE); + WM_jobs_callbacks(wm_job, ptcache_job_startjob, NULL, NULL, ptcache_job_endjob); + + WM_set_locked_interface(CTX_wm_manager(C), true); + + WM_jobs_start(CTX_wm_manager(C), wm_job); + + WM_event_add_modal_handler(C, op); + + /* we must run modal until the bake job is done, otherwise the undo push + * happens before the job ends, which can lead to race conditions between + * the baking and file writing code */ + return OPERATOR_RUNNING_MODAL; +} + +static int ptcache_bake_modal(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + Scene *scene = (Scene *) op->customdata; + + /* no running blender, remove handler and pass through */ + if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_POINTCACHE)) { + return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; + } + + return OPERATOR_PASS_THROUGH; +} + +static void ptcache_bake_cancel(bContext *C, wmOperator *op) +{ + wmWindowManager *wm = CTX_wm_manager(C); + Scene *scene = (Scene *) op->customdata; + + /* kill on cancel, because job is using op->reports */ + WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_POINTCACHE); +} + static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); @@ -167,7 +283,10 @@ void PTCACHE_OT_bake_all(wmOperatorType *ot) ot->idname = "PTCACHE_OT_bake_all"; /* api callbacks */ - ot->exec = ptcache_bake_all_exec; + ot->exec = ptcache_bake_exec; + ot->invoke = ptcache_bake_invoke; + ot->modal = ptcache_bake_modal; + ot->cancel = ptcache_bake_cancel; ot->poll = ptcache_bake_all_poll; /* flags */ @@ -189,59 +308,7 @@ void PTCACHE_OT_free_bake_all(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } -static int ptcache_bake_exec(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - wmWindow *win = G.background ? NULL : CTX_wm_window(C); - PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); - Object *ob= ptr.id.data; - PointCache *cache= ptr.data; - PTCacheBaker baker; - PTCacheID *pid; - ListBase pidlist; - - BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); - - for (pid=pidlist.first; pid; pid=pid->next) { - if (pid->cache == cache) - break; - } - baker.main = bmain; - baker.scene = scene; - baker.pid = pid; - baker.bake = RNA_boolean_get(op->ptr, "bake"); - baker.render = 0; - baker.anim_init = 0; - baker.quick_step = 1; - baker.break_test = cache_break_test; - baker.break_data = NULL; - - /* Disabled for now as this doesn't work properly, - * and pointcache baking will be reimplemented with - * the job system soon anyways. */ - if (win) { - baker.progressbar = (void (*)(void *, int))WM_cursor_time; - baker.progressend = (void (*)(void *))WM_cursor_modal_restore; - baker.progresscontext = win; - } - else { - printf("\n"); /* empty first line before console reports */ - baker.progressbar = bake_console_progress; - baker.progressend = bake_console_progress_end; - baker.progresscontext = NULL; - } - - BKE_ptcache_bake(&baker); - - BLI_freelistN(&pidlist); - - WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); - WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); - - return OPERATOR_FINISHED; -} static int ptcache_free_bake_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); @@ -275,6 +342,9 @@ void PTCACHE_OT_bake(wmOperatorType *ot) /* api callbacks */ ot->exec = ptcache_bake_exec; + ot->invoke = ptcache_bake_invoke; + ot->modal = ptcache_bake_modal; + ot->cancel = ptcache_bake_cancel; ot->poll = ptcache_poll; /* flags */ @@ -377,7 +447,7 @@ void PTCACHE_OT_add(wmOperatorType *ot) /* api callbacks */ ot->exec = ptcache_add_new_exec; - ot->poll = ptcache_poll; // ptcache_bake_all_poll; + ot->poll = ptcache_poll; /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c index 85b059d5574..f95599592b2 100644 --- a/source/blender/editors/physics/rigidbody_constraint.c +++ b/source/blender/editors/physics/rigidbody_constraint.c @@ -153,7 +153,7 @@ void RIGIDBODY_OT_constraint_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_constraint_type_items, RBC_TYPE_FIXED, "Rigid Body Constraint Type", ""); + ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_rigidbody_constraint_type_items, RBC_TYPE_FIXED, "Rigid Body Constraint Type", ""); } /* ************ Remove Rigid Body Constraint ************** */ diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c index 949084973cf..26d8af82b2d 100644 --- a/source/blender/editors/physics/rigidbody_object.c +++ b/source/blender/editors/physics/rigidbody_object.c @@ -179,7 +179,7 @@ void RIGIDBODY_OT_object_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_object_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", ""); + ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_rigidbody_object_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", ""); } /* ************ Remove Rigid Body ************** */ @@ -270,7 +270,7 @@ void RIGIDBODY_OT_objects_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_object_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", ""); + ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_rigidbody_object_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", ""); } /* ************ Remove Rigid Bodies ************** */ @@ -374,7 +374,7 @@ void RIGIDBODY_OT_shape_change(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_object_shape_items, RB_SHAPE_TRIMESH, "Rigid Body Shape", ""); + ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_rigidbody_object_shape_items, RB_SHAPE_TRIMESH, "Rigid Body Shape", ""); } /* ************ Calculate Mass ************** */ diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c index 0bd9ec5f4cd..bd8505fcf15 100644 --- a/source/blender/editors/physics/rigidbody_world.c +++ b/source/blender/editors/physics/rigidbody_world.c @@ -195,5 +195,7 @@ void RIGIDBODY_OT_world_export(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER, FILE_SPECIAL, FILE_SAVE, FILE_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); + WM_operator_properties_filesel( + ot, FILE_TYPE_FOLDER, FILE_SPECIAL, FILE_SAVE, + FILE_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); } |