[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34208] trunk/blender: Viscoelastic springs for sph particle fluids, original patch by Stephen Whitehorn (chickencoop)

Janne Karhu jhkarh at gmail.com
Sun Jan 9 20:09:42 CET 2011


Revision: 34208
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=34208
Author:   jhk
Date:     2011-01-09 19:09:41 +0000 (Sun, 09 Jan 2011)
Log Message:
-----------
Viscoelastic springs for sph particle fluids, original patch by Stephen Whitehorn (chickencoop)
* Viscoelastic springs between the fluid particles can simulate all kinds
  of viscous and elastic substances, such as jelly and honey. This is
  achieved by creating springs dynamically between neighboring particles
  and adjusting their rest length based on stretching/compression.
* This nearly completes the currently intended functionality for particle
  fluids. The last missing thing is a surfacing extraction algorithm,
  which is needed for a proper representation of a sph fluid.
* I also cleaned up and renamed some of the fluid parameters to make the
  ui a bit easier to understand.
* One addition to the patch is an option to use "initial rest length" for
  the springs, which uses the lengths between the particles at the time of
  spring creation as the spring rest lengths instead of interaction radius/2.
  This makes the fluid keep it's original shape better (good for very
  viscoelastic materials), but can create large density differences inside
  the fluid (not really physically correct for a fluid).
* Viscoelastic springs are stored in point cache as extra data.

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/properties_particle.py
    trunk/blender/source/blender/blenkernel/BKE_pointcache.h
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/blenkernel/intern/pointcache.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/makesdna/DNA_object_force.h
    trunk/blender/source/blender/makesdna/DNA_particle_types.h
    trunk/blender/source/blender/makesrna/intern/rna_particle.c

Modified: trunk/blender/release/scripts/ui/properties_particle.py
===================================================================
--- trunk/blender/release/scripts/ui/properties_particle.py	2011-01-09 18:59:35 UTC (rev 34207)
+++ trunk/blender/release/scripts/ui/properties_particle.py	2011-01-09 19:09:41 UTC (rev 34208)
@@ -445,24 +445,32 @@
             split = layout.split()
             sub = split.column()
             sub.label(text="Fluid Interaction:")
-            sub.prop(fluid, "fluid_radius", slider=True)
-            sub.prop(fluid, "stiffness")
-            sub.prop(fluid, "stiffness_near")
-            sub.prop(fluid, "rest_density")
+            sub.prop(fluid, "fluid_radius")
+            sub.prop(fluid, "repulsion_force")
+            subsub = sub.column(align=True)
+            subsub.prop(fluid, "rest_density")
+            subsub.prop(fluid, "density_force", text="Force")
 
             sub.label(text="Viscosity:")
-            sub.prop(fluid, "viscosity_omega", text="Linear")
-            sub.prop(fluid, "viscosity_beta", text="Square")
+            subsub = sub.column(align=True)
+            subsub.prop(fluid, "linear_viscosity", text="Linear")
+            subsub.prop(fluid, "square_viscosity", text="Square")
 
             sub = split.column()
 
             sub.label(text="Springs:")
-            sub.prop(fluid, "spring_force", text="Force", slider=True)
-            sub.prop(fluid, "rest_length", slider=True)
-            layout.label(text="Multiple fluids interactions:")
+            sub.prop(fluid, "spring_force", text="Force")
+            #Hidden to make ui a bit lighter, can be unhidden for a bit more control
+            #sub.prop(fluid, "rest_length", slider=True)
+            sub.prop(fluid, "use_viscoelastic_springs")
+            subsub = sub.column(align=True)
+            subsub.active = fluid.use_viscoelastic_springs
+            subsub.prop(fluid, "yield_ratio", slider=True)
+            subsub.prop(fluid, "plasticity", slider=True)
+            subsub.prop(fluid, "use_initial_rest_length")
 
             sub.label(text="Buoyancy:")
-            sub.prop(fluid, "buoyancy", slider=True)
+            sub.prop(fluid, "buoyancy", text="Strength", slider=True)
 
         elif part.physics_type == 'KEYED':
             split = layout.split()
@@ -526,6 +534,8 @@
         if part.physics_type == 'KEYED' or part.physics_type == 'BOIDS' or part.physics_type == 'FLUID':
             if part.physics_type == 'BOIDS':
                 layout.label(text="Relations:")
+            elif part.physics_type == 'FLUID':
+                layout.label(text="Fluid interaction:")
 
             row = layout.row()
             row.template_list(psys, "targets", psys, "active_particle_target_index")
