diff options
author | Sebastián Barschkis <sebbas@sebbas.org> | 2020-04-19 21:15:57 +0300 |
---|---|---|
committer | Sebastián Barschkis <sebbas@sebbas.org> | 2020-04-22 17:18:13 +0300 |
commit | fdea3dd7e7109a814561e4a83ff3331badf04e24 (patch) | |
tree | 676f0cea8f1b3b944aa9cf38710997dbfdfec989 | |
parent | d19277c72f1a5acc08eefde9c6c05e2cd4358205 (diff) |
Fluid: Fix for inconsistent behavior with flow and effector objects
Fixes issue with flow and effector objects which were not being used after resuming a bake job.
This issue has been reported in T75729 and T75758.
-rw-r--r-- | intern/mantaflow/extern/manta_fluid_API.h | 1 | ||||
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.cpp | 11 | ||||
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.h | 5 | ||||
-rw-r--r-- | intern/mantaflow/intern/manta_fluid_API.cpp | 4 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/fluid_script.h | 12 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/liquid_script.h | 6 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/smoke_script.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fluid.c | 457 |
8 files changed, 273 insertions, 224 deletions
diff --git a/intern/mantaflow/extern/manta_fluid_API.h b/intern/mantaflow/extern/manta_fluid_API.h index 85cc04b4a52..7825ad14d7d 100644 --- a/intern/mantaflow/extern/manta_fluid_API.h +++ b/intern/mantaflow/extern/manta_fluid_API.h @@ -107,6 +107,7 @@ float *manta_get_phistatic_in(struct MANTA *fluid); float *manta_get_phiobs_in(struct MANTA *fluid); float *manta_get_phiobsstatic_in(struct MANTA *fluid); float *manta_get_phiout_in(struct MANTA *fluid); +float *manta_get_phioutstatic_in(struct MANTA *fluid); /* Smoke functions */ void manta_smoke_export_script(struct MANTA *smoke, struct FluidModifierData *mmd); diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index 539e3080c54..a56ce4c1f60 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -141,6 +141,7 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID) mPhiIn = nullptr; mPhiStaticIn = nullptr; mPhiOutIn = nullptr; + mPhiOutStaticIn = nullptr; mPhi = nullptr; // Mesh @@ -1926,6 +1927,7 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd) bool obstacle = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE; bool guiding = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE; bool invel = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL; + bool outflow = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW; std::string manta_script; @@ -1968,6 +1970,8 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd) manta_script += fluid_alloc_obstacle; if (invel) manta_script += fluid_alloc_invel; + if (outflow) + manta_script += fluid_alloc_outflow; // Noise field if (noise) @@ -2032,6 +2036,7 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) bool fractions = mmd->domain->flags & FLUID_DOMAIN_USE_FRACTIONS; bool guiding = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE; bool invel = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL; + bool outflow = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW; std::string manta_script; @@ -2070,6 +2075,8 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) manta_script += fluid_alloc_fractions; if (invel) manta_script += fluid_alloc_invel; + if (outflow) + manta_script += fluid_alloc_outflow; // Domain init manta_script += header_gridinit + liquid_init_phi; @@ -3119,6 +3126,8 @@ void MANTA::updatePointers() if (mUsingOutflow) { mPhiOutIn = (float *)pyObjectToPointer(callPythonFunction("phiOutIn" + solver_ext, func)); + mPhiOutStaticIn = (float *)pyObjectToPointer( + callPythonFunction("phiOutSIn" + solver_ext, func)); } if (mUsingObstacle) { mPhiObsIn = (float *)pyObjectToPointer(callPythonFunction("phiObsIn" + solver_ext, func)); @@ -3230,7 +3239,7 @@ bool MANTA::hasConfig(FluidModifierData *mmd, int framenr) bool MANTA::hasData(FluidModifierData *mmd, int framenr) { - std::string filename = (mUsingSmoke) ? FLUID_DOMAIN_FILE_DENSITY : FLUID_DOMAIN_FILE_PHI; + std::string filename = (mUsingSmoke) ? FLUID_DOMAIN_FILE_DENSITY : FLUID_DOMAIN_FILE_PP; std::string extension = getCacheFileEnding(mmd->domain->cache_data_format); return BLI_exists(getFile(mmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str()); } diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h index caac63d8e39..21946431f28 100644 --- a/intern/mantaflow/intern/MANTA_main.h +++ b/intern/mantaflow/intern/MANTA_main.h @@ -405,6 +405,10 @@ struct MANTA { { return mPhiOutIn; } + inline float *getPhiOutStaticIn() + { + return mPhiOutStaticIn; + } inline float *getPhi() { return mPhi; @@ -844,6 +848,7 @@ struct MANTA { float *mPhiObsStaticIn; float *mPhiGuideIn; float *mPhiOutIn; + float *mPhiOutStaticIn; float *mPhi; // Mesh fields diff --git a/intern/mantaflow/intern/manta_fluid_API.cpp b/intern/mantaflow/intern/manta_fluid_API.cpp index b4582051c3c..49bc224b3fa 100644 --- a/intern/mantaflow/intern/manta_fluid_API.cpp +++ b/intern/mantaflow/intern/manta_fluid_API.cpp @@ -390,6 +390,10 @@ float *manta_get_phiout_in(MANTA *fluid) { return fluid->getPhiOutIn(); } +float *manta_get_phioutstatic_in(MANTA *fluid) +{ + return fluid->getPhiOutStaticIn(); +} /* Smoke functions */ void manta_smoke_export_script(MANTA *smoke, FluidModifierData *mmd) diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h index e81a44109ef..dd2111db7d7 100644 --- a/intern/mantaflow/intern/strings/fluid_script.h +++ b/intern/mantaflow/intern/strings/fluid_script.h @@ -261,7 +261,7 @@ const std::string fluid_alloc_obstacle = "\n\ mantaMsg('Allocating obstacle data')\n\ numObs_s$ID$ = s$ID$.create(RealGrid)\n\ -phiObsSIn_s$ID$ = s$ID$.create(LevelsetGrid) # helper for static obstacles\n\ +phiObsSIn_s$ID$ = s$ID$.create(LevelsetGrid) # helper for static obstacle objects\n\ phiObsIn_s$ID$ = s$ID$.create(LevelsetGrid)\n\ obvel_s$ID$ = s$ID$.create(MACGrid)\n\ obvelC_s$ID$ = s$ID$.create(Vec3Grid)\n\ @@ -311,7 +311,15 @@ z_invel_s$ID$ = s$ID$.create(RealGrid)\n"; const std::string fluid_alloc_outflow = "\n\ mantaMsg('Allocating outflow data')\n\ -phiOutIn_s$ID$ = s$ID$.create(LevelsetGrid)\n"; +phiOutSIn_s$ID$ = s$ID$.create(LevelsetGrid) # helper for static outflow objects\n\ +phiOutIn_s$ID$ = s$ID$.create(LevelsetGrid)\n\ +\n\ +# Set some initial values\n\ +phiOutSIn_s$ID$.setConst(9999)\n\ +phiOutIn_s$ID$.setConst(9999)\n\ +\n\ +if 'fluid_data_dict_resume_s$ID$' in globals():\n\ + fluid_data_dict_resume_s$ID$.update(phiOutIn=phiOutIn_s$ID$)\n"; ////////////////////////////////////////////////////////////////////// // PRE / POST STEP diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h index 34994f115d7..f20b218427c 100644 --- a/intern/mantaflow/intern/strings/liquid_script.h +++ b/intern/mantaflow/intern/strings/liquid_script.h @@ -191,6 +191,7 @@ def liquid_adaptive_step_$ID$(framenr):\n\ phi_s$ID$.join(phiIn_s$ID$)\n\ \n\ if using_outflow_s$ID$:\n\ + phiOutIn_s$ID$.join(phiOutSIn_s$ID$) # Join static outflow map\n\ phiOut_s$ID$.join(phiOutIn_s$ID$)\n\ \n\ if using_fractions_s$ID$:\n\ @@ -206,6 +207,9 @@ def liquid_adaptive_step_$ID$(framenr):\n\ extrapolateVec3Simple(vel=invelC_s$ID$, phi=phiIn_s$ID$, distance=6, inside=True)\n\ resampleVec3ToMac(source=invelC_s$ID$, target=invel_s$ID$)\n\ pVel_pp$ID$.setSource(invel_s$ID$, isMAC=True)\n\ + # ensure that pvel has vel as source (important when resuming bake jobs)\n\ + else:\n\ + pVel_pp$ID$.setSource(vel_s$ID$, isMAC=True)\n\ \n\ sampleLevelsetWithParticles(phi=phiIn_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, discretization=particleNumber_s$ID$, randomness=randomness_s$ID$)\n\ flags_s$ID$.updateFromLevelset(phi_s$ID$)\n\ @@ -363,7 +367,7 @@ def liquid_step_particles_$ID$():\n\ interpolateGrid(target=phiOut_sp$ID$, source=phiOut_s$ID$)\n\ \n\ # phiIn not needed, bwidth to 0 because we are omitting flags.initDomain()\n\ - setObstacleFlags(flags=flags_sp$ID$, phiObs=phiObs_sp$ID$, phiOut=None, phiIn=None, boundaryWidth=0)\n\ + setObstacleFlags(flags=flags_sp$ID$, phiObs=phiObs_sp$ID$, phiOut=phiOut_sp$ID$, phiIn=None, boundaryWidth=0)\n\ flags_sp$ID$.updateFromLevelset(levelset=phi_sp$ID$)\n\ \n\ # Actual secondary particle simulation\n\ diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h index cb651eb40b3..146106fd147 100644 --- a/intern/mantaflow/intern/strings/smoke_script.h +++ b/intern/mantaflow/intern/strings/smoke_script.h @@ -296,6 +296,7 @@ def smoke_adaptive_step_$ID$(framenr):\n\ extrapolateLsSimple(phi=phiIn_s$ID$, distance=3, inside=False)\n\ \n\ if using_outflow_s$ID$:\n\ + phiOutIn_s$ID$.join(phiOutSIn_s$ID$) # Join static outflow map\n\ phiOut_s$ID$.join(phiOutIn_s$ID$)\n\ \n\ setObstacleFlags(flags=flags_s$ID$, phiObs=phiObs_s$ID$, phiOut=phiOut_s$ID$, phiIn=phiIn_s$ID$, boundaryWidth=1)\n\ diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 578a6a13bb7..08b5b788afd 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -1192,32 +1192,50 @@ static void update_obstacleflags(FluidDomainSettings *mds, mds->active_fields = active_fields; } -static void update_obstacles(Depsgraph *depsgraph, - Scene *scene, - Object *ob, - FluidDomainSettings *mds, - float time_per_frame, - float frame_length, - int frame, - float dt) +static bool escape_effectorobject(Object *flowobj, + FluidDomainSettings *mds, + FluidEffectorSettings *mes, + int frame) { - FluidObjectBB *bb_maps = NULL; - Object **effecobjs = NULL; - uint numeffecobjs = 0, effec_index = 0; - bool is_first_frame = (frame == mds->cache_frame_start); + bool is_static = is_static_object(flowobj); - effecobjs = BKE_collision_objects_create( - depsgraph, ob, mds->effector_group, &numeffecobjs, eModifierType_Fluid); + bool use_effector = (mes->flags & FLUID_EFFECTOR_USE_EFFEC); - /* Update all effector related flags and ensure that corresponding grids get initialized. */ - update_obstacleflags(mds, ob, effecobjs, numeffecobjs); - ensure_obstaclefields(mds); + bool is_resume = (mds->cache_frame_pause_data == frame); + bool is_adaptive = (mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN); + bool is_first_frame = (frame == mds->cache_frame_start); - /* Initialize effector maps for each flow. */ - bb_maps = MEM_callocN(sizeof(struct FluidObjectBB) * numeffecobjs, "fluid_effector_bb_maps"); + /* Cannot use static mode with adaptive domain. + * The adaptive domain might expand and only later discover the static object. */ + if (is_adaptive) { + is_static = false; + } + /* Skip flow objects with disabled inflow flag. */ + if (!use_effector) { + return true; + } + /* Skip static effector objects after initial frame. */ + if (is_static && !is_first_frame && !is_resume) { + return true; + } + return false; +} + +static void compute_obstaclesemission(Scene *scene, + FluidObjectBB *bb_maps, + struct Depsgraph *depsgraph, + float dt, + Object **effecobjs, + int frame, + float frame_length, + FluidDomainSettings *mds, + uint numeffecobjs, + float time_per_frame) +{ + bool is_first_frame = (frame == mds->cache_frame_start); /* Prepare effector maps. */ - for (effec_index = 0; effec_index < numeffecobjs; effec_index++) { + for (int effec_index = 0; effec_index < numeffecobjs; effec_index++) { Object *effecobj = effecobjs[effec_index]; FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(effecobj, eModifierType_Fluid); @@ -1233,20 +1251,8 @@ static void update_obstacles(Depsgraph *depsgraph, int subframes = mes->subframes; FluidObjectBB *bb = &bb_maps[effec_index]; - bool is_static = is_static_object(effecobj); - /* Cannot use static mode with adaptive domain. - * The adaptive domain might expand and only later in the simulations discover the static - * object. */ - if (mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) { - is_static = false; - } - - /* Optimization: Static objects don't need emission computation after first frame. */ - if (is_static && !is_first_frame) { - continue; - } - /* Optimization: Skip effector objects with disabled effec flag. */ - if ((mes->flags & FLUID_EFFECTOR_USE_EFFEC) == 0) { + /* Optimization: Skip this object under certain conditions. */ + if (escape_effectorobject(effecobj, mds, mes, frame)) { continue; } @@ -1314,6 +1320,44 @@ static void update_obstacles(Depsgraph *depsgraph, } } } +} + +static void update_obstacles(Depsgraph *depsgraph, + Scene *scene, + Object *ob, + FluidDomainSettings *mds, + float time_per_frame, + float frame_length, + int frame, + float dt) +{ + FluidObjectBB *bb_maps = NULL; + Object **effecobjs = NULL; + uint numeffecobjs = 0; + bool is_resume = (mds->cache_frame_pause_data == frame); + bool is_first_frame = (frame == mds->cache_frame_start); + + effecobjs = BKE_collision_objects_create( + depsgraph, ob, mds->effector_group, &numeffecobjs, eModifierType_Fluid); + + /* Update all effector related flags and ensure that corresponding grids get initialized. */ + update_obstacleflags(mds, ob, effecobjs, numeffecobjs); + ensure_obstaclefields(mds); + + /* Allocate effector map for each effector object. */ + bb_maps = MEM_callocN(sizeof(struct FluidObjectBB) * numeffecobjs, "fluid_effector_bb_maps"); + + /* Initialize effector map for each effector object. */ + compute_obstaclesemission(scene, + bb_maps, + depsgraph, + dt, + effecobjs, + frame, + frame_length, + mds, + numeffecobjs, + time_per_frame); float *vel_x = manta_get_ob_velocity_x(mds->fluid); float *vel_y = manta_get_ob_velocity_y(mds->fluid); @@ -1364,7 +1408,7 @@ static void update_obstacles(Depsgraph *depsgraph, } /* Prepare grids from effector objects. */ - for (effec_index = 0; effec_index < numeffecobjs; effec_index++) { + for (int effec_index = 0; effec_index < numeffecobjs; effec_index++) { Object *effecobj = effecobjs[effec_index]; FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(effecobj, eModifierType_Fluid); @@ -1374,18 +1418,11 @@ static void update_obstacles(Depsgraph *depsgraph, continue; } - bool is_static = is_static_object(effecobj); /* Cannot use static mode with adaptive domain. * The adaptive domain might expand and only later in the simulations discover the static * object. */ - if (mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) { - is_static = false; - } - - /* Optimization: Static objects don't need emission application after first frame. */ - if (is_static && !is_first_frame) { - continue; - } + bool is_static = is_static_object(effecobj) && + ((mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) == 0); /* Check for initialized effector object. */ if ((mmd2->type & MOD_FLUID_TYPE_EFFEC) && mmd2->effector) { @@ -1425,53 +1462,35 @@ static void update_obstacles(Depsgraph *depsgraph, continue; } - /* Apply static effectors to obstacle grid. */ - if (is_static && is_first_frame) { - if (mes->type == FLUID_EFFECTOR_TYPE_COLLISION) { - apply_effector_fields(mes, - d_index, - distance_map[e_index], - phi_obsstatic_in, - numobjs_map[e_index], - num_obstacles, - 0.0f, - NULL, - 0.0f, - NULL, - 0.0f, - NULL); - } + if (mes->type == FLUID_EFFECTOR_TYPE_COLLISION) { + float *levelset = ((is_first_frame || is_resume) && is_static) ? phi_obsstatic_in : + phi_obs_in; + apply_effector_fields(mes, + d_index, + distance_map[e_index], + levelset, + numobjs_map[e_index], + num_obstacles, + velocity_map[e_index * 3], + vel_x, + velocity_map[e_index * 3 + 1], + vel_y, + velocity_map[e_index * 3 + 2], + vel_z); } - /* Apply moving effectors to obstacle grid. */ - else if (!is_static) { - if (mes->type == FLUID_EFFECTOR_TYPE_COLLISION) { - apply_effector_fields(mes, - d_index, - distance_map[e_index], - phi_obs_in, - numobjs_map[e_index], - num_obstacles, - velocity_map[e_index * 3], - vel_x, - velocity_map[e_index * 3 + 1], - vel_y, - velocity_map[e_index * 3 + 2], - vel_z); - } - if (mes->type == FLUID_EFFECTOR_TYPE_GUIDE) { - apply_effector_fields(mes, - d_index, - distance_map[e_index], - phi_guide_in, - numobjs_map[e_index], - num_guides, - velocity_map[e_index * 3], - vel_x_guide, - velocity_map[e_index * 3 + 1], - vel_y_guide, - velocity_map[e_index * 3 + 2], - vel_z_guide); - } + if (mes->type == FLUID_EFFECTOR_TYPE_GUIDE) { + apply_effector_fields(mes, + d_index, + distance_map[e_index], + phi_guide_in, + numobjs_map[e_index], + num_guides, + velocity_map[e_index * 3], + vel_x_guide, + velocity_map[e_index * 3 + 1], + vel_y_guide, + velocity_map[e_index * 3 + 2], + vel_z_guide); } } } @@ -2468,12 +2487,13 @@ BLI_INLINE void apply_outflow_fields(int index, float *color_b, float *phiout) { - /* determine outflow cells - phiout used in smoke and liquids */ + /* Set levelset value for liquid inflow. + * Ensure that distance value is "joined" into the levelset. */ if (phiout) { - phiout[index] = distance_value; + phiout[index] = MIN2(distance_value, phiout[index]); } - /* set smoke outflow */ + /* Set smoke outflow, i.e. reset cell to zero. */ if (density) { density[index] = 0.0f; } @@ -2702,32 +2722,68 @@ static void update_flowsflags(FluidDomainSettings *mds, mds->active_fields = active_fields; } -static void update_flowsfluids(struct Depsgraph *depsgraph, - Scene *scene, - Object *ob, +static bool escape_flowsobject(Object *flowobj, FluidDomainSettings *mds, - float time_per_frame, - float frame_length, - int frame, - float dt) + FluidFlowSettings *mfs, + int frame) { - FluidObjectBB *bb_maps = NULL; - Object **flowobjs = NULL; - uint numflowobj = 0, flow_index = 0; - bool is_first_frame = (frame == mds->cache_frame_start); - - flowobjs = BKE_collision_objects_create( - depsgraph, ob, mds->fluid_group, &numflowobj, eModifierType_Fluid); - - /* Update all flow related flags and ensure that corresponding grids get initialized. */ - update_flowsflags(mds, ob, flowobjs, numflowobj); - ensure_flowsfields(mds); + bool use_velocity = (mfs->flags & FLUID_FLOW_INITVELOCITY); + bool is_static = is_static_object(flowobj); + + bool liquid_flow = mfs->type == FLUID_FLOW_TYPE_LIQUID; + bool gas_flow = (mfs->type == FLUID_FLOW_TYPE_SMOKE || mfs->type == FLUID_FLOW_TYPE_FIRE || + mfs->type == FLUID_FLOW_TYPE_SMOKEFIRE); + bool is_geometry = (mfs->behavior == FLUID_FLOW_BEHAVIOR_GEOMETRY); + bool is_inflow = (mfs->behavior == FLUID_FLOW_BEHAVIOR_INFLOW); + bool is_outflow = (mfs->behavior == FLUID_FLOW_BEHAVIOR_OUTFLOW); + bool use_flow = (mfs->flags & FLUID_FLOW_USE_INFLOW); + + bool liquid_domain = mds->type == FLUID_DOMAIN_TYPE_LIQUID; + bool gas_domain = mds->type == FLUID_DOMAIN_TYPE_GAS; + bool is_adaptive = (mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN); + bool is_resume = (mds->cache_frame_pause_data == frame); + bool is_first_frame = (mds->cache_frame_start == frame); + + /* Cannot use static mode with adaptive domain. + * The adaptive domain might expand and only later discover the static object. */ + if (is_adaptive) { + is_static = false; + } + /* Skip flow objects with disabled inflow flag. */ + if ((is_inflow || is_outflow) && !use_flow) { + return true; + } + /* No need to compute emission value if it won't be applied. */ + if (liquid_flow && is_geometry && !is_first_frame) { + return true; + } + /* Skip flow object if it does not "belong" to this domain type. */ + if ((liquid_flow && gas_domain) || (gas_flow && liquid_domain)) { + return true; + } + /* Optimization: Static liquid flow objects don't need emission after first frame. + * TODO (sebbas): Also do not use static mode if initial velocities are enabled. */ + if (liquid_flow && is_static && !is_first_frame && !is_resume && !use_velocity) { + return true; + } + return false; +} - /* Initialize emission maps for each flow. */ - bb_maps = MEM_callocN(sizeof(struct FluidObjectBB) * numflowobj, "fluid_flow_bb_maps"); +static void compute_flowsemission(Scene *scene, + FluidObjectBB *bb_maps, + struct Depsgraph *depsgraph, + float dt, + Object **flowobjs, + int frame, + float frame_length, + FluidDomainSettings *mds, + uint numflowobjs, + float time_per_frame) +{ + bool is_first_frame = (frame == mds->cache_frame_start); /* Prepare flow emission maps. */ - for (flow_index = 0; flow_index < numflowobj; flow_index++) { + for (int flow_index = 0; flow_index < numflowobjs; flow_index++) { Object *flowobj = flowobjs[flow_index]; FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(flowobj, eModifierType_Fluid); @@ -2743,37 +2799,8 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, int subframes = mfs->subframes; FluidObjectBB *bb = &bb_maps[flow_index]; - bool use_velocity = mfs->flags & FLUID_FLOW_INITVELOCITY; - bool is_static = is_static_object(flowobj); - /* Cannot use static mode with adaptive domain. - * The adaptive domain might expand and only later in the simulations discover the static - * object. */ - if (mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) { - is_static = false; - } - - /* Optimization: Skip flow objects with disabled inflow flag. */ - if (mfs->behavior == FLUID_FLOW_BEHAVIOR_INFLOW && - (mfs->flags & FLUID_FLOW_USE_INFLOW) == 0) { - continue; - } - /* Optimization: No need to compute emission value if it won't be applied. */ - if (mfs->behavior == FLUID_FLOW_BEHAVIOR_GEOMETRY && !is_first_frame) { - continue; - } - /* Optimization: Skip flow object if it does not "belong" to this domain type. */ - if (mfs->type == FLUID_FLOW_TYPE_LIQUID && mds->type == FLUID_DOMAIN_TYPE_GAS) { - continue; - } - if ((mfs->type == FLUID_FLOW_TYPE_SMOKE || mfs->type == FLUID_FLOW_TYPE_FIRE || - mfs->type == FLUID_FLOW_TYPE_SMOKEFIRE) && - mds->type == FLUID_DOMAIN_TYPE_LIQUID) { - continue; - } - /* Optimization: Static liquid flow objects don't need emission computation after first - * frame. - * TODO (sebbas): Also do not use static mode if initial velocities are enabled. */ - if (mfs->type == FLUID_FLOW_TYPE_LIQUID && is_static && !is_first_frame && !use_velocity) { + /* Optimization: Skip this object under certain conditions. */ + if (escape_flowsobject(flowobj, mds, mfs, frame)) { continue; } @@ -2862,15 +2889,55 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, frame_length, dt); # endif +} + +static void update_flowsfluids(struct Depsgraph *depsgraph, + Scene *scene, + Object *ob, + FluidDomainSettings *mds, + float time_per_frame, + float frame_length, + int frame, + float dt) +{ + FluidObjectBB *bb_maps = NULL; + Object **flowobjs = NULL; + uint numflowobjs = 0; + bool is_resume = (mds->cache_frame_pause_data == frame); + bool is_first_frame = (mds->cache_frame_start == frame); + + flowobjs = BKE_collision_objects_create( + depsgraph, ob, mds->fluid_group, &numflowobjs, eModifierType_Fluid); + + /* Update all flow related flags and ensure that corresponding grids get initialized. */ + update_flowsflags(mds, ob, flowobjs, numflowobjs); + ensure_flowsfields(mds); + + /* Allocate emission map for each flow object. */ + bb_maps = MEM_callocN(sizeof(struct FluidObjectBB) * numflowobjs, "fluid_flow_bb_maps"); + + /* Initialize emission map for each flow object. */ + compute_flowsemission(scene, + bb_maps, + depsgraph, + dt, + flowobjs, + frame, + frame_length, + mds, + numflowobjs, + time_per_frame); /* Adjust domain size if needed. Only do this once for every frame. */ if (mds->type == FLUID_DOMAIN_TYPE_GAS && mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) { - adaptive_domain_adjust(mds, ob, bb_maps, numflowobj, dt); + adaptive_domain_adjust(mds, ob, bb_maps, numflowobjs, dt); } float *phi_in = manta_get_phi_in(mds->fluid); float *phistatic_in = manta_get_phistatic_in(mds->fluid); float *phiout_in = manta_get_phiout_in(mds->fluid); + float *phioutstatic_in = manta_get_phioutstatic_in(mds->fluid); + float *density = manta_smoke_get_density(mds->fluid); float *color_r = manta_smoke_get_color_r(mds->fluid); float *color_g = manta_smoke_get_color_g(mds->fluid); @@ -2893,16 +2960,18 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, float *velz_initial = manta_get_in_velocity_z(mds->fluid); uint z; - bool use_adaptivedomain = (mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN); - /* Grid reset before writing again. */ for (z = 0; z < mds->res[0] * mds->res[1] * mds->res[2]; z++) { + /* Only reset static phi on first frame, dynamic phi gets reset every time. */ + if (phistatic_in && is_first_frame) { + phistatic_in[z] = PHI_MAX; + } if (phi_in) { phi_in[z] = PHI_MAX; } - /* Only reset static inflow on first frame. Only use static inflow without adaptive domains. */ - if (phistatic_in && (is_first_frame || use_adaptivedomain)) { - phistatic_in[z] = PHI_MAX; + /* Only reset static phi on first frame, dynamic phi gets reset every time. */ + if (phioutstatic_in && is_first_frame) { + phioutstatic_in[z] = PHI_MAX; } if (phiout_in) { phiout_in[z] = PHI_MAX; @@ -2934,7 +3003,7 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, } /* Apply emission data for every flow object. */ - for (flow_index = 0; flow_index < numflowobj; flow_index++) { + for (int flow_index = 0; flow_index < numflowobjs; flow_index++) { Object *flowobj = flowobjs[flow_index]; FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(flowobj, eModifierType_Fluid); @@ -2948,38 +3017,11 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, if ((mmd2->type & MOD_FLUID_TYPE_FLOW) && mmd2->flow) { FluidFlowSettings *mfs = mmd2->flow; - bool use_velocity = mfs->flags & FLUID_FLOW_INITVELOCITY; - bool use_inflow = (mfs->flags & FLUID_FLOW_USE_INFLOW); - bool is_liquid = (mfs->type == FLUID_FLOW_TYPE_LIQUID); bool is_inflow = (mfs->behavior == FLUID_FLOW_BEHAVIOR_INFLOW); bool is_geometry = (mfs->behavior == FLUID_FLOW_BEHAVIOR_GEOMETRY); bool is_outflow = (mfs->behavior == FLUID_FLOW_BEHAVIOR_OUTFLOW); - - bool is_static = is_static_object(flowobj); - /* Cannot use static mode with adaptive domain. - * The adaptive domain might expand and only later in the simulations discover the static - * object. */ - if (mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) { - is_static = false; - } - - /* Optimization: Skip flow objects with disabled flow flag. */ - if (is_inflow && !use_inflow) { - continue; - } - /* Optimization: Liquid objects don't always need emission application after first frame. */ - if (is_liquid && !is_first_frame) { - - /* Skip static liquid objects that are not on the first frame. - * TODO (sebbas): Also do not use static mode if initial velocities are enabled. */ - if (is_static && !use_velocity) { - continue; - } - /* Liquid geometry objects don't need emission application after first frame. */ - if (is_geometry) { - continue; - } - } + bool is_static = is_static_object(flowobj) && + ((mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) == 0); FluidObjectBB *bb = &bb_maps[flow_index]; float *velocity_map = bb->velocity; @@ -3012,6 +3054,8 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, /* Delete fluid in outflow regions. */ if (is_outflow) { + float *levelset = ((is_first_frame || is_resume) && is_static) ? phioutstatic_in : + phiout_in; apply_outflow_fields(d_index, distance_map[e_index], density_in, @@ -3021,7 +3065,7 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, color_r_in, color_g_in, color_b_in, - phiout_in); + levelset); } /* Do not apply inflow after the first frame when in geometry mode. */ else if (is_geometry && !is_first_frame) { @@ -3046,31 +3090,10 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, phi_in, emission_in); } - /* Static liquid objects need inflow application onto static phi grid. */ - else if (is_inflow && is_liquid && is_static && is_first_frame) { - apply_inflow_fields(mfs, - 0.0f, - distance_map[e_index], - d_index, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - phistatic_in, - NULL); - } /* Main inflow application. */ else if (is_geometry || is_inflow) { + float *levelset = ((is_first_frame || is_resume) && is_static) ? phistatic_in : + phi_in; apply_inflow_fields(mfs, emission_map[e_index], distance_map[e_index], @@ -3089,7 +3112,7 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, color_g, color_b_in, color_b, - phi_in, + levelset, emission_in); if (mfs->flags & FLUID_FLOW_INITVELOCITY) { velx_initial[d_index] = velocity_map[e_index * 3]; @@ -3607,12 +3630,6 @@ static int manta_step( mds->time_per_frame = time_per_frame; mds->time_total = time_total; - - /* If user requested stop, quit baking */ - if (G.is_break && !mode_replay) { - result = 0; - break; - } } if (mds->type == FLUID_DOMAIN_TYPE_GAS && result) { @@ -3724,6 +3741,11 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, return; } + /* Reset fluid if no fluid present. */ + if (!mds->fluid || mds->cache_flag & FLUID_DOMAIN_OUTDATED_DATA) { + BKE_fluid_modifier_reset_ex(mmd, false); + } + /* Ensure cache directory is not relative. */ const char *relbase = modifier_path_relbase_from_global(ob); BLI_path_abs(mds->cache_directory, relbase); @@ -3741,14 +3763,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, MEM_freeN(objs); } - /* Reset fluid if no fluid present. */ - if (!mds->fluid || mds->cache_flag & FLUID_DOMAIN_OUTDATED_DATA) { - BKE_fluid_modifier_reset_ex(mmd, false); - - /* Fluid domain init must not fail in order to continue modifier evaluation. */ - if (!BKE_fluid_modifier_init(mmd, depsgraph, ob, scene, me)) { - return; - } + /* Fluid domain init must not fail in order to continue modifier evaluation. */ + if (!mds->fluid && !BKE_fluid_modifier_init(mmd, depsgraph, ob, scene, me)) { + return; } BLI_assert(mds->fluid); |