Revision: 35488
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35488
Author:   jhk
Date:     2011-03-12 12:38:11 +0000 (Sat, 12 Mar 2011)
Log Message:
-----------
Completely refactored sph fluid particles. Only the very core of the algorithm 
remains
the same, but big changes have happened both on the outside and on the inside.

New UI:
* The old parameters were quite true to the underlying algorithm, but were 
quite obscure
  from a users point of view. Now there are only a few intuitive basic 
parameters that
  define the basic fluid behavior.
** By default particle size is now used to determine the interaction radius, 
rest
   density and spring rest lengths so that it's easy to get stable simulations 
by simply
   emitting particles for a few frames and adjusting the particle size (easy 
when the
   particle size is drawn) so that the fluid appears continuous (particles are 
touching
   eachother).
** Stiffness - in reality most fluids are very incompressible, but this is a 
very hard
   problem to solve with particle based fluid simulation so some compromises 
have to be
   made. So the bigger the stiffness parameter is the less the fluid will 
compress under
   stress, but the more substeps are needed for stable simulation.
** Viscosity - how much internal friction there is in the fluid. Large 
viscosities also
   smooth out instabilities, so less viscous fluids again need more substeps to 
remain
   stable.
** Buoancy - with high buoancy low pressure areas inside the fluid start to 
rise against
   gravity, and high pressure areas start to come down.

* In addition to these basic parameters there are separate advanced parameters 
that can
  either be tweaked relative to the basic parameters (or particle size) or 
defined
  independently.
** Repulsion - the stiffness parameter tries to keep the fluid density 
constant, but this
   can lead to small clumps of particles, so the repulsion keeps the particles 
better
   separated.
** Stiff viscosity - the normal viscosity only applies when particles are 
moving closer to 
   eachother to allow free flowing fluids. Stiff viscosity also applies 
smoothing to
   particles that are moving away from eachother.
** Interaction radius - by default this is 4 * particle size.
** Rest density - by default this is a density that the particles have when 
they're packed
   densely next to eachother.
** Spring rest length - by default this is 2 * particle size.

* There are also new options for 3d view particle coloring in the display panel 
to show
  particle velocity and acceleration. These make it easier to see what's 
happening in the
  fluid simulations, but can of course be used with other particles as well.

* Viscoelastic springs have some new options too. The plasticity can now be set 
to much
  higher values for instant deletion of springs as the elastic limit is 
exeeded. In addition
  to that there is an option to only create springs for a certain number of 
frames when a
  particle is born. These options give new possibilities for breaking 
viscoelastic fluids.

New in the code:
* Most of the fluids code is now thread safe, so when particle dynamics go 
threaded there
  will be a nice speed boost to fluids as well.
* Fluids now use a bvh-tree instead of a kd-tree for the neighbor lookups. The 
bvh-tree 
  implementation makes the code quite a bit cleaner and should also give a 
slight speed
  boost to the simulation too.
* Previously only force fields were calculated with the different integration 
methods, but
  now the fluid calculations are also done using the selected integration 
method, so there
  are again more choices in effecting simulation accuracy and stability. This 
change also
  included a nice cleanup of the whole particle integration code.

As the internals are pretty stirred up old particle fluid simulations will 
probably not
work correctly straight away, but with some tweaking the same level of control 
is still
available by not using the "relative versions" of the advanced parameters (by 
default these
are not used when loading old files).

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/editors/space_view3d/drawobject.c
    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-03-12 
04:39:43 UTC (rev 35487)
+++ trunk/blender/release/scripts/ui/properties_particle.py     2011-03-12 
12:38:11 UTC (rev 35488)
@@ -505,34 +505,53 @@
 
             split = layout.split()
             sub = split.column()
-            sub.label(text="Fluid Interaction:")
-            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="Fluid properties:")
+            sub.prop(fluid, "stiffness", text="Stiffness")
+            sub.prop(fluid, "linear_viscosity", text="Viscosity")
+            sub.prop(fluid, "buoyancy", text="Buoancy", slider=True)
+            
+            sub = split.column()
+            subsub = sub.row()
+            subsub.label(text="Advanced:")
+            subsub = sub.row()
+            subsub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
+            subsub.prop(fluid, "factor_repulsion", text="")
+            
+            subsub = sub.row()
+            subsub.prop(fluid, "stiff_viscosity", 
slider=fluid.factor_stiff_viscosity)
+            subsub.prop(fluid, "factor_stiff_viscosity", text="")
+            
+            subsub = sub.row()
+            subsub.prop(fluid, "fluid_radius", slider=fluid.factor_radius)
+            subsub.prop(fluid, "factor_radius", text="")
+            
+            subsub = sub.row()
+            subsub.prop(fluid, "rest_density", slider=fluid.factor_density)
+            subsub.prop(fluid, "factor_density", text="")
+            
+            split = layout.split()
 
