Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/fluid.c
| Show All 33 Lines | |||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "DNA_defaults.h" | #include "DNA_defaults.h" | ||||
| #include "DNA_fluid_types.h" | #include "DNA_fluid_types.h" | ||||
| #include "DNA_modifier_types.h" | #include "DNA_modifier_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_rigidbody_types.h" | #include "DNA_rigidbody_types.h" | ||||
| #include "BKE_attribute.h" | |||||
| #include "BKE_effect.h" | #include "BKE_effect.h" | ||||
| #include "BKE_fluid.h" | #include "BKE_fluid.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_pointcache.h" | #include "BKE_pointcache.h" | ||||
| #ifdef WITH_FLUID | #ifdef WITH_FLUID | ||||
| ▲ Show 20 Lines • Show All 474 Lines • ▼ Show 20 Lines | else { | ||||
| copy_v3_v3_int(res, fds->base_res); | copy_v3_v3_int(res, fds->base_res); | ||||
| } | } | ||||
| copy_v3_v3_int(fds->res, res); | copy_v3_v3_int(fds->res, res); | ||||
| fds->total_cells = fds->res[0] * fds->res[1] * fds->res[2]; | fds->total_cells = fds->res[0] * fds->res[1] * fds->res[2]; | ||||
| fds->res_min[0] = fds->res_min[1] = fds->res_min[2] = 0; | fds->res_min[0] = fds->res_min[1] = fds->res_min[2] = 0; | ||||
| copy_v3_v3_int(fds->res_max, res); | copy_v3_v3_int(fds->res_max, res); | ||||
| /* Set time, frame length = 0.1 is at 25fps. */ | /* Set time, frame length = 0.1 is at 25fps. */ | ||||
| float fps = scene->r.frs_sec / scene->r.frs_sec_base; | fds->frame_length = DT_DEFAULT * (25.0f / FPS) * fds->time_scale; | ||||
| fds->frame_length = DT_DEFAULT * (25.0f / fps) * fds->time_scale; | |||||
| /* Initially dt is equal to frame length (dt can change with adaptive-time stepping though). */ | /* Initially dt is equal to frame length (dt can change with adaptive-time stepping though). */ | ||||
| fds->dt = fds->frame_length; | fds->dt = fds->frame_length; | ||||
| fds->time_per_frame = 0; | fds->time_per_frame = 0; | ||||
| fmd->time = scene_framenr; | fmd->time = scene_framenr; | ||||
| /* Allocate fluid. */ | /* Allocate fluid. */ | ||||
| return BKE_fluid_reallocate_fluid(fds, fds->res, 0); | return BKE_fluid_reallocate_fluid(fds, fds->res, 0); | ||||
| ▲ Show 20 Lines • Show All 2,709 Lines • ▼ Show 20 Lines | if (effectors) { | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.min_iter_per_thread = 2; | settings.min_iter_per_thread = 2; | ||||
| BLI_task_parallel_range(0, fds->res[0], &data, update_effectors_task_cb, &settings); | BLI_task_parallel_range(0, fds->res[0], &data, update_effectors_task_cb, &settings); | ||||
| } | } | ||||
| BKE_effectors_free(effectors); | BKE_effectors_free(effectors); | ||||
| } | } | ||||
| static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Object *ob) | static Mesh *create_liquid_geometry(FluidDomainSettings *fds, | ||||
| Scene *scene, | |||||
| Mesh *orgmesh, | |||||
| Object *ob) | |||||
| { | { | ||||
| Mesh *me; | Mesh *me; | ||||
| MVert *mverts; | MVert *mverts; | ||||
| MPoly *mpolys; | MPoly *mpolys; | ||||
| MLoop *mloops; | MLoop *mloops; | ||||
| short *normals, *no_s; | short *normals, *no_s; | ||||
| float no[3]; | float no[3]; | ||||
| float min[3]; | float min[3]; | ||||
| Show All 30 Lines | |||||
| # endif | # endif | ||||
| if (!num_verts || !num_faces) { | if (!num_verts || !num_faces) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* Normals are per vertex, so these must match. */ | /* Normals are per vertex, so these must match. */ | ||||
| BLI_assert(num_verts == num_normals); | BLI_assert(num_verts == num_normals); | ||||
| /* If needed, vertex velocities will be read too. */ | |||||
| bool use_speedvectors = fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS; | |||||
| FluidDomainVertexVelocity *velarray = NULL; | |||||
| float time_mult = 25.0f * DT_DEFAULT; | |||||
| if (use_speedvectors) { | |||||
| if (fds->mesh_velocities) { | |||||
| MEM_freeN(fds->mesh_velocities); | |||||
| } | |||||
| fds->mesh_velocities = MEM_calloc_arrayN( | |||||
| num_verts, sizeof(FluidDomainVertexVelocity), "fluid_mesh_vertvelocities"); | |||||
| fds->totvert = num_verts; | |||||
| velarray = fds->mesh_velocities; | |||||
| } | |||||
| me = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 3, num_faces); | me = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 3, num_faces); | ||||
| if (!me) { | if (!me) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| mverts = me->mvert; | mverts = me->mvert; | ||||
| mpolys = me->mpoly; | mpolys = me->mpoly; | ||||
| mloops = me->mloop; | mloops = me->mloop; | ||||
| Show All 15 Lines | # endif | ||||
| float co_offset[3]; | float co_offset[3]; | ||||
| co_offset[0] = (fds->p0[0] + fds->p1[0]) / 2.0f; | co_offset[0] = (fds->p0[0] + fds->p1[0]) / 2.0f; | ||||
| co_offset[1] = (fds->p0[1] + fds->p1[1]) / 2.0f; | co_offset[1] = (fds->p0[1] + fds->p1[1]) / 2.0f; | ||||
| co_offset[2] = (fds->p0[2] + fds->p1[2]) / 2.0f; | co_offset[2] = (fds->p0[2] + fds->p1[2]) / 2.0f; | ||||
| /* Normals. */ | /* Normals. */ | ||||
| normals = MEM_callocN(sizeof(short[3]) * num_normals, "Fluidmesh_tmp_normals"); | normals = MEM_callocN(sizeof(short[3]) * num_normals, "Fluidmesh_tmp_normals"); | ||||
| /* Velocities. */ | |||||
| /* If needed, vertex velocities will be read too. */ | |||||
| bool use_speedvectors = fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS; | |||||
| float(*velarray)[3] = NULL; | |||||
| float time_mult = fds->dx / (DT_DEFAULT * (25.0f / FPS)); | |||||
| if (use_speedvectors) { | |||||
| CustomDataLayer *velocity_layer = BKE_id_attribute_new( | |||||
| &me->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, NULL); | |||||
| velarray = velocity_layer->data; | |||||
| } | |||||
| /* Loop for vertices and normals. */ | /* Loop for vertices and normals. */ | ||||
| for (i = 0, no_s = normals; i < num_verts && i < num_normals; i++, mverts++, no_s += 3) { | for (i = 0, no_s = normals; i < num_verts && i < num_normals; i++, mverts++, no_s += 3) { | ||||
| /* Vertices (data is normalized cube around domain origin). */ | /* Vertices (data is normalized cube around domain origin). */ | ||||
| mverts->co[0] = manta_liquid_get_vertex_x_at(fds->fluid, i); | mverts->co[0] = manta_liquid_get_vertex_x_at(fds->fluid, i); | ||||
| mverts->co[1] = manta_liquid_get_vertex_y_at(fds->fluid, i); | mverts->co[1] = manta_liquid_get_vertex_y_at(fds->fluid, i); | ||||
| mverts->co[2] = manta_liquid_get_vertex_z_at(fds->fluid, i); | mverts->co[2] = manta_liquid_get_vertex_z_at(fds->fluid, i); | ||||
| Show All 23 Lines | # endif | ||||
| normal_float_to_short_v3(no_s, no); | normal_float_to_short_v3(no_s, no); | ||||
| # ifdef DEBUG_PRINT | # ifdef DEBUG_PRINT | ||||
| /* Debugging: Print coordinates of normals. */ | /* Debugging: Print coordinates of normals. */ | ||||
| printf("no_s[0]: %d, no_s[1]: %d, no_s[2]: %d\n", no_s[0], no_s[1], no_s[2]); | printf("no_s[0]: %d, no_s[1]: %d, no_s[2]: %d\n", no_s[0], no_s[1], no_s[2]); | ||||
| # endif | # endif | ||||
| if (use_speedvectors) { | if (use_speedvectors) { | ||||
| velarray[i].vel[0] = manta_liquid_get_vertvel_x_at(fds->fluid, i) * (fds->dx / time_mult); | velarray[i][0] = manta_liquid_get_vertvel_x_at(fds->fluid, i) * time_mult; | ||||
| velarray[i].vel[1] = manta_liquid_get_vertvel_y_at(fds->fluid, i) * (fds->dx / time_mult); | velarray[i][1] = manta_liquid_get_vertvel_y_at(fds->fluid, i) * time_mult; | ||||
| velarray[i].vel[2] = manta_liquid_get_vertvel_z_at(fds->fluid, i) * (fds->dx / time_mult); | velarray[i][2] = manta_liquid_get_vertvel_z_at(fds->fluid, i) * time_mult; | ||||
| # ifdef DEBUG_PRINT | # ifdef DEBUG_PRINT | ||||
| /* Debugging: Print velocities of vertices. */ | /* Debugging: Print velocities of vertices. */ | ||||
| printf("velarray[%d].vel[0]: %f, velarray[%d].vel[1]: %f, velarray[%d].vel[2]: %f\n", | printf("velarray[%d][0]: %f, velarray[%d][1]: %f, velarray[%d][2]: %f\n", | ||||
| i, | i, | ||||
| velarray[i].vel[0], | velarray[i][0], | ||||
| i, | i, | ||||
| velarray[i].vel[1], | velarray[i][1], | ||||
| i, | i, | ||||
| velarray[i].vel[2]); | velarray[i][2]); | ||||
| # endif | # endif | ||||
| } | } | ||||
| } | } | ||||
| /* Loop for triangles. */ | /* Loop for triangles. */ | ||||
| for (i = 0; i < num_faces; i++, mpolys++, mloops += 3) { | for (i = 0; i < num_faces; i++, mpolys++, mloops += 3) { | ||||
| /* Initialize from existing face. */ | /* Initialize from existing face. */ | ||||
| mpolys->mat_nr = mp_mat_nr; | mpolys->mat_nr = mp_mat_nr; | ||||
| ▲ Show 20 Lines • Show All 253 Lines • ▼ Show 20 Lines | static int manta_step( | ||||
| BLI_mutex_unlock(&object_update_lock); | BLI_mutex_unlock(&object_update_lock); | ||||
| return result; | return result; | ||||
| } | } | ||||
| static void manta_guiding( | static void manta_guiding( | ||||
| Depsgraph *depsgraph, Scene *scene, Object *ob, FluidModifierData *fmd, int frame) | Depsgraph *depsgraph, Scene *scene, Object *ob, FluidModifierData *fmd, int frame) | ||||
| { | { | ||||
| FluidDomainSettings *fds = fmd->domain; | FluidDomainSettings *fds = fmd->domain; | ||||
| float fps = scene->r.frs_sec / scene->r.frs_sec_base; | float dt = DT_DEFAULT * (25.0f / FPS) * fds->time_scale; | ||||
| float dt = DT_DEFAULT * (25.0f / fps) * fds->time_scale; | |||||
| BLI_mutex_lock(&object_update_lock); | BLI_mutex_lock(&object_update_lock); | ||||
| update_obstacles(depsgraph, scene, ob, fds, dt, dt, frame, dt); | update_obstacles(depsgraph, scene, ob, fds, dt, dt, frame, dt); | ||||
| manta_bake_guiding(fds->fluid, fmd, frame); | manta_bake_guiding(fds->fluid, fmd, frame); | ||||
| BLI_mutex_unlock(&object_update_lock); | BLI_mutex_unlock(&object_update_lock); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | # endif | ||||
| /* Adaptive domain needs to know about current state, so save it here. */ | /* Adaptive domain needs to know about current state, so save it here. */ | ||||
| int o_res[3], o_min[3], o_max[3], o_shift[3]; | int o_res[3], o_min[3], o_max[3], o_shift[3]; | ||||
| copy_v3_v3_int(o_res, fds->res); | copy_v3_v3_int(o_res, fds->res); | ||||
| copy_v3_v3_int(o_min, fds->res_min); | copy_v3_v3_int(o_min, fds->res_min); | ||||
| copy_v3_v3_int(o_max, fds->res_max); | copy_v3_v3_int(o_max, fds->res_max); | ||||
| copy_v3_v3_int(o_shift, fds->shift); | copy_v3_v3_int(o_shift, fds->shift); | ||||
| /* Ensure that time parameters are initialized correctly before every step. */ | /* Ensure that time parameters are initialized correctly before every step. */ | ||||
| float fps = scene->r.frs_sec / scene->r.frs_sec_base; | fds->frame_length = DT_DEFAULT * (25.0f / FPS) * fds->time_scale; | ||||
| fds->frame_length = DT_DEFAULT * (25.0f / fps) * fds->time_scale; | |||||
| fds->dt = fds->frame_length; | fds->dt = fds->frame_length; | ||||
| fds->time_per_frame = 0; | fds->time_per_frame = 0; | ||||
| /* Ensure that gravity is copied over every frame (could be keyframed). */ | /* Ensure that gravity is copied over every frame (could be keyframed). */ | ||||
| update_final_gravity(fds, scene); | update_final_gravity(fds, scene); | ||||
| int next_frame = scene_framenr + 1; | int next_frame = scene_framenr + 1; | ||||
| int prev_frame = scene_framenr - 1; | int prev_frame = scene_framenr - 1; | ||||
| ▲ Show 20 Lines • Show All 356 Lines • ▼ Show 20 Lines | if (!G.moving) { | ||||
| } | } | ||||
| } | } | ||||
| Mesh *result = NULL; | Mesh *result = NULL; | ||||
| if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { | if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { | ||||
| if (needs_viewport_update) { | if (needs_viewport_update) { | ||||
| /* Return generated geometry depending on domain type. */ | /* Return generated geometry depending on domain type. */ | ||||
| if (fmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) { | if (fmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) { | ||||
| result = create_liquid_geometry(fmd->domain, me, ob); | result = create_liquid_geometry(fmd->domain, scene, me, ob); | ||||
| } | } | ||||
| if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) { | if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) { | ||||
| result = create_smoke_geometry(fmd->domain, me, ob); | result = create_smoke_geometry(fmd->domain, me, ob); | ||||
| } | } | ||||
| } | } | ||||
| /* Clear flag outside of locked block (above). */ | /* Clear flag outside of locked block (above). */ | ||||
| fmd->domain->cache_flag &= ~FLUID_DOMAIN_OUTDATED_DATA; | fmd->domain->cache_flag &= ~FLUID_DOMAIN_OUTDATED_DATA; | ||||
| ▲ Show 20 Lines • Show All 540 Lines • ▼ Show 20 Lines | #endif | ||||
| MEM_SAFE_FREE(fmd->domain->effector_weights); | MEM_SAFE_FREE(fmd->domain->effector_weights); | ||||
| if (!(fmd->modifier.flag & eModifierFlag_SharedCaches)) { | if (!(fmd->modifier.flag & eModifierFlag_SharedCaches)) { | ||||
| BKE_ptcache_free_list(&(fmd->domain->ptcaches[0])); | BKE_ptcache_free_list(&(fmd->domain->ptcaches[0])); | ||||
| fmd->domain->point_cache[0] = NULL; | fmd->domain->point_cache[0] = NULL; | ||||
| } | } | ||||
| MEM_SAFE_FREE(fmd->domain->mesh_velocities); | |||||
| if (fmd->domain->coba) { | if (fmd->domain->coba) { | ||||
| MEM_freeN(fmd->domain->coba); | MEM_freeN(fmd->domain->coba); | ||||
| } | } | ||||
| MEM_freeN(fmd->domain); | MEM_freeN(fmd->domain); | ||||
| fmd->domain = NULL; | fmd->domain = NULL; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | if (tfmd->domain) { | ||||
| tfds->viscosity_value = fds->viscosity_value; | tfds->viscosity_value = fds->viscosity_value; | ||||
| /* Diffusion options. */ | /* Diffusion options. */ | ||||
| tfds->surface_tension = fds->surface_tension; | tfds->surface_tension = fds->surface_tension; | ||||
| tfds->viscosity_base = fds->viscosity_base; | tfds->viscosity_base = fds->viscosity_base; | ||||
| tfds->viscosity_exponent = fds->viscosity_exponent; | tfds->viscosity_exponent = fds->viscosity_exponent; | ||||
| /* mesh options */ | /* mesh options */ | ||||
| if (fds->mesh_velocities) { | |||||
| tfds->mesh_velocities = MEM_dupallocN(fds->mesh_velocities); | |||||
| } | |||||
| tfds->mesh_concave_upper = fds->mesh_concave_upper; | tfds->mesh_concave_upper = fds->mesh_concave_upper; | ||||
| tfds->mesh_concave_lower = fds->mesh_concave_lower; | tfds->mesh_concave_lower = fds->mesh_concave_lower; | ||||
| tfds->mesh_particle_radius = fds->mesh_particle_radius; | tfds->mesh_particle_radius = fds->mesh_particle_radius; | ||||
| tfds->mesh_smoothen_pos = fds->mesh_smoothen_pos; | tfds->mesh_smoothen_pos = fds->mesh_smoothen_pos; | ||||
| tfds->mesh_smoothen_neg = fds->mesh_smoothen_neg; | tfds->mesh_smoothen_neg = fds->mesh_smoothen_neg; | ||||
| tfds->mesh_scale = fds->mesh_scale; | tfds->mesh_scale = fds->mesh_scale; | ||||
| tfds->totvert = fds->totvert; | |||||
| tfds->mesh_generator = fds->mesh_generator; | tfds->mesh_generator = fds->mesh_generator; | ||||
| /* secondary particle options */ | /* secondary particle options */ | ||||
| tfds->sndparticle_k_b = fds->sndparticle_k_b; | tfds->sndparticle_k_b = fds->sndparticle_k_b; | ||||
| tfds->sndparticle_k_d = fds->sndparticle_k_d; | tfds->sndparticle_k_d = fds->sndparticle_k_d; | ||||
| tfds->sndparticle_k_ta = fds->sndparticle_k_ta; | tfds->sndparticle_k_ta = fds->sndparticle_k_ta; | ||||
| tfds->sndparticle_k_wc = fds->sndparticle_k_wc; | tfds->sndparticle_k_wc = fds->sndparticle_k_wc; | ||||
| tfds->sndparticle_l_max = fds->sndparticle_l_max; | tfds->sndparticle_l_max = fds->sndparticle_l_max; | ||||
| ▲ Show 20 Lines • Show All 154 Lines • Show Last 20 Lines | |||||