@@ -886,6 +896,9 @@
         col.prop(part, "show_number")
         if part.physics_type == 'BOIDS':
             col.prop(part, "show_health")
+        
+ 
+        
 
         col = row.column()
         col.prop(part, "show_material_color", text="Use material color")

Modified: trunk/blender/source/blender/blenkernel/BKE_pointcache.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_pointcache.h	2011-01-09 18:59:35 UTC (rev 34207)
+++ trunk/blender/source/blender/blenkernel/BKE_pointcache.h	2011-01-09 19:09:41 UTC (rev 34208)
@@ -32,6 +32,7 @@
 #include "DNA_ID.h"
 #include "DNA_object_force.h"
 #include "DNA_boid_types.h"
+#include "DNA_particle_types.h"
 #include <stdio.h> /* for FILE */
 
 /* Point cache clearing option, for BKE_ptcache_id_clear, before
@@ -110,6 +111,16 @@
 	"BoidData" // case BPHYS_DATA_BOIDS:
 };
 
+static char *ptcache_extra_datastruct[] = {
+	"",
+	"ParticleSpring"
+};
+
+static int ptcache_extra_datasize[] = {
+	0,
+	sizeof(ParticleSpring)
+};
+
 typedef struct PTCacheFile {
 	FILE *fp;
 
@@ -149,11 +160,11 @@
 	void (*read_stream)(PTCacheFile *pf, void *calldata);
 
 	/* copies custom extradata to cache data */
-	int (*write_extra_data)(void *calldata, struct PTCacheMem *pm, int cfra);
+	void (*write_extra_data)(void *calldata, struct PTCacheMem *pm, int cfra);
 	/* copies custom extradata to cache data */
-	int (*read_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra);
+	void (*read_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra);
 	/* copies custom extradata to cache data */
-	int (*interpolate_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra, float cfra1, float cfra2);
+	void (*interpolate_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra, float cfra1, float cfra2);
 
 	/* total number of simulated points (the cfra parameter is just for using same function pointer with totwrite) */
 	int (*totpoint)(void *calldata, int cfra);

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2011-01-09 18:59:35 UTC (rev 34207)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2011-01-09 19:09:41 UTC (rev 34208)
@@ -561,6 +561,9 @@
 		BLI_freelistN(&psys->targets);
 
 		BLI_kdtree_free(psys->tree);
+ 
+		if(psys->fluid_springs)
+			MEM_freeN(psys->fluid_springs);
 
 		pdEndEffectors(&psys->effectors);
 

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c	2011-01-09 18:59:35 UTC (rev 34207)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c	2011-01-09 19:09:41 UTC (rev 34208)
@@ -54,6 +54,7 @@
 #include "DNA_ipo_types.h" // XXX old animation system stuff... to be removed!
 #include "DNA_listBase.h"
 
+#include "BLI_edgehash.h"
 #include "BLI_rand.h"
 #include "BLI_jitter.h"
 #include "BLI_math.h"
@@ -182,6 +183,13 @@
 
 	/* reset point cache */
 	BKE_ptcache_invalidate(psys->pointcache);
+
+	if(psys->fluid_springs) {
+		MEM_freeN(psys->fluid_springs);
+		psys->fluid_springs = NULL;
+	}
+
+	psys->tot_fluidsprings = psys->alloc_fluidsprings = 0;
 }
 
 static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
@@ -2228,32 +2236,79 @@
  Presented at Siggraph, (2005)
 
 ***********************************************************************************************************/
