diff options
author | Nils Thuerey <nils@thuerey.de> | 2005-11-09 10:56:26 +0300 |
---|---|---|
committer | Nils Thuerey <nils@thuerey.de> | 2005-11-09 10:56:26 +0300 |
commit | e3f681da67989ed87a270a2c07849265d44bb7da (patch) | |
tree | 0f08613c0a39187dd7dbb84df7ff45f39936c36f | |
parent | 564b62901346ba0f40032616c51ac7da1c703a54 (diff) |
- popup menu now aborts by default
- changed directory/prefix input (only 1 string instead of two, more similar to render output settings now)
- changed reading/writing of surface files
- slightly enhanced surface smoothness
-rw-r--r-- | intern/elbeem/intern/blendercall.cpp | 11 | ||||
-rw-r--r-- | intern/elbeem/intern/ntl_world.cpp | 7 | ||||
-rw-r--r-- | intern/elbeem/intern/parametrizer.cpp | 9 | ||||
-rw-r--r-- | intern/elbeem/intern/solver_class.h | 1 | ||||
-rw-r--r-- | intern/elbeem/intern/solver_init.cpp | 28 | ||||
-rw-r--r-- | intern/elbeem/intern/solver_interface.cpp | 5 | ||||
-rw-r--r-- | intern/elbeem/intern/solver_main.cpp | 144 | ||||
-rw-r--r-- | intern/elbeem/intern/solver_relax.h | 40 | ||||
-rw-r--r-- | intern/elbeem/intern/solver_util.cpp | 10 | ||||
-rw-r--r-- | intern/elbeem/intern/utilities.cpp | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 277 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_fluidsim.h | 7 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 52 | ||||
-rw-r--r-- | source/blender/src/fluidsim.c | 145 |
15 files changed, 400 insertions, 355 deletions
diff --git a/intern/elbeem/intern/blendercall.cpp b/intern/elbeem/intern/blendercall.cpp index 2d241ae623a..847dbdd4843 100644 --- a/intern/elbeem/intern/blendercall.cpp +++ b/intern/elbeem/intern/blendercall.cpp @@ -13,18 +13,15 @@ #include "ntl_blenderdumper.h" #include <stdlib.h> +extern "C" void elbeemCheckDebugEnv(void); + extern "C" int performElbeemSimulation(char *cfgfilename) { - const char *strEnvName = "BLENDER_ELBEEMDEBUG"; gWorldState = SIMWORLD_INVALID; strcpy(gWorldStringState,"[none]"); - if(getenv(strEnvName)) { - gDebugLevel = atoi(getenv(strEnvName)); - if(gDebugLevel< 0) gDebugLevel = 0; - if(gDebugLevel>10) gDebugLevel = 0; // only use valid values - if(gDebugLevel>0) debMsgStd("performElbeemSimulation",DM_NOTIFY,"Using envvar '"<<strEnvName<<"'='"<<getenv(strEnvName)<<"', debugLevel set to: "<<gDebugLevel<<"\n", 1); - } + //if(gDebugLevel>0) { + elbeemCheckDebugEnv(); debMsgStd("performElbeemSimulation",DM_NOTIFY,"Running El'Beem from Blender with file '"<< cfgfilename <<"', debugLevel:"<<gDebugLevel<<" ...\n", 2); //} // load given file in command line mode diff --git a/intern/elbeem/intern/ntl_world.cpp b/intern/elbeem/intern/ntl_world.cpp index bd7a6abeb6f..b2677fe7011 100644 --- a/intern/elbeem/intern/ntl_world.cpp +++ b/intern/elbeem/intern/ntl_world.cpp @@ -176,8 +176,10 @@ int ntlWorld::renderAnimation( void ) mThreadRunning = true; // not threaded, but still use the same flags renderScene(); for(int i=0; ((i<mpGlob->getAniFrames()) && (!getStopRenderVisualization() )); i++) { - advanceSims(); - renderScene(); + if(!advanceSims()) { + renderScene(); + } // else means sim panicked, so dont render... + #if ELBEEM_BLENDER==1 // update gui display simulateThreadIncreaseFrame(); @@ -305,6 +307,7 @@ int ntlWorld::advanceSims() if(allPanic) { warnMsg("ntlWorld::advanceSims","All sims panicked... stopping thread" ); setStopRenderVisualization( true ); + return 1; } for(size_t i=0;i<mpSims->size();i++) { SimulationObject *sim = (*mpSims)[i]; diff --git a/intern/elbeem/intern/parametrizer.cpp b/intern/elbeem/intern/parametrizer.cpp index 6f6d275aa2f..c2126314c0a 100644 --- a/intern/elbeem/intern/parametrizer.cpp +++ b/intern/elbeem/intern/parametrizer.cpp @@ -204,10 +204,15 @@ int Parametrizer::calculateAniStart( void ) { /*! get no of steps for a single animation frame */ int Parametrizer::calculateAniStepsPerFrame( void ) { if(!checkSeenValues(PARAM_ANIFRAMETIME)) { - errFatal("Parametrizer::calculateAniStepsPerFrame", " Missing ani frame time argument!", SIMWORLD_INITERROR); + errFatal("Parametrizer::calculateAniStepsPerFrame", "Missing ani frame time argument!", SIMWORLD_INITERROR); return 1; } - return (int)(mAniFrameTime/mStepTime); + int value = (int)(mAniFrameTime/mStepTime); + if((value<0) || (value>1000000)) { + errFatal("Parametrizer::calculateAniStepsPerFrame", "Invalid step-time (="<<mAniFrameTime<<") <> ani-frame-time ("<<mStepTime<<") settings, aborting...", SIMWORLD_INITERROR); + return 1; + } + return value; } /*! get extent of the domain = (1,1,1) if parametrizer not used, (x,y,z) [m] otherwise */ diff --git a/intern/elbeem/intern/solver_class.h b/intern/elbeem/intern/solver_class.h index 214113e5093..40e562b1ab0 100644 --- a/intern/elbeem/intern/solver_class.h +++ b/intern/elbeem/intern/solver_class.h @@ -470,6 +470,7 @@ class LbmFsgrSolver : #if ELBEEM_BLENDER!=1 // test functions + bool mUseTestdata; LbmTestdata *mpTest; void initTestdata(); void destroyTestdata(); diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp index 5d692d8ae52..99db4bc433f 100644 --- a/intern/elbeem/intern/solver_init.cpp +++ b/intern/elbeem/intern/solver_init.cpp @@ -46,6 +46,9 @@ LbmFsgrSolver<D>::LbmFsgrSolver() : { // not much to do here... D::mpIso = new IsoSurface( D::mIsoValue, false ); +#if ELBEEM_BLENDER!=1 + mpTest = new LbmTestdata(); +#endif // ELBEEM_BLENDER!=1 // init equilibrium dist. func LbmFloat rho=1.0; @@ -112,7 +115,6 @@ template<class D> LbmFsgrSolver<D>::~LbmFsgrSolver() { if(!D::mInitDone){ debugOut("LbmFsgrSolver::LbmFsgrSolver : not inited...",0); return; } - #if COMPRESSGRIDS==1 delete mLevel[mMaxRefine].mprsCells[1]; mLevel[mMaxRefine].mprsCells[0] = mLevel[mMaxRefine].mprsCells[1] = NULL; @@ -128,7 +130,8 @@ LbmFsgrSolver<D>::~LbmFsgrSolver() if(mpPreviewSurface) delete mpPreviewSurface; #if ELBEEM_BLENDER!=1 - destroyTestdata(); + if(mUseTestdata) destroyTestdata(); + delete mpTest; #endif // ELBEEM_BLENDER!=1 // always output performance estimate @@ -179,10 +182,14 @@ LbmFsgrSolver<D>::parseAttrList() mForceTadapRefine = D::mpAttrs->readInt("forcetadaprefine", mForceTadapRefine,"LbmFsgrSolver", "mForceTadapRefine", false); // demo mode settings - mFVHeight = D::mpAttrs->readFloat("fvolheight", mFVHeight, "SimulationLbm","mFVHeight", false ); + mFVHeight = D::mpAttrs->readFloat("fvolheight", mFVHeight, "LbmFsgrSolver","mFVHeight", false ); // FIXME check needed? - mFVArea = D::mpAttrs->readFloat("fvolarea", mFVArea, "SimulationLbm","mFArea", false ); + mFVArea = D::mpAttrs->readFloat("fvolarea", mFVArea, "LbmFsgrSolver","mFArea", false ); +#if ELBEEM_BLENDER!=1 + mUseTestdata = D::mpAttrs->readBool("use_testdata", mUseTestdata,"LbmFsgrSolver", "mUseTestdata", false); + mpTest->parseTestdataAttrList(D::mpAttrs); +#endif // ELBEEM_BLENDER!=1 } @@ -296,12 +303,21 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o int maskBits = mMaxRefine; if(PARALLEL==1) maskBits+=2; for(int i=0; i<maskBits; i++) { sizeMask |= (1<<i); } + + // at least size 4 on coarsest level + int minSize = (int)powf(2.0, maskBits+2.0); + if(D::mSizex<minSize) D::mSizex = minSize; + if(D::mSizey<minSize) D::mSizey = minSize; + if(D::mSizez<minSize) D::mSizez = minSize; +errMsg("MMS","minSize"<<minSize); + sizeMask = ~sizeMask; if(debugGridsizeInit) debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez<<" m"<<convertCellFlagType2String(sizeMask) ,10); D::mSizex &= sizeMask; D::mSizey &= sizeMask; D::mSizez &= sizeMask; - // force geom size to match rounded grid sizes + + // force geom size to match rounded/modified grid sizes D::mvGeoEnd[0] = D::mvGeoStart[0] + cellSize*(LbmFloat)D::mSizex; D::mvGeoEnd[1] = D::mvGeoStart[1] + cellSize*(LbmFloat)D::mSizey; D::mvGeoEnd[2] = D::mvGeoStart[2] + cellSize*(LbmFloat)D::mSizez; @@ -1027,7 +1043,7 @@ LbmFsgrSolver<D>::initGeometryFlags() { } // zmax #if ELBEEM_BLENDER!=1 - initTestdata(); + if(mUseTestdata) initTestdata(); #endif // ELBEEM_BLENDER!=1 D::freeGeoTree(); myTime_t geotimeend = getTime(); diff --git a/intern/elbeem/intern/solver_interface.cpp b/intern/elbeem/intern/solver_interface.cpp index 3d77e4a4968..58f9abb05ed 100644 --- a/intern/elbeem/intern/solver_interface.cpp +++ b/intern/elbeem/intern/solver_interface.cpp @@ -406,8 +406,9 @@ void LbmSolverInterface::initGeoTree(int id) { if(mpGiTree != NULL) delete mpGiTree; char treeFlag = (1<<(mGeoInitId+4)); - mpGiTree = new ntlTree( 20, 4, // warning - fixed values for depth & maxtriangles here... - scene, treeFlag ); + mpGiTree = new ntlTree( + 15, 8, // warning - fixed values for depth & maxtriangles here... + scene, treeFlag ); } /*****************************************************************************/ diff --git a/intern/elbeem/intern/solver_main.cpp b/intern/elbeem/intern/solver_main.cpp index c62b8f87321..a8785da15f1 100644 --- a/intern/elbeem/intern/solver_main.cpp +++ b/intern/elbeem/intern/solver_main.cpp @@ -235,7 +235,7 @@ LbmFsgrSolver<D>::stepMain() } // */ #if ELBEEM_BLENDER!=1 - handleTestdata(); + if(mUseTestdata) handleTestdata(); #endif // ELBEEM_BLENDER!=1 } @@ -299,9 +299,6 @@ LbmFsgrSolver<D>::mainLoop(int lev) // local to loop CellFlagType nbflag[LBM_DFNUM]; -#define NBFLAG(l) nbflag[(l)] - // */ - LbmFloat *ccel = NULL; LbmFloat *tcel = NULL; int oldFlag; @@ -318,9 +315,14 @@ LbmFsgrSolver<D>::mainLoop(int lev) // ifempty cell conversion flags bool iffilled, ifemptied; + LbmFloat nbfracs[LBM_DFNUM]; // ffracs of neighbors int recons[LBM_DFNUM]; // reconstruct this DF? int numRecons; // how many are reconstructed? + // slow surf regions smooth (if below) + const LbmFloat smoothStrength = 0.0; //0.01; + const LbmFloat sssUsqrLimit = 1.5 * 0.03*0.03; + const LbmFloat sssUsqrLimitInv = 1.0/sssUsqrLimit; CellFlagType *pFlagSrc; CellFlagType *pFlagDst; @@ -468,8 +470,6 @@ LbmFsgrSolver<D>::mainLoop(int lev) if(oldFlag & (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)) { *pFlagDst = oldFlag; - //RAC(tcel,dFfrac) = 0.0; - //RAC(tcel,dFlux) = FLUX_INIT; // necessary? continue; } /*if( oldFlag & CFNoBndFluid ) { // TEST ME FASTER? @@ -552,8 +552,6 @@ LbmFsgrSolver<D>::mainLoop(int lev) // "normal" fluid cells RAC(tcel,dFfrac) = 1.0; *pFlagDst = (CellFlagType)oldFlag; // newFlag; - //? LbmFloat ofrho=RAC(ccel,0); for(int l=1; l<D::cDfNum; l++) { ofrho += RAC(ccel,l); } -//FST errMsg("TTTfl","at "<<PRINT_IJK<<", rho"<<rho ); calcCurrentMass += rho; calcCurrentVolume += 1.0; continue; @@ -594,23 +592,31 @@ LbmFsgrSolver<D>::mainLoop(int lev) FORDF1 { // dfl loop recons[l] = 0; + nbfracs[l] = 0.0; // finally, "normal" interface cells ---- - if( NBFLAG(l)&(CFFluid|CFBnd) ) { // NEWTEST! FIXME check!!!!!!!!!!!!!!!!!! + if( nbflag[l]&(CFFluid|CFBnd) ) { // NEWTEST! FIXME check!!!!!!!!!!!!!!!!!! change = nbdf(l) - MYDF(l); } // interface cells - distuingish cells that shouldn't fill/empty - else if( NBFLAG(l) & CFInter ) { + else if( nbflag[l] & CFInter ) { - LbmFloat mynbfac = //numNbs[l] / numNbs[0]; - QCELL_NB(lev, i,j,k,SRCS(lev),l, dFlux) / QCELL(lev, i,j,k,SRCS(lev), dFlux); - LbmFloat nbnbfac = 1.0/mynbfac; - //mynbfac = nbnbfac = 1.0; // switch calc flux off - // OLD - if ((oldFlag|NBFLAG(l))&(CFNoNbFluid|CFNoNbEmpty)) { + LbmFloat mynbfac,nbnbfac; + // NEW TEST t1 + // t2 -> off + if((oldFlag&CFNoBndFluid)&&(nbflag[l]&CFNoBndFluid)) { + mynbfac = QCELL_NB(lev, i,j,k,SRCS(lev),l, dFlux) / QCELL(lev, i,j,k,SRCS(lev), dFlux); + nbnbfac = 1.0/mynbfac; + } else { + mynbfac = nbnbfac = 1.0; // switch calc flux off + } + //mynbfac = nbnbfac = 1.0; // switch calc flux off t3 + + // perform interface case handling + if ((oldFlag|nbflag[l])&(CFNoNbFluid|CFNoNbEmpty)) { switch (oldFlag&(CFNoNbFluid|CFNoNbEmpty)) { case 0: // we are a normal cell so... - switch (NBFLAG(l)&(CFNoNbFluid|CFNoNbEmpty)) { + switch (nbflag[l]&(CFNoNbFluid|CFNoNbEmpty)) { case CFNoNbFluid: // just fill current cell = empty neighbor change = nbnbfac*nbdf(l) ; goto changeDone; @@ -622,7 +628,7 @@ LbmFsgrSolver<D>::mainLoop(int lev) case CFNoNbFluid: // we dont have fluid nb's so... - switch (NBFLAG(l)&(CFNoNbFluid|CFNoNbEmpty)) { + switch (nbflag[l]&(CFNoNbFluid|CFNoNbEmpty)) { case 0: case CFNoNbEmpty: // we have no fluid nb's -> just empty @@ -632,7 +638,7 @@ LbmFsgrSolver<D>::mainLoop(int lev) case CFNoNbEmpty: // we dont have empty nb's so... - switch (NBFLAG(l)&(CFNoNbFluid|CFNoNbEmpty)) { + switch (nbflag[l]&(CFNoNbFluid|CFNoNbEmpty)) { case 0: case CFNoNbFluid: // we have no empty nb's -> just fill @@ -644,19 +650,18 @@ LbmFsgrSolver<D>::mainLoop(int lev) // just do normal mass exchange... change = ( nbnbfac*nbdf(l) - mynbfac*MYDF(l) ) ; changeDone: ; - change *= ( myfrac + QCELL_NB(lev, i,j,k, SRCS(lev),l, dFfrac) ) * 0.5; + nbfracs[l] = QCELL_NB(lev, i,j,k, SRCS(lev),l, dFfrac); + change *= (myfrac + nbfracs[l]) * 0.5; } // the other cell is interface // last alternative - reconstruction in this direction else { - //if(NBFLAG(l) & CFEmpty) { recons[l] = true; } + // empty + bnd case recons[l] = 1; numRecons++; change = 0.0; - // which case is this...? empty + bnd } - //FST errMsg("TTTIF","at "<<PRINT_IJK<<",l"<<l<<" m"<<mass<<",c"<<change<<" nbflag"<<convertCellFlagType2String(NBFLAG(l))<<" nbdf"<<nbdf(l)<<" mydf"<<MYDF(l)<<" isflix"<<((NBFLAG(l)&(CFFluid|CFBnd) )!=0) ); // modify mass at SRCS mass += change; } // l @@ -665,15 +670,15 @@ LbmFsgrSolver<D>::mainLoop(int lev) LbmFloat nv1,nv2; LbmFloat nx,ny,nz; - if(NBFLAG(dE) &(CFFluid|CFInter)){ nv1 = RAC((ccel+QCELLSTEP ),dFfrac); } else nv1 = 0.0; - if(NBFLAG(dW) &(CFFluid|CFInter)){ nv2 = RAC((ccel-QCELLSTEP ),dFfrac); } else nv2 = 0.0; + if(nbflag[dE] &(CFFluid|CFInter)){ nv1 = RAC((ccel+QCELLSTEP ),dFfrac); } else nv1 = 0.0; + if(nbflag[dW] &(CFFluid|CFInter)){ nv2 = RAC((ccel-QCELLSTEP ),dFfrac); } else nv2 = 0.0; nx = 0.5* (nv2-nv1); - if(NBFLAG(dN) &(CFFluid|CFInter)){ nv1 = RAC((ccel+(mLevel[lev].lOffsx*QCELLSTEP)),dFfrac); } else nv1 = 0.0; - if(NBFLAG(dS) &(CFFluid|CFInter)){ nv2 = RAC((ccel-(mLevel[lev].lOffsx*QCELLSTEP)),dFfrac); } else nv2 = 0.0; + if(nbflag[dN] &(CFFluid|CFInter)){ nv1 = RAC((ccel+(mLevel[lev].lOffsx*QCELLSTEP)),dFfrac); } else nv1 = 0.0; + if(nbflag[dS] &(CFFluid|CFInter)){ nv2 = RAC((ccel-(mLevel[lev].lOffsx*QCELLSTEP)),dFfrac); } else nv2 = 0.0; ny = 0.5* (nv2-nv1); #if LBMDIM==3 - if(NBFLAG(dT) &(CFFluid|CFInter)){ nv1 = RAC((ccel+(mLevel[lev].lOffsy*QCELLSTEP)),dFfrac); } else nv1 = 0.0; - if(NBFLAG(dB) &(CFFluid|CFInter)){ nv2 = RAC((ccel-(mLevel[lev].lOffsy*QCELLSTEP)),dFfrac); } else nv2 = 0.0; + if(nbflag[dT] &(CFFluid|CFInter)){ nv1 = RAC((ccel+(mLevel[lev].lOffsy*QCELLSTEP)),dFfrac); } else nv1 = 0.0; + if(nbflag[dB] &(CFFluid|CFInter)){ nv2 = RAC((ccel-(mLevel[lev].lOffsy*QCELLSTEP)),dFfrac); } else nv2 = 0.0; nz = 0.5* (nv2-nv1); #else // LBMDIM==3 nz = 0.0; @@ -769,15 +774,13 @@ LbmFsgrSolver<D>::mainLoop(int lev) if(recons[dWB]) { m[dET] = EQWB + EQET - MYDF(dWB); } #endif - // mass streaming done... - // now collide new fluid or "old" if cells + // mass streaming done... do normal collide ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; DEFAULT_COLLIDE; - rho = m[dC]; - FORDF1 { rho+=m[l]; }; - // only with interface neighbors...? PERFORM_USQRMAXCHECK; + // rho init from default collide necessary for fill/empty check below + // inflow bc handling if(oldFlag & (CFMbndInflow)) { // fill if cells in inflow region if(myfrac<0.5) { @@ -802,24 +805,26 @@ LbmFsgrSolver<D>::mainLoop(int lev) // looks much nicer... LISTTRICK #if FSGR_LISTTRICK==1 - if(!iffilled) { - // remove cells independent from amount of change... - if( (oldFlag & CFNoNbEmpty)&&(newFlag & CFNoNbEmpty)&& - ( (mass>(rho*FSGR_LISTTTHRESHFULL)) || ((nbored&CFInter)==0) ) - ) { - //if((nbored&CFInter)==0){ errMsg("NBORED!CFINTER","filled "<<PRINT_IJK); }; - iffilled = 1; - } - } - if(!ifemptied) { - if( (oldFlag & CFNoNbFluid)&&(newFlag & CFNoNbFluid)&& - ( (mass<(rho*FSGR_LISTTTHRESHEMPTY)) || ((nbored&CFInter)==0) ) - ) - { - //if((nbored&CFInter)==0){ errMsg("NBORED!CFINTER","emptied "<<PRINT_IJK); }; - ifemptied = 1; - } - } // */ + if(newFlag&CFNoBndFluid) { // test NEW TEST + if(!iffilled) { + // remove cells independent from amount of change... + if( (oldFlag & CFNoNbEmpty)&&(newFlag & CFNoNbEmpty)&& + ( (mass>(rho*FSGR_LISTTTHRESHFULL)) || ((nbored&CFInter)==0) ) + ) { + //if((nbored&CFInter)==0){ errMsg("NBORED!CFINTER","filled "<<PRINT_IJK); }; + iffilled = 1; + } + } + if(!ifemptied) { + if( (oldFlag & CFNoNbFluid)&&(newFlag & CFNoNbFluid)&& + ( (mass<(rho*FSGR_LISTTTHRESHEMPTY)) || ((nbored&CFInter)==0) ) + ) + { + //if((nbored&CFInter)==0){ errMsg("NBORED!CFINTER","emptied "<<PRINT_IJK); }; + ifemptied = 1; + } + } + } // nobndfluid only */ #endif //iffilled = ifemptied = 0; // DEBUG!!!!!!!!!!!!!!! @@ -855,21 +860,31 @@ LbmFsgrSolver<D>::mainLoop(int lev) RAC(tcel,dFfrac) = (mass/rho); // init new flux value - float flux = 0.5*(float)(D::cDfNum); // dxqn on - //flux = 50.0; // extreme on - for(int nn=1; nn<D::cDfNum; nn++) { - if(RFLAG_NB(lev, i,j,k,SRCS(lev),nn) & (CFFluid|CFInter|CFBnd)) { - flux += D::dfLength[nn]; + float flux = FLUX_INIT; // dxqn on + if(newFlag&CFNoBndFluid) { + //flux = 50.0; // extreme on + for(int nn=1; nn<D::cDfNum; nn++) { + if(nbflag[nn] & (CFFluid|CFInter|CFBnd)) { flux += D::dfLength[nn]; } } - } - //flux = FLUX_INIT; // calc flux off + // optical hack - smooth slow moving + // surface regions + if(usqr< sssUsqrLimit) { + for(int nn=1; nn<D::cDfNum; nn++) { + if(nbfracs[nn]!=0.0) { + LbmFloat curSmooth = (sssUsqrLimit-usqr)*sssUsqrLimitInv; + if(curSmooth>1.0) curSmooth=1.0; + flux *= (1.0+ smoothStrength*curSmooth * (nbfracs[nn]-myfrac)) ; + } + } } + // NEW TEST */ + } + // flux = FLUX_INIT; // calc flux off QCELL(lev, i,j,k,TSET(lev), dFlux) = flux; // */ // perform mass exchange with streamed values QCELL(lev, i,j,k,TSET(lev), dMass) = mass; // MASST // set new flag *pFlagDst = (CellFlagType)newFlag; -//FST errMsg("M","i "<<mass); calcCurrentMass += mass; calcCurrentVolume += RAC(tcel,dFfrac); @@ -919,7 +934,6 @@ LbmFsgrSolver<D>::mainLoop(int lev) // check other vars...? } -#undef NBFLAG template<class D> void @@ -2632,6 +2646,7 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet ) int nbored = 0; FORDF1 { nbored |= RFLAG_NB(workLev, i,j,k, workSet,l); } + if((nbored & CFBnd)==0) { RFLAG(workLev,i,j,k, workSet) |= CFNoBndFluid; } if((nbored & CFFluid)==0) { RFLAG(workLev,i,j,k, workSet) |= CFNoNbFluid; } if((nbored & CFEmpty)==0) { RFLAG(workLev,i,j,k, workSet) |= CFNoNbEmpty; } @@ -2674,8 +2689,11 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet ) // everything in one file again #if defined(__APPLE_CC__) #define LBM_FORCEINCLUDE -#include "solver_init.cpp" -#include "solver_util.cpp" +#include "olver_init.cpp" +#include "olver_util.cpp" +#ifdef ELBEEM_BLENDER +REMOVE_FIX +#endif #undef LBM_FORCEINCLUDE #endif // defined(__APPLE_CC__) diff --git a/intern/elbeem/intern/solver_relax.h b/intern/elbeem/intern/solver_relax.h index 9136cc0fd74..aa8b775fb80 100644 --- a/intern/elbeem/intern/solver_relax.h +++ b/intern/elbeem/intern/solver_relax.h @@ -250,7 +250,7 @@ #define DEFAULT_STREAM \ m[dC] = RAC(ccel,dC); \ FORDF1 { \ - CellFlagType nbf = NBFLAG( D::dfInv[l] );\ + CellFlagType nbf = nbflag[ D::dfInv[l] ];\ if(nbf & CFBnd) { \ if(nbf & CFBndNoslip) { \ /* no slip, default */ \ @@ -277,7 +277,7 @@ #define _________________DEFAULT_STREAM \ m[dC] = RAC(ccel,dC); \ FORDF1 { \ - CellFlagType nbf = NBFLAG( D::dfInv[l] );\ + CellFlagType nbf = nbflag[ D::dfInv[l] ];\ if(nbf & CFBnd) { \ if(nbf & CFBndNoslip) { \ /* no slip, default */ \ @@ -400,26 +400,26 @@ m[dET] = CSRC_ET; m[dEB] = CSRC_EB; m[dWT] = CSRC_WT; m[dWB] = CSRC_WB; \ } else { \ /* explicit streaming, normal velocity always zero for obstacles */ \ - if(NBFLAG(dS )&CFBnd) { m[dN ] = RAC(ccel,dS ); } else { m[dN ] = CSRC_N ; } \ - if(NBFLAG(dN )&CFBnd) { m[dS ] = RAC(ccel,dN ); } else { m[dS ] = CSRC_S ; } \ - if(NBFLAG(dW )&CFBnd) { m[dE ] = RAC(ccel,dW ); } else { m[dE ] = CSRC_E ; } \ - if(NBFLAG(dE )&CFBnd) { m[dW ] = RAC(ccel,dE ); } else { m[dW ] = CSRC_W ; } \ - if(NBFLAG(dB )&CFBnd) { m[dT ] = RAC(ccel,dB ); } else { m[dT ] = CSRC_T ; } \ - if(NBFLAG(dT )&CFBnd) { m[dB ] = RAC(ccel,dT ); } else { m[dB ] = CSRC_B ; } \ + if(nbflag[dS ]&CFBnd) { m[dN ] = RAC(ccel,dS ); } else { m[dN ] = CSRC_N ; } \ + if(nbflag[dN ]&CFBnd) { m[dS ] = RAC(ccel,dN ); } else { m[dS ] = CSRC_S ; } \ + if(nbflag[dW ]&CFBnd) { m[dE ] = RAC(ccel,dW ); } else { m[dE ] = CSRC_E ; } \ + if(nbflag[dE ]&CFBnd) { m[dW ] = RAC(ccel,dE ); } else { m[dW ] = CSRC_W ; } \ + if(nbflag[dB ]&CFBnd) { m[dT ] = RAC(ccel,dB ); } else { m[dT ] = CSRC_T ; } \ + if(nbflag[dT ]&CFBnd) { m[dB ] = RAC(ccel,dT ); } else { m[dB ] = CSRC_B ; } \ \ /* also treat free slip here */ \ - if(NBFLAG(dSW)&CFBnd) { if(NBFLAG(dSW)&CFBndNoslip){ m[dNE] = RAC(ccel,dSW); }else{ DEFAULT_STREAM_FREESLIP(dNE,dSW,NBFLAG(dSW));} } else { m[dNE] = CSRC_NE; } \ - if(NBFLAG(dSE)&CFBnd) { if(NBFLAG(dSE)&CFBndNoslip){ m[dNW] = RAC(ccel,dSE); }else{ DEFAULT_STREAM_FREESLIP(dNW,dSE,NBFLAG(dSE));} } else { m[dNW] = CSRC_NW; } \ - if(NBFLAG(dNW)&CFBnd) { if(NBFLAG(dNW)&CFBndNoslip){ m[dSE] = RAC(ccel,dNW); }else{ DEFAULT_STREAM_FREESLIP(dSE,dNW,NBFLAG(dNW));} } else { m[dSE] = CSRC_SE; } \ - if(NBFLAG(dNE)&CFBnd) { if(NBFLAG(dNE)&CFBndNoslip){ m[dSW] = RAC(ccel,dNE); }else{ DEFAULT_STREAM_FREESLIP(dSW,dNE,NBFLAG(dNE));} } else { m[dSW] = CSRC_SW; } \ - if(NBFLAG(dSB)&CFBnd) { if(NBFLAG(dSB)&CFBndNoslip){ m[dNT] = RAC(ccel,dSB); }else{ DEFAULT_STREAM_FREESLIP(dNT,dSB,NBFLAG(dSB));} } else { m[dNT] = CSRC_NT; } \ - if(NBFLAG(dST)&CFBnd) { if(NBFLAG(dST)&CFBndNoslip){ m[dNB] = RAC(ccel,dST); }else{ DEFAULT_STREAM_FREESLIP(dNB,dST,NBFLAG(dST));} } else { m[dNB] = CSRC_NB; } \ - if(NBFLAG(dNB)&CFBnd) { if(NBFLAG(dNB)&CFBndNoslip){ m[dST] = RAC(ccel,dNB); }else{ DEFAULT_STREAM_FREESLIP(dST,dNB,NBFLAG(dNB));} } else { m[dST] = CSRC_ST; } \ - if(NBFLAG(dNT)&CFBnd) { if(NBFLAG(dNT)&CFBndNoslip){ m[dSB] = RAC(ccel,dNT); }else{ DEFAULT_STREAM_FREESLIP(dSB,dNT,NBFLAG(dNT));} } else { m[dSB] = CSRC_SB; } \ - if(NBFLAG(dWB)&CFBnd) { if(NBFLAG(dWB)&CFBndNoslip){ m[dET] = RAC(ccel,dWB); }else{ DEFAULT_STREAM_FREESLIP(dET,dWB,NBFLAG(dWB));} } else { m[dET] = CSRC_ET; } \ - if(NBFLAG(dWT)&CFBnd) { if(NBFLAG(dWT)&CFBndNoslip){ m[dEB] = RAC(ccel,dWT); }else{ DEFAULT_STREAM_FREESLIP(dEB,dWT,NBFLAG(dWT));} } else { m[dEB] = CSRC_EB; } \ - if(NBFLAG(dEB)&CFBnd) { if(NBFLAG(dEB)&CFBndNoslip){ m[dWT] = RAC(ccel,dEB); }else{ DEFAULT_STREAM_FREESLIP(dWT,dEB,NBFLAG(dEB));} } else { m[dWT] = CSRC_WT; } \ - if(NBFLAG(dET)&CFBnd) { if(NBFLAG(dET)&CFBndNoslip){ m[dWB] = RAC(ccel,dET); }else{ DEFAULT_STREAM_FREESLIP(dWB,dET,NBFLAG(dET));} } else { m[dWB] = CSRC_WB; } \ + if(nbflag[dSW]&CFBnd) { if(nbflag[dSW]&CFBndNoslip){ m[dNE] = RAC(ccel,dSW); }else{ DEFAULT_STREAM_FREESLIP(dNE,dSW,nbflag[dSW]);} } else { m[dNE] = CSRC_NE; } \ + if(nbflag[dSE]&CFBnd) { if(nbflag[dSE]&CFBndNoslip){ m[dNW] = RAC(ccel,dSE); }else{ DEFAULT_STREAM_FREESLIP(dNW,dSE,nbflag[dSE]);} } else { m[dNW] = CSRC_NW; } \ + if(nbflag[dNW]&CFBnd) { if(nbflag[dNW]&CFBndNoslip){ m[dSE] = RAC(ccel,dNW); }else{ DEFAULT_STREAM_FREESLIP(dSE,dNW,nbflag[dNW]);} } else { m[dSE] = CSRC_SE; } \ + if(nbflag[dNE]&CFBnd) { if(nbflag[dNE]&CFBndNoslip){ m[dSW] = RAC(ccel,dNE); }else{ DEFAULT_STREAM_FREESLIP(dSW,dNE,nbflag[dNE]);} } else { m[dSW] = CSRC_SW; } \ + if(nbflag[dSB]&CFBnd) { if(nbflag[dSB]&CFBndNoslip){ m[dNT] = RAC(ccel,dSB); }else{ DEFAULT_STREAM_FREESLIP(dNT,dSB,nbflag[dSB]);} } else { m[dNT] = CSRC_NT; } \ + if(nbflag[dST]&CFBnd) { if(nbflag[dST]&CFBndNoslip){ m[dNB] = RAC(ccel,dST); }else{ DEFAULT_STREAM_FREESLIP(dNB,dST,nbflag[dST]);} } else { m[dNB] = CSRC_NB; } \ + if(nbflag[dNB]&CFBnd) { if(nbflag[dNB]&CFBndNoslip){ m[dST] = RAC(ccel,dNB); }else{ DEFAULT_STREAM_FREESLIP(dST,dNB,nbflag[dNB]);} } else { m[dST] = CSRC_ST; } \ + if(nbflag[dNT]&CFBnd) { if(nbflag[dNT]&CFBndNoslip){ m[dSB] = RAC(ccel,dNT); }else{ DEFAULT_STREAM_FREESLIP(dSB,dNT,nbflag[dNT]);} } else { m[dSB] = CSRC_SB; } \ + if(nbflag[dWB]&CFBnd) { if(nbflag[dWB]&CFBndNoslip){ m[dET] = RAC(ccel,dWB); }else{ DEFAULT_STREAM_FREESLIP(dET,dWB,nbflag[dWB]);} } else { m[dET] = CSRC_ET; } \ + if(nbflag[dWT]&CFBnd) { if(nbflag[dWT]&CFBndNoslip){ m[dEB] = RAC(ccel,dWT); }else{ DEFAULT_STREAM_FREESLIP(dEB,dWT,nbflag[dWT]);} } else { m[dEB] = CSRC_EB; } \ + if(nbflag[dEB]&CFBnd) { if(nbflag[dEB]&CFBndNoslip){ m[dWT] = RAC(ccel,dEB); }else{ DEFAULT_STREAM_FREESLIP(dWT,dEB,nbflag[dEB]);} } else { m[dWT] = CSRC_WT; } \ + if(nbflag[dET]&CFBnd) { if(nbflag[dET]&CFBndNoslip){ m[dWB] = RAC(ccel,dET); }else{ DEFAULT_STREAM_FREESLIP(dWB,dET,nbflag[dET]);} } else { m[dWB] = CSRC_WB; } \ } diff --git a/intern/elbeem/intern/solver_util.cpp b/intern/elbeem/intern/solver_util.cpp index 8bf2df99278..60c8b08be67 100644 --- a/intern/elbeem/intern/solver_util.cpp +++ b/intern/elbeem/intern/solver_util.cpp @@ -62,7 +62,12 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) { if( (RFLAG(lev, i,j,k,workSet)&CFInter) && (!(RFLAG(lev, i,j,k,workSet)&CFNoNbEmpty)) ){ // no empty nb interface cells are treated as full val = (QCELL(lev, i,j,k,workSet, dFfrac)); - //if( (!(RFLAG(lev, i,j,k,workSet)&CFNoBndFluid)) &&(RFLAG(lev, i,j,k,workSet)&CFNoNbFluid)){ val += D::mIsoValue; } + /* // flicker-test-fix: no real difference + if( (!(RFLAG(lev, i,j,k,workSet)&CFNoBndFluid)) && + (RFLAG(lev, i,j,k,workSet)&CFNoNbFluid) && + (val<D::mIsoValue) ){ + val = D::mIsoValue*1.1; } + // */ } else { // fluid? val = 1.0; ///27.0; @@ -107,6 +112,7 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) { *D::mpIso->lbmGetData( i+1 , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[26] ); } + /* for(int k=0;k<mLevel[mMaxRefine].lSizez-1;k++) for(int j=0;j<mLevel[mMaxRefine].lSizey-1;j++) { @@ -213,7 +219,7 @@ vector<ntlGeometryObject*> LbmFsgrSolver<D>::getDebugObjects() { debo.push_back( mpPreviewSurface ); } #ifndef ELBEEM_BLENDER - debo.push_back( mpTest ); + if(mUseTestdata) debo.push_back( mpTest ); #endif // ELBEEM_BLENDER return debo; } diff --git a/intern/elbeem/intern/utilities.cpp b/intern/elbeem/intern/utilities.cpp index b9e97de47fb..acc18fc3bf3 100644 --- a/intern/elbeem/intern/utilities.cpp +++ b/intern/elbeem/intern/utilities.cpp @@ -49,6 +49,7 @@ int globalColorSetting = 0; #else // WIN32 int globalColorSetting = 1; #endif // WIN32 +int globalFirstEnvCheck = 0; //----------------------------------------------------------------------------- @@ -290,9 +291,25 @@ void messageOutputFunc(string from, int id, string msg, myTime_t interval) { } // helper functions from external program using elbeem lib (e.g. Blender) +/* set gDebugLevel according to env. var */ +extern "C" +void elbeemCheckDebugEnv(void) { + const char *strEnvName = "BLENDER_ELBEEMDEBUG"; + if(globalFirstEnvCheck) return; + + if(getenv(strEnvName)) { + gDebugLevel = atoi(getenv(strEnvName)); + if(gDebugLevel< 0) gDebugLevel = 0; + if(gDebugLevel>10) gDebugLevel = 0; // only use valid values + if(gDebugLevel>0) debMsgStd("performElbeemSimulation",DM_NOTIFY,"Using envvar '"<<strEnvName<<"'='"<<getenv(strEnvName)<<"', debugLevel set to: "<<gDebugLevel<<"\n", 1); + } + globalFirstEnvCheck = 1; +} + /* elbeem debug output function */ extern "C" void elbeemDebugOut(char *msg) { + elbeemCheckDebugEnv(); // external messages default to debug level 5... if(gDebugLevel<5) return; // delegate to messageOutputFunc diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d06ff068deb..a620ce2fd1e 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1958,136 +1958,7 @@ DerivedMesh *editmesh_get_derived_base(void) } -/* ***************************** fluidsim derived mesh ***************************** */ - -typedef struct { - MeshDerivedMesh mdm; - - /* release whole mesh? */ - char freeMesh; -} FluidsimDerivedMesh; - -#ifdef WIN32 -#ifndef snprintf -#define snprintf _snprintf -#endif -#endif - - -static void fluidsimDM_release(DerivedMesh *dm) -{ - FluidsimDerivedMesh *fsdm = (FluidsimDerivedMesh*) dm; - if(fsdm->freeMesh) { - // similar to free_mesh(fsdm->mdm.me) , but no things like unlink... - if(fsdm->mdm.me->mvert) MEM_freeN(fsdm->mdm.me->mvert); - if(fsdm->mdm.me->medge) MEM_freeN(fsdm->mdm.me->medge); - if(fsdm->mdm.me->mface) MEM_freeN(fsdm->mdm.me->mface); - MEM_freeN(fsdm->mdm.me); - } - - if (fsdm->mdm.freeNors) MEM_freeN(fsdm->mdm.nors); - if (fsdm->mdm.freeVerts) MEM_freeN(fsdm->mdm.verts); - MEM_freeN(fsdm); -} - -DerivedMesh *getFluidsimDerivedMesh(Object *srcob, int useRenderParams, float *extverts, float *nors) { - int i; - Mesh *mesh = NULL; // srcob->ata; - FluidsimDerivedMesh *fsdm; - MeshDerivedMesh *mdm = NULL; - float (*vertCos)[3]; - int displaymode = 0; - int curFrame = G.scene->r.cfra - 1; /* start with 0 */ - char filename[FILE_MAXFILE],filepath[FILE_MAXFILE+FILE_MAXDIR]; - char curWd[FILE_MAXDIR]; - char debugStrBuffer[256]; - //snprintf(debugStrBuffer,256,"getFluidsimDerivedMesh call (obid '%s', rp %d)\n", srcob->id.name, useRenderParams); // debug - - if(!useRenderParams) { - displaymode = srcob->fluidsimSettings->guiDisplayMode; - } else { - displaymode = srcob->fluidsimSettings->renderDisplayMode; - } - - snprintf(debugStrBuffer,256,"getFluidsimDerivedMesh call (obid '%s', rp %d, dm %d)\n", srcob->id.name, useRenderParams, displaymode); // debug - elbeemDebugOut(debugStrBuffer); // debug - - if((displaymode==1) || (G.obedit==srcob)) { - mesh = srcob->data; - return getMeshDerivedMesh(mesh , srcob, NULL); - } - - // init preview frame - if(displaymode==2) { - // use preview - snprintf(filename,FILE_MAXFILE,"%s_surface_preview_%04d.bobj.gz", srcob->fluidsimSettings->surfdataPrefix, curFrame); - } else { - // load final mesh - snprintf(filename,FILE_MAXFILE,"%s_surface_final_%04d.bobj.gz", srcob->fluidsimSettings->surfdataPrefix, curFrame); - } - BLI_getwdN(curWd); - BLI_make_file_string(G.sce, filepath, srcob->fluidsimSettings->surfdataDir, filename); - - //snprintf(debugStrBuffer,256,"getFluidsimDerivedMesh call (obid '%s', rp %d, dm %d) %s \n", srcob->id.name, useRenderParams, displaymode, filepath); // debug - mesh = readBobjgz(filepath, (Mesh*)(srcob->data) ); - if(!mesh) { - // display org. object upon failure - mesh = srcob->data; - return getMeshDerivedMesh(mesh , srcob, NULL); - } - - if((mesh)&&(mesh->totvert>0)) { - make_edges(mesh, 0); // 0 = make all edges draw - // force all edge draw - for(i=0;i<mesh->totedge;i++) { - //mesh->medge[i].flag = ME_EDGEDRAW; - //snprintf(debugStrBuffer,256,"me %d = %d\n",i,mesh->medge[i].flag); - } - } - - // WARNING copied from getMeshDerivedMesh - fsdm = MEM_callocN(sizeof(*fsdm), "getFluidsimDerivedMesh_fsdm"); - fsdm->freeMesh = 1; - mdm = &fsdm->mdm; - vertCos = NULL; - - mdm->dm.getMinMax = meshDM_getMinMax; - mdm->dm.convertToDispListMesh = meshDM_convertToDispListMesh; - mdm->dm.getNumVerts = meshDM_getNumVerts; - mdm->dm.getNumFaces = meshDM_getNumFaces; - mdm->dm.getVertCos = meshDM_getVertCos; - mdm->dm.getVertCo = meshDM_getVertCo; - mdm->dm.getVertNo = meshDM_getVertNo; - mdm->dm.drawVerts = meshDM_drawVerts; - mdm->dm.drawUVEdges = meshDM_drawUVEdges; - mdm->dm.drawEdges = meshDM_drawEdges; - mdm->dm.drawLooseEdges = meshDM_drawLooseEdges; - mdm->dm.drawFacesSolid = meshDM_drawFacesSolid; - mdm->dm.drawFacesColored = meshDM_drawFacesColored; - mdm->dm.drawFacesTex = meshDM_drawFacesTex; - mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; - mdm->dm.drawMappedEdges = meshDM_drawMappedEdges; - mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; - - // use own release function - mdm->dm.release = fluidsimDM_release; - - mdm->ob = srcob; - mdm->me = mesh; - mdm->verts = mesh->mvert; - mdm->nors = NULL; - mdm->freeNors = 0; - mdm->freeVerts = 0; - - /* if (vertCos) { not needed for fluid meshes... */ - // XXX this is kinda ... see getMeshDerivedMesh - mesh_calc_normals(mdm->verts, mdm->me->totvert, mdm->me->mface, mdm->me->totface, &mdm->nors); - mdm->freeNors = 1; - return (DerivedMesh*) mdm; -} - - -/* ***************************** bobj file handling ***************************** */ +/* ************************* fluidsim bobj file handling **************************** */ /* write .bobj.gz file for a mesh object */ @@ -2179,13 +2050,13 @@ void writeBobjgz(char *filename, struct Object *ob) gzwrite(gzf, &(face[3]), sizeof( face[3] )); } } + + snprintf(debugStrBuffer,256,"Done. #Vertices: %d, #Triangles: %d\n", dlm->totvert, dlm->totface ); + elbeemDebugOut(debugStrBuffer); gzclose( gzf ); if(dlm) displistmesh_free(dlm); dm->release(dm); - - snprintf(debugStrBuffer,256,"done. #Vertices: %d, #Triangles: %d\n", dlm->totvert, dlm->totface ); - elbeemDebugOut(debugStrBuffer); } /* read .bobj.gz file into a fluidsimDerivedMesh struct */ @@ -2195,16 +2066,19 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm) char debugStrBuffer[256]; float wrf; Mesh *newmesh; - const int debugBobjRead = 0; + const int debugBobjRead = 1; // init data from old mesh (materials,flags) MFace *origMFace = &((MFace*) orgmesh->mface)[0]; - int mat_nr = origMFace->mat_nr; - int flag = origMFace->flag; + 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); @@ -2291,10 +2165,6 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm) fsface[i].v4 = face[3]; } - /*if(debugBobjRead) { - for(i=0; i<newmesh->totvert; i++) { snprintf(debugStrBuffer,256,"V %d = %f,%f,%f \n",i, newmesh->mvert[i].co[0],newmesh->mvert[i].co[1],newmesh->mvert[i].co[2] ); } - for(i=0; i<newmesh->totface; i++) { snprintf(debugStrBuffer,256,"F %d = %d,%d,%d,%d \n",i, fsface[i].v1,fsface[i].v2,fsface[i].v3,fsface[i].v4); } - } // debug */ // correct triangles with v3==0 for blender, cycle verts for(i=0; i<newmesh->totface; i++) { if(!fsface[i].v3) { @@ -2317,3 +2187,130 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm) return newmesh; } + +/* ***************************** fluidsim derived mesh ***************************** */ + +typedef struct { + MeshDerivedMesh mdm; + + /* release whole mesh? */ + char freeMesh; +} FluidsimDerivedMesh; + +#ifdef WIN32 +#ifndef snprintf +#define snprintf _snprintf +#endif +#endif + + +static void fluidsimDM_release(DerivedMesh *dm) +{ + FluidsimDerivedMesh *fsdm = (FluidsimDerivedMesh*) dm; + if(fsdm->freeMesh) { + // similar to free_mesh(fsdm->mdm.me) , but no things like unlink... + if(fsdm->mdm.me->mvert) MEM_freeN(fsdm->mdm.me->mvert); + if(fsdm->mdm.me->medge) MEM_freeN(fsdm->mdm.me->medge); + if(fsdm->mdm.me->mface) MEM_freeN(fsdm->mdm.me->mface); + MEM_freeN(fsdm->mdm.me); + } + + if (fsdm->mdm.freeNors) MEM_freeN(fsdm->mdm.nors); + if (fsdm->mdm.freeVerts) MEM_freeN(fsdm->mdm.verts); + MEM_freeN(fsdm); +} + +DerivedMesh *getFluidsimDerivedMesh(Object *srcob, int useRenderParams, float *extverts, float *nors) { + int i; + Mesh *mesh = NULL; + FluidsimDerivedMesh *fsdm; + MeshDerivedMesh *mdm = NULL; + float (*vertCos)[3]; + int displaymode = 0; + int curFrame = G.scene->r.cfra - 1; /* start with 0 */ + char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR]; + char curWd[FILE_MAXDIR]; + char debugStrBuffer[256]; + //snprintf(debugStrBuffer,256,"getFluidsimDerivedMesh call (obid '%s', rp %d)\n", srcob->id.name, useRenderParams); // debug + + if((!srcob)||(!srcob->fluidsimSettings)) { + fprintf(stderr,"??? DEBUG, strange getFluidsimDerivedMesh call!\n\n"); return NULL; + } + + if(!useRenderParams) { + displaymode = srcob->fluidsimSettings->guiDisplayMode; + } else { + displaymode = srcob->fluidsimSettings->renderDisplayMode; + } + + snprintf(debugStrBuffer,256,"getFluidsimDerivedMesh call (obid '%s', rp %d, dm %d)\n", srcob->id.name, useRenderParams, displaymode); // debug + elbeemDebugOut(debugStrBuffer); // debug + + strncpy(targetDir, srcob->fluidsimSettings->surfdataPath, FILE_MAXDIR); + // use preview or final mesh? + if(displaymode==2) { + strcat(targetDir,"fluidsurface_preview_#"); + } else { + strcat(targetDir,"fluidsurface_final_#"); + } + BLI_convertstringcode(targetDir, G.sce, curFrame); // fixed #frame-no + strcpy(targetFile,targetDir); + strcat(targetFile, ".bobj.gz"); + //fprintf(stderr,"getFluidsimDerivedMesh call (obid '', rp %d, dm %d) '%s' \n", useRenderParams, displaymode, targetFile); // debug + + snprintf(debugStrBuffer,256,"getFluidsimDerivedMesh call (obid '%s', rp %d, dm %d) '%s' \n", srcob->id.name, useRenderParams, displaymode, targetFile); // debug + elbeemDebugOut(debugStrBuffer); // debug + + mesh = readBobjgz(targetFile, (Mesh*)(srcob->data) ); + if(!mesh) { + // display org. object upon failure + mesh = srcob->data; + return getMeshDerivedMesh(mesh , srcob, NULL); + } + + if((mesh)&&(mesh->totvert>0)) { + make_edges(mesh, 0); // 0 = make all edges draw + } + + // WARNING copied from getMeshDerivedMesh + fsdm = MEM_callocN(sizeof(*fsdm), "getFluidsimDerivedMesh_fsdm"); + fsdm->freeMesh = 1; + mdm = &fsdm->mdm; + vertCos = NULL; + + mdm->dm.getMinMax = meshDM_getMinMax; + mdm->dm.convertToDispListMesh = meshDM_convertToDispListMesh; + mdm->dm.getNumVerts = meshDM_getNumVerts; + mdm->dm.getNumFaces = meshDM_getNumFaces; + mdm->dm.getVertCos = meshDM_getVertCos; + mdm->dm.getVertCo = meshDM_getVertCo; + mdm->dm.getVertNo = meshDM_getVertNo; + mdm->dm.drawVerts = meshDM_drawVerts; + mdm->dm.drawUVEdges = meshDM_drawUVEdges; + mdm->dm.drawEdges = meshDM_drawEdges; + mdm->dm.drawLooseEdges = meshDM_drawLooseEdges; + mdm->dm.drawFacesSolid = meshDM_drawFacesSolid; + mdm->dm.drawFacesColored = meshDM_drawFacesColored; + mdm->dm.drawFacesTex = meshDM_drawFacesTex; + mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; + mdm->dm.drawMappedEdges = meshDM_drawMappedEdges; + mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; + + // use own release function + mdm->dm.release = fluidsimDM_release; + + mdm->ob = srcob; + mdm->me = mesh; + mdm->verts = mesh->mvert; + mdm->nors = NULL; + mdm->freeNors = 0; + mdm->freeVerts = 0; + + // if (vertCos) { not needed for fluid meshes... + // this is kinda ... see getMeshDerivedMesh + mesh_calc_normals(mdm->verts, mdm->me->totvert, mdm->me->mface, mdm->me->totface, &mdm->nors); + mdm->freeNors = 1; + return (DerivedMesh*) mdm; +} + + diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 86a5bb5d635..ab7352e4a5f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2400,7 +2400,7 @@ static void direct_link_object(FileData *fd, Object *ob) } ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */ if(ob->fluidsimSettings) { - // not much to do for now... fprintf(stderr, "FLUIDSIMT newdataadr\n"); + // not much to do for now... ob->fluidsimSettings->orgMesh = NULL; } diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim.h index e98f0b8a8e9..6a02680d694 100644 --- a/source/blender/makesdna/DNA_object_fluidsim.h +++ b/source/blender/makesdna/DNA_object_fluidsim.h @@ -68,9 +68,6 @@ typedef struct FluidsimSettings { float gstar; /* activate refinement? */ int maxRefine; - /* store output path, and file prefix for baked fluid surface */ - /* strlens; 80= FILE_MAXFILE, 160= FILE_MAXDIR */ - char surfdataDir[160], surfdataPrefix[80]; /* fluid object type settings */ /* gravity strength */ @@ -78,6 +75,10 @@ typedef struct FluidsimSettings { /* store pointer to original mesh (for replacing the current one) */ struct Mesh *orgMesh; + + /* store output path, and file prefix for baked fluid surface */ + /* strlens; 80= FILE_MAXFILE, 160= FILE_MAXDIR */ + char surfdataPath[160+80]; } FluidsimSettings; /* ob->fluidsimSettings defines */ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 82494c0f37f..43897b2f0bd 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1256,18 +1256,19 @@ static void softbody_bake(Object *ob) void fluidsimFilesel(char *selection) { Object *ob = OBACT; - char srcDir[FILE_MAXDIR], srcFile[FILE_MAXFILE]; + char srcDir[FILE_MAXDIR+FILE_MAXFILE], srcFile[FILE_MAXFILE]; char prefix[FILE_MAXFILE]; char *srch, *srchSub, *srchExt, *lastFound; int isElbeemSurf = 0; + // check cfg? + // make prefix strcpy(srcDir, selection); BLI_splitdirstring(srcDir, srcFile); - - // make prefix strcpy(prefix, srcFile); // check if this is a previously generated surface mesh file - srch = strstr(prefix, "_surface_"); + srch = strstr(prefix, "fluidsurface_"); + // TODO search from back... if(srch) { srchSub = strstr(prefix,"_preview_"); if(!srchSub) srchSub = strstr(prefix,"_final_"); @@ -1294,10 +1295,17 @@ void fluidsimFilesel(char *selection) } } - // TODO check srcDir for file path from sce? - strcpy(ob->fluidsimSettings->surfdataDir, srcDir); - strcpy(ob->fluidsimSettings->surfdataPrefix, prefix); - //fprintf(stderr,"fluidsimFilesel: Using surfdata path '%s', prefix '%s' \n", ob->fluidsimSettings->surfdataDir,ob->fluidsimSettings->surfdataPrefix); // DEBUG + if(ob->fluidsimSettings) { + //strcpy(ob->fluidsimSettings->surfdataPath, selection); + strcpy(ob->fluidsimSettings->surfdataPath, srcDir); + //not necessary? strcat(ob->fluidsimSettings->surfdataPath, "/"); + strcat(ob->fluidsimSettings->surfdataPath, prefix); + + // redraw view & buttons... + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } } void do_object_panels(unsigned short event) @@ -1386,22 +1394,18 @@ void do_object_panels(unsigned short event) /* write config files (currently no simulation) */ fluidsimBake(ob); break; - case B_FLUIDSIM_SELDIR: - { - char str[FILE_MAXDIR+FILE_MAXFILE]; - ScrArea *sa = closest_bigger_area(); - strcpy(str,"//"); - ob= OBACT; - /* choose dir for surface files */ - areawinset(sa->win); - activate_fileselect(FILE_SPECIAL, "Select Directory", str, fluidsimFilesel); - } - /* continue with redraw... so no brake here! */ + case B_FLUIDSIM_SELDIR: { + ScrArea *sa = closest_bigger_area(); + ob= OBACT; + /* choose dir for surface files */ + areawinset(sa->win); + activate_fileselect(FILE_SPECIAL, "Select Directory", ob->fluidsimSettings->surfdataPath, fluidsimFilesel); + } + break; case B_FLUIDSIM_FORCEREDRAW: /* force redraw */ - allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); - countall(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); break; @@ -2015,9 +2019,8 @@ static void object_panel_fluidsim(Object *ob) yline -= lineHeight; yline -= 1*separateHeight; - uiDefIconBut(block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL, 0, yline, 20, objHeight, 0, 0, 0, 0, 0, "Select Directory (and/or filenames) to store baked fluid simulation files in"); - uiDefBut(block, TEX, B_FLUIDSIM_FORCEREDRAW,"", 20, yline, 200, objHeight,fss->surfdataDir, 0.0,79.0, 0, 0, "Enter Directory to store baked fluid simulation files in"); - uiDefBut(block, TEX, B_FLUIDSIM_FORCEREDRAW,"", 220, yline, 80, objHeight,fss->surfdataPrefix, 0.0,79.0, 0, 0, "Enter Filename-Prefix to store baked fluid simulation files with"); + 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"); // FIXME what is the 79.0 above? } else { // advanced options @@ -2027,7 +2030,6 @@ static void object_panel_fluidsim(Object *ob) 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 -= separateHeight; yline -= lineHeight; yline -= 1*separateHeight; diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c index c0ab26b7733..546613821f0 100644 --- a/source/blender/src/fluidsim.c +++ b/source/blender/src/fluidsim.c @@ -162,18 +162,12 @@ FluidsimSettings *fluidsimSettingsNew(struct Object *srcob) fss->maxRefine = -1; // maxRefine is set according to resolutionxyz during bake - // fluid settings + // fluid/inflow settings fss->iniVelx = fss->iniVely = fss->iniVelz = 0.0; - strcpy(fss->surfdataDir,"//"); // current dir - // fss->surfdataPrefix take from .blend filename - //strcpy(blendDir, G.sce); - //BLI_splitdirstring(blendDir, blendFile); - //snprintf(fss->surfdataPrefix,FILE_MAXFILE,"%s_%s", blendFile, srcob->id.name); - strcpy(fss->surfdataPrefix,""); // init upon first bake - + strcpy(fss->surfdataPath,""); // leave blank, init upon first bake fss->orgMesh = (Mesh *)srcob->data; return fss; } @@ -186,8 +180,9 @@ void fluidsimSettingsFree(FluidsimSettings *fss) /* helper function */ -void getGeometryObjFilename(struct Object *ob, char *dst, char *srcname) { - snprintf(dst,FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name); +void getGeometryObjFilename(struct Object *ob, char *dst) { //, char *srcname) { + //snprintf(dst,FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name); + snprintf(dst,FILE_MAXFILE, "fluidcfgdata_%s.bobj.gz", ob->id.name); } @@ -220,7 +215,6 @@ void simulateThreadIncreaseFrame(void) { /* ********************** write fluidsim config to file ************************* */ void fluidsimBake(struct Object *ob) { - char fnameCfg[FILE_MAXFILE], fnameCfgPath[FILE_MAXFILE+FILE_MAXDIR]; FILE *fileCfg; struct Object *fsDomain = NULL; FluidsimSettings *fssDomain; @@ -233,16 +227,18 @@ void fluidsimBake(struct Object *ob) const int maxRes = 200; int gridlevels = 0; - char outDir[FILE_MAXDIR], outPrefix[FILE_MAXFILE]; // store & modify output settings - int outStringsChanged = 0; // modified? copy back before baking - int haveSomeFluid = 0; // check if any fluid objects are set + char *suffixConfig = "fluidsim.cfg"; + char *suffixSurface = "fluidsurface"; + char targetDir[FILE_MAXDIR+FILE_MAXFILE]; // store & modify output settings + char targetFile[FILE_MAXDIR+FILE_MAXFILE]; // temp. store filename from targetDir for access + int outStringsChanged = 0; // modified? copy back before baking + int haveSomeFluid = 0; // check if any fluid objects are set const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp if(getenv(strEnvName)) { int dlevel = atoi(getenv(strEnvName)); elbeemSetDebugLevel(dlevel); - //if((dlevel>0) && (dlevel<=10)) debugBake = 1; snprintf(debugStrBuffer,256,"fluidsimBake::msg: Debug messages activated due to envvar '%s'\n",strEnvName); elbeemDebugOut(debugStrBuffer); } @@ -308,45 +304,32 @@ void fluidsimBake(struct Object *ob) } // prepare names... - strcpy(curWd, G.sce); - BLI_splitdirstring(curWd, blendFile); - if(strlen(curWd)<1) { - BLI_getwdN(curWd); - } - // work on these vars here... copy back later - strncpy(outDir, fsDomain->fluidsimSettings->surfdataDir, FILE_MAXDIR); - strncpy(outPrefix, fsDomain->fluidsimSettings->surfdataPrefix, FILE_MAXFILE); - if(strlen(outPrefix)<1) { - // make new from current .blend filename , and domain object name - strcpy(blendDir, G.sce); - BLI_splitdirstring(blendDir, blendFile); - // todo... strip .blend - snprintf(outPrefix,FILE_MAXFILE,"%s_%s", blendFile, fsDomain->id.name); - snprintf(debugStrBuffer,256,"fluidsimBake::error - warning resetting output prefix to '%s'\n", outPrefix); - elbeemDebugOut(debugStrBuffer); - outStringsChanged=1; - } + strncpy(targetDir, fsDomain->fluidsimSettings->surfdataPath, FILE_MAXDIR); + BLI_convertstringcode(targetDir, G.sce, 0); // fixed #frame-no + strcpy(targetFile, targetDir); + strcat(targetFile, suffixConfig); // check selected directory -#ifdef WIN32 - // windows workaroung because stat seems to be broken... - // simply try to open cfg file for writing - snprintf(fnameCfg,FILE_MAXFILE,"%s.cfg", outPrefix); - BLI_make_file_string(curWd, fnameCfgPath, outDir, fnameCfg); - fileCfg = fopen(fnameCfgPath, "w"); - if(fileCfg) { - dirExist = 1; - fclose(fileCfg); - } -#else // WIN32 - BLI_make_file_string(curWd, fnameCfgPath, outDir, ""); - if(S_ISDIR(BLI_exist(fnameCfgPath))) dirExist = 1; -#endif // WIN32 + // simply try to open cfg file for writing to test validity of settings + fileCfg = fopen(targetFile, "w"); + if(fileCfg) { dirExist = 1; fclose(fileCfg); } - if((strlen(outDir)<1) || (!dirExist)) { - // invalid dir, reset to current - strcpy(outDir, "//"); - snprintf(debugStrBuffer,256,"fluidsimBake::error - warning resetting output dir to '%s'\n", outDir); + if((strlen(targetDir)<1) || (!dirExist)) { + char blendDir[FILE_MAXDIR+FILE_MAXFILE], blendFile[FILE_MAXDIR+FILE_MAXFILE]; + // invalid dir, reset to current/previous + strcpy(blendDir, G.sce); + BLI_splitdirstring(blendDir, blendFile); + if(strlen(blendFile)>6){ + int len = strlen(blendFile); + if( (blendFile[len-6]=='.')&& (blendFile[len-5]=='b')&& (blendFile[len-4]=='l')&& + (blendFile[len-3]=='e')&& (blendFile[len-2]=='n')&& (blendFile[len-1]=='d') ){ + blendFile[len-6] = '\0'; + } + } + // todo... strip .blend ? + snprintf(targetDir,FILE_MAXFILE+FILE_MAXDIR,"//%s_%s_", blendFile, fsDomain->id.name); + + snprintf(debugStrBuffer,256,"fluidsimBake::error - warning resetting output dir to '%s'\n", targetDir); elbeemDebugOut(debugStrBuffer); outStringsChanged=1; } @@ -356,38 +339,35 @@ void fluidsimBake(struct Object *ob) char dispmsg[FILE_MAXDIR+FILE_MAXFILE+256]; int selection=0; strcpy(dispmsg,"Output settings set to: '"); - strcat(dispmsg, outDir); - if(dispmsg[ strlen(dispmsg)-1 ]!='/') strcat(dispmsg,"/"); - strcat(dispmsg, outPrefix); - //snprintf(dispmsg, FILE_MAXDIR+FILE_MAXFILE+10, "%s '%s'", changeMsg, fnameCfgPath); + strcat(dispmsg, targetDir); strcat(dispmsg, "'%t|Continue with changed settings%x1|Discard and abort%x0"); // ask user if thats what he/she wants... selection = pupmenu(dispmsg); - if(selection==0) return; + if(selection<1) return; // 0 from menu, or -1 aborted + BLI_convertstringcode(targetDir, G.sce, 0); // fixed #frame-no } // dump data for frame 0 G.scene->r.cfra = 0; scene_update_for_newframe(G.scene, G.scene->lay); - snprintf(fnameCfg,FILE_MAXFILE,"%s.cfg", outPrefix); - BLI_make_file_string(curWd, fnameCfgPath, outDir, fnameCfg); - // start writing - fileCfg = fopen(fnameCfgPath, "w"); + strcpy(targetFile, targetDir); + strcat(targetFile, suffixConfig); + fileCfg = fopen(targetFile, "w"); if(!fileCfg) { - snprintf(debugStrBuffer,256,"fluidsimBake::error - Unable to open file for writing '%s'\n", fnameCfgPath); + snprintf(debugStrBuffer,256,"fluidsimBake::error - Unable to open file for writing '%s'\n", targetFile); elbeemDebugOut(debugStrBuffer); pupmenu("Fluidsim Bake Error%t|Unable to output files... Aborted%x0"); return; } - fprintf(fileCfg, "# Blender ElBeem File , Source %s , Frame %d, to %s \n\n\n", G.sce, -1, fnameCfg ); - // valid settings -> store - strncpy(fsDomain->fluidsimSettings->surfdataDir, outDir, FILE_MAXDIR); - strncpy(fsDomain->fluidsimSettings->surfdataPrefix, outPrefix, FILE_MAXFILE); + fprintf(fileCfg, "# Blender ElBeem File , Source %s , Frame %d, to %s \n\n\n", G.sce, -1, targetFile ); + // file open -> valid settings -> store + strncpy(fsDomain->fluidsimSettings->surfdataPath, targetDir, FILE_MAXDIR); + //strncpy(fsDomain->fluidsimSettings->urfdataPrefix, outPrefix, FILE_MAXFILE); // FIXME set aniframetime from no. frames and duration /* output simulation settings */ @@ -484,7 +464,7 @@ void fluidsimBake(struct Object *ob) " antialias 1; \n" " ambientlight (1, 1, 1); \n" " maxRayDepth 6; \n" - " treeMaxDepth 25; \n" + " treeMaxDepth 25; \n" " treeMaxTriangles 8; \n" " background (0.08, 0.08, 0.20); \n" " eyepoint= (" "%f %f %f"/*4,5,6 eyep*/ "); #cfgset \n" @@ -509,11 +489,9 @@ void fluidsimBake(struct Object *ob) int resx = 200, resy=200; float lookatx=0.0, lookaty=0.0, lookatz=0.0; float fov = 45.0; - char fnamePreview[FILE_MAXFILE]; - char fnamePreviewPath[FILE_MAXFILE+FILE_MAXDIR]; - snprintf(fnamePreview,FILE_MAXFILE,"%s_surface", outPrefix ); - BLI_make_file_string(curWd, fnamePreviewPath, outDir, fnamePreview); + strcpy(targetFile, targetDir); + strcat(targetFile, suffixSurface); resx = G.scene->r.xsch; resy = G.scene->r.ysch; if((cam) && (cam->type == OB_CAMERA)) { @@ -530,7 +508,7 @@ void fluidsimBake(struct Object *ob) } fprintf(fileCfg, rayString, - noFrames, fnamePreviewPath, resx,resy, + noFrames, targetFile, resx,resy, eyex, eyey, eyez , lookatx, lookaty, lookatz, fov @@ -611,7 +589,6 @@ void fluidsimBake(struct Object *ob) " } \n" "\n" ; char fnameObjdat[FILE_MAXFILE]; - char bobjPath[FILE_MAXFILE+FILE_MAXDIR]; for(obit= G.main->object.first; obit; obit= obit->id.next) { //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG @@ -619,26 +596,27 @@ void fluidsimBake(struct Object *ob) (obit->type==OB_MESH) && (obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) ) { - getGeometryObjFilename(obit, fnameObjdat, outPrefix); - BLI_make_file_string(curWd, bobjPath, outDir, fnameObjdat); + getGeometryObjFilename(obit, fnameObjdat); //, outPrefix); + strcpy(targetFile, targetDir); + strcat(targetFile, fnameObjdat); fprintf(fileCfg, objectStringStart, obit->id.name ); // abs path if(obit->fluidsimSettings->type == OB_FLUIDSIM_FLUID) { - fprintf(fileCfg, fluidString, "fluid", bobjPath, // do use absolute paths? + fprintf(fileCfg, fluidString, "fluid", targetFile, // do use absolute paths? (double)obit->fluidsimSettings->iniVelx, (double)obit->fluidsimSettings->iniVely, (double)obit->fluidsimSettings->iniVelz ); } if(obit->fluidsimSettings->type == OB_FLUIDSIM_INFLOW) { - fprintf(fileCfg, fluidString, "inflow", bobjPath, // do use absolute paths? + fprintf(fileCfg, fluidString, "inflow", targetFile, // do use absolute paths? (double)obit->fluidsimSettings->iniVelx, (double)obit->fluidsimSettings->iniVely, (double)obit->fluidsimSettings->iniVelz ); } if(obit->fluidsimSettings->type == OB_FLUIDSIM_OUTFLOW) { - fprintf(fileCfg, fluidString, "outflow", bobjPath, // do use absolute paths? + fprintf(fileCfg, fluidString, "outflow", targetFile, // do use absolute paths? (double)obit->fluidsimSettings->iniVelx, (double)obit->fluidsimSettings->iniVely, (double)obit->fluidsimSettings->iniVelz ); } if(obit->fluidsimSettings->type == OB_FLUIDSIM_OBSTACLE) { - fprintf(fileCfg, obstacleString, "bnd_no" , bobjPath); // abs path + fprintf(fileCfg, obstacleString, "bnd_no" , targetFile); // abs path } fprintf(fileCfg, objectStringEnd ); // abs path - writeBobjgz(bobjPath, obit); + writeBobjgz(targetFile, obit); } } } @@ -657,7 +635,7 @@ void fluidsimBake(struct Object *ob) fprintf(fileCfg, "} // end raytracing\n"); fclose(fileCfg); - snprintf(debugStrBuffer,256,"fluidsimBake::msg: Wrote %s\n", fnameCfg); + snprintf(debugStrBuffer,256,"fluidsimBake::msg: Wrote %s\n", targetFile); elbeemDebugOut(debugStrBuffer); // perform simulation @@ -666,7 +644,9 @@ void fluidsimBake(struct Object *ob) globalBakeLock = SDL_CreateMutex(); globalBakeState = 0; globalBakeFrame = 1; - simthr = SDL_CreateThread(simulateThread, fnameCfgPath); + strcpy(targetFile, targetDir); + strcat(targetFile, suffixConfig); + simthr = SDL_CreateThread(simulateThread, targetFile); #ifndef WIN32 // DEBUG for win32 debugging, dont use threads... #endif // WIN32 @@ -674,7 +654,7 @@ void fluidsimBake(struct Object *ob) snprintf(debugStrBuffer,256,"fluidsimBake::error: Unable to create thread... running without one.\n"); elbeemDebugOut(debugStrBuffer); set_timecursor(0); - performElbeemSimulation(fnameCfgPath); + performElbeemSimulation(targetFile); } else { int done = 0; unsigned short event=0; @@ -733,6 +713,7 @@ void fluidsimBake(struct Object *ob) globalBakeLock = NULL; } // thread creation + // TODO cleanup sim files? // go back to "current" blender time waitcursor(0); G.scene->r.cfra = origFrame; |