-            sub.label(text="Viscosity:")
-            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")
-            #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)
+            
+            sub = split.column()
+            sub.label(text="Advanced:")
+            subsub = sub.row()
+            subsub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
+            subsub.prop(fluid, "factor_rest_length", text="")
+            sub.label(text="")
+            subsub = sub.column()
+            subsub.active = fluid.use_viscoelastic_springs
             subsub.prop(fluid, "use_initial_rest_length")
+            subsub.prop(fluid, "spring_frames", text="Frames")
+            
 
-            sub.label(text="Buoyancy:")
-            sub.prop(fluid, "buoyancy", text="Strength", slider=True)
-
         elif part.physics_type == 'KEYED':
             split = layout.split()
             sub = split.column()
@@ -967,16 +986,15 @@
         if part.physics_type == 'BOIDS':
             col.prop(part, "show_health")
 
-        col = row.column()
-        col.prop(part, "show_material_color", text="Use material color")
+        col = row.column(align=True)
+        col.label(text="Color:")
+        col.prop(part, "draw_color", text="")
+        sub = col.row()
+        sub.active = part.draw_color in ('VELOCITY', 'ACCELERATION')
+        sub.prop(part, "color_maximum", text="Max")
 
         if (path):
             col.prop(part, "draw_step")
-        else:
-            sub = col.column()
-            sub.active = (part.show_material_color is False)
-            #sub.label(text="color")
-            #sub.label(text="Override material color")
 
 
 class PARTICLE_PT_children(ParticleButtonsPanel, bpy.types.Panel):

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c   2011-03-12 
04:39:43 UTC (rev 35487)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c   2011-03-12 
12:38:11 UTC (rev 35488)
@@ -571,6 +571,7 @@
                
                BLI_freelistN(&psys->targets);
 
+               BLI_bvhtree_free(psys->bvhtree);
                BLI_kdtree_free(psys->tree);
  
                if(psys->fluid_springs)
@@ -2703,7 +2704,7 @@
                        sub_v3_v3v3((child-1)->vel, child->co, (child-2)->co);
                        mul_v3_fl((child-1)->vel, 0.5);
 
-                       if(ctx->ma && (part->draw & PART_DRAW_MAT_COL))
+                       if(ctx->ma && (part->draw_col == PART_DRAW_COL_MAT))
                                get_strand_normal(ctx->ma, ornor, cur_length, 
(child-1)->vel);
                }
 
@@ -2722,7 +2723,7 @@
                        cur_length = 0.0f;
                }
 
