Blender V2.61 - r43446
|
00001 00004 /****************************************************************************** 00005 * 00006 * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method 00007 * Copyright 2003-2006 Nils Thuerey 00008 * 00009 * Replaces std. raytracer, and only dumps time dep. objects to disc 00010 * 00011 *****************************************************************************/ 00012 00013 #include <fstream> 00014 #include <sys/types.h> 00015 00016 #include "utilities.h" 00017 #include "ntl_matrices.h" 00018 #include "ntl_blenderdumper.h" 00019 #include "ntl_world.h" 00020 #include "solver_interface.h" 00021 00022 #include <zlib.h> 00023 00024 00025 00026 /****************************************************************************** 00027 * Constructor 00028 *****************************************************************************/ 00029 ntlBlenderDumper::ntlBlenderDumper() : ntlWorld() 00030 { 00031 // same as normal constructor here 00032 } 00033 ntlBlenderDumper::ntlBlenderDumper(string filename, bool commandlineMode) : 00034 ntlWorld(filename,commandlineMode) 00035 { 00036 // init world 00037 } 00038 00039 00040 00041 /****************************************************************************** 00042 * Destructor 00043 *****************************************************************************/ 00044 ntlBlenderDumper::~ntlBlenderDumper() 00045 { 00046 debMsgStd("ntlBlenderDumper",DM_NOTIFY, "ntlBlenderDumper done", 10); 00047 } 00048 00049 // required globals 00050 extern bool glob_mpactive; 00051 extern int glob_mpnum, glob_mpindex; 00052 00053 /****************************************************************************** 00054 * Only dump time dep. objects to file 00055 *****************************************************************************/ 00056 int ntlBlenderDumper::renderScene( void ) 00057 { 00058 char nrStr[5]; /* nr conversion */ 00059 ntlRenderGlobals *glob = mpGlob; 00060 ntlScene *scene = mpGlob->getSimScene(); 00061 bool debugOut = false; 00062 bool debugRender = false; 00063 #if ELBEEM_PLUGIN==1 00064 debugOut = false; 00065 #endif // ELBEEM_PLUGIN==1 00066 00067 vector<string> gmName; // gm names 00068 vector<string> gmMat; // materials for gm 00069 int numGMs = 0; // no. of .obj models created 00070 00071 if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY,"Dumping geometry data", 1); 00072 long startTime = getTime(); 00073 snprintf(nrStr, 5, "%04d", glob->getAniCount() ); 00074 00075 // local scene vars 00076 vector<ntlTriangle> Triangles; 00077 vector<ntlVec3Gfx> Vertices; 00078 vector<ntlVec3Gfx> VertNormals; 00079 00080 // check geo objects 00081 int idCnt = 0; // give IDs to objects 00082 for (vector<ntlGeometryClass*>::iterator iter = scene->getGeoClasses()->begin(); 00083 iter != scene->getGeoClasses()->end(); iter++) { 00084 if(!(*iter)->getVisible()) continue; 00085 int tid = (*iter)->getTypeId(); 00086 00087 if(tid & GEOCLASSTID_OBJECT) { 00088 // normal geom. objects -> ignore 00089 } 00090 if(tid & GEOCLASSTID_SHADER) { 00091 ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter); //dynamic_cast<ntlGeometryShader*>(*iter); 00092 string outname = geoshad->getOutFilename(); 00093 if(outname.length()<1) outname = mpGlob->getOutFilename(); 00094 geoshad->notifyShaderOfDump(DUMP_FULLGEOMETRY, glob->getAniCount(),nrStr,outname); 00095 00096 for (vector<ntlGeometryObject*>::iterator siter = geoshad->getObjectsBegin(); 00097 siter != geoshad->getObjectsEnd(); 00098 siter++) { 00099 if(debugOut) debMsgStd("ntlBlenderDumper::BuildScene",DM_MSG,"added shader geometry "<<(*siter)->getName(), 8); 00100 00101 (*siter)->notifyOfDump(DUMP_FULLGEOMETRY, glob->getAniCount(),nrStr,outname, this->mSimulationTime); 00102 bool doDump = false; 00103 bool isPreview = false; 00104 // only dump final&preview surface meshes 00105 if( (*siter)->getName().find( "final" ) != string::npos) { 00106 doDump = true; 00107 } else if( (*siter)->getName().find( "preview" ) != string::npos) { 00108 doDump = true; 00109 isPreview = true; 00110 } 00111 if(!doDump) continue; 00112 00113 // dont quit, some objects need notifyOfDump call 00114 if((glob_mpactive) && (glob_mpindex>0)) { 00115 continue; //return 0; 00116 } 00117 00118 // only dump geo shader objects 00119 Triangles.clear(); 00120 Vertices.clear(); 00121 VertNormals.clear(); 00122 (*siter)->initialize( mpGlob ); 00123 (*siter)->getTriangles(this->mSimulationTime, &Triangles, &Vertices, &VertNormals, idCnt); 00124 idCnt ++; 00125 00126 // WARNING - this is dirty, but simobjs are the only geoshaders right now 00127 SimulationObject *sim = (SimulationObject *)geoshad; 00128 LbmSolverInterface *lbm = sim->getSolver(); 00129 00130 00131 // always dump mesh, even empty ones... 00132 00133 // dump to binary file 00134 std::ostringstream boutfilename(""); 00135 //boutfilename << ecrpath.str() << outname <<"_"<< (*siter)->getName() <<"_" << nrStr << ".obj"; 00136 boutfilename << outname <<"_"<< (*siter)->getName() <<"_" << nrStr; 00137 if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"B-Dumping: "<< (*siter)->getName() 00138 <<", triangles:"<<Triangles.size()<<", vertices:"<<Vertices.size()<< 00139 " to "<<boutfilename.str() , 7); 00140 gzFile gzf; 00141 00142 // output velocities if desired 00143 if((!isPreview) && (lbm->getDumpVelocities())) { 00144 std::ostringstream bvelfilename; 00145 bvelfilename << boutfilename.str(); 00146 bvelfilename << ".bvel.gz"; 00147 gzf = gzopen(bvelfilename.str().c_str(), "wb9"); 00148 if(gzf) { 00149 int numVerts; 00150 if(sizeof(numVerts)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; } 00151 numVerts = Vertices.size(); 00152 gzwrite(gzf, &numVerts, sizeof(numVerts)); 00153 for(size_t i=0; i<Vertices.size(); i++) { 00154 // returns smoothed velocity, scaled by frame time 00155 ntlVec3Gfx v = lbm->getVelocityAt( Vertices[i][0], Vertices[i][1], Vertices[i][2] ); 00156 // translation not necessary, test rotation & scaling? 00157 for(int j=0; j<3; j++) { 00158 float vertp = v[j]; 00159 //if(i<20) errMsg("ntlBlenderDumper","DUMP_VEL final "<<i<<" = "<<v); 00160 gzwrite(gzf, &vertp, sizeof(vertp)); } 00161 } 00162 gzclose( gzf ); 00163 } 00164 } 00165 00166 // compress all bobj's 00167 boutfilename << ".bobj.gz"; 00168 gzf = gzopen(boutfilename.str().c_str(), "wb1"); // wb9 is slow for large meshes! 00169 if (!gzf) { 00170 errMsg("ntlBlenderDumper::renderScene","Unable to open output '"<<boutfilename<<"' "); 00171 return 1; } 00172 00173 // dont transform velocity output, this is handled in blender 00174 // current transform matrix 00175 ntlMatrix4x4<gfxReal> *trafo; 00176 trafo = lbm->getDomainTrafo(); 00177 if(trafo) { 00178 // transform into source space 00179 for(size_t i=0; i<Vertices.size(); i++) { 00180 Vertices[i] = (*trafo) * Vertices[i]; 00181 } 00182 } 00183 // rotate vertnormals 00184 ntlMatrix4x4<gfxReal> rottrafo; 00185 rottrafo.initId(); 00186 if(lbm->getDomainTrafo()) { 00187 // dont modifiy original! 00188 rottrafo = *lbm->getDomainTrafo(); 00189 ntlVec3Gfx rTrans,rScale,rRot,rShear; 00190 rottrafo.decompose(rTrans,rScale,rRot,rShear); 00191 rottrafo.initRotationXYZ(rRot[0],rRot[1],rRot[2]); 00192 // only rotate here... 00193 for(size_t i=0; i<Vertices.size(); i++) { 00194 VertNormals[i] = rottrafo * VertNormals[i]; 00195 normalize(VertNormals[i]); // remove scaling etc. 00196 } 00197 } 00198 00199 00200 // write to file 00201 int numVerts; 00202 if(sizeof(numVerts)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; } 00203 numVerts = Vertices.size(); 00204 gzwrite(gzf, &numVerts, sizeof(numVerts)); 00205 for(size_t i=0; i<Vertices.size(); i++) { 00206 for(int j=0; j<3; j++) { 00207 float vertp = Vertices[i][j]; 00208 gzwrite(gzf, &vertp, sizeof(vertp)); } 00209 } 00210 00211 // should be the same as Vertices.size 00212 if(VertNormals.size() != (size_t)numVerts) { 00213 errMsg("ntlBlenderDumper::renderScene","Normals have to have same size as vertices!"); 00214 VertNormals.resize( Vertices.size() ); 00215 } 00216 gzwrite(gzf, &numVerts, sizeof(numVerts)); 00217 for(size_t i=0; i<VertNormals.size(); i++) { 00218 for(int j=0; j<3; j++) { 00219 float normp = VertNormals[i][j]; 00220 gzwrite(gzf, &normp, sizeof(normp)); } 00221 } 00222 00223 int numTris = Triangles.size(); 00224 gzwrite(gzf, &numTris, sizeof(numTris)); 00225 for(size_t i=0; i<Triangles.size(); i++) { 00226 for(int j=0; j<3; j++) { 00227 int triIndex = Triangles[i].getPoints()[j]; 00228 gzwrite(gzf, &triIndex, sizeof(triIndex)); } 00229 } 00230 gzclose( gzf ); 00231 debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY," Wrote: '"<<boutfilename.str()<<"' ", 2); 00232 numGMs++; 00233 } 00234 } 00235 00236 } 00237 00238 // output ecr config file 00239 if(numGMs>0) { 00240 if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Objects dumped: "<<numGMs, 10); 00241 } else { 00242 if((glob_mpactive) && (glob_mpindex>0)) { 00243 // ok, nothing to do anyway... 00244 } else { 00245 errFatal("ntlBlenderDumper::renderScene","No objects to dump! Aborting...",SIMWORLD_INITERROR); 00246 return 1; 00247 } 00248 } 00249 00250 // debug timing 00251 long stopTime = getTime(); 00252 debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Scene #"<<nrStr<<" dump time: "<< getTimeString(stopTime-startTime) <<" ", 10); 00253 00254 // still render for preview... 00255 if(debugRender) { 00256 debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY,"Performing preliminary render", 1); 00257 ntlWorld::renderScene(); } 00258 else { 00259 // next frame 00260 glob->setAniCount( glob->getAniCount() +1 ); 00261 } 00262 00263 return 0; 00264 } 00265 00266 00267