Cleanup: remove redundant doxygen \file argument
[blender.git] / intern / elbeem / intern / isosurface.h
1 /** \file \ingroup elbeem
2  */
3 /******************************************************************************
4  *
5  * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
6  * Copyright 2003-2006 Nils Thuerey
7  *
8  * Marching Cubes "displayer"
9  *
10  *****************************************************************************/
11
12 #ifndef ISOSURFACE_H
13
14 #include "ntl_geometryobject.h"
15 #include "ntl_bsptree.h"
16
17 #ifdef WITH_CXX_GUARDEDALLOC
18 #  include "MEM_guardedalloc.h"
19 #endif
20
21 #define ISO_STRICT_DEBUG 0
22 #define ISOSTRICT_EXIT *((int *)0)=0;
23
24 /* access some 3d array */
25 #define ISOLEVEL_INDEX(ii,ij,ik) ((mSizex*mSizey*(ik))+(mSizex*(ij))+((ii)))
26
27 class ParticleTracer;
28
29 /* struct for a small cube in the scalar field */
30 typedef struct {
31   ntlVec3Gfx   pos[8];
32   double  value[8];
33   int i,j,k;
34 } IsoLevelCube;
35
36
37 typedef struct {
38   ntlVec3Gfx v; // vertex
39   ntlVec3Gfx n; // vertex normal
40 } IsoLevelVertex;
41
42 //! class to triangulate a scalar field, e.g. for
43 // the fluid surface, templated by scalar field access object 
44 class IsoSurface : 
45         public ntlGeometryObject //, public S
46 {
47
48         public:
49
50                 /*! Constructor */
51                 IsoSurface(double iso);
52                 /*! Destructor */
53                 virtual ~IsoSurface();
54
55                 /*! Init ararys etc. */
56                 virtual void initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx extent);
57
58                 /*! Reset all values */
59                 void resetAll(gfxReal val);
60
61                 /*! triangulate the scalar field given by pointer*/
62                 void triangulate( void );
63
64                 /*! set particle pointer */
65                 void setParticles(ParticleTracer *pnt,float psize){ mpIsoParts = pnt; mPartSize=psize; };
66                 /*! set # of subdivisions, this has to be done before init! */
67                 void setSubdivs(int s) { 
68                         if(mInitDone) errFatal("IsoSurface::setSubdivs","Changing subdivs after init!", SIMWORLD_INITERROR);
69                         if(s<1) s=1;
70                         if(s>10) s=10;
71                         mSubdivs = s;
72                 }
73                 int  getSubdivs() { return mSubdivs;}
74                 /*! set full edge settings, this has to be done before init! */
75                 void setUseFulledgeArrays(bool set) { 
76                         if(mInitDone) errFatal("IsoSurface::setUseFulledgeArrays","Changing usefulledge after init!", SIMWORLD_INITERROR);
77                         mUseFullEdgeArrays = set;}
78
79         protected:
80
81                 /* variables ... */
82
83                 //! size
84                 int mSizex, mSizey, mSizez;
85
86                 //! data pointer
87                 float *mpData;
88
89                 //! Level of the iso surface 
90                 double mIsoValue;
91
92                 //! Store all the triangles vertices 
93                 vector<IsoLevelVertex> mPoints;
94
95                 //! use full arrays? (not for farfield)
96                 bool mUseFullEdgeArrays;
97                 //! Store indices of calculated points along the cubie edges 
98                 int *mpEdgeVerticesX;
99                 int *mpEdgeVerticesY;
100                 int *mpEdgeVerticesZ;
101                 int mEdgeArSize;
102
103
104                 //! vector for all the triangles (stored as 3 indices) 
105                 vector<unsigned int> mIndices;
106
107                 //! start and end vectors for the triangulation region to create triangles in 
108                 ntlVec3Gfx mStart, mEnd;
109
110                 //! normalized domain extent from parametrizer/visualizer 
111                 ntlVec3Gfx mDomainExtent;
112
113                 //! initialized? 
114                 bool mInitDone;
115
116                 //! amount of surface smoothing
117                 float mSmoothSurface;
118                 //! amount of normal smoothing
119                 float mSmoothNormals;
120                 
121                 //! grid data
122                 vector<int> mAcrossEdge;
123                 vector< vector<int> > mAdjacentFaces;
124
125                 //! cutoff border area
126                 int mCutoff;
127                 //! cutoff heigh values
128                 int *mCutArray;
129                 //! particle pointer 
130                 ParticleTracer *mpIsoParts;
131                 //! particle size
132                 float mPartSize;
133                 //! no of subdivisions
134                 int mSubdivs;
135                 
136                 //! trimesh vars
137                 vector<int> flags;
138                 int mFlagCnt;
139                 vector<ntlVec3Gfx> cornerareas;
140                 vector<float> pointareas;
141                 vector< vector<int> > neighbors;
142
143         public:
144                 // miscelleanous access functions 
145
146                 //! set geometry start (for renderer) 
147                 void setStart(ntlVec3Gfx set) { mStart = set; };
148                 ntlVec3Gfx getStart() { return mStart; };
149                 //! set geometry end (for renderer) 
150                 void setEnd(ntlVec3Gfx set) { mEnd = set; };
151                 ntlVec3Gfx getEnd() { return mEnd; };
152                 //! set iso level value for surface reconstruction 
153                 inline void setIsolevel(double set) { mIsoValue = set; };
154                 //! set loop subdiv num
155                 inline void setSmoothSurface(float set) { mSmoothSurface = set; };
156                 inline void setSmoothNormals(float set) { mSmoothNormals = set; };
157                 inline float getSmoothSurface() { return mSmoothSurface; }
158                 inline float getSmoothNormals() { return mSmoothNormals; }
159
160                 // geometry object functions 
161                 virtual void getTriangles(double t, vector<ntlTriangle> *triangles, 
162                                 vector<ntlVec3Gfx> *vertices, 
163                                 vector<ntlVec3Gfx> *normals, int objectId );
164
165                 //! for easy GUI detection get start of axis aligned bounding box, return NULL of no BB 
166                 virtual inline ntlVec3Gfx *getBBStart()         { return &mStart; }
167                 virtual inline ntlVec3Gfx *getBBEnd()           { return &mEnd; }
168
169                 //! access data array
170                 inline float* getData(){ return mpData; }
171                 inline float* getData(int ii, int jj, int kk){ 
172 #if ISO_STRICT_DEBUG==1
173                         if(ii<0){ errMsg("IsoStrict"," invX- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
174                         if(jj<0){ errMsg("IsoStrict"," invY- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
175                         if(kk<0){ errMsg("IsoStrict"," invZ- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
176                         if(ii>mSizex-1){ errMsg("IsoStrict"," invX+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
177                         if(jj>mSizey-1){ errMsg("IsoStrict"," invY+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
178                         if(kk>mSizez-1){ errMsg("IsoStrict"," invZ+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
179                         return mpData + ISOLEVEL_INDEX(ii, jj, kk); 
180 #else //ISO_STRICT_DEBUG==1
181                         return mpData + ISOLEVEL_INDEX(ii, jj, kk); 
182 #endif
183                 }
184                 inline float* lbmGetData(int ii, int jj, int kk){ 
185 #if ISO_STRICT_DEBUG==1
186                         ii++; jj++; kk++;
187                         if(ii<0){ errMsg("IsoStrict"," invX- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
188                         if(jj<0){ errMsg("IsoStrict"," invY- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
189                         if(kk<0){ errMsg("IsoStrict"," invZ- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
190                         if(ii>mSizex-1){ errMsg("IsoStrict"," invX+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
191                         if(jj>mSizey-1){ errMsg("IsoStrict"," invY+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
192                         if(kk>mSizez-1){ errMsg("IsoStrict"," invZ+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; }
193                         return mpData + ISOLEVEL_INDEX(ii, jj, kk); 
194 #else //ISO_STRICT_DEBUG==1
195                         return mpData + ISOLEVEL_INDEX(ii+1,jj+1,kk+1); 
196 #endif
197                 }
198                 //! set cut off border
199                 inline void setCutoff(int set) { mCutoff = set; };
200                 //! set cut off border
201                 inline void setCutArray(int *set) { mCutArray = set; };
202
203                 //! OpenGL viz "interface"
204                 unsigned int getIsoVertexCount() {
205                         return mPoints.size();
206                 }
207                 unsigned int getIsoIndexCount() {
208                         return mIndices.size();
209                 }
210                 char* getIsoVertexArray() {
211                         return (char *) &(mPoints[0]);
212                 }
213                 unsigned int *getIsoIndexArray() {
214                         return &(mIndices[0]);
215                 }
216                 
217                 // surface smoothing functions
218                 void setSmoothRad(float radi1, float radi2, ntlVec3Gfx mscc);
219                 void smoothSurface(float val, bool smoothNorm);
220                 void smoothNormals(float val);
221                 void computeNormals();
222
223         protected:
224
225                 //! compute normal
226                 inline ntlVec3Gfx getNormal(int i, int j,int k);
227                 //! smoothing helper function
228                 bool diffuseVertexField(ntlVec3Gfx *field, int pointerScale, int v, float invsigma2, ntlVec3Gfx &flt);
229                 vector<int> mDboundary;
230                 float mSCrad1, mSCrad2;
231                 ntlVec3Gfx mSCcenter;
232
233 private:
234 #ifdef WITH_CXX_GUARDEDALLOC
235         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:IsoSurface")
236 #endif
237 };
238
239
240 #define ISOSURFACE_H
241 #endif
242
243