Fluid control: WIP commit before weekend, not working is crashing on the first 3 frames
This commit is contained in:
parent
9bf0bfcae7
commit
d7fecc9e96
@ -166,8 +166,8 @@ CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing']
|
||||
|
||||
CPPFLAGS = ['-DXP_UNIX']
|
||||
CXXFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing']
|
||||
REL_CFLAGS = ['-O2']
|
||||
REL_CCFLAGS = ['-O2']
|
||||
REL_CFLAGS = ['-O3']
|
||||
REL_CCFLAGS = ['-O3']
|
||||
##BF_DEPEND = 'true'
|
||||
##
|
||||
##AR = ar
|
||||
|
5
intern/elbeem/extern/elbeem.h
vendored
5
intern/elbeem/extern/elbeem.h
vendored
@ -32,7 +32,7 @@ typedef struct elbeemSimulationSettings {
|
||||
short version;
|
||||
/* id number of simulation domain, needed if more than a
|
||||
* single domain should be simulated */
|
||||
short domainId;
|
||||
short domainId; // unused within blender
|
||||
|
||||
/* geometrical extent */
|
||||
float geoStart[3], geoSize[3];
|
||||
@ -187,6 +187,9 @@ void elbeemResetSettings(struct elbeemSimulationSettings*);
|
||||
// start fluidsim init (returns !=0 upon failure)
|
||||
int elbeemInit(void);
|
||||
|
||||
// frees fluidsim
|
||||
int elbeemFree(void);
|
||||
|
||||
// start fluidsim init (returns !=0 upon failure)
|
||||
int elbeemAddDomain(struct elbeemSimulationSettings*);
|
||||
|
||||
|
@ -57,6 +57,7 @@ void ControlParticles::initBlenderTest() {
|
||||
initTime(0. , 1.);
|
||||
}
|
||||
|
||||
// blender control object gets converted to mvm flui control object
|
||||
int ControlParticles::initFromObject(ntlGeometryObjModel *model) {
|
||||
vector<ntlTriangle> triangles;
|
||||
vector<ntlVec3Gfx> vertices;
|
||||
@ -73,6 +74,7 @@ int ControlParticles::initFromObject(ntlGeometryObjModel *model) {
|
||||
printf("a animated? %d\n", model->getIsAnimated());
|
||||
printf("b animated? %d\n", model->getMeshAnimated());
|
||||
*/
|
||||
|
||||
model->setGeoInitType(FGI_FLUID);
|
||||
|
||||
model->getTriangles(mCPSTimeStart, &triangles, &vertices, &normals, 1 );
|
||||
@ -137,7 +139,7 @@ int ControlParticles::initFromObject(ntlGeometryObjModel *model) {
|
||||
// init first set, check dist
|
||||
ControlParticleSet firstcps; //T
|
||||
mPartSets.push_back(firstcps);
|
||||
mPartSets[mPartSets.size()-1].time = (gfxReal)0.;
|
||||
mPartSets[mPartSets.size()-1].time = mCPSTimeStart;
|
||||
vector<bool> useCP;
|
||||
|
||||
for(int i=0; i<(int)inspos.size(); i++) {
|
||||
@ -1378,8 +1380,10 @@ void ControlParticles::calculateCpInfluenceOpt(ControlParticle *cp, LbmVec fluid
|
||||
#if (CP_PROJECT2D==1) && (defined(MAIN_2D) || LBMDIM==2)
|
||||
// fillFactor *= 2.0 *0.75 * pdistance; // 2d>3d sampling
|
||||
#endif // (CP_PROJECT2D==1) && (defined(MAIN_2D) || LBMDIM==2)
|
||||
|
||||
LbmFloat signum = getInfluenceAttraction() > 0.0 ? 1.0 : -1.0;
|
||||
cp->density += falloffAtt * fillFactor;
|
||||
force->forceAtt += posDelta *cp->densityWeight *cp->influence;
|
||||
force->forceAtt += posDelta *cp->densityWeight *cp->influence *signum;
|
||||
force->weightAtt += falloffAtt*cp->densityWeight *cp->influence;
|
||||
|
||||
LbmFloat falloffVel = 0.; //CPKernel::kernel(cpfo * 1.0, pdistance);
|
||||
|
@ -96,6 +96,13 @@ int elbeemInit() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fluidsim end
|
||||
extern "C"
|
||||
int elbeemFree() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// start fluidsim init
|
||||
extern "C"
|
||||
int elbeemAddDomain(elbeemSimulationSettings *settings) {
|
||||
@ -253,6 +260,7 @@ int elbeemSimulate(void) {
|
||||
if(getElbeemState() != SIMWORLD_STOP) {
|
||||
// ok, we're done...
|
||||
delete gpWorld;
|
||||
|
||||
gpWorld = NULL;
|
||||
debMsgStd("elbeemSimulate",DM_NOTIFY, "El'Beem simulation done, time: "<<getTimeString(timeend-timestart)<<".\n", 2 );
|
||||
} else {
|
||||
|
@ -688,7 +688,8 @@ ntlScene::~ntlScene()
|
||||
if(mpTree != NULL) delete mpTree;
|
||||
|
||||
// cleanup lists, only if this is the rendering cleanup scene
|
||||
if(mSceneDel) {
|
||||
if(mSceneDel)
|
||||
{
|
||||
for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin();
|
||||
iter != mGeos.end(); iter++) {
|
||||
//errMsg("ntlScene::~ntlScene","Deleting obj "<<(*iter)->getName() );
|
||||
|
@ -236,10 +236,15 @@ ntlWorld::~ntlWorld()
|
||||
{
|
||||
delete mpGlob->getRenderScene();
|
||||
delete mpGlob->getSimScene();
|
||||
delete mpGlob;
|
||||
delete mpLightList;
|
||||
delete mpPropList;
|
||||
delete mpSims;
|
||||
|
||||
delete mpGlob;
|
||||
|
||||
|
||||
// these get assigned to mpGlob but not freed there
|
||||
delete mpLightList;
|
||||
delete mpPropList; // materials
|
||||
delete mpSims;
|
||||
|
||||
#ifndef NOGUI
|
||||
if(mpOpenGLRenderer) delete mpOpenGLRenderer;
|
||||
#endif // NOGUI
|
||||
@ -895,6 +900,8 @@ ntlRenderGlobals::ntlRenderGlobals() :
|
||||
ntlRenderGlobals::~ntlRenderGlobals() {
|
||||
if(mpOpenGlAttr) delete mpOpenGlAttr;
|
||||
if(mpBlenderAttr) delete mpBlenderAttr;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -236,7 +236,6 @@ LbmFsgrSolver::initCpdata()
|
||||
// dont load any file
|
||||
cset->mContrPartFile = string("");
|
||||
|
||||
// TODO dg: switch to channels later
|
||||
cset->mcForceAtt = obj->getCpsAttrFStr();
|
||||
cset->mcRadiusAtt = obj->getCpsAttrFRad();
|
||||
cset->mcForceVel = obj->getCpsVelFStr();
|
||||
@ -491,8 +490,8 @@ LbmFsgrSolver::handleCpdata()
|
||||
// init for current time
|
||||
for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) {
|
||||
ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts;
|
||||
|
||||
LbmControlSet *cset = mpControl->mCons[cpssi];
|
||||
|
||||
cparts->setRadiusAtt(cset->mcRadiusAtt.get(mSimulationTime));
|
||||
cparts->setRadiusVel(cset->mcRadiusVel.get(mSimulationTime));
|
||||
cparts->setInfluenceAttraction(cset->mcForceAtt.get(mSimulationTime) );
|
||||
@ -506,18 +505,22 @@ LbmFsgrSolver::handleCpdata()
|
||||
cparts->setInfluenceVelocity( cset->mcForceVel.get(mSimulationTime), mLevel[fineLev].timestep );
|
||||
cparts->setLastOffset( vec2L(cset->mcCpOffset.get(mSimulationTime-mLevel[fineLev].timestep)) );
|
||||
cparts->setLastScale( vec2L(cset->mcCpScale.get(mSimulationTime-mLevel[fineLev].timestep)) );
|
||||
|
||||
}
|
||||
|
||||
// check actual values
|
||||
LbmFloat iatt = mpControl->mCons[0]->mCparts->getInfluenceAttraction();
|
||||
LbmFloat iatt = ABS(mpControl->mCons[0]->mCparts->getInfluenceAttraction());
|
||||
LbmFloat ivel = mpControl->mCons[0]->mCparts->getInfluenceVelocity();
|
||||
LbmFloat imaxd = mpControl->mCons[0]->mCparts->getInfluenceMaxdist();
|
||||
//errMsg("FINCIT","iatt="<<iatt<<" ivel="<<ivel<<" imaxd="<<imaxd);
|
||||
for(int cpssi=1; cpssi<(int)mpControl->mCons.size(); cpssi++) {
|
||||
LbmFloat iatt2 = mpControl->mCons[cpssi]->mCparts->getInfluenceAttraction();
|
||||
LbmFloat iatt2 = ABS(mpControl->mCons[cpssi]->mCparts->getInfluenceAttraction());
|
||||
LbmFloat ivel2 = mpControl->mCons[cpssi]->mCparts->getInfluenceVelocity();
|
||||
LbmFloat imaxd2 = mpControl->mCons[cpssi]->mCparts->getInfluenceMaxdist();
|
||||
if(iatt2 >iatt) iatt = iatt2;
|
||||
|
||||
// we allow negative attraction force here!
|
||||
if(iatt2 > iatt) iatt = iatt2;
|
||||
|
||||
if(ivel2 >ivel) ivel = ivel2;
|
||||
if(imaxd2>imaxd) imaxd= imaxd2;
|
||||
//errMsg("FINCIT"," "<<cpssi<<" iatt2="<<iatt2<<" ivel2="<<ivel2<<" imaxd2="<<imaxd<<" NEW "<<" iatt="<<iatt<<" ivel="<<ivel<<" imaxd="<<imaxd);
|
||||
@ -581,6 +584,12 @@ LbmFsgrSolver::handleCpdata()
|
||||
for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) {
|
||||
ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts;
|
||||
// ControlParticles *cpmotion = mpControl->mCons[cpssi]->mCpmotion;
|
||||
|
||||
// if control set is not active skip it
|
||||
if((cparts->getControlTimStart() > mSimulationTime) || (cparts->getControlTimEnd() < mLastSimTime))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const LbmFloat velLatticeScale = mLevel[lev].timestep/mLevel[lev].nodeSize;
|
||||
LbmFloat gsx = ((mvGeoEnd[0]-mvGeoStart[0])/(LbmFloat)mLevel[lev].lSizex);
|
||||
|
@ -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
|
||||
|
57
source/blender/blenkernel/BKE_fluidsim.h
Normal file
57
source/blender/blenkernel/BKE_fluidsim.h
Normal file
@ -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] );
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
702
source/blender/blenkernel/intern/fluidsim.c
Normal file
702
source/blender/blenkernel/intern/fluidsim.c
Normal file
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
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
|
||||
|
||||
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++;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3016,10 +3016,6 @@ static void lib_link_object(FileData *fd, Main *main)
|
||||
}
|
||||
act= act->next;
|
||||
}
|
||||
|
||||
if(ob->fluidsimSettings) {
|
||||
ob->fluidsimSettings->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
|
||||
}
|
||||
|
||||
/* texture field */
|
||||
if(ob->pd)
|
||||
@ -3093,6 +3089,12 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
}
|
||||
|
||||
}
|
||||
else if (md->type==eModifierType_Fluidsim) {
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
|
||||
|
||||
fluidmd->fss= newdataadr(fd, fluidmd->fss);
|
||||
fluidmd->fss->ipo = newlibadr_us(fd, lb, fluidmd->fss->ipo);
|
||||
}
|
||||
else if (md->type==eModifierType_Collision) {
|
||||
|
||||
CollisionModifierData *collmd = (CollisionModifierData*) md;
|
||||
@ -3279,13 +3281,6 @@ static void direct_link_object(FileData *fd, Object *ob)
|
||||
direct_link_pointcache(fd, sb->pointcache);
|
||||
}
|
||||
ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
|
||||
if(ob->fluidsimSettings) {
|
||||
// reinit mesh pointers
|
||||
ob->fluidsimSettings->orgMesh = NULL; //ob->data;
|
||||
ob->fluidsimSettings->meshSurface = NULL;
|
||||
ob->fluidsimSettings->meshBB = NULL;
|
||||
ob->fluidsimSettings->meshSurfNormals = NULL;
|
||||
}
|
||||
|
||||
link_list(fd, &ob->particlesystem);
|
||||
direct_link_particlesystems(fd,&ob->particlesystem);
|
||||
@ -7493,8 +7488,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
}
|
||||
}
|
||||
|
||||
if(ob->fluidsimSettings && ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE)
|
||||
part->type = PART_FLUID;
|
||||
|
||||
{
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
if(fluidmd && fluidmd->fss && fluidmd->fss->type == OB_FLUIDSIM_PARTICLE)
|
||||
part->type = PART_FLUID;
|
||||
}
|
||||
|
||||
free_effects(&ob->effect);
|
||||
|
||||
@ -7663,6 +7662,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
la->sun_intensity = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// convert fluids to modifier
|
||||
if(main->versionfile <= 246 && main->subversionfile < 1)
|
||||
{
|
||||
Object *ob;
|
||||
|
||||
for(ob = main->object.first; ob; ob= ob->id.next) {
|
||||
if(ob->fluidsimSettings)
|
||||
{
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifier_new(eModifierType_Fluidsim);
|
||||
BLI_addhead(&ob->modifiers, (ModifierData *)fluidmd);
|
||||
|
||||
MEM_freeN(fluidmd->fss);
|
||||
fluidmd->fss = MEM_dupallocN(ob->fluidsimSettings);
|
||||
fluidmd->fss->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
|
||||
MEM_freeN(ob->fluidsimSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
|
||||
|
@ -846,6 +846,11 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
|
||||
writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
|
||||
writestruct(wd, DATA, "PointCache", 1, clmd->point_cache);
|
||||
}
|
||||
else if(md->type==eModifierType_Fluidsim) {
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
|
||||
|
||||
writestruct(wd, DATA, "FluidsimSettings", 1, fluidmd->fss);
|
||||
}
|
||||
else if (md->type==eModifierType_Collision) {
|
||||
|
||||
/*
|
||||
@ -911,7 +916,6 @@ static void write_objects(WriteData *wd, ListBase *idbase)
|
||||
writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
|
||||
writestruct(wd, DATA, "SoftBody", 1, ob->soft);
|
||||
if(ob->soft) writestruct(wd, DATA, "PointCache", 1, ob->soft->pointcache);
|
||||
writestruct(wd, DATA, "FluidsimSettings", 1, ob->fluidsimSettings); // NT
|
||||
|
||||
write_particlesystems(wd, &ob->particlesystem);
|
||||
write_modifiers(wd, &ob->modifiers);
|
||||
|
@ -35,6 +35,7 @@ typedef enum ModifierType {
|
||||
eModifierType_Cloth,
|
||||
eModifierType_Collision,
|
||||
eModifierType_Bevel,
|
||||
eModifierType_Fluidsim,
|
||||
NUM_MODIFIER_TYPES
|
||||
} ModifierType;
|
||||
|
||||
@ -490,4 +491,11 @@ typedef struct ExplodeModifierData {
|
||||
float protect;
|
||||
} ExplodeModifierData;
|
||||
|
||||
typedef struct FluidsimModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
struct FluidsimSettings *fss; /* definition is is DNA_object_fluidsim.h */
|
||||
struct PointCache *point_cache; /* definition is in DNA_object_force.h */
|
||||
} FluidsimModifierData;
|
||||
|
||||
#endif
|
||||
|
@ -128,7 +128,7 @@ typedef struct FluidsimSettings {
|
||||
float velocityforceStrength;
|
||||
float velocityforceRadius;
|
||||
|
||||
int pad;
|
||||
int lastgoodframe;
|
||||
|
||||
} FluidsimSettings;
|
||||
|
||||
|
@ -674,94 +674,6 @@ static void calc_vertexnormals(Render *re, ObjectRen *obr, int do_tangent, int d
|
||||
MEM_freeN(vtangents);
|
||||
}
|
||||
|
||||
// NT same as calc_vertexnormals, but dont modify the existing vertex normals
|
||||
// only recalculate other render data. If this is at some point used for other things than fluidsim,
|
||||
// this could be made on option for the normal calc_vertexnormals
|
||||
static void calc_fluidsimnormals(Render *re, ObjectRen *obr, int do_nmap_tangent)
|
||||
{
|
||||
int a;
|
||||
|
||||
/* dont clear vertex normals here */
|
||||
// OFF for(a=0; a<obr->totvert; a++) { VertRen *ver= RE_findOrAddVert(obr, a); ver->n[0]=ver->n[1]=ver->n[2]= 0.0; }
|
||||
/* calculate cos of angles and point-masses, use as weight factor to add face normal to vertex */
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
VlakRen *vlr= RE_findOrAddVlak(obr, a);
|
||||
if(vlr->flag & ME_SMOOTH) {
|
||||
VertRen *v1= vlr->v1;
|
||||
VertRen *v2= vlr->v2;
|
||||
VertRen *v3= vlr->v3;
|
||||
VertRen *v4= vlr->v4;
|
||||
float n1[3], n2[3], n3[3], n4[3];
|
||||
float fac1, fac2, fac3, fac4=0.0f;
|
||||
|
||||
if(re->flag & R_GLOB_NOPUNOFLIP)
|
||||
vlr->flag |= R_NOPUNOFLIP;
|
||||
|
||||
VecSubf(n1, v2->co, v1->co);
|
||||
Normalize(n1);
|
||||
VecSubf(n2, v3->co, v2->co);
|
||||
Normalize(n2);
|
||||
if(v4==NULL) {
|
||||
VecSubf(n3, v1->co, v3->co);
|
||||
Normalize(n3);
|
||||
fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
|
||||
fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
|
||||
fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
|
||||
}
|
||||
else {
|
||||
VecSubf(n3, v4->co, v3->co);
|
||||
Normalize(n3);
|
||||
VecSubf(n4, v1->co, v4->co);
|
||||
Normalize(n4);
|
||||
|
||||
fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
|
||||
fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
|
||||
fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
|
||||
fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
|
||||
|
||||
if(!(vlr->flag & R_NOPUNOFLIP)) {
|
||||
if( check_vnormal(vlr->n, v4->n) ) fac4= -fac4;
|
||||
}
|
||||
}
|
||||
|
||||
//if(do_nmap_tangent)
|
||||
// calc_tangent_vector(obr, vlr, fac1, fac2, fac3, fac4);
|
||||
}
|
||||
if(do_nmap_tangent) {
|
||||
/* tangents still need to be calculated for flat faces too */
|
||||
/* weighting removed, they are not vertexnormals */
|
||||
//calc_tangent_vector(obr, vlr);
|
||||
}
|
||||
}
|
||||
|
||||
/* do solid faces */
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
VlakRen *vlr= RE_findOrAddVlak(obr, a);
|
||||
if((vlr->flag & ME_SMOOTH)==0) {
|
||||
float *f1= vlr->v1->n;
|
||||
if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
|
||||
f1= vlr->v2->n;
|
||||
if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
|
||||
f1= vlr->v3->n;
|
||||
if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
|
||||
if(vlr->v4) {
|
||||
f1= vlr->v4->n;
|
||||
if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* normalize vertex normals */
|
||||
for(a=0; a<obr->totvert; a++) {
|
||||
VertRen *ver= RE_findOrAddVert(obr, a);
|
||||
Normalize(ver->n);
|
||||
if(do_nmap_tangent) {
|
||||
float *tav= RE_vertren_get_tangent(obr, ver, 0);
|
||||
if(tav) Normalize(tav);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Autosmoothing: */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -3171,12 +3083,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
|
||||
}
|
||||
}
|
||||
|
||||
if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
|
||||
(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
|
||||
(ob->fluidsimSettings->meshSurface) ) {
|
||||
useFluidmeshNormals = 1;
|
||||
}
|
||||
|
||||
mvert= dm->getVertArray(dm);
|
||||
totvert= dm->getNumVerts(dm);
|
||||
|
||||
@ -3199,17 +3105,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
|
||||
if(do_autosmooth==0) /* autosmooth on original unrotated data to prevent differences between frames */
|
||||
MTC_Mat4MulVecfl(mat, ver->co);
|
||||
|
||||
if(useFluidmeshNormals) {
|
||||
/* normals are inverted in render */
|
||||
xn = -mvert->no[0]/ 32767.0;
|
||||
yn = -mvert->no[1]/ 32767.0;
|
||||
zn = -mvert->no[2]/ 32767.0;
|
||||
/* transfor to cam space */
|
||||
ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
|
||||
ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
|
||||
ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
|
||||
} // useFluidmeshNormals
|
||||
|
||||
if(orco) {
|
||||
ver->orco= orco;
|
||||
orco+=3;
|
||||
@ -3389,12 +3284,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
|
||||
autosmooth(re, obr, mat, me->smoothresh);
|
||||
}
|
||||
|
||||
if(useFluidmeshNormals) {
|
||||
// do not recalculate, only init render data
|
||||
calc_fluidsimnormals(re, obr, need_tangent||need_nmap_tangent);
|
||||
} else {
|
||||
calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent);
|
||||
}
|
||||
calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent);
|
||||
|
||||
if(need_stress)
|
||||
calc_edge_stress(re, obr, me);
|
||||
@ -5273,7 +5163,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
|
||||
//fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test
|
||||
for(j=0;j<3;j++) fsvec[j] = vverts[a].co[j];
|
||||
|
||||
/* (bad) HACK insert average velocity if none is there (see previous comment */
|
||||
/* (bad) HACK insert average velocity if none is there (see previous comment) */
|
||||
if((fsvec[0] == 0.0) && (fsvec[1] == 0.0) && (fsvec[2] == 0.0))
|
||||
{
|
||||
fsvec[0] = avgvel[0];
|
||||
@ -5417,6 +5307,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
|
||||
oldobi= table->first;
|
||||
for(obi= re->instancetable.first; obi && oldobi; obi= obi->next) {
|
||||
int ok= 1;
|
||||
FluidsimModifierData *fluidmd;
|
||||
|
||||
if(!(obi->obr->flag & R_NEED_VECTORS))
|
||||
continue;
|
||||
@ -5440,7 +5331,8 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
|
||||
}
|
||||
|
||||
// NT check for fluidsim special treatment
|
||||
if((obi->ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obi->ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)) {
|
||||
fluidmd = (FluidsimModifierData *)modifiers_findByType(obi->ob, eModifierType_Fluidsim);
|
||||
if(fluidmd && fluidmd->fss && (fluidmd->fss->type & OB_FLUIDSIM_DOMAIN)) {
|
||||
// use preloaded per vertex simulation data , only does calculation for step=1
|
||||
// NOTE/FIXME - velocities and meshes loaded unnecessarily often during the database_fromscene_vectors calls...
|
||||
load_fluidsimspeedvectors(re, obi, oldobi->vectors, step);
|
||||
|
@ -985,7 +985,7 @@ static uiBlock *modifiers_add_menu(void *ob_v)
|
||||
/* Only allow adding through appropriate other interfaces */
|
||||
if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
|
||||
|
||||
if(ELEM(i, eModifierType_Cloth, eModifierType_Collision)) continue;
|
||||
if(ELEM3(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Fluidsim)) continue;
|
||||
|
||||
if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
|
||||
(ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
|
||||
@ -1742,7 +1742,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
|
||||
|
||||
// deletion over the deflection panel
|
||||
// fluid particle modifier can't be deleted here
|
||||
if(md->type!=eModifierType_Collision && !modifier_is_fluid_particles(md))
|
||||
if(md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Collision && !modifier_is_fluid_particles(md))
|
||||
{
|
||||
but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
|
||||
uiButSetFunc(but, modifiers_del, ob, md);
|
||||
@ -1826,6 +1826,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
|
||||
height = 94;
|
||||
} else if (md->type==eModifierType_Explode) {
|
||||
height = 94;
|
||||
} else if (md->type==eModifierType_Fluidsim) {
|
||||
height = 31;
|
||||
}
|
||||
/* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
|
||||
uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, "");
|
||||
@ -1843,7 +1845,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
|
||||
uiButSetFunc(but, modifiers_applyModifier, ob, md);
|
||||
}
|
||||
|
||||
if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
|
||||
if (md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
|
||||
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
|
||||
uiButSetFunc(but, modifiers_copyModifier, ob, md);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_cloth.h"
|
||||
#include "BKE_fluidsim.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_library.h"
|
||||
@ -2240,6 +2241,7 @@ void fluidsimFilesel(char *selection)
|
||||
char prefix[FILE_MAXFILE];
|
||||
char *srch, *srchSub, *srchExt, *lastFound;
|
||||
int isElbeemSurf = 0;
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
|
||||
// make prefix
|
||||
strcpy(srcDir, selection);
|
||||
@ -2274,10 +2276,10 @@ void fluidsimFilesel(char *selection)
|
||||
}
|
||||
}
|
||||
|
||||
if(ob->fluidsimSettings) {
|
||||
strcpy(ob->fluidsimSettings->surfdataPath, srcDir);
|
||||
if(fluidmd && fluidmd->fss) {
|
||||
strcpy(fluidmd->fss->surfdataPath, srcDir);
|
||||
//not necessary? strcat(ob->fluidsimSettings->surfdataPath, "/");
|
||||
strcat(ob->fluidsimSettings->surfdataPath, prefix);
|
||||
strcat(fluidmd->fss->surfdataPath, prefix);
|
||||
|
||||
// redraw view & buttons...
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
@ -2381,13 +2383,14 @@ void do_object_panels(unsigned short event)
|
||||
ParticleSystem *psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
|
||||
ModifierData *md;
|
||||
ParticleSystemModifierData *psmd;
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
|
||||
part->type = PART_FLUID;
|
||||
psys->part = part;
|
||||
psys->pointcache = BKE_ptcache_add();
|
||||
psys->flag |= PSYS_ENABLED;
|
||||
|
||||
ob->fluidsimSettings->type = OB_FLUIDSIM_PARTICLE;
|
||||
fluidmd->fss->type = OB_FLUIDSIM_PARTICLE;
|
||||
|
||||
BLI_addtail(&ob->particlesystem,psys);
|
||||
|
||||
@ -2401,7 +2404,9 @@ void do_object_panels(unsigned short event)
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
break;
|
||||
case B_FLUIDSIM_CHANGETYPE:
|
||||
if(ob && ob->particlesystem.first && ob->fluidsimSettings->type!=OB_FLUIDSIM_PARTICLE){
|
||||
{
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
if(ob && ob->particlesystem.first && fluidmd->fss->type!=OB_FLUIDSIM_PARTICLE){
|
||||
ParticleSystem *psys;
|
||||
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
|
||||
if(psys->part->type==PART_FLUID) {
|
||||
@ -2426,20 +2431,16 @@ void do_object_panels(unsigned short event)
|
||||
}
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
break;
|
||||
}
|
||||
case B_FLUIDSIM_SELDIR:
|
||||
{
|
||||
ScrArea *sa = closest_bigger_area();
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
/* choose dir for surface files */
|
||||
areawinset(sa->win);
|
||||
activate_fileselect(FILE_SPECIAL, "Select Directory", ob->fluidsimSettings->surfdataPath, fluidsimFilesel);
|
||||
activate_fileselect(FILE_SPECIAL, "Select Directory", fluidmd->fss->surfdataPath, fluidsimFilesel);
|
||||
}
|
||||
break;
|
||||
case B_FLUIDSIM_FORCEREDRAW:
|
||||
/* force redraw */
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
break;
|
||||
case B_GROUP_RELINK:
|
||||
group_relink_nla_objects(ob);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
@ -4914,6 +4915,53 @@ static void object_panel_particle_system(Object *ob)
|
||||
}
|
||||
|
||||
/* NT - Panel for fluidsim settings */
|
||||
|
||||
static int _can_fluidsim_at_all(Object *ob)
|
||||
{
|
||||
// list of Yes
|
||||
if ((ob->type==OB_MESH)) return 1;
|
||||
// else deny
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Panel for fluidsim */
|
||||
static void object_fluidsim__enabletoggle(void *ob_v, void *arg2)
|
||||
{
|
||||
Object *ob = ob_v;
|
||||
ModifierData *md = modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
|
||||
if (!md) {
|
||||
md = modifier_new(eModifierType_Fluidsim);
|
||||
BLI_addhead(&ob->modifiers, md);
|
||||
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
else {
|
||||
Object *ob = ob_v;
|
||||
ModifierData *md = modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
|
||||
if (!md)
|
||||
return;
|
||||
|
||||
BLI_remlink(&ob->modifiers, md);
|
||||
|
||||
modifier_free(md);
|
||||
|
||||
BIF_undo_push("Del modifier");
|
||||
|
||||
//ob->softflag |= OB_SB_RESET;
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
|
||||
object_handle_update(ob);
|
||||
countall();
|
||||
}
|
||||
}
|
||||
|
||||
static void object_panel_fluidsim(Object *ob)
|
||||
{
|
||||
#ifndef DISABLE_ELBEEM
|
||||
@ -4922,336 +4970,382 @@ static void object_panel_fluidsim(Object *ob)
|
||||
const int lineHeight = 20;
|
||||
const int separateHeight = 3;
|
||||
const int objHeight = 20;
|
||||
char *msg = NULL;
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
int libdata = 0, val = 0;
|
||||
uiBut *but=NULL;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "object_fluidsim", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
if(uiNewPanel(curarea, block, "Fluid", "Physics", 1060, 0, 318, 204)==0) return;
|
||||
|
||||
uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
|
||||
libdata= object_is_libdata(ob);
|
||||
uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
|
||||
|
||||
if(ob->type==OB_MESH) {
|
||||
if(((Mesh *)ob->data)->totvert == 0) {
|
||||
msg = "Mesh has no vertices.";
|
||||
goto errMessage;
|
||||
}
|
||||
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");
|
||||
val = (fluidmd ? 1:0);
|
||||
|
||||
if(!_can_fluidsim_at_all(ob))
|
||||
{
|
||||
uiDefBut(block, LABEL, 0, "Fluidsim can be activated on mesh only.", 10,200,300,20, NULL, 0.0, 0, 0, 0, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Fluidsim", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to participate in fluid simulation");
|
||||
uiButSetFunc(but, object_fluidsim__enabletoggle, ob, NULL);
|
||||
|
||||
if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
|
||||
FluidsimSettings *fss= ob->fluidsimSettings;
|
||||
|
||||
if(fss==NULL) {
|
||||
fss = ob->fluidsimSettings = fluidsimSettingsNew(ob);
|
||||
}
|
||||
|
||||
/*
|
||||
// no pointcache used in fluidsim *YET*
|
||||
md = (ModifierData*)clmd;
|
||||
if(md) {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Domain", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_DOMAIN, 20.0, 1.0, "Bounding box of this object represents the computational domain of the fluid simulation.");
|
||||
uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Fluid", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_FLUID, 20.0, 2.0, "Object represents a volume of fluid in the simulation.");
|
||||
uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Obstacle", 230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OBSTACLE,20.0, 3.0, "Object is a fixed obstacle.");
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Inflow", 90, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_INFLOW, 20.0, 4.0, "Object adds fluid to the simulation.");
|
||||
uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Outflow", 142, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OUTFLOW, 20.0, 5.0, "Object removes fluid from the simulation.");
|
||||
uiDefButS(block, ROW, B_FLUIDSIM_MAKEPART ,"Particle", 194, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_PARTICLE,20.0, 3.0, "Object is made a particle system to display particles generated by a fluidsim domain object.");
|
||||
|
||||
uiDefButS(block, ROW, B_FLUIDSIM_CHANGETYPE ,"Control", 246, yline, 54,objHeight, &fss->type, 15.0, OB_FLUIDSIM_CONTROL,20.0, 3.0, "Object is made a fluid control mesh, which influences the fluid.");
|
||||
uiDefIconButBitI(block, TOG, eModifierMode_Render, B_BAKE_CACHE_CHANGE, ICON_SCENE, 145, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable fluidsim during rendering");
|
||||
but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_BAKE_CACHE_CHANGE, VICON_VIEW3D, 165, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable fluidsim during interactive display");
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if(fluidmd)
|
||||
{
|
||||
FluidsimSettings *fss = fluidmd->fss;
|
||||
|
||||
if(!fss)
|
||||
return;
|
||||
|
||||
/* GENERAL STUFF */
|
||||
/*
|
||||
if(!libdata) {
|
||||
uiClearButLock();
|
||||
if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
|
||||
uiSetButLock(1, "Please leave editmode.");
|
||||
else if(cache->flag & PTCACHE_BAKED)
|
||||
uiSetButLock(1, "Simulation frames are baked");
|
||||
}
|
||||
*/
|
||||
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE ,"Domain", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_DOMAIN, 20.0, 1.0, "Bounding box of this object represents the computational domain of the fluid simulation." );
|
||||
uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE ,"Fluid", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_FLUID, 20.0, 2.0, "Object represents a volume of fluid in the simulation." );
|
||||
uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE ,"Obstacle", 230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OBSTACLE,20.0, 3.0, "Object is a fixed obstacle." );
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE ,"Inflow", 90, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_INFLOW, 20.0, 4.0, "Object adds fluid to the simulation." );
|
||||
uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE ,"Outflow", 142, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OUTFLOW, 20.0, 5.0, "Object removes fluid from the simulation." );
|
||||
uiDefButS ( block, ROW, B_FLUIDSIM_MAKEPART ,"Particle", 194, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_PARTICLE,20.0, 3.0, "Object is made a particle system to display particles generated by a fluidsim domain object." );
|
||||
|
||||
uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE ,"Control", 246, yline, 54,objHeight, &fss->type, 15.0, OB_FLUIDSIM_CONTROL,20.0, 3.0, "Object is made a fluid control mesh, which influences the fluid." );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
yline -= 2*separateHeight;
|
||||
|
||||
/* display specific settings for each type */
|
||||
if ( fss->type == OB_FLUIDSIM_DOMAIN )
|
||||
{
|
||||
const int maxRes = 512;
|
||||
char memString[32];
|
||||
int i;
|
||||
Mesh *mesh = ob->data;
|
||||
|
||||
// use mesh bounding box and object scaling
|
||||
// TODO fix redraw issue
|
||||
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, memString );
|
||||
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT, "Std", 0,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 0, 20.0, 0, "Show standard domain options." );
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT, "Adv", 25,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 1, 20.0, 1, "Show advanced domain options." );
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT, "Bnd", 50,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 2, 20.0, 2, "Show domain boundary options." );
|
||||
uiBlockEndAlign ( block );
|
||||
|
||||
uiDefBut ( block, BUT, B_FLUIDSIM_BAKE, "BAKE",90, yline,210,objHeight, NULL, 0.0, 0.0, 10, 0, "Perform simulation and output and surface&preview meshes for each frame." );
|
||||
yline -= lineHeight;
|
||||
yline -= 2*separateHeight;
|
||||
|
||||
/* display specific settings for each type */
|
||||
if(fss->type == OB_FLUIDSIM_DOMAIN) {
|
||||
const int maxRes = 512;
|
||||
char memString[32];
|
||||
|
||||
// use mesh bounding box and object scaling
|
||||
// TODO fix redraw issue
|
||||
elbeemEstimateMemreq(fss->resolutionxyz,
|
||||
ob->fluidsimSettings->bbSize[0],ob->fluidsimSettings->bbSize[1],ob->fluidsimSettings->bbSize[2], fss->maxRefine, memString);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Std", 0,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 0, 20.0, 0, "Show standard domain options.");
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Adv", 25,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 1, 20.0, 1, "Show advanced domain options.");
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Bnd", 50,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 2, 20.0, 2, "Show domain boundary options.");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefBut(block, BUT, B_FLUIDSIM_BAKE, "BAKE",90, yline,210,objHeight, NULL, 0.0, 0.0, 10, 0, "Perform simulation and output and surface&preview meshes for each frame.");
|
||||
|
||||
if ( fss->show_advancedoptions == 0 )
|
||||
{
|
||||
uiDefBut ( block, LABEL, 0, "Req. BAKE Memory:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefBut ( block, LABEL, 0, memString, 200,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
yline -= lineHeight;
|
||||
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefButS ( block, NUM, REDRAWBUTSOBJECT, "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" );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
uiBlockBeginAlign ( block );
|
||||
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." );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
yline -= 2*separateHeight;
|
||||
|
||||
if(fss->show_advancedoptions == 0) {
|
||||
uiDefBut(block, LABEL, 0, "Req. BAKE Memory:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefBut(block, LABEL, 0, memString, 200,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
yline -= lineHeight;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, NUM, REDRAWBUTSOBJECT, "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");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
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.");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
yline -= 2*separateHeight;
|
||||
|
||||
if((fss->guiDisplayMode<1) || (fss->guiDisplayMode>3)){ fss->guiDisplayMode=2; } // can be changed by particle setting
|
||||
uiDefBut(block, LABEL, 0, "Disp.-Qual.:", 0,yline, 90,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, MENU, B_FLUIDSIM_FORCEREDRAW, "GuiDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",
|
||||
90,yline,105,objHeight, &fss->guiDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh in the Blender GUI.");
|
||||
uiDefButS(block, MENU, B_DIFF, "RenderDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",
|
||||
195,yline,105,objHeight, &fss->renderDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh for rendering.");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefIconBut(block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL, 0, yline, 20, objHeight, 0, 0, 0, 0, 0, "Select Directory (and/or filename prefix) to store baked fluid simulation files in");
|
||||
uiDefBut(block, TEX, B_FLUIDSIM_FORCEREDRAW,"", 20, yline, 280, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0, "Enter Directory (and/or filename prefix) to store baked fluid simulation files in");
|
||||
uiBlockEndAlign(block);
|
||||
// FIXME what is the 79.0 above?
|
||||
} else if(fss->show_advancedoptions == 1) {
|
||||
// advanced options
|
||||
uiDefBut(block, LABEL, 0, "Gravity:", 0, yline, 90,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_DIFF, "X:", 90, yline, 70,objHeight, &fss->gravx, -1000.1, 1000.1, 10, 0, "Gravity in X direction");
|
||||
uiDefButF(block, NUM, B_DIFF, "Y:", 160, yline, 70,objHeight, &fss->gravy, -1000.1, 1000.1, 10, 0, "Gravity in Y direction");
|
||||
uiDefButF(block, NUM, B_DIFF, "Z:", 230, yline, 70,objHeight, &fss->gravz, -1000.1, 1000.1, 10, 0, "Gravity in Z direction");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
/* viscosity */
|
||||
if (fss->viscosityMode==1) /*manual*/
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, MENU, REDRAWVIEW3D, "Viscosity%t|Manual %x1|Water %x2|Oil %x3|Honey %x4",
|
||||
0,yline, 90,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:", 90, yline, 105,objHeight, &fss->viscosityValue, 0.0, 10.0, 10, 0, "Viscosity setting: value that is multiplied by 10 to the power of (exponent*-1).");
|
||||
uiDefButS(block, NUM, B_DIFF, "Neg-Exp.:", 195, yline, 105,objHeight, &fss->viscosityExponent, 0, 10, 10, 0, "Negative exponent for the viscosity value (to simplify entering small values e.g. 5*10^-6.");
|
||||
uiBlockEndAlign(block);
|
||||
} else {
|
||||
// display preset values
|
||||
uiDefBut(block, LABEL, 0, fluidsimViscosityPresetString[fss->viscosityMode], 90,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
}
|
||||
yline -= lineHeight;
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Realworld-size:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->realsize, 0.001, 10.0, 10, 0, "Size of the simulation domain in meters.");
|
||||
yline -= lineHeight;
|
||||
yline -= 2*separateHeight;
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Gridlevels:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButI(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->maxRefine, -1, 4, 10, 0, "Number of coarsened Grids to use (set to -1 for automatic selection).");
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Compressibility:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->gstar, 0.001, 0.10, 10,0, "Allowed compressibility due to gravitational force for standing fluid (directly affects simulation step size).");
|
||||
yline -= lineHeight;
|
||||
|
||||
} else if(fss->show_advancedoptions == 2) {
|
||||
// copied from obstacle...
|
||||
//yline -= lineHeight + 5;
|
||||
//uiDefBut(block, LABEL, 0, "Domain boundary type settings:", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
//yline -= lineHeight;
|
||||
|
||||
uiBlockBeginAlign(block); // domain
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Noslip", 0, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_NOSLIP, 20.0, 1.0, "Obstacle causes zero normal and tangential velocity (=sticky). Default for all. Only option for moving objects.");
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Part", 100, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!");
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Free", 200, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
|
||||
if(fss->typeFlags&OB_FSBND_PARTSLIP) {
|
||||
uiDefBut(block, LABEL, 0, "PartSlipValue:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->partSlipValue, 0.0, 1.0, 10,0, "Amount of mixing between no- and free-slip, 0=stickier, 1=same as free slip.");
|
||||
yline -= lineHeight;
|
||||
} else {
|
||||
//uiDefBut(block, LABEL, 0, "-", 200,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
}
|
||||
// copied from obstacle...
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Tracer Particles:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButI(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->generateTracers, 0.0, 10000.0, 10,0, "Number of tracer particles to generate.");
|
||||
yline -= lineHeight;
|
||||
uiDefBut(block, LABEL, 0, "Generate Particles:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->generateParticles, 0.0, 10.0, 10,0, "Amount of particles to generate (0=off, 1=normal, >1=more).");
|
||||
yline -= lineHeight;
|
||||
uiDefBut(block, LABEL, 0, "Surface Subdiv:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButI(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->surfaceSubdivs, 0.0, 5.0, 10,0, "Number of isosurface subdivisions. This is necessary for the inclusion of particles into the surface generation. Warning - can lead to longer computation times!");
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Surface Smoothing:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->surfaceSmoothing, 0.0, 5.0, 10,0, "Amount of surface smoothing (0=off, 1=normal, >1=stronger smoothing).");
|
||||
yline -= lineHeight;
|
||||
|
||||
// use new variable...
|
||||
uiDefBut(block, LABEL, 0, "Generate&Use SpeedVecs:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButBitC(block, TOG, 1, REDRAWBUTSOBJECT, "Disable", 200, yline,100,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Default is to generate and use fluidsim vertex speed vectors, this option switches calculation off during bake, and disables loading.");
|
||||
yline -= lineHeight;
|
||||
} // domain 3
|
||||
}
|
||||
else if(
|
||||
(fss->type == OB_FLUIDSIM_FLUID)
|
||||
|| (fss->type == OB_FLUIDSIM_INFLOW)
|
||||
) {
|
||||
uiBlockBeginAlign(block); // fluid
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Volume", 0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh.");
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Shell", 100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh.");
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Both", 200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell.");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
if ( ( fss->guiDisplayMode<1 ) || ( fss->guiDisplayMode>3 ) ) { fss->guiDisplayMode=2; } // can be changed by particle setting
|
||||
uiDefBut ( block, LABEL, 0, "Disp.-Qual.:", 0,yline, 90,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefButS ( block, MENU, B_BAKE_CACHE_CHANGE, "GuiDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",
|
||||
90,yline,105,objHeight, &fss->guiDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh in the Blender GUI." );
|
||||
uiDefButS ( block, MENU, B_DIFF, "RenderDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",
|
||||
195,yline,105,objHeight, &fss->renderDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh for rendering." );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
|
||||
yline -= lineHeight + 5; // fluid + inflow
|
||||
if(fss->type == OB_FLUIDSIM_FLUID) uiDefBut(block, LABEL, 0, "Initial velocity:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
if(fss->type == OB_FLUIDSIM_INFLOW) uiDefBut(block, LABEL, 0, "Inflow velocity:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
yline -= lineHeight;
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_DIFF, "X:", 0, yline, 100,objHeight, &fss->iniVelx, -1000.1, 1000.1, 10, 0, "Fluid velocity in X direction");
|
||||
uiDefButF(block, NUM, B_DIFF, "Y:", 100, yline, 100,objHeight, &fss->iniVely, -1000.1, 1000.1, 10, 0, "Fluid velocity in Y direction");
|
||||
uiDefButF(block, NUM, B_DIFF, "Z:", 200, yline, 100,objHeight, &fss->iniVelz, -1000.1, 1000.1, 10, 0, "Fluid velocity in Z direction");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
|
||||
if(fss->type == OB_FLUIDSIM_INFLOW) { // inflow
|
||||
uiDefBut(block, LABEL, 0, "Local Inflow Coords", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButBitS(block, TOG, OB_FSINFLOW_LOCALCOORD, REDRAWBUTSOBJECT, "Enable", 200, yline,100,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Use local coordinates for inflow (e.g. for rotating objects).");
|
||||
yline -= lineHeight;
|
||||
} else {
|
||||
}
|
||||
|
||||
// domainNovecgen "misused" here
|
||||
uiDefBut(block, LABEL, 0, "Animated Mesh:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButBitC(block, TOG, 1, REDRAWBUTSOBJECT, "Export", 200, yline,100,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated pos/rot/scale IPOs do not require it.");
|
||||
yline -= lineHeight;
|
||||
|
||||
} // fluid inflow
|
||||
else if( (fss->type == OB_FLUIDSIM_OUTFLOW) ) {
|
||||
yline -= lineHeight + 5;
|
||||
|
||||
uiBlockBeginAlign(block); // outflow
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Volume", 0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh.");
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Shell", 100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh.");
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Both", 200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell.");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
|
||||
// domainNovecgen "misused" here
|
||||
uiDefBut(block, LABEL, 0, "Animated Mesh:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButBitC(block, TOG, 1, REDRAWBUTSOBJECT, "Export", 200, yline,100,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated pos/rot/scale IPOs do not require it.");
|
||||
yline -= lineHeight;
|
||||
|
||||
//uiDefBut(block, LABEL, 0, "No additional settings as of now...", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
}
|
||||
else if( (fss->type == OB_FLUIDSIM_OBSTACLE) ) {
|
||||
yline -= lineHeight + 5; // obstacle
|
||||
|
||||
uiBlockBeginAlign(block); // obstacle
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Volume", 0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh.");
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Shell", 100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh.");
|
||||
uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Both", 200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell.");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
|
||||
uiBlockBeginAlign(block); // obstacle
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Noslip", 0, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_NOSLIP, 20.0, 1.0, "Obstacle causes zero normal and tangential velocity (=sticky). Default for all. Only option for moving objects.");
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Part", 100, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!");
|
||||
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Free", 200, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!");
|
||||
uiBlockEndAlign(block);
|
||||
yline -= lineHeight;
|
||||
|
||||
// domainNovecgen "misused" here
|
||||
uiDefBut(block, LABEL, 0, "Animated Mesh:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButBitC(block, TOG, 1, REDRAWBUTSOBJECT, "Export", 200, yline,100,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated loc/rot/scale IPOs do not require it.");
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefBut(block, LABEL, 0, "PartSlip Amount:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
if(fss->typeFlags&OB_FSBND_PARTSLIP) {
|
||||
uiDefButF(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->partSlipValue, 0.0, 1.0, 10,0, "Amount of mixing between no- and free-slip, 0=stickier, 1=same as free slip.");
|
||||
} else { uiDefBut(block, LABEL, 0, "-", 200,yline,100,objHeight, NULL, 0.0, 0, 0, 0, ""); }
|
||||
yline -= lineHeight;
|
||||
|
||||
// generateParticles "misused" here
|
||||
uiDefBut(block, LABEL, 0, "Impact Factor:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->surfaceSmoothing, -2.0, 10.0, 10,0, "This is an unphysical value for moving objects - it controls the impact an obstacle has on the fluid, =0 behaves a bit like outflow (deleting fluid), =1 is default, while >1 results in high forces. Can be used to tweak total mass.");
|
||||
yline -= lineHeight;
|
||||
|
||||
yline -= lineHeight; // obstacle
|
||||
}
|
||||
else if(fss->type == OB_FLUIDSIM_PARTICLE) {
|
||||
|
||||
//fss->type == 0; // off, broken...
|
||||
if(1) {
|
||||
// limited selection, old fixed: fss->typeFlags = (1<<5)|(1<<1);
|
||||
# define PARTBUT_WIDTH (300/3)
|
||||
uiDefButBitS(block, TOG, (1<<2) , REDRAWBUTSOBJECT, "Drops", 0*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show drop particles.");
|
||||
uiDefButBitS(block, TOG, (1<<4) , REDRAWBUTSOBJECT, "Floats", 1*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show floating foam particles.");
|
||||
uiDefButBitS(block, TOG, (1<<5) , REDRAWBUTSOBJECT, "Tracer", 2*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show tracer particles.");
|
||||
yline -= lineHeight;
|
||||
# undef PARTBUT_WIDTH
|
||||
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Size Influence:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->particleInfSize, 0.0, 2.0, 10,0, "Amount of particle size scaling: 0=off (all same size), 1=full (range 0.2-2.0), >1=stronger.");
|
||||
yline -= lineHeight;
|
||||
uiDefBut(block, LABEL, 0, "Alpha Influence:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->particleInfAlpha, 0.0, 2.0, 10,0, "Amount of particle alpha change, inverse of size influence: 0=off (all same alpha), 1=full (large particles get lower alphas, smaller ones higher values).");
|
||||
yline -= lineHeight;
|
||||
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefIconBut ( block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL, 0, yline, 20, objHeight, 0, 0, 0, 0, 0, "Select Directory (and/or filename prefix) to store baked fluid simulation files in" );
|
||||
uiDefBut ( block, TEX, B_BAKE_CACHE_CHANGE,"", 20, yline, 280, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0, "Enter Directory (and/or filename prefix) to store baked fluid simulation files in" );
|
||||
uiBlockEndAlign ( block );
|
||||
// FIXME what is the 79.0 above?
|
||||
}
|
||||
else if ( fss->show_advancedoptions == 1 )
|
||||
{
|
||||
// advanced options
|
||||
uiDefBut ( block, LABEL, 0, "Gravity:", 0, yline, 90,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefButF ( block, NUM, B_DIFF, "X:", 90, yline, 70,objHeight, &fss->gravx, -1000.1, 1000.1, 10, 0, "Gravity in X direction" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "Y:", 160, yline, 70,objHeight, &fss->gravy, -1000.1, 1000.1, 10, 0, "Gravity in Y direction" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "Z:", 230, yline, 70,objHeight, &fss->gravz, -1000.1, 1000.1, 10, 0, "Gravity in Z direction" );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
/* viscosity */
|
||||
if ( fss->viscosityMode==1 ) /*manual*/
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefButS ( block, MENU, REDRAWVIEW3D, "Viscosity%t|Manual %x1|Water %x2|Oil %x3|Honey %x4",
|
||||
0,yline, 90,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:", 90, yline, 105,objHeight, &fss->viscosityValue, 0.0, 10.0, 10, 0, "Viscosity setting: value that is multiplied by 10 to the power of (exponent*-1)." );
|
||||
uiDefButS ( block, NUM, B_DIFF, "Neg-Exp.:", 195, yline, 105,objHeight, &fss->viscosityExponent, 0, 10, 10, 0, "Negative exponent for the viscosity value (to simplify entering small values e.g. 5*10^-6." );
|
||||
uiBlockEndAlign ( block );
|
||||
}
|
||||
else
|
||||
{
|
||||
// display preset values
|
||||
uiDefBut ( block, LABEL, 0, fluidsimViscosityPresetString[fss->viscosityMode], 90,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
}
|
||||
yline -= lineHeight;
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
uiDefBut ( block, LABEL, 0, "Realworld-size:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->realsize, 0.001, 10.0, 10, 0, "Size of the simulation domain in meters." );
|
||||
yline -= lineHeight;
|
||||
yline -= 2*separateHeight;
|
||||
|
||||
uiDefBut ( block, LABEL, 0, "Gridlevels:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButI ( block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->maxRefine, -1, 4, 10, 0, "Number of coarsened Grids to use (set to -1 for automatic selection)." );
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefBut ( block, LABEL, 0, "Compressibility:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->gstar, 0.001, 0.10, 10,0, "Allowed compressibility due to gravitational force for standing fluid (directly affects simulation step size)." );
|
||||
yline -= lineHeight;
|
||||
|
||||
}
|
||||
else if ( fss->show_advancedoptions == 2 )
|
||||
{
|
||||
// copied from obstacle...
|
||||
//yline -= lineHeight + 5;
|
||||
//uiDefBut(block, LABEL, 0, "Domain boundary type settings:", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
//yline -= lineHeight;
|
||||
|
||||
uiBlockBeginAlign ( block ); // domain
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Noslip", 0, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_NOSLIP, 20.0, 1.0, "Obstacle causes zero normal and tangential velocity (=sticky). Default for all. Only option for moving objects." );
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Part", 100, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!" );
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Free", 200, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!" );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
|
||||
if ( fss->typeFlags&OB_FSBND_PARTSLIP )
|
||||
{
|
||||
uiDefBut ( block, LABEL, 0, "PartSlipValue:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->partSlipValue, 0.0, 1.0, 10,0, "Amount of mixing between no- and free-slip, 0=stickier, 1=same as free slip." );
|
||||
yline -= lineHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
//uiDefBut(block, LABEL, 0, "-", 200,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
}
|
||||
// copied from obstacle...
|
||||
|
||||
uiDefBut ( block, LABEL, 0, "Tracer Particles:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButI ( block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->generateTracers, 0.0, 10000.0, 10,0, "Number of tracer particles to generate." );
|
||||
yline -= lineHeight;
|
||||
uiDefBut ( block, LABEL, 0, "Generate Particles:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->generateParticles, 0.0, 10.0, 10,0, "Amount of particles to generate (0=off, 1=normal, >1=more)." );
|
||||
yline -= lineHeight;
|
||||
uiDefBut ( block, LABEL, 0, "Surface Subdiv:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButI ( block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->surfaceSubdivs, 0.0, 5.0, 10,0, "Number of isosurface subdivisions. This is necessary for the inclusion of particles into the surface generation. Warning - can lead to longer computation times!" );
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefBut ( block, LABEL, 0, "Surface Smoothing:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->surfaceSmoothing, 0.0, 5.0, 10,0, "Amount of surface smoothing (0=off, 1=normal, >1=stronger smoothing)." );
|
||||
yline -= lineHeight;
|
||||
|
||||
// use new variable...
|
||||
uiDefBut ( block, LABEL, 0, "Generate&Use SpeedVecs:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButBitC ( block, TOG, 1, REDRAWBUTSOBJECT, "Disable", 200, yline,100,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Default is to generate and use fluidsim vertex speed vectors, this option switches calculation off during bake, and disables loading." );
|
||||
yline -= lineHeight;
|
||||
} // domain 3
|
||||
}
|
||||
else if (
|
||||
( fss->type == OB_FLUIDSIM_FLUID )
|
||||
|| ( fss->type == OB_FLUIDSIM_INFLOW )
|
||||
)
|
||||
{
|
||||
uiBlockBeginAlign ( block ); // fluid
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Volume", 0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh." );
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Shell", 100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh." );
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Both", 200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell." );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
|
||||
yline -= lineHeight + 5; // fluid + inflow
|
||||
if ( fss->type == OB_FLUIDSIM_FLUID ) uiDefBut ( block, LABEL, 0, "Initial velocity:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
if ( fss->type == OB_FLUIDSIM_INFLOW ) uiDefBut ( block, LABEL, 0, "Inflow velocity:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
yline -= lineHeight;
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefButF ( block, NUM, B_DIFF, "X:", 0, yline, 100,objHeight, &fss->iniVelx, -1000.1, 1000.1, 10, 0, "Fluid velocity in X direction" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "Y:", 100, yline, 100,objHeight, &fss->iniVely, -1000.1, 1000.1, 10, 0, "Fluid velocity in Y direction" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "Z:", 200, yline, 100,objHeight, &fss->iniVelz, -1000.1, 1000.1, 10, 0, "Fluid velocity in Z direction" );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
|
||||
if ( fss->type == OB_FLUIDSIM_INFLOW ) // inflow
|
||||
{
|
||||
uiDefBut ( block, LABEL, 0, "Local Inflow Coords", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButBitS ( block, TOG, OB_FSINFLOW_LOCALCOORD, REDRAWBUTSOBJECT, "Enable", 200, yline,100,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Use local coordinates for inflow (e.g. for rotating objects)." );
|
||||
yline -= lineHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
// domainNovecgen "misused" here
|
||||
uiDefBut ( block, LABEL, 0, "Animated Mesh:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButBitC ( block, TOG, 1, REDRAWBUTSOBJECT, "Export", 200, yline,100,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated pos/rot/scale IPOs do not require it." );
|
||||
yline -= lineHeight;
|
||||
|
||||
} // fluid inflow
|
||||
else if ( ( fss->type == OB_FLUIDSIM_OUTFLOW ) )
|
||||
{
|
||||
yline -= lineHeight + 5;
|
||||
|
||||
uiBlockBeginAlign ( block ); // outflow
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Volume", 0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh." );
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Shell", 100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh." );
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Both", 200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell." );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
|
||||
// domainNovecgen "misused" here
|
||||
uiDefBut ( block, LABEL, 0, "Animated Mesh:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButBitC ( block, TOG, 1, REDRAWBUTSOBJECT, "Export", 200, yline,100,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated pos/rot/scale IPOs do not require it." );
|
||||
yline -= lineHeight;
|
||||
|
||||
//uiDefBut(block, LABEL, 0, "No additional settings as of now...", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
}
|
||||
else if ( ( fss->type == OB_FLUIDSIM_OBSTACLE ) )
|
||||
{
|
||||
yline -= lineHeight + 5; // obstacle
|
||||
|
||||
uiBlockBeginAlign ( block ); // obstacle
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Volume", 0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh." );
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Shell", 100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh." );
|
||||
uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Init Both", 200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell." );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
|
||||
uiBlockBeginAlign ( block ); // obstacle
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Noslip", 0, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_NOSLIP, 20.0, 1.0, "Obstacle causes zero normal and tangential velocity (=sticky). Default for all. Only option for moving objects." );
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Part", 100, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!" );
|
||||
uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Free", 200, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!" );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
|
||||
// domainNovecgen "misused" here
|
||||
uiDefBut ( block, LABEL, 0, "Animated Mesh:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButBitC ( block, TOG, 1, REDRAWBUTSOBJECT, "Export", 200, yline,100,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated loc/rot/scale IPOs do not require it." );
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefBut ( block, LABEL, 0, "PartSlip Amount:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
if ( fss->typeFlags&OB_FSBND_PARTSLIP )
|
||||
{
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->partSlipValue, 0.0, 1.0, 10,0, "Amount of mixing between no- and free-slip, 0=stickier, 1=same as free slip." );
|
||||
}
|
||||
else { uiDefBut ( block, LABEL, 0, "-", 200,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "" ); }
|
||||
yline -= lineHeight;
|
||||
|
||||
// generateParticles "misused" here
|
||||
uiDefBut ( block, LABEL, 0, "Impact Factor:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->surfaceSmoothing, -2.0, 10.0, 10,0, "This is an unphysical value for moving objects - it controls the impact an obstacle has on the fluid, =0 behaves a bit like outflow (deleting fluid), =1 is default, while >1 results in high forces. Can be used to tweak total mass." );
|
||||
yline -= lineHeight;
|
||||
|
||||
yline -= lineHeight; // obstacle
|
||||
}
|
||||
else if ( fss->type == OB_FLUIDSIM_PARTICLE )
|
||||
{
|
||||
|
||||
//fss->type == 0; // off, broken...
|
||||
if ( 1 )
|
||||
{
|
||||
// limited selection, old fixed: fss->typeFlags = (1<<5)|(1<<1);
|
||||
# define PARTBUT_WIDTH (300/3)
|
||||
uiDefButBitS ( block, TOG, ( 1<<2 ) , REDRAWBUTSOBJECT, "Drops", 0*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show drop particles." );
|
||||
uiDefButBitS ( block, TOG, ( 1<<4 ) , REDRAWBUTSOBJECT, "Floats", 1*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show floating foam particles." );
|
||||
uiDefButBitS ( block, TOG, ( 1<<5 ) , REDRAWBUTSOBJECT, "Tracer", 2*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show tracer particles." );
|
||||
yline -= lineHeight;
|
||||
# undef PARTBUT_WIDTH
|
||||
|
||||
|
||||
uiDefBut ( block, LABEL, 0, "Size Influence:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->particleInfSize, 0.0, 2.0, 10,0, "Amount of particle size scaling: 0=off (all same size), 1=full (range 0.2-2.0), >1=stronger." );
|
||||
yline -= lineHeight;
|
||||
uiDefBut ( block, LABEL, 0, "Alpha Influence:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->particleInfAlpha, 0.0, 2.0, 10,0, "Amount of particle alpha change, inverse of size influence: 0=off (all same alpha), 1=full (large particles get lower alphas, smaller ones higher values)." );
|
||||
yline -= lineHeight;
|
||||
|
||||
yline -= 1*separateHeight;
|
||||
|
||||
// FSPARTICLE also select input files
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefIconBut(block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL, 0, yline, 20, objHeight, 0, 0, 0, 0, 0, "Select fluid simulation bake directory/prefix to load particles from, same as for domain object.");
|
||||
uiDefBut(block, TEX, B_FLUIDSIM_FORCEREDRAW,"", 20, yline, 280, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0, "Enter fluid simulation bake directory/prefix to load particles from, same as for domain object.");
|
||||
uiBlockEndAlign(block);
|
||||
uiBlockBeginAlign ( block );
|
||||
uiDefIconBut ( block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL, 0, yline, 20, objHeight, 0, 0, 0, 0, 0, "Select fluid simulation bake directory/prefix to load particles from, same as for domain object." );
|
||||
uiDefBut ( block, TEX, B_BAKE_CACHE_CHANGE,"", 20, yline, 280, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0, "Enter fluid simulation bake directory/prefix to load particles from, same as for domain object." );
|
||||
uiBlockEndAlign ( block );
|
||||
yline -= lineHeight;
|
||||
} // disabled for now...
|
||||
|
||||
}
|
||||
else if(fss->type == OB_FLUIDSIM_CONTROL) {
|
||||
|
||||
uiDefButF(block, NUM, B_DIFF, "Time Sta:", 0, yline,150,20, &fss->cpsTimeStart, 0.0, 100.0, 10,0, "Specifies time when the control particles are activated.");
|
||||
uiDefButF(block, NUM, B_DIFF, "Time End:", 150, yline,150,20, &fss->cpsTimeEnd, 0.0, 100.0, 10,0, "Specifies time when the control particles are deactivated.");
|
||||
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Attraction force:", 0,yline,300,20, NULL, 0.0, 0, 0, 0, "");
|
||||
yline -= lineHeight;
|
||||
uiDefButF(block, NUM, B_DIFF, "Strength:", 0, yline,150,20, &fss->attractforceStrength, 0.0, 2.0, 10,0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "Radius:", 150, yline,150,20, &fss->attractforceRadius, 0.0, 2.0, 10,0, "");
|
||||
yline -= lineHeight;
|
||||
uiDefBut(block, LABEL, 0, "Velocity force:", 0,yline,300,20, NULL, 0.0, 0, 0, 0, "");
|
||||
yline -= lineHeight;
|
||||
uiDefButF(block, NUM, B_DIFF, "Strength:", 0, yline,150,20, &fss->velocityforceStrength, 0.0, 2.0, 10,0, "");
|
||||
uiDefButF(block, NUM, B_DIFF, "Radius:", 150, yline,150,20, &fss->velocityforceRadius, 0.0, 2.0, 10,0, "");
|
||||
|
||||
yline -= lineHeight;
|
||||
uiDefButF(block, NUM, B_DIFF, "Quality:", 0, yline,150,20, &fss->cpsQuality, 1.0, 100.0, 10,0, "Specifies the quality which is used for object sampling.");
|
||||
}
|
||||
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;
|
||||
}
|
||||
return;
|
||||
|
||||
} else {
|
||||
msg = "Object not enabled for fluid simulation.";
|
||||
|
||||
}
|
||||
} else {
|
||||
msg = "Only mesh objects can do fluid simulation.";
|
||||
}
|
||||
errMessage:
|
||||
yline -= lineHeight + 5;
|
||||
uiDefBut(block, LABEL, 0, msg, 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
|
||||
yline -= lineHeight;
|
||||
else if ( fss->type == OB_FLUIDSIM_CONTROL )
|
||||
{
|
||||
|
||||
uiDefButF ( block, NUM, B_DIFF, "Time Sta:", 0, yline,150,20, &fss->cpsTimeStart, 0.0, 100.0, 10,0, "Specifies time when the control particles are activated." );
|
||||
uiDefButF ( block, NUM, B_DIFF, "Time End:", 150, yline,150,20, &fss->cpsTimeEnd, 0.0, 100.0, 10,0, "Specifies time when the control particles are deactivated." );
|
||||
|
||||
yline -= lineHeight;
|
||||
|
||||
uiDefBut ( block, LABEL, 0, "Attraction force:", 0,yline,300,20, NULL, 0.0, 0, 0, 0, "" );
|
||||
yline -= lineHeight;
|
||||
uiDefButF ( block, NUM, B_DIFF, "Strength:", 0, yline,150,20, &fss->attractforceStrength, -10.0, 10.0, 10,0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "Radius:", 150, yline,150,20, &fss->attractforceRadius, 0.0, 10.0, 10,0, "" );
|
||||
yline -= lineHeight;
|
||||
uiDefBut ( block, LABEL, 0, "Velocity force:", 0,yline,300,20, NULL, 0.0, 0, 0, 0, "" );
|
||||
yline -= lineHeight;
|
||||
uiDefButF ( block, NUM, B_DIFF, "Strength:", 0, yline,150,20, &fss->velocityforceStrength, 0.0, 10.0, 10,0, "" );
|
||||
uiDefButF ( block, NUM, B_DIFF, "Radius:", 150, yline,150,20, &fss->velocityforceRadius, 0.0, 10.0, 10,0, "" );
|
||||
|
||||
yline -= lineHeight;
|
||||
uiDefButF ( block, NUM, B_DIFF, "Quality:", 0, yline,150,20, &fss->cpsQuality, 5.0, 100.0, 10,0, "Specifies the quality which is used for object sampling (higher = better but slower)." );
|
||||
}
|
||||
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;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif // DISABLE_ELBEEM
|
||||
}
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_fluidsim.h"
|
||||
#include "DNA_particle_types.h"
|
||||
@ -83,6 +84,7 @@
|
||||
#include "BKE_ipo.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_utildefines.h"
|
||||
@ -494,32 +496,31 @@ static void make_fluidsim_editipo(SpaceIpo *si, Object *ob) // NT
|
||||
EditIpo *ei;
|
||||
int a;
|
||||
char *name;
|
||||
FluidsimSettings *fss= ob->fluidsimSettings;
|
||||
int numipos = FLUIDSIM_TOTIPO;
|
||||
int ipo_start_index = 0;
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
FluidsimSettings *fss= fluidmd->fss;
|
||||
|
||||
// we don't need all fluid ipos for all types! - dg
|
||||
/*
|
||||
if(fss->type == OB_FLUIDSIM_CONTROL)
|
||||
{
|
||||
numipos = 4; // there are 4 fluid control ipos
|
||||
ipo_start_index = 9;
|
||||
|
||||
}
|
||||
else */
|
||||
if(fss->type == OB_FLUIDSIM_DOMAIN)
|
||||
else if(fss->type == OB_FLUIDSIM_DOMAIN)
|
||||
{
|
||||
numipos = 5; // there are 5 ipos for fluid domains
|
||||
}/*
|
||||
}
|
||||
else
|
||||
{
|
||||
numipos = 4; // there are 4 for the rest
|
||||
ipo_start_index = 5;
|
||||
}*/
|
||||
}
|
||||
|
||||
ei= si->editipo= MEM_callocN(numipos*sizeof(EditIpo), "fluidsim_editipo");
|
||||
si->totipo = numipos;
|
||||
for(a=ipo_start_index; a<numipos; a++) {
|
||||
for(a=ipo_start_index; a<ipo_start_index+numipos; a++) {
|
||||
//fprintf(stderr,"FSINAME %d %d \n",a,fluidsim_ar[a], (int)(getname_fluidsim_ei(fluidsim_ar[a])) );
|
||||
name = getname_fluidsim_ei(fluidsim_ar[a]);
|
||||
strcpy(ei->name, name);
|
||||
@ -1200,10 +1201,14 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
|
||||
// }
|
||||
}
|
||||
else if(blocktype==ID_FLUIDSIM) {
|
||||
if(ob && ( ob->fluidsimFlag & OB_FLUIDSIM_ENABLE)) {
|
||||
FluidsimSettings *fss= ob->fluidsimSettings;
|
||||
*from= (ID *)ob;
|
||||
if(fss) *ipo= fss->ipo;
|
||||
if(ob)
|
||||
{
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
if(fluidmd) {
|
||||
FluidsimSettings *fss= fluidmd->fss;
|
||||
*from= (ID *)ob;
|
||||
if(fss) *ipo= fss->ipo;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(blocktype==ID_PA) {
|
||||
@ -1900,8 +1905,9 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char
|
||||
}
|
||||
else if(blocktype== ID_FLUIDSIM) {
|
||||
Object *ob= (Object *)from;
|
||||
if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
|
||||
FluidsimSettings *fss= ob->fluidsimSettings;
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
if(fluidmd) {
|
||||
FluidsimSettings *fss= fluidmd->fss;
|
||||
if(fss->ipo==NULL) {
|
||||
fss->ipo= add_ipo("FluidsimIpo", ID_FLUIDSIM);
|
||||
//fprintf(stderr,"FSIPO NEW!\n");
|
||||
|
@ -1601,15 +1601,6 @@ void separate_mesh(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/* blender crashes in derivedmesh drawing if I don't do this... but why?
|
||||
Anyhoo, this function is horrible anyway (ton)
|
||||
the fluidsimFlag also has to be reset btw. (n_t) */
|
||||
if(G.obedit->fluidsimSettings) {
|
||||
fluidsimSettingsFree(G.obedit->fluidsimSettings);
|
||||
G.obedit->fluidsimSettings = NULL;
|
||||
G.obedit->fluidsimFlag = 0;
|
||||
}
|
||||
|
||||
if(em->selected.first) BLI_freelistN(&(em->selected)); /* clear the selection order */
|
||||
|
||||
EM_selectmode_set(); // enforce full consistant selection flags
|
||||
@ -1782,13 +1773,6 @@ void separate_mesh_loose(void)
|
||||
error("Can't separate a mesh with vertex keys");
|
||||
return;
|
||||
}
|
||||
|
||||
/* same problem as in separate_mesh above (n_t) */
|
||||
if(G.obedit->fluidsimSettings) {
|
||||
fluidsimSettingsFree(G.obedit->fluidsimSettings);
|
||||
G.obedit->fluidsimSettings = NULL;
|
||||
G.obedit->fluidsimFlag = 0;
|
||||
}
|
||||
|
||||
TEST_EDITMESH
|
||||
if(multires_test()) return;
|
||||
|
@ -61,7 +61,9 @@
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_fluidsim.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_scene.h"
|
||||
@ -102,9 +104,6 @@
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
// from DerivedMesh.c
|
||||
void initElbeemMesh(struct Object *ob, int *numVertices, float **vertices, int *numTriangles, int **triangles, int useGlobalCoords);
|
||||
|
||||
/* from header info.c */
|
||||
extern int start_progress_bar(void);
|
||||
extern void end_progress_bar(void);
|
||||
@ -128,160 +127,12 @@ char* fluidsimViscosityPresetString[6] = {
|
||||
"INVALID" /* end */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
DerivedMesh dm;
|
||||
|
||||
// similar to MeshDerivedMesh
|
||||
struct Object *ob; // pointer to parent object
|
||||
float *extverts, *nors; // face normals, colors?
|
||||
Mesh *fsmesh; // mesh struct to display (either surface, or original one)
|
||||
char meshFree; // free the mesh afterwards? (boolean)
|
||||
} fluidsimDerivedMesh;
|
||||
|
||||
|
||||
|
||||
/* enable/disable overall compilation */
|
||||
#ifndef DISABLE_ELBEEM
|
||||
|
||||
|
||||
/* ********************** fluid sim settings struct functions ********************** */
|
||||
|
||||
/* allocates and initializes general main data */
|
||||
|
||||
FluidsimSettings *fluidsimSettingsNew(struct Object *srcob)
|
||||
{
|
||||
//char blendDir[FILE_MAXDIR], blendFile[FILE_MAXFILE];
|
||||
FluidsimSettings *fss;
|
||||
|
||||
/* this call uses derivedMesh methods... */
|
||||
if(srcob->type!=OB_MESH) return NULL;
|
||||
|
||||
fss= MEM_callocN( sizeof(FluidsimSettings), "fluidsimsettings memory");
|
||||
|
||||
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;
|
||||
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->iniVelx =
|
||||
fss->iniVely =
|
||||
fss->iniVelz = 0.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);
|
||||
fss->orgMesh = (Mesh *)srcob->data;
|
||||
fss->meshSurface = NULL;
|
||||
fss->meshBB = NULL;
|
||||
fss->meshSurfNormals = NULL;
|
||||
|
||||
// first init of bounding box
|
||||
fss->bbStart[0] = 0.0;
|
||||
fss->bbStart[1] = 0.0;
|
||||
fss->bbStart[2] = 0.0;
|
||||
fss->bbSize[0] = 1.0;
|
||||
fss->bbSize[1] = 1.0;
|
||||
fss->bbSize[2] = 1.0;
|
||||
fluidsimGetAxisAlignedBB(srcob->data, srcob->obmat, fss->bbStart, fss->bbSize, &fss->meshBB);
|
||||
|
||||
// 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
|
||||
|
||||
return fss;
|
||||
}
|
||||
|
||||
/* duplicate struct, analogous to free */
|
||||
static Mesh *fluidsimCopyMesh(Mesh *me)
|
||||
{
|
||||
Mesh *dup = MEM_dupallocN(me);
|
||||
|
||||
CustomData_copy(&me->vdata, &dup->vdata, CD_MASK_MESH, CD_DUPLICATE, me->totvert);
|
||||
CustomData_copy(&me->edata, &dup->edata, CD_MASK_MESH, CD_DUPLICATE, me->totedge);
|
||||
CustomData_copy(&me->fdata, &dup->fdata, CD_MASK_MESH, CD_DUPLICATE, me->totface);
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
FluidsimSettings* fluidsimSettingsCopy(FluidsimSettings *fss)
|
||||
{
|
||||
FluidsimSettings *dupfss;
|
||||
|
||||
if(!fss) return NULL;
|
||||
dupfss = MEM_dupallocN(fss);
|
||||
|
||||
if(fss->meshSurface)
|
||||
dupfss->meshSurface = fluidsimCopyMesh(fss->meshSurface);
|
||||
if(fss->meshBB)
|
||||
dupfss->meshBB = fluidsimCopyMesh(fss->meshBB);
|
||||
|
||||
if(fss->meshSurfNormals) dupfss->meshSurfNormals = MEM_dupallocN(fss->meshSurfNormals);
|
||||
|
||||
return dupfss;
|
||||
}
|
||||
|
||||
/* free struct */
|
||||
static void fluidsimFreeMesh(Mesh *me)
|
||||
{
|
||||
CustomData_free(&me->vdata, me->totvert);
|
||||
CustomData_free(&me->edata, me->totedge);
|
||||
CustomData_free(&me->fdata, me->totface);
|
||||
|
||||
MEM_freeN(me);
|
||||
}
|
||||
|
||||
void fluidsimSettingsFree(FluidsimSettings *fss)
|
||||
{
|
||||
if(fss->meshSurface) {
|
||||
fluidsimFreeMesh(fss->meshSurface);
|
||||
fss->meshSurface = NULL;
|
||||
}
|
||||
if(fss->meshBB) {
|
||||
fluidsimFreeMesh(fss->meshBB);
|
||||
fss->meshBB = NULL;
|
||||
}
|
||||
|
||||
if(fss->meshSurfNormals){ MEM_freeN(fss->meshSurfNormals); fss->meshSurfNormals=NULL; }
|
||||
|
||||
MEM_freeN(fss);
|
||||
}
|
||||
|
||||
|
||||
/* helper function */
|
||||
void fluidsimGetGeometryObjFilename(struct Object *ob, char *dst) { //, char *srcname) {
|
||||
//snprintf(dst,FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name);
|
||||
@ -542,6 +393,8 @@ void fluidsimBake(struct Object *ob)
|
||||
float *channelAttractforceRadius[256];
|
||||
float *channelVelocityforceStrength[256];
|
||||
float *channelVelocityforceRadius[256];
|
||||
FluidsimModifierData *fluidmd = NULL;
|
||||
Mesh *mesh = NULL;
|
||||
|
||||
if(getenv(strEnvName)) {
|
||||
int dlevel = atoi(getenv(strEnvName));
|
||||
@ -566,12 +419,16 @@ void fluidsimBake(struct Object *ob)
|
||||
/* no object pointer, find in selected ones.. */
|
||||
if(!ob) {
|
||||
for(base=G.scene->base.first; base; base= base->next) {
|
||||
if ( ((base)->flag & SELECT)
|
||||
// ignore layer setting for now? && ((base)->lay & G.vd->lay)
|
||||
) {
|
||||
if((!ob)&&(base->object->fluidsimFlag & OB_FLUIDSIM_ENABLE)&&(base->object->type==OB_MESH)) {
|
||||
if(base->object->fluidsimSettings->type == OB_FLUIDSIM_DOMAIN) {
|
||||
if ((base)->flag & SELECT)
|
||||
{
|
||||
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
|
||||
|
||||
if(fluidmdtmp && (base->object->type==OB_MESH))
|
||||
{
|
||||
if(fluidmdtmp->fss->type == OB_FLUIDSIM_DOMAIN)
|
||||
{
|
||||
ob = base->object;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -579,15 +436,17 @@ void fluidsimBake(struct Object *ob)
|
||||
// no domains found?
|
||||
if(!ob) return;
|
||||
}
|
||||
|
||||
|
||||
channelObjCount = 0;
|
||||
for(base=G.scene->base.first; base; base= base->next) {
|
||||
for(base=G.scene->base.first; base; base= base->next)
|
||||
{
|
||||
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
|
||||
obit = base->object;
|
||||
//{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
|
||||
if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
|
||||
(obit->type==OB_MESH) &&
|
||||
(obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH
|
||||
(obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE) ) {
|
||||
if( fluidmdtmp &&
|
||||
(obit->type==OB_MESH) &&
|
||||
(fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH
|
||||
(fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE) )
|
||||
{
|
||||
channelObjCount++;
|
||||
}
|
||||
}
|
||||
@ -598,23 +457,54 @@ void fluidsimBake(struct Object *ob)
|
||||
}
|
||||
|
||||
/* check if there's another domain... */
|
||||
for(base=G.scene->base.first; base; base= base->next) {
|
||||
for(base=G.scene->base.first; base; base= base->next)
|
||||
{
|
||||
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
|
||||
obit = base->object;
|
||||
if((obit->fluidsimFlag & OB_FLUIDSIM_ENABLE)&&(obit->type==OB_MESH)) {
|
||||
if(obit->fluidsimSettings->type == OB_FLUIDSIM_DOMAIN) {
|
||||
if(obit != ob) {
|
||||
//snprintf(debugStrBuffer,256,"fluidsimBake::warning - More than one domain!\n"); elbeemDebugOut(debugStrBuffer);
|
||||
if( fluidmdtmp &&(obit->type==OB_MESH))
|
||||
{
|
||||
if(fluidmdtmp->fss->type == OB_FLUIDSIM_DOMAIN)
|
||||
{
|
||||
if(obit != ob)
|
||||
{
|
||||
pupmenu("Fluidsim Bake Error%t|There should be only one domain object! Aborted%x0");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if theres any fluid
|
||||
// abort baking if not...
|
||||
for(base=G.scene->base.first; base; base= base->next)
|
||||
{
|
||||
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
|
||||
obit = base->object;
|
||||
if( fluidmdtmp &&
|
||||
(obit->type==OB_MESH) &&
|
||||
((fluidmdtmp->fss->type == OB_FLUIDSIM_FLUID) ||
|
||||
(fluidmdtmp->fss->type == OB_FLUIDSIM_INFLOW) ))
|
||||
{
|
||||
haveSomeFluid = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!haveSomeFluid) {
|
||||
pupmenu("Fluidsim Bake Error%t|No fluid objects in scene... Aborted%x0");
|
||||
return;
|
||||
}
|
||||
|
||||
/* these both have to be valid, otherwise we wouldnt be here */
|
||||
/* dont use ob here after...*/
|
||||
fsDomain = ob;
|
||||
domainSettings = ob->fluidsimSettings;
|
||||
fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
domainSettings = fluidmd->fss;
|
||||
ob = NULL;
|
||||
mesh = fsDomain->data;
|
||||
|
||||
// calculate bounding box
|
||||
fluid_get_bb(mesh->mvert, mesh->totvert, fsDomain->obmat, domainSettings->bbStart, domainSettings->bbSize);
|
||||
|
||||
/* rough check of settings... */
|
||||
if(domainSettings->previewresxyz > domainSettings->resolutionxyz) {
|
||||
snprintf(debugStrBuffer,256,"fluidsimBake::warning - Preview (%d) >= Resolution (%d)... setting equal.\n", domainSettings->previewresxyz , domainSettings->resolutionxyz);
|
||||
@ -639,23 +529,6 @@ void fluidsimBake(struct Object *ob)
|
||||
}
|
||||
snprintf(debugStrBuffer,256,"fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name , gridlevels );
|
||||
elbeemDebugOut(debugStrBuffer);
|
||||
|
||||
// check if theres any fluid
|
||||
// abort baking if not...
|
||||
for(base=G.scene->base.first; base; base= base->next) {
|
||||
obit = base->object;
|
||||
if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
|
||||
(obit->type==OB_MESH) && (
|
||||
(obit->fluidsimSettings->type == OB_FLUIDSIM_FLUID) ||
|
||||
(obit->fluidsimSettings->type == OB_FLUIDSIM_INFLOW) )
|
||||
) {
|
||||
haveSomeFluid = 1;
|
||||
}
|
||||
}
|
||||
if(!haveSomeFluid) {
|
||||
pupmenu("Fluidsim Bake Error%t|No fluid objects in scene... Aborted%x0");
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare names...
|
||||
strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
|
||||
@ -719,8 +592,8 @@ void fluidsimBake(struct Object *ob)
|
||||
// dump data for start frame
|
||||
// CHECK more reasonable to number frames according to blender?
|
||||
// dump data for frame 0
|
||||
G.scene->r.cfra = startFrame;
|
||||
scene_update_for_newframe(G.scene, G.scene->lay);
|
||||
G.scene->r.cfra = startFrame;
|
||||
scene_update_for_newframe(G.scene, G.scene->lay);
|
||||
|
||||
// init common export vars for both file export and run
|
||||
for(i=0; i<256; i++) {
|
||||
@ -743,9 +616,8 @@ void fluidsimBake(struct Object *ob)
|
||||
calcViscosity = fluidsimViscosityPreset[ domainSettings->viscosityMode ];
|
||||
}
|
||||
|
||||
bbStart = fsDomain->fluidsimSettings->bbStart;
|
||||
bbSize = fsDomain->fluidsimSettings->bbSize;
|
||||
fluidsimGetAxisAlignedBB(fsDomain->data, fsDomain->obmat, bbStart, bbSize, &domainSettings->meshBB);
|
||||
bbStart = domainSettings->bbStart;
|
||||
bbSize = domainSettings->bbSize;
|
||||
|
||||
// always init
|
||||
{ int timeIcu[1] = { FLUIDSIM_TIME };
|
||||
@ -791,13 +663,15 @@ void fluidsimBake(struct Object *ob)
|
||||
|
||||
// init obj movement channels
|
||||
channelObjCount=0;
|
||||
for(base=G.scene->base.first; base; base= base->next) {
|
||||
for(base=G.scene->base.first; base; base= base->next)
|
||||
{
|
||||
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
|
||||
obit = base->object;
|
||||
//{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
|
||||
if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
|
||||
(obit->type==OB_MESH) &&
|
||||
(obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH
|
||||
(obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE) ) {
|
||||
|
||||
if( fluidmdtmp &&
|
||||
(obit->type==OB_MESH) &&
|
||||
(fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH
|
||||
(fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE) ) {
|
||||
|
||||
// cant use fluidsimInitChannel for obj channels right now, due
|
||||
// to the special DXXX channels, and the rotation specialities
|
||||
@ -824,9 +698,9 @@ void fluidsimBake(struct Object *ob)
|
||||
int activeIcu[1] = { FLUIDSIM_ACTIVE };
|
||||
float activeDefs[1] = { 1 }; // default to on
|
||||
|
||||
inivelDefs[0] = obit->fluidsimSettings->iniVelx;
|
||||
inivelDefs[1] = obit->fluidsimSettings->iniVely;
|
||||
inivelDefs[2] = obit->fluidsimSettings->iniVelz;
|
||||
inivelDefs[0] = fluidmdtmp->fss->iniVelx;
|
||||
inivelDefs[1] = fluidmdtmp->fss->iniVely;
|
||||
inivelDefs[2] = fluidmdtmp->fss->iniVelz;
|
||||
|
||||
// check & init loc,rot,size
|
||||
for(j=0; j<3; j++) {
|
||||
@ -907,19 +781,19 @@ void fluidsimBake(struct Object *ob)
|
||||
float velFSDefs[1];
|
||||
float velFRDefs[1];
|
||||
|
||||
attrFSDefs[0] = obit->fluidsimSettings->attractforceStrength;
|
||||
attrFRDefs[0] = obit->fluidsimSettings->attractforceRadius;
|
||||
velFSDefs[0] = obit->fluidsimSettings->velocityforceStrength;
|
||||
velFRDefs[0] = obit->fluidsimSettings->velocityforceRadius;
|
||||
attrFSDefs[0] = fluidmdtmp->fss->attractforceStrength;
|
||||
attrFRDefs[0] = fluidmdtmp->fss->attractforceRadius;
|
||||
velFSDefs[0] = fluidmdtmp->fss->velocityforceStrength;
|
||||
velFRDefs[0] = fluidmdtmp->fss->velocityforceRadius;
|
||||
|
||||
fluidsimInitChannel( &channelAttractforceStrength[o], allchannelSize, timeAtFrame, attrFSIcu,attrFSDefs, obit->fluidsimSettings->ipo, CHANNEL_FLOAT );
|
||||
fluidsimInitChannel( &channelAttractforceRadius[o], allchannelSize, timeAtFrame, attrFRIcu,attrFRDefs, obit->fluidsimSettings->ipo, CHANNEL_FLOAT );
|
||||
fluidsimInitChannel( &channelVelocityforceStrength[o], allchannelSize, timeAtFrame, velFSIcu,velFSDefs, obit->fluidsimSettings->ipo, CHANNEL_FLOAT );
|
||||
fluidsimInitChannel( &channelVelocityforceRadius[o], allchannelSize, timeAtFrame, velFRIcu,velFRDefs, obit->fluidsimSettings->ipo, CHANNEL_FLOAT );
|
||||
fluidsimInitChannel( &channelAttractforceStrength[o], allchannelSize, timeAtFrame, attrFSIcu,attrFSDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
|
||||
fluidsimInitChannel( &channelAttractforceRadius[o], allchannelSize, timeAtFrame, attrFRIcu,attrFRDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
|
||||
fluidsimInitChannel( &channelVelocityforceStrength[o], allchannelSize, timeAtFrame, velFSIcu,velFSDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
|
||||
fluidsimInitChannel( &channelVelocityforceRadius[o], allchannelSize, timeAtFrame, velFRIcu,velFRDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
|
||||
}
|
||||
|
||||
fluidsimInitChannel( &channelObjInivel[o], allchannelSize, timeAtFrame, inivelIcu,inivelDefs, obit->fluidsimSettings->ipo, CHANNEL_VEC );
|
||||
fluidsimInitChannel( &channelObjActive[o], allchannelSize, timeAtFrame, activeIcu,activeDefs, obit->fluidsimSettings->ipo, CHANNEL_FLOAT );
|
||||
fluidsimInitChannel( &channelObjInivel[o], allchannelSize, timeAtFrame, inivelIcu,inivelDefs, fluidmdtmp->fss->ipo, CHANNEL_VEC );
|
||||
fluidsimInitChannel( &channelObjActive[o], allchannelSize, timeAtFrame, activeIcu,activeDefs, fluidmdtmp->fss->ipo, CHANNEL_FLOAT );
|
||||
|
||||
|
||||
channelObjCount++;
|
||||
@ -959,6 +833,7 @@ void fluidsimBake(struct Object *ob)
|
||||
// setup global settings
|
||||
for(i=0 ; i<3; i++) fsset.geoStart[i] = bbStart[i];
|
||||
for(i=0 ; i<3; i++) fsset.geoSize[i] = bbSize[i];
|
||||
|
||||
// simulate with 50^3
|
||||
fsset.resolutionxyz = (int)domainSettings->resolutionxyz;
|
||||
fsset.previewresxyz = (int)domainSettings->previewresxyz;
|
||||
@ -1019,22 +894,23 @@ void fluidsimBake(struct Object *ob)
|
||||
// init objects
|
||||
channelObjCount = 0;
|
||||
for(base=G.scene->base.first; base; base= base->next) {
|
||||
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(base->object, eModifierType_Fluidsim);
|
||||
obit = base->object;
|
||||
//{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
|
||||
if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && // if has to match 3 places! // CHECKMATCH
|
||||
(obit->type==OB_MESH) &&
|
||||
(obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) &&
|
||||
(obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE)
|
||||
) {
|
||||
if( fluidmdtmp && // if has to match 3 places! // CHECKMATCH
|
||||
(obit->type==OB_MESH) &&
|
||||
(fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN) &&
|
||||
(fluidmdtmp->fss->type != OB_FLUIDSIM_PARTICLE))
|
||||
{
|
||||
float *verts=NULL;
|
||||
int *tris=NULL;
|
||||
int numVerts=0, numTris=0;
|
||||
int o = channelObjCount;
|
||||
int deform = (obit->fluidsimSettings->domainNovecgen); // misused value
|
||||
int deform = (fluidmdtmp->fss->domainNovecgen); // misused value
|
||||
// todo - use blenderInitElbeemMesh
|
||||
elbeemMesh fsmesh;
|
||||
elbeemResetMesh( &fsmesh );
|
||||
fsmesh.type = obit->fluidsimSettings->type;
|
||||
fsmesh.type = fluidmdtmp->fss->type;
|
||||
// get name of object for debugging solver
|
||||
fsmesh.name = obit->id.name;
|
||||
|
||||
@ -1057,24 +933,24 @@ void fluidsimBake(struct Object *ob)
|
||||
if( (fsmesh.type == OB_FLUIDSIM_FLUID) ||
|
||||
(fsmesh.type == OB_FLUIDSIM_INFLOW)) {
|
||||
fsmesh.channelInitialVel = channelObjInivel[o];
|
||||
fsmesh.localInivelCoords = ((obit->fluidsimSettings->typeFlags&OB_FSINFLOW_LOCALCOORD)?1:0);
|
||||
fsmesh.localInivelCoords = ((fluidmdtmp->fss->typeFlags&OB_FSINFLOW_LOCALCOORD)?1:0);
|
||||
}
|
||||
|
||||
if( (obit->fluidsimSettings->typeFlags&OB_FSBND_NOSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP;
|
||||
else if((obit->fluidsimSettings->typeFlags&OB_FSBND_PARTSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_PARTSLIP;
|
||||
else if((obit->fluidsimSettings->typeFlags&OB_FSBND_FREESLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_FREESLIP;
|
||||
fsmesh.obstaclePartslip = obit->fluidsimSettings->partSlipValue;
|
||||
fsmesh.volumeInitType = obit->fluidsimSettings->volumeInitType;
|
||||
fsmesh.obstacleImpactFactor = obit->fluidsimSettings->surfaceSmoothing; // misused value
|
||||
if( (fluidmdtmp->fss->typeFlags&OB_FSBND_NOSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP;
|
||||
else if((fluidmdtmp->fss->typeFlags&OB_FSBND_PARTSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_PARTSLIP;
|
||||
else if((fluidmdtmp->fss->typeFlags&OB_FSBND_FREESLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_FREESLIP;
|
||||
fsmesh.obstaclePartslip = fluidmdtmp->fss->partSlipValue;
|
||||
fsmesh.volumeInitType = fluidmdtmp->fss->volumeInitType;
|
||||
fsmesh.obstacleImpactFactor = fluidmdtmp->fss->surfaceSmoothing; // misused value
|
||||
|
||||
if(fsmesh.type == OB_FLUIDSIM_CONTROL)
|
||||
{
|
||||
// control fluids will get exported as whole
|
||||
deform = 1;
|
||||
|
||||
fsmesh.cpsTimeStart = obit->fluidsimSettings->cpsTimeStart;
|
||||
fsmesh.cpsTimeEnd = obit->fluidsimSettings->cpsTimeEnd;
|
||||
fsmesh.cpsQuality = obit->fluidsimSettings->cpsQuality;
|
||||
fsmesh.cpsTimeStart = fluidmdtmp->fss->cpsTimeStart;
|
||||
fsmesh.cpsTimeEnd = fluidmdtmp->fss->cpsTimeEnd;
|
||||
fsmesh.cpsQuality = fluidmdtmp->fss->cpsQuality;
|
||||
|
||||
fsmesh.channelSizeAttractforceRadius =
|
||||
fsmesh.channelSizeVelocityforceStrength =
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_fluidsim.h"
|
||||
#include "DNA_particle_types.h"
|
||||
@ -68,6 +69,7 @@
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_utildefines.h"
|
||||
@ -162,12 +164,13 @@ void spaceipo_assign_ipo(SpaceIpo *si, Ipo *ipo)
|
||||
}
|
||||
}
|
||||
else if(si->blocktype==ID_FLUIDSIM) { // NT
|
||||
if( (ob->fluidsimSettings) &&
|
||||
(ob->fluidsimSettings->ipo) ) {
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
if( fluidmd && fluidmd->fss &&
|
||||
(fluidmd->fss->ipo) ) {
|
||||
// decrement users counter
|
||||
ob->fluidsimSettings->ipo->id.us--;
|
||||
fluidmd->fss->ipo->id.us--;
|
||||
}
|
||||
ob->fluidsimSettings->ipo = ipo;
|
||||
fluidmd->fss->ipo = ipo;
|
||||
}
|
||||
else if(si->blocktype==ID_PA) {
|
||||
ParticleSystem *psys=psys_get_current(ob);
|
||||
@ -974,6 +977,8 @@ static char *ipo_modeselect_pup(void)
|
||||
str += sprintf(str,formatstring, "Texture",ID_TE, ICON_TEXTURE);
|
||||
|
||||
if(ob){
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
|
||||
if ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_LATTICE)
|
||||
str += sprintf(str,formatstring, "Shape",ID_KE, ICON_EDIT);
|
||||
if (ob->type==OB_ARMATURE)
|
||||
@ -981,7 +986,7 @@ static char *ipo_modeselect_pup(void)
|
||||
#ifdef __CON_IPO
|
||||
str += sprintf(str,formatstring, "Constraint",ID_CO, ICON_CONSTRAINT);
|
||||
#endif
|
||||
if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
|
||||
if(fluidmd) {
|
||||
str += sprintf(str,formatstring,"Fluidsim",ID_FLUIDSIM, ICON_WORLD);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user