diff options
author | Jean-Luc Peurière <jlp@nerim.net> | 2005-09-18 17:27:12 +0400 |
---|---|---|
committer | Jean-Luc Peurière <jlp@nerim.net> | 2005-09-18 17:27:12 +0400 |
commit | e2d577de9ee72a4e97b12652984bbba007bec82c (patch) | |
tree | fb6f6a447d791685b55f28b95534e9571bba4303 /source/blender | |
parent | 9e3468bde2ced17f848c37ddd638829801daa335 (diff) |
initial commit of the fluid simulator.
Ton reviewed and gave his blessing.
Zr, can you have a look ?
see :
http://projects.blender.org/tracker/?func=detail&atid=127&aid=3039&group_id=9
for initial comments.
N_T : the solver itself (elbeem) needs some works to get rid of
warnings
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/SConscript | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 386 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/Makefile | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 9 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 6 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 1 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 5 | ||||
-rw-r--r-- | source/blender/makesdna/intern/makesdna.c | 2 | ||||
-rw-r--r-- | source/blender/src/Makefile | 1 | ||||
-rw-r--r-- | source/blender/src/SConscript | 4 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 186 |
14 files changed, 623 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 55a09fcd158..0ceb39db401 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -205,5 +205,13 @@ struct Object* modifiers_isDeformedByArmature(struct Object *ob); ModifierData* modifiers_getVirtualModifierList (struct Object *ob); + /* Modifier utility calls, do call through type pointer and return + * default values if pointer is optional. + */ +struct ModifierData* modifier_new (int type); +void modifier_free (struct ModifierData *md); + +int modifier_dependsOnTime (struct ModifierData *md); + #endif diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 620890ba7c3..d279fc4a7d7 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -56,6 +56,7 @@ blenkernel_env.Append (CPPPATH = ['.', '../../../intern/decimation/extern', '../imbuf', '../avi', + '#/intern/elbeem/extern', '#/intern/iksolver/extern', '../blenloader']) @@ -71,3 +72,4 @@ SConscript(['bad_level_call_stubs/SConscript']) blenkernel_env.Append (CPPPATH = user_options_dict['OPENGL_INCLUDE']) blenkernel_env.Append (CPPPATH = user_options_dict['Z_INCLUDE']) +blenkernel_env.Append (CPPPATH = user_options_dict['SDL_INCLUDE']) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 5459277c379..5d83bb42753 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -36,6 +36,8 @@ #include <config.h> #endif +#include <zlib.h> + #include "PIL_time.h" #include "MEM_guardedalloc.h" @@ -46,6 +48,8 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_object_fluidsim.h" // N_T +#include "DNA_scene_types.h" // N_T #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -60,6 +64,7 @@ #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_subsurf.h" +#include "LBM_fluidsim.h" #include "BKE_deform.h" #include "BKE_modifier.h" #include "BKE_key.h" @@ -531,6 +536,7 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3] mdm->dm.drawFacesSolid = meshDM_drawFacesSolid; mdm->dm.drawFacesColored = meshDM_drawFacesColored; mdm->dm.drawFacesTex = meshDM_drawFacesTex; + mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; mdm->dm.drawMappedEdges = meshDM_drawMappedEdges; mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; @@ -1429,7 +1435,6 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos) /***/ -typedef float vec3f[3]; DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md) { @@ -1468,6 +1473,14 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM if (deform_r) *deform_r = NULL; *final_r = NULL; + // N_T + if((G.obedit!=ob) && (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE)) { + if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) { + *final_r = getFluidsimDerivedMesh(ob,useRenderParams, NULL,NULL); + if(*final_r) return; + } + } + if (useDeform) { do_mesh_key(me); @@ -1936,3 +1949,374 @@ DerivedMesh *editmesh_get_derived_base(void) { return getEditMeshDerivedMesh(G.editMesh, NULL); } + +// N_T fluidsim declarations +typedef struct { + MeshDerivedMesh mdm; + + /* release whole mesh? */ + char freeMesh; +} FluidsimDerivedMesh; + + +/***/ +// N_T fluidsim interface +#ifdef WIN32 +#ifndef snprintf +#define snprintf _snprintf +#endif +#endif + + +static void fluidsimDM_release(DerivedMesh *dm) +{ + FluidsimDerivedMesh *fsdm = (FluidsimDerivedMesh*) dm; + if(fsdm->freeMesh) { + // similar to free_mesh(fsdm->mdm.me) , but no things like unlink... + if(fsdm->mdm.me->mvert) MEM_freeN(fsdm->mdm.me->mvert); + if(fsdm->mdm.me->medge) MEM_freeN(fsdm->mdm.me->medge); + if(fsdm->mdm.me->mface) MEM_freeN(fsdm->mdm.me->mface); + MEM_freeN(fsdm->mdm.me); + } + + if (fsdm->mdm.freeNors) MEM_freeN(fsdm->mdm.nors); + if (fsdm->mdm.freeVerts) MEM_freeN(fsdm->mdm.verts); + MEM_freeN(fsdm); +} + +DerivedMesh *getFluidsimDerivedMesh(Object *srcob, int useRenderParams, float *extverts, float *nors) { + //fprintf(stderr,"getFluidsimDerivedMesh call (obid '%s', rp %d)\n", srcob->id.name, useRenderParams); // debug + int i; + Mesh *mesh = NULL; // srcob->ata; + FluidsimDerivedMesh *fsdm; + MeshDerivedMesh *mdm = NULL; + float (*vertCos)[3]; + int displaymode = 0; + int curFrame = G.scene->r.cfra - 1; /* start with 0 */ + char filename[FILE_MAXFILE],filepath[FILE_MAXFILE+FILE_MAXDIR]; + char curWd[FILE_MAXDIR]; + + if(!useRenderParams) { + displaymode = srcob->fluidsimSettings->guiDisplayMode; + } else { + displaymode = srcob->fluidsimSettings->renderDisplayMode; + } + + //fprintf(stderr,"getFluidsimDerivedMesh call (obid '%s', rp %d, dm %d)\n", srcob->id.name, useRenderParams, displaymode); // debug + if((displaymode==1) || (G.obedit==srcob)) { + mesh = srcob->data; + return getMeshDerivedMesh(mesh , srcob, NULL); + } + + // init preview frame + if(displaymode==2) { + // use preview + snprintf(filename,FILE_MAXFILE,"%s_surface_preview_%04d.bobj.gz", srcob->fluidsimSettings->surfdataPrefix, curFrame); + } else { + // load final mesh + snprintf(filename,FILE_MAXFILE,"%s_surface_final_%04d.bobj.gz", srcob->fluidsimSettings->surfdataPrefix, curFrame); + } + BLI_getwdN(curWd); + BLI_make_file_string(G.sce, filepath, srcob->fluidsimSettings->surfdataDir, filename); + + //fprintf(stderr,"getFluidsimDerivedMesh call (obid '%s', rp %d, dm %d) %s \n", srcob->id.name, useRenderParams, displaymode, filepath); // debug + mesh = readBobjgz(filepath, (Mesh*)(srcob->data) ); + if(!mesh) { + // display org. object upon failure + mesh = srcob->data; + return getMeshDerivedMesh(mesh , srcob, NULL); + } + if((mesh)&&(mesh->totvert>0)) { + make_edges(mesh); + for(i=0;i<mesh->totedge;i++) { + // force all edge draw + mesh->medge[i].flag |= ME_EDGEDRAW; + //fprintf(stderr,"INI %d a%d f%d\n",fsdm->fsmesh->totedge,i, (fsdm->fsmesh->medge[i].flag & ME_EDGEDRAW) ); + } + } + + // WARNING copied from getMeshDerivedMesh + fsdm = MEM_callocN(sizeof(*fsdm), "getFluidsimDerivedMesh_fsdm"); + fsdm->freeMesh = 1; + mdm = &fsdm->mdm; + vertCos = NULL; + + mdm->dm.getMinMax = meshDM_getMinMax; + mdm->dm.convertToDispListMesh = meshDM_convertToDispListMesh; + mdm->dm.getNumVerts = meshDM_getNumVerts; + mdm->dm.getNumFaces = meshDM_getNumFaces; + mdm->dm.getVertCos = meshDM_getVertCos; + mdm->dm.getVertCo = meshDM_getVertCo; + mdm->dm.getVertNo = meshDM_getVertNo; + mdm->dm.drawVerts = meshDM_drawVerts; + mdm->dm.drawUVEdges = meshDM_drawUVEdges; + mdm->dm.drawEdges = meshDM_drawEdges; + mdm->dm.drawLooseEdges = meshDM_drawLooseEdges; + mdm->dm.drawFacesSolid = meshDM_drawFacesSolid; + mdm->dm.drawFacesColored = meshDM_drawFacesColored; + mdm->dm.drawFacesTex = meshDM_drawFacesTex; + mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; + mdm->dm.drawMappedEdges = meshDM_drawMappedEdges; + mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; + + // use own release function + mdm->dm.release = fluidsimDM_release; + + mdm->ob = srcob; + mdm->me = mesh; + mdm->verts = mesh->mvert; + mdm->nors = NULL; + mdm->freeNors = 0; + mdm->freeVerts = 0; + + //fprintf(stderr,"fsdm loc %f,%f,%f; size %f,%f,%f; rot %f,%f,%f \n", + //mesh->loc[0], mesh->loc[1], mesh->loc[2], + //mesh->size[0], mesh->size[1], mesh->size[2], + //mesh->rot[0], mesh->rot[1], mesh->rot[2]); + + if (vertCos) { + int i; + + mdm->verts = MEM_mallocN(sizeof(*mdm->verts)*mdm->me->totvert, "deformedVerts"); + for (i=0; i<mdm->me->totvert; i++) { + mdm->verts[i].co[0] = vertCos[i][0]; + mdm->verts[i].co[1] = vertCos[i][1]; + mdm->verts[i].co[2] = vertCos[i][2]; + } + mesh_calc_normals(mdm->verts, mdm->me->totvert, mdm->me->mface, mdm->me->totface, &mdm->nors); + mdm->freeNors = 1; + mdm->freeVerts = 1; + } else { + // XXX this is kinda ... see getMeshDerivedMesh + mesh_calc_normals(mdm->verts, mdm->me->totvert, mdm->me->mface, mdm->me->totface, &mdm->nors); + mdm->freeNors = 1; + } + + return (DerivedMesh*) mdm; +} + + +/* ***************************** bobj file handling ***************************** */ + +/* write .bobj.gz file for a mesh object */ + +void writeBobjgz(char *filename, struct Object *ob) +{ + int wri,i,j; + float wrf; + gzFile gzf; + DispListMesh *dlm = NULL; + DerivedMesh *dm; + float vec[3]; + float rotmat[3][3]; + MFace *mface = NULL; + + if(!ob->data || (ob->type!=OB_MESH)) { + fprintf(stderr,"Writing GZ_BOBJ Invalid object %s ...\n", ob->id.name); + return; + } + if((ob->size[0]<0.0) || (ob->size[0]<0.0) || (ob->size[0]<0.0) ) { + fprintf(stderr,"\nfluidSim::writeBobjgz:: Warning object %s has negative scaling - check triangle ordering...?\n\n", ob->id.name); + } + + fprintf(stderr,"Writing GZ_BOBJ '%s' ... ",filename); + gzf = gzopen(filename, "wb9"); + if (!gzf) { + fprintf(stderr,"writeBobjgz::error - Unable to open file for writing '%s'\n", filename); + return; + } + + dm = mesh_create_derived_render(ob); + dlm = dm->convertToDispListMesh(dm, 1); + mface = dlm->mface; + + if(sizeof(wri)!=4) { fprintf(stderr,"Writing GZ_BOBJ, Invalid int size %d...\n", wri); return; } // paranoia check + wri = dlm->totvert; + gzwrite(gzf, &wri, sizeof(wri)); + for(i=0; i<wri;i++) { + VECCOPY(vec, dlm->mvert[i].co); /* get transformed point */ + Mat4MulVecfl(ob->obmat, vec); + //fprintf(stderr,"VTEST %d = %f,%f,%f\n",i,vec[0],vec[1],vec[2]); // DEBUG + for(j=0; j<3; j++) { + wrf = vec[j]; + gzwrite(gzf, &wrf, sizeof( wrf )); + } + } + + // should be the same as Vertices.size + wri = dlm->totvert; + gzwrite(gzf, &wri, sizeof(wri)); + EulToMat3(ob->rot, rotmat); + for(i=0; i<wri;i++) { + VECCOPY(vec, dlm->mvert[i].no); + // FIXME divide? mv->no[0]= (short)(no[0]*32767.0); + Mat3MulVecfl(rotmat, vec); + Normalise(vec); + //fprintf(stderr, "N %s normrot %d %f %f %f\n",ob->id.name, i,vec[0],vec[1],vec[2]); // DEBUG + for(j=0; j<3; j++) { + wrf = vec[j]; //dlm->normals[i][j]; + gzwrite(gzf, &wrf, sizeof( wrf )); + } + } + + + /* compute no. of triangles */ + wri = 0; + for(i=0; i<dlm->totface; i++) { + wri++; + if(mface[i].v4) { wri++; } + } + gzwrite(gzf, &wri, sizeof(wri)); + for(i=0; i<dlm->totface; i++) { + + int face[4]; + face[0] = mface[i].v1; + face[1] = mface[i].v2; + face[2] = mface[i].v3; + face[3] = mface[i].v4; + //fprintf(stderr,"F %s %d = %d,%d,%d,%d \n",ob->id.name, i, face[0],face[1],face[2],face[3] ); + + gzwrite(gzf, &(face[0]), sizeof( face[0] )); + gzwrite(gzf, &(face[1]), sizeof( face[1] )); + gzwrite(gzf, &(face[2]), sizeof( face[2] )); + if(face[3]) { + gzwrite(gzf, &(face[0]), sizeof( face[0] )); + gzwrite(gzf, &(face[2]), sizeof( face[2] )); + gzwrite(gzf, &(face[3]), sizeof( face[3] )); + } + } + + gzclose( gzf ); + if(dlm) displistmesh_free(dlm); + dm->release(dm); + + //fprintf(stderr,"done. #Vertices: %d, #Normals: %d, #Triangles: %d\n", dlm->vertices.size(), dlm->normals.size(), dlm->faces.size() ); +} + +/* security macro for readgin bobjs */ +#define CHECK_GOTBYTES(b,s) \ + if((b)!=4) { \ + if(newmesh->mvert) MEM_freeN(newmesh->mvert); \ + if(newmesh->mface) MEM_freeN(newmesh->mface); \ + if(newmesh) MEM_freeN(newmesh); \ + return NULL; \ + } +/* read .bobj.gz file into a fluidsimDerivedMesh struct */ +Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm) +{ + int wri,i,j; + float wrf; + gzFile gzf; + Mesh *newmesh; + const int debugOutput = 0; + // init data from old mesh (materials,flags) + MFace *origMFace = &((MFace*) orgmesh->mface)[0]; + int mat_nr = origMFace->mat_nr; + int flag = origMFace->flag; + MFace *fsface = NULL; + int gotBytes; + + if(!orgmesh) return NULL; + + // similar to copy_mesh + newmesh = MEM_dupallocN(orgmesh); + newmesh->mat= orgmesh->mat; //MEM_dupallocN(orgmesh->mat); // use original? + + newmesh->mvert= NULL; + newmesh->medge= NULL; + newmesh->mface= NULL; + newmesh->tface= NULL; + newmesh->dface= NULL; + + newmesh->dvert = NULL; //MEM_mallocN (sizeof (MDeformVert)*orgmesh->totvert, "MDeformVert"); + + newmesh->mcol= NULL; //MEM_dupallocN(orgmesh->mcol); + newmesh->msticky= NULL; //MEM_dupallocN(orgmesh->msticky); + newmesh->texcomesh= NULL; + + newmesh->key= NULL; //copy_key(orgmesh->key); + newmesh->totface = 0; + newmesh->totvert = 0; + newmesh->totedge = 0; + newmesh->medge = NULL; //? MEM_mallocN(sizeof(MEdge)*fsdm->fstotedge, "fluidsimDerivedMesh_edges"); + + + if(debugOutput) fprintf(stderr,"Reading '%s' GZ_BOBJ... ",filename); + gzf = gzopen(filename, "rb"); + if (!gzf) { + //fprintf(stderr,"readBobjgz::error - Unable to open file for reading '%s'\n", filename); // DEBUG + MEM_freeN(newmesh); + return NULL; + } + + //if(sizeof(wri)!=4) { fprintf(stderr,"Reading GZ_BOBJ, Invalid int size %d...\n", wri); return NULL; } // paranoia check + + gotBytes = gzread(gzf, &wri, sizeof(wri)); + CHECK_GOTBYTES(gotBytes, "numverts"); + newmesh->totvert = wri; + newmesh->mvert = MEM_mallocN(sizeof(MVert)*newmesh->totvert, "fluidsimDerivedMesh_bobjvertices"); + if(debugOutput) fprintf(stderr,"#vertices %d ", newmesh->totvert); //DEBUG + for(i=0; i<newmesh->totvert;i++) { + for(j=0; j<3; j++) { + gotBytes = gzread(gzf, &wrf, sizeof( wrf )); + CHECK_GOTBYTES(gotBytes, "vert"); + newmesh->mvert[i].co[j] = wrf; + } + //fprintf(stderr,"VTEST %d = %f,%f,%f\n",i,newmesh->mvert[i].co[0],newmesh->mvert[i].co[1],newmesh->mvert[i].co[2]); // DEBUG + } + + // should be the same as Vertices.size + gotBytes = gzread(gzf, &wri, sizeof(wri)); + CHECK_GOTBYTES(gotBytes, "numnorms"); + if(wri != newmesh->totvert) { + // complain #vertices has to be equal to #normals, reset&abort + MEM_freeN(newmesh->mvert); + MEM_freeN(newmesh); + fprintf(stderr,"Reading GZ_BOBJ, #normals=%d, #vertices=%d, aborting...\n", wri,newmesh->totvert ); + return NULL; + } + for(i=0; i<newmesh->totvert;i++) { + for(j=0; j<3; j++) { + gotBytes = gzread(gzf, &wrf, sizeof( wrf )); + CHECK_GOTBYTES(gotBytes, "norm"); + newmesh->mvert[i].no[j] = wrf*32767.0; + } + } + + + /* compute no. of triangles */ + gotBytes = gzread(gzf, &wri, sizeof(wri)); + CHECK_GOTBYTES(gotBytes, "numfaces"); + newmesh->totface = wri; + newmesh->mface = MEM_mallocN(sizeof(MFace)*newmesh->totface, "fluidsimDerivedMesh_bobjfaces"); + if(debugOutput) fprintf(stderr,"#faces %d ", newmesh->totface); // DEBUG + fsface = newmesh->mface; + for(i=0; i<newmesh->totface; i++) { + int face[4]; + + gotBytes = gzread(gzf, &(face[0]), sizeof( face[0] )); + CHECK_GOTBYTES(gotBytes, "f1"); + gotBytes = gzread(gzf, &(face[1]), sizeof( face[1] )); + CHECK_GOTBYTES(gotBytes, "f2"); + gotBytes = gzread(gzf, &(face[2]), sizeof( face[2] )); + CHECK_GOTBYTES(gotBytes, "f3"); + face[3] = 0; + + fsface[i].v1 = face[0]; + fsface[i].v2 = face[1]; + fsface[i].v3 = face[2]; + fsface[i].v4 = face[3]; + //fprintf(stderr,"F %s %d = %d,%d,%d,%d \n",newmesh->ob->id.name, i, face[0],face[1],face[2],face[3] ); + } + + gzclose( gzf ); + + for(i=0;i<newmesh->totface;i++) { + fsface[i].mat_nr = mat_nr; + fsface[i].flag = flag; + } + +// if(debugOutput) fprintf(stderr," done\n"); + return newmesh; +} + diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index 250ddae1fd9..9207023f9a5 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -69,6 +69,7 @@ CPPFLAGS += -I../../render/extern/include CPPFLAGS += -I$(NAN_IKSOLVER)/include CPPFLAGS += -I$(NAN_DECIMATION)/include +CPPFLAGS += -I$(NAN_ELBEEM)/include # path to zlib CPPFLAGS += -I$(NAN_ZLIB)/include diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index d3e2d8c3ea8..58d72b89394 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -51,6 +51,7 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_object_fluidsim.h" #include "DNA_oops_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -1437,6 +1438,16 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay) case OB_MESH: me= ob->data; if(me->key) ob->recalc |= OB_RECALC_DATA; + else if(ob->effect.first) { + Effect *eff= ob->effect.first; + if(eff->type==EFF_WAVE) ob->recalc |= OB_RECALC_DATA; + } + if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) { + // fluidsimSettings might not be initialized during load... + if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) { + ob->recalc |= OB_RECALC_DATA; // NT + } + } break; case OB_CURVE: case OB_SURF: diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a1b03b18eb7..7d84e7830ec 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -216,6 +216,7 @@ void free_object(Object *ob) if(ob->pd) MEM_freeN(ob->pd); if(ob->soft) sbFree(ob->soft); + if(ob->fluidsimSettings) MEM_freeN(ob->fluidsimSettings); /* NT */ } static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin) @@ -730,6 +731,10 @@ Object *add_object(int type) ob->anisotropicFriction[1] = 1.0f; ob->anisotropicFriction[2] = 1.0f; ob->gameflag= OB_PROP; + + /* NT fluid sim defaults */ + ob->fluidsimFlag = 0; + ob->fluidsimSettings = NULL; ob->data= add_obdata_from_type(type); @@ -832,6 +837,10 @@ Object *copy_object(Object *ob) if(ob->pd) obn->pd= MEM_dupallocN(ob->pd); obn->soft= copy_softbody(ob->soft); + + /* NT copy fluid sim setting memory */ + if(ob->fluidsimSettings) ob->fluidsimSettings = MEM_dupallocN(ob->fluidsimSettings); + else ob->fluidsimSettings = NULL; ob->derivedDeform = NULL; ob->derivedFinal = NULL; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 96e10a71479..d11bb9ed563 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -85,6 +85,7 @@ #include "DNA_nla_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_object_fluidsim.h" // NT #include "DNA_oops_types.h" #include "DNA_object_force.h" #include "DNA_packedFile_types.h" @@ -2385,6 +2386,11 @@ static void direct_link_object(FileData *fd, Object *ob) } } } + ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */ + if(ob->fluidsimSettings) { + // not much to do for now... fprintf(stderr, "FLUIDSIMT newdataadr\n"); + ob->fluidsimSettings->orgMesh = NULL; + } link_list(fd, &ob->prop); prop= ob->prop.first; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index c54363e692a..bce6dceb384 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -712,6 +712,7 @@ static void write_objects(WriteData *wd, ListBase *idbase) } } } + writestruct(wd, DATA, "FluidsimSettings", 1, ob->fluidsimSettings); // NT write_modifiers(wd, &ob->modifiers); } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 011c13eb0db..96080e187b1 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -234,6 +234,10 @@ void test_idbutton_cb(void *namev, void *arg2_unused); /* this has MAX_EFFECT settings! Next free define is 1450... */ #define B_SELEFFECT 1430 +/* Fluidsim button defines */ +#define B_FLUIDSIM_BAKE 1450 +#define B_FLUIDSIM_SELDIR 1451 + /* *********************** */ #define B_WORLDBUTS 1600 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 036a2bdc9cb..6bb18fe1df9 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -53,6 +53,7 @@ struct Material; struct bConstraintChannel; struct PartDeflect; struct SoftBody; +struct FluidsimSettings; struct DerivedMesh; typedef struct bDeformGroup { @@ -190,6 +191,10 @@ typedef struct Object { LBuf port; float pad3, smoothresh; /* smoothresh is phong interpolation ray_shadow correction in render */ + + short fluidsimFlag; /* NT toggle fluidsim participation on/off */ + short dnapadFluidsimDummy1, dnapadFluidsimDummy2, dnapadFluidsimDummy3; /* 8byte align */ + struct FluidsimSettings *fluidsimSettings; /* if fluidsim enabled, store additional settings */ struct DerivedMesh *derivedDeform, *derivedFinal; } Object; diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 3db54336060..2354b93dcbb 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -97,6 +97,7 @@ char *includefiles[] = { "DNA_lattice_types.h", "DNA_object_types.h", "DNA_object_force.h", + "DNA_object_fluidsim.h", "DNA_world_types.h", "DNA_radio_types.h", "DNA_scene_types.h", @@ -1104,6 +1105,7 @@ int main(int argc, char ** argv) #include "DNA_lattice_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_object_fluidsim.h", #include "DNA_world_types.h" #include "DNA_radio_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/src/Makefile b/source/blender/src/Makefile index e694880b1dd..f0728897d47 100644 --- a/source/blender/src/Makefile +++ b/source/blender/src/Makefile @@ -59,6 +59,7 @@ endif CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += -I$(NAN_GHOST)/include CPPFLAGS += -I$(NAN_BMFONT)/include +CPPFLAGS += -I$(NAN_ELBEEM)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include $(NAN_SDLCFLAGS) # External interfaces of modules: diff --git a/source/blender/src/SConscript b/source/blender/src/SConscript index 84bdd178b67..7c745b251da 100644 --- a/source/blender/src/SConscript +++ b/source/blender/src/SConscript @@ -23,7 +23,7 @@ source_files = ['B.blend.c', 'cmovie.tga.c', 'cursors.c', 'drawaction.c', - 'drawarmature.c', + 'drawarmature.c', 'drawdeps.c', 'drawimage.c', 'drawimasel.c', @@ -71,6 +71,7 @@ source_files = ['B.blend.c', 'editview.c', 'eventdebug.c', 'filesel.c', + 'fluidsim.c', 'ghostwinlay.c', 'glutil.c', 'headerbuttons.c', @@ -150,6 +151,7 @@ src_env.Append (CPPPATH = ['#/intern/guardedalloc', '../readstreamglue', '../img', '../quicktime', + '#/intern/elbeem/extern', '#/intern/ghost', '#/intern/opennl/extern']) diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index d1455afc879..1b4dfda3975 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1,5 +1,5 @@ /** - * $Id: + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -50,6 +50,7 @@ #include "BKE_main.h" #include "BKE_library.h" #include "BKE_softbody.h" +#include "BKE_utildefines.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -97,6 +98,7 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_object_fluidsim.h" #include "DNA_radio_types.h" #include "DNA_screen_types.h" #include "DNA_sound_types.h" @@ -126,6 +128,7 @@ #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" +#include "LBM_fluidsim.h" #include "BIF_editconstraint.h" #include "BSE_editipo.h" @@ -1182,6 +1185,57 @@ static void softbody_bake(Object *ob) } +// NT store processed path & file prefix for fluidsim bake directory +void fluidsimFilesel(char *selection) +{ + Object *ob = OBACT; + char srcDir[FILE_MAXDIR], srcFile[FILE_MAXFILE]; + char prefix[FILE_MAXFILE]; + char *srch, *srchSub, *srchExt, *lastFound; + int isElbeemSurf = 0; + + strcpy(srcDir, selection); + BLI_splitdirstring(srcDir, srcFile); + + // make prefix + strcpy(prefix, srcFile); + // check if this is a previously generated surface mesh file + srch = strstr(prefix, "_surface_"); + if(srch) { + srchSub = strstr(prefix,"_preview_"); + if(!srchSub) srchSub = strstr(prefix,"_final_"); + srchExt = strstr(prefix,".gz.bobj"); + if(!srchExt) srchExt = strstr(prefix,".bobj"); + if(srchSub && srchExt) { + *srch = '\0'; + isElbeemSurf = 1; + } + } + if(!isElbeemSurf) { + // try to remove suffix + lastFound = NULL; + srch = strchr(prefix, '.'); // search last . from extension + while(srch) { + lastFound = srch; + if(srch) { + srch++; + srch = strchr(srch, '.'); + } + } + if(lastFound) { + *lastFound = '\0'; + } + } + + // TODO check srcDir for file path from sce? + + + strcpy(ob->fluidsimSettings->surfdataDir, srcDir); + strcpy(ob->fluidsimSettings->surfdataPrefix, prefix); + //fprintf(stderr,"fluidsimFilesel: Using surfdata path '%s', prefix '%s' \n", ob->fluidsimSettings->surfdataDir,ob->fluidsimSettings->surfdataPrefix); // DEBUG + +} + void do_object_panels(unsigned short event) { Object *ob; @@ -1261,6 +1315,22 @@ void do_object_panels(unsigned short event) allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); break; + + case B_FLUIDSIM_BAKE: + ob= OBACT; + /* write config files (currently no simulation) */ + fluidsimBake(ob); + break; + case B_FLUIDSIM_SELDIR: { + char str[FILE_MAXDIR+FILE_MAXFILE]; + ScrArea *sa = closest_bigger_area(); + strcpy(str,"//"); + ob= OBACT; + /* chosse dir for surface files */ + areawinset(sa->win); + activate_fileselect(FILE_SPECIAL, "Select Directory", str, fluidsimFilesel); + } + break; default: if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) { @@ -1800,6 +1870,119 @@ static void object_panel_effects(Object *ob) } } +/* NT - Panel for fluidsim settings */ +static void object_panel_fluidsim(Object *ob) +{ + uiBlock *block; + int yline = 160; + const int lineHeight = 20; + const int objHeight = 20; + + block= uiNewBlock(&curarea->uiblocks, "object_fluidsim", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Constraints", "Object"); + if(uiNewPanel(curarea, block, "Fluidsim", "Object", 640, 0, 318, 204)==0) return; + + uiDefButBitS(block, TOG, OB_FLUIDSIM_ENABLE, REDRAWBUTSOBJECT, "Enable", 0,yline, 75,objHeight, + &ob->fluidsimFlag, 0, 0, 0, 0, "Sets object to participate in fluid simulation"); + + if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) { + FluidsimSettings *fss= ob->fluidsimSettings; + + if(fss==NULL) { + fss = ob->fluidsimSettings = fluidsimSettingsNew(ob); // sbNew(); + } + + if(ob->type==OB_MESH) { + + uiBlockBeginAlign(block); + uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Domain", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_DOMAIN, 0.0, 0.0, "Bounding box of this object represents the computational domain of the fluid simulation."); + uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Fluid", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_FLUID, 0.0, 0.0, "Object represents a volume of fluid in the simulation."); + uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Obstacle", 230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OBSTACLE, 0.0, 0.0, "Object is a fixed obstacle."); + yline -= lineHeight; + yline -= 5; + + /* display specific settings for each type */ + if(fss->type == OB_FLUIDSIM_DOMAIN) { + const int maxRes = 200; + + uiDefButS(block, NUM, B_DIFF, "Resolution:", 0, yline,150,objHeight, &fss->resolutionxyz, 1, maxRes, 10, 0, "Domain resolution in X,Y and Z direction"); + uiDefButS(block, NUM, B_DIFF, "Preview-Res.:", 150, yline,150,objHeight, &fss->previewresxyz, 1, 100, 10, 0, "Resolution of the preview meshes to generate, also in X,Y and Z direction"); + yline -= lineHeight; + uiDefButF(block, NUM, B_DIFF, "Real-size:", 0, yline,150,objHeight, &fss->realsize, 0.0, 1.0, 10, 0, "Size of the simulation domain in meters."); + yline -= lineHeight; + + uiDefButF(block, NUM, B_DIFF, "GravX:", 0, yline, 100,objHeight, &fss->gravx, -1000.1, 1000.1, 10, 0, "Gravity in X direction"); + uiDefButF(block, NUM, B_DIFF, "GravY:", 100, yline, 100,objHeight, &fss->gravy, -1000.1, 1000.1, 10, 0, "Gravity in Y direction"); + uiDefButF(block, NUM, B_DIFF, "GravZ:", 200, yline, 100,objHeight, &fss->gravz, -1000.1, 1000.1, 10, 0, "Gravity in Z direction"); + yline -= lineHeight; + uiDefButF(block, NUM, B_DIFF, "Start time:", 0, yline,150,objHeight, &fss->animStart, 0.0, 100.0, 10, 0, "Simulation time of the first blender frame."); + uiDefButF(block, NUM, B_DIFF, "End time:", 150, yline,150,objHeight, &fss->animEnd , 0.0, 100.0, 10, 0, "Simulation time of the last blender frame."); + yline -= lineHeight; + + /* "advanced" settings */ + yline -= 5; + + /* could also be char? */ + uiDefButS(block, MENU, REDRAWVIEW3D, "Viscosity%t|Manual %x1|Water %x2|Oil %x3|Honey %x4", + 0,yline,100,objHeight, &fss->viscosityMode, 0, 0, 0, 0, "Set viscosity of the fluid to a preset value, or use manual input."); + if(fss->viscosityMode==1) { + uiDefButF(block, NUM, B_DIFF, "Value:", 100, yline, 100,objHeight, &fss->viscosityValue, 0.0, 1.0, 10, 0, "Viscosity setting, value that is multiplied by 10 to the power of (exponent*-1)."); + uiDefButS(block, NUM, B_DIFF, "Neg-Exp.:", 200, yline, 100,objHeight, &fss->viscosityExponent, 0, 10, 10, 0, "Negative exponent for the viscosity value (to simplify entering small values e.g. 5*10^-6."); + } else { + // display preset values + uiDefBut(block, LABEL, 0, fluidsimViscosityPresetString[fss->viscosityMode], 100,yline,200,objHeight, NULL, 0.0, 0, 0, 0, ""); + } + yline -= lineHeight; + + uiDefBut(block, LABEL, 0, "Gui:", 0,yline,50,objHeight, NULL, 0.0, 0, 0, 0, ""); + uiDefButS(block, MENU, REDRAWVIEW3D, "GuiDisplayMode%t|Geometry %x1|Preview %x2|Final %x3", + 50,yline,100,objHeight, &fss->guiDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh in the blender gui."); + uiDefBut(block, LABEL, 0, "Rend:", 150,yline,50,objHeight, NULL, 0.0, 0, 0, 0, ""); + uiDefButS(block, MENU, REDRAWVIEW3D, "RenderDisplayMode%t|Geometry %x1|Preview %x2|Final %x3", + 200,yline,100,objHeight, &fss->renderDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh for rendering."); + yline -= lineHeight; + + uiDefBut(block, BUT, B_FLUIDSIM_SELDIR, "Select Output Directory", 0, yline,100,objHeight, NULL, 0.0, 0.0, 10, 0, "Select Directory (and/or filenames) to store baked fluid simulation files in"); + uiDefBut(block, LABEL, 0, fss->surfdataDir, 100,yline,100,objHeight, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, fss->surfdataPrefix, 200,yline,100,objHeight, NULL, 0.0, 0, 0, 0, ""); + yline -= lineHeight; + + uiDefBut(block, BUT, B_FLUIDSIM_BAKE, "BAKE", 0, yline,300,objHeight, NULL, 0.0, 0.0, 10, 0, "Perform simulation and output and surface&preview meshes for each frame."); + } + else if(fss->type == OB_FLUIDSIM_FLUID) { + yline -= lineHeight + 5; + uiDefBut(block, LABEL, 0, "Initial velocity:", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, ""); + yline -= lineHeight; + uiDefButF(block, NUM, B_DIFF, "X:", 0, yline, 100,objHeight, &fss->iniVelx, -1000.1, 1000.1, 10, 0, "Initial fluid velocity in X direction"); + uiDefButF(block, NUM, B_DIFF, "Y:", 100, yline, 100,objHeight, &fss->iniVely, -1000.1, 1000.1, 10, 0, "Initial fluid velocity in Y direction"); + uiDefButF(block, NUM, B_DIFF, "Z:", 200, yline, 100,objHeight, &fss->iniVelz, -1000.1, 1000.1, 10, 0, "Initial fluid velocity in Z direction"); + yline -= lineHeight; + } + else if(fss->type == OB_FLUIDSIM_OBSTACLE) { + yline -= lineHeight + 5; + uiDefBut(block, LABEL, 0, "No additional settings as of now...", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, ""); + yline -= lineHeight; + } + else { + yline -= lineHeight + 5; + /* not yet set */ + uiDefBut(block, LABEL, 0, "Select object type for simulation", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, ""); + yline -= lineHeight; + } + + } else { + yline -= lineHeight + 5; + uiDefBut(block, LABEL, 0, "Sorry - only meshes supported", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, ""); + yline -= lineHeight; + } + } else { + yline -= lineHeight + 5; + uiDefBut(block, LABEL, 0, "Object not enabled for fluid simulation...", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, ""); + yline -= lineHeight; + } + uiBlockEndAlign(block); +} + void object_panels() { Object *ob; @@ -1817,6 +2000,7 @@ void object_panels() } object_panel_deflectors(ob); object_softbodies(ob); + object_panel_fluidsim(ob); uiClearButLock(); } |