diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_fluidsim_util.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_fluidsim_util.c | 897 |
1 files changed, 456 insertions, 441 deletions
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c index f548eb78abd..3744c527983 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -21,7 +21,6 @@ * \ingroup modifiers */ - #include <stddef.h> #include <zlib.h> @@ -56,288 +55,301 @@ // headers for fluidsim bobj meshes #include "LBM_fluidsim.h" - void fluidsim_init(FluidsimModifierData *fluidmd) { #ifdef WITH_MOD_FLUID - if (fluidmd) { - FluidsimSettings *fss = MEM_callocN(sizeof(FluidsimSettings), "fluidsimsettings"); - - fluidmd->fss = fss; - - if (!fss) - return; - - fss->fmd = fluidmd; - fss->type = OB_FLUIDSIM_ENABLE; - fss->threads = 0; - fss->show_advancedoptions = 0; - - fss->resolutionxyz = 65; - fss->previewresxyz = 45; - fss->realsize = 0.5; - fss->guiDisplayMode = OB_FSDOM_PREVIEW; - fss->renderDisplayMode = OB_FSDOM_FINAL; - - fss->viscosityValue = 1.0; - fss->viscosityExponent = 6; - - fss->grav[0] = 0.0; - fss->grav[1] = 0.0; - fss->grav[2] = -9.81; - - fss->animStart = 0.0; - fss->animEnd = 4.0; - fss->animRate = 1.0; - 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 */ - - modifier_path_init(fss->surfdataPath, sizeof(fss->surfdataPath), OB_FLUIDSIM_SURF_DIR_DEFAULT); - - /* first init of bounding box */ - /* no bounding box needed */ - - /* todo - reuse default init from elbeem! */ - fss->typeFlags = OB_FSBND_PARTSLIP | OB_FSSG_NOOBS; - fss->domainNovecgen = 0; - fss->volumeInitType = 1; /* volume */ - fss->partSlipValue = 0.2; - - fss->generateTracers = 0; - fss->generateParticles = 0.0; - fss->surfaceSmoothing = 1.0; - fss->surfaceSubdivs = 0.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->meshVelocities = NULL; - - fss->lastgoodframe = -1; - - fss->flag |= OB_FLUIDSIM_ACTIVE; - - } + if (fluidmd) { + FluidsimSettings *fss = MEM_callocN(sizeof(FluidsimSettings), "fluidsimsettings"); + + fluidmd->fss = fss; + + if (!fss) + return; + + fss->fmd = fluidmd; + fss->type = OB_FLUIDSIM_ENABLE; + fss->threads = 0; + fss->show_advancedoptions = 0; + + fss->resolutionxyz = 65; + fss->previewresxyz = 45; + fss->realsize = 0.5; + fss->guiDisplayMode = OB_FSDOM_PREVIEW; + fss->renderDisplayMode = OB_FSDOM_FINAL; + + fss->viscosityValue = 1.0; + fss->viscosityExponent = 6; + + fss->grav[0] = 0.0; + fss->grav[1] = 0.0; + fss->grav[2] = -9.81; + + fss->animStart = 0.0; + fss->animEnd = 4.0; + fss->animRate = 1.0; + 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 */ + + modifier_path_init(fss->surfdataPath, sizeof(fss->surfdataPath), OB_FLUIDSIM_SURF_DIR_DEFAULT); + + /* first init of bounding box */ + /* no bounding box needed */ + + /* todo - reuse default init from elbeem! */ + fss->typeFlags = OB_FSBND_PARTSLIP | OB_FSSG_NOOBS; + fss->domainNovecgen = 0; + fss->volumeInitType = 1; /* volume */ + fss->partSlipValue = 0.2; + + fss->generateTracers = 0; + fss->generateParticles = 0.0; + fss->surfaceSmoothing = 1.0; + fss->surfaceSubdivs = 0.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->meshVelocities = NULL; + + fss->lastgoodframe = -1; + + fss->flag |= OB_FLUIDSIM_ACTIVE; + } #else - (void)fluidmd; /* unused */ + (void)fluidmd; /* unused */ #endif - return; + return; } void fluidsim_free(FluidsimModifierData *fluidmd) { - if (fluidmd && fluidmd->fss) { - if (fluidmd->fss->meshVelocities) { - MEM_freeN(fluidmd->fss->meshVelocities); - } - MEM_SAFE_FREE(fluidmd->fss); - } - - return; + if (fluidmd && fluidmd->fss) { + if (fluidmd->fss->meshVelocities) { + MEM_freeN(fluidmd->fss->meshVelocities); + } + MEM_SAFE_FREE(fluidmd->fss); + } + + return; } #ifdef WITH_MOD_FLUID /* read .bobj.gz file into a fluidsimMesh struct */ static Mesh *fluidsim_read_obj(const char *filename, const MPoly *mp_example) { - int wri = 0, i; - int gotBytes; - gzFile gzf; - int numverts = 0, numfaces = 0; - Mesh *mesh = NULL; - MPoly *mp; - MLoop *ml; - MVert *mv; - short *normals, *no_s; - float no[3]; - - const short mp_mat_nr = mp_example->mat_nr; - const char mp_flag = mp_example->flag; - - /* ------------------------------------------------ - * get numverts + numfaces first - * ------------------------------------------------ */ - gzf = BLI_gzopen(filename, "rb"); - if (!gzf) { - return NULL; - } - - /* read numverts */ - gotBytes = gzread(gzf, &wri, sizeof(wri)); - numverts = wri; - - /* skip verts */ - gotBytes = gzseek(gzf, numverts * 3 * sizeof(float), SEEK_CUR) != -1; - - - /* read number of normals */ - if (gotBytes) - gotBytes = gzread(gzf, &wri, sizeof(wri)); - - /* skip normals */ - gotBytes = gzseek(gzf, numverts * 3 * sizeof(float), SEEK_CUR) != -1; - - /* get no. of triangles */ - if (gotBytes) - gotBytes = gzread(gzf, &wri, sizeof(wri)); - numfaces = wri; - - gzclose(gzf); - /* ------------------------------------------------ */ - - if (!numfaces || !numverts || !gotBytes) - return NULL; - - gzf = BLI_gzopen(filename, "rb"); - if (!gzf) { - return NULL; - } - - mesh = BKE_mesh_new_nomain(numverts, 0, 0, numfaces * 3, numfaces); - - if (!mesh) { - gzclose(gzf); - return NULL; - } - - /* read numverts */ - gotBytes = gzread(gzf, &wri, sizeof(wri)); - - /* read vertex position from file */ - mv = mesh->mvert; - - for (i = 0; i < numverts; i++, mv++) - gotBytes = gzread(gzf, mv->co, sizeof(float) * 3); - - /* should be the same as numverts */ - gotBytes = gzread(gzf, &wri, sizeof(wri)); - if (wri != numverts) { - if (mesh) - BKE_id_free(NULL, mesh); - gzclose(gzf); - return NULL; - } - - normals = MEM_calloc_arrayN(numverts, 3 * sizeof(short), "fluid_tmp_normals"); - if (!normals) { - if (mesh) - BKE_id_free(NULL, mesh); - gzclose(gzf); - return NULL; - } - - /* read normals from file (but don't save them yet) */ - for (i = numverts, no_s = normals; i > 0; i--, no_s += 3) { - gotBytes = gzread(gzf, no, sizeof(float) * 3); - normal_float_to_short_v3(no_s, no); - } - - /* read no. of triangles */ - gotBytes = gzread(gzf, &wri, sizeof(wri)); - - if (wri != numfaces) { - printf("Fluidsim: error in reading data from file.\n"); - if (mesh) - BKE_id_free(NULL, mesh); - gzclose(gzf); - MEM_freeN(normals); - return NULL; - } - - /* read triangles from file */ - mp = mesh->mpoly; - ml = mesh->mloop; - for (i = 0; i < numfaces; i++, mp++, ml += 3) { - int face[3]; - - gotBytes = gzread(gzf, face, sizeof(int) * 3); - - /* initialize from existing face */ - mp->mat_nr = mp_mat_nr; - mp->flag = mp_flag; - - mp->loopstart = i * 3; - mp->totloop = 3; - - ml[0].v = face[0]; - ml[1].v = face[1]; - ml[2].v = face[2]; - - } - - gzclose(gzf); - - BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_apply_vert_normals(mesh, (short (*)[3])normals); - MEM_freeN(normals); - - // CDDM_calc_normals(result); - return mesh; + int wri = 0, i; + int gotBytes; + gzFile gzf; + int numverts = 0, numfaces = 0; + Mesh *mesh = NULL; + MPoly *mp; + MLoop *ml; + MVert *mv; + short *normals, *no_s; + float no[3]; + + const short mp_mat_nr = mp_example->mat_nr; + const char mp_flag = mp_example->flag; + + /* ------------------------------------------------ + * get numverts + numfaces first + * ------------------------------------------------ */ + gzf = BLI_gzopen(filename, "rb"); + if (!gzf) { + return NULL; + } + + /* read numverts */ + gotBytes = gzread(gzf, &wri, sizeof(wri)); + numverts = wri; + + /* skip verts */ + gotBytes = gzseek(gzf, numverts * 3 * sizeof(float), SEEK_CUR) != -1; + + /* read number of normals */ + if (gotBytes) + gotBytes = gzread(gzf, &wri, sizeof(wri)); + + /* skip normals */ + gotBytes = gzseek(gzf, numverts * 3 * sizeof(float), SEEK_CUR) != -1; + + /* get no. of triangles */ + if (gotBytes) + gotBytes = gzread(gzf, &wri, sizeof(wri)); + numfaces = wri; + + gzclose(gzf); + /* ------------------------------------------------ */ + + if (!numfaces || !numverts || !gotBytes) + return NULL; + + gzf = BLI_gzopen(filename, "rb"); + if (!gzf) { + return NULL; + } + + mesh = BKE_mesh_new_nomain(numverts, 0, 0, numfaces * 3, numfaces); + + if (!mesh) { + gzclose(gzf); + return NULL; + } + + /* read numverts */ + gotBytes = gzread(gzf, &wri, sizeof(wri)); + + /* read vertex position from file */ + mv = mesh->mvert; + + for (i = 0; i < numverts; i++, mv++) + gotBytes = gzread(gzf, mv->co, sizeof(float) * 3); + + /* should be the same as numverts */ + gotBytes = gzread(gzf, &wri, sizeof(wri)); + if (wri != numverts) { + if (mesh) + BKE_id_free(NULL, mesh); + gzclose(gzf); + return NULL; + } + + normals = MEM_calloc_arrayN(numverts, 3 * sizeof(short), "fluid_tmp_normals"); + if (!normals) { + if (mesh) + BKE_id_free(NULL, mesh); + gzclose(gzf); + return NULL; + } + + /* read normals from file (but don't save them yet) */ + for (i = numverts, no_s = normals; i > 0; i--, no_s += 3) { + gotBytes = gzread(gzf, no, sizeof(float) * 3); + normal_float_to_short_v3(no_s, no); + } + + /* read no. of triangles */ + gotBytes = gzread(gzf, &wri, sizeof(wri)); + + if (wri != numfaces) { + printf("Fluidsim: error in reading data from file.\n"); + if (mesh) + BKE_id_free(NULL, mesh); + gzclose(gzf); + MEM_freeN(normals); + return NULL; + } + + /* read triangles from file */ + mp = mesh->mpoly; + ml = mesh->mloop; + for (i = 0; i < numfaces; i++, mp++, ml += 3) { + int face[3]; + + gotBytes = gzread(gzf, face, sizeof(int) * 3); + + /* initialize from existing face */ + mp->mat_nr = mp_mat_nr; + mp->flag = mp_flag; + + mp->loopstart = i * 3; + mp->totloop = 3; + + ml[0].v = face[0]; + ml[1].v = face[1]; + ml[2].v = face[2]; + } + + gzclose(gzf); + + BKE_mesh_calc_edges(mesh, false, false); + BKE_mesh_apply_vert_normals(mesh, (short(*)[3])normals); + MEM_freeN(normals); + + // CDDM_calc_normals(result); + return mesh; } - -void fluid_get_bb( - MVert *mvert, int totvert, float obmat[4][4], - /*RET*/ float start[3], /*RET*/ float size[3]) +void fluid_get_bb(MVert *mvert, + int totvert, + float obmat[4][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]; - - if (totvert == 0) { - zero_v3(start); - zero_v3(size); - return; - } - - copy_v3_v3(vec, mvert[0].co); - mul_m4_v3(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++) { - copy_v3_v3(vec, mvert[i].co); - mul_m4_v3(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; - } + 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]; + + if (totvert == 0) { + zero_v3(start); + zero_v3(size); + return; + } + + copy_v3_v3(vec, mvert[0].co); + mul_m4_v3(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++) { + copy_v3_v3(vec, mvert[i].co); + mul_m4_v3(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; + } } //------------------------------------------------------------------------------- @@ -346,206 +358,209 @@ void fluid_get_bb( void fluid_estimate_memory(Object *ob, FluidsimSettings *fss, char *value) { - Mesh *mesh; + Mesh *mesh; - value[0] = '\0'; + value[0] = '\0'; - if (ob->type == OB_MESH) { - /* use mesh bounding box and object scaling */ - mesh = ob->data; + if (ob->type == OB_MESH) { + /* use mesh bounding box and object scaling */ + mesh = ob->data; - fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize); - elbeemEstimateMemreq(fss->resolutionxyz, fss->bbSize[0], fss->bbSize[1], fss->bbSize[2], fss->maxRefine, value); - } + fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize); + elbeemEstimateMemreq( + fss->resolutionxyz, fss->bbSize[0], fss->bbSize[1], fss->bbSize[2], fss->maxRefine, value); + } } - /* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */ static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, Mesh *mesh, char *filename) { - int wri, i, j; - float wrf; - gzFile gzf; - FluidsimSettings *fss = fluidmd->fss; - int len = strlen(filename); - int totvert = mesh->totvert; - FluidVertexVelocity *velarray = NULL; - - /* mesh and vverts have to be valid from loading... */ - - if (fss->meshVelocities) - MEM_freeN(fss->meshVelocities); - - if (len < 7) { - return; - } - - if (fss->domainNovecgen > 0) return; - - fss->meshVelocities = MEM_calloc_arrayN(mesh->totvert, sizeof(FluidVertexVelocity), "Fluidsim_velocities"); - fss->totvert = totvert; - - velarray = fss->meshVelocities; - - /* .bobj.gz, correct filename - * 87654321 */ - filename[len - 6] = 'v'; - filename[len - 5] = 'e'; - filename[len - 4] = 'l'; - - gzf = BLI_gzopen(filename, "rb"); - if (!gzf) { - MEM_freeN(fss->meshVelocities); - fss->meshVelocities = NULL; - return; - } - - gzread(gzf, &wri, sizeof(wri)); - if (wri != totvert) { - MEM_freeN(fss->meshVelocities); - fss->meshVelocities = NULL; - return; - } - - for (i = 0; i < totvert; i++) { - for (j = 0; j < 3; j++) { - gzread(gzf, &wrf, sizeof(wrf)); - velarray[i].vel[j] = wrf; - } - } - - gzclose(gzf); + int wri, i, j; + float wrf; + gzFile gzf; + FluidsimSettings *fss = fluidmd->fss; + int len = strlen(filename); + int totvert = mesh->totvert; + FluidVertexVelocity *velarray = NULL; + + /* mesh and vverts have to be valid from loading... */ + + if (fss->meshVelocities) + MEM_freeN(fss->meshVelocities); + + if (len < 7) { + return; + } + + if (fss->domainNovecgen > 0) + return; + + fss->meshVelocities = MEM_calloc_arrayN( + mesh->totvert, sizeof(FluidVertexVelocity), "Fluidsim_velocities"); + fss->totvert = totvert; + + velarray = fss->meshVelocities; + + /* .bobj.gz, correct filename + * 87654321 */ + filename[len - 6] = 'v'; + filename[len - 5] = 'e'; + filename[len - 4] = 'l'; + + gzf = BLI_gzopen(filename, "rb"); + if (!gzf) { + MEM_freeN(fss->meshVelocities); + fss->meshVelocities = NULL; + return; + } + + gzread(gzf, &wri, sizeof(wri)); + if (wri != totvert) { + MEM_freeN(fss->meshVelocities); + fss->meshVelocities = NULL; + return; + } + + for (i = 0; i < totvert; i++) { + for (j = 0; j < 3; j++) { + gzread(gzf, &wrf, sizeof(wrf)); + velarray[i].vel[j] = wrf; + } + } + + gzclose(gzf); } static Mesh *fluidsim_read_cache( - Object *ob, Mesh *orgmesh, - FluidsimModifierData *fluidmd, int framenr, int useRenderParams) + Object *ob, Mesh *orgmesh, FluidsimModifierData *fluidmd, int framenr, int useRenderParams) { - int curFrame = framenr /* - 1 */ /*scene->r.sfra*/; /* start with 0 at start frame */ - /* why start with 0 as start frame?? Animations + time are frozen for frame 0 anyway. (See physics_fluid.c for that. - DG */ - /* If we start with frame 0, we need to remap all animation channels, too, because they will all be 1 frame late if using frame-1! - DG */ - - char targetFile[FILE_MAX]; - FluidsimSettings *fss = fluidmd->fss; - Mesh *newmesh = NULL; - MPoly *mpoly; - MPoly mp_example = {0}; - - const int displaymode = useRenderParams ? fss->renderDisplayMode : fss->guiDisplayMode; - - switch (displaymode) { - case OB_FSDOM_GEOM: - /* just display original object */ - return NULL; - case OB_FSDOM_PREVIEW: - /* use preview mesh */ - BLI_join_dirfile(targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_PREVIEW_OBJ_FNAME); - break; - case OB_FSDOM_FINAL: - /* use final mesh */ - BLI_join_dirfile(targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME); - break; - default: - BLI_assert(!"Wrong fluidsim display type"); - return NULL; - } - - /* offset baked frame */ - curFrame += fss->frameOffset; - - BLI_path_abs(targetFile, modifier_path_relbase_from_global(ob)); - BLI_path_frame(targetFile, curFrame, 0); // fixed #frame-no - - /* assign material + flags to new mesh. - * if there's no faces in original mesh, keep materials and flags unchanged */ - mpoly = orgmesh->mpoly; - if (mpoly) { - mp_example = *mpoly; - } - /* else leave NULL'd */ - - newmesh = fluidsim_read_obj(targetFile, &mp_example); - - if (!newmesh) { - /* switch, abort background rendering when fluidsim mesh is missing */ - const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp - - if (G.background == 1) { - if (BLI_getenv(strEnvName2)) { - int elevel = atoi(BLI_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 new mesh */ - 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 == OB_FSDOM_FINAL) { - fluidsim_read_vel_cache(fluidmd, newmesh, targetFile); - } - else { - if (fss->meshVelocities) - MEM_freeN(fss->meshVelocities); - - fss->meshVelocities = NULL; - } - - return newmesh; + int curFrame = framenr /* - 1 */ /*scene->r.sfra*/; /* start with 0 at start frame */ + /* why start with 0 as start frame?? Animations + time are frozen for frame 0 anyway. (See physics_fluid.c for that. - DG */ + /* If we start with frame 0, we need to remap all animation channels, too, because they will all be 1 frame late if using frame-1! - DG */ + + char targetFile[FILE_MAX]; + FluidsimSettings *fss = fluidmd->fss; + Mesh *newmesh = NULL; + MPoly *mpoly; + MPoly mp_example = {0}; + + const int displaymode = useRenderParams ? fss->renderDisplayMode : fss->guiDisplayMode; + + switch (displaymode) { + case OB_FSDOM_GEOM: + /* just display original object */ + return NULL; + case OB_FSDOM_PREVIEW: + /* use preview mesh */ + BLI_join_dirfile( + targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_PREVIEW_OBJ_FNAME); + break; + case OB_FSDOM_FINAL: + /* use final mesh */ + BLI_join_dirfile( + targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME); + break; + default: + BLI_assert(!"Wrong fluidsim display type"); + return NULL; + } + + /* offset baked frame */ + curFrame += fss->frameOffset; + + BLI_path_abs(targetFile, modifier_path_relbase_from_global(ob)); + BLI_path_frame(targetFile, curFrame, 0); // fixed #frame-no + + /* assign material + flags to new mesh. + * if there's no faces in original mesh, keep materials and flags unchanged */ + mpoly = orgmesh->mpoly; + if (mpoly) { + mp_example = *mpoly; + } + /* else leave NULL'd */ + + newmesh = fluidsim_read_obj(targetFile, &mp_example); + + if (!newmesh) { + /* switch, abort background rendering when fluidsim mesh is missing */ + const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp + + if (G.background == 1) { + if (BLI_getenv(strEnvName2)) { + int elevel = atoi(BLI_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 new mesh */ + 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 == OB_FSDOM_FINAL) { + fluidsim_read_vel_cache(fluidmd, newmesh, targetFile); + } + else { + if (fss->meshVelocities) + MEM_freeN(fss->meshVelocities); + + fss->meshVelocities = NULL; + } + + return newmesh; } -#endif // WITH_MOD_FLUID +#endif // WITH_MOD_FLUID -Mesh *fluidsimModifier_do( - FluidsimModifierData *fluidmd, - const ModifierEvalContext *ctx, - Mesh *mesh) +Mesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, + const ModifierEvalContext *ctx, + Mesh *mesh) { #ifdef WITH_MOD_FLUID - Object *ob = ctx->object; - Depsgraph *depsgraph = ctx->depsgraph; - const bool useRenderParams = (ctx->flag & MOD_APPLY_RENDER) != 0; -// const bool isFinalCalc = (ctx->flag & MOD_APPLY_USECACHE) != 0; - Mesh *result = NULL; - int framenr; - FluidsimSettings *fss = NULL; + Object *ob = ctx->object; + Depsgraph *depsgraph = ctx->depsgraph; + const bool useRenderParams = (ctx->flag & MOD_APPLY_RENDER) != 0; + // const bool isFinalCalc = (ctx->flag & MOD_APPLY_USECACHE) != 0; + Mesh *result = NULL; + int framenr; + FluidsimSettings *fss = NULL; - framenr = (int)DEG_get_ctime(depsgraph); + framenr = (int)DEG_get_ctime(depsgraph); - /* only handle fluidsim domains */ - if (fluidmd && fluidmd->fss && (fluidmd->fss->type != OB_FLUIDSIM_DOMAIN)) - return mesh; + /* only handle fluidsim domains */ + if (fluidmd && fluidmd->fss && (fluidmd->fss->type != OB_FLUIDSIM_DOMAIN)) + return mesh; - /* sanity check */ - if (!fluidmd || !fluidmd->fss) - return mesh; + /* sanity check */ + if (!fluidmd || !fluidmd->fss) + return mesh; - fss = fluidmd->fss; + fss = fluidmd->fss; - /* timescale not supported yet - * clmd->sim_parms->timescale = timescale; */ + /* timescale not supported yet + * clmd->sim_parms->timescale = timescale; */ - /* support reversing of baked fluid frames here */ - if ((fss->flag & OB_FLUIDSIM_REVERSE) && (fss->lastgoodframe >= 0)) { - framenr = fss->lastgoodframe - framenr + 1; - CLAMP(framenr, 1, fss->lastgoodframe); - } + /* support reversing of baked fluid frames here */ + if ((fss->flag & OB_FLUIDSIM_REVERSE) && (fss->lastgoodframe >= 0)) { + framenr = fss->lastgoodframe - framenr + 1; + CLAMP(framenr, 1, fss->lastgoodframe); + } - /* try to read from cache */ - /* if the frame is there, fine, otherwise don't do anything */ - if ((result = fluidsim_read_cache(ob, mesh, fluidmd, framenr, useRenderParams))) - return result; + /* try to read from cache */ + /* if the frame is there, fine, otherwise don't do anything */ + if ((result = fluidsim_read_cache(ob, mesh, fluidmd, framenr, useRenderParams))) + return result; - return mesh; + return mesh; #else - /* unused */ - UNUSED_VARS(fluidmd, ctx, mesh); - return NULL; + /* unused */ + UNUSED_VARS(fluidmd, ctx, mesh); + return NULL; #endif } |