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