-static void particle_fluidsim(ParticleSystem *psys, int own_psys, ParticleData *pa, float dtime, float mass, float *gravity)
+#define PSYS_FLUID_SPRINGS_INITIAL_SIZE 256
+ParticleSpring *add_fluid_spring(ParticleSystem *psys, ParticleSpring *spring)
 {
+	/* Are more refs required? */
+	if(psys->alloc_fluidsprings == 0 || psys->fluid_springs == NULL) {
+		psys->alloc_fluidsprings = PSYS_FLUID_SPRINGS_INITIAL_SIZE;
+		psys->fluid_springs = (ParticleSpring*)MEM_callocN(psys->alloc_fluidsprings * sizeof(ParticleSpring), "Particle Fluid Springs");
+	}
+	else if(psys->tot_fluidsprings == psys->alloc_fluidsprings) {
+		/* Double the number of refs allocated */
+		psys->alloc_fluidsprings *= 2;
+		psys->fluid_springs = (ParticleSpring*)MEM_reallocN(psys->fluid_springs, psys->alloc_fluidsprings * sizeof(ParticleSpring));
+	}
+
+	memcpy(psys->fluid_springs + psys->tot_fluidsprings, spring, sizeof(ParticleSpring));
+	psys->tot_fluidsprings++;
+
+	return psys->fluid_springs + psys->tot_fluidsprings - 1;
+}
+
+void  delete_fluid_spring(ParticleSystem *psys, int j)
+{
+	if (j != psys->tot_fluidsprings - 1)
+		psys->fluid_springs[j] = psys->fluid_springs[psys->tot_fluidsprings - 1];
+
+	psys->tot_fluidsprings--;
+
+	if (psys->tot_fluidsprings < psys->alloc_fluidsprings/2 && psys->alloc_fluidsprings > PSYS_FLUID_SPRINGS_INITIAL_SIZE){
+		psys->alloc_fluidsprings /= 2;
+		psys->fluid_springs = (ParticleSpring*)MEM_reallocN(psys->fluid_springs,  psys->alloc_fluidsprings * sizeof(ParticleSpring));
+	}
+}
+
+EdgeHash *build_fluid_springhash(ParticleSystem *psys)
+{
+	EdgeHash *springhash = NULL;
+	ParticleSpring *spring = psys->fluid_springs;
+	int i = 0;
+
+	springhash = BLI_edgehash_new();
+
+	for(i=0, spring=psys->fluid_springs; i<psys->tot_fluidsprings; i++, spring++)
+		BLI_edgehash_insert(springhash, spring->particle_index[0], spring->particle_index[1], SET_INT_IN_POINTER(i+1));
+
+	return springhash;
+}
+static void particle_fluidsim(ParticleSystem *psys, int own_psys, ParticleData *pa, float dtime, float mass, float *gravity, EdgeHash *springhash)
+{
 	SPHFluidSettings *fluid = psys->part->fluid;
 	KDTreeNearest *ptn = NULL;
 	ParticleData *npa;
+	ParticleSpring *spring = NULL;
 
 	float temp[3];
-	float q, q1, u, I, D;
+	float q, q1, u, I, D, rij, d, Lij;
 	float pressure_near, pressure;
 	float p=0, pnear=0;
 
-	float radius = fluid->radius;
 	float omega = fluid->viscosity_omega;
 	float beta = fluid->viscosity_beta;
 	float massfactor = 1.0f/mass;
 	float spring_k = fluid->spring_k;
-	float L = fluid->rest_length;
+	float h = fluid->radius;
+	float L = fluid->rest_length * fluid->radius;
 
-	int n, neighbours = BLI_kdtree_range_search(psys->tree, radius, pa->prev_state.co, NULL, &ptn);
-	int index = own_psys ? pa - psys->particles : -1;
+	int n, neighbours = BLI_kdtree_range_search(psys->tree, h, pa->prev_state.co, NULL, &ptn);
+	int spring_index = 0, index = own_psys ? pa - psys->particles : -1;
 
 	/* pressure and near pressure */
 	for(n=own_psys?1:0; n<neighbours; n++) {
 		sub_v3_v3(ptn[n].co, pa->prev_state.co);
 		mul_v3_fl(ptn[n].co, 1.f/ptn[n].dist);
-		q = ptn[n].dist/radius;
+		q = ptn[n].dist/h;
 
 		if(q < 1.f) {
 			q1 = 1.f - q;
@@ -2272,7 +2327,8 @@
 	for(n=own_psys?1:0; n<neighbours; n++) {
 		npa = psys->particles + ptn[n].index;
 
-		q = ptn[n].dist/radius;
+		rij = ptn[n].dist;
+		q = rij/h;
 		q1 = 1.f-q;
 
 		/* Double Density Relaxation - Algorithm 2 (can't be thread safe!)*/
@@ -2296,14 +2352,40 @@
 				}
 			}
 
-			/* Hooke's spring force */
 			if(spring_k > 0.f) {
-				/* L is a factor of radius */
-				D = 0.5 * dtime * dtime * 10.f * fluid->spring_k * (1.f - L) * (L - q);
+				/* Viscoelastic spring force - Algorithm 4*/
+				if (fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash){
+					spring_index = GET_INT_FROM_POINTER(BLI_edgehash_lookup(springhash, index, ptn[n].index));
 
-				madd_v3_v3fl(pa->state.co, ptn[n].co, -D * massfactor);
-				if(own_psys)
-					madd_v3_v3fl(npa->state.co, ptn[n].co, D * massfactor);
+					if(spring_index) {
+						spring = psys->fluid_springs + spring_index - 1;
+					}
+					else {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list