diff options
Diffstat (limited to 'intern/mantaflow')
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.cpp | 2336 | ||||
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.h | 124 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/fluid_script.h | 70 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/liquid_script.h | 12 | ||||
-rw-r--r-- | intern/mantaflow/intern/strings/smoke_script.h | 36 |
5 files changed, 1356 insertions, 1222 deletions
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index e6da083f3e5..a2666135c34 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -48,7 +48,16 @@ #include "MEM_guardedalloc.h" -std::atomic<int> MANTA::solverID(0); +using std::cerr; +using std::cout; +using std::endl; +using std::ifstream; +using std::istringstream; +using std::ofstream; +using std::ostringstream; +using std::to_string; + +atomic<int> MANTA::solverID(0); int MANTA::with_debug(0); /* Number of particles that the cache reads at once (with zlib). */ @@ -61,30 +70,31 @@ int MANTA::with_debug(0); MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID) { if (with_debug) - std::cout << "FLUID: " << mCurrentID << " with res(" << res[0] << ", " << res[1] << ", " - << res[2] << ")" << std::endl; - - mmd->domain->fluid = this; - - mUsingLiquid = (mmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID); - mUsingSmoke = (mmd->domain->type == FLUID_DOMAIN_TYPE_GAS); - mUsingNoise = (mmd->domain->flags & FLUID_DOMAIN_USE_NOISE) && mUsingSmoke; - mUsingFractions = (mmd->domain->flags & FLUID_DOMAIN_USE_FRACTIONS) && mUsingLiquid; - mUsingMesh = (mmd->domain->flags & FLUID_DOMAIN_USE_MESH) && mUsingLiquid; - mUsingDiffusion = (mmd->domain->flags & FLUID_DOMAIN_USE_DIFFUSION) && mUsingLiquid; - mUsingMVel = (mmd->domain->flags & FLUID_DOMAIN_USE_SPEED_VECTORS) && mUsingLiquid; - mUsingGuiding = (mmd->domain->flags & FLUID_DOMAIN_USE_GUIDE); - mUsingDrops = (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && mUsingLiquid; - mUsingBubbles = (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) && mUsingLiquid; - mUsingFloats = (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) && mUsingLiquid; - mUsingTracers = (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) && mUsingLiquid; - - mUsingHeat = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_HEAT) && mUsingSmoke; - mUsingFire = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_FIRE) && mUsingSmoke; - mUsingColors = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) && mUsingSmoke; - mUsingObstacle = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE); - mUsingInvel = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL); - mUsingOutflow = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW); + cout << "FLUID: " << mCurrentID << " with res(" << res[0] << ", " << res[1] << ", " << res[2] + << ")" << endl; + + FluidDomainSettings *mds = mmd->domain; + mds->fluid = this; + + mUsingLiquid = (mds->type == FLUID_DOMAIN_TYPE_LIQUID); + mUsingSmoke = (mds->type == FLUID_DOMAIN_TYPE_GAS); + mUsingNoise = (mds->flags & FLUID_DOMAIN_USE_NOISE) && mUsingSmoke; + mUsingFractions = (mds->flags & FLUID_DOMAIN_USE_FRACTIONS) && mUsingLiquid; + mUsingMesh = (mds->flags & FLUID_DOMAIN_USE_MESH) && mUsingLiquid; + mUsingDiffusion = (mds->flags & FLUID_DOMAIN_USE_DIFFUSION) && mUsingLiquid; + mUsingMVel = (mds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS) && mUsingLiquid; + mUsingGuiding = (mds->flags & FLUID_DOMAIN_USE_GUIDE); + mUsingDrops = (mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && mUsingLiquid; + mUsingBubbles = (mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) && mUsingLiquid; + mUsingFloats = (mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) && mUsingLiquid; + mUsingTracers = (mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) && mUsingLiquid; + + mUsingHeat = (mds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT) && mUsingSmoke; + mUsingFire = (mds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE) && mUsingSmoke; + mUsingColors = (mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) && mUsingSmoke; + mUsingObstacle = (mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE); + mUsingInvel = (mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL); + mUsingOutflow = (mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW); // Simulation constants mTempAmb = 0; // TODO: Maybe use this later for buoyancy calculation @@ -92,10 +102,8 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID) mResY = res[1]; mResZ = res[2]; mMaxRes = MAX3(mResX, mResY, mResZ); - mConstantScaling = 64.0f / mMaxRes; - mConstantScaling = (mConstantScaling < 1.0f) ? 1.0f : mConstantScaling; mTotalCells = mResX * mResY * mResZ; - mResGuiding = mmd->domain->res; + mResGuiding = mds->res; // Smoke low res grids mDensity = nullptr; @@ -185,90 +193,93 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID) // Setup Mantaflow in Python initializeMantaflow(); + // Initializa RNA map with values that Python will need + initializeRNAMap(mmd); + // Initialize Mantaflow variables in Python // Liquid if (mUsingLiquid) { - initDomain(mmd); - initLiquid(mmd); + initDomain(); + initLiquid(); if (mUsingObstacle) - initObstacle(mmd); + initObstacle(); if (mUsingInvel) - initInVelocity(mmd); + initInVelocity(); if (mUsingOutflow) - initOutflow(mmd); + initOutflow(); if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) { - mUpresParticle = mmd->domain->particle_scale; + mUpresParticle = mds->particle_scale; mResXParticle = mUpresParticle * mResX; mResYParticle = mUpresParticle * mResY; mResZParticle = mUpresParticle * mResZ; mTotalCellsParticles = mResXParticle * mResYParticle * mResZParticle; - initSndParts(mmd); - initLiquidSndParts(mmd); + initSndParts(); + initLiquidSndParts(); } if (mUsingMesh) { - mUpresMesh = mmd->domain->mesh_scale; + mUpresMesh = mds->mesh_scale; mResXMesh = mUpresMesh * mResX; mResYMesh = mUpresMesh * mResY; mResZMesh = mUpresMesh * mResZ; mTotalCellsMesh = mResXMesh * mResYMesh * mResZMesh; // Initialize Mantaflow variables in Python - initMesh(mmd); - initLiquidMesh(mmd); + initMesh(); + initLiquidMesh(); } if (mUsingDiffusion) { - initCurvature(mmd); + initCurvature(); } if (mUsingGuiding) { - mResGuiding = (mmd->domain->guide_parent) ? mmd->domain->guide_res : mmd->domain->res; - initGuiding(mmd); + mResGuiding = (mds->guide_parent) ? mds->guide_res : mds->res; + initGuiding(); } if (mUsingFractions) { - initFractions(mmd); + initFractions(); } } // Smoke if (mUsingSmoke) { - initDomain(mmd); - initSmoke(mmd); + initDomain(); + initSmoke(); if (mUsingHeat) - initHeat(mmd); + initHeat(); if (mUsingFire) - initFire(mmd); + initFire(); if (mUsingColors) - initColors(mmd); + initColors(); if (mUsingObstacle) - initObstacle(mmd); + initObstacle(); if (mUsingInvel) - initInVelocity(mmd); + initInVelocity(); if (mUsingOutflow) - initOutflow(mmd); + initOutflow(); if (mUsingGuiding) { - mResGuiding = (mmd->domain->guide_parent) ? mmd->domain->guide_res : mmd->domain->res; - initGuiding(mmd); + mResGuiding = (mds->guide_parent) ? mds->guide_res : mds->res; + initGuiding(); } if (mUsingNoise) { - int amplify = mmd->domain->noise_scale; + int amplify = mds->noise_scale; mResXNoise = amplify * mResX; mResYNoise = amplify * mResY; mResZNoise = amplify * mResZ; mTotalCellsHigh = mResXNoise * mResYNoise * mResZNoise; // Initialize Mantaflow variables in Python - initNoise(mmd); - initSmokeNoise(mmd); + initNoise(); + initSmokeNoise(); if (mUsingFire) - initFireHigh(mmd); + initFireHigh(); if (mUsingColors) - initColorsHigh(mmd); + initColorsHigh(); } } updatePointers(); @@ -277,32 +288,32 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID) void MANTA::initDomain(FluidModifierData *mmd) { // Vector will hold all python commands that are to be executed - std::vector<std::string> pythonCommands; + vector<string> pythonCommands; // Set manta debug level first pythonCommands.push_back(manta_import + manta_debuglevel); - std::ostringstream ss; + ostringstream ss; ss << "set_manta_debuglevel(" << with_debug << ")"; pythonCommands.push_back(ss.str()); // Now init basic fluid domain - std::string tmpString = fluid_variables + fluid_solver + fluid_alloc + fluid_cache_helper + - fluid_bake_multiprocessing + fluid_bake_data + fluid_bake_noise + - fluid_bake_mesh + fluid_bake_particles + fluid_bake_guiding + - fluid_file_import + fluid_file_export + fluid_save_data + - fluid_load_data + fluid_pre_step + fluid_post_step + - fluid_adapt_time_step + fluid_time_stepping; - std::string finalString = parseScript(tmpString, mmd); + string tmpString = fluid_variables + fluid_solver + fluid_alloc + fluid_cache_helper + + fluid_bake_multiprocessing + fluid_bake_data + fluid_bake_noise + + fluid_bake_mesh + fluid_bake_particles + fluid_bake_guiding + + fluid_file_import + fluid_file_export + fluid_save_data + fluid_load_data + + fluid_pre_step + fluid_post_step + fluid_adapt_time_step + + fluid_time_stepping; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); } void MANTA::initNoise(FluidModifierData *mmd) { - std::vector<std::string> pythonCommands; - std::string tmpString = fluid_variables_noise + fluid_solver_noise; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = fluid_variables_noise + fluid_solver_noise; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -310,10 +321,10 @@ void MANTA::initNoise(FluidModifierData *mmd) void MANTA::initSmoke(FluidModifierData *mmd) { - std::vector<std::string> pythonCommands; - std::string tmpString = smoke_variables + smoke_alloc + smoke_adaptive_step + smoke_save_data + - smoke_load_data + smoke_step; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = smoke_variables + smoke_alloc + smoke_adaptive_step + smoke_save_data + + smoke_load_data + smoke_step; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -321,10 +332,10 @@ void MANTA::initSmoke(FluidModifierData *mmd) void MANTA::initSmokeNoise(FluidModifierData *mmd) { - std::vector<std::string> pythonCommands; - std::string tmpString = smoke_variables_noise + smoke_alloc_noise + smoke_wavelet_noise + - smoke_save_noise + smoke_load_noise + smoke_step_noise; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = smoke_variables_noise + smoke_alloc_noise + smoke_wavelet_noise + + smoke_save_noise + smoke_load_noise + smoke_step_noise; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -334,9 +345,9 @@ void MANTA::initSmokeNoise(FluidModifierData *mmd) void MANTA::initHeat(FluidModifierData *mmd) { if (!mHeat) { - std::vector<std::string> pythonCommands; - std::string tmpString = smoke_alloc_heat + smoke_with_heat; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = smoke_alloc_heat + smoke_with_heat; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -347,9 +358,9 @@ void MANTA::initHeat(FluidModifierData *mmd) void MANTA::initFire(FluidModifierData *mmd) { if (!mFuel) { - std::vector<std::string> pythonCommands; - std::string tmpString = smoke_alloc_fire + smoke_with_fire; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = smoke_alloc_fire + smoke_with_fire; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -360,9 +371,9 @@ void MANTA::initFire(FluidModifierData *mmd) void MANTA::initFireHigh(FluidModifierData *mmd) { if (!mFuelHigh) { - std::vector<std::string> pythonCommands; - std::string tmpString = smoke_alloc_fire_noise + smoke_with_fire; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = smoke_alloc_fire_noise + smoke_with_fire; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -373,9 +384,9 @@ void MANTA::initFireHigh(FluidModifierData *mmd) void MANTA::initColors(FluidModifierData *mmd) { if (!mColorR) { - std::vector<std::string> pythonCommands; - std::string tmpString = smoke_alloc_colors + smoke_init_colors + smoke_with_colors; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = smoke_alloc_colors + smoke_init_colors + smoke_with_colors; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -386,9 +397,9 @@ void MANTA::initColors(FluidModifierData *mmd) void MANTA::initColorsHigh(FluidModifierData *mmd) { if (!mColorRHigh) { - std::vector<std::string> pythonCommands; - std::string tmpString = smoke_alloc_colors_noise + smoke_init_colors_noise + smoke_with_colors; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = smoke_alloc_colors_noise + smoke_init_colors_noise + smoke_with_colors; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -399,10 +410,10 @@ void MANTA::initColorsHigh(FluidModifierData *mmd) void MANTA::initLiquid(FluidModifierData *mmd) { if (!mPhiIn) { - std::vector<std::string> pythonCommands; - std::string tmpString = liquid_variables + liquid_alloc + liquid_init_phi + liquid_save_data + - liquid_load_data + liquid_adaptive_step + liquid_step; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = liquid_variables + liquid_alloc + liquid_init_phi + liquid_save_data + + liquid_load_data + liquid_adaptive_step + liquid_step; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -412,9 +423,9 @@ void MANTA::initLiquid(FluidModifierData *mmd) void MANTA::initMesh(FluidModifierData *mmd) { - std::vector<std::string> pythonCommands; - std::string tmpString = fluid_variables_mesh + fluid_solver_mesh + liquid_load_mesh; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = fluid_variables_mesh + fluid_solver_mesh + liquid_load_mesh; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -423,9 +434,9 @@ void MANTA::initMesh(FluidModifierData *mmd) void MANTA::initLiquidMesh(FluidModifierData *mmd) { - std::vector<std::string> pythonCommands; - std::string tmpString = liquid_alloc_mesh + liquid_step_mesh + liquid_save_mesh; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = liquid_alloc_mesh + liquid_step_mesh + liquid_save_mesh; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -445,9 +456,9 @@ void MANTA::initCurvature(FluidModifierData *mmd) void MANTA::initObstacle(FluidModifierData *mmd) { if (!mPhiObsIn) { - std::vector<std::string> pythonCommands; - std::string tmpString = fluid_alloc_obstacle + fluid_with_obstacle; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = fluid_alloc_obstacle + fluid_with_obstacle; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -458,10 +469,10 @@ void MANTA::initObstacle(FluidModifierData *mmd) void MANTA::initGuiding(FluidModifierData *mmd) { if (!mPhiGuideIn) { - std::vector<std::string> pythonCommands; - std::string tmpString = fluid_variables_guiding + fluid_solver_guiding + fluid_alloc_guiding + - fluid_save_guiding + fluid_load_vel + fluid_load_guiding; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = fluid_variables_guiding + fluid_solver_guiding + fluid_alloc_guiding + + fluid_save_guiding + fluid_load_vel + fluid_load_guiding; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -471,9 +482,9 @@ void MANTA::initGuiding(FluidModifierData *mmd) void MANTA::initFractions(FluidModifierData *mmd) { - std::vector<std::string> pythonCommands; - std::string tmpString = fluid_alloc_fractions + fluid_with_fractions; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = fluid_alloc_fractions + fluid_with_fractions; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -483,9 +494,9 @@ void MANTA::initFractions(FluidModifierData *mmd) void MANTA::initInVelocity(FluidModifierData *mmd) { if (!mInVelocityX) { - std::vector<std::string> pythonCommands; - std::string tmpString = fluid_alloc_invel + fluid_with_invel; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = fluid_alloc_invel + fluid_with_invel; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -496,9 +507,9 @@ void MANTA::initInVelocity(FluidModifierData *mmd) void MANTA::initOutflow(FluidModifierData *mmd) { if (!mPhiOutIn) { - std::vector<std::string> pythonCommands; - std::string tmpString = fluid_alloc_outflow + fluid_with_outflow; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = fluid_alloc_outflow + fluid_with_outflow; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -508,9 +519,9 @@ void MANTA::initOutflow(FluidModifierData *mmd) void MANTA::initSndParts(FluidModifierData *mmd) { - std::vector<std::string> pythonCommands; - std::string tmpString = fluid_variables_particles + fluid_solver_particles; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = fluid_variables_particles + fluid_solver_particles; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -519,11 +530,11 @@ void MANTA::initSndParts(FluidModifierData *mmd) void MANTA::initLiquidSndParts(FluidModifierData *mmd) { if (!mSndParticleData) { - std::vector<std::string> pythonCommands; - std::string tmpString = liquid_alloc_particles + liquid_variables_particles + - liquid_step_particles + fluid_with_sndparts + liquid_load_particles + - liquid_save_particles; - std::string finalString = parseScript(tmpString, mmd); + vector<string> pythonCommands; + string tmpString = liquid_alloc_particles + liquid_variables_particles + + liquid_step_particles + fluid_with_sndparts + liquid_load_particles + + liquid_save_particles; + string finalString = parseScript(tmpString, mmd); pythonCommands.push_back(finalString); runPythonString(pythonCommands); @@ -533,19 +544,22 @@ void MANTA::initLiquidSndParts(FluidModifierData *mmd) MANTA::~MANTA() { if (with_debug) - std::cout << "~FLUID: " << mCurrentID << " with res(" << mResX << ", " << mResY << ", " - << mResZ << ")" << std::endl; + cout << "~FLUID: " << mCurrentID << " with res(" << mResX << ", " << mResY << ", " << mResZ + << ")" << endl; // Destruction string for Python - std::string tmpString = ""; - std::vector<std::string> pythonCommands; + string tmpString = ""; + vector<string> pythonCommands; bool result = false; tmpString += manta_import; tmpString += fluid_delete_all; + // Initializa RNA map with values that Python will need + initializeRNAMap(); + // Leave out mmd argument in parseScript since only looking up IDs - std::string finalString = parseScript(tmpString); + string finalString = parseScript(tmpString); pythonCommands.push_back(finalString); result = runPythonString(pythonCommands); @@ -566,7 +580,7 @@ MANTA::~MANTA() */ static PyObject *manta_main_module = nullptr; -bool MANTA::runPythonString(std::vector<std::string> commands) +bool MANTA::runPythonString(vector<string> commands) { bool success = true; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -575,8 +589,8 @@ bool MANTA::runPythonString(std::vector<std::string> commands) manta_main_module = PyImport_ImportModule("__main__"); } - for (std::vector<std::string>::iterator it = commands.begin(); it != commands.end(); ++it) { - std::string command = *it; + for (vector<string>::iterator it = commands.begin(); it != commands.end(); ++it) { + string command = *it; PyObject *globals_dict = PyModule_GetDict(manta_main_module); PyObject *return_value = PyRun_String( @@ -601,10 +615,10 @@ bool MANTA::runPythonString(std::vector<std::string> commands) void MANTA::initializeMantaflow() { if (with_debug) - std::cout << "Fluid: Initializing Mantaflow framework" << std::endl; + cout << "Fluid: Initializing Mantaflow framework" << endl; - std::string filename = "manta_scene_" + std::to_string(mCurrentID) + ".py"; - std::vector<std::string> fill = std::vector<std::string>(); + string filename = "manta_scene_" + to_string(mCurrentID) + ".py"; + vector<string> fill = vector<string>(); // Initialize extension classes and wrappers srand(0); @@ -616,17 +630,17 @@ void MANTA::initializeMantaflow() void MANTA::terminateMantaflow() { if (with_debug) - std::cout << "Fluid: Releasing Mantaflow framework" << std::endl; + cout << "Fluid: Releasing Mantaflow framework" << endl; PyGILState_STATE gilstate = PyGILState_Ensure(); Pb::finalize(); // Namespace from Mantaflow (registry) PyGILState_Release(gilstate); } -static std::string getCacheFileEnding(char cache_format) +static string getCacheFileEnding(char cache_format) { if (MANTA::with_debug) - std::cout << "MANTA::getCacheFileEnding()" << std::endl; + cout << "MANTA::getCacheFileEnding()" << endl; switch (cache_format) { case FLUID_DOMAIN_FILE_UNI: @@ -640,409 +654,254 @@ static std::string getCacheFileEnding(char cache_format) case FLUID_DOMAIN_FILE_OBJECT: return FLUID_DOMAIN_EXTENSION_OBJ; default: - std::cerr << "Fluid Error -- Could not find file extension. Using default file extension." - << std::endl; + cerr << "Fluid Error -- Could not find file extension. Using default file extension." + << endl; return FLUID_DOMAIN_EXTENSION_UNI; } } -std::string MANTA::getRealValue(const std::string &varName, FluidModifierData *mmd) +static string getBooleanString(int value) { - std::ostringstream ss; - bool is2D = false; - int tmpVar; - float tmpFloat; + return (value) ? "True" : "False"; +} - if (varName == "ID") { - ss << mCurrentID; - return ss.str(); - } +void MANTA::initializeRNAMap(FluidModifierData *mmd) +{ + if (with_debug) + cout << "MANTA::initializeRNAMap()" << endl; + + mRNAMap["ID"] = to_string(mCurrentID); if (!mmd) { - std::cerr << "Fluid Error -- Invalid modifier data." << std::endl; - ss << "ERROR - INVALID MODIFIER DATA"; - return ss.str(); - } - - is2D = (mmd->domain->solver_res == 2); - - if (varName == "USING_SMOKE") - ss << ((mmd->domain->type == FLUID_DOMAIN_TYPE_GAS) ? "True" : "False"); - else if (varName == "USING_LIQUID") - ss << ((mmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) ? "True" : "False"); - else if (varName == "USING_COLORS") - ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_COLORS ? "True" : "False"); - else if (varName == "USING_HEAT") - ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_HEAT ? "True" : "False"); - else if (varName == "USING_FIRE") - ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_FIRE ? "True" : "False"); - else if (varName == "USING_NOISE") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_NOISE ? "True" : "False"); - else if (varName == "USING_OBSTACLE") - ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE ? "True" : "False"); - else if (varName == "USING_GUIDING") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_GUIDE ? "True" : "False"); - else if (varName == "USING_INVEL") - ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL ? "True" : "False"); - else if (varName == "USING_OUTFLOW") - ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW ? "True" : "False"); - else if (varName == "USING_LOG_DISSOLVE") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_DISSOLVE_LOG ? "True" : "False"); - else if (varName == "USING_DISSOLVE") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_DISSOLVE ? "True" : "False"); - else if (varName == "SOLVER_DIM") - ss << mmd->domain->solver_res; - else if (varName == "DO_OPEN") { - tmpVar = (FLUID_DOMAIN_BORDER_BACK | FLUID_DOMAIN_BORDER_FRONT | FLUID_DOMAIN_BORDER_LEFT | - FLUID_DOMAIN_BORDER_RIGHT | FLUID_DOMAIN_BORDER_BOTTOM | FLUID_DOMAIN_BORDER_TOP); - ss << (((mmd->domain->border_collisions & tmpVar) == tmpVar) ? "False" : "True"); - } - else if (varName == "BOUND_CONDITIONS") { - if (mmd->domain->solver_res == 2) { - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_LEFT) == 0) - ss << "x"; - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_RIGHT) == 0) - ss << "X"; - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_FRONT) == 0) - ss << "y"; - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_BACK) == 0) - ss << "Y"; - } - if (mmd->domain->solver_res == 3) { - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_LEFT) == 0) - ss << "x"; - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_RIGHT) == 0) - ss << "X"; - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_FRONT) == 0) - ss << "y"; - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_BACK) == 0) - ss << "Y"; - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_BOTTOM) == 0) - ss << "z"; - if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_TOP) == 0) - ss << "Z"; - } - } - else if (varName == "BOUNDARY_WIDTH") - ss << mmd->domain->boundary_width; - else if (varName == "RES") - ss << mMaxRes; - else if (varName == "RESX") - ss << mResX; - else if (varName == "RESY") - if (is2D) { - ss << mResZ; - } - else { - ss << mResY; - } - else if (varName == "RESZ") { - if (is2D) { - ss << 1; - } - else { - ss << mResZ; - } - } - else if (varName == "FRAME_LENGTH") - ss << mmd->domain->frame_length; - else if (varName == "CFL") - ss << mmd->domain->cfl_condition; - else if (varName == "DT") - ss << mmd->domain->dt; - else if (varName == "TIMESTEPS_MIN") - ss << mmd->domain->timesteps_minimum; - else if (varName == "TIMESTEPS_MAX") - ss << mmd->domain->timesteps_maximum; - else if (varName == "TIME_TOTAL") - ss << mmd->domain->time_total; - else if (varName == "TIME_PER_FRAME") - ss << mmd->domain->time_per_frame; - else if (varName == "VORTICITY") - ss << mmd->domain->vorticity / mConstantScaling; - else if (varName == "FLAME_VORTICITY") - ss << mmd->domain->flame_vorticity / mConstantScaling; - else if (varName == "NOISE_SCALE") - ss << mmd->domain->noise_scale; - else if (varName == "MESH_SCALE") - ss << mmd->domain->mesh_scale; - else if (varName == "PARTICLE_SCALE") - ss << mmd->domain->particle_scale; - else if (varName == "NOISE_RESX") - ss << mResXNoise; - else if (varName == "NOISE_RESY") { - if (is2D) { - ss << mResZNoise; - } - else { - ss << mResYNoise; - } - } - else if (varName == "NOISE_RESZ") { - if (is2D) { - ss << 1; - } - else { - ss << mResZNoise; - } - } - else if (varName == "MESH_RESX") - ss << mResXMesh; - else if (varName == "MESH_RESY") { - if (is2D) { - ss << mResZMesh; - } - else { - ss << mResYMesh; - } - } - else if (varName == "MESH_RESZ") { - if (is2D) { - ss << 1; - } - else { - ss << mResZMesh; - } - } - else if (varName == "PARTICLE_RESX") - ss << mResXParticle; - else if (varName == "PARTICLE_RESY") { - if (is2D) { - ss << mResZParticle; - } - else { - ss << mResYParticle; - } - } - else if (varName == "PARTICLE_RESZ") { - if (is2D) { - ss << 1; - } - else { - ss << mResZParticle; - } - } - else if (varName == "GUIDING_RESX") - ss << mResGuiding[0]; - else if (varName == "GUIDING_RESY") { - if (is2D) { - ss << mResGuiding[2]; - } - else { - ss << mResGuiding[1]; - } + if (with_debug) + cout << "No modifier data given in RNA map setup - returning early" << endl; + return; } - else if (varName == "GUIDING_RESZ") { - if (is2D) { - ss << 1; - } - else { - ss << mResGuiding[2]; - } + + FluidDomainSettings *mds = mmd->domain; + bool is2D = (mds->solver_res == 2); + + string borderCollisions = ""; + if ((mds->border_collisions & FLUID_DOMAIN_BORDER_LEFT) == 0) + borderCollisions += "x"; + if ((mds->border_collisions & FLUID_DOMAIN_BORDER_RIGHT) == 0) + borderCollisions += "X"; + if ((mds->border_collisions & FLUID_DOMAIN_BORDER_FRONT) == 0) + borderCollisions += "y"; + if ((mds->border_collisions & FLUID_DOMAIN_BORDER_BACK) == 0) + borderCollisions += "Y"; + if ((mds->border_collisions & FLUID_DOMAIN_BORDER_BOTTOM) == 0) + borderCollisions += "z"; + if ((mds->border_collisions & FLUID_DOMAIN_BORDER_TOP) == 0) + borderCollisions += "Z"; + + string simulationMethod = ""; + if (mds->simulation_method & FLUID_DOMAIN_METHOD_FLIP) + simulationMethod += "'FLIP'"; + else if (mds->simulation_method & FLUID_DOMAIN_METHOD_APIC) + simulationMethod += "'APIC'"; + + string particleTypesStr = ""; + if (mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) + particleTypesStr += "PtypeSpray"; + if (mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) { + if (!particleTypesStr.empty()) + particleTypesStr += "|"; + particleTypesStr += "PtypeBubble"; + } + if (mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) { + if (!particleTypesStr.empty()) + particleTypesStr += "|"; + particleTypesStr += "PtypeFoam"; + } + if (mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) { + if (!particleTypesStr.empty()) + particleTypesStr += "|"; + particleTypesStr += "PtypeTracer"; + } + if (particleTypesStr.empty()) + particleTypesStr = "0"; + + int particleTypes = (FLUID_DOMAIN_PARTICLE_SPRAY | FLUID_DOMAIN_PARTICLE_BUBBLE | + FLUID_DOMAIN_PARTICLE_FOAM | FLUID_DOMAIN_PARTICLE_TRACER); + + string cacheDirectory(mds->cache_directory); + + float viscosity = mds->viscosity_base * pow(10.0f, -mds->viscosity_exponent); + float domainSize = MAX3(mds->global_size[0], mds->global_size[1], mds->global_size[2]); + + mRNAMap["USING_SMOKE"] = getBooleanString(mds->type == FLUID_DOMAIN_TYPE_GAS); + mRNAMap["USING_LIQUID"] = getBooleanString(mds->type == FLUID_DOMAIN_TYPE_LIQUID); + mRNAMap["USING_COLORS"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS); + mRNAMap["USING_HEAT"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT); + mRNAMap["USING_FIRE"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE); + mRNAMap["USING_NOISE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_NOISE); + mRNAMap["USING_OBSTACLE"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE); + mRNAMap["USING_GUIDING"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_GUIDE); + mRNAMap["USING_INVEL"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL); + mRNAMap["USING_OUTFLOW"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW); + mRNAMap["USING_LOG_DISSOLVE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DISSOLVE_LOG); + mRNAMap["USING_DISSOLVE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DISSOLVE); + mRNAMap["DO_OPEN"] = getBooleanString(mds->border_collisions == 0); + mRNAMap["CACHE_RESUMABLE"] = getBooleanString(mds->cache_type != FLUID_DOMAIN_CACHE_FINAL); + mRNAMap["USING_ADAPTIVETIME"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_TIME); + mRNAMap["USING_SPEEDVECTORS"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS); + mRNAMap["USING_FRACTIONS"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_FRACTIONS); + mRNAMap["DELETE_IN_OBSTACLE"] = getBooleanString(mds->flags & FLUID_DOMAIN_DELETE_IN_OBSTACLE); + mRNAMap["USING_DIFFUSION"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DIFFUSION); + mRNAMap["USING_MESH"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_MESH); + mRNAMap["USING_IMPROVED_MESH"] = getBooleanString(mds->mesh_generator == + FLUID_DOMAIN_MESH_IMPROVED); + mRNAMap["USING_SNDPARTS"] = getBooleanString(mds->particle_type & particleTypes); + mRNAMap["SNDPARTICLE_BOUNDARY_DELETE"] = getBooleanString(mds->sndparticle_boundary == + SNDPARTICLE_BOUNDARY_DELETE); + mRNAMap["SNDPARTICLE_BOUNDARY_PUSHOUT"] = getBooleanString(mds->sndparticle_boundary == + SNDPARTICLE_BOUNDARY_PUSHOUT); + + mRNAMap["SOLVER_DIM"] = to_string(mds->solver_res); + mRNAMap["BOUND_CONDITIONS"] = borderCollisions; + mRNAMap["BOUNDARY_WIDTH"] = to_string(mds->boundary_width); + mRNAMap["RES"] = to_string(mMaxRes); + mRNAMap["RESX"] = to_string(mResX); + mRNAMap["RESY"] = (is2D) ? to_string(mResZ) : to_string(mResY); + mRNAMap["RESZ"] = (is2D) ? to_string(1) : to_string(mResZ); + mRNAMap["TIME_SCALE"] = to_string(mds->time_scale); + mRNAMap["FRAME_LENGTH"] = to_string(mds->frame_length); + mRNAMap["CFL"] = to_string(mds->cfl_condition); + mRNAMap["DT"] = to_string(mds->dt); + mRNAMap["TIMESTEPS_MIN"] = to_string(mds->timesteps_minimum); + mRNAMap["TIMESTEPS_MAX"] = to_string(mds->timesteps_maximum); + mRNAMap["TIME_TOTAL"] = to_string(mds->time_total); + mRNAMap["TIME_PER_FRAME"] = to_string(mds->time_per_frame); + mRNAMap["VORTICITY"] = to_string(mds->vorticity); + mRNAMap["FLAME_VORTICITY"] = to_string(mds->flame_vorticity); + mRNAMap["NOISE_SCALE"] = to_string(mds->noise_scale); + mRNAMap["MESH_SCALE"] = to_string(mds->mesh_scale); + mRNAMap["PARTICLE_SCALE"] = to_string(mds->particle_scale); + mRNAMap["NOISE_RESX"] = to_string(mResXNoise); + mRNAMap["NOISE_RESY"] = (is2D) ? to_string(mResZNoise) : to_string(mResYNoise); + mRNAMap["NOISE_RESZ"] = (is2D) ? to_string(1) : to_string(mResZNoise); + mRNAMap["MESH_RESX"] = to_string(mResXMesh); + mRNAMap["MESH_RESY"] = (is2D) ? to_string(mResZMesh) : to_string(mResYMesh); + mRNAMap["MESH_RESZ"] = (is2D) ? to_string(1) : to_string(mResZMesh); + mRNAMap["PARTICLE_RESX"] = to_string(mResXParticle); + mRNAMap["PARTICLE_RESY"] = (is2D) ? to_string(mResZParticle) : to_string(mResYParticle); + mRNAMap["PARTICLE_RESZ"] = (is2D) ? to_string(1) : to_string(mResZParticle); + mRNAMap["GUIDING_RESX"] = to_string(mResGuiding[0]); + mRNAMap["GUIDING_RESY"] = (is2D) ? to_string(mResGuiding[2]) : to_string(mResGuiding[1]); + mRNAMap["GUIDING_RESZ"] = (is2D) ? to_string(1) : to_string(mResGuiding[2]); + mRNAMap["MIN_RESX"] = to_string(mds->res_min[0]); + mRNAMap["MIN_RESY"] = to_string(mds->res_min[1]); + mRNAMap["MIN_RESZ"] = to_string(mds->res_min[2]); + mRNAMap["BASE_RESX"] = to_string(mds->base_res[0]); + mRNAMap["BASE_RESY"] = to_string(mds->base_res[1]); + mRNAMap["BASE_RESZ"] = to_string(mds->base_res[2]); + mRNAMap["WLT_STR"] = to_string(mds->noise_strength); + mRNAMap["NOISE_POSSCALE"] = to_string(mds->noise_pos_scale); + mRNAMap["NOISE_TIMEANIM"] = to_string(mds->noise_time_anim); + mRNAMap["COLOR_R"] = to_string(mds->active_color[0]); + mRNAMap["COLOR_G"] = to_string(mds->active_color[1]); + mRNAMap["COLOR_B"] = to_string(mds->active_color[2]); + mRNAMap["BUOYANCY_ALPHA"] = to_string(mds->alpha); + mRNAMap["BUOYANCY_BETA"] = to_string(mds->beta); + mRNAMap["DISSOLVE_SPEED"] = to_string(mds->diss_speed); + mRNAMap["BURNING_RATE"] = to_string(mds->burning_rate); + mRNAMap["FLAME_SMOKE"] = to_string(mds->flame_smoke); + mRNAMap["IGNITION_TEMP"] = to_string(mds->flame_ignition); + mRNAMap["MAX_TEMP"] = to_string(mds->flame_max_temp); + mRNAMap["FLAME_SMOKE_COLOR_X"] = to_string(mds->flame_smoke_color[0]); + mRNAMap["FLAME_SMOKE_COLOR_Y"] = to_string(mds->flame_smoke_color[1]); + mRNAMap["FLAME_SMOKE_COLOR_Z"] = to_string(mds->flame_smoke_color[2]); + mRNAMap["CURRENT_FRAME"] = to_string(int(mmd->time)); + mRNAMap["START_FRAME"] = to_string(mds->cache_frame_start); + mRNAMap["END_FRAME"] = to_string(mds->cache_frame_end); + mRNAMap["CACHE_DATA_FORMAT"] = getCacheFileEnding(mds->cache_data_format); + mRNAMap["CACHE_MESH_FORMAT"] = getCacheFileEnding(mds->cache_mesh_format); + mRNAMap["CACHE_NOISE_FORMAT"] = getCacheFileEnding(mds->cache_noise_format); + mRNAMap["CACHE_PARTICLE_FORMAT"] = getCacheFileEnding(mds->cache_particle_format); + mRNAMap["SIMULATION_METHOD"] = simulationMethod; + mRNAMap["FLIP_RATIO"] = to_string(mds->flip_ratio); + mRNAMap["PARTICLE_RANDOMNESS"] = to_string(mds->particle_randomness); + mRNAMap["PARTICLE_NUMBER"] = to_string(mds->particle_number); + mRNAMap["PARTICLE_MINIMUM"] = to_string(mds->particle_minimum); + mRNAMap["PARTICLE_MAXIMUM"] = to_string(mds->particle_maximum); + mRNAMap["PARTICLE_RADIUS"] = to_string(mds->particle_radius); + mRNAMap["FRACTIONS_THRESHOLD"] = to_string(mds->fractions_threshold); + mRNAMap["MESH_CONCAVE_UPPER"] = to_string(mds->mesh_concave_upper); + mRNAMap["MESH_CONCAVE_LOWER"] = to_string(mds->mesh_concave_lower); + mRNAMap["MESH_PARTICLE_RADIUS"] = to_string(mds->mesh_particle_radius); + mRNAMap["MESH_SMOOTHEN_POS"] = to_string(mds->mesh_smoothen_pos); + mRNAMap["MESH_SMOOTHEN_NEG"] = to_string(mds->mesh_smoothen_neg); + mRNAMap["PARTICLE_BAND_WIDTH"] = to_string(mds->particle_band_width); + mRNAMap["SNDPARTICLE_TAU_MIN_WC"] = to_string(mds->sndparticle_tau_min_wc); + mRNAMap["SNDPARTICLE_TAU_MAX_WC"] = to_string(mds->sndparticle_tau_max_wc); + mRNAMap["SNDPARTICLE_TAU_MIN_TA"] = to_string(mds->sndparticle_tau_min_ta); + mRNAMap["SNDPARTICLE_TAU_MAX_TA"] = to_string(mds->sndparticle_tau_max_ta); + mRNAMap["SNDPARTICLE_TAU_MIN_K"] = to_string(mds->sndparticle_tau_min_k); + mRNAMap["SNDPARTICLE_TAU_MAX_K"] = to_string(mds->sndparticle_tau_max_k); + mRNAMap["SNDPARTICLE_K_WC"] = to_string(mds->sndparticle_k_wc); + mRNAMap["SNDPARTICLE_K_TA"] = to_string(mds->sndparticle_k_ta); + mRNAMap["SNDPARTICLE_K_B"] = to_string(mds->sndparticle_k_b); + mRNAMap["SNDPARTICLE_K_D"] = to_string(mds->sndparticle_k_d); + mRNAMap["SNDPARTICLE_L_MIN"] = to_string(mds->sndparticle_l_min); + mRNAMap["SNDPARTICLE_L_MAX"] = to_string(mds->sndparticle_l_max); + mRNAMap["SNDPARTICLE_POTENTIAL_RADIUS"] = to_string(mds->sndparticle_potential_radius); + mRNAMap["SNDPARTICLE_UPDATE_RADIUS"] = to_string(mds->sndparticle_update_radius); + mRNAMap["LIQUID_SURFACE_TENSION"] = to_string(mds->surface_tension); + mRNAMap["FLUID_VISCOSITY"] = to_string(viscosity); + mRNAMap["FLUID_DOMAIN_SIZE"] = to_string(domainSize); + mRNAMap["SNDPARTICLE_TYPES"] = particleTypesStr; + mRNAMap["GUIDING_ALPHA"] = to_string(mds->guide_alpha); + mRNAMap["GUIDING_BETA"] = to_string(mds->guide_beta); + mRNAMap["GUIDING_FACTOR"] = to_string(mds->guide_vel_factor); + mRNAMap["GRAVITY_X"] = to_string(mds->gravity[0]); + mRNAMap["GRAVITY_Y"] = to_string(mds->gravity[1]); + mRNAMap["GRAVITY_Z"] = to_string(mds->gravity[2]); + mRNAMap["CACHE_DIR"] = cacheDirectory; + mRNAMap["NAME_DENSITY"] = FLUID_GRIDNAME_DENSITY; + mRNAMap["NAME_SHADOW"] = FLUID_GRIDNAME_SHADOW; + mRNAMap["NAME_HEAT"] = FLUID_GRIDNAME_HEAT; + mRNAMap["NAME_VELOCITY"] = FLUID_GRIDNAME_VELOCITY; + mRNAMap["NAME_COLORR"] = FLUID_GRIDNAME_COLORR; + mRNAMap["NAME_COLORG"] = FLUID_GRIDNAME_COLORG; + mRNAMap["NAME_COLORB"] = FLUID_GRIDNAME_COLORB; + mRNAMap["NAME_FLAME"] = FLUID_GRIDNAME_FLAME; + mRNAMap["NAME_FUEL"] = FLUID_GRIDNAME_FUEL; + mRNAMap["NAME_REACT"] = FLUID_GRIDNAME_REACT; + mRNAMap["NAME_DENSITYNOISE"] = FLUID_GRIDNAME_DENSITYNOISE; + mRNAMap["NAME_COLORRNOISE"] = FLUID_GRIDNAME_COLORRNOISE; + mRNAMap["NAME_COLORGNOISE"] = FLUID_GRIDNAME_COLORGNOISE; + mRNAMap["NAME_COLORBNOISE"] = FLUID_GRIDNAME_COLORBNOISE; + mRNAMap["NAME_FLAMENOISE"] = FLUID_GRIDNAME_FLAMENOISE; + mRNAMap["NAME_FUELNOISE"] = FLUID_GRIDNAME_FUELNOISE; + mRNAMap["NAME_REACTNOISE"] = FLUID_GRIDNAME_REACTNOISE; +} + +string MANTA::getRealValue(const string &varName) +{ + if (with_debug) + cout << "MANTA::getRealValue()" << endl; + + unordered_map<string, string>::iterator it; + it = mRNAMap.find(varName); + + if (it == mRNAMap.end()) { + cerr << "Fluid Error -- variable " << varName << " not found in RNA map " << it->second + << endl; + return ""; } - else if (varName == "MIN_RESX") - ss << mmd->domain->res_min[0]; - else if (varName == "MIN_RESY") - ss << mmd->domain->res_min[1]; - else if (varName == "MIN_RESZ") - ss << mmd->domain->res_min[2]; - else if (varName == "BASE_RESX") - ss << mmd->domain->base_res[0]; - else if (varName == "BASE_RESY") - ss << mmd->domain->base_res[1]; - else if (varName == "BASE_RESZ") - ss << mmd->domain->base_res[2]; - else if (varName == "WLT_STR") - ss << mmd->domain->noise_strength; - else if (varName == "NOISE_POSSCALE") - ss << mmd->domain->noise_pos_scale; - else if (varName == "NOISE_TIMEANIM") - ss << mmd->domain->noise_time_anim; - else if (varName == "COLOR_R") - ss << mmd->domain->active_color[0]; - else if (varName == "COLOR_G") - ss << mmd->domain->active_color[1]; - else if (varName == "COLOR_B") - ss << mmd->domain->active_color[2]; - else if (varName == "BUOYANCY_ALPHA") - ss << mmd->domain->alpha; - else if (varName == "BUOYANCY_BETA") - ss << mmd->domain->beta; - else if (varName == "DISSOLVE_SPEED") - ss << mmd->domain->diss_speed; - else if (varName == "BURNING_RATE") - ss << mmd->domain->burning_rate; - else if (varName == "FLAME_SMOKE") - ss << mmd->domain->flame_smoke; - else if (varName == "IGNITION_TEMP") - ss << mmd->domain->flame_ignition; - else if (varName == "MAX_TEMP") - ss << mmd->domain->flame_max_temp; - else if (varName == "FLAME_SMOKE_COLOR_X") - ss << mmd->domain->flame_smoke_color[0]; - else if (varName == "FLAME_SMOKE_COLOR_Y") - ss << mmd->domain->flame_smoke_color[1]; - else if (varName == "FLAME_SMOKE_COLOR_Z") - ss << mmd->domain->flame_smoke_color[2]; - else if (varName == "CURRENT_FRAME") - ss << mmd->time; - else if (varName == "START_FRAME") - ss << mmd->domain->cache_frame_start; - else if (varName == "END_FRAME") - ss << mmd->domain->cache_frame_end; - else if (varName == "CACHE_DATA_FORMAT") - ss << getCacheFileEnding(mmd->domain->cache_data_format); - else if (varName == "CACHE_MESH_FORMAT") - ss << getCacheFileEnding(mmd->domain->cache_mesh_format); - else if (varName == "CACHE_NOISE_FORMAT") - ss << getCacheFileEnding(mmd->domain->cache_noise_format); - else if (varName == "CACHE_PARTICLE_FORMAT") - ss << getCacheFileEnding(mmd->domain->cache_particle_format); - else if (varName == "SIMULATION_METHOD") { - if (mmd->domain->simulation_method & FLUID_DOMAIN_METHOD_FLIP) { - ss << "'FLIP'"; - } - else if (mmd->domain->simulation_method & FLUID_DOMAIN_METHOD_APIC) { - ss << "'APIC'"; - } - else { - ss << "'NONE'"; - } + if (with_debug) { + cout << "Found variable " << varName << " with value " << it->second << endl; } - else if (varName == "FLIP_RATIO") - ss << mmd->domain->flip_ratio; - else if (varName == "PARTICLE_RANDOMNESS") - ss << mmd->domain->particle_randomness; - else if (varName == "PARTICLE_NUMBER") - ss << mmd->domain->particle_number; - else if (varName == "PARTICLE_MINIMUM") - ss << mmd->domain->particle_minimum; - else if (varName == "PARTICLE_MAXIMUM") - ss << mmd->domain->particle_maximum; - else if (varName == "PARTICLE_RADIUS") - ss << mmd->domain->particle_radius; - else if (varName == "FRACTIONS_THRESHOLD") - ss << mmd->domain->fractions_threshold; - else if (varName == "MESH_CONCAVE_UPPER") - ss << mmd->domain->mesh_concave_upper; - else if (varName == "MESH_CONCAVE_LOWER") - ss << mmd->domain->mesh_concave_lower; - else if (varName == "MESH_PARTICLE_RADIUS") - ss << mmd->domain->mesh_particle_radius; - else if (varName == "MESH_SMOOTHEN_POS") - ss << mmd->domain->mesh_smoothen_pos; - else if (varName == "MESH_SMOOTHEN_NEG") - ss << mmd->domain->mesh_smoothen_neg; - else if (varName == "USING_MESH") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_MESH ? "True" : "False"); - else if (varName == "USING_IMPROVED_MESH") - ss << (mmd->domain->mesh_generator == FLUID_DOMAIN_MESH_IMPROVED ? "True" : "False"); - else if (varName == "PARTICLE_BAND_WIDTH") - ss << mmd->domain->particle_band_width; - else if (varName == "SNDPARTICLE_TAU_MIN_WC") - ss << mmd->domain->sndparticle_tau_min_wc; - else if (varName == "SNDPARTICLE_TAU_MAX_WC") - ss << mmd->domain->sndparticle_tau_max_wc; - else if (varName == "SNDPARTICLE_TAU_MIN_TA") - ss << mmd->domain->sndparticle_tau_min_ta; - else if (varName == "SNDPARTICLE_TAU_MAX_TA") - ss << mmd->domain->sndparticle_tau_max_ta; - else if (varName == "SNDPARTICLE_TAU_MIN_K") - ss << mmd->domain->sndparticle_tau_min_k; - else if (varName == "SNDPARTICLE_TAU_MAX_K") - ss << mmd->domain->sndparticle_tau_max_k; - else if (varName == "SNDPARTICLE_K_WC") - ss << mmd->domain->sndparticle_k_wc; - else if (varName == "SNDPARTICLE_K_TA") - ss << mmd->domain->sndparticle_k_ta; - else if (varName == "SNDPARTICLE_K_B") - ss << mmd->domain->sndparticle_k_b; - else if (varName == "SNDPARTICLE_K_D") - ss << mmd->domain->sndparticle_k_d; - else if (varName == "SNDPARTICLE_L_MIN") - ss << mmd->domain->sndparticle_l_min; - else if (varName == "SNDPARTICLE_L_MAX") - ss << mmd->domain->sndparticle_l_max; - else if (varName == "SNDPARTICLE_BOUNDARY_DELETE") - ss << (mmd->domain->sndparticle_boundary == SNDPARTICLE_BOUNDARY_DELETE); - else if (varName == "SNDPARTICLE_BOUNDARY_PUSHOUT") - ss << (mmd->domain->sndparticle_boundary == SNDPARTICLE_BOUNDARY_PUSHOUT); - else if (varName == "SNDPARTICLE_POTENTIAL_RADIUS") - ss << mmd->domain->sndparticle_potential_radius; - else if (varName == "SNDPARTICLE_UPDATE_RADIUS") - ss << mmd->domain->sndparticle_update_radius; - else if (varName == "LIQUID_SURFACE_TENSION") - ss << mmd->domain->surface_tension; - else if (varName == "FLUID_VISCOSITY") - ss << mmd->domain->viscosity_base * pow(10.0f, -mmd->domain->viscosity_exponent); - else if (varName == "FLUID_DOMAIN_SIZE") { - tmpFloat = MAX3( - mmd->domain->global_size[0], mmd->domain->global_size[1], mmd->domain->global_size[2]); - ss << tmpFloat; - } - else if (varName == "SNDPARTICLE_TYPES") { - if (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) { - ss << "PtypeSpray"; - } - if (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) { - if (!ss.str().empty()) - ss << "|"; - ss << "PtypeBubble"; - } - if (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) { - if (!ss.str().empty()) - ss << "|"; - ss << "PtypeFoam"; - } - if (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) { - if (!ss.str().empty()) - ss << "|"; - ss << "PtypeTracer"; - } - if (ss.str().empty()) - ss << "0"; - } - else if (varName == "USING_SNDPARTS") { - tmpVar = (FLUID_DOMAIN_PARTICLE_SPRAY | FLUID_DOMAIN_PARTICLE_BUBBLE | - FLUID_DOMAIN_PARTICLE_FOAM | FLUID_DOMAIN_PARTICLE_TRACER); - ss << (((mmd->domain->particle_type & tmpVar)) ? "True" : "False"); - } - else if (varName == "GUIDING_ALPHA") - ss << mmd->domain->guide_alpha; - else if (varName == "GUIDING_BETA") - ss << mmd->domain->guide_beta; - else if (varName == "GUIDING_FACTOR") - ss << mmd->domain->guide_vel_factor; - else if (varName == "GRAVITY_X") - ss << mmd->domain->gravity[0]; - else if (varName == "GRAVITY_Y") - ss << mmd->domain->gravity[1]; - else if (varName == "GRAVITY_Z") - ss << mmd->domain->gravity[2]; - else if (varName == "CACHE_DIR") - ss << mmd->domain->cache_directory; - else if (varName == "CACHE_RESUMABLE") - ss << (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL ? "False" : "True"); - else if (varName == "USING_ADAPTIVETIME") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_ADAPTIVE_TIME ? "True" : "False"); - else if (varName == "USING_SPEEDVECTORS") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_SPEED_VECTORS ? "True" : "False"); - else if (varName == "USING_FRACTIONS") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_FRACTIONS ? "True" : "False"); - else if (varName == "DELETE_IN_OBSTACLE") - ss << (mmd->domain->flags & FLUID_DOMAIN_DELETE_IN_OBSTACLE ? "True" : "False"); - else if (varName == "USING_DIFFUSION") - ss << (mmd->domain->flags & FLUID_DOMAIN_USE_DIFFUSION ? "True" : "False"); - else - std::cerr << "Fluid Error -- Unknown option: " << varName << std::endl; - return ss.str(); -} - -std::string MANTA::parseLine(const std::string &line, FluidModifierData *mmd) + + return it->second; +} + +string MANTA::parseLine(const string &line) { if (line.size() == 0) return ""; - std::string res = ""; + string res = ""; int currPos = 0, start_del = 0, end_del = -1; bool readingVar = false; const char delimiter = '$'; @@ -1055,7 +914,7 @@ std::string MANTA::parseLine(const std::string &line, FluidModifierData *mmd) else if (line[currPos] == delimiter && readingVar) { readingVar = false; end_del = currPos; - res += getRealValue(line.substr(start_del, currPos - start_del), mmd); + res += getRealValue(line.substr(start_del, currPos - start_del)); } currPos++; } @@ -1063,13 +922,21 @@ std::string MANTA::parseLine(const std::string &line, FluidModifierData *mmd) return res; } -std::string MANTA::parseScript(const std::string &setup_string, FluidModifierData *mmd) +string MANTA::parseScript(const string &setup_string, FluidModifierData *mmd) { - std::istringstream f(setup_string); - std::ostringstream res; - std::string line = ""; + if (MANTA::with_debug) + cout << "MANTA::parseScript()" << endl; + + istringstream f(setup_string); + ostringstream res; + string line = ""; + + // Update RNA map if modifier data is handed over + if (mmd) { + initializeRNAMap(mmd); + } while (getline(f, line)) { - res << parseLine(line, mmd) << "\n"; + res << parseLine(line) << "\n"; } return res.str(); } @@ -1077,13 +944,14 @@ std::string MANTA::parseScript(const std::string &setup_string, FluidModifierDat bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr) { if (MANTA::with_debug) - std::cout << "MANTA::updateFlipStructures()" << std::endl; + cout << "MANTA::updateFlipStructures()" << endl; + FluidDomainSettings *mds = mmd->domain; mFlipFromFile = false; if (!mUsingLiquid) return false; - if (BLI_path_is_rel(mmd->domain->cache_directory)) + if (BLI_path_is_rel(mds->cache_directory)) return false; int result = 0; @@ -1096,9 +964,8 @@ bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr) mFlipParticleData->clear(); mFlipParticleVelocity->clear(); - std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); - std::string file = getFile( - mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_PP, pformat.c_str(), framenr); + string pformat = getCacheFileEnding(mds->cache_particle_format); + string file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_PP, pformat, framenr); expected += 1; if (BLI_exists(file.c_str())) { @@ -1106,7 +973,7 @@ bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr) assert(result == expected); } - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_PVEL, pformat.c_str(), framenr); + file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_PVEL, pformat, framenr); expected += 1; if (BLI_exists(file.c_str())) { result += updateParticlesFromFile(file, false, true); @@ -1119,13 +986,14 @@ bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr) bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr) { if (MANTA::with_debug) - std::cout << "MANTA::updateMeshStructures()" << std::endl; + cout << "MANTA::updateMeshStructures()" << endl; + FluidDomainSettings *mds = mmd->domain; mMeshFromFile = false; if (!mUsingMesh) return false; - if (BLI_path_is_rel(mmd->domain->cache_directory)) + if (BLI_path_is_rel(mds->cache_directory)) return false; int result = 0; @@ -1141,9 +1009,9 @@ bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr) if (mMeshVelocities) mMeshVelocities->clear(); - std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format); - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, mformat, framenr); + string mformat = getCacheFileEnding(mds->cache_mesh_format); + string dformat = getCacheFileEnding(mds->cache_data_format); + string file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_FILENAME_MESH, mformat, framenr); expected += 1; if (BLI_exists(file.c_str())) { @@ -1152,7 +1020,7 @@ bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr) } if (mUsingMVel) { - file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESHVEL, dformat, framenr); + file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_FILENAME_MESHVEL, dformat, framenr); expected += 1; if (BLI_exists(file.c_str())) { result += updateMeshFromFile(file); @@ -1166,13 +1034,14 @@ bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr) bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr) { if (MANTA::with_debug) - std::cout << "MANTA::updateParticleStructures()" << std::endl; + cout << "MANTA::updateParticleStructures()" << endl; + FluidDomainSettings *mds = mmd->domain; mParticlesFromFile = false; if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers) return false; - if (BLI_path_is_rel(mmd->domain->cache_directory)) + if (BLI_path_is_rel(mds->cache_directory)) return false; int result = 0; @@ -1186,9 +1055,8 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr) mSndParticleVelocity->clear(); mSndParticleLife->clear(); - std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); - std::string file = getFile( - mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PPSND, pformat, framenr); + string pformat = getCacheFileEnding(mds->cache_particle_format); + string file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_FILENAME_PPSND, pformat, framenr); expected += 1; if (BLI_exists(file.c_str())) { @@ -1196,14 +1064,14 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr) assert(result == expected); } - file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PVELSND, pformat, framenr); + file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_FILENAME_PVELSND, pformat, framenr); expected += 1; if (BLI_exists(file.c_str())) { result += updateParticlesFromFile(file, true, true); assert(result == expected); } - file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PLIFESND, pformat, framenr); + file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_FILENAME_PLIFESND, pformat, framenr); expected += 1; if (BLI_exists(file.c_str())) { result += updateParticlesFromFile(file, true, false); @@ -1213,183 +1081,278 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr) return mParticlesFromFile = (result == expected); } +static void assertGridItems(vector<MANTA::GridItem> gList) +{ + vector<MANTA::GridItem>::iterator gIter = gList.begin(); + int *resPrev = (*gIter).res; + + for (vector<MANTA::GridItem>::iterator it = gList.begin(); it != gList.end(); ++it) { + MANTA::GridItem item = *it; + assert( + ELEM(item.type, FLUID_DOMAIN_GRID_FLOAT, FLUID_DOMAIN_GRID_INT, FLUID_DOMAIN_GRID_VEC3F)); + assert(item.pointer[0]); + if (item.type == FLUID_DOMAIN_GRID_VEC3F) { + assert(item.pointer[1] && item.pointer[2]); + } + assert(item.res[0] == resPrev[0] && item.res[1] == resPrev[1] && item.res[2] == resPrev[2]); + assert((item.name).compare("") != 0); + } + + UNUSED_VARS(resPrev); +} + bool MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr) { if (MANTA::with_debug) - std::cout << "MANTA::updateGridStructures()" << std::endl; + cout << "MANTA::updateGridStructures()" << endl; + FluidDomainSettings *mds = mmd->domain; mSmokeFromFile = false; if (!mUsingSmoke) return false; - if (BLI_path_is_rel(mmd->domain->cache_directory)) + if (BLI_path_is_rel(mds->cache_directory)) return false; int result = 0; - int expected = 0; /* Expected number of read successes for this frame. */ - - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string file = getFile( - mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_DENSITY, dformat, framenr); - - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mDensity, false); - assert(result == expected); - } - - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_SHADOW, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mShadow, false); - assert(result == expected); - } - - if (mUsingHeat) { - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_HEAT, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mHeat, false); - assert(result == expected); - } - } - - if (mUsingColors) { - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORR, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mColorR, false); - assert(result == expected); - } - - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORG, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mColorG, false); - assert(result == expected); - } - - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORB, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mColorB, false); - assert(result == expected); - } - } - - if (mUsingFire) { - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_FLAME, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mFlame, false); - assert(result == expected); - } - - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_FUEL, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mFuel, false); - assert(result == expected); - } - - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_REACT, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mReact, false); - assert(result == expected); - } - } - - return mSmokeFromFile = (result == expected); + string dformat = getCacheFileEnding(mds->cache_data_format); + + vector<FileItem> filesData; + vector<GridItem> gridsData; + + int res[] = {mResX, mResY, mResZ}; + + /* Put grid pointers into pointer lists, some grids have more than 1 pointer. */ + void *aDensity[] = {mDensity}; + void *aShadow[] = {mShadow}; + void *aVelocities[] = {mVelocityX, mVelocityY, mVelocityZ}; + void *aHeat[] = {mHeat}; + void *aColorR[] = {mColorR}; + void *aColorG[] = {mColorG}; + void *aColorB[] = {mColorB}; + void *aFlame[] = {mFlame}; + void *aFuel[] = {mFuel}; + void *aReact[] = {mReact}; + + /* File names for grids. */ + string fDensity = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_DENSITY, dformat, framenr); + string fShadow = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_SHADOW, dformat, framenr); + string fVel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_VELOCITY, dformat, framenr); + string fHeat = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_HEAT, dformat, framenr); + string fColorR = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_COLORR, dformat, framenr); + string fColorG = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_COLORG, dformat, framenr); + string fColorB = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_COLORB, dformat, framenr); + string fFlame = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_FLAME, dformat, framenr); + string fFuel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_FUEL, dformat, framenr); + string fReact = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_REACT, dformat, framenr); + string fFluid = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_DATA, dformat, framenr); + + /* Prepare grid info containers. */ + GridItem gDensity = {aDensity, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_DENSITY}; + GridItem gShadow = {aShadow, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_SHADOW}; + GridItem gVel = {aVelocities, FLUID_DOMAIN_GRID_VEC3F, res, FLUID_GRIDNAME_VELOCITY}; + GridItem gHeat = {aHeat, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_HEAT}; + GridItem gColorR = {aColorR, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_COLORR}; + GridItem gColorG = {aColorG, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_COLORG}; + GridItem gColorB = {aColorB, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_COLORB}; + GridItem gFlame = {aFlame, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_FLAME}; + GridItem gFuel = {aFuel, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_FUEL}; + GridItem gReact = {aReact, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_REACT}; + + /* TODO (sebbas): For now, only allow single file mode. Combined grid file export is todo. */ + const int fileMode = FLUID_DOMAIN_CACHE_FILES_SINGLE; + if (fileMode == FLUID_DOMAIN_CACHE_FILES_SINGLE) { + + filesData.push_back({fDensity, {gDensity}}); + filesData.push_back({fShadow, {gShadow}}); + filesData.push_back({fVel, {gVel}}); + if (mUsingHeat) { + filesData.push_back({fHeat, {gHeat}}); + } + if (mUsingColors) { + filesData.push_back({fColorR, {gColorR}}); + filesData.push_back({fColorG, {gColorG}}); + filesData.push_back({fColorB, {gColorB}}); + } + if (mUsingFire) { + filesData.push_back({fFlame, {gFlame}}); + filesData.push_back({fFuel, {gFuel}}); + filesData.push_back({fReact, {gReact}}); + } + } + else if (fileMode == FLUID_DOMAIN_CACHE_FILES_COMBINED) { + + gridsData.push_back(gDensity); + gridsData.push_back(gShadow); + gridsData.push_back(gVel); + if (mUsingHeat) { + gridsData.push_back(gHeat); + } + if (mUsingColors) { + gridsData.push_back(gColorR); + gridsData.push_back(gColorG); + gridsData.push_back(gColorB); + } + if (mUsingFire) { + gridsData.push_back(gFlame); + gridsData.push_back(gFuel); + gridsData.push_back(gReact); + } + + if (with_debug) { + assertGridItems(gridsData); + } + filesData.push_back({fFluid, gridsData}); + } + + /* Update files from data directory. */ + for (vector<FileItem>::iterator it = filesData.begin(); it != filesData.end(); ++it) { + FileItem item = *it; + if (BLI_exists(item.filename.c_str())) { + result += updateGridsFromFile(item.filename, item.grids); + assert(result); + } + } + + return mSmokeFromFile = result; } bool MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr) { if (MANTA::with_debug) - std::cout << "MANTA::updateNoiseStructures()" << std::endl; + cout << "MANTA::updateNoiseStructures()" << endl; + FluidDomainSettings *mds = mmd->domain; mNoiseFromFile = false; if (!mUsingSmoke || !mUsingNoise) return false; - if (BLI_path_is_rel(mmd->domain->cache_directory)) + if (BLI_path_is_rel(mds->cache_directory)) return false; int result = 0; - int expected = 0; /* Expected number of read successes for this frame. */ + string dformat = getCacheFileEnding(mds->cache_data_format); + string nformat = getCacheFileEnding(mds->cache_noise_format); + + vector<FileItem> filesData, filesNoise; + vector<GridItem> gridsData, gridsNoise; + + int resData[] = {mResX, mResY, mResZ}; + int resNoise[] = {mResXNoise, mResYNoise, mResZNoise}; + + /* Put grid pointers into pointer lists, some grids have more than 1 pointer. */ + void *aShadow[] = {mShadow}; + void *aVelocities[] = {mVelocityX, mVelocityY, mVelocityZ}; + void *aDensity[] = {mDensityHigh}; + void *aColorR[] = {mColorRHigh}; + void *aColorG[] = {mColorGHigh}; + void *aColorB[] = {mColorBHigh}; + void *aFlame[] = {mFlameHigh}; + void *aFuel[] = {mFuelHigh}; + void *aReact[] = {mReactHigh}; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); - std::string file = getFile( - mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_DENSITYNOISE, nformat, framenr); + /* File names for grids. */ + string fShadow = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_SHADOW, dformat, framenr); + string fVel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_VELOCITY, dformat, framenr); + string fFluid = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_DATA, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mDensityHigh, true); - assert(result == expected); - } + string fDensity = getFile( + mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_DENSITYNOISE, nformat, framenr); + string fColorR = getFile( + mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_COLORRNOISE, nformat, framenr); + string fColorG = getFile( + mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_COLORGNOISE, nformat, framenr); + string fColorB = getFile( + mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_COLORBNOISE, nformat, framenr); + string fFlame = getFile( + mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_FLAMENOISE, nformat, framenr); + string fFuel = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_FUELNOISE, nformat, framenr); + string fReact = getFile( + mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_REACTNOISE, nformat, framenr); + string fNoise = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_NOISE, nformat, framenr); - file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_SHADOW, dformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mShadow, false); - assert(result == expected); - } + /* Prepare grid info containers. */ + GridItem gShadow = {aShadow, FLUID_DOMAIN_GRID_FLOAT, resData, FLUID_GRIDNAME_SHADOW}; + GridItem gVel = {aVelocities, FLUID_DOMAIN_GRID_VEC3F, resData, FLUID_GRIDNAME_VELOCITY}; - if (mUsingColors) { - file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORRNOISE, nformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mColorRHigh, true); - assert(result == expected); - } + GridItem gDensity = {aDensity, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_DENSITYNOISE}; + GridItem gColorR = {aColorR, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_COLORRNOISE}; + GridItem gColorG = {aColorG, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_COLORGNOISE}; + GridItem gColorB = {aColorB, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_COLORBNOISE}; + GridItem gFlame = {aFlame, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_FLAMENOISE}; + GridItem gFuel = {aFuel, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_FUELNOISE}; + GridItem gReact = {aReact, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_REACTNOISE}; - file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORGNOISE, nformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mColorGHigh, true); - assert(result == expected); - } + /* TODO (sebbas): For now, only allow single file mode. Combined grid file export is todo. */ + const int fileMode = FLUID_DOMAIN_CACHE_FILES_SINGLE; + if (fileMode == FLUID_DOMAIN_CACHE_FILES_SINGLE) { - file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORBNOISE, nformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mColorBHigh, true); - assert(result == expected); + filesData.push_back({fShadow, {gShadow}}); + filesData.push_back({fVel, {gVel}}); + + filesNoise.push_back({fDensity, {gDensity}}); + if (mUsingColors) { + filesNoise.push_back({fColorR, {gColorR}}); + filesNoise.push_back({fColorG, {gColorG}}); + filesNoise.push_back({fColorB, {gColorB}}); + } + if (mUsingFire) { + filesNoise.push_back({fFlame, {gFlame}}); + filesNoise.push_back({fFuel, {gFuel}}); + filesNoise.push_back({fReact, {gReact}}); } } + else if (fileMode == FLUID_DOMAIN_CACHE_FILES_COMBINED) { - if (mUsingFire) { - file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_FLAMENOISE, nformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mFlameHigh, true); - assert(result == expected); + gridsData.push_back(gShadow); + gridsData.push_back(gVel); + + gridsNoise.push_back(gDensity); + if (mUsingColors) { + gridsNoise.push_back(gColorR); + gridsNoise.push_back(gColorG); + gridsNoise.push_back(gColorB); + } + if (mUsingFire) { + gridsNoise.push_back(gFlame); + gridsNoise.push_back(gFuel); + gridsNoise.push_back(gReact); } - file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_FUELNOISE, nformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mFuelHigh, true); - assert(result == expected); + if (with_debug) { + assertGridItems(gridsData); + assertGridItems(gridsNoise); } + filesData.push_back({fFluid, gridsData}); + filesNoise.push_back({fNoise, gridsNoise}); + } - file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_REACTNOISE, nformat, framenr); - expected += 1; - if (BLI_exists(file.c_str())) { - result += updateGridFromFile(file, mReactHigh, true); - assert(result == expected); + /* Update files from data directory. */ + for (vector<FileItem>::iterator it = filesData.begin(); it != filesData.end(); ++it) { + FileItem item = *it; + if (BLI_exists(item.filename.c_str())) { + result += updateGridsFromFile(item.filename, item.grids); + assert(result); + } + } + + /* Update files from noise directory. */ + for (vector<FileItem>::iterator it = filesNoise.begin(); it != filesNoise.end(); ++it) { + FileItem item = *it; + if (BLI_exists(item.filename.c_str())) { + result += updateGridsFromFile(item.filename, item.grids); + assert(result); } } - return mNoiseFromFile = (result == expected); + return mNoiseFromFile = result; } /* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */ -static std::string escapeSlashes(std::string const &s) +static string escapeSlashes(string const &s) { - std::string result = ""; - for (std::string::const_iterator i = s.begin(), end = s.end(); i != end; ++i) { + string result = ""; + for (string::const_iterator i = s.begin(), end = s.end(); i != end; ++i) { unsigned char c = *i; if (c == '\\') result += "\\\\"; @@ -1402,21 +1365,20 @@ static std::string escapeSlashes(std::string const &s) bool MANTA::writeConfiguration(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::writeConfiguration()" << std::endl; + cout << "MANTA::writeConfiguration()" << endl; FluidDomainSettings *mds = mmd->domain; - std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG); - std::string format = FLUID_DOMAIN_EXTENSION_UNI; - std::string file = getFile( - mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr); + string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG); + string format = FLUID_DOMAIN_EXTENSION_UNI; + string file = getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_FILENAME_CONFIG, format, framenr); /* Create 'config' subdir if it does not exist already. */ BLI_dir_create_recursive(directory.c_str()); gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "wb1"); // do some compression if (!gzf) { - std::cerr << "Fluid Error -- Cannot open file " << file << std::endl; + cerr << "Fluid Error -- Cannot open file " << file << endl; return false; } @@ -1434,6 +1396,7 @@ bool MANTA::writeConfiguration(FluidModifierData *mmd, int framenr) gzwrite(gzf, &mds->res_min, 3 * sizeof(int)); gzwrite(gzf, &mds->res_max, 3 * sizeof(int)); gzwrite(gzf, &mds->active_color, 3 * sizeof(float)); + gzwrite(gzf, &mds->time_total, sizeof(int)); return (gzclose(gzf) == Z_OK); } @@ -1441,17 +1404,18 @@ bool MANTA::writeConfiguration(FluidModifierData *mmd, int framenr) bool MANTA::writeData(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::writeData()" << std::endl; + cout << "MANTA::writeData()" << endl; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; - std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA); - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA); + string dformat = getCacheFileEnding(mds->cache_data_format); + string pformat = getCacheFileEnding(mds->cache_particle_format); - bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); - std::string resumable_cache = (final_cache) ? "False" : "True"; + bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL); + string resumable_cache = (final_cache) ? "False" : "True"; ss.str(""); ss << "fluid_save_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr @@ -1476,16 +1440,17 @@ bool MANTA::writeData(FluidModifierData *mmd, int framenr) bool MANTA::writeNoise(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::writeNoise()" << std::endl; + cout << "MANTA::writeNoise()" << endl; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; - std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE); - std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); + string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE); + string nformat = getCacheFileEnding(mds->cache_noise_format); - bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); - std::string resumable_cache = (final_cache) ? "False" : "True"; + bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL); + string resumable_cache = (final_cache) ? "False" : "True"; if (mUsingSmoke && mUsingNoise) { ss.str(""); @@ -1499,22 +1464,21 @@ bool MANTA::writeNoise(FluidModifierData *mmd, int framenr) bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::readConfiguration()" << std::endl; + cout << "MANTA::readConfiguration()" << endl; FluidDomainSettings *mds = mmd->domain; float dummy; - std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG); - std::string format = FLUID_DOMAIN_EXTENSION_UNI; - std::string file = getFile( - mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr); + string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG); + string format = FLUID_DOMAIN_EXTENSION_UNI; + string file = getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_FILENAME_CONFIG, format, framenr); if (!hasConfig(mmd, framenr)) return false; gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "rb"); // do some compression if (!gzf) { - std::cerr << "Fluid Error -- Cannot open file " << file << std::endl; + cerr << "Fluid Error -- Cannot open file " << file << endl; return false; } @@ -1532,6 +1496,8 @@ bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr) gzread(gzf, &mds->res_min, 3 * sizeof(int)); gzread(gzf, &mds->res_max, 3 * sizeof(int)); gzread(gzf, &mds->active_color, 3 * sizeof(float)); + gzread(gzf, &mds->time_total, sizeof(int)); + mds->total_cells = mds->res[0] * mds->res[1] * mds->res[2]; return (gzclose(gzf) == Z_OK); @@ -1540,21 +1506,22 @@ bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr) bool MANTA::readData(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::readData()" << std::endl; + cout << "MANTA::readData()" << endl; if (!mUsingSmoke && !mUsingLiquid) return false; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; bool result = true; - std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA); - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA); + string dformat = getCacheFileEnding(mds->cache_data_format); + string pformat = getCacheFileEnding(mds->cache_particle_format); - bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); - std::string resumable_cache = (final_cache) ? "False" : "True"; + bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL); + string resumable_cache = (final_cache) ? "False" : "True"; /* Sanity check: Are cache files present? */ if (!hasData(mmd, framenr)) @@ -1585,19 +1552,20 @@ bool MANTA::readData(FluidModifierData *mmd, int framenr) bool MANTA::readNoise(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::readNoise()" << std::endl; + cout << "MANTA::readNoise()" << endl; if (!mUsingSmoke || !mUsingNoise) return false; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; - std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE); - std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); + string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE); + string nformat = getCacheFileEnding(mds->cache_noise_format); - bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); - std::string resumable_cache = (final_cache) ? "False" : "True"; + bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL); + string resumable_cache = (final_cache) ? "False" : "True"; /* Sanity check: Are cache files present? */ if (!hasNoise(mmd, framenr)) @@ -1617,17 +1585,18 @@ bool MANTA::readNoise(FluidModifierData *mmd, int framenr) bool MANTA::readMesh(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::readMesh()" << std::endl; + cout << "MANTA::readMesh()" << endl; if (!mUsingLiquid || !mUsingMesh) return false; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; - std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_MESH); - std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format); - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_MESH); + string mformat = getCacheFileEnding(mds->cache_mesh_format); + string dformat = getCacheFileEnding(mds->cache_data_format); /* Sanity check: Are cache files present? */ if (!hasMesh(mmd, framenr)) @@ -1654,21 +1623,22 @@ bool MANTA::readMesh(FluidModifierData *mmd, int framenr) bool MANTA::readParticles(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::readParticles()" << std::endl; + cout << "MANTA::readParticles()" << endl; if (!mUsingLiquid) return false; if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers) return false; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; - std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_PARTICLES); - std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_PARTICLES); + string pformat = getCacheFileEnding(mds->cache_particle_format); - bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); - std::string resumable_cache = (final_cache) ? "False" : "True"; + bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL); + string resumable_cache = (final_cache) ? "False" : "True"; /* Sanity check: Are cache files present? */ if (!hasParticles(mmd, framenr)) @@ -1685,19 +1655,21 @@ bool MANTA::readParticles(FluidModifierData *mmd, int framenr) bool MANTA::readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain) { if (with_debug) - std::cout << "MANTA::readGuiding()" << std::endl; + cout << "MANTA::readGuiding()" << endl; + + FluidDomainSettings *mds = mmd->domain; if (!mUsingGuiding) return false; - if (!mmd->domain) + if (!mds) return false; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; - std::string directory = (sourceDomain) ? getDirectory(mmd, FLUID_DOMAIN_DIR_DATA) : - getDirectory(mmd, FLUID_DOMAIN_DIR_GUIDE); - std::string gformat = getCacheFileEnding(mmd->domain->cache_data_format); + string directory = (sourceDomain) ? getDirectory(mmd, FLUID_DOMAIN_DIR_DATA) : + getDirectory(mmd, FLUID_DOMAIN_DIR_GUIDE); + string gformat = getCacheFileEnding(mds->cache_data_format); /* Sanity check: Are cache files present? */ if (!hasGuiding(mmd, framenr, sourceDomain)) @@ -1721,28 +1693,26 @@ bool MANTA::readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain) bool MANTA::bakeData(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::bakeData()" << std::endl; + cout << "MANTA::bakeData()" << endl; - std::string tmpString, finalString; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + string tmpString, finalString; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; char cacheDirData[FILE_MAX], cacheDirGuiding[FILE_MAX]; cacheDirData[0] = '\0'; cacheDirGuiding[0] = '\0'; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); - std::string gformat = dformat; // Use same data format for guiding format + string dformat = getCacheFileEnding(mds->cache_data_format); + string pformat = getCacheFileEnding(mds->cache_particle_format); + string gformat = dformat; // Use same data format for guiding format - BLI_path_join(cacheDirData, - sizeof(cacheDirData), - mmd->domain->cache_directory, - FLUID_DOMAIN_DIR_DATA, - nullptr); + BLI_path_join( + cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr); BLI_path_join(cacheDirGuiding, sizeof(cacheDirGuiding), - mmd->domain->cache_directory, + mds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, nullptr); BLI_path_make_safe(cacheDirData); @@ -1760,31 +1730,26 @@ bool MANTA::bakeData(FluidModifierData *mmd, int framenr) bool MANTA::bakeNoise(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::bakeNoise()" << std::endl; + cout << "MANTA::bakeNoise()" << endl; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; char cacheDirData[FILE_MAX], cacheDirNoise[FILE_MAX]; cacheDirData[0] = '\0'; cacheDirNoise[0] = '\0'; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); + string dformat = getCacheFileEnding(mds->cache_data_format); + string nformat = getCacheFileEnding(mds->cache_noise_format); - bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); - std::string resumable_cache = (final_cache) ? "False" : "True"; + bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL); + string resumable_cache = (final_cache) ? "False" : "True"; - 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); + BLI_path_join( + cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr); + BLI_path_join( + cacheDirNoise, sizeof(cacheDirNoise), mds->cache_directory, FLUID_DOMAIN_DIR_NOISE, nullptr); BLI_path_make_safe(cacheDirData); BLI_path_make_safe(cacheDirNoise); @@ -1800,29 +1765,24 @@ bool MANTA::bakeNoise(FluidModifierData *mmd, int framenr) bool MANTA::bakeMesh(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::bakeMesh()" << std::endl; + cout << "MANTA::bakeMesh()" << endl; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; char cacheDirData[FILE_MAX], cacheDirMesh[FILE_MAX]; cacheDirData[0] = '\0'; cacheDirMesh[0] = '\0'; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format); - std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + string dformat = getCacheFileEnding(mds->cache_data_format); + string mformat = getCacheFileEnding(mds->cache_mesh_format); + string pformat = getCacheFileEnding(mds->cache_particle_format); - BLI_path_join(cacheDirData, - sizeof(cacheDirData), - mmd->domain->cache_directory, - FLUID_DOMAIN_DIR_DATA, - nullptr); - BLI_path_join(cacheDirMesh, - sizeof(cacheDirMesh), - mmd->domain->cache_directory, - FLUID_DOMAIN_DIR_MESH, - nullptr); + BLI_path_join( + cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr); + BLI_path_join( + cacheDirMesh, sizeof(cacheDirMesh), mds->cache_directory, FLUID_DOMAIN_DIR_MESH, nullptr); BLI_path_make_safe(cacheDirData); BLI_path_make_safe(cacheDirMesh); @@ -1838,29 +1798,27 @@ bool MANTA::bakeMesh(FluidModifierData *mmd, int framenr) bool MANTA::bakeParticles(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::bakeParticles()" << std::endl; + cout << "MANTA::bakeParticles()" << endl; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; char cacheDirData[FILE_MAX], cacheDirParticles[FILE_MAX]; cacheDirData[0] = '\0'; cacheDirParticles[0] = '\0'; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); - std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format); + string dformat = getCacheFileEnding(mds->cache_data_format); + string pformat = getCacheFileEnding(mds->cache_particle_format); - bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); - std::string resumable_cache = (final_cache) ? "False" : "True"; + bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL); + string resumable_cache = (final_cache) ? "False" : "True"; - BLI_path_join(cacheDirData, - sizeof(cacheDirData), - mmd->domain->cache_directory, - FLUID_DOMAIN_DIR_DATA, - nullptr); + BLI_path_join( + cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr); BLI_path_join(cacheDirParticles, sizeof(cacheDirParticles), - mmd->domain->cache_directory, + mds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, nullptr); BLI_path_make_safe(cacheDirData); @@ -1878,22 +1836,23 @@ bool MANTA::bakeParticles(FluidModifierData *mmd, int framenr) bool MANTA::bakeGuiding(FluidModifierData *mmd, int framenr) { if (with_debug) - std::cout << "MANTA::bakeGuiding()" << std::endl; + cout << "MANTA::bakeGuiding()" << endl; - std::ostringstream ss; - std::vector<std::string> pythonCommands; + ostringstream ss; + vector<string> pythonCommands; + FluidDomainSettings *mds = mmd->domain; char cacheDirGuiding[FILE_MAX]; cacheDirGuiding[0] = '\0'; - std::string gformat = getCacheFileEnding(mmd->domain->cache_data_format); + string gformat = getCacheFileEnding(mds->cache_data_format); - bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL); - std::string resumable_cache = (final_cache) ? "False" : "True"; + bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL); + string resumable_cache = (final_cache) ? "False" : "True"; BLI_path_join(cacheDirGuiding, sizeof(cacheDirGuiding), - mmd->domain->cache_directory, + mds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, nullptr); BLI_path_make_safe(cacheDirGuiding); @@ -1908,8 +1867,8 @@ bool MANTA::bakeGuiding(FluidModifierData *mmd, int framenr) bool MANTA::updateVariables(FluidModifierData *mmd) { - std::string tmpString, finalString; - std::vector<std::string> pythonCommands; + string tmpString, finalString; + vector<string> pythonCommands; tmpString += fluid_variables; if (mUsingSmoke) @@ -1939,13 +1898,15 @@ bool MANTA::updateVariables(FluidModifierData *mmd) void MANTA::exportSmokeScript(FluidModifierData *mmd) { if (with_debug) - std::cout << "MANTA::exportSmokeScript()" << std::endl; + cout << "MANTA::exportSmokeScript()" << endl; char cacheDir[FILE_MAX] = "\0"; char cacheDirScript[FILE_MAX] = "\0"; + FluidDomainSettings *mds = mmd->domain; + BLI_path_join( - cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr); + cacheDir, sizeof(cacheDir), mds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr); BLI_path_make_safe(cacheDir); /* Create 'script' subdir if it does not exist already */ BLI_dir_create_recursive(cacheDir); @@ -1953,16 +1914,16 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd) cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_SMOKE_SCRIPT, nullptr); BLI_path_make_safe(cacheDir); - bool noise = mmd->domain->flags & FLUID_DOMAIN_USE_NOISE; - bool heat = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_HEAT; - bool colors = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_COLORS; - bool fire = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_FIRE; - 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; + bool noise = mds->flags & FLUID_DOMAIN_USE_NOISE; + bool heat = mds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT; + bool colors = mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS; + bool fire = mds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE; + bool obstacle = mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE; + bool guiding = mds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE; + bool invel = mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL; + bool outflow = mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW; - std::string manta_script; + string manta_script; // Libraries manta_script += header_libraries + manta_import; @@ -2034,10 +1995,10 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd) manta_script += header_main + smoke_standalone + fluid_standalone; // Fill in missing variables in script - std::string final_script = MANTA::parseScript(manta_script, mmd); + string final_script = MANTA::parseScript(manta_script, mmd); // Write script - std::ofstream myfile; + ofstream myfile; myfile.open(cacheDirScript); myfile << final_script; myfile.close(); @@ -2046,13 +2007,15 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd) void MANTA::exportLiquidScript(FluidModifierData *mmd) { if (with_debug) - std::cout << "MANTA::exportLiquidScript()" << std::endl; + cout << "MANTA::exportLiquidScript()" << endl; char cacheDir[FILE_MAX] = "\0"; char cacheDirScript[FILE_MAX] = "\0"; + FluidDomainSettings *mds = mmd->domain; + BLI_path_join( - cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr); + cacheDir, sizeof(cacheDir), mds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr); BLI_path_make_safe(cacheDir); /* Create 'script' subdir if it does not exist already */ BLI_dir_create_recursive(cacheDir); @@ -2060,18 +2023,18 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_LIQUID_SCRIPT, nullptr); BLI_path_make_safe(cacheDirScript); - bool mesh = mmd->domain->flags & FLUID_DOMAIN_USE_MESH; - bool drops = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY; - bool bubble = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE; - 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; - bool outflow = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW; + bool mesh = mds->flags & FLUID_DOMAIN_USE_MESH; + bool drops = mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY; + bool bubble = mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE; + bool floater = mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM; + bool tracer = mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER; + bool obstacle = mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE; + bool fractions = mds->flags & FLUID_DOMAIN_USE_FRACTIONS; + bool guiding = mds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE; + bool invel = mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL; + bool outflow = mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW; - std::string manta_script; + string manta_script; // Libraries manta_script += header_libraries + manta_import; @@ -2141,10 +2104,10 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) manta_script += header_main + liquid_standalone + fluid_standalone; // Fill in missing variables in script - std::string final_script = MANTA::parseScript(manta_script, mmd); + string final_script = MANTA::parseScript(manta_script, mmd); // Write script - std::ofstream myfile; + ofstream myfile; myfile.open(cacheDirScript); myfile << final_script; myfile.close(); @@ -2157,14 +2120,12 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) * * Important! Return value: New reference or nullptr * Caller of this function needs to handle reference count of returned object. */ -static PyObject *callPythonFunction(std::string varName, - std::string functionName, - bool isAttribute = false) +static PyObject *callPythonFunction(string varName, string functionName, bool isAttribute = false) { if ((varName == "") || (functionName == "")) { if (MANTA::with_debug) - std::cout << "Missing Python variable name and/or function name -- name is: " << varName - << ", function name is: " << functionName << std::endl; + cout << "Missing Python variable name and/or function name -- name is: " << varName + << ", function name is: " << functionName << endl; return nullptr; } @@ -2217,8 +2178,8 @@ static void *pyObjectToPointer(PyObject *inputObject) Py_DECREF(inputObject); - std::string str(result); - std::istringstream in(str); + string str(result); + istringstream in(str); void *dataPointer = nullptr; in >> dataPointer; @@ -2265,11 +2226,11 @@ static long pyObjectToLong(PyObject *inputObject) int MANTA::getFrame() { if (with_debug) - std::cout << "MANTA::getFrame()" << std::endl; + cout << "MANTA::getFrame()" << endl; - std::string func = "frame"; - std::string id = std::to_string(mCurrentID); - std::string solver = "s" + id; + string func = "frame"; + string id = to_string(mCurrentID); + string solver = "s" + id; return pyObjectToLong(callPythonFunction(solver, func, true)); } @@ -2277,11 +2238,11 @@ int MANTA::getFrame() float MANTA::getTimestep() { if (with_debug) - std::cout << "MANTA::getTimestep()" << std::endl; + cout << "MANTA::getTimestep()" << endl; - std::string func = "timestep"; - std::string id = std::to_string(mCurrentID); - std::string solver = "s" + id; + string func = "timestep"; + string id = to_string(mCurrentID); + string solver = "s" + id; return (float)pyObjectToDouble(callPythonFunction(solver, func, true)); } @@ -2295,10 +2256,10 @@ bool MANTA::needsRealloc(FluidModifierData *mmd) void MANTA::adaptTimestep() { if (with_debug) - std::cout << "MANTA::adaptTimestep()" << std::endl; + cout << "MANTA::adaptTimestep()" << endl; - std::vector<std::string> pythonCommands; - std::ostringstream ss; + vector<string> pythonCommands; + ostringstream ss; ss << "fluid_adapt_time_step_" << mCurrentID << "()"; pythonCommands.push_back(ss.str()); @@ -2306,14 +2267,14 @@ void MANTA::adaptTimestep() runPythonString(pythonCommands); } -bool MANTA::updateMeshFromFile(std::string filename) +bool MANTA::updateMeshFromFile(string filename) { - std::string fname(filename); - std::string::size_type idx; + string fname(filename); + string::size_type idx; idx = fname.rfind('.'); - if (idx != std::string::npos) { - std::string extension = fname.substr(idx + 1); + if (idx != string::npos) { + string extension = fname.substr(idx + 1); if (extension.compare("gz") == 0) return updateMeshFromBobj(filename); @@ -2322,27 +2283,25 @@ bool MANTA::updateMeshFromFile(std::string filename) else if (extension.compare("uni") == 0) return updateMeshFromUni(filename); else - std::cerr << "Fluid Error -- updateMeshFromFile(): Invalid file extension in file: " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromFile(): Invalid file extension in file: " << filename + << endl; } else { - std::cerr << "Fluid Error -- updateMeshFromFile(): Unable to open file: " << filename - << std::endl; + cerr << "Fluid Error -- updateMeshFromFile(): Unable to open file: " << filename << endl; } return false; } -bool MANTA::updateMeshFromBobj(std::string filename) +bool MANTA::updateMeshFromBobj(string filename) { if (with_debug) - std::cout << "MANTA::updateMeshFromBobj()" << std::endl; + cout << "MANTA::updateMeshFromBobj()" << endl; gzFile gzf; gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression if (!gzf) { - std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to open file: " << filename - << std::endl; + cerr << "Fluid Error -- updateMeshFromBobj(): Unable to open file: " << filename << endl; return false; } @@ -2351,15 +2310,14 @@ bool MANTA::updateMeshFromBobj(std::string filename) // Num vertices readBytes = gzread(gzf, &numBuffer, sizeof(int)); if (!readBytes) { - std::cerr - << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh vertices from " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh vertices from " + << filename << endl; gzclose(gzf); return false; } if (with_debug) - std::cout << "read mesh , num verts: " << numBuffer << " , in file: " << filename << std::endl; + cout << "read mesh , num verts: " << numBuffer << " , in file: " << filename << endl; int numChunks = (int)(ceil((float)numBuffer / NODE_CHUNK)); int readLen, readStart, readEnd, k; @@ -2380,8 +2338,8 @@ bool MANTA::updateMeshFromBobj(std::string filename) readBytes = gzread(gzf, bufferVerts, readLen * sizeof(float) * 3); if (!readBytes) { - std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh vertices from " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh vertices from " + << filename << endl; MEM_freeN(bufferVerts); gzclose(gzf); return false; @@ -2393,7 +2351,7 @@ bool MANTA::updateMeshFromBobj(std::string filename) CLAMP(readEnd, 0, numBuffer); k = 0; - for (std::vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) { + for (vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) { mMeshNodes->at(j).pos[0] = bufferVerts[k]; mMeshNodes->at(j).pos[1] = bufferVerts[k + 1]; mMeshNodes->at(j).pos[2] = bufferVerts[k + 2]; @@ -2406,15 +2364,14 @@ bool MANTA::updateMeshFromBobj(std::string filename) // Num normals readBytes = gzread(gzf, &numBuffer, sizeof(int)); if (!readBytes) { - std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh normals from " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh normals from " + << filename << endl; gzclose(gzf); return false; } if (with_debug) - std::cout << "read mesh , num normals : " << numBuffer << " , in file: " << filename - << std::endl; + cout << "read mesh , num normals : " << numBuffer << " , in file: " << filename << endl; if (numBuffer) { // Normals @@ -2433,8 +2390,8 @@ bool MANTA::updateMeshFromBobj(std::string filename) readBytes = gzread(gzf, bufferNormals, readLen * sizeof(float) * 3); if (!readBytes) { - std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh normals from " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh normals from " + << filename << endl; MEM_freeN(bufferNormals); gzclose(gzf); return false; @@ -2446,7 +2403,7 @@ bool MANTA::updateMeshFromBobj(std::string filename) CLAMP(readEnd, 0, numBuffer); k = 0; - for (std::vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) { + for (vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) { mMeshNodes->at(j).normal[0] = bufferNormals[k]; mMeshNodes->at(j).normal[1] = bufferNormals[k + 1]; mMeshNodes->at(j).normal[2] = bufferNormals[k + 2]; @@ -2459,16 +2416,15 @@ bool MANTA::updateMeshFromBobj(std::string filename) // Num triangles readBytes = gzread(gzf, &numBuffer, sizeof(int)); if (!readBytes) { - std::cerr - << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh triangles from " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh triangles from " + << filename << endl; gzclose(gzf); return false; } if (with_debug) - std::cout << "Fluid: Read mesh , num triangles : " << numBuffer << " , in file: " << filename - << std::endl; + cout << "Fluid: Read mesh , num triangles : " << numBuffer << " , in file: " << filename + << endl; numChunks = (int)(ceil((float)numBuffer / TRIANGLE_CHUNK)); @@ -2488,8 +2444,8 @@ bool MANTA::updateMeshFromBobj(std::string filename) readBytes = gzread(gzf, bufferTriangles, readLen * sizeof(int) * 3); if (!readBytes) { - std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh triangles from " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh triangles from " + << filename << endl; MEM_freeN(bufferTriangles); gzclose(gzf); return false; @@ -2501,7 +2457,7 @@ bool MANTA::updateMeshFromBobj(std::string filename) CLAMP(readEnd, 0, numBuffer); k = 0; - for (std::vector<MANTA::Triangle>::size_type j = readStart; j < readEnd; j++, k += 3) { + for (vector<MANTA::Triangle>::size_type j = readStart; j < readEnd; j++, k += 3) { mMeshTriangles->at(j).c[0] = bufferTriangles[k]; mMeshTriangles->at(j).c[1] = bufferTriangles[k + 1]; mMeshTriangles->at(j).c[2] = bufferTriangles[k + 2]; @@ -2513,24 +2469,23 @@ bool MANTA::updateMeshFromBobj(std::string filename) return (gzclose(gzf) == Z_OK); } -bool MANTA::updateMeshFromObj(std::string filename) +bool MANTA::updateMeshFromObj(string filename) { if (with_debug) - std::cout << "MANTA::updateMeshFromObj()" << std::endl; + cout << "MANTA::updateMeshFromObj()" << endl; - std::ifstream ifs(filename); + ifstream ifs(filename); float fbuffer[3]; int ibuffer[3]; int cntVerts = 0, cntNormals = 0, cntTris = 0; if (!ifs.good()) { - std::cerr << "Fluid Error -- updateMeshFromObj(): Unable to open file: " << filename - << std::endl; + cerr << "Fluid Error -- updateMeshFromObj(): Unable to open file: " << filename << endl; return false; } while (ifs.good() && !ifs.eof()) { - std::string id; + string id; ifs >> id; if (id[0] == '#') { @@ -2544,8 +2499,8 @@ bool MANTA::updateMeshFromObj(std::string filename) else if (id == "vn") { // normals if (getNumVertices() != cntVerts) { - std::cerr << "Fluid Error -- updateMeshFromObj(): Invalid number of mesh nodes in file: " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromObj(): Invalid number of mesh nodes in file: " + << filename << endl; return false; } @@ -2568,20 +2523,20 @@ bool MANTA::updateMeshFromObj(std::string filename) } else if (id == "g") { // group - std::string group; + string group; ifs >> group; } else if (id == "f") { // face - std::string face; + string face; for (int i = 0; i < 3; i++) { ifs >> face; - if (face.find('/') != std::string::npos) + if (face.find('/') != string::npos) face = face.substr(0, face.find('/')); // ignore other indices int idx = atoi(face.c_str()) - 1; if (idx < 0) { - std::cerr << "Fluid Error -- updateMeshFromObj(): Invalid face encountered in file: " - << filename << std::endl; + cerr << "Fluid Error -- updateMeshFromObj(): Invalid face encountered in file: " + << filename << endl; return false; } ibuffer[i] = idx; @@ -2603,10 +2558,10 @@ bool MANTA::updateMeshFromObj(std::string filename) return true; } -bool MANTA::updateMeshFromUni(std::string filename) +bool MANTA::updateMeshFromUni(string filename) { if (with_debug) - std::cout << "MANTA::updateMeshFromUni()" << std::endl; + cout << "MANTA::updateMeshFromUni()" << endl; gzFile gzf; float fbuffer[4]; @@ -2614,8 +2569,7 @@ bool MANTA::updateMeshFromUni(std::string filename) gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression if (!gzf) { - std::cerr << "Fluid Error -- updateMeshFromUni(): Unable to open file: " << filename - << std::endl; + cerr << "Fluid Error -- updateMeshFromUni(): Unable to open file: " << filename << endl; return false; } @@ -2623,13 +2577,13 @@ bool MANTA::updateMeshFromUni(std::string filename) char file_magic[5] = {0, 0, 0, 0, 0}; readBytes = gzread(gzf, file_magic, 4); if (!readBytes) { - std::cerr << "Fluid Error -- updateMeshFromUni(): Unable to read header in file: " << filename - << std::endl; + cerr << "Fluid Error -- updateMeshFromUni(): Unable to read header in file: " << filename + << endl; gzclose(gzf); return false; } - std::vector<pVel> *velocityPointer = mMeshVelocities; + vector<pVel> *velocityPointer = mMeshVelocities; // mdata uni header const int STR_LEN_PDATA = 256; @@ -2645,19 +2599,18 @@ bool MANTA::updateMeshFromUni(std::string filename) gzread(gzf, ×tamp, sizeof(unsigned long long)); if (with_debug) - std::cout << "Fluid: Read " << ibuffer[0] << " vertices in file: " << filename << std::endl; + cout << "Fluid: Read " << ibuffer[0] << " vertices in file: " << filename << endl; // Sanity checks const int meshSize = sizeof(float) * 3 + sizeof(int); if (!(bytesPerElement == meshSize) && (elementType == 0)) { - std::cerr << "Fluid Error -- updateMeshFromUni(): Invalid header in file: " << filename - << std::endl; + cerr << "Fluid Error -- updateMeshFromUni(): Invalid header in file: " << filename << endl; gzclose(gzf); return false; } if (!ibuffer[0]) { // Any vertices present? - std::cerr << "Fluid Error -- updateMeshFromUni(): No vertices present in file: " << filename - << std::endl; + cerr << "Fluid Error -- updateMeshFromUni(): No vertices present in file: " << filename + << endl; gzclose(gzf); return false; } @@ -2672,7 +2625,7 @@ bool MANTA::updateMeshFromUni(std::string filename) velocityPointer->resize(numParticles); MANTA::pVel *bufferPVel; - for (std::vector<pVel>::iterator it = velocityPointer->begin(); it != velocityPointer->end(); + for (vector<pVel>::iterator it = velocityPointer->begin(); it != velocityPointer->end(); ++it) { gzread(gzf, fbuffer, sizeof(float) * 3); bufferPVel = (MANTA::pVel *)fbuffer; @@ -2684,44 +2637,42 @@ bool MANTA::updateMeshFromUni(std::string filename) return (gzclose(gzf) == Z_OK); } -bool MANTA::updateParticlesFromFile(std::string filename, bool isSecondarySys, bool isVelData) +bool MANTA::updateParticlesFromFile(string filename, bool isSecondarySys, bool isVelData) { if (with_debug) - std::cout << "MANTA::updateParticlesFromFile()" << std::endl; + cout << "MANTA::updateParticlesFromFile()" << endl; - std::string fname(filename); - std::string::size_type idx; + string fname(filename); + string::size_type idx; idx = fname.rfind('.'); - if (idx != std::string::npos) { - std::string extension = fname.substr(idx + 1); + if (idx != string::npos) { + string extension = fname.substr(idx + 1); if (extension.compare("uni") == 0) return updateParticlesFromUni(filename, isSecondarySys, isVelData); else - std::cerr << "Fluid Error -- updateParticlesFromFile(): Invalid file extension in file: " - << filename << std::endl; + cerr << "Fluid Error -- updateParticlesFromFile(): Invalid file extension in file: " + << filename << endl; return false; } else { - std::cerr << "Fluid Error -- updateParticlesFromFile(): Unable to open file: " << filename - << std::endl; + cerr << "Fluid Error -- updateParticlesFromFile(): Unable to open file: " << filename << endl; return false; } } -bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bool isVelData) +bool MANTA::updateParticlesFromUni(string filename, bool isSecondarySys, bool isVelData) { if (with_debug) - std::cout << "MANTA::updateParticlesFromUni()" << std::endl; + cout << "MANTA::updateParticlesFromUni()" << endl; gzFile gzf; int ibuffer[4]; gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression if (!gzf) { - std::cerr << "Fluid Error -- updateParticlesFromUni(): Unable to open file: " << filename - << std::endl; + cerr << "Fluid Error -- updateParticlesFromUni(): Unable to open file: " << filename << endl; return false; } @@ -2729,24 +2680,24 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo char file_magic[5] = {0, 0, 0, 0, 0}; readBytes = gzread(gzf, file_magic, 4); if (!readBytes) { - std::cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read header in file: " - << filename << std::endl; + cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read header in file: " << filename + << endl; gzclose(gzf); return false; } if (!strcmp(file_magic, "PB01")) { - std::cerr << "Fluid Error -- updateParticlesFromUni(): Particle uni file format v01 not " - "supported anymore." - << std::endl; + cerr << "Fluid Error -- updateParticlesFromUni(): Particle uni file format v01 not " + "supported anymore." + << endl; gzclose(gzf); return false; } // Pointer to FLIP system or to secondary particle system - std::vector<pData> *dataPointer = nullptr; - std::vector<pVel> *velocityPointer = nullptr; - std::vector<float> *lifePointer = nullptr; + vector<pData> *dataPointer = nullptr; + vector<pVel> *velocityPointer = nullptr; + vector<float> *lifePointer = nullptr; if (isSecondarySys) { dataPointer = mSndParticleData; @@ -2772,19 +2723,19 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo gzread(gzf, ×tamp, sizeof(unsigned long long)); if (with_debug) - std::cout << "Fluid: Read " << ibuffer[0] << " particles in file: " << filename << std::endl; + cout << "Fluid: Read " << ibuffer[0] << " particles in file: " << filename << endl; // Sanity checks const int partSysSize = sizeof(float) * 3 + sizeof(int); if (!(bytesPerElement == partSysSize) && (elementType == 0)) { - std::cerr << "Fluid Error -- updateParticlesFromUni(): Invalid header in file: " << filename - << std::endl; + cerr << "Fluid Error -- updateParticlesFromUni(): Invalid header in file: " << filename + << endl; gzclose(gzf); return false; } if (!ibuffer[0]) { // Any particles present? if (with_debug) - std::cout << "Fluid: No particles present in file: " << filename << std::endl; + cout << "Fluid: No particles present in file: " << filename << endl; gzclose(gzf); return true; // return true since having no particles in a cache file is valid } @@ -2812,9 +2763,8 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo readBytes = gzread(gzf, bufferPData, readLen * sizeof(pData)); if (!readBytes) { - std::cerr - << "Fluid Error -- updateParticlesFromUni(): Unable to read particle data in file: " - << filename << std::endl; + cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle data in file: " + << filename << endl; MEM_freeN(bufferPData); gzclose(gzf); return false; @@ -2826,7 +2776,7 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo CLAMP(readEnd, 0, numParticles); int k = 0; - for (std::vector<MANTA::pData>::size_type j = readStart; j < readEnd; j++, k++) { + for (vector<MANTA::pData>::size_type j = readStart; j < readEnd; j++, k++) { dataPointer->at(j).pos[0] = bufferPData[k].pos[0]; dataPointer->at(j).pos[1] = bufferPData[k].pos[1]; dataPointer->at(j).pos[2] = bufferPData[k].pos[2]; @@ -2853,9 +2803,9 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo readBytes = gzread(gzf, bufferPVel, readLen * sizeof(pVel)); if (!readBytes) { - std::cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle velocities " - "in file: " - << filename << std::endl; + cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle velocities " + "in file: " + << filename << endl; MEM_freeN(bufferPVel); gzclose(gzf); return false; @@ -2867,7 +2817,7 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo CLAMP(readEnd, 0, numParticles); int k = 0; - for (std::vector<MANTA::pVel>::size_type j = readStart; j < readEnd; j++, k++) { + for (vector<MANTA::pVel>::size_type j = readStart; j < readEnd; j++, k++) { velocityPointer->at(j).pos[0] = bufferPVel[k].pos[0]; velocityPointer->at(j).pos[1] = bufferPVel[k].pos[1]; velocityPointer->at(j).pos[2] = bufferPVel[k].pos[2]; @@ -2892,9 +2842,8 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo readBytes = gzread(gzf, bufferPLife, readLen * sizeof(float)); if (!readBytes) { - std::cerr - << "Fluid Error -- updateParticlesFromUni(): Unable to read particle life in file: " - << filename << std::endl; + cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle life in file: " + << filename << endl; MEM_freeN(bufferPLife); gzclose(gzf); return false; @@ -2906,7 +2855,7 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo CLAMP(readEnd, 0, numParticles); int k = 0; - for (std::vector<float>::size_type j = readStart; j < readEnd; j++, k++) { + for (vector<float>::size_type j = readStart; j < readEnd; j++, k++) { lifePointer->at(j) = bufferPLife[k]; } todoParticles -= readLen; @@ -2916,141 +2865,158 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo return (gzclose(gzf) == Z_OK); } -bool MANTA::updateGridFromFile(std::string filename, float *grid, bool isNoise) +bool MANTA::updateGridsFromFile(string filename, vector<GridItem> grids) { if (with_debug) - std::cout << "MANTA::updateGridFromFile()" << std::endl; + cout << "MANTA::updateGridsFromFile()" << endl; - if (!grid) { - std::cerr << "Fluid Error -- updateGridFromFile(): Cannot read into uninitialized grid (grid " - "is null)." - << std::endl; + if (grids.empty()) { + cerr << "Fluid Error -- updateGridsFromFile(): Cannot read into uninitialized grid vector." + << endl; return false; } - std::string fname(filename); - std::string::size_type idx; + string fname(filename); + string::size_type idx; idx = fname.rfind('.'); - if (idx != std::string::npos) { - std::string extension = fname.substr(idx + 1); + if (idx != string::npos) { + string extension = fname.substr(idx); - if (extension.compare("uni") == 0) - return updateGridFromUni(filename, grid, isNoise); + if (extension.compare(FLUID_DOMAIN_EXTENSION_UNI) == 0) { + return updateGridsFromUni(filename, grids); + } #if OPENVDB == 1 - else if (extension.compare("vdb") == 0) - return updateGridFromVDB(filename, grid, isNoise); + else if (extension.compare(FLUID_DOMAIN_EXTENSION_OPENVDB) == 0) { + return updateGridsFromVDB(filename, grids); + } #endif - else if (extension.compare("raw") == 0) - return updateGridFromRaw(filename, grid, isNoise); - else - std::cerr << "Fluid Error -- updateGridFromFile(): Invalid file extension in file: " - << filename << std::endl; + else if (extension.compare(FLUID_DOMAIN_EXTENSION_RAW) == 0) { + return updateGridsFromRaw(filename, grids); + } + else { + cerr << "Fluid Error -- updateGridsFromFile(): Invalid file extension in file: " << filename + << endl; + } return false; } else { - std::cerr << "Fluid Error -- updateGridFromFile(): Unable to open file: " << filename - << std::endl; + cerr << "Fluid Error -- updateGridsFromFile(): Unable to open file: " << filename << endl; return false; } } -bool MANTA::updateGridFromUni(std::string filename, float *grid, bool isNoise) +bool MANTA::updateGridsFromUni(string filename, vector<GridItem> grids) { if (with_debug) - std::cout << "MANTA::updateGridFromUni()" << std::endl; + cout << "MANTA::updateGridsFromUni()" << endl; gzFile gzf; + int expectedBytes = 0, readBytes = 0; int ibuffer[4]; gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); if (!gzf) { - std::cerr << "Fluid Error -- updateGridFromUni(): Unable to open file: " << filename - << std::endl; + cerr << "Fluid Error -- updateGridsFromUni(): Unable to open file: " << filename << endl; return false; } - int readBytes = 0; char file_magic[5] = {0, 0, 0, 0, 0}; readBytes = gzread(gzf, file_magic, 4); if (!readBytes) { - std::cerr << "Fluid Error -- updateGridFromUni(): Unable to read header in file: " << filename - << std::endl; + cerr << "Fluid Error -- updateGridsFromUni(): Invalid header in file: " << filename << endl; gzclose(gzf); return false; } - - if (!strcmp(file_magic, "DDF2")) { - std::cerr - << "Fluid Error -- updateGridFromUni(): Grid uni file format DDF2 not supported anymore." - << std::endl; + if (!strcmp(file_magic, "DDF2") || !strcmp(file_magic, "MNT1") || !strcmp(file_magic, "MNT2")) { + cerr << "Fluid Error -- updateGridsFromUni(): Unsupported header in file: " << filename + << endl; gzclose(gzf); return false; } - if (!strcmp(file_magic, "MNT1")) { - std::cerr - << "Fluid Error -- updateGridFromUni(): Grid uni file format MNT1 not supported anymore." - << std::endl; - gzclose(gzf); - return false; - } - - if (!strcmp(file_magic, "MNT2")) { - std::cerr - << "Fluid Error -- updateGridFromUni(): Grid uni file format MNT2 not supported anymore." - << std::endl; - gzclose(gzf); - return false; - } + if (!strcmp(file_magic, "MNT3")) { - // 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 + // 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)); - // 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)); - - int resX = (isNoise) ? mResXNoise : mResX; - int resY = (isNoise) ? mResYNoise : mResY; - int resZ = (isNoise) ? mResZNoise : mResZ; + if (with_debug) + cout << "Fluid: Read " << ibuffer[3] << " grid type in file: " << filename << endl; + + for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) { + GridItem gridItem = *gIter; + void **pointerList = gridItem.pointer; + int type = gridItem.type; + int *res = gridItem.res; + assert(pointerList[0]); + assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]); + UNUSED_VARS(res); + + switch (type) { + case FLUID_DOMAIN_GRID_VEC3F: { + assert(pointerList[1] && pointerList[2]); + float **fpointers = (float **)pointerList; + expectedBytes = sizeof(float) * 3 * ibuffer[0] * ibuffer[1] * ibuffer[2]; + readBytes = 0; + for (int i = 0; i < ibuffer[0] * ibuffer[1] * ibuffer[2]; ++i) { + for (int j = 0; j < 3; ++j) { + readBytes += gzread(gzf, fpointers[j], sizeof(float)); + ++fpointers[j]; + } + } + break; + } + case FLUID_DOMAIN_GRID_FLOAT: { + float **fpointers = (float **)pointerList; + expectedBytes = sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2]; + readBytes = gzread( + gzf, fpointers[0], sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2]); + break; + } + default: { + cerr << "Fluid Error -- Unknown grid type" << endl; + } + } - if (with_debug) - std::cout << "Fluid: Read " << ibuffer[3] << " grid type in file: " << filename << std::endl; + if (!readBytes) { + cerr << "Fluid Error -- updateGridFromRaw(): Unable to read raw file: " << filename + << endl; + gzclose(gzf); + return false; + } + assert(expectedBytes == readBytes); + (void)expectedBytes; - // Sanity checks - if (ibuffer[0] != resX || ibuffer[1] != resY || ibuffer[2] != resZ) { - std::cout << "Fluid: Grid dim doesn't match, read: (" << ibuffer[0] << ", " << ibuffer[1] - << ", " << ibuffer[2] << ") vs setup: (" << resX << ", " << resY << ", " << resZ - << ")" << std::endl; + if (with_debug) + cout << "Fluid: Read successfully: " << filename << endl; + } + } + else { + cerr << "Fluid Error -- updateGridsFromUni(): Unknown header in file: " << filename << endl; gzclose(gzf); return false; } - // Actual data reading - if (!strcmp(file_magic, "MNT3")) { - gzread(gzf, grid, sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2]); - } - - if (with_debug) - std::cout << "Fluid: Read successfully: " << filename << std::endl; - return (gzclose(gzf) == Z_OK); } #if OPENVDB == 1 -bool MANTA::updateGridFromVDB(std::string filename, float *grid, bool isNoise) +bool MANTA::updateGridsFromVDB(string filename, vector<GridItem> grids) { if (with_debug) - std::cout << "MANTA::updateGridFromVDB()" << std::endl; + cout << "MANTA::updateGridsFromVDB()" << endl; openvdb::initialize(); openvdb::io::File file(filename); @@ -3058,67 +3024,191 @@ bool MANTA::updateGridFromVDB(std::string filename, float *grid, bool isNoise) file.open(); } catch (const openvdb::IoError &) { - std::cerr << "Fluid Error -- updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename - << std::endl; + cerr << "Fluid Error -- updateGridsFromVDB(): IOError, invalid OpenVDB file: " << filename + << endl; + return false; + } + if (grids.empty()) { + cerr << "Fluid Error -- updateGridsFromVDB(): No grids found in grid vector" << endl; return false; } + unordered_map<string, openvdb::FloatGrid::Accessor> floatAccessors; + unordered_map<string, openvdb::Vec3SGrid::Accessor> vec3fAccessors; openvdb::GridBase::Ptr baseGrid; - for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName(); - ++nameIter) { - baseGrid = file.readGrid(nameIter.gridName()); - break; + + /* Get accessors to all grids in this OpenVDB file.*/ + for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) { + GridItem gridItem = *gIter; + string itemName = gridItem.name; + int itemType = gridItem.type; + + for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName(); + ++nameIter) { + string vdbName = nameIter.gridName(); + bool nameMatch = !itemName.compare(vdbName); + + /* Support for <= 2.83: If file has only one grid in it, use that grid. */ + openvdb::io::File::NameIterator peekNext = nameIter; + bool onlyGrid = (++peekNext == file.endName()); + if (onlyGrid) { + vdbName = itemName; + } + + if (nameMatch || onlyGrid) { + baseGrid = file.readGrid(nameIter.gridName()); + + switch (itemType) { + case FLUID_DOMAIN_GRID_VEC3F: { + openvdb::Vec3SGrid::Ptr gridVDB = openvdb::gridPtrCast<openvdb::Vec3SGrid>(baseGrid); + openvdb::Vec3SGrid::Accessor vdbAccessor = gridVDB->getAccessor(); + vec3fAccessors.emplace(vdbName, vdbAccessor); + break; + } + case FLUID_DOMAIN_GRID_FLOAT: { + openvdb::FloatGrid::Ptr gridVDB = openvdb::gridPtrCast<openvdb::FloatGrid>(baseGrid); + openvdb::FloatGrid::Accessor vdbAccessor = gridVDB->getAccessor(); + floatAccessors.emplace(vdbName, vdbAccessor); + break; + } + default: { + cerr << "Fluid Error -- Unknown grid type" << endl; + } + } + } + else { + cerr << "Fluid Error -- Could not read grid from file" << endl; + return false; + } + } } file.close(); - openvdb::FloatGrid::Ptr gridVDB = openvdb::gridPtrCast<openvdb::FloatGrid>(baseGrid); - openvdb::FloatGrid::Accessor accessor = gridVDB->getAccessor(); - - int resX = (isNoise) ? mResXNoise : mResX; - int resY = (isNoise) ? mResYNoise : mResY; - int resZ = (isNoise) ? mResZNoise : mResZ; size_t index = 0; - for (int z = 0; z < resZ; ++z) { - for (int y = 0; y < resY; ++y) { - for (int x = 0; x < resX; ++x, ++index) { + + /* Use res of first grid for grid loop. All grids must be same size anyways. */ + vector<GridItem>::iterator gIter = grids.begin(); + int *res = (*gIter).res; + + for (int z = 0; z < res[2]; ++z) { + for (int y = 0; y < res[1]; ++y) { + for (int x = 0; x < res[0]; ++x, ++index) { openvdb::Coord xyz(x, y, z); - float v = accessor.getValue(xyz); - grid[index] = v; + + for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) { + GridItem gridItem = *gIter; + void **pointerList = gridItem.pointer; + int type = gridItem.type; + int *res = gridItem.res; + assert(pointerList[0]); + assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]); + UNUSED_VARS(res); + + switch (type) { + case FLUID_DOMAIN_GRID_VEC3F: { + unordered_map<string, openvdb::Vec3SGrid::Accessor>::iterator it; + it = vec3fAccessors.find(gridItem.name); + if (it == vec3fAccessors.end()) { + cerr << "Fluid Error -- '" << gridItem.name << "' not in vdb grid map" << endl; + return false; + } + openvdb::Vec3f v = it->second.getValue(xyz); + + assert(pointerList[1] && pointerList[2]); + float **fpointers = (float **)pointerList; + for (int j = 0; j < 3; ++j) { + (fpointers[j])[index] = (float)v[j]; + } + break; + } + case FLUID_DOMAIN_GRID_FLOAT: { + unordered_map<string, openvdb::FloatGrid::Accessor>::iterator it; + it = floatAccessors.find(gridItem.name); + if (it == floatAccessors.end()) { + cerr << "Fluid Error -- '" << gridItem.name << "' not in vdb grid map" << endl; + return false; + } + float v = it->second.getValue(xyz); + float **fpointers = (float **)pointerList; + (fpointers[0])[index] = v; + break; + } + default: { + cerr << "Fluid Error -- Unknown grid type" << endl; + } + } + } } } } + if (with_debug) + cout << "Fluid: Read successfully: " << filename << endl; + return true; } #endif -bool MANTA::updateGridFromRaw(std::string filename, float *grid, bool isNoise) +bool MANTA::updateGridsFromRaw(string filename, vector<GridItem> grids) { if (with_debug) - std::cout << "MANTA::updateGridFromRaw()" << std::endl; + cout << "MANTA::updateGridsFromRaw()" << endl; gzFile gzf; int expectedBytes, readBytes; gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb"); if (!gzf) { - std::cout << "MANTA::updateGridFromRaw(): unable to open file" << std::endl; + cout << "MANTA::updateGridsFromRaw(): unable to open file" << endl; return false; } - int resX = (isNoise) ? mResXNoise : mResX; - int resY = (isNoise) ? mResYNoise : mResY; - int resZ = (isNoise) ? mResZNoise : mResZ; + for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) { + GridItem gridItem = *gIter; + void **pointerList = gridItem.pointer; + int type = gridItem.type; + int *res = gridItem.res; + assert(pointerList[0]); + assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]); + UNUSED_VARS(res); + + switch (type) { + case FLUID_DOMAIN_GRID_VEC3F: { + assert(pointerList[1] && pointerList[2]); + float **fpointers = (float **)pointerList; + expectedBytes = sizeof(float) * 3 * res[0] * res[1] * res[2]; + readBytes = 0; + for (int i = 0; i < res[0] * res[1] * res[2]; ++i) { + for (int j = 0; j < 3; ++j) { + readBytes += gzread(gzf, fpointers[j], sizeof(float)); + ++fpointers[j]; + } + } + break; + } + case FLUID_DOMAIN_GRID_FLOAT: { + float **fpointers = (float **)pointerList; + expectedBytes = sizeof(float) * res[0] * res[1] * res[2]; + readBytes = gzread(gzf, fpointers[0], expectedBytes); + break; + } + default: { + cerr << "Fluid Error -- Unknown grid type" << endl; + } + } + + if (!readBytes) { + cerr << "Fluid Error -- updateGridsFromRaw(): Unable to read raw file: " << filename << endl; + gzclose(gzf); + return false; + } + assert(expectedBytes == readBytes); - expectedBytes = sizeof(float) * resX * resY * resZ; - readBytes = gzread(gzf, grid, expectedBytes); - if (!readBytes) { - std::cerr << "Fluid Error -- updateGridFromRaw(): Unable to read raw file: " << filename - << std::endl; - gzclose(gzf); - return false; + if (with_debug) + cout << "Fluid: Read successfully: " << filename << endl; } - assert(expectedBytes == readBytes); + if (with_debug) + cout << "Fluid: Read successfully: " << filename << endl; return (gzclose(gzf) == Z_OK); } @@ -3126,25 +3216,25 @@ bool MANTA::updateGridFromRaw(std::string filename, float *grid, bool isNoise) void MANTA::updatePointers() { if (with_debug) - std::cout << "MANTA::updatePointers()" << std::endl; - - std::string func = "getDataPointer"; - std::string funcNodes = "getNodesDataPointer"; - std::string funcTris = "getTrisDataPointer"; - - std::string id = std::to_string(mCurrentID); - std::string solver = "s" + id; - std::string parts = "pp" + id; - std::string snd = "sp" + id; - std::string mesh = "sm" + id; - std::string mesh2 = "mesh" + id; - std::string noise = "sn" + id; - std::string solver_ext = "_" + solver; - std::string parts_ext = "_" + parts; - std::string snd_ext = "_" + snd; - std::string mesh_ext = "_" + mesh; - std::string mesh_ext2 = "_" + mesh2; - std::string noise_ext = "_" + noise; + cout << "MANTA::updatePointers()" << endl; + + string func = "getDataPointer"; + string funcNodes = "getNodesDataPointer"; + string funcTris = "getTrisDataPointer"; + + string id = to_string(mCurrentID); + string solver = "s" + id; + string parts = "pp" + id; + string snd = "sp" + id; + string mesh = "sm" + id; + string mesh2 = "mesh" + id; + string noise = "sn" + id; + string solver_ext = "_" + solver; + string parts_ext = "_" + parts; + string snd_ext = "_" + snd; + string mesh_ext = "_" + mesh; + string mesh_ext2 = "_" + mesh2; + string noise_ext = "_" + noise; mFlags = (int *)pyObjectToPointer(callPythonFunction("flags" + solver_ext, func)); mPhiIn = (float *)pyObjectToPointer(callPythonFunction("phiIn" + solver_ext, func)); @@ -3231,27 +3321,27 @@ void MANTA::updatePointers() } if (mUsingLiquid) { mPhi = (float *)pyObjectToPointer(callPythonFunction("phi" + solver_ext, func)); - mFlipParticleData = (std::vector<pData> *)pyObjectToPointer( + mFlipParticleData = (vector<pData> *)pyObjectToPointer( callPythonFunction("pp" + solver_ext, func)); - mFlipParticleVelocity = (std::vector<pVel> *)pyObjectToPointer( + mFlipParticleVelocity = (vector<pVel> *)pyObjectToPointer( callPythonFunction("pVel" + parts_ext, func)); } if (mUsingLiquid && mUsingMesh) { - mMeshNodes = (std::vector<Node> *)pyObjectToPointer( + mMeshNodes = (vector<Node> *)pyObjectToPointer( callPythonFunction("mesh" + mesh_ext, funcNodes)); - mMeshTriangles = (std::vector<Triangle> *)pyObjectToPointer( + mMeshTriangles = (vector<Triangle> *)pyObjectToPointer( callPythonFunction("mesh" + mesh_ext, funcTris)); } if (mUsingLiquid && mUsingMVel) { - mMeshVelocities = (std::vector<pVel> *)pyObjectToPointer( + mMeshVelocities = (vector<pVel> *)pyObjectToPointer( callPythonFunction("mVel" + mesh_ext2, func)); } if (mUsingLiquid && (mUsingDrops | mUsingBubbles | mUsingFloats | mUsingTracers)) { - mSndParticleData = (std::vector<pData> *)pyObjectToPointer( + mSndParticleData = (vector<pData> *)pyObjectToPointer( callPythonFunction("ppSnd" + snd_ext, func)); - mSndParticleVelocity = (std::vector<pVel> *)pyObjectToPointer( + mSndParticleVelocity = (vector<pVel> *)pyObjectToPointer( callPythonFunction("pVelSnd" + parts_ext, func)); - mSndParticleLife = (std::vector<float> *)pyObjectToPointer( + mSndParticleLife = (vector<float> *)pyObjectToPointer( callPythonFunction("pLifeSnd" + parts_ext, func)); } @@ -3264,50 +3354,49 @@ void MANTA::updatePointers() bool MANTA::hasConfig(FluidModifierData *mmd, int framenr) { - std::string extension = FLUID_DOMAIN_EXTENSION_UNI; + string extension = FLUID_DOMAIN_EXTENSION_UNI; return BLI_exists( - getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, extension, framenr).c_str()); + getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_FILENAME_CONFIG, extension, framenr).c_str()); } bool MANTA::hasData(FluidModifierData *mmd, int framenr) { - std::string filename = (mUsingSmoke) ? FLUID_DOMAIN_FILE_DENSITY : FLUID_DOMAIN_FILE_PP; - std::string extension = getCacheFileEnding(mmd->domain->cache_data_format); + string filename = (mUsingSmoke) ? FLUID_FILENAME_DENSITY : FLUID_FILENAME_PP; + string extension = getCacheFileEnding(mmd->domain->cache_data_format); return BLI_exists(getFile(mmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str()); } bool MANTA::hasNoise(FluidModifierData *mmd, int framenr) { - std::string extension = getCacheFileEnding(mmd->domain->cache_noise_format); + string extension = getCacheFileEnding(mmd->domain->cache_noise_format); return BLI_exists( - getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_DENSITYNOISE, extension, framenr) + getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_DENSITYNOISE, extension, framenr) .c_str()); } bool MANTA::hasMesh(FluidModifierData *mmd, int framenr) { - std::string extension = getCacheFileEnding(mmd->domain->cache_mesh_format); + string extension = getCacheFileEnding(mmd->domain->cache_mesh_format); return BLI_exists( - getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, extension, framenr).c_str()); + getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_FILENAME_MESH, extension, framenr).c_str()); } bool MANTA::hasParticles(FluidModifierData *mmd, int framenr) { - std::string extension = getCacheFileEnding(mmd->domain->cache_particle_format); + string extension = getCacheFileEnding(mmd->domain->cache_particle_format); return BLI_exists( - getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PPSND, extension, framenr) - .c_str()); + getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_FILENAME_PPSND, extension, framenr).c_str()); } bool MANTA::hasGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain) { - std::string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE; - std::string filename = (sourceDomain) ? FLUID_DOMAIN_FILE_VEL : FLUID_DOMAIN_FILE_GUIDEVEL; - std::string extension = getCacheFileEnding(mmd->domain->cache_data_format); + string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE; + string filename = (sourceDomain) ? FLUID_FILENAME_VELOCITY : FLUID_FILENAME_GUIDEVEL; + string extension = getCacheFileEnding(mmd->domain->cache_data_format); return BLI_exists(getFile(mmd, subdirectory, filename, extension, framenr).c_str()); } -std::string MANTA::getDirectory(FluidModifierData *mmd, std::string subdirectory) +string MANTA::getDirectory(FluidModifierData *mmd, string subdirectory) { char directory[FILE_MAX]; BLI_path_join( @@ -3316,15 +3405,12 @@ std::string MANTA::getDirectory(FluidModifierData *mmd, std::string subdirectory return directory; } -std::string MANTA::getFile(FluidModifierData *mmd, - std::string subdirectory, - std::string fname, - std::string extension, - int framenr) +string MANTA::getFile( + FluidModifierData *mmd, string subdirectory, string fname, string extension, int framenr) { char targetFile[FILE_MAX]; - std::string path = getDirectory(mmd, subdirectory); - std::string filename = fname + extension; + string path = getDirectory(mmd, subdirectory); + string filename = fname + extension; BLI_join_dirfile(targetFile, sizeof(targetFile), path.c_str(), filename.c_str()); BLI_path_frame(targetFile, framenr, 0); return targetFile; diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h index 5c40fdf7dd8..6a8484c75d9 100644 --- a/intern/mantaflow/intern/MANTA_main.h +++ b/intern/mantaflow/intern/MANTA_main.h @@ -27,8 +27,14 @@ #include <atomic> #include <cassert> #include <string> +#include <unordered_map> #include <vector> +using std::atomic; +using std::string; +using std::unordered_map; +using std::vector; + struct MANTA { public: MANTA(int *res, struct FluidModifierData *mmd); @@ -54,25 +60,38 @@ struct MANTA { int flags; } Triangle; + // Cache helper typedefs + typedef struct GridItem { + void **pointer; /* Array of pointers for this grid.*/ + int type; + int *res; + string name; + } GridItem; + + typedef struct FileItem { + string filename; + vector<GridItem> grids; + } FileItem; + // Manta step, handling everything void step(struct FluidModifierData *mmd, int startFrame); // Grid initialization functions - void initHeat(struct FluidModifierData *mmd); - void initFire(struct FluidModifierData *mmd); - void initColors(struct FluidModifierData *mmd); - void initFireHigh(struct FluidModifierData *mmd); - void initColorsHigh(struct FluidModifierData *mmd); - void initLiquid(FluidModifierData *mmd); - void initLiquidMesh(FluidModifierData *mmd); - void initObstacle(FluidModifierData *mmd); - void initCurvature(FluidModifierData *mmd); - void initGuiding(FluidModifierData *mmd); - void initFractions(FluidModifierData *mmd); - void initInVelocity(FluidModifierData *mmd); - void initOutflow(FluidModifierData *mmd); - void initSndParts(FluidModifierData *mmd); - void initLiquidSndParts(FluidModifierData *mmd); + void initHeat(struct FluidModifierData *mmd = NULL); + void initFire(struct FluidModifierData *mmd = NULL); + void initColors(struct FluidModifierData *mmd = NULL); + void initFireHigh(struct FluidModifierData *mmd = NULL); + void initColorsHigh(struct FluidModifierData *mmd = NULL); + void initLiquid(FluidModifierData *mmd = NULL); + void initLiquidMesh(FluidModifierData *mmd = NULL); + void initObstacle(FluidModifierData *mmd = NULL); + void initCurvature(FluidModifierData *mmd = NULL); + void initGuiding(FluidModifierData *mmd = NULL); + void initFractions(FluidModifierData *mmd = NULL); + void initInVelocity(FluidModifierData *mmd = NULL); + void initOutflow(FluidModifierData *mmd = NULL); + void initSndParts(FluidModifierData *mmd = NULL); + void initLiquidSndParts(FluidModifierData *mmd = NULL); // Pointer transfer: Mantaflow -> Blender void updatePointers(); @@ -415,7 +434,7 @@ struct MANTA { return mPhi; } - static std::atomic<int> solverID; + static atomic<int> solverID; static int with_debug; // on or off (1 or 0), also sets manta debug level // Mesh getters @@ -742,6 +761,8 @@ struct MANTA { size_t mTotalCellsMesh; size_t mTotalCellsParticles; + unordered_map<string, string> mRNAMap; + int mCurrentID; bool mUsingHeat; @@ -854,45 +875,46 @@ struct MANTA { float *mPhi; // Mesh fields - std::vector<Node> *mMeshNodes; - std::vector<Triangle> *mMeshTriangles; - std::vector<pVel> *mMeshVelocities; + vector<Node> *mMeshNodes; + vector<Triangle> *mMeshTriangles; + vector<pVel> *mMeshVelocities; // Particle fields - std::vector<pData> *mFlipParticleData; - std::vector<pVel> *mFlipParticleVelocity; - - std::vector<pData> *mSndParticleData; - std::vector<pVel> *mSndParticleVelocity; - std::vector<float> *mSndParticleLife; - - void initDomain(struct FluidModifierData *mmd); - void initNoise(struct FluidModifierData *mmd); - void initMesh(struct FluidModifierData *mmd); - void initSmoke(struct FluidModifierData *mmd); - void initSmokeNoise(struct FluidModifierData *mmd); + vector<pData> *mFlipParticleData; + vector<pVel> *mFlipParticleVelocity; + + vector<pData> *mSndParticleData; + vector<pVel> *mSndParticleVelocity; + vector<float> *mSndParticleLife; + + void initializeRNAMap(struct FluidModifierData *mmd = NULL); + void initDomain(struct FluidModifierData *mmd = NULL); + void initNoise(struct FluidModifierData *mmd = NULL); + void initMesh(struct FluidModifierData *mmd = NULL); + void initSmoke(struct FluidModifierData *mmd = NULL); + void initSmokeNoise(struct FluidModifierData *mmd = NULL); void initializeMantaflow(); void terminateMantaflow(); - bool runPythonString(std::vector<std::string> commands); - std::string getRealValue(const std::string &varName, FluidModifierData *mmd); - std::string parseLine(const std::string &line, FluidModifierData *mmd); - std::string parseScript(const std::string &setup_string, FluidModifierData *mmd = NULL); - bool updateMeshFromBobj(std::string filename); - bool updateMeshFromObj(std::string filename); - bool updateMeshFromUni(std::string filename); - bool updateParticlesFromUni(std::string filename, bool isSecondarySys, bool isVelData); - bool updateGridFromUni(std::string filename, float *grid, bool isNoise); - bool updateGridFromVDB(std::string filename, float *grid, bool isNoise); - bool updateGridFromRaw(std::string filename, float *grid, bool isNoise); - bool updateMeshFromFile(std::string filename); - bool updateParticlesFromFile(std::string filename, bool isSecondarySys, bool isVelData); - bool updateGridFromFile(std::string filename, float *grid, bool isNoise); - std::string getDirectory(struct FluidModifierData *mmd, std::string subdirectory); - std::string getFile(struct FluidModifierData *mmd, - std::string subdirectory, - std::string fname, - std::string extension, - int framenr); + bool runPythonString(vector<string> commands); + string getRealValue(const string &varName); + string parseLine(const string &line); + string parseScript(const string &setup_string, FluidModifierData *mmd = NULL); + bool updateMeshFromBobj(string filename); + bool updateMeshFromObj(string filename); + bool updateMeshFromUni(string filename); + bool updateParticlesFromUni(string filename, bool isSecondarySys, bool isVelData); + bool updateGridsFromUni(string filename, vector<GridItem> grids); + bool updateGridsFromVDB(string filename, vector<GridItem> grids); + bool updateGridsFromRaw(string filename, vector<GridItem> grids); + bool updateMeshFromFile(string filename); + bool updateParticlesFromFile(string filename, bool isSecondarySys, bool isVelData); + bool updateGridsFromFile(string filename, vector<GridItem> grids); + string getDirectory(struct FluidModifierData *mmd, string subdirectory); + string getFile(struct FluidModifierData *mmd, + string subdirectory, + string fname, + string extension, + int framenr); }; #endif diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h index dd2111db7d7..cf99717c102 100644 --- a/intern/mantaflow/intern/strings/fluid_script.h +++ b/intern/mantaflow/intern/strings/fluid_script.h @@ -92,7 +92,7 @@ const std::string fluid_variables = mantaMsg('Fluid variables')\n\ dim_s$ID$ = $SOLVER_DIM$\n\ res_s$ID$ = $RES$\n\ -gravity_s$ID$ = vec3($GRAVITY_X$, $GRAVITY_Y$, $GRAVITY_Z$)\n\ +gravity_s$ID$ = vec3($GRAVITY_X$, $GRAVITY_Y$, $GRAVITY_Z$) # in SI unit (e.g. m/s^2)\n\ gs_s$ID$ = vec3($RESX$, $RESY$, $RESZ$)\n\ maxVel_s$ID$ = 0\n\ \n\ @@ -115,9 +115,16 @@ using_speedvectors_s$ID$ = $USING_SPEEDVECTORS$\n\ using_diffusion_s$ID$ = $USING_DIFFUSION$\n\ \n\ # Fluid time params\n\ +timeScale_s$ID$ = $TIME_SCALE$\n\ timeTotal_s$ID$ = $TIME_TOTAL$\n\ timePerFrame_s$ID$ = $TIME_PER_FRAME$\n\ -frameLength_s$ID$ = $FRAME_LENGTH$\n\ +\n\ +# In Blender fluid.c: frame_length = DT_DEFAULT * (25.0 / fps) * time_scale\n\ +# with DT_DEFAULT = 0.1\n\ +frameLength_s$ID$ = $FRAME_LENGTH$\n\ +frameLengthUnscaled_s$ID$ = frameLength_s$ID$ / timeScale_s$ID$\n\ +frameLengthRaw_s$ID$ = 0.1 * 25 # dt = 0.1 at 25 fps\n\ +\n\ dt0_s$ID$ = $DT$\n\ cflCond_s$ID$ = $CFL$\n\ timestepsMin_s$ID$ = $TIMESTEPS_MIN$\n\ @@ -132,8 +139,29 @@ end_frame_s$ID$ = $END_FRAME$\n\ domainSize_s$ID$ = $FLUID_DOMAIN_SIZE$ # longest domain side in meters\n\ viscosity_s$ID$ = $FLUID_VISCOSITY$ / (domainSize_s$ID$*domainSize_s$ID$) # kinematic viscosity in m^2/s\n\ \n\ -# Factor to convert blender velocities to manta velocities\n\ -toMantaUnitsFac_s$ID$ = (1.0 / (1.0 / res_s$ID$))\n # = dt/dx * 1/dt "; +# Factors to convert Blender units to Manta units\n\ +ratioMetersToRes_s$ID$ = float(domainSize_s$ID$) / float(res_s$ID$) # [meters / cells]\n\ +mantaMsg('1 Mantaflow cell is ' + str(ratioMetersToRes_s$ID$) + ' Blender length units long.')\n\ +\n\ +ratioResToBLength_s$ID$ = float(res_s$ID$) / float(domainSize_s$ID$) # [cells / blength] (blength: cm, m, or km, ... )\n\ +mantaMsg('1 Blender length unit is ' + str(ratioResToBLength_s$ID$) + ' Mantaflow cells long.')\n\ +\n\ +ratioBTimeToTimstep_s$ID$ = float(1) / float(frameLengthRaw_s$ID$) # the time within 1 blender time unit, see also fluid.c\n\ +mantaMsg('1 Blender time unit is ' + str(ratioBTimeToTimstep_s$ID$) + ' Mantaflow time units long.')\n\ +\n\ +ratioFrameToFramelength_s$ID$ = float(1) / float(frameLengthUnscaled_s$ID$ ) # the time within 1 frame\n\ +mantaMsg('frame / frameLength is ' + str(ratioFrameToFramelength_s$ID$) + ' Mantaflow time units long.')\n\ +\n\ +scaleAcceleration_s$ID$ = ratioResToBLength_s$ID$ * (ratioBTimeToTimstep_s$ID$**2)# [meters/btime^2] to [cells/timestep^2] (btime: sec, min, or h, ...)\n\ +mantaMsg('scaleAcceleration is ' + str(scaleAcceleration_s$ID$))\n\ +\n\ +scaleSpeedFrames_s$ID$ = ratioResToBLength_s$ID$ * ratioFrameToFramelength_s$ID$ # [blength/frame] to [cells/frameLength]\n\ +mantaMsg('scaleSpeed is ' + str(scaleSpeedFrames_s$ID$))\n\ +\n\ +scaleSpeedTime_s$ID$ = ratioResToBLength_s$ID$ * ratioBTimeToTimstep_s$ID$ # [blength/btime] to [cells/frameLength]\n\ +mantaMsg('scaleSpeedTime is ' + str(scaleSpeedTime_s$ID$))\n\ +\n\ +gravity_s$ID$ *= scaleAcceleration_s$ID$ # scale from world acceleration to cell based acceleration\n"; const std::string fluid_variables_noise = "\n\ @@ -231,7 +259,7 @@ const std::string fluid_alloc = "\n\ mantaMsg('Fluid alloc data')\n\ flags_s$ID$ = s$ID$.create(FlagGrid)\n\ -vel_s$ID$ = s$ID$.create(MACGrid)\n\ +vel_s$ID$ = s$ID$.create(MACGrid, name='$NAME_VELOCITY$')\n\ velTmp_s$ID$ = s$ID$.create(MACGrid)\n\ x_vel_s$ID$ = s$ID$.create(RealGrid)\n\ y_vel_s$ID$ = s$ID$.create(RealGrid)\n\ @@ -342,17 +370,16 @@ def fluid_pre_step_$ID$():\n\ y_obvel_s$ID$.safeDivide(numObs_s$ID$)\n\ z_obvel_s$ID$.safeDivide(numObs_s$ID$)\n\ \n\ - x_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ - y_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ - z_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ - \n\ + x_obvel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ + y_obvel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ + z_obvel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ copyRealToVec3(sourceX=x_obvel_s$ID$, sourceY=y_obvel_s$ID$, sourceZ=z_obvel_s$ID$, target=obvelC_s$ID$)\n\ \n\ # translate invels (world space) to grid space\n\ if using_invel_s$ID$:\n\ - x_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ - y_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ - z_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ + x_invel_s$ID$.multConst(scaleSpeedTime_s$ID$)\n\ + y_invel_s$ID$.multConst(scaleSpeedTime_s$ID$)\n\ + z_invel_s$ID$.multConst(scaleSpeedTime_s$ID$)\n\ copyRealToVec3(sourceX=x_invel_s$ID$, sourceY=y_invel_s$ID$, sourceZ=z_invel_s$ID$, target=invelC_s$ID$)\n\ \n\ if using_guiding_s$ID$:\n\ @@ -362,9 +389,9 @@ def fluid_pre_step_$ID$():\n\ velT_s$ID$.multConst(vec3(gamma_sg$ID$))\n\ \n\ # translate external forces (world space) to grid space\n\ - x_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ - y_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ - z_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\ + x_force_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ + y_force_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ + z_force_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ copyRealToVec3(sourceX=x_force_s$ID$, sourceY=y_force_s$ID$, sourceZ=z_force_s$ID$, target=forces_s$ID$)\n\ \n\ # If obstacle has velocity, i.e. is a moving obstacle, switch to dynamic preconditioner\n\ @@ -531,7 +558,7 @@ def bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_ \n\ sn$ID$.frame = framenr\n\ sn$ID$.frameLength = frameLength_s$ID$\n\ - sn$ID$.timeTotal = abs(framenr - start_frame_s$ID$) * frameLength_s$ID$\n\ + sn$ID$.timeTotal = timeTotal_s$ID$\n\ sn$ID$.timestep = frameLength_s$ID$ # no adaptive timestep for noise\n\ \n\ smoke_step_noise_$ID$(framenr)\n\ @@ -549,7 +576,7 @@ def bake_mesh_process_$ID$(framenr, format_data, format_mesh, format_particles, \n\ sm$ID$.frame = framenr\n\ sm$ID$.frameLength = frameLength_s$ID$\n\ - sm$ID$.timeTotal = abs(framenr - start_frame_s$ID$) * frameLength_s$ID$\n\ + sm$ID$.timeTotal = timeTotal_s$ID$\n\ sm$ID$.timestep = frameLength_s$ID$ # no adaptive timestep for mesh\n\ \n\ #if using_smoke_s$ID$:\n\ @@ -573,7 +600,7 @@ def bake_particles_process_$ID$(framenr, format_data, format_particles, path_dat \n\ sp$ID$.frame = framenr\n\ sp$ID$.frameLength = frameLength_s$ID$\n\ - sp$ID$.timeTotal = abs(framenr - start_frame_s$ID$) * frameLength_s$ID$\n\ + sp$ID$.timeTotal = timeTotal_s$ID$\n\ sp$ID$.timestep = frameLength_s$ID$ # no adaptive timestep for particles\n\ \n\ #if using_smoke_s$ID$:\n\ @@ -598,10 +625,9 @@ def bake_guiding_process_$ID$(framenr, format_guiding, path_guiding, resumable): y_guidevel_s$ID$.safeDivide(numGuides_s$ID$)\n\ z_guidevel_s$ID$.safeDivide(numGuides_s$ID$)\n\ \n\ - x_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\ - y_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\ - z_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\ - \n\ + x_guidevel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ + y_guidevel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ + z_guidevel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\ copyRealToVec3(sourceX=x_guidevel_s$ID$, sourceY=y_guidevel_s$ID$, sourceZ=z_guidevel_s$ID$, target=guidevelC_s$ID$)\n\ \n\ mantaMsg('Extrapolating guiding velocity')\n\ diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h index 9d1f1024ddb..b70c26b6043 100644 --- a/intern/mantaflow/intern/strings/liquid_script.h +++ b/intern/mantaflow/intern/strings/liquid_script.h @@ -68,7 +68,7 @@ c_s_sp$ID$ = 0.4 # classification constant for snd parts\n\ c_b_sp$ID$ = 0.77 # classification constant for snd parts\n\ pot_radius_sp$ID$ = $SNDPARTICLE_POTENTIAL_RADIUS$\n\ update_radius_sp$ID$ = $SNDPARTICLE_UPDATE_RADIUS$\n\ -scaleFromManta_sp$ID$ = $FLUID_DOMAIN_SIZE$ / float(res_s$ID$) # resize factor for snd parts\n"; +using_snd_pushout_sp$ID$ = $SNDPARTICLE_BOUNDARY_PUSHOUT$\n"; ////////////////////////////////////////////////////////////////////// // GRIDS & MESH & PARTICLESYSTEM @@ -268,7 +268,7 @@ def liquid_step_$ID$():\n\ velOld_s$ID$.copyFrom(vel_s$ID$)\n\ \n\ # forces & pressure solve\n\ - addGravity(flags=flags_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$)\n\ + addGravity(flags=flags_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, scale=False)\n\ \n\ mantaMsg('Adding external forces')\n\ addForceField(flags=flags_s$ID$, vel=vel_s$ID$, force=forces_s$ID$)\n\ @@ -377,10 +377,10 @@ def liquid_step_particles_$ID$():\n\ flags_sp$ID$.updateFromLevelset(levelset=phi_sp$ID$)\n\ \n\ # Actual secondary particle simulation\n\ - flipComputeSecondaryParticlePotentials(potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, normal=normal_sp$ID$, phi=phi_sp$ID$, radius=pot_radius_sp$ID$, tauMinTA=tauMin_ta_sp$ID$, tauMaxTA=tauMax_ta_sp$ID$, tauMinWC=tauMin_wc_sp$ID$, tauMaxWC=tauMax_wc_sp$ID$, tauMinKE=tauMin_k_sp$ID$, tauMaxKE=tauMax_k_sp$ID$, scaleFromManta=scaleFromManta_sp$ID$)\n\ - flipSampleSecondaryParticles(mode='single', flags=flags_sp$ID$, v=vel_sp$ID$, pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, lMin=lMin_sp$ID$, lMax=lMax_sp$ID$, potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, k_ta=k_ta_sp$ID$, k_wc=k_wc_sp$ID$, dt=sp$ID$.timestep)\n\ - flipUpdateSecondaryParticles(mode='linear', pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, f_sec=pForceSnd_pp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, neighborRatio=neighborRatio_sp$ID$, radius=update_radius_sp$ID$, gravity=gravity_s$ID$, k_b=k_b_sp$ID$, k_d=k_d_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, dt=sp$ID$.timestep)\n\ - if $SNDPARTICLE_BOUNDARY_PUSHOUT$:\n\ + flipComputeSecondaryParticlePotentials(potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, normal=normal_sp$ID$, phi=phi_sp$ID$, radius=pot_radius_sp$ID$, tauMinTA=tauMin_ta_sp$ID$, tauMaxTA=tauMax_ta_sp$ID$, tauMinWC=tauMin_wc_sp$ID$, tauMaxWC=tauMax_wc_sp$ID$, tauMinKE=tauMin_k_sp$ID$, tauMaxKE=tauMax_k_sp$ID$, scaleFromManta=ratioMetersToRes_s$ID$)\n\ + flipSampleSecondaryParticles(mode='single', flags=flags_sp$ID$, v=vel_sp$ID$, pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, lMin=lMin_sp$ID$, lMax=lMax_sp$ID$, potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, k_ta=k_ta_sp$ID$, k_wc=k_wc_sp$ID$)\n\ + flipUpdateSecondaryParticles(mode='linear', pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, f_sec=pForceSnd_pp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, neighborRatio=neighborRatio_sp$ID$, radius=update_radius_sp$ID$, gravity=gravity_s$ID$, scale=False, k_b=k_b_sp$ID$, k_d=k_d_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$)\n\ + if using_snd_pushout_sp$ID$:\n\ pushOutofObs(parts=ppSnd_sp$ID$, flags=flags_sp$ID$, phiObs=phiObs_sp$ID$, shift=1.0)\n\ flipDeleteParticlesInObstacle(pts=ppSnd_sp$ID$, flags=flags_sp$ID$) # delete particles inside obstacle and outflow cells\n\ \n\ diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h index fdb58543cec..72d5e20b58b 100644 --- a/intern/mantaflow/intern/strings/smoke_script.h +++ b/intern/mantaflow/intern/strings/smoke_script.h @@ -81,10 +81,10 @@ using_fire_s$ID$ = True\n"; const std::string smoke_alloc = "\n\ mantaMsg('Smoke alloc')\n\ -shadow_s$ID$ = s$ID$.create(RealGrid)\n\ +shadow_s$ID$ = s$ID$.create(RealGrid, name='$NAME_SHADOW$')\n\ emission_s$ID$ = s$ID$.create(RealGrid)\n\ emissionIn_s$ID$ = s$ID$.create(RealGrid)\n\ -density_s$ID$ = s$ID$.create(RealGrid)\n\ +density_s$ID$ = s$ID$.create(RealGrid, name='$NAME_DENSITY$')\n\ densityIn_s$ID$ = s$ID$.create(RealGrid)\n\ heat_s$ID$ = None # allocated dynamically\n\ heatIn_s$ID$ = None\n\ @@ -108,7 +108,7 @@ const std::string smoke_alloc_noise = "\n\ mantaMsg('Smoke alloc noise')\n\ vel_sn$ID$ = sn$ID$.create(MACGrid)\n\ -density_sn$ID$ = sn$ID$.create(RealGrid)\n\ +density_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_DENSITYNOISE$')\n\ phiIn_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\ phiOut_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\ phiObs_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\ @@ -157,9 +157,9 @@ 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)\n\ -color_g_s$ID$ = s$ID$.create(RealGrid)\n\ -color_b_s$ID$ = s$ID$.create(RealGrid)\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)\n\ color_g_in_s$ID$ = s$ID$.create(RealGrid)\n\ color_b_in_s$ID$ = s$ID$.create(RealGrid)\n\ @@ -178,9 +178,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)\n\ -color_g_sn$ID$ = sn$ID$.create(RealGrid)\n\ -color_b_sn$ID$ = sn$ID$.create(RealGrid)\n\ +color_r_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORRNOISE$')\n\ +color_g_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORGNOISE$')\n\ +color_b_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORBNOISE$')\n\ \n\ # Add objects to dict to load them later on\n\ if 'smoke_noise_dict_final_s$ID$' in globals():\n\ @@ -213,7 +213,7 @@ 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)\n\ +heat_s$ID$ = s$ID$.create(RealGrid, name='$NAME_HEAT$')\n\ heatIn_s$ID$ = s$ID$.create(RealGrid)\n\ \n\ # Add objects to dict to load them later on\n\ @@ -232,9 +232,9 @@ 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)\n\ -fuel_s$ID$ = s$ID$.create(RealGrid)\n\ -react_s$ID$ = s$ID$.create(RealGrid)\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)\n\ reactIn_s$ID$ = s$ID$.create(RealGrid)\n\ \n\ @@ -252,9 +252,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)\n\ -fuel_sn$ID$ = sn$ID$.create(RealGrid)\n\ -react_sn$ID$ = sn$ID$.create(RealGrid)\n\ +flame_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FLAMENOISE$')\n\ +fuel_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FUELNOISE$')\n\ +react_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_REACTNOISE$')\n\ \n\ # Add objects to dict to load them later on\n\ if 'smoke_noise_dict_final_s$ID$' in globals():\n\ @@ -376,9 +376,9 @@ def smoke_step_$ID$():\n\ \n\ if using_heat_s$ID$:\n\ mantaMsg('Adding heat buoyancy')\n\ - addBuoyancy(flags=flags_s$ID$, density=heat_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_heat_s$ID$)\n\ + addBuoyancy(flags=flags_s$ID$, density=heat_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_heat_s$ID$, scale=False)\n\ mantaMsg('Adding buoyancy')\n\ - addBuoyancy(flags=flags_s$ID$, density=density_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_dens_s$ID$)\n\ + addBuoyancy(flags=flags_s$ID$, density=density_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_dens_s$ID$, scale=False)\n\ \n\ mantaMsg('Adding forces')\n\ addForceField(flags=flags_s$ID$, vel=vel_s$ID$, force=forces_s$ID$)\n\ |