diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2008-07-25 22:57:16 +0400 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2008-07-25 22:57:16 +0400 |
commit | d7fecc9e963d8823d3e6a045c96d3a166ac031a6 (patch) | |
tree | 80f91447a2112454b2651d12fbf2bedada2d9076 /source/blender/blenkernel | |
parent | 9bf0bfcae74f27e5bc2d5b20a70b21c3668542e4 (diff) |
Fluid control: WIP commit before weekend, not working is crashing on the first 3 frames
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_fluidsim.h | 57 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pointcache.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 652 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fluidsim.c | 702 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 77 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 176 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pointcache.c | 16 |
11 files changed, 946 insertions, 761 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index f76cdbc64b7..d951c8401e3 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -41,7 +41,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 246 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 1 #define BLENDER_MINVERSION 245 #define BLENDER_MINSUBVERSION 15 diff --git a/source/blender/blenkernel/BKE_fluidsim.h b/source/blender/blenkernel/BKE_fluidsim.h new file mode 100644 index 00000000000..12df42e85c1 --- /dev/null +++ b/source/blender/blenkernel/BKE_fluidsim.h @@ -0,0 +1,57 @@ +/** + * BKE_fluidsim.h + * + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "DNA_modifier_types.h" +#include "DNA_object_fluidsim.h" // N_T +#include "DNA_object_types.h" + +#include "BKE_DerivedMesh.h" + +/* old interface */ +FluidsimSettings *fluidsimSettingsNew(struct Object *srcob); + + +void initElbeemMesh(Object *ob, int *numVertices, float **vertices, int *numTriangles, int **triangles, int useGlobalCoords); + +void loadFluidsimMesh(Object *srcob, int useRenderParams); + + +/* new fluid-modifier interface */ +void fluidsim_init(FluidsimModifierData *fluidmd); +void fluidsim_free(FluidsimModifierData *fluidmd); + +DerivedMesh *fluidsim_read_cache(Object *ob, FluidsimModifierData *fluidmd, int framenr, int useRenderParams); +DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc); + +void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4], + /*RET*/ float start[3], /*RET*/ float size[3] ); + + + diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 5bc467465a8..e4ce502e142 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -54,7 +54,8 @@ /* PTCacheID types */ #define PTCACHE_TYPE_SOFTBODY 0 #define PTCACHE_TYPE_PARTICLES 1 -#define PTCACHE_TYPE_CLOTH 2 +#define PTCACHE_TYPE_CLOTH 2 +#define PTCACHE_TYPE_FLUIDSIM 3 /* Structs */ struct Object; @@ -83,6 +84,7 @@ typedef struct PTCacheID { void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb); void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys); void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd); +void BKE_ptcache_id_from_fluidsim(PTCacheID *pid, struct Object *ob, struct FluidsimModifierData *fluidmd); void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 4d3f9143b85..bfd47f14009 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -33,8 +33,6 @@ #include <config.h> #endif -#include <zlib.h> - #include "PIL_time.h" #include "MEM_guardedalloc.h" @@ -66,6 +64,7 @@ #include "BKE_deform.h" #include "BKE_displist.h" #include "BKE_effect.h" +#include "BKE_fluidsim.h" #include "BKE_global.h" #include "BKE_key.h" #include "BKE_material.h" @@ -85,11 +84,6 @@ #include "BIF_gl.h" #include "BIF_glutil.h" -// headers for fluidsim bobj meshes -#include <stdlib.h> -#include "LBM_fluidsim.h" -#include "elbeem.h" - /////////////////////////////////// /////////////////////////////////// @@ -411,35 +405,15 @@ void DM_swap_face_data(DerivedMesh *dm, int index, int *corner_indices) static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]) { DerivedMesh *dm = CDDM_from_mesh(me, ob); - int i, dofluidsim; - - dofluidsim = ((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && - (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&& - (ob->fluidsimSettings->meshSurface) && - (me->totvert == ((Mesh *)(ob->fluidsimSettings->meshSurface))->totvert)); - - if (vertCos && !dofluidsim) + + if(!dm) + return NULL; + + if (vertCos) CDDM_apply_vert_coords(dm, vertCos); CDDM_calc_normals(dm); - /* apply fluidsim normals */ - if (dofluidsim) { - // use normals from readBobjgz - // TODO? check for modifiers!? - MVert *fsvert = ob->fluidsimSettings->meshSurfNormals; - short (*normals)[3] = MEM_mallocN(sizeof(short)*3*me->totvert, "fluidsim nor"); - - for (i=0; i<me->totvert; i++) { - VECCOPY(normals[i], fsvert[i].no); - //mv->no[0]= 30000; mv->no[1]= mv->no[2]= 0; // DEBUG fixed test normals - } - - CDDM_apply_vert_normals(dm, normals); - - MEM_freeN(normals); - } - return dm; } @@ -1891,7 +1865,6 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], float (*deformedVerts)[3] = NULL; DerivedMesh *dm, *orcodm, *finaldm; int numVerts = me->totvert; - int fluidsimMeshUsed = 0; int required_mode; md = firstmd = modifiers_getVirtualModifierList(ob); @@ -1907,21 +1880,6 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], if(deform_r) *deform_r = NULL; *final_r = NULL; - /* replace original mesh by fluidsim surface mesh for fluidsim - * domain objects - */ - if((G.obedit!=ob) && !needMapping) { - if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE)) { - if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) { - loadFluidsimMesh(ob,useRenderParams); - fluidsimMeshUsed = 1; - /* might have changed... */ - me = ob->data; - numVerts = me->totvert; - } - } - } - if(useRenderParams) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; @@ -1969,18 +1927,11 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], #endif } } else { - if(!fluidsimMeshUsed) { - /* default behaviour for meshes */ - if(inputVertexCos) - deformedVerts = inputVertexCos; - else - deformedVerts = mesh_getRefKeyCos(me, &numVerts); - } else { - /* the fluid sim mesh might have more vertices than the original - * one, so inputVertexCos shouldnt be used - */ - deformedVerts = mesh_getVertexCos(me, &numVerts); - } + /* default behaviour for meshes */ + if(inputVertexCos) + deformedVerts = inputVertexCos; + else + deformedVerts = mesh_getRefKeyCos(me, &numVerts); } @@ -2158,9 +2109,6 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], MEM_freeN(deformedVerts); BLI_linklist_free(datamasks, NULL); - - /* restore mesh in any case */ - if(fluidsimMeshUsed) ob->data = ob->fluidsimSettings->orgMesh; } static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3] @@ -2844,582 +2792,4 @@ int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**defo return numleft; } -/* ************************* fluidsim bobj file handling **************************** */ - -#ifndef DISABLE_ELBEEM - -#ifdef WIN32 -#ifndef snprintf -#define snprintf _snprintf -#endif -#endif - -/* write .bobj.gz file for a mesh object */ -void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int append, float time) -{ - char debugStrBuffer[256]; - int wri,i,j,totvert,totface; - float wrf; - gzFile gzf; - DerivedMesh *dm; - float vec[3]; - float rotmat[3][3]; - MVert *mvert; - MFace *mface; - //if(append)return; // DEBUG - - if(!ob->data || (ob->type!=OB_MESH)) { - snprintf(debugStrBuffer,256,"Writing GZ_BOBJ Invalid object %s ...\n", ob->id.name); - elbeemDebugOut(debugStrBuffer); - return; - } - if((ob->size[0]<0.0) || (ob->size[0]<0.0) || (ob->size[0]<0.0) ) { - snprintf(debugStrBuffer,256,"\nfluidSim::writeBobjgz:: Warning object %s has negative scaling - check triangle ordering...?\n\n", ob->id.name); - elbeemDebugOut(debugStrBuffer); - } - - snprintf(debugStrBuffer,256,"Writing GZ_BOBJ '%s' ... ",filename); elbeemDebugOut(debugStrBuffer); - if(append) gzf = gzopen(filename, "a+b9"); - else gzf = gzopen(filename, "wb9"); - if (!gzf) { - snprintf(debugStrBuffer,256,"writeBobjgz::error - Unable to open file for writing '%s'\n", filename); - elbeemDebugOut(debugStrBuffer); - return; - } - - dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH); - //dm = mesh_create_derived_no_deform(ob,NULL); - - mvert = dm->getVertArray(dm); - mface = dm->getFaceArray(dm); - totvert = dm->getNumVerts(dm); - totface = dm->getNumFaces(dm); - - // write time value for appended anim mesh - if(append) { - gzwrite(gzf, &time, sizeof(time)); - } - - // continue with verts/norms - if(sizeof(wri)!=4) { snprintf(debugStrBuffer,256,"Writing GZ_BOBJ, Invalid int size %d...\n", wri); elbeemDebugOut(debugStrBuffer); return; } // paranoia check - wri = dm->getNumVerts(dm); - mvert = dm->getVertArray(dm); - gzwrite(gzf, &wri, sizeof(wri)); - for(i=0; i<wri;i++) { - VECCOPY(vec, mvert[i].co); - if(useGlobalCoords) { Mat4MulVecfl(ob->obmat, vec); } - for(j=0; j<3; j++) { - wrf = vec[j]; - gzwrite(gzf, &wrf, sizeof( wrf )); - } - } - - // should be the same as Vertices.size - wri = totvert; - gzwrite(gzf, &wri, sizeof(wri)); - EulToMat3(ob->rot, rotmat); - for(i=0; i<wri;i++) { - VECCOPY(vec, mvert[i].no); - Normalize(vec); - if(useGlobalCoords) { Mat3MulVecfl(rotmat, vec); } - for(j=0; j<3; j++) { - wrf = vec[j]; - gzwrite(gzf, &wrf, sizeof( wrf )); - } - } - - // append only writes verts&norms - if(!append) { - //float side1[3],side2[3],norm1[3],norm2[3]; - //float inpf; - - // compute no. of triangles - wri = 0; - for(i=0; i<totface; i++) { - wri++; - if(mface[i].v4) { wri++; } - } - gzwrite(gzf, &wri, sizeof(wri)); - for(i=0; i<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; - //snprintf(debugStrBuffer,256,"F %s %d = %d,%d,%d,%d \n",ob->id.name, i, face[0],face[1],face[2],face[3] ); elbeemDebugOut(debugStrBuffer); - //VecSubf(side1, mvert[face[1]].co,mvert[face[0]].co); - //VecSubf(side2, mvert[face[2]].co,mvert[face[0]].co); - //Crossf(norm1,side1,side2); - gzwrite(gzf, &(face[0]), sizeof( face[0] )); - gzwrite(gzf, &(face[1]), sizeof( face[1] )); - gzwrite(gzf, &(face[2]), sizeof( face[2] )); - if(face[3]) { - //VecSubf(side1, mvert[face[2]].co,mvert[face[0]].co); - //VecSubf(side2, mvert[face[3]].co,mvert[face[0]].co); - //Crossf(norm2,side1,side2); - //inpf = Inpf(norm1,norm2); - //if(inpf>0.) { - gzwrite(gzf, &(face[0]), sizeof( face[0] )); - gzwrite(gzf, &(face[2]), sizeof( face[2] )); - gzwrite(gzf, &(face[3]), sizeof( face[3] )); - //} else { - //gzwrite(gzf, &(face[0]), sizeof( face[0] )); - //gzwrite(gzf, &(face[3]), sizeof( face[3] )); - //gzwrite(gzf, &(face[2]), sizeof( face[2] )); - //} - } // quad - } - } - - snprintf(debugStrBuffer,256,"Done. #Vertices: %d, #Triangles: %d\n", totvert, totface ); - elbeemDebugOut(debugStrBuffer); - - gzclose( gzf ); - dm->release(dm); -} - -void initElbeemMesh(struct Object *ob, - int *numVertices, float **vertices, - int *numTriangles, int **triangles, - int useGlobalCoords) -{ - DerivedMesh *dm = NULL; - MVert *mvert; - MFace *mface; - int countTris=0, i, totvert, totface; - float *verts; - int *tris; - - dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH); - //dm = mesh_create_derived_no_deform(ob,NULL); - - mvert = dm->getVertArray(dm); - mface = dm->getFaceArray(dm); - totvert = dm->getNumVerts(dm); - totface = dm->getNumFaces(dm); - - *numVertices = totvert; - verts = MEM_callocN( totvert*3*sizeof(float), "elbeemmesh_vertices"); - for(i=0; i<totvert; i++) { - VECCOPY( &verts[i*3], mvert[i].co); - if(useGlobalCoords) { Mat4MulVecfl(ob->obmat, &verts[i*3]); } - } - *vertices = verts; - - for(i=0; i<totface; i++) { - countTris++; - if(mface[i].v4) { countTris++; } - } - *numTriangles = countTris; - tris = MEM_callocN( countTris*3*sizeof(int), "elbeemmesh_triangles"); - countTris = 0; - for(i=0; i<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; - - tris[countTris*3+0] = face[0]; - tris[countTris*3+1] = face[1]; - tris[countTris*3+2] = face[2]; - countTris++; - if(face[3]) { - tris[countTris*3+0] = face[0]; - tris[countTris*3+1] = face[2]; - tris[countTris*3+2] = face[3]; - countTris++; - } - } - *triangles = tris; - - dm->release(dm); -} - -/* read .bobj.gz file into a fluidsimDerivedMesh struct */ -Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) //, fluidsimDerivedMesh *fsdm) -{ - int wri,i,j; - char debugStrBuffer[256]; - float wrf; - Mesh *newmesh; - const int debugBobjRead = 1; - // init data from old mesh (materials,flags) - MFace *origMFace = &((MFace*) orgmesh->mface)[0]; - int mat_nr = -1; - int flag = -1; - MFace *fsface = NULL; - int gotBytes; - gzFile gzf; - - if(!orgmesh) return NULL; - if(!origMFace) return NULL; - mat_nr = origMFace->mat_nr; - flag = origMFace->flag; - - // similar to copy_mesh - newmesh = MEM_dupallocN(orgmesh); - newmesh->mat= orgmesh->mat; - - newmesh->mvert= NULL; - newmesh->medge= NULL; - newmesh->mface= NULL; - newmesh->mtface= NULL; - - newmesh->dvert = NULL; - - newmesh->mcol= NULL; - newmesh->msticky= NULL; - newmesh->texcomesh= NULL; - memset(&newmesh->vdata, 0, sizeof(newmesh->vdata)); - memset(&newmesh->edata, 0, sizeof(newmesh->edata)); - memset(&newmesh->fdata, 0, sizeof(newmesh->fdata)); - - newmesh->key= NULL; - newmesh->totface = 0; - newmesh->totvert = 0; - newmesh->totedge = 0; - newmesh->medge = NULL; - - - snprintf(debugStrBuffer,256,"Reading '%s' GZ_BOBJ... ",filename); elbeemDebugOut(debugStrBuffer); - gzf = gzopen(filename, "rb"); - // gzf = fopen(filename, "rb"); - // debug: fread(b,c,1,a) = gzread(a,b,c) - if (!gzf) { - //snprintf(debugStrBuffer,256,"readBobjgz::error - Unable to open file for reading '%s'\n", filename); // DEBUG - MEM_freeN(newmesh); - return NULL; - } - - //if(sizeof(wri)!=4) { snprintf(debugStrBuffer,256,"Reading GZ_BOBJ, Invalid int size %d...\n", wri); return NULL; } // paranoia check - gotBytes = gzread(gzf, &wri, sizeof(wri)); - newmesh->totvert = wri; - newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, CD_CALLOC, NULL, newmesh->totvert); - if(debugBobjRead){ snprintf(debugStrBuffer,256,"#vertices %d ", newmesh->totvert); elbeemDebugOut(debugStrBuffer); } //DEBUG - for(i=0; i<newmesh->totvert;i++) { - //if(debugBobjRead) snprintf(debugStrBuffer,256,"V %d = ",i); - for(j=0; j<3; j++) { - gotBytes = gzread(gzf, &wrf, sizeof( wrf )); - newmesh->mvert[i].co[j] = wrf; - //if(debugBobjRead) snprintf(debugStrBuffer,256,"%25.20f ", wrf); - } - //if(debugBobjRead) snprintf(debugStrBuffer,256,"\n"); - } - - // should be the same as Vertices.size - gotBytes = gzread(gzf, &wri, sizeof(wri)); - if(wri != newmesh->totvert) { - // complain #vertices has to be equal to #normals, reset&abort - CustomData_free_layer_active(&newmesh->vdata, CD_MVERT, newmesh->totvert); - MEM_freeN(newmesh); - snprintf(debugStrBuffer,256,"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 )); - newmesh->mvert[i].no[j] = (short)(wrf*32767.0f); - //newmesh->mvert[i].no[j] = 0.5; // DEBUG tst - } - //fprintf(stderr," DEBDPCN nm%d, %d = %d,%d,%d \n", - //(int)(newmesh->mvert), i, newmesh->mvert[i].no[0], newmesh->mvert[i].no[1], newmesh->mvert[i].no[2]); - } - //fprintf(stderr," DPCN 0 = %d,%d,%d \n", newmesh->mvert[0].no[0], newmesh->mvert[0].no[1], newmesh->mvert[0].no[2]); - - - /* compute no. of triangles */ - gotBytes = gzread(gzf, &wri, sizeof(wri)); - newmesh->totface = wri; - newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, CD_CALLOC, NULL, newmesh->totface); - if(debugBobjRead){ snprintf(debugStrBuffer,256,"#faces %d ", newmesh->totface); elbeemDebugOut(debugStrBuffer); } //DEBUG - fsface = newmesh->mface; - for(i=0; i<newmesh->totface; i++) { - int face[4]; - - gotBytes = gzread(gzf, &(face[0]), sizeof( face[0] )); - gotBytes = gzread(gzf, &(face[1]), sizeof( face[1] )); - gotBytes = gzread(gzf, &(face[2]), sizeof( face[2] )); - face[3] = 0; - - fsface[i].v1 = face[0]; - fsface[i].v2 = face[1]; - fsface[i].v3 = face[2]; - fsface[i].v4 = face[3]; - } - - // correct triangles with v3==0 for blender, cycle verts - for(i=0; i<newmesh->totface; i++) { - if(!fsface[i].v3) { - int temp = fsface[i].v1; - fsface[i].v1 = fsface[i].v2; - fsface[i].v2 = fsface[i].v3; - fsface[i].v3 = temp; - } - } - - gzclose( gzf ); - for(i=0;i<newmesh->totface;i++) { - fsface[i].mat_nr = mat_nr; - fsface[i].flag = flag; - fsface[i].edcode = ME_V1V2 | ME_V2V3 | ME_V3V1; - //snprintf(debugStrBuffer,256,"%d : %d,%d,%d\n", i,fsface[i].mat_nr, fsface[i].flag, fsface[i].edcode ); - } - - snprintf(debugStrBuffer,256," (%d,%d) done\n", newmesh->totvert,newmesh->totface); elbeemDebugOut(debugStrBuffer); //DEBUG - return newmesh; -} - -/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */ -void readVelgz(char *filename, Object *srcob) -{ - char debugStrBuffer[256]; - int wri, i, j; - float wrf; - gzFile gzf; - MVert *vverts = srcob->fluidsimSettings->meshSurfNormals; - int len = strlen(filename); - Mesh *mesh = srcob->data; - // mesh and vverts have to be valid from loading... - - // clean up in any case - for(i=0; i<mesh->totvert;i++) { - for(j=0; j<3; j++) { - vverts[i].co[j] = 0.; - } - } - if(srcob->fluidsimSettings->domainNovecgen>0) return; - - if(len<7) { - //printf("readVelgz Eror: invalid filename '%s'\n",filename); // DEBUG - return; - } - - // .bobj.gz , correct filename - // 87654321 - filename[len-6] = 'v'; - filename[len-5] = 'e'; - filename[len-4] = 'l'; - - snprintf(debugStrBuffer,256,"Reading '%s' GZ_VEL... ",filename); elbeemDebugOut(debugStrBuffer); - gzf = gzopen(filename, "rb"); - if (!gzf) { - //printf("readVelgz Eror: unable to open file '%s'\n",filename); // DEBUG - return; - } - - gzread(gzf, &wri, sizeof( wri )); - if(wri != mesh->totvert) { - //printf("readVelgz Eror: invalid no. of velocities %d vs. %d aborting.\n" ,wri ,mesh->totvert ); // DEBUG - return; - } - - for(i=0; i<mesh->totvert;i++) { - for(j=0; j<3; j++) { - gzread(gzf, &wrf, sizeof( wrf )); - vverts[i].co[j] = wrf; - } - //if(i<20) fprintf(stderr, "GZ_VELload %d = %f,%f,%f \n",i,vverts[i].co[0],vverts[i].co[1],vverts[i].co[2]); // DEBUG - } - - gzclose(gzf); -} - - -/* ***************************** fluidsim derived mesh ***************************** */ - -/* check which file to load, and replace old mesh of the object with it */ -/* this replacement is undone at the end of mesh_calc_modifiers */ -void loadFluidsimMesh(Object *srcob, int useRenderParams) -{ - Mesh *mesh = NULL; - float *bbStart = NULL, *bbSize = NULL; - float lastBB[3]; - int displaymode = 0; - int curFrame = G.scene->r.cfra - 1 /*G.scene->r.sfra*/; /* start with 0 at start frame */ - char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR]; - char debugStrBuffer[256]; - //snprintf(debugStrBuffer,256,"loadFluidsimMesh call (obid '%s', rp %d)\n", srcob->id.name, useRenderParams); // debug - - if((!srcob)||(!srcob->fluidsimSettings)) { - snprintf(debugStrBuffer,256,"DEBUG - Invalid loadFluidsimMesh call, rp %d, dm %d)\n", useRenderParams, displaymode); // debug - elbeemDebugOut(debugStrBuffer); // debug - return; - } - // make sure the original mesh data pointer is stored - if(!srcob->fluidsimSettings->orgMesh) { - srcob->fluidsimSettings->orgMesh = srcob->data; - } - - // free old mesh, if there is one (todo, check if it's still valid?) - if(srcob->fluidsimSettings->meshSurface) { - Mesh *freeFsMesh = srcob->fluidsimSettings->meshSurface; - - // similar to free_mesh(...) , but no things like unlink... - CustomData_free(&freeFsMesh->vdata, freeFsMesh->totvert); - CustomData_free(&freeFsMesh->edata, freeFsMesh->totedge); - CustomData_free(&freeFsMesh->fdata, freeFsMesh->totface); - MEM_freeN(freeFsMesh); - - if(srcob->data == srcob->fluidsimSettings->meshSurface) - srcob->data = srcob->fluidsimSettings->orgMesh; - srcob->fluidsimSettings->meshSurface = NULL; - - if(srcob->fluidsimSettings->meshSurfNormals) MEM_freeN(srcob->fluidsimSettings->meshSurfNormals); - srcob->fluidsimSettings->meshSurfNormals = NULL; - } - - // init bounding box - bbStart = srcob->fluidsimSettings->bbStart; - bbSize = srcob->fluidsimSettings->bbSize; - lastBB[0] = bbSize[0]; // TEST - lastBB[1] = bbSize[1]; - lastBB[2] = bbSize[2]; - fluidsimGetAxisAlignedBB(srcob->fluidsimSettings->orgMesh, srcob->obmat, bbStart, bbSize, &srcob->fluidsimSettings->meshBB); - // check free fsmesh... TODO - - if(!useRenderParams) { - displaymode = srcob->fluidsimSettings->guiDisplayMode; - } else { - displaymode = srcob->fluidsimSettings->renderDisplayMode; - } - - snprintf(debugStrBuffer,256,"loadFluidsimMesh call (obid '%s', rp %d, dm %d), curFra=%d, sFra=%d #=%d \n", - srcob->id.name, useRenderParams, displaymode, G.scene->r.cfra, G.scene->r.sfra, curFrame ); // debug - elbeemDebugOut(debugStrBuffer); // debug - - strncpy(targetDir, srcob->fluidsimSettings->surfdataPath, FILE_MAXDIR); - // use preview or final mesh? - if(displaymode==1) { - // just display original object - srcob->data = srcob->fluidsimSettings->orgMesh; - return; - } else if(displaymode==2) { - strcat(targetDir,"fluidsurface_preview_####"); - } else { // 3 - strcat(targetDir,"fluidsurface_final_####"); - } - BLI_convertstringcode(targetDir, G.sce); - BLI_convertstringframe(targetDir, curFrame); // fixed #frame-no - - strcpy(targetFile,targetDir); - strcat(targetFile, ".bobj.gz"); - - snprintf(debugStrBuffer,256,"loadFluidsimMesh call (obid '%s', rp %d, dm %d) '%s' \n", srcob->id.name, useRenderParams, displaymode, targetFile); // debug - elbeemDebugOut(debugStrBuffer); // debug - - if(displaymode!=2) { // dont add bounding box for final - mesh = readBobjgz(targetFile, srcob->fluidsimSettings->orgMesh ,NULL,NULL); - } else { - mesh = readBobjgz(targetFile, srcob->fluidsimSettings->orgMesh, bbSize,bbSize ); - } - if(!mesh) { - // switch, abort background rendering when fluidsim mesh is missing - const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp - if(G.background==1) { - if(getenv(strEnvName2)) { - int elevel = atoi(getenv(strEnvName2)); - if(elevel>0) { - printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n",strEnvName2, targetFile); - exit(1); - } - } - } - - // display org. object upon failure - srcob->data = srcob->fluidsimSettings->orgMesh; - return; - } - - if((mesh)&&(mesh->totvert>0)) { - make_edges(mesh, 0); // 0 = make all edges draw - } - srcob->fluidsimSettings->meshSurface = mesh; - srcob->data = mesh; - srcob->fluidsimSettings->meshSurfNormals = MEM_dupallocN(mesh->mvert); - - // load vertex velocities, if they exist... - // TODO? use generate flag as loading flag as well? - // warning, needs original .bobj.gz mesh loading filename - if(displaymode==3) { - readVelgz(targetFile, srcob); - } else { - // no data for preview, only clear... - int i,j; - for(i=0; i<mesh->totvert;i++) { for(j=0; j<3; j++) { srcob->fluidsimSettings->meshSurfNormals[i].co[j] = 0.; }} - } - - //fprintf(stderr,"LOADFLM DEBXHCH fs=%d 3:%d,%d,%d \n", (int)mesh, ((Mesh *)(srcob->fluidsimSettings->meshSurface))->mvert[3].no[0], ((Mesh *)(srcob->fluidsimSettings->meshSurface))->mvert[3].no[1], ((Mesh *)(srcob->fluidsimSettings->meshSurface))->mvert[3].no[2]); - return; -} - -/* helper function */ -/* init axis aligned BB for mesh object */ -void fluidsimGetAxisAlignedBB(struct Mesh *mesh, float obmat[][4], - /*RET*/ float start[3], /*RET*/ float size[3], /*RET*/ struct Mesh **bbmesh ) -{ - float bbsx=0.0, bbsy=0.0, bbsz=0.0; - float bbex=1.0, bbey=1.0, bbez=1.0; - int i; - float vec[3]; - - VECCOPY(vec, mesh->mvert[0].co); - Mat4MulVecfl(obmat, vec); - bbsx = vec[0]; bbsy = vec[1]; bbsz = vec[2]; - bbex = vec[0]; bbey = vec[1]; bbez = vec[2]; - - for(i=1; i<mesh->totvert;i++) { - VECCOPY(vec, mesh->mvert[i].co); - Mat4MulVecfl(obmat, vec); - - if(vec[0] < bbsx){ bbsx= vec[0]; } - if(vec[1] < bbsy){ bbsy= vec[1]; } - if(vec[2] < bbsz){ bbsz= vec[2]; } - if(vec[0] > bbex){ bbex= vec[0]; } - if(vec[1] > bbey){ bbey= vec[1]; } - if(vec[2] > bbez){ bbez= vec[2]; } - } - - // return values... - if(start) { - start[0] = bbsx; - start[1] = bbsy; - start[2] = bbsz; - } - if(size) { - size[0] = bbex-bbsx; - size[1] = bbey-bbsy; - size[2] = bbez-bbsz; - } - - // init bounding box mesh? - if(bbmesh) { - int i,j; - Mesh *newmesh = NULL; - if(!(*bbmesh)) { newmesh = MEM_callocN(sizeof(Mesh), "fluidsimGetAxisAlignedBB_meshbb"); } - else { newmesh = *bbmesh; } - - newmesh->totvert = 8; - if(!newmesh->mvert) - newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, CD_CALLOC, NULL, newmesh->totvert); - for(i=0; i<8; i++) { - for(j=0; j<3; j++) newmesh->mvert[i].co[j] = start[j]; - } - - newmesh->totface = 6; - if(!newmesh->mface) - newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, CD_CALLOC, NULL, newmesh->totface); - - *bbmesh = newmesh; - } -} - -#else // DISABLE_ELBEEM - -/* dummy for mesh_calc_modifiers */ -void loadFluidsimMesh(Object *srcob, int useRenderParams) { -} - -#endif // DISABLE_ELBEEM diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 472df3d0f26..4bc3c3a3883 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -764,10 +764,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob) dm->deformedOnly = 1; - if(ob && ob->fluidsimSettings && ob->fluidsimSettings->meshSurface) - alloctype= CD_DUPLICATE; - else - alloctype= CD_REFERENCE; + alloctype= CD_REFERENCE; CustomData_merge(&mesh->vdata, &dm->vertData, CD_MASK_MESH, alloctype, mesh->totvert); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 80f450000bb..9dc89a49196 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1963,12 +1963,6 @@ static void dag_object_time_update_flags(Object *ob) ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; } } - if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) { - // fluidsimSettings might not be initialized during load... - if(ob->fluidsimSettings->type & (OB_FLUIDSIM_DOMAIN|OB_FLUIDSIM_PARTICLE)) { - ob->recalc |= OB_RECALC_DATA; // NT FSPARTICLE - } - } if(ob->particlesystem.first) ob->recalc |= OB_RECALC_DATA; break; diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c new file mode 100644 index 00000000000..63be80f90f9 --- /dev/null +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -0,0 +1,702 @@ +/** + * fluidsim.c + * + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_force.h" // for pointcache +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" // N_T + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_customdata.h" +#include "BKE_DerivedMesh.h" +#include "BKE_fluidsim.h" +#include "BKE_global.h" +#include "BKE_modifier.h" +#include "BKE_mesh.h" +#include "BKE_pointcache.h" +#include "BKE_utildefines.h" + +// headers for fluidsim bobj meshes +#include <stdlib.h> +#include "LBM_fluidsim.h" +#include "elbeem.h" +#include <zlib.h> +#include <string.h> +#include <stdio.h> + +/* ************************* fluidsim bobj file handling **************************** */ + +#ifndef DISABLE_ELBEEM + +// ----------------------------------------- +// forward decleration +// ----------------------------------------- + +// ----------------------------------------- + +void fluidsim_init(FluidsimModifierData *fluidmd) +{ + if(fluidmd) + { + FluidsimSettings *fss = MEM_callocN(sizeof(FluidsimSettings), "fluidsimsettings"); + + fluidmd->fss = fss; + + if(!fss) + return; + + fss->type = 0; + fss->show_advancedoptions = 0; + + fss->resolutionxyz = 50; + fss->previewresxyz = 25; + fss->realsize = 0.03; + fss->guiDisplayMode = 2; // preview + fss->renderDisplayMode = 3; // render + + fss->viscosityMode = 2; // default to water + fss->viscosityValue = 1.0; + fss->viscosityExponent = 6; + + // dg TODO: change this to [] + fss->gravx = 0.0; + fss->gravy = 0.0; + fss->gravz = -9.81; + fss->animStart = 0.0; + fss->animEnd = 0.30; + fss->gstar = 0.005; // used as normgstar + fss->maxRefine = -1; + // maxRefine is set according to resolutionxyz during bake + + // fluid/inflow settings + // fss->iniVel --> automatically set to 0 + + /* elubie: changed this to default to the same dir as the render output + to prevent saving to C:\ on Windows */ + BLI_strncpy(fss->surfdataPath, btempdir, FILE_MAX); + + // first init of bounding box + // no bounding box needed + + // todo - reuse default init from elbeem! + fss->typeFlags = 0; + fss->domainNovecgen = 0; + fss->volumeInitType = 1; // volume + fss->partSlipValue = 0.0; + + fss->generateTracers = 0; + fss->generateParticles = 0.0; + fss->surfaceSmoothing = 1.0; + fss->surfaceSubdivs = 1.0; + fss->particleInfSize = 0.0; + fss->particleInfAlpha = 0.0; + + // init fluid control settings + fss->attractforceStrength = 0.2; + fss->attractforceRadius = 0.75; + fss->velocityforceStrength = 0.2; + fss->velocityforceRadius = 0.75; + fss->cpsTimeStart = fss->animStart; + fss->cpsTimeEnd = fss->animEnd; + fss->cpsQuality = 10.0; // 1.0 / 10.0 => means 0.1 width + + /* + BAD TODO: this is done in buttons_object.c in the moment + Mesh *mesh = ob->data; + // calculate bounding box + fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize); + */ + + fss->lastgoodframe = -1; + + } + + return; +} + +void fluidsim_free(FluidsimModifierData *fluidmd) +{ + if(fluidmd) + { + MEM_freeN(fluidmd->fss); + } + + return; +} + +DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) +{ + DerivedMesh *result = NULL; + int framenr; + FluidsimSettings *fss; + + framenr= (int)G.scene->r.cfra; + + // only handle fluidsim domains + if(fluidmd && fluidmd->fss && (fluidmd->fss->type != OB_FLUIDSIM_DOMAIN)) + return dm; + + // timescale not supported yet + // clmd->sim_parms->timescale= timescale; + + /* try to read from cache */ + if((result = fluidsim_read_cache(ob, fluidmd, framenr, useRenderParams))) { + fss->lastgoodframe = framenr; + return result; + } + else + { + // display last known good frame + if(fss->lastgoodframe >= 0) + { + if((result = fluidsim_read_cache(ob, fluidmd, framenr, useRenderParams))) { + return result; + } + } + + result = CDDM_copy(dm); + + if(!result) { + return dm; + } + } + + return result; +} + +/* read .bobj.gz file into a fluidsimDerivedMesh struct */ +static DerivedMesh *fluidsim_read_obj(char *filename) +{ + int wri,i,j; + float wrf; + int gotBytes; + gzFile gzf; + int numverts = 0, numfaces = 0, numedges = 0; + DerivedMesh *dm = NULL; + MFace *mface; + MVert *mvert; + short *normals; + + // ------------------------------------------------ + // get numverts + numfaces first + // ------------------------------------------------ + gzf = gzopen(filename, "rb"); + if (!gzf) + { + return NULL; + } + + // read numverts + gotBytes = gzread(gzf, &wri, sizeof(wri)); + numverts = wri; + + // skip verts + for(i=0; i<numverts*3; i++) + { + gotBytes = gzread(gzf, &wrf, sizeof( wrf )); + } + + // read number of normals + gotBytes = gzread(gzf, &wri, sizeof(wri)); + + // skip normals + for(i=0; i<numverts*3; i++) + { + gotBytes = gzread(gzf, &wrf, sizeof( wrf )); + } + + /* get no. of triangles */ + gotBytes = gzread(gzf, &wri, sizeof(wri)); + numfaces = wri; + + gzclose( gzf ); + // ------------------------------------------------ + + + // dg - TODO: check for numfaces / numverts = 0 + if(!numfaces || !numverts) + return NULL; + + gzf = gzopen(filename, "rb"); + if (!gzf) + { + return NULL; + } + + dm = CDDM_new(numverts, 0, numfaces); + + if(!dm) + { + gzclose( gzf ); + return NULL; + } + + // read numverts + gotBytes = gzread(gzf, &wri, sizeof(wri)); + + // read vertex position from file + mvert = CDDM_get_verts(dm); + for(i=0; i<numverts; i++) + { + MVert *mv = &mvert[i]; + + for(j=0; j<3; j++) + { + gotBytes = gzread(gzf, &wrf, sizeof( wrf )); + mv->co[j] = wrf; + } + } + + // should be the same as numverts + gotBytes = gzread(gzf, &wri, sizeof(wri)); + if(wri != numverts) + { + if(dm) + dm->release(dm); + gzclose( gzf ); + return NULL; + } + /* + normals = MEM_callocN(sizeof(short) * numverts * 3, "fluid_tmp_normals" ); + if(!normals) + { + if(dm) + dm->release(dm); + gzclose( gzf ); + return NULL; + } + */ + // read normals from file (but don't save them yet) + for(i=0; i<numverts*3;i++) + { + gotBytes = gzread(gzf, &wrf, sizeof( wrf )); + // normals[i] = (short)(wrf*32767.0f); + } + + + /* read no. of triangles */ + gotBytes = gzread(gzf, &wri, sizeof(wri)); + + if(wri!=numfaces) + printf("Fluidsim: error in reading data from file.\n"); + + // read triangles from file + mface = CDDM_get_faces(dm); + for(i=0; i<numfaces; i++) + { + int face[4]; + MFace *mf = &mface[i]; + + gotBytes = gzread(gzf, &(face[0]), sizeof( face[0] )); + gotBytes = gzread(gzf, &(face[1]), sizeof( face[1] )); + gotBytes = gzread(gzf, &(face[2]), sizeof( face[2] )); + face[3] = 0; + + // check if 3rd vertex has index 0 (not allowed in blender) + if(face[2]) + { + mf->v1 = face[0]; + mf->v2 = face[1]; + mf->v3 = face[2]; + } + else + { + mf->v1 = face[1]; + mf->v2 = face[2]; + mf->v3 = face[0]; + } + mface[i].v4 = face[3]; + + test_index_face(mf, NULL, 0, 3); + } + + gzclose( gzf ); + + CDDM_calc_edges(dm); + + // CDDM_apply_vert_normals(dm, (short (*)[3])normals); + // CDDM_calc_normals(result); + + return dm; +} + +DerivedMesh *fluidsim_read_cache(Object *ob, FluidsimModifierData *fluidmd, int framenr, int useRenderParams) +{ + int displaymode = 0; + int curFrame = G.scene->r.cfra - 1 /*G.scene->r.sfra*/; /* start with 0 at start frame */ + char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR]; + FluidsimSettings *fss = fluidmd->fss; + DerivedMesh *dm = NULL; + + if(!useRenderParams) { + displaymode = fss->guiDisplayMode; + } else { + displaymode = fss->renderDisplayMode; + } + + strncpy(targetDir, fss->surfdataPath, FILE_MAXDIR); + + // use preview or final mesh? + if(displaymode==1) + { + // just display original object + return NULL; + } + else if(displaymode==2) + { + strcat(targetDir,"fluidsurface_preview_####"); + } + else + { // 3 + strcat(targetDir,"fluidsurface_final_####"); + } + + BLI_convertstringcode(targetDir, G.sce); + BLI_convertstringframe(targetDir, curFrame); // fixed #frame-no + + strcpy(targetFile,targetDir); + strcat(targetFile, ".bobj.gz"); + + dm = fluidsim_read_obj(targetFile); + + if(!dm) + { + // switch, abort background rendering when fluidsim mesh is missing + const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp + + if(G.background==1) { + if(getenv(strEnvName2)) { + int elevel = atoi(getenv(strEnvName2)); + if(elevel>0) { + printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n",strEnvName2, targetFile); + exit(1); + } + } + } + + // display org. object upon failure which is in dm + return NULL; + } + + // load vertex velocities, if they exist... + // TODO? use generate flag as loading flag as well? + // warning, needs original .bobj.gz mesh loading filename + /* + if(displaymode==3) + { + readVelgz(targetFile, srcob); + } + else + { + // no data for preview, only clear... + int i,j; + for(i=0; i<mesh->totvert;i++) { for(j=0; j<3; j++) { srcob->fluidsimSettings->meshSurfNormals[i].co[j] = 0.; }} + }*/ + + return dm; +} + +void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4], + /*RET*/ float start[3], /*RET*/ float size[3] ) +{ + float bbsx=0.0, bbsy=0.0, bbsz=0.0; + float bbex=1.0, bbey=1.0, bbez=1.0; + int i; + float vec[3]; + + VECCOPY(vec, mvert[0].co); + Mat4MulVecfl(obmat, vec); + bbsx = vec[0]; bbsy = vec[1]; bbsz = vec[2]; + bbex = vec[0]; bbey = vec[1]; bbez = vec[2]; + + for(i = 1; i < totvert; i++) { + VECCOPY(vec, mvert[i].co); + Mat4MulVecfl(obmat, vec); + + if(vec[0] < bbsx){ bbsx= vec[0]; } + if(vec[1] < bbsy){ bbsy= vec[1]; } + if(vec[2] < bbsz){ bbsz= vec[2]; } + if(vec[0] > bbex){ bbex= vec[0]; } + if(vec[1] > bbey){ bbey= vec[1]; } + if(vec[2] > bbez){ bbez= vec[2]; } + } + + // return values... + if(start) { + start[0] = bbsx; + start[1] = bbsy; + start[2] = bbsz; + } + if(size) { + size[0] = bbex-bbsx; + size[1] = bbey-bbsy; + size[2] = bbez-bbsz; + } +} + +//------------------------------------------------------------------------------- +// old interface +//------------------------------------------------------------------------------- + + + +//------------------------------------------------------------------------------- +// file handling +//------------------------------------------------------------------------------- + + +/* write .bobj.gz file for a mesh object */ +void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int append, float time) +{ + int wri,i,j,totvert,totface; + float wrf; + gzFile gzf; + DerivedMesh *dm; + float vec[3]; + float rotmat[3][3]; + MVert *mvert; + MFace *mface; + //if(append)return; // DEBUG + + if(!ob->data || (ob->type!=OB_MESH)) + { + return; + } + if((ob->size[0]<0.0) || (ob->size[0]<0.0) || (ob->size[0]<0.0) ) + { + return; + } + + if(append) gzf = gzopen(filename, "a+b9"); + else gzf = gzopen(filename, "wb9"); + + if (!gzf) + return; + + dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH); + //dm = mesh_create_derived_no_deform(ob,NULL); + + mvert = dm->getVertArray(dm); + mface = dm->getFaceArray(dm); + totvert = dm->getNumVerts(dm); + totface = dm->getNumFaces(dm); + + // write time value for appended anim mesh + if(append) + { + gzwrite(gzf, &time, sizeof(time)); + } + + // continue with verts/norms + if(sizeof(wri)!=4) { return; } // paranoia check + wri = dm->getNumVerts(dm); + mvert = dm->getVertArray(dm); + gzwrite(gzf, &wri, sizeof(wri)); + for(i=0; i<wri;i++) + { + VECCOPY(vec, mvert[i].co); + if(useGlobalCoords) { Mat4MulVecfl(ob->obmat, vec); } + for(j=0; j<3; j++) { + wrf = vec[j]; + gzwrite(gzf, &wrf, sizeof( wrf )); + } + } + + // should be the same as Vertices.size + wri = totvert; + gzwrite(gzf, &wri, sizeof(wri)); + EulToMat3(ob->rot, rotmat); + for(i=0; i<wri;i++) + { + VECCOPY(vec, mvert[i].no); + Normalize(vec); + if(useGlobalCoords) { Mat3MulVecfl(rotmat, vec); } + for(j=0; j<3; j++) { + wrf = vec[j]; + gzwrite(gzf, &wrf, sizeof( wrf )); + } + } + + // append only writes verts&norms + if(!append) { + // compute no. of triangles + wri = 0; + for(i=0; i<totface; i++) + { + wri++; + if(mface[i].v4) { wri++; } + } + gzwrite(gzf, &wri, sizeof(wri)); + for(i=0; i<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; + + 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] )); + } // quad + } + } + + gzclose( gzf ); + dm->release(dm); +} + +void initElbeemMesh(struct Object *ob, + int *numVertices, float **vertices, + int *numTriangles, int **triangles, + int useGlobalCoords) +{ + DerivedMesh *dm = NULL; + MVert *mvert; + MFace *mface; + int countTris=0, i, totvert, totface; + float *verts; + int *tris; + + dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH); + //dm = mesh_create_derived_no_deform(ob,NULL); + + mvert = dm->getVertArray(dm); + mface = dm->getFaceArray(dm); + totvert = dm->getNumVerts(dm); + totface = dm->getNumFaces(dm); + + *numVertices = totvert; + verts = MEM_callocN( totvert*3*sizeof(float), "elbeemmesh_vertices"); + for(i=0; i<totvert; i++) { + VECCOPY( &verts[i*3], mvert[i].co); + if(useGlobalCoords) { Mat4MulVecfl(ob->obmat, &verts[i*3]); } + } + *vertices = verts; + + for(i=0; i<totface; i++) { + countTris++; + if(mface[i].v4) { countTris++; } + } + *numTriangles = countTris; + tris = MEM_callocN( countTris*3*sizeof(int), "elbeemmesh_triangles"); + countTris = 0; + for(i=0; i<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; + + tris[countTris*3+0] = face[0]; + tris[countTris*3+1] = face[1]; + tris[countTris*3+2] = face[2]; + countTris++; + if(face[3]) { + tris[countTris*3+0] = face[0]; + tris[countTris*3+1] = face[2]; + tris[countTris*3+2] = face[3]; + countTris++; + } + } + *triangles = tris; + + dm->release(dm); +} + +/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */ +void readVelgz(char *filename, Object *srcob) +{ + int wri, i, j; + float wrf; + gzFile gzf; + MVert *vverts = srcob->fluidsimSettings->meshSurfNormals; + int len = strlen(filename); + Mesh *mesh = srcob->data; + // mesh and vverts have to be valid from loading... + + // clean up in any case + for(i=0; i<mesh->totvert;i++) + { + for(j=0; j<3; j++) + { + vverts[i].co[j] = 0.; + } + } + if(srcob->fluidsimSettings->domainNovecgen>0) return; + + if(len<7) + { + return; + } + + // .bobj.gz , correct filename + // 87654321 + filename[len-6] = 'v'; + filename[len-5] = 'e'; + filename[len-4] = 'l'; + + gzf = gzopen(filename, "rb"); + if (!gzf) + return; + + gzread(gzf, &wri, sizeof( wri )); + if(wri != mesh->totvert) + { + return; + } + + for(i=0; i<mesh->totvert;i++) + { + for(j=0; j<3; j++) + { + gzread(gzf, &wrf, sizeof( wrf )); + vverts[i].co[j] = wrf; + } + } + + gzclose(gzf); +} + + +#endif // DISABLE_ELBEEM + diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f13f8ef0298..ded13611683 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -55,7 +55,9 @@ #include "MEM_guardedalloc.h" #include "DNA_armature_types.h" +#include "DNA_camera_types.h" #include "DNA_cloth_types.h" +#include "DNA_curve_types.h" #include "DNA_effect_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" @@ -66,8 +68,6 @@ #include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" -#include "DNA_curve_types.h" -#include "DNA_camera_types.h" #include "BLI_editVert.h" @@ -77,29 +77,30 @@ #include "BKE_main.h" #include "BKE_anim.h" #include "BKE_bad_level_calls.h" +#include "BKE_bmesh.h" +#include "BKE_booleanops.h" #include "BKE_cloth.h" #include "BKE_collision.h" +#include "BKE_cdderivedmesh.h" #include "BKE_curve.h" #include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_cdderivedmesh.h" #include "BKE_DerivedMesh.h" -#include "BKE_booleanops.h" #include "BKE_displist.h" -#include "BKE_modifier.h" +#include "BKE_fluidsim.h" +#include "BKE_global.h" #include "BKE_lattice.h" #include "BKE_library.h" -#include "BKE_subsurf.h" -#include "BKE_object.h" -#include "BKE_mesh.h" -#include "BKE_softbody.h" -#include "BKE_cloth.h" #include "BKE_material.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_object.h" #include "BKE_particle.h" #include "BKE_pointcache.h" +#include "BKE_softbody.h" +#include "BKE_subsurf.h" #include "BKE_utildefines.h" + #include "depsgraph_private.h" -#include "BKE_bmesh.h" #include "LOD_DependKludge.h" #include "LOD_decimation.h" @@ -6890,6 +6891,49 @@ static DerivedMesh * explodeModifier_applyModifier( } return derivedData; } + +/* Fluidsim */ +static void fluidsimModifier_initData(ModifierData *md) +{ + FluidsimModifierData *fluidmd= (FluidsimModifierData*) md; + + fluidsim_init(fluidmd); +} +static void fluidsimModifier_freeData(ModifierData *md) +{ + FluidsimModifierData *fluidmd= (FluidsimModifierData*) md; + + fluidsim_free(fluidmd); +} + +static DerivedMesh * fluidsimModifier_applyModifier( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + int useRenderParams, int isFinalCalc) +{ + FluidsimModifierData *fluidmd= (FluidsimModifierData*) md; + DerivedMesh *result = NULL; + + /* check for alloc failing */ + if(!fluidmd->fss) + { + fluidsimModifier_initData(md); + + if(!fluidmd->fss) + return derivedData; + } + + result = fluidsimModifier_do(fluidmd, ob, derivedData, useRenderParams, isFinalCalc); + + if(result) { CDDM_calc_normals(result); return result; } + + return derivedData; +} + +static int fluidsimModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + /* MeshDeform */ static void meshdeformModifier_initData(ModifierData *md) @@ -7521,6 +7565,15 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->dependsOnTime = explodeModifier_dependsOnTime; mti->requiredDataMask = explodeModifier_requiredDataMask; mti->applyModifier = explodeModifier_applyModifier; + + mti = INIT_TYPE(Fluidsim); + mti->type = eModifierTypeType_Nonconstructive + | eModifierTypeFlag_RequiresOriginalData; + mti->flags = eModifierTypeFlag_AcceptsMesh; + mti->initData = fluidsimModifier_initData; + mti->freeData = fluidsimModifier_freeData; + mti->dependsOnTime = fluidsimModifier_dependsOnTime; + mti->applyModifier = fluidsimModifier_applyModifier; typeArrInit = 0; #undef INIT_TYPE diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 7b36e46d45e..08845fb1a53 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -267,7 +267,6 @@ void free_object(Object *ob) MEM_freeN(ob->pd); } if(ob->soft) sbFree(ob->soft); - if(ob->fluidsimSettings) fluidsimSettingsFree(ob->fluidsimSettings); } static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin) @@ -1208,15 +1207,6 @@ Object *copy_object(Object *ob) } obn->soft= copy_softbody(ob->soft); - /* NT copy fluid sim setting memory */ - if(obn->fluidsimSettings) { - obn->fluidsimSettings = fluidsimSettingsCopy(ob->fluidsimSettings); - /* copying might fail... */ - if(obn->fluidsimSettings) { - obn->fluidsimSettings->orgMesh = (Mesh *)obn->data; - } - } - copy_object_particlesystems(obn, ob); obn->derivedDeform = NULL; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index f70648965f4..6973ad51e43 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4540,7 +4540,7 @@ void psys_changed_type(ParticleSystem *psys) } static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra) -{ +{ if(psys->particles){ MEM_freeN(psys->particles); psys->particles = 0; @@ -4549,94 +4549,98 @@ static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra) /* fluid sim particle import handling, actual loading of particles from file */ #ifndef DISABLE_ELBEEM - if( (1) && (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && // broken, disabled for now! - (ob->fluidsimSettings)) { - ParticleSettings *part = psys->part; - ParticleData *pa=0; - char *suffix = "fluidsurface_particles_####"; - char *suffix2 = ".gz"; - char filename[256]; - char debugStrBuffer[256]; - int curFrame = G.scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading - int p, j, numFileParts, totpart; - int readMask, activeParts = 0, fileParts = 0; - gzFile gzf; - - if(ob==G.obedit) // off... - return; - - // ok, start loading - strcpy(filename, ob->fluidsimSettings->surfdataPath); - strcat(filename, suffix); - BLI_convertstringcode(filename, G.sce); - BLI_convertstringframe(filename, curFrame); // fixed #frame-no - strcat(filename, suffix2); - - gzf = gzopen(filename, "rb"); - if (!gzf) { - snprintf(debugStrBuffer,256,"readFsPartData::error - Unable to open file for reading '%s' \n", filename); - //elbeemDebugOut(debugStrBuffer); - return; - } - - gzread(gzf, &totpart, sizeof(totpart)); - numFileParts = totpart; - totpart = (G.rendering)?totpart:(part->disp*totpart)/100; + { + FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); - part->totpart= totpart; - part->sta=part->end = 1.0f; - part->lifetime = G.scene->r.efra + 1; - - /* initialize particles */ - realloc_particles(ob, psys, part->totpart); - initialize_all_particles(ob, psys, 0); - - // set up reading mask - readMask = ob->fluidsimSettings->typeFlags; - - for(p=0, pa=psys->particles; p<totpart; p++, pa++) { - int ptype=0; - - gzread(gzf, &ptype, sizeof( ptype )); - if(ptype&readMask) { - activeParts++; - - gzread(gzf, &(pa->size), sizeof( float )); - - pa->size /= 10.0f; - - for(j=0; j<3; j++) { - float wrf; - gzread(gzf, &wrf, sizeof( wrf )); - pa->state.co[j] = wrf; - //fprintf(stderr,"Rj%d ",j); - } - for(j=0; j<3; j++) { - float wrf; - gzread(gzf, &wrf, sizeof( wrf )); - pa->state.vel[j] = wrf; - } - - pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f; - pa->state.rot[0] = 1.0; - pa->state.rot[1] = pa->state.rot[2] = pa->state.rot[3] = 0.0; - - pa->alive = PARS_ALIVE; - //if(a<25) fprintf(stderr,"FSPARTICLE debug set %s , a%d = %f,%f,%f , life=%f \n", filename, a, pa->co[0],pa->co[1],pa->co[2], pa->lifetime ); - } else { - // skip... - for(j=0; j<2*3+1; j++) { - float wrf; gzread(gzf, &wrf, sizeof( wrf )); + if( fluidmd && fluidmd->fss) { + FluidsimSettings *fss= fluidmd->fss; + ParticleSettings *part = psys->part; + ParticleData *pa=0; + char *suffix = "fluidsurface_particles_####"; + char *suffix2 = ".gz"; + char filename[256]; + char debugStrBuffer[256]; + int curFrame = G.scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading + int p, j, numFileParts, totpart; + int readMask, activeParts = 0, fileParts = 0; + gzFile gzf; + + if(ob==G.obedit) // off... + return; + + // ok, start loading + strcpy(filename, fss->surfdataPath); + strcat(filename, suffix); + BLI_convertstringcode(filename, G.sce); + BLI_convertstringframe(filename, curFrame); // fixed #frame-no + strcat(filename, suffix2); + + gzf = gzopen(filename, "rb"); + if (!gzf) { + snprintf(debugStrBuffer,256,"readFsPartData::error - Unable to open file for reading '%s' \n", filename); + //elbeemDebugOut(debugStrBuffer); + return; + } + + gzread(gzf, &totpart, sizeof(totpart)); + numFileParts = totpart; + totpart = (G.rendering)?totpart:(part->disp*totpart)/100; + + part->totpart= totpart; + part->sta=part->end = 1.0f; + part->lifetime = G.scene->r.efra + 1; + + /* initialize particles */ + realloc_particles(ob, psys, part->totpart); + initialize_all_particles(ob, psys, 0); + + // set up reading mask + readMask = fss->typeFlags; + + for(p=0, pa=psys->particles; p<totpart; p++, pa++) { + int ptype=0; + + gzread(gzf, &ptype, sizeof( ptype )); + if(ptype&readMask) { + activeParts++; + + gzread(gzf, &(pa->size), sizeof( float )); + + pa->size /= 10.0f; + + for(j=0; j<3; j++) { + float wrf; + gzread(gzf, &wrf, sizeof( wrf )); + pa->state.co[j] = wrf; + //fprintf(stderr,"Rj%d ",j); + } + for(j=0; j<3; j++) { + float wrf; + gzread(gzf, &wrf, sizeof( wrf )); + pa->state.vel[j] = wrf; + } + + pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f; + pa->state.rot[0] = 1.0; + pa->state.rot[1] = pa->state.rot[2] = pa->state.rot[3] = 0.0; + + pa->alive = PARS_ALIVE; + //if(a<25) fprintf(stderr,"FSPARTICLE debug set %s , a%d = %f,%f,%f , life=%f \n", filename, a, pa->co[0],pa->co[1],pa->co[2], pa->lifetime ); + } else { + // skip... + for(j=0; j<2*3+1; j++) { + float wrf; gzread(gzf, &wrf, sizeof( wrf )); + } } + fileParts++; } - fileParts++; - } - gzclose( gzf ); - - totpart = psys->totpart = activeParts; - snprintf(debugStrBuffer,256,"readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d \n", psys->totpart,activeParts,fileParts,readMask); - elbeemDebugOut(debugStrBuffer); - } // fluid sim particles done + gzclose( gzf ); + + totpart = psys->totpart = activeParts; + snprintf(debugStrBuffer,256,"readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d \n", psys->totpart,activeParts,fileParts,readMask); + elbeemDebugOut(debugStrBuffer); + } // fluid sim particles done + } #endif // DISABLE_ELBEEM } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 43805959e62..c406e57872d 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -123,6 +123,17 @@ void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *cl pid->cache= clmd->point_cache; } +void BKE_ptcache_id_from_fluidsim(PTCacheID *pid, Object *ob, FluidsimModifierData *fluidmd) +{ + memset(pid, 0, sizeof(PTCacheID)); + + pid->ob= ob; + pid->data= fluidmd; + pid->type= PTCACHE_TYPE_FLUIDSIM; + pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)fluidmd); + pid->cache= fluidmd->point_cache; +} + void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) { PTCacheID *pid; @@ -155,6 +166,11 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) BKE_ptcache_id_from_cloth(pid, ob, (ClothModifierData*)md); BLI_addtail(lb, pid); } + else if(md->type == eModifierType_Fluidsim) { + pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID"); + BKE_ptcache_id_from_fluidsim(pid, ob, (FluidsimModifierData*)md); + BLI_addtail(lb, pid); + } } } |