* Enabled rna access to fluid sim velocity vectors
authorMatt Ebb <matt@mke3.net>
Thu, 12 May 2011 22:52:30 +0000 (22:52 +0000)
committerMatt Ebb <matt@mke3.net>
Thu, 12 May 2011 22:52:30 +0000 (22:52 +0000)
The main purpose for this is to allow rendering motion blurred blender fluids in external renderers (eg. http://vimeo.com/21870635 ).

Python code snippet for interpreting this data here: http://www.pasteall.org/21577 . Cleaned up some ugly hacks in this area too

* Also added read-only access to scene.subframe to RNA - setting current frame and subframe should still go via scene.frame_set()

source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_object_fluidsim.h
source/blender/makesrna/intern/rna_fluidsim.c
source/blender/makesrna/intern/rna_scene.c
source/blender/modifiers/intern/MOD_fluidsim_util.c
source/blender/render/intern/source/convertblender.c

index afa571769ab1f900ea1299d46aae02efa190ba7f..5543e8420078c569c1044b85cf3099127418205f 100644 (file)
@@ -3967,7 +3967,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        
                        fluidmd->fss= newdataadr(fd, fluidmd->fss);
                        fluidmd->fss->fmd= fluidmd;
-                       fluidmd->fss->meshSurfNormals = NULL;
+                       fluidmd->fss->meshVelocities = NULL;
                }
                else if (md->type==eModifierType_Smoke) {
                        SmokeModifierData *smd = (SmokeModifierData*) md;
@@ -9623,7 +9623,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                
                                fluidmd->fss->lastgoodframe = INT_MAX;
                                fluidmd->fss->flag = 0;
-                               fluidmd->fss->meshSurfNormals = NULL;
+                               fluidmd->fss->meshVelocities = NULL;
                        }
                }
        }
index e8360b99d69fe0cd2f3e970f8228a50ecb908660..6f4c16cb7f34b254fbb7cfede073a96d04438ca7 100644 (file)
@@ -42,7 +42,10 @@ extern "C" {
        
 struct Mesh;
 struct Ipo;
-struct MVert;
+
+typedef struct FluidVertexVelocity {
+       float vel[3];
+} FluidVertexVelocity;
        
 typedef struct FluidsimSettings {
        struct FluidsimModifierData *fmd; /* for fast RNA access */
@@ -82,8 +85,6 @@ typedef struct FluidsimSettings {
 
        /* store pointer to original mesh (for replacing the current one) */
        struct Mesh *orgMesh;
-       /* pointer to the currently loaded fluidsim mesh */
-       struct Mesh *meshSurface;
        /* a mesh to display the bounding box used for simulation */
        struct Mesh *meshBB;
 
@@ -122,8 +123,10 @@ typedef struct FluidsimSettings {
        /* testing vars */
        float farFieldSize;
 
-       /* save fluidsurface normals in mvert.no, and surface vertex velocities (if available) in mvert.co */
-       struct MVert *meshSurfNormals;
+       /* vertex velocities of simulated fluid mesh */
+       struct FluidVertexVelocity *meshVelocities;
+       /* number of vertices in simulated fluid mesh */
+       int totvert;
        
        /* Fluid control settings */
        float cpsTimeStart;
@@ -136,6 +139,8 @@ typedef struct FluidsimSettings {
        float velocityforceRadius;
 
        int lastgoodframe;
+       
+       int pad;
 
 } FluidsimSettings;
 
index acec2ca7a24806552e94c1d618a93e71cacd799b..7c93ae4168bef222dfe28403f8caba1644ecd48f 100644 (file)
@@ -195,6 +195,18 @@ static char *rna_FluidSettings_path(PointerRNA *ptr)
        return BLI_sprintfN("modifiers[\"%s\"].settings", md->name);
 }
 
+static void rna_FluidMeshVertex_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+       FluidsimSettings *fss = (FluidsimSettings*)ptr->data;
+       rna_iterator_array_begin(iter, fss->meshVelocities, sizeof(float)*3, fss->totvert, 0, NULL);
+}
+
+static int rna_FluidMeshVertex_data_length(PointerRNA *ptr)
+{
+       FluidsimSettings *fss = (FluidsimSettings*)ptr->data;
+       return fss->totvert;
+}
+
 #else
 
 static void rna_def_fluidsim_slip(StructRNA *srna)
@@ -219,6 +231,24 @@ static void rna_def_fluidsim_slip(StructRNA *srna)
        RNA_def_property_ui_text(prop, "Partial Slip Amount", "Amount of mixing between no- and free-slip, 0 is no slip and 1 is free slip");
 }
 
+static void rna_def_fluid_mesh_vertices(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+       
+       srna= RNA_def_struct(brna, "FluidMeshVertex", NULL);
+       RNA_def_struct_sdna(srna, "FluidVertexVelocity");
+       RNA_def_struct_ui_text(srna, "Fluid Mesh Vertex", "Vertex of a simulated fluid mesh");
+       RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL);
+
+       prop= RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VELOCITY);
+       RNA_def_property_array(prop, 3);
+       RNA_def_property_float_sdna(prop, NULL, "vel");
+       RNA_def_property_ui_text(prop, "Velocity", "");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+}
+
+
 static void rna_def_fluidsim_domain(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -367,6 +397,13 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
        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)");
