forked from bartvdbraak/blender
Mantaflow [Part 2]: Added fluid wrapper files
Files from /intern/mantaflow handle the communication between core Blender code and Mantaflow itself. It's the bridge to communicate with Mantas Python functions. Code from /intern/mantaflow/intern/strings/ is pure Manta code and would likely need less attention in the review. Reviewed By: sergey Maniphest Tasks: T59995 Differential Revision: https://developer.blender.org/D3851
This commit is contained in:
parent
4ff7c5eed6
commit
2aa4301c88
67
intern/mantaflow/CMakeLists.txt
Normal file
67
intern/mantaflow/CMakeLists.txt
Normal file
@ -0,0 +1,67 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2019, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Sebastian Barschkis (sebbas)
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
add_definitions(-DWITH_FLUID=1)
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
add_definitions(-DOPENVDB=1)
|
||||
endif()
|
||||
|
||||
set(INC
|
||||
extern
|
||||
intern/strings
|
||||
../../source/blender/makesdna
|
||||
../../source/blender/blenlib
|
||||
)
|
||||
|
||||
# Python is always required
|
||||
add_definitions(-DWITH_PYTHON)
|
||||
|
||||
set(INC_SYS
|
||||
../../extern/mantaflow/helper/util
|
||||
../../extern/mantaflow/helper/pwrapper
|
||||
../../extern/mantaflow/preprocessed
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
${ZLIB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/manta_python_API.cpp
|
||||
intern/manta_fluid_API.cpp
|
||||
intern/MANTA_main.cpp
|
||||
|
||||
extern/manta_python_API.h
|
||||
extern/manta_fluid_API.h
|
||||
intern/MANTA_main.h
|
||||
intern/strings/fluid_script.h
|
||||
intern/strings/smoke_script.h
|
||||
intern/strings/liquid_script.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
extern_mantaflow
|
||||
)
|
||||
|
||||
blender_add_lib(bf_intern_mantaflow "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
232
intern/mantaflow/extern/manta_fluid_API.h
vendored
Normal file
232
intern/mantaflow/extern/manta_fluid_API.h
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Sebastian Barschkis (sebbas)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file mantaflow/extern/manta_smoke_API.h
|
||||
* \ingroup mantaflow
|
||||
*/
|
||||
|
||||
#ifndef MANTA_API_H
|
||||
#define MANTA_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct MANTA;
|
||||
|
||||
/* Fluid functions */
|
||||
struct MANTA *manta_init(int *res, struct FluidModifierData *mmd);
|
||||
void manta_free(struct MANTA *fluid);
|
||||
void manta_ensure_obstacle(struct MANTA *fluid, struct FluidModifierData *mmd);
|
||||
void manta_ensure_guiding(struct MANTA *fluid, struct FluidModifierData *mmd);
|
||||
void manta_ensure_invelocity(struct MANTA *fluid, struct FluidModifierData *mmd);
|
||||
void manta_ensure_outflow(struct MANTA *fluid, struct FluidModifierData *mmd);
|
||||
int manta_write_config(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_write_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_read_config(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_read_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_read_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_read_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_read_particles(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_read_guiding(struct MANTA *fluid,
|
||||
struct FluidModifierData *mmd,
|
||||
int framenr,
|
||||
bool sourceDomain);
|
||||
int manta_update_liquid_structures(struct MANTA *fluid,
|
||||
struct FluidModifierData *mmd,
|
||||
int framenr);
|
||||
int manta_update_mesh_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_update_particle_structures(struct MANTA *fluid,
|
||||
struct FluidModifierData *mmd,
|
||||
int framenr);
|
||||
int manta_bake_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_bake_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_bake_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_bake_particles(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
int manta_bake_guiding(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr);
|
||||
void manta_update_variables(struct MANTA *fluid, struct FluidModifierData *mmd);
|
||||
int manta_get_frame(struct MANTA *fluid);
|
||||
float manta_get_timestep(struct MANTA *fluid);
|
||||
void manta_adapt_timestep(struct MANTA *fluid);
|
||||
bool manta_needs_realloc(struct MANTA *fluid, struct FluidModifierData *mmd);
|
||||
|
||||
/* Fluid accessors */
|
||||
size_t manta_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */);
|
||||
size_t manta_get_index2d(int x, int max_x, int y /*, int max_y, int z, int max_z */);
|
||||
float *manta_get_velocity_x(struct MANTA *fluid);
|
||||
float *manta_get_velocity_y(struct MANTA *fluid);
|
||||
float *manta_get_velocity_z(struct MANTA *fluid);
|
||||
float *manta_get_ob_velocity_x(struct MANTA *fluid);
|
||||
float *manta_get_ob_velocity_y(struct MANTA *fluid);
|
||||
float *manta_get_ob_velocity_z(struct MANTA *fluid);
|
||||
float *manta_get_guide_velocity_x(struct MANTA *fluid);
|
||||
float *manta_get_guide_velocity_y(struct MANTA *fluid);
|
||||
float *manta_get_guide_velocity_z(struct MANTA *fluid);
|
||||
float *manta_get_in_velocity_x(struct MANTA *fluid);
|
||||
float *manta_get_in_velocity_y(struct MANTA *fluid);
|
||||
float *manta_get_in_velocity_z(struct MANTA *fluid);
|
||||
float *manta_get_force_x(struct MANTA *fluid);
|
||||
float *manta_get_force_y(struct MANTA *fluid);
|
||||
float *manta_get_force_z(struct MANTA *fluid);
|
||||
float *manta_get_phiguide_in(struct MANTA *fluid);
|
||||
int *manta_get_num_obstacle(struct MANTA *fluid);
|
||||
int *manta_get_num_guide(struct MANTA *fluid);
|
||||
int manta_get_res_x(struct MANTA *fluid);
|
||||
int manta_get_res_y(struct MANTA *fluid);
|
||||
int manta_get_res_z(struct MANTA *fluid);
|
||||
float *manta_get_phi_in(struct MANTA *fluid);
|
||||
float *manta_get_phiobs_in(struct MANTA *fluid);
|
||||
float *manta_get_phiout_in(struct MANTA *fluid);
|
||||
|
||||
/* Smoke functions */
|
||||
void manta_smoke_export_script(struct MANTA *smoke, struct FluidModifierData *mmd);
|
||||
void manta_smoke_export(struct MANTA *smoke,
|
||||
float *dt,
|
||||
float *dx,
|
||||
float **dens,
|
||||
float **react,
|
||||
float **flame,
|
||||
float **fuel,
|
||||
float **heat,
|
||||
float **vx,
|
||||
float **vy,
|
||||
float **vz,
|
||||
float **r,
|
||||
float **g,
|
||||
float **b,
|
||||
int **obstacles,
|
||||
float **shadow);
|
||||
void manta_smoke_turbulence_export(struct MANTA *smoke,
|
||||
float **dens,
|
||||
float **react,
|
||||
float **flame,
|
||||
float **fuel,
|
||||
float **r,
|
||||
float **g,
|
||||
float **b,
|
||||
float **tcu,
|
||||
float **tcv,
|
||||
float **tcw,
|
||||
float **tcu2,
|
||||
float **tcv2,
|
||||
float **tcw2);
|
||||
void manta_smoke_get_rgba(struct MANTA *smoke, float *data, int sequential);
|
||||
void manta_smoke_turbulence_get_rgba(struct MANTA *smoke, float *data, int sequential);
|
||||
void manta_smoke_get_rgba_from_density(struct MANTA *smoke,
|
||||
float color[3],
|
||||
float *data,
|
||||
int sequential);
|
||||
void manta_smoke_turbulence_get_rgba_from_density(struct MANTA *smoke,
|
||||
float color[3],
|
||||
float *data,
|
||||
int sequential);
|
||||
void manta_smoke_ensure_heat(struct MANTA *smoke, struct FluidModifierData *mmd);
|
||||
void manta_smoke_ensure_fire(struct MANTA *smoke, struct FluidModifierData *mmd);
|
||||
void manta_smoke_ensure_colors(struct MANTA *smoke, struct FluidModifierData *mmd);
|
||||
|
||||
/* Smoke accessors */
|
||||
float *manta_smoke_get_density(struct MANTA *smoke);
|
||||
float *manta_smoke_get_fuel(struct MANTA *smoke);
|
||||
float *manta_smoke_get_react(struct MANTA *smoke);
|
||||
float *manta_smoke_get_heat(struct MANTA *smoke);
|
||||
float *manta_smoke_get_flame(struct MANTA *smoke);
|
||||
float *manta_smoke_get_shadow(struct MANTA *fluid);
|
||||
float *manta_smoke_get_color_r(struct MANTA *smoke);
|
||||
float *manta_smoke_get_color_g(struct MANTA *smoke);
|
||||
float *manta_smoke_get_color_b(struct MANTA *smoke);
|
||||
int *manta_smoke_get_obstacle(struct MANTA *smoke);
|
||||
float *manta_smoke_get_density_in(struct MANTA *smoke);
|
||||
float *manta_smoke_get_heat_in(struct MANTA *smoke);
|
||||
float *manta_smoke_get_color_r_in(struct MANTA *smoke);
|
||||
float *manta_smoke_get_color_g_in(struct MANTA *smoke);
|
||||
float *manta_smoke_get_color_b_in(struct MANTA *smoke);
|
||||
float *manta_smoke_get_fuel_in(struct MANTA *smoke);
|
||||
float *manta_smoke_get_react_in(struct MANTA *smoke);
|
||||
float *manta_smoke_get_emission_in(struct MANTA *smoke);
|
||||
int manta_smoke_has_heat(struct MANTA *smoke);
|
||||
int manta_smoke_has_fuel(struct MANTA *smoke);
|
||||
int manta_smoke_has_colors(struct MANTA *smoke);
|
||||
float *manta_smoke_turbulence_get_density(struct MANTA *smoke);
|
||||
float *manta_smoke_turbulence_get_fuel(struct MANTA *smoke);
|
||||
float *manta_smoke_turbulence_get_react(struct MANTA *smoke);
|
||||
float *manta_smoke_turbulence_get_color_r(struct MANTA *smoke);
|
||||
float *manta_smoke_turbulence_get_color_g(struct MANTA *smoke);
|
||||
float *manta_smoke_turbulence_get_color_b(struct MANTA *smoke);
|
||||
float *manta_smoke_turbulence_get_flame(struct MANTA *smoke);
|
||||
int manta_smoke_turbulence_has_fuel(struct MANTA *smoke);
|
||||
int manta_smoke_turbulence_has_colors(struct MANTA *smoke);
|
||||
void manta_smoke_turbulence_get_res(struct MANTA *smoke, int *res);
|
||||
int manta_smoke_turbulence_get_cells(struct MANTA *smoke);
|
||||
|
||||
/* Liquid functions */
|
||||
void manta_liquid_export_script(struct MANTA *smoke, struct FluidModifierData *mmd);
|
||||
void manta_liquid_ensure_sndparts(struct MANTA *fluid, struct FluidModifierData *mmd);
|
||||
|
||||
/* Liquid accessors */
|
||||
int manta_liquid_get_particle_res_x(struct MANTA *liquid);
|
||||
int manta_liquid_get_particle_res_y(struct MANTA *liquid);
|
||||
int manta_liquid_get_particle_res_z(struct MANTA *liquid);
|
||||
int manta_liquid_get_mesh_res_x(struct MANTA *liquid);
|
||||
int manta_liquid_get_mesh_res_y(struct MANTA *liquid);
|
||||
int manta_liquid_get_mesh_res_z(struct MANTA *liquid);
|
||||
int manta_liquid_get_particle_upres(struct MANTA *liquid);
|
||||
int manta_liquid_get_mesh_upres(struct MANTA *liquid);
|
||||
int manta_liquid_get_num_verts(struct MANTA *liquid);
|
||||
int manta_liquid_get_num_normals(struct MANTA *liquid);
|
||||
int manta_liquid_get_num_triangles(struct MANTA *liquid);
|
||||
float manta_liquid_get_vertex_x_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_vertex_y_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_vertex_z_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_normal_x_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_normal_y_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_normal_z_at(struct MANTA *liquid, int i);
|
||||
int manta_liquid_get_triangle_x_at(struct MANTA *liquid, int i);
|
||||
int manta_liquid_get_triangle_y_at(struct MANTA *liquid, int i);
|
||||
int manta_liquid_get_triangle_z_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_vertvel_x_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_vertvel_y_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_vertvel_z_at(struct MANTA *liquid, int i);
|
||||
int manta_liquid_get_num_flip_particles(struct MANTA *liquid);
|
||||
int manta_liquid_get_num_snd_particles(struct MANTA *liquid);
|
||||
int manta_liquid_get_flip_particle_flag_at(struct MANTA *liquid, int i);
|
||||
int manta_liquid_get_snd_particle_flag_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_flip_particle_position_x_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_flip_particle_position_y_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_flip_particle_position_z_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_flip_particle_velocity_x_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_flip_particle_velocity_y_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_flip_particle_velocity_z_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_snd_particle_position_x_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_snd_particle_position_y_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_snd_particle_position_z_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_snd_particle_velocity_x_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_snd_particle_velocity_y_at(struct MANTA *liquid, int i);
|
||||
float manta_liquid_get_snd_particle_velocity_z_at(struct MANTA *liquid, int i);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MANTA_API_H_ */
|
45
intern/mantaflow/extern/manta_python_API.h
vendored
Normal file
45
intern/mantaflow/extern/manta_python_API.h
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Sebastian Barschkis (sebbas)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file mantaflow/extern/manta_python_API.h
|
||||
* \ingroup mantaflow
|
||||
*/
|
||||
|
||||
#ifndef MANTA_PYTHON_API_H
|
||||
#define MANTA_PYTHON_API_H
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyObject *Manta_initPython(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
2679
intern/mantaflow/intern/MANTA_main.cpp
Normal file
2679
intern/mantaflow/intern/MANTA_main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
850
intern/mantaflow/intern/MANTA_main.h
Normal file
850
intern/mantaflow/intern/MANTA_main.h
Normal file
@ -0,0 +1,850 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Sebastian Barschkis (sebbas)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file mantaflow/intern/MANTA.h
|
||||
* \ingroup mantaflow
|
||||
*/
|
||||
|
||||
#ifndef MANTA_A_H
|
||||
#define MANTA_A_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
struct MANTA {
|
||||
public:
|
||||
MANTA(int *res, struct FluidModifierData *mmd);
|
||||
MANTA(){};
|
||||
virtual ~MANTA();
|
||||
|
||||
// Mirroring Mantaflow structures for particle data (pVel also used for mesh vert vels)
|
||||
typedef struct PData {
|
||||
float pos[3];
|
||||
int flag;
|
||||
} pData;
|
||||
typedef struct PVel {
|
||||
float pos[3];
|
||||
} pVel;
|
||||
|
||||
// Mirroring Mantaflow structures for meshes
|
||||
typedef struct Node {
|
||||
int flags;
|
||||
float pos[3], normal[3];
|
||||
} Node;
|
||||
typedef struct Triangle {
|
||||
int c[3];
|
||||
int flags;
|
||||
} Triangle;
|
||||
|
||||
// Manta step, handling everything
|
||||
void step(struct FluidModifierData *mmd, int startFrame);
|
||||
|
||||
// Grid initialization functions
|
||||
void initHeat(struct FluidModifierData *mmd);
|
||||
void initFire(struct FluidModifierData *mmd);
|
||||
void initColors(struct FluidModifierData *mmd);
|
||||
void initFireHigh(struct FluidModifierData *mmd);
|
||||
void initColorsHigh(struct FluidModifierData *mmd);
|
||||
void initLiquid(FluidModifierData *mmd);
|
||||
void initLiquidMesh(FluidModifierData *mmd);
|
||||
void initObstacle(FluidModifierData *mmd);
|
||||
void initGuiding(FluidModifierData *mmd);
|
||||
void initFractions(FluidModifierData *mmd);
|
||||
void initInVelocity(FluidModifierData *mmd);
|
||||
void initOutflow(FluidModifierData *mmd);
|
||||
void initSndParts(FluidModifierData *mmd);
|
||||
void initLiquidSndParts(FluidModifierData *mmd);
|
||||
|
||||
// Pointer transfer: Mantaflow -> Blender
|
||||
void updatePointers();
|
||||
|
||||
// Write cache
|
||||
int writeConfiguration(FluidModifierData *mmd, int framenr);
|
||||
int writeData(FluidModifierData *mmd, int framenr);
|
||||
// write call for noise, mesh and particles were left in bake calls for now
|
||||
|
||||
// Read cache (via Manta save/load)
|
||||
int readConfiguration(FluidModifierData *mmd, int framenr);
|
||||
int readData(FluidModifierData *mmd, int framenr);
|
||||
int readNoise(FluidModifierData *mmd, int framenr);
|
||||
int readMesh(FluidModifierData *mmd, int framenr);
|
||||
int readParticles(FluidModifierData *mmd, int framenr);
|
||||
int readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain);
|
||||
|
||||
// Read cache (via file read functions in MANTA - e.g. read .bobj.gz meshes, .uni particles)
|
||||
int updateMeshStructures(FluidModifierData *mmd, int framenr);
|
||||
int updateFlipStructures(FluidModifierData *mmd, int framenr);
|
||||
int updateParticleStructures(FluidModifierData *mmd, int framenr);
|
||||
void updateVariables(FluidModifierData *mmd);
|
||||
|
||||
// Bake cache
|
||||
int bakeData(FluidModifierData *mmd, int framenr);
|
||||
int bakeNoise(FluidModifierData *mmd, int framenr);
|
||||
int bakeMesh(FluidModifierData *mmd, int framenr);
|
||||
int bakeParticles(FluidModifierData *mmd, int framenr);
|
||||
int bakeGuiding(FluidModifierData *mmd, int framenr);
|
||||
|
||||
// IO for Mantaflow scene script
|
||||
void exportSmokeScript(struct FluidModifierData *mmd);
|
||||
void exportLiquidScript(struct FluidModifierData *mmd);
|
||||
|
||||
inline size_t getTotalCells()
|
||||
{
|
||||
return mTotalCells;
|
||||
}
|
||||
inline size_t getTotalCellsHigh()
|
||||
{
|
||||
return mTotalCellsHigh;
|
||||
}
|
||||
inline bool usingNoise()
|
||||
{
|
||||
return mUsingNoise;
|
||||
}
|
||||
inline int getResX()
|
||||
{
|
||||
return mResX;
|
||||
}
|
||||
inline int getResY()
|
||||
{
|
||||
return mResY;
|
||||
}
|
||||
inline int getResZ()
|
||||
{
|
||||
return mResZ;
|
||||
}
|
||||
inline int getParticleResX()
|
||||
{
|
||||
return mResXParticle;
|
||||
}
|
||||
inline int getParticleResY()
|
||||
{
|
||||
return mResYParticle;
|
||||
}
|
||||
inline int getParticleResZ()
|
||||
{
|
||||
return mResZParticle;
|
||||
}
|
||||
inline int getMeshResX()
|
||||
{
|
||||
return mResXMesh;
|
||||
}
|
||||
inline int getMeshResY()
|
||||
{
|
||||
return mResYMesh;
|
||||
}
|
||||
inline int getMeshResZ()
|
||||
{
|
||||
return mResZMesh;
|
||||
}
|
||||
inline int getResXHigh()
|
||||
{
|
||||
return mResXNoise;
|
||||
}
|
||||
inline int getResYHigh()
|
||||
{
|
||||
return mResYNoise;
|
||||
}
|
||||
inline int getResZHigh()
|
||||
{
|
||||
return mResZNoise;
|
||||
}
|
||||
inline int getMeshUpres()
|
||||
{
|
||||
return mUpresMesh;
|
||||
}
|
||||
inline int getParticleUpres()
|
||||
{
|
||||
return mUpresParticle;
|
||||
}
|
||||
|
||||
// Smoke getters
|
||||
inline float *getDensity()
|
||||
{
|
||||
return mDensity;
|
||||
}
|
||||
inline float *getHeat()
|
||||
{
|
||||
return mHeat;
|
||||
}
|
||||
inline float *getVelocityX()
|
||||
{
|
||||
return mVelocityX;
|
||||
}
|
||||
inline float *getVelocityY()
|
||||
{
|
||||
return mVelocityY;
|
||||
}
|
||||
inline float *getVelocityZ()
|
||||
{
|
||||
return mVelocityZ;
|
||||
}
|
||||
inline float *getObVelocityX()
|
||||
{
|
||||
return mObVelocityX;
|
||||
}
|
||||
inline float *getObVelocityY()
|
||||
{
|
||||
return mObVelocityY;
|
||||
}
|
||||
inline float *getObVelocityZ()
|
||||
{
|
||||
return mObVelocityZ;
|
||||
}
|
||||
inline float *getGuideVelocityX()
|
||||
{
|
||||
return mGuideVelocityX;
|
||||
}
|
||||
inline float *getGuideVelocityY()
|
||||
{
|
||||
return mGuideVelocityY;
|
||||
}
|
||||
inline float *getGuideVelocityZ()
|
||||
{
|
||||
return mGuideVelocityZ;
|
||||
}
|
||||
inline float *getInVelocityX()
|
||||
{
|
||||
return mInVelocityX;
|
||||
}
|
||||
inline float *getInVelocityY()
|
||||
{
|
||||
return mInVelocityY;
|
||||
}
|
||||
inline float *getInVelocityZ()
|
||||
{
|
||||
return mInVelocityZ;
|
||||
}
|
||||
inline float *getForceX()
|
||||
{
|
||||
return mForceX;
|
||||
}
|
||||
inline float *getForceY()
|
||||
{
|
||||
return mForceY;
|
||||
}
|
||||
inline float *getForceZ()
|
||||
{
|
||||
return mForceZ;
|
||||
}
|
||||
inline int *getObstacle()
|
||||
{
|
||||
return mObstacle;
|
||||
}
|
||||
inline int *getNumObstacle()
|
||||
{
|
||||
return mNumObstacle;
|
||||
}
|
||||
inline int *getNumGuide()
|
||||
{
|
||||
return mNumGuide;
|
||||
}
|
||||
inline float *getFlame()
|
||||
{
|
||||
return mFlame;
|
||||
}
|
||||
inline float *getFuel()
|
||||
{
|
||||
return mFuel;
|
||||
}
|
||||
inline float *getReact()
|
||||
{
|
||||
return mReact;
|
||||
}
|
||||
inline float *getColorR()
|
||||
{
|
||||
return mColorR;
|
||||
}
|
||||
inline float *getColorG()
|
||||
{
|
||||
return mColorG;
|
||||
}
|
||||
inline float *getColorB()
|
||||
{
|
||||
return mColorB;
|
||||
}
|
||||
inline float *getShadow()
|
||||
{
|
||||
return mShadow;
|
||||
}
|
||||
inline float *getDensityIn()
|
||||
{
|
||||
return mDensityIn;
|
||||
}
|
||||
inline float *getHeatIn()
|
||||
{
|
||||
return mHeatIn;
|
||||
}
|
||||
inline float *getColorRIn()
|
||||
{
|
||||
return mColorRIn;
|
||||
}
|
||||
inline float *getColorGIn()
|
||||
{
|
||||
return mColorGIn;
|
||||
}
|
||||
inline float *getColorBIn()
|
||||
{
|
||||
return mColorBIn;
|
||||
}
|
||||
inline float *getFuelIn()
|
||||
{
|
||||
return mFuelIn;
|
||||
}
|
||||
inline float *getReactIn()
|
||||
{
|
||||
return mReactIn;
|
||||
}
|
||||
inline float *getEmissionIn()
|
||||
{
|
||||
return mEmissionIn;
|
||||
}
|
||||
|
||||
inline float *getDensityHigh()
|
||||
{
|
||||
return mDensityHigh;
|
||||
}
|
||||
inline float *getFlameHigh()
|
||||
{
|
||||
return mFlameHigh;
|
||||
}
|
||||
inline float *getFuelHigh()
|
||||
{
|
||||
return mFuelHigh;
|
||||
}
|
||||
inline float *getReactHigh()
|
||||
{
|
||||
return mReactHigh;
|
||||
}
|
||||
inline float *getColorRHigh()
|
||||
{
|
||||
return mColorRHigh;
|
||||
}
|
||||
inline float *getColorGHigh()
|
||||
{
|
||||
return mColorGHigh;
|
||||
}
|
||||
inline float *getColorBHigh()
|
||||
{
|
||||
return mColorBHigh;
|
||||
}
|
||||
inline float *getTextureU()
|
||||
{
|
||||
return mTextureU;
|
||||
}
|
||||
inline float *getTextureV()
|
||||
{
|
||||
return mTextureV;
|
||||
}
|
||||
inline float *getTextureW()
|
||||
{
|
||||
return mTextureW;
|
||||
}
|
||||
inline float *getTextureU2()
|
||||
{
|
||||
return mTextureU2;
|
||||
}
|
||||
inline float *getTextureV2()
|
||||
{
|
||||
return mTextureV2;
|
||||
}
|
||||
inline float *getTextureW2()
|
||||
{
|
||||
return mTextureW2;
|
||||
}
|
||||
|
||||
inline float *getPhiIn()
|
||||
{
|
||||
return mPhiIn;
|
||||
}
|
||||
inline float *getPhiObsIn()
|
||||
{
|
||||
return mPhiObsIn;
|
||||
}
|
||||
inline float *getPhiGuideIn()
|
||||
{
|
||||
return mPhiGuideIn;
|
||||
}
|
||||
inline float *getPhiOutIn()
|
||||
{
|
||||
return mPhiOutIn;
|
||||
}
|
||||
inline float *getPhi()
|
||||
{
|
||||
return mPhi;
|
||||
}
|
||||
|
||||
static std::atomic<bool> mantaInitialized;
|
||||
static std::atomic<int> solverID;
|
||||
static int with_debug; // on or off (1 or 0), also sets manta debug level
|
||||
|
||||
// Mesh getters
|
||||
inline int getNumVertices()
|
||||
{
|
||||
return (mMeshNodes && !mMeshNodes->empty()) ? mMeshNodes->size() : 0;
|
||||
}
|
||||
inline int getNumNormals()
|
||||
{
|
||||
return (mMeshNodes && !mMeshNodes->empty()) ? mMeshNodes->size() : 0;
|
||||
}
|
||||
inline int getNumTriangles()
|
||||
{
|
||||
return (mMeshTriangles && !mMeshTriangles->empty()) ? mMeshTriangles->size() : 0;
|
||||
}
|
||||
|
||||
inline float getVertexXAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshNodes && !mMeshNodes->empty()) {
|
||||
assert(i < mMeshNodes->size());
|
||||
return (*mMeshNodes)[i].pos[0];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getVertexYAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshNodes && !mMeshNodes->empty()) {
|
||||
assert(i < mMeshNodes->size());
|
||||
return (*mMeshNodes)[i].pos[1];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getVertexZAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshNodes && !mMeshNodes->empty()) {
|
||||
assert(i < mMeshNodes->size());
|
||||
return (*mMeshNodes)[i].pos[2];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline float getNormalXAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshNodes && !mMeshNodes->empty()) {
|
||||
assert(i < mMeshNodes->size());
|
||||
return (*mMeshNodes)[i].normal[0];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getNormalYAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshNodes && !mMeshNodes->empty()) {
|
||||
assert(i < mMeshNodes->size());
|
||||
return (*mMeshNodes)[i].normal[1];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getNormalZAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshNodes && !mMeshNodes->empty()) {
|
||||
assert(i < mMeshNodes->size());
|
||||
return (*mMeshNodes)[i].normal[2];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline int getTriangleXAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshTriangles && !mMeshTriangles->empty()) {
|
||||
assert(i < mMeshTriangles->size());
|
||||
return (*mMeshTriangles)[i].c[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline int getTriangleYAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshTriangles && !mMeshTriangles->empty()) {
|
||||
assert(i < mMeshTriangles->size());
|
||||
return (*mMeshTriangles)[i].c[1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline int getTriangleZAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshTriangles && !mMeshTriangles->empty()) {
|
||||
assert(i < mMeshTriangles->size());
|
||||
return (*mMeshTriangles)[i].c[2];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline float getVertVelXAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshVelocities && !mMeshVelocities->empty()) {
|
||||
assert(i < mMeshVelocities->size());
|
||||
return (*mMeshVelocities)[i].pos[0];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getVertVelYAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshVelocities && !mMeshVelocities->empty()) {
|
||||
assert(i < mMeshVelocities->size());
|
||||
return (*mMeshVelocities)[i].pos[1];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getVertVelZAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mMeshVelocities && !mMeshVelocities->empty()) {
|
||||
assert(i < mMeshVelocities->size());
|
||||
return (*mMeshVelocities)[i].pos[2];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// Particle getters
|
||||
inline int getFlipParticleFlagAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mFlipParticleData && !mFlipParticleData->empty()) {
|
||||
assert(i < mFlipParticleData->size());
|
||||
return (*mFlipParticleData)[i].flag;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline int getSndParticleFlagAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mSndParticleData && !mSndParticleData->empty()) {
|
||||
assert(i < mSndParticleData->size());
|
||||
return (*mSndParticleData)[i].flag;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline float getFlipParticlePositionXAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mFlipParticleData && !mFlipParticleData->empty()) {
|
||||
assert(i < mFlipParticleData->size());
|
||||
return (*mFlipParticleData)[i].pos[0];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getFlipParticlePositionYAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mFlipParticleData && !mFlipParticleData->empty()) {
|
||||
assert(i < mFlipParticleData->size());
|
||||
return (*mFlipParticleData)[i].pos[1];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getFlipParticlePositionZAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mFlipParticleData && !mFlipParticleData->empty()) {
|
||||
assert(i < mFlipParticleData->size());
|
||||
return (*mFlipParticleData)[i].pos[2];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline float getSndParticlePositionXAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mSndParticleData && !mSndParticleData->empty()) {
|
||||
assert(i < mSndParticleData->size());
|
||||
return (*mSndParticleData)[i].pos[0];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getSndParticlePositionYAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mSndParticleData && !mSndParticleData->empty()) {
|
||||
assert(i < mSndParticleData->size());
|
||||
return (*mSndParticleData)[i].pos[1];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getSndParticlePositionZAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mSndParticleData && !mSndParticleData->empty()) {
|
||||
assert(i < mSndParticleData->size());
|
||||
return (*mSndParticleData)[i].pos[2];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline float getFlipParticleVelocityXAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mFlipParticleVelocity && !mFlipParticleVelocity->empty()) {
|
||||
assert(i < mFlipParticleVelocity->size());
|
||||
return (*mFlipParticleVelocity)[i].pos[0];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getFlipParticleVelocityYAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mFlipParticleVelocity && !mFlipParticleVelocity->empty()) {
|
||||
assert(i < mFlipParticleVelocity->size());
|
||||
return (*mFlipParticleVelocity)[i].pos[1];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getFlipParticleVelocityZAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mFlipParticleVelocity && !mFlipParticleVelocity->empty()) {
|
||||
assert(i < mFlipParticleVelocity->size());
|
||||
return (*mFlipParticleVelocity)[i].pos[2];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline float getSndParticleVelocityXAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mSndParticleVelocity && !mSndParticleVelocity->empty()) {
|
||||
assert(i < mSndParticleVelocity->size());
|
||||
return (*mSndParticleVelocity)[i].pos[0];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getSndParticleVelocityYAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mSndParticleVelocity && !mSndParticleVelocity->empty()) {
|
||||
assert(i < mSndParticleVelocity->size());
|
||||
return (*mSndParticleVelocity)[i].pos[1];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
inline float getSndParticleVelocityZAt(int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
if (mSndParticleVelocity && !mSndParticleVelocity->empty()) {
|
||||
assert(i < mSndParticleVelocity->size());
|
||||
return (*mSndParticleVelocity)[i].pos[2];
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline float *getFlipParticleData()
|
||||
{
|
||||
return (mFlipParticleData && !mFlipParticleData->empty()) ?
|
||||
(float *)&mFlipParticleData->front() :
|
||||
NULL;
|
||||
}
|
||||
inline float *getSndParticleData()
|
||||
{
|
||||
return (mSndParticleData && !mSndParticleData->empty()) ? (float *)&mSndParticleData->front() :
|
||||
NULL;
|
||||
}
|
||||
|
||||
inline float *getFlipParticleVelocity()
|
||||
{
|
||||
return (mFlipParticleVelocity && !mFlipParticleVelocity->empty()) ?
|
||||
(float *)&mFlipParticleVelocity->front() :
|
||||
NULL;
|
||||
}
|
||||
inline float *getSndParticleVelocity()
|
||||
{
|
||||
return (mSndParticleVelocity && !mSndParticleVelocity->empty()) ?
|
||||
(float *)&mSndParticleVelocity->front() :
|
||||
NULL;
|
||||
}
|
||||
inline float *getSndParticleLife()
|
||||
{
|
||||
return (mSndParticleLife && !mSndParticleLife->empty()) ? (float *)&mSndParticleLife->front() :
|
||||
NULL;
|
||||
}
|
||||
|
||||
inline int getNumFlipParticles()
|
||||
{
|
||||
return (mFlipParticleData && !mFlipParticleData->empty()) ? mFlipParticleData->size() : 0;
|
||||
}
|
||||
inline int getNumSndParticles()
|
||||
{
|
||||
return (mSndParticleData && !mSndParticleData->empty()) ? mSndParticleData->size() : 0;
|
||||
}
|
||||
|
||||
// Direct access to solver time attributes
|
||||
int getFrame();
|
||||
float getTimestep();
|
||||
void adaptTimestep();
|
||||
|
||||
bool needsRealloc(FluidModifierData *mmd);
|
||||
|
||||
private:
|
||||
// simulation constants
|
||||
size_t mTotalCells;
|
||||
size_t mTotalCellsHigh;
|
||||
size_t mTotalCellsMesh;
|
||||
size_t mTotalCellsParticles;
|
||||
|
||||
int mCurrentID;
|
||||
|
||||
bool mUsingHeat;
|
||||
bool mUsingColors;
|
||||
bool mUsingFire;
|
||||
bool mUsingObstacle;
|
||||
bool mUsingGuiding;
|
||||
bool mUsingFractions;
|
||||
bool mUsingInvel;
|
||||
bool mUsingOutflow;
|
||||
bool mUsingNoise;
|
||||
bool mUsingMesh;
|
||||
bool mUsingMVel;
|
||||
bool mUsingLiquid;
|
||||
bool mUsingSmoke;
|
||||
bool mUsingDrops;
|
||||
bool mUsingBubbles;
|
||||
bool mUsingFloats;
|
||||
bool mUsingTracers;
|
||||
|
||||
int mResX;
|
||||
int mResY;
|
||||
int mResZ;
|
||||
int mMaxRes;
|
||||
|
||||
int mResXNoise;
|
||||
int mResYNoise;
|
||||
int mResZNoise;
|
||||
int mResXMesh;
|
||||
int mResYMesh;
|
||||
int mResZMesh;
|
||||
int mResXParticle;
|
||||
int mResYParticle;
|
||||
int mResZParticle;
|
||||
int *mResGuiding;
|
||||
|
||||
int mUpresMesh;
|
||||
int mUpresParticle;
|
||||
|
||||
float mTempAmb; /* ambient temperature */
|
||||
float mConstantScaling;
|
||||
|
||||
// Fluid grids
|
||||
float *mVelocityX;
|
||||
float *mVelocityY;
|
||||
float *mVelocityZ;
|
||||
float *mObVelocityX;
|
||||
float *mObVelocityY;
|
||||
float *mObVelocityZ;
|
||||
float *mGuideVelocityX;
|
||||
float *mGuideVelocityY;
|
||||
float *mGuideVelocityZ;
|
||||
float *mInVelocityX;
|
||||
float *mInVelocityY;
|
||||
float *mInVelocityZ;
|
||||
float *mForceX;
|
||||
float *mForceY;
|
||||
float *mForceZ;
|
||||
int *mObstacle;
|
||||
int *mNumObstacle;
|
||||
int *mNumGuide;
|
||||
|
||||
// Smoke grids
|
||||
float *mDensity;
|
||||
float *mHeat;
|
||||
float *mFlame;
|
||||
float *mFuel;
|
||||
float *mReact;
|
||||
float *mColorR;
|
||||
float *mColorG;
|
||||
float *mColorB;
|
||||
float *mShadow;
|
||||
float *mDensityIn;
|
||||
float *mHeatIn;
|
||||
float *mFuelIn;
|
||||
float *mReactIn;
|
||||
float *mEmissionIn;
|
||||
float *mColorRIn;
|
||||
float *mColorGIn;
|
||||
float *mColorBIn;
|
||||
float *mDensityHigh;
|
||||
float *mFlameHigh;
|
||||
float *mFuelHigh;
|
||||
float *mReactHigh;
|
||||
float *mColorRHigh;
|
||||
float *mColorGHigh;
|
||||
float *mColorBHigh;
|
||||
float *mTextureU;
|
||||
float *mTextureV;
|
||||
float *mTextureW;
|
||||
float *mTextureU2;
|
||||
float *mTextureV2;
|
||||
float *mTextureW2;
|
||||
|
||||
// Liquid grids
|
||||
float *mPhiIn;
|
||||
float *mPhiObsIn;
|
||||
float *mPhiGuideIn;
|
||||
float *mPhiOutIn;
|
||||
float *mPhi;
|
||||
|
||||
// Mesh fields
|
||||
std::vector<Node> *mMeshNodes;
|
||||
std::vector<Triangle> *mMeshTriangles;
|
||||
std::vector<pVel> *mMeshVelocities;
|
||||
|
||||
// Particle fields
|
||||
std::vector<pData> *mFlipParticleData;
|
||||
std::vector<pVel> *mFlipParticleVelocity;
|
||||
|
||||
std::vector<pData> *mSndParticleData;
|
||||
std::vector<pVel> *mSndParticleVelocity;
|
||||
std::vector<float> *mSndParticleLife;
|
||||
|
||||
void initDomain(struct FluidModifierData *mmd);
|
||||
void initNoise(struct FluidModifierData *mmd);
|
||||
void initMesh(struct FluidModifierData *mmd);
|
||||
void initSmoke(struct FluidModifierData *mmd);
|
||||
void initSmokeNoise(struct FluidModifierData *mmd);
|
||||
void initializeMantaflow();
|
||||
void terminateMantaflow();
|
||||
void runPythonString(std::vector<std::string> commands);
|
||||
std::string getRealValue(const std::string &varName, FluidModifierData *mmd);
|
||||
std::string parseLine(const std::string &line, FluidModifierData *mmd);
|
||||
std::string parseScript(const std::string &setup_string, FluidModifierData *mmd = NULL);
|
||||
void updateMeshFromBobj(const char *filename);
|
||||
void updateMeshFromObj(const char *filename);
|
||||
void updateMeshFromUni(const char *filename);
|
||||
void updateParticlesFromUni(const char *filename, bool isSecondarySys, bool isVelData);
|
||||
void updateMeshFromFile(const char *filename);
|
||||
void updateParticlesFromFile(const char *filename, bool isSecondarySys, bool isVelData);
|
||||
template<class T>
|
||||
void setPointers(std::vector<std::tuple<T **, std::string, std::string, bool>>);
|
||||
};
|
||||
|
||||
#endif
|
872
intern/mantaflow/intern/manta_fluid_API.cpp
Normal file
872
intern/mantaflow/intern/manta_fluid_API.cpp
Normal file
@ -0,0 +1,872 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Sebastian Barschkis (sebbas)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file mantaflow/intern/manta_smoke_API.cpp
|
||||
* \ingroup mantaflow
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "MANTA_main.h"
|
||||
#include "manta_fluid_API.h"
|
||||
|
||||
/* Fluid functions */
|
||||
MANTA *manta_init(int *res, struct FluidModifierData *mmd)
|
||||
{
|
||||
return new MANTA(res, mmd);
|
||||
}
|
||||
void manta_free(MANTA *fluid)
|
||||
{
|
||||
delete fluid;
|
||||
fluid = nullptr;
|
||||
}
|
||||
|
||||
void manta_ensure_obstacle(MANTA *fluid, struct FluidModifierData *mmd)
|
||||
{
|
||||
if (!fluid)
|
||||
return;
|
||||
fluid->initObstacle(mmd);
|
||||
fluid->updatePointers();
|
||||
}
|
||||
void manta_ensure_guiding(MANTA *fluid, struct FluidModifierData *mmd)
|
||||
{
|
||||
if (!fluid)
|
||||
return;
|
||||
fluid->initGuiding(mmd);
|
||||
fluid->updatePointers();
|
||||
}
|
||||
void manta_ensure_invelocity(MANTA *fluid, struct FluidModifierData *mmd)
|
||||
{
|
||||
if (!fluid)
|
||||
return;
|
||||
fluid->initInVelocity(mmd);
|
||||
fluid->updatePointers();
|
||||
}
|
||||
void manta_ensure_outflow(MANTA *fluid, struct FluidModifierData *mmd)
|
||||
{
|
||||
if (!fluid)
|
||||
return;
|
||||
fluid->initOutflow(mmd);
|
||||
fluid->updatePointers();
|
||||
}
|
||||
|
||||
int manta_write_config(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->writeConfiguration(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_write_data(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->writeData(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_read_config(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->readConfiguration(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_read_data(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->readData(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_read_noise(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->readNoise(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_read_mesh(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->readMesh(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_read_particles(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->readParticles(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_read_guiding(MANTA *fluid, FluidModifierData *mmd, int framenr, bool sourceDomain)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->readGuiding(mmd, framenr, sourceDomain);
|
||||
}
|
||||
|
||||
int manta_update_liquid_structures(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->updateFlipStructures(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_update_mesh_structures(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->updateMeshStructures(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_update_particle_structures(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->updateParticleStructures(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_bake_data(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->bakeData(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_bake_noise(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->bakeNoise(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_bake_mesh(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->bakeMesh(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_bake_particles(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->bakeParticles(mmd, framenr);
|
||||
}
|
||||
|
||||
int manta_bake_guiding(MANTA *fluid, FluidModifierData *mmd, int framenr)
|
||||
{
|
||||
if (!fluid || !mmd)
|
||||
return 0;
|
||||
return fluid->bakeGuiding(mmd, framenr);
|
||||
}
|
||||
|
||||
void manta_update_variables(MANTA *fluid, FluidModifierData *mmd)
|
||||
{
|
||||
if (!fluid)
|
||||
return;
|
||||
fluid->updateVariables(mmd);
|
||||
}
|
||||
|
||||
int manta_get_frame(MANTA *fluid)
|
||||
{
|
||||
if (!fluid)
|
||||
return 0;
|
||||
return fluid->getFrame();
|
||||
}
|
||||
|
||||
float manta_get_timestep(MANTA *fluid)
|
||||
{
|
||||
if (!fluid)
|
||||
return 0;
|
||||
return fluid->getTimestep();
|
||||
}
|
||||
|
||||
void manta_adapt_timestep(MANTA *fluid)
|
||||
{
|
||||
if (!fluid)
|
||||
return;
|
||||
fluid->adaptTimestep();
|
||||
}
|
||||
|
||||
bool manta_needs_realloc(MANTA *fluid, FluidModifierData *mmd)
|
||||
{
|
||||
if (!fluid)
|
||||
return false;
|
||||
return fluid->needsRealloc(mmd);
|
||||
}
|
||||
|
||||
/* Fluid accessors */
|
||||
size_t manta_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */)
|
||||
{
|
||||
return x + y * max_x + z * max_x * max_y;
|
||||
}
|
||||
size_t manta_get_index2d(int x, int max_x, int y /*, int max_y, int z, int max_z */)
|
||||
{
|
||||
return x + y * max_x;
|
||||
}
|
||||
float *manta_get_velocity_x(MANTA *fluid)
|
||||
{
|
||||
return fluid->getVelocityX();
|
||||
}
|
||||
float *manta_get_velocity_y(MANTA *fluid)
|
||||
{
|
||||
return fluid->getVelocityY();
|
||||
}
|
||||
float *manta_get_velocity_z(MANTA *fluid)
|
||||
{
|
||||
return fluid->getVelocityZ();
|
||||
}
|
||||
|
||||
float *manta_get_ob_velocity_x(MANTA *fluid)
|
||||
{
|
||||
return fluid->getObVelocityX();
|
||||
}
|
||||
float *manta_get_ob_velocity_y(MANTA *fluid)
|
||||
{
|
||||
return fluid->getObVelocityY();
|
||||
}
|
||||
float *manta_get_ob_velocity_z(MANTA *fluid)
|
||||
{
|
||||
return fluid->getObVelocityZ();
|
||||
}
|
||||
|
||||
float *manta_get_guide_velocity_x(MANTA *fluid)
|
||||
{
|
||||
return fluid->getGuideVelocityX();
|
||||
}
|
||||
float *manta_get_guide_velocity_y(MANTA *fluid)
|
||||
{
|
||||
return fluid->getGuideVelocityY();
|
||||
}
|
||||
float *manta_get_guide_velocity_z(MANTA *fluid)
|
||||
{
|
||||
return fluid->getGuideVelocityZ();
|
||||
}
|
||||
|
||||
float *manta_get_in_velocity_x(MANTA *fluid)
|
||||
{
|
||||
return fluid->getInVelocityX();
|
||||
}
|
||||
float *manta_get_in_velocity_y(MANTA *fluid)
|
||||
{
|
||||
return fluid->getInVelocityY();
|
||||
}
|
||||
float *manta_get_in_velocity_z(MANTA *fluid)
|
||||
{
|
||||
return fluid->getInVelocityZ();
|
||||
}
|
||||
|
||||
float *manta_get_force_x(MANTA *fluid)
|
||||
{
|
||||
return fluid->getForceX();
|
||||
}
|
||||
float *manta_get_force_y(MANTA *fluid)
|
||||
{
|
||||
return fluid->getForceY();
|
||||
}
|
||||
float *manta_get_force_z(MANTA *fluid)
|
||||
{
|
||||
return fluid->getForceZ();
|
||||
}
|
||||
|
||||
float *manta_get_phiguide_in(MANTA *fluid)
|
||||
{
|
||||
return fluid->getPhiGuideIn();
|
||||
}
|
||||
|
||||
int *manta_get_num_obstacle(MANTA *fluid)
|
||||
{
|
||||
return fluid->getNumObstacle();
|
||||
}
|
||||
int *manta_get_num_guide(MANTA *fluid)
|
||||
{
|
||||
return fluid->getNumGuide();
|
||||
}
|
||||
|
||||
int manta_get_res_x(MANTA *fluid)
|
||||
{
|
||||
return fluid->getResX();
|
||||
}
|
||||
int manta_get_res_y(MANTA *fluid)
|
||||
{
|
||||
return fluid->getResY();
|
||||
}
|
||||
int manta_get_res_z(MANTA *fluid)
|
||||
{
|
||||
return fluid->getResZ();
|
||||
}
|
||||
|
||||
float *manta_get_phi_in(MANTA *fluid)
|
||||
{
|
||||
return fluid->getPhiIn();
|
||||
}
|
||||
float *manta_get_phiobs_in(MANTA *fluid)
|
||||
{
|
||||
return fluid->getPhiObsIn();
|
||||
}
|
||||
float *manta_get_phiout_in(MANTA *fluid)
|
||||
{
|
||||
return fluid->getPhiOutIn();
|
||||
}
|
||||
|
||||
/* Smoke functions */
|
||||
void manta_smoke_export_script(MANTA *smoke, FluidModifierData *mmd)
|
||||
{
|
||||
if (!smoke || !mmd)
|
||||
return;
|
||||
smoke->exportSmokeScript(mmd);
|
||||
}
|
||||
|
||||
void manta_smoke_export(MANTA *smoke,
|
||||
float *dt,
|
||||
float *dx,
|
||||
float **dens,
|
||||
float **react,
|
||||
float **flame,
|
||||
float **fuel,
|
||||
float **heat,
|
||||
float **vx,
|
||||
float **vy,
|
||||
float **vz,
|
||||
float **r,
|
||||
float **g,
|
||||
float **b,
|
||||
int **obstacle,
|
||||
float **shadow)
|
||||
{
|
||||
if (dens)
|
||||
*dens = smoke->getDensity();
|
||||
if (fuel)
|
||||
*fuel = smoke->getFuel();
|
||||
if (react)
|
||||
*react = smoke->getReact();
|
||||
if (flame)
|
||||
*flame = smoke->getFlame();
|
||||
if (heat)
|
||||
*heat = smoke->getHeat();
|
||||
*vx = smoke->getVelocityX();
|
||||
*vy = smoke->getVelocityY();
|
||||
*vz = smoke->getVelocityZ();
|
||||
if (r)
|
||||
*r = smoke->getColorR();
|
||||
if (g)
|
||||
*g = smoke->getColorG();
|
||||
if (b)
|
||||
*b = smoke->getColorB();
|
||||
*obstacle = smoke->getObstacle();
|
||||
*shadow = smoke->getShadow();
|
||||
*dt = 1; // dummy value, not needed for smoke
|
||||
*dx = 1; // dummy value, not needed for smoke
|
||||
}
|
||||
|
||||
void manta_smoke_turbulence_export(MANTA *smoke,
|
||||
float **dens,
|
||||
float **react,
|
||||
float **flame,
|
||||
float **fuel,
|
||||
float **r,
|
||||
float **g,
|
||||
float **b,
|
||||
float **tcu,
|
||||
float **tcv,
|
||||
float **tcw,
|
||||
float **tcu2,
|
||||
float **tcv2,
|
||||
float **tcw2)
|
||||
{
|
||||
if (!smoke && !(smoke->usingNoise()))
|
||||
return;
|
||||
|
||||
*dens = smoke->getDensityHigh();
|
||||
if (fuel)
|
||||
*fuel = smoke->getFuelHigh();
|
||||
if (react)
|
||||
*react = smoke->getReactHigh();
|
||||
if (flame)
|
||||
*flame = smoke->getFlameHigh();
|
||||
if (r)
|
||||
*r = smoke->getColorRHigh();
|
||||
if (g)
|
||||
*g = smoke->getColorGHigh();
|
||||
if (b)
|
||||
*b = smoke->getColorBHigh();
|
||||
*tcu = smoke->getTextureU();
|
||||
*tcv = smoke->getTextureV();
|
||||
*tcw = smoke->getTextureW();
|
||||
|
||||
*tcu2 = smoke->getTextureU2();
|
||||
*tcv2 = smoke->getTextureV2();
|
||||
*tcw2 = smoke->getTextureW2();
|
||||
}
|
||||
|
||||
static void get_rgba(
|
||||
float *r, float *g, float *b, float *a, int total_cells, float *data, int sequential)
|
||||
{
|
||||
int i;
|
||||
/* Use offsets to map RGB grids to to correct location in data grid. */
|
||||
int m = 4, i_g = 1, i_b = 2, i_a = 3;
|
||||
if (sequential) {
|
||||
m = 1;
|
||||
i_g *= total_cells;
|
||||
i_b *= total_cells;
|
||||
i_a *= total_cells;
|
||||
}
|
||||
|
||||
for (i = 0; i < total_cells; i++) {
|
||||
float alpha = a[i];
|
||||
if (alpha) {
|
||||
data[i * m] = r[i];
|
||||
data[i * m + i_g] = g[i];
|
||||
data[i * m + i_b] = b[i];
|
||||
}
|
||||
else {
|
||||
data[i * m] = data[i * m + i_g] = data[i * m + i_b] = 0.0f;
|
||||
}
|
||||
data[i * m + i_a] = alpha;
|
||||
}
|
||||
}
|
||||
|
||||
void manta_smoke_get_rgba(MANTA *smoke, float *data, int sequential)
|
||||
{
|
||||
get_rgba(smoke->getColorR(),
|
||||
smoke->getColorG(),
|
||||
smoke->getColorB(),
|
||||
smoke->getDensity(),
|
||||
smoke->getTotalCells(),
|
||||
data,
|
||||
sequential);
|
||||
}
|
||||
|
||||
void manta_smoke_turbulence_get_rgba(MANTA *smoke, float *data, int sequential)
|
||||
{
|
||||
get_rgba(smoke->getColorRHigh(),
|
||||
smoke->getColorGHigh(),
|
||||
smoke->getColorBHigh(),
|
||||
smoke->getDensityHigh(),
|
||||
smoke->getTotalCellsHigh(),
|
||||
data,
|
||||
sequential);
|
||||
}
|
||||
|
||||
static void get_rgba_from_density(
|
||||
float color[3], float *a, int total_cells, float *data, int sequential)
|
||||
{
|
||||
int i;
|
||||
int m = 4, i_g = 1, i_b = 2, i_a = 3;
|
||||
if (sequential) {
|
||||
m = 1;
|
||||
i_g *= total_cells;
|
||||
i_b *= total_cells;
|
||||
i_a *= total_cells;
|
||||
}
|
||||
|
||||
for (i = 0; i < total_cells; i++) {
|
||||
float alpha = a[i];
|
||||
if (alpha) {
|
||||
data[i * m] = color[0] * alpha;
|
||||
data[i * m + i_g] = color[1] * alpha;
|
||||
data[i * m + i_b] = color[2] * alpha;
|
||||
}
|
||||
else {
|
||||
data[i * m] = data[i * m + i_g] = data[i * m + i_b] = 0.0f;
|
||||
}
|
||||
data[i * m + i_a] = alpha;
|
||||
}
|
||||
}
|
||||
|
||||
void manta_smoke_get_rgba_from_density(MANTA *smoke, float color[3], float *data, int sequential)
|
||||
{
|
||||
get_rgba_from_density(color, smoke->getDensity(), smoke->getTotalCells(), data, sequential);
|
||||
}
|
||||
|
||||
void manta_smoke_turbulence_get_rgba_from_density(MANTA *smoke,
|
||||
float color[3],
|
||||
float *data,
|
||||
int sequential)
|
||||
{
|
||||
get_rgba_from_density(
|
||||
color, smoke->getDensityHigh(), smoke->getTotalCellsHigh(), data, sequential);
|
||||
}
|
||||
|
||||
void manta_smoke_ensure_heat(MANTA *smoke, struct FluidModifierData *mmd)
|
||||
{
|
||||
if (smoke) {
|
||||
smoke->initHeat(mmd);
|
||||
smoke->updatePointers();
|
||||
}
|
||||
}
|
||||
|
||||
void manta_smoke_ensure_fire(MANTA *smoke, struct FluidModifierData *mmd)
|
||||
{
|
||||
if (smoke) {
|
||||
smoke->initFire(mmd);
|
||||
if (smoke->usingNoise()) {
|
||||
smoke->initFireHigh(mmd);
|
||||
}
|
||||
smoke->updatePointers();
|
||||
}
|
||||
}
|
||||
|
||||
void manta_smoke_ensure_colors(MANTA *smoke, struct FluidModifierData *mmd)
|
||||
{
|
||||
if (smoke) {
|
||||
smoke->initColors(mmd);
|
||||
if (smoke->usingNoise()) {
|
||||
smoke->initColorsHigh(mmd);
|
||||
}
|
||||
smoke->updatePointers();
|
||||
}
|
||||
}
|
||||
|
||||
/* Smoke accessors */
|
||||
float *manta_smoke_get_density(MANTA *smoke)
|
||||
{
|
||||
return smoke->getDensity();
|
||||
}
|
||||
float *manta_smoke_get_fuel(MANTA *smoke)
|
||||
{
|
||||
return smoke->getFuel();
|
||||
}
|
||||
float *manta_smoke_get_react(MANTA *smoke)
|
||||
{
|
||||
return smoke->getReact();
|
||||
}
|
||||
float *manta_smoke_get_heat(MANTA *smoke)
|
||||
{
|
||||
return smoke->getHeat();
|
||||
}
|
||||
float *manta_smoke_get_flame(MANTA *smoke)
|
||||
{
|
||||
return smoke->getFlame();
|
||||
}
|
||||
float *manta_smoke_get_shadow(MANTA *fluid)
|
||||
{
|
||||
return fluid->getShadow();
|
||||
}
|
||||
|
||||
float *manta_smoke_get_color_r(MANTA *smoke)
|
||||
{
|
||||
return smoke->getColorR();
|
||||
}
|
||||
float *manta_smoke_get_color_g(MANTA *smoke)
|
||||
{
|
||||
return smoke->getColorG();
|
||||
}
|
||||
float *manta_smoke_get_color_b(MANTA *smoke)
|
||||
{
|
||||
return smoke->getColorB();
|
||||
}
|
||||
|
||||
int *manta_smoke_get_obstacle(MANTA *smoke)
|
||||
{
|
||||
return smoke->getObstacle();
|
||||
}
|
||||
|
||||
float *manta_smoke_get_density_in(MANTA *smoke)
|
||||
{
|
||||
return smoke->getDensityIn();
|
||||
}
|
||||
float *manta_smoke_get_heat_in(MANTA *smoke)
|
||||
{
|
||||
return smoke->getHeatIn();
|
||||
}
|
||||
float *manta_smoke_get_color_r_in(MANTA *smoke)
|
||||
{
|
||||
return smoke->getColorRIn();
|
||||
}
|
||||
float *manta_smoke_get_color_g_in(MANTA *smoke)
|
||||
{
|
||||
return smoke->getColorGIn();
|
||||
}
|
||||
float *manta_smoke_get_color_b_in(MANTA *smoke)
|
||||
{
|
||||
return smoke->getColorBIn();
|
||||
}
|
||||
float *manta_smoke_get_fuel_in(MANTA *smoke)
|
||||
{
|
||||
return smoke->getFuelIn();
|
||||
}
|
||||
float *manta_smoke_get_react_in(MANTA *smoke)
|
||||
{
|
||||
return smoke->getReactIn();
|
||||
}
|
||||
float *manta_smoke_get_emission_in(MANTA *smoke)
|
||||
{
|
||||
return smoke->getEmissionIn();
|
||||
}
|
||||
|
||||
int manta_smoke_has_heat(MANTA *smoke)
|
||||
{
|
||||
return (smoke->getHeat()) ? 1 : 0;
|
||||
}
|
||||
int manta_smoke_has_fuel(MANTA *smoke)
|
||||
{
|
||||
return (smoke->getFuel()) ? 1 : 0;
|
||||
}
|
||||
int manta_smoke_has_colors(MANTA *smoke)
|
||||
{
|
||||
return (smoke->getColorR() && smoke->getColorG() && smoke->getColorB()) ? 1 : 0;
|
||||
}
|
||||
|
||||
float *manta_smoke_turbulence_get_density(MANTA *smoke)
|
||||
{
|
||||
return (smoke && smoke->usingNoise()) ? smoke->getDensityHigh() : nullptr;
|
||||
}
|
||||
float *manta_smoke_turbulence_get_fuel(MANTA *smoke)
|
||||
{
|
||||
return (smoke && smoke->usingNoise()) ? smoke->getFuelHigh() : nullptr;
|
||||
}
|
||||
float *manta_smoke_turbulence_get_react(MANTA *smoke)
|
||||
{
|
||||
return (smoke && smoke->usingNoise()) ? smoke->getReactHigh() : nullptr;
|
||||
}
|
||||
float *manta_smoke_turbulence_get_color_r(MANTA *smoke)
|
||||
{
|
||||
return (smoke && smoke->usingNoise()) ? smoke->getColorRHigh() : nullptr;
|
||||
}
|
||||
float *manta_smoke_turbulence_get_color_g(MANTA *smoke)
|
||||
{
|
||||
return (smoke && smoke->usingNoise()) ? smoke->getColorGHigh() : nullptr;
|
||||
}
|
||||
float *manta_smoke_turbulence_get_color_b(MANTA *smoke)
|
||||
{
|
||||
return (smoke && smoke->usingNoise()) ? smoke->getColorBHigh() : nullptr;
|
||||
}
|
||||
float *manta_smoke_turbulence_get_flame(MANTA *smoke)
|
||||
{
|
||||
return (smoke && smoke->usingNoise()) ? smoke->getFlameHigh() : nullptr;
|
||||
}
|
||||
|
||||
int manta_smoke_turbulence_has_fuel(MANTA *smoke)
|
||||
{
|
||||
return (smoke->getFuelHigh()) ? 1 : 0;
|
||||
}
|
||||
int manta_smoke_turbulence_has_colors(MANTA *smoke)
|
||||
{
|
||||
return (smoke->getColorRHigh() && smoke->getColorGHigh() && smoke->getColorBHigh()) ? 1 : 0;
|
||||
}
|
||||
|
||||
void manta_smoke_turbulence_get_res(MANTA *smoke, int *res)
|
||||
{
|
||||
if (smoke && smoke->usingNoise()) {
|
||||
res[0] = smoke->getResXHigh();
|
||||
res[1] = smoke->getResYHigh();
|
||||
res[2] = smoke->getResZHigh();
|
||||
}
|
||||
}
|
||||
int manta_smoke_turbulence_get_cells(MANTA *smoke)
|
||||
{
|
||||
int total_cells_high = smoke->getResXHigh() * smoke->getResYHigh() * smoke->getResZHigh();
|
||||
return (smoke && smoke->usingNoise()) ? total_cells_high : 0;
|
||||
}
|
||||
|
||||
/* Liquid functions */
|
||||
void manta_liquid_export_script(MANTA *liquid, FluidModifierData *mmd)
|
||||
{
|
||||
if (!liquid || !mmd)
|
||||
return;
|
||||
liquid->exportLiquidScript(mmd);
|
||||
}
|
||||
|
||||
void manta_liquid_ensure_sndparts(MANTA *liquid, struct FluidModifierData *mmd)
|
||||
{
|
||||
if (liquid) {
|
||||
liquid->initLiquidSndParts(mmd);
|
||||
liquid->updatePointers();
|
||||
}
|
||||
}
|
||||
|
||||
/* Liquid accessors */
|
||||
int manta_liquid_get_particle_res_x(MANTA *liquid)
|
||||
{
|
||||
return liquid->getParticleResX();
|
||||
}
|
||||
int manta_liquid_get_particle_res_y(MANTA *liquid)
|
||||
{
|
||||
return liquid->getParticleResY();
|
||||
}
|
||||
int manta_liquid_get_particle_res_z(MANTA *liquid)
|
||||
{
|
||||
return liquid->getParticleResZ();
|
||||
}
|
||||
|
||||
int manta_liquid_get_mesh_res_x(MANTA *liquid)
|
||||
{
|
||||
return liquid->getMeshResX();
|
||||
}
|
||||
int manta_liquid_get_mesh_res_y(MANTA *liquid)
|
||||
{
|
||||
return liquid->getMeshResY();
|
||||
}
|
||||
int manta_liquid_get_mesh_res_z(MANTA *liquid)
|
||||
{
|
||||
return liquid->getMeshResZ();
|
||||
}
|
||||
|
||||
int manta_liquid_get_particle_upres(MANTA *liquid)
|
||||
{
|
||||
return liquid->getParticleUpres();
|
||||
}
|
||||
int manta_liquid_get_mesh_upres(MANTA *liquid)
|
||||
{
|
||||
return liquid->getMeshUpres();
|
||||
}
|
||||
|
||||
int manta_liquid_get_num_verts(MANTA *liquid)
|
||||
{
|
||||
return liquid->getNumVertices();
|
||||
}
|
||||
int manta_liquid_get_num_normals(MANTA *liquid)
|
||||
{
|
||||
return liquid->getNumNormals();
|
||||
}
|
||||
int manta_liquid_get_num_triangles(MANTA *liquid)
|
||||
{
|
||||
return liquid->getNumTriangles();
|
||||
}
|
||||
|
||||
float manta_liquid_get_vertex_x_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getVertexXAt(i);
|
||||
}
|
||||
float manta_liquid_get_vertex_y_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getVertexYAt(i);
|
||||
}
|
||||
float manta_liquid_get_vertex_z_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getVertexZAt(i);
|
||||
}
|
||||
|
||||
float manta_liquid_get_normal_x_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getNormalXAt(i);
|
||||
}
|
||||
float manta_liquid_get_normal_y_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getNormalYAt(i);
|
||||
}
|
||||
float manta_liquid_get_normal_z_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getNormalZAt(i);
|
||||
}
|
||||
|
||||
int manta_liquid_get_triangle_x_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getTriangleXAt(i);
|
||||
}
|
||||
int manta_liquid_get_triangle_y_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getTriangleYAt(i);
|
||||
}
|
||||
int manta_liquid_get_triangle_z_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getTriangleZAt(i);
|
||||
}
|
||||
|
||||
float manta_liquid_get_vertvel_x_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getVertVelXAt(i);
|
||||
}
|
||||
float manta_liquid_get_vertvel_y_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getVertVelYAt(i);
|
||||
}
|
||||
float manta_liquid_get_vertvel_z_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getVertVelZAt(i);
|
||||
}
|
||||
|
||||
int manta_liquid_get_num_flip_particles(MANTA *liquid)
|
||||
{
|
||||
return liquid->getNumFlipParticles();
|
||||
}
|
||||
int manta_liquid_get_num_snd_particles(MANTA *liquid)
|
||||
{
|
||||
return liquid->getNumSndParticles();
|
||||
}
|
||||
|
||||
int manta_liquid_get_flip_particle_flag_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getFlipParticleFlagAt(i);
|
||||
}
|
||||
int manta_liquid_get_snd_particle_flag_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getSndParticleFlagAt(i);
|
||||
}
|
||||
|
||||
float manta_liquid_get_flip_particle_position_x_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getFlipParticlePositionXAt(i);
|
||||
}
|
||||
float manta_liquid_get_flip_particle_position_y_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getFlipParticlePositionYAt(i);
|
||||
}
|
||||
float manta_liquid_get_flip_particle_position_z_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getFlipParticlePositionZAt(i);
|
||||
}
|
||||
|
||||
float manta_liquid_get_flip_particle_velocity_x_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getFlipParticleVelocityXAt(i);
|
||||
}
|
||||
float manta_liquid_get_flip_particle_velocity_y_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getFlipParticleVelocityYAt(i);
|
||||
}
|
||||
float manta_liquid_get_flip_particle_velocity_z_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getFlipParticleVelocityZAt(i);
|
||||
}
|
||||
|
||||
float manta_liquid_get_snd_particle_position_x_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getSndParticlePositionXAt(i);
|
||||
}
|
||||
float manta_liquid_get_snd_particle_position_y_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getSndParticlePositionYAt(i);
|
||||
}
|
||||
float manta_liquid_get_snd_particle_position_z_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getSndParticlePositionZAt(i);
|
||||
}
|
||||
|
||||
float manta_liquid_get_snd_particle_velocity_x_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getSndParticleVelocityXAt(i);
|
||||
}
|
||||
float manta_liquid_get_snd_particle_velocity_y_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getSndParticleVelocityYAt(i);
|
||||
}
|
||||
float manta_liquid_get_snd_particle_velocity_z_at(MANTA *liquid, int i)
|
||||
{
|
||||
return liquid->getSndParticleVelocityZAt(i);
|
||||
}
|
36
intern/mantaflow/intern/manta_python_API.cpp
Normal file
36
intern/mantaflow/intern/manta_python_API.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Sebastian Barschkis (sebbas)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file mantaflow/intern/manta_python_API.cpp
|
||||
* \ingroup mantaflow
|
||||
*/
|
||||
|
||||
#include "manta_python_API.h"
|
||||
#include "manta.h"
|
||||
|
||||
PyObject *Manta_initPython(void)
|
||||
{
|
||||
return Pb::PyInit_Main();
|
||||
}
|
805
intern/mantaflow/intern/strings/fluid_script.h
Normal file
805
intern/mantaflow/intern/strings/fluid_script.h
Normal file
@ -0,0 +1,805 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Sebastian Barschkis (sebbas)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file mantaflow/intern/strings/shared_script.h
|
||||
* \ingroup mantaflow
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// LIBRARIES
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string manta_import =
|
||||
"\
|
||||
from manta import *\n\
|
||||
import os.path, shutil, math, sys, gc, multiprocessing, platform, time\n\
|
||||
\n\
|
||||
withMPBake = False # Bake files asynchronously\n\
|
||||
withMPSave = True # Save files asynchronously\n\
|
||||
isWindows = platform.system() != 'Darwin' and platform.system() != 'Linux'\n\
|
||||
# TODO (sebbas): Use this to simulate Windows multiprocessing (has default mode spawn)\n\
|
||||
#try:\n\
|
||||
# multiprocessing.set_start_method('spawn')\n\
|
||||
#except:\n\
|
||||
# pass\n\
|
||||
\n\
|
||||
bpy = sys.modules.get('bpy')\n\
|
||||
if bpy is not None:\n\
|
||||
sys.executable = bpy.app.binary_path_python\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DEBUG
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string manta_debuglevel =
|
||||
"\n\
|
||||
def set_manta_debuglevel(level):\n\
|
||||
setDebugLevel(level=level)\n # level 0 = mute all output from manta\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// SOLVERS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_solver =
|
||||
"\n\
|
||||
mantaMsg('Solver base')\n\
|
||||
s$ID$ = Solver(name='solver_base$ID$', gridSize=gs_s$ID$, dim=dim_s$ID$)\n";
|
||||
|
||||
const std::string fluid_solver_noise =
|
||||
"\n\
|
||||
mantaMsg('Solver noise')\n\
|
||||
sn$ID$ = Solver(name='solver_noise$ID$', gridSize=gs_sn$ID$)\n";
|
||||
|
||||
const std::string fluid_solver_mesh =
|
||||
"\n\
|
||||
mantaMsg('Solver mesh')\n\
|
||||
sm$ID$ = Solver(name='solver_mesh$ID$', gridSize=gs_sm$ID$)\n";
|
||||
|
||||
const std::string fluid_solver_particles =
|
||||
"\n\
|
||||
mantaMsg('Solver particles')\n\
|
||||
sp$ID$ = Solver(name='solver_particles$ID$', gridSize=gs_sp$ID$)\n";
|
||||
|
||||
const std::string fluid_solver_guiding =
|
||||
"\n\
|
||||
mantaMsg('Solver guiding')\n\
|
||||
sg$ID$ = Solver(name='solver_guiding$ID$', gridSize=gs_sg$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// VARIABLES
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_variables =
|
||||
"\n\
|
||||
mantaMsg('Fluid variables')\n\
|
||||
dim_s$ID$ = $SOLVER_DIM$\n\
|
||||
res_s$ID$ = $RES$\n\
|
||||
gravity_s$ID$ = vec3($GRAVITY_X$, $GRAVITY_Y$, $GRAVITY_Z$)\n\
|
||||
gs_s$ID$ = vec3($RESX$, $RESY$, $RESZ$)\n\
|
||||
maxVel_s$ID$ = 0\n\
|
||||
\n\
|
||||
doOpen_s$ID$ = $DO_OPEN$\n\
|
||||
boundConditions_s$ID$ = '$BOUND_CONDITIONS$'\n\
|
||||
boundaryWidth_s$ID$ = $BOUNDARY_WIDTH$\n\
|
||||
\n\
|
||||
using_smoke_s$ID$ = $USING_SMOKE$\n\
|
||||
using_liquid_s$ID$ = $USING_LIQUID$\n\
|
||||
using_noise_s$ID$ = $USING_NOISE$\n\
|
||||
using_adaptTime_s$ID$ = $USING_ADAPTIVETIME$\n\
|
||||
using_obstacle_s$ID$ = $USING_OBSTACLE$\n\
|
||||
using_guiding_s$ID$ = $USING_GUIDING$\n\
|
||||
using_fractions_s$ID$ = $USING_FRACTIONS$\n\
|
||||
using_invel_s$ID$ = $USING_INVEL$\n\
|
||||
using_outflow_s$ID$ = $USING_OUTFLOW$\n\
|
||||
using_sndparts_s$ID$ = $USING_SNDPARTS$\n\
|
||||
using_speedvectors_s$ID$ = $USING_SPEEDVECTORS$\n\
|
||||
\n\
|
||||
# Fluid time params\n\
|
||||
timeTotal_s$ID$ = $TIME_TOTAL$\n\
|
||||
timePerFrame_s$ID$ = $TIME_PER_FRAME$\n\
|
||||
frameLength_s$ID$ = $FRAME_LENGTH$\n\
|
||||
dt0_s$ID$ = $DT$\n\
|
||||
cflCond_s$ID$ = $CFL$\n\
|
||||
timestepsMin_s$ID$ = $TIMESTEPS_MIN$\n\
|
||||
timestepsMax_s$ID$ = $TIMESTEPS_MAX$\n\
|
||||
\n\
|
||||
# Fluid diffusion / viscosity\n\
|
||||
domainSize_s$ID$ = $FLUID_DOMAIN_SIZE$ # longest domain side in meters\n\
|
||||
viscosity_s$ID$ = $FLUID_VISCOSITY$ / (domainSize_s$ID$*domainSize_s$ID$) # kinematic viscosity in m^2/s\n\
|
||||
\n\
|
||||
# Factor to convert blender velocities to manta velocities\n\
|
||||
toMantaUnitsFac_s$ID$ = (1.0 / (1.0 / res_s$ID$))\n # = dt/dx * 1/dt ";
|
||||
|
||||
const std::string fluid_variables_noise =
|
||||
"\n\
|
||||
mantaMsg('Fluid variables noise')\n\
|
||||
upres_sn$ID$ = $NOISE_SCALE$\n\
|
||||
gs_sn$ID$ = vec3(upres_sn$ID$*gs_s$ID$.x, upres_sn$ID$*gs_s$ID$.y, upres_sn$ID$*gs_s$ID$.z)\n";
|
||||
|
||||
const std::string fluid_variables_mesh =
|
||||
"\n\
|
||||
mantaMsg('Fluid variables mesh')\n\
|
||||
upres_sm$ID$ = $MESH_SCALE$\n\
|
||||
gs_sm$ID$ = vec3(upres_sm$ID$*gs_s$ID$.x, upres_sm$ID$*gs_s$ID$.y, upres_sm$ID$*gs_s$ID$.z)\n";
|
||||
|
||||
const std::string fluid_variables_particles =
|
||||
"\n\
|
||||
mantaMsg('Fluid variables particles')\n\
|
||||
upres_sp$ID$ = $PARTICLE_SCALE$\n\
|
||||
gs_sp$ID$ = vec3(upres_sp$ID$*gs_s$ID$.x, upres_sp$ID$*gs_s$ID$.y, upres_sp$ID$*gs_s$ID$.z)\n";
|
||||
|
||||
const std::string fluid_variables_guiding =
|
||||
"\n\
|
||||
mantaMsg('Fluid variables guiding')\n\
|
||||
gs_sg$ID$ = vec3($GUIDING_RESX$, $GUIDING_RESY$, $GUIDING_RESZ$)\n\
|
||||
\n\
|
||||
alpha_sg$ID$ = $GUIDING_ALPHA$\n\
|
||||
beta_sg$ID$ = $GUIDING_BETA$\n\
|
||||
gamma_sg$ID$ = $GUIDING_FACTOR$\n\
|
||||
tau_sg$ID$ = 1.0\n\
|
||||
sigma_sg$ID$ = 0.99/tau_sg$ID$\n\
|
||||
theta_sg$ID$ = 1.0\n";
|
||||
|
||||
const std::string fluid_with_obstacle =
|
||||
"\n\
|
||||
using_obstacle_s$ID$ = True\n";
|
||||
|
||||
const std::string fluid_with_guiding =
|
||||
"\n\
|
||||
using_guiding_s$ID$ = True\n";
|
||||
|
||||
const std::string fluid_with_fractions =
|
||||
"\n\
|
||||
using_fractions_s$ID$ = True\n";
|
||||
|
||||
const std::string fluid_with_invel =
|
||||
"\n\
|
||||
using_invel_s$ID$ = True\n";
|
||||
|
||||
const std::string fluid_with_outflow =
|
||||
"\n\
|
||||
using_outflow_s$ID$ = True\n";
|
||||
|
||||
const std::string fluid_with_sndparts =
|
||||
"\n\
|
||||
using_sndparts_s$ID$ = True\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ADAPTIVE TIME STEPPING
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_time_stepping =
|
||||
"\n\
|
||||
mantaMsg('Fluid adaptive time stepping')\n\
|
||||
s$ID$.frameLength = frameLength_s$ID$\n\
|
||||
s$ID$.timestepMin = s$ID$.frameLength / max(1, timestepsMax_s$ID$)\n\
|
||||
s$ID$.timestepMax = s$ID$.frameLength / max(1, timestepsMin_s$ID$)\n\
|
||||
s$ID$.cfl = cflCond_s$ID$\n\
|
||||
s$ID$.timePerFrame = timePerFrame_s$ID$\n\
|
||||
s$ID$.timestep = dt0_s$ID$\n\
|
||||
s$ID$.timeTotal = timeTotal_s$ID$\n\
|
||||
#mantaMsg('timestep: ' + str(s$ID$.timestep) + ' // timPerFrame: ' + str(s$ID$.timePerFrame) + ' // frameLength: ' + str(s$ID$.frameLength) + ' // timeTotal: ' + str(s$ID$.timeTotal) )\n";
|
||||
|
||||
const std::string fluid_adapt_time_step =
|
||||
"\n\
|
||||
def fluid_adapt_time_step_$ID$():\n\
|
||||
mantaMsg('Fluid adapt time step')\n\
|
||||
\n\
|
||||
# time params are animatable\n\
|
||||
s$ID$.frameLength = frameLength_s$ID$\n\
|
||||
s$ID$.cfl = cflCond_s$ID$\n\
|
||||
\n\
|
||||
# ensure that vel grid is full (remember: adaptive domain can reallocate solver)\n\
|
||||
copyRealToVec3(sourceX=x_vel_s$ID$, sourceY=y_vel_s$ID$, sourceZ=z_vel_s$ID$, target=vel_s$ID$)\n\
|
||||
maxVel_s$ID$ = vel_s$ID$.getMax() if vel_s$ID$ else 0\n\
|
||||
if using_adaptTime_s$ID$:\n\
|
||||
mantaMsg('Adapt timestep, maxvel: ' + str(maxVel_s$ID$))\n\
|
||||
s$ID$.adaptTimestep(maxVel_s$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GRIDS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_alloc =
|
||||
"\n\
|
||||
mantaMsg('Fluid alloc data')\n\
|
||||
flags_s$ID$ = s$ID$.create(FlagGrid)\n\
|
||||
vel_s$ID$ = s$ID$.create(MACGrid)\n\
|
||||
velC_s$ID$ = s$ID$.create(MACGrid)\n\
|
||||
x_vel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
y_vel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
z_vel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
pressure_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
phiObs_s$ID$ = s$ID$.create(LevelsetGrid)\n\
|
||||
phiIn_s$ID$ = s$ID$.create(LevelsetGrid)\n\
|
||||
phiOut_s$ID$ = s$ID$.create(LevelsetGrid)\n\
|
||||
forces_s$ID$ = s$ID$.create(Vec3Grid)\n\
|
||||
x_force_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
y_force_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
z_force_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
obvel_s$ID$ = None\n\
|
||||
\n\
|
||||
# Keep track of important objects in dict to load them later on\n\
|
||||
fluid_data_dict_s$ID$ = dict(vel=vel_s$ID$, phiObs=phiObs_s$ID$, phiIn=phiIn_s$ID$, phiOut=phiOut_s$ID$, flags=flags_s$ID$)\n";
|
||||
|
||||
const std::string fluid_alloc_obstacle =
|
||||
"\n\
|
||||
mantaMsg('Allocating obstacle data')\n\
|
||||
numObs_s$ID$ = s$ID$.create(IntGrid)\n\
|
||||
phiObsIn_s$ID$ = s$ID$.create(LevelsetGrid)\n\
|
||||
obvel_s$ID$ = s$ID$.create(MACGrid)\n\
|
||||
obvelC_s$ID$ = s$ID$.create(Vec3Grid)\n\
|
||||
x_obvel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
y_obvel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
z_obvel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
\n\
|
||||
tmpDict_s$ID$ = dict(phiObsIn=phiObsIn_s$ID$)\n\
|
||||
fluid_data_dict_s$ID$.update(tmpDict_s$ID$)\n";
|
||||
|
||||
const std::string fluid_alloc_guiding =
|
||||
"\n\
|
||||
mantaMsg('Allocating guiding data')\n\
|
||||
velT_s$ID$ = s$ID$.create(MACGrid)\n\
|
||||
weightGuide_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
numGuides_s$ID$ = s$ID$.create(IntGrid)\n\
|
||||
phiGuideIn_s$ID$ = s$ID$.create(LevelsetGrid)\n\
|
||||
guidevelC_s$ID$ = s$ID$.create(Vec3Grid)\n\
|
||||
x_guidevel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
y_guidevel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
z_guidevel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
\n\
|
||||
# Final guide vel grid needs to have independent size\n\
|
||||
guidevel_sg$ID$ = sg$ID$.create(MACGrid)\n\
|
||||
\n\
|
||||
# Keep track of important objects in dict to load them later on\n\
|
||||
fluid_guiding_dict_s$ID$ = dict(guidevel=guidevel_sg$ID$)\n";
|
||||
|
||||
const std::string fluid_alloc_fractions =
|
||||
"\n\
|
||||
mantaMsg('Allocating fractions data')\n\
|
||||
fractions_s$ID$ = s$ID$.create(MACGrid)\n";
|
||||
|
||||
const std::string fluid_alloc_invel =
|
||||
"\n\
|
||||
mantaMsg('Allocating initial velocity data')\n\
|
||||
invelC_s$ID$ = s$ID$.create(VecGrid)\n\
|
||||
invel_s$ID$ = s$ID$.create(MACGrid)\n\
|
||||
x_invel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
y_invel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
z_invel_s$ID$ = s$ID$.create(RealGrid)\n";
|
||||
|
||||
const std::string fluid_alloc_outflow =
|
||||
"\n\
|
||||
mantaMsg('Allocating outflow data')\n\
|
||||
phiOutIn_s$ID$ = s$ID$.create(LevelsetGrid)\n";
|
||||
|
||||
const std::string fluid_alloc_sndparts =
|
||||
"\n\
|
||||
mantaMsg('Allocating snd parts low')\n\
|
||||
ppSnd_sp$ID$ = sp$ID$.create(BasicParticleSystem)\n\
|
||||
pVelSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataVec3)\n\
|
||||
pForceSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataVec3)\n\
|
||||
pLifeSnd_pp$ID$ = ppSnd_sp$ID$.create(PdataReal)\n\
|
||||
vel_sp$ID$ = sp$ID$.create(MACGrid)\n\
|
||||
flags_sp$ID$ = sp$ID$.create(FlagGrid)\n\
|
||||
phi_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\
|
||||
phiIn_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\
|
||||
phiObs_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\
|
||||
phiObsIn_sp$ID$ = sp$ID$.create(LevelsetGrid)\n\
|
||||
\n\
|
||||
# Keep track of important objects in dict to load them later on\n\
|
||||
fluid_particles_dict_s$ID$ = dict(ppSnd=ppSnd_sp$ID$, pVelSnd=pVelSnd_pp$ID$, pLifeSnd=pLifeSnd_pp$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// PRE / POST STEP
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_pre_step =
|
||||
"\n\
|
||||
def fluid_pre_step_$ID$():\n\
|
||||
mantaMsg('Fluid pre step')\n\
|
||||
\n\
|
||||
phiObs_s$ID$.setConst(9999)\n\
|
||||
phiOut_s$ID$.setConst(9999)\n\
|
||||
\n\
|
||||
# Main vel grid is copied in adapt time step function\n\
|
||||
\n\
|
||||
# translate obvels (world space) to grid space\n\
|
||||
if using_obstacle_s$ID$:\n\
|
||||
x_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
y_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
z_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
copyRealToVec3(sourceX=x_obvel_s$ID$, sourceY=y_obvel_s$ID$, sourceZ=z_obvel_s$ID$, target=obvelC_s$ID$)\n\
|
||||
\n\
|
||||
# translate invels (world space) to grid space\n\
|
||||
if using_invel_s$ID$:\n\
|
||||
x_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
y_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
z_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
copyRealToVec3(sourceX=x_invel_s$ID$, sourceY=y_invel_s$ID$, sourceZ=z_invel_s$ID$, target=invelC_s$ID$)\n\
|
||||
\n\
|
||||
if using_guiding_s$ID$:\n\
|
||||
weightGuide_s$ID$.multConst(0)\n\
|
||||
weightGuide_s$ID$.addConst(alpha_sg$ID$)\n\
|
||||
interpolateMACGrid(source=guidevel_sg$ID$, target=velT_s$ID$)\n\
|
||||
velT_s$ID$.multConst(vec3(gamma_sg$ID$))\n\
|
||||
\n\
|
||||
# translate external forces (world space) to grid space\n\
|
||||
x_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
y_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
z_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
|
||||
copyRealToVec3(sourceX=x_force_s$ID$, sourceY=y_force_s$ID$, sourceZ=z_force_s$ID$, target=forces_s$ID$)\n\
|
||||
\n\
|
||||
# If obstacle has velocity, i.e. is a moving obstacle, switch to dynamic preconditioner\n\
|
||||
if using_smoke_s$ID$ and using_obstacle_s$ID$ and obvelC_s$ID$.getMax() > 0:\n\
|
||||
mantaMsg('Using dynamic preconditioner')\n\
|
||||
preconditioner_s$ID$ = PcMGDynamic\n\
|
||||
else:\n\
|
||||
mantaMsg('Using static preconditioner')\n\
|
||||
preconditioner_s$ID$ = PcMGStatic\n";
|
||||
|
||||
const std::string fluid_post_step =
|
||||
"\n\
|
||||
def fluid_post_step_$ID$():\n\
|
||||
mantaMsg('Fluid post step')\n\
|
||||
forces_s$ID$.clear()\n\
|
||||
x_force_s$ID$.clear()\n\
|
||||
y_force_s$ID$.clear()\n\
|
||||
z_force_s$ID$.clear()\n\
|
||||
\n\
|
||||
if using_guiding_s$ID$:\n\
|
||||
weightGuide_s$ID$.clear()\n\
|
||||
if using_invel_s$ID$:\n\
|
||||
x_invel_s$ID$.clear()\n\
|
||||
y_invel_s$ID$.clear()\n\
|
||||
z_invel_s$ID$.clear()\n\
|
||||
invel_s$ID$.clear()\n\
|
||||
invelC_s$ID$.clear()\n\
|
||||
\n\
|
||||
# Copy vel grid to reals grids (which Blender internal will in turn use for vel access)\n\
|
||||
copyVec3ToReal(source=vel_s$ID$, targetX=x_vel_s$ID$, targetY=y_vel_s$ID$, targetZ=z_vel_s$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DESTRUCTION
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_delete_all =
|
||||
"\n\
|
||||
mantaMsg('Deleting fluid')\n\
|
||||
# Clear all helper dictionaries first\n\
|
||||
mantaMsg('Clear helper dictionaries')\n\
|
||||
if 'liquid_data_dict_s$ID$' in globals(): liquid_data_dict_s$ID$.clear()\n\
|
||||
if 'liquid_flip_dict_s$ID$' in globals(): liquid_flip_dict_s$ID$.clear()\n\
|
||||
if 'liquid_mesh_dict_s$ID$' in globals(): liquid_mesh_dict_s$ID$.clear()\n\
|
||||
if 'liquid_meshvel_dict_s$ID$' in globals(): liquid_meshvel_dict_s$ID$.clear()\n\
|
||||
if 'liquid_particles_dict_s$ID$' in globals(): liquid_particles_dict_s$ID$.clear()\n\
|
||||
if 'smoke_data_dict_s$ID$' in globals(): smoke_data_dict_s$ID$.clear()\n\
|
||||
if 'smoke_noise_dict_s$ID$' in globals(): smoke_noise_dict_s$ID$.clear()\n\
|
||||
if 'fluid_particles_dict_s$ID$' in globals(): fluid_particles_dict_s$ID$.clear()\n\
|
||||
if 'fluid_guiding_dict_s$ID$' in globals(): fluid_guiding_dict_s$ID$.clear()\n\
|
||||
if 'fluid_data_dict_s$ID$' in globals(): fluid_data_dict_s$ID$.clear()\n\
|
||||
if 'fluid_vel_dict_s$ID$' in globals(): fluid_vel_dict_s$ID$.clear()\n\
|
||||
\n\
|
||||
# Delete all childs from objects (e.g. pdata for particles)\n\
|
||||
mantaMsg('Release solver childs childs')\n\
|
||||
for var in list(globals()):\n\
|
||||
if var.endswith('_pp$ID$') or var.endswith('_mesh$ID$'):\n\
|
||||
del globals()[var]\n\
|
||||
\n\
|
||||
# Now delete childs from solver objects\n\
|
||||
mantaMsg('Release solver childs')\n\
|
||||
for var in list(globals()):\n\
|
||||
if var.endswith('_s$ID$') or var.endswith('_sn$ID$') or var.endswith('_sm$ID$') or var.endswith('_sp$ID$') or var.endswith('_sg$ID$'):\n\
|
||||
del globals()[var]\n\
|
||||
\n\
|
||||
# Extra cleanup for multigrid and fluid guiding\n\
|
||||
mantaMsg('Release multigrid')\n\
|
||||
if 's$ID$' in globals(): releaseMG(s$ID$)\n\
|
||||
if 'sn$ID$' in globals(): releaseMG(sn$ID$)\n\
|
||||
mantaMsg('Release fluid guiding')\n\
|
||||
releaseBlurPrecomp()\n\
|
||||
\n\
|
||||
# Release unreferenced memory (if there is some left, can in fact happen)\n\
|
||||
gc.collect()\n\
|
||||
\n\
|
||||
# Now it is safe to delete solver objects (always need to be deleted last)\n\
|
||||
mantaMsg('Delete base solver')\n\
|
||||
if 's$ID$' in globals(): del s$ID$\n\
|
||||
mantaMsg('Delete noise solver')\n\
|
||||
if 'sn$ID$' in globals(): del sn$ID$\n\
|
||||
mantaMsg('Delete mesh solver')\n\
|
||||
if 'sm$ID$' in globals(): del sm$ID$\n\
|
||||
mantaMsg('Delete particle solver')\n\
|
||||
if 'sp$ID$' in globals(): del sp$ID$\n\
|
||||
mantaMsg('Delete guiding solver')\n\
|
||||
if 'sg$ID$' in globals(): del sg$ID$\n\
|
||||
\n\
|
||||
# Release unreferenced memory (if there is some left)\n\
|
||||
gc.collect()\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// BAKE
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_cache_helper =
|
||||
"\n\
|
||||
def fluid_cache_get_framenr_formatted_$ID$(framenr):\n\
|
||||
return str(framenr).zfill(4) # framenr with leading zeroes\n";
|
||||
|
||||
const std::string fluid_bake_multiprocessing =
|
||||
"\n\
|
||||
def fluid_cache_multiprocessing_start_$ID$(function, framenr, format_data=None, format_noise=None, format_mesh=None, format_particles=None, format_guiding=None, path_data=None, path_noise=None, path_mesh=None, path_particles=None, path_guiding=None, dict=None, do_join=True):\n\
|
||||
mantaMsg('Multiprocessing cache')\n\
|
||||
if __name__ == '__main__':\n\
|
||||
args = (framenr,)\n\
|
||||
if format_data:\n\
|
||||
args += (format_data,)\n\
|
||||
if format_noise:\n\
|
||||
args += (format_noise,)\n\
|
||||
if format_mesh:\n\
|
||||
args += (format_mesh,)\n\
|
||||
if format_particles:\n\
|
||||
args += (format_particles,)\n\
|
||||
if format_guiding:\n\
|
||||
args += (format_guiding,)\n\
|
||||
if path_data:\n\
|
||||
args += (path_data,)\n\
|
||||
if path_noise:\n\
|
||||
args += (path_noise,)\n\
|
||||
if path_mesh:\n\
|
||||
args += (path_mesh,)\n\
|
||||
if path_particles:\n\
|
||||
args += (path_particles,)\n\
|
||||
if path_guiding:\n\
|
||||
args += (path_guiding,)\n\
|
||||
if dict:\n\
|
||||
args += (dict,)\n\
|
||||
p$ID$ = multiprocessing.Process(target=function, args=args)\n\
|
||||
p$ID$.start()\n\
|
||||
if do_join:\n\
|
||||
p$ID$.join()\n";
|
||||
|
||||
const std::string fluid_bake_data =
|
||||
"\n\
|
||||
def bake_fluid_process_data_$ID$(framenr, format_data, format_particles, format_guiding, path_data, path_guiding):\n\
|
||||
mantaMsg('Bake fluid data')\n\
|
||||
\n\
|
||||
s$ID$.frame = framenr\n\
|
||||
# Must not set 'timeTotal' here. Remember, this function is called from manta.c while-loop\n\
|
||||
\n\
|
||||
start_time = time.time()\n\
|
||||
if using_smoke_s$ID$:\n\
|
||||
smoke_adaptive_step_$ID$(framenr)\n\
|
||||
if using_liquid_s$ID$:\n\
|
||||
liquid_adaptive_step_$ID$(framenr)\n\
|
||||
mantaMsg('--- Step: %s seconds ---' % (time.time() - start_time))\n\
|
||||
\n\
|
||||
def bake_fluid_data_$ID$(path_data, path_guiding, framenr, format_data, format_particles, format_guiding):\n\
|
||||
if not withMPBake or isWindows:\n\
|
||||
bake_fluid_process_data_$ID$(framenr, format_data, format_particles, format_guiding, path_data, path_guiding)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=bake_fluid_process_data_$ID$, framenr=framenr, format_data=format_data, format_particles=format_particles, format_guiding=format_guiding, path_data=path_data, path_guiding=path_guiding, do_join=False)\n";
|
||||
|
||||
const std::string fluid_bake_noise =
|
||||
"\n\
|
||||
def bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_noise):\n\
|
||||
mantaMsg('Bake fluid noise')\n\
|
||||
\n\
|
||||
sn$ID$.frame = framenr\n\
|
||||
sn$ID$.timeTotal = (framenr-1) * frameLength_s$ID$\n\
|
||||
sn$ID$.timestep = dt0_s$ID$\n\
|
||||
mantaMsg('sn$ID$.timeTotal: ' + str(sn$ID$.timeTotal))\n\
|
||||
\n\
|
||||
smoke_step_noise_$ID$(framenr)\n\
|
||||
smoke_save_noise_$ID$(path_noise, framenr, format_noise)\n\
|
||||
\n\
|
||||
def bake_noise_$ID$(path_data, path_noise, framenr, format_data, format_noise):\n\
|
||||
if not withMPBake or isWindows:\n\
|
||||
bake_noise_process_$ID$(framenr, format_data, format_noise, path_data, path_noise)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=bake_noise_process_$ID$, framenr=framenr, format_data=format_data, format_noise=format_noise, path_data=path_data, path_noise=path_noise)\n";
|
||||
|
||||
const std::string fluid_bake_mesh =
|
||||
"\n\
|
||||
def bake_mesh_process_$ID$(framenr, format_data, format_mesh, format_particles, path_data, path_mesh):\n\
|
||||
mantaMsg('Bake fluid mesh')\n\
|
||||
\n\
|
||||
sm$ID$.frame = framenr\n\
|
||||
sm$ID$.timeTotal = (framenr-1) * frameLength_s$ID$\n\
|
||||
sm$ID$.timestep = dt0_s$ID$\n\
|
||||
\n\
|
||||
#if using_smoke_s$ID$:\n\
|
||||
# TODO (sebbas): Future update could include smoke mesh (vortex sheets)\n\
|
||||
if using_liquid_s$ID$:\n\
|
||||
liquid_step_mesh_$ID$()\n\
|
||||
liquid_save_mesh_$ID$(path_mesh, framenr, format_mesh)\n\
|
||||
if using_speedvectors_s$ID$:\n\
|
||||
liquid_save_meshvel_$ID$(path_mesh, framenr, format_data)\n\
|
||||
\n\
|
||||
def bake_mesh_$ID$(path_data, path_mesh, framenr, format_data, format_mesh, format_particles):\n\
|
||||
if not withMPBake or isWindows:\n\
|
||||
bake_mesh_process_$ID$(framenr, format_data, format_mesh, format_particles, path_data, path_mesh)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=bake_mesh_process_$ID$, framenr=framenr, format_data=format_data, format_mesh=format_mesh, format_particles=format_particles, path_data=path_data, path_mesh=path_mesh)\n";
|
||||
|
||||
const std::string fluid_bake_particles =
|
||||
"\n\
|
||||
def bake_particles_process_$ID$(framenr, format_data, format_particles, path_data, path_particles):\n\
|
||||
mantaMsg('Bake secondary particles')\n\
|
||||
\n\
|
||||
sp$ID$.frame = framenr\n\
|
||||
sp$ID$.timeTotal = (framenr-1) * frameLength_s$ID$\n\
|
||||
sp$ID$.timestep = dt0_s$ID$\n\
|
||||
\n\
|
||||
fluid_load_data_$ID$(path_data, framenr, format_data)\n\
|
||||
#if using_smoke_s$ID$:\n\
|
||||
# TODO (sebbas): Future update could include smoke particles (e.g. fire sparks)\n\
|
||||
if using_liquid_s$ID$:\n\
|
||||
liquid_load_data_$ID$(path_data, framenr, format_data)\n\
|
||||
liquid_step_particles_$ID$()\n\
|
||||
fluid_save_particles_$ID$(path_particles, framenr, format_particles)\n\
|
||||
liquid_save_particles_$ID$(path_particles, framenr, format_particles)\n\
|
||||
\n\
|
||||
def bake_particles_$ID$(path_data, path_particles, framenr, format_data, format_particles):\n\
|
||||
if not withMPBake or isWindows:\n\
|
||||
bake_particles_process_$ID$(framenr, format_data, format_particles, path_data, path_particles)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=bake_particles_process_$ID$, framenr=framenr, format_data=format_data, format_particles=format_particles, path_data=path_data, path_particles=path_particles)\n";
|
||||
|
||||
const std::string fluid_bake_guiding =
|
||||
"\n\
|
||||
def bake_guiding_process_$ID$(framenr, format_guiding, path_guiding):\n\
|
||||
mantaMsg('Bake fluid guiding')\n\
|
||||
\n\
|
||||
if framenr>1:\n\
|
||||
fluid_load_guiding_$ID$(path_guiding, framenr-1, format_guiding)\n\
|
||||
\n\
|
||||
x_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\
|
||||
y_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\
|
||||
z_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\
|
||||
copyRealToVec3(sourceX=x_guidevel_s$ID$, sourceY=y_guidevel_s$ID$, sourceZ=z_guidevel_s$ID$, target=guidevelC_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Extrapolating guiding velocity')\n\
|
||||
# ensure velocities inside of guiding object, slightly add guiding vels outside of object too\n\
|
||||
extrapolateVec3Simple(vel=guidevelC_s$ID$, phi=phiGuideIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateVec3Simple(vel=guidevelC_s$ID$, phi=phiGuideIn_s$ID$, distance=4, inside=False)\n\
|
||||
resampleVec3ToMac(source=guidevelC_s$ID$, target=guidevel_sg$ID$)\n\
|
||||
\n\
|
||||
fluid_save_guiding_$ID$(path_guiding, framenr, format_guiding)\n\
|
||||
\n\
|
||||
def bake_guiding_$ID$(path_guiding, framenr, format_guiding):\n\
|
||||
if not withMPBake or isWindows:\n\
|
||||
bake_guiding_process_$ID$(framenr, format_guiding, path_guiding)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=bake_guiding_process_$ID$, framenr=framenr, format_guiding=format_guiding, path_guiding=path_guiding)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// IMPORT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_file_import =
|
||||
"\n\
|
||||
def fluid_file_import_s$ID$(dict, path, framenr, file_format):\n\
|
||||
try:\n\
|
||||
framenr = fluid_cache_get_framenr_formatted_$ID$(framenr)\n\
|
||||
for name, object in dict.items():\n\
|
||||
file = os.path.join(path, name + '_' + framenr + file_format)\n\
|
||||
if os.path.isfile(file):\n\
|
||||
object.load(file)\n\
|
||||
else:\n\
|
||||
mantaMsg('Could not load file ' + str(file))\n\
|
||||
except:\n\
|
||||
mantaMsg('exception found')\n\
|
||||
#mantaMsg(str(e))\n\
|
||||
pass # Just skip file load errors for now\n";
|
||||
|
||||
const std::string fluid_load_particles =
|
||||
"\n\
|
||||
def fluid_load_particles_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Fluid load particles, frame ' + str(framenr))\n\
|
||||
fluid_file_import_s$ID$(dict=fluid_particles_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
const std::string fluid_load_data =
|
||||
"\n\
|
||||
def fluid_load_data_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Fluid load data, frame ' + str(framenr))\n\
|
||||
fluid_file_import_s$ID$(dict=fluid_data_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
|
||||
\n\
|
||||
# When adaptive domain bake is resumed we need correct values in xyz vel grids\n\
|
||||
copyVec3ToReal(source=vel_s$ID$, targetX=x_vel_s$ID$, targetY=y_vel_s$ID$, targetZ=z_vel_s$ID$)\n";
|
||||
|
||||
const std::string fluid_load_guiding =
|
||||
"\n\
|
||||
def fluid_load_guiding_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Fluid load guiding, frame ' + str(framenr))\n\
|
||||
fluid_file_import_s$ID$(dict=fluid_guiding_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
const std::string fluid_load_vel =
|
||||
"\n\
|
||||
def fluid_load_vel_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Fluid load vel, frame ' + str(framenr))\n\
|
||||
fluid_vel_dict = dict(vel=guidevel_sg$ID$)\n\
|
||||
fluid_file_import_s$ID$(dict=fluid_vel_dict, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// EXPORT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_file_export =
|
||||
"\n\
|
||||
def fluid_file_export_s$ID$(framenr, file_format, path, dict, mode_override=True, skip_subframes=True):\n\
|
||||
if skip_subframes and ((timePerFrame_s$ID$ + dt0_s$ID$) < frameLength_s$ID$):\n\
|
||||
return\n\
|
||||
mantaMsg('Fluid file export, frame: ' + str(framenr))\n\
|
||||
try:\n\
|
||||
framenr = fluid_cache_get_framenr_formatted_$ID$(framenr)\n\
|
||||
if not os.path.exists(path):\n\
|
||||
os.makedirs(path)\n\
|
||||
for name, object in dict.items():\n\
|
||||
file = os.path.join(path, name + '_' + framenr + file_format)\n\
|
||||
if not os.path.isfile(file) or mode_override: object.save(file)\n\
|
||||
except Exception as e:\n\
|
||||
mantaMsg(str(e))\n\
|
||||
pass # Just skip file save errors for now\n";
|
||||
|
||||
const std::string fluid_save_particles =
|
||||
"\n\
|
||||
def fluid_save_particles_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid save particles, frame ' + str(framenr))\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(dict=fluid_particles_dict_s$ID$, framenr=framenr, file_format=file_format, path=path)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=fluid_particles_dict_s$ID$, do_join=False)\n";
|
||||
|
||||
const std::string fluid_save_data =
|
||||
"\n\
|
||||
def fluid_save_data_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Fluid save data, frame ' + str(framenr))\n\
|
||||
start_time = time.time()\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(framenr=framenr, file_format=file_format, path=path, dict=fluid_data_dict_s$ID$)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=fluid_data_dict_s$ID$, do_join=False)\n\
|
||||
mantaMsg('--- Save: %s seconds ---' % (time.time() - start_time))\n";
|
||||
|
||||
const std::string fluid_save_guiding =
|
||||
"\n\
|
||||
def fluid_save_guiding_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Fluid save guiding, frame ' + str(framenr))\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(dict=fluid_guiding_dict_s$ID$, framenr=framenr, file_format=file_format, path=path)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=fluid_guiding_dict_s$ID$, do_join=False)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// STANDALONE MODE
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string fluid_standalone =
|
||||
"\n\
|
||||
gui = None\n\
|
||||
if (GUI):\n\
|
||||
gui=Gui()\n\
|
||||
gui.show()\n\
|
||||
gui.pause()\n\
|
||||
\n\
|
||||
cache_dir = '$CACHE_DIR$'\n\
|
||||
file_format_data = '.uni'\n\
|
||||
file_format_noise = '.uni'\n\
|
||||
file_format_particles = '.uni'\n\
|
||||
file_format_mesh = '.bobj.gz'\n\
|
||||
\n\
|
||||
# Start and stop for simulation\n\
|
||||
current_frame = $CURRENT_FRAME$\n\
|
||||
end_frame = $END_FRAME$\n\
|
||||
\n\
|
||||
# How many frame to load from cache\n\
|
||||
from_cache_cnt = 100\n\
|
||||
\n\
|
||||
loop_cnt = 0\n\
|
||||
while current_frame <= end_frame:\n\
|
||||
\n\
|
||||
# Load already simulated data from cache:\n\
|
||||
if loop_cnt < from_cache_cnt:\n\
|
||||
load(current_frame)\n\
|
||||
\n\
|
||||
# Otherwise simulate new data\n\
|
||||
else:\n\
|
||||
while(s$ID$.frame <= current_frame):\n\
|
||||
if using_adaptTime_s$ID$:\n\
|
||||
fluid_adapt_time_step_$ID$()\n\
|
||||
step(current_frame)\n\
|
||||
\n\
|
||||
current_frame += 1\n\
|
||||
loop_cnt += 1\n\
|
||||
\n\
|
||||
if gui:\n\
|
||||
gui.pause()\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// SCRIPT SECTION HEADERS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string header_libraries =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## LIBRARIES\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_main =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## MAIN\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_prepost =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## PRE/POST STEPS\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_steps =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## STEPS\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_import =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## IMPORT\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_grids =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## GRIDS\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_solvers =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## SOLVERS\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_variables =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## VARIABLES\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_time =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## ADAPTIVE TIME\n\
|
||||
######################################################################\n";
|
||||
|
||||
const std::string header_gridinit =
|
||||
"\n\
|
||||
######################################################################\n\
|
||||
## DOMAIN INIT\n\
|
||||
######################################################################\n";
|
462
intern/mantaflow/intern/strings/liquid_script.h
Normal file
462
intern/mantaflow/intern/strings/liquid_script.h
Normal file
@ -0,0 +1,462 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Sebastian Barschkis (sebbas)
|
||||
* Georg Kohl
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file mantaflow/intern/strings/liquid.h
|
||||
* \ingroup mantaflow
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// VARIABLES
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string liquid_variables =
|
||||
"\n\
|
||||
mantaMsg('Liquid variables')\n\
|
||||
narrowBandWidth_s$ID$ = 3\n\
|
||||
combineBandWidth_s$ID$ = narrowBandWidth_s$ID$ - 1\n\
|
||||
adjustedNarrowBandWidth_s$ID$ = $PARTICLE_BAND_WIDTH$ # only used in adjustNumber to control band width\n\
|
||||
particleNumber_s$ID$ = $PARTICLE_NUMBER$\n\
|
||||
minParticles_s$ID$ = $PARTICLE_MINIMUM$\n\
|
||||
maxParticles_s$ID$ = $PARTICLE_MAXIMUM$\n\
|
||||
radiusFactor_s$ID$ = $PARTICLE_RADIUS$\n\
|
||||
using_mesh_s$ID$ = $USING_MESH$\n\
|
||||
using_final_mesh_s$ID$ = $USING_IMPROVED_MESH$\n\
|
||||
using_fractions_s$ID$ = $USING_FRACTIONS$\n\
|
||||
fracThreshold_s$ID$ = $FRACTIONS_THRESHOLD$\n\
|
||||
flipRatio_s$ID$ = $FLIP_RATIO$\n\
|
||||
concaveUpper_s$ID$ = $MESH_CONCAVE_UPPER$\n\
|
||||
concaveLower_s$ID$ = $MESH_CONCAVE_LOWER$\n\
|
||||
meshRadiusFactor_s$ID$ = $MESH_PARTICLE_RADIUS$\n\
|
||||
smoothenPos_s$ID$ = $MESH_SMOOTHEN_POS$\n\
|
||||
smoothenNeg_s$ID$ = $MESH_SMOOTHEN_NEG$\n\
|
||||
randomness_s$ID$ = $PARTICLE_RANDOMNESS$\n\
|
||||
surfaceTension_s$ID$ = $LIQUID_SURFACE_TENSION$\n";
|
||||
|
||||
const std::string liquid_variables_particles =
|
||||
"\n\
|
||||
tauMin_wc_sp$ID$ = $SNDPARTICLE_TAU_MIN_WC$\n\
|
||||
tauMax_wc_sp$ID$ = $SNDPARTICLE_TAU_MAX_WC$\n\
|
||||
tauMin_ta_sp$ID$ = $SNDPARTICLE_TAU_MIN_TA$\n\
|
||||
tauMax_ta_sp$ID$ = $SNDPARTICLE_TAU_MAX_TA$\n\
|
||||
tauMin_k_sp$ID$ = $SNDPARTICLE_TAU_MIN_K$\n\
|
||||
tauMax_k_sp$ID$ = $SNDPARTICLE_TAU_MAX_K$\n\
|
||||
k_wc_sp$ID$ = $SNDPARTICLE_K_WC$\n\
|
||||
k_ta_sp$ID$ = $SNDPARTICLE_K_TA$\n\
|
||||
k_b_sp$ID$ = $SNDPARTICLE_K_B$\n\
|
||||
k_d_sp$ID$ = $SNDPARTICLE_K_D$\n\
|
||||
lMin_sp$ID$ = $SNDPARTICLE_L_MIN$\n\
|
||||
lMax_sp$ID$ = $SNDPARTICLE_L_MAX$\n\
|
||||
c_s_sp$ID$ = 0.4 # classification constant for snd parts\n\
|
||||
c_b_sp$ID$ = 0.77 # classification constant for snd parts\n\
|
||||
pot_radius_sp$ID$ = $SNDPARTICLE_POTENTIAL_RADIUS$\n\
|
||||
update_radius_sp$ID$ = $SNDPARTICLE_UPDATE_RADIUS$\n\
|
||||
scaleFromManta_sp$ID$ = $FLUID_DOMAIN_SIZE$ / float(res_s$ID$) # resize factor for snd parts\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GRIDS & MESH & PARTICLESYSTEM
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string liquid_alloc =
|
||||
"\n\
|
||||
mantaMsg('Liquid alloc')\n\
|
||||
phiParts_s$ID$ = s$ID$.create(LevelsetGrid)\n\
|
||||
phi_s$ID$ = s$ID$.create(LevelsetGrid)\n\
|
||||
phiTmp_s$ID$ = s$ID$.create(LevelsetGrid)\n\
|
||||
curvature_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
velOld_s$ID$ = s$ID$.create(MACGrid)\n\
|
||||
velParts_s$ID$ = s$ID$.create(MACGrid)\n\
|
||||
mapWeights_s$ID$ = s$ID$.create(MACGrid)\n\
|
||||
fractions_s$ID$ = None # allocated dynamically\n\
|
||||
\n\
|
||||
pp_s$ID$ = s$ID$.create(BasicParticleSystem)\n\
|
||||
pVel_pp$ID$ = pp_s$ID$.create(PdataVec3)\n\
|
||||
\n\
|
||||
# Acceleration data for particle nbs\n\
|
||||
pindex_s$ID$ = s$ID$.create(ParticleIndexSystem)\n\
|
||||
gpi_s$ID$ = s$ID$.create(IntGrid)\n\
|
||||
\n\
|
||||
# Keep track of important objects in dict to load them later on\n\
|
||||
liquid_data_dict_s$ID$ = dict(phiParts=phiParts_s$ID$, phi=phi_s$ID$, phiTmp=phiTmp_s$ID$)\n\
|
||||
liquid_flip_dict_s$ID$ = dict(pp=pp_s$ID$, pVel=pVel_pp$ID$)\n";
|
||||
|
||||
const std::string liquid_alloc_mesh =
|
||||
"\n\
|
||||
mantaMsg('Liquid alloc mesh')\n\
|
||||
phiParts_sm$ID$ = sm$ID$.create(LevelsetGrid)\n\
|
||||
phi_sm$ID$ = sm$ID$.create(LevelsetGrid)\n\
|
||||
pp_sm$ID$ = sm$ID$.create(BasicParticleSystem)\n\
|
||||
flags_sm$ID$ = sm$ID$.create(FlagGrid)\n\
|
||||
mesh_sm$ID$ = sm$ID$.create(Mesh)\n\
|
||||
\n\
|
||||
if using_speedvectors_s$ID$:\n\
|
||||
mVel_mesh$ID$ = mesh_sm$ID$.create(MdataVec3)\n\
|
||||
vel_sm$ID$ = sm$ID$.create(MACGrid)\n\
|
||||
\n\
|
||||
# Acceleration data for particle nbs\n\
|
||||
pindex_sm$ID$ = sm$ID$.create(ParticleIndexSystem)\n\
|
||||
gpi_sm$ID$ = sm$ID$.create(IntGrid)\n\
|
||||
\n\
|
||||
# Keep track of important objects in dict to load them later on\n\
|
||||
liquid_mesh_dict_s$ID$ = dict(lMesh=mesh_sm$ID$)\n\
|
||||
\n\
|
||||
if using_speedvectors_s$ID$:\n\
|
||||
liquid_meshvel_dict_s$ID$ = dict(lVelMesh=mVel_mesh$ID$)\n";
|
||||
|
||||
const std::string liquid_alloc_particles =
|
||||
"\n\
|
||||
normal_sp$ID$ = sp$ID$.create(VecGrid)\n\
|
||||
neighborRatio_sp$ID$ = sp$ID$.create(RealGrid)\n\
|
||||
trappedAir_sp$ID$ = sp$ID$.create(RealGrid)\n\
|
||||
waveCrest_sp$ID$ = sp$ID$.create(RealGrid)\n\
|
||||
kineticEnergy_sp$ID$ = sp$ID$.create(RealGrid)\n\
|
||||
\n\
|
||||
# Keep track of important objects in dict to load them later on\n\
|
||||
liquid_particles_dict_s$ID$ = dict(trappedAir=trappedAir_sp$ID$, waveCrest=waveCrest_sp$ID$, kineticEnergy=kineticEnergy_sp$ID$)\n";
|
||||
|
||||
const std::string liquid_init_phi =
|
||||
"\n\
|
||||
# Prepare domain\n\
|
||||
phi_s$ID$.initFromFlags(flags_s$ID$)\n\
|
||||
phiIn_s$ID$.initFromFlags(flags_s$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// STEP FUNCTIONS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string liquid_adaptive_step =
|
||||
"\n\
|
||||
def liquid_adaptive_step_$ID$(framenr):\n\
|
||||
mantaMsg('Manta step, frame ' + str(framenr))\n\
|
||||
s$ID$.frame = framenr\n\
|
||||
\n\
|
||||
fluid_pre_step_$ID$()\n\
|
||||
\n\
|
||||
flags_s$ID$.initDomain(boundaryWidth=1 if using_fractions_s$ID$ else 0, phiWalls=phiObs_s$ID$, outflow=boundConditions_s$ID$)\n\
|
||||
\n\
|
||||
if using_obstacle_s$ID$:\n\
|
||||
mantaMsg('Initializing obstacle levelset')\n\
|
||||
phiObsIn_s$ID$.fillHoles(maxDepth=int(res_s$ID$), boundaryWidth=2)\n\
|
||||
extrapolateLsSimple(phi=phiObsIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateLsSimple(phi=phiObsIn_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
|
||||
phiObs_s$ID$.join(phiObsIn_s$ID$)\n\
|
||||
\n\
|
||||
# Using boundaryWidth=2 to not search beginning from walls (just a performance optimization)\n\
|
||||
# Additional sanity check: fill holes in phiObs which can result after joining with phiObsIn\n\
|
||||
phiObs_s$ID$.fillHoles(maxDepth=int(res_s$ID$), boundaryWidth=2)\n\
|
||||
extrapolateLsSimple(phi=phiObs_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateLsSimple(phi=phiObs_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
|
||||
\n\
|
||||
mantaMsg('Initializing fluid levelset')\n\
|
||||
extrapolateLsSimple(phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateLsSimple(phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
|
||||
phi_s$ID$.join(phiIn_s$ID$)\n\
|
||||
\n\
|
||||
if using_obstacle_s$ID$:\n\
|
||||
phi_s$ID$.subtract(phiObsIn_s$ID$)\n\
|
||||
\n\
|
||||
if using_outflow_s$ID$:\n\
|
||||
phiOut_s$ID$.join(phiOutIn_s$ID$)\n\
|
||||
\n\
|
||||
if using_fractions_s$ID$:\n\
|
||||
updateFractions(flags=flags_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$, boundaryWidth=boundaryWidth_s$ID$, fracThreshold=fracThreshold_s$ID$)\n\
|
||||
setObstacleFlags(flags=flags_s$ID$, phiObs=phiObs_s$ID$, phiOut=phiOut_s$ID$, fractions=fractions_s$ID$, phiIn=phiIn_s$ID$)\n\
|
||||
\n\
|
||||
# add initial velocity: set invel as source grid to ensure const vels in inflow region, sampling makes use of this\n\
|
||||
if using_invel_s$ID$:\n\
|
||||
extrapolateVec3Simple(vel=invelC_s$ID$, phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
resampleVec3ToMac(source=invelC_s$ID$, target=invel_s$ID$)\n\
|
||||
pVel_pp$ID$.setSource(invel_s$ID$, isMAC=True)\n\
|
||||
\n\
|
||||
sampleLevelsetWithParticles(phi=phiIn_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, discretization=particleNumber_s$ID$, randomness=randomness_s$ID$)\n\
|
||||
flags_s$ID$.updateFromLevelset(phi_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Liquid step / s$ID$.frame: ' + str(s$ID$.frame))\n\
|
||||
liquid_step_$ID$()\n\
|
||||
\n\
|
||||
s$ID$.step()\n\
|
||||
\n\
|
||||
fluid_post_step_$ID$()\n";
|
||||
|
||||
const std::string liquid_step =
|
||||
"\n\
|
||||
def liquid_step_$ID$():\n\
|
||||
mantaMsg('Liquid step')\n\
|
||||
\n\
|
||||
mantaMsg('Advecting particles')\n\
|
||||
pp_s$ID$.advectInGrid(flags=flags_s$ID$, vel=vel_s$ID$, integrationMode=IntRK4, deleteInObstacle=False, stopInObstacle=False)\n\
|
||||
\n\
|
||||
mantaMsg('Pushing particles out of obstacles')\n\
|
||||
pushOutofObs(parts=pp_s$ID$, flags=flags_s$ID$, phiObs=phiObs_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Advecting phi')\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=phi_s$ID$, order=1) # first order is usually enough\n\
|
||||
mantaMsg('Advecting velocity')\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=vel_s$ID$, order=2)\n\
|
||||
\n\
|
||||
phiTmp_s$ID$.copyFrom(phi_s$ID$) # save original phi for later use in mesh creation\n\
|
||||
\n\
|
||||
# create level set of particles\n\
|
||||
gridParticleIndex(parts=pp_s$ID$, flags=flags_s$ID$, indexSys=pindex_s$ID$, index=gpi_s$ID$)\n\
|
||||
unionParticleLevelset(parts=pp_s$ID$, indexSys=pindex_s$ID$, flags=flags_s$ID$, index=gpi_s$ID$, phi=phiParts_s$ID$, radiusFactor=radiusFactor_s$ID$)\n\
|
||||
\n\
|
||||
# combine level set of particles with grid level set\n\
|
||||
phi_s$ID$.addConst(1.) # shrink slightly\n\
|
||||
phi_s$ID$.join(phiParts_s$ID$)\n\
|
||||
extrapolateLsSimple(phi=phi_s$ID$, distance=narrowBandWidth_s$ID$+2, inside=True)\n\
|
||||
extrapolateLsSimple(phi=phi_s$ID$, distance=3)\n\
|
||||
phi_s$ID$.setBoundNeumann(0) # make sure no particles are placed at outer boundary\n\
|
||||
\n\
|
||||
if doOpen_s$ID$ or using_outflow_s$ID$:\n\
|
||||
resetOutflow(flags=flags_s$ID$, phi=phi_s$ID$, parts=pp_s$ID$, index=gpi_s$ID$, indexSys=pindex_s$ID$)\n\
|
||||
flags_s$ID$.updateFromLevelset(phi_s$ID$)\n\
|
||||
\n\
|
||||
# combine particles velocities with advected grid velocities\n\
|
||||
mapPartsToMAC(vel=velParts_s$ID$, flags=flags_s$ID$, velOld=velOld_s$ID$, parts=pp_s$ID$, partVel=pVel_pp$ID$, weight=mapWeights_s$ID$)\n\
|
||||
extrapolateMACFromWeight(vel=velParts_s$ID$, distance=2, weight=mapWeights_s$ID$)\n\
|
||||
combineGridVel(vel=velParts_s$ID$, weight=mapWeights_s$ID$, combineVel=vel_s$ID$, phi=phi_s$ID$, narrowBand=combineBandWidth_s$ID$, thresh=0)\n\
|
||||
velOld_s$ID$.copyFrom(vel_s$ID$)\n\
|
||||
\n\
|
||||
# forces & pressure solve\n\
|
||||
addGravity(flags=flags_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Adding external forces')\n\
|
||||
addForceField(flags=flags_s$ID$, vel=vel_s$ID$, force=forces_s$ID$)\n\
|
||||
\n\
|
||||
if using_obstacle_s$ID$:\n\
|
||||
mantaMsg('Extrapolating object velocity')\n\
|
||||
# ensure velocities inside of obs object, slightly add obvels outside of obs object\n\
|
||||
extrapolateVec3Simple(vel=obvelC_s$ID$, phi=phiObsIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateVec3Simple(vel=obvelC_s$ID$, phi=phiObsIn_s$ID$, distance=3, inside=False)\n\
|
||||
resampleVec3ToMac(source=obvelC_s$ID$, target=obvel_s$ID$)\n\
|
||||
\n\
|
||||
extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$, distance=2, intoObs=True if using_fractions_s$ID$ else False)\n\
|
||||
\n\
|
||||
# vel diffusion / viscosity!\n\
|
||||
if viscosity_s$ID$ > 0.:\n\
|
||||
mantaMsg('Viscosity')\n\
|
||||
# diffusion param for solve = const * dt / dx^2\n\
|
||||
alphaV = viscosity_s$ID$ * s$ID$.timestep * float(res_s$ID$*res_s$ID$)\n\
|
||||
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
|
||||
cgSolveDiffusion(flags_s$ID$, vel_s$ID$, alphaV)\n\
|
||||
\n\
|
||||
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Calculating curvature')\n\
|
||||
getLaplacian(laplacian=curvature_s$ID$, grid=phi_s$ID$)\n\
|
||||
\n\
|
||||
if using_guiding_s$ID$:\n\
|
||||
mantaMsg('Guiding and pressure')\n\
|
||||
PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, zeroPressureFixing=not doOpen_s$ID$)\n\
|
||||
else:\n\
|
||||
mantaMsg('Pressure')\n\
|
||||
solvePressure(flags=flags_s$ID$, vel=vel_s$ID$, pressure=pressure_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, obvel=obvel_s$ID$ if using_fractions_s$ID$ else None)\n\
|
||||
\n\
|
||||
extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$, distance=4, intoObs=True if using_fractions_s$ID$ else False)\n\
|
||||
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
|
||||
\n\
|
||||
if not using_fractions_s$ID$:\n\
|
||||
extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$, distance=(int(maxVel_s$ID$*1.25)))\n\
|
||||
\n\
|
||||
# set source grids for resampling, used in adjustNumber!\n\
|
||||
pVel_pp$ID$.setSource(vel_s$ID$, isMAC=True)\n\
|
||||
adjustNumber(parts=pp_s$ID$, vel=vel_s$ID$, flags=flags_s$ID$, minParticles=minParticles_s$ID$, maxParticles=maxParticles_s$ID$, phi=phi_s$ID$, exclude=phiObs_s$ID$, radiusFactor=radiusFactor_s$ID$, narrowBand=adjustedNarrowBandWidth_s$ID$)\n\
|
||||
flipVelocityUpdate(vel=vel_s$ID$, velOld=velOld_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, partVel=pVel_pp$ID$, flipRatio=flipRatio_s$ID$)\n";
|
||||
|
||||
const std::string liquid_step_mesh =
|
||||
"\n\
|
||||
def liquid_step_mesh_$ID$():\n\
|
||||
mantaMsg('Liquid step mesh')\n\
|
||||
\n\
|
||||
interpolateGrid(target=phi_sm$ID$, source=phiTmp_s$ID$)\n\
|
||||
\n\
|
||||
# create surface\n\
|
||||
pp_sm$ID$.readParticles(pp_s$ID$)\n\
|
||||
gridParticleIndex(parts=pp_sm$ID$, flags=flags_sm$ID$, indexSys=pindex_sm$ID$, index=gpi_sm$ID$)\n\
|
||||
\n\
|
||||
if using_final_mesh_s$ID$:\n\
|
||||
mantaMsg('Liquid using improved particle levelset')\n\
|
||||
improvedParticleLevelset(pp_sm$ID$, pindex_sm$ID$, flags_sm$ID$, gpi_sm$ID$, phiParts_sm$ID$, meshRadiusFactor_s$ID$, smoothenPos_s$ID$, smoothenNeg_s$ID$, concaveLower_s$ID$, concaveUpper_s$ID$)\n\
|
||||
else:\n\
|
||||
mantaMsg('Liquid using union particle levelset')\n\
|
||||
unionParticleLevelset(pp_sm$ID$, pindex_sm$ID$, flags_sm$ID$, gpi_sm$ID$, phiParts_sm$ID$, meshRadiusFactor_s$ID$)\n\
|
||||
\n\
|
||||
phi_sm$ID$.addConst(1.) # shrink slightly\n\
|
||||
phi_sm$ID$.join(phiParts_sm$ID$)\n\
|
||||
extrapolateLsSimple(phi=phi_sm$ID$, distance=narrowBandWidth_s$ID$+2, inside=True)\n\
|
||||
extrapolateLsSimple(phi=phi_sm$ID$, distance=3)\n\
|
||||
phi_sm$ID$.setBoundNeumann(0) # make sure no particles are placed at outer boundary\n\
|
||||
\n\
|
||||
# Vert vel vector needs to pull data from vel grid with correct dim\n\
|
||||
if using_speedvectors_s$ID$:\n\
|
||||
interpolateMACGrid(target=vel_sm$ID$, source=vel_s$ID$)\n\
|
||||
mVel_mesh$ID$.setSource(vel_sm$ID$, isMAC=True)\n\
|
||||
\n\
|
||||
phi_sm$ID$.setBound(0.5,int(((upres_sm$ID$)*2)-2) )\n\
|
||||
phi_sm$ID$.createMesh(mesh_sm$ID$)\n";
|
||||
|
||||
const std::string liquid_step_particles =
|
||||
"\n\
|
||||
def liquid_step_particles_$ID$():\n\
|
||||
mantaMsg('Secondary particles step')\n\
|
||||
\n\
|
||||
# no upres: just use the loaded grids\n\
|
||||
if upres_sp$ID$ <= 1:\n\
|
||||
flags_sp$ID$.copyFrom(flags_s$ID$)\n\
|
||||
vel_sp$ID$.copyFrom(vel_s$ID$)\n\
|
||||
phiObs_sp$ID$.copyFrom(phiObs_s$ID$)\n\
|
||||
phi_sp$ID$.copyFrom(phi_s$ID$)\n\
|
||||
\n\
|
||||
# with upres: recreate grids\n\
|
||||
else:\n\
|
||||
# create highres grids by interpolation\n\
|
||||
interpolateMACGrid(target=vel_sp$ID$, source=vel_s$ID$)\n\
|
||||
interpolateGrid(target=phi_sp$ID$, source=phi_s$ID$)\n\
|
||||
flags_sp$ID$.initDomain(boundaryWidth=boundaryWidth_s$ID$, phiWalls=phiObs_sp$ID$, outflow=boundConditions_s$ID$)\n\
|
||||
flags_sp$ID$.updateFromLevelset(levelset=phi_sp$ID$)\n\
|
||||
\n\
|
||||
# actual secondary simulation\n\
|
||||
#extrapolateLsSimple(phi=phi_sp$ID$, distance=radius+1, inside=True)\n\
|
||||
flipComputeSecondaryParticlePotentials(potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, normal=normal_sp$ID$, phi=phi_sp$ID$, radius=pot_radius_sp$ID$, tauMinTA=tauMin_ta_sp$ID$, tauMaxTA=tauMax_ta_sp$ID$, tauMinWC=tauMin_wc_sp$ID$, tauMaxWC=tauMax_wc_sp$ID$, tauMinKE=tauMin_k_sp$ID$, tauMaxKE=tauMax_k_sp$ID$, scaleFromManta=scaleFromManta_sp$ID$)\n\
|
||||
flipSampleSecondaryParticles(mode='single', flags=flags_sp$ID$, v=vel_sp$ID$, pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, lMin=lMin_sp$ID$, lMax=lMax_sp$ID$, potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, k_ta=k_ta_sp$ID$, k_wc=k_wc_sp$ID$, dt=s$ID$.frameLength)\n\
|
||||
flipUpdateSecondaryParticles(mode='linear', pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, f_sec=pForceSnd_pp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, neighborRatio=neighborRatio_sp$ID$, radius=update_radius_sp$ID$, gravity=gravity_s$ID$, k_b=k_b_sp$ID$, k_d=k_d_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, dt=s$ID$.frameLength)\n\
|
||||
if $SNDPARTICLE_BOUNDARY_PUSHOUT$:\n\
|
||||
pushOutofObs(parts = ppSnd_sp$ID$, flags = flags_sp$ID$, phiObs = phiObs_sp$ID$, shift = 1.0)\n\
|
||||
flipDeleteParticlesInObstacle(pts=ppSnd_sp$ID$, flags=flags_sp$ID$)\n\
|
||||
#debugGridInfo(flags = flags_sp$ID$, grid = trappedAir_sp$ID$, name = 'Trapped Air')\n\
|
||||
#debugGridInfo(flags = flags_sp$ID$, grid = waveCrest_sp$ID$, name = 'Wave Crest')\n\
|
||||
#debugGridInfo(flags = flags_sp$ID$, grid = kineticEnergy_sp$ID$, name = 'Kinetic Energy')\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// IMPORT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string liquid_load_data =
|
||||
"\n\
|
||||
def liquid_load_data_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid load data')\n\
|
||||
fluid_file_import_s$ID$(dict=liquid_data_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
const std::string liquid_load_flip =
|
||||
"\n\
|
||||
def liquid_load_flip_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid load flip')\n\
|
||||
fluid_file_import_s$ID$(dict=liquid_flip_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
const std::string liquid_load_mesh =
|
||||
"\n\
|
||||
def liquid_load_mesh_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid load mesh')\n\
|
||||
fluid_file_import_s$ID$(dict=liquid_mesh_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
const std::string liquid_load_meshvel =
|
||||
"\n\
|
||||
def liquid_load_meshvel_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid load meshvel')\n\
|
||||
fluid_file_import_s$ID$(dict=liquid_meshvel_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
const std::string liquid_load_particles =
|
||||
"\n\
|
||||
def liquid_load_particles_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid load particles')\n\
|
||||
fluid_file_import_s$ID$(dict=liquid_particles_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// EXPORT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string liquid_save_data =
|
||||
"\n\
|
||||
def liquid_save_data_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid save data')\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(dict=liquid_data_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_data_dict_s$ID$, do_join=False)\n";
|
||||
|
||||
const std::string liquid_save_flip =
|
||||
"\n\
|
||||
def liquid_save_flip_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid save flip')\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(dict=liquid_flip_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_flip_dict_s$ID$, do_join=False)\n";
|
||||
|
||||
const std::string liquid_save_mesh =
|
||||
"\n\
|
||||
def liquid_save_mesh_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid save mesh')\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(dict=liquid_mesh_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_mesh_dict_s$ID$, do_join=False)\n";
|
||||
|
||||
const std::string liquid_save_meshvel =
|
||||
"\n\
|
||||
def liquid_save_meshvel_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid save mesh vel')\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(dict=liquid_meshvel_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_meshvel_dict_s$ID$, do_join=False)\n";
|
||||
|
||||
const std::string liquid_save_particles =
|
||||
"\n\
|
||||
def liquid_save_particles_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Liquid save particles')\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(dict=liquid_particles_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=liquid_particles_dict_s$ID$, do_join=False)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// STANDALONE MODE
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string liquid_standalone =
|
||||
"\n\
|
||||
# Helper function to call cache load functions\n\
|
||||
def load(frame):\n\
|
||||
fluid_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data)\n\
|
||||
liquid_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data)\n\
|
||||
liquid_load_flip_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_particles)\n\
|
||||
if using_sndparts_s$ID$:\n\
|
||||
fluid_load_particles_$ID$(os.path.join(cache_dir, 'particles'), frame, file_format_particles)\n\
|
||||
liquid_load_particles_$ID$(os.path.join(cache_dir, 'particles'), frame, file_format_particles)\n\
|
||||
if using_mesh_s$ID$:\n\
|
||||
liquid_load_mesh_$ID$(os.path.join(cache_dir, 'mesh'), frame, file_format_mesh)\n\
|
||||
if using_guiding_s$ID$:\n\
|
||||
fluid_load_guiding_$ID$(os.path.join(cache_dir, 'guiding'), frame, file_format_data)\n\
|
||||
\n\
|
||||
# Helper function to call step functions\n\
|
||||
def step(frame):\n\
|
||||
liquid_adaptive_step_$ID$(frame)\n\
|
||||
if using_mesh_s$ID$:\n\
|
||||
liquid_step_mesh_$ID$()\n\
|
||||
if using_sndparts_s$ID$:\n\
|
||||
liquid_step_particles_$ID$()\n";
|
581
intern/mantaflow/intern/strings/smoke_script.h
Normal file
581
intern/mantaflow/intern/strings/smoke_script.h
Normal file
@ -0,0 +1,581 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Sebastian Barschkis (sebbas)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file mantaflow/intern/strings/smoke.h
|
||||
* \ingroup mantaflow
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// VARIABLES
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string smoke_variables =
|
||||
"\n\
|
||||
mantaMsg('Smoke variables low')\n\
|
||||
preconditioner_s$ID$ = PcMGDynamic\n\
|
||||
using_colors_s$ID$ = $USING_COLORS$\n\
|
||||
using_heat_s$ID$ = $USING_HEAT$\n\
|
||||
using_fire_s$ID$ = $USING_FIRE$\n\
|
||||
using_noise_s$ID$ = $USING_NOISE$\n\
|
||||
vorticity_s$ID$ = $VORTICITY$\n\
|
||||
buoyancy_dens_s$ID$ = float($BUOYANCY_ALPHA$) / float($FLUID_DOMAIN_SIZE$)\n\
|
||||
buoyancy_heat_s$ID$ = float($BUOYANCY_BETA$) / float($FLUID_DOMAIN_SIZE$)\n\
|
||||
dissolveSpeed_s$ID$ = $DISSOLVE_SPEED$\n\
|
||||
using_logdissolve_s$ID$ = $USING_LOG_DISSOLVE$\n\
|
||||
using_dissolve_s$ID$ = $USING_DISSOLVE$\n\
|
||||
flameVorticity_s$ID$ = $FLAME_VORTICITY$\n\
|
||||
burningRate_s$ID$ = $BURNING_RATE$\n\
|
||||
flameSmoke_s$ID$ = $FLAME_SMOKE$\n\
|
||||
ignitionTemp_s$ID$ = $IGNITION_TEMP$\n\
|
||||
maxTemp_s$ID$ = $MAX_TEMP$\n\
|
||||
flameSmokeColor_s$ID$ = vec3($FLAME_SMOKE_COLOR_X$,$FLAME_SMOKE_COLOR_Y$,$FLAME_SMOKE_COLOR_Z$)\n";
|
||||
|
||||
const std::string smoke_variables_noise =
|
||||
"\n\
|
||||
mantaMsg('Smoke variables noise')\n\
|
||||
wltStrength_s$ID$ = $WLT_STR$\n\
|
||||
uvs_s$ID$ = 2\n\
|
||||
uvs_offset_s$ID$ = vec3($MIN_RESX$, $MIN_RESY$, $MIN_RESZ$)\n\
|
||||
octaves_s$ID$ = int(math.log(upres_sn$ID$) / math.log(2.0) + 0.5) if (upres_sn$ID$ > 1) else 1\n";
|
||||
|
||||
const std::string smoke_wavelet_noise =
|
||||
"\n\
|
||||
# wavelet noise params\n\
|
||||
wltnoise_sn$ID$.posScale = vec3(int($BASE_RESX$), int($BASE_RESY$), int($BASE_RESZ$)) * (1. / $NOISE_POSSCALE$)\n\
|
||||
wltnoise_sn$ID$.timeAnim = $NOISE_TIMEANIM$\n";
|
||||
|
||||
const std::string smoke_with_heat =
|
||||
"\n\
|
||||
using_heat_s$ID$ = True\n";
|
||||
|
||||
const std::string smoke_with_colors =
|
||||
"\n\
|
||||
using_colors_s$ID$ = True\n";
|
||||
|
||||
const std::string smoke_with_fire =
|
||||
"\n\
|
||||
using_fire_s$ID$ = True\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GRIDS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string smoke_alloc =
|
||||
"\n\
|
||||
mantaMsg('Smoke alloc')\n\
|
||||
shadow_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
emissionIn_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
density_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
densityIn_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
heat_s$ID$ = None # allocated dynamically\n\
|
||||
heatIn_s$ID$ = None\n\
|
||||
flame_s$ID$ = None\n\
|
||||
fuel_s$ID$ = None\n\
|
||||
react_s$ID$ = None\n\
|
||||
fuelIn_s$ID$ = None\n\
|
||||
reactIn_s$ID$ = None\n\
|
||||
color_r_s$ID$ = None\n\
|
||||
color_g_s$ID$ = None\n\
|
||||
color_b_s$ID$ = None\n\
|
||||
color_r_in_s$ID$ = None\n\
|
||||
color_g_in_s$ID$ = None\n\
|
||||
color_b_in_s$ID$ = None\n\
|
||||
\n\
|
||||
# Keep track of important objects in dict to load them later on\n\
|
||||
smoke_data_dict_s$ID$ = dict(density=density_s$ID$, shadow=shadow_s$ID$, densityIn=densityIn_s$ID$, emissionIn=emissionIn_s$ID$)\n";
|
||||
|
||||
const std::string smoke_alloc_noise =
|
||||
"\n\
|
||||
mantaMsg('Smoke alloc noise')\n\
|
||||
vel_sn$ID$ = sn$ID$.create(MACGrid)\n\
|
||||
density_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
phiIn_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
|
||||
phiOut_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
|
||||
phiObs_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
|
||||
flags_sn$ID$ = sn$ID$.create(FlagGrid)\n\
|
||||
tmpIn_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
emissionIn_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
energy_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
tempFlag_s$ID$ = s$ID$.create(FlagGrid)\n\
|
||||
texture_u_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
texture_v_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
texture_w_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
texture_u2_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
texture_v2_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
texture_w2_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
flame_sn$ID$ = None\n\
|
||||
fuel_sn$ID$ = None\n\
|
||||
react_sn$ID$ = None\n\
|
||||
color_r_sn$ID$ = None\n\
|
||||
color_g_sn$ID$ = None\n\
|
||||
color_b_sn$ID$ = None\n\
|
||||
wltnoise_sn$ID$ = sn$ID$.create(NoiseField, fixedSeed=265, loadFromFile=True)\n\
|
||||
\n\
|
||||
mantaMsg('Initializing UV Grids')\n\
|
||||
uvGrid0_s$ID$ = s$ID$.create(VecGrid)\n\
|
||||
uvGrid1_s$ID$ = s$ID$.create(VecGrid)\n\
|
||||
resetUvGrid(target=uvGrid0_s$ID$, offset=uvs_offset_s$ID$)\n\
|
||||
resetUvGrid(target=uvGrid1_s$ID$, offset=uvs_offset_s$ID$)\n\
|
||||
\n\
|
||||
# Sync UV and texture grids\n\
|
||||
copyVec3ToReal(source=uvGrid0_s$ID$, targetX=texture_u_s$ID$, targetY=texture_v_s$ID$, targetZ=texture_w_s$ID$)\n\
|
||||
copyVec3ToReal(source=uvGrid1_s$ID$, targetX=texture_u2_s$ID$, targetY=texture_v2_s$ID$, targetZ=texture_w2_s$ID$)\n\
|
||||
\n\
|
||||
# Keep track of important objects in dict to load them later on\n\
|
||||
smoke_noise_dict_s$ID$ = dict(density_noise=density_sn$ID$, uv0_noise=uvGrid0_s$ID$, uv1_noise=uvGrid1_s$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ADDITIONAL GRIDS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string smoke_alloc_colors =
|
||||
"\n\
|
||||
# Sanity check, clear grids first\n\
|
||||
if 'color_r_s$ID$' in globals(): del color_r_s$ID$\n\
|
||||
if 'color_g_s$ID$' in globals(): del color_g_s$ID$\n\
|
||||
if 'color_b_s$ID$' in globals(): del color_b_s$ID$\n\
|
||||
\n\
|
||||
mantaMsg('Allocating colors')\n\
|
||||
color_r_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
color_g_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
color_b_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
color_r_in_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
color_g_in_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
color_b_in_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
\n\
|
||||
# Add objects to dict to load them later on\n\
|
||||
if 'smoke_data_dict_s$ID$' in globals():\n\
|
||||
smoke_data_dict_s$ID$.update(color_r=color_r_s$ID$, color_g=color_g_s$ID$, color_b=color_b_s$ID$)\n\
|
||||
smoke_data_dict_s$ID$.update(color_r_in=color_r_in_s$ID$, color_g_in=color_g_in_s$ID$, color_b_in=color_b_in_s$ID$)\n";
|
||||
|
||||
const std::string smoke_alloc_colors_noise =
|
||||
"\n\
|
||||
# Sanity check, clear grids first\n\
|
||||
if 'color_r_sn$ID$' in globals(): del color_r_sn$ID$\n\
|
||||
if 'color_g_sn$ID$' in globals(): del color_g_sn$ID$\n\
|
||||
if 'color_b_sn$ID$' in globals(): del color_b_sn$ID$\n\
|
||||
\n\
|
||||
mantaMsg('Allocating colors noise')\n\
|
||||
color_r_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
color_g_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
color_b_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
\n\
|
||||
# Add objects to dict to load them later on\n\
|
||||
if 'smoke_noise_dict_s$ID$' in globals():\n\
|
||||
smoke_noise_dict_s$ID$.update(color_r_noise=color_r_sn$ID$, color_g_noise=color_g_sn$ID$, color_b_noise=color_b_sn$ID$)\n";
|
||||
|
||||
const std::string smoke_init_colors =
|
||||
"\n\
|
||||
mantaMsg('Initializing colors')\n\
|
||||
color_r_s$ID$.copyFrom(density_s$ID$) \n\
|
||||
color_r_s$ID$.multConst($COLOR_R$) \n\
|
||||
color_g_s$ID$.copyFrom(density_s$ID$) \n\
|
||||
color_g_s$ID$.multConst($COLOR_G$) \n\
|
||||
color_b_s$ID$.copyFrom(density_s$ID$) \n\
|
||||
color_b_s$ID$.multConst($COLOR_B$)\n";
|
||||
|
||||
const std::string smoke_init_colors_noise =
|
||||
"\n\
|
||||
mantaMsg('Initializing colors noise')\n\
|
||||
color_r_sn$ID$.copyFrom(density_sn$ID$) \n\
|
||||
color_r_sn$ID$.multConst($COLOR_R$) \n\
|
||||
color_g_sn$ID$.copyFrom(density_sn$ID$) \n\
|
||||
color_g_sn$ID$.multConst($COLOR_G$) \n\
|
||||
color_b_sn$ID$.copyFrom(density_sn$ID$) \n\
|
||||
color_b_sn$ID$.multConst($COLOR_B$)\n";
|
||||
|
||||
const std::string smoke_alloc_heat =
|
||||
"\n\
|
||||
# Sanity check, clear grids first\n\
|
||||
if 'heat_s$ID$' in globals(): del heat_s$ID$\n\
|
||||
if 'heatIn_s$ID$' in globals(): del heatIn_s$ID$\n\
|
||||
\n\
|
||||
mantaMsg('Allocating heat')\n\
|
||||
heat_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
heatIn_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
\n\
|
||||
# Add objects to dict to load them later on\n\
|
||||
if 'smoke_data_dict_s$ID$' in globals():\n\
|
||||
smoke_data_dict_s$ID$.update(heat=heat_s$ID$, heatIn=heatIn_s$ID$)\n";
|
||||
|
||||
const std::string smoke_alloc_fire =
|
||||
"\n\
|
||||
# Sanity check, clear grids first\n\
|
||||
if 'flame_s$ID$' in globals(): del flame_s$ID$\n\
|
||||
if 'fuel_s$ID$' in globals(): del fuel_s$ID$\n\
|
||||
if 'react_s$ID$' in globals(): del react_s$ID$\n\
|
||||
if 'fuelIn_s$ID$' in globals(): del fuelIn_s$ID$\n\
|
||||
if 'reactIn_s$ID$' in globals(): del reactIn_s$ID$\n\
|
||||
\n\
|
||||
mantaMsg('Allocating fire')\n\
|
||||
flame_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
fuel_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
react_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
fuelIn_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
reactIn_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
\n\
|
||||
# Add objects to dict to load them later on\n\
|
||||
if 'smoke_data_dict_s$ID$' in globals():\n\
|
||||
smoke_data_dict_s$ID$.update(flame=flame_s$ID$, fuel=fuel_s$ID$, react=react_s$ID$)\n\
|
||||
smoke_data_dict_s$ID$.update(fuelIn=fuelIn_s$ID$, reactIn=reactIn_s$ID$)\n";
|
||||
|
||||
const std::string smoke_alloc_fire_noise =
|
||||
"\n\
|
||||
# Sanity check, clear grids first\n\
|
||||
if 'flame_sn$ID$' in globals(): del flame_sn$ID$\n\
|
||||
if 'fuel_sn$ID$' in globals(): del fuel_sn$ID$\n\
|
||||
if 'react_sn$ID$' in globals(): del react_sn$ID$\n\
|
||||
\n\
|
||||
mantaMsg('Allocating fire noise')\n\
|
||||
flame_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
fuel_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
react_sn$ID$ = sn$ID$.create(RealGrid)\n\
|
||||
\n\
|
||||
# Add objects to dict to load them later on\n\
|
||||
if 'smoke_noise_dict_s$ID$' in globals():\n\
|
||||
smoke_noise_dict_s$ID$.update(flame_noise=flame_sn$ID$, fuel_noise=fuel_sn$ID$, react_noise=react_sn$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// STEP FUNCTIONS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string smoke_adaptive_step =
|
||||
"\n\
|
||||
def smoke_adaptive_step_$ID$(framenr):\n\
|
||||
mantaMsg('Manta step, frame ' + str(framenr))\n\
|
||||
s$ID$.frame = framenr\n\
|
||||
\n\
|
||||
fluid_pre_step_$ID$()\n\
|
||||
\n\
|
||||
flags_s$ID$.initDomain(boundaryWidth=0, phiWalls=phiObs_s$ID$, outflow=boundConditions_s$ID$)\n\
|
||||
\n\
|
||||
if using_obstacle_s$ID$:\n\
|
||||
mantaMsg('Initializing obstacle levelset')\n\
|
||||
phiObsIn_s$ID$.fillHoles(maxDepth=int(res_s$ID$), boundaryWidth=2)\n\
|
||||
extrapolateLsSimple(phi=phiObsIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateLsSimple(phi=phiObsIn_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
|
||||
phiObs_s$ID$.join(phiObsIn_s$ID$)\n\
|
||||
\n\
|
||||
# Using boundaryWidth=2 to not search beginning from walls (just a performance optimization)\n\
|
||||
# Additional sanity check: fill holes in phiObs which can result after joining with phiObsIn\n\
|
||||
phiObs_s$ID$.fillHoles(maxDepth=int(res_s$ID$), boundaryWidth=2)\n\
|
||||
extrapolateLsSimple(phi=phiObs_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateLsSimple(phi=phiObs_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
|
||||
\n\
|
||||
mantaMsg('Initializing fluid levelset')\n\
|
||||
extrapolateLsSimple(phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateLsSimple(phi=phiIn_s$ID$, distance=int(res_s$ID$/2), inside=False)\n\
|
||||
\n\
|
||||
if using_outflow_s$ID$:\n\
|
||||
phiOut_s$ID$.join(phiOutIn_s$ID$)\n\
|
||||
\n\
|
||||
setObstacleFlags(flags=flags_s$ID$, phiObs=phiObs_s$ID$, phiOut=phiOut_s$ID$, phiIn=phiIn_s$ID$)\n\
|
||||
flags_s$ID$.fillGrid()\n\
|
||||
\n\
|
||||
if timePerFrame_s$ID$ == 0: # Only apply inflow once per frame\n\
|
||||
mantaMsg('Smoke inflow at frame: ' + str(framenr))\n\
|
||||
applyEmission(flags=flags_s$ID$, target=density_s$ID$, source=densityIn_s$ID$, emissionTexture=emissionIn_s$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
if using_heat_s$ID$:\n\
|
||||
applyEmission(flags=flags_s$ID$, target=heat_s$ID$, source=heatIn_s$ID$, emissionTexture=emissionIn_s$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
\n\
|
||||
if using_colors_s$ID$:\n\
|
||||
applyEmission(flags=flags_s$ID$, target=color_r_s$ID$, source=color_r_in_s$ID$, emissionTexture=emissionIn_s$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
applyEmission(flags=flags_s$ID$, target=color_g_s$ID$, source=color_g_in_s$ID$, emissionTexture=emissionIn_s$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
applyEmission(flags=flags_s$ID$, target=color_b_s$ID$, source=color_b_in_s$ID$, emissionTexture=emissionIn_s$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
\n\
|
||||
if using_fire_s$ID$:\n\
|
||||
applyEmission(flags=flags_s$ID$, target=fuel_s$ID$, source=fuelIn_s$ID$, emissionTexture=emissionIn_s$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
applyEmission(flags=flags_s$ID$, target=react_s$ID$, source=reactIn_s$ID$, emissionTexture=emissionIn_s$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
\n\
|
||||
mantaMsg('Smoke step / s$ID$.frame: ' + str(s$ID$.frame))\n\
|
||||
if using_fire_s$ID$:\n\
|
||||
process_burn_$ID$()\n\
|
||||
smoke_step_$ID$()\n\
|
||||
if using_fire_s$ID$:\n\
|
||||
update_flame_$ID$()\n\
|
||||
\n\
|
||||
s$ID$.step()\n\
|
||||
\n\
|
||||
fluid_post_step_$ID$()\n";
|
||||
|
||||
const std::string smoke_step =
|
||||
"\n\
|
||||
def smoke_step_$ID$():\n\
|
||||
mantaMsg('Smoke step low')\n\
|
||||
\n\
|
||||
if using_dissolve_s$ID$:\n\
|
||||
mantaMsg('Dissolving smoke')\n\
|
||||
dissolveSmoke(flags=flags_s$ID$, density=density_s$ID$, heat=heat_s$ID$, red=color_r_s$ID$, green=color_g_s$ID$, blue=color_b_s$ID$, speed=dissolveSpeed_s$ID$, logFalloff=using_logdissolve_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Advecting density')\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=density_s$ID$, order=2)\n\
|
||||
\n\
|
||||
if using_heat_s$ID$:\n\
|
||||
mantaMsg('Advecting heat')\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=heat_s$ID$, order=2)\n\
|
||||
\n\
|
||||
if using_fire_s$ID$:\n\
|
||||
mantaMsg('Advecting fire')\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=fuel_s$ID$, order=2)\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=react_s$ID$, order=2)\n\
|
||||
\n\
|
||||
if using_colors_s$ID$:\n\
|
||||
mantaMsg('Advecting colors')\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=color_r_s$ID$, order=2)\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=color_g_s$ID$, order=2)\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=color_b_s$ID$, order=2)\n\
|
||||
\n\
|
||||
mantaMsg('Advecting velocity')\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=vel_s$ID$, order=2)\n\
|
||||
\n\
|
||||
if doOpen_s$ID$ or using_outflow_s$ID$:\n\
|
||||
resetOutflow(flags=flags_s$ID$, real=density_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Vorticity')\n\
|
||||
if using_fire_s$ID$:\n\
|
||||
flame_s$ID$.copyFrom(fuel_s$ID$) # temporarily misuse flame grid as vorticity storage\n\
|
||||
flame_s$ID$.multConst(flameVorticity_s$ID$)\n\
|
||||
vorticityConfinement(vel=vel_s$ID$, flags=flags_s$ID$, strengthGlobal=vorticity_s$ID$, strengthCell=flame_s$ID$ if using_fire_s$ID$ else None)\n\
|
||||
\n\
|
||||
if using_heat_s$ID$:\n\
|
||||
mantaMsg('Adding heat buoyancy')\n\
|
||||
addBuoyancy(flags=flags_s$ID$, density=heat_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_heat_s$ID$)\n\
|
||||
mantaMsg('Adding buoyancy')\n\
|
||||
addBuoyancy(flags=flags_s$ID$, density=density_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_dens_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Adding forces')\n\
|
||||
addForceField(flags=flags_s$ID$, vel=vel_s$ID$, force=forces_s$ID$)\n\
|
||||
\n\
|
||||
if using_obstacle_s$ID$:\n\
|
||||
mantaMsg('Extrapolating object velocity')\n\
|
||||
# ensure velocities inside of obs object, slightly add obvels outside of obs object\n\
|
||||
extrapolateVec3Simple(vel=obvelC_s$ID$, phi=phiObsIn_s$ID$, distance=int(res_s$ID$/2), inside=True)\n\
|
||||
extrapolateVec3Simple(vel=obvelC_s$ID$, phi=phiObsIn_s$ID$, distance=3, inside=False)\n\
|
||||
resampleVec3ToMac(source=obvelC_s$ID$, target=obvel_s$ID$)\n\
|
||||
\n\
|
||||
# add initial velocity\n\
|
||||
if using_invel_s$ID$:\n\
|
||||
resampleVec3ToMac(source=invelC_s$ID$, target=invel_s$ID$)\n\
|
||||
setInitialVelocity(flags=flags_s$ID$, vel=vel_s$ID$, invel=invel_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Walls')\n\
|
||||
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=obvel_s$ID$ if using_obstacle_s$ID$ else None)\n\
|
||||
\n\
|
||||
if using_guiding_s$ID$:\n\
|
||||
mantaMsg('Guiding and pressure')\n\
|
||||
PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, preconditioner=preconditioner_s$ID$, zeroPressureFixing=not doOpen_s$ID$)\n\
|
||||
else:\n\
|
||||
mantaMsg('Pressure')\n\
|
||||
solvePressure(flags=flags_s$ID$, vel=vel_s$ID$, pressure=pressure_s$ID$, preconditioner=preconditioner_s$ID$, zeroPressureFixing=not doOpen_s$ID$) # closed domains require pressure fixing\n\
|
||||
\n\
|
||||
def process_burn_$ID$():\n\
|
||||
mantaMsg('Process burn')\n\
|
||||
processBurn(fuel=fuel_s$ID$, density=density_s$ID$, react=react_s$ID$, red=color_r_s$ID$ if using_colors_s$ID$ else None, green=color_g_s$ID$ if using_colors_s$ID$ else None, blue=color_b_s$ID$ if using_colors_s$ID$ else None, heat=heat_s$ID$ if using_heat_s$ID$ else None, burningRate=burningRate_s$ID$, flameSmoke=flameSmoke_s$ID$, ignitionTemp=ignitionTemp_s$ID$, maxTemp=maxTemp_s$ID$, flameSmokeColor=flameSmokeColor_s$ID$)\n\
|
||||
\n\
|
||||
def update_flame_$ID$():\n\
|
||||
mantaMsg('Update flame')\n\
|
||||
updateFlame(react=react_s$ID$, flame=flame_s$ID$)\n";
|
||||
|
||||
const std::string smoke_step_noise =
|
||||
"\n\
|
||||
def smoke_step_noise_$ID$(framenr):\n\
|
||||
mantaMsg('Manta step noise, frame ' + str(framenr))\n\
|
||||
sn$ID$.frame = framenr\n\
|
||||
\n\
|
||||
copyRealToVec3(sourceX=texture_u_s$ID$, sourceY=texture_v_s$ID$, sourceZ=texture_w_s$ID$, target=uvGrid0_s$ID$)\n\
|
||||
copyRealToVec3(sourceX=texture_u2_s$ID$, sourceY=texture_v2_s$ID$, sourceZ=texture_w2_s$ID$, target=uvGrid1_s$ID$)\n\
|
||||
\n\
|
||||
flags_sn$ID$.initDomain(boundaryWidth=0, phiWalls=phiObs_sn$ID$, outflow=boundConditions_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Interpolating grids')\n\
|
||||
# Join big obstacle levelset after initDomain() call as it overwrites everything in phiObs\n\
|
||||
if using_obstacle_s$ID$:\n\
|
||||
interpolateGrid(target=phiIn_sn$ID$, source=phiObsIn_s$ID$) # mis-use phiIn_sn\n\
|
||||
phiObs_sn$ID$.join(phiIn_sn$ID$)\n\
|
||||
if using_outflow_s$ID$:\n\
|
||||
interpolateGrid(target=phiOut_sn$ID$, source=phiOut_s$ID$)\n\
|
||||
interpolateGrid(target=phiIn_sn$ID$, source=phiIn_s$ID$)\n\
|
||||
interpolateMACGrid(target=vel_sn$ID$, source=vel_s$ID$)\n\
|
||||
\n\
|
||||
setObstacleFlags(flags=flags_sn$ID$, phiObs=phiObs_sn$ID$, phiOut=phiOut_sn$ID$, phiIn=phiIn_sn$ID$)\n\
|
||||
flags_sn$ID$.fillGrid()\n\
|
||||
\n\
|
||||
# Interpolate emission grids and apply them to big noise grids\n\
|
||||
interpolateGrid(source=densityIn_s$ID$, target=tmpIn_sn$ID$)\n\
|
||||
interpolateGrid(source=emissionIn_s$ID$, target=emissionIn_sn$ID$)\n\
|
||||
\n\
|
||||
# Higher-res noise grid needs scaled emission values\n\
|
||||
tmpIn_sn$ID$.multConst(float(upres_sn$ID$))\n\
|
||||
applyEmission(flags=flags_sn$ID$, target=density_sn$ID$, source=tmpIn_sn$ID$, emissionTexture=emissionIn_sn$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
\n\
|
||||
if using_colors_s$ID$:\n\
|
||||
interpolateGrid(source=color_r_in_s$ID$, target=tmpIn_sn$ID$)\n\
|
||||
applyEmission(flags=flags_sn$ID$, target=color_r_sn$ID$, source=tmpIn_sn$ID$, emissionTexture=emissionIn_sn$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
interpolateGrid(source=color_g_in_s$ID$, target=tmpIn_sn$ID$)\n\
|
||||
applyEmission(flags=flags_sn$ID$, target=color_g_sn$ID$, source=tmpIn_sn$ID$, emissionTexture=emissionIn_sn$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
interpolateGrid(source=color_b_in_s$ID$, target=tmpIn_sn$ID$)\n\
|
||||
applyEmission(flags=flags_sn$ID$, target=color_b_sn$ID$, source=tmpIn_sn$ID$, emissionTexture=emissionIn_sn$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
\n\
|
||||
if using_fire_s$ID$:\n\
|
||||
interpolateGrid(source=fuelIn_s$ID$, target=tmpIn_sn$ID$)\n\
|
||||
applyEmission(flags=flags_sn$ID$, target=fuel_sn$ID$, source=tmpIn_sn$ID$, emissionTexture=emissionIn_sn$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
interpolateGrid(source=reactIn_s$ID$, target=tmpIn_sn$ID$)\n\
|
||||
applyEmission(flags=flags_sn$ID$, target=react_sn$ID$, source=tmpIn_sn$ID$, emissionTexture=emissionIn_sn$ID$, type=FlagInflow|FlagOutflow)\n\
|
||||
\n\
|
||||
mantaMsg('Noise step / sn$ID$.frame: ' + str(sn$ID$.frame))\n\
|
||||
if using_fire_s$ID$:\n\
|
||||
process_burn_noise_$ID$()\n\
|
||||
step_noise_$ID$()\n\
|
||||
if using_fire_s$ID$:\n\
|
||||
update_flame_noise_$ID$()\n\
|
||||
\n\
|
||||
sn$ID$.step()\n\
|
||||
\n\
|
||||
copyVec3ToReal(source=uvGrid0_s$ID$, targetX=texture_u_s$ID$, targetY=texture_v_s$ID$, targetZ=texture_w_s$ID$)\n\
|
||||
copyVec3ToReal(source=uvGrid1_s$ID$, targetX=texture_u2_s$ID$, targetY=texture_v2_s$ID$, targetZ=texture_w2_s$ID$)\n\
|
||||
\n\
|
||||
def step_noise_$ID$():\n\
|
||||
mantaMsg('Smoke step noise')\n\
|
||||
\n\
|
||||
if using_dissolve_s$ID$:\n\
|
||||
mantaMsg('Dissolving noise')\n\
|
||||
dissolveSmoke(flags=flags_sn$ID$, density=density_sn$ID$, heat=None, red=color_r_sn$ID$, green=color_g_sn$ID$, blue=color_b_sn$ID$, speed=dissolveSpeed_s$ID$, logFalloff=using_logdissolve_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Advecting UVs and updating UV weight')\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=uvGrid0_s$ID$, order=2)\n\
|
||||
updateUvWeight(resetTime=sn$ID$.timestep*10.0 , index=0, numUvs=uvs_s$ID$, uv=uvGrid0_s$ID$, offset=uvs_offset_s$ID$)\n\
|
||||
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=uvGrid1_s$ID$, order=2)\n\
|
||||
updateUvWeight(resetTime=sn$ID$.timestep*10.0 , index=1, numUvs=uvs_s$ID$, uv=uvGrid1_s$ID$, offset=uvs_offset_s$ID$)\n\
|
||||
\n\
|
||||
mantaMsg('Energy')\n\
|
||||
computeEnergy(flags=flags_s$ID$, vel=vel_s$ID$, energy=energy_s$ID$)\n\
|
||||
\n\
|
||||
tempFlag_s$ID$.copyFrom(flags_s$ID$)\n\
|
||||
extrapolateSimpleFlags(flags=flags_s$ID$, val=tempFlag_s$ID$, distance=2, flagFrom=FlagObstacle, flagTo=FlagFluid)\n\
|
||||
extrapolateSimpleFlags(flags=tempFlag_s$ID$, val=energy_s$ID$, distance=6, flagFrom=FlagFluid, flagTo=FlagObstacle)\n\
|
||||
computeWaveletCoeffs(energy_s$ID$)\n\
|
||||
\n\
|
||||
sStr_s$ID$ = 1.0 * wltStrength_s$ID$\n\
|
||||
sPos_s$ID$ = 2.0\n\
|
||||
\n\
|
||||
mantaMsg('Applying noise vec')\n\
|
||||
for o in range(octaves_s$ID$):\n\
|
||||
uvWeight_s$ID$ = getUvWeight(uvGrid0_s$ID$)\n\
|
||||
applyNoiseVec3(flags=flags_sn$ID$, target=vel_sn$ID$, noise=wltnoise_sn$ID$, scale=sStr_s$ID$ * uvWeight_s$ID$, scaleSpatial=sPos_s$ID$ , weight=energy_s$ID$, uv=uvGrid0_s$ID$)\n\
|
||||
uvWeight_s$ID$ = getUvWeight(uvGrid1_s$ID$)\n\
|
||||
applyNoiseVec3(flags=flags_sn$ID$, target=vel_sn$ID$, noise=wltnoise_sn$ID$, scale=sStr_s$ID$ * uvWeight_s$ID$, scaleSpatial=sPos_s$ID$ , weight=energy_s$ID$, uv=uvGrid1_s$ID$)\n\
|
||||
\n\
|
||||
sStr_s$ID$ *= 0.06 # magic kolmogorov factor \n\
|
||||
sPos_s$ID$ *= 2.0 \n\
|
||||
\n\
|
||||
for substep in range(int(upres_sn$ID$)):\n\
|
||||
if using_colors_s$ID$: \n\
|
||||
mantaMsg('Advecting colors noise')\n\
|
||||
advectSemiLagrange(flags=flags_sn$ID$, vel=vel_sn$ID$, grid=color_r_sn$ID$, order=2)\n\
|
||||
advectSemiLagrange(flags=flags_sn$ID$, vel=vel_sn$ID$, grid=color_g_sn$ID$, order=2)\n\
|
||||
advectSemiLagrange(flags=flags_sn$ID$, vel=vel_sn$ID$, grid=color_b_sn$ID$, order=2)\n\
|
||||
\n\
|
||||
if using_fire_s$ID$: \n\
|
||||
mantaMsg('Advecting fire noise')\n\
|
||||
advectSemiLagrange(flags=flags_sn$ID$, vel=vel_sn$ID$, grid=fuel_sn$ID$, order=2)\n\
|
||||
advectSemiLagrange(flags=flags_sn$ID$, vel=vel_sn$ID$, grid=react_sn$ID$, order=2)\n\
|
||||
\n\
|
||||
mantaMsg('Advecting density noise')\n\
|
||||
advectSemiLagrange(flags=flags_sn$ID$, vel=vel_sn$ID$, grid=density_sn$ID$, order=2)\n\
|
||||
\n\
|
||||
def process_burn_noise_$ID$():\n\
|
||||
mantaMsg('Process burn noise')\n\
|
||||
processBurn(fuel=fuel_sn$ID$, density=density_sn$ID$, react=react_sn$ID$, red=color_r_sn$ID$ if using_colors_s$ID$ else None, green=color_g_sn$ID$ if using_colors_s$ID$ else None, blue=color_b_sn$ID$ if using_colors_s$ID$ else None, burningRate=burningRate_s$ID$, flameSmoke=flameSmoke_s$ID$, ignitionTemp=ignitionTemp_s$ID$, maxTemp=maxTemp_s$ID$, flameSmokeColor=flameSmokeColor_s$ID$)\n\
|
||||
\n\
|
||||
def update_flame_noise_$ID$():\n\
|
||||
mantaMsg('Update flame noise')\n\
|
||||
updateFlame(react=react_sn$ID$, flame=flame_sn$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// IMPORT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string smoke_load_data =
|
||||
"\n\
|
||||
def smoke_load_data_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Smoke load data')\n\
|
||||
fluid_file_import_s$ID$(dict=smoke_data_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
|
||||
|
||||
const std::string smoke_load_noise =
|
||||
"\n\
|
||||
def smoke_load_noise_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Smoke load noise')\n\
|
||||
fluid_file_import_s$ID$(dict=smoke_noise_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n\
|
||||
\n\
|
||||
# Fill up xyz texture grids, important when resuming a bake\n\
|
||||
copyVec3ToReal(source=uvGrid0_s$ID$, targetX=texture_u_s$ID$, targetY=texture_v_s$ID$, targetZ=texture_w_s$ID$)\n\
|
||||
copyVec3ToReal(source=uvGrid1_s$ID$, targetX=texture_u2_s$ID$, targetY=texture_v2_s$ID$, targetZ=texture_w2_s$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// EXPORT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string smoke_save_data =
|
||||
"\n\
|
||||
def smoke_save_data_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Smoke save data')\n\
|
||||
start_time = time.time()\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(framenr=framenr, file_format=file_format, path=path, dict=smoke_data_dict_s$ID$,)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=smoke_data_dict_s$ID$, do_join=False)\n\
|
||||
mantaMsg('--- Save: %s seconds ---' % (time.time() - start_time))\n";
|
||||
|
||||
const std::string smoke_save_noise =
|
||||
"\n\
|
||||
def smoke_save_noise_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Smoke save noise')\n\
|
||||
if not withMPSave or isWindows:\n\
|
||||
fluid_file_export_s$ID$(dict=smoke_noise_dict_s$ID$, framenr=framenr, file_format=file_format, path=path)\n\
|
||||
else:\n\
|
||||
fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=smoke_noise_dict_s$ID$, do_join=False)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// STANDALONE MODE
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string smoke_standalone =
|
||||
"\n\
|
||||
# Helper function to call cache load functions\n\
|
||||
def load(frame):\n\
|
||||
fluid_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data)\n\
|
||||
smoke_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data)\n\
|
||||
if using_noise_s$ID$:\n\
|
||||
smoke_load_noise_$ID$(os.path.join(cache_dir, 'noise'), frame, file_format_noise)\n\
|
||||
if using_guiding_s$ID$:\n\
|
||||
fluid_load_guiding_$ID$(os.path.join(cache_dir, 'guiding'), frame, file_format_data)\n\
|
||||
\n\
|
||||
# Helper function to call step functions\n\
|
||||
def step(frame):\n\
|
||||
smoke_adaptive_step_$ID$(frame)\n\
|
||||
if using_noise_s$ID$:\n\
|
||||
smoke_step_noise_$ID$(frame)\n";
|
Loading…
Reference in New Issue
Block a user