-               if(ctx->ma && (part->draw & PART_DRAW_MAT_COL)) {
+               if(ctx->ma && (part->draw_col == PART_DRAW_COL_MAT)) {
                        VECCOPY(child->col, &ctx->ma->r)
                        get_strand_normal(ctx->ma, ornor, cur_length, 
child->vel);
                }
@@ -2907,7 +2908,7 @@
 
        psys->lattice = psys_get_lattice(sim);
        ma= give_current_material(sim->ob, psys->part->omat);
-       if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
+       if(ma && (psys->part->draw_col == PART_DRAW_COL_MAT))
                VECCOPY(col, &ma->r)
 
        if((psys->flag & PSYS_GLOBAL_HAIR)==0) {
@@ -3535,16 +3536,15 @@
        part->clength=1.0f;
        part->clength_thres=0.0f;
 
-       part->draw= PART_DRAW_EMITTER|PART_DRAW_MAT_COL;
+       part->draw= PART_DRAW_EMITTER;
        part->draw_line[0]=0.5;
        part->path_start = 0.0f;
        part->path_end = 1.0f;
 
        part->keyed_loops = 1;
 
-#if 0 // XXX old animation system
-       part->ipo = NULL;
-#endif // XXX old animation system
+       part->color_vec_max = 1.f;
+       part->draw_col = PART_DRAW_COL_MAT;
 
        part->simplify_refsize= 1920;
        part->simplify_rate= 1.0f;

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c    
2011-03-12 04:39:43 UTC (rev 35487)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c    
2011-03-12 12:38:11 UTC (rev 35488)
@@ -1957,113 +1957,8 @@
 
        psys->flag |= PSYS_KEYED;
 }
+
 /************************************************/
-/*                     Reactors                                                
        */
-/************************************************/
-//static void push_reaction(ParticleSimulationData *sim, int pa_num, int 
event, ParticleKey *state)
-//{
-//     Object *rob;
-//     ParticleSystem *rpsys;
-//     ParticleSettings *rpart;
-//     ParticleData *pa;
-//     ListBase *lb=&sim->psys->effectors;
-//     ParticleEffectorCache *ec;
-//     ParticleReactEvent *re;
-//
-//     if(lb->first) for(ec = lb->first; ec; ec= ec->next){
-//             if(ec->type & PSYS_EC_REACTOR){
-//                     /* all validity checks already done in add_to_effectors 
*/
-//                     rob=ec->ob;
-//                     rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr);
-//                     rpart=rpsys->part;
-//                     if(rpsys->part->reactevent==event){
-//                             pa=sim->psys->particles+pa_num;
-//                             re= MEM_callocN(sizeof(ParticleReactEvent), 
"react event");
-//                             re->event=event;
-//                             re->pa_num = pa_num;
-//                             re->ob = sim->ob;
-//                             re->psys = sim->psys;
-//                             re->size = pa->size;
-//                             copy_particle_key(&re->state,state,1);
-//
-//                             switch(event){
-//                                     case PART_EVENT_DEATH:
-//                                             re->time=pa->dietime;
-//                                             break;
-//                                     case PART_EVENT_COLLIDE:
-//                                             re->time=state->time;
-//                                             break;
-//                                     case PART_EVENT_NEAR:
-//                                             re->time=state->time;
-//                                             break;
-//                             }
-//
-//                             BLI_addtail(&rpsys->reactevents, re);
-//                     }
-//             }
-//     }
-//}
-//static void react_to_events(ParticleSystem *psys, int pa_num)
-//{
-//     ParticleSettings *part=psys->part;
-//     ParticleData *pa=psys->particles+pa_num;
-//     ParticleReactEvent *re=psys->reactevents.first;
-//     int birth=0;
-//     float dist=0.0f;
-//
-//     for(re=psys->reactevents.first; re; re=re->next){
-//             birth=0;
-//             if(part->from==PART_FROM_PARTICLE){
-//                     if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
-//                             if(re->event==PART_EVENT_NEAR){
-//                                     ParticleData *tpa = 
re->psys->particles+re->pa_num;
-//                                     float pa_time=tpa->time + 
pa->foffset*tpa->lifetime;
-//                                     if(re->time >= pa_time){
-//                                             pa->time=pa_time;
-//                                             
pa->dietime=pa->time+pa->lifetime;
-//                                     }
-//                             }
-//                             else{
-//                                     pa->time=re->time;
-//                                     pa->dietime=pa->time+pa->lifetime;
-//                             }
-//                     }
-//             }
-//             else{
-//                     dist=len_v3v3(pa->state.co, re->state.co);
-//                     if(dist <= re->size){
-//                             if(pa->alive==PARS_UNBORN){
-//                                     pa->time=re->time;
-//                                     pa->dietime=pa->time+pa->lifetime;
-//                                     birth=1;
-//                             }
-//                             if(birth || part->flag&PART_REACT_MULTIPLE){
-//                                     float vec[3];
-//                                     VECSUB(vec,pa->state.co, re->state.co);
-//                                     if(birth==0)
-//                                             
mul_v3_fl(vec,(float)pow(1.0f-dist/re->size,part->reactshape));
-//                                     
VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac);
-//                                     
VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac);
-//                             }
-//                             if(birth)
-//                                     
mul_v3_fl(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape));
-//                     }
-//             }
-//     }
-//}
-//void psys_get_reactor_target(ParticleSimulationData *sim, Object 
**target_ob, ParticleSystem **target_psys)
-//{
-//     Object *tob;
-//
-//     tob = sim->psys->target_ob ? sim->psys->target_ob : sim->ob;
-//     
-//     *target_psys = BLI_findlink(&tob->particlesystem, 
sim->psys->target_psys-1);
-//     if(*target_psys)
-//             *target_ob=tob;
-//     else
-//             *target_ob=0;
-//}
-/************************************************/
 /*                     Point Cache                                             
        */
 /************************************************/
 void psys_make_temp_pointcache(Object *ob, ParticleSystem *psys)
@@ -2094,17 +1989,48 @@
 /************************************************/
 /*                     Effectors                                               
        */
 /************************************************/
+static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
+{
+       if(psys) {
+               PARTICLE_P;
+               int totpart = 0;
+
+               if(!psys->bvhtree || psys->bvhtree_frame != cfra) {
+                       LOOP_SHOWN_PARTICLES {
+                               totpart++;
+                       }
+                       
+                       BLI_bvhtree_free(psys->bvhtree);
+                       psys->bvhtree = BLI_bvhtree_new(totpart, 0.0, 4, 6);
+
+                       LOOP_SHOWN_PARTICLES {
+                               if(pa->alive == PARS_ALIVE) {
+                                       if(pa->state.time == cfra)

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to