+       
+       /* simulated fluid mesh data */
+       prop= RNA_def_property(srna, "fluid_mesh_vertices", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_struct_type(prop, "FluidMeshVertex");
+       RNA_def_property_ui_text(prop, "Fluid Mesh Vertices", "Vertices of the fluid mesh generated by simulation");
+       RNA_def_property_collection_funcs(prop, "rna_FluidMeshVertex_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_FluidMeshVertex_data_length", 0, 0);
+       rna_def_fluid_mesh_vertices(brna);
 }
 
 static void rna_def_fluidsim_volume(StructRNA *srna)
index 8bbde89475a1bf86ae5856efd8db793f352006c4..de724cc2252b1f0bfb2878e5350c66a33a00ac15 100644 (file)
@@ -3226,6 +3226,11 @@ void RNA_def_scene(BlenderRNA *brna)
        RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
        RNA_def_property_update(prop, NC_SCENE|ND_FRAME, "rna_Scene_frame_update");
        
+       prop= RNA_def_property(srna, "frame_subframe", PROP_FLOAT, PROP_TIME);
+       RNA_def_property_float_sdna(prop, NULL, "r.subframe");
+       RNA_def_property_ui_text(prop, "Current Sub-Frame", "");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE|PROP_EDITABLE);
+       
        prop= RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_int_sdna(prop, NULL, "r.sfra");
index 02912e38204ba9908e2fae613fafd6c0dc1a9908..61345427d1c9b2f3eca7c770a92486ad3332215e 100644 (file)
@@ -139,8 +139,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
                fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize); 
                */
                
-               // (ab)used to store velocities
-               fss->meshSurfNormals = NULL;
+               fss->meshVelocities = NULL;
                
                fss->lastgoodframe = -1;
                
@@ -158,10 +157,10 @@ void fluidsim_free(FluidsimModifierData *fluidmd)
 #ifndef DISABLE_ELBEEM
        if(fluidmd)
        {
-               if(fluidmd->fss->meshSurfNormals)
+               if(fluidmd->fss->meshVelocities)
                {
-                       MEM_freeN(fluidmd->fss->meshSurfNormals);
-                       fluidmd->fss->meshSurfNormals = NULL;
+                       MEM_freeN(fluidmd->fss->meshVelocities);
+                       fluidmd->fss->meshVelocities = NULL;
                }
                MEM_freeN(fluidmd->fss);
        }
@@ -394,12 +393,12 @@ static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *
        FluidsimSettings *fss = fluidmd->fss;
        int len = strlen(filename);
        int totvert = dm->getNumVerts(dm);
-       float *velarray = NULL;
+       FluidVertexVelocity *velarray = NULL;
 
        // mesh and vverts have to be valid from loading...
 
