diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_particle.py | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_cloth_types.h | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_cloth.c | 7 | ||||
-rw-r--r-- | source/blender/physics/intern/BPH_mass_spring.cpp | 3 | ||||
-rw-r--r-- | source/blender/physics/intern/hair_volume.c | 71 | ||||
-rw-r--r-- | source/blender/physics/intern/implicit.h | 1 |
6 files changed, 87 insertions, 1 deletions
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 8afd2d02170..5b52475218d 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -323,6 +323,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): sub.separator() sub.prop(cloth, "voxel_resolution") + sub.prop(cloth, "voxel_filter_size") col = split.column() col.label(text="Damping:") diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index c7eee96bd06..39a1abcc76a 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -75,7 +75,9 @@ typedef struct ClothSimSettings { float vel_damping; /* damp the velocity to speed up getting to the resting position */ float shrink_min; /* min amount to shrink cloth by 0.0f (no shrink) - 1.0f (shrink to nothing) */ float shrink_max; /* max amount to shrink cloth by 0.0f (no shrink) - 1.0f (shrink to nothing) */ - int voxel_res; /* resolution of voxel grid for interaction */ + + int voxel_res; /* resolution of voxel grid for interaction */ + int voxel_filter_size; /* filter size for voxel grid */ int stepsPerFrame; /* Number of time steps per frame. */ int flags; /* flags, see CSIMSETT_FLAGS enum above. */ @@ -89,6 +91,7 @@ typedef struct ClothSimSettings { short shapekey_rest; /* vertex group for scaling structural stiffness */ short presets; /* used for presets on GUI */ short reset; + int pad; struct EffectorWeights *effector_weights; } ClothSimSettings; diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 8528a664458..eff194fcd5c 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -417,6 +417,13 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Voxel Grid Resolution", "Resolution of the voxel grid for interaction effects"); RNA_def_property_update(prop, 0, "rna_cloth_update"); + prop = RNA_def_property(srna, "voxel_filter_size", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "voxel_filter_size"); + RNA_def_property_range(prop, 0, 8); + RNA_def_property_int_default(prop, 0); + RNA_def_property_ui_text(prop, "Voxel Grid Filter Size", "Number of cells to use for filtering grid velocity"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + /* springs */ prop = RNA_def_property(srna, "use_stiffness_scale", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp index 0fa14fa4eab..4d8f853a16b 100644 --- a/source/blender/physics/intern/BPH_mass_spring.cpp +++ b/source/blender/physics/intern/BPH_mass_spring.cpp @@ -431,6 +431,9 @@ static void cloth_calc_volume_force(ClothModifierData *clmd) } BPH_hair_volume_normalize_vertex_grid(vertex_grid); + /* apply velocity filter */ + BPH_hair_volume_vertex_grid_filter_box(vertex_grid, clmd->sim_parms->voxel_filter_size); + for (i = 0; i < numverts; i++) { float x[3], v[3], f[3], dfdx[3][3], dfdv[3][3]; diff --git a/source/blender/physics/intern/hair_volume.c b/source/blender/physics/intern/hair_volume.c index 2d5efa8260b..7f9704af9f6 100644 --- a/source/blender/physics/intern/hair_volume.c +++ b/source/blender/physics/intern/hair_volume.c @@ -71,6 +71,8 @@ BLI_INLINE void hair_grid_get_scale(int res, const float gmin[3], const float gm typedef struct HairGridVert { float velocity[3]; float density; + + float velocity_smooth[3]; } HairGridVert; typedef struct HairVertexGrid { @@ -293,6 +295,75 @@ void BPH_hair_volume_normalize_vertex_grid(HairVertexGrid *grid) } } +/* Velocity filter kernel + * See http://en.wikipedia.org/wiki/Filter_%28large_eddy_simulation%29 + */ + +BLI_INLINE void hair_volume_filter_box_convolute(HairVertexGrid *grid, float invD, const int kernel_size[3], int i, int j, int k) +{ + int res = grid->res; + int p, q, r; + int minp = max_ii(i - kernel_size[0], 0), maxp = min_ii(i + kernel_size[0], res-1); + int minq = max_ii(j - kernel_size[1], 0), maxq = min_ii(j + kernel_size[1], res-1); + int minr = max_ii(k - kernel_size[2], 0), maxr = min_ii(k + kernel_size[2], res-1); + int offset, kernel_offset, kernel_dq, kernel_dr; + HairGridVert *verts; + float *vel_smooth; + + offset = i + (j + k*res)*res; + verts = grid->verts; + vel_smooth = verts[offset].velocity_smooth; + + kernel_offset = minp + (minq + minr*res)*res; + kernel_dq = res; + kernel_dr = res * res; + for (r = minr; r <= maxr; ++r) { + for (q = minq; q <= maxq; ++q) { + for (p = minp; p <= maxp; ++p) { + + madd_v3_v3fl(vel_smooth, verts[kernel_offset].velocity, invD); + + kernel_offset += 1; + } + kernel_offset += kernel_dq; + } + kernel_offset += kernel_dr; + } +} + +void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_size) +{ + int size = hair_grid_size(grid->res); + int kernel_sizev[3] = {kernel_size, kernel_size, kernel_size}; + int tot; + float invD; + int i, j, k; + + if (kernel_size <= 0) + return; + + tot = kernel_size * 2 + 1; + invD = 1.0f / (float)(tot*tot*tot); + + /* clear values for convolution */ + for (i = 0; i < size; ++i) { + zero_v3(grid->verts[i].velocity_smooth); + } + + for (i = 0; i < grid->res; ++i) { + for (j = 0; j < grid->res; ++j) { + for (k = 0; k < grid->res; ++k) { + hair_volume_filter_box_convolute(grid, invD, kernel_sizev, i, j, k); + } + } + } + + /* apply as new velocity */ + for (i = 0; i < size; ++i) { + copy_v3_v3(grid->verts[i].velocity, grid->verts[i].velocity_smooth); + } +} + HairVertexGrid *BPH_hair_volume_create_vertex_grid(int res, const float gmin[3], const float gmax[3]) { int size = hair_grid_size(res); diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h index 28c4cbcf7ae..2945b0787d4 100644 --- a/source/blender/physics/intern/implicit.h +++ b/source/blender/physics/intern/implicit.h @@ -155,6 +155,7 @@ void BPH_hair_volume_free_vertex_grid(struct HairVertexGrid *grid); void BPH_hair_volume_add_vertex(struct HairVertexGrid *grid, const float x[3], const float v[3]); void BPH_hair_volume_normalize_vertex_grid(struct HairVertexGrid *grid); +void BPH_hair_volume_vertex_grid_filter_box(struct HairVertexGrid *grid, int kernel_size); void BPH_hair_volume_vertex_grid_forces(struct HairVertexGrid *grid, const float x[3], const float v[3], float smoothfac, float pressurefac, float minpressure, float f[3], float dfdx[3][3], float dfdv[3][3]); |