From f2b04302cdecb511879cde972e314bca934a32dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastia=CC=81n=20Barschkis?= Date: Fri, 31 Jul 2020 15:27:01 +0200 Subject: Fluid: Refactored Python pointer update function Use static_cast() where possible and refresh pointers for every frame when in replay mode. The latter is particularly important as this seems to have caused the issue where smoke in the viewport was flickering when loading data from pointers after loading them from disk for the frame before (e.g. when resuming a bake job). --- intern/mantaflow/extern/manta_fluid_API.h | 1 + intern/mantaflow/intern/MANTA_main.cpp | 260 +++++++++++++++------------- intern/mantaflow/intern/MANTA_main.h | 2 +- intern/mantaflow/intern/manta_fluid_API.cpp | 25 ++- 4 files changed, 154 insertions(+), 134 deletions(-) (limited to 'intern/mantaflow') diff --git a/intern/mantaflow/extern/manta_fluid_API.h b/intern/mantaflow/extern/manta_fluid_API.h index 3da1d8f53f0..f3fa01b5121 100644 --- a/intern/mantaflow/extern/manta_fluid_API.h +++ b/intern/mantaflow/extern/manta_fluid_API.h @@ -77,6 +77,7 @@ int manta_get_frame(struct MANTA *fluid); float manta_get_timestep(struct MANTA *fluid); void manta_adapt_timestep(struct MANTA *fluid); bool manta_needs_realloc(struct MANTA *fluid, struct FluidModifierData *fmd); +void manta_update_pointers(struct MANTA *fluid, struct FluidModifierData *fmd); /* Fluid accessors */ size_t manta_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */); diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index 5b2cbb09979..cbf61d6ff77 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -282,7 +282,8 @@ MANTA::MANTA(int *res, FluidModifierData *fmd) : mCurrentID(++solverID) initColorsHigh(); } } - updatePointers(); + + updatePointers(fmd); } void MANTA::initDomain(FluidModifierData *fmd) @@ -1823,12 +1824,18 @@ static PyObject *callPythonFunction(string varName, string functionName, bool is /* Be sure to initialize Python before using it. */ Py_Initialize(); - // Get pyobject that holds result value + /* Get pyobject that holds result value. */ if (!manta_main_module) { PyGILState_Release(gilstate); return nullptr; } + /* Ensure that requested variable is present in module - avoid attribute errors later on. */ + if (!PyObject_HasAttrString(manta_main_module, varName.c_str())) { + PyGILState_Release(gilstate); + return nullptr; + } + var = PyObject_GetAttrString(manta_main_module, varName.c_str()); if (!var) { PyGILState_Release(gilstate); @@ -1911,6 +1918,11 @@ static long pyObjectToLong(PyObject *inputObject) return result; } +template static T *getPointer(string pyObjectName, string pyFunctionName) +{ + return static_cast(pyObjectToPointer(callPythonFunction(pyObjectName, pyFunctionName))); +} + int MANTA::getFrame() { if (with_debug) @@ -1955,137 +1967,137 @@ void MANTA::adaptTimestep() runPythonString(pythonCommands); } -void MANTA::updatePointers() +void MANTA::updatePointers(FluidModifierData *fmd) { if (with_debug) cout << "MANTA::updatePointers()" << endl; + FluidDomainSettings *fds = fmd->domain; + + bool liquid = (fds->type == FLUID_DOMAIN_TYPE_LIQUID); + bool smoke = (fds->type == FLUID_DOMAIN_TYPE_GAS); + bool noise = smoke && fds->flags & FLUID_DOMAIN_USE_NOISE; + bool heat = smoke && fds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT; + bool colors = smoke && fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS; + bool fire = smoke && fds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE; + bool obstacle = fds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE; + bool guiding = fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE; + bool invel = fds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL; + bool outflow = fds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW; + bool drops = liquid && fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY; + bool bubble = liquid && fds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE; + bool floater = liquid && fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM; + bool tracer = liquid && fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER; + bool parts = liquid && (drops | bubble | floater | tracer); + bool mesh = liquid && fds->flags & FLUID_DOMAIN_USE_MESH; + bool meshvel = liquid && mesh && fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS; + 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)); - mPhiStaticIn = (float *)pyObjectToPointer(callPythonFunction("phiSIn" + solver_ext, func)); - mVelocityX = (float *)pyObjectToPointer(callPythonFunction("x_vel" + solver_ext, func)); - mVelocityY = (float *)pyObjectToPointer(callPythonFunction("y_vel" + solver_ext, func)); - mVelocityZ = (float *)pyObjectToPointer(callPythonFunction("z_vel" + solver_ext, func)); - mForceX = (float *)pyObjectToPointer(callPythonFunction("x_force" + solver_ext, func)); - mForceY = (float *)pyObjectToPointer(callPythonFunction("y_force" + solver_ext, func)); - mForceZ = (float *)pyObjectToPointer(callPythonFunction("z_force" + solver_ext, func)); - - if (mUsingOutflow) { - mPhiOutIn = (float *)pyObjectToPointer(callPythonFunction("phiOutIn" + solver_ext, func)); - mPhiOutStaticIn = (float *)pyObjectToPointer( - callPythonFunction("phiOutSIn" + solver_ext, func)); - } - if (mUsingObstacle) { - mPhiObsIn = (float *)pyObjectToPointer(callPythonFunction("phiObsIn" + solver_ext, func)); - mPhiObsStaticIn = (float *)pyObjectToPointer( - callPythonFunction("phiObsSIn" + solver_ext, func)); - mObVelocityX = (float *)pyObjectToPointer(callPythonFunction("x_obvel" + solver_ext, func)); - mObVelocityY = (float *)pyObjectToPointer(callPythonFunction("y_obvel" + solver_ext, func)); - mObVelocityZ = (float *)pyObjectToPointer(callPythonFunction("z_obvel" + solver_ext, func)); - mNumObstacle = (float *)pyObjectToPointer(callPythonFunction("numObs" + solver_ext, func)); - } - if (mUsingGuiding) { - mPhiGuideIn = (float *)pyObjectToPointer(callPythonFunction("phiGuideIn" + solver_ext, func)); - mGuideVelocityX = (float *)pyObjectToPointer( - callPythonFunction("x_guidevel" + solver_ext, func)); - mGuideVelocityY = (float *)pyObjectToPointer( - callPythonFunction("y_guidevel" + solver_ext, func)); - mGuideVelocityZ = (float *)pyObjectToPointer( - callPythonFunction("z_guidevel" + solver_ext, func)); - mNumGuide = (float *)pyObjectToPointer(callPythonFunction("numGuides" + solver_ext, func)); - } - if (mUsingInvel) { - mInVelocityX = (float *)pyObjectToPointer(callPythonFunction("x_invel" + solver_ext, func)); - mInVelocityY = (float *)pyObjectToPointer(callPythonFunction("y_invel" + solver_ext, func)); - mInVelocityZ = (float *)pyObjectToPointer(callPythonFunction("z_invel" + solver_ext, func)); - } - if (mUsingSmoke) { - mDensity = (float *)pyObjectToPointer(callPythonFunction("density" + solver_ext, func)); - mDensityIn = (float *)pyObjectToPointer(callPythonFunction("densityIn" + solver_ext, func)); - mShadow = (float *)pyObjectToPointer(callPythonFunction("shadow" + solver_ext, func)); - mEmissionIn = (float *)pyObjectToPointer(callPythonFunction("emissionIn" + solver_ext, func)); - } - if (mUsingSmoke && mUsingHeat) { - mHeat = (float *)pyObjectToPointer(callPythonFunction("heat" + solver_ext, func)); - mHeatIn = (float *)pyObjectToPointer(callPythonFunction("heatIn" + solver_ext, func)); - } - if (mUsingSmoke && mUsingFire) { - mFlame = (float *)pyObjectToPointer(callPythonFunction("flame" + solver_ext, func)); - mFuel = (float *)pyObjectToPointer(callPythonFunction("fuel" + solver_ext, func)); - mReact = (float *)pyObjectToPointer(callPythonFunction("react" + solver_ext, func)); - mFuelIn = (float *)pyObjectToPointer(callPythonFunction("fuelIn" + solver_ext, func)); - mReactIn = (float *)pyObjectToPointer(callPythonFunction("reactIn" + solver_ext, func)); - } - if (mUsingSmoke && mUsingColors) { - mColorR = (float *)pyObjectToPointer(callPythonFunction("color_r" + solver_ext, func)); - mColorG = (float *)pyObjectToPointer(callPythonFunction("color_g" + solver_ext, func)); - mColorB = (float *)pyObjectToPointer(callPythonFunction("color_b" + solver_ext, func)); - mColorRIn = (float *)pyObjectToPointer(callPythonFunction("color_r_in" + solver_ext, func)); - mColorGIn = (float *)pyObjectToPointer(callPythonFunction("color_g_in" + solver_ext, func)); - mColorBIn = (float *)pyObjectToPointer(callPythonFunction("color_b_in" + solver_ext, func)); - } - if (mUsingSmoke && mUsingNoise) { - mDensityHigh = (float *)pyObjectToPointer(callPythonFunction("density" + noise_ext, func)); - mTextureU = (float *)pyObjectToPointer(callPythonFunction("texture_u" + solver_ext, func)); - mTextureV = (float *)pyObjectToPointer(callPythonFunction("texture_v" + solver_ext, func)); - mTextureW = (float *)pyObjectToPointer(callPythonFunction("texture_w" + solver_ext, func)); - mTextureU2 = (float *)pyObjectToPointer(callPythonFunction("texture_u2" + solver_ext, func)); - mTextureV2 = (float *)pyObjectToPointer(callPythonFunction("texture_v2" + solver_ext, func)); - mTextureW2 = (float *)pyObjectToPointer(callPythonFunction("texture_w2" + solver_ext, func)); - } - if (mUsingSmoke && mUsingNoise && mUsingFire) { - mFlameHigh = (float *)pyObjectToPointer(callPythonFunction("flame" + noise_ext, func)); - mFuelHigh = (float *)pyObjectToPointer(callPythonFunction("fuel" + noise_ext, func)); - mReactHigh = (float *)pyObjectToPointer(callPythonFunction("react" + noise_ext, func)); - } - if (mUsingSmoke && mUsingNoise && mUsingColors) { - mColorRHigh = (float *)pyObjectToPointer(callPythonFunction("color_r" + noise_ext, func)); - mColorGHigh = (float *)pyObjectToPointer(callPythonFunction("color_g" + noise_ext, func)); - mColorBHigh = (float *)pyObjectToPointer(callPythonFunction("color_b" + noise_ext, func)); - } - if (mUsingLiquid) { - mPhi = (float *)pyObjectToPointer(callPythonFunction("phi" + solver_ext, func)); - mFlipParticleData = (vector *)pyObjectToPointer( - callPythonFunction("pp" + solver_ext, func)); - mFlipParticleVelocity = (vector *)pyObjectToPointer( - callPythonFunction("pVel" + parts_ext, func)); - } - if (mUsingLiquid && mUsingMesh) { - mMeshNodes = (vector *)pyObjectToPointer( - callPythonFunction("mesh" + mesh_ext, funcNodes)); - mMeshTriangles = (vector *)pyObjectToPointer( - callPythonFunction("mesh" + mesh_ext, funcTris)); - } - if (mUsingLiquid && mUsingMVel) { - mMeshVelocities = (vector *)pyObjectToPointer( - callPythonFunction("mVel" + mesh_ext2, func)); - } - if (mUsingLiquid && (mUsingDrops | mUsingBubbles | mUsingFloats | mUsingTracers)) { - mSndParticleData = (vector *)pyObjectToPointer( - callPythonFunction("ppSnd" + snd_ext, func)); - mSndParticleVelocity = (vector *)pyObjectToPointer( - callPythonFunction("pVelSnd" + parts_ext, func)); - mSndParticleLife = (vector *)pyObjectToPointer( - callPythonFunction("pLifeSnd" + parts_ext, func)); - } + string s_ext = "_s" + id; + string pp_ext = "_pp" + id; + string snd_ext = "_sp" + id; + string sm_ext = "_sm" + id; + string mesh_ext = "_mesh" + id; + string sn_ext = "_sn" + id; + + mFlags = getPointer("flags" + s_ext, func); + mPhiIn = getPointer("phiIn" + s_ext, func); + mPhiStaticIn = getPointer("phiSIn" + s_ext, func); + mVelocityX = getPointer("x_vel" + s_ext, func); + mVelocityY = getPointer("y_vel" + s_ext, func); + mVelocityZ = getPointer("z_vel" + s_ext, func); + mForceX = getPointer("x_force" + s_ext, func); + mForceY = getPointer("y_force" + s_ext, func); + mForceZ = getPointer("z_force" + s_ext, func); + + /* Outflow. */ + mPhiOutIn = (outflow) ? getPointer("phiOutIn" + s_ext, func) : nullptr; + mPhiOutStaticIn = (outflow) ? getPointer("phiOutSIn" + s_ext, func) : nullptr; + + /* Obstacles. */ + mPhiObsIn = (obstacle) ? getPointer("phiObsIn" + s_ext, func) : nullptr; + mPhiObsStaticIn = (obstacle) ? getPointer("phiObsSIn" + s_ext, func) : nullptr; + mObVelocityX = (obstacle) ? getPointer("x_obvel" + s_ext, func) : nullptr; + mObVelocityY = (obstacle) ? getPointer("y_obvel" + s_ext, func) : nullptr; + mObVelocityZ = (obstacle) ? getPointer("z_obvel" + s_ext, func) : nullptr; + mNumObstacle = (obstacle) ? getPointer("numObs" + s_ext, func) : nullptr; + + /* Guiding. */ + mPhiGuideIn = (guiding) ? getPointer("phiGuideIn" + s_ext, func) : nullptr; + mGuideVelocityX = (guiding) ? getPointer("x_guidevel" + s_ext, func) : nullptr; + mGuideVelocityY = (guiding) ? getPointer("y_guidevel" + s_ext, func) : nullptr; + mGuideVelocityZ = (guiding) ? getPointer("z_guidevel" + s_ext, func) : nullptr; + mNumGuide = (guiding) ? getPointer("numGuides" + s_ext, func) : nullptr; + + /* Initial velocities. */ + mInVelocityX = (invel) ? getPointer("x_invel" + s_ext, func) : nullptr; + mInVelocityY = (invel) ? getPointer("y_invel" + s_ext, func) : nullptr; + mInVelocityZ = (invel) ? getPointer("z_invel" + s_ext, func) : nullptr; + + /* Smoke. */ + mDensity = (smoke) ? getPointer("density" + s_ext, func) : nullptr; + mDensityIn = (smoke) ? getPointer("densityIn" + s_ext, func) : nullptr; + mShadow = (smoke) ? getPointer("shadow" + s_ext, func) : nullptr; + mEmissionIn = (smoke) ? getPointer("emissionIn" + s_ext, func) : nullptr; + + /* Heat. */ + mHeat = (heat) ? getPointer("heat" + s_ext, func) : nullptr; + mHeatIn = (heat) ? getPointer("heatIn" + s_ext, func) : nullptr; + + /* Fire. */ + mFlame = (fire) ? getPointer("flame" + s_ext, func) : nullptr; + mFuel = (fire) ? getPointer("fuel" + s_ext, func) : nullptr; + mReact = (fire) ? getPointer("react" + s_ext, func) : nullptr; + mFuelIn = (fire) ? getPointer("fuelIn" + s_ext, func) : nullptr; + mReactIn = (fire) ? getPointer("reactIn" + s_ext, func) : nullptr; + + /* Colors. */ + mColorR = (colors) ? getPointer("color_r" + s_ext, func) : nullptr; + mColorG = (colors) ? getPointer("color_g" + s_ext, func) : nullptr; + mColorB = (colors) ? getPointer("color_b" + s_ext, func) : nullptr; + mColorRIn = (colors) ? getPointer("color_r_in" + s_ext, func) : nullptr; + mColorGIn = (colors) ? getPointer("color_g_in" + s_ext, func) : nullptr; + mColorBIn = (colors) ? getPointer("color_b_in" + s_ext, func) : nullptr; + + /* Noise. */ + mDensityHigh = (noise) ? getPointer("density" + sn_ext, func) : nullptr; + mTextureU = (noise) ? getPointer("texture_u" + s_ext, func) : nullptr; + mTextureV = (noise) ? getPointer("texture_v" + s_ext, func) : nullptr; + mTextureW = (noise) ? getPointer("texture_w" + s_ext, func) : nullptr; + mTextureU2 = (noise) ? getPointer("texture_u2" + s_ext, func) : nullptr; + mTextureV2 = (noise) ? getPointer("texture_v2" + s_ext, func) : nullptr; + mTextureW2 = (noise) ? getPointer("texture_w2" + s_ext, func) : nullptr; + + /* Fire with noise. */ + mFlameHigh = (noise && fire) ? getPointer("flame" + sn_ext, func) : nullptr; + mFuelHigh = (noise && fire) ? getPointer("fuel" + sn_ext, func) : nullptr; + mReactHigh = (noise && fire) ? getPointer("react" + sn_ext, func) : nullptr; + + /* Colors with noise. */ + mColorRHigh = (noise && colors) ? getPointer("color_r" + sn_ext, func) : nullptr; + mColorGHigh = (noise && colors) ? getPointer("color_g" + sn_ext, func) : nullptr; + mColorBHigh = (noise && colors) ? getPointer("color_b" + sn_ext, func) : nullptr; + + /* Liquid. */ + mPhi = (liquid) ? getPointer("phi" + s_ext, func) : nullptr; + mFlipParticleData = (liquid) ? getPointer>("pp" + s_ext, func) : nullptr; + mFlipParticleVelocity = (liquid) ? getPointer>("pVel" + pp_ext, func) : nullptr; + + /* Mesh. */ + mMeshNodes = (mesh) ? getPointer>("mesh" + sm_ext, funcNodes) : nullptr; + mMeshTriangles = (mesh) ? getPointer>("mesh" + sm_ext, funcTris) : nullptr; + + /* Mesh velocities. */ + mMeshVelocities = (meshvel) ? getPointer>("mVel" + mesh_ext, func) : nullptr; + + /* Secondary particles. */ + mSndParticleData = (parts) ? getPointer>("ppSnd" + snd_ext, func) : nullptr; + mSndParticleVelocity = (parts) ? getPointer>("pVelSnd" + pp_ext, func) : nullptr; + mSndParticleLife = (parts) ? getPointer>("pLifeSnd" + pp_ext, func) : nullptr; mFlipFromFile = false; mMeshFromFile = false; diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h index dae2aea4e08..885ca28871d 100644 --- a/intern/mantaflow/intern/MANTA_main.h +++ b/intern/mantaflow/intern/MANTA_main.h @@ -81,7 +81,7 @@ struct MANTA { void initLiquidSndParts(FluidModifierData *fmd = NULL); // Pointer transfer: Mantaflow -> Blender - void updatePointers(); + void updatePointers(FluidModifierData *fmd); // Write cache bool writeConfiguration(FluidModifierData *fmd, int framenr); diff --git a/intern/mantaflow/intern/manta_fluid_API.cpp b/intern/mantaflow/intern/manta_fluid_API.cpp index 60546bc1183..acc1cfde668 100644 --- a/intern/mantaflow/intern/manta_fluid_API.cpp +++ b/intern/mantaflow/intern/manta_fluid_API.cpp @@ -42,28 +42,28 @@ void manta_ensure_obstacle(MANTA *fluid, struct FluidModifierData *fmd) if (!fluid) return; fluid->initObstacle(fmd); - fluid->updatePointers(); + fluid->updatePointers(fmd); } void manta_ensure_guiding(MANTA *fluid, struct FluidModifierData *fmd) { if (!fluid) return; fluid->initGuiding(fmd); - fluid->updatePointers(); + fluid->updatePointers(fmd); } void manta_ensure_invelocity(MANTA *fluid, struct FluidModifierData *fmd) { if (!fluid) return; fluid->initInVelocity(fmd); - fluid->updatePointers(); + fluid->updatePointers(fmd); } void manta_ensure_outflow(MANTA *fluid, struct FluidModifierData *fmd) { if (!fluid) return; fluid->initOutflow(fmd); - fluid->updatePointers(); + fluid->updatePointers(fmd); } int manta_write_config(MANTA *fluid, FluidModifierData *fmd, int framenr) @@ -229,11 +229,18 @@ void manta_adapt_timestep(MANTA *fluid) bool manta_needs_realloc(MANTA *fluid, FluidModifierData *fmd) { - if (!fluid) + if (!fluid || !fmd) return false; return fluid->needsRealloc(fmd); } +void manta_update_pointers(struct MANTA *fluid, struct FluidModifierData *fmd) +{ + if (!fluid || !fmd) + return; + fluid->updatePointers(fmd); +} + /* Fluid accessors */ size_t manta_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */) { @@ -445,7 +452,7 @@ void manta_smoke_ensure_heat(MANTA *smoke, struct FluidModifierData *fmd) { if (smoke) { smoke->initHeat(fmd); - smoke->updatePointers(); + smoke->updatePointers(fmd); } } @@ -456,7 +463,7 @@ void manta_smoke_ensure_fire(MANTA *smoke, struct FluidModifierData *fmd) if (smoke->usingNoise()) { smoke->initFireHigh(fmd); } - smoke->updatePointers(); + smoke->updatePointers(fmd); } } @@ -467,7 +474,7 @@ void manta_smoke_ensure_colors(MANTA *smoke, struct FluidModifierData *fmd) if (smoke->usingNoise()) { smoke->initColorsHigh(fmd); } - smoke->updatePointers(); + smoke->updatePointers(fmd); } } @@ -649,7 +656,7 @@ void manta_liquid_ensure_sndparts(MANTA *liquid, struct FluidModifierData *fmd) { if (liquid) { liquid->initLiquidSndParts(fmd); - liquid->updatePointers(); + liquid->updatePointers(fmd); } } -- cgit v1.2.3