From b088d1e9969d440ffb7cc9614cef0ca81da46433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 15:56:02 +0100 Subject: [PATCH 1/5] Particle: Added sanity in particle system removal function Added a NULL check since psys_get_modifier() might also return a NULL pointer. --- source/blender/blenkernel/intern/particle.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 97fcef4fd27..eafd530b0d8 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3638,12 +3638,14 @@ void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob } } - /* clear modifier */ + /* Clear modifier, skip empty ones. */ psmd = psys_get_modifier(ob, psys); - BLI_remlink(&ob->modifiers, psmd); - modifier_free((ModifierData *)psmd); + if (psmd) { + BLI_remlink(&ob->modifiers, psmd); + modifier_free((ModifierData *)psmd); + } - /* clear particle system */ + /* Clear particle system. */ BLI_remlink(&ob->particlesystem, psys); if (psys->part) { id_us_min(&psys->part->id); From ae112a38ab8d5b6cb7fe8e9209aa7e0e0209a6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 15:59:10 +0100 Subject: [PATCH 2/5] Fluid: Removed UI locks for cache file types Caches that haven't been baked yet should not be locked. --- .../startup/bl_ui/properties_physics_fluid.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 28c9895f53b..2a918f0c58b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -680,7 +680,7 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings # Deactivate UI if guides are enabled but not baked yet. - layout.active = domain.use_noise and not self.check_domain_has_unbaked_guide(domain) + layout.enabled = domain.use_noise and not self.check_domain_has_unbaked_guide(domain) is_baking_any = domain.is_cache_baking_any has_baked_noise = domain.has_cache_baked_noise @@ -746,7 +746,7 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings # Deactivate UI if guides are enabled but not baked yet. - layout.active = domain.use_mesh and not self.check_domain_has_unbaked_guide(domain) + layout.enabled = domain.use_mesh and not self.check_domain_has_unbaked_guide(domain) is_baking_any = domain.is_cache_baking_any has_baked_mesh = domain.has_cache_baked_mesh @@ -818,7 +818,7 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings # Deactivate UI if guides are enabled but not baked yet. - layout.active = not self.check_domain_has_unbaked_guide(domain) + layout.enabled = not self.check_domain_has_unbaked_guide(domain) is_baking_any = domain.is_cache_baking_any has_baked_particles = domain.has_cache_baked_particles @@ -1072,7 +1072,10 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings is_baking_any = domain.is_cache_baking_any - has_baked_any = domain.has_cache_baked_any + has_baked_data = domain.has_cache_baked_data + has_baked_noise = domain.has_cache_baked_noise + has_baked_mesh = domain.has_cache_baked_mesh + has_baked_particles = domain.has_cache_baked_particles col = layout.column() col.prop(domain, "cache_directory", text="") @@ -1096,18 +1099,24 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): col.separator() col = flow.column() - col.enabled = not is_baking_any and not has_baked_any + col.enabled = not is_baking_any and not has_baked_data col.prop(domain, "cache_data_format", text="Data File Format") if md.domain_settings.domain_type in {'GAS'}: if domain.use_noise: + col = flow.column() + col.enabled = not is_baking_any and not has_baked_noise col.prop(domain, "cache_noise_format", text="Noise File Format") if md.domain_settings.domain_type in {'LIQUID'}: # File format for all particle systemes (FLIP and secondary) + col = flow.column() + col.enabled = not is_baking_any and not has_baked_particles col.prop(domain, "cache_particle_format", text="Particle File Format") if domain.use_mesh: + col = flow.column() + col.enabled = not is_baking_any and not has_baked_mesh col.prop(domain, "cache_mesh_format", text="Mesh File Format") if domain.cache_type == 'FINAL': From e7d71ce9cf1eb8ea73d5d77527fc65e7bd6f5d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 16:53:00 +0100 Subject: [PATCH 3/5] Fluid: Fixed slow cache loading for smoke data Cache files are currently loaded via the Manta Python API. With very big caches this can slow down the viewport playback. Especially smoke simulations, which just load grids and no meshes, can suffer from this. This fix solves this problem by directly loading the cache files from disk (no Python). This fix has been in the works for some time. The developer of this patch is ready to handle any potential fall-out of this patch quickly. --- intern/mantaflow/CMakeLists.txt | 29 ++ intern/mantaflow/extern/manta_fluid_API.h | 2 + intern/mantaflow/intern/MANTA_main.cpp | 418 +++++++++++++++++++- intern/mantaflow/intern/MANTA_main.h | 8 + intern/mantaflow/intern/manta_fluid_API.cpp | 14 + source/blender/blenkernel/intern/fluid.c | 25 +- 6 files changed, 488 insertions(+), 8 deletions(-) diff --git a/intern/mantaflow/CMakeLists.txt b/intern/mantaflow/CMakeLists.txt index c7b3c56c3c2..a3d891907a9 100644 --- a/intern/mantaflow/CMakeLists.txt +++ b/intern/mantaflow/CMakeLists.txt @@ -47,6 +47,35 @@ set(INC_SYS ${ZLIB_INCLUDE_DIRS} ) +if(WITH_TBB) + list(APPEND INC_SYS + ${TBB_INCLUDE_DIRS} + ) + list(APPEND LIB + ${TBB_LIBRARIES} + ) +endif() + +if(WITH_OPENVDB) + list(APPEND INC_SYS + ${BOOST_INCLUDE_DIR} + ${OPENEXR_INCLUDE_DIRS} + ${OPENVDB_INCLUDE_DIRS} + ) + list(APPEND LIB + ${OPENVDB_LIBRARIES} + ${OPENEXR_LIBRARIES} + ${ZLIB_LIBRARIES} + ${BOOST_LIBRARIES} + ) + if(WITH_OPENVDB_BLOSC) + list(APPEND LIB + ${BLOSC_LIBRARIES} + ${ZLIB_LIBRARIES} + ) + endif() +endif() + set(SRC intern/manta_python_API.cpp intern/manta_fluid_API.cpp diff --git a/intern/mantaflow/extern/manta_fluid_API.h b/intern/mantaflow/extern/manta_fluid_API.h index 8dc2cf1805a..4ebedeb5e38 100644 --- a/intern/mantaflow/extern/manta_fluid_API.h +++ b/intern/mantaflow/extern/manta_fluid_API.h @@ -55,6 +55,8 @@ int manta_update_mesh_structures(struct MANTA *fluid, struct FluidModifierData * int manta_update_particle_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); +int manta_update_smoke_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); +int manta_update_noise_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index 7f6ff9094c6..11b8fb820d6 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -27,6 +27,10 @@ #include #include +#if OPENVDB == 1 +# include "openvdb/openvdb.h" +#endif + #include "MANTA_main.h" #include "manta.h" #include "Python.h" @@ -1168,6 +1172,244 @@ int MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr) return 1; } +int MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr) +{ + if (MANTA::with_debug) + std::cout << "MANTA::updateGridStructures()" << std::endl; + + mSmokeFromFile = false; + + if (!mUsingSmoke) + return 0; + if (BLI_path_is_rel(mmd->domain->cache_directory)) + return 0; + + int result = 0; + int expected = 0; /* Expected number of read successes for this frame. */ + + std::ostringstream ss; + char cacheDir[FILE_MAX], targetFile[FILE_MAX]; + cacheDir[0] = '\0'; + targetFile[0] = '\0'; + + std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + BLI_path_join( + cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr); + + expected += 1; + ss.str(""); + ss << "density_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mDensity); + + expected += 1; + ss.str(""); + ss << "shadow_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mShadow); + + if (mUsingHeat) { + expected += 1; + ss.str(""); + ss << "heat_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mHeat); + } + + if (mUsingColors) { + expected += 3; + ss.str(""); + ss << "color_r_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorR); + + ss.str(""); + ss << "color_g_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorG); + + ss.str(""); + ss << "color_b_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorB); + } + + if (mUsingFire) { + expected += 3; + ss.str(""); + ss << "flame_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mFlame); + + ss.str(""); + ss << "fuel_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mFuel); + + ss.str(""); + ss << "react_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mReact); + } + + mSmokeFromFile = true; + return (result == expected) ? 1 : 0; +} + +int MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr) +{ + if (MANTA::with_debug) + std::cout << "MANTA::updateNoiseStructures()" << std::endl; + + mNoiseFromFile = false; + + if (!mUsingSmoke || !mUsingNoise) + return 0; + if (BLI_path_is_rel(mmd->domain->cache_directory)) + return 0; + + int result = 0; + int expected = 0; /* Expected number of read successes for this frame. */ + + std::ostringstream ss; + char cacheDirData[FILE_MAX], cacheDirNoise[FILE_MAX], targetFile[FILE_MAX]; + cacheDirData[0] = '\0'; + cacheDirNoise[0] = '\0'; + targetFile[0] = '\0'; + + std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); + BLI_path_join(cacheDirData, + sizeof(cacheDirData), + mmd->domain->cache_directory, + FLUID_DOMAIN_DIR_DATA, + nullptr); + BLI_path_join(cacheDirNoise, + sizeof(cacheDirNoise), + mmd->domain->cache_directory, + FLUID_DOMAIN_DIR_NOISE, + nullptr); + + expected += 1; + ss.str(""); + ss << "density_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mDensityHigh); + + expected += 1; + ss.str(""); + ss << "shadow_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirData, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mShadow); + + if (mUsingColors) { + expected += 3; + ss.str(""); + ss << "color_r_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorRHigh); + + ss.str(""); + ss << "color_g_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorGHigh); + + ss.str(""); + ss << "color_b_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorBHigh); + } + + if (mUsingFire) { + expected += 3; + ss.str(""); + ss << "flame_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mFlameHigh); + + ss.str(""); + ss << "fuel_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mFuelHigh); + + ss.str(""); + ss << "react_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mReactHigh); + } + + mNoiseFromFile = true; + return (result == expected) ? 1 : 0; +} + /* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */ static std::string escapeSlashes(std::string const &s) { @@ -1194,7 +1436,7 @@ int MANTA::writeConfiguration(FluidModifierData *mmd, int framenr) cacheDir[0] = '\0'; targetFile[0] = '\0'; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + std::string dformat = ".uni"; BLI_path_join( cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_CONFIG, nullptr); @@ -1287,7 +1529,7 @@ int MANTA::readConfiguration(FluidModifierData *mmd, int framenr) targetFile[0] = '\0'; float dummy; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + std::string dformat = ".uni"; BLI_path_join( cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_CONFIG, nullptr); @@ -2533,6 +2775,174 @@ void MANTA::updateParticlesFromUni(const char *filename, bool isSecondarySys, bo gzclose(gzf); } +int MANTA::updateGridFromFile(const char *filename, float *grid) +{ + if (with_debug) + std::cout << "MANTA::updateGridFromFile()" << std::endl; + + if (!grid) { + std::cout << "MANTA::updateGridFromFile(): cannot read into uninitialized grid, grid is null" + << std::endl; + return 0; + } + + std::string fname(filename); + std::string::size_type idx; + + idx = fname.rfind('.'); + if (idx != std::string::npos) { + std::string extension = fname.substr(idx + 1); + + if (extension.compare("uni") == 0) + return updateGridFromUni(filename, grid); + else if (extension.compare("vdb") == 0) + return updateGridFromVDB(filename, grid); + else if (extension.compare("raw") == 0) + return updateGridFromRaw(filename, grid); + else + std::cerr << "MANTA::updateGridFromFile(): invalid file extension in file: " << filename + << std::endl; + return 0; + } + else { + std::cerr << "MANTA::updateGridFromFile(): unable to open file: " << filename << std::endl; + return 0; + } +} + +int MANTA::updateGridFromUni(const char *filename, float *grid) +{ + if (with_debug) + std::cout << "MANTA::updateGridFromUni()" << std::endl; + + gzFile gzf; + int ibuffer[4]; + + gzf = (gzFile)BLI_gzopen(filename, "rb1"); + if (!gzf) { + std::cout << "MANTA::updateGridFromUni(): unable to open file" << std::endl; + return 0; + } + + char ID[5] = {0, 0, 0, 0, 0}; + gzread(gzf, ID, 4); + + if (!strcmp(ID, "DDF2")) { + std::cout << "MANTA::updateGridFromUni(): grid uni file format DDF2 not supported anymore" + << std::endl; + return 0; + } + if (!strcmp(ID, "MNT1")) { + std::cout << "MANTA::updateGridFromUni(): grid uni file format MNT1 not supported anymore" + << std::endl; + return 0; + } + if (!strcmp(ID, "MNT2")) { + std::cout << "MANTA::updateGridFromUni(): grid uni file format MNT2 not supported anymore" + << std::endl; + return 0; + } + + // grid uni header + const int STR_LEN_GRID = 252; + int elementType, bytesPerElement; // data type info + char info[STR_LEN_GRID]; // mantaflow build information + int dimT; // optionally store forth dimension for 4d grids + unsigned long long timestamp; // creation time + + // read grid header + gzread(gzf, &ibuffer, sizeof(int) * 4); // dimX, dimY, dimZ, gridType + gzread(gzf, &elementType, sizeof(int)); + gzread(gzf, &bytesPerElement, sizeof(int)); + gzread(gzf, &info, sizeof(info)); + gzread(gzf, &dimT, sizeof(int)); + gzread(gzf, ×tamp, sizeof(unsigned long long)); + + if (with_debug) + std::cout << "read " << ibuffer[3] << " grid type in file: " << filename << std::endl; + + // Sanity checks + if (ibuffer[0] != mResX || ibuffer[1] != mResY || ibuffer[2] != mResZ) { + std::cout << "grid dim doesn't match, read: (" << ibuffer[0] << ", " << ibuffer[1] << ", " + << ibuffer[2] << ") vs setup: (" << mResX << ", " << mResY << ", " << mResZ << ")" + << std::endl; + return 0; + } + + // Actual data reading + if (!strcmp(ID, "MNT3")) { + gzread(gzf, grid, sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2]); + } + + if (with_debug) + std::cout << "read successfully: " << filename << std::endl; + + gzclose(gzf); + return 1; +} + +int MANTA::updateGridFromVDB(const char *filename, float *grid) +{ + if (with_debug) + std::cout << "MANTA::updateGridFromVDB()" << std::endl; + + openvdb::initialize(); + openvdb::io::File file(filename); + try { + file.open(); + } + catch (const openvdb::v5_1::IoError) { + std::cout << "MANTA::updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename + << std::endl; + return 0; + } + + openvdb::GridBase::Ptr baseGrid; + for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName(); + ++nameIter) { + baseGrid = file.readGrid(nameIter.gridName()); + break; + } + file.close(); + openvdb::FloatGrid::Ptr gridVDB = openvdb::gridPtrCast(baseGrid); + openvdb::FloatGrid::Accessor accessor = gridVDB->getAccessor(); + + size_t index = 0; + for (int z = 0; z < mResZ; ++z) { + for (int y = 0; y < mResY; ++y) { + for (int x = 0; x < mResX; ++x, ++index) { + openvdb::Coord xyz(x, y, z); + float v = accessor.getValue(xyz); + grid[index] = v; + } + } + } + return 1; +} + +int MANTA::updateGridFromRaw(const char *filename, float *grid) +{ + if (with_debug) + std::cout << "MANTA::updateGridFromRaw()" << std::endl; + + gzFile gzf; + int expectedBytes, readBytes; + + gzf = (gzFile)BLI_gzopen(filename, "rb"); + if (!gzf) { + std::cout << "MANTA::updateGridFromRaw(): unable to open file" << std::endl; + return 0; + } + + expectedBytes = sizeof(float) * mResX * mResY * mResZ; + readBytes = gzread(gzf, grid, expectedBytes); + + assert(expectedBytes == readBytes); + + gzclose(gzf); + return 1; +} + void MANTA::updatePointers() { if (with_debug) @@ -2660,7 +3070,9 @@ void MANTA::updatePointers() callPythonFunction("pLifeSnd" + parts_ext, func)); } - mFlipFromFile = true; + mFlipFromFile = false; mMeshFromFile = false; mParticlesFromFile = false; + mSmokeFromFile = false; + mNoiseFromFile = false; } diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h index f8d94e2631c..c1c2c042a73 100644 --- a/intern/mantaflow/intern/MANTA_main.h +++ b/intern/mantaflow/intern/MANTA_main.h @@ -93,6 +93,8 @@ struct MANTA { int updateMeshStructures(FluidModifierData *mmd, int framenr); int updateFlipStructures(FluidModifierData *mmd, int framenr); int updateParticleStructures(FluidModifierData *mmd, int framenr); + int updateSmokeStructures(FluidModifierData *mmd, int framenr); + int updateNoiseStructures(FluidModifierData *mmd, int framenr); void updateVariables(FluidModifierData *mmd); // Bake cache @@ -742,6 +744,8 @@ struct MANTA { bool mFlipFromFile; bool mMeshFromFile; bool mParticlesFromFile; + bool mSmokeFromFile; + bool mNoiseFromFile; int mResX; int mResY; @@ -852,8 +856,12 @@ struct MANTA { void updateMeshFromObj(const char *filename); void updateMeshFromUni(const char *filename); void updateParticlesFromUni(const char *filename, bool isSecondarySys, bool isVelData); + int updateGridFromUni(const char *filename, float *grid); + int updateGridFromVDB(const char *filename, float *grid); + int updateGridFromRaw(const char *filename, float *grid); void updateMeshFromFile(const char *filename); void updateParticlesFromFile(const char *filename, bool isSecondarySys, bool isVelData); + int updateGridFromFile(const char *filename, float *grid); }; #endif diff --git a/intern/mantaflow/intern/manta_fluid_API.cpp b/intern/mantaflow/intern/manta_fluid_API.cpp index 35f2ebbaf44..82bfed7cf61 100644 --- a/intern/mantaflow/intern/manta_fluid_API.cpp +++ b/intern/mantaflow/intern/manta_fluid_API.cpp @@ -143,6 +143,20 @@ int manta_update_particle_structures(MANTA *fluid, FluidModifierData *mmd, int f return fluid->updateParticleStructures(mmd, framenr); } +int manta_update_smoke_structures(MANTA *fluid, FluidModifierData *mmd, int framenr) +{ + if (!fluid || !mmd) + return 0; + return fluid->updateSmokeStructures(mmd, framenr); +} + +int manta_update_noise_structures(MANTA *fluid, FluidModifierData *mmd, int framenr) +{ + if (!fluid || !mmd) + return 0; + return fluid->updateNoiseStructures(mmd, framenr); +} + int manta_bake_data(MANTA *fluid, FluidModifierData *mmd, int framenr) { if (!fluid || !mmd) diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index f35aebbae16..8b959e30aff 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -3505,10 +3505,14 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, manta_needs_realloc(mds->fluid, mmd)) { BKE_fluid_reallocate_fluid(mds, mds->res, 1); } - has_noise = manta_read_noise(mds->fluid, mmd, noise_frame); + if (!baking_data && !baking_noise && !mode_replay) { + has_data = manta_update_noise_structures(mds->fluid, mmd, noise_frame); + } + else { + has_noise = manta_read_noise(mds->fluid, mmd, noise_frame); + } - /* In case of using the adaptive domain, copy all data that was read to a new fluid object. - */ + /* When using the adaptive domain, copy all data that was read to a new fluid object. */ if (with_adaptive && baking_noise) { /* Adaptive domain needs to know about current state, so save it, then copy. */ copy_v3_v3_int(o_res, mds->res); @@ -3521,7 +3525,13 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, mds, o_res, mds->res, o_min, mds->res_min, o_max, o_shift, mds->shift); } } - has_data = manta_read_data(mds->fluid, mmd, data_frame); + if (!baking_data && !baking_noise && !mode_replay) { + /* There is no need to call manta_update_smoke_structures() here. + * The noise cache has already been read with manta_update_noise_structures(). */ + } + else { + has_data = manta_read_data(mds->fluid, mmd, data_frame); + } } /* Read data cache only */ else { @@ -3532,7 +3542,12 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, BKE_fluid_reallocate_fluid(mds, mds->res, 1); } /* Read data cache */ - has_data = manta_read_data(mds->fluid, mmd, data_frame); + if (!baking_data && !baking_particles && !baking_mesh && !mode_replay) { + has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame); + } + else { + has_data = manta_read_data(mds->fluid, mmd, data_frame); + } } if (with_liquid) { if (!baking_data && !baking_particles && !baking_mesh && !mode_replay) { From 1bb702df1e1678b83a7238af2a28ecb73b4fb069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 17:24:09 +0100 Subject: [PATCH 4/5] OpenVDB: Fix IOError in try catch statement Broader exception handling for OpenVDB IO errors. --- intern/mantaflow/intern/MANTA_main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index 11b8fb820d6..798ad9c2854 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -2174,6 +2174,7 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) bool floater = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM; bool tracer = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_TRACER; bool obstacle = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE; + 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; @@ -2210,6 +2211,8 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) manta_script += fluid_alloc_guiding; if (obstacle) manta_script += fluid_alloc_obstacle; + if (fractions) + manta_script += fluid_alloc_fractions; if (invel) manta_script += fluid_alloc_invel; @@ -2891,7 +2894,7 @@ int MANTA::updateGridFromVDB(const char *filename, float *grid) try { file.open(); } - catch (const openvdb::v5_1::IoError) { + catch (const openvdb::IoError) { std::cout << "MANTA::updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename << std::endl; return 0; From f8756554180e583ea765eca4e3931d1bda84ebd9 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 6 Feb 2020 18:24:57 +0200 Subject: [PATCH 5/5] Reference correct sha1s of submodules --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 8a05b618f03..34d98762cef 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 8a05b618f031582c006c6f62b9e60619ab3eef8b +Subproject commit 34d98762cef85b9c065f21a051d1dbe3bf2979b7 diff --git a/release/scripts/addons b/release/scripts/addons index 1470f353c65..8b659917bae 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 1470f353c65034db91131d21ab9c782d029a2ee9 +Subproject commit 8b659917baecbea5471a05369aa754ae544a814b diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index ffbaca558a2..70b649775ee 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit ffbaca558a27bab4716bcd51ca7ea1df8e4f4b14 +Subproject commit 70b649775eeeebedb02c1c7b7aa996a7f6294177