Blender V2.61 - r43446
|
00001 00004 00005 // This file is part of Wavelet Turbulence. 00006 // 00007 // Wavelet Turbulence is free software: you can redistribute it and/or modify 00008 // it under the terms of the GNU General Public License as published by 00009 // the Free Software Foundation, either version 3 of the License, or 00010 // (at your option) any later version. 00011 // 00012 // Wavelet Turbulence is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>. 00019 // 00020 // Copyright 2008 Theodore Kim and Nils Thuerey 00021 // 00023 // 00024 #ifndef IMAGE_H 00025 #define IMAGE_H 00026 00027 #include <stdlib.h> 00028 #include <string> 00029 #include <fstream> 00030 #include <sstream> 00031 #include <zlib.h> 00032 00034 // NT helper functions 00036 template < class T > inline T ABS( T a ) { 00037 return (0 < a) ? a : -a ; 00038 } 00039 00040 template < class T > inline void SWAP_POINTERS( T &a, T &b ) { 00041 T temp = a; 00042 a = b; 00043 b = temp; 00044 } 00045 00046 template < class T > inline void CLAMP( T &a, T b=0., T c=1.) { 00047 if(a<b) { a=b; return; } 00048 if(a>c) { a=c; return; } 00049 } 00050 00051 template < class T > inline T MIN( T a, T b) { 00052 return (a < b) ? a : b; 00053 } 00054 00055 template < class T > inline T MAX( T a, T b) { 00056 return (a > b) ? a : b; 00057 } 00058 00059 template < class T > inline T MAX3( T a, T b, T c) { 00060 T max = (a > b) ? a : b; 00061 max = (max > c) ? max : c; 00062 return max; 00063 } 00064 00065 template < class T > inline float MAX3V( T vec) { 00066 float max = (vec[0] > vec[1]) ? vec[0] : vec[1]; 00067 max = (max > vec[2]) ? max : vec[2]; 00068 return max; 00069 } 00070 00071 template < class T > inline float MIN3V( T vec) { 00072 float min = (vec[0] < vec[1]) ? vec[0] : vec[1]; 00073 min = (min < vec[2]) ? min : vec[2]; 00074 return min; 00075 } 00076 00078 // PNG, POV-Ray, and PBRT output functions 00080 #ifndef NOPNG 00081 #ifdef WIN32 00082 #include "png.h" 00083 #else 00084 #include <png.h> 00085 #endif 00086 #endif // NOPNG 00087 00088 /* 00089 NOTE when someone decided to uncomment the following code, please remember to put it between #ifndef NOPNG #endif 00090 */ 00091 namespace IMAGE { 00092 /* 00093 static int writePng(const char *fileName, unsigned char **rowsp, int w, int h) 00094 { 00095 // defaults 00096 const int colortype = PNG_COLOR_TYPE_RGBA; 00097 const int bitdepth = 8; 00098 png_structp png_ptr = NULL; 00099 png_infop info_ptr = NULL; 00100 png_bytep *rows = rowsp; 00101 00102 FILE *fp = NULL; 00103 std::string doing = "open for writing"; 00104 if (!(fp = fopen(fileName, "wb"))) goto fail; 00105 00106 if(!png_ptr) { 00107 doing = "create png write struct"; 00108 if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto fail; 00109 } 00110 if(!info_ptr) { 00111 doing = "create png info struct"; 00112 if (!(info_ptr = png_create_info_struct(png_ptr))) goto fail; 00113 } 00114 00115 if (setjmp(png_jmpbuf(png_ptr))) goto fail; 00116 doing = "init IO"; 00117 png_init_io(png_ptr, fp); 00118 doing = "write header"; 00119 png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype, PNG_INTERLACE_NONE, 00120 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 00121 doing = "write info"; 00122 png_write_info(png_ptr, info_ptr); 00123 doing = "write image"; 00124 png_write_image(png_ptr, rows); 00125 doing = "write end"; 00126 png_write_end(png_ptr, NULL); 00127 doing = "write destroy structs"; 00128 png_destroy_write_struct(&png_ptr, &info_ptr); 00129 00130 fclose( fp ); 00131 return 0; 00132 00133 fail: 00134 std::cerr << "writePng: could not "<<doing<<" !\n"; 00135 if(fp) fclose( fp ); 00136 if(png_ptr || info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); 00137 return -1; 00138 } 00139 */ 00140 00142 // write a numbered PNG file out, padded with zeros up to three zeros 00144 /* 00145 static void dumpNumberedPNG(int counter, std::string prefix, float* field, int xRes, int yRes) 00146 { 00147 char buffer[256]; 00148 sprintf(buffer,"%04i", counter); 00149 std::string number = std::string(buffer); 00150 00151 unsigned char pngbuf[xRes*yRes*4]; 00152 unsigned char *rows[yRes]; 00153 float *pfield = field; 00154 for (int j=0; j<yRes; j++) { 00155 for (int i=0; i<xRes; i++) { 00156 float val = *pfield; 00157 if(val>1.) val=1.; 00158 if(val<0.) val=0.; 00159 pngbuf[(j*xRes+i)*4+0] = (unsigned char)(val*255.); 00160 pngbuf[(j*xRes+i)*4+1] = (unsigned char)(val*255.); 00161 pngbuf[(j*xRes+i)*4+2] = (unsigned char)(val*255.); 00162 pfield++; 00163 pngbuf[(j*xRes+i)*4+3] = 255; 00164 } 00165 rows[j] = &pngbuf[(yRes-j-1)*xRes*4]; 00166 } 00167 std::string filenamePNG = prefix + number + std::string(".png"); 00168 writePng(filenamePNG.c_str(), rows, xRes, yRes, false); 00169 printf("Writing %s\n", filenamePNG.c_str()); 00170 00171 } 00172 */ 00174 // export pbrt volumegrid geometry object 00176 /* 00177 static void dumpPBRT(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes) 00178 { 00179 char buffer[256]; 00180 sprintf(buffer,"%04i", counter); 00181 std::string number = std::string(buffer); 00182 00183 std::string filenamePbrt = prefix + number + std::string(".pbrt.gz"); 00184 printf("Writing PBRT %s\n", filenamePbrt.c_str()); 00185 00186 float *field = new float[xRes*yRes*zRes]; 00187 // normalize values 00188 float maxDensVal = ABS(fieldOrg[0]); 00189 float targetNorm = 0.5; 00190 for (int i = 0; i < xRes * yRes * zRes; i++) { 00191 if(ABS(fieldOrg[i])>maxDensVal) maxDensVal = ABS(fieldOrg[i]); 00192 field[i] = 0.; 00193 } 00194 if(maxDensVal>0.) { 00195 for (int i = 0; i < xRes * yRes * zRes; i++) { 00196 field[i] = ABS(fieldOrg[i]) / maxDensVal * targetNorm; 00197 } 00198 } 00199 00200 std::fstream fout; 00201 fout.open(filenamePbrt.c_str(), std::ios::out); 00202 00203 int maxRes = (xRes > yRes) ? xRes : yRes; 00204 maxRes = (maxRes > zRes) ? maxRes : zRes; 00205 00206 const float xSize = 1.0 / (float)maxRes * (float)xRes; 00207 const float ySize = 1.0 / (float)maxRes * (float)yRes; 00208 const float zSize = 1.0 / (float)maxRes * (float)zRes; 00209 00210 gzFile file; 00211 file = gzopen(filenamePbrt.c_str(), "wb1"); 00212 if (file == NULL) { 00213 std::cerr << " Couldn't write file " << filenamePbrt << "!!!" << std::endl; 00214 return; 00215 } 00216 00217 // dimensions 00218 gzprintf(file, "Volume \"volumegrid\" \n"); 00219 gzprintf(file, " \"integer nx\" %i\n", xRes); 00220 gzprintf(file, " \"integer ny\" %i\n", yRes); 00221 gzprintf(file, " \"integer nz\" %i\n", zRes); 00222 gzprintf(file, " \"point p0\" [ 0.0 0.0 0.0 ] \"point p1\" [%f %f %f ] \n", xSize, ySize, zSize); 00223 gzprintf(file, " \"float density\" [ \n"); 00224 for (int i = 0; i < xRes * yRes * zRes; i++) 00225 gzprintf(file, "%f ", field[i]); 00226 gzprintf(file, "] \n \n"); 00227 00228 gzclose(file); 00229 delete[] field; 00230 } 00231 */ 00232 00234 // 3D df3 export 00236 /* 00237 static void dumpDF3(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes) 00238 { 00239 char buffer[256]; 00240 00241 // do deferred copying to final directory, better for network directories 00242 sprintf(buffer,"%04i", counter); 00243 std::string number = std::string(buffer); 00244 std::string filenameDf3 = prefix + number + std::string(".df3.gz"); 00245 printf("Writing DF3 %s\n", filenameDf3.c_str()); 00246 00247 gzFile file; 00248 file = gzopen(filenameDf3.c_str(), "wb1"); 00249 if (file == NULL) { 00250 std::cerr << " Couldn't write file " << filenameDf3 << "!!!" << std::endl; 00251 return; 00252 } 00253 00254 // dimensions 00255 const int byteSize = 2; 00256 const unsigned short int onx=xRes,ony=yRes,onz=zRes; 00257 unsigned short int nx,ny,nz; 00258 nx = onx >> 8; 00259 ny = ony >> 8; 00260 nz = onz >> 8; 00261 nx += (onx << 8); 00262 ny += (ony << 8); 00263 nz += (onz << 8); 00264 gzwrite(file, (void*)&nx, sizeof(short)); 00265 gzwrite(file, (void*)&ny, sizeof(short)); 00266 gzwrite(file, (void*)&nz, sizeof(short)); 00267 const int nitems = onx*ony*onz; 00268 const float mul = (float)( (1<<(8*byteSize))-1); 00269 00270 unsigned short int *buf = new unsigned short int[nitems]; 00271 for (int k = 0; k < onz; k++) 00272 for (int j = 0; j < ony; j++) 00273 for (int i = 0; i < onx; i++) { 00274 float val = fieldOrg[k*(onx*ony)+j*onx+i] ; 00275 CLAMP(val); 00276 buf[k*(onx*ony)+j*onx+i] = (short int)(val*mul); 00277 } 00278 gzwrite(file, (void*)buf, sizeof(unsigned short int)* nitems); 00279 00280 gzclose(file); 00281 delete[] buf; 00282 } 00283 */ 00284 00285 }; 00286 00287 00288 #endif 00289