Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2014-09-18 11:06:25 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2015-01-20 11:30:01 +0300
commit226beb986690046adfdf10a3ed72034fa322ccdb (patch)
treea9dfd0f16c58d70566368cb9b0c3e695e06e44d9
parentbbae8f88b8f305a8ed85cab718d2a66b476da3c1 (diff)
Added basic filtering feature for velocity smoothing.
This is part of the original method from "Volumetric Methods for Simulation and Rendering of Hair". The current filter is a simple box filter. Other energy-preserving filters such as gaussian filtering can be implemented later. The filter size is currently given as a cell count. This is not ideal, rather it should use a geometrical length value, but this is too abstract for proper artistical use. Eventually defining the whole grid in terms of spatial size might work better (possibly using an external object).
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py1
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c7
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp3
-rw-r--r--source/blender/physics/intern/hair_volume.c71
-rw-r--r--source/blender/physics/intern/implicit.h1
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]);