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