Restored Fluid Sim baking
authorMatt Ebb <matt@mke3.net>
Thu, 25 Mar 2010 06:27:25 +0000 (06:27 +0000)
committerMatt Ebb <matt@mke3.net>
Thu, 25 Mar 2010 06:27:25 +0000 (06:27 +0000)
This commit restores fluid sim baking functionality in 2.5, it's been on the todo for
a while, and was previously almost completely non-functional. The old
code was quite complicated and specific to the 2.4 animation system, so I've
pretty much rewritten most of it.

This includes:
* Animated variables work again - just key them in the UI. Non-animateable values
should be already set non-animateable in RNA, hopefully I got them all.

Available are: Domain Gravity / Domain Viscosity / Object loc/rot/scale /
Object initial velocity / Deforming meshes / Fluid control Attract strength /
Fluid control Attract radius / Fluid control Velocity strength /
Fluid control Velocity radius / Object Active status (checkbox next to fluid type)

The Domain time scale is still not yet implemented.

* Fluid sim now use global scene units data by default - when enabled, the
scene's global gravity value is used and when units are set (metric/imperial)
the simulation real world size is taken from the object's actual measurements.

* The baking process is now done in the background, using the nifty threaded
Jobs system. It's non-blocking and your domain object will show the simulated
fluid as it becomes available for that frame.

A nice extra thing for the future would be to improve the visualisation of the
object's state while baking, and also the jobs system/ui could do with some
touchups - currently it has to share a bit from the 'render' job, and appears as
'Render' in the header. Progress bars for jobs in the header would be great too.

release/scripts/ui/properties_physics_fluid.py
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/fluidsim.c
source/blender/blenkernel/intern/object.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/ED_fluidsim.h
source/blender/editors/physics/physics_fluid.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/makesdna/DNA_object_fluidsim.h
source/blender/makesrna/intern/rna_fluidsim.c
source/blender/makesrna/intern/rna_object.c

index 9b36b98bc24ac7018b9bc35ed8d86c9ae771f7b9..c6fd7e930d96206ffce6a62426b3dfe9992d4f0d 100644 (file)
@@ -42,7 +42,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel):
         md = context.fluid
         wide_ui = context.region.width > narrowui
 
-        split = layout.split()
+        split = layout.split(percentage=0.5)
         split.operator_context = 'EXEC_DEFAULT'
 
         if md:
@@ -53,7 +53,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel):
             row = split.row(align=True)
             row.prop(md, "render", text="")
             row.prop(md, "realtime", text="")
-
+            
             fluid = md.settings
 
         else:
@@ -67,10 +67,19 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel):
 
         if fluid:
             if wide_ui:
-                layout.prop(fluid, "type")
+                row = layout.row()
+                row.prop(fluid, "type")
+                if fluid.type not in ('NONE', 'DOMAIN', 'PARTICLE'):
+                    row.prop(fluid, "active", text="")
             else:
                 layout.prop(fluid, "type", text="")
-
+                if fluid.type not in ('NONE', 'DOMAIN', 'PARTICLE'):
+                    layout.prop(fluid, "active", text="")
+            
+            layout = layout.column()
+            if fluid.type not in ('NONE', 'DOMAIN', 'PARTICLE'):
+                layout.active = fluid.active
+            
             if fluid.type == 'DOMAIN':
                 layout.operator("fluid.bake", text="Bake Fluid Simulation", icon='MOD_FLUIDSIM')
                 split = layout.split()
@@ -220,15 +229,29 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel):
         layout = self.layout
 
         fluid = context.fluid.settings
+        scene = context.scene
         wide_ui = context.region.width > narrowui
 
         split = layout.split()
 
         col = split.column()
-        col.label(text="Gravity:")
-        col.prop(fluid, "gravity", text="")
-        col.label(text="Real World Size:")
-        col.prop(fluid, "real_world_size", text="Metres")
+        if scene.use_gravity:
+            col.label(text="Using Scene Gravity", icon="SCENE_DATA")
+            sub = col.column()
+            sub.enabled = False
+            sub.prop(fluid, "gravity", text="")
+        else:
+            col.label(text="Gravity:")
+            col.prop(fluid, "gravity", text="")
+        
+        if scene.unit_settings.system != 'NONE':
+            col.label(text="Using Scene Size Units", icon="SCENE_DATA")
+            sub = col.column()
+            sub.enabled = False
+            sub.prop(fluid, "real_world_size", text="Metres")
+        else:
+            col.label(text="Real World Size:")
+            col.prop(fluid, "real_world_size", text="Metres")
 
         if wide_ui:
             col = split.column()
index 1362a19191983e61ea153bb2a7ee61c2e21071d0..84995b60f4bc83ad18ae08acb2ab61eda904568f 100644 (file)
@@ -111,6 +111,8 @@ void where_is_object_simul(struct Scene *scene, struct Object *ob);
 struct BoundBox *unit_boundbox(void);
 void boundbox_set_from_min_max(struct BoundBox *bb, float min[3], float max[3]);
 struct BoundBox *object_get_boundbox(struct Object *ob);
+void object_get_dimensions(struct Object *ob, float *value);
+void object_set_dimensions(struct Object *ob, const float *value);
 void object_boundbox_flag(struct Object *ob, int flag, int set);
 void minmax_object(struct Object *ob, float *min, float *max);
 int minmax_object_duplis(struct Scene *scene, struct Object *ob, float *min, float *max);
index fe0f52e9b00421fca4b237971725266fead7082f..118a44507c98361c4e409fa32f82b74475bba462 100644 (file)
@@ -148,7 +148,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
                
                fss->lastgoodframe = -1;
                
-               fss->flag = 0;
+               fss->flag |= OB_FLUIDSIM_ACTIVE;
 
        }
 #endif
index 64abffa5119f599bed4e0583556b78d7eaa269fc..e4350cfde7ff7e2dfe6dc53e90fcc79e09866d01 100644 (file)
@@ -2305,6 +2305,44 @@ void object_boundbox_flag(Object *ob, int flag, int set)
        }
 }
 
+void object_get_dimensions(Object *ob, float *value)
+{
+       BoundBox *bb = NULL;
+       
+       bb= object_get_boundbox(ob);
+       if (bb) {
+               float scale[3];
+               
+               mat4_to_size( scale,ob->obmat);
+               
+               value[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
+               value[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
+               value[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
+       } else {
+               value[0] = value[1] = value[2] = 0.f;
+       }
+}
+
+void object_set_dimensions(Object *ob, const float *value)
+{
+       BoundBox *bb = NULL;
+       
+       bb= object_get_boundbox(ob);
+       if (bb) {
+               float scale[3], len[3];
+               
+               mat4_to_size( scale,ob->obmat);
+               
+               len[0] = bb->vec[4][0] - bb->vec[0][0];
+               len[1] = bb->vec[2][1] - bb->vec[0][1];
+               len[2] = bb->vec[1][2] - bb->vec[0][2];
+               
+               if (len[0] > 0.f) ob->size[0] = value[0] / len[0];
+               if (len[1] > 0.f) ob->size[1] = value[1] / len[1];
+               if (len[2] > 0.f) ob->size[2] = value[2] / len[2];
+       }
+}
+
 void minmax_object(Object *ob, float *min, float *max)
 {
        BoundBox bb;
index a894df1bd79afe381bcb952a4c4e86a7704c4861..dbdd1685c816c1a88575a0f247a7317a9aea7f24 100644 (file)
@@ -10659,8 +10659,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        for(md= ob->modifiers.first; md; md= md->next) {
                                if (md->type == eModifierType_Fluidsim) {
                                        FluidsimModifierData *fmd = (FluidsimModifierData *)md;
-                               /*      fmd->fss->flag |= OB_FLUIDSIM_ACTIVE; 
-                                       temporarily commented out for matt_ebb */
+                                       fmd->fss->flag |= OB_FLUIDSIM_ACTIVE; 
+                                       fmd->fss->flag |= OB_FLUIDSIM_OVERRIDE_TIME;
                                }
                        }
                }
index 8a9a294d423ff309f740752bbce3ce0dc9d3dea2..a1ab3ba2fcc06e65d298c9d63fbbaa4a094dc026 100644 (file)
@@ -34,8 +34,6 @@
 struct Object;
 struct FluidsimSettings;
 
-extern double fluidsimViscosityPreset[6];
-extern char* fluidsimViscosityPresetString[6];
 
 /* allocates and initializes fluidsim data */
 struct FluidsimSettings* fluidsimSettingsNew(struct Object *srcob);
index 8c05a4efcf65348a03021eef105d26a3ee9c1b91..6f5b8924a13206c825e99cda2a6e59030472a59e 100644 (file)
 #include "MEM_guardedalloc.h"
 
 /* types */
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_object_types.h"
 #include "DNA_object_fluidsim.h"       
 
 #include "BLI_blenlib.h"
 #include "BLI_threads.h"
 #include "BLI_math.h"
 
+#include "BKE_animsys.h"
+#include "BKE_armature.h"
 #include "BKE_blender.h"
 #include "BKE_context.h"
 #include "BKE_customdata.h"
@@ -67,6 +72,7 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_softbody.h"
+#include "BKE_unit.h"
 
 
 #include "LBM_fluidsim.h"
 
 #include "PIL_time.h"
 
-/* XXX */
-/* from header info.c */
-static int start_progress_bar(void) {return 0;};
-static void end_progress_bar(struct wmWindow *win) {WM_cursor_restore(win);};
-static void waitcursor(int val) {};
-static int progress_bar(wmWindow *win, float done, char *busy_info) { WM_timecursor(win,done*100); return 0;}
-static int pupmenu() {return 0;}
-/* XXX */
-
-
-double fluidsimViscosityPreset[6] = {
-       -1.0,   /* unused */
-       -1.0,   /* manual */
-       1.0e-6, /* water */
-       5.0e-5, /* some (thick) oil */
-       2.0e-3, /* ca. honey */
-       -1.0    /* end */
-};
-
-char* fluidsimViscosityPresetString[6] = {
-       "UNUSED",       /* unused */
-       "UNUSED",       /* manual */
-       "  = 1.0 * 10^-6", /* water */
-       "  = 5.0 * 10^-5", /* some (thick) oil */
-       "  = 2.0 * 10^-3", /* ca. honey */
-       "INVALID"       /* end */
-};
+
+static float get_fluid_viscosity(FluidsimSettings *settings)
+{
+       switch (settings->viscosityMode) {
+               case 0:         /* unused */
+                       return -1.0;
+               case 2:         /* water */
+                       return 1.0e-6;
+               case 3:         /* some (thick) oil */
+                       return 5.0e-5;
+               case 4:         /* ca. honey */
+                       return 2.0e-3;
+               case 1:         /* manual */
+               default:
+                       return (1.0/pow(10.0, settings->viscosityExponent)) * settings->viscosityValue;
+       }
+}
+
+static void get_fluid_gravity(float *gravity, Scene *scene, FluidsimSettings *fss)
+{
+       if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
+               copy_v3_v3(gravity, scene->physics_settings.gravity);
+       } else {
+               copy_v3_v3(gravity, &fss->gravx);
+       }
+}
+
+static float get_fluid_size_m(Scene *scene, Object *domainob, FluidsimSettings *fss)
+{
+       if (!scene->unit.system) {
+               return fss->realsize;
+       } else {
+               float dim[3];
+               float longest_axis;
+               
+               object_get_dimensions(domainob, dim);
+               longest_axis = MAX3(dim[0], dim[1], dim[2]);
+               
+               return longest_axis * scene->unit.scale_length;
+       }
+}
+
+static int fluid_is_animated_mesh(FluidsimSettings *fss)
+{
+       return ((fss->type == OB_FLUIDSIM_CONTROL) || fss->domainNovecgen);
+}
 
 /* ********************** fluid sim settings struct functions ********************** */
 
+#if 0
 /* helper function */
 void fluidsimGetGeometryObjFilename(Object *ob, char *dst) { //, char *srcname) {
        //snprintf(dst,FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name);
        snprintf(dst,FILE_MAXFILE, "fluidcfgdata_%s.bobj.gz", ob->id.name);
 }
+#endif
 
 
-
-
-/* ******************************************************************************** */
 /* ********************** fluid sim channel helper functions ********************** */
-/* ******************************************************************************** */
+
+typedef struct FluidAnimChannels {
+       int length;
+       
+       double aniFrameTime;
+       
+       float *timeAtFrame;
+       float *DomainTime;
+       float *DomainGravity;
+       float *DomainViscosity;
+} FluidAnimChannels;
+
+typedef struct FluidObject {
+       struct FluidObject *next, *prev;
+       
+       struct Object *object;
+       
+       float *Translation;
+       float *Rotation;
+       float *Scale;
+       float *Active;
+       
+       float *InitialVelocity;
+       
+       float *AttractforceStrength;
+       float *AttractforceRadius;
+       float *VelocityforceStrength;
+       float *VelocityforceRadius;
+       
+       float *VertexCache;
+       int numVerts, numTris;
+} FluidObject;
 
 // no. of entries for the two channel sizes
 #define CHANNEL_FLOAT 1
 #define CHANNEL_VEC   3
 
-#define FS_FREE_ONECHANNEL(c,str) { \
-       if(c){ MEM_freeN(c); c=NULL; } \
-} // end ONE CHANN, debug: fprintf(stderr,"freeing " str " \n"); 
-
-#define FS_FREE_CHANNELS { \
-       FS_FREE_ONECHANNEL(timeAtIndex,"timeAtIndex");\
-       FS_FREE_ONECHANNEL(timeAtFrame,"timeAtFrame");\
-       FS_FREE_ONECHANNEL(channelDomainTime,"channelDomainTime"); \
-       FS_FREE_ONECHANNEL(channelDomainGravity,"channelDomainGravity");\
-       FS_FREE_ONECHANNEL(channelDomainViscosity,"channelDomainViscosity");\
-       for(i=0;i<256;i++) { \
-               FS_FREE_ONECHANNEL(channelObjMove[i][0],"channelObjMove0"); \
-               FS_FREE_ONECHANNEL(channelObjMove[i][1],"channelObjMove1"); \
-               FS_FREE_ONECHANNEL(channelObjMove[i][2],"channelObjMove2"); \
-               FS_FREE_ONECHANNEL(channelObjInivel[i],"channelObjInivel"); \
-               FS_FREE_ONECHANNEL(channelObjActive[i],"channelObjActive"); \
-               FS_FREE_ONECHANNEL(channelAttractforceStrength[i],"channelAttractforceStrength"); \
-               FS_FREE_ONECHANNEL(channelAttractforceRadius[i],"channelAttractforceRadius"); \
-               FS_FREE_ONECHANNEL(channelVelocityforceStrength[i],"channelVelocityforceStrength"); \
-               FS_FREE_ONECHANNEL(channelVelocityforceRadius[i],"channelVelocityforceRadius"); \
-       }  \
-} // end FS FREE CHANNELS
-
-
 // simplify channels before printing
 // for API this is done anyway upon init
 #if 0
