[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27986] trunk/blender: Fluid physics for particles by Raul Fernandez Hernandez (Farsthary) and Stephen Swhitehorn:

Janne Karhu jhkarh at gmail.com
Sun Apr 4 14:29:07 CEST 2010


Revision: 27986
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27986
Author:   jhk
Date:     2010-04-04 14:29:06 +0200 (Sun, 04 Apr 2010)

Log Message:
-----------
Fluid physics for particles by Raul Fernandez Hernandez (Farsthary) and Stephen Swhitehorn:

This patch add SPH (Smoothed Particle Hydrodynamics)fluid dynamics to the
blender particle system. SPH is an boundless Lagrangian interpolation
technique to solve the fluid motion equations.
 
>From liquids to sand, goo and gases could be simulated using the particle
system.
 
It features internal viscosity, a double density relaxation that accounts
for surface tension effects, static internal springs for plastic fluids,
and buoyancy for gases.

---------------------------------------

This is a commit of the core fluid physics. Raul will work on proper
documentation soon and more features such as surface extraction from
the particle point cloud and increasing stability by sub-frame calculations
later.

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/properties_particle.py
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/makesdna/DNA_particle_types.h
    trunk/blender/source/blender/makesrna/RNA_access.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	2010-04-04 12:09:59 UTC (rev 27985)
+++ trunk/blender/release/scripts/ui/properties_particle.py	2010-04-04 12:29:06 UTC (rev 27986)
@@ -395,6 +395,43 @@
             sub.prop(part, "integrator")
             sub.prop(part, "time_tweak")
 
+        elif part.physics_type == 'FLUID':
+            fluid = part.fluid
+            split = layout.split()
+            sub = split.column()
+
+            sub.label(text="Forces:")
+            sub.prop(part, "brownian_factor")
+            sub.prop(part, "drag_factor", slider=True)
+            sub.prop(part, "damp_factor", slider=True)
+            sub = split.column()
+            sub.prop(part, "size_deflect")
+            sub.prop(part, "die_on_collision")
+            sub.prop(part, "integrator")
+            sub.prop(part, "time_tweak")
+
+            split = layout.split()
+            sub = split.column()
+            sub.label(text="Fluid Interaction:")
+            sub.prop(fluid, "fluid_radius", slider=True)
+            sub.prop(fluid, "stiffness_k")
+            sub.prop(fluid, "stiffness_knear")
+            sub.prop(fluid, "rest_density")
+
+            sub.label(text="Viscosity:")
+            sub.prop(fluid, "viscosity_omega", text="Linear")
+            sub.prop(fluid, "viscosity_beta", text="Square")
+
+            sub = split.column()
+
+            sub.label(text="Springs:")
+            sub.prop(fluid, "spring_k", text="Force", slider=True)
+            sub.prop(fluid, "rest_length", slider=True)
+            layout.label(text="Multiple fluids interactions:")
+
+            sub.label(text="Buoyancy:")
+            sub.prop(fluid, "buoyancy", slider=True)
+
         elif part.physics_type == 'KEYED':
             split = layout.split()
             sub = split.column()
@@ -454,7 +491,7 @@
             col.prop(boids, "banking", slider=True)
             col.prop(boids, "height", slider=True)
 
-        if part.physics_type == 'KEYED' or part.physics_type == 'BOIDS':
+        if part.physics_type == 'KEYED' or part.physics_type == 'BOIDS' or part.physics_type == 'FLUID':
             if part.physics_type == 'BOIDS':
                 layout.label(text="Relations:")
 
@@ -484,7 +521,7 @@
                     col.active = psys.keyed_timing
                     col.prop(key, "time")
                     col.prop(key, "duration")
-                else:
+                elif part.physics_type == 'BOIDS':
                     sub = row.row()
                     #doesn't work yet
                     #sub.red_alert = key.valid
@@ -492,6 +529,12 @@
                     sub.prop(key, "system", text="System")
 
                     layout.prop(key, "mode", expand=True)
