Blender  V2.59
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