@@ -191,336 +222,616 @@ static void fluidsimPrintChannel(FILE *file, float *channel, int paramsize, char
 }
 #endif
 
-static void fluidsimInitChannel(Scene *scene, float **setchannel, int size, float *time, 
-               int *icuIds, float *defaults, Ipo* ipo, int entries) 
+
+/* Note: fluid anim channel data layout
+ * ------------------------------------
+ * CHANNEL_FLOAT:
+ * frame 1     |frame 2
+ * [dataF][time][dataF][time]
+ *
+ * CHANNEL_VEC:
+ * frame 1                   |frame 2
+ * [dataX][dataY][dataZ][time][dataX][dataY][dataZ][time]
+ *
+ */
+
+static void init_time(FluidsimSettings *domainSettings, FluidAnimChannels *channels)
 {
+       int i;
+       
+       channels->timeAtFrame = MEM_callocN( (channels->length+1)*sizeof(float), "timeAtFrame channel");
+       
+       channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1
+       
+       for(i=2; i<=channels->length; i++) {
+               channels->timeAtFrame[i] = channels->timeAtFrame[i-1] + channels->aniFrameTime;
+       }
+}
+
+/* if this is slow, can replace with faster, less readable code */
+static void set_channel(float *channel, float time, float *value, int i, int size)
+{
+       if (size == CHANNEL_FLOAT) {
+               channel[(i * 2) + 0] = value[0];
+               channel[(i * 2) + 1] = time;
+       }
+       else if (size == CHANNEL_VEC) {
+               channel[(i * 4) + 0] = value[0];
+               channel[(i * 4) + 1] = value[1];
+               channel[(i * 4) + 2] = value[2];
+               channel[(i * 4) + 3] = time;
+       }
+}
 
