35using std::istringstream;
37using std::ostringstream;
44 : mCurrentID(++
solverID), mMaxRes(fmd->domain->maxres)
47 cout <<
"FLUID: " << mCurrentID <<
" with res(" << res[0] <<
", " << res[1] <<
", " << res[2]
79 mTotalCells = mResX * mResY * mResZ;
80 mResGuiding = fds->
res;
106 mEmissionIn =
nullptr;
110 mDensityHigh =
nullptr;
111 mFlameHigh =
nullptr;
113 mReactHigh =
nullptr;
114 mColorRHigh =
nullptr;
115 mColorGHigh =
nullptr;
116 mColorBHigh =
nullptr;
120 mTextureU2 =
nullptr;
121 mTextureV2 =
nullptr;
122 mTextureW2 =
nullptr;
126 mPhiStaticIn =
nullptr;
128 mPhiOutStaticIn =
nullptr;
132 mMeshNodes =
nullptr;
133 mMeshTriangles =
nullptr;
134 mMeshVelocities =
nullptr;
138 mPhiObsStaticIn =
nullptr;
139 mNumObstacle =
nullptr;
140 mObVelocityX =
nullptr;
141 mObVelocityY =
nullptr;
142 mObVelocityZ =
nullptr;
145 mPhiGuideIn =
nullptr;
147 mGuideVelocityX =
nullptr;
148 mGuideVelocityY =
nullptr;
149 mGuideVelocityZ =
nullptr;
152 mInVelocityX =
nullptr;
153 mInVelocityY =
nullptr;
154 mInVelocityZ =
nullptr;
157 mFlipParticleData =
nullptr;
158 mFlipParticleVelocity =
nullptr;
159 mParticleData =
nullptr;
160 mParticleVelocity =
nullptr;
161 mParticleLife =
nullptr;
164 mFlipFromFile =
false;
165 mMeshFromFile =
false;
166 mParticlesFromFile =
false;
169 initializeMantaflow();
172 initializeRNAMap(fmd);
174 bool initSuccess =
true;
178 initSuccess &= initDomain();
180 if (mUsingObstacle) {
190 if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) {
192 mResXParticle = mUpresParticle * mResX;
193 mResYParticle = mUpresParticle * mResY;
194 mResZParticle = mUpresParticle * mResZ;
195 mTotalCellsParticles = mResXParticle * mResYParticle * mResZParticle;
203 mResXMesh = mUpresMesh * mResX;
204 mResYMesh = mUpresMesh * mResY;
205 mResZMesh = mUpresMesh * mResZ;
206 mTotalCellsMesh = mResXMesh * mResYMesh * mResZMesh;
209 initSuccess &= initMesh();
213 if (mUsingViscosity) {
217 if (mUsingDiffusion) {
225 if (mUsingFractions) {
232 initSuccess &= initDomain();
233 initSuccess &= initSmoke();
243 if (mUsingObstacle) {
260 mResXNoise = amplify * mResX;
261 mResYNoise = amplify * mResY;
262 mResZNoise = amplify * mResZ;
263 mTotalCellsHigh = mResXNoise * mResYNoise * mResZNoise;
266 initSuccess &= initNoise();
267 initSuccess &= initSmokeNoise();
292 ss <<
"set_manta_debuglevel(" <<
with_debug <<
")";
293 pythonCommands.push_back(ss.str());
297 fluid_bake_multiprocessing + fluid_bake_data + fluid_bake_noise +
298 fluid_bake_mesh + fluid_bake_particles + fluid_bake_guiding +
299 fluid_file_import + fluid_file_export + fluid_pre_step + fluid_post_step +
301 string finalString = parseScript(tmpString, fmd);
302 pythonCommands.push_back(finalString);
303 return runPythonString(pythonCommands);
308 vector<string> pythonCommands;
310 string finalString = parseScript(tmpString, fmd);
311 pythonCommands.push_back(finalString);
313 return runPythonString(pythonCommands);
318 vector<string> pythonCommands;
320 smoke_load_data + smoke_step;
321 string finalString = parseScript(tmpString, fmd);
322 pythonCommands.push_back(finalString);
324 return runPythonString(pythonCommands);
329 vector<string> pythonCommands;
331 smoke_save_noise + smoke_load_noise + smoke_step_noise;
332 string finalString = parseScript(tmpString, fmd);
333 pythonCommands.push_back(finalString);
336 return runPythonString(pythonCommands);
344 string finalString = parseScript(tmpString, fmd);
345 pythonCommands.push_back(finalString);
348 return runPythonString(pythonCommands);
358 string finalString = parseScript(tmpString, fmd);
359 pythonCommands.push_back(finalString);
362 return runPythonString(pythonCommands);
372 string finalString = parseScript(tmpString, fmd);
373 pythonCommands.push_back(finalString);
376 return runPythonString(pythonCommands);
386 string finalString = parseScript(tmpString, fmd);
387 pythonCommands.push_back(finalString);
390 return runPythonString(pythonCommands);
400 string finalString = parseScript(tmpString, fmd);
401 pythonCommands.push_back(finalString);
404 return runPythonString(pythonCommands);
414 liquid_load_data + liquid_adaptive_step + liquid_step;
415 string finalString = parseScript(tmpString, fmd);
416 pythonCommands.push_back(finalString);
419 return runPythonString(pythonCommands);
428 string finalString = parseScript(tmpString, fmd);
429 pythonCommands.push_back(finalString);
432 return runPythonString(pythonCommands);
439 string finalString = parseScript(tmpString, fmd);
440 pythonCommands.push_back(finalString);
443 return runPythonString(pythonCommands);
450 string finalString = parseScript(tmpString, fmd);
451 pythonCommands.push_back(finalString);
453 mUsingViscosity =
true;
454 return runPythonString(pythonCommands);
459 std::vector<std::string> pythonCommands;
461 pythonCommands.push_back(finalString);
463 mUsingDiffusion =
true;
464 return runPythonString(pythonCommands);
472 string finalString = parseScript(tmpString, fmd);
473 pythonCommands.push_back(finalString);
475 return (mUsingObstacle = runPythonString(pythonCommands));
485 fluid_save_guiding + fluid_load_vel + fluid_load_guiding;
486 string finalString = parseScript(tmpString, fmd);
487 pythonCommands.push_back(finalString);
489 return (mUsingGuiding = runPythonString(pythonCommands));
498 string finalString = parseScript(tmpString, fmd);
499 pythonCommands.push_back(finalString);
501 return (mUsingFractions = runPythonString(pythonCommands));
509 string finalString = parseScript(tmpString, fmd);
510 pythonCommands.push_back(finalString);
512 return (mUsingInvel = runPythonString(pythonCommands));
522 string finalString = parseScript(tmpString, fmd);
523 pythonCommands.push_back(finalString);
525 return (mUsingOutflow = runPythonString(pythonCommands));
534 string finalString = parseScript(tmpString, fmd);
535 pythonCommands.push_back(finalString);
537 return runPythonString(pythonCommands);
542 if (!mParticleData) {
546 liquid_save_particles;
547 string finalString = parseScript(tmpString, fmd);
548 pythonCommands.push_back(finalString);
550 return runPythonString(pythonCommands);
558 cout <<
"~FLUID: " << mCurrentID <<
" with res(" << mResX <<
", " << mResY <<
", " << mResZ
568 tmpString += fluid_delete_all;
574 string finalString = parseScript(tmpString);
575 pythonCommands.push_back(finalString);
576 result = runPythonString(pythonCommands);
583 MANTA::terminateMantaflow();
598 PyObject *builtins = PyEval_GetBuiltins();
599 PyObject *mod_main = PyModule_New(
"__main__");
600 PyModule_AddStringConstant(mod_main,
"__name__",
"__main__");
604 PyModule_AddObject(mod_main,
"__file__", PyUnicode_InternFromString(filename));
606 PyModule_AddObjectRef(mod_main,
"__builtins__", builtins);
612 PyObject *modules = PyImport_GetModuleDict();
613 PyObject *main_mod_cmp = PyDict_GetItemString(modules,
"__main__");
614 if (mod_main == main_mod_cmp) {
619 PyDict_SetItemString(modules,
"__main__", mod_main);
624 PyObject *modules = PyImport_GetModuleDict();
625 *r_main_mod = PyDict_GetItemString(modules,
"__main__");
626 Py_XINCREF(*r_main_mod);
631 PyObject *modules = PyImport_GetModuleDict();
632 PyDict_SetItemString(modules,
"__main__", main_mod);
633 Py_XDECREF(main_mod);
664 PyGILState_STATE gilstate = PyGILState_Ensure();
667 PyObject *main_mod_backup;
675 for (vector<string>::iterator it = commands.begin(); it != commands.end(); ++it) {
676 string command = *it;
679 PyObject *return_value = PyRun_String(
680 command.c_str(), Py_file_input, globals_dict, globals_dict);
682 if (return_value ==
nullptr) {
684 if (PyErr_Occurred()) {
695 PyGILState_Release(gilstate);
701void MANTA::initializeMantaflow()
704 cout <<
"Fluid: Initializing Mantaflow framework" <<
endl;
707 string filename =
"manta_scene_" +
to_string(mCurrentID) +
".py";
708 vector<string> fill = vector<string>();
712 PyGILState_STATE gilstate = PyGILState_Ensure();
716 Pb::setup(
false, filename, fill, globals_dict);
717 PyGILState_Release(gilstate);
720void MANTA::terminateMantaflow()
723 cout <<
"Fluid: Releasing Mantaflow framework" <<
endl;
726 PyGILState_STATE gilstate = PyGILState_Ensure();
729 PyGILState_Release(gilstate);
735 cout <<
"MANTA::getCacheFileEnding()" << endl;
738 switch (cache_format) {
750 cerr <<
"Fluid Error -- Could not find file extension. Using default file extension."
758 return (value) ?
"True" :
"False";
764 cout <<
"MANTA::initializeRNAMap()" <<
endl;
771 cout <<
"Fluid: No modifier data given in RNA map setup - returning early" <<
endl;
779 string borderCollisions;
781 borderCollisions +=
"x";
784 borderCollisions +=
"X";
787 borderCollisions +=
"y";
790 borderCollisions +=
"Y";
793 borderCollisions +=
"z";
796 borderCollisions +=
"Z";
799 string particleTypesStr;
801 particleTypesStr +=
"PtypeSpray";
804 if (!particleTypesStr.empty()) {
805 particleTypesStr +=
"|";
807 particleTypesStr +=
"PtypeBubble";
810 if (!particleTypesStr.empty()) {
811 particleTypesStr +=
"|";
813 particleTypesStr +=
"PtypeFoam";
816 if (!particleTypesStr.empty()) {
817 particleTypesStr +=
"|";
819 particleTypesStr +=
"PtypeTracer";
821 if (particleTypesStr.empty()) {
822 particleTypesStr =
"0";
833 string vdbCompressionMethod =
"Compression_None";
835 vdbCompressionMethod =
"Compression_None";
838 vdbCompressionMethod =
"Compression_Zip";
841 vdbCompressionMethod =
"Compression_Blosc";
844 string vdbPrecisionHalf =
"Precision_Half";
846 vdbPrecisionHalf =
"Precision_Full";
849 vdbPrecisionHalf =
"Precision_Half";
852 vdbPrecisionHalf =
"Precision_Mini";
867 mRNAMap[
"DOMAIN_CLOSED"] =
getBooleanString(borderCollisions.compare(
"") == 0);
884 mRNAMap[
"BOUND_CONDITIONS"] = borderCollisions;
903 mRNAMap[
"NOISE_RESX"] =
to_string(mResXNoise);
906 mRNAMap[
"MESH_RESX"] =
to_string(mResXMesh);
909 mRNAMap[
"PARTICLE_RESX"] =
to_string(mResXParticle);
910 mRNAMap[
"PARTICLE_RESY"] = (is2D) ?
to_string(mResZParticle) :
to_string(mResYParticle);
912 mRNAMap[
"GUIDING_RESX"] =
to_string(mResGuiding[0]);
913 mRNAMap[
"GUIDING_RESY"] = (is2D) ?
to_string(mResGuiding[2]) :
to_string(mResGuiding[1]);
974 mRNAMap[
"FLUID_VISCOSITY"] =
to_string(viscosity);
975 mRNAMap[
"FLUID_DOMAIN_SIZE"] =
to_string(domainSize);
979 mRNAMap[
"SNDPARTICLE_TYPES"] = particleTypesStr;
986 mRNAMap[
"CACHE_DIR"] = cacheDirectory;
987 mRNAMap[
"COMPRESSION_OPENVDB"] = vdbCompressionMethod;
988 mRNAMap[
"PRECISION_OPENVDB"] = vdbPrecisionHalf;
1140string MANTA::getRealValue(
const string &varName)
1142 unordered_map<string, string>::iterator it;
1143 it = mRNAMap.find(varName);
1145 if (it == mRNAMap.end()) {
1146 cerr <<
"Fluid Error -- variable " << varName <<
" not found in RNA map" <<
endl;
1153string MANTA::parseLine(
const string &line)
1155 if (line.size() == 0) {
1159 int currPos = 0, start_del = 0, end_del = -1;
1160 bool readingVar =
false;
1161 const char delimiter =
'$';
1162 while (currPos < line.size()) {
1163 if (line[currPos] == delimiter && !readingVar) {
1165 start_del = currPos + 1;
1166 res += line.substr(end_del + 1, currPos - end_del - 1);
1168 else if (line[currPos] == delimiter && readingVar) {
1171 res += getRealValue(line.substr(start_del, currPos - start_del));
1175 res += line.substr(end_del + 1, line.size() - end_del);
1182 cout <<
"MANTA::parseScript()" <<
endl;
1185 istringstream f(setup_string);
1191 initializeRNAMap(fmd);
1193 while (getline(f, line)) {
1194 res << parseLine(line) <<
"\n";
1207 else if (c ==
'\'') {
1220 cout <<
"MANTA::writeConfiguration()" << endl;
1233 gzFile gzf = (gzFile)
BLI_gzopen(file.c_str(),
"wb1");
1235 cerr <<
"Fluid Error -- Cannot open file " << file << endl;
1240 gzwrite(gzf, &fds->
res, 3 *
sizeof(
int));
1241 gzwrite(gzf, &fds->
dx,
sizeof(
float));
1242 gzwrite(gzf, &fds->
dt,
sizeof(
float));
1243 gzwrite(gzf, &fds->
p0, 3 *
sizeof(
float));
1244 gzwrite(gzf, &fds->
p1, 3 *
sizeof(
float));
1245 gzwrite(gzf, &fds->
dp0, 3 *
sizeof(
float));
1246 gzwrite(gzf, &fds->
shift, 3 *
sizeof(
int));
1247 gzwrite(gzf, &fds->
obj_shift_f, 3 *
sizeof(
float));
1248 gzwrite(gzf, &fds->
obmat, 16 *
sizeof(
float));
1249 gzwrite(gzf, &fds->
base_res, 3 *
sizeof(
int));
1250 gzwrite(gzf, &fds->
res_min, 3 *
sizeof(
int));
1251 gzwrite(gzf, &fds->
res_max, 3 *
sizeof(
int));
1256 return (gzclose(gzf) == Z_OK);
1262 cout <<
"MANTA::writeData()" << endl;
1275 ss <<
"smoke_save_data_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1276 <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1277 pythonCommands.push_back(ss.str());
1281 ss <<
"liquid_save_data_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1282 <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1283 pythonCommands.push_back(ss.str());
1285 return runPythonString(pythonCommands);
1291 cout <<
"MANTA::writeNoise()" << endl;
1302 if (mUsingSmoke && mUsingNoise) {
1304 ss <<
"smoke_save_noise_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1305 <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1306 pythonCommands.push_back(ss.str());
1308 return runPythonString(pythonCommands);
1314 cout <<
"MANTA::readConfiguration()" << endl;
1328 gzFile gzf = (gzFile)
BLI_gzopen(file.c_str(),
"rb");
1330 cerr <<
"Fluid Error -- Cannot open file " << file << endl;
1335 gzread(gzf, &fds->
res, 3 *
sizeof(
int));
1336 gzread(gzf, &fds->
dx,
sizeof(
float));
1337 gzread(gzf, &dummy,
sizeof(
float));
1338 gzread(gzf, &fds->
p0, 3 *
sizeof(
float));
1339 gzread(gzf, &fds->
p1, 3 *
sizeof(
float));
1340 gzread(gzf, &fds->
dp0, 3 *
sizeof(
float));
1341 gzread(gzf, &fds->
shift, 3 *
sizeof(
int));
1342 gzread(gzf, &fds->
obj_shift_f, 3 *
sizeof(
float));
1343 gzread(gzf, &fds->
obmat, 16 *
sizeof(
float));
1344 gzread(gzf, &fds->
base_res, 3 *
sizeof(
int));
1345 gzread(gzf, &fds->
res_min, 3 *
sizeof(
int));
1346 gzread(gzf, &fds->
res_max, 3 *
sizeof(
int));
1349 gzread(gzf, &fds->
cache_id, 4 *
sizeof(
char));
1353 return (gzclose(gzf) == Z_OK);
1359 cout <<
"MANTA::readData()" << endl;
1362 if (!mUsingSmoke && !mUsingLiquid) {
1373 string resumable_cache = (!resumable) ?
"False" :
"True";
1382 ss <<
"smoke_load_data_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1383 <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1384 pythonCommands.push_back(ss.str());
1385 result &= runPythonString(pythonCommands);
1386 return (mSmokeFromFile =
result);
1390 ss <<
"liquid_load_data_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1391 <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1392 pythonCommands.push_back(ss.str());
1393 result &= runPythonString(pythonCommands);
1394 return (mFlipFromFile =
result);
1402 cout <<
"MANTA::readNoise()" << endl;
1405 if (!mUsingSmoke || !mUsingNoise) {
1414 string resumable_cache = (!resumable) ?
"False" :
"True";
1427 ss <<
"smoke_load_noise_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1428 <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1429 pythonCommands.push_back(ss.str());
1431 return (mNoiseFromFile = runPythonString(pythonCommands));
1437 cout <<
"MANTA::readMesh()" << endl;
1440 if (!mUsingLiquid || !mUsingMesh) {
1458 ss <<
"liquid_load_mesh_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1459 <<
", '" << mesh_format <<
"')";
1460 pythonCommands.push_back(ss.str());
1464 ss <<
"liquid_load_meshvel_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1465 <<
", '" << volume_format <<
"')";
1466 pythonCommands.push_back(ss.str());
1469 return (mMeshFromFile = runPythonString(pythonCommands));
1475 cout <<
"MANTA::readParticles()" << endl;
1478 if (!mUsingLiquid) {
1481 if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers) {
1490 string resumable_cache = (!resumable) ?
"False" :
"True";
1503 ss <<
"liquid_load_particles_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1504 <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1505 pythonCommands.push_back(ss.str());
1507 return (mParticlesFromFile = runPythonString(pythonCommands));
1513 cout <<
"MANTA::readGuiding()" << endl;
1516 if (!mUsingGuiding) {
1532 if (!
hasGuiding(fmd, framenr, sourceDomain)) {
1538 ss <<
"fluid_load_vel_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1539 <<
", '" << volume_format <<
"')";
1543 ss <<
"fluid_load_guiding_" << mCurrentID <<
"('" <<
escapePath(directory) <<
"', " << framenr
1544 <<
", '" << volume_format <<
"')";
1546 pythonCommands.push_back(ss.str());
1548 return runPythonString(pythonCommands);
1554 cout <<
"MANTA::bakeData()" << endl;
1562 cacheDirData[0] =
'\0';
1563 cacheDirGuiding[0] =
'\0';
1574 ss <<
"bake_fluid_data_" << mCurrentID <<
"('" <<
escapePath(cacheDirData) <<
"', " << framenr
1575 <<
", '" << volume_format <<
"')";
1576 pythonCommands.push_back(ss.str());
1578 return runPythonString(pythonCommands);
1584 cout <<
"MANTA::bakeNoise()" << endl;
1592 cacheDirNoise[0] =
'\0';
1601 ss <<
"bake_noise_" << mCurrentID <<
"('" <<
escapePath(cacheDirNoise) <<
"', " << framenr
1602 <<
", '" << volume_format <<
"')";
1603 pythonCommands.push_back(ss.str());
1605 return runPythonString(pythonCommands);
1611 cout <<
"MANTA::bakeMesh()" << endl;
1619 cacheDirMesh[0] =
'\0';
1628 ss <<
"bake_mesh_" << mCurrentID <<
"('" <<
escapePath(cacheDirMesh) <<
"', " << framenr <<
", '"
1629 << volume_format <<
"', '" << mesh_format <<
"')";
1630 pythonCommands.push_back(ss.str());
1632 return runPythonString(pythonCommands);
1638 cout <<
"MANTA::bakeParticles()" << endl;
1646 cacheDirParticles[0] =
'\0';
1652 sizeof(cacheDirParticles),
1658 ss <<
"bake_particles_" << mCurrentID <<
"('" <<
escapePath(cacheDirParticles) <<
"', "
1659 << framenr <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1660 pythonCommands.push_back(ss.str());
1662 return runPythonString(pythonCommands);
1668 cout <<
"MANTA::bakeGuiding()" << endl;
1676 cacheDirGuiding[0] =
'\0';
1686 ss <<
"bake_guiding_" << mCurrentID <<
"('" <<
escapePath(cacheDirGuiding) <<
"', " << framenr
1687 <<
", '" << volume_format <<
"', " << resumable_cache <<
")";
1688 pythonCommands.push_back(ss.str());
1690 return runPythonString(pythonCommands);
1695 string tmpString, finalString;
1705 if (mUsingGuiding) {
1713 if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) {
1721 finalString = parseScript(tmpString, fmd);
1722 pythonCommands.push_back(finalString);
1724 return runPythonString(pythonCommands);
1730 cout <<
"MANTA::exportSmokeScript()" << endl;
1734 char cacheDirScript[
FILE_MAX] =
"\0";
1754 string manta_script;
1778 manta_script += header_grids + fluid_alloc +
smoke_alloc;
1798 manta_script += fluid_alloc_guiding;
1801 manta_script += fluid_alloc_obstacle;
1804 manta_script += fluid_alloc_invel;
1807 manta_script += fluid_alloc_outflow;
1819 manta_script += header_import + fluid_file_import + fluid_cache_helper + smoke_load_data;
1821 manta_script += smoke_load_noise;
1824 manta_script += fluid_load_guiding;
1828 manta_script += header_prepost + fluid_pre_step + fluid_post_step;
1831 manta_script += header_steps + smoke_adaptive_step + smoke_step;
1833 manta_script += smoke_step_noise;
1837 manta_script += header_main + smoke_standalone + fluid_standalone;
1840 string final_script = MANTA::parseScript(manta_script, fmd);
1844 myfile.open(cacheDirScript);
1845 myfile << final_script;
1848 cerr <<
"Fluid Error -- Could not export standalone Mantaflow smoke domain script";
1857 cout <<
"MANTA::exportLiquidScript()" << endl;
1861 char cacheDirScript[
FILE_MAX] =
"\0";
1884 string manta_script;
1894 if (drops || bubble || floater || tracer) {
1909 if (drops || bubble || floater || tracer) {
1920 manta_script += header_grids + fluid_alloc +
liquid_alloc;
1924 if (drops || bubble || floater || tracer) {
1928 manta_script += fluid_alloc_guiding;
1931 manta_script += fluid_alloc_obstacle;
1934 manta_script += fluid_alloc_fractions;
1937 manta_script += fluid_alloc_invel;
1940 manta_script += fluid_alloc_outflow;
1953 manta_script += header_import + fluid_file_import + fluid_cache_helper + liquid_load_data;
1955 manta_script += liquid_load_mesh;
1957 if (drops || bubble || floater || tracer) {
1958 manta_script += liquid_load_particles;
1961 manta_script += fluid_load_guiding;
1965 manta_script += header_prepost + fluid_pre_step + fluid_post_step;
1968 manta_script += header_steps + liquid_adaptive_step + liquid_step;
1970 manta_script += liquid_step_mesh;
1972 if (drops || bubble || floater || tracer) {
1973 manta_script += liquid_step_particles;
1977 manta_script += header_main + liquid_standalone + fluid_standalone;
1980 string final_script = MANTA::parseScript(manta_script, fmd);
1984 myfile.open(cacheDirScript);
1985 myfile << final_script;
1988 cerr <<
"Fluid Error -- Could not export standalone Mantaflow liquid domain script";
2003 if ((varName ==
"") || (functionName ==
"")) {
2005 cout <<
"Fluid: Missing Python variable name and/or function name -- name is: " << varName
2006 <<
", function name is: " << functionName << endl;
2011 PyGILState_STATE gilstate = PyGILState_Ensure();
2012 PyObject *var =
nullptr, *func =
nullptr, *returnedValue =
nullptr;
2019 PyGILState_Release(gilstate);
2025 PyGILState_Release(gilstate);
2032 PyGILState_Release(gilstate);
2036 func = PyObject_GetAttrString(var, functionName.c_str());
2041 PyGILState_Release(gilstate);
2046 returnedValue = PyObject_CallObject(func,
nullptr);
2047 if (returnedValue ==
nullptr) {
2054 PyGILState_Release(gilstate);
2055 return (!isAttribute) ? returnedValue : func;
2066 PyGILState_STATE gilstate = PyGILState_Ensure();
2068 PyObject *encoded = PyUnicode_AsUTF8String(inputObject);
2069 char *
result = PyBytes_AsString(encoded);
2074 istringstream
in(
str);
2075 void *dataPointer =
nullptr;
2080 PyGILState_Release(gilstate);
2092 PyGILState_STATE gilstate = PyGILState_Ensure();
2096 double result = PyFloat_AS_DOUBLE(inputObject);
2099 PyGILState_Release(gilstate);
2111 PyGILState_STATE gilstate = PyGILState_Ensure();
2113 long result = PyLong_AsLong(inputObject);
2116 PyGILState_Release(gilstate);
2120template<
class T>
static T *
getPointer(
string pyObjectName,
string pyFunctionName)
2128 cout <<
"MANTA::getFrame()" << endl;
2131 string func =
"frame";
2133 string solver =
"s" + id;
2141 cout <<
"MANTA::getTimestep()" << endl;
2144 string func =
"timestep";
2146 string solver =
"s" + id;
2162 cout <<
"MANTA::adaptTimestep()" << endl;
2168 ss <<
"fluid_adapt_time_step_" << mCurrentID <<
"()";
2169 pythonCommands.push_back(ss.str());
2171 runPythonString(pythonCommands);
2177 cout <<
"MANTA::updatePointers()" << endl;
2196 bool parts = !flush && liquid && (drops | bubble | floater | tracer);
2200 string func =
"getDataPointer";
2201 string funcNodes =
"getNodesDataPointer";
2202 string funcTris =
"getTrisDataPointer";
2205 string s_ext =
"_s" + id;
2206 string pp_ext =
"_pp" + id;
2207 string snd_ext =
"_sp" + id;
2208 string sm_ext =
"_sm" + id;
2209 string mesh_ext =
"_mesh" + id;
2210 string sn_ext =
"_sn" + id;
2212 mFlags = (smoke || liquid) ?
getPointer<int>(
"flags" + s_ext, func) :
nullptr;
2213 mPhiIn = (smoke || liquid) ?
getPointer<float>(
"phiIn" + s_ext, func) :
nullptr;
2214 mPhiStaticIn = (smoke || liquid) ?
getPointer<float>(
"phiSIn" + s_ext, func) :
nullptr;
2215 mVelocityX = (smoke || liquid) ?
getPointer<float>(
"x_vel" + s_ext, func) :
nullptr;
2216 mVelocityY = (smoke || liquid) ?
getPointer<float>(
"y_vel" + s_ext, func) :
nullptr;
2217 mVelocityZ = (smoke || liquid) ?
getPointer<float>(
"z_vel" + s_ext, func) :
nullptr;
2218 mForceX = (smoke || liquid) ?
getPointer<float>(
"x_force" + s_ext, func) :
nullptr;
2219 mForceY = (smoke || liquid) ?
getPointer<float>(
"y_force" + s_ext, func) :
nullptr;
2220 mForceZ = (smoke || liquid) ?
getPointer<float>(
"z_force" + s_ext, func) :
nullptr;
2221 mPressure = (smoke || liquid) ?
getPointer<float>(
"pressure" + s_ext, func) :
nullptr;
2225 mPhiOutStaticIn = (outflow) ?
getPointer<float>(
"phiOutSIn" + s_ext, func) :
nullptr;
2229 mPhiObsStaticIn = (obstacle) ?
getPointer<float>(
"phiObsSIn" + s_ext, func) :
nullptr;
2230 mObVelocityX = (obstacle) ?
getPointer<float>(
"x_obvel" + s_ext, func) :
nullptr;
2231 mObVelocityY = (obstacle) ?
getPointer<float>(
"y_obvel" + s_ext, func) :
nullptr;
2232 mObVelocityZ = (obstacle) ?
getPointer<float>(
"z_obvel" + s_ext, func) :
nullptr;
2233 mNumObstacle = (obstacle) ?
getPointer<float>(
"numObs" + s_ext, func) :
nullptr;
2236 mPhiGuideIn = (guiding) ?
getPointer<float>(
"phiGuideIn" + s_ext, func) :
nullptr;
2237 mGuideVelocityX = (guiding) ?
getPointer<float>(
"x_guidevel" + s_ext, func) :
nullptr;
2238 mGuideVelocityY = (guiding) ?
getPointer<float>(
"y_guidevel" + s_ext, func) :
nullptr;
2239 mGuideVelocityZ = (guiding) ?
getPointer<float>(
"z_guidevel" + s_ext, func) :
nullptr;
2251 mEmissionIn = (smoke) ?
getPointer<float>(
"emissionIn" + s_ext, func) :
nullptr;
2308 mFlipFromFile =
false;
2309 mMeshFromFile =
false;
2310 mParticlesFromFile =
false;
2311 mSmokeFromFile =
false;
2312 mNoiseFromFile =
false;
2334 cout <<
"Fluid: Has Data: " << exists << endl;
2361 cout <<
"Fluid: Has Noise: " << exists << endl;
2379 cout <<
"Fluid: Has Mesh: " << exists << endl;
2406 cout <<
"Fluid: Has Particles: " << exists << endl;
2417 bool exists =
BLI_exists(getFile(fmd, subdirectory, filename, extension, framenr).c_str());
2422 exists =
BLI_exists(getFile(fmd, subdirectory, filename, extension, framenr).c_str());
2426 cout <<
"Fluid: Has Guiding: " << exists << endl;
2440string MANTA::getFile(
2441 FluidModifierData *fmd,
string subdirectory,
string fname,
string extension,
int framenr)
2444 string path = getDirectory(fmd, subdirectory);
2445 string filename = fname +
"_####" + extension;
2446 BLI_path_join(targetFile,
sizeof(targetFile), path.c_str(), filename.c_str());
File and directory operations.
void * BLI_gzopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_dir_create_recursive(const char *dirname) ATTR_NONNULL()
bool BLI_path_make_safe(char *path) ATTR_NONNULL(1)
#define BLI_path_join(...)
bool BLI_path_frame(char *path, size_t path_maxncpy, int frame, int digits) ATTR_NONNULL(1)
#define FLUID_DOMAIN_LIQUID_SCRIPT
#define FLUID_NAME_EMISSION
#define FLUID_NAME_TRAPPEDAIR_PARTICLES
#define FLUID_CACHE_VERSION
#define FLUID_NAME_FUEL_NOISE
#define FLUID_NAME_COLORG_NOISE
#define FLUID_NAME_COLORB_NOISE
#define FLUID_NAME_FLAGS_MESH
#define FLUID_DOMAIN_DIR_DATA
#define FLUID_NAME_PHIPARTS_MESH
#define FLUID_DOMAIN_DIR_PARTICLES
#define FLUID_NAME_TMPFLAGS
@ FLUID_DOMAIN_BORDER_BOTTOM
@ FLUID_DOMAIN_BORDER_LEFT
@ FLUID_DOMAIN_BORDER_RIGHT
@ FLUID_DOMAIN_BORDER_FRONT
@ FLUID_DOMAIN_BORDER_TOP
@ FLUID_DOMAIN_BORDER_BACK
@ FLUID_DOMAIN_MESH_IMPROVED
#define FLUID_NAME_PHIOBS_PARTICLES
#define FLUID_NAME_FORCES
#define FLUID_NAME_PHIIN_NOISE
#define FLUID_NAME_WAVECREST_PARTICLES
#define FLUID_NAME_VELOCITY_PARTICLES
#define FLUID_NAME_EMISSIONIN
#define FLUID_NAME_PHIGUIDEIN
#define FLUID_NAME_PLIFE_PARTICLES
#define FLUID_NAME_PFORCE_PARTICLES
#define FLUID_NAME_PHITMP
#define FLUID_NAME_VELOCITYOLD
#define FLUID_NAME_PHIOBSSIN
#define FLUID_NAME_PP_PARTICLES
#define FLUID_NAME_KINETICENERGY_PARTICLES
#define FLUID_NAME_FORCE_Y
#define FLUID_NAME_PINDEX
#define FLUID_NAME_FUELIN
#define FLUID_NAME_PARTICLES
#define FLUID_DOMAIN_EXTENSION_BINOBJ
#define FLUID_NAME_FORCE_Z
#define FLUID_DOMAIN_SMOKE_SCRIPT
#define FLUID_NAME_GUIDEVEL_Z
#define FLUID_NAME_PVEL_PARTICLES
@ SNDPARTICLE_BOUNDARY_DELETE
@ SNDPARTICLE_BOUNDARY_PUSHOUT
#define FLUID_NAME_GUIDEVEL_X
#define FLUID_NAME_TEXTURE_U
#define FLUID_DOMAIN_DIR_MESH
#define FLUID_DOMAIN_DIR_GUIDE
#define FLUID_DOMAIN_DIR_SCRIPT
#define FLUID_NAME_PARTSVEL_PARTICLES
#define FLUID_NAME_TMPIN_NOISE
#define FLUID_NAME_OBVEL_X
#define FLUID_NAME_PHIOBS
#define FLUID_NAME_CONFIG
#define FLUID_NAME_COLORR_NOISE
#define FLUID_DOMAIN_EXTENSION_OPENVDB
#define FLUID_NAME_GPI_MESH
#define FLUID_NAME_VELOCITYZ
#define FLUID_NAME_GUIDEVELC
#define FLUID_NAME_VELOCITYTMP
#define FLUID_NAME_VELOCITYY
#define FLUID_NAME_PINDEX_MESH
#define FLUID_NAME_PHIOUT_PARTICLES
#define FLUID_NAME_CURVATURE
#define FLUID_NAME_PHISIN
@ FLUID_DOMAIN_TYPE_LIQUID
#define FLUID_NAME_VELOCITY_MESH
#define FLUID_DOMAIN_EXTENSION_OBJ
#define FLUID_NAME_INVEL_Z
#define FLUID_NAME_INVELC
#define FLUID_NAME_FLAGS_NOISE
#define FLUID_NAME_PARTSLIFE_PARTICLES
#define FLUID_NAME_COLORR
#define FLUID_NAME_TEXTURE_U2
#define FLUID_NAME_PHIOUT
#define FLUID_NAME_TEXTURE_V2
#define FLUID_NAME_EMISSIONIN_NOISE
#define FLUID_NAME_GUIDEVEL_Y
#define FLUID_NAME_TEXTURE_W2
#define FLUID_NAME_DENSITY_NOISE
@ VDB_PRECISION_MINI_FLOAT
@ VDB_PRECISION_FULL_FLOAT
@ VDB_PRECISION_HALF_FLOAT
#define FLUID_NAME_PHIOUTIN
#define FLUID_NAME_NUMOBS
#define FLUID_NAME_COLORG
#define FLUID_NAME_PHIOUTSIN
#define FLUID_NAME_GUIDEVEL
#define FLUID_NAME_VELOCITYPARTS
#define FLUID_DOMAIN_DIR_CONFIG
#define FLUID_NAME_PHIOBS_NOISE
#define FLUID_NAME_INVEL_Y
#define FLUID_NAME_SHADOW
#define FLUID_NAME_PARTSVELOCITY
#define FLUID_NAME_OBVEL_Y
#define FLUID_NAME_VELOCITYVEC_MESH
#define FLUID_NAME_COLORB
#define FLUID_NAME_OBVELC
#define FLUID_NAME_COLORGIN
#define FLUID_NAME_VELOCITY
#define FLUID_NAME_PHIOBSIN
#define FLUID_NAME_PHI_PARTICLES
#define FLUID_NAME_FORCE_X
#define FLUID_NAME_NEIGHBORRATIO_PARTICLES
#define FLUID_NAME_PARTS_PARTICLES
#define FLUID_NAME_COLORBIN
@ FLUID_DOMAIN_METHOD_APIC
#define FLUID_NAME_GUIDING
#define FLUID_NAME_DENSITY
#define FLUID_NAME_PARTSFORCE_PARTICLES
#define FLUID_NAME_VELOCITY_GUIDE
#define FLUID_DOMAIN_EXTENSION_UNI
#define FLUID_NAME_TEMPERATUREIN
#define FLUID_NAME_INVEL_X
#define FLUID_NAME_REACTIN
struct FluidDomainSettings FluidDomainSettings
#define FLUID_NAME_PRESSURE
#define FLUID_NAME_MAPWEIGHTS
#define FLUID_NAME_FLAME_NOISE
@ FLUID_DOMAIN_ACTIVE_COLORS
@ FLUID_DOMAIN_ACTIVE_FIRE
@ FLUID_DOMAIN_ACTIVE_INVEL
@ FLUID_DOMAIN_ACTIVE_GUIDE
@ FLUID_DOMAIN_ACTIVE_OUTFLOW
@ FLUID_DOMAIN_ACTIVE_HEAT
@ FLUID_DOMAIN_ACTIVE_OBSTACLE
#define FLUID_NAME_PHIOUT_NOISE
#define FLUID_NAME_VELOCITY_NOISE
#define FLUID_NAME_TEXTURE_W
#define FLUID_NAME_PP_MESH
@ FLUID_DOMAIN_FILE_BIN_OBJECT
@ FLUID_DOMAIN_FILE_OBJECT
@ FLUID_DOMAIN_FILE_OPENVDB
#define FLUID_DOMAIN_DIR_NOISE
#define FLUID_NAME_OBVEL_Z
@ FLUID_DOMAIN_DELETE_IN_OBSTACLE
@ FLUID_DOMAIN_USE_RESUMABLE_CACHE
@ FLUID_DOMAIN_USE_DISSOLVE_LOG
@ FLUID_DOMAIN_USE_DIFFUSION
@ FLUID_DOMAIN_USE_ADAPTIVE_TIME
@ FLUID_DOMAIN_USE_VISCOSITY
@ FLUID_DOMAIN_USE_SPEED_VECTORS
@ FLUID_DOMAIN_USE_FRACTIONS
@ FLUID_DOMAIN_USE_DISSOLVE
#define FLUID_NAME_PHIPARTS
#define FLUID_NAME_NUMGUIDES
#define FLUID_NAME_HEATIN
#define FLUID_NAME_FLAGS_PARTICLES
#define FLUID_NAME_TEMPERATURE
#define FLUID_NAME_PHI_MESH
#define FLUID_NAME_FRACTIONS
#define FLUID_NAME_REACT_NOISE
#define FLUID_NAME_TEXTURE_V
#define FLUID_NAME_COLORRIN
@ FLUID_DOMAIN_PARTICLE_SPRAY
@ FLUID_DOMAIN_PARTICLE_FOAM
@ FLUID_DOMAIN_PARTICLE_TRACER
@ FLUID_DOMAIN_PARTICLE_BUBBLE
#define FLUID_NAME_ENERGY
#define FLUID_NAME_VELOCITYX
#define FLUID_NAME_DENSITYIN
#define FLUID_NAME_NORMAL_PARTICLES
#define FLUID_NAME_WEIGHTGUIDE
#define FLUID_DOMAIN_EXTENSION_RAW
static string getBooleanString(int value)
static PyObject * callPythonFunction(string varName, string functionName, bool isAttribute=false)
static string getCacheFileEnding(char cache_format)
static PyObject * manta_python_main_module_create(const char *filename)
static PyObject * manta_main_module
static T * getPointer(string pyObjectName, string pyFunctionName)
static string escapePath(string const &s)
static void manta_python_main_module_restore(PyObject *main_mod)
static void * pyObjectToPointer(PyObject *inputObject)
static void manta_python_main_module_clear()
static void manta_python_main_module_backup(PyObject **r_main_mod)
static PyObject * manta_python_main_module_ensure()
static void manta_python_main_module_activate(PyObject *mod_main)
static double pyObjectToDouble(PyObject *inputObject)
static long pyObjectToLong(PyObject *inputObject)
const std::string fluid_with_outflow
const std::string fluid_variables_noise
const std::string fluid_with_fractions
const std::string fluid_solver_viscosity
const std::string fluid_variables_particles
const std::string fluid_with_invel
const std::string fluid_solver_particles
const std::string fluid_solver_mesh
const std::string manta_import
const std::string manta_debuglevel
const std::string fluid_with_sndparts
const std::string fluid_variables
const std::string fluid_solver_noise
const std::string fluid_variables_viscosity
const std::string fluid_time_stepping
const std::string fluid_solver
const std::string fluid_solver_guiding
const std::string fluid_variables_guiding
const std::string fluid_variables_mesh
const std::string fluid_with_obstacle
static const char * to_string(const Interpolation &interp)
const std::string liquid_alloc_viscosity
const std::string liquid_variables
const std::string liquid_variables_particles
const std::string liquid_alloc_particles
const std::string liquid_alloc
const std::string liquid_alloc_curvature
const std::string liquid_alloc_mesh
const std::string liquid_init_phi
BLI_INLINE std::string & endl()
static float noise(int n)
const std::string smoke_alloc_noise
const std::string smoke_alloc_heat
const std::string smoke_alloc_colors
const std::string smoke_alloc_fire_noise
const std::string smoke_with_colors
const std::string smoke_with_fire
const std::string smoke_with_heat
const std::string smoke_variables
const std::string smoke_variables_noise
const std::string smoke_alloc_colors_noise
const std::string smoke_init_colors_noise
const std::string smoke_init_colors
const std::string smoke_wavelet_noise
const std::string smoke_alloc_fire
const std::string smoke_alloc
float sndparticle_tau_min_wc
int sndparticle_update_radius
char sndparticle_boundary
float fractions_threshold
char cache_particle_format
float particle_randomness
int sndparticle_potential_radius
float mesh_particle_radius
float flame_smoke_color[3]
float sndparticle_tau_max_wc
float sndparticle_tau_max_ta
float sndparticle_tau_min_ta
float particle_band_width
float sndparticle_tau_min_k
char cache_directory[1024]
struct Object * guide_parent
float sndparticle_tau_max_k
struct FluidDomainSettings * domain
bool exportSmokeScript(struct FluidModifierData *fmd)
bool bakeNoise(FluidModifierData *fmd, int framenr)
bool writeNoise(FluidModifierData *fmd, int framenr)
bool initFireHigh(struct FluidModifierData *fmd=nullptr)
bool hasNoise(FluidModifierData *fmd, int framenr)
bool exportLiquidScript(struct FluidModifierData *fmd)
bool readData(FluidModifierData *fmd, int framenr, bool resumable)
bool initOutflow(FluidModifierData *fmd=nullptr)
bool writeConfiguration(FluidModifierData *fmd, int framenr)
bool initFire(struct FluidModifierData *fmd=nullptr)
bool writeData(FluidModifierData *fmd, int framenr)
bool needsRealloc(FluidModifierData *fmd)
bool readParticles(FluidModifierData *fmd, int framenr, bool resumable)
bool readMesh(FluidModifierData *fmd, int framenr)
bool readGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
bool initLiquidViscosity(FluidModifierData *fmd=nullptr)
bool bakeMesh(FluidModifierData *fmd, int framenr)
bool initLiquid(FluidModifierData *fmd=nullptr)
bool initFractions(FluidModifierData *fmd=nullptr)
bool initLiquidMesh(FluidModifierData *fmd=nullptr)
bool hasMesh(FluidModifierData *fmd, int framenr)
bool initGuiding(FluidModifierData *fmd=nullptr)
bool readConfiguration(FluidModifierData *fmd, int framenr)
bool bakeGuiding(FluidModifierData *fmd, int framenr)
static atomic< int > solverID
bool hasParticles(FluidModifierData *fmd, int framenr)
bool initColorsHigh(struct FluidModifierData *fmd=nullptr)
bool initObstacle(FluidModifierData *fmd=nullptr)
bool initColors(struct FluidModifierData *fmd=nullptr)
bool readNoise(FluidModifierData *fmd, int framenr, bool resumable)
bool initSndParts(FluidModifierData *fmd=nullptr)
bool initCurvature(FluidModifierData *fmd=nullptr)
bool hasGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
bool initHeat(struct FluidModifierData *fmd=nullptr)
bool bakeParticles(FluidModifierData *fmd, int framenr)
MANTA(int *res, struct FluidModifierData *fmd)
bool bakeData(FluidModifierData *fmd, int framenr)
bool initInVelocity(FluidModifierData *fmd=nullptr)
void updatePointers(FluidModifierData *fmd, bool flush=false)
bool hasData(FluidModifierData *fmd, int framenr)
bool updateVariables(FluidModifierData *fmd)
bool hasConfig(FluidModifierData *fmd, int framenr)
bool initLiquidSndParts(FluidModifierData *fmd=nullptr)