forked from bartvdbraak/blender
Another fluid type 'control' added and introduced to elbeem, still some issues to solve but with 1 change in fluidsim.c it kind of works already (hint for me - disabled for other people so they don't complain)
This commit is contained in:
parent
baa1001b47
commit
b3303c98b1
2
intern/elbeem/extern/elbeem.h
vendored
2
intern/elbeem/extern/elbeem.h
vendored
@ -226,6 +226,7 @@ double elbeemEstimateMemreq(int res,
|
||||
// structs, for these use OB_xxx defines above
|
||||
|
||||
/*! fluid geometry init types */
|
||||
// type "int" used, so max is 8
|
||||
#define FGI_FLAGSTART 16
|
||||
#define FGI_FLUID (1<<(FGI_FLAGSTART+ 0))
|
||||
#define FGI_NO_FLUID (1<<(FGI_FLAGSTART+ 1))
|
||||
@ -235,6 +236,7 @@ double elbeemEstimateMemreq(int res,
|
||||
#define FGI_NO_BND (1<<(FGI_FLAGSTART+ 5))
|
||||
#define FGI_MBNDINFLOW (1<<(FGI_FLAGSTART+ 6))
|
||||
#define FGI_MBNDOUTFLOW (1<<(FGI_FLAGSTART+ 7))
|
||||
#define FGI_CONTROL (1<<(FGI_FLAGSTART+ 8))
|
||||
|
||||
// all boundary types at once
|
||||
#define FGI_ALLBOUNDS ( FGI_BNDNO | FGI_BNDFREE | FGI_BNDPART | FGI_MBNDINFLOW | FGI_MBNDOUTFLOW )
|
||||
|
@ -57,6 +57,127 @@ void ControlParticles::initBlenderTest() {
|
||||
initTime(0. , 1.);
|
||||
}
|
||||
|
||||
int ControlParticles::initFromObject(ntlGeometryObjModel *model) {
|
||||
vector<ntlTriangle> triangles;
|
||||
vector<ntlVec3Gfx> vertices;
|
||||
vector<ntlVec3Gfx> normals;
|
||||
|
||||
/*
|
||||
model->loadBobjModel(string(infile));
|
||||
|
||||
model->setLoaded(true);
|
||||
|
||||
model->setGeoInitId(gid);
|
||||
*/
|
||||
model->setGeoInitType(FGI_FLUID);
|
||||
|
||||
model->getTriangles(mCPSTimeStart, &triangles, &vertices, &normals, 1 );
|
||||
|
||||
// valid mesh?
|
||||
if(triangles.size() <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ntlRenderGlobals *glob = new ntlRenderGlobals;
|
||||
ntlScene *genscene = new ntlScene( glob, false );
|
||||
genscene->addGeoClass(model);
|
||||
genscene->addGeoObject(model);
|
||||
genscene->buildScene(0., false);
|
||||
char treeFlag = (1<<(4+model->getGeoInitId()));
|
||||
|
||||
ntlTree *tree = new ntlTree(
|
||||
15, 8, // TREEwarning - fixed values for depth & maxtriangles here...
|
||||
genscene, treeFlag );
|
||||
|
||||
// TODO? use params
|
||||
ntlVec3Gfx start,end;
|
||||
model->getExtends(start,end);
|
||||
|
||||
printf("start - x: %f, y: %f, z: %f\n", start[0], start[1], start[2]);
|
||||
printf("end - x: %f, y: %f, z: %f\n", end[0], end[1], end[2]);
|
||||
printf("mCPSWidth: %f\n");
|
||||
|
||||
LbmFloat width = mCPSWidth;
|
||||
if(width<=LBM_EPSILON) { errMsg("ControlParticles::initFromMVMCMesh","Invalid mCPSWidth! "<<mCPSWidth); width=mCPSWidth=0.1; }
|
||||
ntlVec3Gfx org = start+ntlVec3Gfx(width*0.5);
|
||||
gfxReal distance = -1.;
|
||||
vector<ntlVec3Gfx> inspos;
|
||||
int approxmax = (int)( ((end[0]-start[0])/width)*((end[1]-start[1])/width)*((end[2]-start[2])/width) );
|
||||
|
||||
while(org[2]<end[2]) {
|
||||
while(org[1]<end[1]) {
|
||||
while(org[0]<end[0]) {
|
||||
if(checkPointInside(tree, org, distance)) {
|
||||
inspos.push_back(org);
|
||||
}
|
||||
// TODO optimize, use distance
|
||||
org[0] += width;
|
||||
}
|
||||
org[1] += width;
|
||||
org[0] = start[0];
|
||||
}
|
||||
org[2] += width;
|
||||
org[1] = start[1];
|
||||
}
|
||||
|
||||
MeanValueMeshCoords mvm;
|
||||
mvm.calculateMVMCs(vertices,triangles, inspos, mCPSWeightFac);
|
||||
vector<ntlVec3Gfx> ninspos;
|
||||
mvm.transfer(vertices, ninspos);
|
||||
|
||||
// init first set, check dist
|
||||
ControlParticleSet firstcps; //T
|
||||
mPartSets.push_back(firstcps);
|
||||
mPartSets[mPartSets.size()-1].time = (gfxReal)0.;
|
||||
vector<bool> useCP;
|
||||
|
||||
for(int i=0; i<(int)inspos.size(); i++) {
|
||||
ControlParticle p; p.reset();
|
||||
p.pos = vec2L(inspos[i]);
|
||||
|
||||
double cpdist = norm(inspos[i]-ninspos[i]);
|
||||
bool usecpv = true;
|
||||
|
||||
mPartSets[mPartSets.size()-1].particles.push_back(p);
|
||||
useCP.push_back(usecpv);
|
||||
}
|
||||
|
||||
// init further sets, temporal mesh sampling
|
||||
double tsampling = mCPSTimestep;
|
||||
int totcnt = (int)( (mCPSTimeEnd-mCPSTimeStart)/tsampling ), tcnt=0;
|
||||
for(double t=mCPSTimeStart+tsampling; ((t<mCPSTimeEnd) && (ninspos.size()>0.)); t+=tsampling) {
|
||||
ControlParticleSet nextcps; //T
|
||||
mPartSets.push_back(nextcps);
|
||||
mPartSets[mPartSets.size()-1].time = (gfxReal)t;
|
||||
|
||||
vertices.clear(); triangles.clear(); normals.clear();
|
||||
model->getTriangles(t, &triangles, &vertices, &normals, 1 );
|
||||
mvm.transfer(vertices, ninspos);
|
||||
|
||||
tcnt++;
|
||||
for(int i=0; i<(int)ninspos.size(); i++) {
|
||||
|
||||
if(useCP[i]) {
|
||||
ControlParticle p; p.reset();
|
||||
p.pos = vec2L(ninspos[i]);
|
||||
mPartSets[mPartSets.size()-1].particles.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// applyTrafos();
|
||||
|
||||
model->setGeoInitType(FGI_CONTROL);
|
||||
|
||||
initTime(mCPSTimeStart , mCPSTimeEnd);
|
||||
|
||||
delete tree;
|
||||
delete genscene;
|
||||
delete glob;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// init all zero / defaults for a single particle
|
||||
void ControlParticle::reset() {
|
||||
|
@ -13,6 +13,8 @@
|
||||
#ifndef CONTROLPARTICLES_H
|
||||
#define CONTROLPARTICLES_H
|
||||
|
||||
#include "ntl_geometrymodel.h"
|
||||
|
||||
// indicator for LBM inclusion
|
||||
//#ifndef LBMDIM
|
||||
|
||||
@ -226,6 +228,8 @@ public:
|
||||
// blender test init
|
||||
void initBlenderTest();
|
||||
|
||||
int initFromObject(ntlGeometryObjModel *model);
|
||||
|
||||
protected:
|
||||
// sets influence params
|
||||
friend class MultisphGUI;
|
||||
|
@ -177,7 +177,7 @@ int elbeemAddMesh(elbeemMesh *mesh) {
|
||||
case OB_FLUIDSIM_FLUID: initType = FGI_FLUID; break;
|
||||
case OB_FLUIDSIM_INFLOW: initType = FGI_MBNDINFLOW; break;
|
||||
case OB_FLUIDSIM_OUTFLOW: initType = FGI_MBNDOUTFLOW; break;
|
||||
case OB_FLUIDSIM_CONTROL: initType = 0; break; // DG TODO: add correct time for fluid control object
|
||||
case OB_FLUIDSIM_CONTROL: initType = FGI_CONTROL; break;
|
||||
default: return 1; // invalid type
|
||||
}
|
||||
|
||||
|
@ -82,20 +82,21 @@ bool ntlGeometryObject::checkIsAnimated() {
|
||||
/*****************************************************************************/
|
||||
/* Init attributes etc. of this object */
|
||||
/*****************************************************************************/
|
||||
#define GEOINIT_STRINGS 9
|
||||
#define GEOINIT_STRINGS 10
|
||||
static const char *initStringStrs[GEOINIT_STRINGS] = {
|
||||
"fluid",
|
||||
"bnd_no","bnd_noslip",
|
||||
"bnd_free","bnd_freeslip",
|
||||
"bnd_part","bnd_partslip",
|
||||
"inflow", "outflow"
|
||||
"inflow", "outflow", "control",
|
||||
};
|
||||
static int initStringTypes[GEOINIT_STRINGS] = {
|
||||
FGI_FLUID,
|
||||
FGI_BNDNO, FGI_BNDNO,
|
||||
FGI_BNDFREE, FGI_BNDFREE,
|
||||
FGI_BNDPART, FGI_BNDPART,
|
||||
FGI_MBNDINFLOW, FGI_MBNDOUTFLOW
|
||||
FGI_MBNDINFLOW, FGI_MBNDOUTFLOW,
|
||||
FGI_CONTROL
|
||||
};
|
||||
void ntlGeometryObject::initialize(ntlRenderGlobals *glob)
|
||||
{
|
||||
|
@ -17,7 +17,9 @@
|
||||
|
||||
#include "controlparticles.h"
|
||||
|
||||
#include "elbeem.h"
|
||||
|
||||
#include "ntl_geometrymodel.h"
|
||||
|
||||
/******************************************************************************
|
||||
* LbmControlData control set
|
||||
@ -212,6 +214,40 @@ LbmFsgrSolver::initCpdata()
|
||||
// enable for cps via env. vars
|
||||
//if( (getenv("ELBEEM_CPINFILE")) || (getenv("ELBEEM_CPOUTFILE")) ){ mUseTestdata=1; }
|
||||
|
||||
|
||||
// manually switch on! if this is zero, nothing is done...
|
||||
mpControl->mSetForceStrength = this->mTForceStrength = 1.;
|
||||
mpControl->mCons.clear();
|
||||
|
||||
// add new set
|
||||
LbmControlSet *cset;
|
||||
|
||||
cset = new LbmControlSet();
|
||||
cset->initCparts();
|
||||
|
||||
// dont load any file
|
||||
cset->mContrPartFile = string("");
|
||||
|
||||
cset->mcForceAtt = AnimChannel<float>(0.2);
|
||||
cset->mcRadiusAtt = AnimChannel<float>(0.75);
|
||||
cset->mcForceVel = AnimChannel<float>(0.2);
|
||||
cset->mcRadiusVel = AnimChannel<float>(0.75);
|
||||
|
||||
// this value can be left at 0.5:
|
||||
cset->mCparts->setCPSMvmWeightFac(0.5);
|
||||
|
||||
mpControl->mCons.push_back( cset );
|
||||
|
||||
// init all control fluid objects
|
||||
int numobjs = (int)(mpGiObjects->size());
|
||||
for(int o=0; o<numobjs; o++) {
|
||||
ntlGeometryObjModel *obj = (ntlGeometryObjModel *)(*mpGiObjects)[o];
|
||||
if(obj->getGeoInitType() & FGI_CONTROL) {
|
||||
printf("added control object\n");
|
||||
mpControl->mCons[0]->mCparts->initFromObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
// NT blender integration manual test setup
|
||||
if(0) {
|
||||
// manually switch on! if this is zero, nothing is done...
|
||||
|
@ -46,6 +46,8 @@ class ControlForces;
|
||||
|
||||
#include "controlparticles.h"
|
||||
|
||||
#include "ntl_geometrymodel.h"
|
||||
|
||||
// get force entry, set=0 is unused anyway
|
||||
#define LBMGET_FORCE(lev, i,j,k) mpControl->mCpForces[lev][ (LBMGI(lev,i,j,k,0)) ]
|
||||
|
||||
|
@ -1015,7 +1015,8 @@ void fluidsimBake(struct Object *ob)
|
||||
fsmesh.channelScale = channelObjMove[o][2];
|
||||
fsmesh.channelActive = channelObjActive[o];
|
||||
if( (fsmesh.type == OB_FLUIDSIM_FLUID) ||
|
||||
(fsmesh.type == OB_FLUIDSIM_INFLOW) ) {
|
||||
(fsmesh.type == OB_FLUIDSIM_INFLOW) ||
|
||||
(fsmesh.type == OB_FLUIDSIM_CONTROL)) {
|
||||
fsmesh.channelInitialVel = channelObjInivel[o];
|
||||
fsmesh.localInivelCoords = ((obit->fluidsimSettings->typeFlags&OB_FSINFLOW_LOCALCOORD)?1:0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user