-       int i, j;
-       char *cstr = NULL;
-       float *channel = NULL;
+static void set_vertex_channel(float *channel, float time, struct Scene *scene, struct FluidObject *fobj, int i)
+{
+       Object *ob = fobj->object;
+       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+       float *verts;
+       int *tris=NULL, numVerts=0, numTris=0;
+       int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+       int framesize = (3*fobj->numVerts) + 1;
+       int j;
+       
+       if (channel == NULL)
+               return;
        
-       cstr = "fluidsiminit_channelfloat";
-       if(entries>1) cstr = "fluidsiminit_channelvec";
-       channel = MEM_callocN( size* (entries+1)* sizeof(float), cstr );
+       initElbeemMesh(scene, ob, &numVerts, &verts, &numTris, &tris, 1, modifierIndex);
        
-       /* defaults  for now */
-       for(j=0; j<entries; j++) {
-               for(i=1; i<=size; i++) {
-                       channel[(i-1)*(entries+1) + j] = defaults[j];
-               }       
+       /* don't allow mesh to change number of verts in anim sequence */
+       if (numVerts != fobj->numVerts) {
+               MEM_freeN(channel);
+               channel = NULL;
+               return;
        }
        
-       for(i=1; i<=size; i++) {
-               channel[(i-1)*(entries+1) + entries] = time[i];
+       /* fill frame of channel with vertex locations */
+       for(j=0; j < (3*numVerts); j++) {
+               channel[i*framesize + j] = verts[j];
        }
+       channel[i*framesize + framesize-1] = time;
+       
+       MEM_freeN(verts);
+       MEM_freeN(tris);
+}
 
-       *setchannel = channel;
+static void free_domain_channels(FluidAnimChannels *channels)
+{
+       MEM_freeN(channels->timeAtFrame);
+       channels->timeAtFrame = NULL;
+       MEM_freeN(channels->DomainGravity);
+       channels->DomainGravity = NULL;
+       MEM_freeN(channels->DomainViscosity);
+       channels->DomainViscosity = NULL;
+}
 
-#if 0
-       /* goes away completely */
-       int i,j;
-       IpoCurve* icus[3];
-       char *cstr = NULL;
-       float *channel = NULL;
-       float aniFrlen = scene->r.framelen;
-       int current_frame = scene->r.cfra;
-       if((entries<1) || (entries>3)) {
-               printf("fluidsimInitChannel::Error - invalid no. of entries: %d\n",entries);
-               entries = 1;
+static void free_all_fluidobject_channels(ListBase *fobjects)
+{
+       FluidObject *fobj;
+       
+       for (fobj=fobjects->first; fobj; fobj=fobj->next) {
+               if (fobj->Translation) {
+                       MEM_freeN(fobj->Translation);
+                       fobj->Translation = NULL;
+                       MEM_freeN(fobj->Rotation);
+                       fobj->Rotation = NULL;
+                       MEM_freeN(fobj->Scale);
+                       fobj->Scale = NULL;
+                       MEM_freeN(fobj->Active);
+                       fobj->Active = NULL;
+                       MEM_freeN(fobj->InitialVelocity);
+                       fobj->InitialVelocity = NULL;
+               }
+               
+               if (fobj->AttractforceStrength) {
+                       MEM_freeN(fobj->AttractforceStrength);
+                       fobj->AttractforceStrength = NULL;
+                       MEM_freeN(fobj->AttractforceRadius);
+                       fobj->AttractforceRadius = NULL;
+                       MEM_freeN(fobj->VelocityforceStrength);
+                       fobj->VelocityforceStrength = NULL;
+                       MEM_freeN(fobj->VelocityforceRadius);
+                       fobj->VelocityforceRadius = NULL;
+               }
+               
+               if (fobj->VertexCache) {
+                       MEM_freeN(fobj->VertexCache);
+                       fobj->VertexCache = NULL;
+               }
        }
+}
 
-       cstr = "fluidsiminit_channelfloat";
-       if(entries>1) cstr = "fluidsiminit_channelvec";
-       channel = MEM_callocN( size* (entries+1)* sizeof(float), cstr );
+static void fluid_init_all_channels(bContext *C, Object *fsDomain, FluidsimSettings *domainSettings, FluidAnimChannels *channels, ListBase *fobjects)
+{
+       Scene *scene = CTX_data_scene(C);
+       Base *base;
+       int i;
+       int length = channels->length;
+       float eval_time;
        
-       if(ipo) {
-               for(j=0; j<entries; j++) icus[j]  = find_ipocurve(ipo, icuIds[j] );
-       } else {
-               for(j=0; j<entries; j++) icus[j]  = NULL; 
-       }
+       /* XXX: first init time channel - temporary for now */
+       /* init time values (should be done after evaluating animated time curve) */
+       init_time(domainSettings, channels);
        
-       for(j=0; j<entries; j++) {
-               if(icus[j]) { 
-                       for(i=1; i<=size; i++) {
-                               /* Bugfix to make python drivers working
-                               // which uses Blender.get("curframe") 
-                               */
-                               scene->r.cfra = floor(aniFrlen*((float)i));
+       /* allocate domain animation channels */
+       channels->DomainGravity = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "channel DomainGravity");
+       channels->DomainViscosity = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainViscosity");
+       //channels->DomainTime = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime");
+       
+       /* allocate fluid objects */
+       for (base=scene->base.first; base; base= base->next) {
+               Object *ob = base->object;
+               FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+               
+               if (fluidmd) {
+                       FluidObject *fobj = MEM_callocN(sizeof(FluidObject), "Fluid Object");
+                       fobj->object = ob;
+                       
+                       if (ELEM(fluidmd->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE)) {
+                               BLI_addtail(fobjects, fobj);
+                               continue;
+                       }
+                       
+                       fobj->Translation = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "fluidobject Translation");
+                       fobj->Rotation = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "fluidobject Rotation");
+                       fobj->Scale = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "fluidobject Scale");
+                       fobj->Active = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject Active");
+                       fobj->InitialVelocity = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "fluidobject InitialVelocity");
+                       
+                       if (fluidmd->fss->type == OB_FLUIDSIM_CONTROL) {
+                               fobj->AttractforceStrength = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject AttractforceStrength");
+                               fobj->AttractforceRadius = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject AttractforceRadius");
+                               fobj->VelocityforceStrength = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject VelocityforceStrength");
+                               fobj->VelocityforceRadius = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject VelocityforceRadius");
+                       }
+                       
+                       if (fluid_is_animated_mesh(fluidmd->fss)) {
+                               float *verts=NULL;
+                               int *tris=NULL, modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+
+                               initElbeemMesh(scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex);
+                               fobj->VertexCache = MEM_callocN( length *((fobj->numVerts*CHANNEL_VEC)+1) * sizeof(float), "fluidobject VertexCache");
                                
-                               // XXX calc_icu(icus[j], aniFrlen*((float)i) );
-                               channel[(i-1)*(entries+1) + j] = icus[j]->curval;
+                               MEM_freeN(verts);
+                               MEM_freeN(tris);
                        }
-               }  else {
-                       for(i=1; i<=size; i++) { channel[(i-1)*(entries+1) + j] = defaults[j]; }
+                       
+                       BLI_addtail(fobjects, fobj);
                }
-               //printf("fluidsimInitChannel entry:%d , ",j); for(i=1; i<=size; i++) { printf(" val%d:%f ",i, channel[(i-1)*(entries+1) + j] ); } printf(" \n"); // DEBUG
        }
-       // set time values
-       for(i=1; i<=size; i++) {
-               channel[(i-1)*(entries+1) + entries] = time[i];
+       
+       /* now we loop over the frames and fill the allocated channels with data */
+       for (i=0; i<channels->length; i++) {
+               FluidObject *fobj;
+               float viscosity, gravity[3];
+               float timeAtFrame;
+               
+               eval_time = domainSettings->bakeStart + i;
+               timeAtFrame = channels->timeAtFrame[i+1];
+               
+               /* XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation,
+                * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
+                * --> BKE_animsys_evaluate_all_animation(G.main, eval_time);
+                * This doesn't work with drivers:
+                * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
+                */
+               
+               /* Modifying the global scene isn't nice, but we can do it in 
+                * this part of the process before a threaded job is created */
+               scene->r.cfra = (int)eval_time;
+               ED_update_for_newframe(C, 1);
+               
+               /* now scene data should be current according to animation system, so we fill the channels */
+               
+               /* Domain properties - gravity/viscosity/time */
+               get_fluid_gravity(gravity, scene, domainSettings);
+               set_channel(channels->DomainGravity, timeAtFrame, gravity, i, CHANNEL_VEC);
+               viscosity = get_fluid_viscosity(domainSettings);
+               set_channel(channels->DomainViscosity, timeAtFrame, &viscosity, i, CHANNEL_FLOAT);
+               // XXX : set_channel(channels->DomainTime, timeAtFrame, &time, i, CHANNEL_VEC);
+               
+               /* object movement */
+               for (fobj=fobjects->first; fobj; fobj=fobj->next) {
+                       Object *ob = fobj->object;
+                       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+                       float active= (float)(fluidmd->fss->flag & OB_FLUIDSIM_ACTIVE);
+                       float rot_d[3], rot_360[3] = {360.f, 360.f, 360.f};
+                       
+                       if (ELEM(fluidmd->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE))
+                               continue;
+                       
+                       /* init euler rotation values and convert to elbeem format */
+                       BKE_rotMode_change_values(ob->quat, ob->rot, ob->rotAxis, &ob->rotAngle, ob->rotmode, ROT_MODE_EUL);
+                       mul_v3_v3fl(rot_d, ob->rot, 180.f/M_PI);
+                       sub_v3_v3v3(rot_d, rot_360, rot_d);
+                       
+                       set_channel(fobj->Translation, timeAtFrame, ob->loc, i, CHANNEL_VEC);
+                       set_channel(fobj->Rotation, timeAtFrame, rot_d, i, CHANNEL_VEC);
+                       set_channel(fobj->Scale, timeAtFrame, ob->size, i, CHANNEL_VEC);
+                       set_channel(fobj->Active, timeAtFrame, &active, i, CHANNEL_FLOAT);
+                       set_channel(fobj->InitialVelocity, timeAtFrame, &fluidmd->fss->iniVelx, i, CHANNEL_VEC);
+                       
+                       if (fluidmd->fss->type == OB_FLUIDSIM_CONTROL) {
+                               set_channel(fobj->AttractforceStrength, timeAtFrame, &fluidmd->fss->attractforceStrength, i, CHANNEL_FLOAT);
+                               set_channel(fobj->AttractforceRadius, timeAtFrame, &fluidmd->fss->attractforceRadius, i, CHANNEL_FLOAT);
+                               set_channel(fobj->VelocityforceStrength, timeAtFrame, &fluidmd->fss->velocityforceStrength, i, CHANNEL_FLOAT);
+                               set_channel(fobj->VelocityforceRadius, timeAtFrame, &fluidmd->fss->velocityforceRadius, i, CHANNEL_FLOAT);
+                       }
+                       
+                       if (fluid_is_animated_mesh(fluidmd->fss)) {
+                               set_vertex_channel(fobj->VertexCache, timeAtFrame, scene, fobj, i);
+                       }
+               }
        }
-       scene->r.cfra = current_frame;
-       *setchannel = channel;
-#endif
 }
 
-static void fluidsimInitMeshChannel(bContext *C, float **setchannel, int size, Object *obm, int vertices, 
-                                                                       float *time, int modifierIndex) 
+static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length)
 {
-       Scene *scene= CTX_data_scene(C);
-       float *channel = NULL;
-       int mallsize = size* (3*vertices+1);
-       int frame,i;
-       int numVerts=0, numTris=0;
-       int setsize = 3*vertices+1;
-
-       channel = MEM_callocN( mallsize* sizeof(float), "fluidsim_meshchannel" );
-
-       //fprintf(stderr,"\n\nfluidsimInitMeshChannel size%d verts%d mallsize%d \n\n\n",size,vertices,mallsize);
-       for(frame=1; frame<=size; frame++) {
+       FluidObject *fobj;
+       
+       for (fobj=fobjects->first; fobj; fobj=fobj->next) {
+               Object *ob = fobj->object;
+               FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+               int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+               
                float *verts=NULL;
                int *tris=NULL;
-               scene->r.cfra = frame;
-               ED_update_for_newframe(C, 1);
+               int numVerts=0, numTris=0;
+               int deform = fluid_is_animated_mesh(fluidmd->fss);
+               
+               elbeemMesh fsmesh;
+               
+               if (ELEM(fluidmd->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE))
+                       continue;
+               
+               elbeemResetMesh( &fsmesh );
+               
+               fsmesh.type = fluidmd->fss->type;
+               fsmesh.name = ob->id.name;
+               
+               initElbeemMesh(scene, ob, &numVerts, &verts, &numTris, &tris, 0, modifierIndex);
+               
+               fsmesh.numVertices   = numVerts;
+               fsmesh.numTriangles  = numTris;
+               fsmesh.vertices      = verts;
+               fsmesh.triangles     = tris;
+               
+               fsmesh.channelSizeTranslation  = 
+               fsmesh.channelSizeRotation     = 
+               fsmesh.channelSizeScale        = 
+               fsmesh.channelSizeInitialVel   = 
+               fsmesh.channelSizeActive       = length;
+               
+               fsmesh.channelTranslation      = fobj->Translation;
+               fsmesh.channelRotation         = fobj->Rotation;
+               fsmesh.channelScale            = fobj->Scale;
+               fsmesh.channelActive           = fobj->Active;
+               
+               if( ELEM(fsmesh.type, OB_FLUIDSIM_FLUID, OB_FLUIDSIM_INFLOW)) {
+                       fsmesh.channelInitialVel = fobj->InitialVelocity;
+                       fsmesh.localInivelCoords = ((fluidmd->fss->typeFlags & OB_FSINFLOW_LOCALCOORD)?1:0);
+               } 
+               
+               if(fluidmd->fss->typeFlags & OB_FSBND_NOSLIP)
+                       fsmesh.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP;
+               else if(fluidmd->fss->typeFlags & OB_FSBND_PARTSLIP)
+                       fsmesh.obstacleType = FLUIDSIM_OBSTACLE_PARTSLIP;
+               else if(fluidmd->fss->typeFlags & OB_FSBND_FREESLIP)
+                       fsmesh.obstacleType = FLUIDSIM_OBSTACLE_FREESLIP;
+               
+               fsmesh.obstaclePartslip = fluidmd->fss->partSlipValue;
+               fsmesh.volumeInitType = fluidmd->fss->volumeInitType;
+               fsmesh.obstacleImpactFactor = fluidmd->fss->surfaceSmoothing; // misused value
+               
+               if (fsmesh.type == OB_FLUIDSIM_CONTROL) {
+                       fsmesh.cpsTimeStart = fluidmd->fss->cpsTimeStart;
+                       fsmesh.cpsTimeEnd = fluidmd->fss->cpsTimeEnd;
+                       fsmesh.cpsQuality = fluidmd->fss->cpsQuality;
+                       fsmesh.obstacleType = (fluidmd->fss->flag & OB_FLUIDSIM_REVERSE);
+                       
+                       fsmesh.channelSizeAttractforceRadius = 
+                       fsmesh.channelSizeVelocityforceStrength = 
+                       fsmesh.channelSizeVelocityforceRadius = 
+                       fsmesh.channelSizeAttractforceStrength = length;
+                       
+                       fsmesh.channelAttractforceStrength = fobj->AttractforceStrength;
+                       fsmesh.channelAttractforceRadius = fobj->AttractforceRadius;
+                       fsmesh.channelVelocityforceStrength = fobj->VelocityforceStrength;
+                       fsmesh.channelVelocityforceRadius = fobj->VelocityforceRadius;
+               }
+               else {
+                       fsmesh.channelAttractforceStrength =
+                       fsmesh.channelAttractforceRadius = 
+                       fsmesh.channelVelocityforceStrength = 
+                       fsmesh.channelVelocityforceRadius = NULL; 
+               }
+               
+               /* animated meshes */
+               if(deform) {
+                       fsmesh.channelSizeVertices = length;
+                       fsmesh.channelVertices = fobj->VertexCache;
+                               
+                       // remove channels
+                       fsmesh.channelTranslation      = 
+                       fsmesh.channelRotation         = 
+                       fsmesh.channelScale            = NULL; 
+               }
+               
+               elbeemAddMesh(&fsmesh);
+               
+               if(verts) MEM_freeN(verts);
+               if(tris) MEM_freeN(tris);
+               if(fsmesh.channelVertices) MEM_freeN(fsmesh.channelVertices);
+       }
+}
+
+static int fluid_validate_scene(ReportList *reports, Scene *scene, Object *fsDomain)
+{
+       Base *base;
+       Object *newdomain = NULL;
+       int channelObjCount = 0;
+       int fluidInputCount = 0;
 
-               initElbeemMesh(scene, obm, &numVerts, &verts, &numTris, &tris, 1, modifierIndex);
-               //fprintf(stderr,"\nfluidsimInitMeshChannel frame%d verts%d/%d \n\n",frame,vertices,numVerts);
-               for(i=0; i<3*vertices;i++) {
-                       channel[(frame-1)*setsize + i] = verts[i];
-                       //fprintf(stdout," frame%d vert%d=%f \n",frame,i,verts[i]);
-                       //if(i%3==2) fprintf(stdout,"\n");
+       for(base=scene->base.first; base; base= base->next)
+       {
+               Object *ob = base->object;
+               FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);                    
+
+               /* only find objects with fluid modifiers */
+               if (!fluidmdtmp || ob->type != OB_MESH) continue;
+                       
+               if(fluidmdtmp->fss->type == OB_FLUIDSIM_DOMAIN) {
+                       /* if no initial domain object given, find another potential domain */
+                       if (!fsDomain) {
+                               newdomain = ob;
+                       }
+                       /* if there's more than one domain, cancel */
+                       else if (fsDomain && ob != fsDomain) {
+                               BKE_report(reports, RPT_ERROR, "There should be only one domain object.");
+                               return 0;
+                       }
                }
-               channel[(frame-1)*setsize + setsize-1] = time[frame];
+               
+               /* count number of objects needed for animation channels */
+               if ( !ELEM(fluidmdtmp->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE) )
+                       channelObjCount++;
+               
+               /* count number of fluid input objects */
+               if (ELEM(fluidmdtmp->fss->type, OB_FLUIDSIM_FLUID, OB_FLUIDSIM_INFLOW))
+                       fluidInputCount++;
+       }
 
-               MEM_freeN(verts);
-               MEM_freeN(tris);
+       if (newdomain)
+               fsDomain = newdomain;
+       
+       if (!fsDomain) {
+               BKE_report(reports, RPT_ERROR, "No domain object found.");
+               return 0;
+       }
+       
+       if (channelObjCount>=255) {
+               BKE_report(reports, RPT_ERROR, "Cannot bake with more then 256 objects.");
+               return 0;
        }
-       *setchannel = channel;
+       
+       if (fluidInputCount == 0) {
+               BKE_report(reports, RPT_ERROR, "No fluid input objects in the scene.");
+               return 0;
+       }
+       
+       return 1;
 }
 
 
-/* ******************************************************************************** */
-/* ********************** simulation thread             ************************* */
-/* ******************************************************************************** */
+#define FLUID_SUFFIX_CONFIG            "fluidsim.cfg"
+#define FLUID_SUFFIX_SURFACE   "fluidsurface"
 
-static volatile int    globalBakeState = 0; // 0 everything ok, -1 abort simulation, -2 sim error, 1 sim done
-static volatile int    globalBakeFrame = 0;
-static volatile int g_break= 0;
-
-// run simulation in seperate thread
-static void *fluidsimSimulateThread(void *unused) { // *ptr) {
-       //char* fnameCfgPath = (char*)(ptr);
-       int ret=0;
-       
-       ret = elbeemSimulate();
-       BLI_lock_thread(LOCK_CUSTOM1);
-       if(globalBakeState==0) {
-               if(ret==0) {
-                       // if no error, set to normal exit
-                       globalBakeState = 1;
-               } else {
-                       // simulation failed, display error
-                       globalBakeState = -2;
+static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetFile, char *debugStrBuffer)
+{
+       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim);
+       FluidsimSettings *domainSettings= fluidmd->fss; 
+       FILE *fileCfg;
+       int dirExist = 0;
+       char newSurfdataPath[FILE_MAXDIR+FILE_MAXFILE]; // modified output settings
+       char *suffixConfig = FLUID_SUFFIX_CONFIG;
+       int outStringsChanged = 0;
+       
+       // prepare names...
+       strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
+       strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR);
+       BLI_path_abs(targetDir, G.sce); // fixed #frame-no 
+       
+       strcpy(targetFile, targetDir);
+       strcat(targetFile, suffixConfig);
+       strcat(targetFile,".tmp"); // dont overwrite/delete original file
+       // make sure all directories exist
+       // as the bobjs use the same dir, this only needs to be checked
+       // for the cfg output
+       BLI_make_existing_file(targetFile);
+       
+       // check selected directory
+       // simply try to open cfg file for writing to test validity of settings
+       fileCfg = fopen(targetFile, "w");
+       if(fileCfg) { 
+               dirExist = 1; fclose(fileCfg); 
+               // remove cfg dummy from  directory test
+               BLI_delete(targetFile, 0,0);
+       }
+       
+       if((strlen(targetDir)<1) || (!dirExist)) {
+               char blendDir[FILE_MAXDIR+FILE_MAXFILE];
+               char blendFile[FILE_MAXDIR+FILE_MAXFILE];
+               
+               // invalid dir, reset to current/previous
+               strcpy(blendDir, G.sce);
+               BLI_splitdirstring(blendDir, blendFile);
+               if(strlen(blendFile)>6){
+                       int len = strlen(blendFile);
+                       if( (blendFile[len-6]=='.')&& (blendFile[len-5]=='b')&& (blendFile[len-4]=='l')&&
+                          (blendFile[len-3]=='e')&& (blendFile[len-2]=='n')&& (blendFile[len-1]=='d') ){
+                               blendFile[len-6] = '\0';
+                       }
                }
+               // todo... strip .blend ?
+               snprintf(newSurfdataPath,FILE_MAXFILE+FILE_MAXDIR,"//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name);
+               
+               snprintf(debugStrBuffer,256,"fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath);
+               elbeemDebugOut(debugStrBuffer);
+               outStringsChanged=1;
        }
-       BLI_unlock_thread(LOCK_CUSTOM1);
-       return NULL;
+       
+       // check if modified output dir is ok
+#if 0
+       if(outStringsChanged) {
+               char dispmsg[FILE_MAXDIR+FILE_MAXFILE+256];
+               int  selection=0;
+               strcpy(dispmsg,"Output settings set to: '");
+               strcat(dispmsg, newSurfdataPath);
+               strcat(dispmsg, "'%t|Continue with changed settings%x1|Discard and abort%x0");
+               
+               // ask user if thats what he/she wants...
+               selection = pupmenu(dispmsg);
+               if(selection<1) return 0; // 0 from menu, or -1 aborted
+               strcpy(targetDir, newSurfdataPath);
+               strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR);
+               BLI_path_abs(targetDir, G.sce); // fixed #frame-no 
+       }
+#endif 
+       return outStringsChanged;
+}
+
+/* ******************************************************************************** */
+/* ********************** write fluidsim config to file ************************* */
+/* ******************************************************************************** */
+
+typedef struct FluidBakeJob {
+       /* from wmJob */
+       void *owner;
+       short *stop, *do_update;
+       
+       int current_frame;
+       elbeemSimulationSettings *settings;
+} FluidBakeJob;
+
+static void fluidbake_free(void *customdata)
+{
+       FluidBakeJob *fb= customdata;
+       MEM_freeN(fb);
+}
+
+/* called by fluidbake, only to check job 'stop' value */
+static int fluidbake_breakjob(void *customdata)
+{
+       //FluidBakeJob *fb= (FluidBakeJob *)customdata;
+       //return *(fb->stop);
+       
+       /* this is not nice yet, need to make the jobs list template better 
+        * for identifying/acting upon various different jobs */
+       /* but for now we'll reuse the render break... */
+       return (G.afbreek);
+}
+
+/* called by fluidbake, wmJob sends notifier */
+static void fluidbake_updatejob(void *customdata, char *str)
+{
+       FluidBakeJob *fb= customdata;
+       
+       *(fb->do_update)= 1;
 }
 
+static void fluidbake_startjob(void *customdata, short *stop, short *do_update)
+{
+       FluidBakeJob *fb= customdata;
+       
+       fb->stop= stop;
+       fb->do_update = do_update;
+       
+       G.afbreek= 0;   /* XXX shared with render - replace with job 'stop' switch */
+       
+       elbeemSimulate();
+       *do_update= 1;
+       *stop = 0;
+}
 
 int runSimulationCallback(void *data, int status, int frame) {
-       //elbeemSimulationSettings *settings = (elbeemSimulationSettings*)data;
+       FluidBakeJob *fb = (FluidBakeJob *)data;
+       
+       //elbeemSimulationSettings *settings = fb->settings;
        //printf("elbeem blender cb s%d, f%d, domainid:%d \n", status,frame, settings->domainId ); // DEBUG
-       int state = 0;
-       if(status==FLUIDSIM_CBSTATUS_NEWFRAME) {
-               BLI_lock_thread(LOCK_CUSTOM1);
-               globalBakeFrame = frame-1;
-               BLI_unlock_thread(LOCK_CUSTOM1);
-       }
        
-       //if((frameCounter==3) && (!frameStop)) { frameStop=1; return 1; }
-               
-       BLI_lock_thread(LOCK_CUSTOM1);
-       state = globalBakeState;
-       BLI_unlock_thread(LOCK_CUSTOM1);
+       if (status == FLUIDSIM_CBSTATUS_NEWFRAME)
+               fluidbake_updatejob(fb, "");
        
-       if(state!=0) {
+       if (fluidbake_breakjob(fb))  {
                return FLUIDSIM_CBRET_ABORT;
        }
        
        return FLUIDSIM_CBRET_CONTINUE;
 }
 
-
-/* ******************************************************************************** */
-/* ********************** write fluidsim config to file ************************* */
-/* ******************************************************************************** */
-
-int fluidsimBake(bContext *C, ReportList *reports, Object *ob)
+int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain)
 {
        Scene *scene= CTX_data_scene(C);
-       FILE *fileCfg;
        int i;
-       Object *fsDomain = NULL;
        FluidsimSettings *domainSettings;
-       Object *obit = NULL; /* object iterator */
-       Base *base;
-       int origFrame = scene->r.cfra;
+
        char debugStrBuffer[256];
-       int dirExist = 0;
+       
        int gridlevels = 0;
-       int simAborted = 0; // was the simulation aborted by user?
-       int  doExportOnly = 0;
-       char *exportEnvStr = "BLENDER_ELBEEMEXPORTONLY";
        const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp
-       //char *channelNames[3] = { "translation","rotation","scale" };
+       char *suffixConfig = FLUID_SUFFIX_CONFIG;
+       char *suffixSurface = FLUID_SUFFIX_SURFACE;
 
-       char *suffixConfig = "fluidsim.cfg";
-       char *suffixSurface = "fluidsurface";
-       char newSurfdataPath[FILE_MAXDIR+FILE_MAXFILE]; // modified output settings
        char targetDir[FILE_MAXDIR+FILE_MAXFILE];  // store & modify output settings
        char targetFile[FILE_MAXDIR+FILE_MAXFILE]; // temp. store filename from targetDir for access
        int  outStringsChanged = 0;             // modified? copy back before baking
-       int  haveSomeFluid = 0;                 // check if any fluid objects are set
 
-       // config vars, inited before either export or run...
-       double calcViscosity = 0.0;
-       int noFrames;
-       double aniFrameTime;
-       float aniFrlen;
-       int   channelObjCount;
-       float *bbStart = NULL;
-       float *bbSize = NULL;
        float domainMat[4][4];
        float invDomMat[4][4];
-       // channel data
-       int   allchannelSize; // fixed by no. of frames
-       int   startFrame = 1;  // dont use scene->r.sfra here, always start with frame 1
-       // easy frame -> sim time calc
-       float *timeAtFrame=NULL, *timeAtIndex=NULL;
-       // domain
-       float *channelDomainTime = NULL;
-       float *channelDomainViscosity = NULL; 
-       float *channelDomainGravity = NULL;
-       // objects (currently max. 256 objs)
-       float *channelObjMove[256][3]; // object movments , 0=trans, 1=rot, 2=scale
-       float *channelObjInivel[256];    // initial velocities
-       float *channelObjActive[256];    // obj active channel
-       
-       /* fluid control channels */
-       float *channelAttractforceStrength[256];
-       float *channelAttractforceRadius[256];
-       float *channelVelocityforceStrength[256];
-       float *channelVelocityforceRadius[256];
+
+       int noFrames;
+       int origFrame = scene->r.cfra;
+       
+       FluidAnimChannels *channels = MEM_callocN(sizeof(FluidAnimChannels), "fluid domain animation channels");
+       ListBase *fobjects = MEM_callocN(sizeof(ListBase), "fluid objects");
        FluidsimModifierData *fluidmd = NULL;
        Mesh *mesh = NULL;
        
+       wmJob *steve;
+       FluidBakeJob *fb;
+       elbeemSimulationSettings fsset;
+       
+       steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, 0);
+       fb= MEM_callocN(sizeof(FluidBakeJob), "fluid bake job");
+       
        if(getenv(strEnvName)) {
                int dlevel = atoi(getenv(strEnvName));
                elbeemSetDebugLevel(dlevel);
                snprintf(debugStrBuffer,256,"fluidsimBake::msg: Debug messages activated due to envvar '%s'\n",strEnvName); 
                elbeemDebugOut(debugStrBuffer);
        }
-       if(getenv(exportEnvStr)) {
-               doExportOnly = atoi(getenv(exportEnvStr));
-               snprintf(debugStrBuffer,256,"fluidsimBake::msg: Exporting mode set to '%d' due to envvar '%s'\n",doExportOnly, exportEnvStr); 
-               elbeemDebugOut(debugStrBuffer);
-       }
-
-       // make sure it corresponds to startFrame setting
-       // old: noFrames = scene->r.efra - scene->r.sfra +1;
+       
+       /* make sure it corresponds to startFrame setting (old: noFrames = scene->r.efra - scene->r.sfra +1) */;
        noFrames = scene->r.efra - 0;
        if(noFrames<=0) {
                BKE_report(reports, RPT_ERROR, "No frames to export - check your animation range settings.");
                return 0;
        }
-
-       /* no object pointer, find in selected ones.. */
-       if(!ob) {
-               for(base=scene->base.first; base; base= base->next) {
-                       if ((base)->flag & SELECT) 
-                       {
-                               FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
-                               
-                               if(fluidmdtmp && (base->object->type==OB_MESH)) 
-                               {
-                                       if(fluidmdtmp->fss->type == OB_FLUIDSIM_DOMAIN) 
-                                       {
-                                               ob = base->object;
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               // no domains found?
-               if(!ob) return 0;
-       }
        
-       channelObjCount = 0;
-       for(base=scene->base.first; base; base= base->next) 
-       {
-               FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
-               obit = base->object;
-               if( fluidmdtmp && 
-                       (obit->type==OB_MESH) &&
-                       (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) &&  // if has to match 3 places! // CHECKMATCH
-                       (fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE) ) 
-               {
-                       channelObjCount++;
-               }
-       }
-       
-       if (channelObjCount>=255) {
-               BKE_report(reports, RPT_ERROR, "Cannot bake with more then 256 objects.");
+       /* check scene for sane object/modifier settings */
+       if (!fluid_validate_scene(reports, scene, fsDomain)) {
                return 0;
        }
 
-       /* check if there's another domain... */
-       for(base=scene->base.first; base; base= base->next) 
-       {
-               FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
-               obit = base->object;
-               if( fluidmdtmp &&(obit->type==OB_MESH)) 
-               {
-                       if(fluidmdtmp->fss->type == OB_FLUIDSIM_DOMAIN) 
-                       {
-                               if(obit != ob) 
-                               {
-                                       BKE_report(reports, RPT_ERROR, "There should be only one domain object.");
-                                       return 0;
-                               }
-                       }
-               }
-       }
-       
-       // check if theres any fluid
-       // abort baking if not...
-       for(base=scene->base.first; base; base= base->next) 
-       {
-               FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
-               obit = base->object;
-               if( fluidmdtmp && 
-                       (obit->type==OB_MESH) && 
-                       ((fluidmdtmp->fss->type == OB_FLUIDSIM_FLUID) ||
-                       (fluidmdtmp->fss->type == OB_FLUIDSIM_INFLOW) ))
-               {
-                       haveSomeFluid = 1;
-                       break;
-               }
-       }
-       if(!haveSomeFluid) {
-               BKE_report(reports, RPT_ERROR, "No fluid objects in scene.");
-               return 0;
-       }
        
        /* these both have to be valid, otherwise we wouldnt be here */
-       /* dont use ob here after...*/
-       fsDomain = ob;
-       fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+       fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim);
        domainSettings = fluidmd->fss;
-       ob = NULL;
        mesh = fsDomain->data;
        
+       domainSettings->bakeStart = 1;
+       domainSettings->bakeEnd = scene->r.efra;
+       
        // calculate bounding box
        fluid_get_bb(mesh->mvert, mesh->totvert, fsDomain->obmat, domainSettings->bbStart, domainSettings->bbSize);
        
@@ -551,107 +862,26 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *ob)
        }
        snprintf(debugStrBuffer,256,"fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name , gridlevels ); 
        elbeemDebugOut(debugStrBuffer);
-
-       // prepare names...
-       strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
-       strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR);
-       BLI_path_abs(targetDir, G.sce); // fixed #frame-no 
-
-       strcpy(targetFile, targetDir);
-       strcat(targetFile, suffixConfig);
-       if(!doExportOnly) { strcat(targetFile,".tmp"); }  // dont overwrite/delete original file
-       // make sure all directories exist
-       // as the bobjs use the same dir, this only needs to be checked
-       // for the cfg output
-       BLI_make_existing_file(targetFile);
-
-       // check selected directory
-       // simply try to open cfg file for writing to test validity of settings
-       fileCfg = fopen(targetFile, "w");
-       if(fileCfg) { 
-               dirExist = 1; fclose(fileCfg); 
-               // remove cfg dummy from  directory test
-               if(!doExportOnly) { BLI_delete(targetFile, 0,0); }
-       }
-
-       if((strlen(targetDir)<1) || (!dirExist)) {
-               char blendDir[FILE_MAXDIR+FILE_MAXFILE], blendFile[FILE_MAXDIR+FILE_MAXFILE];
-               // invalid dir, reset to current/previous
-               strcpy(blendDir, G.sce);
-               BLI_splitdirstring(blendDir, blendFile);
-               if(strlen(blendFile)>6){
-                       int len = strlen(blendFile);
-                       if( (blendFile[len-6]=='.')&& (blendFile[len-5]=='b')&& (blendFile[len-4]=='l')&&
-                                       (blendFile[len-3]=='e')&& (blendFile[len-2]=='n')&& (blendFile[len-1]=='d') ){
-                               blendFile[len-6] = '\0';
-                       }
-               }
-               // todo... strip .blend ?
-               snprintf(newSurfdataPath,FILE_MAXFILE+FILE_MAXDIR,"//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name);
-
-               snprintf(debugStrBuffer,256,"fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath);
-               elbeemDebugOut(debugStrBuffer);
-               outStringsChanged=1;
-       }
-
-       // check if modified output dir is ok
-       if(outStringsChanged) {
-               char dispmsg[FILE_MAXDIR+FILE_MAXFILE+256];
-               int  selection=0;
-               strcpy(dispmsg,"Output settings set to: '");
-               strcat(dispmsg, newSurfdataPath);
-               strcat(dispmsg, "'%t|Continue with changed settings%x1|Discard and abort%x0");
-
-               // ask user if thats what he/she wants...
-               selection = pupmenu(dispmsg);
-               if(selection<1) return 0; // 0 from menu, or -1 aborted
-               strcpy(targetDir, newSurfdataPath);
-               strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR);
-               BLI_path_abs(targetDir, G.sce); // fixed #frame-no 
-       }
        
-       // --------------------------------------------------------------------------------------------
-       // dump data for start frame 
-       // CHECK more reasonable to number frames according to blender?
-       // dump data for frame 0
-       scene->r.cfra = startFrame;
-       ED_update_for_newframe(C, 1);
        
-       // init common export vars for both file export and run
-       for(i=0; i<256; i++) {
-               channelObjMove[i][0] = channelObjMove[i][1] = channelObjMove[i][2] = NULL;
-               channelObjInivel[i] = NULL;
-               channelObjActive[i] = NULL;
-               channelAttractforceStrength[i] = NULL;
-               channelAttractforceRadius[i] = NULL;
-               channelVelocityforceStrength[i] = NULL;
-               channelVelocityforceRadius[i] = NULL;
-       }
-       allchannelSize = scene->r.efra; // always use till last frame
-       aniFrameTime = (domainSettings->animEnd - domainSettings->animStart)/(double)noFrames;
-       // blender specific - scale according to map old/new settings in anim panel:
-       aniFrlen = scene->r.framelen;
-       if(domainSettings->viscosityMode==1) {
-               /* manual mode, visc=value/(10^-vexp) */
-               calcViscosity = (1.0/pow(10.0,domainSettings->viscosityExponent)) * domainSettings->viscosityValue;
-       } else {
-               calcViscosity = fluidsimViscosityPreset[ domainSettings->viscosityMode ];
-       }
-
-       bbStart = domainSettings->bbStart;
-       bbSize = domainSettings->bbSize;
+       
+       /* ******** prepare output file paths ******** */
+       outStringsChanged = fluid_init_filepaths(fsDomain, targetDir, targetFile, debugStrBuffer);
+       channels->length = scene->r.efra;
+       channels->aniFrameTime = (domainSettings->animEnd - domainSettings->animStart)/(double)noFrames;
+       
+       /* ******** initialise and allocate animation channels ******** */
+       fluid_init_all_channels(C, fsDomain, domainSettings, channels, fobjects);
 
-       // always init
+       /* reset to original current frame */
+       scene->r.cfra = origFrame;
+       ED_update_for_newframe(C, 1);
+       
+       
+       /* ---- XXX: No Time animation curve for now, leaving this code here for reference 
+        
        { int timeIcu[1] = { FLUIDSIM_TIME };
                float timeDef[1] = { 1. };
-               int gravIcu[3] = { FLUIDSIM_GRAV_X, FLUIDSIM_GRAV_Y, FLUIDSIM_GRAV_Z };
-               float gravDef[3];
-               int viscIcu[1] = { FLUIDSIM_VISC };
-               float viscDef[1] = { 1. };
-
-               gravDef[0] = domainSettings->gravx;
-               gravDef[1] = domainSettings->gravy;
-               gravDef[2] = domainSettings->gravz;
 
                // time channel is a bit special, init by hand...
                timeAtIndex = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatindex");
@@ -659,7 +889,7 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *ob)
                        timeAtIndex[i] = (float)(i-startFrame);
                }
                fluidsimInitChannel(scene, &channelDomainTime, allchannelSize, timeAtIndex, timeIcu,timeDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB
-               // time channel is a multiplicator for aniFrameTime
+               // time channel is a multiplicator for 
                if(channelDomainTime) {
                        for(i=0; i<allchannelSize; i++) { 
                                channelDomainTime[i*2+0] = aniFrameTime * channelDomainTime[i*2+0]; 
@@ -676,466 +906,117 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *ob)
                        for(i=2; i<=allchannelSize; i++) { timeAtFrame[i] = timeAtFrame[i-1]+aniFrameTime; }
                }
 
-               fluidsimInitChannel(scene, &channelDomainViscosity, allchannelSize, timeAtFrame, viscIcu,viscDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB
-               if(channelDomainViscosity) {
-                       for(i=0; i<allchannelSize; i++) { channelDomainViscosity[i*2+0] = calcViscosity * channelDomainViscosity[i*2+0]; }
-               }
-               fluidsimInitChannel(scene, &channelDomainGravity, allchannelSize, timeAtFrame, gravIcu,gravDef, domainSettings->ipo, CHANNEL_VEC );
        } // domain channel init
-       
-       // init obj movement channels
-       channelObjCount=0;
-       for(base=scene->base.first; base; base= base->next) 
-       {
-               FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
-               obit = base->object;
-               
-               if( fluidmdtmp && 
-                       (obit->type==OB_MESH) &&
-                       (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) &&  // if has to match 3 places! // CHECKMATCH
-                       (fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE) ) {
-
-                       //  cant use fluidsimInitChannel for obj channels right now, due
-                       //  to the special DXXX channels, and the rotation specialities
-                       IpoCurve *icuex[3][3];
-                       //IpoCurve *par_icuex[3][3];
-#if 0
-                       int icuIds[3][3] = { 
-                               {OB_LOC_X,  OB_LOC_Y,  OB_LOC_Z},
-                               {OB_ROT_X,  OB_ROT_Y,  OB_ROT_Z},
-                               {OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z} 
-                       };
-                       int icudIds[3][3] = { 
-                               {OB_DLOC_X,  OB_DLOC_Y,  OB_DLOC_Z},
-                               {OB_DROT_X,  OB_DROT_Y,  OB_DROT_Z},
-                               {OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z} 
-                       };
-#endif
-                       // relative ipos
-                       IpoCurve *icudex[3][3];
-                       //IpoCurve *par_icudex[3][3];
-                       int j,k;
-                       float vals[3] = {0.0,0.0,0.0}; 
-                       int o = channelObjCount;
-                       int   inivelIcu[3] =  { FLUIDSIM_VEL_X, FLUIDSIM_VEL_Y, FLUIDSIM_VEL_Z };
-                       float inivelDefs[3];
-                       int   activeIcu[1] =  { FLUIDSIM_ACTIVE };
-                       float activeDefs[1] = { 1 }; // default to on
-
-                       inivelDefs[0] = fluidmdtmp->fss->iniVelx;
-                       inivelDefs[1] = fluidmdtmp->fss->iniVely;
-                       inivelDefs[2] = fluidmdtmp->fss->iniVelz;
-
-                       // check & init loc,rot,size
-                       for(j=0; j<3; j++) {
-                               for(k=0; k<3; k++) {
-                                       // XXX prevent invalid memory access until this works
-                                       icuex[j][k]= NULL;
-                                       icudex[j][k]= NULL;
-
-                                       // XXX icuex[j][k]  = find_ipocurve(obit->ipo, icuIds[j][k] );
-                                       // XXX icudex[j][k] = find_ipocurve(obit->ipo, icudIds[j][k] );
-                                       // XXX lines below were already disabled!
-                                       //if(obit->parent) {
-                                               //par_icuex[j][k]  = find_ipocurve(obit->parent->ipo, icuIds[j][k] );
-                                               //par_icudex[j][k] = find_ipocurve(obit->parent->ipo, icudIds[j][k] );
-                                       //}
-                               }
-                       }
-
-                       for(j=0; j<3; j++) {
-                               channelObjMove[o][j] = MEM_callocN( allchannelSize*4*sizeof(float), "fluidsiminit_objmovchannel");
-                               for(i=1; i<=allchannelSize; i++) {
-
-                                       for(k=0; k<3; k++) {
-                                               if(icuex[j][k]) { 
-                                                       // IPO exists, use it ...
-                                                       // XXX calc_icu(icuex[j][k], aniFrlen*((float)i) );
-                                                       vals[k] = icuex[j][k]->curval; 
-                                                       if(obit->parent) {
-                                                               // add parent transform, multiply scaling, add trafo&rot
-                                                               //calc_icu(par_icuex[j][k], aniFrlen*((float)i) );
-                                                               //if(j==2) { vals[k] *= par_icuex[j][k]->curval; }
-                                                               //else { vals[k] += par_icuex[j][k]->curval; }
-                                                       }
-                                               } else {
-                                                       // use defaults from static values
-                                                       float setval=0.0;
-                                                       if(j==0) { 
-                                                               setval = obit->loc[k];
-                                                               if(obit->parent){ setval += obit->parent->loc[k]; }
-                                                       } else if(j==1) { 
-                                                               setval = ( 180.0*obit->rot[k] )/( 10.0*M_PI );
-                                                               if(obit->parent){ setval = ( 180.0*(obit->rot[k]+obit->parent->rot[k]) )/( 10.0*M_PI ); }
-                                                       } else { 
-                                                               setval = obit->size[k]; 
-                                                               if(obit->parent){ setval *= obit->parent->size[k]; }
-                                                       }
-                                                       vals[k] = setval;
-                                               }
-                                               if(icudex[j][k]) { 
-                                                       // XXX calc_icu(icudex[j][k], aniFrlen*((float)i) );
-                                                       //vals[k] += icudex[j][k]->curval; 
-                                                       // add transform, multiply scaling, add trafo&rot
-                                                       if(j==2) { vals[k] *= icudex[j][k]->curval; }
-                                                       else { vals[k] += icudex[j][k]->curval; }
-                                                       if(obit->parent) {
-                                                               // add parent transform, multiply scaling, add trafo&rot
-                                                               //calc_icu(par_icuex[j][k], aniFrlen*((float)i) );
-                                                               //if(j==2) { vals[k] *= par_icudex[j][k]->curval; }
-                                                               //else { vals[k] += par_icudex[j][k]->curval; }
-                                                       }
-                                               } 
-                                       } // k
-
-                                       for(k=0; k<3; k++) {
-                                               float set = vals[k];
-                                               if(j==1) { // rot is downscaled by 10 for ipo !?
-                                                       set = 360.0 - (10.0*set);
-                                               }
-                                               channelObjMove[o][j][(i-1)*4 + k] = set;
-                                       } // k
-                                       channelObjMove[o][j][(i-1)*4 + 3] = timeAtFrame[i];
-                               }
-                       }
-                       
-                       {
-                               int   attrFSIcu[1] =  { FLUIDSIM_ATTR_FORCE_STR };
-                               int   attrFRIcu[1] =  { FLUIDSIM_ATTR_FORCE_RADIUS };
-                               int   velFSIcu[1] =  { FLUIDSIM_VEL_FORCE_STR };
-                               int   velFRIcu[1] =  { FLUIDSIM_VEL_FORCE_RADIUS };
-
-                               float attrFSDefs[1];
-                               float attrFRDefs[1];
-                               float velFSDefs[1];
-                               float velFRDefs[1];
-                               
-                               attrFSDefs[0] = fluidmdtmp->fss->attractforceStrength;
-                               attrFRDefs[0] = fluidmdtmp->fss->attractforceRadius;
-                               velFSDefs[0] = fluidmdtmp->fss->velocityforceStrength;
-                               velFRDefs[0] = fluidmdtmp->fss->velocityforceRadius;
-                               
-                               fluidsimInitChannel(scene, &channelAttractforceStrength[o], allchannelSize, timeAtFrame, attrFSIcu,attrFSDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
-                               fluidsimInitChannel(scene, &channelAttractforceRadius[o], allchannelSize, timeAtFrame, attrFRIcu,attrFRDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
-                               fluidsimInitChannel(scene, &channelVelocityforceStrength[o], allchannelSize, timeAtFrame, velFSIcu,velFSDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
-                               fluidsimInitChannel(scene, &channelVelocityforceRadius[o], allchannelSize, timeAtFrame, velFRIcu,velFRDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
-                       }
-                       
-                       fluidsimInitChannel(scene, &channelObjInivel[o], allchannelSize, timeAtFrame, inivelIcu,inivelDefs, fluidmdtmp->fss->ipo, CHANNEL_VEC );
-                       fluidsimInitChannel(scene, &channelObjActive[o], allchannelSize, timeAtFrame, activeIcu,activeDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
+       */
                
-
-                       channelObjCount++;
-
-               }
-       }
-
-       // init trafo matrix
+       /* ******** init domain object's matrix ******** */
        copy_m4_m4(domainMat, fsDomain->obmat);
        if(!invert_m4_m4(invDomMat, domainMat)) {
                snprintf(debugStrBuffer,256,"fluidsimBake::error - Invalid obj matrix?\n"); 
                elbeemDebugOut(debugStrBuffer);
                BKE_report(reports, RPT_ERROR, "Invalid object matrix."); 
-               // FIXME add fatal msg
-               FS_FREE_CHANNELS;
+
+               free_domain_channels(channels);
+               MEM_freeN(channels);
+               
+               free_all_fluidobject_channels(fobjects);
+               BLI_freelistN(fobjects);
+               MEM_freeN(fobjects);
                return 0;
        }
 
-       // --------------------------------------------------------------------------------------------
-       // start writing / exporting
+       /* ********  start writing / exporting ******** */
        strcpy(targetFile, targetDir);
        strcat(targetFile, suffixConfig);
-       if(!doExportOnly) { strcat(targetFile,".tmp"); }  // dont overwrite/delete original file
+       strcat(targetFile,".tmp");  // dont overwrite/delete original file
+       
        // make sure these directories exist as well
        if(outStringsChanged) {
                BLI_make_existing_file(targetFile);
        }
 
-       if(!doExportOnly) {
-               ListBase threads;
-
-               // perform simulation with El'Beem api and threads
-               elbeemSimulationSettings fsset;
-               elbeemResetSettings(&fsset);
-               fsset.version = 1;
+       /* ******** export domain to elbeem ******** */
+       elbeemResetSettings(&fsset);
+       fsset.version = 1;
 
-               // setup global settings
-               for(i=0 ; i<3; i++) fsset.geoStart[i] = bbStart[i];
-               for(i=0 ; i<3; i++) fsset.geoSize[i] = bbSize[i];
-               
-               // simulate with 50^3
-               fsset.resolutionxyz = (int)domainSettings->resolutionxyz;
-               fsset.previewresxyz = (int)domainSettings->previewresxyz;
-               // 10cm water domain
-               fsset.realsize = domainSettings->realsize;
-               fsset.viscosity = calcViscosity;
-               // earth gravity
-               fsset.gravity[0] = domainSettings->gravx;
-               fsset.gravity[1] = domainSettings->gravy;
-               fsset.gravity[2] = domainSettings->gravz;
-               // simulate 5 frames, each 0.03 seconds, output to ./apitest_XXX.bobj.gz
-               fsset.animStart = domainSettings->animStart;
-               fsset.aniFrameTime = aniFrameTime;
-               fsset.noOfFrames = noFrames; // is otherwise subtracted in parser
-               strcpy(targetFile, targetDir);
-               strcat(targetFile, suffixSurface);
-               // defaults for compressibility and adaptive grids
-               fsset.gstar = domainSettings->gstar;
-               fsset.maxRefine = domainSettings->maxRefine; // check <-> gridlevels
-               fsset.generateParticles = domainSettings->generateParticles; 
-               fsset.numTracerParticles = domainSettings->generateTracers; 
-               fsset.surfaceSmoothing = domainSettings->surfaceSmoothing; 
-               fsset.surfaceSubdivs = domainSettings->surfaceSubdivs; 
-               fsset.farFieldSize = domainSettings->farFieldSize; 
-               strcpy( fsset.outputPath, targetFile);
-
-               // domain channels
-               fsset.channelSizeFrameTime = 
-               fsset.channelSizeViscosity = 
-               fsset.channelSizeGravity =  allchannelSize;
-               fsset.channelFrameTime = channelDomainTime;
-               fsset.channelViscosity = channelDomainViscosity;
-               fsset.channelGravity = channelDomainGravity;
-
-               fsset.runsimCallback = &runSimulationCallback;
-               fsset.runsimUserData = &fsset;
-
-               if(     (domainSettings->typeFlags&OB_FSBND_NOSLIP))   fsset.domainobsType = FLUIDSIM_OBSTACLE_NOSLIP;
-               else if((domainSettings->typeFlags&OB_FSBND_PARTSLIP)) fsset.domainobsType = FLUIDSIM_OBSTACLE_PARTSLIP;
-               else if((domainSettings->typeFlags&OB_FSBND_FREESLIP)) fsset.domainobsType = FLUIDSIM_OBSTACLE_FREESLIP;
-               fsset.domainobsPartslip = domainSettings->partSlipValue;
-               fsset.generateVertexVectors = (domainSettings->domainNovecgen==0);
-
-               // init blender trafo matrix
-                // fprintf(stderr,"elbeemInit - mpTrafo:\n");
-               { int j; 
-               for(i=0; i<4; i++) {
-                       for(j=0; j<4; j++) {
-                               fsset.surfaceTrafo[i*4+j] = invDomMat[j][i];
-                                // fprintf(stderr,"elbeemInit - mpTrafo %d %d = %f (%d) \n", i,j, fsset.surfaceTrafo[i*4+j] , (i*4+j) );
-                       }
-               } }
-
-         // init solver with settings
-               elbeemInit();
-               elbeemAddDomain(&fsset);
-               
-               // init objects
-               channelObjCount = 0;
-               for(base=scene->base.first; base; base= base->next) {
-                       FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
-                       obit = base->object;
-                       //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
-                       if( fluidmdtmp &&  // if has to match 3 places! // CHECKMATCH
-                               (obit->type==OB_MESH) &&
-                               (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) &&
-                               (fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE)) 
-                       {
-                               float *verts=NULL;
-                               int *tris=NULL;
-                               int numVerts=0, numTris=0;
-                               int o = channelObjCount;
-                               int     deform = (fluidmdtmp->fss->domainNovecgen); // misused value
-                               // todo - use blenderInitElbeemMesh
-                               int modifierIndex = modifiers_indexInObject(obit, (ModifierData *)fluidmdtmp);
-                               
-                               elbeemMesh fsmesh;
-                               elbeemResetMesh( &fsmesh );
-                               fsmesh.type = fluidmdtmp->fss->type;
-                               // get name of object for debugging solver
-                               fsmesh.name = obit->id.name; 
-
-                               initElbeemMesh(scene, obit, &numVerts, &verts, &numTris, &tris, 0, modifierIndex);
-                               fsmesh.numVertices   = numVerts;
-                               fsmesh.numTriangles  = numTris;
-                               fsmesh.vertices      = verts;
-                               fsmesh.triangles     = tris;
-
-                               fsmesh.channelSizeTranslation  = 
-                               fsmesh.channelSizeRotation     = 
-                               fsmesh.channelSizeScale        = 
-                               fsmesh.channelSizeInitialVel   = 
-                               fsmesh.channelSizeActive       = allchannelSize;
-
-                               fsmesh.channelTranslation      = channelObjMove[o][0];
-                               fsmesh.channelRotation         = channelObjMove[o][1];
-                               fsmesh.channelScale            = channelObjMove[o][2];
-                               fsmesh.channelActive           = channelObjActive[o];
-                               if( (fsmesh.type == OB_FLUIDSIM_FLUID) ||
-                               (fsmesh.type == OB_FLUIDSIM_INFLOW)) {
-                                       fsmesh.channelInitialVel       = channelObjInivel[o];
-                                       fsmesh.localInivelCoords = ((fluidmdtmp->fss->typeFlags&OB_FSINFLOW_LOCALCOORD)?1:0);
-                               } 
-
-                               if(     (fluidmdtmp->fss->typeFlags&OB_FSBND_NOSLIP))   fsmesh.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP;
-                               else if((fluidmdtmp->fss->typeFlags&OB_FSBND_PARTSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_PARTSLIP;
-                               else if((fluidmdtmp->fss->typeFlags&OB_FSBND_FREESLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_FREESLIP;
-                               fsmesh.obstaclePartslip = fluidmdtmp->fss->partSlipValue;
-                               fsmesh.volumeInitType = fluidmdtmp->fss->volumeInitType;
-                               fsmesh.obstacleImpactFactor = fluidmdtmp->fss->surfaceSmoothing; // misused value
-                               
-                               if(fsmesh.type == OB_FLUIDSIM_CONTROL)
-                               {
-                                       // control fluids will get exported as whole
-                                       deform = 1;
-                                       
-                                       fsmesh.cpsTimeStart = fluidmdtmp->fss->cpsTimeStart;
-                                       fsmesh.cpsTimeEnd = fluidmdtmp->fss->cpsTimeEnd;
-                                       fsmesh.cpsQuality = fluidmdtmp->fss->cpsQuality;
-                                       fsmesh.obstacleType = (fluidmdtmp->fss->flag & OB_FLUIDSIM_REVERSE);
-                                       
-                                       fsmesh.channelSizeAttractforceRadius = 
-                                       fsmesh.channelSizeVelocityforceStrength = 
-                                       fsmesh.channelSizeVelocityforceRadius = 
-                                       fsmesh.channelSizeAttractforceStrength = allchannelSize;
-                                       
-                                       fsmesh.channelAttractforceStrength = channelAttractforceStrength[o];
-                                       fsmesh.channelAttractforceRadius = channelAttractforceRadius[o];
-                                       fsmesh.channelVelocityforceStrength = channelVelocityforceStrength[o];
-                                       fsmesh.channelVelocityforceRadius = channelVelocityforceRadius[o];
-                               }
-                               else 
-                               {
-                                       // set channels to 0
-                                       fsmesh.channelAttractforceStrength =
-                                       fsmesh.channelAttractforceRadius = 
-                                       fsmesh.channelVelocityforceStrength = 
-                                       fsmesh.channelVelocityforceRadius = NULL; 
-                               }
-
-                               // animated meshes
-                               if(deform) {
-                                       fsmesh.channelSizeVertices = allchannelSize;
-                                       fluidsimInitMeshChannel(C, &fsmesh.channelVertices, allchannelSize, obit, numVerts, timeAtFrame, modifierIndex);
-                                       scene->r.cfra = startFrame;
-                                       ED_update_for_newframe(C, 1);
-                                       // remove channels
-                                       fsmesh.channelTranslation      = 
-                                       fsmesh.channelRotation         = 
-                                       fsmesh.channelScale            = NULL; 
-                               } 
-
-                               elbeemAddMesh(&fsmesh);
-
-                               if(verts) MEM_freeN(verts);
-                               if(tris) MEM_freeN(tris);
-                               if(fsmesh.channelVertices) MEM_freeN(fsmesh.channelVertices);
-                               channelObjCount++;
-                       } // valid mesh
-               } // objects
-               //domainSettings->type = OB_FLUIDSIM_DOMAIN; // enable for bake display again
-               
-               // set to neutral, -1 means user abort, -2 means init error
-               globalBakeState = 0;
-               globalBakeFrame = 0;
-               
-               BLI_init_threads(&threads, fluidsimSimulateThread, 1);
-               BLI_insert_thread(&threads, targetFile);
-               
-               {
-                       int done = 0;
-                       float noFramesf = (float)noFrames;
-                       float percentdone = 0.0, oldpercentdone = -1.0;
-                       int lastRedraw = -1;
-                       
-                       g_break= 0;
-                       G.afbreek= 0;   /* blender_test_break uses this global */
-                       
-                       start_progress_bar();
-
-                       while(done==0) {
-                               char busy_mess[80];
-                               
-                               waitcursor(1);
-                               
-                               // lukep we add progress bar as an interim mesure
-                               percentdone = globalBakeFrame / noFramesf;
-                               if (percentdone != oldpercentdone) {
-                                       sprintf(busy_mess, "baking fluids %d / %d       |||", globalBakeFrame, (int) noFramesf);
-                                       percentdone = percentdone < 0.0 ? 0.0:percentdone;
-                                       progress_bar(CTX_wm_window(C), percentdone, busy_mess );
-                                       oldpercentdone = percentdone;
-                               }
-                               
-                               //XXX no more need for longer delay to prevent frequent redrawing
-                               PIL_sleep_ms(200);
-                               
-                               BLI_lock_thread(LOCK_CUSTOM1);
-                               if(globalBakeState != 0) done = 1; // 1=ok, <0=error/abort
-                               BLI_unlock_thread(LOCK_CUSTOM1);
-
-                               if (!G.background) {
-                                       g_break= blender_test_break();
-                                       
-                                       if(g_break)
-                                       {
-                                               // abort...
-                                               BLI_lock_thread(LOCK_CUSTOM1);
-                                               
-                                               if(domainSettings)
-                                                       domainSettings->lastgoodframe = startFrame+globalBakeFrame;
-                                               
-                                               done = -1;
-                                               globalBakeFrame = 0;
-                                               globalBakeState = -1;
-                                               simAborted = 1;
-                                               BLI_unlock_thread(LOCK_CUSTOM1);
-                                               break;
-                                       }
-                               } 
-
-                               // redraw the 3D for showing progress once in a while...
-                               if(lastRedraw!=globalBakeFrame) {
-#if 0                                  
-                                       ScrArea *sa;
-                                       scene->r.cfra = startFrame+globalBakeFrame;
-                                       lastRedraw = globalBakeFrame;
-                                       ED_update_for_newframe(C, 1);
-                                       sa= G.curscreen->areabase.first;
-                                       while(sa) {
-                                               if(sa->spacetype == SPACE_VIEW3D) { scrarea_do_windraw(sa); }
-                                               sa= sa->next;   
-                                       } 
-                                       screen_swapbuffers();
-#endif
-                               } // redraw
-                       }
-                       end_progress_bar(CTX_wm_window(C));
+       // setup global settings
+       copy_v3_v3(fsset.geoStart, domainSettings->bbStart);
+       copy_v3_v3(fsset.geoSize, domainSettings->bbSize);
+       
+       // simulate with 50^3
+       fsset.resolutionxyz = (int)domainSettings->resolutionxyz;
+       fsset.previewresxyz = (int)domainSettings->previewresxyz;
+
+       fsset.realsize = get_fluid_size_m(scene, fsDomain, domainSettings);
+       fsset.viscosity = get_fluid_viscosity(domainSettings);
+       get_fluid_gravity(fsset.gravity, scene, domainSettings);
+
+       // simulate 5 frames, each 0.03 seconds, output to ./apitest_XXX.bobj.gz
+       fsset.animStart = domainSettings->animStart;
+       fsset.aniFrameTime = channels->aniFrameTime;
+       fsset.noOfFrames = noFrames; // is otherwise subtracted in parser
+       strcpy(targetFile, targetDir);
+       strcat(targetFile, suffixSurface);
+       // defaults for compressibility and adaptive grids
+       fsset.gstar = domainSettings->gstar;
+       fsset.maxRefine = domainSettings->maxRefine; // check <-> gridlevels
+       fsset.generateParticles = domainSettings->generateParticles; 
+       fsset.numTracerParticles = domainSettings->generateTracers; 
+       fsset.surfaceSmoothing = domainSettings->surfaceSmoothing; 
+       fsset.surfaceSubdivs = domainSettings->surfaceSubdivs; 
+       fsset.farFieldSize = domainSettings->farFieldSize; 
+       strcpy( fsset.outputPath, targetFile);
+
+       // domain channels
+       fsset.channelSizeFrameTime = 
+       fsset.channelSizeViscosity = 
+       fsset.channelSizeGravity = channels->length;
+       fsset.channelFrameTime = channels->DomainTime;
+       fsset.channelViscosity = channels->DomainViscosity;
+       fsset.channelGravity = channels->DomainGravity;
+       
+       fsset.runsimCallback = &runSimulationCallback;
+       fsset.runsimUserData = fb;
+
+       if (domainSettings->typeFlags & OB_FSBND_NOSLIP)                fsset.domainobsType = FLUIDSIM_OBSTACLE_NOSLIP;
+       else if (domainSettings->typeFlags&OB_FSBND_PARTSLIP)   fsset.domainobsType = FLUIDSIM_OBSTACLE_PARTSLIP;
+       else if (domainSettings->typeFlags&OB_FSBND_FREESLIP)   fsset.domainobsType = FLUIDSIM_OBSTACLE_FREESLIP;
+       fsset.domainobsPartslip = domainSettings->partSlipValue;
+       fsset.generateVertexVectors = (domainSettings->domainNovecgen==0);
+
+       // init blender domain transform matrix
+       { int j; 
+       for(i=0; i<4; i++) {
+               for(j=0; j<4; j++) {
+                       fsset.surfaceTrafo[i*4+j] = invDomMat[j][i];
                }
-               BLI_end_threads(&threads);
-       } // El'Beem API init, thread creation 
-       // --------------------------------------------------------------------------------------------
-       else
-       { // write config file to be run with command line simulator
-               BKE_report(reports, RPT_WARNING, "Config file export not supported.");
-       } // config file export done!
-
-       // --------------------------------------------------------------------------------------------
-       FS_FREE_CHANNELS;
+       } }
 
-       // go back to "current" blender time
-       waitcursor(0);
+       /* ******** init solver with settings ******** */
+       elbeemInit();
+       elbeemAddDomain(&fsset);
        
-       if(globalBakeState >= 0)
-       {
-               if(domainSettings)
-                       domainSettings->lastgoodframe = startFrame+globalBakeFrame;
-       }
+       /* ******** export all fluid objects to elbeem ******** */
+       export_fluid_objects(fobjects, scene, channels->length);
        
-       scene->r.cfra = origFrame;
-       ED_update_for_newframe(C, 1);
-
-       if(!simAborted) {
-               char elbeemerr[256];
+       /* custom data for fluid bake job */
+       fb->settings = &fsset;
+       
+       /* setup job */
+       WM_jobs_customdata(steve, fb, fluidbake_free);
+       WM_jobs_timer(steve, 0.1, NC_SCENE|ND_FRAME, NC_SCENE|ND_FRAME);
+       WM_jobs_callbacks(steve, fluidbake_startjob, NULL, NULL);
+       
+       WM_jobs_start(CTX_wm_manager(C), steve);
 
-               // check if some error occurred
-               if(globalBakeState==-2) {
-                       elbeemGetErrorString(elbeemerr);
-                       BKE_reportf(reports, RPT_ERROR, "Failed to initialize [Msg: %s]", elbeemerr);
-                       return 0;
-               } // init error
-       }
+       /* ******** free stored animation data ******** */
+       free_domain_channels(channels);
+       MEM_freeN(channels);
        
+       free_all_fluidobject_channels(fobjects);
+       BLI_freelistN(fobjects);
+       MEM_freeN(fobjects);
+
        // elbeemFree();
        return 1;
 }
@@ -1181,7 +1062,6 @@ static int fluid_bake_exec(bContext *C, wmOperator *op)
 {
        Object *ob= CTX_data_active_object(C);
 
-       // XXX TODO redraw, escape, non-blocking, ..
        if(!fluidsimBake(C, op->reports, ob))
                return OPERATOR_CANCELLED;
 
index 370076b5b07ee625a67b3d0e53c9d549b350c321..fa9308111b0f0e238f3981fd76413abaf828f5c6 100644 (file)
@@ -258,6 +258,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
                                        buttons_area_redraw(sa, BCONTEXT_TEXTURE);
                                        buttons_area_redraw(sa, BCONTEXT_WORLD);
                                        buttons_area_redraw(sa, BCONTEXT_DATA);
+                                       buttons_area_redraw(sa, BCONTEXT_PHYSICS);
                                        sbuts->preview= 1;
                                        break;
                                case ND_OB_ACTIVE:
index fa918fc30d9254c1cabe5a94ba1ac75c1317bf7f..700021eaceb17eb29de153c5d2beb05c794a2c6c 100644 (file)
@@ -63,8 +63,10 @@ typedef struct FluidsimSettings {
        short viscosityExponent;
        /* gravity strength */
        float gravx,gravy,gravz;
-       /* anim start end time */
+       /* anim start end time (in seconds) */
        float animStart, animEnd;
+       /* bake start end time (in blender frames) */
+       int bakeStart, bakeEnd;
        /* g star param (LBM compressibility) */
        float gstar;
        /* activate refinement? */
@@ -160,8 +162,10 @@ typedef struct FluidsimSettings {
 #define OB_FSPART_FLOAT   (1<<4)
 #define OB_FSPART_TRACER  (1<<5)
 
-// new fluid bit flags for fss->flags - dg
-#define OB_FLUIDSIM_REVERSE (1 << 0)
+// new fluid bit flags for fss->flags
+#define OB_FLUIDSIM_REVERSE                    (1 << 0)
+#define OB_FLUIDSIM_ACTIVE                     (1 << 1)
+#define OB_FLUIDSIM_OVERRIDE_TIME      (1 << 2)
 
 #ifdef __cplusplus
 }
index 0156387706881424c32fbe21353a76e5e0e9d8de..0782ee4fb841247f70e7fd1a372382ac10b044f7 100644 (file)
@@ -172,6 +172,7 @@ static void rna_def_fluidsim_slip(StructRNA *srna)
 
        prop= RNA_def_property(srna, "slip_type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_bitflag_sdna(prop, NULL, "typeFlags");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_enum_items(prop, slip_items);
        RNA_def_property_ui_text(prop, "Slip Type", "");
 
@@ -215,16 +216,6 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
        RNA_def_property_range(prop, 1, 100);
        RNA_def_property_ui_text(prop, "Preview Resolution", "Preview resolution in X,Y and Z direction");
 
-       prop= RNA_def_property(srna, "start_time", PROP_FLOAT, PROP_TIME);
-       RNA_def_property_float_sdna(prop, NULL, "animStart");
-       RNA_def_property_range(prop, 0, 100);
-       RNA_def_property_ui_text(prop, "Start Time", "Simulation time of the first blender frame");
-
-       prop= RNA_def_property(srna, "end_time", PROP_FLOAT, PROP_TIME);
-       RNA_def_property_float_sdna(prop, NULL, "animEnd");
-       RNA_def_property_range(prop, 0, 100);
-       RNA_def_property_ui_text(prop, "End Time", "Simulation time of the last blender frame");
-
        prop= RNA_def_property(srna, "viewport_display_mode", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "guiDisplayMode");
        RNA_def_property_enum_items(prop, quality_items);
@@ -252,13 +243,31 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Memory Estimate", "Estimated amount of memory needed for baking the domain");
 
        /* advanced settings */
-
        prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION);
        RNA_def_property_float_sdna(prop, NULL, "gravx");
        RNA_def_property_array(prop, 3);
        RNA_def_property_range(prop, -1000.1, 1000.1);
        RNA_def_property_ui_text(prop, "Gravity", "Gravity in X, Y and Z direction");
-
+       
+       prop= RNA_def_property(srna, "override_time", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", OB_FLUIDSIM_OVERRIDE_TIME);
+       RNA_def_property_ui_text(prop, "Override Time", "Use a custom start and end time (in seconds) instead of the scene's timeline");
+       
+       prop= RNA_def_property(srna, "start_time", PROP_FLOAT, PROP_TIME);
+       RNA_def_property_float_sdna(prop, NULL, "animStart");
+       RNA_def_property_range(prop, 0, 100);
+       RNA_def_property_ui_text(prop, "Start Time", "Simulation time of the first blender frame");
+       
+       prop= RNA_def_property(srna, "end_time", PROP_FLOAT, PROP_TIME);
+       RNA_def_property_float_sdna(prop, NULL, "animEnd");
+       RNA_def_property_range(prop, 0, 100);
+       RNA_def_property_ui_text(prop, "End Time", "Simulation time of the last blender frame");
+       
+       prop= RNA_def_property(srna, "real_world_size", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "realsize");
+       RNA_def_property_range(prop, 0.001, 10);
+       RNA_def_property_ui_text(prop, "Real World Size", "Size of the simulation domain in metres");
+       
        prop= RNA_def_property(srna, "viscosity_preset", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "viscosityMode");
        RNA_def_property_enum_items(prop, viscosity_items);
@@ -274,18 +283,15 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
        RNA_def_property_range(prop, 0, 10);
        RNA_def_property_ui_text(prop, "Viscosity Exponent", "Negative exponent for the viscosity value (to simplify entering small values e.g. 5*10^-6.)");
 
-       prop= RNA_def_property(srna, "real_world_size", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "realsize");
-       RNA_def_property_range(prop, 0.001, 10);
-       RNA_def_property_ui_text(prop, "Real World Size", "Size of the simulation domain in metres");
-
        prop= RNA_def_property(srna, "grid_levels", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "maxRefine");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_range(prop, -1, 4);
        RNA_def_property_ui_text(prop, "Grid Levels", "Number of coarsened grids to use (-1 for automatic)");
 
        prop= RNA_def_property(srna, "compressibility", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "gstar");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_range(prop, 0.001, 0.1);
        RNA_def_property_ui_text(prop, "Compressibility", "Allowed compressibility due to gravitational force for standing fluid. (directly affects simulation step size)");
 
@@ -295,27 +301,32 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "surface_smoothing", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "surfaceSmoothing");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_range(prop, 0.0, 5.0);
        RNA_def_property_ui_text(prop, "Surface Smoothing", "Amount of surface smoothing. A value of 0 is off, 1 is normal smoothing and more than 1 is extra smoothing");
 
        prop= RNA_def_property(srna, "surface_subdivisions", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "surfaceSubdivs");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_range(prop, 0, 5);
        RNA_def_property_ui_text(prop, "Surface Subdivisions", "Number of isosurface subdivisions. This is necessary for the inclusion of particles into the surface generation. Warning - can lead to longer computation times!");
 
        prop= RNA_def_property(srna, "generate_speed_vectors", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_negative_sdna(prop, NULL, "domainNovecgen", 0);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_ui_text(prop, "Generate Speed Vectors", "Generate speed vectors for vector blur");
 
        /* particles */
 
        prop= RNA_def_property(srna, "tracer_particles", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "generateTracers");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_range(prop, 0, 10000);
        RNA_def_property_ui_text(prop, "Tracer Particles", "Number of tracer particles to generate");
 
        prop= RNA_def_property(srna, "generate_particles", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "generateParticles");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_range(prop, 0.0, 10.0);
        RNA_def_property_ui_text(prop, "Generate Particles", "Amount of particles to generate (0=off, 1=normal, >1=more)");
 }
@@ -332,14 +343,25 @@ static void rna_def_fluidsim_volume(StructRNA *srna)
 
        prop= RNA_def_property(srna, "volume_initialization", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_bitflag_sdna(prop, NULL, "volumeInitType");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_enum_items(prop, volume_type_items);
        RNA_def_property_ui_text(prop, "Volume Initialization", "Volume initialization type");
 
        prop= RNA_def_property(srna, "export_animated_mesh", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "domainNovecgen", 0);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_ui_text(prop, "Export Animated Mesh", "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated pos/rot/scale IPOs do not require it");
 }
 
+static void rna_def_fluidsim_active(StructRNA *srna)
+{
+       PropertyRNA *prop;
+       
+       prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", OB_FLUIDSIM_ACTIVE);
+       RNA_def_property_ui_text(prop, "Active", "Object contributes to the fluid simulation");
+}
+
 static void rna_def_fluidsim_fluid(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -349,8 +371,9 @@ static void rna_def_fluidsim_fluid(BlenderRNA *brna)
        RNA_def_struct_sdna(srna, "FluidsimSettings");
        RNA_def_struct_ui_text(srna, "Fluid Fluid Simulation Settings", "Fluid simulation settings for the fluid in the simulation");
 
+       rna_def_fluidsim_active(srna);
        rna_def_fluidsim_volume(srna);
-
+       
        prop= RNA_def_property(srna, "initial_velocity", PROP_FLOAT, PROP_VELOCITY);
        RNA_def_property_float_sdna(prop, NULL, "iniVelx");
        RNA_def_property_array(prop, 3);
@@ -363,15 +386,17 @@ static void rna_def_fluidsim_obstacle(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
-          srna= RNA_def_struct(brna, "ObstacleFluidSettings", "FluidSettings");
+       srna= RNA_def_struct(brna, "ObstacleFluidSettings", "FluidSettings");
        RNA_def_struct_sdna(srna, "FluidsimSettings");
        RNA_def_struct_ui_text(srna, "Obstacle Fluid Simulation Settings", "Fluid simulation settings for obstacles in the simulation");
 
+       rna_def_fluidsim_active(srna);
        rna_def_fluidsim_volume(srna);
        rna_def_fluidsim_slip(srna);
 
        prop= RNA_def_property(srna, "impact_factor", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "surfaceSmoothing");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_range(prop, -2.0, 10.0);
        RNA_def_property_ui_text(prop, "Impact Factor", "This is an unphysical value for moving objects - it controls the impact an obstacle has on the fluid, =0 behaves a bit like outflow (deleting fluid), =1 is default, while >1 results in high forces. Can be used to tweak total mass");
 }
@@ -381,10 +406,11 @@ static void rna_def_fluidsim_inflow(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
-          srna= RNA_def_struct(brna, "InflowFluidSettings", "FluidSettings");
+       srna= RNA_def_struct(brna, "InflowFluidSettings", "FluidSettings");
        RNA_def_struct_sdna(srna, "FluidsimSettings");
        RNA_def_struct_ui_text(srna, "Inflow Fluid Simulation Settings", "Fluid simulation settings for objects adding fluids in the simulation");
 
+       rna_def_fluidsim_active(srna);
        rna_def_fluidsim_volume(srna);
 
        prop= RNA_def_property(srna, "inflow_velocity", PROP_FLOAT, PROP_VELOCITY);
@@ -394,6 +420,7 @@ static void rna_def_fluidsim_inflow(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Inflow Velocity", "Initial velocity of fluid");
 
        prop= RNA_def_property(srna, "local_coordinates", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_boolean_sdna(prop, NULL, "typeFlags", OB_FSINFLOW_LOCALCOORD);
        RNA_def_property_ui_text(prop, "Local Coordinates", "Use local coordinates for inflow. (e.g. for rotating objects)");
 }
@@ -402,10 +429,11 @@ static void rna_def_fluidsim_outflow(BlenderRNA *brna)
 {
        StructRNA *srna;
 
-          srna= RNA_def_struct(brna, "OutflowFluidSettings", "FluidSettings");
+       srna= RNA_def_struct(brna, "OutflowFluidSettings", "FluidSettings");
        RNA_def_struct_sdna(srna, "FluidsimSettings");
        RNA_def_struct_ui_text(srna, "Outflow Fluid Simulation Settings", "Fluid simulation settings for objects removing fluids from the simulation");
 
+       rna_def_fluidsim_active(srna);
        rna_def_fluidsim_volume(srna);
 }
 
@@ -414,7 +442,7 @@ static void rna_def_fluidsim_particle(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
-          srna= RNA_def_struct(brna, "ParticleFluidSettings", "FluidSettings");
+       srna= RNA_def_struct(brna, "ParticleFluidSettings", "FluidSettings");
        RNA_def_struct_sdna(srna, "FluidsimSettings");
        RNA_def_struct_ui_text(srna, "Particle Fluid Simulation Settings", "Fluid simulation settings for objects storing fluid particles generated by the simulation");
 
@@ -452,10 +480,12 @@ static void rna_def_fluidsim_control(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
-          srna= RNA_def_struct(brna, "ControlFluidSettings", "FluidSettings");
+       srna= RNA_def_struct(brna, "ControlFluidSettings", "FluidSettings");
        RNA_def_struct_sdna(srna, "FluidsimSettings");
        RNA_def_struct_ui_text(srna, "Control Fluid Simulation Settings", "Fluid simulation settings for objects controlling the motion of fluid in the simulation");
 
+       rna_def_fluidsim_active(srna);
+       
        prop= RNA_def_property(srna, "start_time", PROP_FLOAT, PROP_TIME);
        RNA_def_property_float_sdna(prop, NULL, "cpsTimeStart");
        RNA_def_property_range(prop, 0.0, 100.0);
@@ -488,11 +518,13 @@ static void rna_def_fluidsim_control(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "quality", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "cpsQuality");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_range(prop, 5.0, 100.0);
        RNA_def_property_ui_text(prop, "Quality", "Specifies the quality which is used for object sampling. (higher = better but slower)");
 
        prop= RNA_def_property(srna, "reverse_frames", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", OB_FLUIDSIM_REVERSE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_ui_text(prop, "Reverse Frames", "Reverse control object movement");
 }
 
@@ -522,6 +554,7 @@ void RNA_def_fluidsim(BlenderRNA *brna)
        prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_bitflag_sdna(prop, NULL, "type");
        RNA_def_property_enum_items(prop, prop_fluid_type_items);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_ui_text(prop, "Type", "Type of participation in the fluid simulation");
        RNA_def_property_update(prop, 0, "rna_FluidSettings_update_type");
 
index 86767342586152a5ebf3420bfd6f7cf0d9ace4e4..3823af25619e0f4c7516ae0424b822845d087889 100644 (file)
@@ -579,41 +579,13 @@ static void rna_Object_rotation_mode_set(PointerRNA *ptr, int value)
 static void rna_Object_dimensions_get(PointerRNA *ptr, float *value)
 {
        Object *ob= ptr->data;
-       BoundBox *bb = NULL;
-       
-       bb= object_get_boundbox(ob);
-       if (bb) {
-               float scale[3];
-               
-               mat4_to_size( scale,ob->obmat);
-               
-               value[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
-               value[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
-               value[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
-       } else {
-               value[0] = value[1] = value[2] = 0.f;
-       }
+       object_get_dimensions(ob, value);
 }
 
 static void rna_Object_dimensions_set(PointerRNA *ptr, const float *value)
 {
        Object *ob= ptr->data;
-       BoundBox *bb = NULL;
-       
-       bb= object_get_boundbox(ob);
-       if (bb) {
-               float scale[3], len[3];
-               
-               mat4_to_size( scale,ob->obmat);
-               
-               len[0] = bb->vec[4][0] - bb->vec[0][0];
-               len[1] = bb->vec[2][1] - bb->vec[0][1];
-               len[2] = bb->vec[1][2] - bb->vec[0][2];
-               
-               if (len[0] > 0.f) ob->size[0] = value[0] / len[0];
-               if (len[1] > 0.f) ob->size[1] = value[1] / len[1];
-               if (len[2] > 0.f) ob->size[2] = value[2] / len[2];
-       }
+       object_set_dimensions(ob, value);
 }
 
 static int rna_Object_location_editable(PointerRNA *ptr, int index)