[Bf-blender-cvs] [3b9716d] temp_merge_gooseberry_hair: Added basic filtering feature for velocity smoothing.

Lukas Tönne noreply at git.blender.org
Mon Jan 19 20:49:21 CET 2015


Commit: 3b9716dd61bfee46ab4a9d290309d0414b2c93ba
Author: Lukas Tönne
Date:   Thu Sep 18 09:06:25 2014 +0200
Branches: temp_merge_gooseberry_hair
https://developer.blender.org/rB3b9716dd61bfee46ab4a9d290309d0414b2c93ba

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).

===================================================================

M	release/scripts/startup/bl_ui/properties_particle.py
M	source/blender/makesdna/DNA_cloth_types.h
M	source/blender/makesrna/intern/rna_cloth.c
M	source/blender/physics/intern/BPH_mass_spring.cpp
M	source/blender/physics/intern/hair_volume.c
M	source/blender/physics/intern/implicit.h

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index d8a0ab2..43baf09 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -299,6 +299,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 c7eee96..39a1abc 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 8528a66..eff194f 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 0fa14fa..4d8f853 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 2d5efa8..7f9704a 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 28c4cbc..2945b07 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]);




More information about the Bf-blender-cvs mailing list