Biomechanical Joint Model
 Author: Anderson Maciel

comemesh.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2002 by Anderson Maciel                                 *
00003  *   andi.maciel@gmail.com                                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  **************************************************************************/
00030 
00031 #include <algebra/comemesh.h>
00032 #include <algebra/comepoint3d.h>
00033 #include <algebra/comevector3d.h>
00034 #include <bio/comebiostructure.h>
00035 #include <bio/comemoleculescartilage.h>
00036 //#include <bio/comemoleculestissue.h>
00037 #include <VCOLLIDE/RAPID/RAPID.H>
00038 #include <math.h>
00039 
00040 #ifndef VTK_USE_ANSI_STDLIB
00041 #define VTK_USE_ANSI_STDLIB
00042 #endif
00043 #include <vtkPolyDataReader.h>
00044 #include <vtkPolyData.h>
00045 #include <vtkCellArray.h>
00046 
00047 int COME_Mesh::textureCount = 0;
00051 COME_Mesh::COME_Mesh(){
00052 
00053         texture         = NULL; 
00054         textureID = 0;
00055 }
00056 
00057 COME_Mesh :: COME_Mesh( const vector<COME_Vertex3D> verticesN, const vector<COME_Face> facesN, COME_BioStructure* parentN ){
00058 
00059         vertices        = verticesN; 
00060         faces           = facesN;
00061         parent          = parentN;
00062         texture         = NULL;
00063 }
00064 
00065 COME_Mesh ::~COME_Mesh(){
00066 
00067         
00068 }
00069 
00073 
00074 void                            
00075 COME_Mesh :: addFaceAsIndices( vector<int> indicesN ){
00076 
00077         COME_Face face( indicesN, this );
00078         face.updateNormal();
00080         //face.setNearestMolecule( ((COME_MoleculesCartilage*)parent)->getTissue()->nearestTo( face.getCenter() ) );
00081 
00082         faces.push_back( face );
00083 }
00084 
00085 void
00086 COME_Mesh :: addVertex( COME_Vertex3D vertexN ){
00087 
00088         vertices.push_back( vertexN );
00089         verticesGlobal.push_back( vertexN ); 
00090 }
00091 
00092 void
00093 COME_Mesh :: setAVertex( COME_Vertex3D vertN, int iPosN ){
00094 
00095         vertices[iPosN] = vertN;
00096 
00097 }
00098 
00099 void
00100 COME_Mesh :: setCollisionDetectableFaces() {
00101 
00102         vector<COME_Face*> result;
00103         for (int i = 0; i < faces.size();i++){
00104                 
00105                 for ( int iPos = 0; iPos < faces[i].getNumberVertices(); iPos ++ ){  
00106                         
00107                         if( faces[i].getVertex( iPos ).vpDistance( COME_Point3D() ) < ((COME_BioStructure*)parent)->getCollisionRadius() ){
00108                                 faces[i].setCollisionDetectable( true );
00109                                 break;
00110                         }
00111                         faces[i].setCollisionDetectable( false );
00112                 }
00113         }
00114 }
00115 
00116 void
00117 COME_Mesh :: setFileName( string newName ){
00118 
00119         meshFile = newName;
00120 }
00121         
00122 
00126 
00127 string
00128 COME_Mesh :: getFileName(){
00129 
00130         return meshFile;
00131 }
00132 
00133 vector<COME_Vertex3D>&  
00134 COME_Mesh :: getVertices(){
00135 
00136         return vertices;
00137 }
00138 
00139 vector<COME_Vertex3D>*
00140 COME_Mesh :: getVerticesPt(){
00141 
00142         return &vertices;
00143 }
00144 vector<COME_Vertex3D>   
00145 COME_Mesh :: getVerticesGlobal() {
00146         return verticesGlobal;
00147 }
00148 
00149 vector<COME_Vertex3D>*
00150 COME_Mesh::getVerticesGlobalPt(){
00151         return &verticesGlobal;
00152 }
00153 
00154 COME_Matrix
00155 COME_Mesh:: getGIM(){
00156         return ((COME_BioStructure*)parent)->getGIM();
00157 }
00158 
00159 COME_Vertex3D*
00160 COME_Mesh :: getAVertexGlobalPositionPt( int iPosN ) {
00161  return &verticesGlobal[iPosN];
00162 }
00163 
00164 COME_Vertex3D
00165 COME_Mesh :: getAVertexGlobalPosition( int iPosN ) {
00166 
00167         return verticesGlobal[ iPosN ];
00168 }
00169 
00170 COME_Vertex3D
00171 COME_Mesh :: getClosestVertex( COME_Point3D givenPoint ) const {
00172 
00173         double minDist  = givenPoint.vpDistance( verticesGlobal[ 0 ] );
00174         int nearest             = 0;
00175         //search the vertex nearest of the currentPoint
00176         for ( int i = 1; i < verticesGlobal.size(); i++ ){
00177         
00178                 double currDist = givenPoint.vpDistance( verticesGlobal[ i ] );
00179                 if( currDist < minDist ){
00180                         minDist = currDist;
00181                         nearest = i;
00182                 }
00183         }
00184         return verticesGlobal[ nearest ];
00185 }
00186 
00187 int
00188 COME_Mesh :: getClosestVertexIndex( COME_Point3D givenPoint ) const {
00189 
00190         double minDist  = givenPoint.vpDistance( verticesGlobal[ 0 ] );
00191         int nearest     = 0;
00192         //search the vertex nearest of the currentPoint
00193         for ( int i = 1; i < verticesGlobal.size(); i++ ){
00194         
00195                 double currDist = givenPoint.vpDistance( verticesGlobal[ i ] );
00196                 if( currDist < minDist ){
00197                         minDist = currDist;
00198                         nearest = i;
00199                 }
00200         }
00201         return nearest;
00202 }
00203 
00204 int
00205 COME_Mesh :: getClosestFaceIndex( COME_Point3D givenPoint ) {
00206 
00207         double minDist  = faces[0].distancePointFaceGlobal( givenPoint );
00208         int nearestF    = 0;
00209 
00210         for( int iF = 1; iF < faces.size(); iF++ ){
00211                 double currDist = faces[iF].distancePointFaceGlobal( givenPoint );
00212                 
00213                 if( currDist < minDist ){
00214                         minDist = currDist;
00215                         nearestF = iF;
00216                 }
00217         }
00218         
00219         return nearestF;
00220 }
00221 
00222 vector<COME_Face>       
00223 COME_Mesh :: getFaces() const {
00224         return faces;
00225 }
00226 
00227 vector<COME_Face>       *
00228 COME_Mesh :: getFacesPt() {
00229         return &faces;
00230 }
00231 
00232 vector<COME_Face*>      
00233 COME_Mesh :: getPtFaces() {
00234 
00235         vector<COME_Face*> result;
00236         for (int i = 0; i < faces.size();i++){
00237                 result.push_back(&faces[i]);
00238         }
00239         return result;
00240 }
00241 
00242 vector<COME_Vertex3D>
00243 COME_Mesh :: getVerticesFace( int iNumberFace ) const{
00244         
00245         vector<COME_Vertex3D> vertex;
00246 
00247         COME_Face faceN = faces[ iNumberFace ];
00248         for ( int iPos = 0; iPos < faceN.getNumberVertices(); iPos ++ ){  
00249                         
00250                 vertex.push_back( faceN.getVertex( iPos ) );    
00251         }
00252 
00253         return vertex;
00254 }
00255 
00256 vector<COME_Vertex3D>
00257 COME_Mesh :: getVerticesFaceGlobalPosition( int iNumberFace ) const{
00258         
00259         vector<COME_Vertex3D> vertex;
00260 
00261         COME_Face faceN = faces[ iNumberFace ];
00262         for ( int iPos = 0; iPos < faceN.getNumberVertices(); iPos ++ ){  
00263                         
00264                 vertex.push_back( faceN.getVertexGlobalPosition( iPos ) );      
00265         }
00266 
00267         return vertex;
00268 }
00269 
00270 COME_Vertex3D
00271 COME_Mesh :: getAVertex( int iPosN ) const{
00272 
00273         return vertices[ iPosN ];
00274 }
00275 
00276 COME_Vertex3D*
00277 COME_Mesh :: getAVertexPt( int iPosN ){
00278 
00279         return &vertices[ iPosN ];
00280 }
00281 
00282 
00283 COME_Face
00284 COME_Mesh :: getAFace( int iNumberFace ) const{
00285 
00286         return faces[ iNumberFace ];
00287 }
00288 
00289 COME_Face*
00290 COME_Mesh :: getAFacePt( int iNumberFace ){
00291 
00292         return &faces[ iNumberFace ];
00293 }
00294 
00295 int                     
00296 COME_Mesh :: getNumberFaces() const{
00297 
00298         return faces.size();
00299 }
00300 
00301 void 
00302 COME_Mesh :: getEnvelop( COME_Point3D& mins, COME_Point3D& maxs ){
00303 
00304         double xMin = 0.0,yMin = 0.0,zMin = 0.0,xMax = 0.0,yMax = 0.0,zMax = 0.0;
00305 
00306         if( vertices.size() > 0 ){
00307                 //initialization
00308                 xMin  = vertices[ 0 ].getX();
00309                 yMin  = vertices[ 0 ].getY();   
00310                 zMin  = vertices[ 0 ].getZ();
00311                 xMax  = xMin; 
00312                 yMax  = yMin;
00313                 zMax  = zMin;
00314                 
00315                 for ( int i = 1; i < vertices.size(); i++ ){
00316                 
00317                         //min
00318                         if ( xMin > vertices[ i ].getX() ){
00319                         
00320                                 xMin = vertices[ i ].getX();            
00321                         }
00322         
00323                         if ( yMin > vertices[ i ].getY() ){
00324                         
00325                                 yMin = vertices[ i ].getY();            
00326                         }
00327         
00328                         if ( zMin > vertices[ i ].getZ() ){
00329                         
00330                                 zMin = vertices[ i ].getZ();            
00331                         }
00332         
00333         
00334                         //max
00335                         if ( xMax < vertices[ i ].getX() ){
00336                         
00337                                 xMax = vertices[ i ].getX();            
00338                         }
00339         
00340                         if ( yMax < vertices[ i ].getY() ){
00341                         
00342                                 yMax = vertices[ i ].getY();            
00343                         }
00344         
00345                         if ( zMax < vertices[ i ].getZ() ){
00346                         
00347                                 zMax = vertices[ i ].getZ();            
00348                         }
00349         
00350         
00351                 }
00352         } else {
00353                 printf( "Mesh is empty, envelop is set to (0 0 0) (0 0 0). \n" );
00354         }
00355 
00356         mins.setXYZ( xMin, yMin, zMin );
00357         maxs.setXYZ( xMax, yMax, zMax );
00358 
00359 }
00360 
00361 COME_Point3D
00362 COME_Mesh::medialPoint(){
00363 
00364         COME_Point3D medial;
00365         for ( int i = 0; i < vertices.size(); i++ ){
00366         
00367                 medial = medial + vertices[i];
00368         }
00369         medial = medial * ( 1.0 / (double)vertices.size() );
00370         return medial;
00371 }
00372 
00373 void 
00374 COME_Mesh :: resetCollisionDisps(){
00375 
00376         for ( int i = 0; i < vertices.size(); i++ ){
00377         
00378                 verticesGlobal[i].setCollisionDisp( COME_Vector3D() );
00379                 verticesGlobal[i].setVelocityDisp( COME_Vector3D() );
00380         }
00381         
00382 }
00383 
00387 
00388 // Recalculates all the vertices position based on the anchoring molecules
00389 // and updates the faces normals as well as the Vertices normals
00390 void 
00391 COME_Mesh:: updateSkin(){
00392         if (COME::flagSkinning ){
00393                 //printf( "Updating skinning\n" );
00394                 updateGlobalPositions();
00395                 updateFacesNormalsGlobalPosition();
00396                 //Would be good to calculate the vertices normals only if we realy need them
00397                 //if (calcNormals){
00398                         updateVerticesNormalsGlobalPosition();
00399                 //}
00400         }
00401 }
00402 
00403 void    
00404 COME_Mesh :: updateGlobalPositions() {
00405 
00406         COME_Matrix localGIM = ((COME_BioStructure*)parent)->getGIM();
00407 
00408         //printf( " BEFORE %f %f %f\n", verticesGlobal[1].getX(), verticesGlobal[1].getY(), verticesGlobal[1].getZ());
00409         for( int i = 0; i < vertices.size(); i++ ){
00410                 if( vertices[i].localPositions.size() > 0 ){
00411                         verticesGlobal[i] = /*localGIM **/ vertices[i].getBlendedPosition();
00412                         verticesGlobal[i].setTexCoord( vertices[i].getTexCoord() );
00413                         verticesGlobal[i].setOwnerFace( vertices[i].getOwnerFace() );
00414                         verticesGlobal[i].anchors = vertices[i].anchors;
00415                         verticesGlobal[i].localPositions = vertices[i].localPositions;
00416                         //printf("skinning ON\n");
00417                 } else {
00418                         verticesGlobal[i] = localGIM * vertices[i];
00419                         //printf("NO skinning\n");
00420                 }
00421                 //verticesGlobal[i].setCollisionDisp( COME_Vector3D() );
00422         }
00423         //printf( " AFTER_ %f %f %f\n", verticesGlobal[1].getX(), verticesGlobal[1].getY(), verticesGlobal[1].getZ());
00424 }
00425 
00426 void
00427 COME_Mesh::updateFacesNormalsGlobalPosition(){
00428         
00429         for (int i = 0; i < faces.size();i++){
00430                 faces[i].updateNormalGlobalPosition();
00431                 //printf(" FACES NORMALS: %f %f %f \n", faces[i].getNormalGlobalPosition().x, faces[i].getNormalGlobalPosition().y, faces[i].getNormalGlobalPosition().z );
00432                 
00434                 /*double lacor[4]; lacor[0]=1; lacor[1]=0.2; lacor[2]=0.2; lacor[3]=1;
00435                 faces[i].getVertexGlobalPositionPt(0)->setColor( lacor );
00436                 faces[i].getVertexGlobalPositionPt(1)->setColor( lacor );
00437                 faces[i].getVertexGlobalPositionPt(2)->setColor( lacor );*/
00438         }
00439 }
00440 
00441 void
00442 COME_Mesh :: updateVerticesNormals(){
00443         
00444         for( int i = 0; i < vertices.size(); i++ ){
00445                 
00446                 vector <int> neighbourFaces = verticesGlobal[i].getNeighbourFaces();
00447                 COME_Vector3D totalNormals;
00448                 
00449                 for( int j = 0; j < neighbourFaces.size(); j++ ){
00450                         totalNormals += faces[neighbourFaces[j]].getNormal();
00451                         //printf("NEIGHBOUR FACES NORMALS: %f %f %f \n", faces[neighbourFaces[j]].getNormalGlobalPosition().x, faces[neighbourFaces[j]].getNormalGlobalPosition().y, faces[neighbourFaces[j]].getNormalGlobalPosition().z );
00452                 }
00453                 totalNormals = totalNormals / neighbourFaces.size();
00454                 totalNormals.vpNormalize();
00455                 verticesGlobal[i].setNormal(totalNormals);
00456                 //printf(" Vertices Globals: %f %f %f \n", totalNormals.x, totalNormals.y, totalNormals.z );
00457  
00458         }
00459 }
00460 
00461 void
00462 COME_Mesh :: updateVerticesNormalsGlobalPosition(){
00463         
00464         for( int i = 0; i < vertices.size(); i++ ){
00465                 
00466                 vector <int> neighbourFaces = verticesGlobal[i].getNeighbourFaces();
00467                 COME_Vector3D totalNormals;
00468                 
00469                 for( int j = 0; j < neighbourFaces.size(); j++ ){
00470                         totalNormals += faces[neighbourFaces[j]].getNormalGlobalPosition();
00471                         //printf("NEIGHBOUR FACES NORMALS: %f %f %f \n", faces[neighbourFaces[j]].getNormalGlobalPosition().x, faces[neighbourFaces[j]].getNormalGlobalPosition().y, faces[neighbourFaces[j]].getNormalGlobalPosition().z );
00472                 }
00473                 totalNormals = totalNormals / neighbourFaces.size();
00474                 totalNormals.vpNormalize();
00475                 verticesGlobal[i].setNormalGlobalPosition(totalNormals);
00476                 //printf(" Vertices Globals: %f %f %f \n", totalNormals.x, totalNormals.y, totalNormals.z );
00477  
00478         }
00479 }
00480 
00481 
00485 
00486 bool
00487 COME_Mesh :: isInside( COME_Point3D currentPoint ){
00488 
00489         double area = 0.0;
00490         for ( int f = 0; f < faces.size(); f++ ){
00491                 faces[f].setParent(this); // This is not good, used because parent was lost
00492                 area += faces[f].geoSolidAngle( currentPoint );
00493         }
00494         return ( ( ( area > 2*M_PI ) || ( area < -2*M_PI ) ) ? true : false );
00495         
00496 
00497 }
00498 
00503 void
00504 COME_Mesh::findIntersections( COME_Point3D pi, COME_Point3D pf, vector<COME_Point3D> *allIntersections ){
00505 
00506         COME_Vector3D n, v, vl, vll;
00507         double t, denom, U, V;
00508         
00509         vector<COME_Vertex3D>* allVertices = getVerticesGlobalPt();
00510 
00511         for (int i = 0; i < faces.size();i++){
00512 
00513                 v = allVertices->at(faces[i].getIndexVertex(0));
00514                 vl = allVertices->at(faces[i].getIndexVertex(1));
00515                 vll = allVertices->at(faces[i].getIndexVertex(2));
00516                 n = faces[i].getNormal();
00517                 
00518                 // If segment and face are parallel the average position of the vertices should be the intersecting point, but the code is commented below to avoid indesirable points when faces are very large
00519                 denom = COME_Vector3D( pf - pi ).vpDotProduct(n);
00520                 /*if( denom == 0.0 ){
00521                         // point is put in the face center
00522                         allIntersections->push_back( COME_Vector3D( v + vl + vll ) / 3.0 );
00523                         continue;
00524                 }
00525                 */
00526                 
00527                 t = -(COME_Vector3D( pi - v ).vpDotProduct(n) / denom);
00528                 COME_Vector3D VPt = ( pi - v ) + ( ( pf - pi ) * t );
00529                 
00530                 denom = ((vl-v)*(vll-v)).maxK();
00531                 U = (VPt*(vll-v)).maxK()/denom;
00532                 V = ((vl-v)*VPt).maxK()/denom;
00533                                 
00534                 if( ( U >= 0.0 ) && ( U <= 1.0 ) && ( V >= 0.0 ) && ( V <= 1.0 ) && ( U+V >= 0.0 ) && ( U+V <= 1.0 ) ){
00535                         allIntersections->push_back( v+VPt );
00536                 }
00537         }
00538 }
00539 
00543 bool
00544 COME_Mesh :: loadFile( string fileName, double scaleFactor, COME_Point3D originTranslation ){
00545 
00546         FILE *file;
00547         float x1, y1, z1, x2, y2, z2, t1, t2;
00548         int v1, v2, v3, terminator;
00549 
00550         setFileName( fileName );
00551         //Split here to load vtk files
00552 
00553         if( !( fileName.find(".vtk",0) == string::npos ) ){
00554 
00555                         // open and load the file
00556                         vtkPolyDataReader *vtkComeLoader = vtkPolyDataReader::New();
00557                         vtkComeLoader->SetFileName( fileName.c_str() );
00558                         vtkComeLoader->Update();
00559                         vtkPolyData *vtkData = vtkComeLoader->GetOutput();
00560 
00561                         vtkIdType *pts = 0;
00562                         vtkIdType npts = 0;
00563                         float *floatArray;
00564 
00565                         // parse the polydata
00566 
00567                         npts = vtkData->GetNumberOfPoints();
00568                         for (int i = 0;  i < npts; i++)
00569                         {
00570                                 floatArray = vtkData->GetPoint( i );
00571                                 addVertex( COME_Vertex3D( ( floatArray[0]-originTranslation.getX() )* scaleFactor, ( floatArray[1]-originTranslation.getY() )* scaleFactor, ( floatArray[2]-originTranslation.getZ() )* scaleFactor ) );
00572                         }
00573 
00574                         vtkCellArray *inputPolys = vtkData->GetPolys();
00575                         inputPolys->InitTraversal();
00576                         
00577                         while(inputPolys->GetNextCell(npts,pts))
00578                         {
00579                                 vector<int> thisFace;
00580                                 thisFace.push_back( pts[0] );
00581                                 thisFace.push_back( pts[1] );
00582                                 thisFace.push_back( pts[2] );
00583                                 addFaceAsIndices( thisFace );
00584                         }
00585                 
00586         } else if( file = fopen( fileName.c_str(), "r" ) ){
00587                 char buffer[90];
00588                 string str_buffer;
00589                 do {
00590                         fgets( buffer, 80, file ); 
00591                         str_buffer = buffer;
00592 
00593                         if( feof( file ) ){
00594                                 printf( "Wrong format file. \"point [\\r|n\" or \"vertex [\\r|n\" section not found.");
00595                                 exit(0);
00596                         }
00597                 } 
00598 //#ifndef _WIN32
00599                 while( ( ( str_buffer.find( "point [\r", 0 ) == string::npos ) && ( str_buffer.find( "vertex [\r", 0 ) == string::npos ) ) && ( ( str_buffer.find( "point [\n", 0 ) == string::npos ) && ( str_buffer.find( "vertex [\n", 0 ) == string::npos ) ) ) ;
00600 //#else
00601                 //while( ( ( str_buffer.find( "point [\n", 0 ) == string::npos ) && ( str_buffer.find( "vertex [\n", 0 ) == string::npos ) ) && ( ( str_buffer.find( "point [\n", 0 ) == string::npos ) && ( str_buffer.find( "vertex [\n", 0 ) == string::npos ) ) ) ;
00602                 //while( strcmp( buffer, "              point [\n") && strcmp( buffer, "                vertex [\n") );
00603 //#endif
00604 
00605                 printf( "Start reading points.\n" );
00606                 while( fscanf( file, "                  %f %f %f, %f %f %f, ", &x1, &y1, &z1, &x2, &y2, &z2 ) ){
00607 
00608                         addVertex( COME_Vertex3D( ( x1-originTranslation.getX() )* scaleFactor, ( y1-originTranslation.getY() )* scaleFactor, ( z1-originTranslation.getZ() )* scaleFactor ) );
00609                         addVertex( COME_Vertex3D( ( x2-originTranslation.getX() )* scaleFactor, ( y2-originTranslation.getY() )* scaleFactor, ( z2-originTranslation.getZ() )* scaleFactor ) );
00610                 }
00611                 printf( "Finished reading points.\n" );
00612 
00613                 do {
00614                         fgets( buffer, 80, file ); 
00615                         str_buffer = buffer;
00616                         if( feof( file ) ){
00617                                 printf( "Wrong format file. \"coordIndex [\\r\" section not found.");
00618                                 exit(0);
00619                         }
00620                 }while( ( str_buffer.find( "coordIndex [\r", 0 ) == string::npos ) && ( str_buffer.find( "coordIndex [\n", 0 ) == string::npos ) );
00621 
00622                 printf( "Start reading faces.\n" );
00623                 while( fscanf( file, "                  %d, %d, %d, %d,", &v1, &v2, &v3, &terminator ) ){
00624 
00625                         vector<int> thisFace;
00626                         thisFace.push_back( v1 );
00627                         thisFace.push_back( v2 );
00628                         thisFace.push_back( v3 );
00629                         addFaceAsIndices( thisFace );
00630                 }
00631                 printf( "Finished reading faces.\n" );
00632                 
00634                 rewind(file);
00635                 bool noTexture = false;
00636                 do {
00637                         fgets( buffer, 80, file ); 
00638                         str_buffer = buffer;
00639                         if( feof( file ) ){
00640                                 printf( " \"texCoord\" section not found.");
00641                                 noTexture = true;
00642                                 break;//exit(0);
00643                         }
00644                 }while( ( str_buffer.find( "texCoord", 0 ) == string::npos ) );
00645                 if( !noTexture ){
00646                         fpos_t filePos;
00647                         do {
00648                                 fgetpos ( file , &filePos );
00649                                 fgets( buffer, 80, file ); 
00650                                 str_buffer = buffer;
00651                                 printf( "str_buffer=%s\n", str_buffer.c_str() );
00652                                 if( feof( file ) ){
00653                                         printf( "Texture coordinates not found.");
00654                                         noTexture = true;
00655                                         break;//exit(0);
00656                                 }
00657                         }while( ( str_buffer.find( "point [", 0 ) == string::npos ) );
00658         
00659                         if( ! noTexture ){
00660                                 printf( "Start reading texture coordinates.\n" );
00661                                 int texInd = 0;
00662                                 fsetpos ( file , &filePos );
00663                                 fscanf( file, "         point [ %f %f,", &t1, &t2 );
00664                                 vertices[texInd++].setTexCoord( COME_Point2D(t1, t2) );
00665                                 while( fscanf( file, "          %f %f,", &t1, &t2 ) == 2 ){
00666                                         // add tex coordinates to vertices here
00667                                         vertices[texInd++].setTexCoord( COME_Point2D(t1, t2) );
00668                                 }
00669                                 printf( "Finished reading texture coordinates.\n" );
00670                         }
00671                 }
00672 
00673                 fclose( file );
00674 
00675                 printf( "Start calculating normals.\n" );
00676                 updateFacesNormalsGlobalPosition();
00677                 updateVerticesNormalsGlobalPosition();
00678                 printf( "Finished calculating normals.\n" );
00679 
00680                 
00681                 printf( "File %s loaded and scaled by %f.\n", fileName.c_str(), scaleFactor );
00682 
00683                 //Initialize deformation saving
00684                 /*string deformFileName = fileName;
00685                 deformFileName.replace( deformFileName.size()-3, 3, ".pre" );
00686                 fclose( fopen( deformFileName.c_str(), "wb" ) );
00687                 setDescription( deformFileName );
00688                 */
00689 
00690         } else {
00691                 printf( "Could not open file %s.\n", fileName.c_str() );
00692         }
00693         return false;
00694 
00695 }
00696 
00700 void
00701 COME_Mesh :: resetMesh(){
00702 
00703         faces.clear();
00704         vertices.clear();
00705 }
00706 
00711 void
00712 COME_Mesh :: update(){
00713 
00714         for( int i = 0; i < vertices. size(); i++ ){
00715 
00716                 COME_Vector3D displacement = faces[ vertices[i].getOwnerFace() ].getNearestMolecule()->getLastDisplacement();
00717                 vertices[i] += displacement;
00718                 vertices[i].setCollisionDisp( COME_Vector3D() );
00720         }
00721 }
00722 
00726 void
00727 COME_Mesh :: estabilishLinkVerticesFaces(){
00728 
00729         for( int i = 0; i < faces.size(); i++ ){
00730 
00731                 vertices[ faces[i].getIndexVertex(0) ].setOwnerFace( i );
00732                 vertices[ faces[i].getIndexVertex(1) ].setOwnerFace( i );
00733                 vertices[ faces[i].getIndexVertex(2) ].setOwnerFace( i );
00734         }
00735 }
00736 
00741 int
00742 COME_Mesh :: simplify( double minDistance ){
00743 
00744 
00745         //
00746         for( int iFaces = 0; iFaces < faces.size(); /*iFaces++*/ ){
00747 
00748                 if( COME_Vector3D( faces[iFaces].getVertex(0) - faces[iFaces].getVertex(1) ).vpModule() < minDistance ){
00749                         
00750                         edgeCollapse( faces[iFaces].getIndexVertex(0), faces[iFaces].getIndexVertex(1) );
00751                         //iFaces = 0;
00752                 } else if( COME_Vector3D( faces[iFaces].getVertex(1) - faces[iFaces].getVertex(2) ).vpModule() < minDistance ){
00753                         
00754                         edgeCollapse( faces[iFaces].getIndexVertex(1), faces[iFaces].getIndexVertex(2) );
00755                         //iFaces = 0;
00756                 } else if( COME_Vector3D( faces[iFaces].getVertex(2) - faces[iFaces].getVertex(0) ).vpModule() < minDistance ){
00757                         
00758                         edgeCollapse( faces[iFaces].getIndexVertex(2), faces[iFaces].getIndexVertex(0) );
00759                         //iFaces = 0;
00760                 } else {
00761                         iFaces ++;
00762                 }
00763 
00764         }
00765 
00766         return faces.size();
00767 }
00768 
00772 void
00773 COME_Mesh :: edgeCollapse( int v1, int v2 ){
00774 
00775 
00776         vector<COME_Face>::iterator iterFaces = faces.begin();
00777         for( int iFaces = 0; iFaces < faces.size(); iFaces++, iterFaces++ ){
00778 
00779                 if( faces[iFaces].containsVertexIndex( v1 ) && faces[iFaces].containsVertexIndex( v2 ) ){
00780 
00781                         // remove face
00782                         faces.erase( iterFaces);//, iterFaces );
00783 
00784                 } else if( faces[iFaces].containsVertexIndex( v1 ) ){
00785 
00786                         // change vertex of the face
00787                         faces[iFaces].replaceIndex( v1, v2 );
00788                 }
00789         }
00790         // remove vertice v1
00791         vector<COME_Vertex3D>::iterator iterVertices = vertices.begin();
00792         for( int iVertices = 0; iVertices < vertices.size(); iVertices++, iterVertices++ ){
00793                 if( iVertices == v1 ){
00794                         vertices.erase( iterVertices );//, iterVertices );
00795                         break;
00796                 }
00797         }
00798 }
00799 
00804 void
00805 COME_Mesh :: transform( COME_Matrix M ){
00806 
00807         for( int i = 0; i < vertices. size(); i++ ){
00808 
00809                 vertices[i] = M * vertices[i];
00810         }
00811         updateSkin();
00812 }
00813 
00814 
00818 void
00819 COME_Mesh :: scale( double factor ){
00820 
00821         for( int i = 0; i < vertices. size(); i++ ){
00822 
00823                 vertices[i] = vertices[i] * factor;
00824         }
00825         updateSkin();
00826 
00827 }
00828 
00834 void
00835 COME_Mesh :: scaleOnNormals( double factor ){
00836 
00837         for( int i = 0; i < vertices. size(); i++ ){
00838 
00839                 COME_Vector3D displacement = vertices[i].getNormal() * -factor;
00840                 vertices[i] += displacement;
00841         }
00842         updateSkin();
00843 
00844 }
00845 
00849 void
00850 COME_Mesh :: scale( double factorx, double factory, double factorz ){
00851 
00852         // Find central point
00853         double accX = 0.0, accY = 0.0, accZ = 0.0;
00854         int n;
00855         for( n = 0; n < vertices.size(); n++ ){
00856                 accX+=vertices[n].getX();
00857                 accY+=vertices[n].getY();
00858                 accZ+=vertices[n].getZ();
00859         }
00860         accX/=(double)n; accY/=(double)n; accZ/=(double)n;
00861         
00862         // Translate to origin
00863         translate( -accX, -accY, -accZ );
00864         
00865         //Apply scaling
00866         for( int i = 0; i < vertices. size(); i++ ){
00867 
00868                 vertices[i].setXYZ( vertices[i].getX() * factorx, vertices[i].getY() * factory, vertices[i].getZ() * factorz );
00869         }
00870         
00871         // Translate back to position
00872         translate( accX, accY, accZ );
00873 
00874         updateSkin();
00875 }
00876 
00880 void
00881 COME_Mesh :: translate( double dx, double dy, double dz ){
00882 
00883         for( int i = 0; i < vertices. size(); i++ ){
00884                 vertices[i].setXYZ( vertices[i].getX() + dx, vertices[i].getY() + dy, vertices[i].getZ() + dz );
00885         }
00886         
00887         updateSkin(); 
00888 }
00889 
00895 void
00896 COME_Mesh :: rotate( double rx, double ry, double rz ){
00897 
00898         // Find central point
00899         double accX = 0.0, accY = 0.0, accZ = 0.0;
00900         int n;
00901         for( n = 0; n < vertices.size(); n++ ){
00902                 accX+=vertices[n].getX();
00903                 accY+=vertices[n].getY();
00904                 accZ+=vertices[n].getZ();
00905         }
00906         accX/=(double)n; accY/=(double)n; accZ/=(double)n;
00907         
00908         // Translate to origin
00909         translate( -accX, -accY, -accZ );
00910         
00911         // Apply rotations
00912         for( int i = 0; i < vertices.size(); i++ ){
00913 
00915                 vertices[i].setXYZ(
00916                         vertices[i].getX(),
00917                         vertices[i].getY() * cos( rx ) + vertices[i].getZ() * sin( rx ),
00918                         vertices[i].getZ() * cos( rx ) - vertices[i].getY() * sin( rx )
00919                 );
00921                 vertices[i].setXYZ(
00922                         vertices[i].getX() * cos( ry ) - vertices[i].getZ() * sin( ry ),
00923                         vertices[i].getY(),
00924                         vertices[i].getX() * sin( ry ) + vertices[i].getZ() * cos( ry )
00925                 );
00927                 vertices[i].setXYZ(
00928                         vertices[i].getX() * cos( rz ) + vertices[i].getY() * sin( rz ),
00929                         vertices[i].getY() * cos( rz ) - vertices[i].getX() * sin( rz ),
00930                         vertices[i].getZ()
00931                 );
00932         }
00933         
00934         // Translate back to position
00935         translate( accX, accY, accZ );
00936         
00937         updateSkin();
00938 }
00942 
00948 void
00949 COME_Mesh :: anchorToMolecules( COME_MoleculesTissue* substract, int anchorNumber ){
00950 
00951         printf( "GO ANCHOR? Molec=%d Anchor=%d \n", substract->getShape()->size(), anchorNumber );
00952         if( substract->getShape()->size() >= anchorNumber ){
00953                 printf( "Anchoring... " );
00954                 // For every vertex, find the "anchorNumber" nearest molecules
00955                 for( int i = 0; i < vertices.size(); i++ ){     
00956                         list<COME_Molecule*>::iterator iter;
00957                         /*
00958                         for (iter = substract->getShape()->begin(); iter != substract->getShape()->end(); iter++ ){                     
00959                                 if( (*iter)->getConnectionList()->size() >= 3 ){
00960                                         
00961                                         
00962                                         if( vertices[i].anchors.size() < anchorNumber ){
00963                                                 vertices[i].addAnchor( (*iter) );
00964                                         } else {
00965                                                 //changeAnchorIfNear((*iter),anchorNumber, i);
00966 
00967                                                 for( int contaMenor = 0; contaMenor < vertices[i].anchors.size(); contaMenor++ ){
00968 
00969                                                         if(     vertices[i].anchors[contaMenor]->getPosition().vpDistance( vertices[i] ) > (*iter)->getPosition().vpDistance( vertices[i] ) ){
00970                                                                 vertices[i].anchors[contaMenor] = (*iter);
00971                                                                 break;
00972                                                         }
00973                                                 }
00974                                         }
00975 
00976                                 } else {
00977                                         printf( "An anchor has been found which does not have at least 3 connections. Ignoring that molecule as an anchor.\n" );
00978                                         //return;
00979                                 }
00980                         }*/
00981                         COME_Molecule* anchor1, *anchor2, *anchor3, *anchor4;
00982                         //iter = substract->getShape()->begin();
00983                         //anchor1 = (*iter); iter++;
00984                         //anchor2 = (*iter); iter++;
00985                         //anchor3 = (*iter); iter++;//iter++;
00986                         //anchor4 = (*iter);
00987                         //anchor1 = anchor2 = anchor3 = anchor4 = substract->getShape()->back();
00988                         
00989                         double minDist = INFINITE;
00990                         for (iter = substract->getShape()->begin(); iter != substract->getShape()->end(); iter++ ){                     
00991                                 if( (*iter)->getConnectionList()->size() >= 3 ){
00992 
00993                                         if( minDist > (*iter)->getPosition().vpDistance( vertices[i] ) ){
00994                                                 minDist = (*iter)->getPosition().vpDistance( vertices[i] );
00995                                                 anchor1 = (*iter);
00996                                         }
00997                                 } else {
00998                                         printf( "An anchor has been found which does not have at least 3 connections. Ignoring that molecule as an anchor.\n" );
00999                                 }
01000                         }
01001                         minDist = INFINITE;
01002                         for (iter = substract->getShape()->begin(); iter != substract->getShape()->end(); iter++ ){                     
01003                                 if( (*iter) != anchor1 )
01004                                 if( (*iter)->getConnectionList()->size() >= 3 ){
01005 
01006                                         if( minDist > (*iter)->getPosition().vpDistance( vertices[i] ) ){
01007                                                 minDist = (*iter)->getPosition().vpDistance( vertices[i] );
01008                                                 anchor2 = (*iter);
01009                                         }
01010                                 } else {
01011                                         printf( "An anchor has been found which does not have at least 3 connections. Ignoring that molecule as an anchor.\n" );
01012                                 }
01013                         }
01014                         minDist = INFINITE;
01015                         for (iter = substract->getShape()->begin(); iter != substract->getShape()->end(); iter++ ){                     
01016                                 if( ( (*iter) != anchor1 ) && ( (*iter) != anchor2 ) )
01017                                 if( (*iter)->getConnectionList()->size() >= 3 ){
01018 
01019                                         if( minDist > (*iter)->getPosition().vpDistance( vertices[i] ) ){
01020                                                 minDist = (*iter)->getPosition().vpDistance( vertices[i] );
01021                                                 anchor3 = (*iter);
01022                                         }
01023                                 } else {
01024                                         printf( "An anchor has been found which does not have at least 3 connections. Ignoring that molecule as an anchor.\n" );
01025                                 }
01026                         }
01027                         minDist = INFINITE;
01028                         for (iter = substract->getShape()->begin(); iter != substract->getShape()->end(); iter++ ){                     
01029                                 if( ( (*iter) != anchor1 ) && ( (*iter) != anchor2 ) && ( (*iter) != anchor3 ) )
01030                                 if( (*iter)->getConnectionList()->size() >= 3 ){
01031 
01032                                         if( minDist > (*iter)->getPosition().vpDistance( vertices[i] ) ){
01033                                                 minDist = (*iter)->getPosition().vpDistance( vertices[i] );
01034                                                 anchor4 = (*iter);
01035                                         }
01036                                 } else {
01037                                         printf( "An anchor has been found which does not have at least 3 connections. Ignoring that molecule as an anchor.\n" );
01038                                 }
01039                         }
01040 
01041                         vertices[i].addAnchor( anchor1 );
01042                         vertices[i].addAnchor( anchor2 );
01043                         vertices[i].addAnchor( anchor3 );
01044                         vertices[i].addAnchor( anchor4 );
01045                         //printf( "anchor of %d ar at %f %f %f \n %f %f %f - %f %f %f \n", i, vertices[i].x, vertices[i].y, vertices[i].z, anchor1->getPosition().x, anchor1->getPosition().y, anchor1->getPosition().z, anchor4->getPosition().x, anchor4->getPosition().y, anchor4->getPosition().z );
01046 /*
01047                         verticesGlobal[i].addAnchor( anchor1 );
01048                         verticesGlobal[i].addAnchor( anchor2 );
01049                         verticesGlobal[i].addAnchor( anchor3 );
01050                         verticesGlobal[i].addAnchor( anchor4 );
01051 */                      
01052                 }
01053         
01054                 initClosestNeighbour();
01055                 printf( "done.\n" );
01056         }
01057         
01058         // Set buois
01059         for( int iv = 0; iv < vertices.size(); iv++ ){
01060                 for( int a = 0; a < vertices[iv].getAnchors().size(); a++ ){
01061                         vertices[iv].anchors[a]->addBuoy( &(verticesGlobal[iv]), iv );
01062                 }
01063 
01064         }
01065         /*
01066         // Testar aqui se as bóias foram setadas para as moleculas do substrato
01067         list<COME_Molecule*>::iterator iter;
01068         for( iter = substract->getShape()->begin(); iter != substract->getShape()->end(); iter++ ){
01069                 
01070                 vector<COME_Vertex3D*> *boias = (*iter)->getBuois();
01071                 for( int b = 0; b < boias->size(); b++ ){
01072                         printf( "%s: %f %f %f\n", substract->getParent()->getDescription().c_str(), (*boias)[b]->getX(), (*boias)[b]->getY(), (*boias)[b]->getZ() );
01073                 }
01074                 printf( "=======next molec=====\n" );
01075                  
01076         }
01077         printf( "==============end organ============\n" );
01078         */
01079 }
01080 
01081 //used by anchorToMolecules
01082 void  
01083 COME_Mesh :: changeAnchorIfNear( COME_Molecule* molecule, int anchorNumber, int vert ){
01084 
01085                 int maxDistantAnchor = findDistantAnchor(vert,anchorNumber);                    
01086                 double actualDistance = molecule->getPosition().vpDistance(vertices[vert]);
01087                 double maxDistance =  vertices[vert].anchors[maxDistantAnchor]->getPosition().vpDistance(vertices[vert]) ;
01088                 
01089                 //printf( "%f %f \n", actualDistance, maxDistance );
01090 
01091                 if( actualDistance < maxDistance){
01092                         vertices[vert].anchors[maxDistantAnchor] = molecule;
01093                 }
01094                                         
01095 }
01096 
01098 //returns the index of the most distant anchor to a given vertex
01100 int 
01101 COME_Mesh :: findDistantAnchor(int indVertex, int anchorNumber){
01102         
01103         double maxDistance=0;
01104         double actualDistance=0;
01105         int result = 0;
01106 
01107         for( int j = 0; j < anchorNumber; j++ ){                
01108                 actualDistance = vertices[indVertex].anchors[j]->getPosition().vpDistance( vertices[indVertex] );
01109                         if (actualDistance > maxDistance){
01110                                 maxDistance = actualDistance;
01111                                 result = j;
01112                         }               
01113          }
01114         return result;
01115 }
01117 //Initialises (finds and stores) the closest Anchor-molecule
01119 void 
01120 COME_Mesh :: initClosestNeighbour(){
01121         
01122         for (int f= 0 ; f < faces.size(); f++){
01123                 int closestVertex = 0;
01124                 int closestMolecule = 0;
01125                 double actualDistance = 0;              
01126                 vector <COME_Vertex3D> faceVertices = faces[f].getVertices();
01127                 double closestDistance = faceVertices[closestVertex].anchors[closestMolecule]->getPosition().vpDistance(faceVertices[closestVertex]);
01128                 for (int i= 0 ; i < faceVertices.size(); i++){
01129 
01130                         //printf( "face %d vert %d is at %f %f %f \n", f, i, faceVertices[i].x, faceVertices[i].y, faceVertices[i].z );
01131                         //vector <COME_Molecule*> molecules = faceVertices[i].anchors;
01132 
01133                         for (int j =0 ; j < faceVertices[i].anchors.size(); j++){                               
01134                                 actualDistance = faceVertices[i].anchors[j]->getPosition().vpDistance(faceVertices[i]);
01135                                 if (actualDistance < closestDistance){
01136                                         closestDistance = actualDistance;
01137                                         closestVertex = i;
01138                                         closestMolecule = j;
01139                                 }
01140                         }
01141 
01142                 }
01143                 faces[f].setNearestMolecule(faceVertices[closestVertex].anchors[closestMolecule]);
01144         }
01145 }
01147 //calculates the center of gravity of the mesh
01149 COME_Vertex3D 
01150 COME_Mesh:: calcGravityPoint(vector<COME_Vertex3D> vertices){
01151 
01152         int n=vertices.size();
01153         COME_Vertex3D gravityCenter;
01154         
01155         for(int i=0;i<n;i++){           
01156                 gravityCenter.x+=vertices[i].x;
01157                 gravityCenter.y+=vertices[i].y;
01158                 gravityCenter.z+=vertices[i].z;                 
01159         }
01160         gravityCenter.x /= n;
01161         gravityCenter.y /= n;
01162         gravityCenter.z /= n;
01163         return gravityCenter;
01164 }
01165 
01167 //calculates the area of a Face
01169 double 
01170 COME_Mesh::calcAreaOfFace(vector<COME_Vertex3D> verticesFace){
01171 
01172         double a,b,c,S;                         
01173         a=sqrt(pow((verticesFace[1].x-verticesFace[2].x),2)+pow((verticesFace[1].y-verticesFace[2].y),2)+pow((verticesFace[1].z-verticesFace[2].z),2));
01174         b=sqrt(pow((verticesFace[0].x-verticesFace[2].x),2)+pow((verticesFace[0].y-verticesFace[2].y),2)+pow((verticesFace[0].z-verticesFace[2].z),2));
01175         c=sqrt(pow((verticesFace[1].x-verticesFace[0].x),2)+pow((verticesFace[1].y-verticesFace[0].y),2)+pow((verticesFace[1].z-verticesFace[0].z),2));
01176         S=(a+b+c)/2.0;
01177         return sqrt(S*(S-a)*(S-b)*(S-c));
01178 }
01179 
01180 //Self made absolute 
01181 double myAbs (double x) {
01182   return x > 0 ? x : -x;
01183 }
01184 
01186 //calaculates the distance between the face and the vertex given in parameter
01187 //it is assumed that the normals are up to date
01189 double                          
01190 COME_Mesh :: distanceVertexFace( COME_Vertex3D vertex, vector<COME_Vertex3D> verticesFace){
01191 
01192         COME_Vertex3D A = verticesFace[0];
01193         COME_Vector3D v1;v1.setVector3D( verticesFace[0].getPoint3D() - verticesFace[1].getPoint3D());
01194         COME_Vector3D v2;v2.setVector3D( verticesFace[1].getPoint3D() - verticesFace[2].getPoint3D() );
01195         COME_Vector3D v3 = v1 * v2;
01196         v3.vpNormalize();
01197         COME_Vector3D normal = COME_Vector3D( v3 );
01198         return myAbs(normal.x*(vertex.x-A.x)+normal.y*(vertex.y-A.y)+normal.z*(vertex.z-A.z))/normal.vpModule() ;       
01199 }
01200 
01202 //calculates the volume of the hole mesh in local frame
01204 double 
01205 COME_Mesh :: calcVolume(){
01206 
01207         double volume=0.0;
01208         vector<COME_Vertex3D> verticesGlobal = getVerticesGlobal();
01209         COME_Vertex3D G = calcGravityPoint(verticesGlobal);
01210         vector<COME_Vertex3D> verticesFace;
01211         for( int i = 0; i < faces.size(); i++ ){
01212                 COME_Vertex3D one = verticesGlobal[faces[i].getIndexVertex(0)];
01213                 COME_Vertex3D two = verticesGlobal[faces[i].getIndexVertex(1)];
01214                 COME_Vertex3D three = verticesGlobal[faces[i].getIndexVertex(2)];               
01215                 verticesFace.push_back(one);
01216                 verticesFace.push_back(two);
01217                 verticesFace.push_back(three);
01218                 volume+=calcAreaOfFace(verticesFace)*distanceVertexFace(G, verticesFace)/3;
01219                 verticesFace.clear();
01220         }
01221         return volume;
01222 }
01223 
01227 void
01228 COME_Mesh::initVerticesNeighbours(){
01229                 
01230         printf( "verticesGlobal: %d ; faces: %d\n", verticesGlobal.size(), faces.size() );
01231         for(int i = 0; i < verticesGlobal.size(); i++ ){
01232                 
01233                 for( int j = 0; j < faces.size(); j++ ){
01234 
01235                         if( ( faces[j].getIndexVertex(0) == i ) ||
01236                                 ( faces[j].getIndexVertex(1) == i ) ||
01237                                 ( faces[j].getIndexVertex(2) == i ) ){
01238                                 verticesGlobal[i].addNeighbour(j, this );
01239                         }
01240                 }               
01241         }               
01242 }
01243 
01244 
01248 
01249 void
01250 COME_Mesh::initFacesNeighbours(){
01251                         
01252         for( int a = 0; a < faces.size(); a++ ){                                
01253                 //The indexes of the current face's vertices
01254                 vector <int> actualVertices = faces[a].getIndexVertices();
01255                 
01256                 for ( int b = 0; b < actualVertices.size() ; b++){
01257                         
01258                         for( int c = 0; c < faces.size(); c++ ){
01259 
01260                                 if(a != c){
01261                                         vector<int> verticesOfTempFace = faces[c].getIndexVertices();
01262                                         for (int d = 0; d < verticesOfTempFace.size(); d++){
01263                         
01264                                                 if (actualVertices[b] == verticesOfTempFace[d]){ 
01265                                                         faces[a].addNeighbour(c);
01266                                                         //printf( "FN added: %d\n", c );
01267                                                 }
01268                                         }
01269                                 }
01270                         }
01271                 }
01272         }
01273 }
01274 
01275 
01276 void
01277 COME_Mesh::reverse(char* data,int size) {
01278 
01279   int i;
01280   char temp;
01281   for (i=0;i<size/2;i++)
01282   {
01283     temp=data[i];
01284     data[i]=data[size-i-1];
01285     data[size-i-1]=temp;
01286   }
01287 }
01288 
01289 // quick and dirty bitmap loader...for 24 bit bitmaps with 1 plane only.  
01290 // See http://www.dcs.ed.ac.uk/~mxr/gfx/2d/BMP.txt for more info.
01291 int
01292 COME_Mesh::loadImage( string filename ) {
01293 
01294     FILE *file;
01295     unsigned long size;                 // size of the image in bytes.
01296     unsigned long i;                    // standard counter.
01297     unsigned short int planes;          // number of planes in image (must be 1) 
01298     unsigned short int bpp;             // number of bits per pixel (must be 24)
01299     char temp;                          // temporary color storage for bgr-rgb conversion.
01300     char k[4];
01301     
01302     // allocate space for texture
01303     texture =  (Image *) malloc(sizeof(Image));
01304     if (texture == NULL) {
01305         printf("Error allocating space for texture image");
01306         exit(0);
01307     }
01308     
01309     // make sure the file is there.
01310     if ((file = fopen(filename.c_str(), "rb"))==NULL)
01311     {
01312         printf("File Not Found : %s\n",filename.c_str());
01313         return 0;
01314     }
01315     
01316     // seek through the bmp header, up to the width/height:
01317     fseek(file, 18, SEEK_CUR);
01318 
01319     // read the width
01320     if ((i = fread(k, 4, 1, file)) != 1) {
01321         printf("Error reading width from %s.\n", filename.c_str());
01322         return 0;
01323     }
01324 
01325     //reverse(k,4);
01326     texture->sizeX=*(int*)k;
01327     
01328 
01329    
01330     
01331     printf("Width of %s: %lu\n", filename.c_str(), texture->sizeX);
01332     
01333     // read the height 
01334     if ((i = fread(k, 4, 1, file)) != 1) {
01335         printf("Error reading height from %s.\n", filename.c_str());
01336         return 0;
01337     }
01338 
01339     //reverse(k,4);
01340     texture->sizeY=*(int*)k;
01341 
01342     printf("Height of %s: %lu\n", filename.c_str(), texture->sizeY);
01343     
01344     // calculate the size (assuming 24 bits or 3 bytes per pixel).
01345     size = texture->sizeX * texture->sizeY * 3;
01346 
01347     // read the planes
01348     if ((fread(k, 2, 1, file)) != 1) {
01349         printf("Error reading planes from %s.\n", filename.c_str());
01350         return 0;
01351     }
01352    
01353     reverse(k,2);
01354     planes=*(int*)k;
01355     planes=1; // :)
01356 
01357 
01358     if (planes != 1) {
01359         printf("Planes from %s is not 1: %u\n", filename.c_str(), planes);
01360         return 0;
01361     }
01362 
01363     // read the bpp
01364     if ((i = fread(&bpp, 2, 1, file)) != 1) {
01365         printf("Error reading bpp from %s.\n", filename.c_str());
01366         return 0;
01367     }
01368     bpp=24;
01369     if (bpp != 24) {
01370         printf("Bpp from %s is not 24: %u\n", filename.c_str(), bpp);
01371         return 0;
01372     }
01373         
01374     // seek past the rest of the bitmap header.
01375     fseek(file, 24, SEEK_CUR);
01376 
01377     // read the data. 
01378     texture->data = (char *) malloc(size);
01379     if (texture->data == NULL) {
01380         printf("Error allocating memory for color-corrected image data");
01381         return 0;       
01382     }
01383 
01384     if ((i = fread(texture->data, size, 1, file)) != 1) {
01385         printf("Error reading image data from %s.\n", filename.c_str());
01386         return 0;
01387     }
01388 
01389     for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
01390         temp = texture->data[i];
01391         texture->data[i] = texture->data[i+2];
01392         texture->data[i+2] = temp;
01393     }
01394     
01395     // we're done.
01396     textureID = textureCount++;
01397     return 1;
01398 }
01399 
01400 Image *
01401 COME_Mesh::getTexture(){
01402 
01403         return texture;
01404 }
01405 
01406 unsigned int*
01407 COME_Mesh::getTextureID(){
01408 
01409         return &textureID;
01410 }

Generated on Thu Dec 1 10:13:34 2005 for COME - Biomechanical Joint Model by  doxygen 1.4.5