Blender V2.61 - r43446

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