Blender V2.61 - r43446

ntl_geometrymodel.cpp

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  * A simple box object
00010  *
00011  *****************************************************************************/
00012 
00013 #include "ntl_geometrymodel.h"
00014 #include "ntl_ray.h"
00015 #include "ntl_world.h"
00016 #include "zlib.h"
00017 
00018 #ifdef WIN32
00019 #ifndef strncasecmp
00020 #define strncasecmp(a,b,c) strcmp(a,b)
00021 #endif
00022 #endif // WIN32
00023 
00024 
00025 /******************************************************************************
00026  * Default Constructor 
00027  *****************************************************************************/
00028 ntlGeometryObjModel::ntlGeometryObjModel( void ) :
00029     ntlGeometryObject(),
00030     mvStart( 0.0 ), mvEnd( 1.0 ),
00031     mLoaded( false ),
00032     mTriangles(), mVertices(), mNormals(),
00033     mcAniVerts(), mcAniNorms(), 
00034     mcAniTimes(), mAniTimeScale(1.), mAniTimeOffset(0.)
00035 {
00036 }
00037 
00038 /******************************************************************************
00039  * Destructor
00040  *****************************************************************************/
00041 ntlGeometryObjModel::~ntlGeometryObjModel()
00042 {
00043     if(!mLoaded) {
00044         errMsg("ntlGeometryObjModel","delete obj...");
00045     }
00046 }
00047 
00048 
00050 bool ntlGeometryObjModel::getMeshAnimated() { 
00051     const bool ret = (mcAniVerts.getSize()>1); 
00052     //errMsg("getMeshAnimated","ret="<<ret<<", size="<<mcAniVerts.getSize() );
00053     return ret;
00054 }
00055 
00057 void ntlGeometryObjModel::getExtends(ntlVec3Gfx &sstart, ntlVec3Gfx &send) {
00058     bool ini=false;
00059     ntlVec3Gfx start(0.),end(0.);
00060     for(int s=0; s<=(int)mcAniVerts.accessValues().size(); s++) {
00061         vector<ntlVec3f> *sverts;
00062         if(mcAniVerts.accessValues().size()>0) {
00063             if(s==(int)mcAniVerts.accessValues().size()) continue;
00064             sverts  = &(mcAniVerts.accessValues()[s].mVerts);
00065         } else sverts = &mVertices;
00066 
00067         for(int i=0; i<(int)sverts->size(); i++) {
00068 
00069             if(!ini) {
00070                 start=(*sverts)[i];
00071                 end=(*sverts)[i];
00072                 //errMsg("getExtends","ini "<<s<<","<<i<<" "<<start<<","<<end);
00073                 ini=true;
00074             } else {
00075                 for(int j=0; j<3; j++) {
00076                     if(start[j] > (*sverts)[i][j]) { start[j]= (*sverts)[i][j]; }
00077                     if(end[j]   < (*sverts)[i][j]) { end[j]  = (*sverts)[i][j]; }
00078                 }
00079                 //errMsg("getExtends","check "<<s<<","<<i<<" "<<start<<","<<end<<" "<< (*sverts)[i]);
00080             }
00081 
00082         }
00083     }
00084     sstart=start;
00085     send=end;
00086 }
00087 
00088 
00089 /*****************************************************************************/
00090 /* Init attributes etc. of this object */
00091 /*****************************************************************************/
00092 void ntlGeometryObjModel::initialize(ntlRenderGlobals *glob) 
00093 {
00094     // perhaps the model is already inited from initModel below?
00095     if(mLoaded==1) {
00096         // init default material
00097         searchMaterial( glob->getMaterials() );
00098         return;
00099     }
00100     
00101     ntlGeometryObject::initialize(glob);
00102     mFilename = mpAttrs->readString("filename", mFilename,"ntlGeometryObjModel", "mFilename", true);
00103 
00104     if(mFilename == "") {
00105         errMsg("ntlGeometryObjModel::initialize","Filename not given!");
00106         return;
00107     }
00108 
00109     const char *suffix = strrchr(mFilename.c_str(), '.');
00110     if (suffix) {
00111         if (!strncasecmp(suffix, ".obj", 4)) {
00112             errMsg("ntlGeometryObjModel::initialize",".obj files not supported!");
00113             return;
00114         } else if (!strncasecmp(suffix, ".gz", 3)) { 
00115             //mType = 1; // assume its .bobj.gz
00116         } else if (!strncasecmp(suffix, ".bobj", 5)) { 
00117             //mType = 1;
00118         }
00119     }
00120 
00121     if(getAttributeList()->exists("ani_times") || (!mcAniTimes.isInited()) ) {
00122         mcAniTimes = mpAttrs->readChannelFloat("ani_times");
00123     }
00124     mAniTimeScale = mpAttrs->readFloat("ani_timescale", mAniTimeScale,"ntlGeometryObjModel", "mAniTimeScale", false);
00125     mAniTimeOffset = mpAttrs->readFloat("ani_timeoffset", mAniTimeOffset,"ntlGeometryObjModel", "mAniTimeOffset", false);
00126 
00127     // continue with standard obj
00128     if(loadBobjModel(mFilename)==0) mLoaded=1;
00129     if(!mLoaded) {
00130         debMsgStd("ntlGeometryObjModel",DM_WARNING,"Unable to load object file '"<<mFilename<<"' !", 0);
00131     }
00132     if(getMeshAnimated()) {
00133         this->mIsAnimated = true;
00134     }
00135 }
00136 
00137 /******************************************************************************
00138  * init model from given vertex and triangle arrays 
00139  *****************************************************************************/
00140 
00141 int ntlGeometryObjModel::initModel(int numVertices, float *vertices, int numTriangles, int *triangles,
00142         int channelSize, float *channelVertices)
00143 {
00144     mVertices.clear();
00145     mVertices.resize( numVertices );
00146     mNormals.resize( numVertices );
00147     for(int i=0; i<numVertices; i++) {
00148         mVertices[i] = ntlVec3Gfx(vertices[i*3+0],vertices[i*3+1],vertices[i*3+2]);
00149         mNormals[i] = ntlVec3Gfx(1.0); // unused, set to !=0.0
00150     }
00151 
00152     mTriangles.clear();
00153     mTriangles.resize( 3*numTriangles );
00154     int triangleErrs=0;
00155     for(int i=0; i<numTriangles; i++) {
00156         for(int j=0;j<3;j++) {
00157             mTriangles[3*i+j] = triangles[i*3+j];
00158             if(mTriangles[3*i+j]<0) { mTriangles[3*i+j]=0; triangleErrs++; }
00159             if(mTriangles[3*i+j]>=numVertices) { mTriangles[3*i+j]=0; triangleErrs++; }
00160         }
00161     }
00162     if(triangleErrs>0) {
00163         errMsg("ntlGeometryObjModel::initModel","Triangle errors occurred ("<<triangleErrs<<")!");
00164     }
00165 
00166     //fprintf(stderr,"initModel DEBUG %d \n",channelSize);
00167     debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Csize:"<<channelSize<<", Cvert:"<<(long)(channelVertices) ,10);
00168     if(channelVertices && (channelSize>0)) {
00169         vector<ntlSetVec3f> aniverts;
00170         vector<ntlSetVec3f> aninorms;
00171         vector<double> anitimes;
00172         aniverts.clear();
00173         aninorms.clear();
00174         anitimes.clear();
00175         for(int frame=0; frame<channelSize; frame++) {
00176             ntlSetVec3f averts; averts.mVerts.clear();
00177             ntlSetVec3f anorms; averts.mVerts.clear();
00178             int setsize = (3*numVertices+1);
00179 
00180             ntlVec3Gfx p(0.),n(1.);
00181             for(int i=0; i<numVertices; i++) {
00182                 for(int j=0; j<3; j++) p[j] = channelVertices[frame*setsize+ 3*i +j];
00183                 averts.mVerts.push_back(p);
00184                 anorms.mVerts.push_back(p);
00185                 //debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Frame:"<<frame<<",i:"<<i<<" "<<p,10);
00186             }
00187             if( ((int)averts.mVerts.size()==numVertices) && 
00188                 ((int)anorms.mVerts.size()==numVertices) ) {
00189                 aniverts.push_back(averts);
00190                 aninorms.push_back(anorms);
00191                 double time = (double)channelVertices[frame*setsize+ setsize-1];
00192                 anitimes.push_back(time);
00193             } else {
00194                 errMsg("ntlGeometryObjModel::initModel","Invalid mesh, obj="<<this->getName()<<" frame="<<frame<<" verts="<<averts.mVerts.size()<<"/"<<numVertices<<". Skipping...");
00195             }
00196             //debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Frame:"<<frame<<" at t="<<time,10);
00197         }
00198 
00199         mcAniVerts = AnimChannel<ntlSetVec3f>(aniverts,anitimes);
00200         mcAniNorms = AnimChannel<ntlSetVec3f>(aninorms,anitimes);
00201         debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Ani sets inited: "<< mcAniVerts.accessValues().size() <<","<<mcAniNorms.accessValues().size() <<" ", 1 );
00202     }
00203     if(getMeshAnimated()) {
00204         this->mIsAnimated = true;
00205     }
00206 
00207     // inited, no need to parse attribs etc.
00208     mLoaded = 1;
00209     return 0;
00210 }
00211 
00213 void ntlGeometryObjModel::calcTriangleDivs(vector<ntlVec3Gfx> &verts, vector<ntlTriangle> &tris, gfxReal fsTri) {
00214     // warning - copied from geomobj calc!
00215     errMsg("ntlGeometryObjModel","calcTriangleDivs special!");
00216     mTriangleDivs1.resize( tris.size() );
00217     mTriangleDivs2.resize( tris.size() );
00218     mTriangleDivs3.resize( tris.size() );
00219     for(size_t i=0; i<tris.size(); i++) {
00220         ntlVec3Gfx p0 = verts[ tris[i].getPoints()[0] ];
00221         ntlVec3Gfx p1 = verts[ tris[i].getPoints()[1] ];
00222         ntlVec3Gfx p2 = verts[ tris[i].getPoints()[2] ];
00223         ntlVec3Gfx side1 = p1 - p0;
00224         ntlVec3Gfx side2 = p2 - p0;
00225         ntlVec3Gfx side3 = p1 - p2;
00226         int divs1=0, divs2=0, divs3=0;
00227         if(normNoSqrt(side1) > fsTri*fsTri) { divs1 = (int)(norm(side1)/fsTri); }
00228         if(normNoSqrt(side2) > fsTri*fsTri) { divs2 = (int)(norm(side2)/fsTri); }
00229         //if(normNoSqrt(side3) > fsTri*fsTri) { divs3 = (int)(norm(side3)/fsTri); }
00230 
00231         // special handling
00232         // warning, requires objmodel triangle treatment (no verts dups)
00233         if(getMeshAnimated()) {
00234             vector<ntlSetVec3f> &sverts = mcAniVerts.accessValues();
00235             for(int s=0; s<(int)sverts.size(); s++) {
00236                 p0 = sverts[s].mVerts[ tris[i].getPoints()[0] ];
00237                 p1 = sverts[s].mVerts[ tris[i].getPoints()[1] ];
00238                 p2 = sverts[s].mVerts[ tris[i].getPoints()[2] ];
00239                 side1 = p1 - p0; side2 = p2 - p0; side3 = p1 - p2;
00240                 int tdivs1=0, tdivs2=0, tdivs3=0;
00241                 if(normNoSqrt(side1) > fsTri*fsTri) { tdivs1 = (int)(norm(side1)/fsTri); }
00242                 if(normNoSqrt(side2) > fsTri*fsTri) { tdivs2 = (int)(norm(side2)/fsTri); }
00243                 if(tdivs1>divs1) divs1=tdivs1;
00244                 if(tdivs2>divs2) divs2=tdivs2;
00245                 if(tdivs3>divs3) divs3=tdivs3;
00246             }
00247         } // */
00248         mTriangleDivs1[i] = divs1;
00249         mTriangleDivs2[i] = divs2;
00250         mTriangleDivs3[i] = divs3;
00251     }
00252 }
00253 
00254 
00255 /******************************************************************************
00256  * load model from .obj file
00257  *****************************************************************************/
00258 
00259 int ntlGeometryObjModel::loadBobjModel(string filename)
00260 {
00261     bool haveAniSets=false;
00262     vector<ntlSetVec3f> aniverts;
00263     vector<ntlSetVec3f> aninorms;
00264     vector<double> anitimes;
00265 
00266     const bool debugPrint=false;
00267     const bool debugPrintFull=false;
00268     gzFile gzf;
00269     gzf = gzopen(filename.c_str(), "rb");
00270     if (!gzf) {
00271         errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to open '"<< filename <<"'...\n", SIMWORLD_INITERROR );
00272         return 1;
00273     }
00274 
00275     int numVerts;
00276     if(sizeof(numVerts)!=4) {  // paranoia check
00277         errMsg("Reading GZ_BOBJ"," Invalid int size, check compiler settings: int has to be 4 byte long"); 
00278         goto gzreaderror;
00279     }
00280     gzread(gzf, &numVerts, sizeof(numVerts) );
00281     if(numVerts<0 || numVerts>1e9) {
00282         errMsg("Reading GZ_BOBJ"," invalid num vertices "<< numVerts);
00283         goto gzreaderror;
00284     }
00285     mVertices.clear();
00286     mVertices.resize( numVerts );
00287     for(int i=0; i<numVerts; i++) {
00288         float x[3];
00289         for(int j=0; j<3; j++) {
00290             gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); 
00291         }
00292         mVertices[i] = ntlVec3Gfx(x[0],x[1],x[2]);
00293         if(debugPrintFull) errMsg("FULLV"," "<<i<<" "<< mVertices[i] );
00294     }
00295     if(debugPrint) errMsg("NV"," "<<numVerts<<" "<< mVertices.size() );
00296 
00297     // should be the same as Vertices.size
00298     gzread(gzf, &numVerts, sizeof(numVerts) );
00299     if(numVerts<0 || numVerts>1e9) {
00300         errMsg("Reading GZ_BOBJ","invalid num normals "<< numVerts);
00301         goto gzreaderror;
00302     }
00303     mNormals.clear();
00304     mNormals.resize( numVerts );
00305     for(int i=0; i<numVerts; i++) {
00306         float n[3];
00307         for(int j=0; j<3; j++) {
00308             gzread(gzf, &(n[j]), sizeof( (n[j]) ) ); 
00309         }
00310         mNormals[i] = ntlVec3Gfx(n[0],n[1],n[2]);
00311         if(debugPrintFull) errMsg("FULLN"," "<<i<<" "<< mNormals[i] );
00312     }
00313     if(debugPrint) errMsg("NN"," "<<numVerts<<" "<< mNormals.size() );
00314 
00315     int numTris;
00316     gzread(gzf, &numTris, sizeof(numTris) );
00317     if(numTris<0 || numTris>1e9) {
00318         errMsg("Reading GZ_BOBJ","invalid num normals "<< numTris);
00319         goto gzreaderror;
00320     }
00321     mTriangles.resize( 3*numTris );
00322     for(int i=0; i<numTris; i++) {
00323         int tri[3];
00324         for(int j=0; j<3; j++) {
00325             gzread(gzf, &(tri[j]), sizeof( (tri[j]) ) ); 
00326         }
00327         mTriangles[3*i+0] = tri[0];
00328         mTriangles[3*i+1] = tri[1];
00329         mTriangles[3*i+2] = tri[2];
00330     }
00331     if(debugPrint) errMsg("NT"," "<<numTris<<" "<< mTriangles.size() );
00332 
00333     debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' loaded, #Vertices: "<<mVertices.size()<<", #Normals: "<<mNormals.size()<<", #Triangles: "<<(mTriangles.size()/3)<<" ", 1 );
00334 
00335     // try to load animated mesh
00336     aniverts.clear();
00337     aninorms.clear();
00338     anitimes.clear();
00339     while(1) {
00340         //ntlVec3Gfx check;
00341         float x[3];
00342         float frameTime=0.;
00343         int bytesRead = 0;
00344         int numNorms2=-1, numVerts2=-1;
00345         //for(int j=0; j<3; j++) {
00346             //x[j] = 0.;
00347             //bytesRead += gzread(gzf, &(x[j]), sizeof(float) ); 
00348         //}
00349         //check = ntlVec3Gfx(x[0],x[1],x[2]);
00350         //if(debugPrint) errMsg("ANI_NV1"," "<<check<<" "<<" bytes:"<<bytesRead );
00351         bytesRead += gzread(gzf, &frameTime, sizeof(frameTime) );
00352         //if(bytesRead!=3*sizeof(float)) {
00353         if(bytesRead!=sizeof(float)) {
00354             debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' end of gzfile. ", 10 );
00355             if(anitimes.size()>0) {
00356                 // finally init channels and stop reading file
00357                 mcAniVerts = AnimChannel<ntlSetVec3f>(aniverts,anitimes);
00358                 mcAniNorms = AnimChannel<ntlSetVec3f>(aninorms,anitimes);
00359             }
00360             goto gzreaddone;
00361         }
00362         bytesRead += gzread(gzf, &numVerts2, sizeof(numVerts2) );
00363         haveAniSets=true;
00364         // continue to read new set
00365         vector<ntlVec3Gfx> vertset;
00366         vector<ntlVec3Gfx> normset;
00367         vertset.resize(numVerts);
00368         normset.resize(numVerts);
00369         //vertset[0] = check;
00370         if(debugPrintFull) errMsg("FUL1V"," "<<0<<" "<< vertset[0] );
00371 
00372         for(int i=0; i<numVerts; i++) { // start at one!
00373             for(int j=0; j<3; j++) {
00374                 bytesRead += gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); 
00375             }
00376             vertset[i] = ntlVec3Gfx(x[0],x[1],x[2]);
00377             if(debugPrintFull) errMsg("FUL2V"," "<<i<<" "<< vertset[i] );
00378         }
00379         if(debugPrint) errMsg("ANI_VV"," "<<numVerts<<" "<< vertset.size()<<" bytes:"<<bytesRead );
00380 
00381         bytesRead += gzread(gzf, &numNorms2, sizeof(numNorms2) );
00382         for(int i=0; i<numVerts; i++) {
00383             for(int j=0; j<3; j++) {
00384                 bytesRead += gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); 
00385             }
00386             normset[i] = ntlVec3Gfx(x[0],x[1],x[2]);
00387             if(debugPrintFull) errMsg("FUL2N"," "<<i<<" "<< normset[i] );
00388         }
00389         if(debugPrint) errMsg("ANI_NV"," "<<numVerts<<","<<numVerts2<<","<<numNorms2<<","<< normset.size()<<" bytes:"<<bytesRead );
00390 
00391         // set ok
00392         if(bytesRead== (int)( (numVerts*2*3+1) *sizeof(float)+2*sizeof(int) ) ) {
00393             if(aniverts.size()==0) {
00394                 // TODO, ignore first mesh?
00395                 double anitime = (double)(frameTime-1.); // start offset!? anitimes.size();
00396                 // get for current frame entry
00397                 if(mcAniTimes.getSize()>1)  anitime = mcAniTimes.get(anitime); 
00398                 anitime = anitime*mAniTimeScale+mAniTimeOffset;
00399 
00400                 anitimes.push_back( anitime );
00401                 aniverts.push_back( ntlSetVec3f(mVertices) );
00402                 aninorms.push_back( ntlSetVec3f(mNormals) );
00403                 if(debugPrint) errMsg("ANI_NV","new set "<<mVertices.size()<<","<< mNormals.size()<<" time:"<<anitime );
00404             }
00405             double anitime = (double)(frameTime); //anitimes.size();
00406             // get for current frame entry
00407             if(mcAniTimes.getSize()>1)  anitime = mcAniTimes.get(anitime); 
00408             anitime = anitime*mAniTimeScale+mAniTimeOffset;
00409 
00410             anitimes.push_back( anitime );
00411             aniverts.push_back( ntlSetVec3f(vertset) );
00412             aninorms.push_back( ntlSetVec3f(normset) );
00413             if(debugPrint) errMsg("ANI_NV","new set "<<vertset.size()<<","<< normset.size()<<" time:"<<anitime );
00414         } else {
00415             errMsg("ntlGeometryObjModel::loadBobjModel","Malformed ani set! Aborting... ("<<bytesRead<<") ");
00416             goto gzreaddone;
00417         }
00418     } // anim sets */
00419 
00420 gzreaddone:
00421 
00422     if(haveAniSets) { 
00423         debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' ani sets loaded: "<< mcAniVerts.accessValues().size() <<","<<mcAniNorms.accessValues().size() <<" ", 1 );
00424     }
00425     gzclose( gzf );
00426     return 0;
00427 
00428 gzreaderror:
00429     mTriangles.clear();
00430     mVertices.clear();
00431     mNormals.clear();
00432     gzclose( gzf );
00433     errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to load '"<< filename <<"', exiting...\n", SIMWORLD_INITERROR );
00434     return 1;
00435 }
00436 
00437 
00438 /******************************************************************************
00439  * 
00440  *****************************************************************************/
00441 void 
00442 ntlGeometryObjModel::getTriangles(double t, vector<ntlTriangle> *triangles, 
00443                                                             vector<ntlVec3Gfx> *vertices, 
00444                                                             vector<ntlVec3Gfx> *normals, int objectId )
00445 {
00446     if(!mLoaded) { // invalid type...
00447         return;
00448     }
00449     if(mcAniVerts.getSize()>1) { mVertices = mcAniVerts.get(t).mVerts; }
00450     if(mcAniNorms.getSize()>1) { mNormals  = mcAniNorms.get(t).mVerts; }
00451 
00452     int startvert = vertices->size();
00453     vertices->resize( vertices->size() + mVertices.size() );
00454     normals->resize( normals->size() + mVertices.size() );
00455     for(int i=0; i<(int)mVertices.size(); i++) {
00456         (*vertices)[startvert+i] = mVertices[i];
00457         (*normals)[startvert+i] = mNormals[i];
00458     }
00459 
00460     triangles->reserve(triangles->size() + mTriangles.size()/3 );
00461     for(int i=0; i<(int)mTriangles.size(); i+=3) {
00462         int trip[3];
00463         trip[0] = startvert+mTriangles[i+0];
00464         trip[1] = startvert+mTriangles[i+1];
00465         trip[2] = startvert+mTriangles[i+2];
00466 
00467         //sceneAddTriangle( 
00468                 //mVertices[trip[0]], mVertices[trip[1]], mVertices[trip[2]], 
00469                 //mNormals[trip[0]], mNormals[trip[1]], mNormals[trip[2]], 
00470                 //ntlVec3Gfx(0.0), 1 , triangles,vertices,normals ); /* normal unused */
00471         sceneAddTriangleNoVert( trip, ntlVec3Gfx(0.0), 1 , triangles ); /* normal unused */
00472     }
00473     objectId = -1; // remove warning
00474     // bobj
00475     return;
00476 }
00477 
00478 
00479 
00480 
00481