-       if(fss->meshSurfNormals)
-               MEM_freeN(fss->meshSurfNormals);
+       if(fss->meshVelocities)
+               MEM_freeN(fss->meshVelocities);
 
        if(len<7)
        {
@@ -408,12 +407,10 @@ static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *
 
        if(fss->domainNovecgen>0) return;
 
-       // abusing pointer to hold an array of 3d-velocities
-       fss->meshSurfNormals = MEM_callocN(sizeof(float)*3*dm->getNumVerts(dm), "Fluidsim_velocities");
-       // abusing pointer to hold an INT
-       fss->meshSurface = SET_INT_IN_POINTER(totvert);
+       fss->meshVelocities = MEM_callocN(sizeof(FluidVertexVelocity)*dm->getNumVerts(dm), "Fluidsim_velocities");
+       fss->totvert = totvert;
 
-       velarray = (float *)fss->meshSurfNormals;
+       velarray = fss->meshVelocities;
 
        // .bobj.gz , correct filename
        // 87654321
@@ -424,16 +421,16 @@ static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *
        gzf = gzopen(filename, "rb");
        if (!gzf)
        {
-               MEM_freeN(fss->meshSurfNormals);
-               fss->meshSurfNormals = NULL;
+               MEM_freeN(fss->meshVelocities);
+               fss->meshVelocities = NULL;
                return;
        }
 
        gzread(gzf, &wri, sizeof( wri ));
        if(wri != totvert)
        {
-               MEM_freeN(fss->meshSurfNormals);
-               fss->meshSurfNormals = NULL;
+               MEM_freeN(fss->meshVelocities);
+               fss->meshVelocities = NULL;
                return;
        }
 
@@ -442,7 +439,7 @@ static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *
                for(j=0; j<3; j++)
                {
                        gzread(gzf, &wrf, sizeof( wrf ));
-                       velarray[3*i + j] = wrf;
+                       velarray[i].vel[j] = wrf;
                }
        }
 
@@ -531,10 +528,10 @@ static DerivedMesh *fluidsim_read_cache(DerivedMesh *orgdm, FluidsimModifierData
        }
        else
        {
-               if(fss->meshSurfNormals)
-                       MEM_freeN(fss->meshSurfNormals);
+               if(fss->meshVelocities)
+                       MEM_freeN(fss->meshVelocities);
 
-               fss->meshSurfNormals = NULL;
+               fss->meshVelocities = NULL;
        }
 
        return dm;
index 74ce7957dd757e491b5faa6f1a248b61d861abe2..c1c2fb60abda93f44145b84acf2d1d396194903c 100644 (file)
@@ -5387,7 +5387,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
        float imat[4][4];
        FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsob, eModifierType_Fluidsim);
        FluidsimSettings *fss;
-       float *velarray = NULL;
+       FluidVertexVelocity *velarray = NULL;
        
        /* only one step needed */
        if(step) return 1;
@@ -5401,14 +5401,14 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
        invert_m4_m4(imat, mat);
 
        /* set first vertex OK */
-       if(!fss->meshSurfNormals) return 0;
+       if(!fss->meshVelocities) return 0;
        
-       if( obr->totvert != GET_INT_FROM_POINTER(fss->meshSurface) ) {
+       if( obr->totvert != fss->totvert) {
                //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", obr->totvert, fsob->fluidsimSettings->meshSurface->totvert); // DEBUG
                return 0;
        }
        
-       velarray = (float *)fss->meshSurfNormals;
+       velarray = fss->meshVelocities;
 
        if(obi->flag & R_TRANSFORMED)
                mul_m4_m4m4(winmat, obi->mat, re->winmat);
@@ -5420,7 +5420,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
        so that also small drops/little water volumes return a velocity != 0. 
        But I had no luck in fixing that function - DG */
        for(a=0; a<obr->totvert; a++) {
-               for(j=0;j<3;j++) avgvel[j] += velarray[3*a + j];
+               for(j=0;j<3;j++) avgvel[j] += velarray[a].vel[j];
                
        }
        for(j=0;j<3;j++) avgvel[j] /= (float)(obr->totvert);
@@ -5435,7 +5435,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
                // get fluid velocity
                fsvec[3] = 0.; 
                //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test
-               for(j=0;j<3;j++) fsvec[j] = velarray[3*a + j];
+               for(j=0;j<3;j++) fsvec[j] = velarray[a].vel[j];
                
                /* (bad) HACK insert average velocity if none is there (see previous comment) */
                if((fsvec[0] == 0.0) && (fsvec[1] == 0.0) && (fsvec[2] == 0.0))