Blender  V2.59
isosurface.h
Go to the documentation of this file.
00001 
00004 /******************************************************************************
00005  *
00006  * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
00007  * Copyright 2003-2006 Nils Thuerey
00008  *
00009  * Marching Cubes "displayer"
00010  *
00011  *****************************************************************************/
00012 
00013 #ifndef ISOSURFACE_H
00014 
00015 #include "ntl_geometryobject.h"
00016 #include "ntl_bsptree.h"
00017 
00018 #define ISO_STRICT_DEBUG 0
00019 #define ISOSTRICT_EXIT *((int *)0)=0;
00020 
00021 /* access some 3d array */
00022 #define ISOLEVEL_INDEX(ii,ij,ik) ((mSizex*mSizey*(ik))+(mSizex*(ij))+((ii)))
00023 
00024 class ParticleTracer;
00025 
00026 /* struct for a small cube in the scalar field */
00027 typedef struct {
00028   ntlVec3Gfx   pos[8];
00029   double  value[8];
00030   int i,j,k;
00031 } IsoLevelCube;
00032 
00033 
00034 typedef struct {
00035   ntlVec3Gfx v; // vertex
00036   ntlVec3Gfx n; // vertex normal
00037 } IsoLevelVertex;
00038 
00040 // the fluid surface, templated by scalar field access object 
00041 class IsoSurface : 
00042         public ntlGeometryObject //, public S
00043 {
00044 
00045         public:
00046 
00048                 IsoSurface(double iso);
00050                 virtual ~IsoSurface();
00051 
00053                 virtual void initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx extent);
00054 
00056                 void resetAll(gfxReal val);
00057 
00059                 void triangulate( void );
00060 
00062                 void setParticles(ParticleTracer *pnt,float psize){ mpIsoParts = pnt; mPartSize=psize; };
00064                 void setSubdivs(int s) { 
00065                         if(mInitDone) errFatal("IsoSurface::setSubdivs","Changing subdivs after init!", SIMWORLD_INITERROR);
00066                         if(s<1) s=1; if(s>10) s=10;
00067                         mSubdivs = s; }
00068                 int  getSubdivs() { return mSubdivs;}
00070                 void setUseFulledgeArrays(bool set) { 
00071                         if(mInitDone) errFatal("IsoSurface::setUseFulledgeArrays","Changing usefulledge after init!", SIMWORLD_INITERROR);
00072                         mUseFullEdgeArrays = set;}
00073 
00074         protected:
00075 
00076                 /* variables ... */
00077 
00079                 int mSizex, mSizey, mSizez;
00080 
00082                 float *mpData;
00083 
00085                 double mIsoValue;
00086 
00088                 vector<IsoLevelVertex> mPoints;
00089 
00091                 bool mUseFullEdgeArrays;
00093                 int *mpEdgeVerticesX;
00094                 int *mpEdgeVerticesY;
00095                 int *mpEdgeVerticesZ;
00096                 int mEdgeArSize;
00097 
00098 
00100                 vector<unsigned int> mIndices;
00101 
00103                 ntlVec3Gfx mStart, mEnd;
00104 
00106                 ntlVec3Gfx mDomainExtent;
00107 
00109                 bool mInitDone;
00110 
00112                 float mSmoothSurface;
00114                 float mSmoothNormals;
00115                 
00117                 vector<int> mAcrossEdge;
00118                 vector< vector<int> > mAdjacentFaces;
00119 
00121                 int mCutoff;
00123                 int *mCutArray;
00125                 ParticleTracer *mpIsoParts;
00127                 float mPartSize;
00129                 int mSubdivs;
00130                 
00132                 vector<int> flags;
00133                 int mFlagCnt;
00134                 vector<ntlVec3Gfx> cornerareas;
00135                 vector<float> pointareas;
00136                 vector< vector<int> > neighbors;
00137 
00138         public:
00139                 // miscelleanous access functions 
00140 
00142                 void setStart(ntlVec3Gfx set) { mStart = set; };
00143                 ntlVec3Gfx getStart() { return mStart; };
00145                 void setEnd(ntlVec3Gfx set) { mEnd = set; };
00146                 ntlVec3Gfx getEnd() { return mEnd; };
00148                 inline void setIsolevel(double set) { mIsoValue = set; };
00150                 inline void setSmoothSurface(float set) { mSmoothSurface = set; };
00151                 inline void setSmoothNormals(float set) { mSmoothNormals = set; };
00152                 inline float getSmoothSurface() { return mSmoothSurface; }
00153                 inline float getSmoothNormals() { return mSmoothNormals; }
00154 
00155                 // geometry object functions 
00156                 virtual void getTriangles(double t, vector<ntlTriangle> *triangles, 
00157                                 vector<ntlVec3Gfx> *vertices, 
00158                                 vector<ntlVec3Gfx> *normals, int objectId );
00159 
00161                 virtual inline ntlVec3Gfx *getBBStart()         { return &mStart; }
00162                 virtual inline ntlVec3Gfx *getBBEnd()           { return &mEnd; }
00163 
00165                 inline float* getData(){ return mpData; }
00166                 inline float* getData(int ii, int jj, int kk){ 
00167 #if ISO_STRICT_DEBUG==1
00168                         if(ii<0){ errMsg("IsoStrict"," invX- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00169                         if(jj<0){ errMsg("IsoStrict"," invY- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00170                         if(kk<0){ errMsg("IsoStrict"," invZ- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00171                         if(ii>mSizex-1){ errMsg("IsoStrict"," invX+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00172                         if(jj>mSizey-1){ errMsg("IsoStrict"," invY+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00173                         if(kk>mSizez-1){ errMsg("IsoStrict"," invZ+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00174                         return mpData + ISOLEVEL_INDEX(ii, jj, kk); 
00175 #else //ISO_STRICT_DEBUG==1
00176                         return mpData + ISOLEVEL_INDEX(ii, jj, kk); 
00177 #endif
00178                 }
00179                 inline float* lbmGetData(int ii, int jj, int kk){ 
00180 #if ISO_STRICT_DEBUG==1
00181                         ii++; jj++; kk++;
00182                         if(ii<0){ errMsg("IsoStrict"," invX- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00183                         if(jj<0){ errMsg("IsoStrict"," invY- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00184                         if(kk<0){ errMsg("IsoStrict"," invZ- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00185                         if(ii>mSizex-1){ errMsg("IsoStrict"," invX+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00186                         if(jj>mSizey-1){ errMsg("IsoStrict"," invY+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00187                         if(kk>mSizez-1){ errMsg("IsoStrict"," invZ+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
00188                         return mpData + ISOLEVEL_INDEX(ii, jj, kk); 
00189 #else //ISO_STRICT_DEBUG==1
00190                         return mpData + ISOLEVEL_INDEX(ii+1,jj+1,kk+1); 
00191 #endif
00192                 }
00194                 inline void setCutoff(int set) { mCutoff = set; };
00196                 inline void setCutArray(int *set) { mCutArray = set; };
00197 
00199                 unsigned int getIsoVertexCount() {
00200                         return mPoints.size();
00201                 }
00202                 unsigned int getIsoIndexCount() {
00203                         return mIndices.size();
00204                 }
00205                 char* getIsoVertexArray() {
00206                         return (char *) &(mPoints[0]);
00207                 }
00208                 unsigned int *getIsoIndexArray() {
00209                         return &(mIndices[0]);
00210                 }
00211                 
00212                 // surface smoothing functions
00213                 void setSmoothRad(float radi1, float radi2, ntlVec3Gfx mscc);
00214                 void smoothSurface(float val, bool smoothNorm);
00215                 void smoothNormals(float val);
00216                 void computeNormals();
00217 
00218         protected:
00219 
00221                 inline ntlVec3Gfx getNormal(int i, int j,int k);
00223                 bool diffuseVertexField(ntlVec3Gfx *field, int pointerScale, int v, float invsigma2, ntlVec3Gfx &flt);
00224                 vector<int> mDboundary;
00225                 float mSCrad1, mSCrad2;
00226                 ntlVec3Gfx mSCcenter;
00227 };
00228 
00229 
00230 #define ISOSURFACE_H
00231 #endif
00232 
00233