From e09d0c0d077cff79b55ce32ec5124d5faa73e2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastia=CC=81n=20Barschkis?= Date: Wed, 25 Nov 2020 23:17:47 +0100 Subject: Fluid: Updated Mantaflow source files This update introduces two improvements from the Mantaflow repository: (1) Improved particle sampling: - Liquid and secondary particles are sampled more predictably. With all parameters being equal, baked particles will be computed at the exact same position during every bake. - Before, this was not guaranteed. (2) Sparse grid caching: - While saving grid data to disk, grids will from now on be saved in a sparse structure whenever possible (e.g. density, flame but not levelsets). - With the sparse optimization grid cells with a value under the 'Empty Space' value (already present in domain settings) will not be cached. - The main benefits of this optimization are: Smaller cache sizes and faster playback of simulation data in the viewport. - This optimization works 'out-of-the-box'. There is no option in the UI to enable it. - For now, only smoke simulation grids will take advantage of this optimization. --- intern/mantaflow/intern/MANTA_main.cpp | 1 + intern/mantaflow/intern/strings/fluid_script.h | 9 ++-- intern/mantaflow/intern/strings/smoke_script.h | 60 +++++++++++++------------- 3 files changed, 36 insertions(+), 34 deletions(-) (limited to 'intern') diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index fef6399ab23..d49915e2452 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -871,6 +871,7 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd) mRNAMap["CACHE_DIR"] = cacheDirectory; mRNAMap["COMPRESSION_OPENVDB"] = vdbCompressionMethod; mRNAMap["PRECISION_OPENVDB"] = vdbPrecisionHalf; + mRNAMap["CLIP_OPENVDB"] = to_string(fds->clipping); mRNAMap["PP_PARTICLE_MAXIMUM"] = to_string(fds->sys_particle_maximum); /* Fluid object names. */ diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h index 3aedef4a284..8c9025dd435 100644 --- a/intern/mantaflow/intern/strings/fluid_script.h +++ b/intern/mantaflow/intern/strings/fluid_script.h @@ -159,6 +159,7 @@ gravity_s$ID$ *= scaleAcceleration_s$ID$ # scale from world acceleration to cell # OpenVDB options\n\ vdbCompression_s$ID$ = $COMPRESSION_OPENVDB$\n\ vdbPrecision_s$ID$ = $PRECISION_OPENVDB$\n\ +vdbClip_s$ID$ = $CLIP_OPENVDB$\n\ \n\ # Cache file names\n\ file_data_s$ID$ = '$NAME_DATA$'\n\ @@ -264,8 +265,8 @@ const std::string fluid_alloc = "\n\ mantaMsg('Fluid alloc data')\n\ flags_s$ID$ = s$ID$.create(FlagGrid, name='$NAME_FLAGS$')\n\ -vel_s$ID$ = s$ID$.create(MACGrid, name='$NAME_VELOCITY$')\n\ -velTmp_s$ID$ = s$ID$.create(MACGrid, name='$NAME_VELOCITYTMP$')\n\ +vel_s$ID$ = s$ID$.create(MACGrid, name='$NAME_VELOCITY$', sparse=True)\n\ +velTmp_s$ID$ = s$ID$.create(MACGrid, name='$NAME_VELOCITYTMP$', sparse=True)\n\ x_vel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_VELOCITY_X$')\n\ y_vel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_VELOCITY_Y$')\n\ z_vel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_VELOCITY_Z$')\n\ @@ -682,7 +683,7 @@ def fluid_load_vel_$ID$(path, framenr, file_format):\n\ const std::string fluid_file_export = "\n\ -def fluid_file_export_s$ID$(framenr, file_format, path, dict, file_name=None, mode_override=True, skip_subframes=True):\n\ +def fluid_file_export_s$ID$(framenr, file_format, path, dict, file_name=None, mode_override=True, skip_subframes=True, clipGrid=None):\n\ if skip_subframes and ((timePerFrame_s$ID$ + dt0_s$ID$) < frameLength_s$ID$):\n\ return\n\ mantaMsg('Fluid file export, frame: ' + str(framenr))\n\ @@ -697,7 +698,7 @@ def fluid_file_export_s$ID$(framenr, file_format, path, dict, file_name=None, mo file = os.path.join(path, file_name + '_' + framenr + file_format)\n\ if not os.path.isfile(file) or mode_override:\n\ if file_format == '.vdb':\n\ - saveCombined = save(name=file, objects=list(dict.values()), worldSize=domainSize_s$ID$, skipDeletedParts=True, compression=vdbCompression_s$ID$, precision=vdbPrecision_s$ID$)\n\ + saveCombined = save(name=file, objects=list(dict.values()), worldSize=domainSize_s$ID$, skipDeletedParts=True, compression=vdbCompression_s$ID$, precision=vdbPrecision_s$ID$, clip=vdbClip_s$ID$, clipGrid=clipGrid)\n\ elif file_format == '.bobj.gz' or file_format == '.obj':\n\ for name, object in dict.items():\n\ if not os.path.isfile(file) or mode_override:\n\ diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h index 77ee5fa4077..157cfff1a27 100644 --- a/intern/mantaflow/intern/strings/smoke_script.h +++ b/intern/mantaflow/intern/strings/smoke_script.h @@ -81,11 +81,11 @@ using_fire_s$ID$ = True\n"; const std::string smoke_alloc = "\n\ mantaMsg('Smoke alloc')\n\ -shadow_s$ID$ = s$ID$.create(RealGrid, name='$NAME_SHADOW$')\n\ -emission_s$ID$ = s$ID$.create(RealGrid, name='$NAME_EMISSION$')\n\ +shadow_s$ID$ = s$ID$.create(RealGrid, name='$NAME_SHADOW$', sparse=False)\n\ +emission_s$ID$ = s$ID$.create(RealGrid, name='$NAME_EMISSION$', sparse=True)\n\ emissionIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_EMISSIONIN$')\n\ -density_s$ID$ = s$ID$.create(RealGrid, name='$NAME_DENSITY$')\n\ -densityIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_DENSITYIN$')\n\ +density_s$ID$ = s$ID$.create(RealGrid, name='$NAME_DENSITY$', sparse=True)\n\ +densityIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_DENSITYIN$', sparse=True)\n\ heat_s$ID$ = None # allocated dynamically\n\ heatIn_s$ID$ = None\n\ flame_s$ID$ = None\n\ @@ -111,7 +111,7 @@ const std::string smoke_alloc_noise = "\n\ mantaMsg('Smoke alloc noise')\n\ vel_sn$ID$ = sn$ID$.create(MACGrid, name='$NAME_VELOCITY_NOISE$')\n\ -density_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_DENSITY_NOISE$')\n\ +density_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_DENSITY_NOISE$', sparse=True)\n\ phiIn_sn$ID$ = sn$ID$.create(LevelsetGrid, name='$NAME_PHIIN_NOISE$')\n\ phiOut_sn$ID$ = sn$ID$.create(LevelsetGrid, name='$NAME_PHIOUT_NOISE$')\n\ phiObs_sn$ID$ = sn$ID$.create(LevelsetGrid, name='$NAME_PHIOBS_NOISE$')\n\ @@ -135,8 +135,8 @@ color_b_sn$ID$ = None\n\ wltnoise_sn$ID$ = sn$ID$.create(NoiseField, fixedSeed=265, loadFromFile=True)\n\ \n\ mantaMsg('Initializing UV Grids')\n\ -uvGrid0_s$ID$ = s$ID$.create(VecGrid, name='$NAME_UV0$')\n\ -uvGrid1_s$ID$ = s$ID$.create(VecGrid, name='$NAME_UV1$')\n\ +uvGrid0_s$ID$ = s$ID$.create(VecGrid, name='$NAME_UV0$', sparse=False)\n\ +uvGrid1_s$ID$ = s$ID$.create(VecGrid, name='$NAME_UV1$', sparse=False)\n\ resetUvGrid(target=uvGrid0_s$ID$, offset=uvs_offset_s$ID$)\n\ resetUvGrid(target=uvGrid1_s$ID$, offset=uvs_offset_s$ID$)\n\ \n\ @@ -145,8 +145,8 @@ copyVec3ToReal(source=uvGrid0_s$ID$, targetX=texture_u_s$ID$, targetY=texture_v_ copyVec3ToReal(source=uvGrid1_s$ID$, targetX=texture_u2_s$ID$, targetY=texture_v2_s$ID$, targetZ=texture_w2_s$ID$)\n\ \n\ # Keep track of important objects in dict to load them later on\n\ -smoke_noise_dict_final_s$ID$ = dict(density_noise=density_sn$ID$)\n\ -smoke_noise_dict_resume_s$ID$ = dict(uv0_noise=uvGrid0_s$ID$, uv1_noise=uvGrid1_s$ID$)\n"; +smoke_noise_dict_final_s$ID$ = { 'density_noise' : density_sn$ID$ }\n\ +smoke_noise_dict_resume_s$ID$ = { 'uv0_noise' : uvGrid0_s$ID$, 'uv1_noise' : uvGrid1_s$ID$ }\n"; ////////////////////////////////////////////////////////////////////// // ADDITIONAL GRIDS @@ -160,12 +160,12 @@ if 'color_g_s$ID$' in globals(): del color_g_s$ID$\n\ if 'color_b_s$ID$' in globals(): del color_b_s$ID$\n\ \n\ mantaMsg('Allocating colors')\n\ -color_r_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORR$')\n\ -color_g_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORG$')\n\ -color_b_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORB$')\n\ -color_r_in_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORRIN$')\n\ -color_g_in_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORGIN$')\n\ -color_b_in_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORBIN$')\n\ +color_r_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORR$', sparse=True)\n\ +color_g_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORG$', sparse=True)\n\ +color_b_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORB$', sparse=True)\n\ +color_r_in_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORRIN$', sparse=True)\n\ +color_g_in_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORGIN$', sparse=True)\n\ +color_b_in_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORBIN$', sparse=True)\n\ \n\ # Add objects to dict to load them later on\n\ if 'smoke_data_dict_final_s$ID$' in globals():\n\ @@ -181,9 +181,9 @@ if 'color_g_sn$ID$' in globals(): del color_g_sn$ID$\n\ if 'color_b_sn$ID$' in globals(): del color_b_sn$ID$\n\ \n\ mantaMsg('Allocating colors noise')\n\ -color_r_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORR_NOISE$')\n\ -color_g_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORG_NOISE$')\n\ -color_b_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORB_NOISE$')\n\ +color_r_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORR_NOISE$', sparse=True)\n\ +color_g_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORG_NOISE$', sparse=True)\n\ +color_b_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORB_NOISE$', sparse=True)\n\ \n\ # Add objects to dict to load them later on\n\ if 'smoke_noise_dict_final_s$ID$' in globals():\n\ @@ -216,8 +216,8 @@ if 'heat_s$ID$' in globals(): del heat_s$ID$\n\ if 'heatIn_s$ID$' in globals(): del heatIn_s$ID$\n\ \n\ mantaMsg('Allocating heat')\n\ -heat_s$ID$ = s$ID$.create(RealGrid, name='$NAME_TEMPERATURE$')\n\ -heatIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_TEMPERATUREIN$')\n\ +heat_s$ID$ = s$ID$.create(RealGrid, name='$NAME_TEMPERATURE$', sparse=True)\n\ +heatIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_TEMPERATUREIN$', sparse=True)\n\ \n\ # Add objects to dict to load them later on\n\ if 'smoke_data_dict_final_s$ID$' in globals():\n\ @@ -235,11 +235,11 @@ if 'fuelIn_s$ID$' in globals(): del fuelIn_s$ID$\n\ if 'reactIn_s$ID$' in globals(): del reactIn_s$ID$\n\ \n\ mantaMsg('Allocating fire')\n\ -flame_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FLAME$')\n\ -fuel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FUEL$')\n\ -react_s$ID$ = s$ID$.create(RealGrid, name='$NAME_REACT$')\n\ -fuelIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FUELIN$')\n\ -reactIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_REACTIN$')\n\ +flame_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FLAME$', sparse=True)\n\ +fuel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FUEL$', sparse=True)\n\ +react_s$ID$ = s$ID$.create(RealGrid, name='$NAME_REACT$', sparse=True)\n\ +fuelIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FUELIN$', sparse=True)\n\ +reactIn_s$ID$ = s$ID$.create(RealGrid, name='$NAME_REACTIN$', sparse=True)\n\ \n\ # Add objects to dict to load them later on\n\ if 'smoke_data_dict_final_s$ID$' in globals():\n\ @@ -255,9 +255,9 @@ if 'fuel_sn$ID$' in globals(): del fuel_sn$ID$\n\ if 'react_sn$ID$' in globals(): del react_sn$ID$\n\ \n\ mantaMsg('Allocating fire noise')\n\ -flame_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FLAME_NOISE$')\n\ -fuel_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FUEL_NOISE$')\n\ -react_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_REACT_NOISE$')\n\ +flame_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FLAME_NOISE$', sparse=True)\n\ +fuel_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FUEL_NOISE$', sparse=True)\n\ +react_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_REACT_NOISE$', sparse=True)\n\ \n\ # Add objects to dict to load them later on\n\ if 'smoke_noise_dict_final_s$ID$' in globals():\n\ @@ -575,7 +575,7 @@ def smoke_save_data_$ID$(path, framenr, file_format, resumable):\n\ start_time = time.time()\n\ dict = { **fluid_data_dict_final_s$ID$, **fluid_data_dict_resume_s$ID$, **smoke_data_dict_final_s$ID$, **smoke_data_dict_resume_s$ID$ } if resumable else { **fluid_data_dict_final_s$ID$, **smoke_data_dict_final_s$ID$ } \n\ if not withMPSave or isWindows:\n\ - fluid_file_export_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_data_s$ID$)\n\ + fluid_file_export_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_data_s$ID$, clipGrid=density_s$ID$)\n\ else:\n\ fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_data_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n\ mantaMsg('--- Save: %s seconds ---' % (time.time() - start_time))\n"; @@ -586,7 +586,7 @@ def smoke_save_noise_$ID$(path, framenr, file_format, resumable):\n\ mantaMsg('Smoke save noise')\n\ dict = { **smoke_noise_dict_final_s$ID$, **smoke_noise_dict_resume_s$ID$ } if resumable else { **smoke_noise_dict_final_s$ID$ } \n\ if not withMPSave or isWindows:\n\ - fluid_file_export_s$ID$(dict=dict, framenr=framenr, file_format=file_format, path=path, file_name=file_noise_s$ID$)\n\ + fluid_file_export_s$ID$(dict=dict, framenr=framenr, file_format=file_format, path=path, file_name=file_noise_s$ID$, clipGrid=density_sn$ID$)\n\ else:\n\ fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_noise_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n"; -- cgit v1.2.3