Blender  V3.3
MANTA_main.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. All rights reserved. */
3 
8 #include <fstream>
9 #include <iomanip>
10 #include <iostream>
11 #include <sstream>
12 #include <zlib.h>
13 
14 #include "MANTA_main.h"
15 #include "Python.h"
16 #include "fluid_script.h"
17 #include "liquid_script.h"
18 #include "manta.h"
19 #include "smoke_script.h"
20 
21 #include "BLI_fileops.h"
22 #include "BLI_path_util.h"
23 #include "BLI_utildefines.h"
24 
25 #include "DNA_fluid_types.h"
26 #include "DNA_modifier_types.h"
27 #include "DNA_scene_types.h"
28 
29 #include "MEM_guardedalloc.h"
30 
31 using std::cerr;
32 using std::cout;
33 using std::endl;
34 using std::ifstream;
35 using std::istringstream;
36 using std::ofstream;
37 using std::ostringstream;
38 using std::to_string;
39 
40 atomic<int> MANTA::solverID(0);
41 int MANTA::with_debug(0);
42 
44  : mCurrentID(++solverID), mMaxRes(fmd->domain->maxres)
45 {
46  if (with_debug)
47  cout << "FLUID: " << mCurrentID << " with res(" << res[0] << ", " << res[1] << ", " << res[2]
48  << ")" << endl;
49 
50  FluidDomainSettings *fds = fmd->domain;
51  fds->fluid = this;
52 
53  mUsingLiquid = (fds->type == FLUID_DOMAIN_TYPE_LIQUID);
54  mUsingSmoke = (fds->type == FLUID_DOMAIN_TYPE_GAS);
55  mUsingNoise = (fds->flags & FLUID_DOMAIN_USE_NOISE) && mUsingSmoke;
56  mUsingFractions = (fds->flags & FLUID_DOMAIN_USE_FRACTIONS) && mUsingLiquid;
57  mUsingMesh = (fds->flags & FLUID_DOMAIN_USE_MESH) && mUsingLiquid;
58  mUsingDiffusion = (fds->flags & FLUID_DOMAIN_USE_DIFFUSION) && mUsingLiquid;
59  mUsingViscosity = (fds->flags & FLUID_DOMAIN_USE_VISCOSITY) && mUsingLiquid;
60  mUsingMVel = (fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS) && mUsingLiquid;
61  mUsingGuiding = (fds->flags & FLUID_DOMAIN_USE_GUIDE);
62  mUsingDrops = (fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && mUsingLiquid;
63  mUsingBubbles = (fds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) && mUsingLiquid;
64  mUsingFloats = (fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) && mUsingLiquid;
65  mUsingTracers = (fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) && mUsingLiquid;
66 
67  mUsingHeat = (fds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT) && mUsingSmoke;
68  mUsingFire = (fds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE) && mUsingSmoke;
69  mUsingColors = (fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) && mUsingSmoke;
70  mUsingObstacle = (fds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE);
71  mUsingInvel = (fds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL);
72  mUsingOutflow = (fds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW);
73 
74  /* Simulation constants */
75  mResX = res[0]; /* Current size of domain (will adjust with adaptive domain). */
76  mResY = res[1];
77  mResZ = res[2];
78  mTotalCells = mResX * mResY * mResZ;
79  mResGuiding = fds->res;
80 
81  /* Smoke low res grids. */
82  mDensity = nullptr;
83  mShadow = nullptr;
84  mHeat = nullptr;
85  mVelocityX = nullptr;
86  mVelocityY = nullptr;
87  mVelocityZ = nullptr;
88  mForceX = nullptr;
89  mForceY = nullptr;
90  mForceZ = nullptr;
91  mFlame = nullptr;
92  mFuel = nullptr;
93  mReact = nullptr;
94  mColorR = nullptr;
95  mColorG = nullptr;
96  mColorB = nullptr;
97  mFlags = nullptr;
98  mDensityIn = nullptr;
99  mHeatIn = nullptr;
100  mColorRIn = nullptr;
101  mColorGIn = nullptr;
102  mColorBIn = nullptr;
103  mFuelIn = nullptr;
104  mReactIn = nullptr;
105  mEmissionIn = nullptr;
106  mPressure = nullptr;
107 
108  /* Smoke high res grids. */
109  mDensityHigh = nullptr;
110  mFlameHigh = nullptr;
111  mFuelHigh = nullptr;
112  mReactHigh = nullptr;
113  mColorRHigh = nullptr;
114  mColorGHigh = nullptr;
115  mColorBHigh = nullptr;
116  mTextureU = nullptr;
117  mTextureV = nullptr;
118  mTextureW = nullptr;
119  mTextureU2 = nullptr;
120  mTextureV2 = nullptr;
121  mTextureW2 = nullptr;
122 
123  /* Fluid low res grids. */
124  mPhiIn = nullptr;
125  mPhiStaticIn = nullptr;
126  mPhiOutIn = nullptr;
127  mPhiOutStaticIn = nullptr;
128  mPhi = nullptr;
129 
130  /* Mesh. */
131  mMeshNodes = nullptr;
132  mMeshTriangles = nullptr;
133  mMeshVelocities = nullptr;
134 
135  /* Fluid obstacle. */
136  mPhiObsIn = nullptr;
137  mPhiObsStaticIn = nullptr;
138  mNumObstacle = nullptr;
139  mObVelocityX = nullptr;
140  mObVelocityY = nullptr;
141  mObVelocityZ = nullptr;
142 
143  /* Fluid guiding. */
144  mPhiGuideIn = nullptr;
145  mNumGuide = nullptr;
146  mGuideVelocityX = nullptr;
147  mGuideVelocityY = nullptr;
148  mGuideVelocityZ = nullptr;
149 
150  /* Fluid initial velocity. */
151  mInVelocityX = nullptr;
152  mInVelocityY = nullptr;
153  mInVelocityZ = nullptr;
154 
155  /* Secondary particles. */
156  mFlipParticleData = nullptr;
157  mFlipParticleVelocity = nullptr;
158  mParticleData = nullptr;
159  mParticleVelocity = nullptr;
160  mParticleLife = nullptr;
161 
162  /* Cache read success indicators. */
163  mFlipFromFile = false;
164  mMeshFromFile = false;
165  mParticlesFromFile = false;
166 
167  /* Setup Mantaflow in Python. */
168  initializeMantaflow();
169 
170  /* Initializa RNA map with values that Python will need. */
171  initializeRNAMap(fmd);
172 
173  bool initSuccess = true;
174  /* Initialize Mantaflow variables in Python. */
175  /* Liquid. */
176  if (mUsingLiquid) {
177  initSuccess &= initDomain();
178  initSuccess &= initLiquid();
179  if (mUsingObstacle)
180  initSuccess &= initObstacle();
181  if (mUsingInvel)
182  initSuccess &= initInVelocity();
183  if (mUsingOutflow)
184  initSuccess &= initOutflow();
185 
186  if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) {
187  mUpresParticle = fds->particle_scale;
188  mResXParticle = mUpresParticle * mResX;
189  mResYParticle = mUpresParticle * mResY;
190  mResZParticle = mUpresParticle * mResZ;
191  mTotalCellsParticles = mResXParticle * mResYParticle * mResZParticle;
192 
193  initSuccess &= initSndParts();
194  initSuccess &= initLiquidSndParts();
195  }
196 
197  if (mUsingMesh) {
198  mUpresMesh = fds->mesh_scale;
199  mResXMesh = mUpresMesh * mResX;
200  mResYMesh = mUpresMesh * mResY;
201  mResZMesh = mUpresMesh * mResZ;
202  mTotalCellsMesh = mResXMesh * mResYMesh * mResZMesh;
203 
204  /* Initialize Mantaflow variables in Python. */
205  initSuccess &= initMesh();
206  initSuccess &= initLiquidMesh();
207  }
208 
209  if (mUsingViscosity) {
210  initSuccess &= initLiquidViscosity();
211  }
212 
213  if (mUsingDiffusion) {
214  initSuccess &= initCurvature();
215  }
216 
217  if (mUsingGuiding) {
218  mResGuiding = (fds->guide_parent) ? fds->guide_res : fds->res;
219  initSuccess &= initGuiding();
220  }
221  if (mUsingFractions) {
222  initSuccess &= initFractions();
223  }
224  }
225 
226  /* Smoke. */
227  if (mUsingSmoke) {
228  initSuccess &= initDomain();
229  initSuccess &= initSmoke();
230  if (mUsingHeat)
231  initSuccess &= initHeat();
232  if (mUsingFire)
233  initSuccess &= initFire();
234  if (mUsingColors)
235  initSuccess &= initColors();
236  if (mUsingObstacle)
237  initSuccess &= initObstacle();
238  if (mUsingInvel)
239  initSuccess &= initInVelocity();
240  if (mUsingOutflow)
241  initSuccess &= initOutflow();
242 
243  if (mUsingGuiding) {
244  mResGuiding = (fds->guide_parent) ? fds->guide_res : fds->res;
245  initSuccess &= initGuiding();
246  }
247 
248  if (mUsingNoise) {
249  int amplify = fds->noise_scale;
250  mResXNoise = amplify * mResX;
251  mResYNoise = amplify * mResY;
252  mResZNoise = amplify * mResZ;
253  mTotalCellsHigh = mResXNoise * mResYNoise * mResZNoise;
254 
255  /* Initialize Mantaflow variables in Python. */
256  initSuccess &= initNoise();
257  initSuccess &= initSmokeNoise();
258  if (mUsingFire)
259  initSuccess &= initFireHigh();
260  if (mUsingColors)
261  initSuccess &= initColorsHigh();
262  }
263  }
264  /* All requested initializations must not fail in constructor. */
265  BLI_assert(initSuccess);
266  (void)initSuccess; /* Ignored in release. */
267 
268  updatePointers(fmd);
269 }
270 
271 bool MANTA::initDomain(FluidModifierData *fmd)
272 {
273  /* Vector will hold all python commands that are to be executed. */
274  vector<string> pythonCommands;
275 
276  /* Set manta debug level first. */
277  pythonCommands.push_back(manta_import + manta_debuglevel);
278 
279  ostringstream ss;
280  ss << "set_manta_debuglevel(" << with_debug << ")";
281  pythonCommands.push_back(ss.str());
282 
283  /* Now init basic fluid domain. */
289  string finalString = parseScript(tmpString, fmd);
290  pythonCommands.push_back(finalString);
291  return runPythonString(pythonCommands);
292 }
293 
294 bool MANTA::initNoise(FluidModifierData *fmd)
295 {
296  vector<string> pythonCommands;
297  string tmpString = fluid_variables_noise + fluid_solver_noise;
298  string finalString = parseScript(tmpString, fmd);
299  pythonCommands.push_back(finalString);
300 
301  return runPythonString(pythonCommands);
302 }
303 
304 bool MANTA::initSmoke(FluidModifierData *fmd)
305 {
306  vector<string> pythonCommands;
309  string finalString = parseScript(tmpString, fmd);
310  pythonCommands.push_back(finalString);
311 
312  return runPythonString(pythonCommands);
313 }
314 
315 bool MANTA::initSmokeNoise(FluidModifierData *fmd)
316 {
317  vector<string> pythonCommands;
320  string finalString = parseScript(tmpString, fmd);
321  pythonCommands.push_back(finalString);
322 
323  mUsingNoise = true;
324  return runPythonString(pythonCommands);
325 }
326 
328 {
329  if (!mHeat) {
330  vector<string> pythonCommands;
331  string tmpString = smoke_alloc_heat + smoke_with_heat;
332  string finalString = parseScript(tmpString, fmd);
333  pythonCommands.push_back(finalString);
334 
335  mUsingHeat = true;
336  return runPythonString(pythonCommands);
337  }
338  return false;
339 }
340 
342 {
343  if (!mFuel) {
344  vector<string> pythonCommands;
345  string tmpString = smoke_alloc_fire + smoke_with_fire;
346  string finalString = parseScript(tmpString, fmd);
347  pythonCommands.push_back(finalString);
348 
349  mUsingFire = true;
350  return runPythonString(pythonCommands);
351  }
352  return false;
353 }
354 
356 {
357  if (!mFuelHigh) {
358  vector<string> pythonCommands;
359  string tmpString = smoke_alloc_fire_noise + smoke_with_fire;
360  string finalString = parseScript(tmpString, fmd);
361  pythonCommands.push_back(finalString);
362 
363  mUsingFire = true;
364  return runPythonString(pythonCommands);
365  }
366  return false;
367 }
368 
370 {
371  if (!mColorR) {
372  vector<string> pythonCommands;
374  string finalString = parseScript(tmpString, fmd);
375  pythonCommands.push_back(finalString);
376 
377  mUsingColors = true;
378  return runPythonString(pythonCommands);
379  }
380  return false;
381 }
382 
384 {
385  if (!mColorRHigh) {
386  vector<string> pythonCommands;
388  string finalString = parseScript(tmpString, fmd);
389  pythonCommands.push_back(finalString);
390 
391  mUsingColors = true;
392  return runPythonString(pythonCommands);
393  }
394  return false;
395 }
396 
398 {
399  if (!mPhiIn) {
400  vector<string> pythonCommands;
403  string finalString = parseScript(tmpString, fmd);
404  pythonCommands.push_back(finalString);
405 
406  mUsingLiquid = true;
407  return runPythonString(pythonCommands);
408  }
409  return false;
410 }
411 
412 bool MANTA::initMesh(FluidModifierData *fmd)
413 {
414  vector<string> pythonCommands;
416  string finalString = parseScript(tmpString, fmd);
417  pythonCommands.push_back(finalString);
418 
419  mUsingMesh = true;
420  return runPythonString(pythonCommands);
421 }
422 
424 {
425  vector<string> pythonCommands;
426  string tmpString = liquid_alloc_mesh + liquid_step_mesh + liquid_save_mesh;
427  string finalString = parseScript(tmpString, fmd);
428  pythonCommands.push_back(finalString);
429 
430  mUsingMesh = true;
431  return runPythonString(pythonCommands);
432 }
433 
435 {
436  vector<string> pythonCommands;
438  string finalString = parseScript(tmpString, fmd);
439  pythonCommands.push_back(finalString);
440 
441  mUsingViscosity = true;
442  return runPythonString(pythonCommands);
443 }
444 
446 {
447  std::vector<std::string> pythonCommands;
448  std::string finalString = parseScript(liquid_alloc_curvature, fmd);
449  pythonCommands.push_back(finalString);
450 
451  mUsingDiffusion = true;
452  return runPythonString(pythonCommands);
453 }
454 
456 {
457  if (!mPhiObsIn) {
458  vector<string> pythonCommands;
459  string tmpString = fluid_alloc_obstacle + fluid_with_obstacle;
460  string finalString = parseScript(tmpString, fmd);
461  pythonCommands.push_back(finalString);
462 
463  return (mUsingObstacle = runPythonString(pythonCommands));
464  }
465  return false;
466 }
467 
469 {
470  if (!mPhiGuideIn) {
471  vector<string> pythonCommands;
474  string finalString = parseScript(tmpString, fmd);
475  pythonCommands.push_back(finalString);
476 
477  return (mUsingGuiding = runPythonString(pythonCommands));
478  }
479  return false;
480 }
481 
483 {
484  vector<string> pythonCommands;
485  string tmpString = fluid_alloc_fractions + fluid_with_fractions;
486  string finalString = parseScript(tmpString, fmd);
487  pythonCommands.push_back(finalString);
488 
489  return (mUsingFractions = runPythonString(pythonCommands));
490 }
491 
493 {
494  if (!mInVelocityX) {
495  vector<string> pythonCommands;
496  string tmpString = fluid_alloc_invel + fluid_with_invel;
497  string finalString = parseScript(tmpString, fmd);
498  pythonCommands.push_back(finalString);
499 
500  return (mUsingInvel = runPythonString(pythonCommands));
501  }
502  return false;
503 }
504 
506 {
507  if (!mPhiOutIn) {
508  vector<string> pythonCommands;
509  string tmpString = fluid_alloc_outflow + fluid_with_outflow;
510  string finalString = parseScript(tmpString, fmd);
511  pythonCommands.push_back(finalString);
512 
513  return (mUsingOutflow = runPythonString(pythonCommands));
514  }
515  return false;
516 }
517 
519 {
520  vector<string> pythonCommands;
522  string finalString = parseScript(tmpString, fmd);
523  pythonCommands.push_back(finalString);
524 
525  return runPythonString(pythonCommands);
526 }
527 
529 {
530  if (!mParticleData) {
531  vector<string> pythonCommands;
535  string finalString = parseScript(tmpString, fmd);
536  pythonCommands.push_back(finalString);
537 
538  return runPythonString(pythonCommands);
539  }
540  return false;
541 }
542 
544 {
545  if (with_debug)
546  cout << "~FLUID: " << mCurrentID << " with res(" << mResX << ", " << mResY << ", " << mResZ
547  << ")" << endl;
548 
549  /* Destruction string for Python. */
550  string tmpString = "";
551  vector<string> pythonCommands;
552  bool result = false;
553 
554  tmpString += manta_import;
555  tmpString += fluid_delete_all;
556 
557  /* Initializa RNA map with values that Python will need. */
558  initializeRNAMap();
559 
560  /* Leave out fmd argument in parseScript since only looking up IDs. */
561  string finalString = parseScript(tmpString);
562  pythonCommands.push_back(finalString);
563  result = runPythonString(pythonCommands);
564 
565  /* WARNING: this causes crash on exit in the `cycles_volume_cpu/smoke_color` test,
566  * freeing a single modifier ends up clearing the shared module.
567  * For this to be handled properly there would need to be a initialize/free
568  * function for global data. */
569 #if 0
570  MANTA::terminateMantaflow();
571 #endif
572 
575 }
576 
583 static PyObject *manta_python_main_module_create(const char *filename)
584 {
585  PyObject *builtins = PyEval_GetBuiltins();
586  PyObject *mod_main = PyModule_New("__main__");
587  PyModule_AddStringConstant(mod_main, "__name__", "__main__");
588  if (filename) {
589  /* __file__ mainly for nice UI'ness
590  * NOTE: this won't map to a real file when executing text-blocks and buttons. */
591  PyModule_AddObject(mod_main, "__file__", PyUnicode_InternFromString(filename));
592  }
593  PyModule_AddObject(mod_main, "__builtins__", builtins);
594  Py_INCREF(builtins); /* AddObject steals a reference */
595  return mod_main;
596 }
597 
598 static void manta_python_main_module_activate(PyObject *mod_main)
599 {
600  PyObject *modules = PyImport_GetModuleDict();
601  PyObject *main_mod_cmp = PyDict_GetItemString(modules, "__main__");
602  if (mod_main == main_mod_cmp) {
603  return;
604  }
605  /* NOTE: we could remove the reference to `mod_main` here, but as it's know to be removed
606  * accept that there is temporarily an extra reference. */
607  PyDict_SetItemString(modules, "__main__", mod_main);
608 }
609 
610 static void manta_python_main_module_backup(PyObject **r_main_mod)
611 {
612  PyObject *modules = PyImport_GetModuleDict();
613  *r_main_mod = PyDict_GetItemString(modules, "__main__");
614  Py_XINCREF(*r_main_mod); /* don't free */
615 }
616 
617 static void manta_python_main_module_restore(PyObject *main_mod)
618 {
619  PyObject *modules = PyImport_GetModuleDict();
620  PyDict_SetItemString(modules, "__main__", main_mod);
621  Py_XDECREF(main_mod);
622 }
623 
631 static PyObject *manta_main_module = nullptr;
632 
634 {
635  if (manta_main_module) {
636  Py_DECREF(manta_main_module);
637  manta_main_module = nullptr;
638  }
639 }
640 
642 {
643  if (!manta_main_module) {
644  manta_main_module = manta_python_main_module_create("<manta_namespace>");
645  }
646  return manta_main_module;
647 }
648 
649 bool MANTA::runPythonString(vector<string> commands)
650 {
651  bool success = true;
652  PyGILState_STATE gilstate = PyGILState_Ensure();
653 
654  /* Temporarily set `sys.modules["__main__"]` as some Python modules expect this. */
655  PyObject *main_mod_backup;
656  manta_python_main_module_backup(&main_mod_backup);
657 
658  /* If we never want to run this when the module isn't initialize,
659  * assign with `manta_python_main_module_ensure()`. */
660  BLI_assert(manta_main_module != nullptr);
662 
663  for (vector<string>::iterator it = commands.begin(); it != commands.end(); ++it) {
664  string command = *it;
665 
666  PyObject *globals_dict = PyModule_GetDict(manta_main_module);
667  PyObject *return_value = PyRun_String(
668  command.c_str(), Py_file_input, globals_dict, globals_dict);
669 
670  if (return_value == nullptr) {
671  success = false;
672  if (PyErr_Occurred()) {
673  PyErr_Print();
674  }
675  }
676  else {
677  Py_DECREF(return_value);
678  }
679  }
680 
681  manta_python_main_module_restore(main_mod_backup);
682 
683  PyGILState_Release(gilstate);
684 
685  BLI_assert(success);
686  return success;
687 }
688 
689 void MANTA::initializeMantaflow()
690 {
691  if (with_debug)
692  cout << "Fluid: Initializing Mantaflow framework" << endl;
693 
694  string filename = "manta_scene_" + to_string(mCurrentID) + ".py";
696 
697  /* Initialize extension classes and wrappers. */
698  srand(0);
699  PyGILState_STATE gilstate = PyGILState_Ensure();
700 
702  PyObject *globals_dict = PyModule_GetDict(manta_main_module);
703  Pb::setup(false, filename, fill, globals_dict); /* Namespace from Mantaflow (registry). */
704  PyGILState_Release(gilstate);
705 }
706 
707 void MANTA::terminateMantaflow()
708 {
709  if (with_debug)
710  cout << "Fluid: Releasing Mantaflow framework" << endl;
711 
712  PyGILState_STATE gilstate = PyGILState_Ensure();
713  Pb::finalize(false); /* Namespace from Mantaflow (registry). */
715  PyGILState_Release(gilstate);
716 }
717 
718 static string getCacheFileEnding(char cache_format)
719 {
720  if (MANTA::with_debug)
721  cout << "MANTA::getCacheFileEnding()" << endl;
722 
723  switch (cache_format) {
734  default:
735  cerr << "Fluid Error -- Could not find file extension. Using default file extension."
736  << endl;
738  }
739 }
740 
741 static string getBooleanString(int value)
742 {
743  return (value) ? "True" : "False";
744 }
745 
746 void MANTA::initializeRNAMap(FluidModifierData *fmd)
747 {
748  if (with_debug)
749  cout << "MANTA::initializeRNAMap()" << endl;
750 
751  mRNAMap["ID"] = to_string(mCurrentID);
752 
753  if (!fmd) {
754  if (with_debug)
755  cout << "Fluid: No modifier data given in RNA map setup - returning early" << endl;
756  return;
757  }
758 
759  FluidDomainSettings *fds = fmd->domain;
760  bool is2D = (fds->solver_res == 2);
761 
762  string borderCollisions = "";
764  borderCollisions += "x";
766  borderCollisions += "X";
768  borderCollisions += "y";
770  borderCollisions += "Y";
772  borderCollisions += "z";
773  if ((fds->border_collisions & FLUID_DOMAIN_BORDER_TOP) == 0)
774  borderCollisions += "Z";
775 
776  string particleTypesStr = "";
778  particleTypesStr += "PtypeSpray";
780  if (!particleTypesStr.empty())
781  particleTypesStr += "|";
782  particleTypesStr += "PtypeBubble";
783  }
785  if (!particleTypesStr.empty())
786  particleTypesStr += "|";
787  particleTypesStr += "PtypeFoam";
788  }
790  if (!particleTypesStr.empty())
791  particleTypesStr += "|";
792  particleTypesStr += "PtypeTracer";
793  }
794  if (particleTypesStr.empty())
795  particleTypesStr = "0";
796 
799 
800  string cacheDirectory(fds->cache_directory);
801 
802  float viscosity = fds->viscosity_base * pow(10.0f, -fds->viscosity_exponent);
803  float domainSize = MAX3(fds->global_size[0], fds->global_size[1], fds->global_size[2]);
804 
805  string vdbCompressionMethod = "Compression_None";
807  vdbCompressionMethod = "Compression_None";
808  else if (fds->openvdb_compression == VDB_COMPRESSION_ZIP)
809  vdbCompressionMethod = "Compression_Zip";
811  vdbCompressionMethod = "Compression_Blosc";
812 
813  string vdbPrecisionHalf = "Precision_Half";
815  vdbPrecisionHalf = "Precision_Full";
817  vdbPrecisionHalf = "Precision_Half";
819  vdbPrecisionHalf = "Precision_Mini";
820 
821  mRNAMap["USING_SMOKE"] = getBooleanString(fds->type == FLUID_DOMAIN_TYPE_GAS);
822  mRNAMap["USING_LIQUID"] = getBooleanString(fds->type == FLUID_DOMAIN_TYPE_LIQUID);
823  mRNAMap["USING_COLORS"] = getBooleanString(fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS);
824  mRNAMap["USING_HEAT"] = getBooleanString(fds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT);
825  mRNAMap["USING_FIRE"] = getBooleanString(fds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE);
826  mRNAMap["USING_NOISE"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_NOISE);
827  mRNAMap["USING_OBSTACLE"] = getBooleanString(fds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE);
828  mRNAMap["USING_GUIDING"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_GUIDE);
829  mRNAMap["USING_INVEL"] = getBooleanString(fds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL);
830  mRNAMap["USING_OUTFLOW"] = getBooleanString(fds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW);
831  mRNAMap["USING_LOG_DISSOLVE"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_DISSOLVE_LOG);
832  mRNAMap["USING_DISSOLVE"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_DISSOLVE);
833  mRNAMap["DOMAIN_CLOSED"] = getBooleanString(borderCollisions.compare("") == 0);
834  mRNAMap["CACHE_RESUMABLE"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE);
835  mRNAMap["USING_ADAPTIVETIME"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_TIME);
836  mRNAMap["USING_SPEEDVECTORS"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS);
837  mRNAMap["USING_FRACTIONS"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_FRACTIONS);
838  mRNAMap["DELETE_IN_OBSTACLE"] = getBooleanString(fds->flags & FLUID_DOMAIN_DELETE_IN_OBSTACLE);
839  mRNAMap["USING_DIFFUSION"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_DIFFUSION);
840  mRNAMap["USING_MESH"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_MESH);
841  mRNAMap["USING_IMPROVED_MESH"] = getBooleanString(fds->mesh_generator ==
843  mRNAMap["USING_SNDPARTS"] = getBooleanString(fds->particle_type & particleTypes);
844  mRNAMap["SNDPARTICLE_BOUNDARY_DELETE"] = getBooleanString(fds->sndparticle_boundary ==
846  mRNAMap["SNDPARTICLE_BOUNDARY_PUSHOUT"] = getBooleanString(fds->sndparticle_boundary ==
848 
849  mRNAMap["SOLVER_DIM"] = to_string(fds->solver_res);
850  mRNAMap["BOUND_CONDITIONS"] = borderCollisions;
851  mRNAMap["BOUNDARY_WIDTH"] = to_string(fds->boundary_width);
852  mRNAMap["RES"] = to_string(mMaxRes);
853  mRNAMap["RESX"] = to_string(mResX);
854  mRNAMap["RESY"] = (is2D) ? to_string(mResZ) : to_string(mResY);
855  mRNAMap["RESZ"] = (is2D) ? to_string(1) : to_string(mResZ);
856  mRNAMap["TIME_SCALE"] = to_string(fds->time_scale);
857  mRNAMap["FRAME_LENGTH"] = to_string(fds->frame_length);
858  mRNAMap["CFL"] = to_string(fds->cfl_condition);
859  mRNAMap["DT"] = to_string(fds->dt);
860  mRNAMap["TIMESTEPS_MIN"] = to_string(fds->timesteps_minimum);
861  mRNAMap["TIMESTEPS_MAX"] = to_string(fds->timesteps_maximum);
862  mRNAMap["TIME_TOTAL"] = to_string(fds->time_total);
863  mRNAMap["TIME_PER_FRAME"] = to_string(fds->time_per_frame);
864  mRNAMap["VORTICITY"] = to_string(fds->vorticity);
865  mRNAMap["FLAME_VORTICITY"] = to_string(fds->flame_vorticity);
866  mRNAMap["NOISE_SCALE"] = to_string(fds->noise_scale);
867  mRNAMap["MESH_SCALE"] = to_string(fds->mesh_scale);
868  mRNAMap["PARTICLE_SCALE"] = to_string(fds->particle_scale);
869  mRNAMap["NOISE_RESX"] = to_string(mResXNoise);
870  mRNAMap["NOISE_RESY"] = (is2D) ? to_string(mResZNoise) : to_string(mResYNoise);
871  mRNAMap["NOISE_RESZ"] = (is2D) ? to_string(1) : to_string(mResZNoise);
872  mRNAMap["MESH_RESX"] = to_string(mResXMesh);
873  mRNAMap["MESH_RESY"] = (is2D) ? to_string(mResZMesh) : to_string(mResYMesh);
874  mRNAMap["MESH_RESZ"] = (is2D) ? to_string(1) : to_string(mResZMesh);
875  mRNAMap["PARTICLE_RESX"] = to_string(mResXParticle);
876  mRNAMap["PARTICLE_RESY"] = (is2D) ? to_string(mResZParticle) : to_string(mResYParticle);
877  mRNAMap["PARTICLE_RESZ"] = (is2D) ? to_string(1) : to_string(mResZParticle);
878  mRNAMap["GUIDING_RESX"] = to_string(mResGuiding[0]);
879  mRNAMap["GUIDING_RESY"] = (is2D) ? to_string(mResGuiding[2]) : to_string(mResGuiding[1]);
880  mRNAMap["GUIDING_RESZ"] = (is2D) ? to_string(1) : to_string(mResGuiding[2]);
881  mRNAMap["MIN_RESX"] = to_string(fds->res_min[0]);
882  mRNAMap["MIN_RESY"] = to_string(fds->res_min[1]);
883  mRNAMap["MIN_RESZ"] = to_string(fds->res_min[2]);
884  mRNAMap["BASE_RESX"] = to_string(fds->base_res[0]);
885  mRNAMap["BASE_RESY"] = to_string(fds->base_res[1]);
886  mRNAMap["BASE_RESZ"] = to_string(fds->base_res[2]);
887  mRNAMap["WLT_STR"] = to_string(fds->noise_strength);
888  mRNAMap["NOISE_POSSCALE"] = to_string(fds->noise_pos_scale);
889  mRNAMap["NOISE_TIMEANIM"] = to_string(fds->noise_time_anim);
890  mRNAMap["COLOR_R"] = to_string(fds->active_color[0]);
891  mRNAMap["COLOR_G"] = to_string(fds->active_color[1]);
892  mRNAMap["COLOR_B"] = to_string(fds->active_color[2]);
893  mRNAMap["BUOYANCY_ALPHA"] = to_string(fds->alpha);
894  mRNAMap["BUOYANCY_BETA"] = to_string(fds->beta);
895  mRNAMap["DISSOLVE_SPEED"] = to_string(fds->diss_speed);
896  mRNAMap["BURNING_RATE"] = to_string(fds->burning_rate);
897  mRNAMap["FLAME_SMOKE"] = to_string(fds->flame_smoke);
898  mRNAMap["IGNITION_TEMP"] = to_string(fds->flame_ignition);
899  mRNAMap["MAX_TEMP"] = to_string(fds->flame_max_temp);
900  mRNAMap["FLAME_SMOKE_COLOR_X"] = to_string(fds->flame_smoke_color[0]);
901  mRNAMap["FLAME_SMOKE_COLOR_Y"] = to_string(fds->flame_smoke_color[1]);
902  mRNAMap["FLAME_SMOKE_COLOR_Z"] = to_string(fds->flame_smoke_color[2]);
903  mRNAMap["CURRENT_FRAME"] = to_string(int(fmd->time));
904  mRNAMap["START_FRAME"] = to_string(fds->cache_frame_start);
905  mRNAMap["END_FRAME"] = to_string(fds->cache_frame_end);
906  mRNAMap["CACHE_DATA_FORMAT"] = getCacheFileEnding(fds->cache_data_format);
907  mRNAMap["CACHE_MESH_FORMAT"] = getCacheFileEnding(fds->cache_mesh_format);
908  mRNAMap["CACHE_NOISE_FORMAT"] = getCacheFileEnding(fds->cache_noise_format);
909  mRNAMap["CACHE_PARTICLE_FORMAT"] = getCacheFileEnding(fds->cache_particle_format);
910  mRNAMap["USING_APIC"] = getBooleanString(fds->simulation_method == FLUID_DOMAIN_METHOD_APIC);
911  mRNAMap["FLIP_RATIO"] = to_string(fds->flip_ratio);
912  mRNAMap["PARTICLE_RANDOMNESS"] = to_string(fds->particle_randomness);
913  mRNAMap["PARTICLE_NUMBER"] = to_string(fds->particle_number);
914  mRNAMap["PARTICLE_MINIMUM"] = to_string(fds->particle_minimum);
915  mRNAMap["PARTICLE_MAXIMUM"] = to_string(fds->particle_maximum);
916  mRNAMap["PARTICLE_RADIUS"] = to_string(fds->particle_radius);
917  mRNAMap["FRACTIONS_THRESHOLD"] = to_string(fds->fractions_threshold);
918  mRNAMap["FRACTIONS_DISTANCE"] = to_string(fds->fractions_distance);
919  mRNAMap["MESH_CONCAVE_UPPER"] = to_string(fds->mesh_concave_upper);
920  mRNAMap["MESH_CONCAVE_LOWER"] = to_string(fds->mesh_concave_lower);
921  mRNAMap["MESH_PARTICLE_RADIUS"] = to_string(fds->mesh_particle_radius);
922  mRNAMap["MESH_SMOOTHEN_POS"] = to_string(fds->mesh_smoothen_pos);
923  mRNAMap["MESH_SMOOTHEN_NEG"] = to_string(fds->mesh_smoothen_neg);
924  mRNAMap["PARTICLE_BAND_WIDTH"] = to_string(fds->particle_band_width);
925  mRNAMap["SNDPARTICLE_TAU_MIN_WC"] = to_string(fds->sndparticle_tau_min_wc);
926  mRNAMap["SNDPARTICLE_TAU_MAX_WC"] = to_string(fds->sndparticle_tau_max_wc);
927  mRNAMap["SNDPARTICLE_TAU_MIN_TA"] = to_string(fds->sndparticle_tau_min_ta);
928  mRNAMap["SNDPARTICLE_TAU_MAX_TA"] = to_string(fds->sndparticle_tau_max_ta);
929  mRNAMap["SNDPARTICLE_TAU_MIN_K"] = to_string(fds->sndparticle_tau_min_k);
930  mRNAMap["SNDPARTICLE_TAU_MAX_K"] = to_string(fds->sndparticle_tau_max_k);
931  mRNAMap["SNDPARTICLE_K_WC"] = to_string(fds->sndparticle_k_wc);
932  mRNAMap["SNDPARTICLE_K_TA"] = to_string(fds->sndparticle_k_ta);
933  mRNAMap["SNDPARTICLE_K_B"] = to_string(fds->sndparticle_k_b);
934  mRNAMap["SNDPARTICLE_K_D"] = to_string(fds->sndparticle_k_d);
935  mRNAMap["SNDPARTICLE_L_MIN"] = to_string(fds->sndparticle_l_min);
936  mRNAMap["SNDPARTICLE_L_MAX"] = to_string(fds->sndparticle_l_max);
937  mRNAMap["SNDPARTICLE_POTENTIAL_RADIUS"] = to_string(fds->sndparticle_potential_radius);
938  mRNAMap["SNDPARTICLE_UPDATE_RADIUS"] = to_string(fds->sndparticle_update_radius);
939  mRNAMap["LIQUID_SURFACE_TENSION"] = to_string(fds->surface_tension);
940  mRNAMap["FLUID_VISCOSITY"] = to_string(viscosity);
941  mRNAMap["FLUID_DOMAIN_SIZE"] = to_string(domainSize);
942  mRNAMap["FLUID_DOMAIN_SIZE_X"] = to_string(fds->global_size[0]);
943  mRNAMap["FLUID_DOMAIN_SIZE_Y"] = to_string(fds->global_size[1]);
944  mRNAMap["FLUID_DOMAIN_SIZE_Z"] = to_string(fds->global_size[2]);
945  mRNAMap["SNDPARTICLE_TYPES"] = particleTypesStr;
946  mRNAMap["GUIDING_ALPHA"] = to_string(fds->guide_alpha);
947  mRNAMap["GUIDING_BETA"] = to_string(fds->guide_beta);
948  mRNAMap["GUIDING_FACTOR"] = to_string(fds->guide_vel_factor);
949  mRNAMap["GRAVITY_X"] = to_string(fds->gravity_final[0]);
950  mRNAMap["GRAVITY_Y"] = to_string(fds->gravity_final[1]);
951  mRNAMap["GRAVITY_Z"] = to_string(fds->gravity_final[2]);
952  mRNAMap["CACHE_DIR"] = cacheDirectory;
953  mRNAMap["COMPRESSION_OPENVDB"] = vdbCompressionMethod;
954  mRNAMap["PRECISION_OPENVDB"] = vdbPrecisionHalf;
955  mRNAMap["CLIP_OPENVDB"] = to_string(fds->clipping);
956  mRNAMap["PP_PARTICLE_MAXIMUM"] = to_string(fds->sys_particle_maximum);
957  mRNAMap["USING_VISCOSITY"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_VISCOSITY);
958  mRNAMap["VISCOSITY_VALUE"] = to_string(fds->viscosity_value);
959 
960  /* Fluid object names. */
961  mRNAMap["NAME_FLAGS"] = FLUID_NAME_FLAGS;
962  mRNAMap["NAME_VELOCITY"] = FLUID_NAME_VELOCITY;
963  mRNAMap["NAME_VELOCITYTMP"] = FLUID_NAME_VELOCITYTMP;
964  mRNAMap["NAME_VELOCITY_X"] = FLUID_NAME_VELOCITYX;
965  mRNAMap["NAME_VELOCITY_Y"] = FLUID_NAME_VELOCITYY;
966  mRNAMap["NAME_VELOCITY_Z"] = FLUID_NAME_VELOCITYZ;
967  mRNAMap["NAME_PRESSURE"] = FLUID_NAME_PRESSURE;
968  mRNAMap["NAME_PHIOBS"] = FLUID_NAME_PHIOBS;
969  mRNAMap["NAME_PHISIN"] = FLUID_NAME_PHISIN;
970  mRNAMap["NAME_PHIIN"] = FLUID_NAME_PHIIN;
971  mRNAMap["NAME_PHIOUT"] = FLUID_NAME_PHIOUT;
972  mRNAMap["NAME_FORCES"] = FLUID_NAME_FORCES;
973  mRNAMap["NAME_FORCES_X"] = FLUID_NAME_FORCE_X;
974  mRNAMap["NAME_FORCES_Y"] = FLUID_NAME_FORCE_Y;
975  mRNAMap["NAME_FORCES_Z"] = FLUID_NAME_FORCE_Z;
976  mRNAMap["NAME_NUMOBS"] = FLUID_NAME_NUMOBS;
977  mRNAMap["NAME_PHIOBSSIN"] = FLUID_NAME_PHIOBSSIN;
978  mRNAMap["NAME_PHIOBSIN"] = FLUID_NAME_PHIOBSIN;
979  mRNAMap["NAME_OBVEL"] = FLUID_NAME_OBVEL;
980  mRNAMap["NAME_OBVELC"] = FLUID_NAME_OBVELC;
981  mRNAMap["NAME_OBVEL_X"] = FLUID_NAME_OBVEL_X;
982  mRNAMap["NAME_OBVEL_Y"] = FLUID_NAME_OBVEL_Y;
983  mRNAMap["NAME_OBVEL_Z"] = FLUID_NAME_OBVEL_Z;
984  mRNAMap["NAME_FRACTIONS"] = FLUID_NAME_FRACTIONS;
985  mRNAMap["NAME_INVELC"] = FLUID_NAME_INVELC;
986  mRNAMap["NAME_INVEL_X"] = FLUID_NAME_INVEL_X;
987  mRNAMap["NAME_INVEL_Y"] = FLUID_NAME_INVEL_Y;
988  mRNAMap["NAME_INVEL_Z"] = FLUID_NAME_INVEL_Z;
989  mRNAMap["NAME_PHIOUTSIN"] = FLUID_NAME_PHIOUTSIN;
990  mRNAMap["NAME_PHIOUTIN"] = FLUID_NAME_PHIOUTIN;
991 
992  /* Smoke object names. */
993  mRNAMap["NAME_SHADOW"] = FLUID_NAME_SHADOW;
994  mRNAMap["NAME_EMISSION"] = FLUID_NAME_EMISSION;
995  mRNAMap["NAME_EMISSIONIN"] = FLUID_NAME_EMISSIONIN;
996  mRNAMap["NAME_DENSITY"] = FLUID_NAME_DENSITY;
997  mRNAMap["NAME_DENSITYIN"] = FLUID_NAME_DENSITYIN;
998  mRNAMap["NAME_HEAT"] = FLUID_NAME_HEAT;
999  mRNAMap["NAME_HEATIN"] = FLUID_NAME_HEATIN;
1000  mRNAMap["NAME_TEMPERATURE"] = FLUID_NAME_TEMPERATURE;
1001  mRNAMap["NAME_TEMPERATUREIN"] = FLUID_NAME_TEMPERATUREIN;
1002  mRNAMap["NAME_COLORR"] = FLUID_NAME_COLORR;
1003  mRNAMap["NAME_COLORG"] = FLUID_NAME_COLORG;
1004  mRNAMap["NAME_COLORB"] = FLUID_NAME_COLORB;
1005  mRNAMap["NAME_COLORRIN"] = FLUID_NAME_COLORRIN;
1006  mRNAMap["NAME_COLORGIN"] = FLUID_NAME_COLORGIN;
1007  mRNAMap["NAME_COLORBIN"] = FLUID_NAME_COLORBIN;
1008  mRNAMap["NAME_FLAME"] = FLUID_NAME_FLAME;
1009  mRNAMap["NAME_FUEL"] = FLUID_NAME_FUEL;
1010  mRNAMap["NAME_REACT"] = FLUID_NAME_REACT;
1011  mRNAMap["NAME_FUELIN"] = FLUID_NAME_FUELIN;
1012  mRNAMap["NAME_REACTIN"] = FLUID_NAME_REACTIN;
1013 
1014  /* Liquid object names. */
1015  mRNAMap["NAME_PHIPARTS"] = FLUID_NAME_PHIPARTS;
1016  mRNAMap["NAME_PHI"] = FLUID_NAME_PHI;
1017  mRNAMap["NAME_PHITMP"] = FLUID_NAME_PHITMP;
1018  mRNAMap["NAME_VELOLD"] = FLUID_NAME_VELOCITYOLD;
1019  mRNAMap["NAME_VELPARTS"] = FLUID_NAME_VELOCITYPARTS;
1020  mRNAMap["NAME_MAPWEIGHTS"] = FLUID_NAME_MAPWEIGHTS;
1021  mRNAMap["NAME_PP"] = FLUID_NAME_PP;
1022  mRNAMap["NAME_PVEL"] = FLUID_NAME_PVEL;
1023  mRNAMap["NAME_PARTS"] = FLUID_NAME_PARTS;
1024  mRNAMap["NAME_PARTSVELOCITY"] = FLUID_NAME_PARTSVELOCITY;
1025  mRNAMap["NAME_PINDEX"] = FLUID_NAME_PINDEX;
1026  mRNAMap["NAME_GPI"] = FLUID_NAME_GPI;
1027  mRNAMap["NAME_CURVATURE"] = FLUID_NAME_CURVATURE;
1028 
1029  /* Noise object names. */
1030  mRNAMap["NAME_VELOCITY_NOISE"] = FLUID_NAME_VELOCITY_NOISE;
1031  mRNAMap["NAME_DENSITY_NOISE"] = FLUID_NAME_DENSITY_NOISE;
1032  mRNAMap["NAME_PHIIN_NOISE"] = FLUID_NAME_PHIIN_NOISE;
1033  mRNAMap["NAME_PHIOUT_NOISE"] = FLUID_NAME_PHIOUT_NOISE;
1034  mRNAMap["NAME_PHIOBS_NOISE"] = FLUID_NAME_PHIOBS_NOISE;
1035  mRNAMap["NAME_FLAGS_NOISE"] = FLUID_NAME_FLAGS_NOISE;
1036  mRNAMap["NAME_TMPIN_NOISE"] = FLUID_NAME_TMPIN_NOISE;
1037  mRNAMap["NAME_EMISSIONIN_NOISE"] = FLUID_NAME_EMISSIONIN_NOISE;
1038  mRNAMap["NAME_ENERGY"] = FLUID_NAME_ENERGY;
1039  mRNAMap["NAME_TMPFLAGS"] = FLUID_NAME_TMPFLAGS;
1040  mRNAMap["NAME_TEXTURE_U"] = FLUID_NAME_TEXTURE_U;
1041  mRNAMap["NAME_TEXTURE_V"] = FLUID_NAME_TEXTURE_V;
1042  mRNAMap["NAME_TEXTURE_W"] = FLUID_NAME_TEXTURE_W;
1043  mRNAMap["NAME_TEXTURE_U2"] = FLUID_NAME_TEXTURE_U2;
1044  mRNAMap["NAME_TEXTURE_V2"] = FLUID_NAME_TEXTURE_V2;
1045  mRNAMap["NAME_TEXTURE_W2"] = FLUID_NAME_TEXTURE_W2;
1046  mRNAMap["NAME_UV0"] = FLUID_NAME_UV0;
1047  mRNAMap["NAME_UV1"] = FLUID_NAME_UV1;
1048  mRNAMap["NAME_COLORR_NOISE"] = FLUID_NAME_COLORR_NOISE;
1049  mRNAMap["NAME_COLORG_NOISE"] = FLUID_NAME_COLORG_NOISE;
1050  mRNAMap["NAME_COLORB_NOISE"] = FLUID_NAME_COLORB_NOISE;
1051  mRNAMap["NAME_FLAME_NOISE"] = FLUID_NAME_FLAME_NOISE;
1052  mRNAMap["NAME_FUEL_NOISE"] = FLUID_NAME_FUEL_NOISE;
1053  mRNAMap["NAME_REACT_NOISE"] = FLUID_NAME_REACT_NOISE;
1054 
1055  /* Mesh object names. */
1056  mRNAMap["NAME_PHIPARTS_MESH"] = FLUID_NAME_PHIPARTS_MESH;
1057  mRNAMap["NAME_PHI_MESH"] = FLUID_NAME_PHI_MESH;
1058  mRNAMap["NAME_PP_MESH"] = FLUID_NAME_PP_MESH;
1059  mRNAMap["NAME_FLAGS_MESH"] = FLUID_NAME_FLAGS_MESH;
1060  mRNAMap["NAME_LMESH"] = FLUID_NAME_LMESH;
1061  mRNAMap["NAME_VELOCITYVEC_MESH"] = FLUID_NAME_VELOCITYVEC_MESH;
1062  mRNAMap["NAME_VELOCITY_MESH"] = FLUID_NAME_VELOCITY_MESH;
1063  mRNAMap["NAME_PINDEX_MESH"] = FLUID_NAME_PINDEX_MESH;
1064  mRNAMap["NAME_GPI_MESH"] = FLUID_NAME_GPI_MESH;
1065 
1066  /* Particles object names. */
1067  mRNAMap["NAME_PP_PARTICLES"] = FLUID_NAME_PP_PARTICLES;
1068  mRNAMap["NAME_PVEL_PARTICLES"] = FLUID_NAME_PVEL_PARTICLES;
1069  mRNAMap["NAME_PFORCE_PARTICLES"] = FLUID_NAME_PFORCE_PARTICLES;
1070  mRNAMap["NAME_PLIFE_PARTICLES"] = FLUID_NAME_PLIFE_PARTICLES;
1071  mRNAMap["NAME_PARTS_PARTICLES"] = FLUID_NAME_PARTS_PARTICLES;
1072  mRNAMap["NAME_PARTSVEL_PARTICLES"] = FLUID_NAME_PARTSVEL_PARTICLES;
1073  mRNAMap["NAME_PARTSFORCE_PARTICLES"] = FLUID_NAME_PARTSFORCE_PARTICLES;
1074  mRNAMap["NAME_PARTSLIFE_PARTICLES"] = FLUID_NAME_PARTSLIFE_PARTICLES;
1075  mRNAMap["NAME_VELOCITY_PARTICLES"] = FLUID_NAME_VELOCITY_PARTICLES;
1076  mRNAMap["NAME_FLAGS_PARTICLES"] = FLUID_NAME_FLAGS_PARTICLES;
1077  mRNAMap["NAME_PHI_PARTICLES"] = FLUID_NAME_PHI_PARTICLES;
1078  mRNAMap["NAME_PHIOBS_PARTICLES"] = FLUID_NAME_PHIOBS_PARTICLES;
1079  mRNAMap["NAME_PHIOUT_PARTICLES"] = FLUID_NAME_PHIOUT_PARTICLES;
1080  mRNAMap["NAME_NORMAL_PARTICLES"] = FLUID_NAME_NORMAL_PARTICLES;
1081  mRNAMap["NAME_NEIGHBORRATIO_PARTICLES"] = FLUID_NAME_NEIGHBORRATIO_PARTICLES;
1082  mRNAMap["NAME_TRAPPEDAIR_PARTICLES"] = FLUID_NAME_TRAPPEDAIR_PARTICLES;
1083  mRNAMap["NAME_WAVECREST_PARTICLES"] = FLUID_NAME_WAVECREST_PARTICLES;
1084  mRNAMap["NAME_KINETICENERGY_PARTICLES"] = FLUID_NAME_KINETICENERGY_PARTICLES;
1085 
1086  /* Guiding object names. */
1087  mRNAMap["NAME_VELT"] = FLUID_NAME_VELT;
1088  mRNAMap["NAME_WEIGHTGUIDE"] = FLUID_NAME_WEIGHTGUIDE;
1089  mRNAMap["NAME_NUMGUIDES"] = FLUID_NAME_NUMGUIDES;
1090  mRNAMap["NAME_PHIGUIDEIN"] = FLUID_NAME_PHIGUIDEIN;
1091  mRNAMap["NAME_GUIDEVELC"] = FLUID_NAME_GUIDEVELC;
1092  mRNAMap["NAME_GUIDEVEL_X"] = FLUID_NAME_GUIDEVEL_X;
1093  mRNAMap["NAME_GUIDEVEL_Y"] = FLUID_NAME_GUIDEVEL_Y;
1094  mRNAMap["NAME_GUIDEVEL_Z"] = FLUID_NAME_GUIDEVEL_Z;
1095  mRNAMap["NAME_VELOCITY_GUIDE"] = FLUID_NAME_VELOCITY_GUIDE;
1096 
1097  /* Cache file names. */
1098  mRNAMap["NAME_CONFIG"] = FLUID_NAME_CONFIG;
1099  mRNAMap["NAME_DATA"] = FLUID_NAME_DATA;
1100  mRNAMap["NAME_NOISE"] = FLUID_NAME_NOISE;
1101  mRNAMap["NAME_MESH"] = FLUID_NAME_MESH;
1102  mRNAMap["NAME_PARTICLES"] = FLUID_NAME_PARTICLES;
1103  mRNAMap["NAME_GUIDING"] = FLUID_NAME_GUIDING;
1104 }
1105 
1106 string MANTA::getRealValue(const string &varName)
1107 {
1108  unordered_map<string, string>::iterator it;
1109  it = mRNAMap.find(varName);
1110 
1111  if (it == mRNAMap.end()) {
1112  cerr << "Fluid Error -- variable " << varName << " not found in RNA map " << it->second
1113  << endl;
1114  return "";
1115  }
1116 
1117  return it->second;
1118 }
1119 
1120 string MANTA::parseLine(const string &line)
1121 {
1122  if (line.size() == 0)
1123  return "";
1124  string res = "";
1125  int currPos = 0, start_del = 0, end_del = -1;
1126  bool readingVar = false;
1127  const char delimiter = '$';
1128  while (currPos < line.size()) {
1129  if (line[currPos] == delimiter && !readingVar) {
1130  readingVar = true;
1131  start_del = currPos + 1;
1132  res += line.substr(end_del + 1, currPos - end_del - 1);
1133  }
1134  else if (line[currPos] == delimiter && readingVar) {
1135  readingVar = false;
1136  end_del = currPos;
1137  res += getRealValue(line.substr(start_del, currPos - start_del));
1138  }
1139  currPos++;
1140  }
1141  res += line.substr(end_del + 1, line.size() - end_del);
1142  return res;
1143 }
1144 
1145 string MANTA::parseScript(const string &setup_string, FluidModifierData *fmd)
1146 {
1147  if (MANTA::with_debug)
1148  cout << "MANTA::parseScript()" << endl;
1149 
1150  istringstream f(setup_string);
1151  ostringstream res;
1152  string line = "";
1153 
1154  /* Update RNA map if modifier data is handed over. */
1155  if (fmd) {
1156  initializeRNAMap(fmd);
1157  }
1158  while (getline(f, line)) {
1159  res << parseLine(line) << "\n";
1160  }
1161  return res.str();
1162 }
1163 
1164 /* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */
1165 static string escapePath(string const &s)
1166 {
1167  string result = "";
1168  for (char c : s) {
1169  if (c == '\\') {
1170  result += "\\\\";
1171  }
1172  else if (c == '\'') {
1173  result += "\\\'";
1174  }
1175  else {
1176  result += c;
1177  }
1178  }
1179  return result;
1180 }
1181 
1183 {
1184  if (with_debug)
1185  cout << "MANTA::writeConfiguration()" << endl;
1186 
1187  FluidDomainSettings *fds = fmd->domain;
1188 
1189  string directory = getDirectory(fmd, FLUID_DOMAIN_DIR_CONFIG);
1191  string file = getFile(fmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_NAME_CONFIG, format, framenr);
1192 
1193  /* Create 'config' subdir if it does not exist already. */
1194  BLI_dir_create_recursive(directory.c_str());
1195 
1196  /* Open new file with some compression. */
1197  gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "wb1");
1198  if (!gzf) {
1199  cerr << "Fluid Error -- Cannot open file " << file << endl;
1200  return false;
1201  }
1202 
1203  gzwrite(gzf, &fds->active_fields, sizeof(int));
1204  gzwrite(gzf, &fds->res, 3 * sizeof(int));
1205  gzwrite(gzf, &fds->dx, sizeof(float));
1206  gzwrite(gzf, &fds->dt, sizeof(float));
1207  gzwrite(gzf, &fds->p0, 3 * sizeof(float));
1208  gzwrite(gzf, &fds->p1, 3 * sizeof(float));
1209  gzwrite(gzf, &fds->dp0, 3 * sizeof(float));
1210  gzwrite(gzf, &fds->shift, 3 * sizeof(int));
1211  gzwrite(gzf, &fds->obj_shift_f, 3 * sizeof(float));
1212  gzwrite(gzf, &fds->obmat, 16 * sizeof(float));
1213  gzwrite(gzf, &fds->base_res, 3 * sizeof(int));
1214  gzwrite(gzf, &fds->res_min, 3 * sizeof(int));
1215  gzwrite(gzf, &fds->res_max, 3 * sizeof(int));
1216  gzwrite(gzf, &fds->active_color, 3 * sizeof(float));
1217  gzwrite(gzf, &fds->time_total, sizeof(int));
1218  gzwrite(gzf, &FLUID_CACHE_VERSION, 4 * sizeof(char));
1219 
1220  return (gzclose(gzf) == Z_OK);
1221 }
1222 
1223 bool MANTA::writeData(FluidModifierData *fmd, int framenr)
1224 {
1225  if (with_debug)
1226  cout << "MANTA::writeData()" << endl;
1227 
1228  ostringstream ss;
1229  vector<string> pythonCommands;
1230  FluidDomainSettings *fds = fmd->domain;
1231 
1232  string directory = getDirectory(fmd, FLUID_DOMAIN_DIR_DATA);
1233  string volume_format = getCacheFileEnding(fds->cache_data_format);
1234  string resumable_cache = !(fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
1235 
1236  if (mUsingSmoke) {
1237  ss.str("");
1238  ss << "smoke_save_data_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1239  << ", '" << volume_format << "', " << resumable_cache << ")";
1240  pythonCommands.push_back(ss.str());
1241  }
1242  if (mUsingLiquid) {
1243  ss.str("");
1244  ss << "liquid_save_data_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1245  << ", '" << volume_format << "', " << resumable_cache << ")";
1246  pythonCommands.push_back(ss.str());
1247  }
1248  return runPythonString(pythonCommands);
1249 }
1250 
1251 bool MANTA::writeNoise(FluidModifierData *fmd, int framenr)
1252 {
1253  if (with_debug)
1254  cout << "MANTA::writeNoise()" << endl;
1255 
1256  ostringstream ss;
1257  vector<string> pythonCommands;
1258  FluidDomainSettings *fds = fmd->domain;
1259 
1260  string directory = getDirectory(fmd, FLUID_DOMAIN_DIR_NOISE);
1261  string volume_format = getCacheFileEnding(fds->cache_data_format);
1262  string resumable_cache = !(fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
1263 
1264  if (mUsingSmoke && mUsingNoise) {
1265  ss.str("");
1266  ss << "smoke_save_noise_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1267  << ", '" << volume_format << "', " << resumable_cache << ")";
1268  pythonCommands.push_back(ss.str());
1269  }
1270  return runPythonString(pythonCommands);
1271 }
1272 
1274 {
1275  if (with_debug)
1276  cout << "MANTA::readConfiguration()" << endl;
1277 
1278  FluidDomainSettings *fds = fmd->domain;
1279  float dummy;
1280 
1281  string directory = getDirectory(fmd, FLUID_DOMAIN_DIR_CONFIG);
1283  string file = getFile(fmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_NAME_CONFIG, format, framenr);
1284 
1285  if (!hasConfig(fmd, framenr))
1286  return false;
1287 
1288  gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "rb"); /* Do some compression. */
1289  if (!gzf) {
1290  cerr << "Fluid Error -- Cannot open file " << file << endl;
1291  return false;
1292  }
1293 
1294  gzread(gzf, &fds->active_fields, sizeof(int));
1295  gzread(gzf, &fds->res, 3 * sizeof(int));
1296  gzread(gzf, &fds->dx, sizeof(float));
1297  gzread(gzf, &dummy, sizeof(float)); /* dt not needed right now. */
1298  gzread(gzf, &fds->p0, 3 * sizeof(float));
1299  gzread(gzf, &fds->p1, 3 * sizeof(float));
1300  gzread(gzf, &fds->dp0, 3 * sizeof(float));
1301  gzread(gzf, &fds->shift, 3 * sizeof(int));
1302  gzread(gzf, &fds->obj_shift_f, 3 * sizeof(float));
1303  gzread(gzf, &fds->obmat, 16 * sizeof(float));
1304  gzread(gzf, &fds->base_res, 3 * sizeof(int));
1305  gzread(gzf, &fds->res_min, 3 * sizeof(int));
1306  gzread(gzf, &fds->res_max, 3 * sizeof(int));
1307  gzread(gzf, &fds->active_color, 3 * sizeof(float));
1308  gzread(gzf, &fds->time_total, sizeof(int));
1309  gzread(gzf, &fds->cache_id, 4 * sizeof(char)); /* Older caches might have no id. */
1310 
1311  fds->total_cells = fds->res[0] * fds->res[1] * fds->res[2];
1312 
1313  return (gzclose(gzf) == Z_OK);
1314 }
1315 
1316 bool MANTA::readData(FluidModifierData *fmd, int framenr, bool resumable)
1317 {
1318  if (with_debug)
1319  cout << "MANTA::readData()" << endl;
1320 
1321  if (!mUsingSmoke && !mUsingLiquid)
1322  return false;
1323 
1324  ostringstream ss;
1325  vector<string> pythonCommands;
1326  FluidDomainSettings *fds = fmd->domain;
1327  bool result = true;
1328 
1329  string directory = getDirectory(fmd, FLUID_DOMAIN_DIR_DATA);
1330  string volume_format = getCacheFileEnding(fds->cache_data_format);
1331  string resumable_cache = (!resumable) ? "False" : "True";
1332 
1333  /* Sanity check: Are cache files present? */
1334  if (!hasData(fmd, framenr))
1335  return false;
1336 
1337  if (mUsingSmoke) {
1338  ss.str("");
1339  ss << "smoke_load_data_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1340  << ", '" << volume_format << "', " << resumable_cache << ")";
1341  pythonCommands.push_back(ss.str());
1342  result &= runPythonString(pythonCommands);
1343  return (mSmokeFromFile = result);
1344  }
1345  if (mUsingLiquid) {
1346  ss.str("");
1347  ss << "liquid_load_data_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1348  << ", '" << volume_format << "', " << resumable_cache << ")";
1349  pythonCommands.push_back(ss.str());
1350  result &= runPythonString(pythonCommands);
1351  return (mFlipFromFile = result);
1352  }
1353  return result;
1354 }
1355 
1356 bool MANTA::readNoise(FluidModifierData *fmd, int framenr, bool resumable)
1357 {
1358  if (with_debug)
1359  cout << "MANTA::readNoise()" << endl;
1360 
1361  if (!mUsingSmoke || !mUsingNoise)
1362  return false;
1363 
1364  ostringstream ss;
1365  vector<string> pythonCommands;
1366  FluidDomainSettings *fds = fmd->domain;
1367 
1368  string directory = getDirectory(fmd, FLUID_DOMAIN_DIR_NOISE);
1369  string resumable_cache = (!resumable) ? "False" : "True";
1370 
1371  /* Support older caches which had more granular file format control. */
1372  char format = (!strcmp(fds->cache_id, FLUID_CACHE_VERSION)) ? fds->cache_data_format :
1373  fds->cache_noise_format;
1374  string volume_format = getCacheFileEnding(format);
1375 
1376  /* Sanity check: Are cache files present? */
1377  if (!hasNoise(fmd, framenr))
1378  return false;
1379 
1380  ss.str("");
1381  ss << "smoke_load_noise_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1382  << ", '" << volume_format << "', " << resumable_cache << ")";
1383  pythonCommands.push_back(ss.str());
1384 
1385  return (mNoiseFromFile = runPythonString(pythonCommands));
1386 }
1387 
1388 bool MANTA::readMesh(FluidModifierData *fmd, int framenr)
1389 {
1390  if (with_debug)
1391  cout << "MANTA::readMesh()" << endl;
1392 
1393  if (!mUsingLiquid || !mUsingMesh)
1394  return false;
1395 
1396  ostringstream ss;
1397  vector<string> pythonCommands;
1398  FluidDomainSettings *fds = fmd->domain;
1399 
1400  string directory = getDirectory(fmd, FLUID_DOMAIN_DIR_MESH);
1401  string mesh_format = getCacheFileEnding(fds->cache_mesh_format);
1402  string volume_format = getCacheFileEnding(fds->cache_data_format);
1403 
1404  /* Sanity check: Are cache files present? */
1405  if (!hasMesh(fmd, framenr))
1406  return false;
1407 
1408  ss.str("");
1409  ss << "liquid_load_mesh_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1410  << ", '" << mesh_format << "')";
1411  pythonCommands.push_back(ss.str());
1412 
1413  if (mUsingMVel) {
1414  ss.str("");
1415  ss << "liquid_load_meshvel_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1416  << ", '" << volume_format << "')";
1417  pythonCommands.push_back(ss.str());
1418  }
1419 
1420  return (mMeshFromFile = runPythonString(pythonCommands));
1421 }
1422 
1423 bool MANTA::readParticles(FluidModifierData *fmd, int framenr, bool resumable)
1424 {
1425  if (with_debug)
1426  cout << "MANTA::readParticles()" << endl;
1427 
1428  if (!mUsingLiquid)
1429  return false;
1430  if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers)
1431  return false;
1432 
1433  ostringstream ss;
1434  vector<string> pythonCommands;
1435  FluidDomainSettings *fds = fmd->domain;
1436 
1437  string directory = getDirectory(fmd, FLUID_DOMAIN_DIR_PARTICLES);
1438  string resumable_cache = (!resumable) ? "False" : "True";
1439 
1440  /* Support older caches which had more granular file format control. */
1441  char format = (!strcmp(fds->cache_id, FLUID_CACHE_VERSION)) ? fds->cache_data_format :
1442  fds->cache_particle_format;
1443  string volume_format = getCacheFileEnding(format);
1444 
1445  /* Sanity check: Are cache files present? */
1446  if (!hasParticles(fmd, framenr))
1447  return false;
1448 
1449  ss.str("");
1450  ss << "liquid_load_particles_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1451  << ", '" << volume_format << "', " << resumable_cache << ")";
1452  pythonCommands.push_back(ss.str());
1453 
1454  return (mParticlesFromFile = runPythonString(pythonCommands));
1455 }
1456 
1457 bool MANTA::readGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
1458 {
1459  if (with_debug)
1460  cout << "MANTA::readGuiding()" << endl;
1461 
1462  if (!mUsingGuiding)
1463  return false;
1464  if (!fmd)
1465  return false;
1466 
1467  ostringstream ss;
1468  vector<string> pythonCommands;
1469  FluidDomainSettings *fds = fmd->domain;
1470 
1471  string directory = (sourceDomain) ? getDirectory(fmd, FLUID_DOMAIN_DIR_DATA) :
1472  getDirectory(fmd, FLUID_DOMAIN_DIR_GUIDE);
1473  string volume_format = getCacheFileEnding(fds->cache_data_format);
1474 
1475  /* Sanity check: Are cache files present? */
1476  if (!hasGuiding(fmd, framenr, sourceDomain))
1477  return false;
1478 
1479  if (sourceDomain) {
1480  ss.str("");
1481  ss << "fluid_load_vel_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1482  << ", '" << volume_format << "')";
1483  }
1484  else {
1485  ss.str("");
1486  ss << "fluid_load_guiding_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
1487  << ", '" << volume_format << "')";
1488  }
1489  pythonCommands.push_back(ss.str());
1490 
1491  return runPythonString(pythonCommands);
1492 }
1493 
1494 bool MANTA::bakeData(FluidModifierData *fmd, int framenr)
1495 {
1496  if (with_debug)
1497  cout << "MANTA::bakeData()" << endl;
1498 
1499  string tmpString, finalString;
1500  ostringstream ss;
1501  vector<string> pythonCommands;
1502  FluidDomainSettings *fds = fmd->domain;
1503 
1504  char cacheDirData[FILE_MAX], cacheDirGuiding[FILE_MAX];
1505  cacheDirData[0] = '\0';
1506  cacheDirGuiding[0] = '\0';
1507 
1508  string volume_format = getCacheFileEnding(fds->cache_data_format);
1509 
1510  BLI_path_join(
1511  cacheDirData, sizeof(cacheDirData), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
1512  BLI_path_join(cacheDirGuiding,
1513  sizeof(cacheDirGuiding),
1514  fds->cache_directory,
1516  nullptr);
1517  BLI_path_make_safe(cacheDirData);
1518  BLI_path_make_safe(cacheDirGuiding);
1519 
1520  ss.str("");
1521  ss << "bake_fluid_data_" << mCurrentID << "('" << escapePath(cacheDirData) << "', " << framenr
1522  << ", '" << volume_format << "')";
1523  pythonCommands.push_back(ss.str());
1524 
1525  return runPythonString(pythonCommands);
1526 }
1527 
1528 bool MANTA::bakeNoise(FluidModifierData *fmd, int framenr)
1529 {
1530  if (with_debug)
1531  cout << "MANTA::bakeNoise()" << endl;
1532 
1533  ostringstream ss;
1534  vector<string> pythonCommands;
1535  FluidDomainSettings *fds = fmd->domain;
1536 
1537  char cacheDirNoise[FILE_MAX];
1538  cacheDirNoise[0] = '\0';
1539 
1540  string volume_format = getCacheFileEnding(fds->cache_data_format);
1541 
1542  BLI_path_join(
1543  cacheDirNoise, sizeof(cacheDirNoise), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, nullptr);
1544  BLI_path_make_safe(cacheDirNoise);
1545 
1546  ss.str("");
1547  ss << "bake_noise_" << mCurrentID << "('" << escapePath(cacheDirNoise) << "', " << framenr
1548  << ", '" << volume_format << "')";
1549  pythonCommands.push_back(ss.str());
1550 
1551  return runPythonString(pythonCommands);
1552 }
1553 
1554 bool MANTA::bakeMesh(FluidModifierData *fmd, int framenr)
1555 {
1556  if (with_debug)
1557  cout << "MANTA::bakeMesh()" << endl;
1558 
1559  ostringstream ss;
1560  vector<string> pythonCommands;
1561  FluidDomainSettings *fds = fmd->domain;
1562 
1563  char cacheDirMesh[FILE_MAX];
1564  cacheDirMesh[0] = '\0';
1565 
1566  string volume_format = getCacheFileEnding(fds->cache_data_format);
1567  string mesh_format = getCacheFileEnding(fds->cache_mesh_format);
1568 
1569  BLI_path_join(
1570  cacheDirMesh, sizeof(cacheDirMesh), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, nullptr);
1571  BLI_path_make_safe(cacheDirMesh);
1572 
1573  ss.str("");
1574  ss << "bake_mesh_" << mCurrentID << "('" << escapePath(cacheDirMesh) << "', " << framenr << ", '"
1575  << volume_format << "', '" << mesh_format << "')";
1576  pythonCommands.push_back(ss.str());
1577 
1578  return runPythonString(pythonCommands);
1579 }
1580 
1582 {
1583  if (with_debug)
1584  cout << "MANTA::bakeParticles()" << endl;
1585 
1586  ostringstream ss;
1587  vector<string> pythonCommands;
1588  FluidDomainSettings *fds = fmd->domain;
1589 
1590  char cacheDirParticles[FILE_MAX];
1591  cacheDirParticles[0] = '\0';
1592 
1593  string volume_format = getCacheFileEnding(fds->cache_data_format);
1594  string resumable_cache = !(fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
1595 
1596  BLI_path_join(cacheDirParticles,
1597  sizeof(cacheDirParticles),
1598  fds->cache_directory,
1600  nullptr);
1601  BLI_path_make_safe(cacheDirParticles);
1602 
1603  ss.str("");
1604  ss << "bake_particles_" << mCurrentID << "('" << escapePath(cacheDirParticles) << "', "
1605  << framenr << ", '" << volume_format << "', " << resumable_cache << ")";
1606  pythonCommands.push_back(ss.str());
1607 
1608  return runPythonString(pythonCommands);
1609 }
1610 
1611 bool MANTA::bakeGuiding(FluidModifierData *fmd, int framenr)
1612 {
1613  if (with_debug)
1614  cout << "MANTA::bakeGuiding()" << endl;
1615 
1616  ostringstream ss;
1617  vector<string> pythonCommands;
1618  FluidDomainSettings *fds = fmd->domain;
1619 
1620  char cacheDirGuiding[FILE_MAX];
1621  cacheDirGuiding[0] = '\0';
1622 
1623  string volume_format = getCacheFileEnding(fds->cache_data_format);
1624  string resumable_cache = !(fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
1625 
1626  BLI_path_join(cacheDirGuiding,
1627  sizeof(cacheDirGuiding),
1628  fds->cache_directory,
1630  nullptr);
1631  BLI_path_make_safe(cacheDirGuiding);
1632 
1633  ss.str("");
1634  ss << "bake_guiding_" << mCurrentID << "('" << escapePath(cacheDirGuiding) << "', " << framenr
1635  << ", '" << volume_format << "', " << resumable_cache << ")";
1636  pythonCommands.push_back(ss.str());
1637 
1638  return runPythonString(pythonCommands);
1639 }
1640 
1642 {
1643  string tmpString, finalString;
1644  vector<string> pythonCommands;
1645 
1646  tmpString += fluid_variables;
1647  if (mUsingSmoke)
1648  tmpString += smoke_variables;
1649  if (mUsingLiquid)
1650  tmpString += liquid_variables;
1651  if (mUsingGuiding)
1652  tmpString += fluid_variables_guiding;
1653  if (mUsingNoise) {
1654  tmpString += fluid_variables_noise;
1655  tmpString += smoke_variables_noise;
1656  tmpString += smoke_wavelet_noise;
1657  }
1658  if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) {
1659  tmpString += fluid_variables_particles;
1660  tmpString += liquid_variables_particles;
1661  }
1662  if (mUsingMesh)
1663  tmpString += fluid_variables_mesh;
1664 
1665  finalString = parseScript(tmpString, fmd);
1666  pythonCommands.push_back(finalString);
1667 
1668  return runPythonString(pythonCommands);
1669 }
1670 
1672 {
1673  if (with_debug)
1674  cout << "MANTA::exportSmokeScript()" << endl;
1675 
1676  char cacheDir[FILE_MAX] = "\0";
1677  char cacheDirScript[FILE_MAX] = "\0";
1678 
1679  FluidDomainSettings *fds = fmd->domain;
1680 
1681  BLI_path_join(
1682  cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
1683  BLI_path_make_safe(cacheDir);
1684  /* Create 'script' subdir if it does not exist already */
1685  BLI_dir_create_recursive(cacheDir);
1686  BLI_path_join(
1687  cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_SMOKE_SCRIPT, nullptr);
1688  BLI_path_make_safe(cacheDir);
1689 
1690  bool noise = fds->flags & FLUID_DOMAIN_USE_NOISE;
1691  bool heat = fds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT;
1692  bool colors = fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS;
1693  bool fire = fds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE;
1694  bool obstacle = fds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE;
1695  bool guiding = fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE;
1696  bool invel = fds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL;
1697  bool outflow = fds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW;
1698 
1699  string manta_script;
1700 
1701  /* Libraries. */
1702  manta_script += header_libraries + manta_import;
1703 
1704  /* Variables. */
1705  manta_script += header_variables + fluid_variables + smoke_variables;
1706  if (noise) {
1707  manta_script += fluid_variables_noise + smoke_variables_noise;
1708  }
1709  if (guiding)
1710  manta_script += fluid_variables_guiding;
1711 
1712  /* Solvers. */
1713  manta_script += header_solvers + fluid_solver;
1714  if (noise)
1715  manta_script += fluid_solver_noise;
1716  if (guiding)
1717  manta_script += fluid_solver_guiding;
1718 
1719  /* Grids. */
1720  manta_script += header_grids + fluid_alloc + smoke_alloc;
1721  if (noise) {
1722  manta_script += smoke_alloc_noise;
1723  if (colors)
1724  manta_script += smoke_alloc_colors_noise;
1725  if (fire)
1726  manta_script += smoke_alloc_fire_noise;
1727  }
1728  if (heat)
1729  manta_script += smoke_alloc_heat;
1730  if (colors)
1731  manta_script += smoke_alloc_colors;
1732  if (fire)
1733  manta_script += smoke_alloc_fire;
1734  if (guiding)
1735  manta_script += fluid_alloc_guiding;
1736  if (obstacle)
1737  manta_script += fluid_alloc_obstacle;
1738  if (invel)
1739  manta_script += fluid_alloc_invel;
1740  if (outflow)
1741  manta_script += fluid_alloc_outflow;
1742 
1743  /* Noise field. */
1744  if (noise)
1745  manta_script += smoke_wavelet_noise;
1746 
1747  /* Time. */
1749 
1750  /* Import. */
1752  if (noise)
1753  manta_script += smoke_load_noise;
1754  if (guiding)
1755  manta_script += fluid_load_guiding;
1756 
1757  /* Pre/Post Steps. */
1758  manta_script += header_prepost + fluid_pre_step + fluid_post_step;
1759 
1760  /* Steps. */
1761  manta_script += header_steps + smoke_adaptive_step + smoke_step;
1762  if (noise) {
1763  manta_script += smoke_step_noise;
1764  }
1765 
1766  /* Main. */
1767  manta_script += header_main + smoke_standalone + fluid_standalone;
1768 
1769  /* Fill in missing variables in script. */
1770  string final_script = MANTA::parseScript(manta_script, fmd);
1771 
1772  /* Write script. */
1773  ofstream myfile;
1774  myfile.open(cacheDirScript);
1775  myfile << final_script;
1776  myfile.close();
1777  if (!myfile) {
1778  cerr << "Fluid Error -- Could not export standalone Mantaflow smoke domain script";
1779  return false;
1780  }
1781  return true;
1782 }
1783 
1785 {
1786  if (with_debug)
1787  cout << "MANTA::exportLiquidScript()" << endl;
1788 
1789  char cacheDir[FILE_MAX] = "\0";
1790  char cacheDirScript[FILE_MAX] = "\0";
1791 
1792  FluidDomainSettings *fds = fmd->domain;
1793 
1794  BLI_path_join(
1795  cacheDir, sizeof(cacheDir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
1796  BLI_path_make_safe(cacheDir);
1797  /* Create 'script' subdir if it does not exist already */
1798  BLI_dir_create_recursive(cacheDir);
1799  BLI_path_join(
1800  cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_LIQUID_SCRIPT, nullptr);
1801  BLI_path_make_safe(cacheDirScript);
1802 
1803  bool mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
1804  bool drops = fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY;
1805  bool bubble = fds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE;
1806  bool floater = fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM;
1807  bool tracer = fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER;
1808  bool obstacle = fds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE;
1809  bool fractions = fds->flags & FLUID_DOMAIN_USE_FRACTIONS;
1810  bool guiding = fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE;
1811  bool invel = fds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL;
1812  bool outflow = fds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW;
1813  bool viscosity = fds->flags & FLUID_DOMAIN_USE_VISCOSITY;
1814 
1815  string manta_script;
1816 
1817  /* Libraries. */
1818  manta_script += header_libraries + manta_import;
1819 
1820  /* Variables. */
1822  if (mesh)
1823  manta_script += fluid_variables_mesh;
1824  if (drops || bubble || floater || tracer)
1826  if (guiding)
1827  manta_script += fluid_variables_guiding;
1828  if (viscosity)
1829  manta_script += fluid_variables_viscosity;
1830 
1831  /* Solvers. */
1832  manta_script += header_solvers + fluid_solver;
1833  if (mesh)
1834  manta_script += fluid_solver_mesh;
1835  if (drops || bubble || floater || tracer)
1836  manta_script += fluid_solver_particles;
1837  if (guiding)
1838  manta_script += fluid_solver_guiding;
1839  if (viscosity)
1840  manta_script += fluid_solver_viscosity;
1841 
1842  /* Grids. */
1843  manta_script += header_grids + fluid_alloc + liquid_alloc;
1844  if (mesh)
1845  manta_script += liquid_alloc_mesh;
1846  if (drops || bubble || floater || tracer)
1847  manta_script += liquid_alloc_particles;
1848  if (guiding)
1849  manta_script += fluid_alloc_guiding;
1850  if (obstacle)
1851  manta_script += fluid_alloc_obstacle;
1852  if (fractions)
1853  manta_script += fluid_alloc_fractions;
1854  if (invel)
1855  manta_script += fluid_alloc_invel;
1856  if (outflow)
1857  manta_script += fluid_alloc_outflow;
1858  if (viscosity)
1859  manta_script += liquid_alloc_viscosity;
1860 
1861  /* Domain init. */
1862  manta_script += header_gridinit + liquid_init_phi;
1863 
1864  /* Time. */
1866 
1867  /* Import. */
1869  if (mesh)
1870  manta_script += liquid_load_mesh;
1871  if (drops || bubble || floater || tracer)
1872  manta_script += liquid_load_particles;
1873  if (guiding)
1874  manta_script += fluid_load_guiding;
1875 
1876  /* Pre/Post Steps. */
1877  manta_script += header_prepost + fluid_pre_step + fluid_post_step;
1878 
1879  /* Steps. */
1880  manta_script += header_steps + liquid_adaptive_step + liquid_step;
1881  if (mesh)
1882  manta_script += liquid_step_mesh;
1883  if (drops || bubble || floater || tracer)
1884  manta_script += liquid_step_particles;
1885 
1886  /* Main. */
1887  manta_script += header_main + liquid_standalone + fluid_standalone;
1888 
1889  /* Fill in missing variables in script. */
1890  string final_script = MANTA::parseScript(manta_script, fmd);
1891 
1892  /* Write script. */
1893  ofstream myfile;
1894  myfile.open(cacheDirScript);
1895  myfile << final_script;
1896  myfile.close();
1897  if (!myfile) {
1898  cerr << "Fluid Error -- Could not export standalone Mantaflow liquid domain script";
1899  return false;
1900  }
1901  return true;
1902 }
1903 
1904 /* Call Mantaflow Python functions through this function. Use isAttribute for object attributes,
1905  * e.g. s.cfl (here 's' is varname, 'cfl' functionName, and isAttribute true) or
1906  * grid.getDataPointer (here 's' is varname, 'getDataPointer' functionName, and isAttribute
1907  * false)
1908  *
1909  * Important! Return value: New reference or nullptr
1910  * Caller of this function needs to handle reference count of returned object. */
1911 static PyObject *callPythonFunction(string varName, string functionName, bool isAttribute = false)
1912 {
1913  if ((varName == "") || (functionName == "")) {
1914  if (MANTA::with_debug)
1915  cout << "Fluid: Missing Python variable name and/or function name -- name is: " << varName
1916  << ", function name is: " << functionName << endl;
1917  return nullptr;
1918  }
1919 
1920  PyGILState_STATE gilstate = PyGILState_Ensure();
1921  PyObject *var = nullptr, *func = nullptr, *returnedValue = nullptr;
1922 
1923  /* Be sure to initialize Python before using it. */
1924  Py_Initialize();
1925 
1926  /* Get pyobject that holds result value. */
1927  if (!manta_main_module) {
1928  PyGILState_Release(gilstate);
1929  return nullptr;
1930  }
1931 
1932  /* Ensure that requested variable is present in module - avoid attribute errors later on. */
1933  if (!PyObject_HasAttrString(manta_main_module, varName.c_str())) {
1934  PyGILState_Release(gilstate);
1935  return nullptr;
1936  }
1937 
1938  var = PyObject_GetAttrString(manta_main_module, varName.c_str());
1939  if (!var) {
1940  PyGILState_Release(gilstate);
1941  return nullptr;
1942  }
1943 
1944  func = PyObject_GetAttrString(var, functionName.c_str());
1945 
1946  Py_DECREF(var);
1947  if (!func) {
1948  PyGILState_Release(gilstate);
1949  return nullptr;
1950  }
1951 
1952  if (!isAttribute) {
1953  returnedValue = PyObject_CallObject(func, nullptr);
1954  Py_DECREF(func);
1955  }
1956 
1957  PyGILState_Release(gilstate);
1958  return (!isAttribute) ? returnedValue : func;
1959 }
1960 
1961 /* Argument of this function may be a nullptr.
1962  * If it's not function will handle the reference count decrement of that argument. */
1963 static void *pyObjectToPointer(PyObject *inputObject)
1964 {
1965  if (!inputObject)
1966  return nullptr;
1967 
1968  PyGILState_STATE gilstate = PyGILState_Ensure();
1969 
1970  PyObject *encoded = PyUnicode_AsUTF8String(inputObject);
1971  char *result = PyBytes_AsString(encoded);
1972 
1973  Py_DECREF(inputObject);
1974 
1975  string str(result);
1976  istringstream in(str);
1977  void *dataPointer = nullptr;
1978  in >> dataPointer;
1979 
1980  Py_DECREF(encoded);
1981 
1982  PyGILState_Release(gilstate);
1983  return dataPointer;
1984 }
1985 
1986 /* Argument of this function may be a nullptr.
1987  * If it's not function will handle the reference count decrement of that argument. */
1988 static double pyObjectToDouble(PyObject *inputObject)
1989 {
1990  if (!inputObject)
1991  return 0.0;
1992 
1993  PyGILState_STATE gilstate = PyGILState_Ensure();
1994 
1995  /* Cannot use PyFloat_AsDouble() since its error check crashes.
1996  * Likely because of typedef 'Real' for 'float' types in Mantaflow. */
1997  double result = PyFloat_AS_DOUBLE(inputObject);
1998  Py_DECREF(inputObject);
1999 
2000  PyGILState_Release(gilstate);
2001  return result;
2002 }
2003 
2004 /* Argument of this function may be a nullptr.
2005  * If it's not function will handle the reference count decrement of that argument. */
2006 static long pyObjectToLong(PyObject *inputObject)
2007 {
2008  if (!inputObject)
2009  return 0;
2010 
2011  PyGILState_STATE gilstate = PyGILState_Ensure();
2012 
2013  long result = PyLong_AsLong(inputObject);
2014  Py_DECREF(inputObject);
2015 
2016  PyGILState_Release(gilstate);
2017  return result;
2018 }
2019 
2020 template<class T> static T *getPointer(string pyObjectName, string pyFunctionName)
2021 {
2022  return static_cast<T *>(pyObjectToPointer(callPythonFunction(pyObjectName, pyFunctionName)));
2023 }
2024 
2026 {
2027  if (with_debug)
2028  cout << "MANTA::getFrame()" << endl;
2029 
2030  string func = "frame";
2031  string id = to_string(mCurrentID);
2032  string solver = "s" + id;
2033 
2034  return pyObjectToLong(callPythonFunction(solver, func, true));
2035 }
2036 
2038 {
2039  if (with_debug)
2040  cout << "MANTA::getTimestep()" << endl;
2041 
2042  string func = "timestep";
2043  string id = to_string(mCurrentID);
2044  string solver = "s" + id;
2045 
2046  return (float)pyObjectToDouble(callPythonFunction(solver, func, true));
2047 }
2048 
2050 {
2051  FluidDomainSettings *fds = fmd->domain;
2052  return ((fds->res_max[0] - fds->res_min[0]) != mResX ||
2053  (fds->res_max[1] - fds->res_min[1]) != mResY ||
2054  (fds->res_max[2] - fds->res_min[2]) != mResZ);
2055 }
2056 
2058 {
2059  if (with_debug)
2060  cout << "MANTA::adaptTimestep()" << endl;
2061 
2062  vector<string> pythonCommands;
2063  ostringstream ss;
2064 
2065  ss << "fluid_adapt_time_step_" << mCurrentID << "()";
2066  pythonCommands.push_back(ss.str());
2067 
2068  runPythonString(pythonCommands);
2069 }
2070 
2072 {
2073  if (with_debug)
2074  cout << "MANTA::updatePointers()" << endl;
2075 
2076  FluidDomainSettings *fds = fmd->domain;
2077 
2078  bool liquid = !flush && (fds->type == FLUID_DOMAIN_TYPE_LIQUID);
2079  bool smoke = !flush && (fds->type == FLUID_DOMAIN_TYPE_GAS);
2080  bool noise = !flush && smoke && fds->flags & FLUID_DOMAIN_USE_NOISE;
2081  bool heat = !flush && smoke && fds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT;
2082  bool colors = !flush && smoke && fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS;
2083  bool fire = !flush && smoke && fds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE;
2084  bool obstacle = !flush && fds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE;
2085  bool guiding = !flush && fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE;
2086  bool invel = !flush && fds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL;
2087  bool outflow = !flush && fds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW;
2088  bool drops = !flush && liquid && fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY;
2089  bool bubble = !flush && liquid && fds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE;
2090  bool floater = !flush && liquid && fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM;
2091  bool tracer = !flush && liquid && fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER;
2092  bool parts = !flush && liquid && (drops | bubble | floater | tracer);
2093  bool mesh = !flush && liquid && fds->flags & FLUID_DOMAIN_USE_MESH;
2094  bool meshvel = !flush && liquid && mesh && fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS;
2095 
2096  string func = "getDataPointer";
2097  string funcNodes = "getNodesDataPointer";
2098  string funcTris = "getTrisDataPointer";
2099 
2100  string id = to_string(mCurrentID);
2101  string s_ext = "_s" + id;
2102  string pp_ext = "_pp" + id;
2103  string snd_ext = "_sp" + id;
2104  string sm_ext = "_sm" + id;
2105  string mesh_ext = "_mesh" + id;
2106  string sn_ext = "_sn" + id;
2107 
2108  mFlags = (smoke || liquid) ? getPointer<int>("flags" + s_ext, func) : nullptr;
2109  mPhiIn = (smoke || liquid) ? getPointer<float>("phiIn" + s_ext, func) : nullptr;
2110  mPhiStaticIn = (smoke || liquid) ? getPointer<float>("phiSIn" + s_ext, func) : nullptr;
2111  mVelocityX = (smoke || liquid) ? getPointer<float>("x_vel" + s_ext, func) : nullptr;
2112  mVelocityY = (smoke || liquid) ? getPointer<float>("y_vel" + s_ext, func) : nullptr;
2113  mVelocityZ = (smoke || liquid) ? getPointer<float>("z_vel" + s_ext, func) : nullptr;
2114  mForceX = (smoke || liquid) ? getPointer<float>("x_force" + s_ext, func) : nullptr;
2115  mForceY = (smoke || liquid) ? getPointer<float>("y_force" + s_ext, func) : nullptr;
2116  mForceZ = (smoke || liquid) ? getPointer<float>("z_force" + s_ext, func) : nullptr;
2117  mPressure = (smoke || liquid) ? getPointer<float>("pressure" + s_ext, func) : nullptr;
2118 
2119  /* Outflow. */
2120  mPhiOutIn = (outflow) ? getPointer<float>("phiOutIn" + s_ext, func) : nullptr;
2121  mPhiOutStaticIn = (outflow) ? getPointer<float>("phiOutSIn" + s_ext, func) : nullptr;
2122 
2123  /* Obstacles. */
2124  mPhiObsIn = (obstacle) ? getPointer<float>("phiObsIn" + s_ext, func) : nullptr;
2125  mPhiObsStaticIn = (obstacle) ? getPointer<float>("phiObsSIn" + s_ext, func) : nullptr;
2126  mObVelocityX = (obstacle) ? getPointer<float>("x_obvel" + s_ext, func) : nullptr;
2127  mObVelocityY = (obstacle) ? getPointer<float>("y_obvel" + s_ext, func) : nullptr;
2128  mObVelocityZ = (obstacle) ? getPointer<float>("z_obvel" + s_ext, func) : nullptr;
2129  mNumObstacle = (obstacle) ? getPointer<float>("numObs" + s_ext, func) : nullptr;
2130 
2131  /* Guiding. */
2132  mPhiGuideIn = (guiding) ? getPointer<float>("phiGuideIn" + s_ext, func) : nullptr;
2133  mGuideVelocityX = (guiding) ? getPointer<float>("x_guidevel" + s_ext, func) : nullptr;
2134  mGuideVelocityY = (guiding) ? getPointer<float>("y_guidevel" + s_ext, func) : nullptr;
2135  mGuideVelocityZ = (guiding) ? getPointer<float>("z_guidevel" + s_ext, func) : nullptr;
2136  mNumGuide = (guiding) ? getPointer<float>("numGuides" + s_ext, func) : nullptr;
2137 
2138  /* Initial velocities. */
2139  mInVelocityX = (invel) ? getPointer<float>("x_invel" + s_ext, func) : nullptr;
2140  mInVelocityY = (invel) ? getPointer<float>("y_invel" + s_ext, func) : nullptr;
2141  mInVelocityZ = (invel) ? getPointer<float>("z_invel" + s_ext, func) : nullptr;
2142 
2143  /* Smoke. */
2144  mDensity = (smoke) ? getPointer<float>("density" + s_ext, func) : nullptr;
2145  mDensityIn = (smoke) ? getPointer<float>("densityIn" + s_ext, func) : nullptr;
2146  mShadow = (smoke) ? getPointer<float>("shadow" + s_ext, func) : nullptr;
2147  mEmissionIn = (smoke) ? getPointer<float>("emissionIn" + s_ext, func) : nullptr;
2148 
2149  /* Heat. */
2150  mHeat = (heat) ? getPointer<float>("heat" + s_ext, func) : nullptr;
2151  mHeatIn = (heat) ? getPointer<float>("heatIn" + s_ext, func) : nullptr;
2152 
2153  /* Fire. */
2154  mFlame = (fire) ? getPointer<float>("flame" + s_ext, func) : nullptr;
2155  mFuel = (fire) ? getPointer<float>("fuel" + s_ext, func) : nullptr;
2156  mReact = (fire) ? getPointer<float>("react" + s_ext, func) : nullptr;
2157  mFuelIn = (fire) ? getPointer<float>("fuelIn" + s_ext, func) : nullptr;
2158  mReactIn = (fire) ? getPointer<float>("reactIn" + s_ext, func) : nullptr;
2159 
2160  /* Colors. */
2161  mColorR = (colors) ? getPointer<float>("color_r" + s_ext, func) : nullptr;
2162  mColorG = (colors) ? getPointer<float>("color_g" + s_ext, func) : nullptr;
2163  mColorB = (colors) ? getPointer<float>("color_b" + s_ext, func) : nullptr;
2164  mColorRIn = (colors) ? getPointer<float>("color_r_in" + s_ext, func) : nullptr;
2165  mColorGIn = (colors) ? getPointer<float>("color_g_in" + s_ext, func) : nullptr;
2166  mColorBIn = (colors) ? getPointer<float>("color_b_in" + s_ext, func) : nullptr;
2167 
2168  /* Noise. */
2169  mDensityHigh = (noise) ? getPointer<float>("density" + sn_ext, func) : nullptr;
2170  mTextureU = (noise) ? getPointer<float>("texture_u" + s_ext, func) : nullptr;
2171  mTextureV = (noise) ? getPointer<float>("texture_v" + s_ext, func) : nullptr;
2172  mTextureW = (noise) ? getPointer<float>("texture_w" + s_ext, func) : nullptr;
2173  mTextureU2 = (noise) ? getPointer<float>("texture_u2" + s_ext, func) : nullptr;
2174  mTextureV2 = (noise) ? getPointer<float>("texture_v2" + s_ext, func) : nullptr;
2175  mTextureW2 = (noise) ? getPointer<float>("texture_w2" + s_ext, func) : nullptr;
2176 
2177  /* Fire with noise. */
2178  mFlameHigh = (noise && fire) ? getPointer<float>("flame" + sn_ext, func) : nullptr;
2179  mFuelHigh = (noise && fire) ? getPointer<float>("fuel" + sn_ext, func) : nullptr;
2180  mReactHigh = (noise && fire) ? getPointer<float>("react" + sn_ext, func) : nullptr;
2181 
2182  /* Colors with noise. */
2183  mColorRHigh = (noise && colors) ? getPointer<float>("color_r" + sn_ext, func) : nullptr;
2184  mColorGHigh = (noise && colors) ? getPointer<float>("color_g" + sn_ext, func) : nullptr;
2185  mColorBHigh = (noise && colors) ? getPointer<float>("color_b" + sn_ext, func) : nullptr;
2186 
2187  /* Liquid. */
2188  mPhi = (liquid) ? getPointer<float>("phi" + s_ext, func) : nullptr;
2189  mFlipParticleData = (liquid) ? getPointer<vector<pData>>("pp" + s_ext, func) : nullptr;
2190  mFlipParticleVelocity = (liquid) ? getPointer<vector<pVel>>("pVel" + pp_ext, func) : nullptr;
2191 
2192  /* Mesh. */
2193  mMeshNodes = (mesh) ? getPointer<vector<Node>>("mesh" + sm_ext, funcNodes) : nullptr;
2194  mMeshTriangles = (mesh) ? getPointer<vector<Triangle>>("mesh" + sm_ext, funcTris) : nullptr;
2195 
2196  /* Mesh velocities. */
2197  mMeshVelocities = (meshvel) ? getPointer<vector<pVel>>("mVel" + mesh_ext, func) : nullptr;
2198 
2199  /* Secondary particles. */
2200  mParticleData = (parts) ? getPointer<vector<pData>>("ppSnd" + snd_ext, func) : nullptr;
2201  mParticleVelocity = (parts) ? getPointer<vector<pVel>>("pVelSnd" + pp_ext, func) : nullptr;
2202  mParticleLife = (parts) ? getPointer<vector<float>>("pLifeSnd" + pp_ext, func) : nullptr;
2203 
2204  mFlipFromFile = false;
2205  mMeshFromFile = false;
2206  mParticlesFromFile = false;
2207  mSmokeFromFile = false;
2208  mNoiseFromFile = false;
2209 }
2210 
2211 bool MANTA::hasConfig(FluidModifierData *fmd, int framenr)
2212 {
2213  string extension = FLUID_DOMAIN_EXTENSION_UNI;
2214  return BLI_exists(
2215  getFile(fmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_NAME_CONFIG, extension, framenr).c_str());
2216 }
2217 
2218 bool MANTA::hasData(FluidModifierData *fmd, int framenr)
2219 {
2220  string extension = getCacheFileEnding(fmd->domain->cache_data_format);
2221  bool exists = BLI_exists(
2222  getFile(fmd, FLUID_DOMAIN_DIR_DATA, FLUID_NAME_DATA, extension, framenr).c_str());
2223 
2224  /* Check single file naming. */
2225  if (!exists) {
2226  string filename = (mUsingSmoke) ? FLUID_NAME_DENSITY : FLUID_NAME_PP;
2227  exists = BLI_exists(getFile(fmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str());
2228  }
2229  if (with_debug)
2230  cout << "Fluid: Has Data: " << exists << endl;
2231 
2232  return exists;
2233 }
2234 
2235 bool MANTA::hasNoise(FluidModifierData *fmd, int framenr)
2236 {
2237  string extension = getCacheFileEnding(fmd->domain->cache_data_format);
2238  bool exists = BLI_exists(
2239  getFile(fmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_NOISE, extension, framenr).c_str());
2240 
2241  /* Check single file naming. */
2242  if (!exists) {
2243  extension = getCacheFileEnding(fmd->domain->cache_data_format);
2244  exists = BLI_exists(
2245  getFile(fmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_DENSITY_NOISE, extension, framenr)
2246  .c_str());
2247  }
2248  /* Check single file naming with deprecated extension. */
2249  if (!exists) {
2250  extension = getCacheFileEnding(fmd->domain->cache_noise_format);
2251  exists = BLI_exists(
2252  getFile(fmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_DENSITY_NOISE, extension, framenr)
2253  .c_str());
2254  }
2255  if (with_debug)
2256  cout << "Fluid: Has Noise: " << exists << endl;
2257 
2258  return exists;
2259 }
2260 
2261 bool MANTA::hasMesh(FluidModifierData *fmd, int framenr)
2262 {
2263  string extension = getCacheFileEnding(fmd->domain->cache_mesh_format);
2264  bool exists = BLI_exists(
2265  getFile(fmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_MESH, extension, framenr).c_str());
2266 
2267  /* Check old file naming. */
2268  if (!exists) {
2269  exists = BLI_exists(
2270  getFile(fmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_LMESH, extension, framenr).c_str());
2271  }
2272  if (with_debug)
2273  cout << "Fluid: Has Mesh: " << exists << endl;
2274 
2275  return exists;
2276 }
2277 
2279 {
2280  string extension = getCacheFileEnding(fmd->domain->cache_data_format);
2281  bool exists = BLI_exists(
2282  getFile(fmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PARTICLES, extension, framenr).c_str());
2283 
2284  /* Check single file naming. */
2285  if (!exists) {
2286  extension = getCacheFileEnding(fmd->domain->cache_data_format);
2287  exists = BLI_exists(
2288  getFile(fmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PP_PARTICLES, extension, framenr)
2289  .c_str());
2290  }
2291  /* Check single file naming with deprecated extension. */
2292  if (!exists) {
2293  extension = getCacheFileEnding(fmd->domain->cache_particle_format);
2294  exists = BLI_exists(
2295  getFile(fmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PP_PARTICLES, extension, framenr)
2296  .c_str());
2297  }
2298  if (with_debug)
2299  cout << "Fluid: Has Particles: " << exists << endl;
2300 
2301  return exists;
2302 }
2303 
2304 bool MANTA::hasGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
2305 {
2306  string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE;
2307  string filename = (sourceDomain) ? FLUID_NAME_DATA : FLUID_NAME_GUIDING;
2308  string extension = getCacheFileEnding(fmd->domain->cache_data_format);
2309  bool exists = BLI_exists(getFile(fmd, subdirectory, filename, extension, framenr).c_str());
2310 
2311  /* Check old file naming. */
2312  if (!exists) {
2313  filename = (sourceDomain) ? FLUID_NAME_VEL : FLUID_NAME_GUIDEVEL;
2314  exists = BLI_exists(getFile(fmd, subdirectory, filename, extension, framenr).c_str());
2315  }
2316 
2317  if (with_debug)
2318  cout << "Fluid: Has Guiding: " << exists << endl;
2319 
2320  return exists;
2321 }
2322 
2323 string MANTA::getDirectory(FluidModifierData *fmd, string subdirectory)
2324 {
2325  char directory[FILE_MAX];
2326  BLI_path_join(
2327  directory, sizeof(directory), fmd->domain->cache_directory, subdirectory.c_str(), nullptr);
2328  BLI_path_make_safe(directory);
2329  return directory;
2330 }
2331 
2332 string MANTA::getFile(
2333  FluidModifierData *fmd, string subdirectory, string fname, string extension, int framenr)
2334 {
2335  char targetFile[FILE_MAX];
2336  string path = getDirectory(fmd, subdirectory);
2337  string filename = fname + "_####" + extension;
2338  BLI_join_dirfile(targetFile, sizeof(targetFile), path.c_str(), filename.c_str());
2339  BLI_path_frame(targetFile, framenr, 0);
2340  return targetFile;
2341 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:314
void * BLI_gzopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:913
bool BLI_dir_create_recursive(const char *dir) ATTR_NONNULL()
Definition: fileops.c:1219
bool BLI_path_make_safe(char *path) ATTR_NONNULL(1)
Definition: path_util.c:314
bool BLI_path_frame(char *path, int frame, int digits) ATTR_NONNULL()
Definition: path_util.c:709
#define FILE_MAX
size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1531
#define MAX3(a, b, c)
#define UNUSED_VARS(...)
#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_NAME_NOISE
#define FLUID_DOMAIN_DIR_DATA
#define FLUID_NAME_PHIPARTS_MESH
#define FLUID_NAME_DATA
#define FLUID_DOMAIN_DIR_PARTICLES
#define FLUID_NAME_PP
#define FLUID_NAME_TMPFLAGS
@ FLUID_DOMAIN_TYPE_GAS
@ FLUID_DOMAIN_TYPE_LIQUID
#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_VEL
@ FLUID_DOMAIN_MESH_IMPROVED
#define FLUID_NAME_PP_PARTICLES
#define FLUID_NAME_KINETICENERGY_PARTICLES
#define FLUID_NAME_FORCE_Y
#define FLUID_NAME_PINDEX
#define FLUID_NAME_PVEL
#define FLUID_NAME_FUELIN
#define FLUID_NAME_PARTICLES
#define FLUID_DOMAIN_EXTENSION_BINOBJ
#define FLUID_NAME_FORCE_Z
#define FLUID_NAME_UV0
#define FLUID_DOMAIN_SMOKE_SCRIPT
#define FLUID_NAME_HEAT
#define FLUID_NAME_GUIDEVEL_Z
#define FLUID_NAME_PVEL_PARTICLES
#define FLUID_NAME_LMESH
#define FLUID_NAME_GUIDEVEL_X
#define FLUID_NAME_TEXTURE_U
#define FLUID_DOMAIN_DIR_MESH
#define FLUID_DOMAIN_DIR_GUIDE
#define FLUID_NAME_PHIIN
#define FLUID_DOMAIN_DIR_SCRIPT
#define FLUID_NAME_PARTSVEL_PARTICLES
#define FLUID_NAME_TMPIN_NOISE
#define FLUID_NAME_PHI
#define FLUID_NAME_OBVEL_X
#define FLUID_NAME_PHIOBS
@ FLUID_DOMAIN_PARTICLE_SPRAY
@ FLUID_DOMAIN_PARTICLE_FOAM
@ FLUID_DOMAIN_PARTICLE_TRACER
@ FLUID_DOMAIN_PARTICLE_BUBBLE
#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_METHOD_APIC
#define FLUID_NAME_VELOCITY_MESH
#define FLUID_NAME_MESH
#define FLUID_DOMAIN_EXTENSION_OBJ
#define FLUID_NAME_INVEL_Z
#define FLUID_NAME_INVELC
@ FLUID_DOMAIN_USE_MESH
@ 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_GUIDE
@ FLUID_DOMAIN_USE_VISCOSITY
@ FLUID_DOMAIN_USE_SPEED_VECTORS
@ FLUID_DOMAIN_USE_NOISE
@ FLUID_DOMAIN_USE_FRACTIONS
@ FLUID_DOMAIN_USE_DISSOLVE
#define FLUID_NAME_FLAGS_NOISE
#define FLUID_NAME_PARTSLIFE_PARTICLES
@ 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_COLORR
#define FLUID_NAME_TEXTURE_U2
#define FLUID_NAME_PHIOUT
@ VDB_PRECISION_MINI_FLOAT
@ VDB_PRECISION_FULL_FLOAT
@ VDB_PRECISION_HALF_FLOAT
#define FLUID_NAME_TEXTURE_V2
#define FLUID_NAME_EMISSIONIN_NOISE
#define FLUID_NAME_GUIDEVEL_Y
#define FLUID_NAME_TEXTURE_W2
#define FLUID_NAME_FUEL
#define FLUID_NAME_DENSITY_NOISE
#define FLUID_NAME_VELT
#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
@ SNDPARTICLE_BOUNDARY_DELETE
@ SNDPARTICLE_BOUNDARY_PUSHOUT
#define FLUID_NAME_SHADOW
#define FLUID_NAME_PARTSVELOCITY
#define FLUID_NAME_OBVEL_Y
@ FLUID_DOMAIN_BORDER_BOTTOM
@ FLUID_DOMAIN_BORDER_LEFT
@ FLUID_DOMAIN_BORDER_RIGHT
@ FLUID_DOMAIN_BORDER_FRONT
@ FLUID_DOMAIN_BORDER_TOP
@ FLUID_DOMAIN_BORDER_BACK
#define FLUID_NAME_VELOCITYVEC_MESH
#define FLUID_NAME_COLORB
#define FLUID_NAME_OBVELC
#define FLUID_NAME_COLORGIN
#define FLUID_NAME_VELOCITY
@ VDB_COMPRESSION_NONE
@ VDB_COMPRESSION_ZIP
@ VDB_COMPRESSION_BLOSC
#define FLUID_NAME_PHIOBSIN
#define FLUID_NAME_PHI_PARTICLES
@ FLUID_DOMAIN_FILE_BIN_OBJECT
@ FLUID_DOMAIN_FILE_RAW
@ FLUID_DOMAIN_FILE_OBJECT
@ FLUID_DOMAIN_FILE_UNI
@ FLUID_DOMAIN_FILE_OPENVDB
#define FLUID_NAME_FORCE_X
#define FLUID_NAME_NEIGHBORRATIO_PARTICLES
#define FLUID_NAME_PARTS_PARTICLES
#define FLUID_NAME_COLORBIN
#define FLUID_NAME_GUIDING
#define FLUID_NAME_DENSITY
#define FLUID_NAME_PARTSFORCE_PARTICLES
#define FLUID_NAME_REACT
#define FLUID_NAME_VELOCITY_GUIDE
#define FLUID_DOMAIN_EXTENSION_UNI
#define FLUID_NAME_TEMPERATUREIN
#define FLUID_NAME_INVEL_X
#define FLUID_NAME_GPI
#define FLUID_NAME_FLAME
#define FLUID_NAME_FLAGS
#define FLUID_NAME_REACTIN
#define FLUID_NAME_PRESSURE
#define FLUID_NAME_MAPWEIGHTS
#define FLUID_NAME_FLAME_NOISE
#define FLUID_NAME_PHIOUT_NOISE
#define FLUID_NAME_VELOCITY_NOISE
#define FLUID_NAME_TEXTURE_W
#define FLUID_NAME_PP_MESH
#define FLUID_DOMAIN_DIR_NOISE
#define FLUID_NAME_OBVEL_Z
#define FLUID_NAME_PHIPARTS
#define FLUID_NAME_NUMGUIDES
#define FLUID_NAME_OBVEL
#define FLUID_NAME_HEATIN
#define FLUID_NAME_UV1
#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_PARTS
#define FLUID_NAME_COLORRIN
#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)
Definition: MANTA_main.cpp:741
static string getCacheFileEnding(char cache_format)
Definition: MANTA_main.cpp:718
static PyObject * manta_main_module
Definition: MANTA_main.cpp:631
static PyObject * manta_python_main_module_ensure()
Definition: MANTA_main.cpp:641
static string escapePath(string const &s)
static void manta_python_main_module_restore(PyObject *main_mod)
Definition: MANTA_main.cpp:617
static PyObject * manta_python_main_module_create(const char *filename)
Definition: MANTA_main.cpp:583
static void manta_python_main_module_clear()
Definition: MANTA_main.cpp:633
static void manta_python_main_module_backup(PyObject **r_main_mod)
Definition: MANTA_main.cpp:610
static void manta_python_main_module_activate(PyObject *mod_main)
Definition: MANTA_main.cpp:598
static T * getPointer(string pyObjectName, string pyFunctionName)
static double pyObjectToDouble(PyObject *inputObject)
static long pyObjectToLong(PyObject *inputObject)
static void * pyObjectToPointer(PyObject *inputObject)
static PyObject * callPythonFunction(string varName, string functionName, bool isAttribute=false)
Read Guarded memory(de)allocation.
FILE * file
SyclQueue void void size_t num_bytes void
#define str(s)
const std::string header_import
Definition: fluid_script.h:793
const std::string fluid_save_guiding
Definition: fluid_script.h:715
const std::string fluid_file_import
Definition: fluid_script.h:629
const std::string fluid_alloc_fractions
Definition: fluid_script.h:325
const std::string fluid_pre_step
Definition: fluid_script.h:355
const std::string header_gridinit
Definition: fluid_script.h:823
const std::string fluid_with_outflow
Definition: fluid_script.h:212
const std::string header_main
Definition: fluid_script.h:775
const std::string fluid_alloc
Definition: fluid_script.h:258
const std::string fluid_bake_data
Definition: fluid_script.h:514
const std::string fluid_standalone
Definition: fluid_script.h:729
const std::string fluid_variables_noise
Definition: fluid_script.h:162
const std::string fluid_with_fractions
Definition: fluid_script.h:204
const std::string header_steps
Definition: fluid_script.h:787
const std::string fluid_alloc_invel
Definition: fluid_script.h:330
const std::string fluid_solver_viscosity
Definition: fluid_script.h:67
const std::string fluid_variables_particles
Definition: fluid_script.h:174
const std::string fluid_with_invel
Definition: fluid_script.h:208
const std::string fluid_solver_particles
Definition: fluid_script.h:57
const std::string fluid_solver_mesh
Definition: fluid_script.h:52
const std::string fluid_alloc_obstacle
Definition: fluid_script.h:288
const std::string manta_import
Definition: fluid_script.h:14
const std::string fluid_load_vel
Definition: fluid_script.h:670
const std::string fluid_file_export
Definition: fluid_script.h:682
const std::string fluid_bake_noise
Definition: fluid_script.h:536
const std::string fluid_alloc_outflow
Definition: fluid_script.h:338
const std::string fluid_bake_guiding
Definition: fluid_script.h:600
const std::string fluid_delete_all
Definition: fluid_script.h:408
const std::string manta_debuglevel
Definition: fluid_script.h:33
const std::string header_grids
Definition: fluid_script.h:799
const std::string fluid_bake_multiprocessing
Definition: fluid_script.h:478
const std::string fluid_with_sndparts
Definition: fluid_script.h:216
const std::string header_time
Definition: fluid_script.h:817
const std::string header_libraries
Definition: fluid_script.h:769
const std::string fluid_variables
Definition: fluid_script.h:76
const std::string header_solvers
Definition: fluid_script.h:805
const std::string fluid_adapt_time_step
Definition: fluid_script.h:236
const std::string header_variables
Definition: fluid_script.h:811
const std::string header_prepost
Definition: fluid_script.h:781
const std::string fluid_solver_noise
Definition: fluid_script.h:47
const std::string fluid_alloc_guiding
Definition: fluid_script.h:307
const std::string fluid_variables_viscosity
Definition: fluid_script.h:192
const std::string fluid_cache_helper
Definition: fluid_script.h:473
const std::string fluid_time_stepping
Definition: fluid_script.h:224
const std::string fluid_bake_mesh
Definition: fluid_script.h:554
const std::string fluid_solver
Definition: fluid_script.h:42
const std::string fluid_bake_particles
Definition: fluid_script.h:578
const std::string fluid_solver_guiding
Definition: fluid_script.h:62
const std::string fluid_post_step
Definition: fluid_script.h:394
const std::string fluid_load_guiding
Definition: fluid_script.h:661
const std::string fluid_variables_guiding
Definition: fluid_script.h:180
const std::string fluid_variables_mesh
Definition: fluid_script.h:168
const std::string fluid_with_obstacle
Definition: fluid_script.h:196
static const char * to_string(const Interpolation &interp)
Definition: gl_shader.cc:63
const std::string liquid_load_data
const std::string liquid_save_data
const std::string liquid_alloc_viscosity
const std::string liquid_variables
Definition: liquid_script.h:14
const std::string liquid_save_particles
const std::string liquid_standalone
const std::string liquid_variables_particles
Definition: liquid_script.h:42
const std::string liquid_load_mesh
const std::string liquid_alloc_particles
const std::string liquid_step
const std::string liquid_alloc
Definition: liquid_script.h:66
const std::string liquid_alloc_curvature
const std::string liquid_adaptive_step
const std::string liquid_load_particles
const std::string liquid_step_mesh
const std::string liquid_step_particles
const std::string liquid_alloc_mesh
Definition: liquid_script.h:97
const std::string liquid_init_phi
const std::string liquid_save_mesh
format
Definition: logImageCore.h:38
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
#define T
static unsigned c
Definition: RandGen.cpp:83
std::string to_string(const T &n)
static float noise(int n)
const std::string smoke_alloc_noise
Definition: smoke_script.h:94
const std::string smoke_alloc_heat
Definition: smoke_script.h:196
const std::string smoke_alloc_colors
Definition: smoke_script.h:139
const std::string smoke_alloc_fire_noise
Definition: smoke_script.h:234
const std::string smoke_save_noise
Definition: smoke_script.h:567
const std::string smoke_adaptive_step
Definition: smoke_script.h:256
const std::string smoke_standalone
Definition: smoke_script.h:581
const std::string smoke_with_colors
Definition: smoke_script.h:53
const std::string smoke_load_data
Definition: smoke_script.h:530
const std::string smoke_with_fire
Definition: smoke_script.h:57
const std::string smoke_with_heat
Definition: smoke_script.h:49
const std::string smoke_variables
Definition: smoke_script.h:14
const std::string smoke_variables_noise
Definition: smoke_script.h:35
const std::string smoke_save_data
Definition: smoke_script.h:555
const std::string smoke_alloc_colors_noise
Definition: smoke_script.h:160
const std::string smoke_load_noise
Definition: smoke_script.h:539
const std::string smoke_init_colors_noise
Definition: smoke_script.h:186
const std::string smoke_step_noise
Definition: smoke_script.h:408
const std::string smoke_init_colors
Definition: smoke_script.h:176
const std::string smoke_wavelet_noise
Definition: smoke_script.h:43
const std::string smoke_alloc_fire
Definition: smoke_script.h:212
const std::string smoke_alloc
Definition: smoke_script.h:65
const std::string smoke_step
Definition: smoke_script.h:328
struct MANTA * fluid
char cache_directory[1024]
struct Object * guide_parent
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)
Definition: MANTA_main.cpp:355
bool hasNoise(FluidModifierData *fmd, int framenr)
bool exportLiquidScript(struct FluidModifierData *fmd)
bool readData(FluidModifierData *fmd, int framenr, bool resumable)
bool initOutflow(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:505
bool writeConfiguration(FluidModifierData *fmd, int framenr)
bool initFire(struct FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:341
bool writeData(FluidModifierData *fmd, int framenr)
static int with_debug
Definition: MANTA_main.h:405
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)
Definition: MANTA_main.cpp:434
bool bakeMesh(FluidModifierData *fmd, int framenr)
bool initLiquid(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:397
bool initFractions(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:482
bool initLiquidMesh(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:423
bool hasMesh(FluidModifierData *fmd, int framenr)
bool initGuiding(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:468
bool readConfiguration(FluidModifierData *fmd, int framenr)
virtual ~MANTA()
Definition: MANTA_main.cpp:543
bool bakeGuiding(FluidModifierData *fmd, int framenr)
static atomic< int > solverID
Definition: MANTA_main.h:404
bool hasParticles(FluidModifierData *fmd, int framenr)
bool initColorsHigh(struct FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:383
bool initObstacle(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:455
float getTimestep()
bool initColors(struct FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:369
bool readNoise(FluidModifierData *fmd, int framenr, bool resumable)
bool initSndParts(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:518
bool initCurvature(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:445
bool hasGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
bool initHeat(struct FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:327
bool bakeParticles(FluidModifierData *fmd, int framenr)
MANTA(int *res, struct FluidModifierData *fmd)
Definition: MANTA_main.cpp:43
bool bakeData(FluidModifierData *fmd, int framenr)
bool initInVelocity(FluidModifierData *fmd=nullptr)
Definition: MANTA_main.cpp:492
void adaptTimestep()
int getFrame()
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)
Definition: MANTA_main.cpp:528