Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJean-Luc Peurière <jlp@nerim.net>2005-09-18 17:27:12 +0400
committerJean-Luc Peurière <jlp@nerim.net>2005-09-18 17:27:12 +0400
commite2d577de9ee72a4e97b12652984bbba007bec82c (patch)
treefb6f6a447d791685b55f28b95534e9571bba4303 /source
parent9e3468bde2ced17f848c37ddd638829801daa335 (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')
-rw-r--r--source/Makefile1
-rw-r--r--source/blender/blenkernel/BKE_modifier.h8
-rw-r--r--source/blender/blenkernel/SConscript2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c386
-rw-r--r--source/blender/blenkernel/intern/Makefile1
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c11
-rw-r--r--source/blender/blenkernel/intern/object.c9
-rw-r--r--source/blender/blenloader/intern/readfile.c6
-rw-r--r--source/blender/blenloader/intern/writefile.c1
-rw-r--r--source/blender/include/butspace.h4
-rw-r--r--source/blender/makesdna/DNA_object_types.h5
-rw-r--r--source/blender/makesdna/intern/makesdna.c2
-rw-r--r--source/blender/src/Makefile1
-rw-r--r--source/blender/src/SConscript4
-rw-r--r--source/blender/src/buttons_object.c186
-rw-r--r--source/nan_definitions.mk1
16 files changed, 625 insertions, 3 deletions
diff --git a/source/Makefile b/source/Makefile
index 142aeb1929e..67ec1c82961 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -218,6 +218,7 @@ endif
PULIB = $(NAN_IKSOLVER)/lib/libiksolver.a
PULIB += $(NAN_MOTO)/lib/libmoto.a
+ PULIB += $(NAN_ELBEEM)/lib/$(DEBUG_DIR)libelbeem.a
PULIB += $(OCGDIR)/blender/readblenfile/$(DEBUG_DIR)libreadblenfile.a
PULIB += $(OCGDIR)/blender/src/$(DEBUG_DIR)libsrcpublisher.a
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();
}
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index a8795ecee48..a861a80509c 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -85,6 +85,7 @@ endif
export NAN_TEST_VERBOSITY ?= 1
export NAN_BMFONT ?= $(LCGDIR)/bmfont
export NAN_OPENNL ?= $(LCGDIR)/opennl
+ export NAN_ELBEEM ?= $(LCGDIR)/elbeem
export NAN_SUPERLU ?= $(LCGDIR)/superlu
ifeq ($(FREE_WINDOWS), true)
export NAN_FTGL ?= $(LCGDIR)/gcc/ftgl