diff options
author | Nathan Letwory <nathan@blender.org> | 2020-02-06 19:57:36 +0300 |
---|---|---|
committer | Nathan Letwory <nathan@blender.org> | 2020-02-06 19:57:36 +0300 |
commit | 49b66ad9147a41523eab6b4e579d282d66b9a70a (patch) | |
tree | fc37839a1aafaa98541e13eb572063762132acd1 | |
parent | 807aefd6234f7349d1bef2579def24c8bba9f31f (diff) | |
parent | f8756554180e583ea765eca4e3931d1bda84ebd9 (diff) |
Merge branch 'blender-v2.82-release' into master
-rw-r--r-- | intern/mantaflow/CMakeLists.txt | 29 | ||||
-rw-r--r-- | intern/mantaflow/extern/manta_fluid_API.h | 2 | ||||
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.cpp | 421 | ||||
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.h | 8 | ||||
-rw-r--r-- | intern/mantaflow/intern/manta_fluid_API.cpp | 14 | ||||
m--------- | release/datafiles/locale | 0 | ||||
m--------- | release/scripts/addons | 0 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/properties_physics_fluid.py | 19 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fluid.c | 25 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 10 |
10 files changed, 511 insertions, 17 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..798ad9c2854 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -27,6 +27,10 @@ #include <iomanip> #include <zlib.h> +#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); @@ -1932,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; @@ -1968,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; @@ -2533,6 +2778,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::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<openvdb::FloatGrid>(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 +3073,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/release/datafiles/locale b/release/datafiles/locale -Subproject 74afb3ed35e3271b2609feaf67bea6b8bdffe7c +Subproject 34d98762cef85b9c065f21a051d1dbe3bf2979b diff --git a/release/scripts/addons b/release/scripts/addons -Subproject ad6928706de2fa8f44fa35a275453c716d65e77 +Subproject cbcf507f3045e867c4b2d8e0976b76e1753dc49 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': 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) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 7a352f8c9f8..d68c7a947ae 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); |