+                elif part.physics_type == 'FLUID':
+                    sub = row.row()
+                    #doesn't work yet
+                    #sub.red_alert = key.valid
+                    sub.prop(key, "object", text="")
+                    sub.prop(key, "system", text="System")
 
 
 class PARTICLE_PT_boidbrain(ParticleButtonsPanel):

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2010-04-04 12:09:59 UTC (rev 27985)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2010-04-04 12:29:06 UTC (rev 27986)
@@ -355,6 +355,12 @@
 /************************************************/
 /*			Freeing stuff						*/
 /************************************************/
+void fluid_free_settings(SPHFluidSettings *fluid)
+{
+	if(fluid)
+		MEM_freeN(fluid); 
+}
+
 void psys_free_settings(ParticleSettings *part)
 {
 	BKE_free_animdata(&part->id);
@@ -367,6 +373,7 @@
 	BLI_freelistN(&part->dupliweights);
 
 	boid_free_settings(part->boids);
+	fluid_free_settings(part->fluid);
 }
 
 void free_hair(Object *ob, ParticleSystem *psys, int dynamics)

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c	2010-04-04 12:09:59 UTC (rev 27985)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c	2010-04-04 12:29:06 UTC (rev 27986)
@@ -24,7 +24,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Raul Fernandez Hernandez (Farsthary), Stephen Swhitehorn.
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -2270,6 +2270,137 @@
 	precalc_guides(sim, sim->psys->effectors);
 }
 
+/*************************************************
+                    SPH fluid physics 
+
+ In theory, there could be unlimited implementation
+                    of SPH simulators
+**************************************************/
+void particle_fluidsim(ParticleSystem *psys, ParticleData *pa, ParticleSettings *part, ParticleSimulationData *sim, float dfra, float cfra, float mass){
+/****************************************************************************************************************
+* 	This code uses in some parts adapted algorithms from the pseduo code as outlined in the Research paper
+*	Titled: Particle-based Viscoelastic Fluid Simulation.
+* 	Authors: Simon Clavet, Philippe Beaudoin and Pierre Poulin
+*
+*	Website: http://www.iro.umontreal.ca/labs/infographie/papers/Clavet-2005-PVFS/
+*	Presented at Siggraph, (2005)
+*
+*****************************************************************************************************************/
+	KDTree *tree = psys->tree;
+	KDTreeNearest *ptn = NULL;
+	
+	SPHFluidSettings *fluid = part->fluid;
+	ParticleData *second_particle;
+
+	float start[3], end[3], v[3];
+	float temp[3];
+	float q, radius, D;
+	float p, pnear, pressure_near, pressure;
+	float dtime = dfra * psys_get_timestep(sim);
+	float omega = fluid->viscosity_omega;
+	float beta = fluid->viscosity_omega;
+	float massfactor = 1.0f/mass;
+	int n, neighbours;
+
+		
+	radius 	= fluid->radius;
+
+	VECCOPY(start, pa->prev_state.co);
+	VECCOPY(end, pa->state.co);
+
+	sub_v3_v3v3(v, end, start);
+	mul_v3_fl(v, 1.f/dtime);
+
+	neighbours = BLI_kdtree_range_search(tree, radius, start, NULL, &ptn);
+
+	/* use ptn[n].co to store relative direction */
+	for(n=1; n<neighbours; n++) {
+		sub_v3_v3(ptn[n].co, start);
+		normalize_v3(ptn[n].co);
+	}
+        
+	/* Viscosity - Algorithm 5  */
+	if (omega > 0.f || beta > 0.f) {
+		float u, I;
+
+		for(n=1; n<neighbours; n++) {
+			second_particle = psys->particles + ptn[n].index;
+			q = ptn[n].dist/radius;
+			
+			sub_v3_v3v3(temp, v, second_particle->prev_state.vel);
+			
+			u = dot_v3v3(ptn[n].co, temp);
+
+			if (u > 0){
+				I = dtime * ((1-q) * (omega * u + beta * u*u)) * 0.5f;
+				madd_v3_v3fl(v, ptn[n].co, -I * massfactor);
+			} 
+		}	
+	}
+
+	/* Hooke's spring force  */
+	if (fluid->spring_k > 0.f) {
+		float D, L = fluid->rest_length;
+		for(n=1; n<neighbours; n++) {
+			/* L is a factor of radius */
+			D = dtime * 10.f * fluid->spring_k * (1.f - L) * (L - ptn[n].dist/radius);
+			madd_v3_v3fl(v, ptn[n].co, -D * massfactor);
+		}
+	}
+	/* Update particle position */	
+	VECADDFAC(end, start, v, dtime);
+
+	/* Double Density Relaxation - Algorithm 2 */
+	p = 0;
+	pnear = 0;
+	for(n=1; n<neighbours; n++) {
+		q = ptn[n].dist/radius;
+		p += ((1-q)*(1-q));
+		pnear += ((1-q)*(1-q)*(1-q));
+	}
+	p *= part->mass;
+	pnear *= part->mass;
+	pressure =  fluid->stiffness_k * (p - fluid->rest_density);
+	pressure_near = fluid->stiffness_knear * pnear;
+
+	for(n=1; n<neighbours; n++) {
+		q = ptn[n].dist/radius;
+
+		D =  dtime * dtime * (pressure*(1-q) + pressure_near*(1-q)*(1-q))* 0.5f;
+		madd_v3_v3fl(end, ptn[n].co, -D * massfactor);
+	} 	
+
+	/* Artificial buoyancy force in negative gravity direction  */
+	if (fluid->buoyancy >= 0.f && psys_uses_gravity(sim)) {
+		float B = -dtime * dtime * fluid->buoyancy * (p - fluid->rest_density) * 0.5f;
+		madd_v3_v3fl(end, sim->scene->physics_settings.gravity, -B * massfactor);
+	}
+
+	/* apply final result and recalculate velocity */
+	VECCOPY(pa->state.co, end);
+	sub_v3_v3v3(pa->state.vel, end, start);
+	mul_v3_fl(pa->state.vel, 1.f/dtime);
+
+	if(ptn){ MEM_freeN(ptn); ptn=NULL;}
+}
+
+static void apply_particle_fluidsim(ParticleSystem *psys, ParticleData *pa, ParticleSettings *part, ParticleSimulationData *sim, float dfra, float cfra){
+	ParticleTarget *pt;
+	float dtime = dfra*psys_get_timestep(sim);
+	float particle_mass = part->mass;
+
+	particle_fluidsim(psys, pa, part, sim, dfra, cfra, particle_mass);
+	
+	/*----check other SPH systems (Multifluids) , each fluid has its own parameters---*/
+	for(pt=sim->psys->targets.first; pt; pt=pt->next) {
+		ParticleSystem *epsys = psys_get_target_system(sim->ob, pt);
+
+		if(epsys)
+			particle_fluidsim(epsys, pa, epsys->part, sim, dfra, cfra, particle_mass);
+	}
+	/*----------------------------------------------------------------*/	 	 
+}
+
 /************************************************/
 /*			Newtonian physics					*/
 /************************************************/
@@ -2799,7 +2930,7 @@
 				deflections=max_deflections;
 			}
 			else {
-				float nor_vec[3], tan_vec[3], tan_vel[3], vel[3];
+				float nor_vec[3], tan_vec[3], tan_vel[3];
 				float damp, frict;
 				float inp, inp_v;
 				
@@ -3248,6 +3379,14 @@
 				psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
 		}
 	}
+	else if(part->phystype==PART_PHYS_FLUID){
+		ParticleTarget *pt = psys->targets.first;
+		psys_update_particle_tree(psys, cfra);
+		
+		for(; pt; pt=pt->next) {  /* Updating others systems particle tree for fluid-fluid interaction */
+			if(pt->ob) psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
+		}
+	}
 
 	/* main loop: calculate physics for all particles */
 	LOOP_SHOWN_PARTICLES {
@@ -3318,6 +3457,22 @@
 					}
 					break;
 				}
+				case PART_PHYS_FLUID:
+				{	
+					/* do global forces & effectors */
+					apply_particle_forces(sim, p, pa_dfra, cfra);
+
+					/* do fluid sim */
+					apply_particle_fluidsim(psys, pa, part, sim, pa_dfra, cfra);
+
+					/* deflection */
+ 					if(sim->colliders)
+						deflect_particle(sim, p, pa_dfra, cfra);
+ 					
+					/* rotations, SPH particles are not physical particles, just interpolation particles,  thus rotation has not a direct sense for them */	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list