Compare commits
2 Commits
tmp-eevee-
...
fluid-mant
Author | SHA1 | Date | |
---|---|---|---|
4e84e076b2 | |||
23d5bbd104 |
1
intern/mantaflow/extern/manta_fluid_API.h
vendored
1
intern/mantaflow/extern/manta_fluid_API.h
vendored
@@ -103,6 +103,7 @@ float *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);
|
||||
void manta_get_res(struct MANTA *fluid, int* res);
|
||||
float *manta_get_phi_in(struct MANTA *fluid);
|
||||
float *manta_get_phistatic_in(struct MANTA *fluid);
|
||||
float *manta_get_phiobs_in(struct MANTA *fluid);
|
||||
|
@@ -204,6 +204,14 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
|
||||
mResXParticle = mUpresParticle * mResX;
|
||||
mResYParticle = mUpresParticle * mResY;
|
||||
mResZParticle = mUpresParticle * mResZ;
|
||||
if (fds->solver_res == FLUID_DOMAIN_DIMENSION_2D) {
|
||||
if (fds->slice_axis == SLICE_AXIS_X)
|
||||
mResXParticle = 1;
|
||||
else if (fds->slice_axis == SLICE_AXIS_Y)
|
||||
mResYParticle = 1;
|
||||
else if (fds->slice_axis == SLICE_AXIS_Z)
|
||||
mResZParticle = 1;
|
||||
}
|
||||
mTotalCellsParticles = mResXParticle * mResYParticle * mResZParticle;
|
||||
|
||||
initSuccess &= initSndParts();
|
||||
@@ -266,6 +274,14 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
|
||||
mResXNoise = amplify * mResX;
|
||||
mResYNoise = amplify * mResY;
|
||||
mResZNoise = amplify * mResZ;
|
||||
if (fds->solver_res == FLUID_DOMAIN_DIMENSION_2D) {
|
||||
if (fds->slice_axis == SLICE_AXIS_X)
|
||||
mResXNoise = 1;
|
||||
else if (fds->slice_axis == SLICE_AXIS_Y)
|
||||
mResYNoise = 1;
|
||||
else if (fds->slice_axis == SLICE_AXIS_Z)
|
||||
mResZNoise = 1;
|
||||
}
|
||||
mTotalCellsHigh = mResXNoise * mResYNoise * mResZNoise;
|
||||
|
||||
/* Initialize Mantaflow variables in Python. */
|
||||
@@ -785,8 +801,10 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd)
|
||||
mRNAMap["BOUND_CONDITIONS"] = borderCollisions;
|
||||
mRNAMap["BOUNDARY_WIDTH"] = to_string(fds->boundary_width);
|
||||
mRNAMap["RES"] = to_string(mMaxRes);
|
||||
mRNAMap["RESX"] = to_string(mResX);
|
||||
mRNAMap["RESY"] = (is2D) ? to_string(mResZ) : to_string(mResY);
|
||||
mRNAMap["RESX"] = (is2D && fds->slice_axis == SLICE_AXIS_X) ? to_string(mResY) :
|
||||
to_string(mResX);
|
||||
mRNAMap["RESY"] = (is2D && fds->slice_axis != SLICE_AXIS_Z) ? to_string(mResZ) :
|
||||
to_string(mResY);
|
||||
mRNAMap["RESZ"] = (is2D) ? to_string(1) : to_string(mResZ);
|
||||
mRNAMap["TIME_SCALE"] = to_string(fds->time_scale);
|
||||
mRNAMap["FRAME_LENGTH"] = to_string(fds->frame_length);
|
||||
@@ -801,14 +819,18 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd)
|
||||
mRNAMap["NOISE_SCALE"] = to_string(fds->noise_scale);
|
||||
mRNAMap["MESH_SCALE"] = to_string(fds->mesh_scale);
|
||||
mRNAMap["PARTICLE_SCALE"] = to_string(fds->particle_scale);
|
||||
mRNAMap["NOISE_RESX"] = to_string(mResXNoise);
|
||||
mRNAMap["NOISE_RESY"] = (is2D) ? to_string(mResZNoise) : to_string(mResYNoise);
|
||||
mRNAMap["NOISE_RESX"] = (is2D && fds->slice_axis == SLICE_AXIS_X) ? to_string(mResYNoise) :
|
||||
to_string(mResXNoise);
|
||||
mRNAMap["NOISE_RESY"] = (is2D && fds->slice_axis != SLICE_AXIS_Z) ? to_string(mResZNoise) :
|
||||
to_string(mResYNoise);
|
||||
mRNAMap["NOISE_RESZ"] = (is2D) ? to_string(1) : to_string(mResZNoise);
|
||||
mRNAMap["MESH_RESX"] = to_string(mResXMesh);
|
||||
mRNAMap["MESH_RESY"] = (is2D) ? to_string(mResZMesh) : to_string(mResYMesh);
|
||||
mRNAMap["MESH_RESZ"] = (is2D) ? to_string(1) : to_string(mResZMesh);
|
||||
mRNAMap["PARTICLE_RESX"] = to_string(mResXParticle);
|
||||
mRNAMap["PARTICLE_RESY"] = (is2D) ? to_string(mResZParticle) : to_string(mResYParticle);
|
||||
mRNAMap["PARTICLE_RESX"] = (is2D && fds->slice_axis == SLICE_AXIS_X) ? to_string(mResYParticle) :
|
||||
to_string(mResXParticle);
|
||||
mRNAMap["PARTICLE_RESY"] = (is2D && fds->slice_axis != SLICE_AXIS_Z) ? to_string(mResZParticle) :
|
||||
to_string(mResYParticle);
|
||||
mRNAMap["PARTICLE_RESZ"] = (is2D) ? to_string(1) : to_string(mResZParticle);
|
||||
mRNAMap["GUIDING_RESX"] = to_string(mResGuiding[0]);
|
||||
mRNAMap["GUIDING_RESY"] = (is2D) ? to_string(mResGuiding[2]) : to_string(mResGuiding[1]);
|
||||
|
@@ -279,6 +279,12 @@ int manta_get_res_z(MANTA *fluid)
|
||||
{
|
||||
return fluid->getResZ();
|
||||
}
|
||||
void manta_get_res(MANTA *smoke, int *res)
|
||||
{
|
||||
res[0] = smoke->getResX();
|
||||
res[1] = smoke->getResY();
|
||||
res[2] = smoke->getResZ();
|
||||
}
|
||||
|
||||
float *manta_get_phi_in(MANTA *fluid)
|
||||
{
|
||||
|
@@ -62,22 +62,22 @@ 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";
|
||||
sn$ID$ = Solver(name='solver_noise$ID$', gridSize=gs_sn$ID$, dim=dim_s$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";
|
||||
sm$ID$ = Solver(name='solver_mesh$ID$', gridSize=gs_sm$ID$, dim=dim_s$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";
|
||||
sp$ID$ = Solver(name='solver_particles$ID$', gridSize=gs_sp$ID$, dim=dim_s$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";
|
||||
sg$ID$ = Solver(name='solver_guiding$ID$', gridSize=gs_sg$ID$, dim=dim_s$ID$)\n";
|
||||
|
||||
const std::string fluid_solver_viscosity =
|
||||
"\n\
|
||||
@@ -95,6 +95,11 @@ dim_s$ID$ = $SOLVER_DIM$\n\
|
||||
res_s$ID$ = $RES$\n\
|
||||
gravity_s$ID$ = vec3($GRAVITY_X$, $GRAVITY_Y$, $GRAVITY_Z$) # in SI unit (e.g. m/s^2)\n\
|
||||
gs_s$ID$ = vec3($RESX$, $RESY$, $RESZ$)\n\
|
||||
if dim_s$ID$ == 2:\n\
|
||||
gs_s$ID$.z = 1\n\
|
||||
gravity_s$ID$.y = gravity_s$ID$.z\n\
|
||||
gravity_s$ID$.z = 0\n\
|
||||
\n\
|
||||
maxVel_s$ID$ = 0\n\
|
||||
\n\
|
||||
domainClosed_s$ID$ = $DOMAIN_CLOSED$\n\
|
||||
@@ -178,24 +183,32 @@ 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";
|
||||
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\
|
||||
if dim_s$ID$ == 2:\n\
|
||||
gs_sn$ID$.z = 1\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";
|
||||
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\
|
||||
if dim_s$ID$ == 2:\n\
|
||||
gs_sm$ID$.z = 1\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";
|
||||
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\
|
||||
if dim_s$ID$ == 2:\n\
|
||||
gs_sp$ID$.z = 1\n";
|
||||
|
||||
const std::string fluid_variables_guiding =
|
||||
"\n\
|
||||
mantaMsg('Fluid variables guiding')\n\
|
||||
gs_sg$ID$ = vec3($GUIDING_RESX$, $GUIDING_RESY$, $GUIDING_RESZ$)\n\
|
||||
if dim_s$ID$ == 2:\n\
|
||||
gs_sg$ID$.z = 1\n\
|
||||
\n\
|
||||
alpha_sg$ID$ = $GUIDING_ALPHA$\n\
|
||||
beta_sg$ID$ = $GUIDING_BETA$\n\
|
||||
@@ -206,7 +219,9 @@ theta_sg$ID$ = 1.0\n";
|
||||
|
||||
const std::string fluid_variables_viscosity =
|
||||
"\n\
|
||||
gs_sv$ID$ = vec3($RESX$*2, $RESY$*2, $RESZ$*2)\n";
|
||||
gs_sv$ID$ = vec3($RESX$*2, $RESY$*2, $RESZ$*2)\n\
|
||||
if dim_s$ID$ == 2:\n\
|
||||
gs_sv$ID$.z = 1\n";
|
||||
|
||||
const std::string fluid_with_obstacle =
|
||||
"\n\
|
||||
|
@@ -197,6 +197,9 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel):
|
||||
if PhysicButtonsPanel.poll_gas_domain(context):
|
||||
col.prop(domain, "clipping", text="Empty Space")
|
||||
col.prop(domain, "delete_in_obstacle", text="Delete in Obstacle")
|
||||
col.prop(domain, "solver_res", text="Dimension")
|
||||
if domain.solver_res == '2D':
|
||||
col.prop(domain, "slice_axis", text="Axis")
|
||||
|
||||
if domain.cache_type == 'MODULAR':
|
||||
col.separator()
|
||||
@@ -1379,7 +1382,8 @@ class PHYSICS_PT_viewport_display_slicing(PhysicButtonsPanel, Panel):
|
||||
layout.active = domain.use_slice
|
||||
|
||||
col = layout.column()
|
||||
col.prop(domain, "slice_axis")
|
||||
if domain.solver_res == '3D':
|
||||
col.prop(domain, "slice_axis")
|
||||
col.prop(domain, "slice_depth")
|
||||
|
||||
sub = col.column()
|
||||
|
@@ -89,6 +89,9 @@ void BKE_fluid_particles_set(struct FluidDomainSettings *settings, int value, bo
|
||||
void BKE_fluid_domain_type_set(struct Object *object,
|
||||
struct FluidDomainSettings *settings,
|
||||
int type);
|
||||
void BKE_fluid_domain_solver_res_set(struct Object *object,
|
||||
struct FluidDomainSettings *settings,
|
||||
int type);
|
||||
void BKE_fluid_flow_type_set(struct Object *object, struct FluidFlowSettings *settings, int type);
|
||||
void BKE_fluid_effector_type_set(struct Object *object,
|
||||
struct FluidEffectorSettings *settings,
|
||||
|
@@ -126,10 +126,6 @@ bool BKE_fluid_reallocate_fluid(FluidDomainSettings *fds, int res[3], int free_o
|
||||
}
|
||||
else {
|
||||
fds->fluid = manta_init(res, fds->fmd);
|
||||
|
||||
fds->res_noise[0] = res[0] * fds->noise_scale;
|
||||
fds->res_noise[1] = res[1] * fds->noise_scale;
|
||||
fds->res_noise[2] = res[2] * fds->noise_scale;
|
||||
}
|
||||
|
||||
return (fds->fluid != NULL);
|
||||
@@ -145,7 +141,10 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
|
||||
int n_shift[3])
|
||||
{
|
||||
struct MANTA *fluid_old = fds->fluid;
|
||||
const int block_size = fds->noise_scale;
|
||||
int block_size[3] = {fds->noise_scale, fds->noise_scale, fds->noise_scale};
|
||||
if (fds->solver_res == FLUID_DOMAIN_DIMENSION_2D) {
|
||||
block_size[fds->slice_axis - 1] = 1;
|
||||
}
|
||||
int new_shift[3] = {0};
|
||||
sub_v3_v3v3_int(new_shift, n_shift, o_shift);
|
||||
|
||||
@@ -210,8 +209,9 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
|
||||
float *n_wt_tcv2 = manta_noise_get_texture_v2(fds->fluid);
|
||||
float *n_wt_tcw2 = manta_noise_get_texture_w2(fds->fluid);
|
||||
|
||||
int wt_res_old[3];
|
||||
manta_noise_get_res(fluid_old, wt_res_old);
|
||||
int res_noise[3], res_noise_old[3];
|
||||
manta_noise_get_res(fds->fluid, res_noise);
|
||||
manta_noise_get_res(fluid_old, res_noise_old);
|
||||
|
||||
for (int z = o_min[2]; z < o_max[2]; z++) {
|
||||
for (int y = o_min[1]; y < o_max[1]; y++) {
|
||||
@@ -257,13 +257,13 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
|
||||
if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
|
||||
int i, j, k;
|
||||
/* old grid index */
|
||||
int xx_o = xo * block_size;
|
||||
int yy_o = yo * block_size;
|
||||
int zz_o = zo * block_size;
|
||||
int xx_o = xo * block_size[0];
|
||||
int yy_o = yo * block_size[1];
|
||||
int zz_o = zo * block_size[2];
|
||||
/* new grid index */
|
||||
int xx_n = xn * block_size;
|
||||
int yy_n = yn * block_size;
|
||||
int zz_n = zn * block_size;
|
||||
int xx_n = xn * block_size[0];
|
||||
int yy_n = yn * block_size[1];
|
||||
int zz_n = zn * block_size[2];
|
||||
|
||||
/* insert old texture values into new texture grids */
|
||||
n_wt_tcu[index_new] = o_wt_tcu[index_old];
|
||||
@@ -274,13 +274,13 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
|
||||
n_wt_tcv2[index_new] = o_wt_tcv2[index_old];
|
||||
n_wt_tcw2[index_new] = o_wt_tcw2[index_old];
|
||||
|
||||
for (i = 0; i < block_size; i++) {
|
||||
for (j = 0; j < block_size; j++) {
|
||||
for (k = 0; k < block_size; k++) {
|
||||
for (i = 0; i < block_size[0]; i++) {
|
||||
for (j = 0; j < block_size[1]; j++) {
|
||||
for (k = 0; k < block_size[2]; k++) {
|
||||
int big_index_old = manta_get_index(
|
||||
xx_o + i, wt_res_old[0], yy_o + j, wt_res_old[1], zz_o + k);
|
||||
xx_o + i, res_noise_old[0], yy_o + j, res_noise_old[1], zz_o + k);
|
||||
int big_index_new = manta_get_index(
|
||||
xx_n + i, fds->res_noise[0], yy_n + j, fds->res_noise[1], zz_n + k);
|
||||
xx_n + i, res_noise[0], yy_n + j, res_noise[1], zz_n + k);
|
||||
/* copy data */
|
||||
n_wt_dens[big_index_new] = o_wt_dens[big_index_old];
|
||||
if (n_wt_flame && o_wt_flame) {
|
||||
@@ -455,27 +455,32 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_2D = (fds->solver_res == FLUID_DOMAIN_DIMENSION_2D);
|
||||
const bool is_axis_X = (fds->slice_axis == SLICE_AXIS_X);
|
||||
const bool is_axis_Y = (fds->slice_axis == SLICE_AXIS_Y);
|
||||
const bool is_axis_Z = (fds->slice_axis == SLICE_AXIS_Z);
|
||||
|
||||
/* Define grid resolutions from longest domain side. */
|
||||
if (size[0] >= MAX2(size[1], size[2])) {
|
||||
scale = res / size[0];
|
||||
fds->scale = size[0] / fabsf(ob->scale[0]);
|
||||
fds->base_res[0] = res;
|
||||
fds->base_res[1] = max_ii((int)(size[1] * scale + 0.5f), 4);
|
||||
fds->base_res[2] = max_ii((int)(size[2] * scale + 0.5f), 4);
|
||||
fds->base_res[0] = (is_2D && is_axis_X) ? 1 : res;
|
||||
fds->base_res[1] = (is_2D && is_axis_Y) ? 1 : max_ii((int)(size[1] * scale + 0.5f), 4);
|
||||
fds->base_res[2] = (is_2D && is_axis_Z) ? 1 : max_ii((int)(size[2] * scale + 0.5f), 4);
|
||||
}
|
||||
else if (size[1] >= MAX2(size[0], size[2])) {
|
||||
scale = res / size[1];
|
||||
fds->scale = size[1] / fabsf(ob->scale[1]);
|
||||
fds->base_res[0] = max_ii((int)(size[0] * scale + 0.5f), 4);
|
||||
fds->base_res[1] = res;
|
||||
fds->base_res[2] = max_ii((int)(size[2] * scale + 0.5f), 4);
|
||||
fds->base_res[0] = (is_2D && is_axis_X) ? 1 : max_ii((int)(size[0] * scale + 0.5f), 4);
|
||||
fds->base_res[1] = (is_2D && is_axis_Y) ? 1 : res;
|
||||
fds->base_res[2] = (is_2D && is_axis_Z) ? 1 : max_ii((int)(size[2] * scale + 0.5f), 4);
|
||||
}
|
||||
else {
|
||||
scale = res / size[2];
|
||||
fds->scale = size[2] / fabsf(ob->scale[2]);
|
||||
fds->base_res[0] = max_ii((int)(size[0] * scale + 0.5f), 4);
|
||||
fds->base_res[1] = max_ii((int)(size[1] * scale + 0.5f), 4);
|
||||
fds->base_res[2] = res;
|
||||
fds->base_res[0] = (is_2D && is_axis_X) ? 1 : max_ii((int)(size[0] * scale + 0.5f), 4);
|
||||
fds->base_res[1] = (is_2D && is_axis_Y) ? 1 : max_ii((int)(size[1] * scale + 0.5f), 4);
|
||||
fds->base_res[2] = (is_2D && is_axis_Z) ? 1 : res;
|
||||
}
|
||||
|
||||
/* Set cell size. */
|
||||
@@ -2270,7 +2275,10 @@ static void adaptive_domain_adjust(
|
||||
fds->p1[2] = fds->p0[2] + fds->cell_size[2] * fds->base_res[2];
|
||||
|
||||
/* adjust domain resolution */
|
||||
const int block_size = fds->noise_scale;
|
||||
int block_size[3] = {fds->noise_scale, fds->noise_scale, fds->noise_scale};
|
||||
if (fds->solver_res == FLUID_DOMAIN_DIMENSION_2D) {
|
||||
block_size[fds->slice_axis - 1] = 1;
|
||||
}
|
||||
int min[3] = {32767, 32767, 32767}, max[3] = {-32767, -32767, -32767}, res[3];
|
||||
int total_cells = 1, res_changed = 0, shift_changed = 0;
|
||||
float min_vel[3], max_vel[3];
|
||||
@@ -2282,10 +2290,10 @@ static void adaptive_domain_adjust(
|
||||
float *vx = manta_get_velocity_x(fds->fluid);
|
||||
float *vy = manta_get_velocity_y(fds->fluid);
|
||||
float *vz = manta_get_velocity_z(fds->fluid);
|
||||
int wt_res[3];
|
||||
|
||||
int res_noise[3];
|
||||
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
|
||||
manta_noise_get_res(fds->fluid, wt_res);
|
||||
manta_noise_get_res(fds->fluid, res_noise);
|
||||
}
|
||||
|
||||
INIT_MINMAX(min_vel, max_vel);
|
||||
@@ -2317,14 +2325,15 @@ static void adaptive_domain_adjust(
|
||||
if (max_den < fds->adapt_threshold && fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
|
||||
int i, j, k;
|
||||
/* high res grid index */
|
||||
int xx = (x - fds->res_min[0]) * block_size;
|
||||
int yy = (y - fds->res_min[1]) * block_size;
|
||||
int zz = (z - fds->res_min[2]) * block_size;
|
||||
int xx = (x - fds->res_min[0]) * block_size[0];
|
||||
int yy = (y - fds->res_min[1]) * block_size[1];
|
||||
int zz = (z - fds->res_min[2]) * block_size[2];
|
||||
|
||||
for (i = 0; i < block_size; i++) {
|
||||
for (j = 0; j < block_size; j++) {
|
||||
for (k = 0; k < block_size; k++) {
|
||||
int big_index = manta_get_index(xx + i, wt_res[0], yy + j, wt_res[1], zz + k);
|
||||
for (i = 0; i < block_size[0]; i++) {
|
||||
for (j = 0; j < block_size[1]; j++) {
|
||||
for (k = 0; k < block_size[2]; k++) {
|
||||
int big_index = manta_get_index(
|
||||
xx + i, res_noise[0], yy + j, res_noise[1], zz + k);
|
||||
float den = (bigfuel) ? MAX2(bigdensity[big_index], bigfuel[big_index]) :
|
||||
bigdensity[big_index];
|
||||
if (den > max_den) {
|
||||
@@ -4708,6 +4717,16 @@ void BKE_fluid_effector_type_set(Object *UNUSED(object), FluidEffectorSettings *
|
||||
settings->type = type;
|
||||
}
|
||||
|
||||
void BKE_fluid_domain_solver_res_set(Object *UNUSED(object),
|
||||
FluidDomainSettings *settings,
|
||||
int res)
|
||||
{
|
||||
if (res == FLUID_DOMAIN_DIMENSION_2D && settings->slice_axis == SLICE_AXIS_AUTO) {
|
||||
settings->slice_axis = SLICE_AXIS_X;
|
||||
}
|
||||
settings->solver_res = res;
|
||||
}
|
||||
|
||||
void BKE_fluid_fields_sanitize(FluidDomainSettings *settings)
|
||||
{
|
||||
/* Based on the domain type, certain fields are defaulted accordingly if the selected field
|
||||
|
@@ -4379,6 +4379,21 @@ static void particles_fluid_step(ParticleSimulationData *sim,
|
||||
const float posParticle[3] = {posX, posY, posZ};
|
||||
copy_v3_v3(pa->state.co, posParticle);
|
||||
|
||||
/* Adjust particle position for 2d representation. */
|
||||
if (fds->solver_res == FLUID_DOMAIN_DIMENSION_2D) {
|
||||
if (fds->slice_axis == SLICE_AXIS_X) {
|
||||
float tmp = pa->state.co[1];
|
||||
pa->state.co[1] = pa->state.co[0];
|
||||
pa->state.co[0] = pa->state.co[2];
|
||||
pa->state.co[2] = tmp;
|
||||
}
|
||||
if (fds->slice_axis == SLICE_AXIS_Y) {
|
||||
float tmp = pa->state.co[1];
|
||||
pa->state.co[1] = pa->state.co[2];
|
||||
pa->state.co[2] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Normalize to unit cube around 0. */
|
||||
float resDomain[3] = {resX, resY, resZ};
|
||||
mul_v3_fl(resDomain, 0.5f);
|
||||
@@ -4412,6 +4427,21 @@ static void particles_fluid_step(ParticleSimulationData *sim,
|
||||
const float velParticle[3] = {velX, velY, velZ};
|
||||
copy_v3_v3(pa->state.vel, velParticle);
|
||||
mul_v3_fl(pa->state.vel, fds->dx);
|
||||
|
||||
/* Adjust particle velocity for 2d representation. */
|
||||
if (fds->solver_res == FLUID_DOMAIN_DIMENSION_2D) {
|
||||
if (fds->slice_axis == SLICE_AXIS_X) {
|
||||
float tmp = pa->state.vel[1];
|
||||
pa->state.vel[0] = pa->state.vel[2];
|
||||
pa->state.vel[1] = pa->state.vel[0];
|
||||
pa->state.vel[2] = tmp;
|
||||
}
|
||||
else if (fds->slice_axis == SLICE_AXIS_Y) {
|
||||
float tmp = pa->state.vel[1];
|
||||
pa->state.vel[1] = pa->state.vel[2];
|
||||
pa->state.vel[2] = tmp;
|
||||
}
|
||||
}
|
||||
# if 0
|
||||
/* Debugging: Print particle velocity. */
|
||||
printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n",
|
||||
|
@@ -1392,15 +1392,20 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
|
||||
const bool color_range = (fds->gridlines_color_field == FLUID_GRIDLINE_COLOR_TYPE_RANGE &&
|
||||
fds->use_coba && fds->coba_field != FLUID_DOMAIN_FIELD_FLAGS);
|
||||
|
||||
const bool is_2D = (fds->solver_res == FLUID_DOMAIN_DIMENSION_2D);
|
||||
const bool is_axis_X = (fds->slice_axis == SLICE_AXIS_X);
|
||||
const bool is_axis_Y = (fds->slice_axis == SLICE_AXIS_Y);
|
||||
const bool is_axis_Z = (fds->slice_axis == SLICE_AXIS_Z);
|
||||
|
||||
/* Small cube showing voxel size. */
|
||||
{
|
||||
float min[3];
|
||||
madd_v3fl_v3fl_v3fl_v3i(min, fds->p0, fds->cell_size, fds->res_min);
|
||||
float voxel_cubemat[4][4] = {{0.0f}};
|
||||
/* scale small cube to voxel size */
|
||||
voxel_cubemat[0][0] = fds->cell_size[0] / 2.0f;
|
||||
voxel_cubemat[1][1] = fds->cell_size[1] / 2.0f;
|
||||
voxel_cubemat[2][2] = fds->cell_size[2] / 2.0f;
|
||||
voxel_cubemat[0][0] = (is_2D && is_axis_X) ? 0.0f : (fds->cell_size[0] / 2.0f);
|
||||
voxel_cubemat[1][1] = (is_2D && is_axis_Y) ? 0.0f : (fds->cell_size[1] / 2.0f);
|
||||
voxel_cubemat[2][2] = (is_2D && is_axis_Z) ? 0.0f : (fds->cell_size[2] / 2.0f);
|
||||
voxel_cubemat[3][3] = 1.0f;
|
||||
/* translate small cube to corner */
|
||||
copy_v3_v3(voxel_cubemat[3], min);
|
||||
|
@@ -92,7 +92,8 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata,
|
||||
return;
|
||||
}
|
||||
|
||||
const bool use_slice = (fds->axis_slice_method == AXIS_SLICE_SINGLE);
|
||||
const bool use_slice = (fds->axis_slice_method == AXIS_SLICE_SINGLE) ||
|
||||
(fds->solver_res == FLUID_DOMAIN_DIMENSION_2D);
|
||||
const bool show_phi = ELEM(fds->coba_field,
|
||||
FLUID_DOMAIN_FIELD_PHI,
|
||||
FLUID_DOMAIN_FIELD_PHI_IN,
|
||||
|
@@ -327,7 +327,13 @@ static GPUTexture *create_field_texture(FluidDomainSettings *fds, bool single_pr
|
||||
|
||||
static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
|
||||
{
|
||||
int *dim = (highres) ? fds->res_noise : fds->res;
|
||||
int res[3];
|
||||
if (highres) {
|
||||
manta_noise_get_res(fds->fluid, res);
|
||||
}
|
||||
else {
|
||||
manta_get_res(fds->fluid, res);
|
||||
}
|
||||
|
||||
float *data;
|
||||
if (highres) {
|
||||
@@ -341,7 +347,7 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GPUTexture *tex = create_volume_texture(dim, GPU_R8, GPU_DATA_FLOAT, data);
|
||||
GPUTexture *tex = create_volume_texture(res, GPU_R8, GPU_DATA_FLOAT, data);
|
||||
swizzle_texture_channel_single(tex);
|
||||
return tex;
|
||||
}
|
||||
@@ -356,7 +362,15 @@ static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
|
||||
}
|
||||
|
||||
int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells;
|
||||
int *dim = (highres) ? fds->res_noise : fds->res;
|
||||
|
||||
int res[3];
|
||||
if (highres) {
|
||||
manta_noise_get_res(fds->fluid, res);
|
||||
}
|
||||
else {
|
||||
manta_get_res(fds->fluid, res);
|
||||
}
|
||||
|
||||
float *data = (float *)MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
|
||||
|
||||
if (data == NULL) {
|
||||
@@ -370,7 +384,7 @@ static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
|
||||
manta_smoke_get_rgba(fds->fluid, data, 0);
|
||||
}
|
||||
|
||||
GPUTexture *tex = create_volume_texture(dim, GPU_RGBA8, GPU_DATA_FLOAT, data);
|
||||
GPUTexture *tex = create_volume_texture(res, GPU_RGBA8, GPU_DATA_FLOAT, data);
|
||||
|
||||
MEM_freeN(data);
|
||||
|
||||
@@ -382,7 +396,14 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
|
||||
float *source = NULL;
|
||||
const bool has_fuel = (highres) ? manta_noise_has_fuel(fds->fluid) :
|
||||
manta_smoke_has_fuel(fds->fluid);
|
||||
int *dim = (highres) ? fds->res_noise : fds->res;
|
||||
|
||||
int res[3];
|
||||
if (highres) {
|
||||
manta_noise_get_res(fds->fluid, res);
|
||||
}
|
||||
else {
|
||||
manta_get_res(fds->fluid, res);
|
||||
}
|
||||
|
||||
if (!has_fuel) {
|
||||
return NULL;
|
||||
@@ -395,7 +416,7 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
|
||||
source = manta_smoke_get_flame(fds->fluid);
|
||||
}
|
||||
|
||||
GPUTexture *tex = create_volume_texture(dim, GPU_R8, GPU_DATA_FLOAT, source);
|
||||
GPUTexture *tex = create_volume_texture(res, GPU_R8, GPU_DATA_FLOAT, source);
|
||||
swizzle_texture_channel_single(tex);
|
||||
return tex;
|
||||
}
|
||||
|
@@ -99,7 +99,6 @@
|
||||
.noise_strength = 1.0f, \
|
||||
.noise_pos_scale = 2.0f, \
|
||||
.noise_time_anim = 0.1f, \
|
||||
.res_noise = {0, 0, 0}, \
|
||||
.noise_scale = 2, \
|
||||
.particle_randomness = 0.1f, \
|
||||
.particle_number = 2, \
|
||||
|
@@ -198,6 +198,12 @@ enum {
|
||||
FLUID_DOMAIN_TYPE_LIQUID = 1,
|
||||
};
|
||||
|
||||
/* Fluid domain dimension. */
|
||||
enum {
|
||||
FLUID_DOMAIN_DIMENSION_2D = 2,
|
||||
FLUID_DOMAIN_DIMENSION_3D = 3,
|
||||
};
|
||||
|
||||
/* Mesh levelset generator types. */
|
||||
enum {
|
||||
FLUID_DOMAIN_MESH_IMPROVED = 0,
|
||||
@@ -573,9 +579,7 @@ typedef struct FluidDomainSettings {
|
||||
float noise_strength;
|
||||
float noise_pos_scale;
|
||||
float noise_time_anim;
|
||||
int res_noise[3];
|
||||
int noise_scale;
|
||||
char _pad3[4]; /* Unused. */
|
||||
|
||||
/* Liquid domain options. */
|
||||
float particle_randomness;
|
||||
@@ -589,11 +593,11 @@ typedef struct FluidDomainSettings {
|
||||
float flip_ratio;
|
||||
int sys_particle_maximum;
|
||||
short simulation_method;
|
||||
char _pad4[6];
|
||||
char _pad3[6];
|
||||
|
||||
/* Viscosity options. */
|
||||
float viscosity_value;
|
||||
char _pad5[4];
|
||||
char _pad4[4];
|
||||
|
||||
/* Diffusion options. */
|
||||
float surface_tension;
|
||||
@@ -609,7 +613,7 @@ typedef struct FluidDomainSettings {
|
||||
int mesh_scale;
|
||||
int totvert;
|
||||
short mesh_generator;
|
||||
char _pad6[6]; /* Unused. */
|
||||
char _pad5[6]; /* Unused. */
|
||||
|
||||
/* Secondary particle options. */
|
||||
int particle_type;
|
||||
@@ -630,7 +634,7 @@ typedef struct FluidDomainSettings {
|
||||
int sndparticle_update_radius;
|
||||
char sndparticle_boundary;
|
||||
char sndparticle_combined_export;
|
||||
char _pad7[6]; /* Unused. */
|
||||
char _pad6[6]; /* Unused. */
|
||||
|
||||
/* Fluid guiding options. */
|
||||
float guide_alpha; /* Guiding weight scalar (determines strength). */
|
||||
@@ -638,7 +642,7 @@ typedef struct FluidDomainSettings {
|
||||
float guide_vel_factor; /* Multiply guiding velocity by this factor. */
|
||||
int guide_res[3]; /* Res for velocity guide grids - independent from base res. */
|
||||
short guide_source;
|
||||
char _pad8[2]; /* Unused. */
|
||||
char _pad7[2]; /* Unused. */
|
||||
|
||||
/* Cache options. */
|
||||
int cache_frame_start;
|
||||
@@ -658,7 +662,7 @@ typedef struct FluidDomainSettings {
|
||||
char error[64]; /* Bake error description. */
|
||||
short cache_type;
|
||||
char cache_id[4]; /* Run-time only */
|
||||
char _pad9[2]; /* Unused. */
|
||||
char _pad8[2]; /* Unused. */
|
||||
|
||||
/* Time options. */
|
||||
float dt;
|
||||
@@ -693,19 +697,19 @@ typedef struct FluidDomainSettings {
|
||||
char interp_method;
|
||||
char gridlines_color_field; /* Simulation field used to color map onto gridlines. */
|
||||
char gridlines_cell_filter;
|
||||
char _pad10[7]; /* Unused. */
|
||||
char _pad9[7]; /* Unused. */
|
||||
|
||||
/* OpenVDB cache options. */
|
||||
int openvdb_compression;
|
||||
float clipping;
|
||||
char openvdb_data_depth;
|
||||
char _pad11[7]; /* Unused. */
|
||||
char _pad10[7]; /* Unused. */
|
||||
|
||||
/* -- Deprecated / unsed options (below). -- */
|
||||
|
||||
/* View options. */
|
||||
int viewsettings;
|
||||
char _pad12[4]; /* Unused. */
|
||||
char _pad11[4]; /* Unused. */
|
||||
|
||||
/* Pointcache options. */
|
||||
/* Smoke uses only one cache from now on (index [0]), but keeping the array for now for reading
|
||||
@@ -715,7 +719,7 @@ typedef struct FluidDomainSettings {
|
||||
int cache_comp;
|
||||
int cache_high_comp;
|
||||
char cache_file_format;
|
||||
char _pad13[7]; /* Unused. */
|
||||
char _pad12[7]; /* Unused. */
|
||||
|
||||
} FluidDomainSettings;
|
||||
|
||||
|
@@ -220,6 +220,16 @@ static void rna_Fluid_reset_dependency(Main *bmain, Scene *scene, PointerRNA *pt
|
||||
rna_Fluid_dependency_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_Fluid_slice_axis_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
# ifdef WITH_FLUID
|
||||
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
|
||||
if (settings->solver_res == FLUID_DOMAIN_DIMENSION_2D) {
|
||||
rna_Fluid_domain_data_reset(bmain, scene, ptr);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
static void rna_Fluid_parts_create(Main *bmain,
|
||||
PointerRNA *ptr,
|
||||
const char *pset_name,
|
||||
@@ -863,6 +873,60 @@ static const EnumPropertyItem *rna_Fluid_data_depth_itemf(bContext *UNUSED(C),
|
||||
return item;
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_Fluid_slice_axis_itemf(bContext *UNUSED(C),
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *UNUSED(prop),
|
||||
bool *r_free)
|
||||
{
|
||||
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
|
||||
|
||||
EnumPropertyItem *item = NULL;
|
||||
EnumPropertyItem tmp = {0, "", 0, "", ""};
|
||||
int totitem = 0;
|
||||
|
||||
if (settings->solver_res == FLUID_DOMAIN_DIMENSION_3D) {
|
||||
tmp.value = SLICE_AXIS_AUTO;
|
||||
tmp.identifier = "AUTO";
|
||||
tmp.icon = 0;
|
||||
tmp.name = "Auto";
|
||||
tmp.description = "Adjust slice direction according to the view direction";
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
}
|
||||
|
||||
tmp.value = SLICE_AXIS_X;
|
||||
tmp.identifier = "X";
|
||||
tmp.icon = 0;
|
||||
tmp.name = "X";
|
||||
tmp.description = "Slice along the X axis";
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
|
||||
tmp.value = SLICE_AXIS_Y;
|
||||
tmp.identifier = "Y";
|
||||
tmp.icon = 0;
|
||||
tmp.name = "Y";
|
||||
tmp.description = "Slice along the Y axis";
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
|
||||
tmp.value = SLICE_AXIS_Z;
|
||||
tmp.identifier = "Z";
|
||||
tmp.icon = 0;
|
||||
tmp.name = "Z";
|
||||
tmp.description = "Slice along the Z axis";
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
|
||||
RNA_enum_item_end(&item, &totitem);
|
||||
*r_free = true;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static void rna_Fluid_solver_res_set(struct PointerRNA *ptr, int value)
|
||||
{
|
||||
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
BKE_fluid_domain_solver_res_set(ob, settings, value);
|
||||
}
|
||||
|
||||
static void rna_Fluid_domaintype_set(struct PointerRNA *ptr, int value)
|
||||
{
|
||||
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
|
||||
@@ -1268,6 +1332,12 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
|
||||
{FLUID_DOMAIN_TYPE_LIQUID, "LIQUID", 0, "Liquid", "Create domain for liquids"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem solver_res_items[] = {
|
||||
{FLUID_DOMAIN_DIMENSION_2D, "2D", 0, "2D", "Create 2D domain"},
|
||||
{FLUID_DOMAIN_DIMENSION_3D, "3D", 0, "3D", "Create 3D domain"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem prop_compression_items[] = {
|
||||
{VDB_COMPRESSION_ZIP, "ZIP", 0, "Zip", "Effective but slow compression"},
|
||||
# ifdef WITH_OPENVDB_BLOSC
|
||||
@@ -1351,15 +1421,9 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
/* Axis options are generated dynamically based on domain dimension (2D or 3D). */
|
||||
static const EnumPropertyItem axis_slice_position_items[] = {
|
||||
{SLICE_AXIS_AUTO,
|
||||
"AUTO",
|
||||
0,
|
||||
"Auto",
|
||||
"Adjust slice direction according to the view direction"},
|
||||
{SLICE_AXIS_X, "X", 0, "X", "Slice along the X axis"},
|
||||
{SLICE_AXIS_Y, "Y", 0, "Y", "Slice along the Y axis"},
|
||||
{SLICE_AXIS_Z, "Z", 0, "Z", "Slice along the Z axis"},
|
||||
{0, "NONE", 0, "", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -1670,6 +1734,13 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_flip_parts_update");
|
||||
|
||||
prop = RNA_def_property(srna, "solver_res", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, solver_res_items);
|
||||
RNA_def_property_enum_funcs(prop, NULL, "rna_Fluid_solver_res_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Dimension", "Change the solver resolution");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_datacache_reset");
|
||||
|
||||
prop = RNA_def_property(srna, "delete_in_obstacle", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", FLUID_DOMAIN_DELETE_IN_OBSTACLE);
|
||||
RNA_def_property_ui_text(prop, "Clear In Obstacle", "Delete fluid inside obstacles");
|
||||
@@ -2518,8 +2589,9 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "slice_axis", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "slice_axis");
|
||||
RNA_def_property_enum_items(prop, axis_slice_position_items);
|
||||
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Fluid_slice_axis_itemf");
|
||||
RNA_def_property_ui_text(prop, "Axis", "");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_slice_axis_reset");
|
||||
|
||||
prop = RNA_def_property(srna, "slice_per_voxel", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "slice_per_voxel");
|
||||
|
Reference in